@code-yeongyu/senpi 2026.8.30 → 2026.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +174 -2
- package/README.md +3 -0
- package/dist/core/agent-session.d.ts +28 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +161 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction-execution.d.ts +14 -0
- package/dist/core/compaction/compaction-execution.d.ts.map +1 -0
- package/dist/core/compaction/compaction-execution.js +121 -0
- package/dist/core/compaction/compaction-execution.js.map +1 -0
- package/dist/core/compaction/compaction-settings.d.ts +17 -0
- package/dist/core/compaction/compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/compaction-settings.js +17 -0
- package/dist/core/compaction/compaction-settings.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +13 -26
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +7 -136
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/compaction/ideal-compaction-settings.d.ts +9 -0
- package/dist/core/compaction/ideal-compaction-settings.d.ts.map +1 -0
- package/dist/core/compaction/ideal-compaction-settings.js +7 -0
- package/dist/core/compaction/ideal-compaction-settings.js.map +1 -0
- package/dist/core/compaction-settings-access.d.ts +19 -0
- package/dist/core/compaction-settings-access.d.ts.map +1 -0
- package/dist/core/compaction-settings-access.js +10 -0
- package/dist/core/compaction-settings-access.js.map +1 -0
- package/dist/core/compaction-settings-resolver.d.ts +22 -0
- package/dist/core/compaction-settings-resolver.d.ts.map +1 -0
- package/dist/core/compaction-settings-resolver.js +46 -0
- package/dist/core/compaction-settings-resolver.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts +9 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js +10 -3
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-registry.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts +24 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js +43 -0
- package/dist/core/extensions/builtin/compaction/context-pipeline.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +8 -2
- package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts +17 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js +64 -0
- package/dist/core/extensions/builtin/compaction/emergency-prune.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts +27 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js +84 -0
- package/dist/core/extensions/builtin/compaction/extension-wiring.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/idle-retry.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.js +1 -1
- package/dist/core/extensions/builtin/compaction/idle-retry.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/idle.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/idle.js +13 -2
- package/dist/core/extensions/builtin/compaction/idle.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +152 -154
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +2 -0
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts +14 -0
- package/dist/core/extensions/builtin/compaction/model-selection.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js +37 -0
- package/dist/core/extensions/builtin/compaction/model-selection.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +30 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.js +74 -0
- package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts +9 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js +2 -0
- package/dist/core/extensions/builtin/compaction/openai-remote-dependencies.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +3 -6
- package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts +46 -0
- package/dist/core/extensions/builtin/compaction/orchestration.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js +103 -0
- package/dist/core/extensions/builtin/compaction/orchestration.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/policy.d.ts +12 -2
- package/dist/core/extensions/builtin/compaction/policy.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/policy.js +52 -26
- package/dist/core/extensions/builtin/compaction/policy.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts +8 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js +17 -0
- package/dist/core/extensions/builtin/compaction/speculation-lead.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts +22 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js +16 -0
- package/dist/core/extensions/builtin/compaction/speculative-job.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +23 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js +132 -0
- package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +8 -13
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +21 -197
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts +24 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js +25 -0
- package/dist/core/extensions/builtin/compaction/token-budget-reminder.js.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts +27 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.d.ts.map +1 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js +56 -0
- package/dist/core/extensions/builtin/compaction/tool-admission.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts +5 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.d.ts.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js +76 -0
- package/dist/core/extensions/builtin/hooks/trust-state-json.js.map +1 -0
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts +7 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust-storage.js +60 -8
- package/dist/core/extensions/builtin/hooks/trust-storage.js.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.d.ts +1 -2
- package/dist/core/extensions/builtin/hooks/trust.d.ts.map +1 -1
- package/dist/core/extensions/builtin/hooks/trust.js +1 -72
- package/dist/core/extensions/builtin/hooks/trust.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts +3 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.d.ts.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +108 -0
- package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/presets.js +11 -0
- package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
- package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js +1 -1
- package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts +11 -0
- package/dist/core/extensions/builtin/terminal/runtime-session.d.ts.map +1 -1
- package/dist/core/extensions/builtin/terminal/runtime-session.js +18 -2
- package/dist/core/extensions/builtin/terminal/runtime-session.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/index.js +4 -0
- package/dist/core/extensions/builtin/ttsr/index.js.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.d.ts +2 -0
- package/dist/core/extensions/builtin/ttsr/manager.d.ts.map +1 -1
- package/dist/core/extensions/builtin/ttsr/manager.js +28 -1
- package/dist/core/extensions/builtin/ttsr/manager.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +7 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/retry-fallback/controller.d.ts +14 -0
- package/dist/core/retry-fallback/controller.d.ts.map +1 -1
- package/dist/core/retry-fallback/controller.js +33 -3
- package/dist/core/retry-fallback/controller.js.map +1 -1
- package/dist/core/retry-fallback/log.js +1 -1
- package/dist/core/retry-fallback/log.js.map +1 -1
- package/dist/core/retry-fallback/settings.d.ts.map +1 -1
- package/dist/core/retry-fallback/settings.js +1 -0
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +5 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-activity.d.ts +47 -0
- package/dist/core/session-activity.d.ts.map +1 -0
- package/dist/core/session-activity.js +58 -0
- package/dist/core/session-activity.js.map +1 -0
- package/dist/core/session-manager.d.ts +8 -12
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +118 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-resident-store.d.ts +8 -1
- package/dist/core/session-resident-store.d.ts.map +1 -1
- package/dist/core/session-resident-store.js +12 -5
- package/dist/core/session-resident-store.js.map +1 -1
- package/dist/core/settings-manager.d.ts +8 -85
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -17
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-public-types.d.ts +11 -0
- package/dist/core/settings-public-types.d.ts.map +1 -0
- package/dist/core/settings-public-types.js +2 -0
- package/dist/core/settings-public-types.js.map +1 -0
- package/dist/core/settings-shapes.d.ts +36 -0
- package/dist/core/settings-shapes.d.ts.map +1 -0
- package/dist/core/settings-shapes.js +2 -0
- package/dist/core/settings-shapes.js.map +1 -0
- package/dist/core/shared-host-policy.d.ts +6 -0
- package/dist/core/shared-host-policy.d.ts.map +1 -0
- package/dist/core/shared-host-policy.js +7 -0
- package/dist/core/shared-host-policy.js.map +1 -0
- package/dist/core/terminal-settings.d.ts +22 -0
- package/dist/core/terminal-settings.d.ts.map +1 -0
- package/dist/core/terminal-settings.js +2 -0
- package/dist/core/terminal-settings.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -4
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +27 -11
- package/dist/main.js.map +1 -1
- package/dist/modes/app-server/daemon/process.d.ts +13 -2
- package/dist/modes/app-server/daemon/process.d.ts.map +1 -1
- package/dist/modes/app-server/daemon/process.js +58 -12
- package/dist/modes/app-server/daemon/process.js.map +1 -1
- package/dist/modes/app-server/daemon.js +65 -7
- package/dist/modes/app-server/daemon.js.map +1 -1
- package/dist/modes/index.d.ts +1 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -1
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts +84 -1
- package/dist/modes/interactive/interactive-host-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-host-runtime.js +435 -112
- package/dist/modes/interactive/interactive-host-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +11 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +59 -6
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js +1 -1
- package/dist/modes/interactive/tips/catalog/ethos-tips.js.map +1 -1
- package/dist/modes/rpc/connection-handler.d.ts +12 -5
- package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
- package/dist/modes/rpc/connection-handler.js +180 -25
- package/dist/modes/rpc/connection-handler.js.map +1 -1
- package/dist/modes/rpc/custom-capability.d.ts +2 -0
- package/dist/modes/rpc/custom-capability.d.ts.map +1 -1
- package/dist/modes/rpc/custom-capability.js +2 -0
- package/dist/modes/rpc/custom-capability.js.map +1 -1
- package/dist/modes/rpc/host-ensure.d.ts +17 -0
- package/dist/modes/rpc/host-ensure.d.ts.map +1 -1
- package/dist/modes/rpc/host-ensure.js +150 -23
- package/dist/modes/rpc/host-ensure.js.map +1 -1
- package/dist/modes/rpc/host-lifecycle.d.ts +54 -0
- package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
- package/dist/modes/rpc/host-lifecycle.js +259 -69
- package/dist/modes/rpc/host-lifecycle.js.map +1 -1
- package/dist/modes/rpc/host-watchdog.d.ts +2 -2
- package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
- package/dist/modes/rpc/host-watchdog.js +89 -21
- package/dist/modes/rpc/host-watchdog.js.map +1 -1
- package/dist/modes/rpc/multi-session-host.d.ts +38 -0
- package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
- package/dist/modes/rpc/multi-session-host.js +149 -61
- package/dist/modes/rpc/multi-session-host.js.map +1 -1
- package/dist/modes/rpc/ownership-safe-lock.d.ts +14 -0
- package/dist/modes/rpc/ownership-safe-lock.d.ts.map +1 -0
- package/dist/modes/rpc/ownership-safe-lock.js +87 -0
- package/dist/modes/rpc/ownership-safe-lock.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +13 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +46 -12
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +21 -3
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +1 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/rpc/session-binding.d.ts +2 -1
- package/dist/modes/rpc/session-binding.d.ts.map +1 -1
- package/dist/modes/rpc/session-binding.js +1 -0
- package/dist/modes/rpc/session-binding.js.map +1 -1
- package/dist/modes/rpc/session-command-router.d.ts +54 -1
- package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
- package/dist/modes/rpc/session-command-router.js +180 -3
- package/dist/modes/rpc/session-command-router.js.map +1 -1
- package/dist/modes/rpc/session-event-writer.d.ts +18 -0
- package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
- package/dist/modes/rpc/session-event-writer.js +88 -8
- package/dist/modes/rpc/session-event-writer.js.map +1 -1
- package/dist/modes/rpc/session-registry.d.ts +11 -1
- package/dist/modes/rpc/session-registry.d.ts.map +1 -1
- package/dist/modes/rpc/session-registry.js +25 -0
- package/dist/modes/rpc/session-registry.js.map +1 -1
- package/dist/modes/rpc/socket-transport.d.ts +13 -0
- package/dist/modes/rpc/socket-transport.d.ts.map +1 -0
- package/dist/modes/rpc/socket-transport.js +92 -0
- package/dist/modes/rpc/socket-transport.js.map +1 -0
- package/dist/modes/rpc/widget-line-renderer.d.ts +17 -0
- package/dist/modes/rpc/widget-line-renderer.d.ts.map +1 -0
- package/dist/modes/rpc/widget-line-renderer.js +73 -0
- package/dist/modes/rpc/widget-line-renderer.js.map +1 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +11 -2
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/app-server.md +2 -2
- package/docs/containerization.md +2 -2
- package/docs/development.md +7 -7
- package/docs/extensions.md +5 -5
- package/docs/grok-neo.md +1 -1
- package/docs/index.md +1 -1
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +4 -4
- package/docs/release-guide.md +21 -21
- package/docs/rpc.md +83 -6
- package/docs/sdk.md +1 -1
- package/docs/settings.md +4 -4
- package/docs/skills.md +2 -2
- package/docs/terminal-tools.md +1 -1
- package/docs/termux.md +1 -1
- package/docs/tui.md +1 -1
- package/examples/AGENTS.md +1 -1
- package/examples/sdk/README.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/README.md +2 -2
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/skill-contribution.ts +71 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +3 -1
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/SKILL.md +44 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/breaking-changes.md +75 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/build.md +114 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/dev-tooling.md +34 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/http-networking.md +113 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/install.md +93 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/node-compat-platforms.md +36 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/performance.md +33 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/runtime-apis.md +156 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/security.md +52 -0
- package/node_modules/@code-yeongyu/senpi-codemode/src/skill/bun-1-4/references/test.md +103 -0
- package/node_modules/@earendil-works/pi-agent-core/README.md +3 -0
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/README.md +6 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +24 -7
- package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +7 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +316 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts +4 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js +23 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts +24 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +20 -2
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.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/screen-operations.d.ts +42 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js +34 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-operations.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts +8 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.js +51 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen-text.js.map +1 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts +45 -0
- package/node_modules/@earendil-works/pi-pty/dist/screen.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-pty/dist/screen.js +178 -55
- package/node_modules/@earendil-works/pi-pty/dist/screen.js.map +1 -1
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/README.md +6 -3
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/README.md +5 -4
- package/node_modules/@earendil-works/pi-tui/native/darwin/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/native/win32/README.md +2 -2
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { initTheme, theme } from "../interactive/theme/theme.js";
|
|
2
|
+
export function createLiveComponentRenderer(options) {
|
|
3
|
+
let disposed = false;
|
|
4
|
+
let timer;
|
|
5
|
+
try {
|
|
6
|
+
// RPC hosts do not necessarily pass through the interactive theme setup.
|
|
7
|
+
try {
|
|
8
|
+
void theme.name;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
initTheme("dark");
|
|
12
|
+
}
|
|
13
|
+
let component;
|
|
14
|
+
let lastLines;
|
|
15
|
+
const render = () => {
|
|
16
|
+
if (disposed)
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
const lines = component.render(options.getWidth());
|
|
20
|
+
if (lastLines &&
|
|
21
|
+
lines.length === lastLines.length &&
|
|
22
|
+
lines.every((line, i) => line === lastLines[i]))
|
|
23
|
+
return;
|
|
24
|
+
lastLines = [...lines];
|
|
25
|
+
options.emit(lines);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
// Allow a recovered render to be emitted even when it matches the last
|
|
29
|
+
// successful frame; the fault means the client may have lost that frame.
|
|
30
|
+
lastLines = undefined;
|
|
31
|
+
options.onRenderFault?.(error);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const requestRender = () => {
|
|
35
|
+
if (disposed || timer !== undefined)
|
|
36
|
+
return;
|
|
37
|
+
timer = setTimeout(() => {
|
|
38
|
+
timer = undefined;
|
|
39
|
+
render();
|
|
40
|
+
}, 0);
|
|
41
|
+
};
|
|
42
|
+
const tui = new Proxy({ requestRender }, {
|
|
43
|
+
get(target, property) {
|
|
44
|
+
if (property in target)
|
|
45
|
+
return target[property];
|
|
46
|
+
throw new Error(`RPC live component TUI member is unsupported: ${String(property)}`);
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
component = options.factory(tui, theme, ...(options.factoryArgs ?? []));
|
|
50
|
+
render();
|
|
51
|
+
return {
|
|
52
|
+
rerender: render,
|
|
53
|
+
dispose: () => {
|
|
54
|
+
if (disposed)
|
|
55
|
+
return;
|
|
56
|
+
disposed = true;
|
|
57
|
+
if (timer !== undefined)
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
timer = undefined;
|
|
60
|
+
component.dispose?.();
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
disposed = true;
|
|
66
|
+
if (timer !== undefined)
|
|
67
|
+
clearTimeout(timer);
|
|
68
|
+
timer = undefined;
|
|
69
|
+
options.onRenderFault?.(error);
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=widget-line-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-line-renderer.js","sourceRoot":"","sources":["../../../src/modes/rpc/widget-line-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAc,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAO7E,MAAM,UAAU,2BAA2B,CAAC,OAO3C;IACA,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAgD,CAAC;IACrD,IAAI,CAAC;QACJ,yEAAyE;QACzE,IAAI,CAAC;YACJ,KAAK,KAAK,CAAC,IAAI,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YACR,SAAS,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,SAA2C,CAAC;QAChD,IAAI,SAA+B,CAAC;QACpC,MAAM,MAAM,GAAG,GAAG,EAAE;YACnB,IAAI,QAAQ;gBAAE,OAAO;YACrB,IAAI,CAAC;gBACJ,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACnD,IACC,SAAS;oBACT,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;oBACjC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAY,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,KAAK,SAAU,CAAC,CAAC,CAAC,CAAC;oBAEhE,OAAO;gBACR,SAAS,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,uEAAuE;gBACvE,yEAAyE;gBACzE,SAAS,GAAG,SAAS,CAAC;gBACtB,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;QACF,CAAC,CAAC;QACF,MAAM,aAAa,GAAG,GAAG,EAAE;YAC1B,IAAI,QAAQ,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO;YAC5C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBACvB,KAAK,GAAG,SAAS,CAAC;gBAClB,MAAM,EAAE,CAAC;YACV,CAAC,EAAE,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,EAAE,aAAa,EAA6B,EAAE;YACnE,GAAG,CAAC,MAAM,EAAE,QAAyB;gBACpC,IAAI,QAAQ,IAAI,MAAM;oBAAE,OAAO,MAAM,CAAC,QAAkB,CAAC,CAAC;gBAC1D,MAAM,IAAI,KAAK,CAAC,iDAAiD,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACtF,CAAC;SACD,CAAmB,CAAC;QACrB,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,MAAM,EAAE,CAAC;QACT,OAAO;YACN,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,GAAG,EAAE;gBACb,IAAI,QAAQ;oBAAE,OAAO;gBACrB,QAAQ,GAAG,IAAI,CAAC;gBAChB,IAAI,KAAK,KAAK,SAAS;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC7C,KAAK,GAAG,SAAS,CAAC;gBAClB,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;YACvB,CAAC;SACD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC7C,KAAK,GAAG,SAAS,CAAC;QAClB,OAAO,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC","sourcesContent":["import type { Component, TUI } from \"@earendil-works/pi-tui\";\nimport { initTheme, type Theme, theme } from \"../interactive/theme/theme.ts\";\n\nexport interface LiveComponentRenderer {\n\trerender(): void;\n\tdispose(): void;\n}\n\nexport function createLiveComponentRenderer(options: {\n\tfactory: (...args: [TUI, Theme, ...unknown[]]) => Component & { dispose?(): void };\n\t/** Additional arguments are used by footer factories; widgets retain the 2-arg path. */\n\tfactoryArgs?: readonly unknown[];\n\tgetWidth: () => number;\n\temit: (lines: string[]) => void;\n\tonRenderFault?: (error: unknown) => void;\n}): LiveComponentRenderer | undefined {\n\tlet disposed = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\ttry {\n\t\t// RPC hosts do not necessarily pass through the interactive theme setup.\n\t\ttry {\n\t\t\tvoid theme.name;\n\t\t} catch {\n\t\t\tinitTheme(\"dark\");\n\t\t}\n\t\tlet component: Component & { dispose?(): void };\n\t\tlet lastLines: string[] | undefined;\n\t\tconst render = () => {\n\t\t\tif (disposed) return;\n\t\t\ttry {\n\t\t\t\tconst lines = component.render(options.getWidth());\n\t\t\t\tif (\n\t\t\t\t\tlastLines &&\n\t\t\t\t\tlines.length === lastLines.length &&\n\t\t\t\t\tlines.every((line: string, i: number) => line === lastLines![i])\n\t\t\t\t)\n\t\t\t\t\treturn;\n\t\t\t\tlastLines = [...lines];\n\t\t\t\toptions.emit(lines);\n\t\t\t} catch (error) {\n\t\t\t\t// Allow a recovered render to be emitted even when it matches the last\n\t\t\t\t// successful frame; the fault means the client may have lost that frame.\n\t\t\t\tlastLines = undefined;\n\t\t\t\toptions.onRenderFault?.(error);\n\t\t\t}\n\t\t};\n\t\tconst requestRender = () => {\n\t\t\tif (disposed || timer !== undefined) return;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\trender();\n\t\t\t}, 0);\n\t\t};\n\t\tconst tui = new Proxy({ requestRender } as Record<string, unknown>, {\n\t\t\tget(target, property: string | symbol) {\n\t\t\t\tif (property in target) return target[property as string];\n\t\t\t\tthrow new Error(`RPC live component TUI member is unsupported: ${String(property)}`);\n\t\t\t},\n\t\t}) as unknown as TUI;\n\t\tcomponent = options.factory(tui, theme, ...(options.factoryArgs ?? []));\n\t\trender();\n\t\treturn {\n\t\t\trerender: render,\n\t\t\tdispose: () => {\n\t\t\t\tif (disposed) return;\n\t\t\t\tdisposed = true;\n\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t\tcomponent.dispose?.();\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tdisposed = true;\n\t\tif (timer !== undefined) clearTimeout(timer);\n\t\ttimer = undefined;\n\t\toptions.onRenderFault?.(error);\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-watch.d.ts","sourceRoot":"","sources":["../../src/utils/fs-watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"fs-watch.d.ts","sourceRoot":"","sources":["../../src/utils/fs-watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAS,MAAM,SAAS,CAAC;AAErG,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAE5C,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAUxE;AAED,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,EAC/B,OAAO,EAAE,MAAM,IAAI,EACnB,OAAO,CAAC,EAAE,YAAY,GACpB,SAAS,GAAG,IAAI,CAiBlB"}
|
package/dist/utils/fs-watch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { watch } from "node:fs";
|
|
1
|
+
import { realpathSync, watch } from "node:fs";
|
|
2
2
|
export const FS_WATCH_RETRY_DELAY_MS = 5000;
|
|
3
3
|
export function closeWatcher(watcher) {
|
|
4
4
|
if (!watcher) {
|
|
@@ -13,7 +13,16 @@ export function closeWatcher(watcher) {
|
|
|
13
13
|
}
|
|
14
14
|
export function watchWithErrorHandler(path, listener, onError, options) {
|
|
15
15
|
try {
|
|
16
|
-
|
|
16
|
+
let watchPath = path;
|
|
17
|
+
if (process.platform === "win32") {
|
|
18
|
+
try {
|
|
19
|
+
watchPath = realpathSync.native(path);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// Keep the raw path when it does not exist yet.
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const watcher = watch(watchPath, { ...options, encoding: "utf8" }, listener);
|
|
17
26
|
watcher.on("error", onError);
|
|
18
27
|
return watcher;
|
|
19
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-watch.js","sourceRoot":"","sources":["../../src/utils/fs-watch.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"fs-watch.js","sourceRoot":"","sources":["../../src/utils/fs-watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,YAAY,EAAyC,KAAK,EAAE,MAAM,SAAS,CAAC;AAErG,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAE5C,MAAM,UAAU,YAAY,CAAC,OAAqC;IACjE,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO;IACR,CAAC;IAED,IAAI,CAAC;QACJ,OAAO,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACR,8BAA8B;IAC/B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CACpC,IAAY,EACZ,QAA+B,EAC/B,OAAmB,EACnB,OAAsB;IAEtB,IAAI,CAAC;QACJ,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC;gBACJ,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACR,gDAAgD;YACjD,CAAC;QACF,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC7E,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC","sourcesContent":["import { type FSWatcher, realpathSync, type WatchListener, type WatchOptions, watch } from \"node:fs\";\n\nexport const FS_WATCH_RETRY_DELAY_MS = 5000;\n\nexport function closeWatcher(watcher: FSWatcher | null | undefined): void {\n\tif (!watcher) {\n\t\treturn;\n\t}\n\n\ttry {\n\t\twatcher.close();\n\t} catch {\n\t\t// Ignore watcher close errors\n\t}\n}\n\nexport function watchWithErrorHandler(\n\tpath: string,\n\tlistener: WatchListener<string>,\n\tonError: () => void,\n\toptions?: WatchOptions,\n): FSWatcher | null {\n\ttry {\n\t\tlet watchPath = path;\n\t\tif (process.platform === \"win32\") {\n\t\t\ttry {\n\t\t\t\twatchPath = realpathSync.native(path);\n\t\t\t} catch {\n\t\t\t\t// Keep the raw path when it does not exist yet.\n\t\t\t}\n\t\t}\n\t\tconst watcher = watch(watchPath, { ...options, encoding: \"utf8\" }, listener);\n\t\twatcher.on(\"error\", onError);\n\t\treturn watcher;\n\t} catch {\n\t\tonError();\n\t\treturn null;\n\t}\n}\n"]}
|
package/docs/app-server.md
CHANGED
|
@@ -537,8 +537,8 @@ timestamps, paths, and tokens, and preserves frame order, array order, and notif
|
|
|
537
537
|
From `packages/coding-agent`, build the pinned Codex oracle once, then run the available handshake scenario:
|
|
538
538
|
|
|
539
539
|
```bash
|
|
540
|
-
|
|
541
|
-
|
|
540
|
+
bun scripts/qa-app-server/differential/build-oracle.mjs
|
|
541
|
+
bun scripts/qa-app-server/differential/run.mjs --scenario handshake
|
|
542
542
|
```
|
|
543
543
|
|
|
544
544
|
The build uses `/Users/yeongyu/local-workspaces/codex/codex-rs/Cargo.toml` and writes the binary under that checkout's
|
package/docs/containerization.md
CHANGED
|
@@ -26,7 +26,7 @@ Setup:
|
|
|
26
26
|
```bash
|
|
27
27
|
cp -R packages/coding-agent/examples/extensions/gondolin ~/.senpi/agent/extensions/gondolin
|
|
28
28
|
cd ~/.senpi/agent/extensions/gondolin
|
|
29
|
-
|
|
29
|
+
bun add --ignore-scripts
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Run from the project you want mounted:
|
|
@@ -54,7 +54,7 @@ FROM node:24-bookworm-slim
|
|
|
54
54
|
RUN apt-get update \
|
|
55
55
|
&& apt-get install -y --no-install-recommends bash ca-certificates git ripgrep \
|
|
56
56
|
&& rm -rf /var/lib/apt/lists/*
|
|
57
|
-
RUN
|
|
57
|
+
RUN bun add -g --ignore-scripts @code-yeongyu/senpi
|
|
58
58
|
|
|
59
59
|
WORKDIR /workspace
|
|
60
60
|
ENTRYPOINT ["senpi"]
|
package/docs/development.md
CHANGED
|
@@ -7,8 +7,8 @@ See [AGENTS.md](../../../AGENTS.md) at the monorepo root for fork-specific guide
|
|
|
7
7
|
```bash
|
|
8
8
|
git clone https://github.com/code-yeongyu/senpi
|
|
9
9
|
cd senpi
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
bun install
|
|
11
|
+
bun run build
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Run from source:
|
|
@@ -36,7 +36,7 @@ Change `name`, `configDir`, and `bin` field for your fork. Affects CLI banner, c
|
|
|
36
36
|
|
|
37
37
|
## Path Resolution
|
|
38
38
|
|
|
39
|
-
Three execution modes:
|
|
39
|
+
Three execution modes: bun install, standalone binary (`bun build --compile`), tsx from source.
|
|
40
40
|
|
|
41
41
|
**Always use `src/config.ts`** for package assets:
|
|
42
42
|
|
|
@@ -55,17 +55,17 @@ Never use `__dirname` directly for package assets.
|
|
|
55
55
|
## Testing
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
|
|
58
|
+
bun run test # Vitest across workspaces (skips live-API; default test runner)
|
|
59
59
|
./pi-test.sh # Launch the CLI from source via tsx for manual testing (--no-env unsets API keys)
|
|
60
|
-
|
|
60
|
+
bun run check # Biome + tsc + browser-smoke check (pre-commit equivalent)
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Live-API tests are env-gated vitest tests. Set `PI_ENABLE_LIVE_API_TESTS=1` (or a per-provider flag from `packages/ai/test/live-api-gates.ts`) plus the provider API keys, then run `
|
|
63
|
+
Live-API tests are env-gated vitest tests. Set `PI_ENABLE_LIVE_API_TESTS=1` (or a per-provider flag from `packages/ai/test/live-api-gates.ts`) plus the provider API keys, then run `bun run test`.
|
|
64
64
|
|
|
65
65
|
Run a specific test:
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
|
|
68
|
+
bun run test --workspace @code-yeongyu/senpi -- test/specific.test.ts
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
## Project Structure
|
package/docs/extensions.md
CHANGED
|
@@ -116,7 +116,7 @@ The bundled `model-fallback` extension registers `/fallback` to manage global pe
|
|
|
116
116
|
Use the quick-set form in scripts or any non-TUI mode:
|
|
117
117
|
|
|
118
118
|
```text
|
|
119
|
-
/fallback anthropic/claude-fable-5 ccapi/kimi-k3:max
|
|
119
|
+
/fallback anthropic/claude-fable-5-1 ccapi/kimi-k3:max
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
The first argument is the exact primary model selector; each later argument is an ordered fallback selector. Quick-set validates selectors before saving. At least one fallback is required:
|
|
@@ -184,9 +184,9 @@ To share extensions via npm or git as senpi packages, see [packages.md](packages
|
|
|
184
184
|
| `@earendil-works/pi-ai` | AI utilities (`StringEnum` for Google-compatible enums) |
|
|
185
185
|
| `@earendil-works/pi-tui` | TUI components for custom rendering |
|
|
186
186
|
|
|
187
|
-
npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `
|
|
187
|
+
npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `bun install`, and imports from `node_modules/` are resolved automatically.
|
|
188
188
|
|
|
189
|
-
For distributed senpi packages installed with `senpi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`
|
|
189
|
+
For distributed senpi packages installed with `senpi install` (npm or git), runtime deps must be in `dependencies`. Package installation uses production installs (`bun add --omit=dev`) by default, so `devDependencies` are not available at runtime; when `npmCommand` is configured, git packages use plain `install` for compatibility with wrappers.
|
|
190
190
|
|
|
191
191
|
Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
|
|
192
192
|
|
|
@@ -288,7 +288,7 @@ Defer background resource startup until `session_start` or the command/tool/even
|
|
|
288
288
|
└── my-extension/
|
|
289
289
|
├── package.json # Declares dependencies and entry points
|
|
290
290
|
├── package-lock.json
|
|
291
|
-
├── node_modules/ # After
|
|
291
|
+
├── node_modules/ # After bun install
|
|
292
292
|
└── src/
|
|
293
293
|
└── index.ts
|
|
294
294
|
```
|
|
@@ -307,7 +307,7 @@ Defer background resource startup until `session_start` or the command/tool/even
|
|
|
307
307
|
}
|
|
308
308
|
```
|
|
309
309
|
|
|
310
|
-
Run `
|
|
310
|
+
Run `bun install` in the extension directory, then imports from `node_modules/` work automatically.
|
|
311
311
|
|
|
312
312
|
## Events
|
|
313
313
|
|
package/docs/grok-neo.md
CHANGED
|
@@ -64,7 +64,7 @@ Senpi is a rebranded distribution, so its first-time setup is intentionally unav
|
|
|
64
64
|
|
|
65
65
|
`--grok-neo` runs **in-process**: the chrome is a presentation strategy inside the ordinary interactive mode, in the same senpi process. There is no separate binary and no daemon — unlike the retired `--neo`, which launched a Go TUI binary talking to senpi over a JSONL RPC daemon.
|
|
66
66
|
|
|
67
|
-
For the Bun-compiled binary (`
|
|
67
|
+
For the Bun-compiled binary (`bun run build:binary`) this means one process and one deployable directory. `bun build --compile` produces a single `dist/pi` executable, and its runtime assets ship alongside it in `dist/`: theme JSON files, image assets, the photon WASM module, and the pty native addon. Native `.node` addons are **not** embedded by `bun build --compile`; the pty addon is resolved as a sidecar relative to the executable (`dist/native/prebuilds/<platform-arch>/`). So the honest claim is "one process, one deployable directory" — not one file.
|
|
68
68
|
|
|
69
69
|
## Experimental Status
|
|
70
70
|
|
package/docs/index.md
CHANGED
|
@@ -7,7 +7,7 @@ Senpi is a minimal terminal coding harness. It is designed to stay small at the
|
|
|
7
7
|
Install with npm:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
bun add -g @code-yeongyu/senpi
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
To uninstall senpi itself, use the package manager that installed it:
|
package/docs/packages.md
CHANGED
|
@@ -90,7 +90,7 @@ ssh://git@github.com/user/repo@v1
|
|
|
90
90
|
- Refs are pinned tags or commits. `pi update --extensions` and `pi update --all` do not move them to newer refs, but they do reconcile an existing clone to the configured ref.
|
|
91
91
|
- Use `pi install git:host/user/repo@new-ref` to update settings and move an existing package to a new pinned ref.
|
|
92
92
|
- Cloned to `~/.pi/agent/git/<host>/<path>` (global) or `.pi/git/<host>/<path>` (project).
|
|
93
|
-
- When reconciliation changes the checkout, pi resets and cleans the clone, then runs `
|
|
93
|
+
- When reconciliation changes the checkout, pi resets and cleans the clone, then runs `bun install` if `package.json` exists.
|
|
94
94
|
|
|
95
95
|
**SSH examples:**
|
|
96
96
|
```bash
|
|
@@ -166,7 +166,7 @@ If no `pi` manifest is present, pi auto-discovers resources from these directori
|
|
|
166
166
|
|
|
167
167
|
## Dependencies
|
|
168
168
|
|
|
169
|
-
Third party runtime dependencies belong in `dependencies` in `package.json`. Dependencies that do not register extensions, skills, prompt templates, or themes also belong in `dependencies`. When pi installs a package from npm or git, it runs `
|
|
169
|
+
Third party runtime dependencies belong in `dependencies` in `package.json`. Dependencies that do not register extensions, skills, prompt templates, or themes also belong in `dependencies`. When pi installs a package from npm or git, it runs `bun install`, so those dependencies are installed automatically.
|
|
170
170
|
|
|
171
171
|
Pi bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@earendil-works/pi-ai`, `@earendil-works/pi-agent-core`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, `typebox`.
|
|
172
172
|
|
package/docs/quickstart.md
CHANGED
|
@@ -10,7 +10,7 @@ procedure, see the [release and installation guide](release-guide.md).
|
|
|
10
10
|
Senpi is distributed as an npm package:
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
|
-
|
|
13
|
+
bun add -g @code-yeongyu/senpi
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
### Uninstall
|
|
@@ -18,7 +18,7 @@ npm install -g @code-yeongyu/senpi
|
|
|
18
18
|
Use the package manager that installed senpi:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
#
|
|
21
|
+
# bun add -g
|
|
22
22
|
npm uninstall -g @code-yeongyu/senpi
|
|
23
23
|
|
|
24
24
|
# pnpm
|
|
@@ -91,7 +91,7 @@ Senpi loads context files at startup. Add an `AGENTS.md` file to tell it how to
|
|
|
91
91
|
```markdown
|
|
92
92
|
# Project Instructions
|
|
93
93
|
|
|
94
|
-
- Run `
|
|
94
|
+
- Run `bun run check` after code changes.
|
|
95
95
|
- Do not run production migrations locally.
|
|
96
96
|
- Keep responses concise.
|
|
97
97
|
```
|
|
@@ -123,7 +123,7 @@ Images or text can be pasted with Ctrl+V (Alt+V on Windows); images can also be
|
|
|
123
123
|
In interactive mode:
|
|
124
124
|
|
|
125
125
|
```text
|
|
126
|
-
!
|
|
126
|
+
!bun run lint
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
The command output is sent to the model. Use `!!command` to run a command without adding its output to the model context.
|
package/docs/release-guide.md
CHANGED
|
@@ -216,7 +216,7 @@ change the supported Node/npm installation path or require a configuration migra
|
|
|
216
216
|
`release:local` stages the publish manifest and bundled package tree inside the source checkout
|
|
217
217
|
while packing. Run it from a clean, dedicated release checkout rather than a shared dirty
|
|
218
218
|
worktree. After packing, verify `packages/coding-agent/package.json` still has only the five
|
|
219
|
-
intentional internal bundle entries and run `
|
|
219
|
+
intentional internal bundle entries and run `bun install --ignore-scripts` before resuming
|
|
220
220
|
development so workspace dependency resolution is restored. Do not use destructive Git cleanup
|
|
221
221
|
when other work is present.
|
|
222
222
|
|
|
@@ -225,25 +225,25 @@ when other work is present.
|
|
|
225
225
|
Run from the repository root:
|
|
226
226
|
|
|
227
227
|
```bash
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
CI=1
|
|
228
|
+
bun run check
|
|
229
|
+
bun run build
|
|
230
|
+
CI=1 bun run test
|
|
231
231
|
npm audit --omit=dev
|
|
232
232
|
```
|
|
233
233
|
|
|
234
234
|
The release-script checks are:
|
|
235
235
|
|
|
236
236
|
```bash
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
bun scripts/generate-coding-agent-shrinkwrap.mjs --check
|
|
238
|
+
bun scripts/generate-coding-agent-install-lock.mjs --check
|
|
239
|
+
bun scripts/upstream-release-worthy.mjs
|
|
240
|
+
bun run release --dry-run
|
|
241
|
+
bun scripts/release-notes.mjs extract \
|
|
242
242
|
--version 2026.7.30-2 \
|
|
243
243
|
--tag v2026.7.30-2
|
|
244
244
|
```
|
|
245
245
|
|
|
246
|
-
`
|
|
246
|
+
`bun run release --dry-run` is safe for this workflow. Do not run the live release command:
|
|
247
247
|
the live path commits, tags, and pushes.
|
|
248
248
|
|
|
249
249
|
## Plugin verification
|
|
@@ -251,7 +251,7 @@ the live path commits, tags, and pushes.
|
|
|
251
251
|
Run the focused extension suites:
|
|
252
252
|
|
|
253
253
|
```bash
|
|
254
|
-
|
|
254
|
+
bunx --cwd packages/coding-agent vitest \
|
|
255
255
|
--run \
|
|
256
256
|
test/suite/builtin-extension-sync.test.ts \
|
|
257
257
|
test/suite/vendored-builtins.test.ts \
|
|
@@ -304,7 +304,7 @@ Choose one durable output directory outside the repository:
|
|
|
304
304
|
```bash
|
|
305
305
|
cd /Users/yeongyu/local-workspaces/senpi
|
|
306
306
|
ARTIFACT_ROOT="$HOME/.local/share/senpi-releases/2026.7.30-2"
|
|
307
|
-
|
|
307
|
+
bun run release:local --force --out "$ARTIFACT_ROOT"
|
|
308
308
|
```
|
|
309
309
|
|
|
310
310
|
The canonical npm tarball is:
|
|
@@ -341,7 +341,7 @@ Install the verified tarball through npm without lifecycle scripts, then refresh
|
|
|
341
341
|
command cache:
|
|
342
342
|
|
|
343
343
|
```bash
|
|
344
|
-
|
|
344
|
+
bun add -g --ignore-scripts "$TARBALL"
|
|
345
345
|
hash -r
|
|
346
346
|
command -v senpi
|
|
347
347
|
senpi --version
|
|
@@ -358,7 +358,7 @@ upgrade.
|
|
|
358
358
|
Install the verified tarball:
|
|
359
359
|
|
|
360
360
|
```bash
|
|
361
|
-
|
|
361
|
+
bun add -g --ignore-scripts "$TARBALL"
|
|
362
362
|
```
|
|
363
363
|
|
|
364
364
|
Create an isolated runtime home:
|
|
@@ -437,7 +437,7 @@ Install the transferred artifact:
|
|
|
437
437
|
|
|
438
438
|
```bash
|
|
439
439
|
ssh mengmotaHost \
|
|
440
|
-
'
|
|
440
|
+
'bun add -g --ignore-scripts \
|
|
441
441
|
/tmp/senpi-2026.7.30-2/code-yeongyu-senpi-2026.7.30-2.tgz'
|
|
442
442
|
```
|
|
443
443
|
|
|
@@ -516,10 +516,10 @@ counts must match exactly on each machine.
|
|
|
516
516
|
Re-run version synchronization and lock generation:
|
|
517
517
|
|
|
518
518
|
```bash
|
|
519
|
-
|
|
520
|
-
PI_ALLOW_LOCKFILE_CHANGE=1
|
|
521
|
-
|
|
522
|
-
|
|
519
|
+
bun scripts/sync-versions.js
|
|
520
|
+
PI_ALLOW_LOCKFILE_CHANGE=1 bun install --lockfile-only --ignore-scripts
|
|
521
|
+
bun scripts/generate-coding-agent-shrinkwrap.mjs
|
|
522
|
+
bun scripts/generate-coding-agent-install-lock.mjs
|
|
523
523
|
```
|
|
524
524
|
|
|
525
525
|
Then rebuild before packaging.
|
|
@@ -567,7 +567,7 @@ configuration paths.
|
|
|
567
567
|
Run the MCP suite directly:
|
|
568
568
|
|
|
569
569
|
```bash
|
|
570
|
-
|
|
570
|
+
bunx --cwd packages/coding-agent vitest --run test/mcp/
|
|
571
571
|
```
|
|
572
572
|
|
|
573
573
|
Make only compatibility changes required by a reproduced failure. Do not add fallback logic
|
|
@@ -581,7 +581,7 @@ Rollback changes the executable package only. It does not remove or modify
|
|
|
581
581
|
Reinstall the prior published version:
|
|
582
582
|
|
|
583
583
|
```bash
|
|
584
|
-
|
|
584
|
+
bun add -g @code-yeongyu/senpi@2026.7.30
|
|
585
585
|
```
|
|
586
586
|
|
|
587
587
|
Verify rollback from an isolated home:
|
package/docs/rpc.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# RPC Mode
|
|
2
2
|
|
|
3
|
+
Shared-host clients may advertise the `rendered_components` capability to receive factory-rendered widget, header, and footer records. In a shared session, component rendering uses the minimum width reported by currently attached connections, defaulting to 80 when none report a width; disconnected connections no longer contribute.
|
|
4
|
+
|
|
3
5
|
The shared Unix socket host uses `<agentDir>/rpc-host-daemon/host.pid` and `settings.json` as its ownership state. Clients attach to a compatible existing host regardless of which client surface started it; only incompatible unmanaged owners are refused.
|
|
4
6
|
|
|
5
7
|
RPC mode enables headless operation of the coding agent via a JSON protocol over stdin/stdout. This is useful for embedding the agent in other applications, IDEs, or custom UIs.
|
|
@@ -8,6 +10,10 @@ RPC mode enables headless operation of the coding agent via a JSON protocol over
|
|
|
8
10
|
|
|
9
11
|
## Starting RPC Mode
|
|
10
12
|
|
|
13
|
+
### RPC client lifecycle
|
|
14
|
+
|
|
15
|
+
`RpcClient` accepts an `onDisconnect` callback for an established socket and rejects subsequent transport operations with the typed `RpcTransportGoneError` (also detectable with `isTransportGoneError`). Callers should use the callback to begin recovery and keep the error text out of user-facing output.
|
|
16
|
+
|
|
11
17
|
```bash
|
|
12
18
|
senpi --mode rpc [options]
|
|
13
19
|
```
|
|
@@ -43,7 +49,7 @@ Multi-session mode lets one `senpi --mode rpc` process serve several independent
|
|
|
43
49
|
# Shared JSONL over stdio (legacy multi-session host)
|
|
44
50
|
senpi --mode rpc --multi-session [options]
|
|
45
51
|
|
|
46
|
-
# One shared host over a
|
|
52
|
+
# One shared host over a local socket; each accepted connection has its own JSONL feed
|
|
47
53
|
senpi --mode rpc --listen unix:///tmp/senpi-rpc.sock [options]
|
|
48
54
|
senpi --mode rpc --listen /tmp/senpi-rpc.sock [options]
|
|
49
55
|
```
|
|
@@ -52,11 +58,27 @@ senpi --mode rpc --listen /tmp/senpi-rpc.sock [options]
|
|
|
52
58
|
`unix://@name` where supported by the host platform. Socket mode accepts concurrent connections while retaining one
|
|
53
59
|
process-global session registry.
|
|
54
60
|
|
|
61
|
+
On Windows, listeners and clients deterministically map the logical socket path to
|
|
62
|
+
`\\.\pipe\senpi-rpc-<sha256[:32]>`. Callers keep using the same `unix://` CLI value; the logical path remains the
|
|
63
|
+
ownership and settings identity, and callers never construct the pipe name themselves.
|
|
64
|
+
|
|
55
65
|
Socket event visibility is an all-sessions broadcast: every connected client receives lifecycle and agent events from
|
|
56
66
|
every open session, each tagged with its routing `sessionId`. Correlated responses and extension UI requests are sent
|
|
57
67
|
only to the connection that issued the command. This lets a non-owner observe a foreign turn without requiring a
|
|
58
68
|
separate subscription protocol.
|
|
59
69
|
|
|
70
|
+
### Client information and rendered components
|
|
71
|
+
|
|
72
|
+
Clients may send `set_client_info` with `{ sessionId, width, capabilities? }`. Advertising `rendered_components` registers
|
|
73
|
+
that connection to receive factory-rendered `setWidget`, `setHeader`, and `setFooter` records. Those records are filtered
|
|
74
|
+
per connection; array/undefined widget records and dialog requests retain their existing delivery semantics. Width is
|
|
75
|
+
shared per session using the minimum of attached clients, and a closed or dropped connection no longer contributes its
|
|
76
|
+
width or capability registration. Snapshot replay preserves rendered-component provenance and applies the same capability
|
|
77
|
+
filter to late joiners; a client that registers `rendered_components` while a snapshot is active receives its retained
|
|
78
|
+
factory-rendered records. On a shared socket host, `rendered_components` is registration-only: it is never inherited from the host environment and must be sent in `set_client_info` for each client connection. Registration applies to the sessions attached by that connection; closing one session removes only that session's width and capability association, while socket disposal removes all associations. Clients must re-register `width` and `capabilities` after every reconnect. When the last
|
|
79
|
+
capable connection leaves a still-attached binding, live component renderers and footer data providers are disposed but
|
|
80
|
+
their factories are retained; a later capable connection recreates and re-renders them.
|
|
81
|
+
|
|
60
82
|
### Session auto-titling
|
|
61
83
|
|
|
62
84
|
Auto-generated session titles are on by default only for interactive launches. RPC hosts opt in with
|
|
@@ -76,9 +98,23 @@ Startup: `senpi --mode rpc --multi-session` → NO default session is constructe
|
|
|
76
98
|
|
|
77
99
|
Interactive launches use the shared RPC host by default when a persisted session is available. A cold start takes approximately 1.3 seconds on the first launch; warm attachment to an existing compatible host is fast. To use the local runtime directly for a launch, set `SENPI_DISABLE_SHARED_HOST=1`. This uses the same local fallback runtime and does not change RPC socket behavior for other clients.
|
|
78
100
|
|
|
101
|
+
### Session replacement
|
|
102
|
+
|
|
103
|
+
A replacement (`new_session`, `switch_session`, `fork`) responds as soon as the swap is committed; the derived-surface refresh that rebinds extensions continues afterwards. That refresh does not disturb work the client starts against the committed session: tool activation performed while extensions are still binding no longer cancels an in-flight compaction or invalidates its context. `loaded_surfaces_changed` is emitted only when the surface digest actually changes, so it is NOT a settle barrier clients can wait on.
|
|
104
|
+
|
|
105
|
+
#### Replacement identity event
|
|
106
|
+
|
|
107
|
+
When `new_session`, `switch_session`, or `fork` swaps the live session - including replacements an extension drives, which a client never issued - every attached connection receives:
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
{ "type": "session_replaced", "durableSessionId": "…", "sessionFile": "…", "cwd": "…", "sessionName": "…" }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The command response reports only `{ cancelled }`, so this event is the only push channel carrying the new identity. The identity is `durableSessionId`, never `sessionId`: top-level `sessionId` is reserved for the per-connection routing handle that multi-session hosts tag every record with, and that tag is applied last, so reusing the key would overwrite the identity the event exists to deliver. Classic mode emits the event untagged.
|
|
114
|
+
|
|
79
115
|
### Shared host lifecycle (cold start + idle exit)
|
|
80
116
|
|
|
81
|
-
The lifecycle supervisor is also available to bundled/rebranded runtimes through the hidden internal launch route `--internal-rpc-host-supervisor`. This route is wire-invisible and intended only for desktop launchers: it receives the public socket, ownership directory, and the runtime command/arguments to wrap, then runs the same `host-lifecycle.ts` implementation used by `ensureHost()`. Normal CLI modes do not use or advertise this route.
|
|
117
|
+
The lifecycle supervisor is also available to bundled/rebranded runtimes through the hidden internal launch route `--internal-rpc-host-supervisor`. This route is wire-invisible and intended only for desktop launchers: it receives the public socket, ownership directory, and the runtime command/arguments to wrap, then runs the same `host-lifecycle.ts` implementation used by `ensureHost()`. Normal CLI modes do not use or advertise this route. Compiled standalone binaries also re-enter themselves through this route automatically: a bun executable always boots its embedded entrypoint, so the script-path re-entry used under a JS runtime would be parsed as CLI arguments (`Unknown option: --socket`) and the host could never start.
|
|
82
118
|
|
|
83
119
|
Hosts started through `ensureHost()` are wrapped by a lifecycle supervisor that owns the public socket and spawns the
|
|
84
120
|
real RPC host on a private internal hop. The policy lives in `<agentDir>/rpc-host-daemon/settings.json`:
|
|
@@ -108,12 +144,37 @@ internal directory. The supervisor also exports `SENPI_RPC_HOST_WATCH_PPID` as a
|
|
|
108
144
|
set only by the supervisor: a host started any other way (plain `senpi --mode rpc --listen …`, embedders, hand-started
|
|
109
145
|
hosts) sees neither variable and is unaffected. A host whose supervisor is alive is never touched by this binding.
|
|
110
146
|
|
|
147
|
+
### Shared host occupancy (idle eviction, session cap, empty-host exit)
|
|
148
|
+
|
|
149
|
+
Every open session owns a complete runtime (a lone idle session measures 340-510 MB RSS), so the host enforces three
|
|
150
|
+
occupancy bounds itself, independent of the supervisor and of client cooperation:
|
|
151
|
+
|
|
152
|
+
- **Idle eviction**: a session with no routed command and no session-owned work for
|
|
153
|
+
`SENPI_RPC_SESSION_IDLE_EVICTION_MS` (default 30 minutes) is closed through the exact `close_session` sequence
|
|
154
|
+
(abort → waitForIdle → dispose, all attachments drained, path reservation released) and every attached connection
|
|
155
|
+
receives that handle's `session_closed` broadcast plus a final `close_session` response record. "Session-owned
|
|
156
|
+
work" is the complete activity contract, not just a streaming turn: an agent run, a running bash command,
|
|
157
|
+
background terminal jobs and any other published wake source (terminal monitors, loop-guard holds), compaction,
|
|
158
|
+
and barrier-held session work all defer eviction, and the idle clock restarts when that work settles. An evicted
|
|
159
|
+
session resumes like any other: the next `open_session` with the same `sessionPath` reopens it.
|
|
160
|
+
- **Session cap**: `open_session` beyond `SENPI_RPC_MAX_SESSIONS` concurrently opening/open sessions (default 8)
|
|
161
|
+
fails with `too_many_sessions`. Attaching to an already-hosted session (`attached: true`) adds no runtime and never
|
|
162
|
+
counts against the cap, so resume and second-surface flows keep working while at it.
|
|
163
|
+
- **Empty-host exit**: when the registry holds zero sessions AND no client is connected, continuously for
|
|
164
|
+
`SENPI_RPC_HOST_EMPTY_EXIT_MS` (default 15 minutes), the host exits through its clean shutdown path (flush, socket
|
|
165
|
+
removal), for stdio and `--listen` hosts alike. A connected client counts as occupancy even with no session open,
|
|
166
|
+
so the host never drops a live socket under itself. Supervised hosts stay clean either way: a supervisor reads a
|
|
167
|
+
child exit of 0 without a signal as an intentional idle stop and exits 0 with the same cleanup, not as a crash.
|
|
168
|
+
|
|
169
|
+
Values are positive integers; invalid values fall through to the defaults. These bounds run inside the host process,
|
|
170
|
+
so they hold even for embedders and hand-started hosts that have no supervisor.
|
|
171
|
+
|
|
111
172
|
### D1 normative table (multi-session mode)
|
|
112
173
|
|
|
113
174
|
| Command | Params | Success data | Notes |
|
|
114
175
|
| --- | --- | --- | --- |
|
|
115
176
|
| `get_protocol_info` | - | `{ protocolVersion: 1, serverVersion: string, capabilities: string[], mode: "classic"\|"multi" }` | Answered in BOTH modes; side-effect-free; the capability probe. Multi-session hosts include `multi_session` plus the negotiated launch capabilities. |
|
|
116
|
-
| `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: true }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there, `session-manager.ts:926-940`); `provider`/`modelId` applied only on create (resume restores the session's model — mirrors `SenpiSessionRuntime.ts:198-200`); params form the immutable launch profile (D8). When the path is already held by a fully-open session, the open ATTACHES to it: same routing handle, `attached: true`, one more attachment counted; the runtime is torn down only when the last attachment closes. |
|
|
177
|
+
| `open_session` | `sessionPath?`, `cwd?`, `provider?`, `modelId?`, `thinkingLevel?`, `permissionPreset?` (all optional; paths MUST be absolute) | `{ sessionId, state: RpcSessionState, attached?: true }` | `sessionPath` = today's `--session` semantics (open-if-exists else create persisting there, `session-manager.ts:926-940`); `provider`/`modelId` applied only on create (resume restores the session's model — mirrors `SenpiSessionRuntime.ts:198-200`); params form the immutable launch profile (D8). When the path is already held by a fully-open session, the open ATTACHES to it: same routing handle, `attached: true`, one more attachment counted; the runtime is torn down only when the last attachment closes. Fails with `too_many_sessions` at the occupancy cap (see [Shared host occupancy](#shared-host-occupancy-idle-eviction-session-cap-empty-host-exit)); idle sessions past the eviction window are closed by the host itself. |
|
|
117
178
|
| `close_session` | `sessionId` | `{}` | Aborts active work, awaits agent idle + settled persistence, flushes queued events, detaches subscriptions; its response is the LAST record tagged with that handle — no events after (test-pinned). |
|
|
118
179
|
| `list_sessions` | - | `{ sessions: [{ sessionId, durableSessionId, sessionPath, cwd, name, status }] }` | Includes `opening`/`closing` entries with their status. |
|
|
119
180
|
| every existing command | + `sessionId` (REQUIRED in multi mode) | unchanged | Routed to that session. |
|
|
@@ -132,6 +193,7 @@ In the response `error` field, machine-matchable:
|
|
|
132
193
|
- `missing_session_id` (session-scoped command without `sessionId` in multi mode)
|
|
133
194
|
- `multi_session_disabled` (`open_session` in classic mode)
|
|
134
195
|
- `invalid_path` (relative `sessionPath`/`cwd`)
|
|
196
|
+
- `too_many_sessions` (`open_session` while `SENPI_RPC_MAX_SESSIONS` sessions are already opening/open; attaching to a live session never fails this way)
|
|
135
197
|
- `open_failed: <detail>`
|
|
136
198
|
|
|
137
199
|
### Tagging
|
|
@@ -1650,13 +1712,13 @@ Extensions can request user interaction via `ctx.ui.select()`, `ctx.ui.confirm()
|
|
|
1650
1712
|
There are two categories of extension UI methods:
|
|
1651
1713
|
|
|
1652
1714
|
- **Dialog methods** (`select`, `confirm`, `input`, `editor`): emit an `extension_ui_request` on stdout and block until the client sends back an `extension_ui_response` on stdin with the matching `id`.
|
|
1653
|
-
- **Fire-and-forget methods** (`notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`): emit an `extension_ui_request` on stdout but do not expect a response. The client can display the information or ignore it.
|
|
1715
|
+
- **Fire-and-forget methods** (`notify`, `setStatus`, `setWidget`, `setHeader`, `setFooter`, `setTitle`, `set_editor_text`): emit an `extension_ui_request` on stdout but do not expect a response. The client can display the information or ignore it.
|
|
1654
1716
|
|
|
1655
1717
|
If a dialog method includes a `timeout` field, the agent-side will auto-resolve with a default value when the timeout expires. The client does not need to track timeouts.
|
|
1656
1718
|
|
|
1657
1719
|
Some `ExtensionUIContext` methods are not supported or degraded in RPC mode because they require direct TUI access:
|
|
1658
1720
|
- `custom()` returns `undefined`
|
|
1659
|
-
- `setWorkingMessage()`, `setWorkingIndicator()`, `
|
|
1721
|
+
- `setWorkingMessage()`, `setWorkingIndicator()`, `setEditorComponent()`, `setToolsExpanded()` are no-ops. `setFooter()` and `setHeader()` render factory components for clients advertising `rendered_components`.
|
|
1660
1722
|
- `getEditorText()` returns `""`
|
|
1661
1723
|
- `getToolsExpanded()` returns `false`
|
|
1662
1724
|
- `pasteToEditor()` delegates to `setEditorText()` (no paste/collapse handling)
|
|
@@ -1783,7 +1845,22 @@ Set or clear a widget (block of text lines) displayed above or below the editor.
|
|
|
1783
1845
|
}
|
|
1784
1846
|
```
|
|
1785
1847
|
|
|
1786
|
-
Send `widgetLines: undefined` (or omit it) to clear the widget. The `widgetPlacement` field is `"aboveEditor"` (default) or `"belowEditor"`.
|
|
1848
|
+
Send `widgetLines: undefined` (or omit it) to clear the widget. The `widgetPlacement` field is `"aboveEditor"` (default) or `"belowEditor"`. Component factories are rendered by the host using the attached client's terminal width.
|
|
1849
|
+
|
|
1850
|
+
#### setHeader / setFooter
|
|
1851
|
+
|
|
1852
|
+
Set or clear the extension header or footer using rendered text lines. Clients that do not understand these additive methods ignore them.
|
|
1853
|
+
|
|
1854
|
+
```json
|
|
1855
|
+
{
|
|
1856
|
+
"type": "extension_ui_request",
|
|
1857
|
+
"id": "uuid-10",
|
|
1858
|
+
"method": "setHeader",
|
|
1859
|
+
"widgetLines": ["Header line"]
|
|
1860
|
+
}
|
|
1861
|
+
```
|
|
1862
|
+
|
|
1863
|
+
Omit `widgetLines` to restore the built-in surface. Attached clients send `set_client_info` with their terminal width after attach and on resize; hosts default to width 80 when no width is supplied.
|
|
1787
1864
|
|
|
1788
1865
|
#### setTitle
|
|
1789
1866
|
|
package/docs/sdk.md
CHANGED
|
@@ -36,7 +36,7 @@ await session.prompt("What files are in the current directory?");
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
|
|
39
|
+
bun add @earendil-works/pi-coding-agent
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
The SDK is included in the main package. No separate installation needed.
|