@doingdev/opencode-claude-manager-plugin 0.1.9 → 0.1.11

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.
@@ -2,11 +2,15 @@ import { tool } from '@opencode-ai/plugin';
2
2
  import { managerPromptRegistry } from '../prompts/registry.js';
3
3
  import { getOrCreatePluginServices } from './service-factory.js';
4
4
  const MANAGER_TOOL_IDS = [
5
- 'claude_manager_run',
5
+ 'claude_manager_send',
6
+ 'claude_manager_git_diff',
7
+ 'claude_manager_git_commit',
8
+ 'claude_manager_git_reset',
9
+ 'claude_manager_clear',
10
+ 'claude_manager_status',
6
11
  'claude_manager_metadata',
7
12
  'claude_manager_sessions',
8
13
  'claude_manager_runs',
9
- 'claude_manager_cleanup_run',
10
14
  ];
11
15
  export const ClaudeManagerPlugin = async ({ worktree }) => {
12
16
  const services = getOrCreatePluginServices(worktree);
@@ -16,37 +20,29 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
16
20
  config.command ??= {};
17
21
  config.permission ??= {};
18
22
  const globalPermissions = config.permission;
19
- const managerPermissions = {
20
- claude_manager_run: 'allow',
21
- claude_manager_metadata: 'allow',
22
- claude_manager_sessions: 'allow',
23
- claude_manager_runs: 'allow',
24
- claude_manager_cleanup_run: 'allow',
25
- };
26
- const researchPermissions = {
27
- claude_manager_run: 'deny',
28
- claude_manager_metadata: 'allow',
29
- claude_manager_sessions: 'allow',
30
- claude_manager_runs: 'allow',
31
- claude_manager_cleanup_run: 'deny',
32
- };
23
+ const managerPermissions = {};
24
+ const researchPermissions = {};
33
25
  for (const toolId of MANAGER_TOOL_IDS) {
34
26
  globalPermissions[toolId] ??= 'deny';
27
+ managerPermissions[toolId] = 'allow';
28
+ // Research agent can inspect but not send or modify
29
+ researchPermissions[toolId] =
30
+ toolId === 'claude_manager_send' ||
31
+ toolId === 'claude_manager_git_commit' ||
32
+ toolId === 'claude_manager_git_reset' ||
33
+ toolId === 'claude_manager_clear'
34
+ ? 'deny'
35
+ : 'allow';
35
36
  }
36
37
  config.agent['claude-manager'] ??= {
37
- description: 'Primary agent that manages Claude Code sessions through the bundled plugin tools.',
38
+ description: 'Primary agent that operates Claude Code through a persistent session, reviews work via git diff, and commits/resets changes.',
38
39
  mode: 'primary',
39
40
  color: 'accent',
40
41
  permission: {
41
42
  '*': 'deny',
42
43
  ...managerPermissions,
43
44
  },
44
- prompt: [
45
- managerPromptRegistry.managerSystemPrompt,
46
- 'When Claude Code delegation is useful, prefer the claude_manager_run tool instead of simulating the work yourself.',
47
- 'Use claude_manager_metadata to inspect available Claude commands, skills, and hooks before making assumptions.',
48
- 'Use claude_manager_sessions and claude_manager_runs to inspect prior work before starting a new Claude session.',
49
- ].join(' '),
45
+ prompt: managerPromptRegistry.managerSystemPrompt,
50
46
  };
51
47
  config.agent['claude-manager-research'] ??= {
52
48
  description: 'Subagent that inspects Claude metadata, prior sessions, and manager runs without changing repository state.',
@@ -57,11 +53,20 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
57
53
  ...researchPermissions,
58
54
  },
59
55
  prompt: [
60
- managerPromptRegistry.subagentSystemPrompt,
61
56
  'Focus on inspection and summarization.',
62
- 'Prefer claude_manager_metadata, claude_manager_sessions, and claude_manager_runs over guesswork.',
57
+ 'Use claude_manager_status, claude_manager_metadata, claude_manager_sessions, and claude_manager_runs to gather information.',
63
58
  ].join(' '),
64
59
  };
