@opengsd/gsd-core 1.5.0 → 1.6.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 (63) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/gsd-plan-checker.md +34 -0
  3. package/agents/gsd-planner.md +2 -0
  4. package/bin/install.js +108 -34
  5. package/gemini-extension.json +1 -1
  6. package/gsd-core/bin/gsd-tools.cjs +677 -2
  7. package/gsd-core/bin/lib/adr-parser.cjs +24 -17
  8. package/gsd-core/bin/lib/audit.cjs +2 -2
  9. package/gsd-core/bin/lib/capability-consent.cjs +763 -0
  10. package/gsd-core/bin/lib/capability-ledger.cjs +831 -0
  11. package/gsd-core/bin/lib/capability-lifecycle.cjs +1551 -0
  12. package/gsd-core/bin/lib/capability-loader.cjs +764 -0
  13. package/gsd-core/bin/lib/capability-lock.cjs +553 -0
  14. package/gsd-core/bin/lib/capability-registry.cjs +198 -4
  15. package/gsd-core/bin/lib/capability-source.cjs +1242 -0
  16. package/gsd-core/bin/lib/capability-state.cjs +9 -6
  17. package/gsd-core/bin/lib/capability-trust.cjs +550 -0
  18. package/gsd-core/bin/lib/capability-validator.cjs +2066 -0
  19. package/gsd-core/bin/lib/capability-writer.cjs +14 -5
  20. package/gsd-core/bin/lib/check-command-router.cjs +69 -18
  21. package/gsd-core/bin/lib/command-aliases.cjs +8 -0
  22. package/gsd-core/bin/lib/config-loader.cjs +92 -84
  23. package/gsd-core/bin/lib/config-schema.cjs +26 -7
  24. package/gsd-core/bin/lib/config.cjs +1 -1
  25. package/gsd-core/bin/lib/decisions.cjs +149 -60
  26. package/gsd-core/bin/lib/gap-checker.cjs +126 -11
  27. package/gsd-core/bin/lib/init.cjs +91 -22
  28. package/gsd-core/bin/lib/legacy-cleanup.cjs +96 -0
  29. package/gsd-core/bin/lib/loop-resolver.cjs +26 -2
  30. package/gsd-core/bin/lib/markdown-sectionizer.cjs +471 -0
  31. package/gsd-core/bin/lib/milestone.cjs +41 -2
  32. package/gsd-core/bin/lib/phase-command-router.cjs +5 -0
  33. package/gsd-core/bin/lib/phase-lifecycle.cjs +14 -5
  34. package/gsd-core/bin/lib/phase.cjs +29 -0
  35. package/gsd-core/bin/lib/project-root.cjs +89 -2
  36. package/gsd-core/bin/lib/resolution.cjs +26 -0
  37. package/gsd-core/bin/lib/roadmap-parser.cjs +44 -98
  38. package/gsd-core/bin/lib/runtime-homes.cjs +53 -1
  39. package/gsd-core/bin/lib/semver-compare.cjs +127 -0
  40. package/gsd-core/bin/lib/state-document.cjs +4 -2
  41. package/gsd-core/bin/lib/state.cjs +317 -161
  42. package/gsd-core/bin/lib/uat-predicate.cjs +7 -47
  43. package/gsd-core/bin/lib/uat.cjs +39 -26
  44. package/gsd-core/bin/lib/verify.cjs +29 -13
  45. package/gsd-core/bin/shared/config-defaults.manifest.json +4 -0
  46. package/gsd-core/bin/shared/config-schema.manifest.json +4 -1
  47. package/gsd-core/references/execute-phase-between-wave-reset.md +43 -0
  48. package/gsd-core/references/execute-phase-wave-guard.md +33 -0
  49. package/gsd-core/references/planner-antipatterns.md +48 -0
  50. package/gsd-core/references/planning-config.md +3 -0
  51. package/gsd-core/references/scout-codebase.md +2 -2
  52. package/gsd-core/workflows/discuss-phase/templates/context.md +1 -1
  53. package/gsd-core/workflows/discuss-phase.md +1 -2
  54. package/gsd-core/workflows/execute-phase.md +4 -6
  55. package/package.json +3 -3
  56. package/scripts/gen-capability-matrix.cjs +284 -0
  57. package/scripts/gen-capability-registry.cjs +96 -1853
  58. package/scripts/lint-regression-test-names.allowlist.json +1 -0
  59. package/scripts/lint-resolution-provenance.allowlist.json +1 -0
  60. package/scripts/lint-resolution-provenance.cjs +192 -0
  61. package/scripts/lint-test-file-count.allowlist.json +9 -0
  62. package/scripts/run-tests.cjs +14 -0
  63. package/scripts/sync-manifest-versions.cjs +77 -5
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  const node_fs_1 = __importDefault(require("node:fs"));
14
14
  const node_path_1 = __importDefault(require("node:path"));
