@north-light/crouter 0.3.233 → 0.3.235
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/api/dto/nodes.d.ts +11 -0
- 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 +535 -537
- 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 +1 -9
- 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 +10 -23
- 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/human.js +1 -1
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +4 -4
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +1 -0
- package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +96 -0
- package/dist/commands/memory/delete.js +1 -1
- package/dist/commands/memory/edit.js +6 -3
- package/dist/commands/memory/find.js +2 -2
- package/dist/commands/memory/lint.js +2 -1
- package/dist/commands/memory/list.d.ts +4 -0
- package/dist/commands/memory/list.js +20 -14
- package/dist/commands/memory/move.js +1 -1
- package/dist/commands/memory/read.d.ts +2 -7
- package/dist/commands/memory/read.js +5 -16
- package/dist/commands/memory/shared.d.ts +1 -0
- package/dist/commands/memory/shared.js +17 -8
- package/dist/commands/memory/write.js +8 -4
- package/dist/commands/node/bash.js +2 -1
- package/dist/commands/node/create.js +2 -1
- package/dist/commands/node/inspect.js +11 -10
- package/dist/commands/node/lifecycle.js +5 -13
- package/dist/commands/node/message.js +11 -6
- package/dist/commands/node/subscription.js +7 -2
- package/dist/commands/node/wait.js +9 -4
- 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 +3 -2
- package/dist/commands/pkg/shared.js +0 -2
- package/dist/commands/pkg.js +1 -0
- package/dist/commands/profile/delete.js +2 -1
- package/dist/commands/profile/rename.js +1 -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 +1 -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/commands/sys.js +1 -0
- 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__/cli-help-contract.test.d.ts +1 -0
- package/dist/core/__tests__/cli-help-contract.test.js +150 -0
- 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 +21 -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/__tests__/watchdog-abort-arms-retry.test.js +11 -6
- 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 +61 -19
- 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/meta-file.js +18 -27
- 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.d.ts +8 -0
- package/dist/core/canvas/remote-canvas-source.js +9 -3
- package/dist/core/canvas/render-source.js +31 -13
- package/dist/core/command-manifests/manifest.js +0 -10
- package/dist/core/command-manifests/registry.d.ts +2 -0
- package/dist/core/command-manifests/schema.js +0 -4
- package/dist/core/command-plugins/compose.js +4 -2
- package/dist/core/command-plugins/discovery.d.ts +1 -0
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command-plugins/transport/http-invoke.js +0 -14
- package/dist/core/command.js +2 -6
- package/dist/core/config.js +2 -1
- package/dist/core/fault-classifier.js +8 -0
- 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.d.ts +2 -0
- package/dist/core/pagination.js +2 -3
- 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 +11 -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/rebind.js +50 -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.d.ts +2 -2
- package/dist/core/runtime/launch.js +20 -10
- 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/stop-guard.js +28 -16
- 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/frontmatter-validation.d.ts +1 -0
- package/dist/core/substrate/frontmatter-validation.js +1 -1
- 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__/error-seam.test.js +27 -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 +16 -20
- package/dist/daemon/api/handlers/nodes.js +23 -22
- package/dist/daemon/api/handlers/reports.js +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -6
- package/dist/daemon/api/handlers/worktree.js +6 -22
- package/dist/daemon/api/map.d.ts +4 -2
- package/dist/daemon/api/map.js +22 -8
- 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 +27 -30
- 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 +7 -20
- 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
package/dist/core/fs-utils.d.ts
CHANGED
|
@@ -5,8 +5,15 @@ export declare function realpathOrSelf(p: string): string;
|
|
|
5
5
|
export declare function expandTilde(p: string, homeDir?: string): string;
|
|
6
6
|
export declare function ensureDir(dir: string): void;
|
|
7
7
|
export declare function writeJson(path: string, data: unknown): void;
|
|
8
|
-
export
|
|
9
|
-
|
|
8
|
+
export interface AtomicWriteOptions {
|
|
9
|
+
/** Force this mode regardless of any existing file's mode. Omitted: preserve the existing file's mode, or default a new file to `0o600`. */
|
|
10
|
+
mode?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function atomicWriteJson(path: string, data: unknown, opts?: AtomicWriteOptions): void;
|
|
13
|
+
/** Replace one file's contents in a single rename, so a concurrent reader — the
|
|
14
|
+
* tmux inbox watcher, or crtrd serving a ticket read — sees either the old
|
|
15
|
+
* bytes or the new ones and never a truncated file mid-write. */
|
|
16
|
+
export declare function atomicWriteText(path: string, content: string | Uint8Array, opts?: AtomicWriteOptions): void;
|
|
10
17
|
export declare function readJson<T = unknown>(path: string): T;
|
|
11
18
|
export declare function readJsonIfExists<T = unknown>(path: string): T | null;
|
|
12
19
|
/** Missing or corrupt reads as absent, so a crash artifact never throws. */
|
package/dist/core/fs-utils.js
CHANGED
|
@@ -26,24 +26,16 @@ export function writeJson(path, data) {
|
|
|
26
26
|
ensureDir(dirname(path));
|
|
27
27
|
writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
28
28
|
}
|
|
29
|
-
export function atomicWriteJson(path, data) {
|
|
30
|
-
|
|
31
|
-
const temp = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
32
|
-
const mode = existsSync(path) ? statSync(path).mode & 0o777 : 0o600;
|
|
33
|
-
try {
|
|
34
|
-
writeFileSync(temp, JSON.stringify(data, null, 2) + '\n', { encoding: 'utf8', mode });
|
|
35
|
-
chmodSync(temp, mode);
|
|
36
|
-
renameSync(temp, path);
|
|
37
|
-
}
|
|
38
|
-
finally {
|
|
39
|
-
if (existsSync(temp))
|
|
40
|
-
rmSync(temp, { force: true });
|
|
41
|
-
}
|
|
29
|
+
export function atomicWriteJson(path, data, opts) {
|
|
30
|
+
atomicWriteText(path, JSON.stringify(data, null, 2) + '\n', opts);
|
|
42
31
|
}
|
|
43
|
-
|
|
32
|
+
/** Replace one file's contents in a single rename, so a concurrent reader — the
|
|
33
|
+
* tmux inbox watcher, or crtrd serving a ticket read — sees either the old
|
|
34
|
+
* bytes or the new ones and never a truncated file mid-write. */
|
|
35
|
+
export function atomicWriteText(path, content, opts) {
|
|
44
36
|
ensureDir(dirname(path));
|
|
45
37
|
const temp = `${path}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
46
|
-
const mode = existsSync(path) ? statSync(path).mode & 0o777 : 0o600;
|
|
38
|
+
const mode = opts?.mode ?? (existsSync(path) ? statSync(path).mode & 0o777 : 0o600);
|
|
47
39
|
try {
|
|
48
40
|
writeFileSync(temp, content, { mode });
|
|
49
41
|
chmodSync(temp, mode);
|
package/dist/core/help.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
// Pure functions — no side effects, no commander, no process.exit.
|
|
3
3
|
// Rendering matches reference.md shapes exactly:
|
|
4
4
|
// root L11-32, branch L43-58, leaf L65-189.
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
5
|
// Internal helpers
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
6
|
/** Build a self-named runtime-state element: `<tag attr="v">body</tag>`. The
|
|
9
7
|
* subtree that owns the state authors it through this, so the tag name and any
|
|
10
8
|
* scalar metadata (e.g. a count) travel with the data and render identically
|
|
@@ -42,9 +40,7 @@ function maxLen(names) {
|
|
|
42
40
|
function pad(s, width) {
|
|
43
41
|
return s + ' '.repeat(Math.max(0, width - s.length));
|
|
44
42
|
}
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
43
|
// renderRoot
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
44
|
const IO_CONTRACT = 'I/O contract: flags and positional args on input; stdout is agent-ready markdown/XML you\n' +
|
|
49
45
|
'act on directly — read it as a continuation of your prompt, don\'t parse it as data.\n' +
|
|
50
46
|
'Exit 0 on success, non-zero on failure. Schemas appear at leaf -h; a leaf may route an uncommon flag to focused --flag -h guidance.';
|
|
@@ -132,9 +128,7 @@ export function renderRoot(h) {
|
|
|
132
128
|
lines.push(CAPABILITY_DISCOVERY);
|
|
133
129
|
return lines.join('\n');
|
|
134
130
|
}
|
|
135
|
-
// ---------------------------------------------------------------------------
|
|
136
131
|
// renderBranch
|
|
137
|
-
// ---------------------------------------------------------------------------
|
|
138
132
|
/** Escape a value for a rendered XML attribute. Output is light XML around
|
|
139
133
|
* markdown read as prose by a model, not parsed — so we only guard the
|
|
140
134
|
* double-quote that would visually break the attribute, swapping it for a
|
|
@@ -170,9 +164,7 @@ export function renderBranch(h) {
|
|
|
170
164
|
lines.push('</command>');
|
|
171
165
|
return lines.join('\n');
|
|
172
166
|
}
|
|
173
|
-
// ---------------------------------------------------------------------------
|
|
174
167
|
// renderLeafArgv
|
|
175
|
-
// ---------------------------------------------------------------------------
|
|
176
168
|
/** Build the display label for a param entry (left column). */
|
|
177
169
|
function paramLabel(p) {
|
|
178
170
|
if (p.kind === 'positional')
|
|
@@ -20,8 +20,8 @@ import type { RootDef } from '../command.js';
|
|
|
20
20
|
export declare function writeIfOurs(path: string, content: string, markerPrefix: string): void;
|
|
21
21
|
/** Render and write every built-in export artifact to every present host, while
|
|
22
22
|
* pruning legacy generated artifacts that should no longer be surfaced.
|
|
23
|
-
* Best-effort:
|
|
24
|
-
*
|
|
23
|
+
* Best-effort: reports errors without breaking an unrelated `crtr` command.
|
|
24
|
+
* Kill switch: `CRTR_NO_EXPORTS=1`. */
|
|
25
25
|
export declare function pruneLegacyExports(argv?: string[]): void;
|
|
26
26
|
/** Write every built-in export artifact to every present host. Split from the
|
|
27
27
|
* prune above because the prune must run BEFORE the front door boots (stale
|
|
@@ -16,6 +16,7 @@ import { writeFileSync } from 'node:fs';
|
|
|
16
16
|
import { homedir } from 'node:os';
|
|
17
17
|
import { dirname, join } from 'node:path';
|
|
18
18
|
import { ensureDir, pathExists, readText, removePath } from '../fs-utils.js';
|
|
19
|
+
import { envNoExports } from '../../shared/env.js';
|
|
19
20
|
import { builtinExportPairs, legacyExportArtifacts } from './builtins.js';
|
|
20
21
|
const SKIP_SUBCOMMANDS = new Set([
|
|
21
22
|
'help',
|
|
@@ -73,11 +74,11 @@ function removeIfOurs(path, target, markerPrefix) {
|
|
|
73
74
|
}
|
|
74
75
|
/** Render and write every built-in export artifact to every present host, while
|
|
75
76
|
* pruning legacy generated artifacts that should no longer be surfaced.
|
|
76
|
-
* Best-effort:
|
|
77
|
-
*
|
|
77
|
+
* Best-effort: reports errors without breaking an unrelated `crtr` command.
|
|
78
|
+
* Kill switch: `CRTR_NO_EXPORTS=1`. */
|
|
78
79
|
export function pruneLegacyExports(argv = process.argv) {
|
|
79
80
|
try {
|
|
80
|
-
if (
|
|
81
|
+
if (envNoExports())
|
|
81
82
|
return;
|
|
82
83
|
if (shouldSkipAllForArgv(argv))
|
|
83
84
|
return;
|
|
@@ -90,10 +91,8 @@ export function pruneLegacyExports(argv = process.argv) {
|
|
|
90
91
|
}
|
|
91
92
|
}
|
|
92
93
|
catch (e) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
process.stderr.write(`crtr: exports prune error: ${msg}\n`);
|
|
96
|
-
}
|
|
94
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
95
|
+
process.stderr.write(`crtr: exports prune error: ${msg}\n`);
|
|
97
96
|
}
|
|
98
97
|
}
|
|
99
98
|
/** Write every built-in export artifact to every present host. Split from the
|
|
@@ -103,7 +102,7 @@ export function pruneLegacyExports(argv = process.argv) {
|
|
|
103
102
|
* for building the full command tree just to reach a no-op. */
|
|
104
103
|
export function provisionExports(root, argv = process.argv) {
|
|
105
104
|
try {
|
|
106
|
-
if (
|
|
105
|
+
if (envNoExports())
|
|
107
106
|
return;
|
|
108
107
|
if (shouldSkipAllForArgv(argv))
|
|
109
108
|
return;
|
|
@@ -119,9 +118,7 @@ export function provisionExports(root, argv = process.argv) {
|
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
catch (e) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
process.stderr.write(`crtr: exports error: ${msg}\n`);
|
|
125
|
-
}
|
|
121
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
122
|
+
process.stderr.write(`crtr: exports error: ${msg}\n`);
|
|
126
123
|
}
|
|
127
124
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type PageCommentAnchor, type PageResponses, type PageSlot } from './page-schema.js';
|
|
2
2
|
export type PageAnswer = {
|
|
3
3
|
title: string;
|
|
4
4
|
subtitle?: string;
|
|
@@ -34,7 +34,7 @@ export type PageAnswerGroup = {
|
|
|
34
34
|
}[];
|
|
35
35
|
};
|
|
36
36
|
/** Stored responses predating the `whole` anchor's removal still carry it; answers keep rendering them. */
|
|
37
|
-
export type LegacyCommentAnchor =
|
|
37
|
+
export type LegacyCommentAnchor = PageCommentAnchor | {
|
|
38
38
|
kind: 'whole';
|
|
39
39
|
};
|
|
40
40
|
export type PageAnswerComment = {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { atomicWriteJson, atomicWriteText } from '../fs-utils.js';
|
|
2
|
+
export { atomicWriteJson, atomicWriteText };
|
|
1
3
|
/** The authored page source path, derived from the persisted dialect. */
|
|
2
4
|
export declare function pagePath(dir: string, dialect?: 'jsx' | 'html'): string;
|
|
3
5
|
/** The compiled module the Gateway evaluates for JSX pages. */
|
|
@@ -24,11 +26,6 @@ export declare function isResolved(dir: string): boolean;
|
|
|
24
26
|
export declare function isClaimed(dir: string): boolean;
|
|
25
27
|
/** Resolve and verify a ticket directory without a registry. */
|
|
26
28
|
export declare function requireTicket(dir: string): string;
|
|
27
|
-
/** Replace one file's contents in a single rename, so a concurrent reader —
|
|
28
|
-
* the tmux inbox watcher, or crtrd serving a ticket read — sees either the old
|
|
29
|
-
* bytes or the new ones and never a truncated file mid-write. */
|
|
30
|
-
export declare function atomicWriteText(path: string, contents: string): void;
|
|
31
|
-
export declare function atomicWriteJson(path: string, value: unknown): void;
|
|
32
29
|
/** Publish one immutable JSON record without replacing an existing winner. */
|
|
33
30
|
export declare function publishJsonExclusive(path: string, value: unknown): boolean;
|
|
34
31
|
export declare function clearProgress(dir: string): void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { existsSync, linkSync, mkdirSync, readFileSync, realpathSync,
|
|
1
|
+
import { existsSync, linkSync, mkdirSync, readFileSync, realpathSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
|
+
import { atomicWriteJson, atomicWriteText } from '../fs-utils.js';
|
|
4
|
+
export { atomicWriteJson, atomicWriteText };
|
|
3
5
|
/** The authored page source path, derived from the persisted dialect. */
|
|
4
6
|
export function pagePath(dir, dialect = 'jsx') { return `${dir}/page.${dialect === 'jsx' ? 'tsx' : 'html'}`; }
|
|
5
7
|
/** The compiled module the Gateway evaluates for JSX pages. */
|
|
@@ -51,18 +53,6 @@ export function requireTicket(dir) {
|
|
|
51
53
|
}
|
|
52
54
|
return canonicalDir;
|
|
53
55
|
}
|
|
54
|
-
/** Replace one file's contents in a single rename, so a concurrent reader —
|
|
55
|
-
* the tmux inbox watcher, or crtrd serving a ticket read — sees either the old
|
|
56
|
-
* bytes or the new ones and never a truncated file mid-write. */
|
|
57
|
-
export function atomicWriteText(path, contents) {
|
|
58
|
-
const tmp = `${path}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
59
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
60
|
-
writeFileSync(tmp, contents, { mode: 0o600 });
|
|
61
|
-
renameSync(tmp, path);
|
|
62
|
-
}
|
|
63
|
-
export function atomicWriteJson(path, value) {
|
|
64
|
-
atomicWriteText(path, `${JSON.stringify(value, null, 2)}\n`);
|
|
65
|
-
}
|
|
66
56
|
/** Publish one immutable JSON record without replacing an existing winner. */
|
|
67
57
|
export function publishJsonExclusive(path, value) {
|
|
68
58
|
const tmp = `${path}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
|
|
@@ -2,14 +2,14 @@ import { z } from 'zod';
|
|
|
2
2
|
import { BUILTIN_PAGE_KINDS } from './page-catalog.js';
|
|
3
3
|
import type { ProductPageComponents } from '../../types.js';
|
|
4
4
|
export declare const PAGE_SLOT_ID_PATTERN: RegExp;
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const pageCommentAnchorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6
6
|
kind: z.ZodLiteral<"option">;
|
|
7
7
|
optionId: z.ZodString;
|
|
8
8
|
}, z.core.$strict>, z.ZodObject<{
|
|
9
9
|
kind: z.ZodLiteral<"row">;
|
|
10
10
|
rowId: z.ZodString;
|
|
11
11
|
}, z.core.$strict>], "kind">;
|
|
12
|
-
export type
|
|
12
|
+
export type PageCommentAnchor = z.infer<typeof pageCommentAnchorSchema>;
|
|
13
13
|
export declare const commentSchema: z.ZodObject<{
|
|
14
14
|
id: z.ZodString;
|
|
15
15
|
anchor: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -17,11 +17,11 @@ function uniqueIds(items, ctx, label) {
|
|
|
17
17
|
// one of a question's options, or a table row. Feedback on rendered page content — including
|
|
18
18
|
// the question text itself — is a ticket-level feedback comment (feedback.ts), not part of
|
|
19
19
|
// any response.
|
|
20
|
-
export const
|
|
20
|
+
export const pageCommentAnchorSchema = z.discriminatedUnion('kind', [
|
|
21
21
|
z.object({ kind: z.literal('option'), optionId: itemIdSchema }).strict(),
|
|
22
22
|
z.object({ kind: z.literal('row'), rowId: itemIdSchema }).strict(),
|
|
23
23
|
]);
|
|
24
|
-
export const commentSchema = z.object({ id: z.string().min(1), anchor:
|
|
24
|
+
export const commentSchema = z.object({ id: z.string().min(1), anchor: pageCommentAnchorSchema, text: z.string() }).strict();
|
|
25
25
|
export const optionSchema = z.object({ id: itemIdSchema, label: z.string().min(1), description: z.string().optional(), recommended: z.boolean().optional() }).strict();
|
|
26
26
|
export const optionsConfigSchema = z.object({
|
|
27
27
|
label: z.string().optional(),
|
package/dist/core/human/root.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { realpathSync } from 'node:fs';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { nodeDir, nodesRoot } from '../canvas/paths.js';
|
|
4
|
+
import { activityPath, signalActivity, watchActivity } from '../activity-signal.js';
|
|
5
5
|
export function ticketsRoot() {
|
|
6
6
|
return nodesRoot();
|
|
7
7
|
}
|
|
@@ -17,29 +17,12 @@ export function ticketDir(ticketId) {
|
|
|
17
17
|
return nodeDir(ticketId);
|
|
18
18
|
}
|
|
19
19
|
export function inboxActivityPath() {
|
|
20
|
-
return
|
|
20
|
+
return activityPath('inbox-activity');
|
|
21
21
|
}
|
|
22
22
|
/** Signal one durable ticket mutation to every open inbox without watching every ticket directory. */
|
|
23
23
|
export function signalInboxActivity() {
|
|
24
|
-
|
|
25
|
-
mkdirSync(dirname(inboxActivityPath()), { recursive: true, mode: 0o700 });
|
|
26
|
-
writeFileSync(inboxActivityPath(), `${Date.now()}\n`, { mode: 0o600 });
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
// A later inbox scan is still authoritative.
|
|
30
|
-
}
|
|
24
|
+
signalActivity('inbox-activity');
|
|
31
25
|
}
|
|
32
26
|
export function watchInboxActivity(onChange) {
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
mkdirSync(dirname(activityPath), { recursive: true, mode: 0o700 });
|
|
36
|
-
const watcher = watch(dirname(activityPath), (_event, filename) => {
|
|
37
|
-
if (String(filename) === basename(activityPath))
|
|
38
|
-
onChange();
|
|
39
|
-
});
|
|
40
|
-
return () => watcher.close();
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return () => { };
|
|
44
|
-
}
|
|
27
|
+
return watchActivity('inbox-activity', onChange);
|
|
45
28
|
}
|
package/dist/core/human/scan.js
CHANGED
|
@@ -7,6 +7,10 @@ import { pageAwaitsResponse, pageOverviewActions } from './page-schema.js';
|
|
|
7
7
|
import { parsePage } from './page.js';
|
|
8
8
|
import { pageTicketState, readTicketResult } from './tickets.js';
|
|
9
9
|
import { ticketsRoot } from './root.js';
|
|
10
|
+
import { emitEvent } from '../events/emit.js';
|
|
11
|
+
function errorText(error) {
|
|
12
|
+
return error instanceof Error ? error.message : String(error);
|
|
13
|
+
}
|
|
10
14
|
function claimSummary(dir) {
|
|
11
15
|
const claim = readJsonOrNull(claimPath(dir));
|
|
12
16
|
if (claim === null || typeof claim.host !== 'string' || typeof claim.claimedAt !== 'string' || typeof claim.heartbeatAt !== 'string')
|
|
@@ -94,7 +98,14 @@ export function scanInbox() {
|
|
|
94
98
|
}
|
|
95
99
|
if (isResolved(dir))
|
|
96
100
|
continue;
|
|
97
|
-
|
|
101
|
+
let item;
|
|
102
|
+
try {
|
|
103
|
+
item = reviewSummary(dir, basename(dir)) ?? pageSummary(dir, basename(dir));
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
emitEvent({ level: 'warn', event: 'human.scan.ticket_unreadable', fields: { ticket_id: basename(dir), error: errorText(error) } });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
98
109
|
if (item !== null && (item.kind !== 'page' || item.inbox))
|
|
99
110
|
items.push(item);
|
|
100
111
|
}
|
|
@@ -124,13 +135,19 @@ export function scanPageHistory(nodeId) {
|
|
|
124
135
|
catch {
|
|
125
136
|
continue;
|
|
126
137
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
try {
|
|
139
|
+
const summary = pageSummary(dir, basename(dir));
|
|
140
|
+
if (summary === null)
|
|
141
|
+
continue;
|
|
142
|
+
if (nodeId !== undefined && summary.source.nodeId !== nodeId)
|
|
143
|
+
continue;
|
|
144
|
+
const result = summary.state === 'resolved' ? readTicketResult(dir) : null;
|
|
145
|
+
items.push({ ...summary, ...(result?.kind === 'page' ? { answerDigest: result.summary.replace(/\s+/g, ' ').trim() } : {}) });
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
emitEvent({ level: 'warn', event: 'human.scan.ticket_unreadable', fields: { ticket_id: basename(dir), error: errorText(error) } });
|
|
131
149
|
continue;
|
|
132
|
-
|
|
133
|
-
items.push({ ...summary, ...(result?.kind === 'page' ? { answerDigest: result.summary.replace(/\s+/g, ' ').trim() } : {}) });
|
|
150
|
+
}
|
|
134
151
|
}
|
|
135
152
|
return items.sort((a, b) => Date.parse(a.emittedAt) - Date.parse(b.emittedAt) || a.id.localeCompare(b.id));
|
|
136
153
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { ReviewDescriptor, TicketResult } from './types.js';
|
|
2
2
|
import type { ProductPageComponents } from '../../types.js';
|
|
3
3
|
import { type PageDelivery, type PageManifest, type PageResponses, type PageSource } from './page-schema.js';
|
|
4
|
-
/** Strict decoder for the only canonical final marker.
|
|
4
|
+
/** Strict decoder for the only canonical final marker. Only a missing file reads
|
|
5
|
+
* as absent — a corrupt (unparseable) response is a real anomaly and throws,
|
|
6
|
+
* since silently treating it as "no result yet" would mask data loss instead
|
|
7
|
+
* of surfacing it to whichever caller owns the failure boundary. */
|
|
5
8
|
export declare function readTicketResult(dir: string): TicketResult | null;
|
|
6
9
|
export interface SubmitPageOptions {
|
|
7
10
|
dir: string;
|
|
@@ -27,14 +27,20 @@ const pageResultSchema = z.object({ schema: z.literal('crtr.page-response/v1'),
|
|
|
27
27
|
const pageProgressSchema = z.object({ kind: z.literal('page'), responses: z.record(z.string(), slotResponseSchema), savedAt: iso }).strict();
|
|
28
28
|
const reviewResultSchema = z.object({ schema: z.literal('humanloop.review-response/v1'), kind: z.literal('review'), result: feedbackSchema, completedAt: iso }).strict();
|
|
29
29
|
const canceledResultSchema = z.object({ schema: z.literal('humanloop.cancel/v1'), kind: z.literal('canceled'), canceledAt: iso, reason: z.string().optional(), actor: z.string().optional(), disposition: z.enum(['canceled', 'dismissed']).optional() }).strict();
|
|
30
|
-
/** Strict decoder for the only canonical final marker.
|
|
30
|
+
/** Strict decoder for the only canonical final marker. Only a missing file reads
|
|
31
|
+
* as absent — a corrupt (unparseable) response is a real anomaly and throws,
|
|
32
|
+
* since silently treating it as "no result yet" would mask data loss instead
|
|
33
|
+
* of surfacing it to whichever caller owns the failure boundary. */
|
|
31
34
|
export function readTicketResult(dir) {
|
|
35
|
+
const path = responsePath(dir);
|
|
36
|
+
if (!existsSync(path))
|
|
37
|
+
return null;
|
|
32
38
|
let raw;
|
|
33
39
|
try {
|
|
34
|
-
raw = JSON.parse(readFileSync(
|
|
40
|
+
raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
35
41
|
}
|
|
36
|
-
catch {
|
|
37
|
-
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw new Error(`corrupt ticket result: ${path}`, { cause: error });
|
|
38
44
|
}
|
|
39
45
|
const page = pageResultSchema.safeParse(raw);
|
|
40
46
|
if (page.success)
|
|
@@ -246,7 +252,10 @@ function completePageLocked(dir, responses, claimToken, opts) {
|
|
|
246
252
|
const result = { schema: 'crtr.page-response/v1', kind: 'page', responses: parsedResponses, summary: buildPageSummary(manifest, parsedResponses), completedAt: opts.completedAt ?? new Date().toISOString(), ...(opts.actor === undefined ? {} : { actor: opts.actor }) };
|
|
247
253
|
const won = exclusiveResult(dir, result);
|
|
248
254
|
clearOwnedWork(dir, claimToken);
|
|
249
|
-
|
|
255
|
+
// Lost the race: the winner's result must already be on disk, so a null read
|
|
256
|
+
// here is an anomaly worth surfacing rather than silently falling back to
|
|
257
|
+
// this loser's own uncommitted result.
|
|
258
|
+
return { won, result: won ? result : (readTicketResult(dir) ?? (() => { throw new Error(`lost the completion race but no winning result is on disk: ${dir}`); })()) };
|
|
250
259
|
}
|
|
251
260
|
export function completePage(dir, responses, claimToken, opts = {}) {
|
|
252
261
|
const ticket = requireTicket(dir);
|
|
@@ -288,7 +297,12 @@ export function cancelTicket(dir, opts = {}) {
|
|
|
288
297
|
requireCancelablePage(ticket);
|
|
289
298
|
const result = { schema: 'humanloop.cancel/v1', kind: 'canceled', canceledAt: new Date().toISOString(), ...(opts.reason === undefined ? {} : { reason: opts.reason }), ...(opts.actor === undefined ? {} : { actor: opts.actor }), ...(opts.disposition === undefined ? {} : { disposition: opts.disposition }) };
|
|
290
299
|
const won = exclusiveResult(ticket, result);
|
|
291
|
-
|
|
300
|
+
// Same anomaly as completePageLocked: losing the race with no winning
|
|
301
|
+
// result on disk means the ticket state is broken, not just contended.
|
|
302
|
+
return {
|
|
303
|
+
status: won ? 'canceled' : 'already_resolved',
|
|
304
|
+
result: won ? result : (readTicketResult(ticket) ?? (() => { throw new Error(`lost the cancellation race but no winning result is on disk: ${ticket}`); })()),
|
|
305
|
+
};
|
|
292
306
|
});
|
|
293
307
|
if (canceled.status === 'canceled')
|
|
294
308
|
signalInboxActivity();
|
package/dist/core/io.js
CHANGED
|
@@ -9,9 +9,7 @@ import { ExitCode } from '../types.js';
|
|
|
9
9
|
import { PREVIEW_RESULT_PATH_ENV } from './preview-result-path.js';
|
|
10
10
|
import { renderError } from './render.js';
|
|
11
11
|
import { ApiError } from '../api/index.js';
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
12
|
// output mode — prose (default) vs raw JSON (--json global, for tooling)
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
13
|
let jsonOutput = false;
|
|
16
14
|
let preview;
|
|
17
15
|
/** A preview is bounded UI metadata, never a bulk-data channel. One
|
|
@@ -98,9 +96,7 @@ export class InputError extends CrtrError {
|
|
|
98
96
|
this.payload = payload;
|
|
99
97
|
}
|
|
100
98
|
}
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
99
|
// stdin
|
|
103
|
-
// ---------------------------------------------------------------------------
|
|
104
100
|
/** Read raw stdin to EOF. Returns empty string when stdin is a TTY (no pipe).
|
|
105
101
|
* Called by the argv parser for leaves declaring a `stdin` parameter. */
|
|
106
102
|
export async function readStdinRaw() {
|
|
@@ -148,9 +144,7 @@ export async function peekStdinRaw(timeoutMs = 200) {
|
|
|
148
144
|
process.stdin.resume();
|
|
149
145
|
});
|
|
150
146
|
}
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
147
|
// stdout — the result, nothing else
|
|
153
|
-
// ---------------------------------------------------------------------------
|
|
154
148
|
/** Raw-JSON mirror of a single-shot response (the `--json` escape hatch). The
|
|
155
149
|
* default path renders the result as prose instead — see render.ts. */
|
|
156
150
|
export function emit(obj) {
|
|
@@ -192,15 +186,11 @@ export function writeStdout(s) {
|
|
|
192
186
|
}
|
|
193
187
|
});
|
|
194
188
|
}
|
|
195
|
-
// ---------------------------------------------------------------------------
|
|
196
189
|
// stderr — diagnostics the agent MAY capture, never the result
|
|
197
|
-
// ---------------------------------------------------------------------------
|
|
198
190
|
export function diag(message) {
|
|
199
191
|
process.stderr.write(message + '\n');
|
|
200
192
|
}
|
|
201
|
-
// ---------------------------------------------------------------------------
|
|
202
193
|
// errors
|
|
203
|
-
// ---------------------------------------------------------------------------
|
|
204
194
|
function payloadOf(e) {
|
|
205
195
|
if (e instanceof InputError)
|
|
206
196
|
return e.payload;
|
|
@@ -259,7 +249,6 @@ function jsonSafeResult(result) {
|
|
|
259
249
|
message: 'The completed primary result could not be represented as JSON.',
|
|
260
250
|
};
|
|
261
251
|
}
|
|
262
|
-
// ---------------------------------------------------------------------------
|
|
263
252
|
// ApiError → clean CLI error — the ONE shared translation (plan C-5)
|
|
264
253
|
//
|
|
265
254
|
// A daemon `ApiError` is NOT a `CrtrError`, so left unhandled it falls through
|
|
@@ -268,7 +257,6 @@ function jsonSafeResult(result) {
|
|
|
268
257
|
// error the pre-API leaves surfaced, so every re-plumbed verb shares one
|
|
269
258
|
// contract instead of re-implementing the mapping per command. io.ts importing
|
|
270
259
|
// `ApiError` from `src/api` is canvas-clean (src/api is Node-built-ins only).
|
|
271
|
-
// ---------------------------------------------------------------------------
|
|
272
260
|
/** Map a daemon HTTP status to the stable CLI error code the pre-API leaves
|
|
273
261
|
* used, so agent-facing error contracts survive the re-plumb. Used only as the
|
|
274
262
|
* fallback when the server did NOT round-trip a full structured payload. */
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
// (a project's declaration, an installed plugin's mount prefix, or empty), and
|
|
5
5
|
// its canonical name — the only address resolution accepts — is namespace ⊕
|
|
6
6
|
// local. Pure and side-effect free.
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
7
|
// Segment normalization — the optional `NN-` ordering pin. A physical path may
|
|
9
8
|
// carry a two-digit prefix on any segment (`00-runtime-base/`, `01-spine/`)
|
|
10
9
|
// purely to pin structural order against natural sort. The prefix is NEVER part
|
|
11
10
|
// of identity: only the physical path keeps it.
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
11
|
const NUMERIC_PREFIX_RE = /^\d{2}-/;
|
|
14
12
|
const SEGMENT_RE = /^[A-Za-z0-9._-]+$/;
|
|
15
13
|
/** The filename (and path segment) whose document fronts its directory. */
|
|
@@ -85,9 +83,7 @@ export function physicalRelativePathFor(localName, representation) {
|
|
|
85
83
|
}
|
|
86
84
|
return representation === 'directory-index' ? `${local}/${INDEX_SEGMENT}.md` : `${local}.md`;
|
|
87
85
|
}
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
86
|
// Local name and canonical composition.
|
|
90
|
-
// ---------------------------------------------------------------------------
|
|
91
87
|
/** A document's explicit frontmatter `name` as a local name — normalized with
|
|
92
88
|
* one trailing `INDEX` collapsed — or `null` when it carries none. */
|
|
93
89
|
export function explicitLocalName(fm) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Authoritative broker-side inventory for inline memory references. It uses one
|
|
2
2
|
// target view, exact canonical winners, and the canonical tree for directory
|
|
3
3
|
// browse names; gates, rungs, and slash flags do not affect referenceability.
|
|
4
|
+
import { envNodeId, envProfileId } from '../../shared/env.js';
|
|
4
5
|
import { loadMemoryTargetView } from '../memory-resolver.js';
|
|
5
6
|
import { buildMemoryTree } from './tree.js';
|
|
6
7
|
import { memoryExtensionEffectiveCatalog, projectEffectiveMemoryExtensions } from './extensions.js';
|
|
@@ -21,8 +22,8 @@ const SCOPE_SORT_RANK = {
|
|
|
21
22
|
export function buildRefInventory() {
|
|
22
23
|
const target = {
|
|
23
24
|
cwd: process.cwd(),
|
|
24
|
-
profileId:
|
|
25
|
-
nodeId:
|
|
25
|
+
profileId: envProfileId() || null,
|
|
26
|
+
nodeId: envNodeId() || null,
|
|
26
27
|
};
|
|
27
28
|
const view = loadMemoryTargetView(target, { quiet: true });
|
|
28
29
|
const winners = new Map();
|
package/dist/core/memory/lint.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// a non-fatal authoring smell, `notice` is inspection data (duplicate stores are
|
|
11
11
|
// legitimate, so equal-canonical candidates across stores are reported, never
|
|
12
12
|
// failed).
|
|
13
|
+
import { envNodeId, envProfileId } from '../../shared/env.js';
|
|
13
14
|
import { basename, join, matchesGlob, relative, sep } from 'node:path';
|
|
14
15
|
import { pathExists, readText, realpathOrSelf, walkFiles } from '../fs-utils.js';
|
|
15
16
|
import { parseFrontmatterGeneric } from '../frontmatter.js';
|
|
@@ -51,7 +52,6 @@ function makeResult(findings, checked, documents, storesLinted) {
|
|
|
51
52
|
notices: findings.filter((f) => f.severity === 'notice'),
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
|
-
// ---------------------------------------------------------------------------
|
|
55
55
|
// Body-length caps, measured in WORDS (frontmatter excluded). Words, not lines:
|
|
56
56
|
// house style writes each paragraph as ONE logical line and lets the editor
|
|
57
57
|
// soft-wrap, so a line count measures wrapping style rather than context cost.
|
|
@@ -68,7 +68,6 @@ function makeResult(findings, checked, documents, storesLinted) {
|
|
|
68
68
|
// composes into an agent's persona — are structurally exempt: an agent reads its
|
|
69
69
|
// whole persona by construction. Suppression elsewhere is deliberate and
|
|
70
70
|
// per-doc: `lint-ignore: length`, surfaced ONLY by the finding itself.
|
|
71
|
-
// ---------------------------------------------------------------------------
|
|
72
71
|
const BOOT_CONTENT_MAX_WORDS = 1000;
|
|
73
72
|
const EVENT_CONTENT_MAX_WORDS = 1000;
|
|
74
73
|
const BOOT_PREVIEW_MAX_WORDS = 3000;
|
|
@@ -116,9 +115,7 @@ export function lintShortPreviewBody(fm, body) {
|
|
|
116
115
|
const noun = previewEvents.length === 1 ? 'entry delivers' : 'entries deliver';
|
|
117
116
|
return `body is ${words} words but the ${previewEvents.join('/')} ${noun} \`preview\`; use \`at: content\` so agents receive the whole rule without a separate memory read`;
|
|
118
117
|
}
|
|
119
|
-
// ---------------------------------------------------------------------------
|
|
120
118
|
// Reference resolution: what a `[[link]]` or a `memory-read` route may name.
|
|
121
|
-
// ---------------------------------------------------------------------------
|
|
122
119
|
/** Every canonical name a reference may target in a corpus: each document's
|
|
123
120
|
* exact identity plus every canonical directory, because reading a directory
|
|
124
121
|
* answers with its own document and its listing. Derived from the canonical
|
|
@@ -455,8 +452,8 @@ function lintMemoryReadEntry(entry, doc, fm, resolvable, mounted, add) {
|
|
|
455
452
|
function ambientTarget() {
|
|
456
453
|
return {
|
|
457
454
|
cwd: process.cwd(),
|
|
458
|
-
profileId:
|
|
459
|
-
nodeId:
|
|
455
|
+
profileId: envProfileId() || null,
|
|
456
|
+
nodeId: envNodeId() || null,
|
|
460
457
|
};
|
|
461
458
|
}
|
|
462
459
|
/** Lint every store a target sees, then the diagnostics only the merged view
|
|
@@ -242,6 +242,11 @@ export declare function createMemoryDocSnapshot(target?: MemoryTarget): MemoryDo
|
|
|
242
242
|
/** Resolve several canonical names over one memory-source snapshot. Failed
|
|
243
243
|
* names are omitted so callers can preserve their per-document error behavior. */
|
|
244
244
|
export declare function resolveMemoryDocs(names: readonly string[]): Map<string, MemoryDoc>;
|
|
245
|
+
/** Load the body at an already-resolved memory path with the same frontmatter
|
|
246
|
+
* stripping and in-node path interpolation as `memory read`. Callers that
|
|
247
|
+
* already have the resolved path (such as slash-command discovery) avoid
|
|
248
|
+
* re-walking every memory store for each document. */
|
|
249
|
+
export declare function readMemoryDocContent(path: string, includeFrontmatter?: boolean): string;
|
|
245
250
|
/** The address winner for an exact canonical name in the ambient target. */
|
|
246
251
|
export declare function resolveMemoryDoc(rawName: string, opts?: MemoryResolutionOpts): MemoryDoc;
|
|
247
252
|
/** Resolve a memory document as ANOTHER node would see it — the same precedence
|