sysprom 1.26.0 → 1.27.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.
@@ -1,6 +1,6 @@
1
1
  import * as z from "zod";
2
- import { RelationshipType, NodeStatus } from "../../schema.js";
3
- import { updateNodeOp, addRelationshipOp, removeRelationshipOp, updateMetadataOp, } from "../../operations/index.js";
2
+ import { RelationshipType, NodeStatus, ExternalReferenceRole, } from "../../schema.js";
3
+ import { updateNodeOp, addRelationshipOp, removeRelationshipOp, updateMetadataOp, addExternalReferenceOp, removeExternalReferenceOp, } from "../../operations/index.js";
4
4
  import { mutationOpts, loadDoc, persistDoc } from "../shared.js";
5
5
  // ---------------------------------------------------------------------------
6
6
  // CLI helper functions
@@ -80,6 +80,25 @@ const metaOpts = mutationOpts.extend({
80
80
  .array(z.string())
81
81
  .describe("metadata field updates (key=value format)"),
82
82
  });
83
+ const addRefArgs = z.object({
84
+ id: z.string().describe("node ID to add reference to"),
85
+ });
86
+ const addRefOpts = mutationOpts.extend({
87
+ role: ExternalReferenceRole.describe("reference role"),
88
+ identifier: z
89
+ .string()
90
+ .describe("reference identifier (URI, file path, etc.)"),
91
+ description: z
92
+ .string()
93
+ .optional()
94
+ .describe("optional description of the reference"),
95
+ });
96
+ const removeRefArgs = z.object({
97
+ id: z.string().describe("node ID to remove reference from"),
98
+ });
99
+ const removeRefOpts = mutationOpts.extend({
100
+ identifier: z.string().describe("identifier of the reference to remove"),
101
+ });
83
102
  // ---------------------------------------------------------------------------
84
103
  // Subcommands
85
104
  // ---------------------------------------------------------------------------
@@ -218,6 +237,65 @@ const metaSubcommand = {
218
237
  }
219
238
  },
220
239
  };
240
+ const addRefSubcommand = {
241
+ name: "add-ref",
242
+ description: addExternalReferenceOp.def.description,
243
+ apiLink: addExternalReferenceOp.def.name,
244
+ args: addRefArgs,
245
+ opts: addRefOpts,
246
+ action(rawArgs, rawOpts) {
247
+ const args = addRefArgs.parse(rawArgs);
248
+ const opts = addRefOpts.parse(rawOpts);
249
+ const loaded = loadDoc(opts.path);
250
+ const { doc } = loaded;
251
+ const newDoc = addExternalReferenceOp({
252
+ doc,
253
+ nodeId: args.id,
254
+ role: opts.role,
255
+ identifier: opts.identifier,
256
+ description: opts.description,
257
+ });
258
+ persistDoc(newDoc, loaded, opts);
259
+ if (opts.json) {
260
+ const node = newDoc.nodes.find((n) => n.id === args.id);
261
+ const ref = node?.external_references?.find((r) => r.identifier === opts.identifier);
262
+ console.log(JSON.stringify(ref, null, 2));
263
+ }
264
+ else {
265
+ console.log(`${opts.dryRun ? "[dry-run] Would add" : "Added"} external reference to ${args.id}: ${opts.role} → ${opts.identifier}`);
266
+ }
267
+ },
268
+ };
269
+ const removeRefSubcommand = {
270
+ name: "remove-ref",
271
+ description: removeExternalReferenceOp.def.description,
272
+ apiLink: removeExternalReferenceOp.def.name,
273
+ args: removeRefArgs,
274
+ opts: removeRefOpts,
275
+ action(rawArgs, rawOpts) {
276
+ const args = removeRefArgs.parse(rawArgs);
277
+ const opts = removeRefOpts.parse(rawOpts);
278
+ const loaded = loadDoc(opts.path);
279
+ const { doc } = loaded;
280
+ removeExternalReferenceOp({
281
+ doc,
282
+ nodeId: args.id,
283
+ identifier: opts.identifier,
284
+ });
285
+ const newDoc = removeExternalReferenceOp({
286
+ doc,
287
+ nodeId: args.id,
288
+ identifier: opts.identifier,
289
+ });
290
+ persistDoc(newDoc, loaded, opts);
291
+ if (opts.json) {
292
+ console.log(JSON.stringify({ nodeId: args.id, identifier: opts.identifier }, null, 2));
293
+ }
294
+ else {
295
+ console.log(`${opts.dryRun ? "[dry-run] Would remove" : "Removed"} external reference from ${args.id}: ${opts.identifier}`);
296
+ }
297
+ },
298
+ };
221
299
  // ---------------------------------------------------------------------------
222
300
  // Main command
223
301
  // ---------------------------------------------------------------------------
@@ -228,6 +306,8 @@ export const updateCommand = {
228
306
  nodeSubcommand,
229
307
  addRelSubcommand,
230
308
  removeRelSubcommand,
309
+ addRefSubcommand,
310
+ removeRefSubcommand,
231
311
  metaSubcommand,
232
312
  ],
233
313
  };
@@ -53,6 +53,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
53
53
  "role",
54
54
  "gate",
55
55
  "mode",
56
+ "milestone",
56
57
  "artefact",
57
58
  "decision",
58
59
  "change",
@@ -88,6 +89,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
88
89
  "decision",
89
90
  "change",
90
91
  "invariant",
92
+ "role",
91
93
  ],
92
94
  to: ["invariant", "principle", "policy", "protocol", "concept"],
93
95
  },
@@ -191,6 +193,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
191
193
  "change",
192
194
  "policy",
193
195
  "artefact",
196
+ "role",
194
197
  ],
195
198
  to: ["policy", "protocol", "role", "principle", "invariant", "concept"],
