@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
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var c=Object.defineProperty;var n=(t,r)=>c(t,"name",{value:r,configurable:!0});import{hasActiveLiveSubscription as p,hasLiveMessageWait as f,hasPendingCronWake as m,getNode as d
|
|
1
|
+
var c=Object.defineProperty;var n=(t,r)=>c(t,"name",{value:r,configurable:!0});import{hasActiveLiveSubscription as p,hasLiveMessageWait as f,hasPendingCronWake as m,getNode as d}from"../canvas/index.js";import{contextDir as h}from"../canvas/node-agent-paths.js";import{activeBackgroundBashJobs as g}from"../bash-jobs.js";import{hasOpenReplyBearingRequestByRequester as v}from"../human/requests.js";import{formatCard as o,formatStructuredOutputReprompt as w,STALL_REPROMPT as R}from"../../shared/generated-context.js";import{readOutputRequest as S}from"./structured-output.js";import{STALL_REPROMPT as C}from"../../shared/generated-context.js";function y(t){return o("stop-guard",{},w(JSON.stringify(t,null,2)))}n(y,"formatValidStructuredOutputReprompt");function O(t){return o("stop-guard",{},`Structured-output request file is invalid and cannot be used: ${t}
|
|
2
2
|
|
|
3
3
|
You have two options:
|
|
4
4
|
1. Remove the invalid file (the output-schema.json in your node directory has been corrupted)
|
|
5
5
|
2. Fix the corruption if you know the original request schema
|
|
6
6
|
|
|
7
|
-
After resolving the file, retry with \`crtr push result\` (or \`crtr push result --decline "<reason>" --code <token>\` when the schema cannot be honestly satisfied). If this is unexpected, escalate to the user using \`crtr human send\`.`)}n(O,"formatInvalidStructuredOutputReprompt");function l(t,r){return m(t)?"scheduled":p(t)||f(t)||v(t)||r?"awaiting":null}n(l,"wakeCapableWait");function
|
|
7
|
+
After resolving the file, retry with \`crtr push result\` (or \`crtr push result --decline "<reason>" --code <token>\` when the schema cannot be honestly satisfied). If this is unexpected, escalate to the user using \`crtr human send\`.`)}n(O,"formatInvalidStructuredOutputReprompt");function l(t,r){return m(t)?"scheduled":p(t)||f(t)||v(t)||r?"awaiting":null}n(l,"wakeCapableWait");function A(t,r,i=g(h(t)).length>0){if(r.pushedFinal)return{action:"allow",reason:"finished"};const a=S(t);if(a.state==="valid"){const u=l(t,i);return u!==null?{action:"allow",reason:u}:{action:"reprompt",reason:"stalled",message:y(a.request.schema)}}if(a.state==="invalid")return{action:"reprompt",reason:"stalled",message:O(a.error)};const e=d(t);if(e!==null&&(e.final_report!=null||e.status==="done"||e.status==="dead"||e.status==="canceled"))return{action:"allow",reason:"finished"};if(e!==null&&e.lifecycle==="resident")return{action:"allow",reason:"dormant"};const s=l(t,i);return s!==null?{action:"allow",reason:s}:{action:"reprompt",reason:"stalled",message:o("stop-guard",{},R)}}n(A,"evaluateStop");export{C as STALL_REPROMPT,A as evaluateStop};
|
|
@@ -5,10 +5,10 @@ export type StopSignal = keyof StopSignals;
|
|
|
5
5
|
/** Record a successful command outcome for this broker process. The stophook
|
|
6
6
|
* consumes the marker at settlement, so no broker-side canvas read is needed to
|
|
7
7
|
* recognize the command the node itself just completed. */
|
|
8
|
-
export declare function markStopSignal(nodeId: string, signal: StopSignal): void;
|
|
8
|
+
export declare function markStopSignal(nodeId: string, signal: StopSignal, identity?: string): void;
|
|
9
9
|
/** Consume command outcomes from this broker's just-settled turn. Markers from
|
|
10
10
|
* an earlier crashed broker are discarded rather than bleeding into its successor. */
|
|
11
|
-
export declare function consumeStopSignals(nodeId: string): StopSignals;
|
|
11
|
+
export declare function consumeStopSignals(nodeId: string, identity?: string): StopSignals;
|
|
12
12
|
/** Discard any marker left by an earlier run of this same broker — a run that
|
|
13
13
|
* errored or was interrupted returns before settlement consumes its markers, and
|
|
14
14
|
* the pid stamp cannot tell those apart from the current run's. Called when a new
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var S=Object.defineProperty;var t=(r,n)=>S(r,"name",{value:n,configurable:!0});import{existsSync as l,mkdirSync as m,readFileSync as g,rmSync as s,writeFileSync as y}from"node:fs";import{join as d}from"node:path";import{jobDir as f}from"../canvas/paths.js";const u=["pushedFinal"];function e(r,n){return d(f(r),`.${n}`)}t(e,"signalPath");function a(){return process.env.CRTR_BROKER_PID??String(process.pid)}t(a,"brokerIdentity");function R(r,n,o=a()){m(f(r),{recursive:!0}),y(e(r,n),o)}t(R,"markStopSignal");function b(r,n=a()){const o={pushedFinal:!1};for(const c of u){const i=e(r,c);if(!l(i))continue;const p=g(i,"utf8").trim();s(i,{force:!0}),p===n&&(o[c]=!0)}return o}t(b,"consumeStopSignals");function P(r){for(const n of u)s(e(r,n),{force:!0})}t(P,"clearStopSignals");export{P as clearStopSignals,b as consumeStopSignals,R as markStopSignal};
|
|
@@ -22,9 +22,14 @@ export declare const OUTPUT_SCHEMA_TRANSPORT = "A .json file path, or inline JSO
|
|
|
22
22
|
* nothing, so an over-constrained schema costs the target retries. */
|
|
23
23
|
export declare const OUTPUT_SCHEMA_CONSTRAINTS = "The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result with `crtr push result`; a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines with `crtr push result --decline \"<reason>\" --code <token> [--retryable]`, which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.";
|
|
24
24
|
export declare function outputSchemaPath(nodeId: string): string;
|
|
25
|
-
|
|
25
|
+
/** Broker-visible copy; the daemon validates only against outputSchemaPath. */
|
|
26
|
+
export declare function brokerOutputSchemaPath(nodeId: string): string;
|
|
27
|
+
export declare function projectOutputSchema(nodeId: string): void;
|
|
28
|
+
export declare function outputResultPath(nodeId: string, grantee?: string): string;
|
|
29
|
+
/** The node's machine result, read beneath its agent folder; undefined when it wrote none. */
|
|
30
|
+
export declare function readOutputResult(nodeId: string, grantee?: string): unknown;
|
|
26
31
|
/** The marker a declined request leaves beside where `result.json` would have been. */
|
|
27
|
-
export declare function outputDeclinedPath(nodeId: string): string;
|
|
32
|
+
export declare function outputDeclinedPath(nodeId: string, grantee?: string): string;
|
|
28
33
|
export interface OutputDeclined extends DeclinedResult {
|
|
29
34
|
mode: StructuredOutputMode;
|
|
30
35
|
at: string;
|
|
@@ -36,6 +41,7 @@ export declare function writeOutputSchema(nodeId: string, mode: StructuredOutput
|
|
|
36
41
|
* Returns a tri-state: absent (file doesn't exist), valid (parsed successfully),
|
|
37
42
|
* or invalid (file exists but is malformed). */
|
|
38
43
|
export declare function readOutputRequest(nodeId: string): StructuredOutputState;
|
|
44
|
+
export declare function readBrokerOutputRequest(nodeId: string): StructuredOutputState;
|
|
39
45
|
/** Validate a submitted result value against a stored output schema. Returns
|
|
40
46
|
* the validated value (the validator applies the same benign coercions the
|
|
41
47
|
* retired `submit` tool did — e.g. "5" → 5 for a number field), or throws an
|
|
@@ -45,8 +51,8 @@ export declare function validateStructuredResult(schema: Record<string, unknown>
|
|
|
45
51
|
/** Persist a validated result atomically (temp-file-plus-rename), so a
|
|
46
52
|
* concurrent reader (Core's result poll peeks this file) never sees a torn
|
|
47
53
|
* write. Returns the result path. */
|
|
48
|
-
export declare function writeOutputResult(nodeId: string, value: unknown): string;
|
|
54
|
+
export declare function writeOutputResult(nodeId: string, value: unknown, grantee?: string): string;
|
|
49
55
|
/** Persist a decline atomically. `result.json` is left untouched: a one-off
|
|
50
56
|
* decline after an earlier answered request must not erase that answer. */
|
|
51
|
-
export declare function writeOutputDeclined(nodeId: string, declined: OutputDeclined): string;
|
|
57
|
+
export declare function writeOutputDeclined(nodeId: string, declined: OutputDeclined, grantee?: string): string;
|
|
52
58
|
export declare function removeOutputSchema(nodeId: string): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,
|
|
3
|
-
`,
|
|
4
|
-
`,
|
|
1
|
+
var w=Object.defineProperty;var o=(t,e)=>w(t,"name",{value:e,configurable:!0});import{existsSync as d,mkdirSync as N,readFileSync as c,unlinkSync as S,writeFileSync as v,renameSync as $}from"node:fs";import{dirname as J,resolve as j}from"node:path";import{randomUUID as P}from"node:crypto";import{nodeDir as R,nodeRunDir as O,contextDir as b,nodeAgentDir as l}from"../canvas/paths.js";import{readTextBeneathIfExists as T,unlinkBeneath as _,writeFileBeneath as m}from"../spaces/open-beneath.js";import{InputError as p}from"../io.js";import{isRecord as h}from"../../shared/predicates.js";const H="A .json file path, or inline JSON beginning with `{`.",M='The full schema (including enum, pattern, and numeric bounds) is enforced when the target submits its result with `crtr push result`; a mismatch rejects with the field errors and records nothing, so an over-constrained schema costs the target retries. A target that cannot honestly satisfy the schema declines with `crtr push result --decline "<reason>" --code <token> [--retryable]`, which records a failure outcome with reason `declined` carrying the reason, code, and retryable flag instead of a value.';function i(t){return`${R(t)}/output-schema.json`}o(i,"outputSchemaPath");function f(t){return`${O(t)}/output-schema.json`}o(f,"brokerOutputSchemaPath");function q(t){const e=i(t),r=f(t);d(e)&&m(O(t),r,c(e),{atomic:!0})}o(q,"projectOutputSchema");function x(t,e){return`${b(t,e)}/result.json`}o(x,"outputResultPath");function V(t,e){const r=T(l(t,e),x(t,e));return r===null?void 0:JSON.parse(r)}o(V,"readOutputResult");function y(t,e){return`${b(t,e)}/declined.json`}o(y,"outputDeclinedPath");function W(t){const e=t?.trim();if(e===void 0||e==="")return null;let r,n;if(e.startsWith("{"))r=e,n="inline JSON";else{const u=j(e);n=u;try{r=c(u,"utf8")}catch(s){throw new p({error:"bad_output_schema",message:`could not read output schema from ${u}: ${s.message}`,field:"output-schema",next:"Pass a readable JSON Schema file path, or inline JSON beginning with `{`."})}}let a;try{a=JSON.parse(r)}catch(u){throw new p({error:"bad_output_schema",message:`output schema from ${n} is not valid JSON: ${u.message}`,field:"output-schema",next:"Pass valid JSON whose top-level value is an object."})}if(!h(a))throw new p({error:"bad_output_schema",message:`output schema from ${n} must be a JSON object`,field:"output-schema",next:"Pass a JSON Schema object, not an array, string, number, boolean, or null."});return a}o(W,"parseOutputSchemaValue");function z(t,e,r){const n=i(t);N(J(n),{recursive:!0});const u=`${JSON.stringify({mode:e,schema:r},null,2)}
|
|
2
|
+
`,s=`${n}.${P()}.tmp`;return v(s,u,"utf8"),$(s,n),q(t),n}o(z,"writeOutputSchema");function G(t){return g(i(t))}o(G,"readOutputRequest");function K(t){return g(f(t))}o(K,"readBrokerOutputRequest");function g(t){if(!d(t))return{state:"absent"};let e;try{e=c(t,"utf8")}catch(u){return{state:"invalid",error:`could not read request file: ${u.message}`}}let r;try{r=JSON.parse(e)}catch(u){return{state:"invalid",error:`request file is not valid JSON: ${u.message}`}}if(!h(r))return{state:"invalid",error:"request file top-level value must be an object"};const n=r.mode,a=r.schema;return n!=="terminal"&&n!=="oneoff"?{state:"invalid",error:`mode must be 'terminal' or 'oneoff', got ${JSON.stringify(n)}`}:h(a)?{state:"valid",request:{mode:n,schema:a}}:{state:"invalid",error:`schema must be an object, got ${typeof a}`}}o(g,"readOutputRequestAt");async function L(t,e){const{validateToolArguments:r}=await import("@earendil-works/pi-ai");return r({name:"submit",description:"",parameters:t},{type:"toolCall",id:"structured-output",name:"submit",arguments:e})}o(L,"validateStructuredResult");function Q(t,e,r){const n=l(t,r),a=x(t,r);m(n,a,`${JSON.stringify(e,null,2)}
|
|
3
|
+
`,{atomic:!0});try{_(n,y(t,r))}catch(u){if(u.code!=="ENOENT")throw u}return a}o(Q,"writeOutputResult");function X(t,e,r){const n=y(t,r);return m(l(t,r),n,`${JSON.stringify(e,null,2)}
|
|
4
|
+
`,{atomic:!0}),n}o(X,"writeOutputDeclined");function Y(t){const e=i(t);try{S(e)}catch{}const r=f(t);try{S(r)}catch{}}o(Y,"removeOutputSchema");export{M as OUTPUT_SCHEMA_CONSTRAINTS,H as OUTPUT_SCHEMA_TRANSPORT,f as brokerOutputSchemaPath,y as outputDeclinedPath,x as outputResultPath,i as outputSchemaPath,W as parseOutputSchemaValue,q as projectOutputSchema,K as readBrokerOutputRequest,G as readOutputRequest,V as readOutputResult,Y as removeOutputSchema,L as validateStructuredResult,X as writeOutputDeclined,Q as writeOutputResult,z as writeOutputSchema};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var X=Object.defineProperty;var u=(e,n)=>X(e,"name",{value:n,configurable:!0});import{mkdtempSync as H,rmSync as J,writeFileSync as Q}from"node:fs";import{tmpdir as D}from"node:os";import{join as M}from"node:path";import{ATTACH_CONTROL_BINDINGS as O,BINDING_CATALOG as _,BINDING_IDS as Y,encodeAttachControlInput as Z,formatGesture as V,isAttachPaneBinding as ee,resolveUserKeybindingSettings as ne}from"../keybindings/index.js";import{normalizeTmuxPassthrough as te}from"../config.js";import{withExclusiveDirectoryLock as re}from"../exclusive-lock.js";import{surfaceTmuxStyleArgs as ie}from"./surface-bg.js";import{runTmux as f,shellQuote as h}from"./tmux-driver.js";const A="@crtr_keybindings_manifest",p="root",oe={"crtr.tmux.menu.promote":{description:"promote to orchestrator",action:{kind:"keys",keys:"/promote"}},"crtr.tmux.menu.resume":{description:"find node",action:{kind:"keys",keys:"/resume"}},"crtr.tmux.menu.fork":{description:"fork into idle root",action:{kind:"direct",run:"node fork --pane {pane}"}},"crtr.tmux.menu.demote-mode":{description:"demote to base node",action:{kind:"command",run:"node config --mode base --pane {pane}"}},"crtr.tmux.menu.demote":{description:"demote to terminal (finish when done)",action:{kind:"command",run:"node lifecycle demote --pane {pane}"}},"crtr.tmux.menu.make-resident":{description:"make resident (interactable)",action:{kind:"command",run:"node config --lifecycle resident --pane {pane}"}},"crtr.tmux.menu.detach":{description:"demote + close viewer",action:{kind:"command",run:"node lifecycle demote --pane {pane} --detach"}},"crtr.tmux.menu.close-subtree":{description:"close agent + subtree",action:{kind:"command",run:"node lifecycle close --pane {pane}"}},"crtr.tmux.menu.background-bash":{description:"background running bash",action:{kind:"direct",run:"node bash background --pane {pane}"}},"crtr.tmux.menu.file-review":{description:"review a file",action:{kind:"raw-keys",keys:"M-S-r"}},"crtr.tmux.menu.metadata":{description:"metadata",action:{kind:"keys",keys:"/node-metadata"}},"crtr.tmux.menu.fold-tools":{description:"fold finished tool calls",action:{kind:"keys",keys:"/fold-tools"}},"crtr.tmux.menu.context":{description:"context + reports",action:{kind:"keys",keys:"/context"}},"crtr.tmux.menu.providers":{description:"settings",action:{kind:"popup",run:"sys settings",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.provider-options":{description:"provider options",action:{kind:"popup",run:"sys settings --page provider-options",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.plugins":{description:"plugins",action:{kind:"popup",run:"pkg browse",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.context-admin":{description:"context surface",action:{kind:"popup",run:"sys context admin",size:{w:"98%",h:"96%"}}},"crtr.tmux.menu.graph":{description:"canvas graph",action:{kind:"keys",keys:"/graph"}},"crtr.tmux.menu.focus-manager":{description:"go to manager",action:{kind:"command",run:"surface node focus {manager}"}},"crtr.tmux.menu.copy-id":{description:"copy node id",action:{kind:"command",run:"surface node id --pane {pane}"}},"crtr.tmux.menu.reload-viewer":{description:"reload viewer",action:{kind:"direct",run:"surface reload --pane {pane}"}},"crtr.tmux.menu.recap":{description:"generate recap",action:{kind:"keys",keys:"/recap"}},"crtr.tmux.menu.pin":{description:"pin conversation",action:{kind:"direct",run:"surface node pin --pane {pane}"}},"crtr.tmux.menu.issue.idea":{description:"idea",action:{kind:"popup",run:"canvas issue new --type idea"}},"crtr.tmux.menu.issue.bug":{description:"bug",action:{kind:"popup",run:"canvas issue new --type bug"}}};function b(e){return e.replace(/#/g,"##")}u(b,"escapeTmuxFormats");function se(e){return e.map(h).join(" ")}u(se,"tmuxCommand");const ue={w:"60%",h:"50%"};function U(e,n=!1,t=ue){const r=`crtr canvas chord --pane '#{pane_id}' --run ${h(b(e))}${n?" --interactive":""}`;return n?{argv:["display-popup","-E","-w",t.w,"-h",t.h,"-d","#{pane_current_path}",r],menu:`display-popup -E -w ${t.w} -h ${t.h} -d "#{pane_current_path}" ${h(r)}`}:{argv:["run-shell",`${r} >/dev/null 2>&1`],menu:`run-shell ${h(`${r} >/dev/null 2>&1`)}`}}u(U,"chordCommand");function ce(e){const t=`crtr ${b(e).replace("{pane}","#{pane_id}")} >/dev/null 2>&1`;return{argv:["run-shell","-b",t],menu:`run-shell -b ${h(t)}`}}u(ce,"directCommand");function q(e){switch(e.kind){case"disabled":return null;case"separator":return null;case"dismiss":return{argv:["refresh-client"],menu:"refresh-client"};case"keys":{const n=b(e.keys);return{argv:["send-keys",n,"Enter"],menu:`send-keys -t '#{pane_id}' ${h(n)} Enter`}}case"raw-keys":{const n=b(e.keys);return{argv:["send-keys",n],menu:`send-keys -t '#{pane_id}' ${h(n)}`}}case"literal-input":{const n=b(e.input);return{argv:["send-keys","-l",n],menu:`send-keys -l -t '#{pane_id}' ${h(n)}`}}case"command":return U(e.run);case"direct":return ce(e.run);case"popup":return U(e.run,!0,e.size);case"submenu":{const n=G(e.title,e.items);return{argv:n,menu:se(n)}}}}u(q,"menuActionCommand");function ae(e){return q(e)?.menu??""}u(ae,"renderMenuAction");function de(e){return e.replace(/#\[[^\]]*\]/g,"").length}u(de,"menuItemWidth");function G(e,n){const t=b(e),r=n.reduce((o,c)=>Math.max(o,de(c.description)),0),s=["display-menu","-T",`#[align=centre]${t}`,...ie()];s.push("-x",`#{e|-:#{pane_right},${Math.max(t.length,r)+7}}`,"-y","#{e|+:#{pane_top},3}","--");for(const o of n){if(o.action.kind==="separator"){s.push("");continue}const c=o.action.kind==="disabled"?o.description:b(o.description);s.push(c,o.selector,ae(o.action))}return s.push("","-esc / q to close","",""),s}u(G,"buildMenuArgs");const me={enter:"Enter",escape:"Escape",tab:"Tab",backspace:"BSpace",delete:"DC",space:"Space",up:"Up",down:"Down",left:"Left",right:"Right",pageup:"PPage",pagedown:"NPage",home:"Home",end:"End"};function j(e){if(e==="+")return{key:"+",modifiers:[]};if(e.endsWith("++"))return{key:"+",modifiers:e.slice(0,-2).split("+")};const n=e.split("+");return{key:n.pop(),modifiers:n}}u(j,"normalizedStrokeParts");function pe(e){return v(e)[0]}u(pe,"tmuxKey");function v(e){let{key:n,modifiers:t}=j(e);const r=new Set(t),s=u((o,c)=>[r.has("ctrl")?"C-":"",r.has("alt")?"M-":"",c?"S-":"",me[o]??o].join(""),"name");if(r.has("shift")&&n.length===1&&/[a-z]/.test(n)){const o=n.toUpperCase();return!r.has("ctrl")&&!r.has("alt")?[s(o,!1)]:[s(o,!0),s(o,!1),s(n,!0)]}return[s(n,r.has("shift"))]}u(v,"tmuxKeyNames");function le(e){const{key:n,modifiers:t}=j(e);return t.includes("shift")&&/[a-z]/.test(n)?n.toUpperCase():n==="space"?" ":n}u(le,"menuSelector");function T(e,n,t){const r=[];for(const s of e){const o=n.get(s);if(o!==void 0)for(const c of t.gestures(s))r.push({description:o.description,selector:le(c),action:o.action})}return r}u(T,"boundMenuItems");function fe(e){const n=new Map;for(const[c,l]of Object.entries(oe))l!==void 0&&n.set(c,l);for(const{menuId:c,actionId:l}of O){const x=_.find(w=>w.id===l);if(x===void 0)throw new Error(`missing attach binding definition ${l}`);n.set(c,{description:x.name.toLowerCase(),action:{kind:"literal-input",input:Z(l)}})}const t=T(O.map(({menuId:c})=>c),n,e);t.length>0&&n.set("crtr.tmux.menu.attach",{description:"attach viewer \u203A",action:{kind:"submenu",title:" attach viewer ",items:t}});const r=T(["crtr.tmux.menu.metadata","crtr.tmux.menu.context"],n,e);n.set("crtr.tmux.menu.show",{description:"inspect \u203A",action:{kind:"submenu",title:" inspect node ",items:r}});const s=T(["crtr.tmux.menu.fold-tools"],n,e);n.set("crtr.tmux.menu.view-settings",{description:"display \u203A",action:{kind:"submenu",title:" display ",items:s}});const o=T(["crtr.tmux.menu.issue.idea","crtr.tmux.menu.issue.bug"],n,e);return n.set("crtr.tmux.menu.issues",{description:"create \u203A",action:{kind:"submenu",title:" create ",items:o}}),n}u(fe,"resolvedMenuActions");function ge(e,n){const t=u(c=>T(c,n,e),"boundItems"),r=[],s=u((c,l)=>{l.length!==0&&(r.length>0&&r.push({description:"",selector:"",action:{kind:"separator"}}),r.push({description:`-#[bold]${c}`,selector:"",action:{kind:"disabled"}},...l))},"addGroup");s("Explore",t(["crtr.tmux.menu.resume","crtr.tmux.menu.graph","crtr.tmux.menu.focus-manager","crtr.tmux.menu.show","crtr.tmux.menu.view-settings"])),s("Current node",t(["crtr.tmux.menu.attach","crtr.tmux.menu.background-bash","crtr.tmux.menu.file-review","crtr.tmux.menu.pin","crtr.tmux.menu.copy-id","crtr.tmux.menu.reload-viewer","crtr.tmux.menu.recap"])),s("Lifecycle",t(["crtr.tmux.menu.fork","crtr.tmux.menu.promote","crtr.tmux.menu.demote-mode","crtr.tmux.menu.demote","crtr.tmux.menu.make-resident","crtr.tmux.menu.detach","crtr.tmux.menu.close-subtree"])),s("System",t(["crtr.tmux.menu.providers","crtr.tmux.menu.provider-options","crtr.tmux.menu.plugins","crtr.tmux.menu.context-admin","crtr.tmux.menu.issues"]));const o=e.gestures("crtr.tmux.menu.open");if(o.length>0&&r.length>0){r.push({description:"",selector:"",action:{kind:"separator"}});for(const c of o)r.push({description:`${V(c)} to close`,selector:pe(c),action:{kind:"dismiss"}})}return r}u(ge,"menuItems");function S(e,n){let t=n;for(;t<e.length&&/\s/.test(e[t]);)t+=1;if(t>=e.length)return null;let r=null,s="";for(;t<e.length;){const o=e[t];if(r===null&&/\s/.test(o))break;if(r===null&&(o==="'"||o==='"')){r=o,t+=1;continue}if(r===o){r=null,t+=1;continue}if(o==="\\"&&r!=="'"&&t+1<e.length){s+=e[t+1],t+=2;continue}s+=o,t+=1}return{value:s,end:t}}u(S,"readTmuxToken");function N(e){const n=S(e,0);if(n?.value!=="bind-key")return null;let t=n.end,r=!1;for(;;){const s=S(e,t);if(s===null)return null;if(t=s.end,s.value==="-r"){r=!0;continue}if(s.value!=="-T")continue;const o=S(e,t);if(o===null)return null;const c=S(e,o.end);return c===null?null:{table:o.value,key:c.value,command:e.slice(c.end).trimStart(),repeat:r}}}u(N,"parseTmuxBinding");function $(e,n){const t=f(["list-keys","-T",e]);return t.ok?t.stdout.split(`
|
|
1
|
+
var X=Object.defineProperty;var u=(e,n)=>X(e,"name",{value:n,configurable:!0});import{mkdtempSync as H,rmSync as J,writeFileSync as Q}from"node:fs";import{tmpdir as D}from"node:os";import{join as M}from"node:path";import{ATTACH_CONTROL_BINDINGS as O,BINDING_CATALOG as _,BINDING_IDS as Y,encodeAttachControlInput as Z,formatGesture as V,isAttachPaneBinding as ee,resolveUserKeybindingSettings as ne}from"../keybindings/index.js";import{normalizeTmuxPassthrough as te}from"../config.js";import{withExclusiveDirectoryLock as re}from"../exclusive-lock.js";import{surfaceTmuxStyleArgs as ie}from"./surface-bg.js";import{runTmux as f,shellQuote as h}from"./tmux-driver.js";const A="@crtr_keybindings_manifest",p="root",oe={"crtr.tmux.menu.promote":{description:"promote to orchestrator",action:{kind:"keys",keys:"/promote"}},"crtr.tmux.menu.resume":{description:"find node",action:{kind:"keys",keys:"/resume"}},"crtr.tmux.menu.fork":{description:"fork into idle root",action:{kind:"direct",run:"node fork --pane {pane}"}},"crtr.tmux.menu.demote-mode":{description:"demote to base node",action:{kind:"command",run:"node config --mode base --pane {pane}"}},"crtr.tmux.menu.demote":{description:"demote to terminal (finish when done)",action:{kind:"command",run:"node lifecycle demote --pane {pane}"}},"crtr.tmux.menu.make-resident":{description:"make resident (interactable)",action:{kind:"command",run:"node config --lifecycle resident --pane {pane}"}},"crtr.tmux.menu.detach":{description:"demote + close viewer",action:{kind:"command",run:"node lifecycle demote --pane {pane} --detach"}},"crtr.tmux.menu.close-subtree":{description:"close agent + subtree",action:{kind:"command",run:"node lifecycle close --pane {pane}"}},"crtr.tmux.menu.background-bash":{description:"background running bash",action:{kind:"direct",run:"node bash background --pane {pane}"}},"crtr.tmux.menu.file-review":{description:"review a file",action:{kind:"raw-keys",keys:"M-S-r"}},"crtr.tmux.menu.metadata":{description:"metadata",action:{kind:"keys",keys:"/node-metadata"}},"crtr.tmux.menu.fold-tools":{description:"fold finished tool calls",action:{kind:"keys",keys:"/fold-tools"}},"crtr.tmux.menu.context":{description:"context + reports",action:{kind:"keys",keys:"/context"}},"crtr.tmux.menu.providers":{description:"settings",action:{kind:"popup",run:"sys settings",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.provider-options":{description:"provider options",action:{kind:"popup",run:"sys settings --page provider-options",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.plugins":{description:"plugins",action:{kind:"popup",run:"pkg browse",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.analytics":{description:"analytics",action:{kind:"popup",run:"canvas analytics --pane {pane}",size:{w:"90%",h:"85%"}}},"crtr.tmux.menu.context-admin":{description:"context surface",action:{kind:"popup",run:"sys context admin",size:{w:"98%",h:"96%"}}},"crtr.tmux.menu.graph":{description:"canvas graph",action:{kind:"keys",keys:"/graph"}},"crtr.tmux.menu.focus-manager":{description:"go to manager",action:{kind:"command",run:"surface node focus {manager}"}},"crtr.tmux.menu.copy-id":{description:"copy node id",action:{kind:"command",run:"surface node id --pane {pane}"}},"crtr.tmux.menu.reload-viewer":{description:"reload viewer",action:{kind:"direct",run:"surface reload --pane {pane}"}},"crtr.tmux.menu.recap":{description:"generate recap",action:{kind:"keys",keys:"/recap"}},"crtr.tmux.menu.pin":{description:"pin conversation",action:{kind:"direct",run:"surface node pin --pane {pane}"}},"crtr.tmux.menu.issue.idea":{description:"idea",action:{kind:"popup",run:"canvas issue new --type idea"}},"crtr.tmux.menu.issue.bug":{description:"bug",action:{kind:"popup",run:"canvas issue new --type bug"}}};function b(e){return e.replace(/#/g,"##")}u(b,"escapeTmuxFormats");function se(e){return e.map(h).join(" ")}u(se,"tmuxCommand");const ue={w:"60%",h:"50%"};function U(e,n=!1,t=ue){const r=`crtr canvas chord --pane '#{pane_id}' --run ${h(b(e))}${n?" --interactive":""}`;return n?{argv:["display-popup","-E","-w",t.w,"-h",t.h,"-d","#{pane_current_path}",r],menu:`display-popup -E -w ${t.w} -h ${t.h} -d "#{pane_current_path}" ${h(r)}`}:{argv:["run-shell",`${r} >/dev/null 2>&1`],menu:`run-shell ${h(`${r} >/dev/null 2>&1`)}`}}u(U,"chordCommand");function ce(e){const t=`crtr ${b(e).replace("{pane}","#{pane_id}")} >/dev/null 2>&1`;return{argv:["run-shell","-b",t],menu:`run-shell -b ${h(t)}`}}u(ce,"directCommand");function q(e){switch(e.kind){case"disabled":return null;case"separator":return null;case"dismiss":return{argv:["refresh-client"],menu:"refresh-client"};case"keys":{const n=b(e.keys);return{argv:["send-keys",n,"Enter"],menu:`send-keys -t '#{pane_id}' ${h(n)} Enter`}}case"raw-keys":{const n=b(e.keys);return{argv:["send-keys",n],menu:`send-keys -t '#{pane_id}' ${h(n)}`}}case"literal-input":{const n=b(e.input);return{argv:["send-keys","-l",n],menu:`send-keys -l -t '#{pane_id}' ${h(n)}`}}case"command":return U(e.run);case"direct":return ce(e.run);case"popup":return U(e.run,!0,e.size);case"submenu":{const n=G(e.title,e.items);return{argv:n,menu:se(n)}}}}u(q,"menuActionCommand");function ae(e){return q(e)?.menu??""}u(ae,"renderMenuAction");function de(e){return e.replace(/#\[[^\]]*\]/g,"").length}u(de,"menuItemWidth");function G(e,n){const t=b(e),r=n.reduce((o,c)=>Math.max(o,de(c.description)),0),s=["display-menu","-T",`#[align=centre]${t}`,...ie()];s.push("-x",`#{e|-:#{pane_right},${Math.max(t.length,r)+7}}`,"-y","#{e|+:#{pane_top},3}","--");for(const o of n){if(o.action.kind==="separator"){s.push("");continue}const c=o.action.kind==="disabled"?o.description:b(o.description);s.push(c,o.selector,ae(o.action))}return s.push("","-esc / q to close","",""),s}u(G,"buildMenuArgs");const me={enter:"Enter",escape:"Escape",tab:"Tab",backspace:"BSpace",delete:"DC",space:"Space",up:"Up",down:"Down",left:"Left",right:"Right",pageup:"PPage",pagedown:"NPage",home:"Home",end:"End"};function j(e){if(e==="+")return{key:"+",modifiers:[]};if(e.endsWith("++"))return{key:"+",modifiers:e.slice(0,-2).split("+")};const n=e.split("+");return{key:n.pop(),modifiers:n}}u(j,"normalizedStrokeParts");function pe(e){return v(e)[0]}u(pe,"tmuxKey");function v(e){let{key:n,modifiers:t}=j(e);const r=new Set(t),s=u((o,c)=>[r.has("ctrl")?"C-":"",r.has("alt")?"M-":"",c?"S-":"",me[o]??o].join(""),"name");if(r.has("shift")&&n.length===1&&/[a-z]/.test(n)){const o=n.toUpperCase();return!r.has("ctrl")&&!r.has("alt")?[s(o,!1)]:[s(o,!0),s(o,!1),s(n,!0)]}return[s(n,r.has("shift"))]}u(v,"tmuxKeyNames");function le(e){const{key:n,modifiers:t}=j(e);return t.includes("shift")&&/[a-z]/.test(n)?n.toUpperCase():n==="space"?" ":n}u(le,"menuSelector");function T(e,n,t){const r=[];for(const s of e){const o=n.get(s);if(o!==void 0)for(const c of t.gestures(s))r.push({description:o.description,selector:le(c),action:o.action})}return r}u(T,"boundMenuItems");function fe(e){const n=new Map;for(const[c,l]of Object.entries(oe))l!==void 0&&n.set(c,l);for(const{menuId:c,actionId:l}of O){const x=_.find(w=>w.id===l);if(x===void 0)throw new Error(`missing attach binding definition ${l}`);n.set(c,{description:x.name.toLowerCase(),action:{kind:"literal-input",input:Z(l)}})}const t=T(O.map(({menuId:c})=>c),n,e);t.length>0&&n.set("crtr.tmux.menu.attach",{description:"attach viewer \u203A",action:{kind:"submenu",title:" attach viewer ",items:t}});const r=T(["crtr.tmux.menu.metadata","crtr.tmux.menu.context"],n,e);n.set("crtr.tmux.menu.show",{description:"inspect \u203A",action:{kind:"submenu",title:" inspect node ",items:r}});const s=T(["crtr.tmux.menu.fold-tools"],n,e);n.set("crtr.tmux.menu.view-settings",{description:"display \u203A",action:{kind:"submenu",title:" display ",items:s}});const o=T(["crtr.tmux.menu.issue.idea","crtr.tmux.menu.issue.bug"],n,e);return n.set("crtr.tmux.menu.issues",{description:"create \u203A",action:{kind:"submenu",title:" create ",items:o}}),n}u(fe,"resolvedMenuActions");function ge(e,n){const t=u(c=>T(c,n,e),"boundItems"),r=[],s=u((c,l)=>{l.length!==0&&(r.length>0&&r.push({description:"",selector:"",action:{kind:"separator"}}),r.push({description:`-#[bold]${c}`,selector:"",action:{kind:"disabled"}},...l))},"addGroup");s("Explore",t(["crtr.tmux.menu.resume","crtr.tmux.menu.graph","crtr.tmux.menu.focus-manager","crtr.tmux.menu.show","crtr.tmux.menu.view-settings"])),s("Current node",t(["crtr.tmux.menu.attach","crtr.tmux.menu.background-bash","crtr.tmux.menu.file-review","crtr.tmux.menu.pin","crtr.tmux.menu.copy-id","crtr.tmux.menu.reload-viewer","crtr.tmux.menu.recap"])),s("Lifecycle",t(["crtr.tmux.menu.fork","crtr.tmux.menu.promote","crtr.tmux.menu.demote-mode","crtr.tmux.menu.demote","crtr.tmux.menu.make-resident","crtr.tmux.menu.detach","crtr.tmux.menu.close-subtree"])),s("System",t(["crtr.tmux.menu.providers","crtr.tmux.menu.provider-options","crtr.tmux.menu.plugins","crtr.tmux.menu.analytics","crtr.tmux.menu.context-admin","crtr.tmux.menu.issues"]));const o=e.gestures("crtr.tmux.menu.open");if(o.length>0&&r.length>0){r.push({description:"",selector:"",action:{kind:"separator"}});for(const c of o)r.push({description:`${V(c)} to close`,selector:pe(c),action:{kind:"dismiss"}})}return r}u(ge,"menuItems");function S(e,n){let t=n;for(;t<e.length&&/\s/.test(e[t]);)t+=1;if(t>=e.length)return null;let r=null,s="";for(;t<e.length;){const o=e[t];if(r===null&&/\s/.test(o))break;if(r===null&&(o==="'"||o==='"')){r=o,t+=1;continue}if(r===o){r=null,t+=1;continue}if(o==="\\"&&r!=="'"&&t+1<e.length){s+=e[t+1],t+=2;continue}s+=o,t+=1}return{value:s,end:t}}u(S,"readTmuxToken");function N(e){const n=S(e,0);if(n?.value!=="bind-key")return null;let t=n.end,r=!1;for(;;){const s=S(e,t);if(s===null)return null;if(t=s.end,s.value==="-r"){r=!0;continue}if(s.value!=="-T")continue;const o=S(e,t);if(o===null)return null;const c=S(e,o.end);return c===null?null:{table:o.value,key:c.value,command:e.slice(c.end).trimStart(),repeat:r}}}u(N,"parseTmuxBinding");function $(e,n){const t=f(["list-keys","-T",e]);return t.ok?t.stdout.split(`
|
|
2
2
|
`).find(r=>{const s=N(r);return s?.table===e&&s.key===n})??null:null}u($,"bindingAt");function Pe(e){const n=f(["list-keys","-T",p]);if(!n.ok)return[];const t=new Set(n.stdout.split(`
|
|
3
|
-
`).flatMap(r=>{const s=N(r);return s?.table===p?[s.key]:[]}));return e.filter(r=>!r.includes(" > ")&&v(r).some(s=>t.has(s)))}u(Pe,"occupiedTmuxRootGestures");function
|
|
4
|
-
`,"utf8"),f(["source-file",t])}finally{J(n,{recursive:!0,force:!0})}}u(be,"sourceBindingLine");function K(e){return e.original===null?f(["unbind-key","-T",p,C(e.key)]):be(e.original)}u(K,"restoreWrappedBinding");function we(){return["run-shell","-b",'crtr surface inbox --quiet --tmux-socket "#{socket_path}" --tmux-client "#{client_name}" --target-pane "#{pane_id}"']}u(we,"inboxToggleTmuxCommand");function ve(e){switch(e){case"crtr.tmux.node.next":return["run-shell","crtr surface node cycle --dir next --pane '#{pane_id}' >/dev/null 2>&1"];case"crtr.tmux.node.previous":return["run-shell","crtr surface node cycle --dir prev --pane '#{pane_id}' >/dev/null 2>&1"];case"crtr.tmux.inbox.toggle":return we();default:throw new Error(`no tmux command for ${e}`)}}u(ve,"actionCommand");function $e(){const e=process.env.TMUX?.split(",")[0]?.trim();if(e!==void 0&&e!=="")return`${e}.crtr-keybindings.lock`;const n=f(["display-message","-p","#{socket_path}"]);if(n.ok&&n.stdout!=="")return`${n.stdout}.crtr-keybindings.lock`;const t=typeof process.getuid=="function"?process.getuid():"user";return M(D(),`crtr-tmux-keybindings-${t}.lock`)}u($e,"tmuxBindingLockPath");function Le(e,n=[]){return re($e(),()=>Ie(e,n))}u(Le,"installTmuxBindings");function Ie(e,n=[]){const t=e===void 0?ne():void 0,r=e??t.bindings,s=e===void 0?t.tmuxPassthrough:te(n),o=[],c=[],l=he();if(l===null)return o.push({code:"tmux-error",message:`tmux is unavailable or ${A} is malformed`}),{ok:!1,installed:c,diagnostics:o};const x=new Map;for(const i of s){const a=_.find(d=>d.id===i);if(!(a===void 0||!ee(a))){for(const d of r.gestures(i))if(!d.includes(" > "))for(const m of v(d))x.has(m)||x.set(m,{bindingId:i,gesture:d})}}const w=new Set,I=[];for(const i of l.wrappers){const a=x.get(i.key),d=$(p,i.key);if(d!==null&&d===i.original)continue;if(i.state==="relinquished"||d!==i.wrapper){w.add(i.key),a!==void 0&&I.push({...i,...a,state:"relinquished"});continue}const m=K(i);m.ok||(w.add(i.key),I.push(i),o.push({code:"tmux-error",bindingId:i.bindingId,gesture:i.gesture,message:`could not restore tmux binding ${p}:${i.key}: ${m.stderr}`}))}for(const i of l.pairs){if(i.table===p&&w.has(i.key))continue;const a=f(["unbind-key","-T",i.table,C(i.key)]);!a.ok&&$(i.table,i.key)!==null&&o.push({code:"tmux-error",message:`could not remove crouter binding ${i.table}:${i.key}: ${a.stderr}`})}if(o.some(i=>i.code==="tmux-error")){const i=
|
|
3
|
+
`).flatMap(r=>{const s=N(r);return s?.table===p?[s.key]:[]}));return e.filter(r=>!r.includes(" > ")&&v(r).some(s=>t.has(s)))}u(Pe,"occupiedTmuxRootGestures");function z(e){return typeof e=="object"&&e!==null&&typeof e.table=="string"&&typeof e.key=="string"}u(z,"isInstalledPair");function ke(e){if(typeof e!="object"||e===null)return!1;const n=e;return typeof n.bindingId=="string"&&Y.has(n.bindingId)&&typeof n.gesture=="string"&&typeof n.key=="string"&&(typeof n.original=="string"||n.original===null)&&typeof n.wrapper=="string"&&(n.state==="owned"||n.state==="relinquished")}u(ke,"isWrappedRootBinding");function he(){const e=f(["show-options","-s","-q",A]);if(!e.ok)return null;if(e.stdout==="")return{pairs:[],wrappers:[]};const n=f(["show-options","-s","-qv",A]);if(!n.ok)return null;try{const t=JSON.parse(n.stdout);if(Array.isArray(t))return t.every(z)?{pairs:t,wrappers:[]}:null;if(typeof t!="object"||t===null)return null;const r=t;return!Array.isArray(r.pairs)||!r.pairs.every(z)||!Array.isArray(r.wrappers)||!r.wrappers.every(ke)?null:{pairs:r.pairs,wrappers:r.wrappers}}catch{return null}}u(he,"readManifest");function F(e){return f(["set-option","-s",A,JSON.stringify(e)])}u(F,"writeManifest");function C(e){return e.replace(/\\/g,"\\\\").replace(/;/g,"\\;")}u(C,"tmuxKeyArgument");function xe(e){return`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/;/g,"\\;")}"`}u(xe,"tmuxCommandToken");function ye(e){let n=null,t="";for(let r=0;r<e.length;r+=1){const s=e[r];if(n===null&&(s==="'"||s==='"')){n=s,t+=s;continue}if(n===s){n=null,t+=s;continue}if(s==="\\"&&r+1<e.length){const o=e[r+1];n===null&&o===";"?t+=";":t+=s+o,r+=1;continue}t+=s}return t}u(ye,"bindingCommandForBranch");function be(e){const n=H(M(D(),"crtr-tmux-binding-")),t=M(n,"binding.conf");try{return Q(t,`${e}
|
|
4
|
+
`,"utf8"),f(["source-file",t])}finally{J(n,{recursive:!0,force:!0})}}u(be,"sourceBindingLine");function K(e){return e.original===null?f(["unbind-key","-T",p,C(e.key)]):be(e.original)}u(K,"restoreWrappedBinding");function we(){return["run-shell","-b",'crtr surface inbox --quiet --tmux-socket "#{socket_path}" --tmux-client "#{client_name}" --target-pane "#{pane_id}"']}u(we,"inboxToggleTmuxCommand");function ve(e){switch(e){case"crtr.tmux.node.next":return["run-shell","crtr surface node cycle --dir next --pane '#{pane_id}' >/dev/null 2>&1"];case"crtr.tmux.node.previous":return["run-shell","crtr surface node cycle --dir prev --pane '#{pane_id}' >/dev/null 2>&1"];case"crtr.tmux.inbox.toggle":return we();default:throw new Error(`no tmux command for ${e}`)}}u(ve,"actionCommand");function $e(){const e=process.env.TMUX?.split(",")[0]?.trim();if(e!==void 0&&e!=="")return`${e}.crtr-keybindings.lock`;const n=f(["display-message","-p","#{socket_path}"]);if(n.ok&&n.stdout!=="")return`${n.stdout}.crtr-keybindings.lock`;const t=typeof process.getuid=="function"?process.getuid():"user";return M(D(),`crtr-tmux-keybindings-${t}.lock`)}u($e,"tmuxBindingLockPath");function Le(e,n=[]){return re($e(),()=>Ie(e,n))}u(Le,"installTmuxBindings");function Ie(e,n=[]){const t=e===void 0?ne():void 0,r=e??t.bindings,s=e===void 0?t.tmuxPassthrough:te(n),o=[],c=[],l=he();if(l===null)return o.push({code:"tmux-error",message:`tmux is unavailable or ${A} is malformed`}),{ok:!1,installed:c,diagnostics:o};const x=new Map;for(const i of s){const a=_.find(d=>d.id===i);if(!(a===void 0||!ee(a))){for(const d of r.gestures(i))if(!d.includes(" > "))for(const m of v(d))x.has(m)||x.set(m,{bindingId:i,gesture:d})}}const w=new Set,I=[];for(const i of l.wrappers){const a=x.get(i.key),d=$(p,i.key);if(d!==null&&d===i.original)continue;if(i.state==="relinquished"||d!==i.wrapper){w.add(i.key),a!==void 0&&I.push({...i,...a,state:"relinquished"});continue}const m=K(i);m.ok||(w.add(i.key),I.push(i),o.push({code:"tmux-error",bindingId:i.bindingId,gesture:i.gesture,message:`could not restore tmux binding ${p}:${i.key}: ${m.stderr}`}))}for(const i of l.pairs){if(i.table===p&&w.has(i.key))continue;const a=f(["unbind-key","-T",i.table,C(i.key)]);!a.ok&&$(i.table,i.key)!==null&&o.push({code:"tmux-error",message:`could not remove crouter binding ${i.table}:${i.key}: ${a.stderr}`})}if(o.some(i=>i.code==="tmux-error")){const i=F({pairs:l.pairs,wrappers:I});return i.ok||o.push({code:"tmux-error",message:`could not save crouter tmux ownership manifest: ${i.stderr}`}),{ok:!1,installed:c,diagnostics:o}}const E=u((i,a,d,m,k)=>{if($(i,a)!==null)return o.push({code:"occupied",bindingId:m,gesture:k,message:`${i}:${a} is already bound by tmux; ${m} was not installed`}),!1;const g=f(["bind-key","-T",i,C(a),...d]);return g.ok?(c.push({table:i,key:a}),!0):(o.push({code:"tmux-error",bindingId:m,gesture:k,message:`could not install ${m}: ${g.stderr}`}),!1)},"install"),B=fe(r),R=G(" crtr ",ge(r,B));for(const i of r.gestures("crtr.tmux.menu.open"))for(const a of v(i))E(p,a,R,"crtr.tmux.menu.open",i);for(const i of _){if(i.pair?.field!=="menu")continue;const a=_.find(y=>y.id===i.pair?.pairedId);if(a?.pair?.field!=="global")continue;const d=i.id,m=a.id,k=B.get(d),g=k===void 0?null:q(k.action);if(g===null)throw new Error(`no direct tmux action for paired menu binding ${d}`);for(const y of r.gestures(m))for(const W of v(y))E(p,W,g.argv,m,y)}for(const i of["crtr.tmux.node.next","crtr.tmux.node.previous","crtr.tmux.inbox.toggle"])for(const a of r.gestures(i))for(const d of v(a))E(p,d,ve(i),i,a);const P=[];for(const[i,a]of x){if(w.has(i))continue;const d=$(p,i);if(d===null)continue;const m=N(d);if(m===null||m.command===""){o.push({code:"tmux-error",bindingId:a.bindingId,gesture:a.gesture,message:`could not parse occupied tmux binding ${p}:${i}`});continue}const k=f(["bind-key",...m.repeat?["-r"]:[],"-T",p,C(i),"if-shell","-F","#{!=:#{@crtr_attach},}",`send-keys ${xe(i)}`,ye(m.command)]);if(!k.ok){o.push({code:"tmux-error",bindingId:a.bindingId,gesture:a.gesture,message:`could not wrap ${p}:${i}: ${k.stderr}`});continue}const g=$(p,i);if(g===null||!g.includes("@crtr_attach")){o.push({code:"tmux-error",bindingId:a.bindingId,gesture:a.gesture,message:`could not fingerprint wrapped tmux binding ${p}:${i}`});continue}const y={...a,key:i,original:d,wrapper:g,state:"owned"};I.push(y),P.push(y)}const L=F({pairs:c,wrappers:I});if(!L.ok){o.push({code:"tmux-error",message:`could not save crouter tmux ownership manifest: ${L.stderr}`});for(const i of P)$(p,i.key)===i.wrapper&&K(i)}return{ok:o.every(i=>i.code!=="tmux-error"),installed:c,diagnostics:o}}u(Ie,"reconcileTmuxBindings");export{we as inboxToggleTmuxCommand,Le as installTmuxBindings,Pe as occupiedTmuxRootGestures};
|
|
@@ -238,6 +238,10 @@ export declare function respawnPaneSync(opts: RespawnPaneOpts): boolean;
|
|
|
238
238
|
* process long enough to run the respawn. The returned status only confirms
|
|
239
239
|
* tmux accepted the queued command. */
|
|
240
240
|
export declare function respawnPaneInBackground(opts: RespawnPaneOpts): boolean;
|
|
241
|
+
/** Run a shell command from the tmux server (`run-shell -b`), outside the
|
|
242
|
+
* caller's process tree, so it outlives the caller's pane or popup. The returned
|
|
243
|
+
* status only confirms tmux accepted the command. */
|
|
244
|
+
export declare function runShellInBackground(command: string): boolean;
|
|
241
245
|
/** The command line a pane was originally started with (`#{pane_start_command}`)
|
|
242
246
|
* — the exact command `respawn-pane` with no argument re-runs. undefined when
|
|
243
247
|
* tmux is unreachable or the pane is gone. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)){const s=e.indexOf(" ");if(!(s<0)&&e.slice(s+1)===n){const u=e.slice(0,s);if(u!=="")return u}}return null}r(
|
|
3
|
-
`).filter(t=>t!=="")):null}r(
|
|
4
|
-
`).filter(t=>t!==""))}r(
|
|
5
|
-
`)){const u=/^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(s);if(u===null)continue;const i=Number(u[1]),
|
|
6
|
-
`)){const[i,
|
|
7
|
-
`).filter(e=>e!=="")}r(
|
|
1
|
+
var I=Object.defineProperty;var r=(n,t)=>I(n,"name",{value:t,configurable:!0});import{execFile as g,spawnSync as p}from"node:child_process";import{encodeAttachControlInput as O}from"../keybindings/index.js";import{bundledPiCommandForShell as E}from"./pi-cli.js";import{shellQuote as l}from"../../shared/shell-quote.js";import{envPiBinaryOverride as N}from"../../shared/env.js";function o(n){const t=p("tmux",n,{encoding:"utf8"});return{ok:t.status===0,stdout:(t.stdout??"").trim(),stderr:(t.stderr??"").trim()}}r(o,"tmux");function d(n,t){return o(n===void 0||n===""?t:["-S",n,...t])}r(d,"tmuxOnSocket");function $(){return process.env.TMUX!==void 0&&process.env.TMUX!==""}r($,"inTmux");function K(){return p("tmux",["list-sessions"],{encoding:"utf8",stdio:"ignore"}).status===0}r(K,"tmuxSessionsReachable");function G(){return p("tmux",["list-clients","-F","#{client_name}"],{encoding:"utf8"}).status===0}r(G,"tmuxClientsReachable");function J(n){if(n==="")return null;const t=o(["list-panes","-a","-F","#{pane_id} #{@crtr_node}"]);if(!t.ok)return null;for(const e of t.stdout.split(`
|
|
2
|
+
`)){const s=e.indexOf(" ");if(!(s<0)&&e.slice(s+1)===n){const u=e.slice(0,s);if(u!=="")return u}}return null}r(J,"paneOfNode");function C(){if(!$())return null;const n=o(["display-message","-p","#{session_name} #{window_id} #{pane_id}"]);if(!n.ok)return null;const[t,e,s]=n.stdout.split(" ");return{session:t,window:e,pane:s}}r(C,"currentTmux");function M(n){return o(["has-session","-t",n]).ok}r(M,"sessionExists");function F(){const n=o(["show-options","-s","terminal-overrides"]).stdout;/Enbp=\\+E/.test(n)||o(["set-option","-sga","terminal-overrides","*:Enbp=\\E[?2004h:Dsbp=\\E[?2004l"])}r(F,"ensureBracketedPaste");function T(){F(),o(["set-option","-s","focus-events","on"])}r(T,"ensureServerOptions");function Y(n,t){M(n)||o(["new-session","-d","-s",n,"-c",t]),T()}r(Y,"ensureSession");function w(n){const t=[];for(const[e,s]of Object.entries(n))t.push("-e",`${e}=${s}`);return t}r(w,"envFlags");function Z(n){const t=o(["new-window","-d","-a","-P","-F","#{window_id} #{pane_id}","-t",`${n.session}:`,"-n",n.name,"-c",n.cwd,...w(n.env),n.command]);if(!t.ok)return null;const[e,s]=t.stdout.split(" ");return e===void 0||e===""||s===void 0||s===""?null:{window:e,pane:s}}r(Z,"openNodeWindow");function nn(n,t){const e=o(["split-window","-d",...t.vertical===!0?[]:["-h"],...t.before===!0?["-b"]:[],...t.size!==void 0?["-l",String(t.size)]:[],"-P","-F","#{pane_id}","-t",n,"-c",t.cwd,...w(t.env),t.command]);return e.ok&&e.stdout!==""?e.stdout:null}r(nn,"splitWindow");function tn(n,t){return!(C()?.session===n)&&!o(["switch-client","-t",n]).ok?!1:o(["select-window","-t",t]).ok}r(tn,"focusWindow");function en(n){return o(["kill-window","-t",n]).ok}r(en,"closeWindow");function rn(n,t){return o(["rename-window","-t",n,t]).ok}r(rn,"renameWindow");function on(n){const t=o(["break-pane","-d","-P","-F","#{window_id} #{pane_id}","-s",n]);if(!t.ok)return null;const[e,s]=t.stdout.split(" ");return e===void 0||e===""||s===void 0||s===""?null:{window:e,pane:s}}r(on,"breakPane");function sn(n){return o(["kill-pane","-t",n]).ok}r(sn,"closePane");function un(n,t,e){return o(["display-popup","-E","-t",n,"-d",t,"-w","90%","-h","90%",e]).ok}r(un,"displayPopup");function cn(n,t){const e=o(["display-message","-p","-t",`${n}:${t}`,"#{pane_id}"]);return e.ok&&e.stdout!==""?e.stdout:null}r(cn,"paneOfWindow");function an(n){const t=o(["display-message","-p","-t",n,"#{window_id}"]);return t.ok&&t.stdout!==""?t.stdout:null}r(an,"windowOfPane");function dn(n){const t=o(["display-message","-p","-t",n,"#{session_name} #{window_id}"]);if(!t.ok)return null;const e=/^(.*) (@\d+)$/.exec(t.stdout);return e===null||e[1]===""?null:{session:e[1],window:e[2]}}r(dn,"paneLocation");function pn(n){const t=o(["display-message","-p","-t",n,"#{pane_id}"]);return t.ok&&t.stdout===n}r(pn,"paneExists");function ln(n){const t=o(["display-message","-p","-t",n,"#{pane_id} #{pane_dead}"]);return t.ok&&t.stdout===`${n} 0`}r(ln,"paneRunning");function fn(){const n=o(["list-panes","-a","-F","#{pane_id}"]);return n.ok?new Set(n.stdout.split(`
|
|
3
|
+
`).filter(t=>t!=="")):null}r(fn,"listLivePanes");const R=2e3;async function mn(){const n=await new Promise(t=>{try{g("tmux",["list-panes","-a","-F","#{pane_id}"],{encoding:"utf8",timeout:R,maxBuffer:4194304},(e,s)=>t(e?null:s))}catch{t(null)}});return n===null?null:new Set(n.trim().split(`
|
|
4
|
+
`).filter(t=>t!==""))}r(mn,"listLivePanesAsync");function wn(n){const t=o(["display-message","-p","-t",n,"#{pane_current_path}"]);return t.ok&&t.stdout!==""?t.stdout:null}r(wn,"paneCurrentPath");function xn(n){const t=o(["display-message","-p","-t",n,"#{pane_width} #{pane_height}"]);if(!t.ok)return null;const[e,s]=t.stdout.split(" "),u=Number.parseInt(e,10),i=Number.parseInt(s,10);return Number.isInteger(u)&&u>0&&Number.isInteger(i)&&i>0?{cols:u,rows:i}:null}r(xn,"paneSize");function kn(n,t,e=4e3){const s=r(u=>{const i=["display-message",...u?["-C"]:[],"-d",String(e)];return t!==void 0&&t!==""&&i.push("-t",t),i.push(n),i},"args");return o(s(!0)).ok||o(s(!1)).ok}r(kn,"displayMessage");function gn(n,t,e){return o(["set-option","-p","-t",n,t,e]).ok}r(gn,"setPaneOption");function hn(n,t){const e=o(["show-options","-p","-t",n,"-q","-v",t]);return e.ok?e.stdout:void 0}r(hn,"getPaneOption");const W="@crtr_viewer_at";let h=0,_=Promise.resolve();function _n(n){if(n==="")return;const t=Math.max(Date.now(),h+1);h=t,_=_.then(()=>new Promise(e=>{try{g("tmux",["set-option","-p","-t",n,W,String(t)],()=>e())}catch{e()}}))}r(_n,"stampViewerPaneAsync");function A(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}r(A,"escapeRegex");function x(n,t){const e=n.replace(/^"|"$/g,"");return new RegExp(`(?:^|\\s)surface\\s+attach\\s+to\\s+${A(t)}(?:\\s|$)`).test(e)}r(x,"looksLikeViewerCommand");function V(){const n=p("ps",["-ax","-o","pid=,ppid=,command="],{encoding:"utf8"});if(n.status!==0||typeof n.stdout!="string")return null;const t=new Map,e=new Map;for(const s of n.stdout.split(`
|
|
5
|
+
`)){const u=/^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(s);if(u===null)continue;const i=Number(u[1]),a=Number(u[2]);e.set(i,u[3]);const c=t.get(a)??[];c.push(i),t.set(a,c)}return{childrenOf:t,commandOf:e}}r(V,"readProcessTree");function B(n,t,e){const s=[t];for(;s.length>0;){const u=s.pop();if(x(n.commandOf.get(u)??"",e))return!0;const i=n.childrenOf.get(u);i!==void 0&&s.push(...i)}return!1}r(B,"processTreeHasViewer");function Pn(n){const t=d(n,["list-panes","-a","-F","#{pane_id} #{session_name} #{@crtr_node} #{@crtr_viewer_at}"]);if(!t.ok||t.stdout==="")return[];const e=[];let s;for(const u of t.stdout.split(`
|
|
6
|
+
`)){const[i,a,c,y]=u.split(" ");if(i===void 0||i===""||a===void 0||a===""||c===void 0||c==="")continue;const k=d(n,["display-message","-p","-t",i,"#{pane_current_command} #{pane_start_command} #{pane_pid}"]);if(!k.ok)continue;const[b="",v="",S]=k.stdout.split(" ");if(!(x(b,c)||x(v,c))){s??=V();const m=Number.parseInt(S,10);if(s===null||!Number.isInteger(m)||m<=0||!B(s,m,c))continue}const f=Number.parseInt(y??"",10);e.push({pane:i,session:a,nodeId:c,stampMs:Number.isSafeInteger(f)&&f>=0?f:0})}return e}r(Pn,"liveViewerPanes");function yn(n,t,e){return d(n,["send-keys","-l","-t",t,O(e)]).ok}r(yn,"sendAttachControl");function bn(n,t,e){const s=r(u=>{const i=["display-message",...u?["-C"]:[]];return t!==void 0&&t!==""&&i.push("-c",t),i.push(e),i},"args");return d(n,s(!0)).ok||d(n,s(!1)).ok}r(bn,"displayClientMessage");function P(n){return["respawn-pane","-k","-c",n.cwd,...w(n.env),"-t",n.pane,n.command]}r(P,"respawnPaneArgs");function vn(n){return o(P(n)).ok}r(vn,"respawnPaneSync");function Sn(n){return L(`tmux ${P(n).map(l).join(" ")} >/dev/null 2>&1`)}r(Sn,"respawnPaneInBackground");function L(n){return o(["run-shell","-b",n]).ok}r(L,"runShellInBackground");function In(n){const t=o(["display-message","-p","-t",n,"#{pane_start_command}"]);return t.ok?t.stdout:void 0}r(In,"paneStartCommand");function On(n){const t=o(["display-message","-p","-t",n,"#{pane_pid}"]);if(!t.ok)return;const e=Number.parseInt(t.stdout,10);return Number.isInteger(e)&&e>0?e:void 0}r(On,"panePid");function En(n){return o(["respawn-pane","-k","-t",n]).ok}r(En,"respawnPaneInPlace");function Nn(n,t=N()??E(l)){return[t,...n.map(l)].join(" ")}r(Nn,"piCommand");function j(n){const t=o(["list-windows","-t",n,"-F","#{window_id}"]);return!t.ok||t.stdout===""?[]:t.stdout.split(`
|
|
7
|
+
`).filter(e=>e!=="")}r(j,"listWindowIds");function $n(n,t){return n==null||t==null?!1:j(n).includes(t)}r($n,"windowAlive");function Cn(n,t){return o(["select-window","-t",`${n}:${t}`]).ok}r(Cn,"selectWindow");function Mn(n,t){return o(["select-layout","-t",n,t]).ok}r(Mn,"selectLayout");function Fn(n){return o(["select-pane","-t",n]).ok}r(Fn,"selectPane");function Tn(n){return o(["switch-client","-t",n]).ok}r(Tn,"switchClient");function Rn(n,t){return o(["send-keys","-t",n,t,"Enter"]).ok}r(Rn,"sendKeysEnter");export{W as VIEWER_STAMP_OPTION,on as breakPane,sn as closePane,en as closeWindow,C as currentTmux,bn as displayClientMessage,kn as displayMessage,un as displayPopup,Y as ensureSession,tn as focusWindow,hn as getPaneOption,$ as inTmux,fn as listLivePanes,mn as listLivePanesAsync,j as listWindowIds,Pn as liveViewerPanes,Z as openNodeWindow,wn as paneCurrentPath,pn as paneExists,dn as paneLocation,J as paneOfNode,cn as paneOfWindow,On as panePid,ln as paneRunning,xn as paneSize,In as paneStartCommand,Nn as piCommand,rn as renameWindow,Sn as respawnPaneInBackground,En as respawnPaneInPlace,vn as respawnPaneSync,L as runShellInBackground,o as runTmux,Mn as selectLayout,Fn as selectPane,Cn as selectWindow,yn as sendAttachControl,Rn as sendKeysEnter,M as sessionExists,gn as setPaneOption,l as shellQuote,nn as splitWindow,_n as stampViewerPaneAsync,Tn as switchClient,G as tmuxClientsReachable,K as tmuxSessionsReachable,$n as windowAlive,an as windowOfPane};
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
import { Socket } from 'node:net';
|
|
1
2
|
/** The shared cold-start deadline (ms) a freshly-opened viewer waits for its
|
|
2
3
|
* broker's view.sock — one source of truth for CRTR_ATTACH_WAIT_MS. */
|
|
3
4
|
export declare const BROKER_VIEW_SOCKET_WAIT_MS = 30000;
|
|
4
|
-
/**
|
|
5
|
-
|
|
5
|
+
/** Connect to `nodeId`'s view.sock without following a symlink the node's app
|
|
6
|
+
* planted in its run folder. A refusal or a missing socket surfaces as the
|
|
7
|
+
* socket's 'error' event, as a failed connect does. */
|
|
8
|
+
export declare function connectViewSocket(nodeId: string): Socket;
|
|
9
|
+
/** Resolve true exactly when `nodeId`'s view.sock accepts a connection within
|
|
10
|
+
* `timeoutMs`. A view.sock that is a symlink rejects with the refusal, so no
|
|
11
|
+
* wait reads a planted link as a broker that is still starting. */
|
|
12
|
+
export declare function probeViewSocket(nodeId: string, timeoutMs: number): Promise<boolean>;
|
|
6
13
|
/** Bounded retry for the revive leaf, which has no launch handle to observe. */
|
|
7
14
|
export declare function waitForViewSocketReady(nodeId: string): Promise<boolean>;
|
|
8
15
|
/** Wait for a launched broker's view.sock, failing fast when its launch handle
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var m=Object.defineProperty;var a=(t,e)=>m(t,"name",{value:e,configurable:!0});import{createConnection as p,Socket as S}from"node:net";import{nodeRunDir as d,viewSocketPath as h}from"../canvas/paths.js";import{isBeneathRefusal as x,socketBeneath as _}from"../spaces/open-beneath.js";const u=3e4,l=100,T=u;function f(t){return new Promise(e=>{setTimeout(e,t)})}a(f,"sleep");function E(t){let e;try{e=_(d(t),h(t))}catch(i){const c=new S;return process.nextTick(()=>c.destroy(i)),c}const r=p(e.path);return r.once("connect",e.release),r.once("close",e.release),r}a(E,"connectViewSocket");function w(t,e){return new Promise((r,i)=>{let c=!1,n=null;const s=a(o=>{c||(c=!0,n!==null&&n.destroy(),o instanceof Error?i(o):r(o))},"finish");n=E(t),n.once("connect",()=>s(!0)),n.once("error",o=>s(x(o)?o:!1)),n.setTimeout(e,()=>s(!1))})}a(w,"probeViewSocket");async function B(t){const e=Date.now()+u;for(;Date.now()<=e;){if(await w(t,l))return!0;await f(l)}return!1}a(B,"waitForViewSocketReady");async function C(t,e){const r=Date.now()+u,i=e?.then(()=>"exit");for(;Date.now()<=r;){const c=Math.max(0,r-Date.now()),n=w(t,Math.min(l,c)).then(o=>o?"ready":"retry"),s=i===void 0?await n:await Promise.race([n,i]);if(s==="ready")return!0;if(s==="exit")return!1;if(i!==void 0){if(await Promise.race([f(l).then(()=>"sleep"),i])==="exit")return!1}else await f(l)}return!1}a(C,"waitForBrokerViewSocket");export{T as BROKER_VIEW_SOCKET_WAIT_MS,E as connectViewSocket,w as probeViewSocket,C as waitForBrokerViewSocket,B as waitForViewSocketReady};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var k=Object.defineProperty;var i=(e,r)=>k(e,"name",{value:r,configurable:!0});import{createHash as S}from"node:crypto";import{claimWarmSpare as _,deleteNode as x,getNode as w,listNodes as I,listWarmSpares as $,registerWarmSpare as N,unregisterWarmSpare as R,updateNode as C,warmSpareCount as h}from"../canvas/index.js";import{recordedPidLiveness as b}from"../canvas/pid.js";import{nowIso as P}from"../fs-utils.js";import{admitNodeCreate as L}from"../command-hooks/lifecycle-create.js";import{spawnChildPrepared as W}from"./spawn.js";import{buildLaunchSpecAsync as M}from"./launch.js";import{setModelLive as A}from"./model-swap.js";import{setSituationalContextLive as E}from"./situational-live.js";import{deliverBearingsLive as O}from"./deliver-live.js";import{closeNode as y}from"./close.js";function g(){return process.env.CRTR_WARM_POOL!=="0"}i(g,"warmPoolEnabled");function T(e,r,n){const o=Object.entries(n.env??{}).sort(([c],[t])=>c<t?-1:c>t?1:0),l=JSON.stringify([e,r,n.tools??[],n.extensions??[],n.systemPrompt??null,o]);return S("sha256").update(l).digest("hex").slice(0,32)}i(T,"warmRecipeKey");async function f(e){const{launch:r}=await M(e.kind,e.mode,{lifecycle:"resident",hasManager:!1,...e.model!==null?{model:e.model}:{},cwd:e.cwd,profileId:e.profileId});return{key:T(e.cwd,e.profileId,r),launch:r,request:e}}i(f,"resolveRecipe");async function Z(e,r={},n){const o=await f(e);if(h(o.key)===0)return null;const l=P(),c=await L({kind:e.kind,mode:e.mode,cwd:e.cwd,profile:e.profileId,root:!0,parentId:null,requestingNodeId:e.creator,lifecycle:"resident",replaces:null},e.creator===null?"app:terminal":(()=>{const a=w(e.creator);if(!a?.grantee)throw new Error("warm node creator has no app");return a.grantee})());let t;try{t=_(o.key,l,r)}finally{c()}if(t===null)return null;const m=w(t)?.launch?.model;C(t,{created:l,kind:e.kind,mode:e.mode,name:e.name??e.kind,creator:e.creator,launch:o.launch,persona_ack:{kind:e.kind,mode:e.mode,lifecycle:"resident"},...e.model!==null?{model_override:e.model}:{}});try{n?.(t)}catch(a){return d(t,"birth preparation",a)}try{await O(t)}catch(a){return d(t,"bearings delivery",a)}const p=o.launch.model;if(p!==void 0&&p!==m)try{await A(t,p,o.launch.modelIntent)}catch(a){return d(t,"model swap",a)}if(e.situationalContext!==null)try{await E(t,e.situationalContext)}catch(a){return d(t,"situational-context delivery",a)}return t}i(Z,"claimWarmNode");function d(e,r,n){console.error(`[warm-pool] ${r} failed on claim; closing the spare: ${n.message}`);try{y(e)}catch{}return null}i(d,"abandonSpare");const D=3600*1e3;function q(){const e=[];let r;try{r=$()}catch(o){return console.error(`[warm-pool] spare scan failed: ${o.message}`),e}const n=Date.now()-D;for(const o of r){const l=Date.parse(o.created),c=Number.isNaN(l)||l<n,t=b(o.pi_pid,o.pi_pid_identity),s=(o.status==="active"||o.status==="idle")&&t==="alive";if(!(s&&!c)&&!(t==="indeterminate"&&!c))try{if(!R(o.node_id))continue;if(s)try{y(o.node_id)}catch{}x(o.node_id),e.push(o.node_id)}catch(m){console.error(`[warm-pool] reap failed for ${o.node_id}: ${m.message}`)}}return e}i(q,"reapStaleSpares");const u=new Set;function ee(e){if(g())try{f({...e,model:null,situationalContext:null}).then(v).catch(r=>console.error(`[warm-pool] recipe resolution failed: ${r.message}`))}catch(r){console.error(`[warm-pool] recipe resolution failed: ${r.message}`)}}i(ee,"refillWarmPool");function v(e){const{key:r,request:n}=e;u.has(r)||h(r)>0||(u.add(r),(async()=>{try{await W({kind:n.kind,mode:n.mode,cwd:n.cwd,prompt:"",root:!0,readiness:"await",profile:n.profileId},o=>N(o,r))}catch(o){console.error(`[warm-pool] mint failed for ${n.kind}: ${o.message}`)}finally{u.delete(r)}})())}i(v,"mint");const j=2;function re(){if(!g())return;let e;try{const r=new Set;e=[];for(const n of I({status:["active","idle"]}).reverse()){if(n.parent!==null||n.kind==="human")continue;const o=n.profile_id??null;if(!r.has(o??"")&&(r.add(o??""),e.push({cwd:n.cwd,profileId:o}),e.length>=j))break}}catch(r){console.error(`[warm-pool] prewarm scan failed: ${r.message}`);return}for(const r of e)try{f({kind:"general",mode:"base",cwd:r.cwd,profileId:r.profileId,model:null,situationalContext:null,name:null,creator:null}).then(v).catch(n=>console.error(`[warm-pool] prewarm failed for ${r.cwd}: ${n.message}`))}catch(n){console.error(`[warm-pool] prewarm failed for ${r.cwd}: ${n.message}`)}}i(re,"prewarmRecentRecipes");export{Z as claimWarmNode,re as prewarmRecentRecipes,q as reapStaleSpares,ee as refillWarmPool,g as warmPoolEnabled};
|
package/dist/core/scope.d.ts
CHANGED
|
@@ -27,8 +27,9 @@ export declare function findProjectScopeRoot(startDir?: string): string | null;
|
|
|
27
27
|
* whichever pointer reached it first. `profileId` defaults to the process's
|
|
28
28
|
* selected profile (`CRTR_PROFILE_ID`); a null/unresolvable profile collapses
|
|
29
29
|
* to the single `[startDir]` pointer, reproducing today's behavior exactly.
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Outside a Linux node sandbox, roots are discovered on each call so profile
|
|
31
|
+
* edits and deleted project directories do not leave a stale pointer. A node
|
|
32
|
+
* sandbox has no profile store to read and uses only its cwd pointer.
|
|
32
33
|
*
|
|
33
34
|
* Each root also carries the selected profile relationship's memory ceiling
|
|
34
35
|
* (`findProjectScopeRootsWithMemory`), a projection layered onto this order
|
package/dist/core/scope.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var g=Object.defineProperty;var r=(o,t)=>g(o,"name",{value:t,configurable:!0});import{envProfileId as h,isSandboxedNode as y}from"../shared/env.js";import{homedir as k}from"node:os";import{existsSync as C,statSync as E}from"node:fs";import{join as e,resolve as a,dirname as _}from"node:path";import{CRTR_DIR_NAME as S}from"../types.js";import{assetRoot as j}from"./asset-root.js";import{usage as P}from"./errors.js";import{loadProfileManifest as A}from"./profiles/manifest.js";import{realpathOrSelf as p}from"./fs-utils.js";import{resetRepositoryAssociationCache as N}from"./memory/repository-association.js";import{layoutRoot as O,runtimeRoot as R,userRoot as T}from"./layout.js";const L="content";function W(){return e(j(),"builtin-memory")}r(W,"builtinMemoryRoot");function $(){return e(j(),"builtin-pi-packages")}r($,"builtinPiPackagesDir");function to(o){return e($(),o)}r(to,"builtinPiPackageDir");function b(){return e(R(),"scope")}r(b,"userScopeRoot");function q(o,t){if(!C(o)||!y()&&(p(o)===p(t)||p(o)===p(O())))return!1;try{return E(o).isDirectory()}catch{return!1}}r(q,"isProjectScopeDir");function w(o=process.cwd()){return M(o)[0]??null}r(w,"findProjectScopeRoot");function J(o,t){const n=[],l=p(k());let i=a(o);for(;;){const f=e(i,S);if(q(f,t)&&n.push(f),p(i)===l)return n;const s=_(i);if(s===i)return n;i=s}}r(J,"collectAncestorScopeRoots");function M(o=process.cwd(),t=h()||null){return v(o,t).roots}r(M,"findProjectScopeRoots");function U(o=process.cwd(),t=h()||null){return v(o,t).annotated}r(U,"findProjectScopeRootsWithMemory");function v(o,t){const n=a(o),l=b(),i=[{dir:n,memory:null}];if(!y()&&t!==null&&t!=="")try{const{manifest:u}=A(t);for(const c of u.projects)i.push({dir:c.path,memory:c.memory})}catch{}const f=new Set,s=[],m=new Map;for(const u of i)for(const c of J(u.dir,l))f.has(c)||(f.add(c),s.push(c)),u.memory!==null&&!m.has(c)&&m.set(c,u.memory);const D=s.map(u=>({root:u,memory:m.get(u)??L}));return{roots:s,annotated:D}}r(v,"resolveProjectScopeRoots");function x(o){return w(o)}r(x,"projectScopeRoot");function ro(o,t){return M(o,t)}r(ro,"projectScopeRoots");function eo(o,t){return U(o,t)}r(eo,"projectScopeRootsWithMemory");function d(o){return o==="builtin"?null:o==="user"?b():x()}r(d,"scopeRoot");function no(o){const t=d(o);if(!t)throw P(`no ${o} scope available \u2014 run \`crtr init\` here or use --scope user`);return t}r(no,"requireScopeRoot");function io(o=process.cwd()){const t=w(o);return t||e(a(o),S)}r(io,"ensureProjectScopeRoot");function uo(o){const t=o==="user"?R():d(o);return t?e(t,"plugins"):null}r(uo,"pluginsDir");function co(o){const t=o==="user"?R():d(o);return t?e(t,"marketplaces"):null}r(co,"marketplacesDir");function so(o){if(o==="builtin")return W();if(o==="user")return e(T(),"memory");const t=x();return t?e(t,"memory"):null}r(so,"scopeMemoryDir");function po(o){return e(o.root,"memory")}r(po,"pluginMemoryDir");function Y(o){if(o===void 0)return"all";const t=o.toLowerCase();if(t==="user"||t==="project"||t==="builtin"||t==="all")return t;throw P(`invalid --scope: ${o} (expected user|project|builtin|all)`)}r(Y,"resolveScopeArg");function fo(o){const t=Y(o);if(t==="all"){const n=[];return x()&&n.push("project"),n.push("user"),n.push("builtin"),n}return[t]}r(fo,"listScopes");function lo(){N()}r(lo,"resetScopeCache");export{L as NEUTRAL_PROJECT_MEMORY,W as builtinMemoryRoot,to as builtinPiPackageDir,$ as builtinPiPackagesDir,io as ensureProjectScopeRoot,w as findProjectScopeRoot,M as findProjectScopeRoots,U as findProjectScopeRootsWithMemory,fo as listScopes,co as marketplacesDir,po as pluginMemoryDir,uo as pluginsDir,x as projectScopeRoot,ro as projectScopeRoots,eo as projectScopeRootsWithMemory,no as requireScopeRoot,lo as resetScopeCache,Y as resolveScopeArg,so as scopeMemoryDir,d as scopeRoot,b as userScopeRoot};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var R=Object.defineProperty;var n=(e,o)=>R(e,"name",{value:o,configurable:!0});import{DatabaseSync as p}from"node:sqlite";import{chmodSync as d,existsSync as a,mkdirSync as w,readdirSync as L,rmSync as k,statSync as I,writeFileSync as P}from"node:fs";import{join as i}from"node:path";import v from"proper-lockfile";import{CONFIG_FILE as A,PROFILE_DIR as O,STATE_FILE as f}from"../../types.js";import{withExclusiveDirectoryLock as E}from"../exclusive-lock.js";import{layoutNeedsMigration as j}from"../layout.js";import{providerStore as D,projectStore as T,userStore as G}from"./paths.js";import{createScopedSchema as $,PROVIDER_SCHEMA_VERSION as g,SCOPED_SCHEMA_VERSION as h}from"./schema.js";const u=new Map,C=/^[a-z0-9]+(?:-[a-z0-9]+)*-[0-9a-f]{8}$/;function N(e,o,r){e.prepare("UPDATE scope_owners SET root=? WHERE owner_key=?").run(r,o)}n(N,"writeOwnerRoot");function s(e){return Number(e.prepare("PRAGMA user_version").get().user_version)}n(s,"version");function x(e,o){const r=s(e);if(r===0)throw new Error(`scoped SQL store is uninitialized: ${o.path}; crtr was updated and \`crtr sys daemon restart\` converts local state`);const t=o.kind==="provider"?g:h;if(r>t)throw new Error(`scoped SQL store ${o.path} uses unsupported schema version ${r}`);if(r!==t)throw new Error(`scoped SQL store ${o.path} requires an explicit conversion`)}n(x,"assertVersion");function M(e,o){if(!(o.kind==="provider"||s(e)>=h)){e.exec("PRAGMA busy_timeout = 5000; BEGIN IMMEDIATE");try{s(e)===1&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="grantee")||e.exec("ALTER TABLE profiles ADD COLUMN grantee TEXT"),e.exec("PRAGMA user_version = 2")),s(e)===2&&(e.prepare("PRAGMA table_info(profiles)").all().some(({name:t})=>t==="home")&&e.exec("ALTER TABLE profiles DROP COLUMN home"),e.exec(`PRAGMA user_version = ${h}`)),e.exec("COMMIT")}catch(r){throw e.exec("ROLLBACK"),r}}}n(M,"upgradeScopedStore");function oe(e){const o=new p(e.path);try{M(o,e),x(o,e)}finally{o.close()}}n(oe,"assertScopedStoreReady");function B(e){if(!_(e))return;const o=new p(e.path,{readOnly:!0});let r;try{r=s(o)}finally{o.close()}if(r===0)for(const t of[e.path,`${e.path}-wal`,`${e.path}-shm`])k(t,{force:!0})}n(B,"discardIncompleteScopedStore");function F(e,o){return E(i(e,".init.lock"),()=>{const r=i(e,f),t=Date.now()+5e3;let c=10;for(;;){let y;try{y=v.lockSync(r,{realpath:!1,retries:0,stale:3e4,update:1e4})}catch(l){if(l.code!=="ELOCKED")throw l;const S=t-Date.now();if(S<=0)throw new Error(`timed out waiting for project state conversion lock: ${r}`,{cause:l});Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,Math.min(c,S)),c=Math.min(c*2,250);continue}try{return o()}finally{y()}}})}n(F,"withProjectStateLock");function m(e){a(e)&&d(e,384);for(const o of["-wal","-shm"])a(`${e}${o}`)&&d(`${e}${o}`,384)}n(m,"secure");function _(e){return a(e.path)}n(_,"scopedStoreExists");function z(e){if(e.kind==="project")return[i(e.root,f)];if(e.kind==="provider")return[i(e.root,"anthropic-subscriptions.json"),i(e.root,"openai-codex-subscriptions.json"),i(e.root,"provider-rotation.json")];const o=[i(e.root,A),i(e.root,f),i(e.root,"profile-defaults.json")],r=i(e.root,O);if(a(r))for(const t of L(r,{withFileTypes:!0}))t.isDirectory()&&C.test(t.name)&&o.push(i(r,t.name,"profile.json"),i(r,t.name,A),i(r,t.name,f));return o}n(z,"legacyScopedStorePaths");function Q(e){const o=e.kind==="user"?G(e.root):e.kind==="project"?T(e.root):D(e.root);o.kind!=="project"&&w(o.root,{recursive:!0,mode:448});const r=n(()=>{if(o.kind==="project"&&B(o),_(o))return;const t=z(o).find(a);if(t!==void 0)throw new Error(`legacy scoped state exists at ${t}; crtr was updated and \`crtr sys daemon restart\` converts local state`);K(o,c=>{$(c,o.kind),o.kind!=="provider"&&N(c,o.kind,o.root)})},"initialize");o.kind==="project"?F(o.root,r):E(i(o.root,".init.lock"),r)}n(Q,"initializeFreshScopedStore");function H(e){if(j())throw new Error("layout_migration_required");const o=u.get(e.path);if(o!==void 0)return o;Q(e);const r=new p(e.path);try{return r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON;"),M(r,e),x(r,e),m(e.path),u.set(e.path,r),r}catch(t){throw r.close(),t}}n(H,"openScopedStore");function K(e,o){if(a(e.path))throw new Error(`scoped SQL store already exists: ${e.path}`);if(e.kind!=="project"&&w(e.root,{recursive:!0,mode:448}),!I(e.root).isDirectory())throw new Error(`scoped SQL root is not a directory: ${e.root}`);(e.kind!=="project"||process.platform!=="linux")&&d(e.root,448),P(e.path,"",{mode:384});const r=new p(e.path);try{r.exec("PRAGMA busy_timeout = 5000; PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; BEGIN IMMEDIATE;"),o(r),r.exec("COMMIT")}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}finally{m(e.path),r.close()}}n(K,"createScopedStore");function re(e,o){const r=H(e);if(r.isTransaction)return o(r);r.exec("BEGIN IMMEDIATE");try{const t=o(r);return r.exec("COMMIT"),m(e.path),t}catch(t){try{r.exec("ROLLBACK")}catch{}throw t}}n(re,"withScopedWrite");function te(){for(const e of u.values())e.close();u.clear()}n(te,"closeScopedStores");export{C as PROFILE_ID_SHAPE,oe as assertScopedStoreReady,te as closeScopedStores,K as createScopedStore,B as discardIncompleteScopedStore,Q as initializeFreshScopedStore,z as legacyScopedStorePaths,H as openScopedStore,_ as scopedStoreExists,F as withProjectStateLock,re as withScopedWrite,N as writeOwnerRoot};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
`).withLockAsync(async(
|
|
3
|
-
`),{result:void 0}))}
|
|
1
|
+
var $=Object.defineProperty;var f=(e,r)=>$(e,"name",{value:r,configurable:!0});import{randomUUID as U}from"node:crypto";import{chmodSync as A,copyFileSync as x,existsSync as d,mkdirSync as h,readFileSync as S,readdirSync as P,statSync as I}from"node:fs";import{dirname as b,join as u,relative as V}from"node:path";import J from"proper-lockfile";import{CONFIG_FILE as L,PROFILE_DIR as W,STATE_FILE as w}from"../../types.js";import{LockedJsonFile as D}from"../locked-file.js";import{assertScopedStoreReady as C,createScopedStore as N,discardIncompleteScopedStore as q,legacyScopedStorePaths as j,PROFILE_ID_SHAPE as z,scopedStoreExists as _,withProjectStateLock as G,writeOwnerRoot as H}from"./db.js";import{canonicalRoot as K,providerStore as O,projectStore as M,userStore as X}from"./paths.js";import{profileSpace as B}from"../layout.js";import{createScopedSchema as F}from"./schema.js";function g(e){return JSON.parse(S(e,"utf8"))}f(g,"json");function T(e){return e.some(d)}f(T,"existsLegacy");function v(e,r){const o=u(e,".legacy-scoped-state");try{h(o,{mode:448})}catch(a){if(a.code!=="EEXIST"||!I(o).isDirectory())throw a}A(o,448);for(const a of r)if(d(a)&&I(a).isFile()){const n=V(e,a);if(n===""||n.startsWith(".."))throw new Error(`legacy state is outside its owning root: ${a}`);const t=u(o,n);b(t)!==o&&h(b(t),{recursive:!0,mode:448}),x(a,t),A(t,384)}}f(v,"preserve");import{initializeFreshScopedStore as Se}from"./db.js";function ue(e){const r=e.kind==="user"?X(e.root):e.kind==="project"?M(e.root):O(e.root);if(e.kind!=="project"&&_(r))return;if(e.kind==="provider")throw new Error("provider conversion requires convertLegacyProviderStore() under coordinated shared-agent-dir activation");const o=j(r),a=f(()=>{e.kind==="project"&&q(r),!_(r)&&(e.kind==="project"&&T(o)&&v(r.root,o),N(r,n=>{F(n,e.kind);const t=e.kind==="user"?"user":"project";H(n,t,r.root),e.kind==="user"?ee(n,r.root):k(n,t,u(r.root,w))}),e.kind==="user"&&T(o)&&v(r.root,o))},"convert");e.kind==="project"?G(r.root,()=>{a(),C(r)}):a()}f(ue,"convertLegacyScopedStore");function Q(e){if(!d(e))return[];const r=JSON.parse(S(e,"utf8"));if(!Array.isArray(r))throw new Error(`legacy subscription pool is malformed: ${e}`);const o=new Set;return r.map((a,n)=>{if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy subscription pool entry ${n+1} is malformed: ${e}`);const t=a,s=typeof t.label=="string"?t.label.trim():"",c=typeof t.refresh=="string"?t.refresh.trim():"",i=typeof t.access=="string"?t.access.trim():"",p=Number(t.expires);if(!s||!c||!i||!Number.isFinite(p))throw new Error(`legacy subscription pool entry ${n+1} is incomplete: ${e}`);const m=s.toLowerCase();if(o.has(m))throw new Error(`legacy subscription pool has duplicate label "${s}": ${e}`);o.add(m);const l=f(E=>Number.isFinite(Number(t[E]))?Number(t[E]):0,"timing"),y=typeof t.accountId=="string"&&t.accountId.trim()!==""?t.accountId.trim():void 0;return{label:s,refresh:c,access:i,expires:p,rateLimitedUntil:l("rateLimitedUntil"),lastAttemptAt:l("lastAttemptAt"),lastRateLimitedAt:l("lastRateLimitedAt"),...t.authFailure==="invalid_grant"?{authFailure:"invalid_grant"}:{},...y?{accountId:y}:{}}})}f(Q,"parseLegacyProviderPool");function Y(e){if(!d(e))return{};const r=JSON.parse(S(e,"utf8"));if(r===null||typeof r!="object"||Array.isArray(r))throw new Error(`legacy provider rotation settings are malformed: ${e}`);const o=r;return{...o.defaultFallbackStrength==="ultra"||o.defaultFallbackStrength==="strong"||o.defaultFallbackStrength==="medium"||o.defaultFallbackStrength==="light"?{defaultFallbackStrength:o.defaultFallbackStrength}:{},...typeof o.revertWhenAvailable=="boolean"?{revertWhenAvailable:o.revertWhenAvailable}:{}}}f(Y,"parseLegacyRotation");async function Z(e,r){const o=[];try{for(const a of e)d(a)&&o.push(await J.lock(a,{realpath:!1,retries:0,stale:3e4,update:1e4}));return await r()}finally{await Promise.allSettled(o.reverse().map(a=>a()))}}f(Z,"withLegacyProviderLocks");async function de(e){const r=O(e);if(_(r))return;const o=j(r);await Z(o,async()=>{if(_(r))return;const a=new Map(o.slice(0,2).map((t,s)=>[s===0?"anthropic":"openai-codex",Q(t)])),n=Y(o[2]);h(r.root,{recursive:!0,mode:448}),v(r.root,o);for(const[t,s]of a){const c=Object.fromEntries(s.map(p=>[U(),{refresh:p.refresh,access:p.access,expires:p.expires,...p.accountId?{accountId:p.accountId}:{}}]));await new D(u(r.root,`${t}-credentials.json`),!0,`{"version":1,"accounts":{}}
|
|
2
|
+
`).withLockAsync(async(p,m,l)=>(l(`${JSON.stringify({version:1,accounts:c})}
|
|
3
|
+
`),{result:void 0}))}N(r,t=>{F(t,"provider");for(const[s,c]of a){const i=JSON.parse(S(u(r.root,`${s}-credentials.json`),"utf8")),p=Object.keys(i.accounts),m=t.prepare("INSERT INTO managed_accounts(provider_id,id,label,label_key,position,last_attempt_at,last_rate_limited_at,rate_limited_until,auth_failure) VALUES(?,?,?,?,?,?,?,?,?)");c.forEach((l,y)=>m.run(s,p[y],l.label,l.label.toLowerCase(),y,l.lastAttemptAt,l.lastRateLimitedAt,l.rateLimitedUntil,l.authFailure??null))}(n.defaultFallbackStrength!==void 0||n.revertWhenAvailable!==void 0)&&t.prepare("INSERT INTO rotation_settings(singleton,default_fallback_strength,revert_when_available) VALUES(1,?,?)").run(n.defaultFallbackStrength??null,n.revertWhenAvailable===void 0?null:n.revertWhenAvailable?1:0)})})}f(de,"convertLegacyProviderStore");function R(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy config is malformed: ${o}`);e.prepare("INSERT INTO scope_settings(owner_key,raw_json) VALUES(?,?)").run(r,JSON.stringify(a))}f(R,"importSettings");function k(e,r,o){if(!d(o))return;const a=g(o);if(a===null||typeof a!="object"||Array.isArray(a))throw new Error(`legacy state is malformed: ${o}`);const n=a;e.prepare("INSERT INTO scope_bookkeeping(owner_key,last_self_check,active_canvas) VALUES(?,?,?)").run(r,n.last_self_check??null,n.activeCanvas??null);const t=e.prepare("INSERT INTO scope_marketplaces(owner_key,name,last_updated) VALUES(?,?,?)");for(const[c,i]of Object.entries(n.marketplaces??{}))t.run(r,c,i.last_updated??null);const s=e.prepare("INSERT INTO scope_plugins(owner_key,name,last_updated,etag,checked_at) VALUES(?,?,?,?,?)");for(const[c,i]of Object.entries(n.plugins??{}))s.run(r,c,i.last_updated??null,i.etag??null,i.checked_at??null)}f(k,"importState");function ee(e,r){R(e,"user",u(r,L)),k(e,"user",u(r,w));const o=u(r,W);if(d(o))for(const n of P(o,{withFileTypes:!0})){if(!n.isDirectory()||!z.test(n.name))continue;const t=n.name,s=u(o,t),c=u(s,"profile.json");if(!d(c))throw new Error(`legacy profile manifest is missing: ${c}`);const i=g(c);if(!i||typeof i!="object"||!Array.isArray(i.projects)||typeof i.name!="string"||typeof i.created_at!="string")throw new Error(`legacy profile manifest is malformed: ${c}`);e.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json) VALUES(?,?,?,?,?,?,?,?)").run(t,i.name,i.created_at,i.last_used_at??null,i.paused_at??null,i.default_kind??null,i.grantee??null,JSON.stringify(i.metadata??{})),e.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${t}`,"profile",K(B(i.grantee??"app:terminal",t).memory),t);const p=e.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");i.projects.forEach((m,l)=>p.run(t,m.path,l,m.memory)),R(e,`profile:${t}`,u(s,L)),k(e,`profile:${t}`,u(s,w))}const a=u(r,"profile-defaults.json");if(d(a)){const n=g(a);if(n===null||typeof n!="object"||Array.isArray(n))throw new Error(`legacy profile defaults are malformed: ${a}`);const t=e.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,c]of Object.entries(n)){if(typeof c!="string")throw new Error(`legacy profile default is malformed: ${a}`);t.run(s,c)}}}f(ee,"importUser");export{de as convertLegacyProviderStore,ue as convertLegacyScopedStore,Se as initializeFreshScopedStore};
|
|
@@ -5,8 +5,9 @@ export type StoredProfile = {
|
|
|
5
5
|
};
|
|
6
6
|
export declare function listStoredProfiles(root: string): StoredProfile[];
|
|
7
7
|
export declare function getStoredProfile(root: string, id: string): StoredProfile | null;
|
|
8
|
-
export declare function insertStoredProfile(root: string, profile: StoredProfile
|
|
8
|
+
export declare function insertStoredProfile(root: string, profile: StoredProfile): void;
|
|
9
9
|
export declare function updateStoredProfile(root: string, id: string, mutate: (current: ProfileManifest) => ProfileManifest): StoredProfile | null;
|
|
10
10
|
export declare function deleteStoredProfile(root: string, id: string): boolean;
|
|
11
|
+
export declare function rewriteLocalProfileGrantees(root: string): void;
|
|
11
12
|
export declare function readStoredDefaults(root: string): Record<string, string>;
|
|
12
13
|
export declare function mutateStoredDefaults(root: string, mutate: (current: Record<string, string>) => Record<string, string>): Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _=Object.defineProperty;var o=(r,e)=>_(r,"name",{value:e,configurable:!0});import{canonicalRoot as c,userStore as m}from"./paths.js";import{openScopedStore as
|
|
1
|
+
var _=Object.defineProperty;var o=(r,e)=>_(r,"name",{value:e,configurable:!0});import{canonicalRoot as c,userStore as m}from"./paths.js";import{profileSpace as R}from"../layout.js";import{openScopedStore as E,withScopedWrite as l}from"./db.js";function p(r){return m(r)}o(p,"store");function S(r,e){return{profileId:r.id,manifest:{schema_version:1,name:r.name,projects:e,paused_at:r.paused_at,...r.default_kind===null?{}:{default_kind:r.default_kind},...r.grantee===null?{}:{grantee:r.grantee},...Object.keys(JSON.parse(r.metadata_json)).length===0?{}:{metadata:JSON.parse(r.metadata_json)},created_at:r.created_at,last_used_at:r.last_used_at}}}o(S,"rowToProfile");function f(r,e){const t=r.prepare("SELECT id, name, created_at, last_used_at, paused_at, default_kind, grantee, metadata_json FROM profiles WHERE id=?").get(e);if(!t)return null;const a=r.prepare("SELECT path, memory FROM profile_projects WHERE profile_id=? ORDER BY position").all(e);return S(t,a)}o(f,"get");function k(r){const e=E(p(r));return e.prepare("SELECT id FROM profiles ORDER BY rowid").all().map(({id:a})=>f(e,a)).filter(Boolean)}o(k,"listStoredProfiles");function L(r,e){return f(E(p(r)),e)}o(L,"getStoredProfile");function I(r,e){l(p(r),t=>{t.prepare("INSERT INTO profiles(id,name,created_at,last_used_at,paused_at,default_kind,grantee,metadata_json) VALUES(?,?,?,?,?,?,?,?)").run(e.profileId,e.manifest.name,e.manifest.created_at,e.manifest.last_used_at,e.manifest.paused_at,e.manifest.default_kind??null,e.manifest.grantee??null,JSON.stringify(e.manifest.metadata??{})),t.prepare("INSERT INTO scope_owners(owner_key,kind,root,profile_id) VALUES(?,?,?,?)").run(`profile:${e.profileId}`,"profile",c(R(e.manifest.grantee??"app:terminal",e.profileId).memory),e.profileId);const a=t.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");e.manifest.projects.forEach((i,n)=>a.run(e.profileId,i.path,n,i.memory))})}o(I,"insertStoredProfile");function j(r,e,t){return l(p(r),a=>{const i=f(a,e);if(!i)return null;const n=t(i.manifest);a.prepare("UPDATE profiles SET name=?, last_used_at=?, paused_at=?, default_kind=?, grantee=?, metadata_json=? WHERE id=?").run(n.name,n.last_used_at,n.paused_at,n.default_kind??null,n.grantee??null,JSON.stringify(n.metadata??{}),e),a.prepare("DELETE FROM profile_projects WHERE profile_id=?").run(e);const s=a.prepare("INSERT INTO profile_projects(profile_id,path,position,memory) VALUES(?,?,?,?)");return n.projects.forEach((u,d)=>s.run(e,u.path,d,u.memory)),{profileId:e,manifest:n}})}o(j,"updateStoredProfile");function D(r,e){return l(p(r),t=>{if(!f(t,e))return!1;const a=`profile:${e}`;return t.prepare("DELETE FROM scope_settings WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_bookkeeping WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_marketplaces WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_plugins WHERE owner_key=?").run(a),t.prepare("DELETE FROM scope_owners WHERE owner_key=?").run(a),t.prepare("DELETE FROM profiles WHERE id=?").run(e),!0})}o(D,"deleteStoredProfile");function N(r){l(p(r),e=>{e.prepare("UPDATE profiles SET grantee = 'app:terminal' WHERE grantee = 'user:local'").run()})}o(N,"rewriteLocalProfileGrantees");function F(r){const e=E(p(r));return Object.fromEntries(e.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(t=>[t.directory,t.profile_id]))}o(F,"readStoredDefaults");function M(r,e){return l(p(r),t=>{const a=Object.fromEntries(t.prepare("SELECT directory,profile_id FROM profile_defaults").all().map(s=>[s.directory,s.profile_id])),i=e(a);t.prepare("DELETE FROM profile_defaults").run();const n=t.prepare("INSERT INTO profile_defaults(directory,profile_id) VALUES(?,?)");for(const[s,u]of Object.entries(i))n.run(s,u);return i})}o(M,"mutateStoredDefaults");export{D as deleteStoredProfile,L as getStoredProfile,I as insertStoredProfile,k as listStoredProfiles,M as mutateStoredDefaults,F as readStoredDefaults,N as rewriteLocalProfileGrantees,j as updateStoredProfile};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
-
export declare const SCOPED_SCHEMA_VERSION =
|
|
2
|
+
export declare const SCOPED_SCHEMA_VERSION = 3;
|
|
3
|
+
export declare const PROVIDER_SCHEMA_VERSION = 1;
|
|
3
4
|
export declare function createScopedSchema(db: DatabaseSync, kind: 'user' | 'project' | 'provider'): void;
|