UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

84 lines (83 loc) • 4.26 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. import path from "node:path"; import { deriveInstallations } from "../indexer/installations.js"; import { resolveSourceEntries } from "../indexer/search/search-source.js"; import { displayRef } from "./asset/resolve-ref.js"; import { UsageError } from "./errors.js"; import { prepareWriteTargetForMutation, resolveWorkingStashTarget, resolveWriteTarget, } from "./write-source.js"; function canonicalSources(config) { const sources = resolveSourceEntries(undefined, config); const installations = deriveInstallations(sources); return sources.flatMap((source, index) => { const bundleId = installations[index]?.id; return bundleId ? [{ bundleId, source }] : []; }); } function targetForCanonicalSource(config, canonical, options) { const target = canonical.source.registryId ? resolveWriteTarget(config, canonical.source.registryId, options) : resolveWorkingStashTarget(config, options); if (path.resolve(target.source.path) !== path.resolve(canonical.source.path)) { throw new UsageError(`Bundle "${canonical.bundleId}" no longer resolves to its indexed source root.`); } return target; } /** Resolve the canonical bundle id currently assigned to a write target. */ export function canonicalBundleIdForTarget(config, target) { return (canonicalSources(config).find((candidate) => path.resolve(candidate.source.path) === path.resolve(target.source.path))?.bundleId ?? target.source.name); } /** Resolve a canonical bundle qualifier to its writable target without preparing a Git boundary. */ export function resolveBundleWriteTarget(config, bundleId, options = {}) { const canonical = canonicalSources(config).find((candidate) => candidate.bundleId === bundleId); if (!canonical) { throw new UsageError(`Bundle "${bundleId}" is not configured.`, "INVALID_FLAG_VALUE"); } const target = targetForCanonicalSource(config, canonical, options); return { ...target, source: { ...target.source, name: canonical.bundleId } }; } function resolveExplicitMutationTarget(config, explicitTarget, options) { try { return resolveWriteTarget(config, explicitTarget, options); } catch (error) { try { return resolveBundleWriteTarget(config, explicitTarget, options); } catch { throw error; } } } /** * Reconcile a qualified mutation ref with the explicit target (`--target`, or * the `options.flag` the caller's command spells), then resolve the write * destination. */ export function resolveMutationTarget(config, ref, explicitTarget, options = {}) { const flag = options.flag ?? "--target"; const writeOptions = { requireWritable: options.requireWritable, flag }; const qualifiedTarget = ref.origin ? resolveBundleWriteTarget(config, ref.origin, writeOptions) : undefined; const explicitResolved = explicitTarget ? resolveExplicitMutationTarget(config, explicitTarget, writeOptions) : undefined; if (qualifiedTarget && explicitResolved && path.resolve(qualifiedTarget.source.path) !== path.resolve(explicitResolved.source.path)) { throw new UsageError(`Qualified ref bundle "${ref.origin}" conflicts with ${flag} "${explicitTarget}".`, "INVALID_FLAG_VALUE", `Drop ${flag} or select the same bundle.`); } let target = qualifiedTarget ?? explicitResolved ?? resolveWriteTarget(config, undefined, writeOptions); const bundleId = ref.origin ?? canonicalBundleIdForTarget(config, target); target = prepareWriteTargetForMutation({ ...target, source: { ...target.source, name: bundleId } }, { allowedAdapters: options.allowedAdapters }); const stableRef = { ...ref, origin: bundleId }; const defaultBundle = defaultBundleForTarget(config); return { target, ref: stableRef, displayRef: displayRef({ type: stableRef.type, name: stableRef.name, bundleId: stableRef.origin }, defaultBundle), }; } export function defaultBundleForTarget(config) { return config.defaultBundle; }