196
199
  },
@@ -0,0 +1,534 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Add an external reference to a node.
4
+ *
5
+ * External references link nodes to source documents, ADRs, standards, code files,
6
+ * and other resources outside the SysProM graph.
7
+ */
8
+ export declare const addExternalReferenceOp: import("./define-operation.js").DefinedOperation<z.ZodObject<{
9
+ doc: z.ZodObject<{
10
+ $schema: z.ZodOptional<z.ZodString>;
11
+ metadata: z.ZodOptional<z.ZodObject<{
12
+ title: z.ZodOptional<z.ZodString>;
13
+ doc_type: z.ZodOptional<z.ZodString>;
14
+ scope: z.ZodOptional<z.ZodString>;
15
+ status: z.ZodOptional<z.ZodString>;
16
+ version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
17
+ }, z.core.$loose> & {
18
+ is(value: unknown): value is {
19
+ [x: string]: unknown;
20
+ title?: string | undefined;
21
+ doc_type?: string | undefined;
22
+ scope?: string | undefined;
23
+ status?: string | undefined;
24
+ version?: string | number | undefined;
25
+ };
26
+ }>;
27
+ nodes: z.ZodArray<z.ZodObject<{
28
+ id: z.ZodString;
29
+ type: z.ZodEnum<{
30
+ intent: "intent";
31
+ concept: "concept";
32
+ capability: "capability";
33
+ element: "element";
34
+ realisation: "realisation";
35
+ invariant: "invariant";
36
+ principle: "principle";
37
+ policy: "policy";
38
+ protocol: "protocol";
39
+ stage: "stage";
40
+ role: "role";
41
+ gate: "gate";
42
+ mode: "mode";
43
+ artefact: "artefact";
44
+ decision: "decision";
45
+ change: "change";
46
+ view: "view";
47
+ milestone: "milestone";
48
+ }> & {
49
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
50
+ };
51
+ name: z.ZodString;
52
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
53
+ is(value: unknown): value is string | string[];
54
+ }>;
55
+ status: z.ZodOptional<z.ZodNever>;
56
+ lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
57
+ context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
58
+ is(value: unknown): value is string | string[];
59
+ }>;
60
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
61
+ id: z.ZodString;
62
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
63
+ is(value: unknown): value is string | string[];
64
+ };
65
+ }, z.core.$loose> & {
66
+ is(value: unknown): value is {
67
+ [x: string]: unknown;
68
+ id: string;
69
+ description: string | string[];
70
+ };
71
+ }>>;
72
+ selected: z.ZodOptional<z.ZodString>;
73
+ rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
74
+ is(value: unknown): value is string | string[];
75
+ }>;
76
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
77
+ operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
78
+ type: z.ZodEnum<{
79
+ link: "link";
80
+ add: "add";
81
+ update: "update";
82
+ remove: "remove";
83
+ }>;
84
+ target: z.ZodOptional<z.ZodString>;
85
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
86
+ is(value: unknown): value is string | string[];
87
+ }>;
88
+ }, z.core.$loose> & {
89
+ is(value: unknown): value is {
90
+ [x: string]: unknown;
91
+ type: "link" | "add" | "update" | "remove";
92
+ target?: string | undefined;
93
+ description?: string | string[] | undefined;
94
+ };
95
+ }>>;
96
+ propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
97
+ includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
98
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
99
+ role: z.ZodEnum<{
100
+ output: "output";
101
+ input: "input";
102
+ context: "context";
103
+ evidence: "evidence";
104
+ source: "source";
105
+ standard: "standard";
106
+ prior_art: "prior_art";
107
+ }> & {
108
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
109
+ };
110
+ identifier: z.ZodString;
111
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
112
+ is(value: unknown): value is string | string[];
113
+ }>;
114
+ node_id: z.ZodOptional<z.ZodString>;
115
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
116
+ is(value: unknown): value is string | string[];
117
+ }>;
118
+ }, z.core.$strip> & {
119
+ is(value: unknown): value is {
120
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
121
+ identifier: string;
122
+ description?: string | string[] | undefined;
123
+ node_id?: string | undefined;
124
+ internalised?: string | string[] | undefined;
125
+ };
126
+ }>>;
127
+ readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
128
+ }, z.core.$loose>>;
129
+ relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
130
+ from: z.ZodString;
131
+ to: z.ZodString;
132
+ type: z.ZodEnum<{
133
+ refines: "refines";
134
+ realises: "realises";
135
+ implements: "implements";
136
+ depends_on: "depends_on";
137
+ constrained_by: "constrained_by";
138
+ affects: "affects";
139
+ supersedes: "supersedes";
140
+ must_preserve: "must_preserve";
141
+ part_of: "part_of";
142
+ precedes: "precedes";
143
+ must_follow: "must_follow";
144
+ governed_by: "governed_by";
145
+ modifies: "modifies";
146
+ produces: "produces";
147
+ }> & {
148
+ is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
149
+ };
150
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
151
+ is(value: unknown): value is string | string[];
152
+ }>;
153
+ polarity: z.ZodOptional<z.ZodEnum<{
154
+ positive: "positive";
155
+ negative: "negative";
156
+ neutral: "neutral";
157
+ uncertain: "uncertain";
158
+ }> & {
159
+ is(value: unknown): value is "positive" | "negative" | "neutral" | "uncertain";
160
+ }>;
161
+ strength: z.ZodOptional<z.ZodNumber>;
162
+ }, z.core.$loose> & {
163
+ is(value: unknown): value is {
164
+ [x: string]: unknown;
165
+ from: string;
166
+ to: string;
167
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
168
+ description?: string | string[] | undefined;
169
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
170
+ strength?: number | undefined;
171
+ };
172
+ }>>;
173
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
174
+ role: z.ZodEnum<{
175
+ output: "output";
176
+ input: "input";
177
+ context: "context";
178
+ evidence: "evidence";
179
+ source: "source";
180
+ standard: "standard";
181
+ prior_art: "prior_art";
182
+ }> & {
183
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
184
+ };
185
+ identifier: z.ZodString;
186
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
187
+ is(value: unknown): value is string | string[];
188
+ }>;
189
+ node_id: z.ZodOptional<z.ZodString>;
190
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
191
+ is(value: unknown): value is string | string[];
192
+ }>;
193
+ }, z.core.$strip> & {
194
+ is(value: unknown): value is {
195
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
196
+ identifier: string;
197
+ description?: string | string[] | undefined;
198
+ node_id?: string | undefined;
199
+ internalised?: string | string[] | undefined;
200
+ };
201
+ }>>;
202
+ }, z.core.$strip> & {
203
+ is(value: unknown): value is {
204
+ nodes: {
205
+ [x: string]: unknown;
206
+ id: string;
207
+ type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
208
+ name: string;
209
+ description?: string | string[] | undefined;
210
+ status?: undefined;
211
+ lifecycle?: Record<string, string | boolean> | undefined;
212
+ context?: string | string[] | undefined;
213
+ options?: {
214
+ [x: string]: unknown;
215
+ id: string;
216
+ description: string | string[];
217
+ }[] | undefined;
218
+ selected?: string | undefined;
219
+ rationale?: string | string[] | undefined;
220
+ scope?: string[] | undefined;
221
+ operations?: {
222
+ [x: string]: unknown;
223
+ type: "link" | "add" | "update" | "remove";
224
+ target?: string | undefined;
225
+ description?: string | string[] | undefined;
226
+ }[] | undefined;
227
+ propagation?: Record<string, boolean> | undefined;
228
+ includes?: string[] | undefined;
229
+ external_references?: {
230
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
231
+ identifier: string;
232
+ description?: string | string[] | undefined;
233
+ node_id?: string | undefined;
234
+ internalised?: string | string[] | undefined;
235
+ }[] | undefined;
236
+ subsystem?: /*elided*/ any | undefined;
237
+ }[];
238
+ $schema?: string | undefined;
239
+ metadata?: {
240
+ [x: string]: unknown;
241
+ title?: string | undefined;
242
+ doc_type?: string | undefined;
243
+ scope?: string | undefined;
244
+ status?: string | undefined;
245
+ version?: string | number | undefined;
246
+ } | undefined;
247
+ relationships?: {
248
+ [x: string]: unknown;
249
+ from: string;
250
+ to: string;
251
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
252
+ description?: string | string[] | undefined;
253
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
254
+ strength?: number | undefined;
255
+ }[] | undefined;
256
+ external_references?: {
257
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
258
+ identifier: string;
259
+ description?: string | string[] | undefined;
260
+ node_id?: string | undefined;
261
+ internalised?: string | string[] | undefined;
262
+ }[] | undefined;
263
+ };
264
+ };
265
+ nodeId: z.ZodString;
266
+ role: z.ZodEnum<{
267
+ output: "output";
268
+ input: "input";
269
+ context: "context";
270
+ evidence: "evidence";
271
+ source: "source";
272
+ standard: "standard";
273
+ prior_art: "prior_art";
274
+ }> & {
275
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
276
+ };
277
+ identifier: z.ZodString;
278
+ description: z.ZodOptional<z.ZodString>;
279
+ }, z.core.$strip>, z.ZodObject<{
280
+ $schema: z.ZodOptional<z.ZodString>;
281
+ metadata: z.ZodOptional<z.ZodObject<{
282
+ title: z.ZodOptional<z.ZodString>;
283
+ doc_type: z.ZodOptional<z.ZodString>;
284
+ scope: z.ZodOptional<z.ZodString>;
285
+ status: z.ZodOptional<z.ZodString>;
286
+ version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
287
+ }, z.core.$loose> & {
288
+ is(value: unknown): value is {
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
+ };
296
+ }>;
297
+ nodes: z.ZodArray<z.ZodObject<{
298
+ id: z.ZodString;
299
+ type: z.ZodEnum<{
300
+ intent: "intent";
301
+ concept: "concept";
302
+ capability: "capability";
303
+ element: "element";
304
+ realisation: "realisation";
305
+ invariant: "invariant";
306
+ principle: "principle";
307
+ policy: "policy";
308
+ protocol: "protocol";
309
+ stage: "stage";
310
+ role: "role";
311
+ gate: "gate";
312
+ mode: "mode";
313
+ artefact: "artefact";
314
+ decision: "decision";
315
+ change: "change";
316
+ view: "view";
317
+ milestone: "milestone";
318
+ }> & {
319
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
320
+ };
321
+ name: z.ZodString;
322
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
323
+ is(value: unknown): value is string | string[];
324
+ }>;
325
+ status: z.ZodOptional<z.ZodNever>;
326
+ lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
327
+ context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
328
+ is(value: unknown): value is string | string[];
329
+ }>;
330
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
331
+ id: z.ZodString;
332
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
333
+ is(value: unknown): value is string | string[];
334
+ };
335
+ }, z.core.$loose> & {
336
+ is(value: unknown): value is {
337
+ [x: string]: unknown;
338
+ id: string;
339
+ description: string | string[];
340
+ };
341
+ }>>;
342
+ selected: z.ZodOptional<z.ZodString>;
343
+ rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
344
+ is(value: unknown): value is string | string[];
345
+ }>;
346
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
347
+ operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
348
+ type: z.ZodEnum<{
349
+ link: "link";
350
+ add: "add";
351
+ update: "update";
352
+ remove: "remove";
353
+ }>;
354
+ target: z.ZodOptional<z.ZodString>;
355
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
356
+ is(value: unknown): value is string | string[];
357
+ }>;
358
+ }, z.core.$loose> & {
359
+ is(value: unknown): value is {
360
+ [x: string]: unknown;
361
+ type: "link" | "add" | "update" | "remove";
362
+ target?: string | undefined;
363
+ description?: string | string[] | undefined;
364
+ };
365
+ }>>;
366
+ propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
367
+ includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
368
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
369
+ role: z.ZodEnum<{
370
+ output: "output";
371
+ input: "input";
372
+ context: "context";
373
+ evidence: "evidence";
374
+ source: "source";
375
+ standard: "standard";
376
+ prior_art: "prior_art";
377
+ }> & {
378
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
379
+ };
380
+ identifier: z.ZodString;
381
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
382
+ is(value: unknown): value is string | string[];
383
+ }>;
384
+ node_id: z.ZodOptional<z.ZodString>;
385
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
386
+ is(value: unknown): value is string | string[];
387
+ }>;
388
+ }, z.core.$strip> & {
389
+ is(value: unknown): value is {
390
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
391
+ identifier: string;
392
+ description?: string | string[] | undefined;
393
+ node_id?: string | undefined;
394
+ internalised?: string | string[] | undefined;
395
+ };
396
+ }>>;
397
+ readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
398
+ }, z.core.$loose>>;
399
+ relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
400
+ from: z.ZodString;
401
+ to: z.ZodString;
402
+ type: z.ZodEnum<{
403
+ refines: "refines";
404
+ realises: "realises";
405
+ implements: "implements";
406
+ depends_on: "depends_on";
407
+ constrained_by: "constrained_by";
408
+ affects: "affects";
409
+ supersedes: "supersedes";
410
+ must_preserve: "must_preserve";
411
+ part_of: "part_of";
412
+ precedes: "precedes";
413
+ must_follow: "must_follow";
414
+ governed_by: "governed_by";
415
+ modifies: "modifies";
416
+ produces: "produces";
417
+ }> & {
418
+ is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
419
+ };
420
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
421
+ is(value: unknown): value is string | string[];
422
+ }>;
423
+ polarity: z.ZodOptional<z.ZodEnum<{
424
+ positive: "positive";
425
+ negative: "negative";
426
+ neutral: "neutral";
427
+ uncertain: "uncertain";
428
+ }> & {
429
+ is(value: unknown): value is "positive" | "negative" | "neutral" | "uncertain";
430
+ }>;
431
+ strength: z.ZodOptional<z.ZodNumber>;
432
+ }, z.core.$loose> & {
433
+ is(value: unknown): value is {
434
+ [x: string]: unknown;
435
+ from: string;
436
+ to: string;
437
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
438
+ description?: string | string[] | undefined;
439
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
440
+ strength?: number | undefined;
441
+ };
442
+ }>>;
443
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
444
+ role: z.ZodEnum<{
445
+ output: "output";
446
+ input: "input";
447
+ context: "context";
448
+ evidence: "evidence";
449
+ source: "source";
450
+ standard: "standard";
451
+ prior_art: "prior_art";
452
+ }> & {
453
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
454
+ };
455
+ identifier: z.ZodString;
456
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
457
+ is(value: unknown): value is string | string[];
458
+ }>;
459
+ node_id: z.ZodOptional<z.ZodString>;
460
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
461
+ is(value: unknown): value is string | string[];
462
+ }>;
463
+ }, z.core.$strip> & {
464
+ is(value: unknown): value is {
465
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
466
+ identifier: string;
467
+ description?: string | string[] | undefined;
468
+ node_id?: string | undefined;
469
+ internalised?: string | string[] | undefined;
470
+ };
471
+ }>>;
472
+ }, z.core.$strip> & {
473
+ is(value: unknown): value is {
474
+ nodes: {
475
+ [x: string]: unknown;
476
+ id: string;
477
+ type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
478
+ name: string;
479
+ description?: string | string[] | undefined;
480
+ status?: undefined;
481
+ lifecycle?: Record<string, string | boolean> | undefined;
482
+ context?: string | string[] | undefined;
483
+ options?: {
484
+ [x: string]: unknown;
485
+ id: string;
486
+ description: string | string[];
487
+ }[] | undefined;
488
+ selected?: string | undefined;
489
+ rationale?: string | string[] | undefined;
490
+ scope?: string[] | undefined;
491
+ operations?: {
492
+ [x: string]: unknown;
493
+ type: "link" | "add" | "update" | "remove";
494
+ target?: string | undefined;
495
+ description?: string | string[] | undefined;
496
+ }[] | undefined;
497
+ propagation?: Record<string, boolean> | undefined;
498
+ includes?: string[] | undefined;
499
+ external_references?: {
500
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
501
+ identifier: string;
502
+ description?: string | string[] | undefined;
503
+ node_id?: string | undefined;
504
+ internalised?: string | string[] | undefined;
505
+ }[] | undefined;
506
+ subsystem?: /*elided*/ any | undefined;
507
+ }[];
508
+ $schema?: string | undefined;
509
+ metadata?: {
510
+ [x: string]: unknown;
511
+ title?: string | undefined;
512
+ doc_type?: string | undefined;
513
+ scope?: string | undefined;
514
+ status?: string | undefined;
515
+ version?: string | number | undefined;
516
+ } | undefined;
517
+ relationships?: {
518
+ [x: string]: unknown;
519
+ from: string;
520
+ to: string;
521
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
522
+ description?: string | string[] | undefined;
523
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
524
+ strength?: number | undefined;
525
+ }[] | undefined;
526
+ external_references?: {
527
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
528
+ identifier: string;
529
+ description?: string | string[] | undefined;
530
+ node_id?: string | undefined;
531
+ internalised?: string | string[] | undefined;
532
+ }[] | undefined;
533
+ };
534
+ }>;
@@ -0,0 +1,45 @@
1
+ import * as z from "zod";
2
+ import { defineOperation } from "./define-operation.js";
3
+ import { SysProMDocument, ExternalReferenceRole, } from "../schema.js";
4
+ /**
5
+ * Add an external reference to a node.
6
+ *
7
+ * External references link nodes to source documents, ADRs, standards, code files,
8
+ * and other resources outside the SysProM graph.
9
+ */
10
+ export const addExternalReferenceOp = defineOperation({
11
+ name: "add-external-reference",
12
+ description: "Add an external reference to a node",
13
+ input: z.object({
14
+ doc: SysProMDocument,
15
+ nodeId: z.string().describe("The node to add the reference to"),
16
+ role: ExternalReferenceRole.describe("Reference role (e.g. source, output, evidence, standard)"),
17
+ identifier: z
18
+ .string()
19
+ .describe("Reference identifier (URI, file path, etc.)"),
20
+ description: z
21
+ .string()
22
+ .optional()
23
+ .describe("Optional description of the reference"),
24
+ }),
25
+ output: SysProMDocument,
26
+ fn: (input) => {
27
+ const node = input.doc.nodes.find((n) => n.id === input.nodeId);
28
+ if (!node) {
29
+ throw new Error(`Node not found: ${input.nodeId}`);
30
+ }
31
+ const newRef = {
32
+ role: input.role,
33
+ identifier: input.identifier,
34
+ ...(input.description && { description: input.description }),
35
+ };
36
+ const updatedNode = {
37
+ ...node,
38
+ external_references: [...(node.external_references ?? []), newRef],
39
+ };
40
+ return {
41
+ ...input.doc,
42
+ nodes: input.doc.nodes.map((n) => n.id === input.nodeId ? updatedNode : n),
43
+ };
44
+ },
45
+ });
@@ -5,6 +5,8 @@ export { updateNodeOp } from "./update-node.js";
5
5
  export { addRelationshipOp } from "./add-relationship.js";
