@hue-run/sdk 0.3.2 → 0.4.1
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/CLI.md +270 -47
- package/ENVIRONMENTS.md +10 -0
- package/README.md +19 -3
- package/dist/client.d.ts +5 -5
- package/dist/client.js +13 -6
- package/dist/environment/tools.d.ts +6 -1
- package/dist/environment/tools.js +7 -1
- package/dist/environment/types.d.ts +6 -1
- package/dist/receipt.js +36 -8
- package/dist/setup/application.d.ts +74 -0
- package/dist/setup/application.js +766 -0
- package/dist/setup/backend.d.ts +229 -0
- package/dist/setup/backend.js +855 -0
- package/dist/setup/checkpoint.js +100 -30
- package/dist/setup/cli.js +20 -4
- package/dist/setup/configure.d.ts +13 -0
- package/dist/setup/configure.js +454 -0
- package/dist/setup/credential.d.ts +2 -0
- package/dist/setup/credential.js +9 -0
- package/dist/setup/detect.js +4 -1
- package/dist/setup/installation.d.ts +118 -0
- package/dist/setup/installation.js +605 -0
- package/dist/setup/lock.d.ts +2 -0
- package/dist/setup/lock.js +38 -0
- package/dist/setup/machine.d.ts +1 -10
- package/dist/setup/machine.js +8 -7
- package/dist/setup/render.d.ts +3 -1
- package/dist/setup/render.js +209 -6
- package/dist/setup/runner.d.ts +26 -76
- package/dist/setup/runner.js +320 -45
- package/dist/setup/socket.d.ts +7 -0
- package/dist/setup/socket.js +144 -0
- package/dist/setup/source.d.ts +9 -0
- package/dist/setup/source.js +269 -0
- package/dist/setup/types.d.ts +16 -9
- package/dist/setup/types.js +1 -1
- package/dist/setup.d.ts +6 -2
- package/dist/setup.js +3 -0
- package/dist/types.d.ts +24 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/setup-events.schema.json +16 -9
package/dist/setup/machine.js
CHANGED
|
@@ -14,8 +14,14 @@ export function transitionSetup(state, input) {
|
|
|
14
14
|
}
|
|
15
15
|
if (state.phase === "detecting" && input.type === "project.detected") {
|
|
16
16
|
const plan = {
|
|
17
|
-
steps: [
|
|
18
|
-
|
|
17
|
+
steps: [
|
|
18
|
+
"detect-project",
|
|
19
|
+
"install-runtime",
|
|
20
|
+
"configure-telemetry",
|
|
21
|
+
"verify-application-receipt",
|
|
22
|
+
"claim-project",
|
|
23
|
+
],
|
|
24
|
+
mutatesProject: true,
|
|
19
25
|
backendRequired: true,
|
|
20
26
|
};
|
|
21
27
|
return {
|
|
@@ -31,11 +37,6 @@ export function transitionSetup(state, input) {
|
|
|
31
37
|
{ event: "project.detected", project: input.project },
|
|
32
38
|
{ event: "step.completed", step: "detect-project", outcome: "unchanged" },
|
|
33
39
|
{ event: "plan.ready", plan },
|
|
34
|
-
{
|
|
35
|
-
event: "action.required",
|
|
36
|
-
action: "configure",
|
|
37
|
-
message: "Local inspection is complete. Telemetry configuration is not available in this build; no project files were changed.",
|
|
38
|
-
},
|
|
39
40
|
],
|
|
40
41
|
};
|
|
41
42
|
}
|
package/dist/setup/render.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SetupEvent } from "./types.js";
|
|
2
2
|
/** Supported setup transcript formats. */
|
|
3
3
|
export type SetupOutputMode = "human" | "plain" | "jsonl";
|
|
4
|
+
/** Removes capability-shaped fragments and bounds text before it reaches a public transcript. */
|
|
5
|
+
export declare function redactSetupTranscriptText(value: string): string;
|
|
4
6
|
/** Renders one newline-free JSON object for JSONL output. */
|
|
5
7
|
export declare function renderJsonlEvent(event: SetupEvent): string;
|
|
6
8
|
/** Renders one ANSI-free append-only transcript entry. */
|
package/dist/setup/render.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SETUP_EVENT_CONTRACT_VERSION } from "./types.js";
|
|
1
2
|
const ansi = {
|
|
2
3
|
cyan: "\u001b[36m",
|
|
3
4
|
green: "\u001b[32m",
|
|
@@ -6,6 +7,206 @@ const ansi = {
|
|
|
6
7
|
dim: "\u001b[2m",
|
|
7
8
|
reset: "\u001b[0m",
|
|
8
9
|
};
|
|
10
|
+
/** Removes capability-shaped fragments and bounds text before it reaches a public transcript. */
|
|
11
|
+
export function redactSetupTranscriptText(value) {
|
|
12
|
+
if (typeof value !== "string")
|
|
13
|
+
return "[invalid text]";
|
|
14
|
+
// Normalize encoded/separated spellings before matching, and redact before truncating.
|
|
15
|
+
let normalized = value;
|
|
16
|
+
for (let pass = 0; pass < 3; pass++)
|
|
17
|
+
normalized = normalized
|
|
18
|
+
.replace(/%([a-f0-9]{2})/giu, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
|
|
19
|
+
.replace(/\\u([a-f0-9]{4})/giu, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
|
|
20
|
+
.replaceAll("\\/", "/");
|
|
21
|
+
normalized = normalized.replace(/[\p{Cc}\p{Cf}]/gu, "");
|
|
22
|
+
const withoutUrls = normalized.replace(/https?:\/\/[^\s"'<>]+/giu, (candidate) => {
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(candidate);
|
|
25
|
+
return url.hash || url.pathname.includes("/setup/claim")
|
|
26
|
+
? "[private claim handoff]"
|
|
27
|
+
: candidate;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return "[redacted URL]";
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const redacted = withoutUrls
|
|
34
|
+
// Deliberately recognize incomplete and unknown namespace suffixes too. A
|
|
35
|
+
// transport exception may contain only a truncated credential.
|
|
36
|
+
.replace(/hue_(?:sk|setup|install|claim)_[A-Za-z0-9_-]*/giu, "[private credential]")
|
|
37
|
+
.replace(/#[A-Za-z0-9_-]+/gu, "#[redacted]")
|
|
38
|
+
.replace(/\b(claim[_-]?(?:secret|token))(["']?\s*[:=]\s*["']?)[A-Za-z0-9_-]+/giu, "$1$2[redacted]")
|
|
39
|
+
.replace(/(?<![A-Za-z0-9_-])[A-Za-z0-9_-]{43}(?![A-Za-z0-9_-])/gu, "[private capability]");
|
|
40
|
+
return redacted.slice(0, 1000);
|
|
41
|
+
}
|
|
42
|
+
function choice(value, allowed) {
|
|
43
|
+
return allowed.includes(value) ? value : allowed[0];
|
|
44
|
+
}
|
|
45
|
+
function choices(values, allowed) {
|
|
46
|
+
return Array.isArray(values)
|
|
47
|
+
? [...new Set(values.filter((value) => allowed.includes(value)))]
|
|
48
|
+
: [];
|
|
49
|
+
}
|
|
50
|
+
const steps = [
|
|
51
|
+
"detect-project",
|
|
52
|
+
"install-runtime",
|
|
53
|
+
"configure-telemetry",
|
|
54
|
+
"verify-application-receipt",
|
|
55
|
+
"claim-project",
|
|
56
|
+
];
|
|
57
|
+
function publicEvent(event) {
|
|
58
|
+
const base = {
|
|
59
|
+
contractVersion: SETUP_EVENT_CONTRACT_VERSION,
|
|
60
|
+
runId: redactSetupTranscriptText(event.runId),
|
|
61
|
+
sequence: Number.isSafeInteger(event.sequence) ? event.sequence : 1,
|
|
62
|
+
timestamp: redactSetupTranscriptText(event.timestamp),
|
|
63
|
+
};
|
|
64
|
+
switch (event.event) {
|
|
65
|
+
case "run.started":
|
|
66
|
+
return {
|
|
67
|
+
...base,
|
|
68
|
+
event: "run.started",
|
|
69
|
+
command: choice(event.command, ["setup", "resume", "status", "claim"]),
|
|
70
|
+
mode: choice(event.mode, ["human", "plain", "jsonl"]),
|
|
71
|
+
resumed: event.resumed === true,
|
|
72
|
+
};
|
|
73
|
+
case "project.detected":
|
|
74
|
+
return {
|
|
75
|
+
...base,
|
|
76
|
+
event: "project.detected",
|
|
77
|
+
project: {
|
|
78
|
+
root: redactSetupTranscriptText(event.project.root),
|
|
79
|
+
fingerprint: redactSetupTranscriptText(event.project.fingerprint),
|
|
80
|
+
languages: choices(event.project.languages, ["typescript", "python"]),
|
|
81
|
+
packageManagers: choices(event.project.packageManagers, [
|
|
82
|
+
"bun",
|
|
83
|
+
"npm",
|
|
84
|
+
"pnpm",
|
|
85
|
+
"yarn",
|
|
86
|
+
"uv",
|
|
87
|
+
"poetry",
|
|
88
|
+
"pip",
|
|
89
|
+
]),
|
|
90
|
+
frameworks: choices(event.project.frameworks, [
|
|
91
|
+
"nextjs",
|
|
92
|
+
"nestjs",
|
|
93
|
+
"express",
|
|
94
|
+
"fastapi",
|
|
95
|
+
"django",
|
|
96
|
+
"flask",
|
|
97
|
+
"vercel-ai-sdk",
|
|
98
|
+
]),
|
|
99
|
+
hue: choice(event.project.hue, ["absent", "typescript", "python", "multiple"]),
|
|
100
|
+
openTelemetry: choice(event.project.openTelemetry, [
|
|
101
|
+
"absent",
|
|
102
|
+
"typescript",
|
|
103
|
+
"python",
|
|
104
|
+
"multiple",
|
|
105
|
+
]),
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
case "plan.ready":
|
|
109
|
+
return {
|
|
110
|
+
...base,
|
|
111
|
+
event: "plan.ready",
|
|
112
|
+
plan: {
|
|
113
|
+
steps: choices(event.plan.steps, steps),
|
|
114
|
+
mutatesProject: event.plan.mutatesProject === true,
|
|
115
|
+
backendRequired: event.plan.backendRequired === true,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
case "step.started":
|
|
119
|
+
return { ...base, event: "step.started", step: choice(event.step, steps) };
|
|
120
|
+
case "step.completed":
|
|
121
|
+
return {
|
|
122
|
+
...base,
|
|
123
|
+
event: "step.completed",
|
|
124
|
+
step: choice(event.step, steps),
|
|
125
|
+
outcome: choice(event.outcome, ["unchanged", "changed", "verified", "skipped"]),
|
|
126
|
+
};
|
|
127
|
+
case "file.changed":
|
|
128
|
+
return {
|
|
129
|
+
...base,
|
|
130
|
+
event: "file.changed",
|
|
131
|
+
path: redactSetupTranscriptText(event.path),
|
|
132
|
+
change: choice(event.change, ["created", "updated"]),
|
|
133
|
+
};
|
|
134
|
+
case "diagnostic":
|
|
135
|
+
return {
|
|
136
|
+
...base,
|
|
137
|
+
event: "diagnostic",
|
|
138
|
+
level: choice(event.level, ["info", "warning", "error"]),
|
|
139
|
+
code: redactSetupTranscriptText(event.code),
|
|
140
|
+
message: redactSetupTranscriptText(event.message),
|
|
141
|
+
};
|
|
142
|
+
case "privacy.notice":
|
|
143
|
+
return {
|
|
144
|
+
...base,
|
|
145
|
+
event: "privacy.notice",
|
|
146
|
+
privacyUrl: "https://hue.run/privacy",
|
|
147
|
+
effectiveDate: "2026-08-24",
|
|
148
|
+
securityUrl: "https://trust.hue.run/",
|
|
149
|
+
};
|
|
150
|
+
case "action.required":
|
|
151
|
+
return {
|
|
152
|
+
...base,
|
|
153
|
+
event: "action.required",
|
|
154
|
+
action: choice(event.action, [
|
|
155
|
+
"claim-project",
|
|
156
|
+
"configure",
|
|
157
|
+
"select-project",
|
|
158
|
+
"integrate-application",
|
|
159
|
+
"run-instrumented-request",
|
|
160
|
+
"open-claim-handoff",
|
|
161
|
+
"restart-claim-handoff",
|
|
162
|
+
]),
|
|
163
|
+
message: redactSetupTranscriptText(event.message),
|
|
164
|
+
...(event.command ? { command: redactSetupTranscriptText(event.command) } : {}),
|
|
165
|
+
};
|
|
166
|
+
case "trial.created":
|
|
167
|
+
return {
|
|
168
|
+
...base,
|
|
169
|
+
event: "trial.created",
|
|
170
|
+
trialId: redactSetupTranscriptText(event.trialId),
|
|
171
|
+
expiresAt: redactSetupTranscriptText(event.expiresAt),
|
|
172
|
+
};
|
|
173
|
+
case "receipt.verified":
|
|
174
|
+
return {
|
|
175
|
+
...base,
|
|
176
|
+
event: "receipt.verified",
|
|
177
|
+
receiptId: redactSetupTranscriptText(event.receiptId),
|
|
178
|
+
traceId: redactSetupTranscriptText(event.traceId),
|
|
179
|
+
source: "repository-http-boundary",
|
|
180
|
+
};
|
|
181
|
+
case "claim.required":
|
|
182
|
+
return {
|
|
183
|
+
...base,
|
|
184
|
+
event: "claim.required",
|
|
185
|
+
claimId: redactSetupTranscriptText(event.claimId),
|
|
186
|
+
};
|
|
187
|
+
case "claim.completed":
|
|
188
|
+
return {
|
|
189
|
+
...base,
|
|
190
|
+
event: "claim.completed",
|
|
191
|
+
claimId: redactSetupTranscriptText(event.claimId),
|
|
192
|
+
};
|
|
193
|
+
case "run.completed":
|
|
194
|
+
return {
|
|
195
|
+
...base,
|
|
196
|
+
event: "run.completed",
|
|
197
|
+
outcome: choice(event.outcome, ["ready", "action_required", "unchanged"]),
|
|
198
|
+
checkpointed: event.checkpointed === true,
|
|
199
|
+
};
|
|
200
|
+
case "run.failed":
|
|
201
|
+
return {
|
|
202
|
+
...base,
|
|
203
|
+
event: "run.failed",
|
|
204
|
+
code: redactSetupTranscriptText(event.code),
|
|
205
|
+
message: redactSetupTranscriptText(event.message),
|
|
206
|
+
resumable: event.resumable === true,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
9
210
|
function wrap(text, width, prefix) {
|
|
10
211
|
const available = Math.max(20, width - prefix.length);
|
|
11
212
|
const words = text.split(/\s+/u);
|
|
@@ -46,14 +247,16 @@ function summary(event) {
|
|
|
46
247
|
return `${event.change === "created" ? "Created" : "Updated"} ${event.path}.`;
|
|
47
248
|
case "diagnostic":
|
|
48
249
|
return `${event.code}: ${event.message}`;
|
|
250
|
+
case "privacy.notice":
|
|
251
|
+
return `Privacy notice effective ${event.effectiveDate}: ${event.privacyUrl}. Security: ${event.securityUrl}`;
|
|
49
252
|
case "action.required":
|
|
50
253
|
return `${event.message}${event.command ? ` Next: ${event.command}.` : ""}`;
|
|
51
254
|
case "trial.created":
|
|
52
255
|
return `Anonymous trial ${event.trialId} created; expires ${event.expiresAt}.`;
|
|
53
256
|
case "receipt.verified":
|
|
54
|
-
return `
|
|
257
|
+
return `Repository HTTP boundary receipt ${event.receiptId} verified for trace ${event.traceId}.`;
|
|
55
258
|
case "claim.required":
|
|
56
|
-
return `
|
|
259
|
+
return `Account linkage is ready for project owner action (${event.claimId}).`;
|
|
57
260
|
case "claim.completed":
|
|
58
261
|
return `Claim ${event.claimId} completed.`;
|
|
59
262
|
case "run.completed":
|
|
@@ -64,11 +267,11 @@ function summary(event) {
|
|
|
64
267
|
}
|
|
65
268
|
/** Renders one newline-free JSON object for JSONL output. */
|
|
66
269
|
export function renderJsonlEvent(event) {
|
|
67
|
-
return JSON.stringify(event);
|
|
270
|
+
return JSON.stringify(publicEvent(event));
|
|
68
271
|
}
|
|
69
272
|
/** Renders one ANSI-free append-only transcript entry. */
|
|
70
273
|
export function renderPlainEvent(event, width = 80) {
|
|
71
|
-
const text = summary(event);
|
|
274
|
+
const text = summary(publicEvent(event));
|
|
72
275
|
if (!text)
|
|
73
276
|
return "";
|
|
74
277
|
const marker = event.event === "run.failed"
|
|
@@ -80,7 +283,7 @@ export function renderPlainEvent(event, width = 80) {
|
|
|
80
283
|
}
|
|
81
284
|
/** Renders one lightweight append-only terminal entry; it never moves the cursor or clears the screen. */
|
|
82
285
|
export function renderHumanEvent(event, width = 80, color = true) {
|
|
83
|
-
const text = summary(event);
|
|
286
|
+
const text = summary(publicEvent(event));
|
|
84
287
|
if (!text)
|
|
85
288
|
return "";
|
|
86
289
|
const [symbol, tone] = event.event === "run.failed"
|
|
@@ -102,7 +305,7 @@ export function renderHumanEvent(event, width = 80, color = true) {
|
|
|
102
305
|
export function selectSetupOutputMode(input) {
|
|
103
306
|
if (input.agent)
|
|
104
307
|
return "jsonl";
|
|
105
|
-
if (input.explicit
|
|
308
|
+
if (input.explicit)
|
|
106
309
|
return input.explicit;
|
|
107
310
|
const env = input.env ?? process.env;
|
|
108
311
|
if (!input.isTTY || env.NO_COLOR !== undefined || env.TERM === "dumb" || env.CI !== undefined)
|
package/dist/setup/runner.d.ts
CHANGED
|
@@ -1,101 +1,51 @@
|
|
|
1
|
+
import type { SetupBackendAdapter } from "./backend.js";
|
|
1
2
|
import type { SetupMachineState } from "./machine.js";
|
|
2
3
|
import { type SetupEvent, type SetupProjectDetection } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
export interface SetupBackendTrial {
|
|
5
|
-
/** Non-secret trial identifier. */
|
|
6
|
-
trialId: string;
|
|
7
|
-
/** ISO-8601 trial expiration. */
|
|
8
|
-
expiresAt: string;
|
|
9
|
-
}
|
|
10
|
-
/** Instrumentation-only receipt evidence returned by a future backend adapter. */
|
|
11
|
-
export interface SetupBackendReceipt {
|
|
12
|
-
/** Non-secret receipt identifier. */
|
|
13
|
-
receiptId: string;
|
|
14
|
-
/** Verified lowercase trace identifier; it does not establish content or Scenario suitability. */
|
|
15
|
-
traceId: string;
|
|
16
|
-
}
|
|
17
|
-
/** @inline */
|
|
18
|
-
interface SetupBackendClaimRequired {
|
|
19
|
-
/** Claim is ready for a person. */
|
|
20
|
-
status: "required";
|
|
21
|
-
/** Non-secret claim identifier. */
|
|
22
|
-
claimId: string;
|
|
23
|
-
/** User-facing URL, which must never be checkpointed. */
|
|
24
|
-
url: string;
|
|
25
|
-
}
|
|
26
|
-
/** @inline */
|
|
27
|
-
interface SetupBackendClaimCompleted {
|
|
28
|
-
/** Claim has been confirmed by the backend. */
|
|
29
|
-
status: "completed";
|
|
30
|
-
/** Non-secret claim identifier. */
|
|
31
|
-
claimId: string;
|
|
32
|
-
}
|
|
33
|
-
/** Claim state returned by a future backend adapter. Claim URLs are never checkpointed. */
|
|
34
|
-
export type SetupBackendClaim = SetupBackendClaimRequired | SetupBackendClaimCompleted;
|
|
35
|
-
/** Installer-only network boundary for account attachment. It never creates a Scenario, worker, evaluation, or Hue Run. */
|
|
36
|
-
export interface SetupBackendAdapter {
|
|
37
|
-
/** Creates or idempotently recovers an anonymous trial hard-pinned to `trial_metadata_v1`. */
|
|
38
|
-
createTrial(input: {
|
|
39
|
-
runId: string;
|
|
40
|
-
projectFingerprint: string;
|
|
41
|
-
idempotencyKey: string;
|
|
42
|
-
}, signal?: AbortSignal): Promise<SetupBackendTrial>;
|
|
43
|
-
/**
|
|
44
|
-
* Returns instrumentation-only receipt evidence, or `undefined` while pending.
|
|
45
|
-
* A receipt never authorizes content capture or Scenario publication.
|
|
46
|
-
*/
|
|
47
|
-
verifyReceipt(input: {
|
|
48
|
-
trialId: string;
|
|
49
|
-
idempotencyKey: string;
|
|
50
|
-
}, signal?: AbortSignal): Promise<SetupBackendReceipt | undefined>;
|
|
51
|
-
/** Reads account-claim state after receipt verification without opening the claim URL. */
|
|
52
|
-
getClaim(input: {
|
|
53
|
-
trialId: string;
|
|
54
|
-
idempotencyKey: string;
|
|
55
|
-
}, signal?: AbortSignal): Promise<SetupBackendClaim>;
|
|
56
|
-
}
|
|
57
|
-
/** Static project-inspection boundary. */
|
|
4
|
+
/** Detects the supported language and safe setup plan for a project root. */
|
|
58
5
|
export interface SetupProjectAdapter {
|
|
59
|
-
/** Inspects
|
|
6
|
+
/** Inspects a project without executing its code. */
|
|
60
7
|
detect(root: string, signal?: AbortSignal): Promise<SetupProjectDetection>;
|
|
61
8
|
}
|
|
62
|
-
/**
|
|
9
|
+
/** Persists secret-free setup progress across interruptions. */
|
|
63
10
|
export interface SetupCheckpointAdapter {
|
|
64
|
-
/**
|
|
11
|
+
/** Reads the checkpoint for one setup run and project. */
|
|
65
12
|
load(runId: string, projectRoot: string): Promise<SetupMachineState | undefined>;
|
|
66
|
-
/**
|
|
13
|
+
/** Atomically saves the latest setup state. */
|
|
67
14
|
save(state: SetupMachineState): Promise<void>;
|
|
68
15
|
}
|
|
69
|
-
/**
|
|
16
|
+
/** Backend operations consumed by the resumable setup runner. */
|
|
17
|
+
export type SetupBackendOperations = Pick<SetupBackendAdapter, "prepare" | "resetLocalCache" | "preflight" | "localInstallation" | "provision" | "status" | "credentials" | "installRuntime" | "configure" | "exerciseApplication" | "prepareClaimHandoff" | "verifyApplication" | "verifyRevokedCredential">;
|
|
18
|
+
/** Inputs for one invocation of the resumable setup runner. */
|
|
70
19
|
export interface SetupRunOptions {
|
|
71
|
-
/**
|
|
20
|
+
/** Operation requested by the caller. */
|
|
72
21
|
command: "setup" | "resume" | "status" | "claim";
|
|
73
|
-
/**
|
|
22
|
+
/** Output contract selected by the CLI. */
|
|
74
23
|
mode: "human" | "plain" | "jsonl";
|
|
75
|
-
/** Stable
|
|
24
|
+
/** Stable identifier for this resumable invocation. */
|
|
76
25
|
runId: string;
|
|
77
|
-
/**
|
|
26
|
+
/** Absolute project directory being configured. */
|
|
78
27
|
projectRoot: string;
|
|
79
|
-
/**
|
|
28
|
+
/** Safe project detector. */
|
|
80
29
|
project: SetupProjectAdapter;
|
|
81
|
-
/**
|
|
30
|
+
/** Secret-free checkpoint persistence. */
|
|
82
31
|
checkpoints: SetupCheckpointAdapter;
|
|
83
|
-
/**
|
|
84
|
-
backend?:
|
|
85
|
-
/** Receives each ordered event
|
|
32
|
+
/** Real protocol adapter; omitting it can only report that action is required. */
|
|
33
|
+
backend?: SetupBackendOperations;
|
|
34
|
+
/** Receives each ordered setup event. */
|
|
86
35
|
emit(event: SetupEvent): void | Promise<void>;
|
|
87
|
-
/** Injectable clock
|
|
36
|
+
/** Injectable clock used by deterministic tests. */
|
|
88
37
|
now?: () => Date;
|
|
89
|
-
/**
|
|
38
|
+
/** Cancels bounded local and network work. */
|
|
90
39
|
signal?: AbortSignal;
|
|
40
|
+
/** Explicit owner request to replace the current browser handoff. Human claim commands only. */
|
|
41
|
+
claimRestart?: boolean;
|
|
91
42
|
}
|
|
92
|
-
/**
|
|
43
|
+
/** Terminal outcome and latest resumable state from one setup invocation. */
|
|
93
44
|
export interface SetupRunResult {
|
|
94
|
-
/**
|
|
45
|
+
/** Whether setup is verified, needs owner action, or made no change. */
|
|
95
46
|
outcome: "ready" | "action_required" | "unchanged";
|
|
96
|
-
/**
|
|
47
|
+
/** Latest checkpoint state when project detection has begun. */
|
|
97
48
|
state?: SetupMachineState;
|
|
98
49
|
}
|
|
99
|
-
/** Runs one
|
|
50
|
+
/** Runs one resumable setup command and emits exactly one terminal event. */
|
|
100
51
|
export declare function runSetup(options: SetupRunOptions): Promise<SetupRunResult>;
|
|
101
|
-
export {};
|