@doingdev/opencode-claude-manager-plugin 0.1.31 → 0.1.32

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.
@@ -495,13 +495,21 @@ function extractUsageFromResult(message) {
495
495
  result.outputTokens = usage.output_tokens;
496
496
  }
497
497
  }
498
- // Extract contextWindow from modelUsage
499
- const modelUsage = message.model_usage;
498
+ // Extract contextWindow from modelUsage (camelCase) or model_usage (snake_case)
499
+ const modelUsage = message.modelUsage ??
500
+ message.model_usage;
500
501
  if (isRecord(modelUsage)) {
501
502
  for (const model of Object.values(modelUsage)) {
502
- if (isRecord(model) && typeof model.context_window === 'number') {
503
- result.contextWindowSize = model.context_window;
504
- break;
503
+ if (isRecord(model)) {
504
+ const cw = typeof model.contextWindow === 'number'
505
+ ? model.contextWindow
506
+ : typeof model.context_window === 'number'
507
+ ? model.context_window
508
+ : undefined;
509
+ if (cw !== undefined) {
510
+ result.contextWindowSize = cw;
511
+ break;
512
+ }
505
513
  }
506
514
  }
507
515
  }
@@ -27,6 +27,9 @@ export declare class PersistentManager {
27
27
  finalText: string;
28
28
  turns?: number;
29
29
  totalCostUsd?: number;
30
+ inputTokens?: number;
31
+ outputTokens?: number;
32
+ contextWindowSize?: number;
30
33
  context: SessionContextSnapshot;
31
34
  }>;
32
35
  /**
@@ -26,6 +26,9 @@ export class PersistentManager {
26
26
  finalText: result.finalText,
27
27
  turns: result.turns,
28
28
  totalCostUsd: result.totalCostUsd,
29
+ inputTokens: result.inputTokens,
30
+ outputTokens: result.outputTokens,
31
+ contextWindowSize: result.contextWindowSize,
29
32
  context: this.sessionController.getContextSnapshot(),
30
33
  };
31
34
  }
@@ -18,8 +18,8 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
18
18
  prompt: promptPreview,
19
19
  },
20
20
  });
21
- let turnsSoFar = 0;
22
- let costSoFar = 0;
21
+ let turnsSoFar;
22
+ let costSoFar;
23
23
  const result = await services.manager.sendMessage(cwd, args.message, {
24
24
  model: args.model,
25
25
  effort: args.effort,
@@ -32,7 +32,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
32
32
  if (event.totalCostUsd !== undefined) {
33
33
  costSoFar = event.totalCostUsd;
34
34
  }
35
- const costLabel = `$${costSoFar.toFixed(4)}`;
35
+ const usageSuffix = formatLiveUsage(turnsSoFar, costSoFar);
36
36
  if (event.type === 'tool_call') {
37
37
  let toolName = 'tool';
38
38
  let inputPreview = '';
@@ -48,7 +48,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
48
48
  // ignore parse errors
49
49
  }
50
50
  context.metadata({
51
- title: `Claude Code: Running ${toolName}... (${turnsSoFar} turns, ${costLabel})`,
51
+ title: `Claude Code: Running ${toolName}...${usageSuffix}`,
52
52
  metadata: {
53
53
  sessionId: event.sessionId,
54
54
  type: event.type,
@@ -60,7 +60,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
60
60
  else if (event.type === 'assistant') {
61
61
  const thinkingPreview = event.text.length > 150 ? event.text.slice(0, 150) + '...' : event.text;
62
62
  context.metadata({
63
- title: `Claude Code: Thinking... (${turnsSoFar} turns, ${costLabel})`,
63
+ title: `Claude Code: Thinking...${usageSuffix}`,
64
64
  metadata: {
65
65
  sessionId: event.sessionId,
66
66
  type: event.type,
@@ -80,7 +80,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
80
80
  else if (event.type === 'user') {
81
81
  const preview = event.text.length > 200 ? event.text.slice(0, 200) + '...' : event.text;
82
82
  context.metadata({
83
- title: `Claude Code: Tool result (${turnsSoFar} turns, ${costLabel})`,
83
+ title: `Claude Code: Tool result${usageSuffix}`,
84
84
  metadata: {
85
85
  sessionId: event.sessionId,
86
86
  type: event.type,
@@ -100,7 +100,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
100
100
  // ignore
101
101
  }
102
102
  context.metadata({
103
- title: `Claude Code: ${toolName} running ${elapsed > 0 ? `(${elapsed.toFixed(0)}s)` : ''}... (${turnsSoFar} turns, ${costLabel})`,
103
+ title: `Claude Code: ${toolName} running ${elapsed > 0 ? `(${elapsed.toFixed(0)}s)` : ''}...${usageSuffix}`,
104
104
  metadata: {
105
105
  sessionId: event.sessionId,
106
106
  type: event.type,
@@ -112,7 +112,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
112
112
  else if (event.type === 'tool_summary') {
113
113
  const summary = event.text.length > 200 ? event.text.slice(0, 200) + '...' : event.text;
114
114
  context.metadata({
115
- title: `Claude Code: Tool done (${turnsSoFar} turns, ${costLabel})`,
115
+ title: `Claude Code: Tool done${usageSuffix}`,
116
116
  metadata: {
117
117
  sessionId: event.sessionId,
118
118
  type: event.type,
@@ -123,7 +123,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
123
123
  else if (event.type === 'partial') {
124
124
  const delta = event.text.length > 200 ? event.text.slice(0, 200) + '...' : event.text;
125
125
  context.metadata({
126
- title: `Claude Code: Writing... (${turnsSoFar} turns, ${costLabel})`,
126
+ title: `Claude Code: Writing...${usageSuffix}`,
127
127
  metadata: {
128
128
  sessionId: event.sessionId,
129
129
  type: event.type,
@@ -170,6 +170,9 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
170
170
  finalText: result.finalText,
171
171
  turns: result.turns,
172
172
  totalCostUsd: result.totalCostUsd,
173
+ inputTokens: result.inputTokens,
174
+ outputTokens: result.outputTokens,
175
+ contextWindowSize: result.contextWindowSize,
173
176
  context: result.context,
174
177
  contextWarning,
175
178
  toolOutputs: toolOutputs.length > 0 ? toolOutputs : undefined,
@@ -472,6 +475,19 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
472
475
  function annotateToolRun(context, title, metadata) {
473
476
  context.metadata({ title, metadata });
474
477
  }
478
+ function formatLiveUsage(turns, cost) {
479
+ if (turns === undefined && cost === undefined) {
480
+ return '';
481
+ }
482
+ const parts = [];
483
+ if (turns !== undefined) {
484
+ parts.push(`${turns} turns`);
485
+ }
486
+ if (cost !== undefined) {
487
+ parts.push(`$${cost.toFixed(4)}`);
488
+ }
489
+ return ` (${parts.join(', ')})`;
490
+ }
475
491
  function formatContextWarning(context) {
476
492
  const { warningLevel, estimatedContextPercent, totalTurns, totalCostUsd } = context;
477
493
  if (warningLevel === 'ok' || estimatedContextPercent === null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doingdev/opencode-claude-manager-plugin",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "OpenCode plugin that orchestrates Claude Code sessions.",
5
5
  "keywords": [
6
6
  "opencode",