oh-my-opencode-slim 2.0.0-beta.8 → 2.0.0
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 +86 -32
- package/README.ko-KR.md +690 -0
- package/README.md +118 -45
- package/README.zh-CN.md +97 -37
- package/dist/cli/background-subagents.d.ts +13 -0
- package/dist/cli/companion.d.ts +4 -0
- package/dist/cli/index.d.ts +2 -1
- package/dist/cli/index.js +624 -96
- package/dist/cli/install.d.ts +6 -1
- package/dist/cli/providers.d.ts +2 -1
- package/dist/cli/types.d.ts +8 -0
- package/dist/companion/manager.d.ts +38 -0
- package/dist/config/constants.d.ts +4 -1
- package/dist/config/fallback-chains.d.ts +1 -0
- package/dist/config/schema.d.ts +46 -40
- 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/index.d.ts +0 -2
- package/dist/hooks/json-error-recovery/hook.d.ts +1 -1
- package/dist/hooks/phase-reminder/index.d.ts +1 -1
- package/dist/index.js +1996 -2132
- package/dist/mcp/grep-app.d.ts +1 -1
- package/dist/multiplexer/zellij/index.d.ts +17 -3
- package/dist/tools/cancel-task.d.ts +16 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/preset-manager.d.ts +6 -7
- package/dist/tui.js +71 -32
- package/dist/utils/background-job-board.d.ts +40 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/task.d.ts +2 -0
- package/oh-my-opencode-slim.schema.json +34 -91
- package/package.json +4 -3
- package/src/skills/codemap.md +3 -1
- package/src/skills/deepwork/SKILL.md +25 -3
- package/src/skills/oh-my-opencode-slim/SKILL.md +326 -0
- package/dist/divoom/council.gif +0 -0
- package/dist/divoom/designer.gif +0 -0
- package/dist/divoom/explorer.gif +0 -0
- package/dist/divoom/fixer.gif +0 -0
- package/dist/divoom/input.gif +0 -0
- package/dist/divoom/intro.gif +0 -0
- package/dist/divoom/librarian.gif +0 -0
- package/dist/divoom/manager.d.ts +0 -57
- package/dist/divoom/oracle.gif +0 -0
- package/dist/divoom/orchestrator.gif +0 -0
- package/dist/hooks/goal/index.d.ts +0 -38
- package/dist/hooks/todo-continuation/index.d.ts +0 -55
- package/dist/hooks/todo-continuation/todo-hygiene.d.ts +0 -35
- package/dist/utils/session-manager.d.ts +0 -55
package/dist/mcp/grep-app.d.ts
CHANGED
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Zellij multiplexer implementation
|
|
3
3
|
*
|
|
4
|
-
* Creates
|
|
4
|
+
* Creates panes for sub-agent sessions in Zellij.
|
|
5
|
+
*
|
|
6
|
+
* The default mode creates a dedicated "opencode-agents" tab:
|
|
5
7
|
* - First sub-agent uses the default pane from new-tab
|
|
6
8
|
* - Subsequent sub-agents create new panes
|
|
7
9
|
* - User stays in their original tab
|
|
10
|
+
*
|
|
11
|
+
* The optional "current-tab" mode creates panes in the tab containing the
|
|
12
|
+
* parent OpenCode pane instead.
|
|
8
13
|
*/
|
|
9
|
-
import type { MultiplexerLayout } from '../../config/schema';
|
|
14
|
+
import type { MultiplexerLayout, ZellijPaneMode } from '../../config/schema';
|
|
10
15
|
import type { Multiplexer, PaneResult } from '../types';
|
|
11
16
|
export declare class ZellijMultiplexer implements Multiplexer {
|
|
17
|
+
private readonly paneMode;
|
|
12
18
|
readonly type: "zellij";
|
|
13
19
|
private binaryPath;
|
|
14
20
|
private hasChecked;
|
|
15
21
|
private agentTabId;
|
|
16
22
|
private firstPaneId;
|
|
17
23
|
private firstPaneUsed;
|
|
18
|
-
|
|
24
|
+
private parentTabId;
|
|
25
|
+
private readonly parentPaneId;
|
|
26
|
+
private readonly paneDirection;
|
|
27
|
+
constructor(layout?: MultiplexerLayout, mainPaneSize?: number, paneMode?: ZellijPaneMode);
|
|
19
28
|
isAvailable(): Promise<boolean>;
|
|
20
29
|
isInsideSession(): boolean;
|
|
21
30
|
spawnPane(sessionId: string, description: string, serverUrl: string, directory: string): Promise<PaneResult>;
|
|
31
|
+
private createPaneInCurrentTab;
|
|
22
32
|
private createPaneInAgentTab;
|
|
23
33
|
private runInPane;
|
|
24
34
|
private ensureAgentTab;
|
|
@@ -29,6 +39,10 @@ export declare class ZellijMultiplexer implements Multiplexer {
|
|
|
29
39
|
private listPanes;
|
|
30
40
|
closePane(paneId: string): Promise<boolean>;
|
|
31
41
|
applyLayout(_layout: MultiplexerLayout, _mainPaneSize: number): Promise<void>;
|
|
42
|
+
private directionArgs;
|
|
43
|
+
private tabIdArgs;
|
|
44
|
+
private getParentTabId;
|
|
45
|
+
private findTabIdForPane;
|
|
32
46
|
private getBinary;
|
|
33
47
|
private findBinary;
|
|
34
48
|
}
|
|
@@ -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 {};
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
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';
|
|
@@ -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: {
|
package/dist/tui.js
CHANGED
|
@@ -4,15 +4,29 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -54,7 +68,22 @@ var POLL_INTERVAL_BACKGROUND_MS = 2000;
|
|
|
54
68
|
var DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
|
|
55
69
|
var MAX_POLL_TIME_MS = 5 * 60 * 1000;
|
|
56
70
|
var DEFAULT_MAX_SUBAGENT_DEPTH = 3;
|
|
57
|
-
var PHASE_REMINDER_TEXT = `!IMPORTANT! Scheduler workflow: plan lanes/dependencies → dispatch background specialists → track task IDs →
|
|
71
|
+
var PHASE_REMINDER_TEXT = `!IMPORTANT! Scheduler workflow: plan lanes/dependencies → dispatch background specialists → track task IDs → wait for hook-driven completion → reconcile terminal results → verify. Do not poll running jobs, consume running-job output, or advance dependent work. !END!`;
|
|
72
|
+
var WRITABLE_FILE_OPERATIONS_RULES = `**File Operations Rules**:
|
|
73
|
+
- Prefer dedicated file tools for normal code work: glob/grep/ast_grep_search for discovery, read for file contents, and edit/write/apply_patch for targeted source changes.
|
|
74
|
+
- Use bash for execution and automation: git, package managers, tests, builds, scripts, diagnostics, and shell-native filesystem operations.
|
|
75
|
+
- Shell is acceptable for bulk or mechanical filesystem changes when it is clearer or safer than many individual edits (for example: truncate generated logs, remove build artifacts, batch rename/move files), especially when the user explicitly asks for that shell operation.
|
|
76
|
+
- Before destructive or broad shell operations, verify the target set and quote paths. Prefer a dry-run/listing first when practical.
|
|
77
|
+
- Do not use cat/head/tail/sed/awk only to read code into context; use read/grep unless a shell pipeline is genuinely the better diagnostic.`;
|
|
78
|
+
var READONLY_FILE_OPERATIONS_RULES = `**File Operations Rules**:
|
|
79
|
+
- READ-ONLY: inspect and report; do not modify files.
|
|
80
|
+
- Prefer dedicated file tools for codebase inspection: glob/grep/ast_grep_search for discovery and read for file contents.
|
|
81
|
+
- Bash is allowed for non-mutating diagnostics and shell-native inspection when it is the clearest tool, but not for modifying files.
|
|
82
|
+
- Do not use cat/head/tail/sed/awk only to read code into context; use read/grep unless a shell pipeline is genuinely the better diagnostic.`;
|
|
83
|
+
var NO_SHELL_READONLY_FILE_OPERATIONS_RULES = `**File Operations Rules**:
|
|
84
|
+
- READ-ONLY: inspect and report; do not modify files.
|
|
85
|
+
- Use glob/grep/ast_grep_search for discovery and read for file contents.
|
|
86
|
+
- Do not use bash or shell commands.`;
|
|
58
87
|
var TMUX_SPAWN_DELAY_MS = 500;
|
|
59
88
|
var COUNCILLOR_STAGGER_MS = 250;
|
|
60
89
|
var DEFAULT_DISABLED_AGENTS = ["observer"];
|
|
@@ -124,6 +153,13 @@ function getCustomOpenCodeConfigDir() {
|
|
|
124
153
|
const configDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
125
154
|
return configDir || undefined;
|
|
126
155
|
}
|
|
156
|
+
function getConfigDir() {
|
|
157
|
+
const customConfigDir = getCustomOpenCodeConfigDir();
|
|
158
|
+
if (customConfigDir) {
|
|
159
|
+
return customConfigDir;
|
|
160
|
+
}
|
|
161
|
+
return getDefaultOpenCodeConfigDir();
|
|
162
|
+
}
|
|
127
163
|
function getConfigSearchDirs() {
|
|
128
164
|
const dirs = [getCustomOpenCodeConfigDir(), getDefaultOpenCodeConfigDir()];
|
|
129
165
|
return dirs.filter((dir, index) => {
|
|
@@ -131,7 +167,7 @@ function getConfigSearchDirs() {
|
|
|
131
167
|
});
|
|
132
168
|
}
|
|
133
169
|
function getOpenCodeConfigPaths() {
|
|
134
|
-
const configDir =
|
|
170
|
+
const configDir = getConfigDir();
|
|
135
171
|
return [join(configDir, "opencode.json"), join(configDir, "opencode.jsonc")];
|
|
136
172
|
}
|
|
137
173
|
// src/config/council-schema.ts
|
|
@@ -269,11 +305,13 @@ var MultiplexerLayoutSchema = z2.enum([
|
|
|
269
305
|
"even-horizontal",
|
|
270
306
|
"even-vertical"
|
|
271
307
|
]);
|
|
308
|
+
var ZellijPaneModeSchema = z2.enum(["agent-tab", "current-tab"]);
|
|
272
309
|
var TmuxLayoutSchema = MultiplexerLayoutSchema;
|
|
273
310
|
var MultiplexerConfigSchema = z2.object({
|
|
274
311
|
type: MultiplexerTypeSchema.default("none"),
|
|
275
312
|
layout: MultiplexerLayoutSchema.default("main-vertical"),
|
|
276
|
-
main_pane_size: z2.number().min(20).max(80).default(60)
|
|
313
|
+
main_pane_size: z2.number().min(20).max(80).default(60),
|
|
314
|
+
zellij_pane_mode: ZellijPaneModeSchema.default("agent-tab")
|
|
277
315
|
});
|
|
278
316
|
var TmuxConfigSchema = z2.object({
|
|
279
317
|
enabled: z2.boolean().default(false),
|
|
@@ -284,7 +322,7 @@ var PresetSchema = z2.record(z2.string(), AgentOverrideConfigSchema);
|
|
|
284
322
|
var WebsearchConfigSchema = z2.object({
|
|
285
323
|
provider: z2.enum(["exa", "tavily"]).default("exa")
|
|
286
324
|
});
|
|
287
|
-
var McpNameSchema = z2.enum(["websearch", "context7", "
|
|
325
|
+
var McpNameSchema = z2.enum(["websearch", "context7", "gh_grep"]);
|
|
288
326
|
var InterviewConfigSchema = z2.object({
|
|
289
327
|
maxQuestions: z2.number().int().min(1).max(10).default(2),
|
|
290
328
|
outputFolder: z2.string().min(1).default("interview"),
|
|
@@ -292,28 +330,11 @@ var InterviewConfigSchema = z2.object({
|
|
|
292
330
|
port: z2.number().int().min(0).max(65535).default(0),
|
|
293
331
|
dashboard: z2.boolean().default(false)
|
|
294
332
|
});
|
|
295
|
-
var
|
|
333
|
+
var BackgroundJobsConfigSchema = z2.object({
|
|
296
334
|
maxSessionsPerAgent: z2.number().int().min(1).max(10).default(2),
|
|
297
335
|
readContextMinLines: z2.number().int().min(0).max(1000).default(10),
|
|
298
336
|
readContextMaxFiles: z2.number().int().min(0).max(50).default(8)
|
|
299
337
|
});
|
|
300
|
-
var DivoomConfigSchema = z2.object({
|
|
301
|
-
enabled: z2.boolean().default(false),
|
|
302
|
-
python: z2.string().min(1).default("/Applications/Divoom MiniToo.app/Contents/Resources/.venv/bin/python"),
|
|
303
|
-
script: z2.string().min(1).default("/Applications/Divoom MiniToo.app/Contents/Resources/tools/divoom_send.py"),
|
|
304
|
-
size: z2.number().int().min(1).max(1024).default(128),
|
|
305
|
-
fps: z2.number().int().min(1).max(60).default(8),
|
|
306
|
-
speed: z2.number().int().min(1).max(1e4).default(125),
|
|
307
|
-
maxFrames: z2.number().int().min(1).max(500).default(24),
|
|
308
|
-
posterizeBits: z2.number().int().min(1).max(8).default(3),
|
|
309
|
-
gifs: z2.record(z2.string(), z2.string().min(1)).optional()
|
|
310
|
-
});
|
|
311
|
-
var TodoContinuationConfigSchema = z2.object({
|
|
312
|
-
maxContinuations: z2.number().int().min(1).max(50).default(5).describe("Maximum consecutive auto-continuations before stopping to ask user"),
|
|
313
|
-
cooldownMs: z2.number().int().min(0).max(30000).default(3000).describe("Delay in ms before auto-continuing (gives user time to abort)"),
|
|
314
|
-
autoEnable: z2.boolean().default(false).describe("Automatically enable auto-continue when the orchestrator session has enough todos"),
|
|
315
|
-
autoEnableThreshold: z2.number().int().min(1).max(50).default(4).describe("Number of todos that triggers auto-enable (only used when autoEnable is true)")
|
|
316
|
-
});
|
|
317
338
|
var FailoverConfigSchema = z2.object({
|
|
318
339
|
enabled: z2.boolean().default(true),
|
|
319
340
|
timeoutMs: z2.number().min(0).default(15000),
|
|
@@ -321,6 +342,11 @@ var FailoverConfigSchema = z2.object({
|
|
|
321
342
|
chains: FallbackChainsSchema.default({}),
|
|
322
343
|
retry_on_empty: z2.boolean().default(true).describe("When true (default), empty provider responses are treated as failures, " + "triggering fallback/retry. Set to false to treat them as successes.")
|
|
323
344
|
});
|
|
345
|
+
var CompanionConfigSchema = z2.object({
|
|
346
|
+
enabled: z2.boolean().optional(),
|
|
347
|
+
position: z2.enum(["bottom-right", "bottom-left", "top-right", "top-left"]).optional(),
|
|
348
|
+
size: z2.enum(["small", "medium", "large"]).optional()
|
|
349
|
+
});
|
|
324
350
|
function validateCustomOnlyPromptFields(overrides, ctx, pathPrefix) {
|
|
325
351
|
for (const [name, override] of Object.entries(overrides)) {
|
|
326
352
|
const isBuiltInOrAlias = ALL_AGENT_NAMES.includes(name) || AGENT_ALIASES[name] !== undefined;
|
|
@@ -358,11 +384,10 @@ var PluginConfigSchema = z2.object({
|
|
|
358
384
|
tmux: TmuxConfigSchema.optional(),
|
|
359
385
|
websearch: WebsearchConfigSchema.optional(),
|
|
360
386
|
interview: InterviewConfigSchema.optional(),
|
|
361
|
-
|
|
362
|
-
divoom: DivoomConfigSchema.optional(),
|
|
363
|
-
todoContinuation: TodoContinuationConfigSchema.optional(),
|
|
387
|
+
backgroundJobs: BackgroundJobsConfigSchema.optional(),
|
|
364
388
|
fallback: FailoverConfigSchema.optional(),
|
|
365
|
-
council: CouncilConfigSchema.optional()
|
|
389
|
+
council: CouncilConfigSchema.optional(),
|
|
390
|
+
companion: CompanionConfigSchema.optional()
|
|
366
391
|
}).superRefine((value, ctx) => {
|
|
367
392
|
if (value.agents) {
|
|
368
393
|
validateCustomOnlyPromptFields(value.agents, ctx, ["agents"]);
|
|
@@ -392,7 +417,7 @@ var DEFAULT_AGENT_MCPS = {
|
|
|
392
417
|
orchestrator: ["*", "!context7"],
|
|
393
418
|
designer: [],
|
|
394
419
|
oracle: [],
|
|
395
|
-
librarian: ["websearch", "context7", "
|
|
420
|
+
librarian: ["websearch", "context7", "gh_grep"],
|
|
396
421
|
explorer: [],
|
|
397
422
|
fixer: [],
|
|
398
423
|
observer: [],
|
|
@@ -447,6 +472,12 @@ var CUSTOM_SKILLS = [
|
|
|
447
472
|
description: "Heavy/complex coding sessions and large modifications workflow",
|
|
448
473
|
allowedAgents: ["orchestrator"],
|
|
449
474
|
sourcePath: "src/skills/deepwork"
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
name: "oh-my-opencode-slim",
|
|
478
|
+
description: "Configure, customize, and safely improve oh-my-opencode-slim setups",
|
|
479
|
+
allowedAgents: ["orchestrator"],
|
|
480
|
+
sourcePath: "src/skills/oh-my-opencode-slim"
|
|
450
481
|
}
|
|
451
482
|
];
|
|
452
483
|
|
|
@@ -542,10 +573,10 @@ function mergePluginConfigs(base, override) {
|
|
|
542
573
|
tmux: deepMerge(base.tmux, override.tmux),
|
|
543
574
|
multiplexer: deepMerge(base.multiplexer, override.multiplexer),
|
|
544
575
|
interview: deepMerge(base.interview, override.interview),
|
|
545
|
-
|
|
546
|
-
divoom: deepMerge(base.divoom, override.divoom),
|
|
576
|
+
backgroundJobs: deepMerge(base.backgroundJobs, override.backgroundJobs),
|
|
547
577
|
fallback: deepMerge(base.fallback, override.fallback),
|
|
548
|
-
council: deepMerge(base.council, override.council)
|
|
578
|
+
council: deepMerge(base.council, override.council),
|
|
579
|
+
companion: deepMerge(base.companion, override.companion)
|
|
549
580
|
};
|
|
550
581
|
}
|
|
551
582
|
function deepMerge(base, override) {
|
|
@@ -595,6 +626,13 @@ function loadPluginConfig(directory, options) {
|
|
|
595
626
|
}
|
|
596
627
|
}
|
|
597
628
|
}
|
|
629
|
+
if (config.companion) {
|
|
630
|
+
config.companion = {
|
|
631
|
+
enabled: config.companion.enabled ?? false,
|
|
632
|
+
position: config.companion.position ?? "bottom-right",
|
|
633
|
+
size: config.companion.size ?? "medium"
|
|
634
|
+
};
|
|
635
|
+
}
|
|
598
636
|
return config;
|
|
599
637
|
}
|
|
600
638
|
function loadAgentPrompt(agentName, preset) {
|
|
@@ -632,7 +670,8 @@ function migrateTmuxToMultiplexer(config) {
|
|
|
632
670
|
multiplexer: {
|
|
633
671
|
type: "tmux",
|
|
634
672
|
layout: config.tmux.layout ?? "main-vertical",
|
|
635
|
-
main_pane_size: config.tmux.main_pane_size ?? 60
|
|
673
|
+
main_pane_size: config.tmux.main_pane_size ?? 60,
|
|
674
|
+
zellij_pane_mode: "agent-tab"
|
|
636
675
|
}
|
|
637
676
|
};
|
|
638
677
|
}
|
|
@@ -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;
|
|
@@ -8,13 +14,25 @@ export interface BackgroundJobRecord {
|
|
|
8
14
|
objective?: string;
|
|
9
15
|
state: BackgroundJobState;
|
|
10
16
|
timedOut: boolean;
|
|
17
|
+
statusUncertain: boolean;
|
|
18
|
+
cancellationRequested: boolean;
|
|
11
19
|
terminalUnreconciled: boolean;
|
|
12
20
|
launchedAt: number;
|
|
13
21
|
lastLaunchedAt: number;
|
|
14
22
|
updatedAt: number;
|
|
23
|
+
lastLiveBusyAt?: number;
|
|
15
24
|
completedAt?: number;
|
|
16
25
|
resultSummary?: string;
|
|
26
|
+
lastStatusError?: string;
|
|
17
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;
|
|
18
36
|
}
|
|
19
37
|
export interface BackgroundJobLaunchInput {
|
|
20
38
|
taskID: string;
|
|
@@ -28,22 +46,44 @@ export interface BackgroundJobStatusInput {
|
|
|
28
46
|
taskID: string;
|
|
29
47
|
state: TaskOutputState;
|
|
30
48
|
timedOut?: boolean;
|
|
49
|
+
statusUncertain?: boolean;
|
|
31
50
|
resultSummary?: string;
|
|
51
|
+
lastStatusError?: string;
|
|
32
52
|
now?: number;
|
|
33
53
|
}
|
|
34
54
|
export declare class BackgroundJobBoard {
|
|
35
55
|
private readonly jobs;
|
|
36
56
|
private readonly counters;
|
|
57
|
+
private readonly maxReusablePerAgent;
|
|
58
|
+
private readonly readContextMinLines;
|
|
59
|
+
private readonly readContextMaxFiles;
|
|
60
|
+
constructor(options?: BackgroundJobBoardOptions);
|
|
37
61
|
registerLaunch(input: BackgroundJobLaunchInput): BackgroundJobRecord;
|
|
38
62
|
updateStatus(input: BackgroundJobStatusInput): BackgroundJobRecord | undefined;
|
|
39
63
|
updateFromStatusOutput(output: string): BackgroundJobRecord | undefined;
|
|
64
|
+
markRunningFromLiveSession(taskID: string, now?: number): BackgroundJobRecord | undefined;
|
|
40
65
|
markReconciled(taskID: string, now?: number): BackgroundJobRecord | undefined;
|
|
66
|
+
markCancelled(taskID: string, reason?: string, now?: number, options?: {
|
|
67
|
+
force?: boolean;
|
|
68
|
+
}): BackgroundJobRecord | undefined;
|
|
41
69
|
get(taskID: string): BackgroundJobRecord | undefined;
|
|
70
|
+
resolve(parentSessionID: string, taskIDOrAlias: string): BackgroundJobRecord | undefined;
|
|
71
|
+
resolveReusable(parentSessionID: string, taskIDOrAlias: string, agent?: string): BackgroundJobRecord | undefined;
|
|
72
|
+
markUsed(parentSessionID: string, key: string, now?: number): void;
|
|
73
|
+
taskIDs(): Set<string>;
|
|
74
|
+
addContext(taskID: string, files: ContextFile[]): void;
|
|
42
75
|
list(parentSessionID?: string): BackgroundJobRecord[];
|
|
43
76
|
hasRunning(parentSessionID: string): boolean;
|
|
44
77
|
hasTerminalUnreconciled(parentSessionID: string): boolean;
|
|
45
78
|
formatForPrompt(parentSessionID: string, now?: number): string | undefined;
|
|
46
79
|
clearParent(parentSessionID: string): void;
|
|
47
80
|
drop(taskID: string): void;
|
|
81
|
+
private trimReusable;
|
|
82
|
+
private formatReusableJob;
|
|
48
83
|
private nextAlias;
|
|
49
84
|
}
|
|
85
|
+
export declare function deriveTaskSessionLabel(input: {
|
|
86
|
+
description?: string;
|
|
87
|
+
prompt?: string;
|
|
88
|
+
agentType: string;
|
|
89
|
+
}): string;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -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';
|
package/dist/utils/task.d.ts
CHANGED
|
@@ -13,8 +13,10 @@ export interface TaskStatusOutput {
|
|
|
13
13
|
timedOut: boolean;
|
|
14
14
|
result?: string;
|
|
15
15
|
}
|
|
16
|
+
export type TaskStatusClassification = 'running' | 'terminal' | 'timeout' | 'transient_process_error' | 'unknown_error';
|
|
16
17
|
export declare function parseTaskIdFromTaskOutput(output: string): string | undefined;
|
|
17
18
|
export declare function parseTaskLaunchOutput(output: string): TaskLaunchOutput | undefined;
|
|
18
19
|
export declare function parseTaskStatusOutput(output: string): TaskStatusOutput | undefined;
|
|
20
|
+
export declare function classifyTaskStatusOutput(status: TaskStatusOutput): TaskStatusClassification;
|
|
19
21
|
export declare function parseTaskStateFromOutput(output: string): TaskOutputState | undefined;
|
|
20
22
|
export declare function parseTaskResultFromOutput(output: string): string | undefined;
|
|
@@ -413,6 +413,14 @@
|
|
|
413
413
|
"type": "number",
|
|
414
414
|
"minimum": 20,
|
|
415
415
|
"maximum": 80
|
|
416
|
+
},
|
|
417
|
+
"zellij_pane_mode": {
|
|
418
|
+
"default": "agent-tab",
|
|
419
|
+
"type": "string",
|
|
420
|
+
"enum": [
|
|
421
|
+
"agent-tab",
|
|
422
|
+
"current-tab"
|
|
423
|
+
]
|
|
416
424
|
}
|
|
417
425
|
}
|
|
418
426
|
},
|
|
@@ -486,7 +494,7 @@
|
|
|
486
494
|
}
|
|
487
495
|
}
|
|
488
496
|
},
|
|
489
|
-
"
|
|
497
|
+
"backgroundJobs": {
|
|
490
498
|
"type": "object",
|
|
491
499
|
"properties": {
|
|
492
500
|
"maxSessionsPerAgent": {
|
|
@@ -509,96 +517,6 @@
|
|
|
509
517
|
}
|
|
510
518
|
}
|
|
511
519
|
},
|
|
512
|
-
"divoom": {
|
|
513
|
-
"type": "object",
|
|
514
|
-
"properties": {
|
|
515
|
-
"enabled": {
|
|
516
|
-
"default": false,
|
|
517
|
-
"type": "boolean"
|
|
518
|
-
},
|
|
519
|
-
"python": {
|
|
520
|
-
"default": "/Applications/Divoom MiniToo.app/Contents/Resources/.venv/bin/python",
|
|
521
|
-
"type": "string",
|
|
522
|
-
"minLength": 1
|
|
523
|
-
},
|
|
524
|
-
"script": {
|
|
525
|
-
"default": "/Applications/Divoom MiniToo.app/Contents/Resources/tools/divoom_send.py",
|
|
526
|
-
"type": "string",
|
|
527
|
-
"minLength": 1
|
|
528
|
-
},
|
|
529
|
-
"size": {
|
|
530
|
-
"default": 128,
|
|
531
|
-
"type": "integer",
|
|
532
|
-
"minimum": 1,
|
|
533
|
-
"maximum": 1024
|
|
534
|
-
},
|
|
535
|
-
"fps": {
|
|
536
|
-
"default": 8,
|
|
537
|
-
"type": "integer",
|
|
538
|
-
"minimum": 1,
|
|
539
|
-
"maximum": 60
|
|
540
|
-
},
|
|
541
|
-
"speed": {
|
|
542
|
-
"default": 125,
|
|
543
|
-
"type": "integer",
|
|
544
|
-
"minimum": 1,
|
|
545
|
-
"maximum": 10000
|
|
546
|
-
},
|
|
547
|
-
"maxFrames": {
|
|
548
|
-
"default": 24,
|
|
549
|
-
"type": "integer",
|
|
550
|
-
"minimum": 1,
|
|
551
|
-
"maximum": 500
|
|
552
|
-
},
|
|
553
|
-
"posterizeBits": {
|
|
554
|
-
"default": 3,
|
|
555
|
-
"type": "integer",
|
|
556
|
-
"minimum": 1,
|
|
557
|
-
"maximum": 8
|
|
558
|
-
},
|
|
559
|
-
"gifs": {
|
|
560
|
-
"type": "object",
|
|
561
|
-
"propertyNames": {
|
|
562
|
-
"type": "string"
|
|
563
|
-
},
|
|
564
|
-
"additionalProperties": {
|
|
565
|
-
"type": "string",
|
|
566
|
-
"minLength": 1
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
},
|
|
571
|
-
"todoContinuation": {
|
|
572
|
-
"type": "object",
|
|
573
|
-
"properties": {
|
|
574
|
-
"maxContinuations": {
|
|
575
|
-
"default": 5,
|
|
576
|
-
"description": "Maximum consecutive auto-continuations before stopping to ask user",
|
|
577
|
-
"type": "integer",
|
|
578
|
-
"minimum": 1,
|
|
579
|
-
"maximum": 50
|
|
580
|
-
},
|
|
581
|
-
"cooldownMs": {
|
|
582
|
-
"default": 3000,
|
|
583
|
-
"description": "Delay in ms before auto-continuing (gives user time to abort)",
|
|
584
|
-
"type": "integer",
|
|
585
|
-
"minimum": 0,
|
|
586
|
-
"maximum": 30000
|
|
587
|
-
},
|
|
588
|
-
"autoEnable": {
|
|
589
|
-
"default": false,
|
|
590
|
-
"description": "Automatically enable auto-continue when the orchestrator session has enough todos",
|
|
591
|
-
"type": "boolean"
|
|
592
|
-
},
|
|
593
|
-
"autoEnableThreshold": {
|
|
594
|
-
"default": 4,
|
|
595
|
-
"description": "Number of todos that triggers auto-enable (only used when autoEnable is true)",
|
|
596
|
-
"type": "integer",
|
|
597
|
-
"minimum": 1,
|
|
598
|
-
"maximum": 50
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
},
|
|
602
520
|
"fallback": {
|
|
603
521
|
"type": "object",
|
|
604
522
|
"properties": {
|
|
@@ -738,6 +656,31 @@
|
|
|
738
656
|
"required": [
|
|
739
657
|
"presets"
|
|
740
658
|
]
|
|
659
|
+
},
|
|
660
|
+
"companion": {
|
|
661
|
+
"type": "object",
|
|
662
|
+
"properties": {
|
|
663
|
+
"enabled": {
|
|
664
|
+
"type": "boolean"
|
|
665
|
+
},
|
|
666
|
+
"position": {
|
|
667
|
+
"type": "string",
|
|
668
|
+
"enum": [
|
|
669
|
+
"bottom-right",
|
|
670
|
+
"bottom-left",
|
|
671
|
+
"top-right",
|
|
672
|
+
"top-left"
|
|
673
|
+
]
|
|
674
|
+
},
|
|
675
|
+
"size": {
|
|
676
|
+
"type": "string",
|
|
677
|
+
"enum": [
|
|
678
|
+
"small",
|
|
679
|
+
"medium",
|
|
680
|
+
"large"
|
|
681
|
+
]
|
|
682
|
+
}
|
|
683
|
+
}
|
|
741
684
|
}
|
|
742
685
|
},
|
|
743
686
|
"title": "oh-my-opencode-slim",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode-slim",
|
|
3
|
-
"version": "2.0.0
|
|
3
|
+
"version": "2.0.0",
|
|
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",
|
|
@@ -44,14 +44,15 @@
|
|
|
44
44
|
"oh-my-opencode-slim.schema.json",
|
|
45
45
|
"README.md",
|
|
46
46
|
"README.zh-CN.md",
|
|
47
|
+
"README.ja-JP.md",
|
|
48
|
+
"README.ko-KR.md",
|
|
47
49
|
"LICENSE"
|
|
48
50
|
],
|
|
49
51
|
"scripts": {
|
|
50
52
|
"clean:dist": "bun -e \"import { rmSync } from 'node:fs'; rmSync('dist', { recursive: true, force: true })\"",
|
|
51
53
|
"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
54
|
"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",
|
|
53
|
-
"
|
|
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",
|
|
55
|
+
"build": "bun run clean:dist && bun run build:plugin && bun run build:cli && tsc --emitDeclarationOnly && bun run generate-schema",
|
|
55
56
|
"prepare": "bun run build",
|
|
56
57
|
"contributors:add": "all-contributors add",
|
|
57
58
|
"contributors:check": "all-contributors check",
|
package/src/skills/codemap.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- `src/skills/clonedeps/` (workflow skill for dependency source mirroring)
|
|
20
20
|
- `src/skills/simplify/` (readability/refactor guidance skill)
|
|
21
21
|
- `src/skills/deepwork/` (orchestrator-only workflow for heavy coding sessions)
|
|
22
|
+
- `src/skills/oh-my-opencode-slim/` (orchestrator-only plugin configuration and self-improvement guidance)
|
|
22
23
|
- Files are considered static runtime payload. No plugin TS module in `src/` imports these files directly; they
|
|
23
24
|
are loaded by OpenCode via filesystem installation.
|
|
24
25
|
|
|
@@ -40,5 +41,6 @@
|
|
|
40
41
|
- `verify-release-artifact.ts` enforces artifact completeness by asserting key
|
|
41
42
|
bundled skill payloads such as `src/skills/simplify/SKILL.md`,
|
|
42
43
|
`src/skills/codemap/SKILL.md`, `src/skills/clonedeps/SKILL.md`, and
|
|
43
|
-
`src/skills/deepwork/SKILL.md
|
|
44
|
+
`src/skills/deepwork/SKILL.md`, plus `src/skills/oh-my-opencode-slim/SKILL.md`,
|
|
45
|
+
are present in the tarball.
|
|
44
46
|
- `package.json` scripts (`verify:release`, `build`) rely on these assets to ensure install-time skill availability.
|
|
@@ -33,8 +33,30 @@ Required behavior:
|
|
|
33
33
|
- after each phase, validate, update the deepwork file, prepare the plan file
|
|
34
34
|
for oracle review and ask `@oracle` to review the phase result, fix
|
|
35
35
|
actionable issues, then continue;
|
|
36
|
+
- when a phase includes `@designer`, preserve designer intent across later
|
|
37
|
+
phases. Use `@fixer` only for mechanical follow-up that does not alter the
|
|
38
|
+
UI/UX;
|
|
36
39
|
- finish with final validation and a concise summary.
|
|
37
40
|
|
|
41
|
+
## Designer Handoff Guardrail
|
|
42
|
+
|
|
43
|
+
When a deepwork phase includes `@designer`, treat the delivered UI/UX as
|
|
44
|
+
accepted design intent for later phases. Record any important design decisions in
|
|
45
|
+
the deepwork file before continuing.
|
|
46
|
+
|
|
47
|
+
After designer work:
|
|
48
|
+
|
|
49
|
+
- preserve layout, rhythm, hierarchy, motion, spacing, color, affordances,
|
|
50
|
+
responsiveness, and component feel;
|
|
51
|
+
- review and improve user-facing copy with grounded, normal wording, but do not
|
|
52
|
+
change visual structure or interaction intent;
|
|
53
|
+
- route follow-up visual, responsive, motion, hierarchy, polish, or
|
|
54
|
+
component-feel changes back to `@designer`;
|
|
55
|
+
- use `@fixer` only for bounded mechanical follow-up that preserves the design
|
|
56
|
+
exactly, such as wiring, tests, type fixes, or non-visual behavior changes;
|
|
57
|
+
- if design intent must change, record why in the deepwork file before changing
|
|
58
|
+
it.
|
|
59
|
+
|
|
38
60
|
## Deepwork File
|
|
39
61
|
|
|
40
62
|
Create a task-specific file such as:
|
|
@@ -82,8 +104,8 @@ Use the scheduler model throughout:
|
|
|
82
104
|
|
|
83
105
|
- follow Orchestrator delegations rules
|
|
84
106
|
- record task/session IDs and ownership boundaries;
|
|
85
|
-
-
|
|
86
|
-
- avoid blocking Orchestrator lane
|
|
87
|
-
|
|
107
|
+
- wait for hook-driven background completion before consuming background results;
|
|
108
|
+
- avoid blocking Orchestrator lane while background jobs run; if no independent
|
|
109
|
+
work remains, stop briefly and let the completion event resume the workflow;
|
|
88
110
|
- do not advance to the next phase while relevant jobs are running or terminal
|
|
89
111
|
results are unreconciled.
|