@draht/coding-agent 2026.3.2-2
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/CHANGELOG.md +2866 -0
- package/README.md +566 -0
- package/bin/draht-tools.cjs +912 -0
- package/dist/cli/args.d.ts +48 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +298 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +14 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +79 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +92 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/session-picker.d.ts +9 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +34 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +85 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +235 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-session.d.ts +571 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +2343 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/auth-storage.d.ts +129 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +394 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +47 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +212 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +86 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +242 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +121 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +607 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +35 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +138 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +15 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +71 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +34 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +222 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +971 -0
- package/dist/core/export-html/template.html +54 -0
- package/dist/core/export-html/template.js +1586 -0
- package/dist/core/export-html/tool-renderer.d.ts +35 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +57 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/extensions/index.d.ts +11 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +25 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +415 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +146 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +645 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1011 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +35 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +27 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +102 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +32 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +134 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/keybindings.d.ts +55 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +153 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/messages.d.ts +77 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +123 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-registry.d.ts +112 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +534 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +104 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +432 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/package-manager.d.ts +151 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +1447 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +50 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +268 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +17 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +59 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +184 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +670 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/sdk.d.ts +90 -0
- package/dist/core/sdk.d.ts.map +1 -0
- package/dist/core/sdk.js +235 -0
- package/dist/core/sdk.js.map +1 -0
- package/dist/core/session-manager.d.ts +323 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +1098 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/settings-manager.d.ts +225 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +653 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +58 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +364 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +15 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +22 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/system-prompt.d.ts +24 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +137 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/timings.d.ts +7 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +25 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +55 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +242 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +63 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +243 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +39 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +146 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/find.d.ts +39 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +206 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +45 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +239 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/index.d.ts +73 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +61 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +40 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +118 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +8 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +81 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/read.d.ts +39 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +166 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +70 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +205 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/write.d.ts +29 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +78 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/extensions/gsd-commands.ts +338 -0
- package/dist/extensions/subagent.ts +312 -0
- package/dist/hooks/gsd/draht-post-phase.js +133 -0
- package/dist/hooks/gsd/draht-post-task.js +132 -0
- package/dist/hooks/gsd/draht-pre-execute.js +146 -0
- package/dist/hooks/gsd/draht-quality-gate.js +210 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +812 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +33 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +261 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/index.d.ts +9 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +8 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/interactive/components/armin.d.ts +34 -0
- package/dist/modes/interactive/components/armin.d.ts.map +1 -0
- package/dist/modes/interactive/components/armin.js +333 -0
- package/dist/modes/interactive/components/armin.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +96 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +35 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +162 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +51 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +44 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +71 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +479 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +70 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +79 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
- package/dist/modes/interactive/components/daxnuts.js +140 -0
- package/dist/modes/interactive/components/daxnuts.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +133 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +21 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +17 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +102 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +78 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +26 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +213 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +32 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -0
- package/dist/modes/interactive/components/index.js +33 -0
- package/dist/modes/interactive/components/index.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +41 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +61 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +145 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +47 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +271 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +97 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +275 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +155 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +851 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +56 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +287 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +35 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +46 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +47 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +75 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +752 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +68 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +934 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +113 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +8 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +16 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +315 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +3719 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +84 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +78 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme.js +944 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -0
- package/dist/modes/print-mode.d.ts +28 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +101 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +217 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +405 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +511 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +409 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/prompts/agents/build.md +44 -0
- package/dist/prompts/agents/plan.md +39 -0
- package/dist/prompts/agents/verify.md +33 -0
- package/dist/prompts/commands/atomic-commit.md +39 -0
- package/dist/prompts/commands/discuss-phase.md +25 -0
- package/dist/prompts/commands/execute-phase.md +59 -0
- package/dist/prompts/commands/map-codebase.md +32 -0
- package/dist/prompts/commands/new-project.md +40 -0
- package/dist/prompts/commands/pause-work.md +12 -0
- package/dist/prompts/commands/plan-phase.md +61 -0
- package/dist/prompts/commands/progress.md +12 -0
- package/dist/prompts/commands/quick.md +19 -0
- package/dist/prompts/commands/resume-work.md +13 -0
- package/dist/prompts/commands/verify-work.md +27 -0
- package/dist/utils/changelog.d.ts +21 -0
- package/dist/utils/changelog.d.ts.map +1 -0
- package/dist/utils/changelog.js +87 -0
- package/dist/utils/changelog.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +162 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +7 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -0
- package/dist/utils/clipboard-native.js +14 -0
- package/dist/utils/clipboard-native.js.map +1 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +67 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/git.d.ts +26 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +163 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/image-convert.d.ts +9 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +35 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-resize.d.ts +36 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +181 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +26 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/photon.d.ts +21 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +121 -0
- package/dist/utils/photon.js.map +1 -0
- package/dist/utils/shell.d.ts +26 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +186 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +3 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +251 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/docs/compaction.md +390 -0
- package/docs/custom-provider.md +580 -0
- package/docs/development.md +69 -0
- package/docs/extensions.md +1952 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/json.md +79 -0
- package/docs/keybindings.md +174 -0
- package/docs/models.md +293 -0
- package/docs/packages.md +209 -0
- package/docs/prompt-templates.md +67 -0
- package/docs/providers.md +186 -0
- package/docs/rpc.md +1317 -0
- package/docs/sdk.md +968 -0
- package/docs/session.md +412 -0
- package/docs/settings.md +223 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +231 -0
- package/docs/terminal-setup.md +70 -0
- package/docs/termux.md +127 -0
- package/docs/themes.md +295 -0
- package/docs/tree.md +219 -0
- package/docs/tui.md +887 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +25 -0
- package/examples/extensions/README.md +204 -0
- package/examples/extensions/antigravity-image-gen.ts +413 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/built-in-tool-renderer.ts +246 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +114 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
- package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +132 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/handoff.ts +150 -0
- package/examples/extensions/hello.ts +25 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +426 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +881 -0
- package/examples/extensions/overlay-test.ts +150 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +340 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +398 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/qna.ts +119 -0
- package/examples/extensions/question.ts +264 -0
- package/examples/extensions/questionnaire.ts +427 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +124 -0
- package/examples/extensions/sandbox/index.ts +318 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/sst-resource-manager.ts +203 -0
- package/examples/extensions/status-line.ts +40 -0
- package/examples/extensions/subagent/README.md +172 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +964 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +195 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +299 -0
- package/examples/extensions/tool-override.ts +143 -0
- package/examples/extensions/tools.ts +146 -0
- package/examples/extensions/trigger-compact.ts +40 -0
- package/examples/extensions/truncated-tool.ts +192 -0
- package/examples/extensions/widget-placement.ts +17 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/rpc-extension-ui.ts +632 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +55 -0
- package/examples/sdk/04-skills.ts +46 -0
- package/examples/sdk/05-tools.ts +56 -0
- package/examples/sdk/06-extensions.ts +88 -0
- package/examples/sdk/07-context-files.ts +40 -0
- package/examples/sdk/08-prompt-templates.ts +42 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/examples/sdk/10-settings.ts +51 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +82 -0
- package/examples/sdk/README.md +144 -0
- package/extensions/gsd-commands.ts +338 -0
- package/extensions/subagent.ts +312 -0
- package/hooks/gsd/draht-post-phase.js +133 -0
- package/hooks/gsd/draht-post-task.js +132 -0
- package/hooks/gsd/draht-pre-execute.js +146 -0
- package/hooks/gsd/draht-quality-gate.js +210 -0
- package/package.json +105 -0
- package/prompts/agents/build.md +44 -0
- package/prompts/agents/plan.md +39 -0
- package/prompts/agents/verify.md +33 -0
- package/prompts/commands/atomic-commit.md +39 -0
- package/prompts/commands/discuss-phase.md +25 -0
- package/prompts/commands/execute-phase.md +59 -0
- package/prompts/commands/map-codebase.md +32 -0
- package/prompts/commands/new-project.md +40 -0
- package/prompts/commands/pause-work.md +12 -0
- package/prompts/commands/plan-phase.md +61 -0
- package/prompts/commands/progress.md +12 -0
- package/prompts/commands/quick.md +19 -0
- package/prompts/commands/resume-work.md +13 -0
- package/prompts/commands/verify-work.md +27 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Draht Post-Phase Hook
|
|
6
|
+
* Runs after phase completion to generate reports and update state.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node gsd-post-phase.js <phase-number>
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require("node:fs");
|
|
12
|
+
const path = require("node:path");
|
|
13
|
+
|
|
14
|
+
const phaseNum = process.argv[2];
|
|
15
|
+
if (!phaseNum) {
|
|
16
|
+
console.error("Usage: gsd-post-phase.js <phase-number>");
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const PLANNING = ".planning";
|
|
21
|
+
const LOG_FILE = path.join(PLANNING, "execution-log.jsonl");
|
|
22
|
+
|
|
23
|
+
// 1. Read execution log for this phase
|
|
24
|
+
let entries = [];
|
|
25
|
+
if (fs.existsSync(LOG_FILE)) {
|
|
26
|
+
entries = fs.readFileSync(LOG_FILE, "utf-8")
|
|
27
|
+
.split("\n")
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
.map((l) => JSON.parse(l))
|
|
30
|
+
.filter((e) => e.phase === parseInt(phaseNum, 10));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const passed = entries.filter((e) => e.status === "pass").length;
|
|
34
|
+
const failed = entries.filter((e) => e.status === "fail").length;
|
|
35
|
+
const skipped = entries.filter((e) => e.status === "skip").length;
|
|
36
|
+
const warnings = entries.filter((e) => e.warning).length;
|
|
37
|
+
|
|
38
|
+
// 2. Compute TDD and domain health metrics
|
|
39
|
+
const tddViolations = entries.filter((e) => e.status === "tdd-violation").length;
|
|
40
|
+
|
|
41
|
+
// TDD commit counts: derive from git log scoped to commits since phase start
|
|
42
|
+
// (use the earliest entry timestamp as the lower bound)
|
|
43
|
+
let tddSummary = "⚠️ No TDD commit data in log";
|
|
44
|
+
try {
|
|
45
|
+
const { execSync } = require("node:child_process");
|
|
46
|
+
// Scope to commits that follow TDD naming convention for this phase
|
|
47
|
+
const gitLog = execSync(
|
|
48
|
+
`git log --format=%s --grep="^[0-9]" -E --extended-regexp 2>/dev/null || git log --format=%s 2>/dev/null`,
|
|
49
|
+
{ encoding: "utf-8" }
|
|
50
|
+
).trim();
|
|
51
|
+
const lines = gitLog.split("\n");
|
|
52
|
+
const redCount = lines.filter((l) => /^red:/i.test(l)).length;
|
|
53
|
+
const greenCount = lines.filter((l) => /^green:/i.test(l)).length;
|
|
54
|
+
const refactorCount = lines.filter((l) => /^refactor:/i.test(l)).length;
|
|
55
|
+
if (redCount + greenCount + refactorCount > 0) {
|
|
56
|
+
tddSummary = `🔴 Red: ${redCount} 🟢 Green: ${greenCount} 🔵 Refactor: ${refactorCount}`;
|
|
57
|
+
} else {
|
|
58
|
+
tddSummary = "⚠️ No red:/green:/refactor: commits found — TDD cycle may not have been followed";
|
|
59
|
+
}
|
|
60
|
+
} catch { /* ignore */ }
|
|
61
|
+
|
|
62
|
+
// Domain health: check DOMAIN.md presence and glossary size
|
|
63
|
+
let domainSummary = "⚠️ .planning/DOMAIN.md not found";
|
|
64
|
+
const domainPath = path.join(PLANNING, "DOMAIN.md");
|
|
65
|
+
if (fs.existsSync(domainPath)) {
|
|
66
|
+
const domainContent = fs.readFileSync(domainPath, "utf-8");
|
|
67
|
+
const termMatches = [...domainContent.matchAll(/\b([A-Z][a-zA-Z0-9]+)\b/g)];
|
|
68
|
+
const termCount = new Set(termMatches.map((m) => m[1])).size;
|
|
69
|
+
const hasContexts = domainContent.includes("## Bounded Contexts");
|
|
70
|
+
const hasGlossary = domainContent.includes("## Ubiquitous Language");
|
|
71
|
+
domainSummary = `${hasContexts ? "✅" : "❌"} Bounded Contexts ${hasGlossary ? "✅" : "❌"} Ubiquitous Language 📖 ~${termCount} terms`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// TEST-STRATEGY health
|
|
75
|
+
let testStrategySummary = "⚠️ .planning/TEST-STRATEGY.md not found";
|
|
76
|
+
if (fs.existsSync(path.join(PLANNING, "TEST-STRATEGY.md"))) {
|
|
77
|
+
testStrategySummary = "✅ TEST-STRATEGY.md present";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 3. Generate phase report
|
|
81
|
+
const reportPath = path.join(PLANNING, `phase-${phaseNum}-report.md`);
|
|
82
|
+
const report = `# Phase ${phaseNum} Execution Report
|
|
83
|
+
|
|
84
|
+
Generated: ${new Date().toISOString().replace("T", " ").slice(0, 19)}
|
|
85
|
+
|
|
86
|
+
## Task Results
|
|
87
|
+
- ✅ Passed: ${passed}
|
|
88
|
+
- ❌ Failed: ${failed}
|
|
89
|
+
- ⏭️ Skipped: ${skipped}
|
|
90
|
+
- ⚠️ Warnings: ${warnings}
|
|
91
|
+
|
|
92
|
+
## Execution Log
|
|
93
|
+
| Timestamp | Plan | Task | Status | Commit |
|
|
94
|
+
|-----------|------|------|--------|--------|
|
|
95
|
+
${entries.map((e) => `| ${e.timestamp.slice(0, 19)} | ${e.plan} | ${e.task} | ${e.status} | ${e.commit || "-"} |`).join("\n")}
|
|
96
|
+
|
|
97
|
+
## Quality Gate
|
|
98
|
+
${failed === 0 ? "✅ All tasks passed — ready for verification" : `❌ ${failed} failure(s) — fix plans may be needed`}
|
|
99
|
+
${warnings > 0 ? `⚠️ ${warnings} task(s) introduced type errors` : "✅ No type errors introduced"}
|
|
100
|
+
|
|
101
|
+
## TDD Health
|
|
102
|
+
${tddSummary}
|
|
103
|
+
${tddViolations > 0 ? `❌ ${tddViolations} TDD cycle violation(s) recorded (green: without red:)` : "✅ No TDD cycle violations recorded"}
|
|
104
|
+
|
|
105
|
+
## Domain Model Health
|
|
106
|
+
${domainSummary}
|
|
107
|
+
${testStrategySummary}
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
fs.writeFileSync(reportPath, report);
|
|
111
|
+
console.log(`Phase ${phaseNum} report: ${reportPath}`);
|
|
112
|
+
|
|
113
|
+
// 4. Update ROADMAP.md status
|
|
114
|
+
const roadmapPath = path.join(PLANNING, "ROADMAP.md");
|
|
115
|
+
if (fs.existsSync(roadmapPath)) {
|
|
116
|
+
let roadmap = fs.readFileSync(roadmapPath, "utf-8");
|
|
117
|
+
const newStatus = failed === 0 ? "complete" : "needs-fixes";
|
|
118
|
+
const regex = new RegExp(`(## Phase ${phaseNum}:.+?)— \`\\w+\``, "m");
|
|
119
|
+
roadmap = roadmap.replace(regex, `$1— \`${newStatus}\``);
|
|
120
|
+
fs.writeFileSync(roadmapPath, roadmap);
|
|
121
|
+
console.log(`ROADMAP.md: Phase ${phaseNum} → ${newStatus}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 5. Summary
|
|
125
|
+
console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
126
|
+
console.log(` Draht ► PHASE ${phaseNum} ${failed === 0 ? "COMPLETE ✅" : "NEEDS FIXES ❌"}`);
|
|
127
|
+
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
128
|
+
console.log(`\n${passed} passed, ${failed} failed, ${skipped} skipped`);
|
|
129
|
+
if (failed === 0) {
|
|
130
|
+
console.log(`\nNext: gsd-verify-work ${phaseNum}`);
|
|
131
|
+
} else {
|
|
132
|
+
console.log(`\nNext: gsd-execute-phase ${phaseNum} --gaps-only`);
|
|
133
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Draht Post-Task Hook
|
|
6
|
+
* Runs after each task execution to validate and record results.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node gsd-post-task.js <phase> <plan> <task-num> <status> [commit-hash]
|
|
9
|
+
* Status: pass | fail | skip
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require("node:fs");
|
|
13
|
+
const path = require("node:path");
|
|
14
|
+
const { execSync } = require("node:child_process");
|
|
15
|
+
|
|
16
|
+
const [phaseNum, planNum, taskNum, status, commitHash] = process.argv.slice(2);
|
|
17
|
+
if (!phaseNum || !planNum || !taskNum || !status) {
|
|
18
|
+
console.error("Usage: gsd-post-task.js <phase> <plan> <task-num> <status> [commit-hash]");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const PLANNING = ".planning";
|
|
23
|
+
const LOG_FILE = path.join(PLANNING, "execution-log.jsonl");
|
|
24
|
+
|
|
25
|
+
// 0. TDD cycle compliance check
|
|
26
|
+
// If the current commit message starts with "green:", the previous commit for this
|
|
27
|
+
// task should start with "red:" — enforce the Red → Green order.
|
|
28
|
+
if (commitHash) {
|
|
29
|
+
try {
|
|
30
|
+
// Find the commit message for commitHash and the one before it
|
|
31
|
+
const currentMsg = execSync(`git log --format=%s -n 1 ${commitHash} 2>/dev/null`, { encoding: "utf-8" }).trim();
|
|
32
|
+
if (/^green:/i.test(currentMsg)) {
|
|
33
|
+
// Scope search to commits that mention this phase/plan/task in their message
|
|
34
|
+
// to avoid false positives from unrelated older commits
|
|
35
|
+
const taskPrefix = `${phaseNum}-${planNum}-${taskNum}`;
|
|
36
|
+
const recentMsgs = execSync(`git log --format=%s -n 50 ${commitHash}~1 2>/dev/null`, { encoding: "utf-8" })
|
|
37
|
+
.trim()
|
|
38
|
+
.split("\n")
|
|
39
|
+
.filter((m) => m.includes(taskPrefix) || /^(red|green|refactor):/i.test(m));
|
|
40
|
+
// Find the nearest TDD-cycle commit scoped to this task
|
|
41
|
+
const prevTaskMsg = recentMsgs.find((m) => /^(red|green|refactor):/i.test(m) && m.includes(taskPrefix));
|
|
42
|
+
if (!prevTaskMsg || !/^red:/i.test(prevTaskMsg)) {
|
|
43
|
+
console.log(`⚠️ TDD violation: "green:" commit detected but no preceding "red:" commit found for task ${phaseNum}-${planNum}-${taskNum}`);
|
|
44
|
+
fs.appendFileSync(LOG_FILE, JSON.stringify({
|
|
45
|
+
timestamp: new Date().toISOString(),
|
|
46
|
+
phase: parseInt(phaseNum, 10),
|
|
47
|
+
plan: parseInt(planNum, 10),
|
|
48
|
+
task: parseInt(taskNum, 10),
|
|
49
|
+
status: "tdd-violation",
|
|
50
|
+
warning: "green: commit without preceding red: commit",
|
|
51
|
+
commit: commitHash,
|
|
52
|
+
}) + "\n");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// Not a git repo or commit not found — ignore
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 1. Append to execution log
|
|
61
|
+
const entry = {
|
|
62
|
+
timestamp: new Date().toISOString(),
|
|
63
|
+
phase: parseInt(phaseNum, 10),
|
|
64
|
+
plan: parseInt(planNum, 10),
|
|
65
|
+
task: parseInt(taskNum, 10),
|
|
66
|
+
status,
|
|
67
|
+
commit: commitHash || null,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
fs.appendFileSync(LOG_FILE, JSON.stringify(entry) + "\n");
|
|
71
|
+
|
|
72
|
+
// 2. Run type check if status is pass
|
|
73
|
+
if (status === "pass") {
|
|
74
|
+
try {
|
|
75
|
+
execSync("bun run tsgo --noEmit 2>&1", { timeout: 30000, encoding: "utf-8" });
|
|
76
|
+
// Run tests
|
|
77
|
+
try {
|
|
78
|
+
const testOutput = execSync("bun test 2>&1", { timeout: 60000, encoding: "utf-8" });
|
|
79
|
+
const testMatch = testOutput.match(/(\d+) pass/);
|
|
80
|
+
const testCount = testMatch ? testMatch[1] : "?";
|
|
81
|
+
console.log(`✅ Task ${phaseNum}-${planNum}-${taskNum}: passed + types clean + ${testCount} tests pass`);
|
|
82
|
+
} catch (testErr) {
|
|
83
|
+
const testOut = testErr.stdout || testErr.stderr || "";
|
|
84
|
+
const failMatch = testOut.match(/(\d+) fail/);
|
|
85
|
+
if (failMatch) {
|
|
86
|
+
console.log(`⚠️ Task ${phaseNum}-${planNum}-${taskNum}: passed + types clean but ${failMatch[1]} test(s) failed`);
|
|
87
|
+
} else {
|
|
88
|
+
console.log(`✅ Task ${phaseNum}-${planNum}-${taskNum}: passed + types clean (no test runner found)`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
const output = error.stdout || "";
|
|
93
|
+
const errorCount = (output.match(/error TS/g) || []).length;
|
|
94
|
+
if (errorCount > 0) {
|
|
95
|
+
console.log(`⚠️ Task ${phaseNum}-${planNum}-${taskNum}: passed but ${errorCount} type error(s) introduced`);
|
|
96
|
+
// Append warning to log
|
|
97
|
+
fs.appendFileSync(LOG_FILE, JSON.stringify({
|
|
98
|
+
...entry,
|
|
99
|
+
warning: `${errorCount} type errors introduced`,
|
|
100
|
+
}) + "\n");
|
|
101
|
+
} else {
|
|
102
|
+
console.log(`✅ Task ${phaseNum}-${planNum}-${taskNum}: passed`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} else if (status === "fail") {
|
|
106
|
+
console.log(`❌ Task ${phaseNum}-${planNum}-${taskNum}: FAILED`);
|
|
107
|
+
|
|
108
|
+
// Check if we should create a fix plan
|
|
109
|
+
const logContent = fs.readFileSync(LOG_FILE, "utf-8");
|
|
110
|
+
const taskFailures = logContent.split("\n")
|
|
111
|
+
.filter(Boolean)
|
|
112
|
+
.map((l) => JSON.parse(l))
|
|
113
|
+
.filter((e) => e.phase === parseInt(phaseNum, 10) && e.plan === parseInt(planNum, 10) && e.task === parseInt(taskNum, 10) && e.status === "fail");
|
|
114
|
+
|
|
115
|
+
if (taskFailures.length >= 3) {
|
|
116
|
+
console.log(`\n⚠️ Task has failed 3+ times. Consider creating a fix plan:`);
|
|
117
|
+
console.log(` draht create-fix-plan ${phaseNum} ${planNum} "Task ${taskNum} failed repeatedly"`);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
console.log(`⏭️ Task ${phaseNum}-${planNum}-${taskNum}: skipped`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 3. Update STATE.md last activity
|
|
124
|
+
const statePath = path.join(PLANNING, "STATE.md");
|
|
125
|
+
if (fs.existsSync(statePath)) {
|
|
126
|
+
let state = fs.readFileSync(statePath, "utf-8");
|
|
127
|
+
state = state.replace(
|
|
128
|
+
/## Last Activity:.*/,
|
|
129
|
+
`## Last Activity: ${new Date().toISOString().replace("T", " ").slice(0, 19)}`
|
|
130
|
+
);
|
|
131
|
+
fs.writeFileSync(statePath, state);
|
|
132
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Draht Pre-Execute Hook
|
|
6
|
+
* Runs before gsd-execute-phase to validate preconditions.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node gsd-pre-execute.js <phase-number>
|
|
9
|
+
* Exit 0 = proceed, Exit 1 = abort
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require("node:fs");
|
|
13
|
+
const path = require("node:path");
|
|
14
|
+
const { execSync } = require("node:child_process");
|
|
15
|
+
|
|
16
|
+
const phaseNum = process.argv[2];
|
|
17
|
+
if (!phaseNum) {
|
|
18
|
+
console.error("Usage: gsd-pre-execute.js <phase-number>");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const PLANNING = ".planning";
|
|
23
|
+
const errors = [];
|
|
24
|
+
const warnings = [];
|
|
25
|
+
|
|
26
|
+
// 1. Check .planning/ exists
|
|
27
|
+
if (!fs.existsSync(PLANNING)) {
|
|
28
|
+
errors.push("No .planning/ directory found. Run gsd-new-project first.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. Check STATE.md exists
|
|
32
|
+
if (!fs.existsSync(path.join(PLANNING, "STATE.md"))) {
|
|
33
|
+
errors.push("No STATE.md found. Project not initialized.");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 3. Check ROADMAP.md exists and phase is defined
|
|
37
|
+
const roadmapPath = path.join(PLANNING, "ROADMAP.md");
|
|
38
|
+
if (fs.existsSync(roadmapPath)) {
|
|
39
|
+
const roadmap = fs.readFileSync(roadmapPath, "utf-8");
|
|
40
|
+
if (!roadmap.includes(`Phase ${phaseNum}`)) {
|
|
41
|
+
errors.push(`Phase ${phaseNum} not found in ROADMAP.md`);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
errors.push("No ROADMAP.md found.");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 4. Check phase directory exists with plans
|
|
48
|
+
const phasesDir = path.join(PLANNING, "phases");
|
|
49
|
+
if (fs.existsSync(phasesDir)) {
|
|
50
|
+
const entries = fs.readdirSync(phasesDir);
|
|
51
|
+
const phaseDir = entries.find((e) => e.startsWith(String(phaseNum).padStart(2, "0") + "-"));
|
|
52
|
+
if (!phaseDir) {
|
|
53
|
+
errors.push(`No phase directory found for phase ${phaseNum}. Run gsd-plan-phase first.`);
|
|
54
|
+
} else {
|
|
55
|
+
const phaseFiles = fs.readdirSync(path.join(phasesDir, phaseDir));
|
|
56
|
+
const plans = phaseFiles.filter((f) => f.endsWith("-PLAN.md") && !f.includes("FIX"));
|
|
57
|
+
if (plans.length === 0) {
|
|
58
|
+
errors.push(`No plans found in phase ${phaseNum}. Run gsd-plan-phase first.`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check plans have required elements
|
|
62
|
+
for (const planFile of plans) {
|
|
63
|
+
const content = fs.readFileSync(path.join(phasesDir, phaseDir, planFile), "utf-8");
|
|
64
|
+
if (!content.includes("<task")) {
|
|
65
|
+
warnings.push(`${planFile}: No <task> elements — plan may be incomplete`);
|
|
66
|
+
}
|
|
67
|
+
if (!content.includes("<verify>")) {
|
|
68
|
+
warnings.push(`${planFile}: Missing <verify> steps — tasks won't be verifiable`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// 5. Check git status
|
|
75
|
+
try {
|
|
76
|
+
const status = execSync("git status --porcelain", { encoding: "utf-8" }).trim();
|
|
77
|
+
if (status) {
|
|
78
|
+
const lines = status.split("\n").length;
|
|
79
|
+
warnings.push(`${lines} uncommitted file(s) — consider committing first`);
|
|
80
|
+
}
|
|
81
|
+
} catch {
|
|
82
|
+
warnings.push("Not a git repository — no commit tracking");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 6. Check for CONTINUE-HERE.md (unfinished session)
|
|
86
|
+
if (fs.existsSync(path.join(PLANNING, "CONTINUE-HERE.md"))) {
|
|
87
|
+
warnings.push("CONTINUE-HERE.md exists — previous session may be unfinished. Consider gsd-resume-work.");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 7. Check DOMAIN.md exists and has required sections
|
|
91
|
+
const domainPath = path.join(PLANNING, "DOMAIN.md");
|
|
92
|
+
if (!fs.existsSync(domainPath)) {
|
|
93
|
+
warnings.push("No .planning/DOMAIN.md found — domain model not documented. Run /new-project or /map-codebase to create it.");
|
|
94
|
+
} else {
|
|
95
|
+
const domainContent = fs.readFileSync(domainPath, "utf-8");
|
|
96
|
+
if (!domainContent.includes("## Bounded Contexts")) {
|
|
97
|
+
errors.push("DOMAIN.md is missing '## Bounded Contexts' section.");
|
|
98
|
+
}
|
|
99
|
+
if (!domainContent.includes("## Ubiquitous Language")) {
|
|
100
|
+
errors.push("DOMAIN.md is missing '## Ubiquitous Language' section.");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 8. Check TEST-STRATEGY.md exists
|
|
105
|
+
if (!fs.existsSync(path.join(PLANNING, "TEST-STRATEGY.md"))) {
|
|
106
|
+
warnings.push("No .planning/TEST-STRATEGY.md found — test strategy not documented. Run /new-project or /map-codebase to create it.");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 9. Check all plans have non-empty <test> sections
|
|
110
|
+
if (fs.existsSync(phasesDir)) {
|
|
111
|
+
const entries2 = fs.readdirSync(phasesDir);
|
|
112
|
+
const phaseDir2 = entries2.find((e) => e.startsWith(String(phaseNum).padStart(2, "0") + "-"));
|
|
113
|
+
if (phaseDir2) {
|
|
114
|
+
const phaseFiles2 = fs.readdirSync(path.join(phasesDir, phaseDir2));
|
|
115
|
+
const plans2 = phaseFiles2.filter((f) => f.endsWith("-PLAN.md") && !f.includes("FIX"));
|
|
116
|
+
for (const planFile of plans2) {
|
|
117
|
+
const content = fs.readFileSync(path.join(phasesDir, phaseDir2, planFile), "utf-8");
|
|
118
|
+
// Extract all <test>...</test> blocks and check they are non-empty
|
|
119
|
+
const testMatches = [...content.matchAll(/<test>([\s\S]*?)<\/test>/g)];
|
|
120
|
+
if (testMatches.length === 0) {
|
|
121
|
+
errors.push(`${planFile}: Missing <test> sections — TDD requires tests for every task`);
|
|
122
|
+
} else {
|
|
123
|
+
for (const m of testMatches) {
|
|
124
|
+
if (!m[1].trim()) {
|
|
125
|
+
errors.push(`${planFile}: Empty <test> section found — fill in test cases before executing`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Output
|
|
134
|
+
if (warnings.length > 0) {
|
|
135
|
+
console.log(`⚠️ ${warnings.length} warning(s):`);
|
|
136
|
+
for (const w of warnings) console.log(` - ${w}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (errors.length > 0) {
|
|
140
|
+
console.log(`\n❌ ${errors.length} error(s) — cannot proceed:`);
|
|
141
|
+
for (const e of errors) console.log(` - ${e}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(`✅ Pre-execute checks passed for phase ${phaseNum}`);
|
|
146
|
+
process.exit(0);
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Draht Quality Gate Hook
|
|
6
|
+
* Runs after task completion to enforce quality standards.
|
|
7
|
+
* Called by the build agent after each verify step.
|
|
8
|
+
*
|
|
9
|
+
* Usage: node gsd-quality-gate.js [--strict]
|
|
10
|
+
* Exit 0 = quality OK, Exit 1 = quality issues
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const { execSync } = require("node:child_process");
|
|
14
|
+
const fs = require("node:fs");
|
|
15
|
+
|
|
16
|
+
const strict = process.argv.includes("--strict");
|
|
17
|
+
const issues = [];
|
|
18
|
+
|
|
19
|
+
// 1. TypeScript check
|
|
20
|
+
try {
|
|
21
|
+
execSync("bun run tsgo --noEmit 2>&1", { timeout: 60000, encoding: "utf-8" });
|
|
22
|
+
} catch (error) {
|
|
23
|
+
const output = error.stdout || error.stderr || "";
|
|
24
|
+
const errorCount = (output.match(/error TS/g) || []).length;
|
|
25
|
+
if (errorCount > 0) {
|
|
26
|
+
issues.push({ severity: strict ? "error" : "warning", message: `${errorCount} TypeScript error(s)`, details: output.slice(0, 500) });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// 2. Biome lint check (if biome.json exists)
|
|
31
|
+
if (fs.existsSync("biome.json")) {
|
|
32
|
+
try {
|
|
33
|
+
execSync("bunx biome check --error-on-warnings . 2>&1", { timeout: 30000, encoding: "utf-8" });
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const output = error.stdout || error.stderr || "";
|
|
36
|
+
issues.push({ severity: strict ? "error" : "warning", message: "Biome lint issues", details: output.slice(0, 500) });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 3. Run tests
|
|
41
|
+
try {
|
|
42
|
+
const testOutput = execSync("bun test 2>&1", { timeout: 120000, encoding: "utf-8" });
|
|
43
|
+
const failMatch = testOutput.match(/(\d+) fail/);
|
|
44
|
+
if (failMatch && parseInt(failMatch[1], 10) > 0) {
|
|
45
|
+
issues.push({ severity: strict ? "error" : "warning", message: `${failMatch[1]} test(s) failing` });
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
const output = error.stdout || error.stderr || "";
|
|
49
|
+
const failMatch = output.match(/(\d+) fail/);
|
|
50
|
+
if (failMatch && parseInt(failMatch[1], 10) > 0) {
|
|
51
|
+
issues.push({ severity: strict ? "error" : "warning", message: `${failMatch[1]} test(s) failing` });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// 4. Check for console.log in source files (not tests)
|
|
56
|
+
try {
|
|
57
|
+
const result = execSync(
|
|
58
|
+
"grep -rn 'console\\.log' src/ --include='*.ts' --include='*.tsx' 2>/dev/null | grep -v '// debug' | head -5",
|
|
59
|
+
{ encoding: "utf-8" }
|
|
60
|
+
).trim();
|
|
61
|
+
if (result) {
|
|
62
|
+
issues.push({ severity: "warning", message: `console.log found in source`, details: result });
|
|
63
|
+
}
|
|
64
|
+
} catch { /* grep returns 1 when no match — that's good */ }
|
|
65
|
+
|
|
66
|
+
// 5. Domain glossary compliance
|
|
67
|
+
// Extract terms from DOMAIN.md and flag new PascalCase classes not in the glossary
|
|
68
|
+
const domainMdPath = ".planning/DOMAIN.md";
|
|
69
|
+
if (fs.existsSync(domainMdPath)) {
|
|
70
|
+
try {
|
|
71
|
+
const domainContent = fs.readFileSync(domainMdPath, "utf-8");
|
|
72
|
+
// Collect all PascalCase tokens that appear in the glossary section
|
|
73
|
+
const glossarySection = domainContent.match(/## Ubiquitous Language([\s\S]*?)(?:^##|\Z)/m)?.[1] || "";
|
|
74
|
+
// Each glossary entry is assumed to start the line with a PascalCase term (e.g. "**Order**" or "- Order:")
|
|
75
|
+
const glossaryTerms = new Set(
|
|
76
|
+
[...glossarySection.matchAll(/\b([A-Z][a-zA-Z0-9]+)\b/g)].map((m) => m[1])
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Scan changed source files for PascalCase class/interface/type declarations
|
|
80
|
+
try {
|
|
81
|
+
const changedFiles = execSync(
|
|
82
|
+
"git diff --cached --name-only 2>/dev/null || git diff --name-only HEAD~1",
|
|
83
|
+
{ encoding: "utf-8" }
|
|
84
|
+
).trim().split("\n").filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
85
|
+
|
|
86
|
+
const unknownTerms = [];
|
|
87
|
+
for (const file of changedFiles) {
|
|
88
|
+
if (!fs.existsSync(file)) continue;
|
|
89
|
+
const src = fs.readFileSync(file, "utf-8");
|
|
90
|
+
const declarations = [...src.matchAll(/(?:class|interface|type|enum)\s+([A-Z][a-zA-Z0-9]+)/g)].map((m) => m[1]);
|
|
91
|
+
for (const term of declarations) {
|
|
92
|
+
if (!glossaryTerms.has(term)) {
|
|
93
|
+
unknownTerms.push(`${file}: ${term}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (unknownTerms.length > 0) {
|
|
98
|
+
issues.push({
|
|
99
|
+
severity: "warning",
|
|
100
|
+
message: `${unknownTerms.length} PascalCase type(s) not in DOMAIN.md glossary`,
|
|
101
|
+
details: unknownTerms.slice(0, 5).join(", "),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch { /* ignore git errors */ }
|
|
105
|
+
} catch { /* ignore read errors */ }
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 6. Bounded context boundary check — flag suspicious cross-directory imports
|
|
109
|
+
try {
|
|
110
|
+
const changedSrcFiles = execSync(
|
|
111
|
+
"git diff --cached --name-only 2>/dev/null || git diff --name-only HEAD~1",
|
|
112
|
+
{ encoding: "utf-8" }
|
|
113
|
+
).trim().split("\n").filter((f) => /^src\/[^/]+\//.test(f) && (f.endsWith(".ts") || f.endsWith(".tsx")));
|
|
114
|
+
|
|
115
|
+
const crossContextImports = [];
|
|
116
|
+
for (const file of changedSrcFiles) {
|
|
117
|
+
if (!fs.existsSync(file)) continue;
|
|
118
|
+
// Determine this file's context (first path segment under src/)
|
|
119
|
+
const ownContext = file.split("/")[1];
|
|
120
|
+
const src = fs.readFileSync(file, "utf-8");
|
|
121
|
+
const imports = [...src.matchAll(/from\s+['"](\.\.\/.+?)['"]/g)].map((m) => m[1]);
|
|
122
|
+
for (const imp of imports) {
|
|
123
|
+
// Resolve relative import against the file's directory
|
|
124
|
+
const resolved = path.normalize(path.join(path.dirname(file), imp));
|
|
125
|
+
const parts = resolved.split(path.sep);
|
|
126
|
+
const srcIdx = parts.indexOf("src");
|
|
127
|
+
if (srcIdx !== -1 && parts[srcIdx + 1] && parts[srcIdx + 1] !== ownContext) {
|
|
128
|
+
crossContextImports.push(`${file} → ${parts.slice(srcIdx).join("/")}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (crossContextImports.length > 0) {
|
|
133
|
+
issues.push({
|
|
134
|
+
severity: "warning",
|
|
135
|
+
message: `${crossContextImports.length} suspicious cross-context import(s) detected`,
|
|
136
|
+
details: crossContextImports.slice(0, 3).join("; "),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
} catch { /* ignore */ }
|
|
140
|
+
|
|
141
|
+
// 7. TDD health — check test-to-source file ratio
|
|
142
|
+
try {
|
|
143
|
+
const allSrc = execSync(
|
|
144
|
+
"find src -name '*.ts' -not -name '*.test.ts' -not -name '*.spec.ts' 2>/dev/null | wc -l",
|
|
145
|
+
{ encoding: "utf-8" }
|
|
146
|
+
).trim();
|
|
147
|
+
const allTests = execSync(
|
|
148
|
+
"find src -name '*.test.ts' -o -name '*.spec.ts' 2>/dev/null | wc -l",
|
|
149
|
+
{ encoding: "utf-8" }
|
|
150
|
+
).trim();
|
|
151
|
+
const srcCount = parseInt(allSrc, 10) || 0;
|
|
152
|
+
const testCount = parseInt(allTests, 10) || 0;
|
|
153
|
+
if (srcCount > 0) {
|
|
154
|
+
const ratio = testCount / srcCount;
|
|
155
|
+
if (ratio < 0.3) {
|
|
156
|
+
issues.push({
|
|
157
|
+
severity: "warning",
|
|
158
|
+
message: `TDD health: test-to-source ratio is ${(ratio * 100).toFixed(0)}% (${testCount} tests / ${srcCount} sources) — target ≥ 30%`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} catch { /* ignore — src/ may not exist */ }
|
|
163
|
+
|
|
164
|
+
// 8. Check for TODO/FIXME/HACK comments in changed files
|
|
165
|
+
try {
|
|
166
|
+
const diff = execSync("git diff --cached --name-only 2>/dev/null || git diff --name-only HEAD~1", { encoding: "utf-8" }).trim();
|
|
167
|
+
if (diff) {
|
|
168
|
+
const files = diff.split("\n").filter((f) => f.endsWith(".ts") || f.endsWith(".tsx"));
|
|
169
|
+
for (const file of files) {
|
|
170
|
+
try {
|
|
171
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
172
|
+
const todos = content.match(/\/\/\s*(TODO|FIXME|HACK|XXX):/gi) || [];
|
|
173
|
+
if (todos.length > 0) {
|
|
174
|
+
issues.push({ severity: "info", message: `${file}: ${todos.length} TODO/FIXME comment(s)` });
|
|
175
|
+
}
|
|
176
|
+
} catch { /* file may not exist */ }
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
} catch { /* ignore */ }
|
|
180
|
+
|
|
181
|
+
// Output
|
|
182
|
+
const errors = issues.filter((i) => i.severity === "error");
|
|
183
|
+
const warnings = issues.filter((i) => i.severity === "warning");
|
|
184
|
+
const infos = issues.filter((i) => i.severity === "info");
|
|
185
|
+
|
|
186
|
+
if (errors.length > 0) {
|
|
187
|
+
console.log(`\n❌ Quality Gate FAILED (${errors.length} error(s)):`);
|
|
188
|
+
for (const e of errors) {
|
|
189
|
+
console.log(` ❌ ${e.message}`);
|
|
190
|
+
if (e.details) console.log(` ${e.details.split("\n")[0]}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (warnings.length > 0) {
|
|
195
|
+
console.log(`\n⚠️ ${warnings.length} warning(s):`);
|
|
196
|
+
for (const w of warnings) {
|
|
197
|
+
console.log(` ⚠️ ${w.message}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (infos.length > 0) {
|
|
202
|
+
console.log(`\nℹ️ ${infos.length} note(s):`);
|
|
203
|
+
for (const i of infos) console.log(` ℹ️ ${i.message}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (errors.length === 0 && warnings.length === 0) {
|
|
207
|
+
console.log("✅ Quality gate passed");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
process.exit(errors.length > 0 ? 1 : 0);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { getAgentDir, VERSION } from "./config.js";
|
|
2
|
+
export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type AgentSessionEventListener, type ModelCycleResult, type ParsedSkillBlock, type PromptOptions, parseSkillBlock, type SessionStats, } from "./core/agent-session.js";
|
|
3
|
+
export { type ApiKeyCredential, type AuthCredential, AuthStorage, type AuthStorageBackend, FileAuthStorageBackend, InMemoryAuthStorageBackend, type OAuthCredential, } from "./core/auth-storage.js";
|
|
4
|
+
export { type BranchPreparation, type BranchSummaryResult, type CollectEntriesResult, type CompactionResult, type CutPointResult, calculateContextTokens, collectEntriesForBranchSummary, compact, DEFAULT_COMPACTION_SETTINGS, estimateTokens, type FileOperations, findCutPoint, findTurnStartIndex, type GenerateBranchSummaryOptions, generateBranchSummary, generateSummary, getLastAssistantUsage, prepareBranchEntries, serializeConversation, shouldCompact, } from "./core/compaction/index.js";
|
|
5
|
+
export { createEventBus, type EventBus, type EventBusController } from "./core/event-bus.js";
|
|
6
|
+
export type { AgentEndEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppAction, BashToolCallEvent, BeforeAgentStartEvent, CompactOptions, ContextEvent, ContextUsage, CustomToolCallEvent, EditToolCallEvent, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, GrepToolCallEvent, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, MessageRenderer, MessageRenderOptions, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, RegisteredCommand, RegisteredTool, SessionBeforeCompactEvent, SessionBeforeForkEvent, SessionBeforeSwitchEvent, SessionBeforeTreeEvent, SessionCompactEvent, SessionForkEvent, SessionShutdownEvent, SessionStartEvent, SessionSwitchEvent, SessionTreeEvent, SlashCommandInfo, SlashCommandLocation, SlashCommandSource, TerminalInputHandler, ToolCallEvent, ToolDefinition, ToolInfo, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WriteToolCallEvent, } from "./core/extensions/index.js";
|
|
7
|
+
export { createExtensionRuntime, discoverAndLoadExtensions, ExtensionRunner, isBashToolResult, isEditToolResult, isFindToolResult, isGrepToolResult, isLsToolResult, isReadToolResult, isToolCallEventType, isWriteToolResult, wrapRegisteredTool, wrapRegisteredTools, wrapToolsWithExtensions, wrapToolWithExtensions, } from "./core/extensions/index.js";
|
|
8
|
+
export type { ReadonlyFooterDataProvider } from "./core/footer-data-provider.js";
|
|
9
|
+
export { convertToLlm } from "./core/messages.js";
|
|
10
|
+
export { ModelRegistry } from "./core/model-registry.js";
|
|
11
|
+
export type { PackageManager, PathMetadata, ProgressCallback, ProgressEvent, ResolvedPaths, ResolvedResource, } from "./core/package-manager.js";
|
|
12
|
+
export { DefaultPackageManager } from "./core/package-manager.js";
|
|
13
|
+
export type { ResourceCollision, ResourceDiagnostic, ResourceLoader } from "./core/resource-loader.js";
|
|
14
|
+
export { DefaultResourceLoader } from "./core/resource-loader.js";
|
|
15
|
+
export { type CreateAgentSessionOptions, type CreateAgentSessionResult, createAgentSession, createBashTool, createCodingTools, createEditTool, createFindTool, createGrepTool, createLsTool, createReadOnlyTools, createReadTool, createWriteTool, type PromptTemplate, readOnlyTools, } from "./core/sdk.js";
|
|
16
|
+
export { type BranchSummaryEntry, buildSessionContext, type CompactionEntry, CURRENT_SESSION_VERSION, type CustomEntry, type CustomMessageEntry, type FileEntry, getLatestCompactionEntry, type ModelChangeEntry, migrateSessionEntries, type NewSessionOptions, parseSessionEntries, type SessionContext, type SessionEntry, type SessionEntryBase, type SessionHeader, type SessionInfo, type SessionInfoEntry, SessionManager, type SessionMessageEntry, type ThinkingLevelChangeEntry, } from "./core/session-manager.js";
|
|
17
|
+
export { type CompactionSettings, type ImageSettings, type PackageSource, type RetrySettings, SettingsManager, } from "./core/settings-manager.js";
|
|
18
|
+
export { formatSkillsForPrompt, type LoadSkillsFromDirOptions, type LoadSkillsResult, loadSkills, loadSkillsFromDir, type Skill, type SkillFrontmatter, } from "./core/skills.js";
|
|
19
|
+
export { type BashOperations, type BashSpawnContext, type BashSpawnHook, type BashToolDetails, type BashToolInput, type BashToolOptions, bashTool, codingTools, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type EditOperations, type EditToolDetails, type EditToolInput, type EditToolOptions, editTool, type FindOperations, type FindToolDetails, type FindToolInput, type FindToolOptions, findTool, formatSize, type GrepOperations, type GrepToolDetails, type GrepToolInput, type GrepToolOptions, grepTool, type LsOperations, type LsToolDetails, type LsToolInput, type LsToolOptions, lsTool, type ReadOperations, type ReadToolDetails, type ReadToolInput, type ReadToolOptions, readTool, type ToolsOptions, type TruncationOptions, type TruncationResult, truncateHead, truncateLine, truncateTail, type WriteOperations, type WriteToolInput, type WriteToolOptions, writeTool, } from "./core/tools/index.js";
|
|
20
|
+
export { main } from "./main.js";
|
|
21
|
+
export { InteractiveMode, type InteractiveModeOptions, type PrintModeOptions, runPrintMode, runRpcMode, } from "./modes/index.js";
|
|
22
|
+
export { ArminComponent, AssistantMessageComponent, appKey, appKeyHint, BashExecutionComponent, BorderedLoader, BranchSummaryMessageComponent, CompactionSummaryMessageComponent, CustomEditor, CustomMessageComponent, DynamicBorder, ExtensionEditorComponent, ExtensionInputComponent, ExtensionSelectorComponent, editorKey, FooterComponent, keyHint, LoginDialogComponent, ModelSelectorComponent, OAuthSelectorComponent, type RenderDiffOptions, rawKeyHint, renderDiff, SessionSelectorComponent, type SettingsCallbacks, type SettingsConfig, SettingsSelectorComponent, ShowImagesSelectorComponent, SkillInvocationMessageComponent, ThemeSelectorComponent, ThinkingSelectorComponent, ToolExecutionComponent, type ToolExecutionOptions, TreeSelectorComponent, truncateToVisualLines, UserMessageComponent, UserMessageSelectorComponent, type VisualTruncateResult, } from "./modes/interactive/components/index.js";
|
|
23
|
+
export { getLanguageFromPath, getMarkdownTheme, getSelectListTheme, getSettingsListTheme, highlightCode, initTheme, Theme, type ThemeColor, } from "./modes/interactive/theme/theme.js";
|
|
24
|
+
export { copyToClipboard } from "./utils/clipboard.js";
|
|
25
|
+
export { parseFrontmatter, stripFrontmatter } from "./utils/frontmatter.js";
|
|
26
|
+
export { getShellConfig } from "./utils/shell.js";
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|