60
+ config.command['claude-run'] ??= {
61
+ description: 'Send a task to the persistent Claude Code session.',
62
+ agent: 'claude-manager',
63
+ subtask: true,
64
+ template: [
65
+ 'Use claude_manager_send to send the following task to Claude Code:',
66
+ '$ARGUMENTS',
67
+ 'After it completes, review the result and use claude_manager_git_diff if changes were expected. Commit or reset accordingly.',
68
+ ].join('\n\n'),
69
+ };
65
70
  config.command['claude-metadata'] ??= {
66
71
  description: 'Inspect bundled Claude commands, skills, hooks, and agents.',
67
72
  agent: 'claude-manager-research',
@@ -71,16 +76,6 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
71
76
  'Summarize Claude commands, skills, hooks, discovered agents, and important config files.',
72
77
  ].join(' '),
73
78
  };
74
- config.command['claude-run'] ??= {
75
- description: 'Delegate a task to Claude Code through the manager plugin.',
76
- agent: 'claude-manager',
77
- subtask: true,
78
- template: [
79
- 'Call claude_manager_run immediately for the following task:',
80
- '$ARGUMENTS',
81
- 'Avoid planning narration before the tool call. After it completes, return a concise result summary.',
82
- ].join('\n\n'),
83
- };
84
79
  config.command['claude-sessions'] ??= {
85
80
  description: 'Inspect Claude session history and manager run records.',
86
81
  agent: 'claude-manager-research',
@@ -99,41 +94,103 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
99
94
  }
100
95
  },
101
96
  tool: {
102
- claude_manager_run: tool({
103
- description: 'Delegate a task to Claude Code with optional subagents and worktrees.',
97
+ claude_manager_send: tool({
98
+ description: 'Send a message to the persistent Claude Code session. ' +
99
+ 'Auto-creates a session on first call. Resumes the existing session on subsequent calls. ' +
100
+ 'Returns the assistant response and current context health snapshot.',
104
101
  args: {
105
- task: tool.schema.string().min(1),
106
- mode: tool.schema.enum(['auto', 'single', 'split']).default('auto'),
107
- maxSubagents: tool.schema.number().int().min(1).max(8).default(3),
108
- useWorktrees: tool.schema.boolean().default(true),
109
- includeProjectSettings: tool.schema.boolean().default(true),
102
+ message: tool.schema.string().min(1),
110
103
  model: tool.schema.string().optional(),
111
104
  cwd: tool.schema.string().optional(),
112
105
  },
113
106
  async execute(args, context) {
114
- annotateToolRun(context, 'Delegating task to Claude manager', {
115
- task: args.task,
116
- mode: args.mode,
107
+ annotateToolRun(context, 'Sending to Claude Code session', {
108
+ hasActiveSession: services.manager.getStatus().sessionId !== null,
117
109
  });
118
- let lastProgressSignature = '';
119
- const result = await services.manager.run({
120
- cwd: args.cwd ?? context.worktree,
121
- task: args.task,
122
- mode: args.mode,
123
- maxSubagents: args.maxSubagents,
124
- useWorktrees: args.useWorktrees,
125
- includeProjectSettings: args.includeProjectSettings,
126
- model: args.model,
127
- }, async (run) => {
128
- const progressView = buildRunProgressView(run);
129
- const signature = JSON.stringify(progressView);
130
- if (signature === lastProgressSignature) {
131
- return;
110
+ const result = await services.manager.sendMessage(args.cwd ?? context.worktree, args.message, { model: args.model }, (event) => {
111
+ if (event.type === 'assistant' || event.type === 'tool_call') {
112
+ context.metadata({
113
+ title: 'Claude Code working...',
114
+ metadata: {
115
+ type: event.type,
116
+ preview: event.text.slice(0, 200),
117
+ },
118
+ });
132
119
  }
133
- lastProgressSignature = signature;
134
- context.metadata(progressView);
135
120
  });
136
- return formatManagerRunToolResult(result.run);
121
+ return JSON.stringify({
122
+ sessionId: result.sessionId,
123
+ finalText: result.finalText,
124
+ turns: result.turns,
125
+ totalCostUsd: result.totalCostUsd,
126
+ context: result.context,
127
+ contextWarning: formatContextWarning(result.context),
128
+ }, null, 2);
129
+ },
130
+ }),
131
+ claude_manager_git_diff: tool({
132
+ description: 'Run git diff to see all current changes (staged + unstaged) relative to HEAD.',
133
+ args: {
134
+ cwd: tool.schema.string().optional(),
135
+ },
136
+ async execute(_args, context) {
137
+ annotateToolRun(context, 'Running git diff', {});
138
+ const result = await services.manager.gitDiff();
139
+ return JSON.stringify(result, null, 2);
140
+ },
141
+ }),
142
+ claude_manager_git_commit: tool({
143
+ description: 'Stage all changes and commit with the given message.',
144
+ args: {
145
+ message: tool.schema.string().min(1),
146
+ cwd: tool.schema.string().optional(),
147
+ },
148
+ async execute(args, context) {
149
+ annotateToolRun(context, 'Committing changes', {
150
+ message: args.message,
151
+ });
152
+ const result = await services.manager.gitCommit(args.message);
153
+ return JSON.stringify(result, null, 2);
154
+ },
155
+ }),
156
+ claude_manager_git_reset: tool({
157
+ description: 'Run git reset --hard HEAD and git clean -fd to discard ALL uncommitted changes and untracked files.',
158
+ args: {
159
+ cwd: tool.schema.string().optional(),
160
+ },
161
+ async execute(_args, context) {
162
+ annotateToolRun(context, 'Resetting working directory', {});
163
+ const result = await services.manager.gitReset();
164
+ return JSON.stringify(result, null, 2);
165
+ },
166
+ }),
167
+ claude_manager_clear: tool({
168
+ description: 'Clear the active Claude Code session. The next send will start a fresh session. ' +
169
+ 'Use when context is full, the session is confused, or starting a different task.',
170
+ args: {
171
+ cwd: tool.schema.string().optional(),
172
+ reason: tool.schema.string().optional(),
173
+ },
174
+ async execute(args, context) {
175
+ annotateToolRun(context, 'Clearing session', {
176
+ reason: args.reason,
177
+ });
178
+ const clearedId = await services.manager.clearSession(args.cwd ?? context.worktree);
179
+ return JSON.stringify({ clearedSessionId: clearedId });
180
+ },
181
+ }),
182
+ claude_manager_status: tool({
183
+ description: 'Get the current persistent session status: context usage %, turns, cost, active session ID.',
184
+ args: {
185
+ cwd: tool.schema.string().optional(),
186
+ },
187
+ async execute(_args, context) {
188
+ annotateToolRun(context, 'Checking session status', {});
189
+ const status = services.manager.getStatus();
190
+ return JSON.stringify({
191
+ ...status,
192
+ contextWarning: formatContextWarning(status),
193
+ }, null, 2);
137
194
  },
138
195
  }),
139
196
  claude_manager_metadata: tool({
@@ -169,7 +226,7 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
169
226
  },
170
227
  }),
171
228
  claude_manager_runs: tool({
172
- description: 'List manager runs previously recorded for this repo.',
229
+ description: 'List persistent manager run records.',
173
230
  args: {
174
231
  cwd: tool.schema.string().optional(),
175
232
  runId: tool.schema.string().optional(),
@@ -184,20 +241,6 @@ export const ClaudeManagerPlugin = async ({ worktree }) => {
184
241
  return JSON.stringify(runs, null, 2);
185
242
  },
186
243
  }),
187
- claude_manager_cleanup_run: tool({
188
- description: 'Explicitly remove git worktrees created for a recorded manager run.',
189
- args: {
190
- runId: tool.schema.string().min(1),
191
- cwd: tool.schema.string().optional(),
192
- },
193
- async execute(args, context) {
194
- annotateToolRun(context, 'Cleaning manager worktrees', {
195
- runId: args.runId,
196
- });
197
- const run = await services.manager.cleanupRunWorktrees(args.cwd ?? context.worktree, args.runId);
198
- return JSON.stringify(run, null, 2);
199
- },
200
- }),
201
244
  },
202
245
  };
203
246
  };
@@ -208,11 +251,11 @@ function buildCommandText(command, rawArguments) {
208
251
  const argumentsText = rawArguments.trim();
209
252
  if (command === 'claude-run') {
210
253
  return [
211
- 'Call `claude_manager_run` immediately.',
254
+ 'Use `claude_manager_send` to send the following task to Claude Code:',
212
255
  argumentsText
213
- ? `Task: ${argumentsText}`
214
- : 'Task: Inspect the current repository and wait for follow-up instructions.',
215
- 'Do not add planning text before the tool call. After it completes, give a short result summary.',
256
+ ? argumentsText
257
+ : 'Inspect the current repository and wait for follow-up instructions.',
258
+ 'After it completes, review the result. If code changes were expected, use `claude_manager_git_diff` to review, then `claude_manager_git_commit` or `claude_manager_git_reset` accordingly.',
216
259
  ].join('\n\n');
217
260
  }
218
261
  if (command === 'claude-metadata') {
@@ -237,125 +280,40 @@ function buildCommandText(command, rawArguments) {
237
280
  }
238
281
  function rewriteCommandParts(parts, text) {
239
282
  let hasRewrittenText = false;
240
- const rewrittenParts = parts.map((part) => {
283
+ return parts.map((part) => {
241
284
  if (part.type !== 'text' || hasRewrittenText) {
242
285
  return part;
243
286
  }
244
287
  hasRewrittenText = true;
245
- return {
246
- ...part,
247
- text,
248
- };
288
+ return { ...part, text };
249
289
  });
250
- return rewrittenParts;
251
290
  }
252
- export function formatManagerRunToolResult(run) {
253
- const finalSummary = run.finalSummary ?? summarizeSessionOutputs(run.sessions);
254
- const output = run.sessions.length === 1
255
- ? resolveSessionOutput(run.sessions[0])
256
- : finalSummary;
291
+ function formatContextWarning(context) {
292
+ const { warningLevel, estimatedContextPercent, totalTurns, totalCostUsd } = context;
293
+ if (warningLevel === 'ok' || estimatedContextPercent === null) {
294
+ return null;
295
+ }
296
+ const templates = managerPromptRegistry.contextWarnings;
297
+ const template = warningLevel === 'critical'
298
+ ? templates.critical
299
+ : warningLevel === 'high'
300
+ ? templates.high
301
+ : templates.moderate;
302
+ return template
303
+ .replace('{percent}', String(estimatedContextPercent))
304
+ .replace('{turns}', String(totalTurns))
305
+ .replace('{cost}', totalCostUsd.toFixed(2));
306
+ }
307
+ export function formatRunToolResult(run) {
257
308
  return JSON.stringify({
258
309
  runId: run.id,
259
310
  status: run.status,
260
- output,
261
- finalSummary,
262
- sessions: run.sessions.map((session) => ({
263
- title: session.title,
264
- status: session.status,
265
- output: resolveSessionOutput(session),
266
- claudeSessionId: session.claudeSessionId,
267
- worktreeMode: session.worktreeMode,
268
- branchName: session.branchName,
269
- turns: session.turns,
270
- totalCostUsd: session.totalCostUsd,
271
- })),
272
- inspectRun: {
273
- tool: 'claude_manager_runs',
274
- runId: run.id,
275
- },
311
+ task: run.task,
312
+ sessionId: run.sessionId,
313
+ finalSummary: run.finalSummary,
314
+ messageCount: run.messages.length,
315
+ actionCount: run.actions.length,
316
+ commits: run.commits,
317
+ context: run.context,
276
318
  }, null, 2);
277
319
  }
278
- function buildRunProgressView(run) {
279
- const completed = run.sessions.filter((session) => session.status === 'completed').length;
280
- const failed = run.sessions.filter((session) => session.status === 'failed').length;
281
- const running = run.sessions.filter((session) => session.status === 'running').length;
282
- const pending = run.sessions.filter((session) => session.status === 'pending').length;
283
- const total = run.sessions.length;
284
- return {
285
- title: buildRunProgressTitle(run, { completed, failed, running, total }),
286
- metadata: {
287
- runId: run.id,
288
- status: run.status,
289
- progress: `${completed}/${total} completed`,
290
- active: running,
291
- pending,
292
- failed,
293
- sessions: run.sessions.map(formatSessionActivity),
294
- },
295
- };
296
- }
297
- function buildRunProgressTitle(run, counts) {
298
- const suffix = `(${counts.completed}/${counts.total} complete` +
299
- (counts.running > 0 ? `, ${counts.running} active` : '') +
300
- (counts.failed > 0 ? `, ${counts.failed} failed` : '') +
301
- ')';
302
- if (run.status === 'completed') {
303
- return `Claude manager completed ${suffix}`;
304
- }
305
- if (run.status === 'failed') {
306
- return `Claude manager failed ${suffix}`;
307
- }
308
- if (counts.running > 0) {
309
- return `Claude manager running ${suffix}`;
310
- }
311
- return `Claude manager queued ${suffix}`;
312
- }
313
- function formatSessionActivity(session) {
314
- const parts = [session.title, session.status];
315
- if (session.claudeSessionId) {
316
- parts.push(session.claudeSessionId);
317
- }
318
- const latestEvent = findLatestDisplayEvent(session.events);
319
- if (session.finalText) {
320
- parts.push(truncateForDisplay(session.finalText, 120));
321
- }
322
- else if (session.error) {
323
- parts.push(truncateForDisplay(session.error, 120));
324
- }
325
- else if (latestEvent) {
326
- parts.push(`${latestEvent.type}: ${truncateForDisplay(latestEvent.text, 120)}`);
327
- }
328
- return parts.join(' | ');
329
- }
330
- function findLatestDisplayEvent(events) {
331
- const reversedEvents = [...events].reverse();
332
- const preferredEvent = reversedEvents.find((event) => (event.type === 'result' ||
333
- event.type === 'error' ||
334
- event.type === 'assistant') &&
335
- Boolean(event.text.trim()));
336
- if (preferredEvent) {
337
- return preferredEvent;
338
- }
339
- return [...events]
340
- .reverse()
341
- .find((event) => event.type !== 'partial' && Boolean(event.text.trim()));
342
- }
343
- function truncateForDisplay(text, maxLength) {
344
- const normalized = text.replace(/\s+/g, ' ').trim();
345
- if (normalized.length <= maxLength) {
346
- return normalized;
347
- }
348
- return `${normalized.slice(0, maxLength - 3)}...`;
349
- }
350
- function summarizeSessionOutputs(sessions) {
351
- return sessions
352
- .map((session) => `${session.title}: ${resolveSessionOutput(session)}`)
353
- .join('\n');
354
- }
355
- function resolveSessionOutput(session) {
356
- const latestEvent = findLatestDisplayEvent(session.events);
357
- return (session.finalText?.trim() ||
358
- session.error?.trim() ||
359
- latestEvent?.text.trim() ||
360
- session.status);
361
- }
@@ -1,7 +1,7 @@
1
1
  import { ClaudeSessionService } from '../claude/claude-session.service.js';
2
- import { ManagerOrchestrator } from '../manager/manager-orchestrator.js';
2
+ import { PersistentManager } from '../manager/persistent-manager.js';
3
3
  export interface ClaudeManagerPluginServices {
4
- manager: ManagerOrchestrator;
4
+ manager: PersistentManager;
5
5
  sessions: ClaudeSessionService;
6
6
  }
7
7
  export declare function getOrCreatePluginServices(worktree: string): ClaudeManagerPluginServices;
@@ -1,11 +1,13 @@
1
1
  import { ClaudeAgentSdkAdapter } from '../claude/claude-agent-sdk-adapter.js';
2
2
  import { ClaudeSessionService } from '../claude/claude-session.service.js';
3
- import { ManagerOrchestrator } from '../manager/manager-orchestrator.js';
4
- import { TaskPlanner } from '../manager/task-planner.js';
5
3
  import { ClaudeMetadataService } from '../metadata/claude-metadata.service.js';
6
4
  import { RepoClaudeConfigReader } from '../metadata/repo-claude-config-reader.js';
7
5
  import { FileRunStateStore } from '../state/file-run-state-store.js';
8
- import { WorktreeCoordinator } from '../worktree/worktree-coordinator.js';
6
+ import { ContextTracker } from '../manager/context-tracker.js';
7
+ import { GitOperations } from '../manager/git-operations.js';
8
+ import { SessionController } from '../manager/session-controller.js';
9
+ import { PersistentManager } from '../manager/persistent-manager.js';
10
+ import { managerPromptRegistry } from '../prompts/registry.js';
9
11
  const serviceCache = new Map();
10
12
  export function getOrCreatePluginServices(worktree) {
11
13
  const cachedServices = serviceCache.get(worktree);
@@ -15,7 +17,13 @@ export function getOrCreatePluginServices(worktree) {
15
17
  const sdkAdapter = new ClaudeAgentSdkAdapter();
16
18
  const metadataService = new ClaudeMetadataService(new RepoClaudeConfigReader(), sdkAdapter);
17
19
  const sessionService = new ClaudeSessionService(sdkAdapter, metadataService);
18
- const manager = new ManagerOrchestrator(sessionService, new FileRunStateStore(), new WorktreeCoordinator(), new TaskPlanner());
20
+ const contextTracker = new ContextTracker();
21
+ const sessionController = new SessionController(sdkAdapter, contextTracker, managerPromptRegistry.claudeCodeSessionPrompt);
22
+ const gitOps = new GitOperations(worktree);
23
+ const stateStore = new FileRunStateStore();
24
+ const manager = new PersistentManager(sessionController, gitOps, stateStore, contextTracker);
25
+ // Try to restore active session state (fire and forget)
26
+ manager.tryRestore(worktree).catch(() => { });
19
27
  const services = {
20
28
  manager,
21
29
  sessions: sessionService,
@@ -1,11 +1,45 @@
1
1
  export const managerPromptRegistry = {
2
2
  managerSystemPrompt: [
3
- 'You are the OpenCode manager for Claude Code sessions.',
4
- 'Plan first, delegate carefully, and keep user-visible progress concise.',
5
- 'Prefer deterministic orchestration in code over prompt-only control flow.',
6
- ].join(' '),
7
- subagentSystemPrompt: [
8
- 'You are a Claude execution worker managed by OpenCode.',
9
- 'Stay within assigned scope, report blockers explicitly, and summarize changes with verification notes.',
10
- ].join(' '),
3
+ 'You orchestrate Claude Code through a persistent session. You are a user proxy —',
4
+ 'your job is to make Claude Code do the work, not to do it yourself.',
5
+ '',
6
+ '## Workflow',
7
+ '1. claude_manager_send — send clear, specific instructions',
8
+ '2. claude_manager_git_diff review what changed',
9
+ '3. claude_manager_git_commit checkpoint good work',
10
+ '4. claude_manager_git_reset — discard bad work',
11
+ '5. claude_manager_clear — fresh session when needed',
12
+ '',
13
+ '## Context management',
14
+ 'Check the context snapshot in each send result:',
15
+ '- Under 50%: proceed freely',
16
+ '- 50-70%: consider if next task should reuse or start fresh',
17
+ '- Over 70%: compact or clear before heavy work',
18
+ '- Over 85% or 200k tokens: clear immediately',
19
+ '',
20
+ '## Delegation principles',
21
+ '- Write specific task descriptions with file paths, function names, error messages',
22
+ '- For large features, send sequential focused instructions',
23
+ '- Tell Claude Code to use subagents for parallel/independent parts',
24
+ '- After implementation, always review with git diff before committing',
25
+ '- If work is wrong, send a correction (specific, not "try again") or reset',
26
+ ].join('\n'),
27
+ claudeCodeSessionPrompt: [
28
+ 'You are being directed by an expert automated operator. Treat each message',
29
+ 'as a precise instruction from a skilled Claude Code user.',
30
+ '',
31
+ 'Key behaviors:',
32
+ '- Execute instructions directly without asking for clarification',
33
+ '- Use the Agent tool to spawn subagents for parallel/independent work',
34
+ '- Be concise — no preamble, no restating the task',
35
+ '- Do NOT run git commit, git push, or git reset — the operator handles git',
36
+ '- After completing work, end with a brief verification summary',
37
+ '- When context is heavy, prefer targeted file reads over reading entire files',
38
+ '- Report blockers immediately and specifically',
39
+ ].join('\n'),
40
+ contextWarnings: {
41
+ moderate: 'Session context is filling up ({percent}% estimated). Consider whether a fresh session would be more efficient.',
42
+ high: 'Session context is heavy ({percent}% estimated, {turns} turns, ${cost}). Start a new session or compact first.',
43
+ critical: 'Session context is near capacity ({percent}% estimated). Clear the session immediately before continuing.',
44
+ },
11
45
  };
@@ -1,12 +1,12 @@
1
- import type { ManagerRunRecord } from '../types/contracts.js';
1
+ import type { PersistentRunRecord } from '../types/contracts.js';
2
2
  export declare class FileRunStateStore {
3
3
  private readonly baseDirectoryName;
4
4
  private readonly writeQueues;
5
5
  constructor(baseDirectoryName?: string);
6
- saveRun(run: ManagerRunRecord): Promise<void>;
7
- getRun(cwd: string, runId: string): Promise<ManagerRunRecord | null>;
8
- listRuns(cwd: string): Promise<ManagerRunRecord[]>;
9
- updateRun(cwd: string, runId: string, update: (run: ManagerRunRecord) => ManagerRunRecord): Promise<ManagerRunRecord>;
6
+ saveRun(run: PersistentRunRecord): Promise<void>;
7
+ getRun(cwd: string, runId: string): Promise<PersistentRunRecord | null>;
8
+ listRuns(cwd: string): Promise<PersistentRunRecord[]>;
9
+ updateRun(cwd: string, runId: string, update: (run: PersistentRunRecord) => PersistentRunRecord): Promise<PersistentRunRecord>;
10
10
  private getRunKey;
11
11
  private getRunsDirectory;
12
12
  private getRunPath;