sysprom 1.20.0 → 1.21.1

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 (74) hide show
  1. package/dist/schema.json +4 -44
  2. package/dist/src/cli/commands/add.js +6 -2
  3. package/dist/src/cli/commands/query.js +5 -3
  4. package/dist/src/cli/commands/speckit.js +2 -2
  5. package/dist/src/cli/commands/update.js +6 -4
  6. package/dist/src/endpoint-types.d.ts +4 -0
  7. package/dist/src/endpoint-types.js +22 -121
  8. package/dist/src/json-to-md.js +2 -16
  9. package/dist/src/lifecycle-state.d.ts +9 -0
  10. package/dist/src/lifecycle-state.js +22 -0
  11. package/dist/src/mcp/server.js +3 -6
  12. package/dist/src/md-to-json.js +1 -19
  13. package/dist/src/operations/add-node.d.ts +21 -135
  14. package/dist/src/operations/add-plan-task.d.ts +14 -90
  15. package/dist/src/operations/add-relationship.d.ts +16 -105
  16. package/dist/src/operations/check.d.ts +7 -45
  17. package/dist/src/operations/graph-decision.d.ts +7 -45
  18. package/dist/src/operations/graph-decision.js +0 -1
  19. package/dist/src/operations/graph-dependency.d.ts +7 -45
  20. package/dist/src/operations/graph-dependency.js +3 -23
  21. package/dist/src/operations/graph-refinement.d.ts +7 -45
  22. package/dist/src/operations/graph-shared.js +1 -3
  23. package/dist/src/operations/graph.d.ts +7 -45
  24. package/dist/src/operations/infer-completeness.d.ts +10 -54
  25. package/dist/src/operations/infer-derived.d.ts +7 -45
  26. package/dist/src/operations/infer-derived.js +28 -4
  27. package/dist/src/operations/infer-impact.d.ts +49 -315
  28. package/dist/src/operations/infer-impact.js +22 -3
  29. package/dist/src/operations/infer-lifecycle.d.ts +8 -106
  30. package/dist/src/operations/infer-lifecycle.js +4 -10
  31. package/dist/src/operations/init-document.d.ts +7 -45
  32. package/dist/src/operations/json-to-markdown.d.ts +7 -45
  33. package/dist/src/operations/mark-task-done.d.ts +14 -90
  34. package/dist/src/operations/mark-task-undone.d.ts +14 -90
  35. package/dist/src/operations/markdown-to-json.d.ts +7 -45
  36. package/dist/src/operations/next-id.d.ts +8 -48
  37. package/dist/src/operations/node-history.d.ts +7 -45
  38. package/dist/src/operations/plan-add-task.d.ts +14 -90
  39. package/dist/src/operations/plan-gate.d.ts +7 -45
  40. package/dist/src/operations/plan-init.d.ts +7 -45
  41. package/dist/src/operations/plan-progress.d.ts +7 -45
  42. package/dist/src/operations/plan-status.d.ts +7 -45
  43. package/dist/src/operations/query-node.d.ts +29 -195
  44. package/dist/src/operations/query-nodes.d.ts +15 -91
  45. package/dist/src/operations/query-nodes.js +6 -4
  46. package/dist/src/operations/query-relationships.d.ts +9 -60
  47. package/dist/src/operations/remove-node.d.ts +21 -135
  48. package/dist/src/operations/remove-node.js +11 -1
  49. package/dist/src/operations/remove-relationship.d.ts +15 -104
  50. package/dist/src/operations/rename.d.ts +14 -90
  51. package/dist/src/operations/search.d.ts +14 -90
  52. package/dist/src/operations/speckit-diff.d.ts +7 -45
  53. package/dist/src/operations/speckit-export.d.ts +7 -45
  54. package/dist/src/operations/speckit-import.d.ts +7 -45
  55. package/dist/src/operations/speckit-sync.d.ts +22 -136
  56. package/dist/src/operations/speckit-sync.js +3 -3
  57. package/dist/src/operations/state-at.d.ts +7 -45
  58. package/dist/src/operations/stats.d.ts +7 -45
  59. package/dist/src/operations/sync.d.ts +21 -135
  60. package/dist/src/operations/task-list.d.ts +7 -45
  61. package/dist/src/operations/timeline.d.ts +7 -45
  62. package/dist/src/operations/trace-from-node.d.ts +21 -135
  63. package/dist/src/operations/update-metadata.d.ts +14 -90
  64. package/dist/src/operations/update-node.d.ts +20 -155
  65. package/dist/src/operations/update-plan-task.d.ts +14 -90
  66. package/dist/src/operations/validate.d.ts +7 -45
  67. package/dist/src/operations/validate.js +8 -6
  68. package/dist/src/schema.d.ts +22 -164
  69. package/dist/src/schema.js +4 -27
  70. package/dist/src/speckit/generate.js +10 -7
  71. package/dist/src/speckit/parse.js +6 -3
  72. package/dist/src/speckit/plan.js +1 -1
  73. package/package.json +13 -2
  74. 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
- "enum": [
381
- "proposed",
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
- "triggered_by",
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.status = status;
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
- if (r.status)
20
- console.log(` ${pc.dim("Status")}: ${pc.yellow(r.status)}`);
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 node status"),
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, status), SysProM wins for structure
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
- status: specKitNode.status ?? syspromNode.status,
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("update node status"),
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 lifecycleFields = parseLifecycleFields(node.lifecycle, opts.lifecycle ?? []);
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", "artefact_flow", "stage"],
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", "artefact_flow", "realisation", "concept", "capability"],
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
+ }
@@ -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.status,
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
+ }
@@ -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, status, or other criteria",
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 node status"),
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 status and lifecycle fields",
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
  }),
@@ -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, NodeStatus, ExternalReferenceRole, } from "./schema.js";
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);