noterai 0.1.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.
Files changed (191) hide show
  1. package/README.md +368 -0
  2. package/bin/noter.js +218 -0
  3. package/bin/noter.js.map +1 -0
  4. package/package.json +73 -0
  5. package/packages/client/dist/assets/geist-mono-latin-400-normal-CoULgQGM.woff +0 -0
  6. package/packages/client/dist/assets/geist-mono-latin-400-normal-LC9RFr9I.woff2 +0 -0
  7. package/packages/client/dist/assets/index-CBiNAMaA.js +264 -0
  8. package/packages/client/dist/assets/index-u7i5Fle2.css +1 -0
  9. package/packages/client/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
  10. package/packages/client/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  11. package/packages/client/dist/assets/space-grotesk-latin-600-normal-BflQw4A9.woff +0 -0
  12. package/packages/client/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
  13. package/packages/client/dist/assets/vendor-react-DHeZC_T5.js +17 -0
  14. package/packages/client/dist/index.html +14 -0
  15. package/packages/server/dist/adapters/claudeAdapter.d.ts +34 -0
  16. package/packages/server/dist/adapters/claudeAdapter.d.ts.map +1 -0
  17. package/packages/server/dist/adapters/claudeAdapter.js +281 -0
  18. package/packages/server/dist/adapters/claudeAdapter.js.map +1 -0
  19. package/packages/server/dist/adapters/codexAdapter.d.ts +39 -0
  20. package/packages/server/dist/adapters/codexAdapter.d.ts.map +1 -0
  21. package/packages/server/dist/adapters/codexAdapter.js +347 -0
  22. package/packages/server/dist/adapters/codexAdapter.js.map +1 -0
  23. package/packages/server/dist/adapters/droidAdapter.d.ts +34 -0
  24. package/packages/server/dist/adapters/droidAdapter.d.ts.map +1 -0
  25. package/packages/server/dist/adapters/droidAdapter.js +109 -0
  26. package/packages/server/dist/adapters/droidAdapter.js.map +1 -0
  27. package/packages/server/dist/adapters/genericAdapter.d.ts +50 -0
  28. package/packages/server/dist/adapters/genericAdapter.d.ts.map +1 -0
  29. package/packages/server/dist/adapters/genericAdapter.js +203 -0
  30. package/packages/server/dist/adapters/genericAdapter.js.map +1 -0
  31. package/packages/server/dist/adapters/index.d.ts +7 -0
  32. package/packages/server/dist/adapters/index.d.ts.map +1 -0
  33. package/packages/server/dist/adapters/index.js +7 -0
  34. package/packages/server/dist/adapters/index.js.map +1 -0
  35. package/packages/server/dist/adapters/opencodeAdapter.d.ts +28 -0
  36. package/packages/server/dist/adapters/opencodeAdapter.d.ts.map +1 -0
  37. package/packages/server/dist/adapters/opencodeAdapter.js +265 -0
  38. package/packages/server/dist/adapters/opencodeAdapter.js.map +1 -0
  39. package/packages/server/dist/adapters/opencodeSessionManager.d.ts +13 -0
  40. package/packages/server/dist/adapters/opencodeSessionManager.d.ts.map +1 -0
  41. package/packages/server/dist/adapters/opencodeSessionManager.js +230 -0
  42. package/packages/server/dist/adapters/opencodeSessionManager.js.map +1 -0
  43. package/packages/server/dist/adapters/pathUtils.d.ts +54 -0
  44. package/packages/server/dist/adapters/pathUtils.d.ts.map +1 -0
  45. package/packages/server/dist/adapters/pathUtils.js +86 -0
  46. package/packages/server/dist/adapters/pathUtils.js.map +1 -0
  47. package/packages/server/dist/adapters/piAdapter.d.ts +34 -0
  48. package/packages/server/dist/adapters/piAdapter.d.ts.map +1 -0
  49. package/packages/server/dist/adapters/piAdapter.js +307 -0
  50. package/packages/server/dist/adapters/piAdapter.js.map +1 -0
  51. package/packages/server/dist/autoDetect.d.ts +15 -0
  52. package/packages/server/dist/autoDetect.d.ts.map +1 -0
  53. package/packages/server/dist/autoDetect.js +102 -0
  54. package/packages/server/dist/autoDetect.js.map +1 -0
  55. package/packages/server/dist/config.d.ts +29 -0
  56. package/packages/server/dist/config.d.ts.map +1 -0
  57. package/packages/server/dist/config.js +96 -0
  58. package/packages/server/dist/config.js.map +1 -0
  59. package/packages/server/dist/eventStore.d.ts +14 -0
  60. package/packages/server/dist/eventStore.d.ts.map +1 -0
  61. package/packages/server/dist/eventStore.js +35 -0
  62. package/packages/server/dist/eventStore.js.map +1 -0
  63. package/packages/server/dist/hookWatcher.d.ts +24 -0
  64. package/packages/server/dist/hookWatcher.d.ts.map +1 -0
  65. package/packages/server/dist/hookWatcher.js +152 -0
  66. package/packages/server/dist/hookWatcher.js.map +1 -0
  67. package/packages/server/dist/index.d.ts +58 -0
  68. package/packages/server/dist/index.d.ts.map +1 -0
  69. package/packages/server/dist/index.js +527 -0
  70. package/packages/server/dist/index.js.map +1 -0
  71. package/packages/server/dist/llm/jsonExtractor.d.ts +39 -0
  72. package/packages/server/dist/llm/jsonExtractor.d.ts.map +1 -0
  73. package/packages/server/dist/llm/jsonExtractor.js +83 -0
  74. package/packages/server/dist/llm/jsonExtractor.js.map +1 -0
  75. package/packages/server/dist/llm/ollamaCache.d.ts +19 -0
  76. package/packages/server/dist/llm/ollamaCache.d.ts.map +1 -0
  77. package/packages/server/dist/llm/ollamaCache.js +31 -0
  78. package/packages/server/dist/llm/ollamaCache.js.map +1 -0
  79. package/packages/server/dist/llm/ollamaClient.d.ts +29 -0
  80. package/packages/server/dist/llm/ollamaClient.d.ts.map +1 -0
  81. package/packages/server/dist/llm/ollamaClient.js +117 -0
  82. package/packages/server/dist/llm/ollamaClient.js.map +1 -0
  83. package/packages/server/dist/llm/ollamaQueue.d.ts +7 -0
  84. package/packages/server/dist/llm/ollamaQueue.d.ts.map +1 -0
  85. package/packages/server/dist/llm/ollamaQueue.js +28 -0
  86. package/packages/server/dist/llm/ollamaQueue.js.map +1 -0
  87. package/packages/server/dist/llm/promptBuilder.d.ts +8 -0
  88. package/packages/server/dist/llm/promptBuilder.d.ts.map +1 -0
  89. package/packages/server/dist/llm/promptBuilder.js +85 -0
  90. package/packages/server/dist/llm/promptBuilder.js.map +1 -0
  91. package/packages/server/dist/llm/promptSections.d.ts +64 -0
  92. package/packages/server/dist/llm/promptSections.d.ts.map +1 -0
  93. package/packages/server/dist/llm/promptSections.js +128 -0
  94. package/packages/server/dist/llm/promptSections.js.map +1 -0
  95. package/packages/server/dist/llm/providerModels.d.ts +14 -0
  96. package/packages/server/dist/llm/providerModels.d.ts.map +1 -0
  97. package/packages/server/dist/llm/providerModels.js +67 -0
  98. package/packages/server/dist/llm/providerModels.js.map +1 -0
  99. package/packages/server/dist/llm/suggester.d.ts +12 -0
  100. package/packages/server/dist/llm/suggester.d.ts.map +1 -0
  101. package/packages/server/dist/llm/suggester.js +263 -0
  102. package/packages/server/dist/llm/suggester.js.map +1 -0
  103. package/packages/server/dist/llm/summarizer.d.ts +53 -0
  104. package/packages/server/dist/llm/summarizer.d.ts.map +1 -0
  105. package/packages/server/dist/llm/summarizer.js +174 -0
  106. package/packages/server/dist/llm/summarizer.js.map +1 -0
  107. package/packages/server/dist/persistence.d.ts +42 -0
  108. package/packages/server/dist/persistence.d.ts.map +1 -0
  109. package/packages/server/dist/persistence.js +103 -0
  110. package/packages/server/dist/persistence.js.map +1 -0
  111. package/packages/server/dist/repoContext.d.ts +60 -0
  112. package/packages/server/dist/repoContext.d.ts.map +1 -0
  113. package/packages/server/dist/repoContext.js +197 -0
  114. package/packages/server/dist/repoContext.js.map +1 -0
  115. package/packages/server/dist/routes/blueprint.d.ts +7 -0
  116. package/packages/server/dist/routes/blueprint.d.ts.map +1 -0
  117. package/packages/server/dist/routes/blueprint.js +529 -0
  118. package/packages/server/dist/routes/blueprint.js.map +1 -0
  119. package/packages/server/dist/routes/config.d.ts +17 -0
  120. package/packages/server/dist/routes/config.d.ts.map +1 -0
  121. package/packages/server/dist/routes/config.js +282 -0
  122. package/packages/server/dist/routes/config.js.map +1 -0
  123. package/packages/server/dist/routes/lmstudio.d.ts +4 -0
  124. package/packages/server/dist/routes/lmstudio.d.ts.map +1 -0
  125. package/packages/server/dist/routes/lmstudio.js +67 -0
  126. package/packages/server/dist/routes/lmstudio.js.map +1 -0
  127. package/packages/server/dist/routes/notes.d.ts +5 -0
  128. package/packages/server/dist/routes/notes.d.ts.map +1 -0
  129. package/packages/server/dist/routes/notes.js +60 -0
  130. package/packages/server/dist/routes/notes.js.map +1 -0
  131. package/packages/server/dist/routes/ollama.d.ts +4 -0
  132. package/packages/server/dist/routes/ollama.d.ts.map +1 -0
  133. package/packages/server/dist/routes/ollama.js +207 -0
  134. package/packages/server/dist/routes/ollama.js.map +1 -0
  135. package/packages/server/dist/routes/prompt.d.ts +4 -0
  136. package/packages/server/dist/routes/prompt.d.ts.map +1 -0
  137. package/packages/server/dist/routes/prompt.js +75 -0
  138. package/packages/server/dist/routes/prompt.js.map +1 -0
  139. package/packages/server/dist/routes/refineNotes.d.ts +4 -0
  140. package/packages/server/dist/routes/refineNotes.d.ts.map +1 -0
  141. package/packages/server/dist/routes/refineNotes.js +87 -0
  142. package/packages/server/dist/routes/refineNotes.js.map +1 -0
  143. package/packages/server/dist/routes/repoContext.d.ts +3 -0
  144. package/packages/server/dist/routes/repoContext.d.ts.map +1 -0
  145. package/packages/server/dist/routes/repoContext.js +15 -0
  146. package/packages/server/dist/routes/repoContext.js.map +1 -0
  147. package/packages/server/dist/routes/sessions.d.ts +15 -0
  148. package/packages/server/dist/routes/sessions.d.ts.map +1 -0
  149. package/packages/server/dist/routes/sessions.js +420 -0
  150. package/packages/server/dist/routes/sessions.js.map +1 -0
  151. package/packages/server/dist/routes/summarize.d.ts +6 -0
  152. package/packages/server/dist/routes/summarize.d.ts.map +1 -0
  153. package/packages/server/dist/routes/summarize.js +85 -0
  154. package/packages/server/dist/routes/summarize.js.map +1 -0
  155. package/packages/server/dist/server.d.ts +2 -0
  156. package/packages/server/dist/server.d.ts.map +1 -0
  157. package/packages/server/dist/server.js +6 -0
  158. package/packages/server/dist/server.js.map +1 -0
  159. package/packages/server/dist/sessionManager.d.ts +41 -0
  160. package/packages/server/dist/sessionManager.d.ts.map +1 -0
  161. package/packages/server/dist/sessionManager.js +493 -0
  162. package/packages/server/dist/sessionManager.js.map +1 -0
  163. package/packages/server/dist/sessionScanner.d.ts +22 -0
  164. package/packages/server/dist/sessionScanner.d.ts.map +1 -0
  165. package/packages/server/dist/sessionScanner.js +165 -0
  166. package/packages/server/dist/sessionScanner.js.map +1 -0
  167. package/packages/server/dist/sessionTitle.d.ts +17 -0
  168. package/packages/server/dist/sessionTitle.d.ts.map +1 -0
  169. package/packages/server/dist/sessionTitle.js +321 -0
  170. package/packages/server/dist/sessionTitle.js.map +1 -0
  171. package/packages/server/dist/stateManager.d.ts +38 -0
  172. package/packages/server/dist/stateManager.d.ts.map +1 -0
  173. package/packages/server/dist/stateManager.js +83 -0
  174. package/packages/server/dist/stateManager.js.map +1 -0
  175. package/packages/server/dist/wsServer.d.ts +27 -0
  176. package/packages/server/dist/wsServer.d.ts.map +1 -0
  177. package/packages/server/dist/wsServer.js +144 -0
  178. package/packages/server/dist/wsServer.js.map +1 -0
  179. package/packages/shared/dist/index.d.ts +3 -0
  180. package/packages/shared/dist/index.d.ts.map +1 -0
  181. package/packages/shared/dist/index.js +3 -0
  182. package/packages/shared/dist/index.js.map +1 -0
  183. package/packages/shared/dist/llm/mambaDetect.d.ts +84 -0
  184. package/packages/shared/dist/llm/mambaDetect.d.ts.map +1 -0
  185. package/packages/shared/dist/llm/mambaDetect.js +205 -0
  186. package/packages/shared/dist/llm/mambaDetect.js.map +1 -0
  187. package/packages/shared/dist/types.d.ts +184 -0
  188. package/packages/shared/dist/types.d.ts.map +1 -0
  189. package/packages/shared/dist/types.js +2 -0
  190. package/packages/shared/dist/types.js.map +1 -0
  191. package/scripts/postbuild.js +70 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptSections.js","sourceRoot":"","sources":["../../src/llm/promptSections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared provider model registry and model resolution.