6
6
  export { removeRelationshipOp } from "./remove-relationship.js";
7
7
  export { updateMetadataOp } from "./update-metadata.js";
8
+ export { addExternalReferenceOp } from "./add-external-reference.js";
9
+ export { removeExternalReferenceOp } from "./remove-external-reference.js";
8
10
  export { nextIdOp } from "./next-id.js";
9
11
  export { initDocumentOp } from "./init-document.js";
10
12
  export { planInitOp } from "./plan-init.js";
@@ -6,6 +6,8 @@ export { updateNodeOp } from "./update-node.js";
6
6
  export { addRelationshipOp } from "./add-relationship.js";
7
7
  export { removeRelationshipOp } from "./remove-relationship.js";
8
8
  export { updateMetadataOp } from "./update-metadata.js";
9
+ export { addExternalReferenceOp } from "./add-external-reference.js";
10
+ export { removeExternalReferenceOp } from "./remove-external-reference.js";
9
11
  export { nextIdOp } from "./next-id.js";
10
12
  export { initDocumentOp } from "./init-document.js";
11
13
  export { planInitOp } from "./plan-init.js";
@@ -0,0 +1,519 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Remove an external reference from a node by its identifier.
4
+ */
5
+ export declare const removeExternalReferenceOp: import("./define-operation.js").DefinedOperation<z.ZodObject<{
6
+ doc: z.ZodObject<{
7
+ $schema: z.ZodOptional<z.ZodString>;
8
+ metadata: z.ZodOptional<z.ZodObject<{
9
+ title: z.ZodOptional<z.ZodString>;
10
+ doc_type: z.ZodOptional<z.ZodString>;
11
+ scope: z.ZodOptional<z.ZodString>;
12
+ status: z.ZodOptional<z.ZodString>;
13
+ version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
14
+ }, z.core.$loose> & {
15
+ is(value: unknown): value is {
16
+ [x: string]: unknown;
17
+ title?: string | undefined;
18
+ doc_type?: string | undefined;
19
+ scope?: string | undefined;
20
+ status?: string | undefined;
21
+ version?: string | number | undefined;
22
+ };
23
+ }>;
24
+ nodes: z.ZodArray<z.ZodObject<{
25
+ id: z.ZodString;
26
+ type: z.ZodEnum<{
27
+ intent: "intent";
28
+ concept: "concept";
29
+ capability: "capability";
30
+ element: "element";
31
+ realisation: "realisation";
32
+ invariant: "invariant";
33
+ principle: "principle";
34
+ policy: "policy";
35
+ protocol: "protocol";
36
+ stage: "stage";
37
+ role: "role";
38
+ gate: "gate";
39
+ mode: "mode";
40
+ artefact: "artefact";
41
+ decision: "decision";
42
+ change: "change";
43
+ view: "view";
44
+ milestone: "milestone";
45
+ }> & {
46
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
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.ZodNever>;
53
+ lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
54
+ context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
55
+ is(value: unknown): value is string | string[];
56
+ }>;
57
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
58
+ id: z.ZodString;
59
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
60
+ is(value: unknown): value is string | string[];
61
+ };
62
+ }, z.core.$loose> & {
63
+ is(value: unknown): value is {
64
+ [x: string]: unknown;
65
+ id: string;
66
+ description: string | string[];
67
+ };
68
+ }>>;
69
+ selected: z.ZodOptional<z.ZodString>;
70
+ rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
71
+ is(value: unknown): value is string | string[];
72
+ }>;
73
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
74
+ operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
75
+ type: z.ZodEnum<{
76
+ link: "link";
77
+ add: "add";
78
+ update: "update";
79
+ remove: "remove";
80
+ }>;
81
+ target: z.ZodOptional<z.ZodString>;
82
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
83
+ is(value: unknown): value is string | string[];
84
+ }>;
85
+ }, z.core.$loose> & {
86
+ is(value: unknown): value is {
87
+ [x: string]: unknown;
88
+ type: "link" | "add" | "update" | "remove";
89
+ target?: string | undefined;
90
+ description?: string | string[] | undefined;
91
+ };
92
+ }>>;
93
+ propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
94
+ includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
95
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
96
+ role: z.ZodEnum<{
97
+ output: "output";
98
+ input: "input";
99
+ context: "context";
100
+ evidence: "evidence";
101
+ source: "source";
102
+ standard: "standard";
103
+ prior_art: "prior_art";
104
+ }> & {
105
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
106
+ };
107
+ identifier: z.ZodString;
108
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
109
+ is(value: unknown): value is string | string[];
110
+ }>;
111
+ node_id: z.ZodOptional<z.ZodString>;
112
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
113
+ is(value: unknown): value is string | string[];
114
+ }>;
115
+ }, z.core.$strip> & {
116
+ is(value: unknown): value is {
117
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
118
+ identifier: string;
119
+ description?: string | string[] | undefined;
120
+ node_id?: string | undefined;
121
+ internalised?: string | string[] | undefined;
122
+ };
123
+ }>>;
124
+ readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
125
+ }, z.core.$loose>>;
126
+ relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
127
+ from: z.ZodString;
128
+ to: z.ZodString;
129
+ type: z.ZodEnum<{
130
+ refines: "refines";
131
+ realises: "realises";
132
+ implements: "implements";
133
+ depends_on: "depends_on";
134
+ constrained_by: "constrained_by";
135
+ affects: "affects";
136
+ supersedes: "supersedes";
137
+ must_preserve: "must_preserve";
138
+ part_of: "part_of";
139
+ precedes: "precedes";
140
+ must_follow: "must_follow";
141
+ governed_by: "governed_by";
142
+ modifies: "modifies";
143
+ produces: "produces";
144
+ }> & {
145
+ is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
146
+ };
147
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
148
+ is(value: unknown): value is string | string[];
149
+ }>;
150
+ polarity: z.ZodOptional<z.ZodEnum<{
151
+ positive: "positive";
152
+ negative: "negative";
153
+ neutral: "neutral";
154
+ uncertain: "uncertain";
155
+ }> & {
156
+ is(value: unknown): value is "positive" | "negative" | "neutral" | "uncertain";
157
+ }>;
158
+ strength: z.ZodOptional<z.ZodNumber>;
159
+ }, z.core.$loose> & {
160
+ is(value: unknown): value is {
161
+ [x: string]: unknown;
162
+ from: string;
163
+ to: string;
164
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
165
+ description?: string | string[] | undefined;
166
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
167
+ strength?: number | undefined;
168
+ };
169
+ }>>;
170
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
171
+ role: z.ZodEnum<{
172
+ output: "output";
173
+ input: "input";
174
+ context: "context";
175
+ evidence: "evidence";
176
+ source: "source";
177
+ standard: "standard";
178
+ prior_art: "prior_art";
179
+ }> & {
180
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
181
+ };
182
+ identifier: z.ZodString;
183
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
184
+ is(value: unknown): value is string | string[];
185
+ }>;
186
+ node_id: z.ZodOptional<z.ZodString>;
187
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
188
+ is(value: unknown): value is string | string[];
189
+ }>;
190
+ }, z.core.$strip> & {
191
+ is(value: unknown): value is {
192
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
193
+ identifier: string;
194
+ description?: string | string[] | undefined;
195
+ node_id?: string | undefined;
196
+ internalised?: string | string[] | undefined;
197
+ };
198
+ }>>;
199
+ }, z.core.$strip> & {
200
+ is(value: unknown): value is {
201
+ nodes: {
202
+ [x: string]: unknown;
203
+ id: string;
204
+ type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
205
+ name: string;
206
+ description?: string | string[] | undefined;
207
+ status?: undefined;
208
+ lifecycle?: Record<string, string | boolean> | undefined;
209
+ context?: string | string[] | undefined;
210
+ options?: {
211
+ [x: string]: unknown;
212
+ id: string;
213
+ description: string | string[];
214
+ }[] | undefined;
215
+ selected?: string | undefined;
216
+ rationale?: string | string[] | undefined;
217
+ scope?: string[] | undefined;
218
+ operations?: {
219
+ [x: string]: unknown;
220
+ type: "link" | "add" | "update" | "remove";
221
+ target?: string | undefined;
222
+ description?: string | string[] | undefined;
223
+ }[] | undefined;
224
+ propagation?: Record<string, boolean> | undefined;
225
+ includes?: string[] | undefined;
226
+ external_references?: {
227
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
228
+ identifier: string;
229
+ description?: string | string[] | undefined;
230
+ node_id?: string | undefined;
231
+ internalised?: string | string[] | undefined;
232
+ }[] | undefined;
233
+ subsystem?: /*elided*/ any | undefined;
234
+ }[];
235
+ $schema?: string | undefined;
236
+ metadata?: {
237
+ [x: string]: unknown;
238
+ title?: string | undefined;
239
+ doc_type?: string | undefined;
240
+ scope?: string | undefined;
241
+ status?: string | undefined;
242
+ version?: string | number | undefined;
243
+ } | undefined;
244
+ relationships?: {
245
+ [x: string]: unknown;
246
+ from: string;
247
+ to: string;
248
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
249
+ description?: string | string[] | undefined;
250
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
251
+ strength?: number | undefined;
252
+ }[] | undefined;
253
+ external_references?: {
254
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
255
+ identifier: string;
256
+ description?: string | string[] | undefined;
257
+ node_id?: string | undefined;
258
+ internalised?: string | string[] | undefined;
259
+ }[] | undefined;
260
+ };
261
+ };
262
+ nodeId: z.ZodString;
263
+ identifier: z.ZodString;
264
+ }, z.core.$strip>, z.ZodObject<{
265
+ $schema: z.ZodOptional<z.ZodString>;
266
+ metadata: z.ZodOptional<z.ZodObject<{
267
+ title: z.ZodOptional<z.ZodString>;
268
+ doc_type: z.ZodOptional<z.ZodString>;
269
+ scope: z.ZodOptional<z.ZodString>;
270
+ status: z.ZodOptional<z.ZodString>;
271
+ version: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodInt]>>;
272
+ }, z.core.$loose> & {
273
+ is(value: unknown): value is {
274
+ [x: string]: unknown;
275
+ title?: string | undefined;
276
+ doc_type?: string | undefined;
277
+ scope?: string | undefined;
278
+ status?: string | undefined;
279
+ version?: string | number | undefined;
280
+ };
281
+ }>;
282
+ nodes: z.ZodArray<z.ZodObject<{
283
+ id: z.ZodString;
284
+ type: z.ZodEnum<{
285
+ intent: "intent";
286
+ concept: "concept";
287
+ capability: "capability";
288
+ element: "element";
289
+ realisation: "realisation";
290
+ invariant: "invariant";
291
+ principle: "principle";
292
+ policy: "policy";
293
+ protocol: "protocol";
294
+ stage: "stage";
295
+ role: "role";
296
+ gate: "gate";
297
+ mode: "mode";
298
+ artefact: "artefact";
299
+ decision: "decision";
300
+ change: "change";
301
+ view: "view";
302
+ milestone: "milestone";
303
+ }> & {
304
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
305
+ };
306
+ name: z.ZodString;
307
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
308
+ is(value: unknown): value is string | string[];
309
+ }>;
310
+ status: z.ZodOptional<z.ZodNever>;
311
+ lifecycle: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
312
+ context: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
313
+ is(value: unknown): value is string | string[];
314
+ }>;
315
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
316
+ id: z.ZodString;
317
+ description: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
318
+ is(value: unknown): value is string | string[];
319
+ };
320
+ }, z.core.$loose> & {
321
+ is(value: unknown): value is {
322
+ [x: string]: unknown;
323
+ id: string;
324
+ description: string | string[];
325
+ };
326
+ }>>;
327
+ selected: z.ZodOptional<z.ZodString>;
328
+ rationale: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
329
+ is(value: unknown): value is string | string[];
330
+ }>;
331
+ scope: z.ZodOptional<z.ZodArray<z.ZodString>>;
332
+ operations: z.ZodOptional<z.ZodArray<z.ZodObject<{
333
+ type: z.ZodEnum<{
334
+ link: "link";
335
+ add: "add";
336
+ update: "update";
337
+ remove: "remove";
338
+ }>;
339
+ target: z.ZodOptional<z.ZodString>;
340
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
341
+ is(value: unknown): value is string | string[];
342
+ }>;
343
+ }, z.core.$loose> & {
344
+ is(value: unknown): value is {
345
+ [x: string]: unknown;
346
+ type: "link" | "add" | "update" | "remove";
347
+ target?: string | undefined;
348
+ description?: string | string[] | undefined;
349
+ };
350
+ }>>;
351
+ propagation: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodBoolean>>;
352
+ includes: z.ZodOptional<z.ZodArray<z.ZodString>>;
353
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
354
+ role: z.ZodEnum<{
355
+ output: "output";
356
+ input: "input";
357
+ context: "context";
358
+ evidence: "evidence";
359
+ source: "source";
360
+ standard: "standard";
361
+ prior_art: "prior_art";
362
+ }> & {
363
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
364
+ };
365
+ identifier: z.ZodString;
366
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
367
+ is(value: unknown): value is string | string[];
368
+ }>;
369
+ node_id: z.ZodOptional<z.ZodString>;
370
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
371
+ is(value: unknown): value is string | string[];
372
+ }>;
373
+ }, z.core.$strip> & {
374
+ is(value: unknown): value is {
375
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
376
+ identifier: string;
377
+ description?: string | string[] | undefined;
378
+ node_id?: string | undefined;
379
+ internalised?: string | string[] | undefined;
380
+ };
381
+ }>>;
382
+ readonly subsystem: z.ZodOptional<z.ZodObject</*elided*/ any, z.core.$strip>>;
383
+ }, z.core.$loose>>;
384
+ relationships: z.ZodOptional<z.ZodArray<z.ZodObject<{
385
+ from: z.ZodString;
386
+ to: z.ZodString;
387
+ type: z.ZodEnum<{
388
+ refines: "refines";
389
+ realises: "realises";
390
+ implements: "implements";
391
+ depends_on: "depends_on";
392
+ constrained_by: "constrained_by";
393
+ affects: "affects";
394
+ supersedes: "supersedes";
395
+ must_preserve: "must_preserve";
396
+ part_of: "part_of";
397
+ precedes: "precedes";
398
+ must_follow: "must_follow";
399
+ governed_by: "governed_by";
400
+ modifies: "modifies";
401
+ produces: "produces";
402
+ }> & {
403
+ is(value: unknown): value is "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
404
+ };
405
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
406
+ is(value: unknown): value is string | string[];
407
+ }>;
408
+ polarity: z.ZodOptional<z.ZodEnum<{
409
+ positive: "positive";
410
+ negative: "negative";
411
+ neutral: "neutral";
412
+ uncertain: "uncertain";
413
+ }> & {
414
+ is(value: unknown): value is "positive" | "negative" | "neutral" | "uncertain";
415
+ }>;
416
+ strength: z.ZodOptional<z.ZodNumber>;
417
+ }, z.core.$loose> & {
418
+ is(value: unknown): value is {
419
+ [x: string]: unknown;
420
+ from: string;
421
+ to: string;
422
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
423
+ description?: string | string[] | undefined;
424
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
425
+ strength?: number | undefined;
426
+ };
427
+ }>>;
428
+ external_references: z.ZodOptional<z.ZodArray<z.ZodObject<{
429
+ role: z.ZodEnum<{
430
+ output: "output";
431
+ input: "input";
432
+ context: "context";
433
+ evidence: "evidence";
434
+ source: "source";
435
+ standard: "standard";
436
+ prior_art: "prior_art";
437
+ }> & {
438
+ is(value: unknown): value is "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
439
+ };
440
+ identifier: z.ZodString;
441
+ description: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
442
+ is(value: unknown): value is string | string[];
443
+ }>;
444
+ node_id: z.ZodOptional<z.ZodString>;
445
+ internalised: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]> & {
446
+ is(value: unknown): value is string | string[];
447
+ }>;
448
+ }, z.core.$strip> & {
449
+ is(value: unknown): value is {
450
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
451
+ identifier: string;
452
+ description?: string | string[] | undefined;
453
+ node_id?: string | undefined;
454
+ internalised?: string | string[] | undefined;
455
+ };
456
+ }>>;
457
+ }, z.core.$strip> & {
458
+ is(value: unknown): value is {
459
+ nodes: {
460
+ [x: string]: unknown;
461
+ id: string;
462
+ type: "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
463
+ name: string;
464
+ description?: string | string[] | undefined;
465
+ status?: undefined;
466
+ lifecycle?: Record<string, string | boolean> | undefined;
467
+ context?: string | string[] | undefined;
468
+ options?: {
469
+ [x: string]: unknown;
470
+ id: string;
471
+ description: string | string[];
472
+ }[] | undefined;
473
+ selected?: string | undefined;
474
+ rationale?: string | string[] | undefined;
475
+ scope?: string[] | undefined;
476
+ operations?: {
477
+ [x: string]: unknown;
478
+ type: "link" | "add" | "update" | "remove";
479
+ target?: string | undefined;
480
+ description?: string | string[] | undefined;
481
+ }[] | undefined;
482
+ propagation?: Record<string, boolean> | undefined;
483
+ includes?: string[] | undefined;
484
+ external_references?: {
485
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
486
+ identifier: string;
487
+ description?: string | string[] | undefined;
488
+ node_id?: string | undefined;
489
+ internalised?: string | string[] | undefined;
490
+ }[] | undefined;
491
+ subsystem?: /*elided*/ any | undefined;
492
+ }[];
493
+ $schema?: string | undefined;
494
+ metadata?: {
495
+ [x: string]: unknown;
496
+ title?: string | undefined;
497
+ doc_type?: string | undefined;
498
+ scope?: string | undefined;
499
+ status?: string | undefined;
500
+ version?: string | number | undefined;
501
+ } | undefined;
502
+ relationships?: {
503
+ [x: string]: unknown;
504
+ from: string;
505
+ to: string;
506
+ type: "refines" | "realises" | "implements" | "depends_on" | "constrained_by" | "affects" | "supersedes" | "must_preserve" | "part_of" | "precedes" | "must_follow" | "governed_by" | "modifies" | "produces";
507
+ description?: string | string[] | undefined;
508
+ polarity?: "positive" | "negative" | "neutral" | "uncertain" | undefined;
509
+ strength?: number | undefined;
510
+ }[] | undefined;
511
+ external_references?: {
512
+ role: "output" | "input" | "context" | "evidence" | "source" | "standard" | "prior_art";
513
+ identifier: string;
514
+ description?: string | string[] | undefined;
515
+ node_id?: string | undefined;
516
+ internalised?: string | string[] | undefined;
517
+ }[] | undefined;
518
+ };
519
+ }>;
@@ -0,0 +1,37 @@
1
+ import * as z from "zod";
2
+ import { defineOperation } from "./define-operation.js";
3
+ import { SysProMDocument } from "../schema.js";
4
+ /**
5
+ * Remove an external reference from a node by its identifier.
6
+ */
7
+ export const removeExternalReferenceOp = defineOperation({
8
+ name: "remove-external-reference",
9
+ description: "Remove an external reference from a node",
10
+ input: z.object({
11
+ doc: SysProMDocument,
12
+ nodeId: z.string().describe("The node to remove the reference from"),
13
+ identifier: z
14
+ .string()
15
+ .describe("The identifier of the reference to remove"),
16
+ }),
17
+ output: SysProMDocument,
18
+ fn: (input) => {
19
+ const node = input.doc.nodes.find((n) => n.id === input.nodeId);
20
+ if (!node) {
21
+ throw new Error(`Node not found: ${input.nodeId}`);
22
+ }
23
+ const refs = node.external_references ?? [];
24
+ const found = refs.some((r) => r.identifier === input.identifier);
25
+ if (!found) {
26
+ throw new Error(`Reference not found: ${input.identifier} on node ${input.nodeId}`);
27
+ }
28
+ const updatedNode = {
29
+ ...node,
30
+ external_references: refs.filter((r) => r.identifier !== input.identifier),
31
+ };
32
+ return {
33
+ ...input.doc,
34
+ nodes: input.doc.nodes.map((n) => n.id === input.nodeId ? updatedNode : n),
35
+ };
36
+ },
37
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sysprom",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "description": "SysProM — System Provenance Model CLI and library",
5
5
  "author": "ExaDev",
6
6
  "homepage": "https://exadev.github.io/SysProM",