@doingdev/opencode-claude-manager-plugin 0.1.5 → 0.1.6
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
CHANGED
|
@@ -50,7 +50,7 @@ If you are testing locally, point OpenCode at the local package or plugin file u
|
|
|
50
50
|
|
|
51
51
|
## OpenCode tools
|
|
52
52
|
|
|
53
|
-
- `claude_manager_run` - run a task through Claude with optional splitting and worktrees
|
|
53
|
+
- `claude_manager_run` - run a task through Claude with optional splitting and worktrees; returns a compact output summary and a `runId` for deeper inspection
|
|
54
54
|
- `claude_manager_metadata` - inspect available Claude commands, skills, hooks, and settings
|
|
55
55
|
- `claude_manager_sessions` - list Claude sessions or inspect a saved transcript
|
|
56
56
|
- `claude_manager_runs` - inspect persisted manager run records
|
|
@@ -136,10 +136,14 @@ function normalizeSdkMessage(message) {
|
|
|
136
136
|
};
|
|
137
137
|
}
|
|
138
138
|
if (message.type === 'stream_event') {
|
|
139
|
+
const partialText = extractPartialEventText(message.event);
|
|
140
|
+
if (!partialText) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
139
143
|
return {
|
|
140
144
|
type: 'partial',
|
|
141
145
|
sessionId,
|
|
142
|
-
text:
|
|
146
|
+
text: partialText,
|
|
143
147
|
rawType: message.type,
|
|
144
148
|
};
|
|
145
149
|
}
|
|
@@ -191,21 +195,21 @@ function normalizeSdkMessage(message) {
|
|
|
191
195
|
}
|
|
192
196
|
function extractPartialEventText(event) {
|
|
193
197
|
if (!event || typeof event !== 'object') {
|
|
194
|
-
return
|
|
198
|
+
return null;
|
|
195
199
|
}
|
|
196
200
|
const eventRecord = event;
|
|
197
|
-
const eventType = typeof eventRecord.type === 'string' ? eventRecord.type : 'stream_event';
|
|
198
201
|
const delta = eventRecord.delta;
|
|
199
202
|
if (delta && typeof delta === 'object') {
|
|
200
203
|
const deltaRecord = delta;
|
|
201
|
-
if (typeof deltaRecord.text === 'string') {
|
|
204
|
+
if (typeof deltaRecord.text === 'string' && deltaRecord.text.length > 0) {
|
|
202
205
|
return deltaRecord.text;
|
|
203
206
|
}
|
|
204
|
-
if (typeof deltaRecord.partial_json === 'string'
|
|
207
|
+
if (typeof deltaRecord.partial_json === 'string' &&
|
|
208
|
+
deltaRecord.partial_json.length > 0) {
|
|
205
209
|
return deltaRecord.partial_json;
|
|
206
210
|
}
|
|
207
211
|
}
|
|
208
|
-
return
|
|
212
|
+
return null;
|
|
209
213
|
}
|
|
210
214
|
function extractText(payload) {
|
|
211
215
|
if (typeof payload === 'string') {
|
|
@@ -127,7 +127,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
|
|
|
127
127
|
lastProgressSignature = signature;
|
|
128
128
|
context.metadata(progressView);
|
|
129
129
|
});
|
|
130
|
-
return
|
|
130
|
+
return formatManagerRunToolResult(result.run);
|
|
131
131
|
},
|
|
132
132
|
}),
|
|
133
133
|
claude_manager_metadata: tool({
|
|
@@ -243,6 +243,32 @@ function rewriteCommandParts(parts, text) {
|
|
|
243
243
|
});
|
|
244
244
|
return rewrittenParts;
|
|
245
245
|
}
|
|
246
|
+
export function formatManagerRunToolResult(run) {
|
|
247
|
+
const finalSummary = run.finalSummary ?? summarizeSessionOutputs(run.sessions);
|
|
248
|
+
const output = run.sessions.length === 1
|
|
249
|
+
? resolveSessionOutput(run.sessions[0])
|
|
250
|
+
: finalSummary;
|
|
251
|
+
return JSON.stringify({
|
|
252
|
+
runId: run.id,
|
|
253
|
+
status: run.status,
|
|
254
|
+
output,
|
|
255
|
+
finalSummary,
|
|
256
|
+
sessions: run.sessions.map((session) => ({
|
|
257
|
+
title: session.title,
|
|
258
|
+
status: session.status,
|
|
259
|
+
output: resolveSessionOutput(session),
|
|
260
|
+
claudeSessionId: session.claudeSessionId,
|
|
261
|
+
worktreeMode: session.worktreeMode,
|
|
262
|
+
branchName: session.branchName,
|
|
263
|
+
turns: session.turns,
|
|
264
|
+
totalCostUsd: session.totalCostUsd,
|
|
265
|
+
})),
|
|
266
|
+
inspectRun: {
|
|
267
|
+
tool: 'claude_manager_runs',
|
|
268
|
+
runId: run.id,
|
|
269
|
+
},
|
|
270
|
+
}, null, 2);
|
|
271
|
+
}
|
|
246
272
|
function buildRunProgressView(run) {
|
|
247
273
|
const completed = run.sessions.filter((session) => session.status === 'completed').length;
|
|
248
274
|
const failed = run.sessions.filter((session) => session.status === 'failed').length;
|
|
@@ -284,18 +310,26 @@ function formatSessionActivity(session) {
|
|
|
284
310
|
parts.push(session.claudeSessionId);
|
|
285
311
|
}
|
|
286
312
|
const latestEvent = findLatestDisplayEvent(session.events);
|
|
287
|
-
if (
|
|
288
|
-
parts.push(`${latestEvent.type}: ${truncateForDisplay(latestEvent.text, 120)}`);
|
|
289
|
-
}
|
|
290
|
-
else if (session.finalText) {
|
|
313
|
+
if (session.finalText) {
|
|
291
314
|
parts.push(truncateForDisplay(session.finalText, 120));
|
|
292
315
|
}
|
|
293
316
|
else if (session.error) {
|
|
294
317
|
parts.push(truncateForDisplay(session.error, 120));
|
|
295
318
|
}
|
|
319
|
+
else if (latestEvent) {
|
|
320
|
+
parts.push(`${latestEvent.type}: ${truncateForDisplay(latestEvent.text, 120)}`);
|
|
321
|
+
}
|
|
296
322
|
return parts.join(' | ');
|
|
297
323
|
}
|
|
298
324
|
function findLatestDisplayEvent(events) {
|
|
325
|
+
const reversedEvents = [...events].reverse();
|
|
326
|
+
const preferredEvent = reversedEvents.find((event) => (event.type === 'result' ||
|
|
327
|
+
event.type === 'error' ||
|
|
328
|
+
event.type === 'assistant') &&
|
|
329
|
+
Boolean(event.text.trim()));
|
|
330
|
+
if (preferredEvent) {
|
|
331
|
+
return preferredEvent;
|
|
332
|
+
}
|
|
299
333
|
return [...events]
|
|
300
334
|
.reverse()
|
|
301
335
|
.find((event) => event.type !== 'partial' && Boolean(event.text.trim()));
|
|
@@ -307,3 +341,15 @@ function truncateForDisplay(text, maxLength) {
|
|
|
307
341
|
}
|
|
308
342
|
return `${normalized.slice(0, maxLength - 3)}...`;
|
|
309
343
|
}
|
|
344
|
+
function summarizeSessionOutputs(sessions) {
|
|
345
|
+
return sessions
|
|
346
|
+
.map((session) => `${session.title}: ${resolveSessionOutput(session)}`)
|
|
347
|
+
.join('\n');
|
|
348
|
+
}
|
|
349
|
+
function resolveSessionOutput(session) {
|
|
350
|
+
const latestEvent = findLatestDisplayEvent(session.events);
|
|
351
|
+
return (session.finalText?.trim() ||
|
|
352
|
+
session.error?.trim() ||
|
|
353
|
+
latestEvent?.text.trim() ||
|
|
354
|
+
session.status);
|
|
355
|
+
}
|