chainlesschain 0.152.0 → 0.156.2
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 +52 -3
- package/package.json +1 -1
- package/src/commands/a2a.js +201 -0
- package/src/commands/agent.js +1250 -0
- package/src/commands/chat.js +605 -0
- package/src/commands/cli-anything.js +426 -0
- package/src/commands/compliance.js +412 -0
- package/src/commands/config.js +213 -0
- package/src/commands/cowork.js +1463 -0
- package/src/commands/crosschain.js +203 -0
- package/src/commands/dao.js +203 -0
- package/src/commands/economy.js +199 -0
- package/src/commands/encrypt.js +201 -0
- package/src/commands/evolution.js +199 -0
- package/src/commands/evomap.js +625 -0
- package/src/commands/hmemory.js +203 -0
- package/src/commands/inference.js +207 -0
- package/src/commands/kg.js +195 -0
- package/src/commands/llm.js +209 -0
- package/src/commands/memory.js +203 -0
- package/src/commands/orchestrate.js +406 -0
- package/src/commands/pipeline.js +199 -0
- package/src/commands/planmode.js +426 -0
- package/src/commands/plugin.js +209 -0
- package/src/commands/services.js +207 -0
- package/src/commands/setup.js +205 -0
- package/src/commands/skill.js +207 -0
- package/src/commands/start.js +209 -0
- package/src/commands/stream.js +213 -0
- package/src/commands/ui.js +225 -0
- package/src/commands/workflow.js +209 -0
- package/src/index.js +112 -0
- package/src/lib/a2a-protocol.js +332 -0
- package/src/lib/agent-coordinator.js +334 -0
- package/src/lib/agent-economy.js +334 -0
- package/src/lib/agent-router.js +333 -0
- package/src/lib/autonomous-agent.js +332 -0
- package/src/lib/chat-core.js +335 -0
- package/src/lib/cli-anything-bridge.js +341 -0
- package/src/lib/cli-context-engineering.js +351 -0
- package/src/lib/compliance-manager.js +334 -0
- package/src/lib/cowork-adapter.js +336 -0
- package/src/lib/cowork-evomap-adapter.js +341 -0
- package/src/lib/cowork-mcp-tools.js +341 -0
- package/src/lib/cowork-observe-html.js +341 -0
- package/src/lib/cowork-observe.js +341 -0
- package/src/lib/cowork-task-templates.js +342 -1
- package/src/lib/cowork-template-marketplace.js +340 -0
- package/src/lib/cross-chain.js +339 -0
- package/src/lib/crypto-manager.js +334 -0
- package/src/lib/dao-governance.js +339 -0
- package/src/lib/downloader.js +334 -0
- package/src/lib/evolution-system.js +334 -0
- package/src/lib/evomap-client.js +342 -0
- package/src/lib/evomap-federation.js +338 -0
- package/src/lib/evomap-manager.js +330 -0
- package/src/lib/execution-backend.js +330 -0
- package/src/lib/hashline.js +338 -0
- package/src/lib/hierarchical-memory.js +334 -0
- package/src/lib/inference-network.js +341 -0
- package/src/lib/interaction-adapter.js +330 -0
- package/src/lib/interactive-planner.js +354 -0
- package/src/lib/knowledge-graph.js +331 -0
- package/src/lib/pipeline-orchestrator.js +332 -0
- package/src/lib/plan-mode.js +336 -0
- package/src/lib/plugin-autodiscovery.js +334 -0
- package/src/lib/process-manager.js +336 -0
- package/src/lib/provider-options.js +346 -0
- package/src/lib/provider-stream.js +348 -0
- package/src/lib/service-manager.js +337 -0
- package/src/lib/session-core-singletons.js +341 -0
- package/src/lib/skill-mcp.js +336 -0
- package/src/lib/stix-parser.js +346 -0
- package/src/lib/sub-agent-context.js +343 -0
- package/src/lib/sub-agent-profiles.js +335 -0
- package/src/lib/sub-agent-registry.js +336 -0
- package/src/lib/todo-manager.js +336 -0
- package/src/lib/web-ui-server.js +348 -0
- package/src/lib/workflow-expr.js +346 -0
- package/src/lib/ws-chat-handler.js +337 -0
package/src/lib/skill-mcp.js
CHANGED
|
@@ -188,3 +188,339 @@ export async function unmountSkillMcpServers(mcpClient, mountedNames) {
|
|
|
188
188
|
|
|
189
189
|
return { unmounted, errors };
|
|
190
190
|
}
|
|
191
|
+
|
|
192
|
+
// =====================================================================
|
|
193
|
+
// skill-mcp V2 governance overlay (iter27)
|
|
194
|
+
// =====================================================================
|
|
195
|
+
export const SMCPGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
196
|
+
PENDING: "pending",
|
|
197
|
+
ACTIVE: "active",
|
|
198
|
+
STALE: "stale",
|
|
199
|
+
ARCHIVED: "archived",
|
|
200
|
+
});
|
|
201
|
+
export const SMCPGOV_CALL_LIFECYCLE_V2 = Object.freeze({
|
|
202
|
+
QUEUED: "queued",
|
|
203
|
+
INVOKING: "invoking",
|
|
204
|
+
INVOKED: "invoked",
|
|
205
|
+
FAILED: "failed",
|
|
206
|
+
CANCELLED: "cancelled",
|
|
207
|
+
});
|
|
208
|
+
const _smcpgovPTrans = new Map([
|
|
209
|
+
[
|
|
210
|
+
SMCPGOV_PROFILE_MATURITY_V2.PENDING,
|
|
211
|
+
new Set([
|
|
212
|
+
SMCPGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
213
|
+
SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
214
|
+
]),
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
SMCPGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
218
|
+
new Set([
|
|
219
|
+
SMCPGOV_PROFILE_MATURITY_V2.STALE,
|
|
220
|
+
SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
221
|
+
]),
|
|
222
|
+
],
|
|
223
|
+
[
|
|
224
|
+
SMCPGOV_PROFILE_MATURITY_V2.STALE,
|
|
225
|
+
new Set([
|
|
226
|
+
SMCPGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
227
|
+
SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
228
|
+
]),
|
|
229
|
+
],
|
|
230
|
+
[SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
231
|
+
]);
|
|
232
|
+
const _smcpgovPTerminal = new Set([SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
233
|
+
const _smcpgovJTrans = new Map([
|
|
234
|
+
[
|
|
235
|
+
SMCPGOV_CALL_LIFECYCLE_V2.QUEUED,
|
|
236
|
+
new Set([
|
|
237
|
+
SMCPGOV_CALL_LIFECYCLE_V2.INVOKING,
|
|
238
|
+
SMCPGOV_CALL_LIFECYCLE_V2.CANCELLED,
|
|
239
|
+
]),
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
SMCPGOV_CALL_LIFECYCLE_V2.INVOKING,
|
|
243
|
+
new Set([
|
|
244
|
+
SMCPGOV_CALL_LIFECYCLE_V2.INVOKED,
|
|
245
|
+
SMCPGOV_CALL_LIFECYCLE_V2.FAILED,
|
|
246
|
+
SMCPGOV_CALL_LIFECYCLE_V2.CANCELLED,
|
|
247
|
+
]),
|
|
248
|
+
],
|
|
249
|
+
[SMCPGOV_CALL_LIFECYCLE_V2.INVOKED, new Set()],
|
|
250
|
+
[SMCPGOV_CALL_LIFECYCLE_V2.FAILED, new Set()],
|
|
251
|
+
[SMCPGOV_CALL_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
252
|
+
]);
|
|
253
|
+
const _smcpgovPsV2 = new Map();
|
|
254
|
+
const _smcpgovJsV2 = new Map();
|
|
255
|
+
let _smcpgovMaxActive = 6,
|
|
256
|
+
_smcpgovMaxPending = 15,
|
|
257
|
+
_smcpgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
258
|
+
_smcpgovStuckMs = 60 * 1000;
|
|
259
|
+
function _smcpgovPos(n, label) {
|
|
260
|
+
const v = Math.floor(Number(n));
|
|
261
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
262
|
+
throw new Error(`${label} must be positive integer`);
|
|
263
|
+
return v;
|
|
264
|
+
}
|
|
265
|
+
function _smcpgovCheckP(from, to) {
|
|
266
|
+
const a = _smcpgovPTrans.get(from);
|
|
267
|
+
if (!a || !a.has(to))
|
|
268
|
+
throw new Error(`invalid smcpgov profile transition ${from} → ${to}`);
|
|
269
|
+
}
|
|
270
|
+
function _smcpgovCheckJ(from, to) {
|
|
271
|
+
const a = _smcpgovJTrans.get(from);
|
|
272
|
+
if (!a || !a.has(to))
|
|
273
|
+
throw new Error(`invalid smcpgov call transition ${from} → ${to}`);
|
|
274
|
+
}
|
|
275
|
+
function _smcpgovCountActive(owner) {
|
|
276
|
+
let c = 0;
|
|
277
|
+
for (const p of _smcpgovPsV2.values())
|
|
278
|
+
if (p.owner === owner && p.status === SMCPGOV_PROFILE_MATURITY_V2.ACTIVE)
|
|
279
|
+
c++;
|
|
280
|
+
return c;
|
|
281
|
+
}
|
|
282
|
+
function _smcpgovCountPending(profileId) {
|
|
283
|
+
let c = 0;
|
|
284
|
+
for (const j of _smcpgovJsV2.values())
|
|
285
|
+
if (
|
|
286
|
+
j.profileId === profileId &&
|
|
287
|
+
(j.status === SMCPGOV_CALL_LIFECYCLE_V2.QUEUED ||
|
|
288
|
+
j.status === SMCPGOV_CALL_LIFECYCLE_V2.INVOKING)
|
|
289
|
+
)
|
|
290
|
+
c++;
|
|
291
|
+
return c;
|
|
292
|
+
}
|
|
293
|
+
export function setMaxActiveSmcpgovProfilesPerOwnerV2(n) {
|
|
294
|
+
_smcpgovMaxActive = _smcpgovPos(n, "maxActiveSmcpgovProfilesPerOwner");
|
|
295
|
+
}
|
|
296
|
+
export function getMaxActiveSmcpgovProfilesPerOwnerV2() {
|
|
297
|
+
return _smcpgovMaxActive;
|
|
298
|
+
}
|
|
299
|
+
export function setMaxPendingSmcpgovCallsPerProfileV2(n) {
|
|
300
|
+
_smcpgovMaxPending = _smcpgovPos(n, "maxPendingSmcpgovCallsPerProfile");
|
|
301
|
+
}
|
|
302
|
+
export function getMaxPendingSmcpgovCallsPerProfileV2() {
|
|
303
|
+
return _smcpgovMaxPending;
|
|
304
|
+
}
|
|
305
|
+
export function setSmcpgovProfileIdleMsV2(n) {
|
|
306
|
+
_smcpgovIdleMs = _smcpgovPos(n, "smcpgovProfileIdleMs");
|
|
307
|
+
}
|
|
308
|
+
export function getSmcpgovProfileIdleMsV2() {
|
|
309
|
+
return _smcpgovIdleMs;
|
|
310
|
+
}
|
|
311
|
+
export function setSmcpgovCallStuckMsV2(n) {
|
|
312
|
+
_smcpgovStuckMs = _smcpgovPos(n, "smcpgovCallStuckMs");
|
|
313
|
+
}
|
|
314
|
+
export function getSmcpgovCallStuckMsV2() {
|
|
315
|
+
return _smcpgovStuckMs;
|
|
316
|
+
}
|
|
317
|
+
export function _resetStateSkillMcpGovV2() {
|
|
318
|
+
_smcpgovPsV2.clear();
|
|
319
|
+
_smcpgovJsV2.clear();
|
|
320
|
+
_smcpgovMaxActive = 6;
|
|
321
|
+
_smcpgovMaxPending = 15;
|
|
322
|
+
_smcpgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
323
|
+
_smcpgovStuckMs = 60 * 1000;
|
|
324
|
+
}
|
|
325
|
+
export function registerSmcpgovProfileV2({ id, owner, server, metadata } = {}) {
|
|
326
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
327
|
+
if (_smcpgovPsV2.has(id))
|
|
328
|
+
throw new Error(`smcpgov profile ${id} already exists`);
|
|
329
|
+
const now = Date.now();
|
|
330
|
+
const p = {
|
|
331
|
+
id,
|
|
332
|
+
owner,
|
|
333
|
+
server: server || "default",
|
|
334
|
+
status: SMCPGOV_PROFILE_MATURITY_V2.PENDING,
|
|
335
|
+
createdAt: now,
|
|
336
|
+
updatedAt: now,
|
|
337
|
+
lastTouchedAt: now,
|
|
338
|
+
activatedAt: null,
|
|
339
|
+
archivedAt: null,
|
|
340
|
+
metadata: { ...(metadata || {}) },
|
|
341
|
+
};
|
|
342
|
+
_smcpgovPsV2.set(id, p);
|
|
343
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
344
|
+
}
|
|
345
|
+
export function activateSmcpgovProfileV2(id) {
|
|
346
|
+
const p = _smcpgovPsV2.get(id);
|
|
347
|
+
if (!p) throw new Error(`smcpgov profile ${id} not found`);
|
|
348
|
+
const isInitial = p.status === SMCPGOV_PROFILE_MATURITY_V2.PENDING;
|
|
349
|
+
_smcpgovCheckP(p.status, SMCPGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
350
|
+
if (isInitial && _smcpgovCountActive(p.owner) >= _smcpgovMaxActive)
|
|
351
|
+
throw new Error(`max active smcpgov profiles for owner ${p.owner} reached`);
|
|
352
|
+
const now = Date.now();
|
|
353
|
+
p.status = SMCPGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
354
|
+
p.updatedAt = now;
|
|
355
|
+
p.lastTouchedAt = now;
|
|
356
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
357
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
358
|
+
}
|
|
359
|
+
export function staleSmcpgovProfileV2(id) {
|
|
360
|
+
const p = _smcpgovPsV2.get(id);
|
|
361
|
+
if (!p) throw new Error(`smcpgov profile ${id} not found`);
|
|
362
|
+
_smcpgovCheckP(p.status, SMCPGOV_PROFILE_MATURITY_V2.STALE);
|
|
363
|
+
p.status = SMCPGOV_PROFILE_MATURITY_V2.STALE;
|
|
364
|
+
p.updatedAt = Date.now();
|
|
365
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
366
|
+
}
|
|
367
|
+
export function archiveSmcpgovProfileV2(id) {
|
|
368
|
+
const p = _smcpgovPsV2.get(id);
|
|
369
|
+
if (!p) throw new Error(`smcpgov profile ${id} not found`);
|
|
370
|
+
_smcpgovCheckP(p.status, SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
371
|
+
const now = Date.now();
|
|
372
|
+
p.status = SMCPGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
373
|
+
p.updatedAt = now;
|
|
374
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
375
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
376
|
+
}
|
|
377
|
+
export function touchSmcpgovProfileV2(id) {
|
|
378
|
+
const p = _smcpgovPsV2.get(id);
|
|
379
|
+
if (!p) throw new Error(`smcpgov profile ${id} not found`);
|
|
380
|
+
if (_smcpgovPTerminal.has(p.status))
|
|
381
|
+
throw new Error(`cannot touch terminal smcpgov profile ${id}`);
|
|
382
|
+
const now = Date.now();
|
|
383
|
+
p.lastTouchedAt = now;
|
|
384
|
+
p.updatedAt = now;
|
|
385
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
386
|
+
}
|
|
387
|
+
export function getSmcpgovProfileV2(id) {
|
|
388
|
+
const p = _smcpgovPsV2.get(id);
|
|
389
|
+
if (!p) return null;
|
|
390
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
391
|
+
}
|
|
392
|
+
export function listSmcpgovProfilesV2() {
|
|
393
|
+
return [..._smcpgovPsV2.values()].map((p) => ({
|
|
394
|
+
...p,
|
|
395
|
+
metadata: { ...p.metadata },
|
|
396
|
+
}));
|
|
397
|
+
}
|
|
398
|
+
export function createSmcpgovCallV2({ id, profileId, tool, metadata } = {}) {
|
|
399
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
400
|
+
if (_smcpgovJsV2.has(id))
|
|
401
|
+
throw new Error(`smcpgov call ${id} already exists`);
|
|
402
|
+
if (!_smcpgovPsV2.has(profileId))
|
|
403
|
+
throw new Error(`smcpgov profile ${profileId} not found`);
|
|
404
|
+
if (_smcpgovCountPending(profileId) >= _smcpgovMaxPending)
|
|
405
|
+
throw new Error(
|
|
406
|
+
`max pending smcpgov calls for profile ${profileId} reached`,
|
|
407
|
+
);
|
|
408
|
+
const now = Date.now();
|
|
409
|
+
const j = {
|
|
410
|
+
id,
|
|
411
|
+
profileId,
|
|
412
|
+
tool: tool || "",
|
|
413
|
+
status: SMCPGOV_CALL_LIFECYCLE_V2.QUEUED,
|
|
414
|
+
createdAt: now,
|
|
415
|
+
updatedAt: now,
|
|
416
|
+
startedAt: null,
|
|
417
|
+
settledAt: null,
|
|
418
|
+
metadata: { ...(metadata || {}) },
|
|
419
|
+
};
|
|
420
|
+
_smcpgovJsV2.set(id, j);
|
|
421
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
422
|
+
}
|
|
423
|
+
export function invokingSmcpgovCallV2(id) {
|
|
424
|
+
const j = _smcpgovJsV2.get(id);
|
|
425
|
+
if (!j) throw new Error(`smcpgov call ${id} not found`);
|
|
426
|
+
_smcpgovCheckJ(j.status, SMCPGOV_CALL_LIFECYCLE_V2.INVOKING);
|
|
427
|
+
const now = Date.now();
|
|
428
|
+
j.status = SMCPGOV_CALL_LIFECYCLE_V2.INVOKING;
|
|
429
|
+
j.updatedAt = now;
|
|
430
|
+
if (!j.startedAt) j.startedAt = now;
|
|
431
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
432
|
+
}
|
|
433
|
+
export function completeCallSmcpgovV2(id) {
|
|
434
|
+
const j = _smcpgovJsV2.get(id);
|
|
435
|
+
if (!j) throw new Error(`smcpgov call ${id} not found`);
|
|
436
|
+
_smcpgovCheckJ(j.status, SMCPGOV_CALL_LIFECYCLE_V2.INVOKED);
|
|
437
|
+
const now = Date.now();
|
|
438
|
+
j.status = SMCPGOV_CALL_LIFECYCLE_V2.INVOKED;
|
|
439
|
+
j.updatedAt = now;
|
|
440
|
+
if (!j.settledAt) j.settledAt = now;
|
|
441
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
442
|
+
}
|
|
443
|
+
export function failSmcpgovCallV2(id, reason) {
|
|
444
|
+
const j = _smcpgovJsV2.get(id);
|
|
445
|
+
if (!j) throw new Error(`smcpgov call ${id} not found`);
|
|
446
|
+
_smcpgovCheckJ(j.status, SMCPGOV_CALL_LIFECYCLE_V2.FAILED);
|
|
447
|
+
const now = Date.now();
|
|
448
|
+
j.status = SMCPGOV_CALL_LIFECYCLE_V2.FAILED;
|
|
449
|
+
j.updatedAt = now;
|
|
450
|
+
if (!j.settledAt) j.settledAt = now;
|
|
451
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
452
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
453
|
+
}
|
|
454
|
+
export function cancelSmcpgovCallV2(id, reason) {
|
|
455
|
+
const j = _smcpgovJsV2.get(id);
|
|
456
|
+
if (!j) throw new Error(`smcpgov call ${id} not found`);
|
|
457
|
+
_smcpgovCheckJ(j.status, SMCPGOV_CALL_LIFECYCLE_V2.CANCELLED);
|
|
458
|
+
const now = Date.now();
|
|
459
|
+
j.status = SMCPGOV_CALL_LIFECYCLE_V2.CANCELLED;
|
|
460
|
+
j.updatedAt = now;
|
|
461
|
+
if (!j.settledAt) j.settledAt = now;
|
|
462
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
463
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
464
|
+
}
|
|
465
|
+
export function getSmcpgovCallV2(id) {
|
|
466
|
+
const j = _smcpgovJsV2.get(id);
|
|
467
|
+
if (!j) return null;
|
|
468
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
469
|
+
}
|
|
470
|
+
export function listSmcpgovCallsV2() {
|
|
471
|
+
return [..._smcpgovJsV2.values()].map((j) => ({
|
|
472
|
+
...j,
|
|
473
|
+
metadata: { ...j.metadata },
|
|
474
|
+
}));
|
|
475
|
+
}
|
|
476
|
+
export function autoStaleIdleSmcpgovProfilesV2({ now } = {}) {
|
|
477
|
+
const t = now ?? Date.now();
|
|
478
|
+
const flipped = [];
|
|
479
|
+
for (const p of _smcpgovPsV2.values())
|
|
480
|
+
if (
|
|
481
|
+
p.status === SMCPGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
482
|
+
t - p.lastTouchedAt >= _smcpgovIdleMs
|
|
483
|
+
) {
|
|
484
|
+
p.status = SMCPGOV_PROFILE_MATURITY_V2.STALE;
|
|
485
|
+
p.updatedAt = t;
|
|
486
|
+
flipped.push(p.id);
|
|
487
|
+
}
|
|
488
|
+
return { flipped, count: flipped.length };
|
|
489
|
+
}
|
|
490
|
+
export function autoFailStuckSmcpgovCallsV2({ now } = {}) {
|
|
491
|
+
const t = now ?? Date.now();
|
|
492
|
+
const flipped = [];
|
|
493
|
+
for (const j of _smcpgovJsV2.values())
|
|
494
|
+
if (
|
|
495
|
+
j.status === SMCPGOV_CALL_LIFECYCLE_V2.INVOKING &&
|
|
496
|
+
j.startedAt != null &&
|
|
497
|
+
t - j.startedAt >= _smcpgovStuckMs
|
|
498
|
+
) {
|
|
499
|
+
j.status = SMCPGOV_CALL_LIFECYCLE_V2.FAILED;
|
|
500
|
+
j.updatedAt = t;
|
|
501
|
+
if (!j.settledAt) j.settledAt = t;
|
|
502
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
503
|
+
flipped.push(j.id);
|
|
504
|
+
}
|
|
505
|
+
return { flipped, count: flipped.length };
|
|
506
|
+
}
|
|
507
|
+
export function getSkillMcpGovStatsV2() {
|
|
508
|
+
const profilesByStatus = {};
|
|
509
|
+
for (const v of Object.values(SMCPGOV_PROFILE_MATURITY_V2))
|
|
510
|
+
profilesByStatus[v] = 0;
|
|
511
|
+
for (const p of _smcpgovPsV2.values()) profilesByStatus[p.status]++;
|
|
512
|
+
const callsByStatus = {};
|
|
513
|
+
for (const v of Object.values(SMCPGOV_CALL_LIFECYCLE_V2))
|
|
514
|
+
callsByStatus[v] = 0;
|
|
515
|
+
for (const j of _smcpgovJsV2.values()) callsByStatus[j.status]++;
|
|
516
|
+
return {
|
|
517
|
+
totalSmcpgovProfilesV2: _smcpgovPsV2.size,
|
|
518
|
+
totalSmcpgovCallsV2: _smcpgovJsV2.size,
|
|
519
|
+
maxActiveSmcpgovProfilesPerOwner: _smcpgovMaxActive,
|
|
520
|
+
maxPendingSmcpgovCallsPerProfile: _smcpgovMaxPending,
|
|
521
|
+
smcpgovProfileIdleMs: _smcpgovIdleMs,
|
|
522
|
+
smcpgovCallStuckMs: _smcpgovStuckMs,
|
|
523
|
+
profilesByStatus,
|
|
524
|
+
callsByStatus,
|
|
525
|
+
};
|
|
526
|
+
}
|
package/src/lib/stix-parser.js
CHANGED
|
@@ -165,3 +165,349 @@ export function classifyObservable(value) {
|
|
|
165
165
|
if (/^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(v)) return "domain";
|
|
166
166
|
return "unknown";
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
// =====================================================================
|
|
170
|
+
// stix-parser V2 governance overlay (iter27)
|
|
171
|
+
// =====================================================================
|
|
172
|
+
export const STIXGOV_PROFILE_MATURITY_V2 = Object.freeze({
|
|
173
|
+
PENDING: "pending",
|
|
174
|
+
ACTIVE: "active",
|
|
175
|
+
STALE: "stale",
|
|
176
|
+
ARCHIVED: "archived",
|
|
177
|
+
});
|
|
178
|
+
export const STIXGOV_PARSE_LIFECYCLE_V2 = Object.freeze({
|
|
179
|
+
QUEUED: "queued",
|
|
180
|
+
PARSING: "parsing",
|
|
181
|
+
PARSED: "parsed",
|
|
182
|
+
FAILED: "failed",
|
|
183
|
+
CANCELLED: "cancelled",
|
|
184
|
+
});
|
|
185
|
+
const _stixgovPTrans = new Map([
|
|
186
|
+
[
|
|
187
|
+
STIXGOV_PROFILE_MATURITY_V2.PENDING,
|
|
188
|
+
new Set([
|
|
189
|
+
STIXGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
190
|
+
STIXGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
191
|
+
]),
|
|
192
|
+
],
|
|
193
|
+
[
|
|
194
|
+
STIXGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
195
|
+
new Set([
|
|
196
|
+
STIXGOV_PROFILE_MATURITY_V2.STALE,
|
|
197
|
+
STIXGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
198
|
+
]),
|
|
199
|
+
],
|
|
200
|
+
[
|
|
201
|
+
STIXGOV_PROFILE_MATURITY_V2.STALE,
|
|
202
|
+
new Set([
|
|
203
|
+
STIXGOV_PROFILE_MATURITY_V2.ACTIVE,
|
|
204
|
+
STIXGOV_PROFILE_MATURITY_V2.ARCHIVED,
|
|
205
|
+
]),
|
|
206
|
+
],
|
|
207
|
+
[STIXGOV_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
208
|
+
]);
|
|
209
|
+
const _stixgovPTerminal = new Set([STIXGOV_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
210
|
+
const _stixgovJTrans = new Map([
|
|
211
|
+
[
|
|
212
|
+
STIXGOV_PARSE_LIFECYCLE_V2.QUEUED,
|
|
213
|
+
new Set([
|
|
214
|
+
STIXGOV_PARSE_LIFECYCLE_V2.PARSING,
|
|
215
|
+
STIXGOV_PARSE_LIFECYCLE_V2.CANCELLED,
|
|
216
|
+
]),
|
|
217
|
+
],
|
|
218
|
+
[
|
|
219
|
+
STIXGOV_PARSE_LIFECYCLE_V2.PARSING,
|
|
220
|
+
new Set([
|
|
221
|
+
STIXGOV_PARSE_LIFECYCLE_V2.PARSED,
|
|
222
|
+
STIXGOV_PARSE_LIFECYCLE_V2.FAILED,
|
|
223
|
+
STIXGOV_PARSE_LIFECYCLE_V2.CANCELLED,
|
|
224
|
+
]),
|
|
225
|
+
],
|
|
226
|
+
[STIXGOV_PARSE_LIFECYCLE_V2.PARSED, new Set()],
|
|
227
|
+
[STIXGOV_PARSE_LIFECYCLE_V2.FAILED, new Set()],
|
|
228
|
+
[STIXGOV_PARSE_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
229
|
+
]);
|
|
230
|
+
const _stixgovPsV2 = new Map();
|
|
231
|
+
const _stixgovJsV2 = new Map();
|
|
232
|
+
let _stixgovMaxActive = 6,
|
|
233
|
+
_stixgovMaxPending = 15,
|
|
234
|
+
_stixgovIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
235
|
+
_stixgovStuckMs = 60 * 1000;
|
|
236
|
+
function _stixgovPos(n, label) {
|
|
237
|
+
const v = Math.floor(Number(n));
|
|
238
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
239
|
+
throw new Error(`${label} must be positive integer`);
|
|
240
|
+
return v;
|
|
241
|
+
}
|
|
242
|
+
function _stixgovCheckP(from, to) {
|
|
243
|
+
const a = _stixgovPTrans.get(from);
|
|
244
|
+
if (!a || !a.has(to))
|
|
245
|
+
throw new Error(`invalid stixgov profile transition ${from} → ${to}`);
|
|
246
|
+
}
|
|
247
|
+
function _stixgovCheckJ(from, to) {
|
|
248
|
+
const a = _stixgovJTrans.get(from);
|
|
249
|
+
if (!a || !a.has(to))
|
|
250
|
+
throw new Error(`invalid stixgov parse transition ${from} → ${to}`);
|
|
251
|
+
}
|
|
252
|
+
function _stixgovCountActive(owner) {
|
|
253
|
+
let c = 0;
|
|
254
|
+
for (const p of _stixgovPsV2.values())
|
|
255
|
+
if (p.owner === owner && p.status === STIXGOV_PROFILE_MATURITY_V2.ACTIVE)
|
|
256
|
+
c++;
|
|
257
|
+
return c;
|
|
258
|
+
}
|
|
259
|
+
function _stixgovCountPending(profileId) {
|
|
260
|
+
let c = 0;
|
|
261
|
+
for (const j of _stixgovJsV2.values())
|
|
262
|
+
if (
|
|
263
|
+
j.profileId === profileId &&
|
|
264
|
+
(j.status === STIXGOV_PARSE_LIFECYCLE_V2.QUEUED ||
|
|
265
|
+
j.status === STIXGOV_PARSE_LIFECYCLE_V2.PARSING)
|
|
266
|
+
)
|
|
267
|
+
c++;
|
|
268
|
+
return c;
|
|
269
|
+
}
|
|
270
|
+
export function setMaxActiveStixgovProfilesPerOwnerV2(n) {
|
|
271
|
+
_stixgovMaxActive = _stixgovPos(n, "maxActiveStixgovProfilesPerOwner");
|
|
272
|
+
}
|
|
273
|
+
export function getMaxActiveStixgovProfilesPerOwnerV2() {
|
|
274
|
+
return _stixgovMaxActive;
|
|
275
|
+
}
|
|
276
|
+
export function setMaxPendingStixgovParsesPerProfileV2(n) {
|
|
277
|
+
_stixgovMaxPending = _stixgovPos(n, "maxPendingStixgovParsesPerProfile");
|
|
278
|
+
}
|
|
279
|
+
export function getMaxPendingStixgovParsesPerProfileV2() {
|
|
280
|
+
return _stixgovMaxPending;
|
|
281
|
+
}
|
|
282
|
+
export function setStixgovProfileIdleMsV2(n) {
|
|
283
|
+
_stixgovIdleMs = _stixgovPos(n, "stixgovProfileIdleMs");
|
|
284
|
+
}
|
|
285
|
+
export function getStixgovProfileIdleMsV2() {
|
|
286
|
+
return _stixgovIdleMs;
|
|
287
|
+
}
|
|
288
|
+
export function setStixgovParseStuckMsV2(n) {
|
|
289
|
+
_stixgovStuckMs = _stixgovPos(n, "stixgovParseStuckMs");
|
|
290
|
+
}
|
|
291
|
+
export function getStixgovParseStuckMsV2() {
|
|
292
|
+
return _stixgovStuckMs;
|
|
293
|
+
}
|
|
294
|
+
export function _resetStateStixParserGovV2() {
|
|
295
|
+
_stixgovPsV2.clear();
|
|
296
|
+
_stixgovJsV2.clear();
|
|
297
|
+
_stixgovMaxActive = 6;
|
|
298
|
+
_stixgovMaxPending = 15;
|
|
299
|
+
_stixgovIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
300
|
+
_stixgovStuckMs = 60 * 1000;
|
|
301
|
+
}
|
|
302
|
+
export function registerStixgovProfileV2({
|
|
303
|
+
id,
|
|
304
|
+
owner,
|
|
305
|
+
stixVersion,
|
|
306
|
+
metadata,
|
|
307
|
+
} = {}) {
|
|
308
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
309
|
+
if (_stixgovPsV2.has(id))
|
|
310
|
+
throw new Error(`stixgov profile ${id} already exists`);
|
|
311
|
+
const now = Date.now();
|
|
312
|
+
const p = {
|
|
313
|
+
id,
|
|
314
|
+
owner,
|
|
315
|
+
stixVersion: stixVersion || "2.1",
|
|
316
|
+
status: STIXGOV_PROFILE_MATURITY_V2.PENDING,
|
|
317
|
+
createdAt: now,
|
|
318
|
+
updatedAt: now,
|
|
319
|
+
lastTouchedAt: now,
|
|
320
|
+
activatedAt: null,
|
|
321
|
+
archivedAt: null,
|
|
322
|
+
metadata: { ...(metadata || {}) },
|
|
323
|
+
};
|
|
324
|
+
_stixgovPsV2.set(id, p);
|
|
325
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
326
|
+
}
|
|
327
|
+
export function activateStixgovProfileV2(id) {
|
|
328
|
+
const p = _stixgovPsV2.get(id);
|
|
329
|
+
if (!p) throw new Error(`stixgov profile ${id} not found`);
|
|
330
|
+
const isInitial = p.status === STIXGOV_PROFILE_MATURITY_V2.PENDING;
|
|
331
|
+
_stixgovCheckP(p.status, STIXGOV_PROFILE_MATURITY_V2.ACTIVE);
|
|
332
|
+
if (isInitial && _stixgovCountActive(p.owner) >= _stixgovMaxActive)
|
|
333
|
+
throw new Error(`max active stixgov profiles for owner ${p.owner} reached`);
|
|
334
|
+
const now = Date.now();
|
|
335
|
+
p.status = STIXGOV_PROFILE_MATURITY_V2.ACTIVE;
|
|
336
|
+
p.updatedAt = now;
|
|
337
|
+
p.lastTouchedAt = now;
|
|
338
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
339
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
340
|
+
}
|
|
341
|
+
export function staleStixgovProfileV2(id) {
|
|
342
|
+
const p = _stixgovPsV2.get(id);
|
|
343
|
+
if (!p) throw new Error(`stixgov profile ${id} not found`);
|
|
344
|
+
_stixgovCheckP(p.status, STIXGOV_PROFILE_MATURITY_V2.STALE);
|
|
345
|
+
p.status = STIXGOV_PROFILE_MATURITY_V2.STALE;
|
|
346
|
+
p.updatedAt = Date.now();
|
|
347
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
348
|
+
}
|
|
349
|
+
export function archiveStixgovProfileV2(id) {
|
|
350
|
+
const p = _stixgovPsV2.get(id);
|
|
351
|
+
if (!p) throw new Error(`stixgov profile ${id} not found`);
|
|
352
|
+
_stixgovCheckP(p.status, STIXGOV_PROFILE_MATURITY_V2.ARCHIVED);
|
|
353
|
+
const now = Date.now();
|
|
354
|
+
p.status = STIXGOV_PROFILE_MATURITY_V2.ARCHIVED;
|
|
355
|
+
p.updatedAt = now;
|
|
356
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
357
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
358
|
+
}
|
|
359
|
+
export function touchStixgovProfileV2(id) {
|
|
360
|
+
const p = _stixgovPsV2.get(id);
|
|
361
|
+
if (!p) throw new Error(`stixgov profile ${id} not found`);
|
|
362
|
+
if (_stixgovPTerminal.has(p.status))
|
|
363
|
+
throw new Error(`cannot touch terminal stixgov profile ${id}`);
|
|
364
|
+
const now = Date.now();
|
|
365
|
+
p.lastTouchedAt = now;
|
|
366
|
+
p.updatedAt = now;
|
|
367
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
368
|
+
}
|
|
369
|
+
export function getStixgovProfileV2(id) {
|
|
370
|
+
const p = _stixgovPsV2.get(id);
|
|
371
|
+
if (!p) return null;
|
|
372
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
373
|
+
}
|
|
374
|
+
export function listStixgovProfilesV2() {
|
|
375
|
+
return [..._stixgovPsV2.values()].map((p) => ({
|
|
376
|
+
...p,
|
|
377
|
+
metadata: { ...p.metadata },
|
|
378
|
+
}));
|
|
379
|
+
}
|
|
380
|
+
export function createStixgovParseV2({
|
|
381
|
+
id,
|
|
382
|
+
profileId,
|
|
383
|
+
bundleId,
|
|
384
|
+
metadata,
|
|
385
|
+
} = {}) {
|
|
386
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
387
|
+
if (_stixgovJsV2.has(id))
|
|
388
|
+
throw new Error(`stixgov parse ${id} already exists`);
|
|
389
|
+
if (!_stixgovPsV2.has(profileId))
|
|
390
|
+
throw new Error(`stixgov profile ${profileId} not found`);
|
|
391
|
+
if (_stixgovCountPending(profileId) >= _stixgovMaxPending)
|
|
392
|
+
throw new Error(
|
|
393
|
+
`max pending stixgov parses for profile ${profileId} reached`,
|
|
394
|
+
);
|
|
395
|
+
const now = Date.now();
|
|
396
|
+
const j = {
|
|
397
|
+
id,
|
|
398
|
+
profileId,
|
|
399
|
+
bundleId: bundleId || "",
|
|
400
|
+
status: STIXGOV_PARSE_LIFECYCLE_V2.QUEUED,
|
|
401
|
+
createdAt: now,
|
|
402
|
+
updatedAt: now,
|
|
403
|
+
startedAt: null,
|
|
404
|
+
settledAt: null,
|
|
405
|
+
metadata: { ...(metadata || {}) },
|
|
406
|
+
};
|
|
407
|
+
_stixgovJsV2.set(id, j);
|
|
408
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
409
|
+
}
|
|
410
|
+
export function parsingStixgovParseV2(id) {
|
|
411
|
+
const j = _stixgovJsV2.get(id);
|
|
412
|
+
if (!j) throw new Error(`stixgov parse ${id} not found`);
|
|
413
|
+
_stixgovCheckJ(j.status, STIXGOV_PARSE_LIFECYCLE_V2.PARSING);
|
|
414
|
+
const now = Date.now();
|
|
415
|
+
j.status = STIXGOV_PARSE_LIFECYCLE_V2.PARSING;
|
|
416
|
+
j.updatedAt = now;
|
|
417
|
+
if (!j.startedAt) j.startedAt = now;
|
|
418
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
419
|
+
}
|
|
420
|
+
export function completeParseStixgovV2(id) {
|
|
421
|
+
const j = _stixgovJsV2.get(id);
|
|
422
|
+
if (!j) throw new Error(`stixgov parse ${id} not found`);
|
|
423
|
+
_stixgovCheckJ(j.status, STIXGOV_PARSE_LIFECYCLE_V2.PARSED);
|
|
424
|
+
const now = Date.now();
|
|
425
|
+
j.status = STIXGOV_PARSE_LIFECYCLE_V2.PARSED;
|
|
426
|
+
j.updatedAt = now;
|
|
427
|
+
if (!j.settledAt) j.settledAt = now;
|
|
428
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
429
|
+
}
|
|
430
|
+
export function failStixgovParseV2(id, reason) {
|
|
431
|
+
const j = _stixgovJsV2.get(id);
|
|
432
|
+
if (!j) throw new Error(`stixgov parse ${id} not found`);
|
|
433
|
+
_stixgovCheckJ(j.status, STIXGOV_PARSE_LIFECYCLE_V2.FAILED);
|
|
434
|
+
const now = Date.now();
|
|
435
|
+
j.status = STIXGOV_PARSE_LIFECYCLE_V2.FAILED;
|
|
436
|
+
j.updatedAt = now;
|
|
437
|
+
if (!j.settledAt) j.settledAt = now;
|
|
438
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
439
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
440
|
+
}
|
|
441
|
+
export function cancelStixgovParseV2(id, reason) {
|
|
442
|
+
const j = _stixgovJsV2.get(id);
|
|
443
|
+
if (!j) throw new Error(`stixgov parse ${id} not found`);
|
|
444
|
+
_stixgovCheckJ(j.status, STIXGOV_PARSE_LIFECYCLE_V2.CANCELLED);
|
|
445
|
+
const now = Date.now();
|
|
446
|
+
j.status = STIXGOV_PARSE_LIFECYCLE_V2.CANCELLED;
|
|
447
|
+
j.updatedAt = now;
|
|
448
|
+
if (!j.settledAt) j.settledAt = now;
|
|
449
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
450
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
451
|
+
}
|
|
452
|
+
export function getStixgovParseV2(id) {
|
|
453
|
+
const j = _stixgovJsV2.get(id);
|
|
454
|
+
if (!j) return null;
|
|
455
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
456
|
+
}
|
|
457
|
+
export function listStixgovParsesV2() {
|
|
458
|
+
return [..._stixgovJsV2.values()].map((j) => ({
|
|
459
|
+
...j,
|
|
460
|
+
metadata: { ...j.metadata },
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
463
|
+
export function autoStaleIdleStixgovProfilesV2({ now } = {}) {
|
|
464
|
+
const t = now ?? Date.now();
|
|
465
|
+
const flipped = [];
|
|
466
|
+
for (const p of _stixgovPsV2.values())
|
|
467
|
+
if (
|
|
468
|
+
p.status === STIXGOV_PROFILE_MATURITY_V2.ACTIVE &&
|
|
469
|
+
t - p.lastTouchedAt >= _stixgovIdleMs
|
|
470
|
+
) {
|
|
471
|
+
p.status = STIXGOV_PROFILE_MATURITY_V2.STALE;
|
|
472
|
+
p.updatedAt = t;
|
|
473
|
+
flipped.push(p.id);
|
|
474
|
+
}
|
|
475
|
+
return { flipped, count: flipped.length };
|
|
476
|
+
}
|
|
477
|
+
export function autoFailStuckStixgovParsesV2({ now } = {}) {
|
|
478
|
+
const t = now ?? Date.now();
|
|
479
|
+
const flipped = [];
|
|
480
|
+
for (const j of _stixgovJsV2.values())
|
|
481
|
+
if (
|
|
482
|
+
j.status === STIXGOV_PARSE_LIFECYCLE_V2.PARSING &&
|
|
483
|
+
j.startedAt != null &&
|
|
484
|
+
t - j.startedAt >= _stixgovStuckMs
|
|
485
|
+
) {
|
|
486
|
+
j.status = STIXGOV_PARSE_LIFECYCLE_V2.FAILED;
|
|
487
|
+
j.updatedAt = t;
|
|
488
|
+
if (!j.settledAt) j.settledAt = t;
|
|
489
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
490
|
+
flipped.push(j.id);
|
|
491
|
+
}
|
|
492
|
+
return { flipped, count: flipped.length };
|
|
493
|
+
}
|
|
494
|
+
export function getStixParserGovStatsV2() {
|
|
495
|
+
const profilesByStatus = {};
|
|
496
|
+
for (const v of Object.values(STIXGOV_PROFILE_MATURITY_V2))
|
|
497
|
+
profilesByStatus[v] = 0;
|
|
498
|
+
for (const p of _stixgovPsV2.values()) profilesByStatus[p.status]++;
|
|
499
|
+
const parsesByStatus = {};
|
|
500
|
+
for (const v of Object.values(STIXGOV_PARSE_LIFECYCLE_V2))
|
|
501
|
+
parsesByStatus[v] = 0;
|
|
502
|
+
for (const j of _stixgovJsV2.values()) parsesByStatus[j.status]++;
|
|
503
|
+
return {
|
|
504
|
+
totalStixgovProfilesV2: _stixgovPsV2.size,
|
|
505
|
+
totalStixgovParsesV2: _stixgovJsV2.size,
|
|
506
|
+
maxActiveStixgovProfilesPerOwner: _stixgovMaxActive,
|
|
507
|
+
maxPendingStixgovParsesPerProfile: _stixgovMaxPending,
|
|
508
|
+
stixgovProfileIdleMs: _stixgovIdleMs,
|
|
509
|
+
stixgovParseStuckMs: _stixgovStuckMs,
|
|
510
|
+
profilesByStatus,
|
|
511
|
+
parsesByStatus,
|
|
512
|
+
};
|
|
513
|
+
}
|