sysprom 1.25.0 → 1.26.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.
@@ -2,7 +2,7 @@ import pc from "picocolors";
2
2
  import * as z from "zod";
3
3
  import { textToString } from "../../text.js";
4
4
  import { readOpts, loadDoc } from "../shared.js";
5
- import { queryNodesOp, queryNodeOp, queryRelationshipsOp, traceFromNodeOp, timelineOp, nodeHistoryOp, stateAtOp, } from "../../operations/index.js";
5
+ import { queryNodesOp, queryNodeOp, queryRelationshipsOp, queryRelationshipTypesOp, traceFromNodeOp, timelineOp, nodeHistoryOp, stateAtOp, } from "../../operations/index.js";
6
6
  import { NodeType, NodeStatus } from "../../schema.js";
7
7
  import { primaryLifecycleState } from "../../lifecycle-state.js";
8
8
  // ---------------------------------------------------------------------------
@@ -211,6 +211,26 @@ const timelineSubcommand = {
211
211
  }
212
212
  },
213
213
  };
214
+ const relationshipTypesSubcommand = {
215
+ name: "relationship-types",
216
+ description: queryRelationshipTypesOp.def.description,
217
+ apiLink: queryRelationshipTypesOp.def.name,
218
+ opts: readOpts,
219
+ action(_rawArgs, rawOpts) {
220
+ const opts = readOpts.parse(rawOpts);
221
+ const relTypes = queryRelationshipTypesOp({});
222
+ if (opts.json) {
223
+ console.log(JSON.stringify(relTypes, null, 2));
224
+ }
225
+ else {
226
+ for (const relType of relTypes) {
227
+ console.log(pc.bold(relType.type));
228
+ console.log(` ${pc.dim("from")}: ${relType.from.map((t) => pc.cyan(t)).join(", ")}`);
229
+ console.log(` ${pc.dim("to")}: ${relType.to.map((t) => pc.cyan(t)).join(", ")}`);
230
+ }
231
+ }
232
+ },
233
+ };
214
234
  const stateAtSubcommand = {
215
235
  name: "state-at",
216
236
  description: stateAtOp.def.description,
@@ -247,6 +267,7 @@ export const queryCommand = {
247
267
  nodesSubcommand,
248
268
  nodeSubcommand,
249
269
  relsSubcommand,
270
+ relationshipTypesSubcommand,
250
271
  traceSubcommand,
251
272
  timelineSubcommand,
252
273
  stateAtSubcommand,
@@ -18,6 +18,7 @@ export { planGateOp, type GateResultOutput } from "./plan-gate.js";
18
18
  export { queryNodesOp } from "./query-nodes.js";
19
19
  export { queryNodeOp, type NodeDetail } from "./query-node.js";
20
20
  export { queryRelationshipsOp } from "./query-relationships.js";
21
+ export { queryRelationshipTypesOp } from "./query-relationship-types.js";
21
22
  export { traceFromNodeOp, type TraceNode } from "./trace-from-node.js";
22
23
  export { timelineOp, type TimelineEvent } from "./timeline.js";
23
24
  export { nodeHistoryOp } from "./node-history.js";
@@ -20,6 +20,7 @@ export { planGateOp } from "./plan-gate.js";
20
20
  export { queryNodesOp } from "./query-nodes.js";
21
21
  export { queryNodeOp } from "./query-node.js";
22
22
  export { queryRelationshipsOp } from "./query-relationships.js";
23
+ export { queryRelationshipTypesOp } from "./query-relationship-types.js";
23
24
  export { traceFromNodeOp } from "./trace-from-node.js";
24
25
  // Temporal operations
25
26
  export { timelineOp } from "./timeline.js";
@@ -0,0 +1,145 @@
1
+ import * as z from "zod";
2
+ import { RelationshipType, NodeType } from "../schema.js";
3
+ /** Information about valid endpoint types for a relationship type. */
4
+ export interface RelationshipTypeInfo {
5
+ type: RelationshipType;
6
+ from: NodeType[];
7
+ to: NodeType[];
8
+ }
9
+ /** Result of querying relationship endpoint types. */
10
+ export declare const QueryRelationshipTypesResult: z.ZodArray<z.ZodObject<{
11
+ type: z.ZodEnum<{
12
+ refines: "refines";
13
+ realises: "realises";
14
+ implements: "implements";
15
+ depends_on: "depends_on";
16
+ constrained_by: "constrained_by";
17
+ affects: "affects";
18
+ supersedes: "supersedes";
19
+ must_preserve: "must_preserve";
20
+ part_of: "part_of";
21
+ precedes: "precedes";
22
+ must_follow: "must_follow";
23
+ governed_by: "governed_by";
24
+ modifies: "modifies";
25
+ produces: "produces";
26
+ }> & {
27
+ 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";
28
+ };
29
+ from: z.ZodArray<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
+ to: z.ZodArray<z.ZodEnum<{
52
+ intent: "intent";
53
+ concept: "concept";
54
+ capability: "capability";
55
+ element: "element";
56
+ realisation: "realisation";
57
+ invariant: "invariant";
58
+ principle: "principle";
59
+ policy: "policy";
60
+ protocol: "protocol";
61
+ stage: "stage";
62
+ role: "role";
63
+ gate: "gate";
64
+ mode: "mode";
65
+ artefact: "artefact";
66
+ decision: "decision";
67
+ change: "change";
68
+ view: "view";
69
+ milestone: "milestone";
70
+ }> & {
71
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
72
+ }>;
73
+ }, z.core.$strip>>;
74
+ /** Result type for queryRelationshipTypesOp. */
75
+ export type QueryRelationshipTypesResult = z.infer<typeof QueryRelationshipTypesResult>;
76
+ /**
77
+ * Query valid endpoint types for all relationship types.
78
+ *
79
+ * Returns a list of relationship types with their valid source and target node types.
80
+ * Useful for discovering valid combinations before attempting to add relationships.
81
+ */
82
+ export declare const queryRelationshipTypesOp: import("./define-operation.js").DefinedOperation<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
83
+ type: z.ZodEnum<{
84
+ refines: "refines";
85
+ realises: "realises";
86
+ implements: "implements";
87
+ depends_on: "depends_on";
88
+ constrained_by: "constrained_by";
89
+ affects: "affects";
90
+ supersedes: "supersedes";
91
+ must_preserve: "must_preserve";
92
+ part_of: "part_of";
93
+ precedes: "precedes";
94
+ must_follow: "must_follow";
95
+ governed_by: "governed_by";
96
+ modifies: "modifies";
97
+ produces: "produces";
98
+ }> & {
99
+ 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";
100
+ };
101
+ from: z.ZodArray<z.ZodEnum<{
102
+ intent: "intent";
103
+ concept: "concept";
104
+ capability: "capability";
105
+ element: "element";
106
+ realisation: "realisation";
107
+ invariant: "invariant";
108
+ principle: "principle";
109
+ policy: "policy";
110
+ protocol: "protocol";
111
+ stage: "stage";
112
+ role: "role";
113
+ gate: "gate";
114
+ mode: "mode";
115
+ artefact: "artefact";
116
+ decision: "decision";
117
+ change: "change";
118
+ view: "view";
119
+ milestone: "milestone";
120
+ }> & {
121
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
122
+ }>;
123
+ to: z.ZodArray<z.ZodEnum<{
124
+ intent: "intent";
125
+ concept: "concept";
126
+ capability: "capability";
127
+ element: "element";
128
+ realisation: "realisation";
129
+ invariant: "invariant";
130
+ principle: "principle";
131
+ policy: "policy";
132
+ protocol: "protocol";
133
+ stage: "stage";
134
+ role: "role";
135
+ gate: "gate";
136
+ mode: "mode";
137
+ artefact: "artefact";
138
+ decision: "decision";
139
+ change: "change";
140
+ view: "view";
141
+ milestone: "milestone";
142
+ }> & {
143
+ is(value: unknown): value is "intent" | "concept" | "capability" | "element" | "realisation" | "invariant" | "principle" | "policy" | "protocol" | "stage" | "role" | "gate" | "mode" | "artefact" | "decision" | "change" | "view" | "milestone";
144
+ }>;
145
+ }, z.core.$strip>>>;
@@ -0,0 +1,29 @@
1
+ import * as z from "zod";
2
+ import { defineOperation } from "./define-operation.js";
3
+ import { RelationshipType, NodeType } from "../schema.js";
4
+ import { RELATIONSHIP_ENDPOINT_TYPES } from "../endpoint-types.js";
5
+ /** Result of querying relationship endpoint types. */
6
+ export const QueryRelationshipTypesResult = z.array(z.object({
7
+ type: RelationshipType,
8
+ from: z.array(NodeType),
9
+ to: z.array(NodeType),
10
+ }));
11
+ /**
12
+ * Query valid endpoint types for all relationship types.
13
+ *
14
+ * Returns a list of relationship types with their valid source and target node types.
15
+ * Useful for discovering valid combinations before attempting to add relationships.
16
+ */
17
+ export const queryRelationshipTypesOp = defineOperation({
18
+ name: "query-relationship-types",
19
+ description: "Query valid endpoint types for all relationship types",
20
+ input: z.object({}),
21
+ output: QueryRelationshipTypesResult,
22
+ fn: () => {
23
+ return Object.entries(RELATIONSHIP_ENDPOINT_TYPES).map(([relType, endpoints]) => ({
24
+ type: RelationshipType.parse(relType),
25
+ from: endpoints.from,
26
+ to: endpoints.to,
27
+ }));
28
+ },
29
+ });
@@ -118,12 +118,18 @@ export const validateOp = defineOperation({
118
118
  issues.push(`${n.id} (${n.name}): affects domain nodes but has no must_preserve relationship`);
119
119
  }
120
120
  }
121
- // INV13: Decisions must have options and selected
121
+ // INV13: Decisions must have options and selected (if decided)
122
122
  for (const n of input.doc.nodes.filter((n) => n.type === "decision")) {
123
123
  if (!n.options || n.options.length === 0) {
124
124
  issues.push(`${n.id} (${n.name}): decision has no options`);
125
125
  }
126
- if (!n.selected) {
126
+ // Only require selected option if the decision is in a "decided" state
127
+ // Decided states: accepted, implemented, adopted
128
+ // Undecided states allowed: proposed, experimental, deferred
129
+ const isDecided = hasLifecycleState(n, "accepted") ||
130
+ hasLifecycleState(n, "implemented") ||
131
+ hasLifecycleState(n, "adopted");
132
+ if (isDecided && !n.selected) {
127
133
  issues.push(`${n.id} (${n.name}): decision has no selected option`);
128
134
  }
129
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sysprom",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "description": "SysProM — System Provenance Model CLI and library",
5
5
  "author": "ExaDev",
6
6
  "homepage": "https://exadev.github.io/SysProM",