tailii-host 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/LICENSE +21 -0
- package/README.md +51 -0
- package/dist/apnsConfigStore.d.ts +22 -0
- package/dist/apnsConfigStore.js +50 -0
- package/dist/apnsConfigStore.js.map +1 -0
- package/dist/apnsJwtProvider.d.ts +50 -0
- package/dist/apnsJwtProvider.js +158 -0
- package/dist/apnsJwtProvider.js.map +1 -0
- package/dist/apnsSender.d.ts +69 -0
- package/dist/apnsSender.js +155 -0
- package/dist/apnsSender.js.map +1 -0
- package/dist/approvalPushNotifier.d.ts +100 -0
- package/dist/approvalPushNotifier.js +236 -0
- package/dist/approvalPushNotifier.js.map +1 -0
- package/dist/broker.d.ts +24 -0
- package/dist/broker.js +197 -0
- package/dist/broker.js.map +1 -0
- package/dist/chatTailController.d.ts +87 -0
- package/dist/chatTailController.js +292 -0
- package/dist/chatTailController.js.map +1 -0
- package/dist/claudeSessionStore.d.ts +15 -0
- package/dist/claudeSessionStore.js +201 -0
- package/dist/claudeSessionStore.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/codexRolloutTailer.d.ts +56 -0
- package/dist/codexRolloutTailer.js +303 -0
- package/dist/codexRolloutTailer.js.map +1 -0
- package/dist/codexSessionStore.d.ts +23 -0
- package/dist/codexSessionStore.js +274 -0
- package/dist/codexSessionStore.js.map +1 -0
- package/dist/codexUsage.d.ts +16 -0
- package/dist/codexUsage.js +144 -0
- package/dist/codexUsage.js.map +1 -0
- package/dist/deviceTokenStore.d.ts +38 -0
- package/dist/deviceTokenStore.js +73 -0
- package/dist/deviceTokenStore.js.map +1 -0
- package/dist/dirLister.d.ts +9 -0
- package/dist/dirLister.js +98 -0
- package/dist/dirLister.js.map +1 -0
- package/dist/doctor.d.ts +36 -0
- package/dist/doctor.js +162 -0
- package/dist/doctor.js.map +1 -0
- package/dist/engine.d.ts +85 -0
- package/dist/engine.js +962 -0
- package/dist/engine.js.map +1 -0
- package/dist/hook.d.ts +67 -0
- package/dist/hook.js +511 -0
- package/dist/hook.js.map +1 -0
- package/dist/hookSettings.d.ts +40 -0
- package/dist/hookSettings.js +128 -0
- package/dist/hookSettings.js.map +1 -0
- package/dist/idleReaper.d.ts +13 -0
- package/dist/idleReaper.js +30 -0
- package/dist/idleReaper.js.map +1 -0
- package/dist/imageService.d.ts +53 -0
- package/dist/imageService.js +280 -0
- package/dist/imageService.js.map +1 -0
- package/dist/kick.d.ts +8 -0
- package/dist/kick.js +60 -0
- package/dist/kick.js.map +1 -0
- package/dist/launch.d.ts +107 -0
- package/dist/launch.js +396 -0
- package/dist/launch.js.map +1 -0
- package/dist/legacyHomeMigration.d.ts +1 -0
- package/dist/legacyHomeMigration.js +23 -0
- package/dist/legacyHomeMigration.js.map +1 -0
- package/dist/lineWriter.d.ts +9 -0
- package/dist/lineWriter.js +19 -0
- package/dist/lineWriter.js.map +1 -0
- package/dist/mdnsAdvertiser.d.ts +46 -0
- package/dist/mdnsAdvertiser.js +268 -0
- package/dist/mdnsAdvertiser.js.map +1 -0
- package/dist/observationLog.d.ts +54 -0
- package/dist/observationLog.js +108 -0
- package/dist/observationLog.js.map +1 -0
- package/dist/pairingCode.d.ts +60 -0
- package/dist/pairingCode.js +282 -0
- package/dist/pairingCode.js.map +1 -0
- package/dist/paths.d.ts +13 -0
- package/dist/paths.js +46 -0
- package/dist/paths.js.map +1 -0
- package/dist/permissionMode.d.ts +8 -0
- package/dist/permissionMode.js +32 -0
- package/dist/permissionMode.js.map +1 -0
- package/dist/planUsageFetcher.d.ts +35 -0
- package/dist/planUsageFetcher.js +172 -0
- package/dist/planUsageFetcher.js.map +1 -0
- package/dist/protocol.d.ts +329 -0
- package/dist/protocol.js +544 -0
- package/dist/protocol.js.map +1 -0
- package/dist/pushTokenCommand.d.ts +9 -0
- package/dist/pushTokenCommand.js +85 -0
- package/dist/pushTokenCommand.js.map +1 -0
- package/dist/pushTypes.d.ts +41 -0
- package/dist/pushTypes.js +68 -0
- package/dist/pushTypes.js.map +1 -0
- package/dist/sendLog.d.ts +14 -0
- package/dist/sendLog.js +64 -0
- package/dist/sendLog.js.map +1 -0
- package/dist/sessionActivityProvider.d.ts +7 -0
- package/dist/sessionActivityProvider.js +44 -0
- package/dist/sessionActivityProvider.js.map +1 -0
- package/dist/sessionIdleTracker.d.ts +19 -0
- package/dist/sessionIdleTracker.js +42 -0
- package/dist/sessionIdleTracker.js.map +1 -0
- package/dist/sessionListService.d.ts +27 -0
- package/dist/sessionListService.js +85 -0
- package/dist/sessionListService.js.map +1 -0
- package/dist/sessionMetadataStore.d.ts +33 -0
- package/dist/sessionMetadataStore.js +122 -0
- package/dist/sessionMetadataStore.js.map +1 -0
- package/dist/sessionSearch.d.ts +29 -0
- package/dist/sessionSearch.js +139 -0
- package/dist/sessionSearch.js.map +1 -0
- package/dist/setup.d.ts +83 -0
- package/dist/setup.js +412 -0
- package/dist/setup.js.map +1 -0
- package/dist/sleep.d.ts +4 -0
- package/dist/sleep.js +25 -0
- package/dist/sleep.js.map +1 -0
- package/dist/socketPath.d.ts +12 -0
- package/dist/socketPath.js +51 -0
- package/dist/socketPath.js.map +1 -0
- package/dist/subagentTailer.d.ts +15 -0
- package/dist/subagentTailer.js +399 -0
- package/dist/subagentTailer.js.map +1 -0
- package/dist/tmux.d.ts +62 -0
- package/dist/tmux.js +163 -0
- package/dist/tmux.js.map +1 -0
- package/dist/transcriptTailer.d.ts +61 -0
- package/dist/transcriptTailer.js +606 -0
- package/dist/transcriptTailer.js.map +1 -0
- package/dist/usageAggregator.d.ts +12 -0
- package/dist/usageAggregator.js +55 -0
- package/dist/usageAggregator.js.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.js +45 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
// subagentTailer.ts
|
|
2
|
+
// tailii (TS host) — サブエージェント進捗ツリー tail
|
|
3
|
+
// Swift 版 SubagentTailer.swift の移植。
|
|
4
|
+
// claude の `<sessionId>/subagents/agent-*.meta.json` と main/subagent transcript を監視し、
|
|
5
|
+
// subagent_node(spawn/running → completed/error)を engine チャネルへ流す。
|
|
6
|
+
import * as fs from "node:fs";
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import { PROTOCOL_V2 } from "./protocol.js";
|
|
9
|
+
import { abortableSleep } from "./sleep.js";
|
|
10
|
+
import { extractToolActivities, TranscriptTailer } from "./transcriptTailer.js";
|
|
11
|
+
/** サブエージェント meta/jsonl と親 transcript の tool_result を監視する。 */
|
|
12
|
+
export class SubagentTailer {
|
|
13
|
+
pollIntervalMs;
|
|
14
|
+
tailIndefinitely;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
this.pollIntervalMs = options.pollIntervalMs ?? 50;
|
|
17
|
+
this.tailIndefinitely = options.tailIndefinitely ?? true;
|
|
18
|
+
}
|
|
19
|
+
async *streamProjectDir(projectDir, preferredSessionId, newerThanMs = null, signal) {
|
|
20
|
+
const start = Date.now();
|
|
21
|
+
let mainTranscript = null;
|
|
22
|
+
while (!signal?.aborted) {
|
|
23
|
+
mainTranscript = TranscriptTailer.resolveJsonl(projectDir, preferredSessionId, newerThanMs);
|
|
24
|
+
if (mainTranscript !== null)
|
|
25
|
+
break;
|
|
26
|
+
if (!this.tailIndefinitely)
|
|
27
|
+
return;
|
|
28
|
+
await abortableSleep(this.pollIntervalMs, signal);
|
|
29
|
+
if (!this.tailIndefinitely && Date.now() - start > this.pollIntervalMs)
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (mainTranscript === null || signal?.aborted)
|
|
33
|
+
return;
|
|
34
|
+
yield* this.streamSession(mainTranscript, signal);
|
|
35
|
+
}
|
|
36
|
+
async *streamSession(mainTranscript, signal) {
|
|
37
|
+
const sessionId = path.basename(mainTranscript, ".jsonl");
|
|
38
|
+
const subagentsDir = path.join(path.dirname(mainTranscript), sessionId, "subagents");
|
|
39
|
+
const tracked = new Map();
|
|
40
|
+
const fileStates = new Map();
|
|
41
|
+
const ownerByToolUseId = new Map();
|
|
42
|
+
const resultByToolUseId = new Map();
|
|
43
|
+
let aggregateDirty = true;
|
|
44
|
+
while (!signal?.aborted) {
|
|
45
|
+
if (discoverMetaFiles(subagentsDir, tracked))
|
|
46
|
+
aggregateDirty = true;
|
|
47
|
+
const transcriptOwners = transcriptFiles(mainTranscript, tracked);
|
|
48
|
+
for (const transcript of transcriptOwners) {
|
|
49
|
+
const read = readNewLines(transcript.path, fileStates);
|
|
50
|
+
const node = transcript.nodeId === null ? null : (tracked.get(transcript.nodeId) ?? null);
|
|
51
|
+
if (read.reset) {
|
|
52
|
+
aggregateDirty = true;
|
|
53
|
+
if (node !== null)
|
|
54
|
+
node.currentActivity = null;
|
|
55
|
+
}
|
|
56
|
+
if (node !== null)
|
|
57
|
+
node.firstJsonlTimestampMs = read.state.firstTimestampMs;
|
|
58
|
+
if (read.lines.length > 0)
|
|
59
|
+
aggregateDirty = true;
|
|
60
|
+
for (const line of read.lines) {
|
|
61
|
+
if (read.state.firstTimestampMs === null) {
|
|
62
|
+
const ts = timestampMs(line);
|
|
63
|
+
if (ts !== null)
|
|
64
|
+
read.state.firstTimestampMs = ts;
|
|
65
|
+
}
|
|
66
|
+
if (node !== null)
|
|
67
|
+
node.firstJsonlTimestampMs = read.state.firstTimestampMs;
|
|
68
|
+
for (const id of extractSpawnToolUseIds(line))
|
|
69
|
+
read.state.ownerByToolUseId.set(id, transcript.owner);
|
|
70
|
+
for (const hit of extractToolResults(line)) {
|
|
71
|
+
read.state.resultByToolUseId.set(hit.id, { isError: hit.isError, ts: hit.ts });
|
|
72
|
+
}
|
|
73
|
+
if (node !== null) {
|
|
74
|
+
const activity = latestActivitySummary(line);
|
|
75
|
+
if (activity !== null)
|
|
76
|
+
node.currentActivity = activity;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (aggregateDirty) {
|
|
81
|
+
ownerByToolUseId.clear();
|
|
82
|
+
resultByToolUseId.clear();
|
|
83
|
+
for (const transcript of transcriptOwners) {
|
|
84
|
+
const state = fileStates.get(transcript.path);
|
|
85
|
+
if (state === undefined)
|
|
86
|
+
continue;
|
|
87
|
+
for (const [id, owner] of state.ownerByToolUseId)
|
|
88
|
+
ownerByToolUseId.set(id, owner);
|
|
89
|
+
for (const [id, result] of state.resultByToolUseId)
|
|
90
|
+
resultByToolUseId.set(id, result);
|
|
91
|
+
}
|
|
92
|
+
aggregateDirty = false;
|
|
93
|
+
}
|
|
94
|
+
for (const node of tracked.values()) {
|
|
95
|
+
const result = resultByToolUseId.get(node.meta.toolUseId) ?? null;
|
|
96
|
+
const status = result === null ? "running" : (result.isError ? "error" : "completed");
|
|
97
|
+
const ts = result?.ts ?? node.firstJsonlTimestampMs ?? mtimeMs(node.metaPath);
|
|
98
|
+
const parentNodeId = ownerByToolUseId.get(node.meta.toolUseId) ?? fallbackParent(node.meta.spawnDepth);
|
|
99
|
+
const messageNode = {
|
|
100
|
+
nodeId: node.nodeId,
|
|
101
|
+
toolUseId: node.meta.toolUseId,
|
|
102
|
+
parentNodeId,
|
|
103
|
+
agentType: node.meta.agentType,
|
|
104
|
+
label: node.meta.description,
|
|
105
|
+
depth: node.meta.spawnDepth,
|
|
106
|
+
status,
|
|
107
|
+
currentActivity: status === "running" ? node.currentActivity : null,
|
|
108
|
+
ts,
|
|
109
|
+
};
|
|
110
|
+
const key = stableNodeKey(messageNode);
|
|
111
|
+
if (key === node.lastKey)
|
|
112
|
+
continue;
|
|
113
|
+
node.lastKey = key;
|
|
114
|
+
yield { type: "subagent_node", v: PROTOCOL_V2, node: messageNode };
|
|
115
|
+
}
|
|
116
|
+
if (!this.tailIndefinitely)
|
|
117
|
+
return;
|
|
118
|
+
await abortableSleep(this.pollIntervalMs, signal);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function discoverMetaFiles(dir, tracked) {
|
|
123
|
+
let files;
|
|
124
|
+
try {
|
|
125
|
+
files = fs.readdirSync(dir);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
let changed = false;
|
|
131
|
+
for (const file of files.sort()) {
|
|
132
|
+
const match = /^agent-(.+)\.meta\.json$/.exec(file);
|
|
133
|
+
if (match === null)
|
|
134
|
+
continue;
|
|
135
|
+
const nodeId = match[1];
|
|
136
|
+
const existing = tracked.get(nodeId);
|
|
137
|
+
if (existing !== undefined) {
|
|
138
|
+
const jsonlPath = siblingJsonl(existing.metaPath);
|
|
139
|
+
if (existing.jsonlPath !== jsonlPath) {
|
|
140
|
+
existing.jsonlPath = jsonlPath;
|
|
141
|
+
changed = true;
|
|
142
|
+
}
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const metaPath = path.join(dir, file);
|
|
146
|
+
const meta = readMeta(metaPath);
|
|
147
|
+
if (meta === null)
|
|
148
|
+
continue;
|
|
149
|
+
tracked.set(nodeId, {
|
|
150
|
+
nodeId,
|
|
151
|
+
meta,
|
|
152
|
+
metaPath,
|
|
153
|
+
jsonlPath: siblingJsonl(metaPath),
|
|
154
|
+
firstJsonlTimestampMs: null,
|
|
155
|
+
currentActivity: null,
|
|
156
|
+
lastKey: null,
|
|
157
|
+
});
|
|
158
|
+
changed = true;
|
|
159
|
+
}
|
|
160
|
+
return changed;
|
|
161
|
+
}
|
|
162
|
+
function readMeta(metaPath) {
|
|
163
|
+
try {
|
|
164
|
+
const parsed = JSON.parse(fs.readFileSync(metaPath, "utf8"));
|
|
165
|
+
if (typeof parsed["agentType"] !== "string" ||
|
|
166
|
+
typeof parsed["description"] !== "string" ||
|
|
167
|
+
typeof parsed["toolUseId"] !== "string" ||
|
|
168
|
+
typeof parsed["spawnDepth"] !== "number") {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
agentType: parsed["agentType"],
|
|
173
|
+
description: parsed["description"],
|
|
174
|
+
toolUseId: parsed["toolUseId"],
|
|
175
|
+
spawnDepth: parsed["spawnDepth"],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function siblingJsonl(metaPath) {
|
|
183
|
+
const jsonl = metaPath.replace(/\.meta\.json$/, ".jsonl");
|
|
184
|
+
return fs.existsSync(jsonl) ? jsonl : null;
|
|
185
|
+
}
|
|
186
|
+
function transcriptFiles(mainTranscript, tracked) {
|
|
187
|
+
const out = [
|
|
188
|
+
{ path: mainTranscript, owner: "root", nodeId: null },
|
|
189
|
+
];
|
|
190
|
+
for (const node of tracked.values()) {
|
|
191
|
+
if (node.jsonlPath !== null)
|
|
192
|
+
out.push({ path: node.jsonlPath, owner: node.nodeId, nodeId: node.nodeId });
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
function readNewLines(file, states) {
|
|
197
|
+
let stat;
|
|
198
|
+
try {
|
|
199
|
+
stat = fs.statSync(file);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
const state = ensureFileState(file, states);
|
|
203
|
+
return { lines: [], reset: false, state };
|
|
204
|
+
}
|
|
205
|
+
const state = ensureFileState(file, states);
|
|
206
|
+
let reset = false;
|
|
207
|
+
if (stat.size < state.position) {
|
|
208
|
+
state.position = 0;
|
|
209
|
+
state.lineBuf = Buffer.alloc(0);
|
|
210
|
+
state.ownerByToolUseId.clear();
|
|
211
|
+
state.resultByToolUseId.clear();
|
|
212
|
+
state.firstTimestampMs = null;
|
|
213
|
+
reset = true;
|
|
214
|
+
}
|
|
215
|
+
let fd;
|
|
216
|
+
try {
|
|
217
|
+
fd = fs.openSync(file, "r");
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
return { lines: [], reset, state };
|
|
221
|
+
}
|
|
222
|
+
const out = [];
|
|
223
|
+
const chunk = Buffer.alloc(4096);
|
|
224
|
+
try {
|
|
225
|
+
for (;;) {
|
|
226
|
+
const bytesRead = fs.readSync(fd, chunk, 0, chunk.length, state.position);
|
|
227
|
+
if (bytesRead === 0)
|
|
228
|
+
break;
|
|
229
|
+
state.position += bytesRead;
|
|
230
|
+
state.lineBuf = Buffer.concat([state.lineBuf, chunk.subarray(0, bytesRead)]);
|
|
231
|
+
let nl = state.lineBuf.indexOf(0x0a);
|
|
232
|
+
while (nl >= 0) {
|
|
233
|
+
const line = state.lineBuf.subarray(0, nl).toString("utf8").replaceAll("\r", "");
|
|
234
|
+
state.lineBuf = state.lineBuf.subarray(nl + 1);
|
|
235
|
+
if (line.length > 0)
|
|
236
|
+
out.push(line);
|
|
237
|
+
nl = state.lineBuf.indexOf(0x0a);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return { lines: out, reset, state };
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
// Subagent tailing watches a changing set of files, so each tick opens only for
|
|
246
|
+
// the incremental read and closes immediately. Offsets and partial lines stay cached.
|
|
247
|
+
try {
|
|
248
|
+
fs.closeSync(fd);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
// 二重 close 等は無視。
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return { lines: out, reset, state };
|
|
255
|
+
}
|
|
256
|
+
function ensureFileState(file, states) {
|
|
257
|
+
let state = states.get(file);
|
|
258
|
+
if (state === undefined) {
|
|
259
|
+
state = {
|
|
260
|
+
position: 0,
|
|
261
|
+
lineBuf: Buffer.alloc(0),
|
|
262
|
+
ownerByToolUseId: new Map(),
|
|
263
|
+
resultByToolUseId: new Map(),
|
|
264
|
+
firstTimestampMs: null,
|
|
265
|
+
};
|
|
266
|
+
states.set(file, state);
|
|
267
|
+
}
|
|
268
|
+
return state;
|
|
269
|
+
}
|
|
270
|
+
function extractSpawnToolUseIds(line) {
|
|
271
|
+
const content = messageContent(line);
|
|
272
|
+
if (!Array.isArray(content))
|
|
273
|
+
return [];
|
|
274
|
+
const ids = [];
|
|
275
|
+
for (const block of content) {
|
|
276
|
+
if (typeof block !== "object" || block === null)
|
|
277
|
+
continue;
|
|
278
|
+
const rec = block;
|
|
279
|
+
if (rec["type"] !== "tool_use")
|
|
280
|
+
continue;
|
|
281
|
+
// 実データでは Agent、brief のサンプル/旧名では Task。どちらも同じ spawn path として扱う。
|
|
282
|
+
if (rec["name"] !== "Task" && rec["name"] !== "Agent")
|
|
283
|
+
continue;
|
|
284
|
+
if (typeof rec["id"] === "string")
|
|
285
|
+
ids.push(rec["id"]);
|
|
286
|
+
}
|
|
287
|
+
return ids;
|
|
288
|
+
}
|
|
289
|
+
function extractToolResults(line) {
|
|
290
|
+
const content = messageContent(line);
|
|
291
|
+
const ts = timestampMs(line);
|
|
292
|
+
if (!Array.isArray(content))
|
|
293
|
+
return [];
|
|
294
|
+
const out = [];
|
|
295
|
+
for (const block of content) {
|
|
296
|
+
if (typeof block !== "object" || block === null)
|
|
297
|
+
continue;
|
|
298
|
+
const rec = block;
|
|
299
|
+
if (rec["type"] !== "tool_result")
|
|
300
|
+
continue;
|
|
301
|
+
if (typeof rec["tool_use_id"] === "string") {
|
|
302
|
+
out.push({ id: rec["tool_use_id"], isError: rec["is_error"] === true, ts });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return out;
|
|
306
|
+
}
|
|
307
|
+
function latestActivitySummary(line) {
|
|
308
|
+
const activities = extractToolActivities(messageContent(line));
|
|
309
|
+
const latest = activities.at(-1);
|
|
310
|
+
return latest === undefined ? null : truncateActivityLabel(formatActivityLabel(latest));
|
|
311
|
+
}
|
|
312
|
+
function formatActivityLabel(activity) {
|
|
313
|
+
switch (activity.name) {
|
|
314
|
+
case "Bash":
|
|
315
|
+
return `Bash: ${activity.command ?? activity.description ?? stripActivityPrefix(activity.label, activity.name)}`;
|
|
316
|
+
case "Edit":
|
|
317
|
+
case "MultiEdit":
|
|
318
|
+
return `${activity.name} ${displayActivityTarget(activity)}`;
|
|
319
|
+
case "Write":
|
|
320
|
+
case "NotebookEdit":
|
|
321
|
+
return `${activity.name} ${displayActivityTarget(activity)}`;
|
|
322
|
+
case "Read":
|
|
323
|
+
return `Read ${displayActivityTarget(activity)}`;
|
|
324
|
+
case "TodoWrite":
|
|
325
|
+
return "Todo更新";
|
|
326
|
+
default: {
|
|
327
|
+
const detail = displayActivityTarget(activity);
|
|
328
|
+
return detail === activity.name ? activity.name : `${activity.name}: ${detail}`;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function displayActivityTarget(activity) {
|
|
333
|
+
if (activity.file !== undefined && activity.file.length > 0) {
|
|
334
|
+
const base = path.basename(activity.file);
|
|
335
|
+
return base.length > 0 ? base : activity.file;
|
|
336
|
+
}
|
|
337
|
+
return stripActivityPrefix(activity.label, activity.name);
|
|
338
|
+
}
|
|
339
|
+
function stripActivityPrefix(label, fallback) {
|
|
340
|
+
const stripped = label
|
|
341
|
+
.replace(/^(実行済み|編集済み|作成済み|既読|検索済み)\s*/, "")
|
|
342
|
+
.replace(/^Todoを更新しました$/, "Todo更新")
|
|
343
|
+
.trim();
|
|
344
|
+
return stripped.length > 0 ? stripped : fallback;
|
|
345
|
+
}
|
|
346
|
+
function truncateActivityLabel(label) {
|
|
347
|
+
const limit = 60;
|
|
348
|
+
return label.length <= limit ? label : `${label.slice(0, limit - 1)}…`;
|
|
349
|
+
}
|
|
350
|
+
function messageContent(line) {
|
|
351
|
+
try {
|
|
352
|
+
const obj = JSON.parse(line);
|
|
353
|
+
const message = obj["message"];
|
|
354
|
+
if (typeof message === "object" && message !== null) {
|
|
355
|
+
return message["content"];
|
|
356
|
+
}
|
|
357
|
+
return obj["content"];
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function timestampMs(line) {
|
|
364
|
+
try {
|
|
365
|
+
const obj = JSON.parse(line);
|
|
366
|
+
if (typeof obj["timestamp"] !== "string")
|
|
367
|
+
return null;
|
|
368
|
+
const ms = Date.parse(obj["timestamp"]);
|
|
369
|
+
return Number.isFinite(ms) ? ms : null;
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function mtimeMs(file) {
|
|
376
|
+
try {
|
|
377
|
+
return Math.floor(fs.statSync(file).mtimeMs);
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
return 0;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function fallbackParent(depth) {
|
|
384
|
+
return depth <= 1 ? "root" : null;
|
|
385
|
+
}
|
|
386
|
+
function stableNodeKey(node) {
|
|
387
|
+
return JSON.stringify([
|
|
388
|
+
node.nodeId,
|
|
389
|
+
node.toolUseId,
|
|
390
|
+
node.parentNodeId ?? null,
|
|
391
|
+
node.agentType,
|
|
392
|
+
node.label,
|
|
393
|
+
node.depth,
|
|
394
|
+
node.status,
|
|
395
|
+
node.currentActivity ?? null,
|
|
396
|
+
node.ts,
|
|
397
|
+
]);
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=subagentTailer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagentTailer.js","sourceRoot":"","sources":["../src/subagentTailer.ts"],"names":[],"mappings":"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"}
|
package/dist/tmux.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type ControlMessage, type SessionInfo } from "./protocol.js";
|
|
2
|
+
import { SessionMetadataStore } from "./sessionMetadataStore.js";
|
|
3
|
+
/** tmux コマンド 1 回分の実行結果。 */
|
|
4
|
+
export interface TmuxCommandResult {
|
|
5
|
+
exitCode: number;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
}
|
|
9
|
+
/** tmux コマンド実行の注入可能な抽象(テストはモックを注入する)。 */
|
|
10
|
+
export type TmuxCommandRunner = (args: string[]) => Promise<TmuxCommandResult>;
|
|
11
|
+
/** tmux 実行ファイルの既定絶対パス(PATH 外のため絶対指定)。 */
|
|
12
|
+
export declare const DEFAULT_TMUX_PATH = "/opt/homebrew/bin/tmux";
|
|
13
|
+
/** 実 tmux を絶対パスで起動する既定ランナー。tmux 非0 exit は throw せず結果で表現する。 */
|
|
14
|
+
export declare function processTmuxCommandRunner(tmuxPath?: string): TmuxCommandRunner;
|
|
15
|
+
/** TmuxSessionManager が投げる型付きエラー。 */
|
|
16
|
+
export declare class TmuxFailedError extends Error {
|
|
17
|
+
readonly args: string[];
|
|
18
|
+
readonly exitCode: number;
|
|
19
|
+
readonly stderr: string;
|
|
20
|
+
constructor(args: string[], exitCode: number, stderr: string);
|
|
21
|
+
}
|
|
22
|
+
/** reattach の型付き結果。 */
|
|
23
|
+
export type ReattachResult = {
|
|
24
|
+
kind: "attached";
|
|
25
|
+
info: SessionInfo;
|
|
26
|
+
recentOutput: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: "notFound";
|
|
29
|
+
error: ControlMessage;
|
|
30
|
+
};
|
|
31
|
+
/** tmux セッションの list / reattach / kill とメタデータ統合。 */
|
|
32
|
+
export declare class TmuxSessionManager {
|
|
33
|
+
private readonly runner;
|
|
34
|
+
readonly store: SessionMetadataStore;
|
|
35
|
+
private readonly captureLines;
|
|
36
|
+
private readonly protocolVersion;
|
|
37
|
+
constructor(options?: {
|
|
38
|
+
runner?: TmuxCommandRunner;
|
|
39
|
+
store?: SessionMetadataStore;
|
|
40
|
+
captureLines?: number;
|
|
41
|
+
protocolVersion?: number;
|
|
42
|
+
});
|
|
43
|
+
/** 現存する各セッションを name/cwd/alive で列挙する(name 昇順、メタのみは alive:false)。 */
|
|
44
|
+
list(): Promise<SessionInfo[]>;
|
|
45
|
+
/** 既存セッションへ reattach(生存: attached / 不在: session_not_found エラー封筒)。 */
|
|
46
|
+
reattach(name: string): Promise<ReattachResult>;
|
|
47
|
+
/** 指定セッションのみを終了する(tmux kill-session -t <name>)。 */
|
|
48
|
+
kill(name: string): Promise<void>;
|
|
49
|
+
/** 指定セッションの pane へ tmux send-keys を発行する(literal は -l)。 */
|
|
50
|
+
sendKeys(name: string, keys: string[], literal?: boolean): Promise<void>;
|
|
51
|
+
/** `capture-pane -p -t <name> -S -<N>` で末尾 N 行のペイン内容を返す(末尾空行は削る)。 */
|
|
52
|
+
capturePane(name: string): Promise<string>;
|
|
53
|
+
/** `tmux ls` の生存セッション名集合。サーバ未起動 = 空集合として扱う。 */
|
|
54
|
+
private liveSessionNames;
|
|
55
|
+
/**
|
|
56
|
+
* `tmux ls` の生存セッションと最終活動時刻(Unix 秒)を返す。サーバ未起動 = 空。
|
|
57
|
+
* `#{session_activity}` はセッション個別の最終活動時刻で、一覧の updatedAt 権威に使う
|
|
58
|
+
* (同一 cwd でも共有トランスクリプト mtime に潰されず正しく最近使用順で並ぶ)。
|
|
59
|
+
* 活動時刻を伴わない出力(name のみ)は値 null とし、呼び出し側のフォールバックに委ねる。
|
|
60
|
+
*/
|
|
61
|
+
private liveSessions;
|
|
62
|
+
}
|
package/dist/tmux.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// tmux.ts
|
|
2
|
+
// tailii (TS host) — tmux セッションの list / reattach / kill / send-keys / capture-pane
|
|
3
|
+
// Swift 版 TmuxSessionManager.swift の移植。
|
|
4
|
+
// 生存集合は `tmux ls -F '#{session_name}'`、cwd は SessionMetadataStore を権威とする。
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
6
|
+
import { PROTOCOL_V1 } from "./protocol.js";
|
|
7
|
+
import { SessionMetadataStore, validateSessionName } from "./sessionMetadataStore.js";
|
|
8
|
+
/** tmux 実行ファイルの既定絶対パス(PATH 外のため絶対指定)。 */
|
|
9
|
+
export const DEFAULT_TMUX_PATH = "/opt/homebrew/bin/tmux";
|
|
10
|
+
/** 実 tmux を絶対パスで起動する既定ランナー。tmux 非0 exit は throw せず結果で表現する。 */
|
|
11
|
+
export function processTmuxCommandRunner(tmuxPath = DEFAULT_TMUX_PATH) {
|
|
12
|
+
return (args) => new Promise((resolve, reject) => {
|
|
13
|
+
execFile(tmuxPath, args, { maxBuffer: 16 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
14
|
+
if (error && typeof error.code === "string") {
|
|
15
|
+
// 実行ファイル起動自体の失敗(ENOENT 等)のみ throw(Swift 版と同じ境界)。
|
|
16
|
+
reject(error);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const exitCode = error && typeof error.code === "number" ? error.code : error ? 1 : 0;
|
|
20
|
+
resolve({ exitCode, stdout: String(stdout), stderr: String(stderr) });
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/** TmuxSessionManager が投げる型付きエラー。 */
|
|
25
|
+
export class TmuxFailedError extends Error {
|
|
26
|
+
args;
|
|
27
|
+
exitCode;
|
|
28
|
+
stderr;
|
|
29
|
+
constructor(args, exitCode, stderr) {
|
|
30
|
+
super(`tmux ${args.join(" ")} failed (exit ${exitCode}): ${stderr}`);
|
|
31
|
+
this.args = args;
|
|
32
|
+
this.exitCode = exitCode;
|
|
33
|
+
this.stderr = stderr;
|
|
34
|
+
this.name = "TmuxFailedError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** tmux セッションの list / reattach / kill とメタデータ統合。 */
|
|
38
|
+
export class TmuxSessionManager {
|
|
39
|
+
runner;
|
|
40
|
+
store;
|
|
41
|
+
captureLines;
|
|
42
|
+
protocolVersion;
|
|
43
|
+
constructor(options = {}) {
|
|
44
|
+
this.runner = options.runner ?? processTmuxCommandRunner();
|
|
45
|
+
this.store = options.store ?? new SessionMetadataStore();
|
|
46
|
+
this.captureLines = options.captureLines ?? 50;
|
|
47
|
+
this.protocolVersion = options.protocolVersion ?? PROTOCOL_V1;
|
|
48
|
+
}
|
|
49
|
+
/** 現存する各セッションを name/cwd/alive で列挙する(name 昇順、メタのみは alive:false)。 */
|
|
50
|
+
async list() {
|
|
51
|
+
const alive = await this.liveSessions();
|
|
52
|
+
const metas = this.store.all();
|
|
53
|
+
const cwdByName = new Map();
|
|
54
|
+
for (const meta of metas)
|
|
55
|
+
cwdByName.set(meta.name, meta.cwd);
|
|
56
|
+
const names = new Set(alive.keys());
|
|
57
|
+
for (const meta of metas)
|
|
58
|
+
names.add(meta.name);
|
|
59
|
+
const infos = [...names].map((name) => {
|
|
60
|
+
const base = {
|
|
61
|
+
name,
|
|
62
|
+
cwd: cwdByName.get(name) ?? "",
|
|
63
|
+
alive: alive.has(name),
|
|
64
|
+
};
|
|
65
|
+
// tmux のセッション個別の活動時刻を updatedAt(Unix 秒)の権威にする。
|
|
66
|
+
const activity = alive.get(name);
|
|
67
|
+
return activity === undefined || activity === null ? base : { ...base, updatedAt: activity };
|
|
68
|
+
});
|
|
69
|
+
return infos.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
70
|
+
}
|
|
71
|
+
/** 既存セッションへ reattach(生存: attached / 不在: session_not_found エラー封筒)。 */
|
|
72
|
+
async reattach(name) {
|
|
73
|
+
validateSessionName(name);
|
|
74
|
+
const aliveNames = await this.liveSessionNames();
|
|
75
|
+
if (!aliveNames.has(name)) {
|
|
76
|
+
return {
|
|
77
|
+
kind: "notFound",
|
|
78
|
+
error: {
|
|
79
|
+
type: "error",
|
|
80
|
+
v: this.protocolVersion,
|
|
81
|
+
code: "session_not_found",
|
|
82
|
+
message: `セッション '${name}' は存在しません。新規に起動できます。`,
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const cwd = this.store.get(name)?.cwd ?? "";
|
|
87
|
+
const recent = await this.capturePane(name);
|
|
88
|
+
return { kind: "attached", info: { name, cwd, alive: true }, recentOutput: recent };
|
|
89
|
+
}
|
|
90
|
+
/** 指定セッションのみを終了する(tmux kill-session -t <name>)。 */
|
|
91
|
+
async kill(name) {
|
|
92
|
+
validateSessionName(name);
|
|
93
|
+
const args = ["kill-session", "-t", name];
|
|
94
|
+
const result = await this.runner(args);
|
|
95
|
+
if (result.exitCode !== 0) {
|
|
96
|
+
throw new TmuxFailedError(args, result.exitCode, result.stderr);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** 指定セッションの pane へ tmux send-keys を発行する(literal は -l)。 */
|
|
100
|
+
async sendKeys(name, keys, literal = false) {
|
|
101
|
+
validateSessionName(name);
|
|
102
|
+
if (keys.length === 0)
|
|
103
|
+
return;
|
|
104
|
+
const args = ["send-keys", "-t", name];
|
|
105
|
+
if (literal)
|
|
106
|
+
args.push("-l");
|
|
107
|
+
args.push(...keys);
|
|
108
|
+
const result = await this.runner(args);
|
|
109
|
+
if (result.exitCode !== 0) {
|
|
110
|
+
throw new TmuxFailedError(args, result.exitCode, result.stderr);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** `capture-pane -p -t <name> -S -<N>` で末尾 N 行のペイン内容を返す(末尾空行は削る)。 */
|
|
114
|
+
async capturePane(name) {
|
|
115
|
+
const args = ["capture-pane", "-p", "-t", name, "-S", `-${this.captureLines}`];
|
|
116
|
+
const result = await this.runner(args);
|
|
117
|
+
if (result.exitCode !== 0) {
|
|
118
|
+
throw new TmuxFailedError(args, result.exitCode, result.stderr);
|
|
119
|
+
}
|
|
120
|
+
const lines = result.stdout.split("\n");
|
|
121
|
+
while (lines.length > 0 && (lines[lines.length - 1] ?? "").trim() === "") {
|
|
122
|
+
lines.pop();
|
|
123
|
+
}
|
|
124
|
+
return lines.join("\n");
|
|
125
|
+
}
|
|
126
|
+
/** `tmux ls` の生存セッション名集合。サーバ未起動 = 空集合として扱う。 */
|
|
127
|
+
async liveSessionNames() {
|
|
128
|
+
return new Set((await this.liveSessions()).keys());
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* `tmux ls` の生存セッションと最終活動時刻(Unix 秒)を返す。サーバ未起動 = 空。
|
|
132
|
+
* `#{session_activity}` はセッション個別の最終活動時刻で、一覧の updatedAt 権威に使う
|
|
133
|
+
* (同一 cwd でも共有トランスクリプト mtime に潰されず正しく最近使用順で並ぶ)。
|
|
134
|
+
* 活動時刻を伴わない出力(name のみ)は値 null とし、呼び出し側のフォールバックに委ねる。
|
|
135
|
+
*/
|
|
136
|
+
async liveSessions() {
|
|
137
|
+
const args = ["ls", "-F", "#{session_name} #{session_activity}"];
|
|
138
|
+
const result = await this.runner(args);
|
|
139
|
+
if (result.exitCode !== 0) {
|
|
140
|
+
const combined = (result.stdout + result.stderr).toLowerCase();
|
|
141
|
+
if (combined.includes("no server running") || combined.includes("no sessions")) {
|
|
142
|
+
return new Map();
|
|
143
|
+
}
|
|
144
|
+
throw new TmuxFailedError(args, result.exitCode, result.stderr);
|
|
145
|
+
}
|
|
146
|
+
const out = new Map();
|
|
147
|
+
for (const raw of result.stdout.split("\n")) {
|
|
148
|
+
const line = raw.trim();
|
|
149
|
+
if (line.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
const sep = line.lastIndexOf(" ");
|
|
152
|
+
if (sep < 0) {
|
|
153
|
+
out.set(line, null); // 活動時刻なし(name のみ)
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const name = line.slice(0, sep).trim();
|
|
157
|
+
const secs = Number.parseInt(line.slice(sep + 1).trim(), 10);
|
|
158
|
+
out.set(name, Number.isFinite(secs) ? secs : null);
|
|
159
|
+
}
|
|
160
|
+
return out;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=tmux.js.map
|
package/dist/tmux.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux.js","sourceRoot":"","sources":["../src/tmux.ts"],"names":[],"mappings":"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"}
|