@north-light/crouter 0.3.233 → 0.3.234
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.js +16 -15
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +14 -17
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/crtr-commands/index.ts +7 -11
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +8 -8
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +10 -11
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/pi-shell-runner.ts +2 -2
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +3 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +7 -7
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +8 -8
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +6 -6
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/sysprompt-window.ts +3 -3
- package/dist/builtin-pi-packages/pi-crtr-extensions/lib/subscription-state.ts +1 -1
- package/dist/clients/attach/chrome/ticket-panel.js +15 -2
- package/dist/clients/attach/overlays/graph.js +0 -3
- package/dist/clients/attach/overlays/mcp.js +1 -2
- package/dist/clients/attach/render/chat-view.js +0 -12
- package/dist/clients/attach/render/crtr-output.js +0 -2
- package/dist/clients/attach/render/tool-calls.js +0 -6
- package/dist/clients/attach/slash/dispatch.js +8 -11
- package/dist/clients/attach/viewer.js +532 -534
- package/dist/clients/conversation/projection.js +0 -2
- package/dist/clients/inbox/controller.js +22 -3
- package/dist/clients/inbox/review/companion-pane.js +0 -4
- package/dist/clients/inbox/review-adapter.js +0 -7
- package/dist/clients/inbox/tui/slots.d.ts +3 -3
- package/dist/clients/inbox/tui/types.d.ts +2 -2
- package/dist/commands/api-client.js +0 -8
- package/dist/commands/attention.js +0 -8
- package/dist/commands/canvas-browse.js +2 -1
- package/dist/commands/canvas-config.js +0 -10
- package/dist/commands/canvas-history.js +2 -1
- package/dist/commands/cron.js +5 -18
- package/dist/commands/dashboard.js +0 -2
- package/dist/commands/human/feedback.js +2 -1
- package/dist/commands/human/prompts.js +2 -5
- package/dist/commands/human/queue.js +2 -7
- package/dist/commands/human/request.js +0 -14
- package/dist/commands/human/review.js +2 -1
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +4 -4
- package/dist/commands/memory/find.js +2 -2
- package/dist/commands/memory/lint.js +2 -1
- package/dist/commands/memory/read.d.ts +2 -7
- package/dist/commands/memory/read.js +5 -16
- package/dist/commands/memory/shared.js +4 -7
- package/dist/commands/memory/write.js +4 -3
- package/dist/commands/node/bash.js +2 -1
- package/dist/commands/node/create.js +2 -1
- package/dist/commands/node/inspect.js +0 -6
- package/dist/commands/node/lifecycle.js +4 -13
- package/dist/commands/node/message.js +3 -2
- package/dist/commands/node/subscription.js +2 -1
- package/dist/commands/node/wait.js +4 -3
- package/dist/commands/node-context.js +2 -1
- package/dist/commands/node-lifecycle-revive.js +0 -2
- package/dist/commands/node-worktree.js +2 -1
- package/dist/commands/pkg/browse/actions.d.ts +1 -1
- package/dist/commands/pkg/browse/actions.js +4 -4
- package/dist/commands/pkg/browse/catalog.d.ts +1 -1
- package/dist/commands/pkg/browse/catalog.js +15 -15
- package/dist/commands/pkg/browse/command-view.d.ts +1 -1
- package/dist/commands/pkg/browse/command-view.js +3 -3
- package/dist/commands/pkg/browse/detail-panel.d.ts +1 -1
- package/dist/commands/pkg/browse/detail-panel.js +8 -8
- package/dist/commands/pkg/browse/doc-view.d.ts +1 -1
- package/dist/commands/pkg/browse/doc-view.js +3 -3
- package/dist/commands/pkg/browse/list-panel.d.ts +1 -1
- package/dist/commands/pkg/browse/list-panel.js +3 -3
- package/dist/commands/pkg/browse/model.d.ts +3 -3
- package/dist/commands/pkg/browse/shell.d.ts +2 -2
- package/dist/commands/pkg/browse/shell.js +13 -13
- package/dist/commands/pkg/plugin-manage.js +2 -1
- package/dist/commands/pkg/shared.js +0 -2
- package/dist/commands/profile/delete.js +2 -1
- package/dist/commands/push.js +2 -3
- package/dist/commands/revive.js +0 -2
- package/dist/commands/surface/node/placement.js +2 -1
- package/dist/commands/surface-edit.js +2 -1
- package/dist/commands/sys/config.js +0 -4
- package/dist/commands/sys/daemon.js +0 -10
- package/dist/commands/sys/doctor.js +3 -2
- package/dist/commands/sys/panels/broker-limits-panel.d.ts +2 -2
- package/dist/commands/sys/panels/broker-limits-panel.js +4 -4
- package/dist/commands/sys/panels/dependencies-panel.d.ts +2 -2
- package/dist/commands/sys/panels/dependencies-panel.js +2 -2
- package/dist/commands/sys/panels/keybindings-panel.d.ts +1 -1
- package/dist/commands/sys/panels/keybindings-panel.js +5 -5
- package/dist/commands/sys/panels/models-panel.d.ts +4 -4
- package/dist/commands/sys/panels/models-panel.js +11 -10
- package/dist/commands/sys/panels/plugins-panel.d.ts +2 -2
- package/dist/commands/sys/panels/plugins-panel.js +2 -2
- package/dist/commands/sys/panels/prefs-panel.d.ts +2 -2
- package/dist/commands/sys/panels/prefs-panel.js +4 -4
- package/dist/commands/sys/panels/profiles-panel.d.ts +1 -1
- package/dist/commands/sys/panels/profiles-panel.js +14 -13
- package/dist/commands/sys/panels/provider-panel.d.ts +3 -3
- package/dist/commands/sys/panels/provider-panel.js +8 -8
- package/dist/commands/sys/settings-shell.d.ts +3 -3
- package/dist/commands/sys/settings-shell.js +15 -15
- package/dist/commands/sys/setup-settings-runner.d.ts +3 -3
- package/dist/commands/sys/setup-settings-runner.js +5 -5
- package/dist/commands/sys/setup-wizard.d.ts +4 -4
- package/dist/commands/sys/setup-wizard.js +8 -8
- package/dist/commands/sys/support/prepare.js +4 -4
- package/dist/commands/sys/support/submit.js +2 -2
- package/dist/commands/sys/sync-deps.js +0 -2
- package/dist/commands/sys/sync-project-guidance.js +2 -1
- package/dist/commands/sys/sysprompt.js +2 -1
- package/dist/core/__tests__/boot.test.js +0 -8
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +23 -1
- package/dist/core/__tests__/canvas-db-boundary.test.d.ts +1 -0
- package/dist/core/__tests__/canvas-db-boundary.test.js +46 -0
- package/dist/core/__tests__/canvas.test.js +1 -1
- package/dist/core/__tests__/child-death-wake.test.js +0 -2
- package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +1 -0
- package/dist/core/__tests__/cron-armed-context-failure.test.js +145 -0
- package/dist/core/__tests__/daemon-wedge.test.js +0 -4
- package/dist/core/__tests__/dead-node-policy-table.test.js +0 -4
- package/dist/core/__tests__/fixtures/fake-engine.js +4 -14
- package/dist/core/__tests__/fixtures/fake-pi-host.js +5 -5
- package/dist/core/__tests__/focuses.test.js +0 -6
- package/dist/core/__tests__/fs-utils.test.d.ts +1 -0
- package/dist/core/__tests__/fs-utils.test.js +50 -0
- package/dist/core/__tests__/helpers/harness.js +1 -1
- package/dist/core/__tests__/inline-memory-refs.test.js +0 -2
- package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -2
- package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +3 -16
- package/dist/core/__tests__/integration/command-plugins.test.js +0 -24
- package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -6
- package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -26
- package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -4
- package/dist/core/__tests__/integration/live-mutation.test.js +1 -5
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +1 -5
- package/dist/core/__tests__/integration/revive.test.js +0 -12
- package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -6
- package/dist/core/__tests__/integration/tmux-surface.test.js +24 -8
- package/dist/core/__tests__/integration/worktree-reap.test.js +0 -6
- package/dist/core/__tests__/lifecycle.test.js +0 -18
- package/dist/core/__tests__/memory-resolver-precedence.test.js +1 -1
- package/dist/core/__tests__/migration.test.js +2 -2
- package/dist/core/__tests__/on-read-dedup-resume.test.js +3 -3
- package/dist/core/__tests__/pid-identity-match.test.js +1 -1
- package/dist/core/__tests__/plugin-kinds.test.js +1 -1
- package/dist/core/__tests__/plugin-page-components.test.js +1 -1
- package/dist/core/__tests__/preview-registry-sync.test.js +42 -1
- package/dist/core/__tests__/respawn-throttle.test.js +0 -4
- package/dist/core/__tests__/revive-all.test.js +5 -5
- package/dist/core/__tests__/revive-parked-fresh.test.js +62 -11
- package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -8
- package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -8
- package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -2
- package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +1 -0
- package/dist/core/__tests__/tmux-driver-boundary.test.js +50 -0
- package/dist/core/activity-signal.d.ts +7 -0
- package/dist/core/activity-signal.js +38 -0
- package/dist/core/auto-update.js +2 -1
- package/dist/core/bootstrap.js +2 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-transport.test.js +1 -1
- package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
- package/dist/core/canvas/browse/app.js +3 -2
- package/dist/core/canvas/browse/model.d.ts +1 -1
- package/dist/core/canvas/browse/model.js +0 -4
- package/dist/core/canvas/canvas.d.ts +22 -0
- package/dist/core/canvas/canvas.js +50 -18
- package/dist/core/canvas/crons.js +0 -6
- package/dist/core/canvas/db.d.ts +14 -20
- package/dist/core/canvas/db.js +30 -1332
- package/dist/core/canvas/focuses.js +0 -4
- package/dist/core/canvas/history.js +2 -1
- package/dist/core/canvas/migrations.d.ts +20 -0
- package/dist/core/canvas/migrations.js +1339 -0
- package/dist/core/canvas/nav-model.js +1 -11
- package/dist/core/canvas/nav-render.js +0 -8
- package/dist/core/canvas/remote-canvas-source.js +0 -2
- package/dist/core/canvas/render-source.js +31 -13
- package/dist/core/command-manifests/manifest.js +0 -10
- package/dist/core/command-manifests/schema.js +0 -4
- package/dist/core/command-plugins/transport/http-invoke.js +0 -14
- package/dist/core/command.js +0 -4
- package/dist/core/config.js +2 -1
- package/dist/core/feed/inbox.d.ts +10 -0
- package/dist/core/feed/inbox.js +18 -12
- package/dist/core/fs-utils.d.ts +9 -2
- package/dist/core/fs-utils.js +7 -15
- package/dist/core/help.js +0 -8
- package/dist/core/host-exports/export.d.ts +2 -2
- package/dist/core/host-exports/export.js +9 -12
- package/dist/core/human/answer.d.ts +2 -2
- package/dist/core/human/convention.d.ts +2 -5
- package/dist/core/human/convention.js +3 -13
- package/dist/core/human/page-schema.d.ts +2 -2
- package/dist/core/human/page-schema.js +2 -2
- package/dist/core/human/root.js +6 -23
- package/dist/core/human/scan.js +24 -7
- package/dist/core/human/tickets.d.ts +4 -1
- package/dist/core/human/tickets.js +20 -6
- package/dist/core/io.js +0 -12
- package/dist/core/memory/identity.js +0 -4
- package/dist/core/memory/inline-ref-inventory.js +3 -2
- package/dist/core/memory/lint.js +3 -6
- package/dist/core/memory-resolver.d.ts +5 -0
- package/dist/core/memory-resolver.js +14 -12
- package/dist/core/pagination.js +0 -2
- package/dist/core/preview-registry.d.ts +14 -0
- package/dist/core/preview-registry.js +2 -4
- package/dist/core/preview-result-path.js +2 -1
- package/dist/core/profiles/manifest.d.ts +37 -5
- package/dist/core/profiles/manifest.js +44 -24
- package/dist/core/profiles/select.js +0 -4
- package/dist/core/review/signal.js +4 -23
- package/dist/core/review/ticket-filter.d.ts +3 -3
- package/dist/core/review/ticket-filter.js +4 -9
- package/dist/core/runtime/__tests__/engine-route.test.js +1 -1
- package/dist/core/runtime/__tests__/spawn-env.test.js +0 -8
- package/dist/core/runtime/bearings-render.d.ts +56 -0
- package/dist/core/runtime/bearings-render.js +241 -0
- package/dist/core/runtime/bearings.d.ts +2 -17
- package/dist/core/runtime/bearings.js +12 -198
- package/dist/core/runtime/broker/auth-reload.d.ts +39 -0
- package/dist/core/runtime/broker/auth-reload.js +149 -0
- package/dist/core/runtime/broker/engine-drive.d.ts +26 -0
- package/dist/core/runtime/broker/engine-drive.js +257 -0
- package/dist/core/runtime/broker/engine-routing.d.ts +143 -0
- package/dist/core/runtime/broker/engine-routing.js +211 -0
- package/dist/core/runtime/broker/event-projection.js +3 -2
- package/dist/core/runtime/broker/fault-retry.js +5 -4
- package/dist/core/runtime/broker/frame-client.d.ts +38 -0
- package/dist/core/runtime/broker/frame-client.js +129 -0
- package/dist/core/runtime/broker/frame-dispatch.d.ts +12 -189
- package/dist/core/runtime/broker/frame-dispatch.js +89 -1476
- package/dist/core/runtime/broker/frame-engine-control.d.ts +20 -0
- package/dist/core/runtime/broker/frame-engine-control.js +231 -0
- package/dist/core/runtime/broker/frame-memory-refs.d.ts +19 -0
- package/dist/core/runtime/broker/frame-memory-refs.js +41 -0
- package/dist/core/runtime/broker/frame-model-query.d.ts +13 -0
- package/dist/core/runtime/broker/frame-model-query.js +69 -0
- package/dist/core/runtime/broker/frame-read.d.ts +19 -0
- package/dist/core/runtime/broker/frame-read.js +116 -0
- package/dist/core/runtime/broker/frame-replies.d.ts +24 -0
- package/dist/core/runtime/broker/frame-replies.js +64 -0
- package/dist/core/runtime/broker/frame-session.d.ts +34 -0
- package/dist/core/runtime/broker/frame-session.js +203 -0
- package/dist/core/runtime/broker/turn-ignition.d.ts +42 -0
- package/dist/core/runtime/broker/turn-ignition.js +74 -0
- package/dist/core/runtime/broker-extension-render.js +9 -85
- package/dist/core/runtime/broker-protocol.js +0 -4
- package/dist/core/runtime/broker-sdk.js +2 -1
- package/dist/core/runtime/broker.d.ts +1 -1
- package/dist/core/runtime/broker.js +5 -23
- package/dist/core/runtime/fault.js +3 -2
- package/dist/core/runtime/headless-pi.js +3 -2
- package/dist/core/runtime/host.js +2 -3
- package/dist/core/runtime/kickoff.js +0 -4
- package/dist/core/runtime/launch-target.js +2 -1
- package/dist/core/runtime/launch.js +3 -6
- package/dist/core/runtime/lifecycle.js +17 -26
- package/dist/core/runtime/managed-provider-cooling.d.ts +1 -1
- package/dist/core/runtime/naming.js +0 -2
- package/dist/core/runtime/nodes.js +2 -1
- package/dist/core/runtime/persona.js +0 -6
- package/dist/core/runtime/placement-tmux.js +2 -5
- package/dist/core/runtime/placement.js +4 -11
- package/dist/core/runtime/recap.js +4 -3
- package/dist/core/runtime/reopen.js +4 -7
- package/dist/core/runtime/reset.js +0 -4
- package/dist/core/runtime/resume-root.js +0 -2
- package/dist/core/runtime/revive.js +17 -13
- package/dist/core/runtime/session-list-cache.js +2 -2
- package/dist/core/runtime/shell-expansion.js +0 -2
- package/dist/core/runtime/spawn.js +0 -2
- package/dist/core/runtime/stream-watchdog.d.ts +0 -1
- package/dist/core/runtime/stream-watchdog.js +13 -18
- package/dist/core/runtime/tmux-bindings.js +0 -2
- package/dist/core/runtime/tmux-driver.d.ts +12 -0
- package/dist/core/runtime/tmux-driver.js +18 -13
- package/dist/core/runtime/warm-pool.js +0 -4
- package/dist/core/scope.js +4 -3
- package/dist/core/spawn.js +2 -3
- package/dist/core/subscription-state.js +10 -17
- package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +3 -3
- package/dist/core/substrate/render.js +0 -12
- package/dist/core/substrate/schema.js +0 -12
- package/dist/core/substrate/surface-match.js +0 -2
- package/dist/core/termrender/display.js +2 -1
- package/dist/core/tui/page-host.d.ts +3 -3
- package/dist/core/tui/page-host.js +4 -4
- package/dist/core/tui/panel.js +3 -3
- package/dist/core/wake.js +0 -12
- package/dist/core/worktree.js +0 -2
- package/dist/daemon/__tests__/reconciler-signature.test.d.ts +1 -0
- package/dist/daemon/__tests__/reconciler-signature.test.js +36 -0
- package/dist/daemon/api/__tests__/seam/api-server.test.js +2 -16
- package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +3 -11
- package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -6
- package/dist/daemon/api/handlers/attach.js +2 -1
- package/dist/daemon/api/handlers/broker-ops.js +3 -6
- package/dist/daemon/api/handlers/canvas.js +12 -18
- package/dist/daemon/api/handlers/feedback-comments.js +0 -8
- package/dist/daemon/api/handlers/health.js +3 -2
- package/dist/daemon/api/handlers/human-requests.js +0 -10
- package/dist/daemon/api/handlers/human.js +1 -5
- package/dist/daemon/api/handlers/inbox.js +0 -18
- package/dist/daemon/api/handlers/memory.js +1 -1
- package/dist/daemon/api/handlers/messages.js +4 -8
- package/dist/daemon/api/handlers/nodes.js +10 -21
- package/dist/daemon/api/handlers/reports.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -6
- package/dist/daemon/api/map.js +0 -6
- package/dist/daemon/api/router.js +0 -4
- package/dist/daemon/api/server.js +2 -5
- package/dist/daemon/boot-migrations.d.ts +14 -0
- package/dist/daemon/boot-migrations.js +31 -0
- package/dist/daemon/cron/armed-context.d.ts +21 -0
- package/dist/daemon/cron/armed-context.js +100 -0
- package/dist/daemon/cron/capture.d.ts +20 -0
- package/dist/daemon/cron/capture.js +45 -0
- package/dist/daemon/cron/disposition.d.ts +19 -0
- package/dist/daemon/cron/disposition.js +52 -0
- package/dist/daemon/cron/escalation.d.ts +12 -0
- package/dist/daemon/cron/escalation.js +124 -0
- package/dist/daemon/cron/held.d.ts +4 -0
- package/dist/daemon/cron/held.js +20 -0
- package/dist/daemon/cron/lease-recovery.d.ts +3 -0
- package/dist/daemon/cron/lease-recovery.js +119 -0
- package/dist/daemon/cron/live-runs.d.ts +11 -0
- package/dist/daemon/cron/live-runs.js +23 -0
- package/dist/daemon/cron/passes.d.ts +11 -0
- package/dist/daemon/cron/passes.js +78 -0
- package/dist/daemon/cron/settle.d.ts +28 -0
- package/dist/daemon/cron/settle.js +37 -0
- package/dist/daemon/cron/sinks.d.ts +2 -0
- package/dist/daemon/cron/sinks.js +100 -0
- package/dist/daemon/cron-run.d.ts +5 -41
- package/dist/daemon/cron-run.js +193 -882
- package/dist/daemon/crtrd-cli.js +2 -1
- package/dist/daemon/crtrd.js +22 -22
- package/dist/daemon/fleet.js +0 -4
- package/dist/daemon/human/deliver-action.js +2 -1
- package/dist/daemon/human/sweep.js +15 -4
- package/dist/daemon/manage.d.ts +2 -2
- package/dist/daemon/manage.js +4 -13
- package/dist/daemon/pidfile.js +2 -2
- package/dist/daemon/reconcilers/broker-supervision.js +26 -29
- package/dist/daemon/reconcilers/dormant-inbox.d.ts +1 -1
- package/dist/daemon/reconcilers/dormant-inbox.js +2 -1
- package/dist/daemon/reconcilers/live-obligation.js +2 -2
- package/dist/daemon/reconcilers/pending-review-submit.d.ts +1 -1
- package/dist/daemon/reconcilers/pending-review-submit.js +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +2 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +2 -1
- package/dist/daemon/review/companion.js +2 -2
- package/dist/daemon/review/sweep.js +8 -3
- package/dist/migrations/001-surfaces-frontmatter.js +0 -6
- package/dist/migrations/corpus.js +2 -5
- package/dist/migrations/registry.js +15 -2
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -4
- package/dist/pi-extensions/broker-local.js +2 -1
- package/dist/pi-extensions/canvas-bash-valve.js +3 -17
- package/dist/pi-extensions/canvas-context-intro.js +2 -7
- package/dist/pi-extensions/canvas-doc-substrate.js +2 -3
- package/dist/pi-extensions/canvas-goal-capture.js +2 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +5 -12
- package/dist/pi-extensions/canvas-passive-context.js +2 -5
- package/dist/pi-extensions/canvas-preview-result.js +2 -1
- package/dist/pi-extensions/canvas-prompt-scrub.js +2 -1
- package/dist/pi-extensions/canvas-recap.js +3 -16
- package/dist/pi-extensions/canvas-review-boundary.js +2 -5
- package/dist/pi-extensions/canvas-stophook.js +2 -26
- package/dist/pi-extensions/canvas-structured-output.js +2 -1
- package/dist/pi-extensions/canvas-tool-guide.js +2 -1
- package/dist/shared/__tests__/env-boundary.test.d.ts +1 -0
- package/dist/shared/__tests__/env-boundary.test.js +93 -0
- package/dist/shared/env.d.ts +68 -0
- package/dist/shared/env.js +171 -0
- package/package.json +3 -1
- package/runtime.lock.json +2 -2
- package/dist/core/canvas/render.d.ts +0 -47
- package/dist/core/canvas/render.js +0 -245
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
// so node target metadata comes from each node's durable meta.json — the source
|
|
18
18
|
// of truth the database index is rebuilt from — through its existing read-only
|
|
19
19
|
// helper. Missing or corrupt metadata remains a global blocker.
|
|
20
|
+
import { envProfileId } from '../shared/env.js';
|
|
20
21
|
import { readdirSync } from 'node:fs';
|
|
21
22
|
import { dirname, join } from 'node:path';
|
|
22
23
|
import { readMetaObject } from '../core/canvas/meta-file.js';
|
|
@@ -79,7 +80,7 @@ function nodeStoresWithDocs() {
|
|
|
79
80
|
* so discovery must run after that lane, not against `listProfiles()`. */
|
|
80
81
|
export async function discoverCorpus(opts) {
|
|
81
82
|
const cwd = realpathOrSelf(opts.cwd ?? process.cwd());
|
|
82
|
-
const selectedProfileId =
|
|
83
|
+
const selectedProfileId = envProfileId() || null;
|
|
83
84
|
const explicitDirs = opts.explicitDirs ?? [];
|
|
84
85
|
const roots = [];
|
|
85
86
|
const rootSeen = new Set();
|
|
@@ -336,9 +337,7 @@ export async function discoverCorpus(opts) {
|
|
|
336
337
|
nodeMetadata,
|
|
337
338
|
};
|
|
338
339
|
}
|
|
339
|
-
// ---------------------------------------------------------------------------
|
|
340
340
|
// Snapshots
|
|
341
|
-
// ---------------------------------------------------------------------------
|
|
342
341
|
/** Read every discovered store's documents. `preloaded` supplies the per-store
|
|
343
342
|
* convergent lane's FOLDED snapshots so the corpus plans against the bytes a
|
|
344
343
|
* write run leaves behind — identical under `--dry-run`, where the same fold
|
|
@@ -387,9 +386,7 @@ export function buildCorpusSnapshot(discovery, snapshots) {
|
|
|
387
386
|
}));
|
|
388
387
|
return makeCorpusSnapshot(stores, discovery.targets, discovery.roots);
|
|
389
388
|
}
|
|
390
|
-
// ---------------------------------------------------------------------------
|
|
391
389
|
// The runner
|
|
392
|
-
// ---------------------------------------------------------------------------
|
|
393
390
|
function cloneCorpus(corpus) {
|
|
394
391
|
const stores = corpus.stores.map((store) => ({
|
|
395
392
|
...store,
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
// The ordered state-migration registry —
|
|
2
|
-
//
|
|
1
|
+
// The ordered state-migration registry — the SECOND of this repo's three
|
|
2
|
+
// migration homes, and the one for on-disk memory documents, profile
|
|
3
|
+
// manifests, and the corpus lane, driven by `crtr sys migrate`. ONE list for
|
|
4
|
+
// both non-journaled lanes here, so a cut that spans canvas-db and document
|
|
5
|
+
// stores ships as adjacent entries (the journaled lane's entries splice into
|
|
6
|
+
// `../core/canvas/migrations.ts`'s `MIGRATIONS` chain at its tail).
|
|
7
|
+
//
|
|
8
|
+
// The other two homes:
|
|
9
|
+
// - `../core/canvas/migrations.ts` — canvas.db's own versioned schema chain,
|
|
10
|
+
// gated by `PRAGMA user_version`. Steps there may freely read node meta,
|
|
11
|
+
// query other tables mid-step, and build shell commands from canvas data
|
|
12
|
+
// — exactly what this registry's import contract (below) forbids, which
|
|
13
|
+
// is why that chain is not expressed as registrants here.
|
|
14
|
+
// - `../daemon/boot-migrations.ts` — filesystem repairs that run
|
|
15
|
+
// unconditionally at every daemon boot, outside any version gate.
|
|
3
16
|
//
|
|
4
17
|
// Authoring contract (each migration is one file, `NNN-<desc>.ts`, or one
|
|
5
18
|
// directory, `NNN-<desc>/index.ts`, appended here in order):
|
|
@@ -221,7 +221,6 @@ test('queued continuation finishes before natural-stop routing commits', { timeo
|
|
|
221
221
|
assert.equal(shutdown, true, 'settlement routes from the completed continuation');
|
|
222
222
|
assert.equal(getNode('leaf')?.intent ?? null, null, 'the intermediate natural stop never idle-released the node');
|
|
223
223
|
});
|
|
224
|
-
// ---------------------------------------------------------------------------
|
|
225
224
|
// §5.1 — the §1.7 settlement branch map on the focuses table. Every assertion is
|
|
226
225
|
// on the canvas focuses/runtime rows after firing agent_settled (TMUX_PANE is
|
|
227
226
|
// cleared in beforeEach). NOTE (broker-host cut): the placement read `focusOf`
|
|
@@ -232,7 +231,6 @@ test('queued continuation finishes before natural-stop routing commits', { timeo
|
|
|
232
231
|
// but-not-yet-realized viewer, which liveOrPrune passes through). status='done'
|
|
233
232
|
// is reached by setting the runtime row directly (the branch reads
|
|
234
233
|
// getNode(nodeId).status).
|
|
235
|
-
// ---------------------------------------------------------------------------
|
|
236
234
|
test('§5.1.2 truly-done + focused → focus row CLOSED, own presence nulled (Q1)', async () => {
|
|
237
235
|
// R carries a LOCATION so the close-path presence-null is observable.
|
|
238
236
|
createNode(node('R', { parent: null, lifecycle: 'terminal', pane: '%r', tmux_session: 'Suser', window: '@wr' }));
|
|
@@ -323,10 +321,8 @@ test('refresh-yield (intent=refresh) writes NO push — silent to subscribers',
|
|
|
323
321
|
assert.equal(readInboxSince('root').length, 0, 'a yield is silent: NO inbox pointer');
|
|
324
322
|
assert.equal(pi.injected.length, 0, 'no reprompt on a refresh-yield');
|
|
325
323
|
});
|
|
326
|
-
// ---------------------------------------------------------------------------
|
|
327
324
|
// turn_end — stale-⚠ fix: reaching turn_end proves the current provider
|
|
328
325
|
// round-trip and any wedge episode are both over, so both fault links clear.
|
|
329
|
-
// ---------------------------------------------------------------------------
|
|
330
326
|
/** A turn_end event carrying one assistant text block. */
|
|
331
327
|
function turnEndEvent(text) {
|
|
332
328
|
return { message: { role: 'assistant', content: [{ type: 'text', text }] } };
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// These helpers are intentionally independent of the canvas state store. A
|
|
4
4
|
// broker may read its own context files directly, but all node metadata reads
|
|
5
5
|
// and generated-name writes go through crtrd's broker operation projection.
|
|
6
|
+
import { envHomeOverride } from '../shared/env.js';
|
|
6
7
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
7
8
|
import { homedir } from 'node:os';
|
|
8
9
|
import { join } from 'node:path';
|
|
@@ -14,7 +15,7 @@ function contextDir(nodeId) {
|
|
|
14
15
|
if (nodeId === '' || nodeId === '.' || nodeId === '..' || /[\\/\0]/u.test(nodeId)) {
|
|
15
16
|
throw new TypeError('node_id must be a non-empty path segment');
|
|
16
17
|
}
|
|
17
|
-
const canvasHome =
|
|
18
|
+
const canvasHome = envHomeOverride()?.trim() || join(homedir(), CRTR_DIR_NAME, 'canvas');
|
|
18
19
|
return join(canvasHome, 'nodes', nodeId, 'context');
|
|
19
20
|
}
|
|
20
21
|
/** Persist a bare root's first real interactive message without clobbering an
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
// Deviation from upstream: this backend pins `bash` as the shell (upstream
|
|
25
25
|
// consults user shell config via non-exported helpers). Acceptable — crtr's
|
|
26
26
|
// agents are bash-contract anyway.
|
|
27
|
+
import { envBashValveMs, envNodeId } from '../shared/env.js';
|
|
27
28
|
import { spawn } from 'node:child_process';
|
|
28
29
|
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, rmSync, statSync, writeFileSync, } from 'node:fs';
|
|
29
30
|
import { homedir } from 'node:os';
|
|
@@ -34,20 +35,12 @@ import { PREVIEW_RESULT_PATH_ENV, previewResultPath } from '../core/preview-resu
|
|
|
34
35
|
import { resolveAdmittedHostCommand } from '../core/runtime/spawn-env.js';
|
|
35
36
|
import { Type } from 'typebox';
|
|
36
37
|
import { createBashToolDefinition } from '@earendil-works/pi-coding-agent';
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
38
|
// Deadline — 5 minutes by default, overridable via CRTR_BASH_VALVE_MS
|
|
39
39
|
// (undocumented; test-only seam so the E2E valve check doesn't sleep 5m).
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
|
-
const DEFAULT_VALVE_MS = 5 * 60 * 1000;
|
|
42
40
|
const POLL_MS = 200;
|
|
43
41
|
function resolveValveMs() {
|
|
44
|
-
|
|
45
|
-
if (raw === undefined)
|
|
46
|
-
return DEFAULT_VALVE_MS;
|
|
47
|
-
const n = Number(raw);
|
|
48
|
-
return Number.isFinite(n) && n > 0 ? n : DEFAULT_VALVE_MS;
|
|
42
|
+
return envBashValveMs();
|
|
49
43
|
}
|
|
50
|
-
// ---------------------------------------------------------------------------
|
|
51
44
|
// The detached supervisor. Spawned with `detached: true` so it becomes its
|
|
52
45
|
// own process-group leader (pgid === its pid) — killing `-pgid` reaches the
|
|
53
46
|
// real command and anything it forked, even after this pi process exits.
|
|
@@ -59,7 +52,6 @@ function resolveValveMs() {
|
|
|
59
52
|
//
|
|
60
53
|
// `--` before the paths is a dummy $0 (a standard `bash -c script -- args`
|
|
61
54
|
// idiom) so the real payload lands at $1 onward.
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
55
|
// The elapsed rendering mirrors formatBashElapsed() in core/bash-jobs.ts
|
|
64
56
|
// (`12s` / `3m 40s` / `1h 04m`) so the completion message reads the same as the
|
|
65
57
|
// handoff notice; it measures TOTAL runtime, foreground portion included.
|
|
@@ -166,12 +158,10 @@ function readExitCode(path) {
|
|
|
166
158
|
return null;
|
|
167
159
|
}
|
|
168
160
|
}
|
|
169
|
-
// ---------------------------------------------------------------------------
|
|
170
161
|
// Long-sleep guard. A command that opens with `sleep <long>` is a node burning
|
|
171
162
|
// a live window to wait on a clock — the runtime already has waiting primitives
|
|
172
163
|
// that cost nothing (`crtr cron` for a scheduled wake, `crtr node wait deadline`
|
|
173
164
|
// for an inbox-vs-deadline race). Anything over 10s is refused before it runs.
|
|
174
|
-
// ---------------------------------------------------------------------------
|
|
175
165
|
const MAX_INLINE_SLEEP_SECONDS = 10;
|
|
176
166
|
const SLEEP_UNIT_SECONDS = { s: 1, m: 60, h: 3600, d: 86400 };
|
|
177
167
|
/** Seconds a leading `sleep ...` will block for, or null when the command does
|
|
@@ -371,10 +361,7 @@ export function createValveOperations(nodeId, contextDir, takePurpose = () => nu
|
|
|
371
361
|
},
|
|
372
362
|
};
|
|
373
363
|
}
|
|
374
|
-
// ---------------------------------------------------------------------------
|
|
375
364
|
// Extension
|
|
376
|
-
// ---------------------------------------------------------------------------
|
|
377
|
-
// ---------------------------------------------------------------------------
|
|
378
365
|
// `purpose` — the one line a person reads while a command runs
|
|
379
366
|
//
|
|
380
367
|
// An optional deviation from taking pi's definition verbatim, and the only one
|
|
@@ -396,7 +383,6 @@ export function createValveOperations(nodeId, contextDir, takePurpose = () => nu
|
|
|
396
383
|
// Upstream ask: pi's own bash tool should carry this (Claude Code's bash tool
|
|
397
384
|
// has shipped an equivalent `description` field for years). Until it does, the
|
|
398
385
|
// field is re-declared here on top of pi's schema rather than forked into it.
|
|
399
|
-
// ---------------------------------------------------------------------------
|
|
400
386
|
const PURPOSE_DESCRIPTION = [
|
|
401
387
|
'One short clause naming what this step is FOR, in the words of the person you',
|
|
402
388
|
'are working for — "Reading the Acme thread", not "Fetching emails" and never',
|
|
@@ -437,7 +423,7 @@ export function createValveToolDefinition(nodeId, contextDir, cwd, exposePurpose
|
|
|
437
423
|
return { ...schemaDefinition, execute };
|
|
438
424
|
}
|
|
439
425
|
export default function (pi) {
|
|
440
|
-
const nodeId =
|
|
426
|
+
const nodeId = envNodeId();
|
|
441
427
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
442
428
|
return; // inert — builtin bash stays
|
|
443
429
|
const contextDir = process.env['CRTR_CONTEXT_DIR'];
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
//
|
|
23
23
|
// Plain TS-with-types — no imports from @earendil-works/* so this compiles inside
|
|
24
24
|
// crouter's own tsc build without a dep on the pi packages.
|
|
25
|
+
import { envNodeId } from '../shared/env.js';
|
|
25
26
|
import { CONTEXT_INTRO_CUSTOM_TYPE, formatCard, parseCard } from '../shared/generated-context.js';
|
|
26
27
|
import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
27
28
|
import { buildContextBearingsFromState, buildForkBearingsFromState, buildProjectContextBlockForBroker, renderPreferencesFromState, } from '../core/runtime/broker-extension-render.js';
|
|
@@ -35,9 +36,7 @@ import { truncateToWidth } from './truncate.js';
|
|
|
35
36
|
* the block builder in `core/runtime/bearings.ts` because the warm-pool claim's
|
|
36
37
|
* live delivery needs it too; re-exported here as this module's own surface. */
|
|
37
38
|
export { CONTEXT_INTRO_CUSTOM_TYPE };
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
39
|
// Block builder
|
|
40
|
-
// ---------------------------------------------------------------------------
|
|
41
40
|
/** Build the full bearings baseline for a conversation without inherited
|
|
42
41
|
* crouter context. Exported for testing. */
|
|
43
42
|
export async function buildContextIntro(nodeId, target) {
|
|
@@ -50,9 +49,7 @@ export async function buildForkContextIntro(nodeId) {
|
|
|
50
49
|
const state = await brokerExtensionState(nodeId);
|
|
51
50
|
return buildForkBearingsFromState(state, situationalContextEnvelope(nodeId) ?? '');
|
|
52
51
|
}
|
|
53
|
-
// ---------------------------------------------------------------------------
|
|
54
52
|
// Collapsed-by-default rendering
|
|
55
|
-
// ---------------------------------------------------------------------------
|
|
56
53
|
/** Pull the plain text out of a custom message's content (string or blocks). */
|
|
57
54
|
function messageText(message) {
|
|
58
55
|
if (typeof message.content === 'string')
|
|
@@ -127,16 +124,14 @@ export function renderContextMessage(message, options, theme) {
|
|
|
127
124
|
},
|
|
128
125
|
};
|
|
129
126
|
}
|
|
130
|
-
// ---------------------------------------------------------------------------
|
|
131
127
|
// Extension
|
|
132
|
-
// ---------------------------------------------------------------------------
|
|
133
128
|
/** Register new-context baseline assembly; a strict resume changes nothing. */
|
|
134
129
|
export function registerCanvasContextIntro(pi) {
|
|
135
130
|
// Collapse the block to a one-liner until the user expands tool output (Ctrl+O).
|
|
136
131
|
// Harmless to register outside TUI mode (it's only consulted while rendering).
|
|
137
132
|
pi.registerMessageRenderer(CONTEXT_INTRO_CUSTOM_TYPE, renderContextMessage);
|
|
138
133
|
pi.on('session_start', async (event, ctx) => {
|
|
139
|
-
const nodeId =
|
|
134
|
+
const nodeId = envNodeId();
|
|
140
135
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
141
136
|
return;
|
|
142
137
|
const reason = event?.reason;
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// Plain TS-with-types — NO imports from @earendil-works/* (a local structural
|
|
15
15
|
// PiLike interface stands in), so it compiles inside crouter's own tsc build
|
|
16
16
|
// with no dep on the pi packages. Mirrors canvas-context-intro.ts.
|
|
17
|
+
import { envNodeId } from '../shared/env.js';
|
|
17
18
|
import { homedir } from 'node:os';
|
|
18
19
|
import { join, resolve } from 'node:path';
|
|
19
20
|
import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
@@ -22,9 +23,7 @@ import { corpusHasPreCommandSurfaces, demotePreCommandExposures, renderOnCommand
|
|
|
22
23
|
import { clearSessionCache } from '../core/substrate/session-cache.js';
|
|
23
24
|
import { cloneContextExposureState, exposureTarget, freezePreferenceSnapshot, loadContextExposureState, mergeContextExposureState, replaceContextExposureState, saveContextExposureState, sharedContextExposureState, } from '../core/substrate/injected-store.js';
|
|
24
25
|
import { autoLoadedContextInner, mergeAutoLoadedContext } from './envelope-merge.js';
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
26
|
// Extension
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
27
|
/** The stable seam that closes pi's native "Available tools" list. We splice the
|
|
29
28
|
* substrate's boot sections right before it — the agent decides which capability
|
|
30
29
|
* to reach for while reading the tools, so memory docs/preferences must sit
|
|
@@ -63,7 +62,7 @@ const HELD_SIBLING_REASON = [
|
|
|
63
62
|
'Read it, then re-issue your WHOLE command unchanged. The re-issue executes.',
|
|
64
63
|
].join('\n');
|
|
65
64
|
export function registerCanvasDocSubstrate(pi) {
|
|
66
|
-
const nodeId =
|
|
65
|
+
const nodeId = envNodeId();
|
|
67
66
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
68
67
|
return; // not a canvas node — inert
|
|
69
68
|
// One in-place state object is shared with context-intro and rehydrated on a
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
//
|
|
30
30
|
// Plain TS-with-types — no imports from @earendil-works/* so this compiles inside
|
|
31
31
|
// crouter's own tsc build without a dep on the pi packages.
|
|
32
|
+
import { envNodeId } from '../shared/env.js';
|
|
32
33
|
import { captureGoalIfAbsent, generateAndCommitInitialName, } from './broker-local.js';
|
|
33
34
|
import { parseCard } from '../shared/generated-context.js';
|
|
34
35
|
/**
|
|
@@ -41,7 +42,7 @@ import { parseCard } from '../shared/generated-context.js';
|
|
|
41
42
|
export function registerCanvasGoalCapture(pi) {
|
|
42
43
|
pi.on('input', (event) => {
|
|
43
44
|
try {
|
|
44
|
-
const nodeId =
|
|
45
|
+
const nodeId = envNodeId();
|
|
45
46
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
46
47
|
return; // not a canvas node
|
|
47
48
|
const text = (event.text ?? '').trim();
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// trigger, so the agent cannot run on context alone before hearing the person.
|
|
12
12
|
// A context-only batch keeps its wake by triggering on its LAST card while idle,
|
|
13
13
|
// and rides the running turn while streaming.
|
|
14
|
+
import { envNodeId, envProfileId, envWatcherDebounceMs, envWatcherTickMs } from '../shared/env.js';
|
|
14
15
|
import { coalesceBrokerInbox, entryCards, readBrokerCanceledEntryIds, readBrokerCursor, readBrokerInboxSince, reportRefNodeId, } from '../core/runtime/broker/inbox.js';
|
|
15
16
|
import { advanceBrokerInboxCursor, brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
16
17
|
import { emitEvent } from '../core/events/emit.js';
|
|
@@ -18,8 +19,6 @@ import { errorClassFromError } from '../core/events/errors.js';
|
|
|
18
19
|
import { operationIdContext } from '../core/events/operation-id.js';
|
|
19
20
|
import { situationalContextEnvelope, SITUATIONAL_CONTEXT_CUSTOM_TYPE } from '../core/runtime/situational-context.js';
|
|
20
21
|
import { isProfilePaused } from '../core/profiles/manifest.js';
|
|
21
|
-
const DEFAULT_TICK_MS = 800;
|
|
22
|
-
const DEFAULT_DEBOUNCE_MS = 1000;
|
|
23
22
|
const MAX_PENDING_HANDOFFS = 64;
|
|
24
23
|
const MAX_SOURCE_OPERATION_IDS = 16;
|
|
25
24
|
let currentWatcher;
|
|
@@ -31,26 +30,20 @@ class WatcherFatalError extends Error {
|
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
function resolveCadence() {
|
|
34
|
-
const parse = (raw, fallback) => {
|
|
35
|
-
if (raw === undefined)
|
|
36
|
-
return fallback;
|
|
37
|
-
const value = Number(raw);
|
|
38
|
-
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
39
|
-
};
|
|
40
33
|
return {
|
|
41
|
-
tickMs:
|
|
42
|
-
debounceMs:
|
|
34
|
+
tickMs: envWatcherTickMs(),
|
|
35
|
+
debounceMs: envWatcherDebounceMs(),
|
|
43
36
|
};
|
|
44
37
|
}
|
|
45
38
|
function currentNodeId() {
|
|
46
|
-
const nodeId =
|
|
39
|
+
const nodeId = envNodeId();
|
|
47
40
|
return nodeId === undefined || nodeId.trim() === '' ? undefined : nodeId;
|
|
48
41
|
}
|
|
49
42
|
/** The node's profile, read fresh each poll: `crtr profile pause` mutates the
|
|
50
43
|
* manifest file directly, so a live broker sees the flip on its next tick with
|
|
51
44
|
* no daemon round-trip. '' is the historical no-profile row. */
|
|
52
45
|
function profilePaused() {
|
|
53
|
-
const profileId =
|
|
46
|
+
const profileId = envProfileId();
|
|
54
47
|
return profileId !== undefined && profileId !== '' && isProfilePaused(profileId);
|
|
55
48
|
}
|
|
56
49
|
function isFilesystemError(error) {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
//
|
|
19
19
|
// Plain TS-with-types — no imports from @earendil-works/* so this compiles inside
|
|
20
20
|
// crouter's own tsc build without a dep on the pi packages.
|
|
21
|
+
import { envNodeId } from '../shared/env.js';
|
|
21
22
|
import { existsSync, readFileSync } from 'node:fs';
|
|
22
23
|
import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
23
24
|
import { reportPathFromRef } from '../core/runtime/broker-extension-render.js';
|
|
@@ -26,9 +27,7 @@ import { parseCard } from '../shared/generated-context.js';
|
|
|
26
27
|
// Per-entry body cap so a single fat report can't blow the context budget. The
|
|
27
28
|
// full report stays on disk at `ref` if the agent needs more.
|
|
28
29
|
const BODY_CAP = 4_000;
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
30
|
// Report dereference — turn a passive pointer into the message text it carries.
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
31
|
/** Strip the leading YAML frontmatter block a report is written with, returning
|
|
33
32
|
* just the body. Tolerant: no frontmatter → returns the input unchanged. */
|
|
34
33
|
function stripFrontmatter(raw) {
|
|
@@ -126,9 +125,7 @@ export function placeBacklog(text, preText) {
|
|
|
126
125
|
const bodyStart = text.length - card.body.length - CARD_CLOSE.length;
|
|
127
126
|
return `${text.slice(0, bodyStart)}${preText}\n${text.slice(bodyStart)}`;
|
|
128
127
|
}
|
|
129
|
-
// ---------------------------------------------------------------------------
|
|
130
128
|
// Extension
|
|
131
|
-
// ---------------------------------------------------------------------------
|
|
132
129
|
/**
|
|
133
130
|
* Register the passive-context drain on `pi`.
|
|
134
131
|
*
|
|
@@ -138,7 +135,7 @@ export function placeBacklog(text, preText) {
|
|
|
138
135
|
export function registerCanvasPassiveContext(pi) {
|
|
139
136
|
pi.on('input', async (event) => {
|
|
140
137
|
try {
|
|
141
|
-
const nodeId =
|
|
138
|
+
const nodeId = envNodeId();
|
|
142
139
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
143
140
|
return; // not a canvas node
|
|
144
141
|
const drained = drainBrokerPassive(nodeId);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// mirrors its record there, and this hook attaches the record to Pi's
|
|
7
7
|
// ToolResult.details. The attach viewer can render a structured preview
|
|
8
8
|
// without parsing the agent-facing text.
|
|
9
|
+
import { envNodeId } from '../shared/env.js';
|
|
9
10
|
import { existsSync, readFileSync, rmSync } from 'node:fs';
|
|
10
11
|
import { previewResultPath } from '../core/preview-result-path.js';
|
|
11
12
|
function isPreviewRecord(value) {
|
|
@@ -19,7 +20,7 @@ function isPreviewRecord(value) {
|
|
|
19
20
|
/** Loaded into every canvas broker. Plain Pi sessions have no node id and
|
|
20
21
|
* deliberately receive no filesystem transport. */
|
|
21
22
|
export function registerCanvasPreviewResult(pi) {
|
|
22
|
-
if (
|
|
23
|
+
if (envNodeId() === undefined || envNodeId() === '')
|
|
23
24
|
return;
|
|
24
25
|
pi.on('tool_result', (event) => {
|
|
25
26
|
if (event.toolName !== 'bash')
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
//
|
|
24
24
|
// Every rule below is anchored to pi's exact wording and degrades to a no-op if
|
|
25
25
|
// pi rewords, so a pi upgrade can never break a turn here.
|
|
26
|
+
import { envNodeId } from '../shared/env.js';
|
|
26
27
|
const PI_IDENTITY = 'You are an expert coding assistant operating inside pi, a coding agent harness.';
|
|
27
28
|
const NEUTRAL_IDENTITY = 'You are an expert coding assistant.';
|
|
28
29
|
const PI_DOCS_MARKER = 'Pi documentation (read only';
|
|
@@ -40,7 +41,7 @@ export function scrubPromptSelfReference(systemPrompt) {
|
|
|
40
41
|
}
|
|
41
42
|
/** Register the system-prompt scrub for a canvas node. */
|
|
42
43
|
export function registerCanvasPromptScrub(pi) {
|
|
43
|
-
const nodeId =
|
|
44
|
+
const nodeId = envNodeId();
|
|
44
45
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
45
46
|
return;
|
|
46
47
|
pi.on('before_agent_start', (event) => {
|
|
@@ -38,20 +38,17 @@
|
|
|
38
38
|
//
|
|
39
39
|
// Plain TS-with-types — no imports from @earendil-works/* so this compiles
|
|
40
40
|
// inside crouter's own tsc build without a dep on the pi packages.
|
|
41
|
+
import { envNodeId, envRecapIdleMs } from '../shared/env.js';
|
|
41
42
|
import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
42
43
|
import { generateRecap } from '../core/runtime/recap.js';
|
|
43
44
|
import { isReviewBoundary } from '../core/runtime/session-visibility.js';
|
|
44
45
|
import { editorLabelForBrokerNode } from '../core/runtime/broker-extension-render.js';
|
|
45
46
|
import { generateAndCommitRecapName, readRoadmap } from './broker-local.js';
|
|
46
|
-
// ---------------------------------------------------------------------------
|
|
47
47
|
// Tuning constants
|
|
48
|
-
// ---------------------------------------------------------------------------
|
|
49
48
|
/** No-new-message window before a recap is shown. 60s by default; override with
|
|
50
49
|
* CRTR_RECAP_IDLE_MS (for fast runtime verification). */
|
|
51
50
|
function idleMs() {
|
|
52
|
-
|
|
53
|
-
const n = raw !== undefined ? parseInt(raw, 10) : NaN;
|
|
54
|
-
return Number.isFinite(n) && n > 0 ? n : 60_000;
|
|
51
|
+
return envRecapIdleMs();
|
|
55
52
|
}
|
|
56
53
|
/** How often the single low-rate timer checks elapsed-since-last-message. */
|
|
57
54
|
const POLL_MS = 7_000;
|
|
@@ -62,14 +59,10 @@ const CONVO_EDGE_MESSAGES = 5;
|
|
|
62
59
|
* (10 messages × this ≈ the total budget the model needs for the gist). */
|
|
63
60
|
const MESSAGE_CHAR_BUDGET = 1_200;
|
|
64
61
|
const WIDGET_KEY = 'crtr-recap';
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
62
|
// Module-level state — persists across /reload so the timer doesn't stack.
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
63
|
/** The one live poll timer. Cleared and replaced on every re-registration. */
|
|
69
64
|
let liveTimer;
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
65
|
// Conversation extraction — literal user+assistant text ONLY.
|
|
72
|
-
// ---------------------------------------------------------------------------
|
|
73
66
|
/** Pull the literal text out of a message's content (string or text blocks),
|
|
74
67
|
* dropping non-text blocks (thinking, toolCall, image). */
|
|
75
68
|
function messageText(msg) {
|
|
@@ -162,9 +155,7 @@ function buildNamingConversation(sm, assistantPartial, reviewId) {
|
|
|
162
155
|
});
|
|
163
156
|
return sampled.join('\n\n');
|
|
164
157
|
}
|
|
165
|
-
// ---------------------------------------------------------------------------
|
|
166
158
|
// Extension
|
|
167
|
-
// ---------------------------------------------------------------------------
|
|
168
159
|
/**
|
|
169
160
|
* Register the inactivity-recap chrome on `pi`.
|
|
170
161
|
*
|
|
@@ -172,7 +163,7 @@ function buildNamingConversation(sm, assistantPartial, reviewId) {
|
|
|
172
163
|
* or legacy job agent loads it as a no-op.
|
|
173
164
|
*/
|
|
174
165
|
export function registerCanvasRecap(pi, recapGenerator = generateRecap, nameRegenerator) {
|
|
175
|
-
const nodeId =
|
|
166
|
+
const nodeId = envNodeId();
|
|
176
167
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
177
168
|
return; // not a canvas node
|
|
178
169
|
// Captured on session_start; used by the timer and the message handlers.
|
|
@@ -344,9 +335,7 @@ export function registerCanvasRecap(pi, recapGenerator = generateRecap, nameRege
|
|
|
344
335
|
requestRecap(true);
|
|
345
336
|
},
|
|
346
337
|
});
|
|
347
|
-
// -------------------------------------------------------------------------
|
|
348
338
|
// Events
|
|
349
|
-
// -------------------------------------------------------------------------
|
|
350
339
|
pi.on('session_start', (_event, ctx) => {
|
|
351
340
|
ui = ctx.ui;
|
|
352
341
|
sessionManager = ctx.sessionManager;
|
|
@@ -382,9 +371,7 @@ export function registerCanvasRecap(pi, recapGenerator = generateRecap, nameRege
|
|
|
382
371
|
captureLiveModel(ctx);
|
|
383
372
|
onMessage();
|
|
384
373
|
});
|
|
385
|
-
// -------------------------------------------------------------------------
|
|
386
374
|
// The single low-rate idle poll.
|
|
387
|
-
// -------------------------------------------------------------------------
|
|
388
375
|
if (liveTimer !== undefined)
|
|
389
376
|
clearInterval(liveTimer);
|
|
390
377
|
const timer = setInterval(() => {
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
// inherited fork context and before canvas-context-intro appends fork bearings.
|
|
5
5
|
// The display projection starts at this marker while the model keeps the full
|
|
6
6
|
// inherited context.
|
|
7
|
+
import { envNodeId } from '../shared/env.js';
|
|
7
8
|
import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
8
9
|
import { isReviewBoundary, REVIEW_BOUNDARY_CUSTOM_TYPE } from '../core/runtime/session-visibility.js';
|
|
9
10
|
import { formatCard, parseCard } from '../shared/generated-context.js';
|
|
10
11
|
import { truncateToWidth } from './truncate.js';
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
12
|
// Collapsed-by-default rendering
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
13
|
/** Render the marker as a single compact divider; its full content remains in
|
|
15
14
|
* the message list for the model and generated-context presenters. */
|
|
16
15
|
export function renderReviewBoundary(message, options, theme) {
|
|
@@ -32,9 +31,7 @@ export function renderReviewBoundary(message, options, theme) {
|
|
|
32
31
|
},
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
|
-
// ---------------------------------------------------------------------------
|
|
36
34
|
// Extension
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
35
|
/**
|
|
39
36
|
* Register the review boundary marker. Companion nodes receive one boundary
|
|
40
37
|
* marker on session_start that separates inherited context from the visible
|
|
@@ -43,7 +40,7 @@ export function renderReviewBoundary(message, options, theme) {
|
|
|
43
40
|
export function registerCanvasReviewBoundary(pi) {
|
|
44
41
|
pi.registerMessageRenderer(REVIEW_BOUNDARY_CUSTOM_TYPE, renderReviewBoundary);
|
|
45
42
|
pi.on('session_start', async (_event, ctx) => {
|
|
46
|
-
const nodeId =
|
|
43
|
+
const nodeId = envNodeId();
|
|
47
44
|
if (!nodeId || nodeId.trim() === '')
|
|
48
45
|
return;
|
|
49
46
|
let node;
|