chainlesschain 0.143.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.
Files changed (133) hide show
  1. package/package.json +1 -1
  2. package/src/commands/a2a.js +196 -28
  3. package/src/commands/activitypub.js +157 -27
  4. package/src/commands/agent.js +587 -103
  5. package/src/commands/audit.js +206 -0
  6. package/src/commands/bi.js +152 -27
  7. package/src/commands/bm25.js +111 -27
  8. package/src/commands/browse.js +190 -29
  9. package/src/commands/ccron.js +128 -28
  10. package/src/commands/chat.js +207 -0
  11. package/src/commands/compliance.js +414 -34
  12. package/src/commands/compt.js +127 -29
  13. package/src/commands/consol.js +8 -2
  14. package/src/commands/cowork.js +580 -34
  15. package/src/commands/crosschain.js +182 -28
  16. package/src/commands/dao.js +182 -28
  17. package/src/commands/dlp.js +172 -27
  18. package/src/commands/economy.js +205 -50
  19. package/src/commands/evolution.js +203 -50
  20. package/src/commands/evomap.js +182 -27
  21. package/src/commands/fflag.js +74 -22
  22. package/src/commands/git.js +177 -37
  23. package/src/commands/hardening.js +209 -0
  24. package/src/commands/hmemory.js +204 -50
  25. package/src/commands/incentive.js +209 -0
  26. package/src/commands/inference.js +170 -34
  27. package/src/commands/itbudget.js +149 -33
  28. package/src/commands/kg.js +206 -0
  29. package/src/commands/lowcode.js +195 -38
  30. package/src/commands/marketplace.js +206 -0
  31. package/src/commands/matrix.js +179 -27
  32. package/src/commands/mcpscaf.js +145 -33
  33. package/src/commands/meminj.js +145 -33
  34. package/src/commands/nostr.js +178 -27
  35. package/src/commands/orchestrate.js +217 -0
  36. package/src/commands/orchgov.js +144 -33
  37. package/src/commands/pdfp.js +109 -27
  38. package/src/commands/perf.js +169 -32
  39. package/src/commands/perm.js +144 -33
  40. package/src/commands/pipeline.js +207 -52
  41. package/src/commands/planmode.js +141 -32
  42. package/src/commands/privacy.js +203 -0
  43. package/src/commands/promcomp.js +111 -27
  44. package/src/commands/recommend.js +177 -34
  45. package/src/commands/reputation.js +208 -0
  46. package/src/commands/sandbox.js +206 -0
  47. package/src/commands/seshhook.js +145 -33
  48. package/src/commands/seshsearch.js +141 -33
  49. package/src/commands/seshtail.js +144 -33
  50. package/src/commands/seshu.js +152 -33
  51. package/src/commands/sganal.js +123 -29
  52. package/src/commands/siem.js +201 -34
  53. package/src/commands/sla.js +212 -0
  54. package/src/commands/slotfill.js +146 -33
  55. package/src/commands/social.js +157 -32
  56. package/src/commands/stress.js +206 -0
  57. package/src/commands/svccont.js +145 -33
  58. package/src/commands/terraform.js +206 -0
  59. package/src/commands/tms.js +171 -33
  60. package/src/commands/topiccls.js +146 -33
  61. package/src/commands/uprof.js +141 -32
  62. package/src/commands/vcheck.js +122 -28
  63. package/src/commands/webfetch.js +141 -32
  64. package/src/commands/zkp.js +184 -28
  65. package/src/index.js +40 -0
  66. package/src/lib/a2a-protocol.js +319 -51
  67. package/src/lib/activitypub-bridge.js +288 -50
  68. package/src/lib/agent-economy.js +304 -51
  69. package/src/lib/app-builder.js +279 -46
  70. package/src/lib/audit-logger.js +321 -0
  71. package/src/lib/autonomous-agent.js +284 -48
  72. package/src/lib/bi-engine.js +283 -49
  73. package/src/lib/bm25-search.js +301 -49
  74. package/src/lib/browser-automation.js +296 -49
  75. package/src/lib/chat-core.js +336 -0
  76. package/src/lib/claude-code-bridge.js +341 -0
  77. package/src/lib/compliance-framework-reporter.js +305 -51
  78. package/src/lib/compliance-manager.js +330 -0
  79. package/src/lib/compression-telemetry.js +301 -49
  80. package/src/lib/content-recommender.js +317 -52
  81. package/src/lib/cowork-cron.js +298 -49
  82. package/src/lib/cowork-learning.js +333 -0
  83. package/src/lib/cowork-task-runner.js +308 -51
  84. package/src/lib/cowork-workflow.js +327 -0
  85. package/src/lib/cross-chain.js +311 -51
  86. package/src/lib/dao-governance.js +280 -46
  87. package/src/lib/dlp-engine.js +287 -49
  88. package/src/lib/evolution-system.js +278 -47
  89. package/src/lib/evomap-manager.js +280 -46
  90. package/src/lib/execution-backend.js +294 -48
  91. package/src/lib/feature-flags.js +294 -49
  92. package/src/lib/git-integration.js +285 -47
  93. package/src/lib/hardening-manager.js +341 -0
  94. package/src/lib/hierarchical-memory.js +284 -48
  95. package/src/lib/inference-network.js +308 -51
  96. package/src/lib/iteration-budget.js +302 -50
  97. package/src/lib/knowledge-graph.js +333 -0
  98. package/src/lib/matrix-bridge.js +281 -47
  99. package/src/lib/mcp-scaffold.js +318 -54
  100. package/src/lib/memory-injection.js +288 -49
  101. package/src/lib/nostr-bridge.js +286 -49
  102. package/src/lib/orchestrator.js +293 -48
  103. package/src/lib/pdf-parser.js +298 -49
  104. package/src/lib/perf-tuning.js +309 -50
  105. package/src/lib/permission-engine.js +287 -49
  106. package/src/lib/pipeline-orchestrator.js +289 -49
  107. package/src/lib/plan-mode.js +298 -51
  108. package/src/lib/privacy-computing.js +335 -0
  109. package/src/lib/reputation-optimizer.js +340 -0
  110. package/src/lib/sandbox-v2.js +327 -0
  111. package/src/lib/service-container.js +313 -52
  112. package/src/lib/session-consolidator.js +296 -49
  113. package/src/lib/session-hooks.js +312 -53
  114. package/src/lib/session-search.js +304 -51
  115. package/src/lib/session-tail.js +288 -49
  116. package/src/lib/session-usage.js +298 -52
  117. package/src/lib/siem-exporter.js +298 -51
  118. package/src/lib/skill-marketplace.js +345 -0
  119. package/src/lib/sla-manager.js +341 -0
  120. package/src/lib/slot-filler.js +303 -51
  121. package/src/lib/social-graph-analytics.js +295 -49
  122. package/src/lib/social-graph.js +272 -49
  123. package/src/lib/stress-tester.js +342 -0
  124. package/src/lib/sub-agent-registry.js +302 -53
  125. package/src/lib/task-model-selector.js +302 -50
  126. package/src/lib/terraform-manager.js +333 -0
  127. package/src/lib/todo-manager.js +281 -47
  128. package/src/lib/token-incentive.js +341 -0
  129. package/src/lib/topic-classifier.js +297 -49
  130. package/src/lib/user-profile.js +294 -50
  131. package/src/lib/version-checker.js +304 -50
  132. package/src/lib/web-fetch.js +292 -51
  133. package/src/lib/zkp-engine.js +286 -49
