@opengsd/gsd-core 1.3.0 → 1.4.0-rc.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.
Files changed (98) hide show
  1. package/agents/gsd-advisor-researcher.md +1 -20
  2. package/agents/gsd-ai-researcher.md +1 -20
  3. package/agents/gsd-domain-researcher.md +1 -20
  4. package/agents/gsd-executor.md +1 -1
  5. package/agents/gsd-phase-researcher.md +92 -166
  6. package/agents/gsd-planner.md +9 -36
  7. package/agents/gsd-project-researcher.md +62 -141
  8. package/agents/gsd-ui-researcher.md +2 -21
  9. package/agents/gsd-verifier.md +8 -2
  10. package/bin/install.js +85 -4
  11. package/commands/gsd/graphify.md +11 -6
  12. package/commands/gsd/import.md +6 -2
  13. package/commands/gsd/plan-phase.md +2 -2
  14. package/gsd-core/bin/check-latest-version.cjs +3 -2
  15. package/gsd-core/bin/gsd-tools.cjs +238 -32
  16. package/gsd-core/bin/lib/check-command-router.cjs +1 -0
  17. package/gsd-core/bin/lib/cli-exit.cjs +42 -0
  18. package/gsd-core/bin/lib/command-routing-hub.cjs +1 -1
  19. package/gsd-core/bin/lib/commands.cjs +5 -4
  20. package/gsd-core/bin/lib/config.cjs +28 -4
  21. package/gsd-core/bin/lib/core.cjs +72 -28
  22. package/gsd-core/bin/lib/graphify.cjs +2 -2
  23. package/gsd-core/bin/lib/init-command-router.cjs +2 -2
  24. package/gsd-core/bin/lib/init.cjs +19 -3
  25. package/gsd-core/bin/lib/installer-migrations.cjs +61 -22
  26. package/gsd-core/bin/lib/intel.cjs +3 -20
  27. package/gsd-core/bin/lib/package-legitimacy.cjs +368 -0
  28. package/gsd-core/bin/lib/phase.cjs +3 -3
  29. package/gsd-core/bin/lib/research-provider.cjs +137 -0
  30. package/gsd-core/bin/lib/research-store.cjs +167 -0
  31. package/gsd-core/bin/lib/roadmap-upgrade.cjs +4 -19
  32. package/gsd-core/bin/lib/security.cjs +73 -0
  33. package/gsd-core/bin/lib/shell-command-projection.cjs +3 -0
  34. package/gsd-core/bin/lib/validate.cjs +2 -2
  35. package/gsd-core/bin/lib/verification-command-router.cjs +31 -0
  36. package/gsd-core/bin/lib/verification.cjs +193 -0
  37. package/gsd-core/bin/lib/verify.cjs +2 -2
  38. package/gsd-core/bin/lib/workstream-inventory.cjs +1 -1
  39. package/gsd-core/bin/lib/worktree-base-ref.cjs +325 -0
  40. package/gsd-core/bin/lib/worktree-safety.cjs +31 -0
  41. package/gsd-core/bin/shared/config-schema.manifest.json +2 -1
  42. package/gsd-core/bin/verify-reapply-patches.cjs +8 -11
  43. package/gsd-core/references/planner-load-graph-context.md +36 -0
  44. package/gsd-core/references/planning-config.md +3 -1
  45. package/gsd-core/references/research-documentation-lookup.md +29 -0
  46. package/gsd-core/references/research-philosophy.md +29 -0
  47. package/gsd-core/references/research-verification-protocol.md +27 -0
  48. package/gsd-core/workflows/execute-phase.md +19 -8
  49. package/gsd-core/workflows/help/modes/full.md +2 -2
  50. package/gsd-core/workflows/ingest-docs.md +3 -2
  51. package/gsd-core/workflows/plan-phase.md +14 -10
  52. package/gsd-core/workflows/plan-review-convergence.md +3 -3
  53. package/gsd-core/workflows/review.md +22 -5
  54. package/gsd-core/workflows/ship.md +5 -8
  55. package/gsd-core/workflows/spec-phase.md +2 -1
  56. package/gsd-core/workflows/update.md +2 -1
  57. package/hooks/dist/gsd-context-monitor.js +1 -1
  58. package/hooks/dist/gsd-workflow-guard.js +1 -0
  59. package/hooks/dist/gsd-worktree-path-guard.js +1 -1
  60. package/hooks/gsd-context-monitor.js +1 -1
  61. package/hooks/gsd-workflow-guard.js +1 -0
  62. package/hooks/gsd-worktree-path-guard.js +1 -1
  63. package/package.json +4 -1
  64. package/scripts/affected-tests-lib.cjs +3 -2
  65. package/scripts/changeset/cli.cjs +183 -28
  66. package/scripts/changeset/lint.cjs +5 -4
  67. package/scripts/changeset/new.cjs +4 -4
  68. package/scripts/check-alias-drift.cjs +77 -71
  69. package/scripts/check-env.cjs +185 -179
  70. package/scripts/check-npm-integrity.cjs +115 -109
  71. package/scripts/ci-guard-runner.cjs +11 -5
  72. package/scripts/ci-prepare-test-scope.cjs +27 -22
  73. package/scripts/ci-rebase-check.cjs +46 -45
  74. package/scripts/ci-test-scope.cjs +6 -4
  75. package/scripts/diff-touches-shipped-paths.cjs +52 -44
  76. package/scripts/gen-inventory-manifest.cjs +38 -32
  77. package/scripts/gen-research-agents.cjs +276 -0
  78. package/scripts/lib/cli-exit.cjs +56 -0
  79. package/scripts/lint-command-contract.cjs +28 -22
  80. package/scripts/lint-descriptions.cjs +32 -28
  81. package/scripts/lint-docs-required.cjs +4 -4
  82. package/scripts/lint-legacy-dir-name.cjs +56 -52
  83. package/scripts/lint-pr-check-project-dir.cjs +3 -1
  84. package/scripts/lint-shell-command-projection-drift.cjs +27 -22
  85. package/scripts/lint-skill-deps.cjs +31 -26
  86. package/scripts/lint-test-file-count.allowlist.json +1 -0
  87. package/scripts/lint-test-file-count.cjs +5 -4
  88. package/scripts/mutation-matrix.cjs +6 -3
  89. package/scripts/prompt-injection-scan.sh +1 -1
  90. package/scripts/release-notes/format-github-release-notes.cjs +8 -3
  91. package/scripts/release-tarball-smoke.cjs +6 -4
  92. package/scripts/research-profiles.cjs +149 -0
  93. package/scripts/run-affected-tests.cjs +2 -1
  94. package/scripts/run-cross-platform-tests.cjs +11 -7
  95. package/scripts/run-tests.cjs +8 -7
  96. package/scripts/strip-prose-atrefs.cjs +1 -1
  97. package/scripts/sync-runtime-launcher.cjs +0 -3
  98. package/scripts/verify-npm-publish.cjs +14 -26
