sysprom 1.17.0 → 1.18.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/README.md +145 -75
- package/dist/schema.json +2 -1
- package/dist/src/cli/commands/graph.d.ts +15 -0
- package/dist/src/cli/commands/graph.js +51 -2
- package/dist/src/cli/commands/init.d.ts +1 -1
- package/dist/src/cli/commands/json2md.d.ts +30 -1
- package/dist/src/cli/commands/json2md.js +42 -1
- package/dist/src/cli/commands/md2json.d.ts +1 -1
- package/dist/src/cli/commands/sync.d.ts +1 -1
- package/dist/src/cli/define-command.d.ts +1 -1
- package/dist/src/cli/define-command.js +176 -156
- package/dist/src/endpoint-types.js +13 -6
- package/dist/src/json-to-md.d.ts +32 -2
- package/dist/src/json-to-md.js +145 -5
- package/dist/src/md-to-json.js +7 -0
- package/dist/src/operations/add-node.d.ts +12 -9
- package/dist/src/operations/add-plan-task.d.ts +8 -6
- package/dist/src/operations/add-relationship.d.ts +11 -8
- package/dist/src/operations/check.d.ts +4 -3
- package/dist/src/operations/define-operation.d.ts +1 -1
- package/dist/src/operations/graph-decision.d.ts +329 -0
- package/dist/src/operations/graph-decision.js +96 -0
- package/dist/src/operations/graph-dependency.d.ts +329 -0
- package/dist/src/operations/graph-dependency.js +121 -0
- package/dist/src/operations/graph-refinement.d.ts +329 -0
- package/dist/src/operations/graph-refinement.js +97 -0
- package/dist/src/operations/graph-shared.d.ts +116 -0
- package/dist/src/operations/graph-shared.js +257 -0
- package/dist/src/operations/graph.d.ts +20 -4
- package/dist/src/operations/graph.js +129 -36
- package/dist/src/operations/index.d.ts +3 -0
- package/dist/src/operations/index.js +3 -0
- package/dist/src/operations/infer-completeness.d.ts +4 -3
- package/dist/src/operations/infer-derived.d.ts +4 -3
- package/dist/src/operations/infer-impact.d.ts +28 -21
- package/dist/src/operations/infer-lifecycle.d.ts +4 -3
- package/dist/src/operations/init-document.d.ts +4 -3
- package/dist/src/operations/json-to-markdown.d.ts +28 -3
- package/dist/src/operations/json-to-markdown.js +11 -1
- package/dist/src/operations/mark-task-done.d.ts +8 -6
- package/dist/src/operations/mark-task-undone.d.ts +8 -6
- package/dist/src/operations/markdown-to-json.d.ts +4 -3
- package/dist/src/operations/next-id.d.ts +4 -3
- package/dist/src/operations/node-history.d.ts +4 -3
- package/dist/src/operations/plan-add-task.d.ts +8 -6
- package/dist/src/operations/plan-gate.d.ts +4 -3
- package/dist/src/operations/plan-init.d.ts +4 -3
- package/dist/src/operations/plan-progress.d.ts +4 -3
- package/dist/src/operations/plan-status.d.ts +4 -3
- package/dist/src/operations/query-node.d.ts +24 -17
- package/dist/src/operations/query-nodes.d.ts +8 -6
- package/dist/src/operations/query-relationships.d.ts +7 -5
- package/dist/src/operations/remove-node.d.ts +12 -9
- package/dist/src/operations/remove-relationship.d.ts +10 -7
- package/dist/src/operations/rename.d.ts +8 -6
- package/dist/src/operations/search.d.ts +8 -6
- package/dist/src/operations/speckit-diff.d.ts +4 -3
- package/dist/src/operations/speckit-export.d.ts +4 -3
- package/dist/src/operations/speckit-import.d.ts +4 -3
- package/dist/src/operations/speckit-sync.d.ts +12 -9
- package/dist/src/operations/state-at.d.ts +4 -3
- package/dist/src/operations/stats.d.ts +4 -3
- package/dist/src/operations/sync.d.ts +12 -9
- package/dist/src/operations/task-list.d.ts +4 -3
- package/dist/src/operations/timeline.d.ts +4 -3
- package/dist/src/operations/trace-from-node.d.ts +12 -9
- package/dist/src/operations/update-metadata.d.ts +8 -6
- package/dist/src/operations/update-node.d.ts +11 -8
- package/dist/src/operations/update-plan-task.d.ts +8 -6
- package/dist/src/operations/validate.d.ts +4 -3
- package/dist/src/schema.d.ts +15 -10
- package/dist/src/schema.js +3 -11
- package/dist/src/utils/define-schema.d.ts +17 -0
- package/dist/src/utils/define-schema.js +21 -0
- package/package.json +98 -93
- package/schema.json +2 -1
|
@@ -15,7 +15,6 @@ function fieldIsArray(field) {
|
|
|
15
15
|
}
|
|
16
16
|
function fieldIsBoolean(field) {
|
|
17
17
|
const inner = unwrapField(field);
|
|
18
|
-
// ZodBoolean has no unique property, but we can check safeParse
|
|
19
18
|
const trueResult = inner.safeParse(true);
|
|
20
19
|
const strResult = inner.safeParse("test");
|
|
21
20
|
return trueResult.success && !strResult.success;
|
|
@@ -33,26 +32,9 @@ function fieldChoices(field) {
|
|
|
33
32
|
}
|
|
34
33
|
return undefined;
|
|
35
34
|
}
|
|
36
|
-
function isZodField(obj) {
|
|
37
|
-
if (typeof obj !== "object" || obj === null)
|
|
38
|
-
return false;
|
|
39
|
-
// Check if it has methods/properties characteristic of Zod fields
|
|
40
|
-
const maybeField = toRecord(obj);
|
|
41
|
-
return (maybeField !== undefined &&
|
|
42
|
-
(typeof maybeField.safeParse === "function" ||
|
|
43
|
-
"description" in maybeField ||
|
|
44
|
-
"options" in maybeField ||
|
|
45
|
-
"element" in maybeField));
|
|
46
|
-
}
|
|
47
35
|
function isRecord(obj) {
|
|
48
36
|
return typeof obj === "object" && obj !== null;
|
|
49
37
|
}
|
|
50
|
-
function toRecord(obj) {
|
|
51
|
-
if (isRecord(obj)) {
|
|
52
|
-
return obj;
|
|
53
|
-
}
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
38
|
function fieldDescription(field) {
|
|
57
39
|
return field.description ?? "";
|
|
58
40
|
}
|
|
@@ -65,6 +47,12 @@ function isZodLikeSchema(obj) {
|
|
|
65
47
|
const maybeShape = toRecord(obj)?.shape;
|
|
66
48
|
return typeof maybeShape === "object" && maybeShape !== null;
|
|
67
49
|
}
|
|
50
|
+
function toRecord(obj) {
|
|
51
|
+
if (isRecord(obj)) {
|
|
52
|
+
return obj;
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
68
56
|
function getShape(schema) {
|
|
69
57
|
if (isZodLikeSchema(schema)) {
|
|
70
58
|
return schema.shape;
|
|
@@ -72,11 +60,127 @@ function getShape(schema) {
|
|
|
72
60
|
return undefined;
|
|
73
61
|
}
|
|
74
62
|
// ---------------------------------------------------------------------------
|
|
75
|
-
//
|
|
63
|
+
// Helpers
|
|
76
64
|
// ---------------------------------------------------------------------------
|
|
77
65
|
function collect(value, previous) {
|
|
78
66
|
return [...previous, value];
|
|
79
67
|
}
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
// Action handler
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
function actionFailure(message) {
|
|
72
|
+
console.error(message);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
function buildArgsObj(argsSchema, commanderArgs) {
|
|
76
|
+
const argsKeys = argsSchema ? Object.keys(getShape(argsSchema) ?? {}) : [];
|
|
77
|
+
const argsObj = {};
|
|
78
|
+
for (let i = 0; i < argsKeys.length; i++) {
|
|
79
|
+
argsObj[argsKeys[i]] = commanderArgs[i];
|
|
80
|
+
}
|
|
81
|
+
return argsObj;
|
|
82
|
+
}
|
|
83
|
+
function buildOptsObj(argsSchema, commanderArgs) {
|
|
84
|
+
const argsKeys = argsSchema ? Object.keys(getShape(argsSchema) ?? {}) : [];
|
|
85
|
+
const optsObjValue = commanderArgs[argsKeys.length];
|
|
86
|
+
return toRecord(optsObjValue) ?? {};
|
|
87
|
+
}
|
|
88
|
+
function validateAndParse(schema, data, label) {
|
|
89
|
+
const parsed = schema.safeParse(data);
|
|
90
|
+
if (!parsed.success) {
|
|
91
|
+
for (const issue of parsed.error.issues) {
|
|
92
|
+
console.error(`${issue.path.join(".")}: ${issue.message}`);
|
|
93
|
+
}
|
|
94
|
+
actionFailure(`${label} validation failed`);
|
|
95
|
+
}
|
|
96
|
+
return schema.parse(data);
|
|
97
|
+
}
|
|
98
|
+
function runAction(argsSchema, optsSchema, commanderArgs, action) {
|
|
99
|
+
const argsObj = buildArgsObj(argsSchema, commanderArgs);
|
|
100
|
+
const optsObj = buildOptsObj(argsSchema, commanderArgs);
|
|
101
|
+
const argsData = argsSchema
|
|
102
|
+
? validateAndParse(argsSchema, argsObj, "Argument")
|
|
103
|
+
: {};
|
|
104
|
+
const optsData = optsSchema
|
|
105
|
+
? validateAndParse(optsSchema, optsObj, "Option")
|
|
106
|
+
: {};
|
|
107
|
+
try {
|
|
108
|
+
action(argsData, optsData);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
112
|
+
console.error(message);
|
|
113
|
+
actionFailure("Action threw an error");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Argument / option registration helpers
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
function registerArguments(cmd, argsSchema) {
|
|
120
|
+
const shape = getShape(argsSchema);
|
|
121
|
+
if (!shape)
|
|
122
|
+
return;
|
|
123
|
+
for (const key of Object.keys(shape)) {
|
|
124
|
+
const field = shape[key];
|
|
125
|
+
if (!field || !isZodField(field))
|
|
126
|
+
continue;
|
|
127
|
+
const desc = fieldDescription(field);
|
|
128
|
+
const choices = fieldChoices(field);
|
|
129
|
+
const optional = fieldIsOptional(field);
|
|
130
|
+
const flagName = camelToKebab(key);
|
|
131
|
+
if (choices) {
|
|
132
|
+
const arg = new Argument(optional ? `[${flagName}]` : `<${flagName}>`, desc).choices(choices);
|
|
133
|
+
cmd.addArgument(arg);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
cmd.argument(optional ? `[${flagName}]` : `<${flagName}>`, desc);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function registerOption(cmd, flagName, field, desc) {
|
|
141
|
+
const choices = fieldChoices(field);
|
|
142
|
+
const optional = fieldIsOptional(field);
|
|
143
|
+
const isArr = fieldIsArray(field);
|
|
144
|
+
const isBool = fieldIsBoolean(field);
|
|
145
|
+
if (isBool) {
|
|
146
|
+
cmd.addOption(new Option(`--${flagName}`, desc));
|
|
147
|
+
cmd.addOption(new Option(`--no-${flagName}`));
|
|
148
|
+
}
|
|
149
|
+
else if (isArr) {
|
|
150
|
+
const opt = new Option(`--${flagName} <value>`)
|
|
151
|
+
.argParser(collect)
|
|
152
|
+
.default([]);
|
|
153
|
+
if (!optional)
|
|
154
|
+
opt.makeOptionMandatory(true);
|
|
155
|
+
cmd.addOption(opt);
|
|
156
|
+
}
|
|
157
|
+
else if (choices) {
|
|
158
|
+
const opt = new Option(`--${flagName} <value>`).choices(choices);
|
|
159
|
+
if (!optional)
|
|
160
|
+
opt.makeOptionMandatory(true);
|
|
161
|
+
cmd.addOption(opt);
|
|
162
|
+
}
|
|
163
|
+
else if (optional) {
|
|
164
|
+
cmd.addOption(new Option(`--${flagName} <value>`).hideHelp());
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
cmd.addOption(new Option(`--${flagName} <value>`).makeOptionMandatory(true).hideHelp());
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function registerOptions(cmd, optsSchema) {
|
|
171
|
+
const shape = getShape(optsSchema);
|
|
172
|
+
if (!shape)
|
|
173
|
+
return;
|
|
174
|
+
for (const key of Object.keys(shape)) {
|
|
175
|
+
const field = shape[key];
|
|
176
|
+
if (!field || !isZodField(field))
|
|
177
|
+
continue;
|
|
178
|
+
registerOption(cmd, camelToKebab(key), field, fieldDescription(field));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Build Commander from CommandDef
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
80
184
|
/**
|
|
81
185
|
* Build a Commander.js command tree from a declarative CommandDef, wiring up Zod-validated args, options, and actions.
|
|
82
186
|
* @param def - The command definition to build from.
|
|
@@ -92,109 +196,12 @@ function collect(value, previous) {
|
|
|
92
196
|
export function buildCommander(def, parent) {
|
|
93
197
|
const cmd = parent.command(def.name);
|
|
94
198
|
cmd.description(def.description);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (argsShape) {
|
|
98
|
-
for (const key of Object.keys(argsShape)) {
|
|
99
|
-
const field = argsShape[key];
|
|
100
|
-
if (!field || !isZodField(field))
|
|
101
|
-
continue;
|
|
102
|
-
const desc = fieldDescription(field);
|
|
103
|
-
const choices = fieldChoices(field);
|
|
104
|
-
const optional = fieldIsOptional(field);
|
|
105
|
-
const flagName = camelToKebab(key);
|
|
106
|
-
if (choices) {
|
|
107
|
-
const arg = new Argument(optional ? `[${flagName}]` : `<${flagName}>`, desc).choices(choices);
|
|
108
|
-
cmd.addArgument(arg);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
cmd.argument(optional ? `[${flagName}]` : `<${flagName}>`, desc);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
{
|
|
117
|
-
const optsShape = getShape(def.opts);
|
|
118
|
-
if (optsShape) {
|
|
119
|
-
for (const key of Object.keys(optsShape)) {
|
|
120
|
-
const field = optsShape[key];
|
|
121
|
-
if (!field || !isZodField(field))
|
|
122
|
-
continue;
|
|
123
|
-
const desc = fieldDescription(field);
|
|
124
|
-
const choices = fieldChoices(field);
|
|
125
|
-
const flagName = camelToKebab(key);
|
|
126
|
-
const optional = fieldIsOptional(field);
|
|
127
|
-
const isArr = fieldIsArray(field);
|
|
128
|
-
const isBool = fieldIsBoolean(field);
|
|
129
|
-
if (isBool) {
|
|
130
|
-
cmd.option(`--${flagName}`, desc);
|
|
131
|
-
}
|
|
132
|
-
else if (isArr) {
|
|
133
|
-
if (optional) {
|
|
134
|
-
cmd.option(`--${flagName} <value>`, desc, collect, []);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
cmd.requiredOption(`--${flagName} <value>`, desc, collect, []);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
else if (choices) {
|
|
141
|
-
const opt = new Option(`--${flagName} <value>`, desc).choices(choices);
|
|
142
|
-
if (!optional)
|
|
143
|
-
opt.makeOptionMandatory();
|
|
144
|
-
cmd.addOption(opt);
|
|
145
|
-
}
|
|
146
|
-
else if (optional) {
|
|
147
|
-
cmd.option(`--${flagName} <value>`, desc);
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
cmd.requiredOption(`--${flagName} <value>`, desc);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
199
|
+
registerArguments(cmd, def.args);
|
|
200
|
+
registerOptions(cmd, def.opts);
|
|
155
201
|
if (def.action) {
|
|
156
202
|
const action = def.action;
|
|
157
|
-
const argsSchema = def.args;
|
|
158
|
-
const optsSchema = def.opts;
|
|
159
203
|
cmd.action((...commanderArgs) => {
|
|
160
|
-
|
|
161
|
-
const argsShape = getShape(argsSchema);
|
|
162
|
-
if (argsShape) {
|
|
163
|
-
argsKeys = Object.keys(argsShape);
|
|
164
|
-
}
|
|
165
|
-
const argsObj = {};
|
|
166
|
-
for (let i = 0; i < argsKeys.length; i++) {
|
|
167
|
-
argsObj[argsKeys[i]] = commanderArgs[i];
|
|
168
|
-
}
|
|
169
|
-
const optsObjValue = commanderArgs[argsKeys.length];
|
|
170
|
-
const optsObj = toRecord(optsObjValue) ?? {};
|
|
171
|
-
const parsedArgs = argsSchema
|
|
172
|
-
? argsSchema.safeParse(argsObj)
|
|
173
|
-
: { data: {} };
|
|
174
|
-
const parsedOpts = optsSchema
|
|
175
|
-
? optsSchema.safeParse(optsObj)
|
|
176
|
-
: { data: {} };
|
|
177
|
-
if ("success" in parsedArgs && !parsedArgs.success) {
|
|
178
|
-
for (const issue of parsedArgs.error.issues) {
|
|
179
|
-
console.error(`${issue.path.join(".")}: ${issue.message}`);
|
|
180
|
-
}
|
|
181
|
-
process.exit(1);
|
|
182
|
-
}
|
|
183
|
-
if ("success" in parsedOpts && !parsedOpts.success) {
|
|
184
|
-
for (const issue of parsedOpts.error.issues) {
|
|
185
|
-
console.error(`${issue.path.join(".")}: ${issue.message}`);
|
|
186
|
-
}
|
|
187
|
-
process.exit(1);
|
|
188
|
-
}
|
|
189
|
-
try {
|
|
190
|
-
const argsData = "data" in parsedArgs ? parsedArgs.data : {};
|
|
191
|
-
const optsData = "data" in parsedOpts ? parsedOpts.data : {};
|
|
192
|
-
action(argsData, optsData);
|
|
193
|
-
}
|
|
194
|
-
catch (err) {
|
|
195
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
196
|
-
process.exit(1);
|
|
197
|
-
}
|
|
204
|
+
runAction(def.args, def.opts, commanderArgs, action);
|
|
198
205
|
});
|
|
199
206
|
}
|
|
200
207
|
if (def.subcommands) {
|
|
@@ -204,6 +211,54 @@ export function buildCommander(def, parent) {
|
|
|
204
211
|
}
|
|
205
212
|
return cmd;
|
|
206
213
|
}
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
// Documentation extraction
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
function buildArgDocs(shape) {
|
|
218
|
+
const docs = [];
|
|
219
|
+
if (!shape)
|
|
220
|
+
return docs;
|
|
221
|
+
for (const key of Object.keys(shape)) {
|
|
222
|
+
const field = shape[key];
|
|
223
|
+
if (!field || !isZodField(field))
|
|
224
|
+
continue;
|
|
225
|
+
docs.push({
|
|
226
|
+
name: camelToKebab(key),
|
|
227
|
+
description: fieldDescription(field),
|
|
228
|
+
required: !fieldIsOptional(field),
|
|
229
|
+
choices: fieldChoices(field),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return docs;
|
|
233
|
+
}
|
|
234
|
+
function buildOptDocs(shape) {
|
|
235
|
+
const docs = [];
|
|
236
|
+
if (!shape)
|
|
237
|
+
return docs;
|
|
238
|
+
for (const key of Object.keys(shape)) {
|
|
239
|
+
const field = shape[key];
|
|
240
|
+
if (!field || !isZodField(field))
|
|
241
|
+
continue;
|
|
242
|
+
docs.push({
|
|
243
|
+
flag: `--${camelToKebab(key)}`,
|
|
244
|
+
description: fieldDescription(field),
|
|
245
|
+
required: !fieldIsOptional(field),
|
|
246
|
+
repeatable: fieldIsArray(field),
|
|
247
|
+
choices: fieldChoices(field),
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
return docs;
|
|
251
|
+
}
|
|
252
|
+
function isZodField(obj) {
|
|
253
|
+
if (typeof obj !== "object" || obj === null)
|
|
254
|
+
return false;
|
|
255
|
+
const maybeField = toRecord(obj);
|
|
256
|
+
return (maybeField !== undefined &&
|
|
257
|
+
(typeof maybeField.safeParse === "function" ||
|
|
258
|
+
"description" in maybeField ||
|
|
259
|
+
"options" in maybeField ||
|
|
260
|
+
"element" in maybeField));
|
|
261
|
+
}
|
|
207
262
|
/**
|
|
208
263
|
* Extract structured documentation from a CommandDef by introspecting its Zod schemas for args and options.
|
|
209
264
|
* @param def - The command definition to extract docs from.
|
|
@@ -215,46 +270,11 @@ export function buildCommander(def, parent) {
|
|
|
215
270
|
* ```
|
|
216
271
|
*/
|
|
217
272
|
export function extractDocs(def) {
|
|
218
|
-
const args = [];
|
|
219
|
-
{
|
|
220
|
-
const argsShape = getShape(def.args);
|
|
221
|
-
if (argsShape) {
|
|
222
|
-
for (const key of Object.keys(argsShape)) {
|
|
223
|
-
const field = argsShape[key];
|
|
224
|
-
if (!field || !isZodField(field))
|
|
225
|
-
continue;
|
|
226
|
-
args.push({
|
|
227
|
-
name: camelToKebab(key),
|
|
228
|
-
description: fieldDescription(field),
|
|
229
|
-
required: !fieldIsOptional(field),
|
|
230
|
-
choices: fieldChoices(field),
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
const opts = [];
|
|
236
|
-
{
|
|
237
|
-
const optsShape = getShape(def.opts);
|
|
238
|
-
if (optsShape) {
|
|
239
|
-
for (const key of Object.keys(optsShape)) {
|
|
240
|
-
const field = optsShape[key];
|
|
241
|
-
if (!field || !isZodField(field))
|
|
242
|
-
continue;
|
|
243
|
-
opts.push({
|
|
244
|
-
flag: `--${camelToKebab(key)}`,
|
|
245
|
-
description: fieldDescription(field),
|
|
246
|
-
required: !fieldIsOptional(field),
|
|
247
|
-
repeatable: fieldIsArray(field),
|
|
248
|
-
choices: fieldChoices(field),
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
273
|
return {
|
|
254
274
|
name: def.name,
|
|
255
275
|
description: def.description,
|
|
256
|
-
args,
|
|
257
|
-
opts,
|
|
276
|
+
args: buildArgDocs(getShape(def.args)),
|
|
277
|
+
opts: buildOptDocs(getShape(def.opts)),
|
|
258
278
|
subcommands: def.subcommands?.map(extractDocs),
|
|
259
279
|
apiLink: def.apiLink,
|
|
260
280
|
};
|
|
@@ -29,8 +29,8 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
29
29
|
},
|
|
30
30
|
// Realises — implementation hierarchy
|
|
31
31
|
realises: {
|
|
32
|
-
from: ["capability", "element", "realisation"],
|
|
33
|
-
to: ["capability", "element", "realisation"],
|
|
32
|
+
from: ["capability", "element", "realisation", "artefact", "mode"],
|
|
33
|
+
to: ["capability", "element", "realisation", "concept", "stage"],
|
|
34
34
|
},
|
|
35
35
|
// Implements — operationalisation
|
|
36
36
|
implements: {
|
|
@@ -161,7 +161,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
161
161
|
// Performs — process enactment
|
|
162
162
|
performs: {
|
|
163
163
|
from: ["stage", "role"],
|
|
164
|
-
to: ["capability", "artefact", "artefact_flow"],
|
|
164
|
+
to: ["capability", "artefact", "artefact_flow", "stage"],
|
|
165
165
|
},
|
|
166
166
|
// Precedes — temporal ordering
|
|
167
167
|
precedes: {
|
|
@@ -227,6 +227,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
227
227
|
"gate",
|
|
228
228
|
"change",
|
|
229
229
|
"policy",
|
|
230
|
+
"artefact",
|
|
230
231
|
],
|
|
231
232
|
to: ["policy", "protocol", "role", "principle", "invariant", "concept"],
|
|
232
233
|
},
|
|
@@ -269,16 +270,17 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
269
270
|
"stage",
|
|
270
271
|
"decision",
|
|
271
272
|
"change",
|
|
273
|
+
"invariant",
|
|
272
274
|
],
|
|
273
275
|
},
|
|
274
276
|
// Produces — generation
|
|
275
277
|
produces: {
|
|
276
|
-
from: ["stage", "artefact_flow", "realisation"],
|
|
277
|
-
to: ["artefact"],
|
|
278
|
+
from: ["stage", "artefact_flow", "realisation", "concept"],
|
|
279
|
+
to: ["artefact", "concept"],
|
|
278
280
|
},
|
|
279
281
|
// Consumes — usage
|
|
280
282
|
consumes: {
|
|
281
|
-
from: ["stage", "artefact_flow", "realisation"],
|
|
283
|
+
from: ["stage", "artefact_flow", "realisation", "role"],
|
|
282
284
|
to: ["artefact"],
|
|
283
285
|
},
|
|
284
286
|
// Selects — choice and instantiation
|
|
@@ -309,6 +311,11 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
|
|
|
309
311
|
"stage",
|
|
310
312
|
],
|
|
311
313
|
},
|
|
314
|
+
// Justifies — design rationale grounding (principle/decision → invariant/decision/principle/concept)
|
|
315
|
+
justifies: {
|
|
316
|
+
from: ["principle", "decision"],
|
|
317
|
+
to: ["invariant", "decision", "principle", "concept"],
|
|
318
|
+
},
|
|
312
319
|
};
|
|
313
320
|
/**
|
|
314
321
|
* Check if a relationship type is valid for the given endpoint node types.
|
package/dist/src/json-to-md.d.ts
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { type SysProMDocument } from "./schema.js";
|
|
2
|
+
type DiagramLayout = "LR" | "TD" | "RL" | "BT";
|
|
2
3
|
/** Options for controlling JSON-to-Markdown conversion. */
|
|
3
4
|
export interface ConvertOptions {
|
|
4
5
|
form: "single-file" | "multi-doc";
|
|
6
|
+
embedDiagrams?: boolean;
|
|
7
|
+
labelMode?: "friendly" | "compact";
|
|
8
|
+
relationshipLayout?: DiagramLayout;
|
|
9
|
+
refinementLayout?: DiagramLayout;
|
|
10
|
+
decisionLayout?: DiagramLayout;
|
|
11
|
+
dependencyLayout?: DiagramLayout;
|
|
12
|
+
}
|
|
13
|
+
interface MarkdownRenderOptions {
|
|
14
|
+
embedDiagrams?: boolean;
|
|
15
|
+
labelMode?: "friendly" | "compact";
|
|
16
|
+
relationshipLayout?: DiagramLayout;
|
|
17
|
+
refinementLayout?: DiagramLayout;
|
|
18
|
+
decisionLayout?: DiagramLayout;
|
|
19
|
+
dependencyLayout?: DiagramLayout;
|
|
5
20
|
}
|
|
6
21
|
/**
|
|
7
22
|
* Convert a SysProM document to a single Markdown string.
|
|
8
23
|
* @param doc - The SysProM document to convert.
|
|
24
|
+
* @param options
|
|
25
|
+
* @param options.embedDiagrams
|
|
26
|
+
* @param options.labelMode
|
|
27
|
+
* @param options.relationshipLayout
|
|
28
|
+
* @param options.refinementLayout
|
|
29
|
+
* @param options.decisionLayout
|
|
30
|
+
* @param options.dependencyLayout
|
|
9
31
|
* @returns The Markdown representation.
|
|
10
32
|
* @example
|
|
11
33
|
* ```ts
|
|
@@ -13,17 +35,24 @@ export interface ConvertOptions {
|
|
|
13
35
|
* writeFileSync("output.spm.md", md);
|
|
14
36
|
* ```
|
|
15
37
|
*/
|
|
16
|
-
export declare function jsonToMarkdownSingle(doc: SysProMDocument): string;
|
|
38
|
+
export declare function jsonToMarkdownSingle(doc: SysProMDocument, options?: MarkdownRenderOptions): string;
|
|
17
39
|
/**
|
|
18
40
|
* Convert a SysProM document to a multi-document Markdown folder.
|
|
19
41
|
* @param doc - The SysProM document to convert.
|
|
20
42
|
* @param outDir - Output directory path.
|
|
43
|
+
* @param options
|
|
44
|
+
* @param options.embedDiagrams
|
|
45
|
+
* @param options.labelMode
|
|
46
|
+
* @param options.relationshipLayout
|
|
47
|
+
* @param options.refinementLayout
|
|
48
|
+
* @param options.decisionLayout
|
|
49
|
+
* @param options.dependencyLayout
|
|
21
50
|
* @example
|
|
22
51
|
* ```ts
|
|
23
52
|
* jsonToMarkdownMultiDoc(doc, "./SysProM");
|
|
24
53
|
* ```
|
|
25
54
|
*/
|
|
26
|
-
export declare function jsonToMarkdownMultiDoc(doc: SysProMDocument, outDir: string): void;
|
|
55
|
+
export declare function jsonToMarkdownMultiDoc(doc: SysProMDocument, outDir: string, options?: MarkdownRenderOptions): void;
|
|
27
56
|
/**
|
|
28
57
|
* Convert a SysProM document to Markdown, writing to the specified output path.
|
|
29
58
|
* @param doc - The SysProM document to convert.
|
|
@@ -35,3 +64,4 @@ export declare function jsonToMarkdownMultiDoc(doc: SysProMDocument, outDir: str
|
|
|
35
64
|
* ```
|
|
36
65
|
*/
|
|
37
66
|
export declare function jsonToMarkdown(doc: SysProMDocument, output: string, options: ConvertOptions): void;
|
|
67
|
+
export {};
|