@wildo-ai/platform-core-shared 1.1.5 → 1.1.6

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.
Files changed (64) hide show
  1. package/dist/esm/index.d.ts +2 -0
  2. package/dist/esm/index.d.ts.map +1 -1
  3. package/dist/esm/index.js +2 -0
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/runtime/application-backend-env.contracts.d.ts +21 -2
  6. package/dist/esm/runtime/application-backend-env.contracts.d.ts.map +1 -1
  7. package/dist/esm/runtime/application-backend-env.contracts.js +21 -0
  8. package/dist/esm/runtime/application-backend-env.contracts.js.map +1 -1
  9. package/dist/esm/runtime/http-server-env.contracts.d.ts +46 -0
  10. package/dist/esm/runtime/http-server-env.contracts.d.ts.map +1 -0
  11. package/dist/esm/runtime/http-server-env.contracts.js +55 -0
  12. package/dist/esm/runtime/http-server-env.contracts.js.map +1 -0
  13. package/dist/esm/runtime/runtime-topology.contracts.d.ts +0 -4
  14. package/dist/esm/runtime/runtime-topology.contracts.d.ts.map +1 -1
  15. package/dist/esm/runtime/runtime-topology.contracts.js +0 -12
  16. package/dist/esm/runtime/runtime-topology.contracts.js.map +1 -1
  17. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts +106 -4
  18. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts.map +1 -1
  19. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.d.ts +106 -4
  20. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.schemas.d.ts.map +1 -1
  21. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts +15 -0
  22. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts.map +1 -1
  23. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts +15 -0
  24. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts.map +1 -1
  25. package/dist/esm/wildo-applications/wildo-applications.custom.shared.schemas.d.ts +7 -5
  26. package/dist/esm/wildo-applications/wildo-applications.custom.shared.schemas.d.ts.map +1 -1
  27. package/dist/esm/wildo-applications/wildo-applications.custom.shared.schemas.js +7 -5
  28. package/dist/esm/wildo-applications/wildo-applications.custom.shared.schemas.js.map +1 -1
  29. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.d.ts.map +1 -1
  30. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js +23 -0
  31. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js.map +1 -1
  32. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.d.ts +279 -0
  33. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.d.ts.map +1 -0
  34. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.js +303 -0
  35. package/dist/esm/workbench/workbench-creation-console.custom.shared.schemas.js.map +1 -0
  36. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.d.ts +97 -1
  37. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.d.ts.map +1 -1
  38. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.js +86 -0
  39. package/dist/esm/workbench/workbench-creation-conversation.custom.shared.schemas.js.map +1 -1
  40. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts +88 -5
  41. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts.map +1 -1
  42. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js +89 -7
  43. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js.map +1 -1
  44. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts +230 -13
  45. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts.map +1 -1
  46. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js +377 -16
  47. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js.map +1 -1
  48. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts +6 -0
  49. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts.map +1 -1
  50. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js +8 -0
  51. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js.map +1 -1
  52. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts +45 -2
  53. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts.map +1 -1
  54. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js +1 -1
  55. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js.map +1 -1
  56. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.d.ts +16 -2
  57. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.js +25 -2
  59. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.js.map +1 -1
  60. package/dist/tsconfig.build.tsbuildinfo +1 -1
  61. package/package.json +4 -4
  62. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.d.ts +0 -0
  63. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.d.ts.map +0 -0
  64. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.js.map +0 -0
