yarramate 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +9 -1
  2. package/catalogues/core-enrichment.yaml +52 -1
  3. package/dist/adapters/graphify-cli.js +0 -0
  4. package/dist/adapters/likec4-cli.js +0 -0
  5. package/dist/adapters/likec4-export.d.ts +1 -1
  6. package/dist/adapters/likec4-export.js +32 -0
  7. package/dist/adapters/mcp-cli.js +0 -0
  8. package/dist/adapters/visual/client.js +0 -1
  9. package/dist/adapters/visual/protocol-contract.d.ts +118 -35
  10. package/dist/adapters/visual/protocol-contract.js +1 -11
  11. package/dist/adapters/visual/protocol.d.ts +8 -1
  12. package/dist/adapters/visual/protocol.js +86 -46
  13. package/dist/adapters/visual/request.d.ts +37 -0
  14. package/dist/adapters/visual/request.js +131 -0
  15. package/dist/adapters/visual/session-server.d.ts +12 -14
  16. package/dist/adapters/visual/session-server.js +641 -283
  17. package/dist/adapters/visual/session-store.d.ts +31 -29
  18. package/dist/adapters/visual/session-store.js +94 -94
  19. package/dist/adapters/visual/wire.d.ts +36 -10
  20. package/dist/adapters/visual-cli.d.ts +3 -0
  21. package/dist/adapters/visual-cli.js +66 -1
  22. package/dist/apply-command.d.ts +10 -0
  23. package/dist/apply-command.js +399 -247
  24. package/dist/cli.js +0 -0
  25. package/dist/compiler.d.ts +66 -0
  26. package/dist/compiler.js +209 -89
  27. package/dist/graph-projection.d.ts +62 -0
  28. package/dist/graph-projection.js +222 -0
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +1 -1
  31. package/dist/interrogate-command.d.ts +2 -0
  32. package/dist/interrogate-command.js +22 -0
  33. package/dist/kind-label.d.ts +8 -0
  34. package/dist/kind-label.js +8 -0
  35. package/dist/operations.d.ts +139 -0
  36. package/dist/operations.js +11 -0
  37. package/dist/projection.d.ts +2 -0
  38. package/dist/projection.js +8 -2
  39. package/dist/reconciliation.js +8 -7
  40. package/dist/source-document.d.ts +10 -0
  41. package/dist/source-document.js +21 -1
  42. package/dist/visual-app/assets/index-6oSR9RGM.js +354 -0
  43. package/dist/visual-app/assets/index-dwA9AOr5.css +1 -0
  44. package/dist/visual-app/index.html +2 -2
  45. package/docs/CONSUMING-YARRAMATE.md +25 -19
  46. package/package.json +9 -4
  47. package/schema/yarramate-adapter-mapping.schema.json +1 -1
  48. package/schema/yarramate-apply-result.schema.json +8 -2
  49. package/schema/yarramate-document.schema.json +1 -1
  50. package/schema/yarramate-likec4-diagnostic-result.schema.json +1 -1
  51. package/schema/yarramate-operations.schema.json +203 -1
  52. package/schema/yarramate-projection.schema.json +12 -3
  53. package/schema/yarramate-question-catalogue.schema.json +15 -2
  54. package/schema/yarramate-visual-event.schema.json +143 -0
  55. package/schema/yarramate-visual-graph.schema.json +272 -0
  56. package/schema/yarramate-visual-layout.schema.json +41 -0
  57. package/schema/yarramate-visual-model.schema.json +6 -44
  58. package/schema/yarramate-visual-response.schema.json +170 -19
  59. package/schema/yarramate-visual-session-descriptor.schema.json +1 -1
  60. package/schema/yarramate-visual-session-request.schema.json +0 -70
  61. package/schema/yarramate-visual-session-started.schema.json +2 -9
  62. package/schema/yarramate-visual-status.schema.json +3 -2
  63. package/skills/yarramate-architecture/SKILL.md +20 -13
  64. package/skills/yarramate-architecture/references/journey-checklists.md +4 -2
  65. package/skills/yarramate-architecture/references/native-authoring.md +30 -0
  66. package/skills/yarramate-architecture/references/visual-conversations.md +149 -150
  67. package/dist/adapters/visual/likec4-compiler.d.ts +0 -55
  68. package/dist/adapters/visual/likec4-compiler.js +0 -460
  69. package/dist/visual-app/assets/index-CGvC8e3R.css +0 -1
  70. package/dist/visual-app/assets/index-CXuW1tOj.js +0 -209
