oh-my-opencode 2.5.3 → 2.5.4
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.md +14 -15
- package/README.ko.md +14 -15
- package/README.md +14 -15
- package/README.zh-cn.md +14 -15
- package/dist/cli/index.js +185 -25
- package/dist/cli/run/events.d.ts +4 -0
- package/dist/cli/run/types.d.ts +26 -0
- package/dist/config/schema.d.ts +5 -7
- package/dist/features/background-agent/types.d.ts +8 -0
- package/dist/hooks/anthropic-auto-compact/executor.test.d.ts +1 -0
- package/dist/index.js +347 -294
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
|
|
57
57
|
> "Oh My Opencodeは頂点に立っています、敵はいません" — [RyanOnThePath](https://x.com/RyanOnThePath/status/2001438321252118548)
|
|
58
58
|
|
|
59
|
+
> "シジフォスという名前自体が美しいじゃないですか?" — Sigrid ([@sigridjin_eth](https://x.com/sigridjin_eth))
|
|
60
|
+
|
|
59
61
|
---
|
|
60
62
|
|
|
61
63
|
## 目次
|
|
@@ -717,8 +719,8 @@ Oh My OpenCode は以下の場所からフックを読み込んで実行しま
|
|
|
717
719
|
有効時(デフォルト)、Sisyphus はオプションの特殊エージェントを備えた強力なオーケストレーターを提供します:
|
|
718
720
|
|
|
719
721
|
- **Sisyphus**: プライマリオーケストレーターエージェント (Claude Opus 4.5)
|
|
720
|
-
- **Builder-Sisyphus**:
|
|
721
|
-
- **Planner-Sisyphus**:
|
|
722
|
+
- **Builder-Sisyphus**: OpenCode のデフォルトビルドエージェント(SDK 制限により名前変更、デフォルトで無効)
|
|
723
|
+
- **Planner-Sisyphus**: OpenCode のデフォルトプランエージェント(SDK 制限により名前変更、デフォルトで有効)
|
|
722
724
|
|
|
723
725
|
**設定オプション:**
|
|
724
726
|
|
|
@@ -726,26 +728,24 @@ Oh My OpenCode は以下の場所からフックを読み込んで実行しま
|
|
|
726
728
|
{
|
|
727
729
|
"sisyphus_agent": {
|
|
728
730
|
"disabled": false,
|
|
729
|
-
"
|
|
731
|
+
"default_builder_enabled": false,
|
|
730
732
|
"planner_enabled": true,
|
|
731
|
-
"replace_build": true,
|
|
732
733
|
"replace_plan": true
|
|
733
734
|
}
|
|
734
735
|
}
|
|
735
736
|
```
|
|
736
737
|
|
|
737
|
-
**例:Builder-Sisyphus
|
|
738
|
+
**例:Builder-Sisyphus を有効化:**
|
|
738
739
|
|
|
739
740
|
```json
|
|
740
741
|
{
|
|
741
742
|
"sisyphus_agent": {
|
|
742
|
-
"
|
|
743
|
-
"replace_build": false
|
|
743
|
+
"default_builder_enabled": true
|
|
744
744
|
}
|
|
745
745
|
}
|
|
746
746
|
```
|
|
747
747
|
|
|
748
|
-
これにより、Builder-Sisyphus
|
|
748
|
+
これにより、Sisyphus と並行して Builder-Sisyphus エージェントを有効化できます。Sisyphus が有効な場合、デフォルトのビルドエージェントは常にサブエージェントモードに降格されます。
|
|
749
749
|
|
|
750
750
|
**例:すべての Sisyphus オーケストレーションを無効化:**
|
|
751
751
|
|
|
@@ -776,13 +776,12 @@ Oh My OpenCode は以下の場所からフックを読み込んで実行しま
|
|
|
776
776
|
}
|
|
777
777
|
```
|
|
778
778
|
|
|
779
|
-
| オプション
|
|
780
|
-
|
|
|
781
|
-
| `disabled`
|
|
782
|
-
| `
|
|
783
|
-
| `planner_enabled`
|
|
784
|
-
| `
|
|
785
|
-
| `replace_plan` | `true` | `true` の場合、デフォルトのプランエージェントをサブエージェントモードに降格させます。`false` に設定すると、Planner-Sisyphus とデフォルトのプランの両方を利用できます。 |
|
|
779
|
+
| オプション | デフォルト | 説明 |
|
|
780
|
+
| --------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
781
|
+
| `disabled` | `false` | `true` の場合、すべての Sisyphus オーケストレーションを無効化し、元の build/plan をプライマリとして復元します。 |
|
|
782
|
+
| `default_builder_enabled` | `false` | `true` の場合、Builder-Sisyphus エージェントを有効化します(OpenCode build と同じ、SDK 制限により名前変更)。デフォルトでは無効です。 |
|
|
783
|
+
| `planner_enabled` | `true` | `true` の場合、Planner-Sisyphus エージェントを有効化します(OpenCode plan と同じ、SDK 制限により名前変更)。デフォルトで有効です。 |
|
|
784
|
+
| `replace_plan` | `true` | `true` の場合、デフォルトのプランエージェントをサブエージェントモードに降格させます。`false` に設定すると、Planner-Sisyphus とデフォルトのプランの両方を利用できます。 |
|
|
786
785
|
|
|
787
786
|
### Hooks
|
|
788
787
|
|
package/README.ko.md
CHANGED
|
@@ -53,6 +53,8 @@
|
|
|
53
53
|
|
|
54
54
|
> "Oh My Opencode는 독보적입니다, 경쟁자가 없습니다" — [RyanOnThePath](https://x.com/RyanOnThePath/status/2001438321252118548)
|
|
55
55
|
|
|
56
|
+
> "시지푸스 이름 자체가 이쁘잖아요?" — Sigrid ([@sigridjin_eth](https://x.com/sigridjin_eth))
|
|
57
|
+
|
|
56
58
|
---
|
|
57
59
|
|
|
58
60
|
## 목차
|
|
@@ -711,8 +713,8 @@ Schema 자동 완성이 지원됩니다:
|
|
|
711
713
|
활성화 시 (기본값), Sisyphus는 옵션으로 선택 가능한 특화 에이전트들과 함께 강력한 오케스트레이터를 제공합니다:
|
|
712
714
|
|
|
713
715
|
- **Sisyphus**: Primary 오케스트레이터 에이전트 (Claude Opus 4.5)
|
|
714
|
-
- **Builder-Sisyphus**:
|
|
715
|
-
- **Planner-Sisyphus**:
|
|
716
|
+
- **Builder-Sisyphus**: OpenCode 기본 빌드 에이전트 (SDK 제한으로 이름만 변경, 기본적으로 비활성화)
|
|
717
|
+
- **Planner-Sisyphus**: OpenCode 기본 플랜 에이전트 (SDK 제한으로 이름만 변경, 기본적으로 활성화)
|
|
716
718
|
|
|
717
719
|
**설정 옵션:**
|
|
718
720
|
|
|
@@ -720,26 +722,24 @@ Schema 자동 완성이 지원됩니다:
|
|
|
720
722
|
{
|
|
721
723
|
"sisyphus_agent": {
|
|
722
724
|
"disabled": false,
|
|
723
|
-
"
|
|
725
|
+
"default_builder_enabled": false,
|
|
724
726
|
"planner_enabled": true,
|
|
725
|
-
"replace_build": true,
|
|
726
727
|
"replace_plan": true
|
|
727
728
|
}
|
|
728
729
|
}
|
|
729
730
|
```
|
|
730
731
|
|
|
731
|
-
**예시: Builder-Sisyphus
|
|
732
|
+
**예시: Builder-Sisyphus 활성화하기:**
|
|
732
733
|
|
|
733
734
|
```json
|
|
734
735
|
{
|
|
735
736
|
"sisyphus_agent": {
|
|
736
|
-
"
|
|
737
|
-
"replace_build": false
|
|
737
|
+
"default_builder_enabled": true
|
|
738
738
|
}
|
|
739
739
|
}
|
|
740
740
|
```
|
|
741
741
|
|
|
742
|
-
이렇게 하면 Builder-Sisyphus
|
|
742
|
+
이렇게 하면 Sisyphus와 함께 Builder-Sisyphus 에이전트를 활성화할 수 있습니다. Sisyphus가 활성화되면 기본 빌드 에이전트는 항상 subagent 모드로 강등됩니다.
|
|
743
743
|
|
|
744
744
|
**예시: 모든 Sisyphus 오케스트레이션 비활성화:**
|
|
745
745
|
|
|
@@ -770,13 +770,12 @@ Schema 자동 완성이 지원됩니다:
|
|
|
770
770
|
}
|
|
771
771
|
```
|
|
772
772
|
|
|
773
|
-
| 옵션
|
|
774
|
-
|
|
|
775
|
-
| `disabled`
|
|
776
|
-
| `
|
|
777
|
-
| `planner_enabled`
|
|
778
|
-
| `
|
|
779
|
-
| `replace_plan` | `true` | `true`면 기본 플랜 에이전트를 subagent 모드로 강등시킵니다. `false`로 설정하면 Planner-Sisyphus와 기본 플랜을 모두 사용할 수 있습니다. |
|
|
773
|
+
| 옵션 | 기본값 | 설명 |
|
|
774
|
+
| --------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
775
|
+
| `disabled` | `false` | `true`면 모든 Sisyphus 오케스트레이션을 비활성화하고 원래 build/plan을 primary로 복원합니다. |
|
|
776
|
+
| `default_builder_enabled` | `false` | `true`면 Builder-Sisyphus 에이전트를 활성화합니다 (OpenCode build와 동일, SDK 제한으로 이름만 변경). 기본적으로 비활성화되어 있습니다. |
|
|
777
|
+
| `planner_enabled` | `true` | `true`면 Planner-Sisyphus 에이전트를 활성화합니다 (OpenCode plan과 동일, SDK 제한으로 이름만 변경). 기본적으로 활성화되어 있습니다. |
|
|
778
|
+
| `replace_plan` | `true` | `true`면 기본 플랜 에이전트를 subagent 모드로 강등시킵니다. `false`로 설정하면 Planner-Sisyphus와 기본 플랜을 모두 사용할 수 있습니다. |
|
|
780
779
|
|
|
781
780
|
### Hooks
|
|
782
781
|
|
package/README.md
CHANGED
|
@@ -61,6 +61,8 @@ No stupid token consumption massive subagents here. No bloat tools here.
|
|
|
61
61
|
|
|
62
62
|
> "Oh My Opencode is king of the hill and has no contenders" — [RyanOnThePath](https://x.com/RyanOnThePath/status/2001438321252118548)
|
|
63
63
|
|
|
64
|
+
> "Isn't the name Sisyphus itself beautiful?" — Sigrid ([@sigridjin_eth](https://x.com/sigridjin_eth))
|
|
65
|
+
|
|
64
66
|
---
|
|
65
67
|
|
|
66
68
|
## Contents
|
|
@@ -783,8 +785,8 @@ Available agents: `oracle`, `librarian`, `explore`, `frontend-ui-ux-engineer`, `
|
|
|
783
785
|
When enabled (default), Sisyphus provides a powerful orchestrator with optional specialized agents:
|
|
784
786
|
|
|
785
787
|
- **Sisyphus**: Primary orchestrator agent (Claude Opus 4.5)
|
|
786
|
-
- **Builder-Sisyphus**:
|
|
787
|
-
- **Planner-Sisyphus**:
|
|
788
|
+
- **Builder-Sisyphus**: OpenCode's default build agent, renamed due to SDK limitations (disabled by default)
|
|
789
|
+
- **Planner-Sisyphus**: OpenCode's default plan agent, renamed due to SDK limitations (enabled by default)
|
|
788
790
|
|
|
789
791
|
**Configuration Options:**
|
|
790
792
|
|
|
@@ -792,26 +794,24 @@ When enabled (default), Sisyphus provides a powerful orchestrator with optional
|
|
|
792
794
|
{
|
|
793
795
|
"sisyphus_agent": {
|
|
794
796
|
"disabled": false,
|
|
795
|
-
"
|
|
797
|
+
"default_builder_enabled": false,
|
|
796
798
|
"planner_enabled": true,
|
|
797
|
-
"replace_build": true,
|
|
798
799
|
"replace_plan": true
|
|
799
800
|
}
|
|
800
801
|
}
|
|
801
802
|
```
|
|
802
803
|
|
|
803
|
-
**Example: Enable Builder-Sisyphus
|
|
804
|
+
**Example: Enable Builder-Sisyphus:**
|
|
804
805
|
|
|
805
806
|
```json
|
|
806
807
|
{
|
|
807
808
|
"sisyphus_agent": {
|
|
808
|
-
"
|
|
809
|
-
"replace_build": false
|
|
809
|
+
"default_builder_enabled": true
|
|
810
810
|
}
|
|
811
811
|
}
|
|
812
812
|
```
|
|
813
813
|
|
|
814
|
-
This
|
|
814
|
+
This enables Builder-Sisyphus agent alongside Sisyphus. The default build agent is always demoted to subagent mode when Sisyphus is enabled.
|
|
815
815
|
|
|
816
816
|
**Example: Disable all Sisyphus orchestration:**
|
|
817
817
|
|
|
@@ -842,13 +842,12 @@ You can also customize Sisyphus agents like other agents:
|
|
|
842
842
|
}
|
|
843
843
|
```
|
|
844
844
|
|
|
845
|
-
| Option
|
|
846
|
-
|
|
|
847
|
-
| `disabled`
|
|
848
|
-
| `
|
|
849
|
-
| `planner_enabled`
|
|
850
|
-
| `
|
|
851
|
-
| `replace_plan` | `true` | When `true`, demotes default plan agent to subagent mode. Set to `false` to keep both Planner-Sisyphus and default plan available. |
|
|
845
|
+
| Option | Default | Description |
|
|
846
|
+
| --------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
847
|
+
| `disabled` | `false` | When `true`, disables all Sisyphus orchestration and restores original build/plan as primary. |
|
|
848
|
+
| `default_builder_enabled` | `false` | When `true`, enables Builder-Sisyphus agent (same as OpenCode build, renamed due to SDK limitations). Disabled by default. |
|
|
849
|
+
| `planner_enabled` | `true` | When `true`, enables Planner-Sisyphus agent (same as OpenCode plan, renamed due to SDK limitations). Enabled by default. |
|
|
850
|
+
| `replace_plan` | `true` | When `true`, demotes default plan agent to subagent mode. Set to `false` to keep both Planner-Sisyphus and default plan available. |
|
|
852
851
|
|
|
853
852
|
### Hooks
|
|
854
853
|
|
package/README.zh-cn.md
CHANGED
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
|
|
59
59
|
> "Oh My Opencode 独孤求败,没有对手" — [RyanOnThePath](https://x.com/RyanOnThePath/status/2001438321252118548)
|
|
60
60
|
|
|
61
|
+
> "西西弗斯这个名字本身不就很美吗?" — Sigrid ([@sigridjin_eth](https://x.com/sigridjin_eth))
|
|
62
|
+
|
|
61
63
|
---
|
|
62
64
|
|
|
63
65
|
## 目录
|
|
@@ -717,8 +719,8 @@ Agent 爽了,你自然也爽。但我还想直接让你爽。
|
|
|
717
719
|
默认开启。Sisyphus 提供一个强力的编排器,带可选的专门 Agent:
|
|
718
720
|
|
|
719
721
|
- **Sisyphus**:主编排 Agent(Claude Opus 4.5)
|
|
720
|
-
- **Builder-Sisyphus**:
|
|
721
|
-
- **Planner-Sisyphus**:
|
|
722
|
+
- **Builder-Sisyphus**:OpenCode 默认构建 Agent(因 SDK 限制仅改名,默认禁用)
|
|
723
|
+
- **Planner-Sisyphus**:OpenCode 默认计划 Agent(因 SDK 限制仅改名,默认启用)
|
|
722
724
|
|
|
723
725
|
**配置选项:**
|
|
724
726
|
|
|
@@ -726,26 +728,24 @@ Agent 爽了,你自然也爽。但我还想直接让你爽。
|
|
|
726
728
|
{
|
|
727
729
|
"sisyphus_agent": {
|
|
728
730
|
"disabled": false,
|
|
729
|
-
"
|
|
731
|
+
"default_builder_enabled": false,
|
|
730
732
|
"planner_enabled": true,
|
|
731
|
-
"replace_build": true,
|
|
732
733
|
"replace_plan": true
|
|
733
734
|
}
|
|
734
735
|
}
|
|
735
736
|
```
|
|
736
737
|
|
|
737
|
-
**示例:启用 Builder-Sisyphus
|
|
738
|
+
**示例:启用 Builder-Sisyphus:**
|
|
738
739
|
|
|
739
740
|
```json
|
|
740
741
|
{
|
|
741
742
|
"sisyphus_agent": {
|
|
742
|
-
"
|
|
743
|
-
"replace_build": false
|
|
743
|
+
"default_builder_enabled": true
|
|
744
744
|
}
|
|
745
745
|
}
|
|
746
746
|
```
|
|
747
747
|
|
|
748
|
-
|
|
748
|
+
这样能和 Sisyphus 一起启用 Builder-Sisyphus Agent。启用 Sisyphus 后,默认构建 Agent 总会降级为子 Agent 模式。
|
|
749
749
|
|
|
750
750
|
**示例:禁用所有 Sisyphus 编排:**
|
|
751
751
|
|
|
@@ -776,13 +776,12 @@ Sisyphus Agent 也能自定义:
|
|
|
776
776
|
}
|
|
777
777
|
```
|
|
778
778
|
|
|
779
|
-
| 选项
|
|
780
|
-
|
|
|
781
|
-
| `disabled`
|
|
782
|
-
| `
|
|
783
|
-
| `planner_enabled`
|
|
784
|
-
| `
|
|
785
|
-
| `replace_plan` | `true` | 设为 `true` 就把默认计划 Agent 降级为子 Agent 模式。设为 `false` 可以同时保留 Planner-Sisyphus 和默认计划。 |
|
|
779
|
+
| 选项 | 默认值 | 说明 |
|
|
780
|
+
| --------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
781
|
+
| `disabled` | `false` | 设为 `true` 就禁用所有 Sisyphus 编排,恢复原来的 build/plan。 |
|
|
782
|
+
| `default_builder_enabled` | `false` | 设为 `true` 就启用 Builder-Sisyphus Agent(与 OpenCode build 相同,因 SDK 限制仅改名)。默认禁用。 |
|
|
783
|
+
| `planner_enabled` | `true` | 设为 `true` 就启用 Planner-Sisyphus Agent(与 OpenCode plan 相同,因 SDK 限制仅改名)。默认启用。 |
|
|
784
|
+
| `replace_plan` | `true` | 设为 `true` 就把默认计划 Agent 降级为子 Agent 模式。设为 `false` 可以同时保留 Planner-Sisyphus 和默认计划。 |
|
|
786
785
|
|
|
787
786
|
### Hooks
|
|
788
787
|
|
package/dist/cli/index.js
CHANGED
|
@@ -2244,7 +2244,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
2244
2244
|
var require_package = __commonJS((exports, module) => {
|
|
2245
2245
|
module.exports = {
|
|
2246
2246
|
name: "oh-my-opencode",
|
|
2247
|
-
version: "2.5.
|
|
2247
|
+
version: "2.5.3",
|
|
2248
2248
|
description: "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
|
|
2249
2249
|
main: "dist/index.js",
|
|
2250
2250
|
types: "dist/index.d.ts",
|
|
@@ -5152,7 +5152,7 @@ async function createOpencode(options) {
|
|
|
5152
5152
|
}
|
|
5153
5153
|
|
|
5154
5154
|
// src/cli/run/runner.ts
|
|
5155
|
-
var
|
|
5155
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
5156
5156
|
|
|
5157
5157
|
// src/cli/run/completion.ts
|
|
5158
5158
|
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
@@ -5165,7 +5165,8 @@ async function checkCompletionConditions(ctx) {
|
|
|
5165
5165
|
return false;
|
|
5166
5166
|
}
|
|
5167
5167
|
return true;
|
|
5168
|
-
} catch {
|
|
5168
|
+
} catch (err) {
|
|
5169
|
+
console.error(import_picocolors3.default.red(`[completion] API error: ${err}`));
|
|
5169
5170
|
return false;
|
|
5170
5171
|
}
|
|
5171
5172
|
}
|
|
@@ -5207,10 +5208,15 @@ async function areAllDescendantsIdle(ctx, sessionID, allStatuses) {
|
|
|
5207
5208
|
}
|
|
5208
5209
|
|
|
5209
5210
|
// src/cli/run/events.ts
|
|
5211
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
5210
5212
|
function createEventState() {
|
|
5211
5213
|
return {
|
|
5212
5214
|
mainSessionIdle: false,
|
|
5213
|
-
|
|
5215
|
+
mainSessionError: false,
|
|
5216
|
+
lastError: null,
|
|
5217
|
+
lastOutput: "",
|
|
5218
|
+
lastPartText: "",
|
|
5219
|
+
currentTool: null
|
|
5214
5220
|
};
|
|
5215
5221
|
}
|
|
5216
5222
|
async function processEvents(ctx, stream, state) {
|
|
@@ -5218,13 +5224,76 @@ async function processEvents(ctx, stream, state) {
|
|
|
5218
5224
|
if (ctx.abortController.signal.aborted)
|
|
5219
5225
|
break;
|
|
5220
5226
|
try {
|
|
5221
|
-
const payload = event
|
|
5222
|
-
if (!payload)
|
|
5227
|
+
const payload = event;
|
|
5228
|
+
if (!payload?.type) {
|
|
5229
|
+
console.error(import_picocolors4.default.dim(`[event] no type: ${JSON.stringify(event)}`));
|
|
5223
5230
|
continue;
|
|
5231
|
+
}
|
|
5232
|
+
logEventVerbose(ctx, payload);
|
|
5233
|
+
handleSessionError(ctx, payload, state);
|
|
5224
5234
|
handleSessionIdle(ctx, payload, state);
|
|
5225
5235
|
handleSessionStatus(ctx, payload, state);
|
|
5236
|
+
handleMessagePartUpdated(ctx, payload, state);
|
|
5226
5237
|
handleMessageUpdated(ctx, payload, state);
|
|
5227
|
-
|
|
5238
|
+
handleToolExecute(ctx, payload, state);
|
|
5239
|
+
handleToolResult(ctx, payload, state);
|
|
5240
|
+
} catch (err) {
|
|
5241
|
+
console.error(import_picocolors4.default.red(`[event error] ${err}`));
|
|
5242
|
+
}
|
|
5243
|
+
}
|
|
5244
|
+
}
|
|
5245
|
+
function logEventVerbose(ctx, payload) {
|
|
5246
|
+
const props = payload.properties;
|
|
5247
|
+
const info = props?.info;
|
|
5248
|
+
const sessionID = props?.sessionID ?? info?.sessionID;
|
|
5249
|
+
const isMainSession = sessionID === ctx.sessionID;
|
|
5250
|
+
const sessionTag = isMainSession ? import_picocolors4.default.green("[MAIN]") : import_picocolors4.default.yellow(`[${String(sessionID).slice(0, 8)}]`);
|
|
5251
|
+
switch (payload.type) {
|
|
5252
|
+
case "session.idle":
|
|
5253
|
+
case "session.status": {
|
|
5254
|
+
const status = props?.status?.type ?? "idle";
|
|
5255
|
+
console.error(import_picocolors4.default.dim(`${sessionTag} ${payload.type}: ${status}`));
|
|
5256
|
+
break;
|
|
5257
|
+
}
|
|
5258
|
+
case "message.part.updated": {
|
|
5259
|
+
const partProps = props;
|
|
5260
|
+
const role = partProps?.info?.role ?? "unknown";
|
|
5261
|
+
const part = partProps?.part;
|
|
5262
|
+
if (part?.type === "text" && part.text) {
|
|
5263
|
+
const preview = part.text.slice(0, 100).replace(/\n/g, "\\n");
|
|
5264
|
+
console.error(import_picocolors4.default.dim(`${sessionTag} message.part (${role}): "${preview}${part.text.length > 100 ? "..." : ""}"`));
|
|
5265
|
+
} else if (part?.type === "tool-invocation") {
|
|
5266
|
+
const toolPart = part;
|
|
5267
|
+
console.error(import_picocolors4.default.dim(`${sessionTag} message.part (tool): ${toolPart.toolName} [${toolPart.state}]`));
|
|
5268
|
+
}
|
|
5269
|
+
break;
|
|
5270
|
+
}
|
|
5271
|
+
case "message.updated": {
|
|
5272
|
+
const msgProps = props;
|
|
5273
|
+
const role = msgProps?.info?.role ?? "unknown";
|
|
5274
|
+
const content = msgProps?.content ?? "";
|
|
5275
|
+
const preview = content.slice(0, 100).replace(/\n/g, "\\n");
|
|
5276
|
+
console.error(import_picocolors4.default.dim(`${sessionTag} message.updated (${role}): "${preview}${content.length > 100 ? "..." : ""}"`));
|
|
5277
|
+
break;
|
|
5278
|
+
}
|
|
5279
|
+
case "tool.execute": {
|
|
5280
|
+
const toolProps = props;
|
|
5281
|
+
const toolName = toolProps?.name ?? "unknown";
|
|
5282
|
+
const input = toolProps?.input ?? {};
|
|
5283
|
+
const inputStr = JSON.stringify(input).slice(0, 150);
|
|
5284
|
+
console.error(import_picocolors4.default.cyan(`${sessionTag} \u26A1 TOOL.EXECUTE: ${import_picocolors4.default.bold(toolName)}`));
|
|
5285
|
+
console.error(import_picocolors4.default.dim(` input: ${inputStr}${inputStr.length >= 150 ? "..." : ""}`));
|
|
5286
|
+
break;
|
|
5287
|
+
}
|
|
5288
|
+
case "tool.result": {
|
|
5289
|
+
const resultProps = props;
|
|
5290
|
+
const output = resultProps?.output ?? "";
|
|
5291
|
+
const preview = output.slice(0, 200).replace(/\n/g, "\\n");
|
|
5292
|
+
console.error(import_picocolors4.default.green(`${sessionTag} \u2713 TOOL.RESULT: "${preview}${output.length > 200 ? "..." : ""}"`));
|
|
5293
|
+
break;
|
|
5294
|
+
}
|
|
5295
|
+
default:
|
|
5296
|
+
console.error(import_picocolors4.default.dim(`${sessionTag} ${payload.type}`));
|
|
5228
5297
|
}
|
|
5229
5298
|
}
|
|
5230
5299
|
function handleSessionIdle(ctx, payload, state) {
|
|
@@ -5243,6 +5312,36 @@ function handleSessionStatus(ctx, payload, state) {
|
|
|
5243
5312
|
state.mainSessionIdle = false;
|
|
5244
5313
|
}
|
|
5245
5314
|
}
|
|
5315
|
+
function handleSessionError(ctx, payload, state) {
|
|
5316
|
+
if (payload.type !== "session.error")
|
|
5317
|
+
return;
|
|
5318
|
+
const props = payload.properties;
|
|
5319
|
+
if (props?.sessionID === ctx.sessionID) {
|
|
5320
|
+
state.mainSessionError = true;
|
|
5321
|
+
state.lastError = props?.error ? String(props.error instanceof Error ? props.error.message : props.error) : "Unknown error";
|
|
5322
|
+
console.error(import_picocolors4.default.red(`
|
|
5323
|
+
[session.error] ${state.lastError}`));
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
function handleMessagePartUpdated(ctx, payload, state) {
|
|
5327
|
+
if (payload.type !== "message.part.updated")
|
|
5328
|
+
return;
|
|
5329
|
+
const props = payload.properties;
|
|
5330
|
+
if (props?.info?.sessionID !== ctx.sessionID)
|
|
5331
|
+
return;
|
|
5332
|
+
if (props?.info?.role !== "assistant")
|
|
5333
|
+
return;
|
|
5334
|
+
const part = props.part;
|
|
5335
|
+
if (!part)
|
|
5336
|
+
return;
|
|
5337
|
+
if (part.type === "text" && part.text) {
|
|
5338
|
+
const newText = part.text.slice(state.lastPartText.length);
|
|
5339
|
+
if (newText) {
|
|
5340
|
+
process.stdout.write(newText);
|
|
5341
|
+
}
|
|
5342
|
+
state.lastPartText = part.text;
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5246
5345
|
function handleMessageUpdated(ctx, payload, state) {
|
|
5247
5346
|
if (payload.type !== "message.updated")
|
|
5248
5347
|
return;
|
|
@@ -5254,16 +5353,62 @@ function handleMessageUpdated(ctx, payload, state) {
|
|
|
5254
5353
|
const content = props.content;
|
|
5255
5354
|
if (!content || content === state.lastOutput)
|
|
5256
5355
|
return;
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5356
|
+
if (state.lastPartText.length === 0) {
|
|
5357
|
+
const newContent = content.slice(state.lastOutput.length);
|
|
5358
|
+
if (newContent) {
|
|
5359
|
+
process.stdout.write(newContent);
|
|
5360
|
+
}
|
|
5260
5361
|
}
|
|
5261
5362
|
state.lastOutput = content;
|
|
5262
5363
|
}
|
|
5364
|
+
function handleToolExecute(ctx, payload, state) {
|
|
5365
|
+
if (payload.type !== "tool.execute")
|
|
5366
|
+
return;
|
|
5367
|
+
const props = payload.properties;
|
|
5368
|
+
if (props?.sessionID !== ctx.sessionID)
|
|
5369
|
+
return;
|
|
5370
|
+
const toolName = props?.name || "unknown";
|
|
5371
|
+
state.currentTool = toolName;
|
|
5372
|
+
let inputPreview = "";
|
|
5373
|
+
if (props?.input) {
|
|
5374
|
+
const input = props.input;
|
|
5375
|
+
if (input.command) {
|
|
5376
|
+
inputPreview = ` ${import_picocolors4.default.dim(String(input.command).slice(0, 60))}`;
|
|
5377
|
+
} else if (input.pattern) {
|
|
5378
|
+
inputPreview = ` ${import_picocolors4.default.dim(String(input.pattern).slice(0, 40))}`;
|
|
5379
|
+
} else if (input.filePath) {
|
|
5380
|
+
inputPreview = ` ${import_picocolors4.default.dim(String(input.filePath))}`;
|
|
5381
|
+
} else if (input.query) {
|
|
5382
|
+
inputPreview = ` ${import_picocolors4.default.dim(String(input.query).slice(0, 40))}`;
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
process.stdout.write(`
|
|
5386
|
+
${import_picocolors4.default.cyan("\u26A1")} ${import_picocolors4.default.bold(toolName)}${inputPreview}
|
|
5387
|
+
`);
|
|
5388
|
+
}
|
|
5389
|
+
function handleToolResult(ctx, payload, state) {
|
|
5390
|
+
if (payload.type !== "tool.result")
|
|
5391
|
+
return;
|
|
5392
|
+
const props = payload.properties;
|
|
5393
|
+
if (props?.sessionID !== ctx.sessionID)
|
|
5394
|
+
return;
|
|
5395
|
+
const output = props?.output || "";
|
|
5396
|
+
const maxLen = 200;
|
|
5397
|
+
const preview = output.length > maxLen ? output.slice(0, maxLen) + "..." : output;
|
|
5398
|
+
if (preview.trim()) {
|
|
5399
|
+
const lines = preview.split(`
|
|
5400
|
+
`).slice(0, 3);
|
|
5401
|
+
process.stdout.write(import_picocolors4.default.dim(` \u2514\u2500 ${lines.join(`
|
|
5402
|
+
`)}
|
|
5403
|
+
`));
|
|
5404
|
+
}
|
|
5405
|
+
state.currentTool = null;
|
|
5406
|
+
state.lastPartText = "";
|
|
5407
|
+
}
|
|
5263
5408
|
|
|
5264
5409
|
// src/cli/run/runner.ts
|
|
5265
5410
|
var POLL_INTERVAL_MS = 500;
|
|
5266
|
-
var DEFAULT_TIMEOUT_MS =
|
|
5411
|
+
var DEFAULT_TIMEOUT_MS = 0;
|
|
5267
5412
|
async function run(options) {
|
|
5268
5413
|
const {
|
|
5269
5414
|
message,
|
|
@@ -5271,23 +5416,27 @@ async function run(options) {
|
|
|
5271
5416
|
directory = process.cwd(),
|
|
5272
5417
|
timeout = DEFAULT_TIMEOUT_MS
|
|
5273
5418
|
} = options;
|
|
5274
|
-
console.log(
|
|
5419
|
+
console.log(import_picocolors5.default.cyan("Starting opencode server..."));
|
|
5275
5420
|
const abortController = new AbortController;
|
|
5276
|
-
|
|
5277
|
-
|
|
5421
|
+
let timeoutId = null;
|
|
5422
|
+
if (timeout > 0) {
|
|
5423
|
+
timeoutId = setTimeout(() => {
|
|
5424
|
+
console.log(import_picocolors5.default.yellow(`
|
|
5278
5425
|
Timeout reached. Aborting...`));
|
|
5279
|
-
|
|
5280
|
-
|
|
5426
|
+
abortController.abort();
|
|
5427
|
+
}, timeout);
|
|
5428
|
+
}
|
|
5281
5429
|
try {
|
|
5282
5430
|
const { client: client3, server: server2 } = await createOpencode({
|
|
5283
5431
|
signal: abortController.signal
|
|
5284
5432
|
});
|
|
5285
5433
|
const cleanup = () => {
|
|
5286
|
-
|
|
5434
|
+
if (timeoutId)
|
|
5435
|
+
clearTimeout(timeoutId);
|
|
5287
5436
|
server2.close();
|
|
5288
5437
|
};
|
|
5289
5438
|
process.on("SIGINT", () => {
|
|
5290
|
-
console.log(
|
|
5439
|
+
console.log(import_picocolors5.default.yellow(`
|
|
5291
5440
|
Interrupted. Shutting down...`));
|
|
5292
5441
|
cleanup();
|
|
5293
5442
|
process.exit(130);
|
|
@@ -5298,10 +5447,10 @@ Interrupted. Shutting down...`));
|
|
|
5298
5447
|
});
|
|
5299
5448
|
const sessionID = sessionRes.data?.id;
|
|
5300
5449
|
if (!sessionID) {
|
|
5301
|
-
console.error(
|
|
5450
|
+
console.error(import_picocolors5.default.red("Failed to create session"));
|
|
5302
5451
|
return 1;
|
|
5303
5452
|
}
|
|
5304
|
-
console.log(
|
|
5453
|
+
console.log(import_picocolors5.default.dim(`Session: ${sessionID}`));
|
|
5305
5454
|
const ctx = {
|
|
5306
5455
|
client: client3,
|
|
5307
5456
|
sessionID,
|
|
@@ -5311,7 +5460,7 @@ Interrupted. Shutting down...`));
|
|
|
5311
5460
|
const events = await client3.event.subscribe();
|
|
5312
5461
|
const eventState = createEventState();
|
|
5313
5462
|
const eventProcessor = processEvents(ctx, events.stream, eventState);
|
|
5314
|
-
console.log(
|
|
5463
|
+
console.log(import_picocolors5.default.dim(`
|
|
5315
5464
|
Sending prompt...`));
|
|
5316
5465
|
await client3.session.promptAsync({
|
|
5317
5466
|
path: { id: sessionID },
|
|
@@ -5321,16 +5470,26 @@ Sending prompt...`));
|
|
|
5321
5470
|
},
|
|
5322
5471
|
query: { directory }
|
|
5323
5472
|
});
|
|
5324
|
-
console.log(
|
|
5473
|
+
console.log(import_picocolors5.default.dim(`Waiting for completion...
|
|
5325
5474
|
`));
|
|
5326
5475
|
while (!abortController.signal.aborted) {
|
|
5327
5476
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
|
|
5328
5477
|
if (!eventState.mainSessionIdle) {
|
|
5329
5478
|
continue;
|
|
5330
5479
|
}
|
|
5480
|
+
if (eventState.mainSessionError) {
|
|
5481
|
+
console.error(import_picocolors5.default.red(`
|
|
5482
|
+
|
|
5483
|
+
Session ended with error: ${eventState.lastError}`));
|
|
5484
|
+
console.error(import_picocolors5.default.yellow("Check if todos were completed before the error."));
|
|
5485
|
+
abortController.abort();
|
|
5486
|
+
await eventProcessor.catch(() => {});
|
|
5487
|
+
cleanup();
|
|
5488
|
+
return 1;
|
|
5489
|
+
}
|
|
5331
5490
|
const shouldExit = await checkCompletionConditions(ctx);
|
|
5332
5491
|
if (shouldExit) {
|
|
5333
|
-
console.log(
|
|
5492
|
+
console.log(import_picocolors5.default.green(`
|
|
5334
5493
|
|
|
5335
5494
|
All tasks completed.`));
|
|
5336
5495
|
abortController.abort();
|
|
@@ -5347,11 +5506,12 @@ All tasks completed.`));
|
|
|
5347
5506
|
throw err;
|
|
5348
5507
|
}
|
|
5349
5508
|
} catch (err) {
|
|
5350
|
-
|
|
5509
|
+
if (timeoutId)
|
|
5510
|
+
clearTimeout(timeoutId);
|
|
5351
5511
|
if (err instanceof Error && err.name === "AbortError") {
|
|
5352
5512
|
return 130;
|
|
5353
5513
|
}
|
|
5354
|
-
console.error(
|
|
5514
|
+
console.error(import_picocolors5.default.red(`Error: ${err}`));
|
|
5355
5515
|
return 1;
|
|
5356
5516
|
}
|
|
5357
5517
|
}
|
package/dist/cli/run/events.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { RunContext } from "./types";
|
|
2
2
|
export interface EventState {
|
|
3
3
|
mainSessionIdle: boolean;
|
|
4
|
+
mainSessionError: boolean;
|
|
5
|
+
lastError: string | null;
|
|
4
6
|
lastOutput: string;
|
|
7
|
+
lastPartText: string;
|
|
8
|
+
currentTool: string | null;
|
|
5
9
|
}
|
|
6
10
|
export declare function createEventState(): EventState;
|
|
7
11
|
export declare function processEvents(ctx: RunContext, stream: AsyncIterable<unknown>, state: EventState): Promise<void>;
|
package/dist/cli/run/types.d.ts
CHANGED
|
@@ -43,3 +43,29 @@ export interface MessageUpdatedProps {
|
|
|
43
43
|
};
|
|
44
44
|
content?: string;
|
|
45
45
|
}
|
|
46
|
+
export interface MessagePartUpdatedProps {
|
|
47
|
+
info?: {
|
|
48
|
+
sessionID?: string;
|
|
49
|
+
role?: string;
|
|
50
|
+
};
|
|
51
|
+
part?: {
|
|
52
|
+
type?: string;
|
|
53
|
+
text?: string;
|
|
54
|
+
name?: string;
|
|
55
|
+
input?: unknown;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export interface ToolExecuteProps {
|
|
59
|
+
sessionID?: string;
|
|
60
|
+
name?: string;
|
|
61
|
+
input?: Record<string, unknown>;
|
|
62
|
+
}
|
|
63
|
+
export interface ToolResultProps {
|
|
64
|
+
sessionID?: string;
|
|
65
|
+
name?: string;
|
|
66
|
+
output?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface SessionErrorProps {
|
|
69
|
+
sessionID?: string;
|
|
70
|
+
error?: unknown;
|
|
71
|
+
}
|