aiwcli 0.15.5 → 0.17.0
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/README.md +108 -1124
- package/bin/run.js +0 -4
- package/dist/capabilities/branch/adapters.d.ts +2 -0
- package/dist/capabilities/branch/adapters.js +21 -0
- package/dist/capabilities/branch/contracts.d.ts +57 -0
- package/dist/capabilities/branch/contracts.js +1 -0
- package/dist/capabilities/branch/control-plane.d.ts +2 -0
- package/dist/capabilities/branch/control-plane.js +343 -0
- package/dist/capabilities/branch/runtime-core.d.ts +5 -0
- package/dist/capabilities/branch/runtime-core.js +36 -0
- package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
- package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
- package/dist/capabilities/installation/control-plane/clear-command.d.ts +162 -0
- package/dist/capabilities/installation/control-plane/clear-command.js +1249 -0
- package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
- package/dist/capabilities/installation/control-plane/init-command.js +449 -0
- package/dist/capabilities/launch/contracts.d.ts +86 -0
- package/dist/capabilities/launch/contracts.js +1 -0
- package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
- package/dist/capabilities/launch/control-plane/execute-launch.js +261 -0
- package/dist/capabilities/launch/runtime-core/launch-decisions.d.ts +82 -0
- package/dist/capabilities/launch/runtime-core/launch-decisions.js +202 -0
- package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
- package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
- package/dist/cli/base-command.d.ts +18 -0
- package/dist/cli/base-command.js +55 -0
- package/dist/commands/branch.d.ts +1 -21
- package/dist/commands/branch.js +25 -417
- package/dist/commands/clean.d.ts +1 -41
- package/dist/commands/clean.js +1 -196
- package/dist/commands/clear.d.ts +1 -161
- package/dist/commands/clear.js +1 -1121
- package/dist/commands/init/index.d.ts +1 -98
- package/dist/commands/init/index.js +4 -478
- package/dist/commands/launch.d.ts +32 -12
- package/dist/commands/launch.js +107 -166
- package/dist/lib/claude-settings-types.d.ts +31 -19
- package/dist/lib/config.js +1 -2
- package/dist/lib/context/context-formatter.d.ts +74 -0
- package/dist/lib/context/context-formatter.js +493 -0
- package/dist/lib/context/context-selector.d.ts +42 -0
- package/dist/lib/context/context-selector.js +451 -0
- package/dist/lib/context/context-store.d.ts +100 -0
- package/dist/lib/context/context-store.js +644 -0
- package/dist/lib/context/plan-manager.d.ts +54 -0
- package/dist/lib/context/plan-manager.js +282 -0
- package/dist/lib/context/task-tracker.d.ts +44 -0
- package/dist/lib/context/task-tracker.js +146 -0
- package/dist/lib/core-ide-base.d.ts +4 -0
- package/dist/lib/core-ide-base.js +77 -0
- package/dist/lib/core-installer.d.ts +5 -0
- package/dist/lib/core-installer.js +33 -0
- package/dist/lib/debug.d.ts +0 -10
- package/dist/lib/debug.js +0 -10
- package/dist/lib/env-sanitizer.d.ts +25 -0
- package/dist/lib/env-sanitizer.js +46 -0
- package/dist/lib/errors.d.ts +0 -13
- package/dist/lib/errors.js +0 -15
- package/dist/lib/git-exclude-manager.d.ts +2 -2
- package/dist/lib/git-exclude-manager.js +3 -3
- package/dist/lib/hooks/context-monitor-logic.d.ts +6 -0
- package/dist/lib/hooks/context-monitor-logic.js +25 -0
- package/dist/lib/hooks/hook-utils.d.ts +143 -0
- package/dist/lib/hooks/hook-utils.js +620 -0
- package/dist/lib/hooks/prompt-binding-logic.d.ts +7 -0
- package/dist/lib/hooks/prompt-binding-logic.js +50 -0
- package/dist/lib/hooks/session-end-logic.d.ts +5 -0
- package/dist/lib/hooks/session-end-logic.js +51 -0
- package/dist/lib/hooks-merger.js +25 -19
- package/dist/lib/ide-path-resolver.d.ts +19 -7
- package/dist/lib/ide-path-resolver.js +25 -9
- package/dist/lib/install-state.d.ts +34 -0
- package/dist/lib/install-state.js +154 -0
- package/dist/lib/json-io.d.ts +12 -0
- package/dist/lib/json-io.js +30 -0
- package/dist/lib/lsp-patch.d.ts +12 -0
- package/dist/lib/lsp-patch.js +156 -0
- package/dist/lib/multiplexer.d.ts +65 -0
- package/dist/lib/multiplexer.js +38 -0
- package/dist/lib/multiplexers/psmux.d.ts +55 -0
- package/dist/lib/multiplexers/psmux.js +324 -0
- package/dist/lib/multiplexers/tmux.d.ts +36 -0
- package/dist/lib/multiplexers/tmux.js +221 -0
- package/dist/lib/multiplexers/wezterm.d.ts +38 -0
- package/dist/lib/multiplexers/wezterm.js +225 -0
- package/dist/lib/mux-utils.d.ts +6 -0
- package/dist/lib/mux-utils.js +36 -0
- package/dist/lib/paths.d.ts +2 -2
- package/dist/lib/paths.js +2 -2
- package/dist/lib/platform-commands.d.ts +27 -0
- package/dist/lib/platform-commands.js +49 -0
- package/dist/lib/prompt-file-manager.d.ts +23 -0
- package/dist/lib/prompt-file-manager.js +41 -0
- package/dist/lib/runtime/agent-launcher.d.ts +67 -0
- package/dist/lib/runtime/agent-launcher.js +262 -0
- package/dist/lib/runtime/aiw-cli.d.ts +39 -0
- package/dist/lib/runtime/aiw-cli.js +76 -0
- package/dist/lib/runtime/atomic-write.d.ts +19 -0
- package/dist/lib/runtime/atomic-write.js +121 -0
- package/dist/lib/runtime/cli-args.d.ts +58 -0
- package/dist/lib/runtime/cli-args.js +200 -0
- package/dist/lib/runtime/constants.d.ts +56 -0
- package/dist/lib/runtime/constants.js +230 -0
- package/dist/lib/runtime/executable-policy.d.ts +16 -0
- package/dist/lib/runtime/executable-policy.js +57 -0
- package/dist/lib/runtime/git-state.d.ts +9 -0
- package/dist/lib/runtime/git-state.js +59 -0
- package/dist/lib/runtime/inference.d.ts +37 -0
- package/dist/lib/runtime/inference.js +251 -0
- package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
- package/dist/lib/runtime/lint-dispatch.js +285 -0
- package/dist/lib/runtime/logger.d.ts +66 -0
- package/dist/lib/runtime/logger.js +201 -0
- package/dist/lib/runtime/models.d.ts +20 -0
- package/dist/lib/runtime/models.js +20 -0
- package/dist/lib/runtime/platform-adapter.d.ts +7 -0
- package/dist/lib/runtime/platform-adapter.js +21 -0
- package/dist/lib/runtime/preflight.d.ts +24 -0
- package/dist/lib/runtime/preflight.js +65 -0
- package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
- package/dist/lib/runtime/sentinel-ipc.js +67 -0
- package/dist/lib/runtime/state-io.d.ts +31 -0
- package/dist/lib/runtime/state-io.js +179 -0
- package/dist/lib/runtime/stop-words.d.ts +20 -0
- package/dist/lib/runtime/stop-words.js +150 -0
- package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
- package/dist/lib/runtime/subprocess-utils.js +96 -0
- package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
- package/dist/lib/runtime/tmux-preflight.js +78 -0
- package/dist/lib/runtime/utils.d.ts +62 -0
- package/dist/lib/runtime/utils.js +192 -0
- package/dist/lib/schemas.d.ts +250 -0
- package/dist/lib/schemas.js +216 -0
- package/dist/lib/sentinel-manager.d.ts +32 -0
- package/dist/lib/sentinel-manager.js +62 -0
- package/dist/lib/sentinel-wrapper.d.ts +10 -0
- package/dist/lib/sentinel-wrapper.js +29 -0
- package/dist/lib/settings-hierarchy.js +3 -20
- package/dist/lib/shell-adapters/bash-adapter.d.ts +18 -0
- package/dist/lib/shell-adapters/bash-adapter.js +69 -0
- package/dist/lib/shell-adapters/index.d.ts +5 -0
- package/dist/lib/shell-adapters/index.js +7 -0
- package/dist/lib/shell-adapters/powershell-adapter.d.ts +18 -0
- package/dist/lib/shell-adapters/powershell-adapter.js +62 -0
- package/dist/lib/shell-adapters/shell-adapter.d.ts +45 -0
- package/dist/lib/shell-adapters/shell-adapter.js +5 -0
- package/dist/lib/shell-quoting.d.ts +5 -0
- package/dist/lib/shell-quoting.js +17 -0
- package/dist/lib/spawn-errors.d.ts +9 -0
- package/dist/lib/spawn-errors.js +29 -0
- package/dist/lib/spawn.js +5 -11
- package/dist/lib/spinner.d.ts +0 -5
- package/dist/lib/spinner.js +0 -16
- package/dist/lib/template-installer.d.ts +14 -5
- package/dist/lib/template-installer.js +40 -38
- package/dist/lib/template-resolver.d.ts +6 -7
- package/dist/lib/template-resolver.js +26 -21
- package/dist/lib/template-settings-reconstructor.d.ts +7 -2
- package/dist/lib/template-settings-reconstructor.js +76 -45
- package/dist/lib/terminal-strategy.d.ts +12 -0
- package/dist/lib/terminal-strategy.js +55 -0
- package/dist/lib/terminal.d.ts +34 -4
- package/dist/lib/terminal.js +192 -119
- package/dist/lib/tmux-pane-placement.d.ts +17 -0
- package/dist/lib/tmux-pane-placement.js +58 -0
- package/dist/lib/tmux-primitives.d.ts +3 -0
- package/dist/lib/tmux-primitives.js +11 -0
- package/dist/lib/tmux-session.d.ts +32 -0
- package/dist/lib/tmux-session.js +87 -0
- package/dist/lib/tty-detection.js +1 -1
- package/dist/lib/types.d.ts +168 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
- package/dist/platform/launch.d.ts +11 -0
- package/dist/platform/launch.js +11 -0
- package/dist/templates/CLAUDE.md +30 -40
- package/dist/templates/cc-native/.claude/settings.json +26 -36
- package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +20 -12
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +2 -6
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +39 -59
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +9 -11
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +4 -5
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +4 -4
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -27
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +7 -7
- package/dist/templates/cc-native/_cc-native/lib-ts/.mocharc.json +9 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/aggregate-agents.test.ts +118 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/artifacts.test.ts +234 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cc-native-state.test.ts +170 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cli-output-parser.test.ts +73 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/config.test.ts +64 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/constants.test.ts +40 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/debug.test.ts +42 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/exports.test.ts +58 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/helpers.ts +107 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/add-plan-context.hook.test.ts +97 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-questions.hook.test.ts +81 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-review.hook.test.ts +71 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/json-parser.test.ts +99 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator-agent.test.ts +288 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator.test.ts +48 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/reviewers.test.ts +32 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/state.test.ts +124 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/verdict.test.ts +93 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -14
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/format.ts +597 -599
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/index.ts +26 -26
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/tracker.ts +106 -107
- package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/write.ts +118 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +17 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
- package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +2 -3
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/graduation.ts +132 -132
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +88 -86
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +5 -6
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/orchestrator.ts +70 -70
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/output-builder.ts +130 -121
- package/dist/templates/cc-native/_cc-native/lib-ts/package-lock.json +1679 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/package.json +24 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +5 -5
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +1 -6
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/plan-questions.ts +101 -101
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/review-pipeline.ts +511 -543
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/__tests__/agent-providers.test.ts +262 -0
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/agent.ts +71 -85
- package/dist/templates/{_shared/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -150
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/index.ts +12 -12
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/claude-agent.ts +66 -57
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/codex-agent.ts +185 -200
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/gemini-agent.ts +39 -40
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/orchestrator-claude-agent.ts +196 -225
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/schemas.ts +201 -201
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/types.ts +21 -23
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/hyde.test.ts +365 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/ollama-client.test.ts +223 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +12 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +3 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +7 -9
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +16 -19
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +37 -41
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +33 -43
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +3 -4
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +50 -126
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -22
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +14 -89
- package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/verdict.ts +72 -72
- package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +38 -1
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
- package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +38 -16
- package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
- package/dist/templates/cc-native/_cc-native/scripts/council_debate.ts +242 -0
- package/dist/templates/cc-native/_cc-native/scripts/council_debate_simple.ts +294 -0
- package/dist/templates/cc-native/_cc-native/{plan-review/workflows → workflows}/specdev.md +9 -9
- package/dist/templates/core/.claude/skills/codex/SKILL.md +25 -0
- package/dist/templates/core/.claude/skills/devin/SKILL.md +25 -0
- package/dist/templates/core/.claude/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.claude/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.claude/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.codex/skills/codex/SKILL.md +13 -0
- package/dist/templates/core/.codex/skills/devin/SKILL.md +19 -0
- package/dist/templates/core/.codex/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.codex/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.codex/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.devin/AGENTS.md +5 -0
- package/dist/templates/core/.devin/config.json +12 -0
- package/dist/templates/core/.devin/skills/codex/SKILL.md +19 -0
- package/dist/templates/core/.devin/skills/devin/SKILL.md +13 -0
- package/dist/templates/core/.devin/skills/handoff/SKILL.md +11 -0
- package/dist/templates/core/.devin/skills/handoff-resume/SKILL.md +11 -0
- package/dist/templates/core/.devin/skills/meta-plan/SKILL.md +13 -0
- package/dist/templates/core/.windsurf/workflows/handoff-resume.md +9 -0
- package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
- package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
- package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
- package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +15 -44
- package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
- package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
- package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +5 -22
- package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
- package/dist/templates/core/hooks-ts/pre_compact.ts +36 -0
- package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
- package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
- package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
- package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
- package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
- package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
- package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
- package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
- package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +59 -20
- package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
- package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
- package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +179 -41
- package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
- package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +82 -0
- package/dist/templates/core/lib-ts/package.json +19 -0
- package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +369 -0
- package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +108 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +24 -8
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
- package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +60 -23
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +9 -2
- package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
- package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +20 -11
- package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
- package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
- package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
- package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +34 -4
- package/dist/templates/core/lib-ts/schemas.ts +233 -0
- package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
- package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
- package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
- package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
- package/dist/templates/core/scripts/resolve-run.ts +93 -0
- package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
- package/dist/templates/{_shared → core}/scripts/status_line.ts +26 -21
- package/dist/templates/core/skills/codex/CLAUDE.md +83 -0
- package/dist/templates/{_shared → core}/skills/codex/SKILL.md +27 -18
- package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +79 -113
- package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +134 -148
- package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
- package/dist/templates/core/skills/devin/CLAUDE.md +122 -0
- package/dist/templates/core/skills/devin/SKILL.md +73 -0
- package/dist/templates/core/skills/devin/lib/devin-watcher.ts +300 -0
- package/dist/templates/core/skills/devin/scripts/launch-devin.ts +258 -0
- package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
- package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
- package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
- package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
- package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
- package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
- package/oclif.manifest.json +89 -13
- package/package.json +13 -12
- package/dist/lib/base-command.d.ts +0 -114
- package/dist/lib/base-command.js +0 -153
- package/dist/lib/env-compat.d.ts +0 -18
- package/dist/lib/env-compat.js +0 -23
- package/dist/lib/stdin.d.ts +0 -48
- package/dist/lib/stdin.js +0 -60
- package/dist/templates/_shared/.claude/settings.json +0 -120
- package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
- package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
- package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
- package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
- package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
- package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +0 -49
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
- package/dist/templates/_shared/lib-ts/agent-exec/backends/headless.ts +0 -33
- package/dist/templates/_shared/lib-ts/agent-exec/backends/index.ts +0 -6
- package/dist/templates/_shared/lib-ts/agent-exec/backends/tmux.ts +0 -119
- package/dist/templates/_shared/lib-ts/agent-exec/execution-backend.ts +0 -50
- package/dist/templates/_shared/lib-ts/agent-exec/index.ts +0 -6
- package/dist/templates/_shared/lib-ts/agent-exec/structured-output.ts +0 -166
- package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
- package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
- package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
- package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
- package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
- package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
- package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
- package/dist/templates/_shared/lib-ts/package.json +0 -20
- package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
- package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
- package/dist/templates/cc-native/_cc-native/CLAUDE.md +0 -73
- package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +0 -64
- package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/CODING-STANDARDS-CHECKLIST.md +0 -75
- package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +0 -143
- package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +0 -213
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +0 -56
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +0 -53
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +0 -70
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +0 -72
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +0 -64
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +0 -56
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +0 -86
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +0 -59
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +0 -58
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +0 -66
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +0 -71
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +0 -74
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +0 -77
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +0 -62
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +0 -68
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +0 -71
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +0 -61
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +0 -67
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +0 -65
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +0 -74
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +0 -69
- package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +0 -172
- package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +0 -7
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BashAdapter — ShellAdapter for bash (Unix + MSYS2/Git Bash on Windows).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import { REPL_NESTING_VARS } from '../env-sanitizer.js';
|
|
6
|
+
import { execFileAsync, findExecutable } from '../runtime/subprocess-utils.js';
|
|
7
|
+
import { wrapSentinelSh } from '../sentinel-wrapper.js';
|
|
8
|
+
import { quoteForSh } from '../shell-quoting.js';
|
|
9
|
+
import { toMsysPosixPath } from '../tmux-primitives.js';
|
|
10
|
+
export class BashAdapter {
|
|
11
|
+
dialect = 'bash';
|
|
12
|
+
quote(value) {
|
|
13
|
+
return quoteForSh(value);
|
|
14
|
+
}
|
|
15
|
+
buildEnvPreamble(env) {
|
|
16
|
+
return Object.entries(env)
|
|
17
|
+
.map(([key, value]) => `${key}=${this.quote(value)}`)
|
|
18
|
+
.join(' ');
|
|
19
|
+
}
|
|
20
|
+
buildToolCommand(params) {
|
|
21
|
+
const { toolPath, args, env, mode, promptPath, promptText } = params;
|
|
22
|
+
const envPrefix = this.buildEnvPreamble(env);
|
|
23
|
+
const commandArgs = this.appendPromptArg(args, mode, promptText);
|
|
24
|
+
const argPart = commandArgs.map((arg) => this.quote(arg)).join(' ');
|
|
25
|
+
const base = [envPrefix, this.quote(toolPath), argPart]
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.join(' ');
|
|
28
|
+
if (mode === 'exec' && promptPath) {
|
|
29
|
+
return `${base} < ${this.quote(promptPath)}`;
|
|
30
|
+
}
|
|
31
|
+
return base;
|
|
32
|
+
}
|
|
33
|
+
wrapSentinel(params) {
|
|
34
|
+
return wrapSentinelSh(params);
|
|
35
|
+
}
|
|
36
|
+
async resolveToolPath(toolName, nativePath) {
|
|
37
|
+
if (process.platform !== 'win32')
|
|
38
|
+
return nativePath;
|
|
39
|
+
// On Windows, resolve tool from bash's perspective (MSYS2/Git Bash PATH)
|
|
40
|
+
const bash = findExecutable('bash');
|
|
41
|
+
if (!bash)
|
|
42
|
+
return null;
|
|
43
|
+
const result = await execFileAsync(bash, ['-lc', `command -v ${toolName}`], {
|
|
44
|
+
timeout: 3000,
|
|
45
|
+
env: { ...process.env, MSYS_NO_PATHCONV: '1' },
|
|
46
|
+
});
|
|
47
|
+
return result.exitCode === 0 ? result.stdout.trim() || null : null;
|
|
48
|
+
}
|
|
49
|
+
buildNestingCleanup() {
|
|
50
|
+
const pathFix = 'export PATH="/usr/bin:/usr/local/bin:/mingw64/bin:$PATH";';
|
|
51
|
+
const unset = `unset ${REPL_NESTING_VARS.join(' ')};`;
|
|
52
|
+
return `${pathFix} ${unset}`;
|
|
53
|
+
}
|
|
54
|
+
normalizeCwd(cwd) {
|
|
55
|
+
return toMsysPosixPath(cwd);
|
|
56
|
+
}
|
|
57
|
+
wrapQuickExitRetry(command, toolPath, thresholdSec = 10) {
|
|
58
|
+
const warmup = `${toolPath} --version >/dev/null 2>&1`;
|
|
59
|
+
return `${warmup}; _qr_t0=$SECONDS; ${command}; if [ $((SECONDS - _qr_t0)) -lt ${thresholdSec} ]; then ${command}; fi`;
|
|
60
|
+
}
|
|
61
|
+
encodeForExecution(command) {
|
|
62
|
+
return command;
|
|
63
|
+
}
|
|
64
|
+
appendPromptArg(args, mode, promptText) {
|
|
65
|
+
if (mode !== 'repl' || promptText === undefined)
|
|
66
|
+
return args;
|
|
67
|
+
return [...args, promptText];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BashAdapter } from './bash-adapter.js';
|
|
2
|
+
export { PowerShellAdapter } from './powershell-adapter.js';
|
|
3
|
+
export type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
|
|
4
|
+
import type { ShellAdapter } from './shell-adapter.js';
|
|
5
|
+
export declare function shellAdapterForBackend(backend: string): ShellAdapter;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { BashAdapter } from './bash-adapter.js';
|
|
2
|
+
export { PowerShellAdapter } from './powershell-adapter.js';
|
|
3
|
+
import { BashAdapter } from './bash-adapter.js';
|
|
4
|
+
import { PowerShellAdapter } from './powershell-adapter.js';
|
|
5
|
+
export function shellAdapterForBackend(backend) {
|
|
6
|
+
return backend === 'psmux' ? new PowerShellAdapter() : new BashAdapter();
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import type { SentinelWrapOptions, ShellAdapter, ToolCommandParams } from './shell-adapter.js';
|
|
6
|
+
export declare class PowerShellAdapter implements ShellAdapter {
|
|
7
|
+
readonly dialect: "powershell";
|
|
8
|
+
quote(value: string): string;
|
|
9
|
+
buildEnvPreamble(env: Record<string, string>): string;
|
|
10
|
+
buildToolCommand(params: ToolCommandParams): string;
|
|
11
|
+
wrapSentinel(params: SentinelWrapOptions): string;
|
|
12
|
+
resolveToolPath(_toolName: string, nativePath: string): Promise<string | null>;
|
|
13
|
+
buildNestingCleanup(): string;
|
|
14
|
+
normalizeCwd(cwd: string): string;
|
|
15
|
+
wrapQuickExitRetry(command: string, _toolPath: string, _thresholdSec?: number): string;
|
|
16
|
+
encodeForExecution(command: string): string;
|
|
17
|
+
private appendPromptArg;
|
|
18
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PowerShellAdapter — ShellAdapter for PowerShell (Windows, psmux backend).
|
|
3
|
+
* Delegates to low-level primitives in shell-quoting.ts, sentinel-wrapper.ts, etc.
|
|
4
|
+
*/
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { REPL_NESTING_VARS } from '../env-sanitizer.js';
|
|
7
|
+
import { buildBootstrapPrompt } from '../mux-utils.js';
|
|
8
|
+
import { wrapSentinelPowerShell } from '../sentinel-wrapper.js';
|
|
9
|
+
import { quoteForPowerShell, toEncodedPowerShell } from '../shell-quoting.js';
|
|
10
|
+
export class PowerShellAdapter {
|
|
11
|
+
dialect = 'powershell';
|
|
12
|
+
quote(value) {
|
|
13
|
+
return quoteForPowerShell(value);
|
|
14
|
+
}
|
|
15
|
+
buildEnvPreamble(env) {
|
|
16
|
+
return Object.entries(env)
|
|
17
|
+
.map(([key, value]) => `$env:${key}=${this.quote(value)}`)
|
|
18
|
+
.join('; ');
|
|
19
|
+
}
|
|
20
|
+
buildToolCommand(params) {
|
|
21
|
+
const { toolPath, args, env, mode, promptPath } = params;
|
|
22
|
+
const envPrefix = this.buildEnvPreamble(env);
|
|
23
|
+
const commandArgs = this.appendPromptArg(args, mode, promptPath);
|
|
24
|
+
const argArray = commandArgs.map((arg) => this.quote(arg)).join(', ');
|
|
25
|
+
const invocation = `& ${this.quote(toolPath)}${argArray ? ` @(${argArray})` : ''}`;
|
|
26
|
+
const body = mode === 'exec' && promptPath
|
|
27
|
+
? `Get-Content -Raw -Path ${this.quote(promptPath)} | ${invocation}`
|
|
28
|
+
: invocation;
|
|
29
|
+
return [envPrefix, body].filter(Boolean).join('; ');
|
|
30
|
+
}
|
|
31
|
+
wrapSentinel(params) {
|
|
32
|
+
return wrapSentinelPowerShell(params);
|
|
33
|
+
}
|
|
34
|
+
async resolveToolPath(_toolName, nativePath) {
|
|
35
|
+
return nativePath;
|
|
36
|
+
}
|
|
37
|
+
buildNestingCleanup() {
|
|
38
|
+
return REPL_NESTING_VARS
|
|
39
|
+
.map((v) => `Remove-Item Env:\\${v} -ErrorAction SilentlyContinue`)
|
|
40
|
+
.join('; ') + ';';
|
|
41
|
+
}
|
|
42
|
+
normalizeCwd(cwd) {
|
|
43
|
+
return cwd;
|
|
44
|
+
}
|
|
45
|
+
wrapQuickExitRetry(command, _toolPath, _thresholdSec) {
|
|
46
|
+
// Quick-exit retry not implemented for PowerShell — inline retry handles it
|
|
47
|
+
return command;
|
|
48
|
+
}
|
|
49
|
+
encodeForExecution(command) {
|
|
50
|
+
return toEncodedPowerShell(command);
|
|
51
|
+
}
|
|
52
|
+
appendPromptArg(args, mode, promptPath) {
|
|
53
|
+
if (mode !== 'repl' || !promptPath)
|
|
54
|
+
return args;
|
|
55
|
+
const absolutePromptPath = path.resolve(promptPath);
|
|
56
|
+
const formatted = process.platform === 'win32'
|
|
57
|
+
? absolutePromptPath.replaceAll('\\', '/')
|
|
58
|
+
: absolutePromptPath;
|
|
59
|
+
const bootstrap = buildBootstrapPrompt(formatted);
|
|
60
|
+
return [...args, bootstrap];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShellAdapter interface — abstracts shell-dialect differences for command building.
|
|
3
|
+
* BashAdapter and PowerShellAdapter implement this for their respective shells.
|
|
4
|
+
*/
|
|
5
|
+
export interface ToolCommandParams {
|
|
6
|
+
toolPath: string;
|
|
7
|
+
args: string[];
|
|
8
|
+
env: Record<string, string>;
|
|
9
|
+
mode: 'exec' | 'repl';
|
|
10
|
+
promptPath?: string | undefined;
|
|
11
|
+
promptText?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface SentinelWrapOptions {
|
|
14
|
+
command: string;
|
|
15
|
+
sentinelPath: string;
|
|
16
|
+
autoClose: boolean;
|
|
17
|
+
autoCloseCommand?: string | undefined;
|
|
18
|
+
holdPane: boolean;
|
|
19
|
+
holdMessage: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ShellAdapter {
|
|
22
|
+
readonly dialect: 'bash' | 'powershell';
|
|
23
|
+
/** Quote a value for safe inclusion in a shell command. */
|
|
24
|
+
quote(value: string): string;
|
|
25
|
+
/** Build env var assignments as a command preamble (KEY=val for bash, $env:KEY=val for PS). */
|
|
26
|
+
buildEnvPreamble(env: Record<string, string>): string;
|
|
27
|
+
/** Build a complete tool invocation command (env + tool + args + prompt handling). */
|
|
28
|
+
buildToolCommand(params: ToolCommandParams): string;
|
|
29
|
+
/** Wrap a command with sentinel exit-code tracking and optional pane hold. */
|
|
30
|
+
wrapSentinel(params: SentinelWrapOptions): string;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve a tool path for the shell dialect.
|
|
33
|
+
* On Windows with bash, resolves via `command -v` in bash.
|
|
34
|
+
* On Unix or PowerShell, returns nativePath as-is.
|
|
35
|
+
*/
|
|
36
|
+
resolveToolPath(toolName: string, nativePath: string): Promise<string | null>;
|
|
37
|
+
/** Build a shell snippet that clears REPL nesting env vars. */
|
|
38
|
+
buildNestingCleanup(): string;
|
|
39
|
+
/** Normalize a cwd path for the shell dialect (e.g. Windows→POSIX for bash). */
|
|
40
|
+
normalizeCwd(cwd: string): string;
|
|
41
|
+
/** Wrap a command with warmup + quick-exit retry logic. */
|
|
42
|
+
wrapQuickExitRetry(command: string, toolPath: string, thresholdSec?: number): string;
|
|
43
|
+
/** Encode a command for safe execution (identity for bash, Base64 for PowerShell). */
|
|
44
|
+
encodeForExecution(command: string): string;
|
|
45
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function quoteForSh(input: string): string;
|
|
2
|
+
export declare function quoteForPowerShell(input: string): string;
|
|
3
|
+
/** Wrap a PowerShell command using -EncodedCommand to avoid all quoting issues. */
|
|
4
|
+
export declare function toEncodedPowerShell(command: string): string;
|
|
5
|
+
export declare function escapeSingleQuotedPath(path: string, dialect: 'bash' | 'powershell'): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function quoteForSh(input) {
|
|
2
|
+
return `'${input.replaceAll("'", "'\"'\"'")}'`;
|
|
3
|
+
}
|
|
4
|
+
export function quoteForPowerShell(input) {
|
|
5
|
+
return `'${input.replaceAll("'", "''")}'`;
|
|
6
|
+
}
|
|
7
|
+
/** Wrap a PowerShell command using -EncodedCommand to avoid all quoting issues. */
|
|
8
|
+
export function toEncodedPowerShell(command) {
|
|
9
|
+
const encoded = Buffer.from(command, 'utf16le').toString('base64');
|
|
10
|
+
return `powershell.exe -NoProfile -EncodedCommand ${encoded}`;
|
|
11
|
+
}
|
|
12
|
+
export function escapeSingleQuotedPath(path, dialect) {
|
|
13
|
+
if (dialect === 'powershell') {
|
|
14
|
+
return path.replaceAll("'", "''");
|
|
15
|
+
}
|
|
16
|
+
return path.replaceAll("'", String.raw `'\''`);
|
|
17
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProcessSpawnError } from './errors.js';
|
|
2
|
+
export declare function getInstallInstruction(command: string): string;
|
|
3
|
+
export declare function formatCommandNotFoundMessage(command: string): string;
|
|
4
|
+
export declare function formatPathWarning(command: string): string;
|
|
5
|
+
export declare function classifySpawnError(command: string, error: NodeJS.ErrnoException): ProcessSpawnError;
|
|
6
|
+
export declare function resolveWindowsSpawnArgs(command: string, args: string[], cmdExists: (commandName: string) => boolean): null | {
|
|
7
|
+
args: string[];
|
|
8
|
+
command: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ProcessSpawnError } from './errors.js';
|
|
2
|
+
const INSTALL_INSTRUCTIONS = {
|
|
3
|
+
claude: 'Install Claude Code from https://claude.ai/download.',
|
|
4
|
+
codex: 'Install Codex from npm.',
|
|
5
|
+
devin: 'Install Devin from https://cli.devin.ai.',
|
|
6
|
+
};
|
|
7
|
+
export function getInstallInstruction(command) {
|
|
8
|
+
return INSTALL_INSTRUCTIONS[command] ?? 'Check that the command exists and is executable.';
|
|
9
|
+
}
|
|
10
|
+
export function formatCommandNotFoundMessage(command) {
|
|
11
|
+
return `Command not found: ${command}. ${getInstallInstruction(command)}`;
|
|
12
|
+
}
|
|
13
|
+
export function formatPathWarning(command) {
|
|
14
|
+
return `${command} not found on PATH (${getInstallInstruction(command).replace(/\.$/, '')})`;
|
|
15
|
+
}
|
|
16
|
+
export function classifySpawnError(command, error) {
|
|
17
|
+
if (error.code === 'ENOENT') {
|
|
18
|
+
return new ProcessSpawnError(formatCommandNotFoundMessage(command), 'ENOENT');
|
|
19
|
+
}
|
|
20
|
+
if (error.code === 'EACCES') {
|
|
21
|
+
return new ProcessSpawnError(`Permission denied: ${command}. Check file permissions.`, 'EACCES');
|
|
22
|
+
}
|
|
23
|
+
return new ProcessSpawnError(`Failed to spawn ${command}: ${error.message}. Check that the command exists and is executable.`, error.code);
|
|
24
|
+
}
|
|
25
|
+
export function resolveWindowsSpawnArgs(command, args, cmdExists) {
|
|
26
|
+
if (!cmdExists(`${command}.cmd`))
|
|
27
|
+
return null;
|
|
28
|
+
return { command: 'cmd.exe', args: ['/c', command, ...args] };
|
|
29
|
+
}
|
package/dist/lib/spawn.js
CHANGED
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
import { execSync, spawn as nodeSpawn } from 'node:child_process';
|
|
42
42
|
import { debug, debugSpawn } from './debug.js';
|
|
43
43
|
import { ProcessSpawnError } from './errors.js';
|
|
44
|
+
import { classifySpawnError, resolveWindowsSpawnArgs } from './spawn-errors.js';
|
|
44
45
|
/**
|
|
45
46
|
* Spawn an external process and return its exit code.
|
|
46
47
|
*
|
|
@@ -94,9 +95,10 @@ export async function spawnProcess(command, args = [], options = {}) {
|
|
|
94
95
|
catch (error) {
|
|
95
96
|
// If command not found and .cmd file exists, use cmd.exe wrapper
|
|
96
97
|
// This avoids DEP0190 deprecation warning while supporting npm-installed commands
|
|
97
|
-
|
|
98
|
+
const windowsSpawnArgs = resolveWindowsSpawnArgs(command, args, commandExistsInPath);
|
|
99
|
+
if (error instanceof ProcessSpawnError && error.code === 'ENOENT' && windowsSpawnArgs) {
|
|
98
100
|
// Use cmd.exe /c to execute .cmd file without shell mode or deprecation warning
|
|
99
|
-
return attemptSpawn(
|
|
101
|
+
return attemptSpawn(windowsSpawnArgs.command, windowsSpawnArgs.args, { cwd, stdio, detached, shell: false });
|
|
100
102
|
}
|
|
101
103
|
throw error;
|
|
102
104
|
}
|
|
@@ -126,15 +128,7 @@ function attemptSpawn(command, args, spawnOptions) {
|
|
|
126
128
|
const childProcess = nodeSpawn(command, args, spawnOptions);
|
|
127
129
|
// Handle spawn errors (ENOENT, EACCES, etc.)
|
|
128
130
|
childProcess.on('error', (error) => {
|
|
129
|
-
|
|
130
|
-
reject(new ProcessSpawnError(`Command not found: ${command}. Install Claude Code from https://claude.ai/download.`, 'ENOENT'));
|
|
131
|
-
}
|
|
132
|
-
else if (error.code === 'EACCES') {
|
|
133
|
-
reject(new ProcessSpawnError(`Permission denied: ${command}. Check file permissions.`, 'EACCES'));
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
reject(new ProcessSpawnError(`Failed to spawn ${command}: ${error.message}. Check that the command exists and is executable.`, error.code));
|
|
137
|
-
}
|
|
131
|
+
reject(classifySpawnError(command, error));
|
|
138
132
|
});
|
|
139
133
|
// Capture exit code on process close
|
|
140
134
|
childProcess.on('close', (code, signal) => {
|
package/dist/lib/spinner.d.ts
CHANGED
|
@@ -12,8 +12,3 @@ import { type Ora } from 'ora';
|
|
|
12
12
|
export declare function createSpinner(text: string, flags?: {
|
|
13
13
|
quiet?: boolean;
|
|
14
14
|
}): Ora;
|
|
15
|
-
/**
|
|
16
|
-
* Helper for common "loading" operations with spinner.
|
|
17
|
-
* Automatically handles success/failure and cleanup.
|
|
18
|
-
*/
|
|
19
|
-
export declare function withSpinner<T>(text: string, operation: () => Promise<T>): Promise<T>;
|
package/dist/lib/spinner.js
CHANGED
|
@@ -16,19 +16,3 @@ export function createSpinner(text, flags) {
|
|
|
16
16
|
text,
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Helper for common "loading" operations with spinner.
|
|
21
|
-
* Automatically handles success/failure and cleanup.
|
|
22
|
-
*/
|
|
23
|
-
export async function withSpinner(text, operation) {
|
|
24
|
-
const spinner = createSpinner(text).start();
|
|
25
|
-
try {
|
|
26
|
-
const result = await operation();
|
|
27
|
-
spinner.succeed();
|
|
28
|
-
return result;
|
|
29
|
-
}
|
|
30
|
-
catch (error) {
|
|
31
|
-
spinner.fail();
|
|
32
|
-
throw error;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
@@ -34,10 +34,10 @@ interface TemplateInstallationStatus {
|
|
|
34
34
|
existing: TemplateItemStatus[];
|
|
35
35
|
/** Items that are missing from target directory */
|
|
36
36
|
missing: TemplateItemStatus[];
|
|
37
|
-
/** The method-specific
|
|
38
|
-
|
|
39
|
-
/** Whether the
|
|
40
|
-
|
|
37
|
+
/** The method-specific runtime folder name (e.g., '_gsd', '_bmad') */
|
|
38
|
+
runtimeFolder: null | string;
|
|
39
|
+
/** Whether the runtime folder exists */
|
|
40
|
+
runtimeFolderExists: boolean;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
43
|
* Result of template installation
|
|
@@ -74,12 +74,21 @@ export declare function shouldExclude(name: string): boolean;
|
|
|
74
74
|
* @param excludeIdeFolders - If true, exclude IDE config folders (.claude, .windsurf, etc.)
|
|
75
75
|
*/
|
|
76
76
|
export declare function copyDir(src: string, dest: string, excludeIdeFolders?: boolean): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Merge source directory into destination, skipping existing files.
|
|
79
|
+
* Unlike copyDir, this preserves existing files in destination.
|
|
80
|
+
*
|
|
81
|
+
* @param src - Source directory path
|
|
82
|
+
* @param dest - Destination directory path
|
|
83
|
+
*/
|
|
84
|
+
export declare function mergeDirectory(src: string, dest: string, options?: {
|
|
85
|
+
exclude?: (name: string) => boolean;
|
|
86
|
+
}): Promise<void>;
|
|
77
87
|
/**
|
|
78
88
|
* Install template with IDE-specific folder selection.
|
|
79
89
|
*
|
|
80
90
|
* Template structure:
|
|
81
91
|
* - Non-dot folders (e.g., _bmad/, GSR/) → .aiwcli/ (always overwritten)
|
|
82
|
-
* - _shared/ → .aiwcli/_shared/ (always overwritten)
|
|
83
92
|
* - IDE dot folders (e.g., .claude/) → decomposed into method-owned subdirs
|
|
84
93
|
*
|
|
85
94
|
* Settings reconstruction is handled separately by the caller via reconstructIdeSettings().
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
|
-
import {
|
|
2
|
+
import { join } from 'node:path';
|
|
3
3
|
import { IdePathResolver } from './ide-path-resolver.js';
|
|
4
4
|
import { pathExists } from './paths.js';
|
|
5
5
|
/**
|
|
@@ -17,11 +17,11 @@ export async function checkTemplateStatus(templatePath, targetDir, ides, templat
|
|
|
17
17
|
const missing = [];
|
|
18
18
|
// Scan template directory
|
|
19
19
|
const entries = await fs.readdir(templatePath, { withFileTypes: true });
|
|
20
|
-
// Identify
|
|
20
|
+
// Identify method runtime folder based on template name
|
|
21
21
|
// Convention: _templatename (e.g., _gsd, _bmad)
|
|
22
|
-
const
|
|
23
|
-
let
|
|
24
|
-
let
|
|
22
|
+
const runtimeFolderName = `_${templateName}`;
|
|
23
|
+
let runtimeFolder = null;
|
|
24
|
+
let runtimeFolderExists = false;
|
|
25
25
|
// Filter entries to only include relevant items (skip non-selected IDE folders and excluded patterns)
|
|
26
26
|
const relevantEntries = entries.filter((entry) => {
|
|
27
27
|
// Skip excluded patterns (test files, cache, etc.)
|
|
@@ -58,17 +58,17 @@ export async function checkTemplateStatus(templatePath, targetDir, ides, templat
|
|
|
58
58
|
else {
|
|
59
59
|
missing.push(status);
|
|
60
60
|
}
|
|
61
|
-
// Track
|
|
62
|
-
if (status.name ===
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Track method runtime folder
|
|
62
|
+
if (status.name === runtimeFolderName) {
|
|
63
|
+
runtimeFolder = runtimeFolderName;
|
|
64
|
+
runtimeFolderExists = status.exists;
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
return {
|
|
68
68
|
existing,
|
|
69
69
|
missing,
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
runtimeFolder,
|
|
71
|
+
runtimeFolderExists,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
@@ -101,7 +101,7 @@ export async function copyDir(src, dest, excludeIdeFolders = false) {
|
|
|
101
101
|
if (shouldExclude(entry.name)) {
|
|
102
102
|
return false;
|
|
103
103
|
}
|
|
104
|
-
// Exclude IDE config folders if requested (used for
|
|
104
|
+
// Exclude IDE config folders if requested (used for core folder)
|
|
105
105
|
// These folders are used for settings merging, not direct installation
|
|
106
106
|
if (excludeIdeFolders && entry.isDirectory() && entry.name.startsWith('.')) {
|
|
107
107
|
return false;
|
|
@@ -128,16 +128,16 @@ export async function copyDir(src, dest, excludeIdeFolders = false) {
|
|
|
128
128
|
* @param src - Source directory path
|
|
129
129
|
* @param dest - Destination directory path
|
|
130
130
|
*/
|
|
131
|
-
async function mergeDirectory(src, dest) {
|
|
131
|
+
export async function mergeDirectory(src, dest, options) {
|
|
132
132
|
await fs.mkdir(dest, { recursive: true });
|
|
133
133
|
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
134
134
|
const ops = entries
|
|
135
|
-
.filter((entry) => !
|
|
135
|
+
.filter((entry) => !(options?.exclude?.(entry.name)))
|
|
136
136
|
.map(async (entry) => {
|
|
137
137
|
const srcPath = join(src, entry.name);
|
|
138
138
|
const destPath = join(dest, entry.name);
|
|
139
139
|
if (entry.isDirectory()) {
|
|
140
|
-
await mergeDirectory(srcPath, destPath);
|
|
140
|
+
await mergeDirectory(srcPath, destPath, options);
|
|
141
141
|
}
|
|
142
142
|
else if (!(await pathExists(destPath))) {
|
|
143
143
|
await fs.copyFile(srcPath, destPath);
|
|
@@ -150,7 +150,6 @@ async function mergeDirectory(src, dest) {
|
|
|
150
150
|
*
|
|
151
151
|
* Template structure:
|
|
152
152
|
* - Non-dot folders (e.g., _bmad/, GSR/) → .aiwcli/ (always overwritten)
|
|
153
|
-
* - _shared/ → .aiwcli/_shared/ (always overwritten)
|
|
154
153
|
* - IDE dot folders (e.g., .claude/) → decomposed into method-owned subdirs
|
|
155
154
|
*
|
|
156
155
|
* Settings reconstruction is handled separately by the caller via reconstructIdeSettings().
|
|
@@ -205,27 +204,6 @@ export async function installTemplate(config) {
|
|
|
205
204
|
});
|
|
206
205
|
const nonDotResults = await Promise.all(nonDotInstalls);
|
|
207
206
|
installedFolders.push(...nonDotResults);
|
|
208
|
-
// Install root-level _shared directory (shared across all templates)
|
|
209
|
-
// Exclude IDE config folders (.claude, .windsurf) - they are used for settings merging only
|
|
210
|
-
const templatesRoot = dirname(templatePath);
|
|
211
|
-
const rootSharedSrc = join(templatesRoot, '_shared');
|
|
212
|
-
const rootSharedDest = join(containerDir, '_shared');
|
|
213
|
-
if (await pathExists(rootSharedSrc)) {
|
|
214
|
-
await copyDir(rootSharedSrc, rootSharedDest, true); // excludeIdeFolders = true
|
|
215
|
-
installedFolders.push('_shared');
|
|
216
|
-
// Copy shared IDE content (e.g., _shared/.claude/commands/handoff.md)
|
|
217
|
-
// These are non-method-owned files that live in IDE folders
|
|
218
|
-
const sharedIdeInstalls = ides.map(async (ide) => {
|
|
219
|
-
const sharedIdeFolder = join(rootSharedSrc, `.${ide}`);
|
|
220
|
-
if (await pathExists(sharedIdeFolder)) {
|
|
221
|
-
const destIdeFolder = resolver.getIdeDir(ide);
|
|
222
|
-
await fs.mkdir(destIdeFolder, { recursive: true });
|
|
223
|
-
// Merge shared IDE content, skipping files that already exist
|
|
224
|
-
await mergeDirectory(sharedIdeFolder, destIdeFolder);
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
await Promise.all(sharedIdeInstalls);
|
|
228
|
-
}
|
|
229
207
|
// Install method-owned IDE content (decomposed approach)
|
|
230
208
|
// Instead of copying entire .claude/ from template, only copy method-namespaced subdirectories
|
|
231
209
|
const ideInstalls = ides.map(async (ide) => {
|
|
@@ -251,7 +229,7 @@ export async function installTemplate(config) {
|
|
|
251
229
|
}
|
|
252
230
|
else {
|
|
253
231
|
// No method-namespaced child — copy the entire subdirectory, merging with existing
|
|
254
|
-
await mergeDirectory(subdirSrc, subdirDest);
|
|
232
|
+
await mergeDirectory(subdirSrc, subdirDest, { exclude: shouldExclude });
|
|
255
233
|
}
|
|
256
234
|
});
|
|
257
235
|
await Promise.all(subdirOps);
|
|
@@ -260,9 +238,33 @@ export async function installTemplate(config) {
|
|
|
260
238
|
const ideResults = (await Promise.all(ideInstalls)).filter((result) => result !== null);
|
|
261
239
|
installedFolders.push(...ideResults);
|
|
262
240
|
// Settings reconstruction is handled by the caller via reconstructIdeSettings()
|
|
241
|
+
// Write resolved CLI binary path so template scripts can shell out to `aiw`
|
|
242
|
+
await writeAiwBinPath(containerDir);
|
|
263
243
|
return {
|
|
264
244
|
installedFolders,
|
|
265
245
|
sharedSettingsMerged: false,
|
|
266
246
|
templatePath,
|
|
267
247
|
};
|
|
268
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Write the resolved `aiw` binary path to `.aiwcli/.aiw-bin-path`.
|
|
251
|
+
* Template scripts read this file to find the CLI binary for `aiw launch`.
|
|
252
|
+
*/
|
|
253
|
+
async function writeAiwBinPath(containerDir) {
|
|
254
|
+
try {
|
|
255
|
+
// process.argv[1] is the main script entry point (e.g., /path/to/aiw/bin/run.js)
|
|
256
|
+
// Resolve to the bin directory to find the actual `aiw` executable
|
|
257
|
+
const { execSync } = await import('node:child_process');
|
|
258
|
+
const cmd = process.platform === 'win32' ? 'where aiw' : 'which aiw';
|
|
259
|
+
const resolved = execSync(cmd, { encoding: 'utf8', timeout: 3000, stdio: ['pipe', 'pipe', 'pipe'] })
|
|
260
|
+
.trim()
|
|
261
|
+
.split(/\r?\n/)[0]
|
|
262
|
+
?.trim();
|
|
263
|
+
if (resolved) {
|
|
264
|
+
await fs.writeFile(join(containerDir, '.aiw-bin-path'), resolved, 'utf8');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
// Best-effort — aiw will still be found on PATH at runtime
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -12,15 +12,14 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function getTemplatePath(templateName: string): Promise<string>;
|
|
14
14
|
/**
|
|
15
|
-
* Get list of available template names by scanning the templates directory.
|
|
15
|
+
* Get list of available method template names by scanning the templates directory.
|
|
16
16
|
*
|
|
17
|
-
* @returns Array of template names (e.g., ['bmad', '
|
|
17
|
+
* @returns Array of method template names (e.g., ['bmad', 'cc-native'])
|
|
18
18
|
* @throws Error if templates directory cannot be read (indicates corrupted installation)
|
|
19
19
|
*/
|
|
20
|
+
export declare function getAvailableTemplates(): Promise<string[]>;
|
|
20
21
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @returns Absolute path to the _shared template
|
|
22
|
+
* Discover IDE names available in a template path by scanning top-level dot-folders.
|
|
23
|
+
* Example: .claude, .codex -> ['claude', 'codex']
|
|
24
24
|
*/
|
|
25
|
-
export declare function
|
|
26
|
-
export declare function getAvailableTemplates(): Promise<string[]>;
|
|
25
|
+
export declare function getTemplateIdeNamesByPath(templatePath: string): Promise<string[]>;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
+
function getTemplatesRootDir() {
|
|
5
|
+
const currentFileUrl = import.meta.url;
|
|
6
|
+
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
7
|
+
const currentDir = dirname(currentFilePath);
|
|
8
|
+
return join(currentDir, '..', 'templates');
|
|
9
|
+
}
|
|
4
10
|
/**
|
|
5
11
|
* Resolve the absolute path to a bundled template root.
|
|
6
12
|
* Works in both development (src/) and production (dist/) contexts.
|
|
@@ -21,13 +27,10 @@ export async function getTemplatePath(templateName) {
|
|
|
21
27
|
// Get the directory of this file
|
|
22
28
|
// In dev: .../aiwcli/src/lib/
|
|
23
29
|
// In prod: .../aiwcli/dist/lib/
|
|
24
|
-
const currentFileUrl = import.meta.url;
|
|
25
|
-
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
26
|
-
const currentDir = dirname(currentFilePath);
|
|
27
30
|
// Go up one level and into templates/<templateName>
|
|
28
31
|
// src/lib/ → src/templates/<templateName>/
|
|
29
32
|
// dist/lib/ → dist/templates/<templateName>/
|
|
30
|
-
const templatePath = join(
|
|
33
|
+
const templatePath = join(getTemplatesRootDir(), templateName);
|
|
31
34
|
// Validate template exists
|
|
32
35
|
try {
|
|
33
36
|
await fs.access(templatePath);
|
|
@@ -38,29 +41,18 @@ export async function getTemplatePath(templateName) {
|
|
|
38
41
|
return templatePath;
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
|
-
* Get list of available template names by scanning the templates directory.
|
|
44
|
+
* Get list of available method template names by scanning the templates directory.
|
|
42
45
|
*
|
|
43
|
-
* @returns Array of template names (e.g., ['bmad', '
|
|
46
|
+
* @returns Array of method template names (e.g., ['bmad', 'cc-native'])
|
|
44
47
|
* @throws Error if templates directory cannot be read (indicates corrupted installation)
|
|
45
48
|
*/
|
|
46
|
-
/**
|
|
47
|
-
* Get the absolute path to the _shared template directory.
|
|
48
|
-
*
|
|
49
|
-
* @returns Absolute path to the _shared template
|
|
50
|
-
*/
|
|
51
|
-
export function getSharedTemplatePath() {
|
|
52
|
-
const currentFilePath = fileURLToPath(import.meta.url);
|
|
53
|
-
const currentDir = dirname(currentFilePath);
|
|
54
|
-
return join(currentDir, '..', 'templates', '_shared');
|
|
55
|
-
}
|
|
56
49
|
export async function getAvailableTemplates() {
|
|
57
|
-
const
|
|
58
|
-
const currentFilePath = fileURLToPath(currentFileUrl);
|
|
59
|
-
const currentDir = dirname(currentFilePath);
|
|
60
|
-
const templatesDir = join(currentDir, '..', 'templates');
|
|
50
|
+
const templatesDir = getTemplatesRootDir();
|
|
61
51
|
try {
|
|
62
52
|
const entries = await fs.readdir(templatesDir, { withFileTypes: true });
|
|
63
|
-
return entries
|
|
53
|
+
return entries
|
|
54
|
+
.filter((entry) => entry.isDirectory() && !entry.name.startsWith('_') && !RESERVED_TEMPLATE_NAMES.has(entry.name))
|
|
55
|
+
.map((entry) => entry.name);
|
|
64
56
|
}
|
|
65
57
|
catch (error) {
|
|
66
58
|
const err = error;
|
|
@@ -68,3 +60,16 @@ export async function getAvailableTemplates() {
|
|
|
68
60
|
`This indicates a corrupted installation. Please reinstall aiwcli.`);
|
|
69
61
|
}
|
|
70
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Discover IDE names available in a template path by scanning top-level dot-folders.
|
|
65
|
+
* Example: .claude, .codex -> ['claude', 'codex']
|
|
66
|
+
*/
|
|
67
|
+
export async function getTemplateIdeNamesByPath(templatePath) {
|
|
68
|
+
const entries = await fs.readdir(templatePath, { withFileTypes: true });
|
|
69
|
+
return entries
|
|
70
|
+
.filter((entry) => entry.isDirectory() && entry.name.startsWith('.'))
|
|
71
|
+
.map((entry) => entry.name.slice(1))
|
|
72
|
+
.filter((name) => name.length > 0)
|
|
73
|
+
.sort((a, b) => a.localeCompare(b));
|
|
74
|
+
}
|
|
75
|
+
const RESERVED_TEMPLATE_NAMES = new Set(['core']);
|