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
package/src/lib/cowork-cron.js
CHANGED
|
@@ -472,3 +472,333 @@ function _minuteKey(date) {
|
|
|
472
472
|
function _secondKey(date) {
|
|
473
473
|
return `${_minuteKey(date)}-${date.getSeconds()}`;
|
|
474
474
|
}
|
|
475
|
+
|
|
476
|
+
// =====================================================================
|
|
477
|
+
// Cowork Cron V2 governance overlay
|
|
478
|
+
// =====================================================================
|
|
479
|
+
export const CCRON_PROFILE_MATURITY_V2 = Object.freeze({
|
|
480
|
+
PENDING: "pending",
|
|
481
|
+
ACTIVE: "active",
|
|
482
|
+
PAUSED: "paused",
|
|
483
|
+
ARCHIVED: "archived",
|
|
484
|
+
});
|
|
485
|
+
export const CCRON_TICK_LIFECYCLE_V2 = Object.freeze({
|
|
486
|
+
QUEUED: "queued",
|
|
487
|
+
RUNNING: "running",
|
|
488
|
+
COMPLETED: "completed",
|
|
489
|
+
FAILED: "failed",
|
|
490
|
+
CANCELLED: "cancelled",
|
|
491
|
+
});
|
|
492
|
+
const _ccronPTrans = new Map([
|
|
493
|
+
[
|
|
494
|
+
CCRON_PROFILE_MATURITY_V2.PENDING,
|
|
495
|
+
new Set([
|
|
496
|
+
CCRON_PROFILE_MATURITY_V2.ACTIVE,
|
|
497
|
+
CCRON_PROFILE_MATURITY_V2.ARCHIVED,
|
|
498
|
+
]),
|
|
499
|
+
],
|
|
500
|
+
[
|
|
501
|
+
CCRON_PROFILE_MATURITY_V2.ACTIVE,
|
|
502
|
+
new Set([
|
|
503
|
+
CCRON_PROFILE_MATURITY_V2.PAUSED,
|
|
504
|
+
CCRON_PROFILE_MATURITY_V2.ARCHIVED,
|
|
505
|
+
]),
|
|
506
|
+
],
|
|
507
|
+
[
|
|
508
|
+
CCRON_PROFILE_MATURITY_V2.PAUSED,
|
|
509
|
+
new Set([
|
|
510
|
+
CCRON_PROFILE_MATURITY_V2.ACTIVE,
|
|
511
|
+
CCRON_PROFILE_MATURITY_V2.ARCHIVED,
|
|
512
|
+
]),
|
|
513
|
+
],
|
|
514
|
+
[CCRON_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
515
|
+
]);
|
|
516
|
+
const _ccronPTerminal = new Set([CCRON_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
517
|
+
const _ccronTTrans = new Map([
|
|
518
|
+
[
|
|
519
|
+
CCRON_TICK_LIFECYCLE_V2.QUEUED,
|
|
520
|
+
new Set([
|
|
521
|
+
CCRON_TICK_LIFECYCLE_V2.RUNNING,
|
|
522
|
+
CCRON_TICK_LIFECYCLE_V2.CANCELLED,
|
|
523
|
+
]),
|
|
524
|
+
],
|
|
525
|
+
[
|
|
526
|
+
CCRON_TICK_LIFECYCLE_V2.RUNNING,
|
|
527
|
+
new Set([
|
|
528
|
+
CCRON_TICK_LIFECYCLE_V2.COMPLETED,
|
|
529
|
+
CCRON_TICK_LIFECYCLE_V2.FAILED,
|
|
530
|
+
CCRON_TICK_LIFECYCLE_V2.CANCELLED,
|
|
531
|
+
]),
|
|
532
|
+
],
|
|
533
|
+
[CCRON_TICK_LIFECYCLE_V2.COMPLETED, new Set()],
|
|
534
|
+
[CCRON_TICK_LIFECYCLE_V2.FAILED, new Set()],
|
|
535
|
+
[CCRON_TICK_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
536
|
+
]);
|
|
537
|
+
const _ccronPsV2 = new Map();
|
|
538
|
+
const _ccronTsV2 = new Map();
|
|
539
|
+
let _ccronMaxActive = 6,
|
|
540
|
+
_ccronMaxPending = 15,
|
|
541
|
+
_ccronIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
542
|
+
_ccronStuckMs = 60 * 1000;
|
|
543
|
+
function _ccronPos(n, label) {
|
|
544
|
+
const v = Math.floor(Number(n));
|
|
545
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
546
|
+
throw new Error(`${label} must be positive integer`);
|
|
547
|
+
return v;
|
|
548
|
+
}
|
|
549
|
+
function _ccronCheckP(from, to) {
|
|
550
|
+
const a = _ccronPTrans.get(from);
|
|
551
|
+
if (!a || !a.has(to))
|
|
552
|
+
throw new Error(`invalid ccron profile transition ${from} → ${to}`);
|
|
553
|
+
}
|
|
554
|
+
function _ccronCheckT(from, to) {
|
|
555
|
+
const a = _ccronTTrans.get(from);
|
|
556
|
+
if (!a || !a.has(to))
|
|
557
|
+
throw new Error(`invalid ccron tick transition ${from} → ${to}`);
|
|
558
|
+
}
|
|
559
|
+
function _ccronCountActive(owner) {
|
|
560
|
+
let c = 0;
|
|
561
|
+
for (const p of _ccronPsV2.values())
|
|
562
|
+
if (p.owner === owner && p.status === CCRON_PROFILE_MATURITY_V2.ACTIVE) c++;
|
|
563
|
+
return c;
|
|
564
|
+
}
|
|
565
|
+
function _ccronCountPending(profileId) {
|
|
566
|
+
let c = 0;
|
|
567
|
+
for (const t of _ccronTsV2.values())
|
|
568
|
+
if (
|
|
569
|
+
t.profileId === profileId &&
|
|
570
|
+
(t.status === CCRON_TICK_LIFECYCLE_V2.QUEUED ||
|
|
571
|
+
t.status === CCRON_TICK_LIFECYCLE_V2.RUNNING)
|
|
572
|
+
)
|
|
573
|
+
c++;
|
|
574
|
+
return c;
|
|
575
|
+
}
|
|
576
|
+
export function setMaxActiveCcronProfilesPerOwnerV2(n) {
|
|
577
|
+
_ccronMaxActive = _ccronPos(n, "maxActiveCcronProfilesPerOwner");
|
|
578
|
+
}
|
|
579
|
+
export function getMaxActiveCcronProfilesPerOwnerV2() {
|
|
580
|
+
return _ccronMaxActive;
|
|
581
|
+
}
|
|
582
|
+
export function setMaxPendingCcronTicksPerProfileV2(n) {
|
|
583
|
+
_ccronMaxPending = _ccronPos(n, "maxPendingCcronTicksPerProfile");
|
|
584
|
+
}
|
|
585
|
+
export function getMaxPendingCcronTicksPerProfileV2() {
|
|
586
|
+
return _ccronMaxPending;
|
|
587
|
+
}
|
|
588
|
+
export function setCcronProfileIdleMsV2(n) {
|
|
589
|
+
_ccronIdleMs = _ccronPos(n, "ccronProfileIdleMs");
|
|
590
|
+
}
|
|
591
|
+
export function getCcronProfileIdleMsV2() {
|
|
592
|
+
return _ccronIdleMs;
|
|
593
|
+
}
|
|
594
|
+
export function setCcronTickStuckMsV2(n) {
|
|
595
|
+
_ccronStuckMs = _ccronPos(n, "ccronTickStuckMs");
|
|
596
|
+
}
|
|
597
|
+
export function getCcronTickStuckMsV2() {
|
|
598
|
+
return _ccronStuckMs;
|
|
599
|
+
}
|
|
600
|
+
export function _resetStateCoworkCronV2() {
|
|
601
|
+
_ccronPsV2.clear();
|
|
602
|
+
_ccronTsV2.clear();
|
|
603
|
+
_ccronMaxActive = 6;
|
|
604
|
+
_ccronMaxPending = 15;
|
|
605
|
+
_ccronIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
606
|
+
_ccronStuckMs = 60 * 1000;
|
|
607
|
+
}
|
|
608
|
+
export function registerCcronProfileV2({ id, owner, expr, metadata } = {}) {
|
|
609
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
610
|
+
if (_ccronPsV2.has(id)) throw new Error(`ccron profile ${id} already exists`);
|
|
611
|
+
const now = Date.now();
|
|
612
|
+
const p = {
|
|
613
|
+
id,
|
|
614
|
+
owner,
|
|
615
|
+
expr: expr || "0 0 * * *",
|
|
616
|
+
status: CCRON_PROFILE_MATURITY_V2.PENDING,
|
|
617
|
+
createdAt: now,
|
|
618
|
+
updatedAt: now,
|
|
619
|
+
lastTouchedAt: now,
|
|
620
|
+
activatedAt: null,
|
|
621
|
+
archivedAt: null,
|
|
622
|
+
metadata: { ...(metadata || {}) },
|
|
623
|
+
};
|
|
624
|
+
_ccronPsV2.set(id, p);
|
|
625
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
626
|
+
}
|
|
627
|
+
export function activateCcronProfileV2(id) {
|
|
628
|
+
const p = _ccronPsV2.get(id);
|
|
629
|
+
if (!p) throw new Error(`ccron profile ${id} not found`);
|
|
630
|
+
const isInitial = p.status === CCRON_PROFILE_MATURITY_V2.PENDING;
|
|
631
|
+
_ccronCheckP(p.status, CCRON_PROFILE_MATURITY_V2.ACTIVE);
|
|
632
|
+
if (isInitial && _ccronCountActive(p.owner) >= _ccronMaxActive)
|
|
633
|
+
throw new Error(`max active ccron profiles for owner ${p.owner} reached`);
|
|
634
|
+
const now = Date.now();
|
|
635
|
+
p.status = CCRON_PROFILE_MATURITY_V2.ACTIVE;
|
|
636
|
+
p.updatedAt = now;
|
|
637
|
+
p.lastTouchedAt = now;
|
|
638
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
639
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
640
|
+
}
|
|
641
|
+
export function pauseCcronProfileV2(id) {
|
|
642
|
+
const p = _ccronPsV2.get(id);
|
|
643
|
+
if (!p) throw new Error(`ccron profile ${id} not found`);
|
|
644
|
+
_ccronCheckP(p.status, CCRON_PROFILE_MATURITY_V2.PAUSED);
|
|
645
|
+
p.status = CCRON_PROFILE_MATURITY_V2.PAUSED;
|
|
646
|
+
p.updatedAt = Date.now();
|
|
647
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
648
|
+
}
|
|
649
|
+
export function archiveCcronProfileV2(id) {
|
|
650
|
+
const p = _ccronPsV2.get(id);
|
|
651
|
+
if (!p) throw new Error(`ccron profile ${id} not found`);
|
|
652
|
+
_ccronCheckP(p.status, CCRON_PROFILE_MATURITY_V2.ARCHIVED);
|
|
653
|
+
const now = Date.now();
|
|
654
|
+
p.status = CCRON_PROFILE_MATURITY_V2.ARCHIVED;
|
|
655
|
+
p.updatedAt = now;
|
|
656
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
657
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
658
|
+
}
|
|
659
|
+
export function touchCcronProfileV2(id) {
|
|
660
|
+
const p = _ccronPsV2.get(id);
|
|
661
|
+
if (!p) throw new Error(`ccron profile ${id} not found`);
|
|
662
|
+
if (_ccronPTerminal.has(p.status))
|
|
663
|
+
throw new Error(`cannot touch terminal ccron profile ${id}`);
|
|
664
|
+
const now = Date.now();
|
|
665
|
+
p.lastTouchedAt = now;
|
|
666
|
+
p.updatedAt = now;
|
|
667
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
668
|
+
}
|
|
669
|
+
export function getCcronProfileV2(id) {
|
|
670
|
+
const p = _ccronPsV2.get(id);
|
|
671
|
+
if (!p) return null;
|
|
672
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
673
|
+
}
|
|
674
|
+
export function listCcronProfilesV2() {
|
|
675
|
+
return [..._ccronPsV2.values()].map((p) => ({
|
|
676
|
+
...p,
|
|
677
|
+
metadata: { ...p.metadata },
|
|
678
|
+
}));
|
|
679
|
+
}
|
|
680
|
+
export function createCcronTickV2({ id, profileId, tickAt, metadata } = {}) {
|
|
681
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
682
|
+
if (_ccronTsV2.has(id)) throw new Error(`ccron tick ${id} already exists`);
|
|
683
|
+
if (!_ccronPsV2.has(profileId))
|
|
684
|
+
throw new Error(`ccron profile ${profileId} not found`);
|
|
685
|
+
if (_ccronCountPending(profileId) >= _ccronMaxPending)
|
|
686
|
+
throw new Error(`max pending ccron ticks for profile ${profileId} reached`);
|
|
687
|
+
const now = Date.now();
|
|
688
|
+
const t = {
|
|
689
|
+
id,
|
|
690
|
+
profileId,
|
|
691
|
+
tickAt: tickAt || now,
|
|
692
|
+
status: CCRON_TICK_LIFECYCLE_V2.QUEUED,
|
|
693
|
+
createdAt: now,
|
|
694
|
+
updatedAt: now,
|
|
695
|
+
startedAt: null,
|
|
696
|
+
settledAt: null,
|
|
697
|
+
metadata: { ...(metadata || {}) },
|
|
698
|
+
};
|
|
699
|
+
_ccronTsV2.set(id, t);
|
|
700
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
701
|
+
}
|
|
702
|
+
export function runningCcronTickV2(id) {
|
|
703
|
+
const t = _ccronTsV2.get(id);
|
|
704
|
+
if (!t) throw new Error(`ccron tick ${id} not found`);
|
|
705
|
+
_ccronCheckT(t.status, CCRON_TICK_LIFECYCLE_V2.RUNNING);
|
|
706
|
+
const now = Date.now();
|
|
707
|
+
t.status = CCRON_TICK_LIFECYCLE_V2.RUNNING;
|
|
708
|
+
t.updatedAt = now;
|
|
709
|
+
if (!t.startedAt) t.startedAt = now;
|
|
710
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
711
|
+
}
|
|
712
|
+
export function completeCcronTickV2(id) {
|
|
713
|
+
const t = _ccronTsV2.get(id);
|
|
714
|
+
if (!t) throw new Error(`ccron tick ${id} not found`);
|
|
715
|
+
_ccronCheckT(t.status, CCRON_TICK_LIFECYCLE_V2.COMPLETED);
|
|
716
|
+
const now = Date.now();
|
|
717
|
+
t.status = CCRON_TICK_LIFECYCLE_V2.COMPLETED;
|
|
718
|
+
t.updatedAt = now;
|
|
719
|
+
if (!t.settledAt) t.settledAt = now;
|
|
720
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
721
|
+
}
|
|
722
|
+
export function failCcronTickV2(id, reason) {
|
|
723
|
+
const t = _ccronTsV2.get(id);
|
|
724
|
+
if (!t) throw new Error(`ccron tick ${id} not found`);
|
|
725
|
+
_ccronCheckT(t.status, CCRON_TICK_LIFECYCLE_V2.FAILED);
|
|
726
|
+
const now = Date.now();
|
|
727
|
+
t.status = CCRON_TICK_LIFECYCLE_V2.FAILED;
|
|
728
|
+
t.updatedAt = now;
|
|
729
|
+
if (!t.settledAt) t.settledAt = now;
|
|
730
|
+
if (reason) t.metadata.failReason = String(reason);
|
|
731
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
732
|
+
}
|
|
733
|
+
export function cancelCcronTickV2(id, reason) {
|
|
734
|
+
const t = _ccronTsV2.get(id);
|
|
735
|
+
if (!t) throw new Error(`ccron tick ${id} not found`);
|
|
736
|
+
_ccronCheckT(t.status, CCRON_TICK_LIFECYCLE_V2.CANCELLED);
|
|
737
|
+
const now = Date.now();
|
|
738
|
+
t.status = CCRON_TICK_LIFECYCLE_V2.CANCELLED;
|
|
739
|
+
t.updatedAt = now;
|
|
740
|
+
if (!t.settledAt) t.settledAt = now;
|
|
741
|
+
if (reason) t.metadata.cancelReason = String(reason);
|
|
742
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
743
|
+
}
|
|
744
|
+
export function getCcronTickV2(id) {
|
|
745
|
+
const t = _ccronTsV2.get(id);
|
|
746
|
+
if (!t) return null;
|
|
747
|
+
return { ...t, metadata: { ...t.metadata } };
|
|
748
|
+
}
|
|
749
|
+
export function listCcronTicksV2() {
|
|
750
|
+
return [..._ccronTsV2.values()].map((t) => ({
|
|
751
|
+
...t,
|
|
752
|
+
metadata: { ...t.metadata },
|
|
753
|
+
}));
|
|
754
|
+
}
|
|
755
|
+
export function autoPauseIdleCcronProfilesV2({ now } = {}) {
|
|
756
|
+
const t = now ?? Date.now();
|
|
757
|
+
const flipped = [];
|
|
758
|
+
for (const p of _ccronPsV2.values())
|
|
759
|
+
if (
|
|
760
|
+
p.status === CCRON_PROFILE_MATURITY_V2.ACTIVE &&
|
|
761
|
+
t - p.lastTouchedAt >= _ccronIdleMs
|
|
762
|
+
) {
|
|
763
|
+
p.status = CCRON_PROFILE_MATURITY_V2.PAUSED;
|
|
764
|
+
p.updatedAt = t;
|
|
765
|
+
flipped.push(p.id);
|
|
766
|
+
}
|
|
767
|
+
return { flipped, count: flipped.length };
|
|
768
|
+
}
|
|
769
|
+
export function autoFailStuckCcronTicksV2({ now } = {}) {
|
|
770
|
+
const t = now ?? Date.now();
|
|
771
|
+
const flipped = [];
|
|
772
|
+
for (const x of _ccronTsV2.values())
|
|
773
|
+
if (
|
|
774
|
+
x.status === CCRON_TICK_LIFECYCLE_V2.RUNNING &&
|
|
775
|
+
x.startedAt != null &&
|
|
776
|
+
t - x.startedAt >= _ccronStuckMs
|
|
777
|
+
) {
|
|
778
|
+
x.status = CCRON_TICK_LIFECYCLE_V2.FAILED;
|
|
779
|
+
x.updatedAt = t;
|
|
780
|
+
if (!x.settledAt) x.settledAt = t;
|
|
781
|
+
x.metadata.failReason = "auto-fail-stuck";
|
|
782
|
+
flipped.push(x.id);
|
|
783
|
+
}
|
|
784
|
+
return { flipped, count: flipped.length };
|
|
785
|
+
}
|
|
786
|
+
export function getCoworkCronGovStatsV2() {
|
|
787
|
+
const profilesByStatus = {};
|
|
788
|
+
for (const v of Object.values(CCRON_PROFILE_MATURITY_V2))
|
|
789
|
+
profilesByStatus[v] = 0;
|
|
790
|
+
for (const p of _ccronPsV2.values()) profilesByStatus[p.status]++;
|
|
791
|
+
const ticksByStatus = {};
|
|
792
|
+
for (const v of Object.values(CCRON_TICK_LIFECYCLE_V2)) ticksByStatus[v] = 0;
|
|
793
|
+
for (const t of _ccronTsV2.values()) ticksByStatus[t.status]++;
|
|
794
|
+
return {
|
|
795
|
+
totalCcronProfilesV2: _ccronPsV2.size,
|
|
796
|
+
totalCcronTicksV2: _ccronTsV2.size,
|
|
797
|
+
maxActiveCcronProfilesPerOwner: _ccronMaxActive,
|
|
798
|
+
maxPendingCcronTicksPerProfile: _ccronMaxPending,
|
|
799
|
+
ccronProfileIdleMs: _ccronIdleMs,
|
|
800
|
+
ccronTickStuckMs: _ccronStuckMs,
|
|
801
|
+
profilesByStatus,
|
|
802
|
+
ticksByStatus,
|
|
803
|
+
};
|
|
804
|
+
}
|
|
@@ -436,3 +436,336 @@ export function applyPromptPatch(cwd, patch) {
|
|
|
436
436
|
systemPromptExtension: extended,
|
|
437
437
|
};
|
|
438
438
|
}
|
|
439
|
+
|
|
440
|
+
// =====================================================================
|
|
441
|
+
// cowork-learning V2 governance overlay (iter17)
|
|
442
|
+
// =====================================================================
|
|
443
|
+
export const LEARN_PROFILE_MATURITY_V2 = Object.freeze({
|
|
444
|
+
PENDING: "pending",
|
|
445
|
+
ACTIVE: "active",
|
|
446
|
+
STALE: "stale",
|
|
447
|
+
ARCHIVED: "archived",
|
|
448
|
+
});
|
|
449
|
+
export const LEARN_SAMPLE_LIFECYCLE_V2 = Object.freeze({
|
|
450
|
+
QUEUED: "queued",
|
|
451
|
+
TRAINING: "training",
|
|
452
|
+
TRAINED: "trained",
|
|
453
|
+
FAILED: "failed",
|
|
454
|
+
CANCELLED: "cancelled",
|
|
455
|
+
});
|
|
456
|
+
const _learnPTrans = new Map([
|
|
457
|
+
[
|
|
458
|
+
LEARN_PROFILE_MATURITY_V2.PENDING,
|
|
459
|
+
new Set([
|
|
460
|
+
LEARN_PROFILE_MATURITY_V2.ACTIVE,
|
|
461
|
+
LEARN_PROFILE_MATURITY_V2.ARCHIVED,
|
|
462
|
+
]),
|
|
463
|
+
],
|
|
464
|
+
[
|
|
465
|
+
LEARN_PROFILE_MATURITY_V2.ACTIVE,
|
|
466
|
+
new Set([
|
|
467
|
+
LEARN_PROFILE_MATURITY_V2.STALE,
|
|
468
|
+
LEARN_PROFILE_MATURITY_V2.ARCHIVED,
|
|
469
|
+
]),
|
|
470
|
+
],
|
|
471
|
+
[
|
|
472
|
+
LEARN_PROFILE_MATURITY_V2.STALE,
|
|
473
|
+
new Set([
|
|
474
|
+
LEARN_PROFILE_MATURITY_V2.ACTIVE,
|
|
475
|
+
LEARN_PROFILE_MATURITY_V2.ARCHIVED,
|
|
476
|
+
]),
|
|
477
|
+
],
|
|
478
|
+
[LEARN_PROFILE_MATURITY_V2.ARCHIVED, new Set()],
|
|
479
|
+
]);
|
|
480
|
+
const _learnPTerminal = new Set([LEARN_PROFILE_MATURITY_V2.ARCHIVED]);
|
|
481
|
+
const _learnJTrans = new Map([
|
|
482
|
+
[
|
|
483
|
+
LEARN_SAMPLE_LIFECYCLE_V2.QUEUED,
|
|
484
|
+
new Set([
|
|
485
|
+
LEARN_SAMPLE_LIFECYCLE_V2.TRAINING,
|
|
486
|
+
LEARN_SAMPLE_LIFECYCLE_V2.CANCELLED,
|
|
487
|
+
]),
|
|
488
|
+
],
|
|
489
|
+
[
|
|
490
|
+
LEARN_SAMPLE_LIFECYCLE_V2.TRAINING,
|
|
491
|
+
new Set([
|
|
492
|
+
LEARN_SAMPLE_LIFECYCLE_V2.TRAINED,
|
|
493
|
+
LEARN_SAMPLE_LIFECYCLE_V2.FAILED,
|
|
494
|
+
LEARN_SAMPLE_LIFECYCLE_V2.CANCELLED,
|
|
495
|
+
]),
|
|
496
|
+
],
|
|
497
|
+
[LEARN_SAMPLE_LIFECYCLE_V2.TRAINED, new Set()],
|
|
498
|
+
[LEARN_SAMPLE_LIFECYCLE_V2.FAILED, new Set()],
|
|
499
|
+
[LEARN_SAMPLE_LIFECYCLE_V2.CANCELLED, new Set()],
|
|
500
|
+
]);
|
|
501
|
+
const _learnPsV2 = new Map();
|
|
502
|
+
const _learnJsV2 = new Map();
|
|
503
|
+
let _learnMaxActive = 6,
|
|
504
|
+
_learnMaxPending = 20,
|
|
505
|
+
_learnIdleMs = 30 * 24 * 60 * 60 * 1000,
|
|
506
|
+
_learnStuckMs = 60 * 1000;
|
|
507
|
+
function _learnPos(n, label) {
|
|
508
|
+
const v = Math.floor(Number(n));
|
|
509
|
+
if (!Number.isFinite(v) || v <= 0)
|
|
510
|
+
throw new Error(`${label} must be positive integer`);
|
|
511
|
+
return v;
|
|
512
|
+
}
|
|
513
|
+
function _learnCheckP(from, to) {
|
|
514
|
+
const a = _learnPTrans.get(from);
|
|
515
|
+
if (!a || !a.has(to))
|
|
516
|
+
throw new Error(`invalid learn profile transition ${from} → ${to}`);
|
|
517
|
+
}
|
|
518
|
+
function _learnCheckJ(from, to) {
|
|
519
|
+
const a = _learnJTrans.get(from);
|
|
520
|
+
if (!a || !a.has(to))
|
|
521
|
+
throw new Error(`invalid learn sample transition ${from} → ${to}`);
|
|
522
|
+
}
|
|
523
|
+
function _learnCountActive(owner) {
|
|
524
|
+
let c = 0;
|
|
525
|
+
for (const p of _learnPsV2.values())
|
|
526
|
+
if (p.owner === owner && p.status === LEARN_PROFILE_MATURITY_V2.ACTIVE) c++;
|
|
527
|
+
return c;
|
|
528
|
+
}
|
|
529
|
+
function _learnCountPending(profileId) {
|
|
530
|
+
let c = 0;
|
|
531
|
+
for (const j of _learnJsV2.values())
|
|
532
|
+
if (
|
|
533
|
+
j.profileId === profileId &&
|
|
534
|
+
(j.status === LEARN_SAMPLE_LIFECYCLE_V2.QUEUED ||
|
|
535
|
+
j.status === LEARN_SAMPLE_LIFECYCLE_V2.TRAINING)
|
|
536
|
+
)
|
|
537
|
+
c++;
|
|
538
|
+
return c;
|
|
539
|
+
}
|
|
540
|
+
export function setMaxActiveLearnProfilesPerOwnerV2(n) {
|
|
541
|
+
_learnMaxActive = _learnPos(n, "maxActiveLearnProfilesPerOwner");
|
|
542
|
+
}
|
|
543
|
+
export function getMaxActiveLearnProfilesPerOwnerV2() {
|
|
544
|
+
return _learnMaxActive;
|
|
545
|
+
}
|
|
546
|
+
export function setMaxPendingLearnSamplesPerProfileV2(n) {
|
|
547
|
+
_learnMaxPending = _learnPos(n, "maxPendingLearnSamplesPerProfile");
|
|
548
|
+
}
|
|
549
|
+
export function getMaxPendingLearnSamplesPerProfileV2() {
|
|
550
|
+
return _learnMaxPending;
|
|
551
|
+
}
|
|
552
|
+
export function setLearnProfileIdleMsV2(n) {
|
|
553
|
+
_learnIdleMs = _learnPos(n, "learnProfileIdleMs");
|
|
554
|
+
}
|
|
555
|
+
export function getLearnProfileIdleMsV2() {
|
|
556
|
+
return _learnIdleMs;
|
|
557
|
+
}
|
|
558
|
+
export function setLearnSampleStuckMsV2(n) {
|
|
559
|
+
_learnStuckMs = _learnPos(n, "learnSampleStuckMs");
|
|
560
|
+
}
|
|
561
|
+
export function getLearnSampleStuckMsV2() {
|
|
562
|
+
return _learnStuckMs;
|
|
563
|
+
}
|
|
564
|
+
export function _resetStateCoworkLearningV2() {
|
|
565
|
+
_learnPsV2.clear();
|
|
566
|
+
_learnJsV2.clear();
|
|
567
|
+
_learnMaxActive = 6;
|
|
568
|
+
_learnMaxPending = 20;
|
|
569
|
+
_learnIdleMs = 30 * 24 * 60 * 60 * 1000;
|
|
570
|
+
_learnStuckMs = 60 * 1000;
|
|
571
|
+
}
|
|
572
|
+
export function registerLearnProfileV2({ id, owner, topic, metadata } = {}) {
|
|
573
|
+
if (!id || !owner) throw new Error("id and owner required");
|
|
574
|
+
if (_learnPsV2.has(id)) throw new Error(`learn profile ${id} already exists`);
|
|
575
|
+
const now = Date.now();
|
|
576
|
+
const p = {
|
|
577
|
+
id,
|
|
578
|
+
owner,
|
|
579
|
+
topic: topic || "general",
|
|
580
|
+
status: LEARN_PROFILE_MATURITY_V2.PENDING,
|
|
581
|
+
createdAt: now,
|
|
582
|
+
updatedAt: now,
|
|
583
|
+
lastTouchedAt: now,
|
|
584
|
+
activatedAt: null,
|
|
585
|
+
archivedAt: null,
|
|
586
|
+
metadata: { ...(metadata || {}) },
|
|
587
|
+
};
|
|
588
|
+
_learnPsV2.set(id, p);
|
|
589
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
590
|
+
}
|
|
591
|
+
export function activateLearnProfileV2(id) {
|
|
592
|
+
const p = _learnPsV2.get(id);
|
|
593
|
+
if (!p) throw new Error(`learn profile ${id} not found`);
|
|
594
|
+
const isInitial = p.status === LEARN_PROFILE_MATURITY_V2.PENDING;
|
|
595
|
+
_learnCheckP(p.status, LEARN_PROFILE_MATURITY_V2.ACTIVE);
|
|
596
|
+
if (isInitial && _learnCountActive(p.owner) >= _learnMaxActive)
|
|
597
|
+
throw new Error(`max active learn profiles for owner ${p.owner} reached`);
|
|
598
|
+
const now = Date.now();
|
|
599
|
+
p.status = LEARN_PROFILE_MATURITY_V2.ACTIVE;
|
|
600
|
+
p.updatedAt = now;
|
|
601
|
+
p.lastTouchedAt = now;
|
|
602
|
+
if (!p.activatedAt) p.activatedAt = now;
|
|
603
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
604
|
+
}
|
|
605
|
+
export function staleLearnProfileV2(id) {
|
|
606
|
+
const p = _learnPsV2.get(id);
|
|
607
|
+
if (!p) throw new Error(`learn profile ${id} not found`);
|
|
608
|
+
_learnCheckP(p.status, LEARN_PROFILE_MATURITY_V2.STALE);
|
|
609
|
+
p.status = LEARN_PROFILE_MATURITY_V2.STALE;
|
|
610
|
+
p.updatedAt = Date.now();
|
|
611
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
612
|
+
}
|
|
613
|
+
export function archiveLearnProfileV2(id) {
|
|
614
|
+
const p = _learnPsV2.get(id);
|
|
615
|
+
if (!p) throw new Error(`learn profile ${id} not found`);
|
|
616
|
+
_learnCheckP(p.status, LEARN_PROFILE_MATURITY_V2.ARCHIVED);
|
|
617
|
+
const now = Date.now();
|
|
618
|
+
p.status = LEARN_PROFILE_MATURITY_V2.ARCHIVED;
|
|
619
|
+
p.updatedAt = now;
|
|
620
|
+
if (!p.archivedAt) p.archivedAt = now;
|
|
621
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
622
|
+
}
|
|
623
|
+
export function touchLearnProfileV2(id) {
|
|
624
|
+
const p = _learnPsV2.get(id);
|
|
625
|
+
if (!p) throw new Error(`learn profile ${id} not found`);
|
|
626
|
+
if (_learnPTerminal.has(p.status))
|
|
627
|
+
throw new Error(`cannot touch terminal learn profile ${id}`);
|
|
628
|
+
const now = Date.now();
|
|
629
|
+
p.lastTouchedAt = now;
|
|
630
|
+
p.updatedAt = now;
|
|
631
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
632
|
+
}
|
|
633
|
+
export function getLearnProfileV2(id) {
|
|
634
|
+
const p = _learnPsV2.get(id);
|
|
635
|
+
if (!p) return null;
|
|
636
|
+
return { ...p, metadata: { ...p.metadata } };
|
|
637
|
+
}
|
|
638
|
+
export function listLearnProfilesV2() {
|
|
639
|
+
return [..._learnPsV2.values()].map((p) => ({
|
|
640
|
+
...p,
|
|
641
|
+
metadata: { ...p.metadata },
|
|
642
|
+
}));
|
|
643
|
+
}
|
|
644
|
+
export function createLearnSampleV2({ id, profileId, signal, metadata } = {}) {
|
|
645
|
+
if (!id || !profileId) throw new Error("id and profileId required");
|
|
646
|
+
if (_learnJsV2.has(id)) throw new Error(`learn sample ${id} already exists`);
|
|
647
|
+
if (!_learnPsV2.has(profileId))
|
|
648
|
+
throw new Error(`learn profile ${profileId} not found`);
|
|
649
|
+
if (_learnCountPending(profileId) >= _learnMaxPending)
|
|
650
|
+
throw new Error(
|
|
651
|
+
`max pending learn samples for profile ${profileId} reached`,
|
|
652
|
+
);
|
|
653
|
+
const now = Date.now();
|
|
654
|
+
const j = {
|
|
655
|
+
id,
|
|
656
|
+
profileId,
|
|
657
|
+
signal: signal || "",
|
|
658
|
+
status: LEARN_SAMPLE_LIFECYCLE_V2.QUEUED,
|
|
659
|
+
createdAt: now,
|
|
660
|
+
updatedAt: now,
|
|
661
|
+
startedAt: null,
|
|
662
|
+
settledAt: null,
|
|
663
|
+
metadata: { ...(metadata || {}) },
|
|
664
|
+
};
|
|
665
|
+
_learnJsV2.set(id, j);
|
|
666
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
667
|
+
}
|
|
668
|
+
export function trainingLearnSampleV2(id) {
|
|
669
|
+
const j = _learnJsV2.get(id);
|
|
670
|
+
if (!j) throw new Error(`learn sample ${id} not found`);
|
|
671
|
+
_learnCheckJ(j.status, LEARN_SAMPLE_LIFECYCLE_V2.TRAINING);
|
|
672
|
+
const now = Date.now();
|
|
673
|
+
j.status = LEARN_SAMPLE_LIFECYCLE_V2.TRAINING;
|
|
674
|
+
j.updatedAt = now;
|
|
675
|
+
if (!j.startedAt) j.startedAt = now;
|
|
676
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
677
|
+
}
|
|
678
|
+
export function completeSampleLearnV2(id) {
|
|
679
|
+
const j = _learnJsV2.get(id);
|
|
680
|
+
if (!j) throw new Error(`learn sample ${id} not found`);
|
|
681
|
+
_learnCheckJ(j.status, LEARN_SAMPLE_LIFECYCLE_V2.TRAINED);
|
|
682
|
+
const now = Date.now();
|
|
683
|
+
j.status = LEARN_SAMPLE_LIFECYCLE_V2.TRAINED;
|
|
684
|
+
j.updatedAt = now;
|
|
685
|
+
if (!j.settledAt) j.settledAt = now;
|
|
686
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
687
|
+
}
|
|
688
|
+
export function failLearnSampleV2(id, reason) {
|
|
689
|
+
const j = _learnJsV2.get(id);
|
|
690
|
+
if (!j) throw new Error(`learn sample ${id} not found`);
|
|
691
|
+
_learnCheckJ(j.status, LEARN_SAMPLE_LIFECYCLE_V2.FAILED);
|
|
692
|
+
const now = Date.now();
|
|
693
|
+
j.status = LEARN_SAMPLE_LIFECYCLE_V2.FAILED;
|
|
694
|
+
j.updatedAt = now;
|
|
695
|
+
if (!j.settledAt) j.settledAt = now;
|
|
696
|
+
if (reason) j.metadata.failReason = String(reason);
|
|
697
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
698
|
+
}
|
|
699
|
+
export function cancelLearnSampleV2(id, reason) {
|
|
700
|
+
const j = _learnJsV2.get(id);
|
|
701
|
+
if (!j) throw new Error(`learn sample ${id} not found`);
|
|
702
|
+
_learnCheckJ(j.status, LEARN_SAMPLE_LIFECYCLE_V2.CANCELLED);
|
|
703
|
+
const now = Date.now();
|
|
704
|
+
j.status = LEARN_SAMPLE_LIFECYCLE_V2.CANCELLED;
|
|
705
|
+
j.updatedAt = now;
|
|
706
|
+
if (!j.settledAt) j.settledAt = now;
|
|
707
|
+
if (reason) j.metadata.cancelReason = String(reason);
|
|
708
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
709
|
+
}
|
|
710
|
+
export function getLearnSampleV2(id) {
|
|
711
|
+
const j = _learnJsV2.get(id);
|
|
712
|
+
if (!j) return null;
|
|
713
|
+
return { ...j, metadata: { ...j.metadata } };
|
|
714
|
+
}
|
|
715
|
+
export function listLearnSamplesV2() {
|
|
716
|
+
return [..._learnJsV2.values()].map((j) => ({
|
|
717
|
+
...j,
|
|
718
|
+
metadata: { ...j.metadata },
|
|
719
|
+
}));
|
|
720
|
+
}
|
|
721
|
+
export function autoStaleIdleLearnProfilesV2({ now } = {}) {
|
|
722
|
+
const t = now ?? Date.now();
|
|
723
|
+
const flipped = [];
|
|
724
|
+
for (const p of _learnPsV2.values())
|
|
725
|
+
if (
|
|
726
|
+
p.status === LEARN_PROFILE_MATURITY_V2.ACTIVE &&
|
|
727
|
+
t - p.lastTouchedAt >= _learnIdleMs
|
|
728
|
+
) {
|
|
729
|
+
p.status = LEARN_PROFILE_MATURITY_V2.STALE;
|
|
730
|
+
p.updatedAt = t;
|
|
731
|
+
flipped.push(p.id);
|
|
732
|
+
}
|
|
733
|
+
return { flipped, count: flipped.length };
|
|
734
|
+
}
|
|
735
|
+
export function autoFailStuckLearnSamplesV2({ now } = {}) {
|
|
736
|
+
const t = now ?? Date.now();
|
|
737
|
+
const flipped = [];
|
|
738
|
+
for (const j of _learnJsV2.values())
|
|
739
|
+
if (
|
|
740
|
+
j.status === LEARN_SAMPLE_LIFECYCLE_V2.TRAINING &&
|
|
741
|
+
j.startedAt != null &&
|
|
742
|
+
t - j.startedAt >= _learnStuckMs
|
|
743
|
+
) {
|
|
744
|
+
j.status = LEARN_SAMPLE_LIFECYCLE_V2.FAILED;
|
|
745
|
+
j.updatedAt = t;
|
|
746
|
+
if (!j.settledAt) j.settledAt = t;
|
|
747
|
+
j.metadata.failReason = "auto-fail-stuck";
|
|
748
|
+
flipped.push(j.id);
|
|
749
|
+
}
|
|
750
|
+
return { flipped, count: flipped.length };
|
|
751
|
+
}
|
|
752
|
+
export function getCoworkLearningGovStatsV2() {
|
|
753
|
+
const profilesByStatus = {};
|
|
754
|
+
for (const v of Object.values(LEARN_PROFILE_MATURITY_V2))
|
|
755
|
+
profilesByStatus[v] = 0;
|
|
756
|
+
for (const p of _learnPsV2.values()) profilesByStatus[p.status]++;
|
|
757
|
+
const samplesByStatus = {};
|
|
758
|
+
for (const v of Object.values(LEARN_SAMPLE_LIFECYCLE_V2))
|
|
759
|
+
samplesByStatus[v] = 0;
|
|
760
|
+
for (const j of _learnJsV2.values()) samplesByStatus[j.status]++;
|
|
761
|
+
return {
|
|
762
|
+
totalLearnProfilesV2: _learnPsV2.size,
|
|
763
|
+
totalLearnSamplesV2: _learnJsV2.size,
|
|
764
|
+
maxActiveLearnProfilesPerOwner: _learnMaxActive,
|
|
765
|
+
maxPendingLearnSamplesPerProfile: _learnMaxPending,
|
|
766
|
+
learnProfileIdleMs: _learnIdleMs,
|
|
767
|
+
learnSampleStuckMs: _learnStuckMs,
|
|
768
|
+
profilesByStatus,
|
|
769
|
+
samplesByStatus,
|
|
770
|
+
};
|
|
771
|
+
}
|