@@ -0,0 +1,279 @@
1
+ import { z } from 'zod';
2
+ import { WorkbenchCreationHomeLineKind, WorkbenchCreationHomeSection } from './workbench-creation-plane.custom.shared.schemas';
3
+ /**
4
+ * The CREATION CONSOLE contract — how a coding-agent session (Claude Code, or any agent driving
5
+ * `wildo`) follows what the companion did and answers what the companion asks.
6
+ *
7
+ * ## Why a console needs its own contract beside the workbench's resources
8
+ *
9
+ * The companion is the master of application creation: it runs playbooks, dispatches coding
10
+ * workers over ACP, runs judges and generation steps. The person drives it from a CONSOLE — the
11
+ * coding-agent session they are already working in — and the workbench becomes the dashboard of
12
+ * that state (Paul, 2026-09-25). Two things are then owed to the console:
13
+ *
14
+ * 1. FEEDBACK: what the companion did (a run completed or was refused, a dispatch settled, a judge
15
+ * verdict) and what it now waits for.
16
+ * 2. ANSWERS: every question the companion asks must be answerable from the console, once, and
17
+ * the answer must reach the same service the workbench's own operation reaches.
18
+ *
19
+ * The facts already exist as creation-plane rows (Home's lines, the waiting runs, the parked coding
20
+ * questions, the dossier). The workbench reaches them through the resource plane, which needs a
21
+ * signed-in PERSON; a console reaches the companion through the local-token plane
22
+ * (`/api/companion/*`), which is how every `wildo` verb already talks to it. This contract is that
23
+ * plane's view of the SAME rows — no second derivation, and no second implementation of an answer:
24
+ * each answer kind calls the companion service the matching workbench operation calls.
25
+ *
26
+ * ## Why the question queue is ONE list rather than one read per kind
27
+ *
28
+ * A person (or an agent acting for them) asks "what is waiting on me?" once. Four reads, each with
29
+ * its own identity and answer route, is what makes a console skip one. So the companion folds the
30
+ * four row kinds into one list with one identity scheme and one answer door, and says per question
31
+ * which actions it admits — the console restates no policy.
32
+ */
33
+ /**
34
+ * WHAT KIND of question a queued item is — which companion lane asked it, and so which service an
35
+ * answer reaches.
36
+ */
37
+ export declare enum CreationConsoleQuestionKind {
38
+ /**
39
+ * A playbook run SUSPENDED mid-derivation on a round of questions it cannot decide alone. One item
40
+ * per round, carrying every question of the round: the run resumes on one answer to the round.
41
+ */
42
+ CLARIFICATION = "clarification",
43
+ /** A coding worker (an ACP session the companion dispatched) PARKED on a question it asked. */
44
+ PARKED_CODING_QUESTION = "parked-coding-question",
45
+ /**
46
+ * An interview question a step can run as soon as it is answered — the dossier entry the workbench
47
+ * shows as "asked of you now". Answering lands `creator-inputs`; a commit accepts it.
48
+ */
49
+ INTERVIEW = "interview",
50
+ /**
51
+ * A fact a drafted governed document still needs. LISTED so the queue is total over what waits on
52
+ * the person, NOT answerable here: landing governance facts is a whole-document sitting that also
53
+ * names the governance scope and who decided, and `compliance-is-derived-from-the-product.md`
54
+ * holds that questionnaire where it is until the evidence tier exists. Answer it in the workbench.
55
+ */
56
+ GOVERNANCE_FACT = "governance-fact"
57
+ }
58
+ /**
59
+ * WHAT an answer does — the industry three-action model the playbook clarification already uses
60
+ * (MCP elicitation's vocabulary), so every kind of question speaks it.
61
+ */
62
+ export declare enum CreationConsoleAnswerAction {
63
+ /** Give the answer(s). */
64
+ ANSWER = "answer",
65
+ /**
66
+ * Let the asking derivation decide and state its assumption. Clarifications only. May carry the answers
67
+ * the person did give: the run then decides only the questions left unanswered.
68
+ */
69
+ DECLINE = "decline",
70
+ /** Abandon the run that asked. Clarifications and parked coding questions. */
71
+ CANCEL = "cancel"
72
+ }
73
+ /** One question inside a queued item — a clarification round carries several, the others one. */
74
+ export declare const CreationConsole_QuestionField_Schema: z.ZodObject<{
75
+ ref: z.ZodString;
76
+ question: z.ZodString;
77
+ why: z.ZodNullable<z.ZodString>;
78
+ kind: z.ZodString;
79
+ options: z.ZodArray<z.ZodString>;
80
+ }, z.core.$strip>;
81
+ export type CreationConsole_QuestionField = z.infer<typeof CreationConsole_QuestionField_Schema>;
82
+ export declare const CreationConsole_Question_Schema: z.ZodObject<{
83
+ questionId: z.ZodString;
84
+ kind: z.ZodEnum<typeof CreationConsoleQuestionKind>;
85
+ askedAt: z.ZodNullable<z.ZodString>;
86
+ playbookRef: z.ZodNullable<z.ZodString>;
87
+ taskRef: z.ZodNullable<z.ZodString>;
88
+ instanceKey: z.ZodNullable<z.ZodString>;
89
+ definitionRef: z.ZodNullable<z.ZodString>;
90
+ revision: z.ZodNullable<z.ZodString>;
91
+ fields: z.ZodArray<z.ZodObject<{
92
+ ref: z.ZodString;
93
+ question: z.ZodString;
94
+ why: z.ZodNullable<z.ZodString>;
95
+ kind: z.ZodString;
96
+ options: z.ZodArray<z.ZodString>;
97
+ }, z.core.$strip>>;
98
+ actions: z.ZodArray<z.ZodEnum<typeof CreationConsoleAnswerAction>>;
99
+ producingFamily: z.ZodNullable<z.ZodString>;
100
+ dryRun: z.ZodNullable<z.ZodBoolean>;
101
+ resumable: z.ZodNullable<z.ZodBoolean>;
102
+ affectsFamilies: z.ZodArray<z.ZodString>;
103
+ routedToUserId: z.ZodNullable<z.ZodString>;
104
+ }, z.core.$strip>;
105
+ export type CreationConsole_Question = z.infer<typeof CreationConsole_Question_Schema>;
106
+ export declare const CreationConsole_QuestionQueue_Schema: z.ZodObject<{
107
+ computedAt: z.ZodString;
108
+ questions: z.ZodArray<z.ZodObject<{
109
+ questionId: z.ZodString;
110
+ kind: z.ZodEnum<typeof CreationConsoleQuestionKind>;
111
+ askedAt: z.ZodNullable<z.ZodString>;
112
+ playbookRef: z.ZodNullable<z.ZodString>;
113
+ taskRef: z.ZodNullable<z.ZodString>;
114
+ instanceKey: z.ZodNullable<z.ZodString>;
115
+ definitionRef: z.ZodNullable<z.ZodString>;
116
+ revision: z.ZodNullable<z.ZodString>;
117
+ fields: z.ZodArray<z.ZodObject<{
118
+ ref: z.ZodString;
119
+ question: z.ZodString;
120
+ why: z.ZodNullable<z.ZodString>;
121
+ kind: z.ZodString;
122
+ options: z.ZodArray<z.ZodString>;
123
+ }, z.core.$strip>>;
124
+ actions: z.ZodArray<z.ZodEnum<typeof CreationConsoleAnswerAction>>;
125
+ producingFamily: z.ZodNullable<z.ZodString>;
126
+ dryRun: z.ZodNullable<z.ZodBoolean>;
127
+ resumable: z.ZodNullable<z.ZodBoolean>;
128
+ affectsFamilies: z.ZodArray<z.ZodString>;
129
+ routedToUserId: z.ZodNullable<z.ZodString>;
130
+ }, z.core.$strip>>;
131
+ }, z.core.$strip>;
132
+ export type CreationConsole_QuestionQueue = z.infer<typeof CreationConsole_QuestionQueue_Schema>;
133
+ /**
134
+ * One answer to one field. It carries its OWN author because a round is answered in one call while its
135
+ * fields may be answered by different parties (#1658): an agent derives one from a declared fact, the
136
+ * person decides the next. With one author per request, a mixed round either stamped the person's name
137
+ * on the agent's derivation or was refused as incomplete — the agent answering alone could not cover the
138
+ * judgement half, and the resume refuses a round answered in part.
139
+ */
140
+ export declare const CreationConsole_Answer_Schema: z.ZodObject<{
141
+ ref: z.ZodString;
142
+ value: z.ZodString;
143
+ answeredByRef: z.ZodOptional<z.ZodString>;
144
+ }, z.core.$strip>;
145
+ export type CreationConsole_Answer = z.infer<typeof CreationConsole_Answer_Schema>;
146
+ export declare const CreationConsole_AnswerRequest_Schema: z.ZodObject<{
147
+ questionId: z.ZodString;
148
+ revision: z.ZodOptional<z.ZodNullable<z.ZodString>>;
149
+ action: z.ZodEnum<typeof CreationConsoleAnswerAction>;
150
+ answers: z.ZodOptional<z.ZodArray<z.ZodObject<{
151
+ ref: z.ZodString;
152
+ value: z.ZodString;
153
+ answeredByRef: z.ZodOptional<z.ZodString>;
154
+ }, z.core.$strip>>>;
155
+ answeredByRef: z.ZodOptional<z.ZodString>;
156
+ }, z.core.$strip>;
157
+ export type CreationConsole_AnswerRequest = z.infer<typeof CreationConsole_AnswerRequest_Schema>;
158
+ export declare const CreationConsole_AnswerOutcome_Schema: z.ZodObject<{
159
+ questionId: z.ZodString;
160
+ kind: z.ZodEnum<typeof CreationConsoleQuestionKind>;
161
+ action: z.ZodEnum<typeof CreationConsoleAnswerAction>;
162
+ /** What the answering service returned — its own shape (a resumed run's outcome, a landed dossier file). */
163
+ outcome: z.ZodUnknown;
164
+ }, z.core.$loose>;
165
+ export type CreationConsole_AnswerOutcome = z.infer<typeof CreationConsole_AnswerOutcome_Schema>;
166
+ /**
167
+ * One FEED line: a Home line (what happened, what is asked, what could come next) with the row it
168
+ * points at attached, so a console reads a run's verdict or a dispatch's error without a second call.
169
+ *
170
+ * `at` is ISO-8601 here — this is a JSON contract, not a resource row.
171
+ */
172
+ export declare const CreationConsole_FeedLine_Schema: z.ZodObject<{
173
+ lineId: z.ZodString;
174
+ section: z.ZodEnum<typeof WorkbenchCreationHomeSection>;
175
+ kind: z.ZodEnum<typeof WorkbenchCreationHomeLineKind>;
176
+ at: z.ZodNullable<z.ZodString>;
177
+ playbookRef: z.ZodNullable<z.ZodString>;
178
+ taskRef: z.ZodNullable<z.ZodString>;
179
+ subject: z.ZodNullable<z.ZodString>;
180
+ failed: z.ZodBoolean;
181
+ acceptable: z.ZodBoolean;
182
+ needsAnswers: z.ZodBoolean;
183
+ stuckReason: z.ZodNullable<z.ZodString>;
184
+ targetResourceType: z.ZodString;
185
+ targetResourceId: z.ZodString;
186
+ target: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
187
+ questionId: z.ZodNullable<z.ZodString>;
188
+ }, z.core.$strip>;
189
+ export type CreationConsole_FeedLine = z.infer<typeof CreationConsole_FeedLine_Schema>;
190
+ export declare const CreationConsole_Feed_Schema: z.ZodObject<{
191
+ computedAt: z.ZodString;
192
+ lines: z.ZodArray<z.ZodObject<{
193
+ lineId: z.ZodString;
194
+ section: z.ZodEnum<typeof WorkbenchCreationHomeSection>;
195
+ kind: z.ZodEnum<typeof WorkbenchCreationHomeLineKind>;
196
+ at: z.ZodNullable<z.ZodString>;
197
+ playbookRef: z.ZodNullable<z.ZodString>;
198
+ taskRef: z.ZodNullable<z.ZodString>;
199
+ subject: z.ZodNullable<z.ZodString>;
200
+ failed: z.ZodBoolean;
201
+ acceptable: z.ZodBoolean;
202
+ needsAnswers: z.ZodBoolean;
203
+ stuckReason: z.ZodNullable<z.ZodString>;
204
+ targetResourceType: z.ZodString;
205
+ targetResourceId: z.ZodString;
206
+ target: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
207
+ questionId: z.ZodNullable<z.ZodString>;
208
+ }, z.core.$strip>>;
209
+ }, z.core.$strip>;
210
+ export type CreationConsole_Feed = z.infer<typeof CreationConsole_Feed_Schema>;
211
+ /** The one identity rule, applied by the companion when it emits and when it resolves an answer. */
212
+ export declare function formatCreationConsoleQuestionId(kind: CreationConsoleQuestionKind, rowId: string): string;
213
+ /** The inverse of {@link formatCreationConsoleQuestionId}; `null` for anything that is not one. */
214
+ export declare function parseCreationConsoleQuestionId(questionId: string): {
215
+ kind: CreationConsoleQuestionKind;
216
+ rowId: string;
217
+ } | null;
218
+ /**
219
+ * The workbench DEEP LINK (#1652): `?open=<resourceType>:<resourceId>` opens that creation-plane row
220
+ * in the workbench's detail pane, the way clicking its Home line does. `wildo workbench open <ref>`
221
+ * writes it; the workbench reads it once and drops it. One format, owned here, so the writer and the
222
+ * reader cannot disagree about it.
223
+ *
224
+ * The FIRST `:` separates the two, because a resource type never contains one and a row id may.
225
+ */
226
+ export declare const WORKBENCH_OPEN_DETAIL_QUERY_PARAM = "open";
227
+ export declare function formatWorkbenchOpenDetailParam(resourceType: string, resourceId: string): string;
228
+ /** The inverse of {@link formatWorkbenchOpenDetailParam}; `null` for anything that is not one. */
229
+ export declare function parseWorkbenchOpenDetailParam(value: string): {
230
+ resourceType: string;
231
+ resourceId: string;
232
+ } | null;
233
+ /**
234
+ * The PULSE (#1657): a read cheap enough to poll every few seconds from a hook or a status line.
235
+ *
236
+ * Nothing in it is derived on request. `sequence` and `changedAt` move whenever the creation plane's
237
+ * boards are invalidated (every mutation path ends there) or a watched board is republished;
238
+ * `runsInFlight` is the process's own running-run count; `summary` is what the most recent FEED read
239
+ * counted, with its instant — `null` until someone has read the feed, because computing it here would
240
+ * make the pulse as slow as the feed. A poller compares pulses and reads the feed only when one moved.
241
+ */
242
+ export declare const CreationConsole_PulseSummary_Schema: z.ZodObject<{
243
+ asked: z.ZodNumber;
244
+ acceptable: z.ZodNumber;
245
+ failed: z.ZodNumber;
246
+ computedAt: z.ZodString;
247
+ }, z.core.$strip>;
248
+ export type CreationConsole_PulseSummary = z.infer<typeof CreationConsole_PulseSummary_Schema>;
249
+ export declare const CreationConsole_Pulse_Schema: z.ZodObject<{
250
+ sequence: z.ZodNumber;
251
+ changedAt: z.ZodNullable<z.ZodString>;
252
+ runsInFlight: z.ZodNumber;
253
+ summary: z.ZodNullable<z.ZodObject<{
254
+ asked: z.ZodNumber;
255
+ acceptable: z.ZodNumber;
256
+ failed: z.ZodNumber;
257
+ computedAt: z.ZodString;
258
+ }, z.core.$strip>>;
259
+ }, z.core.$strip>;
260
+ export type CreationConsole_Pulse = z.infer<typeof CreationConsole_Pulse_Schema>;
261
+ /** The pulse a feed's lines imply — one counting rule, used by the companion when it serves a feed. */
262
+ export declare function summarizeCreationConsoleFeed(feed: CreationConsole_Feed): CreationConsole_PulseSummary;
263
+ /**
264
+ * Where a running dev companion says it listens (#1657) — `<app>/.wildo-saas/state/companion-endpoint.json`.
265
+ *
266
+ * Written by the companion once its server is up, beside `companion.token`, because the one party that
267
+ * KNOWS the address is the process listening on it. It exists for callers that must answer in
268
+ * milliseconds — the console's per-prompt hook and its status line — which cannot afford the CLI's own
269
+ * address resolution (it evaluates the authored infrastructure config). The record may outlive the
270
+ * process; a caller treats a refused connection as "not running", never the file's presence.
271
+ */
272
+ export declare const COMPANION_ENDPOINT_FILE_NAME = "companion-endpoint.json";
273
+ export declare const CompanionEndpointRecord_Schema: z.ZodObject<{
274
+ origin: z.ZodString;
275
+ pid: z.ZodNumber;
276
+ startedAt: z.ZodString;
277
+ }, z.core.$strip>;
278
+ export type CompanionEndpointRecord = z.infer<typeof CompanionEndpointRecord_Schema>;
279
+ //# sourceMappingURL=workbench-creation-console.custom.shared.schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbench-creation-console.custom.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/workbench/workbench-creation-console.custom.shared.schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,303 @@
1
+ import { z } from 'zod';
2
+ import { WorkbenchCreationHomeLineKind, WorkbenchCreationHomeSection } from './workbench-creation-plane.custom.shared.schemas.js';
3
+ /**
4
+ * The CREATION CONSOLE contract — how a coding-agent session (Claude Code, or any agent driving
5
+ * `wildo`) follows what the companion did and answers what the companion asks.
6
+ *
7
+ * ## Why a console needs its own contract beside the workbench's resources
8
+ *
9
+ * The companion is the master of application creation: it runs playbooks, dispatches coding
10
+ * workers over ACP, runs judges and generation steps. The person drives it from a CONSOLE — the
11
+ * coding-agent session they are already working in — and the workbench becomes the dashboard of
12
+ * that state (Paul, 2026-09-25). Two things are then owed to the console:
13
+ *
14
+ * 1. FEEDBACK: what the companion did (a run completed or was refused, a dispatch settled, a judge
15
+ * verdict) and what it now waits for.
16
+ * 2. ANSWERS: every question the companion asks must be answerable from the console, once, and
17
+ * the answer must reach the same service the workbench's own operation reaches.
18
+ *
19
+ * The facts already exist as creation-plane rows (Home's lines, the waiting runs, the parked coding
20
+ * questions, the dossier). The workbench reaches them through the resource plane, which needs a
21
+ * signed-in PERSON; a console reaches the companion through the local-token plane
22
+ * (`/api/companion/*`), which is how every `wildo` verb already talks to it. This contract is that
23
+ * plane's view of the SAME rows — no second derivation, and no second implementation of an answer:
24
+ * each answer kind calls the companion service the matching workbench operation calls.
25
+ *
26
+ * ## Why the question queue is ONE list rather than one read per kind
27
+ *
28
+ * A person (or an agent acting for them) asks "what is waiting on me?" once. Four reads, each with
29
+ * its own identity and answer route, is what makes a console skip one. So the companion folds the
30
+ * four row kinds into one list with one identity scheme and one answer door, and says per question
31
+ * which actions it admits — the console restates no policy.
32
+ */
33
+ /**
34
+ * WHAT KIND of question a queued item is — which companion lane asked it, and so which service an
35
+ * answer reaches.
36
+ */
37
+ export var CreationConsoleQuestionKind;
38
+ (function (CreationConsoleQuestionKind) {
39
+ /**
40
+ * A playbook run SUSPENDED mid-derivation on a round of questions it cannot decide alone. One item
41
+ * per round, carrying every question of the round: the run resumes on one answer to the round.
42
+ */
43
+ CreationConsoleQuestionKind["CLARIFICATION"] = "clarification";
44
+ /** A coding worker (an ACP session the companion dispatched) PARKED on a question it asked. */
45
+ CreationConsoleQuestionKind["PARKED_CODING_QUESTION"] = "parked-coding-question";
46
+ /**
47
+ * An interview question a step can run as soon as it is answered — the dossier entry the workbench
48
+ * shows as "asked of you now". Answering lands `creator-inputs`; a commit accepts it.
49
+ */
50
+ CreationConsoleQuestionKind["INTERVIEW"] = "interview";
51
+ /**
52
+ * A fact a drafted governed document still needs. LISTED so the queue is total over what waits on
53
+ * the person, NOT answerable here: landing governance facts is a whole-document sitting that also
54
+ * names the governance scope and who decided, and `compliance-is-derived-from-the-product.md`
55
+ * holds that questionnaire where it is until the evidence tier exists. Answer it in the workbench.
56
+ */
57
+ CreationConsoleQuestionKind["GOVERNANCE_FACT"] = "governance-fact";
58
+ })(CreationConsoleQuestionKind || (CreationConsoleQuestionKind = {}));
59
+ /**
60
+ * WHAT an answer does — the industry three-action model the playbook clarification already uses
61
+ * (MCP elicitation's vocabulary), so every kind of question speaks it.
62
+ */
63
+ export var CreationConsoleAnswerAction;
64
+ (function (CreationConsoleAnswerAction) {
65
+ /** Give the answer(s). */
66
+ CreationConsoleAnswerAction["ANSWER"] = "answer";
67
+ /**
68
+ * Let the asking derivation decide and state its assumption. Clarifications only. May carry the answers
69
+ * the person did give: the run then decides only the questions left unanswered.
70
+ */
71
+ CreationConsoleAnswerAction["DECLINE"] = "decline";
72
+ /** Abandon the run that asked. Clarifications and parked coding questions. */
73
+ CreationConsoleAnswerAction["CANCEL"] = "cancel";
74
+ })(CreationConsoleAnswerAction || (CreationConsoleAnswerAction = {}));
75
+ /** One question inside a queued item — a clarification round carries several, the others one. */
76
+ export const CreationConsole_QuestionField_Schema = z.object({
77
+ /** The ref an answer names. */
78
+ ref: z.string().min(1),
79
+ /** The question as a person reads it, verbatim from whoever asked. */
80
+ question: z.string().min(1),
81
+ /** Why it is asked — what cannot be decided without it. NULL when the asker states none. */
82
+ why: z.string().min(1).nullable(),
83
+ /**
84
+ * The answer's shape, in the ASKER's own vocabulary — deliberately a string, because this field carries
85
+ * two: `HumanDecision_FieldKind` (`free_text` | `choice` | `confirm`) for a playbook round, a parked run
86
+ * and an interview question, and the governed-document questionnaire's answer kind for a governance
87
+ * fact. One enum here would be false for one of them.
88
+ */
89
+ kind: z.string().min(1),
90
+ /** The closed answer set for a `choice`; empty otherwise. */
91
+ options: z.array(z.string()),
92
+ });
93
+ export const CreationConsole_Question_Schema = z.object({
94
+ /**
95
+ * `<kind>:<creation-plane row id>`. Row ids are sanitized to `[a-zA-Z0-9_-]`, so the first `:`
96
+ * always separates the kind — see {@link parseCreationConsoleQuestionId}.
97
+ */
98
+ questionId: z.string().min(1),
99
+ kind: z.enum(CreationConsoleQuestionKind),
100
+ /** When it was asked, ISO-8601. NULL when the row records no instant (an interview question has none). */
101
+ askedAt: z.string().nullable(),
102
+ /** The playbook that asks, when a playbook asks. */
103
+ playbookRef: z.string().nullable(),
104
+ /** The build-plan task the asking coding run was working on, for a parked coding question. */
105
+ taskRef: z.string().nullable(),
106
+ /**
107
+ * The opened INSTANCE of the step the question is asked for (#1609), for an interview question; NULL for
108
+ * the step itself and for other kinds. An answer lands on that instance, so the reader must see which.
109
+ */
110
+ instanceKey: z.string().nullable(),
111
+ /** The governed document, for a governance fact. */
112
+ definitionRef: z.string().nullable(),
113
+ /**
114
+ * WHICH revision of the question the console read — the clarification's round, the parked run's
115
+ * suspension ref. An answer must echo it: a run that has moved on to another question refuses an
116
+ * answer written for the previous one (#1584, #1581) instead of applying it to the wrong question.
117
+ * NULL for kinds that have no revision.
118
+ */
119
+ revision: z.string().nullable(),
120
+ /** The questions to answer, in order. */
121
+ fields: z.array(CreationConsole_QuestionField_Schema),
122
+ /** What an answer may do for THIS item — empty when the console cannot answer it. */
123
+ actions: z.array(z.enum(CreationConsoleAnswerAction)),
124
+ /*
125
+ * Facts that change what answering MEANS, for the reader to weigh first. Carried as facts rather
126
+ * than as a sentence: the words belong to whoever renders them (`display-text-comes-from-i18n.md`).
127
+ */
128
+ /** The family a suspended run was producing when it stopped to ask. */
129
+ producingFamily: z.string().nullable(),
130
+ /** The suspended run was a dry run: answering it writes nothing. NULL for other kinds. */
131
+ dryRun: z.boolean().nullable(),
132
+ /** FALSE when the parked coding run cannot re-enter its own session, so an answer starts a new one. NULL for other kinds. */
133
+ resumable: z.boolean().nullable(),
134
+ /** Every family an interview answer feeds — what goes stale when it changes. Empty for other kinds. */
135
+ affectsFamilies: z.array(z.string()),
136
+ /**
137
+ * The signed-in person a clarification is ROUTED to (#1751) — whoever started its run from the workbench
138
+ * or the conversation. Only they may answer it, and the console carries no person, so such an item has
139
+ * no actions here: it is answered in the workbench, signed in as them. NULL when it is unrouted.
140
+ */
141
+ routedToUserId: z.string().nullable(),
142
+ });
143
+ export const CreationConsole_QuestionQueue_Schema = z.object({
144
+ /** When the queue was read, ISO-8601. */
145
+ computedAt: z.string(),
146
+ questions: z.array(CreationConsole_Question_Schema),
147
+ });
148
+ /**
149
+ * One answer to one field. It carries its OWN author because a round is answered in one call while its
150
+ * fields may be answered by different parties (#1658): an agent derives one from a declared fact, the
151
+ * person decides the next. With one author per request, a mixed round either stamped the person's name
152
+ * on the agent's derivation or was refused as incomplete — the agent answering alone could not cover the
153
+ * judgement half, and the resume refuses a round answered in part.
154
+ */
155
+ export const CreationConsole_Answer_Schema = z.object({
156
+ ref: z.string().min(1),
157
+ value: z.string().min(1),
158
+ /** Who gave THIS answer; overrides the request's `answeredByRef` for this field. Same vocabulary. */
159
+ answeredByRef: z.string().min(1).optional(),
160
+ });
161
+ export const CreationConsole_AnswerRequest_Schema = z.object({
162
+ questionId: z.string().min(1),
163
+ /** The `revision` of the item as it was READ. Required for the kinds that carry one. */
164
+ revision: z.string().min(1).nullable().optional(),
165
+ action: z.enum(CreationConsoleAnswerAction),
166
+ /**
167
+ * One entry per answered field, by its `ref`. Required for `answer`, which must cover every field.
168
+ * A clarification's `decline` may carry the fields the person DID answer and delegates only the rest
169
+ * (#1658), so one round can mix what a person decided with what they left to the run.
170
+ */
171
+ answers: z.array(CreationConsole_Answer_Schema).optional(),
172
+ /**
173
+ * WHO answered — recorded for EVERY kind (#1658): on an interview answer in the dossier, on a
174
+ * clarification in the committed `DECISIONS.md`, on a parked coding answer in `CODING-ANSWERS.md`.
175
+ * The local-token plane proves only that the caller
176
+ * is on this machine — the same trust as a git commit author, which is what accepts the answer
177
+ * anyway (`one-source-of-truth.md` rule 7) — so `wildo` sends the workspace's git identity as
178
+ * `git:<email>` unless told otherwise, and an agent answering on its own sends `agent:<name>`. The
179
+ * prefix matters because the same dossier field holds the workbench's signed-in user ids: it says
180
+ * which door an answer came through. Required for an interview answer (the dossier cannot record
181
+ * one without it); optional for the others, which then record nothing rather than a guess.
182
+ *
183
+ * The DEFAULT author of every answer in the request: an answer carrying its own `answeredByRef` keeps
184
+ * it. A parked coding question and an interview answer are one field each, so the two cannot differ.
185
+ */
186
+ answeredByRef: z.string().min(1).optional(),
187
+ });
188
+ export const CreationConsole_AnswerOutcome_Schema = z.looseObject({
189
+ questionId: z.string().min(1),
190
+ kind: z.enum(CreationConsoleQuestionKind),
191
+ action: z.enum(CreationConsoleAnswerAction),
192
+ /** What the answering service returned — its own shape (a resumed run's outcome, a landed dossier file). */
193
+ outcome: z.unknown(),
194
+ });
195
+ /**
196
+ * One FEED line: a Home line (what happened, what is asked, what could come next) with the row it
197
+ * points at attached, so a console reads a run's verdict or a dispatch's error without a second call.
198
+ *
199
+ * `at` is ISO-8601 here — this is a JSON contract, not a resource row.
200
+ */
201
+ export const CreationConsole_FeedLine_Schema = z.object({
202
+ lineId: z.string().min(1),
203
+ section: z.enum(WorkbenchCreationHomeSection),
204
+ kind: z.enum(WorkbenchCreationHomeLineKind),
205
+ at: z.string().nullable(),
206
+ playbookRef: z.string().nullable(),
207
+ taskRef: z.string().nullable(),
208
+ subject: z.string().nullable(),
209
+ failed: z.boolean(),
210
+ acceptable: z.boolean(),
211
+ needsAnswers: z.boolean(),
212
+ stuckReason: z.string().nullable(),
213
+ targetResourceType: z.string().min(1),
214
+ targetResourceId: z.string().min(1),
215
+ /** The row the line points at, as the creation plane serves it. NULL when it has gone since. */
216
+ target: z.record(z.string(), z.unknown()).nullable(),
217
+ /** The queued question this line is about, when it is about exactly one — answer it by this id. */
218
+ questionId: z.string().nullable(),
219
+ });
220
+ export const CreationConsole_Feed_Schema = z.object({
221
+ computedAt: z.string(),
222
+ lines: z.array(CreationConsole_FeedLine_Schema),
223
+ });
224
+ /** The one identity rule, applied by the companion when it emits and when it resolves an answer. */
225
+ export function formatCreationConsoleQuestionId(kind, rowId) {
226
+ return `${kind}:${rowId}`;
227
+ }
228
+ /** The inverse of {@link formatCreationConsoleQuestionId}; `null` for anything that is not one. */
229
+ export function parseCreationConsoleQuestionId(questionId) {
230
+ const separator = questionId.indexOf(':');
231
+ if (separator <= 0 || separator === questionId.length - 1)
232
+ return null;
233
+ const kind = Object.values(CreationConsoleQuestionKind).find((candidate) => candidate === questionId.slice(0, separator));
234
+ return kind ? { kind, rowId: questionId.slice(separator + 1) } : null;
235
+ }
236
+ /**
237
+ * The workbench DEEP LINK (#1652): `?open=<resourceType>:<resourceId>` opens that creation-plane row
238
+ * in the workbench's detail pane, the way clicking its Home line does. `wildo workbench open <ref>`
239
+ * writes it; the workbench reads it once and drops it. One format, owned here, so the writer and the
240
+ * reader cannot disagree about it.
241
+ *
242
+ * The FIRST `:` separates the two, because a resource type never contains one and a row id may.
243
+ */
244
+ export const WORKBENCH_OPEN_DETAIL_QUERY_PARAM = 'open';
245
+ export function formatWorkbenchOpenDetailParam(resourceType, resourceId) {
246
+ return `${resourceType}:${resourceId}`;
247
+ }
248
+ /** The inverse of {@link formatWorkbenchOpenDetailParam}; `null` for anything that is not one. */
249
+ export function parseWorkbenchOpenDetailParam(value) {
250
+ const separator = value.indexOf(':');
251
+ if (separator <= 0 || separator === value.length - 1)
252
+ return null;
253
+ return { resourceType: value.slice(0, separator), resourceId: value.slice(separator + 1) };
254
+ }
255
+ /**
256
+ * The PULSE (#1657): a read cheap enough to poll every few seconds from a hook or a status line.
257
+ *
258
+ * Nothing in it is derived on request. `sequence` and `changedAt` move whenever the creation plane's
259
+ * boards are invalidated (every mutation path ends there) or a watched board is republished;
260
+ * `runsInFlight` is the process's own running-run count; `summary` is what the most recent FEED read
261
+ * counted, with its instant — `null` until someone has read the feed, because computing it here would
262
+ * make the pulse as slow as the feed. A poller compares pulses and reads the feed only when one moved.
263
+ */
264
+ export const CreationConsole_PulseSummary_Schema = z.object({
265
+ /** Lines in the ASKED section: questions waiting on the person. */
266
+ asked: z.number().int().nonnegative(),
267
+ /** Lines marked acceptable: finished work waiting to be committed. */
268
+ acceptable: z.number().int().nonnegative(),
269
+ /** SINCE lines that failed. */
270
+ failed: z.number().int().nonnegative(),
271
+ computedAt: z.string(),
272
+ });
273
+ export const CreationConsole_Pulse_Schema = z.object({
274
+ sequence: z.number().int().nonnegative(),
275
+ changedAt: z.string().nullable(),
276
+ runsInFlight: z.number().int().nonnegative(),
277
+ summary: CreationConsole_PulseSummary_Schema.nullable(),
278
+ });
279
+ /** The pulse a feed's lines imply — one counting rule, used by the companion when it serves a feed. */
280
+ export function summarizeCreationConsoleFeed(feed) {
281
+ return {
282
+ asked: feed.lines.filter((line) => line.section === WorkbenchCreationHomeSection.ASKED).length,
283
+ acceptable: feed.lines.filter((line) => line.acceptable).length,
284
+ failed: feed.lines.filter((line) => line.section === WorkbenchCreationHomeSection.SINCE && line.failed).length,
285
+ computedAt: feed.computedAt,
286
+ };
287
+ }
288
+ /**
289
+ * Where a running dev companion says it listens (#1657) — `<app>/.wildo-saas/state/companion-endpoint.json`.
290
+ *
291
+ * Written by the companion once its server is up, beside `companion.token`, because the one party that
292
+ * KNOWS the address is the process listening on it. It exists for callers that must answer in
293
+ * milliseconds — the console's per-prompt hook and its status line — which cannot afford the CLI's own
294
+ * address resolution (it evaluates the authored infrastructure config). The record may outlive the
295
+ * process; a caller treats a refused connection as "not running", never the file's presence.
296
+ */
297
+ export const COMPANION_ENDPOINT_FILE_NAME = 'companion-endpoint.json';
298
+ export const CompanionEndpointRecord_Schema = z.object({
299
+ origin: z.string().url(),
300
+ pid: z.number().int().positive(),
301
+ startedAt: z.string(),
302
+ });
303
+ //# sourceMappingURL=workbench-creation-console.custom.shared.schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbench-creation-console.custom.shared.schemas.js","sourceRoot":"","sources":["../../../../src/workbench/workbench-creation-console.custom.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\n\nimport { WorkbenchCreationHomeLineKind, WorkbenchCreationHomeSection } from './workbench-creation-plane.custom.shared.schemas';\n\n/**\n * The CREATION CONSOLE contract — how a coding-agent session (Claude Code, or any agent driving\n * `wildo`) follows what the companion did and answers what the companion asks.\n *\n * ## Why a console needs its own contract beside the workbench's resources\n *\n * The companion is the master of application creation: it runs playbooks, dispatches coding\n * workers over ACP, runs judges and generation steps. The person drives it from a CONSOLE — the\n * coding-agent session they are already working in — and the workbench becomes the dashboard of\n * that state (Paul, 2026-09-25). Two things are then owed to the console:\n *\n * 1. FEEDBACK: what the companion did (a run completed or was refused, a dispatch settled, a judge\n * verdict) and what it now waits for.\n * 2. ANSWERS: every question the companion asks must be answerable from the console, once, and\n * the answer must reach the same service the workbench's own operation reaches.\n *\n * The facts already exist as creation-plane rows (Home's lines, the waiting runs, the parked coding\n * questions, the dossier). The workbench reaches them through the resource plane, which needs a\n * signed-in PERSON; a console reaches the companion through the local-token plane\n * (`/api/companion/*`), which is how every `wildo` verb already talks to it. This contract is that\n * plane's view of the SAME rows — no second derivation, and no second implementation of an answer:\n * each answer kind calls the companion service the matching workbench operation calls.\n *\n * ## Why the question queue is ONE list rather than one read per kind\n *\n * A person (or an agent acting for them) asks \"what is waiting on me?\" once. Four reads, each with\n * its own identity and answer route, is what makes a console skip one. So the companion folds the\n * four row kinds into one list with one identity scheme and one answer door, and says per question\n * which actions it admits — the console restates no policy.\n */\n\n/**\n * WHAT KIND of question a queued item is — which companion lane asked it, and so which service an\n * answer reaches.\n */\nexport enum CreationConsoleQuestionKind {\n /**\n * A playbook run SUSPENDED mid-derivation on a round of questions it cannot decide alone. One item\n * per round, carrying every question of the round: the run resumes on one answer to the round.\n */\n CLARIFICATION = 'clarification',\n /** A coding worker (an ACP session the companion dispatched) PARKED on a question it asked. */\n PARKED_CODING_QUESTION = 'parked-coding-question',\n /**\n * An interview question a step can run as soon as it is answered — the dossier entry the workbench\n * shows as \"asked of you now\". Answering lands `creator-inputs`; a commit accepts it.\n */\n INTERVIEW = 'interview',\n /**\n * A fact a drafted governed document still needs. LISTED so the queue is total over what waits on\n * the person, NOT answerable here: landing governance facts is a whole-document sitting that also\n * names the governance scope and who decided, and `compliance-is-derived-from-the-product.md`\n * holds that questionnaire where it is until the evidence tier exists. Answer it in the workbench.\n */\n GOVERNANCE_FACT = 'governance-fact',\n}\n\n/**\n * WHAT an answer does — the industry three-action model the playbook clarification already uses\n * (MCP elicitation's vocabulary), so every kind of question speaks it.\n */\nexport enum CreationConsoleAnswerAction {\n /** Give the answer(s). */\n ANSWER = 'answer',\n /**\n * Let the asking derivation decide and state its assumption. Clarifications only. May carry the answers\n * the person did give: the run then decides only the questions left unanswered.\n */\n DECLINE = 'decline',\n /** Abandon the run that asked. Clarifications and parked coding questions. */\n CANCEL = 'cancel',\n}\n\n/** One question inside a queued item — a clarification round carries several, the others one. */\nexport const CreationConsole_QuestionField_Schema = z.object({\n /** The ref an answer names. */\n ref: z.string().min(1),\n /** The question as a person reads it, verbatim from whoever asked. */\n question: z.string().min(1),\n /** Why it is asked — what cannot be decided without it. NULL when the asker states none. */\n why: z.string().min(1).nullable(),\n /**\n * The answer's shape, in the ASKER's own vocabulary — deliberately a string, because this field carries\n * two: `HumanDecision_FieldKind` (`free_text` | `choice` | `confirm`) for a playbook round, a parked run\n * and an interview question, and the governed-document questionnaire's answer kind for a governance\n * fact. One enum here would be false for one of them.\n */\n kind: z.string().min(1),\n /** The closed answer set for a `choice`; empty otherwise. */\n options: z.array(z.string()),\n});\nexport type CreationConsole_QuestionField = z.infer<typeof CreationConsole_QuestionField_Schema>;\n\nexport const CreationConsole_Question_Schema = z.object({\n /**\n * `<kind>:<creation-plane row id>`. Row ids are sanitized to `[a-zA-Z0-9_-]`, so the first `:`\n * always separates the kind — see {@link parseCreationConsoleQuestionId}.\n */\n questionId: z.string().min(1),\n kind: z.enum(CreationConsoleQuestionKind),\n /** When it was asked, ISO-8601. NULL when the row records no instant (an interview question has none). */\n askedAt: z.string().nullable(),\n /** The playbook that asks, when a playbook asks. */\n playbookRef: z.string().nullable(),\n /** The build-plan task the asking coding run was working on, for a parked coding question. */\n taskRef: z.string().nullable(),\n /**\n * The opened INSTANCE of the step the question is asked for (#1609), for an interview question; NULL for\n * the step itself and for other kinds. An answer lands on that instance, so the reader must see which.\n */\n instanceKey: z.string().nullable(),\n /** The governed document, for a governance fact. */\n definitionRef: z.string().nullable(),\n /**\n * WHICH revision of the question the console read — the clarification's round, the parked run's\n * suspension ref. An answer must echo it: a run that has moved on to another question refuses an\n * answer written for the previous one (#1584, #1581) instead of applying it to the wrong question.\n * NULL for kinds that have no revision.\n */\n revision: z.string().nullable(),\n /** The questions to answer, in order. */\n fields: z.array(CreationConsole_QuestionField_Schema),\n /** What an answer may do for THIS item — empty when the console cannot answer it. */\n actions: z.array(z.enum(CreationConsoleAnswerAction)),\n /*\n * Facts that change what answering MEANS, for the reader to weigh first. Carried as facts rather\n * than as a sentence: the words belong to whoever renders them (`display-text-comes-from-i18n.md`).\n */\n /** The family a suspended run was producing when it stopped to ask. */\n producingFamily: z.string().nullable(),\n /** The suspended run was a dry run: answering it writes nothing. NULL for other kinds. */\n dryRun: z.boolean().nullable(),\n /** FALSE when the parked coding run cannot re-enter its own session, so an answer starts a new one. NULL for other kinds. */\n resumable: z.boolean().nullable(),\n /** Every family an interview answer feeds — what goes stale when it changes. Empty for other kinds. */\n affectsFamilies: z.array(z.string()),\n /**\n * The signed-in person a clarification is ROUTED to (#1751) — whoever started its run from the workbench\n * or the conversation. Only they may answer it, and the console carries no person, so such an item has\n * no actions here: it is answered in the workbench, signed in as them. NULL when it is unrouted.\n */\n routedToUserId: z.string().nullable(),\n});\nexport type CreationConsole_Question = z.infer<typeof CreationConsole_Question_Schema>;\n\nexport const CreationConsole_QuestionQueue_Schema = z.object({\n /** When the queue was read, ISO-8601. */\n computedAt: z.string(),\n questions: z.array(CreationConsole_Question_Schema),\n});\nexport type CreationConsole_QuestionQueue = z.infer<typeof CreationConsole_QuestionQueue_Schema>;\n\n/**\n * One answer to one field. It carries its OWN author because a round is answered in one call while its\n * fields may be answered by different parties (#1658): an agent derives one from a declared fact, the\n * person decides the next. With one author per request, a mixed round either stamped the person's name\n * on the agent's derivation or was refused as incomplete — the agent answering alone could not cover the\n * judgement half, and the resume refuses a round answered in part.\n */\nexport const CreationConsole_Answer_Schema = z.object({\n ref: z.string().min(1),\n value: z.string().min(1),\n /** Who gave THIS answer; overrides the request's `answeredByRef` for this field. Same vocabulary. */\n answeredByRef: z.string().min(1).optional(),\n});\nexport type CreationConsole_Answer = z.infer<typeof CreationConsole_Answer_Schema>;\n\nexport const CreationConsole_AnswerRequest_Schema = z.object({\n questionId: z.string().min(1),\n /** The `revision` of the item as it was READ. Required for the kinds that carry one. */\n revision: z.string().min(1).nullable().optional(),\n action: z.enum(CreationConsoleAnswerAction),\n /**\n * One entry per answered field, by its `ref`. Required for `answer`, which must cover every field.\n * A clarification's `decline` may carry the fields the person DID answer and delegates only the rest\n * (#1658), so one round can mix what a person decided with what they left to the run.\n */\n answers: z.array(CreationConsole_Answer_Schema).optional(),\n /**\n * WHO answered — recorded for EVERY kind (#1658): on an interview answer in the dossier, on a\n * clarification in the committed `DECISIONS.md`, on a parked coding answer in `CODING-ANSWERS.md`.\n * The local-token plane proves only that the caller\n * is on this machine — the same trust as a git commit author, which is what accepts the answer\n * anyway (`one-source-of-truth.md` rule 7) — so `wildo` sends the workspace's git identity as\n * `git:<email>` unless told otherwise, and an agent answering on its own sends `agent:<name>`. The\n * prefix matters because the same dossier field holds the workbench's signed-in user ids: it says\n * which door an answer came through. Required for an interview answer (the dossier cannot record\n * one without it); optional for the others, which then record nothing rather than a guess.\n *\n * The DEFAULT author of every answer in the request: an answer carrying its own `answeredByRef` keeps\n * it. A parked coding question and an interview answer are one field each, so the two cannot differ.\n */\n answeredByRef: z.string().min(1).optional(),\n});\nexport type CreationConsole_AnswerRequest = z.infer<typeof CreationConsole_AnswerRequest_Schema>;\n\nexport const CreationConsole_AnswerOutcome_Schema = z.looseObject({\n questionId: z.string().min(1),\n kind: z.enum(CreationConsoleQuestionKind),\n action: z.enum(CreationConsoleAnswerAction),\n /** What the answering service returned — its own shape (a resumed run's outcome, a landed dossier file). */\n outcome: z.unknown(),\n});\nexport type CreationConsole_AnswerOutcome = z.infer<typeof CreationConsole_AnswerOutcome_Schema>;\n\n/**\n * One FEED line: a Home line (what happened, what is asked, what could come next) with the row it\n * points at attached, so a console reads a run's verdict or a dispatch's error without a second call.\n *\n * `at` is ISO-8601 here — this is a JSON contract, not a resource row.\n */\nexport const CreationConsole_FeedLine_Schema = z.object({\n lineId: z.string().min(1),\n section: z.enum(WorkbenchCreationHomeSection),\n kind: z.enum(WorkbenchCreationHomeLineKind),\n at: z.string().nullable(),\n playbookRef: z.string().nullable(),\n taskRef: z.string().nullable(),\n subject: z.string().nullable(),\n failed: z.boolean(),\n acceptable: z.boolean(),\n needsAnswers: z.boolean(),\n stuckReason: z.string().nullable(),\n targetResourceType: z.string().min(1),\n targetResourceId: z.string().min(1),\n /** The row the line points at, as the creation plane serves it. NULL when it has gone since. */\n target: z.record(z.string(), z.unknown()).nullable(),\n /** The queued question this line is about, when it is about exactly one — answer it by this id. */\n questionId: z.string().nullable(),\n});\nexport type CreationConsole_FeedLine = z.infer<typeof CreationConsole_FeedLine_Schema>;\n\nexport const CreationConsole_Feed_Schema = z.object({\n computedAt: z.string(),\n lines: z.array(CreationConsole_FeedLine_Schema),\n});\nexport type CreationConsole_Feed = z.infer<typeof CreationConsole_Feed_Schema>;\n\n/** The one identity rule, applied by the companion when it emits and when it resolves an answer. */\nexport function formatCreationConsoleQuestionId(kind: CreationConsoleQuestionKind, rowId: string): string {\n return `${kind}:${rowId}`;\n}\n\n/** The inverse of {@link formatCreationConsoleQuestionId}; `null` for anything that is not one. */\nexport function parseCreationConsoleQuestionId(questionId: string): { kind: CreationConsoleQuestionKind; rowId: string } | null {\n const separator = questionId.indexOf(':');\n if (separator <= 0 || separator === questionId.length - 1) return null;\n const kind = Object.values(CreationConsoleQuestionKind).find((candidate) => candidate === questionId.slice(0, separator));\n return kind ? { kind, rowId: questionId.slice(separator + 1) } : null;\n}\n\n/**\n * The workbench DEEP LINK (#1652): `?open=<resourceType>:<resourceId>` opens that creation-plane row\n * in the workbench's detail pane, the way clicking its Home line does. `wildo workbench open <ref>`\n * writes it; the workbench reads it once and drops it. One format, owned here, so the writer and the\n * reader cannot disagree about it.\n *\n * The FIRST `:` separates the two, because a resource type never contains one and a row id may.\n */\nexport const WORKBENCH_OPEN_DETAIL_QUERY_PARAM = 'open';\n\nexport function formatWorkbenchOpenDetailParam(resourceType: string, resourceId: string): string {\n return `${resourceType}:${resourceId}`;\n}\n\n/** The inverse of {@link formatWorkbenchOpenDetailParam}; `null` for anything that is not one. */\nexport function parseWorkbenchOpenDetailParam(value: string): { resourceType: string; resourceId: string } | null {\n const separator = value.indexOf(':');\n if (separator <= 0 || separator === value.length - 1) return null;\n return { resourceType: value.slice(0, separator), resourceId: value.slice(separator + 1) };\n}\n\n/**\n * The PULSE (#1657): a read cheap enough to poll every few seconds from a hook or a status line.\n *\n * Nothing in it is derived on request. `sequence` and `changedAt` move whenever the creation plane's\n * boards are invalidated (every mutation path ends there) or a watched board is republished;\n * `runsInFlight` is the process's own running-run count; `summary` is what the most recent FEED read\n * counted, with its instant — `null` until someone has read the feed, because computing it here would\n * make the pulse as slow as the feed. A poller compares pulses and reads the feed only when one moved.\n */\nexport const CreationConsole_PulseSummary_Schema = z.object({\n /** Lines in the ASKED section: questions waiting on the person. */\n asked: z.number().int().nonnegative(),\n /** Lines marked acceptable: finished work waiting to be committed. */\n acceptable: z.number().int().nonnegative(),\n /** SINCE lines that failed. */\n failed: z.number().int().nonnegative(),\n computedAt: z.string(),\n});\nexport type CreationConsole_PulseSummary = z.infer<typeof CreationConsole_PulseSummary_Schema>;\n\nexport const CreationConsole_Pulse_Schema = z.object({\n sequence: z.number().int().nonnegative(),\n changedAt: z.string().nullable(),\n runsInFlight: z.number().int().nonnegative(),\n summary: CreationConsole_PulseSummary_Schema.nullable(),\n});\nexport type CreationConsole_Pulse = z.infer<typeof CreationConsole_Pulse_Schema>;\n\n/** The pulse a feed's lines imply — one counting rule, used by the companion when it serves a feed. */\nexport function summarizeCreationConsoleFeed(feed: CreationConsole_Feed): CreationConsole_PulseSummary {\n return {\n asked: feed.lines.filter((line) => line.section === WorkbenchCreationHomeSection.ASKED).length,\n acceptable: feed.lines.filter((line) => line.acceptable).length,\n failed: feed.lines.filter((line) => line.section === WorkbenchCreationHomeSection.SINCE && line.failed).length,\n computedAt: feed.computedAt,\n };\n}\n\n/**\n * Where a running dev companion says it listens (#1657) — `<app>/.wildo-saas/state/companion-endpoint.json`.\n *\n * Written by the companion once its server is up, beside `companion.token`, because the one party that\n * KNOWS the address is the process listening on it. It exists for callers that must answer in\n * milliseconds — the console's per-prompt hook and its status line — which cannot afford the CLI's own\n * address resolution (it evaluates the authored infrastructure config). The record may outlive the\n * process; a caller treats a refused connection as \"not running\", never the file's presence.\n */\nexport const COMPANION_ENDPOINT_FILE_NAME = 'companion-endpoint.json';\n\nexport const CompanionEndpointRecord_Schema = z.object({\n origin: z.string().url(),\n pid: z.number().int().positive(),\n startedAt: z.string(),\n});\nexport type CompanionEndpointRecord = z.infer<typeof CompanionEndpointRecord_Schema>;\n"]}