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

80 lines (79 loc) • 2.51 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 { createHash } from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import { isWithin, resolveStashDir, safeRealpath, toPosix } from "../../core/common.js"; const PROJECT_CONFIG_RELATIVE_PATH = path.join(".akm", "config.json"); export function getCurrentWorkflowScopeKey() { const anchor = resolveWorkflowScopeAnchor(process.cwd()); const normalized = normalizeScopePath(anchor); const digest = createHash("sha256").update(normalized).digest("hex"); return `dir:v1:${digest}`; } export function resolveWorkflowScopeAnchor(startDir) { const cwd = safeRealpath(startDir); const projectRoot = findNearestProjectConfigRoot(cwd); if (projectRoot) return projectRoot; const gitRoot = findNearestGitRoot(cwd); if (gitRoot) return gitRoot; try { const stashDir = safeRealpath(resolveStashDir()); if (isWithin(cwd, stashDir)) return stashDir; } catch { // Ignore stash resolution failures and fall back to cwd. } return cwd; } function findNearestProjectConfigRoot(startDir) { let currentDir = startDir; while (true) { const configPath = path.join(currentDir, PROJECT_CONFIG_RELATIVE_PATH); if (isFile(configPath)) { return safeRealpath(currentDir); } const parentDir = path.dirname(currentDir); if (parentDir === currentDir) return null; currentDir = parentDir; } } function findNearestGitRoot(startDir) { let currentDir = startDir; while (true) { const gitPath = path.join(currentDir, ".git"); if (exists(gitPath)) { return safeRealpath(currentDir); } const parentDir = path.dirname(currentDir); if (parentDir === currentDir) return null; currentDir = parentDir; } } function exists(candidate) { try { fs.accessSync(candidate, fs.constants.F_OK); return true; } catch { return false; } } function isFile(candidate) { try { return fs.statSync(candidate).isFile(); } catch { return false; } } function normalizeScopePath(value) { const posix = toPosix(value); return process.platform === "win32" ? posix.toLowerCase() : posix; }