@north-light/crouter 0.3.318 → 0.3.320
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 +0 -3
- package/dist/api/client.js +2 -912
- package/dist/api/dto/attach.js +0 -13
- package/dist/api/dto/bash-jobs.js +1 -9
- package/dist/api/dto/broker-ops.js +0 -6
- package/dist/api/dto/broker.js +0 -20
- package/dist/api/dto/canvas.js +0 -2
- package/dist/api/dto/chat-inventory.js +0 -11
- package/dist/api/dto/common.js +1 -15
- package/dist/api/dto/config.js +0 -3
- package/dist/api/dto/crons.js +1 -10
- package/dist/api/dto/files.js +0 -7
- package/dist/api/dto/focus.js +0 -10
- package/dist/api/dto/health.js +0 -2
- package/dist/api/dto/human-requests.js +0 -4
- package/dist/api/dto/human.js +0 -4
- package/dist/api/dto/inbox.js +0 -4
- package/dist/api/dto/lifecycle.js +0 -3
- package/dist/api/dto/mail.js +0 -1
- package/dist/api/dto/memory.js +0 -6
- package/dist/api/dto/messages.js +0 -2
- package/dist/api/dto/model-config.js +0 -1
- package/dist/api/dto/modelauth.js +0 -4
- package/dist/api/dto/node-outcomes.js +0 -2
- package/dist/api/dto/nodes.js +0 -3
- package/dist/api/dto/profiles.js +1 -4
- package/dist/api/dto/recovery.js +0 -1
- package/dist/api/dto/reports.js +0 -2
- package/dist/api/dto/review-comments.js +0 -5
- package/dist/api/dto/reviews.js +0 -5
- package/dist/api/dto/subscriptions.js +0 -2
- package/dist/api/dto/worktree.js +0 -6
- package/dist/api/errors.js +1 -40
- package/dist/api/index.js +1 -33
- package/dist/api/plugin-manifest-schema.js +0 -23
- package/dist/api/routes.js +1 -147
- package/dist/build-root.js +1 -198
- package/dist/cli.js +3 -99
- package/dist/clients/attach/ansi-cells.js +1 -137
- package/dist/clients/attach/chrome/bash-jobs.js +1 -31
- package/dist/clients/attach/chrome/canvas-panels.js +1 -194
- package/dist/clients/attach/chrome/completion-bell.js +1 -89
- package/dist/clients/attach/chrome/cron-wait.js +1 -34
- package/dist/clients/attach/chrome/git-info.js +2 -44
- package/dist/clients/attach/chrome/header.js +1 -30
- package/dist/clients/attach/chrome/inbox-strip.js +1 -199
- package/dist/clients/attach/chrome/recap.js +1 -19
- package/dist/clients/attach/chrome/review-wait.js +1 -22
- package/dist/clients/attach/chrome/roster.js +4 -275
- package/dist/clients/attach/chrome/status-line.js +1 -117
- package/dist/clients/attach/chrome/ticket-panel.js +1 -280
- package/dist/clients/attach/chrome/widgets.js +1 -51
- package/dist/clients/attach/command.js +1 -107
- package/dist/clients/attach/config.js +1 -274
- package/dist/clients/attach/input/capabilities.js +1 -104
- package/dist/clients/attach/input/clipboard-image.js +3 -220
- package/dist/clients/attach/input/completion-frecency.js +1 -141
- package/dist/clients/attach/input/controller.js +7 -377
- package/dist/clients/attach/input/overlay-owner.js +1 -199
- package/dist/clients/attach/input/ref-autocomplete.js +2 -176
- package/dist/clients/attach/input/titled-editor.js +4 -859
- package/dist/clients/attach/overlays/auth.js +2 -271
- package/dist/clients/attach/overlays/dialogs.js +2 -102
- package/dist/clients/attach/overlays/file-review.js +2 -128
- package/dist/clients/attach/overlays/graph.js +1 -661
- package/dist/clients/attach/overlays/help.js +1 -211
- package/dist/clients/attach/overlays/mcp.js +1 -302
- package/dist/clients/attach/overlays/pickers.js +1 -163
- package/dist/clients/attach/render/activity-slot.js +1 -13
- package/dist/clients/attach/render/assistant-message.js +1 -56
- package/dist/clients/attach/render/card-presentation.js +5 -218
- package/dist/clients/attach/render/chat-view.js +5 -1708
- package/dist/clients/attach/render/condensed-history.js +1 -60
- package/dist/clients/attach/render/context-message.js +1 -63
- package/dist/clients/attach/render/crtr-output.js +17 -905
- package/dist/clients/attach/render/diagram.js +7 -111
- package/dist/clients/attach/render/edit-diff.js +5 -304
- package/dist/clients/attach/render/glyph-codepoints.js +1 -42
- package/dist/clients/attach/render/group-activity.js +2 -263
- package/dist/clients/attach/render/group-recap.js +1 -152
- package/dist/clients/attach/render/markdown-source.js +5 -266
- package/dist/clients/attach/render/measured-container.js +1 -322
- package/dist/clients/attach/render/page-block.js +1 -183
- package/dist/clients/attach/render/scroll-animation.js +1 -80
- package/dist/clients/attach/render/tool-calls.js +3 -361
- package/dist/clients/attach/render/transcript-copy.js +2 -81
- package/dist/clients/attach/render/transcript-search.js +1 -152
- package/dist/clients/attach/render/viewport.js +1 -184
- package/dist/clients/attach/session/banner.js +1 -29
- package/dist/clients/attach/session/bindings.js +1 -71
- package/dist/clients/attach/session/chrome-refresh.js +1 -94
- package/dist/clients/attach/session/connection.js +1 -186
- package/dist/clients/attach/session/context.js +0 -16
- package/dist/clients/attach/session/editor-frame.js +1 -142
- package/dist/clients/attach/session/editor-inventory.js +6 -160
- package/dist/clients/attach/session/file-links.js +1 -68
- package/dist/clients/attach/session/focus-events.js +1 -12
- package/dist/clients/attach/session/frame.js +1 -214
- package/dist/clients/attach/session/frames.js +1 -188
- package/dist/clients/attach/session/identity.js +1 -26
- package/dist/clients/attach/session/input-wiring.js +1 -140
- package/dist/clients/attach/session/invariant.js +1 -15
- package/dist/clients/attach/session/keys.js +1 -77
- package/dist/clients/attach/session/layout.js +1 -59
- package/dist/clients/attach/session/mouse.js +1 -78
- package/dist/clients/attach/session/pane-focus.js +1 -42
- package/dist/clients/attach/session/pane-tag.js +1 -112
- package/dist/clients/attach/session/pi-assets.js +1 -24
- package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
- package/dist/clients/attach/session/profile-files.js +1 -228
- package/dist/clients/attach/session/reconnect.js +1 -175
- package/dist/clients/attach/session/selection.js +3 -108
- package/dist/clients/attach/session/state-sync.js +1 -67
- package/dist/clients/attach/session/surface-frame.js +1 -73
- package/dist/clients/attach/session/surface-host.js +1 -255
- package/dist/clients/attach/session/teardown.js +5 -94
- package/dist/clients/attach/session/transcript-search.js +3 -151
- package/dist/clients/attach/session/whip-achievements.js +2 -145
- package/dist/clients/attach/session/whip.js +1 -362
- package/dist/clients/attach/slash/dispatch.js +1 -706
- package/dist/clients/attach/slash/prompt-preview.js +1 -121
- package/dist/clients/attach/viewer.js +441 -441
- package/dist/clients/conversation/projection.js +1 -324
- package/dist/clients/conversation/submit.js +1 -51
- package/dist/clients/inbox/controller.js +1 -701
- package/dist/clients/inbox/dto-adapt.js +1 -93
- package/dist/clients/inbox/layout.js +1 -9
- package/dist/clients/inbox/page-adapter.js +1 -55
- package/dist/clients/inbox/resolve.js +1 -35
- package/dist/clients/inbox/review/anchors.js +1 -89
- package/dist/clients/inbox/review/comments-client.js +1 -98
- package/dist/clients/inbox/review/companion-pane.js +1 -82
- package/dist/clients/inbox/review/document-surface.js +2 -1188
- package/dist/clients/inbox/review/frame.js +1 -216
- package/dist/clients/inbox/review/keys.js +1 -123
- package/dist/clients/inbox/review/launch.js +1 -151
- package/dist/clients/inbox/review/live-source.js +1 -160
- package/dist/clients/inbox/review/nvim.js +1 -44
- package/dist/clients/inbox/review/remap.js +1 -157
- package/dist/clients/inbox/review/review-client.js +1 -123
- package/dist/clients/inbox/review/roundtrip.js +3 -36
- package/dist/clients/inbox/review/state.js +4 -315
- package/dist/clients/inbox/review-adapter.js +1 -43
- package/dist/clients/inbox/surface.js +1 -152
- package/dist/clients/inbox/tui/ansi.js +3 -321
- package/dist/clients/inbox/tui/input.js +5 -392
- package/dist/clients/inbox/tui/keys.js +1 -104
- package/dist/clients/inbox/tui/page-body.js +1 -66
- package/dist/clients/inbox/tui/panel.js +1 -84
- package/dist/clients/inbox/tui/render.js +2 -368
- package/dist/clients/inbox/tui/slots.js +3 -134
- package/dist/clients/inbox/tui/types.js +0 -1
- package/dist/clients/inbox/tui.js +1 -86
- package/dist/clients/surfaces/host.js +0 -1
- package/dist/commands/api-client.js +4 -290
- package/dist/commands/attention.js +1 -215
- package/dist/commands/canvas-browse.js +1 -70
- package/dist/commands/canvas-config.js +2 -192
- package/dist/commands/canvas-history/grep.js +7 -85
- package/dist/commands/canvas-history/read.js +3 -50
- package/dist/commands/canvas-history/search.js +10 -99
- package/dist/commands/canvas-history/shared.js +1 -139
- package/dist/commands/canvas-history/stats.js +6 -68
- package/dist/commands/canvas-history.js +1 -32
- package/dist/commands/canvas-issue.js +14 -149
- package/dist/commands/canvas-prune.js +1 -108
- package/dist/commands/canvas-roster.js +1 -69
- package/dist/commands/canvas-snapshot.js +1 -34
- package/dist/commands/canvas-use.js +1 -61
- package/dist/commands/canvas.js +1 -49
- package/dist/commands/chord.js +1 -241
- package/dist/commands/cron.js +11 -534
- package/dist/commands/dashboard.js +1 -85
- package/dist/commands/human/components.js +3 -77
- package/dist/commands/human/feedback.js +1 -112
- package/dist/commands/human/prompts.js +1 -331
- package/dist/commands/human/queue.js +1 -191
- package/dist/commands/human/request.js +1 -266
- package/dist/commands/human/review.js +1 -288
- package/dist/commands/human/shared.js +1 -67
- package/dist/commands/human.js +4 -60
- package/dist/commands/memory/delete.js +1 -100
- package/dist/commands/memory/edit.js +21 -219
- package/dist/commands/memory/find.js +2 -244
- package/dist/commands/memory/history.js +5 -199
- package/dist/commands/memory/lint.js +1 -107
- package/dist/commands/memory/list.js +1 -142
- package/dist/commands/memory/move.js +1 -223
- package/dist/commands/memory/origin.js +1 -130
- package/dist/commands/memory/read.js +6 -232
- package/dist/commands/memory/shared.js +12 -802
- package/dist/commands/memory/write.js +13 -235
- package/dist/commands/memory.js +1 -30
- package/dist/commands/node/bash.js +5 -245
- package/dist/commands/node/create.js +3 -332
- package/dist/commands/node/inspect.js +12 -300
- package/dist/commands/node/lifecycle.js +2 -453
- package/dist/commands/node/message.js +1 -161
- package/dist/commands/node/outcome.js +4 -134
- package/dist/commands/node/pyramid.js +2 -79
- package/dist/commands/node/subscription.js +1 -78
- package/dist/commands/node/wait.js +7 -163
- package/dist/commands/node-context.js +2 -159
- package/dist/commands/node-inspect-artifacts.js +8 -109
- package/dist/commands/node-lifecycle-revive.js +1 -217
- package/dist/commands/node-snapshot.js +1 -37
- package/dist/commands/node-transcript.js +1 -62
- package/dist/commands/node-worktree.js +1 -138
- package/dist/commands/node.js +1 -29
- package/dist/commands/pkg/browse/actions.js +1 -198
- package/dist/commands/pkg/browse/catalog.js +1 -466
- package/dist/commands/pkg/browse/command-view.js +1 -191
- package/dist/commands/pkg/browse/detail-panel.js +1 -402
- package/dist/commands/pkg/browse/doc-view.js +1 -89
- package/dist/commands/pkg/browse/list-panel.js +2 -168
- package/dist/commands/pkg/browse/model.js +1 -36
- package/dist/commands/pkg/browse/shell.js +1 -640
- package/dist/commands/pkg/browse.js +1 -27
- package/dist/commands/pkg/market-inspect.js +1 -141
- package/dist/commands/pkg/market-manage.js +1 -327
- package/dist/commands/pkg/market.js +1 -14
- package/dist/commands/pkg/plugin-inspect.js +1 -168
- package/dist/commands/pkg/plugin-manage.js +17 -1109
- package/dist/commands/pkg/plugin.js +1 -14
- package/dist/commands/pkg/shared.js +1 -62
- package/dist/commands/pkg.js +1 -21
- package/dist/commands/profile/default.js +1 -139
- package/dist/commands/profile/delete.js +1 -66
- package/dist/commands/profile/env.js +3 -188
- package/dist/commands/profile/kind.js +2 -35
- package/dist/commands/profile/list.js +1 -43
- package/dist/commands/profile/meta.js +1 -67
- package/dist/commands/profile/new.js +1 -115
- package/dist/commands/profile/pause.js +1 -59
- package/dist/commands/profile/project.js +1 -113
- package/dist/commands/profile/rename.js +1 -38
- package/dist/commands/profile/show.js +1 -52
- package/dist/commands/profile.js +1 -35
- package/dist/commands/push.js +9 -265
- package/dist/commands/revive.js +10 -181
- package/dist/commands/surface/node/cycle.js +1 -83
- package/dist/commands/surface/node/focus.js +1 -81
- package/dist/commands/surface/node/id.js +1 -38
- package/dist/commands/surface/node/pin.js +1 -42
- package/dist/commands/surface/node/placement.js +1 -134
- package/dist/commands/surface-edit.js +1 -157
- package/dist/commands/surface-inbox.js +1 -98
- package/dist/commands/surface-inspect.js +1 -39
- package/dist/commands/surface-node.js +1 -19
- package/dist/commands/surface-reload.js +2 -134
- package/dist/commands/surface-tmux-spread.js +1 -214
- package/dist/commands/surface.js +1 -28
- package/dist/commands/sys/branch.js +1 -19
- package/dist/commands/sys/config.js +1 -353
- package/dist/commands/sys/context/admin/actions.js +2 -246
- package/dist/commands/sys/context/admin/detail-panel.js +1 -247
- package/dist/commands/sys/context/admin/docs-panel.js +1 -191
- package/dist/commands/sys/context/admin/list-view.js +1 -183
- package/dist/commands/sys/context/admin/model.js +1 -229
- package/dist/commands/sys/context/admin/rail-panel.js +1 -227
- package/dist/commands/sys/context/admin/read-view.js +2 -194
- package/dist/commands/sys/context/admin/shell.js +1 -910
- package/dist/commands/sys/context/admin.js +2 -126
- package/dist/commands/sys/context/doc.js +3 -197
- package/dist/commands/sys/context/prompt-review.js +11 -291
- package/dist/commands/sys/context/resolve.js +10 -489
- package/dist/commands/sys/context/sysprompt.js +5 -96
- package/dist/commands/sys/context.js +1 -20
- package/dist/commands/sys/daemon.js +1 -313
- package/dist/commands/sys/doctor.js +1 -617
- package/dist/commands/sys/feedback.js +7 -228
- package/dist/commands/sys/logs.js +3 -129
- package/dist/commands/sys/migrate.js +1 -94
- package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
- package/dist/commands/sys/panels/dependencies-panel.js +1 -80
- package/dist/commands/sys/panels/keybindings-panel.js +1 -703
- package/dist/commands/sys/panels/models-panel.js +1 -1133
- package/dist/commands/sys/panels/plugins-panel.js +1 -80
- package/dist/commands/sys/panels/prefs-panel.js +1 -85
- package/dist/commands/sys/panels/profiles-panel.js +1 -601
- package/dist/commands/sys/panels/provider-panel.js +1 -538
- package/dist/commands/sys/settings-shell.js +1 -400
- package/dist/commands/sys/settings.js +1 -46
- package/dist/commands/sys/setup-core.js +6 -579
- package/dist/commands/sys/setup-settings-runner.js +1 -16
- package/dist/commands/sys/setup-wizard.js +1 -279
- package/dist/commands/sys/setup.js +1 -34
- package/dist/commands/sys/shared.js +1 -81
- package/dist/commands/sys/support/prepare.js +3 -239
- package/dist/commands/sys/support/submit.js +6 -524
- package/dist/commands/sys/support.js +1 -18
- package/dist/commands/sys/sync-deps.js +15 -498
- package/dist/commands/sys/sync-project-guidance.js +4 -481
- package/dist/commands/sys/sync-shared.js +1 -49
- package/dist/commands/sys/sync-skills.js +2 -311
- package/dist/commands/sys/sync.js +1 -18
- package/dist/commands/sys/update.js +1 -147
- package/dist/commands/sys/worktrees.js +5 -53
- package/dist/commands/sys.js +1 -18
- package/dist/core/activity-signal.js +2 -38
- package/dist/core/asset-root.js +1 -18
- package/dist/core/auth-file.js +2 -179
- package/dist/core/auth-interaction.js +3 -94
- package/dist/core/auto-update.js +4 -94
- package/dist/core/bash-guard.js +11 -393
- package/dist/core/bash-jobs.js +7 -411
- package/dist/core/bootstrap.js +2 -53
- package/dist/core/broker-client/client.js +1 -184
- package/dist/core/broker-client/index.js +1 -13
- package/dist/core/broker-client/transport-relay.js +1 -157
- package/dist/core/broker-client/transport-socket.js +1 -179
- package/dist/core/broker-client/transport.js +1 -26
- package/dist/core/canvas/attention.js +1 -47
- package/dist/core/canvas/boot-id.js +1 -26
- package/dist/core/canvas/boot.js +1 -186
- package/dist/core/canvas/browse/app.js +3 -919
- package/dist/core/canvas/browse/model.js +1 -477
- package/dist/core/canvas/browse/pins.js +1 -29
- package/dist/core/canvas/browse/render.js +3 -1055
- package/dist/core/canvas/canvas.js +15 -922
- package/dist/core/canvas/crons.js +11 -481
- package/dist/core/canvas/daemon-owner.js +2 -146
- package/dist/core/canvas/db.js +2 -100
- package/dist/core/canvas/deliveries.js +22 -283
- package/dist/core/canvas/delivery-contract.js +1 -8
- package/dist/core/canvas/executions.js +1 -68
- package/dist/core/canvas/extensions.js +1 -83
- package/dist/core/canvas/focuses.js +1 -77
- package/dist/core/canvas/history.js +24 -860
- package/dist/core/canvas/index.js +1 -15
- package/dist/core/canvas/install-id.js +1 -84
- package/dist/core/canvas/labels.js +1 -43
- package/dist/core/canvas/meta-file.js +1 -89
- package/dist/core/canvas/migrations.js +41 -1150
- package/dist/core/canvas/nav-model.js +1 -231
- package/dist/core/canvas/nav-render.js +1 -260
- package/dist/core/canvas/node-order.js +1 -37
- package/dist/core/canvas/node-recap.js +2 -67
- package/dist/core/canvas/node-sql-migration.js +2 -209
- package/dist/core/canvas/paths.js +1 -153
- package/dist/core/canvas/pid.js +4 -683
- package/dist/core/canvas/recovery.js +3 -565
- package/dist/core/canvas/remote-canvas-source.js +1 -288
- package/dist/core/canvas/remote-transport.js +1 -57
- package/dist/core/canvas/render-source.js +10 -635
- package/dist/core/canvas/sessions.js +1 -78
- package/dist/core/canvas/source.js +1 -47
- package/dist/core/canvas/status-glyph.js +1 -132
- package/dist/core/canvas/telemetry.js +1 -35
- package/dist/core/canvas/types.js +1 -6
- package/dist/core/canvas/waits.js +4 -68
- package/dist/core/canvas/worktrees.js +1 -93
- package/dist/core/clipboard-text.js +1 -57
- package/dist/core/command-hooks/artifact.js +1 -145
- package/dist/core/command-hooks/catalog.js +1 -38
- package/dist/core/command-hooks/compose.js +1 -99
- package/dist/core/command-hooks/discovery.js +1 -228
- package/dist/core/command-hooks/help.js +1 -18
- package/dist/core/command-hooks/index.js +1 -7
- package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
- package/dist/core/command-hooks/lifecycle-create.js +1 -51
- package/dist/core/command-hooks/report.js +1 -28
- package/dist/core/command-hooks/schema.js +1 -157
- package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
- package/dist/core/command-manifests/manifest.js +1 -324
- package/dist/core/command-manifests/registry.js +1 -118
- package/dist/core/command-manifests/schema.js +1 -736
- package/dist/core/command-plugins/bundle.js +1 -261
- package/dist/core/command-plugins/compose.js +1 -65
- package/dist/core/command-plugins/discovery.js +1 -245
- package/dist/core/command-plugins/endpoint.js +1 -48
- package/dist/core/command-plugins/extensions.js +1 -166
- package/dist/core/command-plugins/help-addenda.js +1 -44
- package/dist/core/command-plugins/presence.js +1 -17
- package/dist/core/command-plugins/revalidate.js +2 -152
- package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
- package/dist/core/command-plugins/transport/http-fetch.js +1 -68
- package/dist/core/command-plugins/transport/http-invoke.js +3 -546
- package/dist/core/command.js +10 -739
- package/dist/core/config.js +1 -1059
- package/dist/core/document-lines.js +3 -6
- package/dist/core/env-name.js +1 -9
- package/dist/core/errors.js +1 -52
- package/dist/core/events/emit.js +1 -17
- package/dist/core/events/envelope.js +1 -84
- package/dist/core/events/errors.js +1 -69
- package/dist/core/events/index.js +1 -4
- package/dist/core/events/operation-id.js +1 -24
- package/dist/core/events/read.js +1 -623
- package/dist/core/events/serialize.js +1 -199
- package/dist/core/events/source.js +1 -31
- package/dist/core/events/types.js +1 -11
- package/dist/core/exclusive-lock.js +1 -197
- package/dist/core/fault-classifier.js +1 -96
- package/dist/core/feed/feed.js +7 -202
- package/dist/core/feed/inbox-migrate.js +3 -135
- package/dist/core/feed/inbox.js +10 -122
- package/dist/core/feed/messages.js +6 -212
- package/dist/core/frontmatter.js +1 -35
- package/dist/core/fs-utils.js +3 -202
- package/dist/core/git.js +2 -103
- package/dist/core/help.js +9 -310
- package/dist/core/host-exports/builtins.js +9 -68
- package/dist/core/host-exports/export.js +3 -124
- package/dist/core/human/action-binding.js +1 -40
- package/dist/core/human/answer-text.js +5 -100
- package/dist/core/human/answer.js +1 -119
- package/dist/core/human/claim.js +3 -67
- package/dist/core/human/completion.js +1 -27
- package/dist/core/human/component-docs.js +78 -272
- package/dist/core/human/convention.js +2 -82
- package/dist/core/human/feedback-companion.js +1 -106
- package/dist/core/human/feedback.js +1 -88
- package/dist/core/human/page-authoring.js +1 -19
- package/dist/core/human/page-catalog.js +1 -172
- package/dist/core/human/page-errors.js +1 -7
- package/dist/core/human/page-eval.js +1 -125
- package/dist/core/human/page-html-markdown.js +8 -260
- package/dist/core/human/page-markdown.js +17 -295
- package/dist/core/human/page-schema.js +1 -373
- package/dist/core/human/page-synth.js +8 -27
- package/dist/core/human/page.js +1 -198
- package/dist/core/human/requests.js +15 -466
- package/dist/core/human/review-schema.js +1 -34
- package/dist/core/human/root.js +1 -11
- package/dist/core/human/scan.js +1 -69
- package/dist/core/human/summary.js +1 -5
- package/dist/core/human/tickets.js +1 -171
- package/dist/core/human/types.js +0 -1
- package/dist/core/human/visible-paths.js +1 -77
- package/dist/core/human-actions.js +1 -101
- package/dist/core/inspector/chrome.js +1 -14
- package/dist/core/inspector/contract.js +0 -1
- package/dist/core/inspector/core.js +2 -295
- package/dist/core/inspector/host.js +4 -538
- package/dist/core/inspector/model.js +2 -226
- package/dist/core/inspector/text.js +6 -45
- package/dist/core/inspector/transport.js +1 -36
- package/dist/core/inspector/tui.js +2 -295
- package/dist/core/installed-plugins.js +1 -78
- package/dist/core/io.js +7 -356
- package/dist/core/keybindings/attach-control.js +1 -42
- package/dist/core/keybindings/background-bash.js +1 -33
- package/dist/core/keybindings/catalog.js +1 -256
- package/dist/core/keybindings/inbox.js +1 -25
- package/dist/core/keybindings/index.js +1 -7
- package/dist/core/keybindings/match.js +1 -127
- package/dist/core/keybindings/persistence.js +1 -49
- package/dist/core/keybindings/resolve.js +1 -348
- package/dist/core/keybindings/types.js +0 -1
- package/dist/core/locked-file.js +1 -118
- package/dist/core/log.js +3 -27
- package/dist/core/manifest-recovery.js +1 -72
- package/dist/core/manifest-stale.js +1 -39
- package/dist/core/manifest.js +1 -20
- package/dist/core/memory/doc-link-grammar.js +2 -109
- package/dist/core/memory/extensions.js +1 -221
- package/dist/core/memory/history.js +6 -268
- package/dist/core/memory/identity.js +1 -181
- package/dist/core/memory/inline-ref-grammar.js +1 -98
- package/dist/core/memory/inline-ref-guidance.js +2 -35
- package/dist/core/memory/inline-ref-inventory.js +1 -59
- package/dist/core/memory/lint.js +2 -671
- package/dist/core/memory/project-namespace.js +2 -85
- package/dist/core/memory/repository-association.js +1 -129
- package/dist/core/memory/tree.js +1 -93
- package/dist/core/memory-resolver.js +2 -611
- package/dist/core/model-config.js +1 -107
- package/dist/core/model-routes.js +1 -201
- package/dist/core/nested-stores.js +2 -166
- package/dist/core/output.js +7 -99
- package/dist/core/pagination.js +1 -88
- package/dist/core/plugin-swap-lock.js +1 -31
- package/dist/core/pool-credential-store.js +1 -116
- package/dist/core/predicate.js +1 -191
- package/dist/core/preview-registry.js +2 -411
- package/dist/core/preview-result-path.js +1 -26
- package/dist/core/profiles/default-binding.js +1 -24
- package/dist/core/profiles/deletion-reservation.js +1 -42
- package/dist/core/profiles/env-store.js +2 -162
- package/dist/core/profiles/fuzzy-match.js +1 -92
- package/dist/core/profiles/manifest.js +1 -574
- package/dist/core/profiles/select.js +35 -741
- package/dist/core/profiles/state-block.js +3 -17
- package/dist/core/provider-error-recognition.js +1 -74
- package/dist/core/provider-failure.js +1 -86
- package/dist/core/provider-management.js +1 -22
- package/dist/core/remote-canvas-target.js +1 -30
- package/dist/core/render.js +18 -138
- package/dist/core/resolver.js +1 -111
- package/dist/core/review/birth.js +1 -52
- package/dist/core/review/comments.js +5 -279
- package/dist/core/review/companion.js +1 -215
- package/dist/core/review/document.js +2 -138
- package/dist/core/review/project.js +1 -36
- package/dist/core/review/realize.js +1 -71
- package/dist/core/review/remap.js +4 -141
- package/dist/core/review/signal.js +1 -12
- package/dist/core/review/stage.js +1 -184
- package/dist/core/review/store.js +1 -168
- package/dist/core/review/types.js +1 -23
- package/dist/core/runtime/advertised-command-invocation.js +1 -233
- package/dist/core/runtime/auth-reload.js +1 -67
- package/dist/core/runtime/banner.js +1 -51
- package/dist/core/runtime/bearings-render.js +18 -250
- package/dist/core/runtime/bearings.js +7 -194
- package/dist/core/runtime/bin-contributions.js +2 -186
- package/dist/core/runtime/boot-root.js +1 -107
- package/dist/core/runtime/branded-host.js +2 -264
- package/dist/core/runtime/broker/auth-reload.js +1 -157
- package/dist/core/runtime/broker/client-registry.js +1 -179
- package/dist/core/runtime/broker/daemon-ops.js +1 -88
- package/dist/core/runtime/broker/engine-drive.js +1 -354
- package/dist/core/runtime/broker/engine-routing.js +1 -211
- package/dist/core/runtime/broker/event-projection.js +1 -193
- package/dist/core/runtime/broker/extension-abort.js +1 -36
- package/dist/core/runtime/broker/fault-retry.js +1 -588
- package/dist/core/runtime/broker/frame-client.js +1 -132
- package/dist/core/runtime/broker/frame-dispatch.js +1 -183
- package/dist/core/runtime/broker/frame-engine-control.js +1 -231
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
- package/dist/core/runtime/broker/frame-model-query.js +1 -69
- package/dist/core/runtime/broker/frame-read.js +1 -116
- package/dist/core/runtime/broker/frame-replies.js +1 -64
- package/dist/core/runtime/broker/frame-session.js +4 -203
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
- package/dist/core/runtime/broker/inbox.js +13 -163
- package/dist/core/runtime/broker/node-named.js +1 -27
- package/dist/core/runtime/broker/read-ops.js +1 -171
- package/dist/core/runtime/broker/rebind.js +1 -318
- package/dist/core/runtime/broker/tool-groups.js +1 -246
- package/dist/core/runtime/broker/turn-admission.js +1 -31
- package/dist/core/runtime/broker/turn-ignition.js +1 -84
- package/dist/core/runtime/broker-cli.js +3 -81
- package/dist/core/runtime/broker-extension-render.js +5 -135
- package/dist/core/runtime/broker-inventory.js +1 -116
- package/dist/core/runtime/broker-persona-guidance.js +4 -154
- package/dist/core/runtime/broker-protocol.js +3 -152
- package/dist/core/runtime/broker-request.js +1 -85
- package/dist/core/runtime/broker-sdk.js +1 -129
- package/dist/core/runtime/broker.js +1 -1214
- package/dist/core/runtime/canvas-extensions.js +1 -96
- package/dist/core/runtime/chat-inventory-rows.js +1 -105
- package/dist/core/runtime/close.js +1 -265
- package/dist/core/runtime/command-expansion.js +9 -104
- package/dist/core/runtime/command-surface.js +1 -117
- package/dist/core/runtime/connectivity.js +1 -73
- package/dist/core/runtime/deliver-live.js +1 -88
- package/dist/core/runtime/fault-recovery.js +1 -83
- package/dist/core/runtime/fault.js +1 -17
- package/dist/core/runtime/fleet.js +1 -58
- package/dist/core/runtime/front-door-env.js +1 -16
- package/dist/core/runtime/front-door.js +7 -183
- package/dist/core/runtime/headless-pi.js +1 -161
- package/dist/core/runtime/host.js +1 -457
- package/dist/core/runtime/interactive-deliver.js +1 -51
- package/dist/core/runtime/invocation.js +0 -10
- package/dist/core/runtime/kickoff.js +30 -327
- package/dist/core/runtime/launch-config-worker.js +1 -12
- package/dist/core/runtime/launch-prompt.js +4 -13
- package/dist/core/runtime/launch-target.js +1 -55
- package/dist/core/runtime/launch.js +1 -483
- package/dist/core/runtime/lifecycle.js +2 -213
- package/dist/core/runtime/managed-provider-cooling.js +1 -62
- package/dist/core/runtime/memory.js +1 -17
- package/dist/core/runtime/model-registry.js +1 -13
- package/dist/core/runtime/model-selection.js +1 -135
- package/dist/core/runtime/model-swap.js +1 -86
- package/dist/core/runtime/naming.js +14 -298
- package/dist/core/runtime/nerd-font.js +2 -127
- package/dist/core/runtime/node-read.js +2 -386
- package/dist/core/runtime/nodes.js +1 -331
- package/dist/core/runtime/outcome-document.js +1 -97
- package/dist/core/runtime/package-health.js +4 -99
- package/dist/core/runtime/persona.js +2 -55
- package/dist/core/runtime/pi-cli.js +1 -65
- package/dist/core/runtime/pi-vendored.js +1 -66
- package/dist/core/runtime/placement-tmux.js +1 -81
- package/dist/core/runtime/placement.js +1 -386
- package/dist/core/runtime/promote.js +1 -174
- package/dist/core/runtime/prospective-inventory-cli.js +3 -61
- package/dist/core/runtime/prospective-inventory.js +2 -88
- package/dist/core/runtime/recap.js +27 -103
- package/dist/core/runtime/recycle.js +1 -190
- package/dist/core/runtime/reopen.js +1 -138
- package/dist/core/runtime/reset.js +1 -245
- package/dist/core/runtime/resume-root.js +10 -290
- package/dist/core/runtime/revive-all.js +1 -107
- package/dist/core/runtime/revive.js +4 -544
- package/dist/core/runtime/roadmap.js +4 -38
- package/dist/core/runtime/session-branch.js +1 -46
- package/dist/core/runtime/session-cycles.js +1 -110
- package/dist/core/runtime/session-list-cache.js +1 -406
- package/dist/core/runtime/session-visibility.js +1 -99
- package/dist/core/runtime/shell-expansion.js +9 -100
- package/dist/core/runtime/situational-context.js +2 -67
- package/dist/core/runtime/situational-live.js +1 -41
- package/dist/core/runtime/spawn-env.js +1 -255
- package/dist/core/runtime/spawn.js +3 -577
- package/dist/core/runtime/stamp/channel.js +1 -76
- package/dist/core/runtime/stamp/protocol.js +1 -113
- package/dist/core/runtime/stop-guard.js +7 -116
- package/dist/core/runtime/stop-signals.js +1 -46
- package/dist/core/runtime/stream-watchdog.js +1 -134
- package/dist/core/runtime/structured-output.js +4 -156
- package/dist/core/runtime/surface-bg.js +1 -85
- package/dist/core/runtime/tmux-bindings.js +4 -730
- package/dist/core/runtime/tmux-chrome.js +1 -5
- package/dist/core/runtime/tmux-driver.js +7 -637
- package/dist/core/runtime/tool-group-summary.js +6 -85
- package/dist/core/runtime/turn-visibility.js +1 -31
- package/dist/core/runtime/view-socket.js +1 -83
- package/dist/core/runtime/warm-pool.js +1 -395
- package/dist/core/scope.js +1 -254
- package/dist/core/scoped-state/db.js +1 -135
- package/dist/core/scoped-state/migrate.js +3 -181
- package/dist/core/scoped-state/paths.js +1 -27
- package/dist/core/scoped-state/profiles.js +1 -62
- package/dist/core/scoped-state/providers.js +1 -8
- package/dist/core/scoped-state/schema.js +3 -16
- package/dist/core/scoped-state/settings.js +1 -82
- package/dist/core/secrets.js +2 -55
- package/dist/core/self-update.js +1 -71
- package/dist/core/session-model/session-state.js +1 -180
- package/dist/core/shell-segments.js +4 -169
- package/dist/core/spawn.js +1 -26
- package/dist/core/stdout-errors.js +1 -14
- package/dist/core/subscription-state.js +3 -193
- package/dist/core/substrate/frontmatter-validation.js +1 -105
- package/dist/core/substrate/gate-explain.js +1 -424
- package/dist/core/substrate/gate.js +1 -26
- package/dist/core/substrate/index.js +1 -30
- package/dist/core/substrate/injected-store.js +1 -249
- package/dist/core/substrate/listings.js +1 -115
- package/dist/core/substrate/on-read-node.js +1 -36
- package/dist/core/substrate/on-read.js +9 -315
- package/dist/core/substrate/plan.js +1 -266
- package/dist/core/substrate/render-node.js +1 -30
- package/dist/core/substrate/render.js +65 -689
- package/dist/core/substrate/schema.js +1 -186
- package/dist/core/substrate/session-cache.js +1 -83
- package/dist/core/substrate/subject-fields.js +1 -35
- package/dist/core/substrate/subject.js +1 -47
- package/dist/core/substrate/surface-match.js +1 -242
- package/dist/core/termrender/code-doc.js +5 -92
- package/dist/core/termrender/display.js +2 -56
- package/dist/core/termrender/termrender.js +14 -719
- package/dist/core/termrender/version.js +1 -1
- package/dist/core/timing.js +2 -94
- package/dist/core/tui/draw.js +2 -378
- package/dist/core/tui/fuzzy.js +1 -38
- package/dist/core/tui/markdown.js +3 -407
- package/dist/core/tui/page-host.js +1 -74
- package/dist/core/tui/panel.js +1 -137
- package/dist/core/tui/terminal.js +2 -100
- package/dist/core/user-settings.js +1 -454
- package/dist/core/wake.js +1 -296
- package/dist/core/worktree-close.js +6 -228
- package/dist/core/worktree-containment.js +3 -48
- package/dist/core/worktree-landing.js +4 -56
- package/dist/core/worktree-mutation-async.js +10 -280
- package/dist/core/worktree-quarantine.js +1 -54
- package/dist/core/worktree-sweep.js +6 -453
- package/dist/core/worktree.js +18 -899
- package/dist/daemon/api/bridge.js +8 -418
- package/dist/daemon/api/handlers/attach.js +1 -65
- package/dist/daemon/api/handlers/bash-jobs.js +2 -91
- package/dist/daemon/api/handlers/broker-ops.js +1 -447
- package/dist/daemon/api/handlers/broker-recovery.js +1 -251
- package/dist/daemon/api/handlers/canvas.js +6 -490
- package/dist/daemon/api/handlers/chat-inventory.js +1 -25
- package/dist/daemon/api/handlers/crons.js +1 -373
- package/dist/daemon/api/handlers/daemon.js +1 -76
- package/dist/daemon/api/handlers/feedback-comments.js +3 -199
- package/dist/daemon/api/handlers/files.js +1 -63
- package/dist/daemon/api/handlers/focus.js +1 -92
- package/dist/daemon/api/handlers/health.js +1 -76
- package/dist/daemon/api/handlers/human-requests.js +1 -379
- package/dist/daemon/api/handlers/human.js +1 -3
- package/dist/daemon/api/handlers/inbox-page.js +1 -89
- package/dist/daemon/api/handlers/inbox.js +1 -301
- package/dist/daemon/api/handlers/memory.js +1 -50
- package/dist/daemon/api/handlers/messages.js +2 -506
- package/dist/daemon/api/handlers/model-config.js +1 -44
- package/dist/daemon/api/handlers/modelauth.js +1 -165
- package/dist/daemon/api/handlers/node-outcomes.js +1 -181
- package/dist/daemon/api/handlers/nodes.js +1 -939
- package/dist/daemon/api/handlers/profiles.js +1 -140
- package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
- package/dist/daemon/api/handlers/reports.js +16 -332
- package/dist/daemon/api/handlers/review-comments.js +1 -465
- package/dist/daemon/api/handlers/reviews.js +1 -200
- package/dist/daemon/api/handlers/subscriptions.js +1 -53
- package/dist/daemon/api/handlers/validate.js +1 -58
- package/dist/daemon/api/handlers/worktree.js +1 -39
- package/dist/daemon/api/map.js +2 -735
- package/dist/daemon/api/router.js +1 -190
- package/dist/daemon/api/server.js +11 -408
- package/dist/daemon/boot-migrations.js +1 -31
- package/dist/daemon/companion-retire.js +1 -34
- package/dist/daemon/control.js +1 -22
- package/dist/daemon/cron/armed-context.js +1 -100
- package/dist/daemon/cron/capture.js +2 -45
- package/dist/daemon/cron/disposition.js +1 -55
- package/dist/daemon/cron/escalation.js +3 -124
- package/dist/daemon/cron/held.js +1 -20
- package/dist/daemon/cron/lease-recovery.js +1 -119
- package/dist/daemon/cron/live-runs.js +1 -23
- package/dist/daemon/cron/passes.js +1 -58
- package/dist/daemon/cron/settle.js +1 -61
- package/dist/daemon/cron/sinks.js +2 -59
- package/dist/daemon/cron-run.js +1 -405
- package/dist/daemon/crtrd-cli.js +1 -23
- package/dist/daemon/crtrd.js +8 -854
- package/dist/daemon/delivery/run-delivery.js +1 -164
- package/dist/daemon/fleet.js +17 -475
- package/dist/daemon/human/finish.js +10 -179
- package/dist/daemon/human/settle.js +1 -89
- package/dist/daemon/human/sweep.js +1 -66
- package/dist/daemon/manage.js +2 -595
- package/dist/daemon/messaging/node-message.js +1 -99
- package/dist/daemon/park-activity.js +1 -30
- package/dist/daemon/park-pending.js +1 -52
- package/dist/daemon/pidfile.js +1 -37
- package/dist/daemon/profile-delete.js +1 -306
- package/dist/daemon/reconcilers/bash-deadline.js +1 -80
- package/dist/daemon/reconcilers/broker-supervision.js +4 -761
- package/dist/daemon/reconcilers/controller-death.js +1 -14
- package/dist/daemon/reconcilers/cron-lane.js +1 -29
- package/dist/daemon/reconcilers/delivery-lane.js +1 -130
- package/dist/daemon/reconcilers/live-obligation.js +1 -87
- package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
- package/dist/daemon/reconcilers/node-deadline.js +1 -82
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
- package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
- package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
- package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
- package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
- package/dist/daemon/review/comment-notify.js +2 -109
- package/dist/daemon/review/companion.js +1 -29
- package/dist/daemon/review/deliver.js +3 -8
- package/dist/daemon/review/finish.js +1 -122
- package/dist/daemon/review/sweep.js +1 -18
- package/dist/daemon/startup-policy.js +1 -1
- package/dist/daemon/supervise-cadence.js +1 -6
- package/dist/hook-authoring.js +5 -447
- package/dist/hook-process.js +1 -34
- package/dist/index.js +1 -52
- package/dist/migrations/001-surfaces-frontmatter.js +1 -161
- package/dist/migrations/002-profile-project-memory.js +1 -72
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
- package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
- package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
- package/dist/migrations/activation.js +2 -89
- package/dist/migrations/convergent.js +2 -82
- package/dist/migrations/corpus.js +3 -483
- package/dist/migrations/frontmatter-splice.js +8 -176
- package/dist/migrations/profile-manifests.js +2 -70
- package/dist/migrations/registry.js +1 -42
- package/dist/migrations/runner.js +1 -85
- package/dist/migrations/types.js +0 -24
- package/dist/pi-extensions/broker-local.js +2 -106
- package/dist/pi-extensions/canvas-bash-valve.js +7 -461
- package/dist/pi-extensions/canvas-context-intro.js +2 -113
- package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
- package/dist/pi-extensions/canvas-goal-capture.js +1 -83
- package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
- package/dist/pi-extensions/canvas-passive-context.js +14 -203
- package/dist/pi-extensions/canvas-preview-result.js +2 -72
- package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
- package/dist/pi-extensions/canvas-recap.js +11 -405
- package/dist/pi-extensions/canvas-review-boundary.js +3 -63
- package/dist/pi-extensions/canvas-stamp.js +2 -77
- package/dist/pi-extensions/canvas-stophook.js +1 -643
- package/dist/pi-extensions/canvas-structured-output.js +13 -35
- package/dist/pi-extensions/canvas-tool-guide.js +9 -78
- package/dist/pi-extensions/envelope-merge.js +8 -29
- package/dist/prompts/review.js +20 -42
- package/dist/shared/birth-announcement.js +1 -25
- package/dist/shared/crtr-version.js +1 -18
- package/dist/shared/env.js +1 -214
- package/dist/shared/generated-context.js +11 -226
- package/dist/shared/predicates.js +1 -4
- package/dist/shared/shell-quote.js +1 -5
- package/dist/shared/tool-groups.js +1 -64
- package/dist/shared/working-activity.js +1 -27
- package/dist/suppress-experimental-warnings.js +1 -15
- package/dist/types.js +1 -185
- package/docs/public-api.md +10 -9
- package/package.json +6 -4
- package/runtime.lock.json +5 -5
- package/scripts/pack-minify.mjs +108 -0
- package/dist/api/__tests__/integration/client.test.d.ts +0 -1
- package/dist/api/__tests__/integration/client.test.js +0 -163
- package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
- package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
- package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
- package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
- package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
- package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/context-message.test.js +0 -130
- package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
- package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/diagram.test.js +0 -42
- package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
- package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
- package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
- package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
- package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
- package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
- package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
- package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
- package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
- package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
- package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
- package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
- package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
- package/dist/commands/__tests__/human.test.d.ts +0 -1
- package/dist/commands/__tests__/human.test.js +0 -172
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
- package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
- package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
- package/dist/commands/__tests__/node-message.test.d.ts +0 -1
- package/dist/commands/__tests__/node-message.test.js +0 -112
- package/dist/commands/__tests__/node-new.test.d.ts +0 -1
- package/dist/commands/__tests__/node-new.test.js +0 -58
- package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
- package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
- package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
- package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
- package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
- package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
- package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
- package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
- package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
- package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
- package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
- package/dist/core/__tests__/bash-guard.test.js +0 -190
- package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
- package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
- package/dist/core/__tests__/boot.test.d.ts +0 -1
- package/dist/core/__tests__/boot.test.js +0 -274
- package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
- package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
- package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
- package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
- package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
- package/dist/core/__tests__/broker-preflight.test.js +0 -95
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
- package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
- package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
- package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
- package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
- package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
- package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
- package/dist/core/__tests__/canvas.test.d.ts +0 -1
- package/dist/core/__tests__/canvas.test.js +0 -138
- package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
- package/dist/core/__tests__/child-death-wake.test.js +0 -153
- package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
- package/dist/core/__tests__/cli-help-contract.test.js +0 -152
- package/dist/core/__tests__/close.test.d.ts +0 -1
- package/dist/core/__tests__/close.test.js +0 -284
- package/dist/core/__tests__/collectible.test.d.ts +0 -1
- package/dist/core/__tests__/collectible.test.js +0 -89
- package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
- package/dist/core/__tests__/config-change-delta.test.js +0 -108
- package/dist/core/__tests__/context-intro.test.d.ts +0 -1
- package/dist/core/__tests__/context-intro.test.js +0 -123
- package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
- package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
- package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
- package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
- package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
- package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
- package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
- package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
- package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
- package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-boot.test.js +0 -422
- package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
- package/dist/core/__tests__/daemon-wedge.test.js +0 -106
- package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
- package/dist/core/__tests__/events-contract.test.d.ts +0 -1
- package/dist/core/__tests__/events-contract.test.js +0 -76
- package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
- package/dist/core/__tests__/extension-abort.test.js +0 -21
- package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
- package/dist/core/__tests__/fault-classifier.test.js +0 -138
- package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
- package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
- package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
- package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
- package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
- package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
- package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
- package/dist/core/__tests__/focuses.test.d.ts +0 -1
- package/dist/core/__tests__/focuses.test.js +0 -113
- package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
- package/dist/core/__tests__/fs-utils.test.js +0 -50
- package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
- package/dist/core/__tests__/helpers/broker-clients.js +0 -174
- package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
- package/dist/core/__tests__/helpers/fleet.js +0 -50
- package/dist/core/__tests__/helpers/harness.d.ts +0 -124
- package/dist/core/__tests__/helpers/harness.js +0 -806
- package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
- package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
- package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
- package/dist/core/__tests__/history-inbox.test.js +0 -121
- package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/human-action-delivery.test.js +0 -162
- package/dist/core/__tests__/human-actions.test.d.ts +0 -1
- package/dist/core/__tests__/human-actions.test.js +0 -120
- package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
- package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
- package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
- package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
- package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
- package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
- package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
- package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
- package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
- package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
- package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
- package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
- package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
- package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
- package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
- package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
- package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
- package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
- package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
- package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
- package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
- package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
- package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
- package/dist/core/__tests__/integration/revive.test.js +0 -615
- package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
- package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
- package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
- package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
- package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
- package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
- package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
- package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
- package/dist/core/__tests__/kickoff.test.d.ts +0 -1
- package/dist/core/__tests__/kickoff.test.js +0 -196
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
- package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
- package/dist/core/__tests__/lifecycle.test.js +0 -176
- package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
- package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
- package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
- package/dist/core/__tests__/migration.test.d.ts +0 -1
- package/dist/core/__tests__/migration.test.js +0 -946
- package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
- package/dist/core/__tests__/model-pin-durability.test.js +0 -195
- package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
- package/dist/core/__tests__/model-routes-config.test.js +0 -150
- package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
- package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
- package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
- package/dist/core/__tests__/node-outcome.test.js +0 -246
- package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
- package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
- package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
- package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
- package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
- package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
- package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
- package/dist/core/__tests__/passive-subscription.test.js +0 -120
- package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
- package/dist/core/__tests__/pid-identity-match.test.js +0 -145
- package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
- package/dist/core/__tests__/pid-zombie.test.js +0 -42
- package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-kinds.test.js +0 -182
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
- package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
- package/dist/core/__tests__/plugin-page-components.test.js +0 -159
- package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
- package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
- package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
- package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
- package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
- package/dist/core/__tests__/prune.test.d.ts +0 -1
- package/dist/core/__tests__/prune.test.js +0 -243
- package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
- package/dist/core/__tests__/push-final-guard.test.js +0 -191
- package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
- package/dist/core/__tests__/relaunch-root.test.js +0 -249
- package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
- package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
- package/dist/core/__tests__/repository-association.test.d.ts +0 -1
- package/dist/core/__tests__/repository-association.test.js +0 -153
- package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
- package/dist/core/__tests__/repository-root-identity.test.js +0 -223
- package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
- package/dist/core/__tests__/respawn-throttle.test.js +0 -20
- package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
- package/dist/core/__tests__/review-model-floor.test.js +0 -83
- package/dist/core/__tests__/revive-all.test.d.ts +0 -1
- package/dist/core/__tests__/revive-all.test.js +0 -157
- package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
- package/dist/core/__tests__/revive-capacity.test.js +0 -184
- package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
- package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
- package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
- package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
- package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
- package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
- package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
- package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
- package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
- package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
- package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
- package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
- package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
- package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
- package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
- package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
- package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
- package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
- package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
- package/dist/core/__tests__/secrets.test.d.ts +0 -1
- package/dist/core/__tests__/secrets.test.js +0 -49
- package/dist/core/__tests__/self-update.test.d.ts +0 -1
- package/dist/core/__tests__/self-update.test.js +0 -46
- package/dist/core/__tests__/session-branch.test.d.ts +0 -1
- package/dist/core/__tests__/session-branch.test.js +0 -61
- package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
- package/dist/core/__tests__/session-cycles.test.js +0 -133
- package/dist/core/__tests__/session-model.test.d.ts +0 -1
- package/dist/core/__tests__/session-model.test.js +0 -111
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
- package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
- package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
- package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
- package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
- package/dist/core/__tests__/stdout-errors.test.js +0 -16
- package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
- package/dist/core/__tests__/stop-guard.test.js +0 -237
- package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
- package/dist/core/__tests__/stream-watchdog.test.js +0 -154
- package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
- package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
- package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
- package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
- package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
- package/dist/core/__tests__/worktree-landing.test.js +0 -11
- package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
- package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
- package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
- package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
- package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
- package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/attention.test.js +0 -83
- package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
- package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
- package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
- package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
- package/dist/core/canvas/__tests__/session-window.test.js +0 -70
- package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
- package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
- package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-catalog.test.js +0 -20
- package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
- package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
- package/dist/core/human/__tests__/page.test.d.ts +0 -1
- package/dist/core/human/__tests__/page.test.js +0 -92
- package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
- package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
- package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/env-store.test.js +0 -99
- package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
- package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
- package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
- package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
- package/dist/core/review/__tests__/capture-origin.test.js +0 -150
- package/dist/core/review/__tests__/comments.test.d.ts +0 -1
- package/dist/core/review/__tests__/comments.test.js +0 -116
- package/dist/core/review/__tests__/remap.test.d.ts +0 -1
- package/dist/core/review/__tests__/remap.test.js +0 -177
- package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
- package/dist/core/review/__tests__/stage-identity.test.js +0 -150
- package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
- package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/node-env.test.js +0 -73
- package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
- package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
- package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
- package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
- package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
- package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
- package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
- package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
- package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
- package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
- package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
- package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
- package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
- package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
- package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
- package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
- package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
- package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
- package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
- package/dist/daemon/__tests__/thaw-order.test.js +0 -55
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
- package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
- package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
- package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/model-config.test.js +0 -73
- package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-create-description.test.js +0 -127
- package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
- package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
- package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
- package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
- package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
- package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
- package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
- package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
- package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
- package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
- package/dist/migrations/__tests__/activation.test.d.ts +0 -1
- package/dist/migrations/__tests__/activation.test.js +0 -152
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
- package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
- package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
- package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
- package/dist/shared/__tests__/env-boundary.test.js +0 -95
- package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
- package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
- package/docs/compat/hearth-crtr-v1.md +0 -179
- package/docs/compat/hearth-crtr-v2.md +0 -177
- package/docs/compat/hearth-crtr-v3.md +0 -176
- package/docs/compat/hearth-crtr-v4.md +0 -182
- package/docs/compat/hearth-crtr-v5.md +0 -169
|
@@ -1,1188 +1,2 @@
|
|
|
1
|
-
import { relative, resolve } from 'node:path';
|
|
2
|
-
|
|
3
|
-
import { documentLines } from '../../../core/document-lines.js';
|
|
4
|
-
import { codeRenderedDoc } from '../../../core/termrender/code-doc.js';
|
|
5
|
-
import { deriveAnchorUnits, remapUnitIndex, unitIndexForLine, unitRangeForSpan } from './anchors.js';
|
|
6
|
-
import { centerHorizontal, clipLine, CYAN, DIM, RESET, REVERSE, sanitize, truncate, visibleWidth, YELLOW } from '../tui/ansi.js';
|
|
7
|
-
import { ReviewDocumentError } from './comments-client.js';
|
|
8
|
-
import { closeCompanionPane, companionPaneLive, openCompanionPane } from './companion-pane.js';
|
|
9
|
-
import { PAN_STEP, docSurface, maxHScroll, panBy, renderReviewDoc, renderReviewFrame, renderWidthForCols, reservedRows, } from './frame.js';
|
|
10
|
-
import { matchReviewKey, reviewKeyText } from './keys.js';
|
|
11
|
-
import { renderInputBuffer } from '../tui/render.js';
|
|
12
|
-
import { openReviewedFileInEditor } from './nvim.js';
|
|
13
|
-
import { buildLineMap, remapRange } from './remap.js';
|
|
14
|
-
import { cleanPastedText, closeCompose, closeHelp, closeList, commitCompose, ensureAnchorVisible, halfPageRows, initReviewState, moveActiveUnit, moveListIndex, moveViewRows, openComposeEdit, openComposeNew, openHelp, openList, scrollBy, textBackspace, textDelete, textEnd, textHome, textInsert, textVerticalWrapped, textWordBackspace, textWordLeft, textWordRight, deleteAtListIndex, undoLast, } from './state.js';
|
|
15
|
-
/** The widest the document is ever rendered, however wide the pane is. */
|
|
16
|
-
const DOC_MAX_COLS = 126;
|
|
17
|
-
/** How many places a half-page move is painted at: three midpoints, then the
|
|
18
|
-
* destination. A move of fewer rows than this uses one step per row. */
|
|
19
|
-
const SCROLL_STEPS = 4;
|
|
20
|
-
/** Milliseconds between painted steps. pi-tui paints at most every 16ms, so a
|
|
21
|
-
* shorter gap would drop steps instead of showing them. */
|
|
22
|
-
const SCROLL_STEP_MS = 24;
|
|
23
|
-
/** The one mounted review surface: existing review rendering and navigation
|
|
24
|
-
* over a live file, with comments projected from the daemon and ranges
|
|
25
|
-
* remapped by this terminal as the file changes, plus a status row naming the
|
|
26
|
-
* companion pane the conversation lives in. */
|
|
27
|
-
export class ReviewDocumentSurface {
|
|
28
|
-
absFile;
|
|
29
|
-
fileLabel;
|
|
30
|
-
companionNodeId;
|
|
31
|
-
companionCwd;
|
|
32
|
-
callerPane;
|
|
33
|
-
kind;
|
|
34
|
-
source;
|
|
35
|
-
comments;
|
|
36
|
-
services;
|
|
37
|
-
unsubscribeComments;
|
|
38
|
-
ready;
|
|
39
|
-
cols = 0;
|
|
40
|
-
/** Rows the host assigned this surface; the document frame renders one
|
|
41
|
-
* fewer, because the last line is this surface's status row. */
|
|
42
|
-
hostRows = 0;
|
|
43
|
-
/** The `hostRows` the current state was last reflowed against. A height
|
|
44
|
-
* change matters as much as a width one: `reflow` is what re-runs
|
|
45
|
-
* `ensureAnchorVisible` against the new body height, so a pane shrink
|
|
46
|
-
* cannot strand the active anchor below the visible body. */
|
|
47
|
-
flowedRows = -1;
|
|
48
|
-
_focused = false;
|
|
49
|
-
closed = false;
|
|
50
|
-
spaceArmed = false;
|
|
51
|
-
escapeConfirmArmed = false;
|
|
52
|
-
cancelArmed = false;
|
|
53
|
-
tornDown = false;
|
|
54
|
-
/** The disposition {@link teardown} stated, kept only while there was no
|
|
55
|
-
* handle to close: the mount that follows disposes every standing notice,
|
|
56
|
-
* so {@link setHandle} states it again once the surface is gone. */
|
|
57
|
-
tornDownNotice;
|
|
58
|
-
handle;
|
|
59
|
-
/** The companion pane this surface is bound to, and how it came to be.
|
|
60
|
-
* `paneOrigin` is status-row copy only: teardown reads `paneId`. */
|
|
61
|
-
paneId;
|
|
62
|
-
paneOrigin;
|
|
63
|
-
/** Row increments of a half-page move still to be painted, and the timer
|
|
64
|
-
* walking them. A fresh press settles whatever is in flight before starting
|
|
65
|
-
* its own move, so a held key cannot pile up overlapping animations. */
|
|
66
|
-
scrollSteps = [];
|
|
67
|
-
scrollTimer;
|
|
68
|
-
state;
|
|
69
|
-
cache;
|
|
70
|
-
/** Every non-deleted comment the daemon currently projects, newest last. */
|
|
71
|
-
projection = [];
|
|
72
|
-
status = 'preparing';
|
|
73
|
-
/** This surface's own error/summary state — never a host notice (D1). */
|
|
74
|
-
problem;
|
|
75
|
-
composeAnchorLost = false;
|
|
76
|
-
/** Serializes base-hash transitions so B→C cannot overtake A→B. */
|
|
77
|
-
remapChain = Promise.resolve();
|
|
78
|
-
constructor(opts) {
|
|
79
|
-
this.absFile = opts.review.file;
|
|
80
|
-
this.fileLabel = labelFor(opts.review.cwd, opts.review.file);
|
|
81
|
-
this.companionNodeId = opts.review.companionNodeId;
|
|
82
|
-
this.companionCwd = opts.review.cwd;
|
|
83
|
-
this.callerPane = opts.callerPane;
|
|
84
|
-
this.kind = docSurface(opts.review.file);
|
|
85
|
-
this.source = opts.source;
|
|
86
|
-
this.comments = opts.comments;
|
|
87
|
-
this.services = opts.services;
|
|
88
|
-
this.source.onChange((next, previous) => {
|
|
89
|
-
this.onSourceChanged(next, previous);
|
|
90
|
-
});
|
|
91
|
-
this.unsubscribeComments = this.comments.onChanged(() => {
|
|
92
|
-
void this.refreshProjection();
|
|
93
|
-
});
|
|
94
|
-
this.ready = this.align().catch((error) => {
|
|
95
|
-
if (this.closed)
|
|
96
|
-
return;
|
|
97
|
-
this.status = 'refused';
|
|
98
|
-
this.problem = describe(error);
|
|
99
|
-
this.repaint();
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/** Resolves once the daemon coordinate base has been aligned to the file on
|
|
103
|
-
* disk. The owner may await it so the first painted frame already carries
|
|
104
|
-
* current ranges; painting earlier shows only a preparing line, never a
|
|
105
|
-
* comment at a coordinate the daemon has not accepted. */
|
|
106
|
-
open() {
|
|
107
|
-
return this.ready;
|
|
108
|
-
}
|
|
109
|
-
hasUnsentCompose() {
|
|
110
|
-
const state = this.state;
|
|
111
|
-
return state?.mode === 'compose' && state.compose !== null && state.compose.buffer.length > 0;
|
|
112
|
-
}
|
|
113
|
-
// ── SurfaceComponent ──────────────────────────────────────────────────────
|
|
114
|
-
get focused() {
|
|
115
|
-
return this._focused;
|
|
116
|
-
}
|
|
117
|
-
set focused(value) {
|
|
118
|
-
if (this._focused === value)
|
|
119
|
-
return;
|
|
120
|
-
this._focused = value;
|
|
121
|
-
this.repaint();
|
|
122
|
-
}
|
|
123
|
-
setRows(rows) {
|
|
124
|
-
this.hostRows = Math.max(0, Math.floor(rows));
|
|
125
|
-
}
|
|
126
|
-
/** Exactly the rows the host assigned: the document frame, then this
|
|
127
|
-
* surface's status row. The document is capped at {@link DOC_MAX_COLS} and
|
|
128
|
-
* every line is padded out to the full pane width. */
|
|
129
|
-
render(width) {
|
|
130
|
-
const frameWidth = Math.max(0, Math.floor(width));
|
|
131
|
-
if (this.hostRows <= 0)
|
|
132
|
-
return [];
|
|
133
|
-
const cols = Math.min(frameWidth, DOC_MAX_COLS);
|
|
134
|
-
if (cols !== this.cols || this.hostRows !== this.flowedRows) {
|
|
135
|
-
this.cols = cols;
|
|
136
|
-
this.flowedRows = this.hostRows;
|
|
137
|
-
this.reflow();
|
|
138
|
-
}
|
|
139
|
-
const body = this.rows <= 0 || this.cols <= 0 ? [] : this.renderDocument();
|
|
140
|
-
return [...exactRows(body, this.rows, frameWidth), this.statusRow(frameWidth)];
|
|
141
|
-
}
|
|
142
|
-
/** Rows the document frame itself owns. */
|
|
143
|
-
get rows() {
|
|
144
|
-
return Math.max(0, this.hostRows - 1);
|
|
145
|
-
}
|
|
146
|
-
renderDocument() {
|
|
147
|
-
if (this.status !== 'ready' || this.state === undefined)
|
|
148
|
-
return this.renderPlaceholder();
|
|
149
|
-
const doc = this.document(this.cols, this.state.sourceRevision);
|
|
150
|
-
const lines = renderReviewFrame(this.state, this.fileLabel, doc, this.cols, this.rows, {
|
|
151
|
-
lineNumbers: this.kind.doc === 'code',
|
|
152
|
-
...(this.footerLine() === undefined ? {} : { notice: this.footerLine() }),
|
|
153
|
-
});
|
|
154
|
-
const grouped = this.state.mode === 'list' && this.state.comments.some((comment) => comment.anchorStatus === 'detached')
|
|
155
|
-
? this.renderGroupedList(lines)
|
|
156
|
-
: lines;
|
|
157
|
-
const rendered = this.state.mode === 'compose' && this.composeAnchorLost
|
|
158
|
-
? this.statedComposeAnchor(grouped)
|
|
159
|
-
: grouped;
|
|
160
|
-
return this.focused ? this.markCursorLocation(rendered, this.state) : rendered;
|
|
161
|
-
}
|
|
162
|
-
/** The surface consumes every chunk: nothing typed into a mounted review may
|
|
163
|
-
* reach the transcript beneath it. Esc is the one key this surface answers
|
|
164
|
-
* itself — it closes the review unless an unsent comment holds it open. */
|
|
165
|
-
handleInput(data) {
|
|
166
|
-
if (this.closed)
|
|
167
|
-
return;
|
|
168
|
-
// An armed cancel is answered before every other ladder, and disarms on
|
|
169
|
-
// any key: only a second `x` cancels, and anything else is the ordinary
|
|
170
|
-
// keypress it would have been. `escapeConfirmArmed` is left alone.
|
|
171
|
-
if (this.cancelArmed) {
|
|
172
|
-
this.cancelArmed = false;
|
|
173
|
-
const key = matchReviewKey(data);
|
|
174
|
-
if (key !== null && reviewKeyText(key) === 'x') {
|
|
175
|
-
this.services.cancel();
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (matchesKey(data, Key.escape)) {
|
|
180
|
-
if (this.escapeConfirmArmed) {
|
|
181
|
-
this.escapeConfirmArmed = false;
|
|
182
|
-
if (this.consume(data))
|
|
183
|
-
return;
|
|
184
|
-
this.services.requestClose();
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (this.hasUnsentCompose()) {
|
|
188
|
-
this.escapeConfirmArmed = true;
|
|
189
|
-
this.services.notice('unsent comment — press esc again to discard');
|
|
190
|
-
this.repaint();
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
// Compose mode owns Esc when its buffer is empty; view mode leaves it
|
|
194
|
-
// unconsumed so this surface can close.
|
|
195
|
-
if (this.consume(data))
|
|
196
|
-
return;
|
|
197
|
-
this.services.requestClose();
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (this.escapeConfirmArmed)
|
|
201
|
-
this.escapeConfirmArmed = false;
|
|
202
|
-
this.consume(data);
|
|
203
|
-
}
|
|
204
|
-
/** True when the document's own modes took the chunk. */
|
|
205
|
-
consume(data) {
|
|
206
|
-
if (this.status !== 'ready')
|
|
207
|
-
return false;
|
|
208
|
-
const state = this.state;
|
|
209
|
-
if (state === undefined)
|
|
210
|
-
return false;
|
|
211
|
-
const key = matchReviewKey(data);
|
|
212
|
-
if (key === null)
|
|
213
|
-
return false;
|
|
214
|
-
if (state.mode === 'compose') {
|
|
215
|
-
this.handleComposeKey(key);
|
|
216
|
-
this.repaint();
|
|
217
|
-
return true;
|
|
218
|
-
}
|
|
219
|
-
if (this.spaceArmed) {
|
|
220
|
-
this.handleLeaderKey(key);
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
|
-
if (state.mode === 'list') {
|
|
224
|
-
const consumed = this.handleListKey(key);
|
|
225
|
-
this.repaint();
|
|
226
|
-
return consumed;
|
|
227
|
-
}
|
|
228
|
-
if (state.mode === 'help') {
|
|
229
|
-
if (key.type === 'help' || (key.type === 'cancel' && key.text === undefined)) {
|
|
230
|
-
this.state = closeHelp(state);
|
|
231
|
-
this.repaint();
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
if (key.type === 'cancel') {
|
|
235
|
-
this.state = closeHelp(state);
|
|
236
|
-
this.repaint();
|
|
237
|
-
return true;
|
|
238
|
-
}
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
return this.handleViewKey(key);
|
|
242
|
-
}
|
|
243
|
-
/** A mounted review consumes every notch, ready or not: the transcript
|
|
244
|
-
* beneath it must never scroll while the document stands over it. */
|
|
245
|
-
handleWheel(direction, lines) {
|
|
246
|
-
if (this.closed)
|
|
247
|
-
return false;
|
|
248
|
-
const state = this.state;
|
|
249
|
-
if (this.status !== 'ready' || state === undefined)
|
|
250
|
-
return true;
|
|
251
|
-
this.settleScrollAnimation();
|
|
252
|
-
const current = this.state ?? state;
|
|
253
|
-
const doc = this.document(this.cols, current.sourceRevision);
|
|
254
|
-
const delta = (direction === 'up' ? -1 : 1) * Math.max(1, Math.floor(lines));
|
|
255
|
-
this.state = scrollBy(current, delta, this.bodyHeight(current), doc.lines.length);
|
|
256
|
-
this.repaint();
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
/** A half-page move of the view and the selection together, painted at three
|
|
260
|
-
* midpoints before its destination so the document slides rather than jumps.
|
|
261
|
-
* Whatever is still in flight lands first, keeping every press exact. */
|
|
262
|
-
startScrollAnimation(rows) {
|
|
263
|
-
this.settleScrollAnimation();
|
|
264
|
-
const steps = splitScrollSteps(rows);
|
|
265
|
-
const first = steps.shift();
|
|
266
|
-
if (first === undefined)
|
|
267
|
-
return;
|
|
268
|
-
this.applyScrollRows(first);
|
|
269
|
-
this.scrollSteps = steps;
|
|
270
|
-
this.scheduleScrollStep();
|
|
271
|
-
}
|
|
272
|
-
scheduleScrollStep() {
|
|
273
|
-
if (this.scrollSteps.length === 0)
|
|
274
|
-
return;
|
|
275
|
-
this.scrollTimer = setTimeout(() => {
|
|
276
|
-
this.scrollTimer = undefined;
|
|
277
|
-
const rows = this.scrollSteps.shift();
|
|
278
|
-
if (rows === undefined || this.closed)
|
|
279
|
-
return;
|
|
280
|
-
this.applyScrollRows(rows);
|
|
281
|
-
this.repaint();
|
|
282
|
-
this.scheduleScrollStep();
|
|
283
|
-
}, SCROLL_STEP_MS);
|
|
284
|
-
}
|
|
285
|
-
/** Land every step still to be painted on the state at once. */
|
|
286
|
-
settleScrollAnimation() {
|
|
287
|
-
this.stopScrollAnimation();
|
|
288
|
-
const pending = this.scrollSteps;
|
|
289
|
-
this.scrollSteps = [];
|
|
290
|
-
for (const rows of pending)
|
|
291
|
-
this.applyScrollRows(rows);
|
|
292
|
-
}
|
|
293
|
-
stopScrollAnimation() {
|
|
294
|
-
if (this.scrollTimer === undefined)
|
|
295
|
-
return;
|
|
296
|
-
clearTimeout(this.scrollTimer);
|
|
297
|
-
this.scrollTimer = undefined;
|
|
298
|
-
}
|
|
299
|
-
applyScrollRows(rows) {
|
|
300
|
-
const state = this.state;
|
|
301
|
-
if (this.status !== 'ready' || state === undefined)
|
|
302
|
-
return;
|
|
303
|
-
const doc = this.document(this.cols, state.sourceRevision);
|
|
304
|
-
this.state = moveViewRows(state, rows, this.bodyHeight(state), doc.lines.length);
|
|
305
|
-
}
|
|
306
|
-
/** Repaints are scheduled by the host; this surface never draws directly. */
|
|
307
|
-
invalidate() {
|
|
308
|
-
if (!this.closed)
|
|
309
|
-
this.handle?.invalidate();
|
|
310
|
-
}
|
|
311
|
-
/** The mounted handle is this surface's repaint and close channel, and the
|
|
312
|
-
* host's close is what releases the document's resources. */
|
|
313
|
-
setHandle(handle) {
|
|
314
|
-
if (this.handle !== undefined)
|
|
315
|
-
return;
|
|
316
|
-
this.handle = handle;
|
|
317
|
-
handle.onClose(() => this.close());
|
|
318
|
-
// A teardown that landed before the mount had no handle to close, so the
|
|
319
|
-
// fresh one is closed the moment it arrives: a review settled elsewhere
|
|
320
|
-
// never stands mounted. Its disposition is stated after the close, which
|
|
321
|
-
// is what disposes the notice the earlier teardown raised.
|
|
322
|
-
if (this.tornDown) {
|
|
323
|
-
handle.close();
|
|
324
|
-
const notice = this.tornDownNotice;
|
|
325
|
-
this.tornDownNotice = undefined;
|
|
326
|
-
if (notice !== undefined)
|
|
327
|
-
this.services.notice(notice.text, notice.opts);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
/** The status row's left segment: this document's state in one line. */
|
|
331
|
-
summary() {
|
|
332
|
-
if (this.status === 'refused')
|
|
333
|
-
return `${this.fileLabel} — unavailable`;
|
|
334
|
-
if (this.status === 'preparing')
|
|
335
|
-
return `${this.fileLabel} — preparing`;
|
|
336
|
-
const open = this.projection.filter((comment) => comment.status === 'open').length;
|
|
337
|
-
const detached = this.projection.filter((comment) => comment.anchorStatus === 'detached').length;
|
|
338
|
-
const parts = [this.fileLabel, `${open} open`];
|
|
339
|
-
if (detached > 0)
|
|
340
|
-
parts.push(`${detached} detached`);
|
|
341
|
-
if (this.source.current().status === 'stale')
|
|
342
|
-
parts.push(`stale (${this.source.current().staleReason ?? 'unreadable'})`);
|
|
343
|
-
return parts.join(' · ');
|
|
344
|
-
}
|
|
345
|
-
/** The status row's right segment: where the companion conversation is. */
|
|
346
|
-
companionSegment() {
|
|
347
|
-
return this.paneOrigin === undefined ? 'companion none' : `companion ${this.paneOrigin}`;
|
|
348
|
-
}
|
|
349
|
-
statusRow(width) {
|
|
350
|
-
if (width <= 0)
|
|
351
|
-
return '';
|
|
352
|
-
const right = clipLine(this.companionSegment(), width);
|
|
353
|
-
const left = clipLine(this.summary(), Math.max(0, width - visibleWidth(right) - 1));
|
|
354
|
-
const gap = Math.max(0, width - visibleWidth(left) - visibleWidth(right));
|
|
355
|
-
return `${DIM}${left}${' '.repeat(gap)}${right}${RESET}`;
|
|
356
|
-
}
|
|
357
|
-
// ── Companion pane ────────────────────────────────────────────────
|
|
358
|
-
/** Bind the conversation's pane, opening one only when this surface holds no
|
|
359
|
-
* live pane already and there is no live companion viewer to adopt. A second
|
|
360
|
-
* call therefore keeps the bound pane, whatever state its viewer is in. */
|
|
361
|
-
openCompanion() {
|
|
362
|
-
if (this.closed || this.tornDown)
|
|
363
|
-
return;
|
|
364
|
-
// Adoption can only see a pane once its viewer has tagged it, so through
|
|
365
|
-
// the whole revive-and-connect window the recorded pane is the only thing
|
|
366
|
-
// that keeps this idempotent: without it a retry splits a second pane and
|
|
367
|
-
// orphans the first. A pane that has since died falls through and reopens.
|
|
368
|
-
if (this.paneId !== undefined && companionPaneLive(this.paneId))
|
|
369
|
-
return;
|
|
370
|
-
const result = openCompanionPane({
|
|
371
|
-
companionNodeId: this.companionNodeId,
|
|
372
|
-
cwd: this.companionCwd,
|
|
373
|
-
callerPane: this.callerPane,
|
|
374
|
-
});
|
|
375
|
-
if (result.ok) {
|
|
376
|
-
this.paneId = result.paneId;
|
|
377
|
-
this.paneOrigin = result.origin;
|
|
378
|
-
this.repaint();
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
if (result.reason === 'split_refused') {
|
|
382
|
-
this.services.notice('tmux refused the companion split — press space a to retry');
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
// Without tmux the person still has a way to reach the conversation, and
|
|
386
|
-
// that instruction has to outlive an auto-clearing notice.
|
|
387
|
-
this.services.notice(`The review companion needs tmux — run: crtr surface attach to ${this.companionNodeId}`, { sticky: true });
|
|
388
|
-
}
|
|
389
|
-
/** The one path out of a review that has reached a terminal state — approved,
|
|
390
|
-
* canceled here, or decided elsewhere. The pane goes with the review, never
|
|
391
|
-
* with Esc: closing the document leaves the conversation standing so the
|
|
392
|
-
* review can be re-opened over it. Idempotent. The disposition is stated
|
|
393
|
-
* only after the close, because the host's restoring close disposes every
|
|
394
|
-
* notice raised over the closing surface — a notice raised first would die
|
|
395
|
-
* with the surface and the disposition would never paint. */
|
|
396
|
-
teardown(notice, opts) {
|
|
397
|
-
if (this.tornDown)
|
|
398
|
-
return;
|
|
399
|
-
this.tornDown = true;
|
|
400
|
-
if (this.paneId !== undefined)
|
|
401
|
-
closeCompanionPane(this.paneId, this.companionNodeId);
|
|
402
|
-
this.paneId = undefined;
|
|
403
|
-
this.paneOrigin = undefined;
|
|
404
|
-
if (this.handle === undefined)
|
|
405
|
-
this.tornDownNotice = { text: notice, ...(opts === undefined ? {} : { opts }) };
|
|
406
|
-
this.handle?.close();
|
|
407
|
-
this.services.notice(notice, opts);
|
|
408
|
-
}
|
|
409
|
-
/** Releases this surface's render cache and stops every projected repaint.
|
|
410
|
-
* This surface closes the source it was handed; that close stops its watcher.
|
|
411
|
-
* The companion pane deliberately survives: only {@link teardown} closes it. */
|
|
412
|
-
close() {
|
|
413
|
-
if (this.closed)
|
|
414
|
-
return;
|
|
415
|
-
// Stop the only source of new synchronous callbacks before closing the
|
|
416
|
-
// surface to every already-in-flight asynchronous continuation.
|
|
417
|
-
this.source.close();
|
|
418
|
-
this.closed = true;
|
|
419
|
-
this.stopScrollAnimation();
|
|
420
|
-
this.scrollSteps = [];
|
|
421
|
-
this.unsubscribeComments();
|
|
422
|
-
this.cache = undefined;
|
|
423
|
-
}
|
|
424
|
-
// ── Open-time base alignment ──────────────────────────────────────────────
|
|
425
|
-
/** Bring the daemon's comment coordinates onto the bytes now on disk, then
|
|
426
|
-
* build the first state from what the daemon accepted. The zero-comment case
|
|
427
|
-
* still submits its batch: the base digest itself is what advances, and a
|
|
428
|
-
* later create against current bytes is rejected until it does. */
|
|
429
|
-
async align() {
|
|
430
|
-
// Each pass re-reads the daemon base AND the file, because a write landing
|
|
431
|
-
// during an await would otherwise leave the base aligned to bytes that are
|
|
432
|
-
// already gone. A pass whose source moved under it is discarded and retried
|
|
433
|
-
// against the settled file rather than committed at a hash nobody holds.
|
|
434
|
-
for (;;) {
|
|
435
|
-
const base = await this.comments.anchorBase();
|
|
436
|
-
if (this.closed)
|
|
437
|
-
return;
|
|
438
|
-
if (resolve(base.file) !== resolve(this.absFile)) {
|
|
439
|
-
throw new Error(`review document mismatch — the daemon's canonical file is ${base.file}, not ${this.absFile}`);
|
|
440
|
-
}
|
|
441
|
-
const snapshot = this.source.current();
|
|
442
|
-
if (snapshot.status === 'stale') {
|
|
443
|
-
throw new Error(`the reviewed file cannot be read (${snapshot.staleReason ?? 'unreadable'})`);
|
|
444
|
-
}
|
|
445
|
-
if (base.docHash !== snapshot.sha256) {
|
|
446
|
-
const listed = await this.comments.list();
|
|
447
|
-
if (this.closed)
|
|
448
|
-
return;
|
|
449
|
-
if (this.movedSince(snapshot))
|
|
450
|
-
continue;
|
|
451
|
-
const map = buildLineMap(documentLines(base.text), snapshot.lines);
|
|
452
|
-
await this.comments.remapRanges({
|
|
453
|
-
fromDocHash: base.docHash,
|
|
454
|
-
toDocHash: snapshot.sha256,
|
|
455
|
-
entries: batchEntries(nonDeleted(listed), map),
|
|
456
|
-
});
|
|
457
|
-
if (this.closed)
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
const comments = await this.comments.list();
|
|
461
|
-
if (this.closed)
|
|
462
|
-
return;
|
|
463
|
-
if (this.movedSince(snapshot))
|
|
464
|
-
continue;
|
|
465
|
-
this.projection = nonDeleted(comments);
|
|
466
|
-
this.status = 'ready';
|
|
467
|
-
this.buildState(snapshot);
|
|
468
|
-
this.repaint();
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
movedSince(snapshot) {
|
|
473
|
-
const current = this.source.current();
|
|
474
|
-
return current.status === 'live' && current.sha256 !== snapshot.sha256;
|
|
475
|
-
}
|
|
476
|
-
/** Re-derive this surface from the daemon's own coordinate base. The only
|
|
477
|
-
* honest recovery once a batch is rejected: the local map that produced it
|
|
478
|
-
* is no longer a true description of what the daemon holds. */
|
|
479
|
-
async realign() {
|
|
480
|
-
if (this.closed)
|
|
481
|
-
return;
|
|
482
|
-
try {
|
|
483
|
-
await this.align();
|
|
484
|
-
}
|
|
485
|
-
catch (error) {
|
|
486
|
-
if (this.closed)
|
|
487
|
-
return;
|
|
488
|
-
this.status = 'refused';
|
|
489
|
-
this.problem = describe(error);
|
|
490
|
-
this.repaint();
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
buildState(snapshot) {
|
|
494
|
-
const doc = this.document(this.cols, snapshot.revision);
|
|
495
|
-
this.state = initReviewState(snapshot.lines, deriveAnchorUnits(doc), orderedForDisplay(this.projection), snapshot.revision);
|
|
496
|
-
this.state = ensureAnchorVisible(this.state, doc, this.bodyHeight(this.state));
|
|
497
|
-
}
|
|
498
|
-
// ── Live source ───────────────────────────────────────────────────────────
|
|
499
|
-
onSourceChanged(next, previous) {
|
|
500
|
-
if (this.closed || this.status !== 'ready')
|
|
501
|
-
return;
|
|
502
|
-
const state = this.state;
|
|
503
|
-
if (state === undefined)
|
|
504
|
-
return;
|
|
505
|
-
if (next.status === 'stale') {
|
|
506
|
-
this.problem = undefined;
|
|
507
|
-
this.repaint();
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
if (next.text === previous.text) {
|
|
511
|
-
this.problem = undefined;
|
|
512
|
-
this.repaint();
|
|
513
|
-
return;
|
|
514
|
-
}
|
|
515
|
-
// Order is load-bearing: every coordinate is remapped through ONE map built
|
|
516
|
-
// from the outgoing text, before any unit is re-derived from the new render.
|
|
517
|
-
const map = buildLineMap(previous.lines, next.lines);
|
|
518
|
-
const commentRanges = new Map();
|
|
519
|
-
for (const comment of this.projection) {
|
|
520
|
-
commentRanges.set(comment.id, comment.anchorStatus === 'detached'
|
|
521
|
-
? { range: comment.originalRange ?? { line: comment.line, endLine: comment.endLine }, detached: true }
|
|
522
|
-
: mapRange(map, { line: comment.line, endLine: comment.endLine }));
|
|
523
|
-
}
|
|
524
|
-
// A lost compose anchor stays lost: remapping its old numbers against
|
|
525
|
-
// whatever now occupies them would silently re-point the buffer at
|
|
526
|
-
// unrelated text. Only cancelling or opening a new compose clears it.
|
|
527
|
-
const composeAnchor = state.compose === null || this.composeAnchorLost
|
|
528
|
-
? undefined
|
|
529
|
-
: mapRange(map, state.compose.anchor);
|
|
530
|
-
const activeRange = mapRange(map, unitRange(state, state.activeUnit));
|
|
531
|
-
const selectionRange = state.selectionAnchor === null
|
|
532
|
-
? undefined
|
|
533
|
-
: mapRange(map, unitRange(state, state.selectionAnchor));
|
|
534
|
-
const topLine = mapLine(map, this.topVisibleSourceLine(state), previous.lines.length);
|
|
535
|
-
const doc = this.document(this.cols, next.revision);
|
|
536
|
-
const { units, rowUnits } = deriveAnchorUnits(doc);
|
|
537
|
-
const active = unitRangeForSpan(units, activeRange.range.line, activeRange.range.endLine).hi;
|
|
538
|
-
const selection = selectionRange === undefined
|
|
539
|
-
? null
|
|
540
|
-
: unitRangeForSpan(units, selectionRange.range.line, selectionRange.range.endLine).lo;
|
|
541
|
-
const comments = this.projection.map((comment) => {
|
|
542
|
-
const mapped = commentRanges.get(comment.id);
|
|
543
|
-
if (mapped === undefined)
|
|
544
|
-
return comment;
|
|
545
|
-
return applyMappedRange(comment, mapped);
|
|
546
|
-
});
|
|
547
|
-
this.projection = comments;
|
|
548
|
-
const detached = {};
|
|
549
|
-
for (const comment of comments) {
|
|
550
|
-
if (comment.anchorStatus === 'detached') {
|
|
551
|
-
detached[comment.id] = comment.originalRange ?? { line: comment.line, endLine: comment.endLine };
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
this.composeAnchorLost = this.composeAnchorLost || composeAnchor?.detached === true;
|
|
555
|
-
const compose = state.compose === null || composeAnchor === undefined
|
|
556
|
-
? state.compose
|
|
557
|
-
: { ...state.compose, anchor: composeAnchor.range };
|
|
558
|
-
let nextState = {
|
|
559
|
-
...state,
|
|
560
|
-
sourceLines: next.lines,
|
|
561
|
-
units,
|
|
562
|
-
rowUnits,
|
|
563
|
-
comments: orderedForDisplay(comments),
|
|
564
|
-
sourceRevision: next.revision,
|
|
565
|
-
detached,
|
|
566
|
-
activeUnit: active,
|
|
567
|
-
selectionAnchor: selection,
|
|
568
|
-
compose,
|
|
569
|
-
listIndex: Math.max(0, Math.min(state.listIndex, comments.length - 1)),
|
|
570
|
-
scroll: units[unitIndexForLine(units, topLine)]?.firstRow ?? 0,
|
|
571
|
-
};
|
|
572
|
-
nextState = ensureAnchorVisible(nextState, doc, this.bodyHeight(nextState));
|
|
573
|
-
this.state = nextState;
|
|
574
|
-
this.problem = this.composeAnchorLost ? 'the commented lines were removed — this comment has no anchor' : undefined;
|
|
575
|
-
this.repaint();
|
|
576
|
-
this.remapChain = this.remapChain.then(() => this.submitBatch(previous.sha256, next.sha256, commentRanges), () => this.submitBatch(previous.sha256, next.sha256, commentRanges));
|
|
577
|
-
}
|
|
578
|
-
/** One transaction covering every non-deleted comment. A rejection is stated
|
|
579
|
-
* in this surface's own footer and the projection is re-read from the
|
|
580
|
-
* authority, which is the only thing that can still be true afterwards. */
|
|
581
|
-
async submitBatch(fromDocHash, toDocHash, ranges) {
|
|
582
|
-
if (this.closed)
|
|
583
|
-
return;
|
|
584
|
-
const entries = [...ranges].map(([id, mapped]) => mapped.detached
|
|
585
|
-
? { id, detached: true }
|
|
586
|
-
: { id, anchor: mapped.range });
|
|
587
|
-
try {
|
|
588
|
-
await this.comments.remapRanges({ fromDocHash, toDocHash, entries });
|
|
589
|
-
if (this.closed)
|
|
590
|
-
return;
|
|
591
|
-
await this.refreshProjection();
|
|
592
|
-
}
|
|
593
|
-
catch (error) {
|
|
594
|
-
if (this.closed)
|
|
595
|
-
return;
|
|
596
|
-
this.problem = `comment ranges were rejected — ${describe(error)}`;
|
|
597
|
-
this.repaint();
|
|
598
|
-
await this.realign();
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
// ── Daemon-projected comments ─────────────────────────────────────────────
|
|
602
|
-
async refreshProjection() {
|
|
603
|
-
if (this.closed || this.status === 'refused')
|
|
604
|
-
return;
|
|
605
|
-
try {
|
|
606
|
-
const comments = nonDeleted(await this.comments.list());
|
|
607
|
-
if (this.closed)
|
|
608
|
-
return;
|
|
609
|
-
this.projection = comments;
|
|
610
|
-
const state = this.state;
|
|
611
|
-
if (state !== undefined) {
|
|
612
|
-
const ordered = orderedForDisplay(comments);
|
|
613
|
-
this.state = {
|
|
614
|
-
...state,
|
|
615
|
-
comments: ordered,
|
|
616
|
-
detached: Object.fromEntries(ordered.flatMap((comment) => comment.anchorStatus === 'detached'
|
|
617
|
-
? [[comment.id, comment.originalRange ?? { line: comment.line, endLine: comment.endLine }]]
|
|
618
|
-
: [])),
|
|
619
|
-
listIndex: Math.max(0, Math.min(state.listIndex, ordered.length - 1)),
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
this.repaint();
|
|
623
|
-
}
|
|
624
|
-
catch (error) {
|
|
625
|
-
if (this.closed)
|
|
626
|
-
return;
|
|
627
|
-
this.problem = `comments could not be read — ${describe(error)}`;
|
|
628
|
-
this.repaint();
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
async mutate(operation) {
|
|
632
|
-
if (this.closed)
|
|
633
|
-
return;
|
|
634
|
-
try {
|
|
635
|
-
await operation();
|
|
636
|
-
if (this.closed)
|
|
637
|
-
return;
|
|
638
|
-
this.problem = undefined;
|
|
639
|
-
}
|
|
640
|
-
catch (error) {
|
|
641
|
-
if (this.closed)
|
|
642
|
-
return;
|
|
643
|
-
this.problem = error instanceof ReviewDocumentError
|
|
644
|
-
? `${error.code.replace(/_/g, ' ')} — the document moved under this comment`
|
|
645
|
-
: describe(error);
|
|
646
|
-
this.repaint();
|
|
647
|
-
}
|
|
648
|
-
await this.refreshProjection();
|
|
649
|
-
}
|
|
650
|
-
// ── Keys ──────────────────────────────────────────────────────────────────
|
|
651
|
-
handleComposeKey(key) {
|
|
652
|
-
const state = this.state;
|
|
653
|
-
const compose = state?.compose;
|
|
654
|
-
if (state === undefined || compose === null || compose === undefined)
|
|
655
|
-
return;
|
|
656
|
-
if (key.type === 'cancel' && key.text === undefined) {
|
|
657
|
-
this.composeAnchorLost = false;
|
|
658
|
-
this.state = closeCompose(state);
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
if (key.type === 'confirm') {
|
|
662
|
-
if (this.composeAnchorLost) {
|
|
663
|
-
this.problem = 'comment not saved — its anchored lines were removed';
|
|
664
|
-
return;
|
|
665
|
-
}
|
|
666
|
-
const committed = commitCompose(state);
|
|
667
|
-
this.composeAnchorLost = false;
|
|
668
|
-
this.state = committed.state;
|
|
669
|
-
const commit = committed.commit;
|
|
670
|
-
if (commit === null)
|
|
671
|
-
return;
|
|
672
|
-
const docHash = this.source.current().sha256;
|
|
673
|
-
if (commit.editingId === null) {
|
|
674
|
-
void this.mutate(() => this.comments.create({
|
|
675
|
-
line: commit.anchor.line,
|
|
676
|
-
endLine: commit.anchor.endLine,
|
|
677
|
-
text: commit.text,
|
|
678
|
-
docHash,
|
|
679
|
-
}));
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
const editing = this.projection.find((comment) => comment.id === commit.editingId);
|
|
683
|
-
if (editing === undefined) {
|
|
684
|
-
this.problem = 'that comment no longer exists';
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
void this.mutate(() => this.comments.edit({
|
|
688
|
-
id: editing.id,
|
|
689
|
-
text: commit.text,
|
|
690
|
-
ifRevision: editing.revision,
|
|
691
|
-
}));
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
if (key.type === 'composeNewline') {
|
|
695
|
-
this.state = { ...state, compose: { ...compose, ...textInsert(compose.buffer, compose.cursor, '\n') } };
|
|
696
|
-
return;
|
|
697
|
-
}
|
|
698
|
-
if (key.type === 'composeWordBackspace') {
|
|
699
|
-
this.state = { ...state, compose: { ...compose, ...textWordBackspace(compose.buffer, compose.cursor) } };
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
if (key.type === 'composeBackspace') {
|
|
703
|
-
this.state = { ...state, compose: { ...compose, ...textBackspace(compose.buffer, compose.cursor) } };
|
|
704
|
-
return;
|
|
705
|
-
}
|
|
706
|
-
if (key.type === 'composeDelete') {
|
|
707
|
-
this.state = { ...state, compose: { ...compose, ...textDelete(compose.buffer, compose.cursor) } };
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
if (key.type === 'composeMove') {
|
|
711
|
-
const cursor = key.direction === 'wordLeft'
|
|
712
|
-
? textWordLeft(compose.buffer, compose.cursor)
|
|
713
|
-
: textWordRight(compose.buffer, compose.cursor);
|
|
714
|
-
this.state = { ...state, compose: { ...compose, cursor } };
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
if (key.type === 'arrow' && key.direction === 'left') {
|
|
718
|
-
this.state = { ...state, compose: { ...compose, cursor: Math.max(0, compose.cursor - 1) } };
|
|
719
|
-
return;
|
|
720
|
-
}
|
|
721
|
-
if (key.type === 'arrow' && key.direction === 'right') {
|
|
722
|
-
this.state = {
|
|
723
|
-
...state,
|
|
724
|
-
compose: { ...compose, cursor: Math.min([...compose.buffer].length, compose.cursor + 1) },
|
|
725
|
-
};
|
|
726
|
-
return;
|
|
727
|
-
}
|
|
728
|
-
if (key.type === 'composeHome') {
|
|
729
|
-
this.state = { ...state, compose: { ...compose, cursor: textHome(compose.buffer, compose.cursor) } };
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
if (key.type === 'composeEnd') {
|
|
733
|
-
this.state = { ...state, compose: { ...compose, cursor: textEnd(compose.buffer, compose.cursor) } };
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
if (key.type === 'arrow' && (key.direction === 'up' || key.direction === 'down')) {
|
|
737
|
-
const delta = key.direction === 'up' ? -1 : 1;
|
|
738
|
-
this.state = {
|
|
739
|
-
...state,
|
|
740
|
-
compose: {
|
|
741
|
-
...compose,
|
|
742
|
-
cursor: textVerticalWrapped(compose.buffer, compose.cursor, delta, this.composeWidth()),
|
|
743
|
-
},
|
|
744
|
-
};
|
|
745
|
-
return;
|
|
746
|
-
}
|
|
747
|
-
const text = reviewKeyText(key);
|
|
748
|
-
if (text === undefined)
|
|
749
|
-
return;
|
|
750
|
-
if (key.type === 'paste') {
|
|
751
|
-
const clean = cleanPastedText(text);
|
|
752
|
-
if (clean.length === 0)
|
|
753
|
-
return;
|
|
754
|
-
this.state = { ...state, compose: { ...compose, ...textInsert(compose.buffer, compose.cursor, clean) } };
|
|
755
|
-
return;
|
|
756
|
-
}
|
|
757
|
-
this.state = { ...state, compose: { ...compose, ...textInsert(compose.buffer, compose.cursor, text) } };
|
|
758
|
-
}
|
|
759
|
-
handleLeaderKey(key) {
|
|
760
|
-
const state = this.state;
|
|
761
|
-
this.spaceArmed = false;
|
|
762
|
-
if (state === undefined)
|
|
763
|
-
return;
|
|
764
|
-
const input = reviewKeyText(key);
|
|
765
|
-
if (input === 'c') {
|
|
766
|
-
const opened = openComposeNew(state);
|
|
767
|
-
this.composeAnchorLost = false;
|
|
768
|
-
this.state = ensureAnchorVisible(opened, this.document(this.cols, opened.sourceRevision), this.bodyHeight(opened));
|
|
769
|
-
}
|
|
770
|
-
else if (input === 'l') {
|
|
771
|
-
this.state = openList(state);
|
|
772
|
-
}
|
|
773
|
-
else if (input === 'u') {
|
|
774
|
-
const undone = undoLast(state);
|
|
775
|
-
if (undone.id !== null) {
|
|
776
|
-
const id = undone.id;
|
|
777
|
-
void this.mutate(() => this.comments.remove(id));
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
else if (input === 'e') {
|
|
781
|
-
this.editInEditor();
|
|
782
|
-
}
|
|
783
|
-
else if (input === 's') {
|
|
784
|
-
const snapshot = this.source.current();
|
|
785
|
-
if (snapshot.status === 'stale') {
|
|
786
|
-
this.problem = `approval refused while the source is ${snapshot.staleReason ?? 'unreadable'}`;
|
|
787
|
-
}
|
|
788
|
-
else {
|
|
789
|
-
this.services.submit();
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
else if (input === 'a') {
|
|
793
|
-
this.openCompanion();
|
|
794
|
-
}
|
|
795
|
-
else if (input === 'x') {
|
|
796
|
-
this.armCancel();
|
|
797
|
-
}
|
|
798
|
-
this.repaint();
|
|
799
|
-
}
|
|
800
|
-
/** Cancelling discards the whole review, so it asks once. The armed state is
|
|
801
|
-
* answered in {@link handleInput}, ahead of every mode's ladder. */
|
|
802
|
-
armCancel() {
|
|
803
|
-
this.cancelArmed = true;
|
|
804
|
-
this.services.notice('cancel this review? press x again to confirm');
|
|
805
|
-
}
|
|
806
|
-
handleListKey(key) {
|
|
807
|
-
const state = this.state;
|
|
808
|
-
if (state === undefined)
|
|
809
|
-
return false;
|
|
810
|
-
if (key.type === 'cancel') {
|
|
811
|
-
this.state = closeList(state);
|
|
812
|
-
return true;
|
|
813
|
-
}
|
|
814
|
-
if ((key.type === 'moveUnit' && key.text === 'j') || (key.type === 'arrow' && key.direction === 'down')) {
|
|
815
|
-
this.state = moveListIndex(state, 1);
|
|
816
|
-
return true;
|
|
817
|
-
}
|
|
818
|
-
if ((key.type === 'moveUnit' && key.text === 'k') || (key.type === 'arrow' && key.direction === 'up')) {
|
|
819
|
-
this.state = moveListIndex(state, -1);
|
|
820
|
-
return true;
|
|
821
|
-
}
|
|
822
|
-
if (key.type === 'listEdit' || key.type === 'confirm') {
|
|
823
|
-
if (state.comments.length > 0) {
|
|
824
|
-
const opened = openComposeEdit(state, state.listIndex);
|
|
825
|
-
this.composeAnchorLost = false;
|
|
826
|
-
this.state = ensureAnchorVisible(opened, this.document(this.cols, opened.sourceRevision), this.bodyHeight(opened));
|
|
827
|
-
}
|
|
828
|
-
return true;
|
|
829
|
-
}
|
|
830
|
-
if (key.type === 'scrollPage' && key.text === 'd' && state.comments.length > 0) {
|
|
831
|
-
const deleted = deleteAtListIndex(state);
|
|
832
|
-
if (deleted.id !== null) {
|
|
833
|
-
const id = deleted.id;
|
|
834
|
-
void this.mutate(() => this.comments.remove(id));
|
|
835
|
-
}
|
|
836
|
-
return true;
|
|
837
|
-
}
|
|
838
|
-
if (key.type === 'leader') {
|
|
839
|
-
this.spaceArmed = true;
|
|
840
|
-
return true;
|
|
841
|
-
}
|
|
842
|
-
return false;
|
|
843
|
-
}
|
|
844
|
-
handleViewKey(key) {
|
|
845
|
-
const state = this.state;
|
|
846
|
-
if (state === undefined)
|
|
847
|
-
return false;
|
|
848
|
-
const doc = this.document(this.cols, state.sourceRevision);
|
|
849
|
-
const bodyHeight = this.bodyHeight(state);
|
|
850
|
-
if (key.type === 'leader') {
|
|
851
|
-
this.spaceArmed = true;
|
|
852
|
-
return true;
|
|
853
|
-
}
|
|
854
|
-
if (key.type === 'moveUnit' || (key.type === 'arrow' && (key.direction === 'up' || key.direction === 'down'))) {
|
|
855
|
-
const delta = key.type === 'moveUnit' ? key.delta : key.direction === 'down' ? 1 : -1;
|
|
856
|
-
this.state = ensureAnchorVisible(moveActiveUnit(state, delta, false), doc, bodyHeight);
|
|
857
|
-
}
|
|
858
|
-
else if (key.type === 'extendUnit') {
|
|
859
|
-
this.state = ensureAnchorVisible(moveActiveUnit(state, key.delta, true), doc, bodyHeight);
|
|
860
|
-
}
|
|
861
|
-
else if (key.type === 'scrollPage') {
|
|
862
|
-
this.startScrollAnimation(key.delta * halfPageRows(bodyHeight));
|
|
863
|
-
}
|
|
864
|
-
else if ((key.type === 'pan' || (key.type === 'arrow' && (key.direction === 'left' || key.direction === 'right')))
|
|
865
|
-
&& maxHScroll(state, doc, this.cols, this.rows, this.gutterWidth()) > 0) {
|
|
866
|
-
const delta = key.type === 'pan' ? key.delta : key.direction === 'right' ? 1 : -1;
|
|
867
|
-
this.state = panBy(state, delta * PAN_STEP, doc, this.cols, this.rows, this.gutterWidth());
|
|
868
|
-
}
|
|
869
|
-
else if (key.type === 'help') {
|
|
870
|
-
this.state = openHelp(state);
|
|
871
|
-
}
|
|
872
|
-
else if (key.type === 'cancel' && key.text === undefined) {
|
|
873
|
-
// Esc in view mode belongs to this surface's own ladder, which decides
|
|
874
|
-
// whether an unsent comment should hold the review open.
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
else if (key.type === 'cancel') {
|
|
878
|
-
return false;
|
|
879
|
-
}
|
|
880
|
-
else {
|
|
881
|
-
return false;
|
|
882
|
-
}
|
|
883
|
-
this.repaint();
|
|
884
|
-
return true;
|
|
885
|
-
}
|
|
886
|
-
/** The reviewed file is the deliverable: the person's own editor writes it,
|
|
887
|
-
* this surface never does. The source is re-read the moment the editor exits
|
|
888
|
-
* rather than waiting for the watcher's coalescing window. */
|
|
889
|
-
editInEditor() {
|
|
890
|
-
const state = this.state;
|
|
891
|
-
if (state === undefined)
|
|
892
|
-
return;
|
|
893
|
-
const line = state.units[state.activeUnit]?.start ?? 1;
|
|
894
|
-
const resume = this.services.suspendForChild();
|
|
895
|
-
try {
|
|
896
|
-
const outcome = openReviewedFileInEditor(this.absFile, line);
|
|
897
|
-
if (outcome.error !== undefined)
|
|
898
|
-
this.problem = `editor failed — ${outcome.error}`;
|
|
899
|
-
}
|
|
900
|
-
finally {
|
|
901
|
-
resume();
|
|
902
|
-
}
|
|
903
|
-
this.source.refreshNow();
|
|
904
|
-
}
|
|
905
|
-
// ── Geometry and rendering ────────────────────────────────────────────────
|
|
906
|
-
/** The host owns cursor focus; a focused surface contributes exactly one
|
|
907
|
-
* whole marker at the same visual location the document already calls
|
|
908
|
-
* active. There is deliberately no synthetic fallback row: a marker is
|
|
909
|
-
* only valid when it belongs to a rendered anchor or the compose/list cursor. */
|
|
910
|
-
markCursorLocation(lines, state) {
|
|
911
|
-
// The compose caret is reverse video painted over the character it sits on,
|
|
912
|
-
// so its start sequence is the cell the hardware cursor belongs in.
|
|
913
|
-
if (state.mode === 'compose')
|
|
914
|
-
return markAtToken(lines, REVERSE);
|
|
915
|
-
if (state.mode === 'list') {
|
|
916
|
-
const markedListCursor = markAtToken(lines, `${CYAN}▸${RESET}`);
|
|
917
|
-
if (markedListCursor !== lines)
|
|
918
|
-
return markedListCursor;
|
|
919
|
-
}
|
|
920
|
-
const row = this.activeAnchorFrameRow(state);
|
|
921
|
-
return row === undefined ? lines : markAtToken(lines, `${CYAN}▌${RESET}`, row);
|
|
922
|
-
}
|
|
923
|
-
/** The frame paints source rows after its three-line header. Scroll indicators
|
|
924
|
-
* replace their source rows, so they are never cursor targets. */
|
|
925
|
-
activeAnchorFrameRow(state) {
|
|
926
|
-
const bodyHeight = Math.max(1, this.rows - reservedRows(state, this.cols));
|
|
927
|
-
const total = state.rowUnits.length;
|
|
928
|
-
const scroll = Math.max(0, Math.min(state.scroll, Math.max(0, total - bodyHeight)));
|
|
929
|
-
for (let bodyRow = 0; bodyRow < bodyHeight; bodyRow++) {
|
|
930
|
-
const sourceRow = scroll + bodyRow;
|
|
931
|
-
const replacedByIndicator = (bodyRow === 0 && scroll > 0)
|
|
932
|
-
|| (bodyRow === bodyHeight - 1 && sourceRow < total - 1);
|
|
933
|
-
if (!replacedByIndicator && state.rowUnits[sourceRow] === state.activeUnit)
|
|
934
|
-
return 3 + bodyRow;
|
|
935
|
-
}
|
|
936
|
-
return undefined;
|
|
937
|
-
}
|
|
938
|
-
reflow() {
|
|
939
|
-
const state = this.state;
|
|
940
|
-
if (state === undefined || this.cols <= 0)
|
|
941
|
-
return;
|
|
942
|
-
const previousActive = state.units[state.activeUnit];
|
|
943
|
-
const previousSelection = state.selectionAnchor === null ? undefined : state.units[state.selectionAnchor];
|
|
944
|
-
const doc = this.document(this.cols, state.sourceRevision);
|
|
945
|
-
const { units, rowUnits } = deriveAnchorUnits(doc);
|
|
946
|
-
const reflowed = {
|
|
947
|
-
...state,
|
|
948
|
-
units,
|
|
949
|
-
rowUnits,
|
|
950
|
-
activeUnit: previousActive === undefined ? 0 : remapUnitIndex(units, previousActive),
|
|
951
|
-
selectionAnchor: previousSelection === undefined ? null : remapUnitIndex(units, previousSelection),
|
|
952
|
-
};
|
|
953
|
-
this.state = ensureAnchorVisible(reflowed, doc, this.bodyHeight(reflowed));
|
|
954
|
-
}
|
|
955
|
-
document(width, sourceRevision) {
|
|
956
|
-
const cached = this.cache;
|
|
957
|
-
if (cached !== undefined && cached.width === width && cached.sourceRevision === sourceRevision)
|
|
958
|
-
return cached.doc;
|
|
959
|
-
const text = this.source.current().text;
|
|
960
|
-
const doc = this.kind.doc === 'code'
|
|
961
|
-
? codeRenderedDoc(text, this.kind.language ?? 'text', renderWidthForCols(width))
|
|
962
|
-
: renderReviewDoc(text, width);
|
|
963
|
-
this.cache = { width, sourceRevision, doc };
|
|
964
|
-
return doc;
|
|
965
|
-
}
|
|
966
|
-
bodyHeight(state) {
|
|
967
|
-
const groupedListRows = state.mode === 'list' && state.comments.some((comment) => comment.anchorStatus === 'detached')
|
|
968
|
-
? 1 + (state.comments.some((comment) => comment.anchorStatus !== 'detached') ? 1 : 0)
|
|
969
|
-
: 0;
|
|
970
|
-
return Math.max(1, this.rows - reservedRows(state, this.cols) - groupedListRows);
|
|
971
|
-
}
|
|
972
|
-
composeWidth() {
|
|
973
|
-
return Math.max(10, Math.min(Math.max(20, this.cols - 4), 120) - 2);
|
|
974
|
-
}
|
|
975
|
-
gutterWidth() {
|
|
976
|
-
return this.kind.doc === 'code' ? String(this.source.current().lines.length).length : 0;
|
|
977
|
-
}
|
|
978
|
-
/** The document frame's own footer line: its error, then its stale verdict. */
|
|
979
|
-
footerLine() {
|
|
980
|
-
if (this.problem !== undefined)
|
|
981
|
-
return this.problem;
|
|
982
|
-
const snapshot = this.source.current();
|
|
983
|
-
if (snapshot.status === 'stale') {
|
|
984
|
-
return `source ${snapshot.staleReason ?? 'unreadable'} — showing the last good read; approval is refused`;
|
|
985
|
-
}
|
|
986
|
-
return undefined;
|
|
987
|
-
}
|
|
988
|
-
renderPlaceholder() {
|
|
989
|
-
const message = this.status === 'refused'
|
|
990
|
-
? `Review unavailable — ${this.problem ?? 'the document could not be prepared'}`
|
|
991
|
-
: `Preparing ${this.fileLabel}…`;
|
|
992
|
-
const lines = ['', ` ${message}`];
|
|
993
|
-
while (lines.length < this.rows)
|
|
994
|
-
lines.push('');
|
|
995
|
-
return lines.slice(0, this.rows).map((line) => clipLine(line, this.cols));
|
|
996
|
-
}
|
|
997
|
-
/** `frame.ts` renders the ordinary list. Detached anchors need stronger
|
|
998
|
-
* treatment: their own leading group plus the original range and snippet,
|
|
999
|
-
* because no document marker can lead a person back to them. */
|
|
1000
|
-
renderGroupedList(base) {
|
|
1001
|
-
const state = this.state;
|
|
1002
|
-
const maxW = Math.min(Math.max(20, this.cols - 4), 120);
|
|
1003
|
-
const detached = state.comments.filter((comment) => comment.anchorStatus === 'detached');
|
|
1004
|
-
const anchored = state.comments.filter((comment) => comment.anchorStatus !== 'detached');
|
|
1005
|
-
const panel = [` ${YELLOW}Detached${RESET}`];
|
|
1006
|
-
for (const comment of detached)
|
|
1007
|
-
panel.push(this.commentListRow(comment, state.comments.indexOf(comment), maxW, true));
|
|
1008
|
-
if (anchored.length > 0) {
|
|
1009
|
-
panel.push(` ${DIM}Comments${RESET}`);
|
|
1010
|
-
for (const comment of anchored)
|
|
1011
|
-
panel.push(this.commentListRow(comment, state.comments.indexOf(comment), maxW, false));
|
|
1012
|
-
}
|
|
1013
|
-
panel.push('');
|
|
1014
|
-
panel.push(` ${DIM}j/k${RESET} move ${DIM}enter/e${RESET} edit ${DIM}d${RESET} delete ${DIM}q/esc${RESET} close`);
|
|
1015
|
-
const available = Math.max(0, this.rows - 3);
|
|
1016
|
-
const visible = panel.slice(0, available);
|
|
1017
|
-
const start = Math.max(3, this.rows - visible.length);
|
|
1018
|
-
const out = [...base];
|
|
1019
|
-
const centered = centerHorizontal(visible, this.cols, Math.min(this.cols, maxW + 2));
|
|
1020
|
-
for (let i = 0; i < centered.length; i++)
|
|
1021
|
-
out[start + i] = clipLine(centered[i] ?? '', this.cols);
|
|
1022
|
-
return out.slice(0, this.rows);
|
|
1023
|
-
}
|
|
1024
|
-
/** The compose header states a lost anchor where the person is already
|
|
1025
|
-
* looking, leaving the footer's compose keys intact. */
|
|
1026
|
-
statedComposeAnchor(lines) {
|
|
1027
|
-
const state = this.state;
|
|
1028
|
-
if (state?.compose == null)
|
|
1029
|
-
return lines;
|
|
1030
|
-
const maxW = Math.min(Math.max(20, this.cols - 4), 120);
|
|
1031
|
-
const bufferRows = renderInputBuffer(state.compose.buffer, state.compose.cursor, Math.max(10, maxW - 2)).length;
|
|
1032
|
-
const header = this.rows - (bufferRows + 3);
|
|
1033
|
-
if (header < 0 || header >= lines.length)
|
|
1034
|
-
return lines;
|
|
1035
|
-
const out = [...lines];
|
|
1036
|
-
out[header] = clipLine(centerHorizontal([` ${YELLOW}Comment anchor removed by an edit — esc, then re-anchor:${RESET}`], this.cols, Math.min(this.cols, maxW + 2))[0] ?? '', this.cols);
|
|
1037
|
-
return out;
|
|
1038
|
-
}
|
|
1039
|
-
commentListRow(comment, index, maxW, detached) {
|
|
1040
|
-
const range = detached
|
|
1041
|
-
? comment.originalRange ?? { line: comment.line, endLine: comment.endLine }
|
|
1042
|
-
: { line: comment.line, endLine: comment.endLine };
|
|
1043
|
-
const loc = range.line === range.endLine ? `L${range.line}` : `L${range.line}-${range.endLine}`;
|
|
1044
|
-
const cursor = index === this.state.listIndex ? `${CYAN}▸${RESET}` : ' ';
|
|
1045
|
-
const snippet = detached ? `“${sanitize(comment.lineText).replace(/\s+/g, ' ').trim()}” · ` : '';
|
|
1046
|
-
const text = `${snippet}${sanitize(comment.comment).replace(/\s+/g, ' ').trim()}`;
|
|
1047
|
-
return ` ${cursor} ${DIM}[${loc}]${RESET} ${truncate(text, Math.max(10, maxW - 14))}`;
|
|
1048
|
-
}
|
|
1049
|
-
topVisibleSourceLine(state) {
|
|
1050
|
-
const unit = state.rowUnits[state.scroll];
|
|
1051
|
-
if (unit !== null && unit !== undefined)
|
|
1052
|
-
return state.units[unit]?.start ?? 1;
|
|
1053
|
-
for (let row = state.scroll; row < state.rowUnits.length; row++) {
|
|
1054
|
-
const candidate = state.rowUnits[row];
|
|
1055
|
-
if (candidate !== null && candidate !== undefined)
|
|
1056
|
-
return state.units[candidate]?.start ?? 1;
|
|
1057
|
-
}
|
|
1058
|
-
return 1;
|
|
1059
|
-
}
|
|
1060
|
-
repaint() {
|
|
1061
|
-
this.invalidate();
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
// ── Pure helpers ─────────────────────────────────────────────────────────────
|
|
1065
|
-
/** Split a row move into increments summing exactly to it — one per painted
|
|
1066
|
-
* step, and one per row when the move is shorter than the step count (a jump
|
|
1067
|
-
* of a single row is painted once, not animated). */
|
|
1068
|
-
function splitScrollSteps(rows) {
|
|
1069
|
-
const magnitude = Math.abs(rows);
|
|
1070
|
-
if (magnitude === 0)
|
|
1071
|
-
return [];
|
|
1072
|
-
const direction = Math.sign(rows);
|
|
1073
|
-
const count = Math.min(SCROLL_STEPS, magnitude);
|
|
1074
|
-
const steps = [];
|
|
1075
|
-
let painted = 0;
|
|
1076
|
-
for (let i = 1; i <= count; i++) {
|
|
1077
|
-
const reached = Math.round((magnitude * i) / count);
|
|
1078
|
-
steps.push((reached - painted) * direction);
|
|
1079
|
-
painted = reached;
|
|
1080
|
-
}
|
|
1081
|
-
return steps;
|
|
1082
|
-
}
|
|
1083
|
-
/** Exactly `rows` lines, each exactly `width` cells. */
|
|
1084
|
-
function exactRows(lines, rows, width) {
|
|
1085
|
-
const frame = lines.slice(0, rows).map((line) => padTo(line, width));
|
|
1086
|
-
while (frame.length < rows)
|
|
1087
|
-
frame.push(' '.repeat(width));
|
|
1088
|
-
return frame;
|
|
1089
|
-
}
|
|
1090
|
-
/** `string-width` correctly ignores ANSI but cannot know pi-tui's private
|
|
1091
|
-
* cursor marker is zero-width, so the marker is measured out of the line. */
|
|
1092
|
-
function padTo(line, width) {
|
|
1093
|
-
const bare = line.split(CURSOR_MARKER).join('');
|
|
1094
|
-
const cells = visibleWidth(bare);
|
|
1095
|
-
if (cells > width) {
|
|
1096
|
-
const clipped = clipLine(bare, width);
|
|
1097
|
-
return clipped + ' '.repeat(Math.max(0, width - visibleWidth(clipped)));
|
|
1098
|
-
}
|
|
1099
|
-
return line + ' '.repeat(width - cells);
|
|
1100
|
-
}
|
|
1101
|
-
function labelFor(cwd, absFile) {
|
|
1102
|
-
const rel = relative(cwd, absFile);
|
|
1103
|
-
return rel === '' || rel.startsWith('..') ? absFile : rel;
|
|
1104
|
-
}
|
|
1105
|
-
function nonDeleted(comments) {
|
|
1106
|
-
return comments.filter((comment) => comment.status !== 'deleted');
|
|
1107
|
-
}
|
|
1108
|
-
/** Detached comments lead the list: they no longer point anywhere in the
|
|
1109
|
-
* document, so they are only reachable there. */
|
|
1110
|
-
function orderedForDisplay(comments) {
|
|
1111
|
-
const detached = comments.filter((comment) => comment.anchorStatus === 'detached');
|
|
1112
|
-
const anchored = comments.filter((comment) => comment.anchorStatus !== 'detached');
|
|
1113
|
-
return [...detached, ...anchored];
|
|
1114
|
-
}
|
|
1115
|
-
function unitRange(state, index) {
|
|
1116
|
-
const unit = state.units[index];
|
|
1117
|
-
if (unit === undefined)
|
|
1118
|
-
return { line: 1, endLine: 1 };
|
|
1119
|
-
return { line: unit.start, endLine: unit.end };
|
|
1120
|
-
}
|
|
1121
|
-
/** `remap.ts` speaks 0-based lines with an exclusive end; comment anchors are
|
|
1122
|
-
* 1-based and inclusive. This is the only place the two meet. */
|
|
1123
|
-
function mapRange(map, range) {
|
|
1124
|
-
const result = remapRange(map, { line: range.line - 1, endLine: range.endLine });
|
|
1125
|
-
if (result.kind === 'detached')
|
|
1126
|
-
return { range, detached: true };
|
|
1127
|
-
return { range: { line: result.line + 1, endLine: Math.max(result.line + 1, result.endLine) }, detached: false };
|
|
1128
|
-
}
|
|
1129
|
-
function mapLine(map, line, oldLineCount) {
|
|
1130
|
-
const old = line - 1;
|
|
1131
|
-
const exact = map.get(old);
|
|
1132
|
-
if (exact !== undefined)
|
|
1133
|
-
return exact + 1;
|
|
1134
|
-
// A deleted top row has no range to remap. Preserve locality by choosing the
|
|
1135
|
-
// nearest surviving source row, preferring the following row on a tie.
|
|
1136
|
-
for (let distance = 1; distance < oldLineCount; distance++) {
|
|
1137
|
-
const after = map.get(old + distance);
|
|
1138
|
-
if (after !== undefined)
|
|
1139
|
-
return after + 1;
|
|
1140
|
-
const before = map.get(old - distance);
|
|
1141
|
-
if (before !== undefined)
|
|
1142
|
-
return before + 1;
|
|
1143
|
-
}
|
|
1144
|
-
return 1;
|
|
1145
|
-
}
|
|
1146
|
-
function applyMappedRange(comment, mapped) {
|
|
1147
|
-
if (mapped.detached) {
|
|
1148
|
-
return {
|
|
1149
|
-
...comment,
|
|
1150
|
-
anchorStatus: 'detached',
|
|
1151
|
-
originalRange: comment.originalRange ?? { line: comment.line, endLine: comment.endLine },
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
if (comment.anchorStatus === 'detached')
|
|
1155
|
-
return comment;
|
|
1156
|
-
const shifted = mapped.range.line !== comment.line || mapped.range.endLine !== comment.endLine;
|
|
1157
|
-
return {
|
|
1158
|
-
...comment,
|
|
1159
|
-
line: mapped.range.line,
|
|
1160
|
-
endLine: mapped.range.endLine,
|
|
1161
|
-
anchorStatus: shifted ? 'shifted' : comment.anchorStatus,
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
function batchEntries(comments, map) {
|
|
1165
|
-
return comments.map((comment) => {
|
|
1166
|
-
if (comment.anchorStatus === 'detached')
|
|
1167
|
-
return { id: comment.id, detached: true };
|
|
1168
|
-
const mapped = mapRange(map, { line: comment.line, endLine: comment.endLine });
|
|
1169
|
-
return mapped.detached
|
|
1170
|
-
? { id: comment.id, detached: true }
|
|
1171
|
-
: { id: comment.id, anchor: mapped.range };
|
|
1172
|
-
});
|
|
1173
|
-
}
|
|
1174
|
-
function markAtToken(lines, token, row) {
|
|
1175
|
-
const index = row ?? lines.findIndex((line) => line.includes(token));
|
|
1176
|
-
const line = lines[index];
|
|
1177
|
-
if (line === undefined)
|
|
1178
|
-
return lines;
|
|
1179
|
-
const at = line.indexOf(token);
|
|
1180
|
-
if (at === -1)
|
|
1181
|
-
return lines;
|
|
1182
|
-
const marked = [...lines];
|
|
1183
|
-
marked[index] = `${line.slice(0, at)}${CURSOR_MARKER}${line.slice(at)}`;
|
|
1184
|
-
return marked;
|
|
1185
|
-
}
|
|
1186
|
-
function describe(error) {
|
|
1187
|
-
return error instanceof Error ? error.message : String(error);
|
|
1188
|
-
}
|
|
1
|
+
var J=Object.defineProperty;var d=(o,e)=>J(o,"name",{value:e,configurable:!0});import{relative as Q,resolve as E}from"node:path";import{CURSOR_MARKER as H,Key as Z,matchesKey as k}from"@earendil-works/pi-tui";import{documentLines as ee}from"../../../core/document-lines.js";import{codeRenderedDoc as te}from"../../../core/termrender/code-doc.js";import{deriveAnchorUnits as $,remapUnitIndex as j,unitIndexForLine as se,unitRangeForSpan as T}from"./anchors.js";import{centerHorizontal as W,clipLine as w,CYAN as A,DIM as p,RESET as l,REVERSE as ie,sanitize as N,truncate as ne,visibleWidth as b,YELLOW as O}from"../tui/ansi.js";import{ReviewDocumentError as oe}from"./comments-client.js";import{closeCompanionPane as re,companionPaneLive as ce,openCompanionPane as ae}from"./companion-pane.js";import{PAN_STEP as he,docSurface as de,maxHScroll as le,panBy as ue,renderReviewDoc as fe,renderReviewFrame as me,renderWidthForCols as pe,reservedRows as F}from"./frame.js";import{matchReviewKey as B,reviewKeyText as C}from"./keys.js";import{renderInputBuffer as ge}from"../tui/render.js";import{openReviewedFileInEditor as we}from"./nvim.js";import{buildLineMap as K,remapRange as ve}from"./remap.js";import{cleanPastedText as be,closeCompose as Le,closeHelp as _,closeList as Re,commitCompose as xe,ensureAnchorVisible as g,halfPageRows as Se,initReviewState as $e,moveActiveUnit as V,moveListIndex as q,moveViewRows as Ae,openComposeEdit as Ce,openComposeNew as Me,openHelp as ye,openList as Ie,scrollBy as De,textBackspace as Pe,textDelete as Ue,textEnd as Ee,textHome as He,textInsert as M,textVerticalWrapped as je,textWordBackspace as Te,textWordLeft as We,textWordRight as Ne,deleteAtListIndex as Oe,undoLast as Fe}from"./state.js";const Be=126,Ke=4,_e=24;class ut{static{d(this,"ReviewDocumentSurface")}absFile;fileLabel;companionNodeId;companionCwd;callerPane;kind;source;comments;services;unsubscribeComments;ready;cols=0;hostRows=0;flowedRows=-1;_focused=!1;closed=!1;spaceArmed=!1;escapeConfirmArmed=!1;cancelArmed=!1;tornDown=!1;tornDownNotice;handle;paneId;paneOrigin;scrollSteps=[];scrollTimer;state;cache;projection=[];status="preparing";problem;composeAnchorLost=!1;remapChain=Promise.resolve();constructor(e){this.absFile=e.review.file,this.fileLabel=Ge(e.review.cwd,e.review.file),this.companionNodeId=e.review.companionNodeId,this.companionCwd=e.review.cwd,this.callerPane=e.callerPane,this.kind=de(e.review.file),this.source=e.source,this.comments=e.comments,this.services=e.services,this.source.onChange((t,s)=>{this.onSourceChanged(t,s)}),this.unsubscribeComments=this.comments.onChanged(()=>{this.refreshProjection()}),this.ready=this.align().catch(t=>{this.closed||(this.status="refused",this.problem=R(t),this.repaint())})}open(){return this.ready}hasUnsentCompose(){const e=this.state;return e?.mode==="compose"&&e.compose!==null&&e.compose.buffer.length>0}get focused(){return this._focused}set focused(e){this._focused!==e&&(this._focused=e,this.repaint())}setRows(e){this.hostRows=Math.max(0,Math.floor(e))}render(e){const t=Math.max(0,Math.floor(e));if(this.hostRows<=0)return[];const s=Math.min(t,Be);(s!==this.cols||this.hostRows!==this.flowedRows)&&(this.cols=s,this.flowedRows=this.hostRows,this.reflow());const i=this.rows<=0||this.cols<=0?[]:this.renderDocument();return[...qe(i,this.rows,t),this.statusRow(t)]}get rows(){return Math.max(0,this.hostRows-1)}renderDocument(){if(this.status!=="ready"||this.state===void 0)return this.renderPlaceholder();const e=this.document(this.cols,this.state.sourceRevision),t=me(this.state,this.fileLabel,e,this.cols,this.rows,{lineNumbers:this.kind.doc==="code",...this.footerLine()===void 0?{}:{notice:this.footerLine()}}),s=this.state.mode==="list"&&this.state.comments.some(n=>n.anchorStatus==="detached")?this.renderGroupedList(t):t,i=this.state.mode==="compose"&&this.composeAnchorLost?this.statedComposeAnchor(s):s;return this.focused?this.markCursorLocation(i,this.state):i}handleInput(e){if(!this.closed){if(this.cancelArmed){this.cancelArmed=!1;const t=B(e);if(t!==null&&C(t)==="x"){this.services.cancel();return}}if(k(e,Z.escape)){if(this.escapeConfirmArmed){if(this.escapeConfirmArmed=!1,this.consume(e))return;this.services.requestClose();return}if(this.hasUnsentCompose()){this.escapeConfirmArmed=!0,this.services.notice("unsent comment \u2014 press esc again to discard"),this.repaint();return}if(this.consume(e))return;this.services.requestClose();return}this.escapeConfirmArmed&&(this.escapeConfirmArmed=!1),this.consume(e)}}consume(e){if(this.status!=="ready")return!1;const t=this.state;if(t===void 0)return!1;const s=B(e);if(s===null)return!1;if(t.mode==="compose")return this.handleComposeKey(s),this.repaint(),!0;if(this.spaceArmed)return this.handleLeaderKey(s),!0;if(t.mode==="list"){const i=this.handleListKey(s);return this.repaint(),i}return t.mode==="help"?s.type==="help"||s.type==="cancel"&&s.text===void 0?(this.state=_(t),this.repaint(),!0):s.type==="cancel"?(this.state=_(t),this.repaint(),!0):!1:this.handleViewKey(s)}handleWheel(e,t){if(this.closed)return!1;const s=this.state;if(this.status!=="ready"||s===void 0)return!0;this.settleScrollAnimation();const i=this.state??s,n=this.document(this.cols,i.sourceRevision),r=(e==="up"?-1:1)*Math.max(1,Math.floor(t));return this.state=De(i,r,this.bodyHeight(i),n.lines.length),this.repaint(),!0}startScrollAnimation(e){this.settleScrollAnimation();const t=Ve(e),s=t.shift();s!==void 0&&(this.applyScrollRows(s),this.scrollSteps=t,this.scheduleScrollStep())}scheduleScrollStep(){this.scrollSteps.length!==0&&(this.scrollTimer=setTimeout(()=>{this.scrollTimer=void 0;const e=this.scrollSteps.shift();e===void 0||this.closed||(this.applyScrollRows(e),this.repaint(),this.scheduleScrollStep())},_e))}settleScrollAnimation(){this.stopScrollAnimation();const e=this.scrollSteps;this.scrollSteps=[];for(const t of e)this.applyScrollRows(t)}stopScrollAnimation(){this.scrollTimer!==void 0&&(clearTimeout(this.scrollTimer),this.scrollTimer=void 0)}applyScrollRows(e){const t=this.state;if(this.status!=="ready"||t===void 0)return;const s=this.document(this.cols,t.sourceRevision);this.state=Ae(t,e,this.bodyHeight(t),s.lines.length)}invalidate(){this.closed||this.handle?.invalidate()}setHandle(e){if(this.handle===void 0&&(this.handle=e,e.onClose(()=>this.close()),this.tornDown)){e.close();const t=this.tornDownNotice;this.tornDownNotice=void 0,t!==void 0&&this.services.notice(t.text,t.opts)}}summary(){if(this.status==="refused")return`${this.fileLabel} \u2014 unavailable`;if(this.status==="preparing")return`${this.fileLabel} \u2014 preparing`;const e=this.projection.filter(i=>i.status==="open").length,t=this.projection.filter(i=>i.anchorStatus==="detached").length,s=[this.fileLabel,`${e} open`];return t>0&&s.push(`${t} detached`),this.source.current().status==="stale"&&s.push(`stale (${this.source.current().staleReason??"unreadable"})`),s.join(" \xB7 ")}companionSegment(){return this.paneOrigin===void 0?"companion none":`companion ${this.paneOrigin}`}statusRow(e){if(e<=0)return"";const t=w(this.companionSegment(),e),s=w(this.summary(),Math.max(0,e-b(t)-1)),i=Math.max(0,e-b(s)-b(t));return`${p}${s}${" ".repeat(i)}${t}${l}`}openCompanion(){if(this.closed||this.tornDown||this.paneId!==void 0&&ce(this.paneId))return;const e=ae({companionNodeId:this.companionNodeId,cwd:this.companionCwd,callerPane:this.callerPane});if(e.ok){this.paneId=e.paneId,this.paneOrigin=e.origin,this.repaint();return}if(e.reason==="split_refused"){this.services.notice("tmux refused the companion split \u2014 press space a to retry");return}this.services.notice(`The review companion needs tmux \u2014 run: crtr surface attach to ${this.companionNodeId}`,{sticky:!0})}teardown(e,t){this.tornDown||(this.tornDown=!0,this.paneId!==void 0&&re(this.paneId,this.companionNodeId),this.paneId=void 0,this.paneOrigin=void 0,this.handle===void 0&&(this.tornDownNotice={text:e,...t===void 0?{}:{opts:t}}),this.handle?.close(),this.services.notice(e,t))}close(){this.closed||(this.source.close(),this.closed=!0,this.stopScrollAnimation(),this.scrollSteps=[],this.unsubscribeComments(),this.cache=void 0)}async align(){for(;;){const e=await this.comments.anchorBase();if(this.closed)return;if(E(e.file)!==E(this.absFile))throw new Error(`review document mismatch \u2014 the daemon's canonical file is ${e.file}, not ${this.absFile}`);const t=this.source.current();if(t.status==="stale")throw new Error(`the reviewed file cannot be read (${t.staleReason??"unreadable"})`);if(e.docHash!==t.sha256){const i=await this.comments.list();if(this.closed)return;if(this.movedSince(t))continue;const n=K(ee(e.text),t.lines);if(await this.comments.remapRanges({fromDocHash:e.docHash,toDocHash:t.sha256,entries:Je(y(i),n)}),this.closed)return}const s=await this.comments.list();if(this.closed)return;if(!this.movedSince(t)){this.projection=y(s),this.status="ready",this.buildState(t),this.repaint();return}}}movedSince(e){const t=this.source.current();return t.status==="live"&&t.sha256!==e.sha256}async realign(){if(!this.closed)try{await this.align()}catch(e){if(this.closed)return;this.status="refused",this.problem=R(e),this.repaint()}}buildState(e){const t=this.document(this.cols,e.revision);this.state=$e(e.lines,$(t),I(this.projection),e.revision),this.state=g(this.state,t,this.bodyHeight(this.state))}onSourceChanged(e,t){if(this.closed||this.status!=="ready")return;const s=this.state;if(s===void 0)return;if(e.status==="stale"){this.problem=void 0,this.repaint();return}if(e.text===t.text){this.problem=void 0,this.repaint();return}const i=K(t.lines,e.lines),n=new Map;for(const a of this.projection)n.set(a.id,a.anchorStatus==="detached"?{range:a.originalRange??{line:a.line,endLine:a.endLine},detached:!0}:L(i,{line:a.line,endLine:a.endLine}));const r=s.compose===null||this.composeAnchorLost?void 0:L(i,s.compose.anchor),c=L(i,z(s,s.activeUnit)),u=s.selectionAnchor===null?void 0:L(i,z(s,s.selectionAnchor)),m=Ye(i,this.topVisibleSourceLine(s),t.lines.length),v=this.document(this.cols,e.revision),{units:f,rowUnits:h}=$(v),G=T(f,c.range.line,c.range.endLine).hi,Y=u===void 0?null:T(f,u.range.line,u.range.endLine).lo,x=this.projection.map(a=>{const U=n.get(a.id);return U===void 0?a:Xe(a,U)});this.projection=x;const P={};for(const a of x)a.anchorStatus==="detached"&&(P[a.id]=a.originalRange??{line:a.line,endLine:a.endLine});this.composeAnchorLost=this.composeAnchorLost||r?.detached===!0;const X=s.compose===null||r===void 0?s.compose:{...s.compose,anchor:r.range};let S={...s,sourceLines:e.lines,units:f,rowUnits:h,comments:I(x),sourceRevision:e.revision,detached:P,activeUnit:G,selectionAnchor:Y,compose:X,listIndex:Math.max(0,Math.min(s.listIndex,x.length-1)),scroll:f[se(f,m)]?.firstRow??0};S=g(S,v,this.bodyHeight(S)),this.state=S,this.problem=this.composeAnchorLost?"the commented lines were removed \u2014 this comment has no anchor":void 0,this.repaint(),this.remapChain=this.remapChain.then(()=>this.submitBatch(t.sha256,e.sha256,n),()=>this.submitBatch(t.sha256,e.sha256,n))}async submitBatch(e,t,s){if(this.closed)return;const i=[...s].map(([n,r])=>r.detached?{id:n,detached:!0}:{id:n,anchor:r.range});try{if(await this.comments.remapRanges({fromDocHash:e,toDocHash:t,entries:i}),this.closed)return;await this.refreshProjection()}catch(n){if(this.closed)return;this.problem=`comment ranges were rejected \u2014 ${R(n)}`,this.repaint(),await this.realign()}}async refreshProjection(){if(!(this.closed||this.status==="refused"))try{const e=y(await this.comments.list());if(this.closed)return;this.projection=e;const t=this.state;if(t!==void 0){const s=I(e);this.state={...t,comments:s,detached:Object.fromEntries(s.flatMap(i=>i.anchorStatus==="detached"?[[i.id,i.originalRange??{line:i.line,endLine:i.endLine}]]:[])),listIndex:Math.max(0,Math.min(t.listIndex,s.length-1))}}this.repaint()}catch(e){if(this.closed)return;this.problem=`comments could not be read \u2014 ${R(e)}`,this.repaint()}}async mutate(e){if(!this.closed){try{if(await e(),this.closed)return;this.problem=void 0}catch(t){if(this.closed)return;this.problem=t instanceof oe?`${t.code.replace(/_/g," ")} \u2014 the document moved under this comment`:R(t),this.repaint()}await this.refreshProjection()}}handleComposeKey(e){const t=this.state,s=t?.compose;if(t===void 0||s===null||s===void 0)return;if(e.type==="cancel"&&e.text===void 0){this.composeAnchorLost=!1,this.state=Le(t);return}if(e.type==="confirm"){if(this.composeAnchorLost){this.problem="comment not saved \u2014 its anchored lines were removed";return}const n=xe(t);this.composeAnchorLost=!1,this.state=n.state;const r=n.commit;if(r===null)return;const c=this.source.current().sha256;if(r.editingId===null){this.mutate(()=>this.comments.create({line:r.anchor.line,endLine:r.anchor.endLine,text:r.text,docHash:c}));return}const u=this.projection.find(m=>m.id===r.editingId);if(u===void 0){this.problem="that comment no longer exists";return}this.mutate(()=>this.comments.edit({id:u.id,text:r.text,ifRevision:u.revision}));return}if(e.type==="composeNewline"){this.state={...t,compose:{...s,...M(s.buffer,s.cursor,`
|
|
2
|
+
`)}};return}if(e.type==="composeWordBackspace"){this.state={...t,compose:{...s,...Te(s.buffer,s.cursor)}};return}if(e.type==="composeBackspace"){this.state={...t,compose:{...s,...Pe(s.buffer,s.cursor)}};return}if(e.type==="composeDelete"){this.state={...t,compose:{...s,...Ue(s.buffer,s.cursor)}};return}if(e.type==="composeMove"){const n=e.direction==="wordLeft"?We(s.buffer,s.cursor):Ne(s.buffer,s.cursor);this.state={...t,compose:{...s,cursor:n}};return}if(e.type==="arrow"&&e.direction==="left"){this.state={...t,compose:{...s,cursor:Math.max(0,s.cursor-1)}};return}if(e.type==="arrow"&&e.direction==="right"){this.state={...t,compose:{...s,cursor:Math.min([...s.buffer].length,s.cursor+1)}};return}if(e.type==="composeHome"){this.state={...t,compose:{...s,cursor:He(s.buffer,s.cursor)}};return}if(e.type==="composeEnd"){this.state={...t,compose:{...s,cursor:Ee(s.buffer,s.cursor)}};return}if(e.type==="arrow"&&(e.direction==="up"||e.direction==="down")){const n=e.direction==="up"?-1:1;this.state={...t,compose:{...s,cursor:je(s.buffer,s.cursor,n,this.composeWidth())}};return}const i=C(e);if(i!==void 0){if(e.type==="paste"){const n=be(i);if(n.length===0)return;this.state={...t,compose:{...s,...M(s.buffer,s.cursor,n)}};return}this.state={...t,compose:{...s,...M(s.buffer,s.cursor,i)}}}}handleLeaderKey(e){const t=this.state;if(this.spaceArmed=!1,t===void 0)return;const s=C(e);if(s==="c"){const i=Me(t);this.composeAnchorLost=!1,this.state=g(i,this.document(this.cols,i.sourceRevision),this.bodyHeight(i))}else if(s==="l")this.state=Ie(t);else if(s==="u"){const i=Fe(t);if(i.id!==null){const n=i.id;this.mutate(()=>this.comments.remove(n))}}else if(s==="e")this.editInEditor();else if(s==="s"){const i=this.source.current();i.status==="stale"?this.problem=`approval refused while the source is ${i.staleReason??"unreadable"}`:this.services.submit()}else s==="a"?this.openCompanion():s==="x"&&this.armCancel();this.repaint()}armCancel(){this.cancelArmed=!0,this.services.notice("cancel this review? press x again to confirm")}handleListKey(e){const t=this.state;if(t===void 0)return!1;if(e.type==="cancel")return this.state=Re(t),!0;if(e.type==="moveUnit"&&e.text==="j"||e.type==="arrow"&&e.direction==="down")return this.state=q(t,1),!0;if(e.type==="moveUnit"&&e.text==="k"||e.type==="arrow"&&e.direction==="up")return this.state=q(t,-1),!0;if(e.type==="listEdit"||e.type==="confirm"){if(t.comments.length>0){const s=Ce(t,t.listIndex);this.composeAnchorLost=!1,this.state=g(s,this.document(this.cols,s.sourceRevision),this.bodyHeight(s))}return!0}if(e.type==="scrollPage"&&e.text==="d"&&t.comments.length>0){const s=Oe(t);if(s.id!==null){const i=s.id;this.mutate(()=>this.comments.remove(i))}return!0}return e.type==="leader"?(this.spaceArmed=!0,!0):!1}handleViewKey(e){const t=this.state;if(t===void 0)return!1;const s=this.document(this.cols,t.sourceRevision),i=this.bodyHeight(t);if(e.type==="leader")return this.spaceArmed=!0,!0;if(e.type==="moveUnit"||e.type==="arrow"&&(e.direction==="up"||e.direction==="down")){const n=e.type==="moveUnit"?e.delta:e.direction==="down"?1:-1;this.state=g(V(t,n,!1),s,i)}else if(e.type==="extendUnit")this.state=g(V(t,e.delta,!0),s,i);else if(e.type==="scrollPage")this.startScrollAnimation(e.delta*Se(i));else if((e.type==="pan"||e.type==="arrow"&&(e.direction==="left"||e.direction==="right"))&&le(t,s,this.cols,this.rows,this.gutterWidth())>0){const n=e.type==="pan"?e.delta:e.direction==="right"?1:-1;this.state=ue(t,n*he,s,this.cols,this.rows,this.gutterWidth())}else if(e.type==="help")this.state=ye(t);else return e.type==="cancel"&&e.text===void 0||e.type==="cancel",!1;return this.repaint(),!0}editInEditor(){const e=this.state;if(e===void 0)return;const t=e.units[e.activeUnit]?.start??1,s=this.services.suspendForChild();try{const i=we(this.absFile,t);i.error!==void 0&&(this.problem=`editor failed \u2014 ${i.error}`)}finally{s()}this.source.refreshNow()}markCursorLocation(e,t){if(t.mode==="compose")return D(e,ie);if(t.mode==="list"){const i=D(e,`${A}\u25B8${l}`);if(i!==e)return i}const s=this.activeAnchorFrameRow(t);return s===void 0?e:D(e,`${A}\u258C${l}`,s)}activeAnchorFrameRow(e){const t=Math.max(1,this.rows-F(e,this.cols)),s=e.rowUnits.length,i=Math.max(0,Math.min(e.scroll,Math.max(0,s-t)));for(let n=0;n<t;n++){const r=i+n;if(!(n===0&&i>0||n===t-1&&r<s-1)&&e.rowUnits[r]===e.activeUnit)return 3+n}}reflow(){const e=this.state;if(e===void 0||this.cols<=0)return;const t=e.units[e.activeUnit],s=e.selectionAnchor===null?void 0:e.units[e.selectionAnchor],i=this.document(this.cols,e.sourceRevision),{units:n,rowUnits:r}=$(i),c={...e,units:n,rowUnits:r,activeUnit:t===void 0?0:j(n,t),selectionAnchor:s===void 0?null:j(n,s)};this.state=g(c,i,this.bodyHeight(c))}document(e,t){const s=this.cache;if(s!==void 0&&s.width===e&&s.sourceRevision===t)return s.doc;const i=this.source.current().text,n=this.kind.doc==="code"?te(i,this.kind.language??"text",pe(e)):fe(i,e);return this.cache={width:e,sourceRevision:t,doc:n},n}bodyHeight(e){const t=e.mode==="list"&&e.comments.some(s=>s.anchorStatus==="detached")?1+(e.comments.some(s=>s.anchorStatus!=="detached")?1:0):0;return Math.max(1,this.rows-F(e,this.cols)-t)}composeWidth(){return Math.max(10,Math.min(Math.max(20,this.cols-4),120)-2)}gutterWidth(){return this.kind.doc==="code"?String(this.source.current().lines.length).length:0}footerLine(){if(this.problem!==void 0)return this.problem;const e=this.source.current();if(e.status==="stale")return`source ${e.staleReason??"unreadable"} \u2014 showing the last good read; approval is refused`}renderPlaceholder(){const t=["",` ${this.status==="refused"?`Review unavailable \u2014 ${this.problem??"the document could not be prepared"}`:`Preparing ${this.fileLabel}\u2026`}`];for(;t.length<this.rows;)t.push("");return t.slice(0,this.rows).map(s=>w(s,this.cols))}renderGroupedList(e){const t=this.state,s=Math.min(Math.max(20,this.cols-4),120),i=t.comments.filter(h=>h.anchorStatus==="detached"),n=t.comments.filter(h=>h.anchorStatus!=="detached"),r=[` ${O}Detached${l}`];for(const h of i)r.push(this.commentListRow(h,t.comments.indexOf(h),s,!0));if(n.length>0){r.push(` ${p}Comments${l}`);for(const h of n)r.push(this.commentListRow(h,t.comments.indexOf(h),s,!1))}r.push(""),r.push(` ${p}j/k${l} move ${p}enter/e${l} edit ${p}d${l} delete ${p}q/esc${l} close`);const c=Math.max(0,this.rows-3),u=r.slice(0,c),m=Math.max(3,this.rows-u.length),v=[...e],f=W(u,this.cols,Math.min(this.cols,s+2));for(let h=0;h<f.length;h++)v[m+h]=w(f[h]??"",this.cols);return v.slice(0,this.rows)}statedComposeAnchor(e){const t=this.state;if(t?.compose==null)return e;const s=Math.min(Math.max(20,this.cols-4),120),i=ge(t.compose.buffer,t.compose.cursor,Math.max(10,s-2)).length,n=this.rows-(i+3);if(n<0||n>=e.length)return e;const r=[...e];return r[n]=w(W([` ${O}Comment anchor removed by an edit \u2014 esc, then re-anchor:${l}`],this.cols,Math.min(this.cols,s+2))[0]??"",this.cols),r}commentListRow(e,t,s,i){const n=i?e.originalRange??{line:e.line,endLine:e.endLine}:{line:e.line,endLine:e.endLine},r=n.line===n.endLine?`L${n.line}`:`L${n.line}-${n.endLine}`,c=t===this.state.listIndex?`${A}\u25B8${l}`:" ",m=`${i?`\u201C${N(e.lineText).replace(/\s+/g," ").trim()}\u201D \xB7 `:""}${N(e.comment).replace(/\s+/g," ").trim()}`;return` ${c} ${p}[${r}]${l} ${ne(m,Math.max(10,s-14))}`}topVisibleSourceLine(e){const t=e.rowUnits[e.scroll];if(t!=null)return e.units[t]?.start??1;for(let s=e.scroll;s<e.rowUnits.length;s++){const i=e.rowUnits[s];if(i!=null)return e.units[i]?.start??1}return 1}repaint(){this.invalidate()}}function Ve(o){const e=Math.abs(o);if(e===0)return[];const t=Math.sign(o),s=Math.min(Ke,e),i=[];let n=0;for(let r=1;r<=s;r++){const c=Math.round(e*r/s);i.push((c-n)*t),n=c}return i}d(Ve,"splitScrollSteps");function qe(o,e,t){const s=o.slice(0,e).map(i=>ze(i,t));for(;s.length<e;)s.push(" ".repeat(t));return s}d(qe,"exactRows");function ze(o,e){const t=o.split(H).join(""),s=b(t);if(s>e){const i=w(t,e);return i+" ".repeat(Math.max(0,e-b(i)))}return o+" ".repeat(e-s)}d(ze,"padTo");function Ge(o,e){const t=Q(o,e);return t===""||t.startsWith("..")?e:t}d(Ge,"labelFor");function y(o){return o.filter(e=>e.status!=="deleted")}d(y,"nonDeleted");function I(o){const e=o.filter(s=>s.anchorStatus==="detached"),t=o.filter(s=>s.anchorStatus!=="detached");return[...e,...t]}d(I,"orderedForDisplay");function z(o,e){const t=o.units[e];return t===void 0?{line:1,endLine:1}:{line:t.start,endLine:t.end}}d(z,"unitRange");function L(o,e){const t=ve(o,{line:e.line-1,endLine:e.endLine});return t.kind==="detached"?{range:e,detached:!0}:{range:{line:t.line+1,endLine:Math.max(t.line+1,t.endLine)},detached:!1}}d(L,"mapRange");function Ye(o,e,t){const s=e-1,i=o.get(s);if(i!==void 0)return i+1;for(let n=1;n<t;n++){const r=o.get(s+n);if(r!==void 0)return r+1;const c=o.get(s-n);if(c!==void 0)return c+1}return 1}d(Ye,"mapLine");function Xe(o,e){if(e.detached)return{...o,anchorStatus:"detached",originalRange:o.originalRange??{line:o.line,endLine:o.endLine}};if(o.anchorStatus==="detached")return o;const t=e.range.line!==o.line||e.range.endLine!==o.endLine;return{...o,line:e.range.line,endLine:e.range.endLine,anchorStatus:t?"shifted":o.anchorStatus}}d(Xe,"applyMappedRange");function Je(o,e){return o.map(t=>{if(t.anchorStatus==="detached")return{id:t.id,detached:!0};const s=L(e,{line:t.line,endLine:t.endLine});return s.detached?{id:t.id,detached:!0}:{id:t.id,anchor:s.range}})}d(Je,"batchEntries");function D(o,e,t){const s=t??o.findIndex(c=>c.includes(e)),i=o[s];if(i===void 0)return o;const n=i.indexOf(e);if(n===-1)return o;const r=[...o];return r[s]=`${i.slice(0,n)}${H}${i.slice(n)}`,r}d(D,"markAtToken");function R(o){return o instanceof Error?o.message:String(o)}d(R,"describe");export{ut as ReviewDocumentSurface};
|