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
120 lines (119 loc) • 5.16 kB
JavaScript
// 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/.
/**
* The stages' view of the `improve_ledger` table: record an attempt, and load
* the rows candidate selection reads before it spends an LLM call. The
* repository owns the schema and the outcome → cadence rule.
*/
import fs from "node:fs";
import { getStateDbPath, withImmediateTransaction, withStateDb } from "../../core/state-db.js";
import { warn } from "../../core/warn.js";
import { isContentDrivenRow, isLedgerBlocked, listImproveLedgerRows, PAIR_PASS_LEDGER_SOURCE, recordImproveLedger, } from "../../storage/repositories/improve-ledger-repository.js";
import { openSqliteReadSnapshot } from "../../storage/sqlite-read-snapshot.js";
export { isContentDrivenRow, isLedgerBlocked, PAIR_PASS_LEDGER_SOURCE };
/** An improve candidate's durable state key: its index item_ref, else its conceptId. */
export function stateKey(ref, itemRef) {
return itemRef ?? ref;
}
/** The conceptId part of a durable key (`bundle//conceptId` → `conceptId`). */
export function stripBundle(ref) {
const boundary = ref.indexOf("//");
return boundary >= 0 ? ref.slice(boundary + 2) : ref;
}
function ledgerDbPath(access) {
return access?.proposalsCtx?.dbPath ?? access?.eventsCtx?.dbPath;
}
/**
* Run `fn` against the ledger's database: the run's borrowed handle, a read
* snapshot for a read-only caller (`undefined` when state.db does not exist),
* or a managed open.
*/
function withLedgerDb(access, fn) {
const borrowed = access?.eventsCtx?.db;
if (borrowed)
return fn(borrowed);
const dbPath = ledgerDbPath(access);
if (access?.readOnly) {
const db = openSqliteReadSnapshot(dbPath ?? getStateDbPath());
if (!db)
return undefined;
try {
return fn(db);
}
finally {
db.close();
}
}
return withStateDb(fn, dbPath !== undefined ? { path: dbPath } : undefined);
}
/**
* Record what a stage just did with one or more refs. Best-effort: a failure
* is a warning, never an error on top of an LLM result. (Proposal mints and
* decisions write the ledger in their own transactions.)
*/
export function recordLedgerAttempt(access, inputs) {
const list = Array.isArray(inputs) ? inputs : [inputs];
if (list.length === 0 || access?.readOnly || access?.eventsCtx?.readOnly)
return;
const now = access?.proposalsCtx?.now ?? access?.eventsCtx?.now ?? Date.now;
const at = new Date(now()).toISOString();
try {
withLedgerDb(access, (db) => withImmediateTransaction(db, () => {
for (const input of list) {
recordImproveLedger(db, {
stashDir: input.stashDir,
ref: input.ref,
source: input.source,
outcome: input.outcome,
at,
...(input.proposalId !== undefined ? { proposalId: input.proposalId } : {}),
...(input.detail !== undefined ? { detail: input.detail } : {}),
...(input.contentHash !== undefined ? { contentHash: input.contentHash } : {}),
});
}
}));
}
catch (error) {
const first = list[0];
const more = list.length > 1 ? ` (+${list.length - 1} more)` : "";
warn(`[improve] ledger write failed for ${first.ref}${more} (${first.source} → ${first.outcome}): ${error instanceof Error ? error.message : String(error)}`);
}
}
export function ledgerKey(source, ref) {
return `${source}\0${ref}`;
}
/** Read state.db through `fn` without creating it: `undefined` when there is none yet. */
export function readLedgerDb(access, fn) {
if (!access?.eventsCtx?.db && !fs.existsSync(ledgerDbPath(access) ?? getStateDbPath()))
return undefined;
return withLedgerDb(access, fn);
}
/** Every ledger row for `sources` in one query; no state.db yet means nothing was attempted. */
export function loadLedgerSnapshot(access, stashDir, sources) {
const out = new Map();
try {
readLedgerDb(access, (db) => {
for (const row of listImproveLedgerRows(db, stashDir, sources))
out.set(ledgerKey(row.source, row.ref), row);
});
}
catch (error) {
warn(`[improve] ledger read failed: ${error instanceof Error ? error.message : String(error)}`);
}
return out;
}
/** The row for a candidate under its durable key. */
export function ledgerRowFor(snapshot, source, ref, itemRef) {
return snapshot.get(ledgerKey(source, stateKey(ref, itemRef)));
}
/** `ref → last_attempt_at` for one source over a candidate set (the signal-delta cursor). */
export function lastAttemptByRef(snapshot, source, candidates) {
const out = new Map();
for (const candidate of candidates) {
const row = ledgerRowFor(snapshot, source, candidate.ref, candidate.itemRef);
if (row)
out.set(candidate.ref, row.lastAttemptAt);
}
return out;
}