@north-light/crouter 0.3.353 → 0.3.354
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 +35 -25
- package/dist/api/client.js +2 -2
- package/dist/api/dto/broker-ops.d.ts +2 -36
- package/dist/api/dto/canvas.d.ts +8 -13
- package/dist/api/dto/config.d.ts +4 -0
- package/dist/api/dto/delivery.d.ts +61 -0
- package/dist/api/dto/docs.d.ts +133 -0
- package/dist/api/dto/docs.js +1 -0
- package/dist/api/dto/health.d.ts +26 -79
- package/dist/api/dto/node-outcomes.d.ts +1 -3
- package/dist/api/dto/nodes.d.ts +5 -26
- package/dist/api/dto/objects.d.ts +167 -0
- package/dist/api/dto/objects.js +1 -0
- package/dist/api/dto/profiles.d.ts +14 -8
- package/dist/api/dto/reports.d.ts +9 -7
- package/dist/api/dto/reviews.d.ts +9 -3
- package/dist/api/dto/worktree.d.ts +1 -1
- package/dist/api/index.d.ts +0 -1
- package/dist/api/index.js +1 -1
- package/dist/api/routes.d.ts +14 -12
- package/dist/api/routes.js +1 -1
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
- package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
- package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
- package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
- package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
- package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
- package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
- package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
- package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
- package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
- package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
- package/dist/builtin-memory/crouter-sdk/README.md +5 -6
- package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
- package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
- package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
- package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
- package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
- package/dist/builtin-memory/explore/exploration-doc.md +4 -4
- package/dist/builtin-memory/insights/capture.md +6 -6
- package/dist/builtin-memory/insights/init.md +14 -14
- package/dist/builtin-memory/internal/INDEX.md +4 -4
- package/dist/builtin-memory/internal/agent-shaping.md +20 -20
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
- package/dist/builtin-memory/internal/marketplaces.md +2 -2
- package/dist/builtin-memory/internal/memory-loading.md +31 -30
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/plugins.md +16 -14
- package/dist/builtin-memory/internal/storage-tiers.md +4 -4
- package/dist/builtin-memory/memory-read-orientation.md +1 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
- package/dist/clients/attach/input/controller.js +1 -1
- package/dist/clients/attach/input/ref-autocomplete.js +1 -1
- package/dist/clients/attach/input/titled-editor.js +1 -1
- package/dist/clients/attach/render/chat-view.js +1 -1
- package/dist/clients/attach/render/crtr-output.d.ts +1 -2
- package/dist/clients/attach/render/crtr-output.js +17 -17
- package/dist/clients/attach/render/group-activity.d.ts +8 -8
- package/dist/clients/attach/render/group-activity.js +2 -2
- package/dist/clients/attach/render/group-recap.js +1 -1
- package/dist/clients/attach/render/tool-calls.d.ts +1 -1
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/slash/dispatch.js +1 -1
- package/dist/clients/attach/viewer.js +806 -1553
- package/dist/commands/api-client.d.ts +2 -0
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/canvas/edges.d.ts +2 -0
- package/dist/commands/canvas/edges.js +2 -0
- package/dist/commands/canvas/list.d.ts +4 -0
- package/dist/commands/canvas/list.js +3 -0
- package/dist/commands/canvas/read.d.ts +8 -0
- package/dist/commands/canvas/read.js +5 -0
- package/dist/commands/canvas/search.d.ts +2 -0
- package/dist/commands/canvas/search.js +3 -0
- package/dist/commands/canvas/unwatch.d.ts +2 -0
- package/dist/commands/canvas/unwatch.js +1 -0
- package/dist/commands/canvas/watch.d.ts +3 -0
- package/dist/commands/canvas/watch.js +1 -0
- package/dist/commands/canvas-analytics.js +1 -1
- package/dist/commands/canvas-history/grep.js +4 -4
- package/dist/commands/canvas-history/read.js +2 -2
- package/dist/commands/canvas-history/search.js +7 -7
- package/dist/commands/canvas-history/shared.d.ts +0 -1
- package/dist/commands/canvas-history/shared.js +1 -1
- package/dist/commands/canvas-history/stats.js +2 -2
- package/dist/commands/canvas-history.js +1 -1
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/doc/delete.d.ts +2 -0
- package/dist/commands/doc/delete.js +1 -0
- package/dist/commands/doc/edit.d.ts +2 -0
- package/dist/commands/doc/edit.js +1 -0
- package/dist/commands/doc/history.d.ts +2 -0
- package/dist/commands/doc/history.js +2 -0
- package/dist/commands/doc/lint.d.ts +2 -0
- package/dist/commands/doc/lint.js +2 -0
- package/dist/commands/doc/list.d.ts +2 -0
- package/dist/commands/doc/list.js +1 -0
- package/dist/commands/doc/move.d.ts +2 -0
- package/dist/commands/doc/move.js +1 -0
- package/dist/commands/doc/read.d.ts +2 -0
- package/dist/commands/doc/read.js +1 -0
- package/dist/commands/doc/shared.d.ts +25 -0
- package/dist/commands/doc/shared.js +2 -0
- package/dist/commands/doc/write.d.ts +2 -0
- package/dist/commands/doc/write.js +1 -0
- package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
- package/dist/commands/doc.js +1 -0
- package/dist/commands/human/review.js +1 -1
- package/dist/commands/node/bash.js +2 -2
- package/dist/commands/node/create.js +1 -1
- package/dist/commands/node/inspect.js +10 -10
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/node/outcome.js +1 -1
- package/dist/commands/node/subscription.js +1 -1
- package/dist/commands/node-context.js +2 -2
- package/dist/commands/pkg/browse/catalog.js +1 -1
- package/dist/commands/pkg/browse/doc-view.js +1 -1
- package/dist/commands/pkg/browse/model.d.ts +9 -17
- package/dist/commands/pkg/plugin-inspect.js +1 -1
- package/dist/commands/pkg/plugin-manage.d.ts +4 -8
- package/dist/commands/pkg/plugin-manage.js +15 -17
- package/dist/commands/profile/list.js +1 -1
- package/dist/commands/profile/new.js +1 -1
- package/dist/commands/profile/project.js +1 -1
- package/dist/commands/profile/show.js +1 -1
- package/dist/commands/push.js +3 -3
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/context/admin/actions.d.ts +18 -43
- package/dist/commands/sys/context/admin/actions.js +1 -2
- package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
- package/dist/commands/sys/context/admin/detail-panel.js +2 -1
- package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
- package/dist/commands/sys/context/admin/docs-panel.js +1 -1
- package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
- package/dist/commands/sys/context/admin/list-view.js +1 -1
- package/dist/commands/sys/context/admin/model.d.ts +96 -69
- package/dist/commands/sys/context/admin/model.js +1 -1
- package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
- package/dist/commands/sys/context/admin/rail-panel.js +1 -1
- package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
- package/dist/commands/sys/context/admin/read-view.js +1 -2
- package/dist/commands/sys/context/admin/shell.d.ts +26 -31
- package/dist/commands/sys/context/admin/shell.js +1 -1
- package/dist/commands/sys/context/admin.js +2 -2
- package/dist/commands/sys/context/doc.js +2 -3
- package/dist/commands/sys/context/expose.js +2 -2
- package/dist/commands/sys/context/prompt-review.js +4 -4
- package/dist/commands/sys/context/resolve.d.ts +92 -65
- package/dist/commands/sys/context/resolve.js +7 -9
- package/dist/commands/sys/context.js +1 -1
- package/dist/commands/sys/doctor.js +1 -1
- package/dist/commands/sys/migrate.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/sync-deps.d.ts +6 -11
- package/dist/commands/sys/sync-deps.js +7 -8
- package/dist/commands/sys/sync-project-guidance.js +5 -4
- package/dist/commands/sys/sync-shared.d.ts +41 -4
- package/dist/commands/sys/sync-shared.js +1 -1
- package/dist/commands/sys/sync-skills.js +2 -2
- package/dist/commands/sys/sync.js +1 -1
- package/dist/core/bash-job-supervisor.d.ts +2 -3
- package/dist/core/bash-job-supervisor.js +3 -3
- package/dist/core/bash-jobs.d.ts +0 -5
- package/dist/core/bash-jobs.js +7 -7
- package/dist/core/bootstrap.js +2 -2
- package/dist/core/canvas/canvas.d.ts +6 -50
- package/dist/core/canvas/canvas.js +16 -21
- package/dist/core/canvas/db.d.ts +4 -1
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/history.d.ts +11 -39
- package/dist/core/canvas/history.js +9 -20
- package/dist/core/canvas/install-id.d.ts +2 -2
- package/dist/core/canvas/install-id.js +1 -1
- package/dist/core/canvas/memory-reads.d.ts +5 -0
- package/dist/core/canvas/memory-reads.js +1 -1
- package/dist/core/canvas/migrations.js +215 -41
- package/dist/core/canvas/node-agent-paths.js +1 -1
- package/dist/core/canvas/node-tokens.js +1 -1
- package/dist/core/canvas/paths.d.ts +0 -4
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
- package/dist/core/canvas/remote-canvas-source.js +1 -1
- package/dist/core/canvas/render-source.d.ts +9 -6
- package/dist/core/canvas/render-source.js +6 -6
- package/dist/core/canvas/sessions.js +2 -2
- package/dist/core/canvas/source.d.ts +6 -0
- package/dist/core/canvas/tree.d.ts +29 -0
- package/dist/core/canvas/tree.js +12 -0
- package/dist/core/canvas/types.d.ts +0 -20
- package/dist/core/command-plugins/bundle.js +1 -1
- package/dist/core/config.d.ts +1 -1
- package/dist/core/conversation-store/listener.js +4 -2
- package/dist/core/feed/feed.d.ts +9 -7
- package/dist/core/feed/feed.js +3 -7
- package/dist/core/feed/inbox.d.ts +3 -5
- package/dist/core/feed/inbox.js +1 -10
- package/dist/core/feed/messages.d.ts +33 -6
- package/dist/core/feed/messages.js +10 -7
- package/dist/core/feed/reports.d.ts +10 -0
- package/dist/core/feed/reports.js +2 -0
- package/dist/core/grants/remove.js +1 -1
- package/dist/core/graph/access.d.ts +24 -0
- package/dist/core/graph/access.js +8 -0
- package/dist/core/graph/bodies.d.ts +6 -0
- package/dist/core/graph/bodies.js +1 -0
- package/dist/core/graph/deletion.d.ts +9 -0
- package/dist/core/graph/deletion.js +5 -0
- package/dist/core/graph/diff.d.ts +4 -0
- package/dist/core/graph/diff.js +4 -0
- package/dist/core/graph/documents.d.ts +160 -0
- package/dist/core/graph/documents.js +7 -0
- package/dist/core/graph/edges.d.ts +24 -0
- package/dist/core/graph/edges.js +1 -0
- package/dist/core/graph/events.d.ts +26 -0
- package/dist/core/graph/events.js +6 -0
- package/dist/core/graph/exposures.d.ts +53 -0
- package/dist/core/graph/exposures.js +4 -0
- package/dist/core/graph/jobs.d.ts +31 -0
- package/dist/core/graph/jobs.js +2 -0
- package/dist/core/graph/names.d.ts +28 -0
- package/dist/core/graph/names.js +3 -0
- package/dist/core/graph/objects.d.ts +55 -0
- package/dist/core/graph/objects.js +9 -0
- package/dist/core/graph/package-docs.d.ts +31 -0
- package/dist/core/graph/package-docs.js +5 -0
- package/dist/core/graph/package-files.d.ts +20 -0
- package/dist/core/graph/package-files.js +2 -0
- package/dist/core/graph/reader.d.ts +21 -0
- package/dist/core/graph/reader.js +3 -0
- package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
- package/dist/core/graph/repo-sync/exchange.js +2 -0
- package/dist/core/graph/repo-sync/identity.d.ts +30 -0
- package/dist/core/graph/repo-sync/identity.js +1 -0
- package/dist/core/graph/repo-sync/index.d.ts +4 -0
- package/dist/core/graph/repo-sync/index.js +1 -0
- package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
- package/dist/core/graph/repo-sync/mirror.js +6 -0
- package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
- package/dist/core/graph/repo-sync/ref-format.js +2 -0
- package/dist/core/graph/repo-sync/repos.d.ts +17 -0
- package/dist/core/graph/repo-sync/repos.js +3 -0
- package/dist/core/graph/repo-sync/sync.d.ts +42 -0
- package/dist/core/graph/repo-sync/sync.js +2 -0
- package/dist/core/graph/rules.d.ts +26 -0
- package/dist/core/graph/rules.js +3 -0
- package/dist/core/graph/spaces/app.d.ts +3 -0
- package/dist/core/graph/spaces/app.js +1 -0
- package/dist/core/graph/spaces/index.d.ts +19 -0
- package/dist/core/graph/spaces/index.js +1 -0
- package/dist/core/graph/spaces/person.d.ts +5 -0
- package/dist/core/graph/spaces/person.js +2 -0
- package/dist/core/graph/spaces/repo.d.ts +4 -0
- package/dist/core/graph/spaces/repo.js +1 -0
- package/dist/core/graph/types.d.ts +75 -0
- package/dist/core/graph/types.js +1 -0
- package/dist/core/graph/watches.d.ts +62 -0
- package/dist/core/graph/watches.js +18 -0
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/requests.d.ts +3 -1
- package/dist/core/human/requests.js +6 -6
- package/dist/core/inspector/model.js +2 -2
- package/dist/core/io.js +5 -5
- package/dist/core/layout-migrate/index.d.ts +24 -1
- package/dist/core/layout-migrate/index.js +4 -4
- package/dist/core/layout-migrate/paths.d.ts +4 -0
- package/dist/core/layout-migrate/paths.js +1 -1
- package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
- package/dist/core/layout-migrate/stored-paths.js +11 -11
- package/dist/core/layout-migrate/stores.d.ts +19 -6
- package/dist/core/layout-migrate/stores.js +3 -4
- package/dist/core/manifest.d.ts +0 -2
- package/dist/core/manifest.js +1 -1
- package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
- package/dist/core/plugin-extensions.js +1 -0
- package/dist/core/preview-registry.d.ts +1 -1
- package/dist/core/preview-registry.js +3 -2
- package/dist/core/profiles/manifest.d.ts +7 -7
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/profiles/select.js +3 -3
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/stage.d.ts +12 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/store.d.ts +2 -0
- package/dist/core/review/store.js +1 -1
- package/dist/core/review/types.d.ts +7 -1
- package/dist/core/runs/events.js +1 -1
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runs/questions.js +2 -2
- package/dist/core/runtime/bearings-render.d.ts +13 -7
- package/dist/core/runtime/bearings-render.js +12 -12
- package/dist/core/runtime/bearings.d.ts +8 -18
- package/dist/core/runtime/bearings.js +7 -7
- package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
- package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
- package/dist/core/runtime/broker/inbox.d.ts +1 -4
- package/dist/core/runtime/broker/inbox.js +1 -10
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
- package/dist/core/runtime/broker/retry-card-elision.js +1 -0
- package/dist/core/runtime/broker-extension-render.d.ts +0 -13
- package/dist/core/runtime/broker-extension-render.js +2 -4
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker-protocol.d.ts +1 -1
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +9 -4
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/kickoff.js +17 -19
- package/dist/core/runtime/launch-target.d.ts +7 -0
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/ledger.d.ts +10 -0
- package/dist/core/runtime/ledger.js +3 -0
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/nodes.d.ts +10 -2
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.d.ts +2 -2
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.d.ts +2 -2
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/prospective-inventory-cli.js +2 -2
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/roadmap.d.ts +17 -9
- package/dist/core/runtime/roadmap.js +4 -4
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -3
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/structured-output.d.ts +3 -1
- package/dist/core/runtime/structured-output.js +4 -4
- package/dist/core/scope.d.ts +1 -32
- package/dist/core/scope.js +1 -1
- package/dist/core/scoped-state/db.js +2 -1
- package/dist/core/scoped-state/migrate.js +2 -2
- package/dist/core/scoped-state/profiles.d.ts +11 -0
- package/dist/core/scoped-state/profiles.js +1 -1
- package/dist/core/scoped-state/schema.d.ts +1 -1
- package/dist/core/scoped-state/schema.js +7 -5
- package/dist/core/spaces/permissions.d.ts +0 -14
- package/dist/core/spaces/permissions.js +1 -1
- package/dist/core/spaces/stop.d.ts +13 -0
- package/dist/core/spaces/stop.js +2 -2
- package/dist/core/storage/tables.d.ts +1 -1
- package/dist/core/substrate/delivery/corpus.d.ts +21 -0
- package/dist/core/substrate/delivery/corpus.js +3 -0
- package/dist/core/substrate/delivery/deliver.d.ts +76 -0
- package/dist/core/substrate/delivery/deliver.js +6 -0
- package/dist/core/substrate/delivery/listings.d.ts +27 -0
- package/dist/core/substrate/delivery/listings.js +4 -0
- package/dist/core/substrate/delivery/match.d.ts +28 -0
- package/dist/core/substrate/delivery/match.js +1 -0
- package/dist/core/substrate/delivery/plan.d.ts +67 -0
- package/dist/core/substrate/delivery/plan.js +3 -0
- package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
- package/dist/core/substrate/delivery/render-boot.js +54 -0
- package/dist/core/substrate/delivery/render-event.d.ts +47 -0
- package/dist/core/substrate/delivery/render-event.js +6 -0
- package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
- package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
- package/dist/core/substrate/delivery/types.d.ts +30 -0
- package/dist/core/substrate/delivery/types.js +0 -0
- package/dist/core/substrate/gate-explain.d.ts +0 -13
- package/dist/core/substrate/gate-explain.js +1 -1
- package/dist/core/substrate/schema.d.ts +11 -139
- package/dist/core/substrate/schema.js +1 -1
- package/dist/core/substrate/subject-fields.d.ts +3 -0
- package/dist/core/substrate/subject.d.ts +2 -1
- package/dist/core/substrate/subject.js +1 -1
- package/dist/daemon/api/handlers/app-profiles.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +1 -2
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.js +5 -5
- package/dist/daemon/api/handlers/daemon.js +1 -1
- package/dist/daemon/api/handlers/delivery.d.ts +2 -0
- package/dist/daemon/api/handlers/delivery.js +1 -0
- package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
- package/dist/daemon/api/handlers/docs.js +1 -0
- package/dist/daemon/api/handlers/hook-exec.js +1 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/node-records.js +2 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/objects.d.ts +2 -0
- package/dist/daemon/api/handlers/objects.js +5 -0
- package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
- package/dist/daemon/api/handlers/package-docs.js +1 -0
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/reports.d.ts +2 -2
- package/dist/daemon/api/handlers/reports.js +4 -4
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/map.d.ts +2 -2
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.d.ts +1 -1
- package/dist/daemon/api/operations.js +1 -1
- package/dist/daemon/api/reader.d.ts +17 -0
- package/dist/daemon/api/reader.js +1 -0
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/control.d.ts +2 -3
- package/dist/daemon/crtrd.js +8 -6
- package/dist/daemon/fleet.js +4 -4
- package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
- package/dist/daemon/reconcilers/bash-deadline.js +2 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/node-deadline.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/review/deliver.js +2 -2
- package/dist/daemon/review/finish.js +1 -1
- package/dist/hook-authoring.d.ts +0 -1
- package/dist/hook-authoring.js +3 -3
- package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
- package/dist/migrations/004-canvas-documents/apply.js +1 -0
- package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
- package/dist/migrations/004-canvas-documents/fields.js +2 -0
- package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
- package/dist/migrations/004-canvas-documents/index.js +2 -0
- package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
- package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
- package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
- package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
- package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
- package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
- package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
- package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
- package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
- package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
- package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
- package/dist/migrations/004-canvas-documents/plan.js +3 -0
- package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
- package/dist/migrations/004-canvas-documents/pointers.js +4 -0
- package/dist/migrations/activation.d.ts +9 -18
- package/dist/migrations/activation.js +2 -2
- package/dist/pi-extensions/broker-local.d.ts +2 -2
- package/dist/pi-extensions/broker-local.js +2 -2
- package/dist/pi-extensions/canvas-bash-valve.js +5 -4
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-passive-context.js +1 -1
- package/dist/pi-extensions/canvas-recap.js +2 -2
- package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/prompts/review.js +3 -3
- package/dist/shared/env.d.ts +5 -0
- package/dist/shared/env.js +1 -1
- package/dist/shared/generated-context.js +2 -10
- package/dist/shared/inbox-entry-body.d.ts +22 -0
- package/dist/shared/inbox-entry-body.js +10 -0
- package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
- package/dist/shared/inline-ref-guidance.js +2 -0
- package/dist/types.d.ts +3 -1
- package/docs/cli/memory-and-preferences.md +12 -14
- package/docs/concepts/README.md +1 -1
- package/docs/concepts/lifecycle-and-wakes.md +1 -1
- package/docs/concepts/memory.md +15 -15
- package/docs/concepts/nodes-and-the-canvas.md +1 -1
- package/docs/concepts/profiles-kinds-and-modes.md +5 -5
- package/docs/concepts/scopes-and-trust.md +1 -1
- package/docs/concepts/why-a-daemon.md +1 -1
- package/docs/sdk/README.md +5 -6
- package/docs/sdk/errors.md +0 -13
- package/docs/sdk/guides/README.md +0 -1
- package/docs/sdk/nodes.md +0 -2
- package/docs/sdk/resources.md +0 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +11 -11
- package/dist/api/dto/memory.d.ts +0 -171
- package/dist/api/dto/memory.js +0 -1
- package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
- package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
- package/dist/commands/broker-permissions.d.ts +0 -2
- package/dist/commands/broker-permissions.js +0 -1
- package/dist/commands/memory/client.d.ts +0 -11
- package/dist/commands/memory/client.js +0 -1
- package/dist/commands/memory/delete.d.ts +0 -1
- package/dist/commands/memory/delete.js +0 -1
- package/dist/commands/memory/edit.d.ts +0 -1
- package/dist/commands/memory/edit.js +0 -21
- package/dist/commands/memory/find.d.ts +0 -1
- package/dist/commands/memory/find.js +0 -1
- package/dist/commands/memory/history.d.ts +0 -1
- package/dist/commands/memory/history.js +0 -5
- package/dist/commands/memory/lint.d.ts +0 -1
- package/dist/commands/memory/lint.js +0 -1
- package/dist/commands/memory/list.d.ts +0 -1
- package/dist/commands/memory/list.js +0 -1
- package/dist/commands/memory/move.d.ts +0 -1
- package/dist/commands/memory/move.js +0 -1
- package/dist/commands/memory/origin.d.ts +0 -1
- package/dist/commands/memory/origin.js +0 -1
- package/dist/commands/memory/read.d.ts +0 -1
- package/dist/commands/memory/read.js +0 -6
- package/dist/commands/memory/shared.d.ts +0 -22
- package/dist/commands/memory/shared.js +0 -1
- package/dist/commands/memory/write.d.ts +0 -1
- package/dist/commands/memory/write.js +0 -13
- package/dist/commands/memory.js +0 -1
- package/dist/commands/node-inspect-artifacts.d.ts +0 -1
- package/dist/commands/node-inspect-artifacts.js +0 -8
- package/dist/core/help/memory-extensions.d.ts +0 -3
- package/dist/core/help/memory-extensions.js +0 -2
- package/dist/core/memory/cli-selector.d.ts +0 -13
- package/dist/core/memory/cli-selector.js +0 -1
- package/dist/core/memory/doc-link-grammar.d.ts +0 -20
- package/dist/core/memory/doc-link-grammar.js +0 -2
- package/dist/core/memory/extensions.js +0 -1
- package/dist/core/memory/history.d.ts +0 -87
- package/dist/core/memory/history.js +0 -6
- package/dist/core/memory/identity.d.ts +0 -65
- package/dist/core/memory/identity.js +0 -1
- package/dist/core/memory/inline-ref-guidance.js +0 -2
- package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
- package/dist/core/memory/inline-ref-inventory.js +0 -1
- package/dist/core/memory/lint.d.ts +0 -163
- package/dist/core/memory/lint.js +0 -2
- package/dist/core/memory/mutation-domain.d.ts +0 -113
- package/dist/core/memory/mutation-domain.js +0 -12
- package/dist/core/memory/mutations.d.ts +0 -74
- package/dist/core/memory/mutations.js +0 -1
- package/dist/core/memory/project-namespace.d.ts +0 -31
- package/dist/core/memory/project-namespace.js +0 -2
- package/dist/core/memory/repository-association.d.ts +0 -31
- package/dist/core/memory/repository-association.js +0 -1
- package/dist/core/memory/service.d.ts +0 -145
- package/dist/core/memory/service.js +0 -2
- package/dist/core/memory/tree.d.ts +0 -39
- package/dist/core/memory/tree.js +0 -1
- package/dist/core/memory-resolver.d.ts +0 -280
- package/dist/core/memory-resolver.js +0 -2
- package/dist/core/nested-stores.d.ts +0 -18
- package/dist/core/nested-stores.js +0 -1
- package/dist/core/runtime/memory.d.ts +0 -3
- package/dist/core/runtime/memory.js +0 -1
- package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
- package/dist/core/substrate/frontmatter-validation.js +0 -1
- package/dist/core/substrate/gate.d.ts +0 -16
- package/dist/core/substrate/gate.js +0 -1
- package/dist/core/substrate/index.d.ts +0 -18
- package/dist/core/substrate/index.js +0 -1
- package/dist/core/substrate/injected-store.d.ts +0 -75
- package/dist/core/substrate/injected-store.js +0 -2
- package/dist/core/substrate/listings.d.ts +0 -28
- package/dist/core/substrate/listings.js +0 -1
- package/dist/core/substrate/memory-events.d.ts +0 -6
- package/dist/core/substrate/memory-events.js +0 -1
- package/dist/core/substrate/on-read-node.d.ts +0 -6
- package/dist/core/substrate/on-read-node.js +0 -1
- package/dist/core/substrate/on-read.d.ts +0 -101
- package/dist/core/substrate/on-read.js +0 -9
- package/dist/core/substrate/plan.d.ts +0 -94
- package/dist/core/substrate/plan.js +0 -1
- package/dist/core/substrate/render-node.d.ts +0 -12
- package/dist/core/substrate/render-node.js +0 -1
- package/dist/core/substrate/render.d.ts +0 -41
- package/dist/core/substrate/render.js +0 -65
- package/dist/core/substrate/session-cache.d.ts +0 -27
- package/dist/core/substrate/session-cache.js +0 -1
- package/dist/core/substrate/surface-match.d.ts +0 -73
- package/dist/core/substrate/surface-match.js +0 -1
- package/dist/daemon/api/handlers/memory.js +0 -5
- package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
- package/dist/migrations/001-surfaces-frontmatter.js +0 -1
- package/dist/migrations/002-profile-project-memory.d.ts +0 -2
- package/dist/migrations/002-profile-project-memory.js +0 -1
- package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
- package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
- package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
- package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
- package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
- package/dist/migrations/convergent.d.ts +0 -43
- package/dist/migrations/convergent.js +0 -2
- package/dist/migrations/corpus.d.ts +0 -75
- package/dist/migrations/corpus.js +0 -3
- package/dist/migrations/frontmatter-splice.d.ts +0 -15
- package/dist/migrations/frontmatter-splice.js +0 -8
- package/dist/migrations/profile-manifests.d.ts +0 -30
- package/dist/migrations/profile-manifests.js +0 -2
- package/dist/migrations/registry.d.ts +0 -7
- package/dist/migrations/registry.js +0 -1
- package/dist/migrations/runner.d.ts +0 -43
- package/dist/migrations/runner.js +0 -1
- package/dist/migrations/types.d.ts +0 -211
- package/dist/shared/birth-announcement.d.ts +0 -12
- package/dist/shared/birth-announcement.js +0 -1
- package/docs/sdk/guides/app-memory.md +0 -22
- package/docs/sdk/memory.md +0 -85
- /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
- /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
- /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)},"render")});export{
|
|
1
|
+
var m=Object.defineProperty;var s=(t,n)=>m(t,"name",{value:n,configurable:!0});import{envNodeId as u}from"../shared/env.js";import{spawnSync as a}from"node:child_process";import{existsSync as f,mkdirSync as h,mkdtempSync as v,rmSync as x,symlinkSync as b}from"node:fs";import{tmpdir as y}from"node:os";import{dirname as g,join as d}from"node:path";import{defineLeaf as w}from"../core/command.js";import{InputError as l}from"../core/io.js";import{cliClient as T,rethrowAsCliError as R}from"./api-client.js";function c(t){return t.replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"node"}s(c,"sanitize");async function S(t){const n=await T().getContext(t),o=[];for(const e of n.roots){const r=e.dir,i=e.node_id.slice(0,8),p=e.self?`self-${c(e.label)}`:`${c(e.label)}-${i}`;o.push({nodeId:e.node_id,label:p,dir:g(r),self:e.self,fileCount:e.files,contextDir:r})}return o}s(S,"resolveRoots");function $(){const t=a("nvim",["--version"],{stdio:"ignore"});return t.error===void 0&&(t.status===0||t.status===null)}s($,"nvimAvailable");function _(t){const n=v(d(y(),"crtr-context-"));for(const o of t){const e=o.self?`0-${o.label}`:o.label,r=d(n,e);h(r,{recursive:!0});try{f(o.contextDir)&&b(o.contextDir,d(r,"context"),"dir")}catch{}}return n}s(_,"buildSymlinkTree");const Y=w({name:"context",description:"browse this node + its subscriptions\u2019 context dirs in an nvim popup",whenToUse:"you want to SEE what the nodes you subscribe to have written \u2014 open a read-only nvim file explorer over this node\u2019s context dir and every subscribed node\u2019s context dir at once (reports are documents: `crtr canvas read <node>/reports/<name>`). The /context popup shells this. Piped it prints the roster instead",help:{name:"node inspect context",summary:"open a read-only nvim file explorer over this node\u2019s context dir and those of every node it subscribes to",params:[{kind:"flag",name:"node",type:"string",required:!1,constraint:"Node id to root on. Defaults to $CRTR_NODE_ID (the calling node)."}],output:[{name:"roots",type:"object[]",required:!0,constraint:"Resolved browse roots: {node_id, label, dir, self, files}. Returned on the piped/non-TTY path."}],outputKind:"object",effects:["TTY: builds a temp dir of labelled node dirs, symlinking each available `context` dir inside it, then execs `nvim -R` on the tree; the temp links are removed on exit (real dirs untouched).","Requires nvim on PATH (a crtr strong dependency). Missing nvim -> error with an install hint.","Non-TTY / piped: prints the resolved roster and exits 0; opens nothing."]},run:s(async t=>{const n=t.node?.trim()||u();if(n===void 0||n==="")throw new l({error:"no_node",message:"no current node: $CRTR_NODE_ID is unset and --node was not given",field:"node",next:"Run this from inside a canvas node (the /context popup does), or pass --node <id>."});let o;try{o=await S(n)}catch(i){R(i)}const e=o.map(i=>({node_id:i.nodeId,label:i.label,dir:i.dir,self:i.self,files:i.fileCount}));if(!process.stdout.isTTY)return{roots:e};if(!$())throw new l({error:"nvim_missing",message:"nvim is not on PATH \u2014 `crtr node inspect context` opens the context explorer in nvim",next:"Install Neovim (macOS: `brew install neovim`; Debian/Ubuntu: `apt install neovim`), then retry."});const r=_(o);try{a("nvim",["-R","."],{cwd:r,stdio:"inherit"})}finally{x(r,{recursive:!0,force:!0})}return{roots:e}},"run"),render:s(t=>{const n=t.roots??[];if(n.length===0)return"No node dirs to show (no subscriptions with written context or reports, and this node\u2019s own context dir is empty/absent).";const o=n.map(e=>{const r=e.self===!0?" (self)":"";return` ${String(e.label)}${r} ${String(e.files)} files ${String(e.dir)}`});return[`Context roots (${n.length}):`,...o].join(`
|
|
2
|
+
`)},"render")});export{Y as nodeContextLeaf};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var D=Object.defineProperty;var l=(e,n)=>D(e,"name",{value:n,configurable:!0});import{statSync as C}from"node:fs";import{isAbsolute as z,join as k}from"node:path";import{SUBTREE_NAMES as U,coreCommandPaths as B,extensibleCoreBranches as _}from"../../../build-root.js";import{discoverPluginCommandCandidates as F,validateEffectiveCommandPlugins as L,validatePluginCommands as W}from"../../../core/command-plugins/discovery.js";import{qualifiedTopLevelCommandName as w}from"../../../core/command-manifests/registry.js";import{listDirs as x,pathExists as A,walkFiles as q}from"../../../core/fs-utils.js";import{currentSha as Z,gitSync as G}from"../../../core/git.js";import{listPluginMemoryDocs as H}from"../../../core/memory-resolver.js";import{memoryExtensionEffectiveCatalog as K,projectEffectiveMemoryExtensions as O}from"../../../core/memory/extensions.js";import{readMarketplaceManifest as J,readPluginManifest as E}from"../../../core/manifest.js";import{readConfig as Q}from"../../../core/config.js";import{parseSubstrateDoc as V}from"../../../core/substrate/schema.js";import{projectScopeRoot as y}from"../../../core/scope.js";import{runtimeRoot as S}from"../../../core/layout.js";import{isGitUrl as X}from"../shared.js";import{INSTALLED_SOURCE_ID as $,marketplaceSourceId as M}from"./model.js";function P(e){const n=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/.exec(e);return n===null?null:{core:[Number(n[1]),Number(n[2]),Number(n[3])],prerelease:n[4]?.split(".")??[]}}l(P,"parseSemver");function Y(e,n){for(let t=0;t<e.core.length;t+=1){const o=e.core[t]-n.core[t];if(o!==0)return o}if(e.prerelease.length===0||n.prerelease.length===0)return e.prerelease.length===n.prerelease.length?0:e.prerelease.length===0?1:-1;for(let t=0;t<Math.max(e.prerelease.length,n.prerelease.length);t+=1){const o=e.prerelease[t],a=n.prerelease[t];if(o===void 0||a===void 0)return o===void 0?-1:1;const i=/^\d+$/.test(o),r=/^\d+$/.test(a);if(i&&r){const s=Number(o)-Number(a);if(s!==0)return s}else{if(i!==r)return i?-1:1;if(o!==a)return o<a?-1:1}}return 0}l(Y,"compareSemver");function j(e,n){if(e===void 0||n===void 0)return!1;const t=P(e),o=P(n);return t!==null&&o!==null&&Y(o,t)>0}l(j,"offeredVersionIsNewer");function ee(e){return e.startsWith("./")||e.startsWith("../")||!z(e)&&!X(e)}l(ee,"isMarketplaceRelativeSource");function I(e,n){return{kind:"installed",scope:e.scope,enabled:e.enabled,version:e.version,path:e.root,updateAvailable:j(e.version,n)}}l(I,"pluginInstallState");function ne(e,n){return{key:`${$}:${e.scope}:${e.name}`,name:e.name,ref:e.name,sourceId:$,...e.sourceMarketplace!==void 0?{marketplace:e.sourceMarketplace}:{},...n===void 0?{}:{version:n},description:e.manifest.description,keywords:[],owner:e.manifest.owner,source:e.manifest.source,install:I(e,n),root:e.root}}l(ne,"installedEntry");function v(e,n){return`${e}:${n}`}l(v,"marketplacePluginKey");function te(e,n){const t=Z(e.root)??void 0,o=G(["show","-s","--format=%cI","HEAD"],e.root),a=o.status===0&&o.stdout.trim()||void 0,i=e.manifest.plugins;return{name:e.name,scope:e.scope,url:e.url,ref:e.ref,path:e.root,owner:e.manifest.owner,version:e.manifest.version,pluginCount:i.length,installedCount:i.filter(r=>n.has(v(e.name,r.name))).length,updatableCount:i.filter(r=>{const s=n.get(v(e.name,r.name));return s!==void 0&&j(s.version,r.version)}).length,revision:t,revisionDate:a}}l(te,"marketplaceDetail");function re(e,n,t){const o=t.get(v(e.name,n.name)),a=ee(n.source)?k(e.root,n.source):void 0;return{key:`${M(e.name,e.scope)}:${n.name}`,name:n.name,ref:`${e.name}/${n.name}`,sourceId:M(e.name,e.scope),marketplace:e.name,version:n.version,description:n.description,keywords:n.keywords??[],owner:e.manifest.owner,source:n.source,install:o===void 0?{kind:"absent"}:I(o,n.version),...o!==void 0?{root:o.root}:a!==void 0&&A(a)?{root:a}:{}}}l(re,"marketplaceEntry");function R(e,n){try{return Q(e)}catch(t){return n.push(`Could not read ${e} config: ${b(t)}`),null}}l(R,"readableConfig");function oe(e){const n=[...y()===null?[]:[{scope:"project",root:y()}],{scope:"user",root:S()}],t=[];for(const{scope:o,root:a}of n){const i=R(o,e);for(const r of x(k(a,"plugins"))){const s=k(a,"plugins",r);try{const c=E(s);if(c===null){e.push(`Plugin "${r}" has no readable manifest: ${s}`);continue}const u=i?.plugins[r];t.push({name:r,scope:o,root:s,manifest:c,enabled:typeof u?.enabled=="boolean"?u.enabled:!0,sourceMarketplace:typeof u?.source_marketplace=="string"?u.source_marketplace:void 0,version:typeof u?.version=="string"?u.version:c.version})}catch(c){e.push(`Could not read plugin "${r}": ${b(c)}`)}}}return t}l(oe,"readInstalledPlugins");function se(e,n,t){if(!Array.isArray(e))return t.push(`Marketplace "${n}" has an invalid plugins list.`),[];const o=[];for(const[a,i]of e.entries()){if(typeof i!="object"||i===null||Array.isArray(i)){t.push(`Marketplace "${n}" has an invalid plugin entry at index ${a}.`);continue}const r=i;if(typeof r.name!="string"||r.name===""||typeof r.source!="string"||r.source===""){t.push(`Marketplace "${n}" has a plugin entry without a name and source at index ${a}.`);continue}o.push({name:r.name,source:r.source,...typeof r.version=="string"?{version:r.version}:{},...typeof r.description=="string"?{description:r.description}:{},...Array.isArray(r.keywords)&&r.keywords.every(s=>typeof s=="string")?{keywords:r.keywords}:{}})}return o}l(se,"marketplaceEntries");function ae(e,n,t){if(typeof e!="object"||e===null||Array.isArray(e))return t.push(`Marketplace "${n}" has an invalid manifest.`),null;const o=e;if(typeof o.name!="string"||o.name==="")return t.push(`Marketplace "${n}" has a manifest without a name.`),null;const a=o.owner,i=typeof a=="object"&&a!==null&&!Array.isArray(a)?{...typeof a.name=="string"?{name:a.name}:{},...typeof a.email=="string"?{email:a.email}:{}}:void 0;return{name:o.name,plugins:se(o.plugins,o.name,t),...typeof o.version=="string"?{version:o.version}:{},...i!==void 0?{owner:i}:{}}}l(ae,"readableMarketplaceManifest");function ie(e){const n=[...y()===null?[]:[{scope:"project",root:y()}],{scope:"user",root:S()}],t=[];for(const{scope:o,root:a}of n){const i=R(o,e);for(const r of x(k(a,"marketplaces"))){const s=k(a,"marketplaces",r);try{const c=J(s);if(c===null){e.push(`Marketplace "${r}" has no readable manifest: ${s}`);continue}const u=ae(c,r,e);if(u===null)continue;const d=i?.marketplaces[r];t.push({name:r,scope:o,root:s,manifest:u,url:d?.url??"",ref:d?.ref??"main"})}catch(c){e.push(`Could not read marketplace "${r}": ${b(c)}`)}}}return t}l(ie,"readMarketplaces");function Ee(){const e=[],n=oe(e),t=ie(e),o=new Map(n.filter(r=>r.sourceMarketplace!==void 0).map(r=>[v(r.sourceMarketplace,r.name),r])),a=new Map(t.flatMap(r=>r.manifest.plugins.map(s=>[v(r.name,s.name),s.version]))),i=[{id:$,kind:"installed",label:"Installed",entries:n.map(r=>ne(r,r.sourceMarketplace===void 0?void 0:a.get(v(r.sourceMarketplace,r.name)))).sort((r,s)=>r.name.localeCompare(s.name))}];for(const r of t.sort((s,c)=>s.name.localeCompare(c.name)))try{i.push({id:M(r.name,r.scope),kind:"marketplace",label:r.name,marketplace:te(r,o),entries:r.manifest.plugins.map(s=>re(r,s,o)).sort((s,c)=>s.name.localeCompare(c.name))})}catch(s){e.push(`Could not load marketplace "${r.name}": ${b(s)}`)}return{sources:i,installScopes:["user",...y()===null?[]:["project"]],warnings:e}}l(Ee,"loadCatalog");function T(e,n=[]){const t=[...n,e.name];return e.kind==="branch"?{path:t,kind:"branch",description:e.description,whenToUse:e.whenToUse,summary:e.summary,...e.tier!==void 0?{tier:e.tier}:{},...e.passthrough!==void 0?{passthrough:e.passthrough}:{},...e.rootEntry!==void 0?{rootEntry:e.rootEntry}:{},children:e.children.map(o=>T(o,t)),params:[],output:[],effects:[]}:{path:t,kind:"leaf",description:e.description,whenToUse:e.whenToUse,summary:e.summary,...e.tier!==void 0?{tier:e.tier}:{},children:[],params:e.params,output:e.output,effects:[...e.effects],..."rest"in e?{rest:{method:e.rest.method,path:e.rest.path,streaming:e.rest.streaming===!0}}:{}}}l(T,"commandNode");function le(e){return H(e,e.scope,!0).flatMap(n=>{const t=V(n);if(t===null)return[];let o;try{o=C(t.path).size}catch{}return[{name:t.name,kind:t.kind,...t.shortForm!==""?{shortForm:t.shortForm}:{},...t.whenAndWhyToRead!==""?{routingLine:t.whenAndWhyToRead}:{},path:t.path,...o!==void 0?{sizeBytes:o}:{},surfaces:t.surfaces,unlisted:t.unlisted,slash:t.slash,...t.gate!==void 0?{gate:t.gate}:{},...t.rationale!==void 0?{rationale:t.rationale}:{},extensions:O(n.frontmatter?.extensions,K(n)),body:t.body}]})}l(le,"docDetails");function ce(e){try{return q(e).reduce((n,t)=>n+C(t).size,0)}catch{return}}l(ce,"directorySize");async function Se(e){if(e.root===void 0||!A(e.root))return null;try{const n=E(e.root);if(n===null)return null;const t=e.install.kind==="installed"?e.install.scope:"user",o={name:e.name,scope:t,root:e.root,manifest:n,enabled:e.install.kind!=="installed"||e.install.enabled},a=new Set(U),[i,r]=await Promise.all([B(),_()]);let s=W(o,a,i,r);const c=[];if(e.install.kind==="installed"&&e.install.enabled)try{s=L(a,void 0,void 0,i,r).find(p=>p.plugin.root===e.root)??s}catch(d){c.push({message:`Could not resolve the effective command registry: ${b(d)}`,next:"Repair the unreadable installed plugin manifest, then reopen the dossier."})}if(e.install.kind!=="installed"||!e.install.enabled){const d=new Map;for(const m of F())if(m.plugin.root!==e.root)for(const f of m.contributions){const h=d.get(f.node.name)??[];h.push(m.plugin),d.set(f.node.name,h)}const p=e.install.kind==="installed"?"enabling":"installing";s.contributions=s.contributions.map(m=>{const f=d.get(m.node.name);if(f===void 0||f.length===0)return m;const h=w({name:e.name,sourceMarketplace:e.marketplace},m.node.name),N=f.map(g=>`moves ${g.name}'s to "${w(g,m.node.name)}"`);return s.issues.push({code:"command_collision",plugin:o.name,path:m.node.name,message:`top-level command "${m.node.name}" is already claimed by ${f.map(g=>g.name).join(", ")} \u2014 ${p} mounts this one as "${h}" and ${N.join(" and ")}`,received:[...f.map(g=>g.name),o.name].join(", "),expected:"an origin-qualified top-level command for each claimant",next:`After ${p}, invoke "${h}".`}),{...m,node:{...m.node,name:h}}})}const u=n.transport;return{root:e.root,transport:u?.kind??null,...u?.kind==="exec"&&u.executable!==void 0?{transportTarget:u.executable}:{},...u?.kind==="http"?{transportTarget:u.endpoint}:{},commands:s.contributions.map(d=>T(d.node)),commandIssues:[...s.issues.map(({message:d,next:p})=>({message:d,...p!==void 0?{next:p}:{}})),...c],docs:le(o),sizeBytes:ce(e.root)}}catch{return null}}l(Se,"loadCapability");function b(e){return e instanceof Error?e.message:String(e)}l(b,"errorMessage");export{Se as loadCapability,Ee as loadCatalog};
|
|
1
|
+
var z=Object.defineProperty;var l=(e,n)=>z(e,"name",{value:n,configurable:!0});import{statSync as w}from"node:fs";import{isAbsolute as D,join as k}from"node:path";import{SUBTREE_NAMES as U,coreCommandPaths as B,extensibleCoreBranches as _}from"../../../build-root.js";import{discoverPluginCommandCandidates as F,validateEffectiveCommandPlugins as L,validatePluginCommands as q}from"../../../core/command-plugins/discovery.js";import{qualifiedTopLevelCommandName as C}from"../../../core/command-manifests/registry.js";import{listDirs as x,pathExists as A,walkFiles as Z}from"../../../core/fs-utils.js";import{currentSha as W,gitSync as G}from"../../../core/git.js";import{packageFiles as H}from"../../../core/graph/package-files.js";import{readMarketplaceManifest as K,readPluginManifest as E}from"../../../core/manifest.js";import{readConfig as O}from"../../../core/config.js";import{documentFields as J}from"../../../migrations/004-canvas-documents/fields.js";import{pluginMemoryDir as Q,projectScopeRoot as y}from"../../../core/scope.js";import{runtimeRoot as S}from"../../../core/layout.js";import{isGitUrl as V}from"../shared.js";import{INSTALLED_SOURCE_ID as $,marketplaceSourceId as M}from"./model.js";function I(e){const n=/^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.-]+)?$/.exec(e);return n===null?null:{core:[Number(n[1]),Number(n[2]),Number(n[3])],prerelease:n[4]?.split(".")??[]}}l(I,"parseSemver");function X(e,n){for(let r=0;r<e.core.length;r+=1){const o=e.core[r]-n.core[r];if(o!==0)return o}if(e.prerelease.length===0||n.prerelease.length===0)return e.prerelease.length===n.prerelease.length?0:e.prerelease.length===0?1:-1;for(let r=0;r<Math.max(e.prerelease.length,n.prerelease.length);r+=1){const o=e.prerelease[r],a=n.prerelease[r];if(o===void 0||a===void 0)return o===void 0?-1:1;const i=/^\d+$/.test(o),t=/^\d+$/.test(a);if(i&&t){const s=Number(o)-Number(a);if(s!==0)return s}else{if(i!==t)return i?-1:1;if(o!==a)return o<a?-1:1}}return 0}l(X,"compareSemver");function P(e,n){if(e===void 0||n===void 0)return!1;const r=I(e),o=I(n);return r!==null&&o!==null&&X(o,r)>0}l(P,"offeredVersionIsNewer");function Y(e){return e.startsWith("./")||e.startsWith("../")||!D(e)&&!V(e)}l(Y,"isMarketplaceRelativeSource");function j(e,n){return{kind:"installed",scope:e.scope,enabled:e.enabled,version:e.version,path:e.root,updateAvailable:P(e.version,n)}}l(j,"pluginInstallState");function ee(e,n){return{key:`${$}:${e.scope}:${e.name}`,name:e.name,ref:e.name,sourceId:$,...e.sourceMarketplace!==void 0?{marketplace:e.sourceMarketplace}:{},...n===void 0?{}:{version:n},description:e.manifest.description,keywords:[],owner:e.manifest.owner,source:e.manifest.source,install:j(e,n),root:e.root}}l(ee,"installedEntry");function v(e,n){return`${e}:${n}`}l(v,"marketplacePluginKey");function ne(e,n){const r=W(e.root)??void 0,o=G(["show","-s","--format=%cI","HEAD"],e.root),a=o.status===0&&o.stdout.trim()||void 0,i=e.manifest.plugins;return{name:e.name,scope:e.scope,url:e.url,ref:e.ref,path:e.root,owner:e.manifest.owner,version:e.manifest.version,pluginCount:i.length,installedCount:i.filter(t=>n.has(v(e.name,t.name))).length,updatableCount:i.filter(t=>{const s=n.get(v(e.name,t.name));return s!==void 0&&P(s.version,t.version)}).length,revision:r,revisionDate:a}}l(ne,"marketplaceDetail");function te(e,n,r){const o=r.get(v(e.name,n.name)),a=Y(n.source)?k(e.root,n.source):void 0;return{key:`${M(e.name,e.scope)}:${n.name}`,name:n.name,ref:`${e.name}/${n.name}`,sourceId:M(e.name,e.scope),marketplace:e.name,version:n.version,description:n.description,keywords:n.keywords??[],owner:e.manifest.owner,source:n.source,install:o===void 0?{kind:"absent"}:j(o,n.version),...o!==void 0?{root:o.root}:a!==void 0&&A(a)?{root:a}:{}}}l(te,"marketplaceEntry");function N(e,n){try{return O(e)}catch(r){return n.push(`Could not read ${e} config: ${b(r)}`),null}}l(N,"readableConfig");function re(e){const n=[...y()===null?[]:[{scope:"project",root:y()}],{scope:"user",root:S()}],r=[];for(const{scope:o,root:a}of n){const i=N(o,e);for(const t of x(k(a,"plugins"))){const s=k(a,"plugins",t);try{const c=E(s);if(c===null){e.push(`Plugin "${t}" has no readable manifest: ${s}`);continue}const u=i?.plugins[t];r.push({name:t,scope:o,root:s,manifest:c,enabled:typeof u?.enabled=="boolean"?u.enabled:!0,sourceMarketplace:typeof u?.source_marketplace=="string"?u.source_marketplace:void 0,version:typeof u?.version=="string"?u.version:c.version})}catch(c){e.push(`Could not read plugin "${t}": ${b(c)}`)}}}return r}l(re,"readInstalledPlugins");function oe(e,n,r){if(!Array.isArray(e))return r.push(`Marketplace "${n}" has an invalid plugins list.`),[];const o=[];for(const[a,i]of e.entries()){if(typeof i!="object"||i===null||Array.isArray(i)){r.push(`Marketplace "${n}" has an invalid plugin entry at index ${a}.`);continue}const t=i;if(typeof t.name!="string"||t.name===""||typeof t.source!="string"||t.source===""){r.push(`Marketplace "${n}" has a plugin entry without a name and source at index ${a}.`);continue}o.push({name:t.name,source:t.source,...typeof t.version=="string"?{version:t.version}:{},...typeof t.description=="string"?{description:t.description}:{},...Array.isArray(t.keywords)&&t.keywords.every(s=>typeof s=="string")?{keywords:t.keywords}:{}})}return o}l(oe,"marketplaceEntries");function se(e,n,r){if(typeof e!="object"||e===null||Array.isArray(e))return r.push(`Marketplace "${n}" has an invalid manifest.`),null;const o=e;if(typeof o.name!="string"||o.name==="")return r.push(`Marketplace "${n}" has a manifest without a name.`),null;const a=o.owner,i=typeof a=="object"&&a!==null&&!Array.isArray(a)?{...typeof a.name=="string"?{name:a.name}:{},...typeof a.email=="string"?{email:a.email}:{}}:void 0;return{name:o.name,plugins:oe(o.plugins,o.name,r),...typeof o.version=="string"?{version:o.version}:{},...i!==void 0?{owner:i}:{}}}l(se,"readableMarketplaceManifest");function ae(e){const n=[...y()===null?[]:[{scope:"project",root:y()}],{scope:"user",root:S()}],r=[];for(const{scope:o,root:a}of n){const i=N(o,e);for(const t of x(k(a,"marketplaces"))){const s=k(a,"marketplaces",t);try{const c=K(s);if(c===null){e.push(`Marketplace "${t}" has no readable manifest: ${s}`);continue}const u=se(c,t,e);if(u===null)continue;const d=i?.marketplaces[t];r.push({name:t,scope:o,root:s,manifest:u,url:d?.url??"",ref:d?.ref??"main"})}catch(c){e.push(`Could not read marketplace "${t}": ${b(c)}`)}}}return r}l(ae,"readMarketplaces");function xe(){const e=[],n=re(e),r=ae(e),o=new Map(n.filter(t=>t.sourceMarketplace!==void 0).map(t=>[v(t.sourceMarketplace,t.name),t])),a=new Map(r.flatMap(t=>t.manifest.plugins.map(s=>[v(t.name,s.name),s.version]))),i=[{id:$,kind:"installed",label:"Installed",entries:n.map(t=>ee(t,t.sourceMarketplace===void 0?void 0:a.get(v(t.sourceMarketplace,t.name)))).sort((t,s)=>t.name.localeCompare(s.name))}];for(const t of r.sort((s,c)=>s.name.localeCompare(c.name)))try{i.push({id:M(t.name,t.scope),kind:"marketplace",label:t.name,marketplace:ne(t,o),entries:t.manifest.plugins.map(s=>te(t,s,o)).sort((s,c)=>s.name.localeCompare(c.name))})}catch(s){e.push(`Could not load marketplace "${t.name}": ${b(s)}`)}return{sources:i,installScopes:["user",...y()===null?[]:["project"]],warnings:e}}l(xe,"loadCatalog");function R(e,n=[]){const r=[...n,e.name];return e.kind==="branch"?{path:r,kind:"branch",description:e.description,whenToUse:e.whenToUse,summary:e.summary,...e.tier!==void 0?{tier:e.tier}:{},...e.passthrough!==void 0?{passthrough:e.passthrough}:{},...e.rootEntry!==void 0?{rootEntry:e.rootEntry}:{},children:e.children.map(o=>R(o,r)),params:[],output:[],effects:[]}:{path:r,kind:"leaf",description:e.description,whenToUse:e.whenToUse,summary:e.summary,...e.tier!==void 0?{tier:e.tier}:{},children:[],params:e.params,output:e.output,effects:[...e.effects],..."rest"in e?{rest:{method:e.rest.method,path:e.rest.path,streaming:e.rest.streaming===!0}}:{}}}l(R,"commandNode");function ie(e){return H(Q(e)).files.map(n=>{const r=J(n.frontmatter,n.body,{missingPrivacy:"public"});let o;try{o=w(n.path).size}catch{}return{name:`${e.name}/${n.name}`,kind:r.kind==="preference"?"preference":"knowledge",...r.summary!==null?{shortForm:r.summary}:{},...r.preview!==""?{routingLine:r.preview}:{},path:n.path,...o!==void 0?{sizeBytes:o}:{},rules:r.rules,unlisted:r.unlisted,...r.whyItExists!==null?{rationale:r.whyItExists}:{},body:n.body}})}l(ie,"docDetails");function le(e){try{return Z(e).reduce((n,r)=>n+w(r).size,0)}catch{return}}l(le,"directorySize");async function Ae(e){if(e.root===void 0||!A(e.root))return null;try{const n=E(e.root);if(n===null)return null;const r=e.install.kind==="installed"?e.install.scope:"user",o={name:e.name,scope:r,root:e.root,manifest:n,enabled:e.install.kind!=="installed"||e.install.enabled},a=new Set(U),[i,t]=await Promise.all([B(),_()]);let s=q(o,a,i,t);const c=[];if(e.install.kind==="installed"&&e.install.enabled)try{s=L(a,void 0,void 0,i,t).find(p=>p.plugin.root===e.root)??s}catch(d){c.push({message:`Could not resolve the effective command registry: ${b(d)}`,next:"Repair the unreadable installed plugin manifest, then reopen the dossier."})}if(e.install.kind!=="installed"||!e.install.enabled){const d=new Map;for(const m of F())if(m.plugin.root!==e.root)for(const f of m.contributions){const h=d.get(f.node.name)??[];h.push(m.plugin),d.set(f.node.name,h)}const p=e.install.kind==="installed"?"enabling":"installing";s.contributions=s.contributions.map(m=>{const f=d.get(m.node.name);if(f===void 0||f.length===0)return m;const h=C({name:e.name,sourceMarketplace:e.marketplace},m.node.name),T=f.map(g=>`moves ${g.name}'s to "${C(g,m.node.name)}"`);return s.issues.push({code:"command_collision",plugin:o.name,path:m.node.name,message:`top-level command "${m.node.name}" is already claimed by ${f.map(g=>g.name).join(", ")} \u2014 ${p} mounts this one as "${h}" and ${T.join(" and ")}`,received:[...f.map(g=>g.name),o.name].join(", "),expected:"an origin-qualified top-level command for each claimant",next:`After ${p}, invoke "${h}".`}),{...m,node:{...m.node,name:h}}})}const u=n.transport;return{root:e.root,transport:u?.kind??null,...u?.kind==="exec"&&u.executable!==void 0?{transportTarget:u.executable}:{},...u?.kind==="http"?{transportTarget:u.endpoint}:{},commands:s.contributions.map(d=>R(d.node)),commandIssues:[...s.issues.map(({message:d,next:p})=>({message:d,...p!==void 0?{next:p}:{}})),...c],docs:ie(o),sizeBytes:le(e.root)}}catch{return null}}l(Ae,"loadCapability");function b(e){return e instanceof Error?e.message:String(e)}l(b,"errorMessage");export{Ae as loadCapability,xe as loadCatalog};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var l=Object.defineProperty;var h=(n,s)=>l(n,"name",{value:s,configurable:!0});import{getMarkdownTheme as g}from"@earendil-works/pi-coding-agent";import{Markdown as c,visibleWidth as p,wrapTextWithAnsi as $}from"@earendil-works/pi-tui";import{theme as r,wrapText as x}from"../../../core/tui/panel.js";function B(n,s){const t=[],i=Math.max(1,s);t.push(...o(n.name,i).map(e=>r.fg("accent",r.bold(e)))),t.push(r.fg("dim",n.kind)),n.shortForm&&(t.push(""),t.push(...a(n.shortForm,i))),t.push("",r.fg("dim","READ WHEN")),t.push(...a(n.routingLine||"Not declared.",i)),t.push("",r.fg("dim","ROUTING")),n.rules.length===0&&t.push(...a("No rules \u2014 reachable through directory listings and explicit reads only.",i));for(const e of n.rules){const u=[`deliver ${e.deliver}`];e.match?.length&&u.push(e.match.join(", ")),e.matchFrontmatter!==void 0&&u.push(JSON.stringify(e.matchFrontmatter)),e.if!==void 0&&u.push(`if ${JSON.stringify(e.if)}`),t.push(...f(e.on,u.join(" "),i))}return n.unlisted&&t.push(...f("unlisted","suppressed from directory listings",i)),n.rationale&&(t.push("",r.fg("dim","RATIONALE")),t.push(...a(n.rationale,i))),t.push("",r.fg("dim","ON DISK")),t.push(...f("path",n.path,i)),t.push(...f("size",N(n.sizeBytes),i)),t.push("",r.fg("dim","BODY"),""),t.push(...new c(n.body,0,0,g()).render(i)),t}h(B,"renderDocView");function a(n,s){return o(n,Math.max(1,s-2)).map(i=>` ${r.fg("dim",i)}`)}h(a,"paragraph");function f(n,s,t){const i=` ${n} `,e=" ".repeat(p(i)),u=Math.max(1,t-p(i));return o(s,u).map((m,d)=>d===0?`${r.fg("accent",i)}${r.fg("dim",m)}`:`${e}${r.fg("dim",m)}`)}h(f,"field");function o(n,s){const t=n.trim();return t.split(/\s+/).some(i=>p(i)>s)?$(t,s):x(t,s)}h(o,"wrapped");function N(n){return n===void 0?"unknown":n<1024?`${n} B`:n<1024*1024?`${Math.round(n/1024)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}h(N,"size");export{B as renderDocView};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Field, InputParam } from '../../../core/help.js';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { RuleSpec } from '../../../core/graph/types.js';
|
|
3
|
+
import type { OwnerRef, Scope } from '../../../types.js';
|
|
4
4
|
/** The scopes that can hold a marketplace, and that a plugin can be installed
|
|
5
5
|
* into. Narrower than `Scope`: `builtin` names plugins that ship with crtr, and
|
|
6
6
|
* `listAllMarketplaces()` never yields it, so a builtin marketplace or a
|
|
@@ -77,7 +77,7 @@ export declare function flattenCommands(nodes: CommandNode[]): CommandNode[];
|
|
|
77
77
|
* name. `routingLine` is agent read-routing — WHEN to open it — and belongs
|
|
78
78
|
* under the doc view's own heading, never in the description slot. */
|
|
79
79
|
export interface DocDetail {
|
|
80
|
-
/** `<plugin>/<path>` — the identifier `crtr
|
|
80
|
+
/** `<plugin>/<path>` — the identifier `crtr canvas read` takes. */
|
|
81
81
|
name: string;
|
|
82
82
|
kind: "knowledge" | "preference";
|
|
83
83
|
/** Frontmatter `short-form`: the abbreviated content. */
|
|
@@ -87,22 +87,14 @@ export interface DocDetail {
|
|
|
87
87
|
/** Absolute path to the `.md` on disk. */
|
|
88
88
|
path: string;
|
|
89
89
|
sizeBytes?: number;
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/** Frontmatter `unlisted`: suppressed from directory listings. */
|
|
90
|
+
/** Routing rules: when the doc delivers, and how much. Empty = reachable
|
|
91
|
+
* through listings and explicit reads only. */
|
|
92
|
+
rules: RuleSpec[];
|
|
93
|
+
/** Suppressed from directory listings. */
|
|
95
94
|
unlisted: boolean;
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
/** Frontmatter `gate`: eligibility predicate over the node's config. */
|
|
99
|
-
gate?: Record<string, unknown>;
|
|
100
|
-
/** Frontmatter `rationale`: the observed failure the doc exists to close.
|
|
101
|
-
* Maintainer-facing — never delivered to a reading agent. */
|
|
95
|
+
/** The observed failure the doc exists to close. Maintainer-facing — never
|
|
96
|
+
* delivered to a reading agent. */
|
|
102
97
|
rationale?: string;
|
|
103
|
-
/** Effective valid plugin-owned metadata. Enabled declaration defaults appear
|
|
104
|
-
* here without materializing in the memory document. */
|
|
105
|
-
extensions: Record<string, Record<string, MemoryExtensionScalar>>;
|
|
106
98
|
/** Markdown body, frontmatter stripped. */
|
|
107
99
|
body: string;
|
|
108
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var b=Object.defineProperty;var u=(
|
|
1
|
+
var b=Object.defineProperty;var u=(t,a)=>b(t,"name",{value:a,configurable:!0});import{defineLeaf as f}from"../../core/command.js";import{notFound as k}from"../../core/errors.js";import{paginate as v}from"../../core/pagination.js";import{listInstalledPlugins as x,findPluginByName as p}from"../../core/resolver.js";import{packageFiles as j}from"../../core/graph/package-files.js";import{validatePluginCommands as q,validateEffectiveCommandPlugins as P}from"../../core/command-plugins/discovery.js";import{compileHookRegistry as w,discoverHookRegistry as S}from"../../core/command-hooks/discovery.js";import{hasDeclaredHooks as R,hookReport as g}from"../../core/command-hooks/report.js";import{SUBTREE_NAMES as M,coreCommandPaths as C,coreHookCatalog as D,extensibleCoreBranches as E}from"../../build-root.js";import{pluginMemoryDir as _,resolveScopeArg as h,projectScopeRoot as y}from"../../core/scope.js";async function B(t){if(!R(t.manifest))return;const a=await D(),l=S(a),n=l.validations.find(i=>i.plugin.root===t.root);if(n===void 0){const i=w(a,[t]);return g(i.validations[0])}return g(n,l.issues.filter(i=>i.plugin===t.name&&i.scope===t.scope))}u(B,"hookInspectionReport");const V=f({name:"list",description:"paginated list of installed plugins",whenToUse:"enumerating installed plugins across user and project scope, optionally including disabled plugins",help:{name:"pkg plugin list",summary:"paginated list of installed plugins",params:[{kind:"flag",name:"scope",type:"enum",choices:["user","project","all"],required:!1,constraint:"Default: all."},{kind:"flag",name:"include-disabled",type:"bool",required:!1,constraint:"Include disabled plugins. Default: false."},{kind:"flag",name:"limit",type:"int",required:!1,default:50,constraint:"Default 50, max 200."},{kind:"flag",name:"cursor",type:"string",required:!1,constraint:"Opaque token from next_cursor. Omit on first call."}],output:[{name:"items",type:"object[]",required:!0,constraint:"Each: {name, scope, version?, enabled, transport, source_marketplace?, path}. transport is exec or http for command plugins, null for docs-only plugins. Sorted by scope then name ascending."},{name:"next_cursor",type:"string | null",required:!0,constraint:"null means no more items."},{name:"total",type:"integer | null",required:!0,constraint:"Exact when cheap; null otherwise."}],outputKind:"object",effects:["None. Read-only."]},run:u(async t=>{const a=t.scope,l=t.includeDisabled??!1,n=t.limit,i=n!==void 0?Math.min(Math.max(1,n),200):50,c=t.cursor;let m;if(a!==void 0){const e=h(a);m=e==="all"?["project","user"].filter(s=>s!=="project"||y()!==null):[e]}else m=["project","user"].filter(e=>e!=="project"||y()!==null);const o=m.flatMap(e=>x(e)).filter(e=>l||e.enabled).sort((e,s)=>e.scope==="project"&&s.scope!=="project"?-1:e.scope!=="project"&&s.scope==="project"?1:e.name.localeCompare(s.name)),d=v(o,{limit:i,cursor:c!==void 0?c:void 0},{defaultLimit:50,maxLimit:200,keyOf:u(e=>`${e.scope}:${e.name}`,"keyOf"),total:"count"});return{items:d.items.map(e=>({name:e.name,scope:e.scope,version:e.version,enabled:e.enabled,transport:e.manifest.transport?.kind??null,source_marketplace:e.sourceMarketplace,path:e.root})),next_cursor:d.next_cursor,total:d.total}},"run")}),W=f({name:"show",description:"read plugin manifest and substrate inventory",whenToUse:"reading one installed plugin in detail: manifest, provided memory docs, scope, path, and enabled state",help:{name:"pkg plugin show",summary:"read plugin manifest and metadata by name",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Narrows resolution."}],output:[{name:"name",type:"string",required:!0,constraint:"Plugin name."},{name:"scope",type:"string",required:!0,constraint:"Scope the plugin is installed in."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the plugin directory."},{name:"enabled",type:"boolean",required:!0,constraint:"Whether the plugin is active."},{name:"manifest",type:"object",required:!0,constraint:"Full plugin.json contents."},{name:"docs",type:"object[]",required:!0,constraint:"Each: {name, path}. Memory docs provided by the plugin (its `<pluginName>/` memory subtree)."},{name:"commands",type:"object",required:!1,constraint:"Present only when the plugin declares a command manifest (manifest.commands). {manifestPath: string, mounts: string[] (accepted command paths), extensibleBranches: string[] (plugin mount names accepting repository fragments), issues: object[] ({code, path?, message, received, expected, next})}. Validated statically; command execution never occurs."},{name:"hooks",type:"object",required:!1,constraint:"Present for every hook declaration, including hook-only plugins. {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[] ({code, path?, message, received, expected, next}), trust: string}. Static only: no hook executable runs."}],outputKind:"object",effects:["None. Read-only. Command and lifecycle-hook manifests are validated statically; plugin executables are never executed."]},run:u(async t=>{const a=t.name,l=t.scope;let n;if(l!==void 0){const o=h(l);o==="all"||o==="builtin"?n=p(a):n=p(a,o)}else n=p(a);if(n===null)throw k(`plugin not found: ${a}`);const i=j(_(n)).files.map(o=>({name:`${n.name}/${o.name}`,path:o.path}));let c;if(typeof n.manifest.commands=="string"&&n.manifest.commands.length>0){const o=new Set(M),[d,e]=await Promise.all([C(),E()]),s=P(o,void 0,void 0,d,e).find(r=>r.plugin.root===n.root)??q(n,o,d,e);c={manifestPath:s.manifestPath,mounts:[...s.contributions.map(r=>r.node.name),...s.coreMounts.map(r=>[...r.parent,r.node.name].join(" "))],extensibleBranches:s.contributions.filter(r=>r.node.extensible===!0).map(r=>r.node.name),issues:s.issues}}const m=await B(n);return{name:n.name,scope:n.scope,path:n.root,enabled:n.enabled,manifest:n.manifest,docs:i.map(o=>({name:o.name,path:o.path})),...c!==void 0?{commands:c}:{},...m!==void 0?{hooks:m}:{}}},"run")});export{V as pluginList,W as pluginShow};
|
|
@@ -34,18 +34,14 @@ interface BundleReplaceResult extends Record<string, unknown> {
|
|
|
34
34
|
hooks?: HookReport;
|
|
35
35
|
memory?: PluginMemoryReport;
|
|
36
36
|
}
|
|
37
|
-
/** Who owns the
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* corpus is the caller's own directory the install keeps as a live link: the
|
|
41
|
-
* rewrite lands there, outlives a rejected install, and is never rolled back. */
|
|
37
|
+
/** Who owns the memory store a candidate gate checks. A `package` store is
|
|
38
|
+
* bytes this command owns (staged, or installed under the scope's plugins dir);
|
|
39
|
+
* a `linked` store is the caller's own directory the install keeps as a live link. */
|
|
42
40
|
type PluginMemoryOwnership = 'package' | 'linked';
|
|
43
41
|
interface PluginMemoryReport extends Record<string, unknown> {
|
|
44
42
|
/** Markdown documents the candidate's memory store holds. */
|
|
45
43
|
docs: number;
|
|
46
|
-
/**
|
|
47
|
-
migrated: string[];
|
|
48
|
-
/** The caller-owned directory converged in place, absent for a package corpus. */
|
|
44
|
+
/** The caller-owned directory kept as a live link, absent for a package corpus. */
|
|
49
45
|
linkedSource?: string;
|
|
50
46
|
}
|
|
51
47
|
/** Validate a package candidate before it gains an active plugin path. The
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
var
|
|
2
|
-
${
|
|
3
|
-
`)}`,{issues:
|
|
4
|
-
${
|
|
5
|
-
`)}`,{issues:
|
|
6
|
-
${
|
|
7
|
-
`)}`,{issues:
|
|
8
|
-
${
|
|
9
|
-
`)}`,{issues:
|
|
10
|
-
${
|
|
11
|
-
`)}`,{issues:
|
|
12
|
-
${
|
|
13
|
-
`)}`,{
|
|
14
|
-
${m.
|
|
15
|
-
`)}`,{issues:u,next:`Correct the package's memory documents, then retry \u2014 "${e.name}" was not activated.`})}return{docs:v.documents,migrated:[...new Set([...l.wrote.consumers,...l.wrote.identities])].map(m=>oe(r,m)).sort(),...o==="linked"?{linkedSource:me(r)}:{}}}d(Dn,"migratePluginMemory");async function R(e,t,n,i,o,r,a="package"){try{cn(e)}catch(u){const m=u instanceof Error?u.message:String(u);throw f(`plugin manifest at ${o} declares invalid memory_extensions: ${m}`)}Cn(e,o),Hn(e,o),An(e,o),Ln(e,o);const[s,c]=await Promise.all([J(),Q()]),l=ne({name:e.name,scope:n,root:t,manifest:e,enabled:!0},new Set(Y),s,c);if(l.issues.length>0)throw X(`plugin command behavior at ${o} is invalid`,l.issues);await Bn(e,t,n,i,o,r);const p=h(t,"memory"),v=h(i,"memory","__plugin_candidate__.md");for(const u of sn(p,m=>m.endsWith(".md"),m=>m.startsWith("."))){let m;try{m=kn(an(u)).data}catch(b){throw f(`plugin memory document ${U(t,u)} has invalid YAML frontmatter: ${b instanceof Error?b.message.split(`
|
|
16
|
-
`)[0]:String(b)}`)}const y=vn(m);if(y!==null)throw f(`plugin memory document ${U(t,u)} is invalid: ${y}`);for(const b of un(m?.extensions,dn({scope:n,path:v},{candidate:e})))throw f(`plugin memory document ${U(t,u)} is invalid: ${b.path}: ${b.message}`)}return Dn(e,t,n,o,a)}d(R,"assertPluginCandidateValid");function Nn(e){return{kind:"http",endpoint:new URL(e.endpoint).origin,...e.authEnv!==void 0?{authEnv:e.authEnv}:{}}}d(Nn,"invocationTransport");function A(e,t){const n=M(e,t);if(n===e||!n.startsWith(e+Ve))throw f(`bundle member path escapes the staging directory: ${t}`);return n}d(A,"stagedPath");function Un(e,t,n){rn(A(e,".crouter-plugin/plugin.json"),t);for(const i of n.directories)j(A(e,i.path));O(A(e,"commands.json"),n.commandsBytes);for(const i of n.memory){const o=A(e,i.path);j(M(o,"..")),O(o,i.bytes)}if(n.hooks!==void 0){O(A(e,"hooks.json"),n.hooks.manifest);for(const i of n.hooks.files){const o=A(e,i.path);j(M(o,"..")),O(o,i.bytes)}We(A(e,"hooks/dispatch"),493)}}d(Un,"writeStagedBundle");async function Fn(e,t,n,i,o){const r=await R(o,n,t,i,`${n}/.crouter-plugin/plugin.json`),a={name:e,scope:t,root:n,manifest:o,enabled:!0},[s,c]=await Promise.all([J(),Q()]),l=ne(a,new Set(Y),s,c);if(l.issues.length>0)throw X(`bundle staged package for "${e}" is invalid`,l.issues);return r}d(Fn,"validateStagedBundle");function Se(e){return e.sourceMarketplace!==void 0||ee(e.root)||G(e.root)}d(Se,"isSourceInstalled");function Re(e){throw f(`HTTP plugin "${e}" uses the removed commands-only endpoint format`,{next:`Run \`crtr pkg plugin remove ${e}\`, then reinstall it with \`crtr pkg plugin install --name ${e} --endpoint <archive-url>\`.`})}d(Re,"rejectLegacyHttpPlugin");function Vn(e,t,n){if(!k(n))return;const i=H(e,t);if(i?.manifest.bundle!==void 0)return i;throw i?.manifest.transport?.kind==="http"&&i!==void 0&&!Se(i)&&Re(e),f(`plugin "${e}" already exists at ${n}; run \`crtr pkg plugin remove ${e}\` before installing the archive plugin.`)}d(Vn,"existingBundleRoot");function Ee(e,t,n,i){const o=je(e,t.endpoint,t.authEnv),r={endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},a=h(_(n),e);return Vn(e,n,a),{bundle:r,transport:Nn(r),scopeRootPath:i,root:a}}d(Ee,"resolveBundleTarget");function Te(e,t){return{name:e,endpoint:t.endpoint,...t.authEnv!==void 0?{authEnv:t.authEnv}:{}}}d(Te,"fetchTarget");const Wn=6e4,On=1e4;async function qe(e,t,n,i){const o=t==="project"?Z():T();return j(h(o,"tmp")),nn(ue(o,e),()=>i(o),{timeoutMs:n,timeoutError:d(()=>f(`timed out waiting for another crtr process to finish replacing plugin "${e}"`,{next:`Re-run once that process has finished, or check for a stalled crtr holding ${ue(o,e)}.`}),"timeoutError")})}d(qe,"withBundleSwapLock");async function Me(e,t,n,i){return qe(e,n,Wn,async o=>{const r=Ee(e,t,n,o),a=await ke(Te(e,r.bundle));if(a.status!==200){const s=`HTTP plugin bundle fetch failed for "${e}": ${a.message}`;throw a.status==="auth_env_missing"?$(s):a.status==="cli_unreachable"?ze(s):f(s)}return Ae(e,n,r,a.raw,a.etag,i)})}d(Me,"replaceBundlePlugin");async function Mt(e,t,n,i){return qe(e,n,On,async o=>{try{const r=Ee(e,t,n,o),a=i.conditional?Je(n).plugins[e]?.etag:void 0,s={...a!==void 0?{ifNoneMatch:a}:{},...i.timeoutMs!==void 0?{timeoutMs:i.timeoutMs}:{}},c=await ke(Te(e,r.bundle),s);if(c.status===304)return;if(c.status!==200)throw f(`HTTP plugin bundle revalidation failed for "${e}": ${c.message}`);const l=Ce(c.raw);if(Gn(e,n,r.root,l)){_e(n,e,c.etag,{swapped:!1});return}return await Ae(e,n,r,c.raw,c.etag,i,l)}finally{zn(n,e)}})}d(Mt,"revalidateBundlePlugin");function zn(e,t){V(e,n=>{n.plugins[t]===void 0&&(n.plugins[t]={}),n.plugins[t].checked_at=W()})}d(zn,"recordPluginCheck");function _e(e,t,n,i){V(e,o=>{o.plugins[t]===void 0&&(o.plugins[t]={}),i.swapped&&(o.plugins[t].last_updated=W()),o.plugins[t].checked_at=W(),n===void 0?delete o.plugins[t].etag:o.plugins[t].etag=n})}d(_e,"recordCheckedGeneration");function Ce(e){return Oe("sha256").update(e).digest("hex").slice(0,12)}d(Ce,"bundleVersion");function Gn(e,t,n,i){return Ye(t).plugins[e]?.version!==i?!1:k(h(n,"commands.json"))}d(Gn,"isInstalledGeneration");async function Ae(e,t,n,i,o,r,a){const{bundle:s,transport:c,scopeRootPath:l,root:p}=n,[v,u]=await Promise.all([J(),Q()]),m=await Sn(i,{reservedCoreNames:new Set(Y),coreCommandPaths:v,extensibleCoreBranches:u});if(m.bundle===void 0)throw X(`HTTP plugin bundle for "${e}" is invalid`,m.issues);const y=a??Ce(i),b={name:e,version:y,commands:"commands.json",transport:c,bundle:s,...m.bundle.kinds!==void 0?{kinds:m.bundle.kinds}:{},...m.bundle.page_components!==void 0?{page_components:m.bundle.page_components}:{},...m.bundle.memory_extensions!==void 0?{memory_extensions:m.bundle.memory_extensions}:{},...m.bundle.hooks!==void 0?{hooks:"hooks.json",hookExecutable:"hooks/dispatch"}:{}},P=h(l,"tmp"),x=h(P,`${e}.${process.pid}`),q=`${x}.prev`;if(k(q))throw f(`cannot replace plugin "${e}": prior interrupted replacement remains at ${q}`);j(P),j(_(t)),S(x);let D;try{j(x),Un(x,b,m.bundle),D=await Fn(e,t,x,l,b);let L=!1;k(p)&&(w(p,q),L=!0);try{w(x,p)}catch(De){throw L&&w(q,p),De}L&&S(q)}finally{S(x)}z(t,l),I(t,L=>{L.plugins[e]={enabled:r.enable?!0:L.plugins[e]?.enabled??!0,version:y}}),_e(t,e,o,{swapped:!0});const re=await te(e,t);if(re===void 0)throw f(`bundle plugin "${e}" has no staged command report`);const ae=await ie(e,t);return{name:e,scope:t,path:p,transport:"http",version:y,docs:m.bundle.memory.length,kinds:Object.keys(m.bundle.kinds??{}).length,pageComponents:(m.bundle.page_components??[]).length,commands:re,...ae!==void 0?{hooks:ae}:{},...D!==void 0?{memory:D}:{}}}d(Ae,"applyBundleArchive");async function Kn(e,t,n,i){const o=je(e,t,n);return Me(e,{endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},i,{enable:!0})}d(Kn,"installHttpPlugin");function Yn(e){if(e.startsWith("./")||e.startsWith("../")||e.startsWith("/"))return{kind:"local",value:e};if(be(e))return{kind:"git",value:e};const t=e.split("/");if(t.length===2&&t[0]!==""&&t[1]!=="")return{kind:"marketplace",value:{marketplace:t[0],plugin:t[1]}};throw $(`invalid plugin install ref: ${e}
|
|
17
|
-
Accepted forms: marketplace/plugin, git URL (https://, ssh://, git@, file://, or *.git), or local path starting ./, ../, or /. Bare plugin names are not install refs.`)}d(Yn,"classifyInstallRef");function Le(e){return e.startsWith("./")||e.startsWith("../")||!Fe(e)&&!be(e)}d(Le,"isMarketplaceRelativeSource");async function He(e,t,n){const i=t.get(e);if(i!==void 0)return i;const o=Ge(e);if(o===null){if(n.strict)throw g(`marketplace not found: ${e}`);return null}const r=he(o.root);if(r===null)throw g(`marketplace manifest not found: ${o.root}/.crouter-marketplace/marketplace.json`);if(!ee(o.root)){const l={marketplace:o,manifest:r,pull:{updated:!1,sha:C(o.root)??""}};return t.set(e,l),l}const a=C(o.root),s=h(se(o.root),`.${e}.${process.pid}.${Date.now()}.candidate`),c=`${s}.previous`;try{K(o.url,s,{ref:o.ref,depth:1});const l=he(s);if(l===null)throw g(`marketplace manifest not found in candidate checkout: ${s}/.crouter-marketplace/marketplace.json`);const p=le().filter(u=>u.sourceMarketplace===e&&G(u.root));for(const u of p){const m=l.plugins.find(D=>D.name===u.name);if(m===void 0||!Le(m.source))throw f(`marketplace candidate removes relative-source plugin "${u.name}" while it is installed`);const y=on(u.root);if(y===null)throw f(`installed marketplace plugin "${u.name}" has no readable symlink target`);const b=U(o.root,M(se(u.root),y)),P=M(s,m.source);if(P!==M(s,b))throw f(`marketplace candidate moves installed relative-source plugin "${u.name}" from ${b} to ${m.source}`);if(!k(P))throw g(`marketplace candidate source path does not exist for plugin "${u.name}": ${P}`);const x=E(P);if(x===null)throw g(`plugin manifest not found in marketplace candidate: ${P}/.crouter-plugin/plugin.json`);const q=u.scope==="project"?B("project"):T();await R(x,P,u.scope,q,`${P}/.crouter-plugin/plugin.json`)}w(o.root,c);try{w(s,o.root)}catch(u){throw w(c,o.root),u}S(c);for(const u of p){const m=l.plugins.find(y=>y.name===u.name);Be(u.scope,u.name,m.version??u.manifest.version)}V(o.scope,u=>{u.marketplaces[e]===void 0&&(u.marketplaces[e]={}),u.marketplaces[e].last_updated=W()});const v={marketplace:o,manifest:l,pull:{updated:a!==C(o.root),sha:C(o.root)??""}};return t.set(e,v),v}finally{S(s),k(c)&&!k(o.root)&&w(c,o.root)}}d(He,"refreshMarketplace");function Be(e,t,n){I(e,i=>{const o=i.plugins[t];o!==void 0?n!==void 0&&(o.version=n):i.plugins[t]={enabled:!0,version:n}}),V(e,i=>{i.plugins[t]===void 0&&(i.plugins[t]={}),i.plugins[t].last_updated=W()})}d(Be,"updatePluginVersion");async function Jn(e,t,n){const i=n==="project"?Z():T();z(n,i);const o=_(n),r=ln(e),a=h(i,"tmp",`${r}.${process.pid}.${Date.now()}`);j(h(i,"tmp"));try{K(e,a,{ref:t,depth:1});const s=E(a);if(s===null)throw f(`cloned repo does not contain a valid .crouter-plugin/plugin.json: ${e}`);const c=await R(s,a,n,i,`${e}/.crouter-plugin/plugin.json`),l=h(o,s.name);if(k(l))throw f(`plugin "${s.name}" is already installed at ${l}`);return j(o),w(a,l),I(n,p=>{p.plugins[s.name]={enabled:!0,version:s.version}}),{name:s.name,scope:n,path:l,...c!==void 0?{memory:c}:{}}}finally{S(a)}}d(Jn,"installFromGit");async function Qn(e,t){const n=M(e),i=E(n);if(i===null)throw g(`plugin manifest not found at ${n}/.crouter-plugin/plugin.json`);const o=t==="project"?Z():T(),r=await R(i,n,t,o,`${n}/.crouter-plugin/plugin.json`,void 0,"linked");z(t,o);const a=h(_(t),i.name);if(k(a))throw f(`plugin "${i.name}" is already installed at ${a}`);return pe(n,a),I(t,s=>{s.plugins[i.name]={enabled:!0,version:i.version}}),{name:i.name,scope:t,path:a,...r!==void 0?{memory:r}:{}}}d(Qn,"installFromLocal");async function Xn(e,t){const n=await He(e.marketplace,new Map,{strict:!0});if(n===null)throw g(`marketplace not found: ${e.marketplace}`);const i=n.manifest.plugins.find(l=>l.name===e.plugin);if(i===void 0)throw g(`plugin "${e.plugin}" not found in marketplace "${e.marketplace}"`);const o=B(t);z(t,o);const r=h(_(t),e.plugin);if(k(r))throw f(`plugin "${e.plugin}" is already installed at ${r}`);let a,s;if(Le(i.source)){const l=h(n.marketplace.root,i.source);if(!k(l))throw g(`plugin source path does not exist: ${l}`);const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`,void 0,"linked"),pe(l,r),a=p}else{const l=h(o,"tmp",`${e.plugin}.${process.pid}.${Date.now()}`);j(h(o,"tmp"));try{K(i.source,l,{depth:1});const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`),j(_(t)),w(l,r),a=p}finally{S(l)}}const c=i.version??a.version;return I(t,l=>{const p={enabled:!0,source_marketplace:e.marketplace};c!==void 0&&(p.version=c),l.plugins[e.plugin]=p}),{name:e.plugin,scope:t,path:r,...s!==void 0?{memory:s}:{}}}d(Xn,"installFromMarketplace");async function Zn(e){if(G(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?B("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`,void 0,"linked");return{updated:!1,sha:C(e.root)??"",manifest:s,...l!==void 0?{memory:l}:{}}}if(!ee(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?B("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`);return{updated:!1,sha:"",manifest:s,...l!==void 0?{memory:l}:{}}}const t=fe(["config","--get","remote.origin.url"],e.root).stdout.trim();if(t==="")throw f(`plugin "${e.name}" has no origin remote to stage an update from`);const n=fe(["symbolic-ref","--short","HEAD"],e.root).stdout.trim();if(n==="")throw f(`plugin "${e.name}" is detached at its installed revision and has no tracked branch to update`);const i=e.scope==="project"?B("project"):T(),o=h(i,"tmp",`${e.name}.${process.pid}.${Date.now()}.candidate`),r=`${o}.previous`,a=C(e.root);j(h(i,"tmp"));try{K(t,o,{ref:n,depth:1});const s=E(o);if(s===null)throw g(`plugin manifest not found in update candidate: ${o}/.crouter-plugin/plugin.json`);const c=await R(s,o,e.scope,i,`${o}/.crouter-plugin/plugin.json`);w(e.root,r);try{w(o,e.root)}catch(p){throw w(r,e.root),p}S(r);const l=C(e.root)??"";return{updated:a!==l,sha:l,manifest:s,...c!==void 0?{memory:c}:{}}}finally{S(o),k(r)&&!k(e.root)&&w(r,e.root)}}d(Zn,"updateGitPluginCandidate");async function Ie(e,t,n){const i=Se(e);if(!i&&e.manifest.bundle!==void 0){const p=await Me(e.name,e.manifest.bundle,e.scope,{enable:e.enabled});return{name:e.name,transport:"http",updated:!0,version:p.version,docs:p.docs,kinds:p.kinds,pageComponents:p.pageComponents,commands:p.commands,...p.hooks!==void 0?{hooks:p.hooks}:{},...p.memory!==void 0?{memory:p.memory}:{}}}e.manifest.transport?.kind==="http"&&!i&&Re(e.name);let o,r=!1;if(e.sourceMarketplace!==void 0){const p=await He(e.sourceMarketplace,t,n);p!==null&&(o=p.manifest.plugins.find(u=>u.name===e.name)?.version,r=p.pull.updated)}const a=await Zn(e);Be(e.scope,e.name,o??a.manifest.version);const s=await te(e.name,e.scope),c=await ie(e.name,e.scope),l=Pe(a.manifest);return{name:e.name,...e.manifest.transport!==void 0?{transport:e.manifest.transport.kind}:{},updated:r||a.updated,sha:a.sha,...s!==void 0?{commands:s}:{},...c!==void 0?{hooks:c}:{},...a.memory!==void 0?{memory:a.memory}:{},...l.length>0?{warnings:l}:{}}}d(Ie,"updateOnePlugin");const _t=F({name:"install",description:"install from a ref or HTTP endpoint",whenToUse:"installing one plugin from a marketplace ref, git URL, local path, or an HTTP directory-archive endpoint",help:{name:"pkg plugin install",summary:"install a plugin from a ref or HTTP endpoint",params:[{kind:"positional",name:"install-ref",type:"string",required:!1,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 /."},{kind:"flag",name:"endpoint",type:"string",required:!1,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."},{kind:"flag",name:"name",type:"string",required:!1,constraint:"Required with --endpoint and rejected without it. Lowercase kebab-case plugin handle."},{kind:"flag",name:"auth-env",type:"string",required:!1,constraint:"Optional environment variable holding the HTTP bearer token. Accepted only with --endpoint; its value is never stored."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: project if available, else user."},{kind:"flag",name:"ref",type:"string",required:!1,constraint:"Git ref (branch/tag) for git URL installs. Rejected with --endpoint; ignored for marketplace and local path refs."}],output:[{name:"name",type:"string",required:!0,constraint:"Plugin name as installed."},{name:"scope",type:"string",required:!0,constraint:"Scope the plugin was installed into."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the installed plugin directory."},{name:"transport",type:"string",required:!1,constraint:"exec or http when the plugin declares commands. Always http for an --endpoint install."},{name:"version",type:"string",required:!1,constraint:"First 12 hex characters of the fetched archive SHA-256 for an --endpoint install."},{name:"docs",type:"integer",required:!1,constraint:"Memory document count written from an --endpoint archive."},{name:"kinds",type:"integer",required:!1,constraint:"Kind-registry entry count declared by an --endpoint archive\u2019s bundle.json."},{name:"pageComponents",type:"integer",required:!1,constraint:"Page-component registration count declared by an --endpoint archive\u2019s bundle.json."},{name:"commands",type:"object",required:!1,constraint:"Present only when the plugin declares a command manifest. {mounts: string[] (accepted command paths now live for the next invocation), issues: object[] (typed validation issues that rejected a contribution \u2014 {code, path?, message, received, expected, next})}. Validated statically; commands are never executed."},{name:"hooks",type:"object",required:!1,constraint:"Present only when the plugin declares hooks. {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}. Command targets, lifecycle events, and replacement collisions are validated statically; hook executables are never run."},{name:"warnings",type:"string[]",required:!1,constraint:"Advisory missing PATH executable requirements declared by the installed plugin. The install still succeeds and leaves the plugin enabled."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only when the install keeps that directory as a live link)}."}],outputKind:"object",effects:["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.","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, memory docs, and, when declared, hooks.json plus the hooks/ tree; it also copies any kind-registry entries the bundle.json declares (they join the launch registry below this scope\u2019s own config.json kinds), and any page components it declares (they join the active page-component catalog alongside the user config entries); a fetch or validation failure preserves the prior package.","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.","Plugin command hooks go live on the next crtr invocation. They run implicitly with caller authority, may receive normalized inputs and after results, may block or replace declared targets, and may transmit received data. Lifecycle hooks run unprompted at every declared event before node launch and may transmit node identity and resolved paths. Hook executables are never run during install or update validation.","A plugin manifest `requires` declaration is checked against the PATH a node bash receives after install. Missing executables emit a warning with the declared install hint but never fail the install, disable the plugin, or remove its bare-binary contributions.","Before activation the candidate\u2019s memory corpus is migrated to exact canonical identity and refused if it cannot mount. A staged candidate is migrated in staging and rolls back with the package; a local path or marketplace-relative source stays a live link, so its own directory is rewritten in place, keeps that rewrite whether or not the install completes, and is named as `memory.linkedSource`. A refused corpus writes nothing and installs nothing."]},run:d(async e=>{N();const t=e.installRef,n=e.endpoint,i=e.name,o=e.authEnv,r=e.scope,a=e.ref,s=Mn(r);if(t===void 0==(n===void 0))throw $("provide exactly one of INSTALL-REF or --endpoint");if(n!==void 0){if(i===void 0)throw $("--name is required with --endpoint");if(a!==void 0)throw $("--ref is only valid with a git INSTALL-REF, not --endpoint");return Kn(i,n,o,s)}if(i!==void 0)throw $("--name is only valid with --endpoint");if(o!==void 0)throw $("--auth-env is only valid with --endpoint");const c=Yn(t),l=c.kind==="marketplace"?await Xn(c.value,s):c.kind==="local"?await Qn(c.value,s):await Jn(c.value,a,s),p=H(l.name,l.scope),v=await te(l.name,l.scope),u=await ie(l.name,l.scope),m=p===null?[]:Pe(p.manifest);return{...l,...p?.manifest.transport!==void 0?{transport:p.manifest.transport.kind}:{},...v!==void 0?{commands:v}:{},...u!==void 0?{hooks:u}:{},...m.length>0?{warnings:m}:{}}},"run")}),Ct=F({name:"remove",description:"remove plugin and directory",whenToUse:"uninstalling a plugin: deletes its directory and removes it from config",help:{name:"pkg plugin remove",summary:"remove a plugin and its directory from the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to remove."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: searches every scope."}],output:[{name:"scopes",type:"string[]",required:!0,constraint:"Scopes the plugin was removed from."}],outputKind:"object",effects:["Deletes the plugin directory. Removes the plugin entry from config.json."]},run:d(async e=>{N();const t=e.name,n=e.scope;if(t==="crtr")throw $('cannot remove builtin plugin "crtr" \u2014 it ships with the binary');let i;if(n!==void 0){const r=ce(n);if(r==="builtin")throw $("cannot remove plugins from builtin scope");i=r==="all"?["project","user"].filter(a=>a!=="project"||de()!==null):[r]}else i=["project","user"].filter(r=>r!=="project"||de()!==null);const o=[];for(const r of i){const a=_(r);if(a===null)continue;const s=h(a,t);k(s)&&(S(s),I(r,c=>{delete c.plugins[t]}),V(r,c=>{delete c.plugins[t]}),o.push(r))}if(o.length===0)throw g(`plugin not found: ${t}`);return{scopes:o}},"run")}),At=F({name:"enable",description:"enable a plugin",whenToUse:"reactivating a plugin that was previously disabled so its memory docs resolve again",help:{name:"pkg plugin enable",summary:"enable a plugin in the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to enable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only for a symlinked install)}."}],outputKind:"object",effects:["Validates the installed package before any config change: its memory corpus is migrated to exact canonical identity and refused if it cannot mount. A refusal leaves the plugin disabled.","Sets plugin enabled=true in config.json."]},run:d(async e=>{N();const t=e.name,n=qn(t,e.scope);if(n===null)throw g(`plugin not found: ${t}`);const i=E(n.root);if(i===null)throw g(`plugin manifest not found at ${n.root}/.crouter-plugin/plugin.json`);const o=n.scope==="project"?B("project"):T(),r=await R(i,n.root,n.scope,o,`${n.root}/.crouter-plugin/plugin.json`,void 0,G(n.root)?"linked":"package");return{scope:(await $e(e,!0)).scope,...r!==void 0?{memory:r}:{}}},"run")}),Lt=F({name:"disable",description:"disable without removing",whenToUse:"hiding a plugin from resolution without deleting it, so you can re-enable it later",help:{name:"pkg plugin disable",summary:"disable a plugin (keeps files, hides from resolution)",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to disable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."}],outputKind:"object",effects:["Sets plugin enabled=false in config.json."]},run:d(async e=>(N(),{scope:(await $e(e,!1)).scope}),"run")}),Ht=F({name:"update",description:"update installed plugin content",whenToUse:"refreshing one named plugin or all installed plugins: archive plugins replace their complete package, while source-installed plugins retain their source update behavior",help:{name:"pkg plugin update",summary:"refresh one or all installed plugins",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Plugin name to update. Omit to update all installed plugins."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Narrows resolution."}],output:[{name:"updated",type:"object[]",required:!0,constraint:"One entry per plugin processed: {name, transport?, updated, sha?, version?, docs?, kinds?, pageComponents?, commands?, hooks?, memory?, warnings?, error?}. memory is present for a plugin shipping a memory store and reports the same corpus migration install performs: {docs, migrated, linkedSource?}. Archive plugins report transport=http and replace their complete directory after an authenticated refetch; version is the archive content identifier, docs is the written memory-document count, kinds is the declared kind-registry entry count, and pageComponents is the declared page-component registration 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[] (accepted command paths), issues: object[]}. hooks is present for plugins declaring hooks: {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}; it is static and never executes hooks. warnings lists advisory PATH requirements that remain absent after update."}],outputKind:"object",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.","Each candidate passes the same pre-activation memory-corpus migration install performs, with the same linked-source rewrite semantics for a symlinked install."]},run:d(async e=>{N();const t=e.name,n=e.scope,i=n===void 0?void 0:ce(n),o=new Map;if(t!==void 0){const s=i===void 0||i==="all"||i==="builtin"?H(t):H(t,i);if(s===null)throw g(`plugin not found: ${t}${i===void 0||i==="all"||i==="builtin"?"":` (scope: ${i})`}`);return{updated:[await Ie(s,o,{strict:!0})]}}const r=le().filter(s=>s.scope!=="builtin"&&(i===void 0||i==="all"||s.scope===i)),a=[];for(const s of r)try{a.push(await Ie(s,o,{strict:!1}))}catch(c){a.push({name:s.name,...s.manifest.transport!==void 0?{transport:s.manifest.transport.kind}:{},updated:!1,error:c instanceof Error?c.message:String(c)})}return{updated:a}},"run")});export{R as assertPluginCandidateValid,Xn as installFromMarketplace,Le as isMarketplaceRelativeSource,Lt as pluginDisable,At as pluginEnable,_t as pluginInstall,Ct as pluginRemove,Ht as pluginUpdate,Mt as revalidateBundlePlugin};
|
|
1
|
+
var Be=Object.defineProperty;var d=(e,n)=>Be(e,"name",{value:n,configurable:!0});import{envProfileId as De}from"../../shared/env.js";import{dirname as ae,join as h,resolve as C,isAbsolute as Ie,relative as N,sep as Fe}from"node:path";import{chmodSync as Ne,renameSync as w,writeFileSync as O}from"node:fs";import{createHash as Ue}from"node:crypto";import{defineLeaf as U}from"../../core/command.js";import{cliClient as Ve,rethrowAsCliError as We}from"../api-client.js";import{notFound as g,usage as $,general as m,network as Oe,CrtrError as ze}from"../../core/errors.js";import{findMarketplaceByName as Ge,findPluginByName as B,listAllPlugins as se}from"../../core/resolver.js";import{pluginsDir as A,ensureProjectScopeRoot as Z,userScopeRoot as T,resolveScopeArg as le,projectScopeRoot as ce,requireScopeRoot as D}from"../../core/scope.js";import{readConfig as Ke,readState as Je,updateConfig as I,updateState as V,ensureScopeInitialized as z,invalidPluginKindsReasons as Ye,invalidPluginBinReasons as Qe,invalidPluginRequiresReasons as Xe,normalizeRequires as Ze}from"../../core/config.js";import{withExclusiveDirectoryLockAsync as en}from"../../core/exclusive-lock.js";import{bundleSwapLockPath as de}from"../../core/plugin-swap-lock.js";import{invalidPageComponentsReasons as nn}from"../../core/human/page-catalog.js";import{pathExists as y,ensureDir as j,removePath as S,nowIso as W,linkOrCopy as ue,isSymlink as G,readSymlinkTarget as tn,atomicWriteJson as on,readText as rn,realpathOrSelf as an,walkFiles as sn}from"../../core/fs-utils.js";import{clone as K,deriveNameFromUrl as ln,currentSha as M,gitSync as pe,isGitRepo as ee}from"../../core/git.js";import{readMarketplaceManifest as fe,readPluginManifest as E}from"../../core/manifest.js";import{pluginExtensionCatalog as cn,validateMemoryExtensionValues as dn,validatePluginMemoryExtensions as un}from"../../core/plugin-extensions.js";import{lintPackageFrontmatter as pn,packageFiles as fn}from"../../core/graph/package-files.js";import{parseFrontmatterGeneric as mn}from"../../core/frontmatter.js";import{validatePluginCommands as ne,validateEffectiveCommandPlugins as hn}from"../../core/command-plugins/discovery.js";import{normalizeEndpoint as gn,validateEndpoint as yn,validateHttpPluginTransport as vn}from"../../core/command-plugins/endpoint.js";import{buildBrokerEnv as kn,resolvePathExecutable as wn}from"../../core/runtime/spawn-env.js";import{validatePluginBundle as bn}from"../../core/command-plugins/bundle.js";import{compileHookRegistry as me,discoverCandidateHookRegistry as $n,discoverCandidateHookRegistryForCandidates as jn,discoverHookRegistry as Pn}from"../../core/command-hooks/discovery.js";import{hasDeclaredHooks as he,hookReport as ge}from"../../core/command-hooks/report.js";import{fetchHttpPluginBundle as ye}from"../../core/command-plugins/transport/http-fetch.js";import{SUBTREE_NAMES as J,coreCommandPaths as Y,coreHookCatalog as ve,extensibleCoreBranches as Q}from"../../build-root.js";import{ExitCode as xn}from"../../types.js";import{isGitUrl as ke,resolvePluginConfigTarget as Sn,setPluginEnabled as we,resolveInstallScope as Rn}from"./shared.js";async function te(e,n){const t=B(e,n);if(t===null||typeof t.manifest.commands!="string"||t.manifest.commands.length===0)return;const i=new Set(J),[o,s]=await Promise.all([Y(),Q()]),a=hn(i,void 0,void 0,o,s).find(r=>r.plugin.root===t.root)??ne(t,i,o,s);return{mounts:[...a.contributions.map(r=>r.node.name),...a.coreMounts.map(r=>[...r.parent,r.node.name].join(" "))],issues:a.issues}}d(te,"commandReport");const En=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;function be(e,n,t){if(typeof e!="string"||!En.test(e))throw $("invalid --name: expected a lowercase kebab-case plugin handle");const i=yn(n);if(!i.isValid)throw $(`invalid --endpoint: ${i.errors.join("; ")}`);const o=gn(n),s=vn({kind:"http",endpoint:o,...t!==void 0?{authEnv:t}:{}});if(s.transport===void 0)throw $(`invalid HTTP plugin transport: ${s.errors.join("; ")}`);return s.transport}d(be,"validateHttpInstall");function X(e,n){const t=n.map(i=>`- ${i.code}${i.path!==void 0?` at ${i.path}`:""}: ${i.message} (received ${JSON.stringify(i.received)}, expected ${i.expected})`);return m(`${e}:
|
|
2
|
+
${t.join(`
|
|
3
|
+
`)}`,{issues:n,...n.length>0?{next:n[0].next}:{}})}d(X,"invalidBundleError");function Tn(e,n){if(e.kinds===void 0)return;const t=Ye(e.kinds);if(t.length>0)throw m(`plugin manifest at ${n} declares an invalid kinds block:
|
|
4
|
+
${t.map(i=>`- ${i}`).join(`
|
|
5
|
+
`)}`,{issues:t})}d(Tn,"assertManifestKindsValid");function qn(e,n){if(e.bin===void 0)return;const t=Qe(e.bin);if(t.length>0)throw m(`plugin manifest at ${n} declares an invalid bin block:
|
|
6
|
+
${t.map(i=>`- ${i}`).join(`
|
|
7
|
+
`)}`,{issues:t})}d(qn,"assertManifestBinValid");function Cn(e,n){if(e.requires===void 0)return;const t=Xe(e.requires);if(t.length>0)throw m(`plugin manifest at ${n} declares an invalid requires block:
|
|
8
|
+
${t.map(i=>`- ${i}`).join(`
|
|
9
|
+
`)}`,{issues:t})}d(Cn,"assertManifestRequiresValid");function $e(e){if(e.requires===void 0)return[];const n=kn({argv:[],env:{CRTR_NODE_CWD:process.cwd(),CRTR_PROFILE_ID:De()??""}});return Object.entries(Ze(e.requires)).filter(([t])=>wn(t,n,process.cwd())===null).map(([t,i])=>`Warning: plugin "${e.name}" requires "${t}" on PATH \u2014 ${i}`)}d($e,"missingRequirementWarnings");function An(e,n){if(e.page_components===void 0)return;const t=nn(e.page_components);if(t.length>0)throw m(`plugin manifest at ${n} declares an invalid page_components block:
|
|
10
|
+
${t.map(i=>`- ${i}`).join(`
|
|
11
|
+
`)}`,{issues:t})}d(An,"assertManifestPageComponentsValid");async function ie(e,n){const t=B(e,n);if(t===null||!he(t.manifest))return;const i=await ve(),o=Pn(i),s=o.validations.find(a=>a.plugin.root===t.root);if(s===void 0){const a=me(i,[t]);return ge(a.validations[0])}return ge(s,o.issues.filter(a=>a.plugin===t.name&&a.scope===t.scope))}d(ie,"hookLifecycleReport");async function Mn(e,n,t,i,o,s){if(!he(e))return;const a={name:e.name,scope:t,root:n,manifest:e,enabled:!0},r=s??[{plugin:a,scopeRoot:i}],c=await ve(),l=s===void 0?$n(c,a,i):jn(c,r),v=l.validations.find(p=>p.plugin.root===n)===void 0?me(c,[a]).issues:l.issues.filter(p=>p.plugin===a.name&&p.scope===a.scope);if(v.length>0)throw X(`plugin hook behavior at ${o} is invalid`,v)}d(Mn,"assertManifestHooksValid");function _n(e,n){const t=N(e,n);return t===""?e:t}d(_n,"storeRelative");function Hn(e,n,t,i,o){const s=h(n,"memory");if(!y(s))return;const{files:a,invalid:r}=fn(s);if(r.length>0){const c=r.map(l=>`- ${_n(s,l.path)}: ${l.error}`);throw m(`plugin "${e.name}" memory corpus at ${i} has documents that cannot be named:
|
|
12
|
+
${c.join(`
|
|
13
|
+
`)}`,{issues:r,next:`Correct the package's memory documents, then retry \u2014 "${e.name}" was not activated.`})}return{docs:a.length,...o==="linked"?{linkedSource:an(s)}:{}}}d(Hn,"migratePluginMemory");async function R(e,n,t,i,o,s,a="package"){try{un(e)}catch(p){const f=p instanceof Error?p.message:String(p);throw m(`plugin manifest at ${o} declares invalid memory_extensions: ${f}`)}Tn(e,o),An(e,o),qn(e,o),Cn(e,o);const[r,c]=await Promise.all([Y(),Q()]),l=ne({name:e.name,scope:t,root:n,manifest:e,enabled:!0},new Set(J),r,c);if(l.issues.length>0)throw X(`plugin command behavior at ${o} is invalid`,l.issues);await Mn(e,n,t,i,o,s);const u=h(n,"memory"),v=cn(t,i,{candidate:e});for(const p of sn(u,f=>f.endsWith(".md"),f=>f.startsWith("."))){let f;try{f=mn(rn(p)).data}catch(b){throw m(`plugin memory document ${N(n,p)} has invalid YAML frontmatter: ${b instanceof Error?b.message.split(`
|
|
14
|
+
`)[0]:String(b)}`)}const k=pn(f);if(k!==null)throw m(`plugin memory document ${N(n,p)} is invalid: ${k}`);for(const b of dn(f?.extensions,v))throw m(`plugin memory document ${N(n,p)} is invalid: ${b.path}: ${b.message}`)}return Hn(e,n,t,o,a)}d(R,"assertPluginCandidateValid");function Ln(e){return{kind:"http",endpoint:new URL(e.endpoint).origin,...e.authEnv!==void 0?{authEnv:e.authEnv}:{}}}d(Ln,"invocationTransport");function _(e,n){const t=C(e,n);if(t===e||!t.startsWith(e+Fe))throw m(`bundle member path escapes the staging directory: ${n}`);return t}d(_,"stagedPath");function Bn(e,n,t){on(_(e,".crouter-plugin/plugin.json"),n);for(const i of t.directories)j(_(e,i.path));O(_(e,"commands.json"),t.commandsBytes);for(const i of t.memory){const o=_(e,i.path);j(C(o,"..")),O(o,i.bytes)}if(t.hooks!==void 0){O(_(e,"hooks.json"),t.hooks.manifest);for(const i of t.hooks.files){const o=_(e,i.path);j(C(o,"..")),O(o,i.bytes)}Ne(_(e,"hooks/dispatch"),493)}}d(Bn,"writeStagedBundle");async function Dn(e,n,t,i,o){const s=await R(o,t,n,i,`${t}/.crouter-plugin/plugin.json`),a={name:e,scope:n,root:t,manifest:o,enabled:!0},[r,c]=await Promise.all([Y(),Q()]),l=ne(a,new Set(J),r,c);if(l.issues.length>0)throw X(`bundle staged package for "${e}" is invalid`,l.issues);return s}d(Dn,"validateStagedBundle");function je(e){return e.sourceMarketplace!==void 0||ee(e.root)||G(e.root)}d(je,"isSourceInstalled");function Pe(e){throw m(`HTTP plugin "${e}" uses the removed commands-only endpoint format`,{next:`Run \`crtr pkg plugin remove ${e}\`, then reinstall it with \`crtr pkg plugin install --name ${e} --endpoint <archive-url>\`.`})}d(Pe,"rejectLegacyHttpPlugin");function In(e,n,t){if(!y(t))return;const i=B(e,n);if(i?.manifest.bundle!==void 0)return i;throw i?.manifest.transport?.kind==="http"&&i!==void 0&&!je(i)&&Pe(e),m(`plugin "${e}" already exists at ${t}; run \`crtr pkg plugin remove ${e}\` before installing the archive plugin.`)}d(In,"existingBundleRoot");function xe(e,n,t,i){const o=be(e,n.endpoint,n.authEnv),s={endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},a=h(A(t),e);return In(e,t,a),{bundle:s,transport:Ln(s),scopeRootPath:i,root:a}}d(xe,"resolveBundleTarget");function Se(e,n){return{name:e,endpoint:n.endpoint,...n.authEnv!==void 0?{authEnv:n.authEnv}:{}}}d(Se,"fetchTarget");const Fn=6e4,Nn=1e4;async function Re(e,n,t,i){const o=n==="project"?Z():T();return j(h(o,"tmp")),en(de(o,e),()=>i(o),{timeoutMs:t,timeoutError:d(()=>m(`timed out waiting for another crtr process to finish replacing plugin "${e}"`,{next:`Re-run once that process has finished, or check for a stalled crtr holding ${de(o,e)}.`}),"timeoutError")})}d(Re,"withBundleSwapLock");async function Ee(e,n,t,i){return Re(e,t,Fn,async o=>{const s=xe(e,n,t,o),a=await ye(Se(e,s.bundle));if(a.status!==200){const r=`HTTP plugin bundle fetch failed for "${e}": ${a.message}`;throw a.status==="auth_env_missing"?$(r):a.status==="cli_unreachable"?Oe(r):m(r)}return Ce(e,t,s,a.raw,a.etag,i)})}d(Ee,"replaceBundlePlugin");async function St(e,n,t,i){return Re(e,t,Nn,async o=>{try{const s=xe(e,n,t,o),a=i.conditional?Je(t).plugins[e]?.etag:void 0,r={...a!==void 0?{ifNoneMatch:a}:{},...i.timeoutMs!==void 0?{timeoutMs:i.timeoutMs}:{}},c=await ye(Se(e,s.bundle),r);if(c.status===304)return;if(c.status!==200)throw m(`HTTP plugin bundle revalidation failed for "${e}": ${c.message}`);const l=qe(c.raw);if(Vn(e,t,s.root,l)){Te(t,e,c.etag,{swapped:!1});return}return await Ce(e,t,s,c.raw,c.etag,i,l)}finally{Un(t,e)}})}d(St,"revalidateBundlePlugin");function Un(e,n){V(e,t=>{t.plugins[n]===void 0&&(t.plugins[n]={}),t.plugins[n].checked_at=W()})}d(Un,"recordPluginCheck");function Te(e,n,t,i){V(e,o=>{o.plugins[n]===void 0&&(o.plugins[n]={}),i.swapped&&(o.plugins[n].last_updated=W()),o.plugins[n].checked_at=W(),t===void 0?delete o.plugins[n].etag:o.plugins[n].etag=t})}d(Te,"recordCheckedGeneration");function qe(e){return Ue("sha256").update(e).digest("hex").slice(0,12)}d(qe,"bundleVersion");function Vn(e,n,t,i){return Ke(n).plugins[e]?.version!==i?!1:y(h(t,"commands.json"))}d(Vn,"isInstalledGeneration");async function Ce(e,n,t,i,o,s,a){const{bundle:r,transport:c,scopeRootPath:l,root:u}=t,[v,p]=await Promise.all([Y(),Q()]),f=await bn(i,{reservedCoreNames:new Set(J),coreCommandPaths:v,extensibleCoreBranches:p});if(f.bundle===void 0)throw X(`HTTP plugin bundle for "${e}" is invalid`,f.issues);const k=a??qe(i),b={name:e,version:k,commands:"commands.json",transport:c,bundle:r,...f.bundle.kinds!==void 0?{kinds:f.bundle.kinds}:{},...f.bundle.page_components!==void 0?{page_components:f.bundle.page_components}:{},...f.bundle.memory_extensions!==void 0?{memory_extensions:f.bundle.memory_extensions}:{},...f.bundle.hooks!==void 0?{hooks:"hooks.json",hookExecutable:"hooks/dispatch"}:{}},P=h(l,"tmp"),x=h(P,`${e}.${process.pid}`),q=`${x}.prev`;if(y(q))throw m(`cannot replace plugin "${e}": prior interrupted replacement remains at ${q}`);j(P),j(A(n)),S(x);let F;try{j(x),Bn(x,b,f.bundle),F=await Dn(e,n,x,l,b);let L=!1;y(u)&&(w(u,q),L=!0);try{w(x,u)}catch(Le){throw L&&w(q,u),Le}L&&S(q)}finally{S(x)}z(n,l),I(n,L=>{L.plugins[e]={enabled:s.enable?!0:L.plugins[e]?.enabled??!0,version:k}}),Te(n,e,o,{swapped:!0});const oe=await te(e,n);if(oe===void 0)throw m(`bundle plugin "${e}" has no staged command report`);const re=await ie(e,n);return{name:e,scope:n,path:u,transport:"http",version:k,docs:f.bundle.memory.length,kinds:Object.keys(f.bundle.kinds??{}).length,pageComponents:(f.bundle.page_components??[]).length,commands:oe,...re!==void 0?{hooks:re}:{},...F!==void 0?{memory:F}:{}}}d(Ce,"applyBundleArchive");async function Wn(e,n,t,i){const o=be(e,n,t);return Ee(e,{endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},i,{enable:!0})}d(Wn,"installHttpPlugin");function On(e){if(e.startsWith("./")||e.startsWith("../")||e.startsWith("/"))return{kind:"local",value:e};if(ke(e))return{kind:"git",value:e};const n=e.split("/");if(n.length===2&&n[0]!==""&&n[1]!=="")return{kind:"marketplace",value:{marketplace:n[0],plugin:n[1]}};throw $(`invalid plugin install ref: ${e}
|
|
15
|
+
Accepted forms: marketplace/plugin, git URL (https://, ssh://, git@, file://, or *.git), or local path starting ./, ../, or /. Bare plugin names are not install refs.`)}d(On,"classifyInstallRef");function Ae(e){return e.startsWith("./")||e.startsWith("../")||!Ie(e)&&!ke(e)}d(Ae,"isMarketplaceRelativeSource");async function Me(e,n,t){const i=n.get(e);if(i!==void 0)return i;const o=Ge(e);if(o===null){if(t.strict)throw g(`marketplace not found: ${e}`);return null}const s=fe(o.root);if(s===null)throw g(`marketplace manifest not found: ${o.root}/.crouter-marketplace/marketplace.json`);if(!ee(o.root)){const l={marketplace:o,manifest:s,pull:{updated:!1,sha:M(o.root)??""}};return n.set(e,l),l}const a=M(o.root),r=h(ae(o.root),`.${e}.${process.pid}.${Date.now()}.candidate`),c=`${r}.previous`;try{K(o.url,r,{ref:o.ref,depth:1});const l=fe(r);if(l===null)throw g(`marketplace manifest not found in candidate checkout: ${r}/.crouter-marketplace/marketplace.json`);const u=se().filter(p=>p.sourceMarketplace===e&&G(p.root));for(const p of u){const f=l.plugins.find(F=>F.name===p.name);if(f===void 0||!Ae(f.source))throw m(`marketplace candidate removes relative-source plugin "${p.name}" while it is installed`);const k=tn(p.root);if(k===null)throw m(`installed marketplace plugin "${p.name}" has no readable symlink target`);const b=N(o.root,C(ae(p.root),k)),P=C(r,f.source);if(P!==C(r,b))throw m(`marketplace candidate moves installed relative-source plugin "${p.name}" from ${b} to ${f.source}`);if(!y(P))throw g(`marketplace candidate source path does not exist for plugin "${p.name}": ${P}`);const x=E(P);if(x===null)throw g(`plugin manifest not found in marketplace candidate: ${P}/.crouter-plugin/plugin.json`);const q=p.scope==="project"?D("project"):T();await R(x,P,p.scope,q,`${P}/.crouter-plugin/plugin.json`)}w(o.root,c);try{w(r,o.root)}catch(p){throw w(c,o.root),p}S(c);for(const p of u){const f=l.plugins.find(k=>k.name===p.name);_e(p.scope,p.name,f.version??p.manifest.version)}V(o.scope,p=>{p.marketplaces[e]===void 0&&(p.marketplaces[e]={}),p.marketplaces[e].last_updated=W()});const v={marketplace:o,manifest:l,pull:{updated:a!==M(o.root),sha:M(o.root)??""}};return n.set(e,v),v}finally{S(r),y(c)&&!y(o.root)&&w(c,o.root)}}d(Me,"refreshMarketplace");function _e(e,n,t){I(e,i=>{const o=i.plugins[n];o!==void 0?t!==void 0&&(o.version=t):i.plugins[n]={enabled:!0,version:t}}),V(e,i=>{i.plugins[n]===void 0&&(i.plugins[n]={}),i.plugins[n].last_updated=W()})}d(_e,"updatePluginVersion");async function zn(e,n,t){const i=t==="project"?Z():T();z(t,i);const o=A(t),s=ln(e),a=h(i,"tmp",`${s}.${process.pid}.${Date.now()}`);j(h(i,"tmp"));try{K(e,a,{ref:n,depth:1});const r=E(a);if(r===null)throw m(`cloned repo does not contain a valid .crouter-plugin/plugin.json: ${e}`);const c=await R(r,a,t,i,`${e}/.crouter-plugin/plugin.json`),l=h(o,r.name);if(y(l))throw m(`plugin "${r.name}" is already installed at ${l}`);return j(o),w(a,l),I(t,u=>{u.plugins[r.name]={enabled:!0,version:r.version}}),{name:r.name,scope:t,path:l,...c!==void 0?{memory:c}:{}}}finally{S(a)}}d(zn,"installFromGit");async function Gn(e,n){const t=C(e),i=E(t);if(i===null)throw g(`plugin manifest not found at ${t}/.crouter-plugin/plugin.json`);const o=n==="project"?Z():T(),s=await R(i,t,n,o,`${t}/.crouter-plugin/plugin.json`,void 0,"linked");z(n,o);const a=h(A(n),i.name);if(y(a))throw m(`plugin "${i.name}" is already installed at ${a}`);return ue(t,a),I(n,r=>{r.plugins[i.name]={enabled:!0,version:i.version}}),{name:i.name,scope:n,path:a,...s!==void 0?{memory:s}:{}}}d(Gn,"installFromLocal");async function Kn(e,n){const t=await Me(e.marketplace,new Map,{strict:!0});if(t===null)throw g(`marketplace not found: ${e.marketplace}`);const i=t.manifest.plugins.find(l=>l.name===e.plugin);if(i===void 0)throw g(`plugin "${e.plugin}" not found in marketplace "${e.marketplace}"`);const o=D(n);z(n,o);const s=h(A(n),e.plugin);if(y(s))throw m(`plugin "${e.plugin}" is already installed at ${s}`);let a,r;if(Ae(i.source)){const l=h(t.marketplace.root,i.source);if(!y(l))throw g(`plugin source path does not exist: ${l}`);const u=E(l);if(u===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);r=await R(u,l,n,o,`${l}/.crouter-plugin/plugin.json`,void 0,"linked"),ue(l,s),a=u}else{const l=h(o,"tmp",`${e.plugin}.${process.pid}.${Date.now()}`);j(h(o,"tmp"));try{K(i.source,l,{depth:1});const u=E(l);if(u===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);r=await R(u,l,n,o,`${l}/.crouter-plugin/plugin.json`),j(A(n)),w(l,s),a=u}finally{S(l)}}const c=i.version??a.version;return I(n,l=>{const u={enabled:!0,source_marketplace:e.marketplace};c!==void 0&&(u.version=c),l.plugins[e.plugin]=u}),{name:e.plugin,scope:n,path:s,...r!==void 0?{memory:r}:{}}}d(Kn,"installFromMarketplace");async function Jn(e){if(G(e.root)){const r=E(e.root);if(r===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?D("project"):T(),l=await R(r,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`,void 0,"linked");return{updated:!1,sha:M(e.root)??"",manifest:r,...l!==void 0?{memory:l}:{}}}if(!ee(e.root)){const r=E(e.root);if(r===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?D("project"):T(),l=await R(r,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`);return{updated:!1,sha:"",manifest:r,...l!==void 0?{memory:l}:{}}}const n=pe(["config","--get","remote.origin.url"],e.root).stdout.trim();if(n==="")throw m(`plugin "${e.name}" has no origin remote to stage an update from`);const t=pe(["symbolic-ref","--short","HEAD"],e.root).stdout.trim();if(t==="")throw m(`plugin "${e.name}" is detached at its installed revision and has no tracked branch to update`);const i=e.scope==="project"?D("project"):T(),o=h(i,"tmp",`${e.name}.${process.pid}.${Date.now()}.candidate`),s=`${o}.previous`,a=M(e.root);j(h(i,"tmp"));try{K(n,o,{ref:t,depth:1});const r=E(o);if(r===null)throw g(`plugin manifest not found in update candidate: ${o}/.crouter-plugin/plugin.json`);const c=await R(r,o,e.scope,i,`${o}/.crouter-plugin/plugin.json`);w(e.root,s);try{w(o,e.root)}catch(u){throw w(s,e.root),u}S(s);const l=M(e.root)??"";return{updated:a!==l,sha:l,manifest:r,...c!==void 0?{memory:c}:{}}}finally{S(o),y(s)&&!y(e.root)&&w(s,e.root)}}d(Jn,"updateGitPluginCandidate");async function He(e,n,t){const i=je(e);if(!i&&e.manifest.bundle!==void 0){const u=await Ee(e.name,e.manifest.bundle,e.scope,{enable:e.enabled});return{name:e.name,transport:"http",updated:!0,version:u.version,docs:u.docs,kinds:u.kinds,pageComponents:u.pageComponents,commands:u.commands,...u.hooks!==void 0?{hooks:u.hooks}:{},...u.memory!==void 0?{memory:u.memory}:{}}}e.manifest.transport?.kind==="http"&&!i&&Pe(e.name);let o,s=!1;if(e.sourceMarketplace!==void 0){const u=await Me(e.sourceMarketplace,n,t);u!==null&&(o=u.manifest.plugins.find(p=>p.name===e.name)?.version,s=u.pull.updated)}const a=await Jn(e);_e(e.scope,e.name,o??a.manifest.version);const r=await te(e.name,e.scope),c=await ie(e.name,e.scope),l=$e(a.manifest);return{name:e.name,...e.manifest.transport!==void 0?{transport:e.manifest.transport.kind}:{},updated:s||a.updated,sha:a.sha,...r!==void 0?{commands:r}:{},...c!==void 0?{hooks:c}:{},...a.memory!==void 0?{memory:a.memory}:{},...l.length>0?{warnings:l}:{}}}d(He,"updateOnePlugin");async function H(e){const t=(await Ve().documents.reconcilePackages().catch(i=>We(i))).conflicts.find(i=>i.plugin===e);if(t)throw new ze("conflict",`plugin "${e}" is installed but its documents are not on the canvas: ${t.message}`,xn.GENERAL,{plugin:e,next:"Uninstall the other package providing that plugin name, then run `crtr pkg plugin update --name "+e+"`."})}d(H,"reconcilePluginDocuments");const Rt=U({name:"install",description:"install from a ref or HTTP endpoint",whenToUse:"installing one plugin from a marketplace ref, git URL, local path, or an HTTP directory-archive endpoint",help:{name:"pkg plugin install",summary:"install a plugin from a ref or HTTP endpoint",params:[{kind:"positional",name:"install-ref",type:"string",required:!1,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 /."},{kind:"flag",name:"endpoint",type:"string",required:!1,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."},{kind:"flag",name:"name",type:"string",required:!1,constraint:"Required with --endpoint and rejected without it. Lowercase kebab-case plugin handle."},{kind:"flag",name:"auth-env",type:"string",required:!1,constraint:"Optional environment variable holding the HTTP bearer token. Accepted only with --endpoint; its value is never stored."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: project if available, else user."},{kind:"flag",name:"ref",type:"string",required:!1,constraint:"Git ref (branch/tag) for git URL installs. Rejected with --endpoint; ignored for marketplace and local path refs."}],output:[{name:"name",type:"string",required:!0,constraint:"Plugin name as installed."},{name:"scope",type:"string",required:!0,constraint:"Scope the plugin was installed into."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the installed plugin directory."},{name:"transport",type:"string",required:!1,constraint:"exec or http when the plugin declares commands. Always http for an --endpoint install."},{name:"version",type:"string",required:!1,constraint:"First 12 hex characters of the fetched archive SHA-256 for an --endpoint install."},{name:"docs",type:"integer",required:!1,constraint:"Memory document count written from an --endpoint archive."},{name:"kinds",type:"integer",required:!1,constraint:"Kind-registry entry count declared by an --endpoint archive\u2019s bundle.json."},{name:"pageComponents",type:"integer",required:!1,constraint:"Page-component registration count declared by an --endpoint archive\u2019s bundle.json."},{name:"commands",type:"object",required:!1,constraint:"Present only when the plugin declares a command manifest. {mounts: string[] (accepted command paths now live for the next invocation), issues: object[] (typed validation issues that rejected a contribution \u2014 {code, path?, message, received, expected, next})}. Validated statically; commands are never executed."},{name:"hooks",type:"object",required:!1,constraint:"Present only when the plugin declares hooks. {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}. Command targets, lifecycle events, and replacement collisions are validated statically; hook executables are never run."},{name:"warnings",type:"string[]",required:!1,constraint:"Advisory missing PATH executable requirements declared by the installed plugin. The install still succeeds and leaves the plugin enabled."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), linkedSource?: string (the caller-owned directory, present only when the install keeps that directory as a live link)}."}],outputKind:"object",effects:["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.","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, memory docs, and, when declared, hooks.json plus the hooks/ tree; it also copies any kind-registry entries the bundle.json declares (they join the launch registry below this scope\u2019s own config.json kinds), and any page components it declares (they join the active page-component catalog alongside the user config entries); a fetch or validation failure preserves the prior package.","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.","Plugin command hooks go live on the next crtr invocation. They run implicitly with caller authority, may receive normalized inputs and after results, may block or replace declared targets, and may transmit received data. Lifecycle hooks run unprompted at every declared event before node launch and may transmit node identity and resolved paths. Hook executables are never run during install or update validation.","A plugin manifest `requires` declaration is checked against the PATH a node bash receives after install. Missing executables emit a warning with the declared install hint but never fail the install, disable the plugin, or remove its bare-binary contributions.","Before activation the candidate\u2019s memory store is checked for identity findings and refused if it cannot mount; a local path or marketplace-relative source stays a live link, named as `memory.linkedSource`. A refused store installs nothing."]},run:d(async e=>{const n=e.installRef,t=e.endpoint,i=e.name,o=e.authEnv,s=e.scope,a=e.ref,r=Rn(s);if(n===void 0==(t===void 0))throw $("provide exactly one of INSTALL-REF or --endpoint");if(t!==void 0){if(i===void 0)throw $("--name is required with --endpoint");if(a!==void 0)throw $("--ref is only valid with a git INSTALL-REF, not --endpoint");const k=await Wn(i,t,o,r);return await H(i),k}if(i!==void 0)throw $("--name is only valid with --endpoint");if(o!==void 0)throw $("--auth-env is only valid with --endpoint");const c=On(n),l=c.kind==="marketplace"?await Kn(c.value,r):c.kind==="local"?await Gn(c.value,r):await zn(c.value,a,r),u=B(l.name,l.scope),v=await te(l.name,l.scope),p=await ie(l.name,l.scope),f=u===null?[]:$e(u.manifest);return await H(l.name),{...l,...u?.manifest.transport!==void 0?{transport:u.manifest.transport.kind}:{},...v!==void 0?{commands:v}:{},...p!==void 0?{hooks:p}:{},...f.length>0?{warnings:f}:{}}},"run")}),Et=U({name:"remove",description:"remove plugin and directory",whenToUse:"uninstalling a plugin: deletes its directory and removes it from config",help:{name:"pkg plugin remove",summary:"remove a plugin and its directory from the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to remove."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: searches every scope."}],output:[{name:"scopes",type:"string[]",required:!0,constraint:"Scopes the plugin was removed from."}],outputKind:"object",effects:["Deletes the plugin directory. Removes the plugin entry from config.json."]},run:d(async e=>{const n=e.name,t=e.scope;if(n==="crtr")throw $('cannot remove builtin plugin "crtr" \u2014 it ships with the binary');let i;if(t!==void 0){const s=le(t);if(s==="builtin")throw $("cannot remove plugins from builtin scope");i=s==="all"?["project","user"].filter(a=>a!=="project"||ce()!==null):[s]}else i=["project","user"].filter(s=>s!=="project"||ce()!==null);const o=[];for(const s of i){const a=A(s);if(a===null)continue;const r=h(a,n);y(r)&&(S(r),I(s,c=>{delete c.plugins[n]}),V(s,c=>{delete c.plugins[n]}),o.push(s))}if(o.length===0)throw g(`plugin not found: ${n}`);return await H(),{scopes:o}},"run")}),Tt=U({name:"enable",description:"enable a plugin",whenToUse:"reactivating a plugin that was previously disabled so its memory docs resolve again",help:{name:"pkg plugin enable",summary:"enable a plugin in the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to enable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), linkedSource?: string (the caller-owned directory, present only for a symlinked install)}."}],outputKind:"object",effects:["Validates the installed package before any config change: its memory store is checked for identity findings and refused if it cannot mount. A refusal leaves the plugin disabled.","Sets plugin enabled=true in config.json."]},run:d(async e=>{const n=e.name,t=Sn(n,e.scope);if(t===null)throw g(`plugin not found: ${n}`);const i=E(t.root);if(i===null)throw g(`plugin manifest not found at ${t.root}/.crouter-plugin/plugin.json`);const o=t.scope==="project"?D("project"):T(),s=await R(i,t.root,t.scope,o,`${t.root}/.crouter-plugin/plugin.json`,void 0,G(t.root)?"linked":"package"),a=await we(e,!0);return await H(n),{scope:a.scope,...s!==void 0?{memory:s}:{}}},"run")}),qt=U({name:"disable",description:"disable without removing",whenToUse:"hiding a plugin from resolution without deleting it, so you can re-enable it later",help:{name:"pkg plugin disable",summary:"disable a plugin (keeps files, hides from resolution)",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to disable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."}],outputKind:"object",effects:["Sets plugin enabled=false in config.json."]},run:d(async e=>{const n=await we(e,!1);return await H(),{scope:n.scope}},"run")}),Ct=U({name:"update",description:"update installed plugin content",whenToUse:"refreshing one named plugin or all installed plugins: archive plugins replace their complete package, while source-installed plugins retain their source update behavior",help:{name:"pkg plugin update",summary:"refresh one or all installed plugins",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Plugin name to update. Omit to update all installed plugins."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Narrows resolution."}],output:[{name:"updated",type:"object[]",required:!0,constraint:"One entry per plugin processed: {name, transport?, updated, sha?, version?, docs?, kinds?, pageComponents?, commands?, hooks?, memory?, warnings?, error?}. memory is present for a plugin shipping a memory store and reports the same memory check install performs: {docs, linkedSource?}. Archive plugins report transport=http and replace their complete directory after an authenticated refetch; version is the archive content identifier, docs is the written memory-document count, kinds is the declared kind-registry entry count, and pageComponents is the declared page-component registration 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[] (accepted command paths), issues: object[]}. hooks is present for plugins declaring hooks: {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}; it is static and never executes hooks. warnings lists advisory PATH requirements that remain absent after update."}],outputKind:"object",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.","Each candidate passes the same pre-activation memory check install performs."]},run:d(async e=>{const n=e.name,t=e.scope,i=t===void 0?void 0:le(t),o=new Map;if(n!==void 0){const r=i===void 0||i==="all"||i==="builtin"?B(n):B(n,i);if(r===null)throw g(`plugin not found: ${n}${i===void 0||i==="all"||i==="builtin"?"":` (scope: ${i})`}`);const c=await He(r,o,{strict:!0});return await H(n),{updated:[c]}}const s=se().filter(r=>r.scope!=="builtin"&&(i===void 0||i==="all"||r.scope===i)),a=[];for(const r of s)try{a.push(await He(r,o,{strict:!1}))}catch(c){a.push({name:r.name,...r.manifest.transport!==void 0?{transport:r.manifest.transport.kind}:{},updated:!1,error:c instanceof Error?c.message:String(c)})}return await H(),{updated:a}},"run")});export{R as assertPluginCandidateValid,Kn as installFromMarketplace,Ae as isMarketplaceRelativeSource,qt as pluginDisable,Tt as pluginEnable,Rt as pluginInstall,Et as pluginRemove,Ct as pluginUpdate,St as revalidateBundlePlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var n=(t,e)=>a(t,"name",{value:e,configurable:!0});import{defineLeaf as s}from"../../core/command.js";import{emitLine as o}from"../../core/io.js";import{cliClient as p}from"../api-client.js";const
|
|
1
|
+
var a=Object.defineProperty;var n=(t,e)=>a(t,"name",{value:e,configurable:!0});import{defineLeaf as s}from"../../core/command.js";import{emitLine as o}from"../../core/io.js";import{cliClient as p}from"../api-client.js";const f=s({name:"list",description:"inventory every profile visible to you and its project relationships",whenToUse:"browse every profile that exists \u2014 one line each with its id, name, explicit project relationships, owning app, paused state, and last-used time. Reach for `profile show` once you have picked one, for its full manifest.",help:{name:"profile list",summary:"every profile the daemon shows the caller (its own app's, plus any another app shared) as JSONL, sorted by name then profile_id",output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects_count",type:"int",required:!0,constraint:"Number of `{path}` project relationships on the manifest."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` relationships in manifest order. `path` defines profile purview."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."}],outputKind:"jsonl",effects:["None. Read-only."]},run:n(async()=>{const t=(await p().listProfiles()).sort((e,i)=>{const r=e.name.localeCompare(i.name);return r!==0?r:e.id.localeCompare(i.id)});for(const e of t)o({profile_id:e.id,name:e.name,projects_count:e.projects.length,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,last_used_at:e.last_used_at});o({follow_up:"Show one in full with `crtr profile show <profile>`."})},"run")});export{f as listLeaf};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var l=Object.defineProperty;var n=(e,t)=>l(e,"name",{value:t,configurable:!0});import{defineLeaf as p}from"../../core/command.js";import{usage as i}from"../../core/errors.js";import{resolve as f}from"node:path";import{cliClient as s}from"../api-client.js";import{resolveMetaPairs as m}from"./meta.js";const k=p({name:"new",description:"create a new profile",whenToUse:"you are establishing a new agent identity \u2014 a stable id, a display name, and its own memory store. Pass at most one initial project directory here (the parser has no repeatable-flag support); use `profile project add` afterward for every additional one. Use `--root` (no name) to provision the canonical stable root profile \u2014 the default identity a home falls back to \u2014 idempotently, without spawning a node.",help:{name:"profile new",summary:"create a profile of the caller's app in the scoped store and its app memory folder",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Display name for the profile. Also slugified into the stable profile id \u2014 the id never changes on later rename. Required unless `--root` is given; mutually exclusive with `--root`."},{kind:"flag",name:"root",type:"bool",required:!1,constraint:"Provision the canonical stable root profile (fixed id `root-00000000`, name `root`) \u2014 the fallback default identity for a home \u2014 instead of a fresh named one. Idempotent: re-running returns the existing root. Node-free (no `node new --root` needed). Mutually exclusive with `--name`/`--project`/`--default-kind`/`--meta`."},{kind:"flag",name:"project",type:"path",required:!1,constraint:"One initial project directory. Must already exist and be a directory; resolved to its absolute real path before storing. Creates a purview relationship. Singular \u2014 add more with `crtr profile project add` after creation."},{kind:"flag",name:"default-kind",type:"string",required:!1,constraint:"Installed persona kind for node creates under this profile that omit --kind. Defaults to general when omitted; the daemon validates it against its installed kind registry."},{kind:"flag",name:"meta",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE metadata entry (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`. Each entry reaches every broker launched under the profile as `CRTR_PROFILE_META_<KEY>` env; readable back via `profile show` \u2014 not for secrets (those go to `profile env`)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere."},{name:"memory_path",type:"string",required:!0,constraint:"Absolute path to the profile memory directory."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` project relationships in manifest order. `path` defines purview. Empty when --project was omitted."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"default_kind",type:"string",required:!0,constraint:"Default persona kind for node creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map; empty when --meta was omitted."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."}],outputKind:"object",effects:["Creates a profile row owned by the caller's app (the terminal app for a person) and its memory directory under that app's space. A name the caller's app already holds is refused."]},run:n(async e=>{const t=e.name,r=e.project,a=e.defaultKind,o=m(e.meta,"meta");if(e.root===!0){if(t!==void 0||r!==void 0||a!==void 0||Object.keys(o).length>0)throw i("`--root` provisions the canonical stable root profile and takes no `--name`/`--project`/`--default-kind`/`--meta`.");return d(await s().ensureProfile("root"))}if(t===void 0)throw i("provide `--name <name>` to create a profile, or `--root` to provision the stable root profile.");return d(await s().createProfile({name:t,...r!==void 0?{projects:[{path:f(r)}]}:{},...a!==void 0?{default_kind:a}:{},...Object.keys(o).length>0?{metadata:o}:{}}))},"run")});function d(e){return{profile_id:e.id,memory_path:e.memory_path,projects:e.projects,app:e.app,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at}}n(d,"newProfileOutput");export{k as newLeaf};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var t=(e,
|
|
1
|
+
var p=Object.defineProperty;var t=(e,o)=>p(e,"name",{value:o,configurable:!0});import{defineLeaf as i,defineBranch as d}from"../../core/command.js";import{resolve as s}from"node:path";import{cliClient as a}from"../api-client.js";import{resolveProfileViaDaemon as n}from"./daemon-profiles.js";import{PROFILE_PROJECT_MEMORY_VALUES as l}from"../../api/dto/profiles.js";const c=i({name:"add",description:"add a project to a profile's purview",whenToUse:"a profile needs purview over another project directory \u2014 extend it after creation.",help:{name:"profile project add",summary:"add a project relationship to a profile, deduped by real path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to add. Must exist and be a directory; resolved to its absolute real path before storing. A path already on the profile keeps its position and nothing changes."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path}` relationships in profile order. `path` defines purview."}],outputKind:"object",effects:["Appends a new project relationship to the profile row; purview follows `path`. Running brokers discover the updated projects on their next scope read."]},run:t(async e=>{const{id:o}=await n(e.profile),r=await a().updateProfile(o,{add_project:{path:s(e.dir)}});return{profile_id:r.id,projects:r.projects}},"run")}),m=i({name:"remove",description:"remove a project relationship from a profile's purview",whenToUse:"a profile no longer needs purview over one of its listed project directories \u2014 narrow it back. Works even if the directory itself was since deleted.",help:{name:"profile project remove",summary:"remove a project directory from a profile's manifest",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to remove, matched against the stored project `path`. Does not require the directory to still exist on disk. The profile's app home does not change."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path}` relationships in profile order."}],outputKind:"object",effects:["Removes a project relationship from the profile row. This narrows purview. Running brokers discover the updated projects on their next scope read."]},run:t(async e=>{const{id:o}=await n(e.profile),r=await a().updateProfile(o,{remove_project:s(e.dir)});return{profile_id:r.id,projects:r.projects}},"run")}),u=i({name:"limit",description:"set how much of one owner's documents automatic delivery may disclose",whenToUse:"a profile's nodes should get less of one owner's documents (a repo, `user`, an app, a plugin) at boot and workspace-open \u2014 or that limit should be lifted.",help:{name:"profile project limit",summary:"set a profile's automatic delivery limit for one owner handle",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"owner",type:"string",required:!0,constraint:"Owner handle the limit applies to: a repo handle, `user`, an app, a profile, or a plugin."},{kind:"flag",name:"level",type:"enum",choices:[...l],required:!0,constraint:"Maximum automatic delivery of this owner's documents at boot and workspace-open: `none`, `name`, `preview`, or `content`. `content` is no limit and removes the entry. Does not change explicit `crtr canvas read` access."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"delivery_limits",type:"object",required:!0,constraint:"The profile\u2019s limits after the change, keyed by owner handle; an owner not listed is not limited."}],outputKind:"object",effects:["Sets or removes one entry in the profile's `delivery_limits`. It caps only automatic `boot` and `workspace-open` delivery; a node's own documents are never capped."]},run:t(async e=>{const{id:o}=await n(e.profile),r=await a().updateProfile(o,{set_delivery_limit:{owner:e.owner,level:e.level}});return{profile_id:r.id,delivery_limits:r.delivery_limits}},"run")}),g=d({name:"project",description:"manage a profile's project purview and automatic delivery limits",whenToUse:"changing a profile\u2019s project purview after creation, or limiting how much of one owner's documents its nodes get automatically.",help:{name:"profile project",summary:"manage project purview and per-owner automatic delivery limits",model:"Each `{path}` relationship widens purview: the profile resolves config from `path`. `add` appends a new real path; `remove` narrows purview. `limit` sets the profile's `delivery_limits` entry for one owner handle, which caps only automatic boot and workspace-open delivery of that owner's documents; explicit reads are not capped. Purview and delivery limits are both independent of a per-cwd default pin (`crtr profile default`)."},children:[c,m,u]});export{g as projectBranch};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var i=(r,e)=>a(r,"name",{value:e,configurable:!0});import{defineLeaf as n}from"../../core/command.js";import{resolveProfileViaDaemon as o}from"./daemon-profiles.js";const l=n({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, owning app, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's settings and memory path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path
|
|
1
|
+
var a=Object.defineProperty;var i=(r,e)=>a(r,"name",{value:e,configurable:!0});import{defineLeaf as n}from"../../core/command.js";import{resolveProfileViaDaemon as o}from"./daemon-profiles.js";const l=n({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, owning app, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's settings and memory path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path}` relationships in manifest order. `path` defines profile purview."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map \u2014 each entry reaches brokers launched under the profile as `CRTR_PROFILE_META_<KEY>` env. Empty when none."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."},{name:"memory_path",type:"string",required:!0,constraint:"Absolute path to the profile memory directory."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands, including the SQL-backed raw settings surface."}],outputKind:"object",effects:["None. Read-only."]},run:i(async r=>{const e=await o(r.profile),t=e.id;return{profile_id:t,name:e.name,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at,last_used_at:e.last_used_at,memory_path:e.memory_path,follow_up:e.paused_at===null?`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, pause it with \`crtr profile pause ${t}\`, or set its default kind with \`crtr profile kind ${t} <kind>\`.`:`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path>\`, or resume it with \`crtr profile resume ${t}\`.`}},"run")});export{l as showLeaf};
|