akm-cli 0.9.16-alpha.1 → 0.9.16

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.
Files changed (147) hide show
  1. package/CHANGELOG.md +56 -132
  2. package/dist/assets/hints/cli-hints-full.md +13 -6
  3. package/dist/assets/tasks/core/index-refresh.yml +1 -1
  4. package/dist/assets/tasks/improve/akm-improve-catchup.yml +3 -6
  5. package/dist/cli/retired-commands.js +0 -4
  6. package/dist/cli/unknown-flags.js +3 -36
  7. package/dist/commands/env/env-binding.js +4 -4
  8. package/dist/commands/env/env-cli.js +3 -3
  9. package/dist/commands/improve/collapse-detector.js +2 -2
  10. package/dist/commands/improve/consolidate.js +4 -6
  11. package/dist/commands/improve/improve-cli.js +20 -15
  12. package/dist/commands/improve/reflect.js +23 -2
  13. package/dist/commands/lint/base-linter.js +9 -0
  14. package/dist/commands/lint/env-key-rules.js +2 -2
  15. package/dist/commands/proposal/propose.js +15 -1
  16. package/dist/commands/proposal/repository.js +3 -12
  17. package/dist/commands/proposal/validators/proposal-quality-validators.js +40 -3
  18. package/dist/commands/proposal/validators/proposal-validators.js +5 -4
  19. package/dist/commands/read/curate.js +44 -34
  20. package/dist/commands/read/search.js +35 -54
  21. package/dist/commands/read/show.js +21 -2
  22. package/dist/commands/registry-cli.js +5 -5
  23. package/dist/commands/sources/add-cli.js +59 -16
  24. package/dist/commands/sources/bundle-cli.js +35 -11
  25. package/dist/commands/sources/bundle-config-ops.js +30 -0
  26. package/dist/commands/sources/dangerous-env-audit.js +4 -4
  27. package/dist/commands/sources/info.js +8 -8
  28. package/dist/commands/sources/installed-stashes.js +55 -61
  29. package/dist/commands/sources/source-add.js +39 -38
  30. package/dist/commands/sources/source-manage.js +34 -12
  31. package/dist/commands/sources/stash-cli.js +111 -119
  32. package/dist/commands/sources/stash-skeleton.js +6 -3
  33. package/dist/commands/tasks/explain.js +4 -1
  34. package/dist/commands/tasks/tasks-cli.js +31 -9
  35. package/dist/commands/tasks/tasks.js +239 -194
  36. package/dist/commands/tasks/validate.js +20 -32
  37. package/dist/core/activation-policy.js +4 -4
  38. package/dist/core/adapter/adapters/akm-adapter.js +8 -35
  39. package/dist/core/adapter/adapters/akm-metadata.js +1 -11
  40. package/dist/core/adapter/execution-source.js +10 -29
  41. package/dist/core/asset/asset-placement.js +0 -35
  42. package/dist/core/config/config-schema.js +64 -8
  43. package/dist/core/config/config-sources.js +96 -2
  44. package/dist/core/config/config.js +190 -24
  45. package/dist/core/config/legacy-source-shape-shim.js +9 -0
  46. package/dist/core/config/schema/embedding.js +30 -7
  47. package/dist/core/config/schema/execution.js +23 -0
  48. package/dist/core/config/schema/experimental.js +1 -1
  49. package/dist/core/config/schema/scheduler.js +20 -0
  50. package/dist/core/config/schema/search.js +10 -12
  51. package/dist/core/config/schema/sources-bundles.js +32 -1
  52. package/dist/core/content-safety.js +52 -0
  53. package/dist/core/errors.js +2 -5
  54. package/dist/core/maintenance-barrier.js +11 -13
  55. package/dist/core/paths.js +11 -0
  56. package/dist/core/run-lock.js +2 -5
  57. package/dist/core/state/migrations.js +1 -26
  58. package/dist/core/state-db.js +27 -63
  59. package/dist/core/type-presentation.js +1 -1
  60. package/dist/core/write-source.js +13 -8
  61. package/dist/indexer/bundle-identity-guard.js +45 -8
  62. package/dist/indexer/ensure-index.js +0 -5
  63. package/dist/indexer/index-db-contention.js +56 -0
  64. package/dist/indexer/index-rebuild-lock.js +73 -0
  65. package/dist/indexer/index-written-assets.js +171 -133
  66. package/dist/indexer/indexer.js +1621 -458
  67. package/dist/indexer/lookup/adapter-concept-owner.js +5 -19
  68. package/dist/indexer/materialize-embeddings.js +785 -0
  69. package/dist/indexer/passes/dir-staleness.js +161 -0
  70. package/dist/indexer/passes/metadata.js +1 -18
  71. package/dist/indexer/scan/drain-dir.js +70 -27
  72. package/dist/indexer/search/db-search.js +89 -373
  73. package/dist/indexer/search/ranking-contributors.js +16 -21
  74. package/dist/indexer/search/ranking.js +57 -135
  75. package/dist/indexer/search/search-source.js +29 -11
  76. package/dist/integrations/agent/execution-lowering.js +3 -2
  77. package/dist/integrations/agent/execution-preparation.js +32 -1
  78. package/dist/integrations/agent/prompts.js +1 -1
  79. package/dist/integrations/agent/request-lowering.js +3 -2
  80. package/dist/llm/client.js +3 -11
  81. package/dist/llm/embedder.js +3 -10
  82. package/dist/llm/embedders/remote.js +104 -133
  83. package/dist/llm/feature-gate.js +2 -4
  84. package/dist/llm/rerank-client.js +3 -3
  85. package/dist/output/html-render.js +2 -1
  86. package/dist/output/shapes/passthrough.js +2 -1
  87. package/dist/output/stdout.js +24 -0
  88. package/dist/output/text/command-format.js +13 -19
  89. package/dist/output/text/helpers.js +1 -1
  90. package/dist/output/text/index.js +2 -5
  91. package/dist/output/text.js +4 -3
  92. package/dist/registry/resolve.js +37 -10
  93. package/dist/scripts/akm-migrate-node.js +15197 -11351
  94. package/dist/scripts/akm-migrate.js +15514 -11668
  95. package/dist/setup/semantic-assets.js +2 -2
  96. package/dist/setup/setup.js +3 -3
  97. package/dist/setup/steps/connection.js +2 -3
  98. package/dist/setup/steps/tasks.js +29 -36
  99. package/dist/sources/providers/git-install.js +17 -11
  100. package/dist/sources/providers/git-provider.js +12 -5
  101. package/dist/sources/providers/git-stash.js +38 -16
  102. package/dist/sources/snapshot-fetchers/website-ingest.js +3 -3
  103. package/dist/storage/repositories/embedding-salvage-repository.js +184 -0
  104. package/dist/storage/repositories/index-connection.js +3 -1
  105. package/dist/storage/repositories/index-entries-repository.js +68 -77
  106. package/dist/storage/repositories/index-entry-schema.js +25 -16
  107. package/dist/storage/repositories/index-fts-repository.js +263 -29
  108. package/dist/storage/repositories/index-meta-repository.js +29 -0
  109. package/dist/storage/repositories/index-schema.js +122 -115
  110. package/dist/storage/repositories/index-utility-repository.js +1 -1
  111. package/dist/storage/repositories/index-vec-repository.js +435 -22
  112. package/dist/tasks/activation-config.js +90 -0
  113. package/dist/tasks/backends/cron.js +9 -0
  114. package/dist/tasks/backends/launchd.js +1 -0
  115. package/dist/tasks/backends/schtasks.js +2 -0
  116. package/dist/tasks/embedded.js +4 -5
  117. package/dist/tasks/scheduler-binding.js +2 -2
  118. package/dist/tasks/scheduler-sync-preview.js +8 -1
  119. package/dist/tasks/scheduler-sync.js +19 -10
  120. package/dist/tasks/source/parse-task-source.js +10 -113
  121. package/dist/tasks/source/project-v4.js +2 -2
  122. package/dist/tasks/source/task-source-v4.js +4 -12
  123. package/dist/tasks/source/task-to-v3.js +4 -12
  124. package/dist/tasks/source/task-to-v4.js +40 -7
  125. package/docs/migration/README.md +1 -0
  126. package/docs/migration/release-notes/0.9.15.md +36 -34
  127. package/docs/migration/release-notes/0.9.16.md +60 -98
  128. package/docs/migration/release-notes/README.md +0 -5
  129. package/docs/migration/v0.9.1-to-v0.9.2.md +6 -9
  130. package/docs/reference/cli.md +124 -122
  131. package/docs/reference/configuration.md +137 -133
  132. package/docs/reference/data-and-telemetry.md +1 -2
  133. package/docs/reference/tasks.md +34 -29
  134. package/package.json +1 -1
  135. package/schemas/akm-config.json +170 -6
  136. package/schemas/akm-task.json +1 -2
  137. package/dist/commands/sources/index-status.js +0 -99
  138. package/dist/core/hash.js +0 -18
  139. package/dist/indexer/drain.js +0 -306
  140. package/dist/indexer/embedding-identity.js +0 -20
  141. package/dist/indexer/enrich.js +0 -260
  142. package/dist/indexer/reconcile.js +0 -890
  143. package/dist/indexer/scan/parse-file.js +0 -66
  144. package/dist/indexer/units/unit.js +0 -159
  145. package/dist/llm/embedders/provider-limits.js +0 -288
  146. package/dist/storage/repositories/files-repository.js +0 -181
  147. package/dist/storage/repositories/units-repository.js +0 -510
