akm-cli 0.7.0 → 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 (327) hide show
  1. package/package.json +8 -8
  2. package/dist/tests/add-website-source.test.js +0 -119
  3. package/dist/tests/agent/agent-config-loader.test.js +0 -70
  4. package/dist/tests/agent/agent-config.test.js +0 -221
  5. package/dist/tests/agent/agent-detect.test.js +0 -100
  6. package/dist/tests/agent/agent-spawn.test.js +0 -234
  7. package/dist/tests/agent-output.test.js +0 -186
  8. package/dist/tests/architecture/agent-no-llm-sdk-guard.test.js +0 -103
  9. package/dist/tests/architecture/agent-spawn-seam.test.js +0 -193
  10. package/dist/tests/architecture/llm-stateless-seam.test.js +0 -112
  11. package/dist/tests/asset-ref.test.js +0 -192
  12. package/dist/tests/asset-registry.test.js +0 -103
  13. package/dist/tests/asset-spec.test.js +0 -241
  14. package/dist/tests/bench/attribution.test.js +0 -996
  15. package/dist/tests/bench/cleanup-sigint.test.js +0 -83
  16. package/dist/tests/bench/cleanup.js +0 -234
  17. package/dist/tests/bench/cleanup.test.js +0 -166
  18. package/dist/tests/bench/cli.js +0 -1018
  19. package/dist/tests/bench/cli.test.js +0 -445
  20. package/dist/tests/bench/compare.test.js +0 -556
  21. package/dist/tests/bench/corpus.js +0 -317
  22. package/dist/tests/bench/corpus.test.js +0 -258
  23. package/dist/tests/bench/doctor.js +0 -525
  24. package/dist/tests/bench/driver.js +0 -401
  25. package/dist/tests/bench/driver.test.js +0 -584
  26. package/dist/tests/bench/environment.js +0 -233
  27. package/dist/tests/bench/environment.test.js +0 -199
  28. package/dist/tests/bench/evolve-metrics.js +0 -179
  29. package/dist/tests/bench/evolve-metrics.test.js +0 -187
  30. package/dist/tests/bench/evolve.js +0 -647
  31. package/dist/tests/bench/evolve.test.js +0 -624
  32. package/dist/tests/bench/failure-modes.test.js +0 -349
  33. package/dist/tests/bench/feedback-integrity.test.js +0 -457
  34. package/dist/tests/bench/leakage.test.js +0 -228
  35. package/dist/tests/bench/learning-curve.test.js +0 -134
  36. package/dist/tests/bench/metrics.js +0 -2395
  37. package/dist/tests/bench/metrics.test.js +0 -1150
  38. package/dist/tests/bench/no-os-tmpdir-invariant.test.js +0 -43
  39. package/dist/tests/bench/opencode-config.js +0 -194
  40. package/dist/tests/bench/opencode-config.test.js +0 -370
  41. package/dist/tests/bench/report.js +0 -1885
  42. package/dist/tests/bench/report.test.js +0 -1038
  43. package/dist/tests/bench/run-config.js +0 -355
  44. package/dist/tests/bench/run-config.test.js +0 -298
  45. package/dist/tests/bench/run-curate-test.js +0 -32
  46. package/dist/tests/bench/run-failing-tasks.js +0 -56
  47. package/dist/tests/bench/run-full-bench.js +0 -51
  48. package/dist/tests/bench/run-items36-targeted.js +0 -69
  49. package/dist/tests/bench/run-nano-quick.js +0 -42
  50. package/dist/tests/bench/run-waveg-targeted.js +0 -62
  51. package/dist/tests/bench/runner.js +0 -699
  52. package/dist/tests/bench/runner.test.js +0 -958
  53. package/dist/tests/bench/search-bridge.test.js +0 -331
  54. package/dist/tests/bench/tmp.js +0 -131
  55. package/dist/tests/bench/trajectory.js +0 -116
  56. package/dist/tests/bench/trajectory.test.js +0 -127
  57. package/dist/tests/bench/verifier.js +0 -114
  58. package/dist/tests/bench/verifier.test.js +0 -118
  59. package/dist/tests/bench/workflow-evaluator.js +0 -557
  60. package/dist/tests/bench/workflow-evaluator.test.js +0 -421
  61. package/dist/tests/bench/workflow-spec.js +0 -345
  62. package/dist/tests/bench/workflow-spec.test.js +0 -363
  63. package/dist/tests/bench/workflow-trace.js +0 -472
  64. package/dist/tests/bench/workflow-trace.test.js +0 -254
  65. package/dist/tests/benchmark-search-quality.js +0 -536
  66. package/dist/tests/benchmark-suite.js +0 -1441
  67. package/dist/tests/capture-cli.test.js +0 -112
  68. package/dist/tests/cli-errors.test.js +0 -204
  69. package/dist/tests/commands/events.test.js +0 -370
  70. package/dist/tests/commands/history.test.js +0 -418
  71. package/dist/tests/commands/import.test.js +0 -103
  72. package/dist/tests/commands/proposal-cli.test.js +0 -209
  73. package/dist/tests/commands/reflect-propose-cli.test.js +0 -333
  74. package/dist/tests/commands/remember.test.js +0 -97
  75. package/dist/tests/commands/scope-flags.test.js +0 -300
  76. package/dist/tests/commands/search.test.js +0 -537
  77. package/dist/tests/commands/show-indexer-parity.test.js +0 -117
  78. package/dist/tests/commands/show.test.js +0 -294
  79. package/dist/tests/common.test.js +0 -266
  80. package/dist/tests/completions.test.js +0 -142
  81. package/dist/tests/config-cli.test.js +0 -193
  82. package/dist/tests/config-llm-features.test.js +0 -139
  83. package/dist/tests/config.test.js +0 -569
  84. package/dist/tests/contracts/migration-baseline.test.js +0 -43
  85. package/dist/tests/contracts/reflect-propose-envelope.test.js +0 -139
  86. package/dist/tests/contracts/spec-helpers.js +0 -46
  87. package/dist/tests/contracts/v1-spec-section-11-proposal-queue.test.js +0 -228
  88. package/dist/tests/contracts/v1-spec-section-12-agent-config.test.js +0 -56
  89. package/dist/tests/contracts/v1-spec-section-13-lesson-type.test.js +0 -34
  90. package/dist/tests/contracts/v1-spec-section-14-llm-features.test.js +0 -94
  91. package/dist/tests/contracts/v1-spec-section-4-1-asset-types.test.js +0 -39
  92. package/dist/tests/contracts/v1-spec-section-4-2-quality-rules.test.js +0 -44
  93. package/dist/tests/contracts/v1-spec-section-5-configuration.test.js +0 -47
  94. package/dist/tests/contracts/v1-spec-section-6-orchestration.test.js +0 -40
  95. package/dist/tests/contracts/v1-spec-section-7-module-layout.test.js +0 -58
  96. package/dist/tests/contracts/v1-spec-section-8-extension-points.test.js +0 -34
  97. package/dist/tests/contracts/v1-spec-section-9-4-cli-surface.test.js +0 -75
  98. package/dist/tests/contracts/v1-spec-section-9-7-llm-agent-boundary.test.js +0 -36
  99. package/dist/tests/core/write-source.test.js +0 -366
  100. package/dist/tests/curate-command.test.js +0 -87
  101. package/dist/tests/db-scoring.test.js +0 -201
  102. package/dist/tests/db.test.js +0 -654
  103. package/dist/tests/distill-cli-flag.test.js +0 -208
  104. package/dist/tests/distill.test.js +0 -515
  105. package/dist/tests/docker-install.test.js +0 -120
  106. package/dist/tests/e2e.test.js +0 -1419
  107. package/dist/tests/embedder.test.js +0 -340
  108. package/dist/tests/embedding-model-config.test.js +0 -379
  109. package/dist/tests/feedback-command.test.js +0 -172
  110. package/dist/tests/file-context.test.js +0 -552
  111. package/dist/tests/fixtures/scripts/git/summarize-diff.js +0 -9
  112. package/dist/tests/fixtures/scripts/lint/eslint-check.js +0 -7
  113. package/dist/tests/fixtures/stashes/load.js +0 -166
  114. package/dist/tests/fixtures/stashes/load.test.js +0 -97
  115. package/dist/tests/fixtures/stashes/ranking-baseline/scripts/mem0-search.js +0 -12
  116. package/dist/tests/frontmatter.test.js +0 -190
  117. package/dist/tests/fts-field-weighting.test.js +0 -254
  118. package/dist/tests/fuzzy-search.test.js +0 -230
  119. package/dist/tests/git-provider-clone.test.js +0 -45
  120. package/dist/tests/github.test.js +0 -161
  121. package/dist/tests/graph-boost-ranking.test.js +0 -305
  122. package/dist/tests/graph-extraction.test.js +0 -282
  123. package/dist/tests/helpers/usage-events.js +0 -8
  124. package/dist/tests/index-pass-llm.test.js +0 -161
  125. package/dist/tests/indexer.test.js +0 -570
  126. package/dist/tests/info-command.test.js +0 -166
  127. package/dist/tests/init.test.js +0 -69
  128. package/dist/tests/install-script.test.js +0 -246
  129. package/dist/tests/integration/agent-real-profile.test.js +0 -94
  130. package/dist/tests/issue-36-repro.test.js +0 -304
  131. package/dist/tests/issues-191-194.test.js +0 -160
  132. package/dist/tests/lesson-lint.test.js +0 -111
  133. package/dist/tests/llm-client.test.js +0 -115
  134. package/dist/tests/llm-feature-gate.test.js +0 -151
  135. package/dist/tests/llm.test.js +0 -139
  136. package/dist/tests/lockfile.test.js +0 -216
  137. package/dist/tests/manifest.test.js +0 -205
  138. package/dist/tests/markdown.test.js +0 -126
  139. package/dist/tests/matchers-unit.test.js +0 -189
  140. package/dist/tests/memory-inference.test.js +0 -299
  141. package/dist/tests/merge-scoring.test.js +0 -136
  142. package/dist/tests/metadata.test.js +0 -313
  143. package/dist/tests/migration-help.test.js +0 -89
  144. package/dist/tests/origin-resolve.test.js +0 -124
  145. package/dist/tests/output-baseline.test.js +0 -218
  146. package/dist/tests/output-shapes-unit.test.js +0 -478
  147. package/dist/tests/parallel-search.test.js +0 -272
  148. package/dist/tests/parameter-metadata.test.js +0 -365
  149. package/dist/tests/paths.test.js +0 -177
  150. package/dist/tests/progressive-disclosure.test.js +0 -280
  151. package/dist/tests/proposals.test.js +0 -279
  152. package/dist/tests/proposed-quality.test.js +0 -271
  153. package/dist/tests/provider-registry.test.js +0 -32
  154. package/dist/tests/ranking-regression.test.js +0 -548
  155. package/dist/tests/reflect-propose.test.js +0 -455
  156. package/dist/tests/registry-build-index.test.js +0 -394
  157. package/dist/tests/registry-cli.test.js +0 -290
  158. package/dist/tests/registry-index-v2.test.js +0 -430
  159. package/dist/tests/registry-install.test.js +0 -728
  160. package/dist/tests/registry-providers/parity.test.js +0 -189
  161. package/dist/tests/registry-providers/skills-sh.test.js +0 -309
  162. package/dist/tests/registry-providers/static-index.test.js +0 -238
  163. package/dist/tests/registry-resolve.test.js +0 -126
  164. package/dist/tests/registry-search.test.js +0 -923
  165. package/dist/tests/remember-frontmatter.test.js +0 -378
  166. package/dist/tests/remember-unit.test.js +0 -123
  167. package/dist/tests/ripgrep-install.test.js +0 -251
  168. package/dist/tests/ripgrep-resolve.test.js +0 -108
  169. package/dist/tests/ripgrep.test.js +0 -163
  170. package/dist/tests/save-command.test.js +0 -94
  171. package/dist/tests/save-trust-qa-fixes.test.js +0 -270
  172. package/dist/tests/scoring-pipeline.test.js +0 -648
  173. package/dist/tests/search-include-proposed-cli.test.js +0 -118
  174. package/dist/tests/self-update.test.js +0 -442
  175. package/dist/tests/semantic-search-e2e.test.js +0 -512
  176. package/dist/tests/semantic-status.test.js +0 -471
  177. package/dist/tests/setup-run.integration.js +0 -877
  178. package/dist/tests/setup-wizard.test.js +0 -198
  179. package/dist/tests/setup.test.js +0 -131
  180. package/dist/tests/source-add.test.js +0 -11
  181. package/dist/tests/source-clone.test.js +0 -254
  182. package/dist/tests/source-manage.test.js +0 -366
  183. package/dist/tests/source-providers/filesystem.test.js +0 -82
  184. package/dist/tests/source-providers/git.test.js +0 -252
  185. package/dist/tests/source-providers/website.test.js +0 -128
  186. package/dist/tests/source-qa-fixes.test.js +0 -286
  187. package/dist/tests/source-registry.test.js +0 -350
  188. package/dist/tests/source-resolve.test.js +0 -100
  189. package/dist/tests/source-source.test.js +0 -281
  190. package/dist/tests/source.test.js +0 -533
  191. package/dist/tests/tar-utils-scan.test.js +0 -73
  192. package/dist/tests/toggle-components.test.js +0 -73
  193. package/dist/tests/usage-telemetry.test.js +0 -265
  194. package/dist/tests/utility-scoring.test.js +0 -558
  195. package/dist/tests/vault-load-error.test.js +0 -78
  196. package/dist/tests/vault-qa-fixes.test.js +0 -194
  197. package/dist/tests/vault.test.js +0 -429
  198. package/dist/tests/vector-search.test.js +0 -608
  199. package/dist/tests/walker.test.js +0 -252
  200. package/dist/tests/wave2-cluster-bc.test.js +0 -228
  201. package/dist/tests/wave2-cluster-d.test.js +0 -180
  202. package/dist/tests/wave2-cluster-e.test.js +0 -179
  203. package/dist/tests/wiki-qa-fixes.test.js +0 -270
  204. package/dist/tests/wiki.test.js +0 -529
  205. package/dist/tests/workflow-cli.test.js +0 -271
  206. package/dist/tests/workflow-markdown.test.js +0 -171
  207. package/dist/tests/workflow-path-escape.test.js +0 -132
  208. package/dist/tests/workflow-qa-fixes.test.js +0 -395
  209. package/dist/tests/workflows/indexer-rejection.test.js +0 -213
  210. /package/dist/{src/cli.js → cli.js} +0 -0
  211. /package/dist/{src/commands → commands}/completions.js +0 -0
  212. /package/dist/{src/commands → commands}/config-cli.js +0 -0
  213. /package/dist/{src/commands → commands}/curate.js +0 -0
  214. /package/dist/{src/commands → commands}/distill.js +0 -0
  215. /package/dist/{src/commands → commands}/events.js +0 -0
  216. /package/dist/{src/commands → commands}/history.js +0 -0
  217. /package/dist/{src/commands → commands}/info.js +0 -0
  218. /package/dist/{src/commands → commands}/init.js +0 -0
  219. /package/dist/{src/commands → commands}/install-audit.js +0 -0
  220. /package/dist/{src/commands → commands}/installed-stashes.js +0 -0
  221. /package/dist/{src/commands → commands}/migration-help.js +0 -0
  222. /package/dist/{src/commands → commands}/proposal.js +0 -0
  223. /package/dist/{src/commands → commands}/propose.js +0 -0
  224. /package/dist/{src/commands → commands}/reflect.js +0 -0
  225. /package/dist/{src/commands → commands}/registry-search.js +0 -0
  226. /package/dist/{src/commands → commands}/remember.js +0 -0
  227. /package/dist/{src/commands → commands}/search.js +0 -0
  228. /package/dist/{src/commands → commands}/self-update.js +0 -0
  229. /package/dist/{src/commands → commands}/show.js +0 -0
  230. /package/dist/{src/commands → commands}/source-add.js +0 -0
  231. /package/dist/{src/commands → commands}/source-clone.js +0 -0
  232. /package/dist/{src/commands → commands}/source-manage.js +0 -0
  233. /package/dist/{src/commands → commands}/vault.js +0 -0
  234. /package/dist/{src/core → core}/asset-ref.js +0 -0
  235. /package/dist/{src/core → core}/asset-registry.js +0 -0
  236. /package/dist/{src/core → core}/asset-spec.js +0 -0
  237. /package/dist/{src/core → core}/common.js +0 -0
  238. /package/dist/{src/core → core}/config.js +0 -0
  239. /package/dist/{src/core → core}/errors.js +0 -0
  240. /package/dist/{src/core → core}/events.js +0 -0
  241. /package/dist/{src/core → core}/frontmatter.js +0 -0
  242. /package/dist/{src/core → core}/lesson-lint.js +0 -0
  243. /package/dist/{src/core → core}/markdown.js +0 -0
  244. /package/dist/{src/core → core}/paths.js +0 -0
  245. /package/dist/{src/core → core}/proposals.js +0 -0
  246. /package/dist/{src/core → core}/warn.js +0 -0
  247. /package/dist/{src/core → core}/write-source.js +0 -0
  248. /package/dist/{src/indexer → indexer}/db-search.js +0 -0
  249. /package/dist/{src/indexer → indexer}/db.js +0 -0
  250. /package/dist/{src/indexer → indexer}/file-context.js +0 -0
  251. /package/dist/{src/indexer → indexer}/graph-boost.js +0 -0
  252. /package/dist/{src/indexer → indexer}/graph-extraction.js +0 -0
  253. /package/dist/{src/indexer → indexer}/indexer.js +0 -0
  254. /package/dist/{src/indexer → indexer}/manifest.js +0 -0
  255. /package/dist/{src/indexer → indexer}/matchers.js +0 -0
  256. /package/dist/{src/indexer → indexer}/memory-inference.js +0 -0
  257. /package/dist/{src/indexer → indexer}/metadata.js +0 -0
  258. /package/dist/{src/indexer → indexer}/search-fields.js +0 -0
  259. /package/dist/{src/indexer → indexer}/search-source.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/profiles.js +0 -0
  267. /package/dist/{src/integrations → integrations}/agent/prompts.js +0 -0
  268. /package/dist/{src/integrations → integrations}/agent/spawn.js +0 -0
  269. /package/dist/{src/integrations → integrations}/github.js +0 -0
  270. /package/dist/{src/integrations → integrations}/lockfile.js +0 -0
  271. /package/dist/{src/llm → llm}/client.js +0 -0
  272. /package/dist/{src/llm → llm}/embedder.js +0 -0
  273. /package/dist/{src/llm → llm}/embedders/cache.js +0 -0
  274. /package/dist/{src/llm → llm}/embedders/local.js +0 -0
  275. /package/dist/{src/llm → llm}/embedders/remote.js +0 -0
  276. /package/dist/{src/llm → llm}/embedders/types.js +0 -0
  277. /package/dist/{src/llm → llm}/feature-gate.js +0 -0
  278. /package/dist/{src/llm → llm}/graph-extract.js +0 -0
  279. /package/dist/{src/llm → llm}/index-passes.js +0 -0
  280. /package/dist/{src/llm → llm}/memory-infer.js +0 -0
  281. /package/dist/{src/llm → llm}/metadata-enhance.js +0 -0
  282. /package/dist/{src/output → output}/cli-hints.js +0 -0
  283. /package/dist/{src/output → output}/context.js +0 -0
  284. /package/dist/{src/output → output}/renderers.js +0 -0
  285. /package/dist/{src/output → output}/shapes.js +0 -0
  286. /package/dist/{src/output → output}/text.js +0 -0
  287. /package/dist/{src/registry → registry}/build-index.js +0 -0
  288. /package/dist/{src/registry → registry}/create-provider-registry.js +0 -0
  289. /package/dist/{src/registry → registry}/factory.js +0 -0
  290. /package/dist/{src/registry → registry}/origin-resolve.js +0 -0
  291. /package/dist/{src/registry → registry}/providers/index.js +0 -0
  292. /package/dist/{src/registry → registry}/providers/skills-sh.js +0 -0
  293. /package/dist/{src/registry → registry}/providers/static-index.js +0 -0
  294. /package/dist/{src/registry → registry}/providers/types.js +0 -0
  295. /package/dist/{src/registry → registry}/resolve.js +0 -0
  296. /package/dist/{src/registry → registry}/types.js +0 -0
  297. /package/dist/{src/setup → setup}/detect.js +0 -0
  298. /package/dist/{src/setup → setup}/ripgrep-install.js +0 -0
  299. /package/dist/{src/setup → setup}/ripgrep-resolve.js +0 -0
  300. /package/dist/{src/setup → setup}/setup.js +0 -0
  301. /package/dist/{src/setup → setup}/steps.js +0 -0
  302. /package/dist/{src/sources → sources}/include.js +0 -0
  303. /package/dist/{src/sources → sources}/provider-factory.js +0 -0
  304. /package/dist/{src/sources → sources}/provider.js +0 -0
  305. /package/dist/{src/sources → sources}/providers/filesystem.js +0 -0
  306. /package/dist/{src/sources → sources}/providers/git.js +0 -0
  307. /package/dist/{src/sources → sources}/providers/index.js +0 -0
  308. /package/dist/{src/sources → sources}/providers/install-types.js +0 -0
  309. /package/dist/{src/sources → sources}/providers/npm.js +0 -0
  310. /package/dist/{src/sources → sources}/providers/provider-utils.js +0 -0
  311. /package/dist/{src/sources → sources}/providers/sync-from-ref.js +0 -0
  312. /package/dist/{src/sources → sources}/providers/tar-utils.js +0 -0
  313. /package/dist/{src/sources → sources}/providers/website.js +0 -0
  314. /package/dist/{src/sources → sources}/resolve.js +0 -0
  315. /package/dist/{src/sources → sources}/types.js +0 -0
  316. /package/dist/{src/templates → templates}/wiki-templates.js +0 -0
  317. /package/dist/{src/version.js → version.js} +0 -0
  318. /package/dist/{src/wiki → wiki}/wiki.js +0 -0
  319. /package/dist/{src/workflows → workflows}/authoring.js +0 -0
  320. /package/dist/{src/workflows → workflows}/cli.js +0 -0
  321. /package/dist/{src/workflows → workflows}/db.js +0 -0
  322. /package/dist/{src/workflows → workflows}/document-cache.js +0 -0
  323. /package/dist/{src/workflows → workflows}/parser.js +0 -0
  324. /package/dist/{src/workflows → workflows}/renderer.js +0 -0
  325. /package/dist/{src/workflows → workflows}/runs.js +0 -0
  326. /package/dist/{src/workflows → workflows}/schema.js +0 -0
  327. /package/dist/{src/workflows → workflows}/validator.js +0 -0
