akm-cli 0.9.0-rc.2 → 0.9.0-rc.4
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 +40 -12
- package/README.md +7 -8
- package/SECURITY.md +5 -3
- package/dist/akm +44 -33
- package/dist/akm-migrate-storage +44 -33
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/improve-strategies/catchup.json +3 -1
- package/dist/assets/improve-strategies/consolidate.json +3 -1
- package/dist/assets/improve-strategies/frequent.json +3 -1
- package/dist/assets/improve-strategies/graph-refresh.json +3 -1
- package/dist/assets/improve-strategies/memory-focus.json +4 -1
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -0
- package/dist/assets/improve-strategies/quick.json +3 -1
- package/dist/assets/improve-strategies/recombine-only.json +2 -0
- package/dist/assets/improve-strategies/reflect-distill.json +1 -0
- package/dist/assets/improve-strategies/synthesize.json +2 -0
- package/dist/assets/tasks/core/backup.yml +2 -2
- package/dist/cli/config-migrate.js +554 -26
- package/dist/cli.js +28 -11
- package/dist/commands/backup-cli.js +6 -4
- package/dist/commands/config-cli.js +10 -3
- package/dist/commands/feedback-cli.js +24 -7
- package/dist/commands/health/checks.js +94 -15
- package/dist/commands/health/html-report.js +23 -2
- package/dist/commands/health/improve-metrics.js +45 -6
- package/dist/commands/health/md-report.js +10 -1
- package/dist/commands/health/surfaces.js +2 -1
- package/dist/commands/health/windows.js +1 -1
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/anti-collapse.js +3 -3
- package/dist/commands/improve/collapse-detector.js +5 -5
- package/dist/commands/improve/consolidate.js +123 -66
- package/dist/commands/improve/distill/promote-memory.js +8 -6
- package/dist/commands/improve/distill/quality-gate.js +1 -1
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +32 -26
- package/dist/commands/improve/distill.js +52 -36
- package/dist/commands/improve/eligibility.js +9 -8
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +43 -11
- package/dist/commands/improve/improve-auto-accept.js +14 -28
- package/dist/commands/improve/improve-cli.js +4 -2
- package/dist/commands/improve/improve-strategies.js +2 -1
- package/dist/commands/improve/improve.js +49 -8
- package/dist/commands/improve/loop-stages.js +11 -6
- package/dist/commands/improve/preparation.js +51 -17
- package/dist/commands/improve/procedural.js +10 -6
- package/dist/commands/improve/recombine.js +31 -7
- package/dist/commands/improve/reflect.js +24 -14
- package/dist/commands/improve/salience.js +5 -1
- package/dist/commands/improve/source-identity.js +43 -0
- package/dist/commands/migrate-cli.js +36 -0
- package/dist/commands/mv-cli.js +647 -258
- package/dist/commands/proposal/drain.js +16 -4
- package/dist/commands/proposal/proposal-cli.js +3 -2
- package/dist/commands/proposal/proposal.js +16 -55
- package/dist/commands/proposal/repository.js +664 -58
- package/dist/commands/read/curate.js +4 -2
- package/dist/commands/read/knowledge.js +4 -1
- package/dist/commands/read/search.js +6 -2
- package/dist/commands/read/show.js +8 -7
- package/dist/commands/sources/self-update.js +156 -112
- package/dist/commands/sources/sources-cli.js +7 -2
- package/dist/commands/tasks/default-tasks.js +5 -5
- package/dist/commands/tasks/tasks-cli.js +7 -3
- package/dist/commands/tasks/tasks.js +261 -68
- package/dist/core/common.js +36 -3
- package/dist/core/config/config-io.js +2 -2
- package/dist/core/config/config-schema.js +15 -3
- package/dist/core/config/config.js +14 -13
- package/dist/core/file-lock.js +2 -2
- package/dist/core/improve-result.js +87 -7
- package/dist/core/migration-backup.js +816 -171
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/state/migrations.js +4 -7
- package/dist/core/state-db.js +23 -7
- package/dist/core/write-source.js +86 -18
- package/dist/indexer/db/db.js +109 -53
- package/dist/indexer/index-writer-lock.js +38 -37
- package/dist/indexer/index-written-assets.js +73 -56
- package/dist/indexer/indexer.js +5 -1
- package/dist/indexer/search/search-source.js +2 -2
- package/dist/indexer/usage/usage-events.js +8 -2
- package/dist/integrations/agent/engine-resolution.js +14 -7
- package/dist/scripts/migrate-storage.js +887 -992
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +494 -574
- package/dist/setup/detected-engines.js +7 -13
- package/dist/setup/engine-config.js +14 -4
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +1 -1
- package/dist/setup/steps/tasks.js +1 -1
- package/dist/sources/providers/git-stash.js +58 -21
- package/dist/sources/providers/git.js +1 -1
- package/dist/storage/engines/sqlite-migrations.js +138 -3
- package/dist/storage/repositories/events-repository.js +24 -0
- package/dist/storage/repositories/proposals-repository.js +14 -0
- package/dist/storage/repositories/task-history-repository.js +30 -3
- package/dist/tasks/backends/cron.js +71 -38
- package/dist/tasks/backends/exec-utils.js +55 -3
- package/dist/tasks/backends/launchd.js +241 -50
- package/dist/tasks/backends/schtasks.js +434 -59
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +2 -0
- package/dist/tasks/parser.js +142 -6
- package/dist/tasks/resolve-akm-bin.js +19 -4
- package/dist/tasks/runner.js +258 -93
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +86 -0
- package/dist/tasks/task-id.js +37 -0
- package/dist/workflows/db.js +24 -13
- package/dist/workflows/validator.js +24 -2
- package/docs/README.md +103 -0
- package/docs/migration/release-notes/0.9.0.md +28 -9
- package/docs/migration/v0.8-to-v0.9.md +186 -26
- package/package.json +2 -3
package/dist/core/file-lock.js
CHANGED
|
@@ -5,7 +5,7 @@ import { randomUUID } from "node:crypto";
|
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { openDatabase } from "../storage/database.js";
|
|
8
|
-
import { isProcessAlive } from "./common.js";
|
|
8
|
+
import { isProcessAlive, MAX_LOCK_METADATA_BYTES, readTextFileDescriptorWithLimit } from "./common.js";
|
|
9
9
|
function readLockSnapshot(lockPath) {
|
|
10
10
|
let fd;
|
|
11
11
|
try {
|
|
@@ -17,7 +17,7 @@ function readLockSnapshot(lockPath) {
|
|
|
17
17
|
throw err;
|
|
18
18
|
}
|
|
19
19
|
try {
|
|
20
|
-
const rawContent =
|
|
20
|
+
const rawContent = readTextFileDescriptorWithLimit(fd, MAX_LOCK_METADATA_BYTES, "Lock metadata", lockPath);
|
|
21
21
|
const stat = fs.fstatSync(fd);
|
|
22
22
|
return {
|
|
23
23
|
rawContent,
|
|
@@ -44,8 +44,26 @@ const COMMON_FIELDS = [
|
|
|
44
44
|
"sync",
|
|
45
45
|
"terminated",
|
|
46
46
|
];
|
|
47
|
-
const V1_FIELDS = new Set([...COMMON_FIELDS, "profile", "profileFilteredRefs"]);
|
|
47
|
+
const V1_FIELDS = new Set([...COMMON_FIELDS, "profile", "profileFilteredRefs", "stalenessDetection"]);
|
|
48
48
|
const V2_FIELDS = new Set([...COMMON_FIELDS, "strategy", "strategyFilteredRefs"]);
|
|
49
|
+
const STALENESS_DETECTION_FIELDS = new Set([
|
|
50
|
+
"considered",
|
|
51
|
+
"deprecated",
|
|
52
|
+
"confirmed",
|
|
53
|
+
"skipped",
|
|
54
|
+
"durationMs",
|
|
55
|
+
"warnings",
|
|
56
|
+
]);
|
|
57
|
+
const INTERRUPTED_V1_FIELDS = new Set([
|
|
58
|
+
"schemaVersion",
|
|
59
|
+
"ok",
|
|
60
|
+
"profile",
|
|
61
|
+
"scope",
|
|
62
|
+
"dryRun",
|
|
63
|
+
"plannedRefs",
|
|
64
|
+
"actions",
|
|
65
|
+
"terminated",
|
|
66
|
+
]);
|
|
49
67
|
function fail(message) {
|
|
50
68
|
throw new Error(`invalid improve-result envelope: ${message}`);
|
|
51
69
|
}
|
|
@@ -57,6 +75,33 @@ function requireExactFields(value, allowed) {
|
|
|
57
75
|
if (unknown.length > 0)
|
|
58
76
|
fail(`unknown field${unknown.length === 1 ? "" : "s"}: ${unknown.sort().join(", ")}`);
|
|
59
77
|
}
|
|
78
|
+
function isKnownInterruptedV1Partial(value) {
|
|
79
|
+
if (Object.keys(value).some((key) => !INTERRUPTED_V1_FIELDS.has(key)))
|
|
80
|
+
return false;
|
|
81
|
+
if (value.ok !== false || typeof value.dryRun !== "boolean")
|
|
82
|
+
return false;
|
|
83
|
+
if (value.profile !== undefined && typeof value.profile !== "string")
|
|
84
|
+
return false;
|
|
85
|
+
if (!Array.isArray(value.plannedRefs) || value.plannedRefs.length !== 0)
|
|
86
|
+
return false;
|
|
87
|
+
if (!Array.isArray(value.actions) || value.actions.length !== 0)
|
|
88
|
+
return false;
|
|
89
|
+
if (!isRecord(value.scope))
|
|
90
|
+
return false;
|
|
91
|
+
if (Object.keys(value.scope).some((key) => key !== "mode" && key !== "value"))
|
|
92
|
+
return false;
|
|
93
|
+
if (value.scope.mode !== "all" && value.scope.mode !== "type" && value.scope.mode !== "ref")
|
|
94
|
+
return false;
|
|
95
|
+
if (value.scope.value !== undefined && typeof value.scope.value !== "string")
|
|
96
|
+
return false;
|
|
97
|
+
if (!isRecord(value.terminated))
|
|
98
|
+
return false;
|
|
99
|
+
if (Object.keys(value.terminated).some((key) => !["reason", "at", "errorMessage"].includes(key)))
|
|
100
|
+
return false;
|
|
101
|
+
if (typeof value.terminated.reason !== "string" || typeof value.terminated.at !== "string")
|
|
102
|
+
return false;
|
|
103
|
+
return value.terminated.errorMessage === undefined || typeof value.terminated.errorMessage === "string";
|
|
104
|
+
}
|
|
60
105
|
function validateCommon(value) {
|
|
61
106
|
if (typeof value.ok !== "boolean")
|
|
62
107
|
fail("ok must be a boolean");
|
|
@@ -131,6 +176,32 @@ function validateCommon(value) {
|
|
|
131
176
|
if (value[field] !== undefined && !isRecord(value[field]))
|
|
132
177
|
fail(`${field} must be an object`);
|
|
133
178
|
}
|
|
179
|
+
if (isRecord(value.terminated)) {
|
|
180
|
+
requireExactFields(value.terminated, new Set(["reason", "at", "errorMessage"]));
|
|
181
|
+
if (typeof value.terminated.reason !== "string" || typeof value.terminated.at !== "string") {
|
|
182
|
+
fail("terminated.reason and terminated.at must be strings");
|
|
183
|
+
}
|
|
184
|
+
if (value.terminated.errorMessage !== undefined && typeof value.terminated.errorMessage !== "string") {
|
|
185
|
+
fail("terminated.errorMessage must be a string when present");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function validateV1StalenessDetection(value) {
|
|
190
|
+
if (value === undefined)
|
|
191
|
+
return;
|
|
192
|
+
if (!isRecord(value))
|
|
193
|
+
fail("stalenessDetection must be an object");
|
|
194
|
+
const unknown = Object.keys(value).filter((key) => !STALENESS_DETECTION_FIELDS.has(key));
|
|
195
|
+
if (unknown.length > 0) {
|
|
196
|
+
fail(`stalenessDetection has unknown field${unknown.length === 1 ? "" : "s"}: ${unknown.sort().join(", ")}`);
|
|
197
|
+
}
|
|
198
|
+
for (const field of ["considered", "deprecated", "confirmed", "skipped", "durationMs"]) {
|
|
199
|
+
if (typeof value[field] !== "number")
|
|
200
|
+
fail(`stalenessDetection.${field} must be a number`);
|
|
201
|
+
}
|
|
202
|
+
if (!Array.isArray(value.warnings) || value.warnings.some((warning) => typeof warning !== "string")) {
|
|
203
|
+
fail("stalenessDetection.warnings must be an array of strings");
|
|
204
|
+
}
|
|
134
205
|
}
|
|
135
206
|
/** Decode the persisted public v1/v2 contract without guessing across versions. */
|
|
136
207
|
export function decodeImproveResult(input) {
|
|
@@ -146,17 +217,25 @@ export function decodeImproveResult(input) {
|
|
|
146
217
|
if (!isRecord(parsed))
|
|
147
218
|
fail("root must be an object");
|
|
148
219
|
if (parsed.schemaVersion === 1) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
220
|
+
let normalized = parsed;
|
|
221
|
+
let normalizedLegacyPartial = false;
|
|
222
|
+
if (normalized.memorySummary === undefined && isKnownInterruptedV1Partial(normalized)) {
|
|
223
|
+
normalized = { ...normalized, memorySummary: { eligible: 0, derived: 0 } };
|
|
224
|
+
normalizedLegacyPartial = true;
|
|
225
|
+
}
|
|
226
|
+
requireExactFields(normalized, V1_FIELDS);
|
|
227
|
+
validateCommon(normalized);
|
|
228
|
+
validateV1StalenessDetection(normalized.stalenessDetection);
|
|
229
|
+
if (normalized.profile !== undefined && typeof normalized.profile !== "string")
|
|
152
230
|
fail("profile must be a string");
|
|
153
|
-
if (
|
|
231
|
+
if (normalized.profileFilteredRefs !== undefined && !Array.isArray(normalized.profileFilteredRefs)) {
|
|
154
232
|
fail("profileFilteredRefs must be an array");
|
|
155
233
|
}
|
|
156
234
|
return {
|
|
157
|
-
envelope:
|
|
235
|
+
envelope: normalized,
|
|
158
236
|
strategy: null,
|
|
159
|
-
legacyProfile: typeof
|
|
237
|
+
legacyProfile: typeof normalized.profile === "string" ? normalized.profile : null,
|
|
238
|
+
normalizedLegacyPartial,
|
|
160
239
|
};
|
|
161
240
|
}
|
|
162
241
|
if (parsed.schemaVersion === 2) {
|
|
@@ -172,6 +251,7 @@ export function decodeImproveResult(input) {
|
|
|
172
251
|
envelope: parsed,
|
|
173
252
|
strategy: parsed.strategy,
|
|
174
253
|
legacyProfile: null,
|
|
254
|
+
normalizedLegacyPartial: false,
|
|
175
255
|
};
|
|
176
256
|
}
|
|
177
257
|
fail(`unsupported schemaVersion: ${String(parsed.schemaVersion)}`);
|