@@ -167,83 +167,329 @@ export function allSessionsUsage({ limit = 1000 } = {}) {
167
167
 
168
168
  // ===== V2 Surface: Session Usage governance overlay (CLI v0.142.0) =====
169
169
  export const SUSE_BUDGET_MATURITY_V2 = Object.freeze({
170
- PENDING: "pending", ACTIVE: "active", EXHAUSTED: "exhausted", ARCHIVED: "archived",
170
+ PENDING: "pending",
171
+ ACTIVE: "active",
172
+ EXHAUSTED: "exhausted",
173
+ ARCHIVED: "archived",
171
174
  });
172
175
  export const SUSE_RECORD_LIFECYCLE_V2 = Object.freeze({
173
- QUEUED: "queued", RECORDING: "recording", RECORDED: "recorded", REJECTED: "rejected", CANCELLED: "cancelled",
176
+ QUEUED: "queued",
177
+ RECORDING: "recording",
178
+ RECORDED: "recorded",
179
+ REJECTED: "rejected",
180
+ CANCELLED: "cancelled",
174
181
  });
175
182
  const _suseBTrans = new Map([
176
- [SUSE_BUDGET_MATURITY_V2.PENDING, new Set([SUSE_BUDGET_MATURITY_V2.ACTIVE, SUSE_BUDGET_MATURITY_V2.ARCHIVED])],
177
- [SUSE_BUDGET_MATURITY_V2.ACTIVE, new Set([SUSE_BUDGET_MATURITY_V2.EXHAUSTED, SUSE_BUDGET_MATURITY_V2.ARCHIVED])],
178
- [SUSE_BUDGET_MATURITY_V2.EXHAUSTED, new Set([SUSE_BUDGET_MATURITY_V2.ACTIVE, SUSE_BUDGET_MATURITY_V2.ARCHIVED])],
183
+ [
184
+ SUSE_BUDGET_MATURITY_V2.PENDING,
185
+ new Set([SUSE_BUDGET_MATURITY_V2.ACTIVE, SUSE_BUDGET_MATURITY_V2.ARCHIVED]),
186
+ ],
187
+ [
188
+ SUSE_BUDGET_MATURITY_V2.ACTIVE,
189
+ new Set([
190
+ SUSE_BUDGET_MATURITY_V2.EXHAUSTED,
191
+ SUSE_BUDGET_MATURITY_V2.ARCHIVED,
192
+ ]),
193
+ ],
194
+ [
195
+ SUSE_BUDGET_MATURITY_V2.EXHAUSTED,
196
+ new Set([SUSE_BUDGET_MATURITY_V2.ACTIVE, SUSE_BUDGET_MATURITY_V2.ARCHIVED]),
197
+ ],
179
198
  [SUSE_BUDGET_MATURITY_V2.ARCHIVED, new Set()],
180
199
  ]);
181
200
  const _suseBTerminal = new Set([SUSE_BUDGET_MATURITY_V2.ARCHIVED]);
182
201
  const _suseRTrans = new Map([
183
- [SUSE_RECORD_LIFECYCLE_V2.QUEUED, new Set([SUSE_RECORD_LIFECYCLE_V2.RECORDING, SUSE_RECORD_LIFECYCLE_V2.CANCELLED])],
184
- [SUSE_RECORD_LIFECYCLE_V2.RECORDING, new Set([SUSE_RECORD_LIFECYCLE_V2.RECORDED, SUSE_RECORD_LIFECYCLE_V2.REJECTED, SUSE_RECORD_LIFECYCLE_V2.CANCELLED])],
202
+ [
203
+ SUSE_RECORD_LIFECYCLE_V2.QUEUED,
204
+ new Set([
205
+ SUSE_RECORD_LIFECYCLE_V2.RECORDING,
206
+ SUSE_RECORD_LIFECYCLE_V2.CANCELLED,
207
+ ]),
208
+ ],
209
+ [
210
+ SUSE_RECORD_LIFECYCLE_V2.RECORDING,
211
+ new Set([
212
+ SUSE_RECORD_LIFECYCLE_V2.RECORDED,
213
+ SUSE_RECORD_LIFECYCLE_V2.REJECTED,
214
+ SUSE_RECORD_LIFECYCLE_V2.CANCELLED,
215
+ ]),
216
+ ],
185
217
  [SUSE_RECORD_LIFECYCLE_V2.RECORDED, new Set()],
186
218
  [SUSE_RECORD_LIFECYCLE_V2.REJECTED, new Set()],
187
219
  [SUSE_RECORD_LIFECYCLE_V2.CANCELLED, new Set()],
188
220
  ]);
189
221
  const _suseBsV2 = new Map();
190
222
  const _suseRsV2 = new Map();
191
- let _suseMaxActive = 5, _suseMaxPending = 50, _suseIdleMs = 30 * 24 * 60 * 60 * 1000, _suseStuckMs = 30 * 1000;
192
- function _susePos(n, label) { const v = Math.floor(Number(n)); if (!Number.isFinite(v) || v <= 0) throw new Error(`${label} must be positive integer`); return v; }
193
- function _suseCheckB(from, to) { const a = _suseBTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid suse budget transition ${from} → ${to}`); }
194
- function _suseCheckR(from, to) { const a = _suseRTrans.get(from); if (!a || !a.has(to)) throw new Error(`invalid suse record transition ${from} → ${to}`); }
195
- export function setMaxActiveSuseBudgetsPerOwnerV2(n) { _suseMaxActive = _susePos(n, "maxActiveSuseBudgetsPerOwner"); }
196
- export function getMaxActiveSuseBudgetsPerOwnerV2() { return _suseMaxActive; }
197
- export function setMaxPendingSuseRecordsPerBudgetV2(n) { _suseMaxPending = _susePos(n, "maxPendingSuseRecordsPerBudget"); }
198
- export function getMaxPendingSuseRecordsPerBudgetV2() { return _suseMaxPending; }
199
- export function setSuseBudgetIdleMsV2(n) { _suseIdleMs = _susePos(n, "suseBudgetIdleMs"); }
200
- export function getSuseBudgetIdleMsV2() { return _suseIdleMs; }
201
- export function setSuseRecordStuckMsV2(n) { _suseStuckMs = _susePos(n, "suseRecordStuckMs"); }
202
- export function getSuseRecordStuckMsV2() { return _suseStuckMs; }
203
- export function _resetStateSessionUsageV2() { _suseBsV2.clear(); _suseRsV2.clear(); _suseMaxActive = 5; _suseMaxPending = 50; _suseIdleMs = 30 * 24 * 60 * 60 * 1000; _suseStuckMs = 30 * 1000; }
223
+ let _suseMaxActive = 5,
224
+ _suseMaxPending = 50,
225
+ _suseIdleMs = 30 * 24 * 60 * 60 * 1000,
226
+ _suseStuckMs = 30 * 1000;
227
+ function _susePos(n, label) {
228
+ const v = Math.floor(Number(n));
229
+ if (!Number.isFinite(v) || v <= 0)
230
+ throw new Error(`${label} must be positive integer`);
231
+ return v;
232
+ }
233
+ function _suseCheckB(from, to) {
234
+ const a = _suseBTrans.get(from);
235
+ if (!a || !a.has(to))
236
+ throw new Error(`invalid suse budget transition ${from} → ${to}`);
237
+ }
238
+ function _suseCheckR(from, to) {
239
+ const a = _suseRTrans.get(from);
240
+ if (!a || !a.has(to))
241
+ throw new Error(`invalid suse record transition ${from} → ${to}`);
242
+ }
243
+ export function setMaxActiveSuseBudgetsPerOwnerV2(n) {
244
+ _suseMaxActive = _susePos(n, "maxActiveSuseBudgetsPerOwner");
245
+ }
246
+ export function getMaxActiveSuseBudgetsPerOwnerV2() {
247
+ return _suseMaxActive;
248
+ }
249
+ export function setMaxPendingSuseRecordsPerBudgetV2(n) {
250
+ _suseMaxPending = _susePos(n, "maxPendingSuseRecordsPerBudget");
251
+ }
252
+ export function getMaxPendingSuseRecordsPerBudgetV2() {
253
+ return _suseMaxPending;
254
+ }
255
+ export function setSuseBudgetIdleMsV2(n) {
256
+ _suseIdleMs = _susePos(n, "suseBudgetIdleMs");
257
+ }
258
+ export function getSuseBudgetIdleMsV2() {
259
+ return _suseIdleMs;
260
+ }
261
+ export function setSuseRecordStuckMsV2(n) {
262
+ _suseStuckMs = _susePos(n, "suseRecordStuckMs");
263
+ }
264
+ export function getSuseRecordStuckMsV2() {
265
+ return _suseStuckMs;
266
+ }
267
+ export function _resetStateSessionUsageV2() {
268
+ _suseBsV2.clear();
269
+ _suseRsV2.clear();
270
+ _suseMaxActive = 5;
271
+ _suseMaxPending = 50;
272
+ _suseIdleMs = 30 * 24 * 60 * 60 * 1000;
273
+ _suseStuckMs = 30 * 1000;
274
+ }
204
275
  export function registerSuseBudgetV2({ id, owner, limit, metadata } = {}) {
205
- if (!id) throw new Error("suse budget id required"); if (!owner) throw new Error("suse budget owner required");
206
- if (_suseBsV2.has(id)) throw new Error(`suse budget ${id} already registered`);
276
+ if (!id) throw new Error("suse budget id required");
277
+ if (!owner) throw new Error("suse budget owner required");
278
+ if (_suseBsV2.has(id))
279
+ throw new Error(`suse budget ${id} already registered`);
207
280
  const now = Date.now();
208
- const lim = limit == null ? 1000 : Math.max(1, Math.floor(Number(limit)) || 1);
209
- const b = { id, owner, limit: lim, status: SUSE_BUDGET_MATURITY_V2.PENDING, createdAt: now, updatedAt: now, activatedAt: null, archivedAt: null, lastTouchedAt: now, metadata: { ...(metadata || {}) } };
210
- _suseBsV2.set(id, b); return { ...b, metadata: { ...b.metadata } };
281
+ const lim =
282
+ limit == null ? 1000 : Math.max(1, Math.floor(Number(limit)) || 1);
283
+ const b = {
284
+ id,
285
+ owner,
286
+ limit: lim,
287
+ status: SUSE_BUDGET_MATURITY_V2.PENDING,
288
+ createdAt: now,
289
+ updatedAt: now,
290
+ activatedAt: null,
291
+ archivedAt: null,
292
+ lastTouchedAt: now,
293
+ metadata: { ...(metadata || {}) },
294
+ };
295
+ _suseBsV2.set(id, b);
296
+ return { ...b, metadata: { ...b.metadata } };
297
+ }
298
+ function _suseCountActive(owner) {
299
+ let n = 0;
300
+ for (const b of _suseBsV2.values())
301
+ if (b.owner === owner && b.status === SUSE_BUDGET_MATURITY_V2.ACTIVE) n++;
302
+ return n;
211
303
  }
212
- function _suseCountActive(owner) { let n = 0; for (const b of _suseBsV2.values()) if (b.owner === owner && b.status === SUSE_BUDGET_MATURITY_V2.ACTIVE) n++; return n; }
213
304
  export function activateSuseBudgetV2(id) {
214
- const b = _suseBsV2.get(id); if (!b) throw new Error(`suse budget ${id} not found`);
305
+ const b = _suseBsV2.get(id);
306
+ if (!b) throw new Error(`suse budget ${id} not found`);
215
307
  _suseCheckB(b.status, SUSE_BUDGET_MATURITY_V2.ACTIVE);
216
308
  const recovery = b.status === SUSE_BUDGET_MATURITY_V2.EXHAUSTED;
217
- if (!recovery && _suseCountActive(b.owner) >= _suseMaxActive) throw new Error(`max active suse budgets for owner ${b.owner} reached`);
218
- const now = Date.now(); b.status = SUSE_BUDGET_MATURITY_V2.ACTIVE; b.updatedAt = now; b.lastTouchedAt = now; if (!b.activatedAt) b.activatedAt = now;
309
+ if (!recovery && _suseCountActive(b.owner) >= _suseMaxActive)
310
+ throw new Error(`max active suse budgets for owner ${b.owner} reached`);
311
+ const now = Date.now();
312
+ b.status = SUSE_BUDGET_MATURITY_V2.ACTIVE;
313
+ b.updatedAt = now;
314
+ b.lastTouchedAt = now;
315
+ if (!b.activatedAt) b.activatedAt = now;
316
+ return { ...b, metadata: { ...b.metadata } };
317
+ }
318
+ export function exhaustSuseBudgetV2(id) {
319
+ const b = _suseBsV2.get(id);
320
+ if (!b) throw new Error(`suse budget ${id} not found`);
321
+ _suseCheckB(b.status, SUSE_BUDGET_MATURITY_V2.EXHAUSTED);
322
+ b.status = SUSE_BUDGET_MATURITY_V2.EXHAUSTED;
323
+ b.updatedAt = Date.now();
324
+ return { ...b, metadata: { ...b.metadata } };
325
+ }
326
+ export function archiveSuseBudgetV2(id) {
327
+ const b = _suseBsV2.get(id);
328
+ if (!b) throw new Error(`suse budget ${id} not found`);
329
+ _suseCheckB(b.status, SUSE_BUDGET_MATURITY_V2.ARCHIVED);
330
+ const now = Date.now();
331
+ b.status = SUSE_BUDGET_MATURITY_V2.ARCHIVED;
332
+ b.updatedAt = now;
333
+ if (!b.archivedAt) b.archivedAt = now;
334
+ return { ...b, metadata: { ...b.metadata } };
335
+ }
336
+ export function touchSuseBudgetV2(id) {
337
+ const b = _suseBsV2.get(id);
338
+ if (!b) throw new Error(`suse budget ${id} not found`);
339
+ if (_suseBTerminal.has(b.status))
340
+ throw new Error(`cannot touch terminal suse budget ${id}`);
341
+ const now = Date.now();
342
+ b.lastTouchedAt = now;
343
+ b.updatedAt = now;
344
+ return { ...b, metadata: { ...b.metadata } };
345
+ }
346
+ export function getSuseBudgetV2(id) {
347
+ const b = _suseBsV2.get(id);
348
+ if (!b) return null;
219
349
  return { ...b, metadata: { ...b.metadata } };
220
350
  }
221
- export function exhaustSuseBudgetV2(id) { const b = _suseBsV2.get(id); if (!b) throw new Error(`suse budget ${id} not found`); _suseCheckB(b.status, SUSE_BUDGET_MATURITY_V2.EXHAUSTED); b.status = SUSE_BUDGET_MATURITY_V2.EXHAUSTED; b.updatedAt = Date.now(); return { ...b, metadata: { ...b.metadata } }; }
222
- export function archiveSuseBudgetV2(id) { const b = _suseBsV2.get(id); if (!b) throw new Error(`suse budget ${id} not found`); _suseCheckB(b.status, SUSE_BUDGET_MATURITY_V2.ARCHIVED); const now = Date.now(); b.status = SUSE_BUDGET_MATURITY_V2.ARCHIVED; b.updatedAt = now; if (!b.archivedAt) b.archivedAt = now; return { ...b, metadata: { ...b.metadata } }; }
223
- export function touchSuseBudgetV2(id) { const b = _suseBsV2.get(id); if (!b) throw new Error(`suse budget ${id} not found`); if (_suseBTerminal.has(b.status)) throw new Error(`cannot touch terminal suse budget ${id}`); const now = Date.now(); b.lastTouchedAt = now; b.updatedAt = now; return { ...b, metadata: { ...b.metadata } }; }
224
- export function getSuseBudgetV2(id) { const b = _suseBsV2.get(id); if (!b) return null; return { ...b, metadata: { ...b.metadata } }; }
225
- export function listSuseBudgetsV2() { return [..._suseBsV2.values()].map((b) => ({ ...b, metadata: { ...b.metadata } })); }
226
- function _suseCountPending(budgetId) { let n = 0; for (const r of _suseRsV2.values()) if (r.budgetId === budgetId && (r.status === SUSE_RECORD_LIFECYCLE_V2.QUEUED || r.status === SUSE_RECORD_LIFECYCLE_V2.RECORDING)) n++; return n; }
351
+ export function listSuseBudgetsV2() {
352
+ return [..._suseBsV2.values()].map((b) => ({
353
+ ...b,
354
+ metadata: { ...b.metadata },
355
+ }));
356
+ }
357
+ function _suseCountPending(budgetId) {
358
+ let n = 0;
359
+ for (const r of _suseRsV2.values())
360
+ if (
361
+ r.budgetId === budgetId &&
362
+ (r.status === SUSE_RECORD_LIFECYCLE_V2.QUEUED ||
363
+ r.status === SUSE_RECORD_LIFECYCLE_V2.RECORDING)
364
+ )
365
+ n++;
366
+ return n;
367
+ }
227
368
  export function createSuseRecordV2({ id, budgetId, amount, metadata } = {}) {
228
- if (!id) throw new Error("suse record id required"); if (!budgetId) throw new Error("suse record budgetId required");
369
+ if (!id) throw new Error("suse record id required");
370
+ if (!budgetId) throw new Error("suse record budgetId required");
229
371
  if (_suseRsV2.has(id)) throw new Error(`suse record ${id} already exists`);
230
- if (!_suseBsV2.has(budgetId)) throw new Error(`suse budget ${budgetId} not found`);
231
- if (_suseCountPending(budgetId) >= _suseMaxPending) throw new Error(`max pending suse records for budget ${budgetId} reached`);
372
+ if (!_suseBsV2.has(budgetId))
373
+ throw new Error(`suse budget ${budgetId} not found`);
374
+ if (_suseCountPending(budgetId) >= _suseMaxPending)
375
+ throw new Error(`max pending suse records for budget ${budgetId} reached`);
232
376
  const now = Date.now();
233
377
  const amt = amount == null ? 0 : Math.max(0, Number(amount) || 0);
234
- const r = { id, budgetId, amount: amt, status: SUSE_RECORD_LIFECYCLE_V2.QUEUED, createdAt: now, updatedAt: now, startedAt: null, settledAt: null, metadata: { ...(metadata || {}) } };
235
- _suseRsV2.set(id, r); return { ...r, metadata: { ...r.metadata } };
236
- }
237
- export function recordingSuseRecordV2(id) { const r = _suseRsV2.get(id); if (!r) throw new Error(`suse record ${id} not found`); _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.RECORDING); const now = Date.now(); r.status = SUSE_RECORD_LIFECYCLE_V2.RECORDING; r.updatedAt = now; if (!r.startedAt) r.startedAt = now; return { ...r, metadata: { ...r.metadata } }; }
238
- export function recordSuseRecordV2(id) { const r = _suseRsV2.get(id); if (!r) throw new Error(`suse record ${id} not found`); _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.RECORDED); const now = Date.now(); r.status = SUSE_RECORD_LIFECYCLE_V2.RECORDED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; return { ...r, metadata: { ...r.metadata } }; }
239
- export function rejectSuseRecordV2(id, reason) { const r = _suseRsV2.get(id); if (!r) throw new Error(`suse record ${id} not found`); _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.REJECTED); const now = Date.now(); r.status = SUSE_RECORD_LIFECYCLE_V2.REJECTED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.rejectReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
240
- export function cancelSuseRecordV2(id, reason) { const r = _suseRsV2.get(id); if (!r) throw new Error(`suse record ${id} not found`); _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.CANCELLED); const now = Date.now(); r.status = SUSE_RECORD_LIFECYCLE_V2.CANCELLED; r.updatedAt = now; if (!r.settledAt) r.settledAt = now; if (reason) r.metadata.cancelReason = String(reason); return { ...r, metadata: { ...r.metadata } }; }
241
- export function getSuseRecordV2(id) { const r = _suseRsV2.get(id); if (!r) return null; return { ...r, metadata: { ...r.metadata } }; }
242
- export function listSuseRecordsV2() { return [..._suseRsV2.values()].map((r) => ({ ...r, metadata: { ...r.metadata } })); }
243
- export function autoExhaustIdleSuseBudgetsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const b of _suseBsV2.values()) if (b.status === SUSE_BUDGET_MATURITY_V2.ACTIVE && (t - b.lastTouchedAt) >= _suseIdleMs) { b.status = SUSE_BUDGET_MATURITY_V2.EXHAUSTED; b.updatedAt = t; flipped.push(b.id); } return { flipped, count: flipped.length }; }
244
- export function autoRejectStuckSuseRecordsV2({ now } = {}) { const t = now ?? Date.now(); const flipped = []; for (const r of _suseRsV2.values()) if (r.status === SUSE_RECORD_LIFECYCLE_V2.RECORDING && r.startedAt != null && (t - r.startedAt) >= _suseStuckMs) { r.status = SUSE_RECORD_LIFECYCLE_V2.REJECTED; r.updatedAt = t; if (!r.settledAt) r.settledAt = t; r.metadata.rejectReason = "auto-reject-stuck"; flipped.push(r.id); } return { flipped, count: flipped.length }; }
378
+ const r = {
379
+ id,
380
+ budgetId,
381
+ amount: amt,
382
+ status: SUSE_RECORD_LIFECYCLE_V2.QUEUED,
383
+ createdAt: now,
384
+ updatedAt: now,
385
+ startedAt: null,
386
+ settledAt: null,
387
+ metadata: { ...(metadata || {}) },
388
+ };
389
+ _suseRsV2.set(id, r);
390
+ return { ...r, metadata: { ...r.metadata } };
391
+ }
392
+ export function recordingSuseRecordV2(id) {
393
+ const r = _suseRsV2.get(id);
394
+ if (!r) throw new Error(`suse record ${id} not found`);
395
+ _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.RECORDING);
396
+ const now = Date.now();
397
+ r.status = SUSE_RECORD_LIFECYCLE_V2.RECORDING;
398
+ r.updatedAt = now;
399
+ if (!r.startedAt) r.startedAt = now;
400
+ return { ...r, metadata: { ...r.metadata } };
401
+ }
402
+ export function recordSuseRecordV2(id) {
403
+ const r = _suseRsV2.get(id);
404
+ if (!r) throw new Error(`suse record ${id} not found`);
405
+ _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.RECORDED);
406
+ const now = Date.now();
407
+ r.status = SUSE_RECORD_LIFECYCLE_V2.RECORDED;
408
+ r.updatedAt = now;
409
+ if (!r.settledAt) r.settledAt = now;
410
+ return { ...r, metadata: { ...r.metadata } };
411
+ }
412
+ export function rejectSuseRecordV2(id, reason) {
413
+ const r = _suseRsV2.get(id);
414
+ if (!r) throw new Error(`suse record ${id} not found`);
415
+ _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.REJECTED);
416
+ const now = Date.now();
417
+ r.status = SUSE_RECORD_LIFECYCLE_V2.REJECTED;
418
+ r.updatedAt = now;
419
+ if (!r.settledAt) r.settledAt = now;
420
+ if (reason) r.metadata.rejectReason = String(reason);
421
+ return { ...r, metadata: { ...r.metadata } };
422
+ }
423
+ export function cancelSuseRecordV2(id, reason) {
424
+ const r = _suseRsV2.get(id);
425
+ if (!r) throw new Error(`suse record ${id} not found`);
426
+ _suseCheckR(r.status, SUSE_RECORD_LIFECYCLE_V2.CANCELLED);
427
+ const now = Date.now();
428
+ r.status = SUSE_RECORD_LIFECYCLE_V2.CANCELLED;
429
+ r.updatedAt = now;
430
+ if (!r.settledAt) r.settledAt = now;
431
+ if (reason) r.metadata.cancelReason = String(reason);
432
+ return { ...r, metadata: { ...r.metadata } };
433
+ }
434
+ export function getSuseRecordV2(id) {
435
+ const r = _suseRsV2.get(id);
436
+ if (!r) return null;
437
+ return { ...r, metadata: { ...r.metadata } };
438
+ }
439
+ export function listSuseRecordsV2() {
440
+ return [..._suseRsV2.values()].map((r) => ({
441
+ ...r,
442
+ metadata: { ...r.metadata },
443
+ }));
444
+ }
445
+ export function autoExhaustIdleSuseBudgetsV2({ now } = {}) {
446
+ const t = now ?? Date.now();
447
+ const flipped = [];
448
+ for (const b of _suseBsV2.values())
449
+ if (
450
+ b.status === SUSE_BUDGET_MATURITY_V2.ACTIVE &&
451
+ t - b.lastTouchedAt >= _suseIdleMs
452
+ ) {
453
+ b.status = SUSE_BUDGET_MATURITY_V2.EXHAUSTED;
454
+ b.updatedAt = t;
455
+ flipped.push(b.id);
456
+ }
457
+ return { flipped, count: flipped.length };
458
+ }
459
+ export function autoRejectStuckSuseRecordsV2({ now } = {}) {
460
+ const t = now ?? Date.now();
461
+ const flipped = [];
462
+ for (const r of _suseRsV2.values())
463
+ if (
464
+ r.status === SUSE_RECORD_LIFECYCLE_V2.RECORDING &&
465
+ r.startedAt != null &&
466
+ t - r.startedAt >= _suseStuckMs
467
+ ) {
468
+ r.status = SUSE_RECORD_LIFECYCLE_V2.REJECTED;
469
+ r.updatedAt = t;
470
+ if (!r.settledAt) r.settledAt = t;
471
+ r.metadata.rejectReason = "auto-reject-stuck";
472
+ flipped.push(r.id);
473
+ }
474
+ return { flipped, count: flipped.length };
475
+ }
245
476
  export function getSessionUsageGovStatsV2() {
246
- const budgetsByStatus = {}; for (const v of Object.values(SUSE_BUDGET_MATURITY_V2)) budgetsByStatus[v] = 0; for (const b of _suseBsV2.values()) budgetsByStatus[b.status]++;
247
- const recordsByStatus = {}; for (const v of Object.values(SUSE_RECORD_LIFECYCLE_V2)) recordsByStatus[v] = 0; for (const r of _suseRsV2.values()) recordsByStatus[r.status]++;
248
- return { totalSuseBudgetsV2: _suseBsV2.size, totalSuseRecordsV2: _suseRsV2.size, maxActiveSuseBudgetsPerOwner: _suseMaxActive, maxPendingSuseRecordsPerBudget: _suseMaxPending, suseBudgetIdleMs: _suseIdleMs, suseRecordStuckMs: _suseStuckMs, budgetsByStatus, recordsByStatus };
477
+ const budgetsByStatus = {};
478
+ for (const v of Object.values(SUSE_BUDGET_MATURITY_V2))
479
+ budgetsByStatus[v] = 0;
480
+ for (const b of _suseBsV2.values()) budgetsByStatus[b.status]++;
481
+ const recordsByStatus = {};
482
+ for (const v of Object.values(SUSE_RECORD_LIFECYCLE_V2))
483
+ recordsByStatus[v] = 0;
484
+ for (const r of _suseRsV2.values()) recordsByStatus[r.status]++;
485
+ return {
486
+ totalSuseBudgetsV2: _suseBsV2.size,
487
+ totalSuseRecordsV2: _suseRsV2.size,
488
+ maxActiveSuseBudgetsPerOwner: _suseMaxActive,
489
+ maxPendingSuseRecordsPerBudget: _suseMaxPending,
490
+ suseBudgetIdleMs: _suseIdleMs,
491
+ suseRecordStuckMs: _suseStuckMs,
492
+ budgetsByStatus,
493
+ recordsByStatus,
494
+ };
249
495
  }