@north-light/crouter 0.3.170 → 0.3.172
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.d.ts +37 -11
- package/dist/api/client.js +84 -15
- package/dist/api/dto/human.d.ts +53 -39
- package/dist/api/dto/human.js +2 -3
- package/dist/api/dto/inbox.d.ts +0 -1
- package/dist/api/dto/nodes.d.ts +12 -0
- package/dist/api/dto/review-comments.d.ts +137 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +109 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/routes.d.ts +17 -4
- package/dist/api/routes.js +21 -5
- package/dist/build-root.d.ts +1 -16
- package/dist/build-root.js +1 -25
- package/dist/builtin-memory/00-runtime-base.md +7 -5
- package/dist/builtin-memory/04-base-worker.md +1 -1
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
- package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
- package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
- package/dist/builtin-memory/design.md +2 -2
- package/dist/builtin-memory/insights/capture.md +50 -0
- package/dist/builtin-memory/insights/init.md +45 -0
- package/dist/builtin-memory/insights/listen.md +9 -0
- package/dist/builtin-memory/internal/agent-shaping.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +12 -11
- package/dist/builtin-memory/internal/storage-tiers.md +2 -2
- package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
- package/dist/builtin-memory/plan.md +19 -0
- package/dist/builtin-memory/spec/guide.md +38 -0
- package/dist/builtin-memory/spec/requirements.md +31 -0
- package/dist/builtin-memory/spec/roadmap.md +35 -0
- package/dist/builtin-memory/spec.md +10 -86
- package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
- package/dist/cli.js +2 -6
- package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
- package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
- package/dist/clients/attach/__tests__/context-message.test.js +142 -6
- package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
- package/dist/clients/attach/__tests__/diagram.test.js +1 -1
- package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
- package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
- package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
- package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
- package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
- package/dist/clients/attach/chrome/header.d.ts +10 -0
- package/dist/clients/attach/chrome/header.js +30 -0
- package/dist/clients/attach/chrome/recap.d.ts +7 -0
- package/dist/clients/attach/chrome/recap.js +19 -0
- package/dist/clients/attach/chrome/status-line.d.ts +3 -0
- package/dist/clients/attach/chrome/status-line.js +5 -0
- package/dist/clients/attach/chrome/widgets.js +11 -21
- package/dist/clients/attach/command.js +11 -7
- package/dist/clients/attach/config.d.ts +4 -0
- package/dist/clients/attach/config.js +3 -0
- package/dist/clients/attach/input/controller.d.ts +19 -0
- package/dist/clients/attach/input/controller.js +62 -28
- package/dist/clients/attach/input/titled-editor.d.ts +0 -4
- package/dist/clients/attach/input/titled-editor.js +2 -10
- package/dist/clients/attach/overlays/file-review.d.ts +9 -5
- package/dist/clients/attach/overlays/file-review.js +9 -70
- package/dist/clients/attach/overlays/help.d.ts +33 -0
- package/dist/clients/attach/overlays/help.js +204 -0
- package/dist/clients/attach/render/activity-slot.d.ts +4 -0
- package/dist/clients/attach/render/activity-slot.js +13 -0
- package/dist/clients/attach/render/chat-view.d.ts +117 -12
- package/dist/clients/attach/render/chat-view.js +604 -135
- package/dist/clients/attach/render/context-message.d.ts +2 -1
- package/dist/clients/attach/render/context-message.js +17 -13
- package/dist/clients/attach/render/crtr-output.js +1 -3
- package/dist/clients/attach/render/diagram.js +2 -2
- package/dist/clients/attach/render/edit-diff.d.ts +4 -1
- package/dist/clients/attach/render/edit-diff.js +7 -11
- package/dist/clients/attach/render/group-activity.d.ts +32 -0
- package/dist/clients/attach/render/group-activity.js +206 -0
- package/dist/clients/attach/render/group-recap.d.ts +10 -0
- package/dist/clients/attach/render/group-recap.js +93 -0
- package/dist/clients/attach/render/html-markdown.d.ts +17 -0
- package/dist/clients/attach/render/html-markdown.js +228 -0
- package/dist/clients/attach/render/measured-container.d.ts +96 -0
- package/dist/clients/attach/render/measured-container.js +322 -0
- package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
- package/dist/clients/attach/render/scroll-animation.js +80 -0
- package/dist/clients/attach/render/tool-calls.js +6 -6
- package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
- package/dist/clients/attach/render/transcript-copy.js +81 -0
- package/dist/clients/attach/render/viewport.d.ts +29 -0
- package/dist/clients/attach/render/viewport.js +159 -0
- package/dist/clients/attach/session/bindings.d.ts +10 -7
- package/dist/clients/attach/session/bindings.js +23 -8
- package/dist/clients/attach/session/connection.js +4 -5
- package/dist/clients/attach/session/context.d.ts +6 -4
- package/dist/clients/attach/session/frame.d.ts +34 -0
- package/dist/clients/attach/session/frame.js +176 -0
- package/dist/clients/attach/session/frames.d.ts +4 -1
- package/dist/clients/attach/session/frames.js +14 -1
- package/dist/clients/attach/session/identity.js +4 -3
- package/dist/clients/attach/session/input-wiring.d.ts +14 -4
- package/dist/clients/attach/session/input-wiring.js +15 -13
- package/dist/clients/attach/session/invariant.d.ts +9 -0
- package/dist/clients/attach/session/invariant.js +15 -0
- package/dist/clients/attach/session/keys.d.ts +10 -2
- package/dist/clients/attach/session/keys.js +13 -5
- package/dist/clients/attach/session/layout.d.ts +10 -8
- package/dist/clients/attach/session/layout.js +33 -34
- package/dist/clients/attach/session/mouse.d.ts +18 -0
- package/dist/clients/attach/session/mouse.js +64 -0
- package/dist/clients/attach/session/pane-tag.d.ts +3 -0
- package/dist/clients/attach/session/pane-tag.js +51 -8
- package/dist/clients/attach/session/reconnect.d.ts +3 -0
- package/dist/clients/attach/session/reconnect.js +42 -5
- package/dist/clients/attach/session/surface-frame.d.ts +20 -0
- package/dist/clients/attach/session/surface-frame.js +73 -0
- package/dist/clients/attach/session/surface-host.d.ts +64 -0
- package/dist/clients/attach/session/surface-host.js +255 -0
- package/dist/clients/attach/session/whip.d.ts +17 -0
- package/dist/clients/attach/session/whip.js +334 -0
- package/dist/clients/attach/slash/dispatch.d.ts +13 -1
- package/dist/clients/attach/slash/dispatch.js +51 -29
- package/dist/clients/attach/viewer.js +907 -819
- package/dist/clients/conversation/conversation.d.ts +65 -0
- package/dist/clients/conversation/conversation.js +318 -0
- package/dist/clients/conversation/frames.d.ts +30 -0
- package/dist/clients/conversation/frames.js +52 -0
- package/dist/clients/conversation/region.d.ts +51 -0
- package/dist/clients/conversation/region.js +265 -0
- package/dist/clients/conversation/submit.d.ts +38 -0
- package/dist/clients/conversation/submit.js +51 -0
- package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
- package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
- package/dist/clients/inbox/controller.d.ts +79 -0
- package/dist/clients/inbox/controller.js +448 -0
- package/dist/clients/inbox/deck-adapter.d.ts +29 -0
- package/dist/clients/inbox/deck-adapter.js +62 -0
- package/dist/clients/inbox/layout.d.ts +8 -0
- package/dist/clients/inbox/layout.js +9 -0
- package/dist/clients/inbox/resolve.d.ts +10 -0
- package/dist/clients/inbox/resolve.js +34 -0
- package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
- package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
- package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
- package/dist/clients/inbox/review/anchors.d.ts +41 -0
- package/dist/clients/inbox/review/anchors.js +89 -0
- package/dist/clients/inbox/review/columns.d.ts +22 -0
- package/dist/clients/inbox/review/columns.js +40 -0
- package/dist/clients/inbox/review/comments-client.d.ts +66 -0
- package/dist/clients/inbox/review/comments-client.js +98 -0
- package/dist/clients/inbox/review/composition.d.ts +60 -0
- package/dist/clients/inbox/review/composition.js +278 -0
- package/dist/clients/inbox/review/document-region.d.ts +120 -0
- package/dist/clients/inbox/review/document-region.js +902 -0
- package/dist/clients/inbox/review/frame.d.ts +45 -0
- package/dist/clients/inbox/review/frame.js +215 -0
- package/dist/clients/inbox/review/keys.d.ts +67 -0
- package/dist/clients/inbox/review/keys.js +130 -0
- package/dist/clients/inbox/review/launch.d.ts +10 -0
- package/dist/clients/inbox/review/launch.js +129 -0
- package/dist/clients/inbox/review/live-source.d.ts +24 -0
- package/dist/clients/inbox/review/live-source.js +160 -0
- package/dist/clients/inbox/review/nvim.d.ts +13 -0
- package/dist/clients/inbox/review/nvim.js +42 -0
- package/dist/clients/inbox/review/remap.d.ts +51 -0
- package/dist/clients/inbox/review/remap.js +157 -0
- package/dist/clients/inbox/review/review-client.d.ts +30 -0
- package/dist/clients/inbox/review/review-client.js +107 -0
- package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
- package/dist/clients/inbox/review/roundtrip.js +36 -0
- package/dist/clients/inbox/review/state.d.ts +143 -0
- package/dist/clients/inbox/review/state.js +282 -0
- package/dist/clients/inbox/review-adapter.d.ts +29 -0
- package/dist/clients/inbox/review-adapter.js +92 -0
- package/dist/clients/inbox/review-visibility.d.ts +5 -0
- package/dist/clients/inbox/review-visibility.js +19 -0
- package/dist/clients/inbox/surface.d.ts +19 -0
- package/dist/clients/inbox/surface.js +128 -0
- package/dist/clients/inbox/tui/ansi.d.ts +66 -0
- package/dist/clients/inbox/tui/ansi.js +317 -0
- package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
- package/dist/clients/inbox/tui/clipboard.js +26 -0
- package/dist/clients/inbox/tui/input.d.ts +7 -0
- package/dist/clients/inbox/tui/input.js +653 -0
- package/dist/clients/inbox/tui/keys.d.ts +28 -0
- package/dist/clients/inbox/tui/keys.js +111 -0
- package/dist/clients/inbox/tui/panel.d.ts +2 -0
- package/dist/clients/inbox/tui/panel.js +217 -0
- package/dist/clients/inbox/tui/render.d.ts +37 -0
- package/dist/clients/inbox/tui/render.js +476 -0
- package/dist/clients/inbox/tui/types.d.ts +57 -0
- package/dist/clients/inbox/tui/types.js +1 -0
- package/dist/clients/inbox/tui.d.ts +6 -0
- package/dist/clients/inbox/tui.js +74 -0
- package/dist/clients/surfaces/host.d.ts +66 -0
- package/dist/clients/surfaces/host.js +1 -0
- package/dist/clients/surfaces/region.d.ts +16 -0
- package/dist/clients/surfaces/region.js +1 -0
- package/dist/clients/web/__tests__/push-engine.test.js +14 -158
- package/dist/clients/web/dev-server.d.ts +3 -3
- package/dist/clients/web/dev-server.js +9 -23
- package/dist/clients/web/events.js +4 -6
- package/dist/clients/web/push-engine.d.ts +2 -66
- package/dist/clients/web/push-engine.js +30 -161
- package/dist/clients/web/push-registry.d.ts +0 -4
- package/dist/clients/web/push-registry.js +2 -7
- package/dist/clients/web/server.js +3 -35
- package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
- package/dist/clients/web/web-cmd.js +2 -2
- package/dist/commands/__tests__/human.test.js +27 -15
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas-browse.js +1 -1
- package/dist/commands/canvas-issue.js +1 -1
- package/dist/commands/canvas-use.js +1 -1
- package/dist/commands/human/doc.d.ts +2 -0
- package/dist/commands/human/doc.js +98 -0
- package/dist/commands/human/inbox.d.ts +2 -0
- package/dist/commands/human/inbox.js +101 -0
- package/dist/commands/human/prompts.d.ts +2 -3
- package/dist/commands/human/prompts.js +27 -180
- package/dist/commands/human/queue.d.ts +1 -5
- package/dist/commands/human/queue.js +54 -216
- package/dist/commands/human/review.d.ts +2 -0
- package/dist/commands/human/review.js +298 -0
- package/dist/commands/human/shared.d.ts +2 -69
- package/dist/commands/human/shared.js +1 -181
- package/dist/commands/human.js +15 -20
- package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
- package/dist/commands/memory/__tests__/lint.test.js +15 -0
- package/dist/commands/memory/delete.js +2 -2
- package/dist/commands/memory/lint.d.ts +1 -0
- package/dist/commands/memory/lint.js +21 -3
- package/dist/commands/memory/read.js +4 -4
- package/dist/commands/node.js +8 -7
- package/dist/commands/pkg/plugin-manage.js +143 -68
- package/dist/commands/surface-inspect.js +2 -2
- package/dist/commands/surface.js +6 -12
- package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
- package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
- package/dist/commands/sys/config.js +29 -3
- package/dist/commands/sys/feedback.js +1 -1
- package/dist/commands/sys/setup-core.d.ts +12 -11
- package/dist/commands/sys/setup-core.js +55 -46
- package/dist/commands/sys/setup-wizard.d.ts +4 -1
- package/dist/commands/sys/setup-wizard.js +50 -9
- package/dist/commands/sys/sync-deps.js +1 -1
- package/dist/commands/sys.js +4 -6
- package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
- package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
- package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
- package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
- package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
- package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
- package/dist/core/__tests__/full/detach-focus.test.js +1 -1
- package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
- package/dist/core/__tests__/human-deliver.test.js +71 -345
- package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
- package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
- package/dist/core/__tests__/migration.test.js +10 -0
- package/dist/core/__tests__/model-pin-durability.test.js +14 -0
- package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
- package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
- package/dist/core/__tests__/phase4-review-store.test.js +143 -0
- package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
- package/dist/core/__tests__/revive.test.js +22 -53
- package/dist/core/__tests__/session-cycles.test.js +48 -18
- package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
- package/dist/core/__tests__/stop-guard.test.js +16 -1
- package/dist/core/__tests__/tmux-surface.test.js +21 -25
- package/dist/core/asset-root.d.ts +7 -0
- package/dist/core/asset-root.js +18 -0
- package/dist/core/broker-client/client.d.ts +0 -7
- package/dist/core/broker-client/client.js +4 -10
- package/dist/core/broker-client/transport-relay.d.ts +3 -4
- package/dist/core/broker-client/transport-relay.js +3 -4
- package/dist/core/canvas/__tests__/attention.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
- package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
- package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
- package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
- package/dist/core/canvas/attention.js +4 -4
- package/dist/core/canvas/canvas.d.ts +6 -11
- package/dist/core/canvas/canvas.js +11 -33
- package/dist/core/canvas/db.js +207 -38
- package/dist/core/canvas/extensions.d.ts +1 -1
- package/dist/core/canvas/extensions.js +8 -1
- package/dist/core/canvas/index.d.ts +0 -1
- package/dist/core/canvas/index.js +0 -1
- package/dist/core/canvas/nav-model.d.ts +1 -1
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/paths.d.ts +5 -0
- package/dist/core/canvas/paths.js +16 -0
- package/dist/core/canvas/remote-canvas-source.js +2 -2
- package/dist/core/canvas/remote-transport.d.ts +7 -0
- package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
- package/dist/core/canvas/source.js +1 -1
- package/dist/core/canvas/status-glyph.js +4 -12
- package/dist/core/canvas/types.d.ts +10 -35
- package/dist/core/clipboard-text.d.ts +8 -0
- package/dist/core/clipboard-text.js +18 -0
- package/dist/core/command-manifests/registry.d.ts +1 -3
- package/dist/core/command-plugins/bundle.d.ts +29 -0
- package/dist/core/command-plugins/bundle.js +198 -0
- package/dist/core/command-plugins/discovery.d.ts +0 -8
- package/dist/core/command-plugins/discovery.js +2 -39
- package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
- package/dist/core/command-plugins/transport/http-fetch.js +17 -95
- package/dist/core/command.d.ts +1 -13
- package/dist/core/command.js +1 -16
- package/dist/core/config.d.ts +4 -0
- package/dist/core/config.js +28 -3
- package/dist/core/document-lines.d.ts +4 -0
- package/dist/core/document-lines.js +6 -0
- package/dist/core/feed/feed.d.ts +2 -0
- package/dist/core/feed/feed.js +11 -7
- package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
- package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
- package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-core.test.js +144 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
- package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
- package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
- package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
- package/dist/core/human/claim.d.ts +23 -0
- package/dist/core/human/claim.js +67 -0
- package/dist/core/human/convention.d.ts +30 -0
- package/dist/core/human/convention.js +202 -0
- package/dist/core/human/deck-factories.d.ts +8 -0
- package/dist/core/human/deck-factories.js +15 -0
- package/dist/core/human/deck-schema.d.ts +70 -0
- package/dist/core/human/deck-schema.js +92 -0
- package/dist/core/human/root.d.ts +7 -0
- package/dist/core/human/root.js +37 -0
- package/dist/core/human/scan.d.ts +3 -0
- package/dist/core/human/scan.js +76 -0
- package/dist/core/human/summary.d.ts +8 -0
- package/dist/core/human/summary.js +44 -0
- package/dist/core/human/tickets.d.ts +49 -0
- package/dist/core/human/tickets.js +190 -0
- package/dist/core/human/types.d.ts +136 -0
- package/dist/core/human/types.js +5 -0
- package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
- package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
- package/dist/core/inspector/chrome.d.ts +6 -0
- package/dist/core/inspector/chrome.js +14 -0
- package/dist/core/inspector/contract.d.ts +105 -0
- package/dist/core/inspector/contract.js +1 -0
- package/dist/core/inspector/core.d.ts +4 -5
- package/dist/core/inspector/core.js +3 -5
- package/dist/core/inspector/host.d.ts +46 -0
- package/dist/core/{tui → inspector}/host.js +42 -208
- package/dist/core/inspector/text.d.ts +2 -2
- package/dist/core/inspector/transport.d.ts +6 -0
- package/dist/core/inspector/transport.js +36 -0
- package/dist/core/inspector/tui.d.ts +2 -2
- package/dist/core/inspector/tui.js +15 -15
- package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
- package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
- package/dist/core/keybindings/attach-control.d.ts +9 -3
- package/dist/core/keybindings/attach-control.js +3 -1
- package/dist/core/keybindings/catalog.d.ts +6 -5
- package/dist/core/keybindings/catalog.js +61 -133
- package/dist/core/keybindings/inbox.d.ts +5 -6
- package/dist/core/keybindings/inbox.js +9 -10
- package/dist/core/keybindings/index.d.ts +3 -3
- package/dist/core/keybindings/index.js +3 -3
- package/dist/core/keybindings/persistence.d.ts +5 -1
- package/dist/core/keybindings/persistence.js +24 -6
- package/dist/core/keybindings/resolve.d.ts +6 -0
- package/dist/core/keybindings/resolve.js +10 -3
- package/dist/core/memory/inline-ref-grammar.js +2 -3
- package/dist/core/memory-resolver.d.ts +27 -29
- package/dist/core/memory-resolver.js +45 -39
- package/dist/core/model-routes.d.ts +33 -0
- package/dist/core/model-routes.js +42 -3
- package/dist/core/preview-registry.js +17 -55
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
- package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
- package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
- package/dist/core/review/__tests__/capture-origin.test.js +139 -0
- package/dist/core/review/__tests__/comments.test.d.ts +1 -0
- package/dist/core/review/__tests__/comments.test.js +98 -0
- package/dist/core/review/__tests__/project.test.d.ts +1 -0
- package/dist/core/review/__tests__/project.test.js +71 -0
- package/dist/core/review/__tests__/remap.test.d.ts +1 -0
- package/dist/core/review/__tests__/remap.test.js +159 -0
- package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
- package/dist/core/review/__tests__/stage-identity.test.js +140 -0
- package/dist/core/review/birth.d.ts +7 -0
- package/dist/core/review/birth.js +23 -0
- package/dist/core/review/comments.d.ts +69 -0
- package/dist/core/review/comments.js +295 -0
- package/dist/core/review/companion.d.ts +35 -0
- package/dist/core/review/companion.js +205 -0
- package/dist/core/review/document.d.ts +27 -0
- package/dist/core/review/document.js +138 -0
- package/dist/core/review/project.d.ts +13 -0
- package/dist/core/review/project.js +58 -0
- package/dist/core/review/realize.d.ts +19 -0
- package/dist/core/review/realize.js +217 -0
- package/dist/core/review/remap.d.ts +24 -0
- package/dist/core/review/remap.js +156 -0
- package/dist/core/review/signal.d.ts +5 -0
- package/dist/core/review/signal.js +31 -0
- package/dist/core/review/stage.d.ts +26 -0
- package/dist/core/review/stage.js +184 -0
- package/dist/core/review/store.d.ts +46 -0
- package/dist/core/review/store.js +163 -0
- package/dist/core/review/ticket-filter.d.ts +17 -0
- package/dist/core/review/ticket-filter.js +32 -0
- package/dist/core/review/types.d.ts +130 -0
- package/dist/core/review/types.js +23 -0
- package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
- package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
- package/dist/core/runtime/bearings.d.ts +5 -17
- package/dist/core/runtime/bearings.js +88 -71
- package/dist/core/runtime/broker-protocol.d.ts +31 -8
- package/dist/core/runtime/broker.d.ts +15 -1
- package/dist/core/runtime/broker.js +573 -141
- package/dist/core/runtime/canvas-extensions.d.ts +4 -5
- package/dist/core/runtime/canvas-extensions.js +5 -5
- package/dist/core/runtime/front-door.js +4 -4
- package/dist/core/runtime/headless-pi.d.ts +24 -0
- package/dist/core/runtime/headless-pi.js +152 -0
- package/dist/core/runtime/kickoff.d.ts +1 -5
- package/dist/core/runtime/kickoff.js +1 -5
- package/dist/core/runtime/model-registry.d.ts +3 -0
- package/dist/core/runtime/model-registry.js +13 -0
- package/dist/core/runtime/naming-persist.d.ts +4 -0
- package/dist/core/runtime/naming-persist.js +27 -1
- package/dist/core/runtime/naming.d.ts +17 -12
- package/dist/core/runtime/naming.js +91 -140
- package/dist/core/runtime/node-read.js +19 -10
- package/dist/core/runtime/nodes.d.ts +9 -14
- package/dist/core/runtime/nodes.js +3 -53
- package/dist/core/runtime/package-health.d.ts +6 -21
- package/dist/core/runtime/package-health.js +12 -123
- package/dist/core/runtime/placement-tmux.d.ts +2 -1
- package/dist/core/runtime/placement-tmux.js +6 -4
- package/dist/core/runtime/placement.d.ts +1 -0
- package/dist/core/runtime/placement.js +4 -8
- package/dist/core/runtime/promote.js +3 -0
- package/dist/core/runtime/recap.d.ts +2 -7
- package/dist/core/runtime/recap.js +35 -69
- package/dist/core/runtime/revive.js +34 -77
- package/dist/core/runtime/session-cycles.d.ts +4 -0
- package/dist/core/runtime/session-cycles.js +14 -1
- package/dist/core/runtime/session-visibility.d.ts +37 -0
- package/dist/core/runtime/session-visibility.js +83 -0
- package/dist/core/runtime/spawn.js +10 -22
- package/dist/core/runtime/stop-guard.d.ts +1 -1
- package/dist/core/runtime/stop-guard.js +18 -13
- package/dist/core/runtime/surface-bg.js +1 -1
- package/dist/core/runtime/tmux-chrome.d.ts +1 -1
- package/dist/core/runtime/tmux-chrome.js +1 -1
- package/dist/core/runtime/tmux.d.ts +35 -7
- package/dist/core/runtime/tmux.js +439 -62
- package/dist/core/runtime/tool-group-summary.d.ts +19 -0
- package/dist/core/runtime/tool-group-summary.js +88 -0
- package/dist/core/scope.d.ts +2 -7
- package/dist/core/scope.js +9 -35
- package/dist/core/substrate/schema.d.ts +2 -2
- package/dist/core/termrender/code-doc.d.ts +12 -0
- package/dist/core/termrender/code-doc.js +92 -0
- package/dist/core/termrender/display.d.ts +12 -0
- package/dist/core/termrender/display.js +19 -0
- package/dist/core/termrender/termrender.d.ts +73 -0
- package/dist/core/termrender/termrender.js +795 -0
- package/dist/core/termrender/version.d.ts +1 -0
- package/dist/core/termrender/version.js +1 -0
- package/dist/core/tui/terminal.js +1 -2
- package/dist/core/user-settings.d.ts +71 -3
- package/dist/core/user-settings.js +83 -1
- package/dist/daemon/api/__tests__/inbox.test.js +44 -133
- package/dist/daemon/api/handlers/human.d.ts +0 -10
- package/dist/daemon/api/handlers/human.js +104 -702
- package/dist/daemon/api/handlers/inbox.js +113 -142
- package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
- package/dist/daemon/api/handlers/review-comments.js +500 -0
- package/dist/daemon/api/handlers/reviews.d.ts +2 -0
- package/dist/daemon/api/handlers/reviews.js +287 -0
- package/dist/daemon/api/map.d.ts +22 -7
- package/dist/daemon/api/map.js +159 -11
- package/dist/daemon/api/server.js +4 -0
- package/dist/daemon/cron-run.js +6 -9
- package/dist/daemon/crtrd.js +17 -33
- package/dist/daemon/fleet.d.ts +1 -8
- package/dist/daemon/fleet.js +4 -30
- package/dist/daemon/human/finish.d.ts +14 -0
- package/dist/daemon/human/finish.js +115 -0
- package/dist/daemon/human/sweep.d.ts +6 -0
- package/dist/daemon/human/sweep.js +49 -0
- package/dist/daemon/messaging/node-message.d.ts +18 -0
- package/dist/daemon/messaging/node-message.js +70 -0
- package/dist/daemon/review/comment-notify.d.ts +26 -0
- package/dist/daemon/review/comment-notify.js +107 -0
- package/dist/daemon/review/deliver.d.ts +7 -0
- package/dist/daemon/review/deliver.js +56 -0
- package/dist/daemon/review/finish.d.ts +22 -0
- package/dist/daemon/review/finish.js +254 -0
- package/dist/daemon/review/sweep.d.ts +11 -0
- package/dist/daemon/review/sweep.js +120 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
- package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
- package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
- package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
- package/dist/pi-extensions/canvas-context-intro.js +50 -104
- package/dist/pi-extensions/canvas-recap.d.ts +15 -2
- package/dist/pi-extensions/canvas-recap.js +192 -69
- package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
- package/dist/pi-extensions/canvas-review-boundary.js +81 -0
- package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
- package/dist/pi-extensions/canvas-stophook.js +78 -128
- package/dist/pi-extensions/canvas-structured-output.js +52 -8
- package/dist/shared/generated-context.d.ts +29 -4
- package/dist/shared/generated-context.js +122 -7
- package/dist/shared/tool-groups.d.ts +23 -0
- package/dist/shared/tool-groups.js +60 -0
- package/dist/shared/working-activity.d.ts +8 -0
- package/dist/shared/working-activity.js +26 -0
- package/dist/types.d.ts +36 -2
- package/dist/types.js +51 -0
- package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
- package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/compat/hearth-crtr-v4.md +2 -2
- package/docs/compat/hearth-crtr-v5.md +4 -2
- package/docs/public-api.md +3 -3
- package/package.json +21 -14
- package/runtime.lock.json +4661 -1453
- package/scripts/postinstall.mjs +15 -2
- package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
- package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
- package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
- package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
- package/dist/builtin-views/_lib/states.mjs +0 -161
- package/dist/builtin-views/canvas/core.mjs +0 -657
- package/dist/builtin-views/canvas/text.mjs +0 -58
- package/dist/builtin-views/canvas/tui.mjs +0 -168
- package/dist/builtin-views/canvas/web.jsx +0 -121
- package/dist/builtin-views/chat/core.mjs +0 -684
- package/dist/builtin-views/chat/text.mjs +0 -101
- package/dist/builtin-views/chat/tui.mjs +0 -360
- package/dist/builtin-views/chat/web.jsx +0 -362
- package/dist/builtin-views/git-pr/core.mjs +0 -673
- package/dist/builtin-views/git-pr/text.mjs +0 -84
- package/dist/builtin-views/git-pr/tui.mjs +0 -301
- package/dist/builtin-views/git-pr/web.jsx +0 -216
- package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
- package/dist/builtin-views/inbox/core.mjs +0 -1273
- package/dist/builtin-views/inbox/text.mjs +0 -73
- package/dist/builtin-views/inbox/tui.mjs +0 -314
- package/dist/builtin-views/inbox/web.jsx +0 -188
- package/dist/builtin-views/linkedin/core.mjs +0 -906
- package/dist/builtin-views/linkedin/text.mjs +0 -69
- package/dist/builtin-views/linkedin/tui.mjs +0 -413
- package/dist/builtin-views/linkedin/web.jsx +0 -206
- package/dist/builtin-views/prompt-review/core.mjs +0 -735
- package/dist/builtin-views/prompt-review/text.mjs +0 -15
- package/dist/builtin-views/prompt-review/tui.mjs +0 -196
- package/dist/builtin-views/prompt-review/web.jsx +0 -484
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
- package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
- package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
- package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
- package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
- package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
- package/dist/clients/attach/session/mode.d.ts +0 -25
- package/dist/clients/attach/session/mode.js +0 -97
- package/dist/commands/sys/promptstudio.d.ts +0 -2
- package/dist/commands/sys/promptstudio.js +0 -65
- package/dist/commands/view-cycle.d.ts +0 -2
- package/dist/commands/view-cycle.js +0 -130
- package/dist/commands/view-list.d.ts +0 -2
- package/dist/commands/view-list.js +0 -66
- package/dist/commands/view-new.d.ts +0 -2
- package/dist/commands/view-new.js +0 -74
- package/dist/commands/view-pick.d.ts +0 -6
- package/dist/commands/view-pick.js +0 -129
- package/dist/commands/view-run.d.ts +0 -2
- package/dist/commands/view-run.js +0 -214
- package/dist/commands/view.d.ts +0 -2
- package/dist/commands/view.js +0 -31
- package/dist/commands/workspace.d.ts +0 -2
- package/dist/commands/workspace.js +0 -165
- package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
- package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
- package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
- package/dist/core/canvas/human-work-outbox.d.ts +0 -73
- package/dist/core/canvas/human-work-outbox.js +0 -261
- package/dist/core/command-plugins/store.d.ts +0 -16
- package/dist/core/command-plugins/store.js +0 -64
- package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
- package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
- package/dist/core/runtime/fault-recovery-nudge.js +0 -3
- package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
- package/dist/core/tui/host.d.ts +0 -66
- package/dist/core/view/__tests__/transport-cache.test.js +0 -62
- package/dist/core/view/bridge.d.ts +0 -10
- package/dist/core/view/bridge.js +0 -31
- package/dist/core/view/chrome.d.ts +0 -9
- package/dist/core/view/chrome.js +0 -22
- package/dist/core/view/contract.d.ts +0 -205
- package/dist/core/view/contract.js +0 -23
- package/dist/core/view/loader.d.ts +0 -31
- package/dist/core/view/loader.js +0 -188
- package/dist/core/view/stream-local.d.ts +0 -3
- package/dist/core/view/stream-local.js +0 -231
- package/dist/core/view/transport-cache.d.ts +0 -8
- package/dist/core/view/transport-cache.js +0 -38
- package/dist/core/view/transport-local.d.ts +0 -7
- package/dist/core/view/transport-local.js +0 -83
- package/dist/core/view/transport-remote.d.ts +0 -2
- package/dist/core/view/transport.d.ts +0 -10
- package/dist/core/view/transport.js +0 -15
- package/dist/pi-extensions/naming-tool.d.ts +0 -24
- package/dist/pi-extensions/naming-tool.js +0 -67
- package/dist/prompts/view.d.ts +0 -7
- package/dist/prompts/view.js +0 -172
- package/dist/web/ViewChrome.d.ts +0 -7
- package/dist/web/ViewChrome.js +0 -28
- package/dist/web/ViewPane.d.ts +0 -39
- package/dist/web/ViewPane.js +0 -48
- package/dist/web/index.d.ts +0 -8
- package/dist/web/index.js +0 -22
- package/dist/web/runtime.d.ts +0 -39
- package/dist/web/runtime.js +0 -232
- package/dist/web/states.d.ts +0 -24
- package/dist/web/states.js +0 -24
- package/dist/web/transport-http.d.ts +0 -5
- package/dist/web/transport-http.js +0 -34
- package/dist/web/transport-stream.d.ts +0 -3
- package/dist/web/transport-stream.js +0 -204
- package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
- package/dist/web-client/assets/index-aaeu4adv.css +0 -2
- /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
- /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
- /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
- /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
- /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
- /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Parser } from 'tar';
|
|
2
|
+
import { validateCommandManifest } from '../command-manifests/manifest.js';
|
|
3
|
+
function issue(code, message, received, expected, next, path) {
|
|
4
|
+
return { code, message, received, expected, next, ...(path !== undefined ? { path } : {}) };
|
|
5
|
+
}
|
|
6
|
+
function bundleInvalid(message, received, expected, next, path) {
|
|
7
|
+
return issue('plugin_bundle_invalid', message, received, expected, next, path);
|
|
8
|
+
}
|
|
9
|
+
function archiveEnvelopeIssue(archive) {
|
|
10
|
+
// tar v7's Parser always sniffs gzip, even when passed gzip: false. Reject
|
|
11
|
+
// its unambiguous magic bytes before parsing so archive plugins stay tar-only.
|
|
12
|
+
if (archive[0] === 0x1f && archive[1] === 0x8b) {
|
|
13
|
+
return bundleInvalid('bundle archive must be uncompressed tar data', 'gzip-compressed archive', 'an uncompressed tar archive', 'Serve the archive without compression.');
|
|
14
|
+
}
|
|
15
|
+
if (archive.length === 0 || archive.length % 512 !== 0) {
|
|
16
|
+
return bundleInvalid('bundle archive must be a non-empty whole number of 512-byte tar blocks', `${archive.length} bytes`, 'a non-empty tar stream with a 512-byte block length', 'Serve one complete uncompressed tar archive.');
|
|
17
|
+
}
|
|
18
|
+
if (archive.length < 1024 || !archive.subarray(-1024).every((byte) => byte === 0)) {
|
|
19
|
+
return bundleInvalid('bundle archive is missing the required two zero-block terminator', 'archive tail is not 1024 zero bytes', 'a complete tar stream ending in two 512-byte zero blocks', 'Serve the complete uncompressed tar archive.');
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function validateMemberName(path, type) {
|
|
24
|
+
if (path.length === 0 || path.includes('\u0000') || path.includes('\\') || path.startsWith('/') || /^[A-Za-z]:($|\/)/.test(path)) {
|
|
25
|
+
return bundleInvalid('bundle member path must be a safe relative POSIX path', path, 'a relative path without absolute, drive-letter, backslash, or NUL forms', 'Use a safe relative POSIX member path.', path);
|
|
26
|
+
}
|
|
27
|
+
if (type === 'file' && path.endsWith('/')) {
|
|
28
|
+
return bundleInvalid('only directory members may have a trailing slash', path, 'a regular-file path without a trailing slash', 'Emit this member as a regular file path.', path);
|
|
29
|
+
}
|
|
30
|
+
const segments = (type === 'directory' && path.endsWith('/') ? path.slice(0, -1) : path).split('/');
|
|
31
|
+
if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
|
|
32
|
+
return bundleInvalid('bundle member path contains an unsafe segment', path, 'non-empty segments other than . or ..', 'Use a safe relative POSIX member path.', path);
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
function validateMemberShape(path, type) {
|
|
37
|
+
if (type === 'file') {
|
|
38
|
+
if (path === 'bundle.json' || path === 'commands.json' || (path.startsWith('memory/') && path.endsWith('.md')))
|
|
39
|
+
return undefined;
|
|
40
|
+
return bundleInvalid('bundle contains an unsupported file member', path, 'bundle.json, commands.json, or memory/**/*.md', 'Remove unsupported members from the archive.', path);
|
|
41
|
+
}
|
|
42
|
+
if (path === 'memory' || path.startsWith('memory/'))
|
|
43
|
+
return undefined;
|
|
44
|
+
return bundleInvalid('bundle contains an unsupported directory member', path, 'memory or a directory below memory/', 'Remove unsupported directory members from the archive.', path);
|
|
45
|
+
}
|
|
46
|
+
/** A member path as it will exist on disk: directories carry no trailing slash. */
|
|
47
|
+
function materializedPath(member) {
|
|
48
|
+
return member.type === 'directory' && member.path.endsWith('/') ? member.path.slice(0, -1) : member.path;
|
|
49
|
+
}
|
|
50
|
+
/** Reject member sets that cannot become one filesystem tree — a path claimed as
|
|
51
|
+
* both a file and a directory, the same path twice after directory
|
|
52
|
+
* normalization, or a file that another member nests beneath. */
|
|
53
|
+
function validateMemberTree(members) {
|
|
54
|
+
const claimed = new Map();
|
|
55
|
+
for (const member of members) {
|
|
56
|
+
const path = materializedPath(member);
|
|
57
|
+
const existing = claimed.get(path);
|
|
58
|
+
if (existing !== undefined) {
|
|
59
|
+
return bundleInvalid(existing === member.type
|
|
60
|
+
? 'bundle contains a duplicate member'
|
|
61
|
+
: 'bundle claims one path as both a file and a directory', `${path} (${existing} and ${member.type})`, 'each materialized path exactly once, with one type', 'Emit each archive path once, as a single member type.', path);
|
|
62
|
+
}
|
|
63
|
+
claimed.set(path, member.type);
|
|
64
|
+
}
|
|
65
|
+
for (const [path, type] of claimed) {
|
|
66
|
+
if (type !== 'file')
|
|
67
|
+
continue;
|
|
68
|
+
for (const other of claimed.keys()) {
|
|
69
|
+
if (other.startsWith(`${path}/`)) {
|
|
70
|
+
return bundleInvalid('bundle nests a member beneath a regular-file path', `${other} beneath file ${path}`, 'members nested only beneath directory paths', 'Emit the parent path as a directory or remove the nested member.', other);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
async function parseArchive(archive) {
|
|
77
|
+
const members = [];
|
|
78
|
+
const seen = new Set();
|
|
79
|
+
let memberIssue;
|
|
80
|
+
await new Promise((resolve, reject) => {
|
|
81
|
+
const parser = new Parser({
|
|
82
|
+
strict: true,
|
|
83
|
+
maxMetaEntrySize: Number.MAX_SAFE_INTEGER,
|
|
84
|
+
gzip: false,
|
|
85
|
+
brotli: false,
|
|
86
|
+
zstd: false,
|
|
87
|
+
onReadEntry: (entry) => {
|
|
88
|
+
const path = entry.path;
|
|
89
|
+
const type = entry.type === 'File' || entry.type === 'OldFile'
|
|
90
|
+
? 'file'
|
|
91
|
+
: entry.type === 'Directory'
|
|
92
|
+
? 'directory'
|
|
93
|
+
: undefined;
|
|
94
|
+
if (type === undefined || entry.unsupported || entry.ignore || entry.linkpath !== undefined) {
|
|
95
|
+
memberIssue ??= bundleInvalid('bundle member must be a regular file or directory without a link target', `${path} (${entry.type})`, 'a regular file or directory member without link metadata', 'Remove links and unsupported member types from the archive.', path);
|
|
96
|
+
entry.resume();
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
memberIssue ??= validateMemberName(path, type);
|
|
100
|
+
memberIssue ??= validateMemberShape(path, type);
|
|
101
|
+
if (seen.has(path)) {
|
|
102
|
+
memberIssue ??= bundleInvalid('bundle contains a duplicate member', path, 'each member path exactly once', 'Emit each archive member only once.', path);
|
|
103
|
+
}
|
|
104
|
+
seen.add(path);
|
|
105
|
+
const chunks = [];
|
|
106
|
+
entry.on('data', (chunk) => chunks.push(chunk));
|
|
107
|
+
entry.on('end', () => {
|
|
108
|
+
if (memberIssue === undefined)
|
|
109
|
+
members.push({ path, type, bytes: new Uint8Array(Buffer.concat(chunks)) });
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
parser.on('ignoredEntry', (entry) => {
|
|
114
|
+
const path = entry.path;
|
|
115
|
+
memberIssue ??= bundleInvalid('bundle contains an ignored or unsupported archive member', `${path} (${entry.type})`, 'only supported regular file or directory members', 'Remove ignored or unsupported members from the archive.', path);
|
|
116
|
+
entry.resume();
|
|
117
|
+
});
|
|
118
|
+
parser.once('error', reject);
|
|
119
|
+
parser.once('end', resolve);
|
|
120
|
+
try {
|
|
121
|
+
parser.end(Buffer.from(archive));
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
reject(error);
|
|
125
|
+
}
|
|
126
|
+
}).catch((error) => {
|
|
127
|
+
memberIssue ??= bundleInvalid('bundle archive could not be parsed', error instanceof Error ? error.message : String(error), 'a valid complete uncompressed tar archive', 'Fix the archive format and serve it again.');
|
|
128
|
+
});
|
|
129
|
+
return memberIssue === undefined ? { members } : { issue: memberIssue };
|
|
130
|
+
}
|
|
131
|
+
function parseBundleMetadata(bytes) {
|
|
132
|
+
let raw;
|
|
133
|
+
try {
|
|
134
|
+
raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return bundleInvalid('bundle.json is not valid JSON', 'invalid JSON', '{"bundleVersion":1}', 'Write valid bundle metadata.', 'bundle.json');
|
|
138
|
+
}
|
|
139
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw) || Object.keys(raw).length !== 1 || raw['bundleVersion'] !== 1) {
|
|
140
|
+
return bundleInvalid('bundle.json must contain exactly {"bundleVersion":1}', JSON.stringify(raw), 'an object with only bundleVersion set to 1', 'Set bundle.json to {"bundleVersion":1}.', 'bundle.json');
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
function parseCommands(bytes, reservedCoreNames) {
|
|
145
|
+
let raw;
|
|
146
|
+
try {
|
|
147
|
+
raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return {
|
|
151
|
+
issues: [bundleInvalid('commands.json is not valid JSON', 'invalid JSON', 'a valid command-manifest JSON object', 'Regenerate commands.json.', 'commands.json')],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
const validation = validateCommandManifest(raw, { transport: 'http', reservedCoreNames });
|
|
155
|
+
return {
|
|
156
|
+
...(validation.manifest !== undefined ? { commands: validation.manifest } : {}),
|
|
157
|
+
issues: validation.issues,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/** Validate a Core-served plugin directory archive entirely in memory. */
|
|
161
|
+
export async function validatePluginBundle(archive, options) {
|
|
162
|
+
const envelope = archiveEnvelopeIssue(archive);
|
|
163
|
+
if (envelope !== undefined)
|
|
164
|
+
return { issues: [envelope] };
|
|
165
|
+
const parsed = await parseArchive(archive);
|
|
166
|
+
if (parsed.issue !== undefined || parsed.members === undefined)
|
|
167
|
+
return { issues: [parsed.issue] };
|
|
168
|
+
const treeIssue = validateMemberTree(parsed.members);
|
|
169
|
+
if (treeIssue !== undefined)
|
|
170
|
+
return { issues: [treeIssue] };
|
|
171
|
+
const bundle = parsed.members.find((member) => member.path === 'bundle.json' && member.type === 'file');
|
|
172
|
+
const commands = parsed.members.find((member) => member.path === 'commands.json' && member.type === 'file');
|
|
173
|
+
if (bundle === undefined || commands === undefined) {
|
|
174
|
+
return {
|
|
175
|
+
issues: [bundleInvalid('bundle must contain exactly one bundle.json and one commands.json regular file', `bundle.json=${bundle !== undefined}, commands.json=${commands !== undefined}`, 'one regular bundle.json and one regular commands.json member', 'Add the required metadata members to the archive.')],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const metadataIssue = parseBundleMetadata(bundle.bytes);
|
|
179
|
+
if (metadataIssue !== undefined)
|
|
180
|
+
return { issues: [metadataIssue] };
|
|
181
|
+
const commandValidation = parseCommands(commands.bytes, options.reservedCoreNames);
|
|
182
|
+
if (commandValidation.commands === undefined)
|
|
183
|
+
return { issues: commandValidation.issues };
|
|
184
|
+
return {
|
|
185
|
+
bundle: {
|
|
186
|
+
bundleVersion: 1,
|
|
187
|
+
commands: commandValidation.commands,
|
|
188
|
+
commandsBytes: commands.bytes,
|
|
189
|
+
directories: parsed.members
|
|
190
|
+
.filter((member) => member.type === 'directory')
|
|
191
|
+
.map((member) => ({ path: member.path })),
|
|
192
|
+
memory: parsed.members
|
|
193
|
+
.filter((member) => member.type === 'file' && member.path.startsWith('memory/'))
|
|
194
|
+
.map((member) => ({ path: member.path, bytes: member.bytes })),
|
|
195
|
+
},
|
|
196
|
+
issues: [],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
@@ -2,7 +2,6 @@ import type { InstalledPlugin, PluginTransport } from '../../types.js';
|
|
|
2
2
|
import { type ValidatedCommandManifest } from '../command-manifests/manifest.js';
|
|
3
3
|
import type { CommandManifestIssue, DeclBranch as DeclBranchGeneric, DeclLeaf as DeclLeafGeneric } from '../command-manifests/schema.js';
|
|
4
4
|
import type { CommandRegistrySnapshot } from '../command-manifests/registry.js';
|
|
5
|
-
import type { HttpPluginManifestStore } from './store.js';
|
|
6
5
|
export interface CommandDiscoveryIssue extends CommandManifestIssue {
|
|
7
6
|
plugin: string;
|
|
8
7
|
}
|
|
@@ -22,12 +21,6 @@ export interface PluginCommandValidation {
|
|
|
22
21
|
transport?: PluginTransport;
|
|
23
22
|
contributions: ValidatedContribution[];
|
|
24
23
|
issues: CommandDiscoveryIssue[];
|
|
25
|
-
absentStore?: boolean;
|
|
26
|
-
httpManifestStore?: HttpPluginManifestStore;
|
|
27
|
-
}
|
|
28
|
-
export interface AbsentStoreHydration {
|
|
29
|
-
hydratedAny: boolean;
|
|
30
|
-
diagnostics: string[];
|
|
31
24
|
}
|
|
32
25
|
export declare function effectiveCommandPlugins(startDir?: string, profileId?: string | null): InstalledPlugin[];
|
|
33
26
|
export declare function validatePluginCommands(plugin: InstalledPlugin, reservedNames?: ReadonlySet<string>): PluginCommandValidation;
|
|
@@ -38,4 +31,3 @@ export declare function discoverCommandContributions(reservedNames: ReadonlySet<
|
|
|
38
31
|
issues: CommandDiscoveryIssue[];
|
|
39
32
|
};
|
|
40
33
|
export declare function buildExternalCommandSnapshot(reservedCoreNames: ReadonlySet<string>): CommandRegistrySnapshot;
|
|
41
|
-
export declare function hydrateAbsentHttpPlugins(): Promise<AbsentStoreHydration>;
|
|
@@ -6,8 +6,6 @@ import { validateCommandManifest } from '../command-manifests/manifest.js';
|
|
|
6
6
|
import { resolveCommandRegistry } from '../command-manifests/registry.js';
|
|
7
7
|
import { adaptPluginContributions } from './compose.js';
|
|
8
8
|
import { validateHttpPluginTransport } from './endpoint.js';
|
|
9
|
-
import { readHttpPluginManifest, resolveHttpPluginManifestStore, writeHttpPluginManifest } from './store.js';
|
|
10
|
-
import { fetchHttpPluginManifest } from './transport/http-fetch.js';
|
|
11
9
|
export function effectiveCommandPlugins(startDir = process.cwd(), profileId) {
|
|
12
10
|
const seen = new Set();
|
|
13
11
|
const result = [];
|
|
@@ -97,10 +95,7 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
|
|
|
97
95
|
const transport = transportFor(plugin, issues);
|
|
98
96
|
if (transport === undefined)
|
|
99
97
|
return { plugin, manifestPath, contributions: [], issues };
|
|
100
|
-
const
|
|
101
|
-
? resolveHttpPluginManifestStore({ root: plugin.root, commands }) ?? undefined
|
|
102
|
-
: undefined;
|
|
103
|
-
const safe = transport.kind === 'http' ? httpManifestStore?.path ?? null : safePath(plugin.root, commands);
|
|
98
|
+
const safe = safePath(plugin.root, commands);
|
|
104
99
|
if (safe === null) {
|
|
105
100
|
issues.push({ code: 'command_path_unsafe', plugin: plugin.name, message: 'commands pointer escapes the plugin root or is not a regular file', received: commands, expected: 'a relative path to a regular file inside the plugin root', next: 'Fix plugin.json.commands.', path: 'commands' });
|
|
106
101
|
return { plugin, manifestPath, transport, contributions: [], issues };
|
|
@@ -108,14 +103,12 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
|
|
|
108
103
|
manifestPath = safe;
|
|
109
104
|
let bytes;
|
|
110
105
|
try {
|
|
111
|
-
bytes =
|
|
106
|
+
bytes = readFileSync(safe);
|
|
112
107
|
}
|
|
113
108
|
catch {
|
|
114
109
|
bytes = null;
|
|
115
110
|
}
|
|
116
111
|
if (bytes === null) {
|
|
117
|
-
if (transport.kind === 'http')
|
|
118
|
-
return { plugin, manifestPath, transport, contributions: [], issues, absentStore: true, httpManifestStore };
|
|
119
112
|
issues.push({ code: 'command_manifest_unreadable', plugin: plugin.name, message: 'commands.json is missing or unreadable', received: safe, expected: 'a readable JSON file', next: 'Reinstall or update the plugin.' });
|
|
120
113
|
return { plugin, manifestPath, transport, contributions: [], issues };
|
|
121
114
|
}
|
|
@@ -124,8 +117,6 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
|
|
|
124
117
|
raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
|
|
125
118
|
}
|
|
126
119
|
catch {
|
|
127
|
-
if (transport.kind === 'http')
|
|
128
|
-
return { plugin, manifestPath, transport, contributions: [], issues, absentStore: true, httpManifestStore };
|
|
129
120
|
issues.push({ code: 'command_manifest_invalid', plugin: plugin.name, message: 'commands.json is not valid JSON', received: safe, expected: 'a JSON object', next: 'Regenerate commands.json.' });
|
|
130
121
|
return { plugin, manifestPath, transport, contributions: [], issues };
|
|
131
122
|
}
|
|
@@ -171,31 +162,3 @@ export function buildExternalCommandSnapshot(reservedCoreNames) {
|
|
|
171
162
|
const resolved = resolveCommandRegistry(candidates, reservedCoreNames);
|
|
172
163
|
return { contributions: resolved.contributions, issues: [...validations.flatMap((validation) => validation.issues.map((issue) => contributorIssue(validation.plugin, issue))), ...resolved.issues] };
|
|
173
164
|
}
|
|
174
|
-
export async function hydrateAbsentHttpPlugins() {
|
|
175
|
-
let hydratedAny = false;
|
|
176
|
-
const diagnostics = [];
|
|
177
|
-
for (const validation of discoverPluginCommandCandidates()) {
|
|
178
|
-
if (validation.transport?.kind !== 'http')
|
|
179
|
-
continue;
|
|
180
|
-
const unsafePath = validation.issues.find((issue) => issue.code === 'command_path_unsafe');
|
|
181
|
-
if (unsafePath !== undefined) {
|
|
182
|
-
diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${unsafePath.code}: ${unsafePath.message} — ${unsafePath.next}`);
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
if (!validation.absentStore || validation.httpManifestStore === undefined)
|
|
186
|
-
continue;
|
|
187
|
-
try {
|
|
188
|
-
const result = await fetchHttpPluginManifest({ name: validation.plugin.name, endpoint: validation.transport.endpoint, ...(validation.transport.authEnv !== undefined ? { authEnv: validation.transport.authEnv } : {}) });
|
|
189
|
-
if (result.status === 200) {
|
|
190
|
-
writeHttpPluginManifest(validation.httpManifestStore, result.raw);
|
|
191
|
-
hydratedAny = true;
|
|
192
|
-
}
|
|
193
|
-
else
|
|
194
|
-
diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${result.message} — run \`crtr pkg plugin update --name ${validation.plugin.name}\``);
|
|
195
|
-
}
|
|
196
|
-
catch (error) {
|
|
197
|
-
diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${error.message} — run \`crtr pkg plugin update --name ${validation.plugin.name}\``);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return { hydratedAny, diagnostics };
|
|
201
|
-
}
|
|
@@ -1,42 +1,16 @@
|
|
|
1
1
|
import type { HttpPluginFetchTarget } from '../endpoint.js';
|
|
2
|
-
|
|
3
|
-
/** Result of a successful manifest fetch. */
|
|
2
|
+
/** Exact archive bytes returned by a successful authenticated bundle fetch. */
|
|
4
3
|
export interface FetchSuccess {
|
|
5
4
|
status: 200;
|
|
6
5
|
raw: Uint8Array;
|
|
7
6
|
}
|
|
8
|
-
/** Typed failures from manifest fetch. */
|
|
9
7
|
export type FetchResult = FetchSuccess | FetchFailure;
|
|
10
8
|
export interface FetchFailure {
|
|
11
9
|
status: 'auth_env_missing' | 'cli_unreachable' | 'cli_protocol_error';
|
|
12
10
|
message: string;
|
|
13
11
|
}
|
|
14
12
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* Implements the core authenticated GET primitive for T0/T2/T4 fetches:
|
|
18
|
-
* - Reads bearer token from `authEnv` env var at invocation time
|
|
19
|
-
* - Fails with `auth_env_missing` USAGE before network if env var is named but empty
|
|
20
|
-
* - Performs one GET request with `Accept: application/json` header
|
|
21
|
-
* - Attaches `Authorization: Bearer <token>` header when auth var is configured
|
|
22
|
-
* - A single 10-second socket-inactivity timeout (Node's `timeout` option) covers
|
|
23
|
-
* the whole request — there is no separate connect clock and no 30s total cap;
|
|
24
|
-
* that two-clock model belongs to the invoker's per-leaf HTTP calls (§6.6), not
|
|
25
|
-
* this simpler manifest-fetch primitive.
|
|
26
|
-
* - Returns exact response bytes on 2xx success
|
|
27
|
-
* - Returns typed `cli_unreachable` NETWORK on transport/timeout failures
|
|
28
|
-
* - Returns typed `cli_protocol_error` GENERAL on non-2xx without parseable error body
|
|
29
|
-
*
|
|
30
|
-
* No retries, no conditional request (ETag/If-None-Match), no 304 handling.
|
|
13
|
+
* One authenticated GET for a plugin directory archive. It has one ten-second
|
|
14
|
+
* inactivity timeout and never retries or conditionally revalidates.
|
|
31
15
|
*/
|
|
32
|
-
export declare function
|
|
33
|
-
/**
|
|
34
|
-
* Explicit refresh: unconditional fetch and replace stored manifest.
|
|
35
|
-
*
|
|
36
|
-
* Called when user runs `crtr pkg plugin update <name>`. Always fetches
|
|
37
|
-
* regardless of stored-manifest state, and replaces it on success.
|
|
38
|
-
* On failure, preserves existing manifest bytes and throws CrtrError.
|
|
39
|
-
*
|
|
40
|
-
* Returns the raw manifest bytes on success.
|
|
41
|
-
*/
|
|
42
|
-
export declare function refreshHttpPlugin(target: HttpPluginFetchTarget, store: HttpPluginManifestStore): Promise<Uint8Array>;
|
|
16
|
+
export declare function fetchHttpPluginBundle(registration: HttpPluginFetchTarget): Promise<FetchResult>;
|
|
@@ -1,31 +1,11 @@
|
|
|
1
1
|
import { URL } from 'node:url';
|
|
2
2
|
import { request as httpsRequest } from 'node:https';
|
|
3
3
|
import { request as httpRequest } from 'node:http';
|
|
4
|
-
import { writeHttpPluginManifest } from '../store.js';
|
|
5
|
-
import { general, network, usage } from '../../errors.js';
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
// Core fetch primitive
|
|
8
|
-
// ---------------------------------------------------------------------------
|
|
9
4
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* Implements the core authenticated GET primitive for T0/T2/T4 fetches:
|
|
13
|
-
* - Reads bearer token from `authEnv` env var at invocation time
|
|
14
|
-
* - Fails with `auth_env_missing` USAGE before network if env var is named but empty
|
|
15
|
-
* - Performs one GET request with `Accept: application/json` header
|
|
16
|
-
* - Attaches `Authorization: Bearer <token>` header when auth var is configured
|
|
17
|
-
* - A single 10-second socket-inactivity timeout (Node's `timeout` option) covers
|
|
18
|
-
* the whole request — there is no separate connect clock and no 30s total cap;
|
|
19
|
-
* that two-clock model belongs to the invoker's per-leaf HTTP calls (§6.6), not
|
|
20
|
-
* this simpler manifest-fetch primitive.
|
|
21
|
-
* - Returns exact response bytes on 2xx success
|
|
22
|
-
* - Returns typed `cli_unreachable` NETWORK on transport/timeout failures
|
|
23
|
-
* - Returns typed `cli_protocol_error` GENERAL on non-2xx without parseable error body
|
|
24
|
-
*
|
|
25
|
-
* No retries, no conditional request (ETag/If-None-Match), no 304 handling.
|
|
5
|
+
* One authenticated GET for a plugin directory archive. It has one ten-second
|
|
6
|
+
* inactivity timeout and never retries or conditionally revalidates.
|
|
26
7
|
*/
|
|
27
|
-
export async function
|
|
28
|
-
// Check auth env var and fail before network if named but empty
|
|
8
|
+
export async function fetchHttpPluginBundle(registration) {
|
|
29
9
|
let token;
|
|
30
10
|
if (registration.authEnv) {
|
|
31
11
|
token = process.env[registration.authEnv];
|
|
@@ -36,101 +16,43 @@ export async function fetchHttpPluginManifest(registration) {
|
|
|
36
16
|
};
|
|
37
17
|
}
|
|
38
18
|
}
|
|
39
|
-
// Parse endpoint URL
|
|
40
19
|
let url;
|
|
41
20
|
try {
|
|
42
21
|
url = new URL(registration.endpoint);
|
|
43
22
|
}
|
|
44
|
-
catch
|
|
23
|
+
catch {
|
|
45
24
|
return {
|
|
46
25
|
status: 'cli_protocol_error',
|
|
47
26
|
message: `Invalid endpoint URL: ${registration.endpoint}`,
|
|
48
27
|
};
|
|
49
28
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
'Accept': 'application/json',
|
|
53
|
-
};
|
|
54
|
-
if (token) {
|
|
29
|
+
const headers = { Accept: 'application/x-tar' };
|
|
30
|
+
if (token)
|
|
55
31
|
headers['Authorization'] = `Bearer ${token}`;
|
|
56
|
-
}
|
|
57
|
-
// Perform the GET request
|
|
58
32
|
return new Promise((resolve) => {
|
|
59
33
|
const request = url.protocol === 'https:' ? httpsRequest : httpRequest;
|
|
60
|
-
const
|
|
61
|
-
method: 'GET',
|
|
62
|
-
headers,
|
|
63
|
-
timeout: 10_000, // 10 second manifest fetch timeout per spec §6.6
|
|
64
|
-
};
|
|
65
|
-
const req = request(url, options, (res) => {
|
|
34
|
+
const req = request(url, { method: 'GET', headers, timeout: 10_000 }, (res) => {
|
|
66
35
|
let body = Buffer.alloc(0);
|
|
67
|
-
res.on('data', (chunk) => {
|
|
68
|
-
body = Buffer.concat([body, chunk]);
|
|
69
|
-
});
|
|
36
|
+
res.on('data', (chunk) => { body = Buffer.concat([body, chunk]); });
|
|
70
37
|
res.on('end', () => {
|
|
71
38
|
if (!res.statusCode) {
|
|
72
|
-
resolve({
|
|
73
|
-
status: 'cli_protocol_error',
|
|
74
|
-
message: 'No HTTP status code received.',
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
39
|
+
resolve({ status: 'cli_protocol_error', message: 'No HTTP status code received.' });
|
|
77
40
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
41
|
+
else if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
42
|
+
resolve({ status: 200, raw: new Uint8Array(body) });
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
resolve({ status: 'cli_protocol_error', message: `HTTP ${res.statusCode} from ${registration.endpoint}` });
|
|
85
46
|
}
|
|
86
|
-
// Non-2xx failure
|
|
87
|
-
resolve({
|
|
88
|
-
status: 'cli_protocol_error',
|
|
89
|
-
message: `HTTP ${res.statusCode} from ${registration.endpoint}`,
|
|
90
|
-
});
|
|
91
47
|
});
|
|
92
48
|
});
|
|
93
49
|
req.on('timeout', () => {
|
|
94
50
|
req.destroy();
|
|
95
|
-
resolve({
|
|
96
|
-
status: 'cli_unreachable',
|
|
97
|
-
message: `Request timeout (10s) fetching ${registration.endpoint}`,
|
|
98
|
-
});
|
|
51
|
+
resolve({ status: 'cli_unreachable', message: `Request timeout (10s) fetching ${registration.endpoint}` });
|
|
99
52
|
});
|
|
100
|
-
req.on('error', (
|
|
101
|
-
resolve({
|
|
102
|
-
status: 'cli_unreachable',
|
|
103
|
-
message: `Network error fetching ${registration.endpoint}: ${err.message}`,
|
|
104
|
-
});
|
|
53
|
+
req.on('error', (error) => {
|
|
54
|
+
resolve({ status: 'cli_unreachable', message: `Network error fetching ${registration.endpoint}: ${error.message}` });
|
|
105
55
|
});
|
|
106
56
|
req.end();
|
|
107
57
|
});
|
|
108
58
|
}
|
|
109
|
-
// ---------------------------------------------------------------------------
|
|
110
|
-
// Store-integrated helpers
|
|
111
|
-
// ---------------------------------------------------------------------------
|
|
112
|
-
/**
|
|
113
|
-
* Explicit refresh: unconditional fetch and replace stored manifest.
|
|
114
|
-
*
|
|
115
|
-
* Called when user runs `crtr pkg plugin update <name>`. Always fetches
|
|
116
|
-
* regardless of stored-manifest state, and replaces it on success.
|
|
117
|
-
* On failure, preserves existing manifest bytes and throws CrtrError.
|
|
118
|
-
*
|
|
119
|
-
* Returns the raw manifest bytes on success.
|
|
120
|
-
*/
|
|
121
|
-
export async function refreshHttpPlugin(target, store) {
|
|
122
|
-
// Unconditional fetch
|
|
123
|
-
const result = await fetchHttpPluginManifest(target);
|
|
124
|
-
if (result.status !== 200) {
|
|
125
|
-
if (result.status === 'auth_env_missing') {
|
|
126
|
-
throw usage(result.message);
|
|
127
|
-
}
|
|
128
|
-
if (result.status === 'cli_unreachable') {
|
|
129
|
-
throw network(result.message);
|
|
130
|
-
}
|
|
131
|
-
throw general(result.message);
|
|
132
|
-
}
|
|
133
|
-
// Write to the resolved HTTP manifest store.
|
|
134
|
-
writeHttpPluginManifest(store, result.raw);
|
|
135
|
-
return result.raw;
|
|
136
|
-
}
|
package/dist/core/command.d.ts
CHANGED
|
@@ -166,17 +166,5 @@ export interface ParseArgvOptions {
|
|
|
166
166
|
* Returns a plain object whose keys are camelCase parameter names.
|
|
167
167
|
* Optionally tracks which parameters were explicitly provided via a callback. */
|
|
168
168
|
export declare function parseArgv(params: InputParam[], tokens: string[], options?: ParseArgvOptions): Promise<Record<string, unknown>>;
|
|
169
|
-
|
|
170
|
-
export interface RunCliOptions {
|
|
171
|
-
/** The one unknown-first-token retry seam. Called exactly once only when an
|
|
172
|
-
* unknown first token misses at root (walk stopped at root, `path` empty,
|
|
173
|
-
* on a real non-help token), where absent HTTP-plugin stores may hydrate.
|
|
174
|
-
* A deeper unknown token under a known command (`path` non-empty) never
|
|
175
|
-
* calls it. It returns a freshly rebuilt root when hydration produced new
|
|
176
|
-
* commands to re-walk the original argv against, otherwise undefined to
|
|
177
|
-
* surface the plain `unknown_path` error. crtr's core fast path passes no
|
|
178
|
-
* options, so a recognized core first token has zero HTTP-plugin I/O. */
|
|
179
|
-
onUnknownFirstTokenMiss?: () => Promise<RootDef | undefined>;
|
|
180
|
-
}
|
|
181
|
-
export declare function runCli(root: RootDef, argv: string[], options?: RunCliOptions): Promise<void>;
|
|
169
|
+
export declare function runCli(root: RootDef, argv: string[]): Promise<void>;
|
|
182
170
|
export {};
|
package/dist/core/command.js
CHANGED
|
@@ -547,7 +547,7 @@ export async function parseArgv(params, tokens, options) {
|
|
|
547
547
|
}
|
|
548
548
|
return result;
|
|
549
549
|
}
|
|
550
|
-
export async function runCli(root, argv
|
|
550
|
+
export async function runCli(root, argv) {
|
|
551
551
|
// argv is process.argv — strip node binary + script path. `--json` is a
|
|
552
552
|
// global: pull it out anywhere it appears so the rest of argv parses against
|
|
553
553
|
// the leaf schema unchanged, and switch stdout from rendered prose to raw
|
|
@@ -570,21 +570,6 @@ export async function runCli(root, argv, options) {
|
|
|
570
570
|
}
|
|
571
571
|
let { node, path, remaining } = walk(root, tokens);
|
|
572
572
|
try {
|
|
573
|
-
// An unknown first token that misses at root is the only site absent
|
|
574
|
-
// HTTP-plugin stores may hydrate. A deeper unknown token under a known
|
|
575
|
-
// command never triggers it. Invoke the seam once; if it hydrated commands,
|
|
576
|
-
// re-walk the original argv against the rebuilt root. Keeping it inside the
|
|
577
|
-
// try sends any seam failure through the ordinary error handler.
|
|
578
|
-
if (options?.onUnknownFirstTokenMiss !== undefined &&
|
|
579
|
-
node.kind === 'root' &&
|
|
580
|
-
path.length === 0 &&
|
|
581
|
-
remaining.length > 0 &&
|
|
582
|
-
remaining[0] !== '-h' &&
|
|
583
|
-
remaining[0] !== '--help') {
|
|
584
|
-
const rebuilt = await options.onUnknownFirstTokenMiss();
|
|
585
|
-
if (rebuilt !== undefined)
|
|
586
|
-
({ node, path, remaining } = walk(rebuilt, tokens));
|
|
587
|
-
}
|
|
588
573
|
// Passthrough branches (e.g. `crtr capture`) opt out of the tree model
|
|
589
574
|
// entirely: forward every token after the branch verbatim to an external
|
|
590
575
|
// binary before any of the normal unknown-path / help / dispatch logic
|
package/dist/core/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Scope, ScopeConfig, ScopeState, KindConfig, ModelLaddersConfig, ModelProvider, ModelStrength, ModelRouteConfig, ModelRoutingConfig } from '../types.js';
|
|
2
|
+
import { type BindingId } from './keybindings/catalog.js';
|
|
2
3
|
export declare function configPath(scope: Scope): string | null;
|
|
3
4
|
export declare function statePath(scope: Scope): string | null;
|
|
4
5
|
export declare function readConfig(scope: Scope): ScopeConfig;
|
|
@@ -22,6 +23,9 @@ export declare function writeConfig(scope: Scope, config: ScopeConfig): void;
|
|
|
22
23
|
export declare function writeRawConfig(scope: Scope, config: Partial<ScopeConfig>): void;
|
|
23
24
|
export declare function writeState(scope: Scope, state: ScopeState): void;
|
|
24
25
|
export declare function ensureScopeInitialized(scope: Scope, root: string): void;
|
|
26
|
+
/** Normalize the user-owned list of attach actions allowed to bridge through an
|
|
27
|
+
* occupied tmux root binding. Unknown and non-attach ids have no effect. */
|
|
28
|
+
export declare function normalizeTmuxPassthrough(raw: unknown): BindingId[];
|
|
25
29
|
/** Raw (un-defaulted) partial config for one scope, or null if the scope has
|
|
26
30
|
* no root or no config.json. Used by `readMergedLaunchConfig` to layer
|
|
27
31
|
* scopes onto each other WITHOUT each scope's own default-fill masking a
|
package/dist/core/config.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { mkdirSync, rmSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { isDeepStrictEqual } from 'node:util';
|
|
4
|
-
import { CONFIG_FILE, STATE_FILE, CONDENSED_HISTORY_MODES, defaultScopeConfig, defaultScopeState, defaultModelLaddersConfig, defaultKindsConfig, defaultRemoteCanvasConfig } from '../types.js';
|
|
4
|
+
import { CONFIG_FILE, STATE_FILE, CONDENSED_HISTORY_MODES, MOUSE_MODE_DEFAULTS, DEFAULT_WHIP_MESSAGES, defaultScopeConfig, defaultScopeState, defaultModelLaddersConfig, defaultKindsConfig, defaultRemoteCanvasConfig } from '../types.js';
|
|
5
|
+
import { BINDING_CATALOG, BINDING_IDS, isAttachPaneBinding } from './keybindings/catalog.js';
|
|
5
6
|
import { emitEvent } from './events/emit.js';
|
|
6
7
|
import { atomicWriteJson, readJsonIfExists, writeJson, ensureDir } from './fs-utils.js';
|
|
7
8
|
import { scopeRoot, requireScopeRoot, findProjectScopeRoots } from './scope.js';
|
|
8
9
|
import { profileRoot } from './profiles/manifest.js';
|
|
9
10
|
import { SCOPE_CONFIG_KEYS } from './user-settings.js';
|
|
11
|
+
import { normalizeWorkingGerunds } from '../shared/working-activity.js';
|
|
10
12
|
function configPathFor(root) {
|
|
11
13
|
return join(root, CONFIG_FILE);
|
|
12
14
|
}
|
|
@@ -132,7 +134,7 @@ export function ensureScopeInitialized(scope, root) {
|
|
|
132
134
|
// a missing `modelLadders` from whatever build is CURRENTLY running, and an explicit
|
|
133
135
|
// user override (`sys config set modelLadders...`) still persists and still wins.
|
|
134
136
|
// Keybindings are sparse user overrides, so an untouched scope omits that member too.
|
|
135
|
-
const { modelLadders: _omittedModelLadders, keybindings: _omittedKeybindings, brokerThresholds, ...rest } = defaultScopeConfig();
|
|
137
|
+
const { modelLadders: _omittedModelLadders, keybindings: _omittedKeybindings, tmux_passthrough: _omittedTmuxPassthrough, brokerThresholds, ...rest } = defaultScopeConfig();
|
|
136
138
|
// Broker thresholds are host-wide daemon policy, so only user scope
|
|
137
139
|
// persists them. Project config must never acquire a machine setting.
|
|
138
140
|
atomicWriteJson(cfgPath, scope === 'user' ? { ...rest, brokerThresholds } : rest);
|
|
@@ -149,6 +151,14 @@ function normalizeKeybindings(raw) {
|
|
|
149
151
|
}
|
|
150
152
|
return out;
|
|
151
153
|
}
|
|
154
|
+
const ATTACH_PANE_BINDING_IDS = new Set(BINDING_CATALOG.filter(isAttachPaneBinding).map((definition) => definition.id));
|
|
155
|
+
/** Normalize the user-owned list of attach actions allowed to bridge through an
|
|
156
|
+
* occupied tmux root binding. Unknown and non-attach ids have no effect. */
|
|
157
|
+
export function normalizeTmuxPassthrough(raw) {
|
|
158
|
+
if (!Array.isArray(raw))
|
|
159
|
+
return [];
|
|
160
|
+
return [...new Set(raw.filter((id) => typeof id === 'string' && BINDING_IDS.has(id) && ATTACH_PANE_BINDING_IDS.has(id)))];
|
|
161
|
+
}
|
|
152
162
|
function mergeModelLadders(raw, base = defaultModelLaddersConfig()) {
|
|
153
163
|
const defaults = base;
|
|
154
164
|
if (raw === null || typeof raw !== 'object')
|
|
@@ -414,6 +424,12 @@ function mergeBrokerThresholds(raw, defaults) {
|
|
|
414
424
|
? { warning, automaticReviveCap }
|
|
415
425
|
: { ...defaults };
|
|
416
426
|
}
|
|
427
|
+
function normalizeWhipMessages(raw) {
|
|
428
|
+
if (!Array.isArray(raw))
|
|
429
|
+
return [...DEFAULT_WHIP_MESSAGES];
|
|
430
|
+
const messages = raw.filter((message) => typeof message === 'string' && message.trim() !== '').map((message) => message.trim());
|
|
431
|
+
return messages.length > 0 ? messages : [...DEFAULT_WHIP_MESSAGES];
|
|
432
|
+
}
|
|
417
433
|
function mergeConfig(partial) {
|
|
418
434
|
const defaults = defaultScopeConfig();
|
|
419
435
|
const schema_version = defaults.schema_version;
|
|
@@ -436,19 +452,28 @@ function mergeConfig(partial) {
|
|
|
436
452
|
: defaults.auto_open_child_viewers;
|
|
437
453
|
const brokerThresholds = mergeBrokerThresholds(partial.brokerThresholds, defaults.brokerThresholds);
|
|
438
454
|
const completion_bell = typeof partial.completion_bell === 'boolean' ? partial.completion_bell : defaults.completion_bell;
|
|
455
|
+
const working_gerunds = normalizeWorkingGerunds(partial.working_gerunds);
|
|
456
|
+
const whip_mode = typeof partial.whip_mode === 'boolean' ? partial.whip_mode : defaults.whip_mode;
|
|
457
|
+
const whip_messages = normalizeWhipMessages(partial.whip_messages);
|
|
458
|
+
const mouse_mode_default = MOUSE_MODE_DEFAULTS.includes(partial.mouse_mode_default)
|
|
459
|
+
? partial.mouse_mode_default
|
|
460
|
+
: defaults.mouse_mode_default;
|
|
439
461
|
const live_cycles = normalizePositiveInteger(partial.live_cycles, defaults.live_cycles);
|
|
440
462
|
const condensed_history = CONDENSED_HISTORY_MODES.includes(partial.condensed_history)
|
|
441
463
|
? partial.condensed_history
|
|
442
464
|
: defaults.condensed_history;
|
|
443
465
|
const fold_finished_tools = typeof partial.fold_finished_tools === 'boolean' ? partial.fold_finished_tools : defaults.fold_finished_tools;
|
|
466
|
+
const summarize_tool_calls = typeof partial.summarize_tool_calls === 'boolean' ? partial.summarize_tool_calls : defaults.summarize_tool_calls;
|
|
467
|
+
const detailed_tool_recaps = typeof partial.detailed_tool_recaps === 'boolean' ? partial.detailed_tool_recaps : defaults.detailed_tool_recaps;
|
|
444
468
|
const keybindings = normalizeKeybindings(partial.keybindings);
|
|
469
|
+
const tmux_passthrough = normalizeTmuxPassthrough(partial.tmux_passthrough);
|
|
445
470
|
const modelLadders = mergeModelLadders(partial.modelLadders);
|
|
446
471
|
const modelRoutes = mergeModelRoutes(partial.modelRoutes);
|
|
447
472
|
const modelRouting = mergeModelRouting(partial.modelRouting, undefined);
|
|
448
473
|
const kinds = mergeKinds(partial.kinds);
|
|
449
474
|
const remoteCanvas = mergeRemoteCanvas(partial.remoteCanvas);
|
|
450
475
|
const spawnEnv = mergeSpawnEnv(partial.spawnEnv, defaults.spawnEnv?.allow);
|
|
451
|
-
return { schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, completion_bell, live_cycles, condensed_history, fold_finished_tools, keybindings, modelLadders, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, spawnEnv };
|
|
476
|
+
return { schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, completion_bell, working_gerunds, whip_mode, whip_messages, mouse_mode_default, live_cycles, condensed_history, fold_finished_tools, summarize_tool_calls, detailed_tool_recaps, keybindings, tmux_passthrough, modelLadders, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, spawnEnv };
|
|
452
477
|
}
|
|
453
478
|
/** Raw (un-defaulted) partial config for one scope, or null if the scope has
|
|
454
479
|
* no root or no config.json. Used by `readMergedLaunchConfig` to layer
|