@defai.digital/cli 13.4.7 → 13.4.9
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/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +20 -135
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/call.d.ts.map +1 -1
- package/dist/commands/call.js +12 -0
- package/dist/commands/call.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +7 -14
- package/dist/commands/setup.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +34 -10
- package/dist/parser.js.map +1 -1
- package/dist/shared-cli-registry.d.ts +32 -0
- package/dist/shared-cli-registry.d.ts.map +1 -0
- package/dist/shared-cli-registry.js +167 -0
- package/dist/shared-cli-registry.js.map +1 -0
- package/dist/web/api.d.ts +10 -0
- package/dist/web/api.d.ts.map +1 -1
- package/dist/web/api.js +48 -44
- package/dist/web/api.js.map +1 -1
- package/dist/web/dashboard.d.ts.map +1 -1
- package/dist/web/dashboard.js +12 -3
- package/dist/web/dashboard.js.map +1 -1
- package/package.json +21 -21
package/dist/parser.js
CHANGED
|
@@ -5,6 +5,25 @@ const MS_PER_SECOND = 1000;
|
|
|
5
5
|
const MS_PER_MINUTE = SECONDS_PER_MINUTE * MS_PER_SECOND;
|
|
6
6
|
/** Milliseconds per hour */
|
|
7
7
|
const MS_PER_HOUR = SECONDS_PER_HOUR * MS_PER_SECOND;
|
|
8
|
+
/** Valid format options */
|
|
9
|
+
const VALID_FORMATS = ['json', 'text'];
|
|
10
|
+
/**
|
|
11
|
+
* Parse a positive integer from a string with strict validation.
|
|
12
|
+
* Returns undefined if the string is not a valid positive integer.
|
|
13
|
+
*
|
|
14
|
+
* @param value - The string value to parse
|
|
15
|
+
* @param optionName - The option name for warning messages
|
|
16
|
+
* @returns The parsed positive integer, or undefined if invalid
|
|
17
|
+
*/
|
|
18
|
+
function parsePositiveInt(value, optionName) {
|
|
19
|
+
// Use Number() for strict parsing (unlike parseInt which accepts "10abc" as 10)
|
|
20
|
+
const num = Number(value);
|
|
21
|
+
if (Number.isInteger(num) && num > 0) {
|
|
22
|
+
return num;
|
|
23
|
+
}
|
|
24
|
+
console.warn(`Warning: Invalid value "${value}" for --${optionName}. Must be a positive integer.`);
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
8
27
|
/**
|
|
9
28
|
* Default CLI options
|
|
10
29
|
*/
|
|
@@ -115,8 +134,13 @@ export function parseArgs(argv) {
|
|
|
115
134
|
options.verbose = true;
|
|
116
135
|
break;
|
|
117
136
|
case 'format':
|
|
118
|
-
if (nextArg
|
|
119
|
-
|
|
137
|
+
if (nextArg !== undefined && !nextArg.startsWith('-')) {
|
|
138
|
+
if (nextArg === 'json' || nextArg === 'text') {
|
|
139
|
+
options.format = nextArg;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.warn(`Warning: Invalid format "${nextArg}". Valid formats: ${VALID_FORMATS.join(', ')}. Using default "text".`);
|
|
143
|
+
}
|
|
120
144
|
i++;
|
|
121
145
|
}
|
|
122
146
|
break;
|
|
@@ -140,8 +164,8 @@ export function parseArgs(argv) {
|
|
|
140
164
|
break;
|
|
141
165
|
case 'limit':
|
|
142
166
|
if (nextArg !== undefined && !nextArg.startsWith('-')) {
|
|
143
|
-
const num =
|
|
144
|
-
if (
|
|
167
|
+
const num = parsePositiveInt(nextArg, 'limit');
|
|
168
|
+
if (num !== undefined) {
|
|
145
169
|
options.limit = num;
|
|
146
170
|
}
|
|
147
171
|
i++;
|
|
@@ -159,8 +183,8 @@ export function parseArgs(argv) {
|
|
|
159
183
|
break;
|
|
160
184
|
case 'max-iterations':
|
|
161
185
|
if (nextArg !== undefined && !nextArg.startsWith('-')) {
|
|
162
|
-
const num =
|
|
163
|
-
if (
|
|
186
|
+
const num = parsePositiveInt(nextArg, 'max-iterations');
|
|
187
|
+
if (num !== undefined) {
|
|
164
188
|
options.maxIterations = num;
|
|
165
189
|
}
|
|
166
190
|
i++;
|
|
@@ -208,8 +232,8 @@ export function parseArgs(argv) {
|
|
|
208
232
|
break;
|
|
209
233
|
case 'max-tokens':
|
|
210
234
|
if (nextArg !== undefined && !nextArg.startsWith('-')) {
|
|
211
|
-
const num =
|
|
212
|
-
if (
|
|
235
|
+
const num = parsePositiveInt(nextArg, 'max-tokens');
|
|
236
|
+
if (num !== undefined) {
|
|
213
237
|
options.maxTokens = num;
|
|
214
238
|
}
|
|
215
239
|
i++;
|
|
@@ -235,8 +259,8 @@ export function parseArgs(argv) {
|
|
|
235
259
|
break;
|
|
236
260
|
case 'refresh':
|
|
237
261
|
if (nextArg !== undefined && !nextArg.startsWith('-')) {
|
|
238
|
-
const num =
|
|
239
|
-
if (
|
|
262
|
+
const num = parsePositiveInt(nextArg, 'refresh');
|
|
263
|
+
if (num !== undefined) {
|
|
240
264
|
options.refresh = num;
|
|
241
265
|
}
|
|
242
266
|
i++;
|
package/dist/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAElC,8BAA8B;AAC9B,MAAM,aAAa,GAAG,IAAI,CAAC;AAE3B,8BAA8B;AAC9B,MAAM,aAAa,GAAG,kBAAkB,GAAG,aAAa,CAAC;AAEzD,4BAA4B;AAC5B,MAAM,WAAW,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAErD,2BAA2B;AAC3B,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;AAEhD;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,KAAa,EAAE,UAAkB;IACzD,gFAAgF;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,2BAA2B,KAAK,WAAW,UAAU,+BAA+B,CAAC,CAAC;IACnG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,eAAe,GAAe;IAClC,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE,SAAS;IACrB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,SAAS;IAChB,wBAAwB;IACxB,OAAO,EAAE,KAAK;IACd,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,KAAK;IAChB,2BAA2B;IAC3B,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,SAAS;IACpB,0BAA0B;IAC1B,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,KAAK;IACd,wBAAwB;IACxB,IAAI,EAAE,SAAS;IACf,oBAAoB;IACpB,QAAQ,EAAE,SAAS;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;IACR,cAAc;IACd,aAAa;IACb,UAAU;IACV,OAAO;IACP,OAAO;IACP,uBAAuB;IACvB,SAAS;IACT,gBAAgB;IAChB,UAAU;IACV,YAAY;IACZ,0BAA0B;IAC1B,UAAU;IACV,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,YAAY;IACZ,yBAAyB;IACzB,SAAS;IACT,SAAS;IACT,uBAAuB;IACvB,MAAM;IACN,mBAAmB;IACnB,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,4BAA4B;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAe,EAAE,GAAG,eAAe,EAAE,CAAC;IACnD,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,MAAM,WAAW,GAAa,EAAE,CAAC,CAAC,kCAAkC;IACpE,IAAI,OAAO,GAAG,MAAM,CAAC;IAErB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAE5B,mCAAmC;YACnC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,0DAA0D;gBAC1D,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtB,2EAA2E;gBAC3E,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACtD,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC1B,CAAC,EAAE,CAAC,CAAC,mCAAmC;gBAC1C,CAAC;gBACD,CAAC,EAAE,CAAC;gBACJ,SAAS;YACX,CAAC;YAED,QAAQ,GAAG,EAAE,CAAC;gBACZ,KAAK,MAAM;oBACT,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBACpB,MAAM;gBACR,KAAK,SAAS;oBACZ,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,MAAM;gBACR,KAAK,SAAS;oBACZ,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,MAAM;gBACR,KAAK,QAAQ;oBACX,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;4BAC7C,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC;wBAC3B,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,IAAI,CAAC,4BAA4B,OAAO,qBAAqB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;wBAC1H,CAAC;wBACD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,cAAc;oBACjB,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,WAAW,GAAG,OAAO,CAAC;wBAC9B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,aAAa;oBAChB,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;wBAC7B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,UAAU;oBACb,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;wBAC1B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;wBAC/C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;4BACtB,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC;wBACtB,CAAC;wBACD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC;wBACxB,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,uBAAuB;gBACvB,KAAK,SAAS;oBACZ,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,MAAM;gBACR,KAAK,gBAAgB;oBACnB,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;wBACxD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;4BACtB,OAAO,CAAC,aAAa,GAAG,GAAG,CAAC;wBAC9B,CAAC;wBACD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,UAAU;oBACb,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;wBAC1B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,YAAY;oBACf,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;oBACzB,MAAM;gBACR,0BAA0B;gBAC1B,KAAK,UAAU;oBACb,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC;wBAC3B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,MAAM;oBACT,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;wBACvD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,OAAO;oBACV,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC;wBACxB,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,MAAM;oBACT,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;wBACvB,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,MAAM;oBACT,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;wBACvB,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,KAAK,YAAY;oBACf,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;wBACpD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;4BACtB,OAAO,CAAC,SAAS,GAAG,GAAG,CAAC;wBAC1B,CAAC;wBACD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,uBAAuB;gBACvB,KAAK,MAAM;oBACT,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;wBACvB,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,mBAAmB;gBACnB,KAAK,UAAU;oBACb,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC;wBAC3B,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;gBACR,yBAAyB;gBACzB,KAAK,SAAS;oBACZ,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBACvB,MAAM;gBACR,KAAK,SAAS;oBACZ,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtD,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;wBACjD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;4BACtB,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;wBACxB,CAAC;wBACD,CAAC,EAAE,CAAC;oBACN,CAAC;oBACD,MAAM;YACV,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,wCAAwC;YACxC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC3B,IAAI,SAAS,GAAG,IAAI,CAAC;YACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,SAAS,GAAG,KAAK,CAAC;oBAClB,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,oDAAoD;gBACpD,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,6BAA6B;gBAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,QAAQ,IAAI,EAAE,CAAC;wBACb,KAAK,GAAG;4BACN,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BACpB,MAAM;wBACR,KAAK,GAAG;4BACN,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;4BACvB,MAAM;wBACR,KAAK,GAAG;4BACN,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;4BACvB,MAAM;oBACV,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAED,CAAC,EAAE,CAAC;IACN,CAAC;IAED,sCAAsC;IACtC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IACxC,CAAC;IAED,0CAA0C;IAC1C,IAAI,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,GAAG,SAAS,CAAC;IACtB,CAAC;IAED,OAAO;QACL,OAAO;QACP,IAAI,EAAE,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC;QAClD,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAa,EACb,MAAuB;IAEvB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;aACxB,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;aACjD,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,kCAAkC,CACnE,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,GAAG;YACN,OAAO,KAAK,GAAG,aAAa,CAAC;QAC/B,KAAK,GAAG;YACN,OAAO,KAAK,GAAG,aAAa,CAAC;QAC/B,KAAK,GAAG;YACN,OAAO,KAAK,GAAG,WAAW,CAAC;QAC7B;YACE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI Agent Registry
|
|
3
|
+
*
|
|
4
|
+
* Provides a singleton agent registry shared across all CLI components.
|
|
5
|
+
* This prevents the "Agent already exists" errors that occur when multiple
|
|
6
|
+
* registry instances try to load the same agents from disk.
|
|
7
|
+
*
|
|
8
|
+
* INV-CLI-REG-001: Single registry instance per CLI process
|
|
9
|
+
* INV-CLI-REG-002: Example agents loaded exactly once
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/defai-digital/AutomatosX/issues/46
|
|
12
|
+
*/
|
|
13
|
+
import { type AgentRegistry } from '@defai.digital/agent-domain';
|
|
14
|
+
/**
|
|
15
|
+
* Get path to global agent storage file
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGlobalAgentStoragePath(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Get the shared CLI agent registry
|
|
20
|
+
*
|
|
21
|
+
* Returns the same registry instance across all CLI components.
|
|
22
|
+
* Loads example agents on first access.
|
|
23
|
+
*
|
|
24
|
+
* INV-CLI-REG-001: Uses atomic promise assignment to prevent race conditions
|
|
25
|
+
*/
|
|
26
|
+
export declare function getCLIAgentRegistry(): Promise<AgentRegistry>;
|
|
27
|
+
/**
|
|
28
|
+
* Reset the shared registry (for testing purposes only)
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare function _resetCLIRegistry(): void;
|
|
32
|
+
//# sourceMappingURL=shared-cli-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-cli-registry.d.ts","sourceRoot":"","sources":["../src/shared-cli-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAUrC;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAoHD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,aAAa,CAAC,CAgBlE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI Agent Registry
|
|
3
|
+
*
|
|
4
|
+
* Provides a singleton agent registry shared across all CLI components.
|
|
5
|
+
* This prevents the "Agent already exists" errors that occur when multiple
|
|
6
|
+
* registry instances try to load the same agents from disk.
|
|
7
|
+
*
|
|
8
|
+
* INV-CLI-REG-001: Single registry instance per CLI process
|
|
9
|
+
* INV-CLI-REG-002: Example agents loaded exactly once
|
|
10
|
+
*
|
|
11
|
+
* @see https://github.com/defai-digital/AutomatosX/issues/46
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from 'node:fs';
|
|
14
|
+
import * as os from 'node:os';
|
|
15
|
+
import * as path from 'node:path';
|
|
16
|
+
import { fileURLToPath } from 'node:url';
|
|
17
|
+
import { createPersistentAgentRegistry, createAgentLoader, } from '@defai.digital/agent-domain';
|
|
18
|
+
import { DATA_DIR_NAME, AGENTS_FILENAME, getErrorMessage } from '@defai.digital/contracts';
|
|
19
|
+
// Get the directory of this module for finding bundled examples
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = path.dirname(__filename);
|
|
22
|
+
// Storage path for persistent agents (uses home directory - matches MCP server)
|
|
23
|
+
const AGENT_STORAGE_PATH = path.join(os.homedir(), DATA_DIR_NAME, AGENTS_FILENAME);
|
|
24
|
+
/**
|
|
25
|
+
* Get path to global agent storage file
|
|
26
|
+
*/
|
|
27
|
+
export function getGlobalAgentStoragePath() {
|
|
28
|
+
return AGENT_STORAGE_PATH;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get path to example agents directory.
|
|
32
|
+
* Checks multiple locations to support both development and npm install scenarios.
|
|
33
|
+
*/
|
|
34
|
+
function getExampleAgentsDir() {
|
|
35
|
+
// Try bundled agents first (when installed via npm)
|
|
36
|
+
// __dirname is 'dist/', bundled is at '../bundled/agents'
|
|
37
|
+
const bundledPath = path.join(__dirname, '..', 'bundled', 'agents');
|
|
38
|
+
if (fs.existsSync(bundledPath)) {
|
|
39
|
+
return bundledPath;
|
|
40
|
+
}
|
|
41
|
+
// Try from commands directory (for backward compatibility)
|
|
42
|
+
const commandsBundledPath = path.join(__dirname, '..', '..', 'bundled', 'agents');
|
|
43
|
+
if (fs.existsSync(commandsBundledPath)) {
|
|
44
|
+
return commandsBundledPath;
|
|
45
|
+
}
|
|
46
|
+
// Try development path (when running from source repo)
|
|
47
|
+
const devPath = path.join(__dirname, '..', '..', '..', 'examples', 'agents');
|
|
48
|
+
if (fs.existsSync(devPath)) {
|
|
49
|
+
return devPath;
|
|
50
|
+
}
|
|
51
|
+
// Fallback to bundled path even if it doesn't exist (will be handled gracefully)
|
|
52
|
+
return bundledPath;
|
|
53
|
+
}
|
|
54
|
+
// Singleton registry - shared across all CLI components
|
|
55
|
+
let _cliRegistry = null;
|
|
56
|
+
let _cliRegistryPromise = null;
|
|
57
|
+
let _exampleAgentsLoaded = false;
|
|
58
|
+
/**
|
|
59
|
+
* Compare two semver version strings
|
|
60
|
+
*/
|
|
61
|
+
function isNewerVersion(newVersion, oldVersion) {
|
|
62
|
+
if (!newVersion)
|
|
63
|
+
return false;
|
|
64
|
+
if (!oldVersion)
|
|
65
|
+
return true;
|
|
66
|
+
const parseVersion = (v) => {
|
|
67
|
+
// Handle pre-release by stripping it for now (simple comparison)
|
|
68
|
+
const cleanVersion = v.split('-')[0] ?? v;
|
|
69
|
+
return cleanVersion.split('.').map(part => parseInt(part, 10) || 0);
|
|
70
|
+
};
|
|
71
|
+
const newParts = parseVersion(newVersion);
|
|
72
|
+
const oldParts = parseVersion(oldVersion);
|
|
73
|
+
for (let i = 0; i < Math.max(newParts.length, oldParts.length); i++) {
|
|
74
|
+
const newPart = newParts[i] || 0;
|
|
75
|
+
const oldPart = oldParts[i] || 0;
|
|
76
|
+
if (newPart > oldPart)
|
|
77
|
+
return true;
|
|
78
|
+
if (newPart < oldPart)
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Initialize the registry and load example agents
|
|
85
|
+
*/
|
|
86
|
+
async function initializeCLIRegistry() {
|
|
87
|
+
// Create persistent registry
|
|
88
|
+
const registry = createPersistentAgentRegistry({
|
|
89
|
+
storagePath: AGENT_STORAGE_PATH,
|
|
90
|
+
createDir: true,
|
|
91
|
+
loadOnInit: true,
|
|
92
|
+
});
|
|
93
|
+
// Load example agents only once
|
|
94
|
+
if (!_exampleAgentsLoaded) {
|
|
95
|
+
_exampleAgentsLoaded = true;
|
|
96
|
+
const exampleAgentsDir = getExampleAgentsDir();
|
|
97
|
+
if (fs.existsSync(exampleAgentsDir)) {
|
|
98
|
+
try {
|
|
99
|
+
const loader = createAgentLoader({
|
|
100
|
+
agentsDir: exampleAgentsDir,
|
|
101
|
+
extensions: ['.json', '.yaml', '.yml'],
|
|
102
|
+
});
|
|
103
|
+
const exampleAgents = await loader.loadAll();
|
|
104
|
+
for (const agent of exampleAgents) {
|
|
105
|
+
try {
|
|
106
|
+
const existing = await registry.get(agent.agentId);
|
|
107
|
+
if (!existing) {
|
|
108
|
+
// Agent doesn't exist - register it
|
|
109
|
+
await registry.register(agent);
|
|
110
|
+
}
|
|
111
|
+
else if (isNewerVersion(agent.version, existing.version)) {
|
|
112
|
+
// Example agent has newer version - update the persisted agent
|
|
113
|
+
await registry.update(agent.agentId, agent);
|
|
114
|
+
}
|
|
115
|
+
// If agent exists with same or newer version, silently skip
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
// Only log non-duplicate errors
|
|
119
|
+
const message = getErrorMessage(error);
|
|
120
|
+
if (!message.toLowerCase().includes('already exists')) {
|
|
121
|
+
console.warn(`Failed to register agent ${agent.agentId}:`, message);
|
|
122
|
+
}
|
|
123
|
+
// Silently ignore "already exists" - expected during normal operation
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
// Log but don't fail - example agents are optional
|
|
129
|
+
console.warn('Failed to load example agents:', getErrorMessage(error));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return registry;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get the shared CLI agent registry
|
|
137
|
+
*
|
|
138
|
+
* Returns the same registry instance across all CLI components.
|
|
139
|
+
* Loads example agents on first access.
|
|
140
|
+
*
|
|
141
|
+
* INV-CLI-REG-001: Uses atomic promise assignment to prevent race conditions
|
|
142
|
+
*/
|
|
143
|
+
export async function getCLIAgentRegistry() {
|
|
144
|
+
if (_cliRegistry !== null) {
|
|
145
|
+
return _cliRegistry;
|
|
146
|
+
}
|
|
147
|
+
if (_cliRegistryPromise === null) {
|
|
148
|
+
// Assign promise immediately before any async work to prevent race condition
|
|
149
|
+
_cliRegistryPromise = initializeCLIRegistry().then(registry => {
|
|
150
|
+
_cliRegistry = registry;
|
|
151
|
+
// Clear promise after resolution to save memory
|
|
152
|
+
_cliRegistryPromise = null;
|
|
153
|
+
return registry;
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return _cliRegistryPromise;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Reset the shared registry (for testing purposes only)
|
|
160
|
+
* @internal
|
|
161
|
+
*/
|
|
162
|
+
export function _resetCLIRegistry() {
|
|
163
|
+
_cliRegistry = null;
|
|
164
|
+
_cliRegistryPromise = null;
|
|
165
|
+
_exampleAgentsLoaded = false;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=shared-cli-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-cli-registry.js","sourceRoot":"","sources":["../src/shared-cli-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/web/api.d.ts
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides REST API endpoints for the web dashboard.
|
|
5
5
|
* Wraps existing domain services to expose via HTTP.
|
|
6
|
+
*
|
|
7
|
+
* KNOWN PERFORMANCE ISSUE (INV-API-PERF-001):
|
|
8
|
+
* Several handlers use an N+1 query pattern where traces are fetched first,
|
|
9
|
+
* then events are fetched for each trace individually. This is acceptable for
|
|
10
|
+
* the local dashboard use case (typically < 200 traces), but would need
|
|
11
|
+
* refactoring for production scale. Consider batch fetching or pagination
|
|
12
|
+
* if performance becomes an issue.
|
|
13
|
+
*
|
|
14
|
+
* Affected handlers: handleStatus, handleProviderHistory, handleAgentHistory,
|
|
15
|
+
* handleTraces, handleWorkflowEvents, handleClassificationStats
|
|
6
16
|
*/
|
|
7
17
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
8
18
|
/**
|
package/dist/web/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/web/api.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/web/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAkCjE;;;;GAIG;AACH,UAAU,uBAAuB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IAC9C,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAyID;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAElF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CA2H/F"}
|
package/dist/web/api.js
CHANGED
|
@@ -3,17 +3,49 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides REST API endpoints for the web dashboard.
|
|
5
5
|
* Wraps existing domain services to expose via HTTP.
|
|
6
|
+
*
|
|
7
|
+
* KNOWN PERFORMANCE ISSUE (INV-API-PERF-001):
|
|
8
|
+
* Several handlers use an N+1 query pattern where traces are fetched first,
|
|
9
|
+
* then events are fetched for each trace individually. This is acceptable for
|
|
10
|
+
* the local dashboard use case (typically < 200 traces), but would need
|
|
11
|
+
* refactoring for production scale. Consider batch fetching or pagination
|
|
12
|
+
* if performance becomes an issue.
|
|
13
|
+
*
|
|
14
|
+
* Affected handlers: handleStatus, handleProviderHistory, handleAgentHistory,
|
|
15
|
+
* handleTraces, handleWorkflowEvents, handleClassificationStats
|
|
6
16
|
*/
|
|
7
|
-
import * as os from 'node:os';
|
|
8
17
|
import * as fs from 'node:fs';
|
|
9
18
|
import * as path from 'node:path';
|
|
10
19
|
import { fileURLToPath } from 'node:url';
|
|
11
|
-
import {
|
|
20
|
+
import { getErrorMessage } from '@defai.digital/contracts';
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// INV-API-VAL-001: Input Validation Constants
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/** Maximum length for any ID parameter to prevent DoS via long strings */
|
|
25
|
+
const MAX_ID_LENGTH = 128;
|
|
26
|
+
/** UUID v4 format regex for trace IDs */
|
|
27
|
+
const UUID_REGEX = /^[a-f0-9]{8}-[a-f0-9]{4}-[4][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i;
|
|
28
|
+
/**
|
|
29
|
+
* Validates a trace ID is a valid UUID and within length limits
|
|
30
|
+
* INV-API-VAL-001: Strict UUID validation for trace IDs
|
|
31
|
+
*/
|
|
32
|
+
function isValidTraceId(id) {
|
|
33
|
+
if (!id || id.length > MAX_ID_LENGTH)
|
|
34
|
+
return false;
|
|
35
|
+
return UUID_REGEX.test(id);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Validates a generic ID (workflow, agent, provider) is within length limits
|
|
39
|
+
* INV-API-VAL-001: Length validation for all IDs
|
|
40
|
+
*/
|
|
41
|
+
function isValidId(id) {
|
|
42
|
+
return typeof id === 'string' && id.length > 0 && id.length <= MAX_ID_LENGTH;
|
|
43
|
+
}
|
|
12
44
|
// Get the directory of this module (for finding bundled examples)
|
|
13
45
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
46
|
const __dirname = path.dirname(__filename);
|
|
15
47
|
import { getProviderRegistry, getTraceStore, getSessionManager as getSharedSessionManager, } from '../bootstrap.js';
|
|
16
|
-
import {
|
|
48
|
+
import { getCLIAgentRegistry } from '../shared-cli-registry.js';
|
|
17
49
|
import { createWorkflowLoader, findWorkflowDir, } from '@defai.digital/workflow-engine';
|
|
18
50
|
import { CLI_VERSION } from '../commands/help.js';
|
|
19
51
|
import { getProviderStatus as checkProviderHealth } from '../commands/status.js';
|
|
@@ -74,16 +106,6 @@ async function getWorkflowLoader() {
|
|
|
74
106
|
}
|
|
75
107
|
return workflowLoaderPromise;
|
|
76
108
|
}
|
|
77
|
-
// Lazy singletons with Promise-based initialization to prevent race conditions
|
|
78
|
-
let agentRegistry;
|
|
79
|
-
let agentRegistryPromise;
|
|
80
|
-
/**
|
|
81
|
-
* Get the global agent storage path (same as MCP server).
|
|
82
|
-
* Uses home directory for consistency across all AutomatosX components.
|
|
83
|
-
*/
|
|
84
|
-
function getGlobalAgentStoragePath() {
|
|
85
|
-
return path.join(os.homedir(), DATA_DIR_NAME, AGENTS_FILENAME);
|
|
86
|
-
}
|
|
87
109
|
/**
|
|
88
110
|
* Get the session manager from CLI bootstrap (shared instance)
|
|
89
111
|
* This ensures the web dashboard sees the same sessions as other CLI components
|
|
@@ -91,25 +113,6 @@ function getGlobalAgentStoragePath() {
|
|
|
91
113
|
function getSessionManager() {
|
|
92
114
|
return getSharedSessionManager();
|
|
93
115
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Get or create the agent registry (thread-safe)
|
|
96
|
-
* Uses atomic promise assignment pattern for safety
|
|
97
|
-
*/
|
|
98
|
-
async function getAgentRegistry() {
|
|
99
|
-
if (agentRegistry)
|
|
100
|
-
return agentRegistry;
|
|
101
|
-
if (!agentRegistryPromise) {
|
|
102
|
-
// Assign promise immediately to prevent potential race conditions
|
|
103
|
-
agentRegistryPromise = Promise.resolve().then(() => {
|
|
104
|
-
const registry = createPersistentAgentRegistry({
|
|
105
|
-
storagePath: getGlobalAgentStoragePath(),
|
|
106
|
-
});
|
|
107
|
-
agentRegistry = registry;
|
|
108
|
-
return registry;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
return agentRegistryPromise;
|
|
112
|
-
}
|
|
113
116
|
/**
|
|
114
117
|
* Cached provider status (set at monitor startup)
|
|
115
118
|
*/
|
|
@@ -140,36 +143,37 @@ export function createAPIHandler() {
|
|
|
140
143
|
const workflowEventsMatch = apiPath.match(/^\/workflows\/([a-z0-9-]+)\/events$/i);
|
|
141
144
|
const traceSearchMatch = apiPath.match(/^\/traces\/search\?(.*)$/i) || apiPath.match(/^\/traces\/search$/i);
|
|
142
145
|
// INV-TR-020 through INV-TR-024: Hierarchical trace tree endpoint
|
|
143
|
-
|
|
146
|
+
// INV-API-VAL-001: Validate all IDs before processing
|
|
147
|
+
if (traceTreeMatch && isValidTraceId(traceTreeMatch[1])) {
|
|
144
148
|
const traceId = traceTreeMatch[1];
|
|
145
149
|
response = await handleTraceTree(traceId);
|
|
146
150
|
}
|
|
147
|
-
else if (traceClassificationMatch && traceClassificationMatch[1]) {
|
|
151
|
+
else if (traceClassificationMatch && isValidTraceId(traceClassificationMatch[1])) {
|
|
148
152
|
// PRD-2026-003: Classification observability endpoint
|
|
149
153
|
const traceId = traceClassificationMatch[1];
|
|
150
154
|
response = await handleTraceClassification(traceId);
|
|
151
155
|
}
|
|
152
|
-
else if (traceDetailMatch && traceDetailMatch[1]) {
|
|
156
|
+
else if (traceDetailMatch && isValidTraceId(traceDetailMatch[1])) {
|
|
153
157
|
const traceId = traceDetailMatch[1];
|
|
154
158
|
response = await handleTraceDetail(traceId);
|
|
155
159
|
}
|
|
156
|
-
else if (workflowDetailMatch && workflowDetailMatch[1]) {
|
|
160
|
+
else if (workflowDetailMatch && isValidId(workflowDetailMatch[1])) {
|
|
157
161
|
const workflowId = workflowDetailMatch[1];
|
|
158
162
|
response = await handleWorkflowDetail(workflowId);
|
|
159
163
|
}
|
|
160
|
-
else if (providerHistoryMatch && providerHistoryMatch[1]) {
|
|
164
|
+
else if (providerHistoryMatch && isValidId(providerHistoryMatch[1])) {
|
|
161
165
|
const providerId = providerHistoryMatch[1];
|
|
162
166
|
response = await handleProviderHistory(providerId);
|
|
163
167
|
}
|
|
164
|
-
else if (agentHistoryMatch && agentHistoryMatch[1]) {
|
|
168
|
+
else if (agentHistoryMatch && isValidId(agentHistoryMatch[1])) {
|
|
165
169
|
const agentId = agentHistoryMatch[1];
|
|
166
170
|
response = await handleAgentHistory(agentId);
|
|
167
171
|
}
|
|
168
|
-
else if (agentDetailMatch && agentDetailMatch[1]) {
|
|
172
|
+
else if (agentDetailMatch && isValidId(agentDetailMatch[1])) {
|
|
169
173
|
const agentId = agentDetailMatch[1];
|
|
170
174
|
response = await handleAgentDetail(agentId);
|
|
171
175
|
}
|
|
172
|
-
else if (workflowEventsMatch && workflowEventsMatch[1]) {
|
|
176
|
+
else if (workflowEventsMatch && isValidId(workflowEventsMatch[1])) {
|
|
173
177
|
const workflowId = workflowEventsMatch[1];
|
|
174
178
|
response = await handleWorkflowEvents(workflowId);
|
|
175
179
|
}
|
|
@@ -360,7 +364,7 @@ async function handleAgents() {
|
|
|
360
364
|
*/
|
|
361
365
|
async function handleAgentDetail(agentId) {
|
|
362
366
|
try {
|
|
363
|
-
const registry = await
|
|
367
|
+
const registry = await getCLIAgentRegistry();
|
|
364
368
|
const agent = await registry.get(agentId);
|
|
365
369
|
if (!agent) {
|
|
366
370
|
return { success: false, error: `Agent not found: ${agentId}` };
|
|
@@ -1007,7 +1011,7 @@ async function handleAgentHistory(agentId) {
|
|
|
1007
1011
|
}
|
|
1008
1012
|
}
|
|
1009
1013
|
// Get agent info
|
|
1010
|
-
const registry = await
|
|
1014
|
+
const registry = await getCLIAgentRegistry();
|
|
1011
1015
|
const agent = await registry.get(agentId);
|
|
1012
1016
|
return {
|
|
1013
1017
|
success: true,
|
|
@@ -1416,7 +1420,7 @@ async function getSessionData() {
|
|
|
1416
1420
|
*/
|
|
1417
1421
|
async function getAgentData() {
|
|
1418
1422
|
try {
|
|
1419
|
-
const registry = await
|
|
1423
|
+
const registry = await getCLIAgentRegistry();
|
|
1420
1424
|
const agents = await registry.list();
|
|
1421
1425
|
return agents.slice(0, 50).map(agent => ({
|
|
1422
1426
|
agentId: agent.agentId,
|
|
@@ -1621,7 +1625,7 @@ async function getMetricsData() {
|
|
|
1621
1625
|
// ignore
|
|
1622
1626
|
}
|
|
1623
1627
|
try {
|
|
1624
|
-
const registry = await
|
|
1628
|
+
const registry = await getCLIAgentRegistry();
|
|
1625
1629
|
const agents = await registry.list();
|
|
1626
1630
|
activeAgents = agents.filter(a => a.enabled !== false).length;
|
|
1627
1631
|
}
|