@bendyline/gezel 1.0.2 → 1.0.4
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/checks/index.d.ts +1 -1
- package/dist/checks/index.js +2 -2
- package/dist/{index-CWMNVAhp.d.ts → index-Cj_G8Y-S.d.ts} +1369 -11
- package/dist/index.d.ts +46 -8
- package/dist/index.js +2247 -1053
- package/dist/markdown/index.d.ts +1 -1
- package/dist/markdown/index.js +55 -6
- package/dist/{report-action-DIz_2QOu.d.ts → report-action-UJ-pJpZO.d.ts} +43 -0
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +730 -571
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -500,13 +500,14 @@ var GateCheckSchema = z3.discriminatedUnion("kind", [
|
|
|
500
500
|
label: z3.string().min(1).optional(),
|
|
501
501
|
artifact: z3.boolean().optional()
|
|
502
502
|
}),
|
|
503
|
-
/** `file` must NOT match `pattern` (regex)
|
|
503
|
+
/** `file` must NOT match `pattern` (regex), in the workspace or artifacts drawer. */
|
|
504
504
|
z3.object({
|
|
505
505
|
kind: z3.literal("notContains"),
|
|
506
506
|
file: z3.string().min(1),
|
|
507
507
|
pattern: z3.string().min(1),
|
|
508
508
|
flags: z3.string().optional(),
|
|
509
|
-
label: z3.string().min(1).optional()
|
|
509
|
+
label: z3.string().min(1).optional(),
|
|
510
|
+
artifact: z3.boolean().optional()
|
|
510
511
|
}),
|
|
511
512
|
/**
|
|
512
513
|
* `file` may use high-risk claim wording only when the exact matched
|
|
@@ -649,6 +650,20 @@ var GateCheckSchema = z3.discriminatedUnion("kind", [
|
|
|
649
650
|
tools: z3.array(z3.string().min(1)).min(1),
|
|
650
651
|
minSuccessful: z3.number().int().positive().optional()
|
|
651
652
|
}),
|
|
653
|
+
/**
|
|
654
|
+
* A PR-review coverage ledger must name every changed path materialized in
|
|
655
|
+
* a connector corpus. The ledger is workspace JSON (`reviewedFiles` by
|
|
656
|
+
* default); the source records live in the read-only artifacts drawer and
|
|
657
|
+
* carry their authoritative path in frontmatter. This prevents a polished
|
|
658
|
+
* report from passing after only the first context-sized prefix was read.
|
|
659
|
+
*/
|
|
660
|
+
z3.object({
|
|
661
|
+
kind: z3.literal("corpusCoverage"),
|
|
662
|
+
file: z3.string().min(1),
|
|
663
|
+
corpusDir: z3.string().min(1),
|
|
664
|
+
reviewedField: z3.string().min(1).optional(),
|
|
665
|
+
recordField: z3.string().min(1).optional()
|
|
666
|
+
}),
|
|
652
667
|
/**
|
|
653
668
|
* The H1 slide titles in `file` must match the numbered slide headings in
|
|
654
669
|
* `outlineFile`, one-for-one and in order. This makes a locked Markdown
|
|
@@ -658,7 +673,9 @@ var GateCheckSchema = z3.discriminatedUnion("kind", [
|
|
|
658
673
|
z3.object({
|
|
659
674
|
kind: z3.literal("markdownHeadingsMatch"),
|
|
660
675
|
file: z3.string().min(1),
|
|
661
|
-
outlineFile: z3.string().min(1)
|
|
676
|
+
outlineFile: z3.string().min(1),
|
|
677
|
+
/** Read outlineFile from artifacts while file uses the check's primary surface. */
|
|
678
|
+
outlineArtifact: z3.boolean().optional()
|
|
662
679
|
}),
|
|
663
680
|
/**
|
|
664
681
|
* Named facts in `file` must come from authorized sources: each fact
|
|
@@ -921,6 +938,12 @@ var AdvanceWhenSchema = z5.object({
|
|
|
921
938
|
/** Step to activate on the signal. Defaults to `next`; must resolve like `next`. */
|
|
922
939
|
goto: z5.string().optional()
|
|
923
940
|
});
|
|
941
|
+
var CraftbookStepInputSchema = z5.object({
|
|
942
|
+
/** Path relative to the selected drawer's root. */
|
|
943
|
+
file: z5.string().min(1).describe("Path relative to the selected drawer root."),
|
|
944
|
+
/** Read from the artifacts drawer instead of the project workspace. */
|
|
945
|
+
artifact: z5.boolean().optional().describe("True for the artifacts drawer; false/omitted for the project workspace.")
|
|
946
|
+
});
|
|
924
947
|
var ModelTierSchema = z5.enum(MODEL_TIER_ORDER);
|
|
925
948
|
var CraftbookStepSchema = z5.object({
|
|
926
949
|
id: z5.string().min(1),
|
|
@@ -961,6 +984,10 @@ var CraftbookStepSchema = z5.object({
|
|
|
961
984
|
* read the LAST ref's output (legacy routing; prefer gate routing).
|
|
962
985
|
*/
|
|
963
986
|
onExit: ScriptRefListSchema.optional(),
|
|
987
|
+
/** Required file inputs for this step, in the order they should be opened. */
|
|
988
|
+
consumes: z5.array(CraftbookStepInputSchema).min(1).optional().describe(
|
|
989
|
+
"Files this step must open before working. Artifact inputs also require an explicit `read_artifact` call in the step prompt."
|
|
990
|
+
),
|
|
964
991
|
/** See {@link AdvanceWhenSchema}. */
|
|
965
992
|
advanceWhen: AdvanceWhenSchema.optional(),
|
|
966
993
|
/** The end-of-step decision. See {@link StepGateSchema} (current) / {@link GateSpecSchema} (legacy). */
|
|
@@ -972,14 +999,16 @@ var CraftbookStepSchema = z5.object({
|
|
|
972
999
|
* Marks the parent step that triggers a declarative per-item fanout
|
|
973
1000
|
* (see {@link CraftbookSpawnSchema}). When this step activates on a
|
|
974
1001
|
* spawn-host task, the runtime reads the craftbook's `spawn.overFile`
|
|
975
|
-
*
|
|
1002
|
+
* JSON array on its declared surface and spawns one child task per item — no model
|
|
976
1003
|
* tool call. Inert unless the craftbook also declares `spawn`.
|
|
977
1004
|
*/
|
|
978
1005
|
spawnFanout: z5.boolean().optional()
|
|
979
1006
|
});
|
|
980
1007
|
var CraftbookSpawnSchema = z5.object({
|
|
981
|
-
/**
|
|
1008
|
+
/** Surface-relative JSON file the parent produces; its array drives the fanout. */
|
|
982
1009
|
overFile: z5.string().min(1),
|
|
1010
|
+
/** Read overFile from the artifacts drawer instead of the project workspace. */
|
|
1011
|
+
overArtifact: z5.boolean().optional(),
|
|
983
1012
|
/** Dotted path to the array inside `overFile`. Absent → the file itself is the array. */
|
|
984
1013
|
itemsPath: z5.string().optional(),
|
|
985
1014
|
/** Entry step id of the child template. Defaults to the first `steps` entry. */
|
|
@@ -1015,6 +1044,14 @@ function validateCraftbookGraph(cb) {
|
|
|
1015
1044
|
problems.push(`step "${s.id}" advanceWhen.goto "${s.advanceWhen.goto}" missing from steps`);
|
|
1016
1045
|
}
|
|
1017
1046
|
}
|
|
1047
|
+
for (const input of s.consumes ?? []) {
|
|
1048
|
+
if (!input.artifact) continue;
|
|
1049
|
+
if (!/`read_artifact(?:`|\()/.test(s.prompt ?? "")) {
|
|
1050
|
+
problems.push(
|
|
1051
|
+
`step "${s.id}" consumes artifact "${input.file}" but its prompt does not explicitly call \`read_artifact\``
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1018
1055
|
if (s.gate) {
|
|
1019
1056
|
const gate = normalizeStepGate(s.gate);
|
|
1020
1057
|
if (s.terminal && gate.at === "activation") {
|
|
@@ -1307,6 +1344,9 @@ var NewCraftbookStepSchema = z5.object({
|
|
|
1307
1344
|
assignee: TaskAssigneeSchema.optional(),
|
|
1308
1345
|
onEnter: ScriptRefListSchema.optional(),
|
|
1309
1346
|
onExit: ScriptRefListSchema.optional(),
|
|
1347
|
+
consumes: z5.array(CraftbookStepInputSchema).min(1).optional().describe(
|
|
1348
|
+
"Files this step must open before working. Artifact inputs also require an explicit `read_artifact` call in the step prompt."
|
|
1349
|
+
),
|
|
1310
1350
|
advanceWhen: AdvanceWhenSchema.optional(),
|
|
1311
1351
|
gate: StepGateUnionSchema.optional(),
|
|
1312
1352
|
/** See {@link StepDeliverableSchema} — one field attaches the enforced gate. */
|
|
@@ -1419,6 +1459,7 @@ function resolveSteps(blueprints) {
|
|
|
1419
1459
|
...s.assignee ? { assignee: s.assignee } : {},
|
|
1420
1460
|
...s.onEnter ? { onEnter: s.onEnter } : {},
|
|
1421
1461
|
...s.onExit ? { onExit: s.onExit } : {},
|
|
1462
|
+
...s.consumes && s.consumes.length > 0 ? { consumes: s.consumes } : {},
|
|
1422
1463
|
...s.advanceWhen ? { advanceWhen: s.advanceWhen } : {},
|
|
1423
1464
|
...s.gate ? { gate: s.gate } : {},
|
|
1424
1465
|
...s.next ? { next: s.next } : {},
|
|
@@ -1541,6 +1582,10 @@ function applyStepPatch(step, patch) {
|
|
|
1541
1582
|
delete updated.onExit;
|
|
1542
1583
|
} else updated.onExit = patch.onExit;
|
|
1543
1584
|
}
|
|
1585
|
+
if (patch.consumes !== void 0) {
|
|
1586
|
+
if (patch.consumes === null || patch.consumes.length === 0) delete updated.consumes;
|
|
1587
|
+
else updated.consumes = patch.consumes;
|
|
1588
|
+
}
|
|
1544
1589
|
if (patch.advanceWhen !== void 0) {
|
|
1545
1590
|
if (patch.advanceWhen === null) delete updated.advanceWhen;
|
|
1546
1591
|
else updated.advanceWhen = patch.advanceWhen;
|
|
@@ -1719,7 +1764,7 @@ function craftbookDocFormatFromEnv(value) {
|
|
|
1719
1764
|
}
|
|
1720
1765
|
|
|
1721
1766
|
// src/schemas/craftbook-test.ts
|
|
1722
|
-
import { z as
|
|
1767
|
+
import { z as z20 } from "zod";
|
|
1723
1768
|
|
|
1724
1769
|
// src/schemas/history.ts
|
|
1725
1770
|
import { z as z18 } from "zod";
|
|
@@ -3701,7 +3746,15 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3701
3746
|
kind: z17.string(),
|
|
3702
3747
|
summary: z17.string(),
|
|
3703
3748
|
at: z17.string(),
|
|
3704
|
-
taskRef: z17.string().optional()
|
|
3749
|
+
taskRef: z17.string().optional(),
|
|
3750
|
+
/**
|
|
3751
|
+
* Gezel responsible for the event, when History recorded one. Kept
|
|
3752
|
+
* separate from the human-readable summary so fixed-presentation
|
|
3753
|
+
* clients (notably the role-name-only CLI) can render the actor using
|
|
3754
|
+
* their own naming mode instead of leaking the friendly name embedded
|
|
3755
|
+
* in the audit prose.
|
|
3756
|
+
*/
|
|
3757
|
+
gezelId: z17.string().optional()
|
|
3705
3758
|
}),
|
|
3706
3759
|
/**
|
|
3707
3760
|
* Emitted when a gezel crosses a growth level threshold and a pending
|
|
@@ -4242,608 +4295,173 @@ var ListHistoryResponseSchema = z18.object({
|
|
|
4242
4295
|
entries: z18.array(HistoryEntrySchema)
|
|
4243
4296
|
});
|
|
4244
4297
|
|
|
4245
|
-
// src/schemas/
|
|
4246
|
-
|
|
4247
|
-
var
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
var NodeScriptPassesCheckSchema = z19.object({
|
|
4258
|
-
kind: z19.literal("nodeScriptPasses"),
|
|
4259
|
-
script: z19.string().min(1),
|
|
4260
|
-
timeoutMs: z19.number().int().positive().optional(),
|
|
4261
|
-
requiredOutput: z19.array(
|
|
4262
|
-
z19.object({
|
|
4263
|
-
pattern: z19.string().min(1),
|
|
4264
|
-
flags: z19.string().optional(),
|
|
4265
|
-
label: z19.string().optional()
|
|
4266
|
-
}).strict()
|
|
4267
|
-
).optional()
|
|
4268
|
-
}).strict();
|
|
4269
|
-
var BinaryDocumentCheckSchema = z19.object({
|
|
4270
|
-
kind: z19.literal("binaryDocument"),
|
|
4271
|
-
file: z19.string().min(1),
|
|
4272
|
-
/** Look in the artifacts drawer instead of the workspace. */
|
|
4273
|
-
artifact: z19.boolean().optional(),
|
|
4274
|
-
/** Floor on the container's byte length; defaults to 1000. */
|
|
4275
|
-
minBytes: z19.number().int().positive().optional()
|
|
4276
|
-
}).strict();
|
|
4277
|
-
var CraftbookTestCheckSchema = z19.union([
|
|
4278
|
-
GateCheckSchema,
|
|
4279
|
-
PrometheusAlertsCheckSchema,
|
|
4280
|
-
NodeScriptPassesCheckSchema,
|
|
4281
|
-
BinaryDocumentCheckSchema
|
|
4282
|
-
]);
|
|
4283
|
-
var MockServiceIdSchema = z19.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/, "mock service ids are lowercase kebab-case");
|
|
4284
|
-
var MockToolsetIdSchema = z19.string().min(1).regex(
|
|
4285
|
-
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/,
|
|
4286
|
-
"mock toolset ids are lowercase catalog ids or scoped npm-style ids"
|
|
4298
|
+
// src/schemas/project.ts
|
|
4299
|
+
import { z as z19 } from "zod";
|
|
4300
|
+
var HttpsOriginSchema = z19.string().url().refine(
|
|
4301
|
+
(value) => {
|
|
4302
|
+
try {
|
|
4303
|
+
const url = new URL(value);
|
|
4304
|
+
return url.protocol === "https:" && !url.username && !url.password && url.pathname === "/" && !url.search && !url.hash;
|
|
4305
|
+
} catch {
|
|
4306
|
+
return false;
|
|
4307
|
+
}
|
|
4308
|
+
},
|
|
4309
|
+
{ message: "must be an exact HTTPS origin (for example https://api.example.com)" }
|
|
4287
4310
|
);
|
|
4288
|
-
var
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
z19.
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
}).strict(),
|
|
4315
|
-
z19.object({
|
|
4316
|
-
kind: z19.literal("webhook"),
|
|
4317
|
-
id: MockServiceIdSchema,
|
|
4318
|
-
description: z19.string().min(1),
|
|
4319
|
-
/** Receiver path; defaults to `/webhook` when omitted. */
|
|
4320
|
-
path: z19.string().min(1).optional()
|
|
4321
|
-
}).strict(),
|
|
4322
|
-
z19.object({
|
|
4323
|
-
kind: z19.literal("cli"),
|
|
4324
|
-
id: MockServiceIdSchema,
|
|
4325
|
-
description: z19.string().min(1),
|
|
4326
|
-
/** Fake-CLI shim seeded as a workspace file (today's dry-run pattern). */
|
|
4327
|
-
shim: z19.object({ path: z19.string().min(1), content: z19.string() }).strict()
|
|
4328
|
-
}).strict(),
|
|
4329
|
-
z19.object({
|
|
4330
|
-
kind: z19.literal("mcp"),
|
|
4331
|
-
id: MockServiceIdSchema,
|
|
4332
|
-
description: z19.string().min(1),
|
|
4333
|
-
/** Override the local-catalog id when the mock replaces a real dependency. */
|
|
4334
|
-
toolsetId: MockToolsetIdSchema.optional(),
|
|
4335
|
-
/**
|
|
4336
|
-
* Served live by the eval mock rail: each declared tool becomes a
|
|
4337
|
-
* real tool on a per-trial Streamable-HTTP MCP endpoint, installed
|
|
4338
|
-
* into the trial via a local-catalog `mock-mcp-<id>` toolset.
|
|
4339
|
-
* `resultTemplate` is JSON-encoded as the tool result text
|
|
4340
|
-
* (default `{"ok":true}` when absent).
|
|
4341
|
-
*/
|
|
4342
|
-
tools: z19.array(
|
|
4343
|
-
z19.object({
|
|
4344
|
-
name: z19.string().min(1),
|
|
4345
|
-
description: z19.string().min(1),
|
|
4346
|
-
resultTemplate: z19.unknown().optional(),
|
|
4347
|
-
/** Deterministic stateful responses, consumed in call order; the last repeats. */
|
|
4348
|
-
resultSequence: z19.array(z19.unknown()).min(1).optional(),
|
|
4349
|
-
/**
|
|
4350
|
-
* Deterministic eval-only file materialization after this
|
|
4351
|
-
* tool call. The fixture must match the container the
|
|
4352
|
-
* deliverable's extension claims — a `minimal-pptx` written
|
|
4353
|
-
* to a `.docx` path now fails the `binaryDocument` check on
|
|
4354
|
-
* content type rather than sliding through a byte floor.
|
|
4355
|
-
*/
|
|
4356
|
-
writeFixture: z19.object({
|
|
4357
|
-
surface: z19.enum(["workspace", "artifact"]),
|
|
4358
|
-
pathArgument: z19.string().min(1),
|
|
4359
|
-
fixture: z19.enum(["minimal-pptx", "minimal-docx", "minimal-pdf", "minimal-png"])
|
|
4360
|
-
}).strict().optional()
|
|
4361
|
-
}).strict()
|
|
4362
|
-
).min(1)
|
|
4363
|
-
}).strict()
|
|
4364
|
-
]);
|
|
4365
|
-
var CraftbookTestFixtureFileSchema = z19.object({
|
|
4366
|
-
path: z19.string().min(1),
|
|
4367
|
-
content: z19.string(),
|
|
4368
|
-
/** Defaults to `workspace`; `harness` never enters the model-visible project. */
|
|
4369
|
-
surface: z19.enum(["workspace", "artifact", "harness"]).optional(),
|
|
4311
|
+
var ProjectGitHubSchema = z19.object({
|
|
4312
|
+
// Accept any non-empty string. Git URLs come in many forms beyond
|
|
4313
|
+
// `https://`: ssh shorthand (`git@github.com:owner/repo`), local
|
|
4314
|
+
// filesystem paths (`/path/to/bare.git`), other-host references.
|
|
4315
|
+
// The strict `.url()` validator rejected the filesystem-path form
|
|
4316
|
+
// and broke Phase-3 worktree tests that use a local bare repo as
|
|
4317
|
+
// the upstream. Higher layers (the github sync code) parse the URL
|
|
4318
|
+
// and reject anything that doesn't shape up as a clonable ref.
|
|
4319
|
+
url: z19.string().min(1),
|
|
4320
|
+
branch: z19.string().optional(),
|
|
4321
|
+
/** Resolved absolute path to the working tree. Managed by the service. */
|
|
4322
|
+
checkoutDir: z19.string().optional(),
|
|
4323
|
+
lastSyncedAt: z19.string().optional(),
|
|
4324
|
+
/** Repo default branch (e.g. "main"), detected lazily and cached. Managed by the service. */
|
|
4325
|
+
defaultBranch: z19.string().optional()
|
|
4326
|
+
});
|
|
4327
|
+
var ProjectConnectorBindingSchema = z19.object({
|
|
4328
|
+
/** Stable binding id; also the SecretStore `fieldId` + corpus-slug seed. */
|
|
4329
|
+
id: z19.string().min(1),
|
|
4330
|
+
/** The connector-type catalog id, e.g. `mail-gmail`, `linear-issues`. */
|
|
4331
|
+
type: z19.string().min(1),
|
|
4332
|
+
/** Catalog source the type resolved from (provenance/pin). */
|
|
4333
|
+
sourceId: z19.string().optional(),
|
|
4334
|
+
/** Pinned connector-type version. */
|
|
4335
|
+
version: z19.string().optional(),
|
|
4336
|
+
displayName: z19.string().optional(),
|
|
4370
4337
|
/**
|
|
4371
|
-
*
|
|
4372
|
-
*
|
|
4338
|
+
* Artifact-relative corpus root (`data/<corpusName>`), resolved once at bind
|
|
4339
|
+
* time and never recomputed — renaming a binding must not strand its corpus.
|
|
4340
|
+
*/
|
|
4341
|
+
corpusDir: z19.string().optional(),
|
|
4342
|
+
/** Per-binding config, validated at bind time against the type's `configSchema`. */
|
|
4343
|
+
config: z19.record(z19.string(), z19.unknown()).default({}),
|
|
4344
|
+
/** Opaque, adapter-shaped incremental-sync cursor. Persisted so resync resumes. */
|
|
4345
|
+
cursor: z19.unknown().optional(),
|
|
4346
|
+
/** Pause syncing without unbinding. */
|
|
4347
|
+
disabled: z19.boolean().optional(),
|
|
4348
|
+
lastSyncedAt: z19.string().optional(),
|
|
4349
|
+
/** Last sync error, surfaced in the UI; cleared on the next success. */
|
|
4350
|
+
lastError: z19.string().optional()
|
|
4351
|
+
});
|
|
4352
|
+
var ProjectNudgeConfigSchema = z19.object({
|
|
4353
|
+
enabled: z19.boolean().optional(),
|
|
4354
|
+
rapidIntervalMs: z19.number().int().positive().optional(),
|
|
4355
|
+
slowIntervalMs: z19.number().int().positive().optional(),
|
|
4356
|
+
recentActivityWindowMs: z19.number().int().positive().optional(),
|
|
4357
|
+
rapidAttemptsBeforeBackoff: z19.number().int().positive().optional(),
|
|
4358
|
+
/**
|
|
4359
|
+
* Grace period applied to the very first nudge a project ever
|
|
4360
|
+
* receives, measured from `project.createdAt`. Default per tempo;
|
|
4361
|
+
* setting `0` opts out (legacy behavior — first nudge fires as
|
|
4362
|
+
* soon as the rapid interval allows).
|
|
4373
4363
|
*/
|
|
4374
|
-
|
|
4364
|
+
firstNudgeGraceMs: z19.number().int().nonnegative().optional()
|
|
4365
|
+
});
|
|
4366
|
+
var ProjectNudgeStateSchema = z19.object({
|
|
4367
|
+
lastNudgedAt: z19.string().optional(),
|
|
4368
|
+
consecutiveRapidNudges: z19.number().int().nonnegative().optional()
|
|
4369
|
+
});
|
|
4370
|
+
var ProjectTabVisibilitySchema = z19.object({
|
|
4371
|
+
overview: z19.boolean().optional(),
|
|
4372
|
+
tasks: z19.boolean().optional(),
|
|
4373
|
+
approvals: z19.boolean().optional(),
|
|
4374
|
+
workspace: z19.boolean().optional(),
|
|
4375
|
+
artifacts: z19.boolean().optional(),
|
|
4376
|
+
map: z19.boolean().optional()
|
|
4375
4377
|
}).strict();
|
|
4376
|
-
var
|
|
4377
|
-
|
|
4378
|
-
|
|
4378
|
+
var ProjectManagedWorkspaceWritePolicySchema = z19.enum(["auto", "allow", "deny"]);
|
|
4379
|
+
var ProjectTypeProvenanceSchema = z19.object({
|
|
4380
|
+
/** Catalog id of the applied project type. */
|
|
4381
|
+
id: z19.string(),
|
|
4382
|
+
/** Type version installed at adoption. */
|
|
4383
|
+
version: z19.string(),
|
|
4384
|
+
/** Catalog source the type resolved from (`bundled` | `local` | `community` | …). */
|
|
4385
|
+
source: z19.string(),
|
|
4386
|
+
/** Param values collected at adoption, substituted into templates + seed files. */
|
|
4387
|
+
params: z19.record(z19.string(), z19.unknown()).optional(),
|
|
4388
|
+
/** ISO timestamp of adoption. */
|
|
4389
|
+
appliedAt: z19.string()
|
|
4390
|
+
});
|
|
4391
|
+
var ProjectSchema = z19.object({
|
|
4392
|
+
id: EntityIdSchema,
|
|
4393
|
+
name: z19.string(),
|
|
4379
4394
|
description: z19.string().optional(),
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
/** Exact values supplied to the catalog craftbook's `paramSchema`. */
|
|
4388
|
-
craftbookParams: z19.record(z19.string(), z19.string()).optional(),
|
|
4395
|
+
workingDir: z19.string().optional(),
|
|
4396
|
+
/** Optional gezel that acts as the project's voorman (foreman). Surfaces in
|
|
4397
|
+
* the project detail pane, flows into the system prompt when a session is
|
|
4398
|
+
* scoped here. For solo projects (`mode === 'solo'`) this same field
|
|
4399
|
+
* holds the project's Builder — the data is unchanged, only the
|
|
4400
|
+
* label flips. */
|
|
4401
|
+
voormanGezelId: z19.string().optional(),
|
|
4389
4402
|
/**
|
|
4390
|
-
*
|
|
4391
|
-
*
|
|
4392
|
-
*
|
|
4403
|
+
* Internal marker: ISO timestamp of the one-time automatic voorman
|
|
4404
|
+
* assignment. The indexer ensures every project ends up with a voorman
|
|
4405
|
+
* — adopting the `@project` gezel minted from an AGENTS.md/CLAUDE.md, or
|
|
4406
|
+
* (when there's no instruction file) promoting an existing roster gezel.
|
|
4407
|
+
* Set once a voorman has been ensured so a later *manual* clear isn't
|
|
4408
|
+
* silently re-populated on the next scan. Not user-editable; absent on
|
|
4409
|
+
* projects last written before this field existed.
|
|
4393
4410
|
*/
|
|
4394
|
-
|
|
4395
|
-
}).strict();
|
|
4396
|
-
var CraftbookTestDeliverableSchema = z19.object({
|
|
4397
|
-
path: z19.string().min(1),
|
|
4398
|
-
kind: DeliverableKindSchema,
|
|
4399
|
-
minBytes: z19.number().int().positive().optional(),
|
|
4400
|
-
checks: z19.array(CraftbookTestCheckSchema).optional()
|
|
4401
|
-
}).strict();
|
|
4402
|
-
var CraftbookTestMockExpectationSchema = z19.object({
|
|
4403
|
-
/** Mock service id from `mocks[]`. */
|
|
4404
|
-
service: MockServiceIdSchema,
|
|
4405
|
-
minRequests: z19.number().int().positive().optional(),
|
|
4406
|
-
/** Regex sources matched against logged request paths. */
|
|
4407
|
-
requiredPaths: z19.array(z19.string().min(1)).optional(),
|
|
4408
|
-
forbiddenPaths: z19.array(z19.string().min(1)).optional(),
|
|
4411
|
+
voormanAutoAssignedAt: z19.string().optional(),
|
|
4409
4412
|
/**
|
|
4410
|
-
*
|
|
4411
|
-
*
|
|
4412
|
-
*
|
|
4413
|
-
*
|
|
4414
|
-
*
|
|
4413
|
+
* Roster — gezels that have been pulled into this project. Populated
|
|
4414
|
+
* automatically the first time a gezel is set as voorman, opens a
|
|
4415
|
+
* session scoped here, is pinged via `message_gezel` / `ask_gezel`,
|
|
4416
|
+
* or is assigned to a task; can also be edited explicitly via the
|
|
4417
|
+
* `add_gezel_to_project` / `remove_gezel_from_project` MCP tools.
|
|
4418
|
+
*
|
|
4419
|
+
* Advisory: not used to gate access — any gezel can still chat or be
|
|
4420
|
+
* assigned to a task here; the roster is for "team" UX surfacing,
|
|
4421
|
+
* notification scoping, and tracking who actually does work in the
|
|
4422
|
+
* project. Order is not significant. Missing on disk → empty roster
|
|
4423
|
+
* (back-compat with every project written before this field
|
|
4424
|
+
* existed).
|
|
4415
4425
|
*/
|
|
4416
|
-
|
|
4417
|
-
/** Per-MCP-tool call budgets for repeated journeys or retries. */
|
|
4418
|
-
toolCalls: z19.record(
|
|
4419
|
-
z19.string().min(1),
|
|
4420
|
-
z19.object({
|
|
4421
|
-
minCalls: z19.number().int().nonnegative().default(1),
|
|
4422
|
-
maxCalls: z19.number().int().nonnegative().optional()
|
|
4423
|
-
}).strict().refine(
|
|
4424
|
-
(value) => value.maxCalls === void 0 || value.minCalls <= value.maxCalls,
|
|
4425
|
-
"minCalls must be less than or equal to maxCalls"
|
|
4426
|
-
)
|
|
4427
|
-
).optional()
|
|
4428
|
-
}).strict();
|
|
4429
|
-
var CraftbookTestHistoryExpectationSchema = z19.object({
|
|
4430
|
-
kind: HistoryEventKindSchema,
|
|
4431
|
-
minEntries: z19.number().int().nonnegative().default(1),
|
|
4432
|
-
maxEntries: z19.number().int().nonnegative().optional(),
|
|
4433
|
-
summaryPattern: z19.string().min(1).optional(),
|
|
4434
|
-
flags: z19.string().optional(),
|
|
4435
|
-
details: z19.record(z19.string(), z19.union([z19.string(), z19.number(), z19.boolean(), z19.null()])).optional()
|
|
4436
|
-
}).strict();
|
|
4437
|
-
var CraftbookTestSuccessSchema = z19.object({
|
|
4438
|
-
summary: z19.string().min(1),
|
|
4439
|
-
deliverables: z19.array(CraftbookTestDeliverableSchema).optional(),
|
|
4440
|
-
checks: z19.array(CraftbookTestCheckSchema).optional(),
|
|
4441
|
-
taskNotes: z19.object({
|
|
4442
|
-
minBytes: z19.number().int().positive().optional(),
|
|
4443
|
-
checks: z19.array(CraftbookTestCheckSchema).optional(),
|
|
4444
|
-
requireCraftbookTask: z19.boolean().optional()
|
|
4445
|
-
}).strict().optional(),
|
|
4446
|
-
taskGraph: z19.object({
|
|
4447
|
-
checks: z19.array(CraftbookTestCheckSchema).optional(),
|
|
4448
|
-
requireCraftbookTask: z19.boolean().optional(),
|
|
4449
|
-
/** Require the matching task to reach a terminal step (or complete). */
|
|
4450
|
-
requireTerminalStep: z19.boolean().optional(),
|
|
4451
|
-
requireDraftRef: z19.boolean().optional(),
|
|
4452
|
-
draft: z19.object({
|
|
4453
|
-
status: z19.enum(["draft", "paused", "active", "complete", "canceled"]).optional(),
|
|
4454
|
-
minDescriptionBytes: z19.number().int().positive().optional(),
|
|
4455
|
-
minOutcomes: z19.number().int().positive().optional(),
|
|
4456
|
-
minSteps: z19.number().int().positive().optional(),
|
|
4457
|
-
requireTerminalVerification: z19.boolean().optional(),
|
|
4458
|
-
requireGatedBuildSteps: z19.boolean().optional()
|
|
4459
|
-
}).strict().optional()
|
|
4460
|
-
}).strict().optional(),
|
|
4461
|
-
/** Assertions evaluated against the live mock server's request log. */
|
|
4462
|
-
mocks: z19.array(CraftbookTestMockExpectationSchema).optional(),
|
|
4463
|
-
/** Assertions evaluated against the project's append-only History log. */
|
|
4464
|
-
history: z19.array(CraftbookTestHistoryExpectationSchema).optional(),
|
|
4465
|
-
/** Workspace fixtures whose final content must equal the seeded bytes exactly. */
|
|
4466
|
-
unchangedFixtures: z19.array(z19.string().min(1)).optional()
|
|
4467
|
-
}).strict();
|
|
4468
|
-
var CraftbookTestRubricSchema = z19.object({
|
|
4469
|
-
artifact: z19.object({
|
|
4470
|
-
/** Workspace or artifact path the judge reads (adapter derives the basename). */
|
|
4471
|
-
path: z19.string().min(1),
|
|
4472
|
-
kind: z19.enum(["html", "markdown", "yaml", "typescript", "json", "text"])
|
|
4473
|
-
}).strict(),
|
|
4474
|
-
axes: z19.array(z19.object({ name: z19.string().min(1), description: z19.string().min(1) }).strict()).min(1),
|
|
4475
|
-
contextNote: z19.string().optional()
|
|
4476
|
-
}).strict();
|
|
4477
|
-
var CraftbookTestSpecSchema = z19.object({
|
|
4478
|
-
schemaVersion: z19.literal(CRAFTBOOK_TEST_SCHEMA_VERSION),
|
|
4479
|
-
title: z19.string().min(1),
|
|
4480
|
-
objective: z19.string().min(1),
|
|
4426
|
+
gezelIds: z19.array(z19.string()).optional(),
|
|
4481
4427
|
/**
|
|
4482
|
-
*
|
|
4483
|
-
*
|
|
4484
|
-
*
|
|
4428
|
+
* Suggested-work keys the user has dismissed ("don't offer this again
|
|
4429
|
+
* here"). Advisory UI state, same spirit as `gezelIds`: enabling a
|
|
4430
|
+
* dismissed key un-dismisses it, and a materialized host always
|
|
4431
|
+
* outranks a dismissal. Keys are the stable suggested-work identities
|
|
4432
|
+
* (`gezel-template:<templateId>:<craftbookId>[#N]` /
|
|
4433
|
+
* `project-type:<typeId>:<scheduleKey>`). Deliberately not exposed
|
|
4434
|
+
* through the model-facing `update_project` MCP tool.
|
|
4485
4435
|
*/
|
|
4486
|
-
|
|
4487
|
-
/** Kickoff chat message the harness sends. Required — every book runs. */
|
|
4488
|
-
prompt: z19.string().min(1),
|
|
4489
|
-
setup: CraftbookTestSetupSchema,
|
|
4490
|
-
mocks: z19.array(MockServiceSchema).default([]),
|
|
4491
|
-
success: CraftbookTestSuccessSchema,
|
|
4492
|
-
rubric: CraftbookTestRubricSchema,
|
|
4493
|
-
qualityFocus: z19.array(z19.string().min(1)).default([]),
|
|
4436
|
+
suggestedWorkDismissed: z19.array(z19.string()).optional(),
|
|
4494
4437
|
/**
|
|
4495
|
-
*
|
|
4496
|
-
*
|
|
4438
|
+
* Shared per-project configuration values ("project properties") that
|
|
4439
|
+
* craftbook params and features draw from — e.g. `content.language`,
|
|
4440
|
+
* the designated language a translator gezel targets. Keys are ids
|
|
4441
|
+
* from the well-known registry in `project-properties.ts`, but unknown
|
|
4442
|
+
* ids are allowed (the registry improves display, it doesn't gate).
|
|
4443
|
+
* Values are plain strings; empty string is treated as unset.
|
|
4497
4444
|
*/
|
|
4498
|
-
|
|
4499
|
-
}).strict().superRefine((spec, ctx) => {
|
|
4500
|
-
const mockIds = new Set(spec.mocks.map((m) => m.id));
|
|
4501
|
-
const mockById = new Map(spec.mocks.map((m) => [m.id, m]));
|
|
4502
|
-
for (const [i, expectation] of (spec.success.mocks ?? []).entries()) {
|
|
4503
|
-
if (!mockIds.has(expectation.service)) {
|
|
4504
|
-
ctx.addIssue({
|
|
4505
|
-
code: z19.ZodIssueCode.custom,
|
|
4506
|
-
path: ["success", "mocks", i, "service"],
|
|
4507
|
-
message: `success.mocks[${i}] references unknown mock service "${expectation.service}"`
|
|
4508
|
-
});
|
|
4509
|
-
}
|
|
4510
|
-
if (expectation.requiredTools && expectation.requiredTools.length > 0) {
|
|
4511
|
-
const target = mockById.get(expectation.service);
|
|
4512
|
-
if (target && target.kind !== "mcp") {
|
|
4513
|
-
ctx.addIssue({
|
|
4514
|
-
code: z19.ZodIssueCode.custom,
|
|
4515
|
-
path: ["success", "mocks", i, "requiredTools"],
|
|
4516
|
-
message: `success.mocks[${i}].requiredTools requires an mcp service; "${expectation.service}" is kind "${target.kind}"`
|
|
4517
|
-
});
|
|
4518
|
-
} else if (target?.kind === "mcp") {
|
|
4519
|
-
const declared = new Set(target.tools.map((tool) => tool.name));
|
|
4520
|
-
for (const name of expectation.requiredTools) {
|
|
4521
|
-
if (!declared.has(name)) {
|
|
4522
|
-
ctx.addIssue({
|
|
4523
|
-
code: z19.ZodIssueCode.custom,
|
|
4524
|
-
path: ["success", "mocks", i, "requiredTools"],
|
|
4525
|
-
message: `success.mocks[${i}].requiredTools names undeclared tool "${name}" on mcp service "${expectation.service}"`
|
|
4526
|
-
});
|
|
4527
|
-
}
|
|
4528
|
-
}
|
|
4529
|
-
}
|
|
4530
|
-
}
|
|
4531
|
-
if (expectation.toolCalls && Object.keys(expectation.toolCalls).length > 0) {
|
|
4532
|
-
const target = mockById.get(expectation.service);
|
|
4533
|
-
if (target && target.kind !== "mcp") {
|
|
4534
|
-
ctx.addIssue({
|
|
4535
|
-
code: z19.ZodIssueCode.custom,
|
|
4536
|
-
path: ["success", "mocks", i, "toolCalls"],
|
|
4537
|
-
message: `success.mocks[${i}].toolCalls requires an mcp service; "${expectation.service}" is kind "${target.kind}"`
|
|
4538
|
-
});
|
|
4539
|
-
} else if (target?.kind === "mcp") {
|
|
4540
|
-
const declared = new Set(target.tools.map((tool) => tool.name));
|
|
4541
|
-
for (const name of Object.keys(expectation.toolCalls)) {
|
|
4542
|
-
if (!declared.has(name)) {
|
|
4543
|
-
ctx.addIssue({
|
|
4544
|
-
code: z19.ZodIssueCode.custom,
|
|
4545
|
-
path: ["success", "mocks", i, "toolCalls", name],
|
|
4546
|
-
message: `success.mocks[${i}].toolCalls names undeclared tool "${name}" on mcp service "${expectation.service}"`
|
|
4547
|
-
});
|
|
4548
|
-
}
|
|
4549
|
-
}
|
|
4550
|
-
}
|
|
4551
|
-
}
|
|
4552
|
-
}
|
|
4553
|
-
for (const [i, mock] of spec.mocks.entries()) {
|
|
4554
|
-
if (mock.kind === "http" && mock.credential.name !== `mock.${mock.id}`) {
|
|
4555
|
-
ctx.addIssue({
|
|
4556
|
-
code: z19.ZodIssueCode.custom,
|
|
4557
|
-
path: ["mocks", i, "credential", "name"],
|
|
4558
|
-
message: `http mock "${mock.id}" must use credential name "mock.${mock.id}"`
|
|
4559
|
-
});
|
|
4560
|
-
}
|
|
4561
|
-
}
|
|
4562
|
-
const workspaceFixtures = new Set(
|
|
4563
|
-
spec.setup.files.filter((file) => file.surface === void 0 || file.surface === "workspace").map((file) => file.path)
|
|
4564
|
-
);
|
|
4565
|
-
for (const [i, path] of (spec.success.unchangedFixtures ?? []).entries()) {
|
|
4566
|
-
if (!workspaceFixtures.has(path)) {
|
|
4567
|
-
ctx.addIssue({
|
|
4568
|
-
code: z19.ZodIssueCode.custom,
|
|
4569
|
-
path: ["success", "unchangedFixtures", i],
|
|
4570
|
-
message: `unchanged fixture "${path}" is not a seeded workspace file`
|
|
4571
|
-
});
|
|
4572
|
-
}
|
|
4573
|
-
}
|
|
4574
|
-
for (const [i, expectation] of (spec.success.history ?? []).entries()) {
|
|
4575
|
-
if (expectation.maxEntries !== void 0 && expectation.minEntries > expectation.maxEntries) {
|
|
4576
|
-
ctx.addIssue({
|
|
4577
|
-
code: z19.ZodIssueCode.custom,
|
|
4578
|
-
path: ["success", "history", i],
|
|
4579
|
-
message: "minEntries must be less than or equal to maxEntries"
|
|
4580
|
-
});
|
|
4581
|
-
}
|
|
4582
|
-
}
|
|
4583
|
-
});
|
|
4584
|
-
function parseCraftbookTestSpec(raw, opts) {
|
|
4585
|
-
const mode = opts?.mode ?? "strict";
|
|
4586
|
-
const candidate = mode === "tolerant" ? deepStripUnknown(raw) : raw;
|
|
4587
|
-
const parsed = CraftbookTestSpecSchema.safeParse(candidate);
|
|
4588
|
-
if (parsed.success) return { ok: true, spec: parsed.data };
|
|
4589
|
-
return {
|
|
4590
|
-
ok: false,
|
|
4591
|
-
errors: parsed.error.issues.map((issue) => {
|
|
4592
|
-
const path = issue.path.length > 0 ? issue.path.map(String).join(".") : "<root>";
|
|
4593
|
-
return `${path}: ${issue.message}`;
|
|
4594
|
-
})
|
|
4595
|
-
};
|
|
4596
|
-
}
|
|
4597
|
-
function deepStripUnknown(raw) {
|
|
4598
|
-
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
|
|
4599
|
-
const record = structuredClone(raw);
|
|
4600
|
-
const version = record.schemaVersion;
|
|
4601
|
-
if (typeof version === "number" && Number.isInteger(version) && version > CRAFTBOOK_TEST_SCHEMA_VERSION) {
|
|
4602
|
-
record.schemaVersion = CRAFTBOOK_TEST_SCHEMA_VERSION;
|
|
4603
|
-
}
|
|
4604
|
-
for (let pass = 0; pass < 16; pass++) {
|
|
4605
|
-
const attempt = CraftbookTestSpecSchema.safeParse(record);
|
|
4606
|
-
if (attempt.success) return record;
|
|
4607
|
-
const unknownKeyIssues = attempt.error.issues.filter(
|
|
4608
|
-
(issue) => issue.code === z19.ZodIssueCode.unrecognized_keys
|
|
4609
|
-
);
|
|
4610
|
-
if (unknownKeyIssues.length === 0) return record;
|
|
4611
|
-
for (const issue of unknownKeyIssues) {
|
|
4612
|
-
const target = resolvePath(record, issue.path);
|
|
4613
|
-
if (target && typeof target === "object" && !Array.isArray(target)) {
|
|
4614
|
-
for (const key of issue.keys) delete target[key];
|
|
4615
|
-
}
|
|
4616
|
-
}
|
|
4617
|
-
}
|
|
4618
|
-
return record;
|
|
4619
|
-
}
|
|
4620
|
-
function resolvePath(root, path) {
|
|
4621
|
-
let node = root;
|
|
4622
|
-
for (const segment of path) {
|
|
4623
|
-
if (node === null || typeof node !== "object") return void 0;
|
|
4624
|
-
node = node[segment];
|
|
4625
|
-
}
|
|
4626
|
-
return node;
|
|
4627
|
-
}
|
|
4628
|
-
|
|
4629
|
-
// src/schemas/codex-setup.ts
|
|
4630
|
-
import { z as z20 } from "zod";
|
|
4631
|
-
var CodexSetupModelOptionSchema = z20.object({
|
|
4632
|
-
id: z20.string().min(1),
|
|
4633
|
-
label: z20.string().min(1),
|
|
4634
|
-
description: z20.string().optional(),
|
|
4635
|
-
kind: z20.enum(["gezel", "model"]).default("model"),
|
|
4636
|
-
provider: z20.string().min(1),
|
|
4637
|
-
/** Stable gezel id for persona-backed entries. Absent on raw-model entries. */
|
|
4638
|
-
gezelId: z20.string().min(1).optional(),
|
|
4639
|
-
role: z20.string().min(1).optional(),
|
|
4640
|
-
/** Human-readable name of the effective inference model behind a gezel. */
|
|
4641
|
-
modelLabel: z20.string().min(1).optional(),
|
|
4642
|
-
contextWindow: z20.number().int().positive().optional(),
|
|
4643
|
-
supportsReasoning: z20.boolean().optional(),
|
|
4644
|
-
supportsTools: z20.boolean().optional()
|
|
4645
|
-
});
|
|
4646
|
-
var CodexSetupStateSchema = z20.enum([
|
|
4647
|
-
"not-configured",
|
|
4648
|
-
"configured",
|
|
4649
|
-
"update-needed",
|
|
4650
|
-
"conflict",
|
|
4651
|
-
"unavailable"
|
|
4652
|
-
]);
|
|
4653
|
-
var CodexSetupStatusResponseSchema = z20.object({
|
|
4654
|
-
state: CodexSetupStateSchema,
|
|
4655
|
-
models: z20.array(CodexSetupModelOptionSchema),
|
|
4656
|
-
configuredModel: z20.string().optional(),
|
|
4657
|
-
recommendedModel: z20.string().optional(),
|
|
4658
|
-
reasons: z20.array(z20.string()),
|
|
4659
|
-
message: z20.string().optional(),
|
|
4660
|
-
codexInstalled: z20.boolean(),
|
|
4661
|
-
codexVersion: z20.string().optional(),
|
|
4662
|
-
codexPath: z20.string().optional(),
|
|
4663
|
-
endpointsEnabled: z20.boolean(),
|
|
4664
|
-
profileName: z20.string().min(1),
|
|
4665
|
-
profilePath: z20.string().min(1),
|
|
4666
|
-
launchCommand: z20.string().min(1),
|
|
4667
|
-
bridge: z20.object({
|
|
4668
|
-
baseUrl: z20.string().url(),
|
|
4669
|
-
listening: z20.boolean(),
|
|
4670
|
-
port: z20.number().int().nonnegative()
|
|
4671
|
-
}),
|
|
4672
|
-
canConfigure: z20.boolean(),
|
|
4673
|
-
/** Whether Gezel-owned credential/state material exists and can be safely removed. */
|
|
4674
|
-
canRemove: z20.boolean()
|
|
4675
|
-
});
|
|
4676
|
-
var ConfigureCodexRequestSchema = z20.object({
|
|
4677
|
-
model: z20.string().min(1)
|
|
4678
|
-
});
|
|
4679
|
-
|
|
4680
|
-
// src/schemas/project.ts
|
|
4681
|
-
import { z as z21 } from "zod";
|
|
4682
|
-
var HttpsOriginSchema = z21.string().url().refine(
|
|
4683
|
-
(value) => {
|
|
4684
|
-
try {
|
|
4685
|
-
const url = new URL(value);
|
|
4686
|
-
return url.protocol === "https:" && !url.username && !url.password && url.pathname === "/" && !url.search && !url.hash;
|
|
4687
|
-
} catch {
|
|
4688
|
-
return false;
|
|
4689
|
-
}
|
|
4690
|
-
},
|
|
4691
|
-
{ message: "must be an exact HTTPS origin (for example https://api.example.com)" }
|
|
4692
|
-
);
|
|
4693
|
-
var ProjectGitHubSchema = z21.object({
|
|
4694
|
-
// Accept any non-empty string. Git URLs come in many forms beyond
|
|
4695
|
-
// `https://`: ssh shorthand (`git@github.com:owner/repo`), local
|
|
4696
|
-
// filesystem paths (`/path/to/bare.git`), other-host references.
|
|
4697
|
-
// The strict `.url()` validator rejected the filesystem-path form
|
|
4698
|
-
// and broke Phase-3 worktree tests that use a local bare repo as
|
|
4699
|
-
// the upstream. Higher layers (the github sync code) parse the URL
|
|
4700
|
-
// and reject anything that doesn't shape up as a clonable ref.
|
|
4701
|
-
url: z21.string().min(1),
|
|
4702
|
-
branch: z21.string().optional(),
|
|
4703
|
-
/** Resolved absolute path to the working tree. Managed by the service. */
|
|
4704
|
-
checkoutDir: z21.string().optional(),
|
|
4705
|
-
lastSyncedAt: z21.string().optional(),
|
|
4706
|
-
/** Repo default branch (e.g. "main"), detected lazily and cached. Managed by the service. */
|
|
4707
|
-
defaultBranch: z21.string().optional()
|
|
4708
|
-
});
|
|
4709
|
-
var ProjectConnectorBindingSchema = z21.object({
|
|
4710
|
-
/** Stable binding id; also the SecretStore `fieldId` + corpus-slug seed. */
|
|
4711
|
-
id: z21.string().min(1),
|
|
4712
|
-
/** The connector-type catalog id, e.g. `mail-gmail`, `linear-issues`. */
|
|
4713
|
-
type: z21.string().min(1),
|
|
4714
|
-
/** Catalog source the type resolved from (provenance/pin). */
|
|
4715
|
-
sourceId: z21.string().optional(),
|
|
4716
|
-
/** Pinned connector-type version. */
|
|
4717
|
-
version: z21.string().optional(),
|
|
4718
|
-
displayName: z21.string().optional(),
|
|
4719
|
-
/**
|
|
4720
|
-
* Artifact-relative corpus root (`data/<corpusName>`), resolved once at bind
|
|
4721
|
-
* time and never recomputed — renaming a binding must not strand its corpus.
|
|
4722
|
-
*/
|
|
4723
|
-
corpusDir: z21.string().optional(),
|
|
4724
|
-
/** Per-binding config, validated at bind time against the type's `configSchema`. */
|
|
4725
|
-
config: z21.record(z21.string(), z21.unknown()).default({}),
|
|
4726
|
-
/** Opaque, adapter-shaped incremental-sync cursor. Persisted so resync resumes. */
|
|
4727
|
-
cursor: z21.unknown().optional(),
|
|
4728
|
-
/** Pause syncing without unbinding. */
|
|
4729
|
-
disabled: z21.boolean().optional(),
|
|
4730
|
-
lastSyncedAt: z21.string().optional(),
|
|
4731
|
-
/** Last sync error, surfaced in the UI; cleared on the next success. */
|
|
4732
|
-
lastError: z21.string().optional()
|
|
4733
|
-
});
|
|
4734
|
-
var ProjectNudgeConfigSchema = z21.object({
|
|
4735
|
-
enabled: z21.boolean().optional(),
|
|
4736
|
-
rapidIntervalMs: z21.number().int().positive().optional(),
|
|
4737
|
-
slowIntervalMs: z21.number().int().positive().optional(),
|
|
4738
|
-
recentActivityWindowMs: z21.number().int().positive().optional(),
|
|
4739
|
-
rapidAttemptsBeforeBackoff: z21.number().int().positive().optional(),
|
|
4740
|
-
/**
|
|
4741
|
-
* Grace period applied to the very first nudge a project ever
|
|
4742
|
-
* receives, measured from `project.createdAt`. Default per tempo;
|
|
4743
|
-
* setting `0` opts out (legacy behavior — first nudge fires as
|
|
4744
|
-
* soon as the rapid interval allows).
|
|
4745
|
-
*/
|
|
4746
|
-
firstNudgeGraceMs: z21.number().int().nonnegative().optional()
|
|
4747
|
-
});
|
|
4748
|
-
var ProjectNudgeStateSchema = z21.object({
|
|
4749
|
-
lastNudgedAt: z21.string().optional(),
|
|
4750
|
-
consecutiveRapidNudges: z21.number().int().nonnegative().optional()
|
|
4751
|
-
});
|
|
4752
|
-
var ProjectTabVisibilitySchema = z21.object({
|
|
4753
|
-
overview: z21.boolean().optional(),
|
|
4754
|
-
tasks: z21.boolean().optional(),
|
|
4755
|
-
approvals: z21.boolean().optional(),
|
|
4756
|
-
workspace: z21.boolean().optional(),
|
|
4757
|
-
artifacts: z21.boolean().optional(),
|
|
4758
|
-
map: z21.boolean().optional()
|
|
4759
|
-
}).strict();
|
|
4760
|
-
var ProjectManagedWorkspaceWritePolicySchema = z21.enum(["auto", "allow", "deny"]);
|
|
4761
|
-
var ProjectTypeProvenanceSchema = z21.object({
|
|
4762
|
-
/** Catalog id of the applied project type. */
|
|
4763
|
-
id: z21.string(),
|
|
4764
|
-
/** Type version installed at adoption. */
|
|
4765
|
-
version: z21.string(),
|
|
4766
|
-
/** Catalog source the type resolved from (`bundled` | `local` | `community` | …). */
|
|
4767
|
-
source: z21.string(),
|
|
4768
|
-
/** Param values collected at adoption, substituted into templates + seed files. */
|
|
4769
|
-
params: z21.record(z21.string(), z21.unknown()).optional(),
|
|
4770
|
-
/** ISO timestamp of adoption. */
|
|
4771
|
-
appliedAt: z21.string()
|
|
4772
|
-
});
|
|
4773
|
-
var ProjectSchema = z21.object({
|
|
4774
|
-
id: EntityIdSchema,
|
|
4775
|
-
name: z21.string(),
|
|
4776
|
-
description: z21.string().optional(),
|
|
4777
|
-
workingDir: z21.string().optional(),
|
|
4778
|
-
/** Optional gezel that acts as the project's voorman (foreman). Surfaces in
|
|
4779
|
-
* the project detail pane, flows into the system prompt when a session is
|
|
4780
|
-
* scoped here. For solo projects (`mode === 'solo'`) this same field
|
|
4781
|
-
* holds the project's ambachtsman — the data is unchanged, only the
|
|
4782
|
-
* label flips. */
|
|
4783
|
-
voormanGezelId: z21.string().optional(),
|
|
4784
|
-
/**
|
|
4785
|
-
* Internal marker: ISO timestamp of the one-time automatic voorman
|
|
4786
|
-
* assignment. The indexer ensures every project ends up with a voorman
|
|
4787
|
-
* — adopting the `@project` gezel minted from an AGENTS.md/CLAUDE.md, or
|
|
4788
|
-
* (when there's no instruction file) promoting an existing roster gezel.
|
|
4789
|
-
* Set once a voorman has been ensured so a later *manual* clear isn't
|
|
4790
|
-
* silently re-populated on the next scan. Not user-editable; absent on
|
|
4791
|
-
* projects last written before this field existed.
|
|
4792
|
-
*/
|
|
4793
|
-
voormanAutoAssignedAt: z21.string().optional(),
|
|
4794
|
-
/**
|
|
4795
|
-
* Roster — gezels that have been pulled into this project. Populated
|
|
4796
|
-
* automatically the first time a gezel is set as voorman, opens a
|
|
4797
|
-
* session scoped here, is pinged via `message_gezel` / `ask_gezel`,
|
|
4798
|
-
* or is assigned to a task; can also be edited explicitly via the
|
|
4799
|
-
* `add_gezel_to_project` / `remove_gezel_from_project` MCP tools.
|
|
4800
|
-
*
|
|
4801
|
-
* Advisory: not used to gate access — any gezel can still chat or be
|
|
4802
|
-
* assigned to a task here; the roster is for "team" UX surfacing,
|
|
4803
|
-
* notification scoping, and tracking who actually does work in the
|
|
4804
|
-
* project. Order is not significant. Missing on disk → empty roster
|
|
4805
|
-
* (back-compat with every project written before this field
|
|
4806
|
-
* existed).
|
|
4807
|
-
*/
|
|
4808
|
-
gezelIds: z21.array(z21.string()).optional(),
|
|
4809
|
-
/**
|
|
4810
|
-
* Suggested-work keys the user has dismissed ("don't offer this again
|
|
4811
|
-
* here"). Advisory UI state, same spirit as `gezelIds`: enabling a
|
|
4812
|
-
* dismissed key un-dismisses it, and a materialized host always
|
|
4813
|
-
* outranks a dismissal. Keys are the stable suggested-work identities
|
|
4814
|
-
* (`gezel-template:<templateId>:<craftbookId>[#N]` /
|
|
4815
|
-
* `project-type:<typeId>:<scheduleKey>`). Deliberately not exposed
|
|
4816
|
-
* through the model-facing `update_project` MCP tool.
|
|
4817
|
-
*/
|
|
4818
|
-
suggestedWorkDismissed: z21.array(z21.string()).optional(),
|
|
4819
|
-
/**
|
|
4820
|
-
* Shared per-project configuration values ("project properties") that
|
|
4821
|
-
* craftbook params and features draw from — e.g. `content.language`,
|
|
4822
|
-
* the designated language a translator gezel targets. Keys are ids
|
|
4823
|
-
* from the well-known registry in `project-properties.ts`, but unknown
|
|
4824
|
-
* ids are allowed (the registry improves display, it doesn't gate).
|
|
4825
|
-
* Values are plain strings; empty string is treated as unset.
|
|
4826
|
-
*/
|
|
4827
|
-
properties: z21.record(z21.string(), z21.string()).optional(),
|
|
4445
|
+
properties: z19.record(z19.string(), z19.string()).optional(),
|
|
4828
4446
|
/**
|
|
4829
4447
|
* Project shape. `crew` (the default) is the original behavior — the
|
|
4830
4448
|
* voorman recruits and coordinates a team of specialists. `solo` is a
|
|
4831
|
-
* "job" — a single
|
|
4449
|
+
* "job" — a single Builder (stored in
|
|
4832
4450
|
* `voormanGezelId`) handles the whole project themselves; team-
|
|
4833
4451
|
* management MCP tools are stripped from their session, and the
|
|
4834
4452
|
* Meester is instructed not to nominate other gezels. Missing → `crew`
|
|
4835
4453
|
* for back-compat with every project on disk before this field
|
|
4836
4454
|
* existed.
|
|
4837
4455
|
*/
|
|
4838
|
-
mode:
|
|
4456
|
+
mode: z19.enum(["crew", "solo"]).optional(),
|
|
4839
4457
|
/**
|
|
4840
4458
|
* Optional custom label for this project's lead gezel, overriding the
|
|
4841
|
-
* mode-based default ("Voorman" / "
|
|
4459
|
+
* mode-based default ("Voorman" / "Builder") everywhere the UI
|
|
4842
4460
|
* renders it. Set by a project type at adoption (e.g. checkers →
|
|
4843
4461
|
* "Opponent"); absent → the mode default. The data field stays
|
|
4844
4462
|
* `voormanGezelId` — only the label changes.
|
|
4845
4463
|
*/
|
|
4846
|
-
leadLabel:
|
|
4464
|
+
leadLabel: z19.string().optional(),
|
|
4847
4465
|
/**
|
|
4848
4466
|
* Lean-agent profile (set by a project type at adoption, e.g. checkers).
|
|
4849
4467
|
* When true, sessions here get a minimal tool surface (the type's script
|
|
@@ -4851,7 +4469,7 @@ var ProjectSchema = z21.object({
|
|
|
4851
4469
|
* scaffolding). Keeps small local models from being overwhelmed on a
|
|
4852
4470
|
* focused single-purpose task. Absent → the full agent profile.
|
|
4853
4471
|
*/
|
|
4854
|
-
leanProfile:
|
|
4472
|
+
leanProfile: z19.boolean().optional(),
|
|
4855
4473
|
/**
|
|
4856
4474
|
* Per-project workspace-indexing switch. Missing/true preserves the
|
|
4857
4475
|
* historical behavior: structural discovery plus the content-index refresh
|
|
@@ -4864,9 +4482,9 @@ var ProjectSchema = z21.object({
|
|
|
4864
4482
|
* document index. Project-type manifests may seed the value at adoption and
|
|
4865
4483
|
* the user can override it later in Project Settings.
|
|
4866
4484
|
*/
|
|
4867
|
-
indexingEnabled:
|
|
4485
|
+
indexingEnabled: z19.boolean().optional(),
|
|
4868
4486
|
github: ProjectGitHubSchema.optional(),
|
|
4869
|
-
connectors:
|
|
4487
|
+
connectors: z19.array(ProjectConnectorBindingSchema).optional(),
|
|
4870
4488
|
nudgeConfig: ProjectNudgeConfigSchema.optional(),
|
|
4871
4489
|
nudgeState: ProjectNudgeStateSchema.optional(),
|
|
4872
4490
|
/**
|
|
@@ -4889,7 +4507,7 @@ var ProjectSchema = z21.object({
|
|
|
4889
4507
|
* @deprecated Use `managedWorkspaceWritePolicy` and the centralized
|
|
4890
4508
|
* `projectManagedWorkspaceWritable` resolver.
|
|
4891
4509
|
*/
|
|
4892
|
-
allowGezelWrites:
|
|
4510
|
+
allowGezelWrites: z19.boolean().optional(),
|
|
4893
4511
|
/**
|
|
4894
4512
|
* Per-project Codex execution posture selected from the project status bar.
|
|
4895
4513
|
* It overrides per-gezel/install Codex defaults so the visible control is
|
|
@@ -4926,7 +4544,7 @@ var ProjectSchema = z21.object({
|
|
|
4926
4544
|
* weak local model having to take an explicit action. Reversible and
|
|
4927
4545
|
* non-destructive; chat and direct tool calls keep working.
|
|
4928
4546
|
*/
|
|
4929
|
-
status:
|
|
4547
|
+
status: z19.enum(["active", "readonly", "inactive", "stable"]).optional(),
|
|
4930
4548
|
/**
|
|
4931
4549
|
* Bury this project in the navigation without deleting it. Archived
|
|
4932
4550
|
* projects remain available from the dedicated section in the full
|
|
@@ -4936,13 +4554,13 @@ var ProjectSchema = z21.object({
|
|
|
4936
4554
|
* Missing/false means visible in the ordinary project UX, preserving
|
|
4937
4555
|
* compatibility with projects written before archiving existed.
|
|
4938
4556
|
*/
|
|
4939
|
-
archived:
|
|
4557
|
+
archived: z19.boolean().optional(),
|
|
4940
4558
|
/**
|
|
4941
4559
|
* Per-project override of the `run_nodejs_script` wall-clock
|
|
4942
4560
|
* timeout. Clamped between 30 seconds and 30 minutes. Missing →
|
|
4943
4561
|
* the service-side default (5 min) applies.
|
|
4944
4562
|
*/
|
|
4945
|
-
workspaceScriptTimeoutMs:
|
|
4563
|
+
workspaceScriptTimeoutMs: z19.number().int().min(3e4).max(30 * 6e4).optional(),
|
|
4946
4564
|
/**
|
|
4947
4565
|
* Named credentials this project is explicitly allowed to use.
|
|
4948
4566
|
* Credentials are stored once globally in `SecretStore`; a grant
|
|
@@ -4951,13 +4569,13 @@ var ProjectSchema = z21.object({
|
|
|
4951
4569
|
* Missing → no credentials granted. See `scripts/dispatcher.ts`
|
|
4952
4570
|
* and `secrets/registry.ts` for resolution.
|
|
4953
4571
|
*/
|
|
4954
|
-
grantedCredentials:
|
|
4572
|
+
grantedCredentials: z19.array(z19.string()).optional(),
|
|
4955
4573
|
/**
|
|
4956
4574
|
* Advanced exact-origin bindings for toolset credentials. Built-in provider
|
|
4957
4575
|
* credentials are service-pinned and webhook credentials follow the
|
|
4958
4576
|
* configured webhook URL, so entries for those names are ignored.
|
|
4959
4577
|
*/
|
|
4960
|
-
credentialAllowedOrigins:
|
|
4578
|
+
credentialAllowedOrigins: z19.record(z19.string(), z19.array(HttpsOriginSchema)).optional(),
|
|
4961
4579
|
/**
|
|
4962
4580
|
* Explicit user override of the project's type (an id from the bundled
|
|
4963
4581
|
* project-type taxonomy, see `project-types/taxonomy.ts`). When set, it
|
|
@@ -4965,17 +4583,17 @@ var ProjectSchema = z21.object({
|
|
|
4965
4583
|
* (unset) → fall back to auto-detection. Missing on every project written
|
|
4966
4584
|
* before this field existed.
|
|
4967
4585
|
*/
|
|
4968
|
-
projectTypeId:
|
|
4586
|
+
projectTypeId: z19.string().optional(),
|
|
4969
4587
|
/**
|
|
4970
4588
|
* Auto-detected project type, recomputed on each content-index scan from
|
|
4971
4589
|
* the workspace file mix + about/mission text. Not user-editable — the
|
|
4972
4590
|
* user expresses an override via `projectTypeId`. Absent until the first
|
|
4973
4591
|
* scan classifies the project (or when nothing scores above the floor).
|
|
4974
4592
|
*/
|
|
4975
|
-
detectedProjectType:
|
|
4976
|
-
id:
|
|
4977
|
-
score:
|
|
4978
|
-
scannedAt:
|
|
4593
|
+
detectedProjectType: z19.object({
|
|
4594
|
+
id: z19.string(),
|
|
4595
|
+
score: z19.number(),
|
|
4596
|
+
scannedAt: z19.string()
|
|
4979
4597
|
}).optional(),
|
|
4980
4598
|
/**
|
|
4981
4599
|
* Provenance of an applied custom project type (see docs/project-types.md).
|
|
@@ -4991,9 +4609,9 @@ var ProjectSchema = z21.object({
|
|
|
4991
4609
|
* installer-managed shared root and operated on by this user's daemon.
|
|
4992
4610
|
* The engine broker never opens the project or receives its paths.
|
|
4993
4611
|
*/
|
|
4994
|
-
storageScope:
|
|
4995
|
-
createdAt:
|
|
4996
|
-
updatedAt:
|
|
4612
|
+
storageScope: z19.enum(["user", "machine-shared"]).optional(),
|
|
4613
|
+
createdAt: z19.string(),
|
|
4614
|
+
updatedAt: z19.string()
|
|
4997
4615
|
});
|
|
4998
4616
|
function resolveProjectTypeId(project) {
|
|
4999
4617
|
return project.projectTypeId ?? project.detectedProjectType?.id;
|
|
@@ -5002,435 +4620,898 @@ function projectAllowsAmbientWork(project) {
|
|
|
5002
4620
|
const status = project.status ?? "active";
|
|
5003
4621
|
return status === "active";
|
|
5004
4622
|
}
|
|
5005
|
-
var InstalledPackageSchema =
|
|
5006
|
-
name:
|
|
5007
|
-
version:
|
|
4623
|
+
var InstalledPackageSchema = z19.object({
|
|
4624
|
+
name: z19.string(),
|
|
4625
|
+
version: z19.string()
|
|
5008
4626
|
});
|
|
5009
4627
|
var ProjectDetailSchema = ProjectSchema.extend({
|
|
5010
|
-
packages:
|
|
4628
|
+
packages: z19.array(InstalledPackageSchema),
|
|
5011
4629
|
/** Contents of `documents/about.md` inside the project, if present. */
|
|
5012
|
-
about:
|
|
4630
|
+
about: z19.string().optional(),
|
|
5013
4631
|
/** Contents of `documents/missionObjectives.md`, if present. */
|
|
5014
|
-
missionObjectives:
|
|
4632
|
+
missionObjectives: z19.string().optional()
|
|
5015
4633
|
});
|
|
5016
|
-
var ProjectFileEntrySchema =
|
|
5017
|
-
name:
|
|
5018
|
-
path:
|
|
5019
|
-
isDirectory:
|
|
4634
|
+
var ProjectFileEntrySchema = z19.object({
|
|
4635
|
+
name: z19.string(),
|
|
4636
|
+
path: z19.string(),
|
|
4637
|
+
isDirectory: z19.boolean(),
|
|
5020
4638
|
/** File mtime (ms epoch). Populated only when the caller opts into stats. */
|
|
5021
|
-
mtimeMs:
|
|
4639
|
+
mtimeMs: z19.number().optional()
|
|
5022
4640
|
});
|
|
5023
4641
|
var ProjectGithubSchema = ProjectGitHubSchema;
|
|
5024
4642
|
|
|
5025
|
-
// src/schemas/
|
|
5026
|
-
|
|
5027
|
-
var
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
4643
|
+
// src/schemas/craftbook-test.ts
|
|
4644
|
+
var CRAFTBOOK_TEST_SCHEMA_VERSION = 1;
|
|
4645
|
+
var CRAFTBOOK_TEST_FILENAME = "test.json";
|
|
4646
|
+
var PrometheusAlertsCheckSchema = z20.object({
|
|
4647
|
+
kind: z20.literal("prometheusAlerts"),
|
|
4648
|
+
file: z20.string().min(1),
|
|
4649
|
+
minRules: z20.number().int().positive().optional(),
|
|
4650
|
+
maxPageAlerts: z20.number().int().nonnegative().optional(),
|
|
4651
|
+
allowedSeverities: z20.array(z20.string().min(1)).optional(),
|
|
4652
|
+
requiredServices: z20.array(z20.string().min(1)).optional(),
|
|
4653
|
+
requiredRunbookUrls: z20.array(z20.string().min(1)).optional()
|
|
4654
|
+
}).strict();
|
|
4655
|
+
var NodeScriptPassesCheckSchema = z20.object({
|
|
4656
|
+
kind: z20.literal("nodeScriptPasses"),
|
|
4657
|
+
script: z20.string().min(1),
|
|
4658
|
+
timeoutMs: z20.number().int().positive().optional(),
|
|
4659
|
+
requiredOutput: z20.array(
|
|
4660
|
+
z20.object({
|
|
4661
|
+
pattern: z20.string().min(1),
|
|
4662
|
+
flags: z20.string().optional(),
|
|
4663
|
+
label: z20.string().optional()
|
|
4664
|
+
}).strict()
|
|
4665
|
+
).optional()
|
|
4666
|
+
}).strict();
|
|
4667
|
+
var BinaryDocumentCheckSchema = z20.object({
|
|
4668
|
+
kind: z20.literal("binaryDocument"),
|
|
4669
|
+
file: z20.string().min(1),
|
|
4670
|
+
/** Look in the artifacts drawer instead of the workspace. */
|
|
4671
|
+
artifact: z20.boolean().optional(),
|
|
4672
|
+
/** Floor on the container's byte length; defaults to 1000. */
|
|
4673
|
+
minBytes: z20.number().int().positive().optional()
|
|
4674
|
+
}).strict();
|
|
4675
|
+
var CraftbookTestCheckSchema = z20.union([
|
|
4676
|
+
GateCheckSchema,
|
|
4677
|
+
PrometheusAlertsCheckSchema,
|
|
4678
|
+
NodeScriptPassesCheckSchema,
|
|
4679
|
+
BinaryDocumentCheckSchema
|
|
5031
4680
|
]);
|
|
5032
|
-
var
|
|
5033
|
-
var
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
/**
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
})
|
|
5071
|
-
|
|
5072
|
-
|
|
5073
|
-
|
|
5074
|
-
|
|
5075
|
-
|
|
5076
|
-
})
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
})
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
expression: z23.string(),
|
|
5120
|
-
lastTickAt: z23.string().optional(),
|
|
5121
|
-
nextTickAt: z23.string().optional(),
|
|
5122
|
-
overlap: TaskCronOverlapSchema.optional()
|
|
5123
|
-
});
|
|
5124
|
-
var TaskVariationSchema = z23.object({
|
|
5125
|
-
title: z23.string().optional(),
|
|
5126
|
-
plan: z23.string().optional(),
|
|
5127
|
-
description: z23.string().optional(),
|
|
5128
|
-
context: z23.record(z23.string(), z23.string()).optional()
|
|
5129
|
-
});
|
|
5130
|
-
var TaskFanoutSchema = z23.object({
|
|
5131
|
-
count: z23.number().int().positive(),
|
|
5132
|
-
variations: z23.array(TaskVariationSchema).optional(),
|
|
5133
|
-
materializedAt: z23.string().optional()
|
|
5134
|
-
});
|
|
5135
|
-
var NewTaskFanoutSchema = z23.object({
|
|
5136
|
-
count: z23.number().int().positive(),
|
|
5137
|
-
variations: z23.array(TaskVariationSchema).optional()
|
|
5138
|
-
});
|
|
5139
|
-
var TaskNightShiftSchema = z23.object({
|
|
5140
|
-
enabled: z23.boolean(),
|
|
5141
|
-
onceADay: z23.boolean().optional(),
|
|
5142
|
-
lastRunDay: z23.string().optional()
|
|
5143
|
-
});
|
|
5144
|
-
var TaskCraftbookStepSchema = CraftbookStepSchema.extend({
|
|
5145
|
-
createdAt: z23.string(),
|
|
5146
|
-
completedAt: z23.string().optional(),
|
|
5147
|
-
attemptCount: z23.number().int().nonnegative().optional(),
|
|
5148
|
-
lastActivatedAt: z23.string().optional(),
|
|
5149
|
-
/**
|
|
5150
|
-
* Completion-gate rejections since this step last activated. Distinct
|
|
5151
|
-
* from `attemptCount` (which counts ACTIVATIONS — loop-backs): a
|
|
5152
|
-
* rejection holds the step active without re-activating it. Reset by
|
|
5153
|
-
* `bumpStepActivation` so a loop-back grants a fresh budget.
|
|
5154
|
-
*/
|
|
5155
|
-
gateAttempts: z23.number().int().nonnegative().optional(),
|
|
4681
|
+
var MockServiceIdSchema = z20.string().min(1).regex(/^[a-z0-9][a-z0-9-]*$/, "mock service ids are lowercase kebab-case");
|
|
4682
|
+
var MockToolsetIdSchema = z20.string().min(1).regex(
|
|
4683
|
+
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/,
|
|
4684
|
+
"mock toolset ids are lowercase catalog ids or scoped npm-style ids"
|
|
4685
|
+
);
|
|
4686
|
+
var MockHttpRouteSchema = z20.object({
|
|
4687
|
+
method: z20.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).default("GET"),
|
|
4688
|
+
/** Exact path, `:param` segments, or a trailing `*` wildcard. */
|
|
4689
|
+
path: z20.string().min(1),
|
|
4690
|
+
status: z20.number().int().min(100).max(599).default(200),
|
|
4691
|
+
headers: z20.record(z20.string(), z20.string()).optional(),
|
|
4692
|
+
/** String bodies are served verbatim; anything else is JSON-encoded. */
|
|
4693
|
+
body: z20.unknown(),
|
|
4694
|
+
latencyMs: z20.number().int().nonnegative().optional()
|
|
4695
|
+
}).strict();
|
|
4696
|
+
var MockServiceSchema = z20.discriminatedUnion("kind", [
|
|
4697
|
+
z20.object({
|
|
4698
|
+
kind: z20.literal("http"),
|
|
4699
|
+
id: MockServiceIdSchema,
|
|
4700
|
+
description: z20.string().min(1),
|
|
4701
|
+
/**
|
|
4702
|
+
* v1 mock HTTP is reachable ONLY through the `http.authed`
|
|
4703
|
+
* credential rail (anonymous script/browser HTTP hard-rejects
|
|
4704
|
+
* loopback), so a credential is required. The harness seeds it and
|
|
4705
|
+
* grants the mock's exact origin on the trial project.
|
|
4706
|
+
*/
|
|
4707
|
+
credential: z20.object({
|
|
4708
|
+
name: z20.string().regex(/^mock\.[a-z0-9][a-z0-9.-]*$/, "mock credentials are named mock.<service-id>"),
|
|
4709
|
+
authScheme: z20.enum(["bearer", "basic"]).optional()
|
|
4710
|
+
}).strict(),
|
|
4711
|
+
routes: z20.array(MockHttpRouteSchema).min(1)
|
|
4712
|
+
}).strict(),
|
|
4713
|
+
z20.object({
|
|
4714
|
+
kind: z20.literal("webhook"),
|
|
4715
|
+
id: MockServiceIdSchema,
|
|
4716
|
+
description: z20.string().min(1),
|
|
4717
|
+
/** Receiver path; defaults to `/webhook` when omitted. */
|
|
4718
|
+
path: z20.string().min(1).optional()
|
|
4719
|
+
}).strict(),
|
|
4720
|
+
z20.object({
|
|
4721
|
+
kind: z20.literal("cli"),
|
|
4722
|
+
id: MockServiceIdSchema,
|
|
4723
|
+
description: z20.string().min(1),
|
|
4724
|
+
/** Fake-CLI shim seeded as a workspace file (today's dry-run pattern). */
|
|
4725
|
+
shim: z20.object({ path: z20.string().min(1), content: z20.string() }).strict()
|
|
4726
|
+
}).strict(),
|
|
4727
|
+
z20.object({
|
|
4728
|
+
kind: z20.literal("mcp"),
|
|
4729
|
+
id: MockServiceIdSchema,
|
|
4730
|
+
description: z20.string().min(1),
|
|
4731
|
+
/** Override the local-catalog id when the mock replaces a real dependency. */
|
|
4732
|
+
toolsetId: MockToolsetIdSchema.optional(),
|
|
4733
|
+
/**
|
|
4734
|
+
* Served live by the eval mock rail: each declared tool becomes a
|
|
4735
|
+
* real tool on a per-trial Streamable-HTTP MCP endpoint, installed
|
|
4736
|
+
* into the trial via a local-catalog `mock-mcp-<id>` toolset.
|
|
4737
|
+
* `resultTemplate` is JSON-encoded as the tool result text
|
|
4738
|
+
* (default `{"ok":true}` when absent).
|
|
4739
|
+
*/
|
|
4740
|
+
tools: z20.array(
|
|
4741
|
+
z20.object({
|
|
4742
|
+
name: z20.string().min(1),
|
|
4743
|
+
description: z20.string().min(1),
|
|
4744
|
+
resultTemplate: z20.unknown().optional(),
|
|
4745
|
+
/** Deterministic stateful responses, consumed in call order; the last repeats. */
|
|
4746
|
+
resultSequence: z20.array(z20.unknown()).min(1).optional(),
|
|
4747
|
+
/**
|
|
4748
|
+
* Deterministic eval-only file materialization after this
|
|
4749
|
+
* tool call. The fixture must match the container the
|
|
4750
|
+
* deliverable's extension claims — a `minimal-pptx` written
|
|
4751
|
+
* to a `.docx` path now fails the `binaryDocument` check on
|
|
4752
|
+
* content type rather than sliding through a byte floor.
|
|
4753
|
+
*/
|
|
4754
|
+
writeFixture: z20.object({
|
|
4755
|
+
surface: z20.enum(["workspace", "artifact"]),
|
|
4756
|
+
pathArgument: z20.string().min(1),
|
|
4757
|
+
fixture: z20.enum(["minimal-pptx", "minimal-docx", "minimal-pdf", "minimal-png"])
|
|
4758
|
+
}).strict().optional()
|
|
4759
|
+
}).strict()
|
|
4760
|
+
).min(1)
|
|
4761
|
+
}).strict()
|
|
4762
|
+
]);
|
|
4763
|
+
var CraftbookTestFixtureFileSchema = z20.object({
|
|
4764
|
+
path: z20.string().min(1),
|
|
4765
|
+
content: z20.string(),
|
|
4766
|
+
/** Defaults to `workspace`; `harness` never enters the model-visible project. */
|
|
4767
|
+
surface: z20.enum(["workspace", "artifact", "harness"]).optional(),
|
|
5156
4768
|
/**
|
|
5157
|
-
*
|
|
5158
|
-
* to
|
|
5159
|
-
* rejection instead of re-running gate scripts, and the chat nudge
|
|
5160
|
-
* dedupes on `messageFingerprint`.
|
|
4769
|
+
* Whether the fixture is presented to the model as source material.
|
|
4770
|
+
* Defaults to true; false still seeds the file for browsers and graders.
|
|
5161
4771
|
*/
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
4772
|
+
modelInput: z20.boolean().optional()
|
|
4773
|
+
}).strict();
|
|
4774
|
+
var CraftbookTestWorkerSchema = z20.object({
|
|
4775
|
+
name: z20.string().min(1),
|
|
4776
|
+
role: z20.string().min(1),
|
|
4777
|
+
description: z20.string().optional(),
|
|
4778
|
+
about: z20.string().optional()
|
|
4779
|
+
}).strict();
|
|
4780
|
+
var CraftbookTestSetupSchema = z20.object({
|
|
4781
|
+
projectName: z20.string().min(1),
|
|
4782
|
+
about: z20.string().optional(),
|
|
4783
|
+
missionObjectives: z20.string().optional(),
|
|
4784
|
+
/** Reproduce project write posture before the craftbook task starts. */
|
|
4785
|
+
managedWorkspaceWritePolicy: ProjectManagedWorkspaceWritePolicySchema.optional(),
|
|
4786
|
+
files: z20.array(CraftbookTestFixtureFileSchema).default([]),
|
|
4787
|
+
/** Exact values supplied to the catalog craftbook's `paramSchema`. */
|
|
4788
|
+
craftbookParams: z20.record(z20.string(), z20.string()).optional(),
|
|
5168
4789
|
/**
|
|
5169
|
-
*
|
|
5170
|
-
*
|
|
5171
|
-
*
|
|
5172
|
-
* advancing; `lastRedriveAt` = when it last did (also the cooldown
|
|
5173
|
-
* anchor so a re-drive isn't itself read as fresh progress). Distinct
|
|
5174
|
-
* from `attemptCount` (activations) and `gateAttempts` (gate
|
|
5175
|
-
* rejections), which count model-driven events — these count autonomous
|
|
5176
|
-
* re-pokes of a silent assignee. Reset by `bumpStepActivation` so a
|
|
5177
|
-
* fresh activation / loop-back grants a fresh re-drive budget.
|
|
4790
|
+
* Direct execution target. When present the harness seeds this gezel
|
|
4791
|
+
* and sends the kickoff straight to it (measuring whether the book
|
|
4792
|
+
* guides the work); absent → the Meester routes.
|
|
5178
4793
|
*/
|
|
5179
|
-
|
|
5180
|
-
|
|
4794
|
+
worker: CraftbookTestWorkerSchema.optional()
|
|
4795
|
+
}).strict();
|
|
4796
|
+
var CraftbookTestDeliverableSchema = z20.object({
|
|
4797
|
+
path: z20.string().min(1),
|
|
4798
|
+
kind: DeliverableKindSchema,
|
|
4799
|
+
/** Grade the path in the project's artifacts drawer, not its workspace. */
|
|
4800
|
+
artifact: z20.boolean().optional(),
|
|
4801
|
+
minBytes: z20.number().int().positive().optional(),
|
|
4802
|
+
checks: z20.array(CraftbookTestCheckSchema).optional()
|
|
4803
|
+
}).strict();
|
|
4804
|
+
var CraftbookTestMockExpectationSchema = z20.object({
|
|
4805
|
+
/** Mock service id from `mocks[]`. */
|
|
4806
|
+
service: MockServiceIdSchema,
|
|
4807
|
+
minRequests: z20.number().int().positive().optional(),
|
|
4808
|
+
/** Regex sources matched against logged request paths. */
|
|
4809
|
+
requiredPaths: z20.array(z20.string().min(1)).optional(),
|
|
4810
|
+
forbiddenPaths: z20.array(z20.string().min(1)).optional(),
|
|
5181
4811
|
/**
|
|
5182
|
-
*
|
|
5183
|
-
*
|
|
5184
|
-
*
|
|
5185
|
-
*
|
|
5186
|
-
*
|
|
5187
|
-
* changes the signature and resets the ladder.
|
|
5188
|
-
*
|
|
5189
|
-
* Deliberately NOT stripped by `bumpStepActivation`: `onReject: <self>`
|
|
5190
|
-
* loop gates reset `gateAttempts`/`lastGateReject` on every pass, so
|
|
5191
|
-
* this trail is the only cross-activation plateau memory. Self-healing
|
|
5192
|
-
* — real progress changes the trailing signature.
|
|
4812
|
+
* Exact MCP tool names that must each have been called at least once
|
|
4813
|
+
* on this service (`kind: 'mcp'` only). Exact names, not regexes —
|
|
4814
|
+
* the tool roster is fully declared in the same file, so a pattern
|
|
4815
|
+
* buys nothing and invites drift. Cross-checked against the mock's
|
|
4816
|
+
* declared `tools[]` at parse time.
|
|
5193
4817
|
*/
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
})
|
|
4818
|
+
requiredTools: z20.array(z20.string().min(1)).optional(),
|
|
4819
|
+
/** Per-MCP-tool call budgets for repeated journeys or retries. */
|
|
4820
|
+
toolCalls: z20.record(
|
|
4821
|
+
z20.string().min(1),
|
|
4822
|
+
z20.object({
|
|
4823
|
+
minCalls: z20.number().int().nonnegative().default(1),
|
|
4824
|
+
maxCalls: z20.number().int().nonnegative().optional()
|
|
4825
|
+
}).strict().refine(
|
|
4826
|
+
(value) => value.maxCalls === void 0 || value.minCalls <= value.maxCalls,
|
|
4827
|
+
"minCalls must be less than or equal to maxCalls"
|
|
4828
|
+
)
|
|
5206
4829
|
).optional()
|
|
5207
|
-
});
|
|
5208
|
-
var
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
4830
|
+
}).strict();
|
|
4831
|
+
var CraftbookTestHistoryExpectationSchema = z20.object({
|
|
4832
|
+
kind: HistoryEventKindSchema,
|
|
4833
|
+
minEntries: z20.number().int().nonnegative().default(1),
|
|
4834
|
+
maxEntries: z20.number().int().nonnegative().optional(),
|
|
4835
|
+
summaryPattern: z20.string().min(1).optional(),
|
|
4836
|
+
flags: z20.string().optional(),
|
|
4837
|
+
details: z20.record(z20.string(), z20.union([z20.string(), z20.number(), z20.boolean(), z20.null()])).optional()
|
|
4838
|
+
}).strict();
|
|
4839
|
+
var CraftbookTestSuccessSchema = z20.object({
|
|
4840
|
+
summary: z20.string().min(1),
|
|
4841
|
+
deliverables: z20.array(CraftbookTestDeliverableSchema).optional(),
|
|
4842
|
+
checks: z20.array(CraftbookTestCheckSchema).optional(),
|
|
4843
|
+
taskNotes: z20.object({
|
|
4844
|
+
minBytes: z20.number().int().positive().optional(),
|
|
4845
|
+
checks: z20.array(CraftbookTestCheckSchema).optional(),
|
|
4846
|
+
requireCraftbookTask: z20.boolean().optional()
|
|
4847
|
+
}).strict().optional(),
|
|
4848
|
+
taskGraph: z20.object({
|
|
4849
|
+
checks: z20.array(CraftbookTestCheckSchema).optional(),
|
|
4850
|
+
requireCraftbookTask: z20.boolean().optional(),
|
|
4851
|
+
/** Require the matching task to reach a terminal step (or complete). */
|
|
4852
|
+
requireTerminalStep: z20.boolean().optional(),
|
|
4853
|
+
requireDraftRef: z20.boolean().optional(),
|
|
4854
|
+
draft: z20.object({
|
|
4855
|
+
status: z20.enum(["draft", "paused", "active", "complete", "canceled"]).optional(),
|
|
4856
|
+
minDescriptionBytes: z20.number().int().positive().optional(),
|
|
4857
|
+
minOutcomes: z20.number().int().positive().optional(),
|
|
4858
|
+
minSteps: z20.number().int().positive().optional(),
|
|
4859
|
+
requireTerminalVerification: z20.boolean().optional(),
|
|
4860
|
+
requireGatedBuildSteps: z20.boolean().optional()
|
|
4861
|
+
}).strict().optional()
|
|
4862
|
+
}).strict().optional(),
|
|
4863
|
+
/** Assertions evaluated against the live mock server's request log. */
|
|
4864
|
+
mocks: z20.array(CraftbookTestMockExpectationSchema).optional(),
|
|
4865
|
+
/** Assertions evaluated against the project's append-only History log. */
|
|
4866
|
+
history: z20.array(CraftbookTestHistoryExpectationSchema).optional(),
|
|
4867
|
+
/** Workspace fixtures whose final content must equal the seeded bytes exactly. */
|
|
4868
|
+
unchangedFixtures: z20.array(z20.string().min(1)).optional()
|
|
4869
|
+
}).strict();
|
|
4870
|
+
var CraftbookTestRubricSchema = z20.object({
|
|
4871
|
+
artifact: z20.object({
|
|
4872
|
+
/** Workspace or artifact path the judge reads (adapter derives the basename). */
|
|
4873
|
+
path: z20.string().min(1),
|
|
4874
|
+
kind: z20.enum(["html", "markdown", "yaml", "typescript", "json", "text"])
|
|
4875
|
+
}).strict(),
|
|
4876
|
+
axes: z20.array(z20.object({ name: z20.string().min(1), description: z20.string().min(1) }).strict()).min(1),
|
|
4877
|
+
contextNote: z20.string().optional()
|
|
4878
|
+
}).strict();
|
|
4879
|
+
var CraftbookTestSpecSchema = z20.object({
|
|
4880
|
+
schemaVersion: z20.literal(CRAFTBOOK_TEST_SCHEMA_VERSION),
|
|
4881
|
+
title: z20.string().min(1),
|
|
4882
|
+
objective: z20.string().min(1),
|
|
5230
4883
|
/**
|
|
5231
|
-
*
|
|
5232
|
-
*
|
|
5233
|
-
*
|
|
5234
|
-
* {@link CraftbookSpawnSchema}.
|
|
4884
|
+
* Task-class taxonomy tags (e.g. `html-game`, `corpus`, `external`).
|
|
4885
|
+
* The single declared source for harness selection and batch
|
|
4886
|
+
* planning — replaces the old regex classifiers.
|
|
5235
4887
|
*/
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
4888
|
+
tags: z20.array(z20.string().min(1)).default([]),
|
|
4889
|
+
/** Kickoff chat message the harness sends. Required — every book runs. */
|
|
4890
|
+
prompt: z20.string().min(1),
|
|
4891
|
+
setup: CraftbookTestSetupSchema,
|
|
4892
|
+
mocks: z20.array(MockServiceSchema).default([]),
|
|
4893
|
+
success: CraftbookTestSuccessSchema,
|
|
4894
|
+
rubric: CraftbookTestRubricSchema,
|
|
4895
|
+
qualityFocus: z20.array(z20.string().min(1)).default([]),
|
|
5239
4896
|
/**
|
|
5240
|
-
*
|
|
5241
|
-
*
|
|
5242
|
-
* rendered — do not re-collapse". One-way in v1: gates are carried
|
|
5243
|
-
* verbatim, so a later re-route to a bigger model just walks fewer
|
|
5244
|
-
* steps.
|
|
4897
|
+
* Sanctioned escape hatch for experiments — carried opaquely, never
|
|
4898
|
+
* interpreted by CI. Promote a field out of here before relying on it.
|
|
5245
4899
|
*/
|
|
5246
|
-
|
|
5247
|
-
})
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
4900
|
+
extensions: z20.record(z20.string(), z20.unknown()).optional()
|
|
4901
|
+
}).strict().superRefine((spec, ctx) => {
|
|
4902
|
+
const mockIds = new Set(spec.mocks.map((m) => m.id));
|
|
4903
|
+
const mockById = new Map(spec.mocks.map((m) => [m.id, m]));
|
|
4904
|
+
for (const [i, expectation] of (spec.success.mocks ?? []).entries()) {
|
|
4905
|
+
if (!mockIds.has(expectation.service)) {
|
|
4906
|
+
ctx.addIssue({
|
|
4907
|
+
code: z20.ZodIssueCode.custom,
|
|
4908
|
+
path: ["success", "mocks", i, "service"],
|
|
4909
|
+
message: `success.mocks[${i}] references unknown mock service "${expectation.service}"`
|
|
4910
|
+
});
|
|
4911
|
+
}
|
|
4912
|
+
if (expectation.requiredTools && expectation.requiredTools.length > 0) {
|
|
4913
|
+
const target = mockById.get(expectation.service);
|
|
4914
|
+
if (target && target.kind !== "mcp") {
|
|
4915
|
+
ctx.addIssue({
|
|
4916
|
+
code: z20.ZodIssueCode.custom,
|
|
4917
|
+
path: ["success", "mocks", i, "requiredTools"],
|
|
4918
|
+
message: `success.mocks[${i}].requiredTools requires an mcp service; "${expectation.service}" is kind "${target.kind}"`
|
|
4919
|
+
});
|
|
4920
|
+
} else if (target?.kind === "mcp") {
|
|
4921
|
+
const declared = new Set(target.tools.map((tool) => tool.name));
|
|
4922
|
+
for (const name of expectation.requiredTools) {
|
|
4923
|
+
if (!declared.has(name)) {
|
|
4924
|
+
ctx.addIssue({
|
|
4925
|
+
code: z20.ZodIssueCode.custom,
|
|
4926
|
+
path: ["success", "mocks", i, "requiredTools"],
|
|
4927
|
+
message: `success.mocks[${i}].requiredTools names undeclared tool "${name}" on mcp service "${expectation.service}"`
|
|
4928
|
+
});
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4933
|
+
if (expectation.toolCalls && Object.keys(expectation.toolCalls).length > 0) {
|
|
4934
|
+
const target = mockById.get(expectation.service);
|
|
4935
|
+
if (target && target.kind !== "mcp") {
|
|
4936
|
+
ctx.addIssue({
|
|
4937
|
+
code: z20.ZodIssueCode.custom,
|
|
4938
|
+
path: ["success", "mocks", i, "toolCalls"],
|
|
4939
|
+
message: `success.mocks[${i}].toolCalls requires an mcp service; "${expectation.service}" is kind "${target.kind}"`
|
|
4940
|
+
});
|
|
4941
|
+
} else if (target?.kind === "mcp") {
|
|
4942
|
+
const declared = new Set(target.tools.map((tool) => tool.name));
|
|
4943
|
+
for (const name of Object.keys(expectation.toolCalls)) {
|
|
4944
|
+
if (!declared.has(name)) {
|
|
4945
|
+
ctx.addIssue({
|
|
4946
|
+
code: z20.ZodIssueCode.custom,
|
|
4947
|
+
path: ["success", "mocks", i, "toolCalls", name],
|
|
4948
|
+
message: `success.mocks[${i}].toolCalls names undeclared tool "${name}" on mcp service "${expectation.service}"`
|
|
4949
|
+
});
|
|
4950
|
+
}
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
}
|
|
4954
|
+
}
|
|
4955
|
+
for (const [i, mock] of spec.mocks.entries()) {
|
|
4956
|
+
if (mock.kind === "http" && mock.credential.name !== `mock.${mock.id}`) {
|
|
4957
|
+
ctx.addIssue({
|
|
4958
|
+
code: z20.ZodIssueCode.custom,
|
|
4959
|
+
path: ["mocks", i, "credential", "name"],
|
|
4960
|
+
message: `http mock "${mock.id}" must use credential name "mock.${mock.id}"`
|
|
4961
|
+
});
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
const workspaceFixtures = new Set(
|
|
4965
|
+
spec.setup.files.filter((file) => file.surface === void 0 || file.surface === "workspace").map((file) => file.path)
|
|
4966
|
+
);
|
|
4967
|
+
for (const [i, path] of (spec.success.unchangedFixtures ?? []).entries()) {
|
|
4968
|
+
if (!workspaceFixtures.has(path)) {
|
|
4969
|
+
ctx.addIssue({
|
|
4970
|
+
code: z20.ZodIssueCode.custom,
|
|
4971
|
+
path: ["success", "unchangedFixtures", i],
|
|
4972
|
+
message: `unchanged fixture "${path}" is not a seeded workspace file`
|
|
4973
|
+
});
|
|
4974
|
+
}
|
|
4975
|
+
}
|
|
4976
|
+
for (const [i, expectation] of (spec.success.history ?? []).entries()) {
|
|
4977
|
+
if (expectation.maxEntries !== void 0 && expectation.minEntries > expectation.maxEntries) {
|
|
4978
|
+
ctx.addIssue({
|
|
4979
|
+
code: z20.ZodIssueCode.custom,
|
|
4980
|
+
path: ["success", "history", i],
|
|
4981
|
+
message: "minEntries must be less than or equal to maxEntries"
|
|
4982
|
+
});
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
5254
4985
|
});
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
4986
|
+
function parseCraftbookTestSpec(raw, opts) {
|
|
4987
|
+
const mode = opts?.mode ?? "strict";
|
|
4988
|
+
const candidate = mode === "tolerant" ? deepStripUnknown(raw) : raw;
|
|
4989
|
+
const parsed = CraftbookTestSpecSchema.safeParse(candidate);
|
|
4990
|
+
if (parsed.success) return { ok: true, spec: parsed.data };
|
|
4991
|
+
return {
|
|
4992
|
+
ok: false,
|
|
4993
|
+
errors: parsed.error.issues.map((issue) => {
|
|
4994
|
+
const path = issue.path.length > 0 ? issue.path.map(String).join(".") : "<root>";
|
|
4995
|
+
return `${path}: ${issue.message}`;
|
|
4996
|
+
})
|
|
4997
|
+
};
|
|
4998
|
+
}
|
|
4999
|
+
function deepStripUnknown(raw) {
|
|
5000
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return raw;
|
|
5001
|
+
const record = structuredClone(raw);
|
|
5002
|
+
const version = record.schemaVersion;
|
|
5003
|
+
if (typeof version === "number" && Number.isInteger(version) && version > CRAFTBOOK_TEST_SCHEMA_VERSION) {
|
|
5004
|
+
record.schemaVersion = CRAFTBOOK_TEST_SCHEMA_VERSION;
|
|
5005
|
+
}
|
|
5006
|
+
for (let pass = 0; pass < 16; pass++) {
|
|
5007
|
+
const attempt = CraftbookTestSpecSchema.safeParse(record);
|
|
5008
|
+
if (attempt.success) return record;
|
|
5009
|
+
const unknownKeyIssues = attempt.error.issues.filter(
|
|
5010
|
+
(issue) => issue.code === z20.ZodIssueCode.unrecognized_keys
|
|
5011
|
+
);
|
|
5012
|
+
if (unknownKeyIssues.length === 0) return record;
|
|
5013
|
+
for (const issue of unknownKeyIssues) {
|
|
5014
|
+
const target = resolvePath(record, issue.path);
|
|
5015
|
+
if (target && typeof target === "object" && !Array.isArray(target)) {
|
|
5016
|
+
for (const key of issue.keys) delete target[key];
|
|
5017
|
+
}
|
|
5018
|
+
}
|
|
5019
|
+
}
|
|
5020
|
+
return record;
|
|
5021
|
+
}
|
|
5022
|
+
function resolvePath(root, path) {
|
|
5023
|
+
let node = root;
|
|
5024
|
+
for (const segment of path) {
|
|
5025
|
+
if (node === null || typeof node !== "object") return void 0;
|
|
5026
|
+
node = node[segment];
|
|
5027
|
+
}
|
|
5028
|
+
return node;
|
|
5029
|
+
}
|
|
5030
|
+
|
|
5031
|
+
// src/schemas/codex-setup.ts
|
|
5032
|
+
import { z as z21 } from "zod";
|
|
5033
|
+
var CodexSetupModelOptionSchema = z21.object({
|
|
5034
|
+
id: z21.string().min(1),
|
|
5035
|
+
label: z21.string().min(1),
|
|
5036
|
+
description: z21.string().optional(),
|
|
5037
|
+
kind: z21.enum(["gezel", "model"]).default("model"),
|
|
5038
|
+
provider: z21.string().min(1),
|
|
5039
|
+
/** Stable gezel id for persona-backed entries. Absent on raw-model entries. */
|
|
5040
|
+
gezelId: z21.string().min(1).optional(),
|
|
5041
|
+
role: z21.string().min(1).optional(),
|
|
5042
|
+
/** Human-readable name of the effective inference model behind a gezel. */
|
|
5043
|
+
modelLabel: z21.string().min(1).optional(),
|
|
5044
|
+
contextWindow: z21.number().int().positive().optional(),
|
|
5045
|
+
supportsReasoning: z21.boolean().optional(),
|
|
5046
|
+
supportsTools: z21.boolean().optional()
|
|
5261
5047
|
});
|
|
5262
|
-
var
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5048
|
+
var CodexSetupStateSchema = z21.enum([
|
|
5049
|
+
"not-configured",
|
|
5050
|
+
"configured",
|
|
5051
|
+
"update-needed",
|
|
5052
|
+
"conflict",
|
|
5053
|
+
"unavailable"
|
|
5054
|
+
]);
|
|
5055
|
+
var CodexSetupStatusResponseSchema = z21.object({
|
|
5056
|
+
state: CodexSetupStateSchema,
|
|
5057
|
+
models: z21.array(CodexSetupModelOptionSchema),
|
|
5058
|
+
configuredModel: z21.string().optional(),
|
|
5059
|
+
recommendedModel: z21.string().optional(),
|
|
5060
|
+
reasons: z21.array(z21.string()),
|
|
5061
|
+
message: z21.string().optional(),
|
|
5062
|
+
codexInstalled: z21.boolean(),
|
|
5063
|
+
codexVersion: z21.string().optional(),
|
|
5064
|
+
codexPath: z21.string().optional(),
|
|
5065
|
+
endpointsEnabled: z21.boolean(),
|
|
5066
|
+
profileName: z21.string().min(1),
|
|
5067
|
+
profilePath: z21.string().min(1),
|
|
5068
|
+
launchCommand: z21.string().min(1),
|
|
5069
|
+
bridge: z21.object({
|
|
5070
|
+
baseUrl: z21.string().url(),
|
|
5071
|
+
listening: z21.boolean(),
|
|
5072
|
+
port: z21.number().int().nonnegative()
|
|
5073
|
+
}),
|
|
5074
|
+
canConfigure: z21.boolean(),
|
|
5075
|
+
/** Whether Gezel-owned credential/state material exists and can be safely removed. */
|
|
5076
|
+
canRemove: z21.boolean()
|
|
5077
|
+
});
|
|
5078
|
+
var ConfigureCodexRequestSchema = z21.object({
|
|
5079
|
+
model: z21.string().min(1)
|
|
5080
|
+
});
|
|
5081
|
+
|
|
5082
|
+
// src/schemas/project-local.ts
|
|
5083
|
+
import { z as z22 } from "zod";
|
|
5084
|
+
var InstructionSourceFileSchema = z22.enum([
|
|
5085
|
+
"AGENTS.md",
|
|
5086
|
+
"CLAUDE.md",
|
|
5087
|
+
".github/copilot-instructions.md"
|
|
5088
|
+
]);
|
|
5089
|
+
var InstructionMergeModeSchema = z22.enum(["primary", "concat"]);
|
|
5090
|
+
var ProjectLocalConfigSchema = z22.object({
|
|
5091
|
+
schemaVersion: z22.literal(1).default(1),
|
|
5092
|
+
sourceFile: InstructionSourceFileSchema.optional(),
|
|
5093
|
+
mergeMode: InstructionMergeModeSchema.optional(),
|
|
5094
|
+
aboutHash: z22.string().optional(),
|
|
5095
|
+
derivedAt: z22.string().optional()
|
|
5096
|
+
});
|
|
5097
|
+
var ImportedGezelProvenanceSchema = z22.object({
|
|
5098
|
+
/** sha256 of the instruction file contents the gezel was last derived from. */
|
|
5099
|
+
hash: z22.string(),
|
|
5100
|
+
/** Which instruction file won precedence. */
|
|
5101
|
+
sourceFile: InstructionSourceFileSchema,
|
|
5102
|
+
mergeMode: InstructionMergeModeSchema.optional(),
|
|
5103
|
+
/** Encoded gezel id (`proj__<projectId>__project`). */
|
|
5104
|
+
gezelId: z22.string(),
|
|
5307
5105
|
/**
|
|
5308
|
-
*
|
|
5309
|
-
*
|
|
5310
|
-
*
|
|
5311
|
-
* second host. Deliberately absent from `CreateTaskRequestSchema`:
|
|
5312
|
-
* models and HTTP callers can't stamp it; only the service does, via
|
|
5313
|
-
* `TaskManager.create` extras.
|
|
5106
|
+
* Set true once the user edits the gezel's identity in the UI. The sync
|
|
5107
|
+
* engine then stops touching identity (the `about` is always file-driven
|
|
5108
|
+
* regardless).
|
|
5314
5109
|
*/
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5110
|
+
userEdited: z22.boolean().optional()
|
|
5111
|
+
});
|
|
5112
|
+
var ImportedAboutProvenanceSchema = z22.object({
|
|
5113
|
+
/** sha256 of the instruction content last merged into `about.md`. */
|
|
5114
|
+
hash: z22.string(),
|
|
5115
|
+
/** Which instruction file the merged content came from. */
|
|
5116
|
+
sourceFile: z22.string()
|
|
5117
|
+
});
|
|
5118
|
+
var ImportedCraftbookProvenanceSchema = z22.object({
|
|
5119
|
+
/** sha256 of the SKILL.md body the craftbook was last derived from. */
|
|
5120
|
+
hash: z22.string(),
|
|
5121
|
+
/** Project-local craftbook id this skill produced. */
|
|
5122
|
+
craftbookId: z22.string(),
|
|
5123
|
+
/** Generated JS script names attached to the craftbook (if any). */
|
|
5124
|
+
scriptNames: z22.array(z22.string()).default([]),
|
|
5125
|
+
/** True once the user edits the imported craftbook; sync stops clobbering it. */
|
|
5126
|
+
userEdited: z22.boolean().optional()
|
|
5127
|
+
});
|
|
5128
|
+
var ImportProvenanceSchema = z22.object({
|
|
5129
|
+
version: z22.literal(1).default(1),
|
|
5130
|
+
gezel: ImportedGezelProvenanceSchema.optional(),
|
|
5131
|
+
about: ImportedAboutProvenanceSchema.optional(),
|
|
5132
|
+
craftbooks: z22.record(z22.string(), ImportedCraftbookProvenanceSchema).default({})
|
|
5133
|
+
});
|
|
5134
|
+
var PendingScriptSchema = z22.object({
|
|
5135
|
+
/** Script file name (without `.ts`). */
|
|
5136
|
+
name: z22.string(),
|
|
5137
|
+
/** Translated gezel-sdk TypeScript body. */
|
|
5138
|
+
body: z22.string(),
|
|
5139
|
+
/** Translator self-reported confidence, 0–1. Static conversions are 1. */
|
|
5140
|
+
confidence: z22.number().min(0).max(1),
|
|
5141
|
+
/** The original shell snippet, for the reviewer to compare against. */
|
|
5142
|
+
sourceBlock: z22.string(),
|
|
5143
|
+
/** Who produced the translation. Absent on legacy items = 'llm'. */
|
|
5144
|
+
origin: z22.enum(["static", "llm"]).optional()
|
|
5145
|
+
});
|
|
5146
|
+
var PendingPersonaSchema = z22.object({
|
|
5147
|
+
role: z22.string(),
|
|
5148
|
+
/** Generator-shaped about.md body (Identity section from the skill's intro). */
|
|
5149
|
+
about: z22.string()
|
|
5150
|
+
});
|
|
5151
|
+
var PendingImportItemSchema = z22.object({
|
|
5152
|
+
/** Workspace-relative SKILL.md path this proposal came from. */
|
|
5153
|
+
skillSource: z22.string(),
|
|
5154
|
+
/** sha256 of the raw skill body + companion-file list — lets sync skip an unchanged, still-pending skill. */
|
|
5155
|
+
sourceHash: z22.string(),
|
|
5156
|
+
/** Draft craftbook to write on approval. */
|
|
5157
|
+
craftbook: CraftbookSchema,
|
|
5158
|
+
/** Generated scripts to write on approval (empty when prose-only). */
|
|
5159
|
+
scripts: z22.array(PendingScriptSchema).default([]),
|
|
5160
|
+
/** Persona to mint on approval (persona-shaped skills only). */
|
|
5161
|
+
persona: PendingPersonaSchema.optional(),
|
|
5162
|
+
/** Converter honesty ledger — features of the source skill not carried over. */
|
|
5163
|
+
notes: z22.array(z22.string()).optional(),
|
|
5164
|
+
createdAt: z22.string()
|
|
5165
|
+
});
|
|
5166
|
+
var PendingImportsSchema = z22.object({
|
|
5167
|
+
version: z22.literal(1).default(1),
|
|
5168
|
+
items: z22.array(PendingImportItemSchema).default([])
|
|
5169
|
+
});
|
|
5170
|
+
|
|
5171
|
+
// src/schemas/task.ts
|
|
5172
|
+
import { z as z23 } from "zod";
|
|
5173
|
+
var TaskStatusSchema = z23.enum(["draft", "paused", "active", "complete", "canceled"]);
|
|
5174
|
+
var TaskCronOverlapSchema = z23.enum(["skip", "queue", "concurrent"]);
|
|
5175
|
+
var TaskCronSchema = z23.object({
|
|
5176
|
+
expression: z23.string(),
|
|
5177
|
+
lastTickAt: z23.string().optional(),
|
|
5178
|
+
nextTickAt: z23.string().optional(),
|
|
5179
|
+
overlap: TaskCronOverlapSchema.optional()
|
|
5180
|
+
});
|
|
5181
|
+
var TaskVariationSchema = z23.object({
|
|
5182
|
+
title: z23.string().optional(),
|
|
5183
|
+
plan: z23.string().optional(),
|
|
5184
|
+
description: z23.string().optional(),
|
|
5185
|
+
context: z23.record(z23.string(), z23.string()).optional()
|
|
5186
|
+
});
|
|
5187
|
+
var TaskFanoutSchema = z23.object({
|
|
5188
|
+
count: z23.number().int().positive(),
|
|
5189
|
+
variations: z23.array(TaskVariationSchema).optional(),
|
|
5190
|
+
materializedAt: z23.string().optional()
|
|
5191
|
+
});
|
|
5192
|
+
var NewTaskFanoutSchema = z23.object({
|
|
5193
|
+
count: z23.number().int().positive(),
|
|
5194
|
+
variations: z23.array(TaskVariationSchema).optional()
|
|
5195
|
+
});
|
|
5196
|
+
var TaskNightShiftSchema = z23.object({
|
|
5197
|
+
enabled: z23.boolean(),
|
|
5198
|
+
onceADay: z23.boolean().optional(),
|
|
5199
|
+
lastRunDay: z23.string().optional()
|
|
5200
|
+
});
|
|
5201
|
+
var TaskCraftbookStepSchema = CraftbookStepSchema.extend({
|
|
5202
|
+
createdAt: z23.string(),
|
|
5203
|
+
completedAt: z23.string().optional(),
|
|
5204
|
+
attemptCount: z23.number().int().nonnegative().optional(),
|
|
5205
|
+
lastActivatedAt: z23.string().optional(),
|
|
5356
5206
|
/**
|
|
5357
|
-
*
|
|
5358
|
-
*
|
|
5359
|
-
*
|
|
5207
|
+
* Completion-gate rejections since this step last activated. Distinct
|
|
5208
|
+
* from `attemptCount` (which counts ACTIVATIONS — loop-backs): a
|
|
5209
|
+
* rejection holds the step active without re-activating it. Reset by
|
|
5210
|
+
* `bumpStepActivation` so a loop-back grants a fresh budget.
|
|
5360
5211
|
*/
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5212
|
+
gateAttempts: z23.number().int().nonnegative().optional(),
|
|
5213
|
+
/**
|
|
5214
|
+
* Repeat-reject damper. When the gated deliverable is byte-identical
|
|
5215
|
+
* to what the gate last rejected, the runtime returns this cached
|
|
5216
|
+
* rejection instead of re-running gate scripts, and the chat nudge
|
|
5217
|
+
* dedupes on `messageFingerprint`.
|
|
5218
|
+
*/
|
|
5219
|
+
lastGateReject: z23.object({
|
|
5220
|
+
contentHash: z23.string().optional(),
|
|
5221
|
+
messageFingerprint: z23.string(),
|
|
5364
5222
|
message: z23.string(),
|
|
5365
|
-
params: z23.record(z23.string(), z23.unknown()).optional(),
|
|
5366
5223
|
at: z23.string()
|
|
5367
5224
|
}).optional(),
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5225
|
+
/**
|
|
5226
|
+
* Anti-stall re-drive bookkeeping for the idle step supervisor
|
|
5227
|
+
* (`TaskScheduler.sweepStuckSteps`). `redriveCount` = how many times the
|
|
5228
|
+
* supervisor has re-poked THIS active step after it went idle without
|
|
5229
|
+
* advancing; `lastRedriveAt` = when it last did (also the cooldown
|
|
5230
|
+
* anchor so a re-drive isn't itself read as fresh progress). Distinct
|
|
5231
|
+
* from `attemptCount` (activations) and `gateAttempts` (gate
|
|
5232
|
+
* rejections), which count model-driven events — these count autonomous
|
|
5233
|
+
* re-pokes of a silent assignee. Reset by `bumpStepActivation` so a
|
|
5234
|
+
* fresh activation / loop-back grants a fresh re-drive budget.
|
|
5235
|
+
*/
|
|
5236
|
+
redriveCount: z23.number().int().nonnegative().optional(),
|
|
5237
|
+
lastRedriveAt: z23.string().optional(),
|
|
5238
|
+
/**
|
|
5239
|
+
* Rolling reject trail (capped at 8 entries, oldest dropped). One entry
|
|
5240
|
+
* per real completion-gate rejection PLUS one per damped byte-identical
|
|
5241
|
+
* resubmit (`frozen: true`). `signatureHash` hashes the failing-check
|
|
5242
|
+
* IDENTITY set (GateCheckOutcome labels), not prose or bytes — byte
|
|
5243
|
+
* churn with an unmoved failure set IS a plateau; a cleared check
|
|
5244
|
+
* changes the signature and resets the ladder.
|
|
5245
|
+
*
|
|
5246
|
+
* Deliberately NOT stripped by `bumpStepActivation`: `onReject: <self>`
|
|
5247
|
+
* loop gates reset `gateAttempts`/`lastGateReject` on every pass, so
|
|
5248
|
+
* this trail is the only cross-activation plateau memory. Self-healing
|
|
5249
|
+
* — real progress changes the trailing signature.
|
|
5250
|
+
*/
|
|
5251
|
+
gateAttemptHistory: z23.array(
|
|
5252
|
+
z23.object({
|
|
5253
|
+
at: z23.string(),
|
|
5254
|
+
attempt: z23.number().int().nonnegative(),
|
|
5255
|
+
contentHash: z23.string().optional(),
|
|
5256
|
+
signatureHash: z23.string(),
|
|
5257
|
+
messageFingerprint: z23.string(),
|
|
5258
|
+
/** Failing GateCheckOutcome labels (or `script:<name>`). */
|
|
5259
|
+
failedChecks: z23.array(z23.string()).optional(),
|
|
5260
|
+
/** True when this entry records a damped byte-identical resubmit. */
|
|
5261
|
+
frozen: z23.boolean().optional()
|
|
5262
|
+
})
|
|
5263
|
+
).optional()
|
|
5371
5264
|
});
|
|
5372
|
-
var
|
|
5373
|
-
|
|
5374
|
-
|
|
5265
|
+
var TaskCraftbookSchema = z23.object({
|
|
5266
|
+
id: z23.string().min(1),
|
|
5267
|
+
name: z23.string().min(1),
|
|
5268
|
+
description: z23.string().optional(),
|
|
5269
|
+
version: z23.string().optional(),
|
|
5270
|
+
basedOn: CraftbookBasedOnSchema.optional(),
|
|
5375
5271
|
plan: z23.string().optional(),
|
|
5376
|
-
|
|
5272
|
+
defaultAssignee: TaskAssigneeSchema.optional(),
|
|
5273
|
+
steps: z23.array(TaskCraftbookStepSchema).min(1),
|
|
5274
|
+
entryStepId: z23.string().min(1),
|
|
5275
|
+
triggers: z23.array(z23.string()).optional(),
|
|
5276
|
+
hooks: z23.array(HookSpecSchema).optional(),
|
|
5277
|
+
/** Invocation schema retained with the task snapshot for audit/UI context. */
|
|
5278
|
+
paramSchema: z23.record(z23.string(), z23.unknown()).optional(),
|
|
5279
|
+
toolsets: z23.array(CraftbookToolsetNeedSchema).optional(),
|
|
5280
|
+
connectors: z23.array(CraftbookConnectorNeedSchema).optional(),
|
|
5377
5281
|
/**
|
|
5378
|
-
*
|
|
5379
|
-
*
|
|
5380
|
-
*
|
|
5381
|
-
* resolution overrides at step level anyway. Falls back to the user
|
|
5382
|
-
* when nothing resolves. See `TaskSchema.assigneeAuto`.
|
|
5282
|
+
* Embedded script sources snapshotted from the source craftbook, so the
|
|
5283
|
+
* task's gate/lifecycle scripts execute from its own copy — `scope:
|
|
5284
|
+
* 'craftbook'` refs resolve here first, project-installed copy second.
|
|
5383
5285
|
*/
|
|
5384
|
-
|
|
5286
|
+
scripts: CraftbookScriptsSchema.optional(),
|
|
5385
5287
|
/**
|
|
5386
|
-
*
|
|
5387
|
-
*
|
|
5388
|
-
*
|
|
5288
|
+
* Declarative per-item fanout config, snapshotted from the source
|
|
5289
|
+
* craftbook so the runtime reads it at fanout time (the `spawnFanout`
|
|
5290
|
+
* step's activation reads `spawn.overFile` from the workspace). See
|
|
5291
|
+
* {@link CraftbookSpawnSchema}.
|
|
5389
5292
|
*/
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
/** Catalog source id, when distinguishing local from bundled etc. */
|
|
5394
|
-
craftbookSourceId: z23.string().optional(),
|
|
5395
|
-
/** Specific catalog version of the main craftbook. */
|
|
5396
|
-
craftbookVersion: z23.string().optional(),
|
|
5397
|
-
/** Inline blueprint for the main craftbook (mutually exclusive with craftbookId). */
|
|
5398
|
-
steps: z23.array(NewCraftbookStepSchema).optional(),
|
|
5399
|
-
/** Optional entry step id when supplying inline steps; defaults to first step. */
|
|
5400
|
-
entryStepId: z23.string().optional(),
|
|
5401
|
-
/** Invocation-time param values for the main craftbook (launcher). */
|
|
5402
|
-
craftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5403
|
-
/** Invocation-time param values copied to each spawned child. */
|
|
5404
|
-
spawnsCraftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5405
|
-
/** Spawn-side (for schedule hosts and fanouts): catalog reference. */
|
|
5406
|
-
spawnsCraftbookId: z23.string().optional(),
|
|
5407
|
-
spawnsCraftbookSourceId: z23.string().optional(),
|
|
5408
|
-
spawnsCraftbookVersion: z23.string().optional(),
|
|
5409
|
-
spawnsSteps: z23.array(NewCraftbookStepSchema).optional(),
|
|
5410
|
-
spawnsEntryStepId: z23.string().optional(),
|
|
5411
|
-
parentTaskRef: z23.string().optional(),
|
|
5412
|
-
cron: z23.object({
|
|
5413
|
-
expression: z23.string(),
|
|
5414
|
-
overlap: TaskCronOverlapSchema.optional()
|
|
5415
|
-
}).optional(),
|
|
5416
|
-
nightShift: z23.object({
|
|
5417
|
-
enabled: z23.boolean(),
|
|
5418
|
-
onceADay: z23.boolean().optional()
|
|
5419
|
-
}).optional(),
|
|
5420
|
-
fanout: NewTaskFanoutSchema.optional(),
|
|
5421
|
-
createdBy: TaskAssigneeSchema.optional(),
|
|
5293
|
+
spawn: CraftbookSpawnSchema.optional(),
|
|
5294
|
+
createdAt: z23.string(),
|
|
5295
|
+
updatedAt: z23.string(),
|
|
5422
5296
|
/**
|
|
5423
|
-
*
|
|
5424
|
-
*
|
|
5425
|
-
*
|
|
5426
|
-
*
|
|
5427
|
-
*
|
|
5428
|
-
* on cron/fanout hosts (their children dispatch via their own
|
|
5429
|
-
* activation hooks — flag-dispatching the host would double-engage).
|
|
5297
|
+
* Tier the embedded book was collapse-rendered for (D3). Stamped by
|
|
5298
|
+
* the tier-collapse pass at handoff dispatch; presence means "already
|
|
5299
|
+
* rendered — do not re-collapse". One-way in v1: gates are carried
|
|
5300
|
+
* verbatim, so a later re-route to a bigger model just walks fewer
|
|
5301
|
+
* steps.
|
|
5430
5302
|
*/
|
|
5431
|
-
|
|
5432
|
-
})
|
|
5433
|
-
|
|
5303
|
+
renderedForTier: ModelTierSchema.optional()
|
|
5304
|
+
});
|
|
5305
|
+
var TaskCraftbookSourceSchema = z23.object({
|
|
5306
|
+
role: z23.enum(["main", "spawn"]),
|
|
5307
|
+
catalogId: z23.string(),
|
|
5308
|
+
version: z23.string().optional(),
|
|
5309
|
+
/** Source identifier from the catalog (e.g. "bundled", "local"). */
|
|
5310
|
+
sourceId: z23.string().optional()
|
|
5311
|
+
});
|
|
5312
|
+
var OutcomeSchema = z23.object({
|
|
5313
|
+
id: z23.string(),
|
|
5314
|
+
text: z23.string().min(1),
|
|
5315
|
+
met: z23.boolean().optional(),
|
|
5316
|
+
evidence: z23.string().optional(),
|
|
5317
|
+
verifiedAt: z23.string().optional()
|
|
5318
|
+
});
|
|
5319
|
+
var TaskSchema = z23.object({
|
|
5320
|
+
projectId: z23.string(),
|
|
5321
|
+
num: z23.number().int().positive(),
|
|
5322
|
+
ref: z23.string(),
|
|
5323
|
+
title: z23.string(),
|
|
5324
|
+
description: z23.string().optional(),
|
|
5325
|
+
plan: z23.string().optional(),
|
|
5326
|
+
/**
|
|
5327
|
+
* Expected outcomes — prose of what should be created/updated at
|
|
5328
|
+
* successful completion, each individually verifiable. Authored during
|
|
5329
|
+
* planning; checked by the terminal verification step. See `OutcomeSchema`.
|
|
5330
|
+
*/
|
|
5331
|
+
outcomes: z23.array(OutcomeSchema).optional(),
|
|
5332
|
+
status: TaskStatusSchema,
|
|
5333
|
+
assignee: TaskAssigneeSchema,
|
|
5334
|
+
/**
|
|
5335
|
+
* The assignee was derived, not chosen — it mirrors whoever the ENTRY
|
|
5336
|
+
* step's `suggestedRole` resolved to. Set when a task is created
|
|
5337
|
+
* without a named assignee; cleared the moment anyone pins one.
|
|
5338
|
+
*
|
|
5339
|
+
* A draft carries the flag with an interim `{kind:'user'}` assignee:
|
|
5340
|
+
* drafts resolve no roles (that would create gezels for a task that
|
|
5341
|
+
* may never run), so `activate()` is the first moment a concrete
|
|
5342
|
+
* specialist exists to point at.
|
|
5343
|
+
*/
|
|
5344
|
+
assigneeAuto: z23.boolean().optional(),
|
|
5345
|
+
craftbook: TaskCraftbookSchema,
|
|
5346
|
+
spawnsCraftbook: TaskCraftbookSchema.optional(),
|
|
5347
|
+
sourceCraftbookIds: z23.array(TaskCraftbookSourceSchema).optional(),
|
|
5348
|
+
/**
|
|
5349
|
+
* Invocation-time parameter values supplied when this task was
|
|
5350
|
+
* launched from a parameterized craftbook (the command launcher).
|
|
5351
|
+
* Stringified for the CLI round-trip; the declared types live on the
|
|
5352
|
+
* craftbook's `paramSchema`. Surfaced directly in every task-scoped
|
|
5353
|
+
* prompt so later specialists retain the authoritative inputs even when
|
|
5354
|
+
* an invocation path did not also stamp an entry-step note.
|
|
5355
|
+
*/
|
|
5356
|
+
craftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5357
|
+
/**
|
|
5358
|
+
* Invocation parameters for a schedule/fanout host's child template.
|
|
5359
|
+
* Copied to each spawned child's `craftbookParams`.
|
|
5360
|
+
*/
|
|
5361
|
+
spawnsCraftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5362
|
+
activeStepId: z23.string().optional(),
|
|
5363
|
+
parentTaskRef: z23.string().optional(),
|
|
5364
|
+
/**
|
|
5365
|
+
* Provenance for service-materialized tasks (today: project-type
|
|
5366
|
+
* schedule hosts). The dedup key that makes re-applying a type
|
|
5367
|
+
* idempotent — apply scans for a matching origin instead of creating a
|
|
5368
|
+
* second host. Deliberately absent from `CreateTaskRequestSchema`:
|
|
5369
|
+
* models and HTTP callers can't stamp it; only the service does, via
|
|
5370
|
+
* `TaskManager.create` extras.
|
|
5371
|
+
*/
|
|
5372
|
+
origin: z23.discriminatedUnion("kind", [
|
|
5373
|
+
z23.object({
|
|
5374
|
+
kind: z23.literal("project-type-schedule"),
|
|
5375
|
+
typeId: z23.string(),
|
|
5376
|
+
/** Schedule identity within the type — craftbook id, `#N`-suffixed on repeats. */
|
|
5377
|
+
scheduleKey: z23.string()
|
|
5378
|
+
}),
|
|
5379
|
+
z23.object({
|
|
5380
|
+
/**
|
|
5381
|
+
* A durable control surface for work executed by the service
|
|
5382
|
+
* itself. `managedByGezelId` is presentation/provenance only:
|
|
5383
|
+
* the user assignee remains in place so TaskRunner never opens
|
|
5384
|
+
* a duplicate model session for the system loop.
|
|
5385
|
+
*/
|
|
5386
|
+
kind: z23.literal("system-job"),
|
|
5387
|
+
jobId: z23.string(),
|
|
5388
|
+
managedByGezelId: z23.string().optional()
|
|
5389
|
+
}),
|
|
5390
|
+
z23.object({
|
|
5391
|
+
/** A fix task linked back to one durable project-local BW issue. */
|
|
5392
|
+
kind: z23.literal("boekwachter-issue"),
|
|
5393
|
+
issueRef: z23.string().regex(/^BW-[1-9]\d*$/),
|
|
5394
|
+
path: z23.string().min(1)
|
|
5395
|
+
}),
|
|
5396
|
+
z23.object({
|
|
5397
|
+
/**
|
|
5398
|
+
* An invoke_craftbook call keyed to one persisted root chat turn.
|
|
5399
|
+
* The HTTP task boundary uses this opaque digest to return the first
|
|
5400
|
+
* still-active task when a provider continuation repeats the call.
|
|
5401
|
+
*/
|
|
5402
|
+
kind: z23.literal("craftbook-invocation"),
|
|
5403
|
+
key: z23.string().regex(/^craftbook-root-v1:[a-f0-9]{64}$/)
|
|
5404
|
+
}),
|
|
5405
|
+
z23.object({
|
|
5406
|
+
/**
|
|
5407
|
+
* A host materialized from a gezel template's `suggestedCraftbooks`
|
|
5408
|
+
* entry via the suggested-work layer. `suggestionKey` is the
|
|
5409
|
+
* entry's key within the template (`<craftbookId>` or
|
|
5410
|
+
* `<craftbookId>#N` on repeats) — together with `templateId` it is
|
|
5411
|
+
* the toggle identity: enable resurrects a matching paused host
|
|
5412
|
+
* instead of creating a second one.
|
|
5413
|
+
*/
|
|
5414
|
+
kind: z23.literal("gezel-suggested-craftbook"),
|
|
5415
|
+
templateId: z23.string(),
|
|
5416
|
+
suggestionKey: z23.string()
|
|
5417
|
+
})
|
|
5418
|
+
]).optional(),
|
|
5419
|
+
cron: TaskCronSchema.optional(),
|
|
5420
|
+
nightShift: TaskNightShiftSchema.optional(),
|
|
5421
|
+
fanout: TaskFanoutSchema.optional(),
|
|
5422
|
+
/**
|
|
5423
|
+
* Handoff payload stamped by the most recent approving gate script.
|
|
5424
|
+
* Injected verbatim into the next step's handoff seed prompt (and
|
|
5425
|
+
* readable by scripts via `tasks.read`); replaced on each approval.
|
|
5426
|
+
*/
|
|
5427
|
+
lastGateHandoff: z23.object({
|
|
5428
|
+
fromStepId: z23.string(),
|
|
5429
|
+
toStepId: z23.string().optional(),
|
|
5430
|
+
message: z23.string(),
|
|
5431
|
+
params: z23.record(z23.string(), z23.unknown()).optional(),
|
|
5432
|
+
at: z23.string()
|
|
5433
|
+
}).optional(),
|
|
5434
|
+
/**
|
|
5435
|
+
* Naming presentation inherited from the session that launched this
|
|
5436
|
+
* workflow. Task handoffs create fresh sessions (and may be rehydrated
|
|
5437
|
+
* after restart), so they cannot rely on the launcher's session record
|
|
5438
|
+
* still being available when the next step starts.
|
|
5439
|
+
*/
|
|
5440
|
+
roleBasedNameOnlyMode: z23.boolean().optional(),
|
|
5441
|
+
createdAt: z23.string(),
|
|
5442
|
+
updatedAt: z23.string(),
|
|
5443
|
+
createdBy: TaskAssigneeSchema
|
|
5444
|
+
});
|
|
5445
|
+
var CreateTaskRequestSchema = z23.object({
|
|
5446
|
+
title: z23.string().min(1),
|
|
5447
|
+
description: z23.string().min(40),
|
|
5448
|
+
plan: z23.string().optional(),
|
|
5449
|
+
outcomes: z23.array(OutcomeSchema).optional(),
|
|
5450
|
+
/**
|
|
5451
|
+
* Who owns the task. Omit it on a craftbook whose entry step names a
|
|
5452
|
+
* `suggestedRole` and the resolved specialist becomes the assignee —
|
|
5453
|
+
* naming one here would only be an arbitrary pick that the role
|
|
5454
|
+
* resolution overrides at step level anyway. Falls back to the user
|
|
5455
|
+
* when nothing resolves. See `TaskSchema.assigneeAuto`.
|
|
5456
|
+
*/
|
|
5457
|
+
assignee: TaskAssigneeSchema.optional(),
|
|
5458
|
+
/**
|
|
5459
|
+
* Initial status. Defaults to 'active'. Pass 'draft' to create an
|
|
5460
|
+
* inert task (e.g. a plan being authored) that won't tick or dispatch
|
|
5461
|
+
* until `activate`d. Drafts may not be schedule hosts.
|
|
5462
|
+
*/
|
|
5463
|
+
status: z23.enum(["draft", "active"]).optional(),
|
|
5464
|
+
/** Resolve the main craftbook from the catalog by id. */
|
|
5465
|
+
craftbookId: z23.string().optional(),
|
|
5466
|
+
/** Catalog source id, when distinguishing local from bundled etc. */
|
|
5467
|
+
craftbookSourceId: z23.string().optional(),
|
|
5468
|
+
/** Specific catalog version of the main craftbook. */
|
|
5469
|
+
craftbookVersion: z23.string().optional(),
|
|
5470
|
+
/** Inline blueprint for the main craftbook (mutually exclusive with craftbookId). */
|
|
5471
|
+
steps: z23.array(NewCraftbookStepSchema).optional(),
|
|
5472
|
+
/** Optional entry step id when supplying inline steps; defaults to first step. */
|
|
5473
|
+
entryStepId: z23.string().optional(),
|
|
5474
|
+
/** Invocation-time param values for the main craftbook (launcher). */
|
|
5475
|
+
craftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5476
|
+
/** Invocation-time param values copied to each spawned child. */
|
|
5477
|
+
spawnsCraftbookParams: z23.record(z23.string(), z23.string()).optional(),
|
|
5478
|
+
/** Spawn-side (for schedule hosts and fanouts): catalog reference. */
|
|
5479
|
+
spawnsCraftbookId: z23.string().optional(),
|
|
5480
|
+
spawnsCraftbookSourceId: z23.string().optional(),
|
|
5481
|
+
spawnsCraftbookVersion: z23.string().optional(),
|
|
5482
|
+
spawnsSteps: z23.array(NewCraftbookStepSchema).optional(),
|
|
5483
|
+
spawnsEntryStepId: z23.string().optional(),
|
|
5484
|
+
parentTaskRef: z23.string().optional(),
|
|
5485
|
+
cron: z23.object({
|
|
5486
|
+
expression: z23.string(),
|
|
5487
|
+
overlap: TaskCronOverlapSchema.optional()
|
|
5488
|
+
}).optional(),
|
|
5489
|
+
nightShift: z23.object({
|
|
5490
|
+
enabled: z23.boolean(),
|
|
5491
|
+
onceADay: z23.boolean().optional()
|
|
5492
|
+
}).optional(),
|
|
5493
|
+
fanout: NewTaskFanoutSchema.optional(),
|
|
5494
|
+
createdBy: TaskAssigneeSchema.optional(),
|
|
5495
|
+
/** Preserve the launcher's naming presentation across task handoffs. */
|
|
5496
|
+
roleBasedNameOnlyMode: z23.boolean().optional(),
|
|
5497
|
+
/**
|
|
5498
|
+
* Enqueue the entry-step handoff immediately after create — the
|
|
5499
|
+
* single-channel kickoff (there is no "tell a gezel about work"
|
|
5500
|
+
* separate from "hand a gezel the work"). The worker starts in a
|
|
5501
|
+
* task-scoped session with the step prompt + gate contract
|
|
5502
|
+
* in-prompt. Invalid on drafts (they kick off via `activate`) and
|
|
5503
|
+
* on cron/fanout hosts (their children dispatch via their own
|
|
5504
|
+
* activation hooks — flag-dispatching the host would double-engage).
|
|
5505
|
+
*/
|
|
5506
|
+
dispatchEntry: z23.boolean().optional(),
|
|
5507
|
+
/**
|
|
5508
|
+
* Internal invoke_craftbook idempotency digest. The task route converts
|
|
5509
|
+
* it into service-owned Task.origin provenance; ordinary create_task
|
|
5510
|
+
* callers omit it.
|
|
5511
|
+
*/
|
|
5512
|
+
craftbookInvocationKey: z23.string().regex(/^craftbook-root-v1:[a-f0-9]{64}$/).optional()
|
|
5513
|
+
}).refine((v) => !!v.craftbookId !== !!(v.steps && v.steps.length > 0), {
|
|
5514
|
+
message: "exactly one of craftbookId or steps must be provided for the main craftbook",
|
|
5434
5515
|
path: ["craftbookId"]
|
|
5435
5516
|
}).refine(
|
|
5436
5517
|
(v) => {
|
|
@@ -5532,6 +5613,8 @@ var UpdateTaskStepRequestSchema = z23.object({
|
|
|
5532
5613
|
/** Step automation hooks (single ref or ordered list). `null` detaches. */
|
|
5533
5614
|
onEnter: ScriptRefListSchema.nullable().optional(),
|
|
5534
5615
|
onExit: ScriptRefListSchema.nullable().optional(),
|
|
5616
|
+
/** Required file inputs for the step. `null` clears the declaration. */
|
|
5617
|
+
consumes: z23.array(CraftbookStepInputSchema).min(1).nullable().optional(),
|
|
5535
5618
|
/** Auto-advance contract. `null` clears it. */
|
|
5536
5619
|
advanceWhen: AdvanceWhenSchema.nullable().optional(),
|
|
5537
5620
|
/** The end-of-step gate (current or legacy shape). `null` clears it. */
|
|
@@ -6342,7 +6425,7 @@ var ProjectTypeCompositionShape = {
|
|
|
6342
6425
|
tabVisibility: ProjectTabVisibilitySchema.optional(),
|
|
6343
6426
|
/**
|
|
6344
6427
|
* Project shape for instances of this type. `solo` marks a single-gezel
|
|
6345
|
-
* "
|
|
6428
|
+
* "Builder" experience (games, the chat room): the one roster gezel
|
|
6346
6429
|
* does everything, no separate overseer voorman is recruited, and the UI
|
|
6347
6430
|
* collapses the crew picker to that lead. Maps onto the project's `mode`
|
|
6348
6431
|
* at adoption. Omit for the default crew shape.
|
|
@@ -6350,9 +6433,9 @@ var ProjectTypeCompositionShape = {
|
|
|
6350
6433
|
mode: z26.enum(["crew", "solo"]).optional(),
|
|
6351
6434
|
/**
|
|
6352
6435
|
* Custom label for this type's project lead, shown wherever the generic
|
|
6353
|
-
* "Voorman" / "
|
|
6436
|
+
* "Voorman" / "Builder" would appear (the chat chip, project
|
|
6354
6437
|
* settings) — e.g. checkers uses "Opponent". Aimed at solo types that
|
|
6355
|
-
* want a domain word instead of "
|
|
6438
|
+
* want a domain word instead of "Builder". The underlying data field
|
|
6356
6439
|
* stays `voormanGezelId`; only the rendered label changes.
|
|
6357
6440
|
*/
|
|
6358
6441
|
leadLabel: z26.string().min(1).optional(),
|
|
@@ -6461,6 +6544,13 @@ var ConnectorActionSchema = z26.object({
|
|
|
6461
6544
|
/** Consent gate this action clears at commit time (e.g. `recipient-allowlist`). */
|
|
6462
6545
|
consentScope: z26.string()
|
|
6463
6546
|
});
|
|
6547
|
+
var ConnectorSetupInstructionsSchema = z26.object({
|
|
6548
|
+
title: z26.string().min(1),
|
|
6549
|
+
description: z26.string().min(1).optional(),
|
|
6550
|
+
steps: z26.array(z26.string().min(1)).optional(),
|
|
6551
|
+
url: z26.string().url().optional(),
|
|
6552
|
+
urlLabel: z26.string().min(1).optional()
|
|
6553
|
+
});
|
|
6464
6554
|
var ConnectorTypeCompositionShape = {
|
|
6465
6555
|
/** Which driver executes the fetch. */
|
|
6466
6556
|
driver: ConnectorDriverSchema,
|
|
@@ -6468,6 +6558,8 @@ var ConnectorTypeCompositionShape = {
|
|
|
6468
6558
|
configSchema: z26.record(z26.string(), z26.unknown()).optional(),
|
|
6469
6559
|
/** Shape of the credential the binding stores in the SecretStore. */
|
|
6470
6560
|
secretShape: z26.record(z26.string(), z26.unknown()).optional(),
|
|
6561
|
+
/** Concise setup guidance rendered above the binding form. */
|
|
6562
|
+
setupInstructions: ConnectorSetupInstructionsSchema.optional(),
|
|
6471
6563
|
/**
|
|
6472
6564
|
* Driver-specific fetch config: `{adapterId}` (native) | `{server,list,fetch}`
|
|
6473
6565
|
* (mcp) | `{fetch|cli}` (script) | `{component,action,...}` (spectral).
|
|
@@ -6777,6 +6869,15 @@ var ChatModelMlxSourceSchema = z26.object({
|
|
|
6777
6869
|
});
|
|
6778
6870
|
var ChatModelIdentitySchema = IdentityCommonSchema.extend({
|
|
6779
6871
|
kind: z26.literal("chat-model"),
|
|
6872
|
+
/**
|
|
6873
|
+
* Organization that created the core model weights when it differs from
|
|
6874
|
+
* the catalog maintainer (for example, a quant maintained by its converter).
|
|
6875
|
+
* Omit when `maintainer` already names the maker.
|
|
6876
|
+
*/
|
|
6877
|
+
maker: z26.object({
|
|
6878
|
+
name: z26.string().min(1),
|
|
6879
|
+
url: z26.string().url().optional()
|
|
6880
|
+
}).optional(),
|
|
6780
6881
|
parameterSize: z26.string(),
|
|
6781
6882
|
supportsTools: z26.boolean(),
|
|
6782
6883
|
contextWindow: z26.number().int().positive().optional(),
|
|
@@ -6874,6 +6975,11 @@ var ChatModelManifestSchema = z26.object({
|
|
|
6874
6975
|
name: z26.string(),
|
|
6875
6976
|
url: z26.string().url().optional()
|
|
6876
6977
|
}),
|
|
6978
|
+
/** Core-model maker; present when it differs from `maintainer`. */
|
|
6979
|
+
maker: z26.object({
|
|
6980
|
+
name: z26.string().min(1),
|
|
6981
|
+
url: z26.string().url().optional()
|
|
6982
|
+
}).optional(),
|
|
6877
6983
|
logo: z26.string().optional(),
|
|
6878
6984
|
license: z26.string().optional(),
|
|
6879
6985
|
...LicenseMetaShape,
|
|
@@ -7685,6 +7791,18 @@ var ChatSessionSchema = z28.object({
|
|
|
7685
7791
|
}),
|
|
7686
7792
|
/** Snapshot of the gezel's about.md at session creation, for drift warnings. */
|
|
7687
7793
|
aboutSnapshot: z28.string().optional(),
|
|
7794
|
+
/**
|
|
7795
|
+
* Per-session override of `config.roleBasedNameOnlyMode` ("boring mode").
|
|
7796
|
+
* Stamped at creation when the creating client has a fixed presentation
|
|
7797
|
+
* mode — the TUI always renders role-based labels, so it pins the
|
|
7798
|
+
* sessions it creates to `true`. This keeps the prompt (what the model
|
|
7799
|
+
* is told about other gezels) consistent with what that client shows;
|
|
7800
|
+
* without it the TUI displayed `reviewer:` while the system prompt said
|
|
7801
|
+
* "the voorman is Tomas", and the model naturally leaked names into
|
|
7802
|
+
* prose. Unset = follow the live config flag, which is what desktop
|
|
7803
|
+
* sessions do.
|
|
7804
|
+
*/
|
|
7805
|
+
roleBasedNameOnlyMode: z28.boolean().optional(),
|
|
7688
7806
|
/** Set when the last attempted resume failed — UI surfaces a banner. */
|
|
7689
7807
|
resumeFailed: z28.boolean().optional(),
|
|
7690
7808
|
/**
|
|
@@ -7913,7 +8031,14 @@ var CreateChatSessionRequestSchema = z28.object({
|
|
|
7913
8031
|
projectId: z28.string().optional(),
|
|
7914
8032
|
taskRef: z28.string().optional(),
|
|
7915
8033
|
stepId: z28.string().optional(),
|
|
7916
|
-
craftbookRef: z28.string().optional()
|
|
8034
|
+
craftbookRef: z28.string().optional(),
|
|
8035
|
+
/**
|
|
8036
|
+
* Pin the session's name-rendering mode instead of following
|
|
8037
|
+
* `config.roleBasedNameOnlyMode`. Passed by clients whose presentation
|
|
8038
|
+
* mode is fixed (the TUI) so prompt-side name rendering matches their
|
|
8039
|
+
* labels. See `ChatSessionSchema.roleBasedNameOnlyMode`.
|
|
8040
|
+
*/
|
|
8041
|
+
roleBasedNameOnlyMode: z28.boolean().optional()
|
|
7917
8042
|
});
|
|
7918
8043
|
var ListChatSessionsResponseSchema = z28.object({
|
|
7919
8044
|
sessions: z28.array(ChatSessionSummarySchema)
|
|
@@ -8539,13 +8664,26 @@ var GitHubPullFileSchema = z33.object({
|
|
|
8539
8664
|
additions: z33.number().int(),
|
|
8540
8665
|
deletions: z33.number().int(),
|
|
8541
8666
|
changes: z33.number().int(),
|
|
8542
|
-
/**
|
|
8667
|
+
/** Unified diff hunk, if requested and returned by GitHub. */
|
|
8543
8668
|
patch: z33.string().optional(),
|
|
8669
|
+
/** Character count before Gezel's local patch budget was applied. */
|
|
8670
|
+
patchChars: z33.number().int().nonnegative().optional(),
|
|
8671
|
+
/** True when Gezel clipped `patch`; callers must request the file/diff directly. */
|
|
8672
|
+
patchTruncated: z33.boolean().optional(),
|
|
8544
8673
|
/** Prior path when `status === 'renamed'`. */
|
|
8545
8674
|
previousFilename: z33.string().optional()
|
|
8546
8675
|
});
|
|
8547
8676
|
var ListGitHubPullFilesResponseSchema = z33.object({
|
|
8548
|
-
files: z33.array(GitHubPullFileSchema)
|
|
8677
|
+
files: z33.array(GitHubPullFileSchema),
|
|
8678
|
+
/** Total files in the PR before an optional path filter. */
|
|
8679
|
+
allFiles: z33.number().int().nonnegative().optional(),
|
|
8680
|
+
/** Total files selected by the optional path filter. */
|
|
8681
|
+
totalFiles: z33.number().int().nonnegative().optional(),
|
|
8682
|
+
offset: z33.number().int().nonnegative().optional(),
|
|
8683
|
+
limit: z33.number().int().positive().optional(),
|
|
8684
|
+
hasMore: z33.boolean().optional(),
|
|
8685
|
+
nextOffset: z33.number().int().nonnegative().optional(),
|
|
8686
|
+
includesPatch: z33.boolean().optional()
|
|
8549
8687
|
});
|
|
8550
8688
|
var GitHubPullCommentSchema = z33.object({
|
|
8551
8689
|
id: z33.number(),
|
|
@@ -8562,7 +8700,14 @@ var ListGitHubPullCommentsResponseSchema = z33.object({
|
|
|
8562
8700
|
});
|
|
8563
8701
|
var GitHubPullDiffResponseSchema = z33.object({
|
|
8564
8702
|
number: z33.number().int(),
|
|
8565
|
-
diff: z33.string()
|
|
8703
|
+
diff: z33.string(),
|
|
8704
|
+
/** Exact changed path when this is a file-scoped diff. */
|
|
8705
|
+
path: z33.string().optional(),
|
|
8706
|
+
offset: z33.number().int().nonnegative().optional(),
|
|
8707
|
+
returnedChars: z33.number().int().nonnegative().optional(),
|
|
8708
|
+
totalChars: z33.number().int().nonnegative().optional(),
|
|
8709
|
+
truncated: z33.boolean().optional(),
|
|
8710
|
+
nextOffset: z33.number().int().nonnegative().optional()
|
|
8566
8711
|
});
|
|
8567
8712
|
var GitHubCreateCommentRequestSchema = z33.object({
|
|
8568
8713
|
body: z33.string().min(1)
|
|
@@ -10850,6 +10995,13 @@ var GezelConfigSchema = z37.object({
|
|
|
10850
10995
|
* Advanced.
|
|
10851
10996
|
*/
|
|
10852
10997
|
showAdvancedFeatures: z37.boolean().optional(),
|
|
10998
|
+
/**
|
|
10999
|
+
* When `true`, very early work-in-progress surfaces are revealed in the
|
|
11000
|
+
* UI and CLI. This is a discoverability preference, not a security or
|
|
11001
|
+
* service-layer capability boundary. Defaults on in development builds
|
|
11002
|
+
* and off in releases; an explicit user choice always wins.
|
|
11003
|
+
*/
|
|
11004
|
+
showWorkInProgressFeatures: z37.boolean().optional(),
|
|
10853
11005
|
/**
|
|
10854
11006
|
* Debug-only opt-in: when `true`, the service rewrites every
|
|
10855
11007
|
* template-derived gezel's `about.md` back to the prose its catalog
|
|
@@ -11126,7 +11278,7 @@ var GezelConfigSchema = z37.object({
|
|
|
11126
11278
|
* crew with granular per-step craftbooks. Right for raw-completion
|
|
11127
11279
|
* local models, where gezel's loop IS the agent.
|
|
11128
11280
|
* - `flat`: route concrete asks to a single generalist (`start_job` →
|
|
11129
|
-
* solo
|
|
11281
|
+
* solo Builder, which already collapses the craftbook onto the
|
|
11130
11282
|
* one specialist). Right for self-orchestrating providers (codex-cli,
|
|
11131
11283
|
* anthropic-cli, copilot) that bring their own agent loop — the crew
|
|
11132
11284
|
* + granular steps are mostly redundant overhead for them (eval data:
|
|
@@ -12030,6 +12182,12 @@ var ListProjectsResponseSchema = z37.object({
|
|
|
12030
12182
|
var CreateProjectRequestSchema = z37.object({
|
|
12031
12183
|
name: z37.string().min(1),
|
|
12032
12184
|
description: z37.string().optional(),
|
|
12185
|
+
/**
|
|
12186
|
+
* Existing local folder to use as the project workspace. Folder-backed
|
|
12187
|
+
* projects are created with ambient Meester progress check-ins disabled;
|
|
12188
|
+
* the user can opt back in from Project Settings.
|
|
12189
|
+
*/
|
|
12190
|
+
workingDir: z37.string().min(1).optional(),
|
|
12033
12191
|
// about/missionObjectives are *encouraged, not required* at the wire level.
|
|
12034
12192
|
// The New Project dialog still enforces the 60/40 richness minimums for the
|
|
12035
12193
|
// blank/GitHub flows (where the user is authoring context from scratch), but
|
|
@@ -12042,7 +12200,7 @@ var CreateProjectRequestSchema = z37.object({
|
|
|
12042
12200
|
missionObjectives: z37.string().optional().describe('Concrete success criteria \u2014 usually a bullet list. What does "done" look like?'),
|
|
12043
12201
|
/**
|
|
12044
12202
|
* Project shape. `crew` (default) → traditional voorman-coordinates-
|
|
12045
|
-
* specialists. `solo` → a "job": one
|
|
12203
|
+
* specialists. `solo` → a "job": one Builder does
|
|
12046
12204
|
* everything themselves; team-management tools are filtered out for
|
|
12047
12205
|
* sessions on this project.
|
|
12048
12206
|
*/
|
|
@@ -17460,6 +17618,7 @@ var STEP_FENCE_KEYS = [
|
|
|
17460
17618
|
"deliverable",
|
|
17461
17619
|
"onEnter",
|
|
17462
17620
|
"onExit",
|
|
17621
|
+
"consumes",
|
|
17463
17622
|
"advanceWhen",
|
|
17464
17623
|
"gate",
|
|
17465
17624
|
"next",
|
|
@@ -18757,6 +18916,68 @@ function isMoEFromTags(tags) {
|
|
|
18757
18916
|
});
|
|
18758
18917
|
}
|
|
18759
18918
|
|
|
18919
|
+
// src/model-attribution.ts
|
|
18920
|
+
function modelAttribution(manifest) {
|
|
18921
|
+
const sourceOwners = [
|
|
18922
|
+
manifest.llamaCpp?.huggingfaceRepo,
|
|
18923
|
+
manifest.mlx?.huggingfaceRepo,
|
|
18924
|
+
manifest.ds4?.huggingfaceRepo
|
|
18925
|
+
].map((repo) => repo ? huggingFaceOwnerFromRepo(repo) : null).filter((owner) => owner !== null);
|
|
18926
|
+
const explicitMakerOwner = manifest.maker?.url ? huggingFaceOwnerFromUrl(manifest.maker.url) : null;
|
|
18927
|
+
const maintainerOwner = manifest.maintainer.url ? huggingFaceOwnerFromUrl(manifest.maintainer.url) : null;
|
|
18928
|
+
const upstreamOwner = manifest.upstream ? huggingFaceOwnerFromUrl(manifest.upstream) : null;
|
|
18929
|
+
const normalizedSources = new Set(sourceOwners.map(normalizeOrganization));
|
|
18930
|
+
const maintainerIsSource = [manifest.maintainer.name, maintainerOwner].filter((name) => name !== null).some((name) => normalizedSources.has(normalizeOrganization(name)));
|
|
18931
|
+
const upstreamIsSource = upstreamOwner ? normalizedSources.has(normalizeOrganization(upstreamOwner)) : false;
|
|
18932
|
+
const makerFromUpstream = !manifest.maker && maintainerIsSource && upstreamOwner && !upstreamIsSource;
|
|
18933
|
+
const maker = manifest.maker?.name ?? (makerFromUpstream ? displayOrganizationName(upstreamOwner) : manifest.maintainer.name);
|
|
18934
|
+
const makerAliases = /* @__PURE__ */ new Set([normalizeOrganization(maker)]);
|
|
18935
|
+
if (explicitMakerOwner) makerAliases.add(normalizeOrganization(explicitMakerOwner));
|
|
18936
|
+
if (upstreamOwner) makerAliases.add(normalizeOrganization(upstreamOwner));
|
|
18937
|
+
if (!manifest.maker && !makerFromUpstream) {
|
|
18938
|
+
makerAliases.add(normalizeOrganization(manifest.maintainer.name));
|
|
18939
|
+
if (maintainerOwner) makerAliases.add(normalizeOrganization(maintainerOwner));
|
|
18940
|
+
}
|
|
18941
|
+
const customizers = [];
|
|
18942
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18943
|
+
const customizerCandidates = manifest.maker ? [manifest.maintainer.name, ...sourceOwners] : sourceOwners;
|
|
18944
|
+
for (const owner of customizerCandidates) {
|
|
18945
|
+
const normalized = normalizeOrganization(owner);
|
|
18946
|
+
if (!normalized || makerAliases.has(normalized) || seen.has(normalized)) continue;
|
|
18947
|
+
seen.add(normalized);
|
|
18948
|
+
customizers.push(owner);
|
|
18949
|
+
}
|
|
18950
|
+
return { maker, customizers };
|
|
18951
|
+
}
|
|
18952
|
+
function displayOrganizationName(owner) {
|
|
18953
|
+
const knownNames = {
|
|
18954
|
+
"deepseek-ai": "DeepSeek",
|
|
18955
|
+
"zai-org": "Z.ai"
|
|
18956
|
+
};
|
|
18957
|
+
return knownNames[owner.toLowerCase()] ?? owner;
|
|
18958
|
+
}
|
|
18959
|
+
function formatModelAttribution(manifest) {
|
|
18960
|
+
const attribution = modelAttribution(manifest);
|
|
18961
|
+
return attribution.customizers.length > 0 ? `${attribution.maker}, customized by ${attribution.customizers.join(", ")}` : attribution.maker;
|
|
18962
|
+
}
|
|
18963
|
+
function huggingFaceOwnerFromRepo(repo) {
|
|
18964
|
+
const slash = repo.indexOf("/");
|
|
18965
|
+
return slash > 0 ? repo.slice(0, slash) : null;
|
|
18966
|
+
}
|
|
18967
|
+
function huggingFaceOwnerFromUrl(value) {
|
|
18968
|
+
try {
|
|
18969
|
+
const url = new URL(value);
|
|
18970
|
+
if (url.hostname.toLowerCase() !== "huggingface.co") return null;
|
|
18971
|
+
const owner = url.pathname.split("/").filter(Boolean)[0];
|
|
18972
|
+
return owner ?? null;
|
|
18973
|
+
} catch {
|
|
18974
|
+
return null;
|
|
18975
|
+
}
|
|
18976
|
+
}
|
|
18977
|
+
function normalizeOrganization(value) {
|
|
18978
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
18979
|
+
}
|
|
18980
|
+
|
|
18760
18981
|
// src/fitness-badge.ts
|
|
18761
18982
|
var CHECK_LABELS = [
|
|
18762
18983
|
{ key: "spawn", label: "did not start" },
|
|
@@ -22933,9 +23154,9 @@ var scorecard_default = {
|
|
|
22933
23154
|
schemaVersion: 1,
|
|
22934
23155
|
runs: [
|
|
22935
23156
|
{
|
|
22936
|
-
id: "2026-08-
|
|
23157
|
+
id: "2026-08-13-m4max-llamacpp",
|
|
22937
23158
|
provenance: {
|
|
22938
|
-
startedAt: "2026-08-
|
|
23159
|
+
startedAt: "2026-08-13T07:05:36.620Z",
|
|
22939
23160
|
device: {
|
|
22940
23161
|
label: "Mac \xB7 Apple M4 Max",
|
|
22941
23162
|
platform: "darwin",
|
|
@@ -22944,8 +23165,8 @@ var scorecard_default = {
|
|
|
22944
23165
|
osRelease: "darwin 25.5.0",
|
|
22945
23166
|
cpuModel: "Apple M4 Max"
|
|
22946
23167
|
},
|
|
22947
|
-
harnessCommit: "
|
|
22948
|
-
gildeVersion: "0.1.
|
|
23168
|
+
harnessCommit: "c5904085",
|
|
23169
|
+
gildeVersion: "0.1.23",
|
|
22949
23170
|
count: 3,
|
|
22950
23171
|
judgeModelId: null
|
|
22951
23172
|
},
|
|
@@ -22982,57 +23203,978 @@ var scorecard_default = {
|
|
|
22982
23203
|
}
|
|
22983
23204
|
},
|
|
22984
23205
|
{
|
|
22985
|
-
id: "2026-08-
|
|
22986
|
-
provenance: {
|
|
22987
|
-
startedAt: "2026-08-
|
|
22988
|
-
device: {
|
|
22989
|
-
label: "Mac \xB7 Apple M4 Max",
|
|
22990
|
-
platform: "darwin",
|
|
22991
|
-
arch: "arm64",
|
|
22992
|
-
memoryGb: 64,
|
|
22993
|
-
osRelease: "darwin 25.5.0",
|
|
22994
|
-
cpuModel: "Apple M4 Max"
|
|
23206
|
+
id: "2026-08-11-m4max-llamacpp",
|
|
23207
|
+
provenance: {
|
|
23208
|
+
startedAt: "2026-08-11T16:21:09.513Z",
|
|
23209
|
+
device: {
|
|
23210
|
+
label: "Mac \xB7 Apple M4 Max",
|
|
23211
|
+
platform: "darwin",
|
|
23212
|
+
arch: "arm64",
|
|
23213
|
+
memoryGb: 64,
|
|
23214
|
+
osRelease: "darwin 25.5.0",
|
|
23215
|
+
cpuModel: "Apple M4 Max"
|
|
23216
|
+
},
|
|
23217
|
+
harnessCommit: "b2ea2819",
|
|
23218
|
+
gildeVersion: "0.1.20",
|
|
23219
|
+
count: 3,
|
|
23220
|
+
judgeModelId: null
|
|
23221
|
+
},
|
|
23222
|
+
suites: ["core", "productivity"],
|
|
23223
|
+
scenariosBySuite: {
|
|
23224
|
+
core: [
|
|
23225
|
+
"tictactoe",
|
|
23226
|
+
"petshop",
|
|
23227
|
+
"tankcombat",
|
|
23228
|
+
"schema-migration",
|
|
23229
|
+
"failing-tests-spec",
|
|
23230
|
+
"symptom-debug",
|
|
23231
|
+
"data-wrangle",
|
|
23232
|
+
"incident-postmortem",
|
|
23233
|
+
"ops-runbook-anomaly",
|
|
23234
|
+
"plan-and-estimate",
|
|
23235
|
+
"conflict-synthesis"
|
|
23236
|
+
],
|
|
23237
|
+
productivity: [
|
|
23238
|
+
"constrained-comms",
|
|
23239
|
+
"craftbook-week-plan",
|
|
23240
|
+
"craftbook-ab-test-readout",
|
|
23241
|
+
"craftbook-annotated-bibliography",
|
|
23242
|
+
"records-intake",
|
|
23243
|
+
"plan-and-estimate",
|
|
23244
|
+
"meeting-followup",
|
|
23245
|
+
"craftbook-spreadsheet-model",
|
|
23246
|
+
"conflict-synthesis",
|
|
23247
|
+
"docblocks-theme-roundtrip",
|
|
23248
|
+
"craftbook-research-to-document",
|
|
23249
|
+
"craftbook-powerpoint-deck",
|
|
23250
|
+
"wikipedia-research-brief"
|
|
23251
|
+
]
|
|
23252
|
+
}
|
|
23253
|
+
},
|
|
23254
|
+
{
|
|
23255
|
+
id: "2026-08-09-m4max-llamacpp",
|
|
23256
|
+
provenance: {
|
|
23257
|
+
startedAt: "2026-08-09T23:39:13.000Z",
|
|
23258
|
+
device: {
|
|
23259
|
+
label: "Mac \xB7 Apple M4 Max",
|
|
23260
|
+
platform: "darwin",
|
|
23261
|
+
arch: "arm64",
|
|
23262
|
+
memoryGb: 64,
|
|
23263
|
+
osRelease: "darwin 25.5.0",
|
|
23264
|
+
cpuModel: "Apple M4 Max"
|
|
23265
|
+
},
|
|
23266
|
+
harnessCommit: "e2859602",
|
|
23267
|
+
gildeVersion: "0.1.17",
|
|
23268
|
+
count: 3,
|
|
23269
|
+
judgeModelId: null
|
|
23270
|
+
},
|
|
23271
|
+
suites: ["core", "productivity"],
|
|
23272
|
+
scenariosBySuite: {
|
|
23273
|
+
core: [
|
|
23274
|
+
"tictactoe",
|
|
23275
|
+
"petshop",
|
|
23276
|
+
"tankcombat",
|
|
23277
|
+
"schema-migration",
|
|
23278
|
+
"failing-tests-spec",
|
|
23279
|
+
"symptom-debug",
|
|
23280
|
+
"data-wrangle",
|
|
23281
|
+
"incident-postmortem",
|
|
23282
|
+
"ops-runbook-anomaly",
|
|
23283
|
+
"plan-and-estimate",
|
|
23284
|
+
"conflict-synthesis"
|
|
23285
|
+
],
|
|
23286
|
+
productivity: [
|
|
23287
|
+
"constrained-comms",
|
|
23288
|
+
"craftbook-week-plan",
|
|
23289
|
+
"craftbook-ab-test-readout",
|
|
23290
|
+
"craftbook-annotated-bibliography",
|
|
23291
|
+
"records-intake",
|
|
23292
|
+
"plan-and-estimate",
|
|
23293
|
+
"meeting-followup",
|
|
23294
|
+
"craftbook-spreadsheet-model",
|
|
23295
|
+
"conflict-synthesis",
|
|
23296
|
+
"docblocks-theme-roundtrip",
|
|
23297
|
+
"craftbook-research-to-document",
|
|
23298
|
+
"craftbook-powerpoint-deck",
|
|
23299
|
+
"wikipedia-research-brief"
|
|
23300
|
+
]
|
|
23301
|
+
},
|
|
23302
|
+
note: "Published scorecard sweep (llama-cpp, count-strict)."
|
|
23303
|
+
}
|
|
23304
|
+
],
|
|
23305
|
+
results: [
|
|
23306
|
+
{
|
|
23307
|
+
modelId: "gemma4-26b-q4",
|
|
23308
|
+
label: "gemma4-26b-q4",
|
|
23309
|
+
engine: "llama-cpp",
|
|
23310
|
+
tier: "medium",
|
|
23311
|
+
parameterSize: "25.2B",
|
|
23312
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23313
|
+
suiteId: "core",
|
|
23314
|
+
performance: {
|
|
23315
|
+
prefillTokensPerSec: 1264,
|
|
23316
|
+
decodeTokensPerSec: 107.5,
|
|
23317
|
+
samples: 1
|
|
23318
|
+
},
|
|
23319
|
+
runtime: {
|
|
23320
|
+
contextTokens: 120832,
|
|
23321
|
+
peakMemoryMb: 42690
|
|
23322
|
+
},
|
|
23323
|
+
judge: {
|
|
23324
|
+
meanScore: 5.7,
|
|
23325
|
+
artifacts: 9,
|
|
23326
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23327
|
+
},
|
|
23328
|
+
cells: [
|
|
23329
|
+
{
|
|
23330
|
+
scenarioId: "tictactoe",
|
|
23331
|
+
trials: 3,
|
|
23332
|
+
successes: 3,
|
|
23333
|
+
nonModelFailures: 0,
|
|
23334
|
+
medianDurationMs: 127411
|
|
23335
|
+
},
|
|
23336
|
+
{
|
|
23337
|
+
scenarioId: "petshop",
|
|
23338
|
+
trials: 3,
|
|
23339
|
+
successes: 3,
|
|
23340
|
+
nonModelFailures: 0,
|
|
23341
|
+
medianDurationMs: 482159
|
|
23342
|
+
},
|
|
23343
|
+
{
|
|
23344
|
+
scenarioId: "tankcombat",
|
|
23345
|
+
trials: 3,
|
|
23346
|
+
successes: 3,
|
|
23347
|
+
nonModelFailures: 0,
|
|
23348
|
+
medianDurationMs: 290618
|
|
23349
|
+
},
|
|
23350
|
+
{
|
|
23351
|
+
scenarioId: "schema-migration",
|
|
23352
|
+
trials: 3,
|
|
23353
|
+
successes: 3,
|
|
23354
|
+
nonModelFailures: 0,
|
|
23355
|
+
medianDurationMs: 69039
|
|
23356
|
+
},
|
|
23357
|
+
{
|
|
23358
|
+
scenarioId: "failing-tests-spec",
|
|
23359
|
+
trials: 3,
|
|
23360
|
+
successes: 3,
|
|
23361
|
+
nonModelFailures: 0,
|
|
23362
|
+
medianDurationMs: 28770
|
|
23363
|
+
},
|
|
23364
|
+
{
|
|
23365
|
+
scenarioId: "symptom-debug",
|
|
23366
|
+
trials: 3,
|
|
23367
|
+
successes: 3,
|
|
23368
|
+
nonModelFailures: 0,
|
|
23369
|
+
medianDurationMs: 83940
|
|
23370
|
+
},
|
|
23371
|
+
{
|
|
23372
|
+
scenarioId: "data-wrangle",
|
|
23373
|
+
trials: 3,
|
|
23374
|
+
successes: 3,
|
|
23375
|
+
nonModelFailures: 0,
|
|
23376
|
+
medianDurationMs: 48055
|
|
23377
|
+
},
|
|
23378
|
+
{
|
|
23379
|
+
scenarioId: "incident-postmortem",
|
|
23380
|
+
trials: 3,
|
|
23381
|
+
successes: 3,
|
|
23382
|
+
nonModelFailures: 0,
|
|
23383
|
+
medianDurationMs: 189005
|
|
23384
|
+
},
|
|
23385
|
+
{
|
|
23386
|
+
scenarioId: "ops-runbook-anomaly",
|
|
23387
|
+
trials: 3,
|
|
23388
|
+
successes: 3,
|
|
23389
|
+
nonModelFailures: 0,
|
|
23390
|
+
medianDurationMs: 233624
|
|
23391
|
+
},
|
|
23392
|
+
{
|
|
23393
|
+
scenarioId: "plan-and-estimate",
|
|
23394
|
+
trials: 3,
|
|
23395
|
+
successes: 3,
|
|
23396
|
+
nonModelFailures: 0,
|
|
23397
|
+
medianDurationMs: 17679
|
|
23398
|
+
},
|
|
23399
|
+
{
|
|
23400
|
+
scenarioId: "conflict-synthesis",
|
|
23401
|
+
trials: 3,
|
|
23402
|
+
successes: 3,
|
|
23403
|
+
nonModelFailures: 0,
|
|
23404
|
+
medianDurationMs: 52710
|
|
23405
|
+
}
|
|
23406
|
+
]
|
|
23407
|
+
},
|
|
23408
|
+
{
|
|
23409
|
+
modelId: "muse-glimmer-30b-q4",
|
|
23410
|
+
label: "muse-glimmer-30b-q4",
|
|
23411
|
+
engine: "llama-cpp",
|
|
23412
|
+
tier: "medium",
|
|
23413
|
+
parameterSize: "30B",
|
|
23414
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23415
|
+
suiteId: "core",
|
|
23416
|
+
performance: {
|
|
23417
|
+
prefillTokensPerSec: 226,
|
|
23418
|
+
decodeTokensPerSec: 26,
|
|
23419
|
+
samples: 1
|
|
23420
|
+
},
|
|
23421
|
+
runtime: {
|
|
23422
|
+
contextTokens: 131072,
|
|
23423
|
+
peakMemoryMb: 19638
|
|
23424
|
+
},
|
|
23425
|
+
judge: {
|
|
23426
|
+
meanScore: 6.5,
|
|
23427
|
+
artifacts: 9,
|
|
23428
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23429
|
+
},
|
|
23430
|
+
cells: [
|
|
23431
|
+
{
|
|
23432
|
+
scenarioId: "tictactoe",
|
|
23433
|
+
trials: 3,
|
|
23434
|
+
successes: 3,
|
|
23435
|
+
nonModelFailures: 0,
|
|
23436
|
+
medianDurationMs: 210652
|
|
23437
|
+
},
|
|
23438
|
+
{
|
|
23439
|
+
scenarioId: "petshop",
|
|
23440
|
+
trials: 3,
|
|
23441
|
+
successes: 3,
|
|
23442
|
+
nonModelFailures: 0,
|
|
23443
|
+
medianDurationMs: 356601
|
|
23444
|
+
},
|
|
23445
|
+
{
|
|
23446
|
+
scenarioId: "tankcombat",
|
|
23447
|
+
trials: 3,
|
|
23448
|
+
successes: 3,
|
|
23449
|
+
nonModelFailures: 0,
|
|
23450
|
+
medianDurationMs: 272117
|
|
23451
|
+
},
|
|
23452
|
+
{
|
|
23453
|
+
scenarioId: "schema-migration",
|
|
23454
|
+
trials: 3,
|
|
23455
|
+
successes: 3,
|
|
23456
|
+
nonModelFailures: 0,
|
|
23457
|
+
medianDurationMs: 269225
|
|
23458
|
+
},
|
|
23459
|
+
{
|
|
23460
|
+
scenarioId: "failing-tests-spec",
|
|
23461
|
+
trials: 3,
|
|
23462
|
+
successes: 3,
|
|
23463
|
+
nonModelFailures: 0,
|
|
23464
|
+
medianDurationMs: 279796
|
|
23465
|
+
},
|
|
23466
|
+
{
|
|
23467
|
+
scenarioId: "symptom-debug",
|
|
23468
|
+
trials: 3,
|
|
23469
|
+
successes: 3,
|
|
23470
|
+
nonModelFailures: 0,
|
|
23471
|
+
medianDurationMs: 239896
|
|
23472
|
+
},
|
|
23473
|
+
{
|
|
23474
|
+
scenarioId: "data-wrangle",
|
|
23475
|
+
trials: 3,
|
|
23476
|
+
successes: 3,
|
|
23477
|
+
nonModelFailures: 0,
|
|
23478
|
+
medianDurationMs: 563414
|
|
23479
|
+
},
|
|
23480
|
+
{
|
|
23481
|
+
scenarioId: "incident-postmortem",
|
|
23482
|
+
trials: 3,
|
|
23483
|
+
successes: 2,
|
|
23484
|
+
nonModelFailures: 0,
|
|
23485
|
+
medianDurationMs: 4467148
|
|
23486
|
+
},
|
|
23487
|
+
{
|
|
23488
|
+
scenarioId: "ops-runbook-anomaly",
|
|
23489
|
+
trials: 3,
|
|
23490
|
+
successes: 2,
|
|
23491
|
+
nonModelFailures: 0,
|
|
23492
|
+
medianDurationMs: 474336
|
|
23493
|
+
},
|
|
23494
|
+
{
|
|
23495
|
+
scenarioId: "plan-and-estimate",
|
|
23496
|
+
trials: 3,
|
|
23497
|
+
successes: 3,
|
|
23498
|
+
nonModelFailures: 0,
|
|
23499
|
+
medianDurationMs: 150465
|
|
23500
|
+
},
|
|
23501
|
+
{
|
|
23502
|
+
scenarioId: "conflict-synthesis",
|
|
23503
|
+
trials: 3,
|
|
23504
|
+
successes: 2,
|
|
23505
|
+
nonModelFailures: 0,
|
|
23506
|
+
medianDurationMs: 404097
|
|
23507
|
+
}
|
|
23508
|
+
]
|
|
23509
|
+
},
|
|
23510
|
+
{
|
|
23511
|
+
modelId: "nemotron3.5-lightning-30b-q4",
|
|
23512
|
+
label: "nemotron3.5-lightning-30b-q4",
|
|
23513
|
+
engine: "llama-cpp",
|
|
23514
|
+
tier: "medium",
|
|
23515
|
+
parameterSize: "30B",
|
|
23516
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23517
|
+
suiteId: "core",
|
|
23518
|
+
performance: {
|
|
23519
|
+
prefillTokensPerSec: 1030,
|
|
23520
|
+
decodeTokensPerSec: 93.2,
|
|
23521
|
+
samples: 1
|
|
23522
|
+
},
|
|
23523
|
+
runtime: {
|
|
23524
|
+
contextTokens: 1048576,
|
|
23525
|
+
peakMemoryMb: 30085
|
|
23526
|
+
},
|
|
23527
|
+
judge: {
|
|
23528
|
+
meanScore: 5.6,
|
|
23529
|
+
artifacts: 9,
|
|
23530
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23531
|
+
},
|
|
23532
|
+
cells: [
|
|
23533
|
+
{
|
|
23534
|
+
scenarioId: "tictactoe",
|
|
23535
|
+
trials: 3,
|
|
23536
|
+
successes: 3,
|
|
23537
|
+
nonModelFailures: 0,
|
|
23538
|
+
medianDurationMs: 90179
|
|
23539
|
+
},
|
|
23540
|
+
{
|
|
23541
|
+
scenarioId: "petshop",
|
|
23542
|
+
trials: 3,
|
|
23543
|
+
successes: 3,
|
|
23544
|
+
nonModelFailures: 0,
|
|
23545
|
+
medianDurationMs: 899922
|
|
23546
|
+
},
|
|
23547
|
+
{
|
|
23548
|
+
scenarioId: "tankcombat",
|
|
23549
|
+
trials: 3,
|
|
23550
|
+
successes: 3,
|
|
23551
|
+
nonModelFailures: 0,
|
|
23552
|
+
medianDurationMs: 65485
|
|
23553
|
+
},
|
|
23554
|
+
{
|
|
23555
|
+
scenarioId: "schema-migration",
|
|
23556
|
+
trials: 3,
|
|
23557
|
+
successes: 3,
|
|
23558
|
+
nonModelFailures: 0,
|
|
23559
|
+
medianDurationMs: 133904
|
|
23560
|
+
},
|
|
23561
|
+
{
|
|
23562
|
+
scenarioId: "failing-tests-spec",
|
|
23563
|
+
trials: 3,
|
|
23564
|
+
successes: 2,
|
|
23565
|
+
nonModelFailures: 0,
|
|
23566
|
+
medianDurationMs: 230269
|
|
23567
|
+
},
|
|
23568
|
+
{
|
|
23569
|
+
scenarioId: "symptom-debug",
|
|
23570
|
+
trials: 3,
|
|
23571
|
+
successes: 3,
|
|
23572
|
+
nonModelFailures: 0,
|
|
23573
|
+
medianDurationMs: 94023
|
|
23574
|
+
},
|
|
23575
|
+
{
|
|
23576
|
+
scenarioId: "data-wrangle",
|
|
23577
|
+
trials: 3,
|
|
23578
|
+
successes: 2,
|
|
23579
|
+
nonModelFailures: 0,
|
|
23580
|
+
medianDurationMs: 319197
|
|
23581
|
+
},
|
|
23582
|
+
{
|
|
23583
|
+
scenarioId: "incident-postmortem",
|
|
23584
|
+
trials: 3,
|
|
23585
|
+
successes: 1,
|
|
23586
|
+
nonModelFailures: 0,
|
|
23587
|
+
medianDurationMs: 223455
|
|
23588
|
+
},
|
|
23589
|
+
{
|
|
23590
|
+
scenarioId: "ops-runbook-anomaly",
|
|
23591
|
+
trials: 3,
|
|
23592
|
+
successes: 3,
|
|
23593
|
+
nonModelFailures: 0,
|
|
23594
|
+
medianDurationMs: 93099
|
|
23595
|
+
},
|
|
23596
|
+
{
|
|
23597
|
+
scenarioId: "plan-and-estimate",
|
|
23598
|
+
trials: 3,
|
|
23599
|
+
successes: 2,
|
|
23600
|
+
nonModelFailures: 0,
|
|
23601
|
+
medianDurationMs: 68902
|
|
23602
|
+
},
|
|
23603
|
+
{
|
|
23604
|
+
scenarioId: "conflict-synthesis",
|
|
23605
|
+
trials: 3,
|
|
23606
|
+
successes: 1,
|
|
23607
|
+
nonModelFailures: 0,
|
|
23608
|
+
medianDurationMs: 254006
|
|
23609
|
+
}
|
|
23610
|
+
]
|
|
23611
|
+
},
|
|
23612
|
+
{
|
|
23613
|
+
modelId: "qwen3.6-35b-a3b-q4",
|
|
23614
|
+
label: "qwen3.6-35b-a3b-q4",
|
|
23615
|
+
engine: "llama-cpp",
|
|
23616
|
+
tier: "medium",
|
|
23617
|
+
parameterSize: "35B",
|
|
23618
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23619
|
+
suiteId: "core",
|
|
23620
|
+
performance: {
|
|
23621
|
+
prefillTokensPerSec: 1104,
|
|
23622
|
+
decodeTokensPerSec: 71.3,
|
|
23623
|
+
samples: 1
|
|
23624
|
+
},
|
|
23625
|
+
runtime: {
|
|
23626
|
+
contextTokens: 262144,
|
|
23627
|
+
peakMemoryMb: 26502
|
|
23628
|
+
},
|
|
23629
|
+
judge: {
|
|
23630
|
+
meanScore: 8.1,
|
|
23631
|
+
artifacts: 9,
|
|
23632
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23633
|
+
},
|
|
23634
|
+
cells: [
|
|
23635
|
+
{
|
|
23636
|
+
scenarioId: "tictactoe",
|
|
23637
|
+
trials: 3,
|
|
23638
|
+
successes: 3,
|
|
23639
|
+
nonModelFailures: 0,
|
|
23640
|
+
medianDurationMs: 92213
|
|
23641
|
+
},
|
|
23642
|
+
{
|
|
23643
|
+
scenarioId: "petshop",
|
|
23644
|
+
trials: 3,
|
|
23645
|
+
successes: 3,
|
|
23646
|
+
nonModelFailures: 0,
|
|
23647
|
+
medianDurationMs: 162363
|
|
23648
|
+
},
|
|
23649
|
+
{
|
|
23650
|
+
scenarioId: "tankcombat",
|
|
23651
|
+
trials: 3,
|
|
23652
|
+
successes: 3,
|
|
23653
|
+
nonModelFailures: 0,
|
|
23654
|
+
medianDurationMs: 247709
|
|
23655
|
+
},
|
|
23656
|
+
{
|
|
23657
|
+
scenarioId: "schema-migration",
|
|
23658
|
+
trials: 3,
|
|
23659
|
+
successes: 2,
|
|
23660
|
+
nonModelFailures: 0,
|
|
23661
|
+
medianDurationMs: 186639
|
|
23662
|
+
},
|
|
23663
|
+
{
|
|
23664
|
+
scenarioId: "failing-tests-spec",
|
|
23665
|
+
trials: 3,
|
|
23666
|
+
successes: 3,
|
|
23667
|
+
nonModelFailures: 0,
|
|
23668
|
+
medianDurationMs: 28425
|
|
23669
|
+
},
|
|
23670
|
+
{
|
|
23671
|
+
scenarioId: "symptom-debug",
|
|
23672
|
+
trials: 3,
|
|
23673
|
+
successes: 3,
|
|
23674
|
+
nonModelFailures: 0,
|
|
23675
|
+
medianDurationMs: 37627
|
|
23676
|
+
},
|
|
23677
|
+
{
|
|
23678
|
+
scenarioId: "data-wrangle",
|
|
23679
|
+
trials: 3,
|
|
23680
|
+
successes: 2,
|
|
23681
|
+
nonModelFailures: 0,
|
|
23682
|
+
medianDurationMs: 47569
|
|
23683
|
+
},
|
|
23684
|
+
{
|
|
23685
|
+
scenarioId: "incident-postmortem",
|
|
23686
|
+
trials: 3,
|
|
23687
|
+
successes: 3,
|
|
23688
|
+
nonModelFailures: 0,
|
|
23689
|
+
medianDurationMs: 73048
|
|
23690
|
+
},
|
|
23691
|
+
{
|
|
23692
|
+
scenarioId: "ops-runbook-anomaly",
|
|
23693
|
+
trials: 3,
|
|
23694
|
+
successes: 3,
|
|
23695
|
+
nonModelFailures: 0,
|
|
23696
|
+
medianDurationMs: 98132
|
|
23697
|
+
},
|
|
23698
|
+
{
|
|
23699
|
+
scenarioId: "plan-and-estimate",
|
|
23700
|
+
trials: 3,
|
|
23701
|
+
successes: 3,
|
|
23702
|
+
nonModelFailures: 0,
|
|
23703
|
+
medianDurationMs: 27443
|
|
23704
|
+
},
|
|
23705
|
+
{
|
|
23706
|
+
scenarioId: "conflict-synthesis",
|
|
23707
|
+
trials: 3,
|
|
23708
|
+
successes: 2,
|
|
23709
|
+
nonModelFailures: 0,
|
|
23710
|
+
medianDurationMs: 82923
|
|
23711
|
+
}
|
|
23712
|
+
]
|
|
23713
|
+
},
|
|
23714
|
+
{
|
|
23715
|
+
modelId: "gemma4-26b-q4",
|
|
23716
|
+
label: "gemma4-26b-q4",
|
|
23717
|
+
engine: "llama-cpp",
|
|
23718
|
+
tier: "medium",
|
|
23719
|
+
parameterSize: "25.2B",
|
|
23720
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23721
|
+
suiteId: "productivity",
|
|
23722
|
+
performance: {
|
|
23723
|
+
prefillTokensPerSec: 1264,
|
|
23724
|
+
decodeTokensPerSec: 107.5,
|
|
23725
|
+
samples: 1
|
|
23726
|
+
},
|
|
23727
|
+
runtime: {
|
|
23728
|
+
contextTokens: 120832,
|
|
23729
|
+
peakMemoryMb: 41762
|
|
23730
|
+
},
|
|
23731
|
+
judge: {
|
|
23732
|
+
meanScore: 6,
|
|
23733
|
+
artifacts: 19,
|
|
23734
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23735
|
+
},
|
|
23736
|
+
cells: [
|
|
23737
|
+
{
|
|
23738
|
+
scenarioId: "constrained-comms",
|
|
23739
|
+
trials: 3,
|
|
23740
|
+
successes: 3,
|
|
23741
|
+
nonModelFailures: 0,
|
|
23742
|
+
medianDurationMs: 22693
|
|
23743
|
+
},
|
|
23744
|
+
{
|
|
23745
|
+
scenarioId: "craftbook-week-plan",
|
|
23746
|
+
trials: 3,
|
|
23747
|
+
successes: 3,
|
|
23748
|
+
nonModelFailures: 0,
|
|
23749
|
+
medianDurationMs: 58001
|
|
23750
|
+
},
|
|
23751
|
+
{
|
|
23752
|
+
scenarioId: "craftbook-ab-test-readout",
|
|
23753
|
+
trials: 3,
|
|
23754
|
+
successes: 0,
|
|
23755
|
+
nonModelFailures: 0,
|
|
23756
|
+
medianDurationMs: 196546
|
|
23757
|
+
},
|
|
23758
|
+
{
|
|
23759
|
+
scenarioId: "craftbook-annotated-bibliography",
|
|
23760
|
+
trials: 3,
|
|
23761
|
+
successes: 3,
|
|
23762
|
+
nonModelFailures: 0,
|
|
23763
|
+
medianDurationMs: 33179
|
|
23764
|
+
},
|
|
23765
|
+
{
|
|
23766
|
+
scenarioId: "records-intake",
|
|
23767
|
+
trials: 3,
|
|
23768
|
+
successes: 3,
|
|
23769
|
+
nonModelFailures: 0,
|
|
23770
|
+
medianDurationMs: 58377
|
|
23771
|
+
},
|
|
23772
|
+
{
|
|
23773
|
+
scenarioId: "plan-and-estimate",
|
|
23774
|
+
trials: 3,
|
|
23775
|
+
successes: 3,
|
|
23776
|
+
nonModelFailures: 0,
|
|
23777
|
+
medianDurationMs: 17469
|
|
23778
|
+
},
|
|
23779
|
+
{
|
|
23780
|
+
scenarioId: "meeting-followup",
|
|
23781
|
+
trials: 3,
|
|
23782
|
+
successes: 3,
|
|
23783
|
+
nonModelFailures: 0,
|
|
23784
|
+
medianDurationMs: 48022
|
|
23785
|
+
},
|
|
23786
|
+
{
|
|
23787
|
+
scenarioId: "craftbook-spreadsheet-model",
|
|
23788
|
+
trials: 3,
|
|
23789
|
+
successes: 0,
|
|
23790
|
+
nonModelFailures: 0,
|
|
23791
|
+
medianDurationMs: 191950
|
|
23792
|
+
},
|
|
23793
|
+
{
|
|
23794
|
+
scenarioId: "conflict-synthesis",
|
|
23795
|
+
trials: 3,
|
|
23796
|
+
successes: 3,
|
|
23797
|
+
nonModelFailures: 0,
|
|
23798
|
+
medianDurationMs: 48088
|
|
23799
|
+
},
|
|
23800
|
+
{
|
|
23801
|
+
scenarioId: "docblocks-theme-roundtrip",
|
|
23802
|
+
trials: 3,
|
|
23803
|
+
successes: 3,
|
|
23804
|
+
nonModelFailures: 0,
|
|
23805
|
+
medianDurationMs: 27505
|
|
23806
|
+
},
|
|
23807
|
+
{
|
|
23808
|
+
scenarioId: "craftbook-research-to-document",
|
|
23809
|
+
trials: 3,
|
|
23810
|
+
successes: 3,
|
|
23811
|
+
nonModelFailures: 0,
|
|
23812
|
+
medianDurationMs: 32944
|
|
23813
|
+
},
|
|
23814
|
+
{
|
|
23815
|
+
scenarioId: "craftbook-powerpoint-deck",
|
|
23816
|
+
trials: 3,
|
|
23817
|
+
successes: 0,
|
|
23818
|
+
nonModelFailures: 0,
|
|
23819
|
+
medianDurationMs: 937028
|
|
23820
|
+
},
|
|
23821
|
+
{
|
|
23822
|
+
scenarioId: "wikipedia-research-brief",
|
|
23823
|
+
trials: 3,
|
|
23824
|
+
successes: 1,
|
|
23825
|
+
nonModelFailures: 0,
|
|
23826
|
+
medianDurationMs: 81272
|
|
23827
|
+
}
|
|
23828
|
+
]
|
|
23829
|
+
},
|
|
23830
|
+
{
|
|
23831
|
+
modelId: "muse-glimmer-30b-q4",
|
|
23832
|
+
label: "muse-glimmer-30b-q4",
|
|
23833
|
+
engine: "llama-cpp",
|
|
23834
|
+
tier: "medium",
|
|
23835
|
+
parameterSize: "30B",
|
|
23836
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23837
|
+
suiteId: "productivity",
|
|
23838
|
+
performance: {
|
|
23839
|
+
prefillTokensPerSec: 228,
|
|
23840
|
+
decodeTokensPerSec: 26,
|
|
23841
|
+
samples: 2
|
|
23842
|
+
},
|
|
23843
|
+
runtime: {
|
|
23844
|
+
contextTokens: 131072,
|
|
23845
|
+
peakMemoryMb: 19648
|
|
23846
|
+
},
|
|
23847
|
+
judge: {
|
|
23848
|
+
meanScore: 5.5,
|
|
23849
|
+
artifacts: 25,
|
|
23850
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23851
|
+
},
|
|
23852
|
+
cells: [
|
|
23853
|
+
{
|
|
23854
|
+
scenarioId: "constrained-comms",
|
|
23855
|
+
trials: 3,
|
|
23856
|
+
successes: 3,
|
|
23857
|
+
nonModelFailures: 0,
|
|
23858
|
+
medianDurationMs: 168777
|
|
23859
|
+
},
|
|
23860
|
+
{
|
|
23861
|
+
scenarioId: "craftbook-week-plan",
|
|
23862
|
+
trials: 3,
|
|
23863
|
+
successes: 0,
|
|
23864
|
+
nonModelFailures: 0,
|
|
23865
|
+
medianDurationMs: 635096
|
|
23866
|
+
},
|
|
23867
|
+
{
|
|
23868
|
+
scenarioId: "craftbook-ab-test-readout",
|
|
23869
|
+
trials: 3,
|
|
23870
|
+
successes: 1,
|
|
23871
|
+
nonModelFailures: 0,
|
|
23872
|
+
medianDurationMs: 505316
|
|
23873
|
+
},
|
|
23874
|
+
{
|
|
23875
|
+
scenarioId: "craftbook-annotated-bibliography",
|
|
23876
|
+
trials: 3,
|
|
23877
|
+
successes: 3,
|
|
23878
|
+
nonModelFailures: 0,
|
|
23879
|
+
medianDurationMs: 153322
|
|
23880
|
+
},
|
|
23881
|
+
{
|
|
23882
|
+
scenarioId: "records-intake",
|
|
23883
|
+
trials: 3,
|
|
23884
|
+
successes: 2,
|
|
23885
|
+
nonModelFailures: 0,
|
|
23886
|
+
medianDurationMs: 2593201
|
|
23887
|
+
},
|
|
23888
|
+
{
|
|
23889
|
+
scenarioId: "plan-and-estimate",
|
|
23890
|
+
trials: 3,
|
|
23891
|
+
successes: 3,
|
|
23892
|
+
nonModelFailures: 0,
|
|
23893
|
+
medianDurationMs: 185158
|
|
23894
|
+
},
|
|
23895
|
+
{
|
|
23896
|
+
scenarioId: "meeting-followup",
|
|
23897
|
+
trials: 3,
|
|
23898
|
+
successes: 2,
|
|
23899
|
+
nonModelFailures: 0,
|
|
23900
|
+
medianDurationMs: 680419
|
|
23901
|
+
},
|
|
23902
|
+
{
|
|
23903
|
+
scenarioId: "craftbook-spreadsheet-model",
|
|
23904
|
+
trials: 3,
|
|
23905
|
+
successes: 0,
|
|
23906
|
+
nonModelFailures: 0,
|
|
23907
|
+
medianDurationMs: 541672
|
|
23908
|
+
},
|
|
23909
|
+
{
|
|
23910
|
+
scenarioId: "conflict-synthesis",
|
|
23911
|
+
trials: 3,
|
|
23912
|
+
successes: 2,
|
|
23913
|
+
nonModelFailures: 0,
|
|
23914
|
+
medianDurationMs: 344063
|
|
23915
|
+
},
|
|
23916
|
+
{
|
|
23917
|
+
scenarioId: "docblocks-theme-roundtrip",
|
|
23918
|
+
trials: 3,
|
|
23919
|
+
successes: 3,
|
|
23920
|
+
nonModelFailures: 0,
|
|
23921
|
+
medianDurationMs: 248997
|
|
23922
|
+
},
|
|
23923
|
+
{
|
|
23924
|
+
scenarioId: "craftbook-research-to-document",
|
|
23925
|
+
trials: 3,
|
|
23926
|
+
successes: 3,
|
|
23927
|
+
nonModelFailures: 0,
|
|
23928
|
+
medianDurationMs: 274010
|
|
23929
|
+
},
|
|
23930
|
+
{
|
|
23931
|
+
scenarioId: "craftbook-powerpoint-deck",
|
|
23932
|
+
trials: 3,
|
|
23933
|
+
successes: 0,
|
|
23934
|
+
nonModelFailures: 0,
|
|
23935
|
+
medianDurationMs: 3009529
|
|
23936
|
+
},
|
|
23937
|
+
{
|
|
23938
|
+
scenarioId: "wikipedia-research-brief",
|
|
23939
|
+
trials: 3,
|
|
23940
|
+
successes: 3,
|
|
23941
|
+
nonModelFailures: 0,
|
|
23942
|
+
medianDurationMs: 353289
|
|
23943
|
+
}
|
|
23944
|
+
]
|
|
23945
|
+
},
|
|
23946
|
+
{
|
|
23947
|
+
modelId: "nemotron3.5-lightning-30b-q4",
|
|
23948
|
+
label: "nemotron3.5-lightning-30b-q4",
|
|
23949
|
+
engine: "llama-cpp",
|
|
23950
|
+
tier: "medium",
|
|
23951
|
+
parameterSize: "30B",
|
|
23952
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
23953
|
+
suiteId: "productivity",
|
|
23954
|
+
performance: {
|
|
23955
|
+
prefillTokensPerSec: 1030,
|
|
23956
|
+
decodeTokensPerSec: 93.2,
|
|
23957
|
+
samples: 1
|
|
23958
|
+
},
|
|
23959
|
+
runtime: {
|
|
23960
|
+
contextTokens: 1048576,
|
|
23961
|
+
peakMemoryMb: 29452
|
|
23962
|
+
},
|
|
23963
|
+
judge: {
|
|
23964
|
+
meanScore: 5.6,
|
|
23965
|
+
artifacts: 27,
|
|
23966
|
+
judgeModel: "claude-sonnet-4-6"
|
|
23967
|
+
},
|
|
23968
|
+
cells: [
|
|
23969
|
+
{
|
|
23970
|
+
scenarioId: "constrained-comms",
|
|
23971
|
+
trials: 3,
|
|
23972
|
+
successes: 0,
|
|
23973
|
+
nonModelFailures: 0,
|
|
23974
|
+
medianDurationMs: 91133
|
|
22995
23975
|
},
|
|
22996
|
-
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23976
|
+
{
|
|
23977
|
+
scenarioId: "craftbook-week-plan",
|
|
23978
|
+
trials: 3,
|
|
23979
|
+
successes: 3,
|
|
23980
|
+
nonModelFailures: 0,
|
|
23981
|
+
medianDurationMs: 113088
|
|
23982
|
+
},
|
|
23983
|
+
{
|
|
23984
|
+
scenarioId: "craftbook-ab-test-readout",
|
|
23985
|
+
trials: 3,
|
|
23986
|
+
successes: 3,
|
|
23987
|
+
nonModelFailures: 0,
|
|
23988
|
+
medianDurationMs: 283896
|
|
23989
|
+
},
|
|
23990
|
+
{
|
|
23991
|
+
scenarioId: "craftbook-annotated-bibliography",
|
|
23992
|
+
trials: 3,
|
|
23993
|
+
successes: 3,
|
|
23994
|
+
nonModelFailures: 0,
|
|
23995
|
+
medianDurationMs: 73049
|
|
23996
|
+
},
|
|
23997
|
+
{
|
|
23998
|
+
scenarioId: "records-intake",
|
|
23999
|
+
trials: 3,
|
|
24000
|
+
successes: 1,
|
|
24001
|
+
nonModelFailures: 0,
|
|
24002
|
+
medianDurationMs: 395444
|
|
24003
|
+
},
|
|
24004
|
+
{
|
|
24005
|
+
scenarioId: "plan-and-estimate",
|
|
24006
|
+
trials: 3,
|
|
24007
|
+
successes: 1,
|
|
24008
|
+
nonModelFailures: 0,
|
|
24009
|
+
medianDurationMs: 105986
|
|
24010
|
+
},
|
|
24011
|
+
{
|
|
24012
|
+
scenarioId: "meeting-followup",
|
|
24013
|
+
trials: 3,
|
|
24014
|
+
successes: 3,
|
|
24015
|
+
nonModelFailures: 0,
|
|
24016
|
+
medianDurationMs: 113144
|
|
24017
|
+
},
|
|
24018
|
+
{
|
|
24019
|
+
scenarioId: "craftbook-spreadsheet-model",
|
|
24020
|
+
trials: 3,
|
|
24021
|
+
successes: 3,
|
|
24022
|
+
nonModelFailures: 0,
|
|
24023
|
+
medianDurationMs: 233654
|
|
24024
|
+
},
|
|
24025
|
+
{
|
|
24026
|
+
scenarioId: "conflict-synthesis",
|
|
24027
|
+
trials: 3,
|
|
24028
|
+
successes: 1,
|
|
24029
|
+
nonModelFailures: 0,
|
|
24030
|
+
medianDurationMs: 469600
|
|
24031
|
+
},
|
|
24032
|
+
{
|
|
24033
|
+
scenarioId: "docblocks-theme-roundtrip",
|
|
24034
|
+
trials: 3,
|
|
24035
|
+
successes: 1,
|
|
24036
|
+
nonModelFailures: 0,
|
|
24037
|
+
medianDurationMs: 109277
|
|
24038
|
+
},
|
|
24039
|
+
{
|
|
24040
|
+
scenarioId: "craftbook-research-to-document",
|
|
24041
|
+
trials: 3,
|
|
24042
|
+
successes: 3,
|
|
24043
|
+
nonModelFailures: 0,
|
|
24044
|
+
medianDurationMs: 130992
|
|
24045
|
+
},
|
|
24046
|
+
{
|
|
24047
|
+
scenarioId: "craftbook-powerpoint-deck",
|
|
24048
|
+
trials: 3,
|
|
24049
|
+
successes: 0,
|
|
24050
|
+
nonModelFailures: 0,
|
|
24051
|
+
medianDurationMs: 791082
|
|
24052
|
+
},
|
|
24053
|
+
{
|
|
24054
|
+
scenarioId: "wikipedia-research-brief",
|
|
24055
|
+
trials: 3,
|
|
24056
|
+
successes: 1,
|
|
24057
|
+
nonModelFailures: 0,
|
|
24058
|
+
medianDurationMs: 136065
|
|
24059
|
+
}
|
|
24060
|
+
]
|
|
24061
|
+
},
|
|
24062
|
+
{
|
|
24063
|
+
modelId: "qwen3.6-35b-a3b-q4",
|
|
24064
|
+
label: "qwen3.6-35b-a3b-q4",
|
|
24065
|
+
engine: "llama-cpp",
|
|
24066
|
+
tier: "medium",
|
|
24067
|
+
parameterSize: "35B",
|
|
24068
|
+
runId: "2026-08-13-m4max-llamacpp",
|
|
24069
|
+
suiteId: "productivity",
|
|
24070
|
+
performance: {
|
|
24071
|
+
prefillTokensPerSec: 1104,
|
|
24072
|
+
decodeTokensPerSec: 71.3,
|
|
24073
|
+
samples: 1
|
|
23000
24074
|
},
|
|
23001
|
-
|
|
23002
|
-
|
|
23003
|
-
|
|
23004
|
-
"tictactoe",
|
|
23005
|
-
"petshop",
|
|
23006
|
-
"tankcombat",
|
|
23007
|
-
"schema-migration",
|
|
23008
|
-
"failing-tests-spec",
|
|
23009
|
-
"symptom-debug",
|
|
23010
|
-
"data-wrangle",
|
|
23011
|
-
"incident-postmortem",
|
|
23012
|
-
"ops-runbook-anomaly",
|
|
23013
|
-
"plan-and-estimate",
|
|
23014
|
-
"conflict-synthesis"
|
|
23015
|
-
],
|
|
23016
|
-
productivity: [
|
|
23017
|
-
"constrained-comms",
|
|
23018
|
-
"craftbook-week-plan",
|
|
23019
|
-
"craftbook-ab-test-readout",
|
|
23020
|
-
"craftbook-annotated-bibliography",
|
|
23021
|
-
"records-intake",
|
|
23022
|
-
"plan-and-estimate",
|
|
23023
|
-
"meeting-followup",
|
|
23024
|
-
"craftbook-spreadsheet-model",
|
|
23025
|
-
"conflict-synthesis",
|
|
23026
|
-
"docblocks-theme-roundtrip",
|
|
23027
|
-
"craftbook-research-to-document",
|
|
23028
|
-
"craftbook-powerpoint-deck",
|
|
23029
|
-
"wikipedia-research-brief"
|
|
23030
|
-
]
|
|
24075
|
+
runtime: {
|
|
24076
|
+
contextTokens: 262144,
|
|
24077
|
+
peakMemoryMb: 25657
|
|
23031
24078
|
},
|
|
23032
|
-
|
|
23033
|
-
|
|
23034
|
-
|
|
23035
|
-
|
|
24079
|
+
judge: {
|
|
24080
|
+
meanScore: 6.6,
|
|
24081
|
+
artifacts: 27,
|
|
24082
|
+
judgeModel: "claude-sonnet-4-6"
|
|
24083
|
+
},
|
|
24084
|
+
cells: [
|
|
24085
|
+
{
|
|
24086
|
+
scenarioId: "constrained-comms",
|
|
24087
|
+
trials: 3,
|
|
24088
|
+
successes: 3,
|
|
24089
|
+
nonModelFailures: 0,
|
|
24090
|
+
medianDurationMs: 22314
|
|
24091
|
+
},
|
|
24092
|
+
{
|
|
24093
|
+
scenarioId: "craftbook-week-plan",
|
|
24094
|
+
trials: 3,
|
|
24095
|
+
successes: 3,
|
|
24096
|
+
nonModelFailures: 0,
|
|
24097
|
+
medianDurationMs: 88382
|
|
24098
|
+
},
|
|
24099
|
+
{
|
|
24100
|
+
scenarioId: "craftbook-ab-test-readout",
|
|
24101
|
+
trials: 3,
|
|
24102
|
+
successes: 3,
|
|
24103
|
+
nonModelFailures: 0,
|
|
24104
|
+
medianDurationMs: 303967
|
|
24105
|
+
},
|
|
24106
|
+
{
|
|
24107
|
+
scenarioId: "craftbook-annotated-bibliography",
|
|
24108
|
+
trials: 3,
|
|
24109
|
+
successes: 3,
|
|
24110
|
+
nonModelFailures: 0,
|
|
24111
|
+
medianDurationMs: 47530
|
|
24112
|
+
},
|
|
24113
|
+
{
|
|
24114
|
+
scenarioId: "records-intake",
|
|
24115
|
+
trials: 3,
|
|
24116
|
+
successes: 3,
|
|
24117
|
+
nonModelFailures: 0,
|
|
24118
|
+
medianDurationMs: 22365
|
|
24119
|
+
},
|
|
24120
|
+
{
|
|
24121
|
+
scenarioId: "plan-and-estimate",
|
|
24122
|
+
trials: 3,
|
|
24123
|
+
successes: 3,
|
|
24124
|
+
nonModelFailures: 0,
|
|
24125
|
+
medianDurationMs: 32491
|
|
24126
|
+
},
|
|
24127
|
+
{
|
|
24128
|
+
scenarioId: "meeting-followup",
|
|
24129
|
+
trials: 3,
|
|
24130
|
+
successes: 3,
|
|
24131
|
+
nonModelFailures: 0,
|
|
24132
|
+
medianDurationMs: 89751
|
|
24133
|
+
},
|
|
24134
|
+
{
|
|
24135
|
+
scenarioId: "craftbook-spreadsheet-model",
|
|
24136
|
+
trials: 3,
|
|
24137
|
+
successes: 3,
|
|
24138
|
+
nonModelFailures: 0,
|
|
24139
|
+
medianDurationMs: 228470
|
|
24140
|
+
},
|
|
24141
|
+
{
|
|
24142
|
+
scenarioId: "conflict-synthesis",
|
|
24143
|
+
trials: 3,
|
|
24144
|
+
successes: 1,
|
|
24145
|
+
nonModelFailures: 0,
|
|
24146
|
+
medianDurationMs: 211329
|
|
24147
|
+
},
|
|
24148
|
+
{
|
|
24149
|
+
scenarioId: "docblocks-theme-roundtrip",
|
|
24150
|
+
trials: 3,
|
|
24151
|
+
successes: 3,
|
|
24152
|
+
nonModelFailures: 0,
|
|
24153
|
+
medianDurationMs: 17446
|
|
24154
|
+
},
|
|
24155
|
+
{
|
|
24156
|
+
scenarioId: "craftbook-research-to-document",
|
|
24157
|
+
trials: 3,
|
|
24158
|
+
successes: 3,
|
|
24159
|
+
nonModelFailures: 0,
|
|
24160
|
+
medianDurationMs: 22407
|
|
24161
|
+
},
|
|
24162
|
+
{
|
|
24163
|
+
scenarioId: "craftbook-powerpoint-deck",
|
|
24164
|
+
trials: 3,
|
|
24165
|
+
successes: 1,
|
|
24166
|
+
nonModelFailures: 0,
|
|
24167
|
+
medianDurationMs: 1493404
|
|
24168
|
+
},
|
|
24169
|
+
{
|
|
24170
|
+
scenarioId: "wikipedia-research-brief",
|
|
24171
|
+
trials: 3,
|
|
24172
|
+
successes: 1,
|
|
24173
|
+
nonModelFailures: 0,
|
|
24174
|
+
medianDurationMs: 125222
|
|
24175
|
+
}
|
|
24176
|
+
]
|
|
24177
|
+
},
|
|
23036
24178
|
{
|
|
23037
24179
|
modelId: "gemma4-26b-q4",
|
|
23038
24180
|
label: "gemma4-26b-q4",
|
|
@@ -25379,6 +26521,11 @@ function collapseCraftbookForTier(book, opts) {
|
|
|
25379
26521
|
0,
|
|
25380
26522
|
...members.map((m) => m.gate ? normalizeStepGate(m.gate).maxAttempts ?? 0 : 0)
|
|
25381
26523
|
);
|
|
26524
|
+
const consumes = members.flatMap((member) => member.consumes ?? []).filter(
|
|
26525
|
+
(input, index, all) => all.findIndex(
|
|
26526
|
+
(candidate) => candidate.file === input.file && Boolean(candidate.artifact) === Boolean(input.artifact)
|
|
26527
|
+
) === index
|
|
26528
|
+
);
|
|
25382
26529
|
const isLast = groupIdx === groups.length - 1;
|
|
25383
26530
|
const nextGroupAnchor = groups[groupIdx + 1];
|
|
25384
26531
|
const nextId = nextGroupAnchor ? nextGroupAnchor.filter((m) => hasCompletionGate(m)).slice(-1)[0] ?? nextGroupAnchor[nextGroupAnchor.length - 1] : void 0;
|
|
@@ -25394,6 +26541,7 @@ function collapseCraftbookForTier(book, opts) {
|
|
|
25394
26541
|
const step = {
|
|
25395
26542
|
...anchor,
|
|
25396
26543
|
prompt: collapsedPrompt({ anchor, mergedNames, checks }),
|
|
26544
|
+
...consumes.length > 0 ? { consumes } : { consumes: void 0 },
|
|
25397
26545
|
gate,
|
|
25398
26546
|
// Terminal + advanceWhen is an illegal combination; the terminal
|
|
25399
26547
|
// group keeps only its completion gate.
|
|
@@ -25403,7 +26551,7 @@ function collapseCraftbookForTier(book, opts) {
|
|
|
25403
26551
|
advanceWhen: anchor.advanceWhen ? { ...anchor.advanceWhen, goto: void 0 } : void 0
|
|
25404
26552
|
}
|
|
25405
26553
|
};
|
|
25406
|
-
for (const key of ["terminal", "advanceWhen", "next"]) {
|
|
26554
|
+
for (const key of ["terminal", "advanceWhen", "next", "consumes"]) {
|
|
25407
26555
|
if (step[key] === void 0) delete step[key];
|
|
25408
26556
|
}
|
|
25409
26557
|
if (step.advanceWhen && step.advanceWhen.goto === void 0) {
|
|
@@ -25542,6 +26690,16 @@ function docFromCraftbook(book) {
|
|
|
25542
26690
|
};
|
|
25543
26691
|
}
|
|
25544
26692
|
function augmentGraphProblem(problem, stepIds) {
|
|
26693
|
+
const artifactInput = /^step "([^"]+)" consumes artifact "([^"]+)" but its prompt does not explicitly call `read_artifact`$/.exec(
|
|
26694
|
+
problem
|
|
26695
|
+
);
|
|
26696
|
+
if (artifactInput) {
|
|
26697
|
+
return {
|
|
26698
|
+
where: `steps (id "${artifactInput[1]}") \u2192 prompt`,
|
|
26699
|
+
message: `${problem}.`,
|
|
26700
|
+
fix: `start the procedure with \`read_artifact({ path: ${JSON.stringify(artifactInput[2])} })\`; artifact paths are not workspace paths`
|
|
26701
|
+
};
|
|
26702
|
+
}
|
|
25545
26703
|
const missing = /"([^"]+)" missing from steps/.exec(problem);
|
|
25546
26704
|
if (missing) {
|
|
25547
26705
|
const near = nearestMatch(missing[1], stepIds);
|
|
@@ -26861,9 +28019,38 @@ function deriveThreadTitleFromMessages(messages, options = {}) {
|
|
|
26861
28019
|
return starter ? deriveThreadTitle(starter.content) : null;
|
|
26862
28020
|
}
|
|
26863
28021
|
|
|
28022
|
+
// src/catalog-work-in-progress.ts
|
|
28023
|
+
var CONNECTOR_PROJECT_TYPE_BASES = /* @__PURE__ */ new Set(["email", "social-media"]);
|
|
28024
|
+
function resolveShowWorkInProgressFeatures(configured, buildVersion) {
|
|
28025
|
+
return configured ?? buildVersion === "0.0.0";
|
|
28026
|
+
}
|
|
28027
|
+
function catalogItemUsesConnectors(item, connectorCraftbookIds2 = /* @__PURE__ */ new Set()) {
|
|
28028
|
+
const manifest = item.manifest;
|
|
28029
|
+
if (manifest.kind === "craftbook-template") {
|
|
28030
|
+
return (manifest.connectors?.length ?? 0) > 0;
|
|
28031
|
+
}
|
|
28032
|
+
if (manifest.kind !== "project-type") return false;
|
|
28033
|
+
if (manifest.extends && CONNECTOR_PROJECT_TYPE_BASES.has(manifest.extends)) return true;
|
|
28034
|
+
if ((manifest.craftbooks ?? []).some((id) => connectorCraftbookIds2.has(id))) return true;
|
|
28035
|
+
return (manifest.schedules ?? []).some(
|
|
28036
|
+
(schedule) => connectorCraftbookIds2.has(schedule.craftbook)
|
|
28037
|
+
);
|
|
28038
|
+
}
|
|
28039
|
+
function connectorCraftbookIds(items) {
|
|
28040
|
+
return new Set(
|
|
28041
|
+
items.flatMap(
|
|
28042
|
+
(item) => item.manifest.kind === "craftbook-template" && catalogItemUsesConnectors(item) ? [item.manifest.id] : []
|
|
28043
|
+
)
|
|
28044
|
+
);
|
|
28045
|
+
}
|
|
28046
|
+
function visibleCatalogItems(items, showWorkInProgressFeatures, connectorIds = connectorCraftbookIds(items)) {
|
|
28047
|
+
if (showWorkInProgressFeatures) return [...items];
|
|
28048
|
+
return items.filter((item) => !catalogItemUsesConnectors(item, connectorIds));
|
|
28049
|
+
}
|
|
28050
|
+
|
|
26864
28051
|
// src/index.ts
|
|
26865
|
-
var GEZEL_VERSION = "1.0.
|
|
26866
|
-
var GEZEL_CONTENT_COMPAT = "1.
|
|
28052
|
+
var GEZEL_VERSION = "1.0.4";
|
|
28053
|
+
var GEZEL_CONTENT_COMPAT = "1.26226";
|
|
26867
28054
|
function nowIso() {
|
|
26868
28055
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
26869
28056
|
}
|
|
@@ -26990,6 +28177,7 @@ export {
|
|
|
26990
28177
|
CraftbookSchema,
|
|
26991
28178
|
CraftbookScriptsSchema,
|
|
26992
28179
|
CraftbookSpawnSchema,
|
|
28180
|
+
CraftbookStepInputSchema,
|
|
26993
28181
|
CraftbookStepSchema,
|
|
26994
28182
|
CraftbookSuggestionSchema,
|
|
26995
28183
|
CraftbookSummarySchema,
|
|
@@ -27895,6 +29083,7 @@ export {
|
|
|
27895
29083
|
blockSize,
|
|
27896
29084
|
buildIssueUrl,
|
|
27897
29085
|
buildSuiteScoreboard,
|
|
29086
|
+
catalogItemUsesConnectors,
|
|
27898
29087
|
cellAttributableTrials,
|
|
27899
29088
|
classifySecurityLevel,
|
|
27900
29089
|
coerceDeliverableKind,
|
|
@@ -27906,6 +29095,7 @@ export {
|
|
|
27906
29095
|
composeFileContext,
|
|
27907
29096
|
composeFitnessBadge,
|
|
27908
29097
|
computeModelFit,
|
|
29098
|
+
connectorCraftbookIds,
|
|
27909
29099
|
craftbookDocFormatFromEnv,
|
|
27910
29100
|
craftbookFromDoc,
|
|
27911
29101
|
craftbookRequirementsMet,
|
|
@@ -27948,6 +29138,7 @@ export {
|
|
|
27948
29138
|
formatCraftbookDocErrors,
|
|
27949
29139
|
formatErrorReport,
|
|
27950
29140
|
formatJsonSchemaViolations,
|
|
29141
|
+
formatModelAttribution,
|
|
27951
29142
|
formatNpmRegistrySpec,
|
|
27952
29143
|
formatPassClaim,
|
|
27953
29144
|
formatReviewProvenance,
|
|
@@ -28024,6 +29215,7 @@ export {
|
|
|
28024
29215
|
meetsCapabilityFloor,
|
|
28025
29216
|
mergeStreets,
|
|
28026
29217
|
metaToFormValue,
|
|
29218
|
+
modelAttribution,
|
|
28027
29219
|
modelFitnessKey,
|
|
28028
29220
|
nearestFreeRect,
|
|
28029
29221
|
nearestMatch,
|
|
@@ -28098,6 +29290,7 @@ export {
|
|
|
28098
29290
|
resolveRoleId,
|
|
28099
29291
|
resolveSandboxCopilot,
|
|
28100
29292
|
resolveSecurityPolicy,
|
|
29293
|
+
resolveShowWorkInProgressFeatures,
|
|
28101
29294
|
resolveSteps,
|
|
28102
29295
|
retryTransient,
|
|
28103
29296
|
rewriteGezelHrefs,
|
|
@@ -28154,6 +29347,7 @@ export {
|
|
|
28154
29347
|
validateScriptInput,
|
|
28155
29348
|
verifyBinaryDocumentBytes,
|
|
28156
29349
|
videoMemoryBudgetBytes,
|
|
29350
|
+
visibleCatalogItems,
|
|
28157
29351
|
workshopTempoDefaults,
|
|
28158
29352
|
writeProcessOutput,
|
|
28159
29353
|
xpForLevel,
|