oh-my-opencode 2.8.0 → 2.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +12 -10
- package/README.ko.md +12 -10
- package/README.md +8 -6
- package/README.zh-cn.md +12 -10
- package/dist/cli/config-manager.d.ts +6 -0
- package/dist/cli/index.js +194 -39
- package/dist/config/schema.d.ts +4 -4
- package/dist/hooks/comment-checker/downloader.d.ts +2 -1
- package/dist/index.js +23 -14
- package/package.json +2 -2
package/README.ja.md
CHANGED
|
@@ -874,7 +874,7 @@ Oh My OpenCode は以下の場所からフックを読み込んで実行しま
|
|
|
874
874
|
}
|
|
875
875
|
```
|
|
876
876
|
|
|
877
|
-
利用可能なフック:`todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `
|
|
877
|
+
利用可能なフック:`todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`
|
|
878
878
|
|
|
879
879
|
**`auto-update-checker`と`startup-toast`について**: `startup-toast` フックは `auto-update-checker` のサブ機能です。アップデートチェックは有効なまま起動トースト通知のみを無効化するには、`disabled_hooks` に `"startup-toast"` を追加してください。すべてのアップデートチェック機能(トーストを含む)を無効化するには、`"auto-update-checker"` を追加してください。
|
|
880
880
|
|
|
@@ -926,20 +926,22 @@ OpenCode でサポートされるすべての LSP 構成およびカスタム設
|
|
|
926
926
|
```json
|
|
927
927
|
{
|
|
928
928
|
"experimental": {
|
|
929
|
+
"preemptive_compaction": true,
|
|
930
|
+
"truncate_all_tool_outputs": true,
|
|
929
931
|
"aggressive_truncation": true,
|
|
930
|
-
"auto_resume": true
|
|
931
|
-
"truncate_all_tool_outputs": false
|
|
932
|
+
"auto_resume": true
|
|
932
933
|
}
|
|
933
934
|
}
|
|
934
935
|
```
|
|
935
936
|
|
|
936
|
-
| オプション
|
|
937
|
-
|
|
|
938
|
-
| `
|
|
939
|
-
| `
|
|
940
|
-
| `truncate_all_tool_outputs`
|
|
941
|
-
|
|
942
|
-
|
|
937
|
+
| オプション | デフォルト | 説明 |
|
|
938
|
+
| --------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
939
|
+
| `preemptive_compaction` | `false` | トークン制限に達する前にセッションを事前にコンパクションします。デフォルトでコンテキストウィンドウ使用率80%で実行されます。 |
|
|
940
|
+
| `preemptive_compaction_threshold` | `0.80` | プリエンプティブコンパクションをトリガーする閾値(0.5-0.95)。`preemptive_compaction`が有効な場合のみ適用されます。 |
|
|
941
|
+
| `truncate_all_tool_outputs` | `false` | ホワイトリストのツール(Grep、Glob、LSP、AST-grep)だけでなく、すべてのツール出力を切り詰めます。Tool output truncator はデフォルトで有効です - `disabled_hooks`で無効化できます。 |
|
|
942
|
+
| `aggressive_truncation` | `false` | トークン制限を超えた場合、ツール出力を積極的に切り詰めて制限内に収めます。デフォルトの切り詰めより積極的です。不十分な場合は要約/復元にフォールバックします。 |
|
|
943
|
+
| `auto_resume` | `false` | thinking block エラーや thinking disabled violation からの回復成功後、自動的にセッションを再開します。最後のユーザーメッセージを抽出して続行します。 |
|
|
944
|
+
| `dcp_for_compaction` | `false` | コンパクション用DCP(動的コンテキスト整理)を有効化 - トークン制限超過時に最初に実行されます。コンパクション前に重複したツール呼び出しと古いツール出力を整理します。 |
|
|
943
945
|
|
|
944
946
|
**警告**:これらの機能は実験的であり、予期しない動作を引き起こす可能性があります。影響を理解した場合にのみ有効にしてください。
|
|
945
947
|
|
package/README.ko.md
CHANGED
|
@@ -871,7 +871,7 @@ Schema 자동 완성이 지원됩니다:
|
|
|
871
871
|
}
|
|
872
872
|
```
|
|
873
873
|
|
|
874
|
-
사용 가능한 훅: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `
|
|
874
|
+
사용 가능한 훅: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`
|
|
875
875
|
|
|
876
876
|
**`auto-update-checker`와 `startup-toast`에 대한 참고사항**: `startup-toast` 훅은 `auto-update-checker`의 하위 기능입니다. 업데이트 확인은 유지하면서 시작 토스트 알림만 비활성화하려면 `disabled_hooks`에 `"startup-toast"`를 추가하세요. 모든 업데이트 확인 기능(토스트 포함)을 비활성화하려면 `"auto-update-checker"`를 추가하세요.
|
|
877
877
|
|
|
@@ -923,20 +923,22 @@ OpenCode 에서 지원하는 모든 LSP 구성 및 커스텀 설정 (opencode.js
|
|
|
923
923
|
```json
|
|
924
924
|
{
|
|
925
925
|
"experimental": {
|
|
926
|
+
"preemptive_compaction": true,
|
|
927
|
+
"truncate_all_tool_outputs": true,
|
|
926
928
|
"aggressive_truncation": true,
|
|
927
|
-
"auto_resume": true
|
|
928
|
-
"truncate_all_tool_outputs": false
|
|
929
|
+
"auto_resume": true
|
|
929
930
|
}
|
|
930
931
|
}
|
|
931
932
|
```
|
|
932
933
|
|
|
933
|
-
| 옵션
|
|
934
|
-
|
|
|
935
|
-
| `
|
|
936
|
-
| `
|
|
937
|
-
| `truncate_all_tool_outputs`
|
|
938
|
-
|
|
939
|
-
|
|
934
|
+
| 옵션 | 기본값 | 설명 |
|
|
935
|
+
| --------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
936
|
+
| `preemptive_compaction` | `false` | 토큰 제한에 도달하기 전에 세션을 미리 컴팩션합니다. 기본적으로 컨텍스트 윈도우 사용량이 80%일 때 실행됩니다. |
|
|
937
|
+
| `preemptive_compaction_threshold` | `0.80` | 선제적 컴팩션을 트리거할 임계값 비율(0.5-0.95). `preemptive_compaction`이 활성화된 경우에만 적용됩니다. |
|
|
938
|
+
| `truncate_all_tool_outputs` | `false` | 화이트리스트 도구(Grep, Glob, LSP, AST-grep)만이 아닌 모든 도구 출력을 잘라냅니다. Tool output truncator는 기본적으로 활성화됩니다 - `disabled_hooks`로 비활성화 가능합니다. |
|
|
939
|
+
| `aggressive_truncation` | `false` | 토큰 제한을 초과하면 도구 출력을 공격적으로 잘라내어 제한 내에 맞춥니다. 기본 truncation보다 더 공격적입니다. 부족하면 요약/복구로 fallback합니다. |
|
|
940
|
+
| `auto_resume` | `false` | thinking block 에러나 thinking disabled violation으로부터 성공적으로 복구한 후 자동으로 세션을 재개합니다. 마지막 사용자 메시지를 추출하여 계속합니다. |
|
|
941
|
+
| `dcp_for_compaction` | `false` | 컴팩션용 DCP(동적 컨텍스트 정리) 활성화 - 토큰 제한 초과 시 먼저 실행됩니다. 컴팩션 전에 중복 도구 호출과 오래된 도구 출력을 정리합니다. |
|
|
940
942
|
|
|
941
943
|
**경고**: 이 기능들은 실험적이며 예상치 못한 동작을 유발할 수 있습니다. 의미를 이해한 경우에만 활성화하세요.
|
|
942
944
|
|
package/README.md
CHANGED
|
@@ -910,7 +910,7 @@ Disable specific built-in hooks via `disabled_hooks` in `~/.config/opencode/oh-m
|
|
|
910
910
|
}
|
|
911
911
|
```
|
|
912
912
|
|
|
913
|
-
Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `
|
|
913
|
+
Available hooks: `todo-continuation-enforcer`, `context-window-monitor`, `session-recovery`, `session-notification`, `comment-checker`, `grep-output-truncator`, `tool-output-truncator`, `directory-agents-injector`, `directory-readme-injector`, `empty-task-response-detector`, `think-mode`, `anthropic-context-window-limit-recovery`, `rules-injector`, `background-notification`, `auto-update-checker`, `startup-toast`, `keyword-detector`, `agent-usage-reminder`, `non-interactive-env`, `interactive-bash-session`, `empty-message-sanitizer`, `compaction-context-injector`, `thinking-block-validator`, `claude-code-hooks`, `ralph-loop`
|
|
914
914
|
|
|
915
915
|
**Note on `auto-update-checker` and `startup-toast`**: The `startup-toast` hook is a sub-feature of `auto-update-checker`. To disable only the startup toast notification while keeping update checking enabled, add `"startup-toast"` to `disabled_hooks`. To disable all update checking features (including the toast), add `"auto-update-checker"` to `disabled_hooks`.
|
|
916
916
|
|
|
@@ -962,20 +962,22 @@ Opt-in experimental features that may change or be removed in future versions. U
|
|
|
962
962
|
```json
|
|
963
963
|
{
|
|
964
964
|
"experimental": {
|
|
965
|
+
"preemptive_compaction": true,
|
|
966
|
+
"truncate_all_tool_outputs": true,
|
|
965
967
|
"aggressive_truncation": true,
|
|
966
|
-
"auto_resume": true
|
|
967
|
-
"truncate_all_tool_outputs": false
|
|
968
|
+
"auto_resume": true
|
|
968
969
|
}
|
|
969
970
|
}
|
|
970
971
|
```
|
|
971
972
|
|
|
972
973
|
| Option | Default | Description |
|
|
973
974
|
| --------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
975
|
+
| `preemptive_compaction` | `false` | Compacts session proactively before hitting hard token limits. Runs at 80% context window usage by default. |
|
|
976
|
+
| `preemptive_compaction_threshold` | `0.80` | Threshold percentage (0.5-0.95) to trigger preemptive compaction. Only applies when `preemptive_compaction` is enabled. |
|
|
977
|
+
| `truncate_all_tool_outputs` | `false` | Truncates ALL tool outputs instead of just whitelisted tools (Grep, Glob, LSP, AST-grep). Tool output truncator is enabled by default - disable via `disabled_hooks`. |
|
|
974
978
|
| `aggressive_truncation` | `false` | When token limit is exceeded, aggressively truncates tool outputs to fit within limits. More aggressive than the default truncation behavior. Falls back to summarize/revert if insufficient. |
|
|
975
979
|
| `auto_resume` | `false` | Automatically resumes session after successful recovery from thinking block errors or thinking disabled violations. Extracts the last user message and continues. |
|
|
976
|
-
| `
|
|
977
|
-
|
|
978
|
-
**Note**: `dcp-for-compaction` (Dynamic Context Pruning for compaction) is now a hook, not an experimental feature. It's enabled by default and can be disabled via `disabled_hooks: ["dcp-for-compaction"]`.
|
|
980
|
+
| `dcp_for_compaction` | `false` | Enable DCP (Dynamic Context Pruning) for compaction - runs first when token limit exceeded. Prunes duplicate tool calls and old tool outputs before running compaction. |
|
|
979
981
|
|
|
980
982
|
**Warning**: These features are experimental and may cause unexpected behavior. Enable only if you understand the implications.
|
|
981
983
|
|
package/README.zh-cn.md
CHANGED
|
@@ -878,7 +878,7 @@ Sisyphus Agent 也能自定义:
|
|
|
878
878
|
}
|
|
879
879
|
```
|
|
880
880
|
|
|
881
|
-
可关的 hook:`todo-continuation-enforcer`、`context-window-monitor`、`session-recovery`、`session-notification`、`comment-checker`、`grep-output-truncator`、`tool-output-truncator`、`directory-agents-injector`、`directory-readme-injector`、`empty-task-response-detector`、`think-mode`、`anthropic-context-window-limit-recovery`、`rules-injector`、`background-notification`、`auto-update-checker`、`startup-toast`、`keyword-detector`、`agent-usage-reminder`、`non-interactive-env`、`interactive-bash-session`、`empty-message-sanitizer`、`
|
|
881
|
+
可关的 hook:`todo-continuation-enforcer`、`context-window-monitor`、`session-recovery`、`session-notification`、`comment-checker`、`grep-output-truncator`、`tool-output-truncator`、`directory-agents-injector`、`directory-readme-injector`、`empty-task-response-detector`、`think-mode`、`anthropic-context-window-limit-recovery`、`rules-injector`、`background-notification`、`auto-update-checker`、`startup-toast`、`keyword-detector`、`agent-usage-reminder`、`non-interactive-env`、`interactive-bash-session`、`empty-message-sanitizer`、`compaction-context-injector`、`thinking-block-validator`、`claude-code-hooks`、`ralph-loop`
|
|
882
882
|
|
|
883
883
|
**关于 `auto-update-checker` 和 `startup-toast`**: `startup-toast` hook 是 `auto-update-checker` 的子功能。若想保持更新检查但只禁用启动提示通知,在 `disabled_hooks` 中添加 `"startup-toast"`。若要禁用所有更新检查功能(包括提示),添加 `"auto-update-checker"`。
|
|
884
884
|
|
|
@@ -930,20 +930,22 @@ Oh My OpenCode 送你重构工具(重命名、代码操作)。
|
|
|
930
930
|
```json
|
|
931
931
|
{
|
|
932
932
|
"experimental": {
|
|
933
|
+
"preemptive_compaction": true,
|
|
934
|
+
"truncate_all_tool_outputs": true,
|
|
933
935
|
"aggressive_truncation": true,
|
|
934
|
-
"auto_resume": true
|
|
935
|
-
"truncate_all_tool_outputs": false
|
|
936
|
+
"auto_resume": true
|
|
936
937
|
}
|
|
937
938
|
}
|
|
938
939
|
```
|
|
939
940
|
|
|
940
|
-
| 选项
|
|
941
|
-
|
|
|
942
|
-
| `
|
|
943
|
-
| `
|
|
944
|
-
| `truncate_all_tool_outputs`
|
|
945
|
-
|
|
946
|
-
|
|
941
|
+
| 选项 | 默认值 | 说明 |
|
|
942
|
+
| --------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
943
|
+
| `preemptive_compaction` | `false` | 在达到 token 限制之前主动压缩会话。默认在上下文窗口使用率达到 80% 时运行。 |
|
|
944
|
+
| `preemptive_compaction_threshold` | `0.80` | 触发预先压缩的阈值比例(0.5-0.95)。仅在 `preemptive_compaction` 启用时生效。 |
|
|
945
|
+
| `truncate_all_tool_outputs` | `false` | 截断所有工具输出,而不仅仅是白名单工具(Grep、Glob、LSP、AST-grep)。Tool output truncator 默认启用 - 使用 `disabled_hooks` 禁用。 |
|
|
946
|
+
| `aggressive_truncation` | `false` | 超出 token 限制时,激进地截断工具输出以适应限制。比默认截断更激进。不够的话会回退到摘要/恢复。 |
|
|
947
|
+
| `auto_resume` | `false` | 从 thinking block 错误或 thinking disabled violation 成功恢复后,自动恢复会话。提取最后一条用户消息继续执行。 |
|
|
948
|
+
| `dcp_for_compaction` | `false` | 启用压缩用 DCP(动态上下文剪枝)- 在超出 token 限制时首先执行。在压缩前清理重复的工具调用和旧的工具输出。 |
|
|
947
949
|
|
|
948
950
|
**警告**:这些功能是实验性的,可能会导致意外行为。只有在理解其影响的情况下才启用。
|
|
949
951
|
|
|
@@ -12,7 +12,13 @@ export declare function isOpenCodeInstalled(): Promise<boolean>;
|
|
|
12
12
|
export declare function getOpenCodeVersion(): Promise<string | null>;
|
|
13
13
|
export declare function addAuthPlugins(config: InstallConfig): Promise<ConfigMergeResult>;
|
|
14
14
|
export declare function setupChatGPTHotfix(): ConfigMergeResult;
|
|
15
|
+
export interface BunInstallResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
timedOut?: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
15
20
|
export declare function runBunInstall(): Promise<boolean>;
|
|
21
|
+
export declare function runBunInstallWithDetails(): Promise<BunInstallResult>;
|
|
16
22
|
export declare const ANTIGRAVITY_PROVIDER_CONFIG: {
|
|
17
23
|
google: {
|
|
18
24
|
name: string;
|
package/dist/cli/index.js
CHANGED
|
@@ -2657,7 +2657,7 @@ var require_napi = __commonJS((exports, module) => {
|
|
|
2657
2657
|
var require_package = __commonJS((exports, module) => {
|
|
2658
2658
|
module.exports = {
|
|
2659
2659
|
name: "oh-my-opencode",
|
|
2660
|
-
version: "2.
|
|
2660
|
+
version: "2.8.1",
|
|
2661
2661
|
description: "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
|
|
2662
2662
|
main: "dist/index.js",
|
|
2663
2663
|
types: "dist/index.d.ts",
|
|
@@ -2680,7 +2680,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
2680
2680
|
"./schema.json": "./dist/oh-my-opencode.schema.json"
|
|
2681
2681
|
},
|
|
2682
2682
|
scripts: {
|
|
2683
|
-
build: "bun build src/index.ts src/google-auth.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && bun run build:schema",
|
|
2683
|
+
build: "bun build src/index.ts src/google-auth.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
2684
2684
|
"build:schema": "bun run script/build-schema.ts",
|
|
2685
2685
|
clean: "rm -rf dist",
|
|
2686
2686
|
prepublishOnly: "bun run clean && bun run build",
|
|
@@ -3335,7 +3335,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
3335
3335
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
3336
3336
|
|
|
3337
3337
|
// src/cli/config-manager.ts
|
|
3338
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
3338
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync, statSync } from "fs";
|
|
3339
3339
|
import { homedir } from "os";
|
|
3340
3340
|
import { join as join2 } from "path";
|
|
3341
3341
|
// src/shared/command-executor.ts
|
|
@@ -4233,6 +4233,35 @@ var OPENCODE_PACKAGE_JSON = join2(OPENCODE_CONFIG_DIR, "package.json");
|
|
|
4233
4233
|
var OMO_CONFIG = join2(OPENCODE_CONFIG_DIR, "oh-my-opencode.json");
|
|
4234
4234
|
var OPENCODE_BINARIES = ["opencode", "opencode-desktop"];
|
|
4235
4235
|
var CHATGPT_HOTFIX_REPO = "code-yeongyu/opencode-openai-codex-auth#fix/orphaned-function-call-output-with-tools";
|
|
4236
|
+
var BUN_INSTALL_TIMEOUT_SECONDS = 60;
|
|
4237
|
+
var BUN_INSTALL_TIMEOUT_MS = BUN_INSTALL_TIMEOUT_SECONDS * 1000;
|
|
4238
|
+
function isPermissionError(err) {
|
|
4239
|
+
const nodeErr = err;
|
|
4240
|
+
return nodeErr?.code === "EACCES" || nodeErr?.code === "EPERM";
|
|
4241
|
+
}
|
|
4242
|
+
function isFileNotFoundError(err) {
|
|
4243
|
+
const nodeErr = err;
|
|
4244
|
+
return nodeErr?.code === "ENOENT";
|
|
4245
|
+
}
|
|
4246
|
+
function formatErrorWithSuggestion(err, context) {
|
|
4247
|
+
if (isPermissionError(err)) {
|
|
4248
|
+
return `Permission denied: Cannot ${context}. Try running with elevated permissions or check file ownership.`;
|
|
4249
|
+
}
|
|
4250
|
+
if (isFileNotFoundError(err)) {
|
|
4251
|
+
return `File not found while trying to ${context}. The file may have been deleted or moved.`;
|
|
4252
|
+
}
|
|
4253
|
+
if (err instanceof SyntaxError) {
|
|
4254
|
+
return `JSON syntax error while trying to ${context}: ${err.message}. Check for missing commas, brackets, or invalid characters.`;
|
|
4255
|
+
}
|
|
4256
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4257
|
+
if (message.includes("ENOSPC")) {
|
|
4258
|
+
return `Disk full: Cannot ${context}. Free up disk space and try again.`;
|
|
4259
|
+
}
|
|
4260
|
+
if (message.includes("EROFS")) {
|
|
4261
|
+
return `Read-only filesystem: Cannot ${context}. Check if the filesystem is mounted read-only.`;
|
|
4262
|
+
}
|
|
4263
|
+
return `Failed to ${context}: ${message}`;
|
|
4264
|
+
}
|
|
4236
4265
|
async function fetchLatestVersion(packageName) {
|
|
4237
4266
|
try {
|
|
4238
4267
|
const res = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
|
|
@@ -4253,12 +4282,29 @@ function detectConfigFormat() {
|
|
|
4253
4282
|
}
|
|
4254
4283
|
return { format: "none", path: OPENCODE_JSON };
|
|
4255
4284
|
}
|
|
4256
|
-
function
|
|
4285
|
+
function isEmptyOrWhitespace(content) {
|
|
4286
|
+
return content.trim().length === 0;
|
|
4287
|
+
}
|
|
4288
|
+
function parseConfigWithError(path2) {
|
|
4257
4289
|
try {
|
|
4290
|
+
const stat = statSync(path2);
|
|
4291
|
+
if (stat.size === 0) {
|
|
4292
|
+
return { config: null, error: `Config file is empty: ${path2}. Delete it or add valid JSON content.` };
|
|
4293
|
+
}
|
|
4258
4294
|
const content = readFileSync2(path2, "utf-8");
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4295
|
+
if (isEmptyOrWhitespace(content)) {
|
|
4296
|
+
return { config: null, error: `Config file contains only whitespace: ${path2}. Delete it or add valid JSON content.` };
|
|
4297
|
+
}
|
|
4298
|
+
const config = parseJsonc(content);
|
|
4299
|
+
if (config === null || config === undefined) {
|
|
4300
|
+
return { config: null, error: `Config file parsed to null/undefined: ${path2}. Ensure it contains valid JSON.` };
|
|
4301
|
+
}
|
|
4302
|
+
if (typeof config !== "object" || Array.isArray(config)) {
|
|
4303
|
+
return { config: null, error: `Config file must contain a JSON object, not ${Array.isArray(config) ? "an array" : typeof config}: ${path2}` };
|
|
4304
|
+
}
|
|
4305
|
+
return { config };
|
|
4306
|
+
} catch (err) {
|
|
4307
|
+
return { config: null, error: formatErrorWithSuggestion(err, `parse config file ${path2}`) };
|
|
4262
4308
|
}
|
|
4263
4309
|
}
|
|
4264
4310
|
function ensureConfigDir() {
|
|
@@ -4267,7 +4313,11 @@ function ensureConfigDir() {
|
|
|
4267
4313
|
}
|
|
4268
4314
|
}
|
|
4269
4315
|
function addPluginToOpenCodeConfig() {
|
|
4270
|
-
|
|
4316
|
+
try {
|
|
4317
|
+
ensureConfigDir();
|
|
4318
|
+
} catch (err) {
|
|
4319
|
+
return { success: false, configPath: OPENCODE_CONFIG_DIR, error: formatErrorWithSuggestion(err, "create config directory") };
|
|
4320
|
+
}
|
|
4271
4321
|
const { format: format2, path: path2 } = detectConfigFormat();
|
|
4272
4322
|
const pluginName = "oh-my-opencode";
|
|
4273
4323
|
try {
|
|
@@ -4277,10 +4327,11 @@ function addPluginToOpenCodeConfig() {
|
|
|
4277
4327
|
`);
|
|
4278
4328
|
return { success: true, configPath: path2 };
|
|
4279
4329
|
}
|
|
4280
|
-
const
|
|
4281
|
-
if (!config) {
|
|
4282
|
-
return { success: false, configPath: path2, error: "Failed to parse config" };
|
|
4330
|
+
const parseResult = parseConfigWithError(path2);
|
|
4331
|
+
if (!parseResult.config) {
|
|
4332
|
+
return { success: false, configPath: path2, error: parseResult.error ?? "Failed to parse config file" };
|
|
4283
4333
|
}
|
|
4334
|
+
const config = parseResult.config;
|
|
4284
4335
|
const plugins = config.plugin ?? [];
|
|
4285
4336
|
if (plugins.some((p2) => p2.startsWith(pluginName))) {
|
|
4286
4337
|
return { success: true, configPath: path2 };
|
|
@@ -4309,7 +4360,7 @@ function addPluginToOpenCodeConfig() {
|
|
|
4309
4360
|
}
|
|
4310
4361
|
return { success: true, configPath: path2 };
|
|
4311
4362
|
} catch (err) {
|
|
4312
|
-
return { success: false, configPath: path2, error:
|
|
4363
|
+
return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "update opencode config") };
|
|
4313
4364
|
}
|
|
4314
4365
|
}
|
|
4315
4366
|
function deepMerge(target, source) {
|
|
@@ -4366,23 +4417,47 @@ function generateOmoConfig(installConfig) {
|
|
|
4366
4417
|
return config;
|
|
4367
4418
|
}
|
|
4368
4419
|
function writeOmoConfig(installConfig) {
|
|
4369
|
-
|
|
4420
|
+
try {
|
|
4421
|
+
ensureConfigDir();
|
|
4422
|
+
} catch (err) {
|
|
4423
|
+
return { success: false, configPath: OPENCODE_CONFIG_DIR, error: formatErrorWithSuggestion(err, "create config directory") };
|
|
4424
|
+
}
|
|
4370
4425
|
try {
|
|
4371
4426
|
const newConfig = generateOmoConfig(installConfig);
|
|
4372
4427
|
if (existsSync2(OMO_CONFIG)) {
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4428
|
+
try {
|
|
4429
|
+
const stat = statSync(OMO_CONFIG);
|
|
4430
|
+
const content = readFileSync2(OMO_CONFIG, "utf-8");
|
|
4431
|
+
if (stat.size === 0 || isEmptyOrWhitespace(content)) {
|
|
4432
|
+
writeFileSync(OMO_CONFIG, JSON.stringify(newConfig, null, 2) + `
|
|
4433
|
+
`);
|
|
4434
|
+
return { success: true, configPath: OMO_CONFIG };
|
|
4435
|
+
}
|
|
4436
|
+
const existing = parseJsonc(content);
|
|
4437
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
4438
|
+
writeFileSync(OMO_CONFIG, JSON.stringify(newConfig, null, 2) + `
|
|
4439
|
+
`);
|
|
4440
|
+
return { success: true, configPath: OMO_CONFIG };
|
|
4441
|
+
}
|
|
4442
|
+
delete existing.agents;
|
|
4443
|
+
const merged = deepMerge(existing, newConfig);
|
|
4444
|
+
writeFileSync(OMO_CONFIG, JSON.stringify(merged, null, 2) + `
|
|
4445
|
+
`);
|
|
4446
|
+
} catch (parseErr) {
|
|
4447
|
+
if (parseErr instanceof SyntaxError) {
|
|
4448
|
+
writeFileSync(OMO_CONFIG, JSON.stringify(newConfig, null, 2) + `
|
|
4378
4449
|
`);
|
|
4450
|
+
return { success: true, configPath: OMO_CONFIG };
|
|
4451
|
+
}
|
|
4452
|
+
throw parseErr;
|
|
4453
|
+
}
|
|
4379
4454
|
} else {
|
|
4380
4455
|
writeFileSync(OMO_CONFIG, JSON.stringify(newConfig, null, 2) + `
|
|
4381
4456
|
`);
|
|
4382
4457
|
}
|
|
4383
4458
|
return { success: true, configPath: OMO_CONFIG };
|
|
4384
4459
|
} catch (err) {
|
|
4385
|
-
return { success: false, configPath: OMO_CONFIG, error:
|
|
4460
|
+
return { success: false, configPath: OMO_CONFIG, error: formatErrorWithSuggestion(err, "write oh-my-opencode config") };
|
|
4386
4461
|
}
|
|
4387
4462
|
}
|
|
4388
4463
|
async function findOpenCodeBinaryWithVersion() {
|
|
@@ -4412,10 +4487,22 @@ async function getOpenCodeVersion() {
|
|
|
4412
4487
|
return result?.version ?? null;
|
|
4413
4488
|
}
|
|
4414
4489
|
async function addAuthPlugins(config) {
|
|
4415
|
-
|
|
4490
|
+
try {
|
|
4491
|
+
ensureConfigDir();
|
|
4492
|
+
} catch (err) {
|
|
4493
|
+
return { success: false, configPath: OPENCODE_CONFIG_DIR, error: formatErrorWithSuggestion(err, "create config directory") };
|
|
4494
|
+
}
|
|
4416
4495
|
const { format: format2, path: path2 } = detectConfigFormat();
|
|
4417
4496
|
try {
|
|
4418
|
-
|
|
4497
|
+
let existingConfig = null;
|
|
4498
|
+
if (format2 !== "none") {
|
|
4499
|
+
const parseResult = parseConfigWithError(path2);
|
|
4500
|
+
if (parseResult.error && !parseResult.config) {
|
|
4501
|
+
existingConfig = {};
|
|
4502
|
+
} else {
|
|
4503
|
+
existingConfig = parseResult.config;
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4419
4506
|
const plugins = existingConfig?.plugin ?? [];
|
|
4420
4507
|
if (config.hasGemini) {
|
|
4421
4508
|
const version = await fetchLatestVersion("opencode-antigravity-auth");
|
|
@@ -4434,16 +4521,34 @@ async function addAuthPlugins(config) {
|
|
|
4434
4521
|
`);
|
|
4435
4522
|
return { success: true, configPath: path2 };
|
|
4436
4523
|
} catch (err) {
|
|
4437
|
-
return { success: false, configPath: path2, error:
|
|
4524
|
+
return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add auth plugins to config") };
|
|
4438
4525
|
}
|
|
4439
4526
|
}
|
|
4440
4527
|
function setupChatGPTHotfix() {
|
|
4441
|
-
|
|
4528
|
+
try {
|
|
4529
|
+
ensureConfigDir();
|
|
4530
|
+
} catch (err) {
|
|
4531
|
+
return { success: false, configPath: OPENCODE_CONFIG_DIR, error: formatErrorWithSuggestion(err, "create config directory") };
|
|
4532
|
+
}
|
|
4442
4533
|
try {
|
|
4443
4534
|
let packageJson = {};
|
|
4444
4535
|
if (existsSync2(OPENCODE_PACKAGE_JSON)) {
|
|
4445
|
-
|
|
4446
|
-
|
|
4536
|
+
try {
|
|
4537
|
+
const stat = statSync(OPENCODE_PACKAGE_JSON);
|
|
4538
|
+
const content = readFileSync2(OPENCODE_PACKAGE_JSON, "utf-8");
|
|
4539
|
+
if (stat.size > 0 && !isEmptyOrWhitespace(content)) {
|
|
4540
|
+
packageJson = JSON.parse(content);
|
|
4541
|
+
if (typeof packageJson !== "object" || packageJson === null || Array.isArray(packageJson)) {
|
|
4542
|
+
packageJson = {};
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
} catch (parseErr) {
|
|
4546
|
+
if (parseErr instanceof SyntaxError) {
|
|
4547
|
+
packageJson = {};
|
|
4548
|
+
} else {
|
|
4549
|
+
throw parseErr;
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4447
4552
|
}
|
|
4448
4553
|
const deps = packageJson.dependencies ?? {};
|
|
4449
4554
|
deps["opencode-openai-codex-auth"] = CHATGPT_HOTFIX_REPO;
|
|
@@ -4452,20 +4557,47 @@ function setupChatGPTHotfix() {
|
|
|
4452
4557
|
`);
|
|
4453
4558
|
return { success: true, configPath: OPENCODE_PACKAGE_JSON };
|
|
4454
4559
|
} catch (err) {
|
|
4455
|
-
return { success: false, configPath: OPENCODE_PACKAGE_JSON, error:
|
|
4560
|
+
return { success: false, configPath: OPENCODE_PACKAGE_JSON, error: formatErrorWithSuggestion(err, "setup ChatGPT hotfix in package.json") };
|
|
4456
4561
|
}
|
|
4457
4562
|
}
|
|
4458
4563
|
async function runBunInstall() {
|
|
4564
|
+
const result = await runBunInstallWithDetails();
|
|
4565
|
+
return result.success;
|
|
4566
|
+
}
|
|
4567
|
+
async function runBunInstallWithDetails() {
|
|
4459
4568
|
try {
|
|
4460
4569
|
const proc = Bun.spawn(["bun", "install"], {
|
|
4461
4570
|
cwd: OPENCODE_CONFIG_DIR,
|
|
4462
4571
|
stdout: "pipe",
|
|
4463
4572
|
stderr: "pipe"
|
|
4464
4573
|
});
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4574
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve("timeout"), BUN_INSTALL_TIMEOUT_MS));
|
|
4575
|
+
const exitPromise = proc.exited.then(() => "completed");
|
|
4576
|
+
const result = await Promise.race([exitPromise, timeoutPromise]);
|
|
4577
|
+
if (result === "timeout") {
|
|
4578
|
+
try {
|
|
4579
|
+
proc.kill();
|
|
4580
|
+
} catch {}
|
|
4581
|
+
return {
|
|
4582
|
+
success: false,
|
|
4583
|
+
timedOut: true,
|
|
4584
|
+
error: `bun install timed out after ${BUN_INSTALL_TIMEOUT_SECONDS} seconds. Try running manually: cd ~/.config/opencode && bun i`
|
|
4585
|
+
};
|
|
4586
|
+
}
|
|
4587
|
+
if (proc.exitCode !== 0) {
|
|
4588
|
+
const stderr = await new Response(proc.stderr).text();
|
|
4589
|
+
return {
|
|
4590
|
+
success: false,
|
|
4591
|
+
error: stderr.trim() || `bun install failed with exit code ${proc.exitCode}`
|
|
4592
|
+
};
|
|
4593
|
+
}
|
|
4594
|
+
return { success: true };
|
|
4595
|
+
} catch (err) {
|
|
4596
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4597
|
+
return {
|
|
4598
|
+
success: false,
|
|
4599
|
+
error: `bun install failed: ${message}. Is bun installed? Try: curl -fsSL https://bun.sh/install | bash`
|
|
4600
|
+
};
|
|
4469
4601
|
}
|
|
4470
4602
|
}
|
|
4471
4603
|
var ANTIGRAVITY_PROVIDER_CONFIG = {
|
|
@@ -4521,10 +4653,22 @@ var CODEX_PROVIDER_CONFIG = {
|
|
|
4521
4653
|
}
|
|
4522
4654
|
};
|
|
4523
4655
|
function addProviderConfig(config) {
|
|
4524
|
-
|
|
4656
|
+
try {
|
|
4657
|
+
ensureConfigDir();
|
|
4658
|
+
} catch (err) {
|
|
4659
|
+
return { success: false, configPath: OPENCODE_CONFIG_DIR, error: formatErrorWithSuggestion(err, "create config directory") };
|
|
4660
|
+
}
|
|
4525
4661
|
const { format: format2, path: path2 } = detectConfigFormat();
|
|
4526
4662
|
try {
|
|
4527
|
-
|
|
4663
|
+
let existingConfig = null;
|
|
4664
|
+
if (format2 !== "none") {
|
|
4665
|
+
const parseResult = parseConfigWithError(path2);
|
|
4666
|
+
if (parseResult.error && !parseResult.config) {
|
|
4667
|
+
existingConfig = {};
|
|
4668
|
+
} else {
|
|
4669
|
+
existingConfig = parseResult.config;
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4528
4672
|
const newConfig = { ...existingConfig ?? {} };
|
|
4529
4673
|
const providers = newConfig.provider ?? {};
|
|
4530
4674
|
if (config.hasGemini) {
|
|
@@ -4540,7 +4684,7 @@ function addProviderConfig(config) {
|
|
|
4540
4684
|
`);
|
|
4541
4685
|
return { success: true, configPath: path2 };
|
|
4542
4686
|
} catch (err) {
|
|
4543
|
-
return { success: false, configPath: path2, error:
|
|
4687
|
+
return { success: false, configPath: path2, error: formatErrorWithSuggestion(err, "add provider config") };
|
|
4544
4688
|
}
|
|
4545
4689
|
}
|
|
4546
4690
|
function detectCurrentConfig() {
|
|
@@ -4555,10 +4699,11 @@ function detectCurrentConfig() {
|
|
|
4555
4699
|
if (format2 === "none") {
|
|
4556
4700
|
return result;
|
|
4557
4701
|
}
|
|
4558
|
-
const
|
|
4559
|
-
if (!
|
|
4702
|
+
const parseResult = parseConfigWithError(path2);
|
|
4703
|
+
if (!parseResult.config) {
|
|
4560
4704
|
return result;
|
|
4561
4705
|
}
|
|
4706
|
+
const openCodeConfig = parseResult.config;
|
|
4562
4707
|
const plugins = openCodeConfig.plugin ?? [];
|
|
4563
4708
|
result.isInstalled = plugins.some((p2) => p2.startsWith("oh-my-opencode"));
|
|
4564
4709
|
if (!result.isInstalled) {
|
|
@@ -4570,8 +4715,18 @@ function detectCurrentConfig() {
|
|
|
4570
4715
|
return result;
|
|
4571
4716
|
}
|
|
4572
4717
|
try {
|
|
4718
|
+
const stat = statSync(OMO_CONFIG);
|
|
4719
|
+
if (stat.size === 0) {
|
|
4720
|
+
return result;
|
|
4721
|
+
}
|
|
4573
4722
|
const content = readFileSync2(OMO_CONFIG, "utf-8");
|
|
4723
|
+
if (isEmptyOrWhitespace(content)) {
|
|
4724
|
+
return result;
|
|
4725
|
+
}
|
|
4574
4726
|
const omoConfig = parseJsonc(content);
|
|
4727
|
+
if (!omoConfig || typeof omoConfig !== "object") {
|
|
4728
|
+
return result;
|
|
4729
|
+
}
|
|
4575
4730
|
const agents = omoConfig.agents ?? {};
|
|
4576
4731
|
if (agents["Sisyphus"]?.model === "opencode/big-pickle") {
|
|
4577
4732
|
result.hasClaude = false;
|
|
@@ -19720,8 +19875,7 @@ var HookNameSchema = exports_external.enum([
|
|
|
19720
19875
|
"interactive-bash-session",
|
|
19721
19876
|
"empty-message-sanitizer",
|
|
19722
19877
|
"thinking-block-validator",
|
|
19723
|
-
"ralph-loop"
|
|
19724
|
-
"dcp-for-compaction"
|
|
19878
|
+
"ralph-loop"
|
|
19725
19879
|
]);
|
|
19726
19880
|
var BuiltinCommandNameSchema = exports_external.enum([
|
|
19727
19881
|
"init-deep"
|
|
@@ -19806,8 +19960,9 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
19806
19960
|
auto_resume: exports_external.boolean().optional(),
|
|
19807
19961
|
preemptive_compaction: exports_external.boolean().optional(),
|
|
19808
19962
|
preemptive_compaction_threshold: exports_external.number().min(0.5).max(0.95).optional(),
|
|
19809
|
-
truncate_all_tool_outputs: exports_external.boolean().
|
|
19810
|
-
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional()
|
|
19963
|
+
truncate_all_tool_outputs: exports_external.boolean().optional(),
|
|
19964
|
+
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
|
19965
|
+
dcp_for_compaction: exports_external.boolean().optional()
|
|
19811
19966
|
});
|
|
19812
19967
|
var SkillSourceSchema = exports_external.union([
|
|
19813
19968
|
exports_external.string(),
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -54,7 +54,6 @@ export declare const HookNameSchema: z.ZodEnum<{
|
|
|
54
54
|
"empty-message-sanitizer": "empty-message-sanitizer";
|
|
55
55
|
"thinking-block-validator": "thinking-block-validator";
|
|
56
56
|
"ralph-loop": "ralph-loop";
|
|
57
|
-
"dcp-for-compaction": "dcp-for-compaction";
|
|
58
57
|
}>;
|
|
59
58
|
export declare const BuiltinCommandNameSchema: z.ZodEnum<{
|
|
60
59
|
"init-deep": "init-deep";
|
|
@@ -674,7 +673,7 @@ export declare const ExperimentalConfigSchema: z.ZodObject<{
|
|
|
674
673
|
auto_resume: z.ZodOptional<z.ZodBoolean>;
|
|
675
674
|
preemptive_compaction: z.ZodOptional<z.ZodBoolean>;
|
|
676
675
|
preemptive_compaction_threshold: z.ZodOptional<z.ZodNumber>;
|
|
677
|
-
truncate_all_tool_outputs: z.
|
|
676
|
+
truncate_all_tool_outputs: z.ZodOptional<z.ZodBoolean>;
|
|
678
677
|
dynamic_context_pruning: z.ZodOptional<z.ZodObject<{
|
|
679
678
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
680
679
|
notification: z.ZodDefault<z.ZodEnum<{
|
|
@@ -701,6 +700,7 @@ export declare const ExperimentalConfigSchema: z.ZodObject<{
|
|
|
701
700
|
}, z.core.$strip>>;
|
|
702
701
|
}, z.core.$strip>>;
|
|
703
702
|
}, z.core.$strip>>;
|
|
703
|
+
dcp_for_compaction: z.ZodOptional<z.ZodBoolean>;
|
|
704
704
|
}, z.core.$strip>;
|
|
705
705
|
export declare const SkillSourceSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
706
706
|
path: z.ZodString;
|
|
@@ -802,7 +802,6 @@ export declare const OhMyOpenCodeConfigSchema: z.ZodObject<{
|
|
|
802
802
|
"empty-message-sanitizer": "empty-message-sanitizer";
|
|
803
803
|
"thinking-block-validator": "thinking-block-validator";
|
|
804
804
|
"ralph-loop": "ralph-loop";
|
|
805
|
-
"dcp-for-compaction": "dcp-for-compaction";
|
|
806
805
|
}>>>;
|
|
807
806
|
disabled_commands: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
808
807
|
"init-deep": "init-deep";
|
|
@@ -1350,7 +1349,7 @@ export declare const OhMyOpenCodeConfigSchema: z.ZodObject<{
|
|
|
1350
1349
|
auto_resume: z.ZodOptional<z.ZodBoolean>;
|
|
1351
1350
|
preemptive_compaction: z.ZodOptional<z.ZodBoolean>;
|
|
1352
1351
|
preemptive_compaction_threshold: z.ZodOptional<z.ZodNumber>;
|
|
1353
|
-
truncate_all_tool_outputs: z.
|
|
1352
|
+
truncate_all_tool_outputs: z.ZodOptional<z.ZodBoolean>;
|
|
1354
1353
|
dynamic_context_pruning: z.ZodOptional<z.ZodObject<{
|
|
1355
1354
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
1356
1355
|
notification: z.ZodDefault<z.ZodEnum<{
|
|
@@ -1377,6 +1376,7 @@ export declare const OhMyOpenCodeConfigSchema: z.ZodObject<{
|
|
|
1377
1376
|
}, z.core.$strip>>;
|
|
1378
1377
|
}, z.core.$strip>>;
|
|
1379
1378
|
}, z.core.$strip>>;
|
|
1379
|
+
dcp_for_compaction: z.ZodOptional<z.ZodBoolean>;
|
|
1380
1380
|
}, z.core.$strip>>;
|
|
1381
1381
|
auto_update: z.ZodOptional<z.ZodBoolean>;
|
|
1382
1382
|
skills: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodString>, z.ZodIntersection<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Get the cache directory for oh-my-opencode binaries.
|
|
3
|
-
*
|
|
3
|
+
* On Windows: Uses %LOCALAPPDATA% or %APPDATA% (Windows conventions)
|
|
4
|
+
* On Unix: Follows XDG Base Directory Specification
|
|
4
5
|
*/
|
|
5
6
|
export declare function getCacheDir(): string;
|
|
6
7
|
/**
|
package/dist/index.js
CHANGED
|
@@ -5659,6 +5659,11 @@ var PLATFORM_MAP = {
|
|
|
5659
5659
|
"win32-x64": { os: "windows", arch: "amd64", ext: "zip" }
|
|
5660
5660
|
};
|
|
5661
5661
|
function getCacheDir() {
|
|
5662
|
+
if (process.platform === "win32") {
|
|
5663
|
+
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
5664
|
+
const base2 = localAppData || join11(homedir5(), "AppData", "Local");
|
|
5665
|
+
return join11(base2, "oh-my-opencode", "bin");
|
|
5666
|
+
}
|
|
5662
5667
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
5663
5668
|
const base = xdgCache || join11(homedir5(), ".cache");
|
|
5664
5669
|
return join11(base, "oh-my-opencode", "bin");
|
|
@@ -5783,6 +5788,15 @@ function getBinaryName2() {
|
|
|
5783
5788
|
}
|
|
5784
5789
|
function findCommentCheckerPathSync() {
|
|
5785
5790
|
const binaryName = getBinaryName2();
|
|
5791
|
+
const cachedPath = getCachedBinaryPath();
|
|
5792
|
+
if (cachedPath) {
|
|
5793
|
+
debugLog2("found binary in cache:", cachedPath);
|
|
5794
|
+
return cachedPath;
|
|
5795
|
+
}
|
|
5796
|
+
if (!import.meta.url) {
|
|
5797
|
+
debugLog2("import.meta.url is undefined, skipping package resolution");
|
|
5798
|
+
return null;
|
|
5799
|
+
}
|
|
5786
5800
|
try {
|
|
5787
5801
|
const require2 = createRequire2(import.meta.url);
|
|
5788
5802
|
const cliPkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
@@ -5792,13 +5806,8 @@ function findCommentCheckerPathSync() {
|
|
|
5792
5806
|
debugLog2("found binary in main package:", binaryPath);
|
|
5793
5807
|
return binaryPath;
|
|
5794
5808
|
}
|
|
5795
|
-
} catch {
|
|
5796
|
-
debugLog2("main package not installed");
|
|
5797
|
-
}
|
|
5798
|
-
const cachedPath = getCachedBinaryPath();
|
|
5799
|
-
if (cachedPath) {
|
|
5800
|
-
debugLog2("found binary in cache:", cachedPath);
|
|
5801
|
-
return cachedPath;
|
|
5809
|
+
} catch (err) {
|
|
5810
|
+
debugLog2("main package not installed or resolution failed:", err);
|
|
5802
5811
|
}
|
|
5803
5812
|
debugLog2("no binary found in known locations");
|
|
5804
5813
|
return null;
|
|
@@ -6026,7 +6035,7 @@ var TRUNCATABLE_TOOLS = [
|
|
|
6026
6035
|
];
|
|
6027
6036
|
function createToolOutputTruncatorHook(ctx, options) {
|
|
6028
6037
|
const truncator = createDynamicTruncator(ctx);
|
|
6029
|
-
const truncateAll = options?.experimental?.truncate_all_tool_outputs ??
|
|
6038
|
+
const truncateAll = options?.experimental?.truncate_all_tool_outputs ?? false;
|
|
6030
6039
|
const toolExecuteAfter = async (input, output) => {
|
|
6031
6040
|
if (!truncateAll && !TRUNCATABLE_TOOLS.includes(input.tool))
|
|
6032
6041
|
return;
|
|
@@ -7958,7 +7967,7 @@ function createPreemptiveCompactionHook(ctx, options) {
|
|
|
7958
7967
|
const experimental = options?.experimental;
|
|
7959
7968
|
const onBeforeSummarize = options?.onBeforeSummarize;
|
|
7960
7969
|
const getModelLimit = options?.getModelLimit;
|
|
7961
|
-
const enabled = experimental?.preemptive_compaction
|
|
7970
|
+
const enabled = experimental?.preemptive_compaction === true;
|
|
7962
7971
|
const threshold = experimental?.preemptive_compaction_threshold ?? DEFAULT_THRESHOLD;
|
|
7963
7972
|
if (!enabled) {
|
|
7964
7973
|
return { event: async () => {} };
|
|
@@ -31934,8 +31943,7 @@ var HookNameSchema = exports_external.enum([
|
|
|
31934
31943
|
"interactive-bash-session",
|
|
31935
31944
|
"empty-message-sanitizer",
|
|
31936
31945
|
"thinking-block-validator",
|
|
31937
|
-
"ralph-loop"
|
|
31938
|
-
"dcp-for-compaction"
|
|
31946
|
+
"ralph-loop"
|
|
31939
31947
|
]);
|
|
31940
31948
|
var BuiltinCommandNameSchema = exports_external.enum([
|
|
31941
31949
|
"init-deep"
|
|
@@ -32020,8 +32028,9 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
32020
32028
|
auto_resume: exports_external.boolean().optional(),
|
|
32021
32029
|
preemptive_compaction: exports_external.boolean().optional(),
|
|
32022
32030
|
preemptive_compaction_threshold: exports_external.number().min(0.5).max(0.95).optional(),
|
|
32023
|
-
truncate_all_tool_outputs: exports_external.boolean().
|
|
32024
|
-
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional()
|
|
32031
|
+
truncate_all_tool_outputs: exports_external.boolean().optional(),
|
|
32032
|
+
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
|
32033
|
+
dcp_for_compaction: exports_external.boolean().optional()
|
|
32025
32034
|
});
|
|
32026
32035
|
var SkillSourceSchema = exports_external.union([
|
|
32027
32036
|
exports_external.string(),
|
|
@@ -32310,7 +32319,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
32310
32319
|
});
|
|
32311
32320
|
const anthropicContextWindowLimitRecovery = isHookEnabled("anthropic-context-window-limit-recovery") ? createAnthropicContextWindowLimitRecoveryHook(ctx, {
|
|
32312
32321
|
experimental: pluginConfig.experimental,
|
|
32313
|
-
dcpForCompaction:
|
|
32322
|
+
dcpForCompaction: pluginConfig.experimental?.dcp_for_compaction
|
|
32314
32323
|
}) : null;
|
|
32315
32324
|
const compactionContextInjector = createCompactionContextInjector();
|
|
32316
32325
|
const preemptiveCompaction = createPreemptiveCompactionHook(ctx, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"./schema.json": "./dist/oh-my-opencode.schema.json"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"build": "bun build src/index.ts src/google-auth.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm && bun run build:schema",
|
|
26
|
+
"build": "bun build src/index.ts src/google-auth.ts --outdir dist --target bun --format esm --external @ast-grep/napi && tsc --emitDeclarationOnly && bun build src/cli/index.ts --outdir dist/cli --target bun --format esm --external @ast-grep/napi && bun run build:schema",
|
|
27
27
|
"build:schema": "bun run script/build-schema.ts",
|
|
28
28
|
"clean": "rm -rf dist",
|
|
29
29
|
"prepublishOnly": "bun run clean && bun run build",
|