akm-cli 0.9.2-alpha.2 → 0.9.2-alpha.3
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 +45 -1
- package/dist/indexer/walk/matchers.js +39 -2
- package/dist/scripts/akm-migrate-node.js +11 -2
- package/dist/scripts/akm-migrate.js +11 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,9 +6,53 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.2-alpha.3] - 2026-08-26
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Currency in prose no longer retypes an asset as a command** (#824). The
|
|
14
|
+
smart-Markdown classifier matched `$1`/`$2`/`$3` with a trailing word
|
|
15
|
+
boundary, and that boundary sits between the `2` and the comma in `$2,000` —
|
|
16
|
+
so any note quoting a price was indexed as a `command`, its ref moved to
|
|
17
|
+
`commands/<dir>/<slug>`, and it left its own namespace. Measured on a real
|
|
18
|
+
corpus, 3 of 51 memory documents were affected, and those 3 were exactly the
|
|
19
|
+
3 whose bodies matched. `$ARGUMENTS` is unambiguous and keeps its existing
|
|
20
|
+
precedence over a directory hint; the numeric placeholders now exclude a
|
|
21
|
+
following digit (or a `.`/`,` followed by one), and where they still
|
|
22
|
+
disagree with a directory that declares a type, the declaration wins. The
|
|
23
|
+
defect is present identically in 0.9.1 — it only became visible once the
|
|
24
|
+
0.9.2-alpha.2 retrieval work let mistyped assets surface in results.
|
|
25
|
+
|
|
26
|
+
### Documentation
|
|
27
|
+
|
|
28
|
+
- Recorded the 0.9.2 retrieval measurement in
|
|
29
|
+
`docs/plans/benchmark-tuning-findings.md` §2e (#825). Retrieval-only probes
|
|
30
|
+
with no model in the loop, identical corpora, only the CLI version differing:
|
|
31
|
+
LoCoMo zero-hit 75.0% -> 0.0% and evidence recall@5 0.154 -> 0.590;
|
|
32
|
+
LongMemEval zero-hit 100% -> 0.0% and recall@5 0.000 -> 1.000.
|
|
33
|
+
|
|
9
34
|
## [0.9.2-alpha.2] - 2026-08-25
|
|
10
35
|
|
|
11
|
-
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Retrieval:** relaxed zero-hit lexical queries centrally, stabilized
|
|
39
|
+
relaxed-retrieval quality, and preserved name quality through relaxed
|
|
40
|
+
ranking. This is the change measured in §2e above — it is what lifted the
|
|
41
|
+
retrieval ceiling that had floored memory-backed evaluation.
|
|
42
|
+
- **Indexing:** verify vec completeness before promotion; compare vec IDs as
|
|
43
|
+
exact sets; materialize vectors for targeted writes; make nested entry
|
|
44
|
+
mutation atomic; reconcile clean before final verification; restore static
|
|
45
|
+
embedding imports.
|
|
46
|
+
- **Markdown projection:** parse nested links safely, parse destination
|
|
47
|
+
phases, and project with stateful delimiters.
|
|
48
|
+
- **Sources:** reconcile local bundle updates and report incomplete filesystem
|
|
49
|
+
reconciliation.
|
|
50
|
+
- **Extract:** keep malformed model output retryable.
|
|
51
|
+
|
|
52
|
+
### Performance
|
|
53
|
+
|
|
54
|
+
- Keep targeted embedding selection narrow and preserve targeted vec
|
|
55
|
+
degradation.
|
|
12
56
|
|
|
13
57
|
## [0.9.2-alpha.1] - 2026-08-24
|
|
14
58
|
|
|
@@ -101,7 +101,21 @@ const DIR_TYPE_MAP = [
|
|
|
101
101
|
test: (ext) => ext === ".md",
|
|
102
102
|
},
|
|
103
103
|
];
|
|
104
|
-
|
|
104
|
+
/**
|
|
105
|
+
* `$ARGUMENTS` — unambiguous. Nothing else writes it, so finding it in a body
|
|
106
|
+
* is strong evidence of a command wherever the file lives.
|
|
107
|
+
*/
|
|
108
|
+
const ARGUMENTS_PLACEHOLDER_RE = /\$ARGUMENTS/;
|
|
109
|
+
/**
|
|
110
|
+
* `$1` / `$2` / `$3` — AMBIGUOUS, because ordinary prose writes money the same
|
|
111
|
+
* way. The old combined pattern used `\$[123]\b`, and `\b` sits between the
|
|
112
|
+
* `2` and the comma in `$2,000`, so every note quoting a price read as a
|
|
113
|
+
* command (#824). Excluding a following digit, or a `.`/`,` that is itself
|
|
114
|
+
* followed by a digit, rules out `$1,200` / `$2,000` / `$2.50` / `$12` while
|
|
115
|
+
* still matching `$1.` at the end of a sentence — a period with no digit after
|
|
116
|
+
* it is not part of a number.
|
|
117
|
+
*/
|
|
118
|
+
const NUMERIC_PLACEHOLDER_RE = /\$[123](?!\d|[.,]\d)/;
|
|
105
119
|
const SMART_MD_FACTS = {
|
|
106
120
|
workflow: { type: "workflow", specificity: 19 },
|
|
107
121
|
toolsAgent: { type: "agent", specificity: 20 },
|
|
@@ -141,6 +155,17 @@ function matchDirectoryHint(dirName, ctx, specificity) {
|
|
|
141
155
|
}
|
|
142
156
|
return null;
|
|
143
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* True when some ancestor directory already DECLARES this file's type via
|
|
160
|
+
* `DIR_TYPE_MAP` — the same walk `classifyByDirectory` performs. Derived from
|
|
161
|
+
* path fields alone, so `smartMdPathCandidates` can apply it without reading
|
|
162
|
+
* bytes.
|
|
163
|
+
*/
|
|
164
|
+
function hasDeclaredDirType(ctx) {
|
|
165
|
+
if (isNestedSkillResource(ctx))
|
|
166
|
+
return false;
|
|
167
|
+
return ctx.ancestorDirs.some((dir) => matchDirectoryHint(dir, ctx, 0) !== null);
|
|
168
|
+
}
|
|
144
169
|
function classifyByExtension(ctx) {
|
|
145
170
|
if (ctx.fileName === "SKILL.md") {
|
|
146
171
|
return { type: "skill", specificity: 25 };
|
|
@@ -204,7 +229,19 @@ function classifyBySmartMd(ctx) {
|
|
|
204
229
|
return SMART_MD_FACTS.command;
|
|
205
230
|
}
|
|
206
231
|
}
|
|
207
|
-
|
|
232
|
+
// `$ARGUMENTS` is unambiguous, so it keeps its long-standing precedence: a
|
|
233
|
+
// command dropped under `knowledge/` is still found as a command.
|
|
234
|
+
if (ARGUMENTS_PLACEHOLDER_RE.test(body)) {
|
|
235
|
+
return SMART_MD_FACTS.command;
|
|
236
|
+
}
|
|
237
|
+
// A NUMERIC placeholder is a guess, and a typed directory is a declaration.
|
|
238
|
+
// Where the two disagree the declaration wins — otherwise a note that merely
|
|
239
|
+
// quotes a price is retyped, which is #824: `memories/*.md` mentioning
|
|
240
|
+
// `$2,000` were indexed as commands, their refs moved to
|
|
241
|
+
// `commands/memories/<slug>`, and they left the `memories/` namespace
|
|
242
|
+
// entirely. Outside a typed directory there is no declaration to defer to,
|
|
243
|
+
// so the guess still stands.
|
|
244
|
+
if (NUMERIC_PLACEHOLDER_RE.test(body) && !hasDeclaredDirType(ctx)) {
|
|
208
245
|
return SMART_MD_FACTS.command;
|
|
209
246
|
}
|
|
210
247
|
if (fm && "model" in fm) {
|
|
@@ -14421,7 +14421,8 @@ var DIR_TYPE_MAP = [
|
|
|
14421
14421
|
test: (ext) => ext === ".md"
|
|
14422
14422
|
}
|
|
14423
14423
|
];
|
|
14424
|
-
var
|
|
14424
|
+
var ARGUMENTS_PLACEHOLDER_RE = /\$ARGUMENTS/;
|
|
14425
|
+
var NUMERIC_PLACEHOLDER_RE = /\$[123](?!\d|[.,]\d)/;
|
|
14425
14426
|
var SMART_MD_FACTS = {
|
|
14426
14427
|
workflow: { type: "workflow", specificity: 19 },
|
|
14427
14428
|
toolsAgent: { type: "agent", specificity: 20 },
|
|
@@ -14449,6 +14450,11 @@ function matchDirectoryHint(dirName, ctx, specificity) {
|
|
|
14449
14450
|
}
|
|
14450
14451
|
return null;
|
|
14451
14452
|
}
|
|
14453
|
+
function hasDeclaredDirType(ctx) {
|
|
14454
|
+
if (isNestedSkillResource(ctx))
|
|
14455
|
+
return false;
|
|
14456
|
+
return ctx.ancestorDirs.some((dir) => matchDirectoryHint(dir, ctx, 0) !== null);
|
|
14457
|
+
}
|
|
14452
14458
|
function classifyByExtension(ctx) {
|
|
14453
14459
|
if (ctx.fileName === "SKILL.md") {
|
|
14454
14460
|
return { type: "skill", specificity: 25 };
|
|
@@ -14498,7 +14504,10 @@ function classifyBySmartMd(ctx) {
|
|
|
14498
14504
|
return SMART_MD_FACTS.command;
|
|
14499
14505
|
}
|
|
14500
14506
|
}
|
|
14501
|
-
if (
|
|
14507
|
+
if (ARGUMENTS_PLACEHOLDER_RE.test(body)) {
|
|
14508
|
+
return SMART_MD_FACTS.command;
|
|
14509
|
+
}
|
|
14510
|
+
if (NUMERIC_PLACEHOLDER_RE.test(body) && !hasDeclaredDirType(ctx)) {
|
|
14502
14511
|
return SMART_MD_FACTS.command;
|
|
14503
14512
|
}
|
|
14504
14513
|
if (fm && "model" in fm) {
|
|
@@ -14352,7 +14352,8 @@ var DIR_TYPE_MAP = [
|
|
|
14352
14352
|
test: (ext) => ext === ".md"
|
|
14353
14353
|
}
|
|
14354
14354
|
];
|
|
14355
|
-
var
|
|
14355
|
+
var ARGUMENTS_PLACEHOLDER_RE = /\$ARGUMENTS/;
|
|
14356
|
+
var NUMERIC_PLACEHOLDER_RE = /\$[123](?!\d|[.,]\d)/;
|
|
14356
14357
|
var SMART_MD_FACTS = {
|
|
14357
14358
|
workflow: { type: "workflow", specificity: 19 },
|
|
14358
14359
|
toolsAgent: { type: "agent", specificity: 20 },
|
|
@@ -14380,6 +14381,11 @@ function matchDirectoryHint(dirName, ctx, specificity) {
|
|
|
14380
14381
|
}
|
|
14381
14382
|
return null;
|
|
14382
14383
|
}
|
|
14384
|
+
function hasDeclaredDirType(ctx) {
|
|
14385
|
+
if (isNestedSkillResource(ctx))
|
|
14386
|
+
return false;
|
|
14387
|
+
return ctx.ancestorDirs.some((dir) => matchDirectoryHint(dir, ctx, 0) !== null);
|
|
14388
|
+
}
|
|
14383
14389
|
function classifyByExtension(ctx) {
|
|
14384
14390
|
if (ctx.fileName === "SKILL.md") {
|
|
14385
14391
|
return { type: "skill", specificity: 25 };
|
|
@@ -14429,7 +14435,10 @@ function classifyBySmartMd(ctx) {
|
|
|
14429
14435
|
return SMART_MD_FACTS.command;
|
|
14430
14436
|
}
|
|
14431
14437
|
}
|
|
14432
|
-
if (
|
|
14438
|
+
if (ARGUMENTS_PLACEHOLDER_RE.test(body)) {
|
|
14439
|
+
return SMART_MD_FACTS.command;
|
|
14440
|
+
}
|
|
14441
|
+
if (NUMERIC_PLACEHOLDER_RE.test(body) && !hasDeclaredDirType(ctx)) {
|
|
14433
14442
|
return SMART_MD_FACTS.command;
|
|
14434
14443
|
}
|
|
14435
14444
|
if (fm && "model" in fm) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.9.2-alpha.
|
|
3
|
+
"version": "0.9.2-alpha.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cursor.",
|
|
6
6
|
"keywords": [
|