@north-light/crouter 0.3.170 → 0.3.172
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +37 -11
- package/dist/api/client.js +84 -15
- package/dist/api/dto/human.d.ts +53 -39
- package/dist/api/dto/human.js +2 -3
- package/dist/api/dto/inbox.d.ts +0 -1
- package/dist/api/dto/nodes.d.ts +12 -0
- package/dist/api/dto/review-comments.d.ts +137 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +109 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/routes.d.ts +17 -4
- package/dist/api/routes.js +21 -5
- package/dist/build-root.d.ts +1 -16
- package/dist/build-root.js +1 -25
- package/dist/builtin-memory/00-runtime-base.md +7 -5
- package/dist/builtin-memory/04-base-worker.md +1 -1
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
- package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
- package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
- package/dist/builtin-memory/design.md +2 -2
- package/dist/builtin-memory/insights/capture.md +50 -0
- package/dist/builtin-memory/insights/init.md +45 -0
- package/dist/builtin-memory/insights/listen.md +9 -0
- package/dist/builtin-memory/internal/agent-shaping.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +12 -11
- package/dist/builtin-memory/internal/storage-tiers.md +2 -2
- package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
- package/dist/builtin-memory/plan.md +19 -0
- package/dist/builtin-memory/spec/guide.md +38 -0
- package/dist/builtin-memory/spec/requirements.md +31 -0
- package/dist/builtin-memory/spec/roadmap.md +35 -0
- package/dist/builtin-memory/spec.md +10 -86
- package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
- package/dist/cli.js +2 -6
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
- package/dist/clients/attach/__tests__/context-message.test.js +142 -6
- package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
- package/dist/clients/attach/__tests__/diagram.test.js +1 -1
- package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
- package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
- package/dist/clients/attach/chrome/header.d.ts +10 -0
- package/dist/clients/attach/chrome/header.js +30 -0
- package/dist/clients/attach/chrome/recap.d.ts +7 -0
- package/dist/clients/attach/chrome/recap.js +19 -0
- package/dist/clients/attach/chrome/status-line.d.ts +3 -0
- package/dist/clients/attach/chrome/status-line.js +5 -0
- package/dist/clients/attach/chrome/widgets.js +11 -21
- package/dist/clients/attach/command.js +11 -7
- package/dist/clients/attach/config.d.ts +4 -0
- package/dist/clients/attach/config.js +3 -0
- package/dist/clients/attach/input/controller.d.ts +19 -0
- package/dist/clients/attach/input/controller.js +62 -28
- package/dist/clients/attach/input/titled-editor.d.ts +0 -4
- package/dist/clients/attach/input/titled-editor.js +2 -10
- package/dist/clients/attach/overlays/file-review.d.ts +9 -5
- package/dist/clients/attach/overlays/file-review.js +9 -70
- package/dist/clients/attach/overlays/help.d.ts +33 -0
- package/dist/clients/attach/overlays/help.js +204 -0
- package/dist/clients/attach/render/activity-slot.d.ts +4 -0
- package/dist/clients/attach/render/activity-slot.js +13 -0
- package/dist/clients/attach/render/chat-view.d.ts +117 -12
- package/dist/clients/attach/render/chat-view.js +604 -135
- package/dist/clients/attach/render/context-message.d.ts +2 -1
- package/dist/clients/attach/render/context-message.js +17 -13
- package/dist/clients/attach/render/crtr-output.js +1 -3
- package/dist/clients/attach/render/diagram.js +2 -2
- package/dist/clients/attach/render/edit-diff.d.ts +4 -1
- package/dist/clients/attach/render/edit-diff.js +7 -11
- package/dist/clients/attach/render/group-activity.d.ts +32 -0
- package/dist/clients/attach/render/group-activity.js +206 -0
- package/dist/clients/attach/render/group-recap.d.ts +10 -0
- package/dist/clients/attach/render/group-recap.js +93 -0
- package/dist/clients/attach/render/html-markdown.d.ts +17 -0
- package/dist/clients/attach/render/html-markdown.js +228 -0
- package/dist/clients/attach/render/measured-container.d.ts +96 -0
- package/dist/clients/attach/render/measured-container.js +322 -0
- package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
- package/dist/clients/attach/render/scroll-animation.js +80 -0
- package/dist/clients/attach/render/tool-calls.js +6 -6
- package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
- package/dist/clients/attach/render/transcript-copy.js +81 -0
- package/dist/clients/attach/render/viewport.d.ts +29 -0
- package/dist/clients/attach/render/viewport.js +159 -0
- package/dist/clients/attach/session/bindings.d.ts +10 -7
- package/dist/clients/attach/session/bindings.js +23 -8
- package/dist/clients/attach/session/connection.js +4 -5
- package/dist/clients/attach/session/context.d.ts +6 -4
- package/dist/clients/attach/session/frame.d.ts +34 -0
- package/dist/clients/attach/session/frame.js +176 -0
- package/dist/clients/attach/session/frames.d.ts +4 -1
- package/dist/clients/attach/session/frames.js +14 -1
- package/dist/clients/attach/session/identity.js +4 -3
- package/dist/clients/attach/session/input-wiring.d.ts +14 -4
- package/dist/clients/attach/session/input-wiring.js +15 -13
- package/dist/clients/attach/session/invariant.d.ts +9 -0
- package/dist/clients/attach/session/invariant.js +15 -0
- package/dist/clients/attach/session/keys.d.ts +10 -2
- package/dist/clients/attach/session/keys.js +13 -5
- package/dist/clients/attach/session/layout.d.ts +10 -8
- package/dist/clients/attach/session/layout.js +33 -34
- package/dist/clients/attach/session/mouse.d.ts +18 -0
- package/dist/clients/attach/session/mouse.js +64 -0
- package/dist/clients/attach/session/pane-tag.d.ts +3 -0
- package/dist/clients/attach/session/pane-tag.js +51 -8
- package/dist/clients/attach/session/reconnect.d.ts +3 -0
- package/dist/clients/attach/session/reconnect.js +42 -5
- package/dist/clients/attach/session/surface-frame.d.ts +20 -0
- package/dist/clients/attach/session/surface-frame.js +73 -0
- package/dist/clients/attach/session/surface-host.d.ts +64 -0
- package/dist/clients/attach/session/surface-host.js +255 -0
- package/dist/clients/attach/session/whip.d.ts +17 -0
- package/dist/clients/attach/session/whip.js +334 -0
- package/dist/clients/attach/slash/dispatch.d.ts +13 -1
- package/dist/clients/attach/slash/dispatch.js +51 -29
- package/dist/clients/attach/viewer.js +907 -819
- package/dist/clients/conversation/conversation.d.ts +65 -0
- package/dist/clients/conversation/conversation.js +318 -0
- package/dist/clients/conversation/frames.d.ts +30 -0
- package/dist/clients/conversation/frames.js +52 -0
- package/dist/clients/conversation/region.d.ts +51 -0
- package/dist/clients/conversation/region.js +265 -0
- package/dist/clients/conversation/submit.d.ts +38 -0
- package/dist/clients/conversation/submit.js +51 -0
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
- package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
- package/dist/clients/inbox/controller.d.ts +79 -0
- package/dist/clients/inbox/controller.js +448 -0
- package/dist/clients/inbox/deck-adapter.d.ts +29 -0
- package/dist/clients/inbox/deck-adapter.js +62 -0
- package/dist/clients/inbox/layout.d.ts +8 -0
- package/dist/clients/inbox/layout.js +9 -0
- package/dist/clients/inbox/resolve.d.ts +10 -0
- package/dist/clients/inbox/resolve.js +34 -0
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
- package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
- package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
- package/dist/clients/inbox/review/anchors.d.ts +41 -0
- package/dist/clients/inbox/review/anchors.js +89 -0
- package/dist/clients/inbox/review/columns.d.ts +22 -0
- package/dist/clients/inbox/review/columns.js +40 -0
- package/dist/clients/inbox/review/comments-client.d.ts +66 -0
- package/dist/clients/inbox/review/comments-client.js +98 -0
- package/dist/clients/inbox/review/composition.d.ts +60 -0
- package/dist/clients/inbox/review/composition.js +278 -0
- package/dist/clients/inbox/review/document-region.d.ts +120 -0
- package/dist/clients/inbox/review/document-region.js +902 -0
- package/dist/clients/inbox/review/frame.d.ts +45 -0
- package/dist/clients/inbox/review/frame.js +215 -0
- package/dist/clients/inbox/review/keys.d.ts +67 -0
- package/dist/clients/inbox/review/keys.js +130 -0
- package/dist/clients/inbox/review/launch.d.ts +10 -0
- package/dist/clients/inbox/review/launch.js +129 -0
- package/dist/clients/inbox/review/live-source.d.ts +24 -0
- package/dist/clients/inbox/review/live-source.js +160 -0
- package/dist/clients/inbox/review/nvim.d.ts +13 -0
- package/dist/clients/inbox/review/nvim.js +42 -0
- package/dist/clients/inbox/review/remap.d.ts +51 -0
- package/dist/clients/inbox/review/remap.js +157 -0
- package/dist/clients/inbox/review/review-client.d.ts +30 -0
- package/dist/clients/inbox/review/review-client.js +107 -0
- package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
- package/dist/clients/inbox/review/roundtrip.js +36 -0
- package/dist/clients/inbox/review/state.d.ts +143 -0
- package/dist/clients/inbox/review/state.js +282 -0
- package/dist/clients/inbox/review-adapter.d.ts +29 -0
- package/dist/clients/inbox/review-adapter.js +92 -0
- package/dist/clients/inbox/review-visibility.d.ts +5 -0
- package/dist/clients/inbox/review-visibility.js +19 -0
- package/dist/clients/inbox/surface.d.ts +19 -0
- package/dist/clients/inbox/surface.js +128 -0
- package/dist/clients/inbox/tui/ansi.d.ts +66 -0
- package/dist/clients/inbox/tui/ansi.js +317 -0
- package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
- package/dist/clients/inbox/tui/clipboard.js +26 -0
- package/dist/clients/inbox/tui/input.d.ts +7 -0
- package/dist/clients/inbox/tui/input.js +653 -0
- package/dist/clients/inbox/tui/keys.d.ts +28 -0
- package/dist/clients/inbox/tui/keys.js +111 -0
- package/dist/clients/inbox/tui/panel.d.ts +2 -0
- package/dist/clients/inbox/tui/panel.js +217 -0
- package/dist/clients/inbox/tui/render.d.ts +37 -0
- package/dist/clients/inbox/tui/render.js +476 -0
- package/dist/clients/inbox/tui/types.d.ts +57 -0
- package/dist/clients/inbox/tui/types.js +1 -0
- package/dist/clients/inbox/tui.d.ts +6 -0
- package/dist/clients/inbox/tui.js +74 -0
- package/dist/clients/surfaces/host.d.ts +66 -0
- package/dist/clients/surfaces/host.js +1 -0
- package/dist/clients/surfaces/region.d.ts +16 -0
- package/dist/clients/surfaces/region.js +1 -0
- package/dist/clients/web/__tests__/push-engine.test.js +14 -158
- package/dist/clients/web/dev-server.d.ts +3 -3
- package/dist/clients/web/dev-server.js +9 -23
- package/dist/clients/web/events.js +4 -6
- package/dist/clients/web/push-engine.d.ts +2 -66
- package/dist/clients/web/push-engine.js +30 -161
- package/dist/clients/web/push-registry.d.ts +0 -4
- package/dist/clients/web/push-registry.js +2 -7
- package/dist/clients/web/server.js +3 -35
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
- package/dist/clients/web/web-cmd.js +2 -2
- package/dist/commands/__tests__/human.test.js +27 -15
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/canvas-issue.js +1 -1
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human/doc.d.ts +2 -0
- package/dist/commands/human/doc.js +98 -0
- package/dist/commands/human/inbox.d.ts +2 -0
- package/dist/commands/human/inbox.js +101 -0
- package/dist/commands/human/prompts.d.ts +2 -3
- package/dist/commands/human/prompts.js +27 -180
- package/dist/commands/human/queue.d.ts +1 -5
- package/dist/commands/human/queue.js +54 -216
- package/dist/commands/human/review.d.ts +2 -0
- package/dist/commands/human/review.js +298 -0
- package/dist/commands/human/shared.d.ts +2 -69
- package/dist/commands/human/shared.js +1 -181
- package/dist/commands/human.js +15 -20
- package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
- package/dist/commands/memory/__tests__/lint.test.js +15 -0
- package/dist/commands/memory/delete.js +2 -2
- package/dist/commands/memory/lint.d.ts +1 -0
- package/dist/commands/memory/lint.js +21 -3
- package/dist/commands/memory/read.js +4 -4
- package/dist/commands/node.js +8 -7
- package/dist/commands/pkg/plugin-manage.js +143 -68
- package/dist/commands/surface-inspect.js +2 -2
- package/dist/commands/surface.js +6 -12
- package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
- package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
- package/dist/commands/sys/config.js +29 -3
- package/dist/commands/sys/feedback.js +1 -1
- package/dist/commands/sys/setup-core.d.ts +12 -11
- package/dist/commands/sys/setup-core.js +55 -46
- package/dist/commands/sys/setup-wizard.d.ts +4 -1
- package/dist/commands/sys/setup-wizard.js +50 -9
- package/dist/commands/sys/sync-deps.js +1 -1
- package/dist/commands/sys.js +4 -6
- package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
- package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
- package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
- package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
- package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
- package/dist/core/__tests__/full/detach-focus.test.js +1 -1
- package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
- package/dist/core/__tests__/human-deliver.test.js +71 -345
- package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
- package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
- package/dist/core/__tests__/migration.test.js +10 -0
- package/dist/core/__tests__/model-pin-durability.test.js +14 -0
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
- package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-store.test.js +143 -0
- package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
- package/dist/core/__tests__/revive.test.js +22 -53
- package/dist/core/__tests__/session-cycles.test.js +48 -18
- package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
- package/dist/core/__tests__/stop-guard.test.js +16 -1
- package/dist/core/__tests__/tmux-surface.test.js +21 -25
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/broker-client/client.d.ts +0 -7
- package/dist/core/broker-client/client.js +4 -10
- package/dist/core/broker-client/transport-relay.d.ts +3 -4
- package/dist/core/broker-client/transport-relay.js +3 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
- package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
- package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
- package/dist/core/canvas/attention.js +4 -4
- package/dist/core/canvas/canvas.d.ts +6 -11
- package/dist/core/canvas/canvas.js +11 -33
- package/dist/core/canvas/db.js +207 -38
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +8 -1
- package/dist/core/canvas/index.d.ts +0 -1
- package/dist/core/canvas/index.js +0 -1
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/paths.d.ts +5 -0
- package/dist/core/canvas/paths.js +16 -0
- package/dist/core/canvas/remote-canvas-source.js +2 -2
- package/dist/core/canvas/remote-transport.d.ts +7 -0
- package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/status-glyph.js +4 -12
- package/dist/core/canvas/types.d.ts +10 -35
- package/dist/core/clipboard-text.d.ts +8 -0
- package/dist/core/clipboard-text.js +18 -0
- package/dist/core/command-manifests/registry.d.ts +1 -3
- package/dist/core/command-plugins/bundle.d.ts +29 -0
- package/dist/core/command-plugins/bundle.js +198 -0
- package/dist/core/command-plugins/discovery.d.ts +0 -8
- package/dist/core/command-plugins/discovery.js +2 -39
- package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
- package/dist/core/command-plugins/transport/http-fetch.js +17 -95
- package/dist/core/command.d.ts +1 -13
- package/dist/core/command.js +1 -16
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +28 -3
- package/dist/core/document-lines.d.ts +4 -0
- package/dist/core/document-lines.js +6 -0
- package/dist/core/feed/feed.d.ts +2 -0
- package/dist/core/feed/feed.js +11 -7
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
- package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-core.test.js +144 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
- package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
- package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
- package/dist/core/human/claim.d.ts +23 -0
- package/dist/core/human/claim.js +67 -0
- package/dist/core/human/convention.d.ts +30 -0
- package/dist/core/human/convention.js +202 -0
- package/dist/core/human/deck-factories.d.ts +8 -0
- package/dist/core/human/deck-factories.js +15 -0
- package/dist/core/human/deck-schema.d.ts +70 -0
- package/dist/core/human/deck-schema.js +92 -0
- package/dist/core/human/root.d.ts +7 -0
- package/dist/core/human/root.js +37 -0
- package/dist/core/human/scan.d.ts +3 -0
- package/dist/core/human/scan.js +76 -0
- package/dist/core/human/summary.d.ts +8 -0
- package/dist/core/human/summary.js +44 -0
- package/dist/core/human/tickets.d.ts +49 -0
- package/dist/core/human/tickets.js +190 -0
- package/dist/core/human/types.d.ts +136 -0
- package/dist/core/human/types.js +5 -0
- package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
- package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
- package/dist/core/inspector/chrome.d.ts +6 -0
- package/dist/core/inspector/chrome.js +14 -0
- package/dist/core/inspector/contract.d.ts +105 -0
- package/dist/core/inspector/contract.js +1 -0
- package/dist/core/inspector/core.d.ts +4 -5
- package/dist/core/inspector/core.js +3 -5
- package/dist/core/inspector/host.d.ts +46 -0
- package/dist/core/{tui → inspector}/host.js +42 -208
- package/dist/core/inspector/text.d.ts +2 -2
- package/dist/core/inspector/transport.d.ts +6 -0
- package/dist/core/inspector/transport.js +36 -0
- package/dist/core/inspector/tui.d.ts +2 -2
- package/dist/core/inspector/tui.js +15 -15
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
- package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
- package/dist/core/keybindings/attach-control.d.ts +9 -3
- package/dist/core/keybindings/attach-control.js +3 -1
- package/dist/core/keybindings/catalog.d.ts +6 -5
- package/dist/core/keybindings/catalog.js +61 -133
- package/dist/core/keybindings/inbox.d.ts +5 -6
- package/dist/core/keybindings/inbox.js +9 -10
- package/dist/core/keybindings/index.d.ts +3 -3
- package/dist/core/keybindings/index.js +3 -3
- package/dist/core/keybindings/persistence.d.ts +5 -1
- package/dist/core/keybindings/persistence.js +24 -6
- package/dist/core/keybindings/resolve.d.ts +6 -0
- package/dist/core/keybindings/resolve.js +10 -3
- package/dist/core/memory/inline-ref-grammar.js +2 -3
- package/dist/core/memory-resolver.d.ts +27 -29
- package/dist/core/memory-resolver.js +45 -39
- package/dist/core/model-routes.d.ts +33 -0
- package/dist/core/model-routes.js +42 -3
- package/dist/core/preview-registry.js +17 -55
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
- package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
- package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
- package/dist/core/review/__tests__/capture-origin.test.js +139 -0
- package/dist/core/review/__tests__/comments.test.d.ts +1 -0
- package/dist/core/review/__tests__/comments.test.js +98 -0
- package/dist/core/review/__tests__/project.test.d.ts +1 -0
- package/dist/core/review/__tests__/project.test.js +71 -0
- package/dist/core/review/__tests__/remap.test.d.ts +1 -0
- package/dist/core/review/__tests__/remap.test.js +159 -0
- package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
- package/dist/core/review/__tests__/stage-identity.test.js +140 -0
- package/dist/core/review/birth.d.ts +7 -0
- package/dist/core/review/birth.js +23 -0
- package/dist/core/review/comments.d.ts +69 -0
- package/dist/core/review/comments.js +295 -0
- package/dist/core/review/companion.d.ts +35 -0
- package/dist/core/review/companion.js +205 -0
- package/dist/core/review/document.d.ts +27 -0
- package/dist/core/review/document.js +138 -0
- package/dist/core/review/project.d.ts +13 -0
- package/dist/core/review/project.js +58 -0
- package/dist/core/review/realize.d.ts +19 -0
- package/dist/core/review/realize.js +217 -0
- package/dist/core/review/remap.d.ts +24 -0
- package/dist/core/review/remap.js +156 -0
- package/dist/core/review/signal.d.ts +5 -0
- package/dist/core/review/signal.js +31 -0
- package/dist/core/review/stage.d.ts +26 -0
- package/dist/core/review/stage.js +184 -0
- package/dist/core/review/store.d.ts +46 -0
- package/dist/core/review/store.js +163 -0
- package/dist/core/review/ticket-filter.d.ts +17 -0
- package/dist/core/review/ticket-filter.js +32 -0
- package/dist/core/review/types.d.ts +130 -0
- package/dist/core/review/types.js +23 -0
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
- package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
- package/dist/core/runtime/bearings.d.ts +5 -17
- package/dist/core/runtime/bearings.js +88 -71
- package/dist/core/runtime/broker-protocol.d.ts +31 -8
- package/dist/core/runtime/broker.d.ts +15 -1
- package/dist/core/runtime/broker.js +573 -141
- package/dist/core/runtime/canvas-extensions.d.ts +4 -5
- package/dist/core/runtime/canvas-extensions.js +5 -5
- package/dist/core/runtime/front-door.js +4 -4
- package/dist/core/runtime/headless-pi.d.ts +24 -0
- package/dist/core/runtime/headless-pi.js +152 -0
- package/dist/core/runtime/kickoff.d.ts +1 -5
- package/dist/core/runtime/kickoff.js +1 -5
- package/dist/core/runtime/model-registry.d.ts +3 -0
- package/dist/core/runtime/model-registry.js +13 -0
- package/dist/core/runtime/naming-persist.d.ts +4 -0
- package/dist/core/runtime/naming-persist.js +27 -1
- package/dist/core/runtime/naming.d.ts +17 -12
- package/dist/core/runtime/naming.js +91 -140
- package/dist/core/runtime/node-read.js +19 -10
- package/dist/core/runtime/nodes.d.ts +9 -14
- package/dist/core/runtime/nodes.js +3 -53
- package/dist/core/runtime/package-health.d.ts +6 -21
- package/dist/core/runtime/package-health.js +12 -123
- package/dist/core/runtime/placement-tmux.d.ts +2 -1
- package/dist/core/runtime/placement-tmux.js +6 -4
- package/dist/core/runtime/placement.d.ts +1 -0
- package/dist/core/runtime/placement.js +4 -8
- package/dist/core/runtime/promote.js +3 -0
- package/dist/core/runtime/recap.d.ts +2 -7
- package/dist/core/runtime/recap.js +35 -69
- package/dist/core/runtime/revive.js +34 -77
- package/dist/core/runtime/session-cycles.d.ts +4 -0
- package/dist/core/runtime/session-cycles.js +14 -1
- package/dist/core/runtime/session-visibility.d.ts +37 -0
- package/dist/core/runtime/session-visibility.js +83 -0
- package/dist/core/runtime/spawn.js +10 -22
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +18 -13
- package/dist/core/runtime/surface-bg.js +1 -1
- package/dist/core/runtime/tmux-chrome.d.ts +1 -1
- package/dist/core/runtime/tmux-chrome.js +1 -1
- package/dist/core/runtime/tmux.d.ts +35 -7
- package/dist/core/runtime/tmux.js +439 -62
- package/dist/core/runtime/tool-group-summary.d.ts +19 -0
- package/dist/core/runtime/tool-group-summary.js +88 -0
- package/dist/core/scope.d.ts +2 -7
- package/dist/core/scope.js +9 -35
- package/dist/core/substrate/schema.d.ts +2 -2
- package/dist/core/termrender/code-doc.d.ts +12 -0
- package/dist/core/termrender/code-doc.js +92 -0
- package/dist/core/termrender/display.d.ts +12 -0
- package/dist/core/termrender/display.js +19 -0
- package/dist/core/termrender/termrender.d.ts +73 -0
- package/dist/core/termrender/termrender.js +795 -0
- package/dist/core/termrender/version.d.ts +1 -0
- package/dist/core/termrender/version.js +1 -0
- package/dist/core/tui/terminal.js +1 -2
- package/dist/core/user-settings.d.ts +71 -3
- package/dist/core/user-settings.js +83 -1
- package/dist/daemon/api/__tests__/inbox.test.js +44 -133
- package/dist/daemon/api/handlers/human.d.ts +0 -10
- package/dist/daemon/api/handlers/human.js +104 -702
- package/dist/daemon/api/handlers/inbox.js +113 -142
- package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
- package/dist/daemon/api/handlers/review-comments.js +500 -0
- package/dist/daemon/api/handlers/reviews.d.ts +2 -0
- package/dist/daemon/api/handlers/reviews.js +287 -0
- package/dist/daemon/api/map.d.ts +22 -7
- package/dist/daemon/api/map.js +159 -11
- package/dist/daemon/api/server.js +4 -0
- package/dist/daemon/cron-run.js +6 -9
- package/dist/daemon/crtrd.js +17 -33
- package/dist/daemon/fleet.d.ts +1 -8
- package/dist/daemon/fleet.js +4 -30
- package/dist/daemon/human/finish.d.ts +14 -0
- package/dist/daemon/human/finish.js +115 -0
- package/dist/daemon/human/sweep.d.ts +6 -0
- package/dist/daemon/human/sweep.js +49 -0
- package/dist/daemon/messaging/node-message.d.ts +18 -0
- package/dist/daemon/messaging/node-message.js +70 -0
- package/dist/daemon/review/comment-notify.d.ts +26 -0
- package/dist/daemon/review/comment-notify.js +107 -0
- package/dist/daemon/review/deliver.d.ts +7 -0
- package/dist/daemon/review/deliver.js +56 -0
- package/dist/daemon/review/finish.d.ts +22 -0
- package/dist/daemon/review/finish.js +254 -0
- package/dist/daemon/review/sweep.d.ts +11 -0
- package/dist/daemon/review/sweep.js +120 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
- package/dist/pi-extensions/canvas-context-intro.js +50 -104
- package/dist/pi-extensions/canvas-recap.d.ts +15 -2
- package/dist/pi-extensions/canvas-recap.js +192 -69
- package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
- package/dist/pi-extensions/canvas-review-boundary.js +81 -0
- package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
- package/dist/pi-extensions/canvas-stophook.js +78 -128
- package/dist/pi-extensions/canvas-structured-output.js +52 -8
- package/dist/shared/generated-context.d.ts +29 -4
- package/dist/shared/generated-context.js +122 -7
- package/dist/shared/tool-groups.d.ts +23 -0
- package/dist/shared/tool-groups.js +60 -0
- package/dist/shared/working-activity.d.ts +8 -0
- package/dist/shared/working-activity.js +26 -0
- package/dist/types.d.ts +36 -2
- package/dist/types.js +51 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
- package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/compat/hearth-crtr-v4.md +2 -2
- package/docs/compat/hearth-crtr-v5.md +4 -2
- package/docs/public-api.md +3 -3
- package/package.json +21 -14
- package/runtime.lock.json +4661 -1453
- package/scripts/postinstall.mjs +15 -2
- package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
- package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
- package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
- package/dist/builtin-views/_lib/states.mjs +0 -161
- package/dist/builtin-views/canvas/core.mjs +0 -657
- package/dist/builtin-views/canvas/text.mjs +0 -58
- package/dist/builtin-views/canvas/tui.mjs +0 -168
- package/dist/builtin-views/canvas/web.jsx +0 -121
- package/dist/builtin-views/chat/core.mjs +0 -684
- package/dist/builtin-views/chat/text.mjs +0 -101
- package/dist/builtin-views/chat/tui.mjs +0 -360
- package/dist/builtin-views/chat/web.jsx +0 -362
- package/dist/builtin-views/git-pr/core.mjs +0 -673
- package/dist/builtin-views/git-pr/text.mjs +0 -84
- package/dist/builtin-views/git-pr/tui.mjs +0 -301
- package/dist/builtin-views/git-pr/web.jsx +0 -216
- package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
- package/dist/builtin-views/inbox/core.mjs +0 -1273
- package/dist/builtin-views/inbox/text.mjs +0 -73
- package/dist/builtin-views/inbox/tui.mjs +0 -314
- package/dist/builtin-views/inbox/web.jsx +0 -188
- package/dist/builtin-views/linkedin/core.mjs +0 -906
- package/dist/builtin-views/linkedin/text.mjs +0 -69
- package/dist/builtin-views/linkedin/tui.mjs +0 -413
- package/dist/builtin-views/linkedin/web.jsx +0 -206
- package/dist/builtin-views/prompt-review/core.mjs +0 -735
- package/dist/builtin-views/prompt-review/text.mjs +0 -15
- package/dist/builtin-views/prompt-review/tui.mjs +0 -196
- package/dist/builtin-views/prompt-review/web.jsx +0 -484
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
- package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
- package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
- package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
- package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
- package/dist/clients/attach/session/mode.d.ts +0 -25
- package/dist/clients/attach/session/mode.js +0 -97
- package/dist/commands/sys/promptstudio.d.ts +0 -2
- package/dist/commands/sys/promptstudio.js +0 -65
- package/dist/commands/view-cycle.d.ts +0 -2
- package/dist/commands/view-cycle.js +0 -130
- package/dist/commands/view-list.d.ts +0 -2
- package/dist/commands/view-list.js +0 -66
- package/dist/commands/view-new.d.ts +0 -2
- package/dist/commands/view-new.js +0 -74
- package/dist/commands/view-pick.d.ts +0 -6
- package/dist/commands/view-pick.js +0 -129
- package/dist/commands/view-run.d.ts +0 -2
- package/dist/commands/view-run.js +0 -214
- package/dist/commands/view.d.ts +0 -2
- package/dist/commands/view.js +0 -31
- package/dist/commands/workspace.d.ts +0 -2
- package/dist/commands/workspace.js +0 -165
- package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
- package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
- package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
- package/dist/core/canvas/human-work-outbox.d.ts +0 -73
- package/dist/core/canvas/human-work-outbox.js +0 -261
- package/dist/core/command-plugins/store.d.ts +0 -16
- package/dist/core/command-plugins/store.js +0 -64
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
- package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
- package/dist/core/runtime/fault-recovery-nudge.js +0 -3
- package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
- package/dist/core/tui/host.d.ts +0 -66
- package/dist/core/view/__tests__/transport-cache.test.js +0 -62
- package/dist/core/view/bridge.d.ts +0 -10
- package/dist/core/view/bridge.js +0 -31
- package/dist/core/view/chrome.d.ts +0 -9
- package/dist/core/view/chrome.js +0 -22
- package/dist/core/view/contract.d.ts +0 -205
- package/dist/core/view/contract.js +0 -23
- package/dist/core/view/loader.d.ts +0 -31
- package/dist/core/view/loader.js +0 -188
- package/dist/core/view/stream-local.d.ts +0 -3
- package/dist/core/view/stream-local.js +0 -231
- package/dist/core/view/transport-cache.d.ts +0 -8
- package/dist/core/view/transport-cache.js +0 -38
- package/dist/core/view/transport-local.d.ts +0 -7
- package/dist/core/view/transport-local.js +0 -83
- package/dist/core/view/transport-remote.d.ts +0 -2
- package/dist/core/view/transport.d.ts +0 -10
- package/dist/core/view/transport.js +0 -15
- package/dist/pi-extensions/naming-tool.d.ts +0 -24
- package/dist/pi-extensions/naming-tool.js +0 -67
- package/dist/prompts/view.d.ts +0 -7
- package/dist/prompts/view.js +0 -172
- package/dist/web/ViewChrome.d.ts +0 -7
- package/dist/web/ViewChrome.js +0 -28
- package/dist/web/ViewPane.d.ts +0 -39
- package/dist/web/ViewPane.js +0 -48
- package/dist/web/index.d.ts +0 -8
- package/dist/web/index.js +0 -22
- package/dist/web/runtime.d.ts +0 -39
- package/dist/web/runtime.js +0 -232
- package/dist/web/states.d.ts +0 -24
- package/dist/web/states.js +0 -24
- package/dist/web/transport-http.d.ts +0 -5
- package/dist/web/transport-http.js +0 -34
- package/dist/web/transport-stream.d.ts +0 -3
- package/dist/web/transport-stream.js +0 -204
- package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
- package/dist/web-client/assets/index-aaeu4adv.css +0 -2
- /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
- /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
- /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
- /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
- /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// session/mouse.ts — terminal mouse reporting for the attach viewport.
|
|
2
|
+
//
|
|
3
|
+
// Mouse reporting starts from the user's configured default. Follow-tmux mode
|
|
4
|
+
// leaves native terminal selection alone when tmux mouse is off; inside a
|
|
5
|
+
// reporting viewer, every mouse sequence is consumed so clicks and drags can
|
|
6
|
+
// never become editor input.
|
|
7
|
+
import { spawnSync } from 'node:child_process';
|
|
8
|
+
import { inTmux } from '../../../core/runtime/placement-tmux.js';
|
|
9
|
+
const MOUSE_REPORTING_ON = '\x1b[?1002h\x1b[?1006h';
|
|
10
|
+
const MOUSE_REPORTING_OFF = '\x1b[?1002l\x1b[?1006l';
|
|
11
|
+
/** Lines moved for one terminal wheel notch. */
|
|
12
|
+
export const WHEEL_LINES = 3;
|
|
13
|
+
function detectMouseDefault() {
|
|
14
|
+
if (!inTmux())
|
|
15
|
+
return false;
|
|
16
|
+
const result = spawnSync('tmux', ['show-options', '-gv', 'mouse'], { encoding: 'utf8' });
|
|
17
|
+
return result.status === 0 && result.stdout?.trim() === 'on';
|
|
18
|
+
}
|
|
19
|
+
/** Create per-viewer mouse reporting from the user's saved starting mode. */
|
|
20
|
+
export function createMouseReporting(write, defaultMode) {
|
|
21
|
+
let isEnabled = defaultMode === 'on' || (defaultMode === 'tmux' && detectMouseDefault());
|
|
22
|
+
const reassert = () => {
|
|
23
|
+
write(isEnabled ? MOUSE_REPORTING_ON : MOUSE_REPORTING_OFF);
|
|
24
|
+
};
|
|
25
|
+
const disable = () => {
|
|
26
|
+
isEnabled = false;
|
|
27
|
+
try {
|
|
28
|
+
write(MOUSE_REPORTING_OFF);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Terminal restoration is best-effort, including during process exit.
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
process.once('exit', disable);
|
|
35
|
+
return {
|
|
36
|
+
enabled: () => isEnabled,
|
|
37
|
+
toggle: () => {
|
|
38
|
+
isEnabled = !isEnabled;
|
|
39
|
+
reassert();
|
|
40
|
+
return isEnabled;
|
|
41
|
+
},
|
|
42
|
+
reassert,
|
|
43
|
+
disable,
|
|
44
|
+
install: (tui, onWheel) => tui.addInputListener((data) => {
|
|
45
|
+
let consumed = false;
|
|
46
|
+
const withoutSgr = data.replace(/\x1b\[<(\d+);(\d+);\d+[Mm]/g, (_match, buttons, column) => {
|
|
47
|
+
consumed = true;
|
|
48
|
+
const button = Number(buttons) & ~(4 | 8 | 16);
|
|
49
|
+
if (button === 64)
|
|
50
|
+
onWheel('up', WHEEL_LINES, Number(column));
|
|
51
|
+
if (button === 65)
|
|
52
|
+
onWheel('down', WHEEL_LINES, Number(column));
|
|
53
|
+
return '';
|
|
54
|
+
});
|
|
55
|
+
const withoutMouse = withoutSgr.replace(/\x1b\[M[\s\S]{3}/g, () => {
|
|
56
|
+
consumed = true;
|
|
57
|
+
return '';
|
|
58
|
+
});
|
|
59
|
+
if (!consumed)
|
|
60
|
+
return undefined;
|
|
61
|
+
return withoutMouse.length > 0 ? { data: withoutMouse } : { consume: true };
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
* to call from a teardown that runs before it was ever claimed. */
|
|
9
9
|
export declare function createPaneTag(remote: boolean, nodeId: string): {
|
|
10
10
|
set: () => void;
|
|
11
|
+
stamp: () => void;
|
|
11
12
|
clear: () => void;
|
|
12
13
|
pane: () => string | undefined;
|
|
13
14
|
};
|
|
14
15
|
export declare function tagAttachPane(remote: boolean, pane: string | undefined, nodeId: string, setOpt?: (pane: string, name: string, value: string) => void): void;
|
|
15
16
|
export declare function untagAttachPane(remote: boolean, pane: string | undefined, setOpt?: (pane: string, name: string, value: string) => void): void;
|
|
17
|
+
export declare function tagAttachViewerPane(pane: string | undefined, setOpt?: (pane: string, name: string, value: string) => void): void;
|
|
18
|
+
export declare function untagAttachViewerPane(pane: string | undefined, setOpt?: (pane: string, name: string, value: string) => void): void;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
// session/pane-tag.ts —
|
|
2
|
-
// host-agnostic `nodeInPane()` (the Alt+C cycle/recycle/close/demote family)
|
|
3
|
-
// resolve which broker-hosted node a viewer pane is showing.
|
|
1
|
+
// session/pane-tag.ts — pane tags owned by an attach viewer.
|
|
4
2
|
//
|
|
5
|
-
//
|
|
6
|
-
// lifecycle
|
|
7
|
-
//
|
|
8
|
-
|
|
3
|
+
// `@crtr_node` is local identity used by nodeInPane(). A remote attach never
|
|
4
|
+
// sets it, so local lifecycle cannot resolve a remote node id (or a colliding
|
|
5
|
+
// local id) from that pane. `@crtr_attach` carries no identity: every local or
|
|
6
|
+
// remote attach viewer sets it so tmux can conditionally forward opted-in root
|
|
7
|
+
// gestures into whichever attach pane currently has focus.
|
|
8
|
+
import { currentTmux, setPaneOption, stampViewerPaneAsync, VIEWER_STAMP_OPTION, } from '../../../core/runtime/placement-tmux.js';
|
|
9
9
|
/** The tag's lifecycle for one viewer: `set()` once the startup checkpoint has
|
|
10
10
|
* cleared, `clear()` on teardown so a stray tag can't outlive the pane.
|
|
11
11
|
* `pane()` is the id teardown reports as this viewer's home.
|
|
@@ -20,11 +20,38 @@ export function createPaneTag(remote, nodeId) {
|
|
|
20
20
|
set: () => {
|
|
21
21
|
pane = process.env['TMUX_PANE'] ?? currentTmux()?.pane;
|
|
22
22
|
tagAttachPane(remote, pane, nodeId);
|
|
23
|
+
tagAttachViewerPane(pane);
|
|
24
|
+
stampAttachPane(remote, pane);
|
|
25
|
+
},
|
|
26
|
+
stamp: () => {
|
|
27
|
+
if (remote || pane === undefined || pane === '')
|
|
28
|
+
return;
|
|
29
|
+
stampViewerPaneAsync(pane);
|
|
30
|
+
},
|
|
31
|
+
clear: () => {
|
|
32
|
+
untagAttachPane(remote, pane);
|
|
33
|
+
untagAttachViewerPane(pane);
|
|
34
|
+
unstampAttachPane(remote, pane);
|
|
23
35
|
},
|
|
24
|
-
clear: () => untagAttachPane(remote, pane),
|
|
25
36
|
pane: () => pane,
|
|
26
37
|
};
|
|
27
38
|
}
|
|
39
|
+
function stampAttachPane(remote, pane) {
|
|
40
|
+
if (remote || pane === undefined || pane === '')
|
|
41
|
+
return;
|
|
42
|
+
try {
|
|
43
|
+
setPaneOption(pane, VIEWER_STAMP_OPTION, String(Date.now()));
|
|
44
|
+
}
|
|
45
|
+
catch { /* best-effort */ }
|
|
46
|
+
}
|
|
47
|
+
function unstampAttachPane(remote, pane) {
|
|
48
|
+
if (remote || pane === undefined || pane === '')
|
|
49
|
+
return;
|
|
50
|
+
try {
|
|
51
|
+
setPaneOption(pane, VIEWER_STAMP_OPTION, '');
|
|
52
|
+
}
|
|
53
|
+
catch { /* best-effort */ }
|
|
54
|
+
}
|
|
28
55
|
export function tagAttachPane(remote, pane, nodeId, setOpt = setPaneOption) {
|
|
29
56
|
if (remote || pane === undefined || pane === '')
|
|
30
57
|
return;
|
|
@@ -41,3 +68,19 @@ export function untagAttachPane(remote, pane, setOpt = setPaneOption) {
|
|
|
41
68
|
}
|
|
42
69
|
catch { /* best-effort */ }
|
|
43
70
|
}
|
|
71
|
+
export function tagAttachViewerPane(pane, setOpt = setPaneOption) {
|
|
72
|
+
if (pane === undefined || pane === '')
|
|
73
|
+
return;
|
|
74
|
+
try {
|
|
75
|
+
setOpt(pane, '@crtr_attach', '1');
|
|
76
|
+
}
|
|
77
|
+
catch { /* best-effort */ }
|
|
78
|
+
}
|
|
79
|
+
export function untagAttachViewerPane(pane, setOpt = setPaneOption) {
|
|
80
|
+
if (pane === undefined || pane === '')
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
setOpt(pane, '@crtr_attach', '');
|
|
84
|
+
}
|
|
85
|
+
catch { /* best-effort */ }
|
|
86
|
+
}
|
|
@@ -33,5 +33,8 @@ export interface ReconnectSupervisor {
|
|
|
33
33
|
/** Install the permanent frame/error/close handlers. Call once, AFTER the
|
|
34
34
|
* connect race is settled and its temporary listeners are gone. */
|
|
35
35
|
install: () => void;
|
|
36
|
+
/** Cancel the current delay/redial wait. Ordinary attach never calls this;
|
|
37
|
+
* bounded companion surfaces call it before closing their socket. */
|
|
38
|
+
stop: () => void;
|
|
36
39
|
}
|
|
37
40
|
export declare function createReconnect(ctx: Pick<AttachSession, 'nodeId' | 'socket' | 'canvasSource'>, hooks: ReconnectHooks): ReconnectSupervisor;
|
|
@@ -12,7 +12,6 @@ import { reconnectShouldGiveUp } from '../../../core/broker-client/index.js';
|
|
|
12
12
|
const RECONNECT_ACTIVE_DELAY_CAP_MS = 1_000;
|
|
13
13
|
/** Dormant by choice — low-rate patience. */
|
|
14
14
|
const RECONNECT_DORMANT_DELAY_MS = 3_000;
|
|
15
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
16
15
|
export function createReconnect(ctx, hooks) {
|
|
17
16
|
const { nodeId, socket, canvasSource } = ctx;
|
|
18
17
|
let lastSocketError;
|
|
@@ -22,6 +21,30 @@ export function createReconnect(ctx, hooks) {
|
|
|
22
21
|
// closes its pane instead of freezing a scary "broker gone" corpse.
|
|
23
22
|
// `dead`/`canceled` keep the corpse.
|
|
24
23
|
let finalizedDone = false;
|
|
24
|
+
let stopped = false;
|
|
25
|
+
let resolveStopped = () => { };
|
|
26
|
+
let retryTimer;
|
|
27
|
+
let cancelRetry;
|
|
28
|
+
const stoppedSignal = new Promise((resolve) => {
|
|
29
|
+
resolveStopped = resolve;
|
|
30
|
+
});
|
|
31
|
+
const waitForRetry = (ms) => {
|
|
32
|
+
if (stopped)
|
|
33
|
+
return Promise.resolve(false);
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
const settle = (elapsed) => {
|
|
36
|
+
retryTimer = undefined;
|
|
37
|
+
cancelRetry = undefined;
|
|
38
|
+
resolve(elapsed);
|
|
39
|
+
};
|
|
40
|
+
retryTimer = setTimeout(() => settle(true), ms);
|
|
41
|
+
cancelRetry = () => {
|
|
42
|
+
if (retryTimer !== undefined)
|
|
43
|
+
clearTimeout(retryTimer);
|
|
44
|
+
settle(false);
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
};
|
|
25
48
|
// The handshake the viewer sends on connect AND on every successful redial.
|
|
26
49
|
// After a broker refresh / crash-revive the fresh process has no memory of
|
|
27
50
|
// this client, so re-`hello` resumes the role chosen at the original attach
|
|
@@ -51,7 +74,7 @@ export function createReconnect(ctx, hooks) {
|
|
|
51
74
|
hooks.setNotice('↻ node refreshing — reconnecting…', { sticky: true });
|
|
52
75
|
let delay = 200;
|
|
53
76
|
try {
|
|
54
|
-
while (!hooks.isTornDown()) {
|
|
77
|
+
while (!stopped && !hooks.isTornDown()) {
|
|
55
78
|
// The row read is advisory: a transient canvas-source error must never
|
|
56
79
|
// kill the supervisor loop — treat it as "keep trying" and read again
|
|
57
80
|
// on the next attempt. `canvasSource` is genuinely remote-backed under
|
|
@@ -81,7 +104,12 @@ export function createReconnect(ctx, hooks) {
|
|
|
81
104
|
hooks.onEnterDormancy();
|
|
82
105
|
hooks.setNotice(dormant ? '' : '↻ node refreshing — reconnecting…', { sticky: !dormant });
|
|
83
106
|
try {
|
|
84
|
-
await
|
|
107
|
+
const redialed = await Promise.race([
|
|
108
|
+
socket.redial().then(() => true),
|
|
109
|
+
stoppedSignal.then(() => false),
|
|
110
|
+
]);
|
|
111
|
+
if (!redialed || stopped || hooks.isTornDown())
|
|
112
|
+
return;
|
|
85
113
|
sendHello();
|
|
86
114
|
viewerDormant = false;
|
|
87
115
|
hooks.setNotice('');
|
|
@@ -89,7 +117,9 @@ export function createReconnect(ctx, hooks) {
|
|
|
89
117
|
}
|
|
90
118
|
catch {
|
|
91
119
|
// ENOENT (socket not recreated yet) / ECONNREFUSED (listen not ready) → retry.
|
|
92
|
-
await
|
|
120
|
+
const elapsed = await waitForRetry(dormant ? RECONNECT_DORMANT_DELAY_MS : Math.min(delay, RECONNECT_ACTIVE_DELAY_CAP_MS));
|
|
121
|
+
if (!elapsed)
|
|
122
|
+
return;
|
|
93
123
|
delay *= 2;
|
|
94
124
|
}
|
|
95
125
|
}
|
|
@@ -100,7 +130,7 @@ export function createReconnect(ctx, hooks) {
|
|
|
100
130
|
// latch eats every future close event and hangs the viewer forever).
|
|
101
131
|
reconnecting = false;
|
|
102
132
|
}
|
|
103
|
-
if (!hooks.isTornDown())
|
|
133
|
+
if (!stopped && !hooks.isTornDown())
|
|
104
134
|
hooks.teardown(finalizedDone ? 'node-done' : 'broker-gone');
|
|
105
135
|
};
|
|
106
136
|
const install = () => {
|
|
@@ -123,5 +153,12 @@ export function createReconnect(ctx, hooks) {
|
|
|
123
153
|
isDormant: () => viewerDormant,
|
|
124
154
|
lastSocketError: () => lastSocketError,
|
|
125
155
|
install,
|
|
156
|
+
stop: () => {
|
|
157
|
+
if (stopped)
|
|
158
|
+
return;
|
|
159
|
+
stopped = true;
|
|
160
|
+
cancelRetry?.();
|
|
161
|
+
resolveStopped();
|
|
162
|
+
},
|
|
126
163
|
};
|
|
127
164
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Component } from '@earendil-works/pi-tui';
|
|
2
|
+
import type { SurfaceComponent } from '../../surfaces/host.js';
|
|
3
|
+
/**
|
|
4
|
+
* The opaque rectangle wrapper used for every viewer surface. Rows are read
|
|
5
|
+
* and pushed inside the render pass: a surface hidden beneath another surface
|
|
6
|
+
* is not rendered, and therefore never observes a stale height when restored.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SurfaceFrame implements Component {
|
|
9
|
+
private readonly surface;
|
|
10
|
+
private readonly focusTarget;
|
|
11
|
+
private readonly getRows;
|
|
12
|
+
private _focused;
|
|
13
|
+
constructor(surface: SurfaceComponent, focusTarget: Component, getRows: () => number);
|
|
14
|
+
get focused(): boolean;
|
|
15
|
+
set focused(value: boolean);
|
|
16
|
+
get wantsKeyRelease(): boolean;
|
|
17
|
+
render(width: number): string[];
|
|
18
|
+
handleInput(data: string): void;
|
|
19
|
+
invalidate(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { CURSOR_MARKER, isFocusable, sliceByColumn, truncateToWidth, visibleWidth, } from '@earendil-works/pi-tui';
|
|
2
|
+
import { reportInvariant as report } from './invariant.js';
|
|
3
|
+
/**
|
|
4
|
+
* The opaque rectangle wrapper used for every viewer surface. Rows are read
|
|
5
|
+
* and pushed inside the render pass: a surface hidden beneath another surface
|
|
6
|
+
* is not rendered, and therefore never observes a stale height when restored.
|
|
7
|
+
*/
|
|
8
|
+
export class SurfaceFrame {
|
|
9
|
+
surface;
|
|
10
|
+
focusTarget;
|
|
11
|
+
getRows;
|
|
12
|
+
_focused = false;
|
|
13
|
+
constructor(surface, focusTarget, getRows) {
|
|
14
|
+
this.surface = surface;
|
|
15
|
+
this.focusTarget = focusTarget;
|
|
16
|
+
this.getRows = getRows;
|
|
17
|
+
}
|
|
18
|
+
get focused() {
|
|
19
|
+
return this._focused;
|
|
20
|
+
}
|
|
21
|
+
set focused(value) {
|
|
22
|
+
this._focused = value;
|
|
23
|
+
if (isFocusable(this.focusTarget))
|
|
24
|
+
this.focusTarget.focused = value;
|
|
25
|
+
}
|
|
26
|
+
get wantsKeyRelease() {
|
|
27
|
+
return this.focusTarget.wantsKeyRelease ?? this.surface.wantsKeyRelease ?? false;
|
|
28
|
+
}
|
|
29
|
+
render(width) {
|
|
30
|
+
const rows = Math.max(0, Math.floor(this.getRows()));
|
|
31
|
+
const columns = Math.max(0, Math.floor(width));
|
|
32
|
+
this.surface.setRows(rows);
|
|
33
|
+
const rendered = this.surface.render(columns);
|
|
34
|
+
if (rendered.length !== rows) {
|
|
35
|
+
reportInvariant(`surface rendered ${rendered.length} rows; expected ${rows}`);
|
|
36
|
+
}
|
|
37
|
+
const frame = rendered.slice(0, rows).map((line) => {
|
|
38
|
+
if (visibleWidth(line) > columns) {
|
|
39
|
+
reportInvariant(`surface row is ${visibleWidth(line)} cells wide; expected at most ${columns}`);
|
|
40
|
+
return padToWidth(sliceByColumn(line, 0, columns, true), columns);
|
|
41
|
+
}
|
|
42
|
+
return padToWidth(line, columns);
|
|
43
|
+
});
|
|
44
|
+
while (frame.length < rows)
|
|
45
|
+
frame.push(' '.repeat(columns));
|
|
46
|
+
const markerCount = countMarkers(frame);
|
|
47
|
+
if (markerCount > 1) {
|
|
48
|
+
reportInvariant(`surface frame contains ${markerCount} CURSOR_MARKER sequences; expected at most one`);
|
|
49
|
+
return frame.map(stripCursorMarkers);
|
|
50
|
+
}
|
|
51
|
+
return frame;
|
|
52
|
+
}
|
|
53
|
+
handleInput(data) {
|
|
54
|
+
const handler = this.focusTarget.handleInput ?? this.surface.handleInput;
|
|
55
|
+
handler?.call(this.focusTarget.handleInput === undefined ? this.surface : this.focusTarget, data);
|
|
56
|
+
}
|
|
57
|
+
invalidate() {
|
|
58
|
+
this.surface.invalidate();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function padToWidth(line, width) {
|
|
62
|
+
return truncateToWidth(line, width, '', true);
|
|
63
|
+
}
|
|
64
|
+
function countMarkers(lines) {
|
|
65
|
+
return lines.reduce((count, line) => count + line.split(CURSOR_MARKER).length - 1, 0);
|
|
66
|
+
}
|
|
67
|
+
function stripCursorMarkers(line) {
|
|
68
|
+
return line.split(CURSOR_MARKER).join('');
|
|
69
|
+
}
|
|
70
|
+
/** Invariants are reported without taking down the attached viewer. */
|
|
71
|
+
function reportInvariant(message) {
|
|
72
|
+
report('surface-frame', message);
|
|
73
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type Component, type TUI } from '@earendil-works/pi-tui';
|
|
2
|
+
import type { SurfaceComponent, SurfaceHandle, SurfaceHost } from '../../surfaces/host.js';
|
|
3
|
+
import type { MouseReporting } from './mouse.js';
|
|
4
|
+
/** The status line's notice options, which the host preserves on both paths. */
|
|
5
|
+
export interface NoticeOptions {
|
|
6
|
+
/** Keep the notice up until it is replaced or cleared, with no auto-clear. */
|
|
7
|
+
sticky?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ViewerSurfaceHostOptions {
|
|
10
|
+
tui: TUI;
|
|
11
|
+
mouse: MouseReporting;
|
|
12
|
+
/** The host's assigned row count; surfaces never read terminal geometry. */
|
|
13
|
+
rows: () => number;
|
|
14
|
+
/** Fallback notice sink used when no surface is mounted. */
|
|
15
|
+
statusNotice: (text: string, opts?: NoticeOptions) => void;
|
|
16
|
+
/** Styling supplied by the viewer's status-line palette. */
|
|
17
|
+
formatNotice: (text: string) => string;
|
|
18
|
+
noticeMs: number;
|
|
19
|
+
capabilities: SurfaceHost['capabilities'];
|
|
20
|
+
selfPane?: string;
|
|
21
|
+
}
|
|
22
|
+
/** The viewer's one host for full-pane surfaces. */
|
|
23
|
+
export declare class ViewerSurfaceHost implements SurfaceHost {
|
|
24
|
+
readonly capabilities: SurfaceHost['capabilities'];
|
|
25
|
+
private readonly tui;
|
|
26
|
+
private readonly mouse;
|
|
27
|
+
private readonly getRows;
|
|
28
|
+
private readonly statusNotice;
|
|
29
|
+
private readonly formatNotice;
|
|
30
|
+
private readonly noticeMs;
|
|
31
|
+
private readonly selfPane;
|
|
32
|
+
private readonly stack;
|
|
33
|
+
private noticeOverlay;
|
|
34
|
+
private noticeTimer;
|
|
35
|
+
constructor(options: ViewerSurfaceHostOptions);
|
|
36
|
+
mount(component: SurfaceComponent, opts?: {
|
|
37
|
+
focus?: Component;
|
|
38
|
+
}): SurfaceHandle;
|
|
39
|
+
/**
|
|
40
|
+
* The one visible notice channel. Surfaces call this with a message only; the
|
|
41
|
+
* viewer routes its whole notice verb through here, so both status-line
|
|
42
|
+
* semantics survive a mounted surface: an empty string clears the current
|
|
43
|
+
* notice rather than painting a bare warning icon, and `sticky` suppresses the
|
|
44
|
+
* auto-clear for a condition that is not time-bounded (a reconnect loop, an
|
|
45
|
+
* armed confirmation).
|
|
46
|
+
*/
|
|
47
|
+
notice(text: string, opts?: NoticeOptions): void;
|
|
48
|
+
suspendForChild(): () => void;
|
|
49
|
+
focusNode(nodeId: string): Promise<boolean>;
|
|
50
|
+
pickReviewFile(spec: {
|
|
51
|
+
candidates: readonly string[];
|
|
52
|
+
cwd: string;
|
|
53
|
+
title?: string;
|
|
54
|
+
}): Promise<string | null>;
|
|
55
|
+
/** Offer wheel input to the topmost surface only. */
|
|
56
|
+
handleWheel(direction: 'up' | 'down', lines: number, column: number): boolean;
|
|
57
|
+
/** Whether a full-pane surface currently owns input. */
|
|
58
|
+
hasFullPaneSurface(): boolean;
|
|
59
|
+
/** Close the whole stack before the viewer tears down its TUI. */
|
|
60
|
+
closeAll(): void;
|
|
61
|
+
private closeEntry;
|
|
62
|
+
private disposeNotice;
|
|
63
|
+
private disposeNoticeOverlay;
|
|
64
|
+
}
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { truncateToWidth, } from '@earendil-works/pi-tui';
|
|
2
|
+
import { cliClient } from '../../../commands/api-client.js';
|
|
3
|
+
import { focusViewer } from '../../../commands/node.js';
|
|
4
|
+
import { daemonErrorMessage } from '../../inbox/resolve.js';
|
|
5
|
+
import { buildFileReviewPicker } from '../overlays/file-review.js';
|
|
6
|
+
import { reportInvariant as report } from './invariant.js';
|
|
7
|
+
import { SurfaceFrame } from './surface-frame.js';
|
|
8
|
+
const SURFACE_OVERLAY_OPTIONS = {
|
|
9
|
+
anchor: 'top-left',
|
|
10
|
+
width: '100%',
|
|
11
|
+
maxHeight: '100%',
|
|
12
|
+
margin: 0,
|
|
13
|
+
};
|
|
14
|
+
const NOTICE_OVERLAY_OPTIONS = {
|
|
15
|
+
anchor: 'top-left',
|
|
16
|
+
width: '100%',
|
|
17
|
+
margin: 0,
|
|
18
|
+
nonCapturing: true,
|
|
19
|
+
};
|
|
20
|
+
/** The viewer's one host for full-pane surfaces. */
|
|
21
|
+
export class ViewerSurfaceHost {
|
|
22
|
+
capabilities;
|
|
23
|
+
tui;
|
|
24
|
+
mouse;
|
|
25
|
+
getRows;
|
|
26
|
+
statusNotice;
|
|
27
|
+
formatNotice;
|
|
28
|
+
noticeMs;
|
|
29
|
+
selfPane;
|
|
30
|
+
stack = [];
|
|
31
|
+
noticeOverlay;
|
|
32
|
+
noticeTimer;
|
|
33
|
+
constructor(options) {
|
|
34
|
+
this.tui = options.tui;
|
|
35
|
+
this.mouse = options.mouse;
|
|
36
|
+
this.getRows = options.rows;
|
|
37
|
+
this.statusNotice = options.statusNotice;
|
|
38
|
+
this.formatNotice = options.formatNotice;
|
|
39
|
+
this.noticeMs = options.noticeMs;
|
|
40
|
+
this.capabilities = options.capabilities;
|
|
41
|
+
this.selfPane = options.selfPane;
|
|
42
|
+
}
|
|
43
|
+
mount(component, opts) {
|
|
44
|
+
this.disposeNotice();
|
|
45
|
+
const frame = new SurfaceFrame(component, opts?.focus ?? component, this.getRows);
|
|
46
|
+
const overlay = this.tui.showOverlay(frame, SURFACE_OVERLAY_OPTIONS);
|
|
47
|
+
const entry = { component, frame, overlay, cleanup: [], closed: false, closing: false };
|
|
48
|
+
const previous = this.stack[this.stack.length - 1];
|
|
49
|
+
if (previous)
|
|
50
|
+
previous.overlay.setHidden(true);
|
|
51
|
+
this.stack.push(entry);
|
|
52
|
+
return {
|
|
53
|
+
close: () => this.closeEntry(entry, true),
|
|
54
|
+
invalidate: () => {
|
|
55
|
+
if (!entry.closed && this.stack[this.stack.length - 1] === entry)
|
|
56
|
+
this.tui.requestRender();
|
|
57
|
+
},
|
|
58
|
+
onClose: (fn) => {
|
|
59
|
+
if (entry.closed || entry.closing) {
|
|
60
|
+
reportInvariant('onClose registered after surface close');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
entry.cleanup.push(fn);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The one visible notice channel. Surfaces call this with a message only; the
|
|
69
|
+
* viewer routes its whole notice verb through here, so both status-line
|
|
70
|
+
* semantics survive a mounted surface: an empty string clears the current
|
|
71
|
+
* notice rather than painting a bare warning icon, and `sticky` suppresses the
|
|
72
|
+
* auto-clear for a condition that is not time-bounded (a reconnect loop, an
|
|
73
|
+
* armed confirmation).
|
|
74
|
+
*/
|
|
75
|
+
notice(text, opts) {
|
|
76
|
+
this.disposeNotice();
|
|
77
|
+
if (this.stack.length === 0) {
|
|
78
|
+
this.statusNotice(text, opts);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (text === '')
|
|
82
|
+
return;
|
|
83
|
+
const notice = new NoticeOverlay(() => this.formatNotice(text));
|
|
84
|
+
this.noticeOverlay = this.tui.showOverlay(notice, NOTICE_OVERLAY_OPTIONS);
|
|
85
|
+
if (opts?.sticky !== true && this.noticeMs > 0) {
|
|
86
|
+
this.noticeTimer = setTimeout(() => {
|
|
87
|
+
this.noticeTimer = undefined;
|
|
88
|
+
this.disposeNoticeOverlay();
|
|
89
|
+
}, this.noticeMs);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
suspendForChild() {
|
|
93
|
+
this.tui.stop();
|
|
94
|
+
return () => {
|
|
95
|
+
this.tui.start();
|
|
96
|
+
this.mouse.reassert();
|
|
97
|
+
this.tui.invalidate();
|
|
98
|
+
this.tui.requestRender(true);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async focusNode(nodeId) {
|
|
102
|
+
if (!this.capabilities.canFocusNode || this.selfPane === undefined || this.selfPane === '') {
|
|
103
|
+
this.notice('Focusing a node needs a local viewer in tmux');
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const node = await cliClient().getNode(nodeId);
|
|
108
|
+
const result = await focusViewer(nodeId, {
|
|
109
|
+
pane: this.selfPane,
|
|
110
|
+
cwd: node.cwd,
|
|
111
|
+
name: node.name,
|
|
112
|
+
});
|
|
113
|
+
if (!result.focused)
|
|
114
|
+
this.notice('Could not open that node’s viewer');
|
|
115
|
+
return result.focused;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
this.notice(daemonErrorMessage(error));
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
pickReviewFile(spec) {
|
|
123
|
+
return new Promise((resolve) => {
|
|
124
|
+
let handle;
|
|
125
|
+
let settled = false;
|
|
126
|
+
const settle = (value) => {
|
|
127
|
+
if (settled)
|
|
128
|
+
return;
|
|
129
|
+
settled = true;
|
|
130
|
+
resolve(value);
|
|
131
|
+
handle.close();
|
|
132
|
+
};
|
|
133
|
+
const picker = buildFileReviewPicker(spec.candidates, spec.cwd, (file) => settle(file), () => settle(null), (message) => this.notice(message));
|
|
134
|
+
handle = this.mount(titled(picker.component, spec.title), { focus: picker.focus });
|
|
135
|
+
handle.onClose(() => settle(null));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/** Offer wheel input to the topmost surface only. */
|
|
139
|
+
handleWheel(direction, lines, column) {
|
|
140
|
+
return this.stack[this.stack.length - 1]?.component.handleWheel?.(direction, lines, column) ?? false;
|
|
141
|
+
}
|
|
142
|
+
/** Whether a full-pane surface currently owns input. */
|
|
143
|
+
hasFullPaneSurface() {
|
|
144
|
+
return this.stack.length > 0;
|
|
145
|
+
}
|
|
146
|
+
/** Close the whole stack before the viewer tears down its TUI. */
|
|
147
|
+
closeAll() {
|
|
148
|
+
const bottom = this.stack[0];
|
|
149
|
+
if (bottom)
|
|
150
|
+
this.closeEntry(bottom, false);
|
|
151
|
+
this.disposeNotice();
|
|
152
|
+
}
|
|
153
|
+
closeEntry(entry, restore) {
|
|
154
|
+
if (entry.closed || entry.closing)
|
|
155
|
+
return;
|
|
156
|
+
const index = this.stack.indexOf(entry);
|
|
157
|
+
if (index === -1) {
|
|
158
|
+
entry.closed = true;
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
entry.closing = true;
|
|
162
|
+
// Closing a parent owns every descendant. Close top-down, without
|
|
163
|
+
// restoring an intermediate surface that is about to be closed too.
|
|
164
|
+
while (this.stack.indexOf(entry) !== -1) {
|
|
165
|
+
const currentIndex = this.stack.indexOf(entry);
|
|
166
|
+
const child = this.stack[currentIndex + 1];
|
|
167
|
+
if (!child)
|
|
168
|
+
break;
|
|
169
|
+
this.closeEntry(child, false);
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
entry.overlay.hide();
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
reportInvariant(`surface overlay hide failed: ${errorMessage(error)}`);
|
|
176
|
+
}
|
|
177
|
+
for (const cleanup of entry.cleanup) {
|
|
178
|
+
try {
|
|
179
|
+
const result = cleanup();
|
|
180
|
+
if (result && typeof result.then === 'function') {
|
|
181
|
+
void result.catch((error) => reportInvariant(`surface cleanup failed: ${errorMessage(error)}`));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
reportInvariant(`surface cleanup failed: ${errorMessage(error)}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
entry.cleanup.length = 0;
|
|
189
|
+
entry.closed = true;
|
|
190
|
+
entry.closing = false;
|
|
191
|
+
const currentIndex = this.stack.indexOf(entry);
|
|
192
|
+
if (currentIndex !== -1)
|
|
193
|
+
this.stack.splice(currentIndex, 1);
|
|
194
|
+
if (restore) {
|
|
195
|
+
// A notice belongs to the surface it was raised over, so it goes when that
|
|
196
|
+
// surface does — including when the stack empties and no lower surface is
|
|
197
|
+
// left to restore, which would otherwise strand the overlay above the
|
|
198
|
+
// bare cockpit.
|
|
199
|
+
this.disposeNotice();
|
|
200
|
+
const top = this.stack[this.stack.length - 1];
|
|
201
|
+
if (top)
|
|
202
|
+
top.overlay.setHidden(false);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
disposeNotice() {
|
|
206
|
+
this.disposeNoticeOverlay();
|
|
207
|
+
if (this.noticeTimer !== undefined) {
|
|
208
|
+
clearTimeout(this.noticeTimer);
|
|
209
|
+
this.noticeTimer = undefined;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
disposeNoticeOverlay() {
|
|
213
|
+
this.noticeOverlay?.hide();
|
|
214
|
+
this.noticeOverlay = undefined;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
class NoticeOverlay {
|
|
218
|
+
text;
|
|
219
|
+
constructor(text) {
|
|
220
|
+
this.text = text;
|
|
221
|
+
}
|
|
222
|
+
render(width) {
|
|
223
|
+
return [truncateToWidth(this.text(), Math.max(0, width), '', true)];
|
|
224
|
+
}
|
|
225
|
+
invalidate() { }
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Apply an optional picker title without giving the host a second picker. A
|
|
229
|
+
* surface owes the host exactly its assigned rows, so this fills the rectangle
|
|
230
|
+
* the picker's natural height leaves short instead of handing the frame a
|
|
231
|
+
* three-row component and tripping its invariant on every render.
|
|
232
|
+
*/
|
|
233
|
+
function titled(component, title) {
|
|
234
|
+
let rows = 0;
|
|
235
|
+
return {
|
|
236
|
+
setRows: (value) => {
|
|
237
|
+
rows = Math.max(0, Math.floor(value));
|
|
238
|
+
},
|
|
239
|
+
render: (width) => {
|
|
240
|
+
const lines = component.render(width);
|
|
241
|
+
const body = title === undefined ? lines : [truncateToWidth(title, Math.max(0, width), '', true), ...lines.slice(1)];
|
|
242
|
+
const frame = body.slice(0, rows);
|
|
243
|
+
while (frame.length < rows)
|
|
244
|
+
frame.push('');
|
|
245
|
+
return frame;
|
|
246
|
+
},
|
|
247
|
+
invalidate: () => component.invalidate(),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function reportInvariant(message) {
|
|
251
|
+
report('surface-host', message);
|
|
252
|
+
}
|
|
253
|
+
function errorMessage(error) {
|
|
254
|
+
return error instanceof Error ? error.message : String(error);
|
|
255
|
+
}
|