@north-light/crouter 0.3.349 → 0.3.350
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/bin/crtr-launcher +4 -0
- package/bin/runtime-generation-manifest.mjs +12 -2
- package/dist/api/client.d.ts +50 -7
- package/dist/api/client.js +2 -2
- package/dist/api/dto/analytics.d.ts +184 -0
- package/dist/api/dto/analytics.js +0 -0
- package/dist/api/dto/broker-ops.d.ts +43 -1
- package/dist/api/dto/config.d.ts +11 -0
- package/dist/api/dto/grants.d.ts +14 -0
- package/dist/api/dto/grants.js +0 -0
- package/dist/api/dto/human-requests.d.ts +14 -0
- package/dist/api/dto/memory.d.ts +6 -0
- package/dist/api/dto/modelauth.d.ts +35 -0
- package/dist/api/dto/node-records.d.ts +35 -0
- package/dist/api/dto/node-records.js +0 -0
- package/dist/api/dto/nodes.d.ts +5 -0
- package/dist/api/dto/profiles.d.ts +38 -3
- package/dist/api/dto/worktree.d.ts +11 -0
- package/dist/api/errors.d.ts +23 -1
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/node-transport.js +1 -1
- package/dist/api/routes.d.ts +22 -0
- package/dist/api/routes.js +1 -1
- package/dist/build-root.d.ts +6 -1
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/crouter-sdk/client.md +34 -0
- package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
- package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
- package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
- package/dist/cli.js +9 -8
- package/dist/clients/attach/chrome/inbox-strip.js +1 -1
- package/dist/clients/attach/chrome/roster.js +1 -1
- package/dist/clients/attach/config.js +1 -1
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/overlays/graph.js +1 -1
- package/dist/clients/attach/render/tool-calls.js +3 -3
- package/dist/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/viewer.js +1569 -816
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/broker-permissions.d.ts +2 -0
- package/dist/commands/broker-permissions.js +1 -0
- package/dist/commands/canvas-analytics/chart.d.ts +52 -0
- package/dist/commands/canvas-analytics/chart.js +1 -0
- package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
- package/dist/commands/canvas-analytics/drilldown.js +1 -0
- package/dist/commands/canvas-analytics/format.d.ts +29 -0
- package/dist/commands/canvas-analytics/format.js +1 -0
- package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
- package/dist/commands/canvas-analytics/graph-detail.js +2 -0
- package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
- package/dist/commands/canvas-analytics/graphs.js +1 -0
- package/dist/commands/canvas-analytics/memory.d.ts +2 -0
- package/dist/commands/canvas-analytics/memory.js +1 -0
- package/dist/commands/canvas-analytics/overview.d.ts +2 -0
- package/dist/commands/canvas-analytics/overview.js +1 -0
- package/dist/commands/canvas-analytics/shell.d.ts +60 -0
- package/dist/commands/canvas-analytics/shell.js +2 -0
- package/dist/commands/canvas-analytics/time.d.ts +2 -0
- package/dist/commands/canvas-analytics/time.js +1 -0
- package/dist/commands/canvas-analytics/usage.d.ts +2 -0
- package/dist/commands/canvas-analytics/usage.js +1 -0
- package/dist/commands/canvas-analytics/view.d.ts +85 -0
- package/dist/commands/canvas-analytics/view.js +1 -0
- package/dist/commands/canvas-analytics.d.ts +2 -0
- package/dist/commands/canvas-analytics.js +1 -0
- package/dist/commands/canvas-prune.js +1 -1
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -5
- package/dist/commands/human/components.d.ts +2 -0
- package/dist/commands/human/components.js +2 -2
- package/dist/commands/human/prompts.js +1 -1
- package/dist/commands/human/queue.js +1 -1
- package/dist/commands/memory/client.d.ts +11 -0
- package/dist/commands/memory/client.js +1 -0
- package/dist/commands/memory/delete.js +1 -1
- package/dist/commands/memory/edit.js +3 -3
- package/dist/commands/memory/find.js +1 -1
- package/dist/commands/memory/history.js +4 -4
- package/dist/commands/memory/lint.js +1 -1
- package/dist/commands/memory/list.d.ts +0 -2
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/move.js +1 -1
- package/dist/commands/memory/origin.js +1 -1
- package/dist/commands/memory/read.d.ts +0 -5
- package/dist/commands/memory/read.js +3 -3
- package/dist/commands/memory/shared.d.ts +0 -178
- package/dist/commands/memory/shared.js +1 -12
- package/dist/commands/memory/write.js +5 -5
- package/dist/commands/node/bash.js +5 -5
- package/dist/commands/node/create.d.ts +0 -17
- package/dist/commands/node/create.js +2 -3
- package/dist/commands/node/inspect.js +6 -6
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/node-context.js +2 -2
- package/dist/commands/node-inspect-artifacts.js +6 -6
- package/dist/commands/pkg/browse/catalog.js +1 -1
- package/dist/commands/pkg/browse/model.d.ts +1 -1
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +10 -10
- package/dist/commands/profile/daemon-profiles.d.ts +13 -0
- package/dist/commands/profile/daemon-profiles.js +4 -0
- package/dist/commands/profile/delete.js +1 -1
- package/dist/commands/profile/env.d.ts +6 -0
- package/dist/commands/profile/env.js +2 -2
- package/dist/commands/profile/kind.js +1 -2
- package/dist/commands/profile/list.js +1 -1
- package/dist/commands/profile/meta.js +1 -1
- package/dist/commands/profile/new.js +1 -1
- package/dist/commands/profile/pause.js +1 -1
- package/dist/commands/profile/project.js +1 -1
- package/dist/commands/profile/rename.js +1 -1
- package/dist/commands/profile/show.js +1 -1
- package/dist/commands/profile.js +1 -1
- package/dist/commands/push.js +3 -3
- package/dist/commands/surface-inspect.js +1 -1
- package/dist/commands/sys/branch.js +1 -1
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +3 -3
- package/dist/commands/sys/context/admin/actions.js +1 -1
- package/dist/commands/sys/context/admin/model.d.ts +1 -0
- package/dist/commands/sys/context/admin/model.js +1 -1
- package/dist/commands/sys/context/admin.js +1 -1
- package/dist/commands/sys/context/expose.js +2 -1
- package/dist/commands/sys/context/prompt-review.js +2 -2
- package/dist/commands/sys/context/resolve.js +7 -7
- package/dist/commands/sys/context/sysprompt.js +1 -1
- package/dist/commands/sys/join.d.ts +1 -0
- package/dist/commands/sys/join.js +1 -0
- package/dist/commands/sys/migrate.js +1 -1
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +6 -6
- package/dist/commands/sys/setup-core.d.ts +1 -1
- package/dist/commands/sys/setup-core.js +6 -6
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/setup.js +1 -1
- package/dist/commands/sys/spaces.d.ts +1 -0
- package/dist/commands/sys/spaces.js +2 -0
- package/dist/commands/sys/sync-deps.js +2 -2
- package/dist/commands/sys/sync-project-guidance.js +4 -4
- package/dist/commands/sys/sync-skills.js +2 -2
- package/dist/commands/sys/worktrees.d.ts +1 -0
- package/dist/commands/sys/worktrees.js +1 -1
- package/dist/commands/sys.js +1 -1
- package/dist/core/auth-file.js +2 -2
- package/dist/core/bash-job-supervisor.d.ts +6 -0
- package/dist/core/bash-job-supervisor.js +4 -0
- package/dist/core/bash-jobs.d.ts +13 -6
- package/dist/core/bash-jobs.js +8 -7
- package/dist/core/broker-client/transport-relay.d.ts +6 -3
- package/dist/core/broker-client/transport-relay.js +1 -1
- package/dist/core/broker-client/transport-socket.d.ts +6 -1
- package/dist/core/broker-client/transport-socket.js +1 -1
- package/dist/core/canvas/canvas.d.ts +39 -18
- package/dist/core/canvas/canvas.js +21 -20
- package/dist/core/canvas/context-strip.d.ts +20 -0
- package/dist/core/canvas/context-strip.js +5 -0
- package/dist/core/canvas/crons.d.ts +12 -20
- package/dist/core/canvas/crons.js +15 -13
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/deliveries.d.ts +4 -1
- package/dist/core/canvas/deliveries.js +1 -1
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/history.d.ts +2 -1
- package/dist/core/canvas/history.js +17 -18
- package/dist/core/canvas/memory-reads.d.ts +19 -0
- package/dist/core/canvas/memory-reads.js +1 -0
- package/dist/core/canvas/migrations.d.ts +0 -4
- package/dist/core/canvas/migrations.js +99 -32
- package/dist/core/canvas/nav-render.js +1 -1
- package/dist/core/canvas/node-agent-paths.d.ts +8 -0
- package/dist/core/canvas/node-agent-paths.js +1 -0
- package/dist/core/canvas/node-recap.d.ts +2 -2
- package/dist/core/canvas/node-recap.js +2 -2
- package/dist/core/canvas/node-tokens.d.ts +24 -0
- package/dist/core/canvas/node-tokens.js +5 -0
- package/dist/core/canvas/paths.d.ts +16 -19
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/render-source.d.ts +2 -2
- package/dist/core/canvas/render-source.js +6 -9
- package/dist/core/canvas/sessions.d.ts +18 -0
- package/dist/core/canvas/sessions.js +4 -1
- package/dist/core/canvas/types.d.ts +22 -6
- package/dist/core/command-hooks/compose.js +1 -1
- package/dist/core/command-hooks/discovery.d.ts +15 -1
- package/dist/core/command-hooks/discovery.js +1 -1
- package/dist/core/command-hooks/help.d.ts +2 -2
- package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
- package/dist/core/command-hooks/lifecycle-create.js +1 -1
- package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
- package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-hooks/transport/plan.d.ts +3 -0
- package/dist/core/command-hooks/transport/plan.js +1 -0
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command.d.ts +6 -2
- package/dist/core/command.js +6 -6
- package/dist/core/config.d.ts +8 -5
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.d.ts +1 -0
- package/dist/core/conversation-store/client-worker.js +1 -0
- package/dist/core/conversation-store/client.d.ts +2 -0
- package/dist/core/conversation-store/client.js +2 -0
- package/dist/core/conversation-store/file-store.d.ts +37 -0
- package/dist/core/conversation-store/file-store.js +9 -0
- package/dist/core/conversation-store/index.d.ts +50 -0
- package/dist/core/conversation-store/index.js +1 -0
- package/dist/core/conversation-store/listener.d.ts +4 -0
- package/dist/core/conversation-store/listener.js +3 -0
- package/dist/core/conversation-store/patch.d.ts +1 -0
- package/dist/core/conversation-store/patch.js +1 -0
- package/dist/core/directory/join.d.ts +27 -0
- package/dist/core/directory/join.js +1 -0
- package/dist/core/disk-usage.d.ts +4 -0
- package/dist/core/disk-usage.js +1 -0
- package/dist/core/events/emit.d.ts +2 -0
- package/dist/core/events/emit.js +3 -1
- package/dist/core/feed/feed.js +4 -4
- package/dist/core/feed/messages.d.ts +3 -0
- package/dist/core/feed/messages.js +6 -6
- package/dist/core/fs-utils.d.ts +2 -0
- package/dist/core/fs-utils.js +3 -3
- package/dist/core/grants/local.d.ts +4 -0
- package/dist/core/grants/local.js +1 -0
- package/dist/core/grants/mirror.d.ts +44 -0
- package/dist/core/grants/mirror.js +4 -0
- package/dist/core/grants/on-sync.d.ts +22 -0
- package/dist/core/grants/on-sync.js +1 -0
- package/dist/core/grants/remove.d.ts +7 -0
- package/dist/core/grants/remove.js +1 -0
- package/dist/core/grants/sandboxes.d.ts +7 -0
- package/dist/core/grants/sandboxes.js +1 -0
- package/dist/core/grants/sync.d.ts +12 -0
- package/dist/core/grants/sync.js +1 -0
- package/dist/core/help/memory-extensions.d.ts +3 -0
- package/dist/core/help/memory-extensions.js +2 -0
- package/dist/core/help.d.ts +14 -0
- package/dist/core/help.js +7 -7
- package/dist/core/host-exports/builtins.js +3 -3
- package/dist/core/host-exports/export.js +3 -3
- package/dist/core/human/action-binding.d.ts +2 -0
- package/dist/core/human/action-binding.js +1 -1
- package/dist/core/human/feedback-companion.d.ts +0 -1
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/page-schema.d.ts +1 -1
- package/dist/core/inspector/core.d.ts +2 -0
- package/dist/core/inspector/core.js +1 -1
- package/dist/core/inspector/tui.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/io.js +6 -6
- package/dist/core/keybindings/catalog.d.ts +1 -1
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/layout-migrate/index.d.ts +15 -0
- package/dist/core/layout-migrate/index.js +4 -0
- package/dist/core/layout-migrate/paths.d.ts +26 -0
- package/dist/core/layout-migrate/paths.js +1 -0
- package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
- package/dist/core/layout-migrate/stored-paths.js +11 -0
- package/dist/core/layout-migrate/stores.d.ts +17 -0
- package/dist/core/layout-migrate/stores.js +4 -0
- package/dist/core/layout.d.ts +26 -0
- package/dist/core/layout.js +2 -0
- package/dist/core/llm/run.d.ts +60 -0
- package/dist/core/llm/run.js +4 -0
- package/dist/core/memory/cli-selector.d.ts +13 -0
- package/dist/core/memory/cli-selector.js +1 -0
- package/dist/core/memory/history.d.ts +5 -4
- package/dist/core/memory/history.js +6 -6
- package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
- package/dist/core/memory/inline-ref-inventory.js +1 -1
- package/dist/core/memory/lint.js +2 -2
- package/dist/core/memory/mutation-domain.d.ts +2 -2
- package/dist/core/memory/mutation-domain.js +8 -7
- package/dist/core/memory/mutations.js +1 -1
- package/dist/core/memory/service.d.ts +5 -0
- package/dist/core/memory/service.js +2 -2
- package/dist/core/memory-resolver.d.ts +11 -7
- package/dist/core/memory-resolver.js +2 -2
- package/dist/core/model-auth/daemon-login.d.ts +13 -0
- package/dist/core/model-auth/daemon-login.js +1 -0
- package/dist/core/model-auth/flows.d.ts +45 -0
- package/dist/core/model-auth/flows.js +1 -0
- package/dist/core/model-auth/handoff-jti.d.ts +4 -0
- package/dist/core/model-auth/handoff-jti.js +1 -0
- package/dist/core/model-routes.js +1 -1
- package/dist/core/nested-stores.d.ts +2 -1
- package/dist/core/nested-stores.js +1 -2
- package/dist/core/preview-registry.js +2 -2
- package/dist/core/profiles/env-store.js +2 -2
- package/dist/core/profiles/manifest.d.ts +16 -5
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/provider-management.js +1 -1
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/companion.d.ts +0 -2
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/fork.js +2 -2
- package/dist/core/review/realize.js +1 -1
- package/dist/core/review/stage.d.ts +1 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runs/events.d.ts +34 -0
- package/dist/core/runs/events.js +1 -0
- package/dist/core/runs/operations.d.ts +43 -0
- package/dist/core/runs/operations.js +12 -0
- package/dist/core/runtime/bearings-render.d.ts +2 -2
- package/dist/core/runtime/bearings-render.js +11 -11
- package/dist/core/runtime/bearings.js +2 -2
- package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
- package/dist/core/runtime/broker/cli-relay.js +1 -0
- package/dist/core/runtime/broker/client-registry.d.ts +0 -5
- package/dist/core/runtime/broker/client-registry.js +1 -1
- package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
- package/dist/core/runtime/broker/engine-drive.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
- package/dist/core/runtime/broker/frame-dispatch.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
- package/dist/core/runtime/broker/frame-read.js +1 -1
- package/dist/core/runtime/broker/frame-session.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/inbox.d.ts +1 -2
- package/dist/core/runtime/broker/inbox.js +7 -10
- package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
- package/dist/core/runtime/broker/model-adapter.js +2 -0
- package/dist/core/runtime/broker/node-token.d.ts +3 -0
- package/dist/core/runtime/broker/node-token.js +1 -0
- package/dist/core/runtime/broker/read-ops.js +1 -1
- package/dist/core/runtime/broker/rebind.d.ts +2 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
- package/dist/core/runtime/broker/turn-ignition.js +1 -1
- package/dist/core/runtime/broker-cli.js +3 -3
- package/dist/core/runtime/broker-extension-render.d.ts +2 -5
- package/dist/core/runtime/broker-extension-render.js +4 -4
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker-protocol.d.ts +7 -8
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/canvas-extensions.d.ts +1 -0
- package/dist/core/runtime/canvas-extensions.js +1 -1
- package/dist/core/runtime/close.d.ts +9 -0
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/fleet.d.ts +1 -1
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +2 -2
- package/dist/core/runtime/headless-pi.d.ts +1 -1
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +1 -1
- package/dist/core/runtime/host.js +3 -1
- package/dist/core/runtime/invocation.d.ts +3 -0
- package/dist/core/runtime/kickoff.d.ts +1 -0
- package/dist/core/runtime/kickoff.js +16 -16
- package/dist/core/runtime/launch-target.d.ts +1 -1
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/launch.d.ts +10 -35
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/memory.d.ts +1 -1
- package/dist/core/runtime/memory.js +1 -1
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/model-swap.d.ts +17 -19
- package/dist/core/runtime/model-swap.js +1 -1
- package/dist/core/runtime/node-read.js +3 -2
- package/dist/core/runtime/nodes.d.ts +7 -0
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/package-health.js +2 -2
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/pi-vendored.js +1 -1
- package/dist/core/runtime/placement-tmux.d.ts +1 -1
- package/dist/core/runtime/placement-tmux.js +1 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +2 -0
- package/dist/core/runtime/recovery-hold.js +1 -0
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +1 -1
- package/dist/core/runtime/revive.js +2 -3
- package/dist/core/runtime/roadmap.js +4 -4
- package/dist/core/runtime/run-command.d.ts +6 -0
- package/dist/core/runtime/run-command.js +1 -1
- package/dist/core/runtime/session-branch.d.ts +2 -8
- package/dist/core/runtime/session-branch.js +1 -1
- package/dist/core/runtime/session-list-cache.d.ts +6 -22
- package/dist/core/runtime/session-list-cache.js +1 -1
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/spawn-env.d.ts +6 -6
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -0
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/stop-signals.d.ts +2 -2
- package/dist/core/runtime/stop-signals.js +1 -1
- package/dist/core/runtime/structured-output.d.ts +10 -4
- package/dist/core/runtime/structured-output.js +4 -4
- package/dist/core/runtime/tmux-bindings.js +3 -3
- package/dist/core/runtime/tmux-driver.d.ts +4 -0
- package/dist/core/runtime/tmux-driver.js +7 -7
- package/dist/core/runtime/view-socket.d.ts +9 -2
- package/dist/core/runtime/view-socket.js +1 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scope.d.ts +3 -2
- package/dist/core/scope.js +1 -1
- package/dist/core/scoped-state/db.js +1 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/profiles.d.ts +2 -1
- package/dist/core/scoped-state/profiles.js +1 -1
- package/dist/core/scoped-state/schema.d.ts +2 -1
- package/dist/core/scoped-state/schema.js +4 -4
- package/dist/core/scopes.d.ts +2 -2
- package/dist/core/scopes.js +1 -1
- package/dist/core/secrets.d.ts +1 -0
- package/dist/core/secrets.js +2 -2
- package/dist/core/spaces/mounts.d.ts +32 -0
- package/dist/core/spaces/mounts.js +1 -0
- package/dist/core/spaces/open-beneath.d.ts +71 -0
- package/dist/core/spaces/open-beneath.js +1 -0
- package/dist/core/spaces/permissions.d.ts +46 -0
- package/dist/core/spaces/permissions.js +1 -0
- package/dist/core/spaces/process.d.ts +27 -0
- package/dist/core/spaces/process.js +1 -0
- package/dist/core/spaces/space.d.ts +8 -0
- package/dist/core/spaces/space.js +2 -0
- package/dist/core/spaces/stop.d.ts +8 -0
- package/dist/core/spaces/stop.js +2 -0
- package/dist/core/spaces/users.d.ts +19 -0
- package/dist/core/spaces/users.js +1 -0
- package/dist/core/subscription-state.d.ts +2 -0
- package/dist/core/subscription-state.js +3 -3
- package/dist/core/substrate/frontmatter-validation.js +1 -1
- package/dist/core/substrate/injected-store.d.ts +28 -3
- package/dist/core/substrate/injected-store.js +2 -1
- package/dist/core/substrate/listings.js +1 -1
- package/dist/core/substrate/memory-events.d.ts +6 -0
- package/dist/core/substrate/memory-events.js +1 -0
- package/dist/core/substrate/on-read-node.js +1 -1
- package/dist/core/substrate/on-read.d.ts +6 -6
- package/dist/core/substrate/on-read.js +5 -5
- package/dist/core/substrate/plan.js +1 -1
- package/dist/core/substrate/render-node.js +1 -1
- package/dist/core/substrate/render.d.ts +4 -3
- package/dist/core/substrate/render.js +38 -38
- package/dist/core/substrate/schema.d.ts +6 -0
- package/dist/core/substrate/schema.js +1 -1
- package/dist/core/tui/panel.js +1 -1
- package/dist/core/user-settings.d.ts +12 -0
- package/dist/core/user-settings.js +1 -1
- package/dist/core/worktree-mutation-async.js +5 -5
- package/dist/core/worktree-quarantine.js +1 -1
- package/dist/core/worktree-remove.d.ts +15 -0
- package/dist/core/worktree-remove.js +1 -0
- package/dist/core/worktree-sweep.js +6 -6
- package/dist/daemon/analytics/compute.d.ts +37 -0
- package/dist/daemon/analytics/compute.js +1 -0
- package/dist/daemon/analytics/scan-worker.d.ts +1 -0
- package/dist/daemon/analytics/scan-worker.js +2 -0
- package/dist/daemon/analytics/scan.d.ts +37 -0
- package/dist/daemon/analytics/scan.js +1 -0
- package/dist/daemon/api/app-listener.d.ts +11 -0
- package/dist/daemon/api/app-listener.js +21 -0
- package/dist/daemon/api/bridge.js +5 -5
- package/dist/daemon/api/handlers/analytics.d.ts +2 -0
- package/dist/daemon/api/handlers/analytics.js +1 -0
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +2 -2
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.d.ts +1 -1
- package/dist/daemon/api/handlers/canvas.js +6 -6
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/files.d.ts +1 -1
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/health.js +2 -2
- package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
- package/dist/daemon/api/handlers/hook-exec.js +1 -0
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +2 -0
- package/dist/daemon/api/handlers/llm.js +3 -0
- package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
- package/dist/daemon/api/handlers/memory-reads.js +1 -0
- package/dist/daemon/api/handlers/memory.js +5 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.d.ts +2 -0
- package/dist/daemon/api/handlers/node-records.js +3 -0
- package/dist/daemon/api/handlers/nodes.d.ts +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/profiles.d.ts +4 -1
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/reports.js +5 -3
- package/dist/daemon/api/handlers/reviews.d.ts +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
- package/dist/daemon/api/handlers/run-routes.js +1 -0
- package/dist/daemon/api/handlers/runs.d.ts +9 -0
- package/dist/daemon/api/handlers/runs.js +1 -0
- package/dist/daemon/api/handlers/subscriptions.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +10 -4
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.d.ts +18 -0
- package/dist/daemon/api/operations.js +1 -0
- package/dist/daemon/api/principal.d.ts +42 -0
- package/dist/daemon/api/principal.js +1 -0
- package/dist/daemon/api/router.d.ts +27 -3
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +4 -0
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +7 -0
- package/dist/daemon/api/vendor-signin.js +77 -0
- package/dist/daemon/api/viewer-presence.d.ts +3 -0
- package/dist/daemon/api/viewer-presence.js +1 -0
- package/dist/daemon/cron/armed-context.d.ts +4 -0
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.d.ts +5 -5
- package/dist/daemon/cron-run.js +1 -1
- package/dist/daemon/crtrd.js +8 -7
- package/dist/daemon/delivery/run-delivery.d.ts +4 -0
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/fleet.d.ts +1 -1
- package/dist/daemon/fleet.js +6 -6
- package/dist/daemon/human/finish.js +7 -7
- package/dist/daemon/joined-owner.d.ts +5 -0
- package/dist/daemon/joined-owner.js +1 -0
- package/dist/daemon/manage.js +2 -2
- package/dist/daemon/messaging/node-message.js +1 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.js +1 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/delivery-lane.js +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +6 -0
- package/dist/daemon/runs/append-section.js +2 -0
- package/dist/daemon/runs/observer.d.ts +5 -0
- package/dist/daemon/runs/observer.js +4 -0
- package/dist/launcher/bwrap.d.ts +4 -0
- package/dist/launcher/bwrap.js +2 -0
- package/dist/launcher/client.d.ts +2 -0
- package/dist/launcher/client.js +3 -0
- package/dist/launcher/main.d.ts +1 -0
- package/dist/launcher/main.js +3 -0
- package/dist/launcher/netrule.d.ts +1 -0
- package/dist/launcher/netrule.js +1 -0
- package/dist/launcher/seccomp.d.ts +1 -0
- package/dist/launcher/seccomp.js +1 -0
- package/dist/launcher/spec.d.ts +88 -0
- package/dist/launcher/spec.js +1 -0
- package/dist/launcher/users.d.ts +18 -0
- package/dist/launcher/users.js +7 -0
- package/dist/launcher/validate.d.ts +22 -0
- package/dist/launcher/validate.js +1 -0
- package/dist/migrations/corpus.js +3 -3
- package/dist/migrations/runner.js +1 -1
- package/dist/native/linux/addon.node +0 -0
- package/dist/native/linux.d.ts +29 -0
- package/dist/native/linux.js +1 -0
- package/dist/pi-extensions/broker-local.js +2 -2
- package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
- package/dist/pi-extensions/canvas-bash-valve.js +4 -7
- package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
- package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
- package/dist/pi-extensions/canvas-passive-context.js +11 -11
- package/dist/pi-extensions/canvas-recap.js +6 -6
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.js +4 -4
- package/dist/pi-extensions/canvas-tool-guide.js +1 -1
- package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
- package/dist/pi-extensions/system-prompt-entry.js +1 -0
- package/dist/shared/env.d.ts +5 -1
- package/dist/shared/env.js +1 -1
- package/dist/shared/strip-cd-prefix.d.ts +1 -0
- package/dist/shared/strip-cd-prefix.js +1 -0
- package/dist/types.d.ts +31 -15
- package/docs/cli/memory-and-preferences.md +3 -1
- package/docs/sdk/client.md +34 -0
- package/docs/sdk/errors.md +2 -0
- package/docs/sdk/memory.md +2 -2
- package/docs/sdk/streaming.md +21 -0
- package/package.json +18 -4
- package/packages/crouter-identity/dist/index.d.ts +54 -0
- package/packages/crouter-identity/dist/index.js +166 -0
- package/packages/crouter-identity/package.json +33 -0
- package/runtime.lock.json +34 -8
- package/scripts/build-native-linux.mjs +16 -0
- package/scripts/install-runtime.mjs +9 -7
- package/scripts/lib/isolation-env.mjs +42 -0
- package/scripts/runtime-smoke.mjs +49 -0
- package/src/native/linux/addon.c +249 -0
- package/dist/core/profiles/state-block.d.ts +0 -4
- package/dist/core/profiles/state-block.js +0 -3
- package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
- package/dist/core/runtime/broker/auth-reload.js +0 -1
- package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
- package/dist/core/substrate/cli-context-delivery.js +0 -1
|
@@ -26,7 +26,8 @@ import {
|
|
|
26
26
|
markSubscriptionAuthenticationFailed,
|
|
27
27
|
markSubscriptionRateLimited,
|
|
28
28
|
markSubscriptionSuccess,
|
|
29
|
-
|
|
29
|
+
retryAfterMsFromHeaders,
|
|
30
|
+
retryAfterMsFromError,
|
|
30
31
|
promoteSubscription,
|
|
31
32
|
readRotationConfig,
|
|
32
33
|
readSubscriptionPool,
|
|
@@ -60,6 +61,11 @@ const TRANSIENT_RETRY_BACKOFFS_MS = [250, 750];
|
|
|
60
61
|
// so cool it down only briefly -- long enough to rotate to another credential / fallback
|
|
61
62
|
// provider, short enough that it comes back quickly if it was the only option.
|
|
62
63
|
const TRANSIENT_ROTATE_COOLDOWN_MS = 60 * 1000;
|
|
64
|
+
// A 401/403 before any content means the provider refused this credential (a lapsed
|
|
65
|
+
// plan, a revoked server-side key). That is not a transient blip, but it is not proof
|
|
66
|
+
// the account is gone either: cool the account for 30 minutes and rotate, rather than
|
|
67
|
+
// the 30-day invalid_grant backoff. Exact requests keep the auth error.
|
|
68
|
+
const AUTH_REJECTED_COOLDOWN_MS = 30 * 60 * 1000;
|
|
63
69
|
// A few short outer retries absorb a normal multi-broker collision; if the metadata file
|
|
64
70
|
// remains busy, the provider call still proceeds. Subscription bookkeeping must never turn a
|
|
65
71
|
// healthy model response into a fatal generation fault.
|
|
@@ -124,15 +130,20 @@ type AttemptResult = {
|
|
|
124
130
|
// `usage`/`quota` substrings stay out of the message match: they are false-positive
|
|
125
131
|
// magnets (e.g. "usage" appears in normal assistant text), while the precise
|
|
126
132
|
// terminal usage-limit signals above still cool the credential down and rotate to the
|
|
127
|
-
// next one.
|
|
133
|
+
// next one. A status 401/403 rotates with AUTH_REJECTED_COOLDOWN_MS unless the request
|
|
134
|
+
// is exact.
|
|
128
135
|
type ProviderErrorClassification = {
|
|
129
136
|
kind: "rate_limit" | "transient" | "fatal";
|
|
130
137
|
status?: number;
|
|
131
138
|
reason: string;
|
|
132
139
|
hadRetryAfterHeader: boolean;
|
|
140
|
+
/** Cooldown this classification imposes regardless of any Retry-After header. */
|
|
141
|
+
cooldownMs?: number;
|
|
133
142
|
};
|
|
134
143
|
|
|
135
|
-
|
|
144
|
+
type ProviderClassificationPolicy = { rotateOnAuth: boolean };
|
|
145
|
+
|
|
146
|
+
function classifyProviderSignal(signal: ProviderErrorSignal, policy: ProviderClassificationPolicy): ProviderErrorClassification {
|
|
136
147
|
const hadRetryAfterHeader = signal.retryAfterMs !== undefined;
|
|
137
148
|
if (signal.kind === 'rate-limit' && signal.matchedOn === 'status') {
|
|
138
149
|
return { kind: 'rate_limit', status: signal.status, reason: 'http 429', hadRetryAfterHeader };
|
|
@@ -144,6 +155,9 @@ function classifyProviderSignal(signal: ProviderErrorSignal): ProviderErrorClass
|
|
|
144
155
|
return { kind: 'transient', status: signal.status, reason: `http ${signal.status}`, hadRetryAfterHeader };
|
|
145
156
|
}
|
|
146
157
|
const textMatches = signal.textMatches ?? (signal.matchedOn === 'text' && signal.match ? [{ kind: signal.kind, match: signal.match }] : []);
|
|
158
|
+
if (policy.rotateOnAuth && signal.kind === 'auth' && signal.matchedOn === 'status' && !textMatches.some(({ kind }) => kind === 'rate-limit')) {
|
|
159
|
+
return { kind: 'rate_limit', status: signal.status, reason: `http ${signal.status}`, hadRetryAfterHeader, cooldownMs: AUTH_REJECTED_COOLDOWN_MS };
|
|
160
|
+
}
|
|
147
161
|
const transientMatch = textMatches.find(({ kind }) => kind === 'connection' || kind === 'socket' || kind === 'service-unavailable' || kind === 'overloaded');
|
|
148
162
|
if (transientMatch) {
|
|
149
163
|
return { kind: 'transient', status: signal.status, reason: transientMatch.match.toLowerCase(), hadRetryAfterHeader };
|
|
@@ -155,7 +169,7 @@ function classifyProviderSignal(signal: ProviderErrorSignal): ProviderErrorClass
|
|
|
155
169
|
return { kind: 'fatal', status: signal.status, reason: 'unclassified', hadRetryAfterHeader };
|
|
156
170
|
}
|
|
157
171
|
|
|
158
|
-
function classifyProviderFailure(failure: NormalizedProviderFailure, retryAfterMs: number | undefined): ProviderErrorClassification {
|
|
172
|
+
function classifyProviderFailure(failure: NormalizedProviderFailure, retryAfterMs: number | undefined, policy: ProviderClassificationPolicy): ProviderErrorClassification {
|
|
159
173
|
const nested = failure.causes ?? [];
|
|
160
174
|
const code = failure.code ?? nested.find((cause) => cause.code !== undefined)?.code;
|
|
161
175
|
const errno = failure.errno ?? nested.find((cause) => cause.errno !== undefined)?.errno;
|
|
@@ -168,16 +182,16 @@ function classifyProviderFailure(failure: NormalizedProviderFailure, retryAfterM
|
|
|
168
182
|
code,
|
|
169
183
|
errno,
|
|
170
184
|
message,
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
function classifyProviderError(error: unknown, observed: { status?: number; retryAfterMs?: number }): ProviderErrorClassification {
|
|
175
|
-
return classifyProviderFailure(normalizeProviderFailure(error, { status: observed.status }), observed.retryAfterMs);
|
|
185
|
+
}), policy);
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
/** Test seam for the policy mapping over the shared recognition signal. */
|
|
179
|
-
export function __classifyProviderErrorForTest(
|
|
180
|
-
|
|
189
|
+
export function __classifyProviderErrorForTest(
|
|
190
|
+
error: unknown,
|
|
191
|
+
observed: { status?: number; retryAfterMs?: number } = {},
|
|
192
|
+
policy: ProviderClassificationPolicy = { rotateOnAuth: false },
|
|
193
|
+
): ProviderErrorClassification {
|
|
194
|
+
return classifyProviderFailure(normalizeProviderFailure(error, { status: observed.status }), observed.retryAfterMs, policy);
|
|
181
195
|
}
|
|
182
196
|
|
|
183
197
|
function providerFailureAssistantMessage(model: Model<any>, failure: NormalizedProviderFailure): AssistantMessage {
|
|
@@ -325,15 +339,6 @@ function toAssistantError(model: Model<any>, errorMessage: string): AssistantMes
|
|
|
325
339
|
};
|
|
326
340
|
}
|
|
327
341
|
|
|
328
|
-
function retryAfterMs(headers: Record<string, string>): number | undefined {
|
|
329
|
-
const retryAfterMsHeader = headers["retry-after-ms"];
|
|
330
|
-
if (retryAfterMsHeader) {
|
|
331
|
-
const millis = Number(retryAfterMsHeader);
|
|
332
|
-
if (Number.isFinite(millis)) return Math.max(0, millis);
|
|
333
|
-
}
|
|
334
|
-
return parseRetryAfterHeader(headers["retry-after"]);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
342
|
type RefreshedCredential = { refresh: string; access: string; expires: number };
|
|
338
343
|
// Codex login carries the ChatGPT `accountId`; Anthropic identity is enriched from its OAuth
|
|
339
344
|
// profile after login. Optional so both providers and the test seam fit.
|
|
@@ -556,6 +561,7 @@ async function streamProviderAttempt(
|
|
|
556
561
|
credential: ResolvedCredential | undefined,
|
|
557
562
|
outer: AssistantMessageEventStream,
|
|
558
563
|
): Promise<AttemptResult> {
|
|
564
|
+
const policy: ProviderClassificationPolicy = { rotateOnAuth: !isExactModel(state) };
|
|
559
565
|
for (let attempt = 1; ; attempt++) {
|
|
560
566
|
const attemptAt = Date.now();
|
|
561
567
|
let observedStatus: number | undefined;
|
|
@@ -594,7 +600,7 @@ async function streamProviderAttempt(
|
|
|
594
600
|
onResponse: async (response: { status: number; headers: Record<string, string> }, responseModel: Model<any>) => {
|
|
595
601
|
observedStatus = response.status;
|
|
596
602
|
if (response.status === 429 || response.status === 503) {
|
|
597
|
-
requestedRetryAfterMs =
|
|
603
|
+
requestedRetryAfterMs = retryAfterMsFromHeaders(response.headers);
|
|
598
604
|
}
|
|
599
605
|
await options?.onResponse?.(response as any, responseModel);
|
|
600
606
|
},
|
|
@@ -639,7 +645,7 @@ async function streamProviderAttempt(
|
|
|
639
645
|
}
|
|
640
646
|
failure = normalizeProviderFailure(event.error, { status: observedStatus });
|
|
641
647
|
failureMessage = failure.message;
|
|
642
|
-
classification = classifyProviderFailure(failure, requestedRetryAfterMs);
|
|
648
|
+
classification = classifyProviderFailure(failure, requestedRetryAfterMs, policy);
|
|
643
649
|
if (classification.kind === "fatal" || sawContent) {
|
|
644
650
|
emit({ ...event, error: providerFailureAssistantMessage(model, failure) });
|
|
645
651
|
flush();
|
|
@@ -663,9 +669,10 @@ async function streamProviderAttempt(
|
|
|
663
669
|
flush();
|
|
664
670
|
return { result: "fatal", attemptAt };
|
|
665
671
|
}
|
|
672
|
+
requestedRetryAfterMs ??= retryAfterMsFromError(error);
|
|
666
673
|
failure = normalizeProviderFailure(error, { status: observedStatus });
|
|
667
674
|
failureMessage = failure.message;
|
|
668
|
-
classification = classifyProviderFailure(failure, requestedRetryAfterMs);
|
|
675
|
+
classification = classifyProviderFailure(failure, requestedRetryAfterMs, policy);
|
|
669
676
|
if (classification.kind === "fatal" || sawContent) {
|
|
670
677
|
emit({
|
|
671
678
|
type: "error",
|
|
@@ -689,7 +696,7 @@ async function streamProviderAttempt(
|
|
|
689
696
|
}
|
|
690
697
|
|
|
691
698
|
if (classification.kind === "rate_limit") {
|
|
692
|
-
return { result: "rate_limited", retryAfterMs: requestedRetryAfterMs, attemptAt, classification };
|
|
699
|
+
return { result: "rate_limited", retryAfterMs: classification.cooldownMs ?? requestedRetryAfterMs, attemptAt, classification, failureMessage };
|
|
693
700
|
}
|
|
694
701
|
|
|
695
702
|
// Transient: retry the SAME credential/provider in place first -- no cooldown for the
|
|
@@ -787,7 +794,11 @@ async function runManagedProvider(
|
|
|
787
794
|
configuredValue(state, 'nodeCwd', 'CRTR_NODE_CWD'),
|
|
788
795
|
configuredValue(state, 'profileId', 'CRTR_PROFILE_ID'),
|
|
789
796
|
) : [];
|
|
790
|
-
|
|
797
|
+
// The node's thinking level holds on its own model; a route to another
|
|
798
|
+
// provider or model takes that cell's thinking.
|
|
799
|
+
const onLiveModel = (candidate: { providerId: string; modelId: string }): boolean =>
|
|
800
|
+
candidate.providerId === model.provider && candidate.modelId === model.id;
|
|
801
|
+
const liveRank = (expanded.find((candidate) => onLiveModel(candidate) && candidate.thinkingLevel === liveThinking) ?? expanded.find(onLiveModel))?.rank ?? 0;
|
|
791
802
|
const routeCandidates: RouteCandidate[] = expanded.slice(liveRank)
|
|
792
803
|
.map((route) => {
|
|
793
804
|
const registry = state.runtimeContext?.modelRegistry;
|
|
@@ -795,9 +806,10 @@ async function runManagedProvider(
|
|
|
795
806
|
if (!registry || !routeModel) return undefined;
|
|
796
807
|
const availability = probeRouteAvailability(route, registry);
|
|
797
808
|
if (!availability.registered || (!isManagedProvider(route.providerId) && !availability.authenticated)) return undefined;
|
|
798
|
-
return { routeId: route.routeId, credentialSource: route.credentialSource, rank: route.rank, providerId: route.providerId, model: routeModel, thinkingLevel: route.thinkingLevel };
|
|
809
|
+
return { routeId: route.routeId, credentialSource: route.credentialSource, rank: route.rank, providerId: route.providerId, model: routeModel, thinkingLevel: onLiveModel(route) ? liveThinking : route.thinkingLevel };
|
|
799
810
|
})
|
|
800
|
-
.filter((candidate): candidate is RouteCandidate => candidate !== undefined)
|
|
811
|
+
.filter((candidate): candidate is RouteCandidate => candidate !== undefined)
|
|
812
|
+
.filter((candidate, index, all) => all.findIndex((other) => other.routeId === candidate.routeId && other.providerId === candidate.providerId && other.model.id === candidate.model.id && other.thinkingLevel === candidate.thinkingLevel) === index);
|
|
801
813
|
const isLiveRoute = (candidate: RouteCandidate): boolean =>
|
|
802
814
|
candidate.providerId === model.provider && candidate.model.id === model.id && candidate.thinkingLevel === liveThinking;
|
|
803
815
|
// A cooling or unauthenticated managed route contributes its diagnostic and may
|
|
@@ -822,6 +834,9 @@ async function runManagedProvider(
|
|
|
822
834
|
const cooldownAttempts = new Map<string, number>();
|
|
823
835
|
let terminalModel = model;
|
|
824
836
|
let lastTransientFailure: AttemptResult | undefined;
|
|
837
|
+
// The last pre-content 401/403 that cooled a route; its text is the only
|
|
838
|
+
// record of why the routes ran out when they end in a cooling error.
|
|
839
|
+
let lastAuthRejection: AttemptResult | undefined;
|
|
825
840
|
// Any HTTP response observed this pass (a status, a Retry-After header, or a
|
|
826
841
|
// rate-limit classification) proves this process can still reach a provider,
|
|
827
842
|
// clearing the poisoned-transport suspicion.
|
|
@@ -858,6 +873,7 @@ async function runManagedProvider(
|
|
|
858
873
|
if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true) sawHttpEvidence = true;
|
|
859
874
|
const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
|
|
860
875
|
if (result.result === 'transient_exhausted') lastTransientFailure = result;
|
|
876
|
+
if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403)) lastAuthRejection = result;
|
|
861
877
|
localCoolingDeadlines.set(routeId, Math.max(localCoolingDeadlines.get(routeId) ?? 0, Date.now() + cooldownMs));
|
|
862
878
|
logRouteQueueAdvance(candidate, candidates[0], result);
|
|
863
879
|
continue;
|
|
@@ -898,6 +914,7 @@ async function runManagedProvider(
|
|
|
898
914
|
if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true) sawHttpEvidence = true;
|
|
899
915
|
const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
|
|
900
916
|
if (result.result === 'transient_exhausted') lastTransientFailure = result;
|
|
917
|
+
if (result.result === 'rate_limited' && (result.classification?.status === 401 || result.classification?.status === 403)) lastAuthRejection = result;
|
|
901
918
|
if (result.result === 'rate_limited' && result.retryAfterMs !== undefined) {
|
|
902
919
|
const persisted = await recordSubscriptionMutation(`recording ${getProviderLabel(providerId)} server cooldown`, () => markSubscriptionRateLimited(providerId, freshCredential.label, cooldownMs, result.attemptAt));
|
|
903
920
|
if (persisted) cooldownAttempts.set(`${routeId}/${freshCredential.label}`, result.attemptAt);
|
|
@@ -931,7 +948,11 @@ async function runManagedProvider(
|
|
|
931
948
|
}
|
|
932
949
|
state.transportOnlyExhaustedPasses = 0;
|
|
933
950
|
if (coolingDeadline !== undefined) {
|
|
934
|
-
|
|
951
|
+
const cooling = `cooling down ~${Math.ceil((coolingDeadline - Date.now()) / 1000)}s`;
|
|
952
|
+
const message = lastAuthRejection === undefined
|
|
953
|
+
? `All provider routes are rate limited (${cooling}; tried ${tried})`
|
|
954
|
+
: `All provider routes are rate limited or rejected (${cooling}; last rejection ${lastAuthRejection.classification!.reason}: ${lastAuthRejection.failureMessage ?? 'no error message'}; tried ${tried})`;
|
|
955
|
+
emitCoolingError(stream, terminalModel, new ManagedProviderCoolingError(message, coolingDeadline));
|
|
935
956
|
return;
|
|
936
957
|
}
|
|
937
958
|
const authFailure = [...authFailures][0];
|
|
@@ -1047,7 +1068,9 @@ async function restoreHigherRankIfAvailable(state: ProviderRotationState, pi: Ex
|
|
|
1047
1068
|
configuredValue(state, 'nodeCwd', 'CRTR_NODE_CWD'),
|
|
1048
1069
|
configuredValue(state, 'profileId', 'CRTR_PROFILE_ID'),
|
|
1049
1070
|
);
|
|
1050
|
-
const
|
|
1071
|
+
const onLiveModel = (candidate: { providerId: string; modelId: string }): boolean =>
|
|
1072
|
+
candidate.providerId === ctx.model?.provider && candidate.modelId === ctx.model?.id;
|
|
1073
|
+
const liveRank = (candidates.find((candidate) => onLiveModel(candidate) && candidate.thinkingLevel === liveThinking) ?? candidates.find(onLiveModel))?.rank;
|
|
1051
1074
|
if (liveRank === undefined) return false;
|
|
1052
1075
|
const preferred = candidates.find((candidate) => candidate.rank < liveRank && resolveProviderCandidates([{
|
|
1053
1076
|
...candidate,
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`,"utf8"),
|
|
4
|
-
`);return}try{if(
|
|
5
|
-
`);return}let r;try{const{reconcileFirstRun:
|
|
6
|
-
`)})}catch(
|
|
7
|
-
`)}finally{if(r!==void 0)try{
|
|
8
|
-
`)}}}
|
|
9
|
-
`),process.
|
|
2
|
+
var h=Object.defineProperty;var s=(r,o)=>h(r,"name",{value:o,configurable:!0});import"./suppress-experimental-warnings.js";import{mkdirSync as w,openSync as v,readFileSync as R,renameSync as S,rmSync as E,statSync as f,writeFileSync as _}from"node:fs";import{dirname as l,join as c}from"node:path";import{enableCompileCache as b}from"node:module";import{fileURLToPath as d}from"node:url";import{isDaemonControlInvocation as u,isLayoutMigrationInvocation as x,personOnlyInvocation as C,resolveDaemonControlRoot as N,resolveLayoutMigrationRoot as A,resolveRoot as I}from"./build-root.js";import{maybeBootRoot as $}from"./core/runtime/front-door.js";import{maybeAutoUpdate as k}from"./core/auto-update.js";import{ensureProjectScope as O}from"./core/bootstrap.js";import{provisionExports as T,pruneLegacyExports as F}from"./core/host-exports/export.js";import{revalidateBundlePlugins as M}from"./core/command-plugins/revalidate.js";import{renderNode as D,runCli as g,walk as L}from"./core/command.js";import{dispatchWithStaleRecovery as P}from"./core/manifest-recovery.js";import{installStdoutErrorPolicy as U}from"./core/stdout-errors.js";import{handle as j}from"./core/io.js";import{CrtrError as m}from"./core/errors.js";import{ExitCode as y}from"./types.js";import{layoutNeedsMigration as B,runtimeRoot as K}from"./core/layout.js";import{ApiError as G}from"./api/index.js";import{mark as i}from"./core/timing.js";import{isSandboxedNode as J,envNodeId as W}from"./shared/env.js";import{nodeRunDir as q}from"./core/canvas/paths.js";import{installBrokerConfigSnapshot as V}from"./core/config.js";v(d(import.meta.url),"r"),U(),i("cli.entry",{cmd:process.argv[2]??"(bare)"});try{b()}catch{}i("cli.compile_cache");const z=c(l(d(import.meta.url)),".."),p=c(K(),"first-run.json");function a(r){return(r instanceof Error?r.message:String(r)).split(/\r?\n/,1)[0]??""}s(a,"errorMessage");function H(r){const o=l(p);w(o,{recursive:!0});const t=`${p}.${process.pid}.${Date.now()}.tmp`;try{_(t,JSON.stringify({packageVersion:r,completedAt:new Date().toISOString()})+`
|
|
3
|
+
`,"utf8"),S(t,p)}finally{E(t,{force:!0})}}s(H,"writeFirstRunMarker");async function Q(){if(process.env.CRTR_NO_AUTO_INIT==="1")return;try{if(f(p,{throwIfNoEntry:!1})!==void 0)return}catch(o){process.stderr.write(`crtr: first-run reconcile marker check failed: ${a(o)}
|
|
4
|
+
`);return}try{if(f(c(z,".git"),{throwIfNoEntry:!1})!==void 0)return}catch(o){process.stderr.write(`crtr: first-run reconcile source check failed: ${a(o)}
|
|
5
|
+
`);return}let r;try{const{reconcileFirstRun:o}=await import("./commands/sys/setup-core.js");r=await o((t,e)=>{process.stderr.write(`crtr: first-run reconcile ${t} failed: ${a(e)}
|
|
6
|
+
`)})}catch(o){process.stderr.write(`crtr: first-run reconcile failed: ${a(o)}
|
|
7
|
+
`)}finally{if(r!==void 0)try{H(r)}catch(o){process.stderr.write(`crtr: first-run reconcile marker failed: ${a(o)}
|
|
8
|
+
`)}}}s(Q,"maybeReconcileFirstRun");async function X(){const r=x(process.argv),o=J();if(o){const e=C(process.argv);if(e!==null)throw new m("permission_error",`crtr ${e} is not available to an app's node`,y.USAGE,{next:"Run this command from the person's terminal."});const n=JSON.parse(R(c(q(W()),"broker-launch.json"),"utf8"));if(!n.configSnapshot)throw new Error("node launch is missing its config snapshot");V(n.configSnapshot)}if(!o&&B()&&!u(process.argv)&&!r)throw new m("layout_migration_required","run crtr sys migrate while the runtime is offline",y.NETWORK,{next:"Run `crtr sys migrate` while the runtime is offline, then restart it."});if(r){const e=await A();if(process.argv.slice(4).some(n=>n==="-h"||n==="--help")){process.stdout.write(D(L(e,["sys","migrate"]).node)+`
|
|
9
|
+
`);return}await g(e,process.argv);return}if(o||(F(process.argv),await Q()),await $(process.argv),i("cli.front_door_passed"),u(process.argv)){await g(await N(),process.argv);return}o||await M(process.argv),i("cli.plugins_revalidated");const t=await I(process.argv[2]);i("cli.root_resolved"),o||(T(t,process.argv),O(process.argv),k(process.argv)),i("cli.dispatch_start"),await P(t,process.argv),i("cli.dispatch_done")}s(X,"main"),X().catch(r=>{(r instanceof Error&&r.name==="AbortError"||r instanceof Error&&/operation was aborted/i.test(r.message))&&(process.stderr.write(`crtr: Interrupted
|
|
10
|
+
`),process.exit(130)),(r instanceof G||r instanceof m)&&(j(r),process.exit(typeof process.exitCode=="number"?process.exitCode:1));const t=r instanceof Error?r.message:String(r);process.stderr.write(`crtr: ${t}
|
|
10
11
|
`),process.exit(1)});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var v=Object.defineProperty;var o=(u,c)=>v(u,"name",{value:c,configurable:!0});import{Container as D,Text as I,decodeKittyPrintable as L,matchesKey as b}from"@earendil-works/pi-tui";import{DynamicBorder as K}from"@earendil-works/pi-coding-agent";import{byNewestFirst as O,inboxRowFromDTO as $}from"../../inbox/dto-adapt.js";import{cliClient as _}from"../../../commands/api-client.js";import{fillBar as F,fillWidth as W,navLabel as q,stripSgr as A,truncate as B,REVERSE as H,YELLOW as P,RESET as j}from"../../../core/canvas/nav-render.js";const x=3;function V(u){return u.kind==="page"?u.emittedAt:u.blockedSince}o(V,"ticketTime");function X(u){const c=Date.now()-Date.parse(u);if(!Number.isFinite(c)||c<0)return"now";const a=Math.floor(c/6e4);if(a<1)return"now";if(a<60)return`${a}m`;const m=Math.floor(a/60);return m<24?`${m}h`:`${Math.floor(m/24)}d`}o(X,"ageLabel");function ee(u,c){const{nodeId:a,remote:m,canvasSource:y,tui:k,pal:M}=u,h=new D;let i=[],g=new Map,r,l=0;const R=o(e=>{const n=e.source.nodeId,s=n!==void 0&&n!==a?` \xB7 ${q(g.get(n)??null,n)}`:"";return B(` ${P}\u2691${j} ${e.title}${M.faint(` \xB7 ${X(V(e))}${s}`)}`)},"rowLine"),p=o(()=>{if(c.syncCursor(),h.clear(),i.length>0&&!c.suppressed()){const e=r===void 0?-1:i.findIndex(s=>s.dir===r);e>=0&&(l=Math.min(Math.max(l,e-x+1),e)),l=Math.max(0,Math.min(l,Math.max(0,i.length-x)));for(const s of i.slice(l,l+x)){const t=R(s);h.addChild(new I(s.dir===r?F(A(t),W(),H):t,1,0))}const n=i.length-Math.min(x,i.length-l);n>0&&h.addChild(new I(M.faint(` +${n} more`),1,0)),h.addChild(new K(M.border))}k.requestRender()},"paint"),S=o(async()=>{const e=new Map((await y.listNodes()).map(t=>[t.node_id,t])),n=new Map,s=o(async t=>{if(n.has(t))return;const f=e.get(t)??null;if(t!==a&&f?.kind==="human")return;n.set(t,f);const d=await y.subscriptionsOf(t).catch(()=>[]);for(const T of d)await s(T.node_id)},"visit");return await s(a),n},"subtreeNodes"),C=o(async()=>{if(m)return;g=await S();const e=_(),[n,s]=await Promise.all([e.listHumanInbox(),e.getInboxHistory()]),t=new Map;for(const f of n.tickets){const d=$(f);t.set(d.dir,d)}for(const f of s.tickets){const d=$(f);d.kind==="page"&&(d.source.nodeId===void 0||!g.has(d.source.nodeId)||d.state!=="pending"||!d.awaitsResponse||d.inbox||t.has(d.dir)||t.set(d.dir,d))}i=[...t.values()].filter(f=>f.source.nodeId!==void 0&&g.has(f.source.nodeId)).sort(O),r!==void 0&&!i.some(f=>f.dir===r)&&(r=void 0),p()},"refresh"),w=o(()=>{r!==void 0&&(r=void 0,p())},"exit"),E=o(()=>{if(!m){if(r!==void 0){w();return}if(i.length===0){c.setNotice("No pending human requests in this subtree");return}c.exitRoster(),r=i[0].dir,l=0,p()}},"toggle"),N=o(()=>{const e=i.find(n=>n.dir===r);e!==void 0&&(w(),c.openTicket(e))},"openSelected");return{component:h,refresh:C,handleKey:o(e=>{if(r===void 0)return!1;const n=i.findIndex(t=>t.dir===r),s=L(e)??(e.length===1?e:void 0);return b(e,"up")||s==="k"?(n>0&&(r=i[n-1].dir,p()),!0):b(e,"down")||s==="j"?(n>=0&&n<i.length-1?(r=i[n+1].dir,p()):w(),!0):b(e,"enter")?(N(),!0):b(e,"escape")?(w(),!0):(w(),!1)},"handleKey"),toggle:E,active:o(()=>r!==void 0,"active"),pendingTickets:o(()=>[...i],"pendingTickets")}}o(ee,"createInboxStrip");export{ee as createInboxStrip};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var M=Object.defineProperty;var i=(b,n)=>M(b,"name",{value:n,configurable:!0});import{execFile as C}from"node:child_process";import{Text as P,decodeKittyPrintable as H,matchesKey as h}from"@earendil-works/pi-tui";import{cliClient as S}from"../../../commands/api-client.js";import{activeBackgroundBashJobs as I}from"../../../core/bash-jobs.js";import{contextDir as T}from"../../../core/canvas/paths.js";import{fillBar as O,fillWidth as D,stripSgr as J,REVERSE as U}from"../../../core/canvas/nav-render.js";import{buildCanvasPanelLines as F}from"./canvas-panels.js";const L=15e3;function ne(b,n){const{editor:_,tui:x,pal:K,nodeId:l,remote:a,role:v,canvasSource:$}=b,w=b.containers.reports;let o=[],r,y=process.env.CRTR_ATTACH_ROSTER;y!==void 0&&delete process.env.CRTR_ATTACH_ROSTER;let u,g;const p=i(()=>{n.syncCursor(),w.clear();for(const e of o){const t=e.key===r;w.addChild(new P(t?O(J(e.line),D(),U):e.line,1,0))}x.requestRender()},"paint"),A=i(async()=>{const e=a?[]:(await S().listCrons()).filter(c=>c.created_by===l),t=a?[]:I(T(l)),d=a?[]:(await S().listReviews({state:"open",origin_node_id:l})).reviews;if(o=(await F(l,n.asks(),K,$,e,t,d)).items,y!==void 0){const c=y;y=void 0;const R=o.find(j=>j.kind==="node"&&j.nodeId===c);R!==void 0&&(r=R.key)}r!==void 0&&!o.some(c=>c.key===r)&&(r=void 0),u!==void 0&&!t.some(c=>c.jobId===u?.jobId)&&m(!0),p()},"refresh"),m=i(e=>{g!==void 0&&(clearTimeout(g),g=void 0),u!==void 0&&(u=void 0,e&&n.setNotice(""))},"disarmKill"),f=i(()=>{m(!0),r!==void 0&&(r=void 0,p())},"exit"),N=i(e=>H(e)??(e.length===1?e:void 0),"typed"),E=i((e,t=40)=>{const d=(e.split(`
|
|
1
|
+
var M=Object.defineProperty;var i=(b,n)=>M(b,"name",{value:n,configurable:!0});import{execFile as C}from"node:child_process";import{Text as P,decodeKittyPrintable as H,matchesKey as h}from"@earendil-works/pi-tui";import{cliClient as S}from"../../../commands/api-client.js";import{activeBackgroundBashJobs as I}from"../../../core/bash-jobs.js";import{contextDir as T}from"../../../core/canvas/node-agent-paths.js";import{fillBar as O,fillWidth as D,stripSgr as J,REVERSE as U}from"../../../core/canvas/nav-render.js";import{buildCanvasPanelLines as F}from"./canvas-panels.js";const L=15e3;function ne(b,n){const{editor:_,tui:x,pal:K,nodeId:l,remote:a,role:v,canvasSource:$}=b,w=b.containers.reports;let o=[],r,y=process.env.CRTR_ATTACH_ROSTER;y!==void 0&&delete process.env.CRTR_ATTACH_ROSTER;let u,g;const p=i(()=>{n.syncCursor(),w.clear();for(const e of o){const t=e.key===r;w.addChild(new P(t?O(J(e.line),D(),U):e.line,1,0))}x.requestRender()},"paint"),A=i(async()=>{const e=a?[]:(await S().listCrons()).filter(c=>c.created_by===l),t=a?[]:I(T(l)),d=a?[]:(await S().listReviews({state:"open",origin_node_id:l})).reviews;if(o=(await F(l,n.asks(),K,$,e,t,d)).items,y!==void 0){const c=y;y=void 0;const R=o.find(j=>j.kind==="node"&&j.nodeId===c);R!==void 0&&(r=R.key)}r!==void 0&&!o.some(c=>c.key===r)&&(r=void 0),u!==void 0&&!t.some(c=>c.jobId===u?.jobId)&&m(!0),p()},"refresh"),m=i(e=>{g!==void 0&&(clearTimeout(g),g=void 0),u!==void 0&&(u=void 0,e&&n.setNotice(""))},"disarmKill"),f=i(()=>{m(!0),r!==void 0&&(r=void 0,p())},"exit"),N=i(e=>H(e)??(e.length===1?e:void 0),"typed"),E=i((e,t=40)=>{const d=(e.split(`
|
|
2
2
|
`)[0]??"").replace(/\s+/g," ").trim();return d.length>t?`${d.slice(0,t-1)}\u2026`:d},"commandHead"),B=i(()=>{if(v!=="controller"){n.setNotice("Read-only observer attach \u2014 cannot stop background jobs");return}const e=I(T(l));if(e.length===0){n.setNotice("Background job already finished"),n.requestChromeRefresh();return}if(e.length>1){n.setNotice(`${e.length} background jobs \u2014 press \u21B5 to pick one in the Inspector`);return}const t=e[0];u={jobId:t.jobId,label:E(t.command)},n.setNotice(`Stop \u201C${u.label}\u201D? Press y to confirm.`,{sticky:!0}),g=setTimeout(()=>m(!0),L)},"armKill"),k=i(()=>{const e=u;e!==void 0&&(m(!1),n.setNotice(`Stopping \u201C${e.label}\u201D\u2026`),C("crtr",["node","bash","kill",e.jobId,"--node",l],t=>{n.setNotice(t===null?`Stopped \u201C${e.label}\u201D.`:`Could not stop the job: ${t.message.split(`
|
|
3
3
|
`)[0]}`),n.requestChromeRefresh()}))},"confirmKill");_.onCursorDownAtBottom=a?void 0:()=>{r!==void 0||o.length===0||(r=o[0].key,p())};const q=i(()=>{const e=o.find(s=>s.key===r);if(e===void 0||a)return;if(e.kind==="crons"){f(),n.openInspector("schedule");return}if(e.kind==="review"){if(v!=="controller"){n.setNotice("Read-only observer attach \u2014 cannot open the review companion");return}f(),C("crtr",["surface","node","focus",e.companionNodeId],s=>{s!==null&&n.setNotice(`Could not open the companion: ${s.message.split(`
|
|
4
4
|
`)[0]}`)});return}if(e.kind==="bash"){if(I(T(l)).length===0){n.setNotice("Background job already finished"),n.requestChromeRefresh();return}f(),n.openInspector("jobs");return}const t=e.nodeId;if(t===l){f();return}if(v!=="controller"){n.setNotice("Read-only observer attach \u2014 cannot focus nodes");return}const d=process.env.TMUX_PANE;if(d===void 0||d===""){n.setNotice("cannot swap \u2014 no tmux pane");return}C("tmux",["run-shell","-b",`crtr surface node focus ${t} --pane ${d} --in-place >/dev/null 2>&1`],()=>{})},"openSelected");return{refresh:A,handleKey:i(e=>{if(a)return!1;const t=h(e,"down"),d=h(e,"up");if(r===void 0)return!1;const s=o.findIndex(R=>R.key===r),c=o[s];if(u!==void 0){if(N(e)==="y")return k(),!0;m(!0)}return c?.kind==="bash"&&N(e)==="x"?(B(),!0):d?(s<=0?f():(r=o[s-1].key,p()),!0):t?(s>=0&&s<o.length-1&&(r=o[s+1].key,p()),!0):h(e,"enter")?(q(),!0):h(e,"escape")?(f(),!0):(f(),!1)},"handleKey"),active:i(()=>r!==void 0,"active"),exit:f}}i(ne,"createRoster");export{ne as createRoster};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var y=Object.defineProperty;var t=(e,o)=>y(e,"name",{value:o,configurable:!0});import{readFileSync as p}from"node:fs";import{createRequire as b}from"node:module";import{
|
|
1
|
+
var y=Object.defineProperty;var t=(e,o)=>y(e,"name",{value:o,configurable:!0});import{readFileSync as p}from"node:fs";import{createRequire as b}from"node:module";import{piAgentDir as h}from"../../core/runtime/package-health.js";import{join as i}from"node:path";import{pathToFileURL as x}from"node:url";import{KeybindingsManager as K,TUI_KEYBINDINGS as w,setKeybindings as k}from"@earendil-works/pi-tui";import{initTheme as T,getMarkdownTheme as l,getSelectListTheme as E}from"@earendil-works/pi-coding-agent";import{surfaceBgAnsi as B}from"../../core/runtime/surface-bg.js";function s(){return h()}t(s,"defaultAgentDir");const I={"app.interrupt":{defaultKeys:"escape",description:"Cancel or abort"},"app.clear":{defaultKeys:"ctrl+c",description:"Clear editor"},"app.exit":{defaultKeys:"ctrl+d",description:"Exit when editor is empty"},"app.suspend":{defaultKeys:"ctrl+z",description:"Suspend to background"},"app.thinking.cycle":{defaultKeys:"shift+tab",description:"Cycle thinking level"},"app.model.cycleForward":{defaultKeys:"ctrl+p",description:"Cycle to next model"},"app.model.cycleBackward":{defaultKeys:"shift+ctrl+p",description:"Cycle to previous model"},"app.model.select":{defaultKeys:"ctrl+l",description:"Open model selector"},"app.tools.expand":{defaultKeys:"ctrl+o",description:"Toggle tool output"},"app.thinking.toggle":{defaultKeys:"ctrl+t",description:"Toggle thinking blocks"},"app.editor.external":{defaultKeys:"ctrl+g",description:"Open external editor"},"app.message.followUp":{defaultKeys:[],description:"Queue follow-up message"},"app.message.dequeue":{defaultKeys:"alt+up",description:"Restore queued messages"},"app.clipboard.pasteImage":{defaultKeys:["alt+v","ctrl+v"],description:"Paste image from clipboard"},"app.session.new":{defaultKeys:[],description:"Start a new session"},"app.session.tree":{defaultKeys:[],description:"Open session tree"},"app.session.fork":{defaultKeys:[],description:"Fork current session"},"app.session.resume":{defaultKeys:[],description:"Resume a session"}};function R(e=s()){try{const o=JSON.parse(p(i(e,"keybindings.json"),"utf8")),n=o&&typeof o=="object"&&"keybindings"in o?o.keybindings:o;return!n||typeof n!="object"?void 0:n}catch{return}}t(R,"loadUserKeybindings");const $={"tui.input.newLine":{defaultKeys:["shift+enter","alt+enter"],description:"Insert new line"}};function q(e=s()){const o={...w,...I,...$},n=new K(o,R(e));return k(n),n}t(q,"createKeybindingsManager");let a;function u(){return a||(a=(async()=>{try{const e=import.meta.resolve("@earendil-works/pi-coding-agent"),o=b(e).resolve("@earendil-works/pi-tui");return await import(x(o).href)}catch{return}})()),a}t(u,"editorPiTui");async function H(e){(await u())?.setKeybindings(e)}t(H,"mirrorKeybindingsToEditor");async function J(e){(await u())?.setKittyProtocolActive(e)}t(J,"mirrorKittyProtocolToEditor");let c;function V(){return c||(c=(async()=>{try{const e=import.meta.resolve("@earendil-works/pi-coding-agent");return await(await import(new URL("./utils/tools-manager.js",e).href)).ensureTool("fd",!0)??null}catch{return null}})()),c}t(V,"resolveFdPath");function N(e){const o=[i(e?.cwd??process.cwd(),".pi","settings.json"),i(e?.agentDir??s(),"settings.json")];for(const n of o)try{const r=JSON.parse(p(n,"utf8"));if(r&&typeof r=="object"&&typeof r.theme=="string")return r.theme}catch{}}t(N,"loadThemeName");function z(e){T(N(e))}t(z,"applyTheme");const P=t(e=>`\x1B[2m${e}\x1B[22m`,"FAINT"),C=t(e=>`\x1B[31m${e}\x1B[39m`,"RED"),D=t(e=>`\x1B[33m${e}\x1B[39m`,"YELLOW"),f=t(e=>`\x1B[32m${e}\x1B[39m`,"GREEN"),O=t(e=>`\x1B[92m${e}\x1B[39m`,"BRIGHT_GREEN"),v=t(e=>`\x1B[91m${e}\x1B[39m`,"DIFF_REMOVED"),d="\x1B[48;2;36;36;36m";function A(e,o){return`${d}${e(o).replace(/\x1b\[0m/g,`\x1B[0m${d}`)}`}t(A,"codeSurfaceFragment");function Q(){const e=l(),o=t((n,r)=>A(n,r),"paint");return{...e,codeBlockIndent:`${d}${e.codeBlockIndent??" "}`,codeBlock:t(n=>o(e.codeBlock,n),"codeBlock"),codeBlockBorder:t(n=>o(e.codeBlockBorder,n),"codeBlockBorder"),highlightCode:e.highlightCode?(n,r)=>e.highlightCode(n,r).map(m=>o(g=>g,m)):void 0}}t(Q,"attachMarkdownTheme");function W(){const e=l(),o=E(),n=B();return{accent:e.heading,active:e.code,info:e.link,muted:o.description,faint:P,border:e.hr,bold:e.bold,error:C,warning:D,diffAdded:f,diffRemoved:v,bashMode:f,bashModeAlt:O,surface:t(r=>`${n}${r.replace(/\x1b\[0m/g,`\x1B[0m${n}`)}\x1B[49m`,"surface")}}t(W,"attachPalette");export{z as applyTheme,Q as attachMarkdownTheme,W as attachPalette,q as createKeybindingsManager,s as defaultAgentDir,N as loadThemeName,R as loadUserKeybindings,H as mirrorKeybindingsToEditor,J as mirrorKittyProtocolToEditor,V as resolveFdPath};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`));return}
|
|
1
|
+
var v=Object.defineProperty;var t=(i,n)=>v(i,"name",{value:n,configurable:!0});import{join as C}from"node:path";import{execFile as E}from"node:child_process";import{CredentialSynchronizationError as D,ModelRuntime as N,OAuthSelectorComponent as x,LoginDialogComponent as _}from"@earendil-works/pi-coding-agent";import{deleteAuthCredential as B,setAuthCredential as T}from"../../../core/auth-file.js";import{PoolCredentialStore as z}from"../../../core/pool-credential-store.js";import{secretsDir as F}from"../../../core/layout.js";import{dialogAuthInteraction as O}from"../../../core/auth-interaction.js";import{isManagedProvider as S,removeManagedProvider as U}from"../../../core/subscription-state.js";import{daemonManagedLogin as q}from"../../../core/model-auth/daemon-login.js";import{cliClient as G}from"../../../commands/api-client.js";async function A(i){const n=C(F(),"auth.json"),r=C(i,"models.json"),e=new z(n);let l;const w={read:t(a=>e.read(a),"read"),list:t(()=>e.list(),"list"),modify:t((a,m)=>{const u=l;return l=void 0,u!==void 0&&!u()?Promise.reject(new Error("Login cancelled")):e.modify(a,m)},"modify"),delete:t(a=>e.delete(a),"delete")};return{runtime:await N.create({credentials:w,modelsPath:r}),authPath:n,beforeNextCredentialMutation:t(a=>{l=a},"beforeNextCredentialMutation")}}t(A,"buildLocalAuth");async function M(i){const n=i.getProviders(),r=[...n.filter(e=>e.auth.oauth!==void 0),...n.filter(e=>e.auth.oauth===void 0)];return Promise.all(r.map(async e=>({id:e.id,name:e.name,authType:e.auth.oauth!==void 0?"oauth":"api_key",status:await i.checkAuth(e.id)})))}t(M,"buildProviderList");function H(i){const n=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";E(n,[i],{timeout:5e3},()=>{})}t(H,"openBrowser");async function te(i,n,r,e){const{runtime:l,authPath:w,beforeNextCredentialMutation:h}=await A(n),a=await M(l);return({close:m,replace:u})=>{const P=t(f=>{const s=a.find(o=>o.id===f);if(s===void 0){e(`Unknown provider: ${f}`),m();return}let g=!1,$=!1;const p=t(()=>{g||(g=!0,m())},"finish"),c=new _(i,f,(o,L)=>{g||(o?(e(`Logged in to ${s.name}`),r()):e(L?`Login failed: ${L}`:`Login to ${s.name} was cancelled`),p())},s.name);u(c,c);const j=c.handleInput.bind(c);c.handleInput=o=>{$||j(o)};const b=t(()=>g||c.signal.aborted?!1:($=!0,c.showDetails(["Saving credentials\u2026"]),!0),"beginCommit"),y=O(c,{openBrowser:H,isActive:t(()=>!g&&!c.signal.aborted,"isActive")}),k=t(o=>{if(o instanceof D){e(`Logged in to ${s.name}; provider refresh failed: ${o.message}`),r(),p();return}const L=o;L?.name!=="AbortError"&&L?.message!=="Login cancelled"&&e(`Login error: ${String(L?.message??o)}`),p()},"fail");if(S(f)){q(G(),f,y).then(()=>{g||(e(`Logged in to ${s.name}`),r(),p())}).catch(k);return}if(s.authType==="oauth"){if(l.getProvider(f)?.auth.oauth===void 0){c.showInfo([`Provider "${s.name}" is extension-registered and cannot be logged in`,"from the viewer (the extension runs in the broker, not here).","Run /login directly in the node's terminal, or log in via the pi CLI."].join(`
|
|
2
|
+
`));return}h(b),l.login(f,"oauth",y).then(()=>{g||(e(`Logged in to ${s.name}`),r(),p())}).catch(k).finally(()=>h(void 0))}else c.showPrompt(`Enter API key for ${s.name}:`,"sk-...").then(async o=>{if(!g){if(o.trim()){if(!b())return;await T(f,{type:"api_key",key:o.trim()},w),e(`API key saved for ${s.name}`),r()}else e("No key entered \u2014 login cancelled");p()}}).catch(()=>p())},"onSelect"),d=new x("login",a,P,()=>m());return{component:d,focus:d}}}t(te,"buildLoginPicker");async function ne(i,n,r){const{runtime:e,authPath:l}=await A(i),w=await M(e);return({close:h})=>{const a=t(u=>{const P=w.find(d=>d.id===u);(async()=>{try{S(u)?await U(u):await B(u,l),h(),r(`Logged out of ${P?.name??u}`),n()}catch(d){h(),r(`Logout error: ${d instanceof Error?d.message:String(d)}`)}})()},"onSelect"),m=new x("logout",w,a,()=>h());return{component:m,focus:m}}}t(ne,"buildLogoutPicker");export{te as buildLoginPicker,ne as buildLogoutPicker};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var O=Object.defineProperty;var m=(u,t)=>O(u,"name",{value:t,configurable:!0});import{execFile as q}from"node:child_process";import{matchesKey as P,truncateToWidth as T}from"@earendil-works/pi-tui";import{formatBinding as H,matchesPiTuiInput as L}from"../../../core/keybindings/index.js";import{fullName as B}from"../../../core/canvas/labels.js";import{faultSummary as G,resolveNodeVisual as C}from"../../../core/canvas/status-glyph.js";import{RemoteCanvasSource as W}from"../../../core/canvas/remote-canvas-source.js";import{cliClient as F}from"../../../commands/api-client.js";import{statusRank as M}from"../../../core/canvas/node-order.js";import{navLabel as K,nodeGlyph as j,tokensCell as D,cycleBadge as V,askBadge as Y,activityCell as z,shortId as E,visibleWidth as k,fillBar as A,fillWidth as N,truncate as U,isAttached as X,VIEWPORT_FALLBACK_ROWS as J,ESC as Q,DIM as R,RESET as g,BOLD as S,YELLOW as Z,REVERSE as ee,BG_ATTACHED as te,GREEN as se}from"../../../core/canvas/nav-render.js";const ie=.72,ne={anchor:"center",width:"72%",minWidth:48,maxHeight:"72%",margin:1},re=[["crtr.graph.dismiss","dismiss"],["crtr.graph.focus","focus"],["crtr.graph.revive","revive"],["crtr.graph.close-subtree","close"],["crtr.graph.focus-manager","manager"]],oe=[["crtr.graph.dismiss","dismiss"]],ce=[["crtr.graph.down","down"],["crtr.graph.up","up"],["crtr.graph.first","first"],["crtr.graph.last","last"],["crtr.graph.collapse-or-manager","fold/manager"],["crtr.graph.expand-or-child","expand/child"]],ae=[...["active","idle","done","dead","canceled"].map(u=>[C(u,{}),u]),[C("active",{streaming:!0}),"live"],[C("active",{frozen:!0}),"frozen"],[C("active",{hanging:{kind:"wedged"}}),"fault"]].map(([u,t])=>`${Q}${u.color}m${u.glyph}${g} ${R}${t}${g}`).join(" ");function he(u){return{node_id:u.node_id,name:u.name,kind:u.kind,description:u.description??void 0,cycles:u.cycles??void 0,status:u.status,frozen_at:u.frozen_at,pi_pid:u.pi_pid,telemetry_context_tokens:u.telemetry_context_tokens,telemetry_last_activity:u.telemetry_last_activity,fault:u.fault??null,streaming:u.streaming}}m(he,"graphRow");class be{static{m(this,"GraphOverlay")}tui;self;getAsks;palette;bindings;source;role;onRefreshFailure;onNotice;handle;userExpanded=new Set;userCollapsed=new Set;folds={userExpanded:this.userExpanded,userCollapsed:this.userCollapsed};cursorId;scrollTop=0;pendingConfirm;snapshot;snapshotSeq=0;remote;constructor(t,s,i,e,n,o,f="controller",p=()=>{},r=()=>{}){this.tui=t,this.self=s,this.getAsks=i,this.palette=e,this.bindings=n,this.source=o,this.role=f,this.onRefreshFailure=p,this.onNotice=r,this.remote=o instanceof W}setBindings(t){this.bindings=t,this.handle!==void 0&&this.tui.requestRender()}matches(t,s){return L(this.bindings,t,s,(i,e)=>P(i,e))}hint(t){return t.flatMap(([s,i])=>this.bindings.gestures(s).length===0?[]:[`${H(this.bindings,s)} ${i}`])}fitHints(t,s){const e=[];let n=0;for(const o of this.hint(t)){const f=(e.length===0?0:3)+k(o);if(n+f>s)break;e.push(o),n+=f}return e.join(" \xB7 ")}isOpen(){return this.handle!==void 0}open(){this.handle===void 0&&(this.scrollTop=0,this.pendingConfirm=void 0,this.cursorId=this.self,this.handle=this.tui.showOverlay(this,ne),this.refresh())}close(){this.handle!==void 0&&(this.pendingConfirm=void 0,this.handle.hide(),this.handle=void 0,this.tui.requestRender())}toggle(){this.handle===void 0?this.open():this.close()}refresh(){if(this.handle===void 0)return;const t=++this.snapshotSeq;this.buildSnapshot().then(s=>{t===this.snapshotSeq&&(this.snapshot=s,this.tui.requestRender())}).catch(s=>{this.onRefreshFailure(s),this.tui.requestRender()})}invalidate(){this.refresh()}async fetchInput(){if(this.remote){const e=await this.source.listNodes().catch(()=>[]);return{nodes:new Map(e.map(n=>[n.node_id,n])),subscriptions:m(async n=>(await this.source.subscriptionsOf(n)).map(o=>o.node_id),"subscriptions"),subscribers:m(async n=>(await this.source.subscribersOf(n)).map(o=>o.node_id),"subscribers"),focused:new Set}}const t=await F().canvasGraph(),s=new Map,i=new Map;for(const e of t.edges){const n=s.get(e.from_id);n===void 0?s.set(e.from_id,[e.to_id]):n.push(e.to_id);const o=i.get(e.to_id);o===void 0?i.set(e.to_id,[e.from_id]):o.push(e.from_id)}return{nodes:new Map(t.nodes.map(e=>[e.node_id,he(e)])),subscriptions:m(e=>Promise.resolve(s.get(e)??[]),"subscriptions"),subscribers:m(e=>Promise.resolve(i.get(e)??[]),"subscribers"),focused:new Set(t.focused_node_ids)}}async buildSnapshot(){const t=await this.fetchInput(),{nodes:s,focused:i}=t,e=new Map,n=new Map,o=new Map,f=new Map,p=m(async c=>{const l=e.get(c);if(l!==void 0)return l;let a;try{a=await t.subscriptions(c)}catch{a=[]}const $=a.filter(b=>s.get(b)?.kind!=="human");return e.set(c,$),$},"children"),r=m(async c=>{if(o.has(c))return o.get(c);let l;try{l=(await t.subscribers(c))[0]}catch{l=void 0}return o.set(c,l),l},"manager"),h=m(async()=>{let c=this.self;const l=new Set([c]);for(;;){const a=await r(c);if(a===void 0||l.has(a))break;l.add(a),c=a}return c},"climbRoot"),d=m(async c=>{const l=n.get(c);if(l!==void 0)return l;const a=[...await p(c)];return a.sort(($,b)=>M(s.get($)?.status)-M(s.get(b)?.status)),n.set(c,a),a},"sortedChildren"),w=new Set,v=new Set,I=m(async c=>{const l=s.get(c)?.status==="active";if(v.has(c))return{active:l?1:0,reveal:l||c===this.self};v.add(c);let a=0,$=!1;for(const b of await p(c)){const x=await I(b);a+=x.active,x.reveal&&($=!0)}return f.set(c,a),$&&w.add(c),{active:a+(l?1:0),reveal:$||l||c===this.self}},"visitActivity"),_=await h();await I(_),await Promise.all([...e.keys()].map(c=>d(c)));const y={root:_,rows:[],autoExpanded:w,activeBelow:f,nodes:s,childIds:e,sortedChildIds:n,managerOf:o,focused:i};return y.rows=this.projectRows(y),y}projectRows(t){const s=[],i=new Set,e=[{id:t.root,prefix:"",isRoot:!0,isLast:!0}];for(;e.length>0;){const{id:n,prefix:o,isRoot:f,isLast:p}=e.pop(),r=f?"":p?"\u2514\u2500 ":"\u251C\u2500 ";if(i.has(n)){s.push({id:n,hasKids:!1,isSelf:n===this.self,branch:o+r,cycle:!0,collapsed:!1});continue}i.add(n);const h=t.sortedChildIds.get(n)??[],d=this.folds.userExpanded.has(n)?!1:this.folds.userCollapsed.has(n)?!0:!t.autoExpanded.has(n);if(s.push({id:n,hasKids:h.length>0,isSelf:n===this.self,branch:o+r,cycle:!1,collapsed:d}),d)continue;const w=f?"":o+(p?" ":"\u2502 ");for(let v=h.length-1;v>=0;v--)e.push({id:h[v],prefix:w,isRoot:!1,isLast:v===h.length-1})}return s}repaintFolds(){this.snapshot!==void 0&&(this.snapshot.rows=this.projectRows(this.snapshot)),this.tui.requestRender()}renderSnapshotRow(t,s,i,e){const n=m((b,x)=>i?A(b,N(),ee):x?A(b,N(),te):U(b),"wrap");if(s.cycle){const b=`${s.branch} ${R}\u21BA ${E(s.id)}${g}`;return n(b,!1)}const o=t.nodes.get(s.id)??null,f=j(o),p=K(o,s.id),r=s.isSelf?`${S}${p}${g}`:p,h=`${R}${o?.kind??""}${g}`,d=`${R}${D(o,this.remote)}${g}`,w=s.hasKids&&s.collapsed,v=!i&&w?`${R}\u25B8${g} `:" ",I=V(o),_=t.childIds.get(s.id)?.length??0,y=o!==null&&_>0?` ${R}\u2933${_}${g}`:"",c=o!==null&&o.status!=="active"&&(t.activeBelow.get(o.node_id)??0)>0?` ${se}\u21E3${t.activeBelow.get(o.node_id)??0}${g}`:"",l=o?.fault??null,a=l!==null?` \xB7 ${G(l)}`:"",$=`${s.branch}${v}${f} ${r} ${h} ${d}${I}${y}${c}${Y(s.id,e)}${z(o,this.remote)}${a}`;return n($,X(s.id,o,t.focused,this.remote))}render(t){const s=this.getAsks(),i=this.snapshot?.rows??[];let e=i.findIndex(a=>a.id===this.cursorId);e<0&&(e=i.findIndex(a=>a.id===this.self),e<0&&(e=0)),this.cursorId=i[e]?.id??this.self;const n=process.stdout.rows??J,o=Math.max(3,Math.min(Math.floor(n*ie),n-2)),f=Math.min(o-2,Math.max(2,i.length)),p=f-1,r=p>=3;let h=p;for(let a=0;p>0&&a<4;a++){e<this.scrollTop&&(this.scrollTop=e),e>=this.scrollTop+h&&(this.scrollTop=e-h+1),this.scrollTop=Math.max(0,Math.min(this.scrollTop,Math.max(0,i.length-h)));const $=p-(r&&this.scrollTop>0?1:0)-(r&&this.scrollTop+h<i.length?1:0);if($===h)break;h=Math.max(1,$)}const d=Math.min(i.length,this.scrollTop+h),w=[];r&&this.scrollTop>0&&w.push(`${R} \u2191 ${this.scrollTop} more${g}`);for(let a=this.scrollTop;a<d;a++){const $=this.snapshot;w.push($!==void 0?this.renderSnapshotRow($,i[a],a===e,s):"")}for(r&&d<i.length&&w.push(`${R} \u2193 ${i.length-d} more${g}`),w.unshift(ae);w.length<f;)w.push("");const v=i.length>0?`${S}\u2317 canvas graph${g} ${R}(${e+1}/${i.length})${g}`:`${S}\u2317 canvas graph${g} ${R}(loading)${g}`,I=this.pendingConfirm!==void 0?`${Z}${this.pendingConfirm.label} ${S}${this.hint([["crtr.graph.confirm.accept","accept"],["crtr.graph.confirm.cancel","cancel"]]).join(" \xB7 ")}${g}`:`${R}${this.fitHints([...this.remote||this.role!=="controller"?oe:re,...ce],Math.max(1,t-5))}${g}`,_=this.palette.border,y=Math.max(1,t-4),c=w.map(a=>`${_("\u2502")} ${T(a,y,"",!0)} ${_("\u2502")}`),l=this.palette.surface;return[this.borderRow("\u256D","\u256E",v,t),...c,this.borderRow("\u2570","\u256F",I,t)].map(l)}borderRow(t,s,i,e){const n=this.palette.border,o=Math.max(1,e-5),f=T(i,o,"\u2026"),p=Math.max(0,e-5-k(f));return`${n(`${t}\u2500`)} ${f} ${n("\u2500".repeat(p)+s)}`}handleInput(t){try{this.dispatch(t)}catch{}}dispatch(t){if(this.pendingConfirm!==void 0){if(this.matches("crtr.graph.confirm.accept",t)){const r=this.pendingConfirm.action;this.pendingConfirm=void 0,r()}else this.pendingConfirm=void 0;this.tui.requestRender();return}if(this.matches("crtr.graph.dismiss",t)){this.close();return}const s=this.snapshot,i=s?.rows??[];let e=i.findIndex(r=>r.id===this.cursorId);e<0&&(e=Math.max(0,i.findIndex(r=>r.id===this.self)));const n=i[e],o=m(r=>r!==void 0&&!r.cycle,"isSelectable"),f=m((r,h)=>{for(let d=r+h;d>=0&&d<i.length;d+=h)if(o(i[d]))return d;return r},"step"),p=m(r=>{const h=r===1?0:i.length-1;for(let d=h;d>=0&&d<i.length;d+=r)if(o(i[d]))return d;return e},"edge");if(this.matches("crtr.graph.down",t)){e=f(e,1),this.cursorId=i[e]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.up",t)){e=f(e,-1),this.cursorId=i[e]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.first",t)){this.cursorId=i[p(1)]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.last",t)){this.cursorId=i[p(-1)]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.collapse-or-manager",t)){if(n!==void 0&&n.hasKids&&!n.collapsed)this.userCollapsed.add(n.id),this.userExpanded.delete(n.id),this.repaintFolds();else{const r=s?.managerOf.get(this.cursorId??this.self);r!==void 0&&i.some(h=>h.id===r)&&(this.cursorId=r),this.tui.requestRender()}return}if(this.matches("crtr.graph.expand-or-child",t)){if(n!==void 0&&n.collapsed&&n.hasKids)this.userExpanded.add(n.id),this.userCollapsed.delete(n.id),this.repaintFolds();else if(n!==void 0&&n.hasKids){const r=s?.sortedChildIds.get(n.id)?.[0];r!==void 0&&(this.cursorId=r),this.tui.requestRender()}return}if(this.matches("crtr.graph.focus",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot focus nodes");return}this.cursorId!==void 0&&this.focusTarget(this.cursorId),this.close();return}if(this.matches("crtr.graph.revive",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot revive nodes");return}const r=this.cursorId,h=r===void 0?null:s?.nodes.get(r)??null;r!==void 0&&h!==null&&h.status!=="active"&&h.status!=="idle"&&(this.reviveTarget(r),this.close());return}if(this.matches("crtr.graph.focus-manager",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot focus nodes");return}const r=s?.managerOf.get(this.self);r!==void 0&&(this.focusTarget(r),this.close());return}if(this.matches("crtr.graph.close-subtree",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot close nodes");return}const r=this.cursorId??this.self,h=s?.nodes.get(r)??null,d=h!==null?B(h):E(r);this.pendingConfirm={label:`kill ${d}?`,action:m(()=>this.shellCrtr(["node","lifecycle","close","--node",r]),"action")},this.tui.requestRender();return}}focusTarget(t){const s=["surface","node","focus",t],i=process.env.TMUX_PANE;i!==void 0&&i!==""&&s.push("--pane",i),this.shellCrtr(s)}reviveTarget(t){this.shellCrtr(["node","lifecycle","revive",t],()=>this.focusTarget(t))}shellCrtr(t,s){try{q("crtr",t,e=>{e==null&&s?.()}).stdin?.end()}catch{}}}export{be as GraphOverlay};
|
|
1
|
+
var O=Object.defineProperty;var m=(u,t)=>O(u,"name",{value:t,configurable:!0});import{execFile as q}from"node:child_process";import{matchesKey as P,truncateToWidth as T}from"@earendil-works/pi-tui";import{formatBinding as H,matchesPiTuiInput as L}from"../../../core/keybindings/index.js";import{fullName as B}from"../../../core/canvas/labels.js";import{faultSummary as G,resolveNodeVisual as C}from"../../../core/canvas/status-glyph.js";import{RemoteCanvasSource as W}from"../../../core/canvas/remote-canvas-source.js";import{cliClient as F}from"../../../commands/api-client.js";import{statusRank as M}from"../../../core/canvas/node-order.js";import{navLabel as K,nodeGlyph as j,tokensCell as D,cycleBadge as V,askBadge as Y,activityCell as z,shortId as E,visibleWidth as k,fillBar as A,fillWidth as N,truncate as U,isAttached as X,VIEWPORT_FALLBACK_ROWS as J,ESC as Q,DIM as R,RESET as g,BOLD as S,YELLOW as Z,REVERSE as ee,BG_ATTACHED as te,GREEN as se}from"../../../core/canvas/nav-render.js";const ie=.72,ne={anchor:"center",width:"72%",minWidth:48,maxHeight:"72%",margin:1},re=[["crtr.graph.dismiss","dismiss"],["crtr.graph.focus","focus"],["crtr.graph.revive","revive"],["crtr.graph.close-subtree","close"],["crtr.graph.focus-manager","manager"]],oe=[["crtr.graph.dismiss","dismiss"]],ce=[["crtr.graph.down","down"],["crtr.graph.up","up"],["crtr.graph.first","first"],["crtr.graph.last","last"],["crtr.graph.collapse-or-manager","fold/manager"],["crtr.graph.expand-or-child","expand/child"]],ae=[...["active","idle","done","dead","canceled"].map(u=>[C(u,{}),u]),[C("active",{streaming:!0}),"live"],[C("active",{frozen:!0}),"frozen"],[C("active",{hanging:{kind:"wedged"}}),"fault"]].map(([u,t])=>`${Q}${u.color}m${u.glyph}${g} ${R}${t}${g}`).join(" ");function he(u){return{node_id:u.node_id,name:u.name,kind:u.kind,description:u.description??void 0,cycles:u.cycles??void 0,status:u.status,frozen_at:u.frozen_at,pi_pid:u.pi_pid,telemetry_context_tokens:u.telemetry_context_tokens,telemetry_last_activity:u.telemetry_last_activity,fault:u.fault??null,streaming:u.streaming}}m(he,"graphRow");class be{static{m(this,"GraphOverlay")}tui;self;getAsks;palette;bindings;source;role;onRefreshFailure;onNotice;handle;userExpanded=new Set;userCollapsed=new Set;folds={userExpanded:this.userExpanded,userCollapsed:this.userCollapsed};cursorId;scrollTop=0;pendingConfirm;snapshot;snapshotSeq=0;remote;constructor(t,s,i,e,n,o,f="controller",p=()=>{},r=()=>{}){this.tui=t,this.self=s,this.getAsks=i,this.palette=e,this.bindings=n,this.source=o,this.role=f,this.onRefreshFailure=p,this.onNotice=r,this.remote=o instanceof W}setBindings(t){this.bindings=t,this.handle!==void 0&&this.tui.requestRender()}matches(t,s){return L(this.bindings,t,s,(i,e)=>P(i,e))}hint(t){return t.flatMap(([s,i])=>this.bindings.gestures(s).length===0?[]:[`${H(this.bindings,s)} ${i}`])}fitHints(t,s){const e=[];let n=0;for(const o of this.hint(t)){const f=(e.length===0?0:3)+k(o);if(n+f>s)break;e.push(o),n+=f}return e.join(" \xB7 ")}isOpen(){return this.handle!==void 0}open(){this.handle===void 0&&(this.scrollTop=0,this.pendingConfirm=void 0,this.cursorId=this.self,this.handle=this.tui.showOverlay(this,ne),this.refresh())}close(){this.handle!==void 0&&(this.pendingConfirm=void 0,this.handle.hide(),this.handle=void 0,this.tui.requestRender())}toggle(){this.handle===void 0?this.open():this.close()}refresh(){if(this.handle===void 0)return;const t=++this.snapshotSeq;this.buildSnapshot().then(s=>{t===this.snapshotSeq&&(this.snapshot=s,this.tui.requestRender())}).catch(s=>{this.onRefreshFailure(s),this.tui.requestRender()})}invalidate(){this.refresh()}async fetchInput(){if(this.remote){const e=await this.source.listNodes().catch(()=>[]);return{nodes:new Map(e.map(n=>[n.node_id,n])),subscriptions:m(async n=>(await this.source.subscriptionsOf(n)).map(o=>o.node_id),"subscriptions"),subscribers:m(async n=>(await this.source.subscribersOf(n)).map(o=>o.node_id),"subscribers"),focused:new Set}}const t=await F().canvasGraph(),s=new Map,i=new Map;for(const e of t.edges){const n=s.get(e.from_id);n===void 0?s.set(e.from_id,[e.to_id]):n.push(e.to_id);const o=i.get(e.to_id);o===void 0?i.set(e.to_id,[e.from_id]):o.push(e.from_id)}return{nodes:new Map(t.nodes.map(e=>[e.node_id,he(e)])),subscriptions:m(e=>Promise.resolve(s.get(e)??[]),"subscriptions"),subscribers:m(e=>Promise.resolve(i.get(e)??[]),"subscribers"),focused:new Set(t.focused_node_ids)}}async buildSnapshot(){const t=await this.fetchInput(),{nodes:s,focused:i}=t,e=new Map,n=new Map,o=new Map,f=new Map,p=m(async c=>{const l=e.get(c);if(l!==void 0)return l;let a;try{a=await t.subscriptions(c)}catch{a=[]}const $=a.filter(b=>s.get(b)?.kind!=="human");return e.set(c,$),$},"children"),r=m(async c=>{if(o.has(c))return o.get(c);let l;try{l=(await t.subscribers(c))[0]}catch{l=void 0}return o.set(c,l),l},"manager"),h=m(async()=>{let c=this.self;const l=new Set([c]);for(;;){const a=await r(c);if(a===void 0||l.has(a))break;l.add(a),c=a}return c},"climbRoot"),d=m(async c=>{const l=n.get(c);if(l!==void 0)return l;const a=[...await p(c)];return a.sort(($,b)=>M(s.get($)?.status)-M(s.get(b)?.status)),n.set(c,a),a},"sortedChildren"),w=new Set,v=new Set,I=m(async c=>{const l=s.get(c)?.status==="active";if(v.has(c))return{active:l?1:0,reveal:l||c===this.self};v.add(c);let a=0,$=!1;for(const b of await p(c)){const x=await I(b);a+=x.active,x.reveal&&($=!0)}return f.set(c,a),$&&w.add(c),{active:a+(l?1:0),reveal:$||l||c===this.self}},"visitActivity"),_=await h();await I(_),await Promise.all([...e.keys()].map(c=>d(c)));const y={root:_,rows:[],autoExpanded:w,activeBelow:f,nodes:s,childIds:e,sortedChildIds:n,managerOf:o,focused:i};return y.rows=this.projectRows(y),y}projectRows(t){const s=[],i=new Set,e=[{id:t.root,prefix:"",isRoot:!0,isLast:!0}];for(;e.length>0;){const{id:n,prefix:o,isRoot:f,isLast:p}=e.pop(),r=f?"":p?"\u2514\u2500 ":"\u251C\u2500 ";if(i.has(n)){s.push({id:n,hasKids:!1,isSelf:n===this.self,branch:o+r,cycle:!0,collapsed:!1});continue}i.add(n);const h=t.sortedChildIds.get(n)??[],d=this.folds.userExpanded.has(n)?!1:this.folds.userCollapsed.has(n)?!0:!t.autoExpanded.has(n);if(s.push({id:n,hasKids:h.length>0,isSelf:n===this.self,branch:o+r,cycle:!1,collapsed:d}),d)continue;const w=f?"":o+(p?" ":"\u2502 ");for(let v=h.length-1;v>=0;v--)e.push({id:h[v],prefix:w,isRoot:!1,isLast:v===h.length-1})}return s}repaintFolds(){this.snapshot!==void 0&&(this.snapshot.rows=this.projectRows(this.snapshot)),this.tui.requestRender()}renderSnapshotRow(t,s,i,e){const n=m((b,x)=>i?A(b,N(),ee):x?A(b,N(),te):U(b),"wrap");if(s.cycle){const b=`${s.branch} ${R}\u21BA ${E(s.id)}${g}`;return n(b,!1)}const o=t.nodes.get(s.id)??null,f=j(o),p=K(o,s.id),r=s.isSelf?`${S}${p}${g}`:p,h=`${R}${o?.kind??""}${g}`,d=`${R}${D(o,this.remote)}${g}`,w=s.hasKids&&s.collapsed,v=!i&&w?`${R}\u25B8${g} `:" ",I=V(o),_=t.childIds.get(s.id)?.length??0,y=o!==null&&_>0?` ${R}\u2933${_}${g}`:"",c=o!==null&&o.status!=="active"&&(t.activeBelow.get(o.node_id)??0)>0?` ${se}\u21E3${t.activeBelow.get(o.node_id)??0}${g}`:"",l=o?.fault??null,a=l!==null?` \xB7 ${G(l)}`:"",$=`${s.branch}${v}${f} ${r} ${h} ${d}${I}${y}${c}${Y(s.id,e)}${z(o,this.remote)}${a}`;return n($,X(s.id,o,t.focused,this.remote))}render(t){const s=this.getAsks(),i=this.snapshot?.rows??[];let e=i.findIndex(a=>a.id===this.cursorId);e<0&&(e=i.findIndex(a=>a.id===this.self),e<0&&(e=0)),this.cursorId=i[e]?.id??this.self;const n=process.stdout.rows??J,o=Math.max(3,Math.min(Math.floor(n*ie),n-2)),f=Math.min(o-2,1+Math.max(1,i.length)),p=f-1,r=p>=3;let h=p;for(let a=0;p>0&&a<4;a++){e<this.scrollTop&&(this.scrollTop=e),e>=this.scrollTop+h&&(this.scrollTop=e-h+1),this.scrollTop=Math.max(0,Math.min(this.scrollTop,Math.max(0,i.length-h)));const $=p-(r&&this.scrollTop>0?1:0)-(r&&this.scrollTop+h<i.length?1:0);if($===h)break;h=Math.max(1,$)}const d=Math.min(i.length,this.scrollTop+h),w=[];r&&this.scrollTop>0&&w.push(`${R} \u2191 ${this.scrollTop} more${g}`);for(let a=this.scrollTop;a<d;a++){const $=this.snapshot;w.push($!==void 0?this.renderSnapshotRow($,i[a],a===e,s):"")}for(r&&d<i.length&&w.push(`${R} \u2193 ${i.length-d} more${g}`),w.unshift(ae);w.length<f;)w.push("");const v=i.length>0?`${S}\u2317 canvas graph${g} ${R}(${e+1}/${i.length})${g}`:`${S}\u2317 canvas graph${g} ${R}(loading)${g}`,I=this.pendingConfirm!==void 0?`${Z}${this.pendingConfirm.label} ${S}${this.hint([["crtr.graph.confirm.accept","accept"],["crtr.graph.confirm.cancel","cancel"]]).join(" \xB7 ")}${g}`:`${R}${this.fitHints([...this.remote||this.role!=="controller"?oe:re,...ce],Math.max(1,t-5))}${g}`,_=this.palette.border,y=Math.max(1,t-4),c=w.map(a=>`${_("\u2502")} ${T(a,y,"",!0)} ${_("\u2502")}`),l=this.palette.surface;return[this.borderRow("\u256D","\u256E",v,t),...c,this.borderRow("\u2570","\u256F",I,t)].map(l)}borderRow(t,s,i,e){const n=this.palette.border,o=Math.max(1,e-5),f=T(i,o,"\u2026"),p=Math.max(0,e-5-k(f));return`${n(`${t}\u2500`)} ${f} ${n("\u2500".repeat(p)+s)}`}handleInput(t){try{this.dispatch(t)}catch{}}dispatch(t){if(this.pendingConfirm!==void 0){if(this.matches("crtr.graph.confirm.accept",t)){const r=this.pendingConfirm.action;this.pendingConfirm=void 0,r()}else this.pendingConfirm=void 0;this.tui.requestRender();return}if(this.matches("crtr.graph.dismiss",t)){this.close();return}const s=this.snapshot,i=s?.rows??[];let e=i.findIndex(r=>r.id===this.cursorId);e<0&&(e=Math.max(0,i.findIndex(r=>r.id===this.self)));const n=i[e],o=m(r=>r!==void 0&&!r.cycle,"isSelectable"),f=m((r,h)=>{for(let d=r+h;d>=0&&d<i.length;d+=h)if(o(i[d]))return d;return r},"step"),p=m(r=>{const h=r===1?0:i.length-1;for(let d=h;d>=0&&d<i.length;d+=r)if(o(i[d]))return d;return e},"edge");if(this.matches("crtr.graph.down",t)){e=f(e,1),this.cursorId=i[e]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.up",t)){e=f(e,-1),this.cursorId=i[e]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.first",t)){this.cursorId=i[p(1)]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.last",t)){this.cursorId=i[p(-1)]?.id??this.cursorId,this.tui.requestRender();return}if(this.matches("crtr.graph.collapse-or-manager",t)){if(n!==void 0&&n.hasKids&&!n.collapsed)this.userCollapsed.add(n.id),this.userExpanded.delete(n.id),this.repaintFolds();else{const r=s?.managerOf.get(this.cursorId??this.self);r!==void 0&&i.some(h=>h.id===r)&&(this.cursorId=r),this.tui.requestRender()}return}if(this.matches("crtr.graph.expand-or-child",t)){if(n!==void 0&&n.collapsed&&n.hasKids)this.userExpanded.add(n.id),this.userCollapsed.delete(n.id),this.repaintFolds();else if(n!==void 0&&n.hasKids){const r=s?.sortedChildIds.get(n.id)?.[0];r!==void 0&&(this.cursorId=r),this.tui.requestRender()}return}if(this.matches("crtr.graph.focus",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot focus nodes");return}this.cursorId!==void 0&&this.focusTarget(this.cursorId),this.close();return}if(this.matches("crtr.graph.revive",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot revive nodes");return}const r=this.cursorId,h=r===void 0?null:s?.nodes.get(r)??null;r!==void 0&&h!==null&&h.status!=="active"&&h.status!=="idle"&&(this.reviveTarget(r),this.close());return}if(this.matches("crtr.graph.focus-manager",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot focus nodes");return}const r=s?.managerOf.get(this.self);r!==void 0&&(this.focusTarget(r),this.close());return}if(this.matches("crtr.graph.close-subtree",t)){if(this.remote)return;if(this.role!=="controller"){this.onNotice("Read-only observer attach \u2014 cannot close nodes");return}const r=this.cursorId??this.self,h=s?.nodes.get(r)??null,d=h!==null?B(h):E(r);this.pendingConfirm={label:`kill ${d}?`,action:m(()=>this.shellCrtr(["node","lifecycle","close","--node",r]),"action")},this.tui.requestRender();return}}focusTarget(t){const s=["surface","node","focus",t],i=process.env.TMUX_PANE;i!==void 0&&i!==""&&s.push("--pane",i),this.shellCrtr(s)}reviveTarget(t){this.shellCrtr(["node","lifecycle","revive",t],()=>this.focusTarget(t))}shellCrtr(t,s){try{q("crtr",t,e=>{e==null&&s?.()}).stdin?.end()}catch{}}}export{be as GraphOverlay};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)?0:1)}
|
|
3
|
-
`).map(c=>c.trim()).filter(c=>c.length>0),r=this.folded?s.map(
|
|
1
|
+
var _=Object.defineProperty;var l=(t,e)=>_(t,"name",{value:e,configurable:!0});import{createBashToolDefinition as B,createReadToolDefinition as F,createWriteToolDefinition as S}from"@earendil-works/pi-coding-agent";import{Text as A,getCapabilities as E,hyperlink as H,truncateToWidth as m,visibleWidth as g,wrapTextWithAnsi as M}from"@earendil-works/pi-tui";import{homedir as j}from"node:os";import{isAbsolute as I,resolve as N}from"node:path";import{pathToFileURL as z}from"node:url";import{normalizeBashJobPurpose as P}from"../../../core/bash-jobs.js";import{TOOL_ICON as x}from"../../../core/preview-registry.js";import{stripCdPrefix as U}from"../../../shared/strip-cd-prefix.js";function C(t){return typeof t=="string"?t:""}l(C,"str");const G=5e3;function J(t,e,n,i){if(e===void 0||Date.now()-e<G)return[];const s=n?.()??null;return s===null?[]:[m(` ${t.fg("muted",`\u29D7 ${s}`)}`,i,"\u2026")]}l(J,"backgroundHintLines");class b{static{l(this,"FoldedToolCallController")}folded=!1;component;setFolded(e){this.folded=e}capture(e){return this.component=e,e}callComponent(){return this.component}}function K(t){return t.length===0?0:(t.match(/\n/g)?.length??0)+(t.endsWith(`
|
|
2
|
+
`)?0:1)}l(K,"countFileLines");function k(t,e){if(!t)return"";const n=[];return t.added>0&&n.push(e.fg("toolDiffAdded",`+${t.added}`)),t.removed>0&&n.push(e.fg("toolDiffRemoved",`-${t.removed}`)),n.length>0?` ${n.join(" ")}`:""}l(k,"lineChangesDisplay");function q(t,e){return t===void 0?"":` ${e.fg("toolDiffAdded",`+${t}`)}`}l(q,"lineCountDisplay");function Q(t,e,n,i,s){return`${O(x[t],t,n)} ${D(e,n,i)}${k(s,n)}`}l(Q,"foldedFileCallLine");function V(t){const e=j();return t.startsWith(e)?`~${t.slice(e.length)}`:t}l(V,"shortenPath");function D(t,e,n){if(!t)return e.fg("toolOutput","...");const i=V(t);if(!E().hyperlinks)return i;const s=I(t)?t:N(n,t);return H(i,z(s).href)}l(D,"pathDisplay");function O(t,e,n){return`${n.fg("accent",t)} ${n.fg("toolTitle",n.bold(e))}`}l(O,"header");class X{static{l(this,"IconPrefixedToolCall")}child;prefix;constructor(e,n){this.child=e,this.prefix=n}update(e,n){this.child=e,this.prefix=n}invalidate(){this.child.invalidate()}render(e){const n=g(this.prefix),i=this.child.render(Math.max(1,e-n));return i.length===0?[m(this.prefix.trimEnd(),e,"")]:i.map((s,r)=>r===0?m(`${this.prefix}${s}`,e,""):s)}}function le(t,e=new b){const n=F(t);return{name:"read",label:"read",description:"Render read calls with a crtr icon header in the attach viewer.",parameters:{},renderCall(i,s,r){const o=i,d=C(o?.file_path??o?.path);let a="";if(o?.offset!==void 0||o?.limit!==void 0){const h=typeof o?.offset=="number"?o.offset:1,c=typeof o?.limit=="number"?h+o.limit-1:void 0;a=s.fg("warning",`:${h}${c!==void 0?`-${c}`:""}`)}const u=`${O(x.read,"read",s)} ${D(d,s,r.cwd??t)}${a}`,f=r.lastComponent??new A("",0,0);return f.setText(u),e.capture(f)},renderResult(i,s,r,o){return n.renderResult(i,s,r,o)}}}l(le,"createCrtrReadToolDefinition");function ue(t,e=new b){const n=S(t);let i,s;return{name:"write",label:"write",description:"Render write calls with a crtr icon header in the attach viewer.",parameters:{},renderCall(r,o,d){if(e.folded){const u=r,f=d.isError?void 0:K(C(u?.content)),h=Q("write",C(u?.file_path??u?.path),o,d.cwd??t)+q(f,o);return e.capture(new A(h,0,0))}i=n.renderCall(r,o,{...d,lastComponent:i});const a=`${o.fg("accent",x.write)} `;return s?s.update(i,a):s=new X(i,a),e.capture(s)},renderResult(r,o,d,a){return n.renderResult(r,o,d,a)}}}l(ue,"createCrtrWriteToolDefinition");const Y=/^(&&|\|\||\||;|>>|>|<|2>&1|&)$/;function Z(t){return t.match(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|\S+/g)??[]}l(Z,"tokenize");function v(t,e){const n=Z(t);let i=!0;return n.map(r=>Y.test(r)?(i=!0,e.fg("syntaxOperator",r)):i&&!r.includes("=")?(i=!1,e.fg("syntaxFunction",e.bold(r))):(i=!1,r.startsWith("-")?e.fg("muted",r):/^["']/.test(r)?e.fg("syntaxString",r):e.fg("toolOutput",r))).join(" ")}l(v,"styleCommandLine");class y{static{l(this,"BashCallComponent")}command="";purpose;expanded=!1;folded=!1;timeout;theme;startedAt;hint;invalidate(){}update(e,n,i,s,r,o,d,a){this.theme=e,this.command=n,this.purpose=i,this.expanded=s,this.folded=r,this.timeout=o,this.startedAt=d,this.hint=a}backgroundHintLines(e){const n=this.theme;return n===void 0?[]:J(n,this.startedAt,this.hint,e)}render(e){const n=this.theme;if(!n)return[];const i=n.fg("accent",x.bash);if(this.purpose!==void 0)return[m(`${i} ${n.fg("toolOutput",this.purpose)}`,e,"\u2026")];const s=this.command.split(`
|
|
3
|
+
`).map(c=>c.trim()).filter(c=>c.length>0),r=this.folded?s.map(U):s,o=this.timeout?n.fg("muted",` (timeout ${this.timeout}s)`):"";if(r.length===0)return[`${i} ${n.fg("toolOutput","...")}`];if(this.expanded){const c=g(`${i} `),W=" ".repeat(c),L=Math.max(1,e-c),R=[];for(let p=0;p<r.length;p++){let T=v(r[p],n);p===r.length-1&&(T+=o);const w=M(T,L);for(let $=0;$<w.length;$++)R.push(`${p===0&&$===0?`${i} `:W}${w[$]}`)}return R.map(p=>m(p,e,""))}const d=r.length>1?n.fg("muted",` +${r.length-1} lines`):"",a=g(`${i} `)+g(d)+g(o),u=Math.max(8,e-a),f=r[0],h=f.length>u?`${f.slice(0,Math.max(1,u-1))}\u2026`:f;return[m(`${i} ${v(h,n)}${d}${o}`,e)]}}function fe(t,e){return t instanceof y?t.backgroundHintLines(e):[]}l(fe,"bashCallBackgroundHintLines");function ce(t,e=new b,n){const i=B(t);return{name:"bash",label:"bash",description:"Render plain bash calls as a compact styled command line in the attach viewer.",parameters:{},renderCall(s,r,o){const d=s,a=o.state;a&&o.executionStarted&&a.startedAt===void 0&&(a.startedAt=Date.now(),a.endedAt=void 0);const u=o.lastComponent instanceof y?o.lastComponent:new y,f=a?.startedAt!==void 0&&a.endedAt===void 0;return u.update(r,C(d?.command),e.folded?P(d?.purpose)??void 0:void 0,!!o.expanded&&!e.folded,e.folded,typeof d?.timeout=="number"?d.timeout:void 0,f?a?.startedAt:void 0,n),e.capture(u)},renderResult(s,r,o,d){return i.renderResult(s,r,o,d)}}}l(ce,"createCrtrPlainBashToolDefinition");export{b as FoldedToolCallController,fe as bashCallBackgroundHintLines,ce as createCrtrPlainBashToolDefinition,le as createCrtrReadToolDefinition,ue as createCrtrWriteToolDefinition,Q as foldedFileCallLine};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var T=Object.defineProperty;var o=(e,r)=>T(e,"name",{value:r,configurable:!0});import{createConnection as y}from"node:net";import{apiSocketPath as A,viewSocketPath as P}from"../../../core/canvas/paths.js";import{BrokerClient as x,BrokerUnavailableError as E,RelayTransport as g}from"../../../core/broker-client/index.js";import{resolveRemoteCanvasTarget as _}from"../../../core/remote-canvas-target.js";import{ApiCanvasSource as R,cliCanvasSource as F,cliClient as S,rethrowAsCliError as M}from"../../../commands/api-client.js";import{InputError as p}from"../../../core/io.js";function U(e,r){return e||r?"observer":"controller"}o(U,"resolveHelloRole");async function $(e){const r=Number(process.env.CRTR_ATTACH_WAIT_MS??"");if(!Number.isFinite(r)||r<=0)return;const w=P(e),l=Date.now()+r;for(;Date.now()<l;){if(await new Promise(a=>{const s=y(w),c=o(n=>{s.destroy(),a(n)},"settle");s.once("connect",()=>c(!0)),s.once("error",()=>c(!1))}))return;await new Promise(a=>setTimeout(a,100))}}o($,"preWaitForViewSocket");async function V(e,r,w=!0){const l=r!==void 0,h=l?F({canvasName:r}):new R;let a,s,c,n,d;if(l)a={cwd:process.cwd()},c=new g(e,_(r));else{const t=await h.getNode(e);if(t===null)throw new p({error:"not_found",message:`no node: ${e}`,received:e,next:"List nodes with `crtr node inspect list`."});a=t,s=t;try{if((await S().ensureAttach(e,{resume:!0,revive:!0,wakeParked:w})).parked){const u=await S().getSnapshot(e);n=u.snapshot,d=u.commands}}catch(m){M(m,"The node may be finalized or otherwise not attachable.")}n===void 0&&await $(e),c=new g(e,{socketPath:A()})}const i=new x(e,{transport:c}),k=o(t=>t instanceof E?new p({error:"no_broker",message:t.message,received:e,next:"Focus or revive the node first \u2014 attach needs a running headless broker."}):new p({error:"socket_error",message:`could not attach to node ${e}: ${String(t?.message??t)}`,received:e,next:"Check the node has a running headless broker."}),"toAttachError");let f;return i.on("error",t=>{f===void 0&&(f=t)}),n===void 0&&await new Promise((t,m)=>{const u=o(()=>{C(),t()},"onConnect"),v=o(b=>{C(),m(b)},"onErr"),C=o(()=>{i.off("connect",u),i.off("error",v)},"cleanup");i.on("connect",u),i.on("error",v),i.connect()}).catch(t=>{throw k(t)}),{remote:l,canvasSource:h,meta:a,nodeIdentity:s,socket:i,...n===void 0?{}:{initialSnapshot:n,initialCommands:d},assertConnected:o(()=>{if(n===void 0&&f!==void 0)throw k(f)},"assertConnected")}}o(V,"connectToNode");export{V as connectToNode,$ as preWaitForViewSocket,U as resolveHelloRole};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var j=Object.defineProperty;var l=(e,t)=>j(e,"name",{value:t,configurable:!0});import{constants as k,accessSync as P,existsSync as E,mkdtempSync as z,readFileSync as F,rmSync as p,statSync as C}from"node:fs";import{tmpdir as I}from"node:os";import{delimiter as M,dirname as T,join as a,resolve as g,sep as v}from"node:path";import{execFile as S,spawnSync as q}from"node:child_process";import{loadProfileManifest as O,profileMemoryDir as A}from"../../../core/profiles/manifest.js";import{contextDir as H,reportsDir as L}from"../../../core/canvas/paths.js";import{shellQuote as c}from"../../../core/runtime/placement-tmux.js";import{surfaceTmuxStyleArgs as b}from"../../../core/runtime/surface-bg.js";function R(e,t){const r=new Map(e.map(o=>[o.node_id,o])),n=new Set([t]);for(let o=r.get(t);o?.parent!==null&&o?.parent!==void 0;){const f=o.parent;if(n.has(f))break;n.add(f),o=r.get(f)}const s=[t];for(;s.length>0;){const o=s.pop();for(const f of e)f.parent!==o||n.has(f.node_id)||(n.add(f.node_id),s.push(f.node_id))}return e.filter(o=>n.has(o.node_id)).map(o=>o.node_id)}l(R,"relatedNodeIds");function se(e,t){const r=new Set(R(e,t));return e.filter(n=>r.has(n.node_id)).map(n=>n.cwd)}l(se,"relatedNodeDirs");function W(e){const t=[];for(const r of e)try{t.push(H(r),L(r))}catch{continue}return m(t)}l(W,"familyDocumentDirs");function w(e){try{return C(e).isDirectory()}catch{return!1}}l(w,"isDirectory");function B(e,t){const r=[...t==null?[]:[t],...(process.env.PATH??"").split(M).filter(Boolean).map(n=>a(n,e))];return[...new Set(r)]}l(B,"executableCandidates");function y(e,t){for(const r of B(e,t)){try{P(r,k.X_OK)}catch{continue}if(q(r,["--version"],{stdio:"ignore"}).status===0)return r}return null}l(y,"workingExecutable");function K(e){if(e===null||e==="")return{projects:[],memory:null};try{const{profileId:t,manifest:r}=O(e);return{projects:r.projects.map(n=>n.path),memory:A(t)}}catch{return{projects:[],memory:null}}}l(K,"profileSearchRoots");function m(e){const t=new Set,r=[];for(const n of e){const s=g(n);t.has(s)||!w(s)||(t.add(s),r.push(s))}return r}l(m,"dedupeExistingDirs");function Q(e){return e.filter(t=>!e.some(r=>r!==t&&t.startsWith(r+v)))}l(Q,"outermostDirs");function X(e){const t=[];for(const r of e){let n=g(r);for(;;){const s=a(n,".crouter","memory");w(s)&&t.push(s);const o=T(n);if(o===n)break;n=o}}return m(t)}l(X,"ancestorMemoryDirs");const G=20;function J(e){try{const t=F(e);if(t.length===0)return null;const r=t[t.length-1]===0?t.length-1:t.length;return t.subarray(0,r).toString("utf8")||null}catch{return null}}l(J,"selectionPath");function le(e){const t=y("fd",e.fdPath);if(t===null){e.onNotice("fd is required for profile file search");return}const r=y("fzf");if(r===null){e.onNotice("fzf is required for profile file search");return}const n=y("nvim");if(n===null){e.onNotice("Neovim is required for profile file search");return}const s=K(e.profileId),o=m([e.cwd,...e.nodeDirs,...s.projects]);if(o.length===0){e.onNotice("No profile file-search directories exist");return}const f=Q(o),D=m([...s.memory===null?[]:[s.memory],...X(o)]),u=z(a(I(),"crtr-profile-files-")),x=a(u,"selection"),$=a(u,"candidates"),N=W(e.nodeIds).filter(i=>!f.some(d=>i===d||i.startsWith(d+v))),_=`{ ${[...f.map(i=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("**/.crouter/memory/**")} . ${c(i)}`),...N.map(i=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("/jobs")} . ${c(i)}`),...D.map(i=>`${c(t)} --type f --hidden --exclude .git --no-ignore . ${c(i)}`)].map(i=>`${i} &`).join(" ")} wait; } > ${c($)} && ${c(r)} --print0 --scheme=path --hscroll-off=${G} --header ${c("fuzzy path \u2022 ctrl-y yank file path")} --bind ${c("ctrl-y:execute-silent(printf '%s' {} | { if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif command -v wl-copy >/dev/null 2>&1; then wl-copy; elif command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else cat >/dev/null; fi; }; printf '%s' {} | tmux load-buffer -w -)+abort")} --preview ${c("head -100 -- {}")} < ${c($)} > ${c(x)}`;try{S("tmux",["display-popup","-E","-T"," profile files ","-w","80%","-h","60%",...b(),_],()=>{const i=J(x);if(i===null||!E(i)){p(u,{recursive:!0,force:!0});return}const d=`exec ${c(n)} -- ${c(i)}`;try{S("tmux",["display-popup","-E","-T"," profile file ","-w","90%","-h","90%",...b(),d],()=>p(u,{recursive:!0,force:!0}))}catch(h){p(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file: ${h instanceof Error?h.message:String(h)}`)}})}catch(i){p(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file search: ${i instanceof Error?i.message:String(i)}`)}}l(le,"launchProfileFileSearch");export{le as launchProfileFileSearch,se as relatedNodeDirs,R as relatedNodeIds};
|
|
1
|
+
var j=Object.defineProperty;var l=(e,t)=>j(e,"name",{value:t,configurable:!0});import{constants as k,accessSync as P,existsSync as E,mkdtempSync as z,readFileSync as F,rmSync as p,statSync as C}from"node:fs";import{tmpdir as I}from"node:os";import{delimiter as M,dirname as T,join as a,resolve as g,sep as v}from"node:path";import{execFile as S,spawnSync as q}from"node:child_process";import{loadProfileManifest as O,profileMemoryDir as A}from"../../../core/profiles/manifest.js";import{contextDir as H,reportsDir as L}from"../../../core/canvas/node-agent-paths.js";import{shellQuote as c}from"../../../core/runtime/placement-tmux.js";import{surfaceTmuxStyleArgs as b}from"../../../core/runtime/surface-bg.js";function R(e,t){const r=new Map(e.map(o=>[o.node_id,o])),n=new Set([t]);for(let o=r.get(t);o?.parent!==null&&o?.parent!==void 0;){const f=o.parent;if(n.has(f))break;n.add(f),o=r.get(f)}const s=[t];for(;s.length>0;){const o=s.pop();for(const f of e)f.parent!==o||n.has(f.node_id)||(n.add(f.node_id),s.push(f.node_id))}return e.filter(o=>n.has(o.node_id)).map(o=>o.node_id)}l(R,"relatedNodeIds");function se(e,t){const r=new Set(R(e,t));return e.filter(n=>r.has(n.node_id)).map(n=>n.cwd)}l(se,"relatedNodeDirs");function W(e){const t=[];for(const r of e)try{t.push(H(r),L(r))}catch{continue}return m(t)}l(W,"familyDocumentDirs");function w(e){try{return C(e).isDirectory()}catch{return!1}}l(w,"isDirectory");function B(e,t){const r=[...t==null?[]:[t],...(process.env.PATH??"").split(M).filter(Boolean).map(n=>a(n,e))];return[...new Set(r)]}l(B,"executableCandidates");function y(e,t){for(const r of B(e,t)){try{P(r,k.X_OK)}catch{continue}if(q(r,["--version"],{stdio:"ignore"}).status===0)return r}return null}l(y,"workingExecutable");function K(e){if(e===null||e==="")return{projects:[],memory:null};try{const{profileId:t,manifest:r}=O(e);return{projects:r.projects.map(n=>n.path),memory:A(t)}}catch{return{projects:[],memory:null}}}l(K,"profileSearchRoots");function m(e){const t=new Set,r=[];for(const n of e){const s=g(n);t.has(s)||!w(s)||(t.add(s),r.push(s))}return r}l(m,"dedupeExistingDirs");function Q(e){return e.filter(t=>!e.some(r=>r!==t&&t.startsWith(r+v)))}l(Q,"outermostDirs");function X(e){const t=[];for(const r of e){let n=g(r);for(;;){const s=a(n,".crouter","memory");w(s)&&t.push(s);const o=T(n);if(o===n)break;n=o}}return m(t)}l(X,"ancestorMemoryDirs");const G=20;function J(e){try{const t=F(e);if(t.length===0)return null;const r=t[t.length-1]===0?t.length-1:t.length;return t.subarray(0,r).toString("utf8")||null}catch{return null}}l(J,"selectionPath");function le(e){const t=y("fd",e.fdPath);if(t===null){e.onNotice("fd is required for profile file search");return}const r=y("fzf");if(r===null){e.onNotice("fzf is required for profile file search");return}const n=y("nvim");if(n===null){e.onNotice("Neovim is required for profile file search");return}const s=K(e.profileId),o=m([e.cwd,...e.nodeDirs,...s.projects]);if(o.length===0){e.onNotice("No profile file-search directories exist");return}const f=Q(o),D=m([...s.memory===null?[]:[s.memory],...X(o)]),u=z(a(I(),"crtr-profile-files-")),x=a(u,"selection"),$=a(u,"candidates"),N=W(e.nodeIds).filter(i=>!f.some(d=>i===d||i.startsWith(d+v))),_=`{ ${[...f.map(i=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("**/.crouter/memory/**")} . ${c(i)}`),...N.map(i=>`${c(t)} --type f --hidden --exclude .git --exclude ${c("/jobs")} . ${c(i)}`),...D.map(i=>`${c(t)} --type f --hidden --exclude .git --no-ignore . ${c(i)}`)].map(i=>`${i} &`).join(" ")} wait; } > ${c($)} && ${c(r)} --print0 --scheme=path --hscroll-off=${G} --header ${c("fuzzy path \u2022 ctrl-y yank file path")} --bind ${c("ctrl-y:execute-silent(printf '%s' {} | { if command -v pbcopy >/dev/null 2>&1; then pbcopy; elif command -v wl-copy >/dev/null 2>&1; then wl-copy; elif command -v xclip >/dev/null 2>&1; then xclip -selection clipboard; else cat >/dev/null; fi; }; printf '%s' {} | tmux load-buffer -w -)+abort")} --preview ${c("head -100 -- {}")} < ${c($)} > ${c(x)}`;try{S("tmux",["display-popup","-E","-T"," profile files ","-w","80%","-h","60%",...b(),_],()=>{const i=J(x);if(i===null||!E(i)){p(u,{recursive:!0,force:!0});return}const d=`exec ${c(n)} -- ${c(i)}`;try{S("tmux",["display-popup","-E","-T"," profile file ","-w","90%","-h","90%",...b(),d],()=>p(u,{recursive:!0,force:!0}))}catch(h){p(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file: ${h instanceof Error?h.message:String(h)}`)}})}catch(i){p(u,{recursive:!0,force:!0}),e.onNotice(`Could not open profile file search: ${i instanceof Error?i.message:String(i)}`)}}l(le,"launchProfileFileSearch");export{le as launchProfileFileSearch,se as relatedNodeDirs,R as relatedNodeIds};
|