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.
- package/dist/src/cli/commands/query.js +22 -1
- package/dist/src/operations/index.d.ts +1 -0
- package/dist/src/operations/index.js +1 -0
- package/dist/src/operations/query-relationship-types.d.ts +145 -0
- package/dist/src/operations/query-relationship-types.js +29 -0
- package/dist/src/operations/validate.js +8 -2
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
}
|