@@ -1,877 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
- import path from "node:path";
3
- const DEFAULT_STASH_DIR = "/tmp/akm-default-stash";
4
- const DEFAULT_CONFIG_PATH = "/tmp/akm-config/config.json";
5
- const DEFAULT_CACHE_DIR = "/tmp/akm-cache";
6
- const DEFAULT_REGISTRY_URLS = [
7
- "https://raw.githubusercontent.com/itlackey/akm-registry/main/index.json",
8
- "https://skills.sh",
9
- ];
10
- const promptState = {
11
- confirms: [],
12
- selects: [],
13
- multiselects: [],
14
- texts: [],
15
- logs: [],
16
- notes: [],
17
- outros: [],
18
- };
19
- const setupState = {
20
- currentConfig: {
21
- semanticSearchMode: "auto",
22
- output: { format: "json", detail: "brief" },
23
- },
24
- savedConfigs: [],
25
- initCalls: [],
26
- indexCalls: [],
27
- detectOllamaResult: { available: false, endpoint: "http://localhost:11434", models: [] },
28
- detectAgentPlatformsResult: [],
29
- checkEmbeddingResult: { available: true },
30
- transformersAvailable: true,
31
- indexResult: {
32
- totalEntries: 3,
33
- verification: { ok: true, message: "semantic search verified" },
34
- },
35
- indexError: undefined,
36
- vecAvailable: false,
37
- };
38
- function resetPromptState() {
39
- promptState.confirms.length = 0;
40
- promptState.selects.length = 0;
41
- promptState.multiselects.length = 0;
42
- promptState.texts.length = 0;
43
- promptState.logs.length = 0;
44
- promptState.notes.length = 0;
45
- promptState.outros.length = 0;
46
- }
47
- function resetSetupState() {
48
- setupState.currentConfig = {
49
- semanticSearchMode: "auto",
50
- output: { format: "json", detail: "brief" },
51
- };
52
- setupState.savedConfigs.length = 0;
53
- setupState.initCalls.length = 0;
54
- setupState.indexCalls.length = 0;
55
- setupState.detectOllamaResult = { available: false, endpoint: "http://localhost:11434", models: [] };
56
- setupState.detectAgentPlatformsResult = [];
57
- setupState.checkEmbeddingResult = { available: true };
58
- setupState.transformersAvailable = true;
59
- setupState.indexResult = {
60
- totalEntries: 3,
61
- verification: { ok: true, message: "semantic search verified" },
62
- };
63
- setupState.indexError = undefined;
64
- setupState.vecAvailable = false;
65
- }
66
- beforeEach(() => {
67
- resetPromptState();
68
- resetSetupState();
69
- mock.restore();
70
- });
71
- afterEach(() => {
72
- mock.restore();
73
- });
74
- describe("runSetupWizard", () => {
75
- test("saves config, initializes stash, and indexes on the default happy path", async () => {
76
- mock.module("@clack/prompts", () => ({
77
- isCancel: () => false,
78
- cancel: (message) => {
79
- promptState.logs.push(`[cancel] ${message}`);
80
- },
81
- confirm: async () => promptState.confirms.shift() ?? false,
82
- select: async () => promptState.selects.shift() ?? "done",
83
- multiselect: async () => promptState.multiselects.shift() ?? [],
84
- text: async () => promptState.texts.shift() ?? "",
85
- spinner: () => ({
86
- start: (message) => {
87
- promptState.logs.push(`[spinner:start] ${message}`);
88
- },
89
- stop: (message) => {
90
- promptState.logs.push(`[spinner:stop] ${message}`);
91
- },
92
- }),
93
- log: {
94
- step: (message) => {
95
- promptState.logs.push(`[step] ${message}`);
96
- },
97
- info: (message) => {
98
- promptState.logs.push(`[info] ${message}`);
99
- },
100
- warn: (message) => {
101
- promptState.logs.push(`[warn] ${message}`);
102
- },
103
- success: (message) => {
104
- promptState.logs.push(`[success] ${message}`);
105
- },
106
- },
107
- intro: (message) => {
108
- promptState.logs.push(`[intro] ${message}`);
109
- },
110
- outro: (message) => {
111
- promptState.outros.push(message);
112
- },
113
- note: (message, title) => {
114
- promptState.notes.push(`${title ?? ""}\n${message}`.trim());
115
- },
116
- }));
117
- mock.module("../src/config", () => ({
118
- DEFAULT_CONFIG: {
119
- semanticSearchMode: "auto",
120
- registries: [
121
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
122
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
123
- ],
124
- output: { format: "json", detail: "brief" },
125
- },
126
- getConfigPath: () => DEFAULT_CONFIG_PATH,
127
- loadConfig: () => setupState.currentConfig,
128
- saveConfig: (config) => {
129
- setupState.savedConfigs.push(config);
130
- },
131
- }));
132
- mock.module("../src/paths", () => ({
133
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
134
- getConfigPath: () => DEFAULT_CONFIG_PATH,
135
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
136
- getCacheDir: () => DEFAULT_CACHE_DIR,
137
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
138
- }));
139
- mock.module("../src/detect", () => ({
140
- detectOllama: async () => setupState.detectOllamaResult,
141
- detectAgentPlatforms: () => setupState.detectAgentPlatformsResult,
142
- }));
143
- mock.module("../src/embedder", () => ({
144
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
145
- isTransformersAvailable: () => setupState.transformersAvailable,
146
- checkEmbeddingAvailability: async () => setupState.checkEmbeddingResult,
147
- }));
148
- mock.module("../src/init", () => ({
149
- akmInit: async (options) => {
150
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
151
- setupState.initCalls.push({ dir });
152
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
153
- },
154
- }));
155
- mock.module("../src/indexer", () => ({
156
- akmIndex: async ({ stashDir }) => {
157
- setupState.indexCalls.push({ stashDir });
158
- if (setupState.indexError) {
159
- throw setupState.indexError;
160
- }
161
- return setupState.indexResult;
162
- },
163
- }));
164
- mock.module("../src/db", () => ({
165
- openDatabase: () => ({}),
166
- closeDatabase: () => { },
167
- isVecAvailable: () => setupState.vecAvailable,
168
- }));
169
- promptState.selects.push("default", "done");
170
- promptState.confirms.push(false, true);
171
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
172
- const { runSetupWizard } = await import("../src/setup/setup");
173
- await runSetupWizard();
174
- expect(setupState.savedConfigs).toHaveLength(1);
175
- expect(setupState.savedConfigs[0]?.stashDir).toBe(DEFAULT_STASH_DIR);
176
- expect(setupState.savedConfigs[0]?.semanticSearchMode).toBe("off");
177
- expect(setupState.initCalls).toEqual([{ dir: DEFAULT_STASH_DIR }]);
178
- expect(setupState.indexCalls).toEqual([{ stashDir: DEFAULT_STASH_DIR }]);
179
- expect(promptState.outros[0]).toContain(DEFAULT_CONFIG_PATH);
180
- });
181
- test("keeps semantic search in auto mode when asset preparation fails", async () => {
182
- mock.module("@clack/prompts", () => ({
183
- isCancel: () => false,
184
- cancel: (message) => {
185
- promptState.logs.push(`[cancel] ${message}`);
186
- },
187
- confirm: async () => promptState.confirms.shift() ?? false,
188
- select: async () => promptState.selects.shift() ?? "done",
189
- multiselect: async () => promptState.multiselects.shift() ?? [],
190
- text: async () => promptState.texts.shift() ?? "",
191
- spinner: () => ({
192
- start: (message) => {
193
- promptState.logs.push(`[spinner:start] ${message}`);
194
- },
195
- stop: (message) => {
196
- promptState.logs.push(`[spinner:stop] ${message}`);
197
- },
198
- }),
199
- log: {
200
- step: (message) => {
201
- promptState.logs.push(`[step] ${message}`);
202
- },
203
- info: (message) => {
204
- promptState.logs.push(`[info] ${message}`);
205
- },
206
- warn: (message) => {
207
- promptState.logs.push(`[warn] ${message}`);
208
- },
209
- success: (message) => {
210
- promptState.logs.push(`[success] ${message}`);
211
- },
212
- },
213
- intro: (message) => {
214
- promptState.logs.push(`[intro] ${message}`);
215
- },
216
- outro: (message) => {
217
- promptState.outros.push(message);
218
- },
219
- note: (message, title) => {
220
- promptState.notes.push(`${title ?? ""}\n${message}`.trim());
221
- },
222
- }));
223
- mock.module("../src/config", () => ({
224
- DEFAULT_CONFIG: {
225
- semanticSearchMode: "auto",
226
- registries: [
227
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
228
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
229
- ],
230
- output: { format: "json", detail: "brief" },
231
- },
232
- getConfigPath: () => DEFAULT_CONFIG_PATH,
233
- loadConfig: () => setupState.currentConfig,
234
- saveConfig: (config) => {
235
- setupState.savedConfigs.push(config);
236
- },
237
- }));
238
- mock.module("../src/paths", () => ({
239
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
240
- getConfigPath: () => DEFAULT_CONFIG_PATH,
241
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
242
- getCacheDir: () => DEFAULT_CACHE_DIR,
243
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
244
- }));
245
- mock.module("../src/detect", () => ({
246
- detectOllama: async () => setupState.detectOllamaResult,
247
- detectAgentPlatforms: () => setupState.detectAgentPlatformsResult,
248
- }));
249
- mock.module("../src/embedder", () => ({
250
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
251
- isTransformersAvailable: () => setupState.transformersAvailable,
252
- checkEmbeddingAvailability: async () => setupState.checkEmbeddingResult,
253
- }));
254
- mock.module("../src/init", () => ({
255
- akmInit: async (options) => {
256
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
257
- setupState.initCalls.push({ dir });
258
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
259
- },
260
- }));
261
- mock.module("../src/indexer", () => ({
262
- akmIndex: async ({ stashDir }) => {
263
- setupState.indexCalls.push({ stashDir });
264
- if (setupState.indexError) {
265
- throw setupState.indexError;
266
- }
267
- return setupState.indexResult;
268
- },
269
- }));
270
- mock.module("../src/db", () => ({
271
- openDatabase: () => ({}),
272
- closeDatabase: () => { },
273
- isVecAvailable: () => setupState.vecAvailable,
274
- }));
275
- promptState.selects.push("default", "done");
276
- promptState.confirms.push(true, true, true);
277
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
278
- setupState.checkEmbeddingResult = {
279
- available: false,
280
- reason: "model-download-failed",
281
- message: "download blocked",
282
- };
283
- const { runSetupWizard } = await import("../src/setup/setup");
284
- await runSetupWizard();
285
- expect(setupState.savedConfigs).toHaveLength(1);
286
- expect(setupState.savedConfigs[0]?.semanticSearchMode).toBe("auto");
287
- expect(promptState.logs.some((entry) => entry.includes("remains set to auto, but is currently blocked"))).toBe(true);
288
- expect(setupState.indexCalls).toEqual([{ stashDir: DEFAULT_STASH_DIR }]);
289
- });
290
- test("warns and completes when indexing fails after saving config", async () => {
291
- mock.module("@clack/prompts", () => ({
292
- isCancel: () => false,
293
- cancel: (message) => {
294
- promptState.logs.push(`[cancel] ${message}`);
295
- },
296
- confirm: async () => promptState.confirms.shift() ?? false,
297
- select: async () => promptState.selects.shift() ?? "done",
298
- multiselect: async () => promptState.multiselects.shift() ?? [],
299
- text: async () => promptState.texts.shift() ?? "",
300
- spinner: () => ({
301
- start: (message) => {
302
- promptState.logs.push(`[spinner:start] ${message}`);
303
- },
304
- stop: (message) => {
305
- promptState.logs.push(`[spinner:stop] ${message}`);
306
- },
307
- }),
308
- log: {
309
- step: (message) => {
310
- promptState.logs.push(`[step] ${message}`);
311
- },
312
- info: (message) => {
313
- promptState.logs.push(`[info] ${message}`);
314
- },
315
- warn: (message) => {
316
- promptState.logs.push(`[warn] ${message}`);
317
- },
318
- success: (message) => {
319
- promptState.logs.push(`[success] ${message}`);
320
- },
321
- },
322
- intro: (message) => {
323
- promptState.logs.push(`[intro] ${message}`);
324
- },
325
- outro: (message) => {
326
- promptState.outros.push(message);
327
- },
328
- note: (message, title) => {
329
- promptState.notes.push(`${title ?? ""}\n${message}`.trim());
330
- },
331
- }));
332
- mock.module("../src/config", () => ({
333
- DEFAULT_CONFIG: {
334
- semanticSearchMode: "auto",
335
- registries: [
336
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
337
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
338
- ],
339
- output: { format: "json", detail: "brief" },
340
- },
341
- getConfigPath: () => DEFAULT_CONFIG_PATH,
342
- loadConfig: () => setupState.currentConfig,
343
- saveConfig: (config) => {
344
- setupState.savedConfigs.push(config);
345
- },
346
- }));
347
- mock.module("../src/paths", () => ({
348
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
349
- getConfigPath: () => DEFAULT_CONFIG_PATH,
350
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
351
- getCacheDir: () => DEFAULT_CACHE_DIR,
352
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
353
- }));
354
- mock.module("../src/detect", () => ({
355
- detectOllama: async () => setupState.detectOllamaResult,
356
- detectAgentPlatforms: () => setupState.detectAgentPlatformsResult,
357
- }));
358
- mock.module("../src/embedder", () => ({
359
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
360
- isTransformersAvailable: () => setupState.transformersAvailable,
361
- checkEmbeddingAvailability: async () => setupState.checkEmbeddingResult,
362
- }));
363
- mock.module("../src/init", () => ({
364
- akmInit: async (options) => {
365
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
366
- setupState.initCalls.push({ dir });
367
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
368
- },
369
- }));
370
- mock.module("../src/indexer", () => ({
371
- akmIndex: async ({ stashDir }) => {
372
- setupState.indexCalls.push({ stashDir });
373
- if (setupState.indexError) {
374
- throw setupState.indexError;
375
- }
376
- return setupState.indexResult;
377
- },
378
- }));
379
- mock.module("../src/db", () => ({
380
- openDatabase: () => ({}),
381
- closeDatabase: () => { },
382
- isVecAvailable: () => setupState.vecAvailable,
383
- }));
384
- promptState.selects.push("default", "done");
385
- promptState.confirms.push(false, true);
386
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
387
- setupState.indexError = new Error("index exploded");
388
- const { runSetupWizard } = await import("../src/setup/setup");
389
- await runSetupWizard();
390
- expect(setupState.savedConfigs).toHaveLength(1);
391
- expect(setupState.initCalls).toEqual([{ dir: DEFAULT_STASH_DIR }]);
392
- expect(setupState.indexCalls).toEqual([{ stashDir: DEFAULT_STASH_DIR }]);
393
- expect(promptState.logs.some((entry) => entry.includes("index exploded"))).toBe(true);
394
- expect(promptState.outros).toHaveLength(1);
395
- });
396
- test("warns specifically when remote embedding endpoint is unreachable", async () => {
397
- mock.module("@clack/prompts", () => ({
398
- isCancel: () => false,
399
- cancel: (message) => {
400
- promptState.logs.push(`[cancel] ${message}`);
401
- },
402
- confirm: async () => promptState.confirms.shift() ?? false,
403
- select: async () => promptState.selects.shift() ?? "done",
404
- multiselect: async () => promptState.multiselects.shift() ?? [],
405
- text: async () => promptState.texts.shift() ?? "",
406
- spinner: () => ({ start: () => { }, stop: () => { } }),
407
- log: {
408
- step: (message) => {
409
- promptState.logs.push(`[step] ${message}`);
410
- },
411
- info: (message) => {
412
- promptState.logs.push(`[info] ${message}`);
413
- },
414
- warn: (message) => {
415
- promptState.logs.push(`[warn] ${message}`);
416
- },
417
- success: (message) => {
418
- promptState.logs.push(`[success] ${message}`);
419
- },
420
- },
421
- intro: () => { },
422
- outro: () => { },
423
- note: () => { },
424
- }));
425
- mock.module("../src/config", () => ({
426
- DEFAULT_CONFIG: {
427
- semanticSearchMode: "auto",
428
- registries: [
429
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
430
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
431
- ],
432
- output: { format: "json", detail: "brief" },
433
- },
434
- getConfigPath: () => DEFAULT_CONFIG_PATH,
435
- loadConfig: () => setupState.currentConfig,
436
- saveConfig: (config) => {
437
- setupState.savedConfigs.push(config);
438
- },
439
- }));
440
- mock.module("../src/paths", () => ({
441
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
442
- getConfigPath: () => DEFAULT_CONFIG_PATH,
443
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
444
- getCacheDir: () => DEFAULT_CACHE_DIR,
445
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
446
- }));
447
- mock.module("../src/detect", () => ({
448
- detectOllama: async () => ({
449
- available: true,
450
- endpoint: "http://localhost:11434",
451
- models: ["nomic-embed-text", "llama3.2"],
452
- }),
453
- detectAgentPlatforms: () => [],
454
- }));
455
- mock.module("../src/embedder", () => ({
456
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
457
- isTransformersAvailable: () => true,
458
- checkEmbeddingAvailability: async () => ({
459
- available: false,
460
- reason: "remote-unreachable",
461
- message: "connection refused",
462
- }),
463
- }));
464
- mock.module("../src/init", () => ({
465
- akmInit: async (options) => {
466
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
467
- setupState.initCalls.push({ dir });
468
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
469
- },
470
- }));
471
- mock.module("../src/indexer", () => ({
472
- akmIndex: async ({ stashDir }) => {
473
- setupState.indexCalls.push({ stashDir });
474
- return setupState.indexResult;
475
- },
476
- }));
477
- mock.module("../src/db", () => ({
478
- openDatabase: () => ({}),
479
- closeDatabase: () => { },
480
- isVecAvailable: () => false,
481
- }));
482
- promptState.selects.push("default", "nomic-embed-text", "llama3.2", "done");
483
- promptState.confirms.push(true, true, true);
484
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
485
- promptState.texts.push("384");
486
- const { runSetupWizard } = await import("../src/setup/setup");
487
- await runSetupWizard();
488
- expect(promptState.logs.some((entry) => entry.includes("remote embedding endpoint is not reachable"))).toBe(true);
489
- expect(setupState.savedConfigs.at(-1)?.semanticSearchMode).toBe("auto");
490
- });
491
- test("warns specifically when transformers package is missing during setup prep", async () => {
492
- mock.module("@clack/prompts", () => ({
493
- isCancel: () => false,
494
- cancel: () => { },
495
- confirm: async () => promptState.confirms.shift() ?? false,
496
- select: async () => promptState.selects.shift() ?? "done",
497
- multiselect: async () => promptState.multiselects.shift() ?? [],
498
- text: async () => promptState.texts.shift() ?? "",
499
- spinner: () => ({ start: () => { }, stop: () => { } }),
500
- log: {
501
- step: () => { },
502
- info: (message) => {
503
- promptState.logs.push(`[info] ${message}`);
504
- },
505
- warn: (message) => {
506
- promptState.logs.push(`[warn] ${message}`);
507
- },
508
- success: () => { },
509
- },
510
- intro: () => { },
511
- outro: () => { },
512
- note: () => { },
513
- }));
514
- mock.module("../src/config", () => ({
515
- DEFAULT_CONFIG: {
516
- semanticSearchMode: "auto",
517
- registries: [
518
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
519
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
520
- ],
521
- output: { format: "json", detail: "brief" },
522
- },
523
- getConfigPath: () => DEFAULT_CONFIG_PATH,
524
- loadConfig: () => setupState.currentConfig,
525
- saveConfig: (config) => {
526
- setupState.savedConfigs.push(config);
527
- },
528
- }));
529
- mock.module("../src/paths", () => ({
530
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
531
- getConfigPath: () => DEFAULT_CONFIG_PATH,
532
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
533
- getCacheDir: () => DEFAULT_CACHE_DIR,
534
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
535
- }));
536
- mock.module("../src/detect", () => ({
537
- detectOllama: async () => ({ available: false, endpoint: "http://localhost:11434", models: [] }),
538
- detectAgentPlatforms: () => [],
539
- }));
540
- mock.module("../src/embedder", () => ({
541
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
542
- isTransformersAvailable: () => false,
543
- checkEmbeddingAvailability: async () => ({
544
- available: false,
545
- reason: "missing-package",
546
- message: "@huggingface/transformers is not installed.",
547
- }),
548
- }));
549
- mock.module("../src/init", () => ({
550
- akmInit: async (options) => {
551
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
552
- setupState.initCalls.push({ dir });
553
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
554
- },
555
- }));
556
- mock.module("../src/indexer", () => ({
557
- akmIndex: async ({ stashDir }) => {
558
- setupState.indexCalls.push({ stashDir });
559
- return setupState.indexResult;
560
- },
561
- }));
562
- mock.module("../src/db", () => ({
563
- openDatabase: () => ({}),
564
- closeDatabase: () => { },
565
- isVecAvailable: () => false,
566
- }));
567
- promptState.selects.push("default", "done");
568
- promptState.confirms.push(true, true, true);
569
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
570
- const { runSetupWizard } = await import("../src/setup/setup");
571
- await runSetupWizard();
572
- expect(promptState.logs.some((entry) => entry.includes("Install it with: bun add @huggingface/transformers"))).toBe(true);
573
- expect(setupState.savedConfigs.at(-1)?.semanticSearchMode).toBe("auto");
574
- });
575
- test("keeps semantic search enabled and warns when sqlite-vec/db check fails", async () => {
576
- mock.module("@clack/prompts", () => ({
577
- isCancel: () => false,
578
- cancel: () => { },
579
- confirm: async () => promptState.confirms.shift() ?? false,
580
- select: async () => promptState.selects.shift() ?? "done",
581
- multiselect: async () => promptState.multiselects.shift() ?? [],
582
- text: async () => promptState.texts.shift() ?? "",
583
- spinner: () => ({ start: () => { }, stop: () => { } }),
584
- log: {
585
- step: () => { },
586
- info: (message) => {
587
- promptState.logs.push(`[info] ${message}`);
588
- },
589
- warn: (message) => {
590
- promptState.logs.push(`[warn] ${message}`);
591
- },
592
- success: () => { },
593
- },
594
- intro: () => { },
595
- outro: () => { },
596
- note: () => { },
597
- }));
598
- mock.module("../src/config", () => ({
599
- DEFAULT_CONFIG: {
600
- semanticSearchMode: "auto",
601
- registries: [
602
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
603
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
604
- ],
605
- output: { format: "json", detail: "brief" },
606
- },
607
- getConfigPath: () => DEFAULT_CONFIG_PATH,
608
- loadConfig: () => setupState.currentConfig,
609
- saveConfig: (config) => {
610
- setupState.savedConfigs.push(config);
611
- },
612
- }));
613
- mock.module("../src/paths", () => ({
614
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
615
- getConfigPath: () => DEFAULT_CONFIG_PATH,
616
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
617
- getCacheDir: () => DEFAULT_CACHE_DIR,
618
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
619
- }));
620
- mock.module("../src/detect", () => ({
621
- detectOllama: async () => ({ available: false, endpoint: "http://localhost:11434", models: [] }),
622
- detectAgentPlatforms: () => [],
623
- }));
624
- mock.module("../src/embedder", () => ({
625
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
626
- isTransformersAvailable: () => true,
627
- checkEmbeddingAvailability: async () => ({ available: true }),
628
- }));
629
- mock.module("../src/init", () => ({
630
- akmInit: async (options) => {
631
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
632
- setupState.initCalls.push({ dir });
633
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
634
- },
635
- }));
636
- mock.module("../src/indexer", () => ({
637
- akmIndex: async ({ stashDir }) => {
638
- setupState.indexCalls.push({ stashDir });
639
- return setupState.indexResult;
640
- },
641
- }));
642
- mock.module("../src/db", () => ({
643
- openDatabase: () => {
644
- throw new Error("db locked");
645
- },
646
- closeDatabase: () => { },
647
- isVecAvailable: () => false,
648
- }));
649
- promptState.selects.push("default", "done");
650
- promptState.confirms.push(true, true, true);
651
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
652
- const { runSetupWizard } = await import("../src/setup/setup");
653
- await runSetupWizard();
654
- expect(setupState.savedConfigs).toHaveLength(1);
655
- expect(setupState.savedConfigs[0]?.semanticSearchMode).toBe("auto");
656
- expect(promptState.logs.some((entry) => entry.includes("Semantic search will use the JS fallback"))).toBe(true);
657
- });
658
- test("keeps semantic search enabled when asset preparation is skipped", async () => {
659
- mock.module("@clack/prompts", () => ({
660
- isCancel: () => false,
661
- cancel: () => { },
662
- confirm: async () => promptState.confirms.shift() ?? false,
663
- select: async () => promptState.selects.shift() ?? "done",
664
- multiselect: async () => promptState.multiselects.shift() ?? [],
665
- text: async () => promptState.texts.shift() ?? "",
666
- spinner: () => ({ start: () => { }, stop: () => { } }),
667
- log: {
668
- step: () => { },
669
- info: (message) => {
670
- promptState.logs.push(`[info] ${message}`);
671
- },
672
- warn: () => { },
673
- success: () => { },
674
- },
675
- intro: () => { },
676
- outro: () => { },
677
- note: () => { },
678
- }));
679
- mock.module("../src/config", () => ({
680
- DEFAULT_CONFIG: {
681
- semanticSearchMode: "auto",
682
- registries: [
683
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
684
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
685
- ],
686
- output: { format: "json", detail: "brief" },
687
- },
688
- getConfigPath: () => DEFAULT_CONFIG_PATH,
689
- loadConfig: () => setupState.currentConfig,
690
- saveConfig: (config) => {
691
- setupState.savedConfigs.push(config);
692
- },
693
- }));
694
- mock.module("../src/paths", () => ({
695
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
696
- getConfigPath: () => DEFAULT_CONFIG_PATH,
697
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
698
- getCacheDir: () => DEFAULT_CACHE_DIR,
699
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
700
- }));
701
- mock.module("../src/detect", () => ({
702
- detectOllama: async () => ({ available: false, endpoint: "http://localhost:11434", models: [] }),
703
- detectAgentPlatforms: () => [],
704
- }));
705
- mock.module("../src/embedder", () => ({
706
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
707
- isTransformersAvailable: () => true,
708
- checkEmbeddingAvailability: async () => ({ available: true }),
709
- }));
710
- mock.module("../src/init", () => ({
711
- akmInit: async (options) => {
712
- const dir = options?.dir ?? DEFAULT_STASH_DIR;
713
- setupState.initCalls.push({ dir });
714
- return { stashDir: dir, created: true, configPath: DEFAULT_CONFIG_PATH };
715
- },
716
- }));
717
- mock.module("../src/indexer", () => ({
718
- akmIndex: async ({ stashDir }) => {
719
- setupState.indexCalls.push({ stashDir });
720
- return setupState.indexResult;
721
- },
722
- }));
723
- mock.module("../src/db", () => ({
724
- openDatabase: () => ({}),
725
- closeDatabase: () => { },
726
- isVecAvailable: () => false,
727
- }));
728
- promptState.selects.push("default", "done");
729
- promptState.confirms.push(true, false, true);
730
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
731
- const { runSetupWizard } = await import("../src/setup/setup");
732
- await runSetupWizard();
733
- expect(setupState.savedConfigs).toHaveLength(1);
734
- expect(setupState.savedConfigs[0]?.semanticSearchMode).toBe("auto");
735
- expect(promptState.logs.some((entry) => entry.includes("asset preparation was skipped"))).toBe(true);
736
- });
737
- test("stops before init when config save fails", async () => {
738
- mock.module("@clack/prompts", () => ({
739
- isCancel: () => false,
740
- cancel: () => { },
741
- confirm: async () => promptState.confirms.shift() ?? false,
742
- select: async () => promptState.selects.shift() ?? "done",
743
- multiselect: async () => promptState.multiselects.shift() ?? [],
744
- text: async () => promptState.texts.shift() ?? "",
745
- spinner: () => ({ start: () => { }, stop: () => { } }),
746
- log: { step: () => { }, info: () => { }, warn: () => { }, success: () => { } },
747
- intro: () => { },
748
- outro: () => { },
749
- note: () => { },
750
- }));
751
- let saveCalls = 0;
752
- mock.module("../src/config", () => ({
753
- DEFAULT_CONFIG: {
754
- semanticSearchMode: "auto",
755
- registries: [
756
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
757
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
758
- ],
759
- output: { format: "json", detail: "brief" },
760
- },
761
- getConfigPath: () => DEFAULT_CONFIG_PATH,
762
- loadConfig: () => setupState.currentConfig,
763
- saveConfig: () => {
764
- saveCalls += 1;
765
- throw new Error("EACCES config.json");
766
- },
767
- }));
768
- mock.module("../src/paths", () => ({
769
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
770
- getConfigPath: () => DEFAULT_CONFIG_PATH,
771
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
772
- getCacheDir: () => DEFAULT_CACHE_DIR,
773
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
774
- }));
775
- mock.module("../src/detect", () => ({
776
- detectOllama: async () => ({ available: false, endpoint: "http://localhost:11434", models: [] }),
777
- detectAgentPlatforms: () => [],
778
- }));
779
- mock.module("../src/embedder", () => ({
780
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
781
- isTransformersAvailable: () => true,
782
- checkEmbeddingAvailability: async () => ({ available: true }),
783
- }));
784
- mock.module("../src/init", () => ({
785
- akmInit: async () => {
786
- throw new Error("init should not run");
787
- },
788
- }));
789
- mock.module("../src/indexer", () => ({
790
- akmIndex: async () => {
791
- throw new Error("index should not run");
792
- },
793
- }));
794
- mock.module("../src/db", () => ({
795
- openDatabase: () => ({}),
796
- closeDatabase: () => { },
797
- isVecAvailable: () => false,
798
- }));
799
- promptState.selects.push("default", "done");
800
- promptState.confirms.push(false, true);
801
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
802
- const { runSetupWizard } = await import("../src/setup/setup");
803
- await expect(runSetupWizard()).rejects.toThrow("EACCES config.json");
804
- expect(saveCalls).toBe(1);
805
- expect(setupState.initCalls).toHaveLength(0);
806
- expect(setupState.indexCalls).toHaveLength(0);
807
- });
808
- test("persists config before surfacing init failure", async () => {
809
- mock.module("@clack/prompts", () => ({
810
- isCancel: () => false,
811
- cancel: () => { },
812
- confirm: async () => promptState.confirms.shift() ?? false,
813
- select: async () => promptState.selects.shift() ?? "done",
814
- multiselect: async () => promptState.multiselects.shift() ?? [],
815
- text: async () => promptState.texts.shift() ?? "",
816
- spinner: () => ({ start: () => { }, stop: () => { } }),
817
- log: { step: () => { }, info: () => { }, warn: () => { }, success: () => { } },
818
- intro: () => { },
819
- outro: () => { },
820
- note: () => { },
821
- }));
822
- mock.module("../src/config", () => ({
823
- DEFAULT_CONFIG: {
824
- semanticSearchMode: "auto",
825
- registries: [
826
- { url: DEFAULT_REGISTRY_URLS[0], name: "official" },
827
- { url: DEFAULT_REGISTRY_URLS[1], name: "skills.sh", provider: "skills-sh" },
828
- ],
829
- output: { format: "json", detail: "brief" },
830
- },
831
- getConfigPath: () => DEFAULT_CONFIG_PATH,
832
- loadConfig: () => setupState.currentConfig,
833
- saveConfig: (config) => {
834
- setupState.savedConfigs.push(config);
835
- },
836
- }));
837
- mock.module("../src/paths", () => ({
838
- getDefaultStashDir: () => DEFAULT_STASH_DIR,
839
- getConfigPath: () => DEFAULT_CONFIG_PATH,
840
- getConfigDir: () => path.dirname(DEFAULT_CONFIG_PATH),
841
- getCacheDir: () => DEFAULT_CACHE_DIR,
842
- getSemanticStatusPath: () => path.join(DEFAULT_CACHE_DIR, "semantic-status.json"),
843
- }));
844
- mock.module("../src/detect", () => ({
845
- detectOllama: async () => ({ available: false, endpoint: "http://localhost:11434", models: [] }),
846
- detectAgentPlatforms: () => [],
847
- }));
848
- mock.module("../src/embedder", () => ({
849
- DEFAULT_LOCAL_MODEL: "Xenova/bge-small-en-v1.5",
850
- isTransformersAvailable: () => true,
851
- checkEmbeddingAvailability: async () => ({ available: true }),
852
- }));
853
- mock.module("../src/init", () => ({
854
- akmInit: async () => {
855
- throw new Error("EACCES stash init");
856
- },
857
- }));
858
- mock.module("../src/indexer", () => ({
859
- akmIndex: async () => {
860
- throw new Error("index should not run");
861
- },
862
- }));
863
- mock.module("../src/db", () => ({
864
- openDatabase: () => ({}),
865
- closeDatabase: () => { },
866
- isVecAvailable: () => false,
867
- }));
868
- promptState.selects.push("default", "done");
869
- promptState.confirms.push(false, true);
870
- promptState.multiselects.push([...DEFAULT_REGISTRY_URLS], []);
871
- const { runSetupWizard } = await import("../src/setup/setup");
872
- await expect(runSetupWizard()).rejects.toThrow("EACCES stash init");
873
- expect(setupState.savedConfigs).toHaveLength(1);
874
- expect(setupState.savedConfigs[0]?.stashDir).toBe(DEFAULT_STASH_DIR);
875
- expect(setupState.indexCalls).toHaveLength(0);
876
- });
877
- });