@soleri/core 9.14.4 → 9.16.7
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/data/flows/deliver.flow.yaml +11 -0
- package/data/flows/design.flow.yaml +4 -14
- package/data/flows/enhance.flow.yaml +10 -0
- package/data/flows/explore.flow.yaml +16 -0
- package/data/flows/fix.flow.yaml +1 -1
- package/data/flows/review.flow.yaml +13 -4
- package/dist/brain/brain.d.ts +9 -0
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +11 -1
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +24 -0
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/types.d.ts +1 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/capabilities/chain-mapping.d.ts.map +1 -1
- package/dist/capabilities/chain-mapping.js +5 -4
- package/dist/capabilities/chain-mapping.js.map +1 -1
- package/dist/capabilities/registry.d.ts +6 -0
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js +3 -2
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/chat/chat-session.d.ts +6 -0
- package/dist/chat/chat-session.d.ts.map +1 -1
- package/dist/chat/chat-session.js +68 -17
- package/dist/chat/chat-session.js.map +1 -1
- package/dist/context/context-engine.js +1 -1
- package/dist/context/context-engine.js.map +1 -1
- package/dist/curator/curator.d.ts +6 -0
- package/dist/curator/curator.d.ts.map +1 -1
- package/dist/curator/curator.js +138 -0
- package/dist/curator/curator.js.map +1 -1
- package/dist/curator/types.d.ts +10 -0
- package/dist/curator/types.d.ts.map +1 -1
- package/dist/engine/bin/soleri-engine.js +0 -0
- package/dist/engine/core-ops.d.ts.map +1 -1
- package/dist/engine/core-ops.js +38 -1
- package/dist/engine/core-ops.js.map +1 -1
- package/dist/flows/epilogue.d.ts +5 -1
- package/dist/flows/epilogue.d.ts.map +1 -1
- package/dist/flows/epilogue.js +11 -3
- package/dist/flows/epilogue.js.map +1 -1
- package/dist/flows/executor.d.ts.map +1 -1
- package/dist/flows/executor.js +13 -5
- package/dist/flows/executor.js.map +1 -1
- package/dist/flows/index.d.ts +1 -2
- package/dist/flows/index.d.ts.map +1 -1
- package/dist/flows/index.js +1 -0
- package/dist/flows/index.js.map +1 -1
- package/dist/flows/plan-builder.d.ts +17 -1
- package/dist/flows/plan-builder.d.ts.map +1 -1
- package/dist/flows/plan-builder.js +67 -6
- package/dist/flows/plan-builder.js.map +1 -1
- package/dist/flows/probes.d.ts +1 -1
- package/dist/flows/probes.d.ts.map +1 -1
- package/dist/flows/probes.js +15 -3
- package/dist/flows/probes.js.map +1 -1
- package/dist/flows/types.d.ts +47 -20
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/flows/types.js +6 -1
- package/dist/flows/types.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/intake/content-classifier.d.ts +10 -4
- package/dist/intake/content-classifier.d.ts.map +1 -1
- package/dist/intake/content-classifier.js +19 -5
- package/dist/intake/content-classifier.js.map +1 -1
- package/dist/intake/text-ingester.d.ts +18 -0
- package/dist/intake/text-ingester.d.ts.map +1 -1
- package/dist/intake/text-ingester.js +37 -13
- package/dist/intake/text-ingester.js.map +1 -1
- package/dist/packs/pack-installer.d.ts.map +1 -1
- package/dist/packs/pack-installer.js +28 -2
- package/dist/packs/pack-installer.js.map +1 -1
- package/dist/planning/planner-types.d.ts +2 -0
- package/dist/planning/planner-types.d.ts.map +1 -1
- package/dist/planning/planner.d.ts +4 -0
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +50 -4
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/playbook-executor.d.ts +10 -1
- package/dist/playbooks/playbook-executor.d.ts.map +1 -1
- package/dist/playbooks/playbook-executor.js +8 -2
- package/dist/playbooks/playbook-executor.js.map +1 -1
- package/dist/playbooks/playbook-types.d.ts +8 -0
- package/dist/playbooks/playbook-types.d.ts.map +1 -1
- package/dist/plugins/types.d.ts +2 -2
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +30 -0
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/admin-ops.d.ts.map +1 -1
- package/dist/runtime/admin-ops.js +60 -21
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/admin-setup-ops.d.ts +11 -0
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
- package/dist/runtime/admin-setup-ops.js +146 -37
- package/dist/runtime/admin-setup-ops.js.map +1 -1
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +38 -12
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +16 -4
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/context-facade.d.ts.map +1 -1
- package/dist/runtime/facades/context-facade.js +9 -3
- package/dist/runtime/facades/context-facade.js.map +1 -1
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
- package/dist/runtime/facades/memory-facade.js +20 -7
- package/dist/runtime/facades/memory-facade.js.map +1 -1
- package/dist/runtime/facades/orchestrate-facade.d.ts.map +1 -1
- package/dist/runtime/facades/orchestrate-facade.js +40 -1
- package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +113 -4
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +24 -3
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts +21 -0
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +132 -38
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +16 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/schema-helpers.d.ts.map +1 -1
- package/dist/runtime/schema-helpers.js +4 -0
- package/dist/runtime/schema-helpers.js.map +1 -1
- package/dist/runtime/types.d.ts +19 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.js +16 -3
- package/dist/runtime/vault-linking-ops.js.map +1 -1
- package/dist/scheduler/cron-validator.d.ts +15 -0
- package/dist/scheduler/cron-validator.d.ts.map +1 -0
- package/dist/scheduler/cron-validator.js +93 -0
- package/dist/scheduler/cron-validator.js.map +1 -0
- package/dist/scheduler/platform-linux.d.ts +14 -0
- package/dist/scheduler/platform-linux.d.ts.map +1 -0
- package/dist/scheduler/platform-linux.js +107 -0
- package/dist/scheduler/platform-linux.js.map +1 -0
- package/dist/scheduler/platform-macos.d.ts +15 -0
- package/dist/scheduler/platform-macos.d.ts.map +1 -0
- package/dist/scheduler/platform-macos.js +131 -0
- package/dist/scheduler/platform-macos.js.map +1 -0
- package/dist/scheduler/scheduler-ops.d.ts +14 -0
- package/dist/scheduler/scheduler-ops.d.ts.map +1 -0
- package/dist/scheduler/scheduler-ops.js +77 -0
- package/dist/scheduler/scheduler-ops.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +55 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -0
- package/dist/scheduler/scheduler.js +144 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/types.d.ts +48 -0
- package/dist/scheduler/types.d.ts.map +1 -0
- package/dist/scheduler/types.js +6 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/skills/sync-skills.d.ts +11 -0
- package/dist/skills/sync-skills.d.ts.map +1 -1
- package/dist/skills/sync-skills.js +132 -38
- package/dist/skills/sync-skills.js.map +1 -1
- package/dist/skills/validate-skills.d.ts +32 -0
- package/dist/skills/validate-skills.d.ts.map +1 -0
- package/dist/skills/validate-skills.js +396 -0
- package/dist/skills/validate-skills.js.map +1 -0
- package/dist/utils/worktree-reaper.d.ts +38 -0
- package/dist/utils/worktree-reaper.d.ts.map +1 -0
- package/dist/utils/worktree-reaper.js +85 -0
- package/dist/utils/worktree-reaper.js.map +1 -0
- package/dist/vault/default-canonical-tags.d.ts +15 -0
- package/dist/vault/default-canonical-tags.d.ts.map +1 -0
- package/dist/vault/default-canonical-tags.js +65 -0
- package/dist/vault/default-canonical-tags.js.map +1 -0
- package/dist/vault/scope-detector.d.ts.map +1 -1
- package/dist/vault/scope-detector.js +37 -4
- package/dist/vault/scope-detector.js.map +1 -1
- package/dist/vault/tag-normalizer.d.ts +42 -0
- package/dist/vault/tag-normalizer.d.ts.map +1 -0
- package/dist/vault/tag-normalizer.js +157 -0
- package/dist/vault/tag-normalizer.js.map +1 -0
- package/dist/vault/vault-entries.d.ts.map +1 -1
- package/dist/vault/vault-entries.js +3 -1
- package/dist/vault/vault-entries.js.map +1 -1
- package/package.json +5 -1
- package/src/__tests__/embeddings.test.ts +3 -3
- package/src/agency/agency-manager.test.ts +4 -4
- package/src/agency/default-rules.test.ts +0 -13
- package/src/brain/brain-intelligence.test.ts +0 -5
- package/src/brain/brain.ts +25 -1
- package/src/brain/intelligence.ts +25 -0
- package/src/brain/second-brain-features.test.ts +2 -14
- package/src/brain/types.ts +1 -0
- package/src/capabilities/chain-mapping.test.ts +1 -6
- package/src/capabilities/chain-mapping.ts +6 -4
- package/src/capabilities/registry.test.ts +1 -1
- package/src/capabilities/registry.ts +9 -2
- package/src/chat/agent-loop.test.ts +1 -1
- package/src/chat/chat-enhanced.test.ts +0 -8
- package/src/chat/chat-session.ts +75 -17
- package/src/chat/chat-transport.test.ts +31 -1
- package/src/claudemd/compose.test.ts +0 -5
- package/src/context/context-engine.test.ts +0 -1
- package/src/context/context-engine.ts +1 -1
- package/src/control/intent-router.test.ts +2 -2
- package/src/curator/curator.ts +180 -0
- package/src/curator/tag-manager.test.ts +0 -4
- package/src/curator/types.ts +10 -0
- package/src/domain-packs/types.test.ts +0 -5
- package/src/dream/dream.test.ts +0 -7
- package/src/enforcement/registry.test.ts +2 -2
- package/src/engine/core-ops.test.ts +4 -22
- package/src/engine/core-ops.ts +36 -1
- package/src/engine/module-manifest.test.ts +1 -31
- package/src/engine/register-engine.test.ts +3 -33
- package/src/errors/retry.test.ts +3 -1
- package/src/flows/chain-runner.test.ts +0 -6
- package/src/flows/context-router.test.ts +3 -3
- package/src/flows/epilogue.test.ts +40 -2
- package/src/flows/epilogue.ts +11 -2
- package/src/flows/executor.test.ts +48 -2
- package/src/flows/executor.ts +15 -5
- package/src/flows/index.ts +1 -3
- package/src/flows/plan-builder.test.ts +201 -0
- package/src/flows/plan-builder.ts +81 -5
- package/src/flows/probes.ts +17 -3
- package/src/flows/types.ts +31 -2
- package/src/health/health-registry.test.ts +3 -1
- package/src/index.ts +24 -0
- package/src/intake/content-classifier.ts +22 -4
- package/src/intake/dedup-gate.test.ts +2 -6
- package/src/intake/text-ingester.test.ts +3 -4
- package/src/intake/text-ingester.ts +61 -12
- package/src/llm/llm-client.test.ts +1 -1
- package/src/llm/utils.test.ts +1 -1
- package/src/migrations/migration-runner.test.ts +0 -1
- package/src/operator/operator-context-store.test.ts +0 -13
- package/src/operator/operator-profile.test.ts +2 -20
- package/src/packs/pack-installer.ts +28 -2
- package/src/packs/pack-system.test.ts +2 -2
- package/src/persona/defaults.test.ts +19 -19
- package/src/planning/gap-passes.test.ts +0 -46
- package/src/planning/gap-patterns.test.ts +0 -42
- package/src/planning/goal-ancestry.test.ts +3 -1
- package/src/planning/plan-lifecycle.test.ts +15 -7
- package/src/planning/planner-types.ts +2 -0
- package/src/planning/planner.test.ts +86 -90
- package/src/planning/planner.ts +56 -4
- package/src/planning/reconciliation-engine.test.ts +3 -10
- package/src/planning/task-complexity-assessor.test.ts +0 -5
- package/src/planning/task-verifier.test.ts +3 -1
- package/src/playbooks/generic/generic-playbooks.test.ts +0 -28
- package/src/playbooks/index.test.ts +0 -55
- package/src/playbooks/playbook-executor.test.ts +76 -0
- package/src/playbooks/playbook-executor.ts +24 -3
- package/src/playbooks/playbook-types.ts +8 -0
- package/src/plugins/plugin-registry.test.ts +6 -2
- package/src/project/project-registry.test.ts +2 -0
- package/src/queue/async-infrastructure.test.ts +6 -4
- package/src/queue/job-queue.test.ts +13 -7
- package/src/runtime/admin-extra-ops.test.ts +35 -30
- package/src/runtime/admin-extra-ops.ts +30 -0
- package/src/runtime/admin-ops.test.ts +0 -4
- package/src/runtime/admin-ops.ts +63 -21
- package/src/runtime/admin-setup-ops.test.ts +229 -13
- package/src/runtime/admin-setup-ops.ts +145 -36
- package/src/runtime/archive-ops.test.ts +0 -28
- package/src/runtime/branching-ops.test.ts +0 -17
- package/src/runtime/capture-ops.test.ts +41 -16
- package/src/runtime/capture-ops.ts +78 -46
- package/src/runtime/chain-ops.test.ts +0 -21
- package/src/runtime/facades/admin-facade.test.ts +0 -34
- package/src/runtime/facades/agency-facade.test.ts +0 -39
- package/src/runtime/facades/archive-facade.test.ts +0 -43
- package/src/runtime/facades/brain-facade.test.ts +8 -99
- package/src/runtime/facades/brain-facade.ts +29 -12
- package/src/runtime/facades/branching-facade.test.ts +30 -17
- package/src/runtime/facades/chat-facade.test.ts +0 -91
- package/src/runtime/facades/chat-service-ops.test.ts +0 -24
- package/src/runtime/facades/chat-session-ops.test.ts +0 -12
- package/src/runtime/facades/chat-transport-ops.test.ts +0 -23
- package/src/runtime/facades/context-facade.test.ts +0 -17
- package/src/runtime/facades/context-facade.ts +11 -4
- package/src/runtime/facades/control-facade.test.ts +0 -30
- package/src/runtime/facades/curator-facade.test.ts +0 -33
- package/src/runtime/facades/intake-facade.test.ts +0 -33
- package/src/runtime/facades/links-facade.test.ts +0 -37
- package/src/runtime/facades/loop-facade.test.ts +0 -26
- package/src/runtime/facades/memory-facade.test.ts +0 -18
- package/src/runtime/facades/memory-facade.ts +27 -11
- package/src/runtime/facades/operator-facade.test.ts +0 -31
- package/src/runtime/facades/orchestrate-facade.test.ts +0 -21
- package/src/runtime/facades/orchestrate-facade.ts +39 -1
- package/src/runtime/facades/plan-facade.test.ts +7 -32
- package/src/runtime/facades/plan-facade.ts +137 -4
- package/src/runtime/facades/review-facade.test.ts +1 -49
- package/src/runtime/facades/sync-facade.test.ts +24 -41
- package/src/runtime/facades/tier-facade.test.ts +30 -22
- package/src/runtime/facades/vault-facade.test.ts +0 -41
- package/src/runtime/facades/vault-facade.ts +26 -3
- package/src/runtime/grading-ops.test.ts +0 -27
- package/src/runtime/intake-ops.test.ts +0 -19
- package/src/runtime/loop-ops.test.ts +0 -48
- package/src/runtime/memory-cross-project-ops.test.ts +0 -14
- package/src/runtime/memory-extra-ops.test.ts +4 -8
- package/src/runtime/orchestrate-ops.test.ts +238 -19
- package/src/runtime/orchestrate-ops.ts +166 -41
- package/src/runtime/pack-ops.test.ts +0 -26
- package/src/runtime/planning-extra-ops.test.ts +2 -14
- package/src/runtime/playbook-ops-execution.test.ts +9 -20
- package/src/runtime/playbook-ops.test.ts +4 -67
- package/src/runtime/review-ops.test.ts +0 -15
- package/src/runtime/runtime.ts +18 -0
- package/src/runtime/schema-helpers.ts +4 -0
- package/src/runtime/sync-ops.test.ts +0 -18
- package/src/runtime/tier-ops.test.ts +0 -21
- package/src/runtime/types.ts +19 -0
- package/src/runtime/vault-extra-ops.test.ts +0 -12
- package/src/runtime/vault-linking-ops.test.ts +0 -4
- package/src/runtime/vault-linking-ops.ts +26 -8
- package/src/runtime/vault-sharing-ops.test.ts +0 -9
- package/src/scheduler/cron-validator.ts +101 -0
- package/src/scheduler/platform-linux.ts +122 -0
- package/src/scheduler/platform-macos.ts +150 -0
- package/src/scheduler/scheduler-ops.ts +77 -0
- package/src/scheduler/scheduler.test.ts +247 -0
- package/src/scheduler/scheduler.ts +174 -0
- package/src/scheduler/types.ts +52 -0
- package/src/skills/__tests__/sync-skills.test.ts +6 -17
- package/src/skills/global-claude-md.test.ts +113 -0
- package/src/skills/sync-skills.ts +143 -35
- package/src/skills/validate-skills.test.ts +206 -0
- package/src/skills/validate-skills.ts +470 -0
- package/src/telemetry/telemetry.test.ts +1 -0
- package/src/transport/http-server.test.ts +3 -0
- package/src/transport/session-manager.test.ts +3 -1
- package/src/transport/token-auth.test.ts +6 -9
- package/src/transport/ws-server.test.ts +10 -2
- package/src/utils/worktree-reaper.ts +113 -0
- package/src/vault/__tests__/vault-characterization.test.ts +0 -108
- package/src/vault/default-canonical-tags.ts +64 -0
- package/src/vault/linking.test.ts +0 -2
- package/src/vault/playbook.test.ts +4 -1
- package/src/vault/scope-detector.test.ts +3 -1
- package/src/vault/scope-detector.ts +42 -4
- package/src/vault/tag-normalizer.test.ts +214 -0
- package/src/vault/tag-normalizer.ts +188 -0
- package/src/vault/vault-connect.test.ts +1 -1
- package/src/vault/vault-entries.ts +3 -1
- package/src/vault/vault.test.ts +23 -8
- package/dist/embeddings/index.d.ts +0 -5
- package/dist/embeddings/index.d.ts.map +0 -1
- package/dist/embeddings/index.js +0 -3
- package/dist/embeddings/index.js.map +0 -1
|
@@ -1129,6 +1129,30 @@ export class BrainIntelligence {
|
|
|
1129
1129
|
// ─── Intelligence Pipeline ────────────────────────────────────────
|
|
1130
1130
|
|
|
1131
1131
|
buildIntelligence(): BuildIntelligenceResult {
|
|
1132
|
+
// Step 0: GC — close orphaned sessions with no execution signal older than 24h
|
|
1133
|
+
const TTL_MS = 24 * 60 * 60 * 1000;
|
|
1134
|
+
const cutoff = new Date(Date.now() - TTL_MS).toISOString();
|
|
1135
|
+
const activeSessions = this.listSessions({ active: true, limit: 1000 });
|
|
1136
|
+
let gcClosed = 0;
|
|
1137
|
+
for (const s of activeSessions) {
|
|
1138
|
+
const isOld = s.startedAt < cutoff;
|
|
1139
|
+
const hasNoSignal =
|
|
1140
|
+
s.toolsUsed.length === 0 && s.filesModified.length === 0 && s.planOutcome === null;
|
|
1141
|
+
if (isOld && hasNoSignal) {
|
|
1142
|
+
try {
|
|
1143
|
+
this.lifecycle({
|
|
1144
|
+
action: 'end',
|
|
1145
|
+
sessionId: s.id,
|
|
1146
|
+
planOutcome: 'abandoned',
|
|
1147
|
+
context: 'auto-gc: no execution signal after TTL',
|
|
1148
|
+
});
|
|
1149
|
+
gcClosed++;
|
|
1150
|
+
} catch {
|
|
1151
|
+
// GC must never break the intelligence pipeline
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1132
1156
|
// Step 1: Compute and persist strengths
|
|
1133
1157
|
const strengths = this.computeStrengths();
|
|
1134
1158
|
|
|
@@ -1154,6 +1178,7 @@ export class BrainIntelligence {
|
|
|
1154
1178
|
strengthsComputed: strengths.length,
|
|
1155
1179
|
globalPatterns,
|
|
1156
1180
|
domainProfiles,
|
|
1181
|
+
gcClosed,
|
|
1157
1182
|
};
|
|
1158
1183
|
}
|
|
1159
1184
|
|
|
@@ -33,7 +33,7 @@ import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
|
33
33
|
|
|
34
34
|
let vault: Vault;
|
|
35
35
|
let brain: Brain;
|
|
36
|
-
let
|
|
36
|
+
let _brainIntelligence: BrainIntelligence;
|
|
37
37
|
let planner: Planner;
|
|
38
38
|
let curator: Curator;
|
|
39
39
|
let intentRouter: IntentRouter;
|
|
@@ -99,7 +99,7 @@ beforeAll(() => {
|
|
|
99
99
|
vault = new Vault(':memory:');
|
|
100
100
|
vault.seed(SEED);
|
|
101
101
|
brain = new Brain(vault);
|
|
102
|
-
|
|
102
|
+
_brainIntelligence = new BrainIntelligence(vault, brain);
|
|
103
103
|
planner = new Planner(join(tempDir, 'plans.json'));
|
|
104
104
|
curator = new Curator(vault);
|
|
105
105
|
intentRouter = new IntentRouter(vault);
|
|
@@ -160,18 +160,6 @@ describe('Two-pass vault retrieval (#205)', () => {
|
|
|
160
160
|
// ─── 2. Session Briefing ─────────────────────────────────────────────
|
|
161
161
|
|
|
162
162
|
describe('Session briefing (#202)', () => {
|
|
163
|
-
// Session briefing is an op — tested via the module imports directly
|
|
164
|
-
it('brainIntelligence.listSessions returns sessions', () => {
|
|
165
|
-
const sessions = brainIntelligence.listSessions({ limit: 5 });
|
|
166
|
-
// May be empty in a fresh vault, but shouldn't throw
|
|
167
|
-
expect(Array.isArray(sessions)).toBe(true);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('planner.list returns plans array', () => {
|
|
171
|
-
const plans = planner.list();
|
|
172
|
-
expect(Array.isArray(plans)).toBe(true);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
163
|
it('vault.getRecent returns recent entries', () => {
|
|
176
164
|
const recent = vault.getRecent(5);
|
|
177
165
|
expect(recent.length).toBeGreaterThan(0);
|
package/src/brain/types.ts
CHANGED
|
@@ -6,10 +6,6 @@ describe('chainToCapability', () => {
|
|
|
6
6
|
expect(chainToCapability('vault-search')).toBe('vault.search');
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
it('maps vault-search-antipatterns to vault.search', () => {
|
|
10
|
-
expect(chainToCapability('vault-search-antipatterns')).toBe('vault.search');
|
|
11
|
-
});
|
|
12
|
-
|
|
13
9
|
it('maps memory-search to memory.search', () => {
|
|
14
10
|
expect(chainToCapability('memory-search')).toBe('memory.search');
|
|
15
11
|
});
|
|
@@ -39,9 +35,8 @@ describe('chainToCapability', () => {
|
|
|
39
35
|
expect(chainToCapability('get-stack-guidelines')).toBe('stack.guidelines');
|
|
40
36
|
});
|
|
41
37
|
|
|
42
|
-
it('maps architecture
|
|
38
|
+
it('maps architecture chains', () => {
|
|
43
39
|
expect(chainToCapability('architecture-search')).toBe('architecture.search');
|
|
44
|
-
expect(chainToCapability('cognee-design-search')).toBe('cognee.search');
|
|
45
40
|
});
|
|
46
41
|
|
|
47
42
|
it('maps planning chains', () => {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* deliver.flow.yaml — validate-component, validate-tokens,
|
|
23
23
|
* design-rules-check, test-coverage-check,
|
|
24
24
|
* performance-audit, delivery-checklist
|
|
25
|
-
* design.flow.yaml — vault-search, memory-search,
|
|
25
|
+
* design.flow.yaml — vault-search, memory-search,
|
|
26
26
|
* recommend-design-system, recommend-style,
|
|
27
27
|
* recommend-palette, recommend-typography,
|
|
28
28
|
* get-stack-guidelines, brain-recommend
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* brain-recommend, validate-component, validate-tokens
|
|
31
31
|
* explore.flow.yaml — vault-search, memory-search, brain-strengths,
|
|
32
32
|
* brain-recommend, playbook-search
|
|
33
|
-
* fix.flow.yaml — vault-search
|
|
33
|
+
* fix.flow.yaml — vault-search, memory-search,
|
|
34
34
|
* error-pattern-search, brain-recommend,
|
|
35
35
|
* validate-component, validate-tokens
|
|
36
36
|
* plan.flow.yaml — vault-search, memory-search, brain-recommend,
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
const CHAIN_TO_CAPABILITY: Record<string, string> = {
|
|
43
43
|
// Vault & Knowledge
|
|
44
44
|
'vault-search': 'vault.search',
|
|
45
|
-
'vault-search-antipatterns': 'vault.search',
|
|
46
45
|
'memory-search': 'memory.search',
|
|
47
46
|
'playbook-search': 'vault.playbook',
|
|
48
47
|
|
|
@@ -67,11 +66,14 @@ const CHAIN_TO_CAPABILITY: Record<string, string> = {
|
|
|
67
66
|
|
|
68
67
|
// Architecture
|
|
69
68
|
'architecture-search': 'architecture.search',
|
|
70
|
-
'cognee-design-search': 'cognee.search',
|
|
71
69
|
|
|
72
70
|
// Planning
|
|
73
71
|
'plan-create': 'plan.create',
|
|
74
72
|
|
|
73
|
+
// Capture & Synthesis
|
|
74
|
+
'capture-baseline-state': 'vault.capture',
|
|
75
|
+
'vault-synthesize': 'vault.synthesize',
|
|
76
|
+
|
|
75
77
|
// Review & Quality
|
|
76
78
|
'review-report': 'review.report',
|
|
77
79
|
'accessibility-audit': 'a11y.audit',
|
|
@@ -237,7 +237,7 @@ describe('CapabilityRegistry', () => {
|
|
|
237
237
|
it('classifies blocking capabilities correctly', () => {
|
|
238
238
|
const result = registry.validateFlow({
|
|
239
239
|
steps: [{ needs: ['vault.search', 'auth.validate'] }],
|
|
240
|
-
|
|
240
|
+
'on-missing-capability': { blocking: ['auth.validate'] },
|
|
241
241
|
});
|
|
242
242
|
|
|
243
243
|
expect(result.valid).toBe(false);
|
|
@@ -33,6 +33,12 @@ export interface FlowForValidation {
|
|
|
33
33
|
needs?: string[];
|
|
34
34
|
chains?: string[];
|
|
35
35
|
}>;
|
|
36
|
+
/** Kebab-case (YAML / flow file format). */
|
|
37
|
+
'on-missing-capability'?: {
|
|
38
|
+
default?: string;
|
|
39
|
+
blocking?: string[];
|
|
40
|
+
};
|
|
41
|
+
/** CamelCase alias for programmatic callers. */
|
|
36
42
|
onMissingCapability?: {
|
|
37
43
|
default?: string;
|
|
38
44
|
blocking?: string[];
|
|
@@ -236,8 +242,9 @@ export class CapabilityRegistry {
|
|
|
236
242
|
}
|
|
237
243
|
}
|
|
238
244
|
|
|
239
|
-
// Classify missing capabilities by impact
|
|
240
|
-
const
|
|
245
|
+
// Classify missing capabilities by impact (accept both kebab and camelCase keys)
|
|
246
|
+
const missingCapConfig = flow['on-missing-capability'] ?? flow.onMissingCapability;
|
|
247
|
+
const blockingSet = new Set(missingCapConfig?.blocking ?? []);
|
|
241
248
|
|
|
242
249
|
const degraded = missing.map((capability) => ({
|
|
243
250
|
capability,
|
|
@@ -286,7 +286,7 @@ describe('runAgentLoop', () => {
|
|
|
286
286
|
onToolUse: (name) => toolUses.push(name),
|
|
287
287
|
onToolResult: (name, result, ms) => {
|
|
288
288
|
toolResults.push(`${name}:${result.output}`);
|
|
289
|
-
expect(ms).
|
|
289
|
+
expect(typeof ms).toBe('number');
|
|
290
290
|
},
|
|
291
291
|
},
|
|
292
292
|
);
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
cleanupTempFiles,
|
|
15
15
|
sanitizeForPersistence,
|
|
16
16
|
MAX_FILE_SIZE,
|
|
17
|
-
TEXT_EXTENSIONS,
|
|
18
17
|
} from './file-handler.js';
|
|
19
18
|
import { NotificationEngine } from './notifications.js';
|
|
20
19
|
import type { FileInfo, MultimodalContent } from './file-handler.js';
|
|
@@ -231,13 +230,6 @@ describe('File Handler', () => {
|
|
|
231
230
|
});
|
|
232
231
|
});
|
|
233
232
|
|
|
234
|
-
test('TEXT_EXTENSIONS includes common types', () => {
|
|
235
|
-
expect(TEXT_EXTENSIONS.has('.ts')).toBe(true);
|
|
236
|
-
expect(TEXT_EXTENSIONS.has('.py')).toBe(true);
|
|
237
|
-
expect(TEXT_EXTENSIONS.has('.json')).toBe(true);
|
|
238
|
-
expect(TEXT_EXTENSIONS.has('.md')).toBe(true);
|
|
239
|
-
});
|
|
240
|
-
|
|
241
233
|
test('MAX_FILE_SIZE is 20MB', () => {
|
|
242
234
|
expect(MAX_FILE_SIZE).toBe(20 * 1024 * 1024);
|
|
243
235
|
});
|
package/src/chat/chat-session.ts
CHANGED
|
@@ -16,6 +16,7 @@ const DEFAULT_TTL_MS = 7_200_000; // 2 hours
|
|
|
16
16
|
const DEFAULT_COMPACTION_THRESHOLD = 100;
|
|
17
17
|
const DEFAULT_COMPACTION_KEEP = 40;
|
|
18
18
|
const REAPER_INTERVAL_MS = 60_000; // 1 minute
|
|
19
|
+
const SESSION_SUBDIR = 'sessions';
|
|
19
20
|
|
|
20
21
|
export class ChatSessionManager {
|
|
21
22
|
private sessions = new Map<string, ChatSession>();
|
|
@@ -31,6 +32,7 @@ export class ChatSessionManager {
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
mkdirSync(this.config.storageDir, { recursive: true });
|
|
35
|
+
mkdirSync(this.sessionDir(), { recursive: true });
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// ─── Lifecycle ──────────────────────────────────────────────────
|
|
@@ -78,7 +80,8 @@ export class ChatSessionManager {
|
|
|
78
80
|
*/
|
|
79
81
|
has(sessionId: string): boolean {
|
|
80
82
|
if (this.sessions.has(sessionId)) return true;
|
|
81
|
-
|
|
83
|
+
if (existsSync(this.sessionPath(sessionId))) return true;
|
|
84
|
+
return this.loadSessionFile(this.legacySessionPath(sessionId)) !== undefined;
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
// ─── Message Management ─────────────────────────────────────────
|
|
@@ -159,15 +162,11 @@ export class ChatSessionManager {
|
|
|
159
162
|
*/
|
|
160
163
|
listAll(): string[] {
|
|
161
164
|
const memoryIds = new Set(this.sessions.keys());
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
} catch {
|
|
170
|
-
// Directory may not exist yet
|
|
165
|
+
for (const id of this.readPersistedSessionIds(this.sessionDir())) {
|
|
166
|
+
memoryIds.add(id);
|
|
167
|
+
}
|
|
168
|
+
for (const id of this.readPersistedSessionIds(this.config.storageDir)) {
|
|
169
|
+
memoryIds.add(id);
|
|
171
170
|
}
|
|
172
171
|
return [...memoryIds];
|
|
173
172
|
}
|
|
@@ -246,38 +245,97 @@ export class ChatSessionManager {
|
|
|
246
245
|
session.messages = session.messages.slice(-keep);
|
|
247
246
|
}
|
|
248
247
|
|
|
248
|
+
private sessionDir(): string {
|
|
249
|
+
return join(this.config.storageDir, SESSION_SUBDIR);
|
|
250
|
+
}
|
|
251
|
+
|
|
249
252
|
private sessionPath(sessionId: string): string {
|
|
250
253
|
// Sanitize ID for filesystem safety
|
|
254
|
+
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
255
|
+
return join(this.sessionDir(), `${safe}.json`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private legacySessionPath(sessionId: string): string {
|
|
251
259
|
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
252
260
|
return join(this.config.storageDir, `${safe}.json`);
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
private persistToDisk(session: ChatSession): void {
|
|
256
264
|
try {
|
|
265
|
+
mkdirSync(this.sessionDir(), { recursive: true });
|
|
257
266
|
writeFileSync(this.sessionPath(session.id), JSON.stringify(session), 'utf-8');
|
|
267
|
+
|
|
268
|
+
// Clean up valid legacy session files after migrating to the namespaced path.
|
|
269
|
+
const legacyPath = this.legacySessionPath(session.id);
|
|
270
|
+
if (this.loadSessionFile(legacyPath)) {
|
|
271
|
+
this.removeFile(legacyPath);
|
|
272
|
+
}
|
|
258
273
|
} catch {
|
|
259
274
|
// Disk write failure is non-critical — session lives in memory
|
|
260
275
|
}
|
|
261
276
|
}
|
|
262
277
|
|
|
263
278
|
private loadFromDisk(sessionId: string): ChatSession | undefined {
|
|
264
|
-
const
|
|
279
|
+
const current = this.loadSessionFile(this.sessionPath(sessionId));
|
|
280
|
+
if (current) return current;
|
|
281
|
+
|
|
282
|
+
const legacyPath = this.legacySessionPath(sessionId);
|
|
283
|
+
const legacy = this.loadSessionFile(legacyPath);
|
|
284
|
+
if (legacy) {
|
|
285
|
+
this.persistToDisk(legacy);
|
|
286
|
+
return legacy;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return undefined;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
private removeFromDisk(sessionId: string): void {
|
|
293
|
+
this.removeFile(this.sessionPath(sessionId));
|
|
294
|
+
const legacyPath = this.legacySessionPath(sessionId);
|
|
295
|
+
if (this.loadSessionFile(legacyPath)) {
|
|
296
|
+
this.removeFile(legacyPath);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private removeFile(path: string): void {
|
|
301
|
+
try {
|
|
302
|
+
rmSync(path, { force: true });
|
|
303
|
+
} catch {
|
|
304
|
+
// Removal failure is non-critical
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private loadSessionFile(path: string): ChatSession | undefined {
|
|
265
309
|
if (!existsSync(path)) return undefined;
|
|
266
310
|
|
|
267
311
|
try {
|
|
268
|
-
const data = readFileSync(path, 'utf-8');
|
|
269
|
-
return
|
|
312
|
+
const data = JSON.parse(readFileSync(path, 'utf-8'));
|
|
313
|
+
return this.isChatSession(data) ? data : undefined;
|
|
270
314
|
} catch {
|
|
271
315
|
return undefined;
|
|
272
316
|
}
|
|
273
317
|
}
|
|
274
318
|
|
|
275
|
-
private
|
|
276
|
-
const path = this.sessionPath(sessionId);
|
|
319
|
+
private readPersistedSessionIds(dir: string): string[] {
|
|
277
320
|
try {
|
|
278
|
-
|
|
321
|
+
return readdirSync(dir).flatMap((file) => {
|
|
322
|
+
if (!file.endsWith('.json')) return [];
|
|
323
|
+
const session = this.loadSessionFile(join(dir, file));
|
|
324
|
+
return session ? [session.id] : [];
|
|
325
|
+
});
|
|
279
326
|
} catch {
|
|
280
|
-
|
|
327
|
+
return [];
|
|
281
328
|
}
|
|
282
329
|
}
|
|
330
|
+
|
|
331
|
+
private isChatSession(value: unknown): value is ChatSession {
|
|
332
|
+
if (!value || typeof value !== 'object') return false;
|
|
333
|
+
const session = value as Partial<ChatSession>;
|
|
334
|
+
return (
|
|
335
|
+
typeof session.id === 'string' &&
|
|
336
|
+
Array.isArray(session.messages) &&
|
|
337
|
+
typeof session.createdAt === 'number' &&
|
|
338
|
+
typeof session.lastActiveAt === 'number'
|
|
339
|
+
);
|
|
340
|
+
}
|
|
283
341
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { describe, test, expect, beforeEach, afterEach } from 'vitest';
|
|
7
|
-
import { mkdtempSync, rmSync } from 'node:fs';
|
|
7
|
+
import { mkdtempSync, rmSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { ChatSessionManager } from './chat-session.js';
|
|
@@ -136,6 +136,19 @@ describe('ChatSessionManager', () => {
|
|
|
136
136
|
expect(all).toContain('chat-2');
|
|
137
137
|
});
|
|
138
138
|
|
|
139
|
+
test('listAll ignores non-session JSON files in the storage root', () => {
|
|
140
|
+
manager.getOrCreate('chat-1');
|
|
141
|
+
writeFileSync(
|
|
142
|
+
join(dir, 'plans.json'),
|
|
143
|
+
JSON.stringify({ version: '1.0', plans: [] }),
|
|
144
|
+
'utf-8',
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const all = manager.listAll();
|
|
148
|
+
expect(all).toContain('chat-1');
|
|
149
|
+
expect(all).not.toContain('plans');
|
|
150
|
+
});
|
|
151
|
+
|
|
139
152
|
test('setMeta updates metadata', () => {
|
|
140
153
|
manager.getOrCreate('chat-1');
|
|
141
154
|
manager.setMeta('chat-1', { mood: 'happy' });
|
|
@@ -162,6 +175,23 @@ describe('ChatSessionManager', () => {
|
|
|
162
175
|
manager2.close();
|
|
163
176
|
});
|
|
164
177
|
|
|
178
|
+
test('session files are namespaced away from plans.json collisions', () => {
|
|
179
|
+
writeFileSync(
|
|
180
|
+
join(dir, 'plans.json'),
|
|
181
|
+
JSON.stringify({ version: '1.0', plans: [{ id: 'plan-1' }] }),
|
|
182
|
+
'utf-8',
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
const session = manager.getOrCreate('plans');
|
|
186
|
+
|
|
187
|
+
expect(session.messages).toEqual([]);
|
|
188
|
+
expect(JSON.parse(readFileSync(join(dir, 'plans.json'), 'utf-8'))).toEqual({
|
|
189
|
+
version: '1.0',
|
|
190
|
+
plans: [{ id: 'plan-1' }],
|
|
191
|
+
});
|
|
192
|
+
expect(existsSync(join(dir, 'sessions', 'plans.json'))).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
|
|
165
195
|
test('delete removes from disk', () => {
|
|
166
196
|
manager.getOrCreate('chat-1');
|
|
167
197
|
manager.delete('chat-1');
|
|
@@ -35,11 +35,6 @@ const facades: FacadeConfig[] = [
|
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
describe('compose — constants', () => {
|
|
38
|
-
it('FORMAT_VERSION is a positive integer', () => {
|
|
39
|
-
expect(FORMAT_VERSION).toBeGreaterThan(0);
|
|
40
|
-
expect(Number.isInteger(FORMAT_VERSION)).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
38
|
it('markers contain version', () => {
|
|
44
39
|
expect(OPEN_MARKER).toContain(`v${FORMAT_VERSION}`);
|
|
45
40
|
});
|
|
@@ -398,7 +398,6 @@ describe('ContextEngine', () => {
|
|
|
398
398
|
|
|
399
399
|
it('processing time is a non-negative number', async () => {
|
|
400
400
|
const result = await engine.analyze('any prompt');
|
|
401
|
-
expect(result.processingTimeMs).toBeGreaterThanOrEqual(0);
|
|
402
401
|
expect(typeof result.processingTimeMs).toBe('number');
|
|
403
402
|
});
|
|
404
403
|
|
|
@@ -48,7 +48,7 @@ const ENTITY_PATTERNS: Array<{ type: EntityType; pattern: RegExp; confidence: nu
|
|
|
48
48
|
{
|
|
49
49
|
type: 'technology',
|
|
50
50
|
pattern:
|
|
51
|
-
/\b(?:react|vue|svelte|angular|typescript|javascript|node\.?js|python|rust|go|docker|kubernetes|postgres|sqlite|redis|tailwind|css|html|graphql|rest|grpc)\b/gi,
|
|
51
|
+
/\b(?:react|vue|svelte|angular|typescript|javascript|node\.?js|python|rust|go|docker|kubernetes|postgres|sqlite|redis|tailwind|css|html|graphql|rest|grpc|vitest|jest|mocha|playwright|cypress)\b/gi,
|
|
52
52
|
confidence: 0.85,
|
|
53
53
|
},
|
|
54
54
|
// Patterns: kebab-case compound terms that look like patterns
|
|
@@ -57,7 +57,7 @@ describe('IntentRouter', () => {
|
|
|
57
57
|
expect(result.mode).toBe('FIX-MODE');
|
|
58
58
|
expect(result.method).toBe('keyword');
|
|
59
59
|
expect(result.confidence).toBeGreaterThan(0);
|
|
60
|
-
expect(result.matchedKeywords.length).
|
|
60
|
+
expect(result.matchedKeywords.length).toBe(2);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
it('classifies "build a new component" as BUILD intent', () => {
|
|
@@ -117,7 +117,7 @@ describe('IntentRouter', () => {
|
|
|
117
117
|
// "fix bug broken error" has 4 FIX keywords vs anything else
|
|
118
118
|
const result = router.routeIntent('fix bug broken error');
|
|
119
119
|
expect(result.intent).toBe('fix');
|
|
120
|
-
expect(result.matchedKeywords.length).
|
|
120
|
+
expect(result.matchedKeywords.length).toBe(4);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
it('confidence is capped at 1.0', () => {
|