@llblab/pi-actors 0.42.3 → 0.43.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/AGENTS.md +121 -175
- package/CHANGELOG.md +12 -0
- package/README.md +113 -276
- package/dist/fixtures/protocol/control-endpoint.json +6 -0
- package/dist/fixtures/protocol/control-record.json +9 -0
- package/dist/fixtures/protocol/recipe-summary.json +4 -12
- package/dist/fixtures/protocol/trace-event.json +9 -0
- package/dist/lib/async-runs.d.ts +14 -38
- package/dist/lib/async-runs.js +158 -108
- package/dist/lib/control.d.ts +12 -0
- package/dist/lib/control.js +84 -0
- package/dist/lib/execution-sessions.d.ts +17 -0
- package/dist/lib/execution-sessions.js +85 -0
- package/dist/lib/file-state.d.ts +1 -0
- package/dist/lib/file-state.js +17 -5
- package/dist/lib/inspector-actions.d.ts +2 -2
- package/dist/lib/inspector-actions.js +2 -2
- package/dist/lib/inspector-command.js +3 -3
- package/dist/lib/inspector-overlay.d.ts +52 -70
- package/dist/lib/inspector-overlay.js +532 -905
- package/dist/lib/inspector.d.ts +3 -71
- package/dist/lib/inspector.js +19 -665
- package/dist/lib/limits.d.ts +4 -2
- package/dist/lib/limits.js +4 -2
- package/dist/lib/observability.d.ts +16 -16
- package/dist/lib/observability.js +43 -82
- package/dist/lib/prompts.d.ts +1 -1
- package/dist/lib/prompts.js +2 -2
- package/dist/lib/recipe-control.d.ts +7 -0
- package/dist/lib/recipe-control.js +39 -0
- package/dist/lib/recipes-discovery.js +2 -0
- package/dist/lib/recipes-references.d.ts +1 -14
- package/dist/lib/recipes-references.js +6 -21
- package/dist/lib/review-projection.js +1 -5
- package/dist/lib/run-ui-runtime.js +2 -2
- package/dist/lib/runs-control-delivery.d.ts +21 -0
- package/dist/lib/runs-control-delivery.js +127 -0
- package/dist/lib/runs-controls.d.ts +35 -0
- package/dist/lib/runs-controls.js +144 -0
- package/dist/lib/runs-retention.d.ts +7 -0
- package/dist/lib/runs-retention.js +27 -3
- package/dist/lib/runs-start.js +4 -2
- package/dist/lib/runs-status.js +11 -6
- package/dist/lib/runs-trace.d.ts +24 -0
- package/dist/lib/runs-trace.js +98 -0
- package/dist/lib/runtime-notifier.d.ts +1 -1
- package/dist/lib/runtime-notifier.js +1 -1
- package/dist/lib/tools-inspect.d.ts +3 -3
- package/dist/lib/tools-inspect.js +203 -708
- package/dist/lib/tools-local.js +2 -10
- package/dist/lib/tools-message.d.ts +7 -7
- package/dist/lib/tools-message.js +95 -396
- package/dist/lib/tools-response.d.ts +1 -4
- package/dist/lib/tools-response.js +5 -39
- package/dist/lib/tools-spawn.js +16 -28
- package/dist/lib/tools.js +1 -2
- package/dist/lib/trace-projection.d.ts +22 -0
- package/dist/lib/trace-projection.js +165 -0
- package/dist/recipes/draft-review.json +0 -10
- package/dist/recipes/lens-swarm.json +0 -14
- package/dist/recipes/music-player.json +10 -19
- package/dist/recipes/pipeline-architect-coordinator.json +0 -11
- package/dist/recipes/pipeline-artifact-bundle.json +1 -22
- package/dist/recipes/pipeline-artifact-report.json +1 -18
- package/dist/recipes/pipeline-artifact-write.json +1 -18
- package/dist/recipes/pipeline-async-run-ops.json +0 -12
- package/dist/recipes/pipeline-checkpoint-continuation.json +0 -14
- package/dist/recipes/pipeline-development-tasking.json +0 -12
- package/dist/recipes/pipeline-docs-maintenance.json +0 -12
- package/dist/recipes/pipeline-media-library.json +0 -12
- package/dist/recipes/pipeline-quorum-review.json +0 -12
- package/dist/recipes/pipeline-release-readiness.json +0 -12
- package/dist/recipes/pipeline-release-summary.json +0 -12
- package/dist/recipes/pipeline-repo-health.json +0 -12
- package/dist/recipes/pipeline-research-synthesis.json +0 -11
- package/dist/recipes/pipeline-review-readiness.json +0 -12
- package/dist/recipes/resource-locker.json +27 -0
- package/dist/recipes/subagent-artifact.json +0 -9
- package/dist/recipes/subagent-checkpoint.json +0 -10
- package/dist/recipes/subagent-conflict-report.json +0 -11
- package/dist/recipes/subagent-contradiction-map.json +0 -11
- package/dist/recipes/subagent-critic.json +0 -11
- package/dist/recipes/subagent-evidence-map.json +0 -11
- package/dist/recipes/subagent-followup.json +0 -10
- package/dist/recipes/subagent-judge.json +0 -11
- package/dist/recipes/subagent-merge.json +0 -11
- package/dist/recipes/subagent-normalize.json +0 -11
- package/dist/recipes/subagent-plan.json +0 -11
- package/dist/recipes/subagent-preflight.json +0 -11
- package/dist/recipes/subagent-prompt.json +0 -10
- package/dist/recipes/subagent-quorum.json +0 -10
- package/dist/recipes/subagent-review-coordinator.json +0 -14
- package/dist/recipes/subagent-review.json +0 -11
- package/dist/recipes/subagent-task-card.json +0 -11
- package/dist/recipes/subagent-tools.json +0 -10
- package/dist/recipes/subagent-verify.json +0 -11
- package/dist/recipes/subagents-prompts.json +0 -10
- package/dist/recipes/tool-review.json +0 -10
- package/dist/scripts/async-runner.mjs +25 -25
- package/dist/scripts/conformance.mjs +4 -2
- package/dist/scripts/locker.mjs +200 -66
- package/dist/scripts/music-player.mjs +159 -150
- package/dist/scripts/recipe-utils.mjs +6 -96
- package/dist/scripts/release-gates.mjs +60 -0
- package/dist/scripts/validate-recipe.mjs +3 -53
- package/dist/skills/actors/SKILL.md +53 -266
- package/dist/skills/swarm/SKILL.md +11 -33
- package/docs/0.43-baseline.md +44 -0
- package/docs/README.md +3 -3
- package/docs/actor-inspector.md +26 -64
- package/docs/actors-deep-reference.md +92 -50
- package/docs/async-runs.md +81 -328
- package/docs/command-templates.md +2 -2
- package/docs/component-recipes.md +30 -133
- package/docs/recipe-library.md +57 -182
- package/docs/task-first-recipes.md +10 -12
- package/docs/template-recipes.md +76 -289
- package/docs/tool-registry.md +41 -161
- package/fixtures/protocol/control-endpoint.json +6 -0
- package/fixtures/protocol/control-record.json +9 -0
- package/fixtures/protocol/recipe-summary.json +4 -12
- package/fixtures/protocol/trace-event.json +9 -0
- package/lib/async-runs.ts +202 -201
- package/lib/control.ts +102 -0
- package/lib/execution-sessions.ts +111 -0
- package/lib/file-state.ts +17 -4
- package/lib/inspector-actions.ts +2 -2
- package/lib/inspector-command.ts +3 -3
- package/lib/inspector-overlay.ts +577 -1121
- package/lib/inspector.ts +46 -979
- package/lib/limits.ts +4 -2
- package/lib/observability.ts +60 -101
- package/lib/prompts.ts +2 -2
- package/lib/recipe-control.ts +45 -0
- package/lib/recipes-discovery.ts +2 -0
- package/lib/recipes-references.ts +9 -45
- package/lib/review-projection.ts +1 -5
- package/lib/run-ui-runtime.ts +2 -2
- package/lib/runs-control-delivery.ts +181 -0
- package/lib/runs-controls.ts +204 -0
- package/lib/runs-retention.ts +38 -3
- package/lib/runs-start.ts +4 -2
- package/lib/runs-status.ts +11 -6
- package/lib/runs-trace.ts +132 -0
- package/lib/runtime-notifier.ts +1 -1
- package/lib/tools-inspect.ts +240 -901
- package/lib/tools-local.ts +2 -12
- package/lib/tools-message.ts +112 -519
- package/lib/tools-response.ts +5 -52
- package/lib/tools-spawn.ts +16 -32
- package/lib/tools.ts +1 -2
- package/lib/trace-projection.ts +221 -0
- package/package.json +2 -1
- package/recipes/draft-review.json +0 -10
- package/recipes/lens-swarm.json +0 -14
- package/recipes/music-player.json +10 -19
- package/recipes/pipeline-architect-coordinator.json +0 -11
- package/recipes/pipeline-artifact-bundle.json +1 -22
- package/recipes/pipeline-artifact-report.json +1 -18
- package/recipes/pipeline-artifact-write.json +1 -18
- package/recipes/pipeline-async-run-ops.json +0 -12
- package/recipes/pipeline-checkpoint-continuation.json +0 -14
- package/recipes/pipeline-development-tasking.json +0 -12
- package/recipes/pipeline-docs-maintenance.json +0 -12
- package/recipes/pipeline-media-library.json +0 -12
- package/recipes/pipeline-quorum-review.json +0 -12
- package/recipes/pipeline-release-readiness.json +0 -12
- package/recipes/pipeline-release-summary.json +0 -12
- package/recipes/pipeline-repo-health.json +0 -12
- package/recipes/pipeline-research-synthesis.json +0 -11
- package/recipes/pipeline-review-readiness.json +0 -12
- package/recipes/resource-locker.json +27 -0
- package/recipes/subagent-artifact.json +0 -9
- package/recipes/subagent-checkpoint.json +0 -10
- package/recipes/subagent-conflict-report.json +0 -11
- package/recipes/subagent-contradiction-map.json +0 -11
- package/recipes/subagent-critic.json +0 -11
- package/recipes/subagent-evidence-map.json +0 -11
- package/recipes/subagent-followup.json +0 -10
- package/recipes/subagent-judge.json +0 -11
- package/recipes/subagent-merge.json +0 -11
- package/recipes/subagent-normalize.json +0 -11
- package/recipes/subagent-plan.json +0 -11
- package/recipes/subagent-preflight.json +0 -11
- package/recipes/subagent-prompt.json +0 -10
- package/recipes/subagent-quorum.json +0 -10
- package/recipes/subagent-review-coordinator.json +0 -14
- package/recipes/subagent-review.json +0 -11
- package/recipes/subagent-task-card.json +0 -11
- package/recipes/subagent-tools.json +0 -10
- package/recipes/subagent-verify.json +0 -11
- package/recipes/subagents-prompts.json +0 -10
- package/recipes/tool-review.json +0 -10
- package/scripts/async-runner.mjs +25 -25
- package/scripts/conformance.mjs +4 -2
- package/scripts/locker.mjs +200 -66
- package/scripts/music-player.mjs +159 -150
- package/scripts/recipe-utils.mjs +6 -96
- package/scripts/release-gates.mjs +60 -0
- package/scripts/validate-recipe.mjs +3 -53
- package/skills/actors/SKILL.md +53 -266
- package/skills/swarm/SKILL.md +11 -33
- package/dist/fixtures/protocol/actor-message-branch.json +0 -13
- package/dist/fixtures/protocol/mailbox-contract.json +0 -15
- package/dist/fixtures/protocol/room-message.json +0 -11
- package/dist/fixtures/protocol/room-roster.json +0 -11
- package/dist/fixtures/protocol/run-inbox-message.json +0 -9
- package/dist/fixtures/protocol/run-outbox-event.json +0 -9
- package/dist/lib/mailbox-loop.d.ts +0 -41
- package/dist/lib/mailbox-loop.js +0 -60
- package/dist/lib/messages.d.ts +0 -25
- package/dist/lib/messages.js +0 -122
- package/dist/lib/rooms.d.ts +0 -104
- package/dist/lib/rooms.js +0 -647
- package/dist/lib/runs-mailbox.d.ts +0 -25
- package/dist/lib/runs-mailbox.js +0 -146
- package/dist/lib/runs-messages.d.ts +0 -15
- package/dist/lib/runs-messages.js +0 -179
- package/dist/lib/runs-outbox.d.ts +0 -41
- package/dist/lib/runs-outbox.js +0 -87
- package/dist/lib/tools-mailbox.d.ts +0 -8
- package/dist/lib/tools-mailbox.js +0 -48
- package/dist/recipes/actor-worker.json +0 -39
- package/dist/recipes/coordinator-locker.json +0 -45
- package/dist/recipes/locker.json +0 -45
- package/dist/recipes/pipeline-room-swarm.json +0 -50
- package/dist/recipes/subagent-message.json +0 -32
- package/dist/recipes/utility-actor-message.json +0 -23
- package/dist/scripts/actor-worker.mjs +0 -214
- package/dist/scripts/coordinator.mjs +0 -799
- package/docs/actor-messages.md +0 -225
- package/fixtures/protocol/actor-message-branch.json +0 -13
- package/fixtures/protocol/mailbox-contract.json +0 -15
- package/fixtures/protocol/room-message.json +0 -11
- package/fixtures/protocol/room-roster.json +0 -11
- package/fixtures/protocol/run-inbox-message.json +0 -9
- package/fixtures/protocol/run-outbox-event.json +0 -9
- package/lib/mailbox-loop.ts +0 -144
- package/lib/messages.ts +0 -151
- package/lib/rooms.ts +0 -939
- package/lib/runs-mailbox.ts +0 -208
- package/lib/runs-messages.ts +0 -252
- package/lib/runs-outbox.ts +0 -144
- package/lib/tools-mailbox.ts +0 -56
- package/recipes/actor-worker.json +0 -39
- package/recipes/coordinator-locker.json +0 -45
- package/recipes/locker.json +0 -45
- package/recipes/pipeline-room-swarm.json +0 -50
- package/recipes/subagent-message.json +0 -32
- package/recipes/utility-actor-message.json +0 -23
- package/scripts/actor-worker.mjs +0 -214
- package/scripts/coordinator.mjs +0 -799
package/scripts/recipe-utils.mjs
CHANGED
|
@@ -26,7 +26,6 @@ function usage() {
|
|
|
26
26
|
recipe-utils.mjs changelog-section <file> <version>
|
|
27
27
|
recipe-utils.mjs artifact-manifest <artifact-path> <title> <status> [summary]
|
|
28
28
|
recipe-utils.mjs artifact-write <artifact-path> [create|overwrite|append]
|
|
29
|
-
recipe-utils.mjs actor-message <type> [to] [from] [summary] [metadata-json] [correlation-id] [reply-to]
|
|
30
29
|
recipe-utils.mjs package-summary <package-json>
|
|
31
30
|
recipe-utils.mjs skill-summary <skill-md> [package-json]`);
|
|
32
31
|
}
|
|
@@ -36,41 +35,6 @@ function fail(message) {
|
|
|
36
35
|
process.exit(1);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
const ADDRESS_PATTERN = /^[A-Za-z0-9_.-]+$/;
|
|
40
|
-
const MESSAGE_TYPE_PATTERN = /^[A-Za-z][A-Za-z0-9_.:-]*$/;
|
|
41
|
-
function assertToken(value, label) {
|
|
42
|
-
const normalized = String(value ?? "").trim();
|
|
43
|
-
if (!normalized) fail(`${label} is required`);
|
|
44
|
-
if (!ADDRESS_PATTERN.test(normalized))
|
|
45
|
-
fail(`${label} contains unsupported characters: ${value}`);
|
|
46
|
-
return normalized;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function validateActorAddress(address, label) {
|
|
50
|
-
const value = String(address ?? "").trim();
|
|
51
|
-
if (value === "coordinator") return value;
|
|
52
|
-
const separator = value.indexOf(":");
|
|
53
|
-
if (separator < 0) fail(`${label} must include an actor kind: ${address}`);
|
|
54
|
-
const kind = value.slice(0, separator);
|
|
55
|
-
const rest = value.slice(separator + 1);
|
|
56
|
-
if (kind === "branch") {
|
|
57
|
-
const [run, branch, ...extra] = rest.split("/");
|
|
58
|
-
if (extra.length > 0)
|
|
59
|
-
fail(`${label} branch address has too many parts: ${address}`);
|
|
60
|
-
return `branch:${assertToken(run, `${label} branch run`)}/${assertToken(branch, `${label} branch id`)}`;
|
|
61
|
-
}
|
|
62
|
-
if (["run", "session", "tool"].includes(kind))
|
|
63
|
-
return `${kind}:${assertToken(rest, label)}`;
|
|
64
|
-
fail(`${label} has unsupported actor kind: ${kind}`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function validateMessageType(type) {
|
|
68
|
-
const value = String(type ?? "").trim();
|
|
69
|
-
if (!MESSAGE_TYPE_PATTERN.test(value))
|
|
70
|
-
fail(`Invalid actor message type: ${type}`);
|
|
71
|
-
return value;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
38
|
function walkFiles(dir, maxDepth = 2, depth = 0, out = []) {
|
|
75
39
|
if (depth > maxDepth || !existsSync(dir)) return out;
|
|
76
40
|
for (const entry of readdirSync(dir)) {
|
|
@@ -172,7 +136,7 @@ function runOpsSnapshot(
|
|
|
172
136
|
rootValue.replace(/^~(?=\/|$)/, process.env.HOME ?? "~"),
|
|
173
137
|
);
|
|
174
138
|
const inspectedRun = String(runIdValue || "music");
|
|
175
|
-
const
|
|
139
|
+
const traceFile = join(root, inspectedRun, "trace.jsonl");
|
|
176
140
|
const staleMs = Number(staleMinutesValue) * 60 * 1000;
|
|
177
141
|
const now = Date.now();
|
|
178
142
|
const recommendations = runs.flatMap((run) => {
|
|
@@ -186,10 +150,9 @@ function runOpsSnapshot(
|
|
|
186
150
|
{
|
|
187
151
|
run: run.run,
|
|
188
152
|
reason: "running-stale",
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
body: "stop",
|
|
153
|
+
suggested_inspect: {
|
|
154
|
+
target: `run:${run.run}`,
|
|
155
|
+
view: "control",
|
|
193
156
|
},
|
|
194
157
|
},
|
|
195
158
|
];
|
|
@@ -199,7 +162,7 @@ function runOpsSnapshot(
|
|
|
199
162
|
{
|
|
200
163
|
run: run.run,
|
|
201
164
|
reason: `terminal-${run.status}`,
|
|
202
|
-
suggested_inspect: { target: `run:${run.run}`, view: "
|
|
165
|
+
suggested_inspect: { target: `run:${run.run}`, view: "trace" },
|
|
203
166
|
},
|
|
204
167
|
];
|
|
205
168
|
}
|
|
@@ -210,7 +173,7 @@ function runOpsSnapshot(
|
|
|
210
173
|
{
|
|
211
174
|
runs,
|
|
212
175
|
inspectedRun,
|
|
213
|
-
|
|
176
|
+
trace: tailJsonl(traceFile, linesValue),
|
|
214
177
|
recommendations,
|
|
215
178
|
},
|
|
216
179
|
null,
|
|
@@ -291,57 +254,6 @@ function artifactWrite(pathValue, mode = "create") {
|
|
|
291
254
|
);
|
|
292
255
|
}
|
|
293
256
|
|
|
294
|
-
function actorMessage(
|
|
295
|
-
type = "event",
|
|
296
|
-
to = "coordinator",
|
|
297
|
-
from = "run:{run_id}",
|
|
298
|
-
summary = "",
|
|
299
|
-
metadataValue = "",
|
|
300
|
-
correlationId = "",
|
|
301
|
-
replyTo = "",
|
|
302
|
-
) {
|
|
303
|
-
const messageType = validateMessageType(type);
|
|
304
|
-
const messageTo = validateActorAddress(to, "message.to");
|
|
305
|
-
const messageFrom = validateActorAddress(from, "message.from");
|
|
306
|
-
let metadata = {};
|
|
307
|
-
if (metadataValue) {
|
|
308
|
-
try {
|
|
309
|
-
const parsed = JSON.parse(metadataValue);
|
|
310
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
311
|
-
metadata = parsed;
|
|
312
|
-
else fail("Actor message metadata must be a JSON object");
|
|
313
|
-
} catch (error) {
|
|
314
|
-
fail(`Invalid actor message metadata JSON: ${error.message}`);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
const bodyText = readFileSync(0, "utf8");
|
|
318
|
-
const trimmed = bodyText.trim();
|
|
319
|
-
let body = bodyText;
|
|
320
|
-
if (trimmed) {
|
|
321
|
-
try {
|
|
322
|
-
body = JSON.parse(trimmed);
|
|
323
|
-
} catch {
|
|
324
|
-
body = bodyText;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
console.log(
|
|
328
|
-
JSON.stringify(
|
|
329
|
-
{
|
|
330
|
-
to: messageTo,
|
|
331
|
-
from: messageFrom,
|
|
332
|
-
type: messageType,
|
|
333
|
-
summary: summary || messageType,
|
|
334
|
-
body,
|
|
335
|
-
...(correlationId ? { correlation_id: correlationId } : {}),
|
|
336
|
-
...(replyTo ? { reply_to: replyTo } : {}),
|
|
337
|
-
metadata,
|
|
338
|
-
},
|
|
339
|
-
null,
|
|
340
|
-
2,
|
|
341
|
-
),
|
|
342
|
-
);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
257
|
function packageSummary(fileValue = "package.json") {
|
|
346
258
|
const file = resolve(
|
|
347
259
|
fileValue.replace(/^~(?=\/|$)/, process.env.HOME ?? "~"),
|
|
@@ -475,8 +387,6 @@ else if (command === "artifact-manifest")
|
|
|
475
387
|
artifactManifest(args[0] ?? "artifact.md", args[1], args[2], args[3]);
|
|
476
388
|
else if (command === "artifact-write")
|
|
477
389
|
artifactWrite(args[0] ?? "artifact.md", args[1] ?? "create");
|
|
478
|
-
else if (command === "actor-message")
|
|
479
|
-
actorMessage(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
|
|
480
390
|
else if (command === "package-summary")
|
|
481
391
|
packageSummary(args[0] ?? "package.json");
|
|
482
392
|
else if (command === "skill-summary")
|
|
@@ -93,6 +93,66 @@ try {
|
|
|
93
93
|
}
|
|
94
94
|
console.log("[release] bounded secret and public-path hygiene checked");
|
|
95
95
|
|
|
96
|
+
const removedPaths = [
|
|
97
|
+
"lib/messages.ts",
|
|
98
|
+
"lib/rooms.ts",
|
|
99
|
+
"lib/mailbox-loop.ts",
|
|
100
|
+
"lib/runs-mailbox.ts",
|
|
101
|
+
"lib/runs-messages.ts",
|
|
102
|
+
"lib/runs-outbox.ts",
|
|
103
|
+
"lib/tools-mailbox.ts",
|
|
104
|
+
"scripts/actor-worker.mjs",
|
|
105
|
+
"scripts/coordinator.mjs",
|
|
106
|
+
"recipes/actor-worker.json",
|
|
107
|
+
"recipes/pipeline-room-swarm.json",
|
|
108
|
+
"recipes/subagent-message.json",
|
|
109
|
+
"recipes/utility-actor-message.json",
|
|
110
|
+
"docs/actor-messages.md",
|
|
111
|
+
"docs/run-inspector.md",
|
|
112
|
+
"lib/run-inspector.ts",
|
|
113
|
+
"lib/run-inspector-overlay.ts",
|
|
114
|
+
];
|
|
115
|
+
for (const path of removedPaths) check(!fileSet.has(path), `removed surface returned: ${path}`);
|
|
116
|
+
|
|
117
|
+
const currentSurface = /^(?:lib\/|scripts\/|recipes\/|fixtures\/|skills\/|docs\/|README\.md|AGENTS\.md)/u;
|
|
118
|
+
const forbiddenPatterns = [
|
|
119
|
+
[/room:</u, "room address"],
|
|
120
|
+
[/branch:</u, "branch address"],
|
|
121
|
+
[/communication\.json/u, "communication snapshot"],
|
|
122
|
+
[/\bActor(?:Address|Message)\b/u, "legacy actor type"],
|
|
123
|
+
[/\b(?:actor_address|default_room)\b/u, "legacy spawn placeholder"],
|
|
124
|
+
[/inbox\.jsonl/u, "legacy inbox state"],
|
|
125
|
+
];
|
|
126
|
+
for (const path of files.filter((candidate) => currentSurface.test(candidate))) {
|
|
127
|
+
if (path === "BACKLOG.md" || path === "CHANGELOG.md" || path === "scripts/release-gates.mjs") continue;
|
|
128
|
+
const text = stagedText(path) ?? "";
|
|
129
|
+
for (const [pattern, label] of forbiddenPatterns) {
|
|
130
|
+
check(!pattern.test(text), `${label} in current surface: ${path}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const legacyFallbacks = new Map([
|
|
134
|
+
["lib/observability.ts", "outbox.jsonl"],
|
|
135
|
+
["lib/runs-status.ts", "events.jsonl"],
|
|
136
|
+
["lib/runs-start.ts", "events.jsonl"],
|
|
137
|
+
]);
|
|
138
|
+
for (const path of files.filter((candidate) => currentSurface.test(candidate))) {
|
|
139
|
+
if (path === "BACKLOG.md" || path === "CHANGELOG.md" || path === "scripts/release-gates.mjs") continue;
|
|
140
|
+
const text = stagedText(path) ?? "";
|
|
141
|
+
for (const term of ["outbox.jsonl", "events.jsonl"]) {
|
|
142
|
+
if (!text.includes(term)) continue;
|
|
143
|
+
check(legacyFallbacks.get(path) === term, `legacy state reference outside read-only fallback: ${path} (${term})`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
console.log("[release] removed-surface and legacy-fallback allowlists checked");
|
|
147
|
+
|
|
148
|
+
const baselineShippedLines = 35_077;
|
|
149
|
+
const shippedPath = /^(?:lib\/|scripts\/|recipes\/|docs\/|skills\/)/u;
|
|
150
|
+
const shippedLines = files
|
|
151
|
+
.filter((path) => shippedPath.test(path))
|
|
152
|
+
.reduce((total, path) => total + (((stagedText(path) ?? "").match(/\n/gu) ?? []).length + 1), 0);
|
|
153
|
+
check(shippedLines < baselineShippedLines, `shipped lines ${shippedLines} are not below baseline ${baselineShippedLines}`);
|
|
154
|
+
console.log(`[release] shipped lines ${shippedLines} < frozen baseline ${baselineShippedLines}`);
|
|
155
|
+
|
|
96
156
|
const sources = files.filter((path) => path === "index.ts" || (path.startsWith("lib/") && path.endsWith(".ts")));
|
|
97
157
|
const sourceSet = new Set(sources);
|
|
98
158
|
const graph = new Map();
|
|
@@ -63,13 +63,6 @@ function recipeFiles(target, all) {
|
|
|
63
63
|
.map((file) => resolve(target, file));
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
function mailboxType(value) {
|
|
67
|
-
if (typeof value === "string") return value;
|
|
68
|
-
if (value && typeof value === "object" && typeof value.type === "string")
|
|
69
|
-
return value.type;
|
|
70
|
-
return undefined;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
66
|
function collectTemplateStrings(value, out = []) {
|
|
74
67
|
if (typeof value === "string") out.push(value);
|
|
75
68
|
else if (Array.isArray(value)) value.forEach((item) => collectTemplateStrings(item, out));
|
|
@@ -124,46 +117,13 @@ function validateHelperPaths(file, config) {
|
|
|
124
117
|
return diagnostics;
|
|
125
118
|
}
|
|
126
119
|
|
|
127
|
-
function validateMailboxContract(file, config) {
|
|
128
|
-
const diagnostics = [];
|
|
129
|
-
const mailbox = config.mailbox;
|
|
130
|
-
const accepts = Array.isArray(mailbox?.accepts) ? mailbox.accepts : [];
|
|
131
|
-
const emits = Array.isArray(mailbox?.emits) ? mailbox.emits : [];
|
|
132
|
-
if (config.async === true && !mailbox)
|
|
133
|
-
diagnostics.push("mailbox: async recipes must declare mailbox metadata");
|
|
134
|
-
if (config.async === true && !accepts.map(mailboxType).includes("control.kill"))
|
|
135
|
-
diagnostics.push("mailbox.accepts: async recipes must include control.kill");
|
|
136
|
-
const allowedLegacyTypes = new Set(["awaiting_assignment"]);
|
|
137
|
-
for (const [key, entries] of Object.entries({ accepts, emits })) {
|
|
138
|
-
entries.forEach((entry, index) => {
|
|
139
|
-
const type = mailboxType(entry);
|
|
140
|
-
if (!type) diagnostics.push(`mailbox.${key}[${index}]: must be a string or object with type`);
|
|
141
|
-
else if (
|
|
142
|
-
!allowedLegacyTypes.has(type) &&
|
|
143
|
-
!/^[a-z][a-z0-9_-]*\.(?:[a-z][a-z0-9_-]*|\*)$/.test(type)
|
|
144
|
-
)
|
|
145
|
-
diagnostics.push(`mailbox.${key}[${index}]: message type must use channel.action form`);
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
const allowedDomainTermination = new Set([
|
|
149
|
-
"coordinator-locker.json",
|
|
150
|
-
"locker.json",
|
|
151
|
-
"music-player.json",
|
|
152
|
-
]);
|
|
153
|
-
const hasDomainTermination = accepts
|
|
154
|
-
.map(mailboxType)
|
|
155
|
-
.some((type) => type === "control.stop" || type === "control.cancel");
|
|
156
|
-
if (hasDomainTermination && !allowedDomainTermination.has(file.split(/[\\/]/).pop()))
|
|
157
|
-
diagnostics.push("mailbox.accepts: control.stop/control.cancel are reserved for actor-domain handlers");
|
|
158
|
-
return diagnostics;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
120
|
function qaDiagnostics(file, config) {
|
|
162
121
|
const diagnostics = [];
|
|
163
122
|
const warnings = [];
|
|
164
123
|
if (typeof config.description !== "string" || !config.description.trim())
|
|
165
124
|
warnings.push("description: missing or empty");
|
|
166
|
-
|
|
125
|
+
if (config.mailbox !== undefined)
|
|
126
|
+
diagnostics.push("recipe.mailbox was removed; use control actions and Trace events");
|
|
167
127
|
diagnostics.push(...validateArtifactDeclarations(config));
|
|
168
128
|
diagnostics.push(...validateHelperPaths(file, config));
|
|
169
129
|
const platformSpecificTemplate = collectTemplateStrings(config.template).some(
|
|
@@ -201,17 +161,7 @@ function validateFile(file, qa = false) {
|
|
|
201
161
|
config.imports && typeof config.imports === "object"
|
|
202
162
|
? Object.keys(config.imports).sort()
|
|
203
163
|
: [],
|
|
204
|
-
|
|
205
|
-
config.mailbox && typeof config.mailbox === "object"
|
|
206
|
-
? {
|
|
207
|
-
accepts: Array.isArray(config.mailbox.accepts)
|
|
208
|
-
? config.mailbox.accepts
|
|
209
|
-
: [],
|
|
210
|
-
emits: Array.isArray(config.mailbox.emits)
|
|
211
|
-
? config.mailbox.emits
|
|
212
|
-
: [],
|
|
213
|
-
}
|
|
214
|
-
: undefined,
|
|
164
|
+
control: Array.isArray(config.control) ? config.control : undefined,
|
|
215
165
|
...(qa
|
|
216
166
|
? {
|
|
217
167
|
qa: {
|