@fusionkit/handoff 0.1.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/dist/agents.d.ts +21 -0
- package/dist/agents.js +33 -0
- package/dist/checkpoint-manager.d.ts +14 -0
- package/dist/checkpoint-manager.js +33 -0
- package/dist/defaults.d.ts +18 -0
- package/dist/defaults.js +18 -0
- package/dist/handoff.d.ts +303 -0
- package/dist/handoff.js +593 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +20 -0
- package/dist/isolation.d.ts +12 -0
- package/dist/isolation.js +10 -0
- package/dist/policy.d.ts +69 -0
- package/dist/policy.js +79 -0
- package/dist/review.d.ts +57 -0
- package/dist/review.js +110 -0
- package/dist/run-executor.d.ts +76 -0
- package/dist/run-executor.js +71 -0
- package/dist/run.d.ts +88 -0
- package/dist/run.js +159 -0
- package/dist/targets.d.ts +14 -0
- package/dist/targets.js +20 -0
- package/dist/test/plan.test.d.ts +1 -0
- package/dist/test/plan.test.js +93 -0
- package/dist/test/tools.test.d.ts +1 -0
- package/dist/test/tools.test.js +106 -0
- package/dist/test/triggers.test.d.ts +1 -0
- package/dist/test/triggers.test.js +114 -0
- package/dist/tool-journal.d.ts +13 -0
- package/dist/tool-journal.js +37 -0
- package/dist/tools.d.ts +22 -0
- package/dist/tools.js +99 -0
- package/dist/trace-log.d.ts +6 -0
- package/dist/trace-log.js +9 -0
- package/dist/triggers.d.ts +43 -0
- package/dist/triggers.js +64 -0
- package/package.json +32 -0
package/dist/agents.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AgentSpec } from "@fusionkit/protocol";
|
|
2
|
+
export declare const agents: {
|
|
3
|
+
claudeCode(options?: {
|
|
4
|
+
version?: string;
|
|
5
|
+
}): AgentSpec;
|
|
6
|
+
codex(options?: {
|
|
7
|
+
version?: string;
|
|
8
|
+
}): AgentSpec;
|
|
9
|
+
/**
|
|
10
|
+
* Pi: a host-runtime coding harness driven through the AI SDK harness
|
|
11
|
+
* backend. Runs only on a session tier that registers the pi binding
|
|
12
|
+
* (the swarm's local-model workers); never spawned as a vendor CLI.
|
|
13
|
+
*/
|
|
14
|
+
pi(options?: {
|
|
15
|
+
version?: string;
|
|
16
|
+
}): AgentSpec;
|
|
17
|
+
/** Built-in mock harness: runs without vendor CLIs or API keys. */
|
|
18
|
+
mock(): AgentSpec;
|
|
19
|
+
/** One governed shell command; the task prompt is the command. */
|
|
20
|
+
command(): AgentSpec;
|
|
21
|
+
};
|
package/dist/agents.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed agent constructors, mirroring the AI SDK provider pattern:
|
|
3
|
+
* `agents.claudeCode()` instead of `"claude-code"`. Strings remain
|
|
4
|
+
* acceptable as CLI aliases; the SDK contract is the protocol's
|
|
5
|
+
* `AgentSpec` — there is no separate descriptor shape to convert.
|
|
6
|
+
*/
|
|
7
|
+
function spec(kind, version) {
|
|
8
|
+
return { kind, ...(version ? { version } : {}) };
|
|
9
|
+
}
|
|
10
|
+
export const agents = {
|
|
11
|
+
claudeCode(options = {}) {
|
|
12
|
+
return spec("claude-code", options.version);
|
|
13
|
+
},
|
|
14
|
+
codex(options = {}) {
|
|
15
|
+
return spec("codex", options.version);
|
|
16
|
+
},
|
|
17
|
+
/**
|
|
18
|
+
* Pi: a host-runtime coding harness driven through the AI SDK harness
|
|
19
|
+
* backend. Runs only on a session tier that registers the pi binding
|
|
20
|
+
* (the swarm's local-model workers); never spawned as a vendor CLI.
|
|
21
|
+
*/
|
|
22
|
+
pi(options = {}) {
|
|
23
|
+
return spec("pi", options.version);
|
|
24
|
+
},
|
|
25
|
+
/** Built-in mock harness: runs without vendor CLIs or API keys. */
|
|
26
|
+
mock() {
|
|
27
|
+
return spec("mock");
|
|
28
|
+
},
|
|
29
|
+
/** One governed shell command; the task prompt is the command. */
|
|
30
|
+
command() {
|
|
31
|
+
return spec("command");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Checkpoint } from "@fusionkit/protocol";
|
|
2
|
+
import type { CapturedWorkspace } from "@fusionkit/workspace";
|
|
3
|
+
export declare class HandoffCheckpointManager {
|
|
4
|
+
private readonly history;
|
|
5
|
+
get count(): number;
|
|
6
|
+
snapshot(): Checkpoint[];
|
|
7
|
+
create(input: {
|
|
8
|
+
captured: CapturedWorkspace;
|
|
9
|
+
message?: string;
|
|
10
|
+
transcriptHash?: string;
|
|
11
|
+
toolJournalHash?: string;
|
|
12
|
+
remember?: boolean;
|
|
13
|
+
}): Checkpoint;
|
|
14
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { PROTOCOL_VERSIONS } from "@fusionkit/protocol";
|
|
3
|
+
export class HandoffCheckpointManager {
|
|
4
|
+
history = [];
|
|
5
|
+
get count() {
|
|
6
|
+
return this.history.length;
|
|
7
|
+
}
|
|
8
|
+
snapshot() {
|
|
9
|
+
return [...this.history];
|
|
10
|
+
}
|
|
11
|
+
create(input) {
|
|
12
|
+
const semantic = {
|
|
13
|
+
...(input.transcriptHash ? { transcriptHash: input.transcriptHash } : {}),
|
|
14
|
+
...(input.toolJournalHash ? { toolJournalHash: input.toolJournalHash } : {}),
|
|
15
|
+
...(input.message ? { note: input.message } : {})
|
|
16
|
+
};
|
|
17
|
+
const hasSemantic = input.transcriptHash !== undefined || input.toolJournalHash !== undefined;
|
|
18
|
+
const parent = this.history.at(-1)?.checkpointId;
|
|
19
|
+
const checkpoint = {
|
|
20
|
+
version: PROTOCOL_VERSIONS.checkpoint,
|
|
21
|
+
checkpointId: `chk_${randomUUID()}`,
|
|
22
|
+
createdAt: new Date().toISOString(),
|
|
23
|
+
tier: "workspace",
|
|
24
|
+
...(input.message ? { message: input.message } : {}),
|
|
25
|
+
...(hasSemantic ? { semantic } : {}),
|
|
26
|
+
workspace: input.captured.manifest,
|
|
27
|
+
...(parent ? { parent } : {})
|
|
28
|
+
};
|
|
29
|
+
if (input.remember !== false)
|
|
30
|
+
this.history.push(checkpoint);
|
|
31
|
+
return checkpoint;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared polling and identity defaults used by Handoff.stream and
|
|
3
|
+
* HandoffRun.wait so the two code paths cannot drift apart.
|
|
4
|
+
*
|
|
5
|
+
* The plane API is deliberately poll-based (plain, stateless HTTP): these
|
|
6
|
+
* intervals are the supported transport, and both consumers accept
|
|
7
|
+
* per-call overrides (`pollMs` / `timeoutMs`).
|
|
8
|
+
*/
|
|
9
|
+
/** Interval between status polls. */
|
|
10
|
+
export declare const DEFAULT_POLL_INTERVAL_MS = 300;
|
|
11
|
+
/** Default ceiling for HandoffRun.wait. */
|
|
12
|
+
export declare const DEFAULT_WAIT_TIMEOUT_MS: number;
|
|
13
|
+
/** Default ceiling for Handoff.stream. */
|
|
14
|
+
export declare const DEFAULT_STREAM_TIMEOUT_MS: number;
|
|
15
|
+
/** Actor id recorded when no actor is configured and USER is unset. */
|
|
16
|
+
export declare const DEFAULT_ACTOR_ID = "developer";
|
|
17
|
+
/** Concurrent blob uploads during workspace checkpointing. */
|
|
18
|
+
export declare const BLOB_UPLOAD_CONCURRENCY = 4;
|
package/dist/defaults.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared polling and identity defaults used by Handoff.stream and
|
|
3
|
+
* HandoffRun.wait so the two code paths cannot drift apart.
|
|
4
|
+
*
|
|
5
|
+
* The plane API is deliberately poll-based (plain, stateless HTTP): these
|
|
6
|
+
* intervals are the supported transport, and both consumers accept
|
|
7
|
+
* per-call overrides (`pollMs` / `timeoutMs`).
|
|
8
|
+
*/
|
|
9
|
+
/** Interval between status polls. */
|
|
10
|
+
export const DEFAULT_POLL_INTERVAL_MS = 300;
|
|
11
|
+
/** Default ceiling for HandoffRun.wait. */
|
|
12
|
+
export const DEFAULT_WAIT_TIMEOUT_MS = 5 * 60 * 1000;
|
|
13
|
+
/** Default ceiling for Handoff.stream. */
|
|
14
|
+
export const DEFAULT_STREAM_TIMEOUT_MS = 10 * 60 * 1000;
|
|
15
|
+
/** Actor id recorded when no actor is configured and USER is unset. */
|
|
16
|
+
export const DEFAULT_ACTOR_ID = "developer";
|
|
17
|
+
/** Concurrent blob uploads during workspace checkpointing. */
|
|
18
|
+
export const BLOB_UPLOAD_CONCURRENCY = 4;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import type { ActorRef, AgentSpec, ArtifactKind, BudgetSpec, ChainedEvent, Checkpoint, CheckpointTier, DisclosureReport, ExecutionSpec, HandoffEnvelope, RunStatus, SessionIsolation } from "@fusionkit/protocol";
|
|
2
|
+
import { PlaneClient } from "@fusionkit/sdk";
|
|
3
|
+
import type { PullResult } from "@fusionkit/workspace";
|
|
4
|
+
import type { IsolationStrategy } from "./isolation.js";
|
|
5
|
+
import type { ContinuationPolicy, PlanningDecision } from "./policy.js";
|
|
6
|
+
import type { FiredTrigger } from "./triggers.js";
|
|
7
|
+
import type { ReviewResult, ReviewStrategy } from "./review.js";
|
|
8
|
+
import { HandoffRun } from "./run.js";
|
|
9
|
+
import type { RuntimeTarget } from "./targets.js";
|
|
10
|
+
import type { ToolLike } from "./tools.js";
|
|
11
|
+
export type HandoffConfig = {
|
|
12
|
+
/** Path to the local git workspace this work starts in. */
|
|
13
|
+
workspace: string;
|
|
14
|
+
/** Plane connection: an existing client or url + admin token. */
|
|
15
|
+
plane: PlaneClient | {
|
|
16
|
+
url: string;
|
|
17
|
+
adminToken: string;
|
|
18
|
+
};
|
|
19
|
+
/** Who is asking. Defaults to the OS user. */
|
|
20
|
+
actor?: ActorRef;
|
|
21
|
+
/** Default agent for continuations. Defaults to the mock harness. */
|
|
22
|
+
agent?: AgentSpec;
|
|
23
|
+
/** Client-side continuation policy. Defaults to `localFirst()`. */
|
|
24
|
+
policy?: ContinuationPolicy;
|
|
25
|
+
/** Secret names continuations may request by default. */
|
|
26
|
+
secrets?: string[];
|
|
27
|
+
/** Hosts continuations may reach by default (deny-by-default egress). */
|
|
28
|
+
allowHosts?: string[];
|
|
29
|
+
/** Untracked-file glob allowlist applied at workspace capture. */
|
|
30
|
+
allowUntracked?: string[];
|
|
31
|
+
budget?: BudgetSpec;
|
|
32
|
+
};
|
|
33
|
+
export type ContinueOptions = {
|
|
34
|
+
task: string;
|
|
35
|
+
agent?: AgentSpec;
|
|
36
|
+
/** Durable machine intent. Defaults from the selected agent and task. */
|
|
37
|
+
execution?: ExecutionSpec;
|
|
38
|
+
reason?: string;
|
|
39
|
+
secrets?: string[];
|
|
40
|
+
allowHosts?: string[];
|
|
41
|
+
/** Free-form transcript to carry as semantic state. */
|
|
42
|
+
transcript?: string;
|
|
43
|
+
/** Reuse an existing checkpoint instead of capturing a fresh one. */
|
|
44
|
+
checkpoint?: Checkpoint;
|
|
45
|
+
budget?: BudgetSpec;
|
|
46
|
+
/** How results land at pull time. Defaults to divergence-safe auto. */
|
|
47
|
+
isolate?: IsolationStrategy;
|
|
48
|
+
/** Requested session isolation on the runner. Defaults to "process". */
|
|
49
|
+
session?: SessionIsolation;
|
|
50
|
+
};
|
|
51
|
+
export type ParallelOptions = Omit<ContinueOptions, "task">;
|
|
52
|
+
/**
|
|
53
|
+
* Register provider-style defaults once; subsequent `handoff({...})` calls
|
|
54
|
+
* merge them under their explicit config (explicit values win):
|
|
55
|
+
*
|
|
56
|
+
* defineHandoffConfig({ plane, agent: agents.claudeCode(), policy: localFirst() });
|
|
57
|
+
* const h = handoff({ workspace: "." });
|
|
58
|
+
*/
|
|
59
|
+
export declare function defineHandoffConfig(defaults: Partial<HandoffConfig>): Partial<HandoffConfig>;
|
|
60
|
+
/** Configuration accepted by handoff(): defaults can supply everything but the workspace. */
|
|
61
|
+
export type HandoffInit = Partial<HandoffConfig> & {
|
|
62
|
+
workspace: string;
|
|
63
|
+
};
|
|
64
|
+
export type HandoffTraceEvent = {
|
|
65
|
+
type: "checkpoint.created";
|
|
66
|
+
ts: string;
|
|
67
|
+
checkpointId: string;
|
|
68
|
+
tier: CheckpointTier;
|
|
69
|
+
message?: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: "continuation.planned";
|
|
72
|
+
ts: string;
|
|
73
|
+
decision: PlanningDecision["decision"];
|
|
74
|
+
target: string;
|
|
75
|
+
reasons: string[];
|
|
76
|
+
} | {
|
|
77
|
+
type: "continuation.requested";
|
|
78
|
+
ts: string;
|
|
79
|
+
reason?: string;
|
|
80
|
+
} | {
|
|
81
|
+
type: "envelope.created";
|
|
82
|
+
ts: string;
|
|
83
|
+
envelopeId: string;
|
|
84
|
+
envelopeHash: string;
|
|
85
|
+
target: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: "run.requested";
|
|
88
|
+
ts: string;
|
|
89
|
+
runId: string;
|
|
90
|
+
status: RunStatus;
|
|
91
|
+
task: string;
|
|
92
|
+
} | {
|
|
93
|
+
type: "run.terminal";
|
|
94
|
+
ts: string;
|
|
95
|
+
runId: string;
|
|
96
|
+
status: RunStatus;
|
|
97
|
+
} | {
|
|
98
|
+
type: "results.pulled";
|
|
99
|
+
ts: string;
|
|
100
|
+
runId: string;
|
|
101
|
+
mode: PullResult["mode"];
|
|
102
|
+
} | {
|
|
103
|
+
type: "tool.called";
|
|
104
|
+
ts: string;
|
|
105
|
+
toolName: string;
|
|
106
|
+
inputHash: string;
|
|
107
|
+
outputHash?: string;
|
|
108
|
+
ok: boolean;
|
|
109
|
+
durationMs: number;
|
|
110
|
+
} | {
|
|
111
|
+
type: "model.routed";
|
|
112
|
+
ts: string;
|
|
113
|
+
model: string;
|
|
114
|
+
route: "local" | "cloud";
|
|
115
|
+
escalated: boolean;
|
|
116
|
+
reason: string;
|
|
117
|
+
};
|
|
118
|
+
/** A model routing decision reported by h.model (see withModel). */
|
|
119
|
+
export type ModelDecision = {
|
|
120
|
+
model: string;
|
|
121
|
+
route: "local" | "cloud";
|
|
122
|
+
escalated: boolean;
|
|
123
|
+
reason: string;
|
|
124
|
+
};
|
|
125
|
+
/** Where the work stands: derivable, recomputed, never source of truth. */
|
|
126
|
+
export type HandoffSummary = {
|
|
127
|
+
workspace: string;
|
|
128
|
+
checkpoints: number;
|
|
129
|
+
toolCalls: number;
|
|
130
|
+
continuations: {
|
|
131
|
+
planned: number;
|
|
132
|
+
denied: number;
|
|
133
|
+
requested: number;
|
|
134
|
+
};
|
|
135
|
+
modelRoutes: {
|
|
136
|
+
local: number;
|
|
137
|
+
cloud: number;
|
|
138
|
+
escalations: number;
|
|
139
|
+
};
|
|
140
|
+
runs: {
|
|
141
|
+
runId: string;
|
|
142
|
+
task: string;
|
|
143
|
+
target: string;
|
|
144
|
+
status: RunStatus;
|
|
145
|
+
}[];
|
|
146
|
+
pulls: number;
|
|
147
|
+
};
|
|
148
|
+
/** Live event stream over a set of runs (see Handoff.stream). */
|
|
149
|
+
export type HandoffStreamEvent = {
|
|
150
|
+
type: "run.status";
|
|
151
|
+
runId: string;
|
|
152
|
+
status: RunStatus;
|
|
153
|
+
} | {
|
|
154
|
+
type: "run.event";
|
|
155
|
+
runId: string;
|
|
156
|
+
event: ChainedEvent;
|
|
157
|
+
} | {
|
|
158
|
+
type: "artifact.ready";
|
|
159
|
+
runId: string;
|
|
160
|
+
kind: ArtifactKind;
|
|
161
|
+
hash: string;
|
|
162
|
+
} | {
|
|
163
|
+
type: "run.terminal";
|
|
164
|
+
runId: string;
|
|
165
|
+
status: RunStatus;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* The continuation context. One object that can checkpoint local work,
|
|
169
|
+
* plan a continuation under policy, hand the work to a governed runner
|
|
170
|
+
* pool, and pull the results (and the receipts) back.
|
|
171
|
+
*
|
|
172
|
+
* Built entirely on Warrant primitives: every continuation is a signed
|
|
173
|
+
* run contract, every result is an offline-verifiable receipt, and the
|
|
174
|
+
* envelope hash is pinned inside the contract.
|
|
175
|
+
*/
|
|
176
|
+
export declare class Handoff {
|
|
177
|
+
private readonly client;
|
|
178
|
+
private readonly workspaceDir;
|
|
179
|
+
private readonly actor;
|
|
180
|
+
private readonly agent;
|
|
181
|
+
private readonly policy;
|
|
182
|
+
private readonly secrets;
|
|
183
|
+
private readonly allowHosts;
|
|
184
|
+
private readonly allowUntracked;
|
|
185
|
+
private readonly budget;
|
|
186
|
+
private readonly traceLog;
|
|
187
|
+
private readonly toolJournal;
|
|
188
|
+
private readonly requestedRuns;
|
|
189
|
+
private readonly checkpointsState;
|
|
190
|
+
private lastEnvelopeValue?;
|
|
191
|
+
private userRequestedContinuation;
|
|
192
|
+
private modelEscalationCount;
|
|
193
|
+
constructor(init: HandoffInit);
|
|
194
|
+
/** The local workspace this context is bound to. */
|
|
195
|
+
get workspacePath(): string;
|
|
196
|
+
/** Local trace: every planning, envelope, run, pull, and tool decision. */
|
|
197
|
+
trace(): HandoffTraceEvent[];
|
|
198
|
+
/**
|
|
199
|
+
* Wrap an AI SDK-shaped toolset (any tools with `execute`) so every call
|
|
200
|
+
* is journaled. The journal travels as content-addressed semantic state
|
|
201
|
+
* in the next checkpoint, so a continuation carries what the loop's tools
|
|
202
|
+
* saw and did. Tools still execute locally, in the caller's process —
|
|
203
|
+
* this is capture, not orchestration. For governed *remote* execution,
|
|
204
|
+
* use @fusionkit/adapter-ai-sdk's remoteTools instead.
|
|
205
|
+
*/
|
|
206
|
+
tools<T extends Record<string, ToolLike>>(toolset: T): T;
|
|
207
|
+
/** Snapshot of the observable state that continuation triggers evaluate. */
|
|
208
|
+
private triggerState;
|
|
209
|
+
/** Which of the policy's continueWhen triggers currently fire, and why. */
|
|
210
|
+
firedTriggers(): FiredTrigger[];
|
|
211
|
+
/**
|
|
212
|
+
* Explicitly request continuation (the user gesture). Makes
|
|
213
|
+
* triggers.userRequested() fire on the next needs() check.
|
|
214
|
+
*/
|
|
215
|
+
requestContinuation(reason?: string): void;
|
|
216
|
+
/**
|
|
217
|
+
* Report a model routing decision (wired up by withModel from
|
|
218
|
+
* @fusionkit/adapter-ai-sdk). Escalations feed triggers.modelEscalated().
|
|
219
|
+
*/
|
|
220
|
+
noteModelDecision(decision: ModelDecision): void;
|
|
221
|
+
/**
|
|
222
|
+
* Deterministic check: should this work continue on the target?
|
|
223
|
+
* True when the continuation policy permits the target AND — if the
|
|
224
|
+
* policy declares continueWhen triggers — at least one trigger fires
|
|
225
|
+
* against observable context state (tool failures, slow tools, explicit
|
|
226
|
+
* requests, model escalations). Pure: records nothing, moves nothing.
|
|
227
|
+
*/
|
|
228
|
+
needs(target: RuntimeTarget, options?: Partial<ContinueOptions> & {
|
|
229
|
+
parallelism?: number;
|
|
230
|
+
}): boolean;
|
|
231
|
+
/** Recomputed view over the trace plus live run statuses from the plane. */
|
|
232
|
+
summary(): Promise<HandoffSummary>;
|
|
233
|
+
/** Every checkpoint this context created, oldest first (lineage intact). */
|
|
234
|
+
checkpoints(): Checkpoint[];
|
|
235
|
+
/**
|
|
236
|
+
* Live, typed event stream over a set of runs: status transitions, every
|
|
237
|
+
* appended chained event, artifact availability, and terminal states.
|
|
238
|
+
* Completes when all runs are terminal.
|
|
239
|
+
*/
|
|
240
|
+
stream(runs: HandoffRun[], options?: {
|
|
241
|
+
pollMs?: number;
|
|
242
|
+
timeoutMs?: number;
|
|
243
|
+
}): AsyncGenerator<HandoffStreamEvent, void, void>;
|
|
244
|
+
/** The most recent envelope this context produced. */
|
|
245
|
+
lastEnvelope(): HandoffEnvelope | undefined;
|
|
246
|
+
private record;
|
|
247
|
+
private capture;
|
|
248
|
+
/**
|
|
249
|
+
* Upload the captured workspace with bounded concurrency. Blobs are
|
|
250
|
+
* content-addressed and idempotent, so a partial failure simply leaves
|
|
251
|
+
* already-uploaded blobs in place — retried checkpoints reuse them and
|
|
252
|
+
* the plane's reference-counting GC reclaims any that end up orphaned.
|
|
253
|
+
*/
|
|
254
|
+
private uploadCapture;
|
|
255
|
+
/** Snapshot the tool journal as a content-addressed blob payload. */
|
|
256
|
+
private journalSnapshot;
|
|
257
|
+
/**
|
|
258
|
+
* Capture resumable state: the workspace manifest (git base ref, dirty
|
|
259
|
+
* diff, allowlisted untracked files) plus an optional transcript as
|
|
260
|
+
* semantic state. Content moves to the plane blob store; secret-pattern
|
|
261
|
+
* files are denied capture and the denial is recorded in the manifest.
|
|
262
|
+
*/
|
|
263
|
+
checkpoint(message?: string, options?: {
|
|
264
|
+
transcript?: string;
|
|
265
|
+
}): Promise<Checkpoint>;
|
|
266
|
+
/** Deterministic continuation planning; never moves anything. */
|
|
267
|
+
plan(target: RuntimeTarget, options?: Partial<ContinueOptions>, parallelism?: number): PlanningDecision;
|
|
268
|
+
private buildEnvelope;
|
|
269
|
+
private buildRunRequest;
|
|
270
|
+
/**
|
|
271
|
+
* "What would move?" — the disclosure report for a continuation,
|
|
272
|
+
* computed without uploading, issuing, or executing anything.
|
|
273
|
+
*/
|
|
274
|
+
dryRun(target: RuntimeTarget, options: ContinueOptions): Promise<{
|
|
275
|
+
report: DisclosureReport;
|
|
276
|
+
envelope: HandoffEnvelope;
|
|
277
|
+
decision: PlanningDecision;
|
|
278
|
+
}>;
|
|
279
|
+
/**
|
|
280
|
+
* Continue this work in the target pool: plan under policy (fail
|
|
281
|
+
* closed), checkpoint, wrap the continuation in a content-addressed
|
|
282
|
+
* envelope, and submit it as a governed run whose signed contract pins
|
|
283
|
+
* the envelope hash.
|
|
284
|
+
*/
|
|
285
|
+
continueIn(target: RuntimeTarget, options: ContinueOptions): Promise<HandoffRun>;
|
|
286
|
+
private submit;
|
|
287
|
+
/**
|
|
288
|
+
* Fan the same checkpoint out across several isolated attempts. Each
|
|
289
|
+
* attempt is its own governed run with its own contract, envelope, and
|
|
290
|
+
* receipt; outputs land on separate branches at pull time.
|
|
291
|
+
*/
|
|
292
|
+
parallel(tasks: string[], target: RuntimeTarget, options?: ParallelOptions): Promise<HandoffRun[]>;
|
|
293
|
+
/** Compare fan-out attempts with a typed, deterministic strategy. */
|
|
294
|
+
review(runs: HandoffRun[], options?: {
|
|
295
|
+
choose?: ReviewStrategy;
|
|
296
|
+
}): Promise<ReviewResult>;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Create a continuation context bound to a workspace and a plane. Anything
|
|
300
|
+
* not supplied here falls back to defaults registered via
|
|
301
|
+
* defineHandoffConfig; the workspace is always explicit.
|
|
302
|
+
*/
|
|
303
|
+
export declare function handoff(init: HandoffInit): Handoff;
|