@foothill/agent-move 1.0.9 → 1.0.10
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 +46 -9
- package/package.json +1 -1
- package/packages/client/dist/assets/{BufferResource-Ddjob236.js → BufferResource-Dfd5uHKt.js} +1 -1
- package/packages/client/dist/assets/{CanvasRenderer-B0w6SYyW.js → CanvasRenderer-7Cv6xZVP.js} +1 -1
- package/packages/client/dist/assets/{Filter-NcMGuiK-.js → Filter-CBX7EB7j.js} +1 -1
- package/packages/client/dist/assets/{RenderTargetSystem-DgAzY5_U.js → RenderTargetSystem-ko-v73NG.js} +1 -1
- package/packages/client/dist/assets/{WebGLRenderer-DUWXDPIX.js → WebGLRenderer-vhPQEPUG.js} +1 -1
- package/packages/client/dist/assets/{WebGPURenderer-C1HbrllR.js → WebGPURenderer-Dwywvwqe.js} +1 -1
- package/packages/client/dist/assets/{browserAll-CaF1Fl0O.js → browserAll-QyCAT8_K.js} +1 -1
- package/packages/client/dist/assets/index-BPJtz4FL.js +722 -0
- package/packages/client/dist/assets/{webworkerAll-BJ6UhC7r.js → webworkerAll-hM-gNP7L.js} +1 -1
- package/packages/client/dist/index.html +1 -1
- package/packages/server/dist/config.d.ts +4 -0
- package/packages/server/dist/config.d.ts.map +1 -1
- package/packages/server/dist/config.js +5 -1
- package/packages/server/dist/config.js.map +1 -1
- package/packages/server/dist/index.d.ts.map +1 -1
- package/packages/server/dist/index.js +790 -77
- package/packages/server/dist/index.js.map +1 -1
- package/packages/server/dist/state/activity-processor.d.ts +1 -1
- package/packages/server/dist/state/activity-processor.d.ts.map +1 -1
- package/packages/server/dist/state/activity-processor.js +1 -1
- package/packages/server/dist/state/activity-processor.js.map +1 -1
- package/packages/server/dist/state/agent-state-manager.d.ts +1 -2
- package/packages/server/dist/state/agent-state-manager.d.ts.map +1 -1
- package/packages/server/dist/state/agent-state-manager.js +87 -2
- package/packages/server/dist/state/agent-state-manager.js.map +1 -1
- package/packages/server/dist/state/role-resolver.d.ts +1 -2
- package/packages/server/dist/state/role-resolver.d.ts.map +1 -1
- package/packages/server/dist/state/role-resolver.js.map +1 -1
- package/packages/server/dist/state/task-graph-manager.d.ts +12 -0
- package/packages/server/dist/state/task-graph-manager.d.ts.map +1 -1
- package/packages/server/dist/state/task-graph-manager.js +80 -0
- package/packages/server/dist/state/task-graph-manager.js.map +1 -1
- package/packages/server/dist/watcher/claude/claude-paths.d.ts +18 -0
- package/packages/server/dist/watcher/claude/claude-paths.d.ts.map +1 -0
- package/packages/server/dist/watcher/{claude-paths.js → claude/claude-paths.js} +47 -55
- package/packages/server/dist/watcher/claude/claude-paths.js.map +1 -0
- package/packages/server/dist/watcher/{file-watcher.d.ts → claude/claude-watcher.d.ts} +3 -3
- package/packages/server/dist/watcher/claude/claude-watcher.d.ts.map +1 -0
- package/packages/server/dist/watcher/{file-watcher.js → claude/claude-watcher.js} +59 -65
- package/packages/server/dist/watcher/claude/claude-watcher.js.map +1 -0
- package/packages/server/dist/watcher/claude/jsonl-parser.d.ts +6 -0
- package/packages/server/dist/watcher/claude/jsonl-parser.d.ts.map +1 -0
- package/packages/server/dist/watcher/{jsonl-parser.js → claude/jsonl-parser.js} +1 -1
- package/packages/server/dist/watcher/claude/jsonl-parser.js.map +1 -0
- package/packages/server/dist/watcher/codex/codex-parser.d.ts +30 -0
- package/packages/server/dist/watcher/codex/codex-parser.d.ts.map +1 -0
- package/packages/server/dist/watcher/codex/codex-parser.js +326 -0
- package/packages/server/dist/watcher/codex/codex-parser.js.map +1 -0
- package/packages/server/dist/watcher/codex/codex-paths.d.ts +35 -0
- package/packages/server/dist/watcher/codex/codex-paths.d.ts.map +1 -0
- package/packages/server/dist/watcher/codex/codex-paths.js +46 -0
- package/packages/server/dist/watcher/codex/codex-paths.js.map +1 -0
- package/packages/server/dist/watcher/codex/codex-watcher.d.ts +42 -0
- package/packages/server/dist/watcher/codex/codex-watcher.d.ts.map +1 -0
- package/packages/server/dist/watcher/codex/codex-watcher.js +577 -0
- package/packages/server/dist/watcher/codex/codex-watcher.js.map +1 -0
- package/packages/server/dist/watcher/opencode/opencode-parser.d.ts +1 -1
- package/packages/server/dist/watcher/opencode/opencode-parser.d.ts.map +1 -1
- package/packages/server/dist/watcher/opencode/opencode-parser.js +31 -2
- package/packages/server/dist/watcher/opencode/opencode-paths.d.ts +1 -1
- package/packages/server/dist/watcher/opencode/opencode-paths.d.ts.map +1 -1
- package/packages/server/dist/watcher/opencode/opencode-paths.js +1 -0
- package/packages/server/dist/watcher/opencode/opencode-paths.js.map +1 -1
- package/packages/server/dist/watcher/opencode/opencode-watcher.d.ts.map +1 -1
- package/packages/server/dist/watcher/opencode/opencode-watcher.js +48 -10
- package/packages/server/dist/watcher/opencode/opencode-watcher.js.map +1 -1
- package/packages/server/dist/watcher/path-utils.d.ts +10 -0
- package/packages/server/dist/watcher/path-utils.d.ts.map +1 -0
- package/packages/server/dist/watcher/path-utils.js +38 -0
- package/packages/server/dist/watcher/path-utils.js.map +1 -0
- package/packages/server/dist/watcher/pi/pi-parser.d.ts +19 -0
- package/packages/server/dist/watcher/pi/pi-parser.d.ts.map +1 -0
- package/packages/server/dist/watcher/pi/pi-parser.js +307 -0
- package/packages/server/dist/watcher/pi/pi-parser.js.map +1 -0
- package/packages/server/dist/watcher/pi/pi-paths.d.ts +28 -0
- package/packages/server/dist/watcher/pi/pi-paths.d.ts.map +1 -0
- package/packages/server/dist/watcher/pi/pi-paths.js +86 -0
- package/packages/server/dist/watcher/pi/pi-paths.js.map +1 -0
- package/packages/server/dist/watcher/pi/pi-watcher.d.ts +36 -0
- package/packages/server/dist/watcher/pi/pi-watcher.d.ts.map +1 -0
- package/packages/server/dist/watcher/pi/pi-watcher.js +593 -0
- package/packages/server/dist/watcher/pi/pi-watcher.js.map +1 -0
- package/packages/server/dist/watcher/session-scanner.d.ts +9 -3
- package/packages/server/dist/watcher/session-scanner.d.ts.map +1 -1
- package/packages/server/dist/watcher/session-scanner.js +11 -9
- package/packages/server/dist/watcher/session-scanner.js.map +1 -1
- package/packages/server/dist/watcher/types.d.ts +30 -0
- package/packages/server/dist/watcher/types.d.ts.map +1 -0
- package/packages/server/dist/watcher/types.js +14 -0
- package/packages/server/dist/watcher/types.js.map +1 -0
- package/packages/shared/dist/constants/colors.d.ts +1 -1
- package/packages/shared/dist/constants/colors.js +1 -1
- package/packages/shared/dist/constants/colors.js.map +1 -1
- package/packages/shared/dist/constants/tools.d.ts.map +1 -1
- package/packages/shared/dist/constants/tools.js +30 -1
- package/packages/shared/dist/constants/tools.js.map +1 -1
- package/packages/shared/dist/index.d.ts +1 -1
- package/packages/shared/dist/index.d.ts.map +1 -1
- package/packages/shared/dist/types/agent.d.ts +3 -0
- package/packages/shared/dist/types/agent.d.ts.map +1 -1
- package/packages/client/dist/assets/index-Dh8yWoLP.js +0 -711
- package/packages/server/dist/watcher/claude-paths.d.ts +0 -32
- package/packages/server/dist/watcher/claude-paths.d.ts.map +0 -1
- package/packages/server/dist/watcher/claude-paths.js.map +0 -1
- package/packages/server/dist/watcher/file-watcher.d.ts.map +0 -1
- package/packages/server/dist/watcher/file-watcher.js.map +0 -1
- package/packages/server/dist/watcher/jsonl-parser.d.ts +0 -21
- package/packages/server/dist/watcher/jsonl-parser.d.ts.map +0 -1
- package/packages/server/dist/watcher/jsonl-parser.js.map +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { AgentStateManager } from '../../state/agent-state-manager.js';
|
|
2
|
+
import type { AgentWatcher } from '../agent-watcher.js';
|
|
3
|
+
/**
|
|
4
|
+
* Watches pi coding agent session JSONL files for new activity.
|
|
5
|
+
*
|
|
6
|
+
* Pi stores sessions at: ~/.pi/agent/sessions/--encoded-cwd--/{timestamp}_{uuid}.jsonl
|
|
7
|
+
* The JSONL format uses {type:"message", message:{...}} entries with tool calls
|
|
8
|
+
* as {type:"toolCall"} content blocks inside assistant messages.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PiWatcher implements AgentWatcher {
|
|
11
|
+
private stateManager;
|
|
12
|
+
private watcher;
|
|
13
|
+
private byteOffsets;
|
|
14
|
+
private parser;
|
|
15
|
+
/** Per-file lock to prevent concurrent processFile calls */
|
|
16
|
+
private fileLocks;
|
|
17
|
+
/** Cached session info per file (parsed from session header) */
|
|
18
|
+
private sessionInfoCache;
|
|
19
|
+
constructor(stateManager: AgentStateManager);
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
stop(): void;
|
|
22
|
+
private processFile;
|
|
23
|
+
private doProcessFile;
|
|
24
|
+
/**
|
|
25
|
+
* Extract a prefixed session ID from a pi session file path.
|
|
26
|
+
* Filename format: {timestamp}_{uuid}.jsonl
|
|
27
|
+
*/
|
|
28
|
+
private extractSessionId;
|
|
29
|
+
private buildFallbackSession;
|
|
30
|
+
/**
|
|
31
|
+
* Get the encoded project directory name from a session file path.
|
|
32
|
+
* Path: .../sessions/--encoded-path--/{timestamp}_{uuid}.jsonl
|
|
33
|
+
*/
|
|
34
|
+
private getProjectDirName;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=pi-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-watcher.d.ts","sourceRoot":"","sources":["../../../src/watcher/pi/pi-watcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAG5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMxD;;;;;;GAMG;AACH,qBAAa,SAAU,YAAW,YAAY;IAShC,OAAO,CAAC,YAAY;IARhC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,MAAM,CAAkB;IAChC,4DAA4D;IAC5D,OAAO,CAAC,SAAS,CAAoC;IACrD,gEAAgE;IAChE,OAAO,CAAC,gBAAgB,CAAkC;gBAEtC,YAAY,EAAE,iBAAiB;IAE7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoC5B,IAAI,IAAI,IAAI;IAOZ,OAAO,CAAC,WAAW;YAaL,aAAa;IAyD3B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB;IAM5B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;CAK1B"}
|
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
// dist/watcher/pi/pi-watcher.js
|
|
2
|
+
import chokidar from "chokidar";
|
|
3
|
+
import { stat as stat2, open } from "fs/promises";
|
|
4
|
+
import { join as join5, basename, dirname } from "path";
|
|
5
|
+
import { readdir, stat } from "fs/promises";
|
|
6
|
+
import { join as join2 } from "path";
|
|
7
|
+
import { homedir } from "os";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { homedir as homedir2 } from "os";
|
|
10
|
+
import { join as join4 } from "path";
|
|
11
|
+
import { existsSync as existsSync2 } from "fs";
|
|
12
|
+
import { join as join3 } from "path";
|
|
13
|
+
import { existsSync } from "fs";
|
|
14
|
+
function createFallbackSession(agentType, name) {
|
|
15
|
+
return {
|
|
16
|
+
agentType,
|
|
17
|
+
projectPath: name,
|
|
18
|
+
projectName: name,
|
|
19
|
+
isSubagent: false,
|
|
20
|
+
projectDir: name,
|
|
21
|
+
parentSessionId: null
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var TOOL_NAME_MAP = {
|
|
25
|
+
// OpenCode / pi lowercase → canonical PascalCase
|
|
26
|
+
read: "Read",
|
|
27
|
+
write: "Write",
|
|
28
|
+
edit: "Edit",
|
|
29
|
+
patch: "Patch",
|
|
30
|
+
glob: "Glob",
|
|
31
|
+
bash: "Bash",
|
|
32
|
+
grep: "Grep",
|
|
33
|
+
websearch: "WebSearch",
|
|
34
|
+
webfetch: "WebFetch",
|
|
35
|
+
todoread: "TodoRead",
|
|
36
|
+
todowrite: "TodoWrite",
|
|
37
|
+
// pi-specific tool names
|
|
38
|
+
"edit-diff": "Patch",
|
|
39
|
+
find: "Glob",
|
|
40
|
+
ls: "Bash",
|
|
41
|
+
truncate: "Write",
|
|
42
|
+
// Codex CLI tool names
|
|
43
|
+
shell_command: "Bash",
|
|
44
|
+
exec_command: "Bash",
|
|
45
|
+
read_file: "Read",
|
|
46
|
+
apply_patch: "Patch",
|
|
47
|
+
list_dir: "Bash",
|
|
48
|
+
grep_files: "Grep",
|
|
49
|
+
web_search: "WebSearch",
|
|
50
|
+
js_repl: "Bash",
|
|
51
|
+
js_repl_reset: "Bash",
|
|
52
|
+
spawn_agent: "Agent",
|
|
53
|
+
send_input: "Agent",
|
|
54
|
+
wait: "Agent",
|
|
55
|
+
close_agent: "Agent",
|
|
56
|
+
resume_agent: "Agent",
|
|
57
|
+
spawn_agents_on_csv: "Agent",
|
|
58
|
+
report_agent_job_result: "Agent",
|
|
59
|
+
request_user_input: "AskUserQuestion",
|
|
60
|
+
request_permissions: "AskUserQuestion",
|
|
61
|
+
update_plan: "TodoWrite",
|
|
62
|
+
view_image: "Read",
|
|
63
|
+
image_generation: "Write",
|
|
64
|
+
write_stdin: "Bash",
|
|
65
|
+
search_apps: "WebSearch"
|
|
66
|
+
};
|
|
67
|
+
function normalizeToolName(name) {
|
|
68
|
+
return TOOL_NAME_MAP[name] ?? name;
|
|
69
|
+
}
|
|
70
|
+
function normalizeToolInput(input) {
|
|
71
|
+
if (!("filePath" in input) && !("oldString" in input) && !("newString" in input) && !("replaceAll" in input)) {
|
|
72
|
+
return input;
|
|
73
|
+
}
|
|
74
|
+
const out = { ...input };
|
|
75
|
+
if ("filePath" in out) {
|
|
76
|
+
out.file_path = out.filePath;
|
|
77
|
+
delete out.filePath;
|
|
78
|
+
}
|
|
79
|
+
if ("oldString" in out) {
|
|
80
|
+
out.old_string = out.oldString;
|
|
81
|
+
delete out.oldString;
|
|
82
|
+
}
|
|
83
|
+
if ("newString" in out) {
|
|
84
|
+
out.new_string = out.newString;
|
|
85
|
+
delete out.newString;
|
|
86
|
+
}
|
|
87
|
+
if ("replaceAll" in out) {
|
|
88
|
+
out.replace_all = out.replaceAll;
|
|
89
|
+
delete out.replaceAll;
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
var ZONES = [
|
|
94
|
+
// Row 0
|
|
95
|
+
{
|
|
96
|
+
id: "search",
|
|
97
|
+
label: "Search",
|
|
98
|
+
description: "Grep, WebSearch \u2014 Research & lookup",
|
|
99
|
+
icon: "\u{1F4DA}",
|
|
100
|
+
color: 15381256,
|
|
101
|
+
colStart: 0,
|
|
102
|
+
colSpan: 5,
|
|
103
|
+
rowStart: 0,
|
|
104
|
+
rowSpan: 1,
|
|
105
|
+
x: 0,
|
|
106
|
+
y: 0,
|
|
107
|
+
width: 0,
|
|
108
|
+
height: 0
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "terminal",
|
|
112
|
+
label: "Terminal",
|
|
113
|
+
description: "Bash commands \u2014 Server room",
|
|
114
|
+
icon: "\u{1F4BB}",
|
|
115
|
+
color: 2278750,
|
|
116
|
+
colStart: 5,
|
|
117
|
+
colSpan: 3,
|
|
118
|
+
rowStart: 0,
|
|
119
|
+
rowSpan: 1,
|
|
120
|
+
x: 0,
|
|
121
|
+
y: 0,
|
|
122
|
+
width: 0,
|
|
123
|
+
height: 0
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
id: "web",
|
|
127
|
+
label: "Web",
|
|
128
|
+
description: "WebFetch, Browser \u2014 Network hub",
|
|
129
|
+
icon: "\u{1F310}",
|
|
130
|
+
color: 9133302,
|
|
131
|
+
colStart: 8,
|
|
132
|
+
colSpan: 4,
|
|
133
|
+
rowStart: 0,
|
|
134
|
+
rowSpan: 1,
|
|
135
|
+
x: 0,
|
|
136
|
+
y: 0,
|
|
137
|
+
width: 0,
|
|
138
|
+
height: 0
|
|
139
|
+
},
|
|
140
|
+
// Row 1
|
|
141
|
+
{
|
|
142
|
+
id: "files",
|
|
143
|
+
label: "Files",
|
|
144
|
+
description: "Read, Write, Edit, Glob \u2014 File storage",
|
|
145
|
+
icon: "\u{1F4C1}",
|
|
146
|
+
color: 3900150,
|
|
147
|
+
colStart: 0,
|
|
148
|
+
colSpan: 4,
|
|
149
|
+
rowStart: 1,
|
|
150
|
+
rowSpan: 1,
|
|
151
|
+
x: 0,
|
|
152
|
+
y: 0,
|
|
153
|
+
width: 0,
|
|
154
|
+
height: 0
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "thinking",
|
|
158
|
+
label: "Thinking",
|
|
159
|
+
description: "Planning, Questions \u2014 Conference area",
|
|
160
|
+
icon: "\u{1F4AD}",
|
|
161
|
+
color: 16347926,
|
|
162
|
+
colStart: 4,
|
|
163
|
+
colSpan: 5,
|
|
164
|
+
rowStart: 1,
|
|
165
|
+
rowSpan: 1,
|
|
166
|
+
x: 0,
|
|
167
|
+
y: 0,
|
|
168
|
+
width: 0,
|
|
169
|
+
height: 0
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
id: "messaging",
|
|
173
|
+
label: "Messaging",
|
|
174
|
+
description: "SendMessage, Teams \u2014 Chat & relax",
|
|
175
|
+
icon: "\u{1F4AC}",
|
|
176
|
+
color: 15485081,
|
|
177
|
+
colStart: 9,
|
|
178
|
+
colSpan: 3,
|
|
179
|
+
rowStart: 1,
|
|
180
|
+
rowSpan: 1,
|
|
181
|
+
x: 0,
|
|
182
|
+
y: 0,
|
|
183
|
+
width: 0,
|
|
184
|
+
height: 0
|
|
185
|
+
},
|
|
186
|
+
// Row 2
|
|
187
|
+
{
|
|
188
|
+
id: "spawn",
|
|
189
|
+
label: "Spawn",
|
|
190
|
+
description: "Agent spawn/despawn \u2014 Entry portal",
|
|
191
|
+
icon: "\u{1F300}",
|
|
192
|
+
color: 11032055,
|
|
193
|
+
colStart: 0,
|
|
194
|
+
colSpan: 3,
|
|
195
|
+
rowStart: 2,
|
|
196
|
+
rowSpan: 1,
|
|
197
|
+
x: 0,
|
|
198
|
+
y: 0,
|
|
199
|
+
width: 0,
|
|
200
|
+
height: 0
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
id: "idle",
|
|
204
|
+
label: "Idle",
|
|
205
|
+
description: "Idle agents rest here \u2014 Kitchen & lounge",
|
|
206
|
+
icon: "\u2615",
|
|
207
|
+
color: 7041664,
|
|
208
|
+
colStart: 3,
|
|
209
|
+
colSpan: 5,
|
|
210
|
+
rowStart: 2,
|
|
211
|
+
rowSpan: 1,
|
|
212
|
+
x: 0,
|
|
213
|
+
y: 0,
|
|
214
|
+
width: 0,
|
|
215
|
+
height: 0
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
id: "tasks",
|
|
219
|
+
label: "Tasks",
|
|
220
|
+
description: "TaskCreate, TaskUpdate \u2014 Kanban & planning",
|
|
221
|
+
icon: "\u{1F4CB}",
|
|
222
|
+
color: 1357990,
|
|
223
|
+
colStart: 8,
|
|
224
|
+
colSpan: 4,
|
|
225
|
+
rowStart: 2,
|
|
226
|
+
rowSpan: 1,
|
|
227
|
+
x: 0,
|
|
228
|
+
y: 0,
|
|
229
|
+
width: 0,
|
|
230
|
+
height: 0
|
|
231
|
+
}
|
|
232
|
+
];
|
|
233
|
+
var ZONE_MAP = new Map(ZONES.map((z) => [z.id, z]));
|
|
234
|
+
var PiParser = class {
|
|
235
|
+
/**
|
|
236
|
+
* Parse a single JSONL line from a pi session file into a raw object.
|
|
237
|
+
* Returns the parsed JSON, or null on parse error.
|
|
238
|
+
*/
|
|
239
|
+
parseRaw(line) {
|
|
240
|
+
try {
|
|
241
|
+
return JSON.parse(line);
|
|
242
|
+
} catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Extract a ParsedActivity from a pre-parsed JSONL entry.
|
|
248
|
+
* Returns null for non-actionable entries (session header, user messages, etc.).
|
|
249
|
+
*/
|
|
250
|
+
parseEntry(entry) {
|
|
251
|
+
if (entry.type !== "message")
|
|
252
|
+
return null;
|
|
253
|
+
const msg = entry.message;
|
|
254
|
+
if (!msg || msg.role !== "assistant")
|
|
255
|
+
return null;
|
|
256
|
+
return this.parseAssistantMessage(msg);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Check if a pre-parsed entry is a session header.
|
|
260
|
+
*/
|
|
261
|
+
isSessionHeader(entry) {
|
|
262
|
+
return entry.type === "session";
|
|
263
|
+
}
|
|
264
|
+
parseAssistantMessage(msg) {
|
|
265
|
+
const content = msg.content;
|
|
266
|
+
if (!Array.isArray(content))
|
|
267
|
+
return null;
|
|
268
|
+
for (const block of content) {
|
|
269
|
+
if (block.type === "toolCall") {
|
|
270
|
+
const tool = block;
|
|
271
|
+
return {
|
|
272
|
+
type: "tool_use",
|
|
273
|
+
toolName: normalizeToolName(tool.name),
|
|
274
|
+
toolInput: normalizeToolInput(tool.arguments ?? {}),
|
|
275
|
+
model: msg.model,
|
|
276
|
+
inputTokens: msg.usage?.input,
|
|
277
|
+
outputTokens: msg.usage?.output,
|
|
278
|
+
cacheReadTokens: msg.usage?.cacheRead,
|
|
279
|
+
cacheCreationTokens: msg.usage?.cacheWrite
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
for (const block of content) {
|
|
284
|
+
if (block.type === "text") {
|
|
285
|
+
const text = block.text?.trim() ?? "";
|
|
286
|
+
if (text.length > 0 && text.length < 200) {
|
|
287
|
+
return {
|
|
288
|
+
type: "text",
|
|
289
|
+
text,
|
|
290
|
+
model: msg.model,
|
|
291
|
+
inputTokens: msg.usage?.input,
|
|
292
|
+
outputTokens: msg.usage?.output,
|
|
293
|
+
cacheReadTokens: msg.usage?.cacheRead,
|
|
294
|
+
cacheCreationTokens: msg.usage?.cacheWrite
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
for (const block of content) {
|
|
300
|
+
if (block.type === "thinking") {
|
|
301
|
+
const thinking = block.thinking?.trim() ?? "";
|
|
302
|
+
return {
|
|
303
|
+
type: "tool_use",
|
|
304
|
+
toolName: "thinking",
|
|
305
|
+
toolInput: thinking.length > 0 ? { thought: thinking.slice(0, 120) } : void 0,
|
|
306
|
+
model: msg.model,
|
|
307
|
+
inputTokens: msg.usage?.input,
|
|
308
|
+
outputTokens: msg.usage?.output,
|
|
309
|
+
cacheReadTokens: msg.usage?.cacheRead,
|
|
310
|
+
cacheCreationTokens: msg.usage?.cacheWrite
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (msg.usage && (msg.usage.input || msg.usage.output)) {
|
|
315
|
+
return {
|
|
316
|
+
type: "token_usage",
|
|
317
|
+
inputTokens: msg.usage.input,
|
|
318
|
+
outputTokens: msg.usage.output,
|
|
319
|
+
cacheReadTokens: msg.usage.cacheRead,
|
|
320
|
+
cacheCreationTokens: msg.usage.cacheWrite,
|
|
321
|
+
model: msg.model
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
var config = {
|
|
328
|
+
port: parseInt(process.env.AGENT_MOVE_PORT || "3333", 10),
|
|
329
|
+
claudeHome: join(homedir(), ".claude"),
|
|
330
|
+
idleTimeoutMs: 45e3,
|
|
331
|
+
/** How long after going idle before an agent is automatically shutdown/removed */
|
|
332
|
+
shutdownTimeoutMs: 30 * 60 * 1e3,
|
|
333
|
+
// 30 minutes
|
|
334
|
+
/** How recently a session file must be modified to be considered "active" on startup */
|
|
335
|
+
activeThresholdMs: 10 * 60 * 1e3,
|
|
336
|
+
// 10 minutes
|
|
337
|
+
/** Enable OpenCode session watching (auto-detected if storage dir exists) */
|
|
338
|
+
enableOpenCode: process.env.AGENT_MOVE_OPENCODE !== "false",
|
|
339
|
+
/** Enable pi coding agent session watching (auto-detected if sessions dir exists) */
|
|
340
|
+
enablePi: process.env.AGENT_MOVE_PI !== "false",
|
|
341
|
+
/** Enable Codex CLI session watching (auto-detected if sessions dir exists) */
|
|
342
|
+
enableCodex: process.env.AGENT_MOVE_CODEX !== "false"
|
|
343
|
+
};
|
|
344
|
+
var SessionScanner = class {
|
|
345
|
+
rootDir;
|
|
346
|
+
constructor(rootDir) {
|
|
347
|
+
this.rootDir = rootDir;
|
|
348
|
+
}
|
|
349
|
+
/** Find the most recently modified JSONL per project subdirectory */
|
|
350
|
+
async scan() {
|
|
351
|
+
const results = [];
|
|
352
|
+
try {
|
|
353
|
+
const projects = await readdir(this.rootDir);
|
|
354
|
+
const now = Date.now();
|
|
355
|
+
for (const project of projects) {
|
|
356
|
+
const projectDir = join2(this.rootDir, project);
|
|
357
|
+
try {
|
|
358
|
+
const projectStat = await stat(projectDir);
|
|
359
|
+
if (!projectStat.isDirectory())
|
|
360
|
+
continue;
|
|
361
|
+
const files = await readdir(projectDir);
|
|
362
|
+
let newestFile = null;
|
|
363
|
+
let newestMtime = 0;
|
|
364
|
+
for (const file of files) {
|
|
365
|
+
if (!file.endsWith(".jsonl"))
|
|
366
|
+
continue;
|
|
367
|
+
const filePath = join2(projectDir, file);
|
|
368
|
+
try {
|
|
369
|
+
const fileStat = await stat(filePath);
|
|
370
|
+
if (now - fileStat.mtimeMs < config.activeThresholdMs) {
|
|
371
|
+
if (fileStat.mtimeMs > newestMtime) {
|
|
372
|
+
newestMtime = fileStat.mtimeMs;
|
|
373
|
+
newestFile = filePath;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
} catch {
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (newestFile) {
|
|
380
|
+
results.push(newestFile);
|
|
381
|
+
}
|
|
382
|
+
} catch {
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
} catch {
|
|
386
|
+
}
|
|
387
|
+
return results;
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
function resolveEncodedPath(root, segments) {
|
|
391
|
+
try {
|
|
392
|
+
const parts = segments.split("-").filter(Boolean);
|
|
393
|
+
let currentPath = root;
|
|
394
|
+
let lastName = "";
|
|
395
|
+
let i = 0;
|
|
396
|
+
while (i < parts.length) {
|
|
397
|
+
let found = false;
|
|
398
|
+
const maxLen = Math.min(parts.length - i, 6);
|
|
399
|
+
for (let len = 1; len <= maxLen; len++) {
|
|
400
|
+
const segment = parts.slice(i, i + len).join("-");
|
|
401
|
+
for (const prefix of ["", "."]) {
|
|
402
|
+
const testPath = join3(currentPath, prefix + segment);
|
|
403
|
+
if (existsSync(testPath)) {
|
|
404
|
+
currentPath = testPath;
|
|
405
|
+
lastName = prefix + segment;
|
|
406
|
+
i += len;
|
|
407
|
+
found = true;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (found)
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
if (!found)
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
return lastName || null;
|
|
418
|
+
} catch {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function getPiSessionsDir() {
|
|
423
|
+
const candidate = join4(homedir2(), ".pi", "agent", "sessions");
|
|
424
|
+
return existsSync2(candidate) ? candidate : null;
|
|
425
|
+
}
|
|
426
|
+
function decodePiProjectDir(encoded) {
|
|
427
|
+
let inner = encoded;
|
|
428
|
+
if (inner.startsWith("--") && inner.endsWith("--")) {
|
|
429
|
+
inner = inner.slice(2, -2);
|
|
430
|
+
}
|
|
431
|
+
const driveMatch = inner.match(/^([A-Za-z])--(.*)/);
|
|
432
|
+
if (driveMatch) {
|
|
433
|
+
const resolved = resolveEncodedPath(driveMatch[1] + ":/", driveMatch[2]);
|
|
434
|
+
if (resolved)
|
|
435
|
+
return resolved;
|
|
436
|
+
} else {
|
|
437
|
+
const resolved = resolveEncodedPath("/", inner);
|
|
438
|
+
if (resolved)
|
|
439
|
+
return resolved;
|
|
440
|
+
}
|
|
441
|
+
const parts = inner.split("-").filter(Boolean);
|
|
442
|
+
if (parts.length <= 2)
|
|
443
|
+
return parts.join("/");
|
|
444
|
+
return parts.slice(-2).join("-");
|
|
445
|
+
}
|
|
446
|
+
function parsePiSessionInfo(header, dirName) {
|
|
447
|
+
const projectName = decodePiProjectDir(dirName);
|
|
448
|
+
return {
|
|
449
|
+
agentType: "pi",
|
|
450
|
+
projectPath: header.cwd || dirName,
|
|
451
|
+
projectName,
|
|
452
|
+
isSubagent: !!header.parentSession,
|
|
453
|
+
projectDir: dirName,
|
|
454
|
+
parentSessionId: header.parentSession ? extractSessionIdFromPath(header.parentSession) : null
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function extractSessionIdFromPath(filePath) {
|
|
458
|
+
const match = filePath.match(/([^/\\]+)\.jsonl$/);
|
|
459
|
+
if (!match)
|
|
460
|
+
return null;
|
|
461
|
+
const parts = match[1].split("_");
|
|
462
|
+
const uuid = parts[parts.length - 1];
|
|
463
|
+
return uuid ? `pi:${uuid}` : null;
|
|
464
|
+
}
|
|
465
|
+
var PiWatcher = class {
|
|
466
|
+
stateManager;
|
|
467
|
+
watcher = null;
|
|
468
|
+
byteOffsets = /* @__PURE__ */ new Map();
|
|
469
|
+
parser = new PiParser();
|
|
470
|
+
/** Per-file lock to prevent concurrent processFile calls */
|
|
471
|
+
fileLocks = /* @__PURE__ */ new Map();
|
|
472
|
+
/** Cached session info per file (parsed from session header) */
|
|
473
|
+
sessionInfoCache = /* @__PURE__ */ new Map();
|
|
474
|
+
constructor(stateManager) {
|
|
475
|
+
this.stateManager = stateManager;
|
|
476
|
+
}
|
|
477
|
+
async start() {
|
|
478
|
+
const sessionsDir = getPiSessionsDir();
|
|
479
|
+
if (!sessionsDir) {
|
|
480
|
+
console.log("[pi] No sessions directory found \u2014 pi not installed or not yet used");
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
console.log(`[pi] Sessions directory found at ${sessionsDir}`);
|
|
484
|
+
const scanner = new SessionScanner(sessionsDir);
|
|
485
|
+
const existingFiles = await scanner.scan();
|
|
486
|
+
for (const file of existingFiles) {
|
|
487
|
+
await this.processFile(file);
|
|
488
|
+
}
|
|
489
|
+
const pattern = join5(sessionsDir, "**", "*.jsonl");
|
|
490
|
+
this.watcher = chokidar.watch(pattern, {
|
|
491
|
+
persistent: true,
|
|
492
|
+
ignoreInitial: true,
|
|
493
|
+
awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
|
|
494
|
+
});
|
|
495
|
+
this.watcher.on("add", (filePath) => {
|
|
496
|
+
console.log(`[pi] New session file: ${filePath}`);
|
|
497
|
+
this.processFile(filePath);
|
|
498
|
+
});
|
|
499
|
+
this.watcher.on("change", (filePath) => {
|
|
500
|
+
this.processFile(filePath);
|
|
501
|
+
});
|
|
502
|
+
console.log(`[pi] Watching for JSONL files in ${sessionsDir}`);
|
|
503
|
+
}
|
|
504
|
+
stop() {
|
|
505
|
+
this.watcher?.close();
|
|
506
|
+
this.byteOffsets.clear();
|
|
507
|
+
this.fileLocks.clear();
|
|
508
|
+
this.sessionInfoCache.clear();
|
|
509
|
+
}
|
|
510
|
+
processFile(filePath) {
|
|
511
|
+
const prev = this.fileLocks.get(filePath) ?? Promise.resolve();
|
|
512
|
+
const next = prev.then(() => this.doProcessFile(filePath)).catch(() => {
|
|
513
|
+
}).finally(() => {
|
|
514
|
+
if (this.fileLocks.get(filePath) === next) {
|
|
515
|
+
this.fileLocks.delete(filePath);
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
this.fileLocks.set(filePath, next);
|
|
519
|
+
}
|
|
520
|
+
async doProcessFile(filePath) {
|
|
521
|
+
try {
|
|
522
|
+
const fileStats = await stat2(filePath);
|
|
523
|
+
const currentOffset = this.byteOffsets.get(filePath) ?? 0;
|
|
524
|
+
if (fileStats.size <= currentOffset)
|
|
525
|
+
return;
|
|
526
|
+
const handle = await open(filePath, "r");
|
|
527
|
+
try {
|
|
528
|
+
const buffer = Buffer.alloc(fileStats.size - currentOffset);
|
|
529
|
+
await handle.read(buffer, 0, buffer.length, currentOffset);
|
|
530
|
+
this.byteOffsets.set(filePath, fileStats.size);
|
|
531
|
+
const newContent = buffer.toString("utf-8");
|
|
532
|
+
const lines = newContent.split("\n").filter((l) => l.trim());
|
|
533
|
+
const sessionId = this.extractSessionId(filePath);
|
|
534
|
+
let sessionInfo = this.sessionInfoCache.get(filePath);
|
|
535
|
+
let hadParsedActivity = false;
|
|
536
|
+
for (const line of lines) {
|
|
537
|
+
const raw = this.parser.parseRaw(line);
|
|
538
|
+
if (!raw)
|
|
539
|
+
continue;
|
|
540
|
+
if (!sessionInfo && this.parser.isSessionHeader(raw)) {
|
|
541
|
+
const dirName = this.getProjectDirName(filePath);
|
|
542
|
+
sessionInfo = parsePiSessionInfo(raw, dirName);
|
|
543
|
+
this.sessionInfoCache.set(filePath, sessionInfo);
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
const parsed = this.parser.parseEntry(raw);
|
|
547
|
+
if (parsed) {
|
|
548
|
+
hadParsedActivity = true;
|
|
549
|
+
if (!sessionInfo) {
|
|
550
|
+
sessionInfo = this.buildFallbackSession(filePath);
|
|
551
|
+
this.sessionInfoCache.set(filePath, sessionInfo);
|
|
552
|
+
}
|
|
553
|
+
this.stateManager.processMessage(sessionId, parsed, sessionInfo);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (!hadParsedActivity && lines.length > 0) {
|
|
557
|
+
this.stateManager.heartbeat(sessionId);
|
|
558
|
+
}
|
|
559
|
+
} finally {
|
|
560
|
+
await handle.close();
|
|
561
|
+
}
|
|
562
|
+
} catch (err) {
|
|
563
|
+
if (err.code !== "ENOENT") {
|
|
564
|
+
console.error(`[pi] Error processing ${filePath}:`, err);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Extract a prefixed session ID from a pi session file path.
|
|
570
|
+
* Filename format: {timestamp}_{uuid}.jsonl
|
|
571
|
+
*/
|
|
572
|
+
extractSessionId(filePath) {
|
|
573
|
+
const name = basename(filePath, ".jsonl");
|
|
574
|
+
return `pi:${name}`;
|
|
575
|
+
}
|
|
576
|
+
buildFallbackSession(filePath) {
|
|
577
|
+
const dirName = this.getProjectDirName(filePath);
|
|
578
|
+
const name = dirName.replace(/^--|--$/g, "") || "pi";
|
|
579
|
+
return createFallbackSession("pi", name);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Get the encoded project directory name from a session file path.
|
|
583
|
+
* Path: .../sessions/--encoded-path--/{timestamp}_{uuid}.jsonl
|
|
584
|
+
*/
|
|
585
|
+
getProjectDirName(filePath) {
|
|
586
|
+
const dir = dirname(filePath).replace(/\\/g, "/");
|
|
587
|
+
const parts = dir.split("/");
|
|
588
|
+
return parts[parts.length - 1] || "unknown";
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
export {
|
|
592
|
+
PiWatcher
|
|
593
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-watcher.js","sourceRoot":"","sources":["../../../src/watcher/pi/pi-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGrE;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IASA;IARZ,OAAO,GAA8B,IAAI,CAAC;IAC1C,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;IAChC,4DAA4D;IACpD,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IACrD,gEAAgE;IACxD,gBAAgB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE1D,YAAoB,YAA+B;QAA/B,iBAAY,GAAZ,YAAY,CAAmB;IAAG,CAAC;IAEvD,KAAK,CAAC,KAAK;QACT,MAAM,WAAW,GAAG,gBAAgB,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,EAAE,CAAC,CAAC;QAE/D,2DAA2D;QAC3D,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;QAChD,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAE3C,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE;YACrC,UAAU,EAAE,IAAI;YAChB,aAAa,EAAE,IAAI;YACnB,gBAAgB,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE;SAChE,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;YAClC,OAAO,CAAC,GAAG,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE;YACrC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IAEO,WAAW,CAAC,QAAgB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,IAAI;aACd,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;aACxC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;aACf,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC1C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QACL,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,QAAgB;QAC1C,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAE1D,IAAI,SAAS,CAAC,IAAI,IAAI,aAAa;gBAAE,OAAO;YAE5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,aAAa,CAAC,CAAC;gBAC5D,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;gBAC3D,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;gBAE/C,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAE7D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;gBAClD,IAAI,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAEtD,IAAI,iBAAiB,GAAG,KAAK,CAAC;gBAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACvC,IAAI,CAAC,GAAG;wBAAE,SAAS;oBAEnB,8DAA8D;oBAC9D,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;wBACrD,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;wBACjD,WAAW,GAAG,kBAAkB,CAAC,GAAiC,EAAE,OAAO,CAAC,CAAC;wBAC7E,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;wBACjD,SAAS;oBACX,CAAC;oBAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC3C,IAAI,MAAM,EAAE,CAAC;wBACX,iBAAiB,GAAG,IAAI,CAAC;wBACzB,IAAI,CAAC,WAAW,EAAE,CAAC;4BACjB,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;4BAClD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;wBACnD,CAAC;wBACD,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;oBACnE,CAAC;gBACH,CAAC;gBAED,gEAAgE;gBAChE,IAAI,CAAC,iBAAiB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3C,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,OAAO,CAAC,KAAK,CAAC,yBAAyB,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,gBAAgB,CAAC,QAAgB;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1C,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAEO,oBAAoB,CAAC,QAAgB;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QACrD,OAAO,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;OAGG;IACK,iBAAiB,CAAC,QAAgB;QACxC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scans a directory of project subdirectories for recently active JSONL files.
|
|
3
|
+
* Used by both Claude and pi watchers — each passes its own root directory.
|
|
4
|
+
*
|
|
5
|
+
* Directory structure: {rootDir}/{project-dir}/*.jsonl
|
|
6
|
+
*/
|
|
1
7
|
export declare class SessionScanner {
|
|
2
|
-
private
|
|
3
|
-
constructor(
|
|
4
|
-
/** Find
|
|
8
|
+
private rootDir;
|
|
9
|
+
constructor(rootDir: string);
|
|
10
|
+
/** Find the most recently modified JSONL per project subdirectory */
|
|
5
11
|
scan(): Promise<string[]>;
|
|
6
12
|
}
|
|
7
13
|
//# sourceMappingURL=session-scanner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-scanner.d.ts","sourceRoot":"","sources":["../../src/watcher/session-scanner.ts"],"names":[],"mappings":"AAIA,qBAAa,cAAc;IACb,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"session-scanner.d.ts","sourceRoot":"","sources":["../../src/watcher/session-scanner.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEnC,qEAAqE;IAC/D,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CA+ChC"}
|