akm-cli 0.9.0-beta.5 → 0.9.0-beta.51
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 +711 -0
- package/README.md +12 -4
- package/dist/akm +38 -0
- package/dist/akm-migrate-storage +38 -0
- package/dist/assets/profiles/default.json +9 -4
- package/dist/assets/profiles/frequent.json +1 -1
- package/dist/assets/profiles/memory-focus.json +1 -1
- package/dist/assets/profiles/quick.json +1 -1
- package/dist/assets/profiles/synthesize.json +15 -0
- package/dist/assets/profiles/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +6 -2
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/graph-extract-user-prompt.md +1 -1
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +39 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +38 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +43 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +40 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +43 -0
- package/dist/assets/templates/html/health.html +281 -111
- package/dist/assets/wiki/ingest-workflow-template.md +38 -10
- package/dist/cli/parse-args.js +46 -1
- package/dist/cli/shared.js +28 -0
- package/dist/cli.js +27 -11
- package/dist/commands/agent/agent-dispatch.js +2 -2
- package/dist/commands/agent/agent-support.js +0 -7
- package/dist/commands/agent/contribute-cli.js +17 -4
- package/dist/commands/config-cli.js +18 -2
- package/dist/commands/env/child-env.js +47 -0
- package/dist/commands/env/env-cli.js +33 -26
- package/dist/commands/env/secret-cli.js +36 -22
- package/dist/commands/feedback-cli.js +15 -6
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +76 -72
- package/dist/commands/health/checks.js +49 -1
- package/dist/commands/health/html-report.js +422 -80
- package/dist/commands/health.js +386 -9
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +81 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/{lint.js → improve/consolidate/types.js} +1 -1
- package/dist/commands/improve/consolidate.js +635 -660
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill.js +159 -69
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +124 -2
- package/dist/commands/improve/extract-prompt.js +39 -2
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +389 -40
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/homeostatic.js +467 -0
- package/dist/commands/improve/improve-auto-accept.js +138 -7
- package/dist/commands/improve/improve-cli.js +36 -61
- package/dist/commands/improve/improve-profiles.js +14 -0
- package/dist/commands/improve/improve-result-file.js +14 -25
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +485 -2498
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1083 -0
- package/dist/commands/improve/memory/memory-contradiction-detect.js +23 -28
- package/dist/commands/improve/outcome-loop.js +256 -0
- package/dist/commands/improve/preparation.js +1966 -0
- package/dist/commands/improve/proactive-maintenance.js +115 -0
- package/dist/commands/improve/procedural.js +418 -0
- package/dist/commands/improve/recombine.js +850 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +183 -40
- package/dist/commands/improve/salience.js +438 -0
- package/dist/commands/improve/triage.js +93 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +38 -1
- package/dist/commands/lint/fact-linter.js +39 -0
- package/dist/commands/lint/index.js +31 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +7 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/proposal/drain-policies.js +5 -0
- package/dist/commands/proposal/drain.js +43 -50
- package/dist/commands/proposal/proposal-cli.js +21 -31
- package/dist/commands/proposal/proposal.js +5 -0
- package/dist/commands/proposal/propose.js +7 -2
- package/dist/commands/proposal/validators/proposal-quality-validators.js +9 -8
- package/dist/commands/proposal/validators/proposals.js +189 -63
- package/dist/commands/read/curate.js +414 -94
- package/dist/commands/read/knowledge.js +6 -3
- package/dist/commands/read/search-cli.js +9 -4
- package/dist/commands/read/search.js +10 -6
- package/dist/commands/read/show.js +86 -7
- package/dist/commands/sources/init.js +49 -17
- package/dist/commands/sources/installed-stashes.js +11 -3
- package/dist/commands/sources/schema-repair.js +43 -45
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/source-add.js +7 -3
- package/dist/commands/sources/stash-cli.js +28 -40
- package/dist/commands/sources/stash-skeleton.js +23 -8
- package/dist/commands/tasks/tasks-cli.js +19 -27
- package/dist/commands/tasks/tasks.js +39 -11
- package/dist/commands/wiki-cli.js +21 -35
- package/dist/core/asset/asset-registry.js +3 -1
- package/dist/core/asset/asset-spec.js +18 -2
- package/dist/core/asset/frontmatter.js +166 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/authoring-rules.js +92 -0
- package/dist/core/common.js +0 -5
- package/dist/core/config/config-migration.js +12 -11
- package/dist/core/config/config-schema.js +340 -56
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config.js +28 -7
- package/dist/core/events.js +3 -7
- package/dist/core/improve-types.js +11 -8
- package/dist/core/logs-db.js +10 -66
- package/dist/core/parse.js +36 -16
- package/dist/core/paths.js +3 -0
- package/dist/core/standards/resolve-standards-context.js +87 -0
- package/dist/core/standards/resolve-stash-standards.js +99 -0
- package/dist/core/standards/resolve-type-conventions.js +66 -0
- package/dist/core/state/migrations.js +714 -0
- package/dist/core/state-db.js +525 -474
- package/dist/indexer/db/db.js +439 -247
- package/dist/indexer/db/graph-db.js +129 -86
- package/dist/indexer/ensure-index.js +152 -17
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/graph/graph-extraction.js +218 -4
- package/dist/indexer/index-writer-lock.js +99 -0
- package/dist/indexer/indexer.js +123 -221
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/passes/memory-inference.js +13 -5
- package/dist/indexer/passes/staleness-detect.js +2 -5
- package/dist/indexer/search/db-search.js +19 -6
- package/dist/indexer/search/ranking-contributors.js +22 -0
- package/dist/indexer/search/ranking.js +4 -0
- package/dist/indexer/search/search-source.js +17 -18
- package/dist/indexer/search/semantic-status.js +4 -0
- package/dist/indexer/walk/matchers.js +9 -0
- package/dist/integrations/agent/config.js +6 -53
- package/dist/integrations/agent/index.js +2 -18
- package/dist/integrations/agent/prompts.js +75 -9
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/integrations/harnesses/claude/session-log.js +11 -1
- package/dist/integrations/harnesses/index.js +2 -3
- package/dist/integrations/harnesses/opencode/session-log.js +173 -3
- package/dist/integrations/harnesses/opencode-sdk/index.js +2 -2
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -2
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/client.js +45 -15
- package/dist/llm/embedder.js +42 -3
- package/dist/llm/embedders/deterministic.js +66 -0
- package/dist/llm/embedders/local.js +66 -2
- package/dist/llm/feature-gate.js +8 -4
- package/dist/llm/graph-extract.js +67 -44
- package/dist/llm/memory-infer-impl.js +138 -0
- package/dist/llm/memory-infer.js +1 -127
- package/dist/llm/metadata-enhance.js +44 -31
- package/dist/llm/structured-call.js +49 -0
- package/dist/migrate-storage-node.mjs +8 -0
- package/dist/output/context.js +5 -5
- package/dist/output/renderers.js +74 -2
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/text/helpers.js +16 -1
- package/dist/registry/providers/skills-sh.js +21 -147
- package/dist/registry/providers/static-index.js +15 -157
- package/dist/registry/resolve.js +22 -9
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +2617 -1961
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +759 -510
- package/dist/setup/setup.js +29 -8
- package/dist/sources/include.js +6 -2
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +210 -0
- package/dist/sources/providers/git-provider.js +234 -0
- package/dist/sources/providers/git-stash.js +248 -0
- package/dist/sources/providers/git.js +10 -661
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/provider-utils.js +13 -7
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/sources/providers/website.js +9 -5
- package/dist/sources/website-ingest.js +187 -29
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +239 -0
- package/dist/storage/database.js +45 -10
- package/dist/storage/managed-db.js +82 -0
- package/dist/storage/repositories/registry-cache.js +92 -0
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/backends/cron.js +1 -1
- package/dist/tasks/backends/launchd.js +1 -1
- package/dist/tasks/backends/schtasks.js +1 -1
- package/dist/tasks/{resolveAkmBin.js → resolve-akm-bin.js} +2 -2
- package/dist/tasks/runner.js +5 -13
- package/dist/text-import-hook.mjs +0 -0
- package/dist/wiki/wiki.js +37 -0
- package/dist/workflows/db.js +3 -4
- package/dist/workflows/runtime/runs.js +1 -117
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/data-and-telemetry.md +3 -2
- package/docs/migration/release-notes/0.9.0.md +39 -0
- package/package.json +13 -11
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
package/dist/tasks/runner.js
CHANGED
|
@@ -33,7 +33,7 @@ import { loadConfig } from "../core/config/config.js";
|
|
|
33
33
|
import { NotFoundError, rethrowIfTestIsolationError } from "../core/errors.js";
|
|
34
34
|
import { buildTaskRunId, insertTaskLogLines, openLogsDatabase, } from "../core/logs-db.js";
|
|
35
35
|
import { getTaskLogDir } from "../core/paths.js";
|
|
36
|
-
import { getTaskHistory,
|
|
36
|
+
import { getTaskHistory, queryTaskHistory, upsertTaskHistory, withStateDb } from "../core/state-db.js";
|
|
37
37
|
import { error } from "../core/warn.js";
|
|
38
38
|
import { requireAgentProfile, runAgent } from "../integrations/agent/index.js";
|
|
39
39
|
import { resolveProcessAgentProfile } from "../integrations/agent/config.js";
|
|
@@ -460,8 +460,7 @@ function persistRunLog(input) {
|
|
|
460
460
|
// ── history ─────────────────────────────────────────────────────────────────
|
|
461
461
|
function appendHistory(result) {
|
|
462
462
|
try {
|
|
463
|
-
|
|
464
|
-
try {
|
|
463
|
+
withStateDb((db) => {
|
|
465
464
|
upsertTaskHistory(db, {
|
|
466
465
|
task_id: result.id,
|
|
467
466
|
status: result.status,
|
|
@@ -477,10 +476,7 @@ function appendHistory(result) {
|
|
|
477
476
|
profile: result.target.kind === "prompt" ? result.target.profile : undefined,
|
|
478
477
|
}),
|
|
479
478
|
});
|
|
480
|
-
}
|
|
481
|
-
finally {
|
|
482
|
-
db.close();
|
|
483
|
-
}
|
|
479
|
+
});
|
|
484
480
|
}
|
|
485
481
|
catch (err) {
|
|
486
482
|
rethrowIfTestIsolationError(err);
|
|
@@ -488,8 +484,7 @@ function appendHistory(result) {
|
|
|
488
484
|
}
|
|
489
485
|
}
|
|
490
486
|
export function readTaskHistory(options = {}) {
|
|
491
|
-
|
|
492
|
-
try {
|
|
487
|
+
return withStateDb((db) => {
|
|
493
488
|
let rows;
|
|
494
489
|
if (options.id) {
|
|
495
490
|
const row = getTaskHistory(db, options.id);
|
|
@@ -503,10 +498,7 @@ export function readTaskHistory(options = {}) {
|
|
|
503
498
|
return rows.slice(0, options.limit);
|
|
504
499
|
}
|
|
505
500
|
return rows;
|
|
506
|
-
}
|
|
507
|
-
finally {
|
|
508
|
-
db.close();
|
|
509
|
-
}
|
|
501
|
+
});
|
|
510
502
|
}
|
|
511
503
|
/**
|
|
512
504
|
* Convert a `TaskHistoryRow` from state.db back to a `TaskRunResult` shape
|
|
File without changes
|
package/dist/wiki/wiki.js
CHANGED
|
@@ -224,6 +224,43 @@ function readSchemaDescription(wikiDir) {
|
|
|
224
224
|
return undefined;
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Load a wiki's `schema.md` body and frontmatter.
|
|
229
|
+
*
|
|
230
|
+
* Unlike {@link readSchemaDescription} (which returns only the frontmatter
|
|
231
|
+
* `description` for `listWikis` summaries), this returns the markdown **body**
|
|
232
|
+
* — everything after the closing `---` of the frontmatter — which is where the
|
|
233
|
+
* page contract, operations, and hard rules live. The body is the rulebook
|
|
234
|
+
* injected into the write-time prompt for wiki-page edits.
|
|
235
|
+
*
|
|
236
|
+
* Swallow-and-degrade like the existing reader: a missing file, an unresolvable
|
|
237
|
+
* wiki dir, or malformed content yields `{ body: "", frontmatter: {} }`. Never
|
|
238
|
+
* throws.
|
|
239
|
+
*/
|
|
240
|
+
export function loadWikiSchema(stashRoot, name) {
|
|
241
|
+
const empty = { body: "", frontmatter: {} };
|
|
242
|
+
let wikiDir;
|
|
243
|
+
try {
|
|
244
|
+
wikiDir = resolveWikiDir(stashRoot, name);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return empty;
|
|
248
|
+
}
|
|
249
|
+
let raw;
|
|
250
|
+
try {
|
|
251
|
+
raw = fs.readFileSync(path.join(wikiDir, SCHEMA_MD), "utf8");
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return empty;
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
const parsed = parseFrontmatter(raw);
|
|
258
|
+
return { body: parsed.content, frontmatter: parsed.data };
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
return empty;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
227
264
|
function toIsoDate(ms) {
|
|
228
265
|
return new Date(ms).toISOString();
|
|
229
266
|
}
|
package/dist/workflows/db.js
CHANGED
|
@@ -6,6 +6,7 @@ import path from "node:path";
|
|
|
6
6
|
import { getWorkflowDbPath } from "../core/paths.js";
|
|
7
7
|
import { openDatabase } from "../storage/database.js";
|
|
8
8
|
import { runMigrations as runSqliteMigrations } from "../storage/engines/sqlite-migrations.js";
|
|
9
|
+
import { applyStandardPragmas } from "../storage/sqlite-pragmas.js";
|
|
9
10
|
/**
|
|
10
11
|
* workflow.db — Durable SQLite database for workflow run state.
|
|
11
12
|
*
|
|
@@ -46,12 +47,10 @@ export function openWorkflowDatabase(dbPath = getWorkflowDbPath()) {
|
|
|
46
47
|
fs.mkdirSync(dir, { recursive: true });
|
|
47
48
|
}
|
|
48
49
|
const db = openDatabase(dbPath);
|
|
49
|
-
db.exec("PRAGMA journal_mode = WAL");
|
|
50
50
|
// #589: 30 s busy timeout, matching index.db / state.db. Without it the
|
|
51
51
|
// default is 0 ms, so any concurrent writer fails immediately with
|
|
52
|
-
// SQLITE_BUSY.
|
|
53
|
-
db
|
|
54
|
-
db.exec("PRAGMA foreign_keys = ON");
|
|
52
|
+
// SQLITE_BUSY. #628: journal_mode is configurable via AKM_SQLITE_JOURNAL_MODE.
|
|
53
|
+
applyStandardPragmas(db, { dataDir: dir });
|
|
55
54
|
ensureBaseSchema(db);
|
|
56
55
|
runMigrations(db);
|
|
57
56
|
return db;
|
|
@@ -2,23 +2,16 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
|
-
import fs from "node:fs";
|
|
6
5
|
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
7
6
|
import { loadConfig } from "../../core/config/config.js";
|
|
8
7
|
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
9
8
|
import { appendEvent } from "../../core/events.js";
|
|
10
|
-
import { getDbPath } from "../../core/paths.js";
|
|
11
|
-
import { closeDatabase, openExistingDatabase } from "../../indexer/db/db.js";
|
|
12
|
-
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
13
|
-
import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
|
|
14
|
-
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
15
9
|
import { withWorkflowRunsRepo, } from "../../storage/repositories/workflow-runs-repository.js";
|
|
16
|
-
import { formatWorkflowErrors } from "../authoring/authoring.js";
|
|
17
10
|
import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
|
|
18
|
-
import { parseWorkflow } from "../parser.js";
|
|
19
11
|
import { validateStepSummary } from "../validate-summary.js";
|
|
20
12
|
import { resolveAgentIdentity } from "./agent-identity.js";
|
|
21
13
|
import { evaluateCheckin } from "./checkin.js";
|
|
14
|
+
import { loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
|
|
22
15
|
export async function startWorkflowRun(ref, params = {}, options) {
|
|
23
16
|
const asset = await loadWorkflowAsset(ref);
|
|
24
17
|
return withWorkflowRunsRepo(async (repo) => {
|
|
@@ -299,115 +292,6 @@ async function resolveRunSpecifier(repo, specifier, params) {
|
|
|
299
292
|
const started = await startWorkflowRun(ref, params ?? {});
|
|
300
293
|
return { run: readWorkflowRun(repo, started.run.id), autoStarted: true };
|
|
301
294
|
}
|
|
302
|
-
async function loadWorkflowAsset(ref) {
|
|
303
|
-
const parsed = parseAssetRef(ref);
|
|
304
|
-
if (parsed.type !== "workflow") {
|
|
305
|
-
throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
|
|
306
|
-
}
|
|
307
|
-
const config = loadConfig();
|
|
308
|
-
const allSources = resolveSourceEntries(undefined, config);
|
|
309
|
-
const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
310
|
-
let assetPath;
|
|
311
|
-
let sourcePath;
|
|
312
|
-
for (const source of searchSources) {
|
|
313
|
-
try {
|
|
314
|
-
assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
|
|
315
|
-
sourcePath = source.path;
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
catch {
|
|
319
|
-
/* continue */
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (!assetPath) {
|
|
323
|
-
throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
|
|
324
|
-
}
|
|
325
|
-
const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
|
|
326
|
-
const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${parsed.name}`;
|
|
327
|
-
const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
|
|
328
|
-
const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
|
|
329
|
-
return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
|
|
330
|
-
}
|
|
331
|
-
function loadWorkflowDocumentFromDisk(assetPath) {
|
|
332
|
-
const content = fs.readFileSync(assetPath, "utf8");
|
|
333
|
-
const result = parseWorkflow(content, { path: assetPath });
|
|
334
|
-
if (!result.ok) {
|
|
335
|
-
throw new UsageError(formatWorkflowErrors(assetPath, result.errors));
|
|
336
|
-
}
|
|
337
|
-
return result.document;
|
|
338
|
-
}
|
|
339
|
-
function readWorkflowDocumentFromIndex(sourcePath, ref) {
|
|
340
|
-
const dbPath = getDbPath();
|
|
341
|
-
if (!fs.existsSync(dbPath))
|
|
342
|
-
return null;
|
|
343
|
-
const db = openExistingDatabase(dbPath);
|
|
344
|
-
try {
|
|
345
|
-
const parsed = parseAssetRef(ref);
|
|
346
|
-
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
347
|
-
const row = db
|
|
348
|
-
.prepare(`SELECT wd.document_json AS document_json
|
|
349
|
-
FROM workflow_documents wd
|
|
350
|
-
JOIN entries e ON e.id = wd.entry_id
|
|
351
|
-
WHERE e.entry_type = 'workflow' AND e.entry_key = ?
|
|
352
|
-
LIMIT 1`)
|
|
353
|
-
.get(entryKey);
|
|
354
|
-
if (!row)
|
|
355
|
-
return null;
|
|
356
|
-
try {
|
|
357
|
-
return JSON.parse(row.document_json);
|
|
358
|
-
}
|
|
359
|
-
catch {
|
|
360
|
-
return null;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
finally {
|
|
364
|
-
closeDatabase(db);
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function projectAsset(doc, ref, assetPath, sourcePath) {
|
|
368
|
-
return {
|
|
369
|
-
ref,
|
|
370
|
-
path: assetPath,
|
|
371
|
-
sourcePath,
|
|
372
|
-
title: doc.title,
|
|
373
|
-
...(doc.parameters
|
|
374
|
-
? {
|
|
375
|
-
parameters: doc.parameters.map((p) => ({
|
|
376
|
-
name: p.name,
|
|
377
|
-
...(p.description ? { description: p.description } : {}),
|
|
378
|
-
})),
|
|
379
|
-
}
|
|
380
|
-
: {}),
|
|
381
|
-
steps: doc.steps.map((s) => ({
|
|
382
|
-
id: s.id,
|
|
383
|
-
title: s.title,
|
|
384
|
-
instructions: s.instructions.text,
|
|
385
|
-
...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
|
|
386
|
-
sequenceIndex: s.sequenceIndex,
|
|
387
|
-
})),
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
function resolveWorkflowEntryId(sourcePath, ref) {
|
|
391
|
-
const dbPath = getDbPath();
|
|
392
|
-
if (!fs.existsSync(dbPath))
|
|
393
|
-
return null;
|
|
394
|
-
const db = openExistingDatabase(dbPath);
|
|
395
|
-
try {
|
|
396
|
-
const parsed = parseAssetRef(ref);
|
|
397
|
-
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
398
|
-
const row = db
|
|
399
|
-
.prepare(`SELECT id
|
|
400
|
-
FROM entries
|
|
401
|
-
WHERE entry_type = 'workflow'
|
|
402
|
-
AND entry_key = ?
|
|
403
|
-
LIMIT 1`)
|
|
404
|
-
.get(entryKey);
|
|
405
|
-
return row?.id ?? null;
|
|
406
|
-
}
|
|
407
|
-
finally {
|
|
408
|
-
closeDatabase(db);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
295
|
function readWorkflowRun(repo, runId) {
|
|
412
296
|
const run = repo.getRunById(runId);
|
|
413
297
|
if (!run) {
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
import fs from "node:fs";
|
|
5
|
+
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
6
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
7
|
+
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
8
|
+
import { getDbPath } from "../../core/paths.js";
|
|
9
|
+
import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
10
|
+
import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
|
|
11
|
+
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
12
|
+
import { withIndexDb } from "../../storage/repositories/index-db.js";
|
|
13
|
+
import { formatWorkflowErrors } from "../authoring/authoring.js";
|
|
14
|
+
import { parseWorkflow } from "../parser.js";
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a `workflow:<name>` ref to a fully-projected {@link WorkflowAsset}.
|
|
17
|
+
*
|
|
18
|
+
* Prefers the parsed document cached in `index.db` (fast path) and falls back to
|
|
19
|
+
* reading + parsing the source file from disk. Pure loading/parsing concern —
|
|
20
|
+
* extracted from the run repository so run orchestration no longer owns asset
|
|
21
|
+
* resolution.
|
|
22
|
+
*/
|
|
23
|
+
export async function loadWorkflowAsset(ref) {
|
|
24
|
+
const parsed = parseAssetRef(ref);
|
|
25
|
+
if (parsed.type !== "workflow") {
|
|
26
|
+
throw new UsageError(`Expected a workflow ref (workflow:<name>), got "${ref}".`);
|
|
27
|
+
}
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
const allSources = resolveSourceEntries(undefined, config);
|
|
30
|
+
const searchSources = resolveSourcesForOrigin(parsed.origin, allSources);
|
|
31
|
+
let assetPath;
|
|
32
|
+
let sourcePath;
|
|
33
|
+
for (const source of searchSources) {
|
|
34
|
+
try {
|
|
35
|
+
assetPath = await resolveAssetPath(source.path, "workflow", parsed.name);
|
|
36
|
+
sourcePath = source.path;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* continue */
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!assetPath) {
|
|
44
|
+
throw new NotFoundError(`Workflow not found for ref: workflow:${parsed.name}`);
|
|
45
|
+
}
|
|
46
|
+
const resolvedSourcePath = sourcePath ?? config.stashDir ?? assetPath;
|
|
47
|
+
const fullRef = `${parsed.origin ? `${parsed.origin}//` : ""}workflow:${parsed.name}`;
|
|
48
|
+
const cached = readWorkflowDocumentFromIndex(resolvedSourcePath, fullRef);
|
|
49
|
+
const document = cached ?? loadWorkflowDocumentFromDisk(assetPath);
|
|
50
|
+
return projectAsset(document, fullRef, assetPath, resolvedSourcePath);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the `entries.id` for an indexed workflow, or null when the index
|
|
54
|
+
* database does not yet exist or has no matching entry.
|
|
55
|
+
*/
|
|
56
|
+
export function resolveWorkflowEntryId(sourcePath, ref) {
|
|
57
|
+
if (!fs.existsSync(getDbPath()))
|
|
58
|
+
return null;
|
|
59
|
+
const parsed = parseAssetRef(ref);
|
|
60
|
+
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
61
|
+
return withIndexDb((db) => {
|
|
62
|
+
const row = db
|
|
63
|
+
.prepare(`SELECT id
|
|
64
|
+
FROM entries
|
|
65
|
+
WHERE entry_type = 'workflow'
|
|
66
|
+
AND entry_key = ?
|
|
67
|
+
LIMIT 1`)
|
|
68
|
+
.get(entryKey);
|
|
69
|
+
return row?.id ?? null;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function loadWorkflowDocumentFromDisk(assetPath) {
|
|
73
|
+
const content = fs.readFileSync(assetPath, "utf8");
|
|
74
|
+
const result = parseWorkflow(content, { path: assetPath });
|
|
75
|
+
if (!result.ok) {
|
|
76
|
+
throw new UsageError(formatWorkflowErrors(assetPath, result.errors));
|
|
77
|
+
}
|
|
78
|
+
return result.document;
|
|
79
|
+
}
|
|
80
|
+
function readWorkflowDocumentFromIndex(sourcePath, ref) {
|
|
81
|
+
if (!fs.existsSync(getDbPath()))
|
|
82
|
+
return null;
|
|
83
|
+
const parsed = parseAssetRef(ref);
|
|
84
|
+
const entryKey = `${sourcePath}:${parsed.type}:${parsed.name}`;
|
|
85
|
+
return withIndexDb((db) => {
|
|
86
|
+
const row = db
|
|
87
|
+
.prepare(`SELECT wd.document_json AS document_json
|
|
88
|
+
FROM workflow_documents wd
|
|
89
|
+
JOIN entries e ON e.id = wd.entry_id
|
|
90
|
+
WHERE e.entry_type = 'workflow' AND e.entry_key = ?
|
|
91
|
+
LIMIT 1`)
|
|
92
|
+
.get(entryKey);
|
|
93
|
+
if (!row)
|
|
94
|
+
return null;
|
|
95
|
+
try {
|
|
96
|
+
return JSON.parse(row.document_json);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function projectAsset(doc, ref, assetPath, sourcePath) {
|
|
104
|
+
return {
|
|
105
|
+
ref,
|
|
106
|
+
path: assetPath,
|
|
107
|
+
sourcePath,
|
|
108
|
+
title: doc.title,
|
|
109
|
+
...(doc.parameters
|
|
110
|
+
? {
|
|
111
|
+
parameters: doc.parameters.map((p) => ({
|
|
112
|
+
name: p.name,
|
|
113
|
+
...(p.description ? { description: p.description } : {}),
|
|
114
|
+
})),
|
|
115
|
+
}
|
|
116
|
+
: {}),
|
|
117
|
+
steps: doc.steps.map((s) => ({
|
|
118
|
+
id: s.id,
|
|
119
|
+
title: s.title,
|
|
120
|
+
instructions: s.instructions.text,
|
|
121
|
+
...(s.completionCriteria ? { completionCriteria: s.completionCriteria.map((c) => c.text) } : {}),
|
|
122
|
+
sequenceIndex: s.sequenceIndex,
|
|
123
|
+
})),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -16,14 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* @module workflows/validate-summary
|
|
18
18
|
*/
|
|
19
|
+
import validateSummaryJudgePrompt from "../assets/prompts/validate-summary-judge.md" with { type: "text" };
|
|
19
20
|
import { parseJsonResponse } from "../core/parse.js";
|
|
20
|
-
const JUDGE_SYSTEM =
|
|
21
|
-
"Given a step's completion criteria and a summary of the work an agent claims to have done, " +
|
|
22
|
-
"judge whether the summary provides concrete evidence that EVERY criterion is satisfied. " +
|
|
23
|
-
"Be skeptical: vague, hand-wavy, or unsubstantiated claims do NOT satisfy a criterion. " +
|
|
24
|
-
'Respond with ONLY a JSON object: {"complete": boolean, "missing": string[], "feedback": string}. ' +
|
|
25
|
-
'"missing" lists the exact criteria that are not yet satisfied; "feedback" is a short directive ' +
|
|
26
|
-
"telling the agent what to finish or fix. No prose, no markdown fences.";
|
|
21
|
+
const JUDGE_SYSTEM = validateSummaryJudgePrompt;
|
|
27
22
|
function buildUserPrompt(input) {
|
|
28
23
|
const criteria = input.completionCriteria.map((c, i) => `${i + 1}. ${c}`).join("\n");
|
|
29
24
|
return [
|
|
@@ -63,7 +63,7 @@ Override: set `AKM_CACHE_DIR` or `XDG_CACHE_HOME`.
|
|
|
63
63
|
|
|
64
64
|
| Path | Contents | Safe to delete? |
|
|
65
65
|
|---|---|---|
|
|
66
|
-
| `<stash>/` | All your asset files: agents, skills, commands, knowledge, workflows, memories,
|
|
66
|
+
| `<stash>/` | All your asset files: agents, skills, commands, knowledge, workflows, memories, env files, secrets, wikis, lessons, facts | **No** — this is YOUR data |
|
|
67
67
|
| `<stash>/.akm/` | Hidden AKM metadata (v0.7 proposals, legacy runs) | Caution — check for pending proposals first |
|
|
68
68
|
|
|
69
69
|
Override: set `AKM_STASH_DIR` (or configure `stashDir` in `config.json`).
|
|
@@ -130,7 +130,7 @@ An append-only log of every mutating action you perform with AKM. Events are sto
|
|
|
130
130
|
|
|
131
131
|
### 2. Proposals Table
|
|
132
132
|
|
|
133
|
-
The proposal queue: pending, accepted, and rejected improvement proposals for your stash assets. Generated by `akm
|
|
133
|
+
The proposal queue: pending, accepted, and rejected improvement proposals for your stash assets. Generated by `akm improve`, `akm propose`, and related proposal-producing flows.
|
|
134
134
|
|
|
135
135
|
Contents:
|
|
136
136
|
- Proposal UUID (primary key)
|
|
@@ -216,6 +216,7 @@ You can redirect any AKM directory to a custom path:
|
|
|
216
216
|
|---|---|
|
|
217
217
|
| `AKM_CONFIG_DIR` | Config directory (`~/.config/akm/`) |
|
|
218
218
|
| `AKM_DATA_DIR` | Data directory (`~/.local/share/akm/`) |
|
|
219
|
+
| `AKM_SQLITE_JOURNAL_MODE` | SQLite journal mode: `WAL` (default), `DELETE`, or `TRUNCATE`. Use `DELETE`/`TRUNCATE` on network filesystems (NFS/SMB) where WAL is impossible. When left at the `WAL` default, akm auto-detects a network FS for the data dir and falls back to `DELETE`. |
|
|
219
220
|
| `AKM_STATE_DIR` | State directory (`~/.local/state/akm/`) |
|
|
220
221
|
| `AKM_CACHE_DIR` | Cache directory (`~/.cache/akm/`) |
|
|
221
222
|
| `AKM_STASH_DIR` | Default stash directory (`~/akm/`) |
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Migration notes for akm v0.9.0
|
|
2
|
+
|
|
3
|
+
This is the final 0.9.0 cut. If you were already running a 0.9.0 beta, the
|
|
4
|
+
main upgrade work is to align scripts, prompts, and stash layout with the
|
|
5
|
+
released command surface.
|
|
6
|
+
|
|
7
|
+
Key operator-facing changes:
|
|
8
|
+
|
|
9
|
+
- Node.js is supported again for the published CLI. Install with Bun, Node.js
|
|
10
|
+
>= 20.12, or the prebuilt binary.
|
|
11
|
+
- The legacy `vault` asset type and `akm vault ...` command family are gone.
|
|
12
|
+
Use `env:` for whole `.env` groups and `secret:` for a single sensitive
|
|
13
|
+
value.
|
|
14
|
+
- `akm-migrate-storage` still ships and still performs the non-destructive
|
|
15
|
+
`vaults/` -> `env/` copy for older stashes. Run it before indexing if you are
|
|
16
|
+
upgrading from a stash that still stores `.env` files only under `vaults/`.
|
|
17
|
+
- Proposal workflow is fully consolidated around `akm improve`, `akm propose`,
|
|
18
|
+
and `akm proposal ...`. Update any old `akm reflect`, `akm distill`,
|
|
19
|
+
`akm accept`, `akm reject`, or `akm proposals` usage.
|
|
20
|
+
|
|
21
|
+
Primary public command family for 0.9.0:
|
|
22
|
+
|
|
23
|
+
- `akm improve <ref> [--task "..."]`
|
|
24
|
+
- `akm propose <type> <name> (--task "..." | --file <path>)`
|
|
25
|
+
- `akm proposal list`
|
|
26
|
+
- `akm proposal show <id>`
|
|
27
|
+
- `akm proposal diff <id>`
|
|
28
|
+
- `akm proposal accept <id>`
|
|
29
|
+
- `akm proposal reject <id> --reason "..."`
|
|
30
|
+
|
|
31
|
+
Recommended post-upgrade checks:
|
|
32
|
+
|
|
33
|
+
- Run `akm help migrate 0.9.0` on every machine where the CLI is installed.
|
|
34
|
+
- Run `akm-migrate-storage --yes` once if the stash ever used `vaults/`.
|
|
35
|
+
- Rebuild the index with `akm index`.
|
|
36
|
+
- Review agent instructions and docs for old `vault`, `reflect`, and `distill`
|
|
37
|
+
examples.
|
|
38
|
+
|
|
39
|
+
Full changelog: https://github.com/itlackey/akm/blob/main/CHANGELOG.md
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.9.0-beta.
|
|
3
|
+
"version": "0.9.0-beta.51",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "akm (Agent Knowledge Management) — A package manager for AI agent skills, commands, tools, and knowledge. Works with Claude Code, OpenCode, Cursor, and any AI coding assistant.",
|
|
6
6
|
"keywords": [
|
|
@@ -46,28 +46,30 @@
|
|
|
46
46
|
"docs/data-and-telemetry.md"
|
|
47
47
|
],
|
|
48
48
|
"bin": {
|
|
49
|
-
"akm": "dist/
|
|
50
|
-
"akm-migrate-storage": "dist/
|
|
49
|
+
"akm": "dist/akm",
|
|
50
|
+
"akm-migrate-storage": "dist/akm-migrate-storage"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
|
-
"preinstall": "node -e \"var ua=process.env.npm_config_user_agent||'';var
|
|
54
|
-
"build": "rm -rf dist && bun run tsc --project ./tsconfig.build.json && bun scripts/copy-assets.ts && bun scripts/fix-esm-extensions.ts",
|
|
53
|
+
"preinstall": "node -e \"var ua=process.env.npm_config_user_agent||'';var v=(process.versions.node||'0').split('.').map(function(n){return parseInt(n,10)||0});var ok=v[0]>20||(v[0]===20&&(v[1]>12||(v[1]===12&&v[2]>=0)));if(process.versions.bun||ua.startsWith('bun/')||process.env.BUN_INSTALL||ok){process.exit(0)}console.error('\\n ERROR: akm-cli requires the Bun runtime (https://bun.sh), Node.js >= 20.12, or the prebuilt binary.\\n Install options:\\n 1. Bun: curl -fsSL https://bun.sh/install | bash && bun install -g akm-cli\\n 2. Node: upgrade to Node.js 20.12 or newer (https://nodejs.org)\\n 3. Binary: curl -fsSL https://github.com/itlackey/akm/releases/latest/download/install.sh | bash\\n');process.exit(1)\"",
|
|
54
|
+
"build": "rm -rf dist && bun scripts/gen-config-schema.ts &&bun run tsc --project ./tsconfig.build.json && bun scripts/copy-assets.ts && bun scripts/fix-esm-extensions.ts",
|
|
55
55
|
"check": "bun run lint && bunx tsc --noEmit && bun run test:unit && bun run test:integration",
|
|
56
56
|
"check:fast": "bun run lint && bunx tsc --noEmit && bun run test:unit",
|
|
57
57
|
"check:changed": "bun test tests/output-baseline.test.ts tests/integration/e2e.test.ts tests/stash-search.test.ts && bun run lint && bunx tsc --noEmit",
|
|
58
|
-
"
|
|
59
|
-
"test
|
|
60
|
-
"test:
|
|
58
|
+
"sweep:tmp": "bun scripts/sweep-test-tmp.ts",
|
|
59
|
+
"test": "bash scripts/test-unit.sh",
|
|
60
|
+
"test:unit": "bash scripts/test-unit.sh",
|
|
61
|
+
"test:integration": "bun run sweep:tmp && bun test --isolate --timeout=30000 ./tests/integration ./tests/commands ./tests/workflows",
|
|
62
|
+
"test:unit:shard": "bun run sweep:tmp && bun test --isolate --timeout=30000 ./tests --path-ignore-patterns=tests/integration --shard=${SHARD:?set SHARD=k/N}",
|
|
63
|
+
"test:integration:shard": "bun run sweep:tmp && bun test --isolate --timeout=30000 ./tests/integration ./tests/commands ./tests/workflows --shard=${SHARD:?set SHARD=k/N}",
|
|
61
64
|
"test:node-smoke": "bun scripts/node-smoke.ts",
|
|
62
65
|
"test:node-compat": "AKM_NODE_COMPAT_TESTS=1 bun test --timeout=120000 tests/integration/node-compat.test.ts",
|
|
63
|
-
"test:sharded": "bun test ./tests --shard=1/4 & bun test ./tests --shard=2/4 & bun test ./tests --shard=3/4 & bun test ./tests --shard=4/4 & wait",
|
|
64
66
|
"test:time": "bun scripts/test-timing-report.ts",
|
|
65
67
|
"lint:isolation": "bun scripts/lint-tests-isolation.ts",
|
|
66
68
|
"lint:devto-posts": "bun scripts/lint-devto-posts.ts",
|
|
67
69
|
"lint:devto-posts:fix": "bun scripts/lint-devto-posts.ts --fix",
|
|
68
70
|
"publish:devto": "npx -y @sinedied/devto-cli push \"docs/posts/**/*.md\" --token \"$DEVTO_TOKEN\" --repo \"$GITHUB_REPOSITORY\" --branch \"${GITHUB_REF_NAME:-main}\" --reconcile",
|
|
69
71
|
"release:check": "./tests/release-check.sh",
|
|
70
|
-
"lint": "bunx biome check src/ tests/ && bun scripts/lint-tests-isolation.ts && bun scripts/lint-license-headers.ts && bun scripts/lint-runtime-boundary.ts",
|
|
72
|
+
"lint": "bunx biome check src/ tests/ && bun scripts/lint-tests-isolation.ts && bun scripts/lint-license-headers.ts && bun scripts/lint-runtime-boundary.ts && bun scripts/lint-repository-sql.ts && bun scripts/gen-config-schema.ts --check",
|
|
71
73
|
"lint:runtime-boundary": "bun scripts/lint-runtime-boundary.ts",
|
|
72
74
|
"lint:tests-isolation": "bun scripts/lint-tests-isolation.ts",
|
|
73
75
|
"lint:fix": "bunx biome check --write src/ tests/",
|
|
@@ -93,7 +95,7 @@
|
|
|
93
95
|
},
|
|
94
96
|
"engines": {
|
|
95
97
|
"bun": ">=1.0.0",
|
|
96
|
-
"node": ">=20.
|
|
98
|
+
"node": ">=20.12.0"
|
|
97
99
|
},
|
|
98
100
|
"dependencies": {
|
|
99
101
|
"@clack/prompts": "^1.3.0",
|
package/dist/commands/db-cli.js
DELETED
|
@@ -1,23 +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
|
-
* CLI command surface for `akm db ...`.
|
|
6
|
-
*
|
|
7
|
-
* MVP scope: only `akm db backups` is exposed. It lists the pre-upgrade
|
|
8
|
-
* snapshots written by `backupDataDir()` under `<dataDir>/backups/`.
|
|
9
|
-
*
|
|
10
|
-
* Restoration is intentionally NOT a CLI subcommand for MVP — operators are
|
|
11
|
-
* expected to stop akm and use `scripts/migrations/restore-data-dir.sh` (or a
|
|
12
|
-
* plain `mv`/`cp`) to recover. Keeping the surface narrow lets us evolve the
|
|
13
|
-
* backup format under the hood without locking in an API.
|
|
14
|
-
*/
|
|
15
|
-
import { getDataDir } from "../core/paths.js";
|
|
16
|
-
import { listBackups } from "../indexer/db/db-backup.js";
|
|
17
|
-
export function akmDbBackups() {
|
|
18
|
-
const dataDir = getDataDir();
|
|
19
|
-
return {
|
|
20
|
-
dataDir,
|
|
21
|
-
backups: listBackups(dataDir),
|
|
22
|
-
};
|
|
23
|
-
}
|