akm-cli 0.9.0-beta.45 → 0.9.0-beta.46
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/dist/cli/shared.js +28 -0
- package/dist/cli.js +1 -2
- package/dist/commands/env/env-cli.js +16 -24
- package/dist/commands/env/secret-cli.js +12 -20
- package/dist/commands/graph/graph-cli.js +5 -13
- package/dist/commands/graph/graph.js +3 -3
- package/dist/commands/improve/consolidate/chunking.js +141 -0
- package/dist/commands/improve/consolidate/eligibility.js +64 -0
- package/dist/commands/improve/consolidate/merge.js +145 -0
- package/dist/commands/improve/consolidate/sanitize.js +231 -0
- package/dist/commands/improve/consolidate/types.js +4 -0
- package/dist/commands/improve/consolidate.js +20 -571
- package/dist/commands/improve/distill.js +5 -9
- package/dist/commands/improve/eligibility.js +434 -0
- package/dist/commands/improve/extract-cli.js +9 -1
- package/dist/commands/improve/extract.js +5 -19
- package/dist/commands/improve/improve-auto-accept.js +4 -8
- package/dist/commands/improve/improve-cli.js +35 -60
- package/dist/commands/improve/improve-result-file.js +5 -23
- package/dist/commands/improve/improve-session.js +58 -0
- package/dist/commands/improve/improve.js +107 -3606
- package/dist/commands/improve/locks.js +154 -0
- package/dist/commands/improve/loop-stages.js +1079 -0
- package/dist/commands/improve/preparation.js +1963 -0
- package/dist/commands/improve/recombine.js +6 -12
- package/dist/commands/improve/reflect.js +29 -34
- package/dist/commands/proposal/drain.js +25 -48
- package/dist/commands/proposal/proposal-cli.js +21 -31
- package/dist/commands/proposal/validators/proposals.js +3 -7
- package/dist/commands/read/curate.js +70 -14
- package/dist/commands/read/knowledge.js +2 -2
- package/dist/commands/sources/self-update.js +2 -2
- package/dist/commands/sources/stash-cli.js +9 -37
- package/dist/commands/tasks/tasks-cli.js +19 -27
- package/dist/commands/wiki-cli.js +21 -35
- package/dist/core/config/config.js +18 -2
- package/dist/core/events.js +3 -7
- package/dist/core/logs-db.js +6 -63
- package/dist/core/state/migrations.js +714 -0
- package/dist/core/state-db.js +28 -779
- package/dist/indexer/db/db.js +82 -216
- package/dist/indexer/indexer.js +11 -112
- package/dist/indexer/passes/dir-staleness.js +114 -0
- package/dist/indexer/search/search-source.js +10 -24
- package/dist/integrations/agent/runner-dispatch.js +59 -0
- package/dist/llm/client.js +22 -11
- package/dist/llm/graph-extract.js +28 -39
- package/dist/llm/memory-infer.js +34 -22
- package/dist/llm/metadata-enhance.js +35 -30
- package/dist/llm/structured-call.js +49 -0
- package/dist/output/shapes/passthrough.js +0 -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/scripts/migrate-storage.js +892 -1186
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +214 -179
- package/dist/setup/setup.js +26 -5
- package/dist/sources/providers/filesystem.js +0 -1
- package/dist/sources/providers/git-install.js +206 -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 -671
- package/dist/sources/providers/npm.js +2 -6
- package/dist/sources/providers/sync-from-ref.js +9 -1
- package/dist/sources/providers/website.js +2 -3
- package/dist/sources/website-ingest.js +51 -9
- package/dist/sources/wiki-fetchers/registry.js +53 -0
- package/dist/sources/wiki-fetchers/youtube.js +181 -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/tasks/runner.js +5 -13
- package/dist/workflows/runtime/runs.js +1 -117
- package/dist/workflows/runtime/workflow-asset-loader.js +125 -0
- package/package.json +5 -5
- package/dist/commands/db-cli.js +0 -23
- package/dist/indexer/db/db-backup.js +0 -376
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* `process.exit(1)` after the wrapper when findings exist.
|
|
12
12
|
*/
|
|
13
13
|
import { defineCommand } from "citty";
|
|
14
|
-
import { getStringArg,
|
|
15
|
-
import { defineJsonCommand, output, runWithJsonErrors } from "../cli/shared.js";
|
|
16
|
-
import {
|
|
14
|
+
import { getStringArg, parsePositiveIntFlag } from "../cli/parse-args.js";
|
|
15
|
+
import { defineGroupCommand, defineJsonCommand, output, runWithJsonErrors } from "../cli/shared.js";
|
|
16
|
+
import { resolveStashDir } from "../core/common.js";
|
|
17
17
|
import { loadConfig, resolveConfiguredSources } from "../core/config/config.js";
|
|
18
18
|
import { ConfigError, UsageError } from "../core/errors.js";
|
|
19
19
|
import { getHyphenatedArg, getHyphenatedBoolean } from "../output/context.js";
|
|
@@ -168,13 +168,6 @@ const wikiStashCommand = defineJsonCommand({
|
|
|
168
168
|
},
|
|
169
169
|
async run({ args }) {
|
|
170
170
|
const { stashRaw } = await import("../wiki/wiki.js");
|
|
171
|
-
const { content, preferredName } = await (async () => {
|
|
172
|
-
if (!isHttpUrl(args.source))
|
|
173
|
-
return readKnowledgeInput(args.source);
|
|
174
|
-
const { fetchWebsiteMarkdownSnapshot } = await import("../sources/website-ingest.js");
|
|
175
|
-
const snapshot = await fetchWebsiteMarkdownSnapshot(args.source);
|
|
176
|
-
return { content: snapshot.content, preferredName: args.as ?? snapshot.preferredName };
|
|
177
|
-
})();
|
|
178
171
|
let stashDir;
|
|
179
172
|
if (args.target) {
|
|
180
173
|
// Resolve the named source to its filesystem path.
|
|
@@ -193,6 +186,7 @@ const wikiStashCommand = defineJsonCommand({
|
|
|
193
186
|
else {
|
|
194
187
|
stashDir = resolveStashDir();
|
|
195
188
|
}
|
|
189
|
+
const { content, preferredName } = await readKnowledgeInput(args.source, { stashDir });
|
|
196
190
|
const result = stashRaw({
|
|
197
191
|
stashDir,
|
|
198
192
|
wikiName: args.name,
|
|
@@ -274,34 +268,26 @@ const wikiIngestCommand = defineJsonCommand({
|
|
|
274
268
|
});
|
|
275
269
|
},
|
|
276
270
|
});
|
|
277
|
-
|
|
278
|
-
// (M10) so adding a subcommand can never silently desync from `hasSubcommand`.
|
|
279
|
-
const wikiSubCommands = {
|
|
280
|
-
create: wikiCreateCommand,
|
|
281
|
-
register: wikiRegisterCommand,
|
|
282
|
-
list: wikiListCommand,
|
|
283
|
-
show: wikiShowCommand,
|
|
284
|
-
remove: wikiRemoveCommand,
|
|
285
|
-
pages: wikiPagesCommand,
|
|
286
|
-
search: wikiSearchCommand,
|
|
287
|
-
stash: wikiStashCommand,
|
|
288
|
-
lint: wikiLintCommand,
|
|
289
|
-
ingest: wikiIngestCommand,
|
|
290
|
-
};
|
|
291
|
-
const WIKI_SUBCOMMAND_SET = new Set(Object.keys(wikiSubCommands));
|
|
292
|
-
export const wikiCommand = defineCommand({
|
|
271
|
+
export const wikiCommand = defineGroupCommand({
|
|
293
272
|
meta: {
|
|
294
273
|
name: "wiki",
|
|
295
274
|
description: "Manage multiple markdown wikis (Karpathy-style). akm surfaces (lifecycle, raw/, lint, index); the agent writes pages.",
|
|
296
275
|
},
|
|
297
|
-
subCommands:
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
276
|
+
subCommands: {
|
|
277
|
+
create: wikiCreateCommand,
|
|
278
|
+
register: wikiRegisterCommand,
|
|
279
|
+
list: wikiListCommand,
|
|
280
|
+
show: wikiShowCommand,
|
|
281
|
+
remove: wikiRemoveCommand,
|
|
282
|
+
pages: wikiPagesCommand,
|
|
283
|
+
search: wikiSearchCommand,
|
|
284
|
+
stash: wikiStashCommand,
|
|
285
|
+
lint: wikiLintCommand,
|
|
286
|
+
ingest: wikiIngestCommand,
|
|
287
|
+
},
|
|
288
|
+
async defaultRun() {
|
|
289
|
+
// Default action: list wikis
|
|
290
|
+
const { listWikis } = await import("../wiki/wiki.js");
|
|
291
|
+
output("wiki-list", { wikis: listWikis(resolveStashDir()) });
|
|
306
292
|
},
|
|
307
293
|
});
|
|
@@ -221,7 +221,18 @@ function maybeAutoMigrateConfigFile(configPath, text) {
|
|
|
221
221
|
catch {
|
|
222
222
|
return text; // Malformed JSON — let parseAndValidate surface the error.
|
|
223
223
|
}
|
|
224
|
-
|
|
224
|
+
// Downgrade protection. Skip migration when the on-disk config is NEWER than
|
|
225
|
+
// this binary (=== 1), OR when it carries a configVersion we cannot order
|
|
226
|
+
// against ours (compareConfigVersion returns undefined for an unparseable
|
|
227
|
+
// value — e.g. one written by a newer/foreign akm). Migrating such a config
|
|
228
|
+
// could strip fields a newer binary added, a cross-version data-loss path.
|
|
229
|
+
//
|
|
230
|
+
// A MISSING configVersion (absent → undefined) is a legacy pre-versioning
|
|
231
|
+
// config that MUST still migrate, so the unparseable-skip is gated on the
|
|
232
|
+
// field being PRESENT (`onDiskVersion !== undefined`).
|
|
233
|
+
const onDiskVersion = obj.configVersion;
|
|
234
|
+
const versionOrder = compareConfigVersion(onDiskVersion, CURRENT_CONFIG_VERSION);
|
|
235
|
+
if (versionOrder === 1 || (onDiskVersion !== undefined && versionOrder === undefined)) {
|
|
225
236
|
return text;
|
|
226
237
|
}
|
|
227
238
|
const { changed, result } = migrateConfigShape(obj);
|
|
@@ -450,7 +461,12 @@ function applyRuntimeEnvApiKeys(config) {
|
|
|
450
461
|
}
|
|
451
462
|
// LLM profile keys: AKM_LLM_API_KEY for the default profile, then
|
|
452
463
|
// AKM_PROFILE_<UPPER>_API_KEY for any profile (per-profile wins).
|
|
453
|
-
|
|
464
|
+
// Resolve the default profile the SAME way the rest of the config layer does
|
|
465
|
+
// (resolveDefaultLlmProfileName), so the implicit `profiles.llm.default`
|
|
466
|
+
// fallback is honored. Keying off the raw `defaults.llm` field alone silently
|
|
467
|
+
// dropped AKM_LLM_API_KEY for configs that rely on the implicit default —
|
|
468
|
+
// the same no-op-run class as the 2026-05-23 incident.
|
|
469
|
+
const defaultProfile = resolveDefaultLlmProfileName(next);
|
|
454
470
|
if (next.profiles?.llm) {
|
|
455
471
|
const updated = { ...next.profiles.llm };
|
|
456
472
|
let changed = false;
|
package/dist/core/events.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import path from "node:path";
|
|
28
28
|
import { rethrowIfTestIsolationError } from "./errors.js";
|
|
29
29
|
import { getDataDir } from "./paths.js";
|
|
30
|
-
import { insertEvent, openStateDatabase, readStateEvents } from "./state-db.js";
|
|
30
|
+
import { insertEvent, openStateDatabase, readStateEvents, withStateDb } from "./state-db.js";
|
|
31
31
|
import { error } from "./warn.js";
|
|
32
32
|
/**
|
|
33
33
|
* Legacy events.jsonl path — used only by the migration script
|
|
@@ -82,18 +82,14 @@ export function appendEvent(input, ctx) {
|
|
|
82
82
|
// Default path: open, insert, close.
|
|
83
83
|
const dbPath = resolveDbPath(ctx);
|
|
84
84
|
try {
|
|
85
|
-
|
|
86
|
-
try {
|
|
85
|
+
withStateDb((db) => {
|
|
87
86
|
insertEvent(db, {
|
|
88
87
|
eventType: input.eventType,
|
|
89
88
|
ts,
|
|
90
89
|
ref: input.ref,
|
|
91
90
|
metadata: input.metadata,
|
|
92
91
|
});
|
|
93
|
-
}
|
|
94
|
-
finally {
|
|
95
|
-
db.close();
|
|
96
|
-
}
|
|
92
|
+
}, { path: dbPath });
|
|
97
93
|
}
|
|
98
94
|
catch (err) {
|
|
99
95
|
// Never mask the bun-test isolation guard as a silent "events failed".
|
package/dist/core/logs-db.js
CHANGED
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
* Log lines are high-volume, append-only, and freely purgeable; state.db rows
|
|
17
17
|
* (events, proposals, task_history) are durable records. Separating them keeps
|
|
18
18
|
* state.db small and lets log retention be aggressive without touching durable
|
|
19
|
-
* state.
|
|
20
|
-
*
|
|
19
|
+
* state. Callers that need to correlate a task_history row with its log lines do
|
|
20
|
+
* an application-side join on the {@link buildTaskRunId} key (e.g. `health` via
|
|
21
|
+
* {@link getLoggedRunIds}) — no SQLite ATTACH, so the split survives a future
|
|
22
|
+
* provider change.
|
|
21
23
|
*
|
|
22
24
|
* ## run_id
|
|
23
25
|
*
|
|
@@ -41,7 +43,6 @@ import { openDatabase } from "../storage/database.js";
|
|
|
41
43
|
import { runMigrations as runSqliteMigrations } from "../storage/engines/sqlite-migrations.js";
|
|
42
44
|
import { applyStandardPragmas } from "../storage/sqlite-pragmas.js";
|
|
43
45
|
import { getDataDir } from "./paths.js";
|
|
44
|
-
import { getStateDbPath } from "./state-db.js";
|
|
45
46
|
// ── Path helper ──────────────────────────────────────────────────────────────
|
|
46
47
|
/**
|
|
47
48
|
* Default path: `<dataDir>/logs.db` — alongside state.db so cooperating
|
|
@@ -146,8 +147,8 @@ export function runMigrations(db) {
|
|
|
146
147
|
* Encode a task run's identity — the unique `(task_id, started_at)` pair from
|
|
147
148
|
* state.db `task_history` — as a single run_id string.
|
|
148
149
|
*
|
|
149
|
-
* The format MUST stay in sync with the
|
|
150
|
-
*
|
|
150
|
+
* The format MUST stay in sync with the application-side join key that callers
|
|
151
|
+
* build from a `task_history` row's `task_id` and `started_at`.
|
|
151
152
|
*/
|
|
152
153
|
export function buildTaskRunId(taskId, startedAtIso) {
|
|
153
154
|
return `${taskId}@${startedAtIso}`;
|
|
@@ -230,64 +231,6 @@ export function getLoggedRunIds(db, runIds) {
|
|
|
230
231
|
}
|
|
231
232
|
return out;
|
|
232
233
|
}
|
|
233
|
-
// ── Cross-db: ATTACH state.db ────────────────────────────────────────────────
|
|
234
|
-
/**
|
|
235
|
-
* ATTACH state.db to an open logs.db handle under the schema name `state`,
|
|
236
|
-
* enabling cross-db joins like task_history × task_logs.
|
|
237
|
-
*
|
|
238
|
-
* The state.db file must already exist (callers always open state.db first in
|
|
239
|
-
* practice); attaching a non-existent path would silently create an empty,
|
|
240
|
-
* unmigrated database file, so this throws instead.
|
|
241
|
-
*/
|
|
242
|
-
export function attachStateDatabase(db, stateDbPath) {
|
|
243
|
-
const resolved = stateDbPath ?? getStateDbPath();
|
|
244
|
-
if (!fs.existsSync(resolved)) {
|
|
245
|
-
throw new Error(`Cannot ATTACH state.db: file does not exist at ${resolved}`);
|
|
246
|
-
}
|
|
247
|
-
// prepare().run() rather than db.run(): both drivers support parameterised
|
|
248
|
-
// ATTACH through a prepared statement, and no other call site uses db.run().
|
|
249
|
-
db.prepare("ATTACH DATABASE ? AS state").run(resolved);
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* Convenience: open logs.db with state.db attached as `state`. The returned
|
|
253
|
-
* handle supports cross-db queries such as {@link queryFailedRunLogLines}.
|
|
254
|
-
* Close it like any other handle (DETACH is implicit on close).
|
|
255
|
-
*/
|
|
256
|
-
export function openLogsDatabaseWithState(logsDbPath, stateDbPath) {
|
|
257
|
-
const db = openLogsDatabase(logsDbPath);
|
|
258
|
-
try {
|
|
259
|
-
attachStateDatabase(db, stateDbPath);
|
|
260
|
-
}
|
|
261
|
-
catch (err) {
|
|
262
|
-
db.close();
|
|
263
|
-
throw err;
|
|
264
|
-
}
|
|
265
|
-
return db;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Cross-db join: every log line belonging to a FAILED task_history run whose
|
|
269
|
-
* `started_at` is `>= since` (all failed runs when omitted). Requires a handle
|
|
270
|
-
* opened via {@link openLogsDatabaseWithState}.
|
|
271
|
-
*
|
|
272
|
-
* The join key is the run_id encoding documented on {@link buildTaskRunId}:
|
|
273
|
-
* `task_logs.run_id = task_history.task_id || '@' || task_history.started_at`.
|
|
274
|
-
*/
|
|
275
|
-
export function queryFailedRunLogLines(db, options = {}) {
|
|
276
|
-
const conditions = ["th.status = 'failed'"];
|
|
277
|
-
const params = [];
|
|
278
|
-
if (options.since) {
|
|
279
|
-
conditions.push("th.started_at >= ?");
|
|
280
|
-
params.push(options.since);
|
|
281
|
-
}
|
|
282
|
-
const limit = options.limit !== undefined && options.limit >= 0 ? ` LIMIT ${Math.floor(options.limit)}` : "";
|
|
283
|
-
return db
|
|
284
|
-
.prepare(`SELECT th.task_id, l.run_id, th.started_at, th.status, l.ts, l.stream, l.level, l.line
|
|
285
|
-
FROM state.task_history th
|
|
286
|
-
JOIN task_logs l ON l.run_id = th.task_id || '@' || th.started_at
|
|
287
|
-
WHERE ${conditions.join(" AND ")}
|
|
288
|
-
ORDER BY th.started_at DESC, l.id ASC${limit}`)
|
|
289
|
-
.all(...params);
|
|
290
|
-
}
|
|
291
234
|
// ── Retention ────────────────────────────────────────────────────────────────
|
|
292
235
|
/**
|
|
293
236
|
* Delete task_logs rows older than `retentionDays` (default: 90). Mirrors
|