@hegemonart/get-design-done 1.31.0 → 1.32.0

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 (180) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +75 -0
  4. package/NOTICE +262 -0
  5. package/README.md +13 -1
  6. package/SKILL.md +4 -0
  7. package/agents/design-authority-watcher.md +1 -1
  8. package/agents/perf-analyzer.md +2 -2
  9. package/bin/gdd-mcp +78 -0
  10. package/bin/gdd-sdk +34 -24
  11. package/bin/gdd-state-mcp +78 -0
  12. package/{README.de.md → docs/i18n/README.de.md} +1 -1
  13. package/{README.fr.md → docs/i18n/README.fr.md} +1 -1
  14. package/{README.it.md → docs/i18n/README.it.md} +1 -1
  15. package/{README.ja.md → docs/i18n/README.ja.md} +1 -1
  16. package/{README.ko.md → docs/i18n/README.ko.md} +1 -1
  17. package/{README.zh-CN.md → docs/i18n/README.zh-CN.md} +1 -1
  18. package/hooks/_hook-emit.js +1 -1
  19. package/hooks/budget-enforcer.ts +5 -5
  20. package/hooks/context-exhaustion.ts +2 -2
  21. package/hooks/gdd-precompact-snapshot.js +3 -3
  22. package/hooks/gdd-read-injection-scanner.ts +2 -2
  23. package/hooks/gdd-sessionstart-recap.js +1 -1
  24. package/hooks/gdd-turn-closeout.js +1 -1
  25. package/hooks/hooks.json +9 -0
  26. package/hooks/inject-using-gdd.sh +72 -0
  27. package/hooks/run-hook.cmd +35 -0
  28. package/package.json +20 -9
  29. package/recipes/.gitkeep +0 -0
  30. package/reference/schemas/events.schema.json +63 -1
  31. package/reference/schemas/recipe.schema.json +33 -0
  32. package/scripts/cli/gdd-events.mjs +5 -5
  33. package/scripts/lib/cache/gdd-cache-manager.cjs +1 -1
  34. package/scripts/lib/cli/index.ts +22 -160
  35. package/scripts/lib/connection-probe/index.cjs +1 -1
  36. package/scripts/lib/discuss-parallel-runner/aggregator.ts +1 -1
  37. package/scripts/lib/discuss-parallel-runner/index.ts +1 -1
  38. package/scripts/lib/error-classifier.cjs +24 -227
  39. package/scripts/lib/event-stream/index.ts +25 -193
  40. package/scripts/lib/gdd-errors/index.ts +24 -213
  41. package/scripts/lib/gdd-state/index.ts +23 -161
  42. package/scripts/lib/health-mirror/index.cjs +79 -1
  43. package/scripts/lib/iteration-budget.cjs +23 -199
  44. package/scripts/lib/jittered-backoff.cjs +24 -107
  45. package/scripts/lib/lockfile.cjs +23 -195
  46. package/scripts/lib/logger/index.ts +1 -1
  47. package/scripts/lib/parallelism-engine/concurrency-tuner.cjs +1 -1
  48. package/scripts/lib/perf-analyzer/index.cjs +1 -1
  49. package/scripts/lib/pipeline-runner/index.ts +4 -4
  50. package/scripts/lib/pipeline-runner/state-machine.ts +1 -1
  51. package/scripts/lib/prompt-dedup/index.cjs +1 -1
  52. package/scripts/lib/rate-guard.cjs +2 -2
  53. package/scripts/lib/recipe-loader.cjs +142 -0
  54. package/scripts/lib/session-runner/errors.ts +3 -3
  55. package/scripts/lib/session-runner/index.ts +3 -3
  56. package/scripts/lib/session-runner/transcript.ts +1 -1
  57. package/scripts/lib/tool-scoping/index.ts +1 -1
  58. package/scripts/mcp-servers/gdd-mcp/server.ts +29 -311
  59. package/scripts/mcp-servers/gdd-state/server.ts +28 -282
  60. package/sdk/README.md +45 -0
  61. package/{scripts/lib → sdk}/cli/commands/audit.ts +3 -3
  62. package/{scripts/lib → sdk}/cli/commands/init.ts +3 -3
  63. package/{scripts/lib → sdk}/cli/commands/query.ts +4 -4
  64. package/{scripts/lib → sdk}/cli/commands/run.ts +5 -5
  65. package/{scripts/lib → sdk}/cli/commands/stage.ts +5 -5
  66. package/sdk/cli/index.js +8091 -0
  67. package/sdk/cli/index.ts +172 -0
  68. package/{scripts/lib → sdk}/cli/parse-args.ts +2 -2
  69. package/{scripts/lib/gdd-errors → sdk/errors}/classification.ts +1 -1
  70. package/sdk/errors/index.ts +218 -0
  71. package/{scripts/lib → sdk}/event-stream/emitter.ts +1 -1
  72. package/sdk/event-stream/index.ts +197 -0
  73. package/{scripts/lib → sdk}/event-stream/reader.ts +1 -1
  74. package/{scripts/lib → sdk}/event-stream/types.ts +2 -2
  75. package/{scripts/lib → sdk}/event-stream/writer.ts +1 -1
  76. package/sdk/index.ts +19 -0
  77. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/README.md +3 -3
  78. package/sdk/mcp/gdd-mcp/server.js +1966 -0
  79. package/sdk/mcp/gdd-mcp/server.ts +325 -0
  80. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_cycle_recap.ts +3 -3
  81. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_decisions_list.ts +2 -2
  82. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_events_tail.ts +3 -3
  83. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_health.ts +2 -2
  84. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_intel_get.ts +2 -2
  85. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_learnings_digest.ts +2 -2
  86. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phase_current.ts +2 -2
  87. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phases_list.ts +2 -2
  88. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_plans_list.ts +2 -2
  89. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_reflections_latest.ts +2 -2
  90. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_status.ts +3 -3
  91. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_telemetry_query.ts +3 -3
  92. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/index.ts +2 -2
  93. package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/shared.ts +3 -3
  94. package/sdk/mcp/gdd-state/server.js +2790 -0
  95. package/sdk/mcp/gdd-state/server.ts +294 -0
  96. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_blocker.ts +3 -3
  97. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_decision.ts +3 -3
  98. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_must_have.ts +3 -3
  99. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/checkpoint.ts +2 -2
  100. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/frontmatter_update.ts +2 -2
  101. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/get.ts +3 -3
  102. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/index.ts +1 -1
  103. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/probe_connections.ts +3 -3
  104. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/resolve_blocker.ts +3 -3
  105. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/set_status.ts +2 -2
  106. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/shared.ts +8 -8
  107. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/transition_stage.ts +4 -4
  108. package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/update_progress.ts +2 -2
  109. package/sdk/primitives/error-classifier.cjs +232 -0
  110. package/sdk/primitives/iteration-budget.cjs +205 -0
  111. package/sdk/primitives/jittered-backoff.cjs +112 -0
  112. package/sdk/primitives/lockfile.cjs +201 -0
  113. package/{scripts/lib/gdd-state → sdk/state}/gates.ts +1 -1
  114. package/sdk/state/index.ts +167 -0
  115. package/{scripts/lib/gdd-state → sdk/state}/lockfile.ts +1 -1
  116. package/{scripts/lib/gdd-state → sdk/state}/mutator.ts +1 -1
  117. package/{scripts/lib/gdd-state → sdk/state}/parser.ts +1 -1
  118. package/{scripts/lib/gdd-state → sdk/state}/types.ts +4 -4
  119. package/skills/audit/SKILL.md +13 -0
  120. package/skills/brief/SKILL.md +25 -0
  121. package/skills/design/SKILL.md +17 -0
  122. package/skills/discuss/SKILL.md +13 -0
  123. package/skills/explore/SKILL.md +17 -0
  124. package/skills/health/SKILL.md +6 -0
  125. package/skills/plan/SKILL.md +25 -0
  126. package/skills/quality-gate/SKILL.md +2 -2
  127. package/skills/router/SKILL.md +4 -0
  128. package/skills/router/router-pick-emitter.md +78 -0
  129. package/skills/using-gdd/SKILL.md +78 -0
  130. package/skills/verify/SKILL.md +17 -0
  131. package/scripts/aggregate-agent-metrics.ts +0 -282
  132. package/scripts/bootstrap-manifest.txt +0 -3
  133. package/scripts/bootstrap.sh +0 -80
  134. package/scripts/build-distribution-bundles.cjs +0 -549
  135. package/scripts/build-intel.cjs +0 -486
  136. package/scripts/codegen-schema-types.ts +0 -149
  137. package/scripts/detect-stale-refs.cjs +0 -107
  138. package/scripts/e2e/run-headless.ts +0 -514
  139. package/scripts/extract-changelog-section.cjs +0 -58
  140. package/scripts/gsd-cleanup-incubator.cjs +0 -367
  141. package/scripts/injection-patterns.cjs +0 -58
  142. package/scripts/lint-agentskills-spec.cjs +0 -457
  143. package/scripts/release-smoke-test.cjs +0 -200
  144. package/scripts/rollback-release.sh +0 -42
  145. package/scripts/run-injection-scanner-ci.cjs +0 -83
  146. package/scripts/tests/test-authority-rejected-kinds.sh +0 -58
  147. package/scripts/tests/test-authority-watcher-diff.sh +0 -113
  148. package/scripts/tests/test-motion-provenance.sh +0 -64
  149. package/scripts/validate-frontmatter.ts +0 -409
  150. package/scripts/validate-incubator-scope.cjs +0 -133
  151. package/scripts/validate-schemas.ts +0 -401
  152. package/scripts/validate-skill-length.cjs +0 -283
  153. package/scripts/verify-version-sync.cjs +0 -30
  154. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_cycle_recap.schema.json +0 -0
  155. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_decisions_list.schema.json +0 -0
  156. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_events_tail.schema.json +0 -0
  157. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_health.schema.json +0 -0
  158. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_intel_get.schema.json +0 -0
  159. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_learnings_digest.schema.json +0 -0
  160. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phase_current.schema.json +0 -0
  161. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phases_list.schema.json +0 -0
  162. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_plans_list.schema.json +0 -0
  163. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_reflections_latest.schema.json +0 -0
  164. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_status.schema.json +0 -0
  165. /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_telemetry_query.schema.json +0 -0
  166. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_blocker.schema.json +0 -0
  167. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_decision.schema.json +0 -0
  168. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_must_have.schema.json +0 -0
  169. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/checkpoint.schema.json +0 -0
  170. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/frontmatter_update.schema.json +0 -0
  171. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/get.schema.json +0 -0
  172. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/probe_connections.schema.json +0 -0
  173. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/resolve_blocker.schema.json +0 -0
  174. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/set_status.schema.json +0 -0
  175. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/transition_stage.schema.json +0 -0
  176. /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/update_progress.schema.json +0 -0
  177. /package/{scripts/lib → sdk/primitives}/error-classifier.d.cts +0 -0
  178. /package/{scripts/lib → sdk/primitives}/iteration-budget.d.cts +0 -0
  179. /package/{scripts/lib → sdk/primitives}/jittered-backoff.d.cts +0 -0
  180. /package/{scripts/lib → sdk/primitives}/lockfile.d.cts +0 -0