15
15
  const security_cjs_1 = require("./security.cjs");
16
+ const markdown_sectionizer_cjs_1 = require("./markdown-sectionizer.cjs");
16
17
  const STATUS_REJECT_SET = new Set(['superseded', 'rejected', 'deprecated']);
17
18
  const CANONICAL_HEADERS = {
18
19
  status: ['status', 'state', 'lifecycle', 'stage'],
@@ -208,24 +209,30 @@ function splitEntries(blockText) {
208
209
  .map((line) => line.replace(/^[-*+]\s+/, '').trim())
209
210
  .filter(Boolean);
210
211
  }
212
+ /**
213
+ * Thin adapter: wraps the seam's `collectSections` to produce the same
214
+ * `{ heading: string | null, body: string[] }` shape the rest of adr-parser
215
+ * consumes. ADR-1372 T2 migration.
216
+ */
211
217
  function parseSections(markdown) {
212
- const lines = (typeof markdown === 'string' ? markdown : '').split(/\r?\n/);
213
- const sections = [];
214
- let current = { heading: null, body: [] };
215
- for (const line of lines) {
216
- const m = line.match(/^#{1,6}\s+(.*)$/);
217
- if (m) {
218
- if (current.heading || current.body.length)
219
- sections.push(current);
220
- current = { heading: m[1].trim(), body: [] };
221
- }
222
- else {
223
- current.body.push(line);
224
- }
225
- }
226
- if (current.heading || current.body.length)
227
- sections.push(current);
228
- return sections;
218
+ const content = typeof markdown === 'string' ? markdown : '';
219
+ // collectSections(content, () => true) collects every heading as a stop
220
+ // boundary — mirrors the old line-by-line heading walk exactly.
221
+ const sections = (0, markdown_sectionizer_cjs_1.collectSections)(content, () => true);
222
+ // Map seam Section → MarkdownSection. The seam's HeadingToken.text is the
223
+ // heading text after trimming (same as the old m[1].trim() capture).
224
+ // The body is a trimEnd()-ed joined string; split it back to lines to match
225
+ // the old string[] shape consumed by parseStatusFromSections / parseAdrMarkdown.
226
+ //
227
+ // Note: the old parseSections emitted a leading { heading: null, body: [...] }
228
+ // entry for preamble text before the first heading. Both consumers skip it
229
+ // immediately (parseAdrMarkdown: `if (!heading) continue`; parseStatusFromSections:
230
+ // `classifyHeader(normalizeAdrHeader(null))` → null ≠ 'status' → continue), so
231
+ // the preamble entry was dead code and is not reconstructed here.
232
+ return sections.map((sec) => ({
233
+ heading: sec.heading.text,
234
+ body: sec.body === '' ? [] : sec.body.split('\n'),
235
+ }));
229
236
  }
230
237
  function parseStatusFromSections(sections) {
231
238
  for (const section of sections) {
@@ -68,7 +68,7 @@ function scanDebugSessions(planDir) {
68
68
  continue;
69
69
  // Extract hypothesis from "Current Focus" block if parseable
70
70
  let hypothesis = '';
71
- const focusMatch = content.match(/##\s*Current Focus[^\n]*\n([\s\S]*?)(?=\n##\s|$)/i);
71
+ const focusMatch = content.match(/##\s*Current Focus[^\n]*\n([\s\S]*?)(?=\n##\s|$)/i); // allow-adhoc-markdown: pre-seam read-only section extract in audit.cts; pending migration #1372
72
72
  if (focusMatch) {
73
73
  const focusText = focusMatch[1].trim().split('\n')[0].trim();
74
74
  hypothesis = (0, security_cjs_1.sanitizeForDisplay)(focusText.slice(0, 100));
@@ -506,7 +506,7 @@ function scanContextQuestions(planDir) {
506
506
  }
507
507
  // Also check for ## Open Questions section in body
508
508
  if (questions.length === 0) {
509
- const oqMatch = content.match(/##\s*Open Questions[^\n]*\n([\s\S]*?)(?=\n##\s|$)/i);
509
+ const oqMatch = content.match(/##\s*Open Questions[^\n]*\n([\s\S]*?)(?=\n##\s|$)/i); // allow-adhoc-markdown: pre-seam read-only section extract in audit.cts; pending migration #1372
510
510
  if (oqMatch) {
511
511
  const oqBody = oqMatch[1].trim();
512
512
  if (oqBody && oqBody.length > 0 && !/^\s*none\s*$/i.test(oqBody)) {