@nxuss/lemma 1.37.0 → 1.39.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/README.md +9 -6
- package/bin/brain-ingest.js +86 -27
- package/bin/doctor.js +31 -4
- package/bin/init.js +98 -60
- package/dashboard/dist/assets/index-DNTQXLER.css +1 -0
- package/dashboard/dist/assets/index-DzL_Zu3m.js +452 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/cjs/cli/gitHooks.d.ts +9 -2
- package/dist/cjs/cli/gitHooks.d.ts.map +1 -1
- package/dist/cjs/cli/gitHooks.js +31 -4
- package/dist/cjs/cli/gitHooks.js.map +1 -1
- package/dist/cjs/cli/hostHooks.d.ts +13 -1
- package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
- package/dist/cjs/cli/hostHooks.js +34 -4
- package/dist/cjs/cli/hostHooks.js.map +1 -1
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +42 -5
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/infra/analyzers/index.d.ts +0 -2
- package/dist/cjs/infra/analyzers/index.d.ts.map +1 -1
- package/dist/cjs/infra/analyzers/index.js +1 -6
- package/dist/cjs/infra/analyzers/index.js.map +1 -1
- package/dist/cjs/infra/cli.d.ts +4 -0
- package/dist/cjs/infra/cli.d.ts.map +1 -1
- package/dist/cjs/infra/cli.js +6 -199
- package/dist/cjs/infra/cli.js.map +1 -1
- package/dist/cjs/infra/index.d.ts +1 -3
- package/dist/cjs/infra/index.d.ts.map +1 -1
- package/dist/cjs/infra/index.js +1 -16
- package/dist/cjs/infra/index.js.map +1 -1
- package/dist/cjs/infra/mcp-tools.d.ts.map +1 -1
- package/dist/cjs/infra/mcp-tools.js +8 -453
- package/dist/cjs/infra/mcp-tools.js.map +1 -1
- package/dist/cjs/infra/types.d.ts +0 -101
- package/dist/cjs/infra/types.d.ts.map +1 -1
- package/dist/cjs/infra/types.js +2 -1
- package/dist/cjs/infra/types.js.map +1 -1
- package/dist/cjs/mcp/index.js +33 -10
- package/dist/cjs/mcp/index.js.map +1 -1
- package/dist/cjs/mcp/prompts.d.ts +1 -1
- package/dist/cjs/mcp/prompts.d.ts.map +1 -1
- package/dist/cjs/mcp/prompts.js +8 -21
- package/dist/cjs/mcp/prompts.js.map +1 -1
- package/dist/cjs/mcp/tool-profiles.d.ts +8 -3
- package/dist/cjs/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/cjs/mcp/tool-profiles.js +25 -54
- package/dist/cjs/mcp/tool-profiles.js.map +1 -1
- package/dist/cjs/mcp/tools/memory.d.ts +8 -0
- package/dist/cjs/mcp/tools/memory.d.ts.map +1 -1
- package/dist/cjs/mcp/tools/memory.js +154 -125
- package/dist/cjs/mcp/tools/memory.js.map +1 -1
- package/dist/cjs/mcp/tools.d.ts.map +1 -1
- package/dist/cjs/mcp/tools.js +11 -6
- package/dist/cjs/mcp/tools.js.map +1 -1
- package/dist/cjs/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/cjs/mcp/workspaceShared.js +13 -12
- package/dist/cjs/mcp/workspaceShared.js.map +1 -1
- package/dist/cjs/proxy/ProjectRegistry.d.ts +44 -0
- package/dist/cjs/proxy/ProjectRegistry.d.ts.map +1 -1
- package/dist/cjs/proxy/ProjectRegistry.js +92 -3
- package/dist/cjs/proxy/ProjectRegistry.js.map +1 -1
- package/dist/cjs/subconscious/HostRecall.d.ts +36 -3
- package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/cjs/subconscious/HostRecall.js +164 -37
- package/dist/cjs/subconscious/HostRecall.js.map +1 -1
- package/dist/cjs/subconscious/NarrowEvidence.d.ts +47 -0
- package/dist/cjs/subconscious/NarrowEvidence.d.ts.map +1 -0
- package/dist/cjs/subconscious/NarrowEvidence.js +252 -0
- package/dist/cjs/subconscious/NarrowEvidence.js.map +1 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts +37 -0
- package/dist/cjs/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/cjs/subconscious/TheBrainV2.js +147 -15
- package/dist/cjs/subconscious/TheBrainV2.js.map +1 -1
- package/dist/cjs/subconscious/freshness/LocalFsResolver.d.ts.map +1 -1
- package/dist/cjs/subconscious/freshness/LocalFsResolver.js +17 -0
- package/dist/cjs/subconscious/freshness/LocalFsResolver.js.map +1 -1
- package/dist/cjs/subconscious/recallDigest.d.ts +42 -0
- package/dist/cjs/subconscious/recallDigest.d.ts.map +1 -0
- package/dist/cjs/subconscious/recallDigest.js +94 -0
- package/dist/cjs/subconscious/recallDigest.js.map +1 -0
- package/dist/cjs/utils/OtherLanguageSymbols.d.ts +31 -0
- package/dist/cjs/utils/OtherLanguageSymbols.d.ts.map +1 -0
- package/dist/cjs/utils/OtherLanguageSymbols.js +283 -0
- package/dist/cjs/utils/OtherLanguageSymbols.js.map +1 -0
- package/dist/cjs/utils/SavingsLedger.d.ts +27 -0
- package/dist/cjs/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/cjs/utils/SavingsLedger.js +51 -0
- package/dist/cjs/utils/SavingsLedger.js.map +1 -1
- package/dist/cjs/utils/StoreDraft.d.ts +12 -0
- package/dist/cjs/utils/StoreDraft.d.ts.map +1 -1
- package/dist/cjs/utils/StoreDraft.js +53 -1
- package/dist/cjs/utils/StoreDraft.js.map +1 -1
- package/dist/cjs/utils/SymbolSurgicalContext.d.ts +2 -0
- package/dist/cjs/utils/SymbolSurgicalContext.d.ts.map +1 -1
- package/dist/cjs/utils/SymbolSurgicalContext.js +1 -0
- package/dist/cjs/utils/SymbolSurgicalContext.js.map +1 -1
- package/dist/cjs/utils/reportSavings.d.ts +17 -4
- package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
- package/dist/cjs/utils/reportSavings.js +67 -22
- package/dist/cjs/utils/reportSavings.js.map +1 -1
- package/dist/esm/cli/gitHooks.d.ts +9 -2
- package/dist/esm/cli/gitHooks.d.ts.map +1 -1
- package/dist/esm/cli/gitHooks.js +31 -4
- package/dist/esm/cli/gitHooks.js.map +1 -1
- package/dist/esm/cli/hostHooks.d.ts +13 -1
- package/dist/esm/cli/hostHooks.d.ts.map +1 -1
- package/dist/esm/cli/hostHooks.js +32 -3
- package/dist/esm/cli/hostHooks.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +42 -5
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/infra/analyzers/index.d.ts +0 -2
- package/dist/esm/infra/analyzers/index.d.ts.map +1 -1
- package/dist/esm/infra/analyzers/index.js +0 -2
- package/dist/esm/infra/analyzers/index.js.map +1 -1
- package/dist/esm/infra/cli.d.ts +4 -0
- package/dist/esm/infra/cli.d.ts.map +1 -1
- package/dist/esm/infra/cli.js +6 -199
- package/dist/esm/infra/cli.js.map +1 -1
- package/dist/esm/infra/index.d.ts +1 -3
- package/dist/esm/infra/index.d.ts.map +1 -1
- package/dist/esm/infra/index.js +1 -3
- package/dist/esm/infra/index.js.map +1 -1
- package/dist/esm/infra/mcp-tools.d.ts.map +1 -1
- package/dist/esm/infra/mcp-tools.js +9 -454
- package/dist/esm/infra/mcp-tools.js.map +1 -1
- package/dist/esm/infra/types.d.ts +0 -101
- package/dist/esm/infra/types.d.ts.map +1 -1
- package/dist/esm/infra/types.js +2 -1
- package/dist/esm/infra/types.js.map +1 -1
- package/dist/esm/mcp/index.js +33 -10
- package/dist/esm/mcp/index.js.map +1 -1
- package/dist/esm/mcp/prompts.d.ts +1 -1
- package/dist/esm/mcp/prompts.d.ts.map +1 -1
- package/dist/esm/mcp/prompts.js +8 -21
- package/dist/esm/mcp/prompts.js.map +1 -1
- package/dist/esm/mcp/tool-profiles.d.ts +8 -3
- package/dist/esm/mcp/tool-profiles.d.ts.map +1 -1
- package/dist/esm/mcp/tool-profiles.js +25 -54
- package/dist/esm/mcp/tool-profiles.js.map +1 -1
- package/dist/esm/mcp/tools/memory.d.ts +8 -0
- package/dist/esm/mcp/tools/memory.d.ts.map +1 -1
- package/dist/esm/mcp/tools/memory.js +156 -128
- package/dist/esm/mcp/tools/memory.js.map +1 -1
- package/dist/esm/mcp/tools.d.ts.map +1 -1
- package/dist/esm/mcp/tools.js +12 -7
- package/dist/esm/mcp/tools.js.map +1 -1
- package/dist/esm/mcp/workspaceShared.d.ts.map +1 -1
- package/dist/esm/mcp/workspaceShared.js +13 -12
- package/dist/esm/mcp/workspaceShared.js.map +1 -1
- package/dist/esm/proxy/ProjectRegistry.d.ts +44 -0
- package/dist/esm/proxy/ProjectRegistry.d.ts.map +1 -1
- package/dist/esm/proxy/ProjectRegistry.js +91 -2
- package/dist/esm/proxy/ProjectRegistry.js.map +1 -1
- package/dist/esm/subconscious/HostRecall.d.ts +36 -3
- package/dist/esm/subconscious/HostRecall.d.ts.map +1 -1
- package/dist/esm/subconscious/HostRecall.js +159 -36
- package/dist/esm/subconscious/HostRecall.js.map +1 -1
- package/dist/esm/subconscious/NarrowEvidence.d.ts +47 -0
- package/dist/esm/subconscious/NarrowEvidence.d.ts.map +1 -0
- package/dist/esm/subconscious/NarrowEvidence.js +211 -0
- package/dist/esm/subconscious/NarrowEvidence.js.map +1 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts +37 -0
- package/dist/esm/subconscious/TheBrainV2.d.ts.map +1 -1
- package/dist/esm/subconscious/TheBrainV2.js +146 -14
- package/dist/esm/subconscious/TheBrainV2.js.map +1 -1
- package/dist/esm/subconscious/freshness/LocalFsResolver.d.ts.map +1 -1
- package/dist/esm/subconscious/freshness/LocalFsResolver.js +17 -0
- package/dist/esm/subconscious/freshness/LocalFsResolver.js.map +1 -1
- package/dist/esm/subconscious/recallDigest.d.ts +42 -0
- package/dist/esm/subconscious/recallDigest.d.ts.map +1 -0
- package/dist/esm/subconscious/recallDigest.js +87 -0
- package/dist/esm/subconscious/recallDigest.js.map +1 -0
- package/dist/esm/utils/OtherLanguageSymbols.d.ts +31 -0
- package/dist/esm/utils/OtherLanguageSymbols.d.ts.map +1 -0
- package/dist/esm/utils/OtherLanguageSymbols.js +275 -0
- package/dist/esm/utils/OtherLanguageSymbols.js.map +1 -0
- package/dist/esm/utils/SavingsLedger.d.ts +27 -0
- package/dist/esm/utils/SavingsLedger.d.ts.map +1 -1
- package/dist/esm/utils/SavingsLedger.js +51 -0
- package/dist/esm/utils/SavingsLedger.js.map +1 -1
- package/dist/esm/utils/StoreDraft.d.ts +12 -0
- package/dist/esm/utils/StoreDraft.d.ts.map +1 -1
- package/dist/esm/utils/StoreDraft.js +52 -1
- package/dist/esm/utils/StoreDraft.js.map +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.d.ts +2 -0
- package/dist/esm/utils/SymbolSurgicalContext.d.ts.map +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.js +1 -1
- package/dist/esm/utils/SymbolSurgicalContext.js.map +1 -1
- package/dist/esm/utils/reportSavings.d.ts +17 -4
- package/dist/esm/utils/reportSavings.d.ts.map +1 -1
- package/dist/esm/utils/reportSavings.js +65 -22
- package/dist/esm/utils/reportSavings.js.map +1 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/index-BoeQau6n.css +0 -1
- package/dashboard/dist/assets/index-Clf3qR64.js +0 -451
- package/dist/cjs/infra/analyzers/DriftDetector.d.ts +0 -4
- package/dist/cjs/infra/analyzers/DriftDetector.d.ts.map +0 -1
- package/dist/cjs/infra/analyzers/DriftDetector.js +0 -88
- package/dist/cjs/infra/analyzers/DriftDetector.js.map +0 -1
- package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts +0 -3
- package/dist/cjs/infra/analyzers/InfraAnalyzer.d.ts.map +0 -1
- package/dist/cjs/infra/analyzers/InfraAnalyzer.js +0 -73
- package/dist/cjs/infra/analyzers/InfraAnalyzer.js.map +0 -1
- package/dist/cjs/infra/config.d.ts +0 -17
- package/dist/cjs/infra/config.d.ts.map +0 -1
- package/dist/cjs/infra/config.js +0 -111
- package/dist/cjs/infra/config.js.map +0 -1
- package/dist/cjs/infra/errorCause.d.ts +0 -36
- package/dist/cjs/infra/errorCause.d.ts.map +0 -1
- package/dist/cjs/infra/errorCause.js +0 -143
- package/dist/cjs/infra/errorCause.js.map +0 -1
- package/dist/cjs/infra/providers/InfraProvider.d.ts +0 -9
- package/dist/cjs/infra/providers/InfraProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/InfraProvider.js +0 -3
- package/dist/cjs/infra/providers/InfraProvider.js.map +0 -1
- package/dist/cjs/infra/providers/JenkinsProvider.d.ts +0 -16
- package/dist/cjs/infra/providers/JenkinsProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/JenkinsProvider.js +0 -193
- package/dist/cjs/infra/providers/JenkinsProvider.js.map +0 -1
- package/dist/cjs/infra/providers/OKDProvider.d.ts +0 -24
- package/dist/cjs/infra/providers/OKDProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/OKDProvider.js +0 -296
- package/dist/cjs/infra/providers/OKDProvider.js.map +0 -1
- package/dist/cjs/infra/providers/TerraformProvider.d.ts +0 -17
- package/dist/cjs/infra/providers/TerraformProvider.d.ts.map +0 -1
- package/dist/cjs/infra/providers/TerraformProvider.js +0 -111
- package/dist/cjs/infra/providers/TerraformProvider.js.map +0 -1
- package/dist/cjs/infra/providers/index.d.ts +0 -9
- package/dist/cjs/infra/providers/index.d.ts.map +0 -1
- package/dist/cjs/infra/providers/index.js +0 -34
- package/dist/cjs/infra/providers/index.js.map +0 -1
- package/dist/cjs/infra/templates/jenkins/index.d.ts +0 -15
- package/dist/cjs/infra/templates/jenkins/index.d.ts.map +0 -1
- package/dist/cjs/infra/templates/jenkins/index.js +0 -128
- package/dist/cjs/infra/templates/jenkins/index.js.map +0 -1
- package/dist/cjs/infra/templates/okd/index.d.ts +0 -31
- package/dist/cjs/infra/templates/okd/index.d.ts.map +0 -1
- package/dist/cjs/infra/templates/okd/index.js +0 -149
- package/dist/cjs/infra/templates/okd/index.js.map +0 -1
- package/dist/esm/infra/analyzers/DriftDetector.d.ts +0 -4
- package/dist/esm/infra/analyzers/DriftDetector.d.ts.map +0 -1
- package/dist/esm/infra/analyzers/DriftDetector.js +0 -84
- package/dist/esm/infra/analyzers/DriftDetector.js.map +0 -1
- package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts +0 -3
- package/dist/esm/infra/analyzers/InfraAnalyzer.d.ts.map +0 -1
- package/dist/esm/infra/analyzers/InfraAnalyzer.js +0 -70
- package/dist/esm/infra/analyzers/InfraAnalyzer.js.map +0 -1
- package/dist/esm/infra/config.d.ts +0 -17
- package/dist/esm/infra/config.d.ts.map +0 -1
- package/dist/esm/infra/config.js +0 -101
- package/dist/esm/infra/config.js.map +0 -1
- package/dist/esm/infra/errorCause.d.ts +0 -36
- package/dist/esm/infra/errorCause.d.ts.map +0 -1
- package/dist/esm/infra/errorCause.js +0 -138
- package/dist/esm/infra/errorCause.js.map +0 -1
- package/dist/esm/infra/providers/InfraProvider.d.ts +0 -9
- package/dist/esm/infra/providers/InfraProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/InfraProvider.js +0 -2
- package/dist/esm/infra/providers/InfraProvider.js.map +0 -1
- package/dist/esm/infra/providers/JenkinsProvider.d.ts +0 -16
- package/dist/esm/infra/providers/JenkinsProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/JenkinsProvider.js +0 -186
- package/dist/esm/infra/providers/JenkinsProvider.js.map +0 -1
- package/dist/esm/infra/providers/OKDProvider.d.ts +0 -24
- package/dist/esm/infra/providers/OKDProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/OKDProvider.js +0 -292
- package/dist/esm/infra/providers/OKDProvider.js.map +0 -1
- package/dist/esm/infra/providers/TerraformProvider.d.ts +0 -17
- package/dist/esm/infra/providers/TerraformProvider.d.ts.map +0 -1
- package/dist/esm/infra/providers/TerraformProvider.js +0 -107
- package/dist/esm/infra/providers/TerraformProvider.js.map +0 -1
- package/dist/esm/infra/providers/index.d.ts +0 -9
- package/dist/esm/infra/providers/index.d.ts.map +0 -1
- package/dist/esm/infra/providers/index.js +0 -27
- package/dist/esm/infra/providers/index.js.map +0 -1
- package/dist/esm/infra/templates/jenkins/index.d.ts +0 -15
- package/dist/esm/infra/templates/jenkins/index.d.ts.map +0 -1
- package/dist/esm/infra/templates/jenkins/index.js +0 -124
- package/dist/esm/infra/templates/jenkins/index.js.map +0 -1
- package/dist/esm/infra/templates/okd/index.d.ts +0 -31
- package/dist/esm/infra/templates/okd/index.d.ts.map +0 -1
- package/dist/esm/infra/templates/okd/index.js +0 -142
- package/dist/esm/infra/templates/okd/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspaceShared.js","sourceRoot":"","sources":["../../../src/mcp/workspaceShared.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;
|
|
1
|
+
{"version":3,"file":"workspaceShared.js","sourceRoot":"","sources":["../../../src/mcp/workspaceShared.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,16 +2,60 @@ export interface RegisteredProject {
|
|
|
2
2
|
name: string;
|
|
3
3
|
path: string;
|
|
4
4
|
stack: string;
|
|
5
|
+
/** Last handshake or tool call — what getActive() ranks by. Heartbeats don't move it. */
|
|
5
6
|
lastActive: number;
|
|
7
|
+
/** Last sign of life from any MCP server in this project: handshake, heartbeat or tool call. */
|
|
8
|
+
lastSeen: number;
|
|
9
|
+
/** Last MCP tool call, or null if the project connected but hasn't called a tool yet. */
|
|
10
|
+
lastToolCall: number | null;
|
|
11
|
+
toolCallCount: number;
|
|
6
12
|
}
|
|
13
|
+
export type ProjectStatus = 'active' | 'idle' | 'offline';
|
|
14
|
+
export interface ProjectSnapshot extends RegisteredProject {
|
|
15
|
+
status: ProjectStatus;
|
|
16
|
+
/** Distinct memories a recall note (hook, briefing or read-tool note) put in front of an agent. */
|
|
17
|
+
offeredCount: number;
|
|
18
|
+
/** Of those, how many the agent then opened with get_memory. */
|
|
19
|
+
usedCount: number;
|
|
20
|
+
}
|
|
21
|
+
/** MCP servers heartbeat every 30s; three missed beats and the project counts as disconnected. */
|
|
22
|
+
export declare const OFFLINE_AFTER_MS = 90000;
|
|
23
|
+
/** Same threshold /api/mcp-status uses for "active". */
|
|
24
|
+
export declare const ACTIVE_WITHIN_MS = 60000;
|
|
25
|
+
/**
|
|
26
|
+
* A get_memory counts as using an offered memory only this soon after the offer — a stand-in
|
|
27
|
+
* for "the same working session", since the hook knows the host's session id and the MCP
|
|
28
|
+
* server doesn't.
|
|
29
|
+
*/
|
|
30
|
+
export declare const RECALL_USE_WINDOW_MS: number;
|
|
7
31
|
export declare class ProjectRegistry {
|
|
8
32
|
private projects;
|
|
33
|
+
private recall;
|
|
34
|
+
private tally;
|
|
9
35
|
register(projectPath: string, name: string, stack: string): RegisteredProject;
|
|
36
|
+
/**
|
|
37
|
+
* Keep-alive from an MCP server. Re-registers a project the daemon forgot (it restarted),
|
|
38
|
+
* but leaves lastActive alone so idle sessions heartbeating in the background don't steal
|
|
39
|
+
* getActive() from the project actually being worked on.
|
|
40
|
+
*/
|
|
41
|
+
heartbeat(projectPath: string, name: string, stack: string): RegisteredProject;
|
|
42
|
+
/** A tool call from this project. Registers it if the handshake never reached this daemon. */
|
|
43
|
+
recordToolCall(projectPath: string): RegisteredProject;
|
|
44
|
+
/** A recall note offered these memories in this project. Doesn't touch connection status. */
|
|
45
|
+
recordOffered(projectPath: string, ids: string[], now?: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* get_memory read `id` in this project. True when a note had offered it within
|
|
48
|
+
* RECALL_USE_WINDOW_MS — the agent acted on recall it didn't have to search for. A read of a
|
|
49
|
+
* memory nobody offered (an id from search_memory, or carried over) is not counted here.
|
|
50
|
+
*/
|
|
51
|
+
recordRecallUse(projectPath: string, id: string, now?: number): boolean;
|
|
10
52
|
get(projectPath: string): RegisteredProject | undefined;
|
|
11
53
|
touch(projectPath: string): void;
|
|
12
54
|
getActive(): RegisteredProject | null;
|
|
13
55
|
findByPathFragment(text: string): RegisteredProject | null;
|
|
14
56
|
isStale(project: RegisteredProject, hours?: number): boolean;
|
|
15
57
|
getAll(): RegisteredProject[];
|
|
58
|
+
/** Every known project with its connection status, most recently active first. */
|
|
59
|
+
snapshot(now?: number): ProjectSnapshot[];
|
|
16
60
|
}
|
|
17
61
|
//# sourceMappingURL=ProjectRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectRegistry.d.ts","sourceRoot":"","sources":["../../../src/proxy/ProjectRegistry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ProjectRegistry.d.ts","sourceRoot":"","sources":["../../../src/proxy/ProjectRegistry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,UAAU,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,QAAQ,EAAE,MAAM,CAAC;IACjB,yFAAyF;IACzF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,MAAM,EAAE,aAAa,CAAC;IACtB,mGAAmG;IACnG,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kGAAkG;AAClG,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,QAAqB,CAAC;AAWvD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,MAAM,CAAkC;IAEhD,OAAO,CAAC,KAAK;IASb,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAsB7E;;;;OAIG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,iBAAiB;IAQ9E,8FAA8F;IAC9F,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB;IAUtD,6FAA6F;IAC7F,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,SAAa,GAAG,IAAI;IAUzE;;;;OAIG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,OAAO;IAQ3E,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAIvD,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKhC,SAAS,IAAI,iBAAiB,GAAG,IAAI;IAYrC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAQ1D,OAAO,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,SAAK,GAAG,OAAO;IAIxD,MAAM,IAAI,iBAAiB,EAAE;IAI7B,kFAAkF;IAClF,QAAQ,CAAC,GAAG,SAAa,GAAG,eAAe,EAAE;CAW9C"}
|
|
@@ -1,14 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProjectRegistry = void 0;
|
|
3
|
+
exports.ProjectRegistry = exports.RECALL_USE_WINDOW_MS = exports.ACTIVE_WITHIN_MS = exports.OFFLINE_AFTER_MS = void 0;
|
|
4
|
+
/** MCP servers heartbeat every 30s; three missed beats and the project counts as disconnected. */
|
|
5
|
+
exports.OFFLINE_AFTER_MS = 90000;
|
|
6
|
+
/** Same threshold /api/mcp-status uses for "active". */
|
|
7
|
+
exports.ACTIVE_WITHIN_MS = 60000;
|
|
8
|
+
/**
|
|
9
|
+
* A get_memory counts as using an offered memory only this soon after the offer — a stand-in
|
|
10
|
+
* for "the same working session", since the hook knows the host's session id and the MCP
|
|
11
|
+
* server doesn't.
|
|
12
|
+
*/
|
|
13
|
+
exports.RECALL_USE_WINDOW_MS = 6 * 60 * 60 * 1000;
|
|
14
|
+
const MAX_OFFERED_PER_PROJECT = 2000;
|
|
15
|
+
const folderName = (projectPath) => projectPath.split(/[\\/]/).filter(Boolean).pop() || projectPath;
|
|
4
16
|
class ProjectRegistry {
|
|
5
17
|
constructor() {
|
|
6
18
|
this.projects = new Map();
|
|
19
|
+
this.recall = new Map();
|
|
20
|
+
}
|
|
21
|
+
tally(projectPath) {
|
|
22
|
+
let t = this.recall.get(projectPath);
|
|
23
|
+
if (!t) {
|
|
24
|
+
t = { offered: new Map(), used: new Set() };
|
|
25
|
+
this.recall.set(projectPath, t);
|
|
26
|
+
}
|
|
27
|
+
return t;
|
|
7
28
|
}
|
|
8
29
|
register(projectPath, name, stack) {
|
|
30
|
+
const now = Date.now();
|
|
9
31
|
const existing = this.projects.get(projectPath);
|
|
10
32
|
if (existing) {
|
|
11
|
-
existing.lastActive =
|
|
33
|
+
existing.lastActive = now;
|
|
34
|
+
existing.lastSeen = now;
|
|
12
35
|
if (stack && stack !== existing.stack)
|
|
13
36
|
existing.stack = stack;
|
|
14
37
|
return existing;
|
|
@@ -17,11 +40,63 @@ class ProjectRegistry {
|
|
|
17
40
|
name,
|
|
18
41
|
path: projectPath,
|
|
19
42
|
stack,
|
|
20
|
-
lastActive:
|
|
43
|
+
lastActive: now,
|
|
44
|
+
lastSeen: now,
|
|
45
|
+
lastToolCall: null,
|
|
46
|
+
toolCallCount: 0,
|
|
21
47
|
};
|
|
22
48
|
this.projects.set(projectPath, project);
|
|
23
49
|
return project;
|
|
24
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Keep-alive from an MCP server. Re-registers a project the daemon forgot (it restarted),
|
|
53
|
+
* but leaves lastActive alone so idle sessions heartbeating in the background don't steal
|
|
54
|
+
* getActive() from the project actually being worked on.
|
|
55
|
+
*/
|
|
56
|
+
heartbeat(projectPath, name, stack) {
|
|
57
|
+
const existing = this.projects.get(projectPath);
|
|
58
|
+
if (!existing)
|
|
59
|
+
return this.register(projectPath, name, stack);
|
|
60
|
+
existing.lastSeen = Date.now();
|
|
61
|
+
if (stack && stack !== existing.stack)
|
|
62
|
+
existing.stack = stack;
|
|
63
|
+
return existing;
|
|
64
|
+
}
|
|
65
|
+
/** A tool call from this project. Registers it if the handshake never reached this daemon. */
|
|
66
|
+
recordToolCall(projectPath) {
|
|
67
|
+
const project = this.projects.get(projectPath) ?? this.register(projectPath, folderName(projectPath), '');
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
project.lastActive = now;
|
|
70
|
+
project.lastSeen = now;
|
|
71
|
+
project.lastToolCall = now;
|
|
72
|
+
project.toolCallCount++;
|
|
73
|
+
return project;
|
|
74
|
+
}
|
|
75
|
+
/** A recall note offered these memories in this project. Doesn't touch connection status. */
|
|
76
|
+
recordOffered(projectPath, ids, now = Date.now()) {
|
|
77
|
+
if (!this.projects.has(projectPath))
|
|
78
|
+
this.register(projectPath, folderName(projectPath), '');
|
|
79
|
+
const { offered } = this.tally(projectPath);
|
|
80
|
+
for (const id of ids) {
|
|
81
|
+
offered.delete(id); // re-insert so the oldest offers are the ones evicted
|
|
82
|
+
offered.set(id, now);
|
|
83
|
+
}
|
|
84
|
+
while (offered.size > MAX_OFFERED_PER_PROJECT)
|
|
85
|
+
offered.delete(offered.keys().next().value);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* get_memory read `id` in this project. True when a note had offered it within
|
|
89
|
+
* RECALL_USE_WINDOW_MS — the agent acted on recall it didn't have to search for. A read of a
|
|
90
|
+
* memory nobody offered (an id from search_memory, or carried over) is not counted here.
|
|
91
|
+
*/
|
|
92
|
+
recordRecallUse(projectPath, id, now = Date.now()) {
|
|
93
|
+
const t = this.recall.get(projectPath);
|
|
94
|
+
const at = t?.offered.get(id);
|
|
95
|
+
if (!t || at === undefined || now - at > exports.RECALL_USE_WINDOW_MS)
|
|
96
|
+
return false;
|
|
97
|
+
t.used.add(id);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
25
100
|
get(projectPath) {
|
|
26
101
|
return this.projects.get(projectPath);
|
|
27
102
|
}
|
|
@@ -55,6 +130,20 @@ class ProjectRegistry {
|
|
|
55
130
|
getAll() {
|
|
56
131
|
return Array.from(this.projects.values());
|
|
57
132
|
}
|
|
133
|
+
/** Every known project with its connection status, most recently active first. */
|
|
134
|
+
snapshot(now = Date.now()) {
|
|
135
|
+
return this.getAll()
|
|
136
|
+
.map((p) => {
|
|
137
|
+
let status = 'idle';
|
|
138
|
+
if (now - p.lastSeen > exports.OFFLINE_AFTER_MS)
|
|
139
|
+
status = 'offline';
|
|
140
|
+
else if (p.lastToolCall !== null && now - p.lastToolCall < exports.ACTIVE_WITHIN_MS)
|
|
141
|
+
status = 'active';
|
|
142
|
+
const t = this.recall.get(p.path);
|
|
143
|
+
return { ...p, status, offeredCount: t?.offered.size ?? 0, usedCount: t?.used.size ?? 0 };
|
|
144
|
+
})
|
|
145
|
+
.sort((a, b) => b.lastActive - a.lastActive);
|
|
146
|
+
}
|
|
58
147
|
}
|
|
59
148
|
exports.ProjectRegistry = ProjectRegistry;
|
|
60
149
|
//# sourceMappingURL=ProjectRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectRegistry.js","sourceRoot":"","sources":["../../../src/proxy/ProjectRegistry.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ProjectRegistry.js","sourceRoot":"","sources":["../../../src/proxy/ProjectRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* has no reason to. This module answers a host PostToolUse hook payload with the same kind of
|
|
9
9
|
* note, at the same three moments:
|
|
10
10
|
*
|
|
11
|
-
* - Reading a file the Brain has memories about →
|
|
11
|
+
* - Reading a file the Brain has memories about → a digest of the most relevant (recallDigest).
|
|
12
12
|
* - Editing a file a documented FAILED attempt depends on → a warning. Plain "this will go
|
|
13
13
|
* stale" notes stay off for native edits: they are the common case and not worth context.
|
|
14
14
|
* - A verdict command (test/build/lint) failing with an error the Brain already has a recorded
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
* only when a search actually returns it to a caller.
|
|
28
28
|
*/
|
|
29
29
|
import { TheBrainV2 } from './TheBrainV2';
|
|
30
|
+
import type { RecallTrigger } from '../utils/reportSavings';
|
|
31
|
+
/** A note plus what it put in front of the agent — reported to the dashboard as recall. */
|
|
32
|
+
export interface RecallNote {
|
|
33
|
+
text: string;
|
|
34
|
+
/** Ids the note named. Empty for notes that carry no memory (stale build, status question). */
|
|
35
|
+
offered: string[];
|
|
36
|
+
trigger: RecallTrigger;
|
|
37
|
+
}
|
|
30
38
|
/**
|
|
31
39
|
* BM25 similarity is normalized against the corpus, so the top result of any query scores
|
|
32
40
|
* high — and every fix memory shares the "fix:" token. It only nominates candidates; this
|
|
@@ -41,9 +49,21 @@ export declare function headlineOverlap(a: string, b: string): number;
|
|
|
41
49
|
* Never throws: a recall hint must never be the reason a tool call reports an error.
|
|
42
50
|
*/
|
|
43
51
|
export declare function recallForHookPayload(payload: unknown, cwd?: string, brain?: TheBrainV2): string;
|
|
52
|
+
/** recallForHookPayload with what the note offered, for reporting. Null when there's no note. */
|
|
53
|
+
export declare function hookRecall(payload: unknown, cwd?: string, brain?: TheBrainV2): RecallNote | null;
|
|
44
54
|
export declare function isStatusQuestion(prompt: string): boolean;
|
|
45
|
-
/**
|
|
46
|
-
|
|
55
|
+
/**
|
|
56
|
+
* How much of what the prompt is about appears in a memory's headline: the IDF-weighted share
|
|
57
|
+
* of the prompt's words (or their stem / bilingual synonym) found among the headline's terms.
|
|
58
|
+
*
|
|
59
|
+
* This replaced "share of the headline found in the prompt", which needed a short prompt to
|
|
60
|
+
* restate half of a long, specific headline: measured on Lemma's own Brain it offered the right
|
|
61
|
+
* memory for 1 of 30 real questions; weighted toward the prompt's rare words it offers several
|
|
62
|
+
* times more and never a wrong one (thresholds above). Prompts with under PROMPT_MIN_UNITS
|
|
63
|
+
* informative words are skipped, which is where the false offers were. This note arrives unasked on every prompt, so it keeps
|
|
64
|
+
* a floor — search_memory, which the agent calls on purpose, does not.
|
|
65
|
+
*/
|
|
66
|
+
export declare function promptCoverage(headline: string, prompt: string, idf: (term: string) => number): number;
|
|
47
67
|
/**
|
|
48
68
|
* The note (empty string for none) for a host UserPromptSubmit payload. This is the one
|
|
49
69
|
* moment recall can happen before the agent answers from its own notes: a status question
|
|
@@ -63,4 +83,17 @@ export interface PromptRecallOptions {
|
|
|
63
83
|
mcpProcessDir?: string;
|
|
64
84
|
}
|
|
65
85
|
export declare function recallForPrompt(payload: unknown, cwd?: string, brain?: TheBrainV2, options?: PromptRecallOptions): string;
|
|
86
|
+
/** recallForPrompt with the memories it offered, for reporting. Null when there's nothing to say. */
|
|
87
|
+
export declare function promptRecall(payload: unknown, cwd?: string, brain?: TheBrainV2, options?: PromptRecallOptions): RecallNote | null;
|
|
88
|
+
/** Tools the playbook names, in one ToolSearch line for hosts that defer MCP schemas. */
|
|
89
|
+
export declare const PLAYBOOK_TOOLS: string[];
|
|
90
|
+
/**
|
|
91
|
+
* When to reach for Lemma — triggers, not judgment calls. "Use it when it adds value" let every
|
|
92
|
+
* individual call look cheaper native; these are the moments where Lemma does something the
|
|
93
|
+
* native tools can't, so there is no cheaper alternative to weigh.
|
|
94
|
+
*/
|
|
95
|
+
export declare const LEMMA_PLAYBOOK: string;
|
|
96
|
+
export declare function sessionBriefing(payload: unknown, cwd?: string, brain?: TheBrainV2): string;
|
|
97
|
+
/** sessionBriefing with the memories it named, for reporting. */
|
|
98
|
+
export declare function sessionRecall(payload: unknown, cwd?: string, brain?: TheBrainV2): RecallNote | null;
|
|
66
99
|
//# sourceMappingURL=HostRecall.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HostRecall.d.ts","sourceRoot":"","sources":["../../../src/subconscious/HostRecall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,EAA0C,UAAU,
|
|
1
|
+
{"version":3,"file":"HostRecall.d.ts","sourceRoot":"","sources":["../../../src/subconscious/HostRecall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,EAA0C,UAAU,EAAY,MAAM,cAAc,CAAC;AAO5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,+FAA+F;IAC/F,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;CACxB;AAKD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAoEzC,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5D;AA0BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAE/F;AAED,iGAAiG;AACjG,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAgChG;AAWD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AA6BD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAYtG;AAQD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAmB;IAClC,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAE7H;AAED,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,EAAE,OAAO,GAAE,mBAAwB,GAAG,UAAU,GAAG,IAAI,CA6DrI;AASD,yFAAyF;AACzF,eAAO,MAAM,cAAc,UAQ1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAQf,CAAC;AAIb,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAE1F;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAiCnG"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* has no reason to. This module answers a host PostToolUse hook payload with the same kind of
|
|
10
10
|
* note, at the same three moments:
|
|
11
11
|
*
|
|
12
|
-
* - Reading a file the Brain has memories about →
|
|
12
|
+
* - Reading a file the Brain has memories about → a digest of the most relevant (recallDigest).
|
|
13
13
|
* - Editing a file a documented FAILED attempt depends on → a warning. Plain "this will go
|
|
14
14
|
* stale" notes stay off for native edits: they are the common case and not worth context.
|
|
15
15
|
* - A verdict command (test/build/lint) failing with an error the Brain already has a recorded
|
|
@@ -31,12 +31,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
31
31
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
32
32
|
};
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.FIX_MATCH_MIN_OVERLAP = void 0;
|
|
34
|
+
exports.LEMMA_PLAYBOOK = exports.PLAYBOOK_TOOLS = exports.FIX_MATCH_MIN_OVERLAP = void 0;
|
|
35
35
|
exports.headlineOverlap = headlineOverlap;
|
|
36
36
|
exports.recallForHookPayload = recallForHookPayload;
|
|
37
|
+
exports.hookRecall = hookRecall;
|
|
37
38
|
exports.isStatusQuestion = isStatusQuestion;
|
|
38
|
-
exports.
|
|
39
|
+
exports.promptCoverage = promptCoverage;
|
|
39
40
|
exports.recallForPrompt = recallForPrompt;
|
|
41
|
+
exports.promptRecall = promptRecall;
|
|
42
|
+
exports.sessionBriefing = sessionBriefing;
|
|
43
|
+
exports.sessionRecall = sessionRecall;
|
|
40
44
|
const fs_1 = __importDefault(require("fs"));
|
|
41
45
|
const path_1 = __importDefault(require("path"));
|
|
42
46
|
const TheBrainV2_1 = require("./TheBrainV2");
|
|
@@ -45,6 +49,7 @@ const FixCapture_1 = require("../utils/FixCapture");
|
|
|
45
49
|
const ageLabel_1 = require("../utils/ageLabel");
|
|
46
50
|
const StoreDraft_1 = require("../utils/StoreDraft");
|
|
47
51
|
const staleBuild_1 = require("../mcp/staleBuild");
|
|
52
|
+
const recallDigest_1 = require("./recallDigest");
|
|
48
53
|
const STATE_FILE = path_1.default.join('.lemma', 'session', 'host-recall.json');
|
|
49
54
|
/**
|
|
50
55
|
* BM25 similarity is normalized against the corpus, so the top result of any query scores
|
|
@@ -86,12 +91,12 @@ function fileNote(brain, toolName, filePath) {
|
|
|
86
91
|
return null;
|
|
87
92
|
const name = path_1.default.basename(filePath);
|
|
88
93
|
if (READ_TOOLS.has(toolName)) {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return { key: `read::${path_1.default.resolve(filePath)}::${ids.join(',')}`, text };
|
|
94
|
+
const hits = (0, recallDigest_1.recallableHits)(brain, result.hits);
|
|
95
|
+
if (hits.length === 0)
|
|
96
|
+
return null;
|
|
97
|
+
const ids = hits.map((h) => h.id).sort();
|
|
98
|
+
const digest = (0, recallDigest_1.digestFileHits)(brain, hits);
|
|
99
|
+
return { key: `read::${path_1.default.resolve(filePath)}::${ids.join(',')}`, text: (0, recallDigest_1.formatFileDigest)(name, digest), offered: digest.ids, trigger: 'read' };
|
|
95
100
|
}
|
|
96
101
|
// Native edits: only the escalated case. "N memories will go stale" on every edit is noise.
|
|
97
102
|
if (result.failedHits.length === 0)
|
|
@@ -100,6 +105,8 @@ function fileNote(brain, toolName, filePath) {
|
|
|
100
105
|
return {
|
|
101
106
|
key: `edit::${path_1.default.resolve(filePath)}::${failedIds.join(',')}`,
|
|
102
107
|
text: `⚠️ Lemma Brain: ${failedIds.join(', ')} document an approach to ${name} that was tried and FAILED. get_memory them before continuing down this path.`,
|
|
108
|
+
offered: failedIds,
|
|
109
|
+
trigger: 'edit',
|
|
103
110
|
};
|
|
104
111
|
}
|
|
105
112
|
function headlineTerms(text) {
|
|
@@ -144,6 +151,8 @@ function failureNote(brain, root, output) {
|
|
|
144
151
|
return {
|
|
145
152
|
key: `fix::${match.id}`,
|
|
146
153
|
text: `🧠 Lemma Brain has a recorded fix for a failure like this one (id ${match.id}): "${match.query.slice(0, 120)}". get_memory ${match.id} for the files and diff that fixed it.`,
|
|
154
|
+
offered: [match.id],
|
|
155
|
+
trigger: 'failure',
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
/**
|
|
@@ -151,9 +160,13 @@ function failureNote(brain, root, output) {
|
|
|
151
160
|
* Never throws: a recall hint must never be the reason a tool call reports an error.
|
|
152
161
|
*/
|
|
153
162
|
function recallForHookPayload(payload, cwd, brain) {
|
|
163
|
+
return hookRecall(payload, cwd, brain)?.text ?? '';
|
|
164
|
+
}
|
|
165
|
+
/** recallForHookPayload with what the note offered, for reporting. Null when there's no note. */
|
|
166
|
+
function hookRecall(payload, cwd, brain) {
|
|
154
167
|
try {
|
|
155
168
|
if (!payload || typeof payload !== 'object')
|
|
156
|
-
return
|
|
169
|
+
return null;
|
|
157
170
|
const p = payload;
|
|
158
171
|
const toolName = typeof p.tool_name === 'string' ? p.tool_name : '';
|
|
159
172
|
const root = (0, TeamBrain_1.repoRoot)(cwd || p.cwd || process.cwd());
|
|
@@ -162,31 +175,31 @@ function recallForHookPayload(payload, cwd, brain) {
|
|
|
162
175
|
if (READ_TOOLS.has(toolName) || EDIT_TOOLS.has(toolName)) {
|
|
163
176
|
const raw = p.tool_input?.file_path ?? p.tool_input?.notebook_path;
|
|
164
177
|
if (typeof raw !== 'string' || !raw)
|
|
165
|
-
return
|
|
178
|
+
return null;
|
|
166
179
|
const filePath = path_1.default.isAbsolute(raw) ? raw : path_1.default.join(root, raw);
|
|
167
180
|
note = fileNote(b, toolName, filePath);
|
|
168
181
|
}
|
|
169
182
|
else if (toolName === 'Bash') {
|
|
170
183
|
const command = p.tool_input?.command;
|
|
171
184
|
if (typeof command !== 'string' || !(0, FixCapture_1.isVerdictCommand)(command))
|
|
172
|
-
return
|
|
185
|
+
return null;
|
|
173
186
|
const verdict = (0, FixCapture_1.hookVerdict)(p);
|
|
174
187
|
if (!verdict || verdict.passed)
|
|
175
|
-
return
|
|
188
|
+
return null;
|
|
176
189
|
note = failureNote(b, root, verdict.output);
|
|
177
190
|
}
|
|
178
191
|
if (!note)
|
|
179
|
-
return
|
|
192
|
+
return null;
|
|
180
193
|
const sessionId = typeof p.session_id === 'string' ? p.session_id : '';
|
|
181
194
|
const state = readState(root, sessionId);
|
|
182
195
|
if (state.noted.includes(note.key))
|
|
183
|
-
return
|
|
196
|
+
return null;
|
|
184
197
|
state.noted.push(note.key);
|
|
185
198
|
writeState(root, state);
|
|
186
|
-
return note.text;
|
|
199
|
+
return { text: note.text, offered: note.offered, trigger: note.trigger };
|
|
187
200
|
}
|
|
188
201
|
catch {
|
|
189
|
-
return
|
|
202
|
+
return null;
|
|
190
203
|
}
|
|
191
204
|
}
|
|
192
205
|
/**
|
|
@@ -201,20 +214,52 @@ function isStatusQuestion(prompt) {
|
|
|
201
214
|
}
|
|
202
215
|
/** At most this many memories are named in one prompt note. */
|
|
203
216
|
const MAX_PROMPT_HITS = 3;
|
|
204
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* Share of the prompt's information (IDF-weighted) a memory headline must carry: the best-ranked
|
|
219
|
+
* memory needs PROMPT_TOP_COVERAGE, the next ones PROMPT_MIN_COVERAGE. Measured on Lemma's own
|
|
220
|
+
* Brain: 13 of 35 real questions get the right memory and none a wrong one, while 1 of 40
|
|
221
|
+
* unrelated work prompts gets an offer. The lexical rank is right far more often than any
|
|
222
|
+
* single memory's coverage says, so the top result gets the lower bar.
|
|
223
|
+
*/
|
|
224
|
+
const PROMPT_TOP_COVERAGE = 0.4;
|
|
205
225
|
const PROMPT_MIN_COVERAGE = 0.5;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
/** Prompts with fewer informative words ("run the tests", "commit and push") carry no topic. */
|
|
227
|
+
const PROMPT_MIN_UNITS = 3;
|
|
228
|
+
/** Each word of `text` with its index expansions (stem, synonym tag); stop words drop out. */
|
|
229
|
+
function wordUnits(text) {
|
|
230
|
+
const words = new Set(text
|
|
231
|
+
.normalize('NFD')
|
|
232
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
233
|
+
.toLowerCase()
|
|
234
|
+
.split(/[^a-z0-9]+/)
|
|
235
|
+
.filter(Boolean));
|
|
236
|
+
return [...words].map((w) => (0, TheBrainV2_1.tokenize)(w)).filter((u) => u.length > 0);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* How much of what the prompt is about appears in a memory's headline: the IDF-weighted share
|
|
240
|
+
* of the prompt's words (or their stem / bilingual synonym) found among the headline's terms.
|
|
241
|
+
*
|
|
242
|
+
* This replaced "share of the headline found in the prompt", which needed a short prompt to
|
|
243
|
+
* restate half of a long, specific headline: measured on Lemma's own Brain it offered the right
|
|
244
|
+
* memory for 1 of 30 real questions; weighted toward the prompt's rare words it offers several
|
|
245
|
+
* times more and never a wrong one (thresholds above). Prompts with under PROMPT_MIN_UNITS
|
|
246
|
+
* informative words are skipped, which is where the false offers were. This note arrives unasked on every prompt, so it keeps
|
|
247
|
+
* a floor — search_memory, which the agent calls on purpose, does not.
|
|
248
|
+
*/
|
|
249
|
+
function promptCoverage(headline, prompt, idf) {
|
|
250
|
+
const units = wordUnits(prompt);
|
|
251
|
+
if (units.length < PROMPT_MIN_UNITS)
|
|
211
252
|
return 0;
|
|
212
|
-
const
|
|
213
|
-
let
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
253
|
+
const head = new Set((0, TheBrainV2_1.tokenize)(headline));
|
|
254
|
+
let total = 0;
|
|
255
|
+
let covered = 0;
|
|
256
|
+
for (const unit of units) {
|
|
257
|
+
const weight = Math.max(...unit.map(idf));
|
|
258
|
+
total += weight;
|
|
259
|
+
if (unit.some((t) => head.has(t)))
|
|
260
|
+
covered += weight;
|
|
261
|
+
}
|
|
262
|
+
return total > 0 ? covered / total : 0;
|
|
218
263
|
}
|
|
219
264
|
function promptKey(prompt) {
|
|
220
265
|
let h = 0;
|
|
@@ -223,27 +268,37 @@ function promptKey(prompt) {
|
|
|
223
268
|
return `prompt::${h}`;
|
|
224
269
|
}
|
|
225
270
|
function recallForPrompt(payload, cwd, brain, options = {}) {
|
|
271
|
+
return promptRecall(payload, cwd, brain, options)?.text ?? '';
|
|
272
|
+
}
|
|
273
|
+
/** recallForPrompt with the memories it offered, for reporting. Null when there's nothing to say. */
|
|
274
|
+
function promptRecall(payload, cwd, brain, options = {}) {
|
|
226
275
|
try {
|
|
227
276
|
if (!payload || typeof payload !== 'object')
|
|
228
|
-
return
|
|
277
|
+
return null;
|
|
229
278
|
const p = payload;
|
|
230
279
|
const prompt = typeof p.prompt === 'string' ? p.prompt.trim() : '';
|
|
231
280
|
// Slash commands and one-word replies carry no topic worth a lookup.
|
|
232
281
|
if (prompt.length < 12 || prompt.startsWith('/'))
|
|
233
|
-
return
|
|
282
|
+
return null;
|
|
234
283
|
const root = (0, TeamBrain_1.repoRoot)(cwd || p.cwd || process.cwd());
|
|
235
284
|
const b = brain ?? (0, TheBrainV2_1.getBrain)();
|
|
236
285
|
const lines = [];
|
|
237
286
|
const hits = b
|
|
238
287
|
.search(prompt.slice(0, 600), 8, 0, { countStats: false, projectId: (0, TheBrainV2_1.deriveProjectId)(root), strictProject: true })
|
|
239
|
-
.filter((r) =>
|
|
288
|
+
.filter((r, rank) => promptCoverage(r.query, prompt, (t) => b.termIdf(t)) >= (rank === 0 ? PROMPT_TOP_COVERAGE : PROMPT_MIN_COVERAGE))
|
|
289
|
+
.filter((r) => {
|
|
290
|
+
const entry = b.getEntry(r.id);
|
|
291
|
+
return !entry || (0, TheBrainV2_1.entrySource)(entry) !== 'auto-git';
|
|
292
|
+
})
|
|
240
293
|
.slice(0, MAX_PROMPT_HITS);
|
|
241
294
|
if (hits.length > 0) {
|
|
295
|
+
// With the headline: an id alone gives the agent nothing to judge relevance by.
|
|
242
296
|
const described = hits.map((r) => {
|
|
243
297
|
const verdict = !r.fresh ? 'STALE' : r.untracked ? 'untracked' : 'fresh';
|
|
244
|
-
|
|
298
|
+
const head = r.query.replace(/\s+/g, ' ').trim();
|
|
299
|
+
return ` • ${r.id} (${verdict}, ${(0, ageLabel_1.ageLabel)(r.timestamp)}${r.outcome === 'failed' ? ', FAILED approach' : ''}): ${head.length > 110 ? `${head.slice(0, 109)}…` : head}`;
|
|
245
300
|
});
|
|
246
|
-
lines.push(`🧠 Lemma Brain has ${plural(hits.length, 'a memory', 'memories')} that may bear on this
|
|
301
|
+
lines.push(`🧠 Lemma Brain has ${plural(hits.length, 'a memory', 'memories')} that may bear on this:`, ...described, `get_memory the one that applies before relying on it; a STALE one must be re-checked against the current code.`);
|
|
247
302
|
}
|
|
248
303
|
if (isStatusQuestion(prompt)) {
|
|
249
304
|
lines.push('🧠 This is a status question: recalled memories and notes go stale as MRs merge and issues close. Verify live state (git fetch/log, gh/glab) before saying what is pending.');
|
|
@@ -253,9 +308,11 @@ function recallForPrompt(payload, cwd, brain, options = {}) {
|
|
|
253
308
|
const out = [];
|
|
254
309
|
// Topical lines are deduped per prompt; the other two have their own one-shot rules.
|
|
255
310
|
const key = promptKey(prompt);
|
|
311
|
+
let offered = [];
|
|
256
312
|
if (lines.length > 0 && !state.noted.includes(key)) {
|
|
257
313
|
out.push(...lines);
|
|
258
314
|
state.noted.push(key);
|
|
315
|
+
offered = hits.map((r) => r.id);
|
|
259
316
|
}
|
|
260
317
|
// A build newer than the running MCP process is spoken once per host session: it is true
|
|
261
318
|
// until the user reconnects, and the tool-result suffix never reaches someone who does not
|
|
@@ -271,12 +328,82 @@ function recallForPrompt(payload, cwd, brain, options = {}) {
|
|
|
271
328
|
if (draft)
|
|
272
329
|
out.push(draft);
|
|
273
330
|
if (out.length === 0)
|
|
274
|
-
return
|
|
331
|
+
return null;
|
|
275
332
|
writeState(root, state);
|
|
276
|
-
return out.join('\n');
|
|
333
|
+
return { text: out.join('\n'), offered, trigger: 'prompt' };
|
|
277
334
|
}
|
|
278
335
|
catch {
|
|
279
|
-
return
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// ── SessionStart: the briefing that used to depend on the agent calling for it ──────────
|
|
340
|
+
//
|
|
341
|
+
// CLAUDE.md said "call get_project_onboarding at the start" and "search_memory before
|
|
342
|
+
// investigating". Both were prose the agent could weigh and skip — and did: a session could
|
|
343
|
+
// run start to finish on native tools and never learn the Brain held the answer. A SessionStart
|
|
344
|
+
// hook puts the essentials in context before the first prompt, with no tool call to forget.
|
|
345
|
+
/** Tools the playbook names, in one ToolSearch line for hosts that defer MCP schemas. */
|
|
346
|
+
exports.PLAYBOOK_TOOLS = [
|
|
347
|
+
'search_memory',
|
|
348
|
+
'get_memory',
|
|
349
|
+
'verify_memory',
|
|
350
|
+
'store_memory',
|
|
351
|
+
'update_memory',
|
|
352
|
+
'read_workspace_file',
|
|
353
|
+
'search_workspace',
|
|
354
|
+
];
|
|
355
|
+
/**
|
|
356
|
+
* When to reach for Lemma — triggers, not judgment calls. "Use it when it adds value" let every
|
|
357
|
+
* individual call look cheaper native; these are the moments where Lemma does something the
|
|
358
|
+
* native tools can't, so there is no cheaper alternative to weigh.
|
|
359
|
+
*/
|
|
360
|
+
exports.LEMMA_PLAYBOOK = [
|
|
361
|
+
'Lemma playbook — follow these triggers:',
|
|
362
|
+
' - Before investigating a bug, error or "why does X": search_memory with the error text or question.',
|
|
363
|
+
' - A 🧠 note names memories: get_memory the top one before re-deriving what it says.',
|
|
364
|
+
' - A fix is verified (tests pass, build succeeds, user confirms): store_memory with filePaths — the root cause, trap or failed approach, not a summary of what changed (git log has that).',
|
|
365
|
+
' - A memory turned out outdated or wrong: update_memory / forget_memory — never store a near-duplicate.',
|
|
366
|
+
' - Reading code you have not located yet, or that may hold secrets: search_workspace / read_workspace_file (they scrub keys).',
|
|
367
|
+
`If Lemma's tools are deferred, load them in ONE ToolSearch: select:${exports.PLAYBOOK_TOOLS.map((t) => `mcp__lemma__${t}`).join(',')}`,
|
|
368
|
+
].join('\n');
|
|
369
|
+
const BRIEFING_MEMORIES = 3;
|
|
370
|
+
function sessionBriefing(payload, cwd, brain) {
|
|
371
|
+
return sessionRecall(payload, cwd, brain)?.text ?? '';
|
|
372
|
+
}
|
|
373
|
+
/** sessionBriefing with the memories it named, for reporting. */
|
|
374
|
+
function sessionRecall(payload, cwd, brain) {
|
|
375
|
+
try {
|
|
376
|
+
const p = payload && typeof payload === 'object' ? payload : {};
|
|
377
|
+
const root = (0, TeamBrain_1.repoRoot)(cwd || p.cwd || process.cwd());
|
|
378
|
+
const b = brain ?? (0, TheBrainV2_1.getBrain)();
|
|
379
|
+
const projectId = (0, TheBrainV2_1.deriveProjectId)(root);
|
|
380
|
+
const lines = [];
|
|
381
|
+
let offered = [];
|
|
382
|
+
const { total, items } = b.list({ projectId, limit: 50 });
|
|
383
|
+
if (total === 0) {
|
|
384
|
+
lines.push(`🧠 Lemma is active in ${path_1.default.basename(root)}. The Brain has no memories for this project yet — store_memory once a fix is verified so the next session starts ahead.`);
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
// Newest memories someone wrote on purpose; commit-log ingests are recalled per file instead.
|
|
388
|
+
const deliberate = items
|
|
389
|
+
.filter((i) => {
|
|
390
|
+
const entry = b.getEntry(i.id);
|
|
391
|
+
return !!entry && (0, TheBrainV2_1.entrySource)(entry) !== 'auto-git';
|
|
392
|
+
})
|
|
393
|
+
.slice(0, BRIEFING_MEMORIES);
|
|
394
|
+
lines.push(`🧠 Lemma is active in ${path_1.default.basename(root)}: the Brain holds ${total} ${plural(total, 'memory', 'memories')} for this project.`);
|
|
395
|
+
if (deliberate.length > 0) {
|
|
396
|
+
lines.push('Most recent decisions and fixes:');
|
|
397
|
+
const digest = (0, recallDigest_1.digestFileHits)(b, deliberate, BRIEFING_MEMORIES);
|
|
398
|
+
lines.push(...digest.lines);
|
|
399
|
+
offered = digest.ids;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
lines.push(exports.LEMMA_PLAYBOOK);
|
|
403
|
+
return { text: lines.join('\n'), offered, trigger: 'session' };
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
return null;
|
|
280
407
|
}
|
|
281
408
|
}
|
|
282
409
|
//# sourceMappingURL=HostRecall.js.map
|