akm-cli 0.8.5 → 0.8.7
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
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
6
|
|
|
7
|
+
## [0.8.7] - 2026-06-09
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`incrementalSince` duration strings were silently ignored.** Values like
|
|
12
|
+
`"30m"`, `"24h"`, `"7d"` were passed raw to `narrowToIncrementalCandidates`,
|
|
13
|
+
which compared them against ISO timestamps via string sort. All `2026-...`
|
|
14
|
+
timestamps are lexicographically less than `"30m"` (`'2' < '3'`) and `"24h"`
|
|
15
|
+
(`"20" < "24"`), so `isChanged()` always returned `false` and the candidate
|
|
16
|
+
pool was silently emptied rather than filtered to the window. The fix adds
|
|
17
|
+
`parseSinceToIso()`, which resolves human duration strings to absolute ISO
|
|
18
|
+
timestamps before comparison. Values that already look like ISO timestamps
|
|
19
|
+
are passed through unchanged.
|
|
20
|
+
|
|
21
|
+
## [0.8.6] - 2026-06-09
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **`consolidate.incrementalSince` profile config field.** Setting
|
|
26
|
+
`incrementalSince: "7d"` (or any duration string) in the `consolidate` block
|
|
27
|
+
of an improve profile narrows the candidate pool to memories modified within
|
|
28
|
+
that window plus their top-5 graph neighbours, keeping each pass focused on
|
|
29
|
+
recent changes. This makes it practical to run consolidation more often than
|
|
30
|
+
once per day (e.g. via `akm-improve-consolidate` every 4 h) without
|
|
31
|
+
re-scanning the full pool every time. The nightly default profile leaves this
|
|
32
|
+
unset (full-pool sweep, same as before). The `incrementalSince` option already
|
|
33
|
+
existed in `akmConsolidate()` but was hardcoded off at the call site; the
|
|
34
|
+
field is now surfaced in the config schema and read from the profile.
|
|
35
|
+
|
|
7
36
|
## [0.8.5] - 2026-06-09
|
|
8
37
|
|
|
9
38
|
### Fixed
|
|
@@ -1980,10 +1980,23 @@ async function checkPreEmitDedup(opts) {
|
|
|
1980
1980
|
* everything changed or the index can't answer (fail-open to preserve merge
|
|
1981
1981
|
* correctness). `since` is an ISO timestamp.
|
|
1982
1982
|
*/
|
|
1983
|
+
/**
|
|
1984
|
+
* Parse a human-readable duration string (e.g. "30m", "24h", "7d") to an ISO
|
|
1985
|
+
* timestamp representing `now - duration`. Returns the input unchanged when it
|
|
1986
|
+
* doesn't match the pattern (assumed to already be an ISO timestamp).
|
|
1987
|
+
*/
|
|
1988
|
+
function parseSinceToIso(since) {
|
|
1989
|
+
const m = since.match(/^(\d+)(m|h|d)$/);
|
|
1990
|
+
if (!m)
|
|
1991
|
+
return since;
|
|
1992
|
+
const multiplier = { m: 60_000, h: 3_600_000, d: 86_400_000 }[m[2]];
|
|
1993
|
+
return new Date(Date.now() - parseInt(m[1], 10) * multiplier).toISOString();
|
|
1994
|
+
}
|
|
1983
1995
|
export function narrowToIncrementalCandidates(memories, since, warnings) {
|
|
1996
|
+
const sinceIso = parseSinceToIso(since);
|
|
1984
1997
|
const isChanged = (m) => {
|
|
1985
1998
|
try {
|
|
1986
|
-
return fs.statSync(m.filePath).mtime.toISOString() >
|
|
1999
|
+
return fs.statSync(m.filePath).mtime.toISOString() > sinceIso;
|
|
1987
2000
|
}
|
|
1988
2001
|
catch {
|
|
1989
2002
|
return true; // never silently drop a memory we cannot stat
|
|
@@ -2025,7 +2038,7 @@ export function narrowToIncrementalCandidates(memories, since, warnings) {
|
|
|
2025
2038
|
closeDatabase(db);
|
|
2026
2039
|
}
|
|
2027
2040
|
const candidates = memories.filter((m) => keep.has(m.name));
|
|
2028
|
-
warnings.push(`Incremental consolidation: ${changed.length} changed + neighbours → ${candidates.length}/${memories.length} memories considered (since ${since}).`);
|
|
2041
|
+
warnings.push(`Incremental consolidation: ${changed.length} changed + neighbours → ${candidates.length}/${memories.length} memories considered (since ${since}${sinceIso !== since ? ` = ${sinceIso}` : ""}).`);
|
|
2029
2042
|
return candidates;
|
|
2030
2043
|
}
|
|
2031
2044
|
function loadMemoriesForSource(source, stashDir, warnings) {
|
package/dist/commands/improve.js
CHANGED
|
@@ -2162,13 +2162,11 @@ async function runImprovePostLoopStage(args) {
|
|
|
2162
2162
|
// Tie consolidate proposals back to this improve invocation so
|
|
2163
2163
|
// accept-rate-per-run aggregation works. Mirrors reflect/propose/extract.
|
|
2164
2164
|
sourceRun: `consolidate-${Date.now()}`,
|
|
2165
|
-
//
|
|
2166
|
-
//
|
|
2167
|
-
//
|
|
2168
|
-
//
|
|
2169
|
-
|
|
2170
|
-
// was a band-aid for an every-30-min consolidation cadence that the profile
|
|
2171
|
-
// split has since eliminated.) lastConsolidateTs still gates whether we run.
|
|
2165
|
+
// incrementalSince: when set in the profile config, narrows the candidate
|
|
2166
|
+
// pool to memories modified within that window + their graph neighbours,
|
|
2167
|
+
// keeping each pass focused on recent changes. Omit for a full-pool sweep
|
|
2168
|
+
// (default for nightly passes). See config-schema.ts for guidance.
|
|
2169
|
+
incrementalSince: improveProfile?.processes?.consolidate?.incrementalSince,
|
|
2172
2170
|
maxChunkSize: improveProfile?.processes?.consolidate?.maxChunkSize,
|
|
2173
2171
|
// Honor profile.autoAccept (already merged into options.autoAccept at the
|
|
2174
2172
|
// top of akmImprove). The CLI parser always supplies 90 when --auto-accept
|
|
@@ -132,6 +132,12 @@ export const ImproveProcessConfigSchema = z
|
|
|
132
132
|
defaultSince: z.string().min(1).optional(),
|
|
133
133
|
maxTotalChars: positiveInt.optional(),
|
|
134
134
|
maxChunkSize: z.number().int().min(1).max(50).optional(),
|
|
135
|
+
// Consolidate process: when set, narrows the candidate pool to memories
|
|
136
|
+
// modified within this window (e.g. "7d", "48h") plus their graph
|
|
137
|
+
// neighbours. Useful when consolidation runs more than once per day —
|
|
138
|
+
// keeps each pass focused on recent changes without re-scanning the full
|
|
139
|
+
// pool. Leave unset (full-pool sweep) for the nightly default pass.
|
|
140
|
+
incrementalSince: z.string().min(1).optional(),
|
|
135
141
|
// Triage process config (only meaningful for the `triage` process)
|
|
136
142
|
applyMode: z.enum(["queue", "promote"]).optional(),
|
|
137
143
|
policy: z.string().min(1).optional(),
|
|
@@ -14521,6 +14521,7 @@ var init_config_schema = __esm(() => {
|
|
|
14521
14521
|
defaultSince: exports_external.string().min(1).optional(),
|
|
14522
14522
|
maxTotalChars: positiveInt.optional(),
|
|
14523
14523
|
maxChunkSize: exports_external.number().int().min(1).max(50).optional(),
|
|
14524
|
+
incrementalSince: exports_external.string().min(1).optional(),
|
|
14524
14525
|
applyMode: exports_external.enum(["queue", "promote"]).optional(),
|
|
14525
14526
|
policy: exports_external.string().min(1).optional(),
|
|
14526
14527
|
maxAcceptsPerRun: positiveInt.optional(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
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": [
|