@bendyline/gezel 1.0.6 → 1.0.7
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 +101 -2
- package/dist/checks/index.js +433 -21
- package/dist/{index-D82l7pAm.d.ts → index-BgRfJ_Pt.d.ts} +8488 -361
- package/dist/index.d.ts +766 -15
- package/dist/index.js +17919 -6003
- package/dist/markdown/index.d.ts +1 -1
- package/dist/markdown/index.js +1150 -866
- package/dist/native/index.d.ts +121 -11
- package/dist/native/index.js +80 -7
- package/dist/paths.d.ts +96 -4
- package/dist/paths.js +370 -0
- package/dist/{report-action-ClXIBtpU.d.ts → report-action-Kt6W23xy.d.ts} +813 -4
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +8959 -5804
- package/package.json +1 -1
package/dist/markdown/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/schemas/craftbook.ts
|
|
2
|
-
import { z as
|
|
2
|
+
import { z as z6 } from "zod";
|
|
3
3
|
|
|
4
4
|
// src/roles/tier.ts
|
|
5
5
|
var MODEL_TIER_ORDER = [
|
|
@@ -34,7 +34,9 @@ var NamedScriptCapabilitySchema = z2.enum([
|
|
|
34
34
|
"tasks.read",
|
|
35
35
|
"tasks.write",
|
|
36
36
|
"memory.read",
|
|
37
|
-
"memory.write"
|
|
37
|
+
"memory.write",
|
|
38
|
+
"index.read",
|
|
39
|
+
"index.refresh"
|
|
38
40
|
]);
|
|
39
41
|
var CredentialCapabilitySchema = z2.string().regex(
|
|
40
42
|
/^credential:[a-zA-Z][\w.:-]*$/,
|
|
@@ -601,6 +603,18 @@ var GateCheckSchema = z3.discriminatedUnion("kind", [
|
|
|
601
603
|
minRows: z3.number().int().nonnegative().optional(),
|
|
602
604
|
uniqueBy: z3.string().optional(),
|
|
603
605
|
format: z3.enum(["json", "csv", "auto"]).optional(),
|
|
606
|
+
/**
|
|
607
|
+
* Accept fields beyond `fields` (default false — an exact field set).
|
|
608
|
+
*
|
|
609
|
+
* Strict is right for a locked-schema data deliverable, where an
|
|
610
|
+
* unexpected key means the writer misunderstood the contract. It is
|
|
611
|
+
* wrong for a REGISTER — a findings list, a drift list — where extra
|
|
612
|
+
* context (a cwe, a title, an id) is a better deliverable, not a
|
|
613
|
+
* broken one, and rejecting it grades schema-guessing instead of the
|
|
614
|
+
* work. The underlying `recordSchema` check has always supported this;
|
|
615
|
+
* only the declarative gate could not say it.
|
|
616
|
+
*/
|
|
617
|
+
allowExtraFields: z3.boolean().optional(),
|
|
604
618
|
artifact: z3.boolean().optional()
|
|
605
619
|
}),
|
|
606
620
|
/**
|
|
@@ -646,12 +660,43 @@ var GateCheckSchema = z3.discriminatedUnion("kind", [
|
|
|
646
660
|
* `sourcePath` is non-empty, an exact successful `read_file` of that path
|
|
647
661
|
* qualifies; otherwise one of `tools` must have completed against an
|
|
648
662
|
* external source. The runtime supplies the live tool-call evidence.
|
|
663
|
+
* `externalOptional` softens only the no-sourcePath branch: authored local
|
|
664
|
+
* sources remain mandatory, while a topic-only workflow may recommend web
|
|
665
|
+
* research without becoming impossible under an offline security policy.
|
|
649
666
|
*/
|
|
650
667
|
z3.object({
|
|
651
668
|
kind: z3.literal("researchEvidence"),
|
|
652
669
|
sourcePath: z3.string().optional(),
|
|
653
670
|
tools: z3.array(z3.string().min(1)).min(1),
|
|
654
|
-
minSuccessful: z3.number().int().positive().optional()
|
|
671
|
+
minSuccessful: z3.number().int().positive().optional(),
|
|
672
|
+
externalOptional: z3.boolean().optional()
|
|
673
|
+
}),
|
|
674
|
+
/**
|
|
675
|
+
* Require a real command run during this activation, verified against the
|
|
676
|
+
* service-written run receipts (`workspace.script.run` / `workspace.npx.run`
|
|
677
|
+
* history events — the model cannot forge them, and the gate never
|
|
678
|
+
* executes anything itself). Exactly one of `script` (a package.json
|
|
679
|
+
* script name) or `bin` (an npx binary) names the command; `args` must
|
|
680
|
+
* match the receipt's extra args exactly (default: argless). `expect`
|
|
681
|
+
* judges the LATEST matching run's exit code — `'fail'` is the
|
|
682
|
+
* red-before-green half of a repro-first fix (the failing test must
|
|
683
|
+
* actually fail), `'pass'` is the suite-green proof after it. A timed-out
|
|
684
|
+
* run satisfies neither. On a drafting task the project's commands run
|
|
685
|
+
* against the unmodified tree, so `onDraft: 'defer'` (the default)
|
|
686
|
+
* approves with an explicit "execution deferred until Apply" note instead
|
|
687
|
+
* of demanding a receipt that would be a lie; `'require'` hard-blocks
|
|
688
|
+
* instead. Books standardize on the argless canonical invocation because
|
|
689
|
+
* command approvals pin one invocation hash per script name.
|
|
690
|
+
*/
|
|
691
|
+
z3.object({
|
|
692
|
+
kind: z3.literal("commandEvidence"),
|
|
693
|
+
script: z3.string().min(1).optional(),
|
|
694
|
+
bin: z3.string().min(1).optional(),
|
|
695
|
+
args: z3.array(z3.string()).optional(),
|
|
696
|
+
expect: z3.enum(["pass", "fail"]),
|
|
697
|
+
minRuns: z3.number().int().positive().optional(),
|
|
698
|
+
onDraft: z3.enum(["defer", "require"]).optional(),
|
|
699
|
+
label: z3.string().min(1).optional()
|
|
655
700
|
}),
|
|
656
701
|
/**
|
|
657
702
|
* A PR-review coverage ledger must name every changed path materialized in
|
|
@@ -943,16 +988,39 @@ var HookResultSchema = z4.object({
|
|
|
943
988
|
message: z4.string().optional()
|
|
944
989
|
});
|
|
945
990
|
|
|
991
|
+
// src/schemas/retrieval.ts
|
|
992
|
+
import { z as z5 } from "zod";
|
|
993
|
+
var RETRIEVAL_MODES = ["off", "lean", "balanced", "deep"];
|
|
994
|
+
var RetrievalModeSchema = z5.enum(RETRIEVAL_MODES);
|
|
995
|
+
var RETRIEVAL_SOURCES = [
|
|
996
|
+
"workspace",
|
|
997
|
+
"artifacts",
|
|
998
|
+
"project-memory",
|
|
999
|
+
"gezel-memory",
|
|
1000
|
+
"shared",
|
|
1001
|
+
// Installed knowledge catalogs (read-only reference corpora — .gezk).
|
|
1002
|
+
// Scoped by the user's registry + the project's knowledgeCatalogs policy.
|
|
1003
|
+
"knowledge"
|
|
1004
|
+
];
|
|
1005
|
+
var RetrievalSourceSchema = z5.enum(RETRIEVAL_SOURCES);
|
|
1006
|
+
var RetrievalPolicySchema = z5.object({
|
|
1007
|
+
mode: RetrievalModeSchema,
|
|
1008
|
+
/** Hard prompt budget after the mode preset and context-window clamp. */
|
|
1009
|
+
maxTokens: z5.number().int().min(0).max(16e3).optional(),
|
|
1010
|
+
/** Absent means every corpus appropriate to the current session. */
|
|
1011
|
+
sources: z5.array(RetrievalSourceSchema).min(1).optional()
|
|
1012
|
+
});
|
|
1013
|
+
|
|
946
1014
|
// src/schemas/craftbook.ts
|
|
947
|
-
var CraftbookBranchSchema =
|
|
1015
|
+
var CraftbookBranchSchema = z6.object({
|
|
948
1016
|
when: ScriptOutputPredicateSchema,
|
|
949
|
-
goto:
|
|
1017
|
+
goto: z6.string()
|
|
950
1018
|
});
|
|
951
|
-
var AdvanceWhenSchema =
|
|
1019
|
+
var AdvanceWhenSchema = z6.object({
|
|
952
1020
|
/** Workspace-relative deliverable whose presence signals "this step is done". */
|
|
953
|
-
file:
|
|
1021
|
+
file: z6.string().min(1),
|
|
954
1022
|
/** Liveness floor in bytes (guards against an empty/stub file). Default 1. */
|
|
955
|
-
minBytes:
|
|
1023
|
+
minBytes: z6.number().int().positive().optional(),
|
|
956
1024
|
/**
|
|
957
1025
|
* Named content check the runtime runs before advancing. `html-complete`
|
|
958
1026
|
* = a non-truncated HTML doc (balanced `<script>` tags + a closing
|
|
@@ -973,7 +1041,7 @@ var AdvanceWhenSchema = z5.object({
|
|
|
973
1041
|
* `insert_at_marker` targeting `file` this turn). The `sniff`/`minBytes`
|
|
974
1042
|
* floor still applies on top. Absent → legacy "exists is enough".
|
|
975
1043
|
*/
|
|
976
|
-
requireChange:
|
|
1044
|
+
requireChange: z6.boolean().optional(),
|
|
977
1045
|
/**
|
|
978
1046
|
* Resolve `file` against the project's ARTIFACTS drawer
|
|
979
1047
|
* (`read_artifact` / `write_artifact`) instead of the shipped workspace.
|
|
@@ -983,28 +1051,28 @@ var AdvanceWhenSchema = z5.object({
|
|
|
983
1051
|
* deliverable is gated for size/shape exactly like a workspace one.
|
|
984
1052
|
* Absent → workspace (the default).
|
|
985
1053
|
*/
|
|
986
|
-
artifact:
|
|
1054
|
+
artifact: z6.boolean().optional(),
|
|
987
1055
|
/** Step to activate on the signal. Defaults to `next`; must resolve like `next`. */
|
|
988
|
-
goto:
|
|
1056
|
+
goto: z6.string().optional()
|
|
989
1057
|
});
|
|
990
|
-
var CraftbookStepInputSchema =
|
|
1058
|
+
var CraftbookStepInputSchema = z6.object({
|
|
991
1059
|
/** Path relative to the selected drawer's root. */
|
|
992
|
-
file:
|
|
1060
|
+
file: z6.string().min(1).describe("Path relative to the selected drawer root."),
|
|
993
1061
|
/** Read from the artifacts drawer instead of the project workspace. */
|
|
994
|
-
artifact:
|
|
1062
|
+
artifact: z6.boolean().optional().describe("True for the artifacts drawer; false/omitted for the project workspace.")
|
|
995
1063
|
});
|
|
996
|
-
var ModelTierSchema =
|
|
997
|
-
var CraftbookStepSchema =
|
|
998
|
-
id:
|
|
999
|
-
name:
|
|
1000
|
-
description:
|
|
1064
|
+
var ModelTierSchema = z6.enum(MODEL_TIER_ORDER);
|
|
1065
|
+
var CraftbookStepSchema = z6.object({
|
|
1066
|
+
id: z6.string().min(1),
|
|
1067
|
+
name: z6.string().min(1),
|
|
1068
|
+
description: z6.string().optional(),
|
|
1001
1069
|
/**
|
|
1002
1070
|
* Per-step prompt body. In bundled/local catalog form, this is loaded
|
|
1003
1071
|
* from the per-step `prompt.md` file (when the version manifest carries
|
|
1004
1072
|
* a separate file) and inlined at resolution time.
|
|
1005
1073
|
*/
|
|
1006
|
-
prompt:
|
|
1007
|
-
suggestedGezelId:
|
|
1074
|
+
prompt: z6.string().optional(),
|
|
1075
|
+
suggestedGezelId: z6.string().optional(),
|
|
1008
1076
|
/**
|
|
1009
1077
|
* Free-form role hint ("reviewer", "developer", "designer"). When set
|
|
1010
1078
|
* and `suggestedGezelId` / `assignee` are both absent at step
|
|
@@ -1015,7 +1083,7 @@ var CraftbookStepSchema = z5.object({
|
|
|
1015
1083
|
* specific gezel id. Override by setting `assignee` or
|
|
1016
1084
|
* `suggestedGezelId` at task create time.
|
|
1017
1085
|
*/
|
|
1018
|
-
suggestedRole:
|
|
1086
|
+
suggestedRole: z6.string().optional(),
|
|
1019
1087
|
/**
|
|
1020
1088
|
* Minimum model tier to run this step unsupervised. Overrides the
|
|
1021
1089
|
* `suggestedRole`'s registry floor (roles/registry.ts) when set;
|
|
@@ -1024,6 +1092,8 @@ var CraftbookStepSchema = z5.object({
|
|
|
1024
1092
|
* that clears the floor runs the step.
|
|
1025
1093
|
*/
|
|
1026
1094
|
capabilityFloor: ModelTierSchema.optional(),
|
|
1095
|
+
/** Per-phase indexed-context policy; overrides gezel and install defaults. */
|
|
1096
|
+
retrieval: RetrievalPolicySchema.optional(),
|
|
1027
1097
|
assignee: TaskAssigneeSchema.optional(),
|
|
1028
1098
|
/** Setup scripts, run in order when the step activates. Single ref = legacy shape. */
|
|
1029
1099
|
onEnter: ScriptRefListSchema.optional(),
|
|
@@ -1034,16 +1104,16 @@ var CraftbookStepSchema = z5.object({
|
|
|
1034
1104
|
*/
|
|
1035
1105
|
onExit: ScriptRefListSchema.optional(),
|
|
1036
1106
|
/** Required file inputs for this step, in the order they should be opened. */
|
|
1037
|
-
consumes:
|
|
1107
|
+
consumes: z6.array(CraftbookStepInputSchema).min(1).optional().describe(
|
|
1038
1108
|
"Files this step must open before working. Artifact inputs also require an explicit `read_artifact` call in the step prompt."
|
|
1039
1109
|
),
|
|
1040
1110
|
/** See {@link AdvanceWhenSchema}. */
|
|
1041
1111
|
advanceWhen: AdvanceWhenSchema.optional(),
|
|
1042
1112
|
/** The end-of-step decision. See {@link StepGateSchema} (current) / {@link GateSpecSchema} (legacy). */
|
|
1043
1113
|
gate: StepGateUnionSchema.optional(),
|
|
1044
|
-
next:
|
|
1045
|
-
branches:
|
|
1046
|
-
terminal:
|
|
1114
|
+
next: z6.string().optional(),
|
|
1115
|
+
branches: z6.array(CraftbookBranchSchema).optional(),
|
|
1116
|
+
terminal: z6.boolean().optional(),
|
|
1047
1117
|
/**
|
|
1048
1118
|
* Marks the parent step that triggers a declarative per-item fanout
|
|
1049
1119
|
* (see {@link CraftbookSpawnSchema}). When this step activates on a
|
|
@@ -1051,19 +1121,19 @@ var CraftbookStepSchema = z5.object({
|
|
|
1051
1121
|
* JSON array on its declared surface and spawns one child task per item — no model
|
|
1052
1122
|
* tool call. Inert unless the craftbook also declares `spawn`.
|
|
1053
1123
|
*/
|
|
1054
|
-
spawnFanout:
|
|
1124
|
+
spawnFanout: z6.boolean().optional()
|
|
1055
1125
|
});
|
|
1056
|
-
var CraftbookSpawnSchema =
|
|
1126
|
+
var CraftbookSpawnSchema = z6.object({
|
|
1057
1127
|
/** Surface-relative JSON file the parent produces; its array drives the fanout. */
|
|
1058
|
-
overFile:
|
|
1128
|
+
overFile: z6.string().min(1),
|
|
1059
1129
|
/** Read overFile from the artifacts drawer instead of the project workspace. */
|
|
1060
|
-
overArtifact:
|
|
1130
|
+
overArtifact: z6.boolean().optional(),
|
|
1061
1131
|
/** Dotted path to the array inside `overFile`. Absent → the file itself is the array. */
|
|
1062
|
-
itemsPath:
|
|
1132
|
+
itemsPath: z6.string().optional(),
|
|
1063
1133
|
/** Entry step id of the child template. Defaults to the first `steps` entry. */
|
|
1064
|
-
entryStepId:
|
|
1134
|
+
entryStepId: z6.string().optional(),
|
|
1065
1135
|
/** The per-child step template — same shape as a craftbook's own steps. */
|
|
1066
|
-
steps:
|
|
1136
|
+
steps: z6.array(CraftbookStepSchema).min(1)
|
|
1067
1137
|
});
|
|
1068
1138
|
function validateCraftbookGraph(cb) {
|
|
1069
1139
|
const problems = [];
|
|
@@ -1118,70 +1188,88 @@ function validateCraftbookGraph(cb) {
|
|
|
1118
1188
|
function refineCraftbook(cb, ctx) {
|
|
1119
1189
|
for (const message of validateCraftbookGraph(cb)) {
|
|
1120
1190
|
ctx.addIssue({
|
|
1121
|
-
code:
|
|
1191
|
+
code: z6.ZodIssueCode.custom,
|
|
1122
1192
|
message,
|
|
1123
1193
|
path: message.startsWith("entryStepId") ? ["entryStepId"] : ["steps"]
|
|
1124
1194
|
});
|
|
1125
1195
|
}
|
|
1126
1196
|
for (const message of validateCraftbookScriptRefs(cb)) {
|
|
1127
|
-
ctx.addIssue({ code:
|
|
1197
|
+
ctx.addIssue({ code: z6.ZodIssueCode.custom, message, path: ["steps"] });
|
|
1128
1198
|
}
|
|
1129
1199
|
}
|
|
1130
|
-
var CraftbookRequirementSchema =
|
|
1200
|
+
var CraftbookRequirementSchema = z6.discriminatedUnion("kind", [
|
|
1131
1201
|
/** The project is connected to a GitHub repository. */
|
|
1132
|
-
|
|
1202
|
+
z6.object({ kind: z6.literal("github") }),
|
|
1133
1203
|
/** The project's current git branch is not the main line (main/master). */
|
|
1134
|
-
|
|
1204
|
+
z6.object({ kind: z6.literal("non-main-branch") })
|
|
1205
|
+
]);
|
|
1206
|
+
var CraftbookRecommendationSchema = z6.discriminatedUnion("kind", [
|
|
1207
|
+
/**
|
|
1208
|
+
* Works better with the install-wide External services capability
|
|
1209
|
+
* (`securityPolicy.allowExternalServices`) — web search, URL fetch.
|
|
1210
|
+
*/
|
|
1211
|
+
z6.object({
|
|
1212
|
+
kind: z6.literal("external-services"),
|
|
1213
|
+
/** Human-readable rationale shown in the nudge ("verifies sources with live web search"). */
|
|
1214
|
+
reason: z6.string().optional()
|
|
1215
|
+
})
|
|
1135
1216
|
]);
|
|
1136
|
-
var CraftbookRunModesSchema =
|
|
1137
|
-
scheduled:
|
|
1138
|
-
nightShift:
|
|
1217
|
+
var CraftbookRunModesSchema = z6.object({
|
|
1218
|
+
scheduled: z6.enum(["supported", "recommended"]).optional(),
|
|
1219
|
+
nightShift: z6.enum(["supported", "recommended"]).optional()
|
|
1139
1220
|
});
|
|
1140
|
-
var CraftbookToolsetNeedSchema =
|
|
1221
|
+
var CraftbookToolsetNeedSchema = z6.object({
|
|
1141
1222
|
/** Catalog toolset id, e.g. `github`, `usb-camera`. */
|
|
1142
|
-
toolsetId:
|
|
1223
|
+
toolsetId: z6.string().min(1),
|
|
1143
1224
|
/** Catalog source provenance (bundled/community), when pinned. */
|
|
1144
|
-
sourceId:
|
|
1225
|
+
sourceId: z6.string().optional(),
|
|
1145
1226
|
/** Optional semver floor; presence is recorded but not yet enforced. */
|
|
1146
|
-
minVersion:
|
|
1227
|
+
minVersion: z6.string().optional(),
|
|
1147
1228
|
/**
|
|
1148
1229
|
* When true, the need is a suggestion only — surfaced as a hint, never
|
|
1149
1230
|
* blocks invocation. Default (absent/false) = required: the launcher
|
|
1150
1231
|
* offers install before the craftbook can run.
|
|
1151
1232
|
*/
|
|
1152
|
-
optional:
|
|
1233
|
+
optional: z6.boolean().optional(),
|
|
1153
1234
|
/**
|
|
1154
1235
|
* When true, pre-authorize every tool this toolset exposes for the
|
|
1155
1236
|
* duration the craftbook is active — both via a synthesized PreToolUse
|
|
1156
1237
|
* allow-hook (in-process providers) and the Claude-CLI permission
|
|
1157
1238
|
* broker. Off by default; opt in for unattended/scheduled craftbooks.
|
|
1158
1239
|
*/
|
|
1159
|
-
autoAllow:
|
|
1240
|
+
autoAllow: z6.boolean().optional(),
|
|
1160
1241
|
/** Human-readable rationale shown in the launcher ("pull camera frames"). */
|
|
1161
|
-
reason:
|
|
1242
|
+
reason: z6.string().optional()
|
|
1162
1243
|
});
|
|
1163
|
-
var
|
|
1244
|
+
var CraftbookCommandNeedSchema = z6.object({
|
|
1245
|
+
scope: z6.enum(["script", "npx"]),
|
|
1246
|
+
name: z6.string().min(1),
|
|
1247
|
+
args: z6.array(z6.string()).optional(),
|
|
1248
|
+
reason: z6.string().optional(),
|
|
1249
|
+
optional: z6.boolean().optional()
|
|
1250
|
+
});
|
|
1251
|
+
var CraftbookConnectorNeedSchema = z6.object({
|
|
1164
1252
|
/** Catalog connector-type id, e.g. `github-pulls`, `mail-gmail`. */
|
|
1165
|
-
typeId:
|
|
1253
|
+
typeId: z6.string().min(1),
|
|
1166
1254
|
/** Catalog source provenance (bundled/community), when pinned. */
|
|
1167
|
-
sourceId:
|
|
1255
|
+
sourceId: z6.string().optional(),
|
|
1168
1256
|
/**
|
|
1169
1257
|
* When true, the craftbook still runs without the connector bound —
|
|
1170
1258
|
* the corpus is a bonus, not the substrate. Default (absent/false) =
|
|
1171
1259
|
* required: the launcher offers to bind it before the craftbook runs.
|
|
1172
1260
|
*/
|
|
1173
|
-
optional:
|
|
1261
|
+
optional: z6.boolean().optional(),
|
|
1174
1262
|
/** Human-readable rationale shown in the launcher ("pull the PR diff"). */
|
|
1175
|
-
reason:
|
|
1263
|
+
reason: z6.string().optional()
|
|
1176
1264
|
});
|
|
1177
1265
|
var CRAFTBOOK_SCRIPT_MAX_BYTES = 64 * 1024;
|
|
1178
1266
|
var CRAFTBOOK_SCRIPTS_TOTAL_MAX_BYTES = 256 * 1024;
|
|
1179
1267
|
var CRAFTBOOK_SCRIPTS_MAX_COUNT = 24;
|
|
1180
|
-
var CraftbookScriptsSchema =
|
|
1268
|
+
var CraftbookScriptsSchema = z6.record(ScriptNameSchema, z6.string().min(1).max(CRAFTBOOK_SCRIPT_MAX_BYTES)).superRefine((scripts, ctx) => {
|
|
1181
1269
|
const names = Object.keys(scripts);
|
|
1182
1270
|
if (names.length > CRAFTBOOK_SCRIPTS_MAX_COUNT) {
|
|
1183
1271
|
ctx.addIssue({
|
|
1184
|
-
code:
|
|
1272
|
+
code: z6.ZodIssueCode.custom,
|
|
1185
1273
|
message: `a craftbook carries at most ${CRAFTBOOK_SCRIPTS_MAX_COUNT} scripts (got ${names.length})`
|
|
1186
1274
|
});
|
|
1187
1275
|
}
|
|
@@ -1189,14 +1277,14 @@ var CraftbookScriptsSchema = z5.record(ScriptNameSchema, z5.string().min(1).max(
|
|
|
1189
1277
|
for (const name of names) total += scripts[name].length;
|
|
1190
1278
|
if (total > CRAFTBOOK_SCRIPTS_TOTAL_MAX_BYTES) {
|
|
1191
1279
|
ctx.addIssue({
|
|
1192
|
-
code:
|
|
1280
|
+
code: z6.ZodIssueCode.custom,
|
|
1193
1281
|
message: `craftbook scripts total ${total} bytes \u2014 the ceiling is ${CRAFTBOOK_SCRIPTS_TOTAL_MAX_BYTES}`
|
|
1194
1282
|
});
|
|
1195
1283
|
}
|
|
1196
1284
|
});
|
|
1197
|
-
var CraftbookBasedOnSchema =
|
|
1198
|
-
name:
|
|
1199
|
-
url:
|
|
1285
|
+
var CraftbookBasedOnSchema = z6.object({
|
|
1286
|
+
name: z6.string().min(1),
|
|
1287
|
+
url: z6.string().url().regex(/^https?:\/\//i, "basedOn.url must use http or https")
|
|
1200
1288
|
});
|
|
1201
1289
|
function validateCraftbookScriptRefs(cb) {
|
|
1202
1290
|
if (!cb.scripts) return [];
|
|
@@ -1218,32 +1306,32 @@ function validateCraftbookScriptRefs(cb) {
|
|
|
1218
1306
|
}
|
|
1219
1307
|
return problems;
|
|
1220
1308
|
}
|
|
1221
|
-
var CraftbookSchema =
|
|
1309
|
+
var CraftbookSchema = z6.object({
|
|
1222
1310
|
/** Matches catalog folder name. For ad-hoc embedded craftbooks (inline-steps tasks), a generated id. */
|
|
1223
|
-
id:
|
|
1224
|
-
name:
|
|
1225
|
-
description:
|
|
1311
|
+
id: z6.string().min(1),
|
|
1312
|
+
name: z6.string().min(1),
|
|
1313
|
+
description: z6.string().optional(),
|
|
1226
1314
|
/** Semver from the catalog version this craftbook was resolved from. Unset for ad-hoc embedded books. */
|
|
1227
|
-
version:
|
|
1315
|
+
version: z6.string().optional(),
|
|
1228
1316
|
/** Optional credit + link to the upstream work this craftbook adapts. */
|
|
1229
1317
|
basedOn: CraftbookBasedOnSchema.optional(),
|
|
1230
|
-
plan:
|
|
1318
|
+
plan: z6.string().optional(),
|
|
1231
1319
|
defaultAssignee: TaskAssigneeSchema.optional(),
|
|
1232
|
-
steps:
|
|
1233
|
-
entryStepId:
|
|
1320
|
+
steps: z6.array(CraftbookStepSchema).min(1),
|
|
1321
|
+
entryStepId: z6.string().min(1),
|
|
1234
1322
|
/**
|
|
1235
1323
|
* User-speech phrases that route to this craftbook. Matched
|
|
1236
1324
|
* case-insensitively as substrings against the user's chat input
|
|
1237
1325
|
* (or against a slash-command argument). Optional; absent =
|
|
1238
1326
|
* invocable only via explicit `invoke_craftbook` / Commands panel.
|
|
1239
1327
|
*/
|
|
1240
|
-
triggers:
|
|
1328
|
+
triggers: z6.array(z6.string()).optional(),
|
|
1241
1329
|
/**
|
|
1242
1330
|
* Pre/PostToolUse hooks installed for the duration the craftbook
|
|
1243
1331
|
* is active. The MCP bridge consults this list before forwarding
|
|
1244
1332
|
* a `tools/call`. See `hook.ts` for the decision contract.
|
|
1245
1333
|
*/
|
|
1246
|
-
hooks:
|
|
1334
|
+
hooks: z6.array(HookSpecSchema).optional(),
|
|
1247
1335
|
/**
|
|
1248
1336
|
* Optional squisq/JSON-Schema object describing the parameters this
|
|
1249
1337
|
* craftbook collects before it runs. Its top-level `properties` are
|
|
@@ -1254,19 +1342,26 @@ var CraftbookSchema = z5.object({
|
|
|
1254
1342
|
* structurally; typed as squisq's `SquisqAnnotatedSchema` at the UI
|
|
1255
1343
|
* boundary. Absent = parameterless (the command is injected directly).
|
|
1256
1344
|
*/
|
|
1257
|
-
paramSchema:
|
|
1345
|
+
paramSchema: z6.record(z6.string(), z6.unknown()).optional(),
|
|
1258
1346
|
/**
|
|
1259
1347
|
* CLI token the launcher stages into the terminal and that the
|
|
1260
1348
|
* terminal recognizes. Defaults to `id` when absent — e.g. the
|
|
1261
1349
|
* "Code Review" craftbook (id `review`) sets `command: "code-review"`.
|
|
1262
1350
|
*/
|
|
1263
|
-
command:
|
|
1351
|
+
command: z6.string().regex(/^[a-z][a-z0-9-]*$/).optional(),
|
|
1264
1352
|
/**
|
|
1265
1353
|
* Prerequisites a project must satisfy for this craftbook to be
|
|
1266
1354
|
* applicable. When unmet, the craftbook is hidden from the launcher
|
|
1267
1355
|
* and not recognized as a terminal command. Absent = always offered.
|
|
1268
1356
|
*/
|
|
1269
|
-
requirements:
|
|
1357
|
+
requirements: z6.array(CraftbookRequirementSchema).optional(),
|
|
1358
|
+
/**
|
|
1359
|
+
* Soft "works better with" hints — never gate, only inform UI copy
|
|
1360
|
+
* (the craftbook start card's permission nudge). See
|
|
1361
|
+
* {@link CraftbookRecommendationSchema}. Carried into the runtime
|
|
1362
|
+
* craftbook and the task snapshot, unlike `requirements`.
|
|
1363
|
+
*/
|
|
1364
|
+
recommends: z6.array(CraftbookRecommendationSchema).optional(),
|
|
1270
1365
|
/** Unattended launch modes this recipe is suitable for. */
|
|
1271
1366
|
runModes: CraftbookRunModesSchema.optional(),
|
|
1272
1367
|
/**
|
|
@@ -1277,7 +1372,14 @@ var CraftbookSchema = z5.object({
|
|
|
1277
1372
|
* `requirements`, this is carried into the runtime craftbook and the task
|
|
1278
1373
|
* snapshot. Absent = no declared toolset dependencies.
|
|
1279
1374
|
*/
|
|
1280
|
-
toolsets:
|
|
1375
|
+
toolsets: z6.array(CraftbookToolsetNeedSchema).optional(),
|
|
1376
|
+
/**
|
|
1377
|
+
* Project commands this craftbook's `commandEvidence` gates verify runs
|
|
1378
|
+
* of. See {@link CraftbookCommandNeedSchema}. Carried into the runtime
|
|
1379
|
+
* craftbook and the task snapshot so the kickoff path can raise the
|
|
1380
|
+
* first-use approval questions up front.
|
|
1381
|
+
*/
|
|
1382
|
+
commands: z6.array(CraftbookCommandNeedSchema).optional(),
|
|
1281
1383
|
/**
|
|
1282
1384
|
* Connectors whose mirrored `artifacts/data/` corpus this craftbook reads. The
|
|
1283
1385
|
* launcher binds and syncs them before the first step runs. See
|
|
@@ -1285,7 +1387,7 @@ var CraftbookSchema = z5.object({
|
|
|
1285
1387
|
* craftbook and the task snapshot so a running task records what it
|
|
1286
1388
|
* was launched against. Absent = no connector dependencies.
|
|
1287
1389
|
*/
|
|
1288
|
-
connectors:
|
|
1390
|
+
connectors: z6.array(CraftbookConnectorNeedSchema).optional(),
|
|
1289
1391
|
/**
|
|
1290
1392
|
* Embedded script sources (name → TypeScript). See
|
|
1291
1393
|
* {@link CraftbookScriptsSchema}. Hydrated at resolution time for
|
|
@@ -1301,10 +1403,30 @@ var CraftbookSchema = z5.object({
|
|
|
1301
1403
|
* task snapshot so the runtime reads it at fanout time.
|
|
1302
1404
|
*/
|
|
1303
1405
|
spawn: CraftbookSpawnSchema.optional(),
|
|
1304
|
-
|
|
1305
|
-
|
|
1406
|
+
/**
|
|
1407
|
+
* This craftbook is authored mode-agnostic: it works identically whether
|
|
1408
|
+
* a run edits the workspace in place or drafts a diffpack change
|
|
1409
|
+
* proposal. Concretely, its workspace deliverables and gates evaluate
|
|
1410
|
+
* through the draft overlay, and it carries no mode-specific prose and
|
|
1411
|
+
* no `{{diffpack.*}}` tokens — the runtime injects drafting framing and
|
|
1412
|
+
* re-roots the write tools. Declaring it lets an invocation opt the run
|
|
1413
|
+
* into proposing (`deliveryMode: 'propose'`, or automatically for
|
|
1414
|
+
* unattended runs); the mode is a property of the RUN, never of the
|
|
1415
|
+
* book. Resolution rule in `TaskManager.create`.
|
|
1416
|
+
*/
|
|
1417
|
+
diffpackCapable: z6.boolean().optional(),
|
|
1418
|
+
/**
|
|
1419
|
+
* Minimum model tier for the WHOLE book: every step floors at least
|
|
1420
|
+
* here (per-step `capabilityFloor` still overrides absolutely, and a
|
|
1421
|
+
* stricter role floor still wins — see `effectiveCapabilityFloor` in
|
|
1422
|
+
* roles/registry.ts). The honest "this recipe needs a medium model"
|
|
1423
|
+
* declaration, consumed by per-step routing at dispatch.
|
|
1424
|
+
*/
|
|
1425
|
+
capabilityFloor: ModelTierSchema.optional(),
|
|
1426
|
+
createdAt: z6.string(),
|
|
1427
|
+
updatedAt: z6.string()
|
|
1306
1428
|
}).superRefine(refineCraftbook);
|
|
1307
|
-
var DeliverableKindSchema =
|
|
1429
|
+
var DeliverableKindSchema = z6.enum([
|
|
1308
1430
|
"html-game",
|
|
1309
1431
|
"html-multiscreen-game",
|
|
1310
1432
|
"html-page",
|
|
@@ -1323,97 +1445,101 @@ var DeliverableKindSchema = z5.enum([
|
|
|
1323
1445
|
"data-file",
|
|
1324
1446
|
"generic-file"
|
|
1325
1447
|
]);
|
|
1326
|
-
var StepDeliverableSchema =
|
|
1448
|
+
var StepDeliverableSchema = z6.object({
|
|
1327
1449
|
/** Workspace-relative file the step must produce. The only required field. */
|
|
1328
|
-
path:
|
|
1450
|
+
path: z6.string().min(1),
|
|
1329
1451
|
/** Artifact class; inferred from the file extension when absent. */
|
|
1330
1452
|
kind: DeliverableKindSchema.optional(),
|
|
1331
1453
|
/** Override the class-default byte floor. */
|
|
1332
|
-
minBytes:
|
|
1454
|
+
minBytes: z6.number().int().positive().optional(),
|
|
1333
1455
|
/** Gate rejections before the task pauses for help. */
|
|
1334
|
-
maxAttempts:
|
|
1456
|
+
maxAttempts: z6.number().int().positive().optional(),
|
|
1335
1457
|
/** Gate the artifacts drawer instead of the workspace. */
|
|
1336
|
-
artifact:
|
|
1458
|
+
artifact: z6.boolean().optional(),
|
|
1337
1459
|
/**
|
|
1338
1460
|
* The deliverable is an EDIT to a pre-existing file (fix/refactor):
|
|
1339
1461
|
* presence alone never advances the step — the assignee must have
|
|
1340
1462
|
* written to the file this turn. See {@link AdvanceWhenSchema}.
|
|
1341
1463
|
*/
|
|
1342
|
-
requireChange:
|
|
1464
|
+
requireChange: z6.boolean().optional(),
|
|
1343
1465
|
/**
|
|
1344
1466
|
* For code deliverables: additionally execute the file in the sandbox
|
|
1345
1467
|
* and require exit 0 (a `node:test`/`assert` file exits nonzero on
|
|
1346
1468
|
* failure — exactly the contract). Opt-in.
|
|
1347
1469
|
*/
|
|
1348
|
-
execute:
|
|
1470
|
+
execute: z6.boolean().optional(),
|
|
1349
1471
|
/** For data deliverables: required column names (adds a tableShape check). */
|
|
1350
|
-
columns:
|
|
1472
|
+
columns: z6.array(z6.string().min(1)).min(1).optional(),
|
|
1351
1473
|
/** For data deliverables: minimum row count (adds a tableShape check). */
|
|
1352
|
-
minRows:
|
|
1353
|
-
});
|
|
1354
|
-
var NewCraftbookStepSchema =
|
|
1355
|
-
id:
|
|
1356
|
-
name:
|
|
1357
|
-
description:
|
|
1358
|
-
prompt:
|
|
1359
|
-
suggestedGezelId:
|
|
1474
|
+
minRows: z6.number().int().positive().optional()
|
|
1475
|
+
});
|
|
1476
|
+
var NewCraftbookStepSchema = z6.object({
|
|
1477
|
+
id: z6.string().optional(),
|
|
1478
|
+
name: z6.string().min(1),
|
|
1479
|
+
description: z6.string().optional(),
|
|
1480
|
+
prompt: z6.string().optional(),
|
|
1481
|
+
suggestedGezelId: z6.string().optional(),
|
|
1360
1482
|
/** See {@link CraftbookStepSchema.shape.suggestedRole}. */
|
|
1361
|
-
suggestedRole:
|
|
1483
|
+
suggestedRole: z6.string().optional(),
|
|
1362
1484
|
/** See {@link CraftbookStepSchema.shape.capabilityFloor}. */
|
|
1363
1485
|
capabilityFloor: ModelTierSchema.optional(),
|
|
1486
|
+
/** See {@link CraftbookStepSchema.shape.retrieval}. */
|
|
1487
|
+
retrieval: RetrievalPolicySchema.optional(),
|
|
1364
1488
|
assignee: TaskAssigneeSchema.optional(),
|
|
1365
1489
|
onEnter: ScriptRefListSchema.optional(),
|
|
1366
1490
|
onExit: ScriptRefListSchema.optional(),
|
|
1367
|
-
consumes:
|
|
1491
|
+
consumes: z6.array(CraftbookStepInputSchema).min(1).optional().describe(
|
|
1368
1492
|
"Files this step must open before working. Artifact inputs also require an explicit `read_artifact` call in the step prompt."
|
|
1369
1493
|
),
|
|
1370
1494
|
advanceWhen: AdvanceWhenSchema.optional(),
|
|
1371
1495
|
gate: StepGateUnionSchema.optional(),
|
|
1372
1496
|
/** See {@link StepDeliverableSchema} — one field attaches the enforced gate. */
|
|
1373
1497
|
deliverable: StepDeliverableSchema.optional(),
|
|
1374
|
-
next:
|
|
1375
|
-
branches:
|
|
1376
|
-
terminal:
|
|
1498
|
+
next: z6.string().optional(),
|
|
1499
|
+
branches: z6.array(CraftbookBranchSchema).optional(),
|
|
1500
|
+
terminal: z6.boolean().optional(),
|
|
1377
1501
|
/** See {@link CraftbookStepSchema.shape.spawnFanout}. */
|
|
1378
|
-
spawnFanout:
|
|
1502
|
+
spawnFanout: z6.boolean().optional()
|
|
1379
1503
|
});
|
|
1380
|
-
var CreateCraftbookRequestSchema =
|
|
1381
|
-
id:
|
|
1382
|
-
name:
|
|
1383
|
-
description:
|
|
1504
|
+
var CreateCraftbookRequestSchema = z6.object({
|
|
1505
|
+
id: z6.string().optional(),
|
|
1506
|
+
name: z6.string().min(1),
|
|
1507
|
+
description: z6.string().optional(),
|
|
1384
1508
|
basedOn: CraftbookBasedOnSchema.optional(),
|
|
1385
|
-
plan:
|
|
1509
|
+
plan: z6.string().optional(),
|
|
1386
1510
|
defaultAssignee: TaskAssigneeSchema.optional(),
|
|
1387
|
-
steps:
|
|
1388
|
-
entryStepId:
|
|
1389
|
-
paramSchema:
|
|
1390
|
-
command:
|
|
1391
|
-
requirements:
|
|
1511
|
+
steps: z6.array(NewCraftbookStepSchema).min(1),
|
|
1512
|
+
entryStepId: z6.string().optional(),
|
|
1513
|
+
paramSchema: z6.record(z6.string(), z6.unknown()).optional(),
|
|
1514
|
+
command: z6.string().regex(/^[a-z][a-z0-9-]*$/).optional(),
|
|
1515
|
+
requirements: z6.array(CraftbookRequirementSchema).optional(),
|
|
1516
|
+
recommends: z6.array(CraftbookRecommendationSchema).optional(),
|
|
1392
1517
|
runModes: CraftbookRunModesSchema.optional(),
|
|
1393
|
-
toolsets:
|
|
1518
|
+
toolsets: z6.array(CraftbookToolsetNeedSchema).optional(),
|
|
1394
1519
|
scripts: CraftbookScriptsSchema.optional()
|
|
1395
1520
|
});
|
|
1396
|
-
var UpdateCraftbookRequestSchema =
|
|
1397
|
-
name:
|
|
1398
|
-
description:
|
|
1521
|
+
var UpdateCraftbookRequestSchema = z6.object({
|
|
1522
|
+
name: z6.string().min(1).optional(),
|
|
1523
|
+
description: z6.string().nullable().optional(),
|
|
1399
1524
|
basedOn: CraftbookBasedOnSchema.nullable().optional(),
|
|
1400
|
-
plan:
|
|
1525
|
+
plan: z6.string().nullable().optional(),
|
|
1401
1526
|
defaultAssignee: TaskAssigneeSchema.nullable().optional(),
|
|
1402
|
-
steps:
|
|
1403
|
-
entryStepId:
|
|
1404
|
-
paramSchema:
|
|
1405
|
-
command:
|
|
1406
|
-
requirements:
|
|
1527
|
+
steps: z6.array(NewCraftbookStepSchema).min(1).optional(),
|
|
1528
|
+
entryStepId: z6.string().optional(),
|
|
1529
|
+
paramSchema: z6.record(z6.string(), z6.unknown()).nullable().optional(),
|
|
1530
|
+
command: z6.string().regex(/^[a-z][a-z0-9-]*$/).nullable().optional(),
|
|
1531
|
+
requirements: z6.array(CraftbookRequirementSchema).nullable().optional(),
|
|
1532
|
+
recommends: z6.array(CraftbookRecommendationSchema).nullable().optional(),
|
|
1407
1533
|
runModes: CraftbookRunModesSchema.nullable().optional(),
|
|
1408
|
-
toolsets:
|
|
1534
|
+
toolsets: z6.array(CraftbookToolsetNeedSchema).nullable().optional(),
|
|
1409
1535
|
/** Full-replace semantics: the map is the truth. `null` clears all scripts. */
|
|
1410
1536
|
scripts: CraftbookScriptsSchema.nullable().optional()
|
|
1411
1537
|
});
|
|
1412
|
-
var CraftbookSummarySchema =
|
|
1413
|
-
id:
|
|
1414
|
-
name:
|
|
1415
|
-
description:
|
|
1416
|
-
version:
|
|
1538
|
+
var CraftbookSummarySchema = z6.object({
|
|
1539
|
+
id: z6.string(),
|
|
1540
|
+
name: z6.string(),
|
|
1541
|
+
description: z6.string().optional(),
|
|
1542
|
+
version: z6.string().optional(),
|
|
1417
1543
|
basedOn: CraftbookBasedOnSchema.optional(),
|
|
1418
1544
|
/**
|
|
1419
1545
|
* Where the craftbook came from. `bundled` — shipped catalog;
|
|
@@ -1422,51 +1548,51 @@ var CraftbookSummarySchema = z5.object({
|
|
|
1422
1548
|
* folder (often auto-imported from a `.claude/skills` / `agents/skills`
|
|
1423
1549
|
* SKILL.md). Project craftbooks only surface inside their own project.
|
|
1424
1550
|
*/
|
|
1425
|
-
source:
|
|
1426
|
-
stepCount:
|
|
1551
|
+
source: z6.enum(["bundled", "local", "project"]),
|
|
1552
|
+
stepCount: z6.number().int().nonnegative()
|
|
1427
1553
|
});
|
|
1428
|
-
var ListCraftbooksResponseSchema =
|
|
1429
|
-
craftbooks:
|
|
1554
|
+
var ListCraftbooksResponseSchema = z6.object({
|
|
1555
|
+
craftbooks: z6.array(CraftbookSummarySchema)
|
|
1430
1556
|
});
|
|
1431
|
-
var ProjectCraftbookProvenanceSchema =
|
|
1432
|
-
installedBy:
|
|
1433
|
-
typeId:
|
|
1434
|
-
typeVersion:
|
|
1435
|
-
bookVersion:
|
|
1557
|
+
var ProjectCraftbookProvenanceSchema = z6.object({
|
|
1558
|
+
installedBy: z6.literal("project-type"),
|
|
1559
|
+
typeId: z6.string(),
|
|
1560
|
+
typeVersion: z6.string(),
|
|
1561
|
+
bookVersion: z6.string(),
|
|
1436
1562
|
/** sha256 over the installed book's canonical recipe JSON. */
|
|
1437
|
-
contentHash:
|
|
1438
|
-
installedAt:
|
|
1439
|
-
});
|
|
1440
|
-
var CraftbookSuggestionSchema =
|
|
1441
|
-
id:
|
|
1442
|
-
name:
|
|
1443
|
-
description:
|
|
1444
|
-
source:
|
|
1445
|
-
version:
|
|
1563
|
+
contentHash: z6.string(),
|
|
1564
|
+
installedAt: z6.string()
|
|
1565
|
+
});
|
|
1566
|
+
var CraftbookSuggestionSchema = z6.object({
|
|
1567
|
+
id: z6.string(),
|
|
1568
|
+
name: z6.string(),
|
|
1569
|
+
description: z6.string().optional(),
|
|
1570
|
+
source: z6.enum(["bundled", "local", "project"]),
|
|
1571
|
+
version: z6.string().optional(),
|
|
1446
1572
|
basedOn: CraftbookBasedOnSchema.optional(),
|
|
1447
|
-
stepCount:
|
|
1448
|
-
tags:
|
|
1449
|
-
triggers:
|
|
1450
|
-
score:
|
|
1451
|
-
semantic:
|
|
1452
|
-
lexical:
|
|
1573
|
+
stepCount: z6.number().int().nonnegative(),
|
|
1574
|
+
tags: z6.array(z6.string()).optional(),
|
|
1575
|
+
triggers: z6.array(z6.string()).optional(),
|
|
1576
|
+
score: z6.number(),
|
|
1577
|
+
semantic: z6.number().optional(),
|
|
1578
|
+
lexical: z6.number()
|
|
1453
1579
|
});
|
|
1454
|
-
var SuggestCraftbooksResponseSchema =
|
|
1455
|
-
suggestions:
|
|
1580
|
+
var SuggestCraftbooksResponseSchema = z6.object({
|
|
1581
|
+
suggestions: z6.array(CraftbookSuggestionSchema)
|
|
1456
1582
|
});
|
|
1457
|
-
var CraftbookResponseSchema =
|
|
1583
|
+
var CraftbookResponseSchema = z6.object({
|
|
1458
1584
|
craftbook: CraftbookSchema
|
|
1459
1585
|
});
|
|
1460
1586
|
function slugifyStepId(input) {
|
|
1461
1587
|
return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 64) || "step";
|
|
1462
1588
|
}
|
|
1463
|
-
var StepPositionSchema =
|
|
1589
|
+
var StepPositionSchema = z6.object({
|
|
1464
1590
|
/** Insert immediately after the step with this id. */
|
|
1465
|
-
after:
|
|
1591
|
+
after: z6.string().optional(),
|
|
1466
1592
|
/** Insert immediately before the step with this id. */
|
|
1467
|
-
before:
|
|
1593
|
+
before: z6.string().optional(),
|
|
1468
1594
|
/** Absolute insertion index (clamped to [0, length]). */
|
|
1469
|
-
index:
|
|
1595
|
+
index: z6.number().int().nonnegative().optional()
|
|
1470
1596
|
});
|
|
1471
1597
|
|
|
1472
1598
|
// src/markdown/frontmatter.ts
|
|
@@ -1642,11 +1768,21 @@ var FRONTMATTER_KEYS = [
|
|
|
1642
1768
|
"plan",
|
|
1643
1769
|
"defaultAssignee",
|
|
1644
1770
|
"requirements",
|
|
1771
|
+
"recommends",
|
|
1645
1772
|
"runModes",
|
|
1646
1773
|
"toolsets",
|
|
1647
1774
|
"connectors",
|
|
1648
1775
|
"paramSchema",
|
|
1649
1776
|
"hooks",
|
|
1777
|
+
// Whole-book declarations that are NOT step fields. Omitting one here is
|
|
1778
|
+
// worse than dropping it: the parser reports `unknown key "spawn"` and
|
|
1779
|
+
// refuses the save, so a model that correctly authored a fanout book in
|
|
1780
|
+
// the markdown arm is told its document is malformed.
|
|
1781
|
+
"spawn",
|
|
1782
|
+
"commands",
|
|
1783
|
+
"diffpackCapable",
|
|
1784
|
+
"capabilityFloor",
|
|
1785
|
+
"minGezelVersion",
|
|
1650
1786
|
"version",
|
|
1651
1787
|
"releasedAt"
|
|
1652
1788
|
];
|
|
@@ -1665,7 +1801,10 @@ var STEP_FENCE_KEYS = [
|
|
|
1665
1801
|
"gate",
|
|
1666
1802
|
"next",
|
|
1667
1803
|
"branches",
|
|
1668
|
-
"terminal"
|
|
1804
|
+
"terminal",
|
|
1805
|
+
// Marks the step the spawn block fans out from. Without it a book can
|
|
1806
|
+
// declare `spawn` and have no step that triggers it.
|
|
1807
|
+
"spawnFanout"
|
|
1669
1808
|
];
|
|
1670
1809
|
function parseCraftbookMarkdown(text) {
|
|
1671
1810
|
const errors = [];
|
|
@@ -1853,10 +1992,10 @@ function defaultStepIdForName(name) {
|
|
|
1853
1992
|
}
|
|
1854
1993
|
|
|
1855
1994
|
// src/schemas/gezel.ts
|
|
1856
|
-
import { z as
|
|
1995
|
+
import { z as z19 } from "zod";
|
|
1857
1996
|
|
|
1858
1997
|
// src/poppetje/schema.ts
|
|
1859
|
-
import { z as
|
|
1998
|
+
import { z as z7 } from "zod";
|
|
1860
1999
|
|
|
1861
2000
|
// src/poppetje/catalogs.ts
|
|
1862
2001
|
var BODY_ARCHETYPES = {
|
|
@@ -2002,45 +2141,45 @@ function migrateLegacyAccessory(raw) {
|
|
|
2002
2141
|
}
|
|
2003
2142
|
return r;
|
|
2004
2143
|
}
|
|
2005
|
-
var PoppetjeSchema =
|
|
2144
|
+
var PoppetjeSchema = z7.preprocess(
|
|
2006
2145
|
migrateLegacyAccessory,
|
|
2007
|
-
|
|
2146
|
+
z7.object({
|
|
2008
2147
|
/** Stable id; locks the wood-grain noise seed. Pin to the gezel id at creation. */
|
|
2009
|
-
key:
|
|
2010
|
-
name:
|
|
2011
|
-
bodyShape:
|
|
2012
|
-
figureScale:
|
|
2148
|
+
key: z7.string().min(1),
|
|
2149
|
+
name: z7.string(),
|
|
2150
|
+
bodyShape: z7.enum(BODY_SHAPE_KEYS),
|
|
2151
|
+
figureScale: z7.enum(FIGURE_SCALE_KEYS),
|
|
2013
2152
|
/** Mid-tone of the head. Paired with skin2 for the lateral gradient. */
|
|
2014
|
-
skin:
|
|
2153
|
+
skin: z7.string(),
|
|
2015
2154
|
/** Darker edge tone. */
|
|
2016
|
-
skin2:
|
|
2017
|
-
hair:
|
|
2018
|
-
hairShape:
|
|
2155
|
+
skin2: z7.string(),
|
|
2156
|
+
hair: z7.string(),
|
|
2157
|
+
hairShape: z7.enum(HAIR_SHAPES),
|
|
2019
2158
|
/** Replaces hair when set; 'hood' renders at body level. */
|
|
2020
|
-
hat:
|
|
2159
|
+
hat: z7.enum(HAT_OPTIONS).nullable().optional().default(null),
|
|
2021
2160
|
/** Body overlay; null for an unadorned shirt. */
|
|
2022
|
-
dress:
|
|
2161
|
+
dress: z7.enum(DRESS_OPTIONS).nullable().optional().default(null),
|
|
2023
2162
|
/** Wearable face accessory (glasses, earring, monocle). User-toggleable. */
|
|
2024
|
-
accessory:
|
|
2163
|
+
accessory: z7.enum(ACCESSORY_OPTIONS).nullable().optional().default(null),
|
|
2025
2164
|
/** Facial hair (beard, mustache). Physical — reroll-only. */
|
|
2026
|
-
facialHair:
|
|
2165
|
+
facialHair: z7.enum(FACIAL_HAIR_OPTIONS).nullable().optional().default(null),
|
|
2027
2166
|
/** Small facial detail (freckles, mole). Physical — reroll-only. */
|
|
2028
|
-
mark:
|
|
2029
|
-
expression:
|
|
2030
|
-
shirt:
|
|
2031
|
-
shirtAccent:
|
|
2167
|
+
mark: z7.enum(MARK_OPTIONS).nullable().optional().default(null),
|
|
2168
|
+
expression: z7.enum(EXPRESSION_OPTIONS).optional().default("smile"),
|
|
2169
|
+
shirt: z7.string(),
|
|
2170
|
+
shirtAccent: z7.string(),
|
|
2032
2171
|
/**
|
|
2033
2172
|
* Painted garment pattern over the shirt (buttons, stripes, sash, …).
|
|
2034
2173
|
* Files written before patterns existed parse as `plain` — the bare
|
|
2035
2174
|
* shirt those characters always had.
|
|
2036
2175
|
*/
|
|
2037
|
-
shirtPattern:
|
|
2176
|
+
shirtPattern: z7.enum(SHIRT_PATTERN_OPTIONS).optional().default("plain")
|
|
2038
2177
|
})
|
|
2039
2178
|
);
|
|
2040
2179
|
|
|
2041
2180
|
// src/schemas/claude.ts
|
|
2042
|
-
import { z as
|
|
2043
|
-
var ClaudePermissionModeSchema =
|
|
2181
|
+
import { z as z8 } from "zod";
|
|
2182
|
+
var ClaudePermissionModeSchema = z8.enum([
|
|
2044
2183
|
"default",
|
|
2045
2184
|
"acceptEdits",
|
|
2046
2185
|
"plan",
|
|
@@ -2048,20 +2187,20 @@ var ClaudePermissionModeSchema = z7.enum([
|
|
|
2048
2187
|
]);
|
|
2049
2188
|
|
|
2050
2189
|
// src/schemas/codex.ts
|
|
2051
|
-
import { z as
|
|
2052
|
-
var CodexPermissionModeSchema =
|
|
2053
|
-
var LegacyCodexPermissionModeSchema =
|
|
2190
|
+
import { z as z9 } from "zod";
|
|
2191
|
+
var CodexPermissionModeSchema = z9.enum(["plan", "edit", "reviewed", "full"]);
|
|
2192
|
+
var LegacyCodexPermissionModeSchema = z9.enum([
|
|
2054
2193
|
"default",
|
|
2055
2194
|
"acceptEdits",
|
|
2056
2195
|
"bypassPermissions"
|
|
2057
2196
|
]);
|
|
2058
|
-
var CodexPermissionModeCompatSchema =
|
|
2197
|
+
var CodexPermissionModeCompatSchema = z9.union([
|
|
2059
2198
|
CodexPermissionModeSchema,
|
|
2060
2199
|
LegacyCodexPermissionModeSchema
|
|
2061
2200
|
]);
|
|
2062
2201
|
|
|
2063
2202
|
// src/schemas/entity-id.ts
|
|
2064
|
-
import { z as
|
|
2203
|
+
import { z as z10 } from "zod";
|
|
2065
2204
|
|
|
2066
2205
|
// src/entity-id.ts
|
|
2067
2206
|
var SAFE_ENTITY_ID = /^[A-Za-z0-9@][A-Za-z0-9@._-]{0,199}$/;
|
|
@@ -2096,169 +2235,169 @@ function isSafeEntityId(value) {
|
|
|
2096
2235
|
}
|
|
2097
2236
|
|
|
2098
2237
|
// src/schemas/entity-id.ts
|
|
2099
|
-
var EntityIdSchema =
|
|
2238
|
+
var EntityIdSchema = z10.string().refine(isSafeEntityId, {
|
|
2100
2239
|
message: "must be a portable single-segment entity id"
|
|
2101
2240
|
});
|
|
2102
2241
|
|
|
2103
2242
|
// src/schemas/growth.ts
|
|
2104
|
-
import { z as
|
|
2243
|
+
import { z as z12 } from "zod";
|
|
2105
2244
|
|
|
2106
2245
|
// src/schemas/tuning-profile-registry.ts
|
|
2107
|
-
import { z as
|
|
2108
|
-
var TuningProfileIdSchema =
|
|
2246
|
+
import { z as z11 } from "zod";
|
|
2247
|
+
var TuningProfileIdSchema = z11.string().min(1).describe("Canonical tuning profile id.");
|
|
2109
2248
|
|
|
2110
2249
|
// src/schemas/growth.ts
|
|
2111
|
-
var GrowthEvidenceSchema =
|
|
2250
|
+
var GrowthEvidenceSchema = z12.object({
|
|
2112
2251
|
/** Memory-file day (YYYY-MM-DD) — rewritten server-side from the matched entry. */
|
|
2113
|
-
day:
|
|
2114
|
-
kind:
|
|
2115
|
-
excerpt:
|
|
2116
|
-
});
|
|
2117
|
-
var TraitProposalSchema =
|
|
2118
|
-
id:
|
|
2119
|
-
kind:
|
|
2120
|
-
title:
|
|
2252
|
+
day: z12.string().regex(/^\d{4}-\d{2}-\d{2}$/),
|
|
2253
|
+
kind: z12.enum(["fact", "decision", "pref", "status"]),
|
|
2254
|
+
excerpt: z12.string().min(1).max(400)
|
|
2255
|
+
});
|
|
2256
|
+
var TraitProposalSchema = z12.object({
|
|
2257
|
+
id: z12.string(),
|
|
2258
|
+
kind: z12.literal("trait"),
|
|
2259
|
+
title: z12.string().min(1).max(80),
|
|
2121
2260
|
/** One imperative second-person sentence destined for the prompt. */
|
|
2122
|
-
traitText:
|
|
2123
|
-
evidence:
|
|
2261
|
+
traitText: z12.string().min(1).max(200),
|
|
2262
|
+
evidence: z12.array(GrowthEvidenceSchema).min(1).max(3)
|
|
2124
2263
|
});
|
|
2125
|
-
var TuningActionSchema =
|
|
2126
|
-
|
|
2264
|
+
var TuningActionSchema = z12.discriminatedUnion("type", [
|
|
2265
|
+
z12.object({ type: z12.literal("profile"), profile: TuningProfileIdSchema }),
|
|
2127
2266
|
/** Resolved + clamped at accept time against the then-current frontmatter. */
|
|
2128
|
-
|
|
2267
|
+
z12.object({ type: z12.literal("temperature"), delta: z12.union([z12.literal(0.1), z12.literal(-0.1)]) })
|
|
2129
2268
|
]);
|
|
2130
|
-
var TuningProposalSchema =
|
|
2131
|
-
id:
|
|
2132
|
-
kind:
|
|
2133
|
-
title:
|
|
2134
|
-
description:
|
|
2269
|
+
var TuningProposalSchema = z12.object({
|
|
2270
|
+
id: z12.string(),
|
|
2271
|
+
kind: z12.literal("tuning"),
|
|
2272
|
+
title: z12.string().max(80),
|
|
2273
|
+
description: z12.string().max(300),
|
|
2135
2274
|
action: TuningActionSchema
|
|
2136
2275
|
});
|
|
2137
|
-
var CosmeticProposalSchema =
|
|
2138
|
-
id:
|
|
2139
|
-
kind:
|
|
2140
|
-
title:
|
|
2276
|
+
var CosmeticProposalSchema = z12.object({
|
|
2277
|
+
id: z12.string(),
|
|
2278
|
+
kind: z12.literal("cosmetic"),
|
|
2279
|
+
title: z12.string().max(80),
|
|
2141
2280
|
/** Key into GROWTH_COSMETICS, or a generic `level-N` milestone marker. */
|
|
2142
|
-
cosmeticId:
|
|
2281
|
+
cosmeticId: z12.string()
|
|
2143
2282
|
});
|
|
2144
|
-
var GrowthProposalSchema =
|
|
2283
|
+
var GrowthProposalSchema = z12.discriminatedUnion("kind", [
|
|
2145
2284
|
TraitProposalSchema,
|
|
2146
2285
|
TuningProposalSchema,
|
|
2147
2286
|
CosmeticProposalSchema
|
|
2148
2287
|
]);
|
|
2149
|
-
var PendingLevelUpSchema =
|
|
2150
|
-
toLevel:
|
|
2151
|
-
proposals:
|
|
2152
|
-
createdAt:
|
|
2153
|
-
});
|
|
2154
|
-
var GrowthSignalsSchema =
|
|
2155
|
-
memoryXp:
|
|
2156
|
-
lessonsXp:
|
|
2157
|
-
taskXp:
|
|
2158
|
-
consultXp:
|
|
2159
|
-
});
|
|
2160
|
-
var AdoptedTraitRecordSchema =
|
|
2161
|
-
traitId:
|
|
2162
|
-
text:
|
|
2163
|
-
level:
|
|
2164
|
-
adoptedAt:
|
|
2165
|
-
evidence:
|
|
2288
|
+
var PendingLevelUpSchema = z12.object({
|
|
2289
|
+
toLevel: z12.number().int().min(2),
|
|
2290
|
+
proposals: z12.array(GrowthProposalSchema).min(1).max(5),
|
|
2291
|
+
createdAt: z12.string()
|
|
2292
|
+
});
|
|
2293
|
+
var GrowthSignalsSchema = z12.object({
|
|
2294
|
+
memoryXp: z12.number().int().nonnegative().default(0),
|
|
2295
|
+
lessonsXp: z12.number().int().nonnegative().default(0),
|
|
2296
|
+
taskXp: z12.number().int().nonnegative().default(0),
|
|
2297
|
+
consultXp: z12.number().int().nonnegative().default(0)
|
|
2298
|
+
});
|
|
2299
|
+
var AdoptedTraitRecordSchema = z12.object({
|
|
2300
|
+
traitId: z12.string(),
|
|
2301
|
+
text: z12.string(),
|
|
2302
|
+
level: z12.number().int(),
|
|
2303
|
+
adoptedAt: z12.string(),
|
|
2304
|
+
evidence: z12.array(GrowthEvidenceSchema),
|
|
2166
2305
|
/** Set when the user later retires the trait — kept for the character sheet. */
|
|
2167
|
-
removedAt:
|
|
2306
|
+
removedAt: z12.string().optional()
|
|
2168
2307
|
});
|
|
2169
|
-
var DeclinedProposalRecordSchema =
|
|
2170
|
-
kind:
|
|
2171
|
-
title:
|
|
2308
|
+
var DeclinedProposalRecordSchema = z12.object({
|
|
2309
|
+
kind: z12.enum(["trait", "tuning", "cosmetic"]),
|
|
2310
|
+
title: z12.string(),
|
|
2172
2311
|
/** Used for never-re-offer matching on trait proposals. */
|
|
2173
|
-
traitText:
|
|
2174
|
-
level:
|
|
2175
|
-
declinedAt:
|
|
2176
|
-
});
|
|
2177
|
-
var GezelGrowthStateSchema =
|
|
2178
|
-
version:
|
|
2179
|
-
level:
|
|
2180
|
-
xp:
|
|
2312
|
+
traitText: z12.string().optional(),
|
|
2313
|
+
level: z12.number().int(),
|
|
2314
|
+
declinedAt: z12.string()
|
|
2315
|
+
});
|
|
2316
|
+
var GezelGrowthStateSchema = z12.object({
|
|
2317
|
+
version: z12.literal(1).default(1),
|
|
2318
|
+
level: z12.number().int().min(1).default(1),
|
|
2319
|
+
xp: z12.number().int().nonnegative().default(0),
|
|
2181
2320
|
signals: GrowthSignalsSchema.prefault({}),
|
|
2182
|
-
lastComputedAt:
|
|
2321
|
+
lastComputedAt: z12.string().optional(),
|
|
2183
2322
|
pendingLevelUp: PendingLevelUpSchema.optional(),
|
|
2184
|
-
adoptedTraits:
|
|
2185
|
-
declinedProposals:
|
|
2186
|
-
unlockedCosmetics:
|
|
2323
|
+
adoptedTraits: z12.array(AdoptedTraitRecordSchema).default([]),
|
|
2324
|
+
declinedProposals: z12.array(DeclinedProposalRecordSchema).default([]),
|
|
2325
|
+
unlockedCosmetics: z12.array(z12.object({ id: z12.string(), at: z12.string() })).default([])
|
|
2187
2326
|
});
|
|
2188
|
-
var GezelGrowthSummarySchema =
|
|
2189
|
-
level:
|
|
2327
|
+
var GezelGrowthSummarySchema = z12.object({
|
|
2328
|
+
level: z12.number().int().min(1),
|
|
2190
2329
|
/** True when a level-up is waiting for the user's choice. */
|
|
2191
|
-
pending:
|
|
2330
|
+
pending: z12.boolean().optional()
|
|
2192
2331
|
});
|
|
2193
2332
|
|
|
2194
2333
|
// src/schemas/model-tuning.ts
|
|
2195
|
-
import { z as
|
|
2196
|
-
var DrySamplerSchema =
|
|
2197
|
-
multiplier:
|
|
2198
|
-
base:
|
|
2199
|
-
allowedLength:
|
|
2334
|
+
import { z as z13 } from "zod";
|
|
2335
|
+
var DrySamplerSchema = z13.object({
|
|
2336
|
+
multiplier: z13.number().min(0).max(5).describe("DRY penalty strength. 0 disables. 0.8 is a reasonable default."),
|
|
2337
|
+
base: z13.number().min(0).max(5).optional().describe("Base of the exponential penalty for repeated tokens. Default 1.75."),
|
|
2338
|
+
allowedLength: z13.number().int().min(0).max(64).optional().describe("Minimum n-gram length before DRY kicks in. Default 2.")
|
|
2200
2339
|
}).describe("DRY anti-repetition sampler (llama.cpp only).");
|
|
2201
|
-
var XtcSamplerSchema =
|
|
2202
|
-
probability:
|
|
2203
|
-
threshold:
|
|
2340
|
+
var XtcSamplerSchema = z13.object({
|
|
2341
|
+
probability: z13.number().min(0).max(1).describe("Probability of triggering XTC on any given step."),
|
|
2342
|
+
threshold: z13.number().min(0).max(1).describe("Minimum top-token probability for XTC to fire.")
|
|
2204
2343
|
}).describe("XTC sampler (llama.cpp only).");
|
|
2205
|
-
var SamplingBlockSchema =
|
|
2206
|
-
temperature:
|
|
2207
|
-
topP:
|
|
2208
|
-
topK:
|
|
2209
|
-
minP:
|
|
2210
|
-
maxTokens:
|
|
2211
|
-
seed:
|
|
2212
|
-
repetitionPenalty:
|
|
2213
|
-
repetitionContext:
|
|
2214
|
-
frequencyPenalty:
|
|
2215
|
-
presencePenalty:
|
|
2344
|
+
var SamplingBlockSchema = z13.object({
|
|
2345
|
+
temperature: z13.number().min(0).max(2).optional().describe("Sampling temperature. 0 = greedy. Most reasoning models want 0.6\u20131.0."),
|
|
2346
|
+
topP: z13.number().min(0).max(1).optional().describe("Nucleus sampling. 0.95 is the common default for Qwen, Gemma, Nemotron."),
|
|
2347
|
+
topK: z13.number().int().min(0).max(1e3).optional().describe("Top-k cutoff. 20 for Qwen think, 64 for Gemma, 1 for greedy-on-instruct."),
|
|
2348
|
+
minP: z13.number().min(0).max(1).optional().describe("Min-p cutoff (llama.cpp / MLX / Ollama). Qwen recommends 0."),
|
|
2349
|
+
maxTokens: z13.number().int().positive().optional().describe("Per-turn output token cap. Maps to num_predict / max_tokens / n_predict."),
|
|
2350
|
+
seed: z13.number().int().optional().describe("RNG seed. Unset / negative = random. Best-effort determinism on cloud."),
|
|
2351
|
+
repetitionPenalty: z13.number().min(0).max(3).optional().describe("Local engines (Ollama / llama.cpp / MLX): repeat_penalty. 1.0 = off, 1.1 = mild."),
|
|
2352
|
+
repetitionContext: z13.number().int().positive().optional().describe("Local engines: window size for repetition penalty (`repeat_last_n`)."),
|
|
2353
|
+
frequencyPenalty: z13.number().min(-2).max(2).optional().describe("Cloud (OpenAI) and Ollama / llama.cpp: penalize repeated tokens by frequency."),
|
|
2354
|
+
presencePenalty: z13.number().min(-2).max(2).optional().describe("Cloud (OpenAI) and Ollama / llama.cpp: penalize any reused token."),
|
|
2216
2355
|
dry: DrySamplerSchema.optional(),
|
|
2217
2356
|
xtc: XtcSamplerSchema.optional()
|
|
2218
2357
|
}).describe("Sampling parameters applied per-request.");
|
|
2219
|
-
var ReasoningBlockSchema =
|
|
2220
|
-
effort:
|
|
2358
|
+
var ReasoningBlockSchema = z13.object({
|
|
2359
|
+
effort: z13.enum(["low", "medium", "high"]).optional().describe(
|
|
2221
2360
|
"Cloud reasoning effort. Maps to OpenAI `reasoning.effort` and Anthropic `thinking.budget_tokens` tiers."
|
|
2222
2361
|
),
|
|
2223
|
-
thinkingBudget:
|
|
2362
|
+
thinkingBudget: z13.number().int().positive().optional().describe(
|
|
2224
2363
|
"Explicit thinking-token budget (Anthropic `thinking.budget_tokens`, Nemotron `reasoning_budget`). Wins over `effort` when both set."
|
|
2225
2364
|
),
|
|
2226
|
-
enableThinking:
|
|
2365
|
+
enableThinking: z13.boolean().optional().describe(
|
|
2227
2366
|
"Chat-template toggle for dual-mode models (Qwen3+, Nemotron Nano/Super). Implicit on cloud thinking models."
|
|
2228
2367
|
),
|
|
2229
|
-
templateKwargs:
|
|
2368
|
+
templateKwargs: z13.record(z13.string(), z13.union([z13.string(), z13.number(), z13.boolean()])).optional().describe(
|
|
2230
2369
|
"Chat-template variables that drive this model's reasoning depth, forwarded verbatim as `chat_template_kwargs` on local engines. The names are the model's own \u2014 GPT-OSS reads `reasoning_effort`, Muse Glimmer reads `reasoning_strength` (low|medium|high|xhigh) \u2014 so the manifest declares them rather than the runtime guessing. Lives under `reasoning` (not `engine`) because depth is a per-request choice a tuning profile overrides: `thinking-coding` can ask for xhigh while `instruct` asks for low. Cloud providers ignore it; use `reasoning.effort` there."
|
|
2231
2370
|
)
|
|
2232
2371
|
}).describe("Reasoning controls.");
|
|
2233
|
-
var StructuredOutputSchema =
|
|
2234
|
-
responseFormat:
|
|
2235
|
-
jsonSchema:
|
|
2236
|
-
grammar:
|
|
2372
|
+
var StructuredOutputSchema = z13.object({
|
|
2373
|
+
responseFormat: z13.enum(["text", "json_object"]).optional().describe("Output mode. `text` = freeform (default). `json_object` = enforce JSON."),
|
|
2374
|
+
jsonSchema: z13.unknown().optional().describe("Pin output to a JSON Schema (OpenAI strict mode, llama.cpp --json-schema)."),
|
|
2375
|
+
grammar: z13.string().optional().describe("llama.cpp GBNF grammar. Last-resort structured-output knob.")
|
|
2237
2376
|
}).describe("Structured-output controls.");
|
|
2238
|
-
var PromptTagsSchema =
|
|
2239
|
-
enableThinkingTag:
|
|
2240
|
-
disableThinkingTag:
|
|
2377
|
+
var PromptTagsSchema = z13.object({
|
|
2378
|
+
enableThinkingTag: z13.string().optional().describe("User-prompt tag that enables thinking for this turn (e.g. `/think`)."),
|
|
2379
|
+
disableThinkingTag: z13.string().optional().describe("User-prompt tag that disables thinking for this turn (e.g. `/no_think`).")
|
|
2241
2380
|
}).describe("Per-turn reasoning toggle tags.");
|
|
2242
|
-
var LlamaCppEngineConfigSchema =
|
|
2243
|
-
nGpuLayers:
|
|
2244
|
-
cpuMoe:
|
|
2245
|
-
nCpuMoe:
|
|
2246
|
-
cacheReuse:
|
|
2381
|
+
var LlamaCppEngineConfigSchema = z13.object({
|
|
2382
|
+
nGpuLayers: z13.number().int().min(-1).optional().describe("`--n-gpu-layers` override. -1 = all. Unset = b9843 `auto`/`--fit`."),
|
|
2383
|
+
cpuMoe: z13.boolean().optional().describe("`--cpu-moe`: keep ALL MoE experts in system RAM (attention/dense on GPU)."),
|
|
2384
|
+
nCpuMoe: z13.number().int().min(0).optional().describe("`--n-cpu-moe N`: keep the first N layers\u2019 MoE experts in RAM. Partial split."),
|
|
2385
|
+
cacheReuse: z13.number().int().min(0).optional().describe(
|
|
2247
2386
|
"`--cache-reuse N` prefix-KV reuse chunk. 0 = disable. Unset inherits the global default."
|
|
2248
2387
|
),
|
|
2249
|
-
swaFull:
|
|
2250
|
-
flashAttn:
|
|
2251
|
-
ubatchSize:
|
|
2252
|
-
contextSize:
|
|
2388
|
+
swaFull: z13.boolean().optional().describe("`--swa-full`: full-size SWA cache (Gemma family)."),
|
|
2389
|
+
flashAttn: z13.enum(["on", "off", "auto"]).optional().describe("`--flash-attn` mode override for this model."),
|
|
2390
|
+
ubatchSize: z13.number().int().positive().optional().describe("`--ubatch-size` (inner microbatch) override for this model."),
|
|
2391
|
+
contextSize: z13.number().int().positive().optional().describe(
|
|
2253
2392
|
"Per-turn context ceiling (tokens) this model launches with. Capped by GGUF train ctx."
|
|
2254
2393
|
),
|
|
2255
|
-
chatTemplate:
|
|
2394
|
+
chatTemplate: z13.string().min(1).optional().describe(
|
|
2256
2395
|
"`--chat-template` override for GGUFs whose embedded Jinja template is incompatible with llama.cpp tool parsing."
|
|
2257
2396
|
),
|
|
2258
|
-
threads:
|
|
2259
|
-
batchSize:
|
|
2260
|
-
spec:
|
|
2261
|
-
type:
|
|
2397
|
+
threads: z13.number().int().positive().optional().describe("`--threads` override."),
|
|
2398
|
+
batchSize: z13.number().int().positive().optional().describe("`--batch-size` override."),
|
|
2399
|
+
spec: z13.object({
|
|
2400
|
+
type: z13.enum([
|
|
2262
2401
|
"none",
|
|
2263
2402
|
"draft-mtp",
|
|
2264
2403
|
"draft-eagle3",
|
|
@@ -2270,24 +2409,24 @@ var LlamaCppEngineConfigSchema = z12.object({
|
|
|
2270
2409
|
"ngram-map-k4v",
|
|
2271
2410
|
"ngram-cache"
|
|
2272
2411
|
]).optional().describe("`--spec-type` speculative-decoding mode for this model."),
|
|
2273
|
-
mtp:
|
|
2412
|
+
mtp: z13.boolean().optional().describe(
|
|
2274
2413
|
"VERIFIED capability metadata: this model\u2019s target or companion GGUF carries MTP tensors. Does not enable `draft-mtp` by itself."
|
|
2275
2414
|
),
|
|
2276
|
-
draftModelId:
|
|
2277
|
-
nMax:
|
|
2415
|
+
draftModelId: z13.string().optional().describe("Catalog id / path of the draft model for `draft-simple`."),
|
|
2416
|
+
nMax: z13.number().int().positive().optional().describe("`--spec-draft-n-max`: tokens drafted per step.")
|
|
2278
2417
|
}).optional().describe("Speculative-decoding config for this model.")
|
|
2279
2418
|
}).describe("Per-model llama.cpp launch-flag defaults (engine-level, applied at model load).");
|
|
2280
|
-
var EngineConfigSchema =
|
|
2419
|
+
var EngineConfigSchema = z13.object({
|
|
2281
2420
|
llamaCpp: LlamaCppEngineConfigSchema.optional()
|
|
2282
2421
|
}).describe("Per-model engine launch-flag defaults, keyed by engine.");
|
|
2283
|
-
var ChatModelTuningBaseSchema =
|
|
2422
|
+
var ChatModelTuningBaseSchema = z13.object({
|
|
2284
2423
|
sampling: SamplingBlockSchema.optional(),
|
|
2285
2424
|
samplingWhenThinking: SamplingBlockSchema.optional().describe(
|
|
2286
2425
|
"Sparse override of `sampling` applied when the runtime determines reasoning is engaged. Used by Qwen3+ (different sampling for /think mode) and Nemotron Nano (different sampling for thinking vs instruct)."
|
|
2287
2426
|
),
|
|
2288
2427
|
reasoning: ReasoningBlockSchema.optional(),
|
|
2289
2428
|
output: StructuredOutputSchema.optional(),
|
|
2290
|
-
toolChoice:
|
|
2429
|
+
toolChoice: z13.enum(["auto", "required", "none"]).optional().describe(
|
|
2291
2430
|
"Tool selection mode (cloud + llama.cpp + MLX). `auto` lets the model decide; `required` forces a tool call this turn; `none` disables tools."
|
|
2292
2431
|
),
|
|
2293
2432
|
promptTags: PromptTagsSchema.optional()
|
|
@@ -2296,16 +2435,16 @@ var ChatModelTuningSchema = ChatModelTuningBaseSchema.extend({
|
|
|
2296
2435
|
engine: EngineConfigSchema.optional().describe(
|
|
2297
2436
|
"Per-model ENGINE launch-flag defaults (llama.cpp `--n-gpu-layers`, `--cpu-moe`, `--spec-type`, \u2026). Applied once at model load, not per request \u2014 so it lives on the top-level tuning object, not inside per-request `profiles`."
|
|
2298
2437
|
),
|
|
2299
|
-
profiles:
|
|
2438
|
+
profiles: z13.record(TuningProfileIdSchema, ChatModelTuningBaseSchema.partial()).optional().describe(
|
|
2300
2439
|
"Named tuning presets this model implements. Gezel frontmatter `tuningProfile` selects one; the resolver applies the profile as a layer between installDefault and catalog base. Missing requested profiles walk the canonical fallback chain."
|
|
2301
2440
|
)
|
|
2302
2441
|
}).describe("Per-model sampling, reasoning, and output defaults.");
|
|
2303
2442
|
|
|
2304
2443
|
// src/schemas/question.ts
|
|
2305
|
-
import { z as
|
|
2444
|
+
import { z as z15 } from "zod";
|
|
2306
2445
|
|
|
2307
2446
|
// src/schemas/npm-package.ts
|
|
2308
|
-
import { z as
|
|
2447
|
+
import { z as z14 } from "zod";
|
|
2309
2448
|
var NPM_NAME_SEGMENT = /^[a-z0-9](?:[a-z0-9._~-]*[a-z0-9])?$/;
|
|
2310
2449
|
var SEMVER_NUMBER = String.raw`(?:0|[1-9]\d*)`;
|
|
2311
2450
|
var SEMVER_PART = String.raw`(?:${SEMVER_NUMBER}|[xX*])`;
|
|
@@ -2337,36 +2476,41 @@ function isValidNpmRegistryVersion(value) {
|
|
|
2337
2476
|
return atoms.length > 0 && atoms.every((atom) => SEMVER_ATOM.test(atom));
|
|
2338
2477
|
});
|
|
2339
2478
|
}
|
|
2340
|
-
var NpmPackageNameSchema =
|
|
2479
|
+
var NpmPackageNameSchema = z14.string().refine(isValidNpmPackageName, {
|
|
2341
2480
|
message: "must be a lowercase npm registry package name (for example zod or @types/node)"
|
|
2342
2481
|
});
|
|
2343
|
-
var NpmRegistryVersionSchema =
|
|
2482
|
+
var NpmRegistryVersionSchema = z14.string().refine(isValidNpmRegistryVersion, {
|
|
2344
2483
|
message: "must be a registry dist-tag or semver range"
|
|
2345
2484
|
});
|
|
2346
|
-
var NpmRegistryPackageRequestSchema =
|
|
2485
|
+
var NpmRegistryPackageRequestSchema = z14.object({
|
|
2347
2486
|
package: NpmPackageNameSchema,
|
|
2348
2487
|
version: NpmRegistryVersionSchema.optional()
|
|
2349
2488
|
}).strict();
|
|
2350
2489
|
|
|
2351
2490
|
// src/schemas/question.ts
|
|
2352
|
-
var NpmInstallApprovalDecisionSchema =
|
|
2491
|
+
var NpmInstallApprovalDecisionSchema = z15.object({
|
|
2353
2492
|
package: NpmPackageNameSchema,
|
|
2354
2493
|
version: NpmRegistryVersionSchema,
|
|
2355
|
-
decision:
|
|
2494
|
+
decision: z15.enum(["install", "always", "decline"])
|
|
2356
2495
|
});
|
|
2357
|
-
var QuestionAnswerSchema =
|
|
2496
|
+
var QuestionAnswerSchema = z15.object({
|
|
2358
2497
|
/** Indices into `choices` the user picked. Empty when only write-in. */
|
|
2359
|
-
selectedChoices:
|
|
2498
|
+
selectedChoices: z15.array(z15.number().int().min(0)).optional(),
|
|
2360
2499
|
/** Free-text the user typed. Empty when they only clicked choices. */
|
|
2361
|
-
writeIn:
|
|
2500
|
+
writeIn: z15.string().optional(),
|
|
2362
2501
|
/**
|
|
2363
2502
|
* Set when the user explicitly dismissed BUT wants the gezel to
|
|
2364
2503
|
* proceed anyway with sensible defaults. Triggers a synthetic
|
|
2365
2504
|
* follow-up turn with a `[The user wants you to proceed…]` seed
|
|
2366
2505
|
* so the gezel knows to make decisions on the user's behalf.
|
|
2367
|
-
*
|
|
2506
|
+
*
|
|
2507
|
+
* The plain question card no longer offers this — a "decide for me"
|
|
2508
|
+
* button next to a question the gezel is blocked on invited the one
|
|
2509
|
+
* answer that teaches it nothing. It stays on the approval cards that
|
|
2510
|
+
* mean it literally (declining an image generation, an npm install,
|
|
2511
|
+
* a schedule) and on the permission broker's dismissal path.
|
|
2368
2512
|
*/
|
|
2369
|
-
declined:
|
|
2513
|
+
declined: z15.boolean().optional(),
|
|
2370
2514
|
/**
|
|
2371
2515
|
* Set when the user just wants the question to go away — no
|
|
2372
2516
|
* follow-up turn, no work done, nothing for the gezel to act on.
|
|
@@ -2375,97 +2519,112 @@ var QuestionAnswerSchema = z14.object({
|
|
|
2375
2519
|
* from `declined` so the model never sees a "user wants defaults"
|
|
2376
2520
|
* signal that the user didn't intend. UI label: "Skip".
|
|
2377
2521
|
*/
|
|
2378
|
-
silentSkip:
|
|
2522
|
+
silentSkip: z15.boolean().optional(),
|
|
2379
2523
|
/**
|
|
2380
2524
|
* Per-package decisions for `npm-install-approval` questions. When
|
|
2381
2525
|
* set, the answer handler installs / always-allows / declines each
|
|
2382
2526
|
* package and emits a single follow-up summary into the session.
|
|
2383
2527
|
*/
|
|
2384
|
-
npmInstallDecisions:
|
|
2385
|
-
at:
|
|
2528
|
+
npmInstallDecisions: z15.array(NpmInstallApprovalDecisionSchema).optional(),
|
|
2529
|
+
at: z15.string()
|
|
2386
2530
|
});
|
|
2387
|
-
var NpmInstallApprovalPackageSchema =
|
|
2531
|
+
var NpmInstallApprovalPackageSchema = z15.object({
|
|
2388
2532
|
package: NpmPackageNameSchema,
|
|
2389
2533
|
version: NpmRegistryVersionSchema
|
|
2390
2534
|
});
|
|
2391
|
-
var CommandApprovalScopeSchema =
|
|
2392
|
-
var CommandApprovalInputFileSchema =
|
|
2535
|
+
var CommandApprovalScopeSchema = z15.enum(["script", "npx"]);
|
|
2536
|
+
var CommandApprovalInputFileSchema = z15.object({
|
|
2393
2537
|
/** Workspace-relative, slash-normalized path shown in the approval prompt. */
|
|
2394
|
-
path:
|
|
2395
|
-
sha256:
|
|
2538
|
+
path: z15.string().min(1),
|
|
2539
|
+
sha256: z15.string().regex(/^[a-f0-9]{64}$/)
|
|
2396
2540
|
});
|
|
2397
|
-
var CommandApprovalIntentSchema =
|
|
2398
|
-
kind:
|
|
2541
|
+
var CommandApprovalIntentSchema = z15.object({
|
|
2542
|
+
kind: z15.literal("command-approval"),
|
|
2399
2543
|
scope: CommandApprovalScopeSchema,
|
|
2400
|
-
name:
|
|
2401
|
-
body:
|
|
2402
|
-
args:
|
|
2403
|
-
inputFiles:
|
|
2404
|
-
});
|
|
2405
|
-
var ToolPermissionIntentSchema =
|
|
2406
|
-
kind:
|
|
2407
|
-
toolName:
|
|
2408
|
-
toolInput:
|
|
2409
|
-
});
|
|
2410
|
-
var
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2544
|
+
name: z15.string().min(1),
|
|
2545
|
+
body: z15.string().optional(),
|
|
2546
|
+
args: z15.array(z15.string()).optional(),
|
|
2547
|
+
inputFiles: z15.array(CommandApprovalInputFileSchema).max(128).optional()
|
|
2548
|
+
});
|
|
2549
|
+
var ToolPermissionIntentSchema = z15.object({
|
|
2550
|
+
kind: z15.literal("tool-permission"),
|
|
2551
|
+
toolName: z15.string(),
|
|
2552
|
+
toolInput: z15.record(z15.string(), z15.unknown())
|
|
2553
|
+
});
|
|
2554
|
+
var ClaudeUserQuestionOptionSchema = z15.object({
|
|
2555
|
+
label: z15.string().min(1),
|
|
2556
|
+
description: z15.string().optional()
|
|
2557
|
+
});
|
|
2558
|
+
var ClaudeUserQuestionIntentSchema = z15.object({
|
|
2559
|
+
kind: z15.literal("claude-user-question"),
|
|
2560
|
+
/** The CLI's short topic chip for the question (e.g. "Gate block"). */
|
|
2561
|
+
header: z15.string().optional(),
|
|
2562
|
+
/** Options with descriptions; labels mirror the Question's `choices`. */
|
|
2563
|
+
options: z15.array(ClaudeUserQuestionOptionSchema),
|
|
2564
|
+
/** 0-based position within the originating multi-question call. */
|
|
2565
|
+
questionIndex: z15.number().int().min(0),
|
|
2566
|
+
/** Total questions in the originating call (cards appear sequentially). */
|
|
2567
|
+
questionCount: z15.number().int().min(1)
|
|
2568
|
+
});
|
|
2569
|
+
var ToolsetInstallApprovalIntentSchema = z15.object({
|
|
2570
|
+
kind: z15.literal("toolset-install-approval"),
|
|
2571
|
+
toolsetId: z15.string(),
|
|
2572
|
+
sourceId: z15.string(),
|
|
2573
|
+
version: z15.string(),
|
|
2574
|
+
targetProjectId: z15.string(),
|
|
2575
|
+
craftbookId: z15.string()
|
|
2576
|
+
});
|
|
2577
|
+
var ImageGenerationApprovalIntentSchema = z15.object({
|
|
2578
|
+
kind: z15.literal("image-generation-approval"),
|
|
2579
|
+
provider: z15.string(),
|
|
2580
|
+
model: z15.string(),
|
|
2422
2581
|
/** Truncated prompt the model is about to send. Surfaced verbatim. */
|
|
2423
|
-
promptPreview:
|
|
2582
|
+
promptPreview: z15.string(),
|
|
2424
2583
|
/** Resolved generation size, e.g. '2K 16:9' or '1024x1024'. Optional. */
|
|
2425
|
-
estimatedSize:
|
|
2584
|
+
estimatedSize: z15.string().optional()
|
|
2426
2585
|
});
|
|
2427
|
-
var VideoGenerationApprovalIntentSchema =
|
|
2428
|
-
kind:
|
|
2429
|
-
provider:
|
|
2430
|
-
model:
|
|
2431
|
-
promptPreview:
|
|
2586
|
+
var VideoGenerationApprovalIntentSchema = z15.object({
|
|
2587
|
+
kind: z15.literal("video-generation-approval"),
|
|
2588
|
+
provider: z15.string(),
|
|
2589
|
+
model: z15.string(),
|
|
2590
|
+
promptPreview: z15.string(),
|
|
2432
2591
|
/** Resolved clip shape, e.g. '704×480 · 97f · 24fps'. Optional. */
|
|
2433
|
-
estimatedSize:
|
|
2592
|
+
estimatedSize: z15.string().optional()
|
|
2434
2593
|
});
|
|
2435
|
-
var ScheduleApprovalIntentSchema =
|
|
2436
|
-
kind:
|
|
2437
|
-
typeId:
|
|
2438
|
-
craftbookId:
|
|
2594
|
+
var ScheduleApprovalIntentSchema = z15.object({
|
|
2595
|
+
kind: z15.literal("schedule-approval"),
|
|
2596
|
+
typeId: z15.string(),
|
|
2597
|
+
craftbookId: z15.string(),
|
|
2439
2598
|
/**
|
|
2440
2599
|
* Recurrence flavor. Absent → 'scheduled' (every question written
|
|
2441
2600
|
* before this field existed is a cron schedule). 'night-shift' hosts
|
|
2442
2601
|
* run inside the Night Shift window instead of on a user-visible cron;
|
|
2443
2602
|
* the card copy switches accordingly.
|
|
2444
2603
|
*/
|
|
2445
|
-
runMode:
|
|
2604
|
+
runMode: z15.enum(["scheduled", "night-shift"]).optional(),
|
|
2446
2605
|
/**
|
|
2447
2606
|
* 5-field cron expression (UTC). Surfaced verbatim on the card for
|
|
2448
2607
|
* 'scheduled' hosts; for 'night-shift' hosts it is the internal
|
|
2449
2608
|
* heartbeat and the card shows the window instead.
|
|
2450
2609
|
*/
|
|
2451
|
-
cron:
|
|
2452
|
-
overlap:
|
|
2610
|
+
cron: z15.string(),
|
|
2611
|
+
overlap: z15.enum(["skip", "queue", "concurrent"]).optional()
|
|
2453
2612
|
});
|
|
2454
|
-
var NightShiftReviewIntentSchema =
|
|
2455
|
-
kind:
|
|
2613
|
+
var NightShiftReviewIntentSchema = z15.object({
|
|
2614
|
+
kind: z15.literal("night-shift-review"),
|
|
2456
2615
|
/** The window's day key (see `nightShiftWindowKey`). */
|
|
2457
|
-
windowKey:
|
|
2458
|
-
tasksCompleted:
|
|
2459
|
-
reports:
|
|
2460
|
-
|
|
2461
|
-
projectId:
|
|
2462
|
-
path:
|
|
2463
|
-
title:
|
|
2464
|
-
actionCount:
|
|
2616
|
+
windowKey: z15.string(),
|
|
2617
|
+
tasksCompleted: z15.number(),
|
|
2618
|
+
reports: z15.array(
|
|
2619
|
+
z15.object({
|
|
2620
|
+
projectId: z15.string(),
|
|
2621
|
+
path: z15.string(),
|
|
2622
|
+
title: z15.string().optional(),
|
|
2623
|
+
actionCount: z15.number()
|
|
2465
2624
|
})
|
|
2466
2625
|
)
|
|
2467
2626
|
});
|
|
2468
|
-
var TaskPausedReasonSchema =
|
|
2627
|
+
var TaskPausedReasonSchema = z15.enum([
|
|
2469
2628
|
"gate_exhausted",
|
|
2470
2629
|
"gate_plateau",
|
|
2471
2630
|
"gate_unsatisfiable",
|
|
@@ -2473,25 +2632,26 @@ var TaskPausedReasonSchema = z14.enum([
|
|
|
2473
2632
|
"step_stalled",
|
|
2474
2633
|
"budget_exhausted"
|
|
2475
2634
|
]);
|
|
2476
|
-
var TaskPausedIntentSchema =
|
|
2477
|
-
kind:
|
|
2635
|
+
var TaskPausedIntentSchema = z15.object({
|
|
2636
|
+
kind: z15.literal("task-paused"),
|
|
2478
2637
|
/** `projectId/num` of the paused task — the dedup key. */
|
|
2479
|
-
taskRef:
|
|
2480
|
-
stepId:
|
|
2638
|
+
taskRef: z15.string(),
|
|
2639
|
+
stepId: z15.string().optional(),
|
|
2481
2640
|
reason: TaskPausedReasonSchema
|
|
2482
2641
|
});
|
|
2483
|
-
var QuestionIntentSchema =
|
|
2484
|
-
|
|
2485
|
-
kind:
|
|
2642
|
+
var QuestionIntentSchema = z15.discriminatedUnion("kind", [
|
|
2643
|
+
z15.object({
|
|
2644
|
+
kind: z15.literal("npm-install-approval"),
|
|
2486
2645
|
/**
|
|
2487
2646
|
* Packages that need approval. Always at least one; multiple when
|
|
2488
2647
|
* the gezel batched an install call (encouraged) or when we merged
|
|
2489
2648
|
* a later request into the same pending question for dedup.
|
|
2490
2649
|
*/
|
|
2491
|
-
packages:
|
|
2650
|
+
packages: z15.array(NpmInstallApprovalPackageSchema).min(1)
|
|
2492
2651
|
}),
|
|
2493
2652
|
CommandApprovalIntentSchema,
|
|
2494
2653
|
ToolPermissionIntentSchema,
|
|
2654
|
+
ClaudeUserQuestionIntentSchema,
|
|
2495
2655
|
ToolsetInstallApprovalIntentSchema,
|
|
2496
2656
|
ImageGenerationApprovalIntentSchema,
|
|
2497
2657
|
VideoGenerationApprovalIntentSchema,
|
|
@@ -2499,61 +2659,61 @@ var QuestionIntentSchema = z14.discriminatedUnion("kind", [
|
|
|
2499
2659
|
NightShiftReviewIntentSchema,
|
|
2500
2660
|
TaskPausedIntentSchema
|
|
2501
2661
|
]);
|
|
2502
|
-
var QuestionSchema =
|
|
2503
|
-
id:
|
|
2504
|
-
projectId:
|
|
2505
|
-
gezelId:
|
|
2506
|
-
sessionId:
|
|
2662
|
+
var QuestionSchema = z15.object({
|
|
2663
|
+
id: z15.string(),
|
|
2664
|
+
projectId: z15.string(),
|
|
2665
|
+
gezelId: z15.string(),
|
|
2666
|
+
sessionId: z15.string(),
|
|
2507
2667
|
/** Body of the question — supports markdown. */
|
|
2508
|
-
prompt:
|
|
2668
|
+
prompt: z15.string().min(1),
|
|
2509
2669
|
/** Optional preset choices. Empty / omitted => write-in only. */
|
|
2510
|
-
choices:
|
|
2670
|
+
choices: z15.array(z15.string()).max(20).optional(),
|
|
2511
2671
|
/** Whether the user can also type a write-in alongside choices. Default true. */
|
|
2512
|
-
allowWriteIn:
|
|
2672
|
+
allowWriteIn: z15.boolean().optional(),
|
|
2513
2673
|
/** Whether multiple choices may be selected. Default false. */
|
|
2514
|
-
multiSelect:
|
|
2674
|
+
multiSelect: z15.boolean().optional(),
|
|
2515
2675
|
/**
|
|
2516
2676
|
* Approval-flow attachment: a task this question is *about*. Stored in
|
|
2517
2677
|
* `projectId/num` form so existing parsing helpers work. The UI shows
|
|
2518
2678
|
* the task title + status above the prompt and offers an "Open task"
|
|
2519
2679
|
* link.
|
|
2520
2680
|
*/
|
|
2521
|
-
taskRef:
|
|
2681
|
+
taskRef: z15.string().optional(),
|
|
2522
2682
|
/**
|
|
2523
2683
|
* Approval-flow attachment: a document this question is *about*.
|
|
2524
2684
|
* Project-relative path when `projectId` is set, otherwise into the
|
|
2525
2685
|
* global `~/.gezel/documents/` library. The UI renders a collapsed
|
|
2526
2686
|
* preview + "Open document" link.
|
|
2527
2687
|
*/
|
|
2528
|
-
documentPath:
|
|
2688
|
+
documentPath: z15.string().optional(),
|
|
2529
2689
|
/**
|
|
2530
2690
|
* Service-created specialized-question marker (see `QuestionIntent`
|
|
2531
2691
|
* for context). Absent for plain user-facing questions asked via
|
|
2532
2692
|
* the `ask_user_question` MCP tool.
|
|
2533
2693
|
*/
|
|
2534
2694
|
intent: QuestionIntentSchema.optional(),
|
|
2535
|
-
createdAt:
|
|
2695
|
+
createdAt: z15.string(),
|
|
2536
2696
|
/** Set once the user has answered (or declined). */
|
|
2537
2697
|
answer: QuestionAnswerSchema.optional()
|
|
2538
2698
|
});
|
|
2539
2699
|
|
|
2540
2700
|
// src/schemas/recognition.ts
|
|
2541
|
-
import { z as
|
|
2542
|
-
var ImageExifSchema =
|
|
2543
|
-
make:
|
|
2544
|
-
model:
|
|
2545
|
-
lensModel:
|
|
2546
|
-
dateTimeOriginal:
|
|
2547
|
-
orientation:
|
|
2548
|
-
software:
|
|
2549
|
-
imageDescription:
|
|
2550
|
-
});
|
|
2551
|
-
var ImageStaticMetaSchema =
|
|
2552
|
-
format:
|
|
2553
|
-
width:
|
|
2554
|
-
height:
|
|
2555
|
-
byteLength:
|
|
2556
|
-
sha256:
|
|
2701
|
+
import { z as z16 } from "zod";
|
|
2702
|
+
var ImageExifSchema = z16.object({
|
|
2703
|
+
make: z16.string().optional(),
|
|
2704
|
+
model: z16.string().optional(),
|
|
2705
|
+
lensModel: z16.string().optional(),
|
|
2706
|
+
dateTimeOriginal: z16.string().optional(),
|
|
2707
|
+
orientation: z16.number().int().min(1).max(8).optional(),
|
|
2708
|
+
software: z16.string().optional(),
|
|
2709
|
+
imageDescription: z16.string().optional()
|
|
2710
|
+
});
|
|
2711
|
+
var ImageStaticMetaSchema = z16.object({
|
|
2712
|
+
format: z16.enum(["png", "jpeg", "gif", "webp", "svg", "unknown"]),
|
|
2713
|
+
width: z16.number().int().positive().optional(),
|
|
2714
|
+
height: z16.number().int().positive().optional(),
|
|
2715
|
+
byteLength: z16.number().int().nonnegative(),
|
|
2716
|
+
sha256: z16.string().regex(/^[a-f0-9]{64}$/),
|
|
2557
2717
|
/**
|
|
2558
2718
|
* PNG `tEXt`/`iTXt`/`zTXt` keyword→value pairs. Generation provenance lives
|
|
2559
2719
|
* here (A1111 writes `parameters`, ComfyUI writes `prompt`/`workflow`) and
|
|
@@ -2562,153 +2722,171 @@ var ImageStaticMetaSchema = z15.object({
|
|
|
2562
2722
|
* Attacker-controlled: anyone can author a PNG whose `Description` chunk
|
|
2563
2723
|
* reads "Ignore previous instructions". Renderers MUST fence and cap this.
|
|
2564
2724
|
*/
|
|
2565
|
-
pngText:
|
|
2725
|
+
pngText: z16.record(z16.string(), z16.string()).optional(),
|
|
2566
2726
|
exif: ImageExifSchema.optional(),
|
|
2567
2727
|
/** Withheld from every prompt. See the schema doc above. */
|
|
2568
|
-
gps:
|
|
2728
|
+
gps: z16.object({ lat: z16.number(), lon: z16.number() }).optional(),
|
|
2569
2729
|
/** True when the file carried location data we deliberately dropped. */
|
|
2570
|
-
gpsRedacted:
|
|
2730
|
+
gpsRedacted: z16.boolean().optional(),
|
|
2571
2731
|
/**
|
|
2572
2732
|
* Heuristic from dimensions, format, and metadata — drives `auto` mode
|
|
2573
2733
|
* selection without paying a classifier call.
|
|
2574
2734
|
*/
|
|
2575
|
-
likelyScreenshot:
|
|
2735
|
+
likelyScreenshot: z16.boolean().optional()
|
|
2576
2736
|
});
|
|
2577
|
-
var RecognitionModeSchema =
|
|
2578
|
-
var RecognitionModeRequestSchema =
|
|
2579
|
-
var ImageRecognitionSchema =
|
|
2580
|
-
schemaVersion:
|
|
2581
|
-
sha256:
|
|
2737
|
+
var RecognitionModeSchema = z16.enum(["describe", "ocr", "ui", "extract"]);
|
|
2738
|
+
var RecognitionModeRequestSchema = z16.enum(["auto", "describe", "ocr", "ui", "extract"]);
|
|
2739
|
+
var ImageRecognitionSchema = z16.object({
|
|
2740
|
+
schemaVersion: z16.literal(1),
|
|
2741
|
+
sha256: z16.string().regex(/^[a-f0-9]{64}$/),
|
|
2582
2742
|
meta: ImageStaticMetaSchema,
|
|
2583
|
-
modes:
|
|
2584
|
-
description:
|
|
2585
|
-
ocrText:
|
|
2586
|
-
structured:
|
|
2587
|
-
templateId:
|
|
2588
|
-
data:
|
|
2743
|
+
modes: z16.array(RecognitionModeSchema).min(1),
|
|
2744
|
+
description: z16.string().optional(),
|
|
2745
|
+
ocrText: z16.string().optional(),
|
|
2746
|
+
structured: z16.object({
|
|
2747
|
+
templateId: z16.string().optional(),
|
|
2748
|
+
data: z16.unknown()
|
|
2589
2749
|
}).optional(),
|
|
2590
|
-
engine:
|
|
2591
|
-
modelId:
|
|
2592
|
-
status:
|
|
2593
|
-
failureReason:
|
|
2594
|
-
durationMs:
|
|
2595
|
-
at:
|
|
2750
|
+
engine: z16.enum(["llama-cpp", "mlx", "mock", "none"]),
|
|
2751
|
+
modelId: z16.string(),
|
|
2752
|
+
status: z16.enum(["ok", "partial", "failed", "static-only"]),
|
|
2753
|
+
failureReason: z16.string().optional(),
|
|
2754
|
+
durationMs: z16.number().int().nonnegative(),
|
|
2755
|
+
at: z16.string()
|
|
2596
2756
|
});
|
|
2597
|
-
var MessageImageDigestSchema =
|
|
2757
|
+
var MessageImageDigestSchema = z16.object({
|
|
2598
2758
|
/** The markdown ref exactly as it appears in the message body. */
|
|
2599
|
-
ref:
|
|
2600
|
-
sha256:
|
|
2759
|
+
ref: z16.string(),
|
|
2760
|
+
sha256: z16.string().regex(/^[a-f0-9]{64}$/),
|
|
2601
2761
|
/** Pre-rendered, already capped and fenced-safe. */
|
|
2602
|
-
digest:
|
|
2603
|
-
modelId:
|
|
2604
|
-
modes:
|
|
2605
|
-
status:
|
|
2606
|
-
at:
|
|
2762
|
+
digest: z16.string(),
|
|
2763
|
+
modelId: z16.string(),
|
|
2764
|
+
modes: z16.array(RecognitionModeSchema),
|
|
2765
|
+
status: z16.enum(["ok", "partial", "failed", "static-only"]),
|
|
2766
|
+
at: z16.string()
|
|
2607
2767
|
});
|
|
2608
|
-
var RecognitionRequestSchema =
|
|
2768
|
+
var RecognitionRequestSchema = z16.object({
|
|
2609
2769
|
/** Project-relative artifact path, e.g. `attachments/<uuid>.png`. */
|
|
2610
|
-
artifactPath:
|
|
2611
|
-
data:
|
|
2612
|
-
mimeType:
|
|
2770
|
+
artifactPath: z16.string().min(1).optional(),
|
|
2771
|
+
data: z16.string().min(1).optional(),
|
|
2772
|
+
mimeType: z16.string().optional(),
|
|
2613
2773
|
mode: RecognitionModeRequestSchema.default("auto"),
|
|
2614
2774
|
/** JSON Schema for `extract` mode — fed to llama-server `response_format`. */
|
|
2615
|
-
schema:
|
|
2775
|
+
schema: z16.unknown().optional(),
|
|
2616
2776
|
/** Overrides the configured recognition model for this call. */
|
|
2617
|
-
model:
|
|
2777
|
+
model: z16.string().optional()
|
|
2618
2778
|
});
|
|
2619
|
-
var RecognitionHealthSchema =
|
|
2620
|
-
state:
|
|
2621
|
-
modelId:
|
|
2622
|
-
detail:
|
|
2779
|
+
var RecognitionHealthSchema = z16.object({
|
|
2780
|
+
state: z16.enum(["ok", "no-model", "not-configured", "error"]),
|
|
2781
|
+
modelId: z16.string().optional(),
|
|
2782
|
+
detail: z16.string().optional()
|
|
2623
2783
|
});
|
|
2624
|
-
var RecognitionPullEventSchema =
|
|
2625
|
-
|
|
2626
|
-
type:
|
|
2627
|
-
bytesWritten:
|
|
2628
|
-
totalBytes:
|
|
2784
|
+
var RecognitionPullEventSchema = z16.union([
|
|
2785
|
+
z16.object({
|
|
2786
|
+
type: z16.literal("progress"),
|
|
2787
|
+
bytesWritten: z16.number().int().nonnegative(),
|
|
2788
|
+
totalBytes: z16.number().int().nonnegative().optional()
|
|
2629
2789
|
}),
|
|
2630
|
-
|
|
2631
|
-
|
|
2790
|
+
z16.object({ type: z16.literal("error"), error: z16.string() }),
|
|
2791
|
+
z16.object({ type: z16.literal("done"), id: z16.string() })
|
|
2632
2792
|
]);
|
|
2633
|
-
var RecognitionCatalogEntrySchema =
|
|
2634
|
-
id:
|
|
2635
|
-
name:
|
|
2636
|
-
description:
|
|
2637
|
-
license:
|
|
2638
|
-
approxSizeBytes:
|
|
2639
|
-
recoScore:
|
|
2793
|
+
var RecognitionCatalogEntrySchema = z16.object({
|
|
2794
|
+
id: z16.string(),
|
|
2795
|
+
name: z16.string(),
|
|
2796
|
+
description: z16.string(),
|
|
2797
|
+
license: z16.string(),
|
|
2798
|
+
approxSizeBytes: z16.number().int().nonnegative(),
|
|
2799
|
+
recoScore: z16.number()
|
|
2640
2800
|
});
|
|
2641
|
-
var ListRecognitionCatalogResponseSchema =
|
|
2642
|
-
models:
|
|
2801
|
+
var ListRecognitionCatalogResponseSchema = z16.object({
|
|
2802
|
+
models: z16.array(RecognitionCatalogEntrySchema)
|
|
2643
2803
|
});
|
|
2644
|
-
var InstalledRecognitionModelSchema =
|
|
2645
|
-
id:
|
|
2646
|
-
name:
|
|
2647
|
-
approxSizeBytes:
|
|
2648
|
-
installedAt:
|
|
2649
|
-
weightsPath:
|
|
2650
|
-
mmprojPath:
|
|
2804
|
+
var InstalledRecognitionModelSchema = z16.object({
|
|
2805
|
+
id: z16.string(),
|
|
2806
|
+
name: z16.string(),
|
|
2807
|
+
approxSizeBytes: z16.number().int().nonnegative(),
|
|
2808
|
+
installedAt: z16.string(),
|
|
2809
|
+
weightsPath: z16.string().optional(),
|
|
2810
|
+
mmprojPath: z16.string().optional()
|
|
2651
2811
|
});
|
|
2652
|
-
var ListInstalledRecognitionModelsResponseSchema =
|
|
2653
|
-
models:
|
|
2812
|
+
var ListInstalledRecognitionModelsResponseSchema = z16.object({
|
|
2813
|
+
models: z16.array(InstalledRecognitionModelSchema)
|
|
2814
|
+
});
|
|
2815
|
+
|
|
2816
|
+
// src/schemas/session-lineage.ts
|
|
2817
|
+
import { z as z17 } from "zod";
|
|
2818
|
+
var SessionLinkSchema = z17.object({
|
|
2819
|
+
sessionId: z17.string(),
|
|
2820
|
+
gezelId: z17.string()
|
|
2821
|
+
});
|
|
2822
|
+
var SessionParentSchema = SessionLinkSchema.extend({
|
|
2823
|
+
kind: z17.enum(["delegation", "consultation", "task-entry", "task-handoff"])
|
|
2654
2824
|
});
|
|
2655
2825
|
|
|
2656
2826
|
// src/schemas/session-telemetry.ts
|
|
2657
|
-
import { z as
|
|
2658
|
-
var SessionGpuTaskSchema =
|
|
2827
|
+
import { z as z18 } from "zod";
|
|
2828
|
+
var SessionGpuTaskSchema = z18.enum([
|
|
2659
2829
|
"image_generation",
|
|
2660
2830
|
"video_generation",
|
|
2661
2831
|
"image_recognition"
|
|
2662
2832
|
]);
|
|
2663
|
-
var
|
|
2833
|
+
var SessionTurnPhaseSchema = z18.enum(["preparing", "recall", "provider"]);
|
|
2834
|
+
var SessionTurnTelemetrySchema = z18.object({
|
|
2664
2835
|
/** Epoch ms when the in-flight turn started. */
|
|
2665
|
-
startedAt:
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2836
|
+
startedAt: z18.number(),
|
|
2837
|
+
phase: SessionTurnPhaseSchema,
|
|
2838
|
+
/** Epoch ms when `phase` last changed. */
|
|
2839
|
+
phaseStartedAt: z18.number(),
|
|
2840
|
+
/** Provider requests issued by this user-visible turn, including retries. */
|
|
2841
|
+
providerRequestsStarted: z18.number().int().nonnegative(),
|
|
2842
|
+
streamedContentChars: z18.number().int().nonnegative(),
|
|
2843
|
+
toolCalls: z18.number().int().nonnegative(),
|
|
2844
|
+
fileMutations: z18.number().int().nonnegative()
|
|
2845
|
+
});
|
|
2846
|
+
var SessionTelemetrySchema = z18.object({
|
|
2847
|
+
sessionId: z18.string(),
|
|
2848
|
+
gezelId: z18.string(),
|
|
2849
|
+
projectId: z18.string(),
|
|
2674
2850
|
/** True while a send is currently running for this session. */
|
|
2675
|
-
inflight:
|
|
2676
|
-
turnsStarted:
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2851
|
+
inflight: z18.boolean(),
|
|
2852
|
+
turnsStarted: z18.number().int().nonnegative(),
|
|
2853
|
+
/** Provider requests issued across all turns in this daemon process. */
|
|
2854
|
+
providerRequestsStarted: z18.number().int().nonnegative(),
|
|
2855
|
+
deltaChunks: z18.number().int().nonnegative(),
|
|
2856
|
+
streamedContentChars: z18.number().int().nonnegative(),
|
|
2857
|
+
wirePulses: z18.number().int().nonnegative(),
|
|
2858
|
+
heartbeats: z18.number().int().nonnegative(),
|
|
2859
|
+
enginePhaseEvents: z18.number().int().nonnegative(),
|
|
2682
2860
|
/**
|
|
2683
2861
|
* `engine_phase === 'generating'` transitions — roughly one per completion
|
|
2684
2862
|
* request the engine served (the slot-launch granularity stall logic and
|
|
2685
2863
|
* the eval chatter threshold were calibrated against).
|
|
2686
2864
|
*/
|
|
2687
|
-
generationSpurts:
|
|
2688
|
-
toolCalls:
|
|
2689
|
-
toolArgChars:
|
|
2690
|
-
fileMutations:
|
|
2691
|
-
gpuEvents:
|
|
2865
|
+
generationSpurts: z18.number().int().nonnegative(),
|
|
2866
|
+
toolCalls: z18.number().int().nonnegative(),
|
|
2867
|
+
toolArgChars: z18.number().int().nonnegative(),
|
|
2868
|
+
fileMutations: z18.number().int().nonnegative(),
|
|
2869
|
+
gpuEvents: z18.number().int().nonnegative(),
|
|
2692
2870
|
gpuTaskActive: SessionGpuTaskSchema.nullable(),
|
|
2693
2871
|
/** Epoch ms of the last streamed signal (delta / pulse / heartbeat / phase). */
|
|
2694
|
-
lastStreamActivityAt:
|
|
2695
|
-
lastToolActivityAt:
|
|
2696
|
-
lastMutationAt:
|
|
2697
|
-
lastGpuActivityAt:
|
|
2872
|
+
lastStreamActivityAt: z18.number().nullable(),
|
|
2873
|
+
lastToolActivityAt: z18.number().nullable(),
|
|
2874
|
+
lastMutationAt: z18.number().nullable(),
|
|
2875
|
+
lastGpuActivityAt: z18.number().nullable(),
|
|
2698
2876
|
/** Max of all activity timestamps — "when did ANY progress signal last fire". */
|
|
2699
|
-
lastProgressAt:
|
|
2877
|
+
lastProgressAt: z18.number().nullable(),
|
|
2700
2878
|
/** Counters scoped to the currently-running turn; null between turns. */
|
|
2701
2879
|
currentTurn: SessionTurnTelemetrySchema.nullable()
|
|
2702
2880
|
});
|
|
2703
|
-
var SessionTelemetryListResponseSchema =
|
|
2881
|
+
var SessionTelemetryListResponseSchema = z18.object({
|
|
2704
2882
|
/** Bumped when counter semantics change; consumers gate on it. */
|
|
2705
|
-
version:
|
|
2706
|
-
capturedAt:
|
|
2707
|
-
sessions:
|
|
2883
|
+
version: z18.literal(1),
|
|
2884
|
+
capturedAt: z18.number(),
|
|
2885
|
+
sessions: z18.array(SessionTelemetrySchema)
|
|
2708
2886
|
});
|
|
2709
2887
|
|
|
2710
2888
|
// src/schemas/gezel.ts
|
|
2711
|
-
var ProviderNameSchema =
|
|
2889
|
+
var ProviderNameSchema = z19.enum([
|
|
2712
2890
|
"copilot",
|
|
2713
2891
|
"openai",
|
|
2714
2892
|
"anthropic",
|
|
@@ -2730,27 +2908,27 @@ var ProviderNameSchema = z17.enum([
|
|
|
2730
2908
|
// forward-pass is remoted — so `remote` is NOT a local provider.
|
|
2731
2909
|
"remote"
|
|
2732
2910
|
]);
|
|
2733
|
-
var GezelGenderSchema =
|
|
2734
|
-
var FixedFunctionConfigSchema =
|
|
2911
|
+
var GezelGenderSchema = z19.enum(["male", "female", "non-binary"]);
|
|
2912
|
+
var FixedFunctionConfigSchema = z19.object({
|
|
2735
2913
|
/** MCP tool name to forward to (e.g. `'generate_image'`). */
|
|
2736
|
-
tool:
|
|
2914
|
+
tool: z19.string().min(1),
|
|
2737
2915
|
/** Argument key on the tool that receives the user's message text. */
|
|
2738
|
-
promptKey:
|
|
2916
|
+
promptKey: z19.string().min(1).default("prompt"),
|
|
2739
2917
|
/** Defaults merged into every call; user text on `promptKey` always wins. */
|
|
2740
|
-
defaults:
|
|
2918
|
+
defaults: z19.record(z19.string(), z19.unknown()).optional()
|
|
2741
2919
|
});
|
|
2742
|
-
var GezelTraitSchema =
|
|
2743
|
-
id:
|
|
2920
|
+
var GezelTraitSchema = z19.object({
|
|
2921
|
+
id: z19.string(),
|
|
2744
2922
|
/** One imperative second-person sentence, rendered as a prompt bullet. */
|
|
2745
|
-
text:
|
|
2746
|
-
adoptedAt:
|
|
2747
|
-
source:
|
|
2923
|
+
text: z19.string().min(1).max(200),
|
|
2924
|
+
adoptedAt: z19.string(),
|
|
2925
|
+
source: z19.enum(["levelup", "manual"]).optional()
|
|
2748
2926
|
});
|
|
2749
|
-
var GezelFrontmatterSchema =
|
|
2927
|
+
var GezelFrontmatterSchema = z19.object({
|
|
2750
2928
|
id: EntityIdSchema.optional(),
|
|
2751
|
-
name:
|
|
2752
|
-
description:
|
|
2753
|
-
role:
|
|
2929
|
+
name: z19.string(),
|
|
2930
|
+
description: z19.string().optional(),
|
|
2931
|
+
role: z19.string().optional(),
|
|
2754
2932
|
/**
|
|
2755
2933
|
* Kebab-case slug derived from `role` (or `gezel-N` when role is absent),
|
|
2756
2934
|
* globally unique across the install. Collisions get `-2`, `-3`, …
|
|
@@ -2758,7 +2936,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2758
2936
|
* identifier for @-mentions and as the sole rendered identifier when
|
|
2759
2937
|
* `config.roleBasedNameOnlyMode` is enabled.
|
|
2760
2938
|
*/
|
|
2761
|
-
roleBasedName:
|
|
2939
|
+
roleBasedName: z19.string().optional(),
|
|
2762
2940
|
/**
|
|
2763
2941
|
* One of `male` / `female` / `non-binary`. Assigned at creation time
|
|
2764
2942
|
* from the matching gendered first-name pool (with a small chance of
|
|
@@ -2767,9 +2945,9 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2767
2945
|
* own prompt. Absent on legacy gezels, where references omit pronouns.
|
|
2768
2946
|
*/
|
|
2769
2947
|
gender: GezelGenderSchema.optional(),
|
|
2770
|
-
model:
|
|
2948
|
+
model: z19.string().optional(),
|
|
2771
2949
|
provider: ProviderNameSchema.optional(),
|
|
2772
|
-
reasoningEffort:
|
|
2950
|
+
reasoningEffort: z19.string().optional(),
|
|
2773
2951
|
/**
|
|
2774
2952
|
* Per-gezel sampling / reasoning / structured-output / tool-call overrides.
|
|
2775
2953
|
* Sparse — only set fields override the catalog's recommended defaults.
|
|
@@ -2802,8 +2980,8 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2802
2980
|
* low-temperature `thinking-precise` without locking the user out.
|
|
2803
2981
|
*/
|
|
2804
2982
|
suggestedTuningProfile: TuningProfileIdSchema.optional(),
|
|
2805
|
-
tools:
|
|
2806
|
-
tags:
|
|
2983
|
+
tools: z19.array(z19.string()).optional(),
|
|
2984
|
+
tags: z19.array(z19.string()).optional(),
|
|
2807
2985
|
/**
|
|
2808
2986
|
* When set, switches this gezel into "fixed-function" mode: chat
|
|
2809
2987
|
* messages bypass the LLM and forward to the named MCP tool. See
|
|
@@ -2813,14 +2991,20 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2813
2991
|
*/
|
|
2814
2992
|
fixedFunction: FixedFunctionConfigSchema.optional(),
|
|
2815
2993
|
/** Ollama-only: override the context window (tokens) for this gezel. */
|
|
2816
|
-
numCtx:
|
|
2994
|
+
numCtx: z19.number().int().positive().optional(),
|
|
2817
2995
|
/** When false, suppresses auto-recall on session start for this gezel. */
|
|
2818
|
-
autoRecall:
|
|
2996
|
+
autoRecall: z19.boolean().optional(),
|
|
2997
|
+
/**
|
|
2998
|
+
* Per-gezel proactive indexed-context policy. Supersedes `autoRecall` when
|
|
2999
|
+
* present; absent inherits the install default. The generic `search` tool is
|
|
3000
|
+
* still available in `off` mode.
|
|
3001
|
+
*/
|
|
3002
|
+
retrieval: RetrievalPolicySchema.optional(),
|
|
2819
3003
|
/**
|
|
2820
3004
|
* Chat bubble font id (one of `GEZEL_CHAT_FONTS[*].id`). When unset or
|
|
2821
3005
|
* unrecognized, chat bubbles inherit the app default (Hanken Grotesk).
|
|
2822
3006
|
*/
|
|
2823
|
-
font:
|
|
3007
|
+
font: z19.string().optional(),
|
|
2824
3008
|
/**
|
|
2825
3009
|
* Kokoro TTS voice id (one of `KOKORO_VOICES[*].id`, e.g. `af_heart`,
|
|
2826
3010
|
* `bm_george`). Drives spoken audio rendering — `synthesize_speech`
|
|
@@ -2829,7 +3013,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2829
3013
|
* dialog. Absent on legacy gezels — synthesize falls back to the
|
|
2830
3014
|
* default voice (`af_heart`) when missing.
|
|
2831
3015
|
*/
|
|
2832
|
-
voice:
|
|
3016
|
+
voice: z19.string().optional(),
|
|
2833
3017
|
/**
|
|
2834
3018
|
* Provenance: the id of the gilde catalog template this gezel was
|
|
2835
3019
|
* created from, if any. Written by exact-template or about-omitted
|
|
@@ -2837,7 +3021,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2837
3021
|
* Absent on bespoke-generated or hand-authored gezels. The UI uses
|
|
2838
3022
|
* this to offer "reset to original template" on the about editor.
|
|
2839
3023
|
*/
|
|
2840
|
-
templateId:
|
|
3024
|
+
templateId: z19.string().optional(),
|
|
2841
3025
|
/**
|
|
2842
3026
|
* Provenance: the semver of the template version installed at create
|
|
2843
3027
|
* time. Paired with `templateId`. Absent on gezels created before this
|
|
@@ -2845,7 +3029,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2845
3029
|
* source version" and offers a refresh to current latest without
|
|
2846
3030
|
* comparing.
|
|
2847
3031
|
*/
|
|
2848
|
-
templateVersion:
|
|
3032
|
+
templateVersion: z19.string().optional(),
|
|
2849
3033
|
/**
|
|
2850
3034
|
* Copilot-only: when true, deny the Copilot CLI's built-in tools
|
|
2851
3035
|
* (bash, web_fetch, view, str_replace_editor, read_file, write_file,
|
|
@@ -2854,7 +3038,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2854
3038
|
* itself defaults to the sandboxed MCP surface.
|
|
2855
3039
|
* Provider other than copilot: ignored.
|
|
2856
3040
|
*/
|
|
2857
|
-
sandboxCopilot:
|
|
3041
|
+
sandboxCopilot: z19.boolean().optional(),
|
|
2858
3042
|
/**
|
|
2859
3043
|
* `anthropic-cli`-only: per-gezel override for the Claude CLI permission
|
|
2860
3044
|
* mode. Forwarded as `--permission-mode <value>` to each `claude` invocation.
|
|
@@ -2880,7 +3064,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2880
3064
|
* abstract sigil instead of the parametric poppetje. Default (absent /
|
|
2881
3065
|
* false) renders the poppetje everywhere. Toggled from Gezel Detail.
|
|
2882
3066
|
*/
|
|
2883
|
-
iconOverride:
|
|
3067
|
+
iconOverride: z19.boolean().optional(),
|
|
2884
3068
|
/**
|
|
2885
3069
|
* Standing behavior traits, adopted through the growth system (or
|
|
2886
3070
|
* hand-authored). Rendered as their own `### Traits` block in the
|
|
@@ -2889,7 +3073,7 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2889
3073
|
* The frontmatter list is AUTHORITATIVE for what's active — growth.json
|
|
2890
3074
|
* keeps the evidence-bearing adoption log.
|
|
2891
3075
|
*/
|
|
2892
|
-
traits:
|
|
3076
|
+
traits: z19.array(GezelTraitSchema).max(8).optional(),
|
|
2893
3077
|
/**
|
|
2894
3078
|
* Overrides `config.recognition.mode` for this gezel. A gezel whose job is
|
|
2895
3079
|
* reading screenshots sets `always`; everyone else inherits.
|
|
@@ -2899,46 +3083,48 @@ var GezelFrontmatterSchema = z17.object({
|
|
|
2899
3083
|
* support burden. Native vision is a property of the model *install*, not of
|
|
2900
3084
|
* the gezel, so it has no frontmatter counterpart.
|
|
2901
3085
|
*/
|
|
2902
|
-
recognition:
|
|
3086
|
+
recognition: z19.enum(["auto", "always", "off"]).optional()
|
|
2903
3087
|
});
|
|
2904
|
-
var GezelSectionSchema =
|
|
2905
|
-
heading:
|
|
2906
|
-
template:
|
|
2907
|
-
params:
|
|
2908
|
-
body:
|
|
3088
|
+
var GezelSectionSchema = z19.object({
|
|
3089
|
+
heading: z19.string(),
|
|
3090
|
+
template: z19.string().optional(),
|
|
3091
|
+
params: z19.record(z19.string(), z19.string()).optional(),
|
|
3092
|
+
body: z19.string()
|
|
2909
3093
|
});
|
|
2910
|
-
var ParsedGezelSchema =
|
|
3094
|
+
var ParsedGezelSchema = z19.object({
|
|
2911
3095
|
frontmatter: GezelFrontmatterSchema,
|
|
2912
|
-
sections:
|
|
2913
|
-
source:
|
|
3096
|
+
sections: z19.array(GezelSectionSchema),
|
|
3097
|
+
source: z19.string()
|
|
2914
3098
|
});
|
|
2915
|
-
var GezelSummarySchema =
|
|
3099
|
+
var GezelSummarySchema = z19.object({
|
|
2916
3100
|
id: EntityIdSchema,
|
|
2917
|
-
name:
|
|
2918
|
-
description:
|
|
2919
|
-
role:
|
|
3101
|
+
name: z19.string(),
|
|
3102
|
+
description: z19.string().optional(),
|
|
3103
|
+
role: z19.string().optional(),
|
|
2920
3104
|
/** Mirrors `GezelFrontmatter.roleBasedName`. */
|
|
2921
|
-
roleBasedName:
|
|
3105
|
+
roleBasedName: z19.string().optional(),
|
|
2922
3106
|
/** Mirrors `GezelFrontmatter.gender`. */
|
|
2923
3107
|
gender: GezelGenderSchema.optional(),
|
|
2924
|
-
model:
|
|
3108
|
+
model: z19.string().optional(),
|
|
2925
3109
|
provider: ProviderNameSchema.optional(),
|
|
2926
|
-
reasoningEffort:
|
|
3110
|
+
reasoningEffort: z19.string().optional(),
|
|
2927
3111
|
/** Mirrors `GezelFrontmatter.tuningProfile`. */
|
|
2928
3112
|
tuningProfile: TuningProfileIdSchema.optional(),
|
|
2929
3113
|
/** Mirrors `GezelFrontmatter.suggestedTuningProfile`. */
|
|
2930
3114
|
suggestedTuningProfile: TuningProfileIdSchema.optional(),
|
|
2931
|
-
numCtx:
|
|
2932
|
-
autoRecall:
|
|
2933
|
-
|
|
3115
|
+
numCtx: z19.number().int().positive().optional(),
|
|
3116
|
+
autoRecall: z19.boolean().optional(),
|
|
3117
|
+
/** Mirrors `GezelFrontmatter.retrieval`. */
|
|
3118
|
+
retrieval: RetrievalPolicySchema.optional(),
|
|
3119
|
+
font: z19.string().optional(),
|
|
2934
3120
|
/** Mirrors `GezelFrontmatter.voice` — Kokoro TTS voice id. */
|
|
2935
|
-
voice:
|
|
3121
|
+
voice: z19.string().optional(),
|
|
2936
3122
|
/** Mirrors `GezelFrontmatter.templateId` when the gezel came from a gilde template. */
|
|
2937
|
-
templateId:
|
|
3123
|
+
templateId: z19.string().optional(),
|
|
2938
3124
|
/** Mirrors `GezelFrontmatter.templateVersion`. */
|
|
2939
|
-
templateVersion:
|
|
3125
|
+
templateVersion: z19.string().optional(),
|
|
2940
3126
|
/** Mirrors `GezelFrontmatter.sandboxCopilot`. */
|
|
2941
|
-
sandboxCopilot:
|
|
3127
|
+
sandboxCopilot: z19.boolean().optional(),
|
|
2942
3128
|
/** Mirrors `GezelFrontmatter.claudePermissionMode`. */
|
|
2943
3129
|
claudePermissionMode: ClaudePermissionModeSchema.optional(),
|
|
2944
3130
|
/** Mirrors `GezelFrontmatter.codexPermissionMode`. */
|
|
@@ -2951,7 +3137,7 @@ var GezelSummarySchema = z17.object({
|
|
|
2951
3137
|
* affordance.
|
|
2952
3138
|
*/
|
|
2953
3139
|
fixedFunction: FixedFunctionConfigSchema.optional(),
|
|
2954
|
-
icon:
|
|
3140
|
+
icon: z19.string().optional(),
|
|
2955
3141
|
/**
|
|
2956
3142
|
* The resolved poppetje character data for this gezel. Inlined on
|
|
2957
3143
|
* every list/detail response so the UI can render the parametric SVG
|
|
@@ -2961,9 +3147,9 @@ var GezelSummarySchema = z17.object({
|
|
|
2961
3147
|
*/
|
|
2962
3148
|
poppetje: PoppetjeSchema.optional(),
|
|
2963
3149
|
/** Mirrors `GezelFrontmatter.iconOverride`. */
|
|
2964
|
-
iconOverride:
|
|
3150
|
+
iconOverride: z19.boolean().optional(),
|
|
2965
3151
|
/** Mirrors `GezelFrontmatter.recognition`. */
|
|
2966
|
-
recognition:
|
|
3152
|
+
recognition: z19.enum(["auto", "always", "off"]).optional(),
|
|
2967
3153
|
/**
|
|
2968
3154
|
* Where this gezel lives. `global` (the default when absent — back-compat
|
|
2969
3155
|
* with every gezel on disk before this field existed) is the install-wide
|
|
@@ -2973,15 +3159,15 @@ var GezelSummarySchema = z17.object({
|
|
|
2973
3159
|
* badges project-scoped gezels and the roster only surfaces them inside
|
|
2974
3160
|
* their own project.
|
|
2975
3161
|
*/
|
|
2976
|
-
scope:
|
|
3162
|
+
scope: z19.enum(["global", "project"]).optional(),
|
|
2977
3163
|
/**
|
|
2978
3164
|
* Filesystem ownership boundary, distinct from `scope` above. Shared gezel
|
|
2979
3165
|
* identity lives in the installer-managed machine root; chats, memories,
|
|
2980
3166
|
* growth, credentials, and installed toolsets remain in the user home.
|
|
2981
3167
|
*/
|
|
2982
|
-
storageScope:
|
|
3168
|
+
storageScope: z19.enum(["user", "machine-shared"]).optional(),
|
|
2983
3169
|
/** Mirrors `GezelFrontmatter.traits`. */
|
|
2984
|
-
traits:
|
|
3170
|
+
traits: z19.array(GezelTraitSchema).optional(),
|
|
2985
3171
|
/**
|
|
2986
3172
|
* Lightweight growth summary (level + pending level-up flag),
|
|
2987
3173
|
* hydrated from growth.json and inlined on list/detail responses —
|
|
@@ -2989,11 +3175,11 @@ var GezelSummarySchema = z17.object({
|
|
|
2989
3175
|
* without N+1 follow-up requests.
|
|
2990
3176
|
*/
|
|
2991
3177
|
growth: GezelGrowthSummarySchema.optional(),
|
|
2992
|
-
updatedAt:
|
|
3178
|
+
updatedAt: z19.string()
|
|
2993
3179
|
});
|
|
2994
3180
|
var GezelDetailSchema = GezelSummarySchema.extend({
|
|
2995
3181
|
parsed: ParsedGezelSchema,
|
|
2996
|
-
about:
|
|
3182
|
+
about: z19.string(),
|
|
2997
3183
|
/**
|
|
2998
3184
|
* Optional contents of the per-gezel `tools.md` file. When present
|
|
2999
3185
|
* (non-null), fully replaces the auto-injected `## Tools available
|
|
@@ -3003,43 +3189,87 @@ var GezelDetailSchema = GezelSummarySchema.extend({
|
|
|
3003
3189
|
* default) means no override file exists and the runtime renders
|
|
3004
3190
|
* the auto-block from the live MCP bridge.
|
|
3005
3191
|
*/
|
|
3006
|
-
toolsMd:
|
|
3192
|
+
toolsMd: z19.string().nullable().default(null)
|
|
3007
3193
|
});
|
|
3008
|
-
var ToolCallImageSchema =
|
|
3194
|
+
var ToolCallImageSchema = z19.object({
|
|
3009
3195
|
/** Path relative to the project's artifacts/ root (e.g. `sessions/2026-04-19_143015_snake-test/tool-3-img-0.png`). */
|
|
3010
|
-
path:
|
|
3196
|
+
path: z19.string(),
|
|
3011
3197
|
/** MIME type of the image, used by the UI to set the right `<img>` src URL. */
|
|
3012
|
-
mimeType:
|
|
3198
|
+
mimeType: z19.string()
|
|
3013
3199
|
});
|
|
3014
|
-
var ToolCallAudioSchema =
|
|
3200
|
+
var ToolCallAudioSchema = z19.object({
|
|
3015
3201
|
/** Path relative to the project's artifacts/ root. */
|
|
3016
|
-
path:
|
|
3202
|
+
path: z19.string(),
|
|
3017
3203
|
/** MIME type, e.g. `audio/wav`. */
|
|
3018
|
-
mimeType:
|
|
3204
|
+
mimeType: z19.string(),
|
|
3019
3205
|
/** Duration in seconds when known — used by the UI to show length without preloading the blob. */
|
|
3020
|
-
durationSeconds:
|
|
3206
|
+
durationSeconds: z19.number().optional(),
|
|
3021
3207
|
/** Voice id used to produce this audio (TTS only). */
|
|
3022
|
-
voice:
|
|
3208
|
+
voice: z19.string().optional()
|
|
3023
3209
|
});
|
|
3024
|
-
var ToolCallVideoSchema =
|
|
3210
|
+
var ToolCallVideoSchema = z19.object({
|
|
3025
3211
|
/** Path relative to the project's artifacts/ root (e.g. `generated/video-123.mp4`). */
|
|
3026
|
-
path:
|
|
3212
|
+
path: z19.string(),
|
|
3027
3213
|
/** MIME type, e.g. `video/mp4`. */
|
|
3028
|
-
mimeType:
|
|
3214
|
+
mimeType: z19.string(),
|
|
3029
3215
|
/** Optional poster-frame artifact path for the `<video poster>` attribute. */
|
|
3030
|
-
posterPath:
|
|
3216
|
+
posterPath: z19.string().optional()
|
|
3217
|
+
});
|
|
3218
|
+
var ToolCardStepSchema = z19.object({
|
|
3219
|
+
id: z19.string(),
|
|
3220
|
+
name: z19.string(),
|
|
3221
|
+
status: z19.enum(["done", "active", "pending"])
|
|
3222
|
+
});
|
|
3223
|
+
var CraftbookStartCardSchema = z19.object({
|
|
3224
|
+
kind: z19.literal("craftbook-start"),
|
|
3225
|
+
craftbookId: z19.string(),
|
|
3226
|
+
craftbookName: z19.string(),
|
|
3227
|
+
/** Task ref `projectId/num`. */
|
|
3228
|
+
taskRef: z19.string(),
|
|
3229
|
+
/** The TASK's project — may differ from the session's when invoked cross-project. */
|
|
3230
|
+
projectId: z19.string(),
|
|
3231
|
+
/** Task status at event time. */
|
|
3232
|
+
status: z19.string(),
|
|
3233
|
+
activeStepId: z19.string().optional(),
|
|
3234
|
+
steps: z19.array(ToolCardStepSchema),
|
|
3235
|
+
/** True when the call idempotently returned an already-running task. */
|
|
3236
|
+
reused: z19.boolean().optional(),
|
|
3237
|
+
/**
|
|
3238
|
+
* The craftbook declares it works better with the External services
|
|
3239
|
+
* capability. The UI nudges (with the optional author rationale) only
|
|
3240
|
+
* while the resolved security policy has it disabled.
|
|
3241
|
+
*/
|
|
3242
|
+
recommendsExternalServices: z19.object({ reason: z19.string().optional() }).optional()
|
|
3031
3243
|
});
|
|
3032
|
-
var
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3244
|
+
var TaskStepAdvanceCardSchema = z19.object({
|
|
3245
|
+
kind: z19.literal("task-step-advance"),
|
|
3246
|
+
craftbookId: z19.string(),
|
|
3247
|
+
craftbookName: z19.string(),
|
|
3248
|
+
taskRef: z19.string(),
|
|
3249
|
+
projectId: z19.string(),
|
|
3250
|
+
status: z19.string(),
|
|
3251
|
+
completedStepId: z19.string(),
|
|
3252
|
+
completedStepName: z19.string().optional(),
|
|
3253
|
+
/** Absent when the advance took the task terminal (complete/canceled). */
|
|
3254
|
+
activeStepId: z19.string().optional(),
|
|
3255
|
+
activeStepName: z19.string().optional(),
|
|
3256
|
+
steps: z19.array(ToolCardStepSchema)
|
|
3257
|
+
});
|
|
3258
|
+
var ToolCallCardSchema = z19.discriminatedUnion("kind", [
|
|
3259
|
+
CraftbookStartCardSchema,
|
|
3260
|
+
TaskStepAdvanceCardSchema
|
|
3261
|
+
]);
|
|
3262
|
+
var ChatMessageToolCallSchema = z19.object({
|
|
3263
|
+
name: z19.string(),
|
|
3264
|
+
durationMs: z19.number(),
|
|
3265
|
+
success: z19.boolean(),
|
|
3266
|
+
errorMessage: z19.string().optional(),
|
|
3037
3267
|
/** File path the tool touched, for the References pane. */
|
|
3038
|
-
path:
|
|
3268
|
+
path: z19.string().optional(),
|
|
3039
3269
|
/** Ordered file paths touched by a batched filesystem tool. */
|
|
3040
|
-
paths:
|
|
3270
|
+
paths: z19.array(z19.string()).optional(),
|
|
3041
3271
|
/** Compact, human-readable one-liner ("→ Freja: update the game loop · file: workspace/index.html"). */
|
|
3042
|
-
argsSummary:
|
|
3272
|
+
argsSummary: z19.string().optional(),
|
|
3043
3273
|
/**
|
|
3044
3274
|
* The tool call's FULL arguments, rendered as readable text (field by
|
|
3045
3275
|
* field, bulky values shown in full — not truncated like
|
|
@@ -3050,54 +3280,77 @@ var ChatMessageToolCallSchema = z17.object({
|
|
|
3050
3280
|
* arguments are not a secret vector in this codebase (secrets live in
|
|
3051
3281
|
* the toolset-config path), so this is not separately redacted.
|
|
3052
3282
|
*/
|
|
3053
|
-
argsFull:
|
|
3283
|
+
argsFull: z19.string().optional(),
|
|
3054
3284
|
/** Short full response, or a bounded beginning/end summary for a long response. */
|
|
3055
|
-
resultText:
|
|
3285
|
+
resultText: z19.string().optional(),
|
|
3056
3286
|
/** True when `resultText` is a bounded summary rather than the complete response. */
|
|
3057
|
-
resultTruncated:
|
|
3287
|
+
resultTruncated: z19.boolean().optional(),
|
|
3058
3288
|
/** Image artifacts the tool returned (e.g. browser_snapshot screenshots). */
|
|
3059
|
-
images:
|
|
3289
|
+
images: z19.array(ToolCallImageSchema).optional(),
|
|
3060
3290
|
/** Audio artifacts the tool returned (e.g. synthesize_speech WAV). */
|
|
3061
|
-
audios:
|
|
3291
|
+
audios: z19.array(ToolCallAudioSchema).optional(),
|
|
3062
3292
|
/** Video artifacts the tool returned (e.g. generate_video mp4). */
|
|
3063
|
-
videos:
|
|
3293
|
+
videos: z19.array(ToolCallVideoSchema).optional(),
|
|
3064
3294
|
/**
|
|
3065
3295
|
* Unified diff describing the change a surgical-edit tool made
|
|
3066
3296
|
* (`replace_in_file`, `apply_patch`, `insert_at_marker`). Used by the UI
|
|
3067
3297
|
* to render an inline diff under the tool-call row. Capped at ~100KB
|
|
3068
3298
|
* server-side; larger diffs are truncated with a marker line.
|
|
3069
3299
|
*/
|
|
3070
|
-
diff:
|
|
3071
|
-
addedLines:
|
|
3072
|
-
removedLines:
|
|
3300
|
+
diff: z19.string().optional(),
|
|
3301
|
+
addedLines: z19.number().int().nonnegative().optional(),
|
|
3302
|
+
removedLines: z19.number().int().nonnegative().optional(),
|
|
3303
|
+
/** Rich inline card payload for tools with special renderings — see ToolCallCardSchema. */
|
|
3304
|
+
card: ToolCallCardSchema.optional(),
|
|
3305
|
+
/**
|
|
3306
|
+
* Offset into the turn's `ChatMessage.reasoning` string marking where
|
|
3307
|
+
* this call fired — the same trick `intents[].afterChars` plays on
|
|
3308
|
+
* `content`. Lets the collapsed Thinking expander splice a small
|
|
3309
|
+
* marker into the trace at the spot the model stopped deliberating
|
|
3310
|
+
* and acted, so an expanded trace reads in causal order instead of as
|
|
3311
|
+
* one undifferentiated block above an unrelated tool list.
|
|
3312
|
+
*
|
|
3313
|
+
* Sourced from the PROVIDER's running reasoning length
|
|
3314
|
+
* (`LLMSession.getCurrentTurnReasoningLength`), never from a
|
|
3315
|
+
* manager-side count of `reasoning_delta` events: the persisted trace
|
|
3316
|
+
* is whatever `getLastTurnReasoning()` returns, which several local
|
|
3317
|
+
* providers build by extracting `<think>` blocks per tool-loop
|
|
3318
|
+
* iteration rather than from the delta stream. An offset into a
|
|
3319
|
+
* different string would drift silently.
|
|
3320
|
+
*
|
|
3321
|
+
* Absent for providers that don't implement the getter, and on every
|
|
3322
|
+
* message written before this field existed — the expander then
|
|
3323
|
+
* renders the plain trace it always did.
|
|
3324
|
+
*/
|
|
3325
|
+
afterReasoningChars: z19.number().int().min(0).optional()
|
|
3073
3326
|
});
|
|
3074
|
-
var ChatSessionSourceSchema =
|
|
3075
|
-
kind:
|
|
3327
|
+
var ChatSessionSourceSchema = z19.object({
|
|
3328
|
+
kind: z19.literal("external"),
|
|
3076
3329
|
/** Stable integration id, e.g. `pi`. */
|
|
3077
|
-
appId:
|
|
3330
|
+
appId: z19.string().min(1),
|
|
3078
3331
|
/** Human-facing application name, e.g. `Pi`. */
|
|
3079
|
-
appName:
|
|
3332
|
+
appName: z19.string().min(1),
|
|
3080
3333
|
/** The external application's stable conversation/session identifier. */
|
|
3081
|
-
externalConversationId:
|
|
3334
|
+
externalConversationId: z19.string().min(1),
|
|
3082
3335
|
/** External threads are ledger views; the owning app controls replies. */
|
|
3083
|
-
readOnly:
|
|
3336
|
+
readOnly: z19.literal(true),
|
|
3084
3337
|
/** Working-directory hint supplied by the external app, when available. */
|
|
3085
|
-
workingDirectory:
|
|
3338
|
+
workingDirectory: z19.string().optional(),
|
|
3086
3339
|
/** Project id/name hint supplied by the external app, when available. */
|
|
3087
|
-
projectHint:
|
|
3340
|
+
projectHint: z19.string().optional()
|
|
3088
3341
|
});
|
|
3089
|
-
var ReferencedFileKindSchema =
|
|
3090
|
-
var ReferencedFileSchema =
|
|
3342
|
+
var ReferencedFileKindSchema = z19.enum(["artifact", "workspace"]);
|
|
3343
|
+
var ReferencedFileSchema = z19.object({
|
|
3091
3344
|
kind: ReferencedFileKindSchema,
|
|
3092
|
-
path:
|
|
3093
|
-
});
|
|
3094
|
-
var ChatMessageSchema =
|
|
3095
|
-
role:
|
|
3096
|
-
content:
|
|
3097
|
-
at:
|
|
3098
|
-
from:
|
|
3099
|
-
gezelId:
|
|
3100
|
-
gezelName:
|
|
3345
|
+
path: z19.string()
|
|
3346
|
+
});
|
|
3347
|
+
var ChatMessageSchema = z19.object({
|
|
3348
|
+
role: z19.enum(["user", "assistant"]),
|
|
3349
|
+
content: z19.string(),
|
|
3350
|
+
at: z19.string(),
|
|
3351
|
+
from: z19.object({
|
|
3352
|
+
gezelId: z19.string(),
|
|
3353
|
+
gezelName: z19.string()
|
|
3101
3354
|
}).optional(),
|
|
3102
3355
|
/**
|
|
3103
3356
|
* Real files the assistant reply named in its body text — artifacts
|
|
@@ -3107,7 +3360,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3107
3360
|
* match a real file. Back-stops Copilot's tool-call blindspot and any
|
|
3108
3361
|
* "AI wrote a file outside the MCP tools" path.
|
|
3109
3362
|
*/
|
|
3110
|
-
referencedFiles:
|
|
3363
|
+
referencedFiles: z19.array(ReferencedFileSchema).optional(),
|
|
3111
3364
|
/**
|
|
3112
3365
|
* The artifact-only projection of {@link referencedFiles}, still
|
|
3113
3366
|
* written so an older `@bendyline/gezel-cli` (or any out-of-tree
|
|
@@ -3117,7 +3370,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3117
3370
|
*
|
|
3118
3371
|
* @deprecated superseded by `referencedFiles`
|
|
3119
3372
|
*/
|
|
3120
|
-
referencedArtifacts:
|
|
3373
|
+
referencedArtifacts: z19.array(z19.string()).optional(),
|
|
3121
3374
|
/**
|
|
3122
3375
|
* Task refs (`<projectId>/<num>`) the assistant reply mentioned. Same
|
|
3123
3376
|
* shape as `referencedFiles` — populated on save, gated on the
|
|
@@ -3126,14 +3379,33 @@ var ChatMessageSchema = z17.object({
|
|
|
3126
3379
|
* gezel-ux-roadmap/2" mention so the user can jump to it without
|
|
3127
3380
|
* scrolling the body for the ref.
|
|
3128
3381
|
*/
|
|
3129
|
-
referencedTasks:
|
|
3382
|
+
referencedTasks: z19.array(z19.string()).optional(),
|
|
3383
|
+
/**
|
|
3384
|
+
* Indexed-context sources consulted for THIS user turn (proactive
|
|
3385
|
+
* retrieval). Citations only — source/path/line/score, never the retrieved
|
|
3386
|
+
* text (which lives solely in the provider prompt). Lets the UI render a
|
|
3387
|
+
* "consulted N sources" row so proactive RAG is visible diligence instead
|
|
3388
|
+
* of invisible machinery.
|
|
3389
|
+
*/
|
|
3390
|
+
retrieval: z19.object({
|
|
3391
|
+
hits: z19.array(
|
|
3392
|
+
z19.object({
|
|
3393
|
+
source: RetrievalSourceSchema,
|
|
3394
|
+
projectId: z19.string().optional(),
|
|
3395
|
+
path: z19.string().optional(),
|
|
3396
|
+
line: z19.number().int().positive().optional(),
|
|
3397
|
+
lineEnd: z19.number().int().positive().optional(),
|
|
3398
|
+
score: z19.number()
|
|
3399
|
+
})
|
|
3400
|
+
)
|
|
3401
|
+
}).optional(),
|
|
3130
3402
|
/**
|
|
3131
3403
|
* Tool calls the assistant fired during this turn. Populated on the
|
|
3132
3404
|
* final assistant message; the UI renders them as a collapsible
|
|
3133
3405
|
* "thinking" expando above the reply body so the user can still see
|
|
3134
3406
|
* what ran even after the live stream has closed.
|
|
3135
3407
|
*/
|
|
3136
|
-
toolCalls:
|
|
3408
|
+
toolCalls: z19.array(ChatMessageToolCallSchema).optional(),
|
|
3137
3409
|
/**
|
|
3138
3410
|
* Phase announcements the model emitted via Copilot's `report_intent`
|
|
3139
3411
|
* tool during this turn. Each entry carries the intent label and an
|
|
@@ -3144,10 +3416,10 @@ var ChatMessageSchema = z17.object({
|
|
|
3144
3416
|
* replay and history export are unaffected. Copilot-only; other
|
|
3145
3417
|
* providers don't emit these.
|
|
3146
3418
|
*/
|
|
3147
|
-
intents:
|
|
3148
|
-
|
|
3149
|
-
label:
|
|
3150
|
-
afterChars:
|
|
3419
|
+
intents: z19.array(
|
|
3420
|
+
z19.object({
|
|
3421
|
+
label: z19.string(),
|
|
3422
|
+
afterChars: z19.number().int().min(0)
|
|
3151
3423
|
})
|
|
3152
3424
|
).optional(),
|
|
3153
3425
|
/**
|
|
@@ -3157,7 +3429,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3157
3429
|
* itself lives in the per-project questions file; this id is just
|
|
3158
3430
|
* the foreign key.
|
|
3159
3431
|
*/
|
|
3160
|
-
pendingQuestionId:
|
|
3432
|
+
pendingQuestionId: z19.string().optional(),
|
|
3161
3433
|
/**
|
|
3162
3434
|
* Marks the message as a system-generated synthesis rather than a real
|
|
3163
3435
|
* model turn.
|
|
@@ -3186,7 +3458,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3186
3458
|
* UI renders these as muted bubbles; the model sees them as normal
|
|
3187
3459
|
* assistant turns (the role label is what matters to the API).
|
|
3188
3460
|
*/
|
|
3189
|
-
synthetic:
|
|
3461
|
+
synthetic: z19.enum([
|
|
3190
3462
|
"compaction-summary",
|
|
3191
3463
|
"context-loop-halt",
|
|
3192
3464
|
"turn-aborted",
|
|
@@ -3204,7 +3476,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3204
3476
|
* from loaded transcripts and the live-timeline handler skips its bubble
|
|
3205
3477
|
* while still opening the assistant's streaming slot.
|
|
3206
3478
|
*/
|
|
3207
|
-
hidden:
|
|
3479
|
+
hidden: z19.boolean().optional(),
|
|
3208
3480
|
/**
|
|
3209
3481
|
* This user message was delivered from the session's mid-turn queue
|
|
3210
3482
|
* as a nudge — typed while the previous turn was still streaming and
|
|
@@ -3212,7 +3484,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3212
3484
|
* Display-only marker: the model sees a normal user turn; the UI
|
|
3213
3485
|
* renders a small "nudged" chip on the bubble.
|
|
3214
3486
|
*/
|
|
3215
|
-
nudge:
|
|
3487
|
+
nudge: z19.boolean().optional(),
|
|
3216
3488
|
/**
|
|
3217
3489
|
* The machinery — not the human — authored this `role: 'user'` message.
|
|
3218
3490
|
* Task dispatch seeds, step handoffs, and project-page reaction seeds
|
|
@@ -3231,7 +3503,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3231
3503
|
* widen it without a second field. Messages written before this field
|
|
3232
3504
|
* existed are inferred at read time — see `Store.listTimeline`.
|
|
3233
3505
|
*/
|
|
3234
|
-
origin:
|
|
3506
|
+
origin: z19.enum(["system"]).optional(),
|
|
3235
3507
|
/**
|
|
3236
3508
|
* Persistent warnings attached to this assistant turn — fabricated
|
|
3237
3509
|
* tool-use detection, degraded provider state, etc. The streaming
|
|
@@ -3241,7 +3513,7 @@ var ChatMessageSchema = z17.object({
|
|
|
3241
3513
|
* reload. Populated by the chat manager just before `events.publish`
|
|
3242
3514
|
* fires the `complete` event.
|
|
3243
3515
|
*/
|
|
3244
|
-
warnings:
|
|
3516
|
+
warnings: z19.array(z19.string()).optional(),
|
|
3245
3517
|
/**
|
|
3246
3518
|
* Chain-of-thought captured during this turn. Local providers
|
|
3247
3519
|
* (ollama, llama-cpp, mlx, ds4) extract `<think>…</think>` /
|
|
@@ -3254,14 +3526,14 @@ var ChatMessageSchema = z17.object({
|
|
|
3254
3526
|
* Responses hides reasoning server-side and leaves this unset.
|
|
3255
3527
|
* Empty / whitespace-only captures are dropped.
|
|
3256
3528
|
*/
|
|
3257
|
-
reasoning:
|
|
3529
|
+
reasoning: z19.string().optional(),
|
|
3258
3530
|
/**
|
|
3259
3531
|
* Observed wall-clock span of the streamed private-reasoning trace,
|
|
3260
3532
|
* measured from the first `reasoning_delta` to the last. Optional
|
|
3261
3533
|
* because older messages and providers that only expose reasoning at
|
|
3262
3534
|
* commit time have no trustworthy phase timing.
|
|
3263
3535
|
*/
|
|
3264
|
-
reasoningDurationMs:
|
|
3536
|
+
reasoningDurationMs: z19.number().int().nonnegative().optional(),
|
|
3265
3537
|
/**
|
|
3266
3538
|
* Tool-call bodies the model emitted that the salvage layer
|
|
3267
3539
|
* couldn't parse — the literal text from `<|tool_call|>` markers
|
|
@@ -3276,10 +3548,10 @@ var ChatMessageSchema = z17.object({
|
|
|
3276
3548
|
* hundred chars per body in the populator so a long fabricated body
|
|
3277
3549
|
* doesn't blow up the session file.
|
|
3278
3550
|
*/
|
|
3279
|
-
attemptedToolCalls:
|
|
3280
|
-
|
|
3281
|
-
body:
|
|
3282
|
-
reason:
|
|
3551
|
+
attemptedToolCalls: z19.array(
|
|
3552
|
+
z19.object({
|
|
3553
|
+
body: z19.string(),
|
|
3554
|
+
reason: z19.string().optional()
|
|
3283
3555
|
})
|
|
3284
3556
|
).optional(),
|
|
3285
3557
|
/**
|
|
@@ -3295,28 +3567,28 @@ var ChatMessageSchema = z17.object({
|
|
|
3295
3567
|
* daemon restart, a provider reset, or a context-pressure rebuild — leaving
|
|
3296
3568
|
* the model replaying a bare ``.
|
|
3297
3569
|
*/
|
|
3298
|
-
recognizedImages:
|
|
3570
|
+
recognizedImages: z19.array(MessageImageDigestSchema).optional()
|
|
3299
3571
|
});
|
|
3300
|
-
var ChatTurnErrorDetailSchema =
|
|
3301
|
-
code:
|
|
3572
|
+
var ChatTurnErrorDetailSchema = z19.object({
|
|
3573
|
+
code: z19.string().max(64).optional(),
|
|
3302
3574
|
/** Component that failed — a provider name (`llama-cpp`) or a subsystem. */
|
|
3303
|
-
engine:
|
|
3575
|
+
engine: z19.string().max(64).optional(),
|
|
3304
3576
|
/** Correlation key, also written into the engine's own incident log. */
|
|
3305
|
-
incidentId:
|
|
3577
|
+
incidentId: z19.string().max(64).optional(),
|
|
3306
3578
|
/** Native crash class from the exit snapshot, e.g. `cuda-out-of-memory`. */
|
|
3307
|
-
panicKind:
|
|
3308
|
-
exitCode:
|
|
3309
|
-
signal:
|
|
3579
|
+
panicKind: z19.string().max(64).optional(),
|
|
3580
|
+
exitCode: z19.number().int().nullable().optional(),
|
|
3581
|
+
signal: z19.string().max(32).nullable().optional(),
|
|
3310
3582
|
/**
|
|
3311
3583
|
* Request-independent launch facts copied from the crash snapshot, which
|
|
3312
3584
|
* is contractually free of prompts, tool arguments, and secrets. Bounded
|
|
3313
3585
|
* by the extractor. A machine profile cannot reconstruct which model at
|
|
3314
3586
|
* which context size with which KV type crashed; this can.
|
|
3315
3587
|
*/
|
|
3316
|
-
diagnostics:
|
|
3588
|
+
diagnostics: z19.record(z19.string(), z19.union([z19.string(), z19.number(), z19.boolean()])).optional()
|
|
3317
3589
|
});
|
|
3318
|
-
var ChatEventSchema =
|
|
3319
|
-
|
|
3590
|
+
var ChatEventSchema = z19.discriminatedUnion("type", [
|
|
3591
|
+
z19.object({ type: z19.literal("delta"), content: z19.string() }),
|
|
3320
3592
|
/**
|
|
3321
3593
|
* Live private-reasoning tokens (ds4's think phase), streamed on their
|
|
3322
3594
|
* own channel so they never mix into the visible `delta` stream, the
|
|
@@ -3324,14 +3596,14 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3324
3596
|
* renders them as a distinct "thinking" block that collapses into the
|
|
3325
3597
|
* committed message's reasoning expander once `complete` lands.
|
|
3326
3598
|
*/
|
|
3327
|
-
|
|
3328
|
-
|
|
3599
|
+
z19.object({ type: z19.literal("reasoning_delta"), content: z19.string() }),
|
|
3600
|
+
z19.object({ type: z19.literal("complete"), message: ChatMessageSchema }),
|
|
3329
3601
|
/**
|
|
3330
3602
|
* The user submitted a message, but a cold provider session is still being
|
|
3331
3603
|
* created. Project timelines render this as a temporary pending row until
|
|
3332
3604
|
* the durable `user_message` or a terminal `error` arrives.
|
|
3333
3605
|
*/
|
|
3334
|
-
|
|
3606
|
+
z19.object({ type: z19.literal("user_message_pending"), preview: z19.string() }),
|
|
3335
3607
|
/**
|
|
3336
3608
|
* Emitted right after the user's message is appended to the session
|
|
3337
3609
|
* record. The legacy session-scoped UI inserted user messages locally
|
|
@@ -3339,27 +3611,27 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3339
3611
|
* envelope streams need it so the interleaved timeline can render the
|
|
3340
3612
|
* user's bubble immediately, before any assistant deltas.
|
|
3341
3613
|
*/
|
|
3342
|
-
|
|
3614
|
+
z19.object({ type: z19.literal("user_message"), message: ChatMessageSchema }),
|
|
3343
3615
|
/**
|
|
3344
3616
|
* Emitted when the assistant invokes an MCP tool (OpenAI + Mock paths
|
|
3345
3617
|
* only — Copilot runs tools inside its subprocess, invisible to us).
|
|
3346
3618
|
* The UI surfaces these as "thinking" breadcrumbs.
|
|
3347
3619
|
*/
|
|
3348
|
-
|
|
3349
|
-
type:
|
|
3350
|
-
name:
|
|
3351
|
-
durationMs:
|
|
3352
|
-
success:
|
|
3353
|
-
errorMessage:
|
|
3620
|
+
z19.object({
|
|
3621
|
+
type: z19.literal("tool"),
|
|
3622
|
+
name: z19.string(),
|
|
3623
|
+
durationMs: z19.number(),
|
|
3624
|
+
success: z19.boolean(),
|
|
3625
|
+
errorMessage: z19.string().optional(),
|
|
3354
3626
|
/**
|
|
3355
3627
|
* File path the tool touched (if any). Set for tools that take a `path`
|
|
3356
3628
|
* argument: readFile, writeFile, read_artifact, write_artifact,
|
|
3357
3629
|
* read_document, write_document. Lets the UI build a References panel
|
|
3358
3630
|
* without guessing.
|
|
3359
3631
|
*/
|
|
3360
|
-
path:
|
|
3632
|
+
path: z19.string().optional(),
|
|
3361
3633
|
/** Ordered file paths touched by a batched filesystem tool. */
|
|
3362
|
-
paths:
|
|
3634
|
+
paths: z19.array(z19.string()).optional(),
|
|
3363
3635
|
/**
|
|
3364
3636
|
* Compact human-readable preview of the non-bulky arguments. Example:
|
|
3365
3637
|
* `gezel: "Maya", message: "what's the status of..."`. Values are
|
|
@@ -3367,44 +3639,46 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3367
3639
|
* UI to render a useful in-progress tool line instead of just the
|
|
3368
3640
|
* tool name.
|
|
3369
3641
|
*/
|
|
3370
|
-
argsSummary:
|
|
3642
|
+
argsSummary: z19.string().optional(),
|
|
3371
3643
|
/** Full, readable args for the expand + copy affordance. See the persisted `ChatMessageToolCall.argsFull`. */
|
|
3372
|
-
argsFull:
|
|
3644
|
+
argsFull: z19.string().optional(),
|
|
3373
3645
|
/** Short full response, or a bounded beginning/end summary. */
|
|
3374
|
-
resultText:
|
|
3646
|
+
resultText: z19.string().optional(),
|
|
3375
3647
|
/** True when `resultText` is a bounded summary rather than the complete response. */
|
|
3376
|
-
resultTruncated:
|
|
3648
|
+
resultTruncated: z19.boolean().optional(),
|
|
3377
3649
|
/**
|
|
3378
3650
|
* Image artifacts the tool returned (most commonly browser screenshots).
|
|
3379
3651
|
* Paths are relative to the project's artifacts/ root and resolved
|
|
3380
3652
|
* to URLs by the UI via the artifact-read endpoint.
|
|
3381
3653
|
*/
|
|
3382
|
-
images:
|
|
3654
|
+
images: z19.array(ToolCallImageSchema).optional(),
|
|
3383
3655
|
/**
|
|
3384
3656
|
* Audio artifacts the tool returned (synthesize_speech narrations,
|
|
3385
3657
|
* voice memos transcribed via transcribe_audio). Same artifact-path
|
|
3386
3658
|
* resolution as `images`.
|
|
3387
3659
|
*/
|
|
3388
|
-
audios:
|
|
3660
|
+
audios: z19.array(ToolCallAudioSchema).optional(),
|
|
3389
3661
|
/**
|
|
3390
3662
|
* Video artifacts the tool returned (`generate_video`). Same
|
|
3391
3663
|
* artifact-path resolution as `images`; rendered as a `<video>`
|
|
3392
3664
|
* player in the chat row.
|
|
3393
3665
|
*/
|
|
3394
|
-
videos:
|
|
3666
|
+
videos: z19.array(ToolCallVideoSchema).optional(),
|
|
3395
3667
|
/**
|
|
3396
3668
|
* Unified diff describing the change a surgical-edit tool made
|
|
3397
3669
|
* (`replace_in_file`, `apply_patch`, `insert_at_marker`). Streams to the
|
|
3398
3670
|
* UI mid-turn so the chat bubble can render an inline diff under
|
|
3399
3671
|
* the tool-call row even before the assistant message is finalized.
|
|
3400
3672
|
*/
|
|
3401
|
-
diff:
|
|
3402
|
-
addedLines:
|
|
3403
|
-
removedLines:
|
|
3673
|
+
diff: z19.string().optional(),
|
|
3674
|
+
addedLines: z19.number().int().nonnegative().optional(),
|
|
3675
|
+
removedLines: z19.number().int().nonnegative().optional(),
|
|
3676
|
+
/** Rich inline card payload for tools with special renderings — see ToolCallCardSchema. */
|
|
3677
|
+
card: ToolCallCardSchema.optional()
|
|
3404
3678
|
}),
|
|
3405
|
-
|
|
3406
|
-
type:
|
|
3407
|
-
error:
|
|
3679
|
+
z19.object({
|
|
3680
|
+
type: z19.literal("error"),
|
|
3681
|
+
error: z19.string(),
|
|
3408
3682
|
// Not `detail` — three sibling variants in this union already use that
|
|
3409
3683
|
// name for free-form progress prose, and one union with two meanings for
|
|
3410
3684
|
// one key is a trap.
|
|
@@ -3415,8 +3689,8 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3415
3689
|
* surface. This is terminal for the live UI, but is deliberately not an
|
|
3416
3690
|
* error: it must not poison the session or render failure recovery UI.
|
|
3417
3691
|
*/
|
|
3418
|
-
|
|
3419
|
-
|
|
3692
|
+
z19.object({ type: z19.literal("cancelled") }),
|
|
3693
|
+
z19.object({ type: z19.literal("done") }),
|
|
3420
3694
|
/**
|
|
3421
3695
|
* Emitted when a turn ends up waiting in the provider queue for more
|
|
3422
3696
|
* than a brief grace period (~200ms). `aheadOf` is an approximate
|
|
@@ -3426,7 +3700,7 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3426
3700
|
* emit this event — avoids flashing the indicator on the happy path
|
|
3427
3701
|
* where the queue is empty.
|
|
3428
3702
|
*/
|
|
3429
|
-
|
|
3703
|
+
z19.object({ type: z19.literal("queued"), aheadOf: z19.number().int().min(0) }),
|
|
3430
3704
|
/**
|
|
3431
3705
|
* Ollama-only: emitted for each bare framing chunk that arrives
|
|
3432
3706
|
* on the wire without visible content / tool_calls — the
|
|
@@ -3436,7 +3710,7 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3436
3710
|
* when the model isn't producing visible output. Reset on the
|
|
3437
3711
|
* next real `delta`, `tool`, or `complete`.
|
|
3438
3712
|
*/
|
|
3439
|
-
|
|
3713
|
+
z19.object({ type: z19.literal("wire_pulse") }),
|
|
3440
3714
|
/**
|
|
3441
3715
|
* Live tool-argument stream. Fired while the model is generating a
|
|
3442
3716
|
* structured tool call — most visibly a multi-minute `write_file`
|
|
@@ -3448,7 +3722,7 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3448
3722
|
* "working" block (same pattern as `reasoning_delta`) and drops the
|
|
3449
3723
|
* block when the corresponding `tool` event lands.
|
|
3450
3724
|
*/
|
|
3451
|
-
|
|
3725
|
+
z19.object({ type: z19.literal("tool_args_delta"), name: z19.string(), content: z19.string() }),
|
|
3452
3726
|
/**
|
|
3453
3727
|
* Emitted when a provider tells us it's still doing work — even though
|
|
3454
3728
|
* no visible text/tool event has arrived. Today this is wired from
|
|
@@ -3459,24 +3733,24 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3459
3733
|
* Optional `label` carries a short phase hint ('thinking', 'tool',
|
|
3460
3734
|
* etc.) that the streaming bubble can surface as a status line.
|
|
3461
3735
|
*/
|
|
3462
|
-
|
|
3736
|
+
z19.object({ type: z19.literal("heartbeat"), label: z19.string().optional() }),
|
|
3463
3737
|
/**
|
|
3464
3738
|
* Provider-side warning surfaced mid-turn (e.g. Copilot rate-limit,
|
|
3465
3739
|
* context pressure, degraded mode). The UI renders these inline on
|
|
3466
3740
|
* the streaming bubble so the user sees them immediately instead of
|
|
3467
3741
|
* only finding out when the turn completes or times out.
|
|
3468
3742
|
*/
|
|
3469
|
-
|
|
3470
|
-
type:
|
|
3471
|
-
message:
|
|
3743
|
+
z19.object({
|
|
3744
|
+
type: z19.literal("warning"),
|
|
3745
|
+
message: z19.string(),
|
|
3472
3746
|
/**
|
|
3473
3747
|
* Optional in-app destination for a warning's inline action. Kept
|
|
3474
3748
|
* deliberately narrow: warnings are still readable prose when an older
|
|
3475
3749
|
* client ignores this additive field.
|
|
3476
3750
|
*/
|
|
3477
|
-
action:
|
|
3478
|
-
kind:
|
|
3479
|
-
section:
|
|
3751
|
+
action: z19.object({
|
|
3752
|
+
kind: z19.literal("settings"),
|
|
3753
|
+
section: z19.enum(["llamaCpp", "mlx", "ds4"])
|
|
3480
3754
|
}).optional()
|
|
3481
3755
|
}),
|
|
3482
3756
|
/**
|
|
@@ -3487,18 +3761,18 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3487
3761
|
* offset on the final assistant message so completed bubbles render
|
|
3488
3762
|
* the same segmentation on reload.
|
|
3489
3763
|
*/
|
|
3490
|
-
|
|
3764
|
+
z19.object({ type: z19.literal("intent"), label: z19.string() }),
|
|
3491
3765
|
/**
|
|
3492
3766
|
* Emitted when a new message is enqueued on the per-session queue
|
|
3493
3767
|
* because the session already has a turn in flight. The timeline
|
|
3494
3768
|
* renders a "ghost bubble" under the session's streaming bubble
|
|
3495
3769
|
* showing the queued text preview. Cleared via `queue_removed`.
|
|
3496
3770
|
*/
|
|
3497
|
-
|
|
3498
|
-
type:
|
|
3499
|
-
queueId:
|
|
3500
|
-
preview:
|
|
3501
|
-
enqueuedAt:
|
|
3771
|
+
z19.object({
|
|
3772
|
+
type: z19.literal("queue_enqueued"),
|
|
3773
|
+
queueId: z19.string(),
|
|
3774
|
+
preview: z19.string(),
|
|
3775
|
+
enqueuedAt: z19.string(),
|
|
3502
3776
|
/**
|
|
3503
3777
|
* The entry was queued as a mid-turn nudge — the ghost bubble labels
|
|
3504
3778
|
* it "nudge" and contiguous nudges merge into one turn on drain.
|
|
@@ -3506,7 +3780,7 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3506
3780
|
* every coalesce/edit); the edit affordance fetches it lazily via
|
|
3507
3781
|
* `GET /api/sessions/:id/queue`.
|
|
3508
3782
|
*/
|
|
3509
|
-
nudge:
|
|
3783
|
+
nudge: z19.boolean().optional()
|
|
3510
3784
|
}),
|
|
3511
3785
|
/**
|
|
3512
3786
|
* Emitted when a queued entry leaves the queue — either because
|
|
@@ -3515,10 +3789,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3515
3789
|
* dropped without running (`reason: 'canceled'` via user action,
|
|
3516
3790
|
* `reason: 'rejected'` via session archive / delete / shutdown).
|
|
3517
3791
|
*/
|
|
3518
|
-
|
|
3519
|
-
type:
|
|
3520
|
-
queueId:
|
|
3521
|
-
reason:
|
|
3792
|
+
z19.object({
|
|
3793
|
+
type: z19.literal("queue_removed"),
|
|
3794
|
+
queueId: z19.string(),
|
|
3795
|
+
reason: z19.enum(["started", "canceled", "rejected"])
|
|
3522
3796
|
}),
|
|
3523
3797
|
/**
|
|
3524
3798
|
* Local-provider context policy: emitted when accumulated conversation
|
|
@@ -3526,11 +3800,11 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3526
3800
|
* The UI may suggest starting fresh because this event is never emitted
|
|
3527
3801
|
* for a first-turn standing system/tool prefix.
|
|
3528
3802
|
*/
|
|
3529
|
-
|
|
3530
|
-
type:
|
|
3531
|
-
estimatedTokens:
|
|
3532
|
-
numCtx:
|
|
3533
|
-
model:
|
|
3803
|
+
z19.object({
|
|
3804
|
+
type: z19.literal("context_warning"),
|
|
3805
|
+
estimatedTokens: z19.number(),
|
|
3806
|
+
numCtx: z19.number(),
|
|
3807
|
+
model: z19.string()
|
|
3534
3808
|
}),
|
|
3535
3809
|
/**
|
|
3536
3810
|
* Local-provider context policy: emitted right after in-flight compaction collapses
|
|
@@ -3539,10 +3813,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3539
3813
|
* for a "compacted" variant and refreshes the visible timeline (older
|
|
3540
3814
|
* bubbles are now gone from disk).
|
|
3541
3815
|
*/
|
|
3542
|
-
|
|
3543
|
-
type:
|
|
3544
|
-
removedCount:
|
|
3545
|
-
model:
|
|
3816
|
+
z19.object({
|
|
3817
|
+
type: z19.literal("context_compacted"),
|
|
3818
|
+
removedCount: z19.number().int().nonnegative(),
|
|
3819
|
+
model: z19.string()
|
|
3546
3820
|
}),
|
|
3547
3821
|
/**
|
|
3548
3822
|
* Emitted when the chat manager detects a self-chat / compaction loop —
|
|
@@ -3551,10 +3825,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3551
3825
|
* compaction cycle without making progress. The pipeline halts the turn
|
|
3552
3826
|
* so the user can intervene; the UI surfaces a "looks stuck" banner.
|
|
3553
3827
|
*/
|
|
3554
|
-
|
|
3555
|
-
type:
|
|
3556
|
-
compactionsThisSend:
|
|
3557
|
-
reason:
|
|
3828
|
+
z19.object({
|
|
3829
|
+
type: z19.literal("context_loop"),
|
|
3830
|
+
compactionsThisSend: z19.number().int().positive(),
|
|
3831
|
+
reason: z19.string()
|
|
3558
3832
|
}),
|
|
3559
3833
|
/**
|
|
3560
3834
|
* Emitted when the Keurmeester (frontier quality inspector) steps in
|
|
@@ -3562,23 +3836,23 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3562
3836
|
* UI renders a "stepped in" notice on the thread; the full case
|
|
3563
3837
|
* record lives under `~/.gezel/keurmeester/cases/` keyed by caseId.
|
|
3564
3838
|
*/
|
|
3565
|
-
|
|
3566
|
-
type:
|
|
3567
|
-
caseId:
|
|
3568
|
-
gezelId:
|
|
3569
|
-
gezelName:
|
|
3570
|
-
action:
|
|
3571
|
-
summary:
|
|
3839
|
+
z19.object({
|
|
3840
|
+
type: z19.literal("keurmeester_intervention"),
|
|
3841
|
+
caseId: z19.string(),
|
|
3842
|
+
gezelId: z19.string(),
|
|
3843
|
+
gezelName: z19.string(),
|
|
3844
|
+
action: z19.string(),
|
|
3845
|
+
summary: z19.string()
|
|
3572
3846
|
}),
|
|
3573
3847
|
/**
|
|
3574
3848
|
* Emitted once per session the first time auto-recall runs, so the UI
|
|
3575
3849
|
* can render a "pulled N memories from prior work" chip above the first
|
|
3576
3850
|
* assistant reply.
|
|
3577
3851
|
*/
|
|
3578
|
-
|
|
3579
|
-
type:
|
|
3580
|
-
hitCount:
|
|
3581
|
-
query:
|
|
3852
|
+
z19.object({
|
|
3853
|
+
type: z19.literal("recall_applied"),
|
|
3854
|
+
hitCount: z19.number(),
|
|
3855
|
+
query: z19.string()
|
|
3582
3856
|
}),
|
|
3583
3857
|
/**
|
|
3584
3858
|
* Emitted when a gezel posts a structured question via the
|
|
@@ -3586,14 +3860,14 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3586
3860
|
* questions on this event so the in-chat card, Home pane, and Home
|
|
3587
3861
|
* tab badge all light up together.
|
|
3588
3862
|
*/
|
|
3589
|
-
|
|
3863
|
+
z19.object({ type: z19.literal("question_asked"), question: QuestionSchema }),
|
|
3590
3864
|
/**
|
|
3591
3865
|
* Emitted when the user submits (or declines) an answer. The UI
|
|
3592
3866
|
* uses the same fan-out as `question_asked` to refresh every
|
|
3593
3867
|
* surface; the chat bubble's pending card collapses to its
|
|
3594
3868
|
* answered state.
|
|
3595
3869
|
*/
|
|
3596
|
-
|
|
3870
|
+
z19.object({ type: z19.literal("question_answered"), question: QuestionSchema }),
|
|
3597
3871
|
/**
|
|
3598
3872
|
* A durable task audit event, fanned onto the project's live stream after
|
|
3599
3873
|
* it has been appended to History. This keeps lightweight clients (most
|
|
@@ -3601,13 +3875,13 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3601
3875
|
* second task lifecycle bus. `task.tick` heartbeats are intentionally not
|
|
3602
3876
|
* published; this channel is for user-meaningful changes.
|
|
3603
3877
|
*/
|
|
3604
|
-
|
|
3605
|
-
type:
|
|
3606
|
-
eventId:
|
|
3607
|
-
kind:
|
|
3608
|
-
summary:
|
|
3609
|
-
at:
|
|
3610
|
-
taskRef:
|
|
3878
|
+
z19.object({
|
|
3879
|
+
type: z19.literal("task_event"),
|
|
3880
|
+
eventId: z19.string(),
|
|
3881
|
+
kind: z19.string(),
|
|
3882
|
+
summary: z19.string(),
|
|
3883
|
+
at: z19.string(),
|
|
3884
|
+
taskRef: z19.string().optional(),
|
|
3611
3885
|
/**
|
|
3612
3886
|
* Gezel responsible for the event, when History recorded one. Kept
|
|
3613
3887
|
* separate from the human-readable summary so fixed-presentation
|
|
@@ -3615,18 +3889,18 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3615
3889
|
* their own naming mode instead of leaking the friendly name embedded
|
|
3616
3890
|
* in the audit prose.
|
|
3617
3891
|
*/
|
|
3618
|
-
gezelId:
|
|
3892
|
+
gezelId: z19.string().optional()
|
|
3619
3893
|
}),
|
|
3620
3894
|
/**
|
|
3621
3895
|
* Emitted when a gezel crosses a growth level threshold and a pending
|
|
3622
3896
|
* level-up is created. The UI refreshes growth badges/dots and raises
|
|
3623
3897
|
* a single calm OS notification when the window is hidden.
|
|
3624
3898
|
*/
|
|
3625
|
-
|
|
3626
|
-
type:
|
|
3627
|
-
gezelId:
|
|
3628
|
-
gezelName:
|
|
3629
|
-
toLevel:
|
|
3899
|
+
z19.object({
|
|
3900
|
+
type: z19.literal("growth_level_up"),
|
|
3901
|
+
gezelId: z19.string(),
|
|
3902
|
+
gezelName: z19.string(),
|
|
3903
|
+
toLevel: z19.number().int()
|
|
3630
3904
|
}),
|
|
3631
3905
|
/**
|
|
3632
3906
|
* llama-cpp-only: lifecycle phase of the supervised on-device engine
|
|
@@ -3649,13 +3923,19 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3649
3923
|
* the phase label so users who want to know what's happening can
|
|
3650
3924
|
* see, without cluttering the happy-path status line.
|
|
3651
3925
|
*/
|
|
3652
|
-
|
|
3653
|
-
type:
|
|
3654
|
-
provider:
|
|
3655
|
-
phase:
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3926
|
+
z19.object({
|
|
3927
|
+
type: z19.literal("engine_phase"),
|
|
3928
|
+
provider: z19.enum(["llama-cpp", "mlx", "ds4"]),
|
|
3929
|
+
phase: z19.enum(["starting", "loading_model", "prefill", "generating", "ready"]),
|
|
3930
|
+
/**
|
|
3931
|
+
* Human-readable subject for an ephemeral background completion. Unlike
|
|
3932
|
+
* `detail` (engine diagnostics), this names the user's work — for example
|
|
3933
|
+
* "Indexing src/app.ts". Ordinary chat turns leave it absent.
|
|
3934
|
+
*/
|
|
3935
|
+
activity: z19.string().optional(),
|
|
3936
|
+
detail: z19.string().optional(),
|
|
3937
|
+
progress: z19.number().min(0).max(1).optional(),
|
|
3938
|
+
ttftMs: z19.number().int().nonnegative().optional(),
|
|
3659
3939
|
/**
|
|
3660
3940
|
* Exact cumulative completion tokens decoded so far this turn, as the
|
|
3661
3941
|
* engine counts them (llama-server `timings.predicted_n`, MLX's
|
|
@@ -3664,14 +3944,14 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3664
3944
|
* to an explicitly-approximate character estimate when it is absent,
|
|
3665
3945
|
* so this field is what lets a readout drop its "≈".
|
|
3666
3946
|
*/
|
|
3667
|
-
outputTokens:
|
|
3947
|
+
outputTokens: z19.number().int().nonnegative().optional(),
|
|
3668
3948
|
/**
|
|
3669
3949
|
* Exact decode rate right now, engine-measured over the generation
|
|
3670
3950
|
* phase alone (llama-server `timings.predicted_per_second`, MLX's
|
|
3671
3951
|
* `generation_tps`). Same contract as `outputTokens`: absent means the
|
|
3672
3952
|
* UI must derive and mark its own estimate.
|
|
3673
3953
|
*/
|
|
3674
|
-
tokensPerSec:
|
|
3954
|
+
tokensPerSec: z19.number().nonnegative().optional()
|
|
3675
3955
|
}),
|
|
3676
3956
|
/**
|
|
3677
3957
|
* Per-turn telemetry for locally-hosted providers (llama-cpp, Ollama,
|
|
@@ -3686,21 +3966,21 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3686
3966
|
* local speed metric isn't meaningful when the latency is
|
|
3687
3967
|
* dominated by network round-trips.
|
|
3688
3968
|
*/
|
|
3689
|
-
|
|
3690
|
-
type:
|
|
3691
|
-
provider:
|
|
3969
|
+
z19.object({
|
|
3970
|
+
type: z19.literal("turn_stats"),
|
|
3971
|
+
provider: z19.enum(["llama-cpp", "ollama", "mlx", "ds4"]),
|
|
3692
3972
|
/**
|
|
3693
3973
|
* Model that generated the turn, as the session recorded it. Lets the
|
|
3694
3974
|
* UI bucket speed by model instead of averaging a 27B and a 4B into
|
|
3695
3975
|
* one meaningless number. Optional because older daemons (and remote
|
|
3696
3976
|
* peers on an older wire) don't send it.
|
|
3697
3977
|
*/
|
|
3698
|
-
model:
|
|
3699
|
-
promptTokens:
|
|
3700
|
-
completionTokens:
|
|
3701
|
-
durationMs:
|
|
3978
|
+
model: z19.string().optional(),
|
|
3979
|
+
promptTokens: z19.number().int().nonnegative(),
|
|
3980
|
+
completionTokens: z19.number().int().nonnegative(),
|
|
3981
|
+
durationMs: z19.number().int().nonnegative(),
|
|
3702
3982
|
/** Generation speed in tokens/sec — completionTokens / generationSeconds. */
|
|
3703
|
-
tokensPerSec:
|
|
3983
|
+
tokensPerSec: z19.number().nonnegative().optional()
|
|
3704
3984
|
}),
|
|
3705
3985
|
/**
|
|
3706
3986
|
* Static engine-level metrics that don't change during a session —
|
|
@@ -3712,11 +3992,11 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3712
3992
|
* `engine_phase` (every session waiting on the same supervisor
|
|
3713
3993
|
* startup gets a copy).
|
|
3714
3994
|
*/
|
|
3715
|
-
|
|
3716
|
-
type:
|
|
3717
|
-
provider:
|
|
3995
|
+
z19.object({
|
|
3996
|
+
type: z19.literal("engine_stats"),
|
|
3997
|
+
provider: z19.enum(["llama-cpp", "mlx", "ds4"]),
|
|
3718
3998
|
/** Total bytes allocated across all GGUF buffers + KV cache. */
|
|
3719
|
-
ramAllocBytes:
|
|
3999
|
+
ramAllocBytes: z19.number().nonnegative()
|
|
3720
4000
|
}),
|
|
3721
4001
|
/**
|
|
3722
4002
|
* VRAM tenancy change — a non-LLM workload has taken (or released)
|
|
@@ -3746,9 +4026,9 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3746
4026
|
* `step`/`totalSteps` drive a real progress bar; `secondsPerStep`
|
|
3747
4027
|
* lets the UI show an ETA.
|
|
3748
4028
|
*/
|
|
3749
|
-
|
|
3750
|
-
type:
|
|
3751
|
-
state:
|
|
4029
|
+
z19.object({
|
|
4030
|
+
type: z19.literal("gpu_swap"),
|
|
4031
|
+
state: z19.enum(["started", "progress", "ended"]),
|
|
3752
4032
|
/**
|
|
3753
4033
|
* Shared with session telemetry so a new workload can't light up the
|
|
3754
4034
|
* bubble while staying invisible to stall detection.
|
|
@@ -3761,12 +4041,12 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3761
4041
|
* seconds", which reads as a bug.
|
|
3762
4042
|
*/
|
|
3763
4043
|
task: SessionGpuTaskSchema,
|
|
3764
|
-
detail:
|
|
3765
|
-
prompt:
|
|
3766
|
-
progress:
|
|
3767
|
-
step:
|
|
3768
|
-
totalSteps:
|
|
3769
|
-
secondsPerStep:
|
|
4044
|
+
detail: z19.string().optional(),
|
|
4045
|
+
prompt: z19.string().optional(),
|
|
4046
|
+
progress: z19.number().min(0).max(1).optional(),
|
|
4047
|
+
step: z19.number().int().nonnegative().optional(),
|
|
4048
|
+
totalSteps: z19.number().int().positive().optional(),
|
|
4049
|
+
secondsPerStep: z19.number().nonnegative().optional()
|
|
3770
4050
|
}),
|
|
3771
4051
|
/**
|
|
3772
4052
|
* The turn is parked inside a synchronous `ask_gezel` /
|
|
@@ -3789,10 +4069,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3789
4069
|
* side, same as the `ask_gezel` tool result), so the UI can render
|
|
3790
4070
|
* it verbatim.
|
|
3791
4071
|
*/
|
|
3792
|
-
|
|
3793
|
-
type:
|
|
3794
|
-
state:
|
|
3795
|
-
targetGezelName:
|
|
4072
|
+
z19.object({
|
|
4073
|
+
type: z19.literal("awaiting_gezel"),
|
|
4074
|
+
state: z19.enum(["started", "ended"]),
|
|
4075
|
+
targetGezelName: z19.string()
|
|
3796
4076
|
}),
|
|
3797
4077
|
/**
|
|
3798
4078
|
* A new project was created (via the New Project dialog, the
|
|
@@ -3803,10 +4083,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3803
4083
|
* for the next manual refresh / tab-focus poll. Not a renderable
|
|
3804
4084
|
* timeline event (like `growth_level_up`); the chat surfaces ignore it.
|
|
3805
4085
|
*/
|
|
3806
|
-
|
|
3807
|
-
type:
|
|
3808
|
-
projectId:
|
|
3809
|
-
name:
|
|
4086
|
+
z19.object({
|
|
4087
|
+
type: z19.literal("project_created"),
|
|
4088
|
+
projectId: z19.string(),
|
|
4089
|
+
name: z19.string()
|
|
3810
4090
|
}),
|
|
3811
4091
|
/**
|
|
3812
4092
|
* A project was deleted (via the Project Actions menu, or an equivalent
|
|
@@ -3816,10 +4096,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3816
4096
|
* waiting for the next manual refresh / tab-focus poll. Not a renderable
|
|
3817
4097
|
* timeline event; the chat surfaces ignore it.
|
|
3818
4098
|
*/
|
|
3819
|
-
|
|
3820
|
-
type:
|
|
3821
|
-
projectId:
|
|
3822
|
-
name:
|
|
4099
|
+
z19.object({
|
|
4100
|
+
type: z19.literal("project_deleted"),
|
|
4101
|
+
projectId: z19.string(),
|
|
4102
|
+
name: z19.string()
|
|
3823
4103
|
}),
|
|
3824
4104
|
/**
|
|
3825
4105
|
* A new shared gezel joined the global roster. Emitted on the global
|
|
@@ -3828,10 +4108,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3828
4108
|
* gezels deliberately do not emit this event because they do not belong in
|
|
3829
4109
|
* the global Gezellen list.
|
|
3830
4110
|
*/
|
|
3831
|
-
|
|
3832
|
-
type:
|
|
3833
|
-
gezelId:
|
|
3834
|
-
name:
|
|
4111
|
+
z19.object({
|
|
4112
|
+
type: z19.literal("gezel_created"),
|
|
4113
|
+
gezelId: z19.string(),
|
|
4114
|
+
name: z19.string()
|
|
3835
4115
|
}),
|
|
3836
4116
|
/**
|
|
3837
4117
|
* Global (project-less) signal that Night Shift mode flipped ON/OFF.
|
|
@@ -3839,10 +4119,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3839
4119
|
* menu pill reflects the live state. `source` is the active driver
|
|
3840
4120
|
* (scheduled window vs. a manual shift), null when inactive.
|
|
3841
4121
|
*/
|
|
3842
|
-
|
|
3843
|
-
type:
|
|
3844
|
-
active:
|
|
3845
|
-
source:
|
|
4122
|
+
z19.object({
|
|
4123
|
+
type: z19.literal("night_shift"),
|
|
4124
|
+
active: z19.boolean(),
|
|
4125
|
+
source: z19.enum(["scheduled", "manual"]).nullable()
|
|
3846
4126
|
}),
|
|
3847
4127
|
/**
|
|
3848
4128
|
* Global signal from the meester status generator. `started` fires
|
|
@@ -3851,10 +4131,10 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3851
4131
|
* produced nothing usable — the Home greeting refetches on the
|
|
3852
4132
|
* terminal states instead of polling.
|
|
3853
4133
|
*/
|
|
3854
|
-
|
|
3855
|
-
type:
|
|
3856
|
-
state:
|
|
3857
|
-
generatedAt:
|
|
4134
|
+
z19.object({
|
|
4135
|
+
type: z19.literal("meester_status"),
|
|
4136
|
+
state: z19.enum(["started", "ended", "failed"]),
|
|
4137
|
+
generatedAt: z19.string().optional()
|
|
3858
4138
|
}),
|
|
3859
4139
|
/**
|
|
3860
4140
|
* Global signal from the ambient dashboard generator. `ended` means a
|
|
@@ -3863,11 +4143,11 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3863
4143
|
* the wallpaper when the user opted in, and the Settings card
|
|
3864
4144
|
* refreshes its preview.
|
|
3865
4145
|
*/
|
|
3866
|
-
|
|
3867
|
-
type:
|
|
3868
|
-
state:
|
|
3869
|
-
generatedAt:
|
|
3870
|
-
filename:
|
|
4146
|
+
z19.object({
|
|
4147
|
+
type: z19.literal("ambient_dashboard"),
|
|
4148
|
+
state: z19.enum(["started", "ended", "failed"]),
|
|
4149
|
+
generatedAt: z19.string().optional(),
|
|
4150
|
+
filename: z19.string().optional()
|
|
3871
4151
|
}),
|
|
3872
4152
|
/**
|
|
3873
4153
|
* Global (history-free) heartbeat from the boekwachter indexing loops —
|
|
@@ -3875,23 +4155,27 @@ var ChatEventSchema = z17.discriminatedUnion("type", [
|
|
|
3875
4155
|
* indicator pill; complements (doesn't replace) the polled per-project
|
|
3876
4156
|
* index status. `pending` = files still awaiting AI enrichment when known.
|
|
3877
4157
|
*/
|
|
3878
|
-
|
|
3879
|
-
type:
|
|
3880
|
-
phase:
|
|
3881
|
-
state:
|
|
3882
|
-
projectId:
|
|
3883
|
-
detail:
|
|
3884
|
-
pending:
|
|
4158
|
+
z19.object({
|
|
4159
|
+
type: z19.literal("index_progress"),
|
|
4160
|
+
phase: z19.enum(["scan", "shadow", "enrich", "review", "digest"]),
|
|
4161
|
+
state: z19.enum(["started", "progress", "ended"]),
|
|
4162
|
+
projectId: z19.string().optional(),
|
|
4163
|
+
detail: z19.string().optional(),
|
|
4164
|
+
pending: z19.number().int().nonnegative().optional(),
|
|
3885
4165
|
/** The concrete autonomous gezel doing this work, when the project has one. */
|
|
3886
|
-
gezelId:
|
|
4166
|
+
gezelId: z19.string().optional(),
|
|
3887
4167
|
/** Snapshot of their display name so transient progress remains human-readable. */
|
|
3888
|
-
gezelName:
|
|
4168
|
+
gezelName: z19.string().optional()
|
|
3889
4169
|
})
|
|
3890
4170
|
]);
|
|
3891
|
-
var ChatEventEnvelopeSchema =
|
|
3892
|
-
sessionId:
|
|
3893
|
-
gezelId:
|
|
3894
|
-
projectId:
|
|
4171
|
+
var ChatEventEnvelopeSchema = z19.object({
|
|
4172
|
+
sessionId: z19.string(),
|
|
4173
|
+
gezelId: z19.string(),
|
|
4174
|
+
projectId: z19.string(),
|
|
4175
|
+
/** Present when this live session was opened by another session. */
|
|
4176
|
+
parentSession: SessionParentSchema.optional(),
|
|
4177
|
+
/** Immediate task-step session that handed work to this live session. */
|
|
4178
|
+
handoffFrom: SessionLinkSchema.optional(),
|
|
3895
4179
|
/** Present for externally-owned read-only threads, including live turns. */
|
|
3896
4180
|
sessionSource: ChatSessionSourceSchema.optional(),
|
|
3897
4181
|
event: ChatEventSchema
|
|
@@ -4024,8 +4308,8 @@ function promoteBareChannelNames(text) {
|
|
|
4024
4308
|
}
|
|
4025
4309
|
|
|
4026
4310
|
// src/schemas/report-action.ts
|
|
4027
|
-
import { z as
|
|
4028
|
-
var ReportActionKindSchema =
|
|
4311
|
+
import { z as z20 } from "zod";
|
|
4312
|
+
var ReportActionKindSchema = z20.enum(["fire-craftbook", "create-task", "apply-edits"]);
|
|
4029
4313
|
var commonFields = {
|
|
4030
4314
|
/**
|
|
4031
4315
|
* Author-supplied stable slug — keeps lifecycle state attached across
|
|
@@ -4033,121 +4317,121 @@ var commonFields = {
|
|
|
4033
4317
|
* content hash (`a-<hash>`), which is stable only while the block's
|
|
4034
4318
|
* body is byte-identical.
|
|
4035
4319
|
*/
|
|
4036
|
-
id:
|
|
4320
|
+
id: z20.string().regex(/^[a-z0-9][a-z0-9_-]*$/i).optional(),
|
|
4037
4321
|
/** Short human label for the card ("Fix the unchecked null in parser.ts"). */
|
|
4038
|
-
title:
|
|
4322
|
+
title: z20.string().min(1),
|
|
4039
4323
|
/** One-or-two-sentence rationale shown under the title. */
|
|
4040
|
-
reason:
|
|
4324
|
+
reason: z20.string().optional(),
|
|
4041
4325
|
/**
|
|
4042
4326
|
* Target project. Defaults to the report's own project. Cross-project
|
|
4043
4327
|
* targets are a primary case — the bundled oversight report lives in
|
|
4044
4328
|
* `default` but recommends work in specific projects.
|
|
4045
4329
|
*/
|
|
4046
|
-
projectId:
|
|
4330
|
+
projectId: z20.string().optional()
|
|
4047
4331
|
};
|
|
4048
|
-
var FireCraftbookActionSchema =
|
|
4049
|
-
kind:
|
|
4332
|
+
var FireCraftbookActionSchema = z20.object({
|
|
4333
|
+
kind: z20.literal("fire-craftbook"),
|
|
4050
4334
|
...commonFields,
|
|
4051
|
-
craftbookId:
|
|
4335
|
+
craftbookId: z20.string().min(1),
|
|
4052
4336
|
/** Invocation params for the craftbook's paramSchema (stringified values). */
|
|
4053
|
-
params:
|
|
4337
|
+
params: z20.record(z20.string(), z20.string()).optional()
|
|
4054
4338
|
});
|
|
4055
|
-
var CreateTaskActionSchema =
|
|
4056
|
-
kind:
|
|
4339
|
+
var CreateTaskActionSchema = z20.object({
|
|
4340
|
+
kind: z20.literal("create-task"),
|
|
4057
4341
|
...commonFields,
|
|
4058
4342
|
/** Full work instruction for the bespoke task's single step. */
|
|
4059
|
-
prompt:
|
|
4343
|
+
prompt: z20.string().min(1),
|
|
4060
4344
|
/** Role to recruit for the work (ensure_gezel jobTitle). Default: software developer. */
|
|
4061
|
-
role:
|
|
4345
|
+
role: z20.string().optional()
|
|
4062
4346
|
});
|
|
4063
|
-
var ApplyEditsActionSchema =
|
|
4064
|
-
kind:
|
|
4347
|
+
var ApplyEditsActionSchema = z20.object({
|
|
4348
|
+
kind: z20.literal("apply-edits"),
|
|
4065
4349
|
...commonFields,
|
|
4066
|
-
edits:
|
|
4067
|
-
|
|
4350
|
+
edits: z20.array(
|
|
4351
|
+
z20.object({
|
|
4068
4352
|
/** Workspace-relative target file in the TARGET project. */
|
|
4069
|
-
path:
|
|
4353
|
+
path: z20.string().min(1),
|
|
4070
4354
|
/** Artifacts-relative sidecar `.diff` path in the REPORT's project. */
|
|
4071
|
-
diffArtifact:
|
|
4355
|
+
diffArtifact: z20.string().min(1)
|
|
4072
4356
|
})
|
|
4073
4357
|
).min(1)
|
|
4074
4358
|
});
|
|
4075
|
-
var ReportActionSchema =
|
|
4359
|
+
var ReportActionSchema = z20.discriminatedUnion("kind", [
|
|
4076
4360
|
FireCraftbookActionSchema,
|
|
4077
4361
|
CreateTaskActionSchema,
|
|
4078
4362
|
ApplyEditsActionSchema
|
|
4079
4363
|
]);
|
|
4080
|
-
var ReportActionStateSchema =
|
|
4364
|
+
var ReportActionStateSchema = z20.enum([
|
|
4081
4365
|
"suggested",
|
|
4082
4366
|
"fired",
|
|
4083
4367
|
"applied",
|
|
4084
4368
|
"failed",
|
|
4085
4369
|
"dismissed"
|
|
4086
4370
|
]);
|
|
4087
|
-
var ReportActionRecordSchema =
|
|
4088
|
-
actionId:
|
|
4371
|
+
var ReportActionRecordSchema = z20.object({
|
|
4372
|
+
actionId: z20.string(),
|
|
4089
4373
|
/** Artifacts-relative path of the report the action came from. */
|
|
4090
|
-
reportPath:
|
|
4374
|
+
reportPath: z20.string(),
|
|
4091
4375
|
kind: ReportActionKindSchema,
|
|
4092
|
-
contentHash:
|
|
4093
|
-
firstSeenAt:
|
|
4376
|
+
contentHash: z20.string(),
|
|
4377
|
+
firstSeenAt: z20.string(),
|
|
4094
4378
|
state: ReportActionStateSchema,
|
|
4095
4379
|
/** Task materialized by fire-craftbook / create-task. */
|
|
4096
|
-
taskRef:
|
|
4097
|
-
firedAt:
|
|
4380
|
+
taskRef: z20.string().optional(),
|
|
4381
|
+
firedAt: z20.string().optional(),
|
|
4098
4382
|
/** Stamped when the fired task settles. */
|
|
4099
|
-
settledAt:
|
|
4100
|
-
outcome:
|
|
4383
|
+
settledAt: z20.string().optional(),
|
|
4384
|
+
outcome: z20.enum(["complete", "canceled"]).optional(),
|
|
4101
4385
|
/** apply-edits per-file results. */
|
|
4102
|
-
results:
|
|
4103
|
-
|
|
4104
|
-
path:
|
|
4105
|
-
ok:
|
|
4106
|
-
error:
|
|
4386
|
+
results: z20.array(
|
|
4387
|
+
z20.object({
|
|
4388
|
+
path: z20.string(),
|
|
4389
|
+
ok: z20.boolean(),
|
|
4390
|
+
error: z20.string().optional()
|
|
4107
4391
|
})
|
|
4108
4392
|
).optional()
|
|
4109
4393
|
});
|
|
4110
|
-
var ReportActionParseIssueSchema =
|
|
4394
|
+
var ReportActionParseIssueSchema = z20.object({
|
|
4111
4395
|
/** Zero-based index among the report's gezel-action fences. */
|
|
4112
|
-
index:
|
|
4113
|
-
message:
|
|
4396
|
+
index: z20.number().int(),
|
|
4397
|
+
message: z20.string(),
|
|
4114
4398
|
/** Raw fence body, for the "unreadable action block" card. */
|
|
4115
|
-
raw:
|
|
4399
|
+
raw: z20.string()
|
|
4116
4400
|
});
|
|
4117
|
-
var ReportActionViewSchema =
|
|
4401
|
+
var ReportActionViewSchema = z20.object({
|
|
4118
4402
|
action: ReportActionSchema,
|
|
4119
|
-
id:
|
|
4120
|
-
contentHash:
|
|
4403
|
+
id: z20.string(),
|
|
4404
|
+
contentHash: z20.string(),
|
|
4121
4405
|
state: ReportActionStateSchema,
|
|
4122
|
-
taskRef:
|
|
4123
|
-
firedAt:
|
|
4124
|
-
settledAt:
|
|
4125
|
-
outcome:
|
|
4126
|
-
results:
|
|
4406
|
+
taskRef: z20.string().optional(),
|
|
4407
|
+
firedAt: z20.string().optional(),
|
|
4408
|
+
settledAt: z20.string().optional(),
|
|
4409
|
+
outcome: z20.enum(["complete", "canceled"]).optional(),
|
|
4410
|
+
results: z20.array(z20.object({ path: z20.string(), ok: z20.boolean(), error: z20.string().optional() })).optional(),
|
|
4127
4411
|
/** The stored record predates a changed block body (report regenerated). */
|
|
4128
|
-
contentChanged:
|
|
4412
|
+
contentChanged: z20.boolean().optional()
|
|
4129
4413
|
});
|
|
4130
|
-
var ReportActionsResponseSchema =
|
|
4131
|
-
actions:
|
|
4132
|
-
issues:
|
|
4414
|
+
var ReportActionsResponseSchema = z20.object({
|
|
4415
|
+
actions: z20.array(ReportActionViewSchema),
|
|
4416
|
+
issues: z20.array(ReportActionParseIssueSchema),
|
|
4133
4417
|
/** Records whose action vanished from the regenerated report. */
|
|
4134
|
-
stale:
|
|
4418
|
+
stale: z20.array(ReportActionRecordSchema)
|
|
4135
4419
|
});
|
|
4136
|
-
var FireReportActionRequestSchema =
|
|
4420
|
+
var FireReportActionRequestSchema = z20.object({
|
|
4137
4421
|
/** Artifacts-relative report path. */
|
|
4138
|
-
path:
|
|
4139
|
-
actionId:
|
|
4422
|
+
path: z20.string().min(1),
|
|
4423
|
+
actionId: z20.string().min(1),
|
|
4140
4424
|
/** apply-edits: none. fire-craftbook: overrides the block's params. */
|
|
4141
|
-
params:
|
|
4425
|
+
params: z20.record(z20.string(), z20.string()).optional()
|
|
4142
4426
|
});
|
|
4143
|
-
var FireReportActionResponseSchema =
|
|
4427
|
+
var FireReportActionResponseSchema = z20.object({
|
|
4144
4428
|
record: ReportActionRecordSchema,
|
|
4145
4429
|
/** Set for fire-craftbook / create-task. */
|
|
4146
|
-
taskRef:
|
|
4430
|
+
taskRef: z20.string().optional()
|
|
4147
4431
|
});
|
|
4148
|
-
var DismissReportActionRequestSchema =
|
|
4149
|
-
path:
|
|
4150
|
-
actionId:
|
|
4432
|
+
var DismissReportActionRequestSchema = z20.object({
|
|
4433
|
+
path: z20.string().min(1),
|
|
4434
|
+
actionId: z20.string().min(1)
|
|
4151
4435
|
});
|
|
4152
4436
|
|
|
4153
4437
|
// src/markdown/report-actions.ts
|