@@ -23,6 +23,7 @@
23
23
  const { readdirSync, existsSync } = require('fs');
24
24
  const { join } = require('path');
25
25
  const { execFileSync } = require('child_process');
26
+ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
26
27
 
27
28
  const SUITES = ['all', 'unit', 'integration', 'install', 'security', 'slow'];
28
29
 
@@ -189,13 +190,13 @@ function main() {
189
190
  if (parsed.error) {
190
191
  console.error(`run-tests: ${parsed.error}`);
191
192
  console.error(`Valid suites: ${SUITES.join(', ')}`);
192
- process.exit(2);
193
+ throw new ExitError(2);
193
194
  }
194
195
  const suite = parsed.suite;
195
196
  if (suite !== null && !SUITES.includes(suite)) {
196
197
  console.error(`run-tests: unknown suite "${suite}"`);
197
198
  console.error(`Valid suites: ${SUITES.join(', ')}`);
198
- process.exit(2);
199
+ throw new ExitError(2);
199
200
  }
200
201
 
201
202
  const testDir = process.env.GSD_TEST_DIR
@@ -208,7 +209,7 @@ function main() {
208
209
 
209
210
  if (allFiles.length === 0) {
210
211
  console.error(`No test files found in ${testDir}`);
211
- process.exit(1);
212
+ throw new ExitError(1);
212
213
  }
213
214
 
214
215
  let selectedNames;
@@ -216,7 +217,7 @@ function main() {
216
217
  const explicit = selectExplicitFiles(allFiles, parsed.files, parsed.filesFrom);
217
218
  if (explicit.error) {
218
219
  console.error(`run-tests: ${explicit.error}`);
219
- process.exit(2);
220
+ throw new ExitError(2);
220
221
  }
221
222
  selectedNames = explicit.files;
222
223
  } else {
@@ -229,7 +230,7 @@ function main() {
229
230
  // adversarial tests land) don't gate CI. CI consumers wanting strictness
230
231
  // can grep stderr for "no tests in suite".
231
232
  console.error(`run-tests: no tests in suite "${suite || 'all'}"`);
232
- process.exit(0);
233
+ return 0;
233
234
  }
234
235
 
235
236
  // Build the gitignored bin/lib artifact if absent, before any test requires it.
@@ -304,11 +305,11 @@ function main() {
304
305
  if (firstFailureExit === 0) firstFailureExit = code;
305
306
  }
306
307
  }
307
- if (firstFailureExit !== 0) process.exit(firstFailureExit);
308
+ if (firstFailureExit !== 0) return firstFailureExit;
308
309
  }
309
310
 
310
311
  if (require.main === module) {
311
- main();
312
+ runMain(main);
312
313
  }
313
314
 
314
315
  module.exports = { suiteOf };
@@ -30,7 +30,7 @@ const DRY_RUN = process.argv.includes('--dry-run');
30
30
  const ROOT = path.join(__dirname, '..');
31
31
  const COMMANDS_DIR = path.join(ROOT, 'commands', 'gsd');
32
32
 
33
- const AT_PATH_PATTERN = /@(?:~|\$HOME)\/.+?gsd-core\/[^\s`\)]+/;
33
+ const AT_PATH_PATTERN = /@(?:~|\$HOME)\/.+?gsd-core\/[^\s`)]+/;
34
34
  const mkAtRe = () => new RegExp(AT_PATH_PATTERN.source, 'g');
