yarramate 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/catalogues/core-enrichment.yaml +52 -1
- package/dist/adapters/graphify-cli.js +0 -0
- package/dist/adapters/likec4-cli.js +0 -0
- package/dist/adapters/mcp-cli.js +0 -0
- package/dist/adapters/visual/client.js +0 -1
- package/dist/adapters/visual/protocol-contract.d.ts +118 -35
- package/dist/adapters/visual/protocol-contract.js +1 -11
- package/dist/adapters/visual/protocol.d.ts +8 -1
- package/dist/adapters/visual/protocol.js +86 -46
- package/dist/adapters/visual/request.d.ts +37 -0
- package/dist/adapters/visual/request.js +131 -0
- package/dist/adapters/visual/session-server.d.ts +12 -14
- package/dist/adapters/visual/session-server.js +641 -283
- package/dist/adapters/visual/session-store.d.ts +28 -28
- package/dist/adapters/visual/session-store.js +32 -93
- package/dist/adapters/visual/wire.d.ts +36 -10
- package/dist/adapters/visual-cli.d.ts +3 -0
- package/dist/adapters/visual-cli.js +66 -1
- package/dist/apply-command.d.ts +10 -0
- package/dist/apply-command.js +399 -247
- package/dist/cli.js +0 -0
- package/dist/compiler.d.ts +13 -0
- package/dist/compiler.js +36 -2
- package/dist/graph-projection.d.ts +62 -0
- package/dist/graph-projection.js +222 -0
- package/dist/interrogate-command.d.ts +2 -0
- package/dist/interrogate-command.js +22 -0
- package/dist/kind-label.d.ts +8 -0
- package/dist/kind-label.js +8 -0
- package/dist/operations.d.ts +139 -0
- package/dist/operations.js +11 -0
- package/dist/projection.d.ts +2 -0
- package/dist/projection.js +8 -2
- package/dist/reconciliation.js +8 -7
- package/dist/source-document.d.ts +10 -0
- package/dist/source-document.js +21 -1
- package/dist/visual-app/assets/index-6oSR9RGM.js +354 -0
- package/dist/visual-app/assets/index-dwA9AOr5.css +1 -0
- package/dist/visual-app/index.html +2 -2
- package/docs/CONSUMING-YARRAMATE.md +25 -19
- package/package.json +6 -1
- package/schema/yarramate-adapter-mapping.schema.json +1 -1
- package/schema/yarramate-apply-result.schema.json +8 -2
- package/schema/yarramate-document.schema.json +1 -1
- package/schema/yarramate-operations.schema.json +203 -1
- package/schema/yarramate-projection.schema.json +12 -3
- package/schema/yarramate-question-catalogue.schema.json +15 -2
- package/schema/yarramate-visual-event.schema.json +143 -0
- package/schema/yarramate-visual-graph.schema.json +272 -0
- package/schema/yarramate-visual-layout.schema.json +41 -0
- package/schema/yarramate-visual-model.schema.json +6 -44
- package/schema/yarramate-visual-response.schema.json +170 -19
- package/schema/yarramate-visual-session-descriptor.schema.json +1 -1
- package/schema/yarramate-visual-session-request.schema.json +0 -70
- package/schema/yarramate-visual-session-started.schema.json +2 -9
- package/schema/yarramate-visual-status.schema.json +3 -2
- package/skills/yarramate-architecture/SKILL.md +20 -13
- package/skills/yarramate-architecture/references/journey-checklists.md +4 -2
- package/skills/yarramate-architecture/references/native-authoring.md +30 -0
- package/skills/yarramate-architecture/references/visual-conversations.md +149 -150
- package/dist/adapters/visual/likec4-compiler.d.ts +0 -55
- package/dist/adapters/visual/likec4-compiler.js +0 -460
- package/dist/visual-app/assets/index-CGvC8e3R.css +0 -1
- package/dist/visual-app/assets/index-CXuW1tOj.js +0 -209
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { loadProjection } from '../../projection.js';
|
|
5
|
+
import { loadWorkspaceManifest } from '../../workspace.js';
|
|
6
|
+
import { parseVisualSessionRequest } from './protocol.js';
|
|
7
|
+
import { buildVisualModelGraph } from './session-store.js';
|
|
8
|
+
/**
|
|
9
|
+
* The one manifest a session can serve. `startVisualServer` resolves exactly
|
|
10
|
+
* this path relative to its own working directory, so the builder reads the
|
|
11
|
+
* same file rather than accepting a path that could name a different workspace
|
|
12
|
+
* than the session about to render it.
|
|
13
|
+
*/
|
|
14
|
+
const MANIFEST_PATH = '.yarramate/workspace.yaml';
|
|
15
|
+
const requestDiagnostic = (code, message, path = MANIFEST_PATH) => ({
|
|
16
|
+
severity: 'error',
|
|
17
|
+
code,
|
|
18
|
+
message,
|
|
19
|
+
path,
|
|
20
|
+
pointer: '/',
|
|
21
|
+
line: 1,
|
|
22
|
+
column: 1,
|
|
23
|
+
});
|
|
24
|
+
const digestOf = (source) => createHash('sha256').update(source).digest('hex');
|
|
25
|
+
/**
|
|
26
|
+
* Builds the `yarramate/visual-session-request/v1` document that `start`
|
|
27
|
+
* consumes, from the workspace on disk.
|
|
28
|
+
*
|
|
29
|
+
* The request carries a whole compiled model — 247 nodes and 338 edges for this
|
|
30
|
+
* repository's own architecture — so it is a machine's transcription of the
|
|
31
|
+
* workspace, never something an agent can honestly hand-author. Every input the
|
|
32
|
+
* document needs is already derivable: the graph from the native compiler, the
|
|
33
|
+
* digests from the same sources that compiled, and the view list from the
|
|
34
|
+
* workspace's declared projections.
|
|
35
|
+
*
|
|
36
|
+
* The result is validated through `parseVisualSessionRequest` before it is
|
|
37
|
+
* returned, so the byte ceiling, digest confinement, and authority agreement
|
|
38
|
+
* are the protocol's own rules rather than a second set restated here. A
|
|
39
|
+
* builder that cannot produce a valid document refuses instead of handing a
|
|
40
|
+
* session something it would reject at start.
|
|
41
|
+
*/
|
|
42
|
+
export const buildVisualSessionRequest = (options) => {
|
|
43
|
+
const manifestPath = resolve(options.cwd, MANIFEST_PATH);
|
|
44
|
+
let manifestSource;
|
|
45
|
+
try {
|
|
46
|
+
manifestSource = readFileSync(manifestPath, 'utf8');
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
diagnostics: [
|
|
52
|
+
requestDiagnostic('YMVS410', `Workspace manifest ${manifestPath} cannot be read`),
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const loaded = loadWorkspaceManifest({ path: manifestPath, source: manifestSource }, options.cwd);
|
|
57
|
+
if (!loaded.ok) {
|
|
58
|
+
return { ok: false, diagnostics: loaded.diagnostics };
|
|
59
|
+
}
|
|
60
|
+
const workspace = loaded.workspace;
|
|
61
|
+
// Same order the session's own recompile uses, so the request's graph and
|
|
62
|
+
// every graph the session rebuilds after a commit come from one input list.
|
|
63
|
+
const sourcePaths = [...workspace.profiles, ...workspace.documents];
|
|
64
|
+
const sources = [];
|
|
65
|
+
for (const path of sourcePaths) {
|
|
66
|
+
try {
|
|
67
|
+
sources.push({ path, source: readFileSync(resolve(options.cwd, path), 'utf8') });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
diagnostics: [
|
|
73
|
+
requestDiagnostic('YMVS411', `Workspace source ${path} cannot be read`, path),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const built = buildVisualModelGraph(sources);
|
|
79
|
+
if (!built.ok)
|
|
80
|
+
return { ok: false, diagnostics: built.diagnostics };
|
|
81
|
+
// A projection that does not load is skipped by the session too: the request
|
|
82
|
+
// names a view the browser will actually be able to open.
|
|
83
|
+
const viewIds = workspace.projections.flatMap((projectionPath) => {
|
|
84
|
+
try {
|
|
85
|
+
const projection = loadProjection({
|
|
86
|
+
path: projectionPath,
|
|
87
|
+
source: readFileSync(resolve(options.cwd, projectionPath), 'utf8'),
|
|
88
|
+
});
|
|
89
|
+
return projection.ok ? [projection.projection.id] : [];
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const initialView = options.initialView ?? viewIds[0];
|
|
96
|
+
if (initialView === undefined) {
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
diagnostics: [
|
|
100
|
+
requestDiagnostic('YMVS412', `Workspace ${workspace.id} declares no loadable projection, so a session has no view to open`),
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (!viewIds.includes(initialView)) {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
diagnostics: [
|
|
108
|
+
requestDiagnostic('YMVS413', `Workspace ${workspace.id} declares no projection "${initialView}": ${viewIds.length === 0 ? 'it declares none' : viewIds.join(', ')}`),
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const request = {
|
|
113
|
+
format: 'yarramate/visual-session-request/v1',
|
|
114
|
+
authority: 'canonical',
|
|
115
|
+
title: options.title ?? workspace.id,
|
|
116
|
+
description: options.description ??
|
|
117
|
+
`Native rendering of workspace ${workspace.id} from ${MANIFEST_PATH}`,
|
|
118
|
+
chatEnabled: options.chatEnabled ?? false,
|
|
119
|
+
initialModel: {
|
|
120
|
+
format: 'yarramate/visual-model/v1',
|
|
121
|
+
authority: 'canonical',
|
|
122
|
+
initialView,
|
|
123
|
+
sourceDigests: Object.fromEntries(sources.map(({ path, source }) => [path, digestOf(source)])),
|
|
124
|
+
graph: built.graph,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const parsed = parseVisualSessionRequest(request);
|
|
128
|
+
if (!parsed.ok)
|
|
129
|
+
return { ok: false, diagnostics: parsed.diagnostics };
|
|
130
|
+
return { ok: true, request: parsed.value };
|
|
131
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type VisualDiagnostic, type VisualEvent, type VisualFreezeReason, type VisualHandoff, type VisualLifecycle, type VisualSessionRequest, type VisualSessionStarted, type VisualStatus, type VisualTerminationReason } from
|
|
2
|
-
import { type TerminalEventDependencies, type VisualSessionPaths } from
|
|
3
|
-
import type { VisualRenderedModel, VisualServerFrame, VisualSessionSnapshot, VisualTranscriptRecord } from
|
|
1
|
+
import { type VisualDiagnostic, type VisualEvent, type VisualFreezeReason, type VisualHandoff, type VisualLifecycle, type VisualSessionRequest, type VisualSessionStarted, type VisualStatus, type VisualTerminationReason } from "./protocol.js";
|
|
2
|
+
import { type TerminalEventDependencies, type VisualSessionPaths } from "./session-store.js";
|
|
3
|
+
import type { VisualRenderedModel, VisualServerFrame, VisualSessionSnapshot, VisualTranscriptRecord } from "./wire.js";
|
|
4
4
|
export type { VisualRenderedModel, VisualServerFrame, VisualSessionSnapshot, VisualTranscriptRecord, };
|
|
5
5
|
/**
|
|
6
6
|
* Document name reported by diagnostics the server itself raises — a refused
|
|
@@ -14,9 +14,9 @@ export declare const VISUAL_SERVER_DOCUMENT = "visual-session-server";
|
|
|
14
14
|
* and the page can be neither framed nor used as a base for relative fetches.
|
|
15
15
|
*/
|
|
16
16
|
export declare const VISUAL_BROWSER_HEADERS: {
|
|
17
|
-
readonly
|
|
18
|
-
readonly
|
|
19
|
-
readonly
|
|
17
|
+
readonly "Referrer-Policy": "no-referrer";
|
|
18
|
+
readonly "X-Content-Type-Options": "nosniff";
|
|
19
|
+
readonly "Cache-Control": "no-store";
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* This session's content policy. Every source stays `'self'`; the one addition
|
|
@@ -52,7 +52,6 @@ export type VisualResponseAcceptance = {
|
|
|
52
52
|
readonly accepted: true;
|
|
53
53
|
readonly duplicate: boolean;
|
|
54
54
|
readonly lastSequence: number;
|
|
55
|
-
readonly model?: VisualRenderedModel;
|
|
56
55
|
readonly diagnostics: readonly VisualDiagnostic[];
|
|
57
56
|
} | {
|
|
58
57
|
readonly accepted: false;
|
|
@@ -67,6 +66,8 @@ export interface VisualServerOptions {
|
|
|
67
66
|
readonly request: VisualSessionRequest;
|
|
68
67
|
/** Directory that holds one directory per live session. */
|
|
69
68
|
readonly baseDir: string;
|
|
69
|
+
/** Working directory for resolving .yarramate/workspace.yaml and projections. */
|
|
70
|
+
readonly cwd: string;
|
|
70
71
|
/** Root of the self-contained browser application. */
|
|
71
72
|
readonly assetRoot?: string;
|
|
72
73
|
readonly now?: () => Date;
|
|
@@ -98,8 +99,6 @@ export interface VisualServerHandle {
|
|
|
98
99
|
export interface ActiveVisualSession {
|
|
99
100
|
readonly paths: VisualSessionPaths;
|
|
100
101
|
lifecycle: VisualLifecycle;
|
|
101
|
-
/** Cancels whatever the trusted compiler is doing for this session. */
|
|
102
|
-
readonly compilerAbort: AbortController;
|
|
103
102
|
/** Records why the browser stopped being able to speak. */
|
|
104
103
|
readonly freeze: (reason: VisualFreezeReason) => void;
|
|
105
104
|
/** Settles work already admitted, so recovery reads a quiet journal. */
|
|
@@ -115,11 +114,10 @@ export interface ActiveVisualSession {
|
|
|
115
114
|
* that failed, a browser that never came back, a cancelling main agent, or a
|
|
116
115
|
* runtime shutting itself down.
|
|
117
116
|
*
|
|
118
|
-
* The order is the invariant. Input freezes before anything is read;
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* removes the session directory.
|
|
117
|
+
* The order is the invariant. Input freezes before anything is read; work
|
|
118
|
+
* already admitted is still allowed to finish; exactly one terminal event is
|
|
119
|
+
* journaled; and the handoff is recovered without deleting anything, so
|
|
120
|
+
* `stop` — and only `stop` — is what removes the session directory.
|
|
123
121
|
*/
|
|
124
122
|
export declare const terminateVisualSession: (session: ActiveVisualSession, reason: VisualTerminationReason) => Promise<VisualHandoff>;
|
|
125
123
|
/**
|