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.
- package/README.ja-JP.md +638 -0
- package/README.ko-KR.md +634 -0
- package/README.md +44 -13
- package/README.zh-CN.md +627 -0
- package/dist/cli/background-subagents.d.ts +13 -0
- package/dist/cli/index.js +65 -92
- package/dist/cli/skills.d.ts +2 -30
- package/dist/cli/types.d.ts +0 -1
- package/dist/config/fallback-chains.d.ts +1 -0
- package/dist/config/schema.d.ts +7 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +7 -1
- package/dist/hooks/auto-update-checker/constants.d.ts +1 -0
- package/dist/hooks/auto-update-checker/types.d.ts +10 -0
- package/dist/hooks/deepwork/index.d.ts +13 -0
- package/dist/index.js +300 -121
- package/dist/tools/ast-grep/tools.d.ts +1 -1
- package/dist/tools/cancel-task.d.ts +16 -0
- package/dist/tools/preset-manager.d.ts +6 -7
- package/dist/tools/subtask/tools.d.ts +6 -1
- package/dist/tui.js +17 -62
- package/dist/utils/background-job-board.d.ts +90 -0
- package/oh-my-opencode-slim.schema.json +11 -0
- package/package.json +6 -3
- package/dist/agents/council-master.d.ts +0 -2
- package/dist/background/background-manager.d.ts +0 -203
- package/dist/background/index.d.ts +0 -3
- package/dist/background/multiplexer-session-manager.d.ts +0 -70
- package/dist/background/subagent-depth.d.ts +0 -35
- package/dist/cli/divoom.d.ts +0 -23
- package/dist/goal/index.d.ts +0 -3
- package/dist/goal/manager.d.ts +0 -41
- package/dist/goal/prompts.d.ts +0 -4
- package/dist/goal/store.d.ts +0 -15
- package/dist/goal/types.d.ts +0 -28
- package/dist/integrations/divoom/index.d.ts +0 -3
- package/dist/integrations/divoom/status-manager.d.ts +0 -31
- package/dist/integrations/divoom/swift-helper-source.d.ts +0 -1
- package/dist/integrations/divoom/swift-transport.d.ts +0 -26
- package/dist/integrations/divoom/types.d.ts +0 -41
- package/dist/tools/background.d.ts +0 -13
- package/dist/tools/fork/command.d.ts +0 -28
- package/dist/tools/fork/files.d.ts +0 -33
- package/dist/tools/fork/index.d.ts +0 -10
- package/dist/tools/fork/state.d.ts +0 -7
- package/dist/tools/fork/tools.d.ts +0 -23
- package/dist/tools/fork/vendor.d.ts +0 -28
- package/dist/tools/handoff/command.d.ts +0 -29
- package/dist/tools/handoff/files.d.ts +0 -33
- package/dist/tools/handoff/index.d.ts +0 -10
- package/dist/tools/handoff/state.d.ts +0 -7
- package/dist/tools/handoff/tools.d.ts +0 -23
- package/dist/tools/handoff/vendor.d.ts +0 -28
- package/dist/tools/lsp/client.d.ts +0 -81
- package/dist/tools/lsp/config-store.d.ts +0 -29
- package/dist/tools/lsp/config.d.ts +0 -5
- package/dist/tools/lsp/constants.d.ts +0 -24
- package/dist/tools/lsp/index.d.ts +0 -4
- package/dist/tools/lsp/tools.d.ts +0 -5
- package/dist/tools/lsp/types.d.ts +0 -45
- package/dist/tools/lsp/utils.d.ts +0 -34
- package/dist/utils/tmux-debug-log.d.ts +0 -2
|
@@ -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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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,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
|
-
}
|
package/dist/cli/divoom.d.ts
DELETED
|
@@ -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>;
|
package/dist/goal/index.d.ts
DELETED