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,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitMem Anonymizer
|
|
3
|
+
*
|
|
4
|
+
* Strips PII from diagnostic data before it's collected.
|
|
5
|
+
* Built-in to collector, not post-process.
|
|
6
|
+
*
|
|
7
|
+
* Anonymization rules:
|
|
8
|
+
* - Supabase URL → https://*.supabase.co
|
|
9
|
+
* - API keys → configured: true/false
|
|
10
|
+
* - IP addresses → stripped
|
|
11
|
+
* - Scar/session/decision content → counts only
|
|
12
|
+
* - Error messages → URLs/keys stripped via regex
|
|
13
|
+
* - Cache paths → normalized to ~/.gitmem/...
|
|
14
|
+
* - Hostnames → excluded
|
|
15
|
+
* - Platform/Node version → included
|
|
16
|
+
*
|
|
17
|
+
* Issue: OD-584
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Anonymize a Supabase URL
|
|
21
|
+
*/
|
|
22
|
+
export declare function anonymizeSupabaseUrl(url: string | undefined): string;
|
|
23
|
+
/**
|
|
24
|
+
* Check if an API key is configured (returns boolean, not the key)
|
|
25
|
+
*/
|
|
26
|
+
export declare function isApiKeyConfigured(key: string | undefined): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Anonymize a file path
|
|
29
|
+
*/
|
|
30
|
+
export declare function anonymizePath(filepath: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Anonymize an error message
|
|
33
|
+
*/
|
|
34
|
+
export declare function anonymizeError(error: Error | string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Anonymize arbitrary string content
|
|
37
|
+
*/
|
|
38
|
+
export declare function anonymizeString(content: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Anonymize a cache key (preserve structure, strip values)
|
|
41
|
+
*/
|
|
42
|
+
export declare function anonymizeCacheKey(key: string): string;
|
|
43
|
+
/**
|
|
44
|
+
* Safe environment info extraction
|
|
45
|
+
*/
|
|
46
|
+
export declare function getSafeEnvironmentInfo(): {
|
|
47
|
+
platform: string;
|
|
48
|
+
nodeVersion: string;
|
|
49
|
+
arch: string;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Anonymize tool call parameters
|
|
53
|
+
*/
|
|
54
|
+
export declare function anonymizeToolParams(params: Record<string, unknown> | undefined): Record<string, unknown>;
|
|
55
|
+
//# sourceMappingURL=anonymizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anonymizer.d.ts","sourceRoot":"","sources":["../../src/diagnostics/anonymizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAqCH;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAOpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoBtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAuB5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgBvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYrD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,CAMA;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkCxG"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitMem Anonymizer
|
|
3
|
+
*
|
|
4
|
+
* Strips PII from diagnostic data before it's collected.
|
|
5
|
+
* Built-in to collector, not post-process.
|
|
6
|
+
*
|
|
7
|
+
* Anonymization rules:
|
|
8
|
+
* - Supabase URL → https://*.supabase.co
|
|
9
|
+
* - API keys → configured: true/false
|
|
10
|
+
* - IP addresses → stripped
|
|
11
|
+
* - Scar/session/decision content → counts only
|
|
12
|
+
* - Error messages → URLs/keys stripped via regex
|
|
13
|
+
* - Cache paths → normalized to ~/.gitmem/...
|
|
14
|
+
* - Hostnames → excluded
|
|
15
|
+
* - Platform/Node version → included
|
|
16
|
+
*
|
|
17
|
+
* Issue: OD-584
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Regex patterns for sensitive data
|
|
21
|
+
*/
|
|
22
|
+
const PATTERNS = {
|
|
23
|
+
// API keys (common formats like sk_test_xxx, sk_live_xxx, sk-xxx)
|
|
24
|
+
API_KEY: /(?:sk|pk)[_-](?:test|live|or)?[_-]?[a-zA-Z0-9]{10,}/gi,
|
|
25
|
+
// Bearer tokens
|
|
26
|
+
BEARER_TOKEN: /Bearer\s+[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]*/gi,
|
|
27
|
+
// JWT tokens
|
|
28
|
+
JWT: /eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]*/g,
|
|
29
|
+
// Supabase URLs
|
|
30
|
+
SUPABASE_URL: /https?:\/\/[a-z0-9-]+\.supabase\.co/gi,
|
|
31
|
+
// Generic URLs with potential secrets
|
|
32
|
+
URL_WITH_PARAMS: /https?:\/\/[^\s"']+\?[^\s"']*/gi,
|
|
33
|
+
// IP addresses (IPv4)
|
|
34
|
+
IPV4: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
|
|
35
|
+
// IP addresses (IPv6)
|
|
36
|
+
IPV6: /\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b/g,
|
|
37
|
+
// Email addresses
|
|
38
|
+
EMAIL: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
39
|
+
// File paths (home directory)
|
|
40
|
+
HOME_PATH: /(?:\/Users\/[^\/\s]+|\/home\/[^\/\s]+|C:\\Users\\[^\\]+)/gi,
|
|
41
|
+
// UUIDs (may be session/user IDs)
|
|
42
|
+
UUID: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi,
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Anonymize a Supabase URL
|
|
46
|
+
*/
|
|
47
|
+
export function anonymizeSupabaseUrl(url) {
|
|
48
|
+
if (!url)
|
|
49
|
+
return "not_configured";
|
|
50
|
+
if (url.includes("supabase.co")) {
|
|
51
|
+
return "https://*.supabase.co";
|
|
52
|
+
}
|
|
53
|
+
// Local or custom URL
|
|
54
|
+
return "custom_url_configured";
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if an API key is configured (returns boolean, not the key)
|
|
58
|
+
*/
|
|
59
|
+
export function isApiKeyConfigured(key) {
|
|
60
|
+
return Boolean(key && key.length > 0);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Anonymize a file path
|
|
64
|
+
*/
|
|
65
|
+
export function anonymizePath(filepath) {
|
|
66
|
+
if (!filepath)
|
|
67
|
+
return "";
|
|
68
|
+
// Replace home directory variations
|
|
69
|
+
let result = filepath
|
|
70
|
+
.replace(/\/Users\/[^\/]+/g, "~")
|
|
71
|
+
.replace(/\/home\/[^\/]+/g, "~")
|
|
72
|
+
.replace(/C:\\Users\\[^\\]+/gi, "~");
|
|
73
|
+
// Normalize .gitmem paths
|
|
74
|
+
if (result.includes(".gitmem") || result.includes(".cache/gitmem")) {
|
|
75
|
+
const gitmemIndex = result.indexOf(".gitmem");
|
|
76
|
+
const cacheIndex = result.indexOf(".cache/gitmem");
|
|
77
|
+
const startIndex = gitmemIndex !== -1 ? gitmemIndex : cacheIndex;
|
|
78
|
+
if (startIndex !== -1) {
|
|
79
|
+
result = "~/" + result.slice(startIndex);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Anonymize an error message
|
|
86
|
+
*/
|
|
87
|
+
export function anonymizeError(error) {
|
|
88
|
+
let message = typeof error === "string" ? error : error.message;
|
|
89
|
+
// Strip API keys
|
|
90
|
+
message = message.replace(PATTERNS.API_KEY, "[API_KEY]");
|
|
91
|
+
message = message.replace(PATTERNS.BEARER_TOKEN, "Bearer [TOKEN]");
|
|
92
|
+
message = message.replace(PATTERNS.JWT, "[JWT]");
|
|
93
|
+
// Strip URLs with potential secrets
|
|
94
|
+
message = message.replace(PATTERNS.SUPABASE_URL, "https://*.supabase.co");
|
|
95
|
+
message = message.replace(PATTERNS.URL_WITH_PARAMS, "[URL_REDACTED]");
|
|
96
|
+
// Strip IP addresses
|
|
97
|
+
message = message.replace(PATTERNS.IPV4, "[IP]");
|
|
98
|
+
message = message.replace(PATTERNS.IPV6, "[IP]");
|
|
99
|
+
// Strip email addresses
|
|
100
|
+
message = message.replace(PATTERNS.EMAIL, "[EMAIL]");
|
|
101
|
+
// Strip home paths
|
|
102
|
+
message = message.replace(PATTERNS.HOME_PATH, "~");
|
|
103
|
+
return message;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Anonymize arbitrary string content
|
|
107
|
+
*/
|
|
108
|
+
export function anonymizeString(content) {
|
|
109
|
+
if (!content)
|
|
110
|
+
return "";
|
|
111
|
+
let result = content;
|
|
112
|
+
// Apply all anonymization patterns
|
|
113
|
+
result = result.replace(PATTERNS.API_KEY, "[API_KEY]");
|
|
114
|
+
result = result.replace(PATTERNS.BEARER_TOKEN, "Bearer [TOKEN]");
|
|
115
|
+
result = result.replace(PATTERNS.JWT, "[JWT]");
|
|
116
|
+
result = result.replace(PATTERNS.SUPABASE_URL, "https://*.supabase.co");
|
|
117
|
+
result = result.replace(PATTERNS.IPV4, "[IP]");
|
|
118
|
+
result = result.replace(PATTERNS.IPV6, "[IP]");
|
|
119
|
+
result = result.replace(PATTERNS.EMAIL, "[EMAIL]");
|
|
120
|
+
result = result.replace(PATTERNS.HOME_PATH, "~");
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Anonymize a cache key (preserve structure, strip values)
|
|
125
|
+
*/
|
|
126
|
+
export function anonymizeCacheKey(key) {
|
|
127
|
+
// Cache keys are like: scar_search:abc123:project:5 or decisions:myproject:10
|
|
128
|
+
// Keep the type, anonymize the middle parts, keep the last numeric part
|
|
129
|
+
const parts = key.split(":");
|
|
130
|
+
if (parts.length >= 3) {
|
|
131
|
+
// Keep first and last, hash the middle
|
|
132
|
+
return `${parts[0]}:[hash]:${parts.slice(2).join(":")}`;
|
|
133
|
+
}
|
|
134
|
+
else if (parts.length === 2) {
|
|
135
|
+
// Two parts like decisions:myproject - anonymize second
|
|
136
|
+
return `${parts[0]}:[hash]`;
|
|
137
|
+
}
|
|
138
|
+
return "[cache_key]";
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Safe environment info extraction
|
|
142
|
+
*/
|
|
143
|
+
export function getSafeEnvironmentInfo() {
|
|
144
|
+
return {
|
|
145
|
+
platform: process.platform,
|
|
146
|
+
nodeVersion: process.version,
|
|
147
|
+
arch: process.arch,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Anonymize tool call parameters
|
|
152
|
+
*/
|
|
153
|
+
export function anonymizeToolParams(params) {
|
|
154
|
+
if (!params)
|
|
155
|
+
return {};
|
|
156
|
+
const result = {};
|
|
157
|
+
for (const [key, value] of Object.entries(params)) {
|
|
158
|
+
// Skip content fields entirely
|
|
159
|
+
if (["description", "content", "message", "reflection", "rationale"].includes(key)) {
|
|
160
|
+
result[key] = "[content_redacted]";
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// Anonymize string values
|
|
164
|
+
if (typeof value === "string") {
|
|
165
|
+
// Keep short identifiers, redact longer content
|
|
166
|
+
if (value.length > 50) {
|
|
167
|
+
result[key] = `[string:${value.length}chars]`;
|
|
168
|
+
}
|
|
169
|
+
else if (PATTERNS.API_KEY.test(value) || PATTERNS.EMAIL.test(value)) {
|
|
170
|
+
result[key] = "[redacted]";
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
result[key] = value;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (typeof value === "number" || typeof value === "boolean") {
|
|
177
|
+
result[key] = value;
|
|
178
|
+
}
|
|
179
|
+
else if (Array.isArray(value)) {
|
|
180
|
+
result[key] = `[array:${value.length}items]`;
|
|
181
|
+
}
|
|
182
|
+
else if (typeof value === "object" && value !== null) {
|
|
183
|
+
result[key] = "[object]";
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
result[key] = "[unknown]";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=anonymizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anonymizer.js","sourceRoot":"","sources":["../../src/diagnostics/anonymizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitMem Diagnostics Channels
|
|
3
|
+
*
|
|
4
|
+
* Defines diagnostics_channel channels for zero-overhead instrumentation.
|
|
5
|
+
* When no subscriber is attached, publish() is essentially a no-op.
|
|
6
|
+
*
|
|
7
|
+
* Pattern reference: @ibm/telemetry-js
|
|
8
|
+
* Issue: OD-584
|
|
9
|
+
*/
|
|
10
|
+
import { channel, Channel } from "diagnostics_channel";
|
|
11
|
+
/**
|
|
12
|
+
* Channel names for GitMem diagnostics
|
|
13
|
+
*/
|
|
14
|
+
export declare const CHANNEL_NAMES: {
|
|
15
|
+
readonly TOOL_CALL: "gitmem:tool:call";
|
|
16
|
+
readonly CACHE_HIT: "gitmem:cache:hit";
|
|
17
|
+
readonly CACHE_MISS: "gitmem:cache:miss";
|
|
18
|
+
readonly DB_QUERY: "gitmem:db:query";
|
|
19
|
+
readonly EMBEDDING_CALL: "gitmem:embedding:call";
|
|
20
|
+
readonly ERROR: "gitmem:error";
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Tool call event payload
|
|
24
|
+
*/
|
|
25
|
+
export interface ToolCallEvent {
|
|
26
|
+
tool: string;
|
|
27
|
+
startTime: number;
|
|
28
|
+
endTime?: number;
|
|
29
|
+
durationMs?: number;
|
|
30
|
+
success?: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
params?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Cache event payload
|
|
36
|
+
*/
|
|
37
|
+
export interface CacheEvent {
|
|
38
|
+
key: string;
|
|
39
|
+
type: "scar_search" | "decisions" | "wins" | "embeddings";
|
|
40
|
+
ageMs?: number;
|
|
41
|
+
sizeBytes?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Database query event payload
|
|
45
|
+
*/
|
|
46
|
+
export interface DbQueryEvent {
|
|
47
|
+
operation: string;
|
|
48
|
+
table?: string;
|
|
49
|
+
startTime: number;
|
|
50
|
+
endTime?: number;
|
|
51
|
+
durationMs?: number;
|
|
52
|
+
rowCount?: number;
|
|
53
|
+
success?: boolean;
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Embedding call event payload
|
|
58
|
+
*/
|
|
59
|
+
export interface EmbeddingCallEvent {
|
|
60
|
+
provider: string;
|
|
61
|
+
model?: string;
|
|
62
|
+
inputLength: number;
|
|
63
|
+
startTime: number;
|
|
64
|
+
endTime?: number;
|
|
65
|
+
durationMs?: number;
|
|
66
|
+
success?: boolean;
|
|
67
|
+
error?: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Error event payload
|
|
71
|
+
*/
|
|
72
|
+
export interface ErrorEvent {
|
|
73
|
+
error: Error | string;
|
|
74
|
+
context: string;
|
|
75
|
+
timestamp: number;
|
|
76
|
+
severity: "warning" | "error" | "fatal";
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Diagnostics channels singleton
|
|
80
|
+
*/
|
|
81
|
+
declare class DiagnosticsChannels {
|
|
82
|
+
readonly toolCall: Channel;
|
|
83
|
+
readonly cacheHit: Channel;
|
|
84
|
+
readonly cacheMiss: Channel;
|
|
85
|
+
readonly dbQuery: Channel;
|
|
86
|
+
readonly embeddingCall: Channel;
|
|
87
|
+
readonly error: Channel;
|
|
88
|
+
constructor();
|
|
89
|
+
/**
|
|
90
|
+
* Publish tool call start event
|
|
91
|
+
*/
|
|
92
|
+
publishToolCallStart(tool: string, params?: Record<string, unknown>): ToolCallEvent;
|
|
93
|
+
/**
|
|
94
|
+
* Publish tool call end event
|
|
95
|
+
*/
|
|
96
|
+
publishToolCallEnd(event: ToolCallEvent, success: boolean, error?: string): void;
|
|
97
|
+
/**
|
|
98
|
+
* Publish cache hit event
|
|
99
|
+
*/
|
|
100
|
+
publishCacheHit(key: string, type: CacheEvent["type"], ageMs?: number, sizeBytes?: number): void;
|
|
101
|
+
/**
|
|
102
|
+
* Publish cache miss event
|
|
103
|
+
*/
|
|
104
|
+
publishCacheMiss(key: string, type: CacheEvent["type"]): void;
|
|
105
|
+
/**
|
|
106
|
+
* Publish database query start event
|
|
107
|
+
*/
|
|
108
|
+
publishDbQueryStart(operation: string, table?: string): DbQueryEvent;
|
|
109
|
+
/**
|
|
110
|
+
* Publish database query end event
|
|
111
|
+
*/
|
|
112
|
+
publishDbQueryEnd(event: DbQueryEvent, success: boolean, rowCount?: number, error?: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* Publish embedding call start event
|
|
115
|
+
*/
|
|
116
|
+
publishEmbeddingStart(provider: string, inputLength: number, model?: string): EmbeddingCallEvent;
|
|
117
|
+
/**
|
|
118
|
+
* Publish embedding call end event
|
|
119
|
+
*/
|
|
120
|
+
publishEmbeddingEnd(event: EmbeddingCallEvent, success: boolean, error?: string): void;
|
|
121
|
+
/**
|
|
122
|
+
* Publish error event
|
|
123
|
+
*/
|
|
124
|
+
publishError(error: Error | string, context: string, severity?: ErrorEvent["severity"]): void;
|
|
125
|
+
/**
|
|
126
|
+
* Check if any channel has subscribers
|
|
127
|
+
*/
|
|
128
|
+
hasSubscribers(): boolean;
|
|
129
|
+
}
|
|
130
|
+
export declare const diagnostics: DiagnosticsChannels;
|
|
131
|
+
export { channel };
|
|
132
|
+
//# sourceMappingURL=channels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../../src/diagnostics/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;CAOhB,CAAC;AAEX;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;CACzC;AAED;;GAEG;AACH,cAAM,mBAAmB;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;;IAWxB;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAUnF;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAQhF;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAKhG;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI;IAK7D;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY;IAUpE;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IASjG;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,kBAAkB;IAWhG;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAQtF;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,UAAU,CAAC,UAAU,CAAW,GAAG,IAAI;IAUtG;;OAEG;IACH,cAAc,IAAI,OAAO;CAU1B;AAGD,eAAO,MAAM,WAAW,qBAA4B,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitMem Diagnostics Channels
|
|
3
|
+
*
|
|
4
|
+
* Defines diagnostics_channel channels for zero-overhead instrumentation.
|
|
5
|
+
* When no subscriber is attached, publish() is essentially a no-op.
|
|
6
|
+
*
|
|
7
|
+
* Pattern reference: @ibm/telemetry-js
|
|
8
|
+
* Issue: OD-584
|
|
9
|
+
*/
|
|
10
|
+
import { channel } from "diagnostics_channel";
|
|
11
|
+
/**
|
|
12
|
+
* Channel names for GitMem diagnostics
|
|
13
|
+
*/
|
|
14
|
+
export const CHANNEL_NAMES = {
|
|
15
|
+
TOOL_CALL: "gitmem:tool:call",
|
|
16
|
+
CACHE_HIT: "gitmem:cache:hit",
|
|
17
|
+
CACHE_MISS: "gitmem:cache:miss",
|
|
18
|
+
DB_QUERY: "gitmem:db:query",
|
|
19
|
+
EMBEDDING_CALL: "gitmem:embedding:call",
|
|
20
|
+
ERROR: "gitmem:error",
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Diagnostics channels singleton
|
|
24
|
+
*/
|
|
25
|
+
class DiagnosticsChannels {
|
|
26
|
+
toolCall;
|
|
27
|
+
cacheHit;
|
|
28
|
+
cacheMiss;
|
|
29
|
+
dbQuery;
|
|
30
|
+
embeddingCall;
|
|
31
|
+
error;
|
|
32
|
+
constructor() {
|
|
33
|
+
this.toolCall = channel(CHANNEL_NAMES.TOOL_CALL);
|
|
34
|
+
this.cacheHit = channel(CHANNEL_NAMES.CACHE_HIT);
|
|
35
|
+
this.cacheMiss = channel(CHANNEL_NAMES.CACHE_MISS);
|
|
36
|
+
this.dbQuery = channel(CHANNEL_NAMES.DB_QUERY);
|
|
37
|
+
this.embeddingCall = channel(CHANNEL_NAMES.EMBEDDING_CALL);
|
|
38
|
+
this.error = channel(CHANNEL_NAMES.ERROR);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Publish tool call start event
|
|
42
|
+
*/
|
|
43
|
+
publishToolCallStart(tool, params) {
|
|
44
|
+
const event = {
|
|
45
|
+
tool,
|
|
46
|
+
startTime: Date.now(),
|
|
47
|
+
params,
|
|
48
|
+
};
|
|
49
|
+
this.toolCall.publish(event);
|
|
50
|
+
return event;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Publish tool call end event
|
|
54
|
+
*/
|
|
55
|
+
publishToolCallEnd(event, success, error) {
|
|
56
|
+
event.endTime = Date.now();
|
|
57
|
+
event.durationMs = event.endTime - event.startTime;
|
|
58
|
+
event.success = success;
|
|
59
|
+
event.error = error;
|
|
60
|
+
this.toolCall.publish(event);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Publish cache hit event
|
|
64
|
+
*/
|
|
65
|
+
publishCacheHit(key, type, ageMs, sizeBytes) {
|
|
66
|
+
const event = { key, type, ageMs, sizeBytes };
|
|
67
|
+
this.cacheHit.publish(event);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Publish cache miss event
|
|
71
|
+
*/
|
|
72
|
+
publishCacheMiss(key, type) {
|
|
73
|
+
const event = { key, type };
|
|
74
|
+
this.cacheMiss.publish(event);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Publish database query start event
|
|
78
|
+
*/
|
|
79
|
+
publishDbQueryStart(operation, table) {
|
|
80
|
+
const event = {
|
|
81
|
+
operation,
|
|
82
|
+
table,
|
|
83
|
+
startTime: Date.now(),
|
|
84
|
+
};
|
|
85
|
+
this.dbQuery.publish(event);
|
|
86
|
+
return event;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Publish database query end event
|
|
90
|
+
*/
|
|
91
|
+
publishDbQueryEnd(event, success, rowCount, error) {
|
|
92
|
+
event.endTime = Date.now();
|
|
93
|
+
event.durationMs = event.endTime - event.startTime;
|
|
94
|
+
event.success = success;
|
|
95
|
+
event.rowCount = rowCount;
|
|
96
|
+
event.error = error;
|
|
97
|
+
this.dbQuery.publish(event);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Publish embedding call start event
|
|
101
|
+
*/
|
|
102
|
+
publishEmbeddingStart(provider, inputLength, model) {
|
|
103
|
+
const event = {
|
|
104
|
+
provider,
|
|
105
|
+
model,
|
|
106
|
+
inputLength,
|
|
107
|
+
startTime: Date.now(),
|
|
108
|
+
};
|
|
109
|
+
this.embeddingCall.publish(event);
|
|
110
|
+
return event;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Publish embedding call end event
|
|
114
|
+
*/
|
|
115
|
+
publishEmbeddingEnd(event, success, error) {
|
|
116
|
+
event.endTime = Date.now();
|
|
117
|
+
event.durationMs = event.endTime - event.startTime;
|
|
118
|
+
event.success = success;
|
|
119
|
+
event.error = error;
|
|
120
|
+
this.embeddingCall.publish(event);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Publish error event
|
|
124
|
+
*/
|
|
125
|
+
publishError(error, context, severity = "error") {
|
|
126
|
+
const event = {
|
|
127
|
+
error,
|
|
128
|
+
context,
|
|
129
|
+
timestamp: Date.now(),
|
|
130
|
+
severity,
|
|
131
|
+
};
|
|
132
|
+
this.error.publish(event);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if any channel has subscribers
|
|
136
|
+
*/
|
|
137
|
+
hasSubscribers() {
|
|
138
|
+
return (this.toolCall.hasSubscribers ||
|
|
139
|
+
this.cacheHit.hasSubscribers ||
|
|
140
|
+
this.cacheMiss.hasSubscribers ||
|
|
141
|
+
this.dbQuery.hasSubscribers ||
|
|
142
|
+
this.embeddingCall.hasSubscribers ||
|
|
143
|
+
this.error.hasSubscribers);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Singleton instance
|
|
147
|
+
export const diagnostics = new DiagnosticsChannels();
|
|
148
|
+
// Export channel for external subscription
|
|
149
|
+
export { channel };
|
|
150
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/diagnostics/channels.ts"],"names":[],"mappings":"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"}
|