akm-cli 0.9.0-rc.8 → 0.9.0
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/CHANGELOG.md +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +105 -57
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +37 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +101 -6
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1806
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1234
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -223
- package/dist/migrate/legacy/content-migration.js +0 -305
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -72
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
- package/dist/migrate/legacy/three-db-cutover.js +0 -841
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -1,779 +0,0 @@
|
|
|
1
|
-
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
-
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
-
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
/**
|
|
5
|
-
* @removeIn 0.10.0
|
|
6
|
-
*
|
|
7
|
-
* FROZEN copy of the pre-0.9.0 recognition/placement/ref-grammar/origin-
|
|
8
|
-
* resolution surface — akm 0.9.0 chunk-1, WI-1.4, decision D1-6
|
|
9
|
-
* (chunk-1 brief + anchors §D). Seeds Chunk 8's migrator: it walks the OLD
|
|
10
|
-
* on-disk layout per source with THIS frozen resolver and builds the
|
|
11
|
-
* complete old-ref -> new-id map before any re-layout happens (normative
|
|
12
|
-
* spec §11.4; plan §3.4/§3.3 item 2).
|
|
13
|
-
*
|
|
14
|
-
* ## Why a copy, not a re-export (the #1 chunk-1 trap)
|
|
15
|
-
*
|
|
16
|
-
* A textual copy that still IMPORTS the live modules it freezes is NOT
|
|
17
|
-
* frozen — it breaks the moment those modules change, which for two of them
|
|
18
|
-
* is one/two chunks away:
|
|
19
|
-
*
|
|
20
|
-
* 1. `src/core/asset/asset-ref.ts` imports `{ isAssetType, AkmAssetType }`
|
|
21
|
-
* from `../common`. `isAssetType` is a DYNAMIC check
|
|
22
|
-
* (`Object.hasOwn(TYPE_DIRS, type)`) against the LIVE, evolving
|
|
23
|
-
* `TYPE_DIRS` — and `common.ts:29-88` (the whole `ASSET_TYPES`/
|
|
24
|
-
* `AkmAssetType`/`isAssetType` block) is deleted in Chunk 1.5, one
|
|
25
|
-
* chunk after this one closes.
|
|
26
|
-
* 2. `src/core/asset/asset-spec.ts` imports `buildWorkflowAction` from
|
|
27
|
-
* `../../output/renderers` and `registerActionBuilder`/
|
|
28
|
-
* `registerTypeRenderer` from `./asset-registry`; `ASSET_SPECS_INTERNAL`
|
|
29
|
-
* carries `rendererName`/`actionBuilder` fields that call into that
|
|
30
|
-
* registry. Both `asset-registry.ts` and `output/renderers.ts`'s
|
|
31
|
-
* type-registry are deleted in Chunk 3.
|
|
32
|
-
*
|
|
33
|
-
* This file therefore imports NOTHING from `src/` — only Node builtins
|
|
34
|
-
* (`node:fs`, `node:os`, `node:path`). Concretely (D1-6 a-d):
|
|
35
|
-
*
|
|
36
|
-
* (a) §"Type snapshot" below INLINES a private closed-union of the 14
|
|
37
|
-
* type keys (`LEGACY_TYPE_KEYS`) instead of importing the live
|
|
38
|
-
* `isAssetType`/`TYPE_DIRS`. This is a frozen SNAPSHOT of what the 14
|
|
39
|
-
* built-in types were at this HEAD — it does NOT track types added
|
|
40
|
-
* later via the live `registerAssetType` (out of scope: the old
|
|
41
|
-
* on-disk layout this migrator walks never had dynamically-registered
|
|
42
|
-
* types persisted into it).
|
|
43
|
-
* (b) §"Narrowed AssetSpec" below drops `rendererName`/`actionBuilder`
|
|
44
|
-
* from the copied `AssetSpec` shape — the migrator builds an old-ref
|
|
45
|
-
* map, it never renders, so it has no need of the renderer registry
|
|
46
|
-
* those two fields call into.
|
|
47
|
-
* (c) §"Own extension constants" below is this file's OWN copy of
|
|
48
|
-
* `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName`,
|
|
49
|
-
* independent of the live `core/recognition-util.ts` util home (WI-1.2)
|
|
50
|
-
* — "so the live util home can evolve without touching the migrator"
|
|
51
|
-
* (plan §3.4, architecture-plan.md:138).
|
|
52
|
-
* (d) §"Ref grammar" and §"Origin -> source resolution" below copy the
|
|
53
|
-
* bare/origin-qualified/`.derived` ref shapes and
|
|
54
|
-
* `resolveSourcesForOrigin`/`isRemoteOrigin`/`parseRegistryRef`
|
|
55
|
-
* self-contained, with a documented narrowing on the last one (see
|
|
56
|
-
* that section's header comment) — it drops the LIVE network-fetching
|
|
57
|
-
* artifact-resolution functions (`resolveNpmArtifact` et al.), keeping
|
|
58
|
-
* only the pure ID-deriving parse logic `resolveSourcesForOrigin`
|
|
59
|
-
* actually consumes.
|
|
60
|
-
*
|
|
61
|
-
* ## Provenance (D.2 census table, chunk-1 anchors.md §D.2)
|
|
62
|
-
*
|
|
63
|
-
* - `AssetSpec` interface + `ASSET_SPECS_INTERNAL` (all 14 types) +
|
|
64
|
-
* `TYPE_DIRS` + `isRelevantAssetFile`/`deriveCanonicalAssetName`/
|
|
65
|
-
* `deriveCanonicalAssetNameFromStashRoot`/`resolveAssetPathFromName` —
|
|
66
|
-
* `src/core/asset/asset-spec.ts` (whole file), NARROWED per (b) above.
|
|
67
|
-
* - `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName` —
|
|
68
|
-
* same file (moved to `core/recognition-util.ts` by WI-1.2; this copy
|
|
69
|
-
* predates and is independent of that move, per (c) above).
|
|
70
|
-
* - Ref grammar (bare + `.derived` key shapes) —
|
|
71
|
-
* `src/core/asset/asset-ref.ts` (whole file) +
|
|
72
|
-
* `src/commands/improve/memory/derived-ref.ts:37-83`
|
|
73
|
-
* (`DERIVED_SUFFIX`/`isDerivedMemory`/`resolveParentRef`). The concrete
|
|
74
|
-
* bare/origin-qualified/`.derived` pair algebra this resolver must
|
|
75
|
-
* reproduce is demonstrated today by `rekeyStateDbForMove`
|
|
76
|
-
* (`src/commands/mv-cli.ts:898-967`) — a good reference, not itself part
|
|
77
|
-
* of the freeze.
|
|
78
|
-
* - Origin -> source resolution — `src/registry/origin-resolve.ts` (whole
|
|
79
|
-
* file) + the pure ID-deriving core of its `parseRegistryRef` dependency
|
|
80
|
-
* (`src/registry/resolve.ts`), narrowed per (d) above.
|
|
81
|
-
*
|
|
82
|
-
* ## Deliberately NOT copied (out of WI-1.4 scope — chunk-1 anchors.md §D.1)
|
|
83
|
-
*
|
|
84
|
-
* `WORKFLOW_MIGRATIONS` (Chunk 8's frozen copy) and the pre-0.9 proposal
|
|
85
|
-
* legacy-import fold (now `proposal-fs-import.ts`, the Chunk-5 fold completed
|
|
86
|
-
* in Chunk 8) share this `migrate/legacy/` directory but were NOT this work
|
|
87
|
-
* item's deliverable — they were added by their own owning chunks, not WI-1.4.
|
|
88
|
-
*
|
|
89
|
-
* ## Identifier names are intentionally UNCHANGED from their live sources
|
|
90
|
-
*
|
|
91
|
-
* The manifest's `grepGateScope` explicitly excludes `src/migrate/legacy/`
|
|
92
|
-
* from every zero-count grep ("the frozen §3.4 copy retains dead
|
|
93
|
-
* identifiers by design... do NOT rename identifiers inside the frozen copy
|
|
94
|
-
* to appease greps"). Every exported name below (`AssetSpec`,
|
|
95
|
-
* `ASSET_SPECS_INTERNAL`, `ASSET_SPECS`, `TYPE_DIRS`, `SCRIPT_EXTENSIONS`,
|
|
96
|
-
* `WORKFLOW_EXTENSIONS`, `canonicalizeWorkflowName`, `DERIVED_SUFFIX`,
|
|
97
|
-
* `AssetRef`, `makeAssetRef`, `parseAssetRef`, `isDerivedMemory`,
|
|
98
|
-
* `resolveParentRef`, `resolveSourcesForOrigin`, `isRemoteOrigin`,
|
|
99
|
-
* `parseRegistryRef`, ...) matches its live-module counterpart's name
|
|
100
|
-
* exactly, by design.
|
|
101
|
-
*/
|
|
102
|
-
import fs from "node:fs";
|
|
103
|
-
import os from "node:os";
|
|
104
|
-
import path from "node:path";
|
|
105
|
-
import { fileURLToPath } from "node:url";
|
|
106
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
107
|
-
// Local, self-contained error type — replaces the live `UsageError`/
|
|
108
|
-
// `NotFoundError` (`src/core/errors.ts`) so this file imports nothing from
|
|
109
|
-
// `src/` at all, even a leaf that isn't currently delete-scheduled. Carries
|
|
110
|
-
// an optional `.code` for parity with the messages/codes the live modules
|
|
111
|
-
// threw, though the migrator only needs to catch-and-classify.
|
|
112
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
113
|
-
export class LegacyResolverError extends Error {
|
|
114
|
-
code;
|
|
115
|
-
constructor(message, code) {
|
|
116
|
-
super(message);
|
|
117
|
-
this.name = "LegacyResolverError";
|
|
118
|
-
this.code = code;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
122
|
-
// Type snapshot (D1-6a) — inlined closed union of the 14 built-in asset
|
|
123
|
-
// type keys, replacing the live `isAssetType`/`AkmAssetType`
|
|
124
|
-
// (`src/core/common.ts:29-88`, deleted Chunk 1.5). This is a frozen
|
|
125
|
-
// SNAPSHOT, not a dynamic registry lookup.
|
|
126
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
127
|
-
export const LEGACY_TYPE_KEYS = [
|
|
128
|
-
"skill",
|
|
129
|
-
"command",
|
|
130
|
-
"agent",
|
|
131
|
-
"knowledge",
|
|
132
|
-
"workflow",
|
|
133
|
-
"script",
|
|
134
|
-
"memory",
|
|
135
|
-
"env",
|
|
136
|
-
"secret",
|
|
137
|
-
"wiki",
|
|
138
|
-
"lesson",
|
|
139
|
-
"task",
|
|
140
|
-
"session",
|
|
141
|
-
"fact",
|
|
142
|
-
];
|
|
143
|
-
const LEGACY_TYPE_KEY_SET = new Set(LEGACY_TYPE_KEYS);
|
|
144
|
-
/** Frozen-snapshot replacement for the live `isAssetType` (`core/common.ts:86-88`). */
|
|
145
|
-
export function isAssetType(type) {
|
|
146
|
-
return LEGACY_TYPE_KEY_SET.has(type);
|
|
147
|
-
}
|
|
148
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
149
|
-
// Own extension constants (D1-6c) — independent copy of
|
|
150
|
-
// `SCRIPT_EXTENSIONS`/`WORKFLOW_EXTENSIONS`/`canonicalizeWorkflowName`, not
|
|
151
|
-
// imported from the live `core/recognition-util.ts` util home.
|
|
152
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
153
|
-
/** All recognized script extensions for the script asset type. */
|
|
154
|
-
export const SCRIPT_EXTENSIONS = new Set([
|
|
155
|
-
".sh",
|
|
156
|
-
".ts",
|
|
157
|
-
".js",
|
|
158
|
-
".ps1",
|
|
159
|
-
".cmd",
|
|
160
|
-
".bat",
|
|
161
|
-
".py",
|
|
162
|
-
".rb",
|
|
163
|
-
".go",
|
|
164
|
-
".pl",
|
|
165
|
-
".php",
|
|
166
|
-
".lua",
|
|
167
|
-
".r",
|
|
168
|
-
".swift",
|
|
169
|
-
".kt",
|
|
170
|
-
".kts",
|
|
171
|
-
]);
|
|
172
|
-
/**
|
|
173
|
-
* Recognized workflow asset extensions, in resolution-priority order.
|
|
174
|
-
* `.md` stays FIRST for back-compat; `.yaml`/`.yml` hold YAML workflow
|
|
175
|
-
* programs.
|
|
176
|
-
*/
|
|
177
|
-
export const WORKFLOW_EXTENSIONS = [".md", ".yaml", ".yml"];
|
|
178
|
-
/**
|
|
179
|
-
* Strip a recognized workflow extension (`.md`/`.yaml`/`.yml`) from a
|
|
180
|
-
* workflow asset *name* so `foo`, `foo.yaml`, `foo.yml`, and `foo.md`
|
|
181
|
-
* collapse to one canonical identity.
|
|
182
|
-
*/
|
|
183
|
-
export function canonicalizeWorkflowName(name) {
|
|
184
|
-
const lower = name.toLowerCase();
|
|
185
|
-
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
186
|
-
if (lower.endsWith(ext))
|
|
187
|
-
return name.slice(0, -ext.length);
|
|
188
|
-
}
|
|
189
|
-
return name;
|
|
190
|
-
}
|
|
191
|
-
/** Structural marker suffix for a derived (inferred) memory's canonical name. */
|
|
192
|
-
export const DERIVED_SUFFIX = ".derived";
|
|
193
|
-
function toPosix(input) {
|
|
194
|
-
return input.replace(/\\/g, "/");
|
|
195
|
-
}
|
|
196
|
-
const workflowSpec = {
|
|
197
|
-
isRelevantFile: (fileName) => WORKFLOW_EXTENSIONS.includes(path.extname(fileName).toLowerCase()),
|
|
198
|
-
toCanonicalName: (typeRoot, filePath) => {
|
|
199
|
-
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
200
|
-
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
201
|
-
if (rel.toLowerCase().endsWith(ext))
|
|
202
|
-
return rel.slice(0, -ext.length);
|
|
203
|
-
}
|
|
204
|
-
return rel;
|
|
205
|
-
},
|
|
206
|
-
toAssetPath: (typeRoot, name) => {
|
|
207
|
-
// Explicit extension wins (accepts refs like "release/ship.yaml").
|
|
208
|
-
const lower = name.toLowerCase();
|
|
209
|
-
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
210
|
-
if (lower.endsWith(ext))
|
|
211
|
-
return path.join(typeRoot, name);
|
|
212
|
-
}
|
|
213
|
-
// Probe in priority order — `.md` first for back-compat — and fall back
|
|
214
|
-
// to the markdown path so error messages keep naming the canonical file.
|
|
215
|
-
for (const ext of WORKFLOW_EXTENSIONS) {
|
|
216
|
-
const candidate = path.join(typeRoot, `${name}${ext}`);
|
|
217
|
-
if (fs.existsSync(candidate))
|
|
218
|
-
return candidate;
|
|
219
|
-
}
|
|
220
|
-
return path.join(typeRoot, `${name}.md`);
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
const markdownSpec = {
|
|
224
|
-
isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".md",
|
|
225
|
-
toCanonicalName: (typeRoot, filePath) => {
|
|
226
|
-
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
227
|
-
return rel.endsWith(".md") ? rel.slice(0, -3) : rel;
|
|
228
|
-
},
|
|
229
|
-
toAssetPath: (typeRoot, name) => {
|
|
230
|
-
const withExt = name.endsWith(".md") ? name : `${name}.md`;
|
|
231
|
-
return path.join(typeRoot, withExt);
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
const scriptSpec = {
|
|
235
|
-
isRelevantFile: (fileName) => SCRIPT_EXTENSIONS.has(path.extname(fileName).toLowerCase()),
|
|
236
|
-
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
237
|
-
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
238
|
-
};
|
|
239
|
-
export const ASSET_SPECS_INTERNAL = {
|
|
240
|
-
skill: {
|
|
241
|
-
stashDir: "skills",
|
|
242
|
-
isRelevantFile: (fileName) => fileName === "SKILL.md",
|
|
243
|
-
toCanonicalName: (typeRoot, filePath) => {
|
|
244
|
-
const relDir = toPosix(path.dirname(path.relative(typeRoot, filePath)));
|
|
245
|
-
if (!relDir || relDir === ".")
|
|
246
|
-
return undefined;
|
|
247
|
-
return relDir;
|
|
248
|
-
},
|
|
249
|
-
toAssetPath: (typeRoot, name) => path.join(typeRoot, name, "SKILL.md"),
|
|
250
|
-
},
|
|
251
|
-
command: { stashDir: "commands", ...markdownSpec },
|
|
252
|
-
agent: { stashDir: "agents", ...markdownSpec },
|
|
253
|
-
knowledge: { stashDir: "knowledge", ...markdownSpec },
|
|
254
|
-
workflow: { stashDir: "workflows", ...workflowSpec },
|
|
255
|
-
script: { stashDir: "scripts", ...scriptSpec },
|
|
256
|
-
memory: { stashDir: "memories", ...markdownSpec },
|
|
257
|
-
env: {
|
|
258
|
-
stashDir: "env",
|
|
259
|
-
isRelevantFile: (fileName) => fileName === ".env" || fileName.endsWith(".env"),
|
|
260
|
-
toCanonicalName: (typeRoot, filePath) => {
|
|
261
|
-
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
262
|
-
const fileName = path.basename(rel);
|
|
263
|
-
// Treat ".env" as the "default" env; "<name>.env" → "<name>"
|
|
264
|
-
if (fileName === ".env") {
|
|
265
|
-
const dir = path.dirname(rel);
|
|
266
|
-
return dir === "." || dir === "" ? "default" : `${dir}/default`;
|
|
267
|
-
}
|
|
268
|
-
const stripped = rel.endsWith(".env") ? rel.slice(0, -4) : rel;
|
|
269
|
-
return stripped;
|
|
270
|
-
},
|
|
271
|
-
toAssetPath: (typeRoot, name) => {
|
|
272
|
-
if (name === "default")
|
|
273
|
-
return path.join(typeRoot, ".env");
|
|
274
|
-
return path.join(typeRoot, name.endsWith(".env") ? name : `${name}.env`);
|
|
275
|
-
},
|
|
276
|
-
},
|
|
277
|
-
secret: {
|
|
278
|
-
stashDir: "secrets",
|
|
279
|
-
isRelevantFile: (fileName) => !fileName.endsWith(".lock") && !fileName.endsWith(".sensitive"),
|
|
280
|
-
toCanonicalName: (typeRoot, filePath) => toPosix(path.relative(typeRoot, filePath)),
|
|
281
|
-
toAssetPath: (typeRoot, name) => path.join(typeRoot, name),
|
|
282
|
-
},
|
|
283
|
-
wiki: {
|
|
284
|
-
stashDir: "wikis",
|
|
285
|
-
...markdownSpec,
|
|
286
|
-
},
|
|
287
|
-
lesson: {
|
|
288
|
-
stashDir: "lessons",
|
|
289
|
-
...markdownSpec,
|
|
290
|
-
},
|
|
291
|
-
task: {
|
|
292
|
-
stashDir: "tasks",
|
|
293
|
-
isRelevantFile: (fileName) => path.extname(fileName).toLowerCase() === ".yml",
|
|
294
|
-
toCanonicalName: (typeRoot, filePath) => {
|
|
295
|
-
const rel = toPosix(path.relative(typeRoot, filePath));
|
|
296
|
-
return rel.endsWith(".yml") ? rel.slice(0, -4) : rel;
|
|
297
|
-
},
|
|
298
|
-
toAssetPath: (typeRoot, name) => {
|
|
299
|
-
const withExt = name.endsWith(".yml") ? name : `${name}.yml`;
|
|
300
|
-
return path.join(typeRoot, withExt);
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
session: {
|
|
304
|
-
stashDir: "sessions",
|
|
305
|
-
...markdownSpec,
|
|
306
|
-
},
|
|
307
|
-
fact: {
|
|
308
|
-
stashDir: "facts",
|
|
309
|
-
...markdownSpec,
|
|
310
|
-
},
|
|
311
|
-
};
|
|
312
|
-
export const ASSET_SPECS = ASSET_SPECS_INTERNAL;
|
|
313
|
-
export const TYPE_DIRS = Object.fromEntries(Object.entries(ASSET_SPECS_INTERNAL).map(([type, spec]) => [type, spec.stashDir]));
|
|
314
|
-
export function isRelevantAssetFile(assetType, fileName) {
|
|
315
|
-
return ASSET_SPECS[assetType]?.isRelevantFile(fileName) ?? false;
|
|
316
|
-
}
|
|
317
|
-
export function deriveCanonicalAssetName(assetType, typeRoot, filePath) {
|
|
318
|
-
return ASSET_SPECS[assetType]?.toCanonicalName(typeRoot, filePath);
|
|
319
|
-
}
|
|
320
|
-
export function deriveCanonicalAssetNameFromStashRoot(assetType, stashRoot, filePath) {
|
|
321
|
-
const relPath = toPosix(path.relative(stashRoot, filePath));
|
|
322
|
-
const segments = relPath.split("/").filter(Boolean);
|
|
323
|
-
const firstSegment = segments[0];
|
|
324
|
-
const typeRoot = firstSegment !== undefined && firstSegment === TYPE_DIRS[assetType]
|
|
325
|
-
? path.join(stashRoot, firstSegment)
|
|
326
|
-
: stashRoot;
|
|
327
|
-
return deriveCanonicalAssetName(assetType, typeRoot, filePath);
|
|
328
|
-
}
|
|
329
|
-
export function resolveAssetPathFromName(assetType, typeRoot, name) {
|
|
330
|
-
const spec = ASSET_SPECS[assetType];
|
|
331
|
-
if (!spec)
|
|
332
|
-
throw new Error(`Unknown asset type: "${assetType}"`);
|
|
333
|
-
return spec.toAssetPath(typeRoot, name);
|
|
334
|
-
}
|
|
335
|
-
/** Accepted spelling aliases mapping to a canonical asset type. */
|
|
336
|
-
const TYPE_ALIASES = {
|
|
337
|
-
environment: "env",
|
|
338
|
-
};
|
|
339
|
-
/**
|
|
340
|
-
* Build a ref string from components.
|
|
341
|
-
*
|
|
342
|
-
* Examples:
|
|
343
|
-
* makeAssetRef("script", "deploy.sh") → "script:deploy.sh"
|
|
344
|
-
* makeAssetRef("script", "deploy.sh", "npm:@scope/pkg") → "npm:@scope/pkg//script:deploy.sh"
|
|
345
|
-
*/
|
|
346
|
-
export function makeAssetRef(type, name, origin) {
|
|
347
|
-
validateName(name);
|
|
348
|
-
const normalized = normalizeName(name);
|
|
349
|
-
const asset = `${type}:${normalized}`;
|
|
350
|
-
if (!origin)
|
|
351
|
-
return asset;
|
|
352
|
-
return `${origin}//${asset}`;
|
|
353
|
-
}
|
|
354
|
-
/** Serialize a parsed {@link AssetRef} back to its canonical `[origin//]type:name` string form. */
|
|
355
|
-
export function refToString(ref) {
|
|
356
|
-
return makeAssetRef(ref.type, ref.name, ref.origin);
|
|
357
|
-
}
|
|
358
|
-
/** Parse a ref string in the format `[origin//]type:name`. */
|
|
359
|
-
export function parseAssetRef(ref) {
|
|
360
|
-
const trimmed = ref.trim();
|
|
361
|
-
if (!trimmed)
|
|
362
|
-
throw new LegacyResolverError("Empty ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
363
|
-
let origin;
|
|
364
|
-
let body = trimmed;
|
|
365
|
-
const boundary = trimmed.indexOf("//");
|
|
366
|
-
if (boundary >= 0) {
|
|
367
|
-
origin = trimmed.slice(0, boundary);
|
|
368
|
-
body = trimmed.slice(boundary + 2);
|
|
369
|
-
if (!origin)
|
|
370
|
-
throw new LegacyResolverError("Empty origin in ref.", "MISSING_REQUIRED_ARGUMENT");
|
|
371
|
-
}
|
|
372
|
-
const colon = body.indexOf(":");
|
|
373
|
-
if (colon <= 0) {
|
|
374
|
-
throw new LegacyResolverError(`Invalid ref "${trimmed}". Expected [origin//]type:name, e.g. skill:deploy or knowledge:guide.md`, "MISSING_REQUIRED_ARGUMENT");
|
|
375
|
-
}
|
|
376
|
-
const rawType = body.slice(0, colon);
|
|
377
|
-
const rawName = body.slice(colon + 1);
|
|
378
|
-
// The `vault` asset type was removed in 0.9.0. Point callers at its
|
|
379
|
-
// replacements rather than failing with a generic unknown-type error.
|
|
380
|
-
if (rawType === "vault") {
|
|
381
|
-
throw new LegacyResolverError("The `vault` asset type was removed in 0.9.0 — use `env:` (whole .env config) or `secret:` (a single value).", "MISSING_REQUIRED_ARGUMENT");
|
|
382
|
-
}
|
|
383
|
-
// Type aliases: `environment:` is an accepted spelling of the canonical `env:` type.
|
|
384
|
-
const resolvedType = TYPE_ALIASES[rawType] ?? rawType;
|
|
385
|
-
if (!isAssetType(resolvedType)) {
|
|
386
|
-
throw new LegacyResolverError(`Invalid asset type: "${rawType}".`, "MISSING_REQUIRED_ARGUMENT");
|
|
387
|
-
}
|
|
388
|
-
validateName(rawName);
|
|
389
|
-
const name = normalizeName(rawName);
|
|
390
|
-
return { type: resolvedType, name, origin: origin || undefined };
|
|
391
|
-
}
|
|
392
|
-
function validateName(name) {
|
|
393
|
-
if (!name)
|
|
394
|
-
throw new LegacyResolverError("Empty asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
395
|
-
if (name.includes("\0"))
|
|
396
|
-
throw new LegacyResolverError("Null byte in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
397
|
-
if (/^[A-Za-z]:/.test(name)) {
|
|
398
|
-
throw new LegacyResolverError("Windows drive path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
399
|
-
}
|
|
400
|
-
const normalized = path.posix.normalize(name.replace(/\\/g, "/"));
|
|
401
|
-
if (path.posix.isAbsolute(normalized)) {
|
|
402
|
-
throw new LegacyResolverError("Absolute path in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
403
|
-
}
|
|
404
|
-
if (normalized === ".." || normalized.startsWith("../")) {
|
|
405
|
-
throw new LegacyResolverError("Path traversal in asset name.", "MISSING_REQUIRED_ARGUMENT");
|
|
406
|
-
}
|
|
407
|
-
const segments = normalized.split("/");
|
|
408
|
-
if (segments.some((seg) => seg === "." || seg === "..")) {
|
|
409
|
-
throw new LegacyResolverError("Asset name cannot contain relative path segments.", "MISSING_REQUIRED_ARGUMENT");
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
function normalizeName(name) {
|
|
413
|
-
return path.posix.normalize(name.replace(/\\/g, "/"));
|
|
414
|
-
}
|
|
415
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
416
|
-
// `.derived` key shapes (D1-6d) — self-contained copy of
|
|
417
|
-
// `derived-ref.ts:37-83`'s `DERIVED_SUFFIX`/`isDerivedMemory`/
|
|
418
|
-
// `resolveParentRef`. `asNonEmptyString` is inlined (a two-line pure
|
|
419
|
-
// helper from `core/common.ts:537-541`) rather than imported.
|
|
420
|
-
// ═══════════════════════════════════════════════════════════════════════
|
|
421
|
-
function asNonEmptyString(value) {
|
|
422
|
-
if (typeof value !== "string")
|
|
423
|
-
return undefined;
|
|
424
|
-
const trimmed = value.trim();
|
|
425
|
-
return trimmed.length > 0 ? trimmed : undefined;
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Normalise an arbitrary `source:`/edge string to a canonical `memory:<name>`
|
|
429
|
-
* ref, or `undefined` when it is empty, unparseable, or not a memory ref.
|
|
430
|
-
*/
|
|
431
|
-
function parseMemoryRef(value) {
|
|
432
|
-
if (!value)
|
|
433
|
-
return undefined;
|
|
434
|
-
try {
|
|
435
|
-
const parsed = parseAssetRef(value.trim());
|
|
436
|
-
if (parsed.type !== "memory")
|
|
437
|
-
return undefined;
|
|
438
|
-
return makeAssetRef(parsed.type, parsed.name);
|
|
439
|
-
}
|
|
440
|
-
catch {
|
|
441
|
-
return undefined;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* True when the named memory is a derived/inferred child — either it carries
|
|
446
|
-
* `inferred: true` in its frontmatter or its name ends with the structural
|
|
447
|
-
* `.derived` suffix.
|
|
448
|
-
*/
|
|
449
|
-
export function isDerivedMemory(name, frontmatter) {
|
|
450
|
-
return frontmatter.inferred === true || name.endsWith(DERIVED_SUFFIX);
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Resolve the parent (source) memory ref for a derived memory, or
|
|
454
|
-
* `undefined` when none can be determined. Precedence: `frontmatter.source`,
|
|
455
|
-
* then `frontmatter.derivedFrom`, then the `.derived` name suffix stripped.
|
|
456
|
-
*/
|
|
457
|
-
export function resolveParentRef(name, frontmatter) {
|
|
458
|
-
const fromSource = parseMemoryRef(asNonEmptyString(frontmatter.source));
|
|
459
|
-
if (fromSource)
|
|
460
|
-
return fromSource;
|
|
461
|
-
const derivedFrom = asNonEmptyString(frontmatter.derivedFrom);
|
|
462
|
-
if (derivedFrom)
|
|
463
|
-
return makeAssetRef("memory", derivedFrom);
|
|
464
|
-
if (name.endsWith(DERIVED_SUFFIX)) {
|
|
465
|
-
return makeAssetRef("memory", name.slice(0, -DERIVED_SUFFIX.length));
|
|
466
|
-
}
|
|
467
|
-
return undefined;
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Given an origin string (from an AssetRef) and the full list of stash
|
|
471
|
-
* sources, return the subset of sources to search.
|
|
472
|
-
*
|
|
473
|
-
* Resolution order:
|
|
474
|
-
* 1. undefined → all sources
|
|
475
|
-
* 2. "local" → primary stash only (first entry)
|
|
476
|
-
* 3. exact match → source whose registryId matches verbatim
|
|
477
|
-
* 4. parsed match → parse origin as a registry ref, match by parsed ID
|
|
478
|
-
* 5. path match → source whose resolved path matches the origin
|
|
479
|
-
* 6. empty → indicates a remote/uninstalled origin (caller decides)
|
|
480
|
-
*/
|
|
481
|
-
export function resolveSourcesForOrigin(origin, allSources) {
|
|
482
|
-
if (!origin)
|
|
483
|
-
return allSources;
|
|
484
|
-
// "local" means the primary stash (first entry)
|
|
485
|
-
if (origin === "local") {
|
|
486
|
-
return allSources.length > 0 ? [allSources[0]] : [];
|
|
487
|
-
}
|
|
488
|
-
// Exact registryId match (e.g. origin is "npm:@scope/pkg")
|
|
489
|
-
const byExactId = allSources.filter((s) => s.registryId !== undefined && s.registryId === origin);
|
|
490
|
-
if (byExactId.length > 0)
|
|
491
|
-
return byExactId;
|
|
492
|
-
// Parse origin as a registry ref and match by parsed ID.
|
|
493
|
-
try {
|
|
494
|
-
const parsed = parseRegistryRef(origin);
|
|
495
|
-
const byParsedId = allSources.filter((s) => s.registryId !== undefined && s.registryId === parsed.id);
|
|
496
|
-
if (byParsedId.length > 0)
|
|
497
|
-
return byParsedId;
|
|
498
|
-
}
|
|
499
|
-
catch {
|
|
500
|
-
// Not a valid registry ref — continue to path matching
|
|
501
|
-
}
|
|
502
|
-
// Match by resolved path (any source, including installed)
|
|
503
|
-
const resolvedOrigin = path.resolve(origin);
|
|
504
|
-
const byPath = allSources.filter((s) => path.resolve(s.path) === resolvedOrigin);
|
|
505
|
-
if (byPath.length > 0)
|
|
506
|
-
return byPath;
|
|
507
|
-
// No match — origin may be remote/uninstalled
|
|
508
|
-
return [];
|
|
509
|
-
}
|
|
510
|
-
/**
|
|
511
|
-
* Check whether an origin refers to something that could be fetched
|
|
512
|
-
* remotely (i.e. it looks like a registry ref but isn't installed locally).
|
|
513
|
-
*/
|
|
514
|
-
export function isRemoteOrigin(origin, allSources) {
|
|
515
|
-
if (origin === "local")
|
|
516
|
-
return false;
|
|
517
|
-
return resolveSourcesForOrigin(origin, allSources).length === 0;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* Known prefixes `parseRegistryRef` handles as installable sources. Anything
|
|
521
|
-
* with a colon that doesn't start with one of these is likely a registry
|
|
522
|
-
* search result ID (e.g. `skills-sh:org/skills/name`).
|
|
523
|
-
*/
|
|
524
|
-
const KNOWN_PREFIXES = ["npm:", "github:", "git+", "file:", "http://", "https://"];
|
|
525
|
-
function detectRegistrySearchId(ref) {
|
|
526
|
-
const colonIdx = ref.indexOf(":");
|
|
527
|
-
if (colonIdx < 1)
|
|
528
|
-
return undefined;
|
|
529
|
-
for (const prefix of KNOWN_PREFIXES) {
|
|
530
|
-
if (ref.startsWith(prefix))
|
|
531
|
-
return undefined;
|
|
532
|
-
}
|
|
533
|
-
const prefix = ref.slice(0, colonIdx);
|
|
534
|
-
if (!/^[a-z][a-z0-9-]*$/.test(prefix))
|
|
535
|
-
return undefined;
|
|
536
|
-
const rest = ref.slice(colonIdx + 1);
|
|
537
|
-
const segments = rest.split("/").filter(Boolean);
|
|
538
|
-
const suggestedRef = segments.length >= 2 ? `github:${segments[0]}/${segments[1]}` : undefined;
|
|
539
|
-
const lines = [
|
|
540
|
-
`"${ref}" looks like a registry search result ID, not an installable ref.`,
|
|
541
|
-
`The "${prefix}:" prefix is a registry identifier and cannot be passed to \`akm add\`.`,
|
|
542
|
-
"",
|
|
543
|
-
];
|
|
544
|
-
if (suggestedRef) {
|
|
545
|
-
lines.push(`Try installing the source repository directly:`, ` akm add ${suggestedRef}`, "");
|
|
546
|
-
}
|
|
547
|
-
lines.push("Or search for the installable ref:", ` akm search "${segments.length > 2 ? segments[segments.length - 1] : rest}" --source registry`, "Then install using the installRef value from the result:", " akm add github:owner/repo", " akm add npm:package-name");
|
|
548
|
-
return lines.join("\n");
|
|
549
|
-
}
|
|
550
|
-
/** Parse an install/origin ref string, deriving its `{source, ref, id}` — the pure ID-deriving core of the live `parseRegistryRef`. */
|
|
551
|
-
export function parseRegistryRef(rawRef) {
|
|
552
|
-
const ref = rawRef.trim();
|
|
553
|
-
if (!ref)
|
|
554
|
-
throw new LegacyResolverError("Registry ref is required.");
|
|
555
|
-
const registryIdHint = detectRegistrySearchId(ref);
|
|
556
|
-
if (registryIdHint) {
|
|
557
|
-
throw new LegacyResolverError(registryIdHint);
|
|
558
|
-
}
|
|
559
|
-
if (ref.startsWith("npm:")) {
|
|
560
|
-
return parseNpmRef(ref.slice(4), ref);
|
|
561
|
-
}
|
|
562
|
-
if (ref.startsWith("github:")) {
|
|
563
|
-
return parseGithubShorthand(ref.slice(7), ref);
|
|
564
|
-
}
|
|
565
|
-
if (ref.startsWith("git+")) {
|
|
566
|
-
return parseGitUrl(stripGitTransport(ref), ref);
|
|
567
|
-
}
|
|
568
|
-
if (ref.startsWith("file:")) {
|
|
569
|
-
return tryParseLocalRef(fileUriToPath(ref), true);
|
|
570
|
-
}
|
|
571
|
-
if (ref.startsWith("http://") || ref.startsWith("https://")) {
|
|
572
|
-
return parseRemoteUrl(ref);
|
|
573
|
-
}
|
|
574
|
-
const localRef = tryParseLocalRef(ref, isPathLikeRef(ref));
|
|
575
|
-
if (localRef) {
|
|
576
|
-
return localRef;
|
|
577
|
-
}
|
|
578
|
-
if (ref.startsWith("@") || !looksLikeGithubOwnerRepo(ref)) {
|
|
579
|
-
return parseNpmRef(ref, ref);
|
|
580
|
-
}
|
|
581
|
-
return parseGithubShorthand(ref, ref);
|
|
582
|
-
}
|
|
583
|
-
function parseNpmRef(input, originalRef) {
|
|
584
|
-
const trimmed = input.trim();
|
|
585
|
-
if (!trimmed)
|
|
586
|
-
throw new LegacyResolverError("Invalid npm ref.");
|
|
587
|
-
const parsed = splitNpmNameAndVersion(trimmed);
|
|
588
|
-
validateNpmPackageName(parsed.packageName);
|
|
589
|
-
return {
|
|
590
|
-
source: "npm",
|
|
591
|
-
ref: originalRef,
|
|
592
|
-
id: `npm:${parsed.packageName}`,
|
|
593
|
-
packageName: parsed.packageName,
|
|
594
|
-
requestedVersionOrTag: parsed.requestedVersionOrTag,
|
|
595
|
-
};
|
|
596
|
-
}
|
|
597
|
-
function parseGithubShorthand(input, originalRef) {
|
|
598
|
-
const [repoPart, requestedRef] = splitRefSuffix(input.trim());
|
|
599
|
-
const segments = repoPart.split("/").filter(Boolean);
|
|
600
|
-
if (segments.length !== 2) {
|
|
601
|
-
throw new LegacyResolverError("Invalid GitHub ref. Expected owner/repo or owner/repo#ref.");
|
|
602
|
-
}
|
|
603
|
-
const owner = segments[0];
|
|
604
|
-
const repo = segments[1].replace(/\.git$/i, "");
|
|
605
|
-
if (!owner || !repo) {
|
|
606
|
-
throw new LegacyResolverError("Invalid GitHub ref. Expected owner/repo.");
|
|
607
|
-
}
|
|
608
|
-
return {
|
|
609
|
-
source: "github",
|
|
610
|
-
ref: originalRef,
|
|
611
|
-
id: `github:${owner}/${repo}`,
|
|
612
|
-
owner,
|
|
613
|
-
repo,
|
|
614
|
-
requestedRef,
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
function parseRemoteUrl(rawUrl) {
|
|
618
|
-
let url;
|
|
619
|
-
try {
|
|
620
|
-
url = new URL(rawUrl);
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
throw new LegacyResolverError("Invalid registry URL.");
|
|
624
|
-
}
|
|
625
|
-
if (url.hostname === "github.com") {
|
|
626
|
-
return parseGithubUrl(url, rawUrl);
|
|
627
|
-
}
|
|
628
|
-
return parseGitUrl(rawUrl, rawUrl);
|
|
629
|
-
}
|
|
630
|
-
function parseGithubUrl(url, rawUrl) {
|
|
631
|
-
const segments = url.pathname.split("/").filter(Boolean);
|
|
632
|
-
if (segments.length < 2) {
|
|
633
|
-
throw new LegacyResolverError("Invalid GitHub URL. Expected https://github.com/owner/repo.");
|
|
634
|
-
}
|
|
635
|
-
const owner = segments[0];
|
|
636
|
-
const repo = segments[1].replace(/\.git$/i, "");
|
|
637
|
-
const requestedRef = url.hash ? decodeURIComponent(url.hash.slice(1)) : undefined;
|
|
638
|
-
return {
|
|
639
|
-
source: "github",
|
|
640
|
-
ref: rawUrl,
|
|
641
|
-
id: `github:${owner}/${repo}`,
|
|
642
|
-
owner,
|
|
643
|
-
repo,
|
|
644
|
-
requestedRef,
|
|
645
|
-
};
|
|
646
|
-
}
|
|
647
|
-
function parseGitUrl(input, originalRef) {
|
|
648
|
-
const [urlPart, requestedRef] = splitRefSuffix(input.trim());
|
|
649
|
-
if (!urlPart)
|
|
650
|
-
throw new LegacyResolverError("Invalid git ref. A URL is required.");
|
|
651
|
-
const normalized = urlPart.replace(/\.git$/i, "");
|
|
652
|
-
return {
|
|
653
|
-
source: "git",
|
|
654
|
-
ref: originalRef,
|
|
655
|
-
id: `git:${normalized}`,
|
|
656
|
-
url: urlPart,
|
|
657
|
-
requestedRef,
|
|
658
|
-
};
|
|
659
|
-
}
|
|
660
|
-
function tryParseLocalRef(rawRef, explicitPath) {
|
|
661
|
-
const resolvedPath = path.resolve(rawRef);
|
|
662
|
-
let stat;
|
|
663
|
-
try {
|
|
664
|
-
stat = fs.statSync(resolvedPath);
|
|
665
|
-
}
|
|
666
|
-
catch {
|
|
667
|
-
if (explicitPath) {
|
|
668
|
-
throw new LegacyResolverError(`Local path not found: ${resolvedPath}`, "FILE_NOT_FOUND");
|
|
669
|
-
}
|
|
670
|
-
return undefined;
|
|
671
|
-
}
|
|
672
|
-
if (!stat.isDirectory()) {
|
|
673
|
-
if (explicitPath) {
|
|
674
|
-
throw new LegacyResolverError("Local add path must be a directory, but the provided path is not one.");
|
|
675
|
-
}
|
|
676
|
-
return undefined;
|
|
677
|
-
}
|
|
678
|
-
return {
|
|
679
|
-
source: "local",
|
|
680
|
-
ref: rawRef,
|
|
681
|
-
id: `local:${toReadableLocalId(resolvedPath)}`,
|
|
682
|
-
sourcePath: resolvedPath,
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
function isPathLikeRef(ref) {
|
|
686
|
-
if (ref.startsWith("@"))
|
|
687
|
-
return false;
|
|
688
|
-
if (ref === "." || ref === "..")
|
|
689
|
-
return true;
|
|
690
|
-
if (path.isAbsolute(ref))
|
|
691
|
-
return true;
|
|
692
|
-
if (ref.startsWith("./") || ref.startsWith("../") || ref.startsWith(".\\") || ref.startsWith("..\\")) {
|
|
693
|
-
return true;
|
|
694
|
-
}
|
|
695
|
-
return ref.includes("/") || ref.includes("\\");
|
|
696
|
-
}
|
|
697
|
-
function splitNpmNameAndVersion(input) {
|
|
698
|
-
if (input.startsWith("@")) {
|
|
699
|
-
const secondAt = input.indexOf("@", 1);
|
|
700
|
-
if (secondAt > 0) {
|
|
701
|
-
return {
|
|
702
|
-
packageName: input.slice(0, secondAt),
|
|
703
|
-
requestedVersionOrTag: input.slice(secondAt + 1) || undefined,
|
|
704
|
-
};
|
|
705
|
-
}
|
|
706
|
-
return { packageName: input };
|
|
707
|
-
}
|
|
708
|
-
const at = input.lastIndexOf("@");
|
|
709
|
-
if (at > 0) {
|
|
710
|
-
return {
|
|
711
|
-
packageName: input.slice(0, at),
|
|
712
|
-
requestedVersionOrTag: input.slice(at + 1) || undefined,
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
return { packageName: input };
|
|
716
|
-
}
|
|
717
|
-
function validateNpmPackageName(name) {
|
|
718
|
-
if (!name)
|
|
719
|
-
throw new LegacyResolverError("Invalid npm package name: name is required.");
|
|
720
|
-
if (name.length > 214)
|
|
721
|
-
throw new LegacyResolverError(`Invalid npm package name: "${name}" exceeds 214 characters.`);
|
|
722
|
-
if (name !== name.toLowerCase() && !name.startsWith("@")) {
|
|
723
|
-
throw new LegacyResolverError(`Invalid npm package name: "${name}" must be lowercase.`);
|
|
724
|
-
}
|
|
725
|
-
if (name.startsWith(".") || name.startsWith("_")) {
|
|
726
|
-
throw new LegacyResolverError(`Invalid npm package name: "${name}" cannot start with . or _.`);
|
|
727
|
-
}
|
|
728
|
-
if (/[~'!()*]/.test(name) ||
|
|
729
|
-
name.includes(" ") ||
|
|
730
|
-
encodeURIComponent(name)
|
|
731
|
-
.replace(/%40/g, "@")
|
|
732
|
-
.replace(/%2[Ff]/g, "/") !== name) {
|
|
733
|
-
throw new LegacyResolverError(`Invalid npm package name: "${name}" contains invalid characters.`);
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
function looksLikeGithubOwnerRepo(ref) {
|
|
737
|
-
const [repoPart] = splitRefSuffix(ref);
|
|
738
|
-
const parts = repoPart.split("/").filter(Boolean);
|
|
739
|
-
return parts.length === 2;
|
|
740
|
-
}
|
|
741
|
-
function splitRefSuffix(value) {
|
|
742
|
-
const hash = value.indexOf("#");
|
|
743
|
-
if (hash < 0)
|
|
744
|
-
return [value, undefined];
|
|
745
|
-
return [value.slice(0, hash), value.slice(hash + 1) || undefined];
|
|
746
|
-
}
|
|
747
|
-
/** Strip the `git+` transport prefix from a ref, returning the inner URL. */
|
|
748
|
-
function stripGitTransport(ref) {
|
|
749
|
-
return ref.slice(4); // strip "git+"
|
|
750
|
-
}
|
|
751
|
-
/** Convert a `file:` URI to a local filesystem path. */
|
|
752
|
-
function fileUriToPath(ref) {
|
|
753
|
-
const after = ref.slice(5); // strip "file:"
|
|
754
|
-
// Standard file:///absolute/path — delegate to Node's implementation
|
|
755
|
-
if (after.startsWith("//")) {
|
|
756
|
-
try {
|
|
757
|
-
return fileURLToPath(ref);
|
|
758
|
-
}
|
|
759
|
-
catch {
|
|
760
|
-
// Fall through to custom handling
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
// Non-standard file:./relative or file:../relative or file:/absolute
|
|
764
|
-
return after;
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Build a human-readable local ID from an absolute path.
|
|
768
|
-
* /home/user/akm/skills → ~/akm/skills
|
|
769
|
-
* /tmp/my-stash → /tmp/my-stash
|
|
770
|
-
*/
|
|
771
|
-
function toReadableLocalId(absolutePath) {
|
|
772
|
-
const home = os.homedir();
|
|
773
|
-
if (absolutePath === home)
|
|
774
|
-
return "~";
|
|
775
|
-
if (absolutePath.startsWith(home + path.sep)) {
|
|
776
|
-
return `~/${absolutePath.slice(home.length + 1)}`;
|
|
777
|
-
}
|
|
778
|
-
return absolutePath;
|
|
779
|
-
}
|