@code-yeongyu/senpi 2026.9.24-3 → 2026.9.25
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 +26 -0
- package/dist/bundle/chunks/{app-server-command-OTRHYRIB.js → app-server-command-RB6QUPRI.js} +1 -1
- package/dist/bundle/chunks/{chunk-UM43CBL4.js → chunk-JJ3NJZBD.js} +118 -111
- package/dist/bundle/chunks/chunk-SGYEOIOJ.js +8 -0
- package/dist/bundle/chunks/chunk-YS5YEX4S.js +2 -0
- package/dist/bundle/chunks/{cli-main-TX6I4X4F.js → cli-main-KO53KYDN.js} +1 -1
- package/dist/bundle/chunks/{interactive-mode-UI5Q6FGY.js → interactive-mode-ABDNLJSI.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-D6HMI3RQ.js → multi-session-host-JV3MNWXZ.js} +1 -1
- package/dist/bundle/chunks/{package-manager-cli-3UWH3ZZS.js → package-manager-cli-ZYYAVCXU.js} +1 -1
- package/dist/bundle/chunks/{rpc-mode-LXIZHJSJ.js → rpc-mode-Q2OUJURB.js} +1 -1
- package/dist/bundle/chunks/runtime-session-XBT646O5.js +2 -0
- package/dist/bundle/chunks/session-worker.js +184 -177
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +1 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts +7 -0
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js +23 -4
- package/dist/core/extensions/builtin/cursor-cli-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts +11 -16
- package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-command.js +97 -43
- package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/durable-file.js +11 -4
- package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension-state.d.ts +26 -0
- package/dist/core/extensions/builtin/terminal/extension-state.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/extension-state.js +151 -0
- package/dist/core/extensions/builtin/terminal/extension-state.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/extension.js +32 -308
- package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/lease-file.d.ts +52 -0
- package/dist/core/extensions/builtin/terminal/lease-file.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-file.js +205 -0
- package/dist/core/extensions/builtin/terminal/lease-file.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts +33 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.js +110 -0
- package/dist/core/extensions/builtin/terminal/lease-keeper.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts +1 -0
- package/dist/core/extensions/builtin/terminal/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manager.js +6 -0
- package/dist/core/extensions/builtin/terminal/manager.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts +48 -4
- package/dist/core/extensions/builtin/terminal/manifest-lease.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/manifest-lease.js +141 -59
- package/dist/core/extensions/builtin/terminal/manifest-lease.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +2 -0
- package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-registry.js +15 -10
- package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts +11 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.js +28 -0
- package/dist/core/extensions/builtin/terminal/monitor-state-dir.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts +41 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.js +131 -0
- package/dist/core/extensions/builtin/terminal/orphan-reaper.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-identity.d.ts +21 -0
- package/dist/core/extensions/builtin/terminal/process-identity.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-identity.js +34 -0
- package/dist/core/extensions/builtin/terminal/process-identity.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts +6 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.js +60 -0
- package/dist/core/extensions/builtin/terminal/process-start-probe.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/prompt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/prompt.js +8 -4
- package/dist/core/extensions/builtin/terminal/prompt.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/restore-digest.d.ts +54 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.js +133 -0
- package/dist/core/extensions/builtin/terminal/restore-digest.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-session.d.ts +56 -0
- package/dist/core/extensions/builtin/terminal/restore-session.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore-session.js +238 -0
- package/dist/core/extensions/builtin/terminal/restore-session.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/restore.d.ts +52 -19
- package/dist/core/extensions/builtin/terminal/restore.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/restore.js +63 -138
- package/dist/core/extensions/builtin/terminal/restore.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +17 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/session-activity.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/session-activity.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/session-activity.js +41 -0
- package/dist/core/extensions/builtin/terminal/session-activity.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/shared.d.ts +14 -0
- package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/shared.js +14 -0
- package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts +8 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-model.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts +15 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js +148 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest-parse.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts +15 -2
- package/dist/core/extensions/builtin/terminal/terminal-manifest.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-manifest.js +62 -11
- package/dist/core/extensions/builtin/terminal/terminal-manifest.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts +17 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.js +81 -0
- package/dist/core/extensions/builtin/terminal/terminal-state-gc.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts +5 -0
- package/dist/core/extensions/builtin/terminal/tools/context.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/context.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js +16 -1
- package/dist/core/extensions/builtin/terminal/tools/kill-bash.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts +27 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js +75 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-manifest-binding.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts +35 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.d.ts.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js +67 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor-schema.js.map +1 -0
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts +14 -35
- package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/tools/monitor.js +30 -110
- package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts +7 -6
- package/dist/core/extensions/builtin/todotools/first-turn.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/first-turn.js +8 -8
- package/dist/core/extensions/builtin/todotools/first-turn.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +1 -1
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js +1 -1
- package/dist/core/extensions/builtin/todotools/todo-format.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js +4 -0
- package/dist/core/extensions/builtin/ttsr/detectors/repetitive-turns.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.js +1 -1
- package/dist/core/extensions/builtin/ttsr/prompts.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +6 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/docs/extensions.md +2 -0
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-desktop-engine/README.md +31 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts +38 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js +117 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/handshake.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts +3 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js +3 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts +42 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js +79 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/dist/locator.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/check-prebuild-fresh.mjs +160 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.d.ts +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/index.js +23 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/native/prebuilds/darwin-arm64/senpi-desktop-engine +0 -0
- package/node_modules/@code-yeongyu/senpi-desktop-engine/package.json +53 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-prelude/package.json +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts +38 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/audit.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts +28 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js +102 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/call.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts +14 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js +71 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/engine-schema.generated.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts +7 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js +4 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts +66 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js +8 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/json-rpc.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/session.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts +59 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/dist/wire.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-protocol/package.json +45 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/README.md +27 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-service/package.json +44 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/README.md +20 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.d.ts.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js +2 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/dist/index.js.map +1 -0
- package/node_modules/@code-yeongyu/senpi-desktop-tool/package.json +44 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/cerebras.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts +2 -0
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js +6 -0
- package/node_modules/@earendil-works/pi-pty/dist/pipe-fallback.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-bun.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-native.js +5 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-native.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts +11 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js +24 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-raw-tail.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts +2 -0
- package/node_modules/@earendil-works/pi-pty/dist/session-types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session-types.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts +4 -5
- package/node_modules/@earendil-works/pi-pty/dist/session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/session.js +11 -16
- package/node_modules/@earendil-works/pi-pty/dist/session.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/native/prebuilds/darwin-arm64/senpi_pty.darwin-arm64.node +0 -0
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +22 -7
- package/dist/bundle/chunks/chunk-GFUZPFHN.js +0 -2
- package/dist/bundle/chunks/chunk-JBOV6VNK.js +0 -8
- package/dist/bundle/chunks/runtime-session-F3EXC44D.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,27 @@
|
|
|
12
12
|
|
|
13
13
|
### Removed
|
|
14
14
|
|
|
15
|
+
## [2026.9.25] - 2026-09-25
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- The package now bundles the desktop computer-use engine (`@code-yeongyu/senpi-desktop-engine` with a per-platform `senpi-desktop-engine` executable) and its protocol package. Nothing uses them yet; the `computer` tool that drives them lands in a later release. ([#2129](https://github.com/code-yeongyu/senpi/pull/2129))
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- The Cursor CLI lane (`cursor-cli-oauth`) now sends your request together with any hidden messages that follow it in the same turn; the first request of a session was reaching the model as only the hidden plan reminder, and the model replied that the request was empty. ([#2139](https://github.com/code-yeongyu/senpi/issues/2139))
|
|
28
|
+
|
|
29
|
+
- The repetitive-turns stream rule no longer aborts a handoff block because it restates your request; it compares only the status the block reports, so an agent that repeats the same status is still stopped, and its remediation no longer forbids progress reports. ([#2135](https://github.com/code-yeongyu/senpi/issues/2135))
|
|
30
|
+
|
|
31
|
+
- The first-turn plan opener now waits for your first request instead of arming on a turn an extension started before you spoke (such as a first-launch onboarding greeting), so your real request still opens with a phased todo list. `before_agent_start` handlers can read `event.trigger` (`"prompt"` or `"extension"`). ([#2137](https://github.com/code-yeongyu/senpi/issues/2137))
|
|
32
|
+
- When every todo closes, the cue in the todo result now says that any other report an instruction asks for (a self-review, a checklist) goes inside the handoff block's For you slot, so a project rule that asks for a report no longer replaces the block. ([#2133](https://github.com/code-yeongyu/senpi/issues/2133))
|
|
33
|
+
|
|
34
|
+
### Removed
|
|
35
|
+
|
|
15
36
|
## [2026.9.24-3] - 2026-09-24
|
|
16
37
|
|
|
17
38
|
### Breaking Changes
|
|
@@ -24,6 +45,7 @@
|
|
|
24
45
|
- The first work request of a session (not a question) now opens with a phased `todo` init: a hidden reminder asks for it, and on providers that accept a named tool choice (OpenAI Responses, OpenAI Chat Completions, Anthropic models that allow forced tool use with thinking off) the first request also forces the `todo` call. Set `todo.firstTurnPlan` to `"remind"` for the reminder only or `"off"` to disable it. ([#2121](https://github.com/code-yeongyu/senpi/issues/2121))
|
|
25
46
|
- A `todo` result that creates the list, closes a phase, or closes the last task ends with a one-line cue to write the handoff block, so the report lands right where the transition happens instead of depending on a system-prompt rule the model read long ago. ([#2121](https://github.com/code-yeongyu/senpi/issues/2121))
|
|
26
47
|
- Every `todo` tool result, including errors, opens with `Ask:` (the user request the list serves), `Now:` (the task in progress), and `Next:` (the next open task) lines; the tool result view and `/todo` show the Ask too. The first list anchors to the session's first user message and a later `init` to the newest one; the ask survives compaction. ([#2121](https://github.com/code-yeongyu/senpi/issues/2121))
|
|
48
|
+
- Persistent command monitors now receive `SENPI_MONITOR_ID` and a per-monitor `SENPI_MONITOR_STATE_DIR` that survives restarts, and a re-run after a restart also gets `SENPI_MONITOR_RESTORED=1` and `SENPI_MONITOR_DOWNTIME_MS` (an upper bound), so a watch can keep its baseline and still report a change that happened while senpi was down. ([#2108](https://github.com/code-yeongyu/senpi/issues/2108))
|
|
27
49
|
- `pi.on("before_agent_start", handler, { previewSafe: true })` declares a handler side-effect free in a preview. Only such handlers run in the session-start prompt-cache preview. ([#2115](https://github.com/code-yeongyu/senpi/issues/2115))
|
|
28
50
|
|
|
29
51
|
### Changed
|
|
@@ -34,6 +56,10 @@
|
|
|
34
56
|
|
|
35
57
|
### Fixed
|
|
36
58
|
|
|
59
|
+
- Restarting or resuming a session now brings its persistent monitors back reliably: a stale lease left by a crashed or reused process id is reclaimed, an in-process `/resume` no longer reports its own monitors as "attached in another live process", and a session held by another live process takes over automatically when that process exits. ([#2108](https://github.com/code-yeongyu/senpi/issues/2108))
|
|
60
|
+
- A restored command monitor is reported restored only if it is still running 2 seconds after the re-run; one that exits is reported lost with its exit code and first output line, a watcher left running by a crash is stopped before the re-run (only when its identity is confirmed), and each restored watch gets one "restored after up to <downtime> offline" line. ([#2108](https://github.com/code-yeongyu/senpi/issues/2108))
|
|
61
|
+
- The restore summary is one message that names every monitor with its outcome and reason, is shown to the user as well as the model, and waits for a model instead of being dropped when none is selected yet. ([#2108](https://github.com/code-yeongyu/senpi/issues/2108))
|
|
62
|
+
- One-shot `--print`/`--mode json` runs no longer write terminal leases or manifests, an empty manifest is deleted instead of written, stale leases and empty manifests are cleaned up in the background, and a persistent file monitor no longer times out after 5 minutes. ([#2108](https://github.com/code-yeongyu/senpi/issues/2108))
|
|
37
63
|
- The hidden `<environment_context>` block is now the first content block of the user message it precedes instead of a separate user message, so OpenAI Chat Completions requests no longer carry two consecutive user messages that alternation-enforcing chat templates (vLLM Mistral tool template, Gemma 3) reject. Saved sessions, date or directory rollover, and resume behave as before. ([#2118](https://github.com/code-yeongyu/senpi/issues/2118))
|
|
38
64
|
- The session-start prompt-cache prewarm no longer runs `before_agent_start` handlers that never opted in to previews, so an extension that consumes one-shot state there (such as delivering queued notices) no longer loses it before the first turn. While such a handler is registered the prewarm is skipped and a `prompt-cache-prewarm` entry records `phase: "skipped"` with the reason; a prompt that starts its turn while the preview is still composing cancels it. ([#2115](https://github.com/code-yeongyu/senpi/issues/2115))
|
|
39
65
|
|
package/dist/bundle/chunks/{app-server-command-OTRHYRIB.js → app-server-command-RB6QUPRI.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{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,goalStoreRef,loadMcpConfig,loadSkills,readGoal,resolveAuthMode,updateGoal}from"./chunk-JJ3NJZBD.js";import{require_ignore}from"./chunk-ZKZAATFM.js";import"./chunk-UYCGOK6M.js";import"./chunk-6WBYI25N.js";import{SessionManager,loadEntriesFromFile}from"./chunk-OZCB6BP3.js";import"./chunk-YS5YEX4S.js";import{getCredentialAccounts,getModels,getProviders,getSupportedThinkingLevels,pinCredentialAccount,removeCredentialAccount,subscribeProviderAccountEvents}from"./chunk-SGYEOIOJ.js";import{getAvailableThemesWithPaths,getThemeByName,takeOverStdout,theme,waitForRawStdoutBackpressure,writeRawStdout}from"./chunk-77ACEMYL.js";import{x}from"./chunk-EJKCBRYK.js";import"./chunk-6Q6DGME2.js";import{SettingsManager}from"./chunk-WM5FVFAP.js";import"./chunk-YU2P3CAR.js";import"./chunk-BMX2U22F.js";import"./chunk-MKAM7IRH.js";import{acquireOwnershipSafeLock}from"./chunk-CLZVNQW3.js";import"./chunk-HH3KJDWA.js";import{parseDaemonPidFile,processMatchesPidFile,readProcessStartTime,stopValidatedPid,waitForGone,waitForStartTime}from"./chunk-3WBSBDBX.js";import{attachJsonlLineReader}from"./chunk-UBPMXBOJ.js";import"./chunk-FIJJKSPL.js";import"./chunk-H4QOEVS5.js";import"./chunk-HB35RBP4.js";import"./chunk-HZAKOVHN.js";import"./chunk-TTY5BHCG.js";import"./chunk-FHXKBENX.js";import"./chunk-X3T45623.js";import"./chunk-7X72IACK.js";import"./chunk-KUPQO7MC.js";import"./chunk-Y54V65MS.js";import"./chunk-SUQDU5KM.js";import"./chunk-BSOJHK4W.js";import"./chunk-26UBFF6N.js";import"./chunk-KMJXSXRX.js";import"./chunk-L6JO4M6J.js";import"./chunk-RFB5CBW7.js";import"./chunk-2VZJTDUX.js";import"./chunk-ELFCNCBY.js";import"./chunk-PRC5XIIH.js";import"./chunk-34HMVB33.js";import"./chunk-ZOFZRJSL.js";import"./chunk-2SOVDETB.js";import{APP_NAME,CONFIG_DIR_NAME,ENV_SESSION_DIR,VERSION,getAgentDir,getSessionsDir,resolvePath}from"./chunk-Y65WFI5H.js";import"./chunk-ATQFN5HI.js";import"./chunk-RBCQOIAD.js";import"./chunk-WASCMT6Y.js";import"./chunk-X4Q5YSTE.js";import"./chunk-IXAUDPOK.js";import"./chunk-TTHMOL5G.js";import"./chunk-WVGCQOLJ.js";import"./chunk-BPX6QWPD.js";import{normalizeProviderId}from"./chunk-WL5EQYNL.js";import"./chunk-WDTJ6JKE.js";import"./chunk-5ROMKDLK.js";import"./chunk-3W47LTXQ.js";import"./chunk-DMI55M2N.js";import"./chunk-BQVVQ2LQ.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]`,` ${APP_NAME} app-server daemon <start|stop|status|restart> [--listen <${listenForms}>]`].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}}function parseServerArgs(args){let listen3={kind:"stdio",url:"stdio://"},wsAuth,jsonLogs=!1;for(let index=0;index<args.length;index++){let arg=args[index];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}}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};for(let index=1;index<args.length;index++){let arg=args[index];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}}function parseAppServerCliArgs(args){return args[0]==="daemon"?parseDaemonArgs(args.slice(1)):parseServerArgs(args)}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(`
|