akm-cli 0.7.0-rc1 → 0.7.1

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 (314) hide show
  1. package/dist/{src/cli.js → cli.js} +100 -16
  2. package/dist/{src/commands → commands}/config-cli.js +42 -0
  3. package/dist/{src/commands → commands}/history.js +78 -7
  4. package/dist/{src/commands → commands}/registry-search.js +69 -6
  5. package/dist/{src/commands → commands}/search.js +30 -3
  6. package/dist/{src/commands → commands}/show.js +29 -0
  7. package/dist/{src/commands → commands}/source-add.js +5 -1
  8. package/dist/{src/commands → commands}/source-manage.js +7 -1
  9. package/dist/{src/core → core}/config.js +28 -0
  10. package/dist/{src/indexer → indexer}/db-search.js +1 -0
  11. package/dist/{src/indexer → indexer}/indexer.js +16 -2
  12. package/dist/{src/indexer → indexer}/matchers.js +1 -1
  13. package/dist/{src/indexer → indexer}/search-source.js +4 -2
  14. package/dist/{src/integrations → integrations}/agent/profiles.js +1 -1
  15. package/dist/{src/integrations → integrations}/agent/spawn.js +67 -16
  16. package/dist/{src/integrations → integrations}/github.js +9 -3
  17. package/dist/{src/llm → llm}/embedders/remote.js +37 -3
  18. package/dist/{src/output → output}/cli-hints.js +15 -2
  19. package/dist/{src/output → output}/renderers.js +3 -1
  20. package/dist/{src/output → output}/shapes.js +8 -1
  21. package/dist/{src/output → output}/text.js +156 -3
  22. package/dist/{src/registry → registry}/build-index.js +5 -4
  23. package/dist/{src/registry → registry}/providers/static-index.js +3 -1
  24. package/dist/{src/setup → setup}/setup.js +9 -0
  25. package/dist/{src/wiki → wiki}/wiki.js +54 -6
  26. package/dist/{src/workflows → workflows}/runs.js +37 -3
  27. package/package.json +8 -8
  28. package/dist/tests/add-website-source.test.js +0 -119
  29. package/dist/tests/agent/agent-config-loader.test.js +0 -70
  30. package/dist/tests/agent/agent-config.test.js +0 -221
  31. package/dist/tests/agent/agent-detect.test.js +0 -100
  32. package/dist/tests/agent/agent-spawn.test.js +0 -234
  33. package/dist/tests/agent-output.test.js +0 -186
  34. package/dist/tests/architecture/agent-no-llm-sdk-guard.test.js +0 -103
  35. package/dist/tests/architecture/agent-spawn-seam.test.js +0 -193
  36. package/dist/tests/architecture/llm-stateless-seam.test.js +0 -112
  37. package/dist/tests/asset-ref.test.js +0 -192
  38. package/dist/tests/asset-registry.test.js +0 -103
  39. package/dist/tests/asset-spec.test.js +0 -241
  40. package/dist/tests/bench/attribution.test.js +0 -995
  41. package/dist/tests/bench/cleanup-sigint.test.js +0 -83
  42. package/dist/tests/bench/cleanup.js +0 -203
  43. package/dist/tests/bench/cleanup.test.js +0 -166
  44. package/dist/tests/bench/cli.js +0 -683
  45. package/dist/tests/bench/cli.test.js +0 -177
  46. package/dist/tests/bench/compare.test.js +0 -556
  47. package/dist/tests/bench/corpus.js +0 -314
  48. package/dist/tests/bench/corpus.test.js +0 -258
  49. package/dist/tests/bench/driver.js +0 -346
  50. package/dist/tests/bench/driver.test.js +0 -443
  51. package/dist/tests/bench/evolve-metrics.js +0 -179
  52. package/dist/tests/bench/evolve-metrics.test.js +0 -187
  53. package/dist/tests/bench/evolve.js +0 -580
  54. package/dist/tests/bench/evolve.test.js +0 -616
  55. package/dist/tests/bench/failure-modes.test.js +0 -300
  56. package/dist/tests/bench/feedback-integrity.test.js +0 -456
  57. package/dist/tests/bench/leakage.test.js +0 -125
  58. package/dist/tests/bench/learning-curve.test.js +0 -133
  59. package/dist/tests/bench/metrics.js +0 -2319
  60. package/dist/tests/bench/metrics.test.js +0 -1144
  61. package/dist/tests/bench/no-os-tmpdir-invariant.test.js +0 -43
  62. package/dist/tests/bench/report.js +0 -1821
  63. package/dist/tests/bench/report.test.js +0 -989
  64. package/dist/tests/bench/runner.js +0 -536
  65. package/dist/tests/bench/runner.test.js +0 -958
  66. package/dist/tests/bench/search-bridge.test.js +0 -331
  67. package/dist/tests/bench/tmp.js +0 -41
  68. package/dist/tests/bench/trajectory.js +0 -116
  69. package/dist/tests/bench/trajectory.test.js +0 -127
  70. package/dist/tests/bench/verifier.js +0 -109
  71. package/dist/tests/bench/verifier.test.js +0 -118
  72. package/dist/tests/bench/workflow-evaluator.js +0 -557
  73. package/dist/tests/bench/workflow-evaluator.test.js +0 -421
  74. package/dist/tests/bench/workflow-spec.js +0 -358
  75. package/dist/tests/bench/workflow-spec.test.js +0 -363
  76. package/dist/tests/bench/workflow-trace.js +0 -438
  77. package/dist/tests/bench/workflow-trace.test.js +0 -254
  78. package/dist/tests/benchmark-search-quality.js +0 -536
  79. package/dist/tests/benchmark-suite.js +0 -1441
  80. package/dist/tests/capture-cli.test.js +0 -112
  81. package/dist/tests/cli-errors.test.js +0 -203
  82. package/dist/tests/commands/events.test.js +0 -370
  83. package/dist/tests/commands/history.test.js +0 -223
  84. package/dist/tests/commands/import.test.js +0 -103
  85. package/dist/tests/commands/proposal-cli.test.js +0 -209
  86. package/dist/tests/commands/reflect-propose-cli.test.js +0 -333
  87. package/dist/tests/commands/remember.test.js +0 -97
  88. package/dist/tests/commands/scope-flags.test.js +0 -300
  89. package/dist/tests/commands/search.test.js +0 -537
  90. package/dist/tests/commands/show-indexer-parity.test.js +0 -117
  91. package/dist/tests/commands/show.test.js +0 -294
  92. package/dist/tests/common.test.js +0 -266
  93. package/dist/tests/completions.test.js +0 -142
  94. package/dist/tests/config-cli.test.js +0 -193
  95. package/dist/tests/config-llm-features.test.js +0 -139
  96. package/dist/tests/config.test.js +0 -544
  97. package/dist/tests/contracts/migration-baseline.test.js +0 -43
  98. package/dist/tests/contracts/reflect-propose-envelope.test.js +0 -139
  99. package/dist/tests/contracts/spec-helpers.js +0 -46
  100. package/dist/tests/contracts/v1-spec-section-11-proposal-queue.test.js +0 -228
  101. package/dist/tests/contracts/v1-spec-section-12-agent-config.test.js +0 -56
  102. package/dist/tests/contracts/v1-spec-section-13-lesson-type.test.js +0 -34
  103. package/dist/tests/contracts/v1-spec-section-14-llm-features.test.js +0 -94
  104. package/dist/tests/contracts/v1-spec-section-4-1-asset-types.test.js +0 -39
  105. package/dist/tests/contracts/v1-spec-section-4-2-quality-rules.test.js +0 -44
  106. package/dist/tests/contracts/v1-spec-section-5-configuration.test.js +0 -47
  107. package/dist/tests/contracts/v1-spec-section-6-orchestration.test.js +0 -40
  108. package/dist/tests/contracts/v1-spec-section-7-module-layout.test.js +0 -58
  109. package/dist/tests/contracts/v1-spec-section-8-extension-points.test.js +0 -34
  110. package/dist/tests/contracts/v1-spec-section-9-4-cli-surface.test.js +0 -75
  111. package/dist/tests/contracts/v1-spec-section-9-7-llm-agent-boundary.test.js +0 -36
  112. package/dist/tests/core/write-source.test.js +0 -366
  113. package/dist/tests/curate-command.test.js +0 -87
  114. package/dist/tests/db-scoring.test.js +0 -201
  115. package/dist/tests/db.test.js +0 -654
  116. package/dist/tests/distill-cli-flag.test.js +0 -208
  117. package/dist/tests/distill.test.js +0 -515
  118. package/dist/tests/docker-install.test.js +0 -120
  119. package/dist/tests/e2e.test.js +0 -1398
  120. package/dist/tests/embedder.test.js +0 -340
  121. package/dist/tests/embedding-model-config.test.js +0 -379
  122. package/dist/tests/feedback-command.test.js +0 -172
  123. package/dist/tests/file-context.test.js +0 -552
  124. package/dist/tests/fixtures/scripts/git/summarize-diff.js +0 -9
  125. package/dist/tests/fixtures/scripts/lint/eslint-check.js +0 -7
  126. package/dist/tests/fixtures/stashes/load.js +0 -166
  127. package/dist/tests/fixtures/stashes/load.test.js +0 -88
  128. package/dist/tests/fixtures/stashes/ranking-baseline/scripts/mem0-search.js +0 -12
  129. package/dist/tests/frontmatter.test.js +0 -190
  130. package/dist/tests/fts-field-weighting.test.js +0 -254
  131. package/dist/tests/fuzzy-search.test.js +0 -230
  132. package/dist/tests/git-provider-clone.test.js +0 -45
  133. package/dist/tests/github.test.js +0 -161
  134. package/dist/tests/graph-boost-ranking.test.js +0 -305
  135. package/dist/tests/graph-extraction.test.js +0 -282
  136. package/dist/tests/helpers/usage-events.js +0 -8
  137. package/dist/tests/index-pass-llm.test.js +0 -161
  138. package/dist/tests/indexer.test.js +0 -559
  139. package/dist/tests/info-command.test.js +0 -166
  140. package/dist/tests/init.test.js +0 -69
  141. package/dist/tests/install-script.test.js +0 -246
  142. package/dist/tests/integration/agent-real-profile.test.js +0 -94
  143. package/dist/tests/issue-36-repro.test.js +0 -304
  144. package/dist/tests/issues-191-194.test.js +0 -160
  145. package/dist/tests/lesson-lint.test.js +0 -111
  146. package/dist/tests/llm-client.test.js +0 -115
  147. package/dist/tests/llm-feature-gate.test.js +0 -151
  148. package/dist/tests/llm.test.js +0 -139
  149. package/dist/tests/lockfile.test.js +0 -216
  150. package/dist/tests/manifest.test.js +0 -205
  151. package/dist/tests/markdown.test.js +0 -126
  152. package/dist/tests/matchers-unit.test.js +0 -189
  153. package/dist/tests/memory-inference.test.js +0 -299
  154. package/dist/tests/merge-scoring.test.js +0 -136
  155. package/dist/tests/metadata.test.js +0 -313
  156. package/dist/tests/migration-help.test.js +0 -89
  157. package/dist/tests/origin-resolve.test.js +0 -124
  158. package/dist/tests/output-baseline.test.js +0 -217
  159. package/dist/tests/output-shapes-unit.test.js +0 -476
  160. package/dist/tests/parallel-search.test.js +0 -272
  161. package/dist/tests/parameter-metadata.test.js +0 -365
  162. package/dist/tests/paths.test.js +0 -177
  163. package/dist/tests/progressive-disclosure.test.js +0 -280
  164. package/dist/tests/proposals.test.js +0 -279
  165. package/dist/tests/proposed-quality.test.js +0 -271
  166. package/dist/tests/provider-registry.test.js +0 -32
  167. package/dist/tests/ranking-regression.test.js +0 -548
  168. package/dist/tests/reflect-propose.test.js +0 -455
  169. package/dist/tests/registry-build-index.test.js +0 -378
  170. package/dist/tests/registry-cli.test.js +0 -290
  171. package/dist/tests/registry-index-v2.test.js +0 -430
  172. package/dist/tests/registry-install.test.js +0 -728
  173. package/dist/tests/registry-providers/parity.test.js +0 -189
  174. package/dist/tests/registry-providers/skills-sh.test.js +0 -309
  175. package/dist/tests/registry-providers/static-index.test.js +0 -204
  176. package/dist/tests/registry-resolve.test.js +0 -126
  177. package/dist/tests/registry-search.test.js +0 -723
  178. package/dist/tests/remember-frontmatter.test.js +0 -380
  179. package/dist/tests/remember-unit.test.js +0 -123
  180. package/dist/tests/ripgrep-install.test.js +0 -251
  181. package/dist/tests/ripgrep-resolve.test.js +0 -108
  182. package/dist/tests/ripgrep.test.js +0 -163
  183. package/dist/tests/save-command.test.js +0 -94
  184. package/dist/tests/save-trust-qa-fixes.test.js +0 -270
  185. package/dist/tests/scoring-pipeline.test.js +0 -648
  186. package/dist/tests/search-include-proposed-cli.test.js +0 -118
  187. package/dist/tests/self-update.test.js +0 -442
  188. package/dist/tests/semantic-search-e2e.test.js +0 -512
  189. package/dist/tests/semantic-status.test.js +0 -471
  190. package/dist/tests/setup-run.integration.js +0 -877
  191. package/dist/tests/setup-wizard.test.js +0 -198
  192. package/dist/tests/setup.test.js +0 -131
  193. package/dist/tests/source-add.test.js +0 -11
  194. package/dist/tests/source-clone.test.js +0 -254
  195. package/dist/tests/source-manage.test.js +0 -366
  196. package/dist/tests/source-providers/filesystem.test.js +0 -82
  197. package/dist/tests/source-providers/git.test.js +0 -252
  198. package/dist/tests/source-providers/website.test.js +0 -128
  199. package/dist/tests/source-qa-fixes.test.js +0 -268
  200. package/dist/tests/source-registry.test.js +0 -350
  201. package/dist/tests/source-resolve.test.js +0 -100
  202. package/dist/tests/source-source.test.js +0 -221
  203. package/dist/tests/source.test.js +0 -533
  204. package/dist/tests/tar-utils-scan.test.js +0 -73
  205. package/dist/tests/toggle-components.test.js +0 -73
  206. package/dist/tests/usage-telemetry.test.js +0 -265
  207. package/dist/tests/utility-scoring.test.js +0 -558
  208. package/dist/tests/vault-load-error.test.js +0 -78
  209. package/dist/tests/vault-qa-fixes.test.js +0 -194
  210. package/dist/tests/vault.test.js +0 -429
  211. package/dist/tests/vector-search.test.js +0 -608
  212. package/dist/tests/walker.test.js +0 -252
  213. package/dist/tests/wave2-cluster-bc.test.js +0 -228
  214. package/dist/tests/wave2-cluster-d.test.js +0 -180
  215. package/dist/tests/wave2-cluster-e.test.js +0 -179
  216. package/dist/tests/wiki-qa-fixes.test.js +0 -270
  217. package/dist/tests/wiki.test.js +0 -529
  218. package/dist/tests/workflow-cli.test.js +0 -271
  219. package/dist/tests/workflow-markdown.test.js +0 -171
  220. package/dist/tests/workflow-path-escape.test.js +0 -132
  221. package/dist/tests/workflow-qa-fixes.test.js +0 -377
  222. package/dist/tests/workflows/indexer-rejection.test.js +0 -213
  223. /package/dist/{src/commands → commands}/completions.js +0 -0
  224. /package/dist/{src/commands → commands}/curate.js +0 -0
  225. /package/dist/{src/commands → commands}/distill.js +0 -0
  226. /package/dist/{src/commands → commands}/events.js +0 -0
  227. /package/dist/{src/commands → commands}/info.js +0 -0
  228. /package/dist/{src/commands → commands}/init.js +0 -0
  229. /package/dist/{src/commands → commands}/install-audit.js +0 -0
  230. /package/dist/{src/commands → commands}/installed-stashes.js +0 -0
  231. /package/dist/{src/commands → commands}/migration-help.js +0 -0
  232. /package/dist/{src/commands → commands}/proposal.js +0 -0
  233. /package/dist/{src/commands → commands}/propose.js +0 -0
  234. /package/dist/{src/commands → commands}/reflect.js +0 -0
  235. /package/dist/{src/commands → commands}/remember.js +0 -0
  236. /package/dist/{src/commands → commands}/self-update.js +0 -0
  237. /package/dist/{src/commands → commands}/source-clone.js +0 -0
  238. /package/dist/{src/commands → commands}/vault.js +0 -0
  239. /package/dist/{src/core → core}/asset-ref.js +0 -0
  240. /package/dist/{src/core → core}/asset-registry.js +0 -0
  241. /package/dist/{src/core → core}/asset-spec.js +0 -0
  242. /package/dist/{src/core → core}/common.js +0 -0
  243. /package/dist/{src/core → core}/errors.js +0 -0
  244. /package/dist/{src/core → core}/events.js +0 -0
  245. /package/dist/{src/core → core}/frontmatter.js +0 -0
  246. /package/dist/{src/core → core}/lesson-lint.js +0 -0
  247. /package/dist/{src/core → core}/markdown.js +0 -0
  248. /package/dist/{src/core → core}/paths.js +0 -0
  249. /package/dist/{src/core → core}/proposals.js +0 -0
  250. /package/dist/{src/core → core}/warn.js +0 -0
  251. /package/dist/{src/core → core}/write-source.js +0 -0
  252. /package/dist/{src/indexer → indexer}/db.js +0 -0
  253. /package/dist/{src/indexer → indexer}/file-context.js +0 -0
  254. /package/dist/{src/indexer → indexer}/graph-boost.js +0 -0
  255. /package/dist/{src/indexer → indexer}/graph-extraction.js +0 -0
  256. /package/dist/{src/indexer → indexer}/manifest.js +0 -0
  257. /package/dist/{src/indexer → indexer}/memory-inference.js +0 -0
  258. /package/dist/{src/indexer → indexer}/metadata.js +0 -0
  259. /package/dist/{src/indexer → indexer}/search-fields.js +0 -0
  260. /package/dist/{src/indexer → indexer}/semantic-status.js +0 -0
  261. /package/dist/{src/indexer → indexer}/usage-events.js +0 -0
  262. /package/dist/{src/indexer → indexer}/walker.js +0 -0
  263. /package/dist/{src/integrations → integrations}/agent/config.js +0 -0
  264. /package/dist/{src/integrations → integrations}/agent/detect.js +0 -0
  265. /package/dist/{src/integrations → integrations}/agent/index.js +0 -0
  266. /package/dist/{src/integrations → integrations}/agent/prompts.js +0 -0
  267. /package/dist/{src/integrations → integrations}/lockfile.js +0 -0
  268. /package/dist/{src/llm → llm}/client.js +0 -0
  269. /package/dist/{src/llm → llm}/embedder.js +0 -0
  270. /package/dist/{src/llm → llm}/embedders/cache.js +0 -0
  271. /package/dist/{src/llm → llm}/embedders/local.js +0 -0
  272. /package/dist/{src/llm → llm}/embedders/types.js +0 -0
  273. /package/dist/{src/llm → llm}/feature-gate.js +0 -0
  274. /package/dist/{src/llm → llm}/graph-extract.js +0 -0
  275. /package/dist/{src/llm → llm}/index-passes.js +0 -0
  276. /package/dist/{src/llm → llm}/memory-infer.js +0 -0
  277. /package/dist/{src/llm → llm}/metadata-enhance.js +0 -0
  278. /package/dist/{src/output → output}/context.js +0 -0
  279. /package/dist/{src/registry → registry}/create-provider-registry.js +0 -0
  280. /package/dist/{src/registry → registry}/factory.js +0 -0
  281. /package/dist/{src/registry → registry}/origin-resolve.js +0 -0
  282. /package/dist/{src/registry → registry}/providers/index.js +0 -0
  283. /package/dist/{src/registry → registry}/providers/skills-sh.js +0 -0
  284. /package/dist/{src/registry → registry}/providers/types.js +0 -0
  285. /package/dist/{src/registry → registry}/resolve.js +0 -0
  286. /package/dist/{src/registry → registry}/types.js +0 -0
  287. /package/dist/{src/setup → setup}/detect.js +0 -0
  288. /package/dist/{src/setup → setup}/ripgrep-install.js +0 -0
  289. /package/dist/{src/setup → setup}/ripgrep-resolve.js +0 -0
  290. /package/dist/{src/setup → setup}/steps.js +0 -0
  291. /package/dist/{src/sources → sources}/include.js +0 -0
  292. /package/dist/{src/sources → sources}/provider-factory.js +0 -0
  293. /package/dist/{src/sources → sources}/provider.js +0 -0
  294. /package/dist/{src/sources → sources}/providers/filesystem.js +0 -0
  295. /package/dist/{src/sources → sources}/providers/git.js +0 -0
  296. /package/dist/{src/sources → sources}/providers/index.js +0 -0
  297. /package/dist/{src/sources → sources}/providers/install-types.js +0 -0
  298. /package/dist/{src/sources → sources}/providers/npm.js +0 -0
  299. /package/dist/{src/sources → sources}/providers/provider-utils.js +0 -0
  300. /package/dist/{src/sources → sources}/providers/sync-from-ref.js +0 -0
  301. /package/dist/{src/sources → sources}/providers/tar-utils.js +0 -0
  302. /package/dist/{src/sources → sources}/providers/website.js +0 -0
  303. /package/dist/{src/sources → sources}/resolve.js +0 -0
  304. /package/dist/{src/sources → sources}/types.js +0 -0
  305. /package/dist/{src/templates → templates}/wiki-templates.js +0 -0
  306. /package/dist/{src/version.js → version.js} +0 -0
  307. /package/dist/{src/workflows → workflows}/authoring.js +0 -0
  308. /package/dist/{src/workflows → workflows}/cli.js +0 -0
  309. /package/dist/{src/workflows → workflows}/db.js +0 -0
  310. /package/dist/{src/workflows → workflows}/document-cache.js +0 -0
  311. /package/dist/{src/workflows → workflows}/parser.js +0 -0
  312. /package/dist/{src/workflows → workflows}/renderer.js +0 -0
  313. /package/dist/{src/workflows → workflows}/schema.js +0 -0
  314. /package/dist/{src/workflows → workflows}/validator.js +0 -0
