@hegemonart/get-design-done 1.31.0 → 1.31.5
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 +44 -0
- package/NOTICE +224 -0
- package/README.md +1 -1
- 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/package.json +20 -9
- package/recipes/.gitkeep +0 -0
- 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/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 +1924 -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/quality-gate/SKILL.md +2 -2
- 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
|
@@ -1,218 +1,29 @@
|
|
|
1
|
-
// scripts/lib/gdd-errors/index.ts —
|
|
1
|
+
// scripts/lib/gdd-errors/index.ts — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
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
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
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
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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 —
|
|
1
|
+
// scripts/lib/gdd-state/index.ts — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
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
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// (
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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';
|
|
@@ -1,205 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
// Plan 20-14 — bounded fix-loop iteration budget.
|
|
1
|
+
'use strict';
|
|
2
|
+
// scripts/lib/iteration-budget.cjs — GDD-DEPRECATION-SHIM (Plan 31-5-06, SDK-05, D-02).
|
|
4
3
|
//
|
|
5
|
-
//
|
|
6
|
-
// iteration
|
|
7
|
-
//
|
|
8
|
-
//
|
|
4
|
+
// Thin deprecation shim. The real implementation moved to
|
|
5
|
+
// sdk/primitives/iteration-budget.cjs in Plan 31-5-04 (SDK consolidation).
|
|
6
|
+
// This file is re-created at the OLD path so undocumented EXTERNAL importers
|
|
7
|
+
// (anyone who reached into node_modules/@hegemonart/get-design-done/scripts/
|
|
8
|
+
// lib/iteration-budget.cjs directly) keep working for one minor grace window.
|
|
9
9
|
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
10
|
+
// REMOVED IN v1.33.0 (D-02). Grace window: 1.31.5 ships with shims →
|
|
11
|
+
// 1.32.0 still has them → 1.33.0 removes them. Internal callers already use
|
|
12
|
+
// the sdk/ path (Plan 31-5-04/05) — this shim is external-only and 31-5-10's
|
|
13
|
+
// no-stale-internal-refs guard excludes files carrying the GDD-DEPRECATION-SHIM
|
|
14
|
+
// marker above.
|
|
15
15
|
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
|
|
19
|
-
'use strict';
|
|
20
|
-
|
|
21
|
-
const fs = require('node:fs');
|
|
22
|
-
const path = require('node:path');
|
|
23
|
-
|
|
24
|
-
const { acquire, renameWithRetry } = require('./lockfile.cjs');
|
|
25
|
-
|
|
26
|
-
const STATE_PATH_REL = path.join('.design', 'iteration-budget.json');
|
|
27
|
-
const DEFAULT_BUDGET = 50;
|
|
28
|
-
const LOCK_MAX_WAIT_MS = 5_000;
|
|
29
|
-
|
|
30
|
-
/** Error thrown by `consume()` when the remaining budget would go below 0. */
|
|
31
|
-
class IterationBudgetExhaustedError extends Error {
|
|
32
|
-
constructor(amount, state) {
|
|
33
|
-
super(
|
|
34
|
-
`IterationBudgetExhausted: cannot consume ${amount} — remaining=${state.remaining}, budget=${state.budget}, consumed=${state.consumed}. Caller must surface to user (fix-loop has stopped converging).`,
|
|
35
|
-
);
|
|
36
|
-
this.name = 'IterationBudgetExhaustedError';
|
|
37
|
-
this.amount = amount;
|
|
38
|
-
this.state = state;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function stateAbsPath() {
|
|
43
|
-
return path.join(process.cwd(), STATE_PATH_REL);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Read and validate the state file. Returns null on missing/corrupt. */
|
|
47
|
-
function readStateSync() {
|
|
48
|
-
const p = stateAbsPath();
|
|
49
|
-
if (!fs.existsSync(p)) return null;
|
|
50
|
-
try {
|
|
51
|
-
const raw = fs.readFileSync(p, 'utf8');
|
|
52
|
-
const parsed = JSON.parse(raw);
|
|
53
|
-
if (
|
|
54
|
-
parsed &&
|
|
55
|
-
typeof parsed === 'object' &&
|
|
56
|
-
Number.isInteger(parsed.budget) && parsed.budget >= 0 &&
|
|
57
|
-
Number.isInteger(parsed.remaining) && parsed.remaining >= 0 &&
|
|
58
|
-
Number.isInteger(parsed.consumed) && parsed.consumed >= 0 &&
|
|
59
|
-
Number.isInteger(parsed.refunded) && parsed.refunded >= 0 &&
|
|
60
|
-
typeof parsed.updatedAt === 'string'
|
|
61
|
-
) {
|
|
62
|
-
return parsed;
|
|
63
|
-
}
|
|
64
|
-
return null;
|
|
65
|
-
} catch {
|
|
66
|
-
return null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** Atomically write state under a file-lock. */
|
|
71
|
-
async function writeStateAtomic(state) {
|
|
72
|
-
const p = stateAbsPath();
|
|
73
|
-
const dir = path.dirname(p);
|
|
74
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
75
|
-
const release = await acquire(p, { maxWaitMs: LOCK_MAX_WAIT_MS });
|
|
76
|
-
try {
|
|
77
|
-
// Re-read inside the lock so we merge against the very latest
|
|
78
|
-
// on-disk state, not the value the caller observed pre-lock. This
|
|
79
|
-
// is what makes concurrent consume() from 10 children add up to
|
|
80
|
-
// consumed=10 rather than racing each other.
|
|
81
|
-
const latest = readStateSync();
|
|
82
|
-
const merged = state.mergeFn ? state.mergeFn(latest || state.seed) : state.seed;
|
|
83
|
-
const tmp = `${p}.tmp.${process.pid}.${Date.now()}`;
|
|
84
|
-
fs.writeFileSync(tmp, JSON.stringify(merged, null, 2) + '\n', 'utf8');
|
|
85
|
-
await renameWithRetry(tmp, p);
|
|
86
|
-
return merged;
|
|
87
|
-
} finally {
|
|
88
|
-
await release();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Initialize or restart the iteration budget.
|
|
94
|
-
*
|
|
95
|
-
* @param {number} [budget] default 50
|
|
96
|
-
* @returns {Promise<{budget, remaining, consumed, refunded, updatedAt}>}
|
|
97
|
-
*/
|
|
98
|
-
async function reset(budget = DEFAULT_BUDGET) {
|
|
99
|
-
if (!Number.isFinite(budget) || budget < 0) {
|
|
100
|
-
throw new Error(`iteration-budget.reset: budget must be a non-negative finite number, got ${budget}`);
|
|
101
|
-
}
|
|
102
|
-
const b = Math.floor(budget);
|
|
103
|
-
const state = {
|
|
104
|
-
budget: b,
|
|
105
|
-
remaining: b,
|
|
106
|
-
consumed: 0,
|
|
107
|
-
refunded: 0,
|
|
108
|
-
updatedAt: new Date().toISOString(),
|
|
109
|
-
};
|
|
110
|
-
return writeStateAtomic({ seed: state, mergeFn: () => state });
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Consume N units from the remaining budget. Throws
|
|
115
|
-
* IterationBudgetExhaustedError when N would send remaining below zero.
|
|
116
|
-
*
|
|
117
|
-
* @param {number} [amount] default 1
|
|
118
|
-
* @returns {Promise<{budget, remaining, consumed, refunded, updatedAt}>}
|
|
119
|
-
* the new on-disk state after consumption.
|
|
120
|
-
*/
|
|
121
|
-
async function consume(amount = 1) {
|
|
122
|
-
const n = normalizeAmount(amount);
|
|
123
|
-
// Seed for the case when no state exists yet: auto-init to default budget.
|
|
124
|
-
const seed = defaultState();
|
|
125
|
-
return writeStateAtomic({
|
|
126
|
-
seed,
|
|
127
|
-
mergeFn: (current) => {
|
|
128
|
-
const base = current || seed;
|
|
129
|
-
const nextRemaining = base.remaining - n;
|
|
130
|
-
if (nextRemaining < 0) {
|
|
131
|
-
// Throw without writing — atomic: either consume fully or not at all.
|
|
132
|
-
throw new IterationBudgetExhaustedError(n, base);
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
budget: base.budget,
|
|
136
|
-
remaining: nextRemaining,
|
|
137
|
-
consumed: base.consumed + n,
|
|
138
|
-
refunded: base.refunded,
|
|
139
|
-
updatedAt: new Date().toISOString(),
|
|
140
|
-
};
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Refund N units to the remaining budget, capped at `budget`.
|
|
147
|
-
*
|
|
148
|
-
* @param {number} [amount] default 1
|
|
149
|
-
* @returns {Promise<{budget, remaining, consumed, refunded, updatedAt}>}
|
|
150
|
-
*/
|
|
151
|
-
async function refund(amount = 1) {
|
|
152
|
-
const n = normalizeAmount(amount);
|
|
153
|
-
const seed = defaultState();
|
|
154
|
-
return writeStateAtomic({
|
|
155
|
-
seed,
|
|
156
|
-
mergeFn: (current) => {
|
|
157
|
-
const base = current || seed;
|
|
158
|
-
const nextRemaining = Math.min(base.budget, base.remaining + n);
|
|
159
|
-
// Only count the portion that actually landed — if we were already
|
|
160
|
-
// at budget, the refund is a no-op.
|
|
161
|
-
const actuallyRefunded = nextRemaining - base.remaining;
|
|
162
|
-
return {
|
|
163
|
-
budget: base.budget,
|
|
164
|
-
remaining: nextRemaining,
|
|
165
|
-
consumed: base.consumed,
|
|
166
|
-
refunded: base.refunded + actuallyRefunded,
|
|
167
|
-
updatedAt: new Date().toISOString(),
|
|
168
|
-
};
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Return the current on-disk state. Reads without the lock — callers
|
|
175
|
-
* using this for UI display only see a best-effort snapshot; mutating
|
|
176
|
-
* paths (consume/refund) always re-read inside the lock.
|
|
177
|
-
*/
|
|
178
|
-
function remaining() {
|
|
179
|
-
return readStateSync() || defaultState();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
function normalizeAmount(amount) {
|
|
183
|
-
if (!Number.isFinite(amount) || amount <= 0) {
|
|
184
|
-
throw new Error(`iteration-budget: amount must be a positive finite number, got ${amount}`);
|
|
185
|
-
}
|
|
186
|
-
return Math.floor(amount);
|
|
187
|
-
}
|
|
16
|
+
// Emits a DeprecationWarning exactly ONCE per process: the module-level
|
|
17
|
+
// `warned` flag plus Node's module cache (this file is evaluated once per
|
|
18
|
+
// process regardless of how many times it is required).
|
|
188
19
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
};
|
|
20
|
+
let warned = false;
|
|
21
|
+
if (!warned) {
|
|
22
|
+
warned = true;
|
|
23
|
+
process.emitWarning(
|
|
24
|
+
'scripts/lib/iteration-budget.cjs is deprecated; import sdk/primitives/iteration-budget instead. Removed in v1.33.0.',
|
|
25
|
+
'DeprecationWarning',
|
|
26
|
+
);
|
|
197
27
|
}
|
|
198
28
|
|
|
199
|
-
module.exports =
|
|
200
|
-
consume,
|
|
201
|
-
refund,
|
|
202
|
-
remaining,
|
|
203
|
-
reset,
|
|
204
|
-
IterationBudgetExhaustedError,
|
|
205
|
-
};
|
|
29
|
+
module.exports = require('../../sdk/primitives/iteration-budget.cjs');
|