@wrongstack/sdd 1.0.33 → 1.0.36

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.
@@ -0,0 +1,39 @@
1
+ import type { DefaultMultiAgentCoordinator } from '@wrongstack/core/coordination';
2
+ import type { WorktreeHandle } from '@wrongstack/core/worktree';
3
+ import type { SddParallelRunOptions, SddSubtaskSpec } from './sdd-parallel-run-types.js';
4
+ export interface SddParallelControlsHost {
5
+ isRunning(): boolean;
6
+ opts: SddParallelRunOptions;
7
+ taskWorktrees: Map<string, WorktreeHandle>;
8
+ forgetWorktree(taskId: string, opts?: {
9
+ keepBranchLabel?: boolean;
10
+ }): void;
11
+ baseBranch: string | undefined;
12
+ mergedCommits: Array<{
13
+ taskId: string;
14
+ sha: string;
15
+ title: string;
16
+ }>;
17
+ retryMap: Map<string, number>;
18
+ persistRetries(taskId: string, retries: number): void;
19
+ cancelledTasks: Set<string>;
20
+ emit<K extends keyof import('@wrongstack/core/kernel').EventMap>(event: K, payload: import('@wrongstack/core/kernel').EventMap[K]): void;
21
+ runId: string;
22
+ taskSubagents: Map<string, string>;
23
+ coordinator: DefaultMultiAgentCoordinator | null;
24
+ }
25
+ export declare function cleanupWorktrees(host: SddParallelControlsHost): Promise<number>;
26
+ export declare function rollback(host: SddParallelControlsHost): Promise<{
27
+ ok: boolean;
28
+ reverted: number;
29
+ reason?: string;
30
+ }>;
31
+ export declare function retryTask(host: SddParallelControlsHost, taskId: string): boolean;
32
+ export declare function reassignTask(host: SddParallelControlsHost, taskId: string, agentName: string): boolean;
33
+ export declare function setTaskModel(host: SddParallelControlsHost, taskId: string, model: string | undefined, provider?: string | undefined): boolean;
34
+ export declare function setTaskFallbacks(host: SddParallelControlsHost, taskId: string, fallbackModels: string[] | undefined): boolean;
35
+ export declare function setTaskVerification(host: SddParallelControlsHost, taskId: string, verificationCommand: string | undefined): boolean;
36
+ export declare function cancelTask(host: SddParallelControlsHost, taskId: string): Promise<boolean>;
37
+ export declare function deleteTask(host: SddParallelControlsHost, taskId: string): boolean;
38
+ export declare function splitTask(host: SddParallelControlsHost, taskId: string, subtasks: SddSubtaskSpec[]): string[];
39
+ //# sourceMappingURL=sdd-parallel-controls.d.ts.map
@@ -0,0 +1,196 @@
1
+ import type { AgentFactory } from '@wrongstack/core/coordination';
2
+ import { DefaultMultiAgentCoordinator } from '@wrongstack/core/coordination';
3
+ import type { EventBus } from '@wrongstack/core/kernel';
4
+ import type { TaskNode, TaskResult } from '@wrongstack/core/types';
5
+ import type { WorktreeHandle } from '@wrongstack/core/worktree';
6
+ import type { SddParallelControlsHost } from './sdd-parallel-controls.js';
7
+ import type { SddParallelRunOptions, SddProgress, SddSubtaskSpec, TaskOutcome } from './sdd-parallel-run-types.js';
8
+ import { SddTaskDecomposer } from './sdd-task-decomposer.js';
9
+ import { type SddTaskDispatchHost } from './sdd-task-dispatch.js';
10
+ import { type SddTaskRecoveryHost } from './sdd-task-recovery.js';
11
+ /**
12
+ * Run state and internal machinery behind `SddParallelRun`: limits and
13
+ * per-task bookkeeping, event emission, pause parking, recovery/requeue
14
+ * delegates, coordinator construction, failure handling, worktree
15
+ * integration and the host views the `sdd-task-*` / `sdd-parallel-controls`
16
+ * modules take. `SddParallelRun` (sdd-parallel-run.ts) extends this with the
17
+ * public control API and the scheduler loop; the members the host views need
18
+ * from it are declared abstract here.
19
+ */
20
+ export declare abstract class SddParallelRunState {
21
+ protected readonly opts: SddParallelRunOptions;
22
+ protected readonly slots: number;
23
+ /** Opt-in hard wall-clock cap (undefined → no cap; idle reaper guards instead). */
24
+ protected readonly timeoutMs: number | undefined;
25
+ /** Idle reaper window (ms) — resets on activity; reaps only a genuine stall. */
26
+ protected readonly idleTimeoutMs: number;
27
+ protected readonly maxRetries: number;
28
+ /** Max supervisor rescues per task before it must terminal-fail (loop guard). */
29
+ protected readonly maxSupervisorEscalations: number;
30
+ /** Per-task count of supervisor rescues used (resets nothing — bounds the loop). */
31
+ protected supervisorEscalations: Map<string, number>;
32
+ /** Max end-of-run failed-task sweeps (see `maxFailedRetrySweeps`). */
33
+ protected readonly maxFailedSweeps: number;
34
+ /** How many failed-task sweeps have run this `run()` so far. */
35
+ protected failedSweeps: number;
36
+ /** Completed-count snapshot at the last sweep, to detect a no-progress sweep. */
37
+ protected lastSweepCompleted: number;
38
+ protected decomposer: SddTaskDecomposer;
39
+ protected coordinator: DefaultMultiAgentCoordinator | null;
40
+ protected stopRequested: boolean;
41
+ protected retryMap: Map<string, number>;
42
+ readonly runId: string;
43
+ protected readonly events?: EventBus | undefined;
44
+ protected readonly sessionIdSource: string | (() => string | undefined) | undefined;
45
+ protected readonly maxTotalWaves: number;
46
+ protected readonly maxWallClockMs?: number | undefined;
47
+ protected readonly maxRecoveryRounds: number;
48
+ protected recoveryRounds: number;
49
+ /** Per-run worker identities, so the board shows "who is on what". */
50
+ protected usedNicknames: Set<string>;
51
+ /** Per-task git worktree cwd (Layer 2 worktree isolation; empty otherwise). */
52
+ protected taskCwds: Map<string, string>;
53
+ /** Per-task git worktree branch, for board display. */
54
+ protected taskBranches: Map<string, string>;
55
+ /** Live worktree handles keyed by task id (for commit/merge/release). */
56
+ protected taskWorktrees: Map<string, WorktreeHandle>;
57
+ /** Live subagent id per running task — lets cancelTask() abort exactly one. */
58
+ protected taskSubagents: Map<string, string>;
59
+ /** Tasks the user cancelled mid-flight — skip retry, mark terminal-cancelled. */
60
+ protected cancelledTasks: Set<string>;
61
+ /**
62
+ * Base branch the run's squash commits land on (captured once at start when
63
+ * worktrees are enabled). Anchors a later `rollback()`.
64
+ */
65
+ protected baseBranch: string | undefined;
66
+ /**
67
+ * Squash-merge commits this run landed on the base branch, in landing order.
68
+ * `rollback()` reverts these (newest → oldest). Persisted via the board
69
+ * snapshot so a post-run rollback can read them off disk.
70
+ */
71
+ protected mergedCommits: Array<{
72
+ taskId: string;
73
+ sha: string;
74
+ title: string;
75
+ }>;
76
+ /**
77
+ * Fatal, non-recoverable run error — set together with `stopRequested` when
78
+ * the run hard-stops (e.g. a known-invalid merge that could not be rolled
79
+ * back). Surfaced on `run()`'s result so the caller can see WHY it stopped.
80
+ */
81
+ protected fatalError: string | undefined;
82
+ /** Monotonic dispatch counter (unique subagent ids) + dispatch-round counter. */
83
+ protected dispatchSeq: number;
84
+ protected round: number;
85
+ /**
86
+ * True once `run()` has returned. A FINISHED run is not "running" even when
87
+ * the graph is left unsettled (deadlock exit): `isRunning()` gates
88
+ * `cleanupWorktrees()` / `rollback()` / the Ctrl+C ladders, and a returned
89
+ * run kept reporting live, silently no-oping cleanup and refusing rollback
90
+ * with "run still active" until the user called `stop()` on a run that had
91
+ * already ended. Cleared again at the top of `run()` so a re-run re-arms.
92
+ */
93
+ protected runReturned: boolean;
94
+ constructor(opts: SddParallelRunOptions);
95
+ /** Type-safe emit on the optional EventBus (no-op when unwired). */
96
+ protected emit<K extends keyof import('@wrongstack/core/kernel').EventMap>(event: K, payload: import('@wrongstack/core/kernel').EventMap[K]): void;
97
+ protected currentSessionId(): string;
98
+ protected paused: boolean;
99
+ /** Resolvers for tasks parked in `waitWhilePaused`, woken on resume/stop. */
100
+ protected pausedWaiters: Set<() => void>;
101
+ protected notifyPausedWaiters(): void;
102
+ protected waitWhilePaused(): Promise<void>;
103
+ /**
104
+ * Compute the blocking chains for a deadlock: every still-incomplete task and
105
+ * the blockers (by node id) that are NOT completed. Failed blockers are
106
+ * included since they're the usual deadlock cause once retries are exhausted.
107
+ */
108
+ protected computeDeadlockChains(): Array<{
109
+ blocked: string;
110
+ blockedBy: string[];
111
+ }>;
112
+ /** Requeue failed tasks that block an incomplete dependent. Returns true if any. */
113
+ protected recoverFailedBlockers(): boolean;
114
+ /**
115
+ * Requeue every terminal-failed task that the user did NOT cancel, giving each
116
+ * a fresh `maxRetries` budget. Shared by the automatic end-of-run sweep and
117
+ * the manual "retry all failed" control. Returns the number requeued.
118
+ */
119
+ protected requeueFailedTasks(reason?: string): number;
120
+ /** Restore per-task retry counts persisted in node metadata (resume support). */
121
+ protected restoreRetryMap(): void;
122
+ /** Clean teardown after a stop: reset interrupted tasks + release worktrees. */
123
+ protected teardown(): Promise<void>;
124
+ /**
125
+ * Hard-stop the run after an unrecoverable error: the base branch is in a
126
+ * state no retry can fix (e.g. a known-invalid merge that could not be rolled
127
+ * back), so continuing would contaminate every task forked after this point.
128
+ * The reason is surfaced on `run()`'s result and the `sdd.run.finished` event.
129
+ */
130
+ protected abortRun(reason: string): void;
131
+ protected buildCoordinator(): void;
132
+ protected defaultFactory(): AgentFactory;
133
+ /**
134
+ * Apply a task failure: retry (→ pending, bump retry count) while attempts
135
+ * remain, else consult the optional supervisor (which can rescue via
136
+ * retry/reassign/split), else terminal-fail (→ failed). Shared by the
137
+ * worker-failure, verification-gate, and merge-conflict paths so all three
138
+ * negotiate the same retry budget and emit the same events.
139
+ */
140
+ protected applyTaskFailure(taskId: string, subagentId: string, errMsg: string): Promise<void>;
141
+ /**
142
+ * Consult `superviseFailure` for a task that has exhausted its retries.
143
+ * Applies the verdict (retry / reassign+retry / split) and returns true when
144
+ * the task was rescued (caller must NOT terminal-fail it). Bounded per task by
145
+ * `maxSupervisorEscalations` so an always-"retry" supervisor can't loop forever.
146
+ */
147
+ protected trySupervisorRescue(taskId: string, errMsg: string): Promise<boolean>;
148
+ /**
149
+ * Integrate a verified-successful task's worktree into the base branch.
150
+ * Commits, squash-merges (optionally running `conflictResolver` first), and on
151
+ * success releases the worktree. On an UNRESOLVED conflict it returns
152
+ * `{ok:false}` with the conflicting files so the caller routes the task into
153
+ * the failure path (a retry forks a fresh worktree off the now-advanced base,
154
+ * which usually clears the conflict). No-op `{ok:true}` when worktrees are
155
+ * disabled or none was allocated for this task. Never throws — a merge hiccup
156
+ * degrades to a (retryable) failure rather than wedging the run.
157
+ */
158
+ protected get worktreeState(): {
159
+ taskCwds: Map<string, string>;
160
+ taskBranches: Map<string, string>;
161
+ taskWorktrees: Map<string, WorktreeHandle>;
162
+ mergedCommits: {
163
+ taskId: string;
164
+ sha: string;
165
+ title: string;
166
+ }[];
167
+ };
168
+ protected integrateWorktree(task: TaskNode, result?: TaskResult): Promise<{
169
+ ok: boolean;
170
+ conflictFiles?: string[];
171
+ reason?: string;
172
+ fatal?: boolean;
173
+ }>;
174
+ /** Allocate a fresh git worktree per task in the batch (no-op without a manager). */
175
+ protected allocateWorktrees(tasks: TaskNode[]): Promise<void>;
176
+ /**
177
+ * Resolve each task's worktree after its result is known. Serialized merges
178
+ * (one at a time) keep the base branch consistent; the wave structure already
179
+ * guarantees dependency order (a task's blockers merged in an earlier wave).
180
+ */
181
+ protected resolveWorktrees(tasks: TaskNode[]): Promise<void>;
182
+ protected forgetWorktree(taskId: string, opts?: {
183
+ keepBranchLabel?: boolean;
184
+ }): void;
185
+ /** Persist a task's retry count into node metadata (survives crash → resume). */
186
+ protected persistRetries(taskId: string, retries: number): void;
187
+ protected buildProgress(): SddProgress;
188
+ protected sddTaskRecoveryHost(): SddTaskRecoveryHost;
189
+ protected sddTaskDispatchHost(): SddTaskDispatchHost;
190
+ protected sddParallelControlsHost(): SddParallelControlsHost;
191
+ abstract isRunning(): boolean;
192
+ abstract executeOne(task: TaskNode): Promise<TaskOutcome>;
193
+ abstract setTaskModel(taskId: string, model: string | undefined, provider?: string | undefined): boolean;
194
+ abstract splitTask(taskId: string, subtasks: SddSubtaskSpec[]): string[];
195
+ }
196
+ //# sourceMappingURL=sdd-parallel-run-state.d.ts.map
@@ -1,86 +1,29 @@
1
+ /**
2
+ * SddParallelRun
3
+ *
4
+ * Drives a TaskGraph through ParallelEternalEngine's infrastructure
5
+ * (DefaultMultiAgentCoordinator + AgentSubagentRunner) but powered by
6
+ * SddTaskDecomposer — producing dependency-aware waves instead of
7
+ * goal-driven iterations.
8
+ *
9
+ * One-shot: completes when all tasks are done OR a deadlock is detected.
10
+ * Does NOT loop — each run() call is a discrete execution.
11
+ *
12
+ * Usage:
13
+ * ```
14
+ * const run = new SddParallelRun({ tracker, graph, agent, projectRoot });
15
+ * await run.run({ onWave });
16
+ * // or with progress callback:
17
+ * await run.run({ onProgress: (p) => console.log(renderProgress(p)) });
18
+ * ```
19
+ */
1
20
  import type { TaskTracker } from '@wrongstack/core/tasking';
