@code-yeongyu/senpi 2026.10.10-10 → 2026.10.10-12
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/CHANGELOG.md +62 -0
- package/dist/bundle/chunks/{anthropic-messages-2B35OVB7.js → anthropic-messages-I4Z6VKS3.js} +1 -1
- package/dist/bundle/chunks/{app-server-command-CV6N7JDD.js → app-server-command-EGTBOL5W.js} +2 -2
- package/dist/bundle/chunks/bun-extension-importer-QSQHKXVG.js +20 -0
- package/dist/bundle/chunks/{chunk-4WZF7G6N.js → chunk-2AYAOU6W.js} +12 -10
- package/dist/bundle/chunks/chunk-2ZGQRUGM.js +2506 -0
- package/dist/bundle/chunks/{chunk-ZPJHS64R.js → chunk-5BRVRFJI.js} +1 -1
- package/dist/bundle/chunks/chunk-6SBY4ZWC.js +2 -0
- package/dist/bundle/chunks/chunk-DRVT7RIO.js +2 -0
- package/dist/bundle/chunks/chunk-E75RO54O.js +14 -0
- package/dist/bundle/chunks/{chunk-ZCYTYHDN.js → chunk-IAYFQEXI.js} +1 -1
- package/dist/bundle/chunks/chunk-M4C6Z7UT.js +288 -0
- package/dist/bundle/chunks/chunk-N6HU6BEY.js +9 -0
- package/dist/bundle/chunks/chunk-NEFNNQSV.js +9 -0
- package/dist/bundle/chunks/{chunk-YI7SPFDN.js → chunk-Q3R44CGT.js} +2 -2
- package/dist/bundle/chunks/chunk-QKU6JOA4.js +2 -0
- package/dist/bundle/chunks/{chunk-JRGNL6WM.js → chunk-QXREUA5F.js} +1 -1
- package/dist/bundle/chunks/chunk-SIIACSBE.js +30 -0
- package/dist/bundle/chunks/{chunk-QQZREV6B.js → chunk-SSH4CLHJ.js} +1 -1
- package/dist/bundle/chunks/chunk-TOZBUPZP.js +3 -0
- package/dist/bundle/chunks/chunk-WASCMT6Y.js +2 -0
- package/dist/bundle/chunks/chunk-YU4AYH4C.js +2 -0
- package/dist/bundle/chunks/chunk-ZGCPUGLT.js +6 -0
- package/dist/bundle/chunks/{chunk-NTH33AXY.js → chunk-ZJOYLQXK.js} +1 -1
- package/dist/bundle/chunks/chunk-ZRWOLP4E.js +2 -0
- package/dist/bundle/chunks/cli-main-PANLBILV.js +3 -0
- package/dist/bundle/chunks/{help-fast-path-5P73752B.js → help-fast-path-IQAJFO2G.js} +1 -1
- package/dist/bundle/chunks/{host-command-MWQNTWFA.js → host-command-MWSVX37K.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle-X2J5FTJL.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +8 -8
- package/dist/bundle/chunks/interactive-mode-TQJU6K27.js +2 -0
- package/dist/bundle/chunks/multi-session-host-GBSMDUMG.js +26 -0
- package/dist/bundle/chunks/{package-manager-cli-PXP63ZPT.js → package-manager-cli-IBPABDGR.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-JXT3JYW5.js +2 -0
- package/dist/bundle/chunks/rpc-mode-PFIAS2E5.js +2 -0
- package/dist/bundle/chunks/runtime-session-I4NDNGC5.js +2 -0
- package/dist/bundle/chunks/{schedule-command-MGZLHARF.js → schedule-command-Q4W37FAP.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-YYFCJZXZ.js +3 -0
- package/dist/bundle/chunks/session-picker-YLDBGXTR.js +2 -0
- package/dist/bundle/chunks/session-worker.js +455 -448
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/cli/session-opening.d.ts +5 -0
- package/dist/cli/session-opening.js +11 -0
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.js +56 -33
- package/dist/core/engine-paused.d.ts +6 -0
- package/dist/core/engine-paused.js +50 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +9 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +22 -45
- package/dist/core/extensions/builtin/compaction/index.js +55 -9
- package/dist/core/extensions/builtin/compaction/rejected-recovery.d.ts +11 -0
- package/dist/core/extensions/builtin/compaction/rejected-recovery.js +73 -0
- package/dist/core/extensions/builtin/compaction/retained-message-projection.d.ts +10 -0
- package/dist/core/extensions/builtin/compaction/retained-message-projection.js +102 -0
- package/dist/core/extensions/builtin/goal/continuation.js +2 -0
- package/dist/core/extensions/builtin/goal/direct-input-lifecycle.js +3 -1
- package/dist/core/extensions/builtin/goal/elapsed-ticker.js +2 -0
- package/dist/core/extensions/builtin/goal/format.d.ts +1 -1
- package/dist/core/extensions/builtin/goal/format.js +19 -4
- package/dist/core/extensions/builtin/goal/index.js +16 -9
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +57 -13
- package/dist/core/extensions/builtin/goal/monitor-continuation.js +2 -1
- package/dist/core/extensions/builtin/goal/persistence.js +2 -0
- package/dist/core/extensions/builtin/goal/renderers.js +9 -4
- package/dist/core/extensions/builtin/goal/store.d.ts +5 -0
- package/dist/core/extensions/builtin/goal/store.js +44 -0
- package/dist/core/extensions/builtin/goal/types.d.ts +10 -0
- package/dist/core/extensions/builtin/goal/types.js +4 -0
- package/dist/core/extensions/builtin/goal/ui.js +6 -3
- package/dist/core/extensions/builtin/mcp/index.js +4 -2
- package/dist/core/extensions/builtin/mcp/service-connection.js +1 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/service.js +257 -74
- package/dist/core/extensions/builtin/terminal/process-identity.d.ts +1 -3
- package/dist/core/extensions/builtin/terminal/process-identity.js +1 -7
- package/dist/core/extensions/builtin/terminal/process-start-probe.js +11 -7
- package/dist/core/extensions/builtin/ttsr/index.js +19 -0
- package/dist/core/extensions/bun-extension-importer.d.ts +1 -1
- package/dist/core/extensions/bun-extension-importer.js +7 -3
- package/dist/core/extensions/extension-module-cache.d.ts +4 -3
- package/dist/core/extensions/extension-module-cache.js +8 -22
- package/dist/core/foreign-session-holders.d.ts +7 -0
- package/dist/core/foreign-session-holders.js +63 -0
- package/dist/core/moved-session-cwd.d.ts +7 -0
- package/dist/core/moved-session-cwd.js +23 -0
- package/dist/core/moved-sessions.d.ts +6 -0
- package/dist/core/moved-sessions.js +83 -24
- package/dist/core/resource-loader.js +5 -6
- package/dist/core/resume-target.js +3 -1
- package/dist/core/session-holders.d.ts +2 -1
- package/dist/core/session-holders.js +4 -4
- package/dist/core/session-manager.js +29 -10
- package/dist/core/webview/webview-readiness.d.ts +2 -0
- package/dist/core/webview/webview-readiness.js +9 -0
- package/dist/core/webview/webview-service.d.ts +4 -0
- package/dist/core/webview/webview-service.js +30 -5
- package/dist/main.js +14 -3
- package/dist/modes/app-server/daemon/process.d.ts +7 -1
- package/dist/modes/app-server/daemon/process.js +58 -6
- package/dist/modes/app-server/threads/goal-wire.js +2 -1
- package/dist/modes/interactive/interactive-mode.js +7 -0
- package/dist/modes/rpc/connection-handler.js +3 -2
- package/dist/modes/rpc/custom-capability.d.ts +2 -0
- package/dist/modes/rpc/custom-capability.js +2 -0
- package/dist/modes/rpc/host-capabilities.js +3 -1
- package/dist/modes/rpc/host-client-occupancy.d.ts +2 -1
- package/dist/modes/rpc/host-client-occupancy.js +3 -0
- package/dist/modes/rpc/host-daemon-registration.js +20 -6
- package/dist/modes/rpc/host-daemon-state.d.ts +17 -0
- package/dist/modes/rpc/host-daemon-state.js +60 -0
- package/dist/modes/rpc/host-ensure-start.js +13 -3
- package/dist/modes/rpc/host-ensure-stop.d.ts +1 -1
- package/dist/modes/rpc/host-ensure-stop.js +17 -4
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +20 -2
- package/dist/modes/rpc/host-gc-evidence.js +3 -0
- package/dist/modes/rpc/host-generations.js +4 -1
- package/dist/modes/rpc/host-legacy.d.ts +1 -1
- package/dist/modes/rpc/host-legacy.js +11 -2
- package/dist/modes/rpc/host-lifecycle-activity.d.ts +30 -0
- package/dist/modes/rpc/host-lifecycle-activity.js +136 -4
- package/dist/modes/rpc/host-lifecycle-launch.d.ts +4 -0
- package/dist/modes/rpc/host-lifecycle-launch.js +24 -1
- package/dist/modes/rpc/host-lifecycle-proxy.d.ts +2 -0
- package/dist/modes/rpc/host-lifecycle-proxy.js +4 -1
- package/dist/modes/rpc/host-lifecycle-scratch.js +5 -2
- package/dist/modes/rpc/host-lifecycle-shutdown.d.ts +1 -1
- package/dist/modes/rpc/host-lifecycle-shutdown.js +81 -37
- package/dist/modes/rpc/host-lifecycle.js +23 -1
- package/dist/modes/rpc/host-reservations.d.ts +2 -0
- package/dist/modes/rpc/host-reservations.js +61 -3
- package/dist/modes/rpc/host-stalled-evidence.js +17 -3
- package/dist/modes/rpc/host-stop-intent.d.ts +3 -0
- package/dist/modes/rpc/host-stop-intent.js +3 -0
- package/dist/modes/rpc/host-stop.js +4 -9
- package/dist/modes/rpc/host-successor.js +10 -3
- package/dist/modes/rpc/host-supervisor-log.d.ts +1 -0
- package/dist/modes/rpc/host-supervisor-log.js +9 -0
- package/dist/modes/rpc/multi-session-host.js +8 -6
- package/dist/modes/rpc/rpc-mode.d.ts +3 -1
- package/dist/modes/rpc/rpc-mode.js +3 -1
- package/dist/modes/rpc/rpc-types.d.ts +3 -1
- package/dist/modes/rpc/rpc-types.js +2 -0
- package/dist/modes/rpc/session-command-router.d.ts +1 -1
- package/dist/modes/rpc/session-command-router.js +18 -14
- package/dist/modes/rpc/session-held.d.ts +8 -0
- package/dist/modes/rpc/session-held.js +127 -0
- package/dist/modes/rpc/session-registry-types.d.ts +1 -1
- package/dist/modes/rpc/session-registry.d.ts +2 -0
- package/dist/modes/rpc/session-registry.js +4 -0
- package/dist/modes/rpc/session-worker-client.d.ts +3 -3
- package/dist/modes/rpc/session-worker-client.js +24 -12
- package/dist/modes/rpc/worker-session-claims.d.ts +15 -0
- package/dist/modes/rpc/worker-session-claims.js +61 -0
- package/dist/modes/rpc/worker-session-registry.d.ts +4 -0
- package/dist/modes/rpc/worker-session-registry.js +51 -8
- package/dist/utils/shell.d.ts +6 -2
- package/dist/utils/shell.js +20 -6
- package/docs/app-server.md +1 -1
- package/docs/rpc.md +75 -2
- package/docs/session-format.md +19 -0
- package/package.json +6 -6
- package/dist/bundle/chunks/bun-extension-importer-3TEDTSKJ.js +0 -20
- package/dist/bundle/chunks/chunk-5AKP2VFB.js +0 -16
- package/dist/bundle/chunks/chunk-6Y7VGPJB.js +0 -9
- package/dist/bundle/chunks/chunk-CIRZTP7W.js +0 -2
- package/dist/bundle/chunks/chunk-HKRW6HT5.js +0 -30
- package/dist/bundle/chunks/chunk-JEZWV7JW.js +0 -17
- package/dist/bundle/chunks/chunk-LR5EN45D.js +0 -7
- package/dist/bundle/chunks/chunk-MYVBK47X.js +0 -2
- package/dist/bundle/chunks/chunk-O6YOQUVX.js +0 -2773
- package/dist/bundle/chunks/chunk-TJPMB4VH.js +0 -2
- package/dist/bundle/chunks/chunk-U5KVIAHJ.js +0 -2
- package/dist/bundle/chunks/chunk-XMHO4QQN.js +0 -7
- package/dist/bundle/chunks/cli-main-TM4UFZVC.js +0 -3
- package/dist/bundle/chunks/host-lifecycle-B24G65GD.js +0 -3
- package/dist/bundle/chunks/interactive-mode-CBQW7WRK.js +0 -2
- package/dist/bundle/chunks/multi-session-host-4KXWGRNS.js +0 -25
- package/dist/bundle/chunks/rotation-stream-FQH63DMY.js +0 -2
- package/dist/bundle/chunks/rpc-mode-7WHJHMUP.js +0 -2
- package/dist/bundle/chunks/runtime-session-CWJNFRHY.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-OH7XV2FN.js +0 -3
- package/dist/bundle/chunks/session-picker-UUSW6YSU.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,62 @@
|
|
|
12
12
|
|
|
13
13
|
### Removed
|
|
14
14
|
|
|
15
|
+
## [2026.10.10-12] - 2026-10-10
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- RPC hosts can opt into their ensure caller's lifetime with `owner: "caller"`. After that process exits or is killed, the supervisor stops an idle host after a short grace instead of leaving the shard resident for the normal idle timeout. Surviving peers and active turns keep running; ownership is preserved across reuse and generation handoff. Unowned hosts require no owner filesystem watcher, watch exhaustion falls back to polling, owner identities are timezone-independent, and brief activity resets the grace window ([#3044](https://github.com/code-yeongyu/senpi/issues/3044)).
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- `senpi host stop` followed by `ensure` now waits for the old generation's host child to exit before starting a replacement ([#3054](https://github.com/code-yeongyu/senpi/issues/3054)).
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- Reloading a session releases the previous extension runner and reuses unchanged module graphs instead of retaining another generation. Edited lazy dependencies now invalidate the graph using the bytes actually compiled, including equal-size edits with preserved timestamps ([#3066](https://github.com/code-yeongyu/senpi/pull/3066) by [@jc01rho](https://github.com/jc01rho), [#3068](https://github.com/code-yeongyu/senpi/issues/3068)).
|
|
30
|
+
|
|
31
|
+
- RPC supervisors wait for their host child's observed exit and exit record before releasing ownership. A child still unobserved 30 seconds after SIGKILL leaves its generation, pointer and settings intact and produces a non-zero supervisor exit with the child PID in the log. Stop callers allow the full shutdown budget but cancel their deadline on normal exit, and owner-lifetime tests await OS exit events instead of treating pipe EOF as process exit ([#3054](https://github.com/code-yeongyu/senpi/issues/3054)).
|
|
32
|
+
|
|
33
|
+
- Required compaction no longer wedges when the newest retained message is unsafe. Recovery normalizes live values like session persistence, replaces unsafe tool results without breaking their call pairing, and omits unsafe signed turns only from replay. An unchanged terminal no-safe-suffix rejection is attempted once across automatic triggers and session reopen; provider and summarizer failures remain retryable instead of setting that latch. Recovery diagnostics are actionable and the original transcript is preserved ([#3060](https://github.com/code-yeongyu/senpi/issues/3060), [#3061](https://github.com/code-yeongyu/senpi/pull/3061)).
|
|
34
|
+
|
|
35
|
+
- A goal that stops auto-continuing because progress is stale now reads "Goal stopped: no progress (send a message or /goal resume)" instead of pursuing with a frozen timer. Extension-triggered turns accrue no goal tokens or time while it is stopped; the same turns still count for an active goal. Goal-tool and app-server status snapshots present the stop as paused. The recovery notice appears once at the stop and once on each session reopen, without restarting the goal or repeating on extension reload ([#3026](https://github.com/code-yeongyu/senpi/issues/3026)).
|
|
36
|
+
|
|
37
|
+
- The model-facing `get_goal` result now identifies stale stops with `continuation.status: "stale_stopped"` and explains that a user message or `/goal resume` resumes the goal. Regression coverage also pins both extension delivery paths after an active goal becomes stale in-session, preserving the committed usage at the stop ([#3053](https://github.com/code-yeongyu/senpi/pull/3053)).
|
|
38
|
+
|
|
39
|
+
- Polling `senpi host status` no longer restarts a dead owner's two-second host-exit grace. Observe-only reads follow the normal idle policy, while a dropped unclassified peer and activity on an existing connection still reset continuous quiescence ([#3044](https://github.com/code-yeongyu/senpi/issues/3044)).
|
|
40
|
+
|
|
41
|
+
### Removed
|
|
42
|
+
|
|
43
|
+
## [2026.10.10-11] - 2026-10-09
|
|
44
|
+
|
|
45
|
+
### Breaking Changes
|
|
46
|
+
|
|
47
|
+
### Added
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- When a goal stops continuing because progress is stale, its elapsed timer now stops instead of running indefinitely. Goal guard denials and engine self-stops are persisted as `goal-continuation-stopped` and `engine-paused` entries and delivered to RPC clients; a user message or `/goal resume` resets the goal stop. Failures publishing these new entries no longer interrupt goal timer cleanup, todo processing, guard events or stream-rule stop announcements ([#3007](https://github.com/code-yeongyu/senpi/issues/3007)).
|
|
54
|
+
|
|
55
|
+
- A scheduled prompt created in an OmO desktop thread before the desktop moved its data home now fires: the headless `--session` resume opens the session in the folder's new location instead of exiting with "Stored session working directory does not exist", and the job no longer ends in `failed/`. `--session <id>` and `--resume` find and open such a session from its new folder without offering a rebind, `--continue` continues it when it is the folder's most recently used session, and the resume picker lists it once. Only a folder the desktop's moved-folder record lists is mapped, and the session file is not rewritten ([#2990](https://github.com/code-yeongyu/senpi/issues/2990)).
|
|
56
|
+
|
|
57
|
+
- A multi-session RPC host refuses open/attach and every new session-writing RPC when another live process outside its daemon family holds the file, with typed `session_held` and pid/cwd data. Both guarded host runtimes advertise the exact `session_held` protocol capability; classic bindings do not. Open rechecks after holder publication and rolls back raced admission; stale holders clear automatically. Own workers and predecessor generations preserve existing reservation retry/reclaim semantics. Already-admitted turns finish if a holder arrives mid-turn. Interactive startup and `/resume` warn, including advisory lookup failures, without aborting ([#2951](https://github.com/code-yeongyu/senpi/issues/2951)).
|
|
58
|
+
|
|
59
|
+
- On Windows, stopping a command's process tree (a timed-out or cancelled bash command, hooks, shutdown) no longer uses `taskkill /T`, which could also kill an unrelated older process whose dead parent's pid the command now holds; the tree is computed from creation times and each process is ended by pid ([#2999](https://github.com/code-yeongyu/senpi/issues/2999)).
|
|
60
|
+
|
|
61
|
+
- When the session shuts down while a response is still streaming (for example on SIGTERM), the turn_end boundary now says the session shut down during the turn instead of reporting that it could not resolve the persisted assistant entry ID ([#2995](https://github.com/code-yeongyu/senpi/issues/2995)).
|
|
62
|
+
|
|
63
|
+
- When sessions that share one MCP service resolve different MCP configs (for example a main session and in-process sidecar sessions that load without extensions), one session's attach no longer makes every other session's MCP tools fail with "MCP session or server configuration was replaced.", no longer shuts down MCP servers another live session still declares, and no longer keeps running an MCP server that only a closed session declared ([#2597](https://github.com/code-yeongyu/senpi/issues/2597) by [@ferose](https://github.com/ferose)).
|
|
64
|
+
|
|
65
|
+
- When sessions that share one MCP service differ in project trust, environment or agent directory, a session's skill-declared MCP servers now expand `${VAR}` values under its own trust and environment, and every MCP server spawns, re-authenticates and reports auth status with the credentials of a session that declares it, instead of those of whichever session attached last ([#2986](https://github.com/code-yeongyu/senpi/issues/2986) by [@ferose](https://github.com/ferose)).
|
|
66
|
+
|
|
67
|
+
- A failed retirement of the Chrome a WebView used (for example when `taskkill` cannot run, or the CI readiness log cannot be written) no longer makes every later WebView launch and retirement in that process fail: the release that triggered it still fails with the error, CI's readiness log records it when it can be written, and the next launch and retirement run normally ([#2993](https://github.com/code-yeongyu/senpi/issues/2993)).
|
|
68
|
+
|
|
69
|
+
### Removed
|
|
70
|
+
|
|
15
71
|
## [2026.10.10-10] - 2026-10-09
|
|
16
72
|
|
|
17
73
|
### Breaking Changes
|
|
@@ -24,8 +80,14 @@
|
|
|
24
80
|
|
|
25
81
|
### Fixed
|
|
26
82
|
|
|
83
|
+
- When sessions that share one MCP service resolve different MCP configs (for example a main session and in-process sidecar sessions that load without extensions), one session's attach no longer makes every other session's MCP tools fail with "MCP session or server configuration was replaced.", no longer shuts down MCP servers another live session still declares, and no longer keeps running an MCP server that only a closed session declared ([#2597](https://github.com/code-yeongyu/senpi/issues/2597) by [@ferose](https://github.com/ferose)).
|
|
84
|
+
|
|
85
|
+
- When sessions that share one MCP service differ in project trust, environment or agent directory, a session's skill-declared MCP servers now expand `${VAR}` values under its own trust and environment, and every MCP server spawns, re-authenticates and reports auth status with the credentials of a session that declares it, instead of those of whichever session attached last ([#2986](https://github.com/code-yeongyu/senpi/issues/2986) by [@ferose](https://github.com/ferose)).
|
|
86
|
+
|
|
27
87
|
- When the session file refuses writes, an automatic-turn pause is still announced, a message from another session that arrives at the limit is settled instead of staying pending, and editing your message in `/tree` lifts a pause like sending a new one ([#2967](https://github.com/code-yeongyu/senpi/issues/2967); first listed under 2026.10.10-9 by mistake, it ships in this release).
|
|
28
88
|
|
|
89
|
+
- A failed retirement of the Chrome a WebView used (for example when `taskkill` cannot run, or the CI readiness log cannot be written) no longer makes every later WebView launch and retirement in that process fail: the release that triggered it still fails with the error, CI's readiness log records it when it can be written, and the next launch and retirement run normally ([#2993](https://github.com/code-yeongyu/senpi/issues/2993)).
|
|
90
|
+
|
|
29
91
|
- On Windows, ending a Chrome-backed WebView no longer force-kills unrelated system processes, including the CI runner itself. The cleanup listed Chrome's process tree by recorded parent pid, which Windows never updates when a parent exits and reuses quickly, so a Chrome process that got a dead process's pid pulled whole system trees into the kill list (measured: 145 processes, `csrss.exe` and `wininit.exe` among them). A process now counts as Chrome's child only when it started after the parent it names, and protected system images or ancestors of the current process are never killed even if adopted ([#2353](https://github.com/code-yeongyu/senpi/issues/2353)).
|
|
30
92
|
|
|
31
93
|
- Anthropic Subscription with `resumeMode: "off"` no longer re-writes the whole conversation to the prompt cache every turn: the rebuilt history ends at a cache breakpoint, so each turn reads the earlier conversation from cache and writes only what is new. The breakpoint uses the same cache lifetime Claude Code is pinned to on the managed subscription lanes (1 hour unless `CLAUDE_CODE_PROMPT_CACHE_TTL` says otherwise). A repeated ultrawork directive no longer changes earlier history, a changed one is kept in full, and the "continuity disabled" notice says whether the environment variable, project settings or global settings turned resume off ([#2982](https://github.com/code-yeongyu/senpi/issues/2982)).
|
package/dist/bundle/chunks/{anthropic-messages-2B35OVB7.js → anthropic-messages-I4Z6VKS3.js}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{normalizeToolCallId}from"./chunk-T6IYKWIH.js";import{resolveCloudflareBaseUrl}from"./chunk-OZNCR6E6.js";import{anthropicProviderDiagnosticFromError,anthropicProviderDiagnosticFromSseData,awaitProviderTransport,formatGitHubCopilotToolLimitError,limitGitHubCopilotTools,recordGitHubCopilotToolLimit,withGitHubCopilotFailureNote}from"./chunk-ZABLYCHT.js";import{getPiUserAgent}from"./chunk-QTG7MY2X.js";import{combineAbortSignals}from"./chunk-SJ5DSOBX.js";import{ANTHROPIC_RESERVED_BODY_KEYS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext}from"./chunk-RLFQICEY.js";import{retryProviderRequest}from"./chunk-GQ3YLXVZ.js";import{claudeCodeVersionTooOldHint,getClaudeCodeVersion,isClaudeCodeVersionTooOldError,recoverClaudeCodeVersion
|
|
2
|
+
import{normalizeToolCallId}from"./chunk-T6IYKWIH.js";import{resolveCloudflareBaseUrl}from"./chunk-OZNCR6E6.js";import{anthropicProviderDiagnosticFromError,anthropicProviderDiagnosticFromSseData,awaitProviderTransport,formatGitHubCopilotToolLimitError,limitGitHubCopilotTools,recordGitHubCopilotToolLimit,withGitHubCopilotFailureNote}from"./chunk-ZABLYCHT.js";import{getPiUserAgent}from"./chunk-QTG7MY2X.js";import{combineAbortSignals}from"./chunk-SJ5DSOBX.js";import{ANTHROPIC_RESERVED_BODY_KEYS,adjustMaxTokensForThinking,buildBaseOptions,clampMaxTokensToContext}from"./chunk-RLFQICEY.js";import{retryProviderRequest}from"./chunk-GQ3YLXVZ.js";import{claudeCodeVersionTooOldHint,getClaudeCodeVersion,isClaudeCodeVersionTooOldError,recoverClaudeCodeVersion}from"./chunk-QXREUA5F.js";import{resolveToolNameMatch}from"./chunk-WASCMT6Y.js";import{ANTHROPIC_FEDERATION_RULE_ID_ENV,ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,ANTHROPIC_ORGANIZATION_ID_ENV,ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,ANTHROPIC_WORKSPACE_ID_ENV,applyServerFallbackAbort,applyServerFallbackContinuation,parseServerFallbackReceipt,parseStickyFallbackReceipt,sanitizeAnthropicToolPairs}from"./chunk-RKJNJ3GI.js";import{resolveRootObjectSchema}from"./chunk-CWLCGRUS.js";import{getAnthropicCompat,isAnthropicApiBaseUrl}from"./chunk-6WCOSBI7.js";import{sendWithForcedToolChoiceFallback}from"./chunk-I5HLTDT4.js";import{buildCopilotDynamicHeaders,hasCopilotVisionInput}from"./chunk-KRNXUTZJ.js";import{readProviderDiagnostic}from"./chunk-YOPVJDSU.js";import{registerSessionResourceCleanup}from"./chunk-WHPDEDCC.js";import{splitDeferredTools}from"./chunk-HK46JMSC.js";import{getJsonSchemaToolParameters,isVideoMimeType,resolveJsonSchemaStrictSampling,transformMessages}from"./chunk-VYKBN4MR.js";import{sanitizeSurrogates}from"./chunk-WDTJ6JKE.js";import{getProviderEnvValue}from"./chunk-5ROMKDLK.js";import{parseJsonWithRepair,parseStreamingJson}from"./chunk-3W47LTXQ.js";import{attachProviderDiagnostic}from"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import{appendRetryAfterMsMarker,extract429RetryAfterMs}from"./chunk-PELNNWGO.js";import{calculateCost,getCurrentTools,getDeclaredTools,getInitialSystemMessage,getSystemMessageText,hasToolRedefinitions,normalizeContext,renderSystemMessageUpdate,resolveTranscript}from"./chunk-L4HVJWIF.js";import{AssistantMessageEventStream,appendAssistantMessageDiagnostic}from"./chunk-DMI55M2N.js";import{headersToRecord,providerHeadersToRecord}from"./chunk-PJ34QVL5.js";import{Anthropic}from"./chunk-PUTWVHNH.js";import"./chunk-IKOFCODM.js";var MAX_MESSAGE_CHARS=500,QUOTA_WORDING_PATTERN=/exceeded_current_quota_error|insufficient\s+balance|credits?_required|quota|billing/i,IMAGE_FORMAT_PATTERN=/unsupported image format|unsupported media type for base64 image|invalid data url for image/i;function sdkErrorClassName(error){if(!(error instanceof Error))return;let name=error.constructor?.name;return typeof name=="string"&&name.length>0?name:void 0}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function toShaped(error){return error instanceof Error?error:void 0}function numericStatus(shaped){let status=shaped?.status;return typeof status=="number"&&Number.isFinite(status)?status:void 0}function headerObject(shaped){return shaped?.headers instanceof Headers?shaped.headers:void 0}function nestedProviderCodes(body){if(!isRecord(body))return;let inner=body.error;if(!isRecord(inner))return;let codes=[];for(let key of["type","code"]){let value=inner[key];typeof value=="string"&&value.length>0&&codes.push(value)}return codes.length>0?codes:void 0}function parseLeadingJson(text){let candidate=text.slice(text.indexOf("{"),text.lastIndexOf("}")+1);if(!(!candidate.startsWith("{")||!candidate.endsWith("}")))try{return JSON.parse(candidate)}catch{return}}function quotaWording(shaped,bodyText){return[shaped?.message,bodyText].some(text=>typeof text=="string"&"A_WORDING_PATTERN.test(text))}function normalizeAnthropicRetryFailure(error,context){let message=error instanceof Error?error.message:String(error),shaped=toShaped(error),status=numericStatus(shaped),headers=headerObject(shaped),bodyText=context?.bodyText??message,kind,providerCodes;if(error instanceof Error&&error.name==="AbortError")kind="abort";else if(sdkErrorClassName(error)==="APIConnectionTimeoutError")kind="timeout";else if(sdkErrorClassName(error)==="APIConnectionError")kind="connection";else if(typeof message=="string"&&IMAGE_FORMAT_PATTERN.test(message))kind="image-format";else if(status!==void 0)kind=status===429&"aWording(shaped,bodyText)?"quota-exhausted":"http-status",providerCodes=nestedProviderCodes(shaped?.error);else{let parsed=parseLeadingJson(bodyText);providerCodes=nestedProviderCodes(parsed),kind=providerCodes!==void 0?"provider":"unknown"}let retryAfterMs=extract429RetryAfterMs({status,headers,bodyText}),shouldRetryHeader=headers?.get("x-should-retry"),shouldRetry=shouldRetryHeader==="true"?!0:shouldRetryHeader==="false"?!1:void 0;return{origin:"anthropic-messages",kind,message:message.slice(0,MAX_MESSAGE_CHARS),...status!==void 0?{statusCode:status}:{},...providerCodes!==void 0?{providerCodes}:{},...retryAfterMs!==void 0?{retryAfterMs}:{},...shouldRetry!==void 0?{shouldRetry}:{}}}function escapeXmlAttribute(value){return value.replaceAll("&","&").replaceAll('"',""").replaceAll("'","'").replaceAll("<","<").replaceAll(">",">")}function availableToolGuidance(availableToolNames){if(availableToolNames.length===0)return"To edit files, call only tools available in this request.";let listed=availableToolNames.slice(0,8).join(", "),omitted=availableToolNames.length-8,suffix=omitted>0?` (and ${omitted} more)`:"";return`To edit files, call your own tools: ${listed}${suffix}.`}function demotedToolCallText(name,availableToolNames,firstOccurrence){let escapedName=escapeXmlAttribute(name);return firstOccurrence?[`<unavailable-tool-call name="${escapedName}">`,"Transcript record, not an action available to you. An earlier model in this session",`called "${escapedName}"; that tool does not exist for you and its input is omitted.`,availableToolGuidance(availableToolNames),"</unavailable-tool-call>"].join(`
|
|
3
3
|
`):`<unavailable-tool-call name="${escapedName}"/>`}function demotedToolResultText(name,content){let escapedName=escapeXmlAttribute(name),safeContent=content.replace(/<\/unavailable-tool-result/gi,match=>`<${match.slice(1)}`);return`<unavailable-tool-result name="${escapedName}">${safeContent}</unavailable-tool-result>`}function isRecord2(value){return typeof value=="object"&&value!==null}function collectAvailableToolNames(tools){let defined=new Set;if(Array.isArray(tools))for(let tool of tools)isRecord2(tool)&&typeof tool.name=="string"&&defined.add(tool.name);return defined}function isNativeToolSearchResultBlock(block){return isRecord2(block)&&block.type==="tool_search_tool_result"&&typeof block.tool_use_id=="string"&&isRecord2(block.content)&&Array.isArray(block.content.tool_references)}function demoteUnavailableToolReferences(params){let messages=params.messages;if(!Array.isArray(messages)||messages.length===0)return params;let available=collectAvailableToolNames(params.tools),resolve=name=>resolveToolNameMatch(name,available),demotedCallNames=new Map,renamedCallNames=new Map;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content){if(!isRecord2(block)||block.type!=="tool_use"||typeof block.name!="string")continue;let resolved=resolve(block.name);resolved===void 0?demotedCallNames.set(block.id,block.name):resolved!==block.name&&renamedCallNames.set(block.id,resolved)}let changed=!1,availableToolNames=[...available],droppedSearchUseIds=new Set,droppedSearchNames=new Map;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content){if(!isNativeToolSearchResultBlock(block))continue;let names=block.content.tool_references.filter(item=>isRecord2(item)&&item.type==="tool_reference").map(item=>typeof item.tool_name=="string"?item.tool_name:"");names.length>0&&names.every(name=>resolve(name)===void 0)&&(droppedSearchUseIds.add(block.tool_use_id),droppedSearchNames.set(block.tool_use_id,names))}let seenDemotedCallNames=new Set,rewrittenMessages=[];for(let message of messages){if(!Array.isArray(message.content)){rewrittenMessages.push(message);continue}let messageChanged=!1,content=[];for(let block of message.content){if(message.role==="assistant"&&isRecord2(block)&&block.type==="tool_use"){let demotedName=demotedCallNames.get(block.id);if(demotedName!==void 0){messageChanged=!0;let firstOccurrence=!seenDemotedCallNames.has(demotedName);seenDemotedCallNames.add(demotedName),content.push({type:"text",text:demotedToolCallText(demotedName,availableToolNames,firstOccurrence)});continue}let renamedName=renamedCallNames.get(block.id);if(renamedName!==void 0){messageChanged=!0,content.push({...block,name:renamedName});continue}}if(message.role==="assistant"&&isRecord2(block)&&block.type==="server_tool_use"&&typeof block.id=="string"&&droppedSearchUseIds.has(block.id)){messageChanged=!0;continue}if(message.role==="assistant"&&isNativeToolSearchResultBlock(block)){let omitted=droppedSearchNames.get(block.tool_use_id);if(omitted!==void 0){messageChanged=!0,content.push({type:"text",text:`Tool reference unavailable: ${[...new Set(omitted)].join(", ")}`});continue}let rewritten=rewriteToolReferenceItems(block.content.tool_references,resolve);if(rewritten!==void 0){messageChanged=!0,content.push({...block,content:{...block.content,tool_references:rewritten.kept}});continue}}if(isRecord2(block)&&block.type==="tool_result"){let demotedName=demotedCallNames.get(block.tool_use_id);if(demotedName!==void 0){messageChanged=!0,content.push({type:"text",text:demotedToolResultText(demotedName,toolResultText(block.content))});continue}if(Array.isArray(block.content)){let rewritten=rewriteToolReferenceItems(block.content,resolve);if(rewritten!==void 0){messageChanged=!0;let nextContent=rewritten.kept.length>0?rewritten.kept:[{type:"text",text:`Tool reference unavailable: ${[...new Set(rewritten.omitted)].join(", ")}`}];content.push({...block,content:nextContent});continue}}}content.push(block)}if(messageChanged&&content.length===0){changed=!0;continue}if(messageChanged){changed=!0,rewrittenMessages.push({...message,content});continue}rewrittenMessages.push(message)}return changed?{...params,messages:rewrittenMessages}:params}function demoteToolReferenceReplay(params){let messages=params.messages;if(!Array.isArray(messages)||messages.length===0)return params;let searchUseIds=new Set;for(let message of messages)if(!(message.role!=="assistant"||!Array.isArray(message.content)))for(let block of message.content)isRecord2(block)&&block.type==="tool_search_tool_result"&&typeof block.tool_use_id=="string"&&searchUseIds.add(block.tool_use_id);let changed=!1,demotedNames=new Set,rewrittenMessages=[];for(let message of messages){if(!Array.isArray(message.content)){rewrittenMessages.push(message);continue}let messageChanged=!1,content=[];for(let block of message.content){if(message.role==="assistant"&&isRecord2(block)){if(block.type==="server_tool_use"&&typeof block.id=="string"&&searchUseIds.has(block.id)){messageChanged=!0;continue}if(block.type==="tool_search_tool_result"){messageChanged=!0;let names=isNativeToolSearchResultBlock(block)?toolReferenceNames(block.content.tool_references):[];for(let name of names)demotedNames.add(name);content.push({type:"text",text:names.length>0?`Tool search found: ${names.join(", ")}`:"Tool search found no tools."});continue}}if(isRecord2(block)&&block.type==="tool_result"&&Array.isArray(block.content)){let names=toolReferenceNames(block.content);if(names.length>0){messageChanged=!0;for(let name of names)demotedNames.add(name);let kept=block.content.filter(item=>!(isRecord2(item)&&item.type==="tool_reference"));content.push({...block,content:[...kept,{type:"text",text:`Tools loaded: ${names.join(", ")}`}]});continue}}content.push(block)}if(!messageChanged){rewrittenMessages.push(message);continue}changed=!0,content.length>0&&rewrittenMessages.push({...message,content})}return changed?{...params,messages:rewrittenMessages,...residentTools(params.tools,demotedNames)}:params}function residentTools(tools,names){if(!Array.isArray(tools)||names.size===0)return{};let changed=!1,rewritten=tools.map(tool=>{if(!isRecord2(tool)||tool.defer_loading!==!0||typeof tool.name!="string"||!names.has(tool.name))return tool;changed=!0;let{defer_loading:_deferLoading,...resident}=tool;return resident});return changed?{tools:rewritten}:{}}function toolReferenceNames(items){let names=new Set;for(let item of items)isRecord2(item)&&item.type==="tool_reference"&&typeof item.tool_name=="string"&&names.add(item.tool_name);return[...names]}function rewriteToolReferenceItems(items,resolve){let kept=[],omitted=[],rewritten=!1;for(let item of items){if(!isRecord2(item)||item.type!=="tool_reference"||typeof item.tool_name!="string"){kept.push(item);continue}let resolved=resolve(item.tool_name);if(resolved===void 0){omitted.push(item.tool_name),rewritten=!0;continue}if(resolved!==item.tool_name){kept.push({...item,tool_name:resolved}),rewritten=!0;continue}kept.push(item)}return rewritten?{kept,omitted}:void 0}function toolResultText(content){if(typeof content=="string")return content;if(Array.isArray(content)){let parts=[];for(let item of content)isRecord2(item)&&(item.type==="text"&&typeof item.text=="string"?parts.push(item.text):typeof item.type=="string"&&parts.push(`[${item.type}]`));if(parts.length>0)return parts.join(`
|
|
4
4
|
`)}return"Tool output unavailable."}function resolveCacheRetention(cacheRetention,env,fallback="short"){return cacheRetention||(getProviderEnvValue("PI_CACHE_RETENTION",env)==="long"?"long":typeof process<"u"&&process.env.PI_CACHE_RETENTION!==void 0?"short":fallback)}function getCacheControl(model,cacheRetention,env){let retention=resolveCacheRetention(cacheRetention,env,"short");if(retention==="none")return{retention};let ttl=retention==="long"&&isAnthropicApiBaseUrl(model.baseUrl)&&getAnthropicCompat(model).supportsLongCacheRetention?"1h":void 0;return{retention,cacheControl:{type:"ephemeral",...ttl&&{ttl}}}}var claudeCodeVersion="2.1.292",claudeCodeTools=["Read","Write","Edit","Bash","Grep","Glob","AskUserQuestion","EnterPlanMode","ExitPlanMode","KillShell","NotebookEdit","Skill","Task","TaskOutput","TodoWrite","WebFetch","WebSearch"],ccToolLookup=new Map(claudeCodeTools.map(t=>[t.toLowerCase(),t])),ccToolAliases=new Map([["ask_user_question","AskUserQuestion"]]),toClaudeCodeName=name=>ccToolAliases.get(name)??ccToolLookup.get(name.toLowerCase())??name,fromClaudeCodeName=(name,tools)=>{if(tools&&tools.length>0){let alias=[...ccToolAliases].find(([,wireName])=>wireName===name);if(alias&&tools.some(tool=>tool.name===alias[0]))return alias[0];let lowerName=name.toLowerCase(),matchedTool=tools.find(tool=>tool.name.toLowerCase()===lowerName);if(matchedTool)return matchedTool.name}return name};function convertContentBlocks(content){if(!content.some(c=>c.type==="image"))return sanitizeSurrogates(content.map(c=>c.text).join(`
|
|
5
5
|
`));let blocks=content.map(block=>block.type==="text"?{type:"text",text:sanitizeSurrogates(block.text)}:isVideoMimeType(block.mimeType)?{type:"video",source:{type:"base64",media_type:block.mimeType,data:block.data}}:{type:"image",source:{type:"base64",media_type:block.mimeType,data:block.data}});return blocks.some(b=>b.type==="text")||blocks.unshift({type:"text",text:"(see attached image)"}),blocks}var FINE_GRAINED_TOOL_STREAMING_BETA="fine-grained-tool-streaming-2025-05-14",INTERLEAVED_THINKING_BETA="interleaved-thinking-2025-05-14",COMPUTER_USE_BETA_PREFIX="computer-use-",NATIVE_COMPUTER_TOOL_TYPE="computer_20250124",ADAPTIVE_THINKING_MODEL_MARKERS=["opus-4-6","opus-4-7","opus-4-8","opus-5","sonnet-4-6","sonnet-5","haiku-5-5","fable-5","mythos-5"],NATIVE_XHIGH_EFFORT_MODEL_MARKERS=["opus-4-7","opus-4-8","opus-5","sonnet-5","haiku-5-5","fable-5","mythos-5"],DISABLED_THINKING_REJECTING_MODEL_MARKERS=["fable-5","mythos-5","opus-5-5","opus-5.5","sonnet-5-5","sonnet-5.5","haiku-5-5","haiku-5.5"],UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS=["opus-4-6","opus-4.6","opus-4-7","opus-4.7","opus-4-8","opus-4.8"],SERVER_SIDE_FALLBACK_BETA="server-side-fallback-2026-07-01";function shouldUseServerSideFallbackBeta(model){return(model.compat?.allowedFallbackModels?.length??0)>0}var MID_CONVERSATION_OUTPUT_CONFIG_BETA="mid-conversation-output-config-2026-07-01",THINKING_BINDING_CONTROLS_BETA="thinking-binding-controls-2026-08-01",MID_CONVERSATION_TOOL_CHANGES_BETA="mid-conversation-tool-changes-2026-07-01",DEFERRED_TOOL_PLACEHOLDER={name:"__pi_deferred_placeholder__",description:"Reserved placeholder. Never available. Never call this.",input_schema:{type:"object",properties:{},required:[]},defer_loading:!0};function supportsMidConvoSystemMessages(model){return model.compat?.supportsMidConvoSystemMessages??!1}function supportsMidConvoToolChanges(model){return model.compat?.supportsMidConvoToolChanges??!1}var unsignedThinkingTextReplayFallbacks=new Set,toolReferenceReplayFallbacks=new Set;registerSessionResourceCleanup(sessionId=>{if(sessionId===void 0){unsignedThinkingTextReplayFallbacks.clear(),toolReferenceReplayFallbacks.clear();return}let prefix=`${sessionId}\0`;for(let fallbacks of[unsignedThinkingTextReplayFallbacks,toolReferenceReplayFallbacks])for(let key of fallbacks)key.startsWith(prefix)&&fallbacks.delete(key)});function unsignedThinkingFallbackKey(model,sessionId){return sessionId===void 0?void 0:`${sessionId}\0${model.baseUrl}\0${model.id}`}function isInvalidUnsignedThinkingSignatureError(error){return typeof error=="object"&&error!==null&&"status"in error&&error.status===400&&error instanceof Error&&/Invalid signature in thinking block/i.test(error.message)}function isToolReferenceNotFoundError(error){return error instanceof Error&&"status"in error&&error.status===400&&/Tool reference '[^']*' not found in available tools/i.test(error.message)}function mergeHeaders(...headerSources){let merged={};for(let headers of headerSources)headers&&Object.assign(merged,headers);return merged}function mergeClientHeaders(_model,...headerSources){return mergeHeaders({"User-Agent":getPiUserAgent()},...headerSources)}function hasHeader(headers,name){if(!headers)return!1;let expected=name.toLowerCase();for(let[key,value]of Object.entries(headers))if(key.toLowerCase()===expected&&value!==null&&value.trim().length>0)return!0;return!1}function hasRequestAuth(apiKey,headers){return!!apiKey||hasHeader(headers,"authorization")||hasHeader(headers,"x-api-key")||hasHeader(headers,"cf-aig-authorization")}function assertRequestAuth(provider,apiKey,headers){if(!hasRequestAuth(apiKey,headers))throw new Error(`No API key for provider: ${provider}`)}var PiAnthropic=class extends Anthropic{_shouldResolveDefaultCredentials(){return!1}};function getAnthropicFederation(model,apiKey,headers,env){if(model.provider!=="anthropic"||hasRequestAuth(apiKey,headers))return;let federationRuleId=getProviderEnvValue(ANTHROPIC_FEDERATION_RULE_ID_ENV,env),organizationId=getProviderEnvValue(ANTHROPIC_ORGANIZATION_ID_ENV,env),identityTokenFile=getProviderEnvValue(ANTHROPIC_IDENTITY_TOKEN_FILE_ENV,env);if(!(!federationRuleId||!organizationId||!identityTokenFile))return{organization_id:organizationId,workspace_id:getProviderEnvValue(ANTHROPIC_WORKSPACE_ID_ENV,env),authentication:{type:"oidc_federation",federation_rule_id:federationRuleId,service_account_id:getProviderEnvValue(ANTHROPIC_SERVICE_ACCOUNT_ID_ENV,env),identity_token:{source:"file",path:identityTokenFile}}}}var federationClient;function isRecord3(value){return typeof value=="object"&&value!==null}var REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES=new Set(["server_tool_use","web_search_tool_result","web_fetch_tool_result","code_execution_tool_result","bash_code_execution_tool_result","text_editor_code_execution_tool_result","tool_search_tool_result","container_upload"]);function isReplayableAnthropicProviderNativeBlock(raw){return isRecord3(raw)&&typeof raw.type=="string"&&REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type)}function isSameAnthropicModel(message,model){return message.provider===model.provider&&message.api===model.api&&message.model===model.id}function isAnthropicFallbackMarkerBlock(block){return block.type==="providerNative"&&block.subtype==="fallback"&&isRecord3(block.raw)&&block.raw.type==="fallback"}function lastAnthropicFallbackBoundary(content){let boundary=-1;for(let index=0;index<content.length;index++)isAnthropicFallbackMarkerBlock(content[index])&&(boundary=index);return boundary}function isAnthropicServerToolUseBlock(raw){return isRecord3(raw)&&raw.type==="server_tool_use"&&typeof raw.id=="string"}function isProviderNativeToolUseBlock(raw){return isRecord3(raw)&&(raw.type==="server_tool_use"||raw.type==="mcp_tool_use")}function isAnthropicWebSearchReplayBlock(raw){return isRecord3(raw)?raw.type==="web_search_tool_result"?!0:raw.type==="server_tool_use"&&raw.name==="web_search":!1}function userMessageClosesServerTurn(message){return typeof message.content=="string"?message.content.trim().length>0:message.content.some(block=>block.type==="text"&&block.text.trim().length>0||block.type==="image")}function collectProviderNativeToolPairing(messages,model,deferredToolNames,normalizeToolName,discardedFallbackToolCallIds){let resolvedUseIds=new Set,validResultIds=new Set,pendingUseIds=new Set,loadedReferenceNames=new Set;for(let message of messages){if(message.role==="assistant"){let priorUseIds=pendingUseIds;if(pendingUseIds=new Set,!isSameAnthropicModel(message,model))continue;for(let block of message.content){if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let raw=block.raw;typeof raw.type!="string"||!REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type)||isProviderNativeToolUseBlock(raw)&&typeof raw.id=="string"&&pendingUseIds.add(raw.id)}for(let block of message.content){if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let raw=block.raw;if(typeof raw.type!="string"||!REPLAYABLE_ANTHROPIC_PROVIDER_NATIVE_TYPES.has(raw.type))continue;let toolUseId=raw.tool_use_id;typeof toolUseId=="string"&&(priorUseIds.has(toolUseId)||pendingUseIds.has(toolUseId))&&(resolvedUseIds.add(toolUseId),validResultIds.add(toolUseId))}continue}if(message.role==="toolResult"){if(discardedFallbackToolCallIds.has(message.toolCallId))continue;let emitsReferences=!1;for(let name of message.addedToolNames??[]){let normalizedName=normalizeToolName(name);!deferredToolNames.has(normalizedName)||loadedReferenceNames.has(normalizedName)||(loadedReferenceNames.add(normalizedName),emitsReferences=!0)}emitsReferences&&(pendingUseIds=new Set);continue}message.role==="user"&&userMessageClosesServerTurn(message)&&(pendingUseIds=new Set)}return{resolvedUseIds,liveUseIds:pendingUseIds,validResultIds}}function isUnpairedProviderNativeToolBlock(raw,pairing){if(!isRecord3(raw))return!1;if(isProviderNativeToolUseBlock(raw))return typeof raw.id!="string"||!(pairing.resolvedUseIds.has(raw.id)||pairing.liveUseIds.has(raw.id));let toolUseId=raw.tool_use_id;return typeof toolUseId=="string"&&!pairing.validResultIds.has(toolUseId)}function pairedServerToolUseIdsBeforeBoundary(content,boundary){let paired=new Set;for(let index=0;index<boundary;index++){let block=content[index];if(block.type!=="providerNative"||!isRecord3(block.raw))continue;let toolUseId=block.raw.tool_use_id;typeof toolUseId=="string"&&paired.add(toolUseId)}return paired}function collectDiscardedFallbackToolCallIds(messages,model){let discarded=new Set;for(let message of messages){if(message.role!=="assistant"||!isSameAnthropicModel(message,model))continue;let boundary=lastAnthropicFallbackBoundary(message.content);if(!(boundary<0))for(let index=0;index<boundary;index++){let block=message.content[index];block.type==="toolCall"&&discarded.add(block.id)}}return discarded}function stringRecord(value){if(!isRecord3(value))return;let entries=Object.entries(value);if(!entries.some(([,item])=>typeof item!="string"))return Object.fromEntries(entries)}function isForcedAnthropicToolChoice(toolChoice){return isRecord3(toolChoice)&&(toolChoice.type==="any"||toolChoice.type==="tool")}function extractPayloadRequestMetadata(params){let payload=params,headers=stringRecord(payload.headers);if(!("headers"in payload)&&!("extra_body"in payload))return headers?{params,headers}:{params};let stripped={...payload};return delete stripped.headers,delete stripped.extra_body,headers?{params:stripped,headers}:{params:stripped}}function removeAnthropicBetaHeaders(headers,shouldRemoveBeta){if(!headers)return{changed:!1};let nextHeaders={},changed=!1;for(let[key,value]of Object.entries(headers)){if(key.toLowerCase()!=="anthropic-beta"||value===null){nextHeaders[key]=value;continue}let betas=value.split(",").map(beta=>beta.trim()).filter(beta=>beta.length>0),supportedBetas=betas.filter(beta=>!shouldRemoveBeta(beta));changed=changed||supportedBetas.length!==betas.length,supportedBetas.length>0&&(nextHeaders[key]=supportedBetas.join(", "))}return changed?{changed:!0,headers:Object.keys(nextHeaders).length>0?nextHeaders:void 0}:{changed:!1,headers}}function removeComputerUseBetaHeader(headers){return removeAnthropicBetaHeaders(headers,beta=>beta.startsWith(COMPUTER_USE_BETA_PREFIX))}function sanitizeAdaptiveThinkingHeaders(model,headers){if(!supportsAdaptiveThinking(model))return headers;let headerSanitization=removeAnthropicBetaHeaders(headers,beta=>beta===INTERLEAVED_THINKING_BETA);return headerSanitization.changed?headerSanitization.headers??{}:headers}function rejectsNativeComputerTool(model,toolType){return model.provider==="cloudflare-ai-gateway"&&model.baseUrl.includes("anthropic")?toolType.startsWith("computer_"):matchesModelMarker(model,UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS)&&toolType===NATIVE_COMPUTER_TOOL_TYPE}function rejectsComputerUseBeta(model){return model.provider==="cloudflare-ai-gateway"&&model.baseUrl.includes("anthropic")||matchesModelMarker(model,UNSUPPORTED_NATIVE_COMPUTER_TOOL_MODEL_MARKERS)}function isAnthropicWebSearchToolType(toolType){return toolType.startsWith("web_search_")}function sanitizeUnsupportedNativeTools(model,params){let payload=params,headers=stringRecord(payload.headers),headerSanitization=rejectsComputerUseBeta(model)?removeComputerUseBetaHeader(headers):{changed:!1},rejectsNativeWebSearch=!getAnthropicCompat(model).supportsWebSearch,tools=payload.tools,sanitized={...payload},changed=!1;if(Array.isArray(tools)){let supportedTools=[];for(let tool of tools){let hookTool=tool;if(isRecord3(hookTool)&&typeof hookTool.type=="string"&&(rejectsNativeComputerTool(model,hookTool.type)||rejectsNativeWebSearch&&isAnthropicWebSearchToolType(hookTool.type))){changed=!0;continue}supportedTools.push(tool)}changed&&(supportedTools.length>0?sanitized.tools=supportedTools:delete sanitized.tools)}if(headerSanitization.changed&&(changed=!0,headerSanitization.headers?sanitized.headers=headerSanitization.headers:delete sanitized.headers),changed&&isRecord3(sanitized.tool_choice)){let toolChoiceName=sanitized.tool_choice.name,hasSelectedTool=typeof toolChoiceName=="string"&&Array.isArray(sanitized.tools)&&sanitized.tools.some(tool=>isRecord3(tool)&&tool.name===toolChoiceName);(sanitized.tools===void 0||typeof toolChoiceName=="string"&&!hasSelectedTool)&&delete sanitized.tool_choice}return changed?sanitized:params}function httpStatusOfError(error){if(!isRecord3(error))return;let status=error.status;return typeof status=="number"&&Number.isInteger(status)&&status>=100&&status<600?status:void 0}function sanitizeAdaptiveThinkingPayload(model,params,options){if(!supportsAdaptiveThinking(model))return params;let payload=params,headers=stringRecord(payload.headers),headerSanitization=removeAnthropicBetaHeaders(headers,beta=>beta===INTERLEAVED_THINKING_BETA),sanitized={...payload},changed=!1,thinking=isRecord3(payload.thinking)?payload.thinking:void 0;if(thinking?.type==="enabled"){let display=thinking.display==="omitted"||thinking.display==="summarized"?thinking.display:options?.thinkingDisplay??"summarized";sanitized.thinking={type:"adaptive",display},options?.effort!==void 0&&!isRecord3(payload.output_config)&&(sanitized.output_config={effort:options.effort}),changed=!0}return headerSanitization.changed&&(changed=!0,headerSanitization.headers?sanitized.headers=headerSanitization.headers:delete sanitized.headers),changed?sanitized:params}function isCacheableUserContentBlock(block){return block?.type==="text"||block?.type==="image"||block?.type==="tool_result"}function appendUserBlocks(params,newBlocks){if(newBlocks.length===0)return;let lastParam=params[params.length-1];lastParam?.role==="user"?typeof lastParam.content=="string"?lastParam.content=[{type:"text",text:lastParam.content},...newBlocks]:Array.isArray(lastParam.content)&&lastParam.content.push(...newBlocks):params.push({role:"user",content:newBlocks})}function isToolLoopContinuation(messages){let tail=messages[messages.length-1],preceding=messages[messages.length-2];return tail?.role==="user"&&Array.isArray(tail.content)&&tail.content.some(block=>block.type==="tool_result")&&preceding?.role==="assistant"&&Array.isArray(preceding.content)&&preceding.content.some(block=>block.type==="tool_use")}function markSystemMessageCacheCheckpoint(message,cacheControl){if(!Array.isArray(message.content))return;let lastBlock=message.content[message.content.length-1];lastBlock&&(lastBlock.type==="text"||lastBlock.type==="tool_addition"||lastBlock.type==="tool_removal")&&(lastBlock.cache_control=cacheControl)}function markUserMessageCacheCheckpoint(message,cacheControl){if(message.role!=="user")return!1;if(Array.isArray(message.content)){let lastBlock=message.content[message.content.length-1];return isCacheableUserContentBlock(lastBlock)?(lastBlock.cache_control=cacheControl,!0):!1}return typeof message.content=="string"?(message.content=[{type:"text",text:message.content,cache_control:cacheControl}],!0):!1}var ANTHROPIC_MESSAGE_EVENTS=new Set(["message_start","message_delta","message_stop","content_block_start","content_block_delta","content_block_stop"]);function flushSseEvent(state){if(!state.event&&state.data.length===0)return null;let event={event:state.event,data:state.data.join(`
|
package/dist/bundle/chunks/{app-server-command-CV6N7JDD.js → app-server-command-EGTBOL5W.js}
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url); { const __piWorkerThreads = require("node:worker_threads"); if (typeof __piWorkerThreads.markAsUncloneable !== "function") { __piWorkerThreads.markAsUncloneable = () => {}; } }
|
|
2
|
-
import{import_websocket_server,wrapper_default}from"./chunk-YBZDAABT.js";import{AuthStorage,DefaultResourceLoader,GOAL_STORE_CHANGED_EVENT,ModelRegistry,clearGoal,createAgentSession,createGoal,createPendingQuestion,defaultModelPerProvider,formatProviderNativeBody,formatProviderNativeSummary,getMcpService,goalStoreRef,loadMcpConfig,loadSkills,readGoal,resolveAuthMode,updateGoal}from"./chunk-
|
|
2
|
+
import{import_websocket_server,wrapper_default}from"./chunk-YBZDAABT.js";import{AuthStorage,DefaultResourceLoader,GOAL_STORE_CHANGED_EVENT,ModelRegistry,clearGoal,createAgentSession,createGoal,createPendingQuestion,defaultModelPerProvider,formatProviderNativeBody,formatProviderNativeSummary,getMcpService,goalDisplayStatus,goalStoreRef,loadMcpConfig,loadSkills,readGoal,resolveAuthMode,updateGoal}from"./chunk-2ZGQRUGM.js";import{RPC_ERROR_UNKNOWN_COMMAND,UNKNOWN_COMMAND_CONFIRM_HINT,UnknownCommandError,getCredentialAccounts,getModels,getProviders,pinCredentialAccount,removeCredentialAccount,subscribeProviderAccountEvents}from"./chunk-N6HU6BEY.js";import"./chunk-ZGCPUGLT.js";import{SessionManager,loadEntriesFromFile}from"./chunk-2AYAOU6W.js";import{SettingsManager,getAvailableThemesWithPaths,getThemeByName,takeOverStdout,theme,waitForRawStdoutBackpressure,writeRawStdout}from"./chunk-ZJOYLQXK.js";import"./chunk-TOZBUPZP.js";import"./chunk-LYYI74CY.js";import"./chunk-4GPJOGXZ.js";import{x}from"./chunk-KCVSSFOV.js";import"./chunk-WIAXG52U.js";import"./chunk-DRVT7RIO.js";import{getSupportedThinkingLevels}from"./chunk-SSH4CLHJ.js";import"./chunk-JABBHOD5.js";import"./chunk-SIIACSBE.js";import"./chunk-6SBY4ZWC.js";import"./chunk-QMRJYMNH.js";import"./chunk-QKU6JOA4.js";import"./chunk-ZJHRDQCH.js";import"./chunk-UWYQPA26.js";import"./chunk-H4QOEVS5.js";import"./chunk-IAYFQEXI.js";import"./chunk-JMYO34RK.js";import"./chunk-M4C6Z7UT.js";import{require_ignore}from"./chunk-YU4AYH4C.js";import"./chunk-BMX2U22F.js";import"./chunk-S2TCHQTE.js";import"./chunk-7X72IACK.js";import"./chunk-KUPQO7MC.js";import"./chunk-YU2P3CAR.js";import{runtimeExecArgv}from"./chunk-E75RO54O.js";import{acquireOwnershipSafeLock}from"./chunk-NEFNNQSV.js";import{attachJsonlLineReader}from"./chunk-Q3R44CGT.js";import{parseDaemonPidFile,processMatchesPidFile,readProcessStartTime,stopValidatedPid,waitForGone,waitForStartTime}from"./chunk-ZRWOLP4E.js";import"./chunk-HB35RBP4.js";import"./chunk-G2XAU4BX.js";import"./chunk-RRU5LXMS.js";import"./chunk-VE3D74HN.js";import"./chunk-26UBFF6N.js";import"./chunk-5BRVRFJI.js";import"./chunk-GZVCRV7I.js";import"./chunk-U3VOXCGP.js";import"./chunk-RFB5CBW7.js";import"./chunk-2VZJTDUX.js";import"./chunk-2JKDZXIY.js";import"./chunk-5PB3SNZ7.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{APP_NAME,CONFIG_DIR_NAME,ENV_SESSION_DIR,VERSION,getAgentDir,getSessionsDir,isLocalPath,resolvePath}from"./chunk-463OK2Y4.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-QXREUA5F.js";import"./chunk-WASCMT6Y.js";import"./chunk-RKJNJ3GI.js";import"./chunk-CWLCGRUS.js";import"./chunk-6WCOSBI7.js";import"./chunk-I5HLTDT4.js";import"./chunk-KRNXUTZJ.js";import"./chunk-YOPVJDSU.js";import"./chunk-WHPDEDCC.js";import"./chunk-HK46JMSC.js";import"./chunk-VYKBN4MR.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-45SZOLCU.js";import"./chunk-TAV6QZFM.js";import"./chunk-PELNNWGO.js";import{normalizeProviderId}from"./chunk-L4HVJWIF.js";import"./chunk-DMI55M2N.js";import"./chunk-PJ34QVL5.js";import{__toESM}from"./chunk-IKOFCODM.js";import{isIP}from"node:net";var APP_SERVER_LISTEN_USAGE="Invalid --listen value. Use stdio://, unix://, unix:///abs/path, or ws://IP:PORT.";function formatAppServerUsage(){let listenForms="stdio://|unix://|unix:///abs/path|ws://IP:PORT";return[`Usage: ${APP_NAME} app-server [--listen <${listenForms}>] [--ws-auth <token-file|off>] [--json-logs] [--extension <path>]...`,` ${APP_NAME} app-server daemon <start|stop|status|restart> [--listen <${listenForms}>] [--extension <path>]...`].join(`
|
|
3
3
|
`)}function parseListen(value){if(value==="stdio://")return{kind:"stdio",url:"stdio://"};if(value==="unix://")return{kind:"unix",url:"unix://"};if(value.startsWith("unix:///")){let path=value.slice(7);return path.startsWith("/")?{kind:"unix",url:value,path}:void 0}if(!value.startsWith("ws://"))return;let parsed;try{parsed=new URL(value)}catch(error){if(error instanceof TypeError)return;throw error}let port=Number(parsed.port);if(!(parsed.protocol!=="ws:"||parsed.username!==""||parsed.password!==""||parsed.pathname!=="/"||parsed.search!==""||parsed.hash!==""||parsed.port===""||!Number.isInteger(port)||port<1||port>65535||isIP(parsed.hostname)===0))return{kind:"ws",url:value,host:parsed.hostname,port}}function parseDaemonVerb(value){switch(value){case"start":case"stop":case"status":case"restart":return value;default:return}}function parseWsAuth(value){return value==="off"?{kind:"off"}:{kind:"token-file",path:value}}var EXTENSION_USAGE="--extension requires <path>.";function parseServerArgs(args){let listen3={kind:"stdio",url:"stdio://"},wsAuth,jsonLogs=!1,extensions=[];for(let index=0;index<args.length;index++){let arg=args[index];if(arg==="--extension"){let value=args[index+1];if(value===void 0)return{kind:"usage-error",message:EXTENSION_USAGE};extensions.push(value),index++;continue}if(arg==="--listen"){let value=args[index+1];if(value===void 0)return{kind:"usage-error",message:APP_SERVER_LISTEN_USAGE};let parsed=parseListen(value);if(parsed===void 0)return{kind:"usage-error",message:APP_SERVER_LISTEN_USAGE};listen3=parsed,index++;continue}if(arg==="--ws-auth"){let value=args[index+1];if(value===void 0)return{kind:"usage-error",message:"--ws-auth requires <token-file|off>."};wsAuth=parseWsAuth(value),index++;continue}if(arg==="--json-logs"){jsonLogs=!0;continue}return{kind:"usage-error",message:`Unexpected app-server argument: ${arg}`}}return{kind:"server",listen:listen3,wsAuth,jsonLogs,extensions}}function parseDaemonArgs(args){let verb=parseDaemonVerb(args[0]);if(verb===void 0)return{kind:"usage-error",message:"Usage: app-server daemon <start|stop|status|restart>."};let listen3={kind:"ws",url:"ws://127.0.0.1:18800",host:"127.0.0.1",port:18800},extensions=[];for(let index=1;index<args.length;index++){let arg=args[index];if(arg==="--extension"){let value=args[index+1];if(value===void 0)return{kind:"usage-error",message:EXTENSION_USAGE};extensions.push(value),index++;continue}if(arg==="--listen"){let value=args[index+1];if(value===void 0)return{kind:"usage-error",message:APP_SERVER_LISTEN_USAGE};let parsed=parseListen(value);if(parsed===void 0)return{kind:"usage-error",message:APP_SERVER_LISTEN_USAGE};listen3=parsed,index++;continue}return{kind:"usage-error",message:`Unexpected app-server daemon argument: ${arg}`}}return{kind:"daemon",verb,listen:listen3,extensions}}function parseAppServerCliArgs(args){return args[0]==="daemon"?parseDaemonArgs(args.slice(1)):parseServerArgs(args)}function resolveAppServerExtensionPaths(extensions,cwd=process.cwd()){return extensions.map(value=>isLocalPath(value)?resolvePath(value,cwd):value)}var RpcHandlerError=class extends Error{constructor(error){super(error.message),this.name="RpcHandlerError",this.rpcError=error}};function invalidRequestError(){return{code:-32600,message:"Invalid request"}}function methodNotFoundError(method){return{code:-32601,message:`Method not found: ${method}`}}function invalidParamsError(){return{code:-32602,message:"Invalid params"}}function internalError(message="Internal error"){return{code:-32603,message}}function notInitializedError(){return{code:-32600,message:"Not initialized"}}function alreadyInitializedError(){return{code:-32600,message:"Already initialized"}}function experimentalCapabilityError(method){return{code:-32600,message:`${method} requires experimentalApi capability`}}function registerExtensionRequestMethod(registry,getThread){registry.register("extension_request",{scope:"thread",handler:async({request})=>{let params=request.params;if(typeof params!="object"||params===null||Array.isArray(params))throw new RpcHandlerError({code:-32602,message:"Invalid params"});let threadId=Reflect.get(params,"threadId"),name=Reflect.get(params,"name");if(typeof threadId!="string"||threadId.length===0||typeof name!="string"||name.length===0)throw new RpcHandlerError({code:-32602,message:"Invalid params"});try{return await getThread(threadId).extensionRunner.requestRpc(name,Reflect.get(params,"data"))}catch(error){throw new RpcHandlerError(internalError(error instanceof Error?error.message:String(error)))}}})}function createRegistry(){return new InMemoryMethodRegistry}var InMemoryMethodRegistry=class{constructor(){this.methods=new Map}register(method,registration){this.methods.set(method,registration)}async dispatch(connection,request){if(!connection.initialized){let registration2=this.methods.get(request.method);if(request.method!=="initialize"||registration2?.requiresInit!==!1)return{id:request.id,error:notInitializedError()}}if(connection.initialized&&request.method==="initialize")return{id:request.id,error:alreadyInitializedError()};let registration=this.methods.get(request.method);if(!registration)return{id:request.id,error:methodNotFoundError(request.method)};if(registration.experimental===!0&&connection.capabilities?.experimentalApi!==!0)return{id:request.id,error:experimentalCapabilityError(request.method)};try{let result=await registration.handler({connection,request});return{id:request.id,result}}catch(error){return error instanceof RpcHandlerError?{id:request.id,error:error.rpcError}:{id:request.id,error:internalError(error instanceof Error?error.message:String(error))}}}};function registerFuzzyFileSearchMethods(registry,service){registry.register("fuzzyFileSearch",{scope:"global",handler:({request})=>service.search(parseOneShotParams(request.params))}),registry.register("fuzzyFileSearch/sessionStart",{experimental:!0,scope:"global",handler:({request})=>service.startSession(parseSessionStartParams(request.params))}),registry.register("fuzzyFileSearch/sessionUpdate",{experimental:!0,scope:"global",handler:({request})=>service.updateSession(parseSessionUpdateParams(request.params))}),registry.register("fuzzyFileSearch/sessionStop",{experimental:!0,scope:"global",handler:({request})=>service.stopSession(parseSessionStopParams(request.params))})}function parseOneShotParams(value){let params=objectParams(value,"fuzzyFileSearch");return{query:requiredString(params.query,"fuzzyFileSearch query"),roots:requiredStringArray(params.roots,"fuzzyFileSearch roots"),cancellationToken:optionalString(params.cancellationToken,"fuzzyFileSearch cancellationToken")}}function parseSessionStartParams(value){let params=objectParams(value,"fuzzyFileSearch/sessionStart");return{sessionId:requiredString(params.sessionId,"fuzzyFileSearch/sessionStart sessionId"),roots:requiredStringArray(params.roots,"fuzzyFileSearch/sessionStart roots")}}function parseSessionUpdateParams(value){let params=objectParams(value,"fuzzyFileSearch/sessionUpdate");return{sessionId:requiredString(params.sessionId,"fuzzyFileSearch/sessionUpdate sessionId"),query:requiredString(params.query,"fuzzyFileSearch/sessionUpdate query")}}function parseSessionStopParams(value){let params=objectParams(value,"fuzzyFileSearch/sessionStop");return{sessionId:requiredString(params.sessionId,"fuzzyFileSearch/sessionStop sessionId")}}function objectParams(value,method){if(!isRecord(value))throw invalidRequest(`${method} params must be an object`);return value}function requiredString(value,field){if(typeof value!="string")throw invalidRequest(`${field} must be a string`);return value}function requiredStringArray(value,field){if(!Array.isArray(value)||value.some(entry=>typeof entry!="string"))throw invalidRequest(`${field} must be an array of strings`);return value}function optionalString(value,field){if(value==null)return null;if(typeof value!="string")throw invalidRequest(`${field} must be a string or null`);return value}function invalidRequest(message){return new RpcHandlerError({code:-32600,message})}function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}import{lstat,readdir}from"node:fs/promises";import{basename,join as join2,relative as relative2,resolve,sep as sep2}from"node:path";var import_ignore=__toESM(require_ignore(),1);import{readFile}from"node:fs/promises";import{join,relative,sep}from"node:path";async function addGitignoreScope(matchers,directory){let gitignore=await readableText(join(directory,".gitignore"));return gitignore===void 0?matchers:[...matchers,{directory,matcher:(0,import_ignore.default)().add(gitignore)}]}function isIgnored(matchers,path,isDirectory){let ignored=!1;for(let scope of matchers){let relativePath=relative(scope.directory,path).split(sep).join("/"),result=scope.matcher.test(isDirectory?`${relativePath}/`:relativePath);result.ignored&&(ignored=!0),result.unignored&&(ignored=!1)}return ignored}async function readableText(path){try{return await readFile(path,"utf8")}catch(error){if(error instanceof Error)return;throw error}}var FUZZY_SEARCH_MAX_DEPTH=12,FUZZY_SEARCH_MAX_VISITED_ENTRIES=5e4,FUZZY_SEARCH_RESULT_LIMIT=50,FILENAME_MATCH_BONUS=1e6,CHARACTER_MATCH_SCORE=10,CONTIGUOUS_MATCH_BONUS=20,BOUNDARY_MATCH_BONUS=5,CANCELLATION_YIELD_INTERVAL=256;async function collectFuzzyFileEntries(roots,options={}){let entries=[],state={visitedEntries:0,stopped:!1},maxDepth=options.maxDepth??FUZZY_SEARCH_MAX_DEPTH,maxVisitedEntries=options.maxVisitedEntries??FUZZY_SEARCH_MAX_VISITED_ENTRIES;for(let root of roots){if(options.signal?.aborted||state.stopped)break;let absoluteRoot=resolve(root),rootStat=await readableStat(absoluteRoot);!rootStat?.isDirectory()||rootStat.isSymbolicLink()||await walkDirectory({wireRoot:root,absoluteRoot,absoluteDirectory:absoluteRoot,depth:0,matchers:[],entries,state,signal:options.signal,maxDepth,maxVisitedEntries})}return entries}function rankFuzzyFileEntries(query,entries){if(query.length===0)return[];let results=[];for(let entry of entries){let filenameMatch=scoreSubsequence(entry.fileName,query),pathMatch=filenameMatch??scoreSubsequence(entry.path,query);if(!pathMatch)continue;let filenameOffset=Array.from(entry.path).length-Array.from(entry.fileName).length,indices=filenameMatch?filenameMatch.indices.map(index=>index+filenameOffset):pathMatch.indices;results.push({root:entry.root,path:entry.path,match_type:entry.matchType,file_name:entry.fileName,score:pathMatch.score+(filenameMatch?FILENAME_MATCH_BONUS:0),indices})}return results.sort(compareResults),results.slice(0,FUZZY_SEARCH_RESULT_LIMIT)}async function walkDirectory(input){let matchers=await addGitignoreScope(input.matchers,input.absoluteDirectory),directoryEntries=await readableDirectory(input.absoluteDirectory);directoryEntries.sort((left,right)=>compareText(left.name,right.name));for(let directoryEntry of directoryEntries){if(input.signal?.aborted||input.state.stopped)return;if(input.state.visitedEntries>=input.maxVisitedEntries){input.state.stopped=!0;return}if(input.state.visitedEntries+=1,directoryEntry.name===".git"||directoryEntry.name==="node_modules"||directoryEntry.isSymbolicLink())continue;let isDirectory=directoryEntry.isDirectory();if(!isDirectory&&!directoryEntry.isFile())continue;let absolutePath=join2(input.absoluteDirectory,directoryEntry.name),relativePath=toPosixPath(relative2(input.absoluteRoot,absolutePath));if(isIgnored(matchers,absolutePath,isDirectory))continue;input.entries.push({root:input.wireRoot,path:relativePath,matchType:isDirectory?"directory":"file",fileName:basename(relativePath)});let entryDepth=input.depth+1;isDirectory&&entryDepth<input.maxDepth&&await walkDirectory({...input,absoluteDirectory:absolutePath,depth:entryDepth,matchers}),input.state.visitedEntries%CANCELLATION_YIELD_INTERVAL===0&&await yieldToEventLoop()}}function scoreSubsequence(candidate,query){let normalizedCandidate=normalizeText(candidate),normalizedQuery=query.toLowerCase(),contiguousStart=normalizedCandidate.value.indexOf(normalizedQuery),normalizedIndices=[];if(contiguousStart>=0){let cursor=contiguousStart;for(let character of normalizedQuery)normalizedIndices.push(cursor),cursor+=character.length}else{let cursor=0;for(let character of normalizedQuery){let matchIndex=normalizedCandidate.value.indexOf(character,cursor);if(matchIndex<0)return;normalizedIndices.push(matchIndex),cursor=matchIndex+character.length}}let indices=[];for(let normalizedIndex of normalizedIndices){let sourceIndex=normalizedCandidate.sourceIndices[normalizedIndex];if(sourceIndex===void 0)return;indices.at(-1)!==sourceIndex&&indices.push(sourceIndex)}let candidateCharacters=Array.from(candidate),score=indices.length*CHARACTER_MATCH_SCORE;for(let index=0;index<indices.length;index++){let current=indices[index];if(current===void 0)continue;let previous=indices[index-1];previous!==void 0&¤t===previous+1&&(score+=CONTIGUOUS_MATCH_BONUS),(current===0||isBoundary(candidateCharacters[current-1]))&&(score+=BOUNDARY_MATCH_BONUS)}return{score,indices}}function normalizeText(value){let sourceIndices=[];for(let[sourceIndex,character]of Array.from(value).entries())for(let index=0;index<character.toLowerCase().length;index++)sourceIndices.push(sourceIndex);return{value:value.toLowerCase(),sourceIndices}}function compareResults(left,right){return left.score!==right.score?right.score-left.score:compareText(left.path,right.path)}function compareText(left,right){return left<right?-1:left>right?1:0}function isBoundary(character){return character==="/"||character==="-"||character==="_"||character==="."||character===" "}async function readableDirectory(path){try{return await readdir(path,{withFileTypes:!0})}catch(error){if(error instanceof Error)return[];throw error}}async function readableStat(path){try{return await lstat(path)}catch(error){if(error instanceof Error)return;throw error}}function toPosixPath(path){return path.split(sep2).join("/")}function yieldToEventLoop(){return new Promise(resolve4=>setImmediate(resolve4))}var FuzzyFileSearchService=class{constructor(options){this.activeSearches=new Set,this.pendingSearches=new Map,this.sessions=new Map,this.disposed=!1,this.broadcast=options.broadcast,this.collectEntries=options.collectEntries??((roots,signal)=>collectFuzzyFileEntries(roots,{signal})),this.rankEntries=options.rankEntries??rankFuzzyFileEntries}async search(params){if(this.disposed)return{files:[]};let controller=new AbortController;this.activeSearches.add(controller);let token=params.cancellationToken;token!==null&&(this.pendingSearches.get(token)?.abort(),this.pendingSearches.set(token,controller));try{if(params.query.length===0)return{files:[]};let entries=await this.collectEntries(params.roots,controller.signal);return controller.signal.aborted||this.disposed?{files:[]}:{files:this.rankEntries(params.query,entries)}}finally{this.activeSearches.delete(controller),token!==null&&this.pendingSearches.get(token)===controller&&this.pendingSearches.delete(token)}}startSession(params){if(params.sessionId.length===0)throw invalidRequest2("sessionId must not be empty");this.cancelSession(params.sessionId);let session={id:params.sessionId,roots:params.roots,controller:new AbortController,query:"",version:0,entries:void 0,active:!this.disposed,completedVersion:void 0};return this.sessions.set(session.id,session),this.runTraversal(session),{}}updateSession(params){let session=this.sessions.get(params.sessionId);if(!session?.active)throw invalidRequest2(`fuzzy file search session not found: ${params.sessionId}`);return session.query=params.query,session.version+=1,session.entries!==void 0&&this.emitVersion(session,session.version),{}}stopSession(params){return this.cancelSession(params.sessionId),{}}dispose(){if(!this.disposed){this.disposed=!0;for(let controller of this.activeSearches)controller.abort();this.activeSearches.clear(),this.pendingSearches.clear();for(let session of this.sessions.values())this.deactivate(session);this.sessions.clear()}}async runTraversal(session){let entries;try{entries=await this.collectEntries(session.roots,session.controller.signal)}catch(error){if(!(error instanceof Error))throw error;entries=[]}if(this.isLive(session))for(session.entries=entries;this.isLive(session);){let version=session.version;if(await this.emitVersion(session,version))break}}async emitVersion(session,version){if(await Promise.resolve(),!this.isLive(session)||session.version!==version||session.entries===void 0)return!1;if(session.completedVersion===version)return!0;let query=session.query,files=query.length===0?[]:this.rankEntries(query,session.entries);return!this.isLive(session)||session.version!==version||(this.broadcast({method:"fuzzyFileSearch/sessionUpdated",params:{sessionId:session.id,query,files}}),!this.isLive(session)||session.version!==version)?!1:(session.completedVersion=version,this.broadcast({method:"fuzzyFileSearch/sessionCompleted",params:{sessionId:session.id}}),!0)}cancelSession(sessionId){let session=this.sessions.get(sessionId);session&&(this.deactivate(session),this.sessions.get(sessionId)===session&&this.sessions.delete(sessionId))}deactivate(session){session.active=!1,session.controller.abort()}isLive(session){return!this.disposed&&session.active&&this.sessions.get(session.id)===session}};function invalidRequest2(message){return new RpcHandlerError({code:-32600,message})}var APPROVAL_DECISIONS=["accept","acceptForSession","decline","cancel"],PERMISSION_OPTIONS=["Allow once","Allow always","Deny","Deny with feedback"],CANCEL_REASON="approval request was cancelled because the turn ended",NO_SUBSCRIBER_REASON="no client connected to approve";var ApprovalBridge=class{constructor(sendToThreadSubscribers){this.nextServerRequestId=0,this.pending=new Map,this.sessionAllows=new Set,this.sendToThreadSubscribers=sendToThreadSubscribers}get pendingCount(){return this.pending.size}requestApproval(threadId,kind,payload){let allowKey=createAllowKey(threadId,kind,payload);if(allowKey&&this.sessionAllows.has(allowKey))return Promise.resolve({allow:!0,decision:"acceptForSession"});let requestId=this.nextServerRequestId;this.nextServerRequestId+=1;let request=buildApprovalRequest(threadId,requestId,kind,payload);return new Promise(resolve4=>{this.pending.set(requestId,{threadId,request,allowKey,resolve:resolve4}),!(this.sendToThreadSubscribers(threadId,request)>0)&&(this.pending.delete(requestId),resolve4({allow:!1,decision:"decline",reason:NO_SUBSCRIBER_REASON}))})}resolveResponse(response){let pending=this.pending.get(response.id);if(!pending)return!1;let decision=readDecision(response);return this.pending.delete(response.id),decision==="acceptForSession"&&pending.allowKey&&this.sessionAllows.add(pending.allowKey),this.emitResolved(pending.threadId,response.id),pending.resolve(decisionToOutcome(decision,readReason(response))),!0}replayPendingForThread(threadId){let replayed=0;for(let pending of this.pending.values())pending.threadId===threadId&&(this.sendToThreadSubscribers(threadId,pending.request),replayed+=1);return replayed}cancelPendingForThread(threadId){let cancelled=0;for(let[requestId,pending]of Array.from(this.pending.entries()))pending.threadId===threadId&&(this.pending.delete(requestId),this.emitResolved(threadId,requestId),pending.resolve({allow:!1,decision:"cancel",reason:CANCEL_REASON}),cancelled+=1);return cancelled}emitResolved(threadId,requestId){this.sendToThreadSubscribers(threadId,{method:"serverRequest/resolved",params:{threadId,requestId}})}};function buildApprovalRequest(threadId,requestId,kind,payload){let base={threadId,turnId:payload.turnId??"turn-approval",itemId:payload.itemId??(kind==="commandExecution"?"approval-command":"approval-file-change"),startedAtMs:Date.now()};return kind==="fileChange"?{id:requestId,method:"item/fileChange/requestApproval",params:{...base,reason:payload.reason??null,grantRoot:payload.grantRoot??null}}:{id:requestId,method:"item/commandExecution/requestApproval",params:{...base,approvalId:payload.approvalId??null,environmentId:payload.environmentId??null,reason:payload.reason??null,command:payload.command??null,cwd:payload.cwd??null,availableDecisions:[...APPROVAL_DECISIONS]}}}function decisionToOutcome(decision,reason){return decision==="accept"||decision==="acceptForSession"?{allow:!0,decision}:reason?{allow:!1,decision,reason}:{allow:!1,decision}}function readDecision(response){let decision=isRecord2(response.result)?response.result.decision:void 0;return isApprovalDecision(decision)?decision:"cancel"}function readReason(response){let resultReason=isRecord2(response.result)?response.result.reason??response.result.message:void 0,errorReason=isRecord2(response.error)?response.error.message:void 0,reason=typeof resultReason=="string"?resultReason:errorReason;return typeof reason=="string"&&reason.length>0?reason:void 0}function createAllowKey(threadId,kind,payload){if(!(!payload.toolName||typeof payload.command!="string"))return`${threadId}\0${kind}\0${payload.toolName}\0${payload.command}`}function isApprovalDecision(value){return value==="accept"||value==="acceptForSession"||value==="decline"||value==="cancel"}function isRecord2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function createAppServerUIContext(bridge,threadId,userInput,getTurnId=()=>"turn-user-input"){let pendingInput,editorText="",editorFactory,toolsExpanded=!1;return{question(request,opts){return userInput?.requestUserInput(threadId,getTurnId(),request.requestId,request,opts)??Promise.resolve({status:"unavailable",answers:{},unanswered:request.questions.map(question=>question.id)})},async select(title,options){let prompt=parsePermissionPrompt(title);if(!prompt||!isPermissionOptions(options))return;let outcome=await bridge.requestApproval(threadId,prompt.kind,{turnId:"turn-approval",itemId:`approval-${prompt.toolName}`,toolName:prompt.toolName,command:prompt.command,reason:prompt.reason});return outcome.decision==="accept"?"Allow once":outcome.decision==="acceptForSession"?"Allow always":outcome.reason&&outcome.reason!==NO_SUBSCRIBER_REASON&&outcome.reason!==CANCEL_REASON?(pendingInput=outcome.reason,"Deny with feedback"):"Deny"},async confirm(title,message){return(await bridge.requestApproval(threadId,"commandExecution",{turnId:"turn-approval",itemId:"approval-confirm",toolName:"confirm",command:title,reason:message})).allow},async input(){let value=pendingInput;return pendingInput=void 0,value},notify(){},onTerminalInput(){return()=>{}},setStatus(){},setWorkingMessage(){},setWorkingVisible(){},setWorkingIndicator(){},setHiddenThinkingLabel(){},setWidget(){},setFooter(){},setHeader(){},setTitle(){},custom(){return Promise.reject(new Error("Custom UI is not available in app-server mode."))},pasteToEditor(text){editorText=text},setEditorText(text){editorText=text},getEditorText(){return editorText},async editor(_title,prefill){return prefill},addAutocompleteProvider(){},setEditorComponent(factory){editorFactory=factory},getEditorComponent(){return editorFactory},theme,getAllThemes:getAvailableThemesWithPaths,getTheme(name){return getThemeByName(name)},setTheme(_nextTheme){return{success:!1,error:"Theme switching is not available in app-server mode."}},getToolsExpanded(){return toolsExpanded},setToolsExpanded(expanded){toolsExpanded=expanded}}}function parsePermissionPrompt(title){let[firstLine="",...rest]=title.split(`
|
|
4
4
|
`),prefix="Permission required: ";if(!firstLine.startsWith(prefix))return;let toolName=firstLine.slice(prefix.length).trim(),reason=rest.join(`
|
|
5
5
|
`).trim();return{kind:permissionKind(toolName),toolName,command:readLineValue(reason,"Command: $ ")??readLineValue(reason,"File: ")??readLineValue(reason,"Path: ")??null,reason}}function permissionKind(toolName){return toolName==="edit"||toolName==="write"||toolName==="apply_patch"||toolName==="multiedit"?"fileChange":"commandExecution"}function readLineValue(text,prefix){return text.split(`
|
|
6
6
|
`).find(line=>line.startsWith(prefix))?.slice(prefix.length)}function isPermissionOptions(options){return PERMISSION_OPTIONS.every(option=>options.includes(option))}var SERVER_NOTIFICATION_METHODS=["account/login/completed","account/rateLimits/updated","account/updated","app/list/updated","command/exec/outputDelta","configWarning","deprecationNotice","error","externalAgentConfig/import/completed","externalAgentConfig/import/progress","fs/changed","fuzzyFileSearch/sessionCompleted","fuzzyFileSearch/sessionUpdated","guardianWarning","hook/completed","hook/started","item/agentMessage/delta","item/autoApprovalReview/completed","item/autoApprovalReview/started","item/commandExecution/outputDelta","item/commandExecution/terminalInteraction","item/completed","item/fileChange/outputDelta","item/fileChange/patchUpdated","item/mcpToolCall/progress","item/plan/delta","item/reasoning/summaryPartAdded","item/reasoning/summaryTextDelta","item/reasoning/textDelta","item/started","mcpServer/oauthLogin/completed","mcpServer/startupStatus/updated","model/rerouted","model/safetyBuffering/updated","model/verification","process/exited","process/outputDelta","rawResponse/completed","rawResponseItem/completed","remoteControl/status/changed","serverRequest/resolved","skills/changed","thread/archived","thread/closed","thread/compacted","thread/deleted","thread/environment/connected","thread/environment/disconnected","thread/goal/cleared","thread/goal/updated","thread/name/updated","thread/realtime/closed","thread/realtime/error","thread/realtime/itemAdded","thread/realtime/outputAudio/delta","thread/realtime/sdp","thread/realtime/started","thread/realtime/transcript/delta","thread/realtime/transcript/done","thread/settings/updated","thread/started","thread/status/changed","thread/tokenUsage/updated","thread/unarchived","turn/completed","turn/diff/updated","turn/moderationMetadata","turn/plan/updated","turn/started","warning","windows/worldWritableWarning","windowsSandbox/setupCompleted"],ADDITIVE_CLIENT_NOTIFICATION_METHODS=["item/tool/userInputProgress"],ADDITIVE_SERVER_NOTIFICATION_METHODS=["account/providerAccounts/failover","account/providerAccounts/updated"],EXPERIMENTAL_SERVER_NOTIFICATION_METHODS=["process/exited","process/outputDelta","thread/environment/connected","thread/environment/disconnected","thread/realtime/closed","thread/realtime/error","thread/realtime/itemAdded","thread/realtime/outputAudio/delta","thread/realtime/sdp","thread/realtime/started","thread/realtime/transcript/delta","thread/realtime/transcript/done","thread/settings/updated","turn/moderationMetadata"];function populateNotificationEnvelope(notification,emittedAtMs){return{...notification,emittedAtMs:notification.emittedAtMs??emittedAtMs??Date.now()}}function populateOutboundNotificationEnvelope(message,emittedAtMs){return isRpcNotification(message)?populateNotificationEnvelope(message,emittedAtMs):message}function isJsonObject(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isRpcNotification(message){return"method"in message&&!("id"in message)}function hasOwn(value,key){return Reflect.getOwnPropertyDescriptor(value,key)!==void 0}function isRequestId(value){return typeof value=="string"||typeof value=="number"}function isResponseId(value){return value===null||isRequestId(value)}function parseRpcError(value){if(!isJsonObject(value))return null;let code=value.code,message=value.message;return typeof code!="number"||typeof message!="string"?null:hasOwn(value,"data")?{code,message,data:value.data}:{code,message}}function requestFrom(value,id,method){return hasOwn(value,"params")?{id,method,params:value.params}:{id,method}}function notificationFrom(value,method){return hasOwn(value,"params")?{method,params:value.params}:{method}}function classifyIncoming(value){if(!isJsonObject(value))return{kind:"protocol-invalid",value};let id=value.id,method=value.method;if(hasOwn(value,"id")&&hasOwn(value,"method")&&isRequestId(id)&&typeof method=="string")return{kind:"request",message:requestFrom(value,id,method)};if(hasOwn(value,"id")&&isResponseId(id)&&hasOwn(value,"result"))return{kind:"response",message:{id,result:value.result}};if(hasOwn(value,"id")&&isResponseId(id)&&hasOwn(value,"error")){let error=parseRpcError(value.error);if(error!==null)return{kind:"response",message:{id,error}}}return!hasOwn(value,"id")&&hasOwn(value,"method")&&typeof method=="string"?{kind:"notification",message:notificationFrom(value,method)}:{kind:"protocol-invalid",value}}var DEFAULT_OUTBOUND_QUEUE_LIMIT=32768,DEFAULT_TERMINAL_QUEUE_LIMIT=100,BROADCAST_NOTIFICATION_METHODS=new Set(["remoteControl/status/changed","thread/started","thread/status/changed","thread/closed","thread/deleted","thread/archived","thread/unarchived","thread/name/updated","thread/goal/updated","thread/goal/cleared","thread/tokenUsage/updated","fuzzyFileSearch/sessionUpdated","fuzzyFileSearch/sessionCompleted"]),TERMINAL_NOTIFICATION_METHODS=new Set(["turn/completed","error"]),BroadcastNotificationMethodError=class extends Error{constructor(method){super(`Notification method ${method} is not allowed for broadcast`),this.name="BroadcastNotificationMethodError",this.method=method}},NotificationRouter=class{constructor(options={}){this.connections=new Map,this.threads=new Map,this.outboundQueueLimit=options.outboundQueueLimit??DEFAULT_OUTBOUND_QUEUE_LIMIT,this.terminalQueueLimit=options.terminalQueueLimit??DEFAULT_TERMINAL_QUEUE_LIMIT,this.experimentalNotificationMethods=new Set(options.experimentalNotificationMethods??EXPERIMENTAL_SERVER_NOTIFICATION_METHODS),this.now=options.now??Date.now;for(let connection of options.connections??[])this.addConnection(connection);for(let thread of options.threads??[])this.addThread(thread)}addConnection(connection){this.connections.set(connection.id,{connection,pending:0,closed:!1})}removeConnection(connectionId2){this.connections.delete(connectionId2);let emptiedThreadIds=[];for(let thread of this.threads.values())thread.subscribers.delete(connectionId2)&&thread.subscribers.size===0&&emptiedThreadIds.push(thread.id);return emptiedThreadIds}addThread(thread){this.threads.set(thread.id,thread)}removeThread(threadId){this.threads.delete(threadId)}subscribe(threadId,connectionId2){let thread=this.threads.get(threadId);if(!thread)return;thread.subscribers.add(connectionId2);let connection=this.connections.get(connectionId2);if(connection){for(let notification of thread.queuedTerminalNotifications)this.enqueue(connection,notification);thread.queuedTerminalNotifications=[]}}unsubscribe(threadId,connectionId2){this.threads.get(threadId)?.subscribers.delete(connectionId2)}broadcast(notification){if(!this.canBroadcast(notification.method))throw new BroadcastNotificationMethodError(notification.method);let envelope=populateNotificationEnvelope(notification,this.now());for(let state of this.connections.values())state.connection.initialized&&this.enqueue(state,envelope)}toThread(threadId,message){let thread=this.threads.get(threadId);if(!thread)return;let outbound="id"in message?message:populateNotificationEnvelope(message,this.now()),routed=0;for(let connectionId2 of thread.subscribers){let state=this.connections.get(connectionId2);state?.connection.initialized&&(routed+=1,this.enqueue(state,outbound))}if(routed===0&&!("id"in outbound)&&TERMINAL_NOTIFICATION_METHODS.has(outbound.method))for(thread.queuedTerminalNotifications.push(outbound);thread.queuedTerminalNotifications.length>this.terminalQueueLimit;)thread.queuedTerminalNotifications.shift()}enqueue(state,message){if(state.closed||!("id"in message)&&this.filtered(state.connection,message))return;if(state.connection.transport!=="stdio"&&state.pending>=this.outboundQueueLimit){state.closed=!0,state.connection.close?.("slow-client");return}state.pending+=1;let sendResult=state.connection.send(message);if(sendResult===void 0){state.pending-=1;return}sendResult.then(()=>{state.pending-=1},()=>{state.pending-=1})}canBroadcast(method){return BROADCAST_NOTIFICATION_METHODS.has(method)}filtered(connection,notification){return connection.optOutNotificationMethods?.includes(notification.method)?!0:this.experimentalNotificationMethods.has(notification.method)&&connection.capabilities?.experimentalApi!==!0}};import{existsSync,statSync}from"node:fs";import{resolve as resolve2}from"node:path";function registerAppServerSkillMethods(registry,options={}){let serverCwd=resolvePath(options.serverCwd??process.cwd()),agentDir=options.agentDir??getAgentDir(),cachedLoaders=new Map;registry.register("skills/list",{scope:"global",handler:async({request})=>{let params=parseSkillsListParams(request.params),requestedCwds=params.cwds&¶ms.cwds.length>0?params.cwds:[serverCwd];return{data:await Promise.all(requestedCwds.map(cwd=>{let resolvedCwd=resolvePath(cwd,serverCwd,{trim:!0});return buildSkillsListEntry(resolvedCwd,params.forceReload===!0,{agentDir,threads:options.threads,resourceLoaderFactory:options.resourceLoaderFactory,cachedLoaders})}))}}})}async function buildSkillsListEntry(cwd,forceReload,options){let invalidEntry=validateSkillCwd(cwd);if(invalidEntry)return invalidEntry;try{let loader=await getCachedLoader(cwd,options);forceReload&&await loader.reload();let loaded=loader.getSkills();return{cwd,skills:loaded.skills.map(toWireSkill),errors:loaded.diagnostics.map(diagnostic=>toWireSkillError(diagnostic,cwd))}}catch(error){return{cwd,skills:[],errors:[{path:cwd,message:errorMessage(error)}]}}}function validateSkillCwd(cwd){if(!existsSync(cwd))return{cwd,skills:[],errors:[{path:cwd,message:"skill cwd does not exist"}]};try{if(!statSync(cwd).isDirectory())return{cwd,skills:[],errors:[{path:cwd,message:"skill cwd is not a directory"}]}}catch(error){return{cwd,skills:[],errors:[{path:cwd,message:errorMessage(error)}]}}}async function getCachedLoader(cwd,options){let loaderPromise=options.cachedLoaders.get(cwd);loaderPromise||(loaderPromise=Promise.resolve().then(()=>findLoadedLoader(cwd,options.threads)??createLoader(cwd,options)),options.cachedLoaders.set(cwd,loaderPromise));try{return await loaderPromise}catch(error){throw options.cachedLoaders.delete(cwd),error}}function findLoadedLoader(cwd,threads){if(!threads)return;let loaded=threads.listLoaded().find(thread=>resolve2(thread.cwd)===cwd);if(loaded)try{return threads.getLoadedThread(loaded.id).session.resourceLoader}catch{return}}async function createLoader(cwd,options){if(options.resourceLoaderFactory)return options.resourceLoaderFactory(cwd);let loaded=loadSkills({cwd,agentDir:options.agentDir,skillPaths:[],includeDefaults:!0});return{getSkills:()=>loaded,reload:async()=>{loaded=loadSkills({cwd,agentDir:options.agentDir,skillPaths:[],includeDefaults:!0})}}}function toWireSkill(skill){return{name:skill.name,description:skill.description,path:skill.filePath,scope:mapSkillScope(skill.sourceInfo.scope),enabled:!skill.disableModelInvocation}}function mapSkillScope(scope){switch(scope){case"user":return"user";case"project":return"repo";case"temporary":case"system":return"system";default:return assertNever(scope)}}function toWireSkillError(diagnostic,cwd){return{path:diagnostic.path??cwd,message:diagnostic.message}}function parseSkillsListParams(value){if(value==null)return{};if(!isRecord3(value))throw new RpcHandlerError(invalidParamsError());let cwds=value.cwds;if(cwds!==void 0&&!isStringArray(cwds))throw new RpcHandlerError(invalidParamsError());let forceReload=value.forceReload;if(forceReload!==void 0&&typeof forceReload!="boolean")throw new RpcHandlerError(invalidParamsError());return{cwds,forceReload}}function isStringArray(value){return Array.isArray(value)&&value.every(item=>typeof item=="string")}function isRecord3(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function errorMessage(error){return error instanceof Error?error.message:String(error)}function assertNever(value){throw new Error(`Unhandled skill scope: ${String(value)}`)}var UserInputProtocolError=class extends Error{constructor(message){super(message),this.name="UserInputProtocolError"}};function isRecord4(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function readUserInputResult(value){if(!isRecord4(value))throw new UserInputProtocolError("Invalid user input result");if(value.comment!==void 0&&typeof value.comment!="string")throw new UserInputProtocolError("Invalid user input comment");if(value.cancelled!==void 0&&typeof value.cancelled!="boolean")throw new UserInputProtocolError("Invalid user input cancellation");let answers={};if(value.answers!==void 0){if(!isRecord4(value.answers))throw new UserInputProtocolError("Invalid user input answers");for(let[id,answer]of Object.entries(value.answers)){if(!isRecord4(answer)||!Array.isArray(answer.answers))throw new UserInputProtocolError("Invalid user input answer");let strings=[];for(let text of answer.answers){if(typeof text!="string")throw new UserInputProtocolError("Invalid user input answer text");strings.push(text)}answers[id]={answers:strings}}}return{answers,comment:value.comment,cancelled:value.cancelled}}function toDraft(request,result){let answers={};for(let question of request.questions){let values=result.answers[question.id]?.answers;if(!values)continue;let labels=new Set(question.options.map(option=>option.label)),selected=values.filter(value=>labels.has(value)),text=values.filter(value=>!labels.has(value)).join(`
|
|
7
7
|
`);answers[question.id]={selected,...text?{text}:{}}}return{answers,...result.comment!==void 0?{comment:result.comment}:{}}}var UserInputBridge=class{constructor(send){this.nextId=0,this.pending=new Map,this.send=send}get pendingCount(){return this.pending.size}requestUserInput(threadId,turnId,itemId,canonical,opts){let id=`user-input-${this.nextId++}`,request={id,method:"item/tool/requestUserInput",params:{threadId,turnId,itemId,autoResolutionMs:null,timeoutMs:opts?.timeout??canonical.timeoutMs,waitForAnswer:canonical.waitForAnswer,questions:canonical.questions.map(question=>({...question,isOther:!0,isSecret:!1,options:question.options.length?question.options.map(option=>({label:option.label,description:option.description??""})):null}))}};return new Promise(resolve4=>{let state=createPendingQuestion({request:canonical,now:Date.now,idleTimeoutMs:request.params.timeoutMs,onTimeout:response=>this.finish(id,response)}),abort=()=>this.finish(id,state.cancel());if(this.pending.set(id,{threadId,canonical,request,state,draft:{answers:{}},resolve:resolve4,onProgress:opts?.onProgress,removeAbort:()=>opts?.signal?.removeEventListener("abort",abort)}),opts?.signal?.aborted){abort();return}if(opts?.signal?.addEventListener("abort",abort,{once:!0}),state.result){this.finish(id,state.result);return}this.send(threadId,request)===0&&this.finish(id,state.cancel("unavailable"))})}resolveResponse(response){let pending=this.pending.get(response.id);if(!pending)return!1;if(response.error!==void 0)return this.finish(response.id,pending.state.cancel()),!0;let result=readUserInputResult(response.result),draft=toDraft(pending.canonical,result);if(pending.state.touch(draft),result.cancelled)return this.finish(response.id,pending.state.cancel()),!0;let submitted=pending.state.submit(draft.answers,draft.comment,"rpc_connection");if(submitted)this.finish(response.id,submitted);else{let cancelled=pending.state.cancel(),hasAnswer=Object.values(draft.answers).some(answer=>answer.selected.length>0||answer.text?.trim());this.finish(response.id,hasAnswer?{...cancelled,status:"answered",resolvedBy:"rpc_connection"}:cancelled)}return!0}progress(params){if(!isRecord4(params)||typeof params.requestId!="string"&&typeof params.requestId!="number")return!1;let pending=this.pending.get(params.requestId);if(!pending)return!1;let result=readUserInputResult(params),next=toDraft(pending.canonical,result);return pending.draft={answers:params.answers===void 0?pending.draft.answers:next.answers,comment:params.comment===void 0?pending.draft.comment:next.comment},pending.state.touch(pending.draft),pending.onProgress?.(pending.draft),!0}replayPendingForThread(threadId){let replayed=0;for(let pending of this.pending.values())pending.threadId===threadId&&(this.send(threadId,pending.request),replayed++);return replayed}cancelPendingForThread(threadId){let cancelled=0;for(let[id,pending]of this.pending)pending.threadId===threadId&&(this.finish(id,pending.state.cancel()),cancelled++);return cancelled}finish(id,response){let pending=this.pending.get(id);pending&&(this.pending.delete(id),pending.removeAbort(),this.send(pending.threadId,{method:"serverRequest/resolved",params:{threadId:pending.threadId,requestId:id}}),pending.resolve(response))}};function objectValue(value){return typeof value!="object"||value===null||Array.isArray(value)?{}:Object.assign({},value)}function requiredString2(value,name){if(typeof value!="string"||value.length===0)throw new Error(`Invalid params: ${name} is required`);return value}function optionalString2(value){return typeof value=="string"?value:void 0}function optionalNumber(value){return typeof value=="number"&&Number.isFinite(value)?value:void 0}function connectionId(connection){let id=Reflect.get(connection,"id");if(typeof id!="string"||id.length===0)throw new Error("Connection id is required for thread lifecycle methods");return id}function encodeCursor(offset){return Buffer.from(String(offset),"utf8").toString("base64")}function decodeCursor(cursor){if(!cursor)return 0;let parsed=Number.parseInt(Buffer.from(cursor,"base64").toString("utf8"),10);return Number.isFinite(parsed)&&parsed>=0?parsed:0}import{randomUUID as randomUUID3}from"node:crypto";import{readdir as readdir2,readFile as readFile3,rm as rm2,stat,utimes}from"node:fs/promises";import{join as join4}from"node:path";import{randomUUID}from"node:crypto";import{mkdir,readFile as readFile2,rename,rm,writeFile}from"node:fs/promises";import{basename as basename2,dirname,join as join3}from"node:path";var METADATA_SUFFIX=".metadata.json",threadMutationQueues=new Map,ThreadMetadataStateError=class extends Error{constructor(path,message){super(`${message}: ${path}`),this.name="ThreadMetadataStateError",this.path=path}},ThreadMetadataUpdateError=class extends Error{constructor(){super(...arguments),this.name="ThreadMetadataUpdateError"}};function enqueueThreadMutation(threadId,mutation){let result=(threadMutationQueues.get(threadId)??Promise.resolve()).then(mutation,mutation),settled=result.then(()=>{},()=>{});return threadMutationQueues.set(threadId,settled),result.finally(()=>{threadMutationQueues.get(threadId)===settled&&threadMutationQueues.delete(threadId)})}async function writeSidecarFileAtomic(filePath,contents){await mkdir(dirname(filePath),{recursive:!0});let temporaryPath=join3(dirname(filePath),`.${basename2(filePath)}-${randomUUID()}.tmp`);try{await writeFile(temporaryPath,contents,{encoding:"utf8",mode:384}),await rename(temporaryPath,filePath)}catch(error){try{await rm(temporaryPath,{force:!0})}catch(cleanupError){throw new AggregateError([error,cleanupError],"sidecar write failed and its temporary file could not be removed")}throw error}}function metadataSidecarPathForThread(thread){if(!thread.sessionPath)throw new Error(`Thread ${thread.id} has no session path for metadata state`);return`${thread.sessionPath}${METADATA_SUFFIX}`}var ThreadMetadataState=class{async readGitInfo(thread){return readGitInfoFromPath(metadataSidecarPathForThread(thread))}async updateGitInfo(thread,update){return enqueueThreadMutation(thread.id,async()=>{let path=metadataSidecarPathForThread(thread),current=await readGitInfoFromPath(path),next=mergeGitInfo(current,update);return await writeSidecarFileAtomic(path,`${JSON.stringify(toMetadataRecord(next))}
|
|
8
8
|
`),next})}};function parseGitInfoUpdate(value){if(!isRecord5(value))throw new ThreadMetadataUpdateError("gitInfo must include at least one field");let sha=parseGitInfoUpdateField(value.sha,"sha"),branch=parseGitInfoUpdateField(value.branch,"branch"),originUrl=parseGitInfoUpdateField(value.originUrl,"originUrl");if(sha===void 0&&branch===void 0&&originUrl===void 0)throw new ThreadMetadataUpdateError("gitInfo must include at least one field");return{...sha===void 0?{}:{sha},...branch===void 0?{}:{branch},...originUrl===void 0?{}:{originUrl}}}function mergeGitInfo(current,update){let parsed=parseGitInfoUpdate(update),baseline=current??emptyGitInfo();return{sha:parsed.sha===void 0?baseline.sha:parsed.sha,branch:parsed.branch===void 0?baseline.branch:parsed.branch,originUrl:parsed.originUrl===void 0?baseline.originUrl:parsed.originUrl}}async function readGitInfoFromPath(path){let content;try{content=await readFile2(path,"utf8")}catch(error){if(isNotFoundError(error))return null;throw readError(path,error)}let value;try{value=JSON.parse(content)}catch(error){throw error instanceof SyntaxError?new ThreadMetadataStateError(path,`Invalid metadata sidecar JSON (${error.message})`):error}if(!isRecord5(value)||!isRecord5(value.gitInfo))throw new ThreadMetadataStateError(path,"Invalid metadata sidecar record");return{sha:storedGitInfoField(value.gitInfo.sha,path,"sha"),branch:storedGitInfoField(value.gitInfo.branch,path,"branch"),originUrl:storedGitInfoField(value.gitInfo.originUrl,path,"originUrl")}}function parseGitInfoUpdateField(value,field){if(value==null)return value;if(typeof value!="string"||value.trim().length===0)throw new ThreadMetadataUpdateError(`gitInfo.${field} must not be empty`);return value.trim()}function storedGitInfoField(value,path,field){if(value==null)return null;if(typeof value!="string"||value.trim().length===0)throw new ThreadMetadataStateError(path,`Invalid metadata gitInfo.${field}`);return value.trim()}function toMetadataRecord(gitInfo){return{gitInfo:{...gitInfo.sha===null?{}:{sha:gitInfo.sha},...gitInfo.branch===null?{}:{branch:gitInfo.branch},...gitInfo.originUrl===null?{}:{originUrl:gitInfo.originUrl}}}}function emptyGitInfo(){return{sha:null,branch:null,originUrl:null}}function isRecord5(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNotFoundError(error){return isNodeFsError(error)&&error.code==="ENOENT"}function isNodeFsError(error){return error instanceof Error&&"code"in error}function readError(path,error){return error instanceof Error?new ThreadMetadataStateError(path,`Failed to read metadata sidecar (${error.message})`):new ThreadMetadataStateError(path,`Failed to read metadata sidecar (${String(error)})`)}var ARCHIVE_SUFFIX=".archived",ThreadArchiveStateError=class extends Error{constructor(path,message){super(`${message}: ${path}`),this.name="ThreadArchiveStateError",this.path=path}},ThreadArchiveState=class{constructor(sessionDir){this.sessionDir=sessionDir}async markArchived(thread){await enqueueThreadMutation(thread.id,async()=>{let sidecarPath=sidecarPathForThread(thread);await writeSidecarFileAtomic(sidecarPath,`${JSON.stringify({archivedAt:new Date().toISOString(),thread})}
|
|
9
|
-
`)})}async clearArchived(threadId){await enqueueThreadMutation(threadId,async()=>{let threads=await this.listArchivedThreads();await Promise.all(threads.filter(thread=>thread.id===threadId).map(thread=>rm2(sidecarPathForThread(thread),{force:!0})))})}async unarchive(threadId){return enqueueThreadMutation(threadId,async()=>{let thread=(await this.listArchivedThreads()).find(candidate=>candidate.id===threadId);if(!thread)return;let updatedAt=await touchThreadSession(thread);return await rm2(sidecarPathForThread(thread),{force:!0}),{...thread,updatedAt}})}async isArchived(thread){let path=sidecarPathForThread(thread);try{return await readFile3(path,"utf8"),!0}catch(error){if(isNotFoundError2(error))return!1;throw readError2(path,error)}}async listArchivedThreads(){if(!this.sessionDir)return[];let entries;try{entries=await readdir2(this.sessionDir)}catch(error){if(isNotFoundError2(error))return[];throw readError2(this.sessionDir,error)}let threads=[];for(let entry of entries){if(!entry.endsWith(ARCHIVE_SUFFIX))continue;let thread=await readArchivedThread(join4(this.sessionDir,entry));thread&&threads.push(thread)}return threads}};async function touchThreadSession(thread){if(!thread.sessionPath)throw new Error(`Thread ${thread.id} has no session path to unarchive`);let sessionStat=await stat(thread.sessionPath),previousMs=Date.parse(thread.updatedAt),nextMs=Math.max(Date.now(),sessionStat.mtimeMs+1,Number.isFinite(previousMs)?previousMs+1:0);return await utimes(thread.sessionPath,sessionStat.atime,new Date(nextMs)),new Date(nextMs).toISOString()}function sidecarPathForThread(thread){if(!thread.sessionPath)throw new Error(`Thread ${thread.id} has no session path for archive state`);return`${thread.sessionPath}${ARCHIVE_SUFFIX}`}async function readArchivedThread(path){let content;try{content=await readFile3(path,"utf8")}catch(error){if(isNotFoundError2(error))return null;throw readError2(path,error)}return parseArchivedThread(path,content)}function parseArchivedThread(path,content){let value;try{value=JSON.parse(content)}catch(error){throw error instanceof Error?new ThreadArchiveStateError(path,`Invalid archived thread sidecar JSON (${error.message})`):error}if(!isRecord6(value)||!isRecord6(value.thread))throw new ThreadArchiveStateError(path,"Invalid archived thread sidecar record");let thread=parseWireThread(value.thread);if(!thread)throw new ThreadArchiveStateError(path,"Invalid archived thread record");return thread}function parseWireThread(value){let id=stringField(value.id),sessionId=stringField(value.sessionId),cwd=stringField(value.cwd),createdAt=stringField(value.createdAt),updatedAt=stringField(value.updatedAt),status=isRecord6(value.status)?stringField(value.status.type):null,sessionPath=stringField(value.sessionPath);return!id||!sessionId||!cwd||!createdAt||!updatedAt||!status||!sessionPath||status!=="idle"&&status!=="active"&&status!=="notLoaded"?null:{id,sessionId,cwd,createdAt,updatedAt,status:{type:status},preview:nullableString(value.preview),name:nullableString(value.name),sessionPath}}function stringField(value){return typeof value=="string"&&value.length>0?value:null}function nullableString(value){return typeof value=="string"?value:null}function isRecord6(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNotFoundError2(error){return isNodeFsError2(error)&&error.code==="ENOENT"}function isNodeFsError2(error){return error instanceof Error&&"code"in error}function readError2(path,error){return error instanceof Error?new ThreadArchiveStateError(path,`Failed to read archived thread state (${error.message})`):new ThreadArchiveStateError(path,`Failed to read archived thread state (${String(error)})`)}var GOAL_STATUS_TO_THREAD_STATUS={active:"active",paused:"paused",blocked:"blocked",complete:"complete"};function toThreadGoal(goal){return{threadId:goal.threadId,objective:goal.objective,status:GOAL_STATUS_TO_THREAD_STATUS[goal.status],tokenBudget:goal.tokenBudget??null,tokensUsed:goal.tokensUsed,timeUsedSeconds:goal.timeUsedSeconds,createdAt:goal.createdAt,updatedAt:goal.updatedAt}}import{existsSync as existsSync2,unlinkSync}from"node:fs";var McpWireStatusAdapter=class{#servers;#unsubscribe;constructor(snapshot){this.#servers=mapSnapshot(snapshot)}getServerStatuses(){return this.#servers}update(snapshot){this.#servers=mapSnapshot(snapshot)}bindLiveUpdates(unsubscribe){this.#unsubscribe?.(),this.#unsubscribe=unsubscribe}dispose(){this.#unsubscribe?.(),this.#unsubscribe=void 0}};function createMcpWireStatusAdapter(snapshot){return new McpWireStatusAdapter(snapshot)}function createProcessMcpWireStatusAdapter(options){let config=loadMcpConfig({...options,projectTrusted:!1}),servers=Object.values(config.servers).filter(server=>server.source==="global").map(toConfiguredServer);return createMcpWireStatusAdapter({servers})}var McpWireStatusRegistry=class{#global;#threads=new Map;constructor(global){this.#global=global}setGlobal(adapter){this.#global=adapter}registerThread(threadId,adapter){this.#threads.set(threadId,adapter)}removeThread(threadId){this.#threads.get(threadId)?.dispose(),this.#threads.delete(threadId)}resolve(threadId){return threadId==null?this.#global:this.#threads.get(threadId)}};function createMcpWireStatusRegistry(global){return new McpWireStatusRegistry(global)}function mapSnapshot(snapshot){return[...snapshot.servers].sort((left,right)=>left.name.localeCompare(right.name)).map(server=>({name:server.name,serverInfo:server.serverInfo===null?null:mapServerInfo(server.serverInfo),tools:mapTools(server.tools),resources:server.resources.map(mapResource),resourceTemplates:server.resourceTemplates.map(mapResourceTemplate),authStatus:server.authStatus}))}function toConfiguredServer(server){return{name:server.name,serverInfo:null,tools:[],resources:[],resourceTemplates:[],authStatus:configuredAuthStatus(server)}}function configuredAuthStatus(server){let mode=server.config===void 0?"none":resolveAuthMode(server.config);return mode==="none"?"unsupported":mode==="bearer"?"bearerToken":"notLoggedIn"}function mapServerInfo(info){return{name:info.name,title:info.title,version:info.version,description:info.description,icons:info.icons===null?null:info.icons.map(toJsonValue),websiteUrl:info.websiteUrl}}function mapTools(tools){let mapped={};for(let tool of tools)mapped[tool.name]=mapTool(tool);return mapped}function mapTool(tool){return{name:tool.name,...tool.title===void 0?{}:{title:tool.title},...tool.description===void 0?{}:{description:tool.description},inputSchema:tool.inputSchema,...tool.outputSchema===void 0?{}:{outputSchema:tool.outputSchema},...tool.annotations===void 0?{}:{annotations:tool.annotations},...tool.icons===void 0?{}:{icons:tool.icons.map(toJsonValue)},...tool._meta===void 0?{}:{_meta:tool._meta}}}function mapResource(resource){return{uri:resource.uri,name:resource.name,...resource.title===void 0?{}:{title:resource.title},...resource.description===void 0?{}:{description:resource.description},...resource.mimeType===void 0?{}:{mimeType:resource.mimeType},...resource.size===void 0?{}:{size:resource.size},...resource.annotations===void 0?{}:{annotations:resource.annotations},...resource.icons===void 0?{}:{icons:resource.icons.map(toJsonValue)},...resource._meta===void 0?{}:{_meta:resource._meta}}}function mapResourceTemplate(template){return{uriTemplate:template.uriTemplate,name:template.name,...template.title===void 0?{}:{title:template.title},...template.description===void 0?{}:{description:template.description},...template.mimeType===void 0?{}:{mimeType:template.mimeType},...template.annotations===void 0?{}:{annotations:template.annotations},...template.icons===void 0?{}:{icons:template.icons.map(toJsonValue)},...template._meta===void 0?{}:{_meta:template._meta}}}function toJsonValue(value){return value}import{statSync as statSync2}from"node:fs";function buildDiskThread(info){return{id:info.id,sessionId:info.id,sessionPath:info.path,cwd:info.cwd,createdAt:info.created.toISOString(),updatedAt:persistedUpdatedAt(info),status:{type:"notLoaded"},preview:info.firstMessage&&info.firstMessage!=="(no messages)"?info.firstMessage:null,name:info.name??null}}function persistedUpdatedAt(info){try{let persistedMs=Math.max(info.modified.getTime(),statSync2(info.path).mtimeMs);return new Date(persistedMs).toISOString()}catch{return info.modified.toISOString()}}function compareThreads(left,right){let updated=Date.parse(right.updatedAt)-Date.parse(left.updatedAt);return updated!==0?updated:left.id.localeCompare(right.id)}function encodeCursor2(offset){return Buffer.from(String(offset),"utf8").toString("base64")}function decodeCursor2(cursor){if(!cursor)return 0;let offset=Number.parseInt(Buffer.from(cursor,"base64").toString("utf8"),10);return Number.isFinite(offset)&&offset>=0?offset:0}var ThreadNotFoundError=class extends Error{constructor(threadId){super(`Thread not found: ${threadId}`),this.name="ThreadNotFoundError",this.threadId=threadId}},ThreadRegistry=class{constructor(options={}){this.entries=new Map,this.deletedThreadIds=new Set,this.agentDir=options.agentDir?resolvePath(options.agentDir):void 0,this.sessionDir=options.sessionDir?resolvePath(options.sessionDir):void 0,this.createSession=options.createSession??createAgentSession,this.mcpWireStatuses=createMcpWireStatusRegistry(options.mcpWireStatusAdapter)}async createThread(options){let cwd=resolvePath(options.cwd),sessionManager=SessionManager.create(cwd,this.sessionDir),result=await this.createSession({cwd,agentDir:this.agentDir,sessionManager,model:options.model});return this.deletedThreadIds.delete(result.session.sessionId),this.registerSession(result.session,cwd,void 0,result.initialNotifications,result.mcpWireStatusAdapter)}async resumeThread(threadId){let loaded=this.entries.get(threadId);if(loaded)return loaded;if(this.deletedThreadIds.has(threadId))throw new ThreadNotFoundError(threadId);let sessionInfo=await this.findSessionInfo(threadId);if(!sessionInfo)throw new ThreadNotFoundError(threadId);let sessionManager=SessionManager.open(sessionInfo.path,this.sessionDir,sessionInfo.cwd||void 0),result=await this.createSession({cwd:sessionManager.getCwd(),agentDir:this.agentDir,sessionManager});return this.registerSession(result.session,sessionManager.getCwd(),sessionInfo,result.initialNotifications,result.mcpWireStatusAdapter)}async forkThread(threadId,options={}){let source=await this.resumeThread(threadId),cwd=resolvePath(options.cwd??source.cwd),sourceFile=source.session.sessionFile,sessionManager=sourceFile&&existsSync2(sourceFile)?SessionManager.forkFrom(sourceFile,cwd,this.sessionDir):SessionManager.create(cwd,this.sessionDir,sourceFile?{parentSession:sourceFile}:void 0),result=await this.createSession({cwd,agentDir:this.agentDir,sessionManager,model:options.model});return this.deletedThreadIds.delete(result.session.sessionId),this.registerSession(result.session,cwd,void 0,result.initialNotifications,result.mcpWireStatusAdapter)}async deleteThread(threadId){let loaded=this.entries.get(threadId);if(loaded){loaded.session.dispose(),this.entries.delete(threadId),this.mcpWireStatuses.removeThread(threadId),this.deletedThreadIds.add(threadId);let sessionFile=loaded.session.sessionFile;return sessionFile&&existsSync2(sessionFile)&&unlinkSync(sessionFile),!0}let sessionInfo=await this.findSessionInfo(threadId);return sessionInfo?(existsSync2(sessionInfo.path)&&unlinkSync(sessionInfo.path),this.deletedThreadIds.add(threadId),!0):(this.deletedThreadIds.add(threadId),!1)}listLoaded(){return[...this.entries.values()].map(entry=>this.buildLoadedThread(entry))}async listThreads(options={}){let offset=decodeCursor2(options.cursor),limit=Math.max(0,options.limit??50),threadsById=new Map;for(let info of await this.listSessionInfos())this.deletedThreadIds.has(info.id)||threadsById.set(info.id,buildDiskThread(info));for(let entry of this.entries.values())threadsById.set(entry.id,this.buildLoadedThread(entry));let threads=[...threadsById.values()].sort(compareThreads),page=threads.slice(offset,offset+limit),nextOffset=offset+page.length;return{threads:page,nextCursor:nextOffset<threads.length?encodeCursor2(nextOffset):null}}runThreadTask(threadId,task){let entry=this.getLoadedThread(threadId),run=entry.taskQueue.then(task,task);return entry.taskQueue=run.then(()=>{},()=>{}),run}getLoadedThread(threadId){let entry=this.entries.get(threadId);if(!entry)throw new ThreadNotFoundError(threadId);return entry}getMcpWireStatusAdapter(threadId){let adapter=this.mcpWireStatuses.resolve(threadId);if(adapter!==void 0||threadId===void 0||threadId===null)return adapter;this.getLoadedThread(threadId)}unloadThread(threadId){return this.entries.get(threadId)?.session.dispose(),this.mcpWireStatuses.removeThread(threadId),this.entries.delete(threadId)}async dispose(){let entries=[...this.entries.values()];await Promise.all(entries.map(entry=>entry.taskQueue));for(let entry of entries)entry.session.dispose(),this.mcpWireStatuses.removeThread(entry.id);this.entries.clear()}buildThread(entry){return this.buildLoadedThread(entry)}getSessionDir(){return this.sessionDir}registerSession(session,cwd,sessionInfo,initialNotifications=[],mcpWireStatusAdapter){let existing=this.entries.get(session.sessionId);if(existing)return mcpWireStatusAdapter!==void 0&&(existing.mcpWireStatusAdapter=mcpWireStatusAdapter,this.mcpWireStatuses.registerThread(session.sessionId,mcpWireStatusAdapter)),existing.session!==session&&session.dispose(),existing;let now=new Date().toISOString(),entry={id:session.sessionId,session,cwd,subscribers:new Set,activeTurn:null,queuedTerminalNotifications:[...initialNotifications],status:"idle",taskQueue:Promise.resolve(),createdAt:sessionInfo?.created.toISOString()??now,updatedAt:sessionInfo?.modified.toISOString()??now,mcpWireStatusAdapter};return this.entries.set(entry.id,entry),mcpWireStatusAdapter!==void 0&&this.mcpWireStatuses.registerThread(entry.id,mcpWireStatusAdapter),entry}async findSessionInfo(threadId){return(await this.listSessionInfos()).find(info=>info.id===threadId)}async listSessionInfos(){return this.sessionDir?SessionManager.listAll(this.sessionDir):SessionManager.listAll()}buildLoadedThread(entry){return{id:entry.id,sessionId:entry.session.sessionId,sessionPath:entry.session.sessionFile??null,cwd:entry.cwd,createdAt:entry.createdAt,updatedAt:entry.updatedAt,status:{type:entry.status},preview:entry.session.getUserMessagesForForking()[0]?.text??null,name:entry.session.sessionName??null}}};import*as crypto from"node:crypto";function createTurnId(){return crypto.randomUUID()}var TurnEngineError=class extends RpcHandlerError{constructor(error){super(error),this.name="TurnEngineError",this.error=error}};function parseInput(input){if(input.length===0)throw invalidParams("Invalid params: input must include at least one text item");let content=[],textParts=[];for(let item of input)switch(item.type){case"text":{if(item.text.trim().length===0)throw invalidParams("Invalid params: text input must not be empty");let textItem={type:"text",text:item.text,text_elements:item.text_elements??[]};content.push(textItem),textParts.push(item.text);break}case"image":case"localImage":case"skill":case"mention":throw invalidParams(`Invalid params: unsupported input item type ${item.type}`);default:throw invalidParams("Invalid params: unknown input item type")}if(textParts.length===0)throw invalidParams("Invalid params: text input is required");return{text:textParts.join(`
|
|
9
|
+
`)})}async clearArchived(threadId){await enqueueThreadMutation(threadId,async()=>{let threads=await this.listArchivedThreads();await Promise.all(threads.filter(thread=>thread.id===threadId).map(thread=>rm2(sidecarPathForThread(thread),{force:!0})))})}async unarchive(threadId){return enqueueThreadMutation(threadId,async()=>{let thread=(await this.listArchivedThreads()).find(candidate=>candidate.id===threadId);if(!thread)return;let updatedAt=await touchThreadSession(thread);return await rm2(sidecarPathForThread(thread),{force:!0}),{...thread,updatedAt}})}async isArchived(thread){let path=sidecarPathForThread(thread);try{return await readFile3(path,"utf8"),!0}catch(error){if(isNotFoundError2(error))return!1;throw readError2(path,error)}}async listArchivedThreads(){if(!this.sessionDir)return[];let entries;try{entries=await readdir2(this.sessionDir)}catch(error){if(isNotFoundError2(error))return[];throw readError2(this.sessionDir,error)}let threads=[];for(let entry of entries){if(!entry.endsWith(ARCHIVE_SUFFIX))continue;let thread=await readArchivedThread(join4(this.sessionDir,entry));thread&&threads.push(thread)}return threads}};async function touchThreadSession(thread){if(!thread.sessionPath)throw new Error(`Thread ${thread.id} has no session path to unarchive`);let sessionStat=await stat(thread.sessionPath),previousMs=Date.parse(thread.updatedAt),nextMs=Math.max(Date.now(),sessionStat.mtimeMs+1,Number.isFinite(previousMs)?previousMs+1:0);return await utimes(thread.sessionPath,sessionStat.atime,new Date(nextMs)),new Date(nextMs).toISOString()}function sidecarPathForThread(thread){if(!thread.sessionPath)throw new Error(`Thread ${thread.id} has no session path for archive state`);return`${thread.sessionPath}${ARCHIVE_SUFFIX}`}async function readArchivedThread(path){let content;try{content=await readFile3(path,"utf8")}catch(error){if(isNotFoundError2(error))return null;throw readError2(path,error)}return parseArchivedThread(path,content)}function parseArchivedThread(path,content){let value;try{value=JSON.parse(content)}catch(error){throw error instanceof Error?new ThreadArchiveStateError(path,`Invalid archived thread sidecar JSON (${error.message})`):error}if(!isRecord6(value)||!isRecord6(value.thread))throw new ThreadArchiveStateError(path,"Invalid archived thread sidecar record");let thread=parseWireThread(value.thread);if(!thread)throw new ThreadArchiveStateError(path,"Invalid archived thread record");return thread}function parseWireThread(value){let id=stringField(value.id),sessionId=stringField(value.sessionId),cwd=stringField(value.cwd),createdAt=stringField(value.createdAt),updatedAt=stringField(value.updatedAt),status=isRecord6(value.status)?stringField(value.status.type):null,sessionPath=stringField(value.sessionPath);return!id||!sessionId||!cwd||!createdAt||!updatedAt||!status||!sessionPath||status!=="idle"&&status!=="active"&&status!=="notLoaded"?null:{id,sessionId,cwd,createdAt,updatedAt,status:{type:status},preview:nullableString(value.preview),name:nullableString(value.name),sessionPath}}function stringField(value){return typeof value=="string"&&value.length>0?value:null}function nullableString(value){return typeof value=="string"?value:null}function isRecord6(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function isNotFoundError2(error){return isNodeFsError2(error)&&error.code==="ENOENT"}function isNodeFsError2(error){return error instanceof Error&&"code"in error}function readError2(path,error){return error instanceof Error?new ThreadArchiveStateError(path,`Failed to read archived thread state (${error.message})`):new ThreadArchiveStateError(path,`Failed to read archived thread state (${String(error)})`)}var GOAL_STATUS_TO_THREAD_STATUS={active:"active",paused:"paused",blocked:"blocked",complete:"complete"};function toThreadGoal(goal){return{threadId:goal.threadId,objective:goal.objective,status:GOAL_STATUS_TO_THREAD_STATUS[goalDisplayStatus(goal)],tokenBudget:goal.tokenBudget??null,tokensUsed:goal.tokensUsed,timeUsedSeconds:goal.timeUsedSeconds,createdAt:goal.createdAt,updatedAt:goal.updatedAt}}import{existsSync as existsSync2,unlinkSync}from"node:fs";var McpWireStatusAdapter=class{#servers;#unsubscribe;constructor(snapshot){this.#servers=mapSnapshot(snapshot)}getServerStatuses(){return this.#servers}update(snapshot){this.#servers=mapSnapshot(snapshot)}bindLiveUpdates(unsubscribe){this.#unsubscribe?.(),this.#unsubscribe=unsubscribe}dispose(){this.#unsubscribe?.(),this.#unsubscribe=void 0}};function createMcpWireStatusAdapter(snapshot){return new McpWireStatusAdapter(snapshot)}function createProcessMcpWireStatusAdapter(options){let config=loadMcpConfig({...options,projectTrusted:!1}),servers=Object.values(config.servers).filter(server=>server.source==="global").map(toConfiguredServer);return createMcpWireStatusAdapter({servers})}var McpWireStatusRegistry=class{#global;#threads=new Map;constructor(global){this.#global=global}setGlobal(adapter){this.#global=adapter}registerThread(threadId,adapter){this.#threads.set(threadId,adapter)}removeThread(threadId){this.#threads.get(threadId)?.dispose(),this.#threads.delete(threadId)}resolve(threadId){return threadId==null?this.#global:this.#threads.get(threadId)}};function createMcpWireStatusRegistry(global){return new McpWireStatusRegistry(global)}function mapSnapshot(snapshot){return[...snapshot.servers].sort((left,right)=>left.name.localeCompare(right.name)).map(server=>({name:server.name,serverInfo:server.serverInfo===null?null:mapServerInfo(server.serverInfo),tools:mapTools(server.tools),resources:server.resources.map(mapResource),resourceTemplates:server.resourceTemplates.map(mapResourceTemplate),authStatus:server.authStatus}))}function toConfiguredServer(server){return{name:server.name,serverInfo:null,tools:[],resources:[],resourceTemplates:[],authStatus:configuredAuthStatus(server)}}function configuredAuthStatus(server){let mode=server.config===void 0?"none":resolveAuthMode(server.config);return mode==="none"?"unsupported":mode==="bearer"?"bearerToken":"notLoggedIn"}function mapServerInfo(info){return{name:info.name,title:info.title,version:info.version,description:info.description,icons:info.icons===null?null:info.icons.map(toJsonValue),websiteUrl:info.websiteUrl}}function mapTools(tools){let mapped={};for(let tool of tools)mapped[tool.name]=mapTool(tool);return mapped}function mapTool(tool){return{name:tool.name,...tool.title===void 0?{}:{title:tool.title},...tool.description===void 0?{}:{description:tool.description},inputSchema:tool.inputSchema,...tool.outputSchema===void 0?{}:{outputSchema:tool.outputSchema},...tool.annotations===void 0?{}:{annotations:tool.annotations},...tool.icons===void 0?{}:{icons:tool.icons.map(toJsonValue)},...tool._meta===void 0?{}:{_meta:tool._meta}}}function mapResource(resource){return{uri:resource.uri,name:resource.name,...resource.title===void 0?{}:{title:resource.title},...resource.description===void 0?{}:{description:resource.description},...resource.mimeType===void 0?{}:{mimeType:resource.mimeType},...resource.size===void 0?{}:{size:resource.size},...resource.annotations===void 0?{}:{annotations:resource.annotations},...resource.icons===void 0?{}:{icons:resource.icons.map(toJsonValue)},...resource._meta===void 0?{}:{_meta:resource._meta}}}function mapResourceTemplate(template){return{uriTemplate:template.uriTemplate,name:template.name,...template.title===void 0?{}:{title:template.title},...template.description===void 0?{}:{description:template.description},...template.mimeType===void 0?{}:{mimeType:template.mimeType},...template.annotations===void 0?{}:{annotations:template.annotations},...template.icons===void 0?{}:{icons:template.icons.map(toJsonValue)},...template._meta===void 0?{}:{_meta:template._meta}}}function toJsonValue(value){return value}import{statSync as statSync2}from"node:fs";function buildDiskThread(info){return{id:info.id,sessionId:info.id,sessionPath:info.path,cwd:info.cwd,createdAt:info.created.toISOString(),updatedAt:persistedUpdatedAt(info),status:{type:"notLoaded"},preview:info.firstMessage&&info.firstMessage!=="(no messages)"?info.firstMessage:null,name:info.name??null}}function persistedUpdatedAt(info){try{let persistedMs=Math.max(info.modified.getTime(),statSync2(info.path).mtimeMs);return new Date(persistedMs).toISOString()}catch{return info.modified.toISOString()}}function compareThreads(left,right){let updated=Date.parse(right.updatedAt)-Date.parse(left.updatedAt);return updated!==0?updated:left.id.localeCompare(right.id)}function encodeCursor2(offset){return Buffer.from(String(offset),"utf8").toString("base64")}function decodeCursor2(cursor){if(!cursor)return 0;let offset=Number.parseInt(Buffer.from(cursor,"base64").toString("utf8"),10);return Number.isFinite(offset)&&offset>=0?offset:0}var ThreadNotFoundError=class extends Error{constructor(threadId){super(`Thread not found: ${threadId}`),this.name="ThreadNotFoundError",this.threadId=threadId}},ThreadRegistry=class{constructor(options={}){this.entries=new Map,this.deletedThreadIds=new Set,this.agentDir=options.agentDir?resolvePath(options.agentDir):void 0,this.sessionDir=options.sessionDir?resolvePath(options.sessionDir):void 0,this.createSession=options.createSession??createAgentSession,this.mcpWireStatuses=createMcpWireStatusRegistry(options.mcpWireStatusAdapter)}async createThread(options){let cwd=resolvePath(options.cwd),sessionManager=SessionManager.create(cwd,this.sessionDir),result=await this.createSession({cwd,agentDir:this.agentDir,sessionManager,model:options.model});return this.deletedThreadIds.delete(result.session.sessionId),this.registerSession(result.session,cwd,void 0,result.initialNotifications,result.mcpWireStatusAdapter)}async resumeThread(threadId){let loaded=this.entries.get(threadId);if(loaded)return loaded;if(this.deletedThreadIds.has(threadId))throw new ThreadNotFoundError(threadId);let sessionInfo=await this.findSessionInfo(threadId);if(!sessionInfo)throw new ThreadNotFoundError(threadId);let sessionManager=SessionManager.open(sessionInfo.path,this.sessionDir,sessionInfo.cwd||void 0),result=await this.createSession({cwd:sessionManager.getCwd(),agentDir:this.agentDir,sessionManager});return this.registerSession(result.session,sessionManager.getCwd(),sessionInfo,result.initialNotifications,result.mcpWireStatusAdapter)}async forkThread(threadId,options={}){let source=await this.resumeThread(threadId),cwd=resolvePath(options.cwd??source.cwd),sourceFile=source.session.sessionFile,sessionManager=sourceFile&&existsSync2(sourceFile)?SessionManager.forkFrom(sourceFile,cwd,this.sessionDir):SessionManager.create(cwd,this.sessionDir,sourceFile?{parentSession:sourceFile}:void 0),result=await this.createSession({cwd,agentDir:this.agentDir,sessionManager,model:options.model});return this.deletedThreadIds.delete(result.session.sessionId),this.registerSession(result.session,cwd,void 0,result.initialNotifications,result.mcpWireStatusAdapter)}async deleteThread(threadId){let loaded=this.entries.get(threadId);if(loaded){loaded.session.dispose(),this.entries.delete(threadId),this.mcpWireStatuses.removeThread(threadId),this.deletedThreadIds.add(threadId);let sessionFile=loaded.session.sessionFile;return sessionFile&&existsSync2(sessionFile)&&unlinkSync(sessionFile),!0}let sessionInfo=await this.findSessionInfo(threadId);return sessionInfo?(existsSync2(sessionInfo.path)&&unlinkSync(sessionInfo.path),this.deletedThreadIds.add(threadId),!0):(this.deletedThreadIds.add(threadId),!1)}listLoaded(){return[...this.entries.values()].map(entry=>this.buildLoadedThread(entry))}async listThreads(options={}){let offset=decodeCursor2(options.cursor),limit=Math.max(0,options.limit??50),threadsById=new Map;for(let info of await this.listSessionInfos())this.deletedThreadIds.has(info.id)||threadsById.set(info.id,buildDiskThread(info));for(let entry of this.entries.values())threadsById.set(entry.id,this.buildLoadedThread(entry));let threads=[...threadsById.values()].sort(compareThreads),page=threads.slice(offset,offset+limit),nextOffset=offset+page.length;return{threads:page,nextCursor:nextOffset<threads.length?encodeCursor2(nextOffset):null}}runThreadTask(threadId,task){let entry=this.getLoadedThread(threadId),run=entry.taskQueue.then(task,task);return entry.taskQueue=run.then(()=>{},()=>{}),run}getLoadedThread(threadId){let entry=this.entries.get(threadId);if(!entry)throw new ThreadNotFoundError(threadId);return entry}getMcpWireStatusAdapter(threadId){let adapter=this.mcpWireStatuses.resolve(threadId);if(adapter!==void 0||threadId===void 0||threadId===null)return adapter;this.getLoadedThread(threadId)}unloadThread(threadId){return this.entries.get(threadId)?.session.dispose(),this.mcpWireStatuses.removeThread(threadId),this.entries.delete(threadId)}async dispose(){let entries=[...this.entries.values()];await Promise.all(entries.map(entry=>entry.taskQueue));for(let entry of entries)entry.session.dispose(),this.mcpWireStatuses.removeThread(entry.id);this.entries.clear()}buildThread(entry){return this.buildLoadedThread(entry)}getSessionDir(){return this.sessionDir}registerSession(session,cwd,sessionInfo,initialNotifications=[],mcpWireStatusAdapter){let existing=this.entries.get(session.sessionId);if(existing)return mcpWireStatusAdapter!==void 0&&(existing.mcpWireStatusAdapter=mcpWireStatusAdapter,this.mcpWireStatuses.registerThread(session.sessionId,mcpWireStatusAdapter)),existing.session!==session&&session.dispose(),existing;let now=new Date().toISOString(),entry={id:session.sessionId,session,cwd,subscribers:new Set,activeTurn:null,queuedTerminalNotifications:[...initialNotifications],status:"idle",taskQueue:Promise.resolve(),createdAt:sessionInfo?.created.toISOString()??now,updatedAt:sessionInfo?.modified.toISOString()??now,mcpWireStatusAdapter};return this.entries.set(entry.id,entry),mcpWireStatusAdapter!==void 0&&this.mcpWireStatuses.registerThread(entry.id,mcpWireStatusAdapter),entry}async findSessionInfo(threadId){return(await this.listSessionInfos()).find(info=>info.id===threadId)}async listSessionInfos(){return this.sessionDir?SessionManager.listAll(this.sessionDir):SessionManager.listAll()}buildLoadedThread(entry){return{id:entry.id,sessionId:entry.session.sessionId,sessionPath:entry.session.sessionFile??null,cwd:entry.cwd,createdAt:entry.createdAt,updatedAt:entry.updatedAt,status:{type:entry.status},preview:entry.session.getUserMessagesForForking()[0]?.text??null,name:entry.session.sessionName??null}}};import*as crypto from"node:crypto";function createTurnId(){return crypto.randomUUID()}var TurnEngineError=class extends RpcHandlerError{constructor(error){super(error),this.name="TurnEngineError",this.error=error}};function parseInput(input){if(input.length===0)throw invalidParams("Invalid params: input must include at least one text item");let content=[],textParts=[];for(let item of input)switch(item.type){case"text":{if(item.text.trim().length===0)throw invalidParams("Invalid params: text input must not be empty");let textItem={type:"text",text:item.text,text_elements:item.text_elements??[]};content.push(textItem),textParts.push(item.text);break}case"image":case"localImage":case"skill":case"mention":throw invalidParams(`Invalid params: unsupported input item type ${item.type}`);default:throw invalidParams("Invalid params: unknown input item type")}if(textParts.length===0)throw invalidParams("Invalid params: text input is required");return{text:textParts.join(`
|
|
10
10
|
`),content}}function buildTurn(turnId,status,startedAtMs,completedAtMs,items,message){return{id:turnId,items,itemsView:"full",status,error:status==="failed"?{message:message??"Turn failed",codexErrorInfo:"other",additionalDetails:null}:null,startedAt:startedAtMs/1e3,completedAt:completedAtMs===null?null:completedAtMs/1e3,durationMs:completedAtMs===null?null:completedAtMs-startedAtMs}}function buildUserMessage(clientUserMessageId,content){return{type:"userMessage",id:clientUserMessageId??crypto.randomUUID(),clientId:clientUserMessageId,content:[...content]}}function wireItemToJson(item){let jsonItem={};for(let[key,value]of Object.entries(item))jsonItem[key]=unknownToJsonValue(value);return jsonItem}function readLoggedItems(turnLog,threadId,turnId){return turnLog.readTurns(threadId).find(turn=>turn.turnId===turnId)?.items.map(item=>wireItemToJson(item))??[]}function invalidRequest3(message){return new TurnEngineError({code:-32600,message})}function invalidParams(message){return new TurnEngineError({code:-32602,message})}function toTurnEngineError(error){return error instanceof TurnEngineError?error:new TurnEngineError({code:-32603,message:error instanceof Error?error.message:String(error)})}function unknownToJsonValue(value){if(value===null||typeof value=="string"||typeof value=="number"||typeof value=="boolean")return value;if(Array.isArray(value))return value.map(unknownToJsonValue);if(typeof value=="object"){let objectValue2={};for(let[key,child]of Object.entries(value))objectValue2[key]=unknownToJsonValue(child);return objectValue2}return null}function registerThreadGoalHandlers(registry,options){let handlers=new ThreadGoalHandlers(options);for(let registration of handlers.registrations())registry.register(registration.method,{handler:registration.handler,scope:"thread"})}var ThreadGoalHandlers=class{constructor(options){this.threads=options.threads,this.notifications=options.notifications,this.deferUntilResponded=options.deferUntilResponded}registrations(){return[{method:"thread/goal/set",handler:context=>this.set(context.connection,context.request)},{method:"thread/goal/get",handler:context=>this.get(context.request)},{method:"thread/goal/clear",handler:context=>this.clear(context.connection,context.request)}]}async set(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),status=parseStatus(params.status),objective=parseObjective(params.objective),tokenBudget=parseTokenBudget(params),entry=await this.requireThread(threadId),ref=goalStoreRef(entry.session.sessionManager,entry.cwd),goal=await this.threads.runThreadTask(threadId,async()=>{if(await readGoal(ref)===null){if(objective===void 0)throw invalidRequest3(`objective is required for new goal: ${threadId}`);let created=await createGoal(ref,objective,tokenBudget.present&&tokenBudget.value!==null?tokenBudget.value:void 0);return status===void 0||status==="active"?created:updateGoal(ref,{status},status==="complete"?"model":"user")}let update={...objective===void 0?{}:{objective},...status===void 0?{}:{status},...tokenBudget.present?{tokenBudget:tokenBudget.value}:{}};return updateGoal(ref,update,status==="complete"?"model":"user")});goal.status==="active"&&entry.session.emitExtensionEvent(GOAL_STORE_CHANGED_EVENT,{threadId,ctx:entry.session.extensionRunner.createCommandContext()});let response={goal:toThreadGoal(goal)},notify=()=>{this.notifications.broadcast({method:"thread/goal/updated",params:{threadId,turnId:null,goal:response.goal}})};return this.deferOrRun(connection,notify),response}async get(request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry=await this.requireThread(threadId),ref=goalStoreRef(entry.session.sessionManager,entry.cwd),goal=await this.threads.runThreadTask(threadId,()=>readGoal(ref));return{goal:goal===null?null:toThreadGoal(goal)}}async clear(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry=await this.requireThread(threadId),ref=goalStoreRef(entry.session.sessionManager,entry.cwd),cleared=await this.threads.runThreadTask(threadId,()=>clearGoal(ref));if(cleared){let notify=()=>{this.notifications.broadcast({method:"thread/goal/cleared",params:{threadId}})};this.deferOrRun(connection,notify)}return{cleared}}async requireThread(threadId){let entry;try{entry=await this.threads.resumeThread(threadId)}catch(error){throw error instanceof ThreadNotFoundError?invalidRequest3(`thread not found: ${threadId}`):error}if(entry.session.sessionFile===void 0)throw invalidRequest3(`ephemeral thread does not support goals: ${threadId}`);return entry}deferOrRun(connection,action){this.deferUntilResponded?.(connectionId(connection),action)!==!0&&action()}};function parseStatus(value){if(value!=null)switch(value){case"active":return"active";case"paused":return"paused";case"complete":return"complete";case"blocked":case"usageLimited":case"budgetLimited":throw invalidRequest3(`unsupported goal status: ${value}`);default:throw invalidParams("Invalid params: status must be active, paused, or complete")}}function parseObjective(value){if(value!=null){if(typeof value!="string")throw invalidParams("Invalid params: objective must be a string or null");return value}}function parseTokenBudget(params){if(!Object.hasOwn(params,"tokenBudget"))return{present:!1};let value=params.tokenBudget;if(value===null)return{present:!0,value:null};if(typeof value!="number"||!Number.isSafeInteger(value)||value<0)throw invalidParams("Invalid params: tokenBudget must be a non-negative integer or null");return{present:!0,value}}function paginateHistory(values,options){let cursor=options.cursor===null?null:decodeCursor3(options.cursor,options),ordered=options.sortDirection==="asc"?[...values]:[...values].reverse(),window=cursor===null?ordered:windowFromCursor(ordered,cursor),page=window.slice(0,options.limit),nextCursor=window.length>page.length?encodeCursor3({...options,anchor:page[page.length-1]?.key??"",includeAnchor:!1}):null,backwardsCursor=page.length>0?encodeCursor3({...options,anchor:page[0]?.key??"",includeAnchor:!0}):null;return{data:page.map(value=>value.value),nextCursor,backwardsCursor}}function invalidHistory(message){return new RpcHandlerError({code:-32600,message})}function inclusiveTurnHistoryCursor(threadId,turnId){return encodeCursor3({kind:"turn",threadId,turnId:null,sortDirection:null,anchor:turnId,includeAnchor:!0})}function windowFromCursor(values,cursor){let anchorIndex=values.findIndex(value=>value.key===cursor.anchor);if(anchorIndex<0)throw invalidHistory("invalid cursor: anchor is no longer present");return values.slice(cursor.includeAnchor?anchorIndex:anchorIndex+1)}function encodeCursor3(options){return JSON.stringify({kind:options.kind,threadId:options.threadId,turnId:options.turnId,sortDirection:options.sortDirection,anchor:options.anchor,includeAnchor:options.includeAnchor})}function decodeCursor3(value,options){let parsed;try{parsed=JSON.parse(value)}catch(error){throw error instanceof SyntaxError?invalidHistory(`invalid cursor: ${value}`):error}if(!isHistoryCursor(parsed))throw invalidHistory(`invalid cursor: ${value}`);if(parsed.kind!==options.kind||parsed.threadId!==options.threadId||parsed.turnId!==options.turnId)throw invalidHistory("invalid cursor: cursor is not scoped to this history request");if(parsed.sortDirection!==null){let directionMatches=parsed.sortDirection===options.sortDirection;if(parsed.includeAnchor?directionMatches:!directionMatches)throw invalidHistory("invalid cursor: cursor direction does not match the request")}return parsed}function isHistoryCursor(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;let record=Object.fromEntries(Object.entries(value));return(record.kind==="turn"||record.kind==="item")&&typeof record.threadId=="string"&&(record.turnId===null||typeof record.turnId=="string")&&(record.sortDirection===null||record.sortDirection==="asc"||record.sortDirection==="desc")&&typeof record.anchor=="string"&&typeof record.includeAnchor=="boolean"}var ACTIVE_STATUS={type:"active",activeFlags:[]},IDLE_STATUS={type:"idle"},NOT_LOADED_STATUS={type:"notLoaded"},metadataState=new ThreadMetadataState;async function buildWireThread(entry,turnLog,includeTurns,options={}){let model="session"in entry?entry.session.model:void 0,wire="session"in entry?entryToWire(entry):entry,createdAt=isoSeconds(wire.createdAt),updatedAt=isoSeconds(wire.updatedAt);return{id:wire.id,sessionId:wire.sessionId,forkedFromId:options.forkedFromId??null,parentThreadId:null,preview:wire.preview??"",ephemeral:!1,modelProvider:model?.provider??"unknown",createdAt,updatedAt,recencyAt:options.recencyAt===null?null:isoSeconds(options.recencyAt??wire.updatedAt),status:toGeneratedStatus(wire.status.type),path:"session"in entry?entry.session.sessionFile??null:wire.sessionPath,cwd:wire.cwd,cliVersion:VERSION,source:"appServer",threadSource:null,agentNickname:null,agentRole:null,gitInfo:await metadataState.readGitInfo(wire),name:wire.name,turns:includeTurns?threadTurns(entry,turnLog):[]}}function entryToWire(entry){return{id:entry.id,sessionId:entry.session.sessionId,sessionPath:entry.session.sessionFile??null,cwd:entry.cwd,createdAt:entry.createdAt,updatedAt:entry.updatedAt,status:{type:entry.status},preview:entry.session.getUserMessagesForForking()[0]?.text??null,name:entry.session.sessionName??null}}function loggedTurnToWireTurn(turn,itemsView="full"){let items=turn.items.map(wireItemToThreadItem);return{id:turn.turnId,items:itemsForView(items,itemsView),itemsView,status:turn.status==="running"?"inProgress":turn.status,error:turn.error===null?null:{message:turn.error,codexErrorInfo:"other",additionalDetails:null},startedAt:isoSeconds(turn.startedAt),completedAt:turn.completedAt===null?null:isoSeconds(turn.completedAt),durationMs:turn.durationMs}}function turnsForEntry(entry,turnLog){let loggedTurns=turnLog.readTurns(entry.id);if(loggedTurns.length>0)return loggedTurns;let entries="session"in entry?entry.session.sessionManager.getEntries():"entries"in entry?entry.entries:[];return turnsFromSessionEntries(entries,entry.createdAt)}function turnsFromSessionEntries(entries,fallbackStartedAt){let turns=[],current;for(let entry of entries){if(entry.type!=="message")continue;if(entry.message.role==="user"){current={turnId:`turn-${turns.length+1}`,startedAt:entry.timestamp||fallbackStartedAt,completedAt:null,durationMs:null,error:null,status:"completed",items:[{id:entry.id,type:"userMessage",content:userInputContent(entry.message.content)}]},turns.push(current);continue}if(entry.message.role!=="assistant"||!current)continue;let text=assistantText(entry.message.content);text.length!==0&¤t.items.push({id:entry.id,type:"agentMessage",text,phase:null,memoryCitation:null})}return turns}function userInputContent(content){return typeof content=="string"?[{type:"text",text:content,text_elements:[]}]:Array.isArray(content)?content.flatMap(item=>!isRecord7(item)||item.type!=="text"||typeof item.text!="string"?[]:[{type:"text",text:item.text,text_elements:[]}]):[]}function assistantText(content){return Array.isArray(content)?content.flatMap(item=>isRecord7(item)&&item.type==="text"&&typeof item.text=="string"?[item.text]:[]).join(""):""}function isRecord7(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function threadTurns(entry,turnLog){return turnsForEntry(entry,turnLog).map(turn=>loggedTurnToWireTurn(turn))}function wireItemToThreadItem(item){let type2=item.type,id=typeof item.id=="string"&&item.id.length>0?item.id:"item",jsonItem=wireItemToJson(item);return type2==="userMessage"?{...jsonItem,type:"userMessage",id,clientId:typeof item.clientId=="string"?item.clientId:null,content:Array.isArray(jsonItem.content)?jsonItem.content:[]}:type2==="reasoning"?{...jsonItem,type:"reasoning",id,summary:Array.isArray(jsonItem.summary)?jsonItem.summary:[],content:Array.isArray(jsonItem.content)?jsonItem.content:[stringField2(item,"text")]}:type2==="plan"?{...jsonItem,type:"plan",id,text:stringField2(item,"text")}:type2==="agentMessage"?{...jsonItem,type:"agentMessage",id,text:stringField2(item,"text"),phase:jsonItem.phase??null,memoryCitation:jsonItem.memoryCitation??null}:{...jsonItem,type:typeof type2=="string"?type2:"agentMessage",id}}function itemsForView(items,itemsView){if(itemsView==="notLoaded")return[];if(itemsView==="full")return items;let firstUserMessage=items.find(item=>item.type==="userMessage"),finalAgentMessage=[...items].reverse().find(item=>item.type==="agentMessage");return firstUserMessage&&finalAgentMessage&&firstUserMessage.id!==finalAgentMessage.id?[firstUserMessage,finalAgentMessage]:firstUserMessage?[firstUserMessage]:finalAgentMessage?[finalAgentMessage]:[]}function stringField2(item,key){let value=item[key];return typeof value=="string"?value:""}function toGeneratedStatus(status){switch(status){case"active":return ACTIVE_STATUS;case"idle":return IDLE_STATUS;case"notLoaded":return NOT_LOADED_STATUS}}function isoSeconds(value){let parsed=Date.parse(value);return Number.isFinite(parsed)?parsed/1e3:0}var DEFAULT_TURNS_LIMIT=25,MAX_TURNS_LIMIT=100,DEFAULT_ITEMS_LIMIT=25,MAX_ITEMS_LIMIT=100,MAX_U32=4294967295;async function threadTurnsListResponse(requestParams,dependencies){let params=parseTurnsParams(requestParams),entry=await historyThread(dependencies.threads,dependencies.archiveState,params.threadId),turns=turnsForEntry(entry,dependencies.turnLog).map(turn=>({key:turn.turnId,value:loggedTurnToWireTurn(turn,params.itemsView)}));return paginateHistory(turns,{kind:"turn",threadId:params.threadId,turnId:null,limit:params.limit,sortDirection:params.sortDirection,cursor:params.cursor})}async function threadHistoryTurns(threadId,dependencies){let entry=await historyThread(dependencies.threads,dependencies.archiveState,threadId);return turnsForEntry(entry,dependencies.turnLog)}async function threadItemsListResponse(requestParams,dependencies){let params=parseItemsParams(requestParams),entry=await historyThread(dependencies.threads,dependencies.archiveState,params.threadId),items=[];for(let turn of turnsForEntry(entry,dependencies.turnLog))if(!(params.turnId!==null&¶ms.turnId!==turn.turnId))for(let item of turn.items){let wireItem=wireItemToThreadItem(item);items.push({key:`${turn.turnId}\0${wireItem.id}`,value:{turnId:turn.turnId,item:wireItem}})}return paginateHistory(items,{kind:"item",threadId:params.threadId,turnId:params.turnId,limit:params.limit,sortDirection:params.sortDirection,cursor:params.cursor})}function parseTurnsParams(value){let params=objectValue(value);return{threadId:requiredHistoryString(params.threadId,"threadId"),cursor:optionalCursor(params.cursor),limit:clampLimit(params.limit,DEFAULT_TURNS_LIMIT,MAX_TURNS_LIMIT,"thread/turns/list"),sortDirection:parseSortDirection(params.sortDirection,"desc","thread/turns/list"),itemsView:parseItemsView(params.itemsView)}}function parseItemsParams(value){let params=objectValue(value);return{threadId:requiredHistoryString(params.threadId,"threadId"),turnId:optionalNullableString(params.turnId,"turnId"),cursor:optionalCursor(params.cursor),limit:clampLimit(params.limit,DEFAULT_ITEMS_LIMIT,MAX_ITEMS_LIMIT,"thread/items/list"),sortDirection:parseSortDirection(params.sortDirection,"asc","thread/items/list")}}async function historyThread(threads,archiveState,threadId){try{return threads.getLoadedThread(threadId)}catch(error){if(!(error instanceof ThreadNotFoundError))throw error}let sessionDir=threads.getSessionDir(),session=(sessionDir?await SessionManager.listAll(sessionDir):await SessionManager.listAll()).find(candidate=>candidate.id===threadId);if(session)return{id:threadId,createdAt:session.created.toISOString(),entries:loadEntriesFromFile(session.path).filter(entry=>entry.type!=="session")};let archivedThread=(await archiveState.listArchivedThreads()).find(thread=>thread.id===threadId);if(archivedThread)return archivedThread;throw invalidHistory(`thread not found: ${threadId}`)}function parseSortDirection(value,fallback,method){if(value==null)return fallback;if(value==="asc"||value==="desc")return value;throw invalidHistory(`${method} received an invalid sortDirection`)}function parseItemsView(value){if(value==null)return"summary";if(value==="notLoaded"||value==="summary"||value==="full")return value;throw invalidHistory("thread/turns/list received an invalid itemsView")}function clampLimit(value,fallback,maximum,method){if(value==null)return fallback;if(typeof value!="number"||!Number.isInteger(value)||value<0||value>MAX_U32)throw invalidHistory(`${method} received an invalid limit`);return Math.min(maximum,Math.max(1,value))}function requiredHistoryString(value,name){if(typeof value!="string"||value.length===0)throw invalidHistory(`thread history requires a non-empty ${name}`);return value}function optionalNullableString(value,name){if(value==null)return null;if(typeof value=="string")return value;throw invalidHistory(`thread/items/list received an invalid ${name}`)}function optionalCursor(value){if(value==null)return null;if(typeof value=="string")return value;throw invalidHistory("thread history received an invalid cursor")}var DEFAULT_THREAD_LIST_LIMIT=25;async function listThreadsResponse(requestParams,dependencies){let params=objectValue(requestParams),page=await dependencies.threads.listThreads({cursor:optionalString2(params.cursor)??null,limit:optionalNumber(params.limit)??DEFAULT_THREAD_LIST_LIMIT}),archived=params.archived===!0,threads=archived?await archivedListThreads(page.threads,dependencies.archiveState):page.threads,filtered=await filterByArchiveState(threads,archived,dependencies.archiveState);return{data:await Promise.all(filtered.map(thread=>buildWireThread(thread,dependencies.turnLog,!1))),nextCursor:page.nextCursor,backwardsCursor:null}}function loadedThreadsResponse(requestParams,threads){let params=objectValue(requestParams),cursor=decodeCursor(optionalString2(params.cursor)??null),limit=optionalNumber(params.limit)??Number.POSITIVE_INFINITY,ids=threads.listLoaded().map(thread=>thread.id),data=ids.slice(cursor,cursor+limit),nextOffset=cursor+data.length;return{data,nextCursor:nextOffset<ids.length?encodeCursor(nextOffset):null}}async function filterByArchiveState(threads,archived,archiveState){let filtered=[];for(let thread of threads)await archiveState.isArchived(thread)===archived&&filtered.push(thread);return filtered}async function archivedListThreads(listedThreads,archiveState){let threadsById=new Map;for(let thread of listedThreads)threadsById.set(thread.id,thread);for(let thread of await archiveState.listArchivedThreads())threadsById.set(thread.id,thread);return[...threadsById.values()]}function registerThreadMetadataHandlers(registry,options){let handlers=new ThreadMetadataHandlers(options);for(let registration of handlers.registrations())registry.register(registration.method,{handler:registration.handler,scope:"thread"})}var ThreadMetadataHandlers=class{constructor(options){this.metadataState=new ThreadMetadataState,this.threads=options.threads,this.turnLog=options.turnLog,this.archiveState=options.archiveState}registrations(){return[{method:"thread/metadata/update",handler:context=>this.update(context.request)}]}async update(request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId");try{let archivedThread=await this.findArchivedThread(threadId);if(archivedThread)return await this.metadataState.updateGitInfo(archivedThread,params.gitInfo),{thread:await buildWireThread({...archivedThread,status:{type:"notLoaded"}},this.turnLog,!1)};let entry=await this.threads.resumeThread(threadId);return await this.metadataState.updateGitInfo(this.threads.buildThread(entry),params.gitInfo),{thread:await buildWireThread(entry,this.turnLog,!1)}}catch(error){throw error instanceof ThreadMetadataUpdateError?invalidRequest3(error.message):error instanceof ThreadNotFoundError?invalidRequest3(`thread not found: ${threadId}`):error}}async findArchivedThread(threadId){return(await this.archiveState.listArchivedThreads()).find(thread=>thread.id===threadId)}};var DEFAULT_LIMIT=25,MAX_LIMIT=100,MAX_U322=4294967295,INTERACTIVE_SOURCE_KINDS=["cli","vscode"],THREAD_SOURCE_KINDS=new Set(["cli","vscode","exec","appServer","subAgent","subAgentReview","subAgentCompact","subAgentThreadSpawn","subAgentOther","unknown"]);function parseSearchParams(value){let params=objectValue(value),rawTerm=params.searchTerm;if(typeof rawTerm!="string"||rawTerm.trim().length===0)throw invalidSearch("thread/search requires a non-empty searchTerm");return{searchTerm:rawTerm.trim().toLocaleLowerCase(),cursor:readCursor(params.cursor),limit:readLimit(params.limit),sortKey:readSortKey(params.sortKey),sortDirection:readSortDirection(params.sortDirection),sourceKinds:readSourceKinds(params.sourceKinds),archived:readArchived(params.archived)}}function invalidSearch(message){return new RpcHandlerError({code:-32600,message})}function readSortKey(value){if(value==null)return"created_at";if(value==="created_at"||value==="updated_at"||value==="recency_at")return value;throw invalidSearch("thread/search received an invalid sortKey")}function readSortDirection(value){if(value==null)return"desc";if(value==="asc"||value==="desc")return value;throw invalidSearch("thread/search received an invalid sortDirection")}function readSourceKinds(value){if(value==null||Array.isArray(value)&&value.length===0)return INTERACTIVE_SOURCE_KINDS;if(!Array.isArray(value)||value.some(source=>!isThreadSourceKind(source)))throw invalidSearch("thread/search received an invalid sourceKinds");return[...new Set(value)].sort()}function isThreadSourceKind(value){return typeof value=="string"&&THREAD_SOURCE_KINDS.has(value)}function readCursor(value){if(value==null)return null;if(typeof value=="string")return value;throw invalidSearch("thread/search received an invalid cursor")}function readLimit(value){if(value==null)return DEFAULT_LIMIT;if(typeof value!="number"||!Number.isInteger(value)||value<0||value>MAX_U322)throw invalidSearch("thread/search received an invalid limit");return Math.min(MAX_LIMIT,Math.max(1,value))}function readArchived(value){if(value==null)return!1;if(typeof value=="boolean")return value;throw invalidSearch("thread/search received an invalid archived flag")}var APP_SERVER_SOURCE="appServer";async function threadSearchResponse(requestParams,dependencies){let params=parseSearchParams(requestParams),archivedIds=new Set((await dependencies.archiveState.listArchivedThreads()).map(thread=>thread.id)),sorted=(await searchRecords(dependencies)).filter(record=>{let sourceMatches=params.sourceKinds.includes(APP_SERVER_SOURCE),archiveMatches=archivedIds.has(record.thread.id)===params.archived;return sourceMatches&&archiveMatches&&record.searchableText.toLocaleLowerCase().includes(params.searchTerm)}).sort((left,right)=>compareRecords(left,right,params.sortKey,params.sortDirection)),cursor=params.cursor===null?null:decodeCursor4(params.cursor,params),window=cursor?cursorWindow(sorted,cursor):sorted,page=window.slice(0,params.limit),nextCursor=window.length>page.length?encodeCursor4(page[page.length-1],params,!1):null,backwardsCursor=page.length>0?encodeCursor4(page[0],params,!0):null;return{data:await Promise.all(page.map(record=>toSearchResult(record,params.searchTerm,dependencies))),nextCursor,backwardsCursor}}async function searchRecords(dependencies){let byId=new Map;for(let record of await dependencies.cache.load(dependencies.threads.getSessionDir()))byId.set(record.thread.id,record);for(let wireThread of dependencies.threads.listLoaded()){let current=byId.get(wireThread.id);if(current){byId.set(wireThread.id,{...current,thread:wireThread});continue}let record=loadedThreadRecord(dependencies.threads,wireThread);record&&byId.set(wireThread.id,record)}return[...byId.values()]}function loadedThreadRecord(threads,wireThread){try{let entry=threads.getLoadedThread(wireThread.id);return{thread:wireThread,recencyAt:wireThread.updatedAt,searchableText:entry.session.getUserMessagesForForking().map(message=>message.text).join(" ")}}catch(error){if(error instanceof ThreadNotFoundError)return null;throw error}}async function toSearchResult(record,searchTerm,dependencies){let thread=await buildWireThread(record.thread,dependencies.turnLog,!1,{recencyAt:record.recencyAt});try{let loaded=dependencies.threads.getLoadedThread(record.thread.id);thread=await buildWireThread(loaded,dependencies.turnLog,!1,{recencyAt:record.recencyAt})}catch(error){if(!(error instanceof ThreadNotFoundError))throw error}return{thread,snippet:literalSnippet(record.searchableText,searchTerm)}}function compareRecords(left,right,sortKey,direction){let leftValue=sortValue(left,sortKey),rightValue=sortValue(right,sortKey);return leftValue!==rightValue?direction==="asc"?leftValue-rightValue:rightValue-leftValue:direction==="asc"?left.thread.id.localeCompare(right.thread.id):right.thread.id.localeCompare(left.thread.id)}function sortValue(record,sortKey){let field=sortKey==="created_at"?record.thread.createdAt:sortKey==="updated_at"?record.thread.updatedAt:record.recencyAt,parsed=Date.parse(field);return Number.isFinite(parsed)?parsed:0}function cursorWindow(records,cursor){let anchorIndex=records.findIndex(record=>record.thread.id===cursor.anchorId);if(anchorIndex===-1)throw invalidSearch("thread/search received an invalid cursor anchor");return cursor.includeAnchor?records.slice(anchorIndex):records.slice(anchorIndex+1)}function decodeCursor4(value,params){let parsed;try{parsed=JSON.parse(value)}catch(error){throw error instanceof SyntaxError?invalidSearch(`thread/search received an invalid cursor: ${value}`):error}if(!isSearchCursor(parsed))throw invalidSearch(`thread/search received an invalid cursor: ${value}`);if(parsed.searchTerm!==params.searchTerm||parsed.sortKey!==params.sortKey||parsed.archived!==params.archived||parsed.sourceKinds.join("\0")!==params.sourceKinds.join("\0"))throw invalidSearch("thread/search cursor does not match the requested search");let directionMatches=parsed.sortDirection===params.sortDirection;if(parsed.includeAnchor?directionMatches:!directionMatches)throw invalidSearch("thread/search cursor does not match the requested sort direction");return parsed}function encodeCursor4(record,params,includeAnchor){return record?JSON.stringify({searchTerm:params.searchTerm,sortKey:params.sortKey,sortDirection:params.sortDirection,sourceKinds:params.sourceKinds,archived:params.archived,anchorId:record.thread.id,includeAnchor}):null}function isSearchCursor(value){if(typeof value!="object"||value===null||Array.isArray(value))return!1;let record=Object.fromEntries(Object.entries(value));return typeof record.searchTerm=="string"&&typeof record.sortKey=="string"&&(record.sortDirection==="asc"||record.sortDirection==="desc")&&Array.isArray(record.sourceKinds)&&record.sourceKinds.every(source=>typeof source=="string")&&typeof record.archived=="boolean"&&typeof record.anchorId=="string"&&typeof record.includeAnchor=="boolean"}function literalSnippet(text,term){let index=text.toLocaleLowerCase().indexOf(term);if(index<0)return"";let start=Math.max(0,index-80),end=Math.min(text.length,index+term.length+80);return`${start>0?"... ":""}${text.slice(start,end)}${end<text.length?" ...":""}`}import{readdir as readdir3,readFile as readFile4,stat as stat2}from"node:fs/promises";import{join as join5}from"node:path";var DEFAULT_MAX_ENTRIES=512,ThreadSearchCache=class{constructor(maxEntries=DEFAULT_MAX_ENTRIES){this.entries=new Map,this.hits=0,this.misses=0,this.maxEntries=Math.max(1,Math.trunc(maxEntries))}async load(sessionDir){let directory=sessionDir??getSessionsDir(),names;try{names=(await readdir3(directory)).filter(name=>name.endsWith(".jsonl"))}catch(error){if(isNodeFsError3(error)&&error.code==="ENOENT")return[];throw error}return(await Promise.all(names.map(name=>this.loadFile(join5(directory,name))))).filter(isSearchSessionRecord)}stats(){return{hits:this.hits,misses:this.misses,entries:this.entries.size}}async loadFile(path){let mtimeMs;try{mtimeMs=(await stat2(path)).mtimeMs}catch(error){if(isNodeFsError3(error)&&error.code==="ENOENT")return this.entries.delete(path),null;throw error}let cached=this.entries.get(path);if(cached?.mtimeMs===mtimeMs)return this.hits+=1,this.entries.delete(path),this.entries.set(path,cached),cached.record;this.misses+=1;let content;try{content=await readFile4(path,"utf8")}catch(error){if(isNodeFsError3(error)&&error.code==="ENOENT")return this.entries.delete(path),null;throw error}let record=parseSearchSession(path,mtimeMs,content);if(!record)return this.entries.delete(path),null;for(this.entries.delete(path),this.entries.set(path,{mtimeMs,record});this.entries.size>this.maxEntries;){let oldest=this.entries.keys().next().value;if(oldest===void 0)break;this.entries.delete(oldest)}return record}};function parseSearchSession(path,mtimeMs,content){let header=null,name=null,firstUserMessage=null,lastActivityMs=mtimeMs,lastRecencyMs=mtimeMs,messages=[];for(let line of content.split(`
|
|
11
11
|
`)){let entry=parseRecord(line);if(!entry)continue;if(!header){if(header=parseHeader(entry),!header)return null;let createdAtMs=timestampMs(header.timestamp,mtimeMs);lastActivityMs=createdAtMs,lastRecencyMs=createdAtMs;continue}if(entry.type==="session_info"){name=typeof entry.name=="string"&&entry.name.trim()||null;continue}if(entry.type!=="message")continue;let message=recordValue(entry.message);if(!message)continue;let role=message.role;if(role!=="user"&&role!=="assistant")continue;let activityMs=timestampMs(entry.timestamp,mtimeMs);lastActivityMs=Math.max(lastActivityMs,activityMs),role==="user"&&(lastRecencyMs=Math.max(lastRecencyMs,activityMs));let text=messageText(message.content);text&&(messages.push(text),role==="user"&&firstUserMessage===null&&(firstUserMessage=text))}if(!header)return null;let createdAt=isoTimestamp(timestampMs(header.timestamp,mtimeMs));return{thread:{id:header.id,sessionId:header.id,sessionPath:path,cwd:header.cwd,createdAt,updatedAt:isoTimestamp(lastActivityMs),status:{type:"notLoaded"},preview:firstUserMessage,name},recencyAt:isoTimestamp(lastRecencyMs),searchableText:messages.join(" ")}}function parseHeader(value){if(value.type!=="session")return null;let id=value.id,cwd=value.cwd,timestamp=value.timestamp;return typeof id!="string"||id.length===0||typeof cwd!="string"||typeof timestamp!="string"?null:{id,cwd,timestamp}}function messageText(content){return typeof content=="string"?content:Array.isArray(content)?content.map(block=>{let value=recordValue(block);return value?.type==="text"&&typeof value.text=="string"?value.text:""}).filter(text=>text.length>0).join(" "):""}function parseRecord(line){if(!line.trim())return null;try{let value=JSON.parse(line);return recordValue(value)}catch(error){if(error instanceof SyntaxError)return null;throw error}}function recordValue(value){return typeof value!="object"||value===null||Array.isArray(value)?null:Object.fromEntries(Object.entries(value))}function timestampMs(value,fallback){if(typeof value=="number"&&Number.isFinite(value))return value;if(typeof value=="string"){let parsed=Date.parse(value);if(Number.isFinite(parsed))return parsed}return fallback}function isoTimestamp(value){return new Date(value).toISOString()}function isSearchSessionRecord(value){return value!==null}function isNodeFsError3(value){return value instanceof Error&&"code"in value}var DEFAULT_LIMIT2=50,MAX_LIMIT2=250,MAX_U323=4294967295,SNIPPET_CONTEXT_BEFORE_CHARS=48,SNIPPET_CONTEXT_AFTER_CHARS=96;async function threadSearchOccurrencesResponse(requestParams,dependencies){let params=parseParams(requestParams),turns=await threadHistoryTurns(params.threadId,dependencies),occurrences=collectOccurrences(visibleMessageCandidates(turns),params),start=params.cursor===null?0:cursorStart(occurrences,decodeCursor5(params.cursor,params)),data=occurrences.slice(start,start+params.limit).map(occurrence2=>occurrence2.value),next=occurrences[start+data.length];return{data,nextCursor:next?JSON.stringify({threadId:params.threadId,searchTerm:params.searchTerm,candidateKey:next.candidateKey,occurrenceIndex:next.occurrenceIndex}):null}}function parseParams(value){let params=objectValue(value),threadId=params.threadId;if(typeof threadId!="string"||threadId.length===0)throw invalidOccurrences("thread/searchOccurrences requires a non-empty threadId");let searchTerm=params.searchTerm;if(typeof searchTerm!="string"||searchTerm.trim().length===0)throw invalidOccurrences("thread/searchOccurrences requires a non-empty searchTerm");return{threadId,searchTerm,cursor:parseCursor(params.cursor),limit:parseLimit(params.limit)}}function parseCursor(value){if(value==null)return null;if(typeof value=="string")return value;throw invalidOccurrences("thread/searchOccurrences received an invalid cursor")}function parseLimit(value){if(value==null)return DEFAULT_LIMIT2;if(typeof value!="number"||!Number.isInteger(value)||value<0||value>MAX_U323)throw invalidOccurrences("thread/searchOccurrences received an invalid limit");return Math.min(MAX_LIMIT2,Math.max(1,value))}function visibleMessageCandidates(turns){return turns.flatMap(turn=>{let finalAgentIndex=turn.items.findLastIndex(item=>item.type==="agentMessage");return turn.items.flatMap((item,index)=>{if(item.type!=="userMessage"&&(item.type!=="agentMessage"||index!==finalAgentIndex))return[];let itemId=item.id;if(typeof itemId!="string"||itemId.length===0)return[];let text=searchableText(item);return text.length===0?[]:[{key:`${turn.turnId}\0${itemId}`,turnId:turn.turnId,itemId,text}]})})}function searchableText(item){if(item.type==="agentMessage")return typeof item.text=="string"?markdownToSearchText(item.text):"";let content=item.content;return typeof content=="string"?content:Array.isArray(content)?content.flatMap(input=>isRecord8(input)&&input.type==="text"&&typeof input.text=="string"?[input.text]:[]).join(""):""}function collectOccurrences(candidates,params){return candidates.flatMap(candidate=>findLiteralRanges(candidate.text,params.searchTerm).map((range,occurrenceIndex)=>({candidateKey:candidate.key,occurrenceIndex,value:occurrence(candidate,range,params.threadId)})))}function occurrence(candidate,matched,threadId){let snippetStart=charStartBefore(candidate.text,matched.start,SNIPPET_CONTEXT_BEFORE_CHARS),snippetEnd=charEndAfter(candidate.text,matched.end,SNIPPET_CONTEXT_AFTER_CHARS),leadingEllipsis=snippetStart>0,trailingEllipsis=snippetEnd<candidate.text.length,snippet=`${leadingEllipsis?"... ":""}${candidate.text.slice(snippetStart,snippetEnd)}${trailingEllipsis?" ...":""}`,start=(leadingEllipsis?4:0)+candidate.text.slice(snippetStart,matched.start).length;return{turnId:candidate.turnId,itemId:candidate.itemId,snippet,snippetMatchRange:{start,end:start+matched.end-matched.start},turnCursor:inclusiveTurnHistoryCursor(threadId,candidate.turnId)}}function findLiteralRanges(text,term){let lowercaseNeedle=term.toLowerCase(),lowercaseText=text.toLowerCase(),spans=[],lowercaseOffset=0,originalStart=0;for(let character of text){let folded=character.toLowerCase();spans.push({lowerStart:lowercaseOffset,lowerEnd:lowercaseOffset+folded.length,originalStart,originalEnd:originalStart+character.length}),lowercaseOffset+=folded.length,originalStart+=character.length}let ranges=[],offset=0;for(;;){let start=lowercaseText.indexOf(lowercaseNeedle,offset);if(start<0)return ranges;let end=start+lowercaseNeedle.length,first=spans.find(span=>span.lowerStart<=start&&start<span.lowerEnd),last=spans.find(span=>span.lowerStart<end&&end<=span.lowerEnd);first&&last&&ranges.push({start:first.originalStart,end:last.originalEnd}),offset=end}}function markdownToSearchText(markdown){return x.lex(markdown.trim()).map(markdownTokenText).join(" ").split(/\s+/u).filter(Boolean).join(" ")}function markdownTokenText(value){if(!isRecord8(value))return"";let type2=value.type;if(type2==="br"||type2==="hr"||type2==="space")return" ";if(type2==="code"||type2==="codespan"||type2==="escape"||type2==="html")return typeof value.text=="string"?value.text:"";if(type2==="list"&&Array.isArray(value.items))return value.items.map(markdownTokenText).join(" ");if(type2==="table"){let header=Array.isArray(value.header)?value.header.map(markdownTokenText):[],rows=Array.isArray(value.rows)?value.rows.flatMap(row=>Array.isArray(row)?row.map(markdownTokenText):[]):[];return[...header,...rows].join(" ")}return Array.isArray(value.tokens)?value.tokens.map(markdownTokenText).join(""):typeof value.text=="string"?value.text:""}function decodeCursor5(value,params){let parsed;try{parsed=JSON.parse(value)}catch(error){throw error instanceof SyntaxError?invalidOccurrences(`invalid cursor: ${value}`):error}if(!isSearchCursor2(parsed)||parsed.threadId!==params.threadId||parsed.searchTerm!==params.searchTerm)throw invalidOccurrences(`invalid cursor: ${value}`);return parsed}function cursorStart(occurrences,cursor){let index=occurrences.findIndex(occurrence2=>occurrence2.candidateKey===cursor.candidateKey&&occurrence2.occurrenceIndex===cursor.occurrenceIndex);if(index<0)throw invalidOccurrences("invalid cursor: anchor is no longer present");return index}function isSearchCursor2(value){return isRecord8(value)&&typeof value.threadId=="string"&&typeof value.searchTerm=="string"&&typeof value.candidateKey=="string"&&typeof value.occurrenceIndex=="number"&&Number.isInteger(value.occurrenceIndex)&&value.occurrenceIndex>=0}function charStartBefore(text,index,count){let prefix=text.slice(0,index),characters=Array.from(prefix);return characters.slice(0,Math.max(0,characters.length-count-1)).join("").length}function charEndAfter(text,index,count){return index+Array.from(text.slice(index)).slice(0,count).join("").length}function invalidOccurrences(message){return new RpcHandlerError({code:-32600,message})}function isRecord8(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}var SENPI_COLLABORATION_MODE={mode:"default",settings:{model:"unknown",reasoning_effort:"off",developer_instructions:null}};function buildSenpiCollaborationModePreset(model){return{name:SENPI_COLLABORATION_MODE.mode,mode:null,model,reasoning_effort:null}}function registerThreadSettingsHandlers(registry,options){let handlers=new ThreadSettingsHandlers(options);for(let registration of handlers.registrations())registry.register(registration.method,{handler:registration.handler,scope:"thread",experimental:!0})}var ThreadSettingsHandlers=class{constructor(options){this.threads=options.threads,this.notifications=options.notifications,this.deferUntilResponded=options.deferUntilResponded}registrations(){return[{method:"thread/settings/update",handler:context=>this.update(context.connection,context.request)}]}async update(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),unsupported=Object.keys(params).filter(key=>key!=="threadId"&&key!=="model"&&key!=="effort").sort();if(unsupported.length>0)throw invalidRequest3(`unsupported thread settings: ${unsupported.join(", ")}`);let entry=await this.requireThread(threadId),requestedModel=parseModel(params,entry),requestedEffort=parseEffort(params,requestedModel,entry),before=buildThreadSettings(entry);requestedModel&&!sameModel(requestedModel,entry.session.model)&&await entry.session.setSessionModel(requestedModel,{source:"app-server"}),requestedEffort!==void 0&&requestedEffort!==entry.session.thinkingLevel&&entry.session.setSessionThinkingLevel(requestedEffort);let after=buildThreadSettings(entry);if(JSON.stringify(before)!==JSON.stringify(after)){let notify=()=>{this.notifications.toThread(threadId,{method:"thread/settings/updated",params:{threadId,threadSettings:after}})};this.deferUntilResponded?.(connectionId(connection),notify)!==!0&¬ify()}return{}}async requireThread(threadId){try{return await this.threads.resumeThread(threadId)}catch(error){throw error instanceof ThreadNotFoundError?invalidRequest3(`thread not found: ${threadId}`):error}}};function parseModel(params,entry){if(!Object.hasOwn(params,"model")||params.model===null)return;if(typeof params.model!="string"||params.model.length===0)throw invalidParams("Invalid params: model must be a non-empty string");let reference=params.model,separator=reference.indexOf("/"),model=separator>0?entry.session.modelRegistry.find(reference.slice(0,separator),reference.slice(separator+1)):entry.session.modelRegistry.getAll().find(candidate=>candidate.id===reference);if(!model)throw invalidRequest3(`model not found: ${reference}`);return model}function parseEffort(params,model,entry){if(!Object.hasOwn(params,"effort")||params.effort===null)return;if(typeof params.effort!="string")throw invalidParams("Invalid params: effort must be a string");let effort=(model?getSupportedThinkingLevels(model):entry.session.getAvailableThinkingLevels()).find(level=>level===params.effort);if(!effort)throw invalidParams(`Invalid params: unsupported effort ${params.effort}`);return effort}function sameModel(left,right){return right?.provider===left.provider&&right.id===left.id}function buildThreadSettings(entry){let model=entry.session.model;return{cwd:entry.cwd,approvalPolicy:"never",approvalsReviewer:"user",sandboxPolicy:{type:"dangerFullAccess"},activePermissionProfile:null,model:model?.id??"unknown",modelProvider:model?.provider??"unknown",serviceTier:entry.session.serviceTier??null,effort:entry.session.thinkingLevel,summary:null,collaborationMode:SENPI_COLLABORATION_MODE,personality:null}}var DEFAULT_APPROVAL_POLICY="never";function requestedStartModel(params){let model=optionalString2(params.model);if(!model)return;let parsed=parseModelReference(model,optionalString2(params.modelProvider));if(parsed)return findBuiltinModel(parsed.provider,parsed.modelId)}function requestedApprovalPolicy(params){let value=params.approvalPolicy;switch(value){case"untrusted":case"on-request":case"never":return value;default:return isGranularApproval(value)?value:DEFAULT_APPROVAL_POLICY}}function parseModelReference(model,modelProvider){if(modelProvider){let prefix=`${modelProvider}/`;return{provider:modelProvider,modelId:model.startsWith(prefix)?model.slice(prefix.length):model}}let separator=model.indexOf("/");if(!(separator<=0||separator>=model.length-1))return{provider:model.slice(0,separator),modelId:model.slice(separator+1)}}function isGranularApproval(value){let granular=objectValue(value).granular,object=objectValue(granular);return typeof object.sandbox_approval=="boolean"&&typeof object.rules=="boolean"&&typeof object.skill_approval=="boolean"&&typeof object.request_permissions=="boolean"&&typeof object.mcp_elicitations=="boolean"}function findBuiltinModel(provider,modelId){for(let builtinProvider of getProviders())if(builtinProvider===provider)return getModels(builtinProvider).find(model=>model.id===modelId)}var DEFAULT_IDLE_UNLOAD_MINUTES=30;function registerThreadLifecycleHandlers(registry,options){registerThreadGoalHandlers(registry,options),registerThreadSettingsHandlers(registry,options);let archiveState=new ThreadArchiveState(options.threads.getSessionDir());registerThreadMetadataHandlers(registry,{threads:options.threads,turnLog:options.turnLog,archiveState});let handlers=new ThreadLifecycleHandlers(options,archiveState);for(let registration of handlers.registrations())registry.register(registration.method,{handler:registration.handler,scope:registration.method.startsWith("thread/")?"thread":"global",experimental:registration.experimental});return handlers}var ThreadLifecycleHandlers=class{constructor(options,archiveState){this.searchCache=new ThreadSearchCache,this.idleTimers=new Map,this.threads=options.threads,this.turnLog=options.turnLog,this.notifications=options.notifications,this.replayPendingApprovals=options.replayPendingApprovals,this.deferUntilResponded=options.deferUntilResponded,this.archiveState=archiveState,this.observeThread=options.observeThread,this.idleUnloadMs=Math.max(0,options.idleUnloadMinutes??DEFAULT_IDLE_UNLOAD_MINUTES)*60*1e3}registrations(){return[{method:"thread/start",handler:context=>this.start(context.connection,context.request)},{method:"thread/resume",handler:context=>this.resume(context.connection,context.request)},{method:"thread/fork",handler:context=>this.fork(context.connection,context.request)},{method:"thread/read",handler:context=>this.read(context.request)},{method:"thread/list",handler:context=>listThreadsResponse(context.request.params,{threads:this.threads,turnLog:this.turnLog,archiveState:this.archiveState})},{method:"thread/loaded/list",handler:context=>loadedThreadsResponse(context.request.params,this.threads)},{method:"thread/name/set",handler:context=>this.setName(context.connection,context.request)},{method:"thread/archive",handler:context=>this.archive(context.connection,context.request)},{method:"thread/unarchive",handler:context=>this.unarchive(context.connection,context.request)},{method:"thread/delete",handler:context=>this.delete(context.connection,context.request)},{method:"thread/unsubscribe",handler:context=>this.unsubscribe(context.connection,context.request)},{method:"thread/search",experimental:!0,handler:context=>threadSearchResponse(context.request.params,{threads:this.threads,turnLog:this.turnLog,archiveState:this.archiveState,cache:this.searchCache})},{method:"thread/searchOccurrences",experimental:!0,handler:context=>threadSearchOccurrencesResponse(context.request.params,{archiveState:this.archiveState,threads:this.threads,turnLog:this.turnLog})},{method:"thread/turns/list",experimental:!0,handler:context=>threadTurnsListResponse(context.request.params,{archiveState:this.archiveState,threads:this.threads,turnLog:this.turnLog})},{method:"thread/items/list",experimental:!0,handler:context=>threadItemsListResponse(context.request.params,{archiveState:this.archiveState,threads:this.threads,turnLog:this.turnLog})},{method:"thread/compact/start",handler:context=>this.compact(context.connection,context.request)}]}async start(connection,request){let params=objectValue(request.params),cwd=optionalString2(params.cwd)??process.cwd(),entry=await this.threads.createThread({cwd,model:requestedStartModel(params)});this.attachThread(entry),this.subscribe(entry,connectionId(connection));let response=await this.runtimeResponse(entry,!1,{approvalPolicy:requestedApprovalPolicy(params)});return this.deferOrRun(connection,()=>{this.notifications.broadcast({method:"thread/started",params:{thread:response.thread}})}),response}async resume(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId");try{let entry=await this.threads.resumeThread(threadId);return this.attachThread(entry),this.subscribe(entry,connectionId(connection)),this.notifications.broadcast({method:"thread/status/changed",params:{threadId,status:{type:"idle"}}}),{...await this.runtimeResponse(entry,!0),initialTurnsPage:null}}catch(error){throw error instanceof ThreadNotFoundError?new Error(`no rollout found for thread id ${threadId}`):error}}async fork(connection,request){let params=objectValue(request.params),sourceThreadId=requiredString2(params.threadId,"threadId"),entry=await this.threads.forkThread(sourceThreadId,{cwd:optionalString2(params.cwd)??void 0});this.attachThread(entry),this.subscribe(entry,connectionId(connection));let response=await this.runtimeResponse(entry,!0,{forkedFromId:sourceThreadId});return this.deferOrRun(connection,()=>{this.notifications.broadcast({method:"thread/started",params:{thread:response.thread}})}),response}async read(request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry=await this.threads.resumeThread(threadId);return this.attachThread(entry),{thread:await buildWireThread(entry,this.turnLog,params.includeTurns===!0)}}async setName(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),name=requiredString2(params.name,"name");return(await this.threads.resumeThread(threadId)).session.setSessionName(name),this.deferOrRun(connection,()=>{this.notifications.broadcast({method:"thread/name/updated",params:{threadId,threadName:name}})}),{}}compact(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry;try{entry=this.threads.getLoadedThread(threadId)}catch(error){throw error instanceof ThreadNotFoundError?invalidRequest3(`thread not found: ${threadId}`):error}let startCompaction=()=>{let turnId=randomUUID3(),item={type:"contextCompaction",id:randomUUID3()},startedAtMs=Date.now();this.turnLog.recordTurn(threadId,{turnId,startedAt:new Date(startedAtMs).toISOString(),status:"running"}),this.notifications.toThread(threadId,{method:"item/started",params:{threadId,turnId,item,startedAtMs}}),entry.session.compact().then(()=>this.completeCompaction(threadId,turnId,item),error=>this.turnLog.completeTurn(threadId,turnId,{status:"failed",completedAt:new Date().toISOString(),error:error instanceof Error?error.message:String(error)}))};return this.deferUntilResponded?.(connectionId(connection),startCompaction)!==!0&&startCompaction(),{}}completeCompaction(threadId,turnId,item){let completedAtMs=Date.now();this.turnLog.appendItem(threadId,turnId,item),this.turnLog.completeTurn(threadId,turnId,{status:"completed",completedAt:new Date(completedAtMs).toISOString()}),this.notifications.toThread(threadId,{method:"item/completed",params:{threadId,turnId,item,completedAtMs}})}async archive(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry=await this.threads.resumeThread(threadId);this.clearIdleTimer(threadId);let archivedStatus={type:"notLoaded"};return await this.archiveState.markArchived({...this.threads.buildThread(entry),status:archivedStatus}),this.threads.unloadThread(threadId),this.notifications.removeThread(threadId),this.notifications.broadcast({method:"thread/status/changed",params:{threadId,status:NOT_LOADED_STATUS}}),this.deferOrRun(connection,()=>{this.notifications.broadcast({method:"thread/archived",params:{threadId}})}),{}}async delete(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId");return this.clearIdleTimer(threadId),await this.archiveState.clearArchived(threadId),await this.threads.deleteThread(threadId),this.notifications.removeThread(threadId),this.notifications.broadcast({method:"thread/status/changed",params:{threadId,status:NOT_LOADED_STATUS}}),this.deferOrRun(connection,()=>{this.notifications.broadcast({method:"thread/deleted",params:{threadId}})}),{}}async unarchive(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),archivedThread=await this.archiveState.unarchive(threadId);if(!archivedThread)throw invalidRequest3(`thread not found: ${threadId}`);let wireThread={...archivedThread,status:{type:"notLoaded"}},thread=await buildWireThread(wireThread,this.turnLog,!1),notify=()=>{this.notifications.broadcast({method:"thread/unarchived",params:{threadId}})};return this.deferUntilResponded?.(connectionId(connection),notify)!==!0&¬ify(),{thread}}deferOrRun(connection,action){this.deferUntilResponded?.(connectionId(connection),action)!==!0&&action()}unsubscribe(connection,request){let params=objectValue(request.params),threadId=requiredString2(params.threadId,"threadId"),entry;try{entry=this.threads.getLoadedThread(threadId)}catch(error){if(!(error instanceof ThreadNotFoundError))throw error;return{status:"notLoaded"}}let id=connectionId(connection);return entry.subscribers.has(id)?(this.notifications.unsubscribe(threadId,id),this.scheduleIdleUnload(entry),{status:"unsubscribed"}):{status:"notSubscribed"}}scheduleIdleUnloadForThread(threadId){let entry;try{entry=this.threads.getLoadedThread(threadId)}catch(error){if(!(error instanceof ThreadNotFoundError))throw error;return}this.scheduleIdleUnload(entry)}dispose(){for(let timer of this.idleTimers.values())clearTimeout(timer);this.idleTimers.clear()}async runtimeResponse(entry,includeTurns,options={}){let model=entry.session.model;return{thread:await buildWireThread(entry,this.turnLog,includeTurns,{forkedFromId:options.forkedFromId??null}),model:model?.id??"unknown",modelProvider:model?.provider??"unknown",serviceTier:entry.session.serviceTier??null,cwd:entry.cwd,runtimeWorkspaceRoots:[entry.cwd],instructionSources:[],approvalPolicy:options.approvalPolicy??"never",approvalsReviewer:"user",sandbox:{type:"dangerFullAccess"},activePermissionProfile:null,reasoningEffort:entry.session.thinkingLevel??null,multiAgentMode:"explicitRequestOnly"}}attachThread(entry){this.notifications.addThread(entry),this.observeThread?.(entry.id),this.clearIdleTimer(entry.id)}subscribe(entry,connectionIdValue){this.notifications.subscribe(entry.id,connectionIdValue),this.replayPendingApprovals?.(entry.id,connectionIdValue)}scheduleIdleUnload(entry){if(this.clearIdleTimer(entry.id),entry.subscribers.size>0||entry.activeTurn)return;let timer=setTimeout(()=>this.unloadIfIdle(entry.id),this.idleUnloadMs);timer.unref(),this.idleTimers.set(entry.id,timer)}unloadIfIdle(threadId){this.clearIdleTimer(threadId);let entry;try{entry=this.threads.getLoadedThread(threadId)}catch(error){if(!(error instanceof ThreadNotFoundError))throw error;return}entry.subscribers.size>0||entry.activeTurn||(this.threads.unloadThread(threadId),this.notifications.removeThread(threadId),this.notifications.broadcast({method:"thread/closed",params:{threadId}}),this.notifications.broadcast({method:"thread/status/changed",params:{threadId,status:NOT_LOADED_STATUS}}))}clearIdleTimer(threadId){let timer=this.idleTimers.get(threadId);timer&&(clearTimeout(timer),this.idleTimers.delete(threadId))}};var TurnLog=class{constructor(){this.turnsByThreadId=new Map}recordTurn(threadId,turn){let turns=this.getThreadTurns(threadId),loggedTurn={turnId:turn.turnId,startedAt:turn.startedAt,completedAt:turn.completedAt??null,durationMs:durationBetween(turn.startedAt,turn.completedAt??null),error:turn.error??null,status:turn.status??"running",items:[]};return turns.push(loggedTurn),cloneTurn(loggedTurn)}appendItem(threadId,turnId,item){let turn=this.getThreadTurns(threadId).find(candidate=>candidate.turnId===turnId);if(!turn)throw new Error(`Turn not found: ${turnId}`);turn.items.push(cloneWireItem(item))}completeTurn(threadId,turnId,completion){let turn=this.getThreadTurns(threadId).find(candidate=>candidate.turnId===turnId);if(!turn)throw new Error(`Turn not found: ${turnId}`);turn.status=completion.status,turn.completedAt=completion.completedAt,turn.durationMs=durationBetween(turn.startedAt,completion.completedAt),turn.error=completion.error??null}discardTurn(threadId,turnId){let turns=this.getThreadTurns(threadId),index=turns.findIndex(candidate=>candidate.turnId===turnId);index!==-1&&turns.splice(index,1)}readTurns(threadId){return this.getThreadTurns(threadId).map(cloneTurn)}getThreadTurns(threadId){let turns=this.turnsByThreadId.get(threadId);return turns||(turns=[],this.turnsByThreadId.set(threadId,turns)),turns}};function cloneTurn(turn){return{turnId:turn.turnId,startedAt:turn.startedAt,completedAt:turn.completedAt,durationMs:turn.durationMs,error:turn.error,status:turn.status,items:turn.items.map(cloneWireItem)}}function cloneWireItem(item){return{...item}}function durationBetween(startedAt,completedAt){if(completedAt===null)return null;let startedAtMs=Date.parse(startedAt),completedAtMs=Date.parse(completedAt);return Number.isFinite(startedAtMs)&&Number.isFinite(completedAtMs)?completedAtMs-startedAtMs:null}var MessageItemProjector=class{constructor(notifier){this.textItems=new Map,this.reasoningItems=new Map,this.notifier=notifier}startText(contentIndex){let item=this.createTextItem(contentIndex);return[this.notifier.started({type:"agentMessage",id:item.id,text:"",phase:null,memoryCitation:null})]}deltaText(contentIndex,delta){let item=this.textItems.get(contentIndex)??this.createTextItem(contentIndex);return item.text+=delta,[this.notifier.notification("item/agentMessage/delta",{itemId:item.id,delta})]}completeText(contentIndex,text){let item=this.textItems.get(contentIndex)??this.createTextItem(contentIndex);return item.text=text,item.completed=!0,[this.notifier.completed({type:"agentMessage",id:item.id,text:item.text,phase:null,memoryCitation:null})]}startReasoning(contentIndex){let item=this.createReasoningItem(contentIndex);return[this.notifier.started({type:"reasoning",id:item.id,summary:[],content:[]})]}deltaReasoning(contentIndex,delta){let item=this.reasoningItems.get(contentIndex)??this.createReasoningItem(contentIndex);return item.text+=delta,[this.notifier.notification("item/reasoning/textDelta",{itemId:item.id,delta,contentIndex})]}completeReasoning(contentIndex,text){let item=this.reasoningItems.get(contentIndex)??this.createReasoningItem(contentIndex);return item.text=text,item.completed=!0,[this.notifier.completed({type:"reasoning",id:item.id,summary:[],content:[item.text]})]}completeDanglingText(message){return message.content.flatMap((content,contentIndex)=>content.type==="text"&&!this.textItems.get(contentIndex)?.completed?this.completeText(contentIndex,content.text):content.type==="thinking"&&!this.reasoningItems.get(contentIndex)?.completed?this.completeReasoning(contentIndex,content.thinking):[])}closeDanglingItems(){return[...unfinishedTextItems(this.textItems).flatMap(([contentIndex,item])=>this.completeText(contentIndex,item.text)),...unfinishedTextItems(this.reasoningItems).flatMap(([contentIndex,item])=>this.completeReasoning(contentIndex,item.text))]}createTextItem(contentIndex){let item={id:this.notifier.itemId(contentIndex),text:"",completed:!1};return this.textItems.set(contentIndex,item),item}createReasoningItem(contentIndex){let item={id:this.notifier.itemId(contentIndex),text:"",completed:!1};return this.reasoningItems.set(contentIndex,item),item}};function unfinishedTextItems(items){return Array.from(items.entries()).filter(entry=>!entry[1].completed)}var TurnDiffTracker=class{constructor(){this.fileDiffs=new Map,this.emitted=""}update(toolId,diff,sourceOrder){if(!diff)return;this.fileDiffs.set(toolId,diff);let cumulative=Array.from(sourceOrder,id=>this.fileDiffs.get(id)??"").join("");if(cumulative!==this.emitted)return this.emitted=cumulative,cumulative}};function emptyResult(){return{notifications:[]}}function messageIdFromMessage(message){return message.responseId}function assertNeverProjection(value){throw new Error(`Unhandled app-server projection variant: ${String(value)}`)}function fileChangeProjection(input){let changes=input.status==="inProgress"?[]:fileChanges(input.name,input.args,input.result);return{item:{type:"fileChange",id:input.id,changes,status:input.status},diff:changes.map(change=>change.diff).join("")}}function fileChanges(name,args,result){if(!isRecord9(result)||!isRecord9(result.details))return[];let previewChanges=changesFromPreview(result.details.preview);if(previewChanges.length>0)return previewChanges;let patch=normalizedPatch(result.details.patch),path=isRecord9(args)?readString(args.path)??readString(args.file_path):void 0;if(name!=="edit"&&name!=="write"||!path||!patch)return[];let operation=readOperation(result.details.operation)??(patch.startsWith(`--- /dev/null
|
|
12
12
|
`)?"add":"update"),kind=patchChangeKind(operation,null);return[{path,kind,diff:patch}]}function changesFromPreview(value){return!isRecord9(value)||!Array.isArray(value.files)?[]:value.files.flatMap(file=>{if(!isRecord9(file))return[];let path=readString(file.filePath),operation=readOperation(file.operation),kind=operation?patchChangeKind(operation,readString(file.movePath)??null):void 0,diff=normalizedPatch(file.patch);return path&&kind&&diff?[{path,kind,diff}]:[]})}function normalizedPatch(value){let patch=readString(value);if(patch)return patch.endsWith(`
|