Repository navigation
Building from source
You need Node.js 22 or later, npm and git.
git clone https://github.com/moomoo-agency/craftpages.git
cd craftpages
npm install
npm run dev # the app with hot reload; F12 opens DevToolsOpen any folder with .html files to try it. Before a pull request:
npm run typecheck
npm run lint
npm run format # prettierThe development build keeps its own settings (CraftPages Dev in the app data folder), so it
can run next to an installed CraftPages. If both run at once, give one of them another AI
port in App settings.
To see the update notice in development: CP_FAKE_UPDATE=available npm run dev (or
downloading, ready).
Build each system's installer on that system: sharp, the image library, ships a native
binary per platform, so an app packaged on one OS can't process images on another.
| Command | Run on | Output in dist/
|
|---|---|---|
npm run build:mac |
macOS (either CPU) |
.dmg and .zip for Apple Silicon and Intel |
npm run build:win |
Windows | NSIS installer .exe (x64) |
npm run build:linux |
Linux |
.AppImage and .deb (x64) |
npm run build:unpack |
any | unpacked app, for a quick test |
build:mac adds the other Mac CPU's sharp binary before packaging
(scripts/mac-sharp.mjs); it doesn't change package.json.
.github/workflows/release.yml builds on macOS,
Windows and Linux runners when a version tag is pushed.
-
Set
"version"inpackage.json(e.g.1.0.1) and commit:git add -A git commit -m "CraftPages 1.0.1" git push origin main -
Tag that commit and push the tag:
git tag -a v1.0.1 -m "CraftPages 1.0.1" git push origin v1.0.1 -
When the workflow finishes (about 15 minutes), the release is published under Releases with every installer plus the
latest*.ymlfiles the in-app update check reads (edit the notes there if you like). Installed apps see it within a few hours, or right away with Check now.
The tag must match package.json (v1.0.1 ↔ 1.0.1). To redo a tag after a failed build:
git tag -d v1.0.1
git push origin :refs/tags/v1.0.1Then fix, commit, and tag again. The workflow can also be run by hand from Actions; the installers are then kept as workflow artifacts, not a release.
The Mac builds are signed with a Developer ID certificate and notarized by Apple. The Release workflow passes these repository secrets to the macOS build only:
-
CSC_LINK: the Developer ID Application certificate, a base64.p12(base64 -i cert.p12 | pbcopy) -
CSC_KEY_PASSWORD: the.p12password -
APPLE_ID,APPLE_APP_SPECIFIC_PASSWORD,APPLE_TEAM_ID: for notarization
A local npm run build:mac without them still works, unsigned (electron-builder skips
signing and notarization when there is no certificate).
Windows builds are unsigned, so SmartScreen warns on first launch. To sign them, use a
code-signing certificate (WIN_CSC_LINK / WIN_CSC_KEY_PASSWORD) or Azure Trusted Signing;
see the electron-builder docs.
Electron + React + TypeScript, built with electron-vite. The main process uses parse5 for HTML and sharp for images.
src/
main/ Electron main process
ipc.ts every IPC handler; workspace open/watch
settings.ts app settings (userData), secrets (OS keychain), .sitecms/site.json
history.ts all site writes go through here; backups in .sitecms/history for undo
editing.ts page edit sessions, save, per-page SEO
html/ parse5 tooling: instrumenting, byte-range patches, SEO head fields,
body outline, shared-component fingerprints
preview/ 127.0.0.1 static server, the in-page editor script, screenshots
images.ts sharp import pipeline
media.ts media library, batch optimise, replace everywhere
seo-site.ts site-wide SEO check, sitemap, robots.txt
search/ the site-search box that gets added to sites
scheduler.ts scheduled releases, background mode
publish.ts publishing, overwrite check, rollback
deploy/ Cloudflare Workers static assets (and Pages direct upload), FTP / SFTP
sync/ publish history (snapshots) and sync between computers;
worker/ is the Worker uploaded to the user's Cloudflare account
code.ts code mode: a page's own files, written through the history
updates.ts update check (electron-updater, GitHub releases)
mcp/ WebSocket MCP server, tools, proposals (accept / reject / revert)
preload/ contextBridge: a typed window.api (see src/shared/types.ts)
shared/ types and helpers shared by main and renderer; feature switches
renderer/ React UI (one view per sidebar item) and translations (en, it, uk)
build/ app icons and macOS entitlements
scripts/ build helpers
wiki/ these docs, published to the GitHub wiki on every push to main
Renderers run with contextIsolation: true and nodeIntegration: false. Anything that
touches the disk or the network goes through window.api → IPC → main.
src/shared/features.ts turns off features that are built but
not part of this release:
-
pages: publishing to Cloudflare Pages. Off so new projects only see Workers; projects already set to Pages keep working. -
scheduling: scheduled page edits (go live / come down at a set time), the Publish screen's list of them and background mode. Off for 1.1; the scheduler itself still runs, and scheduled posts work.
The blog, off in 1.0, is on since 1.1.
The wiki pages live in wiki/ in the repository and are copied to the GitHub
wiki by .github/workflows/wiki.yml on every push to
main. Edit them there, not in the wiki itself (changes made on GitHub are overwritten).
Links between pages use [[Page name]].