gitmem-mcp 0.2.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/CHANGELOG.md +47 -0
- package/CLAUDE.md.template +65 -0
- package/LICENSE +21 -0
- package/README.md +221 -0
- package/bin/gitmem.js +383 -0
- package/dist/commands/check.d.ts +33 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +492 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/constants/closing-questions.d.ts +40 -0
- package/dist/constants/closing-questions.d.ts.map +1 -0
- package/dist/constants/closing-questions.js +107 -0
- package/dist/constants/closing-questions.js.map +1 -0
- package/dist/diagnostics/anonymizer.d.ts +55 -0
- package/dist/diagnostics/anonymizer.d.ts.map +1 -0
- package/dist/diagnostics/anonymizer.js +191 -0
- package/dist/diagnostics/anonymizer.js.map +1 -0
- package/dist/diagnostics/channels.d.ts +132 -0
- package/dist/diagnostics/channels.d.ts.map +1 -0
- package/dist/diagnostics/channels.js +150 -0
- package/dist/diagnostics/channels.js.map +1 -0
- package/dist/diagnostics/collector.d.ts +183 -0
- package/dist/diagnostics/collector.d.ts.map +1 -0
- package/dist/diagnostics/collector.js +227 -0
- package/dist/diagnostics/collector.js.map +1 -0
- package/dist/diagnostics/index.d.ts +28 -0
- package/dist/diagnostics/index.d.ts.map +1 -0
- package/dist/diagnostics/index.js +31 -0
- package/dist/diagnostics/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/absorb-observations.d.ts +63 -0
- package/dist/schemas/absorb-observations.d.ts.map +1 -0
- package/dist/schemas/absorb-observations.js +25 -0
- package/dist/schemas/absorb-observations.js.map +1 -0
- package/dist/schemas/active-sessions.d.ts +71 -0
- package/dist/schemas/active-sessions.d.ts.map +1 -0
- package/dist/schemas/active-sessions.js +19 -0
- package/dist/schemas/active-sessions.js.map +1 -0
- package/dist/schemas/analyze.d.ts +38 -0
- package/dist/schemas/analyze.d.ts.map +1 -0
- package/dist/schemas/analyze.js +30 -0
- package/dist/schemas/analyze.js.map +1 -0
- package/dist/schemas/common.d.ts +55 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +65 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/create-decision.d.ts +48 -0
- package/dist/schemas/create-decision.d.ts.map +1 -0
- package/dist/schemas/create-decision.js +31 -0
- package/dist/schemas/create-decision.js.map +1 -0
- package/dist/schemas/create-learning.d.ts +107 -0
- package/dist/schemas/create-learning.d.ts.map +1 -0
- package/dist/schemas/create-learning.js +64 -0
- package/dist/schemas/create-learning.js.map +1 -0
- package/dist/schemas/get-transcript.d.ts +24 -0
- package/dist/schemas/get-transcript.d.ts.map +1 -0
- package/dist/schemas/get-transcript.js +22 -0
- package/dist/schemas/get-transcript.js.map +1 -0
- package/dist/schemas/index.d.ts +23 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +23 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/log.d.ts +36 -0
- package/dist/schemas/log.d.ts.map +1 -0
- package/dist/schemas/log.js +27 -0
- package/dist/schemas/log.js.map +1 -0
- package/dist/schemas/prepare-context.d.ts +41 -0
- package/dist/schemas/prepare-context.d.ts.map +1 -0
- package/dist/schemas/prepare-context.js +31 -0
- package/dist/schemas/prepare-context.js.map +1 -0
- package/dist/schemas/recall.d.ts +41 -0
- package/dist/schemas/recall.d.ts.map +1 -0
- package/dist/schemas/recall.js +47 -0
- package/dist/schemas/recall.js.map +1 -0
- package/dist/schemas/record-scar-usage-batch.d.ts +82 -0
- package/dist/schemas/record-scar-usage-batch.d.ts.map +1 -0
- package/dist/schemas/record-scar-usage-batch.js +25 -0
- package/dist/schemas/record-scar-usage-batch.js.map +1 -0
- package/dist/schemas/record-scar-usage.d.ts +51 -0
- package/dist/schemas/record-scar-usage.d.ts.map +1 -0
- package/dist/schemas/record-scar-usage.js +32 -0
- package/dist/schemas/record-scar-usage.js.map +1 -0
- package/dist/schemas/save-transcript.d.ts +38 -0
- package/dist/schemas/save-transcript.d.ts.map +1 -0
- package/dist/schemas/save-transcript.js +30 -0
- package/dist/schemas/save-transcript.js.map +1 -0
- package/dist/schemas/search.d.ts +36 -0
- package/dist/schemas/search.d.ts.map +1 -0
- package/dist/schemas/search.js +27 -0
- package/dist/schemas/search.js.map +1 -0
- package/dist/schemas/session-close.d.ts +371 -0
- package/dist/schemas/session-close.d.ts.map +1 -0
- package/dist/schemas/session-close.js +95 -0
- package/dist/schemas/session-close.js.map +1 -0
- package/dist/schemas/session-start.d.ts +46 -0
- package/dist/schemas/session-start.d.ts.map +1 -0
- package/dist/schemas/session-start.js +33 -0
- package/dist/schemas/session-start.js.map +1 -0
- package/dist/schemas/thread.d.ts +72 -0
- package/dist/schemas/thread.d.ts.map +1 -0
- package/dist/schemas/thread.js +39 -0
- package/dist/schemas/thread.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +313 -0
- package/dist/server.js.map +1 -0
- package/dist/services/active-sessions.d.ts +66 -0
- package/dist/services/active-sessions.d.ts.map +1 -0
- package/dist/services/active-sessions.js +311 -0
- package/dist/services/active-sessions.js.map +1 -0
- package/dist/services/agent-detection.d.ts +25 -0
- package/dist/services/agent-detection.d.ts.map +1 -0
- package/dist/services/agent-detection.js +93 -0
- package/dist/services/agent-detection.js.map +1 -0
- package/dist/services/analytics.d.ts +201 -0
- package/dist/services/analytics.d.ts.map +1 -0
- package/dist/services/analytics.js +483 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/cache.d.ts +148 -0
- package/dist/services/cache.d.ts.map +1 -0
- package/dist/services/cache.js +384 -0
- package/dist/services/cache.js.map +1 -0
- package/dist/services/cache.test.d.ts +8 -0
- package/dist/services/cache.test.d.ts.map +1 -0
- package/dist/services/cache.test.js +267 -0
- package/dist/services/cache.test.js.map +1 -0
- package/dist/services/compliance-validator.d.ts +30 -0
- package/dist/services/compliance-validator.d.ts.map +1 -0
- package/dist/services/compliance-validator.js +257 -0
- package/dist/services/compliance-validator.js.map +1 -0
- package/dist/services/config.d.ts +48 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +128 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/embedding.d.ts +58 -0
- package/dist/services/embedding.d.ts.map +1 -0
- package/dist/services/embedding.js +243 -0
- package/dist/services/embedding.js.map +1 -0
- package/dist/services/gitmem-dir.d.ts +38 -0
- package/dist/services/gitmem-dir.d.ts.map +1 -0
- package/dist/services/gitmem-dir.js +84 -0
- package/dist/services/gitmem-dir.js.map +1 -0
- package/dist/services/local-file-storage.d.ts +56 -0
- package/dist/services/local-file-storage.d.ts.map +1 -0
- package/dist/services/local-file-storage.js +213 -0
- package/dist/services/local-file-storage.js.map +1 -0
- package/dist/services/local-vector-search.d.ts +137 -0
- package/dist/services/local-vector-search.d.ts.map +1 -0
- package/dist/services/local-vector-search.js +311 -0
- package/dist/services/local-vector-search.js.map +1 -0
- package/dist/services/metrics.d.ts +104 -0
- package/dist/services/metrics.d.ts.map +1 -0
- package/dist/services/metrics.js +264 -0
- package/dist/services/metrics.js.map +1 -0
- package/dist/services/session-state.d.ts +113 -0
- package/dist/services/session-state.d.ts.map +1 -0
- package/dist/services/session-state.js +203 -0
- package/dist/services/session-state.js.map +1 -0
- package/dist/services/startup.d.ts +112 -0
- package/dist/services/startup.d.ts.map +1 -0
- package/dist/services/startup.js +436 -0
- package/dist/services/startup.js.map +1 -0
- package/dist/services/storage.d.ts +43 -0
- package/dist/services/storage.d.ts.map +1 -0
- package/dist/services/storage.js +92 -0
- package/dist/services/storage.js.map +1 -0
- package/dist/services/supabase-client.d.ts +163 -0
- package/dist/services/supabase-client.d.ts.map +1 -0
- package/dist/services/supabase-client.js +510 -0
- package/dist/services/supabase-client.js.map +1 -0
- package/dist/services/thread-dedup.d.ts +44 -0
- package/dist/services/thread-dedup.d.ts.map +1 -0
- package/dist/services/thread-dedup.js +113 -0
- package/dist/services/thread-dedup.js.map +1 -0
- package/dist/services/thread-manager.d.ts +77 -0
- package/dist/services/thread-manager.d.ts.map +1 -0
- package/dist/services/thread-manager.js +250 -0
- package/dist/services/thread-manager.js.map +1 -0
- package/dist/services/thread-suggestions.d.ts +66 -0
- package/dist/services/thread-suggestions.d.ts.map +1 -0
- package/dist/services/thread-suggestions.js +243 -0
- package/dist/services/thread-suggestions.js.map +1 -0
- package/dist/services/thread-supabase.d.ts +111 -0
- package/dist/services/thread-supabase.d.ts.map +1 -0
- package/dist/services/thread-supabase.js +459 -0
- package/dist/services/thread-supabase.js.map +1 -0
- package/dist/services/thread-vitality.d.ts +65 -0
- package/dist/services/thread-vitality.d.ts.map +1 -0
- package/dist/services/thread-vitality.js +143 -0
- package/dist/services/thread-vitality.js.map +1 -0
- package/dist/services/tier.d.ts +52 -0
- package/dist/services/tier.d.ts.map +1 -0
- package/dist/services/tier.js +109 -0
- package/dist/services/tier.js.map +1 -0
- package/dist/services/timezone.d.ts +37 -0
- package/dist/services/timezone.d.ts.map +1 -0
- package/dist/services/timezone.js +147 -0
- package/dist/services/timezone.js.map +1 -0
- package/dist/services/transcript-chunker.d.ts +18 -0
- package/dist/services/transcript-chunker.d.ts.map +1 -0
- package/dist/services/transcript-chunker.js +237 -0
- package/dist/services/transcript-chunker.js.map +1 -0
- package/dist/services/triple-writer.d.ts +128 -0
- package/dist/services/triple-writer.d.ts.map +1 -0
- package/dist/services/triple-writer.js +338 -0
- package/dist/services/triple-writer.js.map +1 -0
- package/dist/services/variant-assignment.d.ts +92 -0
- package/dist/services/variant-assignment.d.ts.map +1 -0
- package/dist/services/variant-assignment.js +196 -0
- package/dist/services/variant-assignment.js.map +1 -0
- package/dist/tools/absorb-observations.d.ts +16 -0
- package/dist/tools/absorb-observations.d.ts.map +1 -0
- package/dist/tools/absorb-observations.js +82 -0
- package/dist/tools/absorb-observations.js.map +1 -0
- package/dist/tools/analyze.d.ts +55 -0
- package/dist/tools/analyze.d.ts.map +1 -0
- package/dist/tools/analyze.js +139 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/cleanup-threads.d.ts +47 -0
- package/dist/tools/cleanup-threads.d.ts.map +1 -0
- package/dist/tools/cleanup-threads.js +127 -0
- package/dist/tools/cleanup-threads.js.map +1 -0
- package/dist/tools/confirm-scars.d.ts +23 -0
- package/dist/tools/confirm-scars.d.ts.map +1 -0
- package/dist/tools/confirm-scars.js +209 -0
- package/dist/tools/confirm-scars.js.map +1 -0
- package/dist/tools/create-decision.d.ts +15 -0
- package/dist/tools/create-decision.d.ts.map +1 -0
- package/dist/tools/create-decision.js +138 -0
- package/dist/tools/create-decision.js.map +1 -0
- package/dist/tools/create-learning.d.ts +15 -0
- package/dist/tools/create-learning.d.ts.map +1 -0
- package/dist/tools/create-learning.js +226 -0
- package/dist/tools/create-learning.js.map +1 -0
- package/dist/tools/create-thread.d.ts +42 -0
- package/dist/tools/create-thread.d.ts.map +1 -0
- package/dist/tools/create-thread.js +180 -0
- package/dist/tools/create-thread.js.map +1 -0
- package/dist/tools/definitions.d.ts +5013 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +2017 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/dismiss-suggestion.d.ts +20 -0
- package/dist/tools/dismiss-suggestion.d.ts.map +1 -0
- package/dist/tools/dismiss-suggestion.js +40 -0
- package/dist/tools/dismiss-suggestion.js.map +1 -0
- package/dist/tools/get-transcript.d.ts +24 -0
- package/dist/tools/get-transcript.d.ts.map +1 -0
- package/dist/tools/get-transcript.js +52 -0
- package/dist/tools/get-transcript.js.map +1 -0
- package/dist/tools/graph-traverse.d.ts +83 -0
- package/dist/tools/graph-traverse.d.ts.map +1 -0
- package/dist/tools/graph-traverse.js +394 -0
- package/dist/tools/graph-traverse.js.map +1 -0
- package/dist/tools/list-threads.d.ts +15 -0
- package/dist/tools/list-threads.d.ts.map +1 -0
- package/dist/tools/list-threads.js +114 -0
- package/dist/tools/list-threads.js.map +1 -0
- package/dist/tools/log.d.ts +43 -0
- package/dist/tools/log.d.ts.map +1 -0
- package/dist/tools/log.js +157 -0
- package/dist/tools/log.js.map +1 -0
- package/dist/tools/prepare-context.d.ts +36 -0
- package/dist/tools/prepare-context.d.ts.map +1 -0
- package/dist/tools/prepare-context.js +353 -0
- package/dist/tools/prepare-context.js.map +1 -0
- package/dist/tools/promote-suggestion.d.ts +25 -0
- package/dist/tools/promote-suggestion.d.ts.map +1 -0
- package/dist/tools/promote-suggestion.js +60 -0
- package/dist/tools/promote-suggestion.js.map +1 -0
- package/dist/tools/recall.d.ts +77 -0
- package/dist/tools/recall.d.ts.map +1 -0
- package/dist/tools/recall.js +423 -0
- package/dist/tools/recall.js.map +1 -0
- package/dist/tools/recall.test.d.ts +5 -0
- package/dist/tools/recall.test.d.ts.map +1 -0
- package/dist/tools/recall.test.js +155 -0
- package/dist/tools/recall.test.js.map +1 -0
- package/dist/tools/record-scar-usage-batch.d.ts +10 -0
- package/dist/tools/record-scar-usage-batch.d.ts.map +1 -0
- package/dist/tools/record-scar-usage-batch.js +153 -0
- package/dist/tools/record-scar-usage-batch.js.map +1 -0
- package/dist/tools/record-scar-usage.d.ts +14 -0
- package/dist/tools/record-scar-usage.d.ts.map +1 -0
- package/dist/tools/record-scar-usage.js +94 -0
- package/dist/tools/record-scar-usage.js.map +1 -0
- package/dist/tools/resolve-thread.d.ts +16 -0
- package/dist/tools/resolve-thread.d.ts.map +1 -0
- package/dist/tools/resolve-thread.js +102 -0
- package/dist/tools/resolve-thread.js.map +1 -0
- package/dist/tools/save-transcript.d.ts +29 -0
- package/dist/tools/save-transcript.d.ts.map +1 -0
- package/dist/tools/save-transcript.js +97 -0
- package/dist/tools/save-transcript.js.map +1 -0
- package/dist/tools/search.d.ts +46 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +186 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/session-close.d.ts +14 -0
- package/dist/tools/session-close.d.ts.map +1 -0
- package/dist/tools/session-close.js +881 -0
- package/dist/tools/session-close.js.map +1 -0
- package/dist/tools/session-start.d.ts +38 -0
- package/dist/tools/session-start.d.ts.map +1 -0
- package/dist/tools/session-start.js +1104 -0
- package/dist/tools/session-start.js.map +1 -0
- package/dist/types/index.d.ts +456 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +76 -0
- package/schema/setup.sql +193 -0
- package/schema/starter-scars.json +206 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active Sessions Registry (GIT-19)
|
|
3
|
+
*
|
|
4
|
+
* CRUD operations for .gitmem/active-sessions.json — the multi-session
|
|
5
|
+
* registry that tracks all running MCP server sessions.
|
|
6
|
+
*
|
|
7
|
+
* Key design decisions:
|
|
8
|
+
* - Atomic writes (write-temp-rename) because multiple processes may
|
|
9
|
+
* register/unregister concurrently.
|
|
10
|
+
* - Sync I/O to match codebase convention (fs.writeFileSync etc).
|
|
11
|
+
* - Graceful degradation: corrupted registry = start fresh.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from "fs";
|
|
14
|
+
import * as path from "path";
|
|
15
|
+
import * as os from "os";
|
|
16
|
+
import { getGitmemDir, getSessionPath } from "./gitmem-dir.js";
|
|
17
|
+
import { ActiveSessionsRegistrySchema } from "../schemas/active-sessions.js";
|
|
18
|
+
const REGISTRY_FILENAME = "active-sessions.json";
|
|
19
|
+
const STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
20
|
+
// --- Atomic write utility ---
|
|
21
|
+
/**
|
|
22
|
+
* Atomic write: write to a temp file in the same directory, then rename.
|
|
23
|
+
* rename() on the same filesystem is atomic on POSIX.
|
|
24
|
+
* Falls back to direct write on rename failure.
|
|
25
|
+
*/
|
|
26
|
+
function atomicWriteFileSync(filePath, data) {
|
|
27
|
+
const dir = path.dirname(filePath);
|
|
28
|
+
const tmpPath = path.join(dir, `.active-sessions.${process.pid}.tmp`);
|
|
29
|
+
try {
|
|
30
|
+
fs.writeFileSync(tmpPath, data, "utf-8");
|
|
31
|
+
fs.renameSync(tmpPath, filePath);
|
|
32
|
+
}
|
|
33
|
+
catch (renameErr) {
|
|
34
|
+
try {
|
|
35
|
+
fs.unlinkSync(tmpPath);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
/* ignore cleanup failure */
|
|
39
|
+
}
|
|
40
|
+
console.warn("[active-sessions] Atomic rename failed, falling back to direct write:", renameErr);
|
|
41
|
+
fs.writeFileSync(filePath, data, "utf-8");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// --- Internal helpers ---
|
|
45
|
+
function getRegistryPath() {
|
|
46
|
+
return path.join(getGitmemDir(), REGISTRY_FILENAME);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Read the registry from disk. Returns empty registry if file
|
|
50
|
+
* doesn't exist, is corrupted, or fails Zod validation.
|
|
51
|
+
*/
|
|
52
|
+
function readRegistry() {
|
|
53
|
+
try {
|
|
54
|
+
const filePath = getRegistryPath();
|
|
55
|
+
if (!fs.existsSync(filePath)) {
|
|
56
|
+
return { sessions: [] };
|
|
57
|
+
}
|
|
58
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
59
|
+
const parsed = JSON.parse(raw);
|
|
60
|
+
const result = ActiveSessionsRegistrySchema.safeParse(parsed);
|
|
61
|
+
if (result.success) {
|
|
62
|
+
return result.data;
|
|
63
|
+
}
|
|
64
|
+
console.warn("[active-sessions] Registry failed validation, starting fresh:", result.error.message);
|
|
65
|
+
return { sessions: [] };
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.warn("[active-sessions] Failed to read registry:", error);
|
|
69
|
+
return { sessions: [] };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Write the registry to disk using atomic write.
|
|
74
|
+
*/
|
|
75
|
+
function writeRegistry(registry) {
|
|
76
|
+
const filePath = getRegistryPath();
|
|
77
|
+
const dir = path.dirname(filePath);
|
|
78
|
+
if (!fs.existsSync(dir)) {
|
|
79
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
atomicWriteFileSync(filePath, JSON.stringify(registry, null, 2));
|
|
82
|
+
}
|
|
83
|
+
// --- CRUD operations ---
|
|
84
|
+
/**
|
|
85
|
+
* Register a new session in the active-sessions registry.
|
|
86
|
+
* Idempotent: re-registering the same session_id replaces the entry.
|
|
87
|
+
*/
|
|
88
|
+
export function registerSession(entry) {
|
|
89
|
+
const registry = readRegistry();
|
|
90
|
+
registry.sessions = registry.sessions.filter((s) => s.session_id !== entry.session_id);
|
|
91
|
+
registry.sessions.push(entry);
|
|
92
|
+
writeRegistry(registry);
|
|
93
|
+
console.error(`[active-sessions] Registered session ${entry.session_id.slice(0, 8)} (agent: ${entry.agent}, pid: ${entry.pid})`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Unregister a session from the active-sessions registry.
|
|
97
|
+
* Returns true if the session was found and removed.
|
|
98
|
+
*/
|
|
99
|
+
export function unregisterSession(sessionId) {
|
|
100
|
+
const registry = readRegistry();
|
|
101
|
+
const before = registry.sessions.length;
|
|
102
|
+
registry.sessions = registry.sessions.filter((s) => s.session_id !== sessionId);
|
|
103
|
+
const removed = registry.sessions.length < before;
|
|
104
|
+
if (removed) {
|
|
105
|
+
writeRegistry(registry);
|
|
106
|
+
console.error(`[active-sessions] Unregistered session ${sessionId.slice(0, 8)}`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
console.warn(`[active-sessions] Session ${sessionId.slice(0, 8)} not found in registry`);
|
|
110
|
+
}
|
|
111
|
+
return removed;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* List all active sessions from the registry.
|
|
115
|
+
*/
|
|
116
|
+
export function listActiveSessions() {
|
|
117
|
+
return readRegistry().sessions;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Find a session by hostname and PID.
|
|
121
|
+
* Used by session_start to detect if this process already has a registered session.
|
|
122
|
+
*/
|
|
123
|
+
export function findSessionByHostPid(hostname, pid) {
|
|
124
|
+
const registry = readRegistry();
|
|
125
|
+
return registry.sessions.find((s) => s.hostname === hostname && s.pid === pid) || null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Find a session by session_id.
|
|
129
|
+
*/
|
|
130
|
+
export function findSessionById(sessionId) {
|
|
131
|
+
const registry = readRegistry();
|
|
132
|
+
return registry.sessions.find((s) => s.session_id === sessionId) || null;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Prune stale sessions from the registry (GIT-22 enhanced).
|
|
136
|
+
*
|
|
137
|
+
* A session is stale if:
|
|
138
|
+
* 1. Its started_at is older than 24 hours, OR
|
|
139
|
+
* 2. Its PID no longer exists on this hostname (process died without cleanup), OR
|
|
140
|
+
* 3. Its per-session directory/session.json is missing (orphaned registry entry)
|
|
141
|
+
*
|
|
142
|
+
* Also cleans up per-session directories for pruned sessions,
|
|
143
|
+
* and removes orphaned session directories with no registry entry.
|
|
144
|
+
* Returns the number of sessions pruned.
|
|
145
|
+
*/
|
|
146
|
+
export function pruneStale() {
|
|
147
|
+
const registry = readRegistry();
|
|
148
|
+
const now = Date.now();
|
|
149
|
+
const currentHostname = os.hostname();
|
|
150
|
+
const before = registry.sessions.length;
|
|
151
|
+
const gitmemDir = getGitmemDir();
|
|
152
|
+
registry.sessions = registry.sessions.filter((entry) => {
|
|
153
|
+
// GIT-22: Check for orphaned registry entry (session file missing)
|
|
154
|
+
const sessionFile = path.join(gitmemDir, "sessions", entry.session_id, "session.json");
|
|
155
|
+
if (!fs.existsSync(sessionFile)) {
|
|
156
|
+
// Only prune if session is old enough that session_start should have written the file.
|
|
157
|
+
// Brand-new sessions may not have the file yet (race window during session_start).
|
|
158
|
+
const age = now - new Date(entry.started_at).getTime();
|
|
159
|
+
if (age > 60_000) { // 1 minute grace period
|
|
160
|
+
console.error(`[active-sessions] Pruning orphaned registry entry ${entry.session_id.slice(0, 8)} (session file missing)`);
|
|
161
|
+
cleanupSessionDir(gitmemDir, entry.session_id);
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Check age
|
|
166
|
+
const age = now - new Date(entry.started_at).getTime();
|
|
167
|
+
if (age > STALE_THRESHOLD_MS) {
|
|
168
|
+
console.error(`[active-sessions] Pruning stale session ${entry.session_id.slice(0, 8)} (age: ${Math.round(age / 3600000)}h)`);
|
|
169
|
+
cleanupSessionDir(gitmemDir, entry.session_id);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
// Check if PID is alive (only for sessions on the same host)
|
|
173
|
+
if (entry.hostname === currentHostname) {
|
|
174
|
+
try {
|
|
175
|
+
process.kill(entry.pid, 0); // Signal 0 = check existence only
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
console.error(`[active-sessions] Pruning dead session ${entry.session_id.slice(0, 8)} (pid ${entry.pid} no longer running)`);
|
|
179
|
+
cleanupSessionDir(gitmemDir, entry.session_id);
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return true;
|
|
184
|
+
});
|
|
185
|
+
const pruned = before - registry.sessions.length;
|
|
186
|
+
if (pruned > 0) {
|
|
187
|
+
writeRegistry(registry);
|
|
188
|
+
console.error(`[active-sessions] Pruned ${pruned} stale session(s)`);
|
|
189
|
+
}
|
|
190
|
+
// GIT-22: Clean up orphaned session directories (dir exists but no registry entry)
|
|
191
|
+
pruneOrphanedDirs(gitmemDir, registry);
|
|
192
|
+
return pruned;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* GIT-22: Remove session directories that have no corresponding registry entry.
|
|
196
|
+
* These can occur when a process crashes after creating the directory but before
|
|
197
|
+
* registering, or when the registry is rebuilt after corruption.
|
|
198
|
+
*/
|
|
199
|
+
function pruneOrphanedDirs(gitmemDir, registry) {
|
|
200
|
+
try {
|
|
201
|
+
const sessionsDir = path.join(gitmemDir, "sessions");
|
|
202
|
+
if (!fs.existsSync(sessionsDir))
|
|
203
|
+
return;
|
|
204
|
+
const registeredIds = new Set(registry.sessions.map((s) => s.session_id));
|
|
205
|
+
const dirs = fs.readdirSync(sessionsDir);
|
|
206
|
+
for (const dirName of dirs) {
|
|
207
|
+
if (registeredIds.has(dirName))
|
|
208
|
+
continue;
|
|
209
|
+
const dirPath = path.join(sessionsDir, dirName);
|
|
210
|
+
try {
|
|
211
|
+
const stat = fs.statSync(dirPath);
|
|
212
|
+
if (!stat.isDirectory())
|
|
213
|
+
continue;
|
|
214
|
+
// Only prune directories older than 1 hour to avoid race conditions
|
|
215
|
+
const ageMs = Date.now() - stat.mtimeMs;
|
|
216
|
+
if (ageMs > 60 * 60 * 1000) {
|
|
217
|
+
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
218
|
+
console.error(`[active-sessions] Cleaned up orphaned session directory: ${dirName.slice(0, 8)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// Ignore errors on individual directories
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// sessionsDir doesn't exist or can't be read — nothing to prune
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Clean up the per-session directory for a pruned/closed session.
|
|
232
|
+
*/
|
|
233
|
+
function cleanupSessionDir(gitmemDir, sessionId) {
|
|
234
|
+
try {
|
|
235
|
+
const sessionDir = path.join(gitmemDir, "sessions", sessionId);
|
|
236
|
+
if (fs.existsSync(sessionDir)) {
|
|
237
|
+
fs.rmSync(sessionDir, { recursive: true, force: true });
|
|
238
|
+
console.error(`[active-sessions] Cleaned up session directory: ${sessionDir}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
console.warn(`[active-sessions] Failed to clean up session directory for ${sessionId.slice(0, 8)}:`, error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// --- GIT-23: Migration from old format ---
|
|
246
|
+
let migrationRan = false;
|
|
247
|
+
/**
|
|
248
|
+
* GIT-23: Migrate from old active-session.json (singular) to new multi-session format.
|
|
249
|
+
*
|
|
250
|
+
* Runs once per process. If old file exists and new registry does not:
|
|
251
|
+
* 1. Read old file
|
|
252
|
+
* 2. Create per-session directory with session.json
|
|
253
|
+
* 3. Create active-sessions.json registry with single entry
|
|
254
|
+
* 4. Rename old file to active-session.json.migrated (backup)
|
|
255
|
+
*
|
|
256
|
+
* Idempotent: skips if new registry already exists or old file is absent.
|
|
257
|
+
*/
|
|
258
|
+
export function migrateFromLegacy() {
|
|
259
|
+
if (migrationRan)
|
|
260
|
+
return false;
|
|
261
|
+
migrationRan = true;
|
|
262
|
+
try {
|
|
263
|
+
const gitmemDir = getGitmemDir();
|
|
264
|
+
const oldPath = path.join(gitmemDir, "active-session.json");
|
|
265
|
+
const newPath = path.join(gitmemDir, REGISTRY_FILENAME);
|
|
266
|
+
// Skip if new registry already exists or old file is absent
|
|
267
|
+
if (fs.existsSync(newPath) || !fs.existsSync(oldPath)) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
const raw = fs.readFileSync(oldPath, "utf-8");
|
|
271
|
+
const old = JSON.parse(raw);
|
|
272
|
+
if (!old.session_id) {
|
|
273
|
+
console.warn("[active-sessions] Legacy file has no session_id, skipping migration");
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
// 1. Create per-session directory with session.json
|
|
277
|
+
const sessionFilePath = getSessionPath(old.session_id, "session.json");
|
|
278
|
+
fs.writeFileSync(sessionFilePath, JSON.stringify({
|
|
279
|
+
...old,
|
|
280
|
+
hostname: old.hostname || os.hostname(),
|
|
281
|
+
pid: old.pid || process.pid,
|
|
282
|
+
}, null, 2));
|
|
283
|
+
// 2. Create registry with single entry
|
|
284
|
+
const entry = {
|
|
285
|
+
session_id: old.session_id,
|
|
286
|
+
agent: old.agent || "CLI",
|
|
287
|
+
started_at: old.started_at || new Date().toISOString(),
|
|
288
|
+
hostname: old.hostname || os.hostname(),
|
|
289
|
+
pid: old.pid || process.pid,
|
|
290
|
+
project: old.project || "orchestra_dev",
|
|
291
|
+
};
|
|
292
|
+
writeRegistry({ sessions: [entry] });
|
|
293
|
+
// 3. Rename old file to backup
|
|
294
|
+
const backupPath = path.join(gitmemDir, "active-session.json.migrated");
|
|
295
|
+
fs.renameSync(oldPath, backupPath);
|
|
296
|
+
console.error(`[active-sessions] Migrated legacy active-session.json → ` +
|
|
297
|
+
`sessions/${old.session_id.slice(0, 8)}/ + active-sessions.json (backup: active-session.json.migrated)`);
|
|
298
|
+
return true;
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
console.warn("[active-sessions] Legacy migration failed (non-fatal):", error);
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Reset migration flag (for testing only).
|
|
307
|
+
*/
|
|
308
|
+
export function resetMigrationFlag() {
|
|
309
|
+
migrationRan = false;
|
|
310
|
+
}
|
|
311
|
+
//# sourceMappingURL=active-sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-sessions.js","sourceRoot":"","sources":["../../src/services/active-sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Detection Service
|
|
3
|
+
*
|
|
4
|
+
* Detects which Claude agent is running based on environment variables,
|
|
5
|
+
* Docker presence, and hostname.
|
|
6
|
+
*
|
|
7
|
+
* Detection matrix (from CLAUDE.md):
|
|
8
|
+
* | ENTRYPOINT | Docker | Hostname | Identity |
|
|
9
|
+
* |------------|--------|----------|----------|
|
|
10
|
+
* | cli | YES | (any) | CLI |
|
|
11
|
+
* | cli | NO | orchestra.nteg.com | CODA-1 |
|
|
12
|
+
* | claude-desktop | NO | (any) | DAC |
|
|
13
|
+
* | (empty) | NO | (local) | Brain_Local |
|
|
14
|
+
* | (empty) | NO | (no fs) | Brain_Cloud |
|
|
15
|
+
*/
|
|
16
|
+
import type { AgentIdentity, DetectedEnvironment } from "../types/index.js";
|
|
17
|
+
/**
|
|
18
|
+
* Detect the current agent identity based on environment
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectAgent(): DetectedEnvironment;
|
|
21
|
+
/**
|
|
22
|
+
* Get just the agent identity (convenience function)
|
|
23
|
+
*/
|
|
24
|
+
export declare function getAgentIdentity(): AgentIdentity;
|
|
25
|
+
//# sourceMappingURL=agent-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-detection.d.ts","sourceRoot":"","sources":["../../src/services/agent-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAyB5E;;GAEG;AACH,wBAAgB,WAAW,IAAI,mBAAmB,CAuCjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Detection Service
|
|
3
|
+
*
|
|
4
|
+
* Detects which Claude agent is running based on environment variables,
|
|
5
|
+
* Docker presence, and hostname.
|
|
6
|
+
*
|
|
7
|
+
* Detection matrix (from CLAUDE.md):
|
|
8
|
+
* | ENTRYPOINT | Docker | Hostname | Identity |
|
|
9
|
+
* |------------|--------|----------|----------|
|
|
10
|
+
* | cli | YES | (any) | CLI |
|
|
11
|
+
* | cli | NO | orchestra.nteg.com | CODA-1 |
|
|
12
|
+
* | claude-desktop | NO | (any) | DAC |
|
|
13
|
+
* | (empty) | NO | (local) | Brain_Local |
|
|
14
|
+
* | (empty) | NO | (no fs) | Brain_Cloud |
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from "node:fs";
|
|
17
|
+
import * as os from "node:os";
|
|
18
|
+
/**
|
|
19
|
+
* Check if running in Docker container
|
|
20
|
+
*/
|
|
21
|
+
function isDocker() {
|
|
22
|
+
try {
|
|
23
|
+
return fs.existsSync("/.dockerenv");
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check if filesystem is accessible (Brain Local vs Brain Cloud)
|
|
31
|
+
*/
|
|
32
|
+
function hasFilesystemAccess() {
|
|
33
|
+
try {
|
|
34
|
+
fs.accessSync("/tmp", fs.constants.R_OK);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Detect the current agent identity based on environment
|
|
43
|
+
*/
|
|
44
|
+
export function detectAgent() {
|
|
45
|
+
const entrypoint = process.env.CLAUDE_CODE_ENTRYPOINT || null;
|
|
46
|
+
const docker = isDocker();
|
|
47
|
+
const hostname = os.hostname();
|
|
48
|
+
let agent;
|
|
49
|
+
if (entrypoint === "cli") {
|
|
50
|
+
if (docker) {
|
|
51
|
+
// CLI in Docker container
|
|
52
|
+
agent = "CLI";
|
|
53
|
+
}
|
|
54
|
+
else if (hostname === "orchestra.nteg.com" || hostname === "cyrus") {
|
|
55
|
+
// CLI on orchestra server = CODA-1
|
|
56
|
+
agent = "CODA-1";
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// CLI elsewhere (fallback)
|
|
60
|
+
agent = "CLI";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (entrypoint === "claude-desktop") {
|
|
64
|
+
// Desktop app code tab
|
|
65
|
+
agent = "DAC";
|
|
66
|
+
}
|
|
67
|
+
else if (!entrypoint) {
|
|
68
|
+
// No entrypoint - could be Brain Local or Brain Cloud
|
|
69
|
+
if (hasFilesystemAccess()) {
|
|
70
|
+
agent = "Brain_Local";
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
agent = "Brain_Cloud";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Unknown entrypoint
|
|
78
|
+
agent = "Unknown";
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
entrypoint,
|
|
82
|
+
docker,
|
|
83
|
+
hostname,
|
|
84
|
+
agent,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get just the agent identity (convenience function)
|
|
89
|
+
*/
|
|
90
|
+
export function getAgentIdentity() {
|
|
91
|
+
return detectAgent().agent;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=agent-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-detection.js","sourceRoot":"","sources":["../../src/services/agent-detection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAG9B;;GAEG;AACH,SAAS,QAAQ;IACf,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAE/B,IAAI,KAAoB,CAAC;IAEzB,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,EAAE,CAAC;YACX,0BAA0B;YAC1B,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;aAAM,IAAI,QAAQ,KAAK,oBAAoB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACrE,mCAAmC;YACnC,KAAK,GAAG,QAAQ,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,2BAA2B;YAC3B,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;IACH,CAAC;SAAM,IAAI,UAAU,KAAK,gBAAgB,EAAE,CAAC;QAC3C,uBAAuB;QACvB,KAAK,GAAG,KAAK,CAAC;IAChB,CAAC;SAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACvB,sDAAsD;QACtD,IAAI,mBAAmB,EAAE,EAAE,CAAC;YAC1B,KAAK,GAAG,aAAa,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,aAAa,CAAC;QACxB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,qBAAqB;QACrB,KAAK,GAAG,SAAS,CAAC;IACpB,CAAC;IAED,OAAO;QACL,UAAU;QACV,MAAM;QACN,QAAQ;QACR,KAAK;KACN,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,WAAW,EAAE,CAAC,KAAK,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Service (OD-567)
|
|
3
|
+
*
|
|
4
|
+
* Shared analytics engine for session insights. Powers both the
|
|
5
|
+
* gitmem-analyze MCP tool (CLI) and the GitMem Console dashboard.
|
|
6
|
+
*
|
|
7
|
+
* Uses directQuery for raw Supabase REST access (no ww-mcp dependency).
|
|
8
|
+
*/
|
|
9
|
+
import type { Project } from "../types/index.js";
|
|
10
|
+
export interface SessionRecord {
|
|
11
|
+
id: string;
|
|
12
|
+
session_title: string | null;
|
|
13
|
+
session_date: string;
|
|
14
|
+
agent: string;
|
|
15
|
+
linear_issue: string | null;
|
|
16
|
+
decisions: unknown[];
|
|
17
|
+
open_threads: string[];
|
|
18
|
+
closing_reflection: ClosingReflection | null;
|
|
19
|
+
close_compliance: CloseCompliance | null;
|
|
20
|
+
created_at: string;
|
|
21
|
+
project: string;
|
|
22
|
+
}
|
|
23
|
+
interface ClosingReflection {
|
|
24
|
+
what_broke?: string;
|
|
25
|
+
what_took_longer?: string;
|
|
26
|
+
do_differently?: string;
|
|
27
|
+
what_worked?: string;
|
|
28
|
+
wrong_assumption?: string;
|
|
29
|
+
scars_applied?: string | string[];
|
|
30
|
+
human_additions?: string;
|
|
31
|
+
}
|
|
32
|
+
interface CloseCompliance {
|
|
33
|
+
agent?: string;
|
|
34
|
+
close_type?: string;
|
|
35
|
+
scars_applied?: number;
|
|
36
|
+
learnings_stored?: number;
|
|
37
|
+
checklist_displayed?: boolean;
|
|
38
|
+
human_asked_for_corrections?: boolean;
|
|
39
|
+
questions_answered_by_agent?: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface AgentBreakdown {
|
|
42
|
+
agent: string;
|
|
43
|
+
session_count: number;
|
|
44
|
+
decisions_total: number;
|
|
45
|
+
threads_total: number;
|
|
46
|
+
close_types: Record<string, number>;
|
|
47
|
+
}
|
|
48
|
+
export interface SummaryAnalytics {
|
|
49
|
+
period: {
|
|
50
|
+
start: string;
|
|
51
|
+
end: string;
|
|
52
|
+
days: number;
|
|
53
|
+
};
|
|
54
|
+
total_sessions: number;
|
|
55
|
+
sessions_with_reflections: number;
|
|
56
|
+
sessions_with_issues: number;
|
|
57
|
+
total_decisions: number;
|
|
58
|
+
total_open_threads: number;
|
|
59
|
+
agents: AgentBreakdown[];
|
|
60
|
+
close_type_distribution: Record<string, number>;
|
|
61
|
+
top_issues: Array<{
|
|
62
|
+
issue: string;
|
|
63
|
+
session_count: number;
|
|
64
|
+
}>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Fetch sessions within a date range.
|
|
68
|
+
* Selects only the fields needed for analytics (no embedding column).
|
|
69
|
+
*/
|
|
70
|
+
export declare function querySessionsByDateRange(startDate: string, endDate: string, project: Project, agentFilter?: string): Promise<SessionRecord[]>;
|
|
71
|
+
export interface ScarUsageRecord {
|
|
72
|
+
scar_id: string;
|
|
73
|
+
scar_title: string | null;
|
|
74
|
+
scar_severity: string | null;
|
|
75
|
+
agent: string | null;
|
|
76
|
+
reference_type: string;
|
|
77
|
+
execution_successful: boolean | null;
|
|
78
|
+
surfaced_at: string;
|
|
79
|
+
}
|
|
80
|
+
export interface RepeatMistakeRecord {
|
|
81
|
+
id: string;
|
|
82
|
+
title: string;
|
|
83
|
+
related_scar_id: string | null;
|
|
84
|
+
repeat_mistake_details: {
|
|
85
|
+
reason?: string;
|
|
86
|
+
} | null;
|
|
87
|
+
created_at: string;
|
|
88
|
+
}
|
|
89
|
+
export interface BlindspotsData {
|
|
90
|
+
period: {
|
|
91
|
+
start: string;
|
|
92
|
+
end: string;
|
|
93
|
+
days: number;
|
|
94
|
+
};
|
|
95
|
+
total_scars_surfaced: number;
|
|
96
|
+
total_scar_usages: number;
|
|
97
|
+
ignored_scars: Array<{
|
|
98
|
+
scar_id: string;
|
|
99
|
+
title: string;
|
|
100
|
+
severity: string;
|
|
101
|
+
times_surfaced: number;
|
|
102
|
+
times_ignored: number;
|
|
103
|
+
ignore_rate: number;
|
|
104
|
+
agents: string[];
|
|
105
|
+
}>;
|
|
106
|
+
failed_applications: Array<{
|
|
107
|
+
scar_id: string;
|
|
108
|
+
title: string;
|
|
109
|
+
times_applied: number;
|
|
110
|
+
times_failed: number;
|
|
111
|
+
failure_rate: number;
|
|
112
|
+
}>;
|
|
113
|
+
repeat_mistakes: Array<{
|
|
114
|
+
id: string;
|
|
115
|
+
title: string;
|
|
116
|
+
original_scar_title: string;
|
|
117
|
+
reason: string;
|
|
118
|
+
created_at: string;
|
|
119
|
+
}>;
|
|
120
|
+
agent_effectiveness: Array<{
|
|
121
|
+
agent: string;
|
|
122
|
+
scars_surfaced: number;
|
|
123
|
+
scars_applied: number;
|
|
124
|
+
application_rate: number;
|
|
125
|
+
success_rate: number;
|
|
126
|
+
}>;
|
|
127
|
+
severity_breakdown: Array<{
|
|
128
|
+
severity: string;
|
|
129
|
+
surfaced: number;
|
|
130
|
+
applied: number;
|
|
131
|
+
ignored: number;
|
|
132
|
+
application_rate: number;
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Fetch scar_usage records within a date range.
|
|
137
|
+
*/
|
|
138
|
+
export declare function queryScarUsageByDateRange(startDate: string, _endDate: string, _project: Project, agentFilter?: string): Promise<ScarUsageRecord[]>;
|
|
139
|
+
/**
|
|
140
|
+
* Fetch repeat mistakes from orchestra_learnings within a date range.
|
|
141
|
+
*/
|
|
142
|
+
export declare function queryRepeatMistakes(startDate: string, _endDate: string, project: Project): Promise<RepeatMistakeRecord[]>;
|
|
143
|
+
/**
|
|
144
|
+
* Resolve scar titles and severities from orchestra_learnings for scar_usage
|
|
145
|
+
* records that have null/missing title data.
|
|
146
|
+
*/
|
|
147
|
+
export declare function enrichScarUsageTitles(usages: ScarUsageRecord[]): Promise<ScarUsageRecord[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Compute blindspots analytics from scar usage and repeat mistake data.
|
|
150
|
+
*/
|
|
151
|
+
export declare function computeBlindspots(usages: ScarUsageRecord[], repeatMistakes: RepeatMistakeRecord[], days: number): BlindspotsData;
|
|
152
|
+
/**
|
|
153
|
+
* Compute basic summary statistics from a set of sessions.
|
|
154
|
+
*/
|
|
155
|
+
export declare function computeSummary(sessions: SessionRecord[], days: number): SummaryAnalytics;
|
|
156
|
+
/**
|
|
157
|
+
* Extract and aggregate closing reflections from sessions.
|
|
158
|
+
* Returns arrays of each reflection field for further analysis.
|
|
159
|
+
*/
|
|
160
|
+
type ReflectionEntry = {
|
|
161
|
+
text: string;
|
|
162
|
+
session_id: string;
|
|
163
|
+
agent: string;
|
|
164
|
+
date: string;
|
|
165
|
+
};
|
|
166
|
+
type ReflectionCategory = {
|
|
167
|
+
entries: ReflectionEntry[];
|
|
168
|
+
total_count: number;
|
|
169
|
+
};
|
|
170
|
+
export declare function aggregateClosingReflections(sessions: SessionRecord[], maxPerCategory?: number, maxTextLength?: number): {
|
|
171
|
+
what_broke: ReflectionCategory;
|
|
172
|
+
what_worked: ReflectionCategory;
|
|
173
|
+
wrong_assumptions: ReflectionCategory;
|
|
174
|
+
do_differently: ReflectionCategory;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Format summary analytics as compact markdown.
|
|
178
|
+
*/
|
|
179
|
+
export declare function formatSummary(data: SummaryAnalytics): string;
|
|
180
|
+
/**
|
|
181
|
+
* Format reflections as compact markdown (top N per category).
|
|
182
|
+
*/
|
|
183
|
+
export declare function formatReflections(data: {
|
|
184
|
+
period: {
|
|
185
|
+
start: string;
|
|
186
|
+
end: string;
|
|
187
|
+
days: number;
|
|
188
|
+
};
|
|
189
|
+
total_sessions_scanned: number;
|
|
190
|
+
sessions_with_reflections: number;
|
|
191
|
+
what_broke: ReflectionCategory;
|
|
192
|
+
what_worked: ReflectionCategory;
|
|
193
|
+
wrong_assumptions: ReflectionCategory;
|
|
194
|
+
do_differently: ReflectionCategory;
|
|
195
|
+
}, topN?: number): string;
|
|
196
|
+
/**
|
|
197
|
+
* Format blindspots as compact markdown.
|
|
198
|
+
*/
|
|
199
|
+
export declare function formatBlindspots(data: BlindspotsData): string;
|
|
200
|
+
export {};
|
|
201
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/services/analytics.ts"],"names":[],"mappings":"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"}
|