package/README.md CHANGED
@@ -184,7 +184,8 @@ people, CI, skills, and agent harnesses.
184
184
 
185
185
  Optional adapters provide LikeC4 visualization from semantic projections,
186
186
  Graphify observations as evidence overlays, loopback-only visual
187
- conversations over a published protocol (beta), and separately governed
187
+ conversations that render the native model and land reviewer edits through
188
+ the same validated `apply` batch (beta), and separately governed
188
189
  compatibility profiles for external languages. Core depends on none of them.
189
190
 
190
191
  YarraMate is not affiliated with or certified by The Open Group. ArchiMate®
@@ -251,6 +252,13 @@ const result = compileWorkspace([
251
252
  lineage for operations that explicitly require kind ancestry. Graph v2
252
253
  remains the stable, graph-only interchange result.
253
254
 
255
+ `compileWorkspaceIncremental(sources, previous)` is the entry point for a
256
+ consumer that recompiles a whole workspace on every write. It returns the
257
+ same result plus an opaque `cache` to hand back on the next call, and
258
+ re-parses only the sources whose text changed; `incremental: false` reports
259
+ that it fell back to a full compile. Reuse is decided by source-text
260
+ equality, so a stale cache costs work but never changes output.
261
+
254
262
  Normative schemas are available through package exports such as
255
263
  `yarramate/schema/document`, `yarramate/schema/workspace`,
256
264
  `yarramate/schema/graph-v2`, `yarramate/schema/projection`,
@@ -1,6 +1,6 @@
1
1
  format: yarramate/question-catalogue/v1
2
2
  id: core-enrichment
3
- version: "0.7"
3
+ version: "0.8"
4
4
  profile: yarramate/core@0.1
5
5
  presentation:
6
6
  title: Core enrichment interview
@@ -1075,3 +1075,54 @@ questions:
1075
1075
  resolution: >-
1076
1076
  Declare architecture states and mark presence with present-in where the
1077
1077
  distinction carries decisions; explicitly decline states otherwise.
1078
+
1079
+ - id: kind-untested
1080
+ wave: hygiene
1081
+ since: "0.8"
1082
+ scope: subject
1083
+ subjects:
1084
+ kinds:
1085
+ - yarramate/core@0.1#resource
1086
+ - yarramate/core@0.1#businessActor
1087
+ - yarramate/core@0.1#businessRole
1088
+ - yarramate/core@0.1#businessCollaboration
1089
+ - yarramate/core@0.1#businessInterface
1090
+ - yarramate/core@0.1#applicationComponent
1091
+ - yarramate/core@0.1#applicationCollaboration
1092
+ - yarramate/core@0.1#applicationInterface
1093
+ - yarramate/core@0.1#node
1094
+ - yarramate/core@0.1#device
1095
+ - yarramate/core@0.1#systemSoftware
1096
+ - yarramate/core@0.1#technologyCollaboration
1097
+ - yarramate/core@0.1#technologyInterface
1098
+ - yarramate/core@0.1#path
1099
+ - yarramate/core@0.1#communicationNetwork
1100
+ - yarramate/core@0.1#equipment
1101
+ - yarramate/core@0.1#facility
1102
+ - yarramate/core@0.1#distributionNetwork
1103
+ trigger:
1104
+ - condition: unconstrained-kind
1105
+ question: >-
1106
+ Nothing in the model tests that {subject.name} is a structural element
1107
+ at all: no behaviour is assigned to it, so reclassifying it as a
1108
+ service, an object, or a goal would compile exactly the same. What
1109
+ does it run, host, or perform?
1110
+ askPlain: >-
1111
+ What does {subject.name} actually do, or what runs on it? The model
1112
+ says what it is but nothing says what it takes part in.
1113
+ materiality: >-
1114
+ A structural kind is a promise that something behaves through this
1115
+ element. Only four relationship kinds constrain the aspect of an
1116
+ endpoint, so where none of them touches the subject the kind is a
1117
+ label no check can contradict — the choice between a node, a piece of
1118
+ system software, and an application component stops carrying
1119
+ information, and diagrams inherit a distinction the model never made.
1120
+ authority: either
1121
+ resolution: >-
1122
+ Assign {subject.name} to the behaviour it performs — the process,
1123
+ function, service, or capability it carries. Assignment is the one
1124
+ claim whose source endpoint must be an active structure, so recording
1125
+ it makes the classification falsifiable. If nothing in scope is
1126
+ assigned to it, reclassify it to a kind that does carry a claim, or
1127
+ retire it with a description saying why it sits outside this
1128
+ architecture.
File without changes
File without changes
@@ -4,7 +4,7 @@ import type { ProjectionResult } from '../projection.js';
4
4
  import type { LikeC4KindMapping } from './likec4-kind-mapping.js';
5
5
  export interface LikeC4ExportDiagnostic {
6
6
  readonly severity: 'error';
7
- readonly code: 'YMLC101' | 'YMLC102' | 'YMLC103' | 'YMLC104' | 'YMLC105' | 'YMLC106' | 'YMLC107' | 'YMLC108' | 'YMLC109' | 'YMLC111';
7
+ readonly code: 'YMLC101' | 'YMLC102' | 'YMLC103' | 'YMLC104' | 'YMLC105' | 'YMLC106' | 'YMLC107' | 'YMLC108' | 'YMLC109' | 'YMLC111' | 'YMLC112';
8
8
  readonly message: string;
9
9
  readonly subject?: string;
10
10
  readonly path: string;
@@ -155,6 +155,38 @@ export function exportLikeC4(projection, mapping, kindMapping, options = {}) {
155
155
  : [` description ${quote(description)}`]), ...metadata, ' }');
156
156
  }
157
157
  }
