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,279 +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 { akmProposalAccept, akmProposalDiff, akmProposalList, akmProposalReject, akmProposalShow, } from "../src/commands/proposal";
6
- import { readEvents } from "../src/core/events";
7
- import { createProposal, diffProposal, getProposal, listProposals, validateProposal } from "../src/core/proposals";
8
- // ── Test setup ──────────────────────────────────────────────────────────────
9
- const tempDirs = [];
10
- const savedEnv = {
11
- AKM_STASH_DIR: process.env.AKM_STASH_DIR,
12
- XDG_CACHE_HOME: process.env.XDG_CACHE_HOME,
13
- XDG_CONFIG_HOME: process.env.XDG_CONFIG_HOME,
14
- };
15
- function makeTempDir(prefix) {
16
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
17
- tempDirs.push(dir);
18
- return dir;
19
- }
20
- function makeStashDir() {
21
- const stash = makeTempDir("akm-proposals-stash-");
22
- // Pre-create the canonical type directories the writer expects.
23
- for (const dir of ["lessons", "skills", "memories"]) {
24
- fs.mkdirSync(path.join(stash, dir), { recursive: true });
25
- }
26
- return stash;
27
- }
28
- function makeConfig(stashDir) {
29
- return {
30
- stashDir,
31
- sources: [{ type: "filesystem", name: "stash", path: stashDir, writable: true }],
32
- defaultWriteTarget: "stash",
33
- };
34
- }
35
- beforeEach(() => {
36
- process.env.XDG_CACHE_HOME = makeTempDir("akm-proposals-cache-");
37
- process.env.XDG_CONFIG_HOME = makeTempDir("akm-proposals-config-");
38
- });
39
- afterEach(() => {
40
- if (savedEnv.AKM_STASH_DIR === undefined)
41
- delete process.env.AKM_STASH_DIR;
42
- else
43
- process.env.AKM_STASH_DIR = savedEnv.AKM_STASH_DIR;
44
- if (savedEnv.XDG_CACHE_HOME === undefined)
45
- delete process.env.XDG_CACHE_HOME;
46
- else
47
- process.env.XDG_CACHE_HOME = savedEnv.XDG_CACHE_HOME;
48
- if (savedEnv.XDG_CONFIG_HOME === undefined)
49
- delete process.env.XDG_CONFIG_HOME;
50
- else
51
- process.env.XDG_CONFIG_HOME = savedEnv.XDG_CONFIG_HOME;
52
- for (const dir of tempDirs.splice(0)) {
53
- fs.rmSync(dir, { recursive: true, force: true });
54
- }
55
- });
56
- // ── Tests ───────────────────────────────────────────────────────────────────
57
- const VALID_LESSON = `---\ndescription: Use ripgrep before grep\nwhen_to_use: Searching large repos for patterns\n---\n\nPrefer rg over grep when scanning large code repos.\n`;
58
- describe("createProposal / listProposals / getProposal", () => {
59
- test("round-trip: create → list → show → accept materialises asset and emits promoted event", async () => {
60
- const stash = makeStashDir();
61
- const config = makeConfig(stash);
62
- const created = createProposal(stash, {
63
- ref: "lesson:rg-over-grep",
64
- source: "distill",
65
- sourceRun: "run-123",
66
- payload: { content: VALID_LESSON },
67
- });
68
- expect(created.id).toBeDefined();
69
- expect(created.status).toBe("pending");
70
- // list
71
- const listResult = akmProposalList({ stashDir: stash });
72
- expect(listResult.totalCount).toBe(1);
73
- expect(listResult.proposals[0]?.id).toBe(created.id);
74
- // show
75
- const showResult = akmProposalShow({ stashDir: stash, id: created.id });
76
- expect(showResult.proposal.ref).toBe("lesson:rg-over-grep");
77
- expect(showResult.validation.ok).toBe(true);
78
- // accept
79
- const acceptResult = await akmProposalAccept({ stashDir: stash, id: created.id, config });
80
- expect(acceptResult.ok).toBe(true);
81
- expect(acceptResult.ref).toBe("lesson:rg-over-grep");
82
- expect(fs.existsSync(acceptResult.assetPath)).toBe(true);
83
- expect(fs.readFileSync(acceptResult.assetPath, "utf8")).toContain("Prefer rg over grep");
84
- // status promoted
85
- const promoted = getProposal(stash, created.id);
86
- expect(promoted.status).toBe("accepted");
87
- expect(promoted.review?.outcome).toBe("accepted");
88
- // promoted event emitted
89
- const events = readEvents({ type: "promoted" });
90
- expect(events.events.length).toBe(1);
91
- expect(events.events[0]?.ref).toBe("lesson:rg-over-grep");
92
- expect(events.events[0]?.metadata?.proposalId).toBe(created.id);
93
- });
94
- test("reject path: archive contains entry, status rejected, rejected event emitted", () => {
95
- const stash = makeStashDir();
96
- const created = createProposal(stash, {
97
- ref: "lesson:bad-idea",
98
- source: "reflect",
99
- payload: { content: VALID_LESSON },
100
- });
101
- const result = akmProposalReject({ stashDir: stash, id: created.id, reason: "duplicate of existing lesson" });
102
- expect(result.ok).toBe(true);
103
- expect(result.proposal.status).toBe("rejected");
104
- expect(result.proposal.review?.reason).toBe("duplicate of existing lesson");
105
- // archive directory contains it
106
- const archivePath = path.join(stash, ".akm", "proposals", "archive", created.id, "proposal.json");
107
- expect(fs.existsSync(archivePath)).toBe(true);
108
- // live queue empty
109
- const live = listProposals(stash);
110
- expect(live).toHaveLength(0);
111
- // rejected event
112
- const events = readEvents({ type: "rejected" });
113
- expect(events.events.length).toBe(1);
114
- expect(events.events[0]?.metadata?.reason).toBe("duplicate of existing lesson");
115
- });
116
- test("multiple proposals for same ref: distinct ids, no path collision", () => {
117
- const stash = makeStashDir();
118
- const a = createProposal(stash, { ref: "lesson:dup", source: "reflect", payload: { content: VALID_LESSON } });
119
- const b = createProposal(stash, { ref: "lesson:dup", source: "distill", payload: { content: VALID_LESSON } });
120
- expect(a.id).not.toBe(b.id);
121
- const list = listProposals(stash);
122
- expect(list.length).toBe(2);
123
- const ids = list.map((p) => p.id).sort();
124
- expect(ids).toEqual([a.id, b.id].sort());
125
- });
126
- });
127
- describe("diff path", () => {
128
- test("new asset: shows new-asset diff with /dev/null marker", () => {
129
- const stash = makeStashDir();
130
- const config = makeConfig(stash);
131
- const proposal = createProposal(stash, {
132
- ref: "lesson:fresh",
133
- source: "reflect",
134
- payload: { content: VALID_LESSON },
135
- });
136
- const diff = diffProposal(stash, config, proposal.id);
137
- expect(diff.isNew).toBe(true);
138
- expect(diff.unified).toContain("/dev/null");
139
- expect(diff.unified).toContain("Prefer rg over grep");
140
- });
141
- test("existing asset + proposal: produces unified diff", async () => {
142
- const stash = makeStashDir();
143
- const config = makeConfig(stash);
144
- // Pre-write an existing lesson so the diff has a left-hand side.
145
- const lessonPath = path.join(stash, "lessons", "rg-over-grep.md");
146
- fs.writeFileSync(lessonPath, `---\ndescription: Use ripgrep before grep\nwhen_to_use: Searching repos\n---\n\nOriginal body.\n`, "utf8");
147
- const proposal = createProposal(stash, {
148
- ref: "lesson:rg-over-grep",
149
- source: "reflect",
150
- payload: { content: VALID_LESSON },
151
- });
152
- const diffResult = akmProposalDiff({ stashDir: stash, id: proposal.id, config });
153
- expect(diffResult.isNew).toBe(false);
154
- expect(diffResult.unified).toContain("---");
155
- expect(diffResult.unified).toContain("+++");
156
- expect(diffResult.unified).toContain("Prefer rg over grep");
157
- });
158
- });
159
- describe("validation failure", () => {
160
- test("invalid lesson frontmatter → accept fails non-zero with clear error", async () => {
161
- const stash = makeStashDir();
162
- const config = makeConfig(stash);
163
- const proposal = createProposal(stash, {
164
- ref: "lesson:no-fields",
165
- source: "distill",
166
- payload: { content: `---\ndescription: ""\nwhen_to_use: ""\n---\n\nbody\n` },
167
- });
168
- const report = validateProposal(proposal);
169
- expect(report.ok).toBe(false);
170
- expect(report.findings.length).toBeGreaterThan(0);
171
- let threw = false;
172
- try {
173
- await akmProposalAccept({ stashDir: stash, id: proposal.id, config });
174
- }
175
- catch (err) {
176
- threw = true;
177
- expect(err.message).toContain("validation");
178
- }
179
- expect(threw).toBe(true);
180
- // Proposal still pending; no asset materialised
181
- const stillPending = getProposal(stash, proposal.id);
182
- expect(stillPending.status).toBe("pending");
183
- expect(fs.existsSync(path.join(stash, "lessons", "no-fields.md"))).toBe(false);
184
- });
185
- test("empty content → validation fails", () => {
186
- const stash = makeStashDir();
187
- const proposal = createProposal(stash, {
188
- ref: "lesson:empty",
189
- source: "distill",
190
- payload: { content: "" },
191
- });
192
- const report = validateProposal(proposal);
193
- expect(report.ok).toBe(false);
194
- expect(report.findings.some((f) => f.kind === "empty-content")).toBe(true);
195
- });
196
- });
197
- // ── #284 GAP-HIGH backfill ───────────────────────────────────────────────────
198
- describe("akmProposalReject — non-pending status (#284 HIGH 4)", () => {
199
- test("rejecting an already-archived proposal → UsageError with .code INVALID_FLAG_VALUE", async () => {
200
- const stash = makeStashDir();
201
- const created = createProposal(stash, {
202
- ref: "lesson:once",
203
- source: "reflect",
204
- payload: { content: VALID_LESSON },
205
- });
206
- // First reject moves it to the archive.
207
- akmProposalReject({ stashDir: stash, id: created.id });
208
- // Second reject must fail with a typed UsageError (.code load-bearing).
209
- let thrown;
210
- try {
211
- akmProposalReject({ stashDir: stash, id: created.id });
212
- }
213
- catch (err) {
214
- thrown = err;
215
- }
216
- expect(thrown).toBeInstanceOf(Error);
217
- const e = thrown;
218
- expect(e.name).toBe("UsageError");
219
- expect(e.code).toBe("INVALID_FLAG_VALUE");
220
- expect(e.message).toMatch(/not pending|already/i);
221
- });
222
- });
223
- describe("akmProposalShow / akmProposalDiff — missing id (#284 HIGH 5)", () => {
224
- test("akmProposalShow on missing id → NotFoundError with .code FILE_NOT_FOUND", () => {
225
- const stash = makeStashDir();
226
- let thrown;
227
- try {
228
- akmProposalShow({ stashDir: stash, id: "deadbeef-0000-0000-0000-000000000000" });
229
- }
230
- catch (err) {
231
- thrown = err;
232
- }
233
- expect(thrown).toBeInstanceOf(Error);
234
- const e = thrown;
235
- expect(e.name).toBe("NotFoundError");
236
- expect(e.code).toBe("FILE_NOT_FOUND");
237
- });
238
- test("akmProposalDiff on missing id → NotFoundError with .code FILE_NOT_FOUND", () => {
239
- const stash = makeStashDir();
240
- const config = makeConfig(stash);
241
- let thrown;
242
- try {
243
- akmProposalDiff({ stashDir: stash, id: "deadbeef-0000-0000-0000-000000000001", config });
244
- }
245
- catch (err) {
246
- thrown = err;
247
- }
248
- expect(thrown).toBeInstanceOf(Error);
249
- const e = thrown;
250
- expect(e.name).toBe("NotFoundError");
251
- expect(e.code).toBe("FILE_NOT_FOUND");
252
- });
253
- });
254
- describe("akmProposalAccept — validation failure (#284 HIGH 6)", () => {
255
- test("validation failure → no `promoted` event emitted; proposal stays pending", async () => {
256
- const stash = makeStashDir();
257
- const config = makeConfig(stash);
258
- // Empty content — fails the lesson lint.
259
- const proposal = createProposal(stash, {
260
- ref: "lesson:invalid",
261
- source: "distill",
262
- payload: { content: "" },
263
- });
264
- let threw = false;
265
- try {
266
- await akmProposalAccept({ stashDir: stash, id: proposal.id, config });
267
- }
268
- catch {
269
- threw = true;
270
- }
271
- expect(threw).toBe(true);
272
- // Critical: `promoted` event must NOT be emitted on validation failure.
273
- const promoted = readEvents({ type: "promoted" });
274
- expect(promoted.events.length).toBe(0);
275
- // And the proposal stays pending.
276
- const stillPending = getProposal(stash, proposal.id);
277
- expect(stillPending.status).toBe("pending");
278
- });
279
- });
@@ -1,271 +0,0 @@
1
- /**
2
- * Issue #224: `quality: "proposed"` is excluded from default search.
3
- *
4
- * Covers:
5
- * - default search excludes `proposed` entries
6
- * - `--include-proposed` (i.e. `akmSearch({ includeProposed: true })`) restores them
7
- * - `generated` and `curated` remain on by default
8
- * - unknown quality values warn once and remain searchable
9
- * - SearchHit projection surfaces optional `quality` when present
10
- *
11
- * Mirrors the harness in `tests/parallel-search.test.ts` and
12
- * `tests/issue-36-repro.test.ts`.
13
- */
14
- import { afterAll, afterEach, beforeEach, describe, expect, test } from "bun:test";
15
- import fs from "node:fs";
16
- import os from "node:os";
17
- import path from "node:path";
18
- import { akmSearch } from "../src/commands/search";
19
- import { saveConfig } from "../src/core/config";
20
- import { akmIndex } from "../src/indexer/indexer";
21
- import { _resetUnknownQualityWarnings, isProposedQuality, validateStashEntry } from "../src/indexer/metadata";
22
- // ── Temp directory tracking ─────────────────────────────────────────────────
23
- const createdTmpDirs = [];
24
- function createTmpDir(prefix = "akm-issue224-") {
25
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
26
- createdTmpDirs.push(dir);
27
- return dir;
28
- }
29
- afterAll(() => {
30
- for (const dir of createdTmpDirs) {
31
- fs.rmSync(dir, { recursive: true, force: true });
32
- }
33
- });
34
- function writeFile(filePath, content = "") {
35
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
36
- fs.writeFileSync(filePath, content);
37
- }
38
- function tmpStash() {
39
- const dir = createTmpDir("akm-issue224-stash-");
40
- for (const sub of ["skills", "commands", "agents", "knowledge", "scripts"]) {
41
- fs.mkdirSync(path.join(dir, sub), { recursive: true });
42
- }
43
- return dir;
44
- }
45
- async function buildTestIndex(stashDir) {
46
- process.env.AKM_STASH_DIR = stashDir;
47
- saveConfig({ semanticSearchMode: "off" });
48
- return akmIndex({ stashDir, full: true });
49
- }
50
- // ── Environment isolation ───────────────────────────────────────────────────
51
- const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
52
- const originalXdgConfigHome = process.env.XDG_CONFIG_HOME;
53
- const originalAkmStashDir = process.env.AKM_STASH_DIR;
54
- let testCacheDir = "";
55
- let testConfigDir = "";
56
- beforeEach(() => {
57
- testCacheDir = createTmpDir("akm-issue224-cache-");
58
- testConfigDir = createTmpDir("akm-issue224-config-");
59
- process.env.XDG_CACHE_HOME = testCacheDir;
60
- process.env.XDG_CONFIG_HOME = testConfigDir;
61
- _resetUnknownQualityWarnings();
62
- });
63
- afterEach(() => {
64
- if (originalXdgCacheHome === undefined) {
65
- delete process.env.XDG_CACHE_HOME;
66
- }
67
- else {
68
- process.env.XDG_CACHE_HOME = originalXdgCacheHome;
69
- }
70
- if (originalXdgConfigHome === undefined) {
71
- delete process.env.XDG_CONFIG_HOME;
72
- }
73
- else {
74
- process.env.XDG_CONFIG_HOME = originalXdgConfigHome;
75
- }
76
- if (originalAkmStashDir === undefined) {
77
- delete process.env.AKM_STASH_DIR;
78
- }
79
- else {
80
- process.env.AKM_STASH_DIR = originalAkmStashDir;
81
- }
82
- if (testCacheDir) {
83
- fs.rmSync(testCacheDir, { recursive: true, force: true });
84
- testCacheDir = "";
85
- }
86
- if (testConfigDir) {
87
- fs.rmSync(testConfigDir, { recursive: true, force: true });
88
- testConfigDir = "";
89
- }
90
- });
91
- // ── Helpers ─────────────────────────────────────────────────────────────────
92
- /**
93
- * Author three skills with deliberately distinct quality markers under the
94
- * same query token so default-vs-include-proposed deltas are obvious.
95
- */
96
- function seedQualitySpread(stashDir) {
97
- // Curated entry
98
- writeFile(path.join(stashDir, "skills", "deploy-curated", "SKILL.md"), "---\ndescription: Curated deploy skill\n---\n# Deploy curated\n");
99
- writeFile(path.join(stashDir, "skills", "deploy-curated", ".stash.json"), JSON.stringify({
100
- entries: [
101
- {
102
- name: "deploy-curated",
103
- type: "skill",
104
- description: "Curated deploy skill",
105
- tags: ["deploy"],
106
- filename: "SKILL.md",
107
- quality: "curated",
108
- },
109
- ],
110
- }));
111
- // Generated entry
112
- writeFile(path.join(stashDir, "skills", "deploy-generated", "SKILL.md"), "---\ndescription: Generated deploy skill\n---\n# Deploy generated\n");
113
- writeFile(path.join(stashDir, "skills", "deploy-generated", ".stash.json"), JSON.stringify({
114
- entries: [
115
- {
116
- name: "deploy-generated",
117
- type: "skill",
118
- description: "Generated deploy skill",
119
- tags: ["deploy"],
120
- filename: "SKILL.md",
121
- quality: "generated",
122
- },
123
- ],
124
- }));
125
- // Proposed entry — should be filtered by default
126
- writeFile(path.join(stashDir, "skills", "deploy-proposed", "SKILL.md"), "---\ndescription: Proposed deploy skill\n---\n# Deploy proposed\n");
127
- writeFile(path.join(stashDir, "skills", "deploy-proposed", ".stash.json"), JSON.stringify({
128
- entries: [
129
- {
130
- name: "deploy-proposed",
131
- type: "skill",
132
- description: "Proposed deploy skill",
133
- tags: ["deploy"],
134
- filename: "SKILL.md",
135
- quality: "proposed",
136
- },
137
- ],
138
- }));
139
- }
140
- // ── Tests ───────────────────────────────────────────────────────────────────
141
- describe("Issue #224: proposed quality is excluded from default search", () => {
142
- test("default search returns curated + generated, excludes proposed", async () => {
143
- const stashDir = tmpStash();
144
- seedQualitySpread(stashDir);
145
- await buildTestIndex(stashDir);
146
- const result = await akmSearch({ query: "deploy", source: "stash" });
147
- const hits = result.hits.filter((h) => h.type !== "registry");
148
- const names = hits.map((h) => h.name);
149
- expect(names).toContain("deploy-curated");
150
- expect(names).toContain("deploy-generated");
151
- expect(names).not.toContain("deploy-proposed");
152
- });
153
- test("--include-proposed surfaces proposed entries alongside the rest", async () => {
154
- const stashDir = tmpStash();
155
- seedQualitySpread(stashDir);
156
- await buildTestIndex(stashDir);
157
- const result = await akmSearch({ query: "deploy", source: "stash", includeProposed: true });
158
- const hits = result.hits.filter((h) => h.type !== "registry");
159
- const names = hits.map((h) => h.name);
160
- expect(names).toContain("deploy-curated");
161
- expect(names).toContain("deploy-generated");
162
- expect(names).toContain("deploy-proposed");
163
- });
164
- test("empty-query enumeration also excludes proposed by default", async () => {
165
- const stashDir = tmpStash();
166
- seedQualitySpread(stashDir);
167
- await buildTestIndex(stashDir);
168
- // Empty query path goes through getAllEntries — exercise that code path too.
169
- const result = await akmSearch({ query: ".", source: "stash", limit: 50 });
170
- const hits = result.hits.filter((h) => h.type !== "registry");
171
- const names = hits.map((h) => h.name);
172
- expect(names).toContain("deploy-curated");
173
- expect(names).toContain("deploy-generated");
174
- expect(names).not.toContain("deploy-proposed");
175
- const opted = await akmSearch({ query: ".", source: "stash", limit: 50, includeProposed: true });
176
- const optedNames = opted.hits.filter((h) => h.type !== "registry").map((h) => h.name);
177
- expect(optedNames).toContain("deploy-proposed");
178
- });
179
- });
180
- describe("Issue #224: SearchHit surfaces optional quality field", () => {
181
- test("hits carry quality verbatim when present, omit it otherwise", async () => {
182
- const stashDir = tmpStash();
183
- seedQualitySpread(stashDir);
184
- await buildTestIndex(stashDir);
185
- const result = await akmSearch({ query: "deploy", source: "stash", includeProposed: true });
186
- const hits = result.hits.filter((h) => h.type !== "registry");
187
- const curated = hits.find((h) => h.name === "deploy-curated");
188
- const generated = hits.find((h) => h.name === "deploy-generated");
189
- const proposed = hits.find((h) => h.name === "deploy-proposed");
190
- expect(curated?.quality).toBe("curated");
191
- expect(generated?.quality).toBe("generated");
192
- expect(proposed?.quality).toBe("proposed");
193
- });
194
- });
195
- describe("Issue #224: unknown quality values warn once and remain searchable", () => {
196
- test("validateStashEntry preserves unknown quality and warns once per value", () => {
197
- const calls = [];
198
- const originalWarn = console.warn;
199
- console.warn = (...args) => {
200
- calls.push(args.map(String).join(" "));
201
- };
202
- try {
203
- _resetUnknownQualityWarnings();
204
- const a = validateStashEntry({ name: "a", type: "skill", quality: "experimental" });
205
- const b = validateStashEntry({ name: "b", type: "skill", quality: "experimental" });
206
- const c = validateStashEntry({ name: "c", type: "skill", quality: "draft" });
207
- expect(a?.quality).toBe("experimental");
208
- expect(b?.quality).toBe("experimental");
209
- expect(c?.quality).toBe("draft");
210
- // One warn per unique unknown value — not per occurrence.
211
- const unknownWarns = calls.filter((c) => c.includes("unknown quality value"));
212
- expect(unknownWarns.length).toBe(2);
213
- expect(unknownWarns.some((m) => m.includes("experimental"))).toBe(true);
214
- expect(unknownWarns.some((m) => m.includes("draft"))).toBe(true);
215
- // Known values must not warn.
216
- const known = validateStashEntry({ name: "d", type: "skill", quality: "curated" });
217
- expect(known?.quality).toBe("curated");
218
- const knownGen = validateStashEntry({ name: "e", type: "skill", quality: "generated" });
219
- expect(knownGen?.quality).toBe("generated");
220
- const knownProp = validateStashEntry({ name: "f", type: "skill", quality: "proposed" });
221
- expect(knownProp?.quality).toBe("proposed");
222
- const stillTwo = calls.filter((c) => c.includes("unknown quality value")).length;
223
- expect(stillTwo).toBe(2);
224
- }
225
- finally {
226
- console.warn = originalWarn;
227
- }
228
- });
229
- test("unknown quality entries remain in default search (treated as included-by-default)", async () => {
230
- const stashDir = tmpStash();
231
- writeFile(path.join(stashDir, "skills", "deploy-experimental", "SKILL.md"), "---\ndescription: Experimental quality marker test\n---\n# deploy\n");
232
- writeFile(path.join(stashDir, "skills", "deploy-experimental", ".stash.json"), JSON.stringify({
233
- entries: [
234
- {
235
- name: "deploy-experimental",
236
- type: "skill",
237
- description: "Experimental quality marker test",
238
- tags: ["deploy"],
239
- filename: "SKILL.md",
240
- quality: "experimental",
241
- },
242
- ],
243
- }));
244
- // Suppress warns from the indexer load path so they don't pollute test output.
245
- const originalWarn = console.warn;
246
- console.warn = () => { };
247
- try {
248
- await buildTestIndex(stashDir);
249
- const result = await akmSearch({ query: "deploy", source: "stash" });
250
- const hits = result.hits.filter((h) => h.type !== "registry");
251
- const names = hits.map((h) => h.name);
252
- expect(names).toContain("deploy-experimental");
253
- // Quality field is surfaced verbatim on the hit.
254
- const experimental = hits.find((h) => h.name === "deploy-experimental");
255
- expect(experimental?.quality).toBe("experimental");
256
- }
257
- finally {
258
- console.warn = originalWarn;
259
- }
260
- });
261
- });
262
- describe("Issue #224: isProposedQuality helper", () => {
263
- test("returns true only for the literal 'proposed' marker", () => {
264
- expect(isProposedQuality("proposed")).toBe(true);
265
- expect(isProposedQuality("curated")).toBe(false);
266
- expect(isProposedQuality("generated")).toBe(false);
267
- expect(isProposedQuality(undefined)).toBe(false);
268
- expect(isProposedQuality("PROPOSED")).toBe(false);
269
- expect(isProposedQuality("experimental")).toBe(false);
270
- });
271
- });
@@ -1,32 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { registerProvider, resolveProviderFactory } from "../src/registry/factory";
3
- import { resolveSourceProviderFactory } from "../src/sources/provider-factory";
4
- describe("provider-registry", () => {
5
- test("resolveProviderFactory returns null for unknown type", () => {
6
- expect(resolveProviderFactory("nonexistent-provider-xyz")).toBeNull();
7
- });
8
- test("registerProvider + resolveProviderFactory round-trips", () => {
9
- const factory = (() => ({
10
- type: "test-provider",
11
- search: async () => ({ hits: [] }),
12
- searchKits: async () => [],
13
- getKit: async () => null,
14
- canHandle: () => false,
15
- }));
16
- registerProvider("test-roundtrip", factory);
17
- expect(resolveProviderFactory("test-roundtrip")).toBe(factory);
18
- });
19
- test("static-index is registered after import", async () => {
20
- // Importing triggers self-registration
21
- await import("../src/registry/providers/static-index");
22
- expect(resolveProviderFactory("static-index")).not.toBeNull();
23
- });
24
- test("skills-sh is registered after import", async () => {
25
- await import("../src/registry/providers/skills-sh");
26
- expect(resolveProviderFactory("skills-sh")).not.toBeNull();
27
- });
28
- test("filesystem stash provider is registered after import", async () => {
29
- await import("../src/sources/providers/filesystem");
30
- expect(resolveSourceProviderFactory("filesystem")).not.toBeNull();
31
- });
32
- });