3
+ * Eliminates duplication between promptBuilder.ts and blueprint.ts.
4
+ */
5
+ import type { LanguageModel } from 'ai';
6
+ import type { AppConfig } from '../config.js';
7
+ export declare const PROVIDER_MODELS: Record<string, {
8
+ modelId: string;
9
+ requiresKey: boolean;
10
+ envKey: string;
11
+ }>;
12
+ export declare function getModel(provider: string, config: AppConfig): LanguageModel;
13
+ export declare function getModelName(provider: string, config: AppConfig): string;
14
+ //# sourceMappingURL=providerModels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerModels.d.ts","sourceRoot":"","sources":["../../src/llm/providerModels.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAOrG,CAAC;AAEF,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,aAAa,CAmC3E;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAQxE"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Shared provider model registry and model resolution.
3
+ * Eliminates duplication between promptBuilder.ts and blueprint.ts.
4
+ */
5
+ import { anthropic } from '@ai-sdk/anthropic';
6
+ import { openai, createOpenAI } from '@ai-sdk/openai';
7
+ import { google } from '@ai-sdk/google';
8
+ import { getOllamaProvider } from './ollamaCache.js';
9
+ import { MissingApiKeyError } from './promptBuilder.js';
10
+ export const PROVIDER_MODELS = {
11
+ anthropic: { modelId: 'claude-sonnet-4-20250514', requiresKey: true, envKey: 'ANTHROPIC_API_KEY' },
12
+ openai: { modelId: 'gpt-4o', requiresKey: true, envKey: 'OPENAI_API_KEY' },
13
+ gemini: { modelId: 'gemini-2.5-flash', requiresKey: true, envKey: 'GEMINI_API_KEY' },
14
+ ollama: { modelId: '', requiresKey: false, envKey: '' },
15
+ 'lm-studio': { modelId: '', requiresKey: false, envKey: '' },
16
+ custom: { modelId: '', requiresKey: false, envKey: '' },
17
+ };
18
+ export function getModel(provider, config) {
19
+ switch (provider) {
20
+ case 'anthropic': {
21
+ if (!config.anthropicApiKey)
22
+ throw new MissingApiKeyError('Anthropic');
23
+ return anthropic(PROVIDER_MODELS.anthropic.modelId);
24
+ }
25
+ case 'openai': {
26
+ if (!config.openaiApiKey)
27
+ throw new MissingApiKeyError('OpenAI');
28
+ return openai(PROVIDER_MODELS.openai.modelId);
29
+ }
30
+ case 'gemini': {
31
+ if (!config.geminiApiKey)
32
+ throw new MissingApiKeyError('Gemini');
33
+ return google(PROVIDER_MODELS.gemini.modelId);
34
+ }
35
+ case 'lm-studio': {
36
+ const lmStudio = createOpenAI({
37
+ baseURL: config.lmStudioBaseUrl || 'http://localhost:1234/v1',
38
+ apiKey: 'lm-studio',
39
+ });
40
+ return lmStudio(config.lmStudioModel || 'default');
41
+ }
42
+ case 'custom': {
43
+ if (!config.customProviderBaseUrl)
44
+ throw new MissingApiKeyError('Custom Provider');
45
+ const customProvider = createOpenAI({
46
+ baseURL: config.customProviderBaseUrl,
47
+ apiKey: config.customProviderApiKey || 'none',
48
+ });
49
+ return customProvider(config.customProviderModel || 'default');
50
+ }
51
+ case 'ollama':
52
+ default: {
53
+ const ollamaProvider = getOllamaProvider({ baseURL: config.ollamaBaseUrl });
54
+ return ollamaProvider(config.ollamaModel);
55
+ }
56
+ }
57
+ }
58
+ export function getModelName(provider, config) {
59
+ switch (provider) {
60
+ case 'anthropic': return PROVIDER_MODELS.anthropic.modelId;
61
+ case 'openai': return PROVIDER_MODELS.openai.modelId;
62
+ case 'gemini': return PROVIDER_MODELS.gemini.modelId;
63
+ case 'ollama': return config.ollamaModel || '';
64
+ default: return config.ollamaModel || '';
65
+ }
66
+ }
67
+ //# sourceMappingURL=providerModels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerModels.js","sourceRoot":"","sources":["../../src/llm/providerModels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { AppConfig } from '../config.js';
2
+ import type { ContextSummary, HumanNotes, TaskOrigin, TaskSuggestion } from '../../../shared/dist/index.js';
3
+ /** Deterministic ID from title — same title always produces same ID */
4
+ export declare function stableTaskId(title: string): string;
5
+ export declare function suggest(summary: ContextSummary | null, notes: HumanNotes, config: AppConfig, origin?: TaskOrigin): Promise<TaskSuggestion[]>;
6
+ /** Merge newly generated suggestions into existing list.
7
+ * - Context-generated tasks always preserved
8
+ * - Pinned tasks always preserved (checked via pinnedIds set)
9
+ * - Unpinned notes-origin tasks replaced by new notes-origin suggestions
10
+ * - Deduplication by stable task ID */
11
+ export declare function mergeSuggestions(existing: TaskSuggestion[], incoming: TaskSuggestion[], pinnedIds: Set<string>): TaskSuggestion[];
12
+ //# sourceMappingURL=suggester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggester.d.ts","sourceRoot":"","sources":["../../src/llm/suggester.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAiH5F,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAsB,OAAO,CAC3B,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,SAAS,EACjB,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CA+I3B;AAED;;;;wCAIwC;AACxC,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,QAAQ,EAAE,cAAc,EAAE,EAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,cAAc,EAAE,CAsBlB"}
@@ -0,0 +1,263 @@
1
+ import { z } from 'zod';
2
+ import { SUGGESTER_QUEUE } from './ollamaQueue.js';
3
+ import { ollamaClient } from './ollamaClient.js';
4
+ import { buildRepoPromptSections, PLACEHOLDER_PATTERNS } from './promptSections.js';
5
+ const TaskSuggestionSchema = z.object({
6
+ suggestions: z.array(z.object({
7
+ id: z.string(),
8
+ title: z.string(),
9
+ rationale: z.string(),
10
+ priority: z.enum(['high', 'medium', 'low']),
11
+ conflictsWithNotes: z.boolean(),
12
+ conflictExplanation: z.string().optional(),
13
+ affectedFiles: z.array(z.string()).optional(),
14
+ suggestedToolCalls: z.array(z.string()).optional(),
15
+ })),
16
+ });
17
+ /** Minimal JSON schema — Ollama format param carries the full schema already */
18
+ const TASK_SUGGESTION_JSON_FORMAT = {
19
+ type: 'object',
20
+ properties: {
21
+ suggestions: {
22
+ type: 'array',
23
+ items: {
24
+ type: 'object',
25
+ properties: {
26
+ id: { type: 'string', description: 'Deterministic hash — will be replaced by server. Send any string.' },
27
+ title: { type: 'string', description: 'Human-readable action sentence. e.g. "Fix auth timeout in auth.ts". Must start with a verb and contain spaces. NOT an ID, NOT gibberish.' },
28
+ rationale: { type: 'string', description: 'WHY this task matters given the context. At least 20 characters.' },
29
+ priority: { type: 'string', enum: ['high', 'medium', 'low'] },
30
+ conflictsWithNotes: { type: 'boolean' },
31
+ conflictExplanation: { type: 'string' },
32
+ affectedFiles: { type: 'array', items: { type: 'string' } },
33
+ suggestedToolCalls: { type: 'array', items: { type: 'string' } },
34
+ },
35
+ required: ['id', 'title', 'rationale', 'priority', 'conflictsWithNotes'],
36
+ },
37
+ },
38
+ },
39
+ required: ['suggestions'],
40
+ };
41
+ /** Shared suggestion rules — compact, no duplication */
42
+ const SUGGESTION_RULES = `Rules:
43
+ 1. Ground every task in specific notes/context details. Generic tasks rejected.
44
+ 2. Most relevant task first.
45
+ 3. Title = specific action sentence starting with a verb (e.g. "Fix auth timeout in auth.ts", "Add rate limiting to API endpoints"). NOT an ID, NOT a slug, NOT gibberish like "task5ktv9f".
46
+ 4. Rationale = WHY this matters given context. At least 20 characters.
47
+ 5. Include affectedFiles array with specific files
48
+ 6. May include suggestedToolCalls (e.g., ["edit_file", "run_tests"])
49
+ 7. No generic placeholders. No ALL_CAPS titles. No ID-like strings.
50
+ 8. Prefer fewer high-confidence tasks over many generic ones
51
+ 9. If tests failing → prioritize fixing
52
+ 10. If errors → prioritize root cause
53
+ 11. Use field "rationale" (NOT "description")
54
+ 12. Set conflictsWithNotes=true + conflictExplanation if task conflicts with notes
55
+ 13. Title must be a human-readable sentence with spaces and at least one verb. Reject gibberish, IDs, slugs, camelCase identifiers.
56
+
57
+ Output: ONLY valid JSON. No markdown, no code blocks.`;
58
+ function buildSuggestionPrompt(summary, notes) {
59
+ const repo = buildRepoPromptSections();
60
+ const toolsUsed = summary.toolsUsed;
61
+ const errorCount = summary.errorCount;
62
+ const testStatus = summary.testStatus;
63
+ return `Analyze dev notes + agent context → generate task suggestions.
64
+
65
+ ## Dev Notes (HIGHEST PRIORITY)
66
+ ${notes.content}
67
+ ${repo.instructions}
68
+ ## Agent Context
69
+ - Activity: ${summary.whatIsHappening}
70
+ - Files: ${summary.filesChanged.join(', ')}
71
+ - Goal: ${summary.currentGoal}
72
+ - Blockers: ${summary.blockers.join(', ') || 'None'}
73
+ - Events: ${summary.rawEventCount}
74
+ ${repo.root}
75
+ ${toolsUsed ? `- Tools: ${toolsUsed.join(', ')}` : ''}
76
+ ${errorCount !== undefined ? `- Errors: ${errorCount}` : ''}
77
+ ${testStatus ? `- Tests: ${testStatus}` : ''}
78
+
79
+ ${SUGGESTION_RULES}`;
80
+ }
81
+ function buildSuggestionPromptFromNotes(notes) {
82
+ const repo = buildRepoPromptSections();
83
+ return `Generate task suggestions from dev notes.
84
+
85
+ ## Dev Notes
86
+ ${notes.content || '(No notes)'}
87
+ ${repo.instructions}
88
+ ${repo.root}
89
+
90
+ Rules:
91
+ 1. Ground every task in specific notes details. Generic tasks rejected.
92
+ 2. Most relevant task first.
93
+ 3. Title = specific action sentence starting with a verb from notes (e.g. "Add input validation to login form"). NOT an ID or gibberish like "task5ktv9f".
94
+ 4. Rationale = why it matters per notes. At least 20 characters.
95
+ 5. No generic placeholders. No ALL_CAPS titles. No ID-like strings.
96
+ 6. Use field "rationale" (NOT "description")
97
+ 7. Include files/components from notes in affectedFiles
98
+ 8. Title must contain spaces and at least one verb.
99
+
100
+ Output: ONLY valid JSON. No markdown, no code blocks.`;
101
+ }
102
+ /** Deterministic ID from title — same title always produces same ID */
103
+ export function stableTaskId(title) {
104
+ let hash = 0;
105
+ for (let i = 0; i < title.length; i++) {
106
+ hash = ((hash << 5) - hash + title.charCodeAt(i)) | 0;
107
+ }
108
+ return `task-${Math.abs(hash).toString(36)}`;
109
+ }
110
+ export async function suggest(summary, notes, config, origin) {
111
+ const promptText = summary
112
+ ? buildSuggestionPrompt(summary, notes)
113
+ : buildSuggestionPromptFromNotes(notes);
114
+ const response = await SUGGESTER_QUEUE.enqueue('suggester', async () => {
115
+ return await ollamaClient(promptText, TASK_SUGGESTION_JSON_FORMAT, config);
116
+ });
117
+ // FIX: Handle models that return raw array instead of {suggestions: [...]}
118
+ // Also handle models that wrap in {output: {suggestions: [...]}} or other shapes
119
+ let suggestionsArray;
120
+ if (Array.isArray(response)) {
121
+ suggestionsArray = response;
122
+ }
123
+ else if (response && Array.isArray(response.suggestions)) {
124
+ suggestionsArray = response.suggestions;
125
+ }
126
+ else if (response && typeof response === 'object') {
127
+ // Defensive: search for the first array-valued key in the response
128
+ const obj = response;
129
+ const arrayKey = Object.keys(obj).find(k => Array.isArray(obj[k]));
130
+ if (arrayKey) {
131
+ suggestionsArray = obj[arrayKey];
132
+ console.error(`[suggester] LLM returned unexpected shape, extracted array from key "${arrayKey}"`);
133
+ }
134
+ else {
135
+ console.error('[suggester] LLM response shape unexpected:', JSON.stringify(response).slice(0, 200));
136
+ throw new Error('Invalid response from LLM: suggestions must be an array');
137
+ }
138
+ }
139
+ else {
140
+ throw new Error('Invalid response from LLM: suggestions must be an array');
141
+ }
142
+ // FIX: Validation gate - filter malformed or placeholder tasks
143
+ const VALIDATED_SUGGESTIONS = [];
144
+ for (const rawSuggestion of suggestionsArray) {
145
+ // FIX: Normalize common schema mismatches from LLM output
146
+ const suggestion = typeof rawSuggestion === 'object' && rawSuggestion !== null
147
+ ? { ...rawSuggestion }
148
+ : {};
149
+ // FIX: Normalize 'description' → 'rationale' for models that return the wrong field name
150
+ if (typeof suggestion.description === 'string' && !suggestion.rationale) {
151
+ suggestion.rationale = suggestion.description;
152
+ delete suggestion.description;
153
+ }
154
+ // Normalize id to string
155
+ if (typeof suggestion.id === 'number') {
156
+ suggestion.id = String(suggestion.id);
157
+ }
158
+ // FIX: Default priority to 'medium' when missing, normalize to lowercase enum
159
+ if (typeof suggestion.priority !== 'string' || !suggestion.priority) {
160
+ suggestion.priority = 'medium';
161
+ }
162
+ else {
163
+ const normalizedPriority = suggestion.priority.toLowerCase().trim();
164
+ if (['high', 'medium', 'low'].includes(normalizedPriority)) {
165
+ suggestion.priority = normalizedPriority;
166
+ }
167
+ else {
168
+ suggestion.priority = 'medium';
169
+ }
170
+ }
171
+ // Normalize conflictsWithNotes to boolean
172
+ if (typeof suggestion.conflictsWithNotes !== 'boolean') {
173
+ const conflictsValue = String(suggestion.conflictsWithNotes).toLowerCase().trim();
174
+ suggestion.conflictsWithNotes = conflictsValue === 'true' || conflictsValue === 'yes' || conflictsValue === '1';
175
+ }
176
+ // FIX: Check required fields exist and are correct types
177
+ // Generate deterministic ID from title so tasks keep same ID across regenerations
178
+ const title = String(suggestion.title ?? '');
179
+ let id = String(suggestion.id ?? '');
180
+ if (!title) {
181
+ continue;
182
+ }
183
+ // Always derive ID from title for stability — ignore LLM-provided IDs
184
+ id = stableTaskId(title);
185
+ const rationale = String(suggestion.rationale ?? '');
186
+ const priority = String(suggestion.priority ?? '');
187
+ const conflictsWithNotes = Boolean(suggestion.conflictsWithNotes);
188
+ if (!title || !rationale || !priority) {
189
+ continue;
190
+ }
191
+ if (title.length < 10) {
192
+ continue;
193
+ }
194
+ if (rationale.length < 20) {
195
+ continue;
196
+ }
197
+ const IS_PLACEHOLDER = PLACEHOLDER_PATTERNS.some(pattern => pattern.test(title));
198
+ if (IS_PLACEHOLDER) {
199
+ continue;
200
+ }
201
+ // Title must contain at least one space — single-word titles are IDs/slugs/gibberish
202
+ if (!title.includes(' ')) {
203
+ continue;
204
+ }
205
+ // Build normalized TaskSuggestion
206
+ const normalizedSuggestion = {
207
+ id,
208
+ title,
209
+ rationale,
210
+ priority: priority,
211
+ conflictsWithNotes,
212
+ origin: origin ?? (summary ? 'context' : 'notes'),
213
+ };
214
+ // FIX: Auto-fill conflictExplanation if missing
215
+ if (conflictsWithNotes && !suggestion.conflictExplanation) {
216
+ normalizedSuggestion.conflictExplanation = 'Task conflicts with developer notes';
217
+ }
218
+ else if (suggestion.conflictExplanation) {
219
+ normalizedSuggestion.conflictExplanation = String(suggestion.conflictExplanation);
220
+ }
221
+ // Normalize optional fields
222
+ if (suggestion.affectedFiles) {
223
+ if (Array.isArray(suggestion.affectedFiles)) {
224
+ normalizedSuggestion.affectedFiles = suggestion.affectedFiles
225
+ .filter((f) => typeof f === 'string');
226
+ }
227
+ }
228
+ if (suggestion.suggestedToolCalls) {
229
+ if (Array.isArray(suggestion.suggestedToolCalls)) {
230
+ normalizedSuggestion.suggestedToolCalls = suggestion.suggestedToolCalls
231
+ .filter((t) => typeof t === 'string');
232
+ }
233
+ }
234
+ VALIDATED_SUGGESTIONS.push(normalizedSuggestion);
235
+ }
236
+ return VALIDATED_SUGGESTIONS;
237
+ }
238
+ /** Merge newly generated suggestions into existing list.
239
+ * - Context-generated tasks always preserved
240
+ * - Pinned tasks always preserved (checked via pinnedIds set)
241
+ * - Unpinned notes-origin tasks replaced by new notes-origin suggestions
242
+ * - Deduplication by stable task ID */
243
+ export function mergeSuggestions(existing, incoming, pinnedIds) {
244
+ // 1. Preserve all context-origin tasks from existing
245
+ const preserved = existing.filter(s => s.origin === 'context');
246
+ // 2. Preserve pinned tasks from existing (regardless of origin)
247
+ const preservedIds = new Set(preserved.map(s => s.id));
248
+ for (const s of existing) {
249
+ if (pinnedIds.has(s.id) && !preservedIds.has(s.id)) {
250
+ preserved.push(s);
251
+ preservedIds.add(s.id);
252
+ }
253
+ }
254
+ // 3. Add incoming tasks, skipping duplicates by ID
255
+ for (const s of incoming) {
256
+ if (!preservedIds.has(s.id)) {
257
+ preserved.push(s);
258
+ preservedIds.add(s.id);
259
+ }
260
+ }
261
+ return preserved;
262
+ }
263
+ //# sourceMappingURL=suggester.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggester.js","sourceRoot":"","sources":["../../src/llm/suggester.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { AppConfig } from '../config.js';
2
+ import type { ContextSummary as ContextSummaryType } from '../../../shared/dist/index.js';
3
+ import type { AgentEvent } from '../../../shared/dist/index.js';
4
+ import type { WsServerManager } from '../wsServer.js';
5
+ import type { EventStore } from '../eventStore.js';
6
+ import { z } from 'zod';
7
+ export declare const ContextSummarySchema: z.ZodObject<{
8
+ id: z.ZodString;
9
+ generatedAt: z.ZodNumber;
10
+ whatIsHappening: z.ZodString;
11
+ filesChanged: z.ZodArray<z.ZodString, "many">;
12
+ currentGoal: z.ZodString;
13
+ blockers: z.ZodArray<z.ZodString, "many">;
14
+ rawEventCount: z.ZodNumber;
15
+ toolsUsed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
16
+ errorCount: z.ZodOptional<z.ZodNumber>;
17
+ testStatus: z.ZodOptional<z.ZodEnum<["passing", "failing", "unknown"]>>;
18
+ lastActivityAt: z.ZodOptional<z.ZodNumber>;
19
+ }, "strip", z.ZodTypeAny, {
20
+ id: string;
21
+ generatedAt: number;
22
+ whatIsHappening: string;
23
+ filesChanged: string[];
24
+ currentGoal: string;
25
+ blockers: string[];
26
+ rawEventCount: number;
27
+ toolsUsed?: string[] | undefined;
28
+ errorCount?: number | undefined;
29
+ testStatus?: "unknown" | "passing" | "failing" | undefined;
30
+ lastActivityAt?: number | undefined;
31
+ }, {
32
+ id: string;
33
+ generatedAt: number;
34
+ whatIsHappening: string;
35
+ filesChanged: string[];
36
+ currentGoal: string;
37
+ blockers: string[];
38
+ rawEventCount: number;
39
+ toolsUsed?: string[] | undefined;
40
+ errorCount?: number | undefined;
41
+ testStatus?: "unknown" | "passing" | "failing" | undefined;
42
+ lastActivityAt?: number | undefined;
43
+ }>;
44
+ export interface Summarizer {
45
+ handleEvent(event: AgentEvent): void;
46
+ triggerSummarization(): Promise<ContextSummaryType | null>;
47
+ /** Reset internal counters/flags when switching sessions so stale state
48
+ * from the previous session does not leak into the new one. */
49
+ resetForSessionSwitch(): void;
50
+ }
51
+ export declare function createSummarizer(config: AppConfig, ws: WsServerManager, eventStore: EventStore): Summarizer;
52
+ export declare function buildSummarizationPrompt(events: AgentEvent[]): string;
53
+ //# sourceMappingURL=summarizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.d.ts","sourceRoot":"","sources":["../../src/llm/summarizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,IAAI,kBAAkB,EAAc,MAAM,eAAe,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY/B,CAAC;AAqBH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,oBAAoB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC3D;oEACgE;IAChE,qBAAqB,IAAI,IAAI,CAAC;CAC/B;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,GAAG,UAAU,CA6G3G;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAuCrE"}
@@ -0,0 +1,174 @@
1
+ import { stateManager } from '../stateManager.js';
2
+ import { z } from 'zod';
3
+ import { INFERENCE_QUEUE } from './ollamaQueue.js';
4
+ import { ollamaClient } from './ollamaClient.js';
5
+ import { buildRepoPromptSections, formatEventCompact, TOKEN_BUDGETS, estimateTokens, hasMeaningfulSummaryContent } from './promptSections.js';
6
+ import { suggest } from './suggester.js';
7
+ import { mergeSuggestions } from './suggester.js';
8
+ import { loadPinnedTaskIds, saveSuggestions } from '../persistence.js';
9
+ export const ContextSummarySchema = z.object({
10
+ id: z.string(),
11
+ generatedAt: z.number(),
12
+ whatIsHappening: z.string(),
13
+ filesChanged: z.array(z.string()),
14
+ currentGoal: z.string(),
15
+ blockers: z.array(z.string()),
16
+ rawEventCount: z.number(),
17
+ toolsUsed: z.array(z.string()).optional(),
18
+ errorCount: z.number().optional(),
19
+ testStatus: z.enum(['passing', 'failing', 'unknown']).optional(),
20
+ lastActivityAt: z.number().optional(),
21
+ });
22
+ /** Minimal JSON schema for format param — no need to duplicate in prompt */
23
+ const CONTEXT_SUMMARY_JSON_FORMAT = {
24
+ type: 'object',
25
+ properties: {
26
+ id: { type: 'string' },
27
+ generatedAt: { type: 'number' },
28
+ whatIsHappening: { type: 'string' },
29
+ filesChanged: { type: 'array', items: { type: 'string' } },
30
+ currentGoal: { type: 'string' },
31
+ blockers: { type: 'array', items: { type: 'string' } },
32
+ rawEventCount: { type: 'number' },
33
+ toolsUsed: { type: 'array', items: { type: 'string' } },
34
+ errorCount: { type: 'number' },
35
+ testStatus: { type: 'string', enum: ['passing', 'failing', 'unknown'] },
36
+ lastActivityAt: { type: 'number' },
37
+ },
38
+ required: ['id', 'generatedAt', 'whatIsHappening', 'filesChanged', 'currentGoal', 'blockers', 'rawEventCount'],
39
+ };
40
+ export function createSummarizer(config, ws, eventStore) {
41
+ let eventsSinceLastSummary = 0;
42
+ const EVENT_THRESHOLD = 10;
43
+ /**
44
+ * Run context-based task generation as a result of a newly committed summary.
45
+ * - Only triggers when this is the FIRST real summary in the session.
46
+ * - Reuses the existing merge logic so context-generated tasks persist on later regeneration.
47
+ * - Replay-safe: if the first-summary task trigger already ran in this process, it does not re-run.
48
+ */
49
+ let firstSummaryContextTaskGenTriggered = false;
50
+ async function runFirstSummaryContextTaskGen(summary) {
51
+ if (firstSummaryContextTaskGenTriggered)
52
+ return;
53
+ firstSummaryContextTaskGenTriggered = true;
54
+ try {
55
+ const notes = stateManager.getNotes() ?? { content: '', updatedAt: Date.now() };
56
+ // FIX: Broadcast start indicator so SUGGESTED_TASK panel can show GENERATING TASK…
57
+ ws.broadcast({ type: 'suggestions-status', payload: { generating: true, reason: 'first-summary' } });
58
+ const fresh = await suggest(summary, notes, config, 'context');
59
+ const existing = stateManager.getSuggestions();
60
+ const pinnedIds = new Set(loadPinnedTaskIds());
61
+ const merged = mergeSuggestions(existing, fresh, pinnedIds);
62
+ stateManager.setSuggestions(merged);
63
+ saveSuggestions(merged);
64
+ ws.broadcast({ type: 'suggestions', payload: merged });
65
+ }
66
+ catch (error) {
67
+ // FIX: Errors are logged but never propagate — first-summary task gen is opportunistic
68
+ console.error('[Summarizer] First-summary context task generation failed:', error instanceof Error ? error.message : error);
69
+ }
70
+ finally {
71
+ ws.broadcast({ type: 'suggestions-status', payload: { generating: false, reason: 'first-summary' } });
72
+ }
73
+ }
74
+ async function runSummarization() {
75
+ try {
76
+ const budget = TOKEN_BUDGETS.summarizer;
77
+ const events = eventStore.getLast(budget.maxEvents);
78
+ const promptText = buildSummarizationPrompt(events);
79
+ // Token budget check — log warning if prompt exceeds budget
80
+ const estTokens = estimateTokens(promptText);
81
+ if (estTokens > budget.maxTotalChars / 3.5) {
82
+ console.error(`[Summarizer] Prompt ~${estTokens} tokens exceeds budget. Consider reducing event count.`);
83
+ }
84
+ const summary = await INFERENCE_QUEUE.enqueue('summarizer', async () => {
85
+ return await ollamaClient(promptText, CONTEXT_SUMMARY_JSON_FORMAT, config);
86
+ });
87
+ // FIX: Gate summary-state replacement on meaningful content.
88
+ // Preserve previous summary/status if the LLM produced a placeholder
89
+ // or empty payload — never let streamed transient/empty content wipe
90
+ // a valid existing summary.
91
+ if (!hasMeaningfulSummaryContent(summary)) {
92
+ console.error('[Summarizer] Discarding placeholder/empty summary — keeping previous state');
93
+ return null;
94
+ }
95
+ const previousSummary = stateManager.getSummary();
96
+ const isFirstSummary = previousSummary === null;
97
+ stateManager.setSummary(summary);
98
+ ws.broadcast({ type: 'summary', payload: summary });
99
+ eventsSinceLastSummary = 0;
100
+ // FIX: On the first real summary, kick off context-based task generation
101
+ // so the SUGGESTED_TASK panel is populated without requiring a notes save.
102
+ if (isFirstSummary) {
103
+ void runFirstSummaryContextTaskGen(summary);
104
+ }
105
+ return summary;
106
+ }
107
+ catch (error) {
108
+ console.error('[Summarizer] Error during summarization:', error);
109
+ return null;
110
+ }
111
+ }
112
+ function shouldTriggerSummarization(eventType) {
113
+ return eventType === 'session.idle' || eventType === 'stop';
114
+ }
115
+ return {
116
+ handleEvent(event) {
117
+ if (shouldTriggerSummarization(event.type)) {
118
+ runSummarization();
119
+ return;
120
+ }
121
+ if (event.type === 'tool.after' || event.type === 'tool.before') {
122
+ eventsSinceLastSummary++;
123
+ if (eventsSinceLastSummary >= EVENT_THRESHOLD) {
124
+ runSummarization();
125
+ }
126
+ }
127
+ },
128
+ triggerSummarization() {
129
+ return runSummarization();
130
+ },
131
+ resetForSessionSwitch() {
132
+ eventsSinceLastSummary = 0;
133
+ firstSummaryContextTaskGenTriggered = false;
134
+ },
135
+ };
136
+ }
137
+ export function buildSummarizationPrompt(events) {
138
+ const budget = TOKEN_BUDGETS.summarizer;
139
+ const repo = buildRepoPromptSections();
140
+ // Compact event formatting with total cap
141
+ let eventDescriptions = events
142
+ .map(e => formatEventCompact(e))
143
+ .join('\n');
144
+ // Enforce total character cap
145
+ if (eventDescriptions.length > budget.maxTotalChars) {
146
+ // Truncate from the beginning (keep most recent events)
147
+ eventDescriptions = eventDescriptions.slice(eventDescriptions.length - budget.maxTotalChars);
148
+ // Find first newline to avoid splitting mid-event
149
+ const firstNl = eventDescriptions.indexOf('\n');
150
+ if (firstNl > 0)
151
+ eventDescriptions = eventDescriptions.slice(firstNl + 1);
152
+ }
153
+ // Compute metadata inline from events (no separate "Session Metadata" section)
154
+ const uniqueTools = [...new Set(events.filter(e => e.type === 'tool.before' || e.type === 'tool.after').map(e => e.tool).filter(Boolean))];
155
+ const errorCount = events.filter(e => e.type === 'error' || e.status === 'failure').length;
156
+ const lastTimestamp = events.length > 0 ? events[events.length - 1].timestamp : Date.now();
157
+ return `Analyze session events → generate code-aware context summary.
158
+ ${repo.root}${repo.instructions}
159
+ ## Events (${events.length} total, tools: ${uniqueTools.join(',') || 'none'}, errors: ${errorCount})
160
+ ${eventDescriptions || 'No events yet.'}
161
+
162
+ ## Analyze (step by step)
163
+ 1. Current activity: what operation RIGHT NOW?
164
+ 2. Files touched/read/modified (full paths)
165
+ 3. Current goal (infer from event sequence)
166
+ 4. Blockers: compile errors, test failures, missing deps, stuck loops (3+ calls same file)
167
+ 5. Tools used: distinct tool names
168
+ 6. Error count
169
+ 7. Test status: passing/failing/unknown
170
+
171
+ Return ONLY valid JSON (no markdown):
172
+ {"id":"summary-${Date.now()}","generatedAt":${Date.now()},"whatIsHappening":"...","filesChanged":["..."],"currentGoal":"...","blockers":["..."],"rawEventCount":${events.length},"toolsUsed":["..."],"errorCount":${errorCount},"testStatus":"passing|failing|unknown","lastActivityAt":${lastTimestamp}}`;
173
+ }
174
+ //# sourceMappingURL=summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../src/llm/summarizer.ts"],"names":[],"mappings":"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"}