@opengsd/gsd-core 1.3.1 → 1.4.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +23 -0
- package/GEMINI.md +53 -0
- package/agents/gsd-advisor-researcher.md +1 -20
- package/agents/gsd-ai-researcher.md +2 -21
- package/agents/gsd-code-fixer.md +1 -1
- package/agents/gsd-code-reviewer.md +1 -1
- package/agents/gsd-domain-researcher.md +2 -21
- package/agents/gsd-eval-auditor.md +1 -1
- package/agents/gsd-eval-planner.md +1 -1
- package/agents/gsd-executor.md +1 -1
- package/agents/gsd-framework-selector.md +1 -1
- package/agents/gsd-nyquist-auditor.md +1 -1
- package/agents/gsd-pattern-mapper.md +1 -1
- package/agents/gsd-phase-researcher.md +92 -166
- package/agents/gsd-planner.md +9 -36
- package/agents/gsd-project-researcher.md +62 -141
- package/agents/gsd-security-auditor.md +1 -1
- package/agents/gsd-ui-auditor.md +1 -1
- package/agents/gsd-ui-checker.md +1 -1
- package/agents/gsd-ui-researcher.md +3 -22
- package/agents/gsd-user-profiler.md +1 -1
- package/agents/gsd-verifier.md +8 -2
- package/bin/install.js +1977 -339
- package/commands/gsd/autonomous.md +2 -0
- package/commands/gsd/execute-phase.md +2 -0
- package/commands/gsd/graphify.md +11 -6
- package/commands/gsd/import.md +6 -2
- package/commands/gsd/plan-phase.md +4 -2
- package/commands/gsd/progress.md +1 -0
- package/commands/gsd/stats.md +1 -0
- package/commands/gsd/update.md +3 -2
- package/gemini-extension.json +6 -0
- package/gsd-core/bin/check-latest-version.cjs +61 -6
- package/gsd-core/bin/gsd-tools.cjs +238 -32
- package/gsd-core/bin/lib/check-command-router.cjs +1 -0
- package/gsd-core/bin/lib/cli-exit.cjs +42 -0
- package/gsd-core/bin/lib/command-routing-hub.cjs +1 -1
- package/gsd-core/bin/lib/commands.cjs +5 -4
- package/gsd-core/bin/lib/config.cjs +28 -4
- package/gsd-core/bin/lib/core.cjs +72 -28
- package/gsd-core/bin/lib/graphify.cjs +2 -2
- package/gsd-core/bin/lib/init-command-router.cjs +2 -2
- package/gsd-core/bin/lib/init.cjs +19 -3
- package/gsd-core/bin/lib/install-profiles.cjs +58 -0
- package/gsd-core/bin/lib/installer-migration-report.cjs +3 -0
- package/gsd-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +1 -1
- package/gsd-core/bin/lib/intel.cjs +3 -20
- package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
- package/gsd-core/bin/lib/phase.cjs +3 -3
- package/gsd-core/bin/lib/research-provider.cjs +137 -0
- package/gsd-core/bin/lib/research-store.cjs +167 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +4 -19
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +67 -9
- package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +56 -0
- package/gsd-core/bin/lib/runtime-homes.cjs +32 -11
- package/gsd-core/bin/lib/security.cjs +73 -0
- package/gsd-core/bin/lib/shell-command-projection.cjs +9 -0
- package/gsd-core/bin/lib/surface.cjs +54 -11
- package/gsd-core/bin/lib/validate.cjs +2 -2
- package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
- package/gsd-core/bin/lib/verification.cjs +193 -0
- package/gsd-core/bin/lib/verify.cjs +2 -2
- package/gsd-core/bin/lib/workstream-inventory.cjs +1 -1
- package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
- package/gsd-core/bin/lib/worktree-safety.cjs +31 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +2 -1
- package/gsd-core/bin/verify-reapply-patches.cjs +8 -11
- package/gsd-core/references/planner-load-graph-context.md +36 -0
- package/gsd-core/references/planning-config.md +3 -1
- package/gsd-core/references/research-documentation-lookup.md +29 -0
- package/gsd-core/references/research-philosophy.md +29 -0
- package/gsd-core/references/research-verification-protocol.md +27 -0
- package/gsd-core/workflows/execute-phase.md +19 -8
- package/gsd-core/workflows/help/modes/full.md +4 -3
- package/gsd-core/workflows/ingest-docs.md +3 -2
- package/gsd-core/workflows/plan-phase.md +14 -10
- package/gsd-core/workflows/plan-review-convergence.md +3 -3
- package/gsd-core/workflows/review.md +24 -7
- package/gsd-core/workflows/ship.md +5 -8
- package/gsd-core/workflows/spec-phase.md +2 -1
- package/gsd-core/workflows/update.md +34 -6
- package/hooks/dist/gsd-config-reload.js +133 -0
- package/hooks/dist/gsd-context-monitor.js +1 -1
- package/hooks/dist/gsd-cursor-post-tool.js +75 -0
- package/hooks/dist/gsd-cursor-session-start.js +52 -0
- package/hooks/dist/gsd-workflow-guard.js +1 -0
- package/hooks/dist/gsd-worktree-path-guard.js +1 -1
- package/hooks/dist/managed-hooks-registry.cjs +3 -0
- package/hooks/gsd-config-reload.js +133 -0
- package/hooks/gsd-context-monitor.js +1 -1
- package/hooks/gsd-cursor-post-tool.js +75 -0
- package/hooks/gsd-cursor-session-start.js +52 -0
- package/hooks/gsd-workflow-guard.js +1 -0
- package/hooks/gsd-worktree-path-guard.js +1 -1
- package/hooks/hooks.json +69 -0
- package/hooks/managed-hooks-registry.cjs +3 -0
- package/package.json +8 -1
- package/scripts/affected-tests-lib.cjs +3 -2
- package/scripts/build-hooks.js +7 -0
- package/scripts/changeset/cli.cjs +226 -28
- package/scripts/changeset/lint.cjs +5 -4
- package/scripts/changeset/new.cjs +4 -4
- package/scripts/check-alias-drift.cjs +77 -71
- package/scripts/check-env.cjs +185 -179
- package/scripts/check-npm-integrity.cjs +115 -109
- package/scripts/ci-guard-runner.cjs +11 -5
- package/scripts/ci-prepare-test-scope.cjs +27 -22
- package/scripts/ci-rebase-check.cjs +46 -45
- package/scripts/ci-test-scope.cjs +126 -22
- package/scripts/diff-touches-shipped-paths.cjs +52 -44
- package/scripts/gen-inventory-manifest.cjs +38 -32
- package/scripts/gen-research-agents.cjs +276 -0
- package/scripts/issue-dedupe.cjs +278 -0
- package/scripts/lib/cli-exit.cjs +56 -0
- package/scripts/lint-command-contract.cjs +28 -22
- package/scripts/lint-descriptions.cjs +32 -28
- package/scripts/lint-docs-required.cjs +4 -4
- package/scripts/lint-legacy-dir-name.cjs +56 -52
- package/scripts/lint-pr-check-project-dir.cjs +3 -1
- package/scripts/lint-shell-command-projection-drift.cjs +27 -22
- package/scripts/lint-skill-deps.cjs +31 -26
- package/scripts/lint-test-file-count.allowlist.json +2 -0
- package/scripts/lint-test-file-count.cjs +5 -4
- package/scripts/mutation-matrix.cjs +6 -3
- package/scripts/prompt-injection-scan.sh +1 -1
- package/scripts/release-notes/discord-release-summary.cjs +373 -0
- package/scripts/release-notes/format-github-release-notes.cjs +8 -3
- package/scripts/release-tarball-smoke.cjs +6 -4
- package/scripts/research-profiles.cjs +149 -0
- package/scripts/run-affected-tests.cjs +2 -1
- package/scripts/run-cross-platform-tests.cjs +11 -7
- package/scripts/run-tests.cjs +8 -7
- package/scripts/strip-prose-atrefs.cjs +1 -1
- package/scripts/sync-manifest-versions.cjs +119 -0
- package/scripts/sync-runtime-launcher.cjs +0 -3
- package/scripts/verify-npm-publish.cjs +14 -26
package/commands/gsd/graphify.md
CHANGED
|
@@ -79,7 +79,8 @@ Modes:
|
|
|
79
79
|
Run:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
node $HOME/.claude/gsd-core/bin/gsd-tools.cjs
|
|
82
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
83
|
+
gsd_run graphify query <term>
|
|
83
84
|
```
|
|
84
85
|
|
|
85
86
|
Parse the JSON output and display results:
|
|
@@ -95,7 +96,8 @@ Parse the JSON output and display results:
|
|
|
95
96
|
Run:
|
|
96
97
|
|
|
97
98
|
```bash
|
|
98
|
-
node $HOME/.claude/gsd-core/bin/gsd-tools.cjs
|
|
99
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
100
|
+
gsd_run graphify status
|
|
99
101
|
```
|
|
100
102
|
|
|
101
103
|
Parse the JSON output and display:
|
|
@@ -119,7 +121,8 @@ Surface both so the agent can choose.
|
|
|
119
121
|
Run:
|
|
120
122
|
|
|
121
123
|
```bash
|
|
122
|
-
node $HOME/.claude/gsd-core/bin/gsd-tools.cjs
|
|
124
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
125
|
+
gsd_run graphify diff
|
|
123
126
|
```
|
|
124
127
|
|
|
125
128
|
Parse the JSON output and display:
|
|
@@ -137,7 +140,8 @@ If no snapshot exists, suggest running `build` twice (first to create, second to
|
|
|
137
140
|
Run the pre-flight check first:
|
|
138
141
|
|
|
139
142
|
```bash
|
|
140
|
-
node "$HOME/.claude/gsd-core/bin/gsd-tools.cjs"
|
|
143
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
144
|
+
gsd_run graphify build
|
|
141
145
|
```
|
|
142
146
|
|
|
143
147
|
Parse the JSON output:
|
|
@@ -156,12 +160,13 @@ GSD > Building knowledge graph...
|
|
|
156
160
|
Run the build, copy artifacts, write the diff snapshot, and report the summary in a single foreground Bash call so the whole pipeline survives to completion. Use a `timeout` of `600000` ms (10 minutes), which covers the `graphify.build_timeout` ceiling (default 300 s) with margin:
|
|
157
161
|
|
|
158
162
|
```bash
|
|
163
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
159
164
|
graphify update . \
|
|
160
165
|
&& cp graphify-out/graph.json .planning/graphs/graph.json \
|
|
161
166
|
&& { [ -f graphify-out/graph.html ] && cp graphify-out/graph.html .planning/graphs/graph.html || true; } \
|
|
162
167
|
&& cp graphify-out/GRAPH_REPORT.md .planning/graphs/GRAPH_REPORT.md \
|
|
163
|
-
&&
|
|
164
|
-
&&
|
|
168
|
+
&& gsd_run graphify build snapshot \
|
|
169
|
+
&& gsd_run graphify status
|
|
165
170
|
```
|
|
166
171
|
|
|
167
172
|
Do NOT pass `run_in_background: true`. Typical builds complete in 15-60 seconds and the entire chain must run foreground.
|
package/commands/gsd/import.md
CHANGED
|
@@ -33,8 +33,12 @@ $ARGUMENTS
|
|
|
33
33
|
|
|
34
34
|
<process>
|
|
35
35
|
If `--from-gsd2` is in $ARGUMENTS:
|
|
36
|
-
Run
|
|
37
|
-
|
|
36
|
+
Run the reverse-migration (append `--path <dir>` if provided):
|
|
37
|
+
```bash
|
|
38
|
+
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
|
39
|
+
gsd_run from-gsd2
|
|
40
|
+
```
|
|
41
|
+
Present the migration result to the user.
|
|
38
42
|
Stop here (do not run the standard import workflow).
|
|
39
43
|
|
|
40
44
|
Otherwise, execute the import workflow end-to-end.
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
name: gsd:plan-phase
|
|
3
3
|
description: Create detailed phase plan (PLAN.md) with verification loop
|
|
4
4
|
argument-hint: "[phase] [--auto] [--research] [--skip-research] [--research-phase <N>] [--view] [--gaps] [--skip-verify] [--prd <file>] [--ingest <path-or-glob>] [--ingest-format <auto|nygard|madr|narrative>] [--reviews] [--text] [--tdd] [--mvp]"
|
|
5
|
+
context: fork
|
|
6
|
+
effort: xhigh
|
|
5
7
|
allowed-tools:
|
|
6
8
|
- Read
|
|
7
9
|
- Write
|
|
@@ -22,8 +24,8 @@ Create executable phase prompts (PLAN.md files) for a roadmap phase with integra
|
|
|
22
24
|
**Research-only mode (`--research-phase <N>`):** Spawn `gsd-phase-researcher` for phase `N`, write `RESEARCH.md`, then exit before the planner runs. Useful for cross-phase research, doc review before committing to a planning approach, and correction-without-replanning loops where iterating on research alone is dramatically cheaper than re-spawning the planner. Replaces the deleted research-phase command (#3042).
|
|
23
25
|
|
|
24
26
|
**Research-only modifiers:**
|
|
25
|
-
- **No flag** — when `RESEARCH.md` already exists,
|
|
26
|
-
- **`--research`** — force-refresh: re-spawn the researcher unconditionally, no prompt.
|
|
27
|
+
- **No flag** — when `RESEARCH.md` already exists, auto-uses it: emits a one-line notice and exits cleanly, no prompt.
|
|
28
|
+
- **`--research`** — force-refresh: re-spawn the researcher unconditionally, no prompt. Bypasses the existing-RESEARCH.md auto-use path.
|
|
27
29
|
- **`--view`** — view-only: print existing `RESEARCH.md` to stdout. Does not spawn the researcher. Cheapest mode for the correction-without-replanning loop. If no `RESEARCH.md` exists yet, errors with a hint to drop `--view`.
|
|
28
30
|
|
|
29
31
|
**Orchestrator role:** Parse arguments, validate phase, research domain (unless skipped), spawn gsd-planner, verify with gsd-plan-checker, iterate until pass or max iterations, present results.
|
package/commands/gsd/progress.md
CHANGED
package/commands/gsd/stats.md
CHANGED
package/commands/gsd/update.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd:update
|
|
3
3
|
description: Update GSD to latest version with changelog display
|
|
4
|
-
argument-hint: "[--sync | --reapply]"
|
|
4
|
+
argument-hint: "[--sync | --reapply | --next | --rc]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Write
|
|
@@ -31,6 +31,7 @@ Routes to the update workflow which handles:
|
|
|
31
31
|
<flags>
|
|
32
32
|
- **--sync**: Sync managed GSD skills across runtime roots so multi-runtime users stay aligned after an update. Runs the sync-skills workflow (--from, --to, --dry-run, --apply flags supported).
|
|
33
33
|
- **--reapply**: Reapply local modifications after a GSD update. Uses three-way comparison (pristine baseline, user-modified backup, newly installed version) to merge user customizations back. Runs the reapply-patches workflow.
|
|
34
|
+
- **--next** (alias **--rc**): Target the `@next` RC dist-tag instead of `@latest` so you can install or refresh a release candidate (e.g. `1.4.0-rc.1`) through the normal update flow — scope/runtime detection, changelog preview, custom-file backup, and cache clearing all still apply. Omitting it keeps targeting `@latest` (no change). See ADR #660 for the RC channel.
|
|
34
35
|
- **(no flag)**: Standard update — check for new version, show changelog, install.
|
|
35
36
|
</flags>
|
|
36
37
|
|
|
@@ -38,7 +39,7 @@ Routes to the update workflow which handles:
|
|
|
38
39
|
Parse the first token of $ARGUMENTS:
|
|
39
40
|
- If it is `--sync`: strip the flag, execute the sync-skills workflow (passing remaining args for --from/--to/--dry-run/--apply).
|
|
40
41
|
- If it is `--reapply`: strip the flag, execute the reapply-patches workflow.
|
|
41
|
-
- Otherwise: execute the update workflow end-to-end.
|
|
42
|
+
- Otherwise (including `--next` / `--rc`): execute the update workflow end-to-end, passing `$ARGUMENTS` through so the workflow's parse_update_channel step can select the release channel.
|
|
42
43
|
|
|
43
44
|
</process>
|
|
44
45
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gsd-core",
|
|
3
|
+
"version": "1.4.0-rc.2",
|
|
4
|
+
"description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.",
|
|
5
|
+
"contextFileName": "GEMINI.md"
|
|
6
|
+
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
const { execNpm } = require('./lib/shell-command-projection.cjs');
|
|
24
|
+
const { runMain } = require('./lib/cli-exit.cjs');
|
|
24
25
|
|
|
25
26
|
// Sourced from the single Package Identity seam (#498), not re-typed. The seam
|
|
26
27
|
// bakes the value from package.json at build time, so it is a code constant —
|
|
@@ -36,18 +37,64 @@ const CHECK_REASON = Object.freeze({
|
|
|
36
37
|
|
|
37
38
|
const SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
|
|
38
39
|
|
|
40
|
+
// #815: the one RC channel ADR #660 sanctions, plus the stable default.
|
|
41
|
+
// An allowlist (not a free string) keeps a typo from silently resolving
|
|
42
|
+
// `npm view` to an empty or foreign dist-tag.
|
|
43
|
+
const ALLOWED_TAGS = Object.freeze(['latest', 'next']);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Build the `npm view` args for a dist-tag. `latest` keeps the bare package
|
|
47
|
+
* spec so the default invocation is byte-for-byte identical to before tag
|
|
48
|
+
* support existed (#815); any other allowlisted tag appends `@<tag>` so
|
|
49
|
+
* `npm view @opengsd/gsd-core@next version` resolves the RC channel (#660).
|
|
50
|
+
*/
|
|
51
|
+
function buildViewArgs(tag = 'latest') {
|
|
52
|
+
if (!ALLOWED_TAGS.includes(tag)) {
|
|
53
|
+
throw new RangeError(`invalid dist-tag '${tag}'; allowed: ${ALLOWED_TAGS.join(', ')}`);
|
|
54
|
+
}
|
|
55
|
+
const spec = tag === 'latest' ? PACKAGE_NAME : `${PACKAGE_NAME}@${tag}`;
|
|
56
|
+
return ['view', spec, 'version'];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Resolve the requested dist-tag from argv. Defaults to `latest` (no flag =>
|
|
61
|
+
* no behavior change). Restricted to ALLOWED_TAGS so a typo can't silently
|
|
62
|
+
* resolve to an empty/foreign tag (#815 alternative 1).
|
|
63
|
+
*/
|
|
64
|
+
function resolveTag(argv) {
|
|
65
|
+
let val;
|
|
66
|
+
const eq = argv.find((a) => typeof a === 'string' && a.startsWith('--tag='));
|
|
67
|
+
if (eq !== undefined) {
|
|
68
|
+
val = eq.slice('--tag='.length);
|
|
69
|
+
} else {
|
|
70
|
+
const i = argv.indexOf('--tag');
|
|
71
|
+
if (i === -1) return 'latest';
|
|
72
|
+
val = argv[i + 1];
|
|
73
|
+
}
|
|
74
|
+
if (!val || !ALLOWED_TAGS.includes(val)) {
|
|
75
|
+
throw new RangeError(
|
|
76
|
+
`invalid --tag '${val || ''}'; allowed: ${ALLOWED_TAGS.join(', ')}`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return val;
|
|
80
|
+
}
|
|
81
|
+
|
|
39
82
|
/**
|
|
40
83
|
* Pure-ish: takes an injected spawn function so tests don't actually run npm.
|
|
41
84
|
* In production, defaults to execNpm() from the shell-projection seam.
|
|
42
85
|
*/
|
|
43
86
|
function checkLatestVersion(opts = {}) {
|
|
87
|
+
const tag = opts.tag || 'latest';
|
|
88
|
+
if (!ALLOWED_TAGS.includes(tag)) {
|
|
89
|
+
throw new RangeError(`invalid dist-tag '${tag}'; allowed: ${ALLOWED_TAGS.join(', ')}`);
|
|
90
|
+
}
|
|
44
91
|
// Default path routes through the shell-projection seam (execNpm owns the
|
|
45
92
|
// Windows shell-flag policy and timeout default). The injection point
|
|
46
93
|
// remains spawnSync-shaped for test compatibility — the adapter below
|
|
47
94
|
// translates { exitCode } → { status } so the consumer logic is unchanged.
|
|
48
95
|
// Bounded at 15s so a hung registry doesn't block /gsd-update (#2993 CR).
|
|
49
96
|
const defaultSpawn = () => {
|
|
50
|
-
const r = execNpm(
|
|
97
|
+
const r = execNpm(buildViewArgs(tag), { timeout: 15_000 });
|
|
51
98
|
return {
|
|
52
99
|
status: r.exitCode,
|
|
53
100
|
stdout: r.stdout,
|
|
@@ -89,8 +136,16 @@ function checkLatestVersion(opts = {}) {
|
|
|
89
136
|
}
|
|
90
137
|
|
|
91
138
|
function main() {
|
|
92
|
-
const
|
|
93
|
-
const
|
|
139
|
+
const argv = process.argv.slice(2);
|
|
140
|
+
const json = argv.includes('--json');
|
|
141
|
+
let tag;
|
|
142
|
+
try {
|
|
143
|
+
tag = resolveTag(argv);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
process.stderr.write(`check-latest-version: ${e.message}\n`);
|
|
146
|
+
return 2;
|
|
147
|
+
}
|
|
148
|
+
const r = checkLatestVersion({ tag });
|
|
94
149
|
if (json) {
|
|
95
150
|
process.stdout.write(JSON.stringify(r) + '\n');
|
|
96
151
|
} else if (r.ok) {
|
|
@@ -98,9 +153,9 @@ function main() {
|
|
|
98
153
|
} else {
|
|
99
154
|
process.stderr.write(`check-latest-version: ${r.reason}: ${r.detail}\n`);
|
|
100
155
|
}
|
|
101
|
-
|
|
156
|
+
return r.ok ? 0 : 1;
|
|
102
157
|
}
|
|
103
158
|
|
|
104
|
-
if (require.main === module) main
|
|
159
|
+
if (require.main === module) runMain(main);
|
|
105
160
|
|
|
106
|
-
module.exports = { checkLatestVersion, CHECK_REASON, PACKAGE_NAME };
|
|
161
|
+
module.exports = { checkLatestVersion, CHECK_REASON, PACKAGE_NAME, ALLOWED_TAGS, buildViewArgs, resolveTag };
|