sysprom 1.16.1 → 1.18.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 +147 -75
- package/dist/schema.json +2 -1
- package/dist/src/cli/commands/add.js +52 -36
- package/dist/src/cli/commands/graph.d.ts +15 -0
- package/dist/src/cli/commands/graph.js +51 -2
- package/dist/src/cli/commands/infer.js +44 -25
- package/dist/src/cli/commands/init.d.ts +1 -1
- package/dist/src/cli/commands/json2md.d.ts +30 -1
- package/dist/src/cli/commands/json2md.js +42 -1
- package/dist/src/cli/commands/md2json.d.ts +1 -1
- package/dist/src/cli/commands/query.js +35 -37
- package/dist/src/cli/commands/speckit.js +81 -77
- package/dist/src/cli/commands/stats.js +4 -4
- package/dist/src/cli/commands/sync.d.ts +1 -1
- package/dist/src/cli/commands/update.js +33 -20
- package/dist/src/cli/define-command.d.ts +1 -1
- package/dist/src/cli/define-command.js +176 -156
- package/dist/src/endpoint-types.js +13 -6
- package/dist/src/io.js +59 -8
- package/dist/src/json-to-md.d.ts +32 -2
- package/dist/src/json-to-md.js +145 -5
- package/dist/src/mcp/server.js +269 -112
- package/dist/src/md-to-json.js +7 -0
- package/dist/src/operations/add-node.d.ts +12 -9
- package/dist/src/operations/add-plan-task.d.ts +8 -6
- package/dist/src/operations/add-relationship.d.ts +11 -8
- package/dist/src/operations/check.d.ts +4 -3
- package/dist/src/operations/define-operation.d.ts +1 -1
- package/dist/src/operations/graph-decision.d.ts +329 -0
- package/dist/src/operations/graph-decision.js +96 -0
- package/dist/src/operations/graph-dependency.d.ts +329 -0
- package/dist/src/operations/graph-dependency.js +121 -0
- package/dist/src/operations/graph-refinement.d.ts +329 -0
- package/dist/src/operations/graph-refinement.js +97 -0
- package/dist/src/operations/graph-shared.d.ts +116 -0
- package/dist/src/operations/graph-shared.js +257 -0
- package/dist/src/operations/graph.d.ts +20 -4
- package/dist/src/operations/graph.js +129 -36
- package/dist/src/operations/index.d.ts +3 -0
- package/dist/src/operations/index.js +3 -0
- package/dist/src/operations/infer-completeness.d.ts +4 -3
- package/dist/src/operations/infer-derived.d.ts +4 -3
- package/dist/src/operations/infer-impact.d.ts +28 -21
- package/dist/src/operations/infer-lifecycle.d.ts +4 -3
- package/dist/src/operations/init-document.d.ts +4 -3
- package/dist/src/operations/json-to-markdown.d.ts +28 -3
- package/dist/src/operations/json-to-markdown.js +11 -1
- package/dist/src/operations/mark-task-done.d.ts +8 -6
- package/dist/src/operations/mark-task-undone.d.ts +8 -6
- package/dist/src/operations/markdown-to-json.d.ts +4 -3
- package/dist/src/operations/next-id.d.ts +4 -3
- package/dist/src/operations/node-history.d.ts +4 -3
- package/dist/src/operations/plan-add-task.d.ts +8 -6
- package/dist/src/operations/plan-gate.d.ts +4 -3
- package/dist/src/operations/plan-init.d.ts +4 -3
- package/dist/src/operations/plan-progress.d.ts +4 -3
- package/dist/src/operations/plan-status.d.ts +4 -3
- package/dist/src/operations/query-node.d.ts +24 -17
- package/dist/src/operations/query-nodes.d.ts +8 -6
- package/dist/src/operations/query-relationships.d.ts +7 -5
- package/dist/src/operations/remove-node.d.ts +12 -9
- package/dist/src/operations/remove-relationship.d.ts +10 -7
- package/dist/src/operations/rename.d.ts +8 -6
- package/dist/src/operations/search.d.ts +8 -6
- package/dist/src/operations/speckit-diff.d.ts +4 -3
- package/dist/src/operations/speckit-export.d.ts +4 -3
- package/dist/src/operations/speckit-import.d.ts +4 -3
- package/dist/src/operations/speckit-sync.d.ts +12 -9
- package/dist/src/operations/state-at.d.ts +4 -3
- package/dist/src/operations/stats.d.ts +4 -3
- package/dist/src/operations/sync.d.ts +12 -9
- package/dist/src/operations/task-list.d.ts +4 -3
- package/dist/src/operations/timeline.d.ts +4 -3
- package/dist/src/operations/trace-from-node.d.ts +12 -9
- package/dist/src/operations/update-metadata.d.ts +8 -6
- package/dist/src/operations/update-node.d.ts +11 -8
- package/dist/src/operations/update-plan-task.d.ts +8 -6
- package/dist/src/operations/validate.d.ts +4 -3
- package/dist/src/schema.d.ts +15 -10
- package/dist/src/schema.js +3 -11
- package/dist/src/utils/define-schema.d.ts +17 -0
- package/dist/src/utils/define-schema.js +21 -0
- package/package.json +98 -93
- package/schema.json +2 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
/** Generate a refinement chain diagram showing how nodes elaborate through abstraction layers. */
|
|
3
|
+
export declare const graphRefinementOp: import("./define-operation.js").DefinedOperation<z.ZodObject<{
|
|
4
|
+
doc: z.ZodObject<{
|
|
5
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
6
|
+
metadata: z.ZodOptional<z.ZodObject<{
|
|
7
|
+
title: z.ZodOptional<z.ZodString>;
|
|
8
|
+
doc_type: z.ZodOptional<z.ZodString>;
|
|
9
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
10
|
+
status: z.ZodOptional<z.ZodString>;
|
|
11
|
+
version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
|
|
12
|
+
}, z.core.$loose> & {
|
|
13
|
+
is(value: unknown): value is {
|
|
14
|
+
[x: string]: unknown;
|
|
15
|
+
title?: string | undefined;
|
|
16
|
+
doc_type?: string | undefined;
|
|
17
|
+
scope?: string | undefined;
|
|
18
|
+
status?: string | undefined;
|
|
19
|
+
version?: string | number | undefined;
|
|
20
|
+
};
|
|
21
|
+
}>;
|
|
22
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
type: z.ZodEnum<{
|
|
25
|
+
intent: "intent";
|
|
26
|
+
concept: "concept";
|
|
27
|
+
capability: "capability";
|
|
28
|
+
element: "element";
|
|
29
|
+
realisation: "realisation";
|
|
30
|
+
invariant: "invariant";
|
|
31
|
+
principle: "principle";
|
|
32
|
+
policy: "policy";
|
|
33
|
+
protocol: "protocol";
|
|
34
|
+
stage: "stage";
|
|
35
|
+
role: "role";
|
|
36
|
+
gate: "gate";
|
|
37
|
+
mode: "mode";
|
|
38
|
+
artefact: "artefact";
|
|
39
|
+
artefact_flow: "artefact_flow";
|
|
40
|
+
decision: "decision";
|
|
41
|
+
change: "change";
|
|
42
|
+
view: "view";
|
|
43
|
+
milestone: "milestone";
|
|
44
|
+
version: "version";
|
|
45
|
+
}> & {
|
|
46
|
+
is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
|
|
47
|
+
};
|
|
48
|
+
name: z.ZodString;
|
|
49
|
+
description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
50
|
+
is(value: unknown): value is string | string[];
|
|
51
|
+
}>;
|
|
52
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
deprecated: "deprecated";
|
|
54
|
+
proposed: "proposed";
|
|
55
|
+
accepted: "accepted";
|
|
56
|
+
active: "active";
|
|
57
|
+
implemented: "implemented";
|
|
58
|
+
adopted: "adopted";
|
|
59
|
+
defined: "defined";
|
|
60
|
+
introduced: "introduced";
|
|
61
|
+
in_progress: "in_progress";
|
|
62
|
+
complete: "complete";
|
|
63
|
+
consolidated: "consolidated";
|
|
64
|
+
experimental: "experimental";
|
|
65
|
+
retired: "retired";
|
|
66
|
+
superseded: "superseded";
|
|
67
|
+
abandoned: "abandoned";
|
|
68
|
+
deferred: "deferred";
|
|
69
|
+
}> & {
|
|
70
|
+
is(value: unknown): value is "deprecated" | "proposed" | "accepted" | "active" | "implemented" | "adopted" | "defined" | "introduced" | "in_progress" | "complete" | "consolidated" | "experimental" | "retired" | "superseded" | "abandoned" | "deferred";
|
|
71
|
+
}>;
|
|
72
|
+
lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
|
|
73
|
+
context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
74
|
+
is(value: unknown): value is string | string[];
|
|
75
|
+
}>;
|
|
76
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
77
|
+
id: z.ZodString;
|
|
78
|
+
description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
79
|
+
is(value: unknown): value is string | string[];
|
|
80
|
+
};
|
|
81
|
+
}, z.core.$loose> & {
|
|
82
|
+
is(value: unknown): value is {
|
|
83
|
+
[x: string]: unknown;
|
|
84
|
+
id: string;
|
|
85
|
+
description: string | string[];
|
|
86
|
+
};
|
|
87
|
+
}>>;
|
|
88
|
+
selected: z.ZodOptional<z.ZodString>;
|
|
89
|
+
rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
90
|
+
is(value: unknown): value is string | string[];
|
|
91
|
+
}>;
|
|
92
|
+
scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
93
|
+
operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
94
|
+
type: z.ZodEnum<{
|
|
95
|
+
link: "link";
|
|
96
|
+
add: "add";
|
|
97
|
+
update: "update";
|
|
98
|
+
remove: "remove";
|
|
99
|
+
}>;
|
|
100
|
+
target: z.ZodOptional<z.ZodString>;
|
|
101
|
+
description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
102
|
+
is(value: unknown): value is string | string[];
|
|
103
|
+
}>;
|
|
104
|
+
}, z.core.$loose> & {
|
|
105
|
+
is(value: unknown): value is {
|
|
106
|
+
[x: string]: unknown;
|
|
107
|
+
type: "link" | "add" | "update" | "remove";
|
|
108
|
+
target?: string | undefined;
|
|
109
|
+
description?: string | string[] | undefined;
|
|
110
|
+
};
|
|
111
|
+
}>>;
|
|
112
|
+
plan: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
113
|
+
description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
114
|
+
is(value: unknown): value is string | string[];
|
|
115
|
+
};
|
|
116
|
+
done: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
|
117
|
+
}, z.core.$loose> & {
|
|
118
|
+
is(value: unknown): value is {
|
|
119
|
+
[x: string]: unknown;
|
|
120
|
+
description: string | string[];
|
|
121
|
+
done?: boolean | undefined;
|
|
122
|
+
};
|
|
123
|
+
}>>;
|
|
124
|
+
propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
|
|
125
|
+
includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
126
|
+
input: z.ZodOptional<z.ZodString>;
|
|
127
|
+
output: z.ZodOptional<z.ZodString>;
|
|
128
|
+
external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
129
|
+
role: z.ZodEnum<{
|
|
130
|
+
output: "output";
|
|
131
|
+
input: "input";
|
|
132
|
+
context: "context";
|
|
133
|
+
evidence: "evidence";
|
|
134
|
+
source: "source";
|
|
135
|
+
standard: "standard";
|
|
136
|
+
prior_art: "prior_art";
|
|
137
|
+
}> & {
|
|
138
|
+
is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
139
|
+
};
|
|
140
|
+
identifier: z.ZodString;
|
|
141
|
+
description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
142
|
+
is(value: unknown): value is string | string[];
|
|
143
|
+
}>;
|
|
144
|
+
node_id: z.ZodOptional<z.ZodString>;
|
|
145
|
+
internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
146
|
+
is(value: unknown): value is string | string[];
|
|
147
|
+
}>;
|
|
148
|
+
}, z.core.$strip> & {
|
|
149
|
+
is(value: unknown): value is {
|
|
150
|
+
role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
151
|
+
identifier: string;
|
|
152
|
+
description?: string | string[] | undefined;
|
|
153
|
+
node_id?: string | undefined;
|
|
154
|
+
internalised?: string | string[] | undefined;
|
|
155
|
+
};
|
|
156
|
+
}>>;
|
|
157
|
+
readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
|
|
158
|
+
}, z.core.$loose>>;
|
|
159
|
+
relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
160
|
+
from: z.ZodString;
|
|
161
|
+
to: z.ZodString;
|
|
162
|
+
type: z.ZodEnum<{
|
|
163
|
+
refines: "refines";
|
|
164
|
+
realises: "realises";
|
|
165
|
+
implements: "implements";
|
|
166
|
+
depends_on: "depends_on";
|
|
167
|
+
constrained_by: "constrained_by";
|
|
168
|
+
affects: "affects";
|
|
169
|
+
supersedes: "supersedes";
|
|
170
|
+
must_preserve: "must_preserve";
|
|
171
|
+
performs: "performs";
|
|
172
|
+
part_of: "part_of";
|
|
173
|
+
precedes: "precedes";
|
|
174
|
+
must_follow: "must_follow";
|
|
175
|
+
blocks: "blocks";
|
|
176
|
+
routes_to: "routes_to";
|
|
177
|
+
governed_by: "governed_by";
|
|
178
|
+
modifies: "modifies";
|
|
179
|
+
triggered_by: "triggered_by";
|
|
180
|
+
applies_to: "applies_to";
|
|
181
|
+
produces: "produces";
|
|
182
|
+
consumes: "consumes";
|
|
183
|
+
transforms_into: "transforms_into";
|
|
184
|
+
selects: "selects";
|
|
185
|
+
requires: "requires";
|
|
186
|
+
disables: "disables";
|
|
187
|
+
influence: "influence";
|
|
188
|
+
justifies: "justifies";
|
|
189
|
+
}> & {
|
|
190
|
+
is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables" | "influence" | "justifies";
|
|
191
|
+
};
|
|
192
|
+
description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
193
|
+
is(value: unknown): value is string | string[];
|
|
194
|
+
}>;
|
|
195
|
+
polarity: z.ZodOptional<z.ZodEnum<{
|
|
196
|
+
positive: "positive";
|
|
197
|
+
negative: "negative";
|
|
198
|
+
neutral: "neutral";
|
|
199
|
+
uncertain: "uncertain";
|
|
200
|
+
}> & {
|
|
201
|
+
is(value: unknown): value is "positive" | "negative" | "neutral" | "uncertain";
|
|
202
|
+
}>;
|
|
203
|
+
strength: z.ZodOptional<z.ZodNumber>;
|
|
204
|
+
}, z.core.$loose> & {
|
|
205
|
+
is(value: unknown): value is {
|
|
206
|
+
[x: string]: unknown;
|
|
207
|
+
from: string;
|
|
208
|
+
to: string;
|
|
209
|
+
type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables" | "influence" | "justifies";
|
|
210
|
+
description?: string | string[] | undefined;
|
|
211
|
+
polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
|
|
212
|
+
strength?: number | undefined;
|
|
213
|
+
};
|
|
214
|
+
}>>;
|
|
215
|
+
external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
216
|
+
role: z.ZodEnum<{
|
|
217
|
+
output: "output";
|
|
218
|
+
input: "input";
|
|
219
|
+
context: "context";
|
|
220
|
+
evidence: "evidence";
|
|
221
|
+
source: "source";
|
|
222
|
+
standard: "standard";
|
|
223
|
+
prior_art: "prior_art";
|
|
224
|
+
}> & {
|
|
225
|
+
is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
226
|
+
};
|
|
227
|
+
identifier: z.ZodString;
|
|
228
|
+
description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
229
|
+
is(value: unknown): value is string | string[];
|
|
230
|
+
}>;
|
|
231
|
+
node_id: z.ZodOptional<z.ZodString>;
|
|
232
|
+
internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
|
|
233
|
+
is(value: unknown): value is string | string[];
|
|
234
|
+
}>;
|
|
235
|
+
}, z.core.$strip> & {
|
|
236
|
+
is(value: unknown): value is {
|
|
237
|
+
role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
238
|
+
identifier: string;
|
|
239
|
+
description?: string | string[] | undefined;
|
|
240
|
+
node_id?: string | undefined;
|
|
241
|
+
internalised?: string | string[] | undefined;
|
|
242
|
+
};
|
|
243
|
+
}>>;
|
|
244
|
+
}, z.core.$strip> & {
|
|
245
|
+
is(value: unknown): value is {
|
|
246
|
+
nodes: {
|
|
247
|
+
[x: string]: unknown;
|
|
248
|
+
id: string;
|
|
249
|
+
type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "artefact_flow" | "decision" | "change" | "view" | "milestone" | "version";
|
|
250
|
+
name: string;
|
|
251
|
+
description?: string | string[] | undefined;
|
|
252
|
+
status?: "deprecated" | "proposed" | "accepted" | "active" | "implemented" | "adopted" | "defined" | "introduced" | "in_progress" | "complete" | "consolidated" | "experimental" | "retired" | "superseded" | "abandoned" | "deferred" | undefined;
|
|
253
|
+
lifecycle?: Record<string, string | boolean> | undefined;
|
|
254
|
+
context?: string | string[] | undefined;
|
|
255
|
+
options?: {
|
|
256
|
+
[x: string]: unknown;
|
|
257
|
+
id: string;
|
|
258
|
+
description: string | string[];
|
|
259
|
+
}[] | undefined;
|
|
260
|
+
selected?: string | undefined;
|
|
261
|
+
rationale?: string | string[] | undefined;
|
|
262
|
+
scope?: string[] | undefined;
|
|
263
|
+
operations?: {
|
|
264
|
+
[x: string]: unknown;
|
|
265
|
+
type: "link" | "add" | "update" | "remove";
|
|
266
|
+
target?: string | undefined;
|
|
267
|
+
description?: string | string[] | undefined;
|
|
268
|
+
}[] | undefined;
|
|
269
|
+
plan?: {
|
|
270
|
+
[x: string]: unknown;
|
|
271
|
+
description: string | string[];
|
|
272
|
+
done?: boolean | undefined;
|
|
273
|
+
}[] | undefined;
|
|
274
|
+
propagation?: Record<string, boolean> | undefined;
|
|
275
|
+
includes?: string[] | undefined;
|
|
276
|
+
input?: string | undefined;
|
|
277
|
+
output?: string | undefined;
|
|
278
|
+
external_references?: {
|
|
279
|
+
role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
280
|
+
identifier: string;
|
|
281
|
+
description?: string | string[] | undefined;
|
|
282
|
+
node_id?: string | undefined;
|
|
283
|
+
internalised?: string | string[] | undefined;
|
|
284
|
+
}[] | undefined;
|
|
285
|
+
subsystem?: /*elided*/ any | undefined;
|
|
286
|
+
}[];
|
|
287
|
+
$schema?: string | undefined;
|
|
288
|
+
metadata?: {
|
|
289
|
+
[x: string]: unknown;
|
|
290
|
+
title?: string | undefined;
|
|
291
|
+
doc_type?: string | undefined;
|
|
292
|
+
scope?: string | undefined;
|
|
293
|
+
status?: string | undefined;
|
|
294
|
+
version?: string | number | undefined;
|
|
295
|
+
} | undefined;
|
|
296
|
+
relationships?: {
|
|
297
|
+
[x: string]: unknown;
|
|
298
|
+
from: string;
|
|
299
|
+
to: string;
|
|
300
|
+
type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "performs" | "part_of" | "precedes" | "must_follow" | "blocks" | "routes_to" | "governed_by" | "modifies" | "triggered_by" | "applies_to" | "produces" | "consumes" | "transforms_into" | "selects" | "requires" | "disables" | "influence" | "justifies";
|
|
301
|
+
description?: string | string[] | undefined;
|
|
302
|
+
polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
|
|
303
|
+
strength?: number | undefined;
|
|
304
|
+
}[] | undefined;
|
|
305
|
+
external_references?: {
|
|
306
|
+
role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
|
|
307
|
+
identifier: string;
|
|
308
|
+
description?: string | string[] | undefined;
|
|
309
|
+
node_id?: string | undefined;
|
|
310
|
+
internalised?: string | string[] | undefined;
|
|
311
|
+
}[] | undefined;
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
format: z.ZodDefault<z.ZodEnum<{
|
|
315
|
+
dot: "dot";
|
|
316
|
+
mermaid: "mermaid";
|
|
317
|
+
}>>;
|
|
318
|
+
seedIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
319
|
+
layout: z.ZodDefault<z.ZodEnum<{
|
|
320
|
+
TD: "TD";
|
|
321
|
+
BT: "BT";
|
|
322
|
+
RL: "RL";
|
|
323
|
+
LR: "LR";
|
|
324
|
+
}>>;
|
|
325
|
+
labelMode: z.ZodDefault<z.ZodEnum<{
|
|
326
|
+
friendly: "friendly";
|
|
327
|
+
compact: "compact";
|
|
328
|
+
}>>;
|
|
329
|
+
}, z.core.$strip>, z.ZodString>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { defineOperation } from "./define-operation.js";
|
|
3
|
+
import { SysProMDocument } from "../schema.js";
|
|
4
|
+
import { sanitiseMermaidId, mermaidShapeForNode, renderMermaidNode, renderMermaidClassDefs, mermaidClassForNode, dotNodeAttrsWithMode, renderRelationshipLabel, } from "./graph-shared.js";
|
|
5
|
+
const REFINEMENT_REL_TYPES = new Set(["refines", "realises", "implements"]);
|
|
6
|
+
function collectRefinementChain(doc, seedIds) {
|
|
7
|
+
const rels = (doc.relationships ?? []).filter((r) => REFINEMENT_REL_TYPES.has(r.type));
|
|
8
|
+
if (seedIds && seedIds.length > 0) {
|
|
9
|
+
const reachable = new Set(seedIds);
|
|
10
|
+
let changed = true;
|
|
11
|
+
while (changed) {
|
|
12
|
+
changed = false;
|
|
13
|
+
for (const r of rels) {
|
|
14
|
+
if (reachable.has(r.from) && !reachable.has(r.to)) {
|
|
15
|
+
reachable.add(r.to);
|
|
16
|
+
changed = true;
|
|
17
|
+
}
|
|
18
|
+
if (reachable.has(r.to) && !reachable.has(r.from)) {
|
|
19
|
+
reachable.add(r.from);
|
|
20
|
+
changed = true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const filteredRels = rels.filter((r) => reachable.has(r.from) && reachable.has(r.to));
|
|
25
|
+
const nodes = doc.nodes.filter((n) => reachable.has(n.id));
|
|
26
|
+
return { nodes, rels: filteredRels };
|
|
27
|
+
}
|
|
28
|
+
const nodeIds = new Set(rels.flatMap((r) => [r.from, r.to]));
|
|
29
|
+
const nodes = doc.nodes.filter((n) => nodeIds.has(n.id));
|
|
30
|
+
return { nodes, rels };
|
|
31
|
+
}
|
|
32
|
+
function generateRefinementMermaid(nodes, rels, labelMode) {
|
|
33
|
+
const lines = [];
|
|
34
|
+
lines.push("graph TD");
|
|
35
|
+
for (const def of renderMermaidClassDefs()) {
|
|
36
|
+
lines.push(` ${def}`);
|
|
37
|
+
}
|
|
38
|
+
lines.push("");
|
|
39
|
+
for (const node of nodes) {
|
|
40
|
+
const shape = mermaidShapeForNode(node);
|
|
41
|
+
const cls = mermaidClassForNode(node);
|
|
42
|
+
lines.push(` ${renderMermaidNode(node.id, node.name, shape, labelMode)}:::${cls}`);
|
|
43
|
+
}
|
|
44
|
+
lines.push("");
|
|
45
|
+
for (const rel of rels) {
|
|
46
|
+
const fromId = sanitiseMermaidId(rel.from);
|
|
47
|
+
const toId = sanitiseMermaidId(rel.to);
|
|
48
|
+
const label = renderRelationshipLabel(rel);
|
|
49
|
+
lines.push(` ${fromId} -->|${label}| ${toId}`);
|
|
50
|
+
}
|
|
51
|
+
return lines.join("\n");
|
|
52
|
+
}
|
|
53
|
+
function generateRefinementDot(nodes, rels, layout, labelMode) {
|
|
54
|
+
const lines = [];
|
|
55
|
+
lines.push("digraph RefinementChain {");
|
|
56
|
+
const rankdir = layout === "TD"
|
|
57
|
+
? "TB"
|
|
58
|
+
: layout === "BT"
|
|
59
|
+
? "BT"
|
|
60
|
+
: layout === "RL"
|
|
61
|
+
? "RL"
|
|
62
|
+
: "LR";
|
|
63
|
+
lines.push(` rankdir=${rankdir};`);
|
|
64
|
+
lines.push(" node [style=filled];");
|
|
65
|
+
for (const node of nodes) {
|
|
66
|
+
lines.push(` "${node.id}" ${dotNodeAttrsWithMode(node, labelMode)};`);
|
|
67
|
+
}
|
|
68
|
+
for (const rel of rels) {
|
|
69
|
+
const label = renderRelationshipLabel(rel);
|
|
70
|
+
lines.push(` "${rel.from}" -> "${rel.to}" [label="${label}"];`);
|
|
71
|
+
}
|
|
72
|
+
lines.push("}");
|
|
73
|
+
return lines.join("\n");
|
|
74
|
+
}
|
|
75
|
+
/** Generate a refinement chain diagram showing how nodes elaborate through abstraction layers. */
|
|
76
|
+
export const graphRefinementOp = defineOperation({
|
|
77
|
+
name: "graphRefinement",
|
|
78
|
+
description: "Generate a refinement chain diagram showing intent → concept → capability → element → realisation relationships.",
|
|
79
|
+
input: z.object({
|
|
80
|
+
doc: SysProMDocument,
|
|
81
|
+
format: z.enum(["mermaid", "dot"]).default("mermaid"),
|
|
82
|
+
seedIds: z.array(z.string()).optional(),
|
|
83
|
+
layout: z.enum(["LR", "TD", "RL", "BT"]).default("TD"),
|
|
84
|
+
labelMode: z.enum(["friendly", "compact"]).default("friendly"),
|
|
85
|
+
}),
|
|
86
|
+
output: z.string(),
|
|
87
|
+
fn({ doc, format, seedIds, layout, labelMode }) {
|
|
88
|
+
const { nodes, rels } = collectRefinementChain(doc, seedIds);
|
|
89
|
+
if (format === "dot") {
|
|
90
|
+
return generateRefinementDot(nodes, rels, layout, labelMode);
|
|
91
|
+
}
|
|
92
|
+
const mermaid = generateRefinementMermaid(nodes, rels, labelMode);
|
|
93
|
+
const mermaidLines = mermaid.split("\n");
|
|
94
|
+
mermaidLines[0] = `graph ${layout}`;
|
|
95
|
+
return mermaidLines.join("\n");
|
|
96
|
+
},
|
|
97
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type Node, type Relationship } from "../schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Sanitise an identifier for use in Mermaid diagrams by replacing
|
|
4
|
+
* non-alphanumeric/underscore characters with an underscore.
|
|
5
|
+
* @param id - Identifier to sanitise
|
|
6
|
+
* @example
|
|
7
|
+
* // sanitiseMermaidId('I1:Name') // 'I1_Name'
|
|
8
|
+
*/
|
|
9
|
+
export declare function sanitiseMermaidId(id: string): string;
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
export interface NodeCategory {
|
|
14
|
+
name: string;
|
|
15
|
+
label: string;
|
|
16
|
+
types: string[];
|
|
17
|
+
colour: string;
|
|
18
|
+
textColour: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const NODE_CATEGORIES: NodeCategory[];
|
|
21
|
+
/**
|
|
22
|
+
* Return the category for a given node. Falls back to the last category
|
|
23
|
+
* if the node type is unknown.
|
|
24
|
+
* @param node - Node to obtain category for
|
|
25
|
+
* @example
|
|
26
|
+
* // categoryForNode(node).name
|
|
27
|
+
*/
|
|
28
|
+
export declare function categoryForNode(node: Node): NodeCategory;
|
|
29
|
+
/**
|
|
30
|
+
* Return the category for a node type.
|
|
31
|
+
* @param type - Node type string
|
|
32
|
+
* @example
|
|
33
|
+
* // categoryForType('intent').name // 'intent'
|
|
34
|
+
*/
|
|
35
|
+
export declare function categoryForType(type: string): NodeCategory;
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
export type MermaidShape = "rounded" | "rectangle" | "rhombus" | "parallelogram";
|
|
40
|
+
/**
|
|
41
|
+
* Map a node to its Mermaid shape.
|
|
42
|
+
* @param node - Node to determine shape for
|
|
43
|
+
* @example
|
|
44
|
+
*/
|
|
45
|
+
export declare function mermaidShapeForNode(node: Node): MermaidShape;
|
|
46
|
+
/**
|
|
47
|
+
* Render a Mermaid node definition for a node id/name/shape.
|
|
48
|
+
* @param id - Node id
|
|
49
|
+
* @param name - Node name
|
|
50
|
+
* @param shape - Shape to render
|
|
51
|
+
* @param mode - Label mode, friendly shows id and name, compact shows id only
|
|
52
|
+
* @example
|
|
53
|
+
*/
|
|
54
|
+
export declare function renderMermaidNode(id: string, name: string, shape: MermaidShape, mode?: "friendly" | "compact"): string;
|
|
55
|
+
/**
|
|
56
|
+
* Render a human-friendly relationship label including polarity and strength
|
|
57
|
+
* @param rel
|
|
58
|
+
* @example
|
|
59
|
+
*/
|
|
60
|
+
export declare function renderRelationshipLabel(rel: Relationship): string;
|
|
61
|
+
/**
|
|
62
|
+
* @example
|
|
63
|
+
*/
|
|
64
|
+
export declare function renderMermaidClassDefs(): string[];
|
|
65
|
+
/**
|
|
66
|
+
* @param node
|
|
67
|
+
* @example
|
|
68
|
+
*/
|
|
69
|
+
export declare function mermaidClassForNode(node: Node): string;
|
|
70
|
+
/**
|
|
71
|
+
* @param node
|
|
72
|
+
* @example
|
|
73
|
+
*/
|
|
74
|
+
export declare function dotNodeAttrs(node: Node): string;
|
|
75
|
+
/**
|
|
76
|
+
* Format a node label according to a mode. "friendly" shows id and name,
|
|
77
|
+
* "compact" shows only the id.
|
|
78
|
+
* @param node
|
|
79
|
+
* @param mode
|
|
80
|
+
* @example
|
|
81
|
+
*/
|
|
82
|
+
export declare function formatNodeLabel(node: Node, mode: "friendly" | "compact"): string;
|
|
83
|
+
/**
|
|
84
|
+
* @param node
|
|
85
|
+
* @param mode
|
|
86
|
+
* @example
|
|
87
|
+
*/
|
|
88
|
+
export declare function dotNodeAttrsWithMode(node: Node, mode?: "friendly" | "compact"): string;
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
*/
|
|
92
|
+
export interface GraphFilterOptions {
|
|
93
|
+
nodeTypes?: string[];
|
|
94
|
+
nodeIds?: string[];
|
|
95
|
+
relTypes?: string[];
|
|
96
|
+
connectedOnly?: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @param nodes
|
|
100
|
+
* @param opts
|
|
101
|
+
* @example
|
|
102
|
+
*/
|
|
103
|
+
export declare function filterNodes(nodes: Node[], opts: GraphFilterOptions): Node[];
|
|
104
|
+
/**
|
|
105
|
+
* @param rels
|
|
106
|
+
* @param opts
|
|
107
|
+
* @param allowedNodeIds
|
|
108
|
+
* @example
|
|
109
|
+
*/
|
|
110
|
+
export declare function filterRelationships(rels: Relationship[], opts: GraphFilterOptions, allowedNodeIds?: Set<string>): Relationship[];
|
|
111
|
+
/**
|
|
112
|
+
* @param nodes
|
|
113
|
+
* @param rels
|
|
114
|
+
* @example
|
|
115
|
+
*/
|
|
116
|
+
export declare function applyConnectedOnly(nodes: Node[], rels: Relationship[]): Node[];
|