@opengsd/gsd-core 1.8.0 → 1.9.1
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.opencode/plugins/gsd-core.js +31 -1
- package/agents/gsd-code-fixer.md +107 -34
- package/agents/gsd-codebase-mapper.md +1 -1
- package/agents/gsd-debug-session-manager.md +36 -0
- package/agents/gsd-executor.md +20 -7
- package/agents/gsd-intel-updater.md +3 -3
- package/agents/gsd-phase-researcher.md +4 -2
- package/agents/gsd-plan-checker.md +20 -0
- package/agents/gsd-planner.md +15 -23
- package/agents/gsd-project-researcher.md +2 -2
- package/agents/gsd-ui-auditor.md +0 -40
- package/bin/install.js +236 -107
- package/commands/gsd/plan-review-convergence.md +5 -1
- package/gsd-core/bin/gsd-tools.cjs +882 -4
- package/gsd-core/bin/lib/api-coverage.cjs +22 -8
- package/gsd-core/bin/lib/audit.cjs +8 -8
- package/gsd-core/bin/lib/capability-consent.cjs +40 -1
- package/gsd-core/bin/lib/capability-lifecycle.cjs +58 -0
- package/gsd-core/bin/lib/capability-loader.cjs +23 -1
- package/gsd-core/bin/lib/capability-registry.cjs +1353 -132
- package/gsd-core/bin/lib/capability-trust.cjs +468 -33
- package/gsd-core/bin/lib/capability-validator.cjs +882 -6
- package/gsd-core/bin/lib/check-command-router.cjs +12 -2
- package/gsd-core/bin/lib/cjs-command-router-adapter.cjs +15 -0
- package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +102 -12
- package/gsd-core/bin/lib/claude-orchestration.cjs +125 -22
- package/gsd-core/bin/lib/commands.cjs +246 -18
- package/gsd-core/bin/lib/config-loader.cjs +200 -28
- package/gsd-core/bin/lib/config.cjs +90 -5
- package/gsd-core/bin/lib/estimate-cli.cjs +336 -0
- package/gsd-core/bin/lib/frontmatter.cjs +125 -15
- package/gsd-core/bin/lib/host-integration.cjs +215 -8
- package/gsd-core/bin/lib/init.cjs +44 -19
- package/gsd-core/bin/lib/install-engine.cjs +1 -0
- package/gsd-core/bin/lib/milestone.cjs +36 -9
- package/gsd-core/bin/lib/model-catalog.cjs +51 -1
- package/gsd-core/bin/lib/observability/logger.cjs +7 -2
- package/gsd-core/bin/lib/phase-command-router.cjs +10 -1
- package/gsd-core/bin/lib/phase-estimation.cjs +398 -0
- package/gsd-core/bin/lib/phase-id.cjs +278 -5
- package/gsd-core/bin/lib/phase.cjs +61 -6
- package/gsd-core/bin/lib/plan-drift-guard.cjs +1 -1
- package/gsd-core/bin/lib/plan-scan.cjs +1 -1
- package/gsd-core/bin/lib/planning-workspace.cjs +9 -2
- package/gsd-core/bin/lib/profile-output.cjs +34 -8
- package/gsd-core/bin/lib/project-root.cjs +48 -0
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +927 -0
- package/gsd-core/bin/lib/review-lane-invocation.cjs +348 -0
- package/gsd-core/bin/lib/review-lane-runner.cjs +594 -0
- package/gsd-core/bin/lib/review-reviewer-selection.cjs +114 -32
- package/gsd-core/bin/lib/roadmap-parser.cjs +54 -6
- package/gsd-core/bin/lib/roadmap.cjs +10 -4
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +31 -4
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +1 -1
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +140 -0
- package/gsd-core/bin/lib/runtime-name-policy.cjs +15 -2
- package/gsd-core/bin/lib/smart-entry.cjs +1 -1
- package/gsd-core/bin/lib/state-document.cjs +164 -20
- package/gsd-core/bin/lib/state-transition.cjs +28 -10
- package/gsd-core/bin/lib/state.cjs +141 -21
- package/gsd-core/bin/lib/uat-predicate.cjs +6 -4
- package/gsd-core/bin/lib/uat.cjs +9 -7
- package/gsd-core/bin/lib/ui-consideration-probe.cjs +2 -2
- package/gsd-core/bin/lib/unusable-input.cjs +216 -0
- package/gsd-core/bin/lib/validate.cjs +32 -0
- package/gsd-core/bin/lib/verification.cjs +51 -14
- package/gsd-core/bin/lib/verify.cjs +146 -22
- package/gsd-core/bin/lib/worktree-safety.cjs +360 -15
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -13
- package/gsd-core/bin/shared/model-catalog.json +5 -0
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +5 -0
- package/gsd-core/references/context-budget.md +40 -0
- package/gsd-core/references/gate-prompts.md +6 -3
- package/gsd-core/references/model-profile-resolution.md +64 -13
- package/gsd-core/references/offer-next.md +88 -0
- package/gsd-core/references/planning-config.md +2 -1
- package/gsd-core/references/reviewer-instances.md +28 -21
- package/gsd-core/references/runtime-aware-dispatch.md +42 -0
- package/gsd-core/references/ui-consideration-probe.md +2 -2
- package/gsd-core/references/worktree-branch-check.md +4 -4
- package/gsd-core/templates/summary-minimal.md +4 -0
- package/gsd-core/templates/summary-standard.md +4 -0
- package/gsd-core/templates/summary.md +7 -0
- package/gsd-core/workflows/ai-integration-phase.md +4 -4
- package/gsd-core/workflows/audit-fix.md +4 -0
- package/gsd-core/workflows/audit-milestone.md +8 -0
- package/gsd-core/workflows/autonomous.md +19 -15
- package/gsd-core/workflows/check-todos.md +2 -2
- package/gsd-core/workflows/code-review-fix.md +14 -6
- package/gsd-core/workflows/code-review.md +93 -21
- package/gsd-core/workflows/debug.md +10 -2
- package/gsd-core/workflows/diagnose-issues.md +4 -0
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +2 -4
- package/gsd-core/workflows/discuss-phase/modes/auto.md +0 -6
- package/gsd-core/workflows/discuss-phase-assumptions.md +15 -9
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/docs-update.md +8 -0
- package/gsd-core/workflows/eval-review.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +4 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +160 -0
- package/gsd-core/workflows/execute-phase.md +85 -115
- package/gsd-core/workflows/execute-plan.md +5 -4
- package/gsd-core/workflows/explore.md +4 -0
- package/gsd-core/workflows/extract-learnings.md +21 -0
- package/gsd-core/workflows/help/modes/full.md +3 -3
- package/gsd-core/workflows/import.md +4 -1
- package/gsd-core/workflows/ingest-docs.md +4 -0
- package/gsd-core/workflows/map-codebase.md +13 -6
- package/gsd-core/workflows/new-milestone.md +10 -2
- package/gsd-core/workflows/new-project.md +11 -4
- package/gsd-core/workflows/next.md +5 -2
- package/gsd-core/workflows/plan-phase.md +42 -46
- package/gsd-core/workflows/plan-review-convergence.md +18 -14
- package/gsd-core/workflows/progress.md +1 -1
- package/gsd-core/workflows/quick.md +14 -3
- package/gsd-core/workflows/review.md +146 -575
- package/gsd-core/workflows/scan.md +9 -1
- package/gsd-core/workflows/secure-phase.md +10 -2
- package/gsd-core/workflows/ship.md +41 -11
- package/gsd-core/workflows/smart-entry.md +1 -1
- package/gsd-core/workflows/ui-phase.md +8 -1
- package/gsd-core/workflows/ui-review.md +8 -1
- package/gsd-core/workflows/update.md +104 -5
- package/gsd-core/workflows/validate-phase.md +10 -2
- package/gsd-core/workflows/verify-work.md +8 -1
- package/hooks/dist/gsd-cursor-session-start.js +6 -2
- package/hooks/dist/gsd-cursor-stop.js +6 -2
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-graphify-update.sh +9 -0
- package/hooks/dist/gsd-phase-boundary.sh +14 -2
- package/hooks/dist/gsd-prompt-guard.js +101 -2
- package/hooks/dist/gsd-read-guard.js +100 -2
- package/hooks/dist/gsd-read-injection-scanner.js +109 -2
- package/hooks/dist/gsd-statusline.js +9 -6
- package/hooks/dist/gsd-workflow-guard.js +110 -6
- package/hooks/dist/gsd-worktree-path-guard.js +132 -8
- package/hooks/dist/lib/cursor-workspace.js +74 -0
- package/hooks/gsd-cursor-session-start.js +6 -2
- package/hooks/gsd-cursor-stop.js +6 -2
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-graphify-update.sh +9 -0
- package/hooks/gsd-phase-boundary.sh +14 -2
- package/hooks/gsd-prompt-guard.js +101 -2
- package/hooks/gsd-read-guard.js +100 -2
- package/hooks/gsd-read-injection-scanner.js +109 -2
- package/hooks/gsd-statusline.js +9 -6
- package/hooks/gsd-workflow-guard.js +110 -6
- package/hooks/gsd-worktree-path-guard.js +132 -8
- package/hooks/lib/cursor-workspace.js +74 -0
- package/package.json +7 -7
- package/pi/gsd.cjs +26 -1
- package/scripts/check-coverage-gate.cjs +51 -0
- package/scripts/check-glossary-refs.cjs +24 -0
- package/scripts/ci-test-scope.cjs +67 -17
- package/scripts/gen-adr-index.cjs +6 -4
- package/scripts/gen-capability-matrix.cjs +26 -2
- package/scripts/gen-capability-registry.cjs +132 -34
- package/scripts/gen-emitted-baseline.cjs +145 -0
- package/scripts/gen-registry.cjs +39 -15
- package/scripts/lint-compiled-artifact-sync.cjs +146 -0
- package/scripts/lint-emitted-drift-ack.cjs +149 -0
- package/scripts/lint-fix-has-regression-test.cjs +131 -0
- package/scripts/lint-resolution-provenance.cjs +9 -0
- package/scripts/mutation-matrix.cjs +4 -0
- package/scripts/prompt-injection-scan.sh +6 -0
- package/scripts/registry-schema.cjs +372 -94
- package/scripts/release-notes/conventional-title.cjs +19 -1
- package/scripts/release-notes/format-github-release-notes.cjs +7 -3
- package/scripts/validate-registry.cjs +10 -6
- package/scripts/workflow-size.cjs +16 -8
- package/skills/gsd-plan-review-convergence/SKILL.md +5 -1
- package/vscode/package.json +1 -1
- package/scripts/gen-golden-install-parity-zcode.cjs +0 -77
- package/scripts/update-size-baseline.cjs +0 -68
package/bin/install.js
CHANGED
|
@@ -325,7 +325,13 @@ const GSD_WINDSURF_HOOK_SCRIPTS = [
|
|
|
325
325
|
|
|
326
326
|
// GSD-managed files under hooks/lib/ (helpers required by gsd-*.sh hooks).
|
|
327
327
|
// git-cmd.js does not start with "gsd-" (shared classifier for #3129), gsd-graphify-rebuild.sh does.
|
|
328
|
-
|
|
328
|
+
// cursor-workspace.js (#2587) is required by the Cursor lifecycle hooks. Those
|
|
329
|
+
// are staged individually by writeCursorHooksJson (Cursor sets
|
|
330
|
+
// hostBehaviors.skipSharedHooksInstall, so it never reaches the bulk hooks/lib
|
|
331
|
+
// copy below) — that function stages this helper alongside them. Listing it
|
|
332
|
+
// here keeps uninstall and the manifest managing it for every OTHER runtime
|
|
333
|
+
// that does receive hooks/lib.
|
|
334
|
+
const GSD_HOOK_LIB_FILES = ['git-cmd.js', 'gsd-graphify-rebuild.sh', 'cursor-workspace.js'];
|
|
329
335
|
|
|
330
336
|
const CODEX_AGENT_SANDBOX = {
|
|
331
337
|
'gsd-executor': 'workspace-write',
|
|
@@ -627,7 +633,7 @@ if (hasMinimal && _profileArgRaw) {
|
|
|
627
633
|
|
|
628
634
|
function selectRuntimesFromArgs(runtimeArgs) {
|
|
629
635
|
if (runtimeArgs.includes('--all')) {
|
|
630
|
-
return ['claude', 'kimi', 'kilo', 'opencode', 'pi', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'zcode'];
|
|
636
|
+
return ['claude', 'kimi', 'kimi-code', 'kilo', 'opencode', 'pi', 'codex', 'copilot', 'antigravity', 'cursor', 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'codebuddy', 'cline', 'zcode'];
|
|
631
637
|
}
|
|
632
638
|
if (runtimeArgs.includes('--both')) {
|
|
633
639
|
return ['claude', 'opencode'];
|
|
@@ -648,6 +654,7 @@ function selectRuntimesFromArgs(runtimeArgs) {
|
|
|
648
654
|
if (runtimeArgs.includes('--qwen')) selected.push('qwen');
|
|
649
655
|
if (runtimeArgs.includes('--hermes')) selected.push('hermes');
|
|
650
656
|
if (runtimeArgs.includes('--kimi')) selected.push('kimi');
|
|
657
|
+
if (runtimeArgs.includes('--kimi-code')) selected.push('kimi-code');
|
|
651
658
|
if (runtimeArgs.includes('--codebuddy')) selected.push('codebuddy');
|
|
652
659
|
if (runtimeArgs.includes('--cline')) selected.push('cline');
|
|
653
660
|
if (runtimeArgs.includes('--zcode')) selected.push('zcode');
|
|
@@ -657,6 +664,62 @@ function selectRuntimesFromArgs(runtimeArgs) {
|
|
|
657
664
|
// Runtime selection - can be set by flags or interactive prompt
|
|
658
665
|
let selectedRuntimes = selectRuntimesFromArgs(args);
|
|
659
666
|
|
|
667
|
+
// #2505 Phase 5: Kimi variant disambiguation (#2513). Kimi CLI (Python, ~/.kimi/)
|
|
668
|
+
// and Kimi Code (Node, ~/.kimi-code/) are two distinct Moonshot products that
|
|
669
|
+
// share the "kimi" brand. Probe for each product's config.toml and warn when
|
|
670
|
+
// the selected runtime doesn't match the detected install — catches the common
|
|
671
|
+
// "ran --kimi --global but actually on Kimi Code" mistake that produced inert
|
|
672
|
+
// YAMLs and empty agent-skills before the Phase 1 descriptor split.
|
|
673
|
+
function disambiguateKimiVariant(runtimes) {
|
|
674
|
+
const home = os.homedir();
|
|
675
|
+
const hasKimiCli = fs.existsSync(path.join(home, '.kimi', 'config.toml'));
|
|
676
|
+
const hasKimiCode = fs.existsSync(path.join(home, '.kimi-code', 'config.toml'));
|
|
677
|
+
const notices = [];
|
|
678
|
+
if (runtimes.includes('kimi') && hasKimiCode && !hasKimiCli) {
|
|
679
|
+
notices.push({
|
|
680
|
+
kind: 'wrong-variant',
|
|
681
|
+
selected: 'kimi',
|
|
682
|
+
detected: 'kimi-code',
|
|
683
|
+
message: `Detected ~/.kimi-code/config.toml (Kimi Code, Node CLI) but not ~/.kimi/config.toml (Kimi CLI, Python). You selected --kimi but appear to be on Kimi Code. Re-run with --kimi-code for a working install. (Kimi CLI = Python kimi-cli with named subagents; Kimi Code = Node CLI with coder/explore/plan built-ins only.)`,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (runtimes.includes('kimi-code') && hasKimiCli && !hasKimiCode) {
|
|
687
|
+
notices.push({
|
|
688
|
+
kind: 'wrong-variant',
|
|
689
|
+
selected: 'kimi-code',
|
|
690
|
+
detected: 'kimi',
|
|
691
|
+
message: `Detected ~/.kimi/config.toml (Kimi CLI, Python) but not ~/.kimi-code/config.toml (Kimi Code, Node CLI). You selected --kimi-code but appear to be on Kimi CLI. Re-run with --kimi for a working install.`,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
// Distinct-entry descriptions when either Kimi variant is selected.
|
|
695
|
+
if (runtimes.includes('kimi')) {
|
|
696
|
+
notices.push({
|
|
697
|
+
kind: 'description',
|
|
698
|
+
runtime: 'kimi',
|
|
699
|
+
message: 'Kimi CLI (Python kimi-cli): named subagents via YAML, config at ~/.kimi/, hooks via ~/.kimi/config.toml [[hooks]].',
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
if (runtimes.includes('kimi-code')) {
|
|
703
|
+
notices.push({
|
|
704
|
+
kind: 'description',
|
|
705
|
+
runtime: 'kimi-code',
|
|
706
|
+
message: 'Kimi Code (Node CLI): three built-in subagents (coder/explore/plan), Agent Skills at ~/.kimi-code/skills/, config at ~/.kimi-code/.',
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
return notices;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (selectedRuntimes.includes('kimi') || selectedRuntimes.includes('kimi-code')) {
|
|
713
|
+
const kimiNotices = disambiguateKimiVariant(selectedRuntimes);
|
|
714
|
+
for (const notice of kimiNotices) {
|
|
715
|
+
if (notice.kind === 'wrong-variant') {
|
|
716
|
+
console.error(`${yellow}⚠ Kimi variant mismatch (${notice.selected} → ${notice.detected}).${reset} ${notice.message}`);
|
|
717
|
+
} else if (notice.kind === 'description') {
|
|
718
|
+
console.log(`${dim} ${notice.runtime}: ${notice.message}${reset}`);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
660
723
|
// #1928: Google sunset Gemini CLI on 2026-06-18; Antigravity CLI is its
|
|
661
724
|
// official successor. `--gemini` is no longer a valid runtime selector —
|
|
662
725
|
// selectRuntimesFromArgs above no longer recognizes it, so it never lands in
|
|
@@ -3956,10 +4019,14 @@ Typed mapping (agent_type-capable schema only):
|
|
|
3956
4019
|
inherited, or unsupported values; do not invent one-off effort literals in
|
|
3957
4020
|
workflow prose.
|
|
3958
4021
|
- \`fork_context: false\` by default — GSD agents load their own context via \`<files_to_read>\` blocks
|
|
3959
|
-
- \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct
|
|
3960
|
-
Codex \`
|
|
3961
|
-
|
|
3962
|
-
|
|
4022
|
+
- \`Task(isolation="worktree")\` / \`Agent(isolation="worktree")\` → no direct \`spawn_agent\` mapping,
|
|
4023
|
+
but Codex declares \`dispatch.isolation: orchestrator-worktree\` (#2584). Codex
|
|
4024
|
+
\`spawn_agent\` still does not create or bind a git worktree; instead GSD itself
|
|
4025
|
+
creates the worktree and process-spawns the executor into it with
|
|
4026
|
+
\`codex exec --cd <dir>\`, performing every git operation on the executor's behalf
|
|
4027
|
+
(its \`workspace-write\` sandbox makes \`.git\` read-only). Workflows must therefore
|
|
4028
|
+
never fabricate a manual worktree protocol — route through the negotiated
|
|
4029
|
+
isolation adapter, which still fails closed for hosts declaring \`none\` (#3360).
|
|
3963
4030
|
|
|
3964
4031
|
Generic-agent workaround (multi_agent_v1 schema — NO agent_type field):
|
|
3965
4032
|
When only the generic \`multi_agent_v1\` schema is available, typed GSD agent dispatch
|
|
@@ -6916,6 +6983,47 @@ function writeCopilotHookConfig(targetDir) {
|
|
|
6916
6983
|
* Generate config.toml and per-agent .toml files for Codex.
|
|
6917
6984
|
* Reads agent .md files from source, extracts metadata, writes .toml configs.
|
|
6918
6985
|
*/
|
|
6986
|
+
|
|
6987
|
+
/**
|
|
6988
|
+
* #2834: Write ~/.gsd/defaults.json for non-Claude runtimes — sets
|
|
6989
|
+
* resolve_model_ids="omit" (so resolveModelInternal() returns '' instead of
|
|
6990
|
+
* Claude aliases the runtime can't resolve) and runtime=<runtime> (so
|
|
6991
|
+
* resolveRuntime() resolves correctly out of the box). MUST be called BEFORE
|
|
6992
|
+
* installCodexConfig (or any other step that reads defaults.json at generation
|
|
6993
|
+
* time), so a clean first install produces correctly-model-routed agent TOMLs.
|
|
6994
|
+
* No-op for Claude runtimes (Claude is the resolveRuntime fallback + has native
|
|
6995
|
+
* model aliases). Preserves an explicit `true` opt-in and existing values.
|
|
6996
|
+
*/
|
|
6997
|
+
function writeNonClaudeDefaults(runtime) {
|
|
6998
|
+
if (_hostBehaviors(runtime).nativeModelAliases || process.env.GSD_TEST_MODE) return;
|
|
6999
|
+
const gsdDir = path.join(os.homedir(), '.gsd');
|
|
7000
|
+
const defaultsPath = path.join(gsdDir, 'defaults.json');
|
|
7001
|
+
try {
|
|
7002
|
+
fs.mkdirSync(gsdDir, { recursive: true });
|
|
7003
|
+
let defaults = {};
|
|
7004
|
+
try { defaults = JSON.parse(fs.readFileSync(defaultsPath, 'utf8')); } catch { /* new file */ }
|
|
7005
|
+
if (defaults === null || typeof defaults !== 'object' || Array.isArray(defaults)) {
|
|
7006
|
+
defaults = {};
|
|
7007
|
+
}
|
|
7008
|
+
// Three-valued domain: false/absent → aliases; true → full IDs; "omit" → ''.
|
|
7009
|
+
const existing = defaults.resolve_model_ids;
|
|
7010
|
+
const shouldDefaultToOmit = existing !== true && existing !== 'omit';
|
|
7011
|
+
if (shouldDefaultToOmit) {
|
|
7012
|
+
defaults.resolve_model_ids = 'omit';
|
|
7013
|
+
fs.writeFileSync(defaultsPath, JSON.stringify(defaults, null, 2) + '\n');
|
|
7014
|
+
console.log(` ${green}✓${reset} Set resolve_model_ids: "omit" in ~/.gsd/defaults.json`);
|
|
7015
|
+
}
|
|
7016
|
+
// #2395: persist runtime for non-Claude runtimes.
|
|
7017
|
+
if (defaults.runtime === undefined || defaults.runtime === null || defaults.runtime === '') {
|
|
7018
|
+
defaults.runtime = runtime;
|
|
7019
|
+
fs.writeFileSync(defaultsPath, JSON.stringify(defaults, null, 2) + '\n');
|
|
7020
|
+
console.log(` ${green}✓${reset} Set runtime: "${runtime}" in ~/.gsd/defaults.json`);
|
|
7021
|
+
}
|
|
7022
|
+
} catch (e) {
|
|
7023
|
+
console.log(` ${yellow}⚠${reset} Could not write ~/.gsd/defaults.json: ${e.message}`);
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
|
|
6919
7027
|
function installCodexConfig(targetDir, agentsSrc, sandboxTier = 'codex-agent-sandbox') {
|
|
6920
7028
|
// ADR-1239 Phase B write-confinement: every Codex config write stays under targetDir.
|
|
6921
7029
|
const configPath = assertDestWithinConfigHome(targetDir, 'config.toml');
|
|
@@ -8434,6 +8542,17 @@ function uninstall(isGlobal, runtime = DEFAULT_RUNTIME) {
|
|
|
8434
8542
|
console.log(` ${green}✓${reset} Removed ${removedLibFiles} hooks/lib/ helper(s)`);
|
|
8435
8543
|
}
|
|
8436
8544
|
}
|
|
8545
|
+
|
|
8546
|
+
// #2717: remove the CommonJS marker GSD wrote into hooks/ for runtimes that
|
|
8547
|
+
// stage .js hooks via dedicated paths (cursor/windsurf/codex) — but ONLY if
|
|
8548
|
+
// it still carries GSD's exact content (a user-authored package.json is
|
|
8549
|
+
// never deleted). Safe no-op for runtimes whose marker lives at the config
|
|
8550
|
+
// root (the shared-bundle path) or that never received one.
|
|
8551
|
+
try {
|
|
8552
|
+
if (hooksSurface.removeCommonJsMarkerIfGsdOwned(hooksDir)) {
|
|
8553
|
+
console.log(` ${green}✓${reset} Removed GSD hooks/package.json (CommonJS marker)`);
|
|
8554
|
+
}
|
|
8555
|
+
} catch { /* best-effort */ }
|
|
8437
8556
|
}
|
|
8438
8557
|
|
|
8439
8558
|
// 4z. Remove the native plugin adapter (#1914, extended to Kilo by #2093).
|
|
@@ -10339,6 +10458,45 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
10339
10458
|
return Array.isArray(scopeLayout) && scopeLayout.length > 0;
|
|
10340
10459
|
})();
|
|
10341
10460
|
|
|
10461
|
+
// #2624: write the .gsd-source marker. Extracted from its former late position so it can be
|
|
10462
|
+
// called BEFORE staging reads the marker (see the call site below). Scoped to the Claude-global
|
|
10463
|
+
// layout (issue #1477) — the only install path that ships the skills layout without a
|
|
10464
|
+
// commands/gsd source tree, so findInstallSourceRoot's walk-up has nothing to find and
|
|
10465
|
+
// /gsd-surface (list/status) throws without it. Points at the package's own commands/gsd
|
|
10466
|
+
// source. Guarded on source presence so a half-published package never writes a dangling
|
|
10467
|
+
// marker. Write failure is non-fatal (install proceeds; warn so /gsd-surface breakage is
|
|
10468
|
+
// diagnosable) — the same contract the late write had.
|
|
10469
|
+
function _writeGsdSourceMarker(runtime, targetDir, src, isGlobal) {
|
|
10470
|
+
if (_hostBehaviors(runtime).sourceMarkerFile && isGlobal) {
|
|
10471
|
+
const gsdSourceCommands = path.join(src, 'commands', 'gsd');
|
|
10472
|
+
if (fs.existsSync(gsdSourceCommands)) {
|
|
10473
|
+
try {
|
|
10474
|
+
// ADR-1239 Phase B write-confinement: the descriptor-sourced marker filename
|
|
10475
|
+
// must resolve under targetDir (parity with the other descriptor-driven writes).
|
|
10476
|
+
const _markerPath = assertDestWithinConfigHome(targetDir, _hostBehaviors(runtime).sourceMarkerFile);
|
|
10477
|
+
fs.writeFileSync(_markerPath, gsdSourceCommands + '\n', 'utf8');
|
|
10478
|
+
} catch (err) {
|
|
10479
|
+
// Non-fatal: install proceeds. But on the Claude-global layout walk-up
|
|
10480
|
+
// also fails (no commands/gsd source tree), so a silent write failure
|
|
10481
|
+
// still leaves /gsd-surface broken at runtime — warn so it's diagnosable.
|
|
10482
|
+
console.warn(` ${yellow}!${reset} Could not write .gsd-source marker (${err.message}); /gsd-surface list/status may fail`);
|
|
10483
|
+
}
|
|
10484
|
+
}
|
|
10485
|
+
}
|
|
10486
|
+
}
|
|
10487
|
+
|
|
10488
|
+
// #2624: write the .gsd-source marker BEFORE any staging reads it. The marker write
|
|
10489
|
+
// formerly lived AFTER staging; on an upgrade the marker still held the PREVIOUS
|
|
10490
|
+
// install's source path (e.g. an npx per-version cache dir that still exists on disk),
|
|
10491
|
+
// so findInstallSourceRoot(configDir) — called inside installRuntimeArtifacts below —
|
|
10492
|
+
// returned the stale path and every converted skill was generated from the OLD version's
|
|
10493
|
+
// commands/gsd, silently installing prior-version content with a self-consistent manifest
|
|
10494
|
+
// hash. Writing first closes the read-before-write hole for every findInstallSourceRoot
|
|
10495
|
+
// consumer (skills, commands, /gsd-surface, capability-state). Placed here (before the
|
|
10496
|
+
// _isSkillsRuntime branch) so it runs for every Claude-global install, matching the
|
|
10497
|
+
// original write's sourceMarkerFile && isGlobal guard exactly.
|
|
10498
|
+
_writeGsdSourceMarker(runtime, targetDir, src, isGlobal);
|
|
10499
|
+
|
|
10342
10500
|
if (_isSkillsRuntime) {
|
|
10343
10501
|
// Layout-driven install for skills-based runtimes (full and minimal modes)
|
|
10344
10502
|
const scope = isGlobal ? 'global' : 'local';
|
|
@@ -10627,35 +10785,11 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
10627
10785
|
failures.push('gsd-core');
|
|
10628
10786
|
}
|
|
10629
10787
|
|
|
10630
|
-
//
|
|
10631
|
-
//
|
|
10632
|
-
//
|
|
10633
|
-
//
|
|
10634
|
-
//
|
|
10635
|
-
// and /gsd-surface (list/status) throws. This is the writer half of the
|
|
10636
|
-
// marker that runtime-artifact-layout.cjs's finders already read (the reader
|
|
10637
|
-
// landed in #1476). It points at the package's own commands/gsd source.
|
|
10638
|
-
// Scoped to the Claude-global layout (issue #1477) — the only install path
|
|
10639
|
-
// that ships the skills layout without a commands/gsd source tree; every
|
|
10640
|
-
// other runtime/scope deploys commands/gsd, so its walk-up already resolves
|
|
10641
|
-
// and needs no marker. Guarded on source presence so a half-published
|
|
10642
|
-
// package never writes a dangling marker.
|
|
10643
|
-
if (_hostBehaviors(runtime).sourceMarkerFile && isGlobal) {
|
|
10644
|
-
const gsdSourceCommands = path.join(src, 'commands', 'gsd');
|
|
10645
|
-
if (fs.existsSync(gsdSourceCommands)) {
|
|
10646
|
-
try {
|
|
10647
|
-
// ADR-1239 Phase B write-confinement: the descriptor-sourced marker filename
|
|
10648
|
-
// must resolve under targetDir (parity with the other descriptor-driven writes).
|
|
10649
|
-
const _markerPath = assertDestWithinConfigHome(targetDir, _hostBehaviors(runtime).sourceMarkerFile);
|
|
10650
|
-
fs.writeFileSync(_markerPath, gsdSourceCommands + '\n', 'utf8');
|
|
10651
|
-
} catch (err) {
|
|
10652
|
-
// Non-fatal: install proceeds. But on the Claude-global layout walk-up
|
|
10653
|
-
// also fails (no commands/gsd source tree), so a silent write failure
|
|
10654
|
-
// still leaves /gsd-surface broken at runtime — warn so it's diagnosable.
|
|
10655
|
-
console.warn(` ${yellow}!${reset} Could not write .gsd-source marker (${err.message}); /gsd-surface list/status may fail`);
|
|
10656
|
-
}
|
|
10657
|
-
}
|
|
10658
|
-
}
|
|
10788
|
+
// #2624: the .gsd-source marker is now written by _writeGsdSourceMarker()
|
|
10789
|
+
// BEFORE staging reads it (see the early call above the _isSkillsRuntime
|
|
10790
|
+
// block). The former write lived here — AFTER staging — which on an upgrade
|
|
10791
|
+
// let staging read a stale prior-version marker and silently install
|
|
10792
|
+
// old-version skill content. Moved up; this site intentionally left empty.
|
|
10659
10793
|
|
|
10660
10794
|
// #1629 critical fix: Windsurf workflow wrappers (convertClaudeCommandToWindsurfWorkflow)
|
|
10661
10795
|
// delegate to command bodies at <targetDir>/gsd-core/commands/gsd/${stem}.md via a
|
|
@@ -11321,7 +11455,15 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
11321
11455
|
throw _earlyInstallErr;
|
|
11322
11456
|
}
|
|
11323
11457
|
|
|
11324
|
-
|
|
11458
|
+
// #2695: this branch runs for BOTH `core` (minimal) and `full` profiles.
|
|
11459
|
+
// Hooks are lightweight infrastructure (update-check + context monitor), not the
|
|
11460
|
+
// "full agent surface" that `core` deliberately omits. The config.toml / agent
|
|
11461
|
+
// generation below is still gated by its own inner `!isMinimalMode` guard, so
|
|
11462
|
+
// `core` enters the branch to receive the hook-file copy + hooks.json wiring but
|
|
11463
|
+
// does NOT get agent roles generated. Before #2695 the outer `!isMinimalMode`
|
|
11464
|
+
// here skipped the whole branch for `core`, so the registered parent hook pointed
|
|
11465
|
+
// at a worker/registry the same installer never delivered.
|
|
11466
|
+
if (plan.installSurface === 'codex-toml') {
|
|
11325
11467
|
// Capture pre-install snapshots before ANY GSD mutation
|
|
11326
11468
|
// (#2760 fix 3). On post-write schema-validation failure OR any throw
|
|
11327
11469
|
// during the mutation sequence (write failure, merge throw, etc.) we
|
|
@@ -11485,6 +11627,10 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
11485
11627
|
|
|
11486
11628
|
let agentCount = 0;
|
|
11487
11629
|
if (!isMinimalMode(_effectiveInstallMode)) {
|
|
11630
|
+
// #2834: write ~/.gsd/defaults.json (resolve_model_ids + runtime) BEFORE generating
|
|
11631
|
+
// agent TOMLs — installCodexConfig reads defaults.json at generation time, so on a
|
|
11632
|
+
// clean first install the runtime-aware model resolver must already know the runtime.
|
|
11633
|
+
writeNonClaudeDefaults(runtime);
|
|
11488
11634
|
try {
|
|
11489
11635
|
// Generate Codex config.toml and per-agent .toml files.
|
|
11490
11636
|
agentCount = installCodexConfig(targetDir, agentsSrc, plan.sandboxTier);
|
|
@@ -11504,9 +11650,18 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
11504
11650
|
|
|
11505
11651
|
// Copy only the hook files that Codex actually registers via its hook configuration (#2153).
|
|
11506
11652
|
// #772: added gsd-context-monitor.js for the new SubagentStart/Stop/PostToolUse events.
|
|
11653
|
+
// #2695: the parent gsd-check-update.js spawn()s gsd-check-update-worker.js, which
|
|
11654
|
+
// require()s managed-hooks-registry.cjs for MANAGED_HOOKS — so all four must be
|
|
11655
|
+
// installed/refreshed together for every profile, or Codex is wired to a dependency
|
|
11656
|
+
// chain the same installer never delivers.
|
|
11507
11657
|
// We deliberately do *not* copy gsd-graphify-update.sh or hooks/lib/ for Codex
|
|
11508
11658
|
// in this change (graphify auto-update support for Codex is out of scope for #3579).
|
|
11509
|
-
const CODEX_HOOKS_TO_COPY = [
|
|
11659
|
+
const CODEX_HOOKS_TO_COPY = [
|
|
11660
|
+
'gsd-check-update.js',
|
|
11661
|
+
'gsd-check-update-worker.js',
|
|
11662
|
+
'managed-hooks-registry.cjs',
|
|
11663
|
+
'gsd-context-monitor.js',
|
|
11664
|
+
];
|
|
11510
11665
|
const codexHooksSrc = path.join(src, 'hooks', 'dist');
|
|
11511
11666
|
if (fs.existsSync(codexHooksSrc)) {
|
|
11512
11667
|
const codexHooksDest = path.join(targetDir, 'hooks');
|
|
@@ -11536,9 +11691,28 @@ function install(isGlobal, runtime = DEFAULT_RUNTIME, options = {}) {
|
|
|
11536
11691
|
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
|
|
11537
11692
|
fs.writeFileSync(destFile, content);
|
|
11538
11693
|
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
|
|
11694
|
+
} else {
|
|
11695
|
+
// #2695: raw byte-for-byte copy for allowlisted artifacts that carry
|
|
11696
|
+
// no {{GSD_VERSION}} placeholder and no runtime path token (e.g.
|
|
11697
|
+
// managed-hooks-registry.cjs, whose only `.claude` mention is inside a
|
|
11698
|
+
// doc comment). Version/path transforms would be a no-op at best and a
|
|
11699
|
+
// surprise at worst; the issue requires the registry copied verbatim.
|
|
11700
|
+
fs.copyFileSync(srcFile, destFile);
|
|
11701
|
+
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
|
|
11539
11702
|
}
|
|
11540
11703
|
}
|
|
11541
11704
|
console.log(` ${green}✓${reset} Installed hooks (Codex)`);
|
|
11705
|
+
// #2717: write the CommonJS marker into hooks/ alongside the staged .js
|
|
11706
|
+
// scripts. Codex is excluded from installSharedHooksBundle by the
|
|
11707
|
+
// !isCodex gate, so it never received the marker the shared-bundle path
|
|
11708
|
+
// writes for the other runtimes. Without it, a ~/.codex/package.json
|
|
11709
|
+
// declaring {"type":"module"} makes Node load gsd-check-update.js /
|
|
11710
|
+
// gsd-context-monitor.js as ESM and their require() calls fail silently.
|
|
11711
|
+
// Reuses the same helper the Cursor/Windsurf writers call so the marker
|
|
11712
|
+
// content + user-file-preservation contract is identical everywhere.
|
|
11713
|
+
if (hooksSurface.ensureCommonJsMarker(codexHooksDest)) {
|
|
11714
|
+
console.log(` ${green}✓${reset} Wrote hooks/package.json (CommonJS mode)`);
|
|
11715
|
+
}
|
|
11542
11716
|
}
|
|
11543
11717
|
|
|
11544
11718
|
// Add Codex hooks (SessionStart for update checking) — requires codex_hooks feature flag
|
|
@@ -12232,58 +12406,11 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
|
|
|
12232
12406
|
configureAntigravityMcpConfig(isGlobal, configDir);
|
|
12233
12407
|
}
|
|
12234
12408
|
|
|
12235
|
-
//
|
|
12236
|
-
//
|
|
12237
|
-
//
|
|
12238
|
-
//
|
|
12239
|
-
|
|
12240
|
-
// chat model instead of pinning the resolved model. See #1156 (default-to-omit
|
|
12241
|
-
// intent) and #1569 (preserve explicit true). Guard matches the #130-class pattern
|
|
12242
|
-
// on configureOpencodePermissions above.
|
|
12243
|
-
if (!_hostBehaviors(runtime).nativeModelAliases && !process.env.GSD_TEST_MODE) {
|
|
12244
|
-
const gsdDir = path.join(os.homedir(), '.gsd');
|
|
12245
|
-
const defaultsPath = path.join(gsdDir, 'defaults.json');
|
|
12246
|
-
try {
|
|
12247
|
-
fs.mkdirSync(gsdDir, { recursive: true });
|
|
12248
|
-
let defaults = {};
|
|
12249
|
-
try { defaults = JSON.parse(fs.readFileSync(defaultsPath, 'utf8')); } catch { /* new file */ }
|
|
12250
|
-
// Recover a malformed (valid-JSON-but-non-object) defaults.json to a fresh object so
|
|
12251
|
-
// the write below succeeds and the file is no longer broken. Without this, `null` /
|
|
12252
|
-
// `[]` / a number / a string bypass the parse catch and either throw a TypeError on
|
|
12253
|
-
// property access (swallowed by the outer try/catch, leaving the file broken) or get
|
|
12254
|
-
// a property set that won't round-trip through JSON.stringify. (#1657)
|
|
12255
|
-
if (defaults === null || typeof defaults !== 'object' || Array.isArray(defaults)) {
|
|
12256
|
-
defaults = {};
|
|
12257
|
-
}
|
|
12258
|
-
// Three-valued domain: false/absent → aliases; true → full IDs; "omit" → ''.
|
|
12259
|
-
// Honor ONLY an explicit canonical `true` opt-in (full model IDs) and an existing
|
|
12260
|
-
// "omit"; default everything else — absent, falsy, OR any non-canonical value — to
|
|
12261
|
-
// "omit", the safe non-Claude default. Allowlist-based so malformed values
|
|
12262
|
-
// (0, "", "yes", {}, …) don't leak Claude aliases the runtime can't resolve (#1569).
|
|
12263
|
-
const existing = defaults.resolve_model_ids;
|
|
12264
|
-
const shouldDefaultToOmit = existing !== true && existing !== 'omit';
|
|
12265
|
-
if (shouldDefaultToOmit) {
|
|
12266
|
-
defaults.resolve_model_ids = 'omit';
|
|
12267
|
-
fs.writeFileSync(defaultsPath, JSON.stringify(defaults, null, 2) + '\n');
|
|
12268
|
-
console.log(` ${green}✓${reset} Set resolve_model_ids: "omit" in ~/.gsd/defaults.json`);
|
|
12269
|
-
}
|
|
12270
|
-
|
|
12271
|
-
// #2395: also persist `runtime: <runtime>` for non-Claude runtimes, so
|
|
12272
|
-
// resolveRuntime() (precedence: GSD_RUNTIME env > config.runtime > 'claude')
|
|
12273
|
-
// resolves to the install's actual runtime identity out of the box — without
|
|
12274
|
-
// this, agent_runtime and every runtime-branded slash hint falls through to
|
|
12275
|
-
// the hard-coded 'claude' default. Mirrors the resolve_model_ids write above:
|
|
12276
|
-
// honor an explicit pre-existing value (any string), only default-populating
|
|
12277
|
-
// when absent. Claude is the resolveRuntime() fallback, so it needs no write.
|
|
12278
|
-
if (defaults.runtime === undefined || defaults.runtime === null || defaults.runtime === '') {
|
|
12279
|
-
defaults.runtime = runtime;
|
|
12280
|
-
fs.writeFileSync(defaultsPath, JSON.stringify(defaults, null, 2) + '\n');
|
|
12281
|
-
console.log(` ${green}✓${reset} Set runtime: "${runtime}" in ~/.gsd/defaults.json`);
|
|
12282
|
-
}
|
|
12283
|
-
} catch (e) {
|
|
12284
|
-
console.log(` ${yellow}⚠${reset} Could not write ~/.gsd/defaults.json: ${e.message}`);
|
|
12285
|
-
}
|
|
12286
|
-
}
|
|
12409
|
+
// #2834: defaults.json (resolve_model_ids + runtime) is now written BEFORE
|
|
12410
|
+
// installCodexConfig via writeNonClaudeDefaults(runtime) — extracted into a
|
|
12411
|
+
// function so it can run at the right point in the flow (before agent TOML
|
|
12412
|
+
// generation reads it). This call is idempotent (preserves existing values).
|
|
12413
|
+
writeNonClaudeDefaults(runtime);
|
|
12287
12414
|
|
|
12288
12415
|
// program + command are now single-source lookups (ADR-1239 Phase B / #1679):
|
|
12289
12416
|
// program is the runtime display label; command is the per-host /gsd-new-project
|
|
@@ -12390,16 +12517,17 @@ const runtimeMap = {
|
|
|
12390
12517
|
'8': 'cursor',
|
|
12391
12518
|
'9': 'hermes',
|
|
12392
12519
|
'10': 'kimi',
|
|
12393
|
-
'11': '
|
|
12394
|
-
'12': '
|
|
12395
|
-
'13': '
|
|
12396
|
-
'14': '
|
|
12397
|
-
'15': '
|
|
12398
|
-
'16': '
|
|
12399
|
-
'17': '
|
|
12520
|
+
'11': 'kimi-code',
|
|
12521
|
+
'12': 'kilo',
|
|
12522
|
+
'13': 'opencode',
|
|
12523
|
+
'14': 'pi',
|
|
12524
|
+
'15': 'qwen',
|
|
12525
|
+
'16': 'trae',
|
|
12526
|
+
'17': 'windsurf',
|
|
12527
|
+
'18': 'zcode'
|
|
12400
12528
|
};
|
|
12401
|
-
const allRuntimes = ['claude', 'antigravity', 'augment', 'cline', 'codebuddy', 'codex', 'copilot', 'cursor', 'hermes', 'kimi', 'kilo', 'opencode', 'pi', 'qwen', 'trae', 'windsurf', 'zcode'];
|
|
12402
|
-
const ALL_RUNTIMES_OPTION = '
|
|
12529
|
+
const allRuntimes = ['claude', 'antigravity', 'augment', 'cline', 'codebuddy', 'codex', 'copilot', 'cursor', 'hermes', 'kimi', 'kimi-code', 'kilo', 'opencode', 'pi', 'qwen', 'trae', 'windsurf', 'zcode'];
|
|
12530
|
+
const ALL_RUNTIMES_OPTION = '19';
|
|
12403
12531
|
|
|
12404
12532
|
/**
|
|
12405
12533
|
* Build the runtime-selection prompt text shown by the interactive installer.
|
|
@@ -12417,14 +12545,15 @@ function buildRuntimePromptText() {
|
|
|
12417
12545
|
${cyan}8${reset}) Cursor ${dim}(~/.cursor)${reset}
|
|
12418
12546
|
${cyan}9${reset}) Hermes Agent ${dim}(~/.hermes)${reset}
|
|
12419
12547
|
${cyan}10${reset}) Kimi ${dim}(~/.config/agents, then ~/.agents if existing)${reset}
|
|
12420
|
-
${cyan}11${reset})
|
|
12421
|
-
${cyan}12${reset})
|
|
12422
|
-
${cyan}13${reset})
|
|
12423
|
-
${cyan}14${reset})
|
|
12424
|
-
${cyan}15${reset})
|
|
12425
|
-
${cyan}16${reset})
|
|
12426
|
-
${cyan}17${reset})
|
|
12427
|
-
${cyan}18${reset})
|
|
12548
|
+
${cyan}11${reset}) Kimi Code ${dim}(~/.kimi-code)${reset}
|
|
12549
|
+
${cyan}12${reset}) Kilo ${dim}(~/.config/kilo)${reset}
|
|
12550
|
+
${cyan}13${reset}) OpenCode ${dim}(~/.config/opencode)${reset}
|
|
12551
|
+
${cyan}14${reset}) pi ${dim}(~/.pi/agent)${reset}
|
|
12552
|
+
${cyan}15${reset}) Qwen Code ${dim}(~/.qwen)${reset}
|
|
12553
|
+
${cyan}16${reset}) Trae ${dim}(~/.trae)${reset}
|
|
12554
|
+
${cyan}17${reset}) Windsurf ${dim}(~/.codeium/windsurf)${reset}
|
|
12555
|
+
${cyan}18${reset}) ZCode ${dim}(~/.zcode)${reset}
|
|
12556
|
+
${cyan}19${reset}) All
|
|
12428
12557
|
|
|
12429
12558
|
${dim}Select multiple: 1,2,6 or 1 2 6${reset}
|
|
12430
12559
|
`;
|
|
@@ -12435,7 +12564,7 @@ function buildRuntimePromptText() {
|
|
|
12435
12564
|
* Pure function — exported so tests can verify split/dedupe/fallback behavior.
|
|
12436
12565
|
* - Accepts comma- and/or whitespace-separated choices
|
|
12437
12566
|
* - Deduplicates while preserving order
|
|
12438
|
-
* - Maps option
|
|
12567
|
+
* - Maps option 19 ("All") to every runtime
|
|
12439
12568
|
* - Falls back to ['claude'] when nothing valid is selected
|
|
12440
12569
|
*/
|
|
12441
12570
|
function parseRuntimeInput(answer) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:plan-review-convergence
|
|
3
3
|
description: "Cross-AI plan convergence - replan until review concerns are resolved."
|
|
4
|
-
argument-hint: "<phase> [--
|
|
4
|
+
argument-hint: "<phase> [--gemini] [--claude] [--codex] [--coderabbit] [--opencode] [--qwen] [--cursor] [--antigravity] [--agy] [--ollama] [--lm-studio] [--llama-cpp] [--kimi-code] [--text] [--ws <name>] [--all] [--max-cycles N]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -44,10 +44,14 @@ Phase number: extracted from $ARGUMENTS (required)
|
|
|
44
44
|
- `--gemini` — Use Gemini CLI as reviewer
|
|
45
45
|
- `--agy` / `--antigravity` — Use Antigravity CLI as reviewer (successor to the discontinued Gemini CLI)
|
|
46
46
|
- `--claude` — Use Claude CLI as reviewer (separate session)
|
|
47
|
+
- `--coderabbit` — Use CodeRabbit as reviewer (reviews the working-tree diff, not the source tree)
|
|
47
48
|
- `--opencode` — Use OpenCode as reviewer
|
|
49
|
+
- `--qwen` — Use Qwen Code CLI as reviewer (Alibaba Qwen models)
|
|
50
|
+
- `--cursor` — Use Cursor agent as reviewer
|
|
48
51
|
- `--ollama` — Use local Ollama server as reviewer (OpenAI-compatible, default host `http://localhost:11434`; configure model via `review.models.ollama`)
|
|
49
52
|
- `--lm-studio` — Use local LM Studio server as reviewer (OpenAI-compatible, default host `http://localhost:1234`; configure model via `review.models.lm_studio`)
|
|
50
53
|
- `--llama-cpp` — Use local llama.cpp server as reviewer (OpenAI-compatible, default host `http://localhost:8080`; configure model via `review.models.llama_cpp`)
|
|
54
|
+
- `--kimi-code` — Use Kimi Code CLI as reviewer (Moonshot AI)
|
|
51
55
|
- `--all` — Use all available CLIs and running local model servers
|
|
52
56
|
- `--max-cycles N` — Maximum replan→review cycles (default: 3)
|
|
53
57
|
|