@co0ontty/wand 4.106.0 → 4.106.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/ai-text-runner.js +24 -14
- package/dist/build-info.d.ts +2 -0
- package/dist/build-info.js +18 -0
- package/dist/build-info.json +3 -3
- package/dist/cli.js +8 -2
- package/dist/daemon-maintenance-state.js +1 -1
- package/dist/daemon-maintenance-targets.d.ts +1 -0
- package/dist/daemon-maintenance-targets.js +25 -9
- package/dist/daemon-maintenance.d.ts +3 -0
- package/dist/daemon-maintenance.js +60 -13
- package/dist/employee-im-types.d.ts +1 -1
- package/dist/employee-input-scheduling.d.ts +4 -0
- package/dist/employee-knowledge-cli.js +5 -5
- package/dist/employee-knowledge.d.ts +3 -1
- package/dist/employee-knowledge.js +24 -8
- package/dist/git-quick-commit.d.ts +2 -0
- package/dist/git-quick-commit.js +15 -2
- package/dist/git-worktree-batch.d.ts +26 -0
- package/dist/git-worktree-batch.js +139 -0
- package/dist/global-knowledge.d.ts +12 -0
- package/dist/global-knowledge.js +124 -0
- package/dist/iteration-log.d.ts +13 -5
- package/dist/iteration-log.js +120 -59
- package/dist/knowledge-types.d.ts +12 -1
- package/dist/knowledge-types.js +4 -0
- package/dist/middleware/api-scope.js +1 -0
- package/dist/model-groups.js +6 -3
- package/dist/models/parsers/opencode.js +31 -1
- package/dist/models.js +15 -14
- package/dist/npm-update-utils.d.ts +5 -2
- package/dist/npm-update-utils.js +34 -4
- package/dist/opencode-cli.d.ts +6 -0
- package/dist/opencode-cli.js +51 -0
- package/dist/opencode-system-fallback.d.ts +1 -0
- package/dist/opencode-system-fallback.js +16 -4
- package/dist/pi-native-event-bridge.js +55 -3
- package/dist/pi-native-input.d.ts +22 -0
- package/dist/pi-native-input.js +77 -0
- package/dist/pi-tmux-host.d.ts +14 -5
- package/dist/pi-tmux-host.js +68 -17
- package/dist/process-manager.js +17 -3
- package/dist/pty-tmux-backend.d.ts +27 -2
- package/dist/pty-tmux-backend.js +471 -70
- package/dist/pty-tmux-log.d.ts +1 -1
- package/dist/pty-tmux-log.js +23 -2
- package/dist/retention-protection.d.ts +1 -1
- package/dist/retention-protection.js +3 -2
- package/dist/retention.d.ts +5 -0
- package/dist/retention.js +11 -0
- package/dist/server-knowledge-routes.js +2 -2
- package/dist/server-session-input-routes.js +38 -19
- package/dist/server-session-lifecycle-routes.js +14 -1
- package/dist/server-session-worktree-routes.js +105 -12
- package/dist/server-task-routes.js +41 -12
- package/dist/server-workspace-routes.js +77 -9
- package/dist/server.js +67 -35
- package/dist/session-registry.d.ts +17 -3
- package/dist/session-registry.js +66 -13
- package/dist/session-service.js +1 -1
- package/dist/storage/internal.d.ts +4 -3
- package/dist/storage/internal.js +3 -3
- package/dist/storage/knowledge-repository.d.ts +5 -0
- package/dist/storage/knowledge-repository.js +75 -16
- package/dist/storage/mappers.d.ts +1 -0
- package/dist/storage/mappers.js +6 -1
- package/dist/storage/migrations.js +60 -0
- package/dist/storage/session-input-repository.d.ts +19 -0
- package/dist/storage/session-input-repository.js +35 -0
- package/dist/storage/task-workflow-repository.d.ts +29 -0
- package/dist/storage/task-workflow-repository.js +110 -0
- package/dist/storage/tasks-repository.d.ts +6 -1
- package/dist/storage/tasks-repository.js +94 -34
- package/dist/storage/workspaces-repository.d.ts +7 -0
- package/dist/storage/workspaces-repository.js +28 -2
- package/dist/storage-cleanup.d.ts +7 -2
- package/dist/storage-cleanup.js +16 -0
- package/dist/storage-schema.js +2 -0
- package/dist/storage.d.ts +5 -1
- package/dist/storage.js +12 -0
- package/dist/structured-exec-host.d.ts +4 -0
- package/dist/structured-exec-pump.d.ts +1 -0
- package/dist/structured-exec-pump.js +18 -11
- package/dist/structured-opencode-adapter.d.ts +2 -1
- package/dist/structured-opencode-adapter.js +32 -8
- package/dist/structured-pi-adapter.js +13 -2
- package/dist/structured-runner.d.ts +6 -0
- package/dist/structured-session-manager-replay.d.ts +2 -0
- package/dist/structured-session-manager-replay.js +27 -0
- package/dist/structured-session-manager.d.ts +32 -21
- package/dist/structured-session-manager.js +395 -118
- package/dist/structured-tmux-host.d.ts +23 -2
- package/dist/structured-tmux-host.js +143 -20
- package/dist/task-actions.js +5 -3
- package/dist/task-archive-policy.js +2 -1
- package/dist/task-comment-dispatch.d.ts +2 -1
- package/dist/task-comment-dispatch.js +19 -6
- package/dist/task-execution-queue.d.ts +2 -0
- package/dist/task-execution-queue.js +10 -10
- package/dist/task-hierarchy.js +1 -1
- package/dist/task-read-model.d.ts +1 -1
- package/dist/task-read-model.js +2 -1
- package/dist/task-types.d.ts +34 -3
- package/dist/task-types.js +21 -5
- package/dist/task-workflow-cli.d.ts +2 -0
- package/dist/task-workflow-cli.js +29 -0
- package/dist/task-workflow-runner.d.ts +4 -0
- package/dist/task-workflow-runner.js +36 -0
- package/dist/task-workflow.d.ts +13 -0
- package/dist/task-workflow.js +48 -0
- package/dist/terminal-daemon-server.js +12 -4
- package/dist/tmux-policy.d.ts +9 -0
- package/dist/tmux-policy.js +46 -0
- package/dist/tmux-terminal-host.js +5 -2
- package/dist/tui/commands.js +2 -1
- package/dist/types.d.ts +5 -0
- package/dist/wand-task-sync.js +5 -0
- package/dist/web-ui/content/ai-teams.js +9 -9
- package/dist/web-ui/content/module-manifest.json +1 -1
- package/dist/web-ui/content/modules/{52574891ef08e29b → 014fa5c6f973badf}/host.js +3 -3
- package/dist/web-ui/content/modules/0818b1d31a11d006/employee-profile.js +1 -0
- package/dist/web-ui/content/modules/{31157ceb6d23b809 → 0a58d9ec273078e4}/chunk.js +3 -3
- package/dist/web-ui/content/modules/{bf3ee58e0da44822 → 0a979dcd165cd0cc}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{5f298a8f43dd0589 → 0c143928e8f96abc}/chunk.js +1 -1
- package/dist/web-ui/content/modules/0e9e42a319f6b8fc/workspace-window.js +1 -0
- package/dist/web-ui/content/modules/{b713cad51ca4c512 → 0f0d1769b732c0bd}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{4970319a83432ec7 → 1447886e6a1e74a4}/chunk.js +1 -1
- package/dist/web-ui/content/modules/151c734cbca31da5/host.js +1 -0
- package/dist/web-ui/content/modules/{e5174201f9d918fb → 16e4ab9c5263fcfd}/chunk.js +1 -1
- package/dist/web-ui/content/modules/17e752fb53952753/host.js +1 -0
- package/dist/web-ui/content/modules/{913187c92a98a1ac → 20ed1454fc09fa6f}/chunk.js +1 -1
- package/dist/web-ui/content/modules/255a3baf59d2b734/home.js +6 -0
- package/dist/web-ui/content/modules/{2f801e53dda62770 → 296dd81886c42b45}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{8891ca8165435ca1 → 2a01f4e525c0725e}/chunk.js +1 -1
- package/dist/web-ui/content/modules/2ab4409c82b44fba/markdown.js +1 -0
- package/dist/web-ui/content/modules/2c955eced11610c2/chunk.js +1 -0
- package/dist/web-ui/content/modules/2d7ee4f9e2c0aca4/panel.js +1 -0
- package/dist/web-ui/content/modules/{3f8830f8ad28decc → 33ae550e4a295c85}/chunk.js +1 -1
- package/dist/web-ui/content/modules/35f4aa4443696bd0/chunk.js +1 -0
- package/dist/web-ui/content/modules/388b37ffcce9d4ff/host.js +1 -0
- package/dist/web-ui/content/modules/39279604dcdac7c7/runtime.js +338 -0
- package/dist/web-ui/content/modules/{57c357d321db5df9 → 3a3cdff2a662b7d3}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{d49f106c4d106057 → 3ab646be55514243}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{16dab1297efd71a7 → 3ae88a5c5e1949d2}/chunk.js +1 -1
- package/dist/web-ui/content/modules/3e3b0e71d6ce80d8/chunk.js +1 -0
- package/dist/web-ui/content/modules/{ec33e17c00c1eb24 → 434aaaaf9604dc34}/chunk.js +1 -1
- package/dist/web-ui/content/modules/4385cd48771e1d4f/host.js +1 -0
- package/dist/web-ui/content/modules/{face3dbf117d63e3 → 4638129d60f549a0}/chunk.js +1 -1
- package/dist/web-ui/content/modules/47407209931b7011/host.js +13 -0
- package/dist/web-ui/content/modules/4829dd712d8b366b/chunk.js +1 -0
- package/dist/web-ui/content/modules/488d5b747bf374c8/chunk.js +1 -0
- package/dist/web-ui/content/modules/{ed7405f064944215 → 4ab085c195f7d76a}/sha256.js +1 -1
- package/dist/web-ui/content/modules/{f27a5d3c6c02a71c → 4c485bd44740fec7}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{771439a41e737ee2 → 4ca0494308ab2bb3}/chunk.js +1 -1
- package/dist/web-ui/content/modules/4ec571218779ba3e/composer-surface-adapter.js +1 -0
- package/dist/web-ui/content/modules/{5933ce8965aa4004 → 5023bf0294c2e7cb}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{e63582a3bce48f7d → 5456e3417600bf15}/chunk.js +1 -1
- package/dist/web-ui/content/modules/55c588b0f5b41a52/host-bridge.js +1 -0
- package/dist/web-ui/content/modules/{9d941d6ff39861b8 → 5c3c8237ba7d8460}/chunk.js +1 -1
- package/dist/web-ui/content/modules/624b858da9834757/host.js +1 -0
- package/dist/web-ui/content/modules/6290be936320d4b1/host.js +1 -0
- package/dist/web-ui/content/modules/66be408793048cc3/progress.js +1 -0
- package/dist/web-ui/content/modules/67a11176a563317b/chunk.js +1 -0
- package/dist/web-ui/content/modules/{e060508ecd50fa7e → 68ef6ec7d26d78cd}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{41445c6589dba325 → 6ec3e41df31927d9}/host.js +2 -2
- package/dist/web-ui/content/modules/{97d7f267959fd385 → 6f10f369445bbcbe}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{d47d75a78ae598e3 → 7295d9ff92d5e1e7}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{f383d892fef73483 → 72cd613de1a5f69b}/chunk.js +1 -1
- package/dist/web-ui/content/modules/73aae1daafeea7e7/workspaces-panel.js +4 -0
- package/dist/web-ui/content/modules/{c2f09c8a472f5d83 → 73d2689f13b9a3e9}/dialog-modal.js +1 -1
- package/dist/web-ui/content/modules/{2f97ddba3842adaa → 75cf0c048e9b92ab}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{4ba1e8c74bed7ef2 → 75dabda3b141296e}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{f3cff7792ba39df8 → 76c10b58d5f92d02}/login-visual.js +1 -1
- package/dist/web-ui/content/modules/{b63e075f222a1266 → 783583a12f5010f8}/library-bridge.js +1 -1
- package/dist/web-ui/content/modules/7e13a8a4a981f2f1/group-editor.js +1 -0
- package/dist/web-ui/content/modules/{0d76e582a7a71b2f → 7e3034fea34c6dae}/chunk.js +1 -1
- package/dist/web-ui/content/modules/80bf3291f2577a68/host.js +1 -0
- package/dist/web-ui/content/modules/{cba6f13c0b2aec1c → 82c3e08f34a6b828}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{dedd4a19bb70e327 → 83d1f4cf82c65f19}/page.js +3 -3
- package/dist/web-ui/content/modules/844f97958f25240c/shell-file-panel-drawer.js +1 -0
- package/dist/web-ui/content/modules/{62e0023451f428cf → 899cdc467044d418}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{5083a5dbb5b155b7 → 8c7ca1fe72741c07}/chunk.js +1 -1
- package/dist/web-ui/content/modules/8dae4ca2261525e4/task-board-host.js +27 -0
- package/dist/web-ui/content/modules/92195c14c74929da/list-filter-panel.js +1 -0
- package/dist/web-ui/content/modules/{a61393bfa976d8d5 → 93793696af76bcbf}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{db521a246e14e5e4 → 97cd6af3da5622b8}/chunk.js +4 -4
- package/dist/web-ui/content/modules/{8de8368570ab089d → 9d3179258249ec77}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{579d486763d47c0d → a234c484078c0568}/chunk.js +1 -1
- package/dist/web-ui/content/modules/a4d215448a089a7d/host.js +1 -0
- package/dist/web-ui/content/modules/{c0a446100d969f3e → ae003f89901c5687}/chunk.js +1 -1
- package/dist/web-ui/content/modules/ae712bdd45b9917e/employee-card.js +1 -0
- package/dist/web-ui/content/modules/{a2caed0139df4b21 → b2a15293f7965d09}/chunk.js +1 -1
- package/dist/web-ui/content/modules/b4ee65e9998f0088/host.js +61 -0
- package/dist/web-ui/content/modules/{bd3daf04a8bf4422 → b666137d17f83be9}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{831b6c7b43e800be → b66beb6c0185256b}/host.js +1 -1
- package/dist/web-ui/content/modules/{816eb9b3a000fb2c → bb03b17e877657de}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{1eab7410d5586038 → bc343afc991db1a1}/chunk.js +1 -1
- package/dist/web-ui/content/modules/bca45976ff8fe2ac/host.js +69 -0
- package/dist/web-ui/content/modules/{d434edbb2f4672e5 → c2715dbfc9eaf510}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{d6fffe2c2a3a738d → c30c220281f35d74}/toast-region.js +1 -1
- package/dist/web-ui/content/modules/c4cc46fa9b4adddc/dropdown-surface.js +1 -0
- package/dist/web-ui/content/modules/c6dd19ee3d3ffd59/brand-identity.js +1 -0
- package/dist/web-ui/content/modules/c7ea6a114e6ff8ae/host.js +1 -0
- package/dist/web-ui/content/modules/{a59734be368daa7e → c916d82c8acef9c8}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{182929e188c1ab3a → cceaedda619a737a}/host.js +1 -1
- package/dist/web-ui/content/modules/cf67f52b076b9d2d/panel-host.js +1 -0
- package/dist/web-ui/content/modules/{9e163d54ff8fd1aa → d26c86558d422313}/chunk.js +1 -1
- package/dist/web-ui/content/modules/d2b8c6c6f3706032/queue-view-adapter.js +1 -0
- package/dist/web-ui/content/modules/d52ebe2ef12a9fa8/chunk.js +3 -0
- package/dist/web-ui/content/modules/{3fe11a75284ad8ae → d552b3bff2151eb6}/host.js +2 -2
- package/dist/web-ui/content/modules/d5d6b4511ac76a6e/chunk.js +3 -0
- package/dist/web-ui/content/modules/{bd7dc4bb46731ee7 → df42e151d625463b}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{2a791cd2e14aa1e0 → e0a04f5ae56c68aa}/notice-view.js +1 -1
- package/dist/web-ui/content/modules/{438807b8bf112cd0 → e28e607c95d6f63a}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{50da446c1377c220 → e3880df97ea62d0c}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{87c7f50d9455d55e → e66196f1ece3e3ad}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{9b12c2301f3a18f3 → eb76307444ac9d71}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{c33935155289c22d → ebff7ca22cee1468}/chunk.js +1 -1
- package/dist/web-ui/content/modules/{4861eca9a8a87ad0 → ed1c712c569960d6}/chunk.js +1 -1
- package/dist/web-ui/content/modules/ee8b9c2d4bec63d4/chunk.js +1 -0
- package/dist/web-ui/content/modules/f458a194ce4208e2/chunk.js +1 -0
- package/dist/web-ui/content/modules/{11af5d14b30e57b6 → f938e826420cfe1b}/chunk.js +1 -1
- package/dist/web-ui/content/modules/fa7b9bf6cc84bfc1/chat-render.js +81 -0
- package/dist/web-ui/content/modules/{ea8fe4b9999fd2aa → fd1fb1834f5f06df}/chunk.js +1 -1
- package/dist/web-ui/content/modules/fd3084e562a3dbd6/host.js +1 -0
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/embedded-assets.d.ts +416 -413
- package/dist/web-ui/embedded-assets.js +5 -5
- package/dist/web-ui/page-route.js +2 -2
- package/dist/web-ui/react/workspaces/types.d.ts +3 -0
- package/dist/web-ui/thinking-efforts.d.ts +2 -0
- package/dist/web-ui/thinking-efforts.js +8 -0
- package/package.json +1 -2
- package/scripts/stage-render-binaries.js +0 -1
- package/skills/wand-knowledge/SKILL.md +5 -3
- package/dist/structured-bounded-keys.d.ts +0 -19
- package/dist/structured-bounded-keys.js +0 -47
- package/dist/web-ui/content/modules/00b168a19664439e/dropdown-surface.js +0 -1
- package/dist/web-ui/content/modules/059c5fb7f128d340/task-board-host.js +0 -27
- package/dist/web-ui/content/modules/07494f5a623e4471/chat-render.js +0 -76
- package/dist/web-ui/content/modules/0a743ad3b4db6874/chunk.js +0 -3
- package/dist/web-ui/content/modules/1858670c0f84fec5/employee-profile.js +0 -1
- package/dist/web-ui/content/modules/20c47dc0442f5a04/host.js +0 -1
- package/dist/web-ui/content/modules/226241b999d12008/host.js +0 -1
- package/dist/web-ui/content/modules/23c4b8d223ec64c5/host.js +0 -61
- package/dist/web-ui/content/modules/2882c97388ff4f7b/employee-card.js +0 -1
- package/dist/web-ui/content/modules/2c90c3be260e6cce/progress.js +0 -1
- package/dist/web-ui/content/modules/2d7be9935394f397/workspace-window.js +0 -1
- package/dist/web-ui/content/modules/389a5112332ec23a/host.js +0 -1
- package/dist/web-ui/content/modules/3ea13e8b3c2deaa4/panel-host.js +0 -1
- package/dist/web-ui/content/modules/42e5c34002fcffb7/chunk.js +0 -1
- package/dist/web-ui/content/modules/4a5d669c90f545cb/host.js +0 -1
- package/dist/web-ui/content/modules/5705d25468274534/host.js +0 -1
- package/dist/web-ui/content/modules/5961ab2947c86ca1/shell-file-panel-drawer.js +0 -1
- package/dist/web-ui/content/modules/5b6e1369df7dea69/chunk.js +0 -1
- package/dist/web-ui/content/modules/6787bdcf56f743a5/host.js +0 -1
- package/dist/web-ui/content/modules/67c39b0398186a9f/host.js +0 -1
- package/dist/web-ui/content/modules/6b16f35c0627bafb/chunk.js +0 -1
- package/dist/web-ui/content/modules/6dd4f3e2f619f7a0/chunk.js +0 -1
- package/dist/web-ui/content/modules/70a2e13e0ccc8549/panel.js +0 -1
- package/dist/web-ui/content/modules/710db590e9707f73/runtime.js +0 -338
- package/dist/web-ui/content/modules/7249950f8771dbeb/workspaces-panel.js +0 -4
- package/dist/web-ui/content/modules/87dcd516ffd9f688/composer-surface-adapter.js +0 -1
- package/dist/web-ui/content/modules/8b7cd7bffdfd69e7/brand-identity.js +0 -1
- package/dist/web-ui/content/modules/8bf9917f6c3429f6/host.js +0 -1
- package/dist/web-ui/content/modules/8e612d4881fa4118/home.js +0 -6
- package/dist/web-ui/content/modules/8e6178262ea63dec/markdown.js +0 -1
- package/dist/web-ui/content/modules/96f2ae970f8c576b/host.js +0 -1
- package/dist/web-ui/content/modules/ba89cd97627e6682/queue-view-adapter.js +0 -1
- package/dist/web-ui/content/modules/c351eb11e0bdec2c/sidebar-peek.js +0 -1
- package/dist/web-ui/content/modules/ca7ca5902a35d26e/chunk.js +0 -1
- package/dist/web-ui/content/modules/d5d28ec375826ef2/chunk.js +0 -3
- package/dist/web-ui/content/modules/d6b16dedb9011c33/chunk.js +0 -1
- package/dist/web-ui/content/modules/d8a7011760f61719/group-editor.js +0 -1
- package/dist/web-ui/content/modules/d9e2b65e9679ad39/host.js +0 -75
- package/dist/web-ui/content/modules/eac72f69716dba05/chunk.js +0 -1
- package/dist/web-ui/content/modules/ebc53dedc3945514/host.js +0 -1
- package/dist/web-ui/content/modules/f43da7050badf54c/host.js +0 -1
- package/dist/web-ui/content/modules/fb2356eced24c4cc/host-bridge.js +0 -1
package/dist/pi-tmux-host.js
CHANGED
|
@@ -6,10 +6,11 @@ import path from "node:path";
|
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
|
-
import { buildChildEnv } from "./env-utils.js";
|
|
9
|
+
import { buildChildEnv, systemEnvValue } from "./env-utils.js";
|
|
10
10
|
import { shellQuote } from "./shell-quote.js";
|
|
11
11
|
import { logInfo } from "./runtime-log.js";
|
|
12
12
|
import { signalNumberFromName } from "./signal-utils.js";
|
|
13
|
+
import { offerNativeInput, resolveNativeInput } from "./pi-native-input.js";
|
|
13
14
|
import { createUtf8TextDecoder } from "./structured-exec-host.js";
|
|
14
15
|
const execute = promisify(execFile);
|
|
15
16
|
const REPLAY_BYTES = 8 * 1024 * 1024;
|
|
@@ -164,7 +165,9 @@ export class PiTmuxHost {
|
|
|
164
165
|
}
|
|
165
166
|
}
|
|
166
167
|
async tmux(args) {
|
|
167
|
-
const result = await execute("tmux",
|
|
168
|
+
const result = await execute("tmux", ["-L", "default", ...args], {
|
|
169
|
+
env: buildChildEnv(false, { TMUX_TMPDIR: systemEnvValue("TMUX_TMPDIR") }), timeout: 10000, maxBuffer: 1024 * 1024,
|
|
170
|
+
});
|
|
168
171
|
return result.stdout;
|
|
169
172
|
}
|
|
170
173
|
state(job) {
|
|
@@ -264,12 +267,13 @@ export class PiTmuxHost {
|
|
|
264
267
|
const sid = request.runId.replace(/^structured:/, "").replace(/[^a-zA-Z0-9-]/g, "-");
|
|
265
268
|
const job = { runId: request.runId, requestId: request.requestId ?? incarnationId, incarnationId,
|
|
266
269
|
tmux: this.prefix + sid + "-" + incarnationId.slice(0, 8), events: path.join(dir, "events.jsonl"), stderr: path.join(dir, "stderr.log"),
|
|
267
|
-
state: path.join(dir, "state.json"), ready: path.join(dir, "ready.json"), ack: path.join(dir, "ack") };
|
|
270
|
+
state: path.join(dir, "state.json"), ready: path.join(dir, "ready.json"), ack: path.join(dir, "ack"), input: path.join(dir, "input") };
|
|
271
|
+
mkdirSync(job.input, { mode: 0o700 });
|
|
268
272
|
for (const file of [job.events, job.stderr])
|
|
269
273
|
writeFileSync(file, "", { mode: 0o600 });
|
|
270
274
|
atomic(job.state, { status: "starting", pid: -1, exitCode: null, signal: null });
|
|
271
275
|
const paths = path.join(dir, "paths.json");
|
|
272
|
-
atomic(paths, { events: job.events, ready: job.ready });
|
|
276
|
+
atomic(paths, { events: job.events, ready: job.ready, input: job.input, initialMessageId: request.nativeInputMessageId });
|
|
273
277
|
const launchDir = mkdtempSync(path.join(os.tmpdir(), "wand-pi-launch-"));
|
|
274
278
|
const socket = path.join(launchDir, "start.sock");
|
|
275
279
|
let handedOff = false;
|
|
@@ -298,7 +302,7 @@ export class PiTmuxHost {
|
|
|
298
302
|
try {
|
|
299
303
|
let exists = false;
|
|
300
304
|
try {
|
|
301
|
-
await this.tmux(["has-session", "-t", job.tmux]);
|
|
305
|
+
await this.tmux(["has-session", "-t", `=${job.tmux}`]);
|
|
302
306
|
exists = true;
|
|
303
307
|
}
|
|
304
308
|
catch { /* a new owned session */ }
|
|
@@ -306,11 +310,13 @@ export class PiTmuxHost {
|
|
|
306
310
|
throw new Error("tmux 名称已被其他会话使用,未接管或停止它。");
|
|
307
311
|
}
|
|
308
312
|
else {
|
|
309
|
-
await this.tmux(["new-session", "-d", "-s", job.tmux, "-x", "120", "-y", "36", "-c", request.cwd, command]);
|
|
313
|
+
job.pane = (await this.tmux(["new-session", "-d", "-P", "-F", "#{pane_id}", "-s", job.tmux, "-x", "120", "-y", "36", "-c", request.cwd, command])).trim();
|
|
314
|
+
if (!/^%\d+$/.test(job.pane))
|
|
315
|
+
throw new Error("Pi tmux pane identity is unavailable");
|
|
310
316
|
await this.tmux(["set-option", "-t", job.tmux, "@wand-native-owner", request.runId]);
|
|
311
|
-
await this.tmux(["set-window-option", "-t",
|
|
317
|
+
await this.tmux(["set-window-option", "-t", job.pane, "remain-on-exit", "off"]);
|
|
312
318
|
}
|
|
313
|
-
const workerPid = Number((await this.tmux(["
|
|
319
|
+
const workerPid = Number((await this.tmux(["display-message", "-p", "-t", job.pane, "#{pane_pid}"])).trim());
|
|
314
320
|
atomic(job.state, { status: "starting", pid: workerPid, workerPid, exitCode: null, signal: null });
|
|
315
321
|
if (request.launchSignal?.aborted)
|
|
316
322
|
throw new Error("Pi 原生启动已取消,未发送输入。");
|
|
@@ -347,6 +353,43 @@ export class PiTmuxHost {
|
|
|
347
353
|
rmSync(launchDir, { recursive: true, force: true });
|
|
348
354
|
}
|
|
349
355
|
}
|
|
356
|
+
offerPiInput(runId, boundaryId, take) {
|
|
357
|
+
const job = this.job(runId);
|
|
358
|
+
if (!job?.input || existsSync(job.ack) || this.state(job).status !== "running")
|
|
359
|
+
return false;
|
|
360
|
+
return offerNativeInput(job.input, boundaryId, job.incarnationId, take);
|
|
361
|
+
}
|
|
362
|
+
resolvePiInput(runId, handoff) {
|
|
363
|
+
const job = this.job(runId);
|
|
364
|
+
if (!job?.input || job.incarnationId !== handoff.incarnationId)
|
|
365
|
+
return { state: "unknown" };
|
|
366
|
+
const exited = this.state(job).status === "exited";
|
|
367
|
+
const resolution = resolveNativeInput(job.input, handoff, exited);
|
|
368
|
+
if (resolution.state !== "unknown" || !exited)
|
|
369
|
+
return resolution;
|
|
370
|
+
// The CLI may exit after committing its boundary but before the next event.
|
|
371
|
+
// Resolve only an exact native entry id from that execution's private session.
|
|
372
|
+
const ready = readJson(job.ready);
|
|
373
|
+
if (!ready?.sessionFile)
|
|
374
|
+
return resolution;
|
|
375
|
+
try {
|
|
376
|
+
const stat = lstatSync(ready.sessionFile);
|
|
377
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > REPLAY_BYTES * 8)
|
|
378
|
+
return resolution;
|
|
379
|
+
const records = readFileSync(ready.sessionFile, "utf8").split("\n");
|
|
380
|
+
for (const line of records) {
|
|
381
|
+
if (!line.trim())
|
|
382
|
+
continue;
|
|
383
|
+
const entry = JSON.parse(line);
|
|
384
|
+
if (entry.type === "custom_message" && entry.customType === "wand-user-input"
|
|
385
|
+
&& entry.details?.inputId === handoff.id && typeof entry.content === "string") {
|
|
386
|
+
return { state: "committed", offer: { ...handoff, text: entry.content } };
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
catch { /* Missing or invalid native history remains unknown, never a replay permission. */ }
|
|
391
|
+
return resolution;
|
|
392
|
+
}
|
|
350
393
|
async attachRun(runId, checkpoint) {
|
|
351
394
|
const job = this.job(runId);
|
|
352
395
|
if (job && !existsSync(job.ack)) {
|
|
@@ -396,9 +439,13 @@ export class PiTmuxHost {
|
|
|
396
439
|
const stopping = (async () => {
|
|
397
440
|
let tag;
|
|
398
441
|
try {
|
|
399
|
-
const
|
|
400
|
-
|
|
442
|
+
const panes = (await this.tmux(["list-panes", "-t", `=${job.tmux}`, "-F", "#{session_name}\t#{pane_id}\t#{pane_pid}"])).trim().split("\n");
|
|
443
|
+
const identity = job.pane ? panes.find(line => line.split("\t")[1] === job.pane) : panes[0];
|
|
444
|
+
if (!identity || identity.split("\t")[0] !== job.tmux)
|
|
401
445
|
throw new Error("Pi tmux 精确目标不匹配,拒绝停止。");
|
|
446
|
+
const workerPid = this.state(job).workerPid;
|
|
447
|
+
if (workerPid && Number(identity.split("\t")[2]) !== workerPid)
|
|
448
|
+
throw new Error("Pi tmux pane generation changed");
|
|
402
449
|
tag = (await this.tmux(["show-options", "-v", "-t", job.tmux, "@wand-native-owner"])).trim();
|
|
403
450
|
}
|
|
404
451
|
catch (error) {
|
|
@@ -408,7 +455,7 @@ export class PiTmuxHost {
|
|
|
408
455
|
}
|
|
409
456
|
if (tag !== job.runId)
|
|
410
457
|
throw new Error("Pi tmux 所有权不匹配,拒绝停止。");
|
|
411
|
-
await this.tmux(["kill-session", "-t", job.tmux]);
|
|
458
|
+
await this.tmux(["kill-session", "-t", `=${job.tmux}`]);
|
|
412
459
|
})();
|
|
413
460
|
this.terminations.set(job.incarnationId, stopping);
|
|
414
461
|
void stopping.catch(() => this.terminations.delete(job.incarnationId));
|
|
@@ -445,14 +492,17 @@ export class PiTmuxHost {
|
|
|
445
492
|
* 而 forgetRun 只写 ack 标记、从不删目录,所以会按回合数无限堆积。
|
|
446
493
|
*
|
|
447
494
|
* 只回收三类确定无主的东西:
|
|
448
|
-
* - slot 已 ack 且 runId
|
|
495
|
+
* - slot 已 ack 且 runId 不在 activeSessionIds 里:整个 slot 无主;
|
|
449
496
|
* - slot 无主的,整槽删除;
|
|
450
497
|
* - slot 仍有主的,只删非 current.json 引用、已 ack 且进程已退出、超保留期的 turn。
|
|
451
498
|
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
499
|
+
* activeSessionIds 只含未归档会话。归档后不再续接这些 turn,已 ack 且进程退出
|
|
500
|
+
* 就可以整槽删除,不再额外等保留期;取消归档从会话自己的消息快照恢复。
|
|
501
|
+
* 保留未归档会话 current.json 指向的 turn:`listRuns` / `adoptRun` 仍靠它的
|
|
502
|
+
* events.jsonl 重放恢复;未 ack 的 slot 可能是尚未收尾的回合,一律不动。
|
|
454
503
|
*/
|
|
455
504
|
collectGarbage(options) {
|
|
505
|
+
const activeSessionIds = options.activeSessionIds ?? options.liveSessionIds;
|
|
456
506
|
const report = { removedSlots: 0, removedTurns: 0, freedBytes: 0 };
|
|
457
507
|
const now = options.now ?? Date.now();
|
|
458
508
|
let entries;
|
|
@@ -471,12 +521,13 @@ export class PiTmuxHost {
|
|
|
471
521
|
continue;
|
|
472
522
|
const acked = existsSync(job.ack);
|
|
473
523
|
const sessionId = job.runId.replace(/^structured:/, "");
|
|
474
|
-
const orphan = !
|
|
524
|
+
const orphan = !activeSessionIds.has(sessionId);
|
|
475
525
|
if (orphan) {
|
|
476
526
|
// 无主 slot 也得等 ack 完成:未 ack 说明回合可能还在收尾。
|
|
527
|
+
// 已删除和已归档都不再续接,进程退出后不再额外等保留期。
|
|
477
528
|
if (!acked)
|
|
478
529
|
continue;
|
|
479
|
-
if (!this.slotIsIdle(slot, job, now,
|
|
530
|
+
if (!this.slotIsIdle(slot, job, now, 0))
|
|
480
531
|
continue;
|
|
481
532
|
report.freedBytes += directoryBytes(slot);
|
|
482
533
|
if (removeTree(slot))
|
|
@@ -533,7 +584,7 @@ export class PiTmuxHost {
|
|
|
533
584
|
return null;
|
|
534
585
|
}
|
|
535
586
|
}
|
|
536
|
-
/** 无主 slot 是否已整体静默:所有 turn
|
|
587
|
+
/** 无主 slot 是否已整体静默:所有 turn 都不再是运行中。retentionMs 为 0 时不等待。 */
|
|
537
588
|
slotIsIdle(slot, job, now, retentionMs) {
|
|
538
589
|
const current = path.dirname(job.events);
|
|
539
590
|
const state = readJson(job.state);
|
package/dist/process-manager.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { knowledgeInstructions } from "./employee-knowledge.js";
|
|
1
|
+
import { globalKnowledgeContext, knowledgeInstructions } from "./employee-knowledge.js";
|
|
2
2
|
import { isOpenRouterFreeSelector } from "./openrouter-free-models.js";
|
|
3
|
+
import { openCodeMajorVersion } from "./opencode-cli.js";
|
|
3
4
|
import { isAutoAssignSelector, defaultModelGroupSelector, resolveModelGroupModels } from "./model-groups.js";
|
|
4
5
|
import { resolveAutoAssign } from "./model-auto-assign.js";
|
|
5
6
|
import { getDefaultModelForProvider } from "./config.js";
|
|
@@ -794,6 +795,15 @@ export class ProcessManager extends EventEmitter {
|
|
|
794
795
|
if (preferredModels.some(isOpenRouterFreeSelector))
|
|
795
796
|
throw new Error("免费模型分组仅支持 Pi 结构化对话。");
|
|
796
797
|
const baseCwd = resolveSessionCwd(cwd, this.config.defaultCwd);
|
|
798
|
+
const openCodeEnv = groupProvider === "opencode" ? buildChildEnv(this.config.inheritEnv !== false) : undefined;
|
|
799
|
+
const openCodeV2 = !!openCodeEnv && await openCodeMajorVersion(openCodeEnv) >= 2;
|
|
800
|
+
let openCodeConfig;
|
|
801
|
+
if (openCodeV2 && preferredModels[0]) {
|
|
802
|
+
const configured = openCodeEnv.OPENCODE_CONFIG_CONTENT ? JSON.parse(openCodeEnv.OPENCODE_CONFIG_CONTENT) : {};
|
|
803
|
+
if (!configured || typeof configured !== "object" || Array.isArray(configured))
|
|
804
|
+
throw new Error("OpenCode 内联配置无效。");
|
|
805
|
+
openCodeConfig = JSON.stringify({ ...configured, model: preferredModels[0] });
|
|
806
|
+
}
|
|
797
807
|
if (this.disposed || start.cancelled)
|
|
798
808
|
throw new Error("终端启动已取消。");
|
|
799
809
|
// When a session is being resumed under the same id, capture its prior
|
|
@@ -843,7 +853,10 @@ export class ProcessManager extends EventEmitter {
|
|
|
843
853
|
// Resolve before touching a resume record/worktree; invalid groups must not disturb prior work.
|
|
844
854
|
// PTY has no reliable pre-input acceptance fact: use the preferred member, never replay automatically.
|
|
845
855
|
const initialThinkingEffort = normalizeThinkingEffort(opts?.thinkingEffort);
|
|
846
|
-
|
|
856
|
+
// v2's interactive CLI takes its model from config; --model belongs to `run` only.
|
|
857
|
+
let processedCommand = this.processCommandForMode(command, effectiveMode, provider, openCodeV2 ? undefined : preferredModels[0], initialThinkingEffort);
|
|
858
|
+
if (openCodeV2 && !/--(?:standalone|server)(?:\s|=|$)/.test(processedCommand))
|
|
859
|
+
processedCommand += " --standalone";
|
|
847
860
|
// 会话级系统提示:provider 有系统提示开关就走开关(PTY 与结构化行为一致),没有就并进首条输入。
|
|
848
861
|
const systemPrompt = (opts?.systemPrompt ?? inheritedRole?.systemPrompt)?.trim() || undefined;
|
|
849
862
|
let initialInputText = initialInput;
|
|
@@ -945,7 +958,7 @@ export class ProcessManager extends EventEmitter {
|
|
|
945
958
|
// Derive authority only after the real session/project binding has been persisted.
|
|
946
959
|
const access = provider ? this.storage.knowledgeSessionScope(id) : null;
|
|
947
960
|
const knowledgeToken = access ? this.storage.issueKnowledgeAccess(id) : undefined;
|
|
948
|
-
const runtimePrompt = access ? [knowledgeInstructions(access),
|
|
961
|
+
const runtimePrompt = access ? [globalKnowledgeContext(this.storage), knowledgeInstructions(access),
|
|
949
962
|
"本终端会话的知识工具只在有效执行期内可用;每次使用知识先 search/read,不把旧轮次快照当作当前状态。访问失效时新开一轮结构化执行或恢复会话,不绕过权限。"].join("\n\n") : undefined;
|
|
950
963
|
const launchPrompt = [systemPrompt, runtimePrompt].filter(Boolean).join("\n\n") || undefined;
|
|
951
964
|
initialInputText = initialInput && launchPrompt && !systemPromptFlag(provider)
|
|
@@ -962,6 +975,7 @@ export class ProcessManager extends EventEmitter {
|
|
|
962
975
|
args: launchPlan.shellArgs,
|
|
963
976
|
cwd: resolvedCwd,
|
|
964
977
|
env: buildChildEnv(this.config.inheritEnv !== false, {
|
|
978
|
+
...(openCodeConfig ? { OPENCODE_CONFIG_CONTENT: openCodeConfig } : {}),
|
|
965
979
|
WAND_SESSION_ID: id,
|
|
966
980
|
WAND_KNOWLEDGE_DB: knowledgeToken ? this.storage.databasePath() : undefined,
|
|
967
981
|
WAND_KNOWLEDGE_TOKEN: knowledgeToken,
|
|
@@ -4,6 +4,8 @@ export interface DaemonPty {
|
|
|
4
4
|
write(data: string): void;
|
|
5
5
|
resize(cols: number, rows: number): void;
|
|
6
6
|
kill(signal?: string): void;
|
|
7
|
+
/** Retire only the observer/attach client; the tmux pane keeps running. */
|
|
8
|
+
detach?(): void;
|
|
7
9
|
onData(listener: (data: string) => void): {
|
|
8
10
|
dispose(): void;
|
|
9
11
|
};
|
|
@@ -11,13 +13,36 @@ export interface DaemonPty {
|
|
|
11
13
|
dispose(): void;
|
|
12
14
|
};
|
|
13
15
|
}
|
|
14
|
-
|
|
16
|
+
export interface PtyTmuxGcReport {
|
|
17
|
+
removedRecords: number;
|
|
18
|
+
freedBytes: number;
|
|
19
|
+
removedSockets: number;
|
|
20
|
+
}
|
|
21
|
+
/** The default tmux server owns panes; attach transports are disposable, not execution owners. */
|
|
15
22
|
export declare class PtyTmuxBackend {
|
|
16
23
|
private readonly directory;
|
|
17
|
-
private readonly
|
|
24
|
+
private readonly legacySocket;
|
|
18
25
|
constructor(configPath: string);
|
|
26
|
+
private connection;
|
|
19
27
|
private tmux;
|
|
28
|
+
private pane;
|
|
29
|
+
/**
|
|
30
|
+
* 只认稳定身份:会话名 + 我们创建的 pane id + 写入的 owner 标记。
|
|
31
|
+
* `pane_pid` 在新建后可能还没就绪,不能作为归属证据;需要时从实时结果取。
|
|
32
|
+
*/
|
|
33
|
+
private assertOwner;
|
|
34
|
+
private isTmuxMissing;
|
|
20
35
|
forget(sessionId: string): void;
|
|
36
|
+
collectGarbage(options: {
|
|
37
|
+
activeSessionIds: ReadonlySet<string>;
|
|
38
|
+
retentionMs: number;
|
|
39
|
+
now?: number;
|
|
40
|
+
}): PtyTmuxGcReport;
|
|
41
|
+
static collectGarbage(configDir: string, options: {
|
|
42
|
+
activeSessionIds: ReadonlySet<string>;
|
|
43
|
+
retentionMs: number;
|
|
44
|
+
now?: number;
|
|
45
|
+
}): PtyTmuxGcReport;
|
|
21
46
|
recover(exclude?: ReadonlySet<string>): Array<{
|
|
22
47
|
request: TerminalSpawnRequest;
|
|
23
48
|
child: DaemonPty;
|