gitmem-mcp 1.0.2 → 1.0.4
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 +20 -6
- package/README.md +30 -9
- package/dist/commands/check.d.ts +1 -1
- package/dist/commands/check.js +4 -3
- package/dist/diagnostics/anonymizer.d.ts +1 -1
- package/dist/diagnostics/anonymizer.js +1 -1
- package/dist/diagnostics/channels.d.ts +1 -1
- package/dist/diagnostics/channels.js +1 -1
- package/dist/diagnostics/collector.d.ts +1 -1
- package/dist/diagnostics/collector.js +1 -1
- package/dist/diagnostics/index.d.ts +1 -1
- package/dist/diagnostics/index.js +1 -1
- package/dist/hooks/quick-retrieve.js +2 -1
- package/dist/index.js +0 -0
- package/dist/schemas/active-sessions.d.ts +9 -9
- package/dist/schemas/active-sessions.js +1 -1
- package/dist/schemas/common.d.ts +2 -5
- package/dist/schemas/common.js +13 -7
- package/dist/schemas/create-learning.d.ts +4 -4
- package/dist/schemas/create-learning.js +1 -1
- package/dist/schemas/session-close.d.ts +5 -8
- package/dist/schemas/session-close.js +7 -3
- package/dist/schemas/session-start.d.ts +4 -4
- package/dist/schemas/session-start.js +1 -1
- package/dist/schemas/thread.d.ts +1 -1
- package/dist/schemas/thread.js +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.js +21 -10
- package/dist/services/active-sessions.js +3 -2
- package/dist/services/agent-briefing.d.ts +12 -0
- package/dist/services/agent-briefing.js +81 -0
- package/dist/services/agent-detection.d.ts +2 -1
- package/dist/services/agent-detection.js +23 -14
- package/dist/services/analytics.d.ts +1 -1
- package/dist/services/analytics.js +3 -3
- package/dist/services/behavioral-decay.js +2 -2
- package/dist/services/cache.d.ts +1 -1
- package/dist/services/cache.js +1 -1
- package/dist/services/compliance-validator.d.ts +1 -1
- package/dist/services/compliance-validator.js +5 -5
- package/dist/services/config.d.ts +1 -1
- package/dist/services/config.js +1 -1
- package/dist/services/file-lock.js +12 -0
- package/dist/services/gitmem-dir.d.ts +17 -4
- package/dist/services/gitmem-dir.js +43 -9
- package/dist/services/local-file-storage.d.ts +1 -1
- package/dist/services/local-file-storage.js +16 -10
- package/dist/services/local-vector-search.d.ts +1 -1
- package/dist/services/local-vector-search.js +2 -2
- package/dist/services/metrics.d.ts +6 -6
- package/dist/services/metrics.js +8 -8
- package/dist/services/session-state.d.ts +7 -7
- package/dist/services/session-state.js +19 -7
- package/dist/services/startup.d.ts +1 -1
- package/dist/services/startup.js +3 -2
- package/dist/services/supabase-client.d.ts +17 -6
- package/dist/services/supabase-client.js +44 -8
- package/dist/services/thread-manager.d.ts +1 -1
- package/dist/services/thread-manager.js +5 -5
- package/dist/services/thread-supabase.d.ts +1 -1
- package/dist/services/thread-supabase.js +2 -2
- package/dist/services/tier.d.ts +2 -0
- package/dist/services/tier.js +4 -0
- package/dist/services/transcript-chunker.d.ts +1 -1
- package/dist/services/transcript-chunker.js +1 -1
- package/dist/services/triple-writer.d.ts +4 -4
- package/dist/services/triple-writer.js +11 -20
- package/dist/services/variant-assignment.d.ts +6 -6
- package/dist/services/variant-assignment.js +9 -8
- package/dist/tools/analyze.d.ts +2 -2
- package/dist/tools/analyze.js +2 -2
- package/dist/tools/archive-learning.js +36 -22
- package/dist/tools/confirm-scars.js +4 -0
- package/dist/tools/create-decision.d.ts +1 -1
- package/dist/tools/create-decision.js +2 -2
- package/dist/tools/create-learning.d.ts +1 -1
- package/dist/tools/create-learning.js +4 -4
- package/dist/tools/create-linear-issue.d.ts +18 -0
- package/dist/tools/create-linear-issue.js +197 -0
- package/dist/tools/create-thread.d.ts +1 -1
- package/dist/tools/create-thread.js +2 -2
- package/dist/tools/definitions.d.ts +280 -58
- package/dist/tools/definitions.js +127 -87
- package/dist/tools/get-transcript.d.ts +1 -1
- package/dist/tools/get-transcript.js +1 -1
- package/dist/tools/graph-traverse.d.ts +1 -1
- package/dist/tools/graph-traverse.js +20 -17
- package/dist/tools/list-threads.d.ts +2 -2
- package/dist/tools/list-threads.js +4 -4
- package/dist/tools/log.d.ts +1 -1
- package/dist/tools/log.js +1 -1
- package/dist/tools/prepare-context.d.ts +1 -1
- package/dist/tools/prepare-context.js +2 -2
- package/dist/tools/recall.d.ts +5 -4
- package/dist/tools/recall.js +37 -28
- package/dist/tools/record-scar-usage-batch.js +2 -2
- package/dist/tools/record-scar-usage.d.ts +1 -1
- package/dist/tools/record-scar-usage.js +3 -3
- package/dist/tools/resolve-thread.d.ts +2 -2
- package/dist/tools/resolve-thread.js +3 -3
- package/dist/tools/save-transcript.d.ts +1 -1
- package/dist/tools/save-transcript.js +1 -1
- package/dist/tools/search.d.ts +1 -1
- package/dist/tools/search.js +1 -1
- package/dist/tools/session-close.d.ts +1 -1
- package/dist/tools/session-close.js +58 -57
- package/dist/tools/session-start.d.ts +5 -5
- package/dist/tools/session-start.js +63 -61
- package/dist/types/index.d.ts +17 -13
- package/hooks/.claude-plugin/plugin.json +1 -1
- package/hooks/scripts/post-tool-use.sh +1 -1
- package/hooks/scripts/recall-check.sh +1 -1
- package/hooks/scripts/session-close-check.sh +1 -1
- package/hooks/scripts/session-start.sh +1 -1
- package/package.json +6 -3
- package/schema/starter-scars.json +3 -153
- package/dist/commands/check.d.ts.map +0 -1
- package/dist/commands/check.js.map +0 -1
- package/dist/constants/closing-questions.d.ts.map +0 -1
- package/dist/constants/closing-questions.js.map +0 -1
- package/dist/diagnostics/anonymizer.d.ts.map +0 -1
- package/dist/diagnostics/anonymizer.js.map +0 -1
- package/dist/diagnostics/channels.d.ts.map +0 -1
- package/dist/diagnostics/channels.js.map +0 -1
- package/dist/diagnostics/collector.d.ts.map +0 -1
- package/dist/diagnostics/collector.js.map +0 -1
- package/dist/diagnostics/index.d.ts.map +0 -1
- package/dist/diagnostics/index.js.map +0 -1
- package/dist/hooks/format-utils.d.ts.map +0 -1
- package/dist/hooks/format-utils.js.map +0 -1
- package/dist/hooks/quick-retrieve.d.ts.map +0 -1
- package/dist/hooks/quick-retrieve.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/schemas/absorb-observations.d.ts.map +0 -1
- package/dist/schemas/absorb-observations.js.map +0 -1
- package/dist/schemas/active-sessions.d.ts.map +0 -1
- package/dist/schemas/active-sessions.js.map +0 -1
- package/dist/schemas/analyze.d.ts.map +0 -1
- package/dist/schemas/analyze.js.map +0 -1
- package/dist/schemas/common.d.ts.map +0 -1
- package/dist/schemas/common.js.map +0 -1
- package/dist/schemas/create-decision.d.ts.map +0 -1
- package/dist/schemas/create-decision.js.map +0 -1
- package/dist/schemas/create-learning.d.ts.map +0 -1
- package/dist/schemas/create-learning.js.map +0 -1
- package/dist/schemas/get-transcript.d.ts.map +0 -1
- package/dist/schemas/get-transcript.js.map +0 -1
- package/dist/schemas/index.d.ts.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/schemas/log.d.ts.map +0 -1
- package/dist/schemas/log.js.map +0 -1
- package/dist/schemas/prepare-context.d.ts.map +0 -1
- package/dist/schemas/prepare-context.js.map +0 -1
- package/dist/schemas/recall.d.ts.map +0 -1
- package/dist/schemas/recall.js.map +0 -1
- package/dist/schemas/record-scar-usage-batch.d.ts.map +0 -1
- package/dist/schemas/record-scar-usage-batch.js.map +0 -1
- package/dist/schemas/record-scar-usage.d.ts.map +0 -1
- package/dist/schemas/record-scar-usage.js.map +0 -1
- package/dist/schemas/registry.d.ts.map +0 -1
- package/dist/schemas/registry.js.map +0 -1
- package/dist/schemas/save-transcript.d.ts.map +0 -1
- package/dist/schemas/save-transcript.js.map +0 -1
- package/dist/schemas/search-transcripts.d.ts.map +0 -1
- package/dist/schemas/search-transcripts.js.map +0 -1
- package/dist/schemas/search.d.ts.map +0 -1
- package/dist/schemas/search.js.map +0 -1
- package/dist/schemas/session-close.d.ts.map +0 -1
- package/dist/schemas/session-close.js.map +0 -1
- package/dist/schemas/session-start.d.ts.map +0 -1
- package/dist/schemas/session-start.js.map +0 -1
- package/dist/schemas/thread.d.ts.map +0 -1
- package/dist/schemas/thread.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/services/active-sessions.d.ts.map +0 -1
- package/dist/services/active-sessions.js.map +0 -1
- package/dist/services/agent-detection.d.ts.map +0 -1
- package/dist/services/agent-detection.js.map +0 -1
- package/dist/services/analytics.d.ts.map +0 -1
- package/dist/services/analytics.js.map +0 -1
- package/dist/services/behavioral-decay.d.ts.map +0 -1
- package/dist/services/behavioral-decay.js.map +0 -1
- package/dist/services/bm25.d.ts.map +0 -1
- package/dist/services/bm25.js.map +0 -1
- package/dist/services/cache.d.ts.map +0 -1
- package/dist/services/cache.js.map +0 -1
- package/dist/services/cache.test.d.ts +0 -8
- package/dist/services/cache.test.d.ts.map +0 -1
- package/dist/services/cache.test.js +0 -267
- package/dist/services/cache.test.js.map +0 -1
- package/dist/services/compliance-validator.d.ts.map +0 -1
- package/dist/services/compliance-validator.js.map +0 -1
- package/dist/services/config.d.ts.map +0 -1
- package/dist/services/config.js.map +0 -1
- package/dist/services/display-protocol.d.ts.map +0 -1
- package/dist/services/display-protocol.js.map +0 -1
- package/dist/services/effect-tracker.d.ts.map +0 -1
- package/dist/services/effect-tracker.js.map +0 -1
- package/dist/services/embedding.d.ts.map +0 -1
- package/dist/services/embedding.js.map +0 -1
- package/dist/services/file-lock.d.ts.map +0 -1
- package/dist/services/file-lock.js.map +0 -1
- package/dist/services/gitmem-dir.d.ts.map +0 -1
- package/dist/services/gitmem-dir.js.map +0 -1
- package/dist/services/local-file-storage.d.ts.map +0 -1
- package/dist/services/local-file-storage.js.map +0 -1
- package/dist/services/local-vector-search.d.ts.map +0 -1
- package/dist/services/local-vector-search.js.map +0 -1
- package/dist/services/metrics.d.ts.map +0 -1
- package/dist/services/metrics.js.map +0 -1
- package/dist/services/session-state.d.ts.map +0 -1
- package/dist/services/session-state.js.map +0 -1
- package/dist/services/startup.d.ts.map +0 -1
- package/dist/services/startup.js.map +0 -1
- package/dist/services/storage.d.ts.map +0 -1
- package/dist/services/storage.js.map +0 -1
- package/dist/services/supabase-client.d.ts.map +0 -1
- package/dist/services/supabase-client.js.map +0 -1
- package/dist/services/thread-dedup.d.ts.map +0 -1
- package/dist/services/thread-dedup.js.map +0 -1
- package/dist/services/thread-manager.d.ts.map +0 -1
- package/dist/services/thread-manager.js.map +0 -1
- package/dist/services/thread-suggestions.d.ts.map +0 -1
- package/dist/services/thread-suggestions.js.map +0 -1
- package/dist/services/thread-supabase.d.ts.map +0 -1
- package/dist/services/thread-supabase.js.map +0 -1
- package/dist/services/thread-vitality.d.ts.map +0 -1
- package/dist/services/thread-vitality.js.map +0 -1
- package/dist/services/tier.d.ts.map +0 -1
- package/dist/services/tier.js.map +0 -1
- package/dist/services/timezone.d.ts.map +0 -1
- package/dist/services/timezone.js.map +0 -1
- package/dist/services/transcript-chunker.d.ts.map +0 -1
- package/dist/services/transcript-chunker.js.map +0 -1
- package/dist/services/triple-writer.d.ts.map +0 -1
- package/dist/services/triple-writer.js.map +0 -1
- package/dist/services/variant-assignment.d.ts.map +0 -1
- package/dist/services/variant-assignment.js.map +0 -1
- package/dist/services/variant-generation.d.ts.map +0 -1
- package/dist/services/variant-generation.js.map +0 -1
- package/dist/tools/absorb-observations.d.ts.map +0 -1
- package/dist/tools/absorb-observations.js.map +0 -1
- package/dist/tools/analyze.d.ts.map +0 -1
- package/dist/tools/analyze.js.map +0 -1
- package/dist/tools/archive-learning.d.ts.map +0 -1
- package/dist/tools/archive-learning.js.map +0 -1
- package/dist/tools/cleanup-threads.d.ts.map +0 -1
- package/dist/tools/cleanup-threads.js.map +0 -1
- package/dist/tools/confirm-scars.d.ts.map +0 -1
- package/dist/tools/confirm-scars.js.map +0 -1
- package/dist/tools/create-decision.d.ts.map +0 -1
- package/dist/tools/create-decision.js.map +0 -1
- package/dist/tools/create-learning.d.ts.map +0 -1
- package/dist/tools/create-learning.js.map +0 -1
- package/dist/tools/create-thread.d.ts.map +0 -1
- package/dist/tools/create-thread.js.map +0 -1
- package/dist/tools/definitions.d.ts.map +0 -1
- package/dist/tools/definitions.js.map +0 -1
- package/dist/tools/dismiss-suggestion.d.ts.map +0 -1
- package/dist/tools/dismiss-suggestion.js.map +0 -1
- package/dist/tools/get-transcript.d.ts.map +0 -1
- package/dist/tools/get-transcript.js.map +0 -1
- package/dist/tools/graph-traverse.d.ts.map +0 -1
- package/dist/tools/graph-traverse.js.map +0 -1
- package/dist/tools/list-threads.d.ts.map +0 -1
- package/dist/tools/list-threads.js.map +0 -1
- package/dist/tools/log.d.ts.map +0 -1
- package/dist/tools/log.js.map +0 -1
- package/dist/tools/prepare-context.d.ts.map +0 -1
- package/dist/tools/prepare-context.js.map +0 -1
- package/dist/tools/promote-suggestion.d.ts.map +0 -1
- package/dist/tools/promote-suggestion.js.map +0 -1
- package/dist/tools/recall.d.ts.map +0 -1
- package/dist/tools/recall.js.map +0 -1
- package/dist/tools/recall.test.d.ts +0 -5
- package/dist/tools/recall.test.d.ts.map +0 -1
- package/dist/tools/recall.test.js +0 -155
- package/dist/tools/recall.test.js.map +0 -1
- package/dist/tools/record-scar-usage-batch.d.ts.map +0 -1
- package/dist/tools/record-scar-usage-batch.js.map +0 -1
- package/dist/tools/record-scar-usage.d.ts.map +0 -1
- package/dist/tools/record-scar-usage.js.map +0 -1
- package/dist/tools/resolve-thread.d.ts.map +0 -1
- package/dist/tools/resolve-thread.js.map +0 -1
- package/dist/tools/save-transcript.d.ts.map +0 -1
- package/dist/tools/save-transcript.js.map +0 -1
- package/dist/tools/search-transcripts.d.ts.map +0 -1
- package/dist/tools/search-transcripts.js.map +0 -1
- package/dist/tools/search.d.ts.map +0 -1
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/session-close.d.ts.map +0 -1
- package/dist/tools/session-close.js.map +0 -1
- package/dist/tools/session-start.d.ts.map +0 -1
- package/dist/tools/session-start.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/hooks/tests/test-hooks.sh +0 -577
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
* Local File Storage — Free Tier Backend
|
|
3
3
|
*
|
|
4
4
|
* Stores scars, sessions, decisions, and scar usage as JSON files
|
|
5
|
-
* in the .gitmem/ directory
|
|
5
|
+
* in the .gitmem/ directory (defaults to ~/.gitmem, overridable via GITMEM_DIR).
|
|
6
6
|
*
|
|
7
7
|
* Provides keyword-based search (no embeddings needed).
|
|
8
8
|
*/
|
|
9
9
|
import * as fs from "fs";
|
|
10
10
|
import * as path from "path";
|
|
11
11
|
import { bm25Search } from "./bm25.js";
|
|
12
|
+
import { getGitmemDir } from "./gitmem-dir.js";
|
|
12
13
|
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
|
|
13
14
|
const WARN_FILE_SIZE = 1 * 1024 * 1024; // 1MB
|
|
14
15
|
export class LocalFileStorage {
|
|
15
16
|
basePath;
|
|
16
17
|
constructor(basePath) {
|
|
17
|
-
this.basePath = basePath ||
|
|
18
|
+
this.basePath = basePath || getGitmemDir();
|
|
18
19
|
this.ensureDir();
|
|
19
20
|
}
|
|
20
21
|
ensureDir() {
|
|
@@ -137,21 +138,26 @@ export class LocalFileStorage {
|
|
|
137
138
|
const results = bm25Search(query, docs, k);
|
|
138
139
|
// Map back to RelevantScar
|
|
139
140
|
const byId = new Map(learnings.map((l) => [String(l.id), l]));
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
const mapped = [];
|
|
142
|
+
for (const r of results) {
|
|
142
143
|
const l = byId.get(r.id);
|
|
143
144
|
if (!l)
|
|
144
|
-
|
|
145
|
-
|
|
145
|
+
continue;
|
|
146
|
+
// Deprioritize starter scars (0.7x multiplier)
|
|
147
|
+
const isStarter = !!l.is_starter;
|
|
148
|
+
const adjustedSimilarity = isStarter ? r.similarity * 0.7 : r.similarity;
|
|
149
|
+
mapped.push({
|
|
146
150
|
id: r.id,
|
|
147
151
|
title: String(l.title),
|
|
148
152
|
description: String(l.description),
|
|
149
153
|
severity: String(l.severity || "medium"),
|
|
150
154
|
counter_arguments: l.counter_arguments || [],
|
|
151
|
-
similarity:
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
similarity: adjustedSimilarity,
|
|
156
|
+
is_starter: isStarter || undefined,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// Re-sort after starter penalty (earned scars float up)
|
|
160
|
+
return mapped.sort((a, b) => b.similarity - a.similarity);
|
|
155
161
|
}
|
|
156
162
|
/**
|
|
157
163
|
* Get the count of learnings stored locally
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - Deterministic results (same model + same data = same results)
|
|
12
12
|
* - Per-container consistency (each loads same data)
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* Cache consistency
|
|
15
15
|
*/
|
|
16
16
|
import type { Project, RelevantScar } from "../types/index.js";
|
|
17
17
|
interface ScarRecord {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* - Deterministic results (same model + same data = same results)
|
|
12
12
|
* - Per-container consistency (each loads same data)
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* Cache consistency
|
|
15
15
|
*/
|
|
16
16
|
import { embed as generateEmbedding, getEmbeddingDim, isEmbeddingAvailable } from "./embedding.js";
|
|
17
17
|
// Embedding dimension — read from provider config at runtime
|
|
@@ -184,7 +184,7 @@ export class LocalVectorSearch {
|
|
|
184
184
|
severity: scar.severity || "medium",
|
|
185
185
|
counter_arguments: scar.counter_arguments || [],
|
|
186
186
|
similarity: Math.round(similarity * 1000) / 1000, // 3 decimal places
|
|
187
|
-
//
|
|
187
|
+
// Include enriched fields for LLM-cooperative enforcement
|
|
188
188
|
why_this_matters: scar.why_this_matters,
|
|
189
189
|
action_protocol: scar.action_protocol,
|
|
190
190
|
self_check_criteria: scar.self_check_criteria,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* GitMem Performance Metrics Service
|
|
3
3
|
*
|
|
4
4
|
* Tracks latency, result counts, and relevance signals for all GitMem tools.
|
|
5
|
-
*
|
|
5
|
+
* Instrumentation layer for performance tracking.
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
8
|
* Tool names that can be tracked
|
|
@@ -15,7 +15,7 @@ export type PhaseTag = "session_start" | "session_refresh" | "session_close" | "
|
|
|
15
15
|
/**
|
|
16
16
|
* Agent identities
|
|
17
17
|
*/
|
|
18
|
-
export type AgentIdentity = "
|
|
18
|
+
export type AgentIdentity = "cli" | "desktop" | "autonomous" | "local" | "cloud";
|
|
19
19
|
/**
|
|
20
20
|
* Metrics data for a query
|
|
21
21
|
*/
|
|
@@ -36,7 +36,7 @@ export interface QueryMetrics {
|
|
|
36
36
|
metadata?: Record<string, unknown>;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* Performance targets
|
|
39
|
+
* Performance targets
|
|
40
40
|
*/
|
|
41
41
|
export declare const PERFORMANCE_TARGETS: Record<ToolName, number>;
|
|
42
42
|
/**
|
|
@@ -58,16 +58,16 @@ export declare class Timer {
|
|
|
58
58
|
export declare function recordMetrics(metrics: QueryMetrics): Promise<void>;
|
|
59
59
|
/**
|
|
60
60
|
* Re-export performance types from types/index.ts
|
|
61
|
-
*
|
|
61
|
+
* Enhanced instrumentation for test harness validation
|
|
62
62
|
*/
|
|
63
63
|
export type { PerformanceData, PerformanceBreakdown, ComponentPerformance, DataSource, CacheStatus, } from "../types/index.js";
|
|
64
64
|
import type { PerformanceData, PerformanceBreakdown, ComponentPerformance, DataSource, CacheStatus } from "../types/index.js";
|
|
65
65
|
/**
|
|
66
|
-
* Build component performance data
|
|
66
|
+
* Build component performance data
|
|
67
67
|
*/
|
|
68
68
|
export declare function buildComponentPerformance(latencyMs: number, source: DataSource, networkCall: boolean, cacheStatus?: CacheStatus): ComponentPerformance;
|
|
69
69
|
/**
|
|
70
|
-
* Count network calls from breakdown
|
|
70
|
+
* Count network calls from breakdown
|
|
71
71
|
*/
|
|
72
72
|
export declare function countNetworkCalls(breakdown?: PerformanceBreakdown): number;
|
|
73
73
|
export declare function buildPerformanceData(toolName: ToolName, latencyMs: number, resultCount: number, options?: {
|
package/dist/services/metrics.js
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
* GitMem Performance Metrics Service
|
|
3
3
|
*
|
|
4
4
|
* Tracks latency, result counts, and relevance signals for all GitMem tools.
|
|
5
|
-
*
|
|
5
|
+
* Instrumentation layer for performance tracking.
|
|
6
6
|
*/
|
|
7
7
|
import { v4 as uuidv4 } from "uuid";
|
|
8
8
|
import * as supabase from "./supabase-client.js";
|
|
9
9
|
import { getEffectTracker } from "./effect-tracker.js";
|
|
10
10
|
import { hasSupabase } from "./tier.js";
|
|
11
11
|
/**
|
|
12
|
-
* Performance targets
|
|
12
|
+
* Performance targets
|
|
13
13
|
*/
|
|
14
14
|
export const PERFORMANCE_TARGETS = {
|
|
15
15
|
recall: 2000,
|
|
16
16
|
search: 500,
|
|
17
17
|
log: 500,
|
|
18
|
-
session_start: 750, //
|
|
19
|
-
session_refresh: 750, //
|
|
20
|
-
session_close: 1500, //
|
|
18
|
+
session_start: 750, // Lean start (was 1500)
|
|
19
|
+
session_refresh: 750, // Lean refresh (was 1500)
|
|
20
|
+
session_close: 1500, // Tightened (was 3000)
|
|
21
21
|
create_learning: 3000,
|
|
22
22
|
create_decision: 3000,
|
|
23
23
|
record_scar_usage: 1000,
|
|
@@ -84,7 +84,7 @@ export async function recordMetrics(metrics) {
|
|
|
84
84
|
await tracker.track("metrics", metrics.tool_name, () => supabase.directUpsert("gitmem_query_metrics", record));
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
-
* Build component performance data
|
|
87
|
+
* Build component performance data
|
|
88
88
|
*/
|
|
89
89
|
export function buildComponentPerformance(latencyMs, source, networkCall, cacheStatus = networkCall ? "miss" : "hit") {
|
|
90
90
|
return {
|
|
@@ -95,7 +95,7 @@ export function buildComponentPerformance(latencyMs, source, networkCall, cacheS
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
* Count network calls from breakdown
|
|
98
|
+
* Count network calls from breakdown
|
|
99
99
|
*/
|
|
100
100
|
export function countNetworkCalls(breakdown) {
|
|
101
101
|
if (!breakdown)
|
|
@@ -136,7 +136,7 @@ export function buildPerformanceData(toolName, latencyMs, resultCount, options)
|
|
|
136
136
|
cache_hit: options?.cache_hit ?? fullyLocal,
|
|
137
137
|
cache_age_ms: options?.cache_age_ms,
|
|
138
138
|
search_mode: options?.search_mode,
|
|
139
|
-
//
|
|
139
|
+
// Detailed instrumentation for test harness
|
|
140
140
|
total_latency_ms: latencyMs,
|
|
141
141
|
network_calls_made: networkCallsMade,
|
|
142
142
|
fully_local: fullyLocal,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session State Management
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Track current session context for auto-injecting into recall calls
|
|
4
|
+
* Track surfaced scars for auto-bridging Q6 answers to scar_usage records
|
|
5
5
|
*
|
|
6
6
|
* Maintains in-memory state of the current active session including:
|
|
7
7
|
* - session_id from session_start
|
|
@@ -54,12 +54,12 @@ export declare function getProject(): string | null;
|
|
|
54
54
|
*/
|
|
55
55
|
export declare function hasActiveIssue(): boolean;
|
|
56
56
|
/**
|
|
57
|
-
*
|
|
57
|
+
* Add surfaced scars to tracking (deduplicates by scar_id)
|
|
58
58
|
* Called by session_start and recall when scars are surfaced.
|
|
59
59
|
*/
|
|
60
60
|
export declare function addSurfacedScars(scars: SurfacedScar[]): void;
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
62
|
+
* Get all surfaced scars for the current session
|
|
63
63
|
*/
|
|
64
64
|
export declare function getSurfacedScars(): SurfacedScar[];
|
|
65
65
|
/**
|
|
@@ -105,15 +105,15 @@ export interface SessionActivity {
|
|
|
105
105
|
}
|
|
106
106
|
export declare function getSessionActivity(): SessionActivity | null;
|
|
107
107
|
/**
|
|
108
|
-
*
|
|
108
|
+
* : Set threads for the current session
|
|
109
109
|
*/
|
|
110
110
|
export declare function setThreads(threads: ThreadObject[]): void;
|
|
111
111
|
/**
|
|
112
|
-
*
|
|
112
|
+
* : Get threads for the current session
|
|
113
113
|
*/
|
|
114
114
|
export declare function getThreads(): ThreadObject[];
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
116
|
+
* : Resolve a thread in session state by ID.
|
|
117
117
|
* Returns the resolved thread or null if not found.
|
|
118
118
|
*/
|
|
119
119
|
export declare function resolveThreadInState(threadId: string, resolutionNote?: string): ThreadObject | null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Session State Management
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Track current session context for auto-injecting into recall calls
|
|
4
|
+
* Track surfaced scars for auto-bridging Q6 answers to scar_usage records
|
|
5
5
|
*
|
|
6
6
|
* Maintains in-memory state of the current active session including:
|
|
7
7
|
* - session_id from session_start
|
|
@@ -59,7 +59,7 @@ export function hasActiveIssue() {
|
|
|
59
59
|
return !!(currentSession?.linearIssue);
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
62
|
+
* Add surfaced scars to tracking (deduplicates by scar_id)
|
|
63
63
|
* Called by session_start and recall when scars are surfaced.
|
|
64
64
|
*/
|
|
65
65
|
export function addSurfacedScars(scars) {
|
|
@@ -76,7 +76,7 @@ export function addSurfacedScars(scars) {
|
|
|
76
76
|
console.error(`[session-state] Surfaced scars tracked: ${currentSession.surfacedScars.length} total`);
|
|
77
77
|
}
|
|
78
78
|
/**
|
|
79
|
-
*
|
|
79
|
+
* Get all surfaced scars for the current session
|
|
80
80
|
*/
|
|
81
81
|
export function getSurfacedScars() {
|
|
82
82
|
return currentSession?.surfacedScars || [];
|
|
@@ -121,6 +121,9 @@ export function hasUnconfirmedScars() {
|
|
|
121
121
|
const confirmedIds = new Set(currentSession.confirmations.map(c => c.scar_id));
|
|
122
122
|
return recallScars.some(s => !confirmedIds.has(s.scar_id));
|
|
123
123
|
}
|
|
124
|
+
// Security: cap unbounded arrays to prevent memory exhaustion in long sessions
|
|
125
|
+
const MAX_OBSERVATIONS = 500;
|
|
126
|
+
const MAX_CHILDREN = 100;
|
|
124
127
|
/**
|
|
125
128
|
* v2 Phase 2: Add observations from sub-agents/teammates
|
|
126
129
|
*/
|
|
@@ -134,6 +137,10 @@ export function addObservations(newObs) {
|
|
|
134
137
|
absorbed_at: o.absorbed_at || new Date().toISOString(),
|
|
135
138
|
}));
|
|
136
139
|
currentSession.observations.push(...timestamped);
|
|
140
|
+
// Cap to prevent memory exhaustion — keep most recent
|
|
141
|
+
if (currentSession.observations.length > MAX_OBSERVATIONS) {
|
|
142
|
+
currentSession.observations = currentSession.observations.slice(-MAX_OBSERVATIONS);
|
|
143
|
+
}
|
|
137
144
|
console.error(`[session-state] Observations tracked: ${currentSession.observations.length} total`);
|
|
138
145
|
return timestamped.length;
|
|
139
146
|
}
|
|
@@ -151,6 +158,11 @@ export function addChild(child) {
|
|
|
151
158
|
console.warn("[session-state] Cannot add child: no active session");
|
|
152
159
|
return;
|
|
153
160
|
}
|
|
161
|
+
// Cap to prevent memory exhaustion — reject silently beyond limit
|
|
162
|
+
if (currentSession.children.length >= MAX_CHILDREN) {
|
|
163
|
+
console.warn(`[session-state] Children cap reached (${MAX_CHILDREN}), ignoring new child: ${child.role}`);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
154
166
|
currentSession.children.push(child);
|
|
155
167
|
console.error(`[session-state] Child registered: ${child.role} (${child.type}), total: ${currentSession.children.length}`);
|
|
156
168
|
}
|
|
@@ -173,7 +185,7 @@ export function getSessionActivity() {
|
|
|
173
185
|
};
|
|
174
186
|
}
|
|
175
187
|
/**
|
|
176
|
-
*
|
|
188
|
+
* : Set threads for the current session
|
|
177
189
|
*/
|
|
178
190
|
export function setThreads(threads) {
|
|
179
191
|
if (!currentSession) {
|
|
@@ -184,13 +196,13 @@ export function setThreads(threads) {
|
|
|
184
196
|
console.error(`[session-state] Threads set: ${threads.length} total`);
|
|
185
197
|
}
|
|
186
198
|
/**
|
|
187
|
-
*
|
|
199
|
+
* : Get threads for the current session
|
|
188
200
|
*/
|
|
189
201
|
export function getThreads() {
|
|
190
202
|
return currentSession?.threads || [];
|
|
191
203
|
}
|
|
192
204
|
/**
|
|
193
|
-
*
|
|
205
|
+
* : Resolve a thread in session state by ID.
|
|
194
206
|
* Returns the resolved thread or null if not found.
|
|
195
207
|
*/
|
|
196
208
|
export function resolveThreadInState(threadId, resolutionNote) {
|
package/dist/services/startup.js
CHANGED
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
* - 500-employees-at-8AM (no Supabase contention during session_start)
|
|
11
11
|
* - Cross-container consistency (same data = same results)
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
*
|
|
14
14
|
*/
|
|
15
15
|
import * as fs from "fs";
|
|
16
16
|
import * as path from "path";
|
|
17
17
|
import { isConfigured, loadScarsWithEmbeddings } from "./supabase-client.js";
|
|
18
|
+
import { getGitmemDir } from "./gitmem-dir.js";
|
|
18
19
|
import { initializeLocalSearch, reinitializeLocalSearch, isLocalSearchReady, getLocalVectorSearch, getCacheMetadata, setCacheTtl, } from "./local-vector-search.js";
|
|
19
20
|
import { getConfig, shouldUseLocalSearch } from "./config.js";
|
|
20
21
|
// Track startup state — unified cache, no per-project partitioning
|
|
@@ -32,7 +33,7 @@ let backgroundRefreshInterval = null;
|
|
|
32
33
|
*/
|
|
33
34
|
function persistScarsForHooks(scars) {
|
|
34
35
|
try {
|
|
35
|
-
const gitmemDir = path.join(
|
|
36
|
+
const gitmemDir = path.join(getGitmemDir(), "cache");
|
|
36
37
|
if (!fs.existsSync(gitmemDir)) {
|
|
37
38
|
fs.mkdirSync(gitmemDir, { recursive: true });
|
|
38
39
|
}
|
|
@@ -5,9 +5,20 @@
|
|
|
5
5
|
* agents/coda/src/services/supabase-mcp.js
|
|
6
6
|
*
|
|
7
7
|
* Uses JSON-RPC 2.0 protocol over HTTPS.
|
|
8
|
-
* Integrates with CacheService for performance
|
|
8
|
+
* Integrates with CacheService for performance.
|
|
9
9
|
*/
|
|
10
10
|
import type { Project, SupabaseListOptions, SupabaseSearchOptions } from "../types/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Build a safe PostgREST `in.(...)` filter from an array of UUIDs.
|
|
13
|
+
* Rejects any non-UUID values to prevent filter injection via comma-splitting.
|
|
14
|
+
*/
|
|
15
|
+
export declare function safeInFilter(ids: string[]): string;
|
|
16
|
+
/**
|
|
17
|
+
* Escape PostgREST special characters in a value used within filter expressions.
|
|
18
|
+
* Prevents injection via characters that have structural meaning in PostgREST syntax:
|
|
19
|
+
* parentheses (group operators), commas (value separators), dots (operator delimiters).
|
|
20
|
+
*/
|
|
21
|
+
export declare function escapePostgRESTValue(value: string): string;
|
|
11
22
|
/**
|
|
12
23
|
* Check if Supabase is configured
|
|
13
24
|
*/
|
|
@@ -54,7 +65,7 @@ export declare function directQueryAll<T = unknown>(table: string, options?: {
|
|
|
54
65
|
order?: string;
|
|
55
66
|
}, pageSize?: number, maxRows?: number): Promise<T[]>;
|
|
56
67
|
/**
|
|
57
|
-
* Knowledge triple from knowledge_triples table
|
|
68
|
+
* Knowledge triple from knowledge_triples table
|
|
58
69
|
*/
|
|
59
70
|
export interface KnowledgeTriple {
|
|
60
71
|
subject: string;
|
|
@@ -67,7 +78,7 @@ export interface KnowledgeTriple {
|
|
|
67
78
|
source_id: string;
|
|
68
79
|
}
|
|
69
80
|
/**
|
|
70
|
-
* Fetch related knowledge triples for a set of scar IDs
|
|
81
|
+
* Fetch related knowledge triples for a set of scar IDs
|
|
71
82
|
*
|
|
72
83
|
* Queries knowledge_triples table where source_id matches any of the provided scar IDs.
|
|
73
84
|
* Returns triples grouped by source_id for easy attachment to scars.
|
|
@@ -99,7 +110,7 @@ export declare function directPatch<T = unknown>(table: string, filters: Record<
|
|
|
99
110
|
* This bypasses ww-mcp because we need the embedding vectors for local search.
|
|
100
111
|
* Returns learnings (scars, patterns, wins, anti-patterns) with full embedding data.
|
|
101
112
|
*
|
|
102
|
-
* NOTE: Changed from "scars only" to "all learning types"
|
|
113
|
+
* NOTE: Changed from "scars only" to "all learning types"
|
|
103
114
|
*/
|
|
104
115
|
export declare function loadScarsWithEmbeddings<T = unknown>(project?: string, limit?: number): Promise<T[]>;
|
|
105
116
|
/**
|
|
@@ -107,7 +118,7 @@ export declare function loadScarsWithEmbeddings<T = unknown>(project?: string, l
|
|
|
107
118
|
*/
|
|
108
119
|
export declare function scarSearch<T = unknown>(query: string, matchCount?: number, project?: Project): Promise<T[]>;
|
|
109
120
|
/**
|
|
110
|
-
* Scar search with caching
|
|
121
|
+
* Scar search with caching
|
|
111
122
|
*
|
|
112
123
|
* Returns cached results if available, otherwise fetches and caches.
|
|
113
124
|
*/
|
|
@@ -117,7 +128,7 @@ export declare function cachedScarSearch<T = unknown>(query: string, matchCount?
|
|
|
117
128
|
cache_age_ms?: number;
|
|
118
129
|
}>;
|
|
119
130
|
/**
|
|
120
|
-
* List records with caching for decisions
|
|
131
|
+
* List records with caching for decisions
|
|
121
132
|
*/
|
|
122
133
|
export declare function cachedListDecisions<T = unknown>(project?: Project, limit?: number): Promise<{
|
|
123
134
|
data: T[];
|
|
@@ -5,9 +5,45 @@
|
|
|
5
5
|
* agents/coda/src/services/supabase-mcp.js
|
|
6
6
|
*
|
|
7
7
|
* Uses JSON-RPC 2.0 protocol over HTTPS.
|
|
8
|
-
* Integrates with CacheService for performance
|
|
8
|
+
* Integrates with CacheService for performance.
|
|
9
9
|
*/
|
|
10
10
|
import { getCache } from "./cache.js";
|
|
11
|
+
// --- PostgREST Input Sanitization ---
|
|
12
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
13
|
+
/**
|
|
14
|
+
* Validate that a value is a UUID. Used to prevent injection in `in.(...)` filters
|
|
15
|
+
* where array elements are joined with commas.
|
|
16
|
+
*/
|
|
17
|
+
function isValidUUID(value) {
|
|
18
|
+
return UUID_PATTERN.test(value);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build a safe PostgREST `in.(...)` filter from an array of UUIDs.
|
|
22
|
+
* Rejects any non-UUID values to prevent filter injection via comma-splitting.
|
|
23
|
+
*/
|
|
24
|
+
export function safeInFilter(ids) {
|
|
25
|
+
const valid = ids.filter(id => isValidUUID(id));
|
|
26
|
+
if (valid.length !== ids.length) {
|
|
27
|
+
console.warn(`[supabase-client] safeInFilter rejected ${ids.length - valid.length} non-UUID values`);
|
|
28
|
+
}
|
|
29
|
+
if (valid.length === 0)
|
|
30
|
+
return "in.()";
|
|
31
|
+
return `in.(${valid.join(",")})`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Escape PostgREST special characters in a value used within filter expressions.
|
|
35
|
+
* Prevents injection via characters that have structural meaning in PostgREST syntax:
|
|
36
|
+
* parentheses (group operators), commas (value separators), dots (operator delimiters).
|
|
37
|
+
*/
|
|
38
|
+
export function escapePostgRESTValue(value) {
|
|
39
|
+
// Reject null bytes
|
|
40
|
+
if (value.includes("\0")) {
|
|
41
|
+
throw new Error("PostgREST value must not contain null bytes");
|
|
42
|
+
}
|
|
43
|
+
// For ilike patterns, escape structural PostgREST chars that could break OR groups
|
|
44
|
+
// PostgREST uses ( ) , as structural delimiters in or=() expressions
|
|
45
|
+
return value.replace(/[(),]/g, "");
|
|
46
|
+
}
|
|
11
47
|
// Configuration from environment
|
|
12
48
|
const SUPABASE_URL = process.env.SUPABASE_URL || "";
|
|
13
49
|
const SUPABASE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_KEY || "";
|
|
@@ -228,7 +264,7 @@ export async function directQueryAll(table, options = {}, pageSize = 1000, maxRo
|
|
|
228
264
|
return allRows;
|
|
229
265
|
}
|
|
230
266
|
/**
|
|
231
|
-
* Fetch related knowledge triples for a set of scar IDs
|
|
267
|
+
* Fetch related knowledge triples for a set of scar IDs
|
|
232
268
|
*
|
|
233
269
|
* Queries knowledge_triples table where source_id matches any of the provided scar IDs.
|
|
234
270
|
* Returns triples grouped by source_id for easy attachment to scars.
|
|
@@ -242,7 +278,7 @@ export async function fetchRelatedTriples(scarIds) {
|
|
|
242
278
|
const triples = await directQuery("knowledge_triples", {
|
|
243
279
|
select: "subject,predicate,object,event_time,decay_weight,half_life_days,decay_floor,source_id",
|
|
244
280
|
filters: {
|
|
245
|
-
source_id:
|
|
281
|
+
source_id: safeInFilter(scarIds),
|
|
246
282
|
},
|
|
247
283
|
});
|
|
248
284
|
for (const triple of triples) {
|
|
@@ -283,7 +319,7 @@ export async function directUpsert(table, data) {
|
|
|
283
319
|
throw new Error(`Supabase upsert error: ${response.status} - ${text.slice(0, 200)}`);
|
|
284
320
|
}
|
|
285
321
|
const result = await response.json();
|
|
286
|
-
//
|
|
322
|
+
// Validate that write actually happened
|
|
287
323
|
// Supabase can return 200 OK with empty array [] when:
|
|
288
324
|
// - RLS policy blocks the write
|
|
289
325
|
// - Constraint violation handled gracefully
|
|
@@ -341,7 +377,7 @@ export async function directPatch(table, filters, data) {
|
|
|
341
377
|
* This bypasses ww-mcp because we need the embedding vectors for local search.
|
|
342
378
|
* Returns learnings (scars, patterns, wins, anti-patterns) with full embedding data.
|
|
343
379
|
*
|
|
344
|
-
* NOTE: Changed from "scars only" to "all learning types"
|
|
380
|
+
* NOTE: Changed from "scars only" to "all learning types"
|
|
345
381
|
*/
|
|
346
382
|
export async function loadScarsWithEmbeddings(project, limit = 500) {
|
|
347
383
|
console.error(`[supabase-direct] Loading learnings with embeddings${project ? ` for project: ${project}` : " (all projects)"}`);
|
|
@@ -384,7 +420,7 @@ export async function scarSearch(query, matchCount = 5, project) {
|
|
|
384
420
|
return result.results || [];
|
|
385
421
|
}
|
|
386
422
|
/**
|
|
387
|
-
* Scar search with caching
|
|
423
|
+
* Scar search with caching
|
|
388
424
|
*
|
|
389
425
|
* Returns cached results if available, otherwise fetches and caches.
|
|
390
426
|
*/
|
|
@@ -394,7 +430,7 @@ export async function cachedScarSearch(query, matchCount = 5, project = "default
|
|
|
394
430
|
return { results: data, cache_hit, cache_age_ms };
|
|
395
431
|
}
|
|
396
432
|
/**
|
|
397
|
-
* List records with caching for decisions
|
|
433
|
+
* List records with caching for decisions
|
|
398
434
|
*/
|
|
399
435
|
export async function cachedListDecisions(project = "default", limit = 5) {
|
|
400
436
|
const cache = getCache();
|
|
@@ -424,7 +460,7 @@ export async function cachedListWins(project = "default", limit = 8, columns) {
|
|
|
424
460
|
return { data, cache_hit, cache_age_ms };
|
|
425
461
|
}
|
|
426
462
|
// ============================================================================
|
|
427
|
-
// STORAGE API
|
|
463
|
+
// STORAGE API
|
|
428
464
|
// ============================================================================
|
|
429
465
|
const TRANSCRIPT_BUCKET = "session-transcripts";
|
|
430
466
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Thread Lifecycle Manager (
|
|
2
|
+
* Thread Lifecycle Manager ()
|
|
3
3
|
*
|
|
4
4
|
* Core logic for thread lifecycle management:
|
|
5
5
|
* - ID generation, migration from plain strings to ThreadObject
|
|
@@ -11,6 +11,7 @@ import * as fs from "fs";
|
|
|
11
11
|
import * as path from "path";
|
|
12
12
|
import * as crypto from "crypto";
|
|
13
13
|
import { normalizeText } from "./thread-dedup.js";
|
|
14
|
+
import { getGitmemDir } from "./gitmem-dir.js";
|
|
14
15
|
// ---------- ID Generation ----------
|
|
15
16
|
/**
|
|
16
17
|
* Generate a thread ID: "t-" + 8 hex chars
|
|
@@ -123,7 +124,7 @@ export function aggregateThreads(sessions, maxSessions = 5, maxAgeDays = 14) {
|
|
|
123
124
|
const rawThreads = session.open_threads || [];
|
|
124
125
|
const normalized = normalizeThreads(rawThreads, session.id);
|
|
125
126
|
for (const thread of normalized) {
|
|
126
|
-
// Skip PROJECT STATE threads
|
|
127
|
+
// Skip PROJECT STATE threads
|
|
127
128
|
if (thread.text.startsWith("PROJECT STATE:"))
|
|
128
129
|
continue;
|
|
129
130
|
// Deduplicate by both thread ID and normalized text content
|
|
@@ -184,8 +185,7 @@ export function resolveThread(threads, options) {
|
|
|
184
185
|
// ---------- Local File Persistence ----------
|
|
185
186
|
const THREADS_FILENAME = "threads.json";
|
|
186
187
|
function getThreadsFilePath() {
|
|
187
|
-
|
|
188
|
-
return path.join(gitmemDir, THREADS_FILENAME);
|
|
188
|
+
return path.join(getGitmemDir(), THREADS_FILENAME);
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
191
|
* Load threads from .gitmem/threads.json.
|
|
@@ -210,7 +210,7 @@ export function loadThreadsFile() {
|
|
|
210
210
|
* Save threads to .gitmem/threads.json.
|
|
211
211
|
*/
|
|
212
212
|
export function saveThreadsFile(threads) {
|
|
213
|
-
const gitmemDir =
|
|
213
|
+
const gitmemDir = getGitmemDir();
|
|
214
214
|
if (!fs.existsSync(gitmemDir)) {
|
|
215
215
|
fs.mkdirSync(gitmemDir, { recursive: true });
|
|
216
216
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Thread Supabase Service
|
|
2
|
+
* Thread Supabase Service
|
|
3
3
|
*
|
|
4
4
|
* Provides Supabase CRUD operations for the orchestra_threads table.
|
|
5
5
|
* Supabase is the source of truth; local .gitmem/threads.json is a cache.
|
|
@@ -318,7 +318,7 @@ export async function syncThreadsToSupabase(threads, project = "default", sessio
|
|
|
318
318
|
if (!hasSupabase() || !supabase.isConfigured() || threads.length === 0) {
|
|
319
319
|
return;
|
|
320
320
|
}
|
|
321
|
-
//
|
|
321
|
+
// Load existing open threads once upfront for text-based dedup.
|
|
322
322
|
// Prevents duplicate creation when closing ceremony generates new thread IDs
|
|
323
323
|
// for threads that already exist with the same (or similar) text.
|
|
324
324
|
let existingOpenThreads = [];
|
package/dist/services/tier.d.ts
CHANGED
|
@@ -49,4 +49,6 @@ export declare function getTablePrefix(): string;
|
|
|
49
49
|
* Get the fully-qualified table name for a base table name
|
|
50
50
|
*/
|
|
51
51
|
export declare function getTableName(baseName: string): string;
|
|
52
|
+
/** Whether all tool aliases (gitmem-*, gm-*) should be advertised (default: false) */
|
|
53
|
+
export declare function hasFullAliases(): boolean;
|
|
52
54
|
//# sourceMappingURL=tier.d.ts.map
|
package/dist/services/tier.js
CHANGED
|
@@ -106,4 +106,8 @@ export function getTablePrefix() {
|
|
|
106
106
|
export function getTableName(baseName) {
|
|
107
107
|
return `${getTablePrefix()}${baseName}`;
|
|
108
108
|
}
|
|
109
|
+
/** Whether all tool aliases (gitmem-*, gm-*) should be advertised (default: false) */
|
|
110
|
+
export function hasFullAliases() {
|
|
111
|
+
return process.env.GITMEM_FULL_ALIASES === "1" || process.env.GITMEM_FULL_ALIASES === "true";
|
|
112
|
+
}
|
|
109
113
|
//# sourceMappingURL=tier.js.map
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Parses JSONL session transcripts, chunks them intelligently,
|
|
5
5
|
* generates embeddings, and stores in orchestra_transcript_chunks.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
*/
|
|
9
9
|
// OpenRouter API configuration (same as local-vector-search)
|
|
10
10
|
const OPENROUTER_API_URL = "https://openrouter.ai/api/v1/embeddings";
|
|
@@ -29,10 +29,10 @@ interface TripleCandidate {
|
|
|
29
29
|
* Then maps to canonical short name if known.
|
|
30
30
|
*
|
|
31
31
|
* Examples:
|
|
32
|
-
* "
|
|
33
|
-
* "
|
|
34
|
-
* "
|
|
35
|
-
* "
|
|
32
|
+
* "Alice Smith" → "Alice" (if mapped)
|
|
33
|
+
* "Bob - Architectural pattern" → "Bob" (if mapped)
|
|
34
|
+
* "Alice: Prefers non-invasive instrumentation" → "Alice" (if mapped)
|
|
35
|
+
* "Unknown Developer - Process decision" → "Unknown Developer" (passthrough)
|
|
36
36
|
*/
|
|
37
37
|
export declare function normalizePersonaLabel(raw: string): string;
|
|
38
38
|
/**
|