@@ -1,197 +1,29 @@
1
- // scripts/lib/event-stream/index.ts — public API for the Phase 20+
2
- // telemetry stream (Plan 20-06, SDK-08).
1
+ // scripts/lib/event-stream/index.ts — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
3
2
  //
4
- // Consumers import ONLY from this file. The internal parts
5
- // (`./types.ts`, `./writer.ts`, `./emitter.ts`) are implementation
6
- // detail; changing them without updating this export surface is a
7
- // breaking change for downstream plans (20-05 MCP handlers, 20-13 hooks).
3
+ // Thin deprecation shim. The real implementation moved to
4
+ // sdk/event-stream/index.ts in Plan 31-5-04 (SDK consolidation). This file
5
+ // is re-created at the OLD path so undocumented EXTERNAL importers (anyone
6
+ // who reached into node_modules/@hegemonart/get-design-done/scripts/lib/
7
+ // event-stream/index.ts directly) keep working for one minor grace window.
8
8
  //
9
- // Surface:
10
- // * appendEvent(ev) — persist + broadcast one event
11
- // * getWriter(opts?) lazy singleton EventWriter
12
- // * getBus() — lazy singleton EventBus
13
- // * reset() — clear module-level singletons (tests)
14
- // * types — BaseEvent, KnownEvent, and every pre-
15
- // registered subtype (StateMutationEvent,
16
- // StateTransitionEvent, …).
17
-
18
- import { hostname } from 'node:os';
19
-
20
- import { EventBus } from './emitter.ts';
21
- import type { Unsubscribe, EventHandler } from './emitter.ts';
22
- import { EventWriter } from './writer.ts';
23
- import type { WriterOptions } from './writer.ts';
24
- import type { BaseEvent, EventMeta } from './types.ts';
25
-
26
- export type {
27
- BaseEvent,
28
- EventMeta,
29
- KnownEvent,
30
- StateMutationEvent,
31
- StateTransitionEvent,
32
- StageEnteredEvent,
33
- StageExitedEvent,
34
- HookFiredEvent,
35
- ErrorEvent,
36
- WaveStartedEvent,
37
- WaveCompletedEvent,
38
- BlockerAddedEvent,
39
- DecisionAddedEvent,
40
- MustHaveAddedEvent,
41
- ParallelismVerdictEvent,
42
- CostUpdateEvent,
43
- RateLimitEvent,
44
- ApiRetryEvent,
45
- CompactBoundaryEvent,
46
- McpProbeEvent,
47
- ReflectionProposedEvent,
48
- ConnectionStatusChangeEvent,
49
- ToolCallStartedEvent,
50
- ToolCallCompletedEvent,
51
- AgentSpawnEvent,
52
- AgentOutcomeEvent,
53
- // Phase 27 / Plan 27-08 — peer-CLI delegation events (D-09).
54
- RuntimeRole,
55
- PeerCallStartedEvent,
56
- PeerCallCompleteEvent,
57
- PeerCallFailedEvent,
58
- } from './types.ts';
59
- export {
60
- KNOWN_EVENT_TYPES,
61
- // Phase 27 / Plan 27-08 — symbolic constants for peer-CLI event names.
62
- PEER_CALL_STARTED,
63
- PEER_CALL_COMPLETE,
64
- PEER_CALL_FAILED,
65
- PEER_CALL_EVENT_TYPES,
66
- DEFAULT_RUNTIME_ROLE,
67
- } from './types.ts';
68
- export { EventBus } from './emitter.ts';
69
- export type { EventHandler, Unsubscribe } from './emitter.ts';
70
- export { EventWriter, DEFAULT_EVENTS_PATH, DEFAULT_MAX_LINE_BYTES } from './writer.ts';
71
- export type { WriterOptions } from './writer.ts';
72
- export { readEvents, aggregate } from './reader.ts';
73
- export type { ReadEventsOptions, AggregateResult } from './reader.ts';
74
-
75
- /**
76
- * Lazily-constructed module-level singletons. `getWriter()` honors the
77
- * first `opts` it receives; subsequent calls with different options are
78
- * ignored. Tests that need to vary options across runs should call
79
- * {@link reset} between runs.
80
- */
81
- let defaultWriter: EventWriter | null = null;
82
- let defaultBus: EventBus | null = null;
83
- /**
84
- * Cached host name. `os.hostname()` is cheap but not free (syscall on
85
- * some platforms) and we stamp it onto every event; compute once.
86
- */
87
- let cachedHost: string | null = null;
88
-
89
- /**
90
- * Return the module-level default writer, constructing it on first
91
- * call. Passing `opts` on subsequent calls is a no-op (the first
92
- * caller wins); that matches the "single shared file per process"
93
- * intent.
94
- */
95
- export function getWriter(opts?: WriterOptions): EventWriter {
96
- if (defaultWriter === null) {
97
- // Honor GDD_EVENTS_PATH env var as the first-choice default path
98
- // when the caller doesn't pass an explicit `opts.path`. Lets test
99
- // harnesses and Plan 21-11's E2E subprocess steer the on-disk
100
- // stream into a fixture-specific directory without chdir'ing the
101
- // entire process. Explicit `opts.path` always wins.
102
- const envPath: string | undefined = process.env['GDD_EVENTS_PATH'];
103
- const finalOpts: WriterOptions =
104
- opts?.path === undefined && envPath !== undefined && envPath.length > 0
105
- ? { ...(opts ?? {}), path: envPath }
106
- : (opts ?? {});
107
- defaultWriter = new EventWriter(finalOpts);
108
- }
109
- return defaultWriter;
110
- }
111
-
112
- /** Return the module-level default bus, constructing it on first call. */
113
- export function getBus(): EventBus {
114
- if (defaultBus === null) {
115
- defaultBus = new EventBus();
116
- }
117
- return defaultBus;
118
- }
119
-
120
- /**
121
- * Persist `ev` to the on-disk JSONL stream AND broadcast it to the
122
- * in-process bus. This is the normal emission path for every Phase 20+
123
- * event producer.
124
- *
125
- * Ordering:
126
- * 1. Stamp `_meta` (pid/host/source) if the caller didn't supply it.
127
- * 2. Persist via `getWriter().append(ev)` — sync, never throws.
128
- * 3. Broadcast via `getBus().emit(ev.type, ev)` AND `emit('*', ev)`
129
- * so typed subscribers and `subscribeAll` observers both see it.
130
- *
131
- * Bus emission can still throw if a subscriber handler throws; we
132
- * intentionally surface that rather than silently swallowing, since a
133
- * failing handler is a programming bug, not an expected runtime
134
- * condition. Plan 20-13's hooks wrap their handler bodies defensively
135
- * for this reason.
136
- */
137
- export function appendEvent(ev: BaseEvent): void {
138
- // Stamp writer-injected metadata if absent. We don't clone the full
139
- // event — callers typically build it fresh per emission — but we do
140
- // need to ensure `_meta` is present by the time we persist.
141
- if (ev._meta === undefined) {
142
- if (cachedHost === null) {
143
- try {
144
- cachedHost = hostname();
145
- } catch {
146
- cachedHost = 'unknown';
147
- }
148
- }
149
- const meta: EventMeta = {
150
- pid: process.pid,
151
- host: cachedHost,
152
- source: 'event-stream',
153
- };
154
- ev._meta = meta;
155
- }
156
-
157
- // Persist first. Bus emission is synchronous; if a subscriber throws
158
- // after we've persisted, the durable record is already safe.
159
- getWriter().append(ev);
160
-
161
- const bus = getBus();
162
- bus.emit(ev.type, ev);
163
- bus.emit('*', ev);
164
- }
165
-
166
- /**
167
- * Reset module-level singletons. Intended for tests that want a fresh
168
- * writer (e.g. pointed at a new temp directory) or a fresh bus (e.g.
169
- * to assert isolation between test cases).
170
- *
171
- * Safe to call from production code but the intended caller is a test.
172
- * `appendEvent()` will lazily reconstruct both singletons on the next
173
- * emission.
174
- */
175
- export function reset(): void {
176
- if (defaultBus !== null) {
177
- defaultBus.removeAllListeners();
178
- }
179
- defaultWriter = null;
180
- defaultBus = null;
181
- }
182
-
183
- // Re-export `subscribe`/`subscribeAll` convenience: some callers only
184
- // need to subscribe, not emit, and `getBus().subscribe(…)` reads fine
185
- // but the shorter form keeps consumer code terse.
186
- /** Convenience: subscribe to one event type on the default bus. */
187
- export function subscribe<T extends BaseEvent = BaseEvent>(
188
- type: T['type'],
189
- handler: EventHandler<T>,
190
- ): Unsubscribe {
191
- return getBus().subscribe<T>(type, handler);
9
+ // REMOVED IN v1.33.0 (D-02). Grace window: 1.31.5 ships with shims →
10
+ // 1.32.0 still has them 1.33.0 removes them. Internal callers already use
11
+ // the sdk/ path (Plan 31-5-04/05) this shim is external-only; 31-5-10's
12
+ // no-stale-internal-refs guard excludes files carrying the
13
+ // GDD-DEPRECATION-SHIM marker above.
14
+ //
15
+ // Runs under --experimental-strip-types, so `export *` re-export is
16
+ // strip-types-clean.
17
+
18
+ import { emitWarning } from 'node:process';
19
+
20
+ let warned = false;
21
+ if (!warned) {
22
+ warned = true;
23
+ emitWarning(
24
+ 'scripts/lib/event-stream/index.ts is deprecated; import sdk/event-stream instead. Removed in v1.33.0.',
25
+ 'DeprecationWarning',
26
+ );
192
27
  }
193
28
 
194
- /** Convenience: subscribe to every event on the default bus. */
195
- export function subscribeAll(handler: EventHandler<BaseEvent>): Unsubscribe {
196
- return getBus().subscribeAll(handler);
197
- }
29
+ export * from '../../../sdk/event-stream/index.ts';
@@ -1,218 +1,29 @@
1
- // scripts/lib/gdd-errors/index.ts — unified GDD error taxonomy.
1
+ // scripts/lib/gdd-errors/index.ts — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
2
2
  //
3
- // Three classes exactly mirrors the GSD errors.ts discipline:
3
+ // Thin deprecation shim. The real implementation moved to sdk/errors/index.ts
4
+ // in Plan 31-5-04 (SDK consolidation). This file is re-created at the OLD
5
+ // path so undocumented EXTERNAL importers (anyone who reached into
6
+ // node_modules/@hegemonart/get-design-done/scripts/lib/gdd-errors/index.ts
7
+ // directly) keep working for one minor grace window.
4
8
  //
5
- // * ValidationError — throw at boundary; "fix your input"
6
- // * StateConflictError — throw; lockfile contention or transition guard
7
- // failed; retryable by upstream
8
- // * OperationFailedError — return in data.error; "couldn't complete in
9
- // this state"; expected failure mode the caller
10
- // should branch on, not crash on
9
+ // REMOVED IN v1.33.0 (D-02). Grace window: 1.31.5 ships with shims →
10
+ // 1.32.0 still has them 1.33.0 removes them. Internal callers already use
11
+ // the sdk/ path (Plan 31-5-04/05) — this shim is external-only; 31-5-10's
12
+ // no-stale-internal-refs guard excludes files carrying the
13
+ // GDD-DEPRECATION-SHIM marker above.
11
14
  //
12
- // MCP tool handlers place OperationFailedError instances into data.error
13
- // so the model can see and reason about them. ValidationError and
14
- // StateConflictError are thrown (non-zero exit path).
15
- //
16
- // Plan 20-01 introduced LockAcquisitionError and TransitionGateFailed as
17
- // local Error subclasses; this module re-exports taxonomy-compliant
18
- // versions so the existing `gdd-state` surface (tests + consumers) keeps
19
- // working unchanged. Plan 20-05 wires `toToolError` into MCP tool
20
- // handlers; Plan 20-06 emits error events to the telemetry stream.
21
-
22
- /** Short machine-readable code. Example: "VALIDATION_MISSING_FIELD". */
23
- export type GDDErrorCode = string;
24
-
25
- /**
26
- * Abstract base class — every GDD taxonomy error inherits from this.
27
- *
28
- * Subclasses set a literal `kind` discriminant so `classify()` can
29
- * branch on it without `instanceof` chains, and `toJSON()` produces a
30
- * lossless payload for tool-result transport.
31
- */
32
- export abstract class GDDError extends Error {
33
- abstract readonly kind: 'validation' | 'state_conflict' | 'operation_failed';
34
- readonly code: GDDErrorCode;
35
- readonly context: Readonly<Record<string, unknown>>;
36
-
37
- constructor(
38
- message: string,
39
- code: GDDErrorCode,
40
- context: Record<string, unknown> = {},
41
- ) {
42
- super(message);
43
- this.code = code;
44
- this.context = Object.freeze({ ...context });
45
- // Set .name to the concrete subclass name (LockAcquisitionError,
46
- // ValidationError, etc.) so error serialization is human-meaningful.
47
- this.name = new.target.name;
48
- }
49
-
50
- /**
51
- * Serialize to a plain object safe for JSON.stringify. Round-trips
52
- * through JSON without loss of `name`, `kind`, `code`, `message`, or
53
- * `context`. Does NOT include the stack trace — MCP tool handlers do
54
- * not forward stacks to the model.
55
- */
56
- toJSON(): {
57
- name: string;
58
- kind: GDDError['kind'];
59
- code: GDDErrorCode;
60
- message: string;
61
- context: Readonly<Record<string, unknown>>;
62
- } {
63
- return {
64
- name: this.name,
65
- kind: this.kind,
66
- code: this.code,
67
- message: this.message,
68
- context: this.context,
69
- };
70
- }
71
- }
72
-
73
- /**
74
- * Throw at boundary when the caller's input is malformed.
75
- *
76
- * Example: MCP tool handler receives an argument that fails schema
77
- * validation; the correct response is `throw new ValidationError(...)`
78
- * so the harness catches it and returns a structured error to the model.
79
- * The model should fix its input and retry.
80
- */
81
- export class ValidationError extends GDDError {
82
- readonly kind = 'validation' as const;
83
- constructor(
84
- message: string,
85
- code: GDDErrorCode = 'VALIDATION',
86
- context?: Record<string, unknown>,
87
- ) {
88
- super(message, code, context);
89
- }
90
- }
91
-
92
- /**
93
- * Throw when a concurrency primitive or transition guard vetoes the
94
- * operation. Retryable by upstream — the caller may try again after a
95
- * backoff, or surface the blocker to the operator.
96
- *
97
- * Examples: lockfile contention (LockAcquisitionError), transition
98
- * gate failure (TransitionGateFailed).
99
- */
100
- export class StateConflictError extends GDDError {
101
- readonly kind = 'state_conflict' as const;
102
- constructor(
103
- message: string,
104
- code: GDDErrorCode = 'STATE_CONFLICT',
105
- context?: Record<string, unknown>,
106
- ) {
107
- super(message, code, context);
108
- }
15
+ // Runs under --experimental-strip-types, so `export *` re-export is
16
+ // strip-types-clean.
17
+
18
+ import { emitWarning } from 'node:process';
19
+
20
+ let warned = false;
21
+ if (!warned) {
22
+ warned = true;
23
+ emitWarning(
24
+ 'scripts/lib/gdd-errors/index.ts is deprecated; import sdk/errors instead. Removed in v1.33.0.',
25
+ 'DeprecationWarning',
26
+ );
109
27
  }
110
28
 
111
- /**
112
- * Return as `data.error` — do NOT throw. This is the expected failure
113
- * mode the caller should branch on: the operation is well-formed, the
114
- * state is valid, but the specific request cannot complete right now.
115
- *
116
- * Example: "try to advance to `design`, but no plan exists yet" — the
117
- * model should be told, not crashed on.
118
- */
119
- export class OperationFailedError extends GDDError {
120
- readonly kind = 'operation_failed' as const;
121
- constructor(
122
- message: string,
123
- code: GDDErrorCode = 'OPERATION_FAILED',
124
- context?: Record<string, unknown>,
125
- ) {
126
- super(message, code, context);
127
- }
128
- }
129
-
130
- // -----------------------------------------------------------------------
131
- // Plan 20-01 compatibility re-exports.
132
- //
133
- // These keep the `gdd-state` module's public surface stable post-refactor:
134
- // - LockAcquisitionError — lockfile contention (plan 20-01 lockfile.ts)
135
- // - TransitionGateFailed — transition gate veto (plan 20-01 transition())
136
- // Both are StateConflictError subclasses (retryable / contention-class
137
- // errors).
138
- // -----------------------------------------------------------------------
139
-
140
- /**
141
- * Error thrown when `acquire()` cannot obtain the lockfile within
142
- * `maxWaitMs`. Carries the contents of the offending lockfile (as
143
- * text — may be JSON, may be garbage if corrupted) so callers can
144
- * surface them to operators.
145
- *
146
- * The `lockPath` and `lockContents` instance properties are preserved
147
- * from the Plan 20-01 shape for API compat; they're also stored in
148
- * the frozen `context` object for uniform GDDError serialization.
149
- */
150
- export class LockAcquisitionError extends StateConflictError {
151
- readonly lockPath: string;
152
- readonly lockContents: string;
153
- readonly waitedMs: number;
154
- constructor(
155
- lockPath: string,
156
- lockContents: string,
157
- waitedMs: number,
158
- context?: Record<string, unknown>,
159
- ) {
160
- super(
161
- `failed to acquire lock at ${lockPath} after ${waitedMs}ms; current holder: ${lockContents}`,
162
- 'LOCK_ACQUISITION',
163
- { ...context, lockPath, lockContents, waitedMs },
164
- );
165
- this.lockPath = lockPath;
166
- this.lockContents = lockContents;
167
- this.waitedMs = waitedMs;
168
- }
169
- }
170
-
171
- /**
172
- * Error thrown when a transition gate vetoes a stage advance. Carries
173
- * the frozen list of blocker messages so callers can surface them to
174
- * operators or retry after resolving.
175
- *
176
- * The `blockers` instance property is preserved from the Plan 20-01
177
- * shape (readonly string[]) for API compat; it's also mirrored into
178
- * the frozen `context` object for uniform GDDError serialization.
179
- */
180
- export class TransitionGateFailed extends StateConflictError {
181
- readonly blockers: readonly string[];
182
- readonly toStage: string;
183
- constructor(
184
- toStage: string,
185
- blockers: string[],
186
- context?: Record<string, unknown>,
187
- ) {
188
- super(
189
- `transition to "${toStage}" blocked by gate: ${blockers.join('; ') || '(no detail)'}`,
190
- 'TRANSITION_GATE_FAILED',
191
- { ...context, toStage, blockers: [...blockers] },
192
- );
193
- this.toStage = toStage;
194
- this.blockers = Object.freeze([...blockers]);
195
- }
196
- }
197
-
198
- /**
199
- * Error thrown by STATE.md `parse()` when the input cannot be
200
- * interpreted. `ValidationError` semantics: the caller (likely the
201
- * operator or an upstream generator) gave us malformed input — fix
202
- * your STATE.md and retry.
203
- *
204
- * The `line` instance property points at the 1-indexed line in the
205
- * source markdown where the parser gave up. It's also mirrored into
206
- * the frozen `context` object.
207
- */
208
- export class ParseError extends ValidationError {
209
- readonly line: number;
210
- constructor(message: string, line: number, context?: Record<string, unknown>) {
211
- super(
212
- `STATE.md parse error at line ${line}: ${message}`,
213
- 'PARSE_ERROR',
214
- { ...context, line },
215
- );
216
- this.line = line;
217
- }
218
- }
29
+ export * from '../../../sdk/errors/index.ts';
@@ -1,167 +1,29 @@
1
- // scripts/lib/gdd-state/index.ts — public API for the gdd-state module.
1
+ // scripts/lib/gdd-state/index.ts — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
2
2
  //
3
- // This is the ONLY file consumers should import from. The module exposes
4
- // exactly five surface-level names:
5
- // * read(path) — parse STATE.md from disk
6
- // * mutate(path, fn) — atomic read-modify-write under a lock
7
- // * transition(path, toStage) gate + stage-advance helper
8
- // * ParsedState (type) — consumer-visible shape
9
- // * Stage (type) — stage enum
3
+ // Thin deprecation shim. The real implementation moved to sdk/state/index.ts
4
+ // in Plan 31-5-04 (SDK consolidation). This file is re-created at the OLD
5
+ // path so undocumented EXTERNAL importers (anyone who reached into
6
+ // node_modules/@hegemonart/get-design-done/scripts/lib/gdd-state/index.ts
7
+ // directly) keep working for one minor grace window.
10
8
  //
11
- // Plan 20-02 wired the real transition gates in via `gateFor(from, to)`
12
- // imported from `./gates.ts`. Plan 20-04 migrated the error classes
13
- // (TransitionGateFailed, LockAcquisitionError, ParseError) to the
14
- // unified `gdd-errors` taxonomy `types.ts` re-exports them verbatim
15
- // so consumers of `gdd-state` need no changes.
16
-
17
- import { readFileSync, writeFileSync, renameSync, unlinkSync, existsSync } from 'node:fs';
18
-
19
- import { acquire } from './lockfile.ts';
20
- import { parse } from './parser.ts';
21
- import { serialize } from './mutator.ts';
22
- import { gateFor } from './gates.ts';
23
- import {
24
- TransitionGateFailed,
25
- isStage,
26
- type ParsedState,
27
- type Stage,
28
- type TransitionResult,
29
- } from './types.ts';
30
-
31
- export type { ParsedState, Stage } from './types.ts';
32
- export { TransitionGateFailed, LockAcquisitionError, ParseError } from './types.ts';
9
+ // REMOVED IN v1.33.0 (D-02). Grace window: 1.31.5 ships with shims
10
+ // 1.32.0 still has them → 1.33.0 removes them. Internal callers already use
11
+ // the sdk/ path (Plan 31-5-04/05) this shim is external-only; 31-5-10's
12
+ // no-stale-internal-refs guard excludes files carrying the
13
+ // GDD-DEPRECATION-SHIM marker above.
14
+ //
15
+ // Runs under --experimental-strip-types, so `export *` re-export is
16
+ // strip-types-clean.
33
17
 
34
- /**
35
- * Read STATE.md from disk and return the parsed state.
36
- *
37
- * Shared-read: no lock is taken. Reads are snapshot-safe for markdown
38
- * (the OS guarantees a coherent view even if a writer is mid-rename —
39
- * we either see the old file or the new file, never a torn write,
40
- * because `mutate()` uses atomic rename).
41
- */
42
- export async function read(path: string): Promise<ParsedState> {
43
- const raw: string = readFileSync(path, 'utf8');
44
- return parse(raw).state;
45
- }
18
+ import { emitWarning } from 'node:process';
46
19
 
47
- /**
48
- * Atomic read-modify-write on STATE.md.
49
- *
50
- * Flow:
51
- * 1. Acquire sibling `.lock` file (PID+timestamp advisory lock).
52
- * 2. Read current contents.
53
- * 3. Apply `fn`.
54
- * 4. Serialize to a `.tmp` file next to `path`.
55
- * 5. `renameSync(.tmp, path)` — POSIX-atomic; on Windows EPERM means
56
- * a scanner held it briefly, retry once.
57
- * 6. Release the lock (in `finally` — released even on mid-fn throw).
58
- *
59
- * Crash between write and rename is benign: STATE.md is untouched; the
60
- * `.tmp` file is orphaned (cleaned up on the next acquire by the caller).
61
- */
62
- export async function mutate(
63
- path: string,
64
- fn: (s: ParsedState) => ParsedState,
65
- ): Promise<ParsedState> {
66
- const release = await acquire(path);
67
- const tmpPath: string = `${path}.tmp`;
68
- try {
69
- const raw: string = readFileSync(path, 'utf8');
70
- const { state, raw_bodies, raw_frontmatter, block_gaps, line_ending } =
71
- parse(raw);
72
- // Deep-clone so the consumer's fn cannot mutate the state we just
73
- // parsed (defensive — apply() does this too for pure callers).
74
- const clone = structuredClone(state);
75
- const next = fn(clone);
76
- const out = serialize(next, {
77
- raw_frontmatter,
78
- raw_bodies,
79
- block_gaps,
80
- line_ending,
81
- });
82
- writeFileSync(tmpPath, out, 'utf8');
83
- try {
84
- renameSync(tmpPath, path);
85
- } catch (err) {
86
- // Windows EPERM retry — AV / indexer holding STATE.md briefly.
87
- const code =
88
- typeof err === 'object' && err !== null && 'code' in err
89
- ? (err as { code?: unknown }).code
90
- : undefined;
91
- if (code === 'EPERM' || code === 'EBUSY') {
92
- await new Promise((r) => setTimeout(r, 50));
93
- renameSync(tmpPath, path);
94
- } else {
95
- throw err;
96
- }
97
- }
98
- return next;
99
- } catch (err) {
100
- // Clean up the orphaned tmp file on failure so we don't pollute.
101
- try {
102
- if (existsSync(tmpPath)) unlinkSync(tmpPath);
103
- } catch {
104
- // best-effort; a leftover tmp file does not corrupt STATE.md.
105
- }
106
- throw err;
107
- } finally {
108
- await release();
109
- }
20
+ let warned = false;
21
+ if (!warned) {
22
+ warned = true;
23
+ emitWarning(
24
+ 'scripts/lib/gdd-state/index.ts is deprecated; import sdk/state instead. Removed in v1.33.0.',
25
+ 'DeprecationWarning',
26
+ );
110
27
  }
111
28
 
112
- /**
113
- * Advance to `toStage` under the locked RMW protocol.
114
- *
115
- * Steps:
116
- * 1. Read current state (outside the lock) to pass to the gate.
117
- * 2. Resolve the gate via `gateFor(position.stage, toStage)`.
118
- * - `null` → TransitionGateFailed "Invalid transition" (skip-stage,
119
- * backward, same-stage, or from outside the Stage union).
120
- * 3. Invoke the gate. If `pass: false`, throw TransitionGateFailed with
121
- * the gate's blockers verbatim.
122
- * 4. If `pass: true`, mutate STATE.md under the lock:
123
- * - frontmatter.stage = toStage
124
- * - position.stage = toStage
125
- * - frontmatter.last_checkpoint = now (ISO)
126
- * - timestamps[`${toStage}_started_at`] = now (ISO)
127
- *
128
- * Returns the updated state plus the gate response (for callers that
129
- * want to log blockers — on pass, `blockers` is always `[]`).
130
- */
131
- export async function transition(
132
- path: string,
133
- toStage: Stage,
134
- ): Promise<TransitionResult> {
135
- // Read (outside the lock) to pass current state to the gate — the
136
- // mutate() below will re-read under the lock before applying changes.
137
- // This two-phase pattern matches the GSD reference implementation.
138
- const beforeMutate = await read(path);
139
- const from: string = beforeMutate.position.stage;
140
- // `position.stage` is typed as `string` in ParsedState (parser tolerates
141
- // `scan` and other pre-brief values). Narrow it to `Stage` before asking
142
- // the gate registry — anything outside the union is an invalid FROM.
143
- if (!isStage(from)) {
144
- throw new TransitionGateFailed(toStage, [
145
- `Invalid transition: from="${from}" is not a recognized Stage`,
146
- ]);
147
- }
148
- const gate = gateFor(from, toStage);
149
- if (gate === null) {
150
- throw new TransitionGateFailed(toStage, [
151
- `Invalid transition: ${from} → ${toStage}`,
152
- ]);
153
- }
154
- const gateResult = gate(beforeMutate);
155
- if (!gateResult.pass) {
156
- throw new TransitionGateFailed(toStage, gateResult.blockers);
157
- }
158
- const nowIso: string = new Date().toISOString();
159
- const nextState = await mutate(path, (s): ParsedState => {
160
- s.frontmatter.stage = toStage;
161
- s.frontmatter.last_checkpoint = nowIso;
162
- s.position.stage = toStage;
163
- s.timestamps[`${toStage}_started_at`] = nowIso;
164
- return s;
165
- });
166
- return { pass: true, blockers: gateResult.blockers, state: nextState };
167
- }
29
+ export * from '../../../sdk/state/index.ts';