oh-my-opencode 5.0.0-beta.25 → 5.0.0-beta.26
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/dist/cli/index.js +266 -153
- package/dist/cli-node/index.js +266 -153
- package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
- package/dist/index.js +1920 -1655
- package/dist/skills/debugging/SKILL.md +2 -0
- package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/dist/skills/debugging/references/runtimes/go.md +15 -1
- package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/dist/skills/debugging/references/runtimes/node.md +25 -0
- package/dist/skills/debugging/references/runtimes/python.md +13 -0
- package/dist/skills/debugging/references/runtimes/rust.md +41 -0
- package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
- package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/dist/skills/debugging/references/tools/dap.md +103 -0
- package/dist/skills/debugging/references/tools/frida.md +193 -0
- package/dist/tools/delegate-task/types.d.ts +3 -0
- package/dist/tui.js +103 -12
- package/package.json +18 -15
- package/packages/lsp-core/src/index.ts +1 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +25 -5
- package/packages/lsp-core/src/lsp/client.ts +26 -0
- package/packages/lsp-core/src/lsp/connection.ts +16 -0
- package/packages/lsp-core/src/lsp/constants.ts +1 -0
- package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
- package/packages/lsp-core/src/lsp/format-document.ts +90 -0
- package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
- package/packages/lsp-core/src/lsp/manager.ts +34 -1
- package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
- package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
- package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
- package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
- package/packages/lsp-core/src/lsp/transport.ts +9 -0
- package/packages/lsp-core/src/lsp/types.ts +8 -0
- package/packages/lsp-core/src/tool-surface.test.ts +13 -1
- package/packages/lsp-core/src/tools/definitions.ts +14 -0
- package/packages/lsp-core/src/tools/format.test.ts +56 -0
- package/packages/lsp-core/src/tools/format.ts +56 -0
- package/packages/lsp-core/src/tools/index.ts +1 -0
- package/packages/lsp-core/src/tools/types.ts +10 -0
- package/packages/lsp-daemon/dist/cli.js +432 -144
- package/packages/lsp-daemon/dist/client.d.ts +10 -0
- package/packages/lsp-daemon/dist/client.js +401 -107
- package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
- package/packages/lsp-daemon/dist/daemon-client.js +3 -0
- package/packages/lsp-daemon/dist/index.js +395 -107
- package/packages/lsp-tools-mcp/dist/cli.js +384 -99
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +53 -0
- package/packages/lsp-tools-mcp/dist/mcp.js +384 -99
- package/packages/lsp-tools-mcp/dist/tools.js +385 -99
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +69 -35
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +21 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +404 -121
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +3 -3
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +3 -3
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -4
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +30 -15
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +30 -15
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/model-catalog.json +3 -3
- package/packages/omo-codex/plugin/package-lock.json +13 -13
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
- package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
- package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +38 -23
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
- package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
- package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
- package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
- package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
- package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
- package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
- package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
- package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# DAP Client (`dap.mjs`) — Drive the Debugger's Protocol, Not Its Text
|
|
2
|
+
|
|
3
|
+
**Design modeled on the `debug` tool of oh-my-pi (https://github.com/can1357/oh-my-pi, branch omp2).** Their harness proved the shape: one structured debug surface with bounded output, stop snapshots, and classified errors. This script brings the same discipline to any agent with a shell — no harness tool registration required.
|
|
4
|
+
|
|
5
|
+
Debuggers already speak the Debug Adapter Protocol (DAP), a machine-readable JSON protocol. Driving DAP beats screen-scraping a PTY for the same reason an API beats OCR: structured stops, structured variables, structured errors. **If the debugger speaks DAP, use this script instead of parsing `gdb`/`pdb` output.**
|
|
6
|
+
|
|
7
|
+
The script is at `references/scripts/dap.mjs` — zero dependencies, runs under Bun or Node.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## When to use which interface
|
|
12
|
+
|
|
13
|
+
| Situation | Use |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Source-level debugging of Python / Go / Node / native code, and you need breakpoints, stepping, variables | `dap.mjs` (this file) |
|
|
16
|
+
| Browser-served JS, or anything already in Chrome | Scripted CDP — see `references/runtimes/node.md` |
|
|
17
|
+
| Stripped binary, no source, no symbols | Ghidra (static) + Frida (live) — see `references/tools/` |
|
|
18
|
+
| The debugger has no DAP mode (plain gdb on an exotic target) | pwndbg, with the output-budget rule from `references/methodology/00-setup.md` |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## How to drive it
|
|
23
|
+
|
|
24
|
+
`dap.mjs` is a **REPL**, not a one-shot command: a debug session is long-lived, so the script runs as a persistent process reading one command per line on stdin and writing bounded text on stdout. Run it as a background shell session, send commands to its stdin, and subscribe to its output.
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
bun references/scripts/dap.mjs
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Every execution-control answer prints a single snapshot line beginning with `STOP:` — subscribe your watcher to that exact prefix so a breakpoint hit wakes you instead of you polling.
|
|
31
|
+
|
|
32
|
+
### Commands
|
|
33
|
+
|
|
34
|
+
| Command | Effect |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `launch <adapter> <program> [args...]` | Spawn a stdio adapter (path to executable or `.mjs` adapter) and launch the program under it |
|
|
37
|
+
| `attach <host:port>` | Connect to a listening adapter over TCP and attach |
|
|
38
|
+
| `break <file>:<line>` / `rmbreak <file>:<line>` | Set / remove a source breakpoint |
|
|
39
|
+
| `continue` / `step` / `next` / `stepin` / `stepout` / `pause` | Execution control; each prints a `STOP:` snapshot when the debuggee next stops |
|
|
40
|
+
| `stack [limit]` | TSV backtrace, bounded |
|
|
41
|
+
| `scopes` | Scopes of the top frame with their variablesReferences |
|
|
42
|
+
| `vars <ref>` | Variables under a variablesReference from `scopes` — refs are session-scoped; always chain `scopes` first |
|
|
43
|
+
| `eval <expr>` | Evaluate in the top frame |
|
|
44
|
+
| `threads` / `sessions` | Thread list / session state |
|
|
45
|
+
| `terminate` / `quit` | End the debuggee / exit the REPL |
|
|
46
|
+
|
|
47
|
+
### Output contract (what keeps your context alive)
|
|
48
|
+
|
|
49
|
+
- Tabular results are TSV with a header row.
|
|
50
|
+
- Hard caps: `MAX_ROWS = 100`, `MAX_OUTPUT_BYTES = 32 KB`. Overflow prints an explicit `TRUNCATED: rows dropped=N bytes dropped=M` line — never a silent cut.
|
|
51
|
+
- After every continue/step: `STOP: stopped reason=<why> threadId=<id> <frame> at <file>:<line>:<col>`. On debuggee exit: `EXIT: terminated`.
|
|
52
|
+
- Errors are one line, classified: `ERR: invalid-args | no-session | adapter-failed | unverified-breakpoint | timeout | terminated | adapter-error`. The token tells you the recovery — see the failure taxonomy in `references/methodology/02-investigate.md`.
|
|
53
|
+
- Every request times out after 15 s (override with `DAP_TIMEOUT_MS`) and the session stays alive.
|
|
54
|
+
- `DAP_DEBUG=1` logs raw protocol traffic to stderr for diagnosing a misbehaving adapter.
|
|
55
|
+
|
|
56
|
+
### Adapter quirks this client already handles
|
|
57
|
+
|
|
58
|
+
- **debugpy** requires `console: "internalConsole"` in the launch request, and withholds the `initialized` event for unrecognized `adapterID`s — the client sends both correctly. It also flushes `initialized` lazily, so the client launches first and awaits the event after.
|
|
59
|
+
- **lldb-dap** reports the launch response's `success` unreliably (`false` even when the process started and stopped) and reports `threadId: 0` on the entry stop. The events are the real signal; the client tolerates the response flag.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Adapter matrix
|
|
64
|
+
|
|
65
|
+
Translated from oh-my-pi's `builtin_adapters()` (omp2 `crates/docserver/src/dap_adapter.rs`). Install the one matching your runtime; the client speaks to all of them the same way.
|
|
66
|
+
|
|
67
|
+
| Runtime | Adapter | Install | Launch mode |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| Python | debugpy | `pip install debugpy` | `python -m debugpy.adapter` (stdio) |
|
|
70
|
+
| Go | dlv | `go install github.com/go-delve/delve/cmd/dlv@latest` | `dlv dap` (stdio) |
|
|
71
|
+
| C/C++/Swift/Rust/Zig | lldb-dap | ships with Xcode CLT / LLVM | `lldb-dap` (stdio) |
|
|
72
|
+
| C/C++/Rust/Zig | codelldb | VS Code extension binary | stdio |
|
|
73
|
+
| C/C++/Rust | gdb | `brew install gdb` / apt | via gdb's DAP mode where available |
|
|
74
|
+
| JS/TS | js-debug | `npm i -g @vscode/js-debug` | stdio |
|
|
75
|
+
| .NET | netcoredbg | GitHub releases | stdio |
|
|
76
|
+
| Ruby | rdbg | `gem install debug` | stdio |
|
|
77
|
+
| Kotlin | kotlin-debug-adapter | GitHub releases | stdio |
|
|
78
|
+
| PHP | php-debug-adapter | composer | stdio |
|
|
79
|
+
| Bash | bash-debug-adapter | GitHub releases | stdio |
|
|
80
|
+
| Dart/Flutter | dart debug adapter | ships with Dart SDK | `dart` (stdio) |
|
|
81
|
+
| Elixir | elixir-ls debugger | GitHub releases | stdio |
|
|
82
|
+
|
|
83
|
+
If an adapter is missing, the install line is the fix — do not fall back to scraping a REPL.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Worked example (Python)
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
launch /path/to/python -m debugpy.adapter myscript.py # or a wrapper script path
|
|
91
|
+
break myscript.py:12
|
|
92
|
+
continue
|
|
93
|
+
STOP: stopped reason=breakpoint threadId=1 compute at myscript.py:12:1
|
|
94
|
+
stack
|
|
95
|
+
scopes
|
|
96
|
+
vars 6 # the variablesReference scopes just printed for Locals
|
|
97
|
+
eval total
|
|
98
|
+
continue
|
|
99
|
+
terminate
|
|
100
|
+
quit
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Cleanup is part of the session: `terminate` the debuggee, `quit` the REPL, and journal any wrapper scripts you created per the skill's cleanup phase.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Frida — Hook a Live Process and See Real Values at Runtime
|
|
2
|
+
|
|
3
|
+
**https://frida.re**
|
|
4
|
+
|
|
5
|
+
Frida injects a JavaScript engine into a running process and lets you intercept function calls, read arguments, patch return values, and trace execution without touching the binary on disk. **When static analysis in Ghidra shows you *what* a function does, Frida shows you what it does *right now*, with real inputs.** The two compose naturally: use Ghidra to find the target function and its offset, then use Frida to hook it and watch live traffic.
|
|
6
|
+
|
|
7
|
+
Choose Frida over Ghidra when you need runtime values (actual arguments, return codes, heap contents) or when the binary's control flow is too obfuscated for static analysis to resolve.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install frida-tools # Python 3 required
|
|
15
|
+
frida --version # verify
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
On macOS, attaching to another user's process needs root (`sudo frida ...`). SIP-protected system binaries (`/usr/bin/*`, `/usr/sbin/*`) are off-limits entirely. On Linux, you may need `ptrace` permissions: run as root or set `kernel.yama.ptrace_scope=0`.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Target discovery with `frida-ps`
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
frida-ps # list local processes
|
|
26
|
+
frida-ps -U # USB-connected device (iOS/Android)
|
|
27
|
+
frida-ps | grep -i target # find your target by name
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## `frida-trace` — zero-code entry point
|
|
33
|
+
|
|
34
|
+
`frida-trace` auto-generates JavaScript handler stubs for every matched function. You don't write any code to start.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
frida-trace -p <pid> -i "recv*" # trace exported functions by glob
|
|
38
|
+
frida-trace -p <pid> -m "-[NSURLSession dataTaskWithRequest:*]" # Objective-C method
|
|
39
|
+
frida-trace -U -p <pid> -j "com.example.App!login*" # Java method (Android)
|
|
40
|
+
frida-trace -f ./target -i "open" # spawn + trace from start
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Generated handler files land in `__handlers__/`. Each looks like:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// __handlers__/libSystem.B.dylib/open.js
|
|
47
|
+
{
|
|
48
|
+
onEnter(log, args, state) {
|
|
49
|
+
// args[0] is the first argument (a pointer)
|
|
50
|
+
log(`open("${args[0].readUtf8String()}")`);
|
|
51
|
+
},
|
|
52
|
+
onLeave(log, retval, state) {
|
|
53
|
+
log(` => ${retval}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Edit that file, save, and `frida-trace` hot-reloads it. This is the fastest path from "I wonder what this function receives" to a concrete answer.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## The JS agent API
|
|
63
|
+
|
|
64
|
+
When `frida-trace` isn't enough, you write a JS agent and load it with `frida` or from a Python host script. These are the building blocks.
|
|
65
|
+
|
|
66
|
+
### Find a function
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// By exported symbol name
|
|
70
|
+
const openPtr = Module.getExportByName(null, "open"); // null = any module
|
|
71
|
+
const sslWritePtr = Module.getExportByName("libssl.so", "SSL_write");
|
|
72
|
+
|
|
73
|
+
// By offset in a stripped binary (get the offset from Ghidra)
|
|
74
|
+
const base = Module.getBaseAddress("target");
|
|
75
|
+
const funcPtr = base.add(0x1a3c);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Intercept calls
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
Interceptor.attach(openPtr, {
|
|
82
|
+
onEnter(args) {
|
|
83
|
+
// args[0], args[1], ... are NativePointer objects
|
|
84
|
+
const path = args[0].readUtf8String();
|
|
85
|
+
const flags = args[1].toInt32();
|
|
86
|
+
send({ event: "open", path: path, flags: flags });
|
|
87
|
+
},
|
|
88
|
+
onLeave(retval) {
|
|
89
|
+
// retval is the return value as a NativePointer
|
|
90
|
+
send({ event: "open_ret", fd: retval.toInt32() });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Read memory
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
args[0].readUtf8String() // read a UTF-8 C string from a pointer
|
|
99
|
+
args[0].readCString() // read a raw C string (stops at null)
|
|
100
|
+
args[1].readByteArray(len) // read len raw bytes (returns ArrayBuffer)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Replace / stub a function
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
// Force a function to always return 0 (e.g. bypass a license check)
|
|
107
|
+
Interceptor.replace(checkLicensePtr, new NativeCallback(function () {
|
|
108
|
+
return 0;
|
|
109
|
+
}, 'int', []));
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Use `Interceptor.replace` sparingly. It changes program behavior, so always note in your journal that you patched something and why.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Python host script
|
|
117
|
+
|
|
118
|
+
A host script lets you load a JS agent, receive `send()` messages, and post-process results from the Python side.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
import frida, sys
|
|
122
|
+
|
|
123
|
+
with open("agent.js") as f:
|
|
124
|
+
agent_source = f.read()
|
|
125
|
+
|
|
126
|
+
def on_message(message, data):
|
|
127
|
+
if message["type"] == "send":
|
|
128
|
+
print(f"[*] {message['payload']}")
|
|
129
|
+
else:
|
|
130
|
+
print(f"[!] {message}")
|
|
131
|
+
|
|
132
|
+
session = frida.attach(int(sys.argv[1]))
|
|
133
|
+
script = session.create_script(agent_source)
|
|
134
|
+
script.on("message", on_message)
|
|
135
|
+
script.load()
|
|
136
|
+
|
|
137
|
+
try:
|
|
138
|
+
sys.stdin.read() # block until Ctrl+C
|
|
139
|
+
except KeyboardInterrupt:
|
|
140
|
+
session.detach()
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The agent runs inside the target; the host script stays in your terminal and prints structured output.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Output-budget discipline
|
|
148
|
+
|
|
149
|
+
**Hooking a hot function (e.g. `malloc`, `read`) will flood your context with thousands of lines.** Don't print every call. Aggregate in the agent and report a summary.
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
// Count calls, report every 1000
|
|
153
|
+
let callCount = 0;
|
|
154
|
+
Interceptor.attach(mallocPtr, {
|
|
155
|
+
onEnter(args) {
|
|
156
|
+
callCount++;
|
|
157
|
+
if (callCount % 1000 === 0) {
|
|
158
|
+
send({ event: "malloc_summary", total_calls: callCount });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Alternatives: filter by argument value, only log calls from a specific caller module, or batch into an array and `send()` on a timer.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## ⚠️ Gotchas
|
|
169
|
+
|
|
170
|
+
**Attach vs. spawn.** `frida -p <pid>` attaches to an already-running process. If you need to catch early initialization (constructors, `main` entry), spawn the process with `frida -f ./target`. Frida pauses it at startup. Resume with `%resume` in the REPL or by calling `device.resume(pid)` from Python.
|
|
171
|
+
|
|
172
|
+
**Stripped binaries have no symbol names.** `Module.getExportByName` returns null for internal functions. You must find the function offset in Ghidra, then compute the address at runtime:
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
const addr = Module.getBaseAddress("target").add(0x4a20);
|
|
176
|
+
Interceptor.attach(addr, { /* ... */ });
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**A crashing target kills your session.** If the target segfaults or aborts, Frida's agent dies with it. Script a respawn loop on the Python side if you expect crashes.
|
|
180
|
+
|
|
181
|
+
**Thread safety.** `onEnter`/`onLeave` fire on multiple threads. Keep shared state to simple counters.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Cleanup
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
kill <pid> # kill any process you spawned with -f
|
|
189
|
+
rm -rf __handlers__/ # remove generated handler stubs
|
|
190
|
+
rm -f agent.js host.py # remove session-specific scripts
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Always note in your journal which processes you attached to and whether you replaced any functions. A forgotten `Interceptor.replace` in a long-running target will cause confusing behavior later.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BackgroundManager } from "../../features/background-agent";
|
|
2
|
+
import type { OhMyOpenCodeConfig } from "../../config";
|
|
2
3
|
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides, SisyphusAgentConfig } from "../../config/schema";
|
|
3
4
|
import type { ModelFallbackControllerAccessor } from "../../hooks/model-fallback";
|
|
4
5
|
import type { LoadedSkill } from "../../features/opencode-skill-loader/types";
|
|
@@ -119,6 +120,8 @@ export interface DelegateTaskToolOptions {
|
|
|
119
120
|
availableCategories?: AvailableCategory[];
|
|
120
121
|
availableSkills?: AvailableSkill[];
|
|
121
122
|
agentOverrides?: AgentOverrides;
|
|
123
|
+
/** Reload model-bearing config at task invocation time so edits are honored without rebuilding tools. */
|
|
124
|
+
loadCurrentModelConfig?: () => Pick<OhMyOpenCodeConfig, "agents" | "categories">;
|
|
122
125
|
sisyphusAgentConfig?: SisyphusAgentConfig;
|
|
123
126
|
modelFallbackControllerAccessor?: ModelFallbackControllerAccessor;
|
|
124
127
|
onSyncSessionCreated?: (event: SyncSessionCreatedEvent) => Promise<void>;
|
package/dist/tui.js
CHANGED
|
@@ -17499,6 +17499,25 @@ var init_telemetry = __esm(() => {
|
|
|
17499
17499
|
}).strict();
|
|
17500
17500
|
});
|
|
17501
17501
|
|
|
17502
|
+
// packages/omo-config-core/src/schema/format-on-mutation.ts
|
|
17503
|
+
var mode, languages, OmoFormatOnMutationLayerSchema, OmoFormatOnMutationSchema;
|
|
17504
|
+
var init_format_on_mutation = __esm(() => {
|
|
17505
|
+
init_zod();
|
|
17506
|
+
mode = _enum2(["off", "best-effort", "required"]);
|
|
17507
|
+
languages = record(string2(), boolean2()).optional();
|
|
17508
|
+
OmoFormatOnMutationLayerSchema = object({
|
|
17509
|
+
mode: mode.optional(),
|
|
17510
|
+
languages,
|
|
17511
|
+
maxFileBytes: number2().int().positive().optional(),
|
|
17512
|
+
timeoutMs: number2().int().positive().optional()
|
|
17513
|
+
}).strict();
|
|
17514
|
+
OmoFormatOnMutationSchema = OmoFormatOnMutationLayerSchema.extend({
|
|
17515
|
+
mode: mode.default("best-effort"),
|
|
17516
|
+
maxFileBytes: number2().int().positive().default(1048576),
|
|
17517
|
+
timeoutMs: number2().int().positive().default(3000)
|
|
17518
|
+
}).strict();
|
|
17519
|
+
});
|
|
17520
|
+
|
|
17502
17521
|
// packages/omo-config-core/src/schema/config.ts
|
|
17503
17522
|
var OmoOpenCodeHarnessConfigSchema, OmoTypedHarnessConfigSchema, OmoConfigProfileSchema, OmoConfigSchema, OmoConfigLayerSchema;
|
|
17504
17523
|
var init_config = __esm(() => {
|
|
@@ -17512,8 +17531,10 @@ var init_config = __esm(() => {
|
|
|
17512
17531
|
init_task();
|
|
17513
17532
|
init_team();
|
|
17514
17533
|
init_telemetry();
|
|
17534
|
+
init_format_on_mutation();
|
|
17515
17535
|
OmoOpenCodeHarnessConfigSchema = record(string2(), unknown());
|
|
17516
17536
|
OmoTypedHarnessConfigSchema = object({
|
|
17537
|
+
formatOnMutation: OmoFormatOnMutationLayerSchema.optional(),
|
|
17517
17538
|
categories: OmoCategoriesConfigSchema.optional(),
|
|
17518
17539
|
agents: OmoAgentsConfigSchema.optional(),
|
|
17519
17540
|
codegraph: OmoCodegraphSettingsLayerSchema.optional(),
|
|
@@ -17525,6 +17546,7 @@ var init_config = __esm(() => {
|
|
|
17525
17546
|
telemetry: OmoTelemetrySettingsLayerSchema.optional()
|
|
17526
17547
|
}).strict();
|
|
17527
17548
|
OmoConfigProfileSchema = object({
|
|
17549
|
+
formatOnMutation: OmoFormatOnMutationLayerSchema.optional(),
|
|
17528
17550
|
categories: OmoCategoriesConfigSchema.optional(),
|
|
17529
17551
|
agents: OmoAgentsConfigSchema.optional(),
|
|
17530
17552
|
codegraph: OmoCodegraphSettingsLayerSchema.optional(),
|
|
@@ -17539,6 +17561,7 @@ var init_config = __esm(() => {
|
|
|
17539
17561
|
"[codex]": OmoTypedHarnessConfigSchema.optional()
|
|
17540
17562
|
}).strict();
|
|
17541
17563
|
OmoConfigSchema = object({
|
|
17564
|
+
formatOnMutation: OmoFormatOnMutationSchema.optional(),
|
|
17542
17565
|
$schema: string2().optional(),
|
|
17543
17566
|
categories: OmoCategoriesConfigSchema.optional(),
|
|
17544
17567
|
agents: OmoAgentsConfigSchema.optional(),
|
|
@@ -17557,6 +17580,7 @@ var init_config = __esm(() => {
|
|
|
17557
17580
|
legacy_migrations: record(string2(), unknown()).optional()
|
|
17558
17581
|
}).strict();
|
|
17559
17582
|
OmoConfigLayerSchema = object({
|
|
17583
|
+
formatOnMutation: OmoFormatOnMutationLayerSchema.optional(),
|
|
17560
17584
|
$schema: string2().optional(),
|
|
17561
17585
|
categories: OmoCategoriesConfigSchema.optional(),
|
|
17562
17586
|
agents: OmoAgentsConfigSchema.optional(),
|
|
@@ -17583,6 +17607,7 @@ var init_schema = __esm(() => {
|
|
|
17583
17607
|
init_codegraph();
|
|
17584
17608
|
init_config();
|
|
17585
17609
|
init_fallback_models();
|
|
17610
|
+
init_format_on_mutation();
|
|
17586
17611
|
init_git_master();
|
|
17587
17612
|
init_harness();
|
|
17588
17613
|
init_memory();
|
|
@@ -18651,6 +18676,9 @@ var init_message_inspection_error = () => {};
|
|
|
18651
18676
|
function getPromptGateMessagesFetchTimeoutMs() {
|
|
18652
18677
|
return promptGateMessagesFetchTimeoutMsForTesting ?? DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS;
|
|
18653
18678
|
}
|
|
18679
|
+
function getPromptGateRevalidationTimeoutMs() {
|
|
18680
|
+
return promptGateRevalidationTimeoutMsForTesting ?? DEFAULT_PROMPT_REVALIDATION_TIMEOUT_MS;
|
|
18681
|
+
}
|
|
18654
18682
|
async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName) {
|
|
18655
18683
|
if (dispatchTimeoutMs <= 0) {
|
|
18656
18684
|
return operation;
|
|
@@ -18669,7 +18697,7 @@ async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName)
|
|
|
18669
18697
|
}
|
|
18670
18698
|
}
|
|
18671
18699
|
}
|
|
18672
|
-
var DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, promptGateMessagesFetchTimeoutMsForTesting;
|
|
18700
|
+
var DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, DEFAULT_PROMPT_REVALIDATION_TIMEOUT_MS = 5000, promptGateMessagesFetchTimeoutMsForTesting, promptGateRevalidationTimeoutMsForTesting;
|
|
18673
18701
|
|
|
18674
18702
|
// packages/utils/src/prompt-async-gate/pending-tool-turn.ts
|
|
18675
18703
|
function getPromptQuery(input) {
|
|
@@ -18866,6 +18894,7 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
18866
18894
|
checkStatus,
|
|
18867
18895
|
checkToolState,
|
|
18868
18896
|
shouldDispatch,
|
|
18897
|
+
retryDispatchFailure,
|
|
18869
18898
|
dispatch
|
|
18870
18899
|
} = args;
|
|
18871
18900
|
const existing = getActiveReservation(sessionID);
|
|
@@ -18920,7 +18949,9 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
18920
18949
|
});
|
|
18921
18950
|
return { status: "active" };
|
|
18922
18951
|
}
|
|
18923
|
-
|
|
18952
|
+
const dispatchDecision = shouldDispatch?.();
|
|
18953
|
+
const resolvedDispatchDecision = dispatchDecision !== undefined && typeof dispatchDecision !== "boolean" ? await withDispatchTimeout(dispatchDecision, Math.min(dispatchTimeoutMs, getPromptGateRevalidationTimeoutMs()), `[prompt-async-gate] ${sessionName} shouldDispatch`) : dispatchDecision;
|
|
18954
|
+
if (resolvedDispatchDecision === false) {
|
|
18924
18955
|
log(`[prompt-async-gate] ${sessionName} cancelled before dispatch`, { sessionID, source });
|
|
18925
18956
|
return { status: "cancelled" };
|
|
18926
18957
|
}
|
|
@@ -18936,6 +18967,7 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
18936
18967
|
log(`[prompt-async-gate] ${sessionName} dispatched`, { sessionID, source });
|
|
18937
18968
|
return { status: "dispatched", response };
|
|
18938
18969
|
} catch (error51) {
|
|
18970
|
+
const queueRetryable = dispatchAttempted && retryDispatchFailure?.(error51) === true;
|
|
18939
18971
|
if (dispatchAttempted) {
|
|
18940
18972
|
rememberRecentPromptDispatch({
|
|
18941
18973
|
sessionID,
|
|
@@ -18946,7 +18978,12 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
18946
18978
|
}
|
|
18947
18979
|
const errorText = error51 instanceof Error ? `${error51.name}: ${error51.message}` : String(error51);
|
|
18948
18980
|
log(`[prompt-async-gate] ${sessionName} failed`, { sessionID, source, error: errorText });
|
|
18949
|
-
return {
|
|
18981
|
+
return {
|
|
18982
|
+
status: "failed",
|
|
18983
|
+
error: error51,
|
|
18984
|
+
dispatchAttempted,
|
|
18985
|
+
...queueRetryable ? { queueRetryable: true } : {}
|
|
18986
|
+
};
|
|
18950
18987
|
} finally {
|
|
18951
18988
|
finishPromptReservation(sessionID, reservation, dispatchAttempted, postDispatchHoldMs);
|
|
18952
18989
|
}
|
|
@@ -18999,6 +19036,7 @@ function schedulePromptQueueDrain(sessionID, delayMs) {
|
|
|
18999
19036
|
promptQueueTimers.set(sessionID, timer);
|
|
19000
19037
|
}
|
|
19001
19038
|
function removePromptQueueEntry(sessionID, entry) {
|
|
19039
|
+
promptQueueRetryStates.delete(entry.id);
|
|
19002
19040
|
const queue = promptQueues.get(sessionID);
|
|
19003
19041
|
if (!queue) {
|
|
19004
19042
|
return;
|
|
@@ -19013,6 +19051,7 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
19013
19051
|
promptQueueDraining.add(sessionID);
|
|
19014
19052
|
clearPromptQueueTimer(sessionID);
|
|
19015
19053
|
let awaitedResult;
|
|
19054
|
+
const deferredRetryIds = new Set;
|
|
19016
19055
|
try {
|
|
19017
19056
|
while (true) {
|
|
19018
19057
|
const queue = promptQueues.get(sessionID);
|
|
@@ -19020,6 +19059,20 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
19020
19059
|
if (!entry) {
|
|
19021
19060
|
break;
|
|
19022
19061
|
}
|
|
19062
|
+
const retryState = promptQueueRetryStates.get(entry.id);
|
|
19063
|
+
if (entry.durableRetry && retryState?.retryAfter !== undefined && retryState.retryAfter > Date.now()) {
|
|
19064
|
+
if (deferredRetryIds.has(entry.id)) {
|
|
19065
|
+
const nextRetryAt = Math.min(...queue.flatMap((queued) => {
|
|
19066
|
+
const retryAfter = promptQueueRetryStates.get(queued.id)?.retryAfter;
|
|
19067
|
+
return retryAfter === undefined ? [] : [retryAfter];
|
|
19068
|
+
}));
|
|
19069
|
+
schedulePromptQueueDrain(sessionID, nextRetryAt - Date.now());
|
|
19070
|
+
break;
|
|
19071
|
+
}
|
|
19072
|
+
deferredRetryIds.add(entry.id);
|
|
19073
|
+
setPromptQueue(sessionID, [...queue.slice(1), entry]);
|
|
19074
|
+
continue;
|
|
19075
|
+
}
|
|
19023
19076
|
promptQueueInFlight.set(sessionID, entry);
|
|
19024
19077
|
const result = await dispatchAfterSessionIdle({
|
|
19025
19078
|
sessionName: entry.sessionName,
|
|
@@ -19035,12 +19088,45 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
19035
19088
|
checkStatus: entry.checkStatus,
|
|
19036
19089
|
checkToolState: entry.checkToolState,
|
|
19037
19090
|
shouldDispatch: entry.shouldDispatch,
|
|
19091
|
+
retryDispatchFailure: entry.retryDispatchFailure,
|
|
19038
19092
|
dispatch: entry.dispatch
|
|
19039
19093
|
});
|
|
19040
19094
|
if (promptQueueInFlight.get(sessionID)?.id === entry.id) {
|
|
19041
19095
|
promptQueueInFlight.delete(sessionID);
|
|
19042
19096
|
}
|
|
19043
|
-
|
|
19097
|
+
const retryableQueuedFailure = result.status === "failed" && (!result.dispatchAttempted || result.queueRetryable === true);
|
|
19098
|
+
if (retryableQueuedFailure) {
|
|
19099
|
+
const failureCount = (promptQueueRetryStates.get(entry.id)?.failureCount ?? 0) + 1;
|
|
19100
|
+
if (entry.durableRetry) {
|
|
19101
|
+
const exponentialBackoffMs = entry.queueRetryMs * 2 ** Math.min(failureCount, 7);
|
|
19102
|
+
const retryDelayMs = Math.max(entry.postDispatchHoldMs, Math.min(exponentialBackoffMs, MAX_DURABLE_RETRY_BACKOFF_MS));
|
|
19103
|
+
promptQueueRetryStates.set(entry.id, {
|
|
19104
|
+
failureCount,
|
|
19105
|
+
retryAfter: Date.now() + retryDelayMs
|
|
19106
|
+
});
|
|
19107
|
+
const currentQueue = promptQueues.get(sessionID);
|
|
19108
|
+
if (currentQueue && currentQueue.length > 1) {
|
|
19109
|
+
setPromptQueue(sessionID, [...currentQueue.slice(1), entry]);
|
|
19110
|
+
continue;
|
|
19111
|
+
}
|
|
19112
|
+
schedulePromptQueueDrain(sessionID, retryDelayMs);
|
|
19113
|
+
break;
|
|
19114
|
+
}
|
|
19115
|
+
if (failureCount >= MAX_QUEUED_RETRYABLE_FAILURES) {
|
|
19116
|
+
log("[prompt-async-gate] dropping queued prompt after repeated retryable failures", {
|
|
19117
|
+
sessionID,
|
|
19118
|
+
source: entry.source,
|
|
19119
|
+
failureCount
|
|
19120
|
+
});
|
|
19121
|
+
removePromptQueueEntry(sessionID, entry);
|
|
19122
|
+
if (awaitedEntry?.id === entry.id) {
|
|
19123
|
+
awaitedResult = result;
|
|
19124
|
+
}
|
|
19125
|
+
continue;
|
|
19126
|
+
}
|
|
19127
|
+
promptQueueRetryStates.set(entry.id, { failureCount });
|
|
19128
|
+
}
|
|
19129
|
+
if (result.status === "active" || result.status === "reserved" || retryableQueuedFailure) {
|
|
19044
19130
|
const queued = queuedResult(entry, 1, result.status === "reserved" ? result.reservedBy : entry.source);
|
|
19045
19131
|
if (awaitedEntry?.id === entry.id) {
|
|
19046
19132
|
awaitedResult = queued;
|
|
@@ -19064,7 +19150,7 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
19064
19150
|
}
|
|
19065
19151
|
return awaitedResult;
|
|
19066
19152
|
}
|
|
19067
|
-
var promptQueues, promptQueueDraining, promptQueueInFlight, promptQueueTimers;
|
|
19153
|
+
var promptQueues, promptQueueDraining, promptQueueInFlight, promptQueueTimers, promptQueueRetryStates, MAX_QUEUED_RETRYABLE_FAILURES = 3, MAX_DURABLE_RETRY_BACKOFF_MS = 30000;
|
|
19068
19154
|
var init_queue = __esm(() => {
|
|
19069
19155
|
init_session_idle_dispatch();
|
|
19070
19156
|
init_reservations();
|
|
@@ -19072,6 +19158,7 @@ var init_queue = __esm(() => {
|
|
|
19072
19158
|
promptQueueDraining = new Set;
|
|
19073
19159
|
promptQueueInFlight = new Map;
|
|
19074
19160
|
promptQueueTimers = new Map;
|
|
19161
|
+
promptQueueRetryStates = new Map;
|
|
19075
19162
|
setExpiredReservationHandler((sessionID) => {
|
|
19076
19163
|
schedulePromptQueueDrain(sessionID, 0);
|
|
19077
19164
|
});
|
|
@@ -78070,7 +78157,17 @@ function isPreSendConnectionFailure(error51) {
|
|
|
78070
78157
|
if (error51.name === "AbortError") {
|
|
78071
78158
|
return false;
|
|
78072
78159
|
}
|
|
78073
|
-
const CONNECTION_CODES = new Set([
|
|
78160
|
+
const CONNECTION_CODES = new Set([
|
|
78161
|
+
"ECONNREFUSED",
|
|
78162
|
+
"ENOTFOUND",
|
|
78163
|
+
"EAI_AGAIN",
|
|
78164
|
+
"ENETUNREACH",
|
|
78165
|
+
"EHOSTUNREACH",
|
|
78166
|
+
"ENETDOWN",
|
|
78167
|
+
"EHOSTDOWN",
|
|
78168
|
+
"EADDRNOTAVAIL",
|
|
78169
|
+
"UND_ERR_CONNECT_TIMEOUT"
|
|
78170
|
+
]);
|
|
78074
78171
|
const self = error51;
|
|
78075
78172
|
if (self.code && CONNECTION_CODES.has(self.code)) {
|
|
78076
78173
|
return true;
|
|
@@ -78082,12 +78179,6 @@ function isPreSendConnectionFailure(error51) {
|
|
|
78082
78179
|
return true;
|
|
78083
78180
|
}
|
|
78084
78181
|
}
|
|
78085
|
-
if (error51 instanceof TypeError) {
|
|
78086
|
-
const msg = error51.message;
|
|
78087
|
-
if (msg.includes("fetch failed") || msg.includes("Unable to connect")) {
|
|
78088
|
-
return true;
|
|
78089
|
-
}
|
|
78090
|
-
}
|
|
78091
78182
|
return false;
|
|
78092
78183
|
}
|
|
78093
78184
|
function markLiveRouteUnavailable(reason) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-opencode",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.26",
|
|
4
4
|
"description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"zod": "^4.4.3"
|
|
182
182
|
},
|
|
183
183
|
"devDependencies": {
|
|
184
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
184
|
+
"@code-yeongyu/senpi": "2026.8.28-2",
|
|
185
185
|
"@oh-my-opencode/agents-md-core": "workspace:*",
|
|
186
186
|
"@oh-my-opencode/ast-grep-mcp": "workspace:*",
|
|
187
187
|
"@oh-my-opencode/boulder-state": "workspace:*",
|
|
@@ -222,18 +222,18 @@
|
|
|
222
222
|
"typescript": "^7.0.2"
|
|
223
223
|
},
|
|
224
224
|
"optionalDependencies": {
|
|
225
|
-
"oh-my-opencode-darwin-arm64": "5.0.0-beta.
|
|
226
|
-
"oh-my-opencode-darwin-x64": "5.0.0-beta.
|
|
227
|
-
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.
|
|
228
|
-
"oh-my-opencode-linux-arm64": "5.0.0-beta.
|
|
229
|
-
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.
|
|
230
|
-
"oh-my-opencode-linux-x64": "5.0.0-beta.
|
|
231
|
-
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.
|
|
232
|
-
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.
|
|
233
|
-
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.
|
|
234
|
-
"oh-my-opencode-windows-arm64": "5.0.0-beta.
|
|
235
|
-
"oh-my-opencode-windows-x64": "5.0.0-beta.
|
|
236
|
-
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.
|
|
225
|
+
"oh-my-opencode-darwin-arm64": "5.0.0-beta.26",
|
|
226
|
+
"oh-my-opencode-darwin-x64": "5.0.0-beta.26",
|
|
227
|
+
"oh-my-opencode-darwin-x64-baseline": "5.0.0-beta.26",
|
|
228
|
+
"oh-my-opencode-linux-arm64": "5.0.0-beta.26",
|
|
229
|
+
"oh-my-opencode-linux-arm64-musl": "5.0.0-beta.26",
|
|
230
|
+
"oh-my-opencode-linux-x64": "5.0.0-beta.26",
|
|
231
|
+
"oh-my-opencode-linux-x64-baseline": "5.0.0-beta.26",
|
|
232
|
+
"oh-my-opencode-linux-x64-musl": "5.0.0-beta.26",
|
|
233
|
+
"oh-my-opencode-linux-x64-musl-baseline": "5.0.0-beta.26",
|
|
234
|
+
"oh-my-opencode-windows-arm64": "5.0.0-beta.26",
|
|
235
|
+
"oh-my-opencode-windows-x64": "5.0.0-beta.26",
|
|
236
|
+
"oh-my-opencode-windows-x64-baseline": "5.0.0-beta.26"
|
|
237
237
|
},
|
|
238
238
|
"overrides": {
|
|
239
239
|
"@earendil-works/pi-agent-core": "0.84.2",
|
|
@@ -249,5 +249,8 @@
|
|
|
249
249
|
},
|
|
250
250
|
"trustedDependencies": [
|
|
251
251
|
"@code-yeongyu/comment-checker"
|
|
252
|
-
]
|
|
252
|
+
],
|
|
253
|
+
"patchedDependencies": {
|
|
254
|
+
"@code-yeongyu/senpi@2026.8.28-2": "patches/@code-yeongyu%2Fsenpi@2026.8.28-2.patch"
|
|
255
|
+
}
|
|
253
256
|
}
|
|
@@ -7,6 +7,7 @@ export * from "./lsp/constants.js";
|
|
|
7
7
|
export * from "./lsp/directory-diagnostics.js";
|
|
8
8
|
export * from "./lsp/effective-extension.js";
|
|
9
9
|
export * from "./lsp/errors.js";
|
|
10
|
+
export * from "./lsp/format-document.js";
|
|
10
11
|
export * from "./lsp/formatters.js";
|
|
11
12
|
export * from "./lsp/infer-extension.js";
|
|
12
13
|
export * from "./lsp/json-rpc-connection.js";
|