@north-light/crouter 0.3.349 → 0.3.350
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/bin/crtr-launcher +4 -0
- package/bin/runtime-generation-manifest.mjs +12 -2
- package/dist/api/client.d.ts +50 -7
- package/dist/api/client.js +2 -2
- package/dist/api/dto/analytics.d.ts +184 -0
- package/dist/api/dto/analytics.js +0 -0
- package/dist/api/dto/broker-ops.d.ts +43 -1
- package/dist/api/dto/config.d.ts +11 -0
- package/dist/api/dto/grants.d.ts +14 -0
- package/dist/api/dto/grants.js +0 -0
- package/dist/api/dto/human-requests.d.ts +14 -0
- package/dist/api/dto/memory.d.ts +6 -0
- package/dist/api/dto/modelauth.d.ts +35 -0
- package/dist/api/dto/node-records.d.ts +35 -0
- package/dist/api/dto/node-records.js +0 -0
- package/dist/api/dto/nodes.d.ts +5 -0
- package/dist/api/dto/profiles.d.ts +38 -3
- package/dist/api/dto/worktree.d.ts +11 -0
- package/dist/api/errors.d.ts +23 -1
- package/dist/api/errors.js +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +1 -1
- package/dist/api/node-transport.js +1 -1
- package/dist/api/routes.d.ts +22 -0
- package/dist/api/routes.js +1 -1
- package/dist/build-root.d.ts +6 -1
- package/dist/build-root.js +1 -1
- package/dist/builtin-memory/crouter-sdk/client.md +34 -0
- package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
- package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
- package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
- package/dist/cli.js +9 -8
- package/dist/clients/attach/chrome/inbox-strip.js +1 -1
- package/dist/clients/attach/chrome/roster.js +1 -1
- package/dist/clients/attach/config.js +1 -1
- package/dist/clients/attach/overlays/auth.js +2 -2
- package/dist/clients/attach/overlays/graph.js +1 -1
- package/dist/clients/attach/render/tool-calls.js +3 -3
- package/dist/clients/attach/session/connection.js +1 -1
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/viewer.js +1569 -816
- package/dist/commands/api-client.js +3 -3
- package/dist/commands/broker-permissions.d.ts +2 -0
- package/dist/commands/broker-permissions.js +1 -0
- package/dist/commands/canvas-analytics/chart.d.ts +52 -0
- package/dist/commands/canvas-analytics/chart.js +1 -0
- package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
- package/dist/commands/canvas-analytics/drilldown.js +1 -0
- package/dist/commands/canvas-analytics/format.d.ts +29 -0
- package/dist/commands/canvas-analytics/format.js +1 -0
- package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
- package/dist/commands/canvas-analytics/graph-detail.js +2 -0
- package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
- package/dist/commands/canvas-analytics/graphs.js +1 -0
- package/dist/commands/canvas-analytics/memory.d.ts +2 -0
- package/dist/commands/canvas-analytics/memory.js +1 -0
- package/dist/commands/canvas-analytics/overview.d.ts +2 -0
- package/dist/commands/canvas-analytics/overview.js +1 -0
- package/dist/commands/canvas-analytics/shell.d.ts +60 -0
- package/dist/commands/canvas-analytics/shell.js +2 -0
- package/dist/commands/canvas-analytics/time.d.ts +2 -0
- package/dist/commands/canvas-analytics/time.js +1 -0
- package/dist/commands/canvas-analytics/usage.d.ts +2 -0
- package/dist/commands/canvas-analytics/usage.js +1 -0
- package/dist/commands/canvas-analytics/view.d.ts +85 -0
- package/dist/commands/canvas-analytics/view.js +1 -0
- package/dist/commands/canvas-analytics.d.ts +2 -0
- package/dist/commands/canvas-analytics.js +1 -0
- package/dist/commands/canvas-prune.js +1 -1
- package/dist/commands/canvas.js +1 -1
- package/dist/commands/cron.js +5 -5
- package/dist/commands/human/components.d.ts +2 -0
- package/dist/commands/human/components.js +2 -2
- package/dist/commands/human/prompts.js +1 -1
- package/dist/commands/human/queue.js +1 -1
- package/dist/commands/memory/client.d.ts +11 -0
- package/dist/commands/memory/client.js +1 -0
- package/dist/commands/memory/delete.js +1 -1
- package/dist/commands/memory/edit.js +3 -3
- package/dist/commands/memory/find.js +1 -1
- package/dist/commands/memory/history.js +4 -4
- package/dist/commands/memory/lint.js +1 -1
- package/dist/commands/memory/list.d.ts +0 -2
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/move.js +1 -1
- package/dist/commands/memory/origin.js +1 -1
- package/dist/commands/memory/read.d.ts +0 -5
- package/dist/commands/memory/read.js +3 -3
- package/dist/commands/memory/shared.d.ts +0 -178
- package/dist/commands/memory/shared.js +1 -12
- package/dist/commands/memory/write.js +5 -5
- package/dist/commands/node/bash.js +5 -5
- package/dist/commands/node/create.d.ts +0 -17
- package/dist/commands/node/create.js +2 -3
- package/dist/commands/node/inspect.js +6 -6
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/node-context.js +2 -2
- package/dist/commands/node-inspect-artifacts.js +6 -6
- package/dist/commands/pkg/browse/catalog.js +1 -1
- package/dist/commands/pkg/browse/model.d.ts +1 -1
- package/dist/commands/pkg/market-manage.js +1 -1
- package/dist/commands/pkg/plugin-manage.js +10 -10
- package/dist/commands/profile/daemon-profiles.d.ts +13 -0
- package/dist/commands/profile/daemon-profiles.js +4 -0
- package/dist/commands/profile/delete.js +1 -1
- package/dist/commands/profile/env.d.ts +6 -0
- package/dist/commands/profile/env.js +2 -2
- package/dist/commands/profile/kind.js +1 -2
- package/dist/commands/profile/list.js +1 -1
- package/dist/commands/profile/meta.js +1 -1
- package/dist/commands/profile/new.js +1 -1
- package/dist/commands/profile/pause.js +1 -1
- package/dist/commands/profile/project.js +1 -1
- package/dist/commands/profile/rename.js +1 -1
- package/dist/commands/profile/show.js +1 -1
- package/dist/commands/profile.js +1 -1
- package/dist/commands/push.js +3 -3
- package/dist/commands/surface-inspect.js +1 -1
- package/dist/commands/sys/branch.js +1 -1
- package/dist/commands/sys/config.js +1 -1
- package/dist/commands/sys/connect.js +3 -3
- package/dist/commands/sys/context/admin/actions.js +1 -1
- package/dist/commands/sys/context/admin/model.d.ts +1 -0
- package/dist/commands/sys/context/admin/model.js +1 -1
- package/dist/commands/sys/context/admin.js +1 -1
- package/dist/commands/sys/context/expose.js +2 -1
- package/dist/commands/sys/context/prompt-review.js +2 -2
- package/dist/commands/sys/context/resolve.js +7 -7
- package/dist/commands/sys/context/sysprompt.js +1 -1
- package/dist/commands/sys/join.d.ts +1 -0
- package/dist/commands/sys/join.js +1 -0
- package/dist/commands/sys/migrate.js +1 -1
- package/dist/commands/sys/panels/models-panel.js +1 -1
- package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
- package/dist/commands/sys/panels/profiles-panel.js +1 -1
- package/dist/commands/sys/provider-login.js +6 -6
- package/dist/commands/sys/setup-core.d.ts +1 -1
- package/dist/commands/sys/setup-core.js +6 -6
- package/dist/commands/sys/setup-settings-runner.js +1 -1
- package/dist/commands/sys/setup.js +1 -1
- package/dist/commands/sys/spaces.d.ts +1 -0
- package/dist/commands/sys/spaces.js +2 -0
- package/dist/commands/sys/sync-deps.js +2 -2
- package/dist/commands/sys/sync-project-guidance.js +4 -4
- package/dist/commands/sys/sync-skills.js +2 -2
- package/dist/commands/sys/worktrees.d.ts +1 -0
- package/dist/commands/sys/worktrees.js +1 -1
- package/dist/commands/sys.js +1 -1
- package/dist/core/auth-file.js +2 -2
- package/dist/core/bash-job-supervisor.d.ts +6 -0
- package/dist/core/bash-job-supervisor.js +4 -0
- package/dist/core/bash-jobs.d.ts +13 -6
- package/dist/core/bash-jobs.js +8 -7
- package/dist/core/broker-client/transport-relay.d.ts +6 -3
- package/dist/core/broker-client/transport-relay.js +1 -1
- package/dist/core/broker-client/transport-socket.d.ts +6 -1
- package/dist/core/broker-client/transport-socket.js +1 -1
- package/dist/core/canvas/canvas.d.ts +39 -18
- package/dist/core/canvas/canvas.js +21 -20
- package/dist/core/canvas/context-strip.d.ts +20 -0
- package/dist/core/canvas/context-strip.js +5 -0
- package/dist/core/canvas/crons.d.ts +12 -20
- package/dist/core/canvas/crons.js +15 -13
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/deliveries.d.ts +4 -1
- package/dist/core/canvas/deliveries.js +1 -1
- package/dist/core/canvas/executions.js +1 -1
- package/dist/core/canvas/history.d.ts +2 -1
- package/dist/core/canvas/history.js +17 -18
- package/dist/core/canvas/memory-reads.d.ts +19 -0
- package/dist/core/canvas/memory-reads.js +1 -0
- package/dist/core/canvas/migrations.d.ts +0 -4
- package/dist/core/canvas/migrations.js +99 -32
- package/dist/core/canvas/nav-render.js +1 -1
- package/dist/core/canvas/node-agent-paths.d.ts +8 -0
- package/dist/core/canvas/node-agent-paths.js +1 -0
- package/dist/core/canvas/node-recap.d.ts +2 -2
- package/dist/core/canvas/node-recap.js +2 -2
- package/dist/core/canvas/node-tokens.d.ts +24 -0
- package/dist/core/canvas/node-tokens.js +5 -0
- package/dist/core/canvas/paths.d.ts +16 -19
- package/dist/core/canvas/paths.js +1 -1
- package/dist/core/canvas/render-source.d.ts +2 -2
- package/dist/core/canvas/render-source.js +6 -9
- package/dist/core/canvas/sessions.d.ts +18 -0
- package/dist/core/canvas/sessions.js +4 -1
- package/dist/core/canvas/types.d.ts +22 -6
- package/dist/core/command-hooks/compose.js +1 -1
- package/dist/core/command-hooks/discovery.d.ts +15 -1
- package/dist/core/command-hooks/discovery.js +1 -1
- package/dist/core/command-hooks/help.d.ts +2 -2
- package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
- package/dist/core/command-hooks/lifecycle-create.js +1 -1
- package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
- package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
- package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
- package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
- package/dist/core/command-hooks/transport/plan.d.ts +3 -0
- package/dist/core/command-hooks/transport/plan.js +1 -0
- package/dist/core/command-plugins/discovery.js +1 -1
- package/dist/core/command.d.ts +6 -2
- package/dist/core/command.js +6 -6
- package/dist/core/config.d.ts +8 -5
- package/dist/core/config.js +1 -1
- package/dist/core/conversation-store/client-worker.d.ts +1 -0
- package/dist/core/conversation-store/client-worker.js +1 -0
- package/dist/core/conversation-store/client.d.ts +2 -0
- package/dist/core/conversation-store/client.js +2 -0
- package/dist/core/conversation-store/file-store.d.ts +37 -0
- package/dist/core/conversation-store/file-store.js +9 -0
- package/dist/core/conversation-store/index.d.ts +50 -0
- package/dist/core/conversation-store/index.js +1 -0
- package/dist/core/conversation-store/listener.d.ts +4 -0
- package/dist/core/conversation-store/listener.js +3 -0
- package/dist/core/conversation-store/patch.d.ts +1 -0
- package/dist/core/conversation-store/patch.js +1 -0
- package/dist/core/directory/join.d.ts +27 -0
- package/dist/core/directory/join.js +1 -0
- package/dist/core/disk-usage.d.ts +4 -0
- package/dist/core/disk-usage.js +1 -0
- package/dist/core/events/emit.d.ts +2 -0
- package/dist/core/events/emit.js +3 -1
- package/dist/core/feed/feed.js +4 -4
- package/dist/core/feed/messages.d.ts +3 -0
- package/dist/core/feed/messages.js +6 -6
- package/dist/core/fs-utils.d.ts +2 -0
- package/dist/core/fs-utils.js +3 -3
- package/dist/core/grants/local.d.ts +4 -0
- package/dist/core/grants/local.js +1 -0
- package/dist/core/grants/mirror.d.ts +44 -0
- package/dist/core/grants/mirror.js +4 -0
- package/dist/core/grants/on-sync.d.ts +22 -0
- package/dist/core/grants/on-sync.js +1 -0
- package/dist/core/grants/remove.d.ts +7 -0
- package/dist/core/grants/remove.js +1 -0
- package/dist/core/grants/sandboxes.d.ts +7 -0
- package/dist/core/grants/sandboxes.js +1 -0
- package/dist/core/grants/sync.d.ts +12 -0
- package/dist/core/grants/sync.js +1 -0
- package/dist/core/help/memory-extensions.d.ts +3 -0
- package/dist/core/help/memory-extensions.js +2 -0
- package/dist/core/help.d.ts +14 -0
- package/dist/core/help.js +7 -7
- package/dist/core/host-exports/builtins.js +3 -3
- package/dist/core/host-exports/export.js +3 -3
- package/dist/core/human/action-binding.d.ts +2 -0
- package/dist/core/human/action-binding.js +1 -1
- package/dist/core/human/feedback-companion.d.ts +0 -1
- package/dist/core/human/feedback-companion.js +1 -1
- package/dist/core/human/page-schema.d.ts +1 -1
- package/dist/core/inspector/core.d.ts +2 -0
- package/dist/core/inspector/core.js +1 -1
- package/dist/core/inspector/tui.js +2 -2
- package/dist/core/installed-plugins.js +1 -1
- package/dist/core/io.js +6 -6
- package/dist/core/keybindings/catalog.d.ts +1 -1
- package/dist/core/keybindings/catalog.js +1 -1
- package/dist/core/layout-migrate/index.d.ts +15 -0
- package/dist/core/layout-migrate/index.js +4 -0
- package/dist/core/layout-migrate/paths.d.ts +26 -0
- package/dist/core/layout-migrate/paths.js +1 -0
- package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
- package/dist/core/layout-migrate/stored-paths.js +11 -0
- package/dist/core/layout-migrate/stores.d.ts +17 -0
- package/dist/core/layout-migrate/stores.js +4 -0
- package/dist/core/layout.d.ts +26 -0
- package/dist/core/layout.js +2 -0
- package/dist/core/llm/run.d.ts +60 -0
- package/dist/core/llm/run.js +4 -0
- package/dist/core/memory/cli-selector.d.ts +13 -0
- package/dist/core/memory/cli-selector.js +1 -0
- package/dist/core/memory/history.d.ts +5 -4
- package/dist/core/memory/history.js +6 -6
- package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
- package/dist/core/memory/inline-ref-inventory.js +1 -1
- package/dist/core/memory/lint.js +2 -2
- package/dist/core/memory/mutation-domain.d.ts +2 -2
- package/dist/core/memory/mutation-domain.js +8 -7
- package/dist/core/memory/mutations.js +1 -1
- package/dist/core/memory/service.d.ts +5 -0
- package/dist/core/memory/service.js +2 -2
- package/dist/core/memory-resolver.d.ts +11 -7
- package/dist/core/memory-resolver.js +2 -2
- package/dist/core/model-auth/daemon-login.d.ts +13 -0
- package/dist/core/model-auth/daemon-login.js +1 -0
- package/dist/core/model-auth/flows.d.ts +45 -0
- package/dist/core/model-auth/flows.js +1 -0
- package/dist/core/model-auth/handoff-jti.d.ts +4 -0
- package/dist/core/model-auth/handoff-jti.js +1 -0
- package/dist/core/model-routes.js +1 -1
- package/dist/core/nested-stores.d.ts +2 -1
- package/dist/core/nested-stores.js +1 -2
- package/dist/core/preview-registry.js +2 -2
- package/dist/core/profiles/env-store.js +2 -2
- package/dist/core/profiles/manifest.d.ts +16 -5
- package/dist/core/profiles/manifest.js +1 -1
- package/dist/core/provider-management.js +1 -1
- package/dist/core/review/birth.js +1 -1
- package/dist/core/review/companion.d.ts +0 -2
- package/dist/core/review/companion.js +1 -1
- package/dist/core/review/fork.js +2 -2
- package/dist/core/review/realize.js +1 -1
- package/dist/core/review/stage.d.ts +1 -1
- package/dist/core/review/stage.js +1 -1
- package/dist/core/review/types.d.ts +1 -1
- package/dist/core/runs/events.d.ts +34 -0
- package/dist/core/runs/events.js +1 -0
- package/dist/core/runs/operations.d.ts +43 -0
- package/dist/core/runs/operations.js +12 -0
- package/dist/core/runtime/bearings-render.d.ts +2 -2
- package/dist/core/runtime/bearings-render.js +11 -11
- package/dist/core/runtime/bearings.js +2 -2
- package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
- package/dist/core/runtime/broker/cli-relay.js +1 -0
- package/dist/core/runtime/broker/client-registry.d.ts +0 -5
- package/dist/core/runtime/broker/client-registry.js +1 -1
- package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
- package/dist/core/runtime/broker/engine-drive.js +1 -1
- package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
- package/dist/core/runtime/broker/frame-dispatch.js +1 -1
- package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
- package/dist/core/runtime/broker/frame-engine-control.js +1 -1
- package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
- package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
- package/dist/core/runtime/broker/frame-read.js +1 -1
- package/dist/core/runtime/broker/frame-session.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/inbox.d.ts +1 -2
- package/dist/core/runtime/broker/inbox.js +7 -10
- package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
- package/dist/core/runtime/broker/model-adapter.js +2 -0
- package/dist/core/runtime/broker/node-token.d.ts +3 -0
- package/dist/core/runtime/broker/node-token.js +1 -0
- package/dist/core/runtime/broker/read-ops.js +1 -1
- package/dist/core/runtime/broker/rebind.d.ts +2 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/tool-groups.js +1 -1
- package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
- package/dist/core/runtime/broker/turn-ignition.js +1 -1
- package/dist/core/runtime/broker-cli.js +3 -3
- package/dist/core/runtime/broker-extension-render.d.ts +2 -5
- package/dist/core/runtime/broker-extension-render.js +4 -4
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker-protocol.d.ts +7 -8
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/canvas-extensions.d.ts +1 -0
- package/dist/core/runtime/canvas-extensions.js +1 -1
- package/dist/core/runtime/close.d.ts +9 -0
- package/dist/core/runtime/close.js +1 -1
- package/dist/core/runtime/deliver-live.js +1 -1
- package/dist/core/runtime/fleet.d.ts +1 -1
- package/dist/core/runtime/front-door-login.js +1 -1
- package/dist/core/runtime/front-door.js +2 -2
- package/dist/core/runtime/headless-pi.d.ts +1 -1
- package/dist/core/runtime/headless-pi.js +1 -1
- package/dist/core/runtime/host.d.ts +1 -1
- package/dist/core/runtime/host.js +3 -1
- package/dist/core/runtime/invocation.d.ts +3 -0
- package/dist/core/runtime/kickoff.d.ts +1 -0
- package/dist/core/runtime/kickoff.js +16 -16
- package/dist/core/runtime/launch-target.d.ts +1 -1
- package/dist/core/runtime/launch-target.js +1 -1
- package/dist/core/runtime/launch.d.ts +10 -35
- package/dist/core/runtime/launch.js +1 -1
- package/dist/core/runtime/lifecycle.js +2 -2
- package/dist/core/runtime/memory.d.ts +1 -1
- package/dist/core/runtime/memory.js +1 -1
- package/dist/core/runtime/model-registry.js +1 -1
- package/dist/core/runtime/model-swap.d.ts +17 -19
- package/dist/core/runtime/model-swap.js +1 -1
- package/dist/core/runtime/node-read.js +3 -2
- package/dist/core/runtime/nodes.d.ts +7 -0
- package/dist/core/runtime/nodes.js +1 -1
- package/dist/core/runtime/outcome-document.js +1 -1
- package/dist/core/runtime/package-health.js +2 -2
- package/dist/core/runtime/persona.js +2 -2
- package/dist/core/runtime/pi-vendored.js +1 -1
- package/dist/core/runtime/placement-tmux.d.ts +1 -1
- package/dist/core/runtime/placement-tmux.js +1 -1
- package/dist/core/runtime/placement.js +1 -1
- package/dist/core/runtime/promote.js +1 -1
- package/dist/core/runtime/provider-credential-gate.js +2 -2
- package/dist/core/runtime/recovery-hold.d.ts +2 -0
- package/dist/core/runtime/recovery-hold.js +1 -0
- package/dist/core/runtime/recycle.js +1 -1
- package/dist/core/runtime/reopen.js +1 -1
- package/dist/core/runtime/reset.js +1 -1
- package/dist/core/runtime/revive.d.ts +1 -1
- package/dist/core/runtime/revive.js +2 -3
- package/dist/core/runtime/roadmap.js +4 -4
- package/dist/core/runtime/run-command.d.ts +6 -0
- package/dist/core/runtime/run-command.js +1 -1
- package/dist/core/runtime/session-branch.d.ts +2 -8
- package/dist/core/runtime/session-branch.js +1 -1
- package/dist/core/runtime/session-list-cache.d.ts +6 -22
- package/dist/core/runtime/session-list-cache.js +1 -1
- package/dist/core/runtime/situational-context.js +2 -2
- package/dist/core/runtime/spawn-env.d.ts +6 -6
- package/dist/core/runtime/spawn-env.js +1 -1
- package/dist/core/runtime/spawn.d.ts +5 -0
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/core/runtime/stop-guard.js +2 -2
- package/dist/core/runtime/stop-signals.d.ts +2 -2
- package/dist/core/runtime/stop-signals.js +1 -1
- package/dist/core/runtime/structured-output.d.ts +10 -4
- package/dist/core/runtime/structured-output.js +4 -4
- package/dist/core/runtime/tmux-bindings.js +3 -3
- package/dist/core/runtime/tmux-driver.d.ts +4 -0
- package/dist/core/runtime/tmux-driver.js +7 -7
- package/dist/core/runtime/view-socket.d.ts +9 -2
- package/dist/core/runtime/view-socket.js +1 -1
- package/dist/core/runtime/warm-pool.js +1 -1
- package/dist/core/scope.d.ts +3 -2
- package/dist/core/scope.js +1 -1
- package/dist/core/scoped-state/db.js +1 -1
- package/dist/core/scoped-state/migrate.js +3 -3
- package/dist/core/scoped-state/profiles.d.ts +2 -1
- package/dist/core/scoped-state/profiles.js +1 -1
- package/dist/core/scoped-state/schema.d.ts +2 -1
- package/dist/core/scoped-state/schema.js +4 -4
- package/dist/core/scopes.d.ts +2 -2
- package/dist/core/scopes.js +1 -1
- package/dist/core/secrets.d.ts +1 -0
- package/dist/core/secrets.js +2 -2
- package/dist/core/spaces/mounts.d.ts +32 -0
- package/dist/core/spaces/mounts.js +1 -0
- package/dist/core/spaces/open-beneath.d.ts +71 -0
- package/dist/core/spaces/open-beneath.js +1 -0
- package/dist/core/spaces/permissions.d.ts +46 -0
- package/dist/core/spaces/permissions.js +1 -0
- package/dist/core/spaces/process.d.ts +27 -0
- package/dist/core/spaces/process.js +1 -0
- package/dist/core/spaces/space.d.ts +8 -0
- package/dist/core/spaces/space.js +2 -0
- package/dist/core/spaces/stop.d.ts +8 -0
- package/dist/core/spaces/stop.js +2 -0
- package/dist/core/spaces/users.d.ts +19 -0
- package/dist/core/spaces/users.js +1 -0
- package/dist/core/subscription-state.d.ts +2 -0
- package/dist/core/subscription-state.js +3 -3
- package/dist/core/substrate/frontmatter-validation.js +1 -1
- package/dist/core/substrate/injected-store.d.ts +28 -3
- package/dist/core/substrate/injected-store.js +2 -1
- package/dist/core/substrate/listings.js +1 -1
- package/dist/core/substrate/memory-events.d.ts +6 -0
- package/dist/core/substrate/memory-events.js +1 -0
- package/dist/core/substrate/on-read-node.js +1 -1
- package/dist/core/substrate/on-read.d.ts +6 -6
- package/dist/core/substrate/on-read.js +5 -5
- package/dist/core/substrate/plan.js +1 -1
- package/dist/core/substrate/render-node.js +1 -1
- package/dist/core/substrate/render.d.ts +4 -3
- package/dist/core/substrate/render.js +38 -38
- package/dist/core/substrate/schema.d.ts +6 -0
- package/dist/core/substrate/schema.js +1 -1
- package/dist/core/tui/panel.js +1 -1
- package/dist/core/user-settings.d.ts +12 -0
- package/dist/core/user-settings.js +1 -1
- package/dist/core/worktree-mutation-async.js +5 -5
- package/dist/core/worktree-quarantine.js +1 -1
- package/dist/core/worktree-remove.d.ts +15 -0
- package/dist/core/worktree-remove.js +1 -0
- package/dist/core/worktree-sweep.js +6 -6
- package/dist/daemon/analytics/compute.d.ts +37 -0
- package/dist/daemon/analytics/compute.js +1 -0
- package/dist/daemon/analytics/scan-worker.d.ts +1 -0
- package/dist/daemon/analytics/scan-worker.js +2 -0
- package/dist/daemon/analytics/scan.d.ts +37 -0
- package/dist/daemon/analytics/scan.js +1 -0
- package/dist/daemon/api/app-listener.d.ts +11 -0
- package/dist/daemon/api/app-listener.js +21 -0
- package/dist/daemon/api/bridge.js +5 -5
- package/dist/daemon/api/handlers/analytics.d.ts +2 -0
- package/dist/daemon/api/handlers/analytics.js +1 -0
- package/dist/daemon/api/handlers/attach.js +1 -1
- package/dist/daemon/api/handlers/bash-jobs.js +2 -2
- package/dist/daemon/api/handlers/bash.js +1 -1
- package/dist/daemon/api/handlers/broker-ops.js +1 -1
- package/dist/daemon/api/handlers/canvas.d.ts +1 -1
- package/dist/daemon/api/handlers/canvas.js +6 -6
- package/dist/daemon/api/handlers/crons.js +1 -1
- package/dist/daemon/api/handlers/files.d.ts +1 -1
- package/dist/daemon/api/handlers/files.js +1 -1
- package/dist/daemon/api/handlers/health.js +2 -2
- package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
- package/dist/daemon/api/handlers/hook-exec.js +1 -0
- package/dist/daemon/api/handlers/human-requests.js +1 -1
- package/dist/daemon/api/handlers/inbox.js +1 -1
- package/dist/daemon/api/handlers/llm.d.ts +2 -0
- package/dist/daemon/api/handlers/llm.js +3 -0
- package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
- package/dist/daemon/api/handlers/memory-reads.js +1 -0
- package/dist/daemon/api/handlers/memory.js +5 -1
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/modelauth.js +1 -1
- package/dist/daemon/api/handlers/node-outcomes.js +1 -1
- package/dist/daemon/api/handlers/node-records.d.ts +2 -0
- package/dist/daemon/api/handlers/node-records.js +3 -0
- package/dist/daemon/api/handlers/nodes.d.ts +1 -1
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/profiles.d.ts +4 -1
- package/dist/daemon/api/handlers/profiles.js +1 -1
- package/dist/daemon/api/handlers/reports.js +5 -3
- package/dist/daemon/api/handlers/reviews.d.ts +1 -1
- package/dist/daemon/api/handlers/reviews.js +1 -1
- package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
- package/dist/daemon/api/handlers/run-routes.js +1 -0
- package/dist/daemon/api/handlers/runs.d.ts +9 -0
- package/dist/daemon/api/handlers/runs.js +1 -0
- package/dist/daemon/api/handlers/subscriptions.js +1 -1
- package/dist/daemon/api/handlers/worktree.js +1 -1
- package/dist/daemon/api/map.d.ts +10 -4
- package/dist/daemon/api/map.js +2 -2
- package/dist/daemon/api/operations.d.ts +18 -0
- package/dist/daemon/api/operations.js +1 -0
- package/dist/daemon/api/principal.d.ts +42 -0
- package/dist/daemon/api/principal.js +1 -0
- package/dist/daemon/api/router.d.ts +27 -3
- package/dist/daemon/api/router.js +1 -1
- package/dist/daemon/api/server.d.ts +4 -0
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/api/vendor-signin.d.ts +7 -0
- package/dist/daemon/api/vendor-signin.js +77 -0
- package/dist/daemon/api/viewer-presence.d.ts +3 -0
- package/dist/daemon/api/viewer-presence.js +1 -0
- package/dist/daemon/cron/armed-context.d.ts +4 -0
- package/dist/daemon/cron/armed-context.js +1 -1
- package/dist/daemon/cron/escalation.js +3 -3
- package/dist/daemon/cron/lease-recovery.js +1 -1
- package/dist/daemon/cron/sinks.js +2 -2
- package/dist/daemon/cron-run.d.ts +5 -5
- package/dist/daemon/cron-run.js +1 -1
- package/dist/daemon/crtrd.js +8 -7
- package/dist/daemon/delivery/run-delivery.d.ts +4 -0
- package/dist/daemon/delivery/run-delivery.js +1 -1
- package/dist/daemon/fleet.d.ts +1 -1
- package/dist/daemon/fleet.js +6 -6
- package/dist/daemon/human/finish.js +7 -7
- package/dist/daemon/joined-owner.d.ts +5 -0
- package/dist/daemon/joined-owner.js +1 -0
- package/dist/daemon/manage.js +2 -2
- package/dist/daemon/messaging/node-message.js +1 -1
- package/dist/daemon/park-activity.js +1 -1
- package/dist/daemon/reconcilers/bash-deadline.js +1 -1
- package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/reconcilers/delivery-lane.js +1 -1
- package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
- package/dist/daemon/reconcilers/live-obligation.js +1 -1
- package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
- package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
- package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
- package/dist/daemon/runs/append-section.d.ts +6 -0
- package/dist/daemon/runs/append-section.js +2 -0
- package/dist/daemon/runs/observer.d.ts +5 -0
- package/dist/daemon/runs/observer.js +4 -0
- package/dist/launcher/bwrap.d.ts +4 -0
- package/dist/launcher/bwrap.js +2 -0
- package/dist/launcher/client.d.ts +2 -0
- package/dist/launcher/client.js +3 -0
- package/dist/launcher/main.d.ts +1 -0
- package/dist/launcher/main.js +3 -0
- package/dist/launcher/netrule.d.ts +1 -0
- package/dist/launcher/netrule.js +1 -0
- package/dist/launcher/seccomp.d.ts +1 -0
- package/dist/launcher/seccomp.js +1 -0
- package/dist/launcher/spec.d.ts +88 -0
- package/dist/launcher/spec.js +1 -0
- package/dist/launcher/users.d.ts +18 -0
- package/dist/launcher/users.js +7 -0
- package/dist/launcher/validate.d.ts +22 -0
- package/dist/launcher/validate.js +1 -0
- package/dist/migrations/corpus.js +3 -3
- package/dist/migrations/runner.js +1 -1
- package/dist/native/linux/addon.node +0 -0
- package/dist/native/linux.d.ts +29 -0
- package/dist/native/linux.js +1 -0
- package/dist/pi-extensions/broker-local.js +2 -2
- package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
- package/dist/pi-extensions/canvas-bash-valve.js +4 -7
- package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
- package/dist/pi-extensions/canvas-context-intro.js +2 -2
- package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
- package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
- package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
- package/dist/pi-extensions/canvas-passive-context.js +11 -11
- package/dist/pi-extensions/canvas-recap.js +6 -6
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/dist/pi-extensions/canvas-structured-output.js +4 -4
- package/dist/pi-extensions/canvas-tool-guide.js +1 -1
- package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
- package/dist/pi-extensions/system-prompt-entry.js +1 -0
- package/dist/shared/env.d.ts +5 -1
- package/dist/shared/env.js +1 -1
- package/dist/shared/strip-cd-prefix.d.ts +1 -0
- package/dist/shared/strip-cd-prefix.js +1 -0
- package/dist/types.d.ts +31 -15
- package/docs/cli/memory-and-preferences.md +3 -1
- package/docs/sdk/client.md +34 -0
- package/docs/sdk/errors.md +2 -0
- package/docs/sdk/memory.md +2 -2
- package/docs/sdk/streaming.md +21 -0
- package/package.json +18 -4
- package/packages/crouter-identity/dist/index.d.ts +54 -0
- package/packages/crouter-identity/dist/index.js +166 -0
- package/packages/crouter-identity/package.json +33 -0
- package/runtime.lock.json +34 -8
- package/scripts/build-native-linux.mjs +16 -0
- package/scripts/install-runtime.mjs +9 -7
- package/scripts/lib/isolation-env.mjs +42 -0
- package/scripts/runtime-smoke.mjs +49 -0
- package/src/native/linux/addon.c +249 -0
- package/dist/core/profiles/state-block.d.ts +0 -4
- package/dist/core/profiles/state-block.js +0 -3
- package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
- package/dist/core/runtime/broker/auth-reload.js +0 -1
- package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
- package/dist/core/substrate/cli-context-delivery.js +0 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type ThinkingLevel } from '@earendil-works/pi-ai/compat';
|
|
2
|
+
type WireContent = string | null | Array<{
|
|
3
|
+
type: 'text';
|
|
4
|
+
text: string;
|
|
5
|
+
} | {
|
|
6
|
+
type: 'image_url';
|
|
7
|
+
image_url: {
|
|
8
|
+
url: string;
|
|
9
|
+
};
|
|
10
|
+
}>;
|
|
11
|
+
export interface LlmRequest {
|
|
12
|
+
messages: Array<{
|
|
13
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
14
|
+
content: WireContent;
|
|
15
|
+
tool_call_id?: string;
|
|
16
|
+
tool_calls?: Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
function: {
|
|
19
|
+
name: string;
|
|
20
|
+
arguments: string;
|
|
21
|
+
};
|
|
22
|
+
}>;
|
|
23
|
+
}>;
|
|
24
|
+
model?: string;
|
|
25
|
+
model_policy?: 'exact' | 'substitute';
|
|
26
|
+
stream?: boolean;
|
|
27
|
+
tools?: Array<{
|
|
28
|
+
type: 'function';
|
|
29
|
+
function: {
|
|
30
|
+
name: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
parameters?: Record<string, unknown>;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
tool_choice?: 'auto' | 'none' | 'required' | {
|
|
36
|
+
type: 'function';
|
|
37
|
+
function: {
|
|
38
|
+
name: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
reasoning_effort?: ThinkingLevel;
|
|
42
|
+
temperature?: number;
|
|
43
|
+
top_p?: number;
|
|
44
|
+
max_tokens?: number;
|
|
45
|
+
metadata?: unknown;
|
|
46
|
+
payer?: 'user' | 'app';
|
|
47
|
+
response_format?: unknown;
|
|
48
|
+
stop?: string | string[];
|
|
49
|
+
seed?: number;
|
|
50
|
+
}
|
|
51
|
+
export declare function parseLlmRequest(raw: unknown): LlmRequest;
|
|
52
|
+
export interface LlmResult {
|
|
53
|
+
completion: Record<string, unknown>;
|
|
54
|
+
chunks: Array<Record<string, unknown>>;
|
|
55
|
+
}
|
|
56
|
+
export declare function runLlm(input: LlmRequest, signal?: AbortSignal, onChunk?: (chunk: Record<string, unknown>) => void, target?: {
|
|
57
|
+
cwd: string;
|
|
58
|
+
profileId: string | null;
|
|
59
|
+
}): Promise<LlmResult>;
|
|
60
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var V=Object.defineProperty;var p=(e,t)=>V(e,"name",{value:t,configurable:!0});import{randomUUID as X}from"node:crypto";import{streamSimple as ee}from"@earendil-works/pi-ai/compat";import{expandModelCandidates as J,parseModelSpec as te,probeRouteAvailability as oe}from"../model-routes.js";import{readMergedLaunchConfig as K}from"../config.js";import{openModelRegistry as ne}from"../runtime/model-registry.js";import{isManagedProvider as $,markSubscriptionRateLimited as re,markSubscriptionSuccess as se,readSubscriptionPool as ie,retryAfterMsFromHeaders as H,retryAfterMsFromError as ae,refreshSubscriptionCredential as le}from"../subscription-state.js";import{RunError as a}from"../runs/operations.js";import{recognizeProviderError as W}from"../provider-error-recognition.js";function ce(e){return typeof e=="string"||e===null||Array.isArray(e)&&e.every(t=>t&&typeof t=="object"&&(t.type==="text"&&typeof t.text=="string"||t.type==="image_url"&&typeof t.image_url?.url=="string"&&/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(t.image_url.url)))}p(ce,"validContent");function z(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,o,r]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:o,data:r}}):e??""}p(z,"imageContent");function ve(e){if(!e||typeof e!="object"||Array.isArray(e))throw new a(400,"invalid_request","body must be an object");const t=e;if(!Array.isArray(t.messages)||!t.messages.every(o=>o&&typeof o=="object"&&["system","user","assistant","tool"].includes(o.role)&&ce(o.content)))throw new a(400,"invalid_request","messages must be chat messages","messages");if(t.messages.some(o=>["system","assistant"].includes(o.role)&&typeof o.content!="string"&&o.content!==null))throw new a(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new a(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new a(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new a(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new a(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new a(400,"invalid_request","stream must be boolean","stream");if(t.tools!==void 0&&(!Array.isArray(t.tools)||!t.tools.every(o=>o?.type==="function"&&typeof o.function?.name=="string"&&o.function.name.length>0&&(o.function.description===void 0||typeof o.function.description=="string")&&(o.function.parameters===void 0||o.function.parameters!==null&&typeof o.function.parameters=="object"&&!Array.isArray(o.function.parameters)&&o.function.parameters.type==="object"))))throw new a(400,"invalid_request","invalid tools","tools");if(t.tool_choice!==void 0&&t.tool_choice!=="auto"&&t.tool_choice!=="none"&&t.tool_choice!=="required"&&(typeof t.tool_choice!="object"||t.tool_choice===null||t.tool_choice.type!=="function"||typeof t.tool_choice.function?.name!="string"))throw new a(400,"invalid_request","invalid tool_choice","tool_choice");if(t.messages.some(o=>o.role==="assistant"&&o.tool_calls!==void 0&&(!Array.isArray(o.tool_calls)||!o.tool_calls.every(r=>r&&typeof r.id=="string"&&typeof r.function?.name=="string"&&typeof r.function.arguments=="string"&&de(r.function.arguments)))))throw new a(400,"invalid_request","invalid assistant tool_calls","messages");if(t.stop!==void 0&&!(typeof t.stop=="string"||Array.isArray(t.stop)&&t.stop.every(o=>typeof o=="string")))throw new a(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new a(400,"invalid_request","invalid seed","seed");for(const[o,r]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||o==="temperature"&&(r<0||r>2)||o==="top_p"&&(r<0||r>1)||o==="max_tokens"&&(!Number.isSafeInteger(r)||r<1)))throw new a(400,"invalid_request",`invalid ${o}`,o);if(t.response_format!==void 0){const o=t.response_format;if(!o||typeof o!="object"||Array.isArray(o)||!["text","json_object","json_schema"].includes(o.type)||o.type==="json_schema"&&(typeof o.json_schema?.name!="string"||!o.json_schema.name||!o.json_schema.schema||typeof o.json_schema.schema!="object"||Array.isArray(o.json_schema.schema)))throw new a(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new a(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}p(ve,"parseLlmRequest");function de(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}p(de,"isJsonObject");function fe(e,t){const o=Date.now(),r=e.messages.map(s=>s.role==="system"?{role:"system",content:s.content??"",timestamp:o}:s.role==="tool"?{role:"toolResult",toolCallId:s.tool_call_id??"",toolName:"",content:typeof s.content=="string"||s.content===null?[{type:"text",text:s.content??""}]:z(s.content),isError:!1,timestamp:o}:s.role==="assistant"?{role:"assistant",content:[...s.content?[{type:"text",text:s.content}]:[],...(s.tool_calls??[]).map(m=>({type:"toolCall",id:m.id,name:m.function.name,arguments:JSON.parse(m.function.arguments)}))],api:"openai-completions",provider:"openai",model:e.model??"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:o}:{role:"user",content:z(s.content),timestamp:o});if(t){const s=r.filter(c=>c.role==="system").map(c=>c.content).join(`
|
|
2
|
+
`).slice(0,16384),m=r.findIndex(c=>c.role==="user");if(s&&m>=0){const c=r[m];r[m]={...c,content:typeof c.content=="string"?`${s}
|
|
3
|
+
|
|
4
|
+
${c.content}`:[{type:"text",text:s},...c.content]}}s&&m<0&&r.unshift({role:"user",content:s,timestamp:o});for(let c=r.length-1;c>=0;c--)r[c]?.role==="system"&&r.splice(c,1)}const y=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{messages:r,...y?{tools:y}:{}}}p(fe,"contextOf");function Y(e,t,o,r){if(!e){const s=K(o,r),m=Object.values({...s.modelRoutes??{},...s.legacyModelRoutes??{}}),c=m.length?[s.modelLadders.defaultProvider,...s.modelRouting?.familyOrder??[],...m.map(b=>b.family)].find(b=>m.some(g=>g.family===b)):s.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:c,strength:"strong",spec:`${c}/strong`}}const y=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return y?{kind:"logical",family:y[1],strength:y[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}p(Y,"requestFor");async function xe(e,t,o,r){if(e.payer==="app")throw new a(403,"payer_not_app","app-paid inference routes are not registered");const y=await ne(),s=Y(e.model,e.model_policy,r?.cwd,r?.profileId),m=p(f=>f.routeId!=="concrete"&&f.routeId!=="exact","configured"),c=p(f=>{const u=y.find(f.providerId,f.modelId);return u!==void 0&&(!e.reasoning_effort||u.reasoning)&&(e.seed===void 0&&e.response_format===void 0||u.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(u.api))},"matchesFeatures"),b=J(s.kind==="exact"?{kind:"concrete",spec:s.spec}:s,r?.cwd,r?.profileId).filter(m);let g;if(s.kind==="logical")g=e.model_policy==="exact"?b.filter(f=>f.family===s.family&&f.strength===s.strength).slice(0,1):b;else{const f=te(s.spec),u=b.filter(d=>d.providerId===f?.providerId&&d.modelId===f.modelId&&(e.model_policy!=="exact"||d.thinkingLevel===f.thinkingLevel)&&c(d));if(e.model_policy==="exact")g=u.slice(0,1);else if(u.length)g=u;else{const d=K(r?.cwd,r?.profileId),k=[...Object.values(d.modelRoutes??{}).flatMap(i=>Object.entries(i.models)),...[d.modelLadders.anthropic,d.modelLadders.openai].flatMap(i=>Object.entries(i))].find(([,i])=>i===s.spec)?.[0],R=Y(void 0,"substitute",r?.cwd,r?.profileId);g=k&&R.kind==="logical"?J({...R,strength:k,spec:s.spec},r?.cwd,r?.profileId).filter(i=>m(i)&&i.strength===k):[]}}if(g=g.filter(c),g.length===0)throw new a(e.model_policy==="exact"?400:404,e.model_policy==="exact"?"substitution_refused":"model_unavailable","no eligible model route is configured");const E=`chatcmpl-${X()}`;let j=1/0;for(const f of g){if(!oe(f,y).authenticated)continue;const u=y.find(f.providerId,f.modelId);if(!u)continue;const d=f.providerId,I=$(d)?ie(d).filter(i=>!i.authFailure):[],k=I.filter(i=>i.rateLimitedUntil<=Date.now());if(I.length&&!k.length){j=Math.min(j,...I.map(i=>i.rateLimitedUntil));continue}const R=I.length?k:[void 0];for(const i of R){const M=Date.now();let D=i?.access;if(i&&i.expires<=Date.now()&&$(d)){const n=y.getProvider(d)?.auth.oauth;if(!n)throw new a(503,"model_unavailable",`no OAuth refresh for ${d}`);D=(await le(d,i.label,_=>n.refresh({type:"oauth",refresh:_,access:"",expires:0},t??new AbortController().signal))).access}const Z=fe(e,!!i),A=i?void 0:await y.getApiKeyAndHeaders(u);if(A&&!A.ok)continue;const w=`${u.provider}/${u.id}`,q=e.model??w;let v=!1,F,x=3e4;const U=[],T=[],S=[];let l;const C=p((n,h=null)=>({id:E,object:"chat.completion.chunk",created:Math.floor(M/1e3),model:w,served_model:w,requested_model:q,substituted:q!==w&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(q),choices:[{index:0,delta:n,finish_reason:h}]}),"chunk"),L=p(n=>{U.push(n),o?.(n)},"emit"),G=ee(u,Z,{apiKey:D??(A?.ok?A.apiKey:void 0),...A?.ok?{headers:A.headers}:{},signal:t,reasoning:e.reasoning_effort??f.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:p(n=>{if(!n||typeof n!="object")return;const h=e.tool_choice,_=h==="required"?u.api==="anthropic-messages"?{type:"any"}:"required":typeof h=="object"&&h!==null?u.api==="anthropic-messages"?{type:"tool",name:h.function.name}:h:void 0;return{...n,..._?{tool_choice:_}:{},...e.stop!==void 0?{[u.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:p(async(n,h)=>{const _=await fetch(n,h);return F=_.status,_.status===429&&(v=!0,x=H(_.headers)??15e3),_},"fetch"),onResponse:p(n=>{n.status===429&&(v=!0,x=H(n.headers)??15e3)},"onResponse")});try{for await(const n of G)n.type==="text_delta"&&(T.push(n.delta),L(C({content:n.delta}))),n.type==="thinking_delta"&&(S.push(n.delta),L(C({reasoning_content:n.delta}))),n.type==="done"&&(l=n.message),n.type==="error"&&(l=n.error)}catch(n){const h=ae(n),_=W({status:n&&typeof n=="object"&&"status"in n?n.status:void 0,message:n instanceof Error?n.message:String(n)});if(!v&&_.kind!=="rate-limit")throw n;v=!0,x=h??x}if(!v&&l?.stopReason==="error"&&W({message:l.errorMessage}).kind==="rate-limit"&&(v=!0,x=15e3),v){if(i&&$(d)&&await re(d,i.label,x,M),j=Math.min(j,Date.now()+x),T.length||S.length)throw new a(503,"server_error","vendor rate limit after output began");continue}const O=l?.rawStopReason!==void 0&&["refusal","sensitive","content_filter","incomplete.content_filter","content_filtered","guardrail_intervened","SAFETY","PROHIBITED_CONTENT","BLOCKLIST","SPII","RECITATION"].includes(l.rawStopReason);if(F===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(l?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(l?.errorMessage??""))throw new a(400,"invalid_request",l.errorMessage,"tool_choice");if(!l||l.stopReason==="error"&&!O||l.stopReason==="aborted")throw new a(503,"model_unavailable",l?.errorMessage??"model request failed");i&&$(d)&&await se(d,i.label,M);const N=l.content.filter(n=>n.type==="toolCall").map(n=>({id:n.id,type:"function",function:{name:n.name,arguments:JSON.stringify(n.arguments)}})),P=O?"content_filter":l.stopReason==="toolUse"?"tool_calls":l.stopReason==="length"?"length":"stop",B={prompt_tokens:l.usage.input,completion_tokens:l.usage.output,total_tokens:l.usage.totalTokens,cache_read_tokens:l.usage.cacheRead,cache_write_tokens:l.usage.cacheWrite,usd_equivalent:null,served_model:w},Q={id:E,object:"chat.completion",created:Math.floor(M/1e3),model:w,served_model:w,requested_model:q,substituted:q!==w&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(q),choices:[{index:0,message:{role:"assistant",content:T.join("")||null,...S.length?{reasoning_content:S.join("")}:{},...N.length?{tool_calls:N}:{},...O?{refusal:l.errorMessage??"Content filtered"}:{}},finish_reason:P}],usage:B,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[n,h]of N.entries())L(C({tool_calls:[{index:n,...h}]}));return L({...C({},P),...O?{choices:[{index:0,delta:{},finish_reason:P,message:{refusal:l.errorMessage??"Content filtered"}}]}:{},usage:B}),{completion:Q,chunks:U}}}throw j!==1/0?new a(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((j-Date.now())/1e3))},void 0,!0):e.model_policy==="exact"?new a(400,"substitution_refused","the requested model is unavailable"):new a(404,"model_unavailable","no usable model route is available")}p(xe,"runLlm");export{ve as parseLlmRequest,xe as runLlm};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MemoryScope, type MemoryStoreDescriptor } from '../memory-resolver.js';
|
|
2
|
+
interface MemorySelectorInput {
|
|
3
|
+
scope?: string | undefined;
|
|
4
|
+
dir?: string | undefined;
|
|
5
|
+
profile?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
/** Legacy sys guidance migration needs this local selector; memory leaves resolve in the daemon. */
|
|
8
|
+
export declare function resolveWriteSelector(input: MemorySelectorInput): {
|
|
9
|
+
scope: MemoryScope;
|
|
10
|
+
memoryDir: string;
|
|
11
|
+
store: MemoryStoreDescriptor;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var y=Object.defineProperty;var c=(e,o)=>y(e,"name",{value:o,configurable:!0});import{existsSync as u,realpathSync as h,statSync as D}from"node:fs";import{dirname as d,join as l,resolve as j}from"node:path";import{envNodeId as v,envProfileId as w}from"../../shared/env.js";import{usage as t}from"../errors.js";import{pathExists as x}from"../fs-utils.js";import{openProjectMemoryStore as m}from"../memory-resolver.js";import{NEUTRAL_PROJECT_MEMORY as R,scopeMemoryDir as S,projectScopeRoot as M,ensureProjectScopeRoot as P,resetScopeCache as $}from"../scope.js";import{loadProfileManifest as I,resolveProfileOperand as E,profileMemoryDir as _}from"../profiles/manifest.js";import{memoryDir as C}from"../runtime/memory.js";import{CRTR_DIR_NAME as N}from"../../types.js";function O(e){if(e.scope!==void 0&&e.scope!=="")throw t(`--dir selects the project store itself and cannot combine with --scope ${e.scope}`,{received:`--dir ${e.dir} --scope ${e.scope}`,next:"Drop --scope: --dir already pins the exact project store."});if(e.profile!==void 0&&e.profile!=="")throw t("--profile only applies to --scope profile; --dir selects a project store",{received:e.profile,next:"Drop --profile when using --dir."})}c(O,"rejectDirConflicts");function b(e){const o=j(e);if(!u(o)||!D(o).isDirectory())throw t(`--dir does not exist or is not a directory: ${e}`,{received:e,next:"Pass an existing project directory."});try{return h(o)}catch{return o}}c(b,"ownerDirFromArg");function q(e,o){if(!(e===void 0||e==="")){if(!o.includes(e))throw t(`invalid --scope: ${e} (expected ${o.join("|")})`);return e}}c(q,"parseScope");function f(e,o){return{scope:e,storeRoot:o,namespace:"",mountStatus:x(o)?"ready":"absent",projectMemory:R}}c(f,"nativeStoreDescriptor");function G(e){if(e.dir!==void 0&&e.dir!==""){O(e);const i=b(e.dir);return $(),{scope:"project",memoryDir:l(i,N,"memory"),store:m(i)}}const r=q(e.scope,["user","project","profile","node"])??(M()!==null?"project":"user");if(e.profile!==void 0&&e.profile!==""&&r!=="profile")throw t(`--profile only applies to --scope profile (resolved scope: ${r})`,{received:e.profile,next:"Drop --profile, or pass --scope profile to target a specific profile store."});if(r==="node"){const i=v()||"";if(i==="")throw t("node scope requires a running node (CRTR_NODE_ID unset); rerun inside a node");const n=C(i);return{scope:r,memoryDir:n,store:f(r,n)}}if(r==="profile"){const i=e.profile!==void 0&&e.profile!=="",n=i?e.profile:w()||"";if(n==="")throw t("profile scope requires a selected profile; rerun inside a profiled node or pass --profile");const{profileId:a}=i?E(n):I(n),p=_(a);return{scope:r,memoryDir:p,store:f(r,p)}}let s=S(r);if(!s&&r==="project"&&(s=l(P(),"memory")),!s)throw t(`no ${r} scope available for writing memory documents`);return r==="project"?{scope:r,memoryDir:s,store:m(d(d(s)))}:{scope:r,memoryDir:s,store:f(r,s)}}c(G,"resolveWriteSelector");export{G as resolveWriteSelector};
|
|
@@ -68,10 +68,11 @@ export interface DeletedHistoryResolution {
|
|
|
68
68
|
export declare function resolveDeletedHistoryLogPath(storeRoot: string, localName: string): DeletedHistoryResolution | null;
|
|
69
69
|
/** Append one record. Single write of one line — concurrent appends interleave
|
|
70
70
|
* whole records, and every record stands alone, so no lock is needed. */
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
/** Append beneath `root`, the store root the log mirrors. */
|
|
72
|
+
export declare function appendHistoryRecord(root: string, logPath: string, record: HistoryRecord): void;
|
|
73
|
+
/** Every record in a log beneath `root` (the store root it mirrors), oldest
|
|
74
|
+
* first (append order). Revision numbers are 1-based positions in this array. */
|
|
75
|
+
export declare function readHistoryRecords(root: string, logPath: string): HistoryRecord[];
|
|
75
76
|
export interface ChangeSummary {
|
|
76
77
|
body_changed: boolean;
|
|
77
78
|
/** Frontmatter field names whose values differ between the two texts. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var M=Object.defineProperty;var l=(t,
|
|
2
|
-
|
|
3
|
-
`),
|
|
4
|
-
`)}l(
|
|
5
|
-
`),
|
|
6
|
-
`);return
|
|
1
|
+
var M=Object.defineProperty;var l=(t,o)=>M(t,"name",{value:o,configurable:!0});import{readdirSync as j}from"node:fs";import{join as x,relative as _}from"node:path";import{appendFileBeneath as A,readTextBeneathIfExists as T}from"../spaces/open-beneath.js";import{envNodeCwd as H,envNodeId as J}from"../../shared/env.js";import{general as D}from"../errors.js";import{parseFrontmatterGeneric as $}from"../frontmatter.js";import{normalizeNameSegment as N}from"./identity.js";const F=".history";function R(t,o){const e=_(t,o);if(e===""||e.startsWith(".."))throw D(`memory document ${o} is not inside its store root ${t}`);return x(t,F,e.replace(/\.md$/i,"")+".jsonl")}l(R,"historyLogPathFor");function Z(t){const o=J(),e=t.actor??{cwd:H()??process.cwd(),...o===void 0?{}:{node:o}};return{op:t.op,at:new Date().toISOString(),...e.node!==void 0?{node:e.node}:{},cwd:e.cwd,...t.from!==void 0?{from:t.from}:{},...t.rationale!==void 0?{rationale:t.rationale}:{},...t.verbatim===!0?{verbatim:!0}:{},before:t.before,after:t.after}}l(Z,"buildHistoryRecord");function tt(t){return R(t.root,t.path)}l(tt,"historyLogPathForDoc");function W(t,o){let e;try{e=j(t,{withFileTypes:!0})}catch{return[]}return e.filter(n=>n.isDirectory()&&N(n.name)===o).sort((n,i)=>n.name===o?-1:i.name===o?1:n.name.localeCompare(i.name)).map(n=>x(t,n.name))}l(W,"matchingDirs");function P(t,o){let e;try{e=j(t,{withFileTypes:!0})}catch{return[]}return e.filter(n=>n.isFile()&&n.name.endsWith(".jsonl")&&N(n.name.slice(0,-6))===o).sort((n,i)=>n.name===`${o}.jsonl`?-1:i.name===`${o}.jsonl`?1:n.name.localeCompare(i.name)).map(n=>x(t,n.name))}l(P,"matchingFiles");function I(t,o,e){let n=[t];for(const i of o)if(n=n.flatMap(a=>W(a,i)),n.length===0)return[];return n.flatMap(i=>P(i,e))}l(I,"historyFilesForSegments");function et(t,o){const e=o.split("/").filter(s=>s!=="").map(N),n=x(t,F),i=I(n,e,"INDEX"),a=e.length===0?[]:I(n,e.slice(0,-1),e[e.length-1]),r=[...i.map(s=>({path:s,representation:"directory-index",winner:!1})),...a.map(s=>({path:s,representation:"leaf-file",winner:!1}))];return r.length===0?null:(r[0].winner=!0,{logPath:r[0].path,candidates:r,...r.length>1?{collision:{paths:r.map(s=>s.path),winner:r[0].path}}:{}})}l(et,"resolveDeletedHistoryLogPath");function nt(t,o,e){A(t,o,JSON.stringify(e)+`
|
|
2
|
+
`)}l(nt,"appendHistoryRecord");function ot(t,o){const e=T(t,o);if(e===null)return[];const n=e.split(`
|
|
3
|
+
`),i=[];for(let a=0;a<n.length;a+=1){const r=n[a];if(r.trim()!=="")try{i.push(JSON.parse(r))}catch{throw D(`corrupt history record at ${o}:${a+1} \u2014 the line is not valid JSON`,{next:"Inspect that line directly; the surrounding records are self-contained and still readable."})}}return i}l(ot,"readHistoryRecords");function rt(t,o){const e=$(t),n=$(o),i=e.data??{},a=n.data??{},r=new Set([...Object.keys(i),...Object.keys(a)]);r.delete("last-updated");const s=[...r].filter(c=>JSON.stringify(i[c])!==JSON.stringify(a[c])).sort((c,f)=>c.localeCompare(f));return{body_changed:e.body!==n.body,frontmatter_changed:s}}l(rt,"summarizeChange");function it(t,o,e=3){const{lines:n,terminated:i}=L(t),{lines:a,terminated:r}=L(o),s=k(E(n,i),E(a,r)),c=[];for(let d=0;d<s.length;d+=1){if(s[d].tag===" ")continue;const p=Math.max(0,d-e),g=Math.min(s.length,d+e+1),u=c[c.length-1];u!==void 0&&p<=u.to?u.to=Math.max(u.to,g):c.push({from:p,to:g})}if(c.length===0)return"";const f=[],w=[];let b=0,O=0;for(const d of s)f.push(b),w.push(O),d.tag!=="+"&&(b+=1),d.tag!=="-"&&(O+=1);const y=[];for(const{from:d,to:p}of c){const g=s.slice(d,p),u=g.filter(h=>h.tag!=="+").length,S=g.filter(h=>h.tag!=="-").length;y.push(`@@ -${u===0?0:f[d]+1},${u} +${S===0?0:w[d]+1},${S} @@`);for(let h=d;h<p;h+=1){const m=s[h];y.push(m.tag+(m.tag==="+"?a[m.index]:n[m.index]));const v=m.tag!=="+"&&!i&&f[h]===n.length-1,C=m.tag!=="-"&&!r&&w[h]===a.length-1;(v||C)&&y.push(B)}}return y.join(`
|
|
4
|
+
`)}l(it,"unifiedDiff");const B="\",K="\0no-newline-at-eof";function E(t,o){return o||t.length===0?t:t.map((e,n)=>n===t.length-1?e+K:e)}l(E,"diffKeys");function L(t){if(t==="")return{lines:[],terminated:!0};const o=t.endsWith(`
|
|
5
|
+
`),e=t.split(`
|
|
6
|
+
`);return o&&e.pop(),{lines:e,terminated:o}}l(L,"toLines");function k(t,o){const e=t.length,n=o.length,i=Array.from({length:e+1},()=>new Array(n+1).fill(0));for(let c=e-1;c>=0;c-=1)for(let f=n-1;f>=0;f-=1)i[c][f]=t[c]===o[f]?i[c+1][f+1]+1:Math.max(i[c+1][f],i[c][f+1]);const a=[];let r=0,s=0;for(;r<e&&s<n;)t[r]===o[s]?(a.push({tag:" ",index:r}),r+=1,s+=1):i[r+1][s]>=i[r][s+1]?(a.push({tag:"-",index:r}),r+=1):(a.push({tag:"+",index:s}),s+=1);for(;r<e;r+=1)a.push({tag:"-",index:r});for(;s<n;s+=1)a.push({tag:"+",index:s});return a}l(k,"diffOps");export{F as HISTORY_DIR,nt as appendHistoryRecord,Z as buildHistoryRecord,R as historyLogPathFor,tt as historyLogPathForDoc,ot as readHistoryRecords,et as resolveDeletedHistoryLogPath,rt as summarizeChange,it as unifiedDiff};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { type MemoryTarget } from '../memory-resolver.js';
|
|
1
2
|
import type { RefMeta } from '../runtime/broker-protocol.js';
|
|
2
3
|
/** Build the inline inventory from exact target-view winners. `refs` carries
|
|
3
4
|
* metadata rows; `names` adds only canonical directory nodes with members for
|
|
4
5
|
* browse links. Gates, rungs, and `slash` do not affect referenceability. */
|
|
5
|
-
export declare function buildRefInventory(): {
|
|
6
|
+
export declare function buildRefInventory(target?: MemoryTarget): {
|
|
6
7
|
refs: RefMeta[];
|
|
7
8
|
names: Set<string>;
|
|
8
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var c=(n,i)=>d(n,"name",{value:i,configurable:!0});import{ambientMemoryTarget as u,loadMemoryTargetView as h}from"../memory-resolver.js";import{buildMemoryTree as y}from"./tree.js";import{memoryExtensionEffectiveCatalog as D,projectEffectiveMemoryExtensions as b}from"./extensions.js";import{parseSubstrateDoc as g}from"../substrate/schema.js";const f={node:0,project:1,profile:2,user:3,builtin:4};function x(n=u()){const i=h(n,{quiet:!0}),s=new Map;for(const e of i.candidateSets()){const o=e.winner,t=g(o);t!==null&&s.set(e.name,{doc:t,memoryDoc:o})}const r=[];for(const[e,{doc:o,memoryDoc:t}]of s){const p=o.scope!=="builtin"&&b(t.frontmatter?.extensions,D(t)).northlight?.visibility!==!1;r.push({name:e,kind:o.kind,scope:o.scope,shortForm:o.shortForm,gatewayVisible:p})}r.sort((e,o)=>{const t=f[e.scope]-f[o.scope];return t!==0?t:e.name.localeCompare(o.name)});const m=new Set(r.map(e=>e.name)),l=y([...s.values()].map(({memoryDoc:e})=>e)),a=c(e=>{e.name!==""&&(e.childDirectories.length>0||e.childDocuments.length>0)&&m.add(e.name);for(const o of e.childDirectories)a(o)},"addDirectoryNames");return a(l.root),{refs:r,names:m}}c(x,"buildRefInventory");export{x as buildRefInventory};
|
package/dist/core/memory/lint.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var J=Object.defineProperty;var w=(e,t)=>J(e,"name",{value:t,configurable:!0});import{envNodeId as Q,envProfileId as Z}from"../../shared/env.js";import{basename as ee,join as L,matchesGlob as te,relative as W,sep as A}from"node:path";import{pathExists as oe,
|
|
2
|
-
`)[0]}`),"yaml-error"}if($e.has(ee(
|
|
1
|
+
var J=Object.defineProperty;var w=(e,t)=>J(e,"name",{value:t,configurable:!0});import{envNodeId as Q,envProfileId as Z}from"../../shared/env.js";import{basename as ee,join as L,matchesGlob as te,relative as W,sep as A}from"node:path";import{pathExists as oe,realpathOrSelf as D}from"../fs-utils.js";import{readFileBeneath as ne,walkFilesBeneath as re}from"../spaces/open-beneath.js";import{parseFrontmatterGeneric as se}from"../frontmatter.js";import{descendantStoreRoots as ie}from"../nested-stores.js";import{projectScopeRoots as ae}from"../scope.js";import{associateRepository as x}from"./repository-association.js";import{loadProfileManifest as ce}from"../profiles/manifest.js";import{loadMemoryTargetView as de,loadStoreMemoryDocs as F,openProjectMemoryStore as B}from"../memory-resolver.js";import{buildMemoryTree as N}from"./tree.js";import{canonicalSegments as E,collapseTrailingIndex as q,INDEX_SEGMENT as $,localNameFromPath as C,normalizeDocName as G,validateExplicitLocalName as le}from"./identity.js";import{lintSubstrateFrontmatter as me,parsedSubstrateSurfaces as j}from"../substrate/frontmatter-validation.js";import{memoryExtensionValidationCatalog as fe,validateMemoryExtensionValues as ue}from"./extensions.js";import{docLinkNames as z}from"./doc-link-grammar.js";const Ce=new Set(["store-namespace","namespace-placement","owner-path-collision","root-name","root-index-unaddressable","local-name","canonical-collision","dangling-link","memory-read-route"]);function M(e,t,r,s){const i=e.filter(a=>a.severity==="error");return{ok:i.length===0,checked:t,documents:r,storesLinted:s,findings:e,errors:i,warnings:e.filter(a=>a.severity==="warning"),notices:e.filter(a=>a.severity==="notice")}}w(M,"makeResult");const P=1e3,V=1e3,O=3e3,he=30,T="Keep the load-bearing core here and split the depth into [[linked]] reference docs carrying no surfaces at all (the listing and the link are how they are found, so they cost nothing until followed). Split by subject: each leaf covers a different subject a task might need on its own; never split off \u201Cfurther evidence\u201D, examples, or references \u2014 a references leaf is never followed, so supporting material stays next to the point it supports or gets cut. Keep it whole \u2014 `lint-ignore: length` in the frontmatter \u2014 only when every reader who surfaces this doc genuinely benefits from reading 100% of it, or it is one indivisible body of knowledge; then splitting just adds hops.";function _(e,t){const r=e["lint-ignore"];return r===t||Array.isArray(r)&&r.includes(t)}w(_,"ignoresRule");function X(e){const t=e.trim();return t===""?0:t.split(/\s+/).length}w(X,"countBodyWords");function pe(e,t,r){if(_(e,"length")||r==="kinds"||r.startsWith("kinds/"))return null;const s=j(e),i=X(t);if(s.some(c=>c.on==="boot"&&c.at==="content")&&i>P)return`body is ${i} words but a boot entry at \`content\` inlines every word into every agent's system prompt \u2014 capped at ${P} words (boot preview gets ${O}; name entries are never capped). ${T}`;const a=[...new Set(s.filter(c=>c.on!=="boot"&&c.at==="content").map(c=>c.on))];return a.length>0&&i>V?`body is ${i} words, over the ${V}-word cap for a \`content\` entry on ${a.join("/")} (the whole body delivers every time the entry fires; name entries are never capped). ${T}`:s.some(c=>c.on==="boot"&&c.at==="preview")&&i>O?`body is ${i} words, over the ${O}-word cap for boot preview (the routing line invites every reader into the whole body, so the cap is the longest doc worth reading end-to-end; boot content is capped at ${P} words; name entries are never capped). ${T}`:null}w(pe,"lintBodyLength");function ye(e,t){const r=X(t);if(r>=he)return null;const s=[...new Set(j(e).filter(a=>a.at==="preview").map(a=>a.on))];if(s.length===0)return null;const i=s.length===1?"entry delivers":"entries deliver";return`body is ${r} words but the ${s.join("/")} ${i} \`preview\`; use \`at: content\` so agents receive the whole rule without a separate memory read`}w(ye,"lintShortPreviewBody");function we(e){const t=new Set,r=w(s=>{s.name!==""&&t.add(s.name);for(const i of s.childDirectories)r(i);for(const i of s.childDocuments)t.add(i.name)},"walk");return r(N(e).root),t}w(we,"resolvableCanonicalNames");function ge(e,t={}){const r=N(e),s=new Map,i=w(o=>{o.name!==""&&s.set(o.name,o);for(const d of o.childDirectories)i(d);for(const d of o.childDocuments)s.set(d.name,d)},"indexWalk");i(r.root);const a=new Set,c=[],u=w(o=>{o===""||a.has(o)||!s.has(o)||(a.add(o),c.push(o))},"enqueue");for(const o of e){const d=o.frontmatter??{};(j(d).length>0||d.slash===!0)&&u(o.name)}for(;c.length>0;){const o=s.get(c.shift()),d=o.document;if(d!==null)for(const p of z(d.body))s.has(p)&&u(p);if(!(d===null||d.localName==="")){for(const p of o.childDirectories)p.document?.frontmatter?.unlisted!==!0&&u(p.name);for(const p of o.childDocuments)p.document.frontmatter?.unlisted!==!0&&u(p.name)}}const h=[];for(const o of e)t.flagStoreRoot!==void 0&&o.store.storeRoot!==t.flagStoreRoot||a.has(o.name)||o.scope==="builtin"||o.plugin!==void 0||o.localName!==""&&(o.name==="kinds"||o.name.startsWith("kinds/")||_(o.frontmatter??{},"orphan")||h.push({severity:"warning",rule:"orphan",path:o.path,name:o.name,scope:o.scope,...o.store.storeRoot===""?{}:{storeRoot:o.store.storeRoot},message:`\`${o.name}\` is unreachable: no surface delivers it, no reached document links it, and no reached directory lists it \u2014 it is findable only by deliberate search. Give it a surface, link it from a reached doc (a cluster index, or its directory's own ${$}.md), or accept it with \`lint-ignore: orphan\`.`}));return h}w(ge,"lintOrphans");const Y='the store\'s root INDEX.md is the workspace front door: give it `surfaces: [{on: workspace-open, at: content}, {on: read, match: "./**", at: content}]` (run `crtr memory write -h` first)',ve=/[*?[\]{}]/;function K(e,t){try{return te(e,t)}catch{return!1}}w(K,"safeGlob");function Re(e,t){const r=e.startsWith("./")?e.slice(2):e,s=e.startsWith("./")?`${t}/${r}`:r;return E(G(s)).join("/")}w(Re,"literalRouteTarget");function be(e,t,r){if(!e.startsWith("./")){for(const a of r)if(K(a,e))return!0;return!1}const s=e.slice(2),i=t===""?"":`${t}/`;for(const a of r)if(a.startsWith(i)&&K(a.slice(i.length),s))return!0;return!1}w(be,"routeMatchesAny");function U(e){const t=E(e),r=t[t.length-1]===$,s=q(e),i=E(s).pop()??e;return`${r?` A directory's own document answers at the directory name, so name \`${s}\` instead.`:""} Run \`crtr memory find ${i}\` for the canonical name, or drop the reference.`}w(U,"missingNameDiagnostic");const $e=new Set(["SKILL.md","MEMORY.md"]);function I(e,t={}){const r=[],s={scope:e.scope,...e.storeRoot===""?{}:{storeRoot:e.storeRoot}},i=w((l,y,n,m,f={})=>{r.push({severity:l,rule:y,path:n,message:m,...s,...f})},"add"),a=e.mountStatus==="ready";e.mountFailure==="collision"?i("error","owner-path-collision",e.namespacePath??e.storeRoot,e.diagnostic??`project memory stores have owner directories that normalize to the same effective prefix \`${e.namespace}\` \u2014 rename one owner directory`):(e.mountStatus==="undeclared"||e.mountStatus==="invalid")&&i("error","store-namespace",e.namespacePath??e.storeRoot,e.diagnostic??"project memory store does not mount"),(e.mountStatus==="undeclared"||e.mountStatus==="invalid")&&t.resolvable!==void 0&&i("notice","reference-check-deferred",e.storeRoot,"links and `memory-read` routes are not checked here: the canonical identities they resolve against are undetermined until this store declares its namespace");const c=e.scope==="project"&&e.plugin===void 0,u=t.frontDoor??"ignore",h=[],o=F(e,!0).filter(l=>!l.physicalRelativePath.split("/").some(y=>y.startsWith("."))),d=new Map(o.map(l=>[l.path,l]));let p=0,v=0;const R=e.mountFailure==="symlink"?[]:re(e.storeRoot,e.storeRoot,l=>l.endsWith(".md"),l=>l.startsWith("."));for(const l of R){const y=W(e.storeRoot,l).split(A).join("/");y!==""&&(p+=1,H({store:e,file:l,relPath:y,doc:d.get(l),isProjectStore:c,mounted:a,...t.resolvable===void 0?{}:{resolvable:t.resolvable},nestedStore:t.nestedStore===!0,add:i,frontDoors:h})==="document"&&(v+=1))}const g=new Map;for(const l of o){const y=g.get(l.name);y?y.push(l):g.set(l.name,[l])}for(const[l,y]of g){if(y.length<2)continue;const n=y.map(m=>m.path);i("error","canonical-collision",n[0],`${y.length} files in this store own canonical name \`${l}\` (${n.join(", ")}); \`${y[0].physicalRelativePath}\` is the deterministic read winner. Recover the collision with \`crtr memory move ${l} --to <new-free-name>\`; move selects the first physical path in stable lexical order, and no filesystem surgery is needed.`,{name:l,paths:n})}if(c){for(const n of h)n.root||i("error","front-door",n.path,`a project store's workspace front door is its root ${$}.md, not this doc \u2014 a {on: workspace-open, at: content} entry here delivers a second whole document at every workspace open; fold it into the root document or lower this entry`);const l=(e.ownerRelativePath??"")==="",y=h.some(n=>n.root&&n.complete);if(l&&!y&&u!=="ignore"){const n=e.ownerDir??e.storeRoot,m=u==="required"?`the selected profile manages this project but its store has no workspace front door \u2014 ${Y}`:`this project store has no workspace front door, so agents open the workspace blind \u2014 ${Y}`;i(u==="required"?"error":"warning","front-door",n,m)}}return M(r,p,v,1)}w(I,"lintMemoryStore");function H(e){const{store:t,file:r,relPath:s,doc:i,isProjectStore:a,mounted:c,resolvable:u,add:h}=e;let o,d;try{({data:o,body:d}=se(ne(t.storeRoot,r).toString("utf8")))}catch(g){return h("error","yaml",r,`invalid YAML frontmatter: ${(g instanceof Error?g.message:String(g)).split(`
|
|
2
|
+
`)[0]}`),"yaml-error"}if($e.has(ee(r)))return"non-document";const p=C(s)==="",v=i===void 0?{}:{name:i.name},R=me(o);if(R!==null&&h("error","schema",r,R,v),o!==null){const g=a&&t.ownerRelativePath==="";if(o.namespace!==void 0&&!(p&&g)){const l=p&&a&&t.ownerRelativePath!==void 0&&t.ownerRelativePath!==""?`\`namespace:\` belongs only on the repository-root store's ${$}.md (${t.namespacePath??t.storeRoot}) \u2014 a nested store's prefix is derived from its path under ${t.repositoryRoot??t.ownerDir??t.storeRoot}`:`\`namespace:\` belongs only on a project store's root ${$}.md, where it declares the whole store's prefix \u2014 drop it here (an explicit \`name:\` is store-LOCAL and never carries a namespace)`;h("error","namespace-placement",r,l,v)}p&&o.name!==void 0&&h("error","root-name",r,`a store's root ${$}.md carries no \`name:\` \u2014 its identity answers at \`${t.namespace}\`; drop the field`,v)}if(i===void 0)return p&&!a&&h("error","root-index-unaddressable",r,`a root ${$}.md has no canonical name in a ${t.scope} store, which declares no namespace \u2014 only a project store's root document answers at its namespace, so rename this file to a named document (\`<topic>.md\`) or fold its content into the docs it introduces`),"document";if(o!==null){if(!p&&o.name!==void 0){const n=o.name;if(typeof n!="string"||n.trim()==="")h("error","local-name",r,`invalid name: ${JSON.stringify(n)} (expected a non-empty store-local name)`,v);else{const m=le(n.trim(),t.namespace);if(!m.ok){const f=Se(G(n.trim()),t.namespace,s);h("error","local-name",r,`invalid name \`${n}\`: ${m.reason} \u2014 ${f}`,v)}}}for(const n of ue(o.extensions,fe(i)))h("error","extension",r,`${n.path}: ${n.message}`,v);const g=pe(o,d,i.name);g!==null&&h("error","length",r,g,v);const l=ye(o,d);l!==null&&h("warning","short-preview",r,l,v);const y=j(o);if(e.nestedStore&&y.some(n=>n.on==="boot")&&h("warning","nested-store-boot",r,"nested-store docs never ride the boot catalog, so its boot surfaces entries are inert \u2014 drop them",v),a&&y.some(n=>n.on==="workspace-open"&&n.at==="content")){const n=y.some(m=>m.on!=="read"||m.at!=="content"?!1:m.match?.includes("./**")===!0);e.frontDoors.push({path:r,root:p,complete:n})}for(const n of y)n.on==="memory-read"&&ke(n,i,o,u,c,h)}if(u!==void 0&&c)for(const g of z(d))u.has(g)||h("error","dangling-link",r,`dangling doc link [[${g}]]: no memory document or directory in this target view has that exact canonical name.${U(g)}`,v);return"document"}w(H,"lintDocumentFile");function Ge(e,t,r={}){const s=[],i={scope:e.scope,...e.storeRoot===""?{}:{storeRoot:e.storeRoot}},a=w((d,p,v,R,g={})=>{s.push({severity:d,rule:p,path:v,message:R,...i,...g})},"add"),c=W(e.storeRoot,t).split(A).join("/"),u=F(e,!0).find(d=>d.path===t),h=[],o=H({store:e,file:t,relPath:c,doc:u,isProjectStore:e.scope==="project"&&e.plugin===void 0,mounted:e.mountStatus==="ready",...r.resolvable===void 0?{}:{resolvable:r.resolvable},nestedStore:r.nestedStore===!0,add:a,frontDoors:h});for(const d of h)d.root||a("error","front-door",d.path,`a project store's workspace front door is its root ${$}.md, not this doc \u2014 a {on: workspace-open, at: content} entry here delivers a second whole document at every workspace open; fold it into the root document or lower this entry`);return M(s,1,o==="document"?1:0,1)}w(Ge,"lintMemoryDocument");function Se(e,t,r){let s=q(e);if(t!==""){const i=E(t),a=E(s);i.every((c,u)=>a[u]===c)&&(s=a.slice(i.length).join("/"))}return s===""?`remove the field: this document's identity would be the store root's, which only the root ${$}.md owns`:s===C(r)?`drop the field \u2014 its physical path already derives \`${s}\``:`use \`name: ${s}\``}w(Se,"suggestedLocalName");function ke(e,t,r,s,i,a){for(const c of e.match??[]){if((c==="**"||c==="*")&&!_(r,"broad-memory-read")){a("warning","broad-memory-read",t.path,`memory-read glob \`${c}\` fires on every memory read \u2014 scope it to a name subtree`,{name:t.name});continue}if(!(s===void 0||!i)){if(!ve.test(c)){const u=Re(c,t.routingAnchor);s.has(u)||a("error","memory-read-route",t.path,`memory-read route \`${c}\` names \`${u}\`, which is no document or directory in this target view, so the entry can never fire.${U(u)}`,{name:t.name});continue}be(c,t.routingAnchor,s)||a("warning","memory-read-route",t.path,`memory-read glob \`${c}\`${c.startsWith("./")?` (anchored at \`${t.routingAnchor}\`)`:""} matches no canonical name in this target view \u2014 a project document's name carries its store's namespace, so an unqualified subtree glob no longer matches`,{name:t.name})}}}w(ke,"lintMemoryReadEntry");function De(){return{cwd:process.cwd(),profileId:Z()||null,nodeId:Q()||null}}w(De,"ambientTarget");function ze(e={}){const t=e.target??De(),r=e.includeDescendants??!0,s=de(t,{...e.scope===void 0?{}:{scope:e.scope},includeDescendants:r,quiet:!0}),i=we(s.docs),a=new Set(r?ie(ae(t.cwd,t.profileId)).map(n=>D(L(n,"memory"))):[]),c=e.scope===void 0||e.scope==="project",u=new Set,h=new Set;if(c&&t.profileId!==null&&t.profileId!=="")try{const{manifest:n}=ce(t.profileId);for(const m of n.projects){const f=D(m.path);u.add(f);const S=x(f);h.add(S.ok?S.association.repositoryRoot:f)}}catch{}const o=D(t.cwd),d=[];let p=0,v=0,R=0;const g=new Set;for(const n of s.stores){const m=n.ownerDir===void 0?null:D(n.ownerDir),f=n.repositoryRoot??m;f!=null&&g.add(f);const k=n.ownerRelativePath!==void 0&&n.ownerRelativePath!==""||!c||m===null?"ignore":h.has(f??m)?"required":u.size===0&&m===o?"advisory":"ignore",b=I(n,{resolvable:i,frontDoor:k,nestedStore:a.has(D(n.storeRoot))});d.push(...b.findings),p+=b.checked,v+=b.documents,R+=b.storesLinted}if(c){for(const f of u){const S=x(f),k=S.ok?S.association.repositoryRoot:f;if(g.has(k))continue;const b=I(B(k),{resolvable:i,frontDoor:"required"});d.push(...b.findings),p+=b.checked,v+=b.documents,R+=b.storesLinted,g.add(k)}const n=x(o),m=n.ok?n.association.repositoryRoot:o;if(u.size===0&&!g.has(m)&&oe(L(t.cwd,".crouter"))){const f=I(B(t.cwd),{resolvable:i,frontDoor:"advisory"});d.push(...f.findings),p+=f.checked,v+=f.documents,R+=f.storesLinted}}const l=N(s.docs),y=w(n=>{const m=n.documentCandidates;m.length>1&&new Set(m.map(f=>f.root)).size>1&&d.push({severity:"notice",rule:"cross-store-candidates",path:m[0].path,name:n.name,paths:m.map(f=>f.path),message:`canonical name \`${n.name}\` is held by ${m.length} stores; this target view reads ${m[0].path} (${m[0].scope}) and the later candidates stay reachable with \`crtr memory read ${n.name} --dir <project>\``});for(const f of n.childDirectories)y(f);for(const f of n.childDocuments)y(f)},"walk");return y(l.root),e.scope===void 0&&d.push(...ge(s.docs)),{...M(d,p,v,R),stores:s.stores,profileProjects:u.size}}w(ze,"lintMemoryTarget");export{Ce as MEMORY_LINT_IDENTITY_RULES,pe as lintBodyLength,Ge as lintMemoryDocument,I as lintMemoryStore,ze as lintMemoryTarget,ge as lintOrphans,ye as lintShortPreviewBody,we as resolvableCanonicalNames};
|
|
@@ -56,8 +56,8 @@ export declare function selectMutationDoc(set: MemoryCandidateSet): MutationDocS
|
|
|
56
56
|
* PHYSICAL store-relative path (`doc.physicalRelativePath.split('/').length`),
|
|
57
57
|
* never the canonical name, which carries the store's namespace on top of it —
|
|
58
58
|
* the same count addresses a `.history/<path>.jsonl` sidecar. Stops at the
|
|
59
|
-
* first non-empty ancestor. */
|
|
60
|
-
export declare function pruneEmptyParents(filePath: string, pathSegments: number): void;
|
|
59
|
+
* first non-empty ancestor. Every directory resolves beneath `root`, the store root. */
|
|
60
|
+
export declare function pruneEmptyParents(root: string, filePath: string, pathSegments: number): void;
|
|
61
61
|
/** Map a STORE-LOCAL name (`topic`, `area/topic`, `INDEX`) to its file path
|
|
62
62
|
* under a memory dir, guarding against traversal/absolute escapes. Physical
|
|
63
63
|
* mapping only: it composes no namespace and collapses no `INDEX`, so a
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
var O=Object.defineProperty;var f=(e,
|
|
2
|
-
${
|
|
1
|
+
var O=Object.defineProperty;var f=(e,t)=>O(e,"name",{value:t,configurable:!0});import{dirname as y,join as g}from"node:path";import{stringify as $,parse as b}from"yaml";import{usage as s}from"../errors.js";import{existsBeneath as A,readdirBeneath as k,rmdirBeneath as J}from"../spaces/open-beneath.js";import{pathExists as P,realpathOrSelf as x}from"../fs-utils.js";import{loadStoreMemoryDocs as q}from"../memory-resolver.js";import{canonicalSegments as D,physicalRelativePathFor as v,stripNamespace as C,validateExplicitLocalName as L}from"./identity.js";import{memoryExtensionValidationCatalog as F}from"./extensions.js";import{SURFACE_EVENTS as S,SURFACE_RUNGS as w}from"../substrate/schema.js";import{SUPPRESSIBLE_RULES as R}from"../substrate/frontmatter-validation.js";function T(e){if(e.scope!=="project"||e.mountStatus==="ready")return e;const t=e.ownerDir??e.storeRoot;if(e.mountStatus==="absent")throw s(`no memory store at ${e.storeRoot}`,{next:`Initialize it with \`crtr memory write <namespace> --dir ${t}\`, which declares the repository namespace.`});const n=e.repositoryRoot??t;throw s(e.diagnostic??`project memory store at ${e.storeRoot} does not declare a namespace`,{next:`Run \`crtr sys migrate --dir ${n}\`.`})}f(T,"requireMountedStore");function j(e){const t=D(e.trim()).join("/");if(t==="")throw s("memory document name required");const n=L(t);if(!n.ok)throw s(`invalid memory document name \`${e}\`: ${n.reason}`,{received:e,next:"Pass the full canonical name (a project document is <namespace>/<local name>); run `crtr memory find <leaf>` to look one up."});return t}f(j,"requireCanonicalName");function M(e,t){T(e);const n=j(t);if(e.namespace==="")return n;const o=C(n,e.namespace);if(o===null)throw s(`\`${n}\` is not in the namespace of the store at ${e.storeRoot} (\`${e.namespace}\`)`,{memory:n,next:`Every document there answers at \`${e.namespace}/<local name>\`; the store's own document answers at \`${e.namespace}\`.`});return o}f(M,"requireLocalNameInStore");function te(e,t,n,o){const i=M(e,t),r=j(t),a=n??q(e,!0),l=o===void 0?null:x(o.path),c=a.find(h=>h.name===r&&x(h.path)!==l);if(c!==void 0)throw s(`${r} already exists in ${e.storeRoot}`,{memory:r,path:c.path,next:`Revise it with \`crtr memory edit ${r}\`, which records the change, or move it with \`crtr memory move\`.`});const p=(i===""?["directory-index"]:["directory-index","leaf-file"]).map(h=>g(e.storeRoot,v(i,h))).filter(h=>P(h)&&x(h)!==l);if(p.length>0)throw s(`${r} cannot be created: ${p.join(" and ")} already exists`,{memory:r,path:p.join(", "),next:"Both `<name>.md` and `<name>/INDEX.md` carry that identity. Read the existing file, then edit, move, or delete it."});const u=i===""||a.some(h=>h.localName.startsWith(`${i}/`))?"directory-index":"leaf-file",d=v(i,u);return{store:e,canonicalName:r,localName:i,representation:u,physicalRelativePath:d,path:g(e.storeRoot,d)}}f(te,"planNewDocumentPlacement");function ne(e){const t=e.winner,n=e.candidates.filter(o=>o.store.storeRoot===t.store.storeRoot);if(n.length>1)throw s(`${e.name} is owned by ${n.length} files in one store: ${n.map(o=>o.path).join(" and ")}`,{memory:e.name,path:n.map(o=>o.path).join(", "),next:`Recover the collision with \`crtr memory move ${e.name} --to <new-free-name>\`; it selects the first physical path in stable lexical order. Do not remove files by hand; \`crtr memory lint\` reports every such collision.`});return t}f(ne,"requireUnambiguousDoc");function oe(e){const n=[...e.candidates.filter(o=>o.store.storeRoot===e.winner.store.storeRoot)].sort((o,i)=>{const r=o.physicalRelativePath.localeCompare(i.physicalRelativePath);return r!==0?r:o.path.localeCompare(i.path)});return{doc:n[0]??e.winner,collisionPaths:n.length>1?n.map(o=>o.path):[]}}f(oe,"selectMutationDoc");function re(e,t,n){let o=t;for(let r=0;r<n;r+=1)o=y(o);let i=y(t);for(;i!==o&&i.startsWith(o)&&A(e,i)&&k(e,i).length===0;)J(e,i),i=y(i)}f(re,"pruneEmptyParents");function ie(e,t){const n=t.split("/").filter(o=>o.length>0);if(n.length===0)throw s("memory document name required");if(n.some(o=>o==="."||o===".."))throw s(`invalid memory document name: ${t}`);return g(e,...n)+".md"}f(ie,"memoryFilePath");function U(e){const t=b(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:`expected an object, got ${JSON.stringify(t)}`}f(U,"parseYamlObject");function ae(e){const t=U(e);if(typeof t=="string")throw s(`--gate must be a YAML/JSON object (field\u2192matcher map): ${t}. Example: --gate '{kind: design}' or --gate '{orchestration.depth: {gte: 2}}'`);return t}f(ae,"coerceGate");const _=new Set(["on","match","match-frontmatter","gate","at"]);function se(e){const t=b(e);if(t===null||typeof t!="object"||Array.isArray(t))throw s(`--surface must be a YAML/JSON object entry {on, at, match?, match-frontmatter?, gate?}, got ${JSON.stringify(t)}. Example: --surface '{on: read, match: "src/**", at: content}'`);const n=t;for(const c of Object.keys(n))if(!_.has(c))throw s(`--surface: unknown key \`${c}\` (an entry carries only on, match, match-frontmatter, gate, at)`);const o=n.on;if(typeof o!="string"||!S.includes(o))throw s(`--surface: invalid \`on\`: ${JSON.stringify(o)} (expected ${S.join("|")})`);const i=n.at;if(typeof i!="string"||!w.includes(i))throw s(`--surface: invalid \`at\`: ${JSON.stringify(i)} (expected ${w.join("|")})`);let r;if(n.match!==void 0){if(o==="boot"||o==="workspace-open")throw s(`--surface: \`match\` is meaningless on \`${o}\` \u2014 the entry's presence is the match; drop it`);if(typeof n.match=="string"){const c=n.match.trim();if(c==="")throw s("--surface: `match` must be a non-empty glob or a non-empty glob list");r=c}else if(Array.isArray(n.match)){const c=n.match.map(m=>typeof m=="string"?m.trim():"");if(c.length===0||c.some(m=>m===""))throw s("--surface: `match` must be a non-empty glob or a non-empty glob list");r=c.length===1?c[0]:c}else throw s(`--surface: invalid \`match\`: ${JSON.stringify(n.match)} (expected a glob string or list)`)}const a=n["match-frontmatter"];if(a!==void 0){if(o!=="read")throw s("--surface: `match-frontmatter` is a `read`-event predicate only");if(a===null||typeof a!="object"||Array.isArray(a))throw s(`--surface: invalid \`match-frontmatter\`: ${JSON.stringify(a)} (expected a field\u2192matcher object)`)}if((o==="read"||o==="memory-read"||o==="command"||o==="pre-command")&&r===void 0&&a===void 0)throw s(`--surface: a \`${o}\` entry requires \`match\`${o==="read"?" or `match-frontmatter`":""}`);const l=n.gate;if(l!==void 0&&(l===null||typeof l!="object"||Array.isArray(l)))throw s(`--surface: invalid \`gate\`: ${JSON.stringify(l)} (expected a field\u2192matcher object)`);return{on:o,...r!==void 0?{match:r}:{},...a!==void 0?{"match-frontmatter":a}:{},...l!==void 0?{gate:l}:{},at:i}}f(se,"coerceSurface");const N=["kind","privacy","when-and-why-to-read","short-form","unlisted","surfaces","gate","slash","rationale","lint-ignore","last-updated","origin"];function ce(e,t){const n={};for(const r of N)e[r]!==void 0&&(n[r]=e[r]);for(const r of Object.keys(e))!(r in n)&&e[r]!==void 0&&(n[r]=e[r]);const o=$(n).replace(/\n+$/,""),i=t.replace(/^\n+/,"").replace(/\s+$/,"");return`---
|
|
2
|
+
${o}
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
${i}
|
|
6
|
-
`}f(ce,"serializeMemoryDoc");const
|
|
7
|
-
${$(
|
|
6
|
+
`}f(ce,"serializeMemoryDoc");const B=/^---[ \t]*\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/;function fe(e){const t=e.match(B);return t?e.slice(t[0].length):e}f(fe,"literalBodySegment");function me(e,t){const n={};for(const i of N)e[i]!==void 0&&(n[i]=e[i]);for(const i of Object.keys(e))!(i in n)&&e[i]!==void 0&&(n[i]=e[i]);return`---
|
|
7
|
+
${$(n).replace(/\n+$/,"")}
|
|
8
8
|
---
|
|
9
|
-
${
|
|
10
|
-
- ${n.join(`
|
|
11
|
-
-
|
|
9
|
+
${/^\r?\n/.test(t)?"":`
|
|
10
|
+
`}${t}`}f(me,"serializeMemoryDocLiteral");function le(e){if(e===void 0)return;const t=Array.isArray(e)?e:[e];if(t.length===0||t.some(n=>typeof n!="string"||!R.includes(n)))throw s(`invalid lint-ignore: ${JSON.stringify(e)} (suppressible rules: ${R.map(n=>`\`${n}\``).join(", ")})`);return t.length===1?t[0]:t}f(le,"coerceLintIgnore");function pe(e){return F(e)}f(pe,"memoryExtensionCatalogForDoc");function ue(e){return e.type!=="enum"?e.type:`enum (${e.values.join("|")})`}f(ue,"declarationValueDescription");function de(e){return typeof e=="string"?JSON.stringify(e):String(e)}f(de,"extensionHelpValue");function E(e,t){const n=/^extensions\.([^.]+)\.([^.]+)$/.exec(e);return n===null?`${t} requires the full path extensions.<plugin>.<field>: ${e}`:{path:e,namespace:n[1],field:n[2]}}f(E,"parseExtensionPath");function I(e,t,n){if(n.type==="boolean")return t==="true"?!0:t==="false"?!1:`${e} expects boolean true or false, received ${JSON.stringify(t)}`;if(n.type==="number"){if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/.test(t))return`${e} expects finite numeric syntax, received ${JSON.stringify(t)}`;const o=Number(t);return Number.isFinite(o)?o:`${e} expects a finite number, received ${JSON.stringify(t)}`}return n.type==="enum"&&!n.values.includes(t)?`${e} expects one of ${n.values.join("|")}, received ${JSON.stringify(t)}`:t}f(I,"parseExtensionValue");function he(e,t,n){const o=[],i=[],r=[],a=new Set,l=new Set;for(const c of e??[]){const m=c.indexOf("=");if(m<0){o.push(`--extension requires extensions.<plugin>.<field>=VALUE: ${c}`);continue}const p=E(c.slice(0,m),"--extension");if(typeof p=="string"){o.push(p);continue}if(a.has(p.path)){o.push(`duplicate --extension path: ${p.path}`);continue}a.add(p.path);const u=n[p.namespace]?.[p.field];if(u===void 0){o.push(`${p.path} is not declared by an installed plugin`);continue}const d=I(p.path,c.slice(m+1),u);if(typeof d=="string"&&u.type!=="string"&&u.type!=="enum"){o.push(d);continue}if(typeof d=="string"&&u.type==="enum"&&!u.values.includes(d)){o.push(`${p.path} expects one of ${u.values.join("|")}, received ${JSON.stringify(d)}`);continue}i.push({...p,value:d})}for(const c of t??[]){const m=E(c,"--unset-extension");if(typeof m=="string"){o.push(m);continue}if(l.has(m.path)){o.push(`duplicate --unset-extension path: ${m.path}`);continue}if(l.add(m.path),n[m.namespace]?.[m.field]===void 0){o.push(`${m.path} is not declared by an installed plugin`);continue}r.push(m)}for(const c of a)l.has(c)&&o.push(`${c} was requested in both --extension and --unset-extension`);if(o.length>0)throw s(`invalid plugin memory extension request:
|
|
11
|
+
- ${o.join(`
|
|
12
|
+
- `)}`,{received:[...e??[],...t??[]].join(", "),next:"Run `crtr memory write -h` or `crtr memory edit -h` for the installed field catalog and value syntax."});return{sets:i,unsets:r}}f(he,"parseRequestedExtensionChanges");function ye(e,t,n){if(t.length===0&&n.length===0)return;const o=e.extensions;if(o!==void 0&&(o===null||typeof o!="object"||Array.isArray(o)))throw s("existing extensions frontmatter must be a mapping before extension fields can be changed",{received:JSON.stringify(o),next:"Repair the extensions mapping, or make a core-field-only edit that preserves it unchanged."});const i={...o??{}};for(const r of t){const a=i[r.namespace];if(a!==void 0&&(a===null||typeof a!="object"||Array.isArray(a)))throw s(`existing ${`extensions.${r.namespace}`} frontmatter must be a mapping before ${r.path} can change`,{received:JSON.stringify(a),next:"Repair the namespace mapping, or make a core-field-only edit that preserves it unchanged."});i[r.namespace]={...a??{},[r.field]:r.value}}for(const r of n){const a=i[r.namespace];if(a===void 0)continue;if(a===null||typeof a!="object"||Array.isArray(a))throw s(`existing ${`extensions.${r.namespace}`} frontmatter must be a mapping before ${r.path} can change`,{received:JSON.stringify(a),next:"Repair the namespace mapping, or make a core-field-only edit that preserves it unchanged."});const l={...a};delete l[r.field],Object.keys(l).length===0?delete i[r.namespace]:i[r.namespace]=l}Object.keys(i).length===0?delete e.extensions:e.extensions=i}f(ye,"applyExtensionChanges");export{ye as applyExtensionChanges,ae as coerceGate,le as coerceLintIgnore,se as coerceSurface,fe as literalBodySegment,pe as memoryExtensionCatalogForDoc,ie as memoryFilePath,he as parseRequestedExtensionChanges,te as planNewDocumentPlacement,re as pruneEmptyParents,j as requireCanonicalName,M as requireLocalNameInStore,T as requireMountedStore,ne as requireUnambiguousDoc,oe as selectMutationDoc,ce as serializeMemoryDoc,me as serializeMemoryDocLiteral};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var ye=Object.defineProperty;var R=(s,m)=>ye(s,"name",{value:m,configurable:!0});import{dirname as I,join as Q,resolve as B}from"node:path";import{rmSync as V,appendFileSync as we,renameSync as ge}from"node:fs";import{CrtrError as Y,notFound as _,usage as l}from"../errors.js";import{parseFrontmatterGeneric as be}from"../frontmatter.js";import{ensureDir as Z,pathExists as ee,readText as A,realpathOrSelf as N,walkFiles as $e,writeText as z}from"../fs-utils.js";import{docLinkNames as ve,findDocLinks as te}from"./doc-link-grammar.js";import{lintMemoryDocument as xe,resolvableCanonicalNames as Re}from"./lint.js";import{descendantStoreRoots as ke}from"../nested-stores.js";import{projectScopeRoots as De}from"../scope.js";import{associateRepository as je}from"./repository-association.js";import{parsedSubstrateSurfaces as Se}from"../substrate/frontmatter-validation.js";import{explicitLocalName as Pe}from"./identity.js";import{buildMemoryTree as Ie}from"./tree.js";import{loadMemoryStoreView as W,loadMemoryTargetView as H,openProjectMemoryStore as Ne,resolveMemoryCandidatesForTarget as oe}from"../memory-resolver.js";import{appendHistoryRecord as C,buildHistoryRecord as M,historyLogPathFor as L,readHistoryRecords as Ee}from"./history.js";import{applyExtensionChanges as ne,coerceGate as re,coerceLintIgnore as ae,coerceSurface as se,literalBodySegment as X,memoryExtensionCatalogForDoc as ie,parseRequestedExtensionChanges as ce,planNewDocumentPlacement as me,pruneEmptyParents as G,requireCanonicalName as de,requireLocalNameInStore as le,requireMountedStore as J,requireUnambiguousDoc as Fe,selectMutationDoc as pe,serializeMemoryDoc as Le,serializeMemoryDocLiteral as K}from"./mutation-domain.js";function q(s){return s.history??{cwd:s.target.cwd,...s.target.nodeId===null?{}:{node:s.target.nodeId}}}R(q,"historyActorFor");function Oe(s){return $e(s,m=>m.endsWith(".md")&&m!=="SKILL.md",m=>m===".crouter").length===0}R(Oe,"emptyMemoryStore");function Ae(s){const m=s.some(o=>o.on==="workspace-open"&&o.at==="content"),i=s.some(o=>{if(o.on!=="read"||o.at!=="content")return!1;const n=o.match;return n==="./**"||Array.isArray(n)&&n.includes("./**")});return m&&i}R(Ae,"hasWorkspaceFrontDoor");function et(s){const{target:m,scope:i,memoryDir:o,store:n,origin:$,fields:c}=s,h=c.name,e=c.kind,t=c.body??"";let d=!1;if(i==="project"&&n.mountStatus!=="ready"&&s.isExplicitProjectStore&&Oe(o)){const r=je(N(n.ownerDir??I(I(o))));if(r.ok){if(r.association.ownerRelativePath!=="")throw l(`${n.ownerDir??I(I(o))} is a nested store in the repository rooted at ${r.association.repositoryRoot}; only the repository root declares a namespace`,{next:"crtr memory write <namespace> --dir <repositoryRoot>, or crtr sys migrate --dir <repositoryRoot>"});d=!0}else r.code==="no-project-root"&&(d=!0)}i==="project"&&n.mountStatus!=="ready"&&!d&&J(n);let y,g;if(d)y=de(h),g=Q(o,"INDEX.md");else{const r=me(n,h);y=r.canonicalName,g=r.path}const v=ae(c.lintIgnore),u=ce(c.extension,void 0,ie({scope:i,path:g})),p={};p.kind=e,d&&(p.namespace=y),p.origin=$;const x=R((r,b)=>{b!==void 0&&(p[r]=b)},"setIf");x("when-and-why-to-read",c.whenAndWhyToRead),x("short-form",c.shortForm),c.unlisted===!0&&(p.unlisted=!0),c.surface!==void 0&&(p.surfaces=c.surface.map(se)),c.gate!==void 0&&(p.gate=re(c.gate)),x("lint-ignore",v),c.slash===!0&&(p.slash=!0),x("rationale",c.rationale),ne(p,u.sets,u.unsets),p["last-updated"]=$.created;const k=p.surfaces;if(i!=="project"&&Array.isArray(k)&&k.some(r=>r!==null&&typeof r=="object"&&r.on==="workspace-open"))throw l("a workspace-open surfaces entry is a project-store mount route; user, profile, and node memory cannot carry one \u2014 drop the entry or write to a project store");if(d){const r=Array.isArray(k)?k.filter(b=>b!==null&&typeof b=="object"):[];if(!Ae(r))throw l(`empty project initialization requires the ordinary workspace front door: --surface '{on: workspace-open, at: content}' and --surface '{on: read, match: "./**", at: content}'`,{memory:y,next:`Pass both front-door surfaces when initializing ${y} with --dir.`})}const j=Le(p,t);Z(o),z(g,j);const E=L(o,g);C(E,M({op:"create",actor:q(s),before:"",after:j}));const D=Se(p),S=ve(t).length>0||D.some(r=>r.on==="memory-read"),F=D.some(r=>r.on==="boot"),P=d?Ne(n.ownerDir??I(I(o))):n,a=xe(P,g,{...S?{resolvable:Re(H({cwd:n.ownerDir??m.cwd,profileId:m.profileId,nodeId:m.nodeId},{quiet:!0,includeDescendants:!0}).docs)}:{},...F?{nestedStore:ke(De(m.cwd,m.profileId)).map(r=>N(Q(r,"memory"))).includes(N(o))}:{}});return{name:y,scope:i,path:g,...a.findings.length===0?{}:{findings:a.findings.map(r=>({severity:r.severity,rule:r.rule,message:r.message}))}}}R(et,"createDoc");const Ce=["short-form","gate","surfaces","unlisted","slash","rationale","lint-ignore"],U=["kind","when-and-why-to-read","origin","last-updated"];function ue(s,m,i,o){if(o!==null)return o.candidates(s);try{return oe(s,m,{includeDescendants:!0,...i!==void 0?{scope:i}:{}})}catch(n){if(n instanceof Y&&n.code==="not_found")return null;throw n}}R(ue,"mutationCandidates");function he(s,m,i){const o=X(s),n=s.length-o.length,$=te(o).filter(h=>h.name===m);let c=s;for(let h=$.length-1;h>=0;h-=1){const e=$[h];c=c.slice(0,n+e.start)+`[[${i}]]`+c.slice(n+e.end)}return{text:c,count:$.length}}R(he,"rewriteRefs");function tt(s){const{target:m,selection:i,fields:o}=s,n=o.name,$=o.rationale,c=o.verbatim===!0,h=o.body??"";let e;try{const a=i.store===null||i.store===void 0?oe(n,m,{includeDescendants:!0,...i.scope===void 0?{}:{scope:i.scope}}):(le(i.store,n),W(i.store,!0).candidates(n));if(a===null)throw _(`memory document not found: ${n}`,{memory:n,next:`\`edit\` revises a document that already exists. Create it with \`crtr memory write ${n} ...\`, or run \`crtr memory find <query>\` if it exists under another name.`});e=Fe(a)}catch(a){throw a instanceof Y&&a.code==="not_found"?_(`memory document not found: ${n}`,{memory:n,next:`\`edit\` revises a document that already exists. Create it with \`crtr memory write ${n} ...\`, or run \`crtr memory find <query>\` if it exists under another name.`}):a}if(e.plugin!==void 0)throw l(`${e.name} belongs to the installed plugin "${e.plugin}" \u2014 a read-only corpus managed by \`crtr pkg\`, not editable here. To override just this doc, write a same-named doc at a writable scope (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,plugin:e.plugin});if(e.scope==="builtin")throw l(`${e.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be edited. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,scope:"builtin"});const t=ae(o.lintIgnore),d=ce(o.extension,o.unsetExtension,ie(e)),y=A(e.path),v={...be(y).data??{}},u={...v};if(e.scope==="project"&&e.localName===""){if(e.store.ownerRelativePath!==""&&Object.prototype.hasOwnProperty.call(v,"namespace"))throw l(`a nested store's INDEX.md carries no namespace: \u2014 the repository at ${e.store.repositoryRoot??e.root} declares it`,{memory:e.name,path:e.path,next:`Run \`crtr memory lint --dir ${e.store.ownerDir??e.root}\` or \`crtr sys migrate --dir ${e.store.repositoryRoot??e.root}\`.`});if(e.store.ownerRelativePath===""&&v.namespace!==e.store.repositoryNamespace)throw l(`the repository namespace on ${e.path} is immutable; it must remain \`${e.store.repositoryNamespace}\``,{memory:e.name,path:e.path});if(v.name!==void 0)throw l(`the project root INDEX at ${e.path} cannot carry a \`name:\` field`,{memory:e.name,path:e.path,next:`Run \`crtr sys migrate --dir ${e.store.repositoryRoot??e.store.ownerDir??e.root}\`.`})}const p=R((a,r)=>{r!==void 0&&(u[a]=r)},"setIf");p("kind",o.kind),p("when-and-why-to-read",o.whenAndWhyToRead),p("short-form",o.shortForm),o.unlisted===!0&&(u.unlisted=!0),o.surface!==void 0&&(u.surfaces=o.surface.map(se)),o.gate!==void 0&&(u.gate=re(o.gate)),p("lint-ignore",t),o.slash===!0&&(u.slash=!0),p("rationale",o.docRationale),ne(u,d.sets,d.unsets);for(const a of o.unset??[]){if(U.includes(a))throw l(`--unset ${a}: ${a} is never clearable`,{memory:e.name,next:`Protected fields are ${U.join(", ")}.`});if(!Ce.includes(a)&&!Object.prototype.hasOwnProperty.call(v,a)){const r=Object.keys(v).filter(b=>!U.includes(b));throw l(`--unset ${a}: ${e.name} has no \`${a}\` field to unset`,{memory:e.name,next:r.length>0?`Fields ${e.name} has: ${r.join(", ")}.`:`${e.name} carries no field eligible for --unset.`})}delete u[a]}const x=u.surfaces;if(e.scope!=="project"&&Array.isArray(x)&&x.some(a=>a!==null&&typeof a=="object"&&a.on==="workspace-open"))throw l("a workspace-open surfaces entry is a project-store mount route; user, profile, and node memory cannot carry one \u2014 drop the entry");const k=X(y),j=h===""?k:h;if(K(u,j)===y)throw l(`edit changed nothing \u2014 ${e.name} already says exactly this, so there is nothing to record`,{memory:e.name,next:"Pipe a different body or pass a frontmatter flag that changes a value. To remove the doc entirely, use `crtr memory delete`."});u["last-updated"]=new Date().toISOString();const D=K(u,j);z(e.path,D);const S=L(e.root,e.path);C(S,M({op:"edit",actor:q(s),rationale:$,...c?{verbatim:!0}:{},before:y,after:D}));const F=[...new Set([...Object.keys(v),...Object.keys(u)])].filter(a=>a!=="last-updated").filter(a=>JSON.stringify(v[a])!==JSON.stringify(u[a])).sort((a,r)=>a.localeCompare(r)),P=[...j!==k?["body"]:[],...F];return{name:e.name,kind:String(u.kind??""),scope:e.scope,path:e.path,revision:Ee(S).length,changed:P}}R(tt,"updateDoc");function ot(s){const{target:m,selection:i,fields:o}=s,n=o.name,$=i.store===null||i.store===void 0?null:W(J(i.store),!0),c=ue(n,m,i.scope,$);if(c===null)throw _(`memory document not found: ${n}`,{memory:n,next:"A delete takes the full canonical name (a project document is <namespace>/<local name>), and a directory\u2019s own document answers at the directory name. Run `crtr memory find <leaf>` to look it up, or pass --dir to reach one exact project store."});const h=pe(c),e=h.doc;if(e.plugin!==void 0)throw l(`${e.name} belongs to the installed plugin "${e.plugin}" \u2014 it is not a scope doc and cannot be deleted here. Manage plugin docs with \`crtr pkg\`. To override just this doc, write a same-named doc at a writable scope (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,plugin:e.plugin});if(e.scope==="builtin")throw l(`${e.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be deleted. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,scope:"builtin"});if(e.localName===""&&e.store.ownerRelativePath==="")throw l(`${e.name} is the repository-root document at ${e.path}, which declares the namespace every document in this repository composes under \u2014 deleting it would unmount the whole repository, so it cannot be deleted.`,{memory:e.name,path:e.path,next:`Delete the documents under \`${e.name}/\` individually, or revise the repository-root document with \`crtr memory edit ${e.name} --rationale "<why>"\`.`});const t=A(e.path),d=L(e.root,e.path);return V(e.path),G(B(e.path),e.physicalRelativePath.split("/").length),C(d,M({op:"delete",actor:q(s),before:t,after:""})),{name:e.name,scope:e.scope,path:e.path,log_path:d,...h.collisionPaths.length>0?{follow_up:`Removed the first physical path in stable lexical order (${e.path}) to recover a same-store collision.`}:{}}}R(ot,"deleteDoc");function nt(s){const{target:m,selection:i,fields:o}=s,n=o.name,$=(o.to??"").trim(),c=i.store===null||i.store===void 0?null:W(J(i.store),!0),h=ue(n,m,i.scope,c);if(h===null)throw Ie(c?.docs??H(m,{quiet:!0,includeDescendants:!0}).docs).isDirectory(n)?l(`${n} is a canonical directory with no document of its own, and a directory never moves as a unit \u2014 move its members individually.`,{memory:n,next:`Run \`crtr memory read ${n}\` to list the members, then \`crtr memory move <member> --to <new-name>\` per document.`}):_(`memory document not found: ${n}`,{memory:n,next:"A move takes the full canonical name (a project document is <namespace>/<local name>), and a directory\u2019s own document answers at the directory name. Run `crtr memory find <leaf>` to look it up, or pass --dir to reach one exact project store."});const e=pe(h),t=e.doc;if(t.plugin!==void 0)throw l(`${t.name} belongs to the installed plugin "${t.plugin}" \u2014 it is not a scope doc and cannot be moved here. Manage plugin docs with \`crtr pkg\`.`,{memory:t.name,plugin:t.plugin});if(t.scope==="builtin")throw l(`${t.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be moved. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${t.name} ...\`).`,{memory:t.name,scope:"builtin"});if(t.localName===""&&t.store.ownerRelativePath==="")throw l(`${t.name} is the repository-root document at ${t.path}, which declares the namespace every document in this repository composes under \u2014 it answers at the namespace itself and cannot be moved.`,{memory:t.name,path:t.path});if($==="")throw l("--to requires the new canonical name");const d=de($);if(d===t.name)throw l(`${t.name} already answers to that name \u2014 nothing to move`);if(t.store.ownerRelativePath===""&&le(t.store,d)==="")throw l(`${d} is the repository namespace of the store at ${t.root} \u2014 its repository-root document declares that namespace and is not a destination a move can create.`,{memory:d});const y=N(t.path),g=me(t.store,d,c?.docs,t),v=N(g.path)===y,u=H(m,{quiet:!0,includeDescendants:!0}).docs,p=c?.docs??u,x=u.find(f=>f.name===t.name),k=x!==void 0&&N(x.path)===y,j=[],E=[];if(k){const f=new Set([y]);for(const w of p){const O=N(w.path);f.has(O)||(f.add(O),te(w.body).some(T=>T.name===t.name)&&(w.plugin!==void 0||w.scope==="builtin"?E.push(w):j.push(w)))}if(E.length>0)throw l(`cannot move ${t.name}: read-only docs link to it with [[${t.name}]] and their refs cannot be rewritten \u2014 `+E.map(w=>`${w.plugin!==void 0?`plugin ${w.plugin}`:w.scope}: ${w.name} (${w.path})`).join("; ")+". Nothing was changed.",{memory:t.name})}const D=[];for(const f of j){const w=A(f.path),{text:O,count:T}=he(w,t.name,d);T!==0&&(z(f.path,O),C(L(f.root,f.path),M({op:"edit",actor:q(s),rationale:`\`crtr memory move\`: [[${t.name}]] \u2192 [[${d}]]`,before:w,after:O})),D.push({name:f.name,scope:f.scope,path:f.path,refs:T}))}const S=A(t.path),F=k?he(S,t.name,d).text:S;let P=F;if(Pe(t.frontmatter)!==null){const f={...t.frontmatter??{}};delete f.name,P=K(f,X(F))}z(g.path,P);const a=t.physicalRelativePath.split("/").length;v||(V(t.path),G(B(t.path),a));const r=L(t.root,t.path),b=L(g.store.storeRoot,g.path);!v&&ee(r)&&(Z(I(b)),ee(b)?(we(b,A(r),"utf8"),V(r)):ge(r,b),G(B(r),a)),C(b,M({op:"move",actor:q(s),from:t.name,before:S,after:P}));const fe=k?D.length>0?` Rewrote [[${t.name}]] in ${D.length} doc${D.length===1?"":"s"}.`:" No inbound refs needed rewriting.":x===void 0?` Inbound [[${t.name}]] refs were left alone: no document answers to that name in this target view, so no link here pointed at the moved file.`:` Inbound [[${t.name}]] refs were left alone: ${x.path} answers to that name in this target view, so they still resolve to it.`;return{name:d,previous_name:t.name,scope:t.scope,path:g.path,log_path:b,refs_rewritten:D,follow_up:`Moved${e.collisionPaths.length>0?` the first physical path in stable lexical order (${t.path}) to recover a same-store collision.`:"."}${fe}`}}R(nt,"moveDoc");export{et as createDoc,ot as deleteDoc,nt as moveDoc,tt as updateDoc};
|
|
1
|
+
var be=Object.defineProperty;var $=(a,s)=>be(a,"name",{value:s,configurable:!0});import{dirname as E,join as te,resolve as G}from"node:path";import{CrtrError as oe,notFound as z,usage as p}from"../errors.js";import{parseFrontmatterGeneric as ve}from"../frontmatter.js";import{realpathOrSelf as I,walkFiles as $e}from"../fs-utils.js";import{appendFileBeneath as xe,existsBeneath as re,readFileBeneath as Re,renameBeneath as ke,unlinkBeneath as J,writeFileBeneath as V}from"../spaces/open-beneath.js";import{docLinkNames as De,findDocLinks as ne}from"./doc-link-grammar.js";import{lintMemoryDocument as je,resolvableCanonicalNames as Se}from"./lint.js";import{descendantStoreRoots as Pe}from"../nested-stores.js";import{projectScopeRoots as Ie}from"../scope.js";import{associateRepository as Ne}from"./repository-association.js";import{parsedSubstrateSurfaces as Ee}from"../substrate/frontmatter-validation.js";import{explicitLocalName as Fe}from"./identity.js";import{buildMemoryTree as Le}from"./tree.js";import{loadMemoryStoreView as K,loadMemoryTargetView as U,openProjectMemoryStore as Oe,resolveMemoryCandidatesForTarget as ae}from"../memory-resolver.js";import{appendHistoryRecord as C,buildHistoryRecord as M,historyLogPathFor as F,readHistoryRecords as Ae}from"./history.js";import{applyExtensionChanges as ie,coerceGate as se,coerceLintIgnore as ce,coerceSurface as me,literalBodySegment as W,memoryExtensionCatalogForDoc as de,parseRequestedExtensionChanges as le,planNewDocumentPlacement as pe,pruneEmptyParents as Q,requireCanonicalName as ue,requireLocalNameInStore as he,requireMountedStore as Y,requireUnambiguousDoc as Ce,selectMutationDoc as fe,serializeMemoryDoc as Me,serializeMemoryDocLiteral as H}from"./mutation-domain.js";function q(a,s){return Re(a,s).toString("utf8")}$(q,"readBeneath");function B(a){return a.history??{cwd:a.target.cwd,...a.target.nodeId===null?{}:{node:a.target.nodeId}}}$(B,"historyActorFor");function qe(a){return $e(a,s=>s.endsWith(".md")&&s!=="SKILL.md",s=>s===".crouter").length===0}$(qe,"emptyMemoryStore");function Be(a){const s=a.some(o=>o.on==="workspace-open"&&o.at==="content"),m=a.some(o=>{if(o.on!=="read"||o.at!=="content")return!1;const r=o.match;return r==="./**"||Array.isArray(r)&&r.includes("./**")});return s&&m}$(Be,"hasWorkspaceFrontDoor");function nt(a){const{target:s,scope:m,memoryDir:o,store:r,origin:b,fields:c}=a,h=c.name,e=c.kind,t=c.body??"";let d=!1;if(m==="project"&&r.mountStatus!=="ready"&&a.isExplicitProjectStore&&qe(o)){const n=Ne(I(r.ownerDir??E(E(o))));if(n.ok){if(n.association.ownerRelativePath!=="")throw p(`${r.ownerDir??E(E(o))} is a nested store in the repository rooted at ${n.association.repositoryRoot}; only the repository root declares a namespace`,{next:"crtr memory write <namespace> --dir <repositoryRoot>, or crtr sys migrate --dir <repositoryRoot>"});d=!0}else n.code==="no-project-root"&&(d=!0)}m==="project"&&r.mountStatus!=="ready"&&!d&&Y(r);let y,g;if(d)y=ue(h),g=te(o,"INDEX.md");else{const n=pe(r,h);y=n.canonicalName,g=n.path}const v=ce(c.lintIgnore),u=le(c.extension,void 0,de({scope:m,path:g})),l={};l.kind=e,l.privacy=c.privacy??"public",d&&(l.namespace=y),l.origin=b;const x=$((n,D)=>{D!==void 0&&(l[n]=D)},"setIf");x("when-and-why-to-read",c.whenAndWhyToRead),x("short-form",c.shortForm),c.unlisted===!0&&(l.unlisted=!0),c.surface!==void 0&&(l.surfaces=c.surface.map(me)),c.gate!==void 0&&(l.gate=se(c.gate)),x("lint-ignore",v),c.slash===!0&&(l.slash=!0),x("rationale",c.rationale),ie(l,u.sets,u.unsets),l["last-updated"]=b.created;const R=l.surfaces;if(m!=="project"&&Array.isArray(R)&&R.some(n=>n!==null&&typeof n=="object"&&n.on==="workspace-open"))throw p("a workspace-open surfaces entry is a project-store mount route; user, profile, and node memory cannot carry one \u2014 drop the entry or write to a project store");if(d){const n=Array.isArray(R)?R.filter(D=>D!==null&&typeof D=="object"):[];if(!Be(n))throw p(`empty project initialization requires the ordinary workspace front door: --surface '{on: workspace-open, at: content}' and --surface '{on: read, match: "./**", at: content}'`,{memory:y,next:`Pass both front-door surfaces when initializing ${y} with --dir.`})}const j=Me(l,t);V(o,g,j);const N=F(o,g);C(o,N,M({op:"create",actor:B(a),before:"",after:j}));const k=Ee(l),S=De(t).length>0||k.some(n=>n.on==="memory-read"),L=k.some(n=>n.on==="boot"),P=d?Oe(r.ownerDir??E(E(o))):r,i=je(P,g,{...S?{resolvable:Se(U({cwd:r.ownerDir??s.cwd,profileId:s.profileId,nodeId:s.nodeId},{quiet:!0,includeDescendants:!0}).docs)}:{},...L?{nestedStore:Pe(Ie(s.cwd,s.profileId)).map(n=>I(te(n,"memory"))).includes(I(o))}:{}});return{name:y,scope:m,path:g,...i.findings.length===0?{}:{findings:i.findings.map(n=>({severity:n.severity,rule:n.rule,message:n.message}))}}}$(nt,"createDoc");const Te=["short-form","gate","surfaces","unlisted","slash","rationale","lint-ignore"],Z=["kind","privacy","when-and-why-to-read","origin","last-updated"];function ye(a,s,m,o){if(o!==null)return o.candidates(a);try{return ae(a,s,{includeDescendants:!0,...m!==void 0?{scope:m}:{}})}catch(r){if(r instanceof oe&&r.code==="not_found")return null;throw r}}$(ye,"mutationCandidates");function we(a,s,m){const o=W(a),r=a.length-o.length,b=ne(o).filter(h=>h.name===s);let c=a;for(let h=b.length-1;h>=0;h-=1){const e=b[h];c=c.slice(0,r+e.start)+`[[${m}]]`+c.slice(r+e.end)}return{text:c,count:b.length}}$(we,"rewriteRefs");function at(a){const{target:s,selection:m,fields:o}=a,r=o.name,b=o.rationale,c=o.verbatim===!0,h=o.body??"";let e;try{const i=m.store===null||m.store===void 0?ae(r,s,{includeDescendants:!0,...m.scope===void 0?{}:{scope:m.scope}}):(he(m.store,r),K(m.store,!0,s).candidates(r));if(i===null)throw z(`memory document not found: ${r}`,{memory:r,next:`\`edit\` revises a document that already exists. Create it with \`crtr memory write ${r} ...\`, or run \`crtr memory find <query>\` if it exists under another name.`});e=Ce(i)}catch(i){throw i instanceof oe&&i.code==="not_found"?z(`memory document not found: ${r}`,{memory:r,next:`\`edit\` revises a document that already exists. Create it with \`crtr memory write ${r} ...\`, or run \`crtr memory find <query>\` if it exists under another name.`}):i}if(e.plugin!==void 0)throw p(`${e.name} belongs to the installed plugin "${e.plugin}" \u2014 a read-only corpus managed by \`crtr pkg\`, not editable here. To override just this doc, write a same-named doc at a writable scope (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,plugin:e.plugin});if(e.scope==="builtin")throw p(`${e.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be edited. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,scope:"builtin"});const t=ce(o.lintIgnore),d=le(o.extension,o.unsetExtension,de(e)),y=q(e.root,e.path),v={...ve(y).data??{}},u={...v};if(u.privacy===void 0&&(u.privacy="private"),e.scope==="project"&&e.localName===""){if(e.store.ownerRelativePath!==""&&Object.prototype.hasOwnProperty.call(v,"namespace"))throw p(`a nested store's INDEX.md carries no namespace: \u2014 the repository at ${e.store.repositoryRoot??e.root} declares it`,{memory:e.name,path:e.path,next:`Run \`crtr memory lint --dir ${e.store.ownerDir??e.root}\` or \`crtr sys migrate --dir ${e.store.repositoryRoot??e.root}\`.`});if(e.store.ownerRelativePath===""&&v.namespace!==e.store.repositoryNamespace)throw p(`the repository namespace on ${e.path} is immutable; it must remain \`${e.store.repositoryNamespace}\``,{memory:e.name,path:e.path});if(v.name!==void 0)throw p(`the project root INDEX at ${e.path} cannot carry a \`name:\` field`,{memory:e.name,path:e.path,next:`Run \`crtr sys migrate --dir ${e.store.repositoryRoot??e.store.ownerDir??e.root}\`.`})}const l=$((i,n)=>{n!==void 0&&(u[i]=n)},"setIf");l("kind",o.kind),l("privacy",o.privacy),l("when-and-why-to-read",o.whenAndWhyToRead),l("short-form",o.shortForm),o.unlisted===!0&&(u.unlisted=!0),o.surface!==void 0&&(u.surfaces=o.surface.map(me)),o.gate!==void 0&&(u.gate=se(o.gate)),l("lint-ignore",t),o.slash===!0&&(u.slash=!0),l("rationale",o.docRationale),ie(u,d.sets,d.unsets);for(const i of o.unset??[]){if(Z.includes(i))throw p(`--unset ${i}: ${i} is never clearable`,{memory:e.name,next:`Protected fields are ${Z.join(", ")}.`});if(!Te.includes(i)&&!Object.prototype.hasOwnProperty.call(v,i)){const n=Object.keys(v).filter(D=>!Z.includes(D));throw p(`--unset ${i}: ${e.name} has no \`${i}\` field to unset`,{memory:e.name,next:n.length>0?`Fields ${e.name} has: ${n.join(", ")}.`:`${e.name} carries no field eligible for --unset.`})}delete u[i]}const x=u.surfaces;if(e.scope!=="project"&&Array.isArray(x)&&x.some(i=>i!==null&&typeof i=="object"&&i.on==="workspace-open"))throw p("a workspace-open surfaces entry is a project-store mount route; user, profile, and node memory cannot carry one \u2014 drop the entry");const R=W(y),j=h===""?R:h;if(H(u,j)===y)throw p(`edit changed nothing \u2014 ${e.name} already says exactly this, so there is nothing to record`,{memory:e.name,next:"Pipe a different body or pass a frontmatter flag that changes a value. To remove the doc entirely, use `crtr memory delete`."});u["last-updated"]=new Date().toISOString();const k=H(u,j);V(e.root,e.path,k);const S=F(e.root,e.path);C(e.root,S,M({op:"edit",actor:B(a),rationale:b,...c?{verbatim:!0}:{},before:y,after:k}));const L=[...new Set([...Object.keys(v),...Object.keys(u)])].filter(i=>i!=="last-updated").filter(i=>JSON.stringify(v[i])!==JSON.stringify(u[i])).sort((i,n)=>i.localeCompare(n)),P=[...j!==R?["body"]:[],...L];return{name:e.name,kind:String(u.kind??""),scope:e.scope,path:e.path,revision:Ae(e.root,S).length,changed:P}}$(at,"updateDoc");function it(a){const{target:s,selection:m,fields:o}=a,r=o.name,b=m.store===null||m.store===void 0?null:K(Y(m.store),!0,s),c=ye(r,s,m.scope,b);if(c===null)throw z(`memory document not found: ${r}`,{memory:r,next:"A delete takes the full canonical name (a project document is <namespace>/<local name>), and a directory\u2019s own document answers at the directory name. Run `crtr memory find <leaf>` to look it up, or pass --dir to reach one exact project store."});const h=fe(c),e=h.doc;if(e.plugin!==void 0)throw p(`${e.name} belongs to the installed plugin "${e.plugin}" \u2014 it is not a scope doc and cannot be deleted here. Manage plugin docs with \`crtr pkg\`. To override just this doc, write a same-named doc at a writable scope (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,plugin:e.plugin});if(e.scope==="builtin")throw p(`${e.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be deleted. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${e.name} ...\`).`,{memory:e.name,scope:"builtin"});if(e.localName===""&&e.store.ownerRelativePath==="")throw p(`${e.name} is the repository-root document at ${e.path}, which declares the namespace every document in this repository composes under \u2014 deleting it would unmount the whole repository, so it cannot be deleted.`,{memory:e.name,path:e.path,next:`Delete the documents under \`${e.name}/\` individually, or revise the repository-root document with \`crtr memory edit ${e.name} --rationale "<why>"\`.`});const t=q(e.root,e.path),d=F(e.root,e.path);return J(e.root,e.path),Q(e.root,G(e.path),e.physicalRelativePath.split("/").length),C(e.root,d,M({op:"delete",actor:B(a),before:t,after:""})),{name:e.name,scope:e.scope,path:e.path,log_path:d,...h.collisionPaths.length>0?{follow_up:`Removed the first physical path in stable lexical order (${e.path}) to recover a same-store collision.`}:{}}}$(it,"deleteDoc");function st(a){const{target:s,selection:m,fields:o}=a,r=o.name,b=(o.to??"").trim(),c=m.store===null||m.store===void 0?null:K(Y(m.store),!0,s),h=ye(r,s,m.scope,c);if(h===null)throw Le(c?.docs??U(s,{quiet:!0,includeDescendants:!0}).docs).isDirectory(r)?p(`${r} is a canonical directory with no document of its own, and a directory never moves as a unit \u2014 move its members individually.`,{memory:r,next:`Run \`crtr memory read ${r}\` to list the members, then \`crtr memory move <member> --to <new-name>\` per document.`}):z(`memory document not found: ${r}`,{memory:r,next:"A move takes the full canonical name (a project document is <namespace>/<local name>), and a directory\u2019s own document answers at the directory name. Run `crtr memory find <leaf>` to look it up, or pass --dir to reach one exact project store."});const e=fe(h),t=e.doc;if(t.plugin!==void 0)throw p(`${t.name} belongs to the installed plugin "${t.plugin}" \u2014 it is not a scope doc and cannot be moved here. Manage plugin docs with \`crtr pkg\`.`,{memory:t.name,plugin:t.plugin});if(t.scope==="builtin")throw p(`${t.name} is a builtin document shipped with the package (read-only) \u2014 it cannot be moved. Override it with a same-named doc at a writable scope instead (\`crtr memory write ${t.name} ...\`).`,{memory:t.name,scope:"builtin"});if(t.localName===""&&t.store.ownerRelativePath==="")throw p(`${t.name} is the repository-root document at ${t.path}, which declares the namespace every document in this repository composes under \u2014 it answers at the namespace itself and cannot be moved.`,{memory:t.name,path:t.path});if(b==="")throw p("--to requires the new canonical name");const d=ue(b);if(d===t.name)throw p(`${t.name} already answers to that name \u2014 nothing to move`);if(t.store.ownerRelativePath===""&&he(t.store,d)==="")throw p(`${d} is the repository namespace of the store at ${t.root} \u2014 its repository-root document declares that namespace and is not a destination a move can create.`,{memory:d});const y=I(t.path),g=pe(t.store,d,c?.docs,t),v=I(g.path)===y,u=U(s,{quiet:!0,includeDescendants:!0}).docs,l=c?.docs??u,x=u.find(f=>f.name===t.name),R=x!==void 0&&I(x.path)===y,j=[],N=[];if(R){const f=new Set([y]);for(const w of l){const T=I(w.path);f.has(T)||(f.add(T),ne(w.body).some(_=>_.name===t.name)&&(w.plugin!==void 0||w.scope==="builtin"?N.push(w):j.push(w)))}if(N.length>0)throw p(`cannot move ${t.name}: read-only docs link to it with [[${t.name}]] and their refs cannot be rewritten \u2014 `+N.map(w=>`${w.plugin!==void 0?`plugin ${w.plugin}`:w.scope}: ${w.name} (${w.path})`).join("; ")+". Nothing was changed.",{memory:t.name})}const k=[];for(const f of j){const w=q(f.root,f.path),{text:T,count:_}=we(w,t.name,d);if(_===0)continue;const X={...f.frontmatter??{}};X.privacy===void 0&&(X.privacy="private");const ee=H(X,W(T));V(f.root,f.path,ee),C(f.root,F(f.root,f.path),M({op:"edit",actor:B(a),rationale:`\`crtr memory move\`: [[${t.name}]] \u2192 [[${d}]]`,before:w,after:ee})),k.push({name:f.name,scope:f.scope,path:f.path,refs:_})}const S=q(t.root,t.path),L=R?we(S,t.name,d).text:S,P={...t.frontmatter??{}};P.privacy===void 0&&(P.privacy="private"),Fe(t.frontmatter)!==null&&delete P.name;const i=H(P,W(L)),n=g.store.storeRoot;V(n,g.path,i);const D=t.physicalRelativePath.split("/").length;v||(J(t.root,t.path),Q(t.root,G(t.path),D));const O=F(t.root,t.path),A=F(n,g.path);!v&&re(t.root,O)&&(re(n,A)?(xe(n,A,q(t.root,O)),J(t.root,O)):ke(t.root,O,A),Q(t.root,G(O),D)),C(n,A,M({op:"move",actor:B(a),from:t.name,before:S,after:i}));const ge=R?k.length>0?` Rewrote [[${t.name}]] in ${k.length} doc${k.length===1?"":"s"}.`:" No inbound refs needed rewriting.":x===void 0?` Inbound [[${t.name}]] refs were left alone: no document answers to that name in this target view, so no link here pointed at the moved file.`:` Inbound [[${t.name}]] refs were left alone: ${x.path} answers to that name in this target view, so they still resolve to it.`;return{name:d,previous_name:t.name,scope:t.scope,path:g.path,log_path:A,refs_rewritten:k,follow_up:`Moved${e.collisionPaths.length>0?` the first physical path in stable lexical order (${t.path}) to recover a same-store collision.`:"."}${ge}`}}$(st,"moveDoc");export{nt as createDoc,it as deleteDoc,st as moveDoc,at as updateDoc};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type MemoryDoc, type MemoryScope, type MemoryStoreDescriptor, type MemoryTarget } from '../memory-resolver.js';
|
|
2
2
|
import { type DeletedHistoryResolution, type HistoryRecord } from './history.js';
|
|
3
|
+
import { type PrivacyLevel } from '../substrate/schema.js';
|
|
3
4
|
export { createDoc, deleteDoc, moveDoc, updateDoc, type CreateDocInput, type DeleteDocInput, type MoveDocInput, type UpdateDocInput, } from './mutations.js';
|
|
4
5
|
export interface MemoryServiceSelection {
|
|
5
6
|
/** Resolution identity is always supplied by the caller; this service never uses ambient process state. */
|
|
@@ -28,6 +29,7 @@ export declare function memoryScopeRank(scope: MemoryScope): number;
|
|
|
28
29
|
export interface ListedMemoryDoc {
|
|
29
30
|
name: string;
|
|
30
31
|
kind: string;
|
|
32
|
+
privacy: PrivacyLevel;
|
|
31
33
|
scope: MemoryScope;
|
|
32
34
|
path: string;
|
|
33
35
|
storeRoot: string;
|
|
@@ -54,12 +56,14 @@ export interface MemorySearchPath {
|
|
|
54
56
|
export interface MemoryRankedSearchHit extends MemorySearchPath {
|
|
55
57
|
name: string;
|
|
56
58
|
kind: string;
|
|
59
|
+
privacy: PrivacyLevel;
|
|
57
60
|
scope: MemoryScope;
|
|
58
61
|
score: number;
|
|
59
62
|
short_form: string;
|
|
60
63
|
}
|
|
61
64
|
export interface MemoryGrepSearchHit extends MemorySearchPath {
|
|
62
65
|
name: string;
|
|
66
|
+
privacy: PrivacyLevel;
|
|
63
67
|
scope: MemoryScope;
|
|
64
68
|
line: number;
|
|
65
69
|
text: string;
|
|
@@ -87,6 +91,7 @@ export interface ReadDocInput extends MemoryServiceSelection {
|
|
|
87
91
|
kind?: string;
|
|
88
92
|
frontmatter?: boolean;
|
|
89
93
|
interpolateNodePaths?: boolean;
|
|
94
|
+
grantee?: string;
|
|
90
95
|
}
|
|
91
96
|
export type ReadDocResult = {
|
|
92
97
|
kind: 'document';
|