@claude-flow/cli 3.65.0 → 3.66.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/.claude/helpers/helpers.manifest.json +5 -4
- package/.claude/helpers/hook-handler.cjs +66 -0
- package/.claude/helpers/learning-loop.cjs +594 -0
- package/catalog-manifest.json +2 -2
- package/dist/src/commands/hooks.js +4 -1
- package/dist/src/init/executor.js +1 -1
- package/dist/src/init/helper-refresh.js +4 -0
- package/dist/src/mcp-tools/http-fetch-pinned.d.ts +44 -0
- package/dist/src/mcp-tools/http-fetch-pinned.js +148 -0
- package/dist/src/mcp-tools/http-fetch-tools.d.ts +11 -2
- package/dist/src/mcp-tools/http-fetch-tools.js +19 -70
- package/dist/src/memory/sona-optimizer.d.ts +7 -0
- package/dist/src/memory/sona-optimizer.js +36 -6
- package/dist/src/memory/verified-lessons.d.ts +80 -0
- package/dist/src/memory/verified-lessons.js +113 -0
- package/dist/src/memory/verified-outcomes.d.ts +9 -47
- package/dist/src/memory/verified-outcomes.js +11 -46
- package/dist/src/update/rate-limiter.d.ts +6 -0
- package/dist/src/update/rate-limiter.js +12 -1
- package/package.json +1 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": {
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.66.0",
|
|
4
4
|
"files": {
|
|
5
5
|
"auto-memory-hook.mjs": "631fac9d518835e2852a406888316bbbddddb49e7ed8e406d2e971f46833df9a",
|
|
6
|
-
"hook-handler.cjs": "
|
|
6
|
+
"hook-handler.cjs": "0ce70981aa33f76d008b6f49626effaf4269918c4094f1a28c1ef6fceb097d6f",
|
|
7
7
|
"intelligence.cjs": "1d981d6c6a35d70a66450e96458e26169e0cede11523ea246a2c129c197a5b4e",
|
|
8
8
|
"statusline.cjs": "d72417ecb38634011a19f095a30e07b9929e6f97663520172ece9be7491b2eaa",
|
|
9
|
-
"router.cjs": "16648b3c0d73b6681ac2d8d13def6a68286c57f5a11004de5b19a0fa088c833d"
|
|
9
|
+
"router.cjs": "16648b3c0d73b6681ac2d8d13def6a68286c57f5a11004de5b19a0fa088c833d",
|
|
10
|
+
"learning-loop.cjs": "d046cd6f8efb7dd40e1d2451516c181fc8b26477aefb1124c0df5f52a23f9190"
|
|
10
11
|
}
|
|
11
12
|
},
|
|
12
|
-
"signature": "
|
|
13
|
+
"signature": "0JTgpgicsDJAdV6HhU9yPawpjklEbbSsyFjLJAqSh2jX9Jx8w4I5wS/EPnd5yp66HNpgU0up0Shay0qTdHeZAA==",
|
|
13
14
|
"algorithm": "ed25519"
|
|
14
15
|
}
|
|
@@ -647,6 +647,8 @@ const router = safeRequire(path.join(helpersDir, 'router.cjs'));
|
|
|
647
647
|
const session = safeRequire(path.join(helpersDir, 'session.cjs'));
|
|
648
648
|
const memory = safeRequire(path.join(helpersDir, 'memory.cjs'));
|
|
649
649
|
const intelligence = safeRequire(path.join(helpersDir, 'intelligence.cjs'));
|
|
650
|
+
// ADR-512: the verified-outcome learning loop, bundled from the ruflo-mods loop source.
|
|
651
|
+
const learningLoop = safeRequire(path.join(helpersDir, 'learning-loop.cjs'));
|
|
650
652
|
|
|
651
653
|
// ── Intelligence timeout protection (fixes #1530, #1531) ───────────────────
|
|
652
654
|
const INTELLIGENCE_TIMEOUT_MS = 3000;
|
|
@@ -703,6 +705,50 @@ async function readStdin() {
|
|
|
703
705
|
// keeps it from firing twice. Only side-effect events can be handed over:
|
|
704
706
|
// guards such as pre-bash always run, whatever the variable says.
|
|
705
707
|
const MOD_OWNABLE_EVENTS = new Set(['route', 'post-edit']);
|
|
708
|
+
|
|
709
|
+
// ADR-512: classic hooks run the verified-outcome learning loop for users without the mod. A
|
|
710
|
+
// mod that records turns itself says so with `learning-loop` (or, before ADR-512, owns
|
|
711
|
+
// `route`), so a turn is never recorded twice.
|
|
712
|
+
function modRecordsTurns(env = process.env) {
|
|
713
|
+
return String(env.RUFLO_MODS_OWNS || '').split(',').some((owned) => ['learning-loop', 'route'].includes(owned.trim()));
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
function learningLoopRoot() {
|
|
717
|
+
return process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// Records the turns the session transcript gained since the last look (all of them when the
|
|
721
|
+
// session ends). Returns the number recorded; never throws.
|
|
722
|
+
function recordLearningTurns(hookInput, final) {
|
|
723
|
+
try {
|
|
724
|
+
const root = learningLoopRoot();
|
|
725
|
+
if (!learningLoop || modRecordsTurns() || !learningLoop.enabled(root)) return 0;
|
|
726
|
+
const agentFor = (text) => {
|
|
727
|
+
try { return (router && router.routeTask && router.routeTask(text).agent) || 'coder'; } catch (e) { return 'coder'; }
|
|
728
|
+
};
|
|
729
|
+
return learningLoop.recordTurns({
|
|
730
|
+
root,
|
|
731
|
+
transcriptPath: hookInput.transcript_path || hookInput.transcriptPath,
|
|
732
|
+
session: hookInput.session_id || hookInput.sessionId,
|
|
733
|
+
final,
|
|
734
|
+
agentFor,
|
|
735
|
+
});
|
|
736
|
+
} catch (e) { return 0; }
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Trains SONA from the recorded turns in a detached `ruflo hooks verified-ingest` (a hook has
|
|
740
|
+
// seconds; an ingest may take longer). At most one spawn a minute per project.
|
|
741
|
+
function spawnLearningIngest() {
|
|
742
|
+
try {
|
|
743
|
+
const root = learningLoopRoot();
|
|
744
|
+
if (!learningLoop || !learningLoop.enabled(root) || !learningLoop.ingestDue(root)) return;
|
|
745
|
+
const stamp = path.join(root, '.claude-flow', 'data', 'verified-ingest.spawned');
|
|
746
|
+
try { if (Date.now() - fs.statSync(stamp).mtimeMs < 60 * 1000) return; } catch (e) { /* never spawned */ }
|
|
747
|
+
fs.mkdirSync(path.dirname(stamp), { recursive: true });
|
|
748
|
+
fs.writeFileSync(stamp, String(Date.now()));
|
|
749
|
+
spawnDetachedHookRefresh('verified-ingest');
|
|
750
|
+
} catch (e) { /* best-effort only */ }
|
|
751
|
+
}
|
|
706
752
|
function ownedByMod(cmd, env = process.env) {
|
|
707
753
|
if (!MOD_OWNABLE_EVENTS.has(cmd)) return false;
|
|
708
754
|
return String(env.RUFLO_MODS_OWNS || '').split(',').some((owned) => owned.trim() === cmd);
|
|
@@ -751,6 +797,16 @@ async function main() {
|
|
|
751
797
|
try { hookInput = JSON.parse(stdinData); } catch (e) { /* ignore parse errors */ }
|
|
752
798
|
}
|
|
753
799
|
|
|
800
|
+
// ADR-512: record what finished and train from it, before the dedup below: it keys session-end
|
|
801
|
+
// on the session id, so after a PreCompact the real SessionEnd would never record the last turn.
|
|
802
|
+
// Recording is idempotent (a per-session transcript offset, ids from transcript positions).
|
|
803
|
+
// PreCompact runs mid-session, where the open turn may still edit and verify: only SessionEnd
|
|
804
|
+
// closes it.
|
|
805
|
+
if (command === 'session-end') {
|
|
806
|
+
recordLearningTurns(hookInput, (hookInput.hook_event_name || hookInput.hookEventName) !== 'PreCompact');
|
|
807
|
+
spawnLearningIngest();
|
|
808
|
+
}
|
|
809
|
+
|
|
754
810
|
if ((command === 'post-edit' || command === 'session-end') &&
|
|
755
811
|
!claimSideEffectEvent(command, stdinData, hookInput)) {
|
|
756
812
|
return;
|
|
@@ -789,6 +845,16 @@ async function main() {
|
|
|
789
845
|
|
|
790
846
|
const handlers = {
|
|
791
847
|
'route': () => {
|
|
848
|
+
// ADR-512: record the turns that finished, then cite the verified lessons that fit this prompt.
|
|
849
|
+
recordLearningTurns(hookInput, false);
|
|
850
|
+
if (learningLoop && !modRecordsTurns()) {
|
|
851
|
+
try {
|
|
852
|
+
if (learningLoop.enabled(learningLoopRoot())) {
|
|
853
|
+
const block = learningLoop.lessonsForPrompt(learningLoopRoot(), prompt);
|
|
854
|
+
if (block) console.log(block);
|
|
855
|
+
}
|
|
856
|
+
} catch (e) { /* non-fatal */ }
|
|
857
|
+
}
|
|
792
858
|
// Inject ranked intelligence context before routing
|
|
793
859
|
// ADR-472: keep the detailed recall so ONE bounded log record (ids, scores, router pick; never the prompt) is appended after routing.
|
|
794
860
|
let recall = null;
|