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.
- package/README.md +368 -0
- package/bin/noter.js +218 -0
- package/bin/noter.js.map +1 -0
- package/package.json +73 -0
- package/packages/client/dist/assets/geist-mono-latin-400-normal-CoULgQGM.woff +0 -0
- package/packages/client/dist/assets/geist-mono-latin-400-normal-LC9RFr9I.woff2 +0 -0
- package/packages/client/dist/assets/index-CBiNAMaA.js +264 -0
- package/packages/client/dist/assets/index-u7i5Fle2.css +1 -0
- package/packages/client/dist/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-600-normal-BflQw4A9.woff +0 -0
- package/packages/client/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
- package/packages/client/dist/assets/vendor-react-DHeZC_T5.js +17 -0
- package/packages/client/dist/index.html +14 -0
- package/packages/server/dist/adapters/claudeAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/claudeAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/claudeAdapter.js +281 -0
- package/packages/server/dist/adapters/claudeAdapter.js.map +1 -0
- package/packages/server/dist/adapters/codexAdapter.d.ts +39 -0
- package/packages/server/dist/adapters/codexAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/codexAdapter.js +347 -0
- package/packages/server/dist/adapters/codexAdapter.js.map +1 -0
- package/packages/server/dist/adapters/droidAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/droidAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/droidAdapter.js +109 -0
- package/packages/server/dist/adapters/droidAdapter.js.map +1 -0
- package/packages/server/dist/adapters/genericAdapter.d.ts +50 -0
- package/packages/server/dist/adapters/genericAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/genericAdapter.js +203 -0
- package/packages/server/dist/adapters/genericAdapter.js.map +1 -0
- package/packages/server/dist/adapters/index.d.ts +7 -0
- package/packages/server/dist/adapters/index.d.ts.map +1 -0
- package/packages/server/dist/adapters/index.js +7 -0
- package/packages/server/dist/adapters/index.js.map +1 -0
- package/packages/server/dist/adapters/opencodeAdapter.d.ts +28 -0
- package/packages/server/dist/adapters/opencodeAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/opencodeAdapter.js +265 -0
- package/packages/server/dist/adapters/opencodeAdapter.js.map +1 -0
- package/packages/server/dist/adapters/opencodeSessionManager.d.ts +13 -0
- package/packages/server/dist/adapters/opencodeSessionManager.d.ts.map +1 -0
- package/packages/server/dist/adapters/opencodeSessionManager.js +230 -0
- package/packages/server/dist/adapters/opencodeSessionManager.js.map +1 -0
- package/packages/server/dist/adapters/pathUtils.d.ts +54 -0
- package/packages/server/dist/adapters/pathUtils.d.ts.map +1 -0
- package/packages/server/dist/adapters/pathUtils.js +86 -0
- package/packages/server/dist/adapters/pathUtils.js.map +1 -0
- package/packages/server/dist/adapters/piAdapter.d.ts +34 -0
- package/packages/server/dist/adapters/piAdapter.d.ts.map +1 -0
- package/packages/server/dist/adapters/piAdapter.js +307 -0
- package/packages/server/dist/adapters/piAdapter.js.map +1 -0
- package/packages/server/dist/autoDetect.d.ts +15 -0
- package/packages/server/dist/autoDetect.d.ts.map +1 -0
- package/packages/server/dist/autoDetect.js +102 -0
- package/packages/server/dist/autoDetect.js.map +1 -0
- package/packages/server/dist/config.d.ts +29 -0
- package/packages/server/dist/config.d.ts.map +1 -0
- package/packages/server/dist/config.js +96 -0
- package/packages/server/dist/config.js.map +1 -0
- package/packages/server/dist/eventStore.d.ts +14 -0
- package/packages/server/dist/eventStore.d.ts.map +1 -0
- package/packages/server/dist/eventStore.js +35 -0
- package/packages/server/dist/eventStore.js.map +1 -0
- package/packages/server/dist/hookWatcher.d.ts +24 -0
- package/packages/server/dist/hookWatcher.d.ts.map +1 -0
- package/packages/server/dist/hookWatcher.js +152 -0
- package/packages/server/dist/hookWatcher.js.map +1 -0
- package/packages/server/dist/index.d.ts +58 -0
- package/packages/server/dist/index.d.ts.map +1 -0
- package/packages/server/dist/index.js +527 -0
- package/packages/server/dist/index.js.map +1 -0
- package/packages/server/dist/llm/jsonExtractor.d.ts +39 -0
- package/packages/server/dist/llm/jsonExtractor.d.ts.map +1 -0
- package/packages/server/dist/llm/jsonExtractor.js +83 -0
- package/packages/server/dist/llm/jsonExtractor.js.map +1 -0
- package/packages/server/dist/llm/ollamaCache.d.ts +19 -0
- package/packages/server/dist/llm/ollamaCache.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaCache.js +31 -0
- package/packages/server/dist/llm/ollamaCache.js.map +1 -0
- package/packages/server/dist/llm/ollamaClient.d.ts +29 -0
- package/packages/server/dist/llm/ollamaClient.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaClient.js +117 -0
- package/packages/server/dist/llm/ollamaClient.js.map +1 -0
- package/packages/server/dist/llm/ollamaQueue.d.ts +7 -0
- package/packages/server/dist/llm/ollamaQueue.d.ts.map +1 -0
- package/packages/server/dist/llm/ollamaQueue.js +28 -0
- package/packages/server/dist/llm/ollamaQueue.js.map +1 -0
- package/packages/server/dist/llm/promptBuilder.d.ts +8 -0
- package/packages/server/dist/llm/promptBuilder.d.ts.map +1 -0
- package/packages/server/dist/llm/promptBuilder.js +85 -0
- package/packages/server/dist/llm/promptBuilder.js.map +1 -0
- package/packages/server/dist/llm/promptSections.d.ts +64 -0
- package/packages/server/dist/llm/promptSections.d.ts.map +1 -0
- package/packages/server/dist/llm/promptSections.js +128 -0
- package/packages/server/dist/llm/promptSections.js.map +1 -0
- package/packages/server/dist/llm/providerModels.d.ts +14 -0
- package/packages/server/dist/llm/providerModels.d.ts.map +1 -0
- package/packages/server/dist/llm/providerModels.js +67 -0
- package/packages/server/dist/llm/providerModels.js.map +1 -0
- package/packages/server/dist/llm/suggester.d.ts +12 -0
- package/packages/server/dist/llm/suggester.d.ts.map +1 -0
- package/packages/server/dist/llm/suggester.js +263 -0
- package/packages/server/dist/llm/suggester.js.map +1 -0
- package/packages/server/dist/llm/summarizer.d.ts +53 -0
- package/packages/server/dist/llm/summarizer.d.ts.map +1 -0
- package/packages/server/dist/llm/summarizer.js +174 -0
- package/packages/server/dist/llm/summarizer.js.map +1 -0
- package/packages/server/dist/persistence.d.ts +42 -0
- package/packages/server/dist/persistence.d.ts.map +1 -0
- package/packages/server/dist/persistence.js +103 -0
- package/packages/server/dist/persistence.js.map +1 -0
- package/packages/server/dist/repoContext.d.ts +60 -0
- package/packages/server/dist/repoContext.d.ts.map +1 -0
- package/packages/server/dist/repoContext.js +197 -0
- package/packages/server/dist/repoContext.js.map +1 -0
- package/packages/server/dist/routes/blueprint.d.ts +7 -0
- package/packages/server/dist/routes/blueprint.d.ts.map +1 -0
- package/packages/server/dist/routes/blueprint.js +529 -0
- package/packages/server/dist/routes/blueprint.js.map +1 -0
- package/packages/server/dist/routes/config.d.ts +17 -0
- package/packages/server/dist/routes/config.d.ts.map +1 -0
- package/packages/server/dist/routes/config.js +282 -0
- package/packages/server/dist/routes/config.js.map +1 -0
- package/packages/server/dist/routes/lmstudio.d.ts +4 -0
- package/packages/server/dist/routes/lmstudio.d.ts.map +1 -0
- package/packages/server/dist/routes/lmstudio.js +67 -0
- package/packages/server/dist/routes/lmstudio.js.map +1 -0
- package/packages/server/dist/routes/notes.d.ts +5 -0
- package/packages/server/dist/routes/notes.d.ts.map +1 -0
- package/packages/server/dist/routes/notes.js +60 -0
- package/packages/server/dist/routes/notes.js.map +1 -0
- package/packages/server/dist/routes/ollama.d.ts +4 -0
- package/packages/server/dist/routes/ollama.d.ts.map +1 -0
- package/packages/server/dist/routes/ollama.js +207 -0
- package/packages/server/dist/routes/ollama.js.map +1 -0
- package/packages/server/dist/routes/prompt.d.ts +4 -0
- package/packages/server/dist/routes/prompt.d.ts.map +1 -0
- package/packages/server/dist/routes/prompt.js +75 -0
- package/packages/server/dist/routes/prompt.js.map +1 -0
- package/packages/server/dist/routes/refineNotes.d.ts +4 -0
- package/packages/server/dist/routes/refineNotes.d.ts.map +1 -0
- package/packages/server/dist/routes/refineNotes.js +87 -0
- package/packages/server/dist/routes/refineNotes.js.map +1 -0
- package/packages/server/dist/routes/repoContext.d.ts +3 -0
- package/packages/server/dist/routes/repoContext.d.ts.map +1 -0
- package/packages/server/dist/routes/repoContext.js +15 -0
- package/packages/server/dist/routes/repoContext.js.map +1 -0
- package/packages/server/dist/routes/sessions.d.ts +15 -0
- package/packages/server/dist/routes/sessions.d.ts.map +1 -0
- package/packages/server/dist/routes/sessions.js +420 -0
- package/packages/server/dist/routes/sessions.js.map +1 -0
- package/packages/server/dist/routes/summarize.d.ts +6 -0
- package/packages/server/dist/routes/summarize.d.ts.map +1 -0
- package/packages/server/dist/routes/summarize.js +85 -0
- package/packages/server/dist/routes/summarize.js.map +1 -0
- package/packages/server/dist/server.d.ts +2 -0
- package/packages/server/dist/server.d.ts.map +1 -0
- package/packages/server/dist/server.js +6 -0
- package/packages/server/dist/server.js.map +1 -0
- package/packages/server/dist/sessionManager.d.ts +41 -0
- package/packages/server/dist/sessionManager.d.ts.map +1 -0
- package/packages/server/dist/sessionManager.js +493 -0
- package/packages/server/dist/sessionManager.js.map +1 -0
- package/packages/server/dist/sessionScanner.d.ts +22 -0
- package/packages/server/dist/sessionScanner.d.ts.map +1 -0
- package/packages/server/dist/sessionScanner.js +165 -0
- package/packages/server/dist/sessionScanner.js.map +1 -0
- package/packages/server/dist/sessionTitle.d.ts +17 -0
- package/packages/server/dist/sessionTitle.d.ts.map +1 -0
- package/packages/server/dist/sessionTitle.js +321 -0
- package/packages/server/dist/sessionTitle.js.map +1 -0
- package/packages/server/dist/stateManager.d.ts +38 -0
- package/packages/server/dist/stateManager.d.ts.map +1 -0
- package/packages/server/dist/stateManager.js +83 -0
- package/packages/server/dist/stateManager.js.map +1 -0
- package/packages/server/dist/wsServer.d.ts +27 -0
- package/packages/server/dist/wsServer.d.ts.map +1 -0
- package/packages/server/dist/wsServer.js +144 -0
- package/packages/server/dist/wsServer.js.map +1 -0
- package/packages/shared/dist/index.d.ts +3 -0
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +3 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/shared/dist/llm/mambaDetect.d.ts +84 -0
- package/packages/shared/dist/llm/mambaDetect.d.ts.map +1 -0
- package/packages/shared/dist/llm/mambaDetect.js +205 -0
- package/packages/shared/dist/llm/mambaDetect.js.map +1 -0
- package/packages/shared/dist/types.d.ts +184 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/types.js +2 -0
- package/packages/shared/dist/types.js.map +1 -0
- package/scripts/postbuild.js +70 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session scanner — discovers session files for file-watching adapters.
|
|
3
|
+
*
|
|
4
|
+
* Each harness stores sessions differently:
|
|
5
|
+
* - claude-code: ~/.claude/transcripts/*.jsonl
|
|
6
|
+
* - pi: ~/.pi/agent/sessions/<workspace-dir>/*.jsonl
|
|
7
|
+
* - codex: ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl
|
|
8
|
+
* - factory-droid: ~/.factory/sessions/<escaped-cwd>/*.jsonl (recursive)
|
|
9
|
+
* - generic: single file (no sessions) or GENERIC_SESSION_DIR if set
|
|
10
|
+
* - opencode: SSE stream (no sessions)
|
|
11
|
+
*/
|
|
12
|
+
import { statSync, existsSync } from 'fs';
|
|
13
|
+
import { join, basename } from 'path';
|
|
14
|
+
import { resolveHomePath, collectFiles } from './adapters/pathUtils.js';
|
|
15
|
+
import { homedir, tmpdir } from 'os';
|
|
16
|
+
import { extractTitle } from './sessionManager.js';
|
|
17
|
+
function getHarnessRoot(harness) {
|
|
18
|
+
switch (harness) {
|
|
19
|
+
case 'claude-code':
|
|
20
|
+
return resolveHomePath('.claude', 'transcripts');
|
|
21
|
+
case 'pi':
|
|
22
|
+
return process.env.PI_SESSION_DIR ?? resolveHomePath('.pi', 'agent', 'sessions');
|
|
23
|
+
case 'codex':
|
|
24
|
+
return process.env.CODEX_SESSION_DIR ?? resolveHomePath('.codex', 'sessions');
|
|
25
|
+
case 'factory-droid':
|
|
26
|
+
return process.env.FACTORY_SESSIONS_DIR ?? join(homedir(), '.factory', 'sessions');
|
|
27
|
+
case 'generic':
|
|
28
|
+
return process.env.GENERIC_LOG_PATH ?? join(tmpdir(), 'noter-generic-events.jsonl');
|
|
29
|
+
default:
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const HARNESS_PATTERNS = {
|
|
34
|
+
'claude-code': {
|
|
35
|
+
pattern: (n) => n.endsWith('.jsonl'),
|
|
36
|
+
recursive: false,
|
|
37
|
+
},
|
|
38
|
+
'pi': {
|
|
39
|
+
pattern: (n) => n.endsWith('.jsonl'),
|
|
40
|
+
recursive: true,
|
|
41
|
+
},
|
|
42
|
+
'codex': {
|
|
43
|
+
pattern: (n) => n.startsWith('rollout-') && n.endsWith('.jsonl'),
|
|
44
|
+
recursive: true,
|
|
45
|
+
},
|
|
46
|
+
'factory-droid': {
|
|
47
|
+
pattern: (n) => n.endsWith('.jsonl') && !n.endsWith('.noter.jsonl') && !n.endsWith('.agentdesk.jsonl'),
|
|
48
|
+
recursive: true,
|
|
49
|
+
},
|
|
50
|
+
'generic': {
|
|
51
|
+
pattern: (n) => n.endsWith('.jsonl'),
|
|
52
|
+
recursive: false,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Estimate event count from file size instead of reading the entire file.
|
|
57
|
+
* JSONL lines are typically 200-800 bytes each. Using 300 as a reasonable
|
|
58
|
+
* average avoids reading potentially 100MB+ files line-by-line just to
|
|
59
|
+
* count entries for display purposes.
|
|
60
|
+
*/
|
|
61
|
+
export function estimateEventCount(filePath) {
|
|
62
|
+
try {
|
|
63
|
+
const size = statSync(filePath).size;
|
|
64
|
+
if (size === 0)
|
|
65
|
+
return 0;
|
|
66
|
+
return Math.max(1, Math.round(size / 300));
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export function hasSessionSupport(harness) {
|
|
73
|
+
// opencode now supports sessions via SQLite DB
|
|
74
|
+
return harness in HARNESS_PATTERNS || harness === 'generic' || harness === 'opencode';
|
|
75
|
+
}
|
|
76
|
+
export function scanSessions(harness, activeFile) {
|
|
77
|
+
// For generic, check if multi-session directory is configured
|
|
78
|
+
if (harness === 'generic') {
|
|
79
|
+
const genericDir = process.env.GENERIC_SESSION_DIR;
|
|
80
|
+
if (genericDir) {
|
|
81
|
+
console.error(`[SessionScanner] Scanning for generic sessions at: ${genericDir}`);
|
|
82
|
+
const files = [];
|
|
83
|
+
collectFiles(genericDir, (n) => n.endsWith('.jsonl'), false, files);
|
|
84
|
+
const sessions = [];
|
|
85
|
+
for (const path of files) {
|
|
86
|
+
try {
|
|
87
|
+
const stats = statSync(path);
|
|
88
|
+
const eventCount = estimateEventCount(path);
|
|
89
|
+
// Skip empty files — no events means nothing to display
|
|
90
|
+
if (eventCount === 0)
|
|
91
|
+
continue;
|
|
92
|
+
sessions.push({
|
|
93
|
+
id: basename(path, '.jsonl'),
|
|
94
|
+
path,
|
|
95
|
+
title: extractTitle(path),
|
|
96
|
+
startedAt: stats.birthtimeMs || stats.ctimeMs,
|
|
97
|
+
lastEventAt: stats.mtimeMs,
|
|
98
|
+
eventCount,
|
|
99
|
+
active: path === activeFile,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// skip unreadable files
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
sessions.sort((a, b) => b.lastEventAt - a.lastEventAt);
|
|
107
|
+
return sessions;
|
|
108
|
+
}
|
|
109
|
+
// Single-file generic mode
|
|
110
|
+
const root = process.env.GENERIC_LOG_PATH ?? join(tmpdir(), 'noter-generic-events.jsonl');
|
|
111
|
+
if (!existsSync(root))
|
|
112
|
+
return [];
|
|
113
|
+
try {
|
|
114
|
+
const stats = statSync(root);
|
|
115
|
+
const eventCount = estimateEventCount(root);
|
|
116
|
+
if (eventCount === 0)
|
|
117
|
+
return [];
|
|
118
|
+
return [{
|
|
119
|
+
id: basename(root, '.jsonl'),
|
|
120
|
+
path: root,
|
|
121
|
+
title: extractTitle(root),
|
|
122
|
+
startedAt: stats.birthtimeMs || stats.ctimeMs,
|
|
123
|
+
lastEventAt: stats.mtimeMs,
|
|
124
|
+
eventCount,
|
|
125
|
+
active: root === activeFile,
|
|
126
|
+
}];
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const root = getHarnessRoot(harness);
|
|
133
|
+
const def = HARNESS_PATTERNS[harness];
|
|
134
|
+
if (!root || !def)
|
|
135
|
+
return [];
|
|
136
|
+
console.error(`[SessionScanner] Scanning for ${harness} sessions at: ${root}`);
|
|
137
|
+
const files = [];
|
|
138
|
+
collectFiles(root, def.pattern, def.recursive, files);
|
|
139
|
+
const sessions = [];
|
|
140
|
+
for (const path of files) {
|
|
141
|
+
try {
|
|
142
|
+
const stats = statSync(path);
|
|
143
|
+
const eventCount = estimateEventCount(path);
|
|
144
|
+
// Skip empty files — no events means nothing to display
|
|
145
|
+
if (eventCount === 0)
|
|
146
|
+
continue;
|
|
147
|
+
sessions.push({
|
|
148
|
+
id: basename(path, '.jsonl'),
|
|
149
|
+
path,
|
|
150
|
+
title: extractTitle(path),
|
|
151
|
+
startedAt: stats.birthtimeMs || stats.ctimeMs,
|
|
152
|
+
lastEventAt: stats.mtimeMs,
|
|
153
|
+
eventCount,
|
|
154
|
+
active: path === activeFile,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// skip unreadable files
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// sort by lastEventAt desc
|
|
162
|
+
sessions.sort((a, b) => b.lastEventAt - a.lastEventAt);
|
|
163
|
+
return sessions;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=sessionScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionScanner.js","sourceRoot":"","sources":["../src/sessionScanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determine whether a session title is human-readable.
|
|
3
|
+
* Returns false for raw file paths, file stems, session UUIDs,
|
|
4
|
+
* timestamp-only strings, and hex-like IDs.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isHumanReadableTitle(title: string | undefined): boolean;
|
|
7
|
+
/** Remove system boilerplate tags from text. */
|
|
8
|
+
export declare function stripSystemBoilerplate(text: string): string;
|
|
9
|
+
/** Read deterministic title from a JSONL session file. */
|
|
10
|
+
export declare function extractTitleFromFile(filePath: string): string;
|
|
11
|
+
/** Read deterministic title from OpenCode SQLite DB for a session. */
|
|
12
|
+
export declare function extractTitleFromOpenCode(dbPath: string, sessionId: string): string;
|
|
13
|
+
/** Read a bounded sample of session text for on-demand summarization. */
|
|
14
|
+
export declare function readSessionSample(filePath: string, maxLines?: number, maxChars?: number): string;
|
|
15
|
+
/** Read a bounded sample from OpenCode SQLite for on-demand summarization. */
|
|
16
|
+
export declare function readOpenCodeSessionSample(dbPath: string, sessionId: string, maxLines?: number, maxChars?: number): string;
|
|
17
|
+
//# sourceMappingURL=sessionTitle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTitle.d.ts","sourceRoot":"","sources":["../src/sessionTitle.ts"],"names":[],"mappings":"AAeA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAkBvE;AA0BD,gDAAgD;AAChD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM3D;AAwID,0DAA0D;AAC1D,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc7D;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAuBlF;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,SAAK,EAAE,QAAQ,SAAO,GAAG,MAAM,CAyB1F;AAED,8EAA8E;AAC9E,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,SAAK,EAAE,QAAQ,SAAO,GAAG,MAAM,CAmCnH"}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { basename } from 'path';
|
|
3
|
+
import Database from 'better-sqlite3';
|
|
4
|
+
const MAX_TITLE_LEN = 60;
|
|
5
|
+
const FIRST_LINES = 15;
|
|
6
|
+
const MAX_SAMPLE_CHARS = 2000;
|
|
7
|
+
const MIN_USEFUL_LEN = 10;
|
|
8
|
+
/** Regex patterns for non-human-readable titles */
|
|
9
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10
|
+
const TIMESTAMP_PATTERN = /^\d{8}_\d{6}$/;
|
|
11
|
+
const TIMESTAMP_PATTERN_2 = /^\d{14}$/;
|
|
12
|
+
const RAW_ID_PATTERN = /^[a-f0-9]{6,32}$/i;
|
|
13
|
+
/**
|
|
14
|
+
* Determine whether a session title is human-readable.
|
|
15
|
+
* Returns false for raw file paths, file stems, session UUIDs,
|
|
16
|
+
* timestamp-only strings, and hex-like IDs.
|
|
17
|
+
*/
|
|
18
|
+
export function isHumanReadableTitle(title) {
|
|
19
|
+
if (!title || title.trim().length === 0)
|
|
20
|
+
return false;
|
|
21
|
+
const t = title.trim();
|
|
22
|
+
// Reject if it looks like a file path.
|
|
23
|
+
// A title containing "/" as a word separator (e.g., "UI / UX") is NOT a path.
|
|
24
|
+
// Only reject if it starts with a path indicator or contains a backslash.
|
|
25
|
+
if (t.startsWith('/') || t.startsWith('./') || t.startsWith('../') || t.includes('\\'))
|
|
26
|
+
return false;
|
|
27
|
+
// Reject if it is exactly the file stem (ends with .jsonl or similar)
|
|
28
|
+
if (/\.[a-z0-9]+$/i.test(t))
|
|
29
|
+
return false;
|
|
30
|
+
// Reject UUIDs
|
|
31
|
+
if (UUID_PATTERN.test(t))
|
|
32
|
+
return false;
|
|
33
|
+
// Reject timestamp-only strings
|
|
34
|
+
if (TIMESTAMP_PATTERN.test(t) || TIMESTAMP_PATTERN_2.test(t))
|
|
35
|
+
return false;
|
|
36
|
+
// Reject short hex-like IDs
|
|
37
|
+
if (RAW_ID_PATTERN.test(t) && t.length <= 32)
|
|
38
|
+
return false;
|
|
39
|
+
// Reject if it equals common fallback stems
|
|
40
|
+
if (t === 'session' || t === 'untitled' || t === 'unknown')
|
|
41
|
+
return false;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const GENERIC_WORDS = new Set([
|
|
45
|
+
'ready', 'started', 'starting', 'thinking', 'loading', 'connected',
|
|
46
|
+
'done', 'ok', 'okay', 'success', 'finished', 'complete', 'completed',
|
|
47
|
+
'processing', 'working', 'please wait', 'wait',
|
|
48
|
+
]);
|
|
49
|
+
const SKILL_ACTIVATION_PATTERNS = [
|
|
50
|
+
/skill\s+['"`]?[\w-]+['"`]?\s+activated/i,
|
|
51
|
+
/activat(?:ed|ing)\s+skill/i,
|
|
52
|
+
/caveman\s+(?:active|mode)/i,
|
|
53
|
+
/system-notification\s*:\s*skill/i,
|
|
54
|
+
];
|
|
55
|
+
const SETUP_PATTERNS = [
|
|
56
|
+
/server\s+running\s+on\s+port/i,
|
|
57
|
+
/startup\s+summary/i,
|
|
58
|
+
/harness\s+(?:initialized|started|booted)/i,
|
|
59
|
+
/adapter\s+(?:initialized|started)/i,
|
|
60
|
+
/watching\s+.*\s+for\s+sessions/i,
|
|
61
|
+
/sessionmanager\s+started/i,
|
|
62
|
+
/connected\s+to\s+event\s+stream/i,
|
|
63
|
+
/spawned\s+.*\s+server/i,
|
|
64
|
+
];
|
|
65
|
+
/** Remove system boilerplate tags from text. */
|
|
66
|
+
export function stripSystemBoilerplate(text) {
|
|
67
|
+
return text
|
|
68
|
+
.replace(/<system-[a-zA-Z-]+[\s\S]*?<\/system-[a-zA-Z-]+>/gi, '')
|
|
69
|
+
.replace(/<system-[a-zA-Z-]+\s*\/>/gi, '')
|
|
70
|
+
.replace(/<\/?system-[^>]*>/g, '')
|
|
71
|
+
.trim();
|
|
72
|
+
}
|
|
73
|
+
function isGeneric(text) {
|
|
74
|
+
const lower = text.toLowerCase().trim();
|
|
75
|
+
if (GENERIC_WORDS.has(lower))
|
|
76
|
+
return true;
|
|
77
|
+
for (const w of GENERIC_WORDS) {
|
|
78
|
+
if (lower === w)
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
function isSkillActivation(text) {
|
|
84
|
+
return SKILL_ACTIVATION_PATTERNS.some((p) => p.test(text));
|
|
85
|
+
}
|
|
86
|
+
function isSetupNoise(text) {
|
|
87
|
+
return SETUP_PATTERNS.some((p) => p.test(text));
|
|
88
|
+
}
|
|
89
|
+
function isNoise(text) {
|
|
90
|
+
const t = text.trim();
|
|
91
|
+
if (t.length === 0)
|
|
92
|
+
return true;
|
|
93
|
+
if (isGeneric(t))
|
|
94
|
+
return true;
|
|
95
|
+
if (isSkillActivation(t))
|
|
96
|
+
return true;
|
|
97
|
+
if (isSetupNoise(t))
|
|
98
|
+
return true;
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
function isUseful(text, allowShort = false) {
|
|
102
|
+
const t = text.trim();
|
|
103
|
+
if (t.length === 0)
|
|
104
|
+
return false;
|
|
105
|
+
if (isNoise(t))
|
|
106
|
+
return false;
|
|
107
|
+
if (!allowShort && t.length < MIN_USEFUL_LEN)
|
|
108
|
+
return false;
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
function formatTitle(text) {
|
|
112
|
+
let t = text.replace(/\r?\n/g, ' ').trim();
|
|
113
|
+
if (t.length > MAX_TITLE_LEN) {
|
|
114
|
+
t = t.slice(0, MAX_TITLE_LEN) + '…';
|
|
115
|
+
}
|
|
116
|
+
return t;
|
|
117
|
+
}
|
|
118
|
+
function parseLine(line) {
|
|
119
|
+
try {
|
|
120
|
+
const parsed = JSON.parse(line);
|
|
121
|
+
// Extract title from session_start events so newly created sessions
|
|
122
|
+
// appear in the displayable list instead of being hidden as "pending"
|
|
123
|
+
if (parsed.type === 'session_start') {
|
|
124
|
+
const title = typeof parsed.title === 'string' ? parsed.title.trim()
|
|
125
|
+
: typeof parsed.sessionTitle === 'string' ? parsed.sessionTitle.trim()
|
|
126
|
+
: '';
|
|
127
|
+
if (title) {
|
|
128
|
+
return { role: 'system', text: title };
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (parsed.type === 'todo_state')
|
|
133
|
+
return null;
|
|
134
|
+
let role;
|
|
135
|
+
let text = '';
|
|
136
|
+
if (parsed.message && typeof parsed.message === 'object') {
|
|
137
|
+
const msg = parsed.message;
|
|
138
|
+
role = typeof msg.role === 'string' ? msg.role : undefined;
|
|
139
|
+
const content = msg.content;
|
|
140
|
+
if (typeof content === 'string') {
|
|
141
|
+
text = stripSystemBoilerplate(content);
|
|
142
|
+
}
|
|
143
|
+
else if (Array.isArray(content)) {
|
|
144
|
+
const texts = content
|
|
145
|
+
.filter((c) => typeof c === 'object' && c !== null && c.type === 'text')
|
|
146
|
+
.map((c) => c.text)
|
|
147
|
+
.filter(Boolean)
|
|
148
|
+
.map((t) => stripSystemBoilerplate(t))
|
|
149
|
+
.filter(Boolean);
|
|
150
|
+
text = texts.join(' ');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (!text && typeof parsed.content === 'string') {
|
|
154
|
+
text = stripSystemBoilerplate(parsed.content);
|
|
155
|
+
}
|
|
156
|
+
if (!text && typeof parsed.text === 'string') {
|
|
157
|
+
text = stripSystemBoilerplate(parsed.text);
|
|
158
|
+
}
|
|
159
|
+
const sender = typeof parsed.sender === 'string' ? parsed.sender : undefined;
|
|
160
|
+
if (!text)
|
|
161
|
+
return null;
|
|
162
|
+
return { role: role || sender, sender, text };
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function extractTitleFromMessages(messages, fallback) {
|
|
169
|
+
// 1. First real user prompt
|
|
170
|
+
for (const m of messages) {
|
|
171
|
+
if ((m.role === 'user' || m.sender === 'user') && isUseful(m.text)) {
|
|
172
|
+
return formatTitle(m.text);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 2. First useful coding-agent response
|
|
176
|
+
for (const m of messages) {
|
|
177
|
+
if ((m.role === 'assistant' || m.sender === 'assistant') && isUseful(m.text)) {
|
|
178
|
+
return formatTitle(m.text);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// 3. Third message if meaningful
|
|
182
|
+
if (messages.length >= 3) {
|
|
183
|
+
const third = messages[2];
|
|
184
|
+
if (isUseful(third.text, true)) {
|
|
185
|
+
return formatTitle(third.text);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// 4. First message if meaningful (short allowed)
|
|
189
|
+
if (messages.length >= 1) {
|
|
190
|
+
const first = messages[0];
|
|
191
|
+
if (isUseful(first.text, true)) {
|
|
192
|
+
return formatTitle(first.text);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// 5. Fallback
|
|
196
|
+
return fallback;
|
|
197
|
+
}
|
|
198
|
+
/** Read deterministic title from a JSONL session file. */
|
|
199
|
+
export function extractTitleFromFile(filePath) {
|
|
200
|
+
if (!existsSync(filePath))
|
|
201
|
+
return basename(filePath, '.jsonl');
|
|
202
|
+
try {
|
|
203
|
+
const data = readFileSync(filePath, { encoding: 'utf-8', flag: 'r' });
|
|
204
|
+
const lines = data.split('\n').filter((l) => l.trim().length > 0);
|
|
205
|
+
const messages = [];
|
|
206
|
+
for (let i = 0; i < Math.min(lines.length, FIRST_LINES); i++) {
|
|
207
|
+
const parsed = parseLine(lines[i]);
|
|
208
|
+
if (parsed)
|
|
209
|
+
messages.push(parsed);
|
|
210
|
+
}
|
|
211
|
+
return extractTitleFromMessages(messages, basename(filePath, '.jsonl'));
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
return basename(filePath, '.jsonl');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/** Read deterministic title from OpenCode SQLite DB for a session. */
|
|
218
|
+
export function extractTitleFromOpenCode(dbPath, sessionId) {
|
|
219
|
+
if (!existsSync(dbPath))
|
|
220
|
+
return sessionId;
|
|
221
|
+
let db = null;
|
|
222
|
+
try {
|
|
223
|
+
db = new Database(dbPath, { readonly: true });
|
|
224
|
+
const rows = db.prepare(`SELECT data FROM message WHERE session_id = ? ORDER BY time_created ASC LIMIT ?`).all(sessionId, FIRST_LINES);
|
|
225
|
+
const messages = [];
|
|
226
|
+
for (const row of rows) {
|
|
227
|
+
if (!row.data)
|
|
228
|
+
continue;
|
|
229
|
+
const parsed = parseLine(row.data);
|
|
230
|
+
if (parsed)
|
|
231
|
+
messages.push(parsed);
|
|
232
|
+
}
|
|
233
|
+
return extractTitleFromMessages(messages, sessionId);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return sessionId;
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
if (db) {
|
|
240
|
+
try {
|
|
241
|
+
db.close();
|
|
242
|
+
}
|
|
243
|
+
catch { /* ignore */ }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/** Read a bounded sample of session text for on-demand summarization. */
|
|
248
|
+
export function readSessionSample(filePath, maxLines = 50, maxChars = 4000) {
|
|
249
|
+
if (!existsSync(filePath))
|
|
250
|
+
return '';
|
|
251
|
+
try {
|
|
252
|
+
const data = readFileSync(filePath, { encoding: 'utf-8', flag: 'r' });
|
|
253
|
+
const allLines = data.split('\n').filter((l) => l.trim().length > 0);
|
|
254
|
+
const textParts = [];
|
|
255
|
+
let charCount = 0;
|
|
256
|
+
// Read from the end of the file to get the most recent events
|
|
257
|
+
const startIdx = Math.max(0, allLines.length - maxLines);
|
|
258
|
+
for (let i = startIdx; i < allLines.length; i++) {
|
|
259
|
+
const parsed = parseLine(allLines[i]);
|
|
260
|
+
if (!parsed)
|
|
261
|
+
continue;
|
|
262
|
+
const text = parsed.text;
|
|
263
|
+
if (!text)
|
|
264
|
+
continue;
|
|
265
|
+
if (charCount + text.length > maxChars) {
|
|
266
|
+
textParts.push(text.slice(0, maxChars - charCount) + '…');
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
textParts.push(text);
|
|
270
|
+
charCount += text.length;
|
|
271
|
+
}
|
|
272
|
+
return textParts.join('\n').trim() || '';
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return '';
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/** Read a bounded sample from OpenCode SQLite for on-demand summarization. */
|
|
279
|
+
export function readOpenCodeSessionSample(dbPath, sessionId, maxLines = 50, maxChars = 4000) {
|
|
280
|
+
if (!existsSync(dbPath))
|
|
281
|
+
return '';
|
|
282
|
+
let db = null;
|
|
283
|
+
try {
|
|
284
|
+
db = new Database(dbPath, { readonly: true });
|
|
285
|
+
// Get the most recent events
|
|
286
|
+
const rows = db.prepare(`SELECT data FROM message WHERE session_id = ? ORDER BY time_created DESC LIMIT ?`).all(sessionId, maxLines);
|
|
287
|
+
rows.reverse();
|
|
288
|
+
const textParts = [];
|
|
289
|
+
let charCount = 0;
|
|
290
|
+
for (const row of rows) {
|
|
291
|
+
if (!row.data)
|
|
292
|
+
continue;
|
|
293
|
+
const parsed = parseLine(row.data);
|
|
294
|
+
if (!parsed)
|
|
295
|
+
continue;
|
|
296
|
+
const text = parsed.text;
|
|
297
|
+
if (!text)
|
|
298
|
+
continue;
|
|
299
|
+
if (charCount + text.length > maxChars) {
|
|
300
|
+
textParts.push(text.slice(0, maxChars - charCount) + '…');
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
textParts.push(text);
|
|
304
|
+
charCount += text.length;
|
|
305
|
+
}
|
|
306
|
+
return textParts.join('\n').trim() || '';
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
console.error('[SessionTitle] OpenCode sample error:', err);
|
|
310
|
+
return '';
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
if (db) {
|
|
314
|
+
try {
|
|
315
|
+
db.close();
|
|
316
|
+
}
|
|
317
|
+
catch { /* ignore */ }
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=sessionTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionTitle.js","sourceRoot":"","sources":["../src/sessionTitle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ContextSummary, TaskSuggestion, HumanNotes, GeneratedPrompt, SourceInfo, AppConfigSnapshot } from '../../shared/dist/index.js';
|
|
2
|
+
import type { RepoContext } from './repoContext.js';
|
|
3
|
+
declare class StateManager {
|
|
4
|
+
private summary;
|
|
5
|
+
private suggestions;
|
|
6
|
+
private notes;
|
|
7
|
+
private promptMap;
|
|
8
|
+
private sourceInfo;
|
|
9
|
+
private configSnapshot;
|
|
10
|
+
private repoContext;
|
|
11
|
+
getSummary(): ContextSummary | null;
|
|
12
|
+
getSuggestions(): TaskSuggestion[];
|
|
13
|
+
getNotes(): HumanNotes | null;
|
|
14
|
+
setSummary(summary: ContextSummary): void;
|
|
15
|
+
setSuggestions(suggestions: TaskSuggestion[]): void;
|
|
16
|
+
setNotes(notes: HumanNotes): void;
|
|
17
|
+
getPromptForTask(taskId: string): GeneratedPrompt | null;
|
|
18
|
+
setPromptForTask(taskId: string, prompt: GeneratedPrompt): void;
|
|
19
|
+
clearPromptMap(): void;
|
|
20
|
+
getSourceInfo(): SourceInfo;
|
|
21
|
+
setSourceInfo(info: SourceInfo): void;
|
|
22
|
+
getConfigSnapshot(): AppConfigSnapshot;
|
|
23
|
+
setConfigSnapshot(snapshot: AppConfigSnapshot): void;
|
|
24
|
+
getRepoContext(): RepoContext | null;
|
|
25
|
+
setRepoContext(ctx: RepoContext): void;
|
|
26
|
+
getState(): {
|
|
27
|
+
summary: ContextSummary | null;
|
|
28
|
+
suggestions: TaskSuggestion[];
|
|
29
|
+
notes: HumanNotes | null;
|
|
30
|
+
source: SourceInfo;
|
|
31
|
+
config: AppConfigSnapshot;
|
|
32
|
+
repoContext: RepoContext | null;
|
|
33
|
+
};
|
|
34
|
+
clear(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare const stateManager: StateManager;
|
|
37
|
+
export { StateManager };
|
|
38
|
+
//# sourceMappingURL=stateManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateManager.d.ts","sourceRoot":"","sources":["../src/stateManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChI,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,cAAM,YAAY;IAChB,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,UAAU,CAA2E;IAC7F,OAAO,CAAC,cAAc,CAAwF;IAC9G,OAAO,CAAC,WAAW,CAA4B;IAE/C,UAAU,IAAI,cAAc,GAAG,IAAI;IAInC,cAAc,IAAI,cAAc,EAAE;IAIlC,QAAQ,IAAI,UAAU,GAAG,IAAI;IAI7B,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIzC,cAAc,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI;IAWnD,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIjC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAIxD,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAI/D,cAAc,IAAI,IAAI;IAItB,aAAa,IAAI,UAAU;IAI3B,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIrC,iBAAiB,IAAI,iBAAiB;IAItC,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAIpD,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAItC,QAAQ,IAAI;QACV,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;QAC/B,WAAW,EAAE,cAAc,EAAE,CAAC;QAC9B,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;QACzB,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,iBAAiB,CAAC;QAC1B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;KACjC;IAWD,KAAK,IAAI,IAAI;CASd;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
class StateManager {
|
|
2
|
+
summary = null;
|
|
3
|
+
suggestions = [];
|
|
4
|
+
notes = null;
|
|
5
|
+
promptMap = new Map();
|
|
6
|
+
sourceInfo = { name: 'none', status: 'disconnected', lastEventAt: null };
|
|
7
|
+
configSnapshot = { activeSource: 'opencode', ollamaModel: 'falcon-h1r:7b-q4_K_M' };
|
|
8
|
+
repoContext = null;
|
|
9
|
+
getSummary() {
|
|
10
|
+
return this.summary;
|
|
11
|
+
}
|
|
12
|
+
getSuggestions() {
|
|
13
|
+
return [...this.suggestions];
|
|
14
|
+
}
|
|
15
|
+
getNotes() {
|
|
16
|
+
return this.notes ? { ...this.notes } : null;
|
|
17
|
+
}
|
|
18
|
+
setSummary(summary) {
|
|
19
|
+
this.summary = summary;
|
|
20
|
+
}
|
|
21
|
+
setSuggestions(suggestions) {
|
|
22
|
+
this.suggestions = [...suggestions];
|
|
23
|
+
// FIX: Remove orphan prompt entries whose tasks no longer exist
|
|
24
|
+
const activeIds = new Set(suggestions.map(s => s.id));
|
|
25
|
+
for (const id of this.promptMap.keys()) {
|
|
26
|
+
if (!activeIds.has(id)) {
|
|
27
|
+
this.promptMap.delete(id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
setNotes(notes) {
|
|
32
|
+
this.notes = { ...notes };
|
|
33
|
+
}
|
|
34
|
+
getPromptForTask(taskId) {
|
|
35
|
+
return this.promptMap.get(taskId) || null;
|
|
36
|
+
}
|
|
37
|
+
setPromptForTask(taskId, prompt) {
|
|
38
|
+
this.promptMap.set(taskId, prompt);
|
|
39
|
+
}
|
|
40
|
+
clearPromptMap() {
|
|
41
|
+
this.promptMap.clear();
|
|
42
|
+
}
|
|
43
|
+
getSourceInfo() {
|
|
44
|
+
return { ...this.sourceInfo };
|
|
45
|
+
}
|
|
46
|
+
setSourceInfo(info) {
|
|
47
|
+
this.sourceInfo = { ...info };
|
|
48
|
+
}
|
|
49
|
+
getConfigSnapshot() {
|
|
50
|
+
return { ...this.configSnapshot };
|
|
51
|
+
}
|
|
52
|
+
setConfigSnapshot(snapshot) {
|
|
53
|
+
this.configSnapshot = { ...snapshot };
|
|
54
|
+
}
|
|
55
|
+
getRepoContext() {
|
|
56
|
+
return this.repoContext;
|
|
57
|
+
}
|
|
58
|
+
setRepoContext(ctx) {
|
|
59
|
+
this.repoContext = ctx;
|
|
60
|
+
}
|
|
61
|
+
getState() {
|
|
62
|
+
return {
|
|
63
|
+
summary: this.summary,
|
|
64
|
+
suggestions: this.suggestions,
|
|
65
|
+
notes: this.notes,
|
|
66
|
+
source: this.sourceInfo,
|
|
67
|
+
config: this.configSnapshot,
|
|
68
|
+
repoContext: this.repoContext,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
clear() {
|
|
72
|
+
this.summary = null;
|
|
73
|
+
this.suggestions = [];
|
|
74
|
+
this.notes = null;
|
|
75
|
+
this.promptMap.clear();
|
|
76
|
+
this.sourceInfo = { name: 'none', status: 'disconnected', lastEventAt: null };
|
|
77
|
+
this.configSnapshot = { activeSource: 'opencode', ollamaModel: 'falcon-h1r:7b-q4_K_M' };
|
|
78
|
+
this.repoContext = null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export const stateManager = new StateManager();
|
|
82
|
+
export { StateManager };
|
|
83
|
+
//# sourceMappingURL=stateManager.js.map
|