sysprom 1.20.0 → 1.21.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/dist/schema.json +4 -44
- package/dist/src/cli/commands/add.js +6 -2
- package/dist/src/cli/commands/query.js +5 -3
- package/dist/src/cli/commands/speckit.js +2 -2
- package/dist/src/cli/commands/update.js +6 -4
- package/dist/src/endpoint-types.d.ts +4 -0
- package/dist/src/endpoint-types.js +22 -121
- package/dist/src/json-to-md.js +2 -16
- package/dist/src/lifecycle-state.d.ts +9 -0
- package/dist/src/lifecycle-state.js +22 -0
- package/dist/src/mcp/server.js +3 -6
- package/dist/src/md-to-json.js +1 -19
- package/dist/src/operations/add-node.d.ts +21 -135
- package/dist/src/operations/add-plan-task.d.ts +14 -90
- package/dist/src/operations/add-relationship.d.ts +16 -105
- package/dist/src/operations/check.d.ts +7 -45
- package/dist/src/operations/graph-decision.d.ts +7 -45
- package/dist/src/operations/graph-decision.js +0 -1
- package/dist/src/operations/graph-dependency.d.ts +7 -45
- package/dist/src/operations/graph-dependency.js +3 -23
- package/dist/src/operations/graph-refinement.d.ts +7 -45
- package/dist/src/operations/graph-shared.js +1 -3
- package/dist/src/operations/graph.d.ts +7 -45
- package/dist/src/operations/infer-completeness.d.ts +10 -54
- package/dist/src/operations/infer-derived.d.ts +7 -45
- package/dist/src/operations/infer-derived.js +28 -4
- package/dist/src/operations/infer-impact.d.ts +49 -315
- package/dist/src/operations/infer-impact.js +22 -3
- package/dist/src/operations/infer-lifecycle.d.ts +8 -106
- package/dist/src/operations/infer-lifecycle.js +4 -10
- package/dist/src/operations/init-document.d.ts +7 -45
- package/dist/src/operations/json-to-markdown.d.ts +7 -45
- package/dist/src/operations/mark-task-done.d.ts +14 -90
- package/dist/src/operations/mark-task-undone.d.ts +14 -90
- package/dist/src/operations/markdown-to-json.d.ts +7 -45
- package/dist/src/operations/next-id.d.ts +8 -48
- package/dist/src/operations/node-history.d.ts +7 -45
- package/dist/src/operations/plan-add-task.d.ts +14 -90
- package/dist/src/operations/plan-gate.d.ts +7 -45
- package/dist/src/operations/plan-init.d.ts +7 -45
- package/dist/src/operations/plan-progress.d.ts +7 -45
- package/dist/src/operations/plan-status.d.ts +7 -45
- package/dist/src/operations/query-node.d.ts +29 -195
- package/dist/src/operations/query-nodes.d.ts +15 -91
- package/dist/src/operations/query-nodes.js +6 -4
- package/dist/src/operations/query-relationships.d.ts +9 -60
- package/dist/src/operations/remove-node.d.ts +21 -135
- package/dist/src/operations/remove-node.js +11 -1
- package/dist/src/operations/remove-relationship.d.ts +15 -104
- package/dist/src/operations/rename.d.ts +14 -90
- package/dist/src/operations/search.d.ts +14 -90
- package/dist/src/operations/speckit-diff.d.ts +7 -45
- package/dist/src/operations/speckit-export.d.ts +7 -45
- package/dist/src/operations/speckit-import.d.ts +7 -45
- package/dist/src/operations/speckit-sync.d.ts +22 -136
- package/dist/src/operations/speckit-sync.js +3 -3
- package/dist/src/operations/state-at.d.ts +7 -45
- package/dist/src/operations/stats.d.ts +7 -45
- package/dist/src/operations/sync.d.ts +21 -135
- package/dist/src/operations/task-list.d.ts +7 -45
- package/dist/src/operations/timeline.d.ts +7 -45
- package/dist/src/operations/trace-from-node.d.ts +21 -135
- package/dist/src/operations/update-metadata.d.ts +14 -90
- package/dist/src/operations/update-node.d.ts +20 -155
- package/dist/src/operations/update-plan-task.d.ts +14 -90
- package/dist/src/operations/validate.d.ts +7 -45
- package/dist/src/operations/validate.js +8 -6
- package/dist/src/schema.d.ts +22 -164
- package/dist/src/schema.js +4 -27
- package/dist/src/speckit/generate.js +10 -7
- package/dist/src/speckit/parse.js +6 -3
- package/dist/src/speckit/plan.js +1 -1
- package/package.json +12 -1
- package/schema.json +4 -44
package/dist/schema.json
CHANGED
|
@@ -210,10 +210,6 @@
|
|
|
210
210
|
},
|
|
211
211
|
"type": "array"
|
|
212
212
|
},
|
|
213
|
-
"input": {
|
|
214
|
-
"description": "ID of the input artefact. Applicable to artefact_flow nodes.",
|
|
215
|
-
"type": "string"
|
|
216
|
-
},
|
|
217
213
|
"lifecycle": {
|
|
218
214
|
"additionalProperties": {
|
|
219
215
|
"anyOf": [
|
|
@@ -306,10 +302,6 @@
|
|
|
306
302
|
},
|
|
307
303
|
"type": "array"
|
|
308
304
|
},
|
|
309
|
-
"output": {
|
|
310
|
-
"description": "ID of the output artefact. Applicable to artefact_flow nodes.",
|
|
311
|
-
"type": "string"
|
|
312
|
-
},
|
|
313
305
|
"plan": {
|
|
314
306
|
"description": "Execution plan as a sequence of tasks. Applicable to change nodes.",
|
|
315
307
|
"items": {
|
|
@@ -377,25 +369,8 @@
|
|
|
377
369
|
"type": "string"
|
|
378
370
|
},
|
|
379
371
|
"status": {
|
|
380
|
-
"
|
|
381
|
-
|
|
382
|
-
"accepted",
|
|
383
|
-
"active",
|
|
384
|
-
"implemented",
|
|
385
|
-
"adopted",
|
|
386
|
-
"defined",
|
|
387
|
-
"introduced",
|
|
388
|
-
"in_progress",
|
|
389
|
-
"complete",
|
|
390
|
-
"consolidated",
|
|
391
|
-
"experimental",
|
|
392
|
-
"deprecated",
|
|
393
|
-
"retired",
|
|
394
|
-
"superseded",
|
|
395
|
-
"abandoned",
|
|
396
|
-
"deferred"
|
|
397
|
-
],
|
|
398
|
-
"type": "string"
|
|
372
|
+
"description": "Deprecated field. Node-level status is not supported; use lifecycle states instead.",
|
|
373
|
+
"not": {}
|
|
399
374
|
},
|
|
400
375
|
"subsystem": {
|
|
401
376
|
"$ref": "#"
|
|
@@ -416,12 +391,10 @@
|
|
|
416
391
|
"gate",
|
|
417
392
|
"mode",
|
|
418
393
|
"artefact",
|
|
419
|
-
"artefact_flow",
|
|
420
394
|
"decision",
|
|
421
395
|
"change",
|
|
422
396
|
"view",
|
|
423
|
-
"milestone"
|
|
424
|
-
"version"
|
|
397
|
+
"milestone"
|
|
425
398
|
],
|
|
426
399
|
"type": "string"
|
|
427
400
|
}
|
|
@@ -488,25 +461,12 @@
|
|
|
488
461
|
"affects",
|
|
489
462
|
"supersedes",
|
|
490
463
|
"must_preserve",
|
|
491
|
-
"performs",
|
|
492
464
|
"part_of",
|
|
493
465
|
"precedes",
|
|
494
466
|
"must_follow",
|
|
495
|
-
"blocks",
|
|
496
|
-
"routes_to",
|
|
497
|
-
"orchestrates",
|
|
498
467
|
"governed_by",
|
|
499
468
|
"modifies",
|
|
500
|
-
"
|
|
501
|
-
"applies_to",
|
|
502
|
-
"produces",
|
|
503
|
-
"consumes",
|
|
504
|
-
"transforms_into",
|
|
505
|
-
"selects",
|
|
506
|
-
"requires",
|
|
507
|
-
"disables",
|
|
508
|
-
"influence",
|
|
509
|
-
"justifies"
|
|
469
|
+
"produces"
|
|
510
470
|
],
|
|
511
471
|
"type": "string"
|
|
512
472
|
}
|
|
@@ -50,8 +50,12 @@ const optsSchema = mutationOpts.extend({
|
|
|
50
50
|
function populateNodeFromOpts(node, description, status, context, rationale, scope, selected, options) {
|
|
51
51
|
if (description)
|
|
52
52
|
node.description = description;
|
|
53
|
-
if (status)
|
|
54
|
-
node.
|
|
53
|
+
if (status) {
|
|
54
|
+
node.lifecycle = {
|
|
55
|
+
...(node.lifecycle ?? {}),
|
|
56
|
+
[status]: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
55
59
|
if (context)
|
|
56
60
|
node.context = context;
|
|
57
61
|
if (rationale)
|
|
@@ -4,6 +4,7 @@ import { textToString } from "../../text.js";
|
|
|
4
4
|
import { readOpts, loadDoc } from "../shared.js";
|
|
5
5
|
import { queryNodesOp, queryNodeOp, queryRelationshipsOp, traceFromNodeOp, timelineOp, nodeHistoryOp, stateAtOp, } from "../../operations/index.js";
|
|
6
6
|
import { NodeType, NodeStatus } from "../../schema.js";
|
|
7
|
+
import { primaryLifecycleState } from "../../lifecycle-state.js";
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
8
9
|
// Presentation helpers
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
@@ -16,8 +17,9 @@ function printNodeCompact(r) {
|
|
|
16
17
|
function printNodeVerbose(r) {
|
|
17
18
|
console.log(`${pc.cyan(r.id)} — ${pc.bold(r.name)}`);
|
|
18
19
|
console.log(` ${pc.dim("Type")}: ${r.type}`);
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const state = primaryLifecycleState(r);
|
|
21
|
+
if (state)
|
|
22
|
+
console.log(` ${pc.dim("State")}: ${pc.yellow(state)}`);
|
|
21
23
|
if (r.description)
|
|
22
24
|
console.log(` ${pc.dim("Description")}: ${textToString(r.description)}`);
|
|
23
25
|
if (r.context)
|
|
@@ -65,7 +67,7 @@ function printTraceTree(tn, depth) {
|
|
|
65
67
|
// ---------------------------------------------------------------------------
|
|
66
68
|
const nodesOpts = readOpts.extend({
|
|
67
69
|
type: NodeType.optional().describe("filter by node type"),
|
|
68
|
-
status: NodeStatus.optional().describe("filter by
|
|
70
|
+
status: NodeStatus.optional().describe("filter by lifecycle state"),
|
|
69
71
|
});
|
|
70
72
|
const nodeArgs = z.object({
|
|
71
73
|
id: z.string().describe("node ID to retrieve"),
|
|
@@ -218,7 +218,7 @@ const syncSubcommand = {
|
|
|
218
218
|
const specKitDoc = parseSpecKitFeature(specKitDir, idPrefix, constitutionPath);
|
|
219
219
|
// Compare documents
|
|
220
220
|
const diff = compareDocuments(syspromDoc, specKitDoc);
|
|
221
|
-
// Merge: Spec-Kit wins for content (description,
|
|
221
|
+
// Merge: Spec-Kit wins for content (description, lifecycle), SysProM wins for structure
|
|
222
222
|
const mergedNodes = new Map(syspromDoc.nodes.map((n) => [n.id, n]));
|
|
223
223
|
const specKitNodes = new Map(specKitDoc.nodes.map((n) => [n.id, n]));
|
|
224
224
|
for (const [id, specKitNode] of specKitNodes) {
|
|
@@ -232,7 +232,7 @@ const syncSubcommand = {
|
|
|
232
232
|
const merged = {
|
|
233
233
|
...syspromNode,
|
|
234
234
|
description: specKitNode.description ?? syspromNode.description,
|
|
235
|
-
|
|
235
|
+
lifecycle: specKitNode.lifecycle ?? syspromNode.lifecycle,
|
|
236
236
|
context: specKitNode.context ?? syspromNode.context,
|
|
237
237
|
options: specKitNode.options ?? syspromNode.options,
|
|
238
238
|
selected: specKitNode.selected ?? syspromNode.selected,
|
|
@@ -52,7 +52,7 @@ const updateNodeArgs = z.object({
|
|
|
52
52
|
});
|
|
53
53
|
const updateNodeOpts = mutationOpts.extend({
|
|
54
54
|
description: z.string().optional().describe("update node description"),
|
|
55
|
-
status: NodeStatus.optional().describe("
|
|
55
|
+
status: NodeStatus.optional().describe("set lifecycle state to true"),
|
|
56
56
|
context: z.string().optional().describe("update node context"),
|
|
57
57
|
rationale: z.string().optional().describe("update node rationale"),
|
|
58
58
|
lifecycle: z
|
|
@@ -97,13 +97,15 @@ const nodeSubcommand = {
|
|
|
97
97
|
const fields = {};
|
|
98
98
|
if (opts.description !== undefined)
|
|
99
99
|
fields.description = opts.description;
|
|
100
|
-
if (opts.status !== undefined)
|
|
101
|
-
fields.status = opts.status;
|
|
102
100
|
if (opts.context !== undefined)
|
|
103
101
|
fields.context = opts.context;
|
|
104
102
|
if (opts.rationale !== undefined)
|
|
105
103
|
fields.rationale = opts.rationale;
|
|
106
|
-
const
|
|
104
|
+
const lifecycleArgs = [...(opts.lifecycle ?? [])];
|
|
105
|
+
if (opts.status !== undefined) {
|
|
106
|
+
lifecycleArgs.push(`${opts.status}=true`);
|
|
107
|
+
}
|
|
108
|
+
const lifecycleFields = parseLifecycleFields(node.lifecycle, lifecycleArgs);
|
|
107
109
|
if (lifecycleFields) {
|
|
108
110
|
fields.lifecycle = lifecycleFields;
|
|
109
111
|
}
|
|
@@ -22,3 +22,7 @@ export declare const RELATIONSHIP_ENDPOINT_TYPES: Record<RelationshipType, {
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export declare function isValidEndpointPair(relType: RelationshipType, fromType: NodeType, toType: NodeType): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* True when a relationship is a read-model view dependency.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isViewReadModelDependsOnRelationship(relType: RelationshipType, fromType: NodeType, toType: NodeType): boolean;
|
|
@@ -54,9 +54,9 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
54
54
|
"gate",
|
|
55
55
|
"mode",
|
|
56
56
|
"artefact",
|
|
57
|
-
"artefact_flow",
|
|
58
57
|
"decision",
|
|
59
58
|
"change",
|
|
59
|
+
"view",
|
|
60
60
|
],
|
|
61
61
|
to: [
|
|
62
62
|
"intent",
|
|
@@ -73,7 +73,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
73
73
|
"gate",
|
|
74
74
|
"mode",
|
|
75
75
|
"artefact",
|
|
76
|
-
"artefact_flow",
|
|
77
76
|
"decision",
|
|
78
77
|
"change",
|
|
79
78
|
],
|
|
@@ -92,26 +91,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
92
91
|
],
|
|
93
92
|
to: ["invariant", "principle", "policy", "protocol", "concept"],
|
|
94
93
|
},
|
|
95
|
-
// Requires — explicit requirements
|
|
96
|
-
requires: {
|
|
97
|
-
from: [
|
|
98
|
-
"intent",
|
|
99
|
-
"concept",
|
|
100
|
-
"capability",
|
|
101
|
-
"element",
|
|
102
|
-
"realisation",
|
|
103
|
-
"stage",
|
|
104
|
-
"change",
|
|
105
|
-
],
|
|
106
|
-
to: [
|
|
107
|
-
"intent",
|
|
108
|
-
"concept",
|
|
109
|
-
"capability",
|
|
110
|
-
"element",
|
|
111
|
-
"realisation",
|
|
112
|
-
"artefact",
|
|
113
|
-
],
|
|
114
|
-
},
|
|
115
94
|
// Affects — broad impact relationships
|
|
116
95
|
affects: {
|
|
117
96
|
from: ["decision", "change", "artefact", "stage"],
|
|
@@ -145,7 +124,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
145
124
|
"realisation",
|
|
146
125
|
"decision",
|
|
147
126
|
"change",
|
|
148
|
-
"version",
|
|
149
127
|
],
|
|
150
128
|
to: [
|
|
151
129
|
"intent",
|
|
@@ -155,19 +133,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
155
133
|
"realisation",
|
|
156
134
|
"decision",
|
|
157
135
|
"change",
|
|
158
|
-
"version",
|
|
159
|
-
],
|
|
160
|
-
},
|
|
161
|
-
// Performs — process enactment
|
|
162
|
-
performs: {
|
|
163
|
-
from: ["stage", "role"],
|
|
164
|
-
to: [
|
|
165
|
-
"capability",
|
|
166
|
-
"artefact",
|
|
167
|
-
"artefact_flow",
|
|
168
|
-
"stage",
|
|
169
|
-
"concept",
|
|
170
|
-
"protocol",
|
|
171
136
|
],
|
|
172
137
|
},
|
|
173
138
|
// Precedes — temporal ordering
|
|
@@ -213,21 +178,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
213
178
|
"mode",
|
|
214
179
|
],
|
|
215
180
|
},
|
|
216
|
-
// Blocks — impediments and constraints
|
|
217
|
-
blocks: {
|
|
218
|
-
from: ["invariant", "policy", "decision", "principle"],
|
|
219
|
-
to: ["decision", "change", "stage"],
|
|
220
|
-
},
|
|
221
|
-
// Routes to — data/process flow
|
|
222
|
-
routes_to: {
|
|
223
|
-
from: ["artefact_flow"],
|
|
224
|
-
to: ["artefact_flow", "stage", "artefact"],
|
|
225
|
-
},
|
|
226
|
-
// Orchestrates — abstract workflow nodes direct executable flow nodes
|
|
227
|
-
orchestrates: {
|
|
228
|
-
from: ["concept", "protocol", "capability"],
|
|
229
|
-
to: ["milestone", "stage", "gate", "artefact_flow"],
|
|
230
|
-
},
|
|
231
181
|
// Governed by — governance relationships
|
|
232
182
|
governed_by: {
|
|
233
183
|
from: [
|
|
@@ -246,7 +196,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
246
196
|
},
|
|
247
197
|
// Modifies — mutation and change
|
|
248
198
|
modifies: {
|
|
249
|
-
from: ["change", "
|
|
199
|
+
from: ["change", "stage"],
|
|
250
200
|
to: [
|
|
251
201
|
"intent",
|
|
252
202
|
"concept",
|
|
@@ -256,80 +206,20 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
256
206
|
"artefact",
|
|
257
207
|
],
|
|
258
208
|
},
|
|
259
|
-
// Transforms into — metamorphosis
|
|
260
|
-
transforms_into: {
|
|
261
|
-
from: ["artefact"],
|
|
262
|
-
to: ["artefact"],
|
|
263
|
-
},
|
|
264
|
-
// Triggered by — causation
|
|
265
|
-
triggered_by: {
|
|
266
|
-
from: ["stage", "gate", "artefact_flow", "change"],
|
|
267
|
-
to: ["decision", "artefact", "gate", "stage"],
|
|
268
|
-
},
|
|
269
|
-
// Disables — negation/reversal
|
|
270
|
-
disables: {
|
|
271
|
-
from: ["decision", "change"],
|
|
272
|
-
to: ["capability", "realisation"],
|
|
273
|
-
},
|
|
274
|
-
// Applies to — applicability and scope
|
|
275
|
-
applies_to: {
|
|
276
|
-
from: ["policy", "principle", "mode", "protocol", "invariant"],
|
|
277
|
-
to: [
|
|
278
|
-
"intent",
|
|
279
|
-
"concept",
|
|
280
|
-
"capability",
|
|
281
|
-
"element",
|
|
282
|
-
"realisation",
|
|
283
|
-
"stage",
|
|
284
|
-
"decision",
|
|
285
|
-
"change",
|
|
286
|
-
"invariant",
|
|
287
|
-
],
|
|
288
|
-
},
|
|
289
209
|
// Produces — generation
|
|
290
210
|
produces: {
|
|
291
|
-
from: ["stage", "
|
|
211
|
+
from: ["stage", "realisation", "concept", "capability"],
|
|
292
212
|
to: ["artefact", "concept"],
|
|
293
213
|
},
|
|
294
|
-
// Consumes — usage
|
|
295
|
-
consumes: {
|
|
296
|
-
from: ["stage", "artefact_flow", "realisation", "role"],
|
|
297
|
-
to: ["artefact"],
|
|
298
|
-
},
|
|
299
|
-
// Selects — choice and instantiation
|
|
300
|
-
selects: {
|
|
301
|
-
from: ["decision", "mode"],
|
|
302
|
-
to: ["capability", "stage"],
|
|
303
|
-
},
|
|
304
|
-
// Influence — soft dependency between decisions and across nodes (CHG40)
|
|
305
|
-
influence: {
|
|
306
|
-
from: [
|
|
307
|
-
"intent",
|
|
308
|
-
"concept",
|
|
309
|
-
"capability",
|
|
310
|
-
"element",
|
|
311
|
-
"realisation",
|
|
312
|
-
"decision",
|
|
313
|
-
"change",
|
|
314
|
-
"stage",
|
|
315
|
-
],
|
|
316
|
-
to: [
|
|
317
|
-
"intent",
|
|
318
|
-
"concept",
|
|
319
|
-
"capability",
|
|
320
|
-
"element",
|
|
321
|
-
"realisation",
|
|
322
|
-
"decision",
|
|
323
|
-
"change",
|
|
324
|
-
"stage",
|
|
325
|
-
],
|
|
326
|
-
},
|
|
327
|
-
// Justifies — design rationale grounding (principle/decision → invariant/decision/principle/concept)
|
|
328
|
-
justifies: {
|
|
329
|
-
from: ["principle", "decision"],
|
|
330
|
-
to: ["invariant", "decision", "principle", "concept"],
|
|
331
|
-
},
|
|
332
214
|
};
|
|
215
|
+
const VIEW_READ_MODEL_DEPENDENCY_TARGETS = [
|
|
216
|
+
"concept",
|
|
217
|
+
"capability",
|
|
218
|
+
"element",
|
|
219
|
+
"stage",
|
|
220
|
+
"artefact",
|
|
221
|
+
"role",
|
|
222
|
+
];
|
|
333
223
|
/**
|
|
334
224
|
* Check if a relationship type is valid for the given endpoint node types.
|
|
335
225
|
* @param relType - The relationship type
|
|
@@ -342,6 +232,17 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
342
232
|
* ```
|
|
343
233
|
*/
|
|
344
234
|
export function isValidEndpointPair(relType, fromType, toType) {
|
|
235
|
+
if (relType === "depends_on" && fromType === "view") {
|
|
236
|
+
return VIEW_READ_MODEL_DEPENDENCY_TARGETS.includes(toType);
|
|
237
|
+
}
|
|
345
238
|
const endpoints = RELATIONSHIP_ENDPOINT_TYPES[relType];
|
|
346
239
|
return endpoints.from.includes(fromType) && endpoints.to.includes(toType);
|
|
347
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* True when a relationship is a read-model view dependency.
|
|
243
|
+
*/
|
|
244
|
+
export function isViewReadModelDependsOnRelationship(relType, fromType, toType) {
|
|
245
|
+
return (relType === "depends_on" &&
|
|
246
|
+
fromType === "view" &&
|
|
247
|
+
VIEW_READ_MODEL_DEPENDENCY_TARGETS.includes(toType));
|
|
248
|
+
}
|
package/dist/src/json-to-md.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { NODE_FILE_MAP, NODE_TYPE_LABELS, NodeType, RelationshipType, RELATIONSHIP_TYPE_LABELS, } from "./schema.js";
|
|
4
|
+
import { primaryLifecycleState } from "./lifecycle-state.js";
|
|
4
5
|
import { graphOp } from "./operations/graph.js";
|
|
5
6
|
import { graphRefinementOp } from "./operations/graph-refinement.js";
|
|
6
7
|
import { graphDecisionOp } from "./operations/graph-decision.js";
|
|
@@ -203,10 +204,6 @@ function renderNode(n, headingLevel, fromIdx, nodeMap, currentFile) {
|
|
|
203
204
|
lines.push(...rels);
|
|
204
205
|
lines.push("");
|
|
205
206
|
}
|
|
206
|
-
if (n.status) {
|
|
207
|
-
lines.push(`- Status: ${n.status}`);
|
|
208
|
-
lines.push("");
|
|
209
|
-
}
|
|
210
207
|
// Decision fields
|
|
211
208
|
if (n.context) {
|
|
212
209
|
lines.push(`Context: ${renderText(n.context)}`);
|
|
@@ -277,16 +274,6 @@ function renderNode(n, headingLevel, fromIdx, nodeMap, currentFile) {
|
|
|
277
274
|
}
|
|
278
275
|
lines.push("");
|
|
279
276
|
}
|
|
280
|
-
// Artefact flow
|
|
281
|
-
if (n.input) {
|
|
282
|
-
lines.push(`- Input: ${n.input}`);
|
|
283
|
-
}
|
|
284
|
-
if (n.output) {
|
|
285
|
-
lines.push(`- Output: ${n.output}`);
|
|
286
|
-
}
|
|
287
|
-
if (n.input || n.output) {
|
|
288
|
-
lines.push("");
|
|
289
|
-
}
|
|
290
277
|
// Inline external references
|
|
291
278
|
if (n.external_references && n.external_references.length > 0) {
|
|
292
279
|
lines.push(...renderExternalReferences(n.external_references));
|
|
@@ -533,7 +520,6 @@ export function jsonToMarkdownSingle(doc, options) {
|
|
|
533
520
|
...NODE_FILE_MAP.CHANGES,
|
|
534
521
|
"view",
|
|
535
522
|
"milestone",
|
|
536
|
-
"version",
|
|
537
523
|
];
|
|
538
524
|
lines.push(...renderNodesGrouped(doc.nodes, allTypes, fromIdx, 2, nodeMap));
|
|
539
525
|
// Diagrams section
|
|
@@ -638,7 +624,7 @@ export function jsonToMarkdownMultiDoc(doc, outDir, options) {
|
|
|
638
624
|
title: `${n.id} — ${n.name}`,
|
|
639
625
|
doc_type: n.type,
|
|
640
626
|
scope: n.type,
|
|
641
|
-
status: n
|
|
627
|
+
status: primaryLifecycleState(n),
|
|
642
628
|
},
|
|
643
629
|
};
|
|
644
630
|
// Count how many distinct file types would be produced
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Node, NodeStatus } from "./schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Return true when a lifecycle state is marked as reached on a node.
|
|
4
|
+
*/
|
|
5
|
+
export declare function hasLifecycleState(node: Node, state: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Return the most advanced reached lifecycle state, if any.
|
|
8
|
+
*/
|
|
9
|
+
export declare function primaryLifecycleState(node: Node): NodeStatus | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NODE_STATUSES } from "./schema.js";
|
|
2
|
+
function isLifecycleReached(value) {
|
|
3
|
+
return value === true || typeof value === "string";
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Return true when a lifecycle state is marked as reached on a node.
|
|
7
|
+
*/
|
|
8
|
+
export function hasLifecycleState(node, state) {
|
|
9
|
+
return isLifecycleReached(node.lifecycle?.[state]);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Return the most advanced reached lifecycle state, if any.
|
|
13
|
+
*/
|
|
14
|
+
export function primaryLifecycleState(node) {
|
|
15
|
+
for (let index = NODE_STATUSES.length - 1; index >= 0; index -= 1) {
|
|
16
|
+
const state = NODE_STATUSES[index];
|
|
17
|
+
if (hasLifecycleState(node, state)) {
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
package/dist/src/mcp/server.js
CHANGED
|
@@ -113,11 +113,11 @@ server.registerTool("stats", {
|
|
|
113
113
|
});
|
|
114
114
|
// Register query-nodes tool
|
|
115
115
|
server.registerTool("query-nodes", {
|
|
116
|
-
description: "Query nodes by type,
|
|
116
|
+
description: "Query nodes by type, lifecycle state, or other criteria",
|
|
117
117
|
inputSchema: z.object({
|
|
118
118
|
path: z.string().describe("Path to SysProM file"),
|
|
119
119
|
type: z.string().optional().describe("Filter by node type"),
|
|
120
|
-
status: z.string().optional().describe("Filter by
|
|
120
|
+
status: z.string().optional().describe("Filter by lifecycle state"),
|
|
121
121
|
}),
|
|
122
122
|
}, ({ path, type, status }) => {
|
|
123
123
|
const { doc } = loadDocument(path);
|
|
@@ -310,7 +310,6 @@ server.registerTool("update-node", {
|
|
|
310
310
|
const allowedFields = [
|
|
311
311
|
"name",
|
|
312
312
|
"description",
|
|
313
|
-
"status",
|
|
314
313
|
"context",
|
|
315
314
|
"options",
|
|
316
315
|
"selected",
|
|
@@ -320,8 +319,6 @@ server.registerTool("update-node", {
|
|
|
320
319
|
"plan",
|
|
321
320
|
"propagation",
|
|
322
321
|
"includes",
|
|
323
|
-
"input",
|
|
324
|
-
"output",
|
|
325
322
|
"external_references",
|
|
326
323
|
];
|
|
327
324
|
const droppedFields = [];
|
|
@@ -495,7 +492,7 @@ server.registerTool("infer-completeness", {
|
|
|
495
492
|
});
|
|
496
493
|
// Register infer-lifecycle tool
|
|
497
494
|
server.registerTool("infer-lifecycle", {
|
|
498
|
-
description: "Infer lifecycle state for nodes based on
|
|
495
|
+
description: "Infer lifecycle state for nodes based on lifecycle fields",
|
|
499
496
|
inputSchema: z.object({
|
|
500
497
|
path: z.string().describe("Path to SysProM file"),
|
|
501
498
|
}),
|
package/dist/src/md-to-json.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import { join, basename } from "node:path";
|
|
4
|
-
import { NODE_FILE_MAP, NODE_LABEL_TO_TYPE, RELATIONSHIP_TYPE_LABELS, RELATIONSHIP_LABEL_TO_TYPE, NodeType, RelationshipType,
|
|
4
|
+
import { NODE_FILE_MAP, NODE_LABEL_TO_TYPE, RELATIONSHIP_TYPE_LABELS, RELATIONSHIP_LABEL_TO_TYPE, NodeType, RelationshipType, ExternalReferenceRole, } from "./schema.js";
|
|
5
5
|
/** Strip markdown link syntax `[text](url)` → `text`. */
|
|
6
6
|
/**
|
|
7
7
|
* Strip markdown link syntax `[text](url)` → `text`.
|
|
@@ -27,12 +27,6 @@ function parseRelType(s) {
|
|
|
27
27
|
throw new Error(`Unknown relationship type: "${s}". Valid types: ${RelationshipType.options.join(", ")}`);
|
|
28
28
|
return result.data;
|
|
29
29
|
}
|
|
30
|
-
function parseNodeStatus(s) {
|
|
31
|
-
const result = NodeStatus.safeParse(s);
|
|
32
|
-
if (!result.success)
|
|
33
|
-
throw new Error(`Unknown node status: "${s}". Valid statuses: ${NodeStatus.options.join(", ")}`);
|
|
34
|
-
return result.data;
|
|
35
|
-
}
|
|
36
30
|
function parseExtRefRole(s) {
|
|
37
31
|
const result = ExternalReferenceRole.safeParse(s);
|
|
38
32
|
if (!result.success)
|
|
@@ -262,10 +256,6 @@ function parseNodeFromSection(section) {
|
|
|
262
256
|
if (descLines.length > 0) {
|
|
263
257
|
node.description = parseText(descLines.join("\n"));
|
|
264
258
|
}
|
|
265
|
-
// Status
|
|
266
|
-
const status = parseSingleValue(body, "- Status");
|
|
267
|
-
if (status)
|
|
268
|
-
node.status = parseNodeStatus(status);
|
|
269
259
|
// Decision fields
|
|
270
260
|
const context = parseSingleValue(body, "Context");
|
|
271
261
|
if (context)
|
|
@@ -316,13 +306,6 @@ function parseNodeFromSection(section) {
|
|
|
316
306
|
const includes = parseListItems(body, "Includes");
|
|
317
307
|
if (includes.length > 0)
|
|
318
308
|
node.includes = includes;
|
|
319
|
-
// Artefact flow
|
|
320
|
-
const input = parseSingleValue(body, "- Input");
|
|
321
|
-
if (input)
|
|
322
|
-
node.input = input;
|
|
323
|
-
const output = parseSingleValue(body, "- Output");
|
|
324
|
-
if (output)
|
|
325
|
-
node.output = output;
|
|
326
309
|
// Lifecycle and propagation from child sections
|
|
327
310
|
for (const child of section.children) {
|
|
328
311
|
if (child.heading === "Lifecycle") {
|
|
@@ -484,7 +467,6 @@ export function markdownSingleToJson(content) {
|
|
|
484
467
|
...NODE_FILE_MAP.CHANGES,
|
|
485
468
|
"view",
|
|
486
469
|
"milestone",
|
|
487
|
-
"version",
|
|
488
470
|
];
|
|
489
471
|
const { nodes, rels } = parseDocFile(content, allTypes);
|
|
490
472
|
const tableRels = parseRelationshipTable(body);
|