2
21
  import type { TaskNode } from '@wrongstack/core/types';
3
- import type { RunResult, SddParallelRunOptions, SddSubtaskSpec, TaskOutcome, WaveResult } from './sdd-parallel-run-types.js';
4
- import { type TaskBatch } from './sdd-task-decomposer.js';
22
+ import { SddParallelRunState } from './sdd-parallel-run-state.js';
23
+ import type { RunResult, SddSubtaskSpec, TaskOutcome, WaveResult } from './sdd-parallel-run-types.js';
24
+ import type { TaskBatch } from './sdd-task-decomposer.js';
5
25
  export type { RunResult, SddParallelRunOptions, SddProgress, SddSubtaskSpec, SddSupervisorVerdict, WaveResult, } from './sdd-parallel-run-types.js';
6
- export declare class SddParallelRun {
7
- private readonly opts;
8
- private readonly slots;
9
- /** Opt-in hard wall-clock cap (undefined → no cap; idle reaper guards instead). */
10
- private readonly timeoutMs;
11
- /** Idle reaper window (ms) — resets on activity; reaps only a genuine stall. */
12
- private readonly idleTimeoutMs;
13
- private readonly maxRetries;
14
- /** Max supervisor rescues per task before it must terminal-fail (loop guard). */
15
- private readonly maxSupervisorEscalations;
16
- /** Per-task count of supervisor rescues used (resets nothing — bounds the loop). */
17
- private supervisorEscalations;
18
- /** Max end-of-run failed-task sweeps (see `maxFailedRetrySweeps`). */
19
- private readonly maxFailedSweeps;
20
- /** How many failed-task sweeps have run this `run()` so far. */
21
- private failedSweeps;
22
- /** Completed-count snapshot at the last sweep, to detect a no-progress sweep. */
23
- private lastSweepCompleted;
24
- private decomposer;
25
- private coordinator;
26
- private stopRequested;
27
- private retryMap;
28
- readonly runId: string;
29
- private readonly events?;
30
- private readonly sessionIdSource;
31
- private readonly maxTotalWaves;
32
- private readonly maxWallClockMs?;
33
- private readonly maxRecoveryRounds;
34
- private recoveryRounds;
35
- /** Per-run worker identities, so the board shows "who is on what". */
36
- private usedNicknames;
37
- /** Per-task git worktree cwd (Layer 2 worktree isolation; empty otherwise). */
38
- private taskCwds;
39
- /** Per-task git worktree branch, for board display. */
40
- private taskBranches;
41
- /** Live worktree handles keyed by task id (for commit/merge/release). */
42
- private taskWorktrees;
43
- /** Live subagent id per running task — lets cancelTask() abort exactly one. */
44
- private taskSubagents;
45
- /** Tasks the user cancelled mid-flight — skip retry, mark terminal-cancelled. */
46
- private cancelledTasks;
47
- /**
48
- * Base branch the run's squash commits land on (captured once at start when
49
- * worktrees are enabled). Anchors a later `rollback()`.
50
- */
51
- private baseBranch;
52
- /**
53
- * Squash-merge commits this run landed on the base branch, in landing order.
54
- * `rollback()` reverts these (newest → oldest). Persisted via the board
55
- * snapshot so a post-run rollback can read them off disk.
56
- */
57
- private mergedCommits;
58
- /**
59
- * Fatal, non-recoverable run error — set together with `stopRequested` when
60
- * the run hard-stops (e.g. a known-invalid merge that could not be rolled
61
- * back). Surfaced on `run()`'s result so the caller can see WHY it stopped.
62
- */
63
- private fatalError;
64
- /** Monotonic dispatch counter (unique subagent ids) + dispatch-round counter. */
65
- private dispatchSeq;
66
- private round;
67
- /**
68
- * True once `run()` has returned. A FINISHED run is not "running" even when
69
- * the graph is left unsettled (deadlock exit): `isRunning()` gates
70
- * `cleanupWorktrees()` / `rollback()` / the Ctrl+C ladders, and a returned
71
- * run kept reporting live, silently no-oping cleanup and refusing rollback
72
- * with "run still active" until the user called `stop()` on a run that had
73
- * already ended. Cleared again at the top of `run()` so a re-run re-arms.
74
- */
75
- private runReturned;
76
- constructor(opts: SddParallelRunOptions);
77
- /** Type-safe emit on the optional EventBus (no-op when unwired). */
78
- private emit;
79
- private currentSessionId;
80
- private paused;
81
- /** Resolvers for tasks parked in `waitWhilePaused`, woken on resume/stop. */
82
- private pausedWaiters;
83
- private notifyPausedWaiters;
26
+ export declare class SddParallelRun extends SddParallelRunState {
84
27
  /** Trigger stop — causes run() to abort after the current wave. */
85
28
  stop(): void;
86
29
  /** Pause: no new wave starts until resume() (the current wave finishes). */
@@ -154,7 +97,6 @@ export declare class SddParallelRun {
154
97
  * The scheduler picks the new pending leaves up on its next dispatch pass.
155
98
  */
156
99
  splitTask(taskId: string, subtasks: SddSubtaskSpec[]): string[];
157
- private waitWhilePaused;
158
100
  /**
159
101
  * Continuous dependency-driven execution. Unlike a wave-barrier loop (where a
160
102
  * whole batch must finish before the next starts), this fills free worker
@@ -164,20 +106,6 @@ export declare class SddParallelRun {
164
106
  * the final summary when the graph settles, deadlocks, stops, or hits a backstop.
165
107
  */
166
108
  run(): Promise<RunResult>;
167
- /**
168
- * Compute the blocking chains for a deadlock: every still-incomplete task and
169
- * the blockers (by node id) that are NOT completed. Failed blockers are
170
- * included since they're the usual deadlock cause once retries are exhausted.
171
- */
172
- private computeDeadlockChains;
173
- /** Requeue failed tasks that block an incomplete dependent. Returns true if any. */
174
- private recoverFailedBlockers;
175
- /**
176
- * Requeue every terminal-failed task that the user did NOT cancel, giving each
177
- * a fresh `maxRetries` budget. Shared by the automatic end-of-run sweep and
178
- * the manual "retry all failed" control. Returns the number requeued.
179
- */
180
- private requeueFailedTasks;
181
109
  /**
182
110
  * Manually requeue all failed tasks to `pending` (board "Retry all failed").
183
111
  * Unlike the automatic sweep this also clears any `cancelled` marker, so a
@@ -186,25 +114,12 @@ export declare class SddParallelRun {
186
114
  * Returns the number of tasks requeued.
187
115
  */
188
116
  retryAllFailed(): number;
189
- /** Restore per-task retry counts persisted in node metadata (resume support). */
190
- private restoreRetryMap;
191
117
  /**
192
118
  * Reset orphaned `in_progress` tasks (no agent runs them after a crash) back
193
119
  * to `pending` so a fresh run re-executes them. Call before constructing a run
194
120
  * from a reloaded graph. Static so callers don't need a run instance.
195
121
  */
196
122
  static resetOrphans(tracker: TaskTracker): number;
197
- /** Clean teardown after a stop: reset interrupted tasks + release worktrees. */
198
- private teardown;
199
- /**
200
- * Hard-stop the run after an unrecoverable error: the base branch is in a
201
- * state no retry can fix (e.g. a known-invalid merge that could not be rolled
202
- * back), so continuing would contaminate every task forked after this point.
203
- * The reason is surfaced on `run()`'s result and the `sdd.run.finished` event.
204
- */
205
- private abortRun;
206
- private buildCoordinator;
207
- private defaultFactory;
208
123
  /**
209
124
  * Execute a batch of tasks together. Retained as a thin wrapper over the
210
125
  * single-task primitive `executeOne` so the wave-oriented tests and any
@@ -221,46 +136,5 @@ export declare class SddParallelRun {
221
136
  * missing coordinator or failed spawn so callers can enforce all-or-nothing.
222
137
  */
223
138
  executeOne(task: TaskNode): Promise<TaskOutcome>;
224
- /**
225
- * Apply a task failure: retry (→ pending, bump retry count) while attempts
226
- * remain, else consult the optional supervisor (which can rescue via
227
- * retry/reassign/split), else terminal-fail (→ failed). Shared by the
228
- * worker-failure, verification-gate, and merge-conflict paths so all three
229
- * negotiate the same retry budget and emit the same events.
230
- */
231
- private applyTaskFailure;
232
- /**
233
- * Consult `superviseFailure` for a task that has exhausted its retries.
234
- * Applies the verdict (retry / reassign+retry / split) and returns true when
235
- * the task was rescued (caller must NOT terminal-fail it). Bounded per task by
236
- * `maxSupervisorEscalations` so an always-"retry" supervisor can't loop forever.
237
- */
238
- private trySupervisorRescue;
239
- /**
240
- * Integrate a verified-successful task's worktree into the base branch.
241
- * Commits, squash-merges (optionally running `conflictResolver` first), and on
242
- * success releases the worktree. On an UNRESOLVED conflict it returns
243
- * `{ok:false}` with the conflicting files so the caller routes the task into
244
- * the failure path (a retry forks a fresh worktree off the now-advanced base,
245
- * which usually clears the conflict). No-op `{ok:true}` when worktrees are
246
- * disabled or none was allocated for this task. Never throws — a merge hiccup
247
- * degrades to a (retryable) failure rather than wedging the run.
248
- */
249
- private get worktreeState();
250
- private integrateWorktree;
251
- /** Allocate a fresh git worktree per task in the batch (no-op without a manager). */
252
- private allocateWorktrees;
253
- /**
254
- * Resolve each task's worktree after its result is known. Serialized merges
255
- * (one at a time) keep the base branch consistent; the wave structure already
256
- * guarantees dependency order (a task's blockers merged in an earlier wave).
257
- */
258
- private resolveWorktrees;
259
- private forgetWorktree;
260
- /** Persist a task's retry count into node metadata (survives crash → resume). */
261
- private persistRetries;
262
- private buildProgress;
263
- private sddTaskRecoveryHost;
264
- private sddTaskDispatchHost;
265
139
  }
266
140
  //# sourceMappingURL=sdd-parallel-run.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Parsing of AI output for `AISpecBuilder`: locating a JSON object / array in
3
+ * free text and validating + normalizing a specification object.
4
+ */
5
+ import type { Specification } from '@wrongstack/core/types';
6
+ /**
7
+ * Parse a spec from a JSON string (from AI output). Validates and normalizes
8
+ * the structure; `fallbackTitle` applies when the JSON has none, `sessionId`
9
+ * is recorded in the spec metadata.
10
+ */
11
+ export declare function parseSpecificationJSON(jsonStr: string, fallbackTitle: string, sessionId: string): Specification;
12
+ /** Extract JSON from AI output (handles ```json blocks and raw JSON). */
13
+ export declare function extractJSONFromText(text: string): string | null;
14
+ /** Extract a JSON array from AI output (for task lists). */
15
+ export declare function extractJSONArrayFromText(text: string): string | null;
16
+ //# sourceMappingURL=spec-builder-parsing.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { AISpecSession } from './sdd-session-types.js';
2
+ export declare function buildQuestioningPrompt(session: AISpecSession, min: number, max: number): string;
3
+ export declare function buildSpecReviewPrompt(session: AISpecSession): string;
4
+ export declare function buildImplementationPrompt(session: AISpecSession): string;
5
+ export declare function buildTaskReviewPrompt(session: AISpecSession): string;
6
+ export declare function buildExecutingPrompt(session: AISpecSession): string;
7
+ //# sourceMappingURL=spec-builder-prompts.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Legacy file persistence for `AISpecBuilder` sessions (`sessionPath`), used
3
+ * when no durable `sessionPersistence` owner is configured. Modules load
4
+ * lazily, as before.
5
+ */
6
+ import { type AISpecSession } from './sdd-session-types.js';
7
+ export declare function writeAISpecSessionFile(sessionPath: string, snapshot: AISpecSession): Promise<void>;
8
+ /** The saved session, or undefined when missing, unreadable or invalid. */
9
+ export declare function readAISpecSessionFile(sessionPath: string): Promise<AISpecSession | undefined>;
10
+ export declare function deleteAISpecSessionFile(sessionPath: string): Promise<void>;
11
+ //# sourceMappingURL=spec-builder-session-file.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { TaskStore, TaskTracker } from '@wrongstack/core/tasking';
1
+ import type { TaskTracker } from '@wrongstack/core/tasking';
2
2
  import type { Specification, TaskGraph, TaskNode, TaskPriority, TaskType } from '@wrongstack/core/types';
3
3
  import { type AtomicityRuleSetConfig } from '@wrongstack/kanban';
4
4
  export interface TaskGeneratorOptions {
@@ -64,5 +64,4 @@ export declare class TaskGenerator {
64
64
  private addRequirementTask;
65
65
  generateSubtasks(parentTaskId: string, spec: Specification): Promise<void>;
66
66
  }
67
- export type { TaskStore };
68
67
  //# sourceMappingURL=task-generator.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/sdd",
3
- "version": "1.0.33",
3
+ "version": "1.0.36",
4
4
  "license": "MIT",
5
5
  "description": "WrongStack Spec-Driven Development engine — standalone package extracted from @wrongstack/core. Task graph generation, tracking, execution, lifecycle management, and AI-driven spec building for SDD workflows.",
6
6
  "repository": {
@@ -27,10 +27,10 @@
27
27
  "!dist/**/*.map"
28
28
  ],
29
29
  "dependencies": {
30
- "@wrongstack/core": "1.0.33",
31
- "@wrongstack/kanban": "1.0.33",
32
- "@wrongstack/primitives": "1.0.33",
33
- "@wrongstack/requirement-intake": "1.0.33"
30
+ "@wrongstack/core": "1.0.36",
31
+ "@wrongstack/kanban": "1.0.36",
32
+ "@wrongstack/primitives": "1.0.36",
33
+ "@wrongstack/requirement-intake": "1.0.36"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.5.1",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "scripts": {
43
43
  "build": "node ../../scripts/build-package.mjs",
44
- "typecheck": "tsc --noEmit",
44
+ "typecheck": "node ../../scripts/bun-typecheck.mjs --noEmit",
45
45
  "test": "vitest run",
46
46
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
47
47
  }