@@ -1,366 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, test } from "bun:test";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import { addStash, listStashes, removeStash } from "../src/commands/source-manage";
6
- import { loadConfig, saveConfig } from "../src/core/config";
7
- const createdTmpDirs = [];
8
- function createTmpDir(prefix = "akm-src-mgmt-") {
9
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
10
- createdTmpDirs.push(dir);
11
- return dir;
12
- }
13
- const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
14
- const originalXdgConfigHome = process.env.XDG_CONFIG_HOME;
15
- const originalAkmStashDir = process.env.AKM_STASH_DIR;
16
- let testCacheDir = "";
17
- let testConfigDir = "";
18
- let testStashDir = "";
19
- beforeEach(() => {
20
- testCacheDir = createTmpDir("akm-src-cache-");
21
- testConfigDir = createTmpDir("akm-src-config-");
22
- testStashDir = createTmpDir("akm-src-stash-");
23
- process.env.XDG_CACHE_HOME = testCacheDir;
24
- process.env.XDG_CONFIG_HOME = testConfigDir;
25
- process.env.AKM_STASH_DIR = testStashDir;
26
- // Write initial config so loadConfig doesn't return defaults with stale caches
27
- saveConfig({ semanticSearchMode: "auto" });
28
- });
29
- afterEach(() => {
30
- if (originalXdgCacheHome === undefined)
31
- delete process.env.XDG_CACHE_HOME;
32
- else
33
- process.env.XDG_CACHE_HOME = originalXdgCacheHome;
34
- if (originalXdgConfigHome === undefined)
35
- delete process.env.XDG_CONFIG_HOME;
36
- else
37
- process.env.XDG_CONFIG_HOME = originalXdgConfigHome;
38
- if (originalAkmStashDir === undefined)
39
- delete process.env.AKM_STASH_DIR;
40
- else
41
- process.env.AKM_STASH_DIR = originalAkmStashDir;
42
- for (const dir of createdTmpDirs) {
43
- try {
44
- fs.rmSync(dir, { recursive: true, force: true });
45
- }
46
- catch { }
47
- }
48
- createdTmpDirs.length = 0;
49
- });
50
- // ── addStash ──────────────────────────────────────────────────────────
51
- describe("addStash", () => {
52
- test("adds a filesystem path", () => {
53
- const stashPath = createTmpDir("akm-fs-source-");
54
- const result = addStash({ target: stashPath });
55
- expect(result.added).toBe(true);
56
- expect(result.entry).toBeDefined();
57
- expect(result.entry?.type).toBe("filesystem");
58
- expect(result.entry?.path).toBe(path.resolve(stashPath));
59
- // Verify persisted
60
- const config = loadConfig();
61
- expect(config.sources).toHaveLength(1);
62
- expect(config.sources?.[0].type).toBe("filesystem");
63
- expect(config.sources?.[0].path).toBe(path.resolve(stashPath));
64
- });
65
- test("adds a filesystem path with a name", () => {
66
- const stashPath = createTmpDir("akm-fs-named-");
67
- const result = addStash({ target: stashPath, name: "my-stash" });
68
- expect(result.added).toBe(true);
69
- expect(result.entry?.name).toBe("my-stash");
70
- });
71
- test("rejects duplicate filesystem paths", () => {
72
- const stashPath = createTmpDir("akm-fs-dup-");
73
- addStash({ target: stashPath });
74
- const result = addStash({ target: stashPath });
75
- expect(result.added).toBe(false);
76
- expect(result.message).toContain("already configured");
77
- });
78
- test("normalizes relative filesystem paths", () => {
79
- const stashPath = createTmpDir("akm-fs-rel-");
80
- const relativePath = path.relative(process.cwd(), stashPath);
81
- const result = addStash({ target: relativePath });
82
- expect(result.added).toBe(true);
83
- expect(result.entry?.path).toBe(path.resolve(stashPath));
84
- });
85
- test("deduplicates paths that resolve to the same directory", () => {
86
- const stashPath = createTmpDir("akm-fs-equiv-");
87
- addStash({ target: stashPath });
88
- // Add again with trailing slash
89
- const result = addStash({ target: `${stashPath}/` });
90
- expect(result.added).toBe(false);
91
- expect(result.message).toContain("already configured");
92
- });
93
- test("adds a URL source", () => {
94
- const url = "https://example.com";
95
- const result = addStash({ target: url, providerType: "website" });
96
- expect(result.added).toBe(true);
97
- expect(result.entry?.type).toBe("website");
98
- expect(result.entry?.url).toBe(url);
99
- const config = loadConfig();
100
- expect(config.sources).toHaveLength(1);
101
- expect(config.sources?.[0].type).toBe("website");
102
- expect(config.sources?.[0].url).toBe(url);
103
- });
104
- test("adds a URL source with name and options", () => {
105
- const url = "https://example.com";
106
- const result = addStash({
107
- target: url,
108
- providerType: "website",
109
- name: "my-source",
110
- options: { searchType: "text" },
111
- });
112
- expect(result.added).toBe(true);
113
- expect(result.entry?.name).toBe("my-source");
114
- expect(result.entry?.options).toEqual({ searchType: "text" });
115
- });
116
- test("throws when URL source has no provider type", () => {
117
- expect(() => addStash({ target: "https://example.com" })).toThrow("--provider is required");
118
- });
119
- test("rejects duplicate URL sources", () => {
120
- const url = "https://example.com";
121
- addStash({ target: url, providerType: "website" });
122
- const result = addStash({ target: url, providerType: "website" });
123
- expect(result.added).toBe(false);
124
- expect(result.message).toContain("already configured");
125
- });
126
- test("supports custom provider types", () => {
127
- const url = "https://custom.example.com";
128
- const result = addStash({ target: url, providerType: "custom-provider" });
129
- expect(result.added).toBe(true);
130
- expect(result.entry?.type).toBe("custom-provider");
131
- });
132
- test("adds an http:// URL source", () => {
133
- const url = "http://example.com";
134
- const result = addStash({ target: url, providerType: "website" });
135
- expect(result.added).toBe(true);
136
- expect(result.entry?.url).toBe(url);
137
- });
138
- test("allows same URL with different provider types", () => {
139
- const url = "https://shared.example.com";
140
- addStash({ target: url, providerType: "website" });
141
- // Same URL but different provider — deduplicates by URL regardless of type
142
- const result = addStash({ target: url, providerType: "custom" });
143
- expect(result.added).toBe(false);
144
- });
145
- test("ignores options for filesystem sources", () => {
146
- const fsPath = createTmpDir("akm-fs-opts-");
147
- const result = addStash({ target: fsPath, options: { key: "value" } });
148
- expect(result.added).toBe(true);
149
- expect(result.entry?.options).toBeUndefined();
150
- });
151
- test("returned stashes array reflects new state", () => {
152
- const fsPath = createTmpDir("akm-stashes-return-");
153
- const result = addStash({ target: fsPath, name: "ret-test" });
154
- expect(result.sources).toHaveLength(1);
155
- expect(result.sources[0].name).toBe("ret-test");
156
- });
157
- test("can add multiple sources of different types", () => {
158
- const fsPath = createTmpDir("akm-multi-fs-");
159
- addStash({ target: fsPath });
160
- addStash({ target: "https://example1.example.com", providerType: "website" });
161
- addStash({ target: "https://custom.example.com", providerType: "custom-provider" });
162
- const config = loadConfig();
163
- expect(config.sources).toHaveLength(3);
164
- expect(config.sources?.[0].type).toBe("filesystem");
165
- expect(config.sources?.[1].type).toBe("website");
166
- expect(config.sources?.[2].type).toBe("custom-provider");
167
- });
168
- test("preserves existing sources when adding", () => {
169
- const config = loadConfig();
170
- saveConfig({
171
- ...config,
172
- sources: [{ type: "website", url: "https://existing.example.com", name: "existing" }],
173
- });
174
- const fsPath = createTmpDir("akm-preserve-");
175
- addStash({ target: fsPath });
176
- const updated = loadConfig();
177
- expect(updated.sources).toHaveLength(2);
178
- expect(updated.sources?.[0].url).toBe("https://existing.example.com");
179
- expect(updated.sources?.[1].type).toBe("filesystem");
180
- });
181
- });
182
- // ── removeStash ───────────────────────────────────────────────────────
183
- describe("removeStash", () => {
184
- test("removes a filesystem source by path", () => {
185
- const fsPath = createTmpDir("akm-rm-fs-");
186
- addStash({ target: fsPath });
187
- const result = removeStash(fsPath);
188
- expect(result.removed).toBe(true);
189
- expect(result.entry?.type).toBe("filesystem");
190
- expect(result.entry?.path).toBe(path.resolve(fsPath));
191
- const config = loadConfig();
192
- expect(config.sources).toHaveLength(0);
193
- });
194
- test("removes a URL source by URL", () => {
195
- const url = "https://example.com";
196
- addStash({ target: url, providerType: "website" });
197
- const result = removeStash(url);
198
- expect(result.removed).toBe(true);
199
- expect(result.entry?.url).toBe(url);
200
- const config = loadConfig();
201
- expect(config.sources).toHaveLength(0);
202
- });
203
- test("removes a source by name", () => {
204
- const url = "https://example.com";
205
- addStash({ target: url, providerType: "website", name: "my-source" });
206
- const result = removeStash("my-source");
207
- expect(result.removed).toBe(true);
208
- expect(result.entry?.name).toBe("my-source");
209
- });
210
- test("returns removed: false for non-existent source", () => {
211
- const result = removeStash("/nonexistent/path");
212
- expect(result.removed).toBe(false);
213
- expect(result.message).toContain("No matching source found");
214
- });
215
- test("removes only the matched source, preserving others", () => {
216
- const fsPath = createTmpDir("akm-rm-keep-");
217
- addStash({ target: fsPath });
218
- addStash({ target: "https://example.com", providerType: "website" });
219
- removeStash(fsPath);
220
- const config = loadConfig();
221
- expect(config.sources).toHaveLength(1);
222
- expect(config.sources?.[0].type).toBe("website");
223
- });
224
- test("prefers URL match over name match", () => {
225
- const url = "https://example.com";
226
- addStash({ target: url, providerType: "website", name: "my-source" });
227
- addStash({ target: "https://other.example.com", providerType: "website", name: url });
228
- // Should match by URL (first entry), not by name (second entry)
229
- const result = removeStash(url);
230
- expect(result.removed).toBe(true);
231
- expect(result.entry?.name).toBe("my-source");
232
- // The second entry (whose name matches the URL) should still exist
233
- const config = loadConfig();
234
- expect(config.sources).toHaveLength(1);
235
- expect(config.sources?.[0].name).toBe(url);
236
- });
237
- test("prefers path match over name match", () => {
238
- const fsPath = createTmpDir("akm-rm-prio-");
239
- addStash({ target: fsPath, name: "path-source" });
240
- addStash({ target: "https://other.example.com", providerType: "website", name: fsPath });
241
- // Should match by path (first entry), not by name (second entry)
242
- const result = removeStash(fsPath);
243
- expect(result.removed).toBe(true);
244
- expect(result.entry?.type).toBe("filesystem");
245
- });
246
- test("removes http:// URL source", () => {
247
- const url = "http://example.com";
248
- addStash({ target: url, providerType: "website" });
249
- const result = removeStash(url);
250
- expect(result.removed).toBe(true);
251
- expect(result.entry?.url).toBe(url);
252
- });
253
- test("returned stashes array reflects new state", () => {
254
- const fsPath = createTmpDir("akm-rm-ret-");
255
- addStash({ target: fsPath, name: "rm-ret-test" });
256
- addStash({ target: "https://keep.example.com", providerType: "website", name: "keep" });
257
- const result = removeStash("rm-ret-test");
258
- expect(result.sources).toHaveLength(1);
259
- expect(result.sources[0].name).toBe("keep");
260
- });
261
- test("removes filesystem source by relative path that resolves correctly", () => {
262
- const fsPath = createTmpDir("akm-rm-rel-");
263
- addStash({ target: fsPath });
264
- const relativePath = path.relative(process.cwd(), fsPath);
265
- const result = removeStash(relativePath);
266
- expect(result.removed).toBe(true);
267
- });
268
- });
269
- // ── listStashes ────────────────────────────────────────────────────────
270
- describe("listStashes", () => {
271
- test("lists empty stash sources", () => {
272
- const result = listStashes();
273
- expect(result.localSources).toBeDefined();
274
- expect(result.sources).toEqual([]);
275
- expect(result.remoteSources).toBeUndefined();
276
- });
277
- test("lists filesystem stash sources", () => {
278
- const fsPath = createTmpDir("akm-list-fs-");
279
- addStash({ target: fsPath });
280
- const result = listStashes();
281
- expect(result.sources).toHaveLength(1);
282
- expect(result.sources[0].type).toBe("filesystem");
283
- });
284
- test("lists URL stash sources", () => {
285
- addStash({ target: "https://example.com", providerType: "website" });
286
- const result = listStashes();
287
- expect(result.sources).toHaveLength(1);
288
- expect(result.sources[0].type).toBe("website");
289
- expect(result.sources[0].url).toBe("https://example.com");
290
- });
291
- test("lists mixed source types", () => {
292
- const fsPath = createTmpDir("akm-list-mixed-");
293
- addStash({ target: fsPath });
294
- addStash({ target: "https://example.com", providerType: "website" });
295
- addStash({ target: "https://custom.example.com", providerType: "custom" });
296
- const result = listStashes();
297
- expect(result.sources).toHaveLength(3);
298
- });
299
- test("includes primary stash dir in localSources", () => {
300
- const result = listStashes();
301
- // The primary stash dir (from AKM_STASH_DIR) should always be first
302
- expect(result.localSources.length).toBeGreaterThanOrEqual(1);
303
- expect(result.localSources[0].path).toBe(path.resolve(testStashDir));
304
- });
305
- });
306
- // ── Round-trip integration ──────────────────────────────────────────────────
307
- describe("round-trip integration", () => {
308
- test("add then list then remove filesystem source", () => {
309
- const fsPath = createTmpDir("akm-roundtrip-fs-");
310
- addStash({ target: fsPath, name: "roundtrip-test" });
311
- const listed = listStashes();
312
- expect(listed.sources.some((s) => s.name === "roundtrip-test")).toBe(true);
313
- removeStash("roundtrip-test");
314
- const afterRemove = listStashes();
315
- expect(afterRemove.sources.some((s) => s.name === "roundtrip-test")).toBe(false);
316
- });
317
- test("add then list then remove URL source", () => {
318
- const url = "https://roundtrip.example.com";
319
- addStash({ target: url, providerType: "website", name: "rt-source" });
320
- const listed = listStashes();
321
- expect(listed.sources.some((s) => s.name === "rt-source")).toBe(true);
322
- removeStash(url);
323
- const afterRemove = listStashes();
324
- expect(afterRemove.sources.some((s) => s.url === url)).toBe(false);
325
- });
326
- test("add then list then remove custom provider source", () => {
327
- const url = "https://custom-roundtrip.example.com";
328
- addStash({
329
- target: url,
330
- providerType: "my-custom",
331
- name: "custom-rt",
332
- options: { key: "value" },
333
- });
334
- const listed = listStashes();
335
- const entry = listed.sources.find((s) => s.name === "custom-rt");
336
- expect(entry).toBeDefined();
337
- expect(entry?.type).toBe("my-custom");
338
- expect(entry?.options).toEqual({ key: "value" });
339
- removeStash("custom-rt");
340
- const afterRemove = listStashes();
341
- expect(afterRemove.sources.some((s) => s.name === "custom-rt")).toBe(false);
342
- });
343
- test("multiple adds and removes maintain order and integrity", () => {
344
- const fs1 = createTmpDir("akm-multi-1-");
345
- const fs2 = createTmpDir("akm-multi-2-");
346
- const url1 = "https://v1.example.com";
347
- const url2 = "https://v2.example.com";
348
- addStash({ target: fs1, name: "fs1" });
349
- addStash({ target: url1, providerType: "website", name: "v1" });
350
- addStash({ target: fs2, name: "fs2" });
351
- addStash({ target: url2, providerType: "website", name: "v2" });
352
- let sources = listStashes().sources;
353
- expect(sources).toHaveLength(4);
354
- expect(sources.map((s) => s.name)).toEqual(["fs1", "v1", "fs2", "v2"]);
355
- // Remove middle entry
356
- removeStash("v1");
357
- sources = listStashes().sources;
358
- expect(sources).toHaveLength(3);
359
- expect(sources.map((s) => s.name)).toEqual(["fs1", "fs2", "v2"]);
360
- // Remove first entry
361
- removeStash("fs1");
362
- sources = listStashes().sources;
363
- expect(sources).toHaveLength(2);
364
- expect(sources.map((s) => s.name)).toEqual(["fs2", "v2"]);
365
- });
366
- });
@@ -1,82 +0,0 @@
1
- import { afterAll, afterEach, beforeEach, describe, expect, test } from "bun:test";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import { resolveSourceProviderFactory } from "../../src/sources/provider-factory";
6
- // Trigger self-registration
7
- import "../../src/sources/providers/filesystem";
8
- const createdTmpDirs = [];
9
- function createTmpDir(prefix = "akm-fs-") {
10
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
11
- createdTmpDirs.push(dir);
12
- return dir;
13
- }
14
- const originalAkmStashDir = process.env.AKM_STASH_DIR;
15
- beforeEach(() => {
16
- process.env.AKM_STASH_DIR = createTmpDir("akm-fs-stash-");
17
- });
18
- afterEach(() => {
19
- if (originalAkmStashDir === undefined)
20
- delete process.env.AKM_STASH_DIR;
21
- else
22
- process.env.AKM_STASH_DIR = originalAkmStashDir;
23
- });
24
- afterAll(() => {
25
- for (const dir of createdTmpDirs) {
26
- fs.rmSync(dir, { recursive: true, force: true });
27
- }
28
- });
29
- describe("FilesystemSourceProvider", () => {
30
- test("self-registers as 'filesystem'", () => {
31
- expect(resolveSourceProviderFactory("filesystem")).toBeTruthy();
32
- });
33
- test("init resolves and path returns the configured path", async () => {
34
- const factory = resolveSourceProviderFactory("filesystem");
35
- expect(factory).toBeTruthy();
36
- if (!factory)
37
- throw new Error("expected filesystem factory to be registered");
38
- const stashDir = createTmpDir("akm-fs-init-");
39
- const provider = factory({ type: "filesystem", path: stashDir, name: "mine" });
40
- await provider.init({
41
- name: "mine",
42
- options: {},
43
- cacheDir: stashDir,
44
- resolveOption: (v) => (typeof v === "string" ? v : undefined),
45
- });
46
- expect(provider.kind).toBe("filesystem");
47
- expect(provider.name).toBe("mine");
48
- expect(provider.path()).toBe(stashDir);
49
- });
50
- test("path() returns the same value across calls (lifetime stability)", () => {
51
- const factory = resolveSourceProviderFactory("filesystem");
52
- expect(factory).toBeTruthy();
53
- if (!factory)
54
- throw new Error("expected filesystem factory to be registered");
55
- const stashDir = createTmpDir("akm-fs-stable-");
56
- const provider = factory({ type: "filesystem", path: stashDir, name: "stable" });
57
- const first = provider.path();
58
- const second = provider.path();
59
- expect(second).toBe(first);
60
- });
61
- test("filesystem providers have no sync() (content is user-managed)", () => {
62
- const factory = resolveSourceProviderFactory("filesystem");
63
- expect(factory).toBeTruthy();
64
- if (!factory)
65
- throw new Error("expected filesystem factory to be registered");
66
- const stashDir = createTmpDir("akm-fs-nosync-");
67
- const provider = factory({ type: "filesystem", path: stashDir, name: "nosync" });
68
- expect(provider.sync).toBeUndefined();
69
- });
70
- test("provider exposes only the v1 SourceProvider surface", () => {
71
- const factory = resolveSourceProviderFactory("filesystem");
72
- expect(factory).toBeTruthy();
73
- if (!factory)
74
- throw new Error("expected filesystem factory to be registered");
75
- const stashDir = createTmpDir("akm-fs-iface-");
76
- const provider = factory({ type: "filesystem", path: stashDir });
77
- expect(provider.search).toBeUndefined();
78
- expect(provider.show).toBeUndefined();
79
- expect(provider.canShow).toBeUndefined();
80
- expect(provider.getContentDir).toBeUndefined();
81
- });
82
- });