@@ -1,181 +0,0 @@
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
- import { SQLITE_CHUNK_SIZE } from "./index-sql.js";
5
- // ── Schema ──────────────────────────────────────────────────────────────────
6
- /**
7
- * Create `files`, `unit_texts` and `units_fts` if they do not already exist.
8
- * Idempotent; never drops or rewrites an existing row. Safe to call on every
9
- * schema ensure, same as `units-repository.ts`'s `ensureUnitTables`.
10
- */
11
- export function ensureFileAndUnitTextTables(db) {
12
- db.exec(`
13
- CREATE TABLE IF NOT EXISTS files (
14
- path TEXT PRIMARY KEY,
15
- bundle_id TEXT NOT NULL,
16
- size INTEGER NOT NULL,
17
- mtime_ms REAL NOT NULL,
18
- ctime_ms REAL NOT NULL DEFAULT -1,
19
- blob_hash TEXT NOT NULL,
20
- adapter_id TEXT NOT NULL DEFAULT ''
21
- );
22
- CREATE INDEX IF NOT EXISTS files_bundle ON files(bundle_id);
23
-
24
- CREATE TABLE IF NOT EXISTS unit_texts (
25
- unit_hash TEXT PRIMARY KEY,
26
- kind TEXT NOT NULL CHECK (kind IN ('card','fragment')),
27
- text TEXT NOT NULL
28
- );
29
- -- index-redesign-contract.md B5f item 2: search runs the lexical query as
30
- -- two kind-scoped lists (card, fragment) so a name/description match
31
- -- ranks in its own small pool instead of competing with body text in one
32
- -- BM25 pool. That kind filter runs on every search, so it needs an index.
33
- CREATE INDEX IF NOT EXISTS unit_texts_kind ON unit_texts(kind);
34
-
35
- CREATE VIRTUAL TABLE IF NOT EXISTS units_fts USING fts5(
36
- unit_hash UNINDEXED, text, tokenize='porter unicode61'
37
- );
38
- `);
39
- ensureFilesAdapterIdColumn(db);
40
- ensureFilesCtimeColumn(db);
41
- }
42
- /**
43
- * `adapter_id` was added after `files`' first release, so a database created
44
- * before it needs an `ALTER TABLE` (`CREATE TABLE IF NOT EXISTS` only shapes
45
- * a fresh table). Idempotent. A pre-existing row's default `''` matches no
46
- * real adapter id, so the very next reconcile sees it as a mismatch and
47
- * re-parses that one file under its current adapter — a one-time,
48
- * self-healing cost, not a correctness gap.
49
- */
50
- function ensureFilesAdapterIdColumn(db) {
51
- const columns = db.prepare("PRAGMA table_info(files)").all();
52
- if (!columns.some((column) => column.name === "adapter_id")) {
53
- db.exec("ALTER TABLE files ADD COLUMN adapter_id TEXT NOT NULL DEFAULT ''");
54
- }
55
- }
56
- /**
57
- * `ctime_ms` was added after `files`' first release, the same additive,
58
- * self-healing way `adapter_id` was (see {@link ensureFilesAdapterIdColumn}):
59
- * a database created before it needs an `ALTER TABLE`. A pre-existing row's
60
- * default `-1` matches no real `ctimeMs` (always >= 0), so the very next
61
- * reconcile sees it as a mismatch and re-parses that one file — a one-time,
62
- * self-healing cost, not a correctness gap.
63
- */
64
- function ensureFilesCtimeColumn(db) {
65
- const columns = db.prepare("PRAGMA table_info(files)").all();
66
- if (!columns.some((column) => column.name === "ctime_ms")) {
67
- db.exec("ALTER TABLE files ADD COLUMN ctime_ms REAL NOT NULL DEFAULT -1");
68
- }
69
- }
70
- // ── files ───────────────────────────────────────────────────────────────────
71
- function rowToFileState(row) {
72
- return {
73
- path: row.path,
74
- bundleId: row.bundle_id,
75
- size: row.size,
76
- mtimeMs: row.mtime_ms,
77
- ctimeMs: row.ctime_ms,
78
- blobHash: row.blob_hash,
79
- adapterId: row.adapter_id,
80
- };
81
- }
82
- /** The stored stat/hash row for one path, or `undefined` if it has never been reconciled. */
83
- export function getFileState(db, path) {
84
- const row = db
85
- .prepare("SELECT path, bundle_id, size, mtime_ms, ctime_ms, blob_hash, adapter_id FROM files WHERE path = ?")
86
- .get(path);
87
- return row ? rowToFileState(row) : undefined;
88
- }
89
- /** Every stored `files` row for one bundle — the stat cache `reconcileRoots` diffs one root's walk against. */
90
- export function getFileStatesByBundle(db, bundleId) {
91
- const rows = db
92
- .prepare("SELECT path, bundle_id, size, mtime_ms, ctime_ms, blob_hash, adapter_id FROM files WHERE bundle_id = ?")
93
- .all(bundleId);
94
- return rows.map(rowToFileState);
95
- }
96
- /** Insert or replace one file's stat/hash row. */
97
- export function upsertFileState(db, row) {
98
- db.prepare(`INSERT INTO files (path, bundle_id, size, mtime_ms, ctime_ms, blob_hash, adapter_id) VALUES (?, ?, ?, ?, ?, ?, ?)
99
- ON CONFLICT(path) DO UPDATE SET bundle_id = excluded.bundle_id, size = excluded.size,
100
- mtime_ms = excluded.mtime_ms, ctime_ms = excluded.ctime_ms, blob_hash = excluded.blob_hash,
101
- adapter_id = excluded.adapter_id`).run(row.path, row.bundleId, row.size, row.mtimeMs, row.ctimeMs, row.blobHash, row.adapterId);
102
- }
103
- /** Remove `files` rows for paths that no longer have an entry (gone, or the adapter no longer recognizes them). */
104
- export function deleteFileStates(db, paths) {
105
- for (let offset = 0; offset < paths.length; offset += SQLITE_CHUNK_SIZE) {
106
- const chunk = paths.slice(offset, offset + SQLITE_CHUNK_SIZE);
107
- const placeholders = chunk.map(() => "?").join(",");
108
- db.prepare(`DELETE FROM files WHERE path IN (${placeholders})`).run(...chunk);
109
- }
110
- }
111
- // ── unit_texts / units_fts ───────────────────────────────────────────────────
112
- /**
113
- * Write the text for every hash in `units` reconcile has not stored before.
114
- * `unit_texts` dedupes itself (`INSERT OR IGNORE` on its `unit_hash` PRIMARY
115
- * KEY); a `units_fts` mirror row is written ONLY when the `unit_texts` insert
116
- * actually happened (FTS5 has no PRIMARY KEY to `OR IGNORE` against, so
117
- * inserting unconditionally would duplicate a hash already indexed).
118
- */
119
- export function insertNewUnitTexts(db, units) {
120
- if (units.length === 0)
121
- return { inserted: 0 };
122
- const insertText = db.prepare("INSERT OR IGNORE INTO unit_texts (unit_hash, kind, text) VALUES (?, ?, ?)");
123
- const insertFts = db.prepare("INSERT INTO units_fts (unit_hash, text) VALUES (?, ?)");
124
- let inserted = 0;
125
- for (const unit of units) {
126
- const result = insertText.run(unit.hash, unit.kind, unit.text);
127
- if (Number(result.changes) > 0) {
128
- insertFts.run(unit.hash, unit.text);
129
- inserted++;
130
- }
131
- }
132
- return { inserted };
133
- }
134
- /**
135
- * Delete `unit_texts`/`units_fts` rows no `entry_units` row references any
136
- * more — a single `NOT EXISTS` sweep, run once at the end of `reconcileRoots`
137
- * (never `reconcilePaths`, whose small known-paths scope makes a full-table
138
- * sweep wasteful for the write-path caller it serves). Vectors
139
- * (`units`/`units_vec`) are never touched here — dropping the text does not
140
- * drop the embedding, so a hash that comes back later resumes serving search
141
- * without re-embedding.
142
- */
143
- export function pruneOrphanUnitTexts(db) {
144
- const before = db.prepare("SELECT COUNT(*) AS n FROM unit_texts").get().n;
145
- db.exec("DELETE FROM units_fts WHERE unit_hash IN (SELECT unit_hash FROM unit_texts WHERE NOT EXISTS " +
146
- "(SELECT 1 FROM entry_units WHERE entry_units.unit_hash = unit_texts.unit_hash))");
147
- db.exec("DELETE FROM unit_texts WHERE NOT EXISTS (SELECT 1 FROM entry_units WHERE entry_units.unit_hash = unit_texts.unit_hash)");
148
- const after = db.prepare("SELECT COUNT(*) AS n FROM unit_texts").get().n;
149
- return { removed: before - after };
150
- }
151
- /**
152
- * Delete `unit_texts`/`units_fts` rows for exactly the hashes in `hashes`
153
- * that no `entry_units` row references any more — the narrow counterpart to
154
- * {@link pruneOrphanUnitTexts}'s whole-table sweep, for a caller that already
155
- * knows precisely which hashes its own write just orphaned (`reconcile.ts`'s
156
- * `applyChange`, run after every write — including `reconcilePaths`, which
157
- * previously never pruned anything and so grew `unit_texts`/`units_fts`
158
- * without bound across repeated edits) rather than sweeping every row in the
159
- * table on every single write. Vectors (`units`/`units_vec`) are never
160
- * touched here either, for the same reason `pruneOrphanUnitTexts` leaves
161
- * them alone: dropping a unit's text must not drop its vector, so a hash
162
- * that returns resumes serving search without re-embedding.
163
- */
164
- export function pruneOrphanUnitTextsForHashes(db, hashes) {
165
- const unique = [...new Set(hashes)];
166
- if (unique.length === 0)
167
- return { removed: 0 };
168
- let removed = 0;
169
- for (let offset = 0; offset < unique.length; offset += SQLITE_CHUNK_SIZE) {
170
- const chunk = unique.slice(offset, offset + SQLITE_CHUNK_SIZE);
171
- const placeholders = chunk.map(() => "?").join(",");
172
- db.prepare(`DELETE FROM units_fts WHERE unit_hash IN (${placeholders}) AND NOT EXISTS ` +
173
- `(SELECT 1 FROM entry_units WHERE entry_units.unit_hash = units_fts.unit_hash)`).run(...chunk);
174
- const result = db
175
- .prepare(`DELETE FROM unit_texts WHERE unit_hash IN (${placeholders}) AND NOT EXISTS ` +
176
- `(SELECT 1 FROM entry_units WHERE entry_units.unit_hash = unit_texts.unit_hash)`)
177
- .run(...chunk);
178
- removed += Number(result.changes);
179
- }
180
- return { removed };
181
- }