@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,1055 +1,3 @@
|
|
|
1
|
-
// render.ts — pure frame rendering for the canvas browser.
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
// verbatim on every keystroke. Redraw is flicker-free: home the cursor (\x1b[H),
|
|
5
|
-
// clear each line to EOL (\x1b[K), and clear below the last line (\x1b[J) so a
|
|
6
|
-
// shrunk frame leaves no stale rows. A full frame per keypress is fine for a
|
|
7
|
-
// picker.
|
|
8
|
-
//
|
|
9
|
-
// COLOR is browse-only and *reinforces* the status glyphs (`● ○ ✓ ✗ ⊘`) which
|
|
10
|
-
// stay the primary, color-free encoding (colorblind / light-bg / NO_COLOR safe).
|
|
11
|
-
// Every hue (fg / bg color) is gated on `caps.color`; structural SGR (bold/dim/
|
|
12
|
-
// reverse) is allowed always. See detectColorCaps() for the gate, and the
|
|
13
|
-
// canvas-browse color spec for the rationale + palette.
|
|
14
|
-
import { STATUS_GLYPH, STATUS_COLOR, isFrozenRow, resolveNodeVisual, faultSummary } from '../status-glyph.js';
|
|
15
|
-
import { TABS, promptText, previewSnippet } from './model.js';
|
|
16
|
-
import { matchIndices } from '../../tui/fuzzy.js';
|
|
17
|
-
// Span/color primitives live in core/tui/draw.ts (one copy, shared with the
|
|
18
|
-
// `crtr view` host). Re-export the color caps so browse's importers + tests keep
|
|
19
|
-
// resolving them from this module.
|
|
20
|
-
import { clip, assemble, detectColorCaps } from '../../tui/draw.js';
|
|
21
|
-
import { renderMarkdownSpans } from '../../tui/markdown.js';
|
|
22
|
-
export { detectColorCaps };
|
|
23
|
-
// Fixed chrome heights, shared with app.ts so its viewport math never drifts
|
|
24
|
-
// from what renderFrame actually draws.
|
|
25
|
-
// header = title + tab bar + status line + separator (+ search input when searching)
|
|
26
|
-
// preview = separator + meta line + PREVIEW_BODY lines of node briefing
|
|
27
|
-
// The body budget is FIXED and divided between four blocks at paint time (see
|
|
28
|
-
// previewPanel): the two optional blocks (recap, report) take two lines each when
|
|
29
|
-
// the node has them, and whatever is left over is split between the two blocks that
|
|
30
|
-
// always render (the ask and the reply). A node with neither therefore shows twice
|
|
31
|
-
// as much literal conversation instead of half a panel of blanks.
|
|
32
|
-
export const RECAP_LINES = 2;
|
|
33
|
-
export const REPORT_LINES = 2;
|
|
34
|
-
export const PREVIEW_BODY = 8;
|
|
35
|
-
export const PREVIEW_HEIGHT = PREVIEW_BODY + 2;
|
|
36
|
-
// ── Preview placement ─────────────────────────────────────────────────────────
|
|
37
|
-
// A wide terminal gets the preview as a full-height RIGHT-HAND COLUMN: the row
|
|
38
|
-
// table drops its flush-right metadata cluster (those per-row facts are noise when
|
|
39
|
-
// you only care about the hovered node — they come back as a facts block inside the
|
|
40
|
-
// panel) and the reclaimed columns become the panel. A narrow terminal cannot spare
|
|
41
|
-
// the columns, so it keeps the bottom panel. The choice is width alone, so there is
|
|
42
|
-
// one code path per layout and never two hand-maintained copies of the content.
|
|
43
|
-
const SIDE_MIN_COLS = 100; // below this the side column would starve the name column
|
|
44
|
-
const SIDE_PANEL_MIN = 46;
|
|
45
|
-
const SIDE_PANEL_MAX = 110;
|
|
46
|
-
const SIDE_PANEL_RATIO = 0.55;
|
|
47
|
-
const SIDE_ROWS_MIN = 40; // the row table never shrinks below this
|
|
48
|
-
const SIDE_GUTTER = ' │ '; // rows │ panel — the dim rule that separates them
|
|
49
|
-
export function previewLayout(cols, previewOn) {
|
|
50
|
-
const width = Math.max(20, cols) - 1; // last column is reserved for \x1b[K
|
|
51
|
-
if (!previewOn)
|
|
52
|
-
return { mode: 'none', panelW: 0, rowsW: width };
|
|
53
|
-
if (cols < SIDE_MIN_COLS)
|
|
54
|
-
return { mode: 'bottom', panelW: 0, rowsW: width };
|
|
55
|
-
const gutter = [...SIDE_GUTTER].length;
|
|
56
|
-
let panelW = Math.min(SIDE_PANEL_MAX, Math.max(SIDE_PANEL_MIN, Math.round(width * SIDE_PANEL_RATIO)));
|
|
57
|
-
if (width - panelW - gutter < SIDE_ROWS_MIN)
|
|
58
|
-
panelW = width - gutter - SIDE_ROWS_MIN;
|
|
59
|
-
if (panelW < SIDE_PANEL_MIN)
|
|
60
|
-
return { mode: 'bottom', panelW: 0, rowsW: width };
|
|
61
|
-
return { mode: 'side', panelW, rowsW: width - panelW - gutter };
|
|
62
|
-
}
|
|
63
|
-
// header = title + tab bar + status line + column header + separator (+ input line)
|
|
64
|
-
// `inputLine` is true whenever a text-input mode is open (search / rename / message)
|
|
65
|
-
// — each adds one prompt row above the column header.
|
|
66
|
-
export function headerHeight(inputLine) {
|
|
67
|
-
return 5 + (inputLine ? 1 : 0);
|
|
68
|
-
}
|
|
69
|
-
// ── Row table layout ──────────────────────────────────────────────────────────
|
|
70
|
-
// A row is three zones: a fixed-width STATUS rail (glyph + word) on the left, the
|
|
71
|
-
// flexible tree-indented NAME in the middle, and a flush-right METADATA cluster
|
|
72
|
-
// (kind/mode · ctx · age · project) whose fixed-width segments align into clean
|
|
73
|
-
// vertical columns down the right edge. Wide terminals widen the name; narrow ones
|
|
74
|
-
// clip the name (and drop the cluster) first. The status WORD — not a lone glyph —
|
|
75
|
-
// is the legible, NO_COLOR-safe state signal.
|
|
76
|
-
const STATUS_W = 10; // glyph + ' ' + longest word ('active'/'cancel') + trailing gap
|
|
77
|
-
const KM_W = 22; // kind/mode column
|
|
78
|
-
const CTX_W = 6; // ctx tokens column
|
|
79
|
-
const AGE_W = 5; // age column
|
|
80
|
-
const PROJ_W = 16; // project (~basename) column, only across All dirs
|
|
81
|
-
const COL_GAP = ' ';
|
|
82
|
-
// ── ANSI ────────────────────────────────────────────────────────────────────
|
|
83
|
-
const ESC = '\x1b[';
|
|
84
|
-
const RESET = `${ESC}0m`;
|
|
85
|
-
const REVERSE = `${ESC}7m`;
|
|
86
|
-
const DIM = `${ESC}2m`;
|
|
87
|
-
const BOLD = `${ESC}1m`;
|
|
88
|
-
const CURSOR_BG = `${ESC}48;5;236m`; // subtle dark-gray cursor-row bg (256-color)
|
|
89
|
-
// Basic-16 ANSI fg codes used by the palette.
|
|
90
|
-
const FG_YELLOW = '33';
|
|
91
|
-
const FG_RED = '31';
|
|
92
|
-
const FG_CYAN = '36';
|
|
93
|
-
const FG_GRAY = '90'; // bright-black
|
|
94
|
-
const FG_BRIGHT_YELLOW = '93';
|
|
95
|
-
const FG_BRIGHT_CYAN = '96'; // query-match highlight (ties to the cyan search accent)
|
|
96
|
-
const FG_MAGENTA = '35'; // pin star (distinct from the yellow ⚑ asks flag)
|
|
97
|
-
function fmtCtx(tokens) {
|
|
98
|
-
if (tokens <= 0)
|
|
99
|
-
return '0k';
|
|
100
|
-
return `${Math.floor(tokens / 1000)}k`;
|
|
101
|
-
}
|
|
102
|
-
/** Tiered ctx-budget hue: dim under 50k, yellow 50–100k, red ≥100k. `undefined`
|
|
103
|
-
* → dim (structural), so low budgets recede. */
|
|
104
|
-
function ctxColorCode(tokens) {
|
|
105
|
-
if (tokens >= 100_000)
|
|
106
|
-
return FG_RED;
|
|
107
|
-
if (tokens >= 50_000)
|
|
108
|
-
return FG_YELLOW;
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
/** Compact relative age, e.g. `45s` `12m` `3h` `5d` `2w` `4mo`. Empty on a bad
|
|
112
|
-
* timestamp. Drives the per-row recency cue + the preview meta line. */
|
|
113
|
-
function relAge(created, now) {
|
|
114
|
-
const t = Date.parse(created);
|
|
115
|
-
if (Number.isNaN(t))
|
|
116
|
-
return '';
|
|
117
|
-
const s = Math.max(0, Math.floor((now - t) / 1000));
|
|
118
|
-
if (s < 60)
|
|
119
|
-
return `${s}s`;
|
|
120
|
-
const m = Math.floor(s / 60);
|
|
121
|
-
if (m < 60)
|
|
122
|
-
return `${m}m`;
|
|
123
|
-
const h = Math.floor(m / 60);
|
|
124
|
-
if (h < 24)
|
|
125
|
-
return `${h}h`;
|
|
126
|
-
const d = Math.floor(h / 24);
|
|
127
|
-
if (d < 7)
|
|
128
|
-
return `${d}d`;
|
|
129
|
-
const w = Math.floor(d / 7);
|
|
130
|
-
if (w < 5)
|
|
131
|
-
return `${w}w`;
|
|
132
|
-
return `${Math.floor(d / 30)}mo`;
|
|
133
|
-
}
|
|
134
|
-
/** Last path segment of a cwd — the project name shown as the All-dirs cue. */
|
|
135
|
-
function baseDir(cwd) {
|
|
136
|
-
const parts = cwd.replace(/\/+$/, '').split('/');
|
|
137
|
-
return parts[parts.length - 1] || cwd;
|
|
138
|
-
}
|
|
139
|
-
// ── Styled spans ──────────────────────────────────────────────────────────────
|
|
140
|
-
//
|
|
141
|
-
// A row is built from styled spans, then assembled to a width-clipped line. This
|
|
142
|
-
// lets each cell carry its own hue (status glyph, ctx tier, asks, match highlight)
|
|
143
|
-
// while clipping by VISIBLE width — ANSI bytes don't count toward the column
|
|
144
|
-
// budget. `fg` is hue (gated on `color`); `bold`/`dim` are structural (always).
|
|
145
|
-
// Span / styleSpan / assemble now live in core/tui/draw.ts (imported above).
|
|
146
|
-
/** Status tallies across the whole canvas, for the right-aligned header. Memoized
|
|
147
|
-
* per tree — the snapshot is immutable for a browse session, so counting is done
|
|
148
|
-
* once, not O(N) on every keystroke (the "massive canvas" target). */
|
|
149
|
-
const summaryCache = new WeakMap();
|
|
150
|
-
function statusCounts(tree) {
|
|
151
|
-
const cached = summaryCache.get(tree);
|
|
152
|
-
if (cached !== undefined)
|
|
153
|
-
return cached;
|
|
154
|
-
const counts = { active: 0, idle: 0, done: 0, dead: 0, canceled: 0 };
|
|
155
|
-
for (const node of tree.nodes.values())
|
|
156
|
-
counts[node.row.status]++;
|
|
157
|
-
const parts = [];
|
|
158
|
-
for (const s of ['active', 'idle', 'done', 'dead', 'canceled']) {
|
|
159
|
-
if (counts[s] > 0)
|
|
160
|
-
parts.push({ status: s, count: counts[s] });
|
|
161
|
-
}
|
|
162
|
-
summaryCache.set(tree, parts);
|
|
163
|
-
return parts;
|
|
164
|
-
}
|
|
165
|
-
function tabBar(active, color) {
|
|
166
|
-
return TABS.map((t) => {
|
|
167
|
-
if (t === active) {
|
|
168
|
-
// Keep the [ ] brackets in BOTH paths so the active tab reads without color.
|
|
169
|
-
return color ? `${BOLD}${ESC}${FG_CYAN}m[ ${t} ]${RESET}` : `${REVERSE}[ ${t} ]${RESET}`;
|
|
170
|
-
}
|
|
171
|
-
return color ? `${DIM} ${t} ${RESET}` : ` ${t} `;
|
|
172
|
-
}).join('');
|
|
173
|
-
}
|
|
174
|
-
const EMPTY_HI = new Set();
|
|
175
|
-
/** Name → spans, splitting out the query-matched chars (bold + bright-cyan) so
|
|
176
|
-
* matches are scannable. Non-matched chars carry the row's name style (dim for
|
|
177
|
-
* terminal status, bold on the cursor row). */
|
|
178
|
-
function nameSpans(name, query, style) {
|
|
179
|
-
const hi = query === '' ? EMPTY_HI : matchIndices(query, name);
|
|
180
|
-
if (hi.size === 0)
|
|
181
|
-
return [{ text: name, style: { dim: style.dim, bold: style.bold } }];
|
|
182
|
-
const out = [];
|
|
183
|
-
let buf = '';
|
|
184
|
-
let bufHi = false;
|
|
185
|
-
const flush = () => {
|
|
186
|
-
if (buf === '')
|
|
187
|
-
return;
|
|
188
|
-
if (bufHi)
|
|
189
|
-
out.push({ text: buf, style: { fg: FG_BRIGHT_CYAN, bold: true } });
|
|
190
|
-
else
|
|
191
|
-
out.push({ text: buf, style: { dim: style.dim, bold: style.bold } });
|
|
192
|
-
buf = '';
|
|
193
|
-
};
|
|
194
|
-
for (let i = 0; i < name.length; i++) {
|
|
195
|
-
const h = hi.has(i);
|
|
196
|
-
if (h !== bufHi) {
|
|
197
|
-
flush();
|
|
198
|
-
bufHi = h;
|
|
199
|
-
}
|
|
200
|
-
buf += name[i];
|
|
201
|
-
}
|
|
202
|
-
flush();
|
|
203
|
-
return out;
|
|
204
|
-
}
|
|
205
|
-
/** Visible (cell) width of a span group — ANSI-free, surrogate-safe. */
|
|
206
|
-
function spansWidth(spans) {
|
|
207
|
-
let n = 0;
|
|
208
|
-
for (const s of spans)
|
|
209
|
-
n += [...s.text].length;
|
|
210
|
-
return n;
|
|
211
|
-
}
|
|
212
|
-
/** The status rail: a status WORD next to its glyph, both in the status hue, padded
|
|
213
|
-
* to STATUS_W so the rail forms a clean left column. `live` (bright green) when the
|
|
214
|
-
* node is genuinely mid-turn; otherwise the lifecycle word. The word is what makes
|
|
215
|
-
* state legible at a glance and survives NO_COLOR (the glyph is the second cue). */
|
|
216
|
-
function statusRail(r) {
|
|
217
|
-
const v = resolveNodeVisual(r.status, {
|
|
218
|
-
streaming: r.streaming === true,
|
|
219
|
-
frozen: isFrozenRow(r),
|
|
220
|
-
hanging: r.hanging ?? null,
|
|
221
|
-
});
|
|
222
|
-
// Plain status keeps browse's own status WORD; overlays (hanging/⟳)
|
|
223
|
-
// carry their own word from resolveNodeVisual. A hanging kind label can exceed
|
|
224
|
-
// STATUS_W — acceptable: the rare, attention-demanding row gets a slightly
|
|
225
|
-
// wider rail (Math.max(1,…) keeps a gap), which draws the eye.
|
|
226
|
-
const word = v.word ?? ({ active: 'active', idle: 'idle', done: 'done', dead: 'dead', canceled: 'cancel' }[r.status] ?? r.status);
|
|
227
|
-
const fg = v.color;
|
|
228
|
-
const text = `${v.glyph} ${word}`;
|
|
229
|
-
const pad = Math.max(1, STATUS_W - [...text].length);
|
|
230
|
-
return [
|
|
231
|
-
{ text, style: { fg, bold: v.bold === true } },
|
|
232
|
-
{ text: ' '.repeat(pad) },
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
|
-
/** The flush-right metadata cluster as fixed-width segments, so kind/mode · ctx ·
|
|
236
|
-
* age · project align into vertical columns down the right edge. `showCwd` adds the
|
|
237
|
-
* project column (only meaningful across All dirs). */
|
|
238
|
-
function metaCluster(r, now, showCwd) {
|
|
239
|
-
const ctxFg = ctxColorCode(r.ctx_tokens);
|
|
240
|
-
const out = [
|
|
241
|
-
{ text: clipPad(`${r.kind}/${r.mode}`, KM_W), style: { fg: FG_GRAY } },
|
|
242
|
-
{ text: COL_GAP },
|
|
243
|
-
{ text: fmtCtx(r.ctx_tokens).padStart(CTX_W), style: { fg: ctxFg, dim: ctxFg === undefined } },
|
|
244
|
-
{ text: COL_GAP },
|
|
245
|
-
{ text: relAge(r.created, now).padStart(AGE_W), style: { dim: true } },
|
|
246
|
-
];
|
|
247
|
-
if (showCwd) {
|
|
248
|
-
out.push({ text: COL_GAP }, { text: clipPad(`~${baseDir(r.cwd)}`, PROJ_W), style: { fg: FG_GRAY } });
|
|
249
|
-
}
|
|
250
|
-
return out;
|
|
251
|
-
}
|
|
252
|
-
/** Left-clip-pad: clip `s` to `w` cells then pad-end with spaces to exactly `w`. */
|
|
253
|
-
function clipPad(s, w) {
|
|
254
|
-
return clip(s, w).padEnd(w);
|
|
255
|
-
}
|
|
256
|
-
/** Compose a row from a flexible LEFT zone and a fixed flush-right RIGHT cluster:
|
|
257
|
-
* pad fills the gap so RIGHT hugs the edge; when the terminal is too narrow the
|
|
258
|
-
* cluster is dropped rather than colliding with the name. The caller has already
|
|
259
|
-
* clipped the name to fit. */
|
|
260
|
-
function assembleRow(left, right, width, color, lineBase, fill) {
|
|
261
|
-
const leftW = spansWidth(left);
|
|
262
|
-
const rightW = spansWidth(right);
|
|
263
|
-
if (right.length === 0 || leftW + rightW + 1 > width) {
|
|
264
|
-
return assemble(left, width, color, lineBase, fill);
|
|
265
|
-
}
|
|
266
|
-
const pad = width - leftW - rightW;
|
|
267
|
-
return assemble([...left, { text: ' '.repeat(pad) }, ...right], width, color, lineBase, fill);
|
|
268
|
-
}
|
|
269
|
-
/** One table row: `<status rail> <indent><collapse> <name> <flags>` ........ `<meta>`.
|
|
270
|
-
* `showCwd` adds the project column (All-dirs view); `now` drives the age. */
|
|
271
|
-
function rowLine(row, tree, width, isCursor, query, caps, showCwd, now, isPinned,
|
|
272
|
-
/** false in side-preview mode: the metadata cluster is replaced by the panel's
|
|
273
|
-
* facts block, so the name gets the whole row. */
|
|
274
|
-
showMeta = true,
|
|
275
|
-
/** true in side-preview mode: pad every row to exactly `width` so the vertical
|
|
276
|
-
* rule and the panel land in the same columns on every line. */
|
|
277
|
-
padToWidth = false) {
|
|
278
|
-
const node = tree.nodes.get(row.id);
|
|
279
|
-
if (node === undefined)
|
|
280
|
-
return '';
|
|
281
|
-
const r = node.row;
|
|
282
|
-
const indent = ' '.repeat(row.depth);
|
|
283
|
-
const collapse = !row.hasChildren ? ' ' : row.collapsed ? '▸' : '▾';
|
|
284
|
-
const terminal = r.status === 'done' || r.status === 'dead' || r.status === 'canceled';
|
|
285
|
-
// Left gutter (fixed slot): an eye when a viewer is ATTACHED — a scannable rail
|
|
286
|
-
// down the left edge of "what's on a screen right now". Blank otherwise.
|
|
287
|
-
const gutter = r.viewed === true
|
|
288
|
-
? { text: '\uf06e ', style: { fg: FG_BRIGHT_CYAN, bold: true } }
|
|
289
|
-
: { text: ' ' };
|
|
290
|
-
// Inline attention flag that travels with the name (fault summary lives in the rail,
|
|
291
|
-
// attached lives in the gutter).
|
|
292
|
-
const flags = [];
|
|
293
|
-
if (r.asks > 0)
|
|
294
|
-
flags.push({ text: ` ⚑${r.asks}`, style: { fg: FG_BRIGHT_YELLOW, bold: true } }); // pending asks
|
|
295
|
-
// Hanging: the fault summary travels with the name (the ⚠ + kind
|
|
296
|
-
// label live in the rail). Dim yellow so it reads as secondary detail.
|
|
297
|
-
if (r.hanging != null)
|
|
298
|
-
flags.push({ text: ` · ${faultSummary(r.hanging, now)}`, style: { fg: FG_YELLOW, dim: true } });
|
|
299
|
-
// Pin marker travels just before the name so a starred node is scannable in any
|
|
300
|
-
// tab/sort. Magenta keeps it distinct from the yellow ⚑ asks flag.
|
|
301
|
-
const pinMark = isPinned ? [{ text: '★ ', style: { fg: FG_MAGENTA, bold: true } }] : [];
|
|
302
|
-
const status = statusRail(r);
|
|
303
|
-
const right = showMeta ? metaCluster(r, now, showCwd) : [];
|
|
304
|
-
const treeLead = `${indent}${collapse} `;
|
|
305
|
-
// Clip the NAME (only) so gutter + status + tree + pin + name + flags + meta all
|
|
306
|
-
// fit; the cluster is dropped first (assembleRow) when even a 4-col name won't fit.
|
|
307
|
-
const fixed = spansWidth([gutter]) + spansWidth(status) + [...treeLead].length + spansWidth(pinMark) + spansWidth(flags);
|
|
308
|
-
const rightW = spansWidth(right);
|
|
309
|
-
const nameMax = Math.max(4, width - fixed - rightW - 1);
|
|
310
|
-
const nameStyle = { dim: !isCursor && terminal, bold: isCursor }; // dim terminal names; bold the cursor row
|
|
311
|
-
const left = [
|
|
312
|
-
gutter,
|
|
313
|
-
...status,
|
|
314
|
-
{ text: treeLead, style: { dim: true } },
|
|
315
|
-
...pinMark,
|
|
316
|
-
...nameSpans(clip(r.name, nameMax), query, nameStyle),
|
|
317
|
-
...flags,
|
|
318
|
-
];
|
|
319
|
-
// Row base: cursor → subtle bg (256) or reverse fallback (also !color); non-matched
|
|
320
|
-
// ancestor → whole-row dim for tree context.
|
|
321
|
-
let lineBase = '';
|
|
322
|
-
let fill = padToWidth;
|
|
323
|
-
if (isCursor) {
|
|
324
|
-
lineBase = caps.color256 ? CURSOR_BG : REVERSE;
|
|
325
|
-
fill = true;
|
|
326
|
-
}
|
|
327
|
-
else if (!row.matched) {
|
|
328
|
-
lineBase = DIM;
|
|
329
|
-
}
|
|
330
|
-
return assembleRow(left, right, width, caps.color, lineBase, fill);
|
|
331
|
-
}
|
|
332
|
-
/** The column-header row — dim labels aligned to the same zones the rows use, so
|
|
333
|
-
* the metadata columns read as a table. */
|
|
334
|
-
function columnHeaderLine(width, showCwd, caps, showMeta = true, padToWidth = false) {
|
|
335
|
-
const left = [
|
|
336
|
-
{ text: ' ' }, // viewer gutter (no label)
|
|
337
|
-
{ text: 'STATUS'.padEnd(STATUS_W), style: { dim: true, bold: true } },
|
|
338
|
-
{ text: 'NAME', style: { dim: true, bold: true } },
|
|
339
|
-
];
|
|
340
|
-
if (!showMeta)
|
|
341
|
-
return assemble(left, width, caps.color, '', padToWidth);
|
|
342
|
-
const right = [
|
|
343
|
-
{ text: 'KIND/MODE'.padEnd(KM_W), style: { dim: true, bold: true } },
|
|
344
|
-
{ text: COL_GAP },
|
|
345
|
-
{ text: 'CTX'.padStart(CTX_W), style: { dim: true, bold: true } },
|
|
346
|
-
{ text: COL_GAP },
|
|
347
|
-
{ text: 'AGE'.padStart(AGE_W), style: { dim: true, bold: true } },
|
|
348
|
-
];
|
|
349
|
-
if (showCwd)
|
|
350
|
-
right.push({ text: COL_GAP }, { text: 'PROJECT'.padEnd(PROJ_W), style: { dim: true, bold: true } });
|
|
351
|
-
return assembleRow(left, right, width, caps.color, '', false);
|
|
352
|
-
}
|
|
353
|
-
/** The status line (always present): active profile/cwd scopes · sort mode ·
|
|
354
|
-
* committed filter. The committed-filter indicator lives here now (not its own
|
|
355
|
-
* line) so a filtered view always advertises its query without consuming a header row. */
|
|
356
|
-
function statusLine(state) {
|
|
357
|
-
const dim = (s) => `${DIM}${s}${RESET}`;
|
|
358
|
-
const profile = state.profileScope === undefined ? 'all profiles' : 'current';
|
|
359
|
-
const scope = state.cwdScope === null ? 'all dirs' : baseDir(state.cwdScope);
|
|
360
|
-
const segs = [
|
|
361
|
-
`${dim('profile')} ${profile}`,
|
|
362
|
-
`${dim('scope')} ${scope}`,
|
|
363
|
-
`${dim('sort')} ${state.sort}`,
|
|
364
|
-
`${dim('lifecycle')} ${state.residentsOnly ? 'residents' : 'all'}`,
|
|
365
|
-
];
|
|
366
|
-
if (!state.search && state.query !== '')
|
|
367
|
-
segs.push(`${dim('filter')} ${state.query}`);
|
|
368
|
-
return segs.join(dim(' · '));
|
|
369
|
-
}
|
|
370
|
-
/** One snippet line → a rendered string with the query-matched columns in bold
|
|
371
|
-
* bright-cyan (mirrors the row name highlight). Unmatched text stays default. */
|
|
372
|
-
function snippetLine(ln, width, caps, base) {
|
|
373
|
-
if (ln.hi.size === 0)
|
|
374
|
-
return assemble([{ text: ln.text, style: base }], width, caps.color, '', false);
|
|
375
|
-
const spans = [];
|
|
376
|
-
let buf = '';
|
|
377
|
-
let bufHi = false;
|
|
378
|
-
const flush = () => {
|
|
379
|
-
if (buf === '')
|
|
380
|
-
return;
|
|
381
|
-
spans.push(bufHi ? { text: buf, style: { fg: FG_BRIGHT_CYAN, bold: true } } : { text: buf, style: base });
|
|
382
|
-
buf = '';
|
|
383
|
-
};
|
|
384
|
-
for (let i = 0; i < ln.text.length; i++) {
|
|
385
|
-
const h = ln.hi.has(i);
|
|
386
|
-
if (h !== bufHi) {
|
|
387
|
-
flush();
|
|
388
|
-
bufHi = h;
|
|
389
|
-
}
|
|
390
|
-
buf += ln.text[i];
|
|
391
|
-
}
|
|
392
|
-
flush();
|
|
393
|
-
return assemble(spans, width, caps.color, '', false);
|
|
394
|
-
}
|
|
395
|
-
/** How the fixed PREVIEW_BODY budget is divided for one row: the optional blocks
|
|
396
|
-
* take their two lines only when the node actually has them, and the remainder is
|
|
397
|
-
* split between the ask and the reply (ask keeps the odd line). */
|
|
398
|
-
export function previewAllocation(hasRecap, hasReport) {
|
|
399
|
-
const recap = hasRecap ? RECAP_LINES : 0;
|
|
400
|
-
const report = hasReport ? REPORT_LINES : 0;
|
|
401
|
-
const free = Math.max(2, PREVIEW_BODY - recap - report);
|
|
402
|
-
const ask = Math.ceil(free / 2);
|
|
403
|
-
return { recap, ask, reply: free - ask, report };
|
|
404
|
-
}
|
|
405
|
-
/** Render one marked block (`marker` on the first line, aligned continuation after)
|
|
406
|
-
* into exactly `lines` rows, or the `empty` placeholder when there is no text. */
|
|
407
|
-
function markedBlock(marker, text, empty, lines, width, caps, query) {
|
|
408
|
-
if (lines <= 0)
|
|
409
|
-
return [];
|
|
410
|
-
const out = [];
|
|
411
|
-
const mark = caps.color ? `${DIM}${marker}${RESET}` : marker;
|
|
412
|
-
const inner = Math.max(1, width - 2);
|
|
413
|
-
// No query → render the text as markdown (see blockLines for why a live query
|
|
414
|
-
// keeps the raw windowed path instead). No spacing: this panel is cramped.
|
|
415
|
-
if (query === '') {
|
|
416
|
-
const md = renderMarkdownSpans(text, inner, lines, false);
|
|
417
|
-
if (md.length === 0)
|
|
418
|
-
out.push(`${mark}${DIM}${clip(empty, inner)}${RESET}`);
|
|
419
|
-
else
|
|
420
|
-
for (const spans of md)
|
|
421
|
-
out.push(`${out.length === 0 ? mark : ' '}${assemble(spans, inner, caps.color, '', false)}`);
|
|
422
|
-
while (out.length < lines)
|
|
423
|
-
out.push('');
|
|
424
|
-
return out;
|
|
425
|
-
}
|
|
426
|
-
const snippet = previewSnippet(query, text, inner, lines);
|
|
427
|
-
if (snippet.length === 0) {
|
|
428
|
-
out.push(`${mark}${DIM}${clip(empty, inner)}${RESET}`);
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
for (const ln of snippet)
|
|
432
|
-
out.push(`${out.length === 0 ? mark : ' '}${snippetLine(ln, inner, caps)}`);
|
|
433
|
-
}
|
|
434
|
-
while (out.length < lines)
|
|
435
|
-
out.push('');
|
|
436
|
-
return out;
|
|
437
|
-
}
|
|
438
|
-
/** One `Goal`/`State` briefing line: a dim fixed-width label then the text. */
|
|
439
|
-
function recapLine(label, text, width, caps) {
|
|
440
|
-
const lbl = `${label.padEnd(6)}`;
|
|
441
|
-
const body = clip(text, Math.max(1, width - lbl.length));
|
|
442
|
-
return caps.color ? `${DIM}${lbl}${RESET}${BOLD}${body}${RESET}` : `${lbl}${body}`;
|
|
443
|
-
}
|
|
444
|
-
/** The bottom preview panel — exactly PREVIEW_HEIGHT lines, ordered by how fast
|
|
445
|
-
* each answers "which node was this, and can I pick it back up?":
|
|
446
|
-
*
|
|
447
|
-
* separator
|
|
448
|
-
* meta status · kind/mode · project · age · ctx · asks · fault/viewing
|
|
449
|
-
* Goal/State the node's last persisted recap briefing — the one-glance answer
|
|
450
|
-
* ❯ ask the spawn prompt in the user's own words (the recognition anchor),
|
|
451
|
-
* or, under a live query, the WINDOWED matching prompt from anywhere
|
|
452
|
-
* in the conversation with the match highlighted
|
|
453
|
-
* ↩ reply the node's last assistant message — where it actually left off
|
|
454
|
-
* ▣ report the newest thing it pushed (age · kind · headline), because a
|
|
455
|
-
* resident's reports are written to be read, unlike its live tail
|
|
456
|
-
*
|
|
457
|
-
* The optional blocks yield their lines to the literal ones when absent, so the
|
|
458
|
-
* panel is never padded with blanks. Always full height so viewport math holds. */
|
|
459
|
-
function previewPanel(r, width, caps, now, query) {
|
|
460
|
-
const out = [`${DIM}${'─'.repeat(width)}${RESET}`];
|
|
461
|
-
if (r === undefined) {
|
|
462
|
-
while (out.length < PREVIEW_HEIGHT)
|
|
463
|
-
out.push('');
|
|
464
|
-
return out;
|
|
465
|
-
}
|
|
466
|
-
const v = resolveNodeVisual(r.status, {
|
|
467
|
-
streaming: r.streaming === true,
|
|
468
|
-
frozen: isFrozenRow(r),
|
|
469
|
-
hanging: r.hanging ?? null,
|
|
470
|
-
});
|
|
471
|
-
const glyph = caps.color
|
|
472
|
-
? `${ESC}${v.color}m${v.glyph}${RESET}`
|
|
473
|
-
: v.glyph;
|
|
474
|
-
const metaPieces = [`${r.status} ${r.kind}/${r.mode}`, baseDir(r.cwd), relAge(r.created, now), `ctx ${fmtCtx(r.ctx_tokens)}`];
|
|
475
|
-
if (r.asks > 0)
|
|
476
|
-
metaPieces.push(`⚑${r.asks}`);
|
|
477
|
-
if (r.hanging != null)
|
|
478
|
-
metaPieces.push(faultSummary(r.hanging, now));
|
|
479
|
-
if (r.streaming === true)
|
|
480
|
-
metaPieces.push('⟳');
|
|
481
|
-
if (r.viewed === true)
|
|
482
|
-
metaPieces.push('\uf06e viewing');
|
|
483
|
-
const metaText = clip(metaPieces.filter((p) => p !== '').join(' · '), Math.max(0, width - 2));
|
|
484
|
-
out.push(caps.color ? `${glyph} ${DIM}${metaText}${RESET}` : `${glyph} ${metaText}`);
|
|
485
|
-
const alloc = previewAllocation(r.recap !== undefined, r.report !== undefined);
|
|
486
|
-
// Goal / State — the generated briefing, the fastest "what is this and where is
|
|
487
|
-
// it" in the panel. Absent for a node that never idled long enough to make one.
|
|
488
|
-
if (r.recap !== undefined) {
|
|
489
|
-
out.push(recapLine('Goal', r.recap.goal === '' ? '—' : r.recap.goal, width, caps));
|
|
490
|
-
out.push(recapLine('State', r.recap.state === '' ? '—' : r.recap.state, width, caps));
|
|
491
|
-
}
|
|
492
|
-
// The ask, verbatim. Under a live query this becomes the windowed match from the
|
|
493
|
-
// WHOLE conversation (the one thing a search result must show), so it keeps the
|
|
494
|
-
// query highlight; with no query it is the spawn prompt from the start.
|
|
495
|
-
const askText = query !== '' ? promptText(r) : (r.goal ?? '');
|
|
496
|
-
out.push(...markedBlock('❯ ', askText, '(no spawn prompt)', alloc.ask, width, caps, query));
|
|
497
|
-
// Where it left off.
|
|
498
|
-
out.push(...markedBlock('↩ ', r.lastAssistant ?? '', '(no reply yet)', alloc.reply, width, caps, ''));
|
|
499
|
-
// What it last delivered. The stamp + kind lead the line because a report's value
|
|
500
|
-
// here is "how recently did this node report, and was that its final?".
|
|
501
|
-
if (r.report !== undefined) {
|
|
502
|
-
const age = relAge(r.report.ts, now);
|
|
503
|
-
const stamp = `${age === '' ? '' : `${age} `}${r.report.kind}`;
|
|
504
|
-
const headline = r.report.heading === '' ? r.report.body : r.report.heading;
|
|
505
|
-
const mark = caps.color ? `${DIM}▣ ${RESET}` : '▣ ';
|
|
506
|
-
const inner = Math.max(1, width - 2);
|
|
507
|
-
const stampText = caps.color ? `${ESC}${FG_CYAN}m${stamp}${RESET}${DIM} · ${RESET}` : `${stamp} · `;
|
|
508
|
-
out.push(`${mark}${stampText}${clip(headline, Math.max(1, inner - stamp.length - 3))}`);
|
|
509
|
-
for (let i = 1; i < alloc.report; i++) {
|
|
510
|
-
const detail = r.report.heading === '' ? '' : r.report.body;
|
|
511
|
-
const ln = previewSnippet('', detail, inner, alloc.report - 1)[i - 1];
|
|
512
|
-
out.push(ln === undefined ? '' : ` ${DIM}${clip(ln.text, inner)}${RESET}`);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return out;
|
|
516
|
-
}
|
|
517
|
-
// ── The side preview panel ────────────────────────────────────────────────────
|
|
518
|
-
//
|
|
519
|
-
// Same four zones as the bottom panel (recap · ask · reply · report) with room to
|
|
520
|
-
// breathe, drawn as designed chrome instead of a wall of prose:
|
|
521
|
-
//
|
|
522
|
-
// <title row, drawn on the column-header line> ★ node name 8-char id
|
|
523
|
-
// ● active ⚑2 asks viewing ← state, in the status hue
|
|
524
|
-
// kind general/base ctx 42k ← facts block: dim right-aligned
|
|
525
|
-
// proj ~northlight age 3h labels, values in their own hues
|
|
526
|
-
// ── GOAL ───────────────────────────── ← hairline + small-caps label
|
|
527
|
-
// ▌ what this conversation is for ← accent bar: the hero quote
|
|
528
|
-
// ── ASK ──────────────────────────────
|
|
529
|
-
// ❯ the spawn prompt, hanging-indented
|
|
530
|
-
//
|
|
531
|
-
// Section bodies are allocated from the panel's real height: everyone asks for a
|
|
532
|
-
// natural size, the largest gives a line back until it fits, and only then does the
|
|
533
|
-
// least-valuable section drop out entirely (report → state → goal → reply; the ask
|
|
534
|
-
// is the recognition anchor and never drops).
|
|
535
|
-
/** A dim hairline with a small-caps section label — `── GOAL ────────`. The optional
|
|
536
|
-
* suffix rides after the label in its own hue (the report's age · kind stamp). */
|
|
537
|
-
function sectionRule(label, width, caps, suffix) {
|
|
538
|
-
const suf = suffix === undefined ? '' : `${suffix.text} `;
|
|
539
|
-
const tail = Math.max(0, width - 4 - label.length - suf.length);
|
|
540
|
-
const sufStyled = suffix === undefined
|
|
541
|
-
? ''
|
|
542
|
-
: caps.color ? `${ESC}${suffix.fg}m${suffix.text}${RESET}${DIM} ` : `${suffix.text} `;
|
|
543
|
-
return `${DIM}── ${BOLD}${label}${RESET}${DIM} ${sufStyled}${'─'.repeat(tail)}${RESET}`;
|
|
544
|
-
}
|
|
545
|
-
/** A marked body block with a hanging indent: `marker` leads the first line, `cont`
|
|
546
|
-
* every wrapped line after it (`▌ ` keeps the accent bar running down a quote).
|
|
547
|
-
* Returns the lines it actually filled — never padded, so the panel stacks tight.
|
|
548
|
-
* `empty` renders a dim placeholder for a block that must show even when absent. */
|
|
549
|
-
function blockLines(marker, cont, markerStyle, text, empty, maxLines, width, caps, query, bodyStyle) {
|
|
550
|
-
if (maxLines <= 0)
|
|
551
|
-
return [];
|
|
552
|
-
const indent = [...marker].length;
|
|
553
|
-
const inner = Math.max(1, width - indent);
|
|
554
|
-
const mk = (s, st) => assemble([{ text: s, style: st }], indent, caps.color, '', true);
|
|
555
|
-
// The ONE case that stays raw: under a live query the ask shows the windowed
|
|
556
|
-
// match with the matched columns highlighted, and stripping `**` would shift
|
|
557
|
-
// every later column out from under the highlight. Everything else renders
|
|
558
|
-
// markdown — headings, lists, and emphasis are how these messages were written.
|
|
559
|
-
if (query === '') {
|
|
560
|
-
const md = renderMarkdownSpans(text, inner, maxLines, true, bodyStyle);
|
|
561
|
-
if (md.length === 0) {
|
|
562
|
-
if (empty === undefined)
|
|
563
|
-
return [];
|
|
564
|
-
return [`${mk(marker, markerStyle)}${DIM}${clip(empty, inner)}${RESET}`];
|
|
565
|
-
}
|
|
566
|
-
return md.map((spans, i) => `${mk(i === 0 ? marker : cont, markerStyle)}${assemble(spans, inner, caps.color, '', false)}`);
|
|
567
|
-
}
|
|
568
|
-
const snippet = previewSnippet(query, text, inner, maxLines);
|
|
569
|
-
if (snippet.length === 0) {
|
|
570
|
-
if (empty === undefined)
|
|
571
|
-
return [];
|
|
572
|
-
return [`${mk(marker, markerStyle)}${DIM}${clip(empty, inner)}${RESET}`];
|
|
573
|
-
}
|
|
574
|
-
return snippet.map((ln, i) => `${mk(i === 0 ? marker : cont, markerStyle)}${snippetLine(ln, inner, caps, bodyStyle)}`);
|
|
575
|
-
}
|
|
576
|
-
// ── The chat transcript ───────────────────────────────────────────────
|
|
577
|
-
//
|
|
578
|
-
// The panel's centrepiece: the node's conversation painted the way the attach viewer
|
|
579
|
-
// paints it — a coloured left bar per turn, a small-caps role label, and the message
|
|
580
|
-
// body with its markdown honoured. It serves two jobs from one renderer:
|
|
581
|
-
//
|
|
582
|
-
// no query — the RECENT tail, newest turn last, so the panel reads as "where did
|
|
583
|
-
// this conversation get to".
|
|
584
|
-
// a query — only the turns that CONTAIN the query, oldest match first, with every
|
|
585
|
-
// occurrence highlighted and the skipped turns counted in a dim elision
|
|
586
|
-
// marker. Every visible line is then evidence for the search.
|
|
587
|
-
/** Rendered lines a single turn may occupy before it is windowed. Bounded by the
|
|
588
|
-
* per-message cap in readTranscript, so this is a ceiling, not a budget. */
|
|
589
|
-
const TURN_RENDER_MAX = 400;
|
|
590
|
-
/** Rendered lines kept above the first match when a matched turn must be windowed. */
|
|
591
|
-
const TURN_MATCH_LEAD = 1;
|
|
592
|
-
/** Lines a single turn may take when several turns share the panel. */
|
|
593
|
-
const TURN_SOFT_CAP = 14;
|
|
594
|
-
/** The matched-run style. `reverse` is structural SGR, so a search match stays
|
|
595
|
-
* visible with hue disabled — which the fg-only row highlight cannot manage. */
|
|
596
|
-
const MATCH_STYLE = { fg: FG_BRIGHT_CYAN, bold: true, reverse: true };
|
|
597
|
-
function spansText(spans) {
|
|
598
|
-
let out = '';
|
|
599
|
-
for (const s of spans)
|
|
600
|
-
out += s.text;
|
|
601
|
-
return out;
|
|
602
|
-
}
|
|
603
|
-
/** Re-style every case-insensitive occurrence of `query` inside already-rendered
|
|
604
|
-
* spans, splitting runs at the match edges. Working on the RENDERED text is what
|
|
605
|
-
* lets a transcript keep its markdown and still highlight: the markup is already
|
|
606
|
-
* gone, so no column can drift out from under a highlight. */
|
|
607
|
-
export function highlightSpans(spans, query) {
|
|
608
|
-
if (query === '')
|
|
609
|
-
return { spans, hits: 0 };
|
|
610
|
-
const text = spansText(spans);
|
|
611
|
-
const lower = text.toLowerCase();
|
|
612
|
-
const q = query.toLowerCase();
|
|
613
|
-
if (lower.indexOf(q) < 0)
|
|
614
|
-
return { spans, hits: 0 };
|
|
615
|
-
const hi = new Uint8Array(text.length);
|
|
616
|
-
let hits = 0;
|
|
617
|
-
for (let i = lower.indexOf(q); i >= 0; i = lower.indexOf(q, i + q.length)) {
|
|
618
|
-
hits++;
|
|
619
|
-
for (let j = i; j < i + q.length; j++)
|
|
620
|
-
hi[j] = 1;
|
|
621
|
-
}
|
|
622
|
-
const out = [];
|
|
623
|
-
let col = 0;
|
|
624
|
-
for (const s of spans) {
|
|
625
|
-
let buf = '';
|
|
626
|
-
let bufHi = hi[col] === 1;
|
|
627
|
-
for (let k = 0; k < s.text.length; k++) {
|
|
628
|
-
const h = hi[col] === 1;
|
|
629
|
-
if (h !== bufHi) {
|
|
630
|
-
if (buf !== '')
|
|
631
|
-
out.push({ text: buf, style: bufHi ? MATCH_STYLE : s.style });
|
|
632
|
-
buf = '';
|
|
633
|
-
bufHi = h;
|
|
634
|
-
}
|
|
635
|
-
buf += s.text[k];
|
|
636
|
-
col++;
|
|
637
|
-
}
|
|
638
|
-
if (buf !== '')
|
|
639
|
-
out.push({ text: buf, style: bufHi ? MATCH_STYLE : s.style });
|
|
640
|
-
}
|
|
641
|
-
return { spans: out, hits };
|
|
642
|
-
}
|
|
643
|
-
const TURN_BAR = '▌ ';
|
|
644
|
-
/** Paint one turn: `▌ YOU` / `▌ AGENT` then the body, every line carrying the bar so
|
|
645
|
-
* a turn stays one contiguous block. The user's bar is the cyan accent and the
|
|
646
|
-
* agent's is dim gray — the same weight distinction the row table already uses
|
|
647
|
-
* between what you said and what the runtime produced. */
|
|
648
|
-
function turnBlock(turn, query, maxLines, width, caps) {
|
|
649
|
-
if (maxLines < 2)
|
|
650
|
-
return { lines: [], hits: 0, truncated: true };
|
|
651
|
-
const user = turn.role === 'user';
|
|
652
|
-
const barStyle = user ? { fg: FG_BRIGHT_CYAN, bold: true } : { fg: FG_GRAY };
|
|
653
|
-
const inner = Math.max(1, width - TURN_BAR.length);
|
|
654
|
-
const bar = () => assemble([{ text: TURN_BAR, style: barStyle }], TURN_BAR.length, caps.color, '', true);
|
|
655
|
-
const out = [
|
|
656
|
-
assemble([{ text: TURN_BAR, style: barStyle }, { text: user ? 'YOU' : 'AGENT', style: { ...barStyle, bold: true } }], width, caps.color, '', false),
|
|
657
|
-
];
|
|
658
|
-
const body = renderMarkdownSpans(turn.text, inner, TURN_RENDER_MAX, false, user ? {} : { dim: true });
|
|
659
|
-
const marked = body.map((spans) => highlightSpans(spans, query));
|
|
660
|
-
const hits = marked.reduce((n, m) => n + m.hits, 0);
|
|
661
|
-
// Window the body when it outgrows its slice of the panel. Searching, the window
|
|
662
|
-
// opens on the first match (that is the only line the search has to prove); idle,
|
|
663
|
-
// it opens at the top of the message.
|
|
664
|
-
const budget = maxLines - 1;
|
|
665
|
-
let start = 0;
|
|
666
|
-
if (marked.length > budget && hits > 0) {
|
|
667
|
-
start = Math.max(0, marked.findIndex((m) => m.hits > 0) - TURN_MATCH_LEAD);
|
|
668
|
-
start = Math.min(start, marked.length - budget);
|
|
669
|
-
}
|
|
670
|
-
const shown = marked.slice(start, start + budget);
|
|
671
|
-
for (const m of shown)
|
|
672
|
-
out.push(`${bar()}${assemble(m.spans, inner, caps.color, '', false)}`);
|
|
673
|
-
// An honest edge: a windowed body must not read as the whole message. The marker
|
|
674
|
-
// costs a body line, so it is only worth drawing when a body line survives it.
|
|
675
|
-
const cutHead = start > 0;
|
|
676
|
-
const cutTail = start + shown.length < marked.length;
|
|
677
|
-
if (cutHead && shown.length > 1)
|
|
678
|
-
out[1] = `${bar()}${DIM}⋯${RESET}`;
|
|
679
|
-
if (cutTail && shown.length > (cutHead ? 2 : 1))
|
|
680
|
-
out[out.length - 1] = `${bar()}${DIM}⋯${RESET}`;
|
|
681
|
-
return { lines: out, hits, truncated: cutHead || cutTail };
|
|
682
|
-
}
|
|
683
|
-
/** The dim `⋯ n turns` marker standing in for turns the search skipped over. */
|
|
684
|
-
function elisionLine(n, width, caps) {
|
|
685
|
-
return assemble([{ text: ` ⋯ ${n} ${n === 1 ? 'turn' : 'turns'}`, style: { dim: true } }], width, caps.color, '', false);
|
|
686
|
-
}
|
|
687
|
-
/** Does this turn contain the query as a literal, case-insensitive substring?
|
|
688
|
-
* Scattered letters are not a transcript hit — the same rule the row preview uses. */
|
|
689
|
-
function turnMatches(turn, query) {
|
|
690
|
-
return query !== '' && turn.text.toLowerCase().indexOf(query.toLowerCase()) >= 0;
|
|
691
|
-
}
|
|
692
|
-
/** How many turns contain the query — the count the section rule advertises. */
|
|
693
|
-
export function transcriptHitTurns(turns, query) {
|
|
694
|
-
return turns.reduce((n, t) => n + (turnMatches(t, query) ? 1 : 0), 0);
|
|
695
|
-
}
|
|
696
|
-
/** The transcript body, at most `height` lines. With a query it shows the matching
|
|
697
|
-
* turns from the oldest match forward; without one it shows the newest turns,
|
|
698
|
-
* bottom-anchored so the latest turn is the last line — the chat reading order. */
|
|
699
|
-
function transcriptLines(turns, query, width, height, caps) {
|
|
700
|
-
if (height <= 0 || turns.length === 0)
|
|
701
|
-
return [];
|
|
702
|
-
const hitIdx = query === '' ? [] : turns.map((t, i) => (turnMatches(t, query) ? i : -1)).filter((i) => i >= 0);
|
|
703
|
-
// Searching with hits: forward from the oldest match, eliding the gaps.
|
|
704
|
-
if (hitIdx.length > 0) {
|
|
705
|
-
const out = [];
|
|
706
|
-
let prev = -1;
|
|
707
|
-
for (const i of hitIdx) {
|
|
708
|
-
const lead = out.length === 0 ? 0 : 1; // blank separator between turns
|
|
709
|
-
const left = height - out.length - lead;
|
|
710
|
-
if (left < 3)
|
|
711
|
-
break; // a header over one elision marker proves nothing
|
|
712
|
-
const { lines } = turnBlock(turns[i], query, Math.min(left, TURN_SOFT_CAP), width, caps);
|
|
713
|
-
if (lines.length === 0)
|
|
714
|
-
break;
|
|
715
|
-
const gap = prev < 0 ? i : i - prev - 1;
|
|
716
|
-
const marker = gap > 0 && out.length + lead + lines.length + 1 <= height;
|
|
717
|
-
if (lead > 0)
|
|
718
|
-
out.push('');
|
|
719
|
-
if (marker)
|
|
720
|
-
out.push(elisionLine(gap, width, caps));
|
|
721
|
-
out.push(...lines);
|
|
722
|
-
prev = i;
|
|
723
|
-
}
|
|
724
|
-
// Slack goes to the turns that FOLLOW the last match, painted in full, so the
|
|
725
|
-
// panel reads on as a conversation instead of stopping dead at the evidence.
|
|
726
|
-
let last = prev;
|
|
727
|
-
for (let i = prev + 1; i < turns.length; i++) {
|
|
728
|
-
const left = height - out.length - 1;
|
|
729
|
-
if (left < 3)
|
|
730
|
-
break;
|
|
731
|
-
const { lines, truncated } = turnBlock(turns[i], query, Math.min(left, TURN_SOFT_CAP), width, caps);
|
|
732
|
-
if (lines.length === 0 || truncated)
|
|
733
|
-
break;
|
|
734
|
-
out.push('', ...lines);
|
|
735
|
-
last = i;
|
|
736
|
-
}
|
|
737
|
-
if (last >= 0 && last < turns.length - 1 && out.length < height) {
|
|
738
|
-
out.push(elisionLine(turns.length - 1 - last, width, caps));
|
|
739
|
-
}
|
|
740
|
-
return out.slice(0, height);
|
|
741
|
-
}
|
|
742
|
-
// No query (or a query that only matched the node's name/kind/id): the tail.
|
|
743
|
-
// Built newest-first so the budget is spent on recent turns, then reversed.
|
|
744
|
-
const blocks = [];
|
|
745
|
-
let used = 0;
|
|
746
|
-
for (let i = turns.length - 1; i >= 0; i--) {
|
|
747
|
-
const newest = blocks.length === 0;
|
|
748
|
-
const lead = newest ? 0 : 1;
|
|
749
|
-
const left = height - used - lead;
|
|
750
|
-
if (left < 3)
|
|
751
|
-
break;
|
|
752
|
-
const { lines, truncated } = turnBlock(turns[i], '', Math.min(left, TURN_SOFT_CAP), width, caps);
|
|
753
|
-
if (lines.length === 0)
|
|
754
|
-
break;
|
|
755
|
-
// Only the newest turn may be shown cut — an older one that no longer fits is
|
|
756
|
-
// dropped whole rather than left as a header over an elision marker, which
|
|
757
|
-
// reads as a message the panel refused to show.
|
|
758
|
-
if (truncated && !newest)
|
|
759
|
-
break;
|
|
760
|
-
if (lead > 0)
|
|
761
|
-
blocks.push(['']);
|
|
762
|
-
blocks.push(lines);
|
|
763
|
-
used += lines.length + lead;
|
|
764
|
-
}
|
|
765
|
-
return blocks.reverse().flat().slice(-height);
|
|
766
|
-
}
|
|
767
|
-
/** What an empty panel body MEANS. `(no conversation yet)` is a claim about the
|
|
768
|
-
* node; it is only true once the session has actually been read. Until then the
|
|
769
|
-
* same blank body means the read is still in flight, and printing the claim made a
|
|
770
|
-
* node the panel had simply not gotten to yet look like a node that had never
|
|
771
|
-
* spoken. */
|
|
772
|
-
function emptyBodyNote(r) {
|
|
773
|
-
const read = r.transcriptLoaded === true || r.previewLoaded === true;
|
|
774
|
-
return read ? `${DIM}(no conversation yet)${RESET}` : `${DIM}(loading…)${RESET}`;
|
|
775
|
-
}
|
|
776
|
-
/** The turns the panel paints. A node that was never revived has no session, so its
|
|
777
|
-
* spawn prompt and last reply stand in — the panel then still reads as a chat
|
|
778
|
-
* rather than going blank, and a remote canvas (no local session file) keeps a body. */
|
|
779
|
-
function panelTurns(r) {
|
|
780
|
-
const t = r.transcript;
|
|
781
|
-
if (t !== undefined && t.length > 0)
|
|
782
|
-
return t;
|
|
783
|
-
const out = [];
|
|
784
|
-
if (r.goal !== undefined && r.goal !== '')
|
|
785
|
-
out.push({ role: 'user', text: r.goal });
|
|
786
|
-
if (r.lastAssistant !== undefined && r.lastAssistant !== '')
|
|
787
|
-
out.push({ role: 'assistant', text: r.lastAssistant });
|
|
788
|
-
return out;
|
|
789
|
-
}
|
|
790
|
-
/** Lines the GOAL and STATE briefings each get. They are one-sentence summaries by
|
|
791
|
-
* construction, so a small fixed budget leaves the chat everything else. */
|
|
792
|
-
const BRIEFING_LINES = 4;
|
|
793
|
-
/** The panel's one metadata line. Deliberately ONE line: the row the cursor sits on
|
|
794
|
-
* already carries this node's status word, ask flag, fault and viewer cues, so a
|
|
795
|
-
* status line and a four-cell facts grid here would spend six of the panel's rows
|
|
796
|
-
* repeating what is on screen a few columns to the left. What is left is what the
|
|
797
|
-
* row table gave up in side mode — kind/mode, project, age, ctx. */
|
|
798
|
-
function panelFactsLine(r, width, now, caps) {
|
|
799
|
-
const ctxFg = ctxColorCode(r.ctx_tokens);
|
|
800
|
-
const dot = () => ({ text: ' · ', style: { dim: true } });
|
|
801
|
-
const spans = [
|
|
802
|
-
{ text: `${r.kind}/${r.mode}`, style: { fg: FG_GRAY } },
|
|
803
|
-
dot(),
|
|
804
|
-
{ text: `~${baseDir(r.cwd)}`, style: { fg: FG_GRAY } },
|
|
805
|
-
dot(),
|
|
806
|
-
{ text: relAge(r.created, now), style: { dim: true } },
|
|
807
|
-
dot(),
|
|
808
|
-
{ text: `ctx ${fmtCtx(r.ctx_tokens)}`, style: { fg: ctxFg, dim: ctxFg === undefined } },
|
|
809
|
-
];
|
|
810
|
-
return assemble(spans, width, caps.color, '', false);
|
|
811
|
-
}
|
|
812
|
-
/** The panel's title, drawn on the column-header row so the header rule crosses
|
|
813
|
-
* beneath it: the pinned star, the node name in bold, its short id flush right. */
|
|
814
|
-
function panelTitleLine(r, width, caps, isPinned) {
|
|
815
|
-
if (r === undefined)
|
|
816
|
-
return assemble([{ text: 'PREVIEW', style: { dim: true, bold: true } }], width, caps.color, '', false);
|
|
817
|
-
const left = [];
|
|
818
|
-
if (isPinned)
|
|
819
|
-
left.push({ text: '★ ', style: { fg: FG_MAGENTA, bold: true } });
|
|
820
|
-
const id = r.node_id.slice(0, 8);
|
|
821
|
-
left.push({ text: clip(r.name, Math.max(4, width - id.length - 2 - spansWidth(left))), style: { bold: true } });
|
|
822
|
-
return assembleRow(left, [{ text: id, style: { dim: true } }], width, caps.color, '', false);
|
|
823
|
-
}
|
|
824
|
-
/** The side panel's body, at most `height` lines. Three exclusive shapes:
|
|
825
|
-
*
|
|
826
|
-
* searching — the panel IS a chat transcript: the turns that literally contain
|
|
827
|
-
* the query, oldest match first, every occurrence highlighted.
|
|
828
|
-
* report — the node's newest pushed report in full (toggled with `V`).
|
|
829
|
-
* default — goal on top, the recent conversation in the middle, state pinned to
|
|
830
|
-
* the bottom edge. That is the vertical order the live chat surface
|
|
831
|
-
* uses, so the preview reads as a small copy of the conversation it
|
|
832
|
-
* is previewing instead of a different presentation of the same node.
|
|
833
|
-
*/
|
|
834
|
-
function sidePanelBody(r, width, height, caps, now, query, showReport) {
|
|
835
|
-
if (height <= 0)
|
|
836
|
-
return [];
|
|
837
|
-
if (r === undefined)
|
|
838
|
-
return [`${DIM}(no selection)${RESET}`];
|
|
839
|
-
// ── searching ── the transcript takes the whole panel. The goal/state briefing is
|
|
840
|
-
// a summary, and a summary cannot show you WHERE your term appears.
|
|
841
|
-
if (query !== '') {
|
|
842
|
-
const turns = panelTurns(r);
|
|
843
|
-
const hits = transcriptHitTurns(turns, query);
|
|
844
|
-
const out = [sectionRule('TRANSCRIPT', width, caps, hits > 0
|
|
845
|
-
? { text: `${hits} ${hits === 1 ? 'turn' : 'turns'}`, fg: FG_BRIGHT_CYAN }
|
|
846
|
-
: { text: 'matched on name', fg: FG_GRAY })];
|
|
847
|
-
const body = transcriptLines(turns, query, width, height - 1, caps);
|
|
848
|
-
out.push(...(body.length === 0 ? [emptyBodyNote(r)] : body));
|
|
849
|
-
return out.slice(0, height);
|
|
850
|
-
}
|
|
851
|
-
const rep = r.report;
|
|
852
|
-
const accentOf = () => {
|
|
853
|
-
const v = resolveNodeVisual(r.status, {
|
|
854
|
-
streaming: r.streaming === true, frozen: isFrozenRow(r), hanging: r.hanging ?? null,
|
|
855
|
-
});
|
|
856
|
-
return { fg: v.color };
|
|
857
|
-
};
|
|
858
|
-
// ── report ── what the node deliberately DELIVERED, at full length. Reports are
|
|
859
|
-
// written to be read, so this one gets the panel rather than a two-line teaser.
|
|
860
|
-
if (showReport && rep !== undefined) {
|
|
861
|
-
const age = relAge(rep.ts, now);
|
|
862
|
-
const out = [sectionRule('REPORT', width, caps, { text: `${age === '' ? '' : `${age} · `}${rep.kind}`, fg: FG_CYAN })];
|
|
863
|
-
const headline = rep.heading === '' ? rep.body : rep.heading;
|
|
864
|
-
out.push(...blockLines('▣ ', ' ', { fg: FG_CYAN, bold: true }, headline, undefined, 3, width, caps, '', { bold: true }));
|
|
865
|
-
if (rep.heading !== '' && rep.body !== '') {
|
|
866
|
-
out.push('');
|
|
867
|
-
out.push(...blockLines(' ', ' ', undefined, rep.body, undefined, height - out.length, width, caps, ''));
|
|
868
|
-
}
|
|
869
|
-
return out.slice(0, height);
|
|
870
|
-
}
|
|
871
|
-
// ── default ── goal, chat, state.
|
|
872
|
-
const out = [panelFactsLine(r, width, now, caps), ''];
|
|
873
|
-
const accent = accentOf();
|
|
874
|
-
const briefing = (label, text) => [
|
|
875
|
-
sectionRule(label, width, caps),
|
|
876
|
-
...blockLines('▌ ', '▌ ', accent, text, undefined, BRIEFING_LINES, width, caps, '', { bold: true }),
|
|
877
|
-
];
|
|
878
|
-
const goal = r.recap?.goal ?? '';
|
|
879
|
-
if (goal !== '')
|
|
880
|
-
out.push(...briefing('GOAL', goal), '');
|
|
881
|
-
// State is measured before the chat is drawn so the chat can claim exactly the
|
|
882
|
-
// slack that is left and state still lands on the panel's bottom edge.
|
|
883
|
-
const stateText = r.recap?.state ?? '';
|
|
884
|
-
const stateBlock = stateText === '' ? [] : [...briefing('STATE', stateText)];
|
|
885
|
-
const reserved = stateBlock.length === 0 ? 0 : stateBlock.length + 1;
|
|
886
|
-
const chatH = height - out.length - reserved - 1 /* the CHAT rule */;
|
|
887
|
-
if (chatH >= 2) {
|
|
888
|
-
out.push(sectionRule('CHAT', width, caps));
|
|
889
|
-
const body = transcriptLines(panelTurns(r), '', width, chatH, caps);
|
|
890
|
-
out.push(...(body.length === 0 ? [emptyBodyNote(r)] : body));
|
|
891
|
-
}
|
|
892
|
-
if (stateBlock.length > 0) {
|
|
893
|
-
while (out.length < height - stateBlock.length)
|
|
894
|
-
out.push('');
|
|
895
|
-
out.push(...stateBlock);
|
|
896
|
-
}
|
|
897
|
-
return out.slice(0, height);
|
|
898
|
-
}
|
|
899
|
-
/** The keybinding help overlay — a full-screen cheatsheet that replaces the body
|
|
900
|
-
* while `?` is held open. Grouped by intent so the whole key surface is legible in
|
|
901
|
-
* one glance (the footer only ever advertises the common few). */
|
|
902
|
-
const HELP_ROWS = [
|
|
903
|
-
['Move', '↑/↓ j/k', 'up / down'],
|
|
904
|
-
['', 'g / G', 'top / bottom'],
|
|
905
|
-
['', '.', 'jump to this node (recenter)'],
|
|
906
|
-
['Tree', '→/← h/l', 'expand / collapse'],
|
|
907
|
-
['', 'space', 'toggle fold'],
|
|
908
|
-
['Tabs', 'Tab / 1-5', 'All · Live · Dormant · Attention · Pinned'],
|
|
909
|
-
['Find', '/', 'fuzzy search (name · kind · id · prompts)'],
|
|
910
|
-
['Pin', 'p', 'star / unstar — floats to top, Pinned tab'],
|
|
911
|
-
['Open', '⏎ o', 'open conversation (closes navigator)'],
|
|
912
|
-
['', 'O', 'open, keep browsing (background)'],
|
|
913
|
-
['Act', 'y', 'copy the node id to the clipboard'],
|
|
914
|
-
['', 'm', 'message the node (no resume)'],
|
|
915
|
-
['', 'R', 'rename the node'],
|
|
916
|
-
['', 'x', 'close-out node + subtree'],
|
|
917
|
-
['', 'K', 'revive now (a hanging node)'],
|
|
918
|
-
['View', 's', 'cycle sort (attention/tree/relevance/recency)'],
|
|
919
|
-
['', 'c', 'toggle cwd scope'],
|
|
920
|
-
['', 'P', 'toggle profile scope'],
|
|
921
|
-
['', 'r', 'toggle residents-only'],
|
|
922
|
-
['', 'v', 'toggle preview (goal, chat, state)'],
|
|
923
|
-
['', 'V', 'in the preview: swap chat for the newest report'],
|
|
924
|
-
['Quit', 'q / Esc', ''],
|
|
925
|
-
];
|
|
926
|
-
function renderHelp(size, caps) {
|
|
927
|
-
const cols = Math.max(20, size.cols);
|
|
928
|
-
const rows = Math.max(8, size.rows);
|
|
929
|
-
const width = cols - 1;
|
|
930
|
-
const lines = [];
|
|
931
|
-
lines.push(`${BOLD}Canvas navigator — keys${RESET}`);
|
|
932
|
-
lines.push('');
|
|
933
|
-
const dim = (s) => `${DIM}${s}${RESET}`;
|
|
934
|
-
for (const [group, keys, desc] of HELP_ROWS) {
|
|
935
|
-
const g = group.padEnd(6);
|
|
936
|
-
const k = keys.padEnd(12);
|
|
937
|
-
const line = ` ${dim(g)}${BOLD}${k}${RESET}${desc === '' ? '' : ` ${dim(desc)}`}`;
|
|
938
|
-
lines.push(clip(line, width));
|
|
939
|
-
}
|
|
940
|
-
lines.push('');
|
|
941
|
-
lines.push(dim(' ? or any key to close'));
|
|
942
|
-
while (lines.length < rows - 1)
|
|
943
|
-
lines.push('');
|
|
944
|
-
const body = lines.map((l) => `${l}${ESC}K`).join('\r\n');
|
|
945
|
-
return `${ESC}H${body}${ESC}J`;
|
|
946
|
-
}
|
|
947
|
-
/**
|
|
948
|
-
* Render the whole frame. Returns a single string that, written as-is, repaints
|
|
949
|
-
* the screen in place. `caps` gates all hue (defaults to a no-color frame so
|
|
950
|
-
* existing callers / non-TTY paths stay color-free).
|
|
951
|
-
*/
|
|
952
|
-
export function renderFrame(state, size, caps = { color: false, color256: false }) {
|
|
953
|
-
if (state.help === true)
|
|
954
|
-
return renderHelp(size, caps);
|
|
955
|
-
const cols = Math.max(20, size.cols);
|
|
956
|
-
const rows = Math.max(8, size.rows);
|
|
957
|
-
const width = cols - 1; // leave the last column for \x1b[K
|
|
958
|
-
const now = Date.now();
|
|
959
|
-
const inputMode = state.search || state.rename === true || state.message === true;
|
|
960
|
-
const lines = [];
|
|
961
|
-
// line 1 — title + right-aligned status summary (each glyph in its status hue).
|
|
962
|
-
const title = `${BOLD}Canvas${RESET} — ${state.totalNodes} nodes`;
|
|
963
|
-
const titlePlainLen = `Canvas — ${state.totalNodes} nodes`.length;
|
|
964
|
-
const parts = statusCounts(state.tree);
|
|
965
|
-
const summaryPlain = parts.map((p) => `${STATUS_GLYPH[p.status]}${p.count}`).join(' ');
|
|
966
|
-
const summaryColored = caps.color
|
|
967
|
-
? parts.map((p) => `${ESC}${STATUS_COLOR[p.status]}m${STATUS_GLYPH[p.status]}${RESET}${DIM}${p.count}${RESET}`).join(' ')
|
|
968
|
-
: `${DIM}${summaryPlain}${RESET}`;
|
|
969
|
-
const gap = width - titlePlainLen - summaryPlain.length;
|
|
970
|
-
lines.push(gap > 1 ? `${title}${' '.repeat(gap)}${summaryColored}` : title);
|
|
971
|
-
// line 2 — tab bar.
|
|
972
|
-
lines.push(tabBar(state.tab, caps.color));
|
|
973
|
-
// line 3 — status line (scope · sort · filter).
|
|
974
|
-
lines.push(statusLine(state));
|
|
975
|
-
// line 4 — the text-input prompt, only while a search / rename / message is open.
|
|
976
|
-
if (inputMode) {
|
|
977
|
-
const prefix = state.rename === true ? 'rename ▸' : state.message === true ? 'msg ▸' : '/';
|
|
978
|
-
const buf = state.rename === true ? (state.renameBuf ?? '') : state.message === true ? (state.messageBuf ?? '') : state.query;
|
|
979
|
-
const p = caps.color ? `${ESC}${FG_CYAN}m${prefix}${RESET}` : prefix;
|
|
980
|
-
lines.push(`${p} ${buf}▎`);
|
|
981
|
-
}
|
|
982
|
-
// Where the preview goes at this width: a full-height right-hand column when
|
|
983
|
-
// there is room for one, else the bottom panel. In side mode the rows give up
|
|
984
|
-
// their metadata cluster and the panel takes those columns.
|
|
985
|
-
const previewOn = state.preview && state.visible.length > 0;
|
|
986
|
-
const layout = previewLayout(cols, previewOn);
|
|
987
|
-
const side = layout.mode === 'side';
|
|
988
|
-
const rowsW = side ? layout.rowsW : width;
|
|
989
|
-
const gutter = `${DIM}${SIDE_GUTTER}${RESET}`;
|
|
990
|
-
const sel = state.visible[state.cursor];
|
|
991
|
-
const selRow = sel !== undefined ? state.tree.nodes.get(sel.id)?.row : undefined;
|
|
992
|
-
// column header (table labels, plus the panel title in side mode) + separator.
|
|
993
|
-
const showCwd = state.cwdScope === null && !side; // project column only matters across dirs
|
|
994
|
-
const colHeader = columnHeaderLine(rowsW, showCwd, caps, !side, side);
|
|
995
|
-
lines.push(side
|
|
996
|
-
? `${colHeader}${gutter}${panelTitleLine(selRow, layout.panelW, caps, sel !== undefined && state.pinned.has(sel.id))}`
|
|
997
|
-
: colHeader);
|
|
998
|
-
lines.push(side
|
|
999
|
-
? `${DIM}${'─'.repeat(rowsW)}─┼─${'─'.repeat(layout.panelW)}${RESET}`
|
|
1000
|
-
: `${DIM}${'─'.repeat(width)}${RESET}`);
|
|
1001
|
-
// body — windowed visible rows, leaving room for the (optional) bottom panel.
|
|
1002
|
-
const head = lines.length; // === headerHeight(state.search)
|
|
1003
|
-
const previewH = layout.mode === 'bottom' ? PREVIEW_HEIGHT : 0;
|
|
1004
|
-
const viewport = Math.max(1, rows - head - 1 /* footer */ - previewH);
|
|
1005
|
-
const start = state.scrollOffset;
|
|
1006
|
-
const end = Math.min(state.visible.length, start + viewport);
|
|
1007
|
-
// In side mode each body line is `<row><rule><panel line>`, so the rows are padded
|
|
1008
|
-
// to an exact width and the panel body is rendered once for the whole column.
|
|
1009
|
-
const panel = side ? sidePanelBody(selRow, layout.panelW, viewport, caps, now, state.query, state.showReport === true) : [];
|
|
1010
|
-
const compose = (row, i) => (side ? `${row}${gutter}${panel[i] ?? ''}` : row);
|
|
1011
|
-
const blankRow = side ? ' '.repeat(rowsW) : '';
|
|
1012
|
-
if (state.visible.length === 0) {
|
|
1013
|
-
lines.push(`${DIM} (no nodes match this view)${RESET}`);
|
|
1014
|
-
for (let i = 1; i < viewport; i++)
|
|
1015
|
-
lines.push('');
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
for (let i = start; i < end; i++) {
|
|
1019
|
-
const vr = state.visible[i];
|
|
1020
|
-
lines.push(compose(rowLine(vr, state.tree, rowsW, i === state.cursor, state.query, caps, showCwd, now, state.pinned.has(vr.id), !side, side), i - start));
|
|
1021
|
-
}
|
|
1022
|
-
for (let i = end - start; i < viewport; i++)
|
|
1023
|
-
lines.push(compose(blankRow, i));
|
|
1024
|
-
}
|
|
1025
|
-
// bottom preview panel — the narrow-terminal layout.
|
|
1026
|
-
if (layout.mode === 'bottom') {
|
|
1027
|
-
for (const l of previewPanel(selRow, width, caps, now, state.query))
|
|
1028
|
-
lines.push(l);
|
|
1029
|
-
}
|
|
1030
|
-
// footer — the y/n close-out confirm takes over when pending; else search / nav.
|
|
1031
|
-
if (state.pendingClose !== null && state.pendingClose !== undefined) {
|
|
1032
|
-
const node = state.tree.nodes.get(state.pendingClose);
|
|
1033
|
-
const who = node !== undefined ? node.row.name : state.pendingClose;
|
|
1034
|
-
const warn = `⚠ ${who} is ⟳ — close it (and its subtree) anyway? y / n`;
|
|
1035
|
-
lines.push(caps.color ? `${BOLD}${ESC}${FG_BRIGHT_YELLOW}m${clip(warn, width)}${RESET}` : `${REVERSE}${clip(warn, width)}${RESET}`);
|
|
1036
|
-
}
|
|
1037
|
-
else if (state.flash !== null && state.flash !== undefined && state.flash !== '') {
|
|
1038
|
-
lines.push(caps.color ? `${BOLD}${clip(state.flash, width)}${RESET}` : `${REVERSE}${clip(state.flash, width)}${RESET}`);
|
|
1039
|
-
}
|
|
1040
|
-
else {
|
|
1041
|
-
// When the cursor row has an active fault, lead the footer with the on-demand kick
|
|
1042
|
-
// hint (K shells `node lifecycle revive <id> --now` — immediate revive instead of
|
|
1043
|
-
// waiting for the daemon's retry schedule).
|
|
1044
|
-
const hangingHint = selRow?.hanging != null ? 'K revive now ' : '';
|
|
1045
|
-
const footer = inputMode
|
|
1046
|
-
? '⏎ commit Esc cancel ⌫ delete'
|
|
1047
|
-
: state.readOnly === true
|
|
1048
|
-
? '↑↓ move →/← tree / search p pin v preview Tab tabs ? more q quit — read-only remote canvas'
|
|
1049
|
-
: `${hangingHint}${selRow?.report !== undefined && side && state.query === '' ? (state.showReport === true ? 'V chat ' : 'V report ') : ''}↑↓ move ⏎ open O bg / search p pin v preview m msg x close ? more q quit`;
|
|
1050
|
-
lines.push(`${DIM}${clip(footer, width)}${RESET}`);
|
|
1051
|
-
}
|
|
1052
|
-
// Assemble: home, each line cleared to EOL, then clear below.
|
|
1053
|
-
const body = lines.map((l) => `${l}${ESC}K`).join('\r\n');
|
|
1054
|
-
return `${ESC}H${body}${ESC}J`;
|
|
1055
|
-
}
|
|
1
|
+
var Nt=Object.defineProperty;var f=(t,n)=>Nt(t,"name",{value:n,configurable:!0});import{STATUS_GLYPH as rt,STATUS_COLOR as It,isFrozenRow as J,resolveNodeVisual as X,faultSummary as lt}from"../status-glyph.js";import{TABS as Pt,promptText as Ht,previewSnippet as q}from"./model.js";import{matchIndices as Gt}from"../../tui/fuzzy.js";import{clip as _,assemble as w,detectColorCaps as Dt}from"../../tui/draw.js";import{renderMarkdownSpans as Q}from"../../tui/markdown.js";const Bt=2,Ft=2,ct=8,it=ct+2,Ut=100,ut=46,jt=110,Yt=.55,at=40,dt=" \u2502 ";function Vt(t,n){const e=Math.max(20,t)-1;if(!n)return{mode:"none",panelW:0,rowsW:e};if(t<Ut)return{mode:"bottom",panelW:0,rowsW:e};const s=[...dt].length;let r=Math.min(jt,Math.max(ut,Math.round(e*Yt)));return e-r-s<at&&(r=e-s-at),r<ut?{mode:"bottom",panelW:0,rowsW:e}:{mode:"side",panelW:r,rowsW:e-r-s}}f(Vt,"previewLayout");function Me(t){return 5+(t?1:0)}f(Me,"headerHeight");const ft=10,$t=22,ht=6,pt=5,gt=16,W=" ",M="\x1B[",$=`${M}0m`,U=`${M}7m`,y=`${M}2m`,C=`${M}1m`,Kt=`${M}48;5;236m`,mt="33",zt="31",H="36",N="90",xt="93",I="96",bt="35";function Z(t){return t<=0?"0k":`${Math.floor(t/1e3)}k`}f(Z,"fmtCtx");function yt(t){if(t>=1e5)return zt;if(t>=5e4)return mt}f(yt,"ctxColorCode");function G(t,n){const e=Date.parse(t);if(Number.isNaN(e))return"";const s=Math.max(0,Math.floor((n-e)/1e3));if(s<60)return`${s}s`;const r=Math.floor(s/60);if(r<60)return`${r}m`;const o=Math.floor(r/60);if(o<24)return`${o}h`;const u=Math.floor(o/24);if(u<7)return`${u}d`;const i=Math.floor(u/7);return i<5?`${i}w`:`${Math.floor(u/30)}mo`}f(G,"relAge");function j(t){const n=t.replace(/\/+$/,"").split("/");return n[n.length-1]||t}f(j,"baseDir");const vt=new WeakMap;function Jt(t){const n=vt.get(t);if(n!==void 0)return n;const e={active:0,idle:0,done:0,dead:0,canceled:0};for(const r of t.nodes.values())e[r.row.status]++;const s=[];for(const r of["active","idle","done","dead","canceled"])e[r]>0&&s.push({status:r,count:e[r]});return vt.set(t,s),s}f(Jt,"statusCounts");function Xt(t,n){return Pt.map(e=>e===t?n?`${C}${M}${H}m[ ${e} ]${$}`:`${U}[ ${e} ]${$}`:n?`${y} ${e} ${$}`:` ${e} `).join("")}f(Xt,"tabBar");const qt=new Set;function Qt(t,n,e){const s=n===""?qt:Gt(n,t);if(s.size===0)return[{text:t,style:{dim:e.dim,bold:e.bold}}];const r=[];let o="",u=!1;const i=f(()=>{o!==""&&(u?r.push({text:o,style:{fg:I,bold:!0}}):r.push({text:o,style:{dim:e.dim,bold:e.bold}}),o="")},"flush");for(let l=0;l<t.length;l++){const c=s.has(l);c!==u&&(i(),u=c),o+=t[l]}return i(),r}f(Qt,"nameSpans");function L(t){let n=0;for(const e of t)n+=[...e.text].length;return n}f(L,"spansWidth");function Zt(t){const n=X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}),e=n.word??{active:"active",idle:"idle",done:"done",dead:"dead",canceled:"cancel"}[t.status]??t.status,s=n.color,r=`${n.glyph} ${e}`,o=Math.max(1,ft-[...r].length);return[{text:r,style:{fg:s,bold:n.bold===!0}},{text:" ".repeat(o)}]}f(Zt,"statusRail");function te(t,n,e){const s=yt(t.ctx_tokens),r=[{text:Et(`${t.kind}/${t.mode}`,$t),style:{fg:N}},{text:W},{text:Z(t.ctx_tokens).padStart(ht),style:{fg:s,dim:s===void 0}},{text:W},{text:G(t.created,n).padStart(pt),style:{dim:!0}}];return e&&r.push({text:W},{text:Et(`~${j(t.cwd)}`,gt),style:{fg:N}}),r}f(te,"metaCluster");function Et(t,n){return _(t,n).padEnd(n)}f(Et,"clipPad");function tt(t,n,e,s,r,o){const u=L(t),i=L(n);if(n.length===0||u+i+1>e)return w(t,e,s,r,o);const l=e-u-i;return w([...t,{text:" ".repeat(l)},...n],e,s,r,o)}f(tt,"assembleRow");function ee(t,n,e,s,r,o,u,i,l,c=!0,h=!1){const a=n.nodes.get(t.id);if(a===void 0)return"";const d=a.row,b=" ".repeat(t.depth),m=t.hasChildren?t.collapsed?"\u25B8":"\u25BE":" ",E=d.status==="done"||d.status==="dead"||d.status==="canceled",v=d.viewed===!0?{text:"\uF06E ",style:{fg:I,bold:!0}}:{text:" "},p=[];d.asks>0&&p.push({text:` \u2691${d.asks}`,style:{fg:xt,bold:!0}}),d.hanging!=null&&p.push({text:` \xB7 ${lt(d.hanging,i)}`,style:{fg:mt,dim:!0}});const x=l?[{text:"\u2605 ",style:{fg:bt,bold:!0}}]:[],T=Zt(d),R=c?te(d,i,u):[],A=`${b}${m} `,D=L([v])+L(T)+[...A].length+L(x)+L(p),B=L(R),K=Math.max(4,e-D-B-1),z={dim:!s&&E,bold:s},O=[v,...T,{text:A,style:{dim:!0}},...x,...Qt(_(d.name,K),r,z),...p];let k="",P=h;return s?(k=o.color256?Kt:U,P=!0):t.matched||(k=y),tt(O,R,e,o.color,k,P)}f(ee,"rowLine");function ne(t,n,e,s=!0,r=!1){const o=[{text:" "},{text:"STATUS".padEnd(ft),style:{dim:!0,bold:!0}},{text:"NAME",style:{dim:!0,bold:!0}}];if(!s)return w(o,t,e.color,"",r);const u=[{text:"KIND/MODE".padEnd($t),style:{dim:!0,bold:!0}},{text:W},{text:"CTX".padStart(ht),style:{dim:!0,bold:!0}},{text:W},{text:"AGE".padStart(pt),style:{dim:!0,bold:!0}}];return n&&u.push({text:W},{text:"PROJECT".padEnd(gt),style:{dim:!0,bold:!0}}),tt(o,u,t,e.color,"",!1)}f(ne,"columnHeaderLine");function oe(t){const n=f(o=>`${y}${o}${$}`,"dim"),e=t.profileScope===void 0?"all profiles":"current",s=t.cwdScope===null?"all dirs":j(t.cwdScope),r=[`${n("profile")} ${e}`,`${n("scope")} ${s}`,`${n("sort")} ${t.sort}`,`${n("lifecycle")} ${t.residentsOnly?"residents":"all"}`];return!t.search&&t.query!==""&&r.push(`${n("filter")} ${t.query}`),r.join(n(" \xB7 "))}f(oe,"statusLine");function Mt(t,n,e,s){if(t.hi.size===0)return w([{text:t.text,style:s}],n,e.color,"",!1);const r=[];let o="",u=!1;const i=f(()=>{o!==""&&(r.push(u?{text:o,style:{fg:I,bold:!0}}:{text:o,style:s}),o="")},"flush");for(let l=0;l<t.text.length;l++){const c=t.hi.has(l);c!==u&&(i(),u=c),o+=t.text[l]}return i(),w(r,n,e.color,"",!1)}f(Mt,"snippetLine");function se(t,n){const e=t?Bt:0,s=n?Ft:0,r=Math.max(2,ct-e-s),o=Math.ceil(r/2);return{recap:e,ask:o,reply:r-o,report:s}}f(se,"previewAllocation");function _t(t,n,e,s,r,o,u){if(s<=0)return[];const i=[],l=o.color?`${y}${t}${$}`:t,c=Math.max(1,r-2);if(u===""){const a=Q(n,c,s,!1);if(a.length===0)i.push(`${l}${y}${_(e,c)}${$}`);else for(const d of a)i.push(`${i.length===0?l:" "}${w(d,c,o.color,"",!1)}`);for(;i.length<s;)i.push("");return i}const h=q(u,n,c,s);if(h.length===0)i.push(`${l}${y}${_(e,c)}${$}`);else for(const a of h)i.push(`${i.length===0?l:" "}${Mt(a,c,o)}`);for(;i.length<s;)i.push("");return i}f(_t,"markedBlock");function Tt(t,n,e,s){const r=`${t.padEnd(6)}`,o=_(n,Math.max(1,e-r.length));return s.color?`${y}${r}${$}${C}${o}${$}`:`${r}${o}`}f(Tt,"recapLine");function re(t,n,e,s,r){const o=[`${y}${"\u2500".repeat(n)}${$}`];if(t===void 0){for(;o.length<it;)o.push("");return o}const u=X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}),i=e.color?`${M}${u.color}m${u.glyph}${$}`:u.glyph,l=[`${t.status} ${t.kind}/${t.mode}`,j(t.cwd),G(t.created,s),`ctx ${Z(t.ctx_tokens)}`];t.asks>0&&l.push(`\u2691${t.asks}`),t.hanging!=null&&l.push(lt(t.hanging,s)),t.streaming===!0&&l.push("\u27F3"),t.viewed===!0&&l.push("\uF06E viewing");const c=_(l.filter(d=>d!=="").join(" \xB7 "),Math.max(0,n-2));o.push(e.color?`${i} ${y}${c}${$}`:`${i} ${c}`);const h=se(t.recap!==void 0,t.report!==void 0);t.recap!==void 0&&(o.push(Tt("Goal",t.recap.goal===""?"\u2014":t.recap.goal,n,e)),o.push(Tt("State",t.recap.state===""?"\u2014":t.recap.state,n,e)));const a=r!==""?Ht(t):t.goal??"";if(o.push(..._t("\u276F ",a,"(no spawn prompt)",h.ask,n,e,r)),o.push(..._t("\u21A9 ",t.lastAssistant??"","(no reply yet)",h.reply,n,e,"")),t.report!==void 0){const d=G(t.report.ts,s),b=`${d===""?"":`${d} `}${t.report.kind}`,m=t.report.heading===""?t.report.body:t.report.heading,E=e.color?`${y}\u25A3 ${$}`:"\u25A3 ",v=Math.max(1,n-2),p=e.color?`${M}${H}m${b}${$}${y} \xB7 ${$}`:`${b} \xB7 `;o.push(`${E}${p}${_(m,Math.max(1,v-b.length-3))}`);for(let x=1;x<h.report;x++){const T=t.report.heading===""?"":t.report.body,R=q("",T,v,h.report-1)[x-1];o.push(R===void 0?"":` ${y}${_(R.text,v)}${$}`)}}return o}f(re,"previewPanel");function Y(t,n,e,s){const r=s===void 0?"":`${s.text} `,o=Math.max(0,n-4-t.length-r.length),u=s===void 0?"":e.color?`${M}${s.fg}m${s.text}${$}${y} `:`${s.text} `;return`${y}\u2500\u2500 ${C}${t}${$}${y} ${u}${"\u2500".repeat(o)}${$}`}f(Y,"sectionRule");function et(t,n,e,s,r,o,u,i,l,c){if(o<=0)return[];const h=[...t].length,a=Math.max(1,u-h),d=f((m,E)=>w([{text:m,style:E}],h,i.color,"",!0),"mk");if(l===""){const m=Q(s,a,o,!0,c);return m.length===0?r===void 0?[]:[`${d(t,e)}${y}${_(r,a)}${$}`]:m.map((E,v)=>`${d(v===0?t:n,e)}${w(E,a,i.color,"",!1)}`)}const b=q(l,s,a,o);return b.length===0?r===void 0?[]:[`${d(t,e)}${y}${_(r,a)}${$}`]:b.map((m,E)=>`${d(E===0?t:n,e)}${Mt(m,a,i,c)}`)}f(et,"blockLines");const le=400,ce=1,nt=14,wt={fg:I,bold:!0,reverse:!0};function ie(t){let n="";for(const e of t)n+=e.text;return n}f(ie,"spansText");function ue(t,n){if(n==="")return{spans:t,hits:0};const e=ie(t),s=e.toLowerCase(),r=n.toLowerCase();if(s.indexOf(r)<0)return{spans:t,hits:0};const o=new Uint8Array(e.length);let u=0;for(let c=s.indexOf(r);c>=0;c=s.indexOf(r,c+r.length)){u++;for(let h=c;h<c+r.length;h++)o[h]=1}const i=[];let l=0;for(const c of t){let h="",a=o[l]===1;for(let d=0;d<c.text.length;d++){const b=o[l]===1;b!==a&&(h!==""&&i.push({text:h,style:a?wt:c.style}),h="",a=b),h+=c.text[d],l++}h!==""&&i.push({text:h,style:a?wt:c.style})}return{spans:i,hits:u}}f(ue,"highlightSpans");const V="\u258C ";function ot(t,n,e,s,r){if(e<2)return{lines:[],hits:0,truncated:!0};const o=t.role==="user",u=o?{fg:I,bold:!0}:{fg:N},i=Math.max(1,s-V.length),l=f(()=>w([{text:V,style:u}],V.length,r.color,"",!0),"bar"),c=[w([{text:V,style:u},{text:o?"YOU":"AGENT",style:{...u,bold:!0}}],s,r.color,"",!1)],a=Q(t.text,i,le,!1,o?{}:{dim:!0}).map(x=>ue(x,n)),d=a.reduce((x,T)=>x+T.hits,0),b=e-1;let m=0;a.length>b&&d>0&&(m=Math.max(0,a.findIndex(x=>x.hits>0)-ce),m=Math.min(m,a.length-b));const E=a.slice(m,m+b);for(const x of E)c.push(`${l()}${w(x.spans,i,r.color,"",!1)}`);const v=m>0,p=m+E.length<a.length;return v&&E.length>1&&(c[1]=`${l()}${y}\u22EF${$}`),p&&E.length>(v?2:1)&&(c[c.length-1]=`${l()}${y}\u22EF${$}`),{lines:c,hits:d,truncated:v||p}}f(ot,"turnBlock");function Rt(t,n,e){return w([{text:` \u22EF ${t} ${t===1?"turn":"turns"}`,style:{dim:!0}}],n,e.color,"",!1)}f(Rt,"elisionLine");function St(t,n){return n!==""&&t.text.toLowerCase().indexOf(n.toLowerCase())>=0}f(St,"turnMatches");function ae(t,n){return t.reduce((e,s)=>e+(St(s,n)?1:0),0)}f(ae,"transcriptHitTurns");function At(t,n,e,s,r){if(s<=0||t.length===0)return[];const o=n===""?[]:t.map((l,c)=>St(l,n)?c:-1).filter(l=>l>=0);if(o.length>0){const l=[];let c=-1;for(const a of o){const d=l.length===0?0:1,b=s-l.length-d;if(b<3)break;const{lines:m}=ot(t[a],n,Math.min(b,nt),e,r);if(m.length===0)break;const E=c<0?a:a-c-1,v=E>0&&l.length+d+m.length+1<=s;d>0&&l.push(""),v&&l.push(Rt(E,e,r)),l.push(...m),c=a}let h=c;for(let a=c+1;a<t.length;a++){const d=s-l.length-1;if(d<3)break;const{lines:b,truncated:m}=ot(t[a],n,Math.min(d,nt),e,r);if(b.length===0||m)break;l.push("",...b),h=a}return h>=0&&h<t.length-1&&l.length<s&&l.push(Rt(t.length-1-h,e,r)),l.slice(0,s)}const u=[];let i=0;for(let l=t.length-1;l>=0;l--){const c=u.length===0,h=c?0:1,a=s-i-h;if(a<3)break;const{lines:d,truncated:b}=ot(t[l],"",Math.min(a,nt),e,r);if(d.length===0||b&&!c)break;h>0&&u.push([""]),u.push(d),i+=d.length+h}return u.reverse().flat().slice(-s)}f(At,"transcriptLines");function kt(t){return t.transcriptLoaded===!0||t.previewLoaded===!0?`${y}(no conversation yet)${$}`:`${y}(loading\u2026)${$}`}f(kt,"emptyBodyNote");function Ct(t){const n=t.transcript;if(n!==void 0&&n.length>0)return n;const e=[];return t.goal!==void 0&&t.goal!==""&&e.push({role:"user",text:t.goal}),t.lastAssistant!==void 0&&t.lastAssistant!==""&&e.push({role:"assistant",text:t.lastAssistant}),e}f(Ct,"panelTurns");const de=4;function fe(t,n,e,s){const r=yt(t.ctx_tokens),o=f(()=>({text:" \xB7 ",style:{dim:!0}}),"dot"),u=[{text:`${t.kind}/${t.mode}`,style:{fg:N}},o(),{text:`~${j(t.cwd)}`,style:{fg:N}},o(),{text:G(t.created,e),style:{dim:!0}},o(),{text:`ctx ${Z(t.ctx_tokens)}`,style:{fg:r,dim:r===void 0}}];return w(u,n,s.color,"",!1)}f(fe,"panelFactsLine");function $e(t,n,e,s){if(t===void 0)return w([{text:"PREVIEW",style:{dim:!0,bold:!0}}],n,e.color,"",!1);const r=[];s&&r.push({text:"\u2605 ",style:{fg:bt,bold:!0}});const o=t.node_id.slice(0,8);return r.push({text:_(t.name,Math.max(4,n-o.length-2-L(r))),style:{bold:!0}}),tt(r,[{text:o,style:{dim:!0}}],n,e.color,"",!1)}f($e,"panelTitleLine");function he(t,n,e,s,r,o,u){if(e<=0)return[];if(t===void 0)return[`${y}(no selection)${$}`];if(o!==""){const p=Ct(t),x=ae(p,o),T=[Y("TRANSCRIPT",n,s,x>0?{text:`${x} ${x===1?"turn":"turns"}`,fg:I}:{text:"matched on name",fg:N})],R=At(p,o,n,e-1,s);return T.push(...R.length===0?[kt(t)]:R),T.slice(0,e)}const i=t.report,l=f(()=>({fg:X(t.status,{streaming:t.streaming===!0,frozen:J(t),hanging:t.hanging??null}).color}),"accentOf");if(u&&i!==void 0){const p=G(i.ts,r),x=[Y("REPORT",n,s,{text:`${p===""?"":`${p} \xB7 `}${i.kind}`,fg:H})],T=i.heading===""?i.body:i.heading;return x.push(...et("\u25A3 "," ",{fg:H,bold:!0},T,void 0,3,n,s,"",{bold:!0})),i.heading!==""&&i.body!==""&&(x.push(""),x.push(...et(" "," ",void 0,i.body,void 0,e-x.length,n,s,""))),x.slice(0,e)}const c=[fe(t,n,r,s),""],h=l(),a=f((p,x)=>[Y(p,n,s),...et("\u258C ","\u258C ",h,x,void 0,de,n,s,"",{bold:!0})],"briefing"),d=t.recap?.goal??"";d!==""&&c.push(...a("GOAL",d),"");const b=t.recap?.state??"",m=b===""?[]:[...a("STATE",b)],E=m.length===0?0:m.length+1,v=e-c.length-E-1;if(v>=2){c.push(Y("CHAT",n,s));const p=At(Ct(t),"",n,v,s);c.push(...p.length===0?[kt(t)]:p)}if(m.length>0){for(;c.length<e-m.length;)c.push("");c.push(...m)}return c.slice(0,e)}f(he,"sidePanelBody");const pe=[["Move","\u2191/\u2193 j/k","up / down"],["","g / G","top / bottom"],["",".","jump to this node (recenter)"],["Tree","\u2192/\u2190 h/l","expand / collapse"],["","space","toggle fold"],["Tabs","Tab / 1-5","All \xB7 Live \xB7 Dormant \xB7 Attention \xB7 Pinned"],["Find","/","fuzzy search (name \xB7 kind \xB7 id \xB7 prompts)"],["Pin","p","star / unstar \u2014 floats to top, Pinned tab"],["Open","\u23CE o","open conversation (closes navigator)"],["","O","open, keep browsing (background)"],["Act","y","copy the node id to the clipboard"],["","m","message the node (no resume)"],["","R","rename the node"],["","x","close-out node + subtree"],["","K","revive now (a hanging node)"],["View","s","cycle sort (attention/tree/relevance/recency)"],["","c","toggle cwd scope"],["","P","toggle profile scope"],["","r","toggle residents-only"],["","v","toggle preview (goal, chat, state)"],["","V","in the preview: swap chat for the newest report"],["Quit","q / Esc",""]];function ge(t,n){const e=Math.max(20,t.cols),s=Math.max(8,t.rows),r=e-1,o=[];o.push(`${C}Canvas navigator \u2014 keys${$}`),o.push("");const u=f(l=>`${y}${l}${$}`,"dim");for(const[l,c,h]of pe){const a=l.padEnd(6),d=c.padEnd(12),b=` ${u(a)}${C}${d}${$}${h===""?"":` ${u(h)}`}`;o.push(_(b,r))}for(o.push(""),o.push(u(" ? or any key to close"));o.length<s-1;)o.push("");const i=o.map(l=>`${l}${M}K`).join(`\r
|
|
2
|
+
`);return`${M}H${i}${M}J`}f(ge,"renderHelp");function _e(t,n,e={color:!1,color256:!1}){if(t.help===!0)return ge(n,e);const s=Math.max(20,n.cols),r=Math.max(8,n.rows),o=s-1,u=Date.now(),i=t.search||t.rename===!0||t.message===!0,l=[],c=`${C}Canvas${$} \u2014 ${t.totalNodes} nodes`,h=`Canvas \u2014 ${t.totalNodes} nodes`.length,a=Jt(t.tree),d=a.map(g=>`${rt[g.status]}${g.count}`).join(" "),b=e.color?a.map(g=>`${M}${It[g.status]}m${rt[g.status]}${$}${y}${g.count}${$}`).join(" "):`${y}${d}${$}`,m=o-h-d.length;if(l.push(m>1?`${c}${" ".repeat(m)}${b}`:c),l.push(Xt(t.tab,e.color)),l.push(oe(t)),i){const g=t.rename===!0?"rename \u25B8":t.message===!0?"msg \u25B8":"/",S=t.rename===!0?t.renameBuf??"":t.message===!0?t.messageBuf??"":t.query,F=e.color?`${M}${H}m${g}${$}`:g;l.push(`${F} ${S}\u258E`)}const E=t.preview&&t.visible.length>0,v=Vt(s,E),p=v.mode==="side",x=p?v.rowsW:o,T=`${y}${dt}${$}`,R=t.visible[t.cursor],A=R!==void 0?t.tree.nodes.get(R.id)?.row:void 0,D=t.cwdScope===null&&!p,B=ne(x,D,e,!p,p);l.push(p?`${B}${T}${$e(A,v.panelW,e,R!==void 0&&t.pinned.has(R.id))}`:B),l.push(p?`${y}${"\u2500".repeat(x)}\u2500\u253C\u2500${"\u2500".repeat(v.panelW)}${$}`:`${y}${"\u2500".repeat(o)}${$}`);const K=l.length,z=v.mode==="bottom"?it:0,O=Math.max(1,r-K-1-z),k=t.scrollOffset,P=Math.min(t.visible.length,k+O),Lt=p?he(A,v.panelW,O,e,u,t.query,t.showReport===!0):[],st=f((g,S)=>p?`${g}${T}${Lt[S]??""}`:g,"compose"),Ot=p?" ".repeat(x):"";if(t.visible.length===0){l.push(`${y} (no nodes match this view)${$}`);for(let g=1;g<O;g++)l.push("")}else{for(let g=k;g<P;g++){const S=t.visible[g];l.push(st(ee(S,t.tree,x,g===t.cursor,t.query,e,D,u,t.pinned.has(S.id),!p,p),g-k))}for(let g=P-k;g<O;g++)l.push(st(Ot,g))}if(v.mode==="bottom")for(const g of re(A,o,e,u,t.query))l.push(g);if(t.pendingClose!==null&&t.pendingClose!==void 0){const g=t.tree.nodes.get(t.pendingClose),F=`\u26A0 ${g!==void 0?g.row.name:t.pendingClose} is \u27F3 \u2014 close it (and its subtree) anyway? y / n`;l.push(e.color?`${C}${M}${xt}m${_(F,o)}${$}`:`${U}${_(F,o)}${$}`)}else if(t.flash!==null&&t.flash!==void 0&&t.flash!=="")l.push(e.color?`${C}${_(t.flash,o)}${$}`:`${U}${_(t.flash,o)}${$}`);else{const g=A?.hanging!=null?"K revive now ":"",S=i?"\u23CE commit Esc cancel \u232B delete":t.readOnly===!0?"\u2191\u2193 move \u2192/\u2190 tree / search p pin v preview Tab tabs ? more q quit \u2014 read-only remote canvas":`${g}${A?.report!==void 0&&p&&t.query===""?t.showReport===!0?"V chat ":"V report ":""}\u2191\u2193 move \u23CE open O bg / search p pin v preview m msg x close ? more q quit`;l.push(`${y}${_(S,o)}${$}`)}const Wt=l.map(g=>`${g}${M}K`).join(`\r
|
|
3
|
+
`);return`${M}H${Wt}${M}J`}f(_e,"renderFrame");export{ct as PREVIEW_BODY,it as PREVIEW_HEIGHT,Bt as RECAP_LINES,Ft as REPORT_LINES,Dt as detectColorCaps,Me as headerHeight,ue as highlightSpans,se as previewAllocation,Vt as previewLayout,_e as renderFrame,ae as transcriptHitTurns};
|