@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,15 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import test from 'node:test';
|
|
3
|
+
import { lintShortPreviewBody } from '../lint.js';
|
|
4
|
+
const previewMemory = {
|
|
5
|
+
'system-prompt-visibility': 'preview',
|
|
6
|
+
'file-read-visibility': 'none',
|
|
7
|
+
};
|
|
8
|
+
test('memory lint warns when a preview body is short enough to inline', () => {
|
|
9
|
+
const shortBody = Array.from({ length: 29 }, (_, index) => `word${index}`).join(' ');
|
|
10
|
+
assert.match(lintShortPreviewBody(previewMemory, shortBody) ?? '', /body is 29 words but system-prompt-visibility is `preview`; use `content`/);
|
|
11
|
+
const contentMemory = { ...previewMemory, 'system-prompt-visibility': 'content' };
|
|
12
|
+
assert.equal(lintShortPreviewBody(contentMemory, shortBody), null);
|
|
13
|
+
const thresholdBody = Array.from({ length: 30 }, (_, index) => `word${index}`).join(' ');
|
|
14
|
+
assert.equal(lintShortPreviewBody(previewMemory, thresholdBody), null);
|
|
15
|
+
});
|
|
@@ -22,12 +22,12 @@ function pruneEmptyParents(filePath, nameSegments) {
|
|
|
22
22
|
export const deleteLeaf = defineLeaf({
|
|
23
23
|
name: 'delete',
|
|
24
24
|
description: 'delete a memory document by name',
|
|
25
|
-
whenToUse: 'a stored document is wrong, obsolete, or superseded and should be removed — the sanctioned way to delete one, so you never rm the markdown off disk. Resolves the name exactly as `read` does (node > project stack > profile > user precedence, leaf-name fallback) and removes that file: if you can read it, you can delete it. Refuses docs you do not own — builtin docs (shipped with the package) and installed-plugin docs (managed by `crtr pkg`) — and refuses an ambiguous leaf name rather than guessing which doc to destroy; pass the full `area/topic` name or `--scope` to pin one.',
|
|
25
|
+
whenToUse: 'a stored document is wrong, obsolete, or superseded and should be removed — the sanctioned way to delete one, so you never rm the markdown off disk. Resolves the name exactly as `read` does (exact/direct matches by node > project stack > profile > user precedence, then leaf-name fallback) and removes that file: if you can read it, you can delete it. Refuses docs you do not own — builtin docs (shipped with the package) and installed-plugin docs (managed by `crtr pkg`) — and refuses an ambiguous leaf name rather than guessing which doc to destroy; pass the full `area/topic` name or `--scope` to pin one.',
|
|
26
26
|
help: {
|
|
27
27
|
name: 'memory delete',
|
|
28
28
|
summary: 'resolve a path-derived name and remove that document from its scope store',
|
|
29
29
|
params: [
|
|
30
|
-
{ kind: 'positional', name: 'name', required: true, constraint: 'Path-derived memory identifier (e.g. `topic` or `area/topic`), resolved as `read` resolves it: precedence node > project stack > profile > user,
|
|
30
|
+
{ kind: 'positional', name: 'name', required: true, constraint: 'Path-derived memory identifier (e.g. `topic` or `area/topic`), resolved as `read` resolves it: exact identity/direct path by precedence node > project stack > profile > user, then bare leaf fallback. A leaf matching multiple different docs in one source is rejected as ambiguous — pass the full name or --scope to disambiguate. May be scope-prefixed (`user/topic`) to pin the store directly.' },
|
|
31
31
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: [...MEMORY_SCOPES], required: false, constraint: 'Restrict resolution to this scope before deleting. Use it to disambiguate a leaf name present at multiple scopes, or to assert which store you mean. builtin is not a choice — builtin docs ship with the package and cannot be deleted.' },
|
|
32
32
|
],
|
|
33
33
|
output: [
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* `docName` is the doc's canonical resolver identity (explicit frontmatter
|
|
4
4
|
* `name`, else the normalized path-derived name) — persona layers under
|
|
5
5
|
* `kinds/` are recognized by it and never capped. */
|
|
6
|
+
export declare function lintShortPreviewBody(fm: Record<string, unknown>, body: string): string | null;
|
|
6
7
|
export declare function lintBodyLength(fm: Record<string, unknown>, body: string, docName: string): string | null;
|
|
7
8
|
/** Schema checks for a doc living in a substrate memory dir: a memory store
|
|
8
9
|
* holds ONLY substrate docs, so a missing/invalid `kind` is an authoring
|
|
@@ -44,6 +44,8 @@ const RUNG_FIELDS = ['system-prompt-visibility', 'file-read-visibility'];
|
|
|
44
44
|
const SYSTEM_CONTENT_MAX_WORDS = 1000;
|
|
45
45
|
const FILE_READ_MAX_WORDS = 1000;
|
|
46
46
|
const SYSTEM_PREVIEW_MAX_WORDS = 3000;
|
|
47
|
+
/** A routing line costs more than it saves for a short rule or fact. */
|
|
48
|
+
const PREVIEW_TO_CONTENT_MAX_WORDS = 30;
|
|
47
49
|
/** Rules a doc may suppress via frontmatter `lint-ignore`. */
|
|
48
50
|
const SUPPRESSIBLE_RULES = ['length'];
|
|
49
51
|
function ignoresRule(fm, rule) {
|
|
@@ -59,6 +61,19 @@ function countBodyWords(body) {
|
|
|
59
61
|
* `docName` is the doc's canonical resolver identity (explicit frontmatter
|
|
60
62
|
* `name`, else the normalized path-derived name) — persona layers under
|
|
61
63
|
* `kinds/` are recognized by it and never capped. */
|
|
64
|
+
export function lintShortPreviewBody(fm, body) {
|
|
65
|
+
const words = countBodyWords(body);
|
|
66
|
+
if (words >= PREVIEW_TO_CONTENT_MAX_WORDS)
|
|
67
|
+
return null;
|
|
68
|
+
const previewAxes = [
|
|
69
|
+
fm['system-prompt-visibility'] === 'preview' ? 'system-prompt-visibility' : undefined,
|
|
70
|
+
fm['file-read-visibility'] === 'preview' ? 'file-read-visibility' : undefined,
|
|
71
|
+
].filter((axis) => axis !== undefined);
|
|
72
|
+
if (previewAxes.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
const verb = previewAxes.length === 1 ? 'is' : 'are';
|
|
75
|
+
return `body is ${words} words but ${previewAxes.join(' and ')} ${verb} \`preview\`; use \`content\` on that axis so agents receive the whole rule without a separate memory read`;
|
|
76
|
+
}
|
|
62
77
|
export function lintBodyLength(fm, body, docName) {
|
|
63
78
|
if (ignoresRule(fm, 'length'))
|
|
64
79
|
return null;
|
|
@@ -175,7 +190,7 @@ export function lintSubstrateSchema(fm) {
|
|
|
175
190
|
* corpus. A dangling link is an authoring error caught HERE, never silently
|
|
176
191
|
* carried; leaf-name fallback is deliberately excluded so links stay stable
|
|
177
192
|
* as the graph grows and another document acquires the same leaf name. */
|
|
178
|
-
function lintFile(file, substrateStore, findings, corpusNames, fallbackName) {
|
|
193
|
+
function lintFile(file, substrateStore, findings, warnings, corpusNames, fallbackName) {
|
|
179
194
|
let fm;
|
|
180
195
|
let body;
|
|
181
196
|
try {
|
|
@@ -195,6 +210,9 @@ function lintFile(file, substrateStore, findings, corpusNames, fallbackName) {
|
|
|
195
210
|
const lengthError = lintBodyLength(fm, body, resolveDocName(fm, fallbackName));
|
|
196
211
|
if (lengthError !== null)
|
|
197
212
|
findings.push({ path: file, error: lengthError });
|
|
213
|
+
const shortPreviewWarning = lintShortPreviewBody(fm, body);
|
|
214
|
+
if (shortPreviewWarning !== null)
|
|
215
|
+
warnings.push(`${file}: ${shortPreviewWarning}`);
|
|
198
216
|
}
|
|
199
217
|
for (const name of docLinkNames(body)) {
|
|
200
218
|
if (!corpusNames.has(name)) {
|
|
@@ -252,7 +270,7 @@ export const lintLeaf = defineLeaf({
|
|
|
252
270
|
continue;
|
|
253
271
|
memoryCount += 1;
|
|
254
272
|
const fallbackName = normalizeDocName(relPath.replace(/\.md$/, ''));
|
|
255
|
-
lintFile(file, basename(file) !== 'MEMORY.md', findings, corpusNames, fallbackName);
|
|
273
|
+
lintFile(file, basename(file) !== 'MEMORY.md', findings, warnings, corpusNames, fallbackName);
|
|
256
274
|
}
|
|
257
275
|
};
|
|
258
276
|
for (const root of projectScopeRoots()) {
|
|
@@ -353,7 +371,7 @@ export const lintLeaf = defineLeaf({
|
|
|
353
371
|
corpora: { memory_stores: memoryCount, profile_projects: profileProjects },
|
|
354
372
|
findings: [],
|
|
355
373
|
warnings,
|
|
356
|
-
follow_up: warnings.length > 0 ? 'Corpus green —
|
|
374
|
+
follow_up: warnings.length > 0 ? 'Corpus green — review the warnings above for non-fatal authoring improvements.' : 'Corpus green — zero invalid frontmatter docs.',
|
|
357
375
|
};
|
|
358
376
|
},
|
|
359
377
|
});
|
|
@@ -10,12 +10,12 @@ import { MEMORY_KINDS } from './shared.js';
|
|
|
10
10
|
export const readLeaf = defineLeaf({
|
|
11
11
|
name: 'read',
|
|
12
12
|
description: 'load a memory document body by name',
|
|
13
|
-
whenToUse: 'a task in front of you matches a stored document and you already know its name — read it before improvising.
|
|
13
|
+
whenToUse: 'a task in front of you matches a stored document and you already know its name — read it before improvising. Exact identity and direct-path matches resolve by scope precedence (node > project stack > profile > user > builtin); bare leaf-name fallback is considered only when no such match exists. You name the document by its crtr identifier, never a file path — do not cat or find the markdown off disk. Reach for `crtr memory find` first when you do not yet know which document applies.',
|
|
14
14
|
help: {
|
|
15
15
|
name: 'memory read',
|
|
16
16
|
summary: 'resolve a path-derived name to its document body, frontmatter stripped unless --frontmatter',
|
|
17
17
|
params: [
|
|
18
|
-
{ kind: 'positional', name: 'name', required: true, constraint: 'Path-derived memory identifier (e.g. `topic` or `area/topic`).
|
|
18
|
+
{ kind: 'positional', name: 'name', required: true, constraint: 'Path-derived memory identifier (e.g. `topic` or `area/topic`). Exact identity and direct-path matches resolve by scope precedence: node > project stack > profile > user > builtin. A bare leaf falls back only when no exact/direct match exists.' },
|
|
19
19
|
{ kind: 'flag', name: 'kind', type: 'enum', choices: [...MEMORY_KINDS], required: false, constraint: 'Narrows resolution when the name is ambiguous across kinds.' },
|
|
20
20
|
{ kind: 'flag', name: 'frontmatter', type: 'bool', required: false, constraint: 'When present, includes the YAML frontmatter in the returned body. Off by default — only the body is returned.' },
|
|
21
21
|
],
|
|
@@ -35,8 +35,8 @@ export const readLeaf = defineLeaf({
|
|
|
35
35
|
const nameRaw = input['name'];
|
|
36
36
|
const kindFilter = input['kind'];
|
|
37
37
|
const includeFrontmatter = input['frontmatter'];
|
|
38
|
-
// Resolve a substrate/memory document across scopes
|
|
39
|
-
//
|
|
38
|
+
// Resolve a substrate/memory document across scopes: exact/direct matches
|
|
39
|
+
// by precedence first, then leaf-name fallback. --kind is threaded
|
|
40
40
|
// INTO resolution (not a post-filter): a nearer wrong-kind doc is skipped
|
|
41
41
|
// so a farther matching-kind doc is found instead of shadowing it into a
|
|
42
42
|
// false not_found. The substrate corpus now includes plugin docs (mounted
|
package/dist/commands/node.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// flow through `crtr push`, and scheduled commands live under `crtr cron`.
|
|
4
4
|
import { defineLeaf, defineBranch } from '../core/command.js';
|
|
5
5
|
import { InputError } from '../core/io.js';
|
|
6
|
-
import {
|
|
6
|
+
import { inboxHint } from '../core/keybindings/index.js';
|
|
7
7
|
import { writeClipboardText } from '../core/clipboard-text.js';
|
|
8
8
|
import { mark } from '../core/timing.js';
|
|
9
9
|
import { displayMessage } from '../core/runtime/tmux-chrome.js';
|
|
@@ -737,7 +737,7 @@ export const surfaceNodeFocusLeaf = defineLeaf({
|
|
|
737
737
|
throw new InputError({
|
|
738
738
|
error: 'not_focusable',
|
|
739
739
|
message: `node ${id} is a human-ask (kind:human), not a conversation — it has no pi session to focus.`,
|
|
740
|
-
next: `The pending question is queued for the human (${
|
|
740
|
+
next: `The pending question is queued for the human (${inboxHint()} opens the inbox); see it with \`crtr human list\`, or retract it with \`crtr human cancel ${id}\`.`,
|
|
741
741
|
});
|
|
742
742
|
}
|
|
743
743
|
// Opening history is not resuming work. A terminal/canceled/crashed node has
|
|
@@ -1733,11 +1733,11 @@ const nodeSubscription = defineBranch({
|
|
|
1733
1733
|
const nodePromote = defineLeaf({
|
|
1734
1734
|
name: 'promote',
|
|
1735
1735
|
description: 'become an orchestrator of a chosen kind',
|
|
1736
|
-
whenToUse: '
|
|
1736
|
+
whenToUse: 'the remaining work contains independent units that can run in parallel, and the task is large enough that coordinating and integrating them will materially improve intelligence, productivity, or elapsed throughput. Become a long-lived, roadmap-holding orchestrator whose primary job is steering those children across refreshes (`node yield`). Keep sequential or tightly coupled work in base mode even when it spans phases or context windows; spawning one helper does not itself require promotion',
|
|
1737
1737
|
tier: 'important',
|
|
1738
1738
|
help: {
|
|
1739
1739
|
name: 'node promote',
|
|
1740
|
-
summary: 'promote yourself to an orchestrator
|
|
1740
|
+
summary: 'promote yourself to an orchestrator when worthwhile parallel delegation should make coordination your primary job; task duration, sequential phases, or one helper do not qualify. Mode only — lifecycle stays as-is unless you pass --resident',
|
|
1741
1741
|
params: [
|
|
1742
1742
|
{ kind: 'flag', name: 'kind', type: 'string', required: false, constraint: 'Specialize as this kind of orchestrator. The <kinds> list below names every top-level installable kind and when to use each; a sub-kind (e.g. plan/reviewers/security) is valid too by exact path but not listed here. For an exact composed persona list, use `crtr sys prompt-review --list --kind <kind>` with the target kind. Defaults to your current kind. Promoting from a generic kind? CHOOSE a concrete one — it sets the orchestrator persona you revive into.' },
|
|
1743
1743
|
{ kind: 'flag', name: 'resident', type: 'bool', required: false, constraint: 'ALSO flip lifecycle→resident: make the node interactable — it stays dormant, woken by inbox/human, and is never forced to submit a final. Omit to stay terminal/orchestrator (delegates + holds a roadmap, but still owes a final up the spine and reaps when done).' },
|
|
@@ -1882,14 +1882,14 @@ const nodeLifecycle = defineBranch({
|
|
|
1882
1882
|
const nodeYield = defineLeaf({
|
|
1883
1883
|
name: 'yield',
|
|
1884
1884
|
description: 'refresh your context, same mode, against your roadmap or goal',
|
|
1885
|
-
whenToUse: 'your context is filling but the mandate remains; refresh in the same mode, or combine the refresh with promotion when
|
|
1885
|
+
whenToUse: 'your context is filling but the mandate remains; refresh in the same mode, or combine the refresh with promotion when meaningful independent work can run in parallel and coordinating it should become your primary job',
|
|
1886
1886
|
help: {
|
|
1887
1887
|
name: 'node yield',
|
|
1888
1888
|
summary: 'request a fresh context window against your roadmap or original goal; mode stays unchanged unless --promote is passed',
|
|
1889
1889
|
guide: 'Persist anything needed after refresh and send any pending human question before invoking; in-flight asks survive the refresh.',
|
|
1890
1890
|
params: [
|
|
1891
|
-
{ kind: 'flag', name: 'promote', type: 'bool', required: false, constraint: 'Also become an orchestrator as you refresh
|
|
1892
|
-
{ kind: 'flag', name: 'kind', type: 'string', required: false, constraint: 'Respecialize as you refresh
|
|
1891
|
+
{ kind: 'flag', name: 'promote', type: 'bool', required: false, constraint: 'Also become an orchestrator as you refresh. Pass only when (1) the remaining work contains independent units that can run in parallel and (2) the task is large enough that parallel execution will materially improve intelligence, productivity, or elapsed throughput after coordination and synthesis. Task length, context exhaustion, sequential phases, or one helper are not enough; keep hands-on work in base mode and yield again as needed. Promote when coordinating and integrating children becomes your primary job. Already an orchestrator? This is not an error: your mode stays orchestrator and a missing roadmap is seeded.' },
|
|
1892
|
+
{ kind: 'flag', name: 'kind', type: 'string', required: false, constraint: 'Respecialize as you refresh. The <kinds> list below names every top-level available kind and when to choose it; a sub-kind (e.g. plan/reviewers/security) is valid too by exact path but not listed here. Defaults to your current kind. With --promote it sets the orchestrator kind you become; without --promote it changes the kind while preserving your current mode.' },
|
|
1893
1893
|
{ kind: 'flag', name: 'model', type: 'enum', choices: ['ultra', 'strong'], required: false, constraint: 'Change the model your fresh revive runs on, by capability tier: `ultra` (frontier — reserve for high-taste judgment or enormous work: speccing, planning something large, e2e-testing something hard to test) or `strong` (opus — regular dev work). Omit to keep your current model. A node steering work is never weaker than opus, so these are the only two choices; the change is durable across future revives.' },
|
|
1894
1894
|
// Deliberate fail-first contract (#395): builtin orchestration guidance shows bare
|
|
1895
1895
|
// `crtr node yield`; that invocation fails fast and surfaces yield's full help just in
|
|
@@ -1903,6 +1903,7 @@ const nodeYield = defineLeaf({
|
|
|
1903
1903
|
{ name: 'model', type: 'string', required: false, constraint: 'The model tier your fresh revive will run on, present only when you changed it with --model.' },
|
|
1904
1904
|
{ name: 'will_refresh', type: 'boolean', required: true, constraint: 'Always true: end your turn and you will revive fresh.' },
|
|
1905
1905
|
],
|
|
1906
|
+
dynamicState: () => kindsStateBlock(),
|
|
1906
1907
|
outputKind: 'object',
|
|
1907
1908
|
effects: ['Sets intent=refresh; the stophook shuts the process down on next stop and the daemon revives it fresh.', '--kind and/or --model durably reshape the node (kind respecialization, model-tier pin) before the refresh-revive; --promote additionally flips mode→orchestrator and seeds a roadmap scaffold — mode is otherwise left exactly as it was.'],
|
|
1908
1909
|
},
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { join, resolve, isAbsolute } from 'node:path';
|
|
2
|
-
import { renameSync } from 'node:fs';
|
|
1
|
+
import { join, resolve, isAbsolute, sep } from 'node:path';
|
|
2
|
+
import { renameSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
3
4
|
import { defineLeaf } from '../../core/command.js';
|
|
4
|
-
import {
|
|
5
|
+
import { notFound, usage, general, network } from '../../core/errors.js';
|
|
5
6
|
import { findMarketplaceByName, findPluginByName, listAllPlugins } from '../../core/resolver.js';
|
|
6
7
|
import { pluginsDir, ensureProjectScopeRoot, userScopeRoot, resolveScopeArg, projectScopeRoot, requireScopeRoot, } from '../../core/scope.js';
|
|
7
8
|
import { updateConfig, updateState, ensureScopeInitialized } from '../../core/config.js';
|
|
8
9
|
import { pathExists, ensureDir, removePath, nowIso, linkOrCopy, isSymlink, atomicWriteJson } from '../../core/fs-utils.js';
|
|
9
10
|
import { clone, pull, deriveNameFromUrl, currentSha, isGitRepo } from '../../core/git.js';
|
|
10
|
-
import {
|
|
11
|
+
import { readMarketplaceManifest, readPluginManifest } from '../../core/manifest.js';
|
|
11
12
|
import { validatePluginCommands, validateEffectiveCommandPlugins } from '../../core/command-plugins/discovery.js';
|
|
12
13
|
import { normalizeEndpoint, validateEndpoint, validateHttpPluginTransport } from '../../core/command-plugins/endpoint.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
14
|
+
import { validatePluginBundle } from '../../core/command-plugins/bundle.js';
|
|
15
|
+
import { fetchHttpPluginBundle } from '../../core/command-plugins/transport/http-fetch.js';
|
|
15
16
|
import { SUBTREE_NAMES } from '../../build-root.js';
|
|
16
|
-
import { ExitCode } from '../../types.js';
|
|
17
17
|
import { isGitUrl, setPluginEnabled, resolveInstallScope } from './shared.js';
|
|
18
18
|
/** Validate a just-installed/updated plugin's command manifest, if it declares
|
|
19
19
|
* one. Returns undefined for plugins without a `commands` pointer. Never
|
|
@@ -32,66 +32,137 @@ function commandReport(name, scope) {
|
|
|
32
32
|
return { mounts: v.contributions.map((c) => c.node.name), issues: v.issues };
|
|
33
33
|
}
|
|
34
34
|
const PLUGIN_NAME_RE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
35
|
-
function unsafeHttpManifestPath(name, commands) {
|
|
36
|
-
throw new CrtrError('command_path_unsafe', `HTTP plugin "${name}" commands pointer escapes the plugin root or is not a regular file`, ExitCode.USAGE, { received: commands, field: 'commands', next: 'Fix plugin.json.commands.' });
|
|
37
|
-
}
|
|
38
35
|
function validateHttpInstall(name, endpoint, authEnv) {
|
|
39
|
-
if (typeof name !== 'string' || !PLUGIN_NAME_RE.test(name))
|
|
36
|
+
if (typeof name !== 'string' || !PLUGIN_NAME_RE.test(name))
|
|
40
37
|
throw usage('invalid --name: expected a lowercase kebab-case plugin handle');
|
|
41
|
-
}
|
|
42
38
|
const endpointValidation = validateEndpoint(endpoint);
|
|
43
|
-
if (!endpointValidation.isValid)
|
|
39
|
+
if (!endpointValidation.isValid)
|
|
44
40
|
throw usage(`invalid --endpoint: ${endpointValidation.errors.join('; ')}`);
|
|
45
|
-
}
|
|
46
41
|
const normalizedEndpoint = normalizeEndpoint(endpoint);
|
|
47
|
-
const transportValidation = validateHttpPluginTransport({
|
|
48
|
-
|
|
49
|
-
endpoint: normalizedEndpoint,
|
|
50
|
-
...(authEnv !== undefined ? { authEnv } : {}),
|
|
51
|
-
});
|
|
52
|
-
if (transportValidation.transport === undefined) {
|
|
42
|
+
const transportValidation = validateHttpPluginTransport({ kind: 'http', endpoint: normalizedEndpoint, ...(authEnv !== undefined ? { authEnv } : {}) });
|
|
43
|
+
if (transportValidation.transport === undefined)
|
|
53
44
|
throw usage(`invalid HTTP plugin transport: ${transportValidation.errors.join('; ')}`);
|
|
54
|
-
}
|
|
55
45
|
return transportValidation.transport;
|
|
56
46
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
function invocationTransport(bundle) {
|
|
48
|
+
return { kind: 'http', endpoint: new URL(bundle.endpoint).origin, ...(bundle.authEnv !== undefined ? { authEnv: bundle.authEnv } : {}) };
|
|
49
|
+
}
|
|
50
|
+
function stagedPath(stagingRoot, relative) {
|
|
51
|
+
const path = resolve(stagingRoot, relative);
|
|
52
|
+
if (path === stagingRoot || !path.startsWith(stagingRoot + sep)) {
|
|
53
|
+
throw general(`bundle member path escapes the staging directory: ${relative}`);
|
|
63
54
|
}
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
return path;
|
|
56
|
+
}
|
|
57
|
+
function writeStagedBundle(stagingRoot, manifest, bundle) {
|
|
58
|
+
atomicWriteJson(stagedPath(stagingRoot, '.crouter-plugin/plugin.json'), manifest);
|
|
59
|
+
for (const directory of bundle.directories)
|
|
60
|
+
ensureDir(stagedPath(stagingRoot, directory.path));
|
|
61
|
+
writeFileSync(stagedPath(stagingRoot, 'commands.json'), bundle.commandsBytes);
|
|
62
|
+
for (const document of bundle.memory) {
|
|
63
|
+
const target = stagedPath(stagingRoot, document.path);
|
|
64
|
+
ensureDir(resolve(target, '..'));
|
|
65
|
+
writeFileSync(target, document.bytes);
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
}
|
|
68
|
+
function validateStagedBundle(name, scope, root, manifest) {
|
|
69
|
+
const staged = { name, scope, root, manifest, enabled: true };
|
|
70
|
+
const validation = validatePluginCommands(staged, new Set(SUBTREE_NAMES));
|
|
71
|
+
if (validation.issues.length > 0) {
|
|
72
|
+
throw general(`bundle staged package for "${name}" is invalid`, { issues: validation.issues });
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function isSourceInstalled(plugin) {
|
|
76
|
+
return plugin.sourceMarketplace !== undefined || isGitRepo(plugin.root) || isSymlink(plugin.root);
|
|
77
|
+
}
|
|
78
|
+
function rejectLegacyHttpPlugin(name) {
|
|
79
|
+
throw general(`HTTP plugin "${name}" uses the removed commands-only endpoint format`, { next: `Run \`crtr pkg plugin remove ${name}\`, then reinstall it with \`crtr pkg plugin install --name ${name} --endpoint <archive-url>\`.` });
|
|
80
|
+
}
|
|
81
|
+
function existingBundleRoot(name, scope, root) {
|
|
82
|
+
if (!pathExists(root))
|
|
83
|
+
return undefined;
|
|
84
|
+
const existing = findPluginByName(name, scope);
|
|
85
|
+
if (existing?.manifest.bundle !== undefined)
|
|
86
|
+
return existing;
|
|
87
|
+
if (existing?.manifest.transport?.kind === 'http' && existing !== undefined && !isSourceInstalled(existing))
|
|
88
|
+
rejectLegacyHttpPlugin(name);
|
|
89
|
+
throw general(`plugin "${name}" already exists at ${root}; run \`crtr pkg plugin remove ${name}\` before installing the archive plugin.`);
|
|
90
|
+
}
|
|
91
|
+
async function replaceBundlePlugin(name, bundleSource, scope, options) {
|
|
92
|
+
const fetchTransport = validateHttpInstall(name, bundleSource.endpoint, bundleSource.authEnv);
|
|
93
|
+
const bundle = { endpoint: fetchTransport.endpoint, ...(fetchTransport.authEnv !== undefined ? { authEnv: fetchTransport.authEnv } : {}) };
|
|
94
|
+
const transport = invocationTransport(bundle);
|
|
95
|
+
const scopeRootPath = scope === 'project' ? ensureProjectScopeRoot() : userScopeRoot();
|
|
96
|
+
const root = join(scopeRootPath, 'plugins', name);
|
|
97
|
+
existingBundleRoot(name, scope, root);
|
|
98
|
+
const fetched = await fetchHttpPluginBundle({ name, endpoint: bundle.endpoint, ...(bundle.authEnv !== undefined ? { authEnv: bundle.authEnv } : {}) });
|
|
72
99
|
if (fetched.status !== 200) {
|
|
73
|
-
const message = `HTTP plugin
|
|
100
|
+
const message = `HTTP plugin bundle fetch failed for "${name}": ${fetched.message}`;
|
|
74
101
|
if (fetched.status === 'auth_env_missing')
|
|
75
102
|
throw usage(message);
|
|
76
103
|
if (fetched.status === 'cli_unreachable')
|
|
77
104
|
throw network(message);
|
|
78
105
|
throw general(message);
|
|
79
106
|
}
|
|
80
|
-
|
|
81
|
-
|
|
107
|
+
const validated = await validatePluginBundle(fetched.raw, { reservedCoreNames: new Set(SUBTREE_NAMES) });
|
|
108
|
+
if (validated.bundle === undefined)
|
|
109
|
+
throw general(`HTTP plugin bundle for "${name}" is invalid`, { issues: validated.issues });
|
|
110
|
+
const version = createHash('sha256').update(fetched.raw).digest('hex').slice(0, 12);
|
|
111
|
+
const manifest = {
|
|
82
112
|
name,
|
|
113
|
+
version,
|
|
83
114
|
commands: 'commands.json',
|
|
84
115
|
transport,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
116
|
+
bundle,
|
|
117
|
+
};
|
|
118
|
+
const tmpRoot = join(scopeRootPath, 'tmp');
|
|
119
|
+
const staging = join(tmpRoot, `${name}.${process.pid}`);
|
|
120
|
+
const previous = `${staging}.prev`;
|
|
121
|
+
if (pathExists(previous))
|
|
122
|
+
throw general(`cannot replace plugin "${name}": prior interrupted replacement remains at ${previous}`);
|
|
123
|
+
ensureDir(tmpRoot);
|
|
124
|
+
ensureDir(join(scopeRootPath, 'plugins'));
|
|
125
|
+
removePath(staging);
|
|
126
|
+
try {
|
|
127
|
+
ensureDir(staging);
|
|
128
|
+
writeStagedBundle(staging, manifest, validated.bundle);
|
|
129
|
+
validateStagedBundle(name, scope, staging, manifest);
|
|
130
|
+
let movedPrevious = false;
|
|
131
|
+
if (pathExists(root)) {
|
|
132
|
+
renameSync(root, previous);
|
|
133
|
+
movedPrevious = true;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
renameSync(staging, root);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (movedPrevious)
|
|
140
|
+
renameSync(previous, root);
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
if (movedPrevious)
|
|
144
|
+
removePath(previous);
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
removePath(staging);
|
|
148
|
+
}
|
|
149
|
+
ensureScopeInitialized(scope, scopeRootPath);
|
|
90
150
|
updateConfig(scope, (cfg) => {
|
|
91
|
-
cfg.plugins[name] = { enabled: true };
|
|
151
|
+
cfg.plugins[name] = { enabled: options.enable ? true : (cfg.plugins[name]?.enabled ?? true), version };
|
|
152
|
+
});
|
|
153
|
+
updateState(scope, (state) => {
|
|
154
|
+
if (state.plugins[name] === undefined)
|
|
155
|
+
state.plugins[name] = {};
|
|
156
|
+
state.plugins[name].last_updated = nowIso();
|
|
92
157
|
});
|
|
93
158
|
const commands = commandReport(name, scope);
|
|
94
|
-
|
|
159
|
+
if (commands === undefined)
|
|
160
|
+
throw general(`bundle plugin "${name}" has no staged command report`);
|
|
161
|
+
return { name, scope, path: root, transport: 'http', version, docs: validated.bundle.memory.length, commands };
|
|
162
|
+
}
|
|
163
|
+
async function installHttpPlugin(name, endpoint, authEnv, scope) {
|
|
164
|
+
const source = validateHttpInstall(name, endpoint, authEnv);
|
|
165
|
+
return replaceBundlePlugin(name, { endpoint: source.endpoint, ...(source.authEnv !== undefined ? { authEnv: source.authEnv } : {}) }, scope, { enable: true });
|
|
95
166
|
}
|
|
96
167
|
function classifyInstallRef(raw) {
|
|
97
168
|
if (raw.startsWith('./') || raw.startsWith('../') || raw.startsWith('/')) {
|
|
@@ -269,22 +340,13 @@ export function installFromMarketplace(ref, scope) {
|
|
|
269
340
|
return { name: ref.plugin, scope, path: destPluginDir };
|
|
270
341
|
}
|
|
271
342
|
async function updateOnePlugin(plugin, marketplaceCache, opts) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
const store = resolveHttpPluginManifestStore({ root: plugin.root, commands: commandsPath });
|
|
278
|
-
if (store === null)
|
|
279
|
-
unsafeHttpManifestPath(plugin.name, commandsPath);
|
|
280
|
-
await refreshHttpPlugin({
|
|
281
|
-
name: plugin.name,
|
|
282
|
-
endpoint: plugin.manifest.transport.endpoint,
|
|
283
|
-
...(plugin.manifest.transport.authEnv !== undefined ? { authEnv: plugin.manifest.transport.authEnv } : {}),
|
|
284
|
-
}, store);
|
|
285
|
-
const commands = commandReport(plugin.name, plugin.scope);
|
|
286
|
-
return { name: plugin.name, transport: 'http', updated: true, ...(commands !== undefined ? { commands } : {}) };
|
|
343
|
+
const sourceInstalled = isSourceInstalled(plugin);
|
|
344
|
+
if (!sourceInstalled && plugin.manifest.bundle !== undefined) {
|
|
345
|
+
const replaced = await replaceBundlePlugin(plugin.name, plugin.manifest.bundle, plugin.scope, { enable: plugin.enabled });
|
|
346
|
+
return { name: plugin.name, transport: 'http', updated: true, version: replaced.version, docs: replaced.docs, commands: replaced.commands };
|
|
287
347
|
}
|
|
348
|
+
if (plugin.manifest.transport?.kind === 'http' && !sourceInstalled)
|
|
349
|
+
rejectLegacyHttpPlugin(plugin.name);
|
|
288
350
|
let contentUpdate = { updated: false, sha: currentSha(plugin.root) ?? '' };
|
|
289
351
|
let marketplaceVersion;
|
|
290
352
|
if (plugin.sourceMarketplace !== undefined) {
|
|
@@ -309,7 +371,7 @@ async function updateOnePlugin(plugin, marketplaceCache, opts) {
|
|
|
309
371
|
const commands = commandReport(plugin.name, plugin.scope);
|
|
310
372
|
return {
|
|
311
373
|
name: plugin.name,
|
|
312
|
-
...(plugin.manifest.transport
|
|
374
|
+
...(plugin.manifest.transport !== undefined ? { transport: plugin.manifest.transport.kind } : {}),
|
|
313
375
|
updated: contentUpdate.updated,
|
|
314
376
|
sha: contentUpdate.sha,
|
|
315
377
|
...(commands !== undefined ? { commands } : {}),
|
|
@@ -318,13 +380,13 @@ async function updateOnePlugin(plugin, marketplaceCache, opts) {
|
|
|
318
380
|
export const pluginInstall = defineLeaf({
|
|
319
381
|
name: 'install',
|
|
320
382
|
description: 'install from a ref or HTTP endpoint',
|
|
321
|
-
whenToUse: 'installing one plugin from a marketplace ref, git URL, local path, or an HTTP
|
|
383
|
+
whenToUse: 'installing one plugin from a marketplace ref, git URL, local path, or an HTTP directory-archive endpoint',
|
|
322
384
|
help: {
|
|
323
385
|
name: 'pkg plugin install',
|
|
324
386
|
summary: 'install a plugin from a ref or HTTP endpoint',
|
|
325
387
|
params: [
|
|
326
388
|
{ kind: 'positional', name: 'install-ref', type: 'string', required: false, constraint: 'Plugin install ref. Provide exactly one of INSTALL-REF or --endpoint. Accepted ref forms: marketplace/plugin; git URL starting https://, ssh://, git@, file://, or ending .git; local path starting ./, ../, or /.' },
|
|
327
|
-
{ kind: 'flag', name: 'endpoint', type: 'string', required: false, constraint: 'HTTP plugin endpoint. Provide exactly one of --endpoint or INSTALL-REF. Must be an absolute https: URL; http: is permitted only for localhost, 127.0.0.1, [::1], ::1, or host.docker.internal. Credentials and fragments are rejected.' },
|
|
389
|
+
{ kind: 'flag', name: 'endpoint', type: 'string', required: false, constraint: 'HTTP plugin directory-archive endpoint. Provide exactly one of --endpoint or INSTALL-REF. Must be an absolute https: URL; http: is permitted only for localhost, 127.0.0.1, [::1], ::1, or host.docker.internal. Credentials and fragments are rejected.' },
|
|
328
390
|
{ kind: 'flag', name: 'name', type: 'string', required: false, constraint: 'Required with --endpoint and rejected without it. Lowercase kebab-case plugin handle.' },
|
|
329
391
|
{ kind: 'flag', name: 'auth-env', type: 'string', required: false, constraint: 'Optional environment variable holding the HTTP bearer token. Accepted only with --endpoint; its value is never stored.' },
|
|
330
392
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: ['user', 'project'], required: false, constraint: 'Default: project if available, else user.' },
|
|
@@ -335,12 +397,14 @@ export const pluginInstall = defineLeaf({
|
|
|
335
397
|
{ name: 'scope', type: 'string', required: true, constraint: 'Scope the plugin was installed into.' },
|
|
336
398
|
{ name: 'path', type: 'string', required: true, constraint: 'Absolute path to the installed plugin directory.' },
|
|
337
399
|
{ name: 'transport', type: 'string', required: false, constraint: 'exec or http when the plugin declares commands. Always http for an --endpoint install.' },
|
|
400
|
+
{ name: 'version', type: 'string', required: false, constraint: 'First 12 hex characters of the fetched archive SHA-256 for an --endpoint install.' },
|
|
401
|
+
{ name: 'docs', type: 'integer', required: false, constraint: 'Memory document count written from an --endpoint archive.' },
|
|
338
402
|
{ name: 'commands', type: 'object', required: false, constraint: 'Present only when the plugin declares a command manifest. {mounts: string[] (accepted top-level command names now live for the next invocation), issues: object[] (typed validation issues that rejected a contribution — {code, path?, message, received, expected, next})}. Validated statically; commands are never executed.' },
|
|
339
403
|
],
|
|
340
404
|
outputKind: 'object',
|
|
341
405
|
effects: [
|
|
342
406
|
'A ref install clones, links, or copies the plugin into the scope plugins directory and registers it with enabled=true. Marketplace installs refresh the source marketplace before resolving the plugin entry.',
|
|
343
|
-
'An --endpoint install validates
|
|
407
|
+
'An --endpoint install fetches and validates one authenticated uncompressed tar archive before writing. It replaces the complete plugin directory with synthesized provenance and invocation metadata, commands.json, and memory docs; a fetch or validation failure preserves the prior package.',
|
|
344
408
|
'If the plugin declares a command manifest, its commands go live on the next crtr invocation. Exec commands run trusted local code only when explicitly invoked; HTTP commands call their declared endpoint only when explicitly invoked.',
|
|
345
409
|
],
|
|
346
410
|
},
|
|
@@ -478,7 +542,7 @@ export const pluginDisable = defineLeaf({
|
|
|
478
542
|
export const pluginUpdate = defineLeaf({
|
|
479
543
|
name: 'update',
|
|
480
544
|
description: 'update installed plugin content',
|
|
481
|
-
whenToUse: 'refreshing one named plugin or all installed plugins:
|
|
545
|
+
whenToUse: 'refreshing one named plugin or all installed plugins: archive plugins replace commands and memory together, while source-installed plugins retain their source update behavior',
|
|
482
546
|
help: {
|
|
483
547
|
name: 'pkg plugin update',
|
|
484
548
|
summary: 'refresh one or all installed plugins',
|
|
@@ -486,10 +550,10 @@ export const pluginUpdate = defineLeaf({
|
|
|
486
550
|
{ kind: 'flag', name: 'name', type: 'string', required: false, constraint: 'Plugin name to update. Omit to update all installed plugins.' },
|
|
487
551
|
],
|
|
488
552
|
output: [
|
|
489
|
-
{ name: 'updated', type: 'object[]', required: true, constraint: 'One entry per plugin processed: {name, transport?, updated, sha?, commands?}.
|
|
553
|
+
{ name: 'updated', type: 'object[]', required: true, constraint: 'One entry per plugin processed: {name, transport?, updated, sha?, version?, docs?, commands?, error?}. Archive plugins report transport=http and replace their complete directory after an authenticated refetch; version is the archive content identifier and docs is the written memory-document count. sha is present for git updates. A bulk update reports and skips a failed archive plugin. commands is present for validated command plugins: {mounts: string[], issues: object[]}.' },
|
|
490
554
|
],
|
|
491
555
|
outputKind: 'object',
|
|
492
|
-
effects: ['
|
|
556
|
+
effects: ['Archive plugins unconditionally re-fetch, validate, and replace their complete package; a named failure exits nonzero and preserves the prior package. Bulk update reports a failed archive plugin and continues. Source-installed plugins retain their source update, version, and last_updated behavior.'],
|
|
493
557
|
},
|
|
494
558
|
run: async (input) => {
|
|
495
559
|
const name = input['name'];
|
|
@@ -503,8 +567,19 @@ export const pluginUpdate = defineLeaf({
|
|
|
503
567
|
}
|
|
504
568
|
const targets = listAllPlugins().filter((p) => p.scope !== 'builtin');
|
|
505
569
|
const results = [];
|
|
506
|
-
for (const plugin of targets)
|
|
507
|
-
|
|
570
|
+
for (const plugin of targets) {
|
|
571
|
+
try {
|
|
572
|
+
results.push(await updateOnePlugin(plugin, marketplaceCache, { strict: false }));
|
|
573
|
+
}
|
|
574
|
+
catch (error) {
|
|
575
|
+
results.push({
|
|
576
|
+
name: plugin.name,
|
|
577
|
+
...(plugin.manifest.transport !== undefined ? { transport: plugin.manifest.transport.kind } : {}),
|
|
578
|
+
updated: false,
|
|
579
|
+
error: error instanceof Error ? error.message : String(error),
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
}
|
|
508
583
|
return { updated: results };
|
|
509
584
|
},
|
|
510
585
|
});
|
|
@@ -4,7 +4,7 @@ import { inspectorCore } from '../core/inspector/core.js';
|
|
|
4
4
|
import { inspectorText } from '../core/inspector/text.js';
|
|
5
5
|
import { inspectorTui } from '../core/inspector/tui.js';
|
|
6
6
|
import { inTmux } from '../core/runtime/placement-tmux.js';
|
|
7
|
-
import {
|
|
7
|
+
import { runInspector } from '../core/inspector/host.js';
|
|
8
8
|
export const surfaceInspectLeaf = defineLeaf({
|
|
9
9
|
name: 'inspect',
|
|
10
10
|
description: 'host the native Inspector for one node',
|
|
@@ -24,7 +24,7 @@ export const surfaceInspectLeaf = defineLeaf({
|
|
|
24
24
|
run: async (input) => {
|
|
25
25
|
const node = input['node'];
|
|
26
26
|
const section = (input['section'] ?? 'overview');
|
|
27
|
-
const host = () =>
|
|
27
|
+
const host = () => runInspector(inspectorCore, inspectorTui, inspectorText, { options: { target: node, section } });
|
|
28
28
|
// Any non-interactive invocation (pipe, redirected stdout) is a static dump.
|
|
29
29
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
30
30
|
await host();
|
package/dist/commands/surface.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
// `crtr surface` — the screen-facing entrypoints.
|
|
2
2
|
//
|
|
3
|
-
// Groups the
|
|
4
|
-
// views, live broker attachment, the split editor workspace, and the browser
|
|
5
|
-
// shell.
|
|
3
|
+
// Groups the screen-facing surface families under one canonical noun.
|
|
6
4
|
import { defineBranch } from '../core/command.js';
|
|
7
|
-
import { registerView } from './view.js';
|
|
8
|
-
import { registerWorkspace } from './workspace.js';
|
|
9
5
|
import { registerWeb } from '../clients/web/web-cmd.js';
|
|
10
6
|
import { registerAttach } from '../clients/attach/command.js';
|
|
11
7
|
import { tmuxSpreadLeaf } from './surface-tmux-spread.js';
|
|
@@ -23,26 +19,24 @@ function namespaceForSurface(node) {
|
|
|
23
19
|
}
|
|
24
20
|
}
|
|
25
21
|
export function registerSurface() {
|
|
26
|
-
const view = registerView();
|
|
27
22
|
const attach = registerAttach();
|
|
28
|
-
const workspace = registerWorkspace();
|
|
29
23
|
const web = registerWeb();
|
|
30
|
-
for (const child of [
|
|
24
|
+
for (const child of [attach, web]) {
|
|
31
25
|
child.tier = 'important';
|
|
32
26
|
namespaceForSurface(child);
|
|
33
27
|
}
|
|
34
28
|
return defineBranch({
|
|
35
29
|
name: 'surface',
|
|
36
30
|
rootEntry: {
|
|
37
|
-
concept: 'screen-facing surfaces — node viewers,
|
|
31
|
+
concept: 'screen-facing surfaces — node viewers, live broker attachment, the Inspector, and the browser shell',
|
|
38
32
|
desc: 'open and manage screen-facing surfaces',
|
|
39
|
-
useWhen: 'you need a UI or presentation surface rather than a node, document, or graph operation — node-viewer navigation,
|
|
33
|
+
useWhen: 'you need a UI or presentation surface rather than a node, document, or graph operation — node-viewer navigation, live broker attachment, node inspection, or the browser-hosted shell',
|
|
40
34
|
},
|
|
41
35
|
help: {
|
|
42
36
|
name: 'surface',
|
|
43
37
|
summary: 'open and manage screen-facing surfaces',
|
|
44
|
-
model: 'Choose `node` for navigation among node viewers. The other
|
|
38
|
+
model: 'Choose `node` for navigation among node viewers. The other commands open a broker attachment, node Inspector, browser shell, subtree spread, or adjacent editor pane.',
|
|
45
39
|
},
|
|
46
|
-
children: [registerSurfaceNode(),
|
|
40
|
+
children: [registerSurfaceNode(), attach, web, surfaceInspectLeaf, surfaceReloadLeaf, tmuxSpreadLeaf, surfaceEditLeaf],
|
|
47
41
|
});
|
|
48
42
|
}
|