graphlin 0.1.3 → 0.2.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +12 -3
- package/docs/decision-service.md +393 -0
- package/docs/extension-authoring.md +553 -0
- package/docs/model-api.md +293 -0
- package/docs/usage.md +465 -0
- package/docs/visualizer-views.md +199 -0
- package/node_modules/@vscode/tree-sitter-wasm/LICENSE +21 -0
- package/node_modules/@vscode/tree-sitter-wasm/README.md +36 -0
- package/node_modules/@vscode/tree-sitter-wasm/SECURITY.md +41 -0
- package/node_modules/@vscode/tree-sitter-wasm/cgmanifest.json +16 -0
- package/node_modules/@vscode/tree-sitter-wasm/package.json +42 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-bash.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-c-sharp.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-cpp.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-css.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-go.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-ini.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-java.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-javascript.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-php.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-powershell.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-python.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-regex.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-ruby.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-rust.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-tsx.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter-typescript.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.js +4075 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/tree-sitter.wasm +0 -0
- package/node_modules/@vscode/tree-sitter-wasm/wasm/web-tree-sitter.d.ts +1027 -0
- package/package.json +74 -9
- package/plugin.json +4 -2
- package/runtime/core/evidence.mjs +43 -9
- package/runtime/core/graph.mjs +11 -6
- package/runtime/core/privacy.mjs +1 -0
- package/runtime/daemon/auth.mjs +7 -3
- package/runtime/daemon/diagnostics.mjs +1 -1
- package/runtime/daemon/extension-api.mjs +203 -0
- package/runtime/daemon/lineage.mjs +70 -0
- package/runtime/daemon/manager.mjs +9 -6
- package/runtime/daemon/model-api.mjs +728 -0
- package/runtime/daemon/model-persistence.mjs +220 -0
- package/runtime/daemon/server.mjs +70 -12
- package/runtime/daemon/settings.mjs +11 -3
- package/runtime/decisions/broker.mjs +349 -0
- package/runtime/decisions/contracts.mjs +179 -0
- package/runtime/decisions/evaluation.mjs +305 -0
- package/runtime/decisions/faults.mjs +32 -0
- package/runtime/decisions/index.mjs +818 -0
- package/runtime/decisions/profiles.mjs +93 -0
- package/runtime/decisions/questions.mjs +268 -0
- package/runtime/discovery/index.mjs +2 -0
- package/runtime/discovery/inventory.mjs +160 -0
- package/runtime/discovery/parser.mjs +40 -0
- package/runtime/discovery/structure.mjs +232 -0
- package/runtime/extensions/contracts.mjs +59 -0
- package/runtime/extensions/frame.mjs +64 -0
- package/runtime/extensions/index.mjs +9 -0
- package/runtime/extensions/manifest.mjs +95 -0
- package/runtime/extensions/packages.mjs +222 -0
- package/runtime/extensions/profiles.mjs +36 -0
- package/runtime/extensions/projection.mjs +130 -0
- package/runtime/extensions/registry.mjs +285 -0
- package/runtime/extensions/scene.mjs +105 -0
- package/runtime/extensions/sdk.d.ts +205 -0
- package/runtime/extensions/sdk.mjs +88 -0
- package/runtime/jev/index.mjs +13 -777
- package/runtime/jev/provider.mjs +101 -0
- package/runtime/jev/questions.mjs +16 -258
- package/runtime/jev/wire.mjs +17 -25
- package/runtime/model/changes.mjs +42 -0
- package/runtime/model/history.mjs +124 -0
- package/runtime/model/index.mjs +2 -0
- package/runtime/model/project-model.mjs +889 -0
- package/runtime/model/records.mjs +239 -0
- package/runtime/pipeline.mjs +127 -48
- package/runtime/platform.mjs +254 -0
- package/runtime/visualizers/blocks.mjs +5 -0
- package/runtime/visualizers/c4.mjs +52 -0
- package/runtime/visualizers/changes.mjs +24 -0
- package/runtime/visualizers/code.mjs +5 -0
- package/runtime/visualizers/index.mjs +23 -0
- package/runtime/visualizers/structure.mjs +120 -0
- package/runtime/visualizers/timeline.mjs +66 -0
- package/runtime/web/app.js +225 -63
- package/runtime/web/extension-frame.js +128 -0
- package/runtime/web/index.html +36 -1
- package/runtime/web/model-client.js +162 -0
- package/runtime/web/platform.js +337 -0
- package/runtime/web/scene.js +111 -0
- package/runtime/web/style.css +49 -0
- package/schemas/graph.schema.json +4 -1
- package/scripts/arguments.mjs +5 -1
- package/scripts/build-packages.mjs +6 -2
- package/scripts/control.mjs +1 -1
- package/scripts/daemon.mjs +2 -1
- package/scripts/extensions.mjs +44 -0
- package/scripts/graphlin.mjs +23 -3
- package/scripts/onboarding.mjs +10 -3
- package/scripts/validate-packages.mjs +54 -8
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// This entry has no Node imports. Bundle it with the extension's one classic
|
|
2
|
+
// browser entry, or use the graphlin:connect event directly without a build tool.
|
|
3
|
+
export { API_VERSION, MODEL_SCHEMA, SCENE_VERSION, EXTENSION_LIMITS } from './contracts.mjs';
|
|
4
|
+
export { validateScene, SCENE_KINDS, SCENE_SHAPES, EDGE_KINDS } from './scene.mjs';
|
|
5
|
+
export { validateDecisionProfile } from './profiles.mjs';
|
|
6
|
+
import { check, exact, id, integer, jsonBytes, EXTENSION_LIMITS } from './contracts.mjs';
|
|
7
|
+
import { validateScene } from './scene.mjs';
|
|
8
|
+
|
|
9
|
+
const CONTEXT = ['instanceId', 'projectId', 'revision', 'viewEpoch', 'requestId'];
|
|
10
|
+
export function validateMessage(message, { model, context } = {}) {
|
|
11
|
+
const payloadFields = {
|
|
12
|
+
'graphlin:project': ['model', 'settings', 'selection'], 'graphlin:scene': ['scene'],
|
|
13
|
+
'graphlin:dispose': [], 'graphlin:error': ['code'], 'graphlin:status': ['status', 'itemCount'],
|
|
14
|
+
'graphlin:select': ['selection'],
|
|
15
|
+
};
|
|
16
|
+
check(message && Object.hasOwn(payloadFields, message.type) &&
|
|
17
|
+
exact(message, ['type', 'apiVersion', ...CONTEXT], payloadFields[message.type]) &&
|
|
18
|
+
message.apiVersion === 1 && ['instanceId', 'projectId', 'requestId'].every(key => id(message[key])) &&
|
|
19
|
+
integer(message.revision) && integer(message.viewEpoch), 'invalid_extension_message');
|
|
20
|
+
jsonBytes(message, EXTENSION_LIMITS.projectionBytes, 'extension_message_limit');
|
|
21
|
+
if (context) check(['apiVersion', ...CONTEXT].every(key => message[key] === context[key]),
|
|
22
|
+
'extension_message_context_mismatch');
|
|
23
|
+
if (model) check(model.schemaVersion === 2 && model.projectId === message.projectId &&
|
|
24
|
+
model.revision === message.revision, 'extension_model_context_mismatch');
|
|
25
|
+
if (message.type === 'graphlin:status') {
|
|
26
|
+
check(['ready', 'busy', 'empty', 'error'].includes(message.status) &&
|
|
27
|
+
integer(message.itemCount, EXTENSION_LIMITS.entities), 'invalid_extension_status');
|
|
28
|
+
}
|
|
29
|
+
if (message.type === 'graphlin:error') {
|
|
30
|
+
check(['extension_projection_failed', 'extension_unavailable', 'extension_cancelled'].includes(message.code),
|
|
31
|
+
'invalid_extension_error');
|
|
32
|
+
}
|
|
33
|
+
if (message.type === 'graphlin:select') {
|
|
34
|
+
check(exact(message.selection, [], ['entityId', 'relationId', 'activityId']) &&
|
|
35
|
+
Object.keys(message.selection).length === 1 && Object.values(message.selection).every(id), 'invalid_extension_selection');
|
|
36
|
+
check(model, 'selection_projection_required');
|
|
37
|
+
const [field, target] = Object.entries(message.selection)[0];
|
|
38
|
+
const collection = { entityId: 'entities', relationId: 'relations', activityId: 'activity' }[field];
|
|
39
|
+
check(Array.isArray(model[collection]) && model[collection].some(value => value.id === target),
|
|
40
|
+
'unknown_extension_selection');
|
|
41
|
+
}
|
|
42
|
+
return message;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Minimal asynchronous lifecycle. The host also enforces deadlines, rate and
|
|
46
|
+
* size limits, context matching, current grants, and disposal on navigation.
|
|
47
|
+
*/
|
|
48
|
+
export function connectExtension({ project, mount, dispose } = {}) {
|
|
49
|
+
check(project === undefined || typeof project === 'function', 'invalid_extension_projector');
|
|
50
|
+
check(mount === undefined || typeof mount === 'function', 'invalid_extension_mount');
|
|
51
|
+
let port, stopped = false, epoch = -1, request = 0;
|
|
52
|
+
const stop = () => {
|
|
53
|
+
if (stopped) return;
|
|
54
|
+
stopped = true; request++;
|
|
55
|
+
port?.close();
|
|
56
|
+
window.removeEventListener('graphlin:connect', connected);
|
|
57
|
+
dispose?.();
|
|
58
|
+
};
|
|
59
|
+
function connected(event) {
|
|
60
|
+
if (port || stopped) return;
|
|
61
|
+
port = event.detail.port;
|
|
62
|
+
mount?.({ root: document.getElementById('graphlin-extension'), assets: event.detail.assets });
|
|
63
|
+
port.onmessage = async event => {
|
|
64
|
+
let message;
|
|
65
|
+
try { message = validateMessage(event.data); } catch { return; }
|
|
66
|
+
if (message.type === 'graphlin:dispose') { stop(); return; }
|
|
67
|
+
if (message.type !== 'graphlin:project' || message.viewEpoch < epoch || stopped) return;
|
|
68
|
+
epoch = message.viewEpoch;
|
|
69
|
+
const current = ++request;
|
|
70
|
+
const context = Object.fromEntries(CONTEXT.map(key => [key, message[key]]));
|
|
71
|
+
try {
|
|
72
|
+
check(message.model?.schemaVersion === 2 && message.model.projectId === message.projectId &&
|
|
73
|
+
message.model.revision === message.revision, 'extension_model_context_mismatch');
|
|
74
|
+
const output = await project?.(message.model, message.settings ?? {}, message.selection ?? null);
|
|
75
|
+
if (current !== request || stopped || !output) return;
|
|
76
|
+
const scene = validateScene(output, { model: message.model });
|
|
77
|
+
port.postMessage({ type: 'graphlin:scene', apiVersion: 1, ...context, scene });
|
|
78
|
+
} catch {
|
|
79
|
+
if (current === request && !stopped) port.postMessage({
|
|
80
|
+
type: 'graphlin:error', apiVersion: 1, ...context, code: 'extension_projection_failed',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
port.start();
|
|
85
|
+
}
|
|
86
|
+
window.addEventListener('graphlin:connect', connected);
|
|
87
|
+
return stop;
|
|
88
|
+
}
|