akm-cli 0.9.0-beta.30 → 0.9.0-beta.31
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 +13 -0
- package/dist/commands/improve/recombine.js +65 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@ 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.0-beta.31] — 2026-06-20
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **#632 — recombine now filters junk tags structurally.** Frontmatter tags that
|
|
14
|
+
are pure numbers, dates (`20260529`), short hex hashes (`002c624c`), version
|
|
15
|
+
strings (`0.8.0`, `v2`), single chars, or common English stopwords (`is`, `the`,
|
|
16
|
+
`for`, `when`, …) carry no topical signal and never form a recombine cluster.
|
|
17
|
+
Unlike `excludeTags` (a fixed project list), this catches the OPEN-ENDED junk —
|
|
18
|
+
every new date or commit hash — with no config upkeep. Exposed as `isJunkTag`.
|
|
19
|
+
On the live stash this turns the recombine cluster set from generic 66–171-member
|
|
20
|
+
buckets into tight topical clusters (`auth`, `architecture`, `patterns`, …).
|
|
21
|
+
|
|
9
22
|
## [0.9.0-beta.30] — 2026-06-20
|
|
10
23
|
|
|
11
24
|
### Changed / Fixed
|
|
@@ -67,6 +67,69 @@ const DEFAULT_CONFIRM_THRESHOLD = 2;
|
|
|
67
67
|
*/
|
|
68
68
|
const DEFAULT_RECOMBINE_OVERLAP = 0.7;
|
|
69
69
|
// ── Clustering by relatedness (NOT similarity) ────────────────────────────────
|
|
70
|
+
/**
|
|
71
|
+
* #632 — English stopwords that occasionally leak into frontmatter tags
|
|
72
|
+
* (`is`, `the`, `for`, …). They carry no topical signal, so a cluster keyed on
|
|
73
|
+
* one is meaningless. Lowercased; matched case-insensitively.
|
|
74
|
+
*/
|
|
75
|
+
const JUNK_STOPWORD_TAGS = new Set([
|
|
76
|
+
"a",
|
|
77
|
+
"an",
|
|
78
|
+
"and",
|
|
79
|
+
"the",
|
|
80
|
+
"to",
|
|
81
|
+
"of",
|
|
82
|
+
"in",
|
|
83
|
+
"on",
|
|
84
|
+
"for",
|
|
85
|
+
"is",
|
|
86
|
+
"are",
|
|
87
|
+
"be",
|
|
88
|
+
"no",
|
|
89
|
+
"not",
|
|
90
|
+
"or",
|
|
91
|
+
"if",
|
|
92
|
+
"it",
|
|
93
|
+
"as",
|
|
94
|
+
"at",
|
|
95
|
+
"by",
|
|
96
|
+
"we",
|
|
97
|
+
"us",
|
|
98
|
+
"do",
|
|
99
|
+
"so",
|
|
100
|
+
"when",
|
|
101
|
+
"then",
|
|
102
|
+
"than",
|
|
103
|
+
"with",
|
|
104
|
+
"from",
|
|
105
|
+
"this",
|
|
106
|
+
"that",
|
|
107
|
+
"uses",
|
|
108
|
+
"use",
|
|
109
|
+
"via",
|
|
110
|
+
]);
|
|
111
|
+
/**
|
|
112
|
+
* #632 — a tag carries no clustering signal (and must be skipped) when it is
|
|
113
|
+
* purely a number / date / hash / version string, a single char, or a common
|
|
114
|
+
* stopword. Unlike `excludeTags` (a fixed project list), this catches the
|
|
115
|
+
* OPEN-ENDED junk — every new date or commit hash — without config upkeep.
|
|
116
|
+
*/
|
|
117
|
+
export function isJunkTag(tag) {
|
|
118
|
+
const t = tag.trim().toLowerCase();
|
|
119
|
+
if (t.length <= 1)
|
|
120
|
+
return true;
|
|
121
|
+
if (JUNK_STOPWORD_TAGS.has(t))
|
|
122
|
+
return true;
|
|
123
|
+
if (/^\d+$/.test(t))
|
|
124
|
+
return true; // pure numbers + dates: 2026, 05, 23, 20260529
|
|
125
|
+
if (/^v?\d+(?:\.\d+)+$/.test(t))
|
|
126
|
+
return true; // versions: 0.8.0, v1.2
|
|
127
|
+
if (/^v\d+$/.test(t))
|
|
128
|
+
return true; // v0, v2
|
|
129
|
+
if (/^[0-9a-f]{4,}$/.test(t) && /\d/.test(t))
|
|
130
|
+
return true; // short hex hashes: 002c624c, 192d
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
70
133
|
/**
|
|
71
134
|
* Build relatedness clusters from the memory pool. Clustering is driven purely
|
|
72
135
|
* by shared tags / graph entities — it MUST NOT use embedding similarity, so
|
|
@@ -114,6 +177,8 @@ export function buildRelatednessClusters(entries, opts) {
|
|
|
114
177
|
for (const tag of entry.entry.tags ?? []) {
|
|
115
178
|
if (excludeTags.has(tag))
|
|
116
179
|
continue;
|
|
180
|
+
if (isJunkTag(tag))
|
|
181
|
+
continue; // #632 — skip numeric/date/hash/version/stopword junk
|
|
117
182
|
add(`tag:${tag}`, entry);
|
|
118
183
|
}
|
|
119
184
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "akm-cli",
|
|
3
|
-
"version": "0.9.0-beta.
|
|
3
|
+
"version": "0.9.0-beta.31",
|
|
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": [
|