@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +75 -0
- package/NOTICE +262 -0
- package/README.md +13 -1
- package/SKILL.md +4 -0
- package/agents/design-authority-watcher.md +1 -1
- package/agents/perf-analyzer.md +2 -2
- package/bin/gdd-mcp +78 -0
- package/bin/gdd-sdk +34 -24
- package/bin/gdd-state-mcp +78 -0
- package/{README.de.md → docs/i18n/README.de.md} +1 -1
- package/{README.fr.md → docs/i18n/README.fr.md} +1 -1
- package/{README.it.md → docs/i18n/README.it.md} +1 -1
- package/{README.ja.md → docs/i18n/README.ja.md} +1 -1
- package/{README.ko.md → docs/i18n/README.ko.md} +1 -1
- package/{README.zh-CN.md → docs/i18n/README.zh-CN.md} +1 -1
- package/hooks/_hook-emit.js +1 -1
- package/hooks/budget-enforcer.ts +5 -5
- package/hooks/context-exhaustion.ts +2 -2
- package/hooks/gdd-precompact-snapshot.js +3 -3
- package/hooks/gdd-read-injection-scanner.ts +2 -2
- package/hooks/gdd-sessionstart-recap.js +1 -1
- package/hooks/gdd-turn-closeout.js +1 -1
- package/hooks/hooks.json +9 -0
- package/hooks/inject-using-gdd.sh +72 -0
- package/hooks/run-hook.cmd +35 -0
- package/package.json +20 -9
- package/recipes/.gitkeep +0 -0
- package/reference/schemas/events.schema.json +63 -1
- package/reference/schemas/recipe.schema.json +33 -0
- package/scripts/cli/gdd-events.mjs +5 -5
- package/scripts/lib/cache/gdd-cache-manager.cjs +1 -1
- package/scripts/lib/cli/index.ts +22 -160
- package/scripts/lib/connection-probe/index.cjs +1 -1
- package/scripts/lib/discuss-parallel-runner/aggregator.ts +1 -1
- package/scripts/lib/discuss-parallel-runner/index.ts +1 -1
- package/scripts/lib/error-classifier.cjs +24 -227
- package/scripts/lib/event-stream/index.ts +25 -193
- package/scripts/lib/gdd-errors/index.ts +24 -213
- package/scripts/lib/gdd-state/index.ts +23 -161
- package/scripts/lib/health-mirror/index.cjs +79 -1
- package/scripts/lib/iteration-budget.cjs +23 -199
- package/scripts/lib/jittered-backoff.cjs +24 -107
- package/scripts/lib/lockfile.cjs +23 -195
- package/scripts/lib/logger/index.ts +1 -1
- package/scripts/lib/parallelism-engine/concurrency-tuner.cjs +1 -1
- package/scripts/lib/perf-analyzer/index.cjs +1 -1
- package/scripts/lib/pipeline-runner/index.ts +4 -4
- package/scripts/lib/pipeline-runner/state-machine.ts +1 -1
- package/scripts/lib/prompt-dedup/index.cjs +1 -1
- package/scripts/lib/rate-guard.cjs +2 -2
- package/scripts/lib/recipe-loader.cjs +142 -0
- package/scripts/lib/session-runner/errors.ts +3 -3
- package/scripts/lib/session-runner/index.ts +3 -3
- package/scripts/lib/session-runner/transcript.ts +1 -1
- package/scripts/lib/tool-scoping/index.ts +1 -1
- package/scripts/mcp-servers/gdd-mcp/server.ts +29 -311
- package/scripts/mcp-servers/gdd-state/server.ts +28 -282
- package/sdk/README.md +45 -0
- package/{scripts/lib → sdk}/cli/commands/audit.ts +3 -3
- package/{scripts/lib → sdk}/cli/commands/init.ts +3 -3
- package/{scripts/lib → sdk}/cli/commands/query.ts +4 -4
- package/{scripts/lib → sdk}/cli/commands/run.ts +5 -5
- package/{scripts/lib → sdk}/cli/commands/stage.ts +5 -5
- package/sdk/cli/index.js +8091 -0
- package/sdk/cli/index.ts +172 -0
- package/{scripts/lib → sdk}/cli/parse-args.ts +2 -2
- package/{scripts/lib/gdd-errors → sdk/errors}/classification.ts +1 -1
- package/sdk/errors/index.ts +218 -0
- package/{scripts/lib → sdk}/event-stream/emitter.ts +1 -1
- package/sdk/event-stream/index.ts +197 -0
- package/{scripts/lib → sdk}/event-stream/reader.ts +1 -1
- package/{scripts/lib → sdk}/event-stream/types.ts +2 -2
- package/{scripts/lib → sdk}/event-stream/writer.ts +1 -1
- package/sdk/index.ts +19 -0
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/README.md +3 -3
- package/sdk/mcp/gdd-mcp/server.js +1966 -0
- package/sdk/mcp/gdd-mcp/server.ts +325 -0
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_cycle_recap.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_decisions_list.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_events_tail.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_health.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_intel_get.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_learnings_digest.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phase_current.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_phases_list.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_plans_list.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_reflections_latest.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_status.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/gdd_telemetry_query.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/index.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/tools/shared.ts +3 -3
- package/sdk/mcp/gdd-state/server.js +2790 -0
- package/sdk/mcp/gdd-state/server.ts +294 -0
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_blocker.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_decision.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/add_must_have.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/checkpoint.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/frontmatter_update.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/get.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/index.ts +1 -1
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/probe_connections.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/resolve_blocker.ts +3 -3
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/set_status.ts +2 -2
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/shared.ts +8 -8
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/transition_stage.ts +4 -4
- package/{scripts/mcp-servers → sdk/mcp}/gdd-state/tools/update_progress.ts +2 -2
- package/sdk/primitives/error-classifier.cjs +232 -0
- package/sdk/primitives/iteration-budget.cjs +205 -0
- package/sdk/primitives/jittered-backoff.cjs +112 -0
- package/sdk/primitives/lockfile.cjs +201 -0
- package/{scripts/lib/gdd-state → sdk/state}/gates.ts +1 -1
- package/sdk/state/index.ts +167 -0
- package/{scripts/lib/gdd-state → sdk/state}/lockfile.ts +1 -1
- package/{scripts/lib/gdd-state → sdk/state}/mutator.ts +1 -1
- package/{scripts/lib/gdd-state → sdk/state}/parser.ts +1 -1
- package/{scripts/lib/gdd-state → sdk/state}/types.ts +4 -4
- package/skills/audit/SKILL.md +13 -0
- package/skills/brief/SKILL.md +25 -0
- package/skills/design/SKILL.md +17 -0
- package/skills/discuss/SKILL.md +13 -0
- package/skills/explore/SKILL.md +17 -0
- package/skills/health/SKILL.md +6 -0
- package/skills/plan/SKILL.md +25 -0
- package/skills/quality-gate/SKILL.md +2 -2
- package/skills/router/SKILL.md +4 -0
- package/skills/router/router-pick-emitter.md +78 -0
- package/skills/using-gdd/SKILL.md +78 -0
- package/skills/verify/SKILL.md +17 -0
- package/scripts/aggregate-agent-metrics.ts +0 -282
- package/scripts/bootstrap-manifest.txt +0 -3
- package/scripts/bootstrap.sh +0 -80
- package/scripts/build-distribution-bundles.cjs +0 -549
- package/scripts/build-intel.cjs +0 -486
- package/scripts/codegen-schema-types.ts +0 -149
- package/scripts/detect-stale-refs.cjs +0 -107
- package/scripts/e2e/run-headless.ts +0 -514
- package/scripts/extract-changelog-section.cjs +0 -58
- package/scripts/gsd-cleanup-incubator.cjs +0 -367
- package/scripts/injection-patterns.cjs +0 -58
- package/scripts/lint-agentskills-spec.cjs +0 -457
- package/scripts/release-smoke-test.cjs +0 -200
- package/scripts/rollback-release.sh +0 -42
- package/scripts/run-injection-scanner-ci.cjs +0 -83
- package/scripts/tests/test-authority-rejected-kinds.sh +0 -58
- package/scripts/tests/test-authority-watcher-diff.sh +0 -113
- package/scripts/tests/test-motion-provenance.sh +0 -64
- package/scripts/validate-frontmatter.ts +0 -409
- package/scripts/validate-incubator-scope.cjs +0 -133
- package/scripts/validate-schemas.ts +0 -401
- package/scripts/validate-skill-length.cjs +0 -283
- package/scripts/verify-version-sync.cjs +0 -30
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_cycle_recap.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_decisions_list.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_events_tail.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_health.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_intel_get.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_learnings_digest.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phase_current.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_phases_list.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_plans_list.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_reflections_latest.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_status.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-mcp/schemas/gdd_telemetry_query.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_blocker.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_decision.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/add_must_have.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/checkpoint.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/frontmatter_update.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/get.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/probe_connections.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/resolve_blocker.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/set_status.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/transition_stage.schema.json +0 -0
- /package/{scripts/mcp-servers → sdk/mcp}/gdd-state/schemas/update_progress.schema.json +0 -0
- /package/{scripts/lib → sdk/primitives}/error-classifier.d.cts +0 -0
- /package/{scripts/lib → sdk/primitives}/iteration-budget.d.cts +0 -0
- /package/{scripts/lib → sdk/primitives}/jittered-backoff.d.cts +0 -0
- /package/{scripts/lib → sdk/primitives}/lockfile.d.cts +0 -0
package/sdk/cli/index.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// sdk/cli/index.ts — Plan 21-09 Task 7 (SDK-21).
|
|
2
|
+
//
|
|
3
|
+
// Main dispatcher for the `gdd-sdk` CLI. Invoked by `bin/gdd-sdk` (the
|
|
4
|
+
// CJS trampoline) with `--experimental-strip-types` so TS runs without
|
|
5
|
+
// a build step.
|
|
6
|
+
//
|
|
7
|
+
// Responsibilities:
|
|
8
|
+
// * Parse argv via parseArgs().
|
|
9
|
+
// * Route by first positional to the matching subcommand module.
|
|
10
|
+
// * Print top-level USAGE on bare `gdd-sdk` / `-h` / `--help`.
|
|
11
|
+
// * Exit with the subcommand's return code. Unknown subcommands
|
|
12
|
+
// exit 3 and print USAGE to stderr.
|
|
13
|
+
//
|
|
14
|
+
// The bottom of this file has the `main()` bootstrap that the trampoline
|
|
15
|
+
// invokes. It catches any accidental throw (subcommands are contracted
|
|
16
|
+
// not to throw) and translates to exit code 3.
|
|
17
|
+
|
|
18
|
+
import { parseArgs, type ParsedArgs } from './parse-args.ts';
|
|
19
|
+
import { runCommand } from './commands/run.ts';
|
|
20
|
+
import { stageCommand } from './commands/stage.ts';
|
|
21
|
+
import { queryCommand } from './commands/query.ts';
|
|
22
|
+
import { auditCommand } from './commands/audit.ts';
|
|
23
|
+
import { initCommand } from './commands/init.ts';
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Top-level USAGE.
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
export const USAGE = `gdd-sdk <command> [flags]
|
|
30
|
+
|
|
31
|
+
Commands:
|
|
32
|
+
run Run the full design pipeline headlessly.
|
|
33
|
+
stage <name> Run a single stage (brief|explore|plan|design|verify|discuss).
|
|
34
|
+
query <op> Typed STATE.md read operations.
|
|
35
|
+
audit Probe connections + dry-run verify.
|
|
36
|
+
init Bootstrap a new project.
|
|
37
|
+
|
|
38
|
+
Use 'gdd-sdk <command> -h' for command-specific flags.
|
|
39
|
+
|
|
40
|
+
Exit codes (general):
|
|
41
|
+
0 success
|
|
42
|
+
1 halted / regression / already-initialized
|
|
43
|
+
2 awaiting-gate / partial (init)
|
|
44
|
+
3 argument / config error
|
|
45
|
+
`;
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Deps.
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
export interface DispatcherDeps {
|
|
52
|
+
readonly stdout?: NodeJS.WritableStream;
|
|
53
|
+
readonly stderr?: NodeJS.WritableStream;
|
|
54
|
+
readonly commands?: {
|
|
55
|
+
readonly run?: typeof runCommand;
|
|
56
|
+
readonly stage?: typeof stageCommand;
|
|
57
|
+
readonly query?: typeof queryCommand;
|
|
58
|
+
readonly audit?: typeof auditCommand;
|
|
59
|
+
readonly init?: typeof initCommand;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Dispatcher.
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Dispatch a parsed ParsedArgs to the appropriate subcommand. Exported
|
|
69
|
+
* for tests (they can construct a ParsedArgs manually and assert the
|
|
70
|
+
* exit code + captured stdout/stderr).
|
|
71
|
+
*/
|
|
72
|
+
export async function dispatch(
|
|
73
|
+
parsed: ParsedArgs,
|
|
74
|
+
deps: DispatcherDeps = {},
|
|
75
|
+
): Promise<number> {
|
|
76
|
+
const stdout = deps.stdout ?? process.stdout;
|
|
77
|
+
const stderr = deps.stderr ?? process.stderr;
|
|
78
|
+
const commands = {
|
|
79
|
+
run: deps.commands?.run ?? runCommand,
|
|
80
|
+
stage: deps.commands?.stage ?? stageCommand,
|
|
81
|
+
query: deps.commands?.query ?? queryCommand,
|
|
82
|
+
audit: deps.commands?.audit ?? auditCommand,
|
|
83
|
+
init: deps.commands?.init ?? initCommand,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Bare invocation or top-level help → USAGE.
|
|
87
|
+
if (parsed.subcommand === null) {
|
|
88
|
+
stdout.write(USAGE);
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
if (
|
|
92
|
+
(parsed.flags['help'] === true || parsed.flags['h'] === true) &&
|
|
93
|
+
// Top-level --help (no subcommand recognized yet; --help before the
|
|
94
|
+
// first positional lands here). Subcommands also honor --help
|
|
95
|
+
// themselves, so this branch only fires for `gdd-sdk --help`.
|
|
96
|
+
parsed.positionals.length === 0 &&
|
|
97
|
+
!KNOWN_SUBCOMMANDS.has(parsed.subcommand)
|
|
98
|
+
) {
|
|
99
|
+
stdout.write(USAGE);
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
switch (parsed.subcommand) {
|
|
104
|
+
case 'run':
|
|
105
|
+
return await commands.run(parsed, { stdout, stderr });
|
|
106
|
+
case 'stage':
|
|
107
|
+
return await commands.stage(parsed, { stdout, stderr });
|
|
108
|
+
case 'query':
|
|
109
|
+
return await commands.query(parsed, { stdout, stderr });
|
|
110
|
+
case 'audit':
|
|
111
|
+
return await commands.audit(parsed, { stdout, stderr });
|
|
112
|
+
case 'init':
|
|
113
|
+
return await commands.init(parsed, { stdout, stderr });
|
|
114
|
+
default:
|
|
115
|
+
stderr.write(
|
|
116
|
+
`gdd-sdk: unknown subcommand "${parsed.subcommand}"\n${USAGE}`,
|
|
117
|
+
);
|
|
118
|
+
return 3;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const KNOWN_SUBCOMMANDS: ReadonlySet<string> = new Set([
|
|
123
|
+
'run',
|
|
124
|
+
'stage',
|
|
125
|
+
'query',
|
|
126
|
+
'audit',
|
|
127
|
+
'init',
|
|
128
|
+
]);
|
|
129
|
+
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Bootstrap entry point — called by bin/gdd-sdk trampoline.
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Top-level main. Parses process.argv.slice(2), dispatches, prints
|
|
136
|
+
* USAGE + exit 3 on any uncaught error. Exported so tests can invoke
|
|
137
|
+
* it directly (bypassing the trampoline).
|
|
138
|
+
*/
|
|
139
|
+
export async function main(
|
|
140
|
+
argv: readonly string[] = process.argv.slice(2),
|
|
141
|
+
deps: DispatcherDeps = {},
|
|
142
|
+
): Promise<number> {
|
|
143
|
+
const parsed = parseArgs(argv);
|
|
144
|
+
return await dispatch(parsed, deps);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// When executed directly by the trampoline, invoke main() + exit.
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
// Only self-invoke when this module IS the entry point. We detect that
|
|
152
|
+
// by checking process.argv[1] (trampoline passes this file's path).
|
|
153
|
+
//
|
|
154
|
+
// `import.meta.url` is the POSIX idiom but this TS runs under --experimental-strip-types
|
|
155
|
+
// as Node16 modules — we use process.argv to stay ESM/CJS-agnostic.
|
|
156
|
+
//
|
|
157
|
+
// Extension-agnostic match (.ts | .js | .cjs): the dual-mode bin trampoline
|
|
158
|
+
// (Plan 31-5-9.5, D-16) runs the raw `.ts` in-repo via --experimental-strip-types
|
|
159
|
+
// AND the esbuild-bundled `.js` from a packed/installed tarball. argv[1] ends in
|
|
160
|
+
// `.js` in the compiled path, so a `.ts`-only check would silently skip main().
|
|
161
|
+
|
|
162
|
+
const entryPath: string = (process.argv[1] ?? '').replace(/\\/g, '/');
|
|
163
|
+
if (/\/sdk\/cli\/index\.(ts|js|cjs|mjs)$/.test(entryPath)) {
|
|
164
|
+
main().then(
|
|
165
|
+
(code) => process.exit(code),
|
|
166
|
+
(err) => {
|
|
167
|
+
// eslint-disable-next-line no-console
|
|
168
|
+
console.error('gdd-sdk: unexpected error:', err);
|
|
169
|
+
process.exit(3);
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// sdk/cli/parse-args.ts — Plan 21-09 Task 1 (SDK-21).
|
|
2
2
|
//
|
|
3
3
|
// Hand-rolled argv parser used by the `gdd-sdk` CLI. No external
|
|
4
4
|
// dependency (no yargs / commander / minimist). Supports the exact
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// (e.g., non-numeric input for a numeric flag). Callers ideally catch
|
|
22
22
|
// and route to exit code 3.
|
|
23
23
|
|
|
24
|
-
import { ValidationError } from '../
|
|
24
|
+
import { ValidationError } from '../errors/index.ts';
|
|
25
25
|
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
// Public types.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
// sdk/errors/index.ts — unified GDD error taxonomy.
|
|
2
|
+
//
|
|
3
|
+
// Three classes exactly — mirrors the GSD errors.ts discipline:
|
|
4
|
+
//
|
|
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
|
|
11
|
+
//
|
|
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
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
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
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// sdk/event-stream/index.ts — public API for the Phase 20+
|
|
2
|
+
// telemetry stream (Plan 20-06, SDK-08).
|
|
3
|
+
//
|
|
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).
|
|
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);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Convenience: subscribe to every event on the default bus. */
|
|
195
|
+
export function subscribeAll(handler: EventHandler<BaseEvent>): Unsubscribe {
|
|
196
|
+
return getBus().subscribeAll(handler);
|
|
197
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// sdk/event-stream/types.ts — typed event envelope + pre-registered
|
|
2
2
|
// event shapes, per Plan 20-06 (SDK-08).
|
|
3
3
|
//
|
|
4
4
|
// The event stream is the Phase 20+ observability primitive that every
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
// Plan 20-04 owns the error taxonomy that feeds `ErrorEvent.payload`:
|
|
25
25
|
// `{ code, message, kind }` mirrors `toToolError(err)` output.
|
|
26
26
|
|
|
27
|
-
import type { Stage } from '../
|
|
27
|
+
import type { Stage } from '../state/types.ts';
|
|
28
28
|
|
|
29
29
|
/** Writer-injected metadata. Never populated by callers. */
|
|
30
30
|
export interface EventMeta {
|
package/sdk/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// sdk/index.ts — public SDK barrel (SC#15, D-04).
|
|
2
|
+
//
|
|
3
|
+
// Storybloq-style two-line-per-module re-export of the public SDK surface.
|
|
4
|
+
// The documented import contract (sdk/README.md, D-04) prefers EXPLICIT
|
|
5
|
+
// per-module paths (`@hegemonart/get-design-done/sdk/state`, `/sdk/cli`, …);
|
|
6
|
+
// this barrel exists for callers who want a single entry point.
|
|
7
|
+
//
|
|
8
|
+
// NOTE: `state` re-exports the three taxonomy error classes
|
|
9
|
+
// (TransitionGateFailed, LockAcquisitionError, ParseError) verbatim from
|
|
10
|
+
// `errors`, so the overlapping names resolve to a single shared binding —
|
|
11
|
+
// `export *` keeps them (no ambiguity, since both paths point at the same
|
|
12
|
+
// identity). The full public surface (read/mutate/transition, appendEvent/
|
|
13
|
+
// getWriter/…, the GDDError taxonomy, the CLI dispatch/main/USAGE) is
|
|
14
|
+
// reachable through this barrel and through the explicit per-module paths.
|
|
15
|
+
|
|
16
|
+
export * from './state/index.ts';
|
|
17
|
+
export * from './event-stream/index.ts';
|
|
18
|
+
export * from './errors/index.ts';
|
|
19
|
+
export * from './cli/index.ts';
|