akm-cli 0.9.0-beta.44 → 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/health.js +5 -0
- 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/parse.js +36 -16
- 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/graph/graph-extraction.js +2 -0
- 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 +58 -42
- 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
|
@@ -13,6 +13,7 @@ import { resolveSourceEntries } from "../../indexer/search/search-source.js";
|
|
|
13
13
|
import { getHyphenatedArg, getHyphenatedBoolean, parseFlagValue } from "../../output/context.js";
|
|
14
14
|
import { akmImprove } from "./improve.js";
|
|
15
15
|
import { buildImproveRunId, recordTerminatedImproveRun, relativeImproveResultPath, writeImproveResultFile, } from "./improve-result-file.js";
|
|
16
|
+
import { runImproveSession } from "./improve-session.js";
|
|
16
17
|
export const improveCommand = defineCommand({
|
|
17
18
|
meta: {
|
|
18
19
|
name: "improve",
|
|
@@ -144,67 +145,44 @@ export const improveCommand = defineCommand({
|
|
|
144
145
|
process.stderr.write(`warning: failed to persist terminated improve run ${runId}: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
145
146
|
}
|
|
146
147
|
};
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
// a SIGTERM'd run
|
|
151
|
-
// improve_runs
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
SIGTERM: { code: 143, reason: "SIGTERM", ack: true },
|
|
156
|
-
SIGINT: { code: 130, reason: "SIGINT", ack: true },
|
|
157
|
-
SIGHUP: { code: 129, reason: "SIGHUP", ack: false },
|
|
158
|
-
};
|
|
159
|
-
const makeSignalHandler = (sig) => () => {
|
|
160
|
-
const { code, reason, ack } = SIGNAL_TABLE[sig];
|
|
161
|
-
// Hard-exit fallback: if the synchronous persist ever hangs (e.g. a
|
|
162
|
-
// stuck sqlite lock under contention), the watchdog still exits with
|
|
163
|
-
// the correct code instead of leaving a zombie process. .unref() keeps
|
|
164
|
-
// the timer from holding the loop open on the normal (fast) path.
|
|
165
|
-
const watchdog = setTimeout(() => process.exit(code), 2000);
|
|
166
|
-
if (typeof watchdog.unref === "function")
|
|
167
|
-
watchdog.unref();
|
|
168
|
-
try {
|
|
169
|
-
persistTerminated(reason);
|
|
170
|
-
}
|
|
171
|
-
finally {
|
|
172
|
-
clearTimeout(watchdog);
|
|
173
|
-
}
|
|
174
|
-
if (ack) {
|
|
175
|
-
process.stderr.write(`[improve] received ${sig}; recorded terminated run ${runId}\n`);
|
|
176
|
-
}
|
|
177
|
-
process.exit(code);
|
|
178
|
-
};
|
|
179
|
-
const sigtermHandler = makeSignalHandler("SIGTERM");
|
|
180
|
-
const sigintHandler = makeSignalHandler("SIGINT");
|
|
181
|
-
const sighupHandler = makeSignalHandler("SIGHUP");
|
|
182
|
-
process.once("SIGTERM", sigtermHandler);
|
|
183
|
-
process.once("SIGINT", sigintHandler);
|
|
184
|
-
process.once("SIGHUP", sighupHandler);
|
|
148
|
+
// R8: the signal table / handlers / watchdog / persist-before-exit
|
|
149
|
+
// choreography lives in `runImproveSession`. It registers the
|
|
150
|
+
// SIGTERM/SIGINT/SIGHUP handlers (each persists the terminated-run row
|
|
151
|
+
// BEFORE process.exit so a SIGTERM'd run — e.g. cron timeout — always
|
|
152
|
+
// leaves a row in improve_runs), awaits the work, then removes the
|
|
153
|
+
// handlers on the way out. `onTerminate` persists synchronously
|
|
154
|
+
// (recordTerminatedImproveRun -> bun:sqlite writes are sync), and the
|
|
155
|
+
// 2000ms watchdog inside the session force-exits if that ever hangs.
|
|
185
156
|
let improveResult;
|
|
186
157
|
try {
|
|
187
|
-
improveResult = await
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
target: targetArg,
|
|
192
|
-
autoAccept,
|
|
193
|
-
...(runId !== undefined ? { runId } : {}),
|
|
194
|
-
...(limitRaw !== undefined ? { limit: limitRaw } : {}),
|
|
195
|
-
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
196
|
-
...(minRetrievalCount !== undefined ? { minRetrievalCount } : {}),
|
|
197
|
-
...(requireFeedbackSignal ? { requireFeedbackSignal } : {}),
|
|
198
|
-
...(skipIfLocked ? { skipIfLocked } : {}),
|
|
199
|
-
...(profileArg !== undefined ? { profile: profileArg } : {}),
|
|
200
|
-
...(Object.keys(syncOverride).length > 0 ? { sync: syncOverride } : {}),
|
|
201
|
-
consolidateOptions: {
|
|
202
|
-
target: targetArg,
|
|
158
|
+
improveResult = await runImproveSession({
|
|
159
|
+
runWork: () => akmImprove({
|
|
160
|
+
scope: scopeArg,
|
|
161
|
+
task: taskArg,
|
|
203
162
|
dryRun,
|
|
163
|
+
target: targetArg,
|
|
204
164
|
autoAccept,
|
|
205
|
-
|
|
206
|
-
...(
|
|
207
|
-
|
|
165
|
+
...(runId !== undefined ? { runId } : {}),
|
|
166
|
+
...(limitRaw !== undefined ? { limit: limitRaw } : {}),
|
|
167
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
168
|
+
...(minRetrievalCount !== undefined ? { minRetrievalCount } : {}),
|
|
169
|
+
...(requireFeedbackSignal ? { requireFeedbackSignal } : {}),
|
|
170
|
+
...(skipIfLocked ? { skipIfLocked } : {}),
|
|
171
|
+
...(profileArg !== undefined ? { profile: profileArg } : {}),
|
|
172
|
+
...(Object.keys(syncOverride).length > 0 ? { sync: syncOverride } : {}),
|
|
173
|
+
consolidateOptions: {
|
|
174
|
+
target: targetArg,
|
|
175
|
+
dryRun,
|
|
176
|
+
autoAccept,
|
|
177
|
+
task: taskArg,
|
|
178
|
+
...(consolidateRecovery !== undefined ? { recoveryMode: consolidateRecovery } : {}),
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
}, {
|
|
182
|
+
signalSource: process,
|
|
183
|
+
exit: process.exit,
|
|
184
|
+
onTerminate: (reason) => persistTerminated(reason),
|
|
185
|
+
ack: (message) => process.stderr.write(`[improve] ${message}; recorded terminated run ${runId}\n`),
|
|
208
186
|
});
|
|
209
187
|
}
|
|
210
188
|
catch (err) {
|
|
@@ -216,9 +194,6 @@ export const improveCommand = defineCommand({
|
|
|
216
194
|
throw err;
|
|
217
195
|
}
|
|
218
196
|
finally {
|
|
219
|
-
process.removeListener("SIGTERM", sigtermHandler);
|
|
220
|
-
process.removeListener("SIGINT", sigintHandler);
|
|
221
|
-
process.removeListener("SIGHUP", sighupHandler);
|
|
222
197
|
clearLogFile();
|
|
223
198
|
}
|
|
224
199
|
const durationMs = Date.now() - startedAtMs;
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import crypto from "node:crypto";
|
|
29
29
|
import path from "node:path";
|
|
30
|
-
import {
|
|
30
|
+
import { recordImproveRun, withStateDb } from "../../core/state-db.js";
|
|
31
31
|
/**
|
|
32
32
|
* Build a stable run-id for a single improve invocation.
|
|
33
33
|
*
|
|
@@ -74,8 +74,7 @@ export function relativeImproveResultPath(runId) {
|
|
|
74
74
|
* `feedback_akm_dryrun_artifact_trap`).
|
|
75
75
|
*/
|
|
76
76
|
export function writeImproveResultFile(stashDir, runId, result, startedAt) {
|
|
77
|
-
|
|
78
|
-
try {
|
|
77
|
+
withStateDb((db) => {
|
|
79
78
|
const completedAt = new Date().toISOString();
|
|
80
79
|
// startedAt is the ISO timestamp captured at process launch (passed from the
|
|
81
80
|
// CLI entry point). If omitted, fall back to the run-id's embedded timestamp
|
|
@@ -95,15 +94,7 @@ export function writeImproveResultFile(stashDir, runId, result, startedAt) {
|
|
|
95
94
|
ok: Boolean(result.ok),
|
|
96
95
|
result,
|
|
97
96
|
});
|
|
98
|
-
}
|
|
99
|
-
finally {
|
|
100
|
-
try {
|
|
101
|
-
db.close();
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
// best-effort
|
|
105
|
-
}
|
|
106
|
-
}
|
|
97
|
+
});
|
|
107
98
|
return relativeImproveResultPath(runId);
|
|
108
99
|
}
|
|
109
100
|
/**
|
|
@@ -138,8 +129,7 @@ export function recordTerminatedImproveRun(stashDir, runId, startedAt, reason, c
|
|
|
138
129
|
...(ctx?.errorMessage ? { errorMessage: ctx.errorMessage } : {}),
|
|
139
130
|
},
|
|
140
131
|
};
|
|
141
|
-
|
|
142
|
-
try {
|
|
132
|
+
withStateDb((db) => {
|
|
143
133
|
recordImproveRun(db, {
|
|
144
134
|
id: runId,
|
|
145
135
|
startedAt,
|
|
@@ -160,13 +150,5 @@ export function recordTerminatedImproveRun(stashDir, runId, startedAt, reason, c
|
|
|
160
150
|
},
|
|
161
151
|
},
|
|
162
152
|
});
|
|
163
|
-
}
|
|
164
|
-
finally {
|
|
165
|
-
try {
|
|
166
|
-
db.close();
|
|
167
|
-
}
|
|
168
|
-
catch {
|
|
169
|
-
// best-effort
|
|
170
|
-
}
|
|
171
|
-
}
|
|
153
|
+
});
|
|
172
154
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
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
|
+
/** Signal -> {exit code, reason, ack message}. */
|
|
5
|
+
export const SIGNAL_TABLE = {
|
|
6
|
+
SIGTERM: { code: 143, reason: "SIGTERM", ack: true },
|
|
7
|
+
SIGINT: { code: 130, reason: "SIGINT", ack: true },
|
|
8
|
+
SIGHUP: { code: 129, reason: "SIGHUP", ack: false },
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Drive the improve-run lifecycle: register signal handlers, await `runWork`,
|
|
12
|
+
* and on clean completion remove the handlers and resolve with the result. The
|
|
13
|
+
* caller (improve-cli.ts) owns success-path result persistence + the final
|
|
14
|
+
* `exit(0)`; this function returns the work result so that choreography stays
|
|
15
|
+
* in the CLI exactly as before.
|
|
16
|
+
*
|
|
17
|
+
* Abnormal paths:
|
|
18
|
+
* - A registered signal fires -> persist terminated row (watchdog-guarded) ->
|
|
19
|
+
* optional ack -> `exit(code)`.
|
|
20
|
+
* - `runWork` rejects -> handlers are removed and the rejection propagates so
|
|
21
|
+
* the CLI's existing catch can persist `"exception"` and rethrow.
|
|
22
|
+
*/
|
|
23
|
+
export async function runImproveSession(opts, deps) {
|
|
24
|
+
const { signalSource, exit, onTerminate, ack } = deps;
|
|
25
|
+
const makeSignalHandler = (sig) => () => {
|
|
26
|
+
const { code, reason, ack: shouldAck } = SIGNAL_TABLE[sig];
|
|
27
|
+
// Hard-exit fallback: if the synchronous persist ever hangs (e.g. a stuck
|
|
28
|
+
// sqlite lock under contention), the watchdog still exits with the correct
|
|
29
|
+
// code instead of leaving a zombie process. .unref() keeps the timer from
|
|
30
|
+
// holding the loop open on the normal (fast) path.
|
|
31
|
+
const watchdog = setTimeout(() => exit(code), 2000);
|
|
32
|
+
if (typeof watchdog.unref === "function")
|
|
33
|
+
watchdog.unref();
|
|
34
|
+
try {
|
|
35
|
+
onTerminate(reason);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
clearTimeout(watchdog);
|
|
39
|
+
}
|
|
40
|
+
if (shouldAck)
|
|
41
|
+
ack?.(`received ${sig}`);
|
|
42
|
+
exit(code);
|
|
43
|
+
};
|
|
44
|
+
const sigtermHandler = makeSignalHandler("SIGTERM");
|
|
45
|
+
const sigintHandler = makeSignalHandler("SIGINT");
|
|
46
|
+
const sighupHandler = makeSignalHandler("SIGHUP");
|
|
47
|
+
signalSource.once("SIGTERM", sigtermHandler);
|
|
48
|
+
signalSource.once("SIGINT", sigintHandler);
|
|
49
|
+
signalSource.once("SIGHUP", sighupHandler);
|
|
50
|
+
try {
|
|
51
|
+
return await opts.runWork();
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
signalSource.removeListener("SIGTERM", sigtermHandler);
|
|
55
|
+
signalSource.removeListener("SIGINT", sigintHandler);
|
|
56
|
+
signalSource.removeListener("SIGHUP", sighupHandler);
|
|
57
|
+
}
|
|
58
|
+
}
|