oh-my-opencode-slim 1.1.1 → 1.1.2

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 (61) hide show
  1. package/README.ja-JP.md +638 -0
  2. package/README.ko-KR.md +634 -0
  3. package/README.md +44 -13
  4. package/README.zh-CN.md +627 -0
  5. package/dist/cli/background-subagents.d.ts +13 -0
  6. package/dist/cli/index.js +65 -92
  7. package/dist/cli/skills.d.ts +2 -30
  8. package/dist/cli/types.d.ts +0 -1
  9. package/dist/config/fallback-chains.d.ts +1 -0
  10. package/dist/config/schema.d.ts +7 -0
  11. package/dist/hooks/auto-update-checker/checker.d.ts +7 -1
  12. package/dist/hooks/auto-update-checker/constants.d.ts +1 -0
  13. package/dist/hooks/auto-update-checker/types.d.ts +10 -0
  14. package/dist/hooks/deepwork/index.d.ts +13 -0
  15. package/dist/index.js +300 -121
  16. package/dist/tools/ast-grep/tools.d.ts +1 -1
  17. package/dist/tools/cancel-task.d.ts +16 -0
  18. package/dist/tools/preset-manager.d.ts +6 -7
  19. package/dist/tools/subtask/tools.d.ts +6 -1
  20. package/dist/tui.js +17 -62
  21. package/dist/utils/background-job-board.d.ts +90 -0
  22. package/oh-my-opencode-slim.schema.json +11 -0
  23. package/package.json +6 -3
  24. package/dist/agents/council-master.d.ts +0 -2
  25. package/dist/background/background-manager.d.ts +0 -203
  26. package/dist/background/index.d.ts +0 -3
  27. package/dist/background/multiplexer-session-manager.d.ts +0 -70
  28. package/dist/background/subagent-depth.d.ts +0 -35
  29. package/dist/cli/divoom.d.ts +0 -23
  30. package/dist/goal/index.d.ts +0 -3
  31. package/dist/goal/manager.d.ts +0 -41
  32. package/dist/goal/prompts.d.ts +0 -4
  33. package/dist/goal/store.d.ts +0 -15
  34. package/dist/goal/types.d.ts +0 -28
  35. package/dist/integrations/divoom/index.d.ts +0 -3
  36. package/dist/integrations/divoom/status-manager.d.ts +0 -31
  37. package/dist/integrations/divoom/swift-helper-source.d.ts +0 -1
  38. package/dist/integrations/divoom/swift-transport.d.ts +0 -26
  39. package/dist/integrations/divoom/types.d.ts +0 -41
  40. package/dist/tools/background.d.ts +0 -13
  41. package/dist/tools/fork/command.d.ts +0 -28
  42. package/dist/tools/fork/files.d.ts +0 -33
  43. package/dist/tools/fork/index.d.ts +0 -10
  44. package/dist/tools/fork/state.d.ts +0 -7
  45. package/dist/tools/fork/tools.d.ts +0 -23
  46. package/dist/tools/fork/vendor.d.ts +0 -28
  47. package/dist/tools/handoff/command.d.ts +0 -29
  48. package/dist/tools/handoff/files.d.ts +0 -33
  49. package/dist/tools/handoff/index.d.ts +0 -10
  50. package/dist/tools/handoff/state.d.ts +0 -7
  51. package/dist/tools/handoff/tools.d.ts +0 -23
  52. package/dist/tools/handoff/vendor.d.ts +0 -28
  53. package/dist/tools/lsp/client.d.ts +0 -81
  54. package/dist/tools/lsp/config-store.d.ts +0 -29
  55. package/dist/tools/lsp/config.d.ts +0 -5
  56. package/dist/tools/lsp/constants.d.ts +0 -24
  57. package/dist/tools/lsp/index.d.ts +0 -4
  58. package/dist/tools/lsp/tools.d.ts +0 -5
  59. package/dist/tools/lsp/types.d.ts +0 -45
  60. package/dist/tools/lsp/utils.d.ts +0 -34
  61. package/dist/utils/tmux-debug-log.d.ts +0 -2
@@ -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,16 @@
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
+ verifyAbortMs?: number;
9
+ abortRetryIntervalMs?: number;
10
+ stableStoppedMs?: number;
11
+ deleteTimeoutMs?: number;
12
+ deleteVerifyMs?: number;
13
+ deleteStableStoppedMs?: number;
14
+ }
15
+ export declare function createCancelTaskTool(options: CancelTaskToolOptions): Record<string, ToolDefinition>;
16
+ export {};
@@ -3,13 +3,12 @@ import type { PluginConfig } from '../config';
3
3
  /**
4
4
  * Creates a preset manager for the /preset slash command.
5
5
  *
6
- * Uses the OpenCode SDK's client.config.update() to change agent models
7
- * and temperatures without restarting. The server invalidates its agent
8
- * cache and re-reads config on the next prompt.
9
- *
10
- * Note: activePreset is tracked in-memory only and resets on plugin reload.
11
- * If the user manually edits config or another mechanism changes agents,
12
- * this tracker may become stale until the next /preset call.
6
+ * Stores the requested runtime preset in plugin memory and updates the
7
+ * plugin-facing TUI snapshot. It deliberately does not call OpenCode's
8
+ * client.config.update() or instance.dispose() from command hooks because
9
+ * OpenCode continues the same command into the prompt loop after
10
+ * command.execute.before, which can break the active conversation while
11
+ * the agent registry is changing.
13
12
  */
14
13
  export declare function createPresetManager(ctx: PluginInput, config: PluginConfig): {
15
14
  handleCommandExecuteBefore: (input: {
@@ -9,12 +9,17 @@ import type { PluginInput, ToolDefinition } from '@opencode-ai/plugin';
9
9
  import type { SubagentDepthTracker } from '../../utils/subagent-depth';
10
10
  import type { SubtaskState } from './state';
11
11
  export type OpencodeClient = PluginInput['client'];
12
+ export declare const DEFAULT_SUBTASK_TIMEOUT_MS: number;
13
+ export interface CreateSubtaskToolOptions {
14
+ /** Worker timeout in ms. 0 disables the timeout. */
15
+ timeoutMs?: number;
16
+ }
12
17
  /**
13
18
  * Create the subtask tool.
14
19
  *
15
20
  * Takes the OpenCode client as a dependency for TUI and session operations.
16
21
  */
17
- export declare function createSubtaskTool(ctx: PluginInput, state: SubtaskState, depthTracker?: SubagentDepthTracker): ToolDefinition;
22
+ export declare function createSubtaskTool(ctx: PluginInput, state: SubtaskState, depthTracker?: SubagentDepthTracker, options?: CreateSubtaskToolOptions): ToolDefinition;
18
23
  /**
19
24
  * Create the read_session tool.
20
25
  *
package/dist/tui.js CHANGED
@@ -140,6 +140,13 @@ function getCustomOpenCodeConfigDir() {
140
140
  const configDir = process.env.OPENCODE_CONFIG_DIR?.trim();
141
141
  return configDir || undefined;
142
142
  }
143
+ function getConfigDir() {
144
+ const customConfigDir = getCustomOpenCodeConfigDir();
145
+ if (customConfigDir) {
146
+ return customConfigDir;
147
+ }
148
+ return getDefaultOpenCodeConfigDir();
149
+ }
143
150
  function getConfigSearchDirs() {
144
151
  const dirs = [getCustomOpenCodeConfigDir(), getDefaultOpenCodeConfigDir()];
145
152
  return dirs.filter((dir, index) => {
@@ -147,7 +154,7 @@ function getConfigSearchDirs() {
147
154
  });
148
155
  }
149
156
  function getOpenCodeConfigPaths() {
150
- const configDir = getDefaultOpenCodeConfigDir();
157
+ const configDir = getConfigDir();
151
158
  return [join(configDir, "opencode.json"), join(configDir, "opencode.jsonc")];
152
159
  }
153
160
  // src/config/council-schema.ts
@@ -330,6 +337,9 @@ var TodoContinuationConfigSchema = z2.object({
330
337
  autoEnable: z2.boolean().default(false).describe("Automatically enable auto-continue when the orchestrator session has enough todos"),
331
338
  autoEnableThreshold: z2.number().int().min(1).max(50).default(4).describe("Number of todos that triggers auto-enable (only used when autoEnable is true)")
332
339
  });
340
+ var SubtaskConfigSchema = z2.object({
341
+ timeoutMs: z2.number().int().min(0).max(24 * 60 * 60 * 1000).optional().describe("Subtask worker timeout in ms. 0 disables the timeout. Defaults to 300000 (5 minutes).")
342
+ });
333
343
  var FailoverConfigSchema = z2.object({
334
344
  enabled: z2.boolean().default(true),
335
345
  timeoutMs: z2.number().min(0).default(15000),
@@ -377,6 +387,7 @@ var PluginConfigSchema = z2.object({
377
387
  sessionManager: SessionManagerConfigSchema.optional(),
378
388
  divoom: DivoomConfigSchema.optional(),
379
389
  todoContinuation: TodoContinuationConfigSchema.optional(),
390
+ subtask: SubtaskConfigSchema.optional(),
380
391
  fallback: FailoverConfigSchema.optional(),
381
392
  council: CouncilConfigSchema.optional()
382
393
  }).superRefine((value, ctx) => {
@@ -460,65 +471,6 @@ var CUSTOM_SKILLS = [
460
471
  }
461
472
  ];
462
473
 
463
- // src/cli/skills.ts
464
- var RECOMMENDED_SKILLS = [
465
- {
466
- name: "agent-browser",
467
- repo: "https://github.com/vercel-labs/agent-browser",
468
- skillName: "agent-browser",
469
- allowedAgents: ["designer"],
470
- description: "High-performance browser automation",
471
- postInstallCommands: [
472
- "npm install -g agent-browser",
473
- "agent-browser install"
474
- ]
475
- }
476
- ];
477
- var PERMISSION_ONLY_SKILLS = [
478
- {
479
- name: "requesting-code-review",
480
- allowedAgents: ["oracle"],
481
- description: "Code review template for reviewer subagents in multi-step workflows"
482
- }
483
- ];
484
- function getSkillPermissionsForAgent(agentName, skillList) {
485
- const permissions = {
486
- "*": agentName === "orchestrator" ? "allow" : "deny"
487
- };
488
- if (skillList) {
489
- permissions["*"] = "deny";
490
- for (const name of skillList) {
491
- if (name === "*") {
492
- permissions["*"] = "allow";
493
- } else if (name.startsWith("!")) {
494
- permissions[name.slice(1)] = "deny";
495
- } else {
496
- permissions[name] = "allow";
497
- }
498
- }
499
- return permissions;
500
- }
501
- for (const skill of RECOMMENDED_SKILLS) {
502
- const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
503
- if (isAllowed) {
504
- permissions[skill.skillName] = "allow";
505
- }
506
- }
507
- for (const skill of CUSTOM_SKILLS) {
508
- const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
509
- if (isAllowed) {
510
- permissions[skill.name] = "allow";
511
- }
512
- }
513
- for (const skill of PERMISSION_ONLY_SKILLS) {
514
- const isAllowed = skill.allowedAgents.includes("*") || skill.allowedAgents.includes(agentName);
515
- if (isAllowed) {
516
- permissions[skill.name] = "allow";
517
- }
518
- }
519
- return permissions;
520
- }
521
-
522
474
  // src/cli/config-io.ts
523
475
  function stripJsonComments(json) {
524
476
  const commentPattern = /\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g;
@@ -533,7 +485,9 @@ function loadConfigFromPath(configPath, options) {
533
485
  const content = fs.readFileSync(configPath, "utf-8");
534
486
  let rawConfig;
535
487
  try {
536
- rawConfig = JSON.parse(stripJsonComments(content));
488
+ const stripped = stripJsonComments(content);
489
+ const interpolated = stripped.replace(/\{env:([^}]+)\}/g, (_, varName) => process.env[varName] ?? "");
490
+ rawConfig = JSON.parse(interpolated);
537
491
  } catch (error) {
538
492
  const message = error instanceof Error ? error.message : String(error);
539
493
  options?.onWarning?.({
@@ -612,7 +566,8 @@ function mergePluginConfigs(base, override) {
612
566
  sessionManager: deepMerge(base.sessionManager, override.sessionManager),
613
567
  divoom: deepMerge(base.divoom, override.divoom),
614
568
  fallback: deepMerge(base.fallback, override.fallback),
615
- council: deepMerge(base.council, override.council)
569
+ council: deepMerge(base.council, override.council),
570
+ subtask: deepMerge(base.subtask, override.subtask)
616
571
  };
617
572
  }
618
573
  function deepMerge(base, override) {
@@ -0,0 +1,90 @@
1
+ import { type TaskOutputState } from './task';
2
+ export interface ContextFile {
3
+ path: string;
4
+ lineCount: number;
5
+ lineNumbers?: number[];
6
+ lastReadAt: number;
7
+ }
8
+ export type BackgroundJobState = TaskOutputState | 'reconciled';
9
+ export interface BackgroundJobRecord {
10
+ taskID: string;
11
+ parentSessionID: string;
12
+ agent: string;
13
+ description: string;
14
+ objective?: string;
15
+ state: BackgroundJobState;
16
+ timedOut: boolean;
17
+ statusUncertain: boolean;
18
+ cancellationRequested: boolean;
19
+ terminalUnreconciled: boolean;
20
+ launchedAt: number;
21
+ lastLaunchedAt: number;
22
+ updatedAt: number;
23
+ lastLiveBusyAt?: number;
24
+ completedAt?: number;
25
+ resultSummary?: string;
26
+ lastStatusError?: string;
27
+ alias: string;
28
+ lastUsedAt: number;
29
+ terminalState?: TaskOutputState;
30
+ contextFiles: ContextFile[];
31
+ }
32
+ export interface BackgroundJobBoardOptions {
33
+ maxReusablePerAgent?: number;
34
+ readContextMinLines?: number;
35
+ readContextMaxFiles?: number;
36
+ }
37
+ export interface BackgroundJobLaunchInput {
38
+ taskID: string;
39
+ parentSessionID: string;
40
+ agent: string;
41
+ description?: string;
42
+ objective?: string;
43
+ now?: number;
44
+ }
45
+ export interface BackgroundJobStatusInput {
46
+ taskID: string;
47
+ state: TaskOutputState;
48
+ timedOut?: boolean;
49
+ statusUncertain?: boolean;
50
+ resultSummary?: string;
51
+ lastStatusError?: string;
52
+ now?: number;
53
+ }
54
+ export declare class BackgroundJobBoard {
55
+ private readonly jobs;
56
+ private readonly counters;
57
+ private readonly maxReusablePerAgent;
58
+ private readonly readContextMinLines;
59
+ private readonly readContextMaxFiles;
60
+ constructor(options?: BackgroundJobBoardOptions);
61
+ registerLaunch(input: BackgroundJobLaunchInput): BackgroundJobRecord;
62
+ updateStatus(input: BackgroundJobStatusInput): BackgroundJobRecord | undefined;
63
+ updateFromStatusOutput(output: string): BackgroundJobRecord | undefined;
64
+ markRunningFromLiveSession(taskID: string, now?: number): BackgroundJobRecord | undefined;
65
+ markReconciled(taskID: string, now?: number): BackgroundJobRecord | undefined;
66
+ markCancelled(taskID: string, reason?: string, now?: number, options?: {
67
+ force?: boolean;
68
+ }): BackgroundJobRecord | undefined;
69
+ get(taskID: string): BackgroundJobRecord | undefined;
70
+ resolve(parentSessionID: string, taskIDOrAlias: string): BackgroundJobRecord | undefined;
71
+ resolveForStatus(parentSessionID: string, taskIDOrAlias: string): BackgroundJobRecord | undefined;
72
+ resolveReusable(parentSessionID: string, taskIDOrAlias: string, agent?: string): BackgroundJobRecord | undefined;
73
+ markUsed(parentSessionID: string, key: string, now?: number): void;
74
+ taskIDs(): Set<string>;
75
+ addContext(taskID: string, files: ContextFile[]): void;
76
+ list(parentSessionID?: string): BackgroundJobRecord[];
77
+ hasRunning(parentSessionID: string): boolean;
78
+ hasTerminalUnreconciled(parentSessionID: string): boolean;
79
+ formatForPrompt(parentSessionID: string, now?: number): string | undefined;
80
+ clearParent(parentSessionID: string): void;
81
+ drop(taskID: string): void;
82
+ private trimReusable;
83
+ private formatReusableJob;
84
+ private nextAlias;
85
+ }
86
+ export declare function deriveTaskSessionLabel(input: {
87
+ description?: string;
88
+ prompt?: string;
89
+ agentType: string;
90
+ }): string;
@@ -599,6 +599,17 @@
599
599
  }
600
600
  }
601
601
  },
602
+ "subtask": {
603
+ "type": "object",
604
+ "properties": {
605
+ "timeoutMs": {
606
+ "description": "Subtask worker timeout in ms. 0 disables the timeout. Defaults to 300000 (5 minutes).",
607
+ "type": "integer",
608
+ "minimum": 0,
609
+ "maximum": 86400000
610
+ }
611
+ }
612
+ },
602
613
  "fallback": {
603
614
  "type": "object",
604
615
  "properties": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-slim",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
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,11 +43,14 @@
43
43
  "src/skills",
44
44
  "oh-my-opencode-slim.schema.json",
45
45
  "README.md",
46
+ "README.zh-CN.md",
47
+ "README.ja-JP.md",
48
+ "README.ko-KR.md",
46
49
  "LICENSE"
47
50
  ],
48
51
  "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",
52
+ "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",
53
+ "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
54
  "copy:divoom-assets": "bun run scripts/copy-divoom-assets.ts",
52
55
  "build": "bun run build:plugin && bun run build:cli && bun run copy:divoom-assets && tsc --emitDeclarationOnly && bun run generate-schema",
53
56
  "prepare": "bun run build",
@@ -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>;
@@ -1,3 +0,0 @@
1
- export { createGoalManager, type GoalManager } from './manager';
2
- export { GoalStore, getGoalStorePath } from './store';
3
- export type { GoalCheckpoint, GoalConfig, GoalRecord, GoalStatus, } from './types';