158
+ // `likec4 validate` accepts an empty model as valid, so it can never notice
159
+ // that selected concepts stopped reaching the emitted text. The shortfall is
160
+ // only visible here, and it is measured on the assembled lines rather than on
161
+ // loop iterations so that a dropped definition is what fails, not a skipped
162
+ // turn of the loop.
163
+ const rendered = new Set(lines.flatMap((line) => {
164
+ if (!line.startsWith(' ') || line.startsWith(' '))
165
+ return [];
166
+ const [head, ...rest] = line.slice(2).split(' = ');
167
+ return rest.length > 0 ? [head] : [];
168
+ }));
169
+ const unrendered = concepts.filter(({ id }) => !rendered.has(externalByNative.get(id)));
170
+ const missing = unrendered[0];
171
+ if (missing !== undefined) {
172
+ const source = sourceForConcept(projection.claims, missing.id) ??
173
+ adapterMappingLocation(mapping, 'adapter');
174
+ return {
175
+ ok: false,
176
+ diagnostics: [
177
+ {
178
+ severity: 'error',
179
+ code: 'YMLC112',
180
+ message: `Rendering coverage: ${concepts.length - unrendered.length} of ${concepts.length} projected concepts reached the LikeC4 model`,
181
+ subject: missing.id,
182
+ path: source.path,
183
+ pointer: source.pointer,
184
+ line: source.line,
185
+ column: source.column,
186
+ },
187
+ ],
188
+ };
189
+ }
158
190
  const relationships = projection.subjects
159
191
  .filter(({ type }) => type === 'relationship')
160
192
  .sort((left, right) => left.id.localeCompare(right.id));
File without changes
@@ -359,7 +359,6 @@ const localVisualStatus = async (descriptor) => {
359
359
  chat: false,
360
360
  choices: false,
361
361
  navigation: false,
362
- modelReplacement: false,
363
362
  transcript: false,
364
363
  },
365
364
  transcriptBytes,
@@ -8,7 +8,10 @@
8
8
  * contract: it can import these declarations and limits without pulling Ajv,
9
9
  * `node:path`, or the schema documents into its bundle.
10
10
  */
