trellis-he 0.6.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +235 -0
- package/README.md +149 -0
- package/bin/trellis.js +3 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +207 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/channel/adapters/claude.d.ts +38 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +209 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +81 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +512 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +79 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +109 -0
- package/dist/commands/channel/adapters/index.js.map +1 -0
- package/dist/commands/channel/adapters/types.d.ts +33 -0
- package/dist/commands/channel/adapters/types.d.ts.map +1 -0
- package/dist/commands/channel/adapters/types.js +2 -0
- package/dist/commands/channel/adapters/types.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +32 -0
- package/dist/commands/channel/agent-loader.d.ts.map +1 -0
- package/dist/commands/channel/agent-loader.js +154 -0
- package/dist/commands/channel/agent-loader.js.map +1 -0
- package/dist/commands/channel/context-loader.d.ts +26 -0
- package/dist/commands/channel/context-loader.d.ts.map +1 -0
- package/dist/commands/channel/context-loader.js +290 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context.d.ts +16 -0
- package/dist/commands/channel/context.d.ts.map +1 -0
- package/dist/commands/channel/context.js +83 -0
- package/dist/commands/channel/context.js.map +1 -0
- package/dist/commands/channel/create.d.ts +27 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +39 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
- package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/channel/dev-parse-trace.js +70 -0
- package/dist/commands/channel/dev-parse-trace.js.map +1 -0
- package/dist/commands/channel/index.d.ts +3 -0
- package/dist/commands/channel/index.d.ts.map +1 -0
- package/dist/commands/channel/index.js +503 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/kill.d.ts +7 -0
- package/dist/commands/channel/kill.d.ts.map +1 -0
- package/dist/commands/channel/kill.js +121 -0
- package/dist/commands/channel/kill.js.map +1 -0
- package/dist/commands/channel/list.d.ts +17 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +233 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/messages.d.ts +16 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +249 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/rm.d.ts +27 -0
- package/dist/commands/channel/rm.d.ts.map +1 -0
- package/dist/commands/channel/rm.js +216 -0
- package/dist/commands/channel/rm.js.map +1 -0
- package/dist/commands/channel/run.d.ts +31 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +137 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +13 -0
- package/dist/commands/channel/send.d.ts.map +1 -0
- package/dist/commands/channel/send.js +26 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/channel/spawn.d.ts +30 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +194 -0
- package/dist/commands/channel/spawn.js.map +1 -0
- package/dist/commands/channel/store/events.d.ts +39 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +87 -0
- package/dist/commands/channel/store/events.js.map +1 -0
- package/dist/commands/channel/store/filter.d.ts +3 -0
- package/dist/commands/channel/store/filter.d.ts.map +1 -0
- package/dist/commands/channel/store/filter.js +2 -0
- package/dist/commands/channel/store/filter.js.map +1 -0
- package/dist/commands/channel/store/lock.d.ts +23 -0
- package/dist/commands/channel/store/lock.d.ts.map +1 -0
- package/dist/commands/channel/store/lock.js +99 -0
- package/dist/commands/channel/store/lock.js.map +1 -0
- package/dist/commands/channel/store/paths.d.ts +63 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +246 -0
- package/dist/commands/channel/store/paths.js.map +1 -0
- package/dist/commands/channel/store/schema.d.ts +27 -0
- package/dist/commands/channel/store/schema.d.ts.map +1 -0
- package/dist/commands/channel/store/schema.js +34 -0
- package/dist/commands/channel/store/schema.js.map +1 -0
- package/dist/commands/channel/store/thread-state.d.ts +5 -0
- package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
- package/dist/commands/channel/store/thread-state.js +16 -0
- package/dist/commands/channel/store/thread-state.js.map +1 -0
- package/dist/commands/channel/store/watch.d.ts +19 -0
- package/dist/commands/channel/store/watch.d.ts.map +1 -0
- package/dist/commands/channel/store/watch.js +146 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +160 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +66 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +143 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +121 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor/turns.d.ts +20 -0
- package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/turns.js +28 -0
- package/dist/commands/channel/supervisor/turns.js.map +1 -0
- package/dist/commands/channel/supervisor/warning.d.ts +48 -0
- package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/warning.js +77 -0
- package/dist/commands/channel/supervisor/warning.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +53 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +304 -0
- package/dist/commands/channel/supervisor.js.map +1 -0
- package/dist/commands/channel/text-body.d.ts +13 -0
- package/dist/commands/channel/text-body.d.ts.map +1 -0
- package/dist/commands/channel/text-body.js +47 -0
- package/dist/commands/channel/text-body.js.map +1 -0
- package/dist/commands/channel/threads.d.ts +39 -0
- package/dist/commands/channel/threads.d.ts.map +1 -0
- package/dist/commands/channel/threads.js +106 -0
- package/dist/commands/channel/threads.js.map +1 -0
- package/dist/commands/channel/title.d.ts +12 -0
- package/dist/commands/channel/title.d.ts.map +1 -0
- package/dist/commands/channel/title.js +24 -0
- package/dist/commands/channel/title.js.map +1 -0
- package/dist/commands/channel/wait.d.ts +18 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +76 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +59 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1459 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mem.d.ts +30 -0
- package/dist/commands/mem.d.ts.map +1 -0
- package/dist/commands/mem.js +424 -0
- package/dist/commands/mem.js.map +1 -0
- package/dist/commands/uninstall.d.ts +27 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +339 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +72 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +1926 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +84 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +35 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +219 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/configurators/antigravity.d.ts +7 -0
- package/dist/configurators/antigravity.d.ts.map +1 -0
- package/dist/configurators/antigravity.js +19 -0
- package/dist/configurators/antigravity.js.map +1 -0
- package/dist/configurators/claude.d.ts +9 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +72 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/codebuddy.d.ts +10 -0
- package/dist/configurators/codebuddy.d.ts.map +1 -0
- package/dist/configurators/codebuddy.js +30 -0
- package/dist/configurators/codebuddy.js.map +1 -0
- package/dist/configurators/codex.d.ts +8 -0
- package/dist/configurators/codex.d.ts.map +1 -0
- package/dist/configurators/codex.js +87 -0
- package/dist/configurators/codex.js.map +1 -0
- package/dist/configurators/copilot.d.ts +10 -0
- package/dist/configurators/copilot.d.ts.map +1 -0
- package/dist/configurators/copilot.js +51 -0
- package/dist/configurators/copilot.js.map +1 -0
- package/dist/configurators/cursor.d.ts +10 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +29 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/droid.d.ts +10 -0
- package/dist/configurators/droid.d.ts.map +1 -0
- package/dist/configurators/droid.js +30 -0
- package/dist/configurators/droid.js.map +1 -0
- package/dist/configurators/gemini.d.ts +16 -0
- package/dist/configurators/gemini.d.ts.map +1 -0
- package/dist/configurators/gemini.js +38 -0
- package/dist/configurators/gemini.js.map +1 -0
- package/dist/configurators/index.d.ts +65 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +367 -0
- package/dist/configurators/index.js.map +1 -0
- package/dist/configurators/kilo.d.ts +7 -0
- package/dist/configurators/kilo.d.ts.map +1 -0
- package/dist/configurators/kilo.js +19 -0
- package/dist/configurators/kilo.js.map +1 -0
- package/dist/configurators/kiro.d.ts +8 -0
- package/dist/configurators/kiro.d.ts.map +1 -0
- package/dist/configurators/kiro.js +24 -0
- package/dist/configurators/kiro.js.map +1 -0
- package/dist/configurators/opencode.d.ts +14 -0
- package/dist/configurators/opencode.d.ts.map +1 -0
- package/dist/configurators/opencode.js +96 -0
- package/dist/configurators/opencode.js.map +1 -0
- package/dist/configurators/pi.d.ts +3 -0
- package/dist/configurators/pi.d.ts.map +1 -0
- package/dist/configurators/pi.js +45 -0
- package/dist/configurators/pi.js.map +1 -0
- package/dist/configurators/qoder.d.ts +11 -0
- package/dist/configurators/qoder.d.ts.map +1 -0
- package/dist/configurators/qoder.js +31 -0
- package/dist/configurators/qoder.js.map +1 -0
- package/dist/configurators/shared.d.ts +178 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +541 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/windsurf.d.ts +7 -0
- package/dist/configurators/windsurf.d.ts.map +1 -0
- package/dist/configurators/windsurf.js +19 -0
- package/dist/configurators/windsurf.js.map +1 -0
- package/dist/configurators/workflow.d.ts +37 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +164 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +70 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +79 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/constants/version.d.ts +9 -0
- package/dist/constants/version.d.ts.map +1 -0
- package/dist/constants/version.js +15 -0
- package/dist/constants/version.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/index.d.ts +62 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +187 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/manifests/0.1.9.json +30 -0
- package/dist/migrations/manifests/0.2.0.json +49 -0
- package/dist/migrations/manifests/0.2.12.json +9 -0
- package/dist/migrations/manifests/0.2.13.json +9 -0
- package/dist/migrations/manifests/0.2.14.json +175 -0
- package/dist/migrations/manifests/0.2.15.json +33 -0
- package/dist/migrations/manifests/0.3.0-beta.0.json +297 -0
- package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
- package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.3.0.json +11 -0
- package/dist/migrations/manifests/0.3.1.json +9 -0
- package/dist/migrations/manifests/0.3.10.json +9 -0
- package/dist/migrations/manifests/0.3.2.json +9 -0
- package/dist/migrations/manifests/0.3.3.json +9 -0
- package/dist/migrations/manifests/0.3.4.json +21 -0
- package/dist/migrations/manifests/0.3.5.json +9 -0
- package/dist/migrations/manifests/0.3.6.json +9 -0
- package/dist/migrations/manifests/0.3.7.json +9 -0
- package/dist/migrations/manifests/0.3.8.json +9 -0
- package/dist/migrations/manifests/0.3.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
- package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
- package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.4.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
- package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
- package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
- package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
- package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
- package/dist/migrations/manifests/0.5.0.json +9 -0
- package/dist/migrations/manifests/0.5.1.json +9 -0
- package/dist/migrations/manifests/0.5.10.json +9 -0
- package/dist/migrations/manifests/0.5.11.json +16 -0
- package/dist/migrations/manifests/0.5.12.json +9 -0
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.2.json +9 -0
- package/dist/migrations/manifests/0.5.3.json +9 -0
- package/dist/migrations/manifests/0.5.4.json +9 -0
- package/dist/migrations/manifests/0.5.5.json +9 -0
- package/dist/migrations/manifests/0.5.6.json +9 -0
- package/dist/migrations/manifests/0.5.7.json +16 -0
- package/dist/migrations/manifests/0.5.8.json +9 -0
- package/dist/migrations/manifests/0.5.9.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +123 -0
- package/dist/templates/claude/agents/trellis-code-architecture-review.md +71 -0
- package/dist/templates/claude/agents/trellis-code-review.md +71 -0
- package/dist/templates/claude/agents/trellis-implement.md +118 -0
- package/dist/templates/claude/agents/trellis-merge-review.md +72 -0
- package/dist/templates/claude/agents/trellis-research.md +137 -0
- package/dist/templates/claude/agents/trellis-spec-review.md +71 -0
- package/dist/templates/claude/index.d.ts +22 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +46 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +73 -0
- package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
- package/dist/templates/codebuddy/agents/trellis-implement.md +110 -0
- package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
- package/dist/templates/codebuddy/index.d.ts +15 -0
- package/dist/templates/codebuddy/index.d.ts.map +1 -0
- package/dist/templates/codebuddy/index.js +15 -0
- package/dist/templates/codebuddy/index.js.map +1 -0
- package/dist/templates/codebuddy/settings.json +59 -0
- package/dist/templates/codex/agents/trellis-check.toml +84 -0
- package/dist/templates/codex/agents/trellis-implement.toml +65 -0
- package/dist/templates/codex/agents/trellis-research.toml +73 -0
- package/dist/templates/codex/config.toml +35 -0
- package/dist/templates/codex/hooks/session-start.py +545 -0
- package/dist/templates/codex/hooks.json +15 -0
- package/dist/templates/codex/index.d.ts +39 -0
- package/dist/templates/codex/index.d.ts.map +1 -0
- package/dist/templates/codex/index.js +85 -0
- package/dist/templates/codex/index.js.map +1 -0
- package/dist/templates/codex/skills/before-dev/SKILL.md +40 -0
- package/dist/templates/codex/skills/brainstorm/SKILL.md +112 -0
- package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
- package/dist/templates/codex/skills/check/SKILL.md +98 -0
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
- package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
- package/dist/templates/codex/skills/finish-work/SKILL.md +90 -0
- package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -0
- package/dist/templates/codex/skills/integrate-skill/SKILL.md +221 -0
- package/dist/templates/codex/skills/onboard/SKILL.md +363 -0
- package/dist/templates/codex/skills/record-session/SKILL.md +67 -0
- package/dist/templates/codex/skills/start/SKILL.md +64 -0
- package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +84 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +65 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +130 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
- package/dist/templates/common/commands/continue.md +56 -0
- package/dist/templates/common/commands/finish-work.md +66 -0
- package/dist/templates/common/commands/start.md +59 -0
- package/dist/templates/common/index.d.ts +48 -0
- package/dist/templates/common/index.d.ts.map +1 -0
- package/dist/templates/common/index.js +104 -0
- package/dist/templates/common/index.js.map +1 -0
- package/dist/templates/common/skills/before-dev.md +41 -0
- package/dist/templates/common/skills/brainstorm.md +112 -0
- package/dist/templates/common/skills/break-loop.md +125 -0
- package/dist/templates/common/skills/check.md +93 -0
- package/dist/templates/common/skills/grill-me.md +49 -0
- package/dist/templates/common/skills/improve-codebase-architecture.md +38 -0
- package/dist/templates/common/skills/tdd.md +34 -0
- package/dist/templates/common/skills/update-spec.md +351 -0
- package/dist/templates/copilot/hooks/session-start.py +547 -0
- package/dist/templates/copilot/hooks.json +19 -0
- package/dist/templates/copilot/index.d.ts +23 -0
- package/dist/templates/copilot/index.d.ts.map +1 -0
- package/dist/templates/copilot/index.js +54 -0
- package/dist/templates/copilot/index.js.map +1 -0
- package/dist/templates/copilot/prompts/before-dev.prompt.md +39 -0
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +111 -0
- package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
- package/dist/templates/copilot/prompts/check.prompt.md +97 -0
- package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
- package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
- package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
- package/dist/templates/copilot/prompts/parallel.prompt.md +204 -0
- package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
- package/dist/templates/copilot/prompts/start.prompt.md +63 -0
- package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
- package/dist/templates/cursor/agents/trellis-check.md +114 -0
- package/dist/templates/cursor/agents/trellis-implement.md +109 -0
- package/dist/templates/cursor/agents/trellis-research.md +136 -0
- package/dist/templates/cursor/hooks.json +24 -0
- package/dist/templates/cursor/index.d.ts +13 -0
- package/dist/templates/cursor/index.d.ts.map +1 -0
- package/dist/templates/cursor/index.js +13 -0
- package/dist/templates/cursor/index.js.map +1 -0
- package/dist/templates/droid/droids/trellis-check.md +107 -0
- package/dist/templates/droid/droids/trellis-implement.md +102 -0
- package/dist/templates/droid/droids/trellis-research.md +137 -0
- package/dist/templates/droid/index.d.ts +15 -0
- package/dist/templates/droid/index.d.ts.map +1 -0
- package/dist/templates/droid/index.js +15 -0
- package/dist/templates/droid/index.js.map +1 -0
- package/dist/templates/droid/settings.json +59 -0
- package/dist/templates/extract.d.ts +40 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +106 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/gemini/agents/trellis-check.md +107 -0
- package/dist/templates/gemini/agents/trellis-implement.md +102 -0
- package/dist/templates/gemini/agents/trellis-research.md +136 -0
- package/dist/templates/gemini/index.d.ts +13 -0
- package/dist/templates/gemini/index.d.ts.map +1 -0
- package/dist/templates/gemini/index.js +13 -0
- package/dist/templates/gemini/index.js.map +1 -0
- package/dist/templates/gemini/settings.json +28 -0
- package/dist/templates/kiro/agents/trellis-check.json +26 -0
- package/dist/templates/kiro/agents/trellis-implement.json +26 -0
- package/dist/templates/kiro/agents/trellis-research.json +30 -0
- package/dist/templates/kiro/index.d.ts +18 -0
- package/dist/templates/kiro/index.d.ts.map +1 -0
- package/dist/templates/kiro/index.js +18 -0
- package/dist/templates/kiro/index.js.map +1 -0
- package/dist/templates/markdown/agents.md +21 -0
- package/dist/templates/markdown/gitignore.txt +15 -0
- package/dist/templates/markdown/index.d.ts +27 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +52 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
- package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +223 -0
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +259 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +595 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +97 -0
- package/dist/templates/markdown/workspace-index.md +125 -0
- package/dist/templates/markdown/worktree.yaml.txt +58 -0
- package/dist/templates/opencode/agents/trellis-check.md +122 -0
- package/dist/templates/opencode/agents/trellis-implement.md +118 -0
- package/dist/templates/opencode/agents/trellis-research.md +145 -0
- package/dist/templates/opencode/lib/session-utils.js +521 -0
- package/dist/templates/opencode/lib/trellis-context.js +381 -0
- package/dist/templates/opencode/package.json +5 -0
- package/dist/templates/opencode/plugins/inject-subagent-context.js +513 -0
- package/dist/templates/opencode/plugins/inject-workflow-state.js +159 -0
- package/dist/templates/opencode/plugins/session-start.js +101 -0
- package/dist/templates/pi/agents/trellis-check.md +37 -0
- package/dist/templates/pi/agents/trellis-implement.md +42 -0
- package/dist/templates/pi/agents/trellis-research.md +25 -0
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1174 -0
- package/dist/templates/pi/index.d.ts +5 -0
- package/dist/templates/pi/index.d.ts.map +1 -0
- package/dist/templates/pi/index.js +12 -0
- package/dist/templates/pi/index.js.map +1 -0
- package/dist/templates/pi/settings.json +21 -0
- package/dist/templates/qoder/agents/trellis-check.md +108 -0
- package/dist/templates/qoder/agents/trellis-implement.md +103 -0
- package/dist/templates/qoder/agents/trellis-research.md +137 -0
- package/dist/templates/qoder/index.d.ts +15 -0
- package/dist/templates/qoder/index.d.ts.map +1 -0
- package/dist/templates/qoder/index.js +15 -0
- package/dist/templates/qoder/index.js.map +1 -0
- package/dist/templates/qoder/settings.json +47 -0
- package/dist/templates/shared-hooks/index.d.ts +50 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +88 -0
- package/dist/templates/shared-hooks/index.js.map +1 -0
- package/dist/templates/shared-hooks/inject-shell-session-context.py +183 -0
- package/dist/templates/shared-hooks/inject-subagent-context.py +771 -0
- package/dist/templates/shared-hooks/inject-workflow-state.py +363 -0
- package/dist/templates/shared-hooks/session-start.py +832 -0
- package/dist/templates/template-utils.d.ts +26 -0
- package/dist/templates/template-utils.d.ts.map +1 -0
- package/dist/templates/template-utils.js +60 -0
- package/dist/templates/template-utils.js.map +1 -0
- package/dist/templates/trellis/config.yaml +90 -0
- package/dist/templates/trellis/gitignore.txt +32 -0
- package/dist/templates/trellis/index.d.ts +52 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +97 -0
- package/dist/templates/trellis/index.js.map +1 -0
- package/dist/templates/trellis/scripts/__init__.py +5 -0
- package/dist/templates/trellis/scripts/add_session.py +547 -0
- package/dist/templates/trellis/scripts/common/__init__.py +92 -0
- package/dist/templates/trellis/scripts/common/active_task.py +626 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +811 -0
- package/dist/templates/trellis/scripts/common/config.py +445 -0
- package/dist/templates/trellis/scripts/common/developer.py +190 -0
- package/dist/templates/trellis/scripts/common/git.py +31 -0
- package/dist/templates/trellis/scripts/common/git_context.py +106 -0
- package/dist/templates/trellis/scripts/common/io.py +37 -0
- package/dist/templates/trellis/scripts/common/log.py +45 -0
- package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
- package/dist/templates/trellis/scripts/common/paths.py +447 -0
- package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
- package/dist/templates/trellis/scripts/common/session_context.py +821 -0
- package/dist/templates/trellis/scripts/common/task_context.py +223 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
- package/dist/templates/trellis/scripts/common/task_store.py +698 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +274 -0
- package/dist/templates/trellis/scripts/common/tasks.py +112 -0
- package/dist/templates/trellis/scripts/common/trellis_config.py +131 -0
- package/dist/templates/trellis/scripts/common/types.py +110 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +212 -0
- package/dist/templates/trellis/scripts/get_context.py +16 -0
- package/dist/templates/trellis/scripts/get_developer.py +26 -0
- package/dist/templates/trellis/scripts/hooks/linear_sync.py +243 -0
- package/dist/templates/trellis/scripts/init_developer.py +51 -0
- package/dist/templates/trellis/scripts/task.py +500 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +750 -0
- package/dist/types/ai-tools.d.ts +95 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +280 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/types/migration.d.ts +125 -0
- package/dist/types/migration.d.ts.map +1 -0
- package/dist/types/migration.js +8 -0
- package/dist/types/migration.js.map +1 -0
- package/dist/utils/compare-versions.d.ts +12 -0
- package/dist/utils/compare-versions.d.ts.map +1 -0
- package/dist/utils/compare-versions.js +86 -0
- package/dist/utils/compare-versions.js.map +1 -0
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +36 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +203 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/posix.d.ts +13 -0
- package/dist/utils/posix.d.ts.map +1 -0
- package/dist/utils/posix.js +15 -0
- package/dist/utils/posix.js.map +1 -0
- package/dist/utils/project-detector.d.ts +46 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +666 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/proxy.d.ts +25 -0
- package/dist/utils/proxy.d.ts.map +1 -0
- package/dist/utils/proxy.js +60 -0
- package/dist/utils/proxy.js.map +1 -0
- package/dist/utils/task-json.d.ts +13 -0
- package/dist/utils/task-json.d.ts.map +1 -0
- package/dist/utils/task-json.js +12 -0
- package/dist/utils/task-json.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +150 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +907 -0
- package/dist/utils/template-fetcher.js.map +1 -0
- package/dist/utils/template-hash.d.ts +123 -0
- package/dist/utils/template-hash.d.ts.map +1 -0
- package/dist/utils/template-hash.js +334 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts +66 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
- package/dist/utils/uninstall-scrubbers.js +342 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -0
- package/dist/utils/workflow-resolver.d.ts +86 -0
- package/dist/utils/workflow-resolver.d.ts.map +1 -0
- package/dist/utils/workflow-resolver.js +265 -0
- package/dist/utils/workflow-resolver.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
# Cross-Platform Thinking Guide
|
|
2
|
+
|
|
3
|
+
> **Purpose**: Catch platform-specific assumptions before they become bugs.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Why This Matters
|
|
8
|
+
|
|
9
|
+
**Most cross-platform bugs come from implicit assumptions**:
|
|
10
|
+
|
|
11
|
+
- Assumed shebang works → breaks on Windows
|
|
12
|
+
- Assumed `/` path separator → breaks on Windows
|
|
13
|
+
- Assumed `\n` line endings → inconsistent behavior
|
|
14
|
+
- Assumed command availability → `grep` vs `findstr`
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Platform Differences Checklist
|
|
19
|
+
|
|
20
|
+
### 1. Script Execution
|
|
21
|
+
|
|
22
|
+
| Assumption | macOS/Linux | Windows |
|
|
23
|
+
|------------|-------------|---------|
|
|
24
|
+
| Shebang (`#!/usr/bin/env python3`) | ✅ Works | ❌ Ignored |
|
|
25
|
+
| Direct execution (`./script.py`) | ✅ Works | ❌ Fails |
|
|
26
|
+
| `python3` command | ✅ Always available | ⚠️ May need `python` |
|
|
27
|
+
| `python` command | ⚠️ May be Python 2 | ✅ Usually Python 3 |
|
|
28
|
+
|
|
29
|
+
**Rule 1**: For user-facing docs, help text, and error messages, either:
|
|
30
|
+
|
|
31
|
+
- state the platform rule explicitly (`python` on Windows, `python3` elsewhere), or
|
|
32
|
+
- render the command through the same platform-aware helper / placeholder the code uses.
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
# BAD - Assumes shebang works
|
|
36
|
+
print("Usage: ./script.py <args>")
|
|
37
|
+
print("Run: script.py <args>")
|
|
38
|
+
|
|
39
|
+
# GOOD - Platform-aware wording
|
|
40
|
+
print("Usage: python on Windows, python3 elsewhere")
|
|
41
|
+
print("Run: {{PYTHON_CMD}} ./.trellis/scripts/task.py <args>")
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Rule 2**: When generating config files at init time, use placeholder + platform detection:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// In template file (settings.json):
|
|
48
|
+
{ "command": "{{PYTHON_CMD}} .claude/hooks/script.py" }
|
|
49
|
+
|
|
50
|
+
// In configurator:
|
|
51
|
+
function getPythonCommand(): string {
|
|
52
|
+
return process.platform === "win32" ? "python" : "python3";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function replacePlaceholders(content: string): string {
|
|
56
|
+
return content.replace(/\{\{PYTHON_CMD\}\}/g, getPythonCommand());
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Rule 3**: When calling Python at runtime from JavaScript, detect platform dynamically:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
import { platform } from "os"
|
|
64
|
+
|
|
65
|
+
const PYTHON_CMD = platform() === "win32" ? "python" : "python3"
|
|
66
|
+
execSync(`${PYTHON_CMD} "${scriptPath}"`, { ... })
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Rule 4**: If you need to verify Python is actually installed (not just choose
|
|
70
|
+
the command), probe the same platform-selected alias you will later render or
|
|
71
|
+
execute:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
function getPythonCommand(platform = process.platform): string {
|
|
75
|
+
return platform === "win32" ? "python" : "python3";
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function warnIfPythonTooOld(): void {
|
|
79
|
+
const cmd = getPythonCommand();
|
|
80
|
+
try {
|
|
81
|
+
execSync(`${cmd} --version`, { stdio: "pipe" });
|
|
82
|
+
} catch {
|
|
83
|
+
// Missing Python is a separate error path; don't silently swap aliases.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Rule 5**: Don't assume the Python version the AI CLI uses matches your shell's `python3`. The user's terminal may resolve `python3` → homebrew 3.11, but AI CLI hosts (including enterprise-forked Claude Code / Cursor distributions) spawn hook subprocesses with a minimal PATH that resolves `python3` → `/usr/bin/python3` → macOS system 3.9. Distributed templates must either target the lowest plausible version or use `from __future__ import annotations` for PEP 604 syntax. See `cli/backend/script-conventions.md` → **CRITICAL: PEP 604 Annotations Require `from __future__ import annotations`** for the hard rule and audit check.
|
|
89
|
+
|
|
90
|
+
**Rule 6**: When calling Python from Python, use `sys.executable`:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import sys
|
|
94
|
+
import subprocess
|
|
95
|
+
|
|
96
|
+
# BAD - Hardcoded command
|
|
97
|
+
subprocess.run(["python3", "other_script.py"])
|
|
98
|
+
|
|
99
|
+
# GOOD - Use current interpreter
|
|
100
|
+
subprocess.run([sys.executable, "other_script.py"])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 2. Path Handling
|
|
104
|
+
|
|
105
|
+
| Assumption | macOS/Linux | Windows |
|
|
106
|
+
|------------|-------------|---------|
|
|
107
|
+
| `/` separator | ✅ Works | ⚠️ Sometimes works |
|
|
108
|
+
| `\` separator | ❌ Escape char | ✅ Native |
|
|
109
|
+
| `pathlib.Path` | ✅ Works | ✅ Works |
|
|
110
|
+
|
|
111
|
+
**Rule (Python)**: Use `pathlib.Path` for all path operations.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# BAD - String concatenation
|
|
115
|
+
path = base + "/" + filename
|
|
116
|
+
|
|
117
|
+
# GOOD - pathlib
|
|
118
|
+
from pathlib import Path
|
|
119
|
+
path = Path(base) / filename
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Logical key vs filesystem path (TypeScript)
|
|
123
|
+
|
|
124
|
+
A path string has two distinct roles. **Treat them differently.**
|
|
125
|
+
|
|
126
|
+
| Role | OS-native (`\` on Windows) | Always POSIX (`/`) |
|
|
127
|
+
|------|---------------------------|--------------------|
|
|
128
|
+
| `fs.readFileSync(p)` / `path.join(cwd, x)` for fs call | ✅ Required | ❌ May fail on Windows |
|
|
129
|
+
| `Map<relPath, content>` key, JSON field, hash dictionary key, anything persisted across OS | ❌ Cross-OS mismatch | ✅ Required |
|
|
130
|
+
|
|
131
|
+
**Rule**: Anywhere a path string crosses OS or persists (Map keys consumed by another OS, JSON fields, hash dictionary keys), normalize to POSIX. Anywhere it goes straight to `fs.*`, leave OS-native.
|
|
132
|
+
|
|
133
|
+
**Single source of truth**: `packages/cli/src/utils/posix.ts` exports `toPosix(p)`. Don't sprinkle `replaceAll('\\', '/')` at every `path.join` site — apply `toPosix` **once at the boundary**: collector exit (Map key entering hash dictionary) or write-time (`saveHashes` before `JSON.stringify`).
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// BAD - logical key carries OS-native separator
|
|
137
|
+
function collectTemplates(): Map<string, string> {
|
|
138
|
+
const files = new Map<string, string>();
|
|
139
|
+
for (const entry of walk(dir)) {
|
|
140
|
+
files.set(path.join(".opencode", entry), readFile(entry)); // \ on Windows
|
|
141
|
+
}
|
|
142
|
+
return files;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// GOOD - normalize at the boundary
|
|
146
|
+
import { toPosix } from "../utils/posix.js";
|
|
147
|
+
|
|
148
|
+
function collectTemplates(): Map<string, string> {
|
|
149
|
+
const files = new Map<string, string>();
|
|
150
|
+
for (const entry of walk(dir)) {
|
|
151
|
+
files.set(toPosix(path.join(".opencode", entry)), readFile(entry));
|
|
152
|
+
}
|
|
153
|
+
return files;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ALSO ACCEPTABLE - write-side defense (for storage helpers like saveHashes)
|
|
157
|
+
function saveHashes(cwd: string, hashes: Record<string, string>): void {
|
|
158
|
+
const normalized = Object.fromEntries(
|
|
159
|
+
Object.entries(hashes).map(([k, v]) => [toPosix(k), v])
|
|
160
|
+
);
|
|
161
|
+
fs.writeFileSync(getHashesPath(cwd), JSON.stringify(normalized, null, 2));
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Common offender**: `path.relative(cwd, fullPath)` produces `\` on Windows. If you then use that string as a hash dictionary lookup key (`hashes[relPath]`), `toPosix` it first, or the lookup misses on Windows.
|
|
166
|
+
|
|
167
|
+
### 3. Line Endings
|
|
168
|
+
|
|
169
|
+
| Format | macOS/Linux | Windows | Git |
|
|
170
|
+
|--------|-------------|---------|-----|
|
|
171
|
+
| `\n` (LF) | ✅ Native | ⚠️ Some tools | ✅ Normalized |
|
|
172
|
+
| `\r\n` (CRLF) | ⚠️ Extra char | ✅ Native | Converted |
|
|
173
|
+
|
|
174
|
+
**Rule 1**: Use `.gitattributes` to enforce consistent line endings.
|
|
175
|
+
|
|
176
|
+
```gitattributes
|
|
177
|
+
* text=auto eol=lf
|
|
178
|
+
*.sh text eol=lf
|
|
179
|
+
*.py text eol=lf
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Rule 2**: When hashing or comparing **content** across platforms, normalize line endings before computing the hash. `.gitattributes` only governs git checkout — files written by users, scripts, or `core.autocrlf=true` may still arrive as CRLF, and `sha256(LF)` ≠ `sha256(CRLF)` for otherwise-identical content.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// BAD - Windows users with autocrlf=true get a different hash
|
|
186
|
+
export function computeHash(content: string): string {
|
|
187
|
+
return createHash("sha256").update(content, "utf-8").digest("hex");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// GOOD - normalize before hashing so logical content hashes identically
|
|
191
|
+
export function computeHash(content: string): string {
|
|
192
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
193
|
+
return createHash("sha256").update(normalized, "utf-8").digest("hex");
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Apply this rule wherever the hash crosses OS boundaries (template hash dictionary, content fingerprints stored in JSON, integrity checks against a remote registry).
|
|
198
|
+
|
|
199
|
+
### 4. Environment Variables
|
|
200
|
+
|
|
201
|
+
| Variable | macOS/Linux | Windows |
|
|
202
|
+
|----------|-------------|---------|
|
|
203
|
+
| `HOME` | ✅ Set | ❌ Use `USERPROFILE` |
|
|
204
|
+
| `PATH` separator | `:` | `;` |
|
|
205
|
+
| Case sensitivity | ✅ Case-sensitive | ❌ Case-insensitive |
|
|
206
|
+
|
|
207
|
+
**Rule 1**: Use `pathlib.Path.home()` instead of environment variables.
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# BAD
|
|
211
|
+
home = os.environ.get("HOME")
|
|
212
|
+
|
|
213
|
+
# GOOD
|
|
214
|
+
home = Path.home()
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Rule 2**: When injecting environment variables into shell commands, generate
|
|
218
|
+
the prefix for the actual shell that will parse the command. Do not choose
|
|
219
|
+
syntax from OS alone. AI tool "Bash" surfaces on Windows may execute through
|
|
220
|
+
PowerShell, Git Bash, MSYS2, or another POSIX-like shell.
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
// BAD - breaks when the host shell is PowerShell
|
|
224
|
+
command = `export TRELLIS_CONTEXT_ID=${shellQuote(contextKey)}; ${command}`;
|
|
225
|
+
|
|
226
|
+
// GOOD - shell-dialect-aware command prefix
|
|
227
|
+
const prefix = process.platform === "win32" && !isWindowsPosixShell(process.env)
|
|
228
|
+
? `$env:TRELLIS_CONTEXT_ID = ${powershellQuote(contextKey)}; `
|
|
229
|
+
: `export TRELLIS_CONTEXT_ID=${shellQuote(contextKey)}; `;
|
|
230
|
+
command = `${prefix}${command}`;
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
On Windows, treat `MSYSTEM`, `MINGW_PREFIX`, `OSTYPE=msys|mingw|cygwin`,
|
|
234
|
+
`SHELL=...bash`, or a platform-specific Git Bash setting as POSIX-shell
|
|
235
|
+
signals. Keep PowerShell as the Windows default when there is no POSIX-shell
|
|
236
|
+
signal.
|
|
237
|
+
|
|
238
|
+
Also make duplicate-injection detection shell-aware. A guard that only matches
|
|
239
|
+
`export VAR=` will miss PowerShell's `$env:VAR = ...` form and can wrap an
|
|
240
|
+
already-correct command a second time.
|
|
241
|
+
|
|
242
|
+
### 5. Command Availability
|
|
243
|
+
|
|
244
|
+
| Command | macOS/Linux | Windows |
|
|
245
|
+
|---------|-------------|---------|
|
|
246
|
+
| `grep` | ✅ Built-in | ❌ Not available |
|
|
247
|
+
| `find` | ✅ Built-in | ⚠️ Different syntax |
|
|
248
|
+
| `cat` | ✅ Built-in | ❌ Use `type` |
|
|
249
|
+
| `tail -f` | ✅ Built-in | ❌ Not available |
|
|
250
|
+
|
|
251
|
+
**Rule**: Use Python standard library instead of shell commands when possible.
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
# BAD - tail -f is not available on Windows
|
|
255
|
+
subprocess.run(["tail", "-f", log_file])
|
|
256
|
+
|
|
257
|
+
# GOOD - Cross-platform implementation
|
|
258
|
+
def tail_follow(file_path: Path) -> None:
|
|
259
|
+
"""Follow a file like 'tail -f', cross-platform compatible."""
|
|
260
|
+
with open(file_path, "r", encoding="utf-8", errors="replace") as f:
|
|
261
|
+
f.seek(0, 2) # Go to end
|
|
262
|
+
while True:
|
|
263
|
+
line = f.readline()
|
|
264
|
+
if line:
|
|
265
|
+
print(line, end="", flush=True)
|
|
266
|
+
else:
|
|
267
|
+
time.sleep(0.1)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Optional Advisory Checks in Agent Sandboxes
|
|
271
|
+
|
|
272
|
+
AI CLI subprocesses may run with outbound network disabled even when the user's
|
|
273
|
+
normal terminal has network access. Prefer local CLI probes over optional
|
|
274
|
+
network probes when the local CLI already exposes the needed information.
|
|
275
|
+
|
|
276
|
+
**Rule 1**: Do not let a failed optional advisory check consume a once-per-session
|
|
277
|
+
marker. Write the marker only after the script resolves a usable value and can
|
|
278
|
+
make the intended decision. Otherwise a transient sandbox/network failure hides
|
|
279
|
+
the hint for the rest of the session.
|
|
280
|
+
|
|
281
|
+
**Rule 2**: If a local command can provide the needed value, try it with a short
|
|
282
|
+
timeout and captured output. For example, `trellis --version` already runs the
|
|
283
|
+
CLI's version comparison logic and can support an actionable update prompt
|
|
284
|
+
without duplicating npm registry parsing.
|
|
285
|
+
|
|
286
|
+
**Rule 3**: Keep advisory checks silent on failure. The user-facing context output
|
|
287
|
+
must not fail or become noisy because an advisory check could not complete.
|
|
288
|
+
|
|
289
|
+
### 6. File Encoding
|
|
290
|
+
|
|
291
|
+
| Default Encoding | macOS/Linux | Windows |
|
|
292
|
+
|------------------|-------------|---------|
|
|
293
|
+
| Terminal | UTF-8 | Often CP1252 or GBK |
|
|
294
|
+
| File I/O | UTF-8 | System locale |
|
|
295
|
+
| Git output | UTF-8 | May vary |
|
|
296
|
+
|
|
297
|
+
**Rule**: Always explicitly specify `encoding="utf-8"` and use `errors="replace"`.
|
|
298
|
+
|
|
299
|
+
> **Checklist**: When writing scripts that print non-ASCII, did you configure stdout encoding?
|
|
300
|
+
> See `backend/script-conventions.md` for the specific pattern.
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
# BAD - Relies on system default
|
|
304
|
+
with open(file, "r") as f:
|
|
305
|
+
content = f.read()
|
|
306
|
+
|
|
307
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
308
|
+
|
|
309
|
+
# GOOD - Explicit encoding with error handling
|
|
310
|
+
with open(file, "r", encoding="utf-8", errors="replace") as f:
|
|
311
|
+
content = f.read()
|
|
312
|
+
|
|
313
|
+
result = subprocess.run(
|
|
314
|
+
cmd,
|
|
315
|
+
capture_output=True,
|
|
316
|
+
text=True,
|
|
317
|
+
encoding="utf-8",
|
|
318
|
+
errors="replace"
|
|
319
|
+
)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Git commands**: Force UTF-8 output encoding:
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
# Force git to output UTF-8
|
|
326
|
+
git_args = ["git", "-c", "i18n.logOutputEncoding=UTF-8"] + args
|
|
327
|
+
result = subprocess.run(
|
|
328
|
+
git_args,
|
|
329
|
+
capture_output=True,
|
|
330
|
+
text=True,
|
|
331
|
+
encoding="utf-8",
|
|
332
|
+
errors="replace"
|
|
333
|
+
)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Change Propagation Checklist
|
|
339
|
+
|
|
340
|
+
When making platform-related changes, check **all these locations**:
|
|
341
|
+
|
|
342
|
+
### Commands / Skills Sync
|
|
343
|
+
- [ ] New command/skill added to ALL platforms (claude, cursor, iflow, codex, and any new platform)
|
|
344
|
+
- [ ] Each platform's test file updated with new entry in `EXPECTED_COMMAND_NAMES` / `EXPECTED_SKILL_NAMES`
|
|
345
|
+
- [ ] Platform-integration spec's required command table updated if adding a new required command
|
|
346
|
+
- [ ] Command format matches platform convention (see `platform-integration.md` → Command Format by Platform)
|
|
347
|
+
|
|
348
|
+
### Documentation & Help Text
|
|
349
|
+
- [ ] Docstrings at top of Python files
|
|
350
|
+
- [ ] `--help` output / argparse descriptions
|
|
351
|
+
- [ ] Usage examples in README
|
|
352
|
+
- [ ] Error messages that suggest commands
|
|
353
|
+
- [ ] Markdown documentation (`.md` files)
|
|
354
|
+
|
|
355
|
+
### Code Locations
|
|
356
|
+
- [ ] `src/templates/` - Template files for new projects
|
|
357
|
+
- [ ] `.trellis/scripts/` - Project's own scripts (if self-hosting)
|
|
358
|
+
- [ ] `dist/` - Built output (rebuild after changes)
|
|
359
|
+
|
|
360
|
+
### Search Pattern
|
|
361
|
+
```bash
|
|
362
|
+
# Find all places that might need updating
|
|
363
|
+
grep -r "python [a-z]" --include="*.py" --include="*.md"
|
|
364
|
+
grep -r "{{PYTHON_CMD}}\\|python3\\|python " --include="*.py" --include="*.md"
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Pre-Commit Checklist
|
|
370
|
+
|
|
371
|
+
Before committing cross-platform code:
|
|
372
|
+
|
|
373
|
+
- [ ] User-facing Python invocations are platform-aware (`python` on Windows, `python3` elsewhere) or use `{{PYTHON_CMD}}`
|
|
374
|
+
- [ ] Python subprocesses from Python use `sys.executable`
|
|
375
|
+
- [ ] All paths use `pathlib.Path`
|
|
376
|
+
- [ ] No hardcoded path separators (`/` or `\`)
|
|
377
|
+
- [ ] Path strings used as logical/persisted keys (Map keys, JSON fields, hash dictionary keys) are normalized via `toPosix()`; `fs.*` calls keep OS-native paths
|
|
378
|
+
- [ ] Content hashes computed across OSes normalize line endings (`\r\n` → `\n`) before hashing
|
|
379
|
+
- [ ] Cross-OS JSON with potential legacy pollution carries a `__version` sentinel and the loader discards unknown/legacy versions
|
|
380
|
+
- [ ] No platform-specific commands without fallbacks (e.g., `tail -f`)
|
|
381
|
+
- [ ] Optional advisory checks do not burn once-per-session markers on failure
|
|
382
|
+
- [ ] All file I/O specifies `encoding="utf-8"` and `errors="replace"`
|
|
383
|
+
- [ ] All subprocess calls specify `encoding="utf-8"` and `errors="replace"`
|
|
384
|
+
- [ ] Git commands use `-c i18n.logOutputEncoding=UTF-8`
|
|
385
|
+
- [ ] External tool API formats verified from documentation
|
|
386
|
+
- [ ] Documentation matches code behavior
|
|
387
|
+
- [ ] Ran search to find all affected locations
|
|
388
|
+
|
|
389
|
+
### 7. External Tool API Contracts
|
|
390
|
+
|
|
391
|
+
When integrating with external tools (Claude Code, Cursor, etc.), their API contracts are **implicit assumptions**.
|
|
392
|
+
|
|
393
|
+
**Rule**: Verify API formats from official documentation, don't guess.
|
|
394
|
+
|
|
395
|
+
```python
|
|
396
|
+
# BAD - Guessed format
|
|
397
|
+
output = {"continue": True, "message": "..."}
|
|
398
|
+
|
|
399
|
+
# GOOD - Verified format from documentation
|
|
400
|
+
output = {
|
|
401
|
+
"hookSpecificOutput": {
|
|
402
|
+
"hookEventName": "SessionStart",
|
|
403
|
+
"additionalContext": "..."
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
> **Warning**: Different hook types may have different output formats.
|
|
409
|
+
> Always check the specific documentation for each hook event.
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## Cross-Platform Persisted JSON: Schema Migration Sentinel
|
|
414
|
+
|
|
415
|
+
When a JSON file may be read/written across OSes (committed to git, synced via cloud, copied between machines) **and an older format may already exist on user disks with cross-platform pollution** (Windows-style keys, CRLF-derived hashes, locale-encoded strings), add a `__version` sentinel and let the loader discard old formats so the writer regenerates clean data.
|
|
416
|
+
|
|
417
|
+
**Why not migrate-in-place?** Path-key migration (`\\` → `/`) plus hash-input migration (CRLF → LF re-hash) plus encoding fixes are correlated — trying to translate the old payload risks producing wrong values. Discarding and regenerating is **safe**: the data is recomputable from disk, and `loadX` returning `{}` triggers the existing init/update path to rebuild canonical entries.
|
|
418
|
+
|
|
419
|
+
```typescript
|
|
420
|
+
const SCHEMA_VERSION = 2;
|
|
421
|
+
type StoredV2 = { __version: number; hashes: Record<string, string> };
|
|
422
|
+
|
|
423
|
+
export function loadHashes(cwd: string): Record<string, string> {
|
|
424
|
+
const file = getHashesPath(cwd);
|
|
425
|
+
if (!fs.existsSync(file)) return {};
|
|
426
|
+
|
|
427
|
+
try {
|
|
428
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf-8")) as unknown;
|
|
429
|
+
|
|
430
|
+
// Reject legacy flat format (no __version) and unknown versions.
|
|
431
|
+
// The next saveHashes / initializeHashes will write a fresh v2 file.
|
|
432
|
+
if (
|
|
433
|
+
!parsed ||
|
|
434
|
+
typeof parsed !== "object" ||
|
|
435
|
+
(parsed as StoredV2).__version !== SCHEMA_VERSION ||
|
|
436
|
+
typeof (parsed as StoredV2).hashes !== "object"
|
|
437
|
+
) {
|
|
438
|
+
return {};
|
|
439
|
+
}
|
|
440
|
+
return (parsed as StoredV2).hashes;
|
|
441
|
+
} catch {
|
|
442
|
+
return {};
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
export function saveHashes(cwd: string, hashes: Record<string, string>): void {
|
|
447
|
+
const payload: StoredV2 = { __version: SCHEMA_VERSION, hashes };
|
|
448
|
+
fs.writeFileSync(getHashesPath(cwd), JSON.stringify(payload, null, 2));
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**When to apply**:
|
|
453
|
+
- Hash dictionaries / content fingerprints (e.g., `.template-hashes.json`)
|
|
454
|
+
- Cache files where stale entries are recomputable from authoritative source
|
|
455
|
+
- Any cross-OS persisted file where format change correlates with cross-platform fixes
|
|
456
|
+
|
|
457
|
+
**When NOT to apply** — if losing the data hurts the user (task state, drafts, settings the user typed). Use real migration there. Sentinel + discard is only safe when data is recomputable.
|
|
458
|
+
|
|
459
|
+
**Reference**: `packages/cli/src/utils/template-hash.ts` v2 envelope.
|
|
460
|
+
|
|
461
|
+
---
|
|
462
|
+
|
|
463
|
+
## JSON/External Data Defensive Checks
|
|
464
|
+
|
|
465
|
+
When parsing JSON or external data, TypeScript types are **compile-time only**. Runtime data may not match.
|
|
466
|
+
|
|
467
|
+
**Rule**: Always add defensive checks for required fields before using them.
|
|
468
|
+
|
|
469
|
+
```typescript
|
|
470
|
+
// BAD - Trusts TypeScript type definition
|
|
471
|
+
interface MigrationItem {
|
|
472
|
+
from: string; // TypeScript says required
|
|
473
|
+
to?: string;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function process(item: MigrationItem) {
|
|
477
|
+
const path = item.from; // Runtime: could be undefined!
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// GOOD - Defensive check before use
|
|
481
|
+
function process(item: MigrationItem) {
|
|
482
|
+
if (!item.from) return; // Skip invalid data
|
|
483
|
+
const path = item.from; // Now guaranteed
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**When to apply**:
|
|
488
|
+
- Parsing JSON files (manifests, configs)
|
|
489
|
+
- API responses
|
|
490
|
+
- User input
|
|
491
|
+
- Any data from external sources
|
|
492
|
+
|
|
493
|
+
**Pattern**: Check existence → then use
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
// Filter pattern - skip invalid items
|
|
497
|
+
const validItems = items.filter(item => item.from && item.to);
|
|
498
|
+
|
|
499
|
+
// Early return pattern - bail on invalid
|
|
500
|
+
if (!data.requiredField) {
|
|
501
|
+
console.warn("Missing required field");
|
|
502
|
+
return defaultValue;
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Common Mistakes
|
|
509
|
+
|
|
510
|
+
### 1. "It works on my Mac"
|
|
511
|
+
|
|
512
|
+
```python
|
|
513
|
+
# Developer's Mac
|
|
514
|
+
subprocess.run(["./script.py"]) # Works!
|
|
515
|
+
|
|
516
|
+
# User's Windows
|
|
517
|
+
subprocess.run(["./script.py"]) # FileNotFoundError
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### 2. "The shebang should handle it"
|
|
521
|
+
|
|
522
|
+
```python
|
|
523
|
+
#!/usr/bin/env python3
|
|
524
|
+
# This line is IGNORED on Windows
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
### 3. "I updated the template"
|
|
528
|
+
|
|
529
|
+
```
|
|
530
|
+
src/templates/script.py ← Updated
|
|
531
|
+
.trellis/scripts/script.py ← Forgot to sync!
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### 4. "Python 3 is always python3"
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
# Developer's Mac/Linux
|
|
538
|
+
python3 script.py # Works!
|
|
539
|
+
|
|
540
|
+
# User's Windows (Python from python.org)
|
|
541
|
+
python3 script.py # 'python3' is not recognized
|
|
542
|
+
python script.py # Works!
|
|
543
|
+
|
|
544
|
+
# Trellis docs/config should say the rule, not guess one alias everywhere
|
|
545
|
+
{{PYTHON_CMD}} script.py
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### 5. "UTF-8 is the default everywhere"
|
|
549
|
+
|
|
550
|
+
```python
|
|
551
|
+
# Developer's Mac (UTF-8 default)
|
|
552
|
+
subprocess.run(cmd, capture_output=True, text=True) # Works!
|
|
553
|
+
|
|
554
|
+
# User's Windows (GBK/CP1252 default)
|
|
555
|
+
subprocess.run(cmd, capture_output=True, text=True) # Garbled Chinese/Unicode
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
> **Note**: stdout encoding is also affected. See `backend/script-conventions.md` for the fix.
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Recovery: When You Find a Platform Bug
|
|
563
|
+
|
|
564
|
+
1. **Fix the immediate issue**
|
|
565
|
+
2. **Search for similar patterns** (grep the codebase)
|
|
566
|
+
3. **Update this guide** with the new pattern
|
|
567
|
+
4. **Add to pre-commit checklist** if recurring
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
**Core Principle**: If it's not explicit, it's an assumption. And assumptions break.
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## Release Checklist: Versioned Files
|
|
576
|
+
|
|
577
|
+
When releasing a new version, ensure **all versioned files** are created/updated:
|
|
578
|
+
|
|
579
|
+
- [ ] `src/migrations/manifests/{version}.json` - Migration manifest exists
|
|
580
|
+
- [ ] Manifest has correct version, description, changelog
|
|
581
|
+
- [ ] `pnpm build` copies manifests to `dist/`
|
|
582
|
+
- [ ] Test upgrade path from older versions (not just adjacent)
|
|
583
|
+
|
|
584
|
+
**Why this matters**: Missing manifests cause "path undefined" errors when users upgrade from older versions.
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
# Verify all expected manifests exist
|
|
588
|
+
ls src/migrations/manifests/
|
|
589
|
+
|
|
590
|
+
# Test upgrade path
|
|
591
|
+
node -e "
|
|
592
|
+
const { getMigrationsForVersion } = require('./dist/migrations/index.js');
|
|
593
|
+
console.log('From 0.2.12:', getMigrationsForVersion('0.2.12', 'CURRENT').length);
|
|
594
|
+
"
|
|
595
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# 思考指南
|
|
2
|
+
|
|
3
|
+
> **作用**:扩展你的思考范围,帮助你提前发现可能遗漏的问题。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 为什么需要思考指南?
|
|
8
|
+
|
|
9
|
+
**大多数 bug 和技术债并不是因为能力不够,而是因为“没想到这一层”**:
|
|
10
|
+
|
|
11
|
+
- 没想到层与层之间会怎样交互 → 跨层 bug
|
|
12
|
+
- 没想到代码模式正在重复 → 到处都是重复代码
|
|
13
|
+
- 没想到边界情况 → 运行时错误
|
|
14
|
+
- 没想到未来维护者 → 代码难以理解
|
|
15
|
+
|
|
16
|
+
这些指南的目标,是帮助你在编码前**问对问题**。
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 可用指南
|
|
21
|
+
|
|
22
|
+
| 指南 | 作用 | 适用场景 |
|
|
23
|
+
|------|------|----------|
|
|
24
|
+
| [代码复用思考指南](./code-reuse-thinking-guide.md) | 识别重复模式,减少重复实现 | 当你注意到相似模式反复出现时 |
|
|
25
|
+
| [跨层思考指南](./cross-layer-thinking-guide.md) | 梳理多层之间的数据流与职责边界 | 涉及多个层级的功能开发 |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 快速参考:什么时候该主动思考
|
|
30
|
+
|
|
31
|
+
### 什么时候该检查跨层问题
|
|
32
|
+
|
|
33
|
+
- [ ] 功能会同时触及 3 层及以上(API、Service、Component、Database)
|
|
34
|
+
- [ ] 数据格式在不同层之间发生变化
|
|
35
|
+
- [ ] 多个消费方需要同一份数据
|
|
36
|
+
- [ ] 你不确定某段逻辑应该放在哪一层
|
|
37
|
+
- [ ] 你正在新增 event kind、JSONL record、RPC payload 或配置字段
|
|
38
|
+
- [ ] UI / 命令层代码开始直接强转原始 payload 字段
|
|
39
|
+
|
|
40
|
+
→ 阅读 [跨层思考指南](./cross-layer-thinking-guide.md)
|
|
41
|
+
|
|
42
|
+
### 什么时候该检查代码复用
|
|
43
|
+
|
|
44
|
+
- [ ] 你写的代码和现有代码很像
|
|
45
|
+
- [ ] 你看到相同模式重复了 3 次以上
|
|
46
|
+
- [ ] 你正在给多个位置新增同一个字段
|
|
47
|
+
- [ ] **你正在修改任何常量或配置**
|
|
48
|
+
- [ ] **你准备新建 utility/helper 函数** ← 先搜索现有实现!
|
|
49
|
+
- [ ] 两个文件都在用本地强转读取同一份未类型化 payload 字段
|
|
50
|
+
- [ ] 多个分支都在根据 \`kind\` / \`action\` 更新同一份派生状态
|
|
51
|
+
|
|
52
|
+
→ 阅读 [代码复用思考指南](./code-reuse-thinking-guide.md)
|
|
53
|
+
|
|
54
|
+
### 什么时候该复核 AI 交叉审查结果
|
|
55
|
+
|
|
56
|
+
- [ ] 审查器说“用户输入可能是恶意的” → 先确认真实数据源(内部清单?用户配置?外部 API?)
|
|
57
|
+
- [ ] 审查器说“缺少校验” → 先判断数据是不是来自可信内部来源
|
|
58
|
+
- [ ] 审查器说“行为变化了” → 先看代码注释,这是否本来就是刻意设计
|
|
59
|
+
- [ ] 审查器在测试里指出“bug” → 心里先删除被测功能,再看测试是否仍然能过;如果能,那就是自证型测试
|
|
60
|
+
|
|
61
|
+
**AI 审查常见误报模式**:
|
|
62
|
+
1. **信任边界混淆**:把内部数据(如随包分发的 JSON manifest)误当成外部不可信输入
|
|
63
|
+
2. **忽略设计注释**:把代码注释里明确说明的有意行为当成 bug
|
|
64
|
+
3. **变量理解错误**:没有一路追踪变量的真实定义(例如 Map 实际按 path 而不是 name 建索引)
|
|
65
|
+
|
|
66
|
+
**复核规则**:每个 CRITICAL/WARNING 结论都必须先回到真实代码核对后再决定优先级。AI 审查保守估计约有 35% 误报率。
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 修改前规则(关键)
|
|
71
|
+
|
|
72
|
+
> **改任何值之前,一定先搜索!**
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 先搜索你准备修改的值
|
|
76
|
+
grep -r "value_to_change" .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
这个习惯能避免大多数“漏改另一处”的 bug。
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 如何使用这个目录
|
|
84
|
+
|
|
85
|
+
1. **编码前**:快速浏览相关思考指南
|
|
86
|
+
2. **编码中**:如果感觉开始重复或复杂,回来对照指南
|
|
87
|
+
3. **出 bug 后**:把新学到的教训补进对应指南
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 如何贡献
|
|
92
|
+
|
|
93
|
+
如果你遇到了新的“没想到这一层”的问题,就把它补充到最相关的指南里。
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
**核心原则**:提前思考 30 分钟,往往能省下 3 小时调试时间。
|