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

91 lines (90 loc) • 3.65 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 { stashDirFor } from "../../core/asset/asset-placement.js"; import { isBundleSlug, parseBundleRef } from "../../core/asset/asset-ref.js"; /** Channel order is the order links are stored and shown in. */ const CHANNELS = [ ["xref", (doc) => doc.xrefs], ["superseded_by", (doc) => doc.supersededBy], ["contradicted_by", (doc) => doc.contradictedBy], ["belief_peer", (doc) => doc.currentBeliefRefs], ["derived_from", (doc) => doc.derivedFrom], ["cites", (doc) => doc.sources], ["links_to", (doc) => doc.links], ["uses", (doc) => doc.uses], ]; /** The links an indexed document declares, in channel then authored order; one per (kind, target). */ export function declaredLinks(doc, owner) { const links = []; const seen = new Set(); for (const [kind, read] of CHANNELS) { for (const raw of stringValues(read(doc))) { const target = linkTarget(raw, owner.conceptId); if (!target) continue; const bundle = target.bundle ?? owner.bundleId; if (bundle === owner.bundleId && target.conceptId === owner.conceptId) continue; const key = `${kind}\0${bundle}\0${target.conceptId}`; if (seen.has(key)) continue; seen.add(key); links.push({ kind, raw, ...target }); } } return links; } function stringValues(value) { if (typeof value === "string") return [value]; return Array.isArray(value) ? value.filter((item) => typeof item === "string") : []; } /** * The target a token names, or `undefined` when the token is not an asset ref * (a session id, a URL, prose, a template placeholder). Retired spellings * convert in memory: `<type>:<name>` (`memory:x`), `wiki:<wiki>/<path>` (0.8 * wikis, now knowledge under `wikis/`), a `.md` suffix, and a `#fragment`. * Inside a wiki page, `raw/…` and `pages/…` are relative to the wiki root. */ function linkTarget(raw, ownerConceptId) { const token = raw.trim(); if (!token || /[\s<*]/.test(token) || token.includes("$(") || token.includes("${")) return; let bundle; let body = token; const boundary = token.indexOf("//"); if (boundary >= 0) { bundle = token.slice(0, boundary); body = token.slice(boundary + 2); if (!isBundleSlug(bundle)) return; } const conceptId = legacyConceptId(body.split("#", 1)[0] ?? "", ownerConceptId); if (conceptId === undefined || conceptId.length <= 1 || conceptId.includes("//")) return; try { return { ...(bundle ? { bundle } : {}), conceptId: parseBundleRef(conceptId).conceptId }; } catch { return; } } function legacyConceptId(body, ownerConceptId) { const stripped = body.replace(/\.md$/i, ""); const colon = stripped.indexOf(":"); if (colon >= 0) { const type = stripped.slice(0, colon); const name = stripped.slice(colon + 1); if (!name || name.includes(":")) return; if (type === "wiki") return `knowledge/wikis/${name}`; const stashDir = stashDirFor(type); return stashDir === undefined ? undefined : `${stashDir}/${name}`; } const wikiRoot = /^((?:[^/]+\/)*?wikis\/[^/]+\/)/.exec(ownerConceptId)?.[1]; if (wikiRoot && /^(raw|pages)\//.test(stripped)) return `${wikiRoot}${stripped}`; return stripped; }