11
- export declare const VISUAL_PROTOCOL_VERSION: 'yarramate/visual-protocol/v1';
11
+ import type { CanvasGraph } from "../../graph-projection.js";
12
+ import type { YarramateApplyResult, YarramateOperation } from "../../operations.js";
13
+ import type { ProjectionDefinition, ProjectionQuery } from "../../projection.js";
14
+ export declare const VISUAL_PROTOCOL_VERSION: "yarramate/visual-protocol/v2";
12
15
  export declare const VISUAL_LIMITS: {
13
16
  readonly messageBytes: number;
14
17
  readonly modelBytes: number;
@@ -17,9 +20,9 @@ export declare const VISUAL_LIMITS: {
17
20
  readonly reconnectMs: number;
18
21
  readonly staleSessionMs: number;
19
22
  };
20
- export type VisualAuthority = 'canonical' | 'ad-hoc';
23
+ export type VisualAuthority = "canonical";
21
24
  export interface VisualDiagnostic {
22
- readonly severity: 'error';
25
+ readonly severity: "error";
23
26
  readonly code: string;
24
27
  readonly message: string;
25
28
  readonly path: string;
@@ -28,38 +31,32 @@ export interface VisualDiagnostic {
28
31
  readonly column: number;
29
32
  }
30
33
  export interface VisualDiagnosticResult {
31
- readonly format: 'yarramate/visual-diagnostic-result/v1';
34
+ readonly format: "yarramate/visual-diagnostic-result/v1";
32
35
  readonly diagnostics: readonly VisualDiagnostic[];
33
36
  }
34
37
  export interface VisualCapabilities {
35
38
  readonly chat: boolean;
36
39
  readonly choices: boolean;
37
40
  readonly navigation: boolean;
38
- readonly modelReplacement: boolean;
39
41
  readonly transcript: boolean;
40
42
  }
41
43
  export interface VisualModel {
42
- readonly format: 'yarramate/visual-model/v1';
44
+ readonly format: "yarramate/visual-model/v1";
43
45
  readonly authority: VisualAuthority;
44
46
  readonly initialView: string;
45
47
  readonly sourceDigests: Readonly<Record<string, string>>;
46
- readonly files: Readonly<Record<string, string>>;
47
- }
48
- export interface VisualCompilerCommand {
49
- readonly command: string;
50
- readonly args: readonly string[];
48
+ readonly graph: CanvasGraph;
51
49
  }
52
50
  export interface VisualSessionRequest {
53
- readonly format: 'yarramate/visual-session-request/v1';
54
- readonly authority: VisualModel['authority'];
51
+ readonly format: "yarramate/visual-session-request/v1";
52
+ readonly authority: VisualModel["authority"];
55
53
  readonly title: string;
56
54
  readonly description: string;
57
55
  readonly chatEnabled: boolean;
58
- readonly compiler: VisualCompilerCommand;
59
56
  readonly initialModel: VisualModel;
60
57
  }
61
58
  export interface VisualSessionStarted {
62
- readonly format: 'yarramate/visual-session-started/v1';
59
+ readonly format: "yarramate/visual-session-started/v1";
63
60
  readonly protocolVersion: typeof VISUAL_PROTOCOL_VERSION;
64
61
  readonly sessionId: string;
65
62
  readonly authority: VisualAuthority;
@@ -74,7 +71,7 @@ export interface VisualSessionStarted {
74
71
  readonly startedAt: string;
75
72
  }
76
73
  export interface VisualSessionDescriptor {
77
- readonly format: 'yarramate/visual-session-descriptor/v1';
74
+ readonly format: "yarramate/visual-session-descriptor/v1";
78
75
  readonly protocolVersion: typeof VISUAL_PROTOCOL_VERSION;
79
76
  readonly sessionId: string;
80
77
  readonly origin: string;
@@ -94,6 +91,44 @@ export interface VisualViewNavigatePayload {
94
91
  readonly viewId: string;
95
92
  readonly requiresAttention: boolean;
96
93
  }
94
+ export interface VisualViewSummary {
95
+ readonly id: string;
96
+ readonly title: string;
97
+ readonly description: string;
98
+ readonly query: ProjectionQuery;
99
+ readonly presentation: ProjectionDefinition["presentation"];
100
+ }
101
+ export interface VisualKindOption {
102
+ readonly id: string;
103
+ readonly label: string;
104
+ }
105
+ export interface VisualFilterQueryPayload {
106
+ readonly query: ProjectionQuery;
107
+ }
108
+ export interface VisualFilterResultPayload {
109
+ readonly query: ProjectionQuery;
110
+ readonly matchedIds: readonly string[];
111
+ }
112
+ export interface VisualViewSavePayload {
113
+ readonly id?: string;
114
+ readonly title: string;
115
+ readonly description: string;
116
+ readonly query: ProjectionQuery;
117
+ readonly presentation: ProjectionDefinition["presentation"];
118
+ }
119
+ export interface VisualLayoutPositions {
120
+ readonly [subjectId: string]: {
121
+ readonly x: number;
122
+ readonly y: number;
123
+ };
124
+ }
125
+ export interface VisualChangesetCommitPayload {
126
+ readonly operations: readonly YarramateOperation[];
127
+ }
128
+ export interface VisualLayoutSavePayload {
129
+ readonly projectionId: string;
130
+ readonly positions: VisualLayoutPositions;
131
+ }
97
132
  /**
98
133
  * Terminal event payload. Every reason is the runtime's to choose: only it
99
134
  * knows whether a session ended by request, by a failing child, by a browser
@@ -104,7 +139,7 @@ export interface VisualSessionEndPayload {
104
139
  }
105
140
  /** End as an untrusted browser may ask for it, and nothing more. */
106
141
  export interface VisualBrowserSessionEndPayload {
107
- readonly reason: 'user-ended';
142
+ readonly reason: "user-ended";
108
143
  }
109
144
  export interface VisualBrowserConnectedPayload {
110
145
  readonly connectionId: string;
@@ -125,24 +160,40 @@ export interface VisualBrowserDisconnectedPayload {
125
160
  * sequence and event identifier.
126
161
  */
127
162
  export type VisualBrowserInput = {
128
- readonly type: 'chat.message';
163
+ readonly type: "chat.message";
129
164
  readonly lastAcknowledgedSequence: number;
130
165
  readonly payload: VisualChatMessagePayload;
131
166
  } | {
132
- readonly type: 'choice.selected';
167
+ readonly type: "choice.selected";
133
168
  readonly lastAcknowledgedSequence: number;
134
169
  readonly payload: VisualChoiceSelectedPayload;
135
170
  } | {
136
- readonly type: 'view.navigate';
171
+ readonly type: "view.navigate";
137
172
  readonly lastAcknowledgedSequence: number;
138
173
  readonly payload: VisualViewNavigatePayload;
139
174
  } | {
140
- readonly type: 'session.end';
175
+ readonly type: "filter.query";
176
+ readonly lastAcknowledgedSequence: number;
177
+ readonly payload: VisualFilterQueryPayload;
178
+ } | {
179
+ readonly type: "view.save";
180
+ readonly lastAcknowledgedSequence: number;
181
+ readonly payload: VisualViewSavePayload;
182
+ } | {
183
+ readonly type: "changeset.commit";
184
+ readonly lastAcknowledgedSequence: number;
185
+ readonly payload: VisualChangesetCommitPayload;
186
+ } | {
187
+ readonly type: "layout.save";
188
+ readonly lastAcknowledgedSequence: number;
189
+ readonly payload: VisualLayoutSavePayload;
190
+ } | {
191
+ readonly type: "session.end";
141
192
  readonly lastAcknowledgedSequence: number;
142
193
  readonly payload: VisualBrowserSessionEndPayload;
143
194
  };
144
195
  interface VisualEventEnvelope<Type extends string, Payload> {
145
- readonly format: 'yarramate/visual-event/v1';
196
+ readonly format: "yarramate/visual-event/v1";
146
197
  readonly sessionId: string;
147
198
  readonly sequence: number;
148
199
  readonly eventId: string;
@@ -150,12 +201,25 @@ interface VisualEventEnvelope<Type extends string, Payload> {
150
201
  readonly timestamp: string;
151
202
  readonly payload: Payload;
152
203
  }
153
- export type VisualEvent = VisualEventEnvelope<'chat.message', VisualChatMessagePayload> | VisualEventEnvelope<'choice.selected', VisualChoiceSelectedPayload> | VisualEventEnvelope<'view.navigate', VisualViewNavigatePayload> | VisualEventEnvelope<'session.end', VisualSessionEndPayload> | VisualEventEnvelope<'browser.connected', VisualBrowserConnectedPayload> | VisualEventEnvelope<'browser.disconnected', VisualBrowserDisconnectedPayload>;
204
+ export type VisualEvent = VisualEventEnvelope<"chat.message", VisualChatMessagePayload> | VisualEventEnvelope<"choice.selected", VisualChoiceSelectedPayload> | VisualEventEnvelope<"view.navigate", VisualViewNavigatePayload> | VisualEventEnvelope<"session.end", VisualSessionEndPayload> | VisualEventEnvelope<"browser.connected", VisualBrowserConnectedPayload> | VisualEventEnvelope<"browser.disconnected", VisualBrowserDisconnectedPayload> | VisualEventEnvelope<"filter.query", VisualFilterQueryPayload> | VisualEventEnvelope<"view.save", VisualViewSavePayload> | VisualEventEnvelope<"changeset.commit", VisualChangesetCommitPayload> | VisualEventEnvelope<"layout.save", VisualLayoutSavePayload>;
205
+ /**
206
+ * The filter a chat turn resolved to. The agent states `query` and nothing
207
+ * else: the runtime evaluates it against the same graph a `filter.query`
208
+ * event is evaluated against and fills `matchedIds` in before the response
209
+ * is journaled or streamed (ADR 0090). `matchedIds` is optional so a
210
+ * resolved response survives a transcript round-trip - an agent that sends
211
+ * one is refused.
212
+ */
213
+ export interface VisualChatAppliedQuery {
214
+ readonly query: ProjectionQuery;
215
+ readonly matchedIds?: readonly string[];
216
+ }
154
217
  export interface VisualChatResponsePayload {
155
218
  readonly text: string;
219
+ readonly appliedQuery?: VisualChatAppliedQuery;
156
220
  }
157
221
  export interface VisualAgentStatusPayload {
158
- readonly state: 'thinking' | 'compiling' | 'waiting' | 'idle';
222
+ readonly state: "thinking" | "compiling" | "waiting" | "idle";
159
223
  readonly detail?: string;
160
224
  }
161
225
  export interface VisualChoiceOption {
@@ -168,9 +232,6 @@ export interface VisualChoicePresentPayload {
168
232
  readonly question: string;
169
233
  readonly options: readonly VisualChoiceOption[];
170
234
  }
171
- export interface VisualModelReplacePayload {
172
- readonly model: VisualModel;
173
- }
174
235
  export interface VisualHandoffSummary {
175
236
  readonly summary: string;
176
237
  readonly confirmedDecisions: readonly string[];
@@ -181,8 +242,30 @@ export interface VisualHandoffSummary {
181
242
  export interface VisualDiagnosticPayload {
182
243
  readonly diagnostics: readonly VisualDiagnostic[];
183
244
  }
245
+ export type VisualViewSaveResultPayload = {
246
+ readonly ok: true;
247
+ readonly id: string;
248
+ readonly path: string;
249
+ } | {
250
+ readonly ok: false;
251
+ readonly diagnostics: readonly VisualDiagnostic[];
252
+ };
253
+ export type VisualApplyResultPayload = {
254
+ readonly ok: true;
255
+ readonly result: YarramateApplyResult;
256
+ } | {
257
+ readonly ok: false;
258
+ readonly diagnostics: readonly VisualDiagnostic[];
259
+ };
260
+ export type VisualLayoutSaveResultPayload = {
261
+ readonly ok: true;
262
+ readonly path: string;
263
+ } | {
264
+ readonly ok: false;
265
+ readonly message: string;
266
+ };
184
267
  interface VisualResponseEnvelope<Type extends string, Payload> {
185
- readonly format: 'yarramate/visual-response/v1';
268
+ readonly format: "yarramate/visual-response/v1";
186
269
  readonly sessionId: string;
187
270
  readonly responseId: string;
188
271
  readonly eventId: string;
@@ -190,11 +273,11 @@ interface VisualResponseEnvelope<Type extends string, Payload> {
190
273
  readonly timestamp: string;
191
274
  readonly payload: Payload;
192
275
  }
193
- export type VisualResponse = VisualResponseEnvelope<'chat.response', VisualChatResponsePayload> | VisualResponseEnvelope<'agent.status', VisualAgentStatusPayload> | VisualResponseEnvelope<'choice.present', VisualChoicePresentPayload> | VisualResponseEnvelope<'model.replace', VisualModelReplacePayload> | VisualResponseEnvelope<'handoff.complete', VisualHandoffSummary> | VisualResponseEnvelope<'diagnostic', VisualDiagnosticPayload>;
194
- export type VisualHandoffDecision = 'completed' | 'cancelled' | 'failed';
195
- export type VisualTerminationReason = 'user-ended' | 'child-failed' | 'browser-timeout' | 'main-cancelled' | 'server-failed' | 'compiler-failed';
276
+ export type VisualResponse = VisualResponseEnvelope<"chat.response", VisualChatResponsePayload> | VisualResponseEnvelope<"agent.status", VisualAgentStatusPayload> | VisualResponseEnvelope<"choice.present", VisualChoicePresentPayload> | VisualResponseEnvelope<"handoff.complete", VisualHandoffSummary> | VisualResponseEnvelope<"diagnostic", VisualDiagnosticPayload>;
277
+ export type VisualHandoffDecision = "completed" | "cancelled" | "failed";
278
+ export type VisualTerminationReason = "user-ended" | "child-failed" | "browser-timeout" | "main-cancelled" | "server-failed" | "compiler-failed";
196
279
  export interface VisualHandoff extends VisualHandoffSummary {
197
- readonly format: 'yarramate/visual-handoff/v1';
280
+ readonly format: "yarramate/visual-handoff/v1";
198
281
  readonly sessionId: string;
199
282
  readonly authority: VisualAuthority;
200
283
  readonly decision: VisualHandoffDecision;
@@ -204,10 +287,10 @@ export interface VisualHandoff extends VisualHandoffSummary {
204
287
  readonly transcript?: readonly (VisualEvent | VisualResponse)[];
205
288
  readonly completedAt: string;
206
289
  }
207
- export type VisualLifecycle = 'starting' | 'running' | 'draining' | 'stopped';
208
- export type VisualFreezeReason = 'message-bytes' | 'model-bytes' | 'transcript-bytes' | 'pending-events' | 'browser-disconnected' | 'terminal-event';
290
+ export type VisualLifecycle = "starting" | "running" | "draining" | "stopped";
291
+ export type VisualFreezeReason = "message-bytes" | "model-bytes" | "transcript-bytes" | "pending-events" | "browser-disconnected" | "terminal-event" | "recompile-failed";
209
292
  export interface VisualStatus {
210
- readonly format: 'yarramate/visual-status/v1';
293
+ readonly format: "yarramate/visual-status/v1";
211
294
  readonly protocolVersion: typeof VISUAL_PROTOCOL_VERSION;
212
295
  readonly sessionId: string;
213
296
  readonly lifecycle: VisualLifecycle;
@@ -1,14 +1,4 @@
1
- /**
2
- * Every visual protocol declaration, and the limits they are measured against,
3
- * with no runtime dependency of any kind.
4
- *
5
- * The validators that police these documents live in `./protocol.js`, which
6
- * re-exports this module so a Node consumer still has one import for the whole
7
- * protocol. The split exists because the browser application ships the same
8
- * contract: it can import these declarations and limits without pulling Ajv,
9
- * `node:path`, or the schema documents into its bundle.
10
- */
11
- export const VISUAL_PROTOCOL_VERSION = 'yarramate/visual-protocol/v1';
1
+ export const VISUAL_PROTOCOL_VERSION = "yarramate/visual-protocol/v2";
12
2
  export const VISUAL_LIMITS = {
13
3
  messageBytes: 64 * 1024,
14
4
  modelBytes: 5 * 1024 * 1024,
@@ -1,10 +1,17 @@
1
1
  import { type ParseResult, type VisualBrowserInput, type VisualDiagnosticResult, type VisualEvent, type VisualHandoff, type VisualModel, type VisualResponse, type VisualSessionDescriptor, type VisualSessionRequest, type VisualSessionStarted, type VisualStatus } from './protocol-contract.js';
2
2
  export * from './protocol-contract.js';
3
- export declare const isSafeVisualModelPath: (candidate: string) => boolean;
4
3
  export declare const parseVisualModel: (input: unknown) => ParseResult<VisualModel>;
5
4
  export declare const parseVisualSessionRequest: (input: unknown) => ParseResult<VisualSessionRequest>;
6
5
  export declare const parseVisualSessionStarted: (input: unknown) => ParseResult<VisualSessionStarted>;
7
6
  export declare const parseVisualSessionDescriptor: (input: unknown) => ParseResult<VisualSessionDescriptor>;
7
+ /**
8
+ * The type an untrusted frame claims to be, when the protocol has that type.
9
+ *
10
+ * A refusal has to say what it refused, and the browser is holding a control
11
+ * open until it does. The claim is worth reporting before the document is
12
+ * known to be valid because the frame that named it is the one that failed.
13
+ */
14
+ export declare const visualBrowserInputType: (input: unknown) => VisualBrowserInput['type'] | undefined;
8
15
  export declare const parseVisualBrowserInput: (input: unknown) => ParseResult<VisualBrowserInput>;
9
16
  export declare const parseVisualEvent: (input: unknown) => ParseResult<VisualEvent>;
10
17
  export declare const parseVisualResponse: (input: unknown) => ParseResult<VisualResponse>;