@opengsd/gsd-core 1.7.0-rc.2 → 1.7.0-rc.4
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/GEMINI.md +25 -23
- package/README.ja-JP.md +4 -3
- package/README.ko-KR.md +4 -3
- package/README.md +7 -6
- package/README.pt-BR.md +4 -3
- package/README.zh-CN.md +4 -3
- package/agents/gsd-advisor-researcher.md +1 -1
- package/agents/gsd-ai-researcher.md +1 -1
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-debug-session-manager.md +1 -1
- package/agents/gsd-debugger.md +1 -1
- package/agents/gsd-domain-researcher.md +1 -1
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-executor.md +4 -4
- package/agents/gsd-intel-updater.md +1 -1
- package/agents/gsd-mempalace-curator.md +1 -1
- package/agents/gsd-phase-researcher.md +2 -2
- package/agents/gsd-plan-checker.md +1 -1
- package/agents/gsd-planner.md +2 -2
- package/agents/gsd-project-researcher.md +2 -2
- package/agents/gsd-research-synthesizer.md +1 -1
- package/agents/gsd-ui-researcher.md +2 -2
- package/agents/gsd-verifier.md +2 -2
- package/bin/install.js +132 -464
- package/commands/gsd/map-codebase.md +4 -4
- package/commands/gsd/mempalace-capture.md +1 -1
- package/commands/gsd/mempalace-recall.md +9 -5
- package/commands/gsd/next.md +29 -0
- package/commands/gsd/ns-project.md +2 -1
- package/commands/gsd/ns-workflow.md +5 -2
- package/commands/gsd/onboard.md +46 -0
- package/gsd-core/bin/ensure-runtime-build.cjs +246 -0
- package/gsd-core/bin/gsd-tools.cjs +72 -3
- package/gsd-core/bin/lib/capability-registry.cjs +684 -264
- package/gsd-core/bin/lib/capability-state.cjs +117 -18
- package/gsd-core/bin/lib/capability-writer.cjs +11 -1
- package/gsd-core/bin/lib/check-command-router.cjs +111 -1
- package/gsd-core/bin/lib/claude-orchestration-command-router.cjs +136 -0
- package/gsd-core/bin/lib/claude-orchestration.cjs +404 -0
- package/gsd-core/bin/lib/clusters.cjs +2 -0
- package/gsd-core/bin/lib/command-aliases.cjs +8 -0
- package/gsd-core/bin/lib/config.cjs +19 -1
- package/gsd-core/bin/lib/core-utils.cjs +41 -0
- package/gsd-core/bin/lib/external-job.cjs +287 -0
- package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +151 -0
- package/gsd-core/bin/lib/graphify.cjs +41 -9
- package/gsd-core/bin/lib/init-command-router.cjs +4 -0
- package/gsd-core/bin/lib/init.cjs +25 -69
- package/gsd-core/bin/lib/install-engine.cjs +8 -5
- package/gsd-core/bin/lib/install-profiles.cjs +2 -0
- package/gsd-core/bin/lib/loop-resolver.cjs +7 -1
- package/gsd-core/bin/lib/milestone.cjs +7 -1
- package/gsd-core/bin/lib/model-resolver.cjs +69 -4
- package/gsd-core/bin/lib/onboard-projection.cjs +309 -0
- package/gsd-core/bin/lib/phase.cjs +14 -2
- package/gsd-core/bin/lib/plan-scan.cjs +9 -1
- package/gsd-core/bin/lib/profile-output.cjs +1 -1
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +21 -19
- package/gsd-core/bin/lib/roadmap.cjs +17 -2
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +18 -13
- package/gsd-core/bin/lib/runtime-name-policy.cjs +11 -11
- package/gsd-core/bin/lib/shell-command-projection.cjs +12 -8
- package/gsd-core/bin/lib/smart-entry.cjs +521 -0
- package/gsd-core/bin/lib/surface.cjs +63 -33
- package/gsd-core/bin/lib/update-context.cjs +0 -5
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
- package/gsd-core/bin/shared/model-catalog.json +5 -5
- package/gsd-core/bin/shared/runtime-aliases.manifest.json +0 -5
- package/gsd-core/references/gates.md +1 -1
- package/gsd-core/references/gsd-run-resolver.md +8 -0
- package/gsd-core/references/planning-config.md +1 -1
- package/gsd-core/templates/project.md +1 -1
- package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/gsd-core/workflows/add-backlog.md +1 -1
- package/gsd-core/workflows/add-phase.md +1 -1
- package/gsd-core/workflows/add-tests.md +1 -1
- package/gsd-core/workflows/add-todo.md +1 -1
- package/gsd-core/workflows/ai-integration-phase.md +1 -1
- package/gsd-core/workflows/audit-fix.md +1 -1
- package/gsd-core/workflows/audit-milestone.md +1 -1
- package/gsd-core/workflows/audit-uat.md +1 -1
- package/gsd-core/workflows/autonomous.md +1 -1
- package/gsd-core/workflows/check-todos.md +1 -1
- package/gsd-core/workflows/cleanup.md +1 -1
- package/gsd-core/workflows/code-review-fix.md +1 -1
- package/gsd-core/workflows/code-review.md +1 -1
- package/gsd-core/workflows/complete-milestone.md +1 -1
- package/gsd-core/workflows/debug.md +1 -1
- package/gsd-core/workflows/diagnose-issues.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/auto.md +1 -1
- package/gsd-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +1 -1
- package/gsd-core/workflows/discuss-phase.md +2 -2
- package/gsd-core/workflows/do.md +5 -4
- package/gsd-core/workflows/docs-update.md +1 -1
- package/gsd-core/workflows/edit-phase.md +1 -1
- package/gsd-core/workflows/eval-review.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +1 -1
- package/gsd-core/workflows/execute-phase.md +4 -5
- package/gsd-core/workflows/execute-plan.md +1 -1
- package/gsd-core/workflows/explore.md +1 -1
- package/gsd-core/workflows/extract-learnings.md +1 -1
- package/gsd-core/workflows/forensics.md +1 -1
- package/gsd-core/workflows/graduation.md +1 -1
- package/gsd-core/workflows/health.md +1 -1
- package/gsd-core/workflows/help/modes/brief.md +2 -1
- package/gsd-core/workflows/help/modes/default.md +2 -1
- package/gsd-core/workflows/help/modes/full.md +25 -1
- package/gsd-core/workflows/help/modes/topic.md +2 -1
- package/gsd-core/workflows/import.md +1 -1
- package/gsd-core/workflows/ingest-docs.md +1 -1
- package/gsd-core/workflows/insert-phase.md +1 -1
- package/gsd-core/workflows/list-seeds.md +1 -1
- package/gsd-core/workflows/list-workspaces.md +1 -1
- package/gsd-core/workflows/manager.md +1 -1
- package/gsd-core/workflows/map-codebase.md +1 -1
- package/gsd-core/workflows/milestone-summary.md +1 -1
- package/gsd-core/workflows/mvp-phase.md +1 -1
- package/gsd-core/workflows/new-milestone.md +1 -1
- package/gsd-core/workflows/new-project.md +1 -1
- package/gsd-core/workflows/new-workspace.md +1 -1
- package/gsd-core/workflows/next.md +1 -1
- package/gsd-core/workflows/onboard.md +277 -0
- package/gsd-core/workflows/pause-work.md +1 -1
- package/gsd-core/workflows/plan-milestone-gaps.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +1 -1
- package/gsd-core/workflows/plan-phase.md +9 -2
- package/gsd-core/workflows/plan-review-convergence.md +1 -1
- package/gsd-core/workflows/plant-seed.md +1 -1
- package/gsd-core/workflows/pr-branch.md +1 -1
- package/gsd-core/workflows/profile-user.md +1 -1
- package/gsd-core/workflows/progress.md +1 -1
- package/gsd-core/workflows/quick.md +21 -1
- package/gsd-core/workflows/reapply-patches.md +1 -1
- package/gsd-core/workflows/remove-phase.md +1 -1
- package/gsd-core/workflows/remove-workspace.md +1 -1
- package/gsd-core/workflows/resume-project.md +1 -1
- package/gsd-core/workflows/review.md +43 -7
- package/gsd-core/workflows/scan.md +1 -1
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/settings-advanced.md +3 -1
- package/gsd-core/workflows/settings-integrations.md +1 -1
- package/gsd-core/workflows/settings.md +1 -1
- package/gsd-core/workflows/ship.md +1 -1
- package/gsd-core/workflows/sketch-wrap-up.md +1 -1
- package/gsd-core/workflows/sketch.md +1 -1
- package/gsd-core/workflows/smart-entry.md +120 -0
- package/gsd-core/workflows/spec-phase.md +8 -6
- package/gsd-core/workflows/spike-wrap-up.md +1 -1
- package/gsd-core/workflows/spike.md +1 -1
- package/gsd-core/workflows/stats.md +1 -1
- package/gsd-core/workflows/thread.md +1 -1
- package/gsd-core/workflows/transition.md +1 -1
- package/gsd-core/workflows/ui-phase.md +1 -1
- package/gsd-core/workflows/ui-review.md +1 -1
- package/gsd-core/workflows/ultraplan-phase.md +1 -1
- package/gsd-core/workflows/update.md +3 -6
- package/gsd-core/workflows/validate-phase.md +1 -1
- package/gsd-core/workflows/verify-phase.md +1 -1
- package/gsd-core/workflows/verify-work.md +62 -4
- package/package.json +3 -5
- package/scripts/ci-test-scope.cjs +19 -1
- package/scripts/gen-golden-install-parity-zcode.cjs +77 -0
- package/scripts/generate-package-identity.cjs +27 -2
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -148
- package/scripts/lint-regression-test-names.allowlist.json +1 -273
- package/scripts/lint-test-file-count.allowlist.json +7 -91
- package/scripts/research-profiles.cjs +6 -6
- package/scripts/run-tests.cjs +18 -3
- package/scripts/slurm-adapter.cjs +269 -0
- package/scripts/sync-manifest-versions.cjs +3 -2
- package/scripts/sync-runtime-launcher.cjs +20 -2
- package/skills/gsd-map-codebase/SKILL.md +3 -3
- package/skills/gsd-mempalace-capture/SKILL.md +1 -1
- package/skills/gsd-mempalace-recall/SKILL.md +9 -5
- package/skills/gsd-next/SKILL.md +30 -0
- package/skills/gsd-ns-project/SKILL.md +1 -0
- package/skills/gsd-ns-workflow/SKILL.md +4 -1
- package/skills/gsd-onboard/SKILL.md +46 -0
- package/gemini-extension.json +0 -6
|
@@ -9,7 +9,7 @@ allowed-tools:
|
|
|
9
9
|
- Grep
|
|
10
10
|
- Write
|
|
11
11
|
- Agent
|
|
12
|
-
requires: [config, new-project, plan-phase]
|
|
12
|
+
requires: [config, new-project, plan-phase, onboard]
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
<objective>
|
|
@@ -42,7 +42,7 @@ Parse the first token of $ARGUMENTS:
|
|
|
42
42
|
Check for .planning/STATE.md - loads context if project already initialized
|
|
43
43
|
|
|
44
44
|
**This command can run:**
|
|
45
|
-
-
|
|
45
|
+
- Via /gsd:onboard for first-time brownfield setup - creates codebase map first
|
|
46
46
|
- After /gsd:new-project (greenfield codebases) - updates codebase map as code evolves
|
|
47
47
|
- Anytime to refresh codebase understanding
|
|
48
48
|
</context>
|
|
@@ -51,7 +51,7 @@ Check for .planning/STATE.md - loads context if project already initialized
|
|
|
51
51
|
**Use map-codebase for:**
|
|
52
52
|
- Brownfield projects before initialization (understand existing code first)
|
|
53
53
|
- Refreshing codebase map after significant changes
|
|
54
|
-
-
|
|
54
|
+
- Refreshing or deepening an onboarded codebase map
|
|
55
55
|
- Before major refactoring (understand current state)
|
|
56
56
|
- When STATE.md references outdated codebase info
|
|
57
57
|
|
|
@@ -71,7 +71,7 @@ Check for .planning/STATE.md - loads context if project already initialized
|
|
|
71
71
|
4. Wait for agents to complete, collect confirmations (NOT document contents)
|
|
72
72
|
5. Verify all 7 documents exist with line counts
|
|
73
73
|
6. Commit codebase map
|
|
74
|
-
7. Offer next steps (typically: /gsd:new-project or /gsd:plan-phase)
|
|
74
|
+
7. Offer next steps (typically: /gsd:onboard, /gsd:new-project, or /gsd:plan-phase)
|
|
75
75
|
</process>
|
|
76
76
|
|
|
77
77
|
<success_criteria>
|
|
@@ -56,7 +56,7 @@ On any error or timeout, stop and let the phase continue -- capture is best-effo
|
|
|
56
56
|
|
|
57
57
|
1. **Dedup first.** Interactive: `mempalace_check_duplicate` on the artifact's deterministic drawer id. Headless: rely on `mempalace mine`'s content-hash idempotency.
|
|
58
58
|
2. **Add the drawer (verbatim).** File the exact artifact text into `room: <room>` of `wing: <wing>` with provenance (`source_file`, phase id). Interactive: `mempalace_add_drawer`. Headless: `mempalace mine <path> --wing <wing> --room <room>`.
|
|
59
|
-
3. **Mirror KG facts** when `config.mempalace.mirror_kg` is true: extract decision/delivery facts and `mempalace_kg_add` them with `valid_from` = the phase date (e.g. `(<project>, decided, <decision>)` from CONTEXT; `(<phase>, delivered, <capability>)` from SUMMARY).
|
|
59
|
+
3. **Mirror KG facts** when `config.mempalace.mirror_kg` is true: extract decision/delivery facts and `mempalace_kg_add` them with `valid_from` = the phase date (e.g. `(<project>, decided, <decision>)` from CONTEXT; `(<phase>, delivered, <capability>)` from SUMMARY). Under `augment` these are an *additive* mirror of GSD's native `.planning/graphs/`. Under `kg_backend`/`replace` the palace KG is the *authoritative* fact store — GSD still produces `.planning/graphs/` through its normal graphify, so an unreachable palace never loses a fact.
|
|
60
60
|
4. Re-running a phase MUST NOT create duplicate drawers (deterministic ids + `check_duplicate`).
|
|
61
61
|
|
|
62
62
|
## Step 4 -- Report
|
|
@@ -48,13 +48,17 @@ This step is `onError: skip` at `plan:pre` -- recall never blocks planning.
|
|
|
48
48
|
## Step 2 -- Resolve wing, mode, and transport
|
|
49
49
|
|
|
50
50
|
1. **Wing.** Use `config.mempalace.wing` if non-empty; otherwise derive from `config.project_code`; otherwise fall back to the repository directory name.
|
|
51
|
-
2. **Mode.** Read `config.mempalace.memory_mode` (`augment` | `kg_backend` | `replace`, default `augment`).
|
|
51
|
+
2. **Mode.** Read `config.mempalace.memory_mode` (`augment` | `kg_backend` | `replace`, default `augment`). It sets how authoritative the palace is during recall:
|
|
52
|
+
- `augment` — the palace is an *additional* layer; read native memory (`.planning/graphs/`, STATE) too and treat the palace as supplementary.
|
|
53
|
+
- `kg_backend` — for knowledge-graph facts, query the palace's temporal KG *first, as the primary source*; fall back to `.planning/graphs/` when the palace is unreachable. Non-KG drawer recall stays additive.
|
|
54
|
+
- `replace` — resolve recall *through the palace as the source of truth*; consult native artifacts only as a fallback when the palace is unreachable.
|
|
55
|
+
In every mode an unreachable palace degrades to native memory — recall never blocks (`onError: skip`).
|
|
52
56
|
3. **Transport.** Prefer the **MCP tools** (`mempalace_*`) in interactive runs *when your MemPalace MCP server is registered and your runtime permits those tools*. Otherwise — headless/cron/autonomous runs, or runtimes that don't grant the MemPalace MCP tools — use the **CLI** (`mempalace wake-up`, `mempalace search`), which this skill's `Bash` allow-tool always covers. If neither is reachable, go to Step 4.
|
|
53
57
|
4. **Topic.** Read the phase `CONTEXT.md` (the consumed artifact). Derive a short search query from its title, goal, and key decisions.
|
|
54
58
|
|
|
55
59
|
## Step 3 -- Retrieve (read-only)
|
|
56
60
|
|
|
57
|
-
All calls in this step are side-effect-free. On any error or timeout, stop retrieving and write whatever was gathered (or the stub) -- never raise.
|
|
61
|
+
All calls in this step are side-effect-free. On any error or timeout, stop retrieving and write whatever was gathered (or the stub) -- never raise. This skill reads only the palace; GSD's planner reads native memory (`.planning/graphs/`, STATE) regardless. So under `kg_backend`/`replace` an unreachable palace falls back to that native memory automatically — reflect that in the stub (Step 4) rather than implying memory is gone.
|
|
58
62
|
|
|
59
63
|
1. **Wake up** (cheap, ~600--900 tokens):
|
|
60
64
|
- Interactive: read the wing identity/summary, then `mempalace_search`.
|
|
@@ -62,7 +66,7 @@ All calls in this step are side-effect-free. On any error or timeout, stop retri
|
|
|
62
66
|
2. **Targeted search:**
|
|
63
67
|
- Interactive: `mempalace_search(query=<topic>, wing=<wing>)`.
|
|
64
68
|
- Headless: `mempalace search "<topic>" --wing <wing>`.
|
|
65
|
-
3. **Knowledge-graph facts** (when `config.mempalace.mirror_kg` is true): `mempalace_kg_query` / `mempalace_kg_timeline` for decisions relevant to the topic and their validity windows.
|
|
69
|
+
3. **Knowledge-graph facts** (when `config.mempalace.mirror_kg` is true): `mempalace_kg_query` / `mempalace_kg_timeline` for decisions relevant to the topic and their validity windows. Under `augment` the palace KG *supplements* GSD's native `.planning/graphs/` — combine both, do not treat the palace as the sole source. Under `kg_backend` or `replace` the palace KG is the *primary* graph source — query it first and use `.planning/graphs/` only as a fallback when the palace is unreachable.
|
|
66
70
|
4. **Dedup** the returned drawers/facts; keep the top results.
|
|
67
71
|
|
|
68
72
|
## Step 4 -- Write MEMORY-RECALL.md
|
|
@@ -86,12 +90,12 @@ _Wing: <wing> · Mode: <mode> · Transport: <mcp|cli>_
|
|
|
86
90
|
- <surprise> — <provenance>
|
|
87
91
|
```
|
|
88
92
|
|
|
89
|
-
When MemPalace is unreachable, write the stub and continue:
|
|
93
|
+
When MemPalace is unreachable, write the stub and continue. Under `kg_backend`/`replace`, name the native fallback so the planner knows memory is not gone — only un-augmented by the palace this run:
|
|
90
94
|
|
|
91
95
|
```markdown
|
|
92
96
|
# Memory Recall (MemPalace)
|
|
93
97
|
|
|
94
|
-
_MemPalace unavailable at recall time —
|
|
98
|
+
_MemPalace unavailable at recall time — falling back to GSD native memory (`.planning/graphs/`, STATE). No palace recall this run._
|
|
95
99
|
```
|
|
96
100
|
|
|
97
101
|
## Anti-Patterns
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:next
|
|
3
|
+
description: Smart entry — detect project state and route to the right next GSD action.
|
|
4
|
+
effort: low
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Glob
|
|
9
|
+
- SlashCommand
|
|
10
|
+
- AskUserQuestion
|
|
11
|
+
---
|
|
12
|
+
<objective>
|
|
13
|
+
GSD smart entry — the state-aware front door. Detect what's going on in this project, then present a short menu of the right next actions and dispatch to one.
|
|
14
|
+
|
|
15
|
+
This is a launcher/router only. It never does the work itself. It reads project + workflow state via `gsd-tools smart-entry --json`, shows a situation-appropriate menu, and hands off to an existing GSD command.
|
|
16
|
+
</objective>
|
|
17
|
+
|
|
18
|
+
<execution_context>
|
|
19
|
+
@~/.claude/gsd-core/workflows/smart-entry.md
|
|
20
|
+
@~/.claude/gsd-core/references/ui-brand.md
|
|
21
|
+
</execution_context>
|
|
22
|
+
|
|
23
|
+
<context>
|
|
24
|
+
Arguments: $ARGUMENTS
|
|
25
|
+
</context>
|
|
26
|
+
|
|
27
|
+
<process>
|
|
28
|
+
Follow ~/.claude/gsd-core/workflows/smart-entry.md. Detect the situation, present the menu, and dispatch exactly one command. Then stop.
|
|
29
|
+
</process>
|
|
@@ -5,7 +5,7 @@ argument-hint: ""
|
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Skill
|
|
8
|
-
requires: [new-project, new-milestone, complete-milestone, audit-milestone, milestone-summary, import, ingest-docs, profile-user, review-backlog]
|
|
8
|
+
requires: [new-project, onboard, new-milestone, complete-milestone, audit-milestone, milestone-summary, import, ingest-docs, profile-user, review-backlog]
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
Route to the appropriate project / milestone skill based on the user's intent.
|
|
@@ -15,6 +15,7 @@ inline as part of `gsd-audit-milestone`'s output.
|
|
|
15
15
|
| User wants | Invoke |
|
|
16
16
|
|---|---|
|
|
17
17
|
| Start a new project | gsd-new-project |
|
|
18
|
+
| Onboard an existing codebase | gsd-onboard |
|
|
18
19
|
| Create a new milestone | gsd-new-milestone |
|
|
19
20
|
| Complete the current milestone | gsd-complete-milestone |
|
|
20
21
|
| Audit a milestone for issues | gsd-audit-milestone |
|
|
@@ -5,13 +5,15 @@ argument-hint: ""
|
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Skill
|
|
8
|
-
requires: [discuss-phase, spec-phase, plan-phase, execute-phase, verify-work, phase, progress, ultraplan-phase, plan-review-convergence, add-tests, ai-integration-phase, autonomous, fast, mvp-phase, quick]
|
|
8
|
+
requires: [discuss-phase, spec-phase, plan-phase, execute-phase, verify-work, phase, progress, next, ultraplan-phase, plan-review-convergence, add-tests, ai-integration-phase, autonomous, fast, mvp-phase, quick]
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
Route to the appropriate phase-pipeline skill based on the user's intent.
|
|
12
12
|
Sub-skill names below are post-#2790 consolidated targets — `gsd-phase`
|
|
13
13
|
absorbs the former add/insert/remove/edit-phase commands and `gsd-progress`
|
|
14
|
-
absorbs the former next/do commands.
|
|
14
|
+
absorbs the former next/do workflow-advance commands. The reclaimed
|
|
15
|
+
`gsd-next` target is the state-aware smart-entry launcher, not the retired
|
|
16
|
+
workflow-advance command.
|
|
15
17
|
|
|
16
18
|
| User wants | Invoke |
|
|
17
19
|
|---|---|
|
|
@@ -22,6 +24,7 @@ absorbs the former next/do commands.
|
|
|
22
24
|
| Verify built features through UAT | gsd-verify-work |
|
|
23
25
|
| Add / insert / remove / edit a phase | gsd-phase |
|
|
24
26
|
| Advance to the next logical step | gsd-progress |
|
|
27
|
+
| Open the state-aware smart-entry launcher | gsd-next |
|
|
25
28
|
| Offload planning to the ultraplan cloud | gsd-ultraplan-phase |
|
|
26
29
|
| Cross-AI plan review convergence loop | gsd-plan-review-convergence |
|
|
27
30
|
| Generate tests for a completed phase | gsd-add-tests |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gsd:onboard
|
|
3
|
+
description: Guide existing codebase onboarding through mapping, doc ingest, and planning setup
|
|
4
|
+
argument-hint: "[--fast] [--text]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Write
|
|
9
|
+
- Glob
|
|
10
|
+
- Grep
|
|
11
|
+
- Agent
|
|
12
|
+
- AskUserQuestion
|
|
13
|
+
requires: [config, new-project, map-codebase, ingest-docs, manager]
|
|
14
|
+
---
|
|
15
|
+
<runtime_note>
|
|
16
|
+
**Copilot (VS Code):** Use `vscode_askquestions` wherever this workflow calls `AskUserQuestion`. They are equivalent — `vscode_askquestions` is the VS Code Copilot implementation of the same interactive question API.
|
|
17
|
+
</runtime_note>
|
|
18
|
+
|
|
19
|
+
<objective>
|
|
20
|
+
Guide brownfield onboarding for an existing codebase by routing through the existing GSD primitives in the safe order: codebase map → docs ingest → project initialization → onboarding summary.
|
|
21
|
+
|
|
22
|
+
**Creates or confirms:**
|
|
23
|
+
- `.planning/codebase/` — evidence-backed codebase map from `/gsd:map-codebase`
|
|
24
|
+
- `.planning/PROJECT.md`, `REQUIREMENTS.md`, `ROADMAP.md`, `STATE.md` — project setup from `/gsd:new-project` or `/gsd:ingest-docs`
|
|
25
|
+
- `.planning/onboarding/SUMMARY.md` — lightweight index of what was learned and the next command
|
|
26
|
+
|
|
27
|
+
**Non-goals:** This command does not execute phases, ship work, or overwrite existing planning artifacts without an explicit gate.
|
|
28
|
+
</objective>
|
|
29
|
+
|
|
30
|
+
<execution_context>
|
|
31
|
+
@~/.claude/gsd-core/workflows/onboard.md
|
|
32
|
+
@~/.claude/gsd-core/references/ui-brand.md
|
|
33
|
+
@~/.claude/gsd-core/references/gate-prompts.md
|
|
34
|
+
</execution_context>
|
|
35
|
+
|
|
36
|
+
<context>
|
|
37
|
+
Arguments: $ARGUMENTS
|
|
38
|
+
|
|
39
|
+
Flags:
|
|
40
|
+
- `--fast` — prefer `/gsd:map-codebase --fast` for the mapping handoff; the complete map is still required before `/gsd:new-project`.
|
|
41
|
+
- `--text` — use plain-text numbered lists instead of TUI menus.
|
|
42
|
+
</context>
|
|
43
|
+
|
|
44
|
+
<process>
|
|
45
|
+
Execute the onboard workflow end-to-end. Preserve all safety gates, text-mode fallbacks, idempotency checks, and top-level handoff rules for nested interactive commands.
|
|
46
|
+
</process>
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Self-healing runtime build (#2002).
|
|
5
|
+
*
|
|
6
|
+
* The GSD runtime CLI (gsd-tools.cjs) require()s ~150 compiled modules from
|
|
7
|
+
* ./lib/*.cjs. Per ADR-457 ("build-at-publish") those are build artifacts:
|
|
8
|
+
* compiled from src/*.cts by `npm run build:lib` (tsc -p tsconfig.build.json),
|
|
9
|
+
* gitignored, and shipped prebuilt in the npm tarball via the prepack /
|
|
10
|
+
* prepublishOnly lifecycle scripts.
|
|
11
|
+
*
|
|
12
|
+
* The Claude Code plugin-marketplace channel does NOT go through `npm publish`
|
|
13
|
+
* or bin/install.js. Claude Code materializes the git tag tree into its plugin
|
|
14
|
+
* cache and at most runs `npm install --ignore-scripts`, so neither `prepare`
|
|
15
|
+
* nor `build:lib` ever fires. The compiled ./lib/*.cjs therefore never exist on
|
|
16
|
+
* that path and every CLI command dies at module load with
|
|
17
|
+
* `Cannot find module './lib/cli-exit.cjs'`.
|
|
18
|
+
*
|
|
19
|
+
* This module heals that: before gsd-tools.cjs require()s ./lib, if the compiled
|
|
20
|
+
* output is absent it invokes tsc once — lock-guarded so the many parallel
|
|
21
|
+
* gsd-tools shell-outs a workflow performs do not race the build — then lets the
|
|
22
|
+
* requires proceed. On the npm path the artifacts already exist, so the common
|
|
23
|
+
* case is a single fs.existsSync check and a no-op.
|
|
24
|
+
*
|
|
25
|
+
* Deliberately depends on nothing under ./lib (that tree is precisely what may
|
|
26
|
+
* be missing) — only on Node built-ins.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
const fs = require('fs');
|
|
30
|
+
const path = require('path');
|
|
31
|
+
const { spawnSync } = require('child_process');
|
|
32
|
+
|
|
33
|
+
// The first module gsd-tools.cjs require()s, and a gitignored build artifact
|
|
34
|
+
// (so it is absent on a raw git-tag checkout even though ~11 other bin/lib/*.cjs
|
|
35
|
+
// are git-tracked). tsconfig.build.json sets noEmitOnError:true, so tsc is
|
|
36
|
+
// all-or-nothing: if this file exists, the whole tree was emitted.
|
|
37
|
+
const SENTINEL = 'cli-exit.cjs';
|
|
38
|
+
|
|
39
|
+
/** Directory holding the compiled ./lib/*.cjs, relative to this file. */
|
|
40
|
+
function defaultLibDir() {
|
|
41
|
+
return path.join(__dirname, 'lib');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Package root (holds tsconfig.build.json + node_modules). This file lives at
|
|
46
|
+
* <root>/gsd-core/bin/ensure-runtime-build.cjs, so the root is two levels up —
|
|
47
|
+
* true for both the dev repo layout and the marketplace plugin-cache checkout
|
|
48
|
+
* (…/<version>/gsd-core/bin/ensure-runtime-build.cjs).
|
|
49
|
+
*/
|
|
50
|
+
function defaultPackageRoot() {
|
|
51
|
+
return path.resolve(__dirname, '..', '..');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Resolve the tsc entry SCRIPT (not the .bin/tsc shim). We run it as
|
|
56
|
+
* `node <tsc.js>` so behaviour is identical on POSIX and Windows and does not
|
|
57
|
+
* depend on a shell or on the .cmd shim. Returns null when TypeScript is not
|
|
58
|
+
* installed under packageRoot.
|
|
59
|
+
*/
|
|
60
|
+
function resolveTscScript(packageRoot) {
|
|
61
|
+
try {
|
|
62
|
+
return require.resolve('typescript/bin/tsc', { paths: [packageRoot] });
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isBuilt(libDir) {
|
|
69
|
+
return fs.existsSync(path.join(libDir, SENTINEL));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Synchronous sleep with no dependencies, portable across platforms. */
|
|
73
|
+
function sleepSync(ms) {
|
|
74
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, Math.max(0, ms));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Raised when the runtime library is missing and cannot be auto-built. The
|
|
79
|
+
* message is user-facing and actionable; callers print `.message` (not a stack).
|
|
80
|
+
*/
|
|
81
|
+
class RuntimeBuildError extends Error {
|
|
82
|
+
constructor(message) {
|
|
83
|
+
super(message);
|
|
84
|
+
this.name = 'RuntimeBuildError';
|
|
85
|
+
this.code = 'GSD_RUNTIME_BUILD_FAILED';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Ensure the compiled ./lib/*.cjs exist, building them once if absent.
|
|
91
|
+
*
|
|
92
|
+
* Idempotent and safe to call concurrently from many processes. When another
|
|
93
|
+
* process holds the build lock, this one waits for the build to finish rather
|
|
94
|
+
* than launching a competing tsc.
|
|
95
|
+
*
|
|
96
|
+
* @param {object} [opts]
|
|
97
|
+
* @param {string} [opts.libDir] Override the compiled-output directory.
|
|
98
|
+
* @param {string} [opts.packageRoot] Override the tsconfig/node_modules root.
|
|
99
|
+
* @param {string|null} [opts.tscScript] Override tsc resolution (null = "absent").
|
|
100
|
+
* @param {function} [opts.spawn] Override spawnSync (for tests).
|
|
101
|
+
* @param {function} [opts.log] Override the progress logger.
|
|
102
|
+
* @param {number} [opts.waitTimeoutMs] Max wait for a peer build (default 120s).
|
|
103
|
+
* @param {number} [opts.pollMs] Poll interval while waiting (default 100ms).
|
|
104
|
+
* @param {function} [opts.onPoll] Test hook invoked before each wait-poll.
|
|
105
|
+
* @returns {{built: true, healed: boolean, waited?: boolean}}
|
|
106
|
+
* @throws {RuntimeBuildError} when the library is absent and cannot be built.
|
|
107
|
+
*/
|
|
108
|
+
function ensureRuntimeBuild(opts = {}) {
|
|
109
|
+
const libDir = opts.libDir || defaultLibDir();
|
|
110
|
+
const packageRoot = opts.packageRoot || defaultPackageRoot();
|
|
111
|
+
const spawn = opts.spawn || spawnSync;
|
|
112
|
+
const log = opts.log || ((m) => process.stderr.write(m + '\n'));
|
|
113
|
+
const waitTimeoutMs = opts.waitTimeoutMs != null ? opts.waitTimeoutMs : 120000;
|
|
114
|
+
const pollMs = opts.pollMs != null ? opts.pollMs : 100;
|
|
115
|
+
|
|
116
|
+
// Fast path: already built (the npm-registry install and every subsequent run).
|
|
117
|
+
if (isBuilt(libDir)) return { built: true, healed: false };
|
|
118
|
+
|
|
119
|
+
const tsconfig = path.join(packageRoot, 'tsconfig.build.json');
|
|
120
|
+
if (!fs.existsSync(tsconfig)) {
|
|
121
|
+
throw new RuntimeBuildError(
|
|
122
|
+
'GSD runtime library is not built and cannot be auto-built: ' +
|
|
123
|
+
`${tsconfig} not found. Run \`npm run build:lib\` in the gsd-core package.`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const tscScript =
|
|
128
|
+
opts.tscScript !== undefined ? opts.tscScript : resolveTscScript(packageRoot);
|
|
129
|
+
if (!tscScript) {
|
|
130
|
+
throw new RuntimeBuildError(
|
|
131
|
+
`GSD runtime library is not built (missing ${path.join(libDir, SENTINEL)}) ` +
|
|
132
|
+
'and TypeScript is unavailable to build it. Run ' +
|
|
133
|
+
`\`npm install && npm run build:lib\` in the gsd-core package (${packageRoot}).`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// libDir may not exist yet on a totally fresh tree; create it so the lock and
|
|
138
|
+
// tsc output have a home.
|
|
139
|
+
fs.mkdirSync(libDir, { recursive: true });
|
|
140
|
+
const lockDir = path.join(libDir, '.build.lock');
|
|
141
|
+
|
|
142
|
+
let haveLock = acquireLock(lockDir);
|
|
143
|
+
if (!haveLock) {
|
|
144
|
+
// A peer process is building. Wait for the sentinel rather than racing tsc.
|
|
145
|
+
const deadline = Date.now() + waitTimeoutMs;
|
|
146
|
+
while (!isBuilt(libDir)) {
|
|
147
|
+
if (typeof opts.onPoll === 'function') opts.onPoll();
|
|
148
|
+
if (isBuilt(libDir)) break;
|
|
149
|
+
if (Date.now() > deadline) break; // peer wedged/crashed — take over below
|
|
150
|
+
sleepSync(pollMs);
|
|
151
|
+
}
|
|
152
|
+
if (isBuilt(libDir)) return { built: true, healed: true, waited: true };
|
|
153
|
+
// Peer never finished; try to take over the (stale) lock.
|
|
154
|
+
haveLock = acquireLock(lockDir);
|
|
155
|
+
if (!haveLock && !isBuilt(libDir)) {
|
|
156
|
+
throw new RuntimeBuildError(
|
|
157
|
+
`GSD runtime build did not complete within ${waitTimeoutMs}ms and the ` +
|
|
158
|
+
`build lock (${lockDir}) is held by another process. Remove it and run ` +
|
|
159
|
+
'`npm run build:lib` if this persists.',
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (isBuilt(libDir)) return { built: true, healed: true, waited: true };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
log('gsd: runtime library not built — compiling once (tsc -p tsconfig.build.json)…');
|
|
167
|
+
// Heal only runs when the build is genuinely absent/broken, so force a full
|
|
168
|
+
// emit: a stale incremental cache from a partial build would make tsc report
|
|
169
|
+
// success without re-emitting the (still-missing) sentinel.
|
|
170
|
+
forceFullEmit(packageRoot, tsconfig);
|
|
171
|
+
const res = spawn(process.execPath, [tscScript, '-p', tsconfig], {
|
|
172
|
+
cwd: packageRoot,
|
|
173
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
174
|
+
encoding: 'utf8',
|
|
175
|
+
});
|
|
176
|
+
if (!res || res.status !== 0) {
|
|
177
|
+
const detail = ((res && (res.stderr || res.stdout)) || '').toString().trim();
|
|
178
|
+
throw new RuntimeBuildError(
|
|
179
|
+
`GSD runtime build failed (tsc exit ${res ? res.status : 'unknown'}). ` +
|
|
180
|
+
`Run \`npm run build:lib\` in ${packageRoot} to see the error.` +
|
|
181
|
+
(detail ? `\n${detail}` : ''),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
} finally {
|
|
185
|
+
releaseLock(lockDir);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (!isBuilt(libDir)) {
|
|
189
|
+
throw new RuntimeBuildError(
|
|
190
|
+
`GSD runtime build ran but ${path.join(libDir, SENTINEL)} is still missing. ` +
|
|
191
|
+
`Run \`npm run build:lib\` in ${packageRoot}.`,
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
return { built: true, healed: true };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Delete tsc's incremental build cache so the heal re-emits every module. The
|
|
199
|
+
* cache path defaults to tsconfig.build.tsbuildinfo (per tsconfig.build.json)
|
|
200
|
+
* but is read from the config when overridden. Best-effort: a missing or
|
|
201
|
+
* unreadable config just falls back to the default and a missing cache is fine.
|
|
202
|
+
*/
|
|
203
|
+
function forceFullEmit(packageRoot, tsconfigPath) {
|
|
204
|
+
let rel = 'tsconfig.build.tsbuildinfo';
|
|
205
|
+
try {
|
|
206
|
+
const cfg = JSON.parse(fs.readFileSync(tsconfigPath, 'utf8'));
|
|
207
|
+
if (cfg && cfg.compilerOptions && cfg.compilerOptions.tsBuildInfoFile) {
|
|
208
|
+
rel = cfg.compilerOptions.tsBuildInfoFile;
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
/* unreadable/JSONC config — use the default cache path */
|
|
212
|
+
}
|
|
213
|
+
try {
|
|
214
|
+
fs.rmSync(path.resolve(packageRoot, rel), { force: true });
|
|
215
|
+
} catch {
|
|
216
|
+
/* best effort */
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Atomically acquire the build lock. Returns true on success. */
|
|
221
|
+
function acquireLock(lockDir) {
|
|
222
|
+
try {
|
|
223
|
+
fs.mkdirSync(lockDir); // atomic — throws EEXIST if a peer holds it
|
|
224
|
+
return true;
|
|
225
|
+
} catch (e) {
|
|
226
|
+
if (e && e.code === 'EEXIST') return false;
|
|
227
|
+
throw e;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Best-effort lock release. */
|
|
232
|
+
function releaseLock(lockDir) {
|
|
233
|
+
try {
|
|
234
|
+
fs.rmSync(lockDir, { recursive: true, force: true });
|
|
235
|
+
} catch {
|
|
236
|
+
/* best effort — a leftover lock is recovered by the wait-then-takeover path */
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
module.exports = {
|
|
241
|
+
ensureRuntimeBuild,
|
|
242
|
+
resolveTscScript,
|
|
243
|
+
isBuilt,
|
|
244
|
+
RuntimeBuildError,
|
|
245
|
+
SENTINEL,
|
|
246
|
+
};
|
|
@@ -179,14 +179,23 @@
|
|
|
179
179
|
*
|
|
180
180
|
* Loop Extension Point Queries (ADR-857 phase 3c):
|
|
181
181
|
* loop render-hooks <point> Resolve + render active Capability hooks at a loop point
|
|
182
|
+
* [--config-dir <path>] [--runtime <r>] [--active-cap <capId>]
|
|
182
183
|
* Returns JSON envelope { point, activeHooks, rendered }
|
|
183
184
|
* Valid points: discuss:pre/post, plan:pre/post,
|
|
184
185
|
* execute:pre/wave:pre/wave:post/post, verify:pre/post, ship:pre/post
|
|
186
|
+
* --runtime: override the auto-detected runtime (#2003) so the config
|
|
187
|
+
* dir resolves to that runtime's home even when
|
|
188
|
+
* .planning/config.json persists a different runtime.
|
|
185
189
|
*
|
|
186
190
|
* Capability State (ADR-857 phase 4b):
|
|
187
|
-
* capability state [--config-dir <path>] Resolve per-capability install/surface/hook-activation state
|
|
191
|
+
* capability state [--config-dir <path>] [--runtime <r>] Resolve per-capability install/surface/hook-activation state
|
|
188
192
|
* Returns JSON envelope { runtimeConfigDir, capabilities[] }
|
|
189
193
|
* --config-dir: runtime config dir (default: auto-detect current runtime)
|
|
194
|
+
* --runtime: override the auto-detected runtime (#2003); bypasses the
|
|
195
|
+
* GSD_RUNTIME → config.runtime → 'claude' precedence so a
|
|
196
|
+
* repo with a persisted runtime can still resolve another
|
|
197
|
+
* runtime's config dir (e.g. driving Claude Code from a
|
|
198
|
+
* repo that persists runtime:"codex").
|
|
190
199
|
*
|
|
191
200
|
* GSD-2 Migration:
|
|
192
201
|
* from-gsd2 [--path <dir>] [--force] [--dry-run]
|
|
@@ -195,6 +204,24 @@
|
|
|
195
204
|
|
|
196
205
|
const fs = require('fs');
|
|
197
206
|
const path = require('path');
|
|
207
|
+
|
|
208
|
+
// #2002 — self-healing runtime build. The compiled ./lib/*.cjs modules this
|
|
209
|
+
// entrypoint require()s below are gitignored build artifacts (ADR-457), shipped
|
|
210
|
+
// prebuilt in the npm tarball. The Claude Code plugin-marketplace channel never
|
|
211
|
+
// runs `npm run build:lib` or bin/install.js, so on that path they can be
|
|
212
|
+
// absent and every command dies at module load. Compile them once (lock-guarded,
|
|
213
|
+
// idempotent, a no-op when already built) before the ./lib requires run.
|
|
214
|
+
const { ensureRuntimeBuild } = require('./ensure-runtime-build.cjs');
|
|
215
|
+
try {
|
|
216
|
+
ensureRuntimeBuild();
|
|
217
|
+
} catch (bootErr) {
|
|
218
|
+
process.stderr.write((bootErr && bootErr.message ? bootErr.message : String(bootErr)) + '\n');
|
|
219
|
+
// Fatal bootstrap failure before the CLI's ExitError/runMain machinery (which
|
|
220
|
+
// lives in ./lib) is available to load, so a direct exit is the only option.
|
|
221
|
+
// eslint-disable-next-line n/no-process-exit
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
224
|
+
|
|
198
225
|
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
|
199
226
|
const io = require('./lib/io.cjs');
|
|
200
227
|
const { error, ERROR_REASON, setJsonErrorMode, output } = io;
|
|
@@ -259,6 +286,7 @@ const { routePhasesCommand } = require('./lib/phases-command-router.cjs');
|
|
|
259
286
|
const { routeValidateCommand } = require('./lib/validate-command-router.cjs');
|
|
260
287
|
const { routeRoadmapCommand } = require('./lib/roadmap-command-router.cjs');
|
|
261
288
|
const { routeAgentCommand } = require('./lib/agent-command-router.cjs');
|
|
289
|
+
const smartEntryMod = require('./lib/smart-entry.cjs');
|
|
262
290
|
const { routeCheckCommand } = require('./lib/check-command-router.cjs');
|
|
263
291
|
const { routeTaskCommand } = require('./lib/task-command-router.cjs');
|
|
264
292
|
const { parseNamedArgs, parseMultiwordArg } = require('./lib/command-arg-projection.cjs');
|
|
@@ -665,7 +693,7 @@ async function main() {
|
|
|
665
693
|
'from-gsd2, frontmatter, gap-analysis, generate-claude-md, generate-claude-profile, ' +
|
|
666
694
|
'generate-dev-preferences, generate-slug, graphify, history-digest, init, intel, ' +
|
|
667
695
|
'capability, classify-confidence, git, learnings, list-seeds, list-todos, loop, milestone, package-legitimacy, phase, phase-plan-index, phases, profile-questionnaire, ' +
|
|
668
|
-
'profile-sample, progress, project-instruction-file, prompt-budget, requirements, research-plan, research-store, resolve-granularity, resolve-model, roadmap, scaffold, state, ' +
|
|
696
|
+
'profile-sample, progress, project-instruction-file, prompt-budget, requirements, research-plan, research-store, resolve-granularity, resolve-model, roadmap, scaffold, smart-entry, state, ' +
|
|
669
697
|
'task, template, user-story, validate, verify, verify-path-exists, verify-summary, eval, workstream, worktree\n\n' +
|
|
670
698
|
'Global flags:\n' +
|
|
671
699
|
' --raw Emit raw output without post-processing\n' +
|
|
@@ -833,6 +861,11 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
833
861
|
break;
|
|
834
862
|
}
|
|
835
863
|
|
|
864
|
+
case 'smart-entry': {
|
|
865
|
+
smartEntryMod.runSmartEntry(cwd, args, raw);
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
|
|
836
869
|
case 'check': {
|
|
837
870
|
routeCheckCommand({ args, cwd, raw });
|
|
838
871
|
break;
|
|
@@ -1574,9 +1607,28 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1574
1607
|
}
|
|
1575
1608
|
loopActiveCap = value;
|
|
1576
1609
|
}
|
|
1610
|
+
// --runtime <r> (#2003): explicit runtime override so the config-dir
|
|
1611
|
+
// resolution bypasses the persisted-runtime fallback (GSD_RUNTIME →
|
|
1612
|
+
// config.runtime). Mirrors the --config-dir dual-form (--runtime X /
|
|
1613
|
+
// --runtime=X) and the capability-set --runtime precedent.
|
|
1614
|
+
let loopRuntime = undefined;
|
|
1615
|
+
const runtimeEqArg = args.find(arg => arg.startsWith('--runtime='));
|
|
1616
|
+
const runtimeIdx = args.indexOf('--runtime');
|
|
1617
|
+
if (runtimeEqArg) {
|
|
1618
|
+
const value = runtimeEqArg.slice('--runtime='.length).trim();
|
|
1619
|
+
if (!value) error('Missing value for --runtime', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1620
|
+
loopRuntime = value;
|
|
1621
|
+
} else if (runtimeIdx !== -1) {
|
|
1622
|
+
const value = args[runtimeIdx + 1];
|
|
1623
|
+
if (!value || value.startsWith('--')) {
|
|
1624
|
+
error('Missing value for --runtime', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1625
|
+
}
|
|
1626
|
+
loopRuntime = value;
|
|
1627
|
+
}
|
|
1577
1628
|
loopResolver.cmdLoopRenderHooks(cwd, args[2], raw, {
|
|
1578
1629
|
configDir: loopConfigDir ? path.resolve(loopConfigDir) : undefined,
|
|
1579
1630
|
activeCap: loopActiveCap,
|
|
1631
|
+
runtime: loopRuntime,
|
|
1580
1632
|
});
|
|
1581
1633
|
} else {
|
|
1582
1634
|
error(
|
|
@@ -1728,7 +1780,24 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
|
|
|
1728
1780
|
configDir = configDirVal;
|
|
1729
1781
|
}
|
|
1730
1782
|
const resolvedConfigDir = configDir ? path.resolve(configDir) : null;
|
|
1731
|
-
|
|
1783
|
+
// --runtime <r> (#2003): explicit runtime override so the config-dir
|
|
1784
|
+
// resolution bypasses the persisted-runtime fallback. Dual-form like
|
|
1785
|
+
// --config-dir (--runtime X / --runtime=X).
|
|
1786
|
+
let stateRuntime = undefined;
|
|
1787
|
+
const stateRuntimeEqArg = args.find(arg => arg.startsWith('--runtime='));
|
|
1788
|
+
const stateRuntimeIdx = args.indexOf('--runtime');
|
|
1789
|
+
if (stateRuntimeEqArg) {
|
|
1790
|
+
const value = stateRuntimeEqArg.slice('--runtime='.length).trim();
|
|
1791
|
+
if (!value) error('Missing value for --runtime', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1792
|
+
stateRuntime = value;
|
|
1793
|
+
} else if (stateRuntimeIdx !== -1) {
|
|
1794
|
+
const value = args[stateRuntimeIdx + 1];
|
|
1795
|
+
if (!value || value.startsWith('--')) {
|
|
1796
|
+
error('Missing value for --runtime', ERROR_REASON ? ERROR_REASON.USAGE : undefined);
|
|
1797
|
+
}
|
|
1798
|
+
stateRuntime = value;
|
|
1799
|
+
}
|
|
1800
|
+
capabilityState.cmdCapabilityState(cwd, resolvedConfigDir, raw, { runtime: stateRuntime });
|
|
1732
1801
|
} else if (capSubcommand === 'set') {
|
|
1733
1802
|
// capability set <id> [--on|--off|--enable|--disable] [--gate <key>=<bool>]... [--config-dir <dir>] [--runtime <r>] [--scope <s>]
|
|
1734
1803
|
const capId = args[2];
|