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.
- package/package.json +1 -1
- package/src/commands/a2a.js +196 -28
- package/src/commands/activitypub.js +157 -27
- package/src/commands/agent.js +587 -103
- package/src/commands/audit.js +206 -0
- package/src/commands/bi.js +152 -27
- package/src/commands/bm25.js +111 -27
- package/src/commands/browse.js +190 -29
- package/src/commands/ccron.js +128 -28
- package/src/commands/chat.js +207 -0
- package/src/commands/compliance.js +414 -34
- package/src/commands/compt.js +127 -29
- package/src/commands/consol.js +8 -2
- package/src/commands/cowork.js +580 -34
- package/src/commands/crosschain.js +182 -28
- package/src/commands/dao.js +182 -28
- package/src/commands/dlp.js +172 -27
- package/src/commands/economy.js +205 -50
- package/src/commands/evolution.js +203 -50
- package/src/commands/evomap.js +182 -27
- package/src/commands/fflag.js +74 -22
- package/src/commands/git.js +177 -37
- package/src/commands/hardening.js +209 -0
- package/src/commands/hmemory.js +204 -50
- package/src/commands/incentive.js +209 -0
- package/src/commands/inference.js +170 -34
- package/src/commands/itbudget.js +149 -33
- package/src/commands/kg.js +206 -0
- package/src/commands/lowcode.js +195 -38
- package/src/commands/marketplace.js +206 -0
- package/src/commands/matrix.js +179 -27
- package/src/commands/mcpscaf.js +145 -33
- package/src/commands/meminj.js +145 -33
- package/src/commands/nostr.js +178 -27
- package/src/commands/orchestrate.js +217 -0
- package/src/commands/orchgov.js +144 -33
- package/src/commands/pdfp.js +109 -27
- package/src/commands/perf.js +169 -32
- package/src/commands/perm.js +144 -33
- package/src/commands/pipeline.js +207 -52
- package/src/commands/planmode.js +141 -32
- package/src/commands/privacy.js +203 -0
- package/src/commands/promcomp.js +111 -27
- package/src/commands/recommend.js +177 -34
- package/src/commands/reputation.js +208 -0
- package/src/commands/sandbox.js +206 -0
- package/src/commands/seshhook.js +145 -33
- package/src/commands/seshsearch.js +141 -33
- package/src/commands/seshtail.js +144 -33
- package/src/commands/seshu.js +152 -33
- package/src/commands/sganal.js +123 -29
- package/src/commands/siem.js +201 -34
- package/src/commands/sla.js +212 -0
- package/src/commands/slotfill.js +146 -33
- package/src/commands/social.js +157 -32
- package/src/commands/stress.js +206 -0
- package/src/commands/svccont.js +145 -33
- package/src/commands/terraform.js +206 -0
- package/src/commands/tms.js +171 -33
- package/src/commands/topiccls.js +146 -33
- package/src/commands/uprof.js +141 -32
- package/src/commands/vcheck.js +122 -28
- package/src/commands/webfetch.js +141 -32
- package/src/commands/zkp.js +184 -28
- package/src/index.js +40 -0
- package/src/lib/a2a-protocol.js +319 -51
- package/src/lib/activitypub-bridge.js +288 -50
- package/src/lib/agent-economy.js +304 -51
- package/src/lib/app-builder.js +279 -46
- package/src/lib/audit-logger.js +321 -0
- package/src/lib/autonomous-agent.js +284 -48
- package/src/lib/bi-engine.js +283 -49
- package/src/lib/bm25-search.js +301 -49
- package/src/lib/browser-automation.js +296 -49
- package/src/lib/chat-core.js +336 -0
- package/src/lib/claude-code-bridge.js +341 -0
- package/src/lib/compliance-framework-reporter.js +305 -51
- package/src/lib/compliance-manager.js +330 -0
- package/src/lib/compression-telemetry.js +301 -49
- package/src/lib/content-recommender.js +317 -52
- package/src/lib/cowork-cron.js +298 -49
- package/src/lib/cowork-learning.js +333 -0
- package/src/lib/cowork-task-runner.js +308 -51
- package/src/lib/cowork-workflow.js +327 -0
- package/src/lib/cross-chain.js +311 -51
- package/src/lib/dao-governance.js +280 -46
- package/src/lib/dlp-engine.js +287 -49
- package/src/lib/evolution-system.js +278 -47
- package/src/lib/evomap-manager.js +280 -46
- package/src/lib/execution-backend.js +294 -48
- package/src/lib/feature-flags.js +294 -49
- package/src/lib/git-integration.js +285 -47
- package/src/lib/hardening-manager.js +341 -0
- package/src/lib/hierarchical-memory.js +284 -48
- package/src/lib/inference-network.js +308 -51
- package/src/lib/iteration-budget.js +302 -50
- package/src/lib/knowledge-graph.js +333 -0
- package/src/lib/matrix-bridge.js +281 -47
- package/src/lib/mcp-scaffold.js +318 -54
- package/src/lib/memory-injection.js +288 -49
- package/src/lib/nostr-bridge.js +286 -49
- package/src/lib/orchestrator.js +293 -48
- package/src/lib/pdf-parser.js +298 -49
- package/src/lib/perf-tuning.js +309 -50
- package/src/lib/permission-engine.js +287 -49
- package/src/lib/pipeline-orchestrator.js +289 -49
- package/src/lib/plan-mode.js +298 -51
- package/src/lib/privacy-computing.js +335 -0
- package/src/lib/reputation-optimizer.js +340 -0
- package/src/lib/sandbox-v2.js +327 -0
- package/src/lib/service-container.js +313 -52
- package/src/lib/session-consolidator.js +296 -49
- package/src/lib/session-hooks.js +312 -53
- package/src/lib/session-search.js +304 -51
- package/src/lib/session-tail.js +288 -49
- package/src/lib/session-usage.js +298 -52
- package/src/lib/siem-exporter.js +298 -51
- package/src/lib/skill-marketplace.js +345 -0
- package/src/lib/sla-manager.js +341 -0
- package/src/lib/slot-filler.js +303 -51
- package/src/lib/social-graph-analytics.js +295 -49
- package/src/lib/social-graph.js +272 -49
- package/src/lib/stress-tester.js +342 -0
- package/src/lib/sub-agent-registry.js +302 -53
- package/src/lib/task-model-selector.js +302 -50
- package/src/lib/terraform-manager.js +333 -0
- package/src/lib/todo-manager.js +281 -47
- package/src/lib/token-incentive.js +341 -0
- package/src/lib/topic-classifier.js +297 -49
- package/src/lib/user-profile.js +294 -50
- package/src/lib/version-checker.js +304 -50
- package/src/lib/web-fetch.js +292 -51
- package/src/lib/zkp-engine.js +286 -49
package/src/lib/session-usage.js
CHANGED
|
@@ -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",
|
|
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",
|
|
176
|
+
QUEUED: "queued",
|
|
177
|
+
RECORDING: "recording",
|
|
178
|
+
RECORDED: "recorded",
|
|
179
|
+
REJECTED: "rejected",
|
|
180
|
+
CANCELLED: "cancelled",
|
|
174
181
|
});
|
|
175
182
|
const _suseBTrans = new Map([
|
|
176
|
-
[
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
[
|
|
184
|
-
|
|
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,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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");
|
|
206
|
-
if (
|
|
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 =
|
|
209
|
-
|
|
210
|
-
|
|
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);
|
|
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)
|
|
218
|
-
|
|
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
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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");
|
|
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))
|
|
231
|
-
|
|
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 = {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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 = {};
|
|
247
|
-
|
|
248
|
-
|
|
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
|
}
|