Files
Brandon ThomasandClaude Opus 5.5 e621098b09 Port the UI to TypeScript and ban raw JavaScript
All UI code moves to strict TypeScript in ui/src/, compiled by tsc (no
bundler) to ui/build/, which index.html loads; the app's build.rs runs the
compile so every cargo build ships the current UI. Sources import each
other as ./x.ts so node --test runs them directly, and the data types
mirror crates/craft-core/src/model.rs.

app.ts now exports start(api) and main.ts wires it to Tauri or the browser
preview, so the UI can be tested in happy-dom against a fake host: sorting,
dragging, clicks, the window picker, status, the urgent view and shortcuts.
Sort toggling and drop placement move into model.ts with unit tests. The
inline error-reporting script becomes report.ts.

CLAUDE.md records the rule: no .js/.mjs/.cjs/.jsx files, inline scripts,
inline handlers or javascript: URLs. ui/src/repo.test.ts enforces it in
make test; make check adds a tsc type-check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:56:15 -04:00

69 lines
2.7 KiB
Makefile

# Convenience targets. Tauri CLI resolves the project from crates/craft-status-app.
APP_DIR := crates/craft-status-app
APP_NAME := Craft Status
BUNDLE := target/release/bundle/macos/$(APP_NAME).app
INSTALLED := /Applications/$(APP_NAME).app
AGENT_ID := ai.storyteller.craft-status
AGENT := $(HOME)/Library/LaunchAgents/$(AGENT_ID).plist
.PHONY: dev run build bundle install uninstall test check ui snapshot preview icons clean
dev: node_modules ## tauri dev, recompiling ui/src/ on change (live-reloads ui/)
npm run --silent watch & trap 'kill $$!' EXIT; cd $(APP_DIR) && cargo tauri dev
run: node_modules ## fast debug binary, no bundling
cargo run -p craft-status-app
build: node_modules ## release build + every installer for this OS
cd $(APP_DIR) && cargo tauri build
bundle: node_modules ## release .app only (macOS)
cd $(APP_DIR) && cargo tauri build --bundles app
install: bundle ## copy to /Applications, start at login, launch now (macOS)
-pkill -x craft-status-app; sleep 1
rm -rf "$(INSTALLED)" && cp -R "$(BUNDLE)" "$(INSTALLED)"
mkdir -p "$(HOME)/Library/LaunchAgents"
printf '%s\n' '<?xml version="1.0" encoding="UTF-8"?>' \
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' \
'<plist version="1.0"><dict>' \
'<key>Label</key><string>$(AGENT_ID)</string>' \
'<key>ProgramArguments</key><array><string>/usr/bin/open</string><string>-a</string><string>$(INSTALLED)</string></array>' \
'<key>RunAtLoad</key><true/>' \
'</dict></plist>' > "$(AGENT)"
open "$(INSTALLED)"
uninstall: ## quit, remove the app and the login item (keeps config + cache)
-pkill -x craft-status-app
rm -rf "$(INSTALLED)" "$(AGENT)"
test: node_modules ## Rust + UI tests
cargo test --workspace
npm test
check: node_modules ## lints
cargo clippy --workspace --all-targets -- -D warnings
cargo fmt --all -- --check
npm run --silent typecheck
snapshot: ## fetch once from GitHub into ui/dev-snapshot.json (prints a table)
cargo run -q -p craft-github --bin craft-fetch -- --snapshot ui/dev-snapshot.json
preview: snapshot ui ## open the UI in a browser against the dev snapshot
@echo "http://127.0.0.1:8766/index.html (Ctrl+C to stop)"
python3 -m http.server 8766 --bind 127.0.0.1 --directory ui
icons: ## regenerate icons from the SVG sources
cd $(APP_DIR) && cargo tauri icon icons-src/app-icon.svg -o icons && rm -rf icons/android icons/ios
cd $(APP_DIR) && cargo tauri icon icons-src/tray.svg -o /tmp/craft-tray -p 64 && cp /tmp/craft-tray/64x64.png icons/tray.png
clean:
cargo clean
node_modules: package.json package-lock.json
npm ci
@touch node_modules
ui: node_modules ## compile ui/src/*.ts to ui/build/ (build.rs does this for app builds)
npm run --silent build