35
35
 
36
36
  function transformLine(line) {
@@ -96,9 +96,6 @@ function removeResolverLines(lines, preamble) {
96
96
  const result = [];
97
97
  let i = 0;
98
98
 
99
- // Build a set of preamble lines for fast lookup (to strip previously-inserted preambles)
100
- const preambleLineSet = new Set(preamble);
101
-
102
99
  while (i < lines.length) {
103
100
  const line = lines[i];
104
101
  const trimmed = line.trim();
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  const cp = require('node:child_process');
11
+ const { ExitError, runMain } = require('./lib/cli-exit.cjs');
11
12
 
12
13
  // ---- Constants ---------------------------------------------------------------
13
14
 
@@ -137,67 +138,57 @@ function parseArgs(argv) {
137
138
  ' --json emit structured JSON output\n' +
138
139
  ' --help, -h show this help\n'
139
140
  );
140
- process.exit(0);
141
+ throw new ExitError(0);
141
142
  } else if (arg === '--package') {
142
143
  const val = args.shift();
143
144
  if (!val || val.startsWith('-')) {
144
- process.stderr.write('error: --package requires a value\n');
145
- process.exit(2);
145
+ throw new ExitError(2, 'error: --package requires a value');
146
146
  }
147
147
  opts.pkg = val;
148
148
  } else if (arg === '--version') {
149
149
  const val = args.shift();
150
150
  if (!val || val.startsWith('-')) {
151
- process.stderr.write('error: --version requires a value\n');
152
- process.exit(2);
151
+ throw new ExitError(2, 'error: --version requires a value');
153
152
  }
154
153
  opts.version = val;
155
154
  } else if (arg === '--dist-tag') {
156
155
  const val = args.shift();
157
156
  if (!val || val.startsWith('-')) {
158
- process.stderr.write('error: --dist-tag requires a value\n');
159
- process.exit(2);
157
+ throw new ExitError(2, 'error: --dist-tag requires a value');
160
158
  }
161
159
  opts.distTag = val;
162
160
  } else if (arg === '--max-attempts') {
163
161
  const val = args.shift();
164
162
  if (!val || val.startsWith('-')) {
165
- process.stderr.write('error: --max-attempts requires a value\n');
166
- process.exit(2);
163
+ throw new ExitError(2, 'error: --max-attempts requires a value');
167
164
  }
168
165
  const n = parseInt(val, 10);
169
166
  if (isNaN(n) || n < 1) {
170
- process.stderr.write('error: --max-attempts must be a positive integer\n');
171
- process.exit(2);
167
+ throw new ExitError(2, 'error: --max-attempts must be a positive integer');
172
168
  }
173
169
  opts.maxAttempts = n;
174
170
  } else if (arg === '--interval-ms') {
175
171
  const val = args.shift();
176
172
  if (!val || val.startsWith('-')) {
177
- process.stderr.write('error: --interval-ms requires a value\n');
178
- process.exit(2);
173
+ throw new ExitError(2, 'error: --interval-ms requires a value');
179
174
  }
180
175
  const n = parseInt(val, 10);
181
176
  if (isNaN(n) || n < 0) {
182
- process.stderr.write('error: --interval-ms must be a non-negative integer\n');
183
- process.exit(2);
177
+ throw new ExitError(2, 'error: --interval-ms must be a non-negative integer');
184
178
  }
185
179
  opts.intervalMs = n;
186
180
  } else if (arg === '--json') {
187
181
  opts.json = true;
188
182
  } else {
189
- process.stderr.write(`unknown argument: ${arg}\n`);
190
- process.exit(2);
183
+ throw new ExitError(2, `unknown argument: ${arg}`);
191
184
  }
192
185
  }
193
186
 
194
187
  if (!opts.pkg) {
195
- process.stderr.write('error: --package is required\n');
196
- process.exit(2);
188
+ throw new ExitError(2, 'error: --package is required');
197
189
  }
198
190
  if (!opts.version) {
199
- process.stderr.write('error: --version is required\n');
200
- process.exit(2);
191
+ throw new ExitError(2, 'error: --version is required');
201
192
  }
202
193
 
203
194
  return opts;
@@ -237,16 +228,13 @@ async function main() {
237
228
  }
238
229
  }
239
230
 
240
- process.exit(result.ok ? 0 : 1);
231
+ return result.ok ? 0 : 1;
241
232
  }
242
233
 
243
234
  // ---- Guard -------------------------------------------------------------------
244
235
 
245
236
  if (require.main === module) {
246
- main().catch((err) => {
247
- process.stderr.write(String((err && err.stack) || err) + '\n');
248
- process.exit(1);
249
- });
237
+ runMain(main);
250
238
  }
251
239
 
252
240
  module.exports = { verifyPublish, parseArgs, REASON, defaultFetchVersion, defaultFetchDistTag };