sysprom 1.23.1 → 1.25.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.
|
@@ -51,10 +51,15 @@ const updateNodeArgs = z.object({
|
|
|
51
51
|
id: z.string().describe("node ID to update"),
|
|
52
52
|
});
|
|
53
53
|
const updateNodeOpts = mutationOpts.extend({
|
|
54
|
+
name: z.string().optional().describe("update node name"),
|
|
54
55
|
description: z.string().optional().describe("update node description"),
|
|
55
56
|
status: NodeStatus.optional().describe("set lifecycle state to true"),
|
|
56
57
|
context: z.string().optional().describe("update node context"),
|
|
57
58
|
rationale: z.string().optional().describe("update node rationale"),
|
|
59
|
+
selected: z
|
|
60
|
+
.string()
|
|
61
|
+
.optional()
|
|
62
|
+
.describe("set selected option on decision nodes"),
|
|
58
63
|
lifecycle: z
|
|
59
64
|
.array(z.string())
|
|
60
65
|
.optional()
|
|
@@ -95,12 +100,16 @@ const nodeSubcommand = {
|
|
|
95
100
|
process.exit(1);
|
|
96
101
|
}
|
|
97
102
|
const fields = {};
|
|
103
|
+
if (opts.name !== undefined)
|
|
104
|
+
fields.name = opts.name;
|
|
98
105
|
if (opts.description !== undefined)
|
|
99
106
|
fields.description = opts.description;
|
|
100
107
|
if (opts.context !== undefined)
|
|
101
108
|
fields.context = opts.context;
|
|
102
109
|
if (opts.rationale !== undefined)
|
|
103
110
|
fields.rationale = opts.rationale;
|
|
111
|
+
if (opts.selected !== undefined)
|
|
112
|
+
fields.selected = opts.selected;
|
|
104
113
|
const lifecycleArgs = [...(opts.lifecycle ?? [])];
|
|
105
114
|
if (opts.status !== undefined) {
|
|
106
115
|
lifecycleArgs.push(`${opts.status}=true`);
|
|
@@ -111,7 +120,7 @@ const nodeSubcommand = {
|
|
|
111
120
|
}
|
|
112
121
|
if (Object.keys(fields).length === 0) {
|
|
113
122
|
console.error("No fields specified to update.");
|
|
114
|
-
console.error("Use --description, --status, --context, --rationale, or --lifecycle.");
|
|
123
|
+
console.error("Use --name, --description, --status, --context, --rationale, --selected, or --lifecycle.");
|
|
115
124
|
process.exit(1);
|
|
116
125
|
}
|
|
117
126
|
const newDoc = updateNodeOp({ doc, id: args.id, fields });
|
|
@@ -160,11 +160,11 @@ function registerOption(cmd, flagName, field, desc) {
|
|
|
160
160
|
opt.makeOptionMandatory(true);
|
|
161
161
|
cmd.addOption(opt);
|
|
162
162
|
}
|
|
163
|
-
else if (optional) {
|
|
164
|
-
cmd.addOption(new Option(`--${flagName} <value>`).hideHelp());
|
|
165
|
-
}
|
|
166
163
|
else {
|
|
167
|
-
|
|
164
|
+
const opt = new Option(`--${flagName} <value>`, desc);
|
|
165
|
+
if (!optional)
|
|
166
|
+
opt.makeOptionMandatory(true);
|
|
167
|
+
cmd.addOption(opt);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
function registerOptions(cmd, optsSchema) {
|
package/dist/src/cli/program.js
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname, resolve } from "node:path";
|
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { buildCommander } from "./define-command.js";
|
|
6
|
+
import { formatCliError } from "./shared.js";
|
|
6
7
|
let cachedVersion;
|
|
7
8
|
function getVersion() {
|
|
8
9
|
if (cachedVersion === undefined) {
|
|
@@ -81,3 +82,13 @@ program
|
|
|
81
82
|
.action(async () => {
|
|
82
83
|
await import("../mcp/server.js");
|
|
83
84
|
});
|
|
85
|
+
// Global error handlers for uncaught exceptions
|
|
86
|
+
process.on("uncaughtException", (error) => {
|
|
87
|
+
console.error(formatCliError(error, false));
|
|
88
|
+
process.exit(1);
|
|
89
|
+
});
|
|
90
|
+
process.on("unhandledRejection", (reason) => {
|
|
91
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
92
|
+
console.error(formatCliError(error, false));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
});
|
package/dist/src/cli/shared.d.ts
CHANGED
|
@@ -72,3 +72,18 @@ export declare function loadDoc(input?: string): LoadedDoc;
|
|
|
72
72
|
* ```
|
|
73
73
|
*/
|
|
74
74
|
export declare function persistDoc(doc: SysProMDocument, loaded: LoadedDoc, opts: MutationOpts): void;
|
|
75
|
+
/**
|
|
76
|
+
* Format an error message for CLI output with issue filing guidance.
|
|
77
|
+
* If the error appears to be unexpected (not a user error), suggests filing an issue.
|
|
78
|
+
* @param error - The error to format
|
|
79
|
+
* @param isUserError - Whether this is a user error (e.g. invalid input); if false, suggests filing an issue
|
|
80
|
+
* @returns Formatted error message
|
|
81
|
+
* @example
|
|
82
|
+
* ```ts
|
|
83
|
+
* try { ... } catch (err: unknown) {
|
|
84
|
+
* console.error(formatCliError(err, false)); // Not a user error - suggest issue
|
|
85
|
+
* process.exit(1);
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function formatCliError(error: unknown, isUserError?: boolean): string;
|
package/dist/src/cli/shared.js
CHANGED
|
@@ -207,3 +207,28 @@ export function persistDoc(doc, loaded, opts) {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Error formatting and reporting
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
const ISSUE_URL = "https://github.com/ExaDev/SysProM/issues/new";
|
|
214
|
+
/**
|
|
215
|
+
* Format an error message for CLI output with issue filing guidance.
|
|
216
|
+
* If the error appears to be unexpected (not a user error), suggests filing an issue.
|
|
217
|
+
* @param error - The error to format
|
|
218
|
+
* @param isUserError - Whether this is a user error (e.g. invalid input); if false, suggests filing an issue
|
|
219
|
+
* @returns Formatted error message
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* try { ... } catch (err: unknown) {
|
|
223
|
+
* console.error(formatCliError(err, false)); // Not a user error - suggest issue
|
|
224
|
+
* process.exit(1);
|
|
225
|
+
* }
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export function formatCliError(error, isUserError = false) {
|
|
229
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
230
|
+
if (isUserError) {
|
|
231
|
+
return message;
|
|
232
|
+
}
|
|
233
|
+
return `${message}\n\nIf this was unexpected or bad UX, please file an issue:\n${ISSUE_URL}`;
|
|
234
|
+
}
|
package/dist/src/mcp/server.js
CHANGED
|
@@ -7,19 +7,27 @@ import { NodeType, RelationshipType } from "../schema.js";
|
|
|
7
7
|
import { validateOp, statsOp, queryNodesOp, queryNodeOp, queryRelationshipsOp, traceFromNodeOp, addNodeOp, removeNodeOp, updateNodeOp, addRelationshipOp, removeRelationshipOp, nextIdOp, inferCompletenessOp, inferLifecycleOp, inferImpactOp, impactSummaryOp, inferDerivedOp, } from "../operations/index.js";
|
|
8
8
|
/**
|
|
9
9
|
* Wrap an error with a descriptive prefix and attach the original as cause.
|
|
10
|
+
* Adds issue filing guidance for unexpected errors.
|
|
10
11
|
* @param prefix - The error prefix (e.g., "Failed to add node")
|
|
11
12
|
* @param error - The caught error
|
|
13
|
+
* @param isUserError - Whether this is a user error; if false, suggests filing an issue
|
|
12
14
|
* @example
|
|
13
15
|
* ```ts
|
|
14
16
|
* try {
|
|
15
17
|
* someOperation();
|
|
16
18
|
* } catch (error) {
|
|
17
|
-
* wrapError("Failed to do X", error);
|
|
19
|
+
* wrapError("Failed to do X", error, false); // Not a user error - suggest issue
|
|
18
20
|
* }
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
|
-
function wrapError(prefix, error) {
|
|
22
|
-
|
|
23
|
+
function wrapError(prefix, error, isUserError = false) {
|
|
24
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
25
|
+
const fullMessage = `${prefix}: ${message}`;
|
|
26
|
+
const issueUrl = "https://github.com/ExaDev/SysProM/issues/new";
|
|
27
|
+
const errorMsg = isUserError
|
|
28
|
+
? fullMessage
|
|
29
|
+
: `${fullMessage}\n\nIf this was unexpected or bad UX, please file an issue: ${issueUrl}`;
|
|
30
|
+
throw new Error(errorMsg, { cause: error });
|
|
23
31
|
}
|
|
24
32
|
// Create MCP server instance
|
|
25
33
|
const server = new McpServer({
|