oh-my-opencode-slim 2.0.0-beta.0 → 2.0.0-beta.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.
Files changed (67) hide show
  1. package/README.ja-JP.md +635 -0
  2. package/README.md +19 -9
  3. package/README.zh-CN.md +624 -0
  4. package/dist/cli/index.js +9 -3
  5. package/dist/config/constants.d.ts +1 -1
  6. package/dist/config/schema.d.ts +3 -3
  7. package/dist/hooks/deepwork/index.d.ts +13 -0
  8. package/dist/hooks/index.d.ts +1 -1
  9. package/dist/hooks/phase-reminder/index.d.ts +1 -1
  10. package/dist/index.js +773 -1253
  11. package/dist/multiplexer/session-manager.d.ts +4 -1
  12. package/dist/tools/ast-grep/tools.d.ts +1 -1
  13. package/dist/tools/cancel-task.d.ts +10 -0
  14. package/dist/tools/index.d.ts +1 -2
  15. package/dist/tui.js +10 -6
  16. package/dist/utils/background-job-board.d.ts +34 -1
  17. package/dist/utils/index.d.ts +0 -1
  18. package/oh-my-opencode-slim.schema.json +1 -1
  19. package/package.json +6 -4
  20. package/src/skills/codemap.md +3 -2
  21. package/src/skills/deepwork/SKILL.md +89 -0
  22. package/dist/agents/council-master.d.ts +0 -2
  23. package/dist/background/background-manager.d.ts +0 -203
  24. package/dist/background/index.d.ts +0 -3
  25. package/dist/background/multiplexer-session-manager.d.ts +0 -70
  26. package/dist/background/subagent-depth.d.ts +0 -35
  27. package/dist/cli/divoom.d.ts +0 -23
  28. package/dist/goal/index.d.ts +0 -3
  29. package/dist/goal/manager.d.ts +0 -41
  30. package/dist/goal/prompts.d.ts +0 -4
  31. package/dist/goal/store.d.ts +0 -15
  32. package/dist/goal/types.d.ts +0 -28
  33. package/dist/hooks/session-goal/index.d.ts +0 -38
  34. package/dist/integrations/divoom/index.d.ts +0 -3
  35. package/dist/integrations/divoom/status-manager.d.ts +0 -31
  36. package/dist/integrations/divoom/swift-helper-source.d.ts +0 -1
  37. package/dist/integrations/divoom/swift-transport.d.ts +0 -26
  38. package/dist/integrations/divoom/types.d.ts +0 -41
  39. package/dist/tools/background.d.ts +0 -13
  40. package/dist/tools/fork/command.d.ts +0 -28
  41. package/dist/tools/fork/files.d.ts +0 -33
  42. package/dist/tools/fork/index.d.ts +0 -10
  43. package/dist/tools/fork/state.d.ts +0 -7
  44. package/dist/tools/fork/tools.d.ts +0 -23
  45. package/dist/tools/fork/vendor.d.ts +0 -28
  46. package/dist/tools/handoff/command.d.ts +0 -29
  47. package/dist/tools/handoff/files.d.ts +0 -33
  48. package/dist/tools/handoff/index.d.ts +0 -10
  49. package/dist/tools/handoff/state.d.ts +0 -7
  50. package/dist/tools/handoff/tools.d.ts +0 -23
  51. package/dist/tools/handoff/vendor.d.ts +0 -28
  52. package/dist/tools/lsp/client.d.ts +0 -81
  53. package/dist/tools/lsp/config-store.d.ts +0 -29
  54. package/dist/tools/lsp/config.d.ts +0 -5
  55. package/dist/tools/lsp/constants.d.ts +0 -24
  56. package/dist/tools/lsp/index.d.ts +0 -4
  57. package/dist/tools/lsp/tools.d.ts +0 -5
  58. package/dist/tools/lsp/types.d.ts +0 -45
  59. package/dist/tools/lsp/utils.d.ts +0 -34
  60. package/dist/tools/subtask/command.d.ts +0 -30
  61. package/dist/tools/subtask/files.d.ts +0 -34
  62. package/dist/tools/subtask/index.d.ts +0 -11
  63. package/dist/tools/subtask/state.d.ts +0 -7
  64. package/dist/tools/subtask/tools.d.ts +0 -23
  65. package/dist/tools/subtask/vendor.d.ts +0 -27
  66. package/dist/utils/session-manager.d.ts +0 -55
  67. package/dist/utils/tmux-debug-log.d.ts +0 -2
@@ -1,5 +1,6 @@
1
1
  import type { PluginInput } from '@opencode-ai/plugin';
2
2
  import type { MultiplexerConfig } from '../config/schema';
3
+ import type { BackgroundJobBoard } from '../utils/background-job-board';
3
4
  interface SessionEvent {
4
5
  type: string;
5
6
  properties?: {
@@ -23,6 +24,7 @@ export declare function resetMultiplexerSessionManagerState(): void;
23
24
  * with polling kept as a fallback for reliability.
24
25
  */
25
26
  export declare class MultiplexerSessionManager {
27
+ private readonly backgroundJobBoard?;
26
28
  private instanceId;
27
29
  private serverUrl;
28
30
  private directory;
@@ -33,7 +35,7 @@ export declare class MultiplexerSessionManager {
33
35
  private closingSessions;
34
36
  private pollInterval?;
35
37
  private enabled;
36
- constructor(ctx: PluginInput, config: MultiplexerConfig);
38
+ constructor(ctx: PluginInput, config: MultiplexerConfig, backgroundJobBoard?: BackgroundJobBoard | undefined);
37
39
  onSessionCreated(event: SessionEvent): Promise<void>;
38
40
  onSessionStatus(event: SessionEvent): Promise<void>;
39
41
  onSessionDeleted(event: SessionEvent): Promise<void>;
@@ -46,6 +48,7 @@ export declare class MultiplexerSessionManager {
46
48
  private isTrackedOrSpawning;
47
49
  private updatePolling;
48
50
  private getSessionId;
51
+ private isRunningBackgroundJob;
49
52
  cleanup(): Promise<void>;
50
53
  }
51
54
  /**
@@ -1,3 +1,3 @@
1
- import { type ToolDefinition } from '@opencode-ai/plugin/tool';
1
+ import { type ToolDefinition } from '@opencode-ai/plugin';
2
2
  export declare const ast_grep_search: ToolDefinition;
3
3
  export declare const ast_grep_replace: ToolDefinition;
@@ -0,0 +1,10 @@
1
+ import { type PluginInput, type ToolDefinition } from '@opencode-ai/plugin';
2
+ import type { BackgroundJobBoard } from '../utils/background-job-board';
3
+ interface CancelTaskToolOptions {
4
+ client: PluginInput['client'];
5
+ backgroundJobBoard: BackgroundJobBoard;
6
+ shouldManageSession: (sessionID: string) => boolean;
7
+ abortTimeoutMs?: number;
8
+ }
9
+ export declare function createCancelTaskTool(options: CancelTaskToolOptions): Record<string, ToolDefinition>;
10
+ export {};
@@ -1,7 +1,6 @@
1
1
  export { ast_grep_replace, ast_grep_search } from './ast-grep';
2
+ export { createCancelTaskTool } from './cancel-task';
2
3
  export { createCouncilTool } from './council';
3
4
  export type { PresetManager } from './preset-manager';
4
5
  export { createPresetManager } from './preset-manager';
5
6
  export { createWebfetchTool } from './smartfetch';
6
- export type { SubtaskCommandManager } from './subtask';
7
- export { createReadSessionTool, createSubtaskCommandManager, createSubtaskState, createSubtaskTool, } from './subtask';
package/dist/tui.js CHANGED
@@ -68,9 +68,7 @@ var POLL_INTERVAL_BACKGROUND_MS = 2000;
68
68
  var DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
69
69
  var MAX_POLL_TIME_MS = 5 * 60 * 1000;
70
70
  var DEFAULT_MAX_SUBAGENT_DEPTH = 3;
71
- var PHASE_REMINDER_TEXT = `!IMPORTANT! Recall the workflow rules:
72
- Understand → build a short work graph with independent lanes, dependencies, and advisory ownership → dispatch independent specialists as background tasks → record task/session IDs → continue orchestration → poll task_status for terminal results → reconcile → verify.
73
- Only consume outputs or advance dependent work when background results are terminal. !END!`;
71
+ var PHASE_REMINDER_TEXT = `!IMPORTANT! Scheduler workflow: plan lanes/dependencies → dispatch background specialists → track task IDs → wait for hook-driven completion or use task_status only when needed → reconcile terminal results → verify. Do not consume running-job output or advance dependent work. !END!`;
74
72
  var TMUX_SPAWN_DELAY_MS = 500;
75
73
  var COUNCILLOR_STAGGER_MS = 250;
76
74
  var DEFAULT_DISABLED_AGENTS = ["observer"];
@@ -308,7 +306,7 @@ var InterviewConfigSchema = z2.object({
308
306
  port: z2.number().int().min(0).max(65535).default(0),
309
307
  dashboard: z2.boolean().default(false)
310
308
  });
311
- var SessionManagerConfigSchema = z2.object({
309
+ var BackgroundJobsConfigSchema = z2.object({
312
310
  maxSessionsPerAgent: z2.number().int().min(1).max(10).default(2),
313
311
  readContextMinLines: z2.number().int().min(0).max(1000).default(10),
314
312
  readContextMaxFiles: z2.number().int().min(0).max(50).default(8)
@@ -374,7 +372,7 @@ var PluginConfigSchema = z2.object({
374
372
  tmux: TmuxConfigSchema.optional(),
375
373
  websearch: WebsearchConfigSchema.optional(),
376
374
  interview: InterviewConfigSchema.optional(),
377
- sessionManager: SessionManagerConfigSchema.optional(),
375
+ backgroundJobs: BackgroundJobsConfigSchema.optional(),
378
376
  divoom: DivoomConfigSchema.optional(),
379
377
  todoContinuation: TodoContinuationConfigSchema.optional(),
380
378
  fallback: FailoverConfigSchema.optional(),
@@ -457,6 +455,12 @@ var CUSTOM_SKILLS = [
457
455
  description: "Clone important dependency source for local inspection",
458
456
  allowedAgents: ["orchestrator"],
459
457
  sourcePath: "src/skills/clonedeps"
458
+ },
459
+ {
460
+ name: "deepwork",
461
+ description: "Heavy/complex coding sessions and large modifications workflow",
462
+ allowedAgents: ["orchestrator"],
463
+ sourcePath: "src/skills/deepwork"
460
464
  }
461
465
  ];
462
466
 
@@ -552,7 +556,7 @@ function mergePluginConfigs(base, override) {
552
556
  tmux: deepMerge(base.tmux, override.tmux),
553
557
  multiplexer: deepMerge(base.multiplexer, override.multiplexer),
554
558
  interview: deepMerge(base.interview, override.interview),
555
- sessionManager: deepMerge(base.sessionManager, override.sessionManager),
559
+ backgroundJobs: deepMerge(base.backgroundJobs, override.backgroundJobs),
556
560
  divoom: deepMerge(base.divoom, override.divoom),
557
561
  fallback: deepMerge(base.fallback, override.fallback),
558
562
  council: deepMerge(base.council, override.council)
@@ -1,4 +1,10 @@
1
1
  import { type TaskOutputState } from './task';
2
+ export interface ContextFile {
3
+ path: string;
4
+ lineCount: number;
5
+ lineNumbers?: number[];
6
+ lastReadAt: number;
7
+ }
2
8
  export type BackgroundJobState = TaskOutputState | 'reconciled';
3
9
  export interface BackgroundJobRecord {
4
10
  taskID: string;
@@ -10,10 +16,19 @@ export interface BackgroundJobRecord {
10
16
  timedOut: boolean;
11
17
  terminalUnreconciled: boolean;
12
18
  launchedAt: number;
19
+ lastLaunchedAt: number;
13
20
  updatedAt: number;
14
21
  completedAt?: number;
15
22
  resultSummary?: string;
16
23
  alias: string;
24
+ lastUsedAt: number;
25
+ terminalState?: TaskOutputState;
26
+ contextFiles: ContextFile[];
27
+ }
28
+ export interface BackgroundJobBoardOptions {
29
+ maxReusablePerAgent?: number;
30
+ readContextMinLines?: number;
31
+ readContextMaxFiles?: number;
17
32
  }
18
33
  export interface BackgroundJobLaunchInput {
19
34
  taskID: string;
@@ -33,16 +48,34 @@ export interface BackgroundJobStatusInput {
33
48
  export declare class BackgroundJobBoard {
34
49
  private readonly jobs;
35
50
  private readonly counters;
51
+ private readonly maxReusablePerAgent;
52
+ private readonly readContextMinLines;
53
+ private readonly readContextMaxFiles;
54
+ constructor(options?: BackgroundJobBoardOptions);
36
55
  registerLaunch(input: BackgroundJobLaunchInput): BackgroundJobRecord;
37
56
  updateStatus(input: BackgroundJobStatusInput): BackgroundJobRecord | undefined;
38
57
  updateFromStatusOutput(output: string): BackgroundJobRecord | undefined;
39
58
  markReconciled(taskID: string, now?: number): BackgroundJobRecord | undefined;
59
+ markCancelled(taskID: string, reason?: string, now?: number): BackgroundJobRecord | undefined;
40
60
  get(taskID: string): BackgroundJobRecord | undefined;
61
+ resolve(parentSessionID: string, taskIDOrAlias: string): BackgroundJobRecord | undefined;
62
+ resolveForStatus(parentSessionID: string, taskIDOrAlias: string): BackgroundJobRecord | undefined;
63
+ resolveReusable(parentSessionID: string, taskIDOrAlias: string, agent?: string): BackgroundJobRecord | undefined;
64
+ markUsed(parentSessionID: string, key: string, now?: number): void;
65
+ taskIDs(): Set<string>;
66
+ addContext(taskID: string, files: ContextFile[]): void;
41
67
  list(parentSessionID?: string): BackgroundJobRecord[];
42
68
  hasRunning(parentSessionID: string): boolean;
43
69
  hasTerminalUnreconciled(parentSessionID: string): boolean;
44
- formatForPrompt(parentSessionID: string): string | undefined;
70
+ formatForPrompt(parentSessionID: string, now?: number): string | undefined;
45
71
  clearParent(parentSessionID: string): void;
46
72
  drop(taskID: string): void;
73
+ private trimReusable;
74
+ private formatReusableJob;
47
75
  private nextAlias;
48
76
  }
77
+ export declare function deriveTaskSessionLabel(input: {
78
+ description?: string;
79
+ prompt?: string;
80
+ agentType: string;
81
+ }): string;
@@ -5,6 +5,5 @@ export * from './internal-initiator';
5
5
  export { getLogDir, initLogger, log, resetLogger } from './logger';
6
6
  export * from './polling';
7
7
  export * from './session';
8
- export * from './session-manager';
9
8
  export * from './task';
10
9
  export { extractZip } from './zip-extractor';
@@ -486,7 +486,7 @@
486
486
  }
487
487
  }
488
488
  },
489
- "sessionManager": {
489
+ "backgroundJobs": {
490
490
  "type": "object",
491
491
  "properties": {
492
492
  "maxSessionsPerAgent": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-slim",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.10",
4
4
  "description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -43,13 +43,15 @@
43
43
  "src/skills",
44
44
  "oh-my-opencode-slim.schema.json",
45
45
  "README.md",
46
+ "README.zh-CN.md",
46
47
  "LICENSE"
47
48
  ],
48
49
  "scripts": {
49
- "build:plugin": "bun build src/index.ts src/tui.ts --outdir dist --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/sdk --external @opentui/core --external @opentui/solid --external jsdom --external zod",
50
- "build:cli": "bun build src/cli/index.ts --outdir dist/cli --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/sdk --external jsdom --external zod",
50
+ "clean:dist": "bun -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
51
+ "build:plugin": "bun build src/index.ts src/tui.ts --outdir dist --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/plugin/* --external @opencode-ai/sdk --external @opencode-ai/sdk/* --external @opentui/core --external @opentui/solid --external jsdom --external zod",
52
+ "build:cli": "bun build src/cli/index.ts --outdir dist/cli --target node --format esm --external @ast-grep/napi --external @opencode-ai/plugin --external @opencode-ai/plugin/* --external @opencode-ai/sdk --external @opencode-ai/sdk/* --external jsdom --external zod",
51
53
  "copy:divoom-assets": "bun run scripts/copy-divoom-assets.ts",
52
- "build": "bun run build:plugin && bun run build:cli && bun run copy:divoom-assets && tsc --emitDeclarationOnly && bun run generate-schema",
54
+ "build": "bun run clean:dist && bun run build:plugin && bun run build:cli && bun run copy:divoom-assets && tsc --emitDeclarationOnly && bun run generate-schema",
53
55
  "prepare": "bun run build",
54
56
  "contributors:add": "all-contributors add",
55
57
  "contributors:check": "all-contributors check",
@@ -18,6 +18,7 @@
18
18
  - `src/skills/codemap/` (command-style repository mapping skill)
19
19
  - `src/skills/clonedeps/` (workflow skill for dependency source mirroring)
20
20
  - `src/skills/simplify/` (readability/refactor guidance skill)
21
+ - `src/skills/deepwork/` (orchestrator-only workflow for heavy coding sessions)
21
22
  - Files are considered static runtime payload. No plugin TS module in `src/` imports these files directly; they
22
23
  are loaded by OpenCode via filesystem installation.
23
24
 
@@ -38,6 +39,6 @@
38
39
  bundled skills when agent policy is derived from built-in recommendations.
39
40
  - `verify-release-artifact.ts` enforces artifact completeness by asserting key
40
41
  bundled skill payloads such as `src/skills/simplify/SKILL.md`,
41
- `src/skills/codemap/SKILL.md`, and `src/skills/clonedeps/SKILL.md` are present
42
- in the tarball.
42
+ `src/skills/codemap/SKILL.md`, `src/skills/clonedeps/SKILL.md`, and
43
+ `src/skills/deepwork/SKILL.md` are present in the tarball.
43
44
  - `package.json` scripts (`verify:release`, `build`) rely on these assets to ensure install-time skill availability.
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: deepwork
3
+ description: Orchestrator-only workflow for heavy coding sessions, multi-phase implementation, and risky refactors. Use for complex work that needs planning, review gates, and persistent progress tracking.
4
+ ---
5
+
6
+ # Deepwork
7
+
8
+ Deepwork is an orchestrator workflow for heavy coding sessions. Use it when the
9
+ work is broad, risky, multi-file, or likely to span several implementation
10
+ phases. Do not use it for trivial edits, quick docs changes, or simple bug fixes.
11
+
12
+ ## Core Contract
13
+
14
+ When deepwork is active, the orchestrator must manage the work as a scheduler,
15
+ not as the default implementation worker.
16
+
17
+ Required behavior:
18
+
19
+ - keep OpenCode todos aligned with the active deepwork phase;
20
+ - create and maintain a local markdown progress file under `.slim/deepwork/`;
21
+ - write valuable research findings into that file as confirmed research context
22
+ when they are received and reconciled;
23
+ - draft a plan before implementation;
24
+ - ask `@oracle` to review the plan and revise it until acceptable;
25
+ - create a phased implementation/delegation plan;
26
+ - before oracle reviews, add relevant confirmed research findings and file
27
+ references to the deepwork file so oracle can review the plan or phase from
28
+ accepted context instead of redoing discovery;
29
+ - ask `@oracle` to review that implementation plan before execution;
30
+ - after oracle review and before each implementation phase, decide the execution
31
+ path: what can run in parallel, what must be sequential, which specialists to
32
+ delegate to, and whether to split the same agent into multiple bounded lanes;
33
+ - after each phase, validate, update the deepwork file, prepare the plan file
34
+ for oracle review and ask `@oracle` to review the phase result, fix
35
+ actionable issues, then continue;
36
+ - finish with final validation and a concise summary.
37
+
38
+ ## Deepwork File
39
+
40
+ Create a task-specific file such as:
41
+
42
+ ```text
43
+ .slim/deepwork/<short-task-slug>.md
44
+ ```
45
+
46
+ Keep `.slim/deepwork/` out of git, but make it readable to OpenCode. Ensure the
47
+ project ignore files include:
48
+
49
+ ```gitignore
50
+ # .gitignore
51
+ .slim/deepwork/
52
+ ```
53
+
54
+ ```gitignore
55
+ # .ignore
56
+ !.slim/deepwork/
57
+ !.slim/deepwork/**
58
+ ```
59
+
60
+ Do not follow a rigid template. Choose whatever markdown structure best fits the
61
+ work. The file only needs to remain useful as persistent session state and should
62
+ capture, as applicable:
63
+
64
+ - current goal and understanding;
65
+ - researched, factual context from `@librarian` to avoid oracle doing its own
66
+ research;
67
+ - plan drafts and oracle review notes;
68
+ - implementation phases and status;
69
+ - validation results;
70
+ - unresolved questions, blockers, and follow-ups.
71
+
72
+ Update this file after major decisions, valuable specialist research, reviews,
73
+ phase completions, validation results, and scope changes.
74
+ When `@librarian` docs, code reads, or external references produce useful
75
+ information, reconcile the result and record the accepted findings here so later
76
+ planning and reviews share the same context instead of rediscovering it.
77
+ Don't put actual contents of local files, reference them by path only.
78
+
79
+ ## Scheduler Discipline
80
+
81
+ Use the scheduler model throughout:
82
+
83
+ - follow Orchestrator delegations rules
84
+ - record task/session IDs and ownership boundaries;
85
+ - poll `task_status` before consuming background results;
86
+ - avoid blocking Orchestrator lane too long; prefer shorter periodic task waits
87
+ rather than one long wait;
88
+ - do not advance to the next phase while relevant jobs are running or terminal
89
+ results are unreconciled.
@@ -1,2 +0,0 @@
1
- import { type AgentDefinition } from './orchestrator';
2
- export declare function createCouncilMasterAgent(model: string, customPrompt?: string, customAppendPrompt?: string): AgentDefinition;
@@ -1,203 +0,0 @@
1
- /**
2
- * Background Task Manager
3
- *
4
- * Manages long-running AI agent tasks that execute in separate sessions.
5
- * Background tasks run independently from the main conversation flow, allowing
6
- * the user to continue working while tasks complete asynchronously.
7
- *
8
- * Key features:
9
- * - Fire-and-forget launch (returns task_id immediately)
10
- * - Creates isolated sessions for background work
11
- * - Event-driven completion detection via session.status
12
- * - Start queue with configurable concurrency limit
13
- * - Supports task cancellation and result retrieval
14
- */
15
- import type { PluginInput } from '@opencode-ai/plugin';
16
- import type { BackgroundTaskConfig, PluginConfig } from '../config';
17
- import type { MultiplexerConfig } from '../config/schema';
18
- import { SubagentDepthTracker } from './subagent-depth';
19
- export declare function loadPersistedTask(taskId: string): BackgroundTask | null;
20
- /**
21
- * Represents a background task running in an isolated session.
22
- * Tasks are tracked from creation through completion or failure.
23
- */
24
- export interface BackgroundTask {
25
- id: string;
26
- sessionId?: string;
27
- description: string;
28
- agent: string;
29
- status: 'pending' | 'starting' | 'running' | 'completed' | 'failed' | 'cancelled';
30
- result?: string;
31
- error?: string;
32
- config: BackgroundTaskConfig;
33
- parentSessionId: string;
34
- startedAt: Date;
35
- completedAt?: Date;
36
- prompt: string;
37
- questions: string[];
38
- }
39
- /**
40
- * Options for launching a new background task.
41
- */
42
- export interface LaunchOptions {
43
- agent: string;
44
- prompt: string;
45
- description: string;
46
- parentSessionId: string;
47
- }
48
- export declare class BackgroundTaskManager {
49
- private tasks;
50
- private tasksBySessionId;
51
- private agentBySessionId;
52
- private depthTracker;
53
- private client;
54
- private directory;
55
- private tmuxEnabled;
56
- private config?;
57
- private backgroundConfig;
58
- private disabledAgents;
59
- private startQueue;
60
- private activeStarts;
61
- private maxConcurrentStarts;
62
- private completionResolvers;
63
- constructor(ctx: PluginInput, multiplexerConfig?: MultiplexerConfig, config?: PluginConfig);
64
- /**
65
- * Look up the delegation rules for an agent type.
66
- * Unknown agent types default to explorer-only access, making it easy
67
- * to add new background agent types without updating SUBAGENT_DELEGATION_RULES.
68
- */
69
- private getSubagentRules;
70
- /**
71
- * Resolve the agent associated with a session.
72
- * Untracked sessions are treated as orchestrator sessions by default.
73
- */
74
- private getSessionAgent;
75
- /**
76
- * Check if a parent session is allowed to delegate to a specific agent type.
77
- * @param parentSessionId - The session ID of the parent
78
- * @param requestedAgent - The agent type being requested
79
- * @returns true if allowed, false if not
80
- */
81
- isAgentAllowed(parentSessionId: string, requestedAgent: string): boolean;
82
- /**
83
- * Get the list of allowed subagents for a parent session.
84
- * @param parentSessionId - The session ID of the parent
85
- * @returns Array of allowed agent names, empty if none
86
- */
87
- getAllowedSubagents(parentSessionId: string): readonly string[];
88
- /**
89
- * Launch a new background task (fire-and-forget).
90
- *
91
- * Phase A (sync): Creates task record and returns immediately.
92
- * Phase B (async): Session creation and prompt sending happen in background.
93
- *
94
- * @param opts - Task configuration options
95
- * @returns The created background task with pending status
96
- */
97
- launch(opts: LaunchOptions): BackgroundTask;
98
- /**
99
- * Enqueue task for background start.
100
- */
101
- private enqueueStart;
102
- /**
103
- * Process start queue with concurrency limit.
104
- */
105
- private processQueue;
106
- private resolveFallbackChain;
107
- /**
108
- * Calculate tool permissions for a spawned agent based on its own delegation rules.
109
- * Agents that cannot delegate (leaf nodes) get delegation tools disabled entirely,
110
- * preventing models from even seeing tools they can never use.
111
- *
112
- * @param agentName - The agent type being spawned
113
- * @returns Tool permissions object with background_task and task enabled/disabled
114
- */
115
- private calculateToolPermissions;
116
- /**
117
- * Start a task in the background (Phase B).
118
- */
119
- private startTask;
120
- /**
121
- * Handle session.status events for completion detection.
122
- * Uses session.status instead of deprecated session.idle.
123
- */
124
- handleSessionStatus(event: {
125
- type: string;
126
- properties?: {
127
- sessionID?: string;
128
- status?: {
129
- type: string;
130
- };
131
- };
132
- }): Promise<void>;
133
- /**
134
- * Handle session.deleted events for cleanup.
135
- * When a session is deleted, cancel associated tasks and clean up.
136
- */
137
- handleSessionDeleted(event: {
138
- type: string;
139
- properties?: {
140
- info?: {
141
- id?: string;
142
- };
143
- sessionID?: string;
144
- };
145
- }): Promise<void>;
146
- /**
147
- * Extract task result and mark complete.
148
- * When retry_on_empty is enabled (default), empty responses are
149
- * treated as failures so the fallback chain can retry.
150
- * When disabled, empty responses succeed with an empty string result.
151
- */
152
- private extractAndCompleteTask;
153
- /**
154
- * Complete a task and notify waiting callers.
155
- */
156
- private completeTask;
157
- /**
158
- * Send completion notification to parent session.
159
- */
160
- private sendCompletionNotification;
161
- /**
162
- * Retrieve the current state of a background task.
163
- *
164
- * Checks in-memory first. If not found (e.g. after plugin reinitialization
165
- * caused by context compaction), falls back to the persisted state on disk.
166
- *
167
- * @param taskId - The task ID to retrieve
168
- * @returns The task object, or null if not found in memory or on disk
169
- */
170
- getResult(taskId: string): BackgroundTask | null;
171
- /**
172
- * Add a question relayed from a background subagent via ask_orchestrator.
173
- * Resolves the task from the session ID in toolContext.
174
- * Returns true if the question was recorded, false if the task wasn't found
175
- * or is no longer active (completed/failed/cancelled).
176
- *
177
- * Questions are persisted to disk immediately for crash safety.
178
- */
179
- addQuestion(sessionId: string, question: string): 'recorded' | 'not-found' | 'terminal' | 'cap-reached';
180
- /**
181
- * Wait for a task to complete.
182
- *
183
- * @param taskId - The task ID to wait for
184
- * @param timeout - Maximum time to wait in milliseconds (0 = no timeout)
185
- * @returns The completed task, or null if not found/timeout
186
- */
187
- waitForCompletion(taskId: string, timeout?: number): Promise<BackgroundTask | null>;
188
- /**
189
- * Cancel one or all running background tasks.
190
- *
191
- * @param taskId - Optional task ID to cancel. If omitted, cancels all pending/running tasks.
192
- * @returns Number of tasks cancelled
193
- */
194
- cancel(taskId?: string): number;
195
- /**
196
- * Clean up all tasks.
197
- */
198
- cleanup(): void;
199
- /**
200
- * Get the depth tracker instance for use by other managers.
201
- */
202
- getDepthTracker(): SubagentDepthTracker;
203
- }
@@ -1,3 +0,0 @@
1
- export { type BackgroundTask, BackgroundTaskManager, type LaunchOptions, loadPersistedTask, } from './background-manager';
2
- export { MultiplexerSessionManager, TmuxSessionManager, } from './multiplexer-session-manager';
3
- export { SubagentDepthTracker } from './subagent-depth';
@@ -1,70 +0,0 @@
1
- import type { PluginInput } from '@opencode-ai/plugin';
2
- import type { MultiplexerConfig } from '../config/schema';
3
- /**
4
- * Event shape for session events
5
- */
6
- interface SessionEvent {
7
- type: string;
8
- properties?: {
9
- info?: {
10
- id?: string;
11
- parentID?: string;
12
- title?: string;
13
- directory?: string;
14
- };
15
- sessionID?: string;
16
- status?: {
17
- type: string;
18
- };
19
- };
20
- }
21
- /**
22
- * MultiplexerSessionManager tracks child sessions and spawns/closes multiplexer panes for them.
23
- *
24
- * Uses session.status events for completion detection instead of polling.
25
- * Supports both tmux and zellij multiplexers.
26
- */
27
- export declare class MultiplexerSessionManager {
28
- private client;
29
- private serverUrl;
30
- private directory;
31
- private multiplexer;
32
- private sessions;
33
- private pollInterval?;
34
- private enabled;
35
- constructor(ctx: PluginInput, config: MultiplexerConfig);
36
- /**
37
- * Handle session.created events.
38
- * Spawns a multiplexer pane for child sessions (those with parentID).
39
- */
40
- onSessionCreated(event: SessionEvent): Promise<void>;
41
- /**
42
- * Handle session.status events for completion detection.
43
- * Uses session.status instead of deprecated session.idle.
44
- *
45
- * When a session becomes idle (completed), close its pane.
46
- */
47
- onSessionStatus(event: SessionEvent): Promise<void>;
48
- /**
49
- * Handle session.deleted events.
50
- * When a session is deleted, close its multiplexer pane immediately.
51
- */
52
- onSessionDeleted(event: SessionEvent): Promise<void>;
53
- private startPolling;
54
- private stopPolling;
55
- /**
56
- * Poll sessions for status updates (fallback for reliability).
57
- * Also handles timeout and missing session detection.
58
- */
59
- private pollSessions;
60
- private closeSession;
61
- /**
62
- * Clean up all tracked sessions.
63
- */
64
- cleanup(): Promise<void>;
65
- }
66
- /**
67
- * @deprecated Use MultiplexerSessionManager instead
68
- */
69
- export declare const TmuxSessionManager: typeof MultiplexerSessionManager;
70
- export {};
@@ -1,35 +0,0 @@
1
- /**
2
- * Tracks subagent spawn depth to prevent excessive nesting.
3
- *
4
- * Depth 0 = root session (user's main conversation)
5
- * Depth 1 = agent spawned by root (e.g., explorer, council)
6
- * Depth 2 = agent spawned by depth-1 agent (e.g., councillor spawned by council)
7
- * Depth 3 = agent spawned by depth-2 agent (max depth by default)
8
- *
9
- * When max depth is exceeded, the spawn is blocked.
10
- */
11
- export declare class SubagentDepthTracker {
12
- private depthBySession;
13
- private readonly _maxDepth;
14
- constructor(maxDepth?: number);
15
- /** Maximum allowed depth. */
16
- get maxDepth(): number;
17
- /**
18
- * Get the current depth of a session.
19
- * Root sessions (not tracked) have depth 0.
20
- */
21
- getDepth(sessionId: string): number;
22
- /**
23
- * Register a child session and check if the spawn is allowed.
24
- * @returns true if allowed, false if max depth exceeded
25
- */
26
- registerChild(parentSessionId: string, childSessionId: string): boolean;
27
- /**
28
- * Clean up session tracking when a session is deleted.
29
- */
30
- cleanup(sessionId: string): void;
31
- /**
32
- * Clean up all tracking data.
33
- */
34
- cleanupAll(): void;
35
- }
@@ -1,23 +0,0 @@
1
- import type { DivoomStatus } from '../integrations/divoom/types';
2
- export type DivoomCliResult = {
3
- exitCode: number;
4
- message?: string;
5
- error?: string;
6
- };
7
- export type DivoomCliOptions = {
8
- cwd?: string;
9
- dryRun?: boolean;
10
- detector?: () => Promise<string | null>;
11
- transportFactory?: (config: {
12
- status: DivoomStatus;
13
- directory: string;
14
- }) => {
15
- sendStatus(update: {
16
- status: DivoomStatus;
17
- reason: string;
18
- timestamp: number;
19
- }): Promise<void>;
20
- };
21
- };
22
- export declare function runDivoomCli(args: string[], options?: DivoomCliOptions): Promise<DivoomCliResult>;
23
- export declare function detectDivoomAddress(): Promise<string | null>;