oh-my-opencode-slim 2.0.0-beta.13 → 2.0.0-beta.15

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.md CHANGED
@@ -2,8 +2,8 @@
2
2
  <a href="https://github.com/alvinunreal/oh-my-opencode-slim/stargazers">
3
3
  <img src="img/4k.png" alt="4K GitHub Stars Milestone" style="border-radius: 10px;">
4
4
  </a>
5
- <h3>✨ V2 Beta Release: Background Orchestration Has Arrived ✨</h3>
6
- <p><i>The orchestrator now schedules specialist agents in the background,<br>while <code>/deepwork</code> turns big goals into file-backed plans.<br>Beta testers: share your feedback with us on Telegram.</i></p>
5
+ <h3>✨ Default Background Orchestration Has Arrived ✨</h3>
6
+ <p><i>The orchestrator now manages the workflow and schedules specialist agents in the background,<br>while <code>/deepwork</code> turns big goals into file-backed plans.<br>Share feedback and questions with us on Telegram.</i></p>
7
7
 
8
8
  <p><b>Open Multi Agent Suite</b> · Mix any models · Auto delegate tasks</p>
9
9
 
@@ -15,7 +15,7 @@
15
15
  </p>
16
16
 
17
17
  <p>
18
- <b>English</b> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja-JP.md">日本語</a>
18
+ <b>English</b> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.ja-JP.md">日本語</a> | <a href="README.ko-KR.md">한국어</a>
19
19
  </p>
20
20
  </div>
21
21
 
@@ -45,22 +45,31 @@ Install and configure oh-my-opencode-slim: https://raw.githubusercontent.com/alv
45
45
  bunx oh-my-opencode-slim@latest install
46
46
  ```
47
47
 
48
- ### V2 Background-Orchestration Beta
48
+ ### Default Background Orchestration
49
49
 
50
- V2 changes the orchestrator from the default execution worker into a scheduler:
51
- it plans work, dispatches specialists as background tasks, receives completion
52
- events from OpenCode or checks status only when needed, then reconciles results
53
- before continuing. This requires OpenCode's native background subagent support,
54
- so beta users must start OpenCode with the experimental flag enabled.
50
+ The orchestrator is now a workflow manager and scheduler, not the main coding
51
+ worker: it plans work, dispatches specialists as background tasks, receives
52
+ completion events from OpenCode or checks status only when needed, then
53
+ reconciles results before continuing. This uses OpenCode's native background
54
+ subagent support, so OpenCode must run with the background-subagents environment
55
+ variable enabled.
55
56
 
56
57
  ```bash
57
- bunx oh-my-opencode-slim@beta install
58
- OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=1 opencode
58
+ bunx oh-my-opencode-slim@beta install --background-subagents=yes
59
59
  ```
60
60
 
61
+ The installer can set this up for you with
62
+ `--background-subagents=ask|yes|no`. In an interactive TTY, the default is
63
+ `ask`; in non-interactive mode, the default is `no`. Use
64
+ `--background-subagents=yes` to opt in immediately or `--background-subagents=no`
65
+ to skip. If you want the installer to write to a specific shell/profile file,
66
+ add `--background-subagents-target=<path>`. After shell setup, restart your
67
+ terminal or source the updated file before starting `opencode`; for a one-shot
68
+ launch, run `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true opencode`.
69
+
61
70
  ### Getting Started
62
71
 
63
- The installer generates both OpenAI and OpenCode Go presets, with OpenAI active by default. OpenAI uses `openai/gpt-5.5` for the higher-judgment agents and `openai/gpt-5.4-mini` for the faster scoped agents. To make OpenCode Go active during install, run `bunx oh-my-opencode-slim@latest install --preset=opencode-go` or change the default preset name in `~/.config/opencode/oh-my-opencode-slim.json` after installation.
72
+ The installer generates both OpenAI and OpenCode Go presets, with OpenAI active by default. OpenAI uses `openai/gpt-5.5` for the workflow manager/scheduler and higher-judgment agents, and `openai/gpt-5.4-mini` for faster scoped specialists. To make OpenCode Go active during install, run `bunx oh-my-opencode-slim@latest install --preset=opencode-go` or change the default preset name in `~/.config/opencode/oh-my-opencode-slim.json` after installation.
64
73
 
65
74
  Then:
66
75
 
@@ -75,11 +84,19 @@ Then:
75
84
  opencode models --refresh
76
85
  ```
77
86
  3. **Open your plugin config** at `~/.config/opencode/oh-my-opencode-slim.json`
87
+ or `$OPENCODE_CONFIG_DIR/oh-my-opencode-slim.json` if you use a custom
88
+ OpenCode config directory
78
89
 
79
90
  4. **Update the models you want for each agent**
80
91
 
81
92
  > [!TIP]
82
- > It's **recommended** to understand how automatic delegation works. The **[Orchestrator prompt](https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/src/agents/orchestrator.ts#L28)** contains the delegation rules, specialist routing logic, and the thresholds for when the main agent should hand work off to subagents. You can alway delegate manually by calling a subagent via: `@agentName <task>`
93
+ > It's **recommended** to understand how background orchestration works. The **[Orchestrator prompt](https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/src/agents/orchestrator.ts#L28)** contains the scheduler rules, specialist routing logic, and thresholds for when work should be assigned to background agents. You can always delegate manually by calling a subagent via: `@agentName <task>`
94
+
95
+ ### Legacy V1 note
96
+
97
+ The current `@latest` package is the background-orchestration release. If a
98
+ maintained V1 branch or tag is created later, it will be documented separately as
99
+ historical compatibility guidance rather than part of the default install path.
83
100
 
84
101
  The default generated configuration includes both `openai` and `opencode-go` presets.
85
102
 
@@ -180,7 +197,7 @@ If any agent fails to respond, check your provider authentication and config fil
180
197
  </tr>
181
198
  <tr>
182
199
  <td colspan="2">
183
- <b>Model Guidance:</b> Choose your default, strongest all-around coding model. Orchestrator is both the main coding agent and the delegator, so it needs strong implementation ability, good judgment, and reliable instruction-following.
200
+ <b>Model Guidance:</b> Choose your strongest planning and judgment model. Orchestrator is the workflow manager: it plans, schedules background specialists, reconciles results, and verifies outcomes, so it needs reliable instruction-following and high-level technical judgment more than raw worker throughput.
184
201
  </td>
185
202
  </tr>
186
203
  </table>
@@ -500,10 +517,9 @@ Use this section as a map: start with installation, then jump to features, confi
500
517
  | Doc | What it covers |
501
518
  |-----|----------------|
502
519
  | **[Council](docs/council.md)** | Run multiple models in parallel and synthesize a single answer with `@council` |
503
- | **[V2 Background Orchestration](docs/v2-background-orchestration.md)** | Scheduler-first orchestrator model built around native background subagents |
520
+ | **[Background Orchestration](docs/v2-background-orchestration.md)** | Scheduler-first orchestrator model built around native background subagents |
504
521
  | **[Multiplexer Integration](docs/multiplexer-integration.md)** | Watch agents work live in Tmux or Zellij panes |
505
522
  | **[Session Management](docs/session-management.md)** | Reuse recent child-agent sessions with short aliases instead of starting over |
506
- | **[Todo Continuation](docs/todo-continuation.md)** | Auto-continue orchestrator sessions with cooldowns and safety checks |
507
523
  | **[Preset Switching](docs/preset-switching.md)** | Switch agent model presets at runtime with `/preset` |
508
524
  | **[Custom Agents](docs/configuration.md#custom-agents)** | Define your own specialists with custom prompts, models, MCP access, and Orchestrator delegation rules |
509
525
  | **[Codemap](docs/codemap.md)** | Generate hierarchical codemaps to understand large codebases faster |
@@ -517,7 +533,7 @@ Use this section as a map: start with installation, then jump to features, confi
517
533
  |-----|----------------|
518
534
  | **[Configuration](docs/configuration.md)** | Config file locations, JSONC support, prompt overrides, and full option reference |
519
535
  | **[Maintainer Guide](docs/maintainers.md)** | Issue triage rules, label meanings, support routing, and repo maintenance workflow |
520
- | **[Skills](docs/skills.md)** | Bundled skills such as `simplify`, `codemap`, and `clonedeps` |
536
+ | **[Skills](docs/skills.md)** | Bundled skills such as `simplify`, `codemap`, `clonedeps`, `deepwork`, and `oh-my-opencode-slim` |
521
537
  | **[MCPs](docs/mcps.md)** | `websearch`, `context7`, `grep_app`, and how MCP permissions work per agent |
522
538
  | **[Tools](docs/tools.md)** | Built-in tool capabilities like `webfetch`, LSP tools, code search, and formatters |
523
539
 
@@ -538,7 +554,7 @@ Use this section as a map: start with installation, then jump to features, confi
538
554
  <p><sub>Every merged contribution leaves a mark on the realm.</sub></p>
539
555
 
540
556
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
541
- [![All Contributors](https://img.shields.io/badge/all_contributors-53-orange.svg?style=flat-square)](#contributors-)
557
+ [![All Contributors](https://img.shields.io/badge/all_contributors-58-orange.svg?style=flat-square)](#contributors-)
542
558
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
543
559
  </div>
544
560
 
@@ -619,6 +635,13 @@ Use this section as a map: start with installation, then jump to features, confi
619
635
  <td align="center" valign="top" width="16.66%"><a href="https://github.com/yolo2h"><img src="https://avatars.githubusercontent.com/u/10754850?v=4?s=100" width="100px;" alt="Yolo"/><br /><sub><b>Yolo</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=yolo2h" title="Code">💻</a></td>
620
636
  <td align="center" valign="top" width="16.66%"><a href="https://github.com/xinxingi"><img src="https://avatars.githubusercontent.com/u/49302071?v=4?s=100" width="100px;" alt="XinXing"/><br /><sub><b>XinXing</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=xinxingi" title="Code">💻</a></td>
621
637
  <td align="center" valign="top" width="16.66%"><a href="https://github.com/eltociear"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt="Ikko Eltociear Ashimine"/><br /><sub><b>Ikko Eltociear Ashimine</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=eltociear" title="Code">💻</a></td>
638
+ <td align="center" valign="top" width="16.66%"><a href="https://github.com/dev-wantap"><img src="https://avatars.githubusercontent.com/u/69743540?v=4?s=100" width="100px;" alt="GWANWOO KIM"/><br /><sub><b>GWANWOO KIM</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=dev-wantap" title="Code">💻</a></td>
639
+ </tr>
640
+ <tr>
641
+ <td align="center" valign="top" width="16.66%"><a href="https://github.com/OmerFarukOruc"><img src="https://avatars.githubusercontent.com/u/7347742?v=4?s=100" width="100px;" alt="Omer Faruk Oruc"/><br /><sub><b>Omer Faruk Oruc</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=OmerFarukOruc" title="Code">💻</a></td>
642
+ <td align="center" valign="top" width="16.66%"><a href="https://khallaf.uk/"><img src="https://avatars.githubusercontent.com/u/51155980?v=4?s=100" width="100px;" alt="Omar Mohamed Khallaf"/><br /><sub><b>Omar Mohamed Khallaf</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=omar-mohamed-khallaf" title="Code">💻</a></td>
643
+ <td align="center" valign="top" width="16.66%"><a href="https://github.com/Qesire"><img src="https://avatars.githubusercontent.com/u/102657430?v=4?s=100" width="100px;" alt="Knowingthesea_Qesire"/><br /><sub><b>Knowingthesea_Qesire</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=Qesire" title="Code">💻</a></td>
644
+ <td align="center" valign="top" width="16.66%"><a href="http://www.flyinghail.net/"><img src="https://avatars.githubusercontent.com/u/157430?v=4?s=100" width="100px;" alt="FENG Hao"/><br /><sub><b>FENG Hao</b></sub></a><br /><a href="https://github.com/alvinunreal/oh-my-opencode-slim/commits?author=flyinghail" title="Code">💻</a></td>
622
645
  </tr>
623
646
  </tbody>
624
647
  </table>
package/README.zh-CN.md CHANGED
@@ -1,9 +1,6 @@
1
1
  <div align="center">
2
- <a href="https://github.com/alvinunreal/oh-my-opencode-slim/stargazers">
3
- <img src="img/v2beta.webp" alt="V2 Beta Release" style="border-radius: 10px;">
4
- </a>
5
- <h3>✨ V2 Beta 版本:后台编排已上线 ✨</h3>
6
- <p><i>编排者(Orchestrator)现在可在后台调度专家智能体,<br>同时 <code>/deepwork</code> 可以将宏大目标转化为基于文件的具体计划。<br>Beta 测试人员:请在 Telegram 上与我们分享您的反馈。</i></p>
2
+ <h3>✨ 默认后台编排已上线 ✨</h3>
3
+ <p><i>编排者(Orchestrator)现在作为工作流管理器在后台调度专家智能体,<br>同时 <code>/deepwork</code> 可以将宏大目标转化为基于文件的具体计划。<br>欢迎在 Telegram 上与我们分享反馈。</i></p>
7
4
 
8
5
  <p><b>开放式多智能体套件</b> · 混合任意模型 · 自动委派任务</p>
9
6
 
@@ -15,7 +12,7 @@
15
12
  </p>
16
13
 
17
14
  <p>
18
- <a href="README.md">English</a> | <b>简体中文</b> | <a href="README.ja-JP.md">日本語</a>
15
+ <a href="README.md">English</a> | <b>简体中文</b> | <a href="README.ja-JP.md">日本語</a> | <a href="README.ko-KR.md">한국어</a>
19
16
  </p>
20
17
  </div>
21
18
 
@@ -43,16 +40,19 @@ Install and configure oh-my-opencode-slim: https://raw.githubusercontent.com/alv
43
40
  bunx oh-my-opencode-slim@latest install
44
41
  ```
45
42
 
46
- ### V2 后台编排 Beta
43
+ > **翻译状态说明:** 英文 README 是最新版本;此中文翻译可能仍有少量旧表述。
47
44
 
48
- V2 将编排者(Orchestrator)从默认的执行工作器转变为调度器:
49
- 它规划工作、将专家作为后台任务分发、轮询其状态,并在继续执行之前核对结果。这需要 OpenCode 原生的后台子智能体支持,因此 Beta 版用户必须在启用实验性标志的情况下启动 OpenCode。
45
+ ### 默认后台编排
46
+
47
+ 当前版本将编排者(Orchestrator)从默认的执行工作器转变为调度器:
48
+ 它规划工作、将专家作为后台任务分发、按需检查状态,并在继续执行之前核对结果。这需要 OpenCode 原生的后台子智能体支持,因此请使用下方环境变量启动 OpenCode。
50
49
 
51
50
  ```bash
52
- bunx oh-my-opencode-slim@beta install
53
- OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=1 opencode
51
+ bunx oh-my-opencode-slim@beta install --background-subagents=yes
54
52
  ```
55
53
 
54
+ 安装后请重启终端或 source 更新过的 shell 文件,然后再运行 `opencode`;也可以一次性使用 `OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true opencode` 启动。
55
+
56
56
  ### 入门指南
57
57
 
58
58
  安装程序会同时生成 OpenAI 和 OpenCode Go 的预设(Preset),默认启用 OpenAI 预设。OpenAI 使用 `openai/gpt-5.5` 作为具备高级判断力智能体的模型,并使用 `openai/gpt-5.4-mini` 作为响应更快速、针对具体任务智能体的模型。若要在安装过程中激活 OpenCode Go 预设,请运行 `bunx oh-my-opencode-slim@latest install --preset=opencode-go` 或在安装后修改 `~/.config/opencode/oh-my-opencode-slim.json` 文件中的默认预设名称。
@@ -74,7 +74,7 @@ OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=1 opencode
74
74
  4. **为您要分配的每个智能体更新模型配置**
75
75
 
76
76
  > [!TIP]
77
- > **强烈建议**了解自动委派(Automatic Delegation)的工作原理。**[编排者提示词 (Orchestrator prompt)](https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/src/agents/orchestrator.ts#L28)** 包含了委派规则、专家路由逻辑,以及主智能体何时将工作转交给子智能体的阈值。您始终可以通过以下方式手动委派任务:`@智能体名称 <任务内容>`
77
+ > **建议**了解后台编排的工作原理。**[编排者提示词 (Orchestrator prompt)](https://github.com/alvinunreal/oh-my-opencode-slim/blob/master/src/agents/orchestrator.ts#L28)** 包含调度规则、专家路由逻辑,以及何时应把工作分配给后台智能体的阈值。您始终可以通过以下方式手动委派任务:`@智能体名称 <任务内容>`
78
78
 
79
79
  默认生成的配置包含 `openai` 和 `opencode-go` 两个预设:
80
80
 
@@ -116,8 +116,10 @@ OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=1 opencode
116
116
 
117
117
  在完成安装与认证后,请验证所有智能体是否已正确配置并能够响应:
118
118
 
119
+ 请先确保已重启终端或 source 更新过的 shell 文件。环境变量生效后可运行 `opencode`;如果尚未更新当前 shell,请使用:
120
+
119
121
  ```bash
120
- opencode
122
+ OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true opencode
121
123
  ```
122
124
 
123
125
  然后运行:
@@ -495,10 +497,8 @@ ping all agents
495
497
  | **[Council (议会) (docs/council.md)](docs/council.md)** | 使用 `@council` 并行运行多个模型并合成单一答案 |
496
498
  | **[多路复用器集成 (docs/multiplexer-integration.md)](docs/multiplexer-integration.md)** | 在 Tmux 或 Zellij 窗格中实时观看智能体的工作过程 |
497
499
  | **[会话管理 (docs/session-management.md)](docs/session-management.md)** | 使用短别名复用最近的子智能体会话,而不是重新开始 |
498
- | **[待办事项持续执行 (docs/todo-continuation.md)](docs/todo-continuation.md)** | 具备冷却时间和安全检查的编排者会话自动持续执行 |
499
500
  | **[运行时预设切换 (docs/preset-switching.md)](docs/preset-switching.md)** | 在运行时使用 `/preset` 切换智能体模型预设 |
500
501
  | **[自定义智能体 (docs/configuration.md#custom-agents)](docs/configuration.md#custom-agents)** | 自定义专家智能体:配置独特的提示词、模型、MCP 权限和编排者委派规则 |
501
- | **[子任务 (docs/subtask.md)](docs/subtask.md)** | 使用 `/subtask` 运行受限的子工作器,并将结构化总结返回到主会话 |
502
502
  | **[代码地图 (Codemap) (docs/codemap.md)](docs/codemap.md)** | 生成层级代码地图,快速理解大型代码库 |
503
503
  | **[克隆依赖 (Clonedeps) (docs/clonedeps.md)](docs/clonedeps.md)** | 将选定的依赖源码克隆到被忽略的本地工作区中以供检查 |
504
504
  | **[访谈式生成 (Interview) (docs/interview.md)](docs/interview.md)** | 通过基于浏览器的问答流,将粗糙的想法转变为结构化的 Markdown 规范文档 |
@@ -0,0 +1,13 @@
1
+ export type BackgroundSubagentsMode = 'ask' | 'yes' | 'no';
2
+ export type ShellKind = 'bash' | 'fish' | 'zsh';
3
+ export declare function isBackgroundSubagentsEnabled(value: string | undefined): boolean;
4
+ export declare function detectShellKind(shell: string | undefined): ShellKind | undefined;
5
+ export declare function detectBackgroundSubagentsTarget(env?: NodeJS.ProcessEnv): string | undefined;
6
+ export declare function getBackgroundSubagentsBlock(targetPath: string): string;
7
+ export declare function manualBackgroundSubagentsInstructions(options?: {
8
+ targetPath?: string;
9
+ shell?: ShellKind;
10
+ }): string;
11
+ export declare function expandHomePath(targetPath: string): string;
12
+ export declare function upsertBackgroundSubagentsBlock(content: string, block: string): string;
13
+ export declare function writeBackgroundSubagentsBlock(targetPath: string): void;
@@ -1,2 +1,3 @@
1
1
  #!/usr/bin/env bun
2
- export {};
2
+ import type { InstallArgs } from './types';
3
+ export declare function parseArgs(args: string[]): InstallArgs;
package/dist/cli/index.js CHANGED
@@ -100,7 +100,7 @@ function getConfigSearchDirs() {
100
100
  });
101
101
  }
102
102
  function getOpenCodeConfigPaths() {
103
- const configDir = getDefaultOpenCodeConfigDir();
103
+ const configDir = getConfigDir();
104
104
  return [join(configDir, "opencode.json"), join(configDir, "opencode.jsonc")];
105
105
  }
106
106
  function getConfigJson() {
@@ -367,12 +367,6 @@ var DivoomConfigSchema = z2.object({
367
367
  posterizeBits: z2.number().int().min(1).max(8).default(3),
368
368
  gifs: z2.record(z2.string(), z2.string().min(1)).optional()
369
369
  });
370
- var TodoContinuationConfigSchema = z2.object({
371
- maxContinuations: z2.number().int().min(1).max(50).default(5).describe("Maximum consecutive auto-continuations before stopping to ask user"),
372
- cooldownMs: z2.number().int().min(0).max(30000).default(3000).describe("Delay in ms before auto-continuing (gives user time to abort)"),
373
- autoEnable: z2.boolean().default(false).describe("Automatically enable auto-continue when the orchestrator session has enough todos"),
374
- autoEnableThreshold: z2.number().int().min(1).max(50).default(4).describe("Number of todos that triggers auto-enable (only used when autoEnable is true)")
375
- });
376
370
  var FailoverConfigSchema = z2.object({
377
371
  enabled: z2.boolean().default(true),
378
372
  timeoutMs: z2.number().min(0).default(15000),
@@ -419,7 +413,6 @@ var PluginConfigSchema = z2.object({
419
413
  interview: InterviewConfigSchema.optional(),
420
414
  backgroundJobs: BackgroundJobsConfigSchema.optional(),
421
415
  divoom: DivoomConfigSchema.optional(),
422
- todoContinuation: TodoContinuationConfigSchema.optional(),
423
416
  fallback: FailoverConfigSchema.optional(),
424
417
  council: CouncilConfigSchema.optional()
425
418
  }).superRefine((value, ctx) => {
@@ -479,6 +472,12 @@ var CUSTOM_SKILLS = [
479
472
  description: "Heavy/complex coding sessions and large modifications workflow",
480
473
  allowedAgents: ["orchestrator"],
481
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"
482
481
  }
483
482
  ];
484
483
  function getCustomSkillsDir() {
@@ -625,6 +624,12 @@ function generateLiteConfig(installConfig) {
625
624
 
626
625
  // src/cli/config-io.ts
627
626
  var PACKAGE_NAME = "oh-my-opencode-slim";
627
+ var DEFAULT_OPENCODE_AGENTS_TO_DISABLE = [
628
+ "build",
629
+ "explore",
630
+ "general",
631
+ "plan"
632
+ ];
628
633
  function isString(value) {
629
634
  return typeof value === "string";
630
635
  }
@@ -705,17 +710,49 @@ function getPluginEntry() {
705
710
  return PACKAGE_NAME;
706
711
  }
707
712
  }
708
- function getOpenCodePluginCacheDir() {
713
+ function getPinnedVersionFromConfig() {
714
+ try {
715
+ const { config } = parseConfig(getExistingConfigPath());
716
+ if (!config)
717
+ return;
718
+ for (const entry of getPlugins(config)) {
719
+ const spec = getPluginSpec(entry);
720
+ if (!spec)
721
+ continue;
722
+ if (spec === PACKAGE_NAME)
723
+ return;
724
+ if (spec.startsWith(`${PACKAGE_NAME}@`)) {
725
+ const version = spec.slice(PACKAGE_NAME.length + 1);
726
+ if (version && version !== "latest")
727
+ return version;
728
+ }
729
+ }
730
+ } catch {}
731
+ return;
732
+ }
733
+ function getVersionFromPackageRoot(packageRoot) {
734
+ try {
735
+ const packageJsonPath = join3(packageRoot, "package.json");
736
+ if (!existsSync3(packageJsonPath))
737
+ return;
738
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
739
+ return pkg.version;
740
+ } catch {
741
+ return;
742
+ }
743
+ }
744
+ function getOpenCodePluginCacheDir(version) {
709
745
  const cacheDir = process.env.XDG_CACHE_HOME?.trim() || join3(homedir2(), ".cache");
710
- return join3(cacheDir, "opencode", "packages", `${PACKAGE_NAME}@latest`);
746
+ const suffix = version ? `${PACKAGE_NAME}@${version}` : `${PACKAGE_NAME}@latest`;
747
+ return join3(cacheDir, "opencode", "packages", suffix);
711
748
  }
712
- function writeOpenCodePluginCacheManifest(cacheDir) {
749
+ function writeOpenCodePluginCacheManifest(cacheDir, version = "latest") {
713
750
  try {
714
751
  writeFileSync(join3(cacheDir, "package.json"), JSON.stringify({
715
752
  name: `${PACKAGE_NAME}-cache`,
716
753
  private: true,
717
754
  dependencies: {
718
- [PACKAGE_NAME]: "latest"
755
+ [PACKAGE_NAME]: version
719
756
  }
720
757
  }, null, 2));
721
758
  return null;
@@ -763,7 +800,10 @@ async function warmOpenCodePluginCache() {
763
800
  if (!packageRoot || !isPackageManagerInstall(packageRoot)) {
764
801
  return null;
765
802
  }
766
- const cacheDir = getOpenCodePluginCacheDir();
803
+ const pinnedVersion = getPinnedVersionFromConfig();
804
+ const runningVersion = getVersionFromPackageRoot(packageRoot);
805
+ const cacheVersion = pinnedVersion ?? runningVersion;
806
+ const cacheDir = getOpenCodePluginCacheDir(cacheVersion);
767
807
  try {
768
808
  mkdirSync3(cacheDir, { recursive: true });
769
809
  } catch (err) {
@@ -773,7 +813,7 @@ async function warmOpenCodePluginCache() {
773
813
  error: `Failed to create OpenCode cache directory: ${err}`
774
814
  };
775
815
  }
776
- const manifestError = writeOpenCodePluginCacheManifest(cacheDir);
816
+ const manifestError = writeOpenCodePluginCacheManifest(cacheDir, cacheVersion);
777
817
  if (manifestError)
778
818
  return manifestError;
779
819
  try {
@@ -956,8 +996,13 @@ function disableDefaultAgents() {
956
996
  }
957
997
  const config = parsedConfig ?? {};
958
998
  const agent = config.agent ?? {};
959
- agent.explore = { disable: true };
960
- agent.general = { disable: true };
999
+ for (const agentName of DEFAULT_OPENCODE_AGENTS_TO_DISABLE) {
1000
+ const existing = agent[agentName];
1001
+ agent[agentName] = {
1002
+ ...existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {},
1003
+ disable: true
1004
+ };
1005
+ }
961
1006
  config.agent = agent;
962
1007
  writeConfig(configPath, config);
963
1008
  return { success: true, configPath };
@@ -1304,8 +1349,103 @@ Options:
1304
1349
  }
1305
1350
 
1306
1351
  // src/cli/install.ts
1307
- import { existsSync as existsSync5 } from "node:fs";
1352
+ import { existsSync as existsSync6 } from "node:fs";
1308
1353
  import { createInterface } from "node:readline/promises";
1354
+
1355
+ // src/cli/background-subagents.ts
1356
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
1357
+ import { homedir as homedir3 } from "node:os";
1358
+ import { dirname as dirname4, join as join5 } from "node:path";
1359
+ var ENV_NAME = "OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS";
1360
+ var START_MARKER = "# >>> oh-my-opencode-slim background subagents >>>";
1361
+ var END_MARKER = "# <<< oh-my-opencode-slim background subagents <<<";
1362
+ function isBackgroundSubagentsEnabled(value) {
1363
+ if (!value)
1364
+ return false;
1365
+ const normalized = value.trim().toLowerCase();
1366
+ return normalized !== "" && !["0", "false", "no", "off"].includes(normalized);
1367
+ }
1368
+ function detectShellKind(shell) {
1369
+ const name = shell?.split("/").at(-1);
1370
+ if (name === "zsh" || name === "bash" || name === "fish")
1371
+ return name;
1372
+ return;
1373
+ }
1374
+ function detectBackgroundSubagentsTarget(env = process.env) {
1375
+ const shell = detectShellKind(env.SHELL);
1376
+ if (shell === "zsh")
1377
+ return join5(homedir3(), ".zshrc");
1378
+ if (shell === "bash")
1379
+ return join5(homedir3(), ".bashrc");
1380
+ if (shell === "fish") {
1381
+ const configHome = env.XDG_CONFIG_HOME || join5(homedir3(), ".config");
1382
+ return join5(configHome, "fish", "conf.d", "opencode-background-subagents.fish");
1383
+ }
1384
+ return;
1385
+ }
1386
+ function getBackgroundSubagentsBlock(targetPath) {
1387
+ const isFish = targetPath.endsWith(".fish");
1388
+ const command = isFish ? `set -gx ${ENV_NAME} true` : `export ${ENV_NAME}=true`;
1389
+ return `${START_MARKER}
1390
+ ${command}
1391
+ ${END_MARKER}`;
1392
+ }
1393
+ function manualBackgroundSubagentsInstructions(options) {
1394
+ const shell = options?.shell ?? (options?.targetPath?.endsWith(".fish") ? "fish" : undefined) ?? detectShellKind(options?.targetPath);
1395
+ const bashZshSnippet = `export ${ENV_NAME}=true`;
1396
+ const fishSnippet = `set -gx ${ENV_NAME} true`;
1397
+ if (shell === "fish") {
1398
+ return `Start OpenCode with background subagents enabled:
1399
+ env ${ENV_NAME}=true opencode
1400
+
1401
+ Or add this to your fish startup file:
1402
+ ${fishSnippet}`;
1403
+ }
1404
+ if (shell === "bash" || shell === "zsh") {
1405
+ return `Start OpenCode with background subagents enabled:
1406
+ ${ENV_NAME}=true opencode
1407
+
1408
+ Or add this to your shell startup file:
1409
+ ${bashZshSnippet}`;
1410
+ }
1411
+ return `Start OpenCode with background subagents enabled:
1412
+ ${ENV_NAME}=true opencode
1413
+
1414
+ Or add one of these to your shell startup file:
1415
+ bash/zsh: ${bashZshSnippet}
1416
+ fish: ${fishSnippet}`;
1417
+ }
1418
+ function expandHomePath(targetPath) {
1419
+ if (targetPath === "~")
1420
+ return homedir3();
1421
+ if (targetPath.startsWith("~/"))
1422
+ return join5(homedir3(), targetPath.slice(2));
1423
+ return targetPath;
1424
+ }
1425
+ function upsertBackgroundSubagentsBlock(content, block) {
1426
+ const start = content.indexOf(START_MARKER);
1427
+ const end = content.indexOf(END_MARKER);
1428
+ if (start !== -1 && end !== -1 && end > start) {
1429
+ const afterEnd = end + END_MARKER.length;
1430
+ return `${content.slice(0, start)}${block}${content.slice(afterEnd)}`;
1431
+ }
1432
+ const separator = content.length > 0 && !content.endsWith(`
1433
+ `) ? `
1434
+
1435
+ ` : "";
1436
+ const prefix = content.length > 0 && content.endsWith(`
1437
+ `) ? `
1438
+ ` : separator;
1439
+ return `${content}${prefix}${block}
1440
+ `;
1441
+ }
1442
+ function writeBackgroundSubagentsBlock(targetPath) {
1443
+ const block = getBackgroundSubagentsBlock(targetPath);
1444
+ const content = existsSync5(targetPath) ? readFileSync4(targetPath, "utf8") : "";
1445
+ const nextContent = upsertBackgroundSubagentsBlock(content, block);
1446
+ mkdirSync4(dirname4(targetPath), { recursive: true });
1447
+ writeFileSync2(targetPath, nextContent);
1448
+ }
1309
1449
  // src/cli/system.ts
1310
1450
  import { spawnSync } from "node:child_process";
1311
1451
  import { statSync as statSync4 } from "node:fs";
@@ -1517,6 +1657,59 @@ async function checkOpenCodeInstalled() {
1517
1657
  printSuccess(`OpenCode ${detectedVersion} detected${pathInfo}`);
1518
1658
  return { ok: true, version: version ?? undefined, path: path2 ?? undefined };
1519
1659
  }
1660
+ function shouldPromptForBackgroundSubagents(config) {
1661
+ return Boolean(config.promptForStar && process.stdin.isTTY);
1662
+ }
1663
+ async function configureBackgroundSubagents(config) {
1664
+ if (isBackgroundSubagentsEnabled(process.env.OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS)) {
1665
+ printSuccess("OpenCode background subagents already enabled in environment");
1666
+ return { enabledNow: true };
1667
+ }
1668
+ const target = config.backgroundSubagentsTarget !== undefined ? expandHomePath(config.backgroundSubagentsTarget) : detectBackgroundSubagentsTarget();
1669
+ if (config.backgroundSubagents === "no") {
1670
+ printInfo("OpenCode background subagents are not enabled.");
1671
+ console.log(manualBackgroundSubagentsInstructions({ targetPath: target }));
1672
+ return { enabledNow: false };
1673
+ }
1674
+ if (!target) {
1675
+ printInfo("No safe shell startup file detected.");
1676
+ console.log(manualBackgroundSubagentsInstructions());
1677
+ return { enabledNow: false };
1678
+ }
1679
+ const block = getBackgroundSubagentsBlock(target);
1680
+ if (config.dryRun) {
1681
+ printInfo("Dry run mode - background subagents block that would be written:");
1682
+ console.log(`Target: ${target}`);
1683
+ console.log(`
1684
+ ${block}
1685
+ `);
1686
+ return { enabledNow: false, configuredTarget: target };
1687
+ }
1688
+ if (config.backgroundSubagents === "ask") {
1689
+ if (!shouldPromptForBackgroundSubagents(config)) {
1690
+ printInfo("Skipped background subagents shell configuration.");
1691
+ console.log(manualBackgroundSubagentsInstructions({ targetPath: target }));
1692
+ return { enabledNow: false };
1693
+ }
1694
+ const shouldWrite = await confirm(`Enable OpenCode background subagents in ${target}?`, true);
1695
+ if (!shouldWrite) {
1696
+ printInfo("Skipped background subagents shell configuration.");
1697
+ console.log(manualBackgroundSubagentsInstructions({ targetPath: target }));
1698
+ return { enabledNow: false };
1699
+ }
1700
+ }
1701
+ try {
1702
+ writeBackgroundSubagentsBlock(target);
1703
+ } catch (error) {
1704
+ const message = error instanceof Error ? error.message : String(error);
1705
+ printError(`Could not write background subagents shell config: ${message}`);
1706
+ printInfo("Add the setting manually instead:");
1707
+ console.log(manualBackgroundSubagentsInstructions({ targetPath: target }));
1708
+ return { enabledNow: false };
1709
+ }
1710
+ printSuccess(`Background subagents enabled ${SYMBOLS.arrow} ${DIM}${target}${RESET}`);
1711
+ return { enabledNow: false, configuredTarget: target };
1712
+ }
1520
1713
  function handleStepResult(result, successMsg) {
1521
1714
  if (!result.success) {
1522
1715
  printError(`Failed: ${result.error}`);
@@ -1529,7 +1722,7 @@ async function runInstall(config) {
1529
1722
  const detected = detectCurrentConfig();
1530
1723
  const isUpdate = detected.isInstalled;
1531
1724
  printHeader(isUpdate);
1532
- let totalSteps = 6;
1725
+ let totalSteps = 7;
1533
1726
  if (config.installCustomSkills)
1534
1727
  totalSteps += 1;
1535
1728
  totalSteps += 1;
@@ -1590,6 +1783,8 @@ async function runInstall(config) {
1590
1783
  if (!handleStepResult(lspResult, "LSP enabled"))
1591
1784
  return 1;
1592
1785
  }
1786
+ printStep(step++, totalSteps, "Configuring OpenCode background subagents...");
1787
+ const backgroundSubagents = await configureBackgroundSubagents(config);
1593
1788
  printStep(step++, totalSteps, "Writing oh-my-opencode-slim configuration...");
1594
1789
  if (config.dryRun) {
1595
1790
  const liteConfig = generateLiteConfig(config);
@@ -1599,7 +1794,7 @@ ${JSON.stringify(liteConfig, null, 2)}
1599
1794
  `);
1600
1795
  } else {
1601
1796
  const configPath2 = getExistingLiteConfigPath();
1602
- const configExists = existsSync5(configPath2);
1797
+ const configExists = existsSync6(configPath2);
1603
1798
  if (configExists && !config.reset) {
1604
1799
  printInfo(`Configuration already exists at ${configPath2}. Use --reset to overwrite.`);
1605
1800
  } else {
@@ -1646,7 +1841,15 @@ ${JSON.stringify(liteConfig, null, 2)}
1646
1841
  console.log(` ${BLUE}${configPath}${RESET}`);
1647
1842
  console.log();
1648
1843
  console.log(" 4. Start OpenCode:");
1649
- console.log(` ${BLUE}$ opencode${RESET}`);
1844
+ if (backgroundSubagents.enabledNow) {
1845
+ console.log(` ${BLUE}$ opencode${RESET}`);
1846
+ } else if (backgroundSubagents.configuredTarget) {
1847
+ console.log(` ${BLUE}$ source ${backgroundSubagents.configuredTarget}${RESET}`);
1848
+ console.log(` ${BLUE}$ opencode${RESET}`);
1849
+ console.log(` ${DIM}Or restart your terminal before running opencode.${RESET}`);
1850
+ } else {
1851
+ console.log(` ${BLUE}$ OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true opencode${RESET}`);
1852
+ }
1650
1853
  console.log();
1651
1854
  console.log(" 5. Verify the agents are responding:");
1652
1855
  console.log(` ${BLUE}> ping all agents${RESET}`);
@@ -1668,7 +1871,9 @@ async function install(args) {
1668
1871
  preset: args.preset,
1669
1872
  promptForStar: args.tui,
1670
1873
  dryRun: args.dryRun,
1671
- reset: args.reset ?? false
1874
+ reset: args.reset ?? false,
1875
+ backgroundSubagents: args.backgroundSubagents ?? "no",
1876
+ backgroundSubagentsTarget: args.backgroundSubagentsTarget
1672
1877
  };
1673
1878
  return runInstall(config);
1674
1879
  }
@@ -1700,6 +1905,15 @@ function parseArgs(args) {
1700
1905
  process.exit(1);
1701
1906
  }
1702
1907
  result.preset = preset;
1908
+ } else if (arg.startsWith("--background-subagents=")) {
1909
+ const mode = arg.split("=")[1];
1910
+ if (!["ask", "yes", "no"].includes(mode)) {
1911
+ console.error("Unsupported --background-subagents value: use ask, yes, or no");
1912
+ process.exit(1);
1913
+ }
1914
+ result.backgroundSubagents = mode;
1915
+ } else if (arg.startsWith("--background-subagents-target=")) {
1916
+ result.backgroundSubagentsTarget = arg.split("=")[1];
1703
1917
  } else if (arg === "--dry-run") {
1704
1918
  result.dryRun = true;
1705
1919
  } else if (arg === "--reset") {
@@ -1709,6 +1923,7 @@ function parseArgs(args) {
1709
1923
  process.exit(0);
1710
1924
  }
1711
1925
  }
1926
+ result.backgroundSubagents ??= result.tui && process.stdin.isTTY ? "ask" : "no";
1712
1927
  return result;
1713
1928
  }
1714
1929
  function printHelp() {
@@ -1722,6 +1937,11 @@ Usage:
1722
1937
  Options:
1723
1938
  --skills=yes|no Install bundled skills (default: yes)
1724
1939
  --preset=<name> Active generated config preset (default: openai)
1940
+ --background-subagents=ask|yes|no
1941
+ Persist required OpenCode background subagent env
1942
+ (default: ask in interactive TTY, otherwise no)
1943
+ --background-subagents-target=<path>
1944
+ Shell startup file to update
1725
1945
  --no-tui Non-interactive mode
1726
1946
  --dry-run Simulate install without writing files
1727
1947
  --reset Force overwrite of existing configuration
@@ -1739,6 +1959,7 @@ For the full config reference, see docs/configuration.md.
1739
1959
  Examples:
1740
1960
  bunx oh-my-opencode-slim install
1741
1961
  bunx oh-my-opencode-slim install --no-tui --skills=yes
1962
+ bunx oh-my-opencode-slim install --background-subagents=yes
1742
1963
  bunx oh-my-opencode-slim install --preset=opencode-go
1743
1964
  bunx oh-my-opencode-slim install --reset
1744
1965
  bunx oh-my-opencode-slim doctor
@@ -1764,7 +1985,12 @@ async function main() {
1764
1985
  process.exit(1);
1765
1986
  }
1766
1987
  }
1767
- main().catch((err) => {
1768
- console.error("Fatal error:", err);
1769
- process.exit(1);
1770
- });
1988
+ if (__require.main == __require.module) {
1989
+ main().catch((err) => {
1990
+ console.error("Fatal error:", err);
1991
+ process.exit(1);
1992
+ });
1993
+ }
1994
+ export {
1995
+ parseArgs
1996
+ };