chainlesschain 0.132.0 → 0.145.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/package.json +1 -1
- package/src/commands/a2a.js +230 -0
- package/src/commands/activitypub.js +191 -0
- package/src/commands/agent.js +601 -0
- package/src/commands/audit.js +206 -0
- package/src/commands/bi.js +186 -0
- package/src/commands/bm25.js +162 -0
- package/src/commands/browse.js +225 -0
- package/src/commands/ccron.js +178 -0
- package/src/commands/chat.js +207 -0
- package/src/commands/compliance.js +420 -0
- package/src/commands/compt.js +176 -0
- package/src/commands/consol.js +237 -0
- package/src/commands/cowork.js +588 -0
- package/src/commands/crosschain.js +216 -0
- package/src/commands/dao.js +216 -0
- package/src/commands/dlp.js +206 -0
- package/src/commands/economy.js +211 -0
- package/src/commands/evolution.js +209 -0
- package/src/commands/evomap.js +216 -0
- package/src/commands/fflag.js +230 -0
- package/src/commands/git.js +185 -0
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +210 -0
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +178 -0
- package/src/commands/itbudget.js +161 -0
- package/src/commands/kg.js +206 -0
- package/src/commands/lowcode.js +201 -0
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +214 -0
- package/src/commands/mcpscaf.js +153 -0
- package/src/commands/meminj.js +153 -0
- package/src/commands/nostr.js +213 -0
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +156 -0
- package/src/commands/pdfp.js +160 -0
- package/src/commands/perf.js +176 -0
- package/src/commands/perm.js +156 -0
- package/src/commands/pipeline.js +211 -0
- package/src/commands/planmode.js +154 -0
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +166 -0
- package/src/commands/recommend.js +185 -0
- package/src/commands/reputation.js +208 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/seshhook.js +153 -0
- package/src/commands/seshsearch.js +149 -0
- package/src/commands/seshtail.js +152 -0
- package/src/commands/seshu.js +160 -0
- package/src/commands/sganal.js +172 -0
- package/src/commands/siem.js +207 -0
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +154 -0
- package/src/commands/social.js +159 -0
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +157 -0
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +183 -0
- package/src/commands/topiccls.js +158 -0
- package/src/commands/uprof.js +154 -0
- package/src/commands/vcheck.js +172 -0
- package/src/commands/webfetch.js +150 -0
- package/src/commands/zkp.js +218 -0
- package/src/harness/prompt-compressor.js +331 -0
- package/src/index.js +101 -1
- package/src/lib/a2a-protocol.js +373 -0
- package/src/lib/activitypub-bridge.js +343 -0
- package/src/lib/agent-economy.js +358 -0
- package/src/lib/app-builder.js +338 -0
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/autonomous-agent.js +341 -0
- package/src/lib/bi-engine.js +339 -0
- package/src/lib/bm25-search.js +333 -0
- package/src/lib/browser-automation.js +352 -0
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/compliance-framework-reporter.js +359 -0
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +333 -0
- package/src/lib/content-recommender.js +370 -0
- package/src/lib/cowork-cron.js +330 -0
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-task-runner.js +362 -0
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +365 -0
- package/src/lib/dao-governance.js +339 -0
- package/src/lib/dlp-engine.js +343 -0
- package/src/lib/evolution-system.js +336 -0
- package/src/lib/evomap-manager.js +339 -0
- package/src/lib/execution-backend.js +351 -0
- package/src/lib/feature-flags.js +330 -0
- package/src/lib/git-integration.js +343 -0
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +341 -0
- package/src/lib/inference-network.js +362 -0
- package/src/lib/iteration-budget.js +357 -0
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/matrix-bridge.js +339 -0
- package/src/lib/mcp-scaffold.js +345 -0
- package/src/lib/memory-injection.js +320 -0
- package/src/lib/nostr-bridge.js +342 -0
- package/src/lib/orchestrator.js +350 -0
- package/src/lib/pdf-parser.js +330 -0
- package/src/lib/perf-tuning.js +364 -0
- package/src/lib/permission-engine.js +319 -0
- package/src/lib/pipeline-orchestrator.js +345 -0
- package/src/lib/plan-mode.js +328 -0
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/prompt-compressor.js +1 -10
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/service-container.js +342 -0
- package/src/lib/session-consolidator.js +352 -0
- package/src/lib/session-hooks.js +340 -0
- package/src/lib/session-search.js +334 -0
- package/src/lib/session-tail.js +320 -0
- package/src/lib/session-usage.js +329 -0
- package/src/lib/siem-exporter.js +352 -0
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +333 -0
- package/src/lib/social-graph-analytics.js +327 -0
- package/src/lib/social-graph.js +304 -0
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +359 -0
- package/src/lib/task-model-selector.js +333 -0
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/todo-manager.js +339 -0
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/topic-classifier.js +353 -0
- package/src/lib/user-profile.js +325 -0
- package/src/lib/version-checker.js +335 -0
- package/src/lib/web-fetch.js +322 -0
- package/src/lib/zkp-engine.js +342 -0
|
@@ -191,3 +191,337 @@ export class SessionSearchIndex {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
|
+
|
|
195
|
+
// ===== V2 Surface: Session Search governance overlay (CLI v0.142.0) =====
|
|
196
|
+
export const SSCH_PROFILE_MATURITY_V2 = Object.freeze({
|
|
197
|
+
PENDING: "pending",
|
|
198
|
+
ACTIVE: "active",
|
|
199
|
+
STALE: "stale",
|
|
200
|
+
ARCHIVED: "archived",
|
|
201
|
+
});
|
|
202
|
+
export const SSCH_QUERY_LIFECYCLE_V2 = Object.freeze({
|
|
203
|
+
QUEUED: "queued",
|
|
204
|
+
SEARCHING: "searching",
|
|
205
|
+
COMPLETED: "completed",
|
|
206
|
+
FAILED: "failed",
|
|
207
|
+
CANCELLED: "cancelled",
|
|
208
|
+
});
|
|
209
|
+
const _sschPTrans = new Map([
|
|
210
|
+
[
|
|
211
|
+
SSCH_PROFILE_MATURITY_V2.PENDING,
|
|
212
|
+
new Set([
|
|
213
|
+
SSCH_PROFILE_MATURITY_V2.ACTIVE,
|
|
214
|
+
SSCH_PROFILE_MATURITY_V2.ARCHIVED,
|
|
215
|
+
]),
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
SSCH_PROFILE_MATURITY_V2.ACTIVE,
|
|
219
|
+
new Set([
|
|
220
|
+
SSCH_PROFILE_MATURITY_V2.STALE,
|
|
221
|
+
SSCH_PROFILE_MATURITY_V2.ARCHIVED,
|
|
222
|
+
]),
|
|
223
|
+
],
|
|
224
|
+
[
|
|
225
|
+
SSCH_PROFILE_MATURITY_V2.STALE,
|
|
226
|
+
new Set([
|
|
227
|
+
SSCH_PROFILE_MATURITY_V2.ACTIVE,
|
|
228
|
+
SSCH_PROFILE_MATURITY_V2.ARCHIVED,
|
|
229
|
+
]),
|
|
230
|
+
],
|
|
231
|
+
[SSCH_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
232
|
+
]);
|
|
233
|
+
const _sschPTerminal = new Set([SSCH_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
234
|
+
const _sschQTrans = new Map([
|
|
235
|
+
[
|
|
236
|
+
SSCH_QUERY_LIFECYCLE_V2.QUEUED,
|
|
237
|
+
new Set([
|
|
238
|
+
SSCH_QUERY_LIFECYCLE_V2.SEARCHING,
|
|
239
|
+
SSCH_QUERY_LIFECYCLE_V2.CANCELLED,
|
|
240
|
+
]),
|
|
241
|
+
],
|
|
242
|
+
[
|
|
243
|
+
SSCH_QUERY_LIFECYCLE_V2.SEARCHING,
|
|
244
|
+
new Set([
|
|
245
|
+
SSCH_QUERY_LIFECYCLE_V2.COMPLETED,
|
|
246
|
+
SSCH_QUERY_LIFECYCLE_V2.FAILED,
|
|
247
|
+
SSCH_QUERY_LIFECYCLE_V2.CANCELLED,
|
|
248
|
+
]),
|
|
249
|
+
],
|
|
250
|
+
[SSCH_QUERY_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
251
|
+
[SSCH_QUERY_LIFECYCLE_V2.FAILED, new Set()],
|
|
252
|
+
[SSCH_QUERY_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
253
|
+
]);
|
|
254
|
+
const _sschPsV2 = new Map();
|
|
255
|
+
const _sschQsV2 = new Map();
|
|
256
|
+
let _sschMaxActive = 8,
|
|
257
|
+
_sschMaxPending = 20,
|
|
258
|
+
_sschIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
259
|
+
_sschStuckMs = 30 * 1000;
|
|
260
|
+
function _sschPos(n, label) {
|
|
261
|
+
const v = Math.floor(Number(n));
|
|
262
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
263
|
+
throw new Error(`${label} must be positive integer`);
|
|
264
|
+
return v;
|
|
265
|
+
}
|
|
266
|
+
function _sschCheckP(from, to) {
|
|
267
|
+
const a = _sschPTrans.get(from);
|
|
268
|
+
if (!a || !a.has(to))
|
|
269
|
+
throw new Error(`invalid ssch profile transition ${from} → ${to}`);
|
|
270
|
+
}
|
|
271
|
+
function _sschCheckQ(from, to) {
|
|
272
|
+
const a = _sschQTrans.get(from);
|
|
273
|
+
if (!a || !a.has(to))
|
|
274
|
+
throw new Error(`invalid ssch query transition ${from} → ${to}`);
|
|
275
|
+
}
|
|
276
|
+
export function setMaxActiveSschProfilesPerOwnerV2(n) {
|
|
277
|
+
_sschMaxActive = _sschPos(n, "maxActiveSschProfilesPerOwner");
|
|
278
|
+
}
|
|
279
|
+
export function getMaxActiveSschProfilesPerOwnerV2() {
|
|
280
|
+
return _sschMaxActive;
|
|
281
|
+
}
|
|
282
|
+
export function setMaxPendingSschQueriesPerProfileV2(n) {
|
|
283
|
+
_sschMaxPending = _sschPos(n, "maxPendingSschQueriesPerProfile");
|
|
284
|
+
}
|
|
285
|
+
export function getMaxPendingSschQueriesPerProfileV2() {
|
|
286
|
+
return _sschMaxPending;
|
|
287
|
+
}
|
|
288
|
+
export function setSschProfileIdleMsV2(n) {
|
|
289
|
+
_sschIdleMs = _sschPos(n, "sschProfileIdleMs");
|
|
290
|
+
}
|
|
291
|
+
export function getSschProfileIdleMsV2() {
|
|
292
|
+
return _sschIdleMs;
|
|
293
|
+
}
|
|
294
|
+
export function setSschQueryStuckMsV2(n) {
|
|
295
|
+
_sschStuckMs = _sschPos(n, "sschQueryStuckMs");
|
|
296
|
+
}
|
|
297
|
+
export function getSschQueryStuckMsV2() {
|
|
298
|
+
return _sschStuckMs;
|
|
299
|
+
}
|
|
300
|
+
export function _resetStateSessionSearchV2() {
|
|
301
|
+
_sschPsV2.clear();
|
|
302
|
+
_sschQsV2.clear();
|
|
303
|
+
_sschMaxActive = 8;
|
|
304
|
+
_sschMaxPending = 20;
|
|
305
|
+
_sschIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
306
|
+
_sschStuckMs = 30 * 1000;
|
|
307
|
+
}
|
|
308
|
+
export function registerSschProfileV2({ id, owner, scope, metadata } = {}) {
|
|
309
|
+
if (!id) throw new Error("ssch profile id required");
|
|
310
|
+
if (!owner) throw new Error("ssch profile owner required");
|
|
311
|
+
if (_sschPsV2.has(id))
|
|
312
|
+
throw new Error(`ssch profile ${id} already registered`);
|
|
313
|
+
const now = Date.now();
|
|
314
|
+
const p = {
|
|
315
|
+
id,
|
|
316
|
+
owner,
|
|
317
|
+
scope: scope || "all",
|
|
318
|
+
status: SSCH_PROFILE_MATURITY_V2.PENDING,
|
|
319
|
+
createdAt: now,
|
|
320
|
+
updatedAt: now,
|
|
321
|
+
activatedAt: null,
|
|
322
|
+
archivedAt: null,
|
|
323
|
+
lastTouchedAt: now,
|
|
324
|
+
metadata: { ...(metadata || {}) },
|
|
325
|
+
};
|
|
326
|
+
_sschPsV2.set(id, p);
|
|
327
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
328
|
+
}
|
|
329
|
+
function _sschCountActive(owner) {
|
|
330
|
+
let n = 0;
|
|
331
|
+
for (const p of _sschPsV2.values())
|
|
332
|
+
if (p.owner === owner && p.status === SSCH_PROFILE_MATURITY_V2.ACTIVE) n++;
|
|
333
|
+
return n;
|
|
334
|
+
}
|
|
335
|
+
export function activateSschProfileV2(id) {
|
|
336
|
+
const p = _sschPsV2.get(id);
|
|
337
|
+
if (!p) throw new Error(`ssch profile ${id} not found`);
|
|
338
|
+
_sschCheckP(p.status, SSCH_PROFILE_MATURITY_V2.ACTIVE);
|
|
339
|
+
const recovery = p.status === SSCH_PROFILE_MATURITY_V2.STALE;
|
|
340
|
+
if (!recovery && _sschCountActive(p.owner) >= _sschMaxActive)
|
|
341
|
+
throw new Error(`max active ssch profiles for owner ${p.owner} reached`);
|
|
342
|
+
const now = Date.now();
|
|
343
|
+
p.status = SSCH_PROFILE_MATURITY_V2.ACTIVE;
|
|
344
|
+
p.updatedAt = now;
|
|
345
|
+
p.lastTouchedAt = now;
|
|
346
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
347
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
348
|
+
}
|
|
349
|
+
export function staleSschProfileV2(id) {
|
|
350
|
+
const p = _sschPsV2.get(id);
|
|
351
|
+
if (!p) throw new Error(`ssch profile ${id} not found`);
|
|
352
|
+
_sschCheckP(p.status, SSCH_PROFILE_MATURITY_V2.STALE);
|
|
353
|
+
p.status = SSCH_PROFILE_MATURITY_V2.STALE;
|
|
354
|
+
p.updatedAt = Date.now();
|
|
355
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
356
|
+
}
|
|
357
|
+
export function archiveSschProfileV2(id) {
|
|
358
|
+
const p = _sschPsV2.get(id);
|
|
359
|
+
if (!p) throw new Error(`ssch profile ${id} not found`);
|
|
360
|
+
_sschCheckP(p.status, SSCH_PROFILE_MATURITY_V2.ARCHIVED);
|
|
361
|
+
const now = Date.now();
|
|
362
|
+
p.status = SSCH_PROFILE_MATURITY_V2.ARCHIVED;
|
|
363
|
+
p.updatedAt = now;
|
|
364
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
365
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
366
|
+
}
|
|
367
|
+
export function touchSschProfileV2(id) {
|
|
368
|
+
const p = _sschPsV2.get(id);
|
|
369
|
+
if (!p) throw new Error(`ssch profile ${id} not found`);
|
|
370
|
+
if (_sschPTerminal.has(p.status))
|
|
371
|
+
throw new Error(`cannot touch terminal ssch profile ${id}`);
|
|
372
|
+
const now = Date.now();
|
|
373
|
+
p.lastTouchedAt = now;
|
|
374
|
+
p.updatedAt = now;
|
|
375
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
376
|
+
}
|
|
377
|
+
export function getSschProfileV2(id) {
|
|
378
|
+
const p = _sschPsV2.get(id);
|
|
379
|
+
if (!p) return null;
|
|
380
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
381
|
+
}
|
|
382
|
+
export function listSschProfilesV2() {
|
|
383
|
+
return [..._sschPsV2.values()].map((p) => ({
|
|
384
|
+
...p,
|
|
385
|
+
metadata: { ...p.metadata },
|
|
386
|
+
}));
|
|
387
|
+
}
|
|
388
|
+
function _sschCountPending(profileId) {
|
|
389
|
+
let n = 0;
|
|
390
|
+
for (const q of _sschQsV2.values())
|
|
391
|
+
if (
|
|
392
|
+
q.profileId === profileId &&
|
|
393
|
+
(q.status === SSCH_QUERY_LIFECYCLE_V2.QUEUED ||
|
|
394
|
+
q.status === SSCH_QUERY_LIFECYCLE_V2.SEARCHING)
|
|
395
|
+
)
|
|
396
|
+
n++;
|
|
397
|
+
return n;
|
|
398
|
+
}
|
|
399
|
+
export function createSschQueryV2({ id, profileId, q, metadata } = {}) {
|
|
400
|
+
if (!id) throw new Error("ssch query id required");
|
|
401
|
+
if (!profileId) throw new Error("ssch query profileId required");
|
|
402
|
+
if (_sschQsV2.has(id)) throw new Error(`ssch query ${id} already exists`);
|
|
403
|
+
if (!_sschPsV2.has(profileId))
|
|
404
|
+
throw new Error(`ssch profile ${profileId} not found`);
|
|
405
|
+
if (_sschCountPending(profileId) >= _sschMaxPending)
|
|
406
|
+
throw new Error(
|
|
407
|
+
`max pending ssch queries for profile ${profileId} reached`,
|
|
408
|
+
);
|
|
409
|
+
const now = Date.now();
|
|
410
|
+
const r = {
|
|
411
|
+
id,
|
|
412
|
+
profileId,
|
|
413
|
+
q: q || "",
|
|
414
|
+
status: SSCH_QUERY_LIFECYCLE_V2.QUEUED,
|
|
415
|
+
createdAt: now,
|
|
416
|
+
updatedAt: now,
|
|
417
|
+
startedAt: null,
|
|
418
|
+
settledAt: null,
|
|
419
|
+
metadata: { ...(metadata || {}) },
|
|
420
|
+
};
|
|
421
|
+
_sschQsV2.set(id, r);
|
|
422
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
423
|
+
}
|
|
424
|
+
export function searchingSschQueryV2(id) {
|
|
425
|
+
const r = _sschQsV2.get(id);
|
|
426
|
+
if (!r) throw new Error(`ssch query ${id} not found`);
|
|
427
|
+
_sschCheckQ(r.status, SSCH_QUERY_LIFECYCLE_V2.SEARCHING);
|
|
428
|
+
const now = Date.now();
|
|
429
|
+
r.status = SSCH_QUERY_LIFECYCLE_V2.SEARCHING;
|
|
430
|
+
r.updatedAt = now;
|
|
431
|
+
if (!r.startedAt) r.startedAt = now;
|
|
432
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
433
|
+
}
|
|
434
|
+
export function completeSschQueryV2(id) {
|
|
435
|
+
const r = _sschQsV2.get(id);
|
|
436
|
+
if (!r) throw new Error(`ssch query ${id} not found`);
|
|
437
|
+
_sschCheckQ(r.status, SSCH_QUERY_LIFECYCLE_V2.COMPLETED);
|
|
438
|
+
const now = Date.now();
|
|
439
|
+
r.status = SSCH_QUERY_LIFECYCLE_V2.COMPLETED;
|
|
440
|
+
r.updatedAt = now;
|
|
441
|
+
if (!r.settledAt) r.settledAt = now;
|
|
442
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
443
|
+
}
|
|
444
|
+
export function failSschQueryV2(id, reason) {
|
|
445
|
+
const r = _sschQsV2.get(id);
|
|
446
|
+
if (!r) throw new Error(`ssch query ${id} not found`);
|
|
447
|
+
_sschCheckQ(r.status, SSCH_QUERY_LIFECYCLE_V2.FAILED);
|
|
448
|
+
const now = Date.now();
|
|
449
|
+
r.status = SSCH_QUERY_LIFECYCLE_V2.FAILED;
|
|
450
|
+
r.updatedAt = now;
|
|
451
|
+
if (!r.settledAt) r.settledAt = now;
|
|
452
|
+
if (reason) r.metadata.failReason = String(reason);
|
|
453
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
454
|
+
}
|
|
455
|
+
export function cancelSschQueryV2(id, reason) {
|
|
456
|
+
const r = _sschQsV2.get(id);
|
|
457
|
+
if (!r) throw new Error(`ssch query ${id} not found`);
|
|
458
|
+
_sschCheckQ(r.status, SSCH_QUERY_LIFECYCLE_V2.CANCELLED);
|
|
459
|
+
const now = Date.now();
|
|
460
|
+
r.status = SSCH_QUERY_LIFECYCLE_V2.CANCELLED;
|
|
461
|
+
r.updatedAt = now;
|
|
462
|
+
if (!r.settledAt) r.settledAt = now;
|
|
463
|
+
if (reason) r.metadata.cancelReason = String(reason);
|
|
464
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
465
|
+
}
|
|
466
|
+
export function getSschQueryV2(id) {
|
|
467
|
+
const r = _sschQsV2.get(id);
|
|
468
|
+
if (!r) return null;
|
|
469
|
+
return { ...r, metadata: { ...r.metadata } };
|
|
470
|
+
}
|
|
471
|
+
export function listSschQueriesV2() {
|
|
472
|
+
return [..._sschQsV2.values()].map((r) => ({
|
|
473
|
+
...r,
|
|
474
|
+
metadata: { ...r.metadata },
|
|
475
|
+
}));
|
|
476
|
+
}
|
|
477
|
+
export function autoStaleIdleSschProfilesV2({ now } = {}) {
|
|
478
|
+
const t = now ?? Date.now();
|
|
479
|
+
const flipped = [];
|
|
480
|
+
for (const p of _sschPsV2.values())
|
|
481
|
+
if (
|
|
482
|
+
p.status === SSCH_PROFILE_MATURITY_V2.ACTIVE &&
|
|
483
|
+
t - p.lastTouchedAt >= _sschIdleMs
|
|
484
|
+
) {
|
|
485
|
+
p.status = SSCH_PROFILE_MATURITY_V2.STALE;
|
|
486
|
+
p.updatedAt = t;
|
|
487
|
+
flipped.push(p.id);
|
|
488
|
+
}
|
|
489
|
+
return { flipped, count: flipped.length };
|
|
490
|
+
}
|
|
491
|
+
export function autoFailStuckSschQueriesV2({ now } = {}) {
|
|
492
|
+
const t = now ?? Date.now();
|
|
493
|
+
const flipped = [];
|
|
494
|
+
for (const r of _sschQsV2.values())
|
|
495
|
+
if (
|
|
496
|
+
r.status === SSCH_QUERY_LIFECYCLE_V2.SEARCHING &&
|
|
497
|
+
r.startedAt != null &&
|
|
498
|
+
t - r.startedAt >= _sschStuckMs
|
|
499
|
+
) {
|
|
500
|
+
r.status = SSCH_QUERY_LIFECYCLE_V2.FAILED;
|
|
501
|
+
r.updatedAt = t;
|
|
502
|
+
if (!r.settledAt) r.settledAt = t;
|
|
503
|
+
r.metadata.failReason = "auto-fail-stuck";
|
|
504
|
+
flipped.push(r.id);
|
|
505
|
+
}
|
|
506
|
+
return { flipped, count: flipped.length };
|
|
507
|
+
}
|
|
508
|
+
export function getSessionSearchGovStatsV2() {
|
|
509
|
+
const profilesByStatus = {};
|
|
510
|
+
for (const v of Object.values(SSCH_PROFILE_MATURITY_V2))
|
|
511
|
+
profilesByStatus[v] = 0;
|
|
512
|
+
for (const p of _sschPsV2.values()) profilesByStatus[p.status]++;
|
|
513
|
+
const queriesByStatus = {};
|
|
514
|
+
for (const v of Object.values(SSCH_QUERY_LIFECYCLE_V2))
|
|
515
|
+
queriesByStatus[v] = 0;
|
|
516
|
+
for (const r of _sschQsV2.values()) queriesByStatus[r.status]++;
|
|
517
|
+
return {
|
|
518
|
+
totalSschProfilesV2: _sschPsV2.size,
|
|
519
|
+
totalSschQueriesV2: _sschQsV2.size,
|
|
520
|
+
maxActiveSschProfilesPerOwner: _sschMaxActive,
|
|
521
|
+
maxPendingSschQueriesPerProfile: _sschMaxPending,
|
|
522
|
+
sschProfileIdleMs: _sschIdleMs,
|
|
523
|
+
sschQueryStuckMs: _sschStuckMs,
|
|
524
|
+
profilesByStatus,
|
|
525
|
+
queriesByStatus,
|
|
526
|
+
};
|
|
527
|
+
}
|
package/src/lib/session-tail.js
CHANGED
|
@@ -126,3 +126,323 @@ export async function* followSession(sessionId, options = {}) {
|
|
|
126
126
|
await new Promise((r) => setTimeout(r, pollMs));
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
|
+
|
|
130
|
+
// ===== V2 Surface: Session Tail governance overlay (CLI v0.142.0) =====
|
|
131
|
+
export const STAIL_SUB_MATURITY_V2 = Object.freeze({
|
|
132
|
+
PENDING: "pending",
|
|
133
|
+
ACTIVE: "active",
|
|
134
|
+
PAUSED: "paused",
|
|
135
|
+
CLOSED: "closed",
|
|
136
|
+
});
|
|
137
|
+
export const STAIL_EVENT_LIFECYCLE_V2 = Object.freeze({
|
|
138
|
+
QUEUED: "queued",
|
|
139
|
+
TAILING: "tailing",
|
|
140
|
+
COMPLETED: "completed",
|
|
141
|
+
FAILED: "failed",
|
|
142
|
+
CANCELLED: "cancelled",
|
|
143
|
+
});
|
|
144
|
+
const _stailSTrans = new Map([
|
|
145
|
+
[
|
|
146
|
+
STAIL_SUB_MATURITY_V2.PENDING,
|
|
147
|
+
new Set([STAIL_SUB_MATURITY_V2.ACTIVE, STAIL_SUB_MATURITY_V2.CLOSED]),
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
STAIL_SUB_MATURITY_V2.ACTIVE,
|
|
151
|
+
new Set([STAIL_SUB_MATURITY_V2.PAUSED, STAIL_SUB_MATURITY_V2.CLOSED]),
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
STAIL_SUB_MATURITY_V2.PAUSED,
|
|
155
|
+
new Set([STAIL_SUB_MATURITY_V2.ACTIVE, STAIL_SUB_MATURITY_V2.CLOSED]),
|
|
156
|
+
],
|
|
157
|
+
[STAIL_SUB_MATURITY_V2.CLOSED, new Set()],
|
|
158
|
+
]);
|
|
159
|
+
const _stailSTerminal = new Set([STAIL_SUB_MATURITY_V2.CLOSED]);
|
|
160
|
+
const _stailETrans = new Map([
|
|
161
|
+
[
|
|
162
|
+
STAIL_EVENT_LIFECYCLE_V2.QUEUED,
|
|
163
|
+
new Set([
|
|
164
|
+
STAIL_EVENT_LIFECYCLE_V2.TAILING,
|
|
165
|
+
STAIL_EVENT_LIFECYCLE_V2.CANCELLED,
|
|
166
|
+
]),
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
STAIL_EVENT_LIFECYCLE_V2.TAILING,
|
|
170
|
+
new Set([
|
|
171
|
+
STAIL_EVENT_LIFECYCLE_V2.COMPLETED,
|
|
172
|
+
STAIL_EVENT_LIFECYCLE_V2.FAILED,
|
|
173
|
+
STAIL_EVENT_LIFECYCLE_V2.CANCELLED,
|
|
174
|
+
]),
|
|
175
|
+
],
|
|
176
|
+
[STAIL_EVENT_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
177
|
+
[STAIL_EVENT_LIFECYCLE_V2.FAILED, new Set()],
|
|
178
|
+
[STAIL_EVENT_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
179
|
+
]);
|
|
180
|
+
const _stailSsV2 = new Map();
|
|
181
|
+
const _stailEsV2 = new Map();
|
|
182
|
+
let _stailMaxActive = 10,
|
|
183
|
+
_stailMaxPending = 30,
|
|
184
|
+
_stailIdleMs = 24 * 60 * 60 * 1000,
|
|
185
|
+
_stailStuckMs = 60 * 1000;
|
|
186
|
+
function _stailPos(n, label) {
|
|
187
|
+
const v = Math.floor(Number(n));
|
|
188
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
189
|
+
throw new Error(`${label} must be positive integer`);
|
|
190
|
+
return v;
|
|
191
|
+
}
|
|
192
|
+
function _stailCheckS(from, to) {
|
|
193
|
+
const a = _stailSTrans.get(from);
|
|
194
|
+
if (!a || !a.has(to))
|
|
195
|
+
throw new Error(`invalid stail subscription transition ${from} → ${to}`);
|
|
196
|
+
}
|
|
197
|
+
function _stailCheckE(from, to) {
|
|
198
|
+
const a = _stailETrans.get(from);
|
|
199
|
+
if (!a || !a.has(to))
|
|
200
|
+
throw new Error(`invalid stail event transition ${from} → ${to}`);
|
|
201
|
+
}
|
|
202
|
+
export function setMaxActiveStailSubsPerOwnerV2(n) {
|
|
203
|
+
_stailMaxActive = _stailPos(n, "maxActiveStailSubsPerOwner");
|
|
204
|
+
}
|
|
205
|
+
export function getMaxActiveStailSubsPerOwnerV2() {
|
|
206
|
+
return _stailMaxActive;
|
|
207
|
+
}
|
|
208
|
+
export function setMaxPendingStailEventsPerSubV2(n) {
|
|
209
|
+
_stailMaxPending = _stailPos(n, "maxPendingStailEventsPerSub");
|
|
210
|
+
}
|
|
211
|
+
export function getMaxPendingStailEventsPerSubV2() {
|
|
212
|
+
return _stailMaxPending;
|
|
213
|
+
}
|
|
214
|
+
export function setStailSubIdleMsV2(n) {
|
|
215
|
+
_stailIdleMs = _stailPos(n, "stailSubIdleMs");
|
|
216
|
+
}
|
|
217
|
+
export function getStailSubIdleMsV2() {
|
|
218
|
+
return _stailIdleMs;
|
|
219
|
+
}
|
|
220
|
+
export function setStailEventStuckMsV2(n) {
|
|
221
|
+
_stailStuckMs = _stailPos(n, "stailEventStuckMs");
|
|
222
|
+
}
|
|
223
|
+
export function getStailEventStuckMsV2() {
|
|
224
|
+
return _stailStuckMs;
|
|
225
|
+
}
|
|
226
|
+
export function _resetStateSessionTailV2() {
|
|
227
|
+
_stailSsV2.clear();
|
|
228
|
+
_stailEsV2.clear();
|
|
229
|
+
_stailMaxActive = 10;
|
|
230
|
+
_stailMaxPending = 30;
|
|
231
|
+
_stailIdleMs = 24 * 60 * 60 * 1000;
|
|
232
|
+
_stailStuckMs = 60 * 1000;
|
|
233
|
+
}
|
|
234
|
+
export function registerStailSubV2({ id, owner, sessionId, metadata } = {}) {
|
|
235
|
+
if (!id) throw new Error("stail sub id required");
|
|
236
|
+
if (!owner) throw new Error("stail sub owner required");
|
|
237
|
+
if (_stailSsV2.has(id)) throw new Error(`stail sub ${id} already registered`);
|
|
238
|
+
const now = Date.now();
|
|
239
|
+
const s = {
|
|
240
|
+
id,
|
|
241
|
+
owner,
|
|
242
|
+
sessionId: sessionId || "*",
|
|
243
|
+
status: STAIL_SUB_MATURITY_V2.PENDING,
|
|
244
|
+
createdAt: now,
|
|
245
|
+
updatedAt: now,
|
|
246
|
+
activatedAt: null,
|
|
247
|
+
closedAt: null,
|
|
248
|
+
lastTouchedAt: now,
|
|
249
|
+
metadata: { ...(metadata || {}) },
|
|
250
|
+
};
|
|
251
|
+
_stailSsV2.set(id, s);
|
|
252
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
253
|
+
}
|
|
254
|
+
function _stailCountActive(owner) {
|
|
255
|
+
let n = 0;
|
|
256
|
+
for (const s of _stailSsV2.values())
|
|
257
|
+
if (s.owner === owner && s.status === STAIL_SUB_MATURITY_V2.ACTIVE) n++;
|
|
258
|
+
return n;
|
|
259
|
+
}
|
|
260
|
+
export function activateStailSubV2(id) {
|
|
261
|
+
const s = _stailSsV2.get(id);
|
|
262
|
+
if (!s) throw new Error(`stail sub ${id} not found`);
|
|
263
|
+
_stailCheckS(s.status, STAIL_SUB_MATURITY_V2.ACTIVE);
|
|
264
|
+
const recovery = s.status === STAIL_SUB_MATURITY_V2.PAUSED;
|
|
265
|
+
if (!recovery && _stailCountActive(s.owner) >= _stailMaxActive)
|
|
266
|
+
throw new Error(`max active stail subs for owner ${s.owner} reached`);
|
|
267
|
+
const now = Date.now();
|
|
268
|
+
s.status = STAIL_SUB_MATURITY_V2.ACTIVE;
|
|
269
|
+
s.updatedAt = now;
|
|
270
|
+
s.lastTouchedAt = now;
|
|
271
|
+
if (!s.activatedAt) s.activatedAt = now;
|
|
272
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
273
|
+
}
|
|
274
|
+
export function pauseStailSubV2(id) {
|
|
275
|
+
const s = _stailSsV2.get(id);
|
|
276
|
+
if (!s) throw new Error(`stail sub ${id} not found`);
|
|
277
|
+
_stailCheckS(s.status, STAIL_SUB_MATURITY_V2.PAUSED);
|
|
278
|
+
s.status = STAIL_SUB_MATURITY_V2.PAUSED;
|
|
279
|
+
s.updatedAt = Date.now();
|
|
280
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
281
|
+
}
|
|
282
|
+
export function closeStailSubV2(id) {
|
|
283
|
+
const s = _stailSsV2.get(id);
|
|
284
|
+
if (!s) throw new Error(`stail sub ${id} not found`);
|
|
285
|
+
_stailCheckS(s.status, STAIL_SUB_MATURITY_V2.CLOSED);
|
|
286
|
+
const now = Date.now();
|
|
287
|
+
s.status = STAIL_SUB_MATURITY_V2.CLOSED;
|
|
288
|
+
s.updatedAt = now;
|
|
289
|
+
if (!s.closedAt) s.closedAt = now;
|
|
290
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
291
|
+
}
|
|
292
|
+
export function touchStailSubV2(id) {
|
|
293
|
+
const s = _stailSsV2.get(id);
|
|
294
|
+
if (!s) throw new Error(`stail sub ${id} not found`);
|
|
295
|
+
if (_stailSTerminal.has(s.status))
|
|
296
|
+
throw new Error(`cannot touch terminal stail sub ${id}`);
|
|
297
|
+
const now = Date.now();
|
|
298
|
+
s.lastTouchedAt = now;
|
|
299
|
+
s.updatedAt = now;
|
|
300
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
301
|
+
}
|
|
302
|
+
export function getStailSubV2(id) {
|
|
303
|
+
const s = _stailSsV2.get(id);
|
|
304
|
+
if (!s) return null;
|
|
305
|
+
return { ...s, metadata: { ...s.metadata } };
|
|
306
|
+
}
|
|
307
|
+
export function listStailSubsV2() {
|
|
308
|
+
return [..._stailSsV2.values()].map((s) => ({
|
|
309
|
+
...s,
|
|
310
|
+
metadata: { ...s.metadata },
|
|
311
|
+
}));
|
|
312
|
+
}
|
|
313
|
+
function _stailCountPending(subId) {
|
|
314
|
+
let n = 0;
|
|
315
|
+
for (const e of _stailEsV2.values())
|
|
316
|
+
if (
|
|
317
|
+
e.subId === subId &&
|
|
318
|
+
(e.status === STAIL_EVENT_LIFECYCLE_V2.QUEUED ||
|
|
319
|
+
e.status === STAIL_EVENT_LIFECYCLE_V2.TAILING)
|
|
320
|
+
)
|
|
321
|
+
n++;
|
|
322
|
+
return n;
|
|
323
|
+
}
|
|
324
|
+
export function createStailEventV2({ id, subId, cursor, metadata } = {}) {
|
|
325
|
+
if (!id) throw new Error("stail event id required");
|
|
326
|
+
if (!subId) throw new Error("stail event subId required");
|
|
327
|
+
if (_stailEsV2.has(id)) throw new Error(`stail event ${id} already exists`);
|
|
328
|
+
if (!_stailSsV2.has(subId)) throw new Error(`stail sub ${subId} not found`);
|
|
329
|
+
if (_stailCountPending(subId) >= _stailMaxPending)
|
|
330
|
+
throw new Error(`max pending stail events for sub ${subId} reached`);
|
|
331
|
+
const now = Date.now();
|
|
332
|
+
const e = {
|
|
333
|
+
id,
|
|
334
|
+
subId,
|
|
335
|
+
cursor: cursor || "0",
|
|
336
|
+
status: STAIL_EVENT_LIFECYCLE_V2.QUEUED,
|
|
337
|
+
createdAt: now,
|
|
338
|
+
updatedAt: now,
|
|
339
|
+
startedAt: null,
|
|
340
|
+
settledAt: null,
|
|
341
|
+
metadata: { ...(metadata || {}) },
|
|
342
|
+
};
|
|
343
|
+
_stailEsV2.set(id, e);
|
|
344
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
345
|
+
}
|
|
346
|
+
export function tailingStailEventV2(id) {
|
|
347
|
+
const e = _stailEsV2.get(id);
|
|
348
|
+
if (!e) throw new Error(`stail event ${id} not found`);
|
|
349
|
+
_stailCheckE(e.status, STAIL_EVENT_LIFECYCLE_V2.TAILING);
|
|
350
|
+
const now = Date.now();
|
|
351
|
+
e.status = STAIL_EVENT_LIFECYCLE_V2.TAILING;
|
|
352
|
+
e.updatedAt = now;
|
|
353
|
+
if (!e.startedAt) e.startedAt = now;
|
|
354
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
355
|
+
}
|
|
356
|
+
export function completeStailEventV2(id) {
|
|
357
|
+
const e = _stailEsV2.get(id);
|
|
358
|
+
if (!e) throw new Error(`stail event ${id} not found`);
|
|
359
|
+
_stailCheckE(e.status, STAIL_EVENT_LIFECYCLE_V2.COMPLETED);
|
|
360
|
+
const now = Date.now();
|
|
361
|
+
e.status = STAIL_EVENT_LIFECYCLE_V2.COMPLETED;
|
|
362
|
+
e.updatedAt = now;
|
|
363
|
+
if (!e.settledAt) e.settledAt = now;
|
|
364
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
365
|
+
}
|
|
366
|
+
export function failStailEventV2(id, reason) {
|
|
367
|
+
const e = _stailEsV2.get(id);
|
|
368
|
+
if (!e) throw new Error(`stail event ${id} not found`);
|
|
369
|
+
_stailCheckE(e.status, STAIL_EVENT_LIFECYCLE_V2.FAILED);
|
|
370
|
+
const now = Date.now();
|
|
371
|
+
e.status = STAIL_EVENT_LIFECYCLE_V2.FAILED;
|
|
372
|
+
e.updatedAt = now;
|
|
373
|
+
if (!e.settledAt) e.settledAt = now;
|
|
374
|
+
if (reason) e.metadata.failReason = String(reason);
|
|
375
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
376
|
+
}
|
|
377
|
+
export function cancelStailEventV2(id, reason) {
|
|
378
|
+
const e = _stailEsV2.get(id);
|
|
379
|
+
if (!e) throw new Error(`stail event ${id} not found`);
|
|
380
|
+
_stailCheckE(e.status, STAIL_EVENT_LIFECYCLE_V2.CANCELLED);
|
|
381
|
+
const now = Date.now();
|
|
382
|
+
e.status = STAIL_EVENT_LIFECYCLE_V2.CANCELLED;
|
|
383
|
+
e.updatedAt = now;
|
|
384
|
+
if (!e.settledAt) e.settledAt = now;
|
|
385
|
+
if (reason) e.metadata.cancelReason = String(reason);
|
|
386
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
387
|
+
}
|
|
388
|
+
export function getStailEventV2(id) {
|
|
389
|
+
const e = _stailEsV2.get(id);
|
|
390
|
+
if (!e) return null;
|
|
391
|
+
return { ...e, metadata: { ...e.metadata } };
|
|
392
|
+
}
|
|
393
|
+
export function listStailEventsV2() {
|
|
394
|
+
return [..._stailEsV2.values()].map((e) => ({
|
|
395
|
+
...e,
|
|
396
|
+
metadata: { ...e.metadata },
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
399
|
+
export function autoPauseIdleStailSubsV2({ now } = {}) {
|
|
400
|
+
const t = now ?? Date.now();
|
|
401
|
+
const flipped = [];
|
|
402
|
+
for (const s of _stailSsV2.values())
|
|
403
|
+
if (
|
|
404
|
+
s.status === STAIL_SUB_MATURITY_V2.ACTIVE &&
|
|
405
|
+
t - s.lastTouchedAt >= _stailIdleMs
|
|
406
|
+
) {
|
|
407
|
+
s.status = STAIL_SUB_MATURITY_V2.PAUSED;
|
|
408
|
+
s.updatedAt = t;
|
|
409
|
+
flipped.push(s.id);
|
|
410
|
+
}
|
|
411
|
+
return { flipped, count: flipped.length };
|
|
412
|
+
}
|
|
413
|
+
export function autoFailStuckStailEventsV2({ now } = {}) {
|
|
414
|
+
const t = now ?? Date.now();
|
|
415
|
+
const flipped = [];
|
|
416
|
+
for (const e of _stailEsV2.values())
|
|
417
|
+
if (
|
|
418
|
+
e.status === STAIL_EVENT_LIFECYCLE_V2.TAILING &&
|
|
419
|
+
e.startedAt != null &&
|
|
420
|
+
t - e.startedAt >= _stailStuckMs
|
|
421
|
+
) {
|
|
422
|
+
e.status = STAIL_EVENT_LIFECYCLE_V2.FAILED;
|
|
423
|
+
e.updatedAt = t;
|
|
424
|
+
if (!e.settledAt) e.settledAt = t;
|
|
425
|
+
e.metadata.failReason = "auto-fail-stuck";
|
|
426
|
+
flipped.push(e.id);
|
|
427
|
+
}
|
|
428
|
+
return { flipped, count: flipped.length };
|
|
429
|
+
}
|
|
430
|
+
export function getSessionTailGovStatsV2() {
|
|
431
|
+
const subsByStatus = {};
|
|
432
|
+
for (const v of Object.values(STAIL_SUB_MATURITY_V2)) subsByStatus[v] = 0;
|
|
433
|
+
for (const s of _stailSsV2.values()) subsByStatus[s.status]++;
|
|
434
|
+
const eventsByStatus = {};
|
|
435
|
+
for (const v of Object.values(STAIL_EVENT_LIFECYCLE_V2))
|
|
436
|
+
eventsByStatus[v] = 0;
|
|
437
|
+
for (const e of _stailEsV2.values()) eventsByStatus[e.status]++;
|
|
438
|
+
return {
|
|
439
|
+
totalStailSubsV2: _stailSsV2.size,
|
|
440
|
+
totalStailEventsV2: _stailEsV2.size,
|
|
441
|
+
maxActiveStailSubsPerOwner: _stailMaxActive,
|
|
442
|
+
maxPendingStailEventsPerSub: _stailMaxPending,
|
|
443
|
+
stailSubIdleMs: _stailIdleMs,
|
|
444
|
+
stailEventStuckMs: _stailStuckMs,
|
|
445
|
+
subsByStatus,
|
|
446
|
+
eventsByStatus,
|
|
447
|
+
};
|
|
448
|
+
}
|