@hue-run/sdk 0.3.0 → 0.3.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 +52 -0
- package/ENVIRONMENTS.md +3 -4
- package/EVALUATIONS.md +10 -7
- package/README.md +10 -4
- package/dist/evals/runner.d.ts +1 -1
- package/dist/evals/runner.js +22 -12
- package/dist/evals/scorer-publication.js +17 -1
- package/dist/evals/scorers.d.ts +10 -4
- package/dist/evals/scorers.js +11 -8
- package/dist/evals/types.d.ts +8 -1
- package/dist/setup/checkpoint.d.ts +14 -0
- package/dist/setup/checkpoint.js +186 -0
- package/dist/setup/cli.d.ts +2 -0
- package/dist/setup/cli.js +150 -0
- package/dist/setup/detect.d.ts +3 -0
- package/dist/setup/detect.js +146 -0
- package/dist/setup/machine.d.ts +109 -0
- package/dist/setup/machine.js +43 -0
- package/dist/setup/render.d.ts +16 -0
- package/dist/setup/render.js +111 -0
- package/dist/setup/runner.d.ts +101 -0
- package/dist/setup/runner.js +117 -0
- package/dist/setup/types.d.ts +145 -0
- package/dist/setup/types.js +2 -0
- package/dist/setup.d.ts +6 -0
- package/dist/setup.js +6 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +12 -1
- package/setup-events.schema.json +134 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createInitialSetupState, transitionSetup } from "./machine.js";
|
|
2
|
+
import { SETUP_EVENT_CONTRACT_VERSION, } from "./types.js";
|
|
3
|
+
/** Runs one installer setup-session command and emits one terminal event; it never launches a Hue Run. */
|
|
4
|
+
export async function runSetup(options) {
|
|
5
|
+
const now = options.now ?? (() => new Date());
|
|
6
|
+
let sequence = 0;
|
|
7
|
+
let terminal = false;
|
|
8
|
+
const emit = async (body) => {
|
|
9
|
+
const event = {
|
|
10
|
+
contractVersion: SETUP_EVENT_CONTRACT_VERSION,
|
|
11
|
+
runId: options.runId,
|
|
12
|
+
sequence: ++sequence,
|
|
13
|
+
timestamp: now().toISOString(),
|
|
14
|
+
...body,
|
|
15
|
+
};
|
|
16
|
+
if (event.event === "run.completed" || event.event === "run.failed") {
|
|
17
|
+
if (terminal)
|
|
18
|
+
throw new Error("Setup runner attempted to emit more than one terminal event");
|
|
19
|
+
terminal = true;
|
|
20
|
+
}
|
|
21
|
+
else if (terminal)
|
|
22
|
+
throw new Error("Setup runner emitted an event after its terminal event");
|
|
23
|
+
await options.emit(event);
|
|
24
|
+
};
|
|
25
|
+
let state;
|
|
26
|
+
try {
|
|
27
|
+
state = await options.checkpoints.load(options.runId, options.projectRoot);
|
|
28
|
+
await emit({
|
|
29
|
+
event: "run.started",
|
|
30
|
+
command: options.command,
|
|
31
|
+
mode: options.mode,
|
|
32
|
+
resumed: state !== undefined,
|
|
33
|
+
});
|
|
34
|
+
if (options.signal?.aborted)
|
|
35
|
+
throw new Error("Setup interrupted");
|
|
36
|
+
if (options.command === "status") {
|
|
37
|
+
await emit({
|
|
38
|
+
event: "diagnostic",
|
|
39
|
+
level: "info",
|
|
40
|
+
code: state ? `checkpoint.${state.phase}` : "checkpoint.absent",
|
|
41
|
+
message: state
|
|
42
|
+
? `Checkpoint phase: ${state.phase}.`
|
|
43
|
+
: "No setup checkpoint exists for this project.",
|
|
44
|
+
});
|
|
45
|
+
await emit({
|
|
46
|
+
event: "run.completed",
|
|
47
|
+
outcome: "unchanged",
|
|
48
|
+
checkpointed: state !== undefined,
|
|
49
|
+
});
|
|
50
|
+
return { outcome: "unchanged", state };
|
|
51
|
+
}
|
|
52
|
+
if (options.command === "claim") {
|
|
53
|
+
await emit({
|
|
54
|
+
event: "action.required",
|
|
55
|
+
action: "claim-project",
|
|
56
|
+
message: "Project claim is not available in this build; no backend request was made. A future adapter must require a verified anonymous telemetry receipt first.",
|
|
57
|
+
});
|
|
58
|
+
await emit({
|
|
59
|
+
event: "run.completed",
|
|
60
|
+
outcome: "action_required",
|
|
61
|
+
checkpointed: state !== undefined,
|
|
62
|
+
});
|
|
63
|
+
return { outcome: "action_required", state };
|
|
64
|
+
}
|
|
65
|
+
if (!state) {
|
|
66
|
+
if (options.command === "resume")
|
|
67
|
+
throw new Error("No setup checkpoint exists for this project");
|
|
68
|
+
state = createInitialSetupState(options.runId, options.projectRoot);
|
|
69
|
+
await options.checkpoints.save(state);
|
|
70
|
+
}
|
|
71
|
+
if (state.phase === "local-ready") {
|
|
72
|
+
await emit({ event: "project.detected", project: state.project });
|
|
73
|
+
await emit({ event: "plan.ready", plan: state.plan });
|
|
74
|
+
await emit({
|
|
75
|
+
event: "action.required",
|
|
76
|
+
action: "configure",
|
|
77
|
+
message: "Local inspection is complete. Telemetry configuration is not available in this build; no project files were changed.",
|
|
78
|
+
});
|
|
79
|
+
await emit({ event: "run.completed", outcome: "action_required", checkpointed: true });
|
|
80
|
+
return { outcome: "action_required", state };
|
|
81
|
+
}
|
|
82
|
+
const first = transitionSetup(state, { type: "start" });
|
|
83
|
+
state = first.state;
|
|
84
|
+
await options.checkpoints.save(state);
|
|
85
|
+
for (const event of first.events)
|
|
86
|
+
await emit(event);
|
|
87
|
+
if (options.signal?.aborted)
|
|
88
|
+
throw new Error("Setup interrupted");
|
|
89
|
+
const project = await options.project.detect(first.effect.root, options.signal);
|
|
90
|
+
if (options.signal?.aborted)
|
|
91
|
+
throw new Error("Setup interrupted");
|
|
92
|
+
const second = transitionSetup(state, { type: "project.detected", project });
|
|
93
|
+
state = second.state;
|
|
94
|
+
await options.checkpoints.save(state);
|
|
95
|
+
for (const event of second.events)
|
|
96
|
+
await emit(event);
|
|
97
|
+
await emit({ event: "run.completed", outcome: "action_required", checkpointed: true });
|
|
98
|
+
return { outcome: "action_required", state };
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (!terminal) {
|
|
102
|
+
const interrupted = options.signal?.aborted ||
|
|
103
|
+
(error instanceof Error && error.message === "Setup interrupted");
|
|
104
|
+
await emit({
|
|
105
|
+
event: "run.failed",
|
|
106
|
+
code: interrupted ? "interrupted" : "setup_failed",
|
|
107
|
+
message: interrupted
|
|
108
|
+
? "Setup session was interrupted and can be resumed."
|
|
109
|
+
: error instanceof Error && error.message.startsWith("No setup checkpoint")
|
|
110
|
+
? error.message
|
|
111
|
+
: "Setup session could not complete. No credentials were stored.",
|
|
112
|
+
resumable: state !== undefined,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/** Version carried by every setup JSONL event. */
|
|
2
|
+
export declare const SETUP_EVENT_CONTRACT_VERSION: 1;
|
|
3
|
+
/** Names in the version 1 setup event contract. */
|
|
4
|
+
export type SetupEventName = "run.started" | "project.detected" | "plan.ready" | "step.started" | "step.completed" | "file.changed" | "diagnostic" | "action.required" | "trial.created" | "receipt.verified" | "claim.required" | "claim.completed" | "run.completed" | "run.failed";
|
|
5
|
+
interface EventBase<Name extends SetupEventName> {
|
|
6
|
+
/** JSONL contract version, independent of the package version. */
|
|
7
|
+
contractVersion: typeof SETUP_EVENT_CONTRACT_VERSION;
|
|
8
|
+
/** Event discriminator. */
|
|
9
|
+
event: Name;
|
|
10
|
+
/** Deterministic installer-session identifier; it is not a Hue Run identifier. */
|
|
11
|
+
runId: string;
|
|
12
|
+
/** One-based sequence within this command invocation. */
|
|
13
|
+
sequence: number;
|
|
14
|
+
/** ISO-8601 time supplied by the runner clock. */
|
|
15
|
+
timestamp: string;
|
|
16
|
+
}
|
|
17
|
+
/** An installer setup-session command invocation began; this is not a Hue Run. */
|
|
18
|
+
export interface RunStartedEvent extends EventBase<"run.started"> {
|
|
19
|
+
/** Command being executed. */
|
|
20
|
+
command: "setup" | "resume" | "status" | "claim";
|
|
21
|
+
/** Renderer selected for this invocation. */
|
|
22
|
+
mode: "human" | "plain" | "jsonl";
|
|
23
|
+
/** Whether a checkpoint existed when the invocation began. */
|
|
24
|
+
resumed: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** Static project facts read without executing repository code. */
|
|
27
|
+
export interface SetupProjectDetection {
|
|
28
|
+
/** Canonical project root. */
|
|
29
|
+
root: string;
|
|
30
|
+
/** Stable hash of the root and detected, non-secret facts. */
|
|
31
|
+
fingerprint: string;
|
|
32
|
+
/** Supported language ecosystems found at the root. */
|
|
33
|
+
languages: Array<"typescript" | "python">;
|
|
34
|
+
/** Package managers identified from declarations or lockfiles. */
|
|
35
|
+
packageManagers: Array<"bun" | "npm" | "pnpm" | "yarn" | "uv" | "poetry" | "pip">;
|
|
36
|
+
/** Known frameworks identified from manifest dependency names. */
|
|
37
|
+
frameworks: Array<"nextjs" | "nestjs" | "express" | "fastapi" | "django" | "flask" | "vercel-ai-sdk">;
|
|
38
|
+
/** Language ecosystems with an existing Hue dependency. */
|
|
39
|
+
hue: "absent" | "typescript" | "python" | "multiple";
|
|
40
|
+
/** Language ecosystems with an existing OpenTelemetry dependency. */
|
|
41
|
+
openTelemetry: "absent" | "typescript" | "python" | "multiple";
|
|
42
|
+
}
|
|
43
|
+
/** Project detection completed. */
|
|
44
|
+
export interface ProjectDetectedEvent extends EventBase<"project.detected"> {
|
|
45
|
+
/** Bounded static detection result. */
|
|
46
|
+
project: SetupProjectDetection;
|
|
47
|
+
}
|
|
48
|
+
/** A bounded local setup plan. */
|
|
49
|
+
export interface SetupPlan {
|
|
50
|
+
/** Ordered setup step names. */
|
|
51
|
+
steps: Array<"detect-project" | "configure-telemetry" | "verify-receipt" | "claim-project">;
|
|
52
|
+
/** Whether this plan is permitted to change project files. */
|
|
53
|
+
mutatesProject: boolean;
|
|
54
|
+
/** Whether completion ultimately requires a backend adapter. */
|
|
55
|
+
backendRequired: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** The deterministic setup plan is ready. */
|
|
58
|
+
export interface PlanReadyEvent extends EventBase<"plan.ready"> {
|
|
59
|
+
/** Deterministic plan for this project. */
|
|
60
|
+
plan: SetupPlan;
|
|
61
|
+
}
|
|
62
|
+
/** A named setup step began. */
|
|
63
|
+
export interface StepStartedEvent extends EventBase<"step.started"> {
|
|
64
|
+
/** Step that began. */
|
|
65
|
+
step: SetupPlan["steps"][number];
|
|
66
|
+
}
|
|
67
|
+
/** A named setup step completed. */
|
|
68
|
+
export interface StepCompletedEvent extends EventBase<"step.completed"> {
|
|
69
|
+
/** Step that completed. */
|
|
70
|
+
step: SetupPlan["steps"][number];
|
|
71
|
+
/** Observable result of the step. */
|
|
72
|
+
outcome: "unchanged" | "changed" | "verified" | "skipped";
|
|
73
|
+
}
|
|
74
|
+
/** A future mutating adapter changed a project file. */
|
|
75
|
+
export interface FileChangedEvent extends EventBase<"file.changed"> {
|
|
76
|
+
/** Project-relative changed path. */
|
|
77
|
+
path: string;
|
|
78
|
+
/** Whether the adapter created or updated the path. */
|
|
79
|
+
change: "created" | "updated";
|
|
80
|
+
}
|
|
81
|
+
/** A secret-free diagnostic safe for terminals and transcripts. */
|
|
82
|
+
export interface DiagnosticEvent extends EventBase<"diagnostic"> {
|
|
83
|
+
/** Diagnostic severity. */
|
|
84
|
+
level: "info" | "warning" | "error";
|
|
85
|
+
/** Stable machine-readable diagnostic code. */
|
|
86
|
+
code: string;
|
|
87
|
+
/** Secret-free human-readable explanation. */
|
|
88
|
+
message: string;
|
|
89
|
+
}
|
|
90
|
+
/** Progress needs an explicit local or human action. */
|
|
91
|
+
export interface ActionRequiredEvent extends EventBase<"action.required"> {
|
|
92
|
+
/** Kind of action needed to continue. */
|
|
93
|
+
action: "claim-project" | "configure" | "run-instrumented-request" | "open-claim-url" | "capture-approved-content" | "review-content-approved-trace";
|
|
94
|
+
/** Secret-free explanation of the action. */
|
|
95
|
+
message: string;
|
|
96
|
+
/** Optional command the caller may run. */
|
|
97
|
+
command?: string;
|
|
98
|
+
/** Optional HTTPS destination for a user action. */
|
|
99
|
+
url?: string;
|
|
100
|
+
}
|
|
101
|
+
/** A backend adapter created an anonymous trial. */
|
|
102
|
+
export interface TrialCreatedEvent extends EventBase<"trial.created"> {
|
|
103
|
+
/** Non-secret backend trial identifier. */
|
|
104
|
+
trialId: string;
|
|
105
|
+
/** ISO-8601 trial expiration. */
|
|
106
|
+
expiresAt: string;
|
|
107
|
+
}
|
|
108
|
+
/** A backend adapter verified instrumentation-only receipt evidence. */
|
|
109
|
+
export interface ReceiptVerifiedEvent extends EventBase<"receipt.verified"> {
|
|
110
|
+
/** Non-secret receipt identifier. */
|
|
111
|
+
receiptId: string;
|
|
112
|
+
/** Verified lowercase OpenTelemetry trace identifier; this does not prove content approval. */
|
|
113
|
+
traceId: string;
|
|
114
|
+
}
|
|
115
|
+
/** The anonymous project can be claimed by a person. */
|
|
116
|
+
export interface ClaimRequiredEvent extends EventBase<"claim.required"> {
|
|
117
|
+
/** Non-secret claim identifier. */
|
|
118
|
+
claimId: string;
|
|
119
|
+
/** User-facing claim destination; never persisted in setup checkpoints. */
|
|
120
|
+
url: string;
|
|
121
|
+
}
|
|
122
|
+
/** A backend adapter confirmed that the project was claimed. */
|
|
123
|
+
export interface ClaimCompletedEvent extends EventBase<"claim.completed"> {
|
|
124
|
+
/** Non-secret completed claim identifier. */
|
|
125
|
+
claimId: string;
|
|
126
|
+
}
|
|
127
|
+
/** Exactly one successful terminal installer event ends a JSONL setup-session invocation. */
|
|
128
|
+
export interface RunCompletedEvent extends EventBase<"run.completed"> {
|
|
129
|
+
/** Terminal invocation result. */
|
|
130
|
+
outcome: "ready" | "action_required" | "unchanged";
|
|
131
|
+
/** Whether resumable state exists after the invocation. */
|
|
132
|
+
checkpointed: boolean;
|
|
133
|
+
}
|
|
134
|
+
/** Exactly one failed terminal installer event ends a JSONL setup-session invocation. */
|
|
135
|
+
export interface RunFailedEvent extends EventBase<"run.failed"> {
|
|
136
|
+
/** Stable machine-readable failure code. */
|
|
137
|
+
code: string;
|
|
138
|
+
/** Sanitized failure explanation. */
|
|
139
|
+
message: string;
|
|
140
|
+
/** Whether a later `resume` can safely continue. */
|
|
141
|
+
resumable: boolean;
|
|
142
|
+
}
|
|
143
|
+
/** Version 1 setup JSONL event union. */
|
|
144
|
+
export type SetupEvent = RunStartedEvent | ProjectDetectedEvent | PlanReadyEvent | StepStartedEvent | StepCompletedEvent | FileChangedEvent | DiagnosticEvent | ActionRequiredEvent | TrialCreatedEvent | ReceiptVerifiedEvent | ClaimRequiredEvent | ClaimCompletedEvent | RunCompletedEvent | RunFailedEvent;
|
|
145
|
+
export {};
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Local, resumable installer setup-session contracts used by the `hue` command. */
|
|
2
|
+
export { SETUP_EVENT_CONTRACT_VERSION, type ActionRequiredEvent, type ClaimCompletedEvent, type ClaimRequiredEvent, type DiagnosticEvent, type FileChangedEvent, type PlanReadyEvent, type ProjectDetectedEvent, type ReceiptVerifiedEvent, type RunCompletedEvent, type RunFailedEvent, type RunStartedEvent, type SetupEvent, type SetupEventName, type SetupPlan, type SetupProjectDetection, type StepCompletedEvent, type StepStartedEvent, type TrialCreatedEvent, } from "./setup/types.js";
|
|
3
|
+
export { createInitialSetupState, transitionSetup, type SetupEffect, type SetupMachineInput, type SetupMachineState, type SetupTransition, } from "./setup/machine.js";
|
|
4
|
+
export { runSetup, type SetupBackendAdapter, type SetupBackendClaim, type SetupBackendReceipt, type SetupBackendTrial, type SetupCheckpointAdapter, type SetupProjectAdapter, type SetupRunOptions, type SetupRunResult, } from "./setup/runner.js";
|
|
5
|
+
export { detectSetupProject } from "./setup/detect.js";
|
|
6
|
+
export { renderHumanEvent, renderJsonlEvent, renderPlainEvent, selectSetupOutputMode, type SetupOutputMode, } from "./setup/render.js";
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Local, resumable installer setup-session contracts used by the `hue` command. */
|
|
2
|
+
export { SETUP_EVENT_CONTRACT_VERSION, } from "./setup/types.js";
|
|
3
|
+
export { createInitialSetupState, transitionSetup, } from "./setup/machine.js";
|
|
4
|
+
export { runSetup, } from "./setup/runner.js";
|
|
5
|
+
export { detectSetupProject } from "./setup/detect.js";
|
|
6
|
+
export { renderHumanEvent, renderJsonlEvent, renderPlainEvent, selectSetupOutputMode, } from "./setup/render.js";
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Package version shared by the instrumentation scope and the export User-Agent. */
|
|
2
|
-
export declare const sdkVersion = "0.3.
|
|
2
|
+
export declare const sdkVersion = "0.3.1";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hue-run/sdk",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|
],
|
|
30
30
|
"files": [
|
|
31
31
|
"dist",
|
|
32
|
+
"CLI.md",
|
|
33
|
+
"setup-events.schema.json",
|
|
32
34
|
"README.md",
|
|
33
35
|
"EVALUATIONS.md",
|
|
34
36
|
"ENVIRONMENTS.md",
|
|
@@ -36,6 +38,9 @@
|
|
|
36
38
|
"LICENSE"
|
|
37
39
|
],
|
|
38
40
|
"type": "module",
|
|
41
|
+
"bin": {
|
|
42
|
+
"hue": "./dist/setup/cli.js"
|
|
43
|
+
},
|
|
39
44
|
"sideEffects": [
|
|
40
45
|
"./dist/evals/schema-worker.js"
|
|
41
46
|
],
|
|
@@ -65,6 +70,12 @@
|
|
|
65
70
|
"import": "./dist/managed.js",
|
|
66
71
|
"default": "./dist/managed.js"
|
|
67
72
|
},
|
|
73
|
+
"./setup": {
|
|
74
|
+
"types": "./dist/setup.d.ts",
|
|
75
|
+
"import": "./dist/setup.js",
|
|
76
|
+
"default": "./dist/setup.js"
|
|
77
|
+
},
|
|
78
|
+
"./setup-events.schema.json": "./setup-events.schema.json",
|
|
68
79
|
"./package.json": "./package.json"
|
|
69
80
|
},
|
|
70
81
|
"scripts": {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://hue.run/schemas/setup-events-v1.json",
|
|
4
|
+
"title": "Hue setup-session installer event version 1",
|
|
5
|
+
"description": "Installer lifecycle events only. run.* events are setup-session invocations, not Hue Runs.",
|
|
6
|
+
"oneOf": [
|
|
7
|
+
{ "$ref": "#/$defs/run.started" },
|
|
8
|
+
{ "$ref": "#/$defs/project.detected" },
|
|
9
|
+
{ "$ref": "#/$defs/plan.ready" },
|
|
10
|
+
{ "$ref": "#/$defs/step.started" },
|
|
11
|
+
{ "$ref": "#/$defs/step.completed" },
|
|
12
|
+
{ "$ref": "#/$defs/file.changed" },
|
|
13
|
+
{ "$ref": "#/$defs/diagnostic" },
|
|
14
|
+
{ "$ref": "#/$defs/action.required" },
|
|
15
|
+
{ "$ref": "#/$defs/trial.created" },
|
|
16
|
+
{ "$ref": "#/$defs/receipt.verified" },
|
|
17
|
+
{ "$ref": "#/$defs/claim.required" },
|
|
18
|
+
{ "$ref": "#/$defs/claim.completed" },
|
|
19
|
+
{ "$ref": "#/$defs/run.completed" },
|
|
20
|
+
{ "$ref": "#/$defs/run.failed" }
|
|
21
|
+
],
|
|
22
|
+
"$defs": {
|
|
23
|
+
"base": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["contractVersion", "event", "runId", "sequence", "timestamp"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"contractVersion": { "const": 1 },
|
|
28
|
+
"event": { "type": "string", "maxLength": 40 },
|
|
29
|
+
"runId": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,80}$" },
|
|
30
|
+
"sequence": { "type": "integer", "minimum": 1, "maximum": 10000 },
|
|
31
|
+
"timestamp": { "type": "string", "format": "date-time", "maxLength": 40 }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"step": { "enum": ["detect-project", "configure-telemetry", "verify-receipt", "claim-project"] },
|
|
35
|
+
"text": { "type": "string", "minLength": 1, "maxLength": 1000 },
|
|
36
|
+
"identifier": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,128}$" },
|
|
37
|
+
"plan": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"additionalProperties": false,
|
|
40
|
+
"required": ["steps", "mutatesProject", "backendRequired"],
|
|
41
|
+
"properties": {
|
|
42
|
+
"steps": { "type": "array", "items": { "$ref": "#/$defs/step" }, "minItems": 1, "maxItems": 10, "uniqueItems": true },
|
|
43
|
+
"mutatesProject": { "type": "boolean" },
|
|
44
|
+
"backendRequired": { "type": "boolean" }
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"project": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"required": ["root", "fingerprint", "languages", "packageManagers", "frameworks", "hue", "openTelemetry"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"root": { "type": "string", "minLength": 1, "maxLength": 4096 },
|
|
53
|
+
"fingerprint": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
54
|
+
"languages": { "type": "array", "items": { "enum": ["typescript", "python"] }, "maxItems": 2, "uniqueItems": true },
|
|
55
|
+
"packageManagers": { "type": "array", "items": { "enum": ["bun", "npm", "pnpm", "yarn", "uv", "poetry", "pip"] }, "maxItems": 7, "uniqueItems": true },
|
|
56
|
+
"frameworks": { "type": "array", "items": { "enum": ["nextjs", "nestjs", "express", "fastapi", "django", "flask", "vercel-ai-sdk"] }, "maxItems": 7, "uniqueItems": true },
|
|
57
|
+
"hue": { "enum": ["absent", "typescript", "python", "multiple"] },
|
|
58
|
+
"openTelemetry": { "enum": ["absent", "typescript", "python", "multiple"] }
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"run.started": {
|
|
62
|
+
"type": "object",
|
|
63
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["command", "mode", "resumed"], "properties": { "event": { "const": "run.started" }, "command": { "enum": ["setup", "resume", "status", "claim"] }, "mode": { "enum": ["human", "plain", "jsonl"] }, "resumed": { "type": "boolean" } } }],
|
|
64
|
+
"unevaluatedProperties": false
|
|
65
|
+
},
|
|
66
|
+
"project.detected": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["project"], "properties": { "event": { "const": "project.detected" }, "project": { "$ref": "#/$defs/project" } } }],
|
|
69
|
+
"unevaluatedProperties": false
|
|
70
|
+
},
|
|
71
|
+
"plan.ready": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["plan"], "properties": { "event": { "const": "plan.ready" }, "plan": { "$ref": "#/$defs/plan" } } }],
|
|
74
|
+
"unevaluatedProperties": false
|
|
75
|
+
},
|
|
76
|
+
"step.started": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["step"], "properties": { "event": { "const": "step.started" }, "step": { "$ref": "#/$defs/step" } } }],
|
|
79
|
+
"unevaluatedProperties": false
|
|
80
|
+
},
|
|
81
|
+
"step.completed": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["step", "outcome"], "properties": { "event": { "const": "step.completed" }, "step": { "$ref": "#/$defs/step" }, "outcome": { "enum": ["unchanged", "changed", "verified", "skipped"] } } }],
|
|
84
|
+
"unevaluatedProperties": false
|
|
85
|
+
},
|
|
86
|
+
"file.changed": {
|
|
87
|
+
"type": "object",
|
|
88
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["path", "change"], "properties": { "event": { "const": "file.changed" }, "path": { "type": "string", "minLength": 1, "maxLength": 4096 }, "change": { "enum": ["created", "updated"] } } }],
|
|
89
|
+
"unevaluatedProperties": false
|
|
90
|
+
},
|
|
91
|
+
"diagnostic": {
|
|
92
|
+
"type": "object",
|
|
93
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["level", "code", "message"], "properties": { "event": { "const": "diagnostic" }, "level": { "enum": ["info", "warning", "error"] }, "code": { "type": "string", "pattern": "^[a-z][a-z0-9_.-]{0,79}$" }, "message": { "$ref": "#/$defs/text" } } }],
|
|
94
|
+
"unevaluatedProperties": false
|
|
95
|
+
},
|
|
96
|
+
"action.required": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["action", "message"], "properties": { "event": { "const": "action.required" }, "action": { "enum": ["claim-project", "configure", "run-instrumented-request", "open-claim-url", "capture-approved-content", "review-content-approved-trace"] }, "message": { "$ref": "#/$defs/text" }, "command": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "type": "string", "format": "uri", "maxLength": 2048 } } }],
|
|
99
|
+
"unevaluatedProperties": false
|
|
100
|
+
},
|
|
101
|
+
"trial.created": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"description": "An anonymous setup trial hard-pinned to trial_metadata_v1.",
|
|
104
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["trialId", "expiresAt"], "properties": { "event": { "const": "trial.created" }, "trialId": { "$ref": "#/$defs/identifier" }, "expiresAt": { "type": "string", "format": "date-time", "maxLength": 40 } } }],
|
|
105
|
+
"unevaluatedProperties": false
|
|
106
|
+
},
|
|
107
|
+
"receipt.verified": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"description": "Instrumentation-only proof for an anonymous trace; not evidence of content approval or Scenario suitability.",
|
|
110
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["receiptId", "traceId"], "properties": { "event": { "const": "receipt.verified" }, "receiptId": { "$ref": "#/$defs/identifier" }, "traceId": { "type": "string", "pattern": "^[a-f0-9]{32}$" } } }],
|
|
111
|
+
"unevaluatedProperties": false
|
|
112
|
+
},
|
|
113
|
+
"claim.required": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["claimId", "url"], "properties": { "event": { "const": "claim.required" }, "claimId": { "$ref": "#/$defs/identifier" }, "url": { "type": "string", "format": "uri", "maxLength": 2048 } } }],
|
|
116
|
+
"unevaluatedProperties": false
|
|
117
|
+
},
|
|
118
|
+
"claim.completed": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["claimId"], "properties": { "event": { "const": "claim.completed" }, "claimId": { "$ref": "#/$defs/identifier" } } }],
|
|
121
|
+
"unevaluatedProperties": false
|
|
122
|
+
},
|
|
123
|
+
"run.completed": {
|
|
124
|
+
"type": "object",
|
|
125
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["outcome", "checkpointed"], "properties": { "event": { "const": "run.completed" }, "outcome": { "enum": ["ready", "action_required", "unchanged"] }, "checkpointed": { "type": "boolean" } } }],
|
|
126
|
+
"unevaluatedProperties": false
|
|
127
|
+
},
|
|
128
|
+
"run.failed": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"allOf": [{ "$ref": "#/$defs/base" }, { "type": "object", "required": ["code", "message", "resumable"], "properties": { "event": { "const": "run.failed" }, "code": { "type": "string", "pattern": "^[a-z][a-z0-9_.-]{0,79}$" }, "message": { "$ref": "#/$defs/text" }, "resumable": { "type": "boolean" } } }],
|
|
131
|
+
"unevaluatedProperties": false
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|