@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18

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 (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -1
  3. package/bin/aiwg.mjs +349 -0
  4. package/dist/src/a2a/agent-card.js +145 -0
  5. package/dist/src/a2a/client.js +411 -0
  6. package/dist/src/a2a/hitl-cli.js +171 -0
  7. package/dist/src/a2a/hitl-driver.js +370 -0
  8. package/dist/src/a2a/hitl.js +181 -0
  9. package/dist/src/a2a/http.js +193 -0
  10. package/dist/src/a2a/jcs.js +128 -0
  11. package/dist/src/a2a/jws.js +187 -0
  12. package/dist/src/a2a/types.js +24 -0
  13. package/dist/src/a2a/webhook.js +240 -0
  14. package/dist/src/activity-log/cli.js +348 -0
  15. package/dist/src/activity-log/parser.js +81 -0
  16. package/dist/src/activity-log/types.js +50 -0
  17. package/dist/src/agents/agent-deployer.js +367 -0
  18. package/dist/src/agents/agent-packager.js +271 -0
  19. package/dist/src/agents/agent-validator.js +271 -0
  20. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  21. package/dist/src/agents/grounding/types.js +12 -0
  22. package/dist/src/agents/index.js +10 -0
  23. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  24. package/dist/src/agents/types.js +7 -0
  25. package/dist/src/api/index.d.ts +10 -0
  26. package/dist/src/api/index.js +10 -0
  27. package/dist/src/artifacts/address-parser.js +73 -0
  28. package/dist/src/artifacts/audit/cli.js +183 -0
  29. package/dist/src/artifacts/audit/drift.js +122 -0
  30. package/dist/src/artifacts/audit/types.js +12 -0
  31. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  32. package/dist/src/artifacts/backends/json-backend.js +129 -0
  33. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  34. package/dist/src/artifacts/browser-export.js +622 -0
  35. package/dist/src/artifacts/capability-resolver.js +94 -0
  36. package/dist/src/artifacts/checksum-manifest.js +91 -0
  37. package/dist/src/artifacts/citation-parser.js +162 -0
  38. package/dist/src/artifacts/cli.js +1486 -0
  39. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  40. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  41. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  42. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  43. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  44. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  45. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  46. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  47. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  48. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  49. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  51. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  52. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  53. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  54. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  55. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  56. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  57. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  58. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  60. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  61. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  62. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  63. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  64. package/dist/src/artifacts/corpus-views/build.js +126 -0
  65. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  66. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  67. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  68. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  69. package/dist/src/artifacts/dep-graph.js +173 -0
  70. package/dist/src/artifacts/discover-facets.js +375 -0
  71. package/dist/src/artifacts/embedding-index.js +354 -0
  72. package/dist/src/artifacts/enrichment/cli.js +240 -0
  73. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  74. package/dist/src/artifacts/enrichment/store.js +90 -0
  75. package/dist/src/artifacts/enrichment/types.js +12 -0
  76. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  77. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  78. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  79. package/dist/src/artifacts/fulltext.js +108 -0
  80. package/dist/src/artifacts/graph-backend.js +51 -0
  81. package/dist/src/artifacts/graph-query.js +247 -0
  82. package/dist/src/artifacts/hybrid-query.js +225 -0
  83. package/dist/src/artifacts/index-builder.js +1089 -0
  84. package/dist/src/artifacts/index-reader.js +112 -0
  85. package/dist/src/artifacts/index-status.js +193 -0
  86. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  87. package/dist/src/artifacts/move.js +154 -0
  88. package/dist/src/artifacts/operational-state.js +239 -0
  89. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  90. package/dist/src/artifacts/query-engine.js +1955 -0
  91. package/dist/src/artifacts/source-graph.js +529 -0
  92. package/dist/src/artifacts/stats.js +169 -0
  93. package/dist/src/artifacts/types.js +606 -0
  94. package/dist/src/artifacts/views/cli.js +293 -0
  95. package/dist/src/artifacts/views/definition.js +170 -0
  96. package/dist/src/artifacts/views/store.js +149 -0
  97. package/dist/src/artifacts/views/types.js +8 -0
  98. package/dist/src/artifacts/watcher.js +255 -0
  99. package/dist/src/catalog/builtin-models.json +636 -0
  100. package/dist/src/catalog/cli.js +228 -0
  101. package/dist/src/catalog/cli.mjs +289 -0
  102. package/dist/src/catalog/index.js +15 -0
  103. package/dist/src/catalog/loader.js +217 -0
  104. package/dist/src/catalog/loader.mjs +251 -0
  105. package/dist/src/catalog/sources.json +41 -0
  106. package/dist/src/catalog/types.js +8 -0
  107. package/dist/src/channel/manager.mjs +504 -0
  108. package/dist/src/cli/agent-spawn.js +178 -0
  109. package/dist/src/cli/cli-extension-loader.js +245 -0
  110. package/dist/src/cli/command-log.js +275 -0
  111. package/dist/src/cli/config-loader.js +232 -0
  112. package/dist/src/cli/env.js +82 -0
  113. package/dist/src/cli/errors.js +150 -0
  114. package/dist/src/cli/find-package-root.js +40 -0
  115. package/dist/src/cli/git-hooks.js +250 -0
  116. package/dist/src/cli/handlers/agentcard.js +206 -0
  117. package/dist/src/cli/handlers/artifacts.js +76 -0
  118. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  119. package/dist/src/cli/handlers/cockpit.js +137 -0
  120. package/dist/src/cli/handlers/command-log.js +37 -0
  121. package/dist/src/cli/handlers/daemon.js +59 -0
  122. package/dist/src/cli/handlers/diagnose.js +300 -0
  123. package/dist/src/cli/handlers/execution-mode.js +105 -0
  124. package/dist/src/cli/handlers/feedback.js +341 -0
  125. package/dist/src/cli/handlers/help.js +147 -0
  126. package/dist/src/cli/handlers/index.js +302 -0
  127. package/dist/src/cli/handlers/init.js +179 -0
  128. package/dist/src/cli/handlers/install.js +129 -0
  129. package/dist/src/cli/handlers/issues.js +46 -0
  130. package/dist/src/cli/handlers/lint.js +42 -0
  131. package/dist/src/cli/handlers/local-executor.js +315 -0
  132. package/dist/src/cli/handlers/marketplace.js +168 -0
  133. package/dist/src/cli/handlers/mc.js +1010 -0
  134. package/dist/src/cli/handlers/models.js +352 -0
  135. package/dist/src/cli/handlers/packages.js +155 -0
  136. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  137. package/dist/src/cli/handlers/ralph.js +575 -0
  138. package/dist/src/cli/handlers/refresh.js +432 -0
  139. package/dist/src/cli/handlers/regenerate.js +336 -0
  140. package/dist/src/cli/handlers/repo-access.js +109 -0
  141. package/dist/src/cli/handlers/run.js +165 -0
  142. package/dist/src/cli/handlers/runtime-info.js +301 -0
  143. package/dist/src/cli/handlers/sandbox.js +197 -0
  144. package/dist/src/cli/handlers/scaffolding.js +149 -0
  145. package/dist/src/cli/handlers/script-runner.js +121 -0
  146. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  147. package/dist/src/cli/handlers/serve.js +1835 -0
  148. package/dist/src/cli/handlers/session.js +348 -0
  149. package/dist/src/cli/handlers/setup.js +440 -0
  150. package/dist/src/cli/handlers/skill-lint.js +367 -0
  151. package/dist/src/cli/handlers/skill-usage.js +74 -0
  152. package/dist/src/cli/handlers/steward.js +567 -0
  153. package/dist/src/cli/handlers/subcommands.js +1702 -0
  154. package/dist/src/cli/handlers/team.js +337 -0
  155. package/dist/src/cli/handlers/types.js +11 -0
  156. package/dist/src/cli/handlers/use.js +2772 -0
  157. package/dist/src/cli/handlers/utilities.js +703 -0
  158. package/dist/src/cli/handlers/version.js +134 -0
  159. package/dist/src/cli/handlers/workspace-context.js +93 -0
  160. package/dist/src/cli/handlers/workspace.js +126 -0
  161. package/dist/src/cli/help-generator.js +178 -0
  162. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  163. package/dist/src/cli/hooks/executor.js +96 -0
  164. package/dist/src/cli/hooks/index.js +15 -0
  165. package/dist/src/cli/hooks/registry.js +143 -0
  166. package/dist/src/cli/hooks/types.js +13 -0
  167. package/dist/src/cli/log.js +492 -0
  168. package/dist/src/cli/project-isolation/detect.js +70 -0
  169. package/dist/src/cli/project-isolation/index.js +7 -0
  170. package/dist/src/cli/project-isolation/signals.js +17 -0
  171. package/dist/src/cli/project-isolation/warning.js +102 -0
  172. package/dist/src/cli/prompt-utils.js +155 -0
  173. package/dist/src/cli/provider-deployment-plan.js +126 -0
  174. package/dist/src/cli/provider-resolution.js +119 -0
  175. package/dist/src/cli/router.js +305 -0
  176. package/dist/src/cli/scope-resolver.js +392 -0
  177. package/dist/src/cli/skill-usage.js +616 -0
  178. package/dist/src/cli/ui.js +224 -0
  179. package/dist/src/cli/watch-service.js +203 -0
  180. package/dist/src/cli/workflow-orchestrator.js +478 -0
  181. package/dist/src/cli/workspace-signals.js +321 -0
  182. package/dist/src/community/footer.js +14 -0
  183. package/dist/src/community/links.js +123 -0
  184. package/dist/src/community/milestones.js +46 -0
  185. package/dist/src/community/nudge-policy.js +93 -0
  186. package/dist/src/config/aiwg-config.js +883 -0
  187. package/dist/src/config/cli.js +703 -0
  188. package/dist/src/config/gitignore.js +156 -0
  189. package/dist/src/config/project-artifacts.js +76 -0
  190. package/dist/src/config/user-config.js +428 -0
  191. package/dist/src/config/user-registry.js +127 -0
  192. package/dist/src/config/workspace.js +276 -0
  193. package/dist/src/contributors/detect.js +39 -0
  194. package/dist/src/contributors/discover.js +172 -0
  195. package/dist/src/contributors/heuristic.js +186 -0
  196. package/dist/src/contributors/index.js +11 -0
  197. package/dist/src/contributors/types.js +13 -0
  198. package/dist/src/contributors/validation.js +116 -0
  199. package/dist/src/data/community.schema.json +43 -0
  200. package/dist/src/data/community.yaml +16 -0
  201. package/dist/src/extensions/capability-index.js +270 -0
  202. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  203. package/dist/src/extensions/commands/definitions.js +3485 -0
  204. package/dist/src/extensions/deployment-registration.js +463 -0
  205. package/dist/src/extensions/index.js +22 -0
  206. package/dist/src/extensions/loader.js +132 -0
  207. package/dist/src/extensions/managed-marker.js +100 -0
  208. package/dist/src/extensions/manifest.js +196 -0
  209. package/dist/src/extensions/project-local-activity.js +114 -0
  210. package/dist/src/extensions/project-local-discovery.js +261 -0
  211. package/dist/src/extensions/project-local-doctor.js +281 -0
  212. package/dist/src/extensions/project-local-gitignore.js +176 -0
  213. package/dist/src/extensions/project-local-paths.js +121 -0
  214. package/dist/src/extensions/project-local-promote.js +218 -0
  215. package/dist/src/extensions/project-local-remove.js +373 -0
  216. package/dist/src/extensions/project-local-scaffold.js +252 -0
  217. package/dist/src/extensions/project-quickref.js +291 -0
  218. package/dist/src/extensions/registry.js +368 -0
  219. package/dist/src/extensions/shadow-resolver.js +271 -0
  220. package/dist/src/extensions/types.js +86 -0
  221. package/dist/src/extensions/upstream-registry.js +195 -0
  222. package/dist/src/extensions/validation.js +631 -0
  223. package/dist/src/features/catalog.js +88 -0
  224. package/dist/src/features/cli.js +197 -0
  225. package/dist/src/features/installer.js +57 -0
  226. package/dist/src/features/paths.js +14 -0
  227. package/dist/src/features/runtime.js +21 -0
  228. package/dist/src/features/status.js +134 -0
  229. package/dist/src/hooks/laziness-detection.js +532 -0
  230. package/dist/src/intake/git-history-analyzer.js +486 -0
  231. package/dist/src/intake/index.js +9 -0
  232. package/dist/src/issues/cli.js +327 -0
  233. package/dist/src/issues/index.js +5 -0
  234. package/dist/src/issues/live.js +154 -0
  235. package/dist/src/issues/local.js +666 -0
  236. package/dist/src/issues/sync.js +143 -0
  237. package/dist/src/issues/types.js +2 -0
  238. package/dist/src/issues/workflows.js +164 -0
  239. package/dist/src/kb/cli.js +173 -0
  240. package/dist/src/lint/cli.js +171 -0
  241. package/dist/src/lint/loader.js +225 -0
  242. package/dist/src/lint/reporters.js +141 -0
  243. package/dist/src/lint/runner.js +364 -0
  244. package/dist/src/lint/types.js +10 -0
  245. package/dist/src/marketplace/cache.js +110 -0
  246. package/dist/src/marketplace/identifier.js +63 -0
  247. package/dist/src/marketplace/registry.js +36 -0
  248. package/dist/src/marketplace/sources/clawhub.js +53 -0
  249. package/dist/src/marketplace/sources/git.js +45 -0
  250. package/dist/src/marketplace/types.js +9 -0
  251. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  252. package/dist/src/mcp/cli.mjs +1197 -0
  253. package/dist/src/mcp/elicitation.mjs +149 -0
  254. package/dist/src/mcp/helpers.mjs +287 -0
  255. package/dist/src/mcp/index.mjs +11 -0
  256. package/dist/src/mcp/profiles.js +263 -0
  257. package/dist/src/mcp/profiles.mjs +360 -0
  258. package/dist/src/mcp/registry.js +376 -0
  259. package/dist/src/mcp/registry.mjs +387 -0
  260. package/dist/src/mcp/server.mjs +633 -0
  261. package/dist/src/mcp/test-simple.mjs +271 -0
  262. package/dist/src/mcp/tools/command-run.mjs +101 -0
  263. package/dist/src/mcp/tools/discovery.mjs +291 -0
  264. package/dist/src/mcp/tools/interaction.mjs +87 -0
  265. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  266. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  267. package/dist/src/memory/cli.js +166 -0
  268. package/dist/src/memory/project-registry.js +282 -0
  269. package/dist/src/metrics/artifact-metrics.js +184 -0
  270. package/dist/src/metrics/context-budget.js +174 -0
  271. package/dist/src/metrics/token-counter.js +133 -0
  272. package/dist/src/models/config-loader.js +228 -0
  273. package/dist/src/models/index.js +22 -0
  274. package/dist/src/models/model-capabilities.v1.json +120 -0
  275. package/dist/src/models/model-catalog.v1.json +96 -0
  276. package/dist/src/models/model-discovery.js +521 -0
  277. package/dist/src/models/provider-models.js +73 -0
  278. package/dist/src/models/provider-policy.js +273 -0
  279. package/dist/src/models/resolver.js +245 -0
  280. package/dist/src/models/router.js +70 -0
  281. package/dist/src/models/types.js +8 -0
  282. package/dist/src/models/wrapper-deployment.js +178 -0
  283. package/dist/src/models/wrapper-route.js +54 -0
  284. package/dist/src/ops/cli.js +268 -0
  285. package/dist/src/ops/registry.js +623 -0
  286. package/dist/src/packages/adapters/clawhub.js +113 -0
  287. package/dist/src/packages/adapters/git.js +153 -0
  288. package/dist/src/packages/adapters/gitea.js +93 -0
  289. package/dist/src/packages/adapters/github.js +69 -0
  290. package/dist/src/packages/adapters/local-cache.js +89 -0
  291. package/dist/src/packages/package-registry.js +143 -0
  292. package/dist/src/packages/registry.js +238 -0
  293. package/dist/src/packages/types.js +11 -0
  294. package/dist/src/plugin/cross-framework-ops.js +475 -0
  295. package/dist/src/plugin/framework-config-loader.js +235 -0
  296. package/dist/src/plugin/framework-detector.js +186 -0
  297. package/dist/src/plugin/framework-isolator.js +341 -0
  298. package/dist/src/plugin/framework-migration.js +371 -0
  299. package/dist/src/plugin/metadata-validator.js +906 -0
  300. package/dist/src/plugin/plugin-installer.js +436 -0
  301. package/dist/src/plugin/plugin-status.js +369 -0
  302. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  303. package/dist/src/plugin/registry-validator.js +344 -0
  304. package/dist/src/plugin/skill-command-translator.js +415 -0
  305. package/dist/src/plugin/workspace-creator.js +189 -0
  306. package/dist/src/plugin/workspace-migrator.js +821 -0
  307. package/dist/src/policy/authorization.js +390 -0
  308. package/dist/src/policy/repo-access.js +215 -0
  309. package/dist/src/provenance/cli.js +16 -0
  310. package/dist/src/providers/capability-matrix.js +300 -0
  311. package/dist/src/providers/capability-matrix.yaml +514 -0
  312. package/dist/src/providers/provider-definitions.js +977 -0
  313. package/dist/src/providers/provider-definitions.mjs +159 -0
  314. package/dist/src/providers/provider-inventory.js +169 -0
  315. package/dist/src/quality/feedback-ab.js +174 -0
  316. package/dist/src/quality/feedback-collector.js +176 -0
  317. package/dist/src/quality/feedback-tracker.js +123 -0
  318. package/dist/src/quality/patterns/adr.json +24 -0
  319. package/dist/src/quality/patterns/sad.json +24 -0
  320. package/dist/src/quality/patterns/test-plan.json +24 -0
  321. package/dist/src/quality/patterns/use-case.json +24 -0
  322. package/dist/src/quality/scoring.js +157 -0
  323. package/dist/src/reflections/cli.js +15 -0
  324. package/dist/src/release/plan.js +139 -0
  325. package/dist/src/research/cache/manager.js +227 -0
  326. package/dist/src/research/clients/arxiv.js +156 -0
  327. package/dist/src/research/clients/base.js +197 -0
  328. package/dist/src/research/clients/crossref.js +112 -0
  329. package/dist/src/research/clients/semantic-scholar.js +126 -0
  330. package/dist/src/research/clients/unpaywall.js +87 -0
  331. package/dist/src/research/index.js +14 -0
  332. package/dist/src/research/query-cli.js +336 -0
  333. package/dist/src/research/services/acquisition.js +313 -0
  334. package/dist/src/research/services/archival.js +225 -0
  335. package/dist/src/research/services/citation.js +279 -0
  336. package/dist/src/research/services/discovery.js +243 -0
  337. package/dist/src/research/services/documentation.js +269 -0
  338. package/dist/src/research/services/index.js +14 -0
  339. package/dist/src/research/services/provenance.js +279 -0
  340. package/dist/src/research/services/quality.js +370 -0
  341. package/dist/src/research/services/types.js +7 -0
  342. package/dist/src/research/storage-cli.js +20 -0
  343. package/dist/src/research/types.js +47 -0
  344. package/dist/src/resources/index.d.ts +2 -0
  345. package/dist/src/resources/index.js +2 -0
  346. package/dist/src/resources/web-release.d.ts +89 -0
  347. package/dist/src/resources/web-release.js +886 -0
  348. package/dist/src/rlm/cache/cli.js +162 -0
  349. package/dist/src/rlm/cache/hash.js +35 -0
  350. package/dist/src/rlm/cache/store.js +170 -0
  351. package/dist/src/rlm/cache/types.js +8 -0
  352. package/dist/src/rlm/cli.js +650 -0
  353. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  354. package/dist/src/serve/agent-router.js +205 -0
  355. package/dist/src/serve/dispatch-router.js +171 -0
  356. package/dist/src/serve/executor-registry.js +715 -0
  357. package/dist/src/serve/mission-conductor.js +177 -0
  358. package/dist/src/serve/orchestrator-adapter.js +113 -0
  359. package/dist/src/serve/orchestrator-override.js +94 -0
  360. package/dist/src/serve/orchestrator-pty.js +133 -0
  361. package/dist/src/serve/pty-bridge.js +799 -0
  362. package/dist/src/serve/sandbox-registry.js +832 -0
  363. package/dist/src/serve/screen-reader.js +228 -0
  364. package/dist/src/serve/stack-adapters.js +68 -0
  365. package/dist/src/serve/telemetry.js +143 -0
  366. package/dist/src/skills/adapters/clawhub.js +250 -0
  367. package/dist/src/skills/adapters/local.js +335 -0
  368. package/dist/src/skills/adapters/openclaw.js +316 -0
  369. package/dist/src/skills/cli.js +334 -0
  370. package/dist/src/skills/registry.js +117 -0
  371. package/dist/src/skills/run.js +259 -0
  372. package/dist/src/skills/runtime.js +94 -0
  373. package/dist/src/skills/types.js +10 -0
  374. package/dist/src/smiths/agentsmith/demo.js +116 -0
  375. package/dist/src/smiths/agentsmith/examples.js +300 -0
  376. package/dist/src/smiths/agentsmith/generator.js +503 -0
  377. package/dist/src/smiths/agentsmith/index.js +11 -0
  378. package/dist/src/smiths/agentsmith/types.js +8 -0
  379. package/dist/src/smiths/commandsmith/example.js +220 -0
  380. package/dist/src/smiths/commandsmith/generator.js +288 -0
  381. package/dist/src/smiths/commandsmith/index.js +41 -0
  382. package/dist/src/smiths/commandsmith/templates.js +296 -0
  383. package/dist/src/smiths/commandsmith/types.js +7 -0
  384. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  385. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  386. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  387. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  388. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  389. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  390. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  391. package/dist/src/smiths/context-pipeline/index.js +30 -0
  392. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  393. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  394. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  395. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  396. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  397. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  398. package/dist/src/smiths/context-pipeline/types.js +23 -0
  399. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  400. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  401. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  402. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  403. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  404. package/dist/src/smiths/hook-bridge/index.js +79 -0
  405. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  406. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  407. package/dist/src/smiths/hook-bridge/types.js +31 -0
  408. package/dist/src/smiths/index.js +39 -0
  409. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  410. package/dist/src/smiths/mcpsmith/example.js +119 -0
  411. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  412. package/dist/src/smiths/mcpsmith/index.js +17 -0
  413. package/dist/src/smiths/mcpsmith/types.js +10 -0
  414. package/dist/src/smiths/platform-paths.js +101 -0
  415. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  416. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  417. package/dist/src/smiths/skillsmith/demo.js +83 -0
  418. package/dist/src/smiths/skillsmith/examples.js +161 -0
  419. package/dist/src/smiths/skillsmith/generator.js +316 -0
  420. package/dist/src/smiths/skillsmith/index.js +12 -0
  421. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  422. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  423. package/dist/src/smiths/skillsmith/types.js +9 -0
  424. package/dist/src/smiths/toolsmith/index.js +10 -0
  425. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  426. package/dist/src/smiths/toolsmith/types.js +8 -0
  427. package/dist/src/storage/backends/fortemi.js +227 -0
  428. package/dist/src/storage/backends/fs.js +134 -0
  429. package/dist/src/storage/backends/logseq.js +309 -0
  430. package/dist/src/storage/backends/obsidian.js +233 -0
  431. package/dist/src/storage/cli.js +468 -0
  432. package/dist/src/storage/config.js +272 -0
  433. package/dist/src/storage/index.js +108 -0
  434. package/dist/src/storage/subsystem-cli.js +201 -0
  435. package/dist/src/storage/types.js +33 -0
  436. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  437. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  438. package/dist/src/testing/corpus/index.js +10 -0
  439. package/dist/src/testing/fixtures/index.js +9 -0
  440. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  441. package/dist/src/testing/generators/index.js +11 -0
  442. package/dist/src/testing/generators/test-case-generator.js +393 -0
  443. package/dist/src/testing/generators/test-code-generator.js +384 -0
  444. package/dist/src/testing/generators/use-case-parser.js +325 -0
  445. package/dist/src/testing/index.js +11 -0
  446. package/dist/src/tracker/capability-protocol.js +118 -0
  447. package/dist/src/update/checker.mjs +396 -0
  448. package/dist/src/update/notifier.mjs +235 -0
  449. package/dist/src/writing/content-diversifier.js +804 -0
  450. package/dist/src/writing/example-generator.js +959 -0
  451. package/dist/src/writing/example-templates.js +99 -0
  452. package/dist/src/writing/pattern-library.js +486 -0
  453. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  454. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  455. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  456. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  457. package/dist/src/writing/patterns/transition-words.json +1285 -0
  458. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  459. package/dist/src/writing/prompt-optimizer.js +660 -0
  460. package/dist/src/writing/prompt-templates.js +583 -0
  461. package/dist/src/writing/scoring-config-loader.js +168 -0
  462. package/dist/src/writing/validation-engine.js +595 -0
  463. package/dist/src/writing/validation-rules.js +380 -0
  464. package/dist/src/writing/voice-analyzer.js +439 -0
  465. package/dist/src/writing/voice-calibration.js +661 -0
  466. package/dist/src/writing/voice-profiles.json +588 -0
  467. package/package.json +65 -9
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Fortemi Storage Adapter
3
+ *
4
+ * Routes storage operations through Fortemi's MCP tool surface. Fortemi
5
+ * is the first-party AIWG semantic-memory project — Rust + PostgreSQL +
6
+ * pgvector + SKOS + W3C PROV — referenced as "Forte" in #934 and
7
+ * confirmed as Fortemi in #961.
8
+ *
9
+ * Tool surface (per `.aiwg/planning/training-framework/phase-4-fortemi-review.md`):
10
+ * capture_knowledge - create note (we use this for first writes)
11
+ * update_note - revise existing note (we use this for re-writes)
12
+ * get_note - retrieve full note (read)
13
+ * list_notes - filter/paginate (list)
14
+ * search - text/semantic/spatial/temporal search (query)
15
+ * manage_collection - organize notes in folders (we use folder=subsystem
16
+ * scope to mirror the StorageAdapter contract)
17
+ *
18
+ * Path semantics:
19
+ * note_id = `${subsystem}:${path}` — the adapter passes the
20
+ * subsystem-relative path; the registry-supplied `subsystem` is
21
+ * prepended to keep different subsystems' notes from colliding.
22
+ *
23
+ * Caveats:
24
+ * - This adapter ships with the parameter shapes documented in the
25
+ * planning doc, but those shapes have NOT yet been validated against
26
+ * a live Fortemi instance. Treat this as alpha. The
27
+ * `McpClientLike.callTool(name, args)` injection point lets tests
28
+ * stub freely; real-world parameter mismatches surface as MCP
29
+ * errors that bubble up to the consumer.
30
+ * - Delete is implemented via `update_note` with `archived: true`
31
+ * because Fortemi's MCP surface does not document a direct delete
32
+ * tool (immutability + versioning is core to the design).
33
+ *
34
+ * @design @.aiwg/architecture/storage-design.md (§5.6)
35
+ * @issue #934
36
+ * @issue #961
37
+ * @issue #972
38
+ */
39
+ const DEFAULT_MCP_SERVER = 'fortemi';
40
+ export class FortemiAdapter {
41
+ subsystem;
42
+ mcpServer;
43
+ scheme;
44
+ clientFactory;
45
+ client = null;
46
+ constructor(opts) {
47
+ this.subsystem = opts.subsystem;
48
+ this.mcpServer = opts.config.mcpServer ?? DEFAULT_MCP_SERVER;
49
+ this.scheme = opts.config.scheme;
50
+ this.clientFactory = opts.clientFactory ?? createDefaultMcpClient;
51
+ }
52
+ async init() {
53
+ if (this.client)
54
+ return;
55
+ this.client = await this.clientFactory(this.mcpServer);
56
+ }
57
+ async close() {
58
+ if (this.client?.close) {
59
+ await this.client.close();
60
+ }
61
+ this.client = null;
62
+ }
63
+ async getClient() {
64
+ if (!this.client)
65
+ await this.init();
66
+ if (!this.client) {
67
+ throw new Error(`storage(fortemi): MCP client unavailable for server "${this.mcpServer}"`);
68
+ }
69
+ return this.client;
70
+ }
71
+ noteId(path) {
72
+ if (typeof path !== 'string' || path.length === 0) {
73
+ throw new Error('storage(fortemi): path must be a non-empty string');
74
+ }
75
+ if (path.includes('\0')) {
76
+ throw new Error(`storage(fortemi): null bytes not allowed in path "${path}"`);
77
+ }
78
+ return `${this.subsystem}:${path}`;
79
+ }
80
+ async read(path) {
81
+ const id = this.noteId(path);
82
+ const client = await this.getClient();
83
+ const result = (await client.callTool('get_note', { note_id: id }));
84
+ if (!result || result.not_found)
85
+ return null;
86
+ const note = result.note;
87
+ if (!note)
88
+ return null;
89
+ return note.revised_content ?? note.content ?? null;
90
+ }
91
+ async write(path, content, meta) {
92
+ const id = this.noteId(path);
93
+ const client = await this.getClient();
94
+ // Try update first; if not found, capture as new. Two calls in the
95
+ // worst case but idempotent — Fortemi's update_note increments the
96
+ // version rather than overwriting, which matches the Phase-4 design.
97
+ const existing = (await client.callTool('get_note', { note_id: id }));
98
+ if (existing && !existing.not_found && existing.note) {
99
+ await client.callTool('update_note', {
100
+ note_id: id,
101
+ content,
102
+ metadata: this.buildMetadata(meta),
103
+ });
104
+ }
105
+ else {
106
+ await client.callTool('capture_knowledge', {
107
+ note_id: id,
108
+ content,
109
+ scheme: this.scheme,
110
+ metadata: this.buildMetadata(meta),
111
+ });
112
+ }
113
+ }
114
+ async list(prefix) {
115
+ if (typeof prefix !== 'string') {
116
+ throw new Error('storage(fortemi): list prefix must be a string');
117
+ }
118
+ const client = await this.getClient();
119
+ const subsystemPrefix = `${this.subsystem}:`;
120
+ const fullPrefix = prefix.length === 0 ? subsystemPrefix : `${subsystemPrefix}${prefix}`;
121
+ const result = (await client.callTool('list_notes', {
122
+ id_prefix: fullPrefix,
123
+ scheme: this.scheme,
124
+ }));
125
+ const notes = result?.notes ?? [];
126
+ return notes
127
+ .filter((n) => typeof n.note_id === 'string' && n.note_id.startsWith(subsystemPrefix))
128
+ .map((n) => {
129
+ const entry = {
130
+ path: n.note_id.slice(subsystemPrefix.length),
131
+ externalId: n.note_id,
132
+ };
133
+ if (typeof n.size === 'number')
134
+ entry.size = n.size;
135
+ if (typeof n.updated_at === 'string') {
136
+ const d = new Date(n.updated_at);
137
+ if (!Number.isNaN(d.getTime()))
138
+ entry.modifiedAt = d;
139
+ }
140
+ return entry;
141
+ });
142
+ }
143
+ async delete(path) {
144
+ // Fortemi's MCP surface does not document a destructive delete —
145
+ // immutability + versioning is core to the design. We mark the note
146
+ // archived via update_note instead. This matches the storage-design
147
+ // contract (delete is "no-op when missing"; here we just suppress
148
+ // the note from list/read by archiving it).
149
+ const id = this.noteId(path);
150
+ const client = await this.getClient();
151
+ const existing = (await client.callTool('get_note', { note_id: id }));
152
+ if (!existing || existing.not_found || !existing.note)
153
+ return;
154
+ await client.callTool('update_note', {
155
+ note_id: id,
156
+ archived: true,
157
+ });
158
+ }
159
+ async query(q) {
160
+ const client = await this.getClient();
161
+ const subsystemPrefix = `${this.subsystem}:`;
162
+ const result = (await client.callTool('search', {
163
+ query: q,
164
+ id_prefix: subsystemPrefix,
165
+ scheme: this.scheme,
166
+ }));
167
+ const results = result?.results ?? [];
168
+ return results
169
+ .filter((r) => typeof r.note_id === 'string' && r.note_id.startsWith(subsystemPrefix))
170
+ .map((r) => ({
171
+ path: r.note_id.slice(subsystemPrefix.length),
172
+ externalId: r.note_id,
173
+ }));
174
+ }
175
+ buildMetadata(meta) {
176
+ const out = {
177
+ subsystem: this.subsystem,
178
+ source: 'aiwg-storage-adapter',
179
+ };
180
+ if (meta?.contentType)
181
+ out['content_type'] = meta.contentType;
182
+ if (meta?.frontmatter)
183
+ out['frontmatter'] = meta.frontmatter;
184
+ if (this.scheme)
185
+ out['scheme'] = this.scheme;
186
+ return out;
187
+ }
188
+ }
189
+ /**
190
+ * Default MCP client factory. Resolves the server config from AIWG's
191
+ * McpServerRegistry, spawns the stdio transport, and returns a
192
+ * connected client.
193
+ *
194
+ * Implemented as a lazy import so tests that inject a stub never load
195
+ * the SDK or touch the registry.
196
+ */
197
+ export const createDefaultMcpClient = async (serverName) => {
198
+ const { McpServerRegistry } = await import('../../mcp/registry.js');
199
+ const registry = new McpServerRegistry();
200
+ const server = await registry.get(serverName);
201
+ if (!server) {
202
+ throw new Error(`storage(fortemi): MCP server "${serverName}" is not registered. ` +
203
+ `Add it via "aiwg mcp add ${serverName} --command <cmd>" before using the fortemi backend.`);
204
+ }
205
+ if (server.type !== 'stdio') {
206
+ throw new Error(`storage(fortemi): only stdio MCP servers are supported (got "${server.type}" for "${serverName}")`);
207
+ }
208
+ // Lazy import the SDK so tests that inject a stub don't pay the cost
209
+ const { Client } = await import('@modelcontextprotocol/sdk/client/index.js');
210
+ const { StdioClientTransport } = await import('@modelcontextprotocol/sdk/client/stdio.js');
211
+ const transport = new StdioClientTransport({
212
+ command: server.command ?? '',
213
+ args: server.args ?? [],
214
+ env: server.env,
215
+ });
216
+ const client = new Client({ name: 'aiwg-storage-fortemi-adapter', version: '1.0.0' }, { capabilities: {} });
217
+ await client.connect(transport);
218
+ return {
219
+ async callTool(name, args) {
220
+ return client.callTool({ name, arguments: args });
221
+ },
222
+ async close() {
223
+ await client.close();
224
+ },
225
+ };
226
+ };
227
+ //# sourceMappingURL=fortemi.js.map
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Filesystem Storage Adapter
3
+ *
4
+ * The default backend. Wraps `fs.promises` and honors per-subsystem root
5
+ * overrides from `storage.config`. Output is byte-identical to the
6
+ * pre-abstraction direct-fs calls so consumer migrations stay safe.
7
+ *
8
+ * @design @.aiwg/architecture/storage-design.md (§5.1)
9
+ * @issue #934
10
+ * @issue #956
11
+ */
12
+ import { existsSync } from 'fs';
13
+ import { appendFile, mkdir, readFile, readdir, rm, stat, writeFile } from 'fs/promises';
14
+ import { dirname, join, relative, resolve, sep } from 'path';
15
+ export class FilesystemAdapter {
16
+ /** Absolute path where this subsystem's content lives. */
17
+ root;
18
+ constructor(root) {
19
+ this.root = resolve(root);
20
+ }
21
+ /**
22
+ * Path traversal guard. Rejects `..`, leading `/`, leading `~`, and
23
+ * backslashes (which on POSIX would be treated as filename chars but
24
+ * are almost always a Windows-vs-POSIX bug). Also rejects empty paths.
25
+ */
26
+ resolveSafe(relPath) {
27
+ if (typeof relPath !== 'string' || relPath.length === 0) {
28
+ throw new Error('storage(fs): path must be a non-empty string');
29
+ }
30
+ if (relPath.includes('\\')) {
31
+ throw new Error(`storage(fs): backslash not allowed in path "${relPath}"`);
32
+ }
33
+ if (relPath.startsWith('/') || relPath.startsWith('~')) {
34
+ throw new Error(`storage(fs): absolute paths not allowed: "${relPath}"`);
35
+ }
36
+ const segments = relPath.split('/');
37
+ if (segments.some((s) => s === '..')) {
38
+ throw new Error(`storage(fs): ".." traversal not allowed in "${relPath}"`);
39
+ }
40
+ const abs = resolve(this.root, relPath);
41
+ // Final guard: ensure the resolved path is still under root, even if
42
+ // the segment check missed something unusual (e.g. empty segments).
43
+ if (abs !== this.root && !abs.startsWith(this.root + sep)) {
44
+ throw new Error(`storage(fs): resolved path escapes subsystem root: "${relPath}"`);
45
+ }
46
+ return abs;
47
+ }
48
+ async read(path) {
49
+ const abs = this.resolveSafe(path);
50
+ if (!existsSync(abs))
51
+ return null;
52
+ return readFile(abs, 'utf-8');
53
+ }
54
+ async write(path, content, _meta) {
55
+ const abs = this.resolveSafe(path);
56
+ await mkdir(dirname(abs), { recursive: true });
57
+ await writeFile(abs, content, 'utf-8');
58
+ }
59
+ /**
60
+ * Atomic append. Uses fs.appendFile, which opens with O_APPEND so the
61
+ * kernel guarantees atomicity for writes ≤ PIPE_BUF (4096 bytes on
62
+ * Linux). Concurrent appenders interleave at line granularity rather
63
+ * than racing read-then-write. See #976.
64
+ */
65
+ async append(path, content) {
66
+ const abs = this.resolveSafe(path);
67
+ await mkdir(dirname(abs), { recursive: true });
68
+ await appendFile(abs, content, 'utf-8');
69
+ }
70
+ async list(prefix) {
71
+ // Empty prefix = list everything under root. A non-empty prefix
72
+ // restricts to entries whose subsystem-relative path starts with it
73
+ // (after path-normalizing the prefix itself).
74
+ if (typeof prefix !== 'string') {
75
+ throw new Error('storage(fs): list prefix must be a string');
76
+ }
77
+ if (prefix.length > 0) {
78
+ // resolveSafe also validates the prefix shape
79
+ this.resolveSafe(prefix);
80
+ }
81
+ if (!existsSync(this.root))
82
+ return [];
83
+ const out = [];
84
+ await walkInto(this.root, this.root, prefix, out);
85
+ return out;
86
+ }
87
+ async delete(path) {
88
+ const abs = this.resolveSafe(path);
89
+ if (!existsSync(abs))
90
+ return;
91
+ await rm(abs, { force: true });
92
+ }
93
+ }
94
+ async function walkInto(root, dir, prefix, out) {
95
+ let entries;
96
+ try {
97
+ entries = await readdir(dir, { withFileTypes: true });
98
+ }
99
+ catch {
100
+ return;
101
+ }
102
+ for (const e of entries) {
103
+ const full = join(dir, e.name);
104
+ const rel = relative(root, full).split(sep).join('/');
105
+ if (e.isDirectory()) {
106
+ // Descend if the dir could contain matches
107
+ if (prefix === '' || rel.startsWith(prefix) || prefix.startsWith(rel + '/')) {
108
+ await walkInto(root, full, prefix, out);
109
+ }
110
+ continue;
111
+ }
112
+ if (!e.isFile())
113
+ continue;
114
+ if (prefix !== '' && !rel.startsWith(prefix))
115
+ continue;
116
+ let size;
117
+ let modifiedAt;
118
+ try {
119
+ const s = await stat(full);
120
+ size = s.size;
121
+ modifiedAt = s.mtime;
122
+ }
123
+ catch {
124
+ // ignore stat failures
125
+ }
126
+ const entry = { path: rel };
127
+ if (size !== undefined)
128
+ entry.size = size;
129
+ if (modifiedAt !== undefined)
130
+ entry.modifiedAt = modifiedAt;
131
+ out.push(entry);
132
+ }
133
+ }
134
+ //# sourceMappingURL=fs.js.map
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Logseq Storage Adapter
3
+ *
4
+ * Writes and reads markdown files in a Logseq graph on disk. Like the
5
+ * Obsidian adapter, this is filesystem-shaped — Logseq graphs are
6
+ * directories of `.md` (or `.org`) files plus a `logseq/` config dir
7
+ * we never touch.
8
+ *
9
+ * About the Logseq HTTP API: as of April 2025 the DB-backed Logseq
10
+ * rewrite is still in development; file-backed graphs remain primary.
11
+ * Logseq exposes an HTTP API at `http://127.0.0.1:12315/api` (with a
12
+ * bearer token issued from Settings → Features → Developer mode), but
13
+ * verifying its exact command surface requires hands-on Logseq access.
14
+ *
15
+ * What this adapter does:
16
+ * - Reads / writes / lists / deletes markdown files via fs
17
+ * - Optional HTTP API reachability probe (when `useApi: true`) —
18
+ * emits a one-time stderr warning if `LOGSEQ_API_TOKEN` is unset or
19
+ * the API is unreachable
20
+ * - Refuses paths into the graph's `logseq/` config directory
21
+ * - Transforms `WriteMeta.frontmatter` from YAML into Logseq's
22
+ * page-level `property:: value` syntax
23
+ * - Never writes block IDs (`id::`) — Logseq auto-assigns them
24
+ *
25
+ * Path layout (mirrors Logseq's on-disk conventions):
26
+ * pages/<title>.md regular pages
27
+ * journals/YYYY_MM_DD.md journal entries
28
+ * logseq/* REFUSED (Logseq config)
29
+ *
30
+ * @design @.aiwg/architecture/storage-design.md (§5.3)
31
+ * @issue #934
32
+ * @issue #958
33
+ */
34
+ import { existsSync } from 'fs';
35
+ import { mkdir, readFile, readdir, rm, stat, writeFile } from 'fs/promises';
36
+ import { dirname, join, relative, resolve, sep } from 'path';
37
+ const LOGSEQ_CONFIG_DIR = 'logseq';
38
+ const DEFAULT_API_URL = 'http://127.0.0.1:12315/api';
39
+ export class LogseqAdapter {
40
+ /** Absolute path to the Logseq graph root. */
41
+ graph;
42
+ apiUrl;
43
+ useApi;
44
+ apiWarned = false;
45
+ constructor(config) {
46
+ this.graph = resolve(expandHome(config.graph));
47
+ this.apiUrl = config.apiUrl ?? DEFAULT_API_URL;
48
+ this.useApi = config.useApi ?? true;
49
+ }
50
+ async init() {
51
+ if (!existsSync(this.graph)) {
52
+ throw new Error(`storage(logseq): graph does not exist: ${this.graph}`);
53
+ }
54
+ if (this.useApi)
55
+ await this.probeApi();
56
+ }
57
+ /**
58
+ * One-shot API reachability probe. Warns once on missing token or
59
+ * unreachable endpoint. Direct fs writes still work without it.
60
+ */
61
+ async probeApi() {
62
+ if (this.apiWarned)
63
+ return;
64
+ const token = process.env['LOGSEQ_API_TOKEN'];
65
+ if (!token) {
66
+ this.apiWarned = true;
67
+ process.stderr.write(`storage(logseq): API requested (useApi: true) but LOGSEQ_API_TOKEN is not set.\n` +
68
+ ` AIWG will continue with direct file writes against the graph.\n` +
69
+ ` Set LOGSEQ_API_TOKEN (Settings → Features → Developer mode) or set "useApi": false to suppress.\n`);
70
+ return;
71
+ }
72
+ try {
73
+ // Lightweight reachability probe — most Logseq API servers respond
74
+ // to a simple POST. We don't synthesize a specific command; just
75
+ // confirm the endpoint is reachable.
76
+ const controller = new AbortController();
77
+ const timer = setTimeout(() => controller.abort(), 2000);
78
+ try {
79
+ await fetch(this.apiUrl, {
80
+ method: 'POST',
81
+ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
82
+ body: JSON.stringify({ method: 'logseq.App.getCurrentGraph' }),
83
+ signal: controller.signal,
84
+ });
85
+ }
86
+ finally {
87
+ clearTimeout(timer);
88
+ }
89
+ }
90
+ catch {
91
+ this.apiWarned = true;
92
+ process.stderr.write(`storage(logseq): API server at ${this.apiUrl} is not reachable.\n` +
93
+ ` AIWG will continue with direct file writes against the graph.\n` +
94
+ ` Start Logseq with the API server enabled, or set "useApi": false to suppress.\n`);
95
+ }
96
+ }
97
+ /**
98
+ * Validate a subsystem-relative path. Rejects traversal, absolute
99
+ * paths, backslashes, and any path inside the graph's `logseq/` dir.
100
+ */
101
+ resolveSafe(relPath) {
102
+ if (typeof relPath !== 'string' || relPath.length === 0) {
103
+ throw new Error('storage(logseq): path must be a non-empty string');
104
+ }
105
+ if (relPath.includes('\\')) {
106
+ throw new Error(`storage(logseq): backslash not allowed in path "${relPath}"`);
107
+ }
108
+ if (relPath.startsWith('/') || relPath.startsWith('~')) {
109
+ throw new Error(`storage(logseq): absolute paths not allowed: "${relPath}"`);
110
+ }
111
+ const segments = relPath.split('/');
112
+ if (segments.some((s) => s === '..')) {
113
+ throw new Error(`storage(logseq): ".." traversal not allowed in "${relPath}"`);
114
+ }
115
+ const abs = resolve(this.graph, relPath);
116
+ if (abs !== this.graph && !abs.startsWith(this.graph + sep)) {
117
+ throw new Error(`storage(logseq): resolved path escapes graph root: "${relPath}"`);
118
+ }
119
+ const relFromGraph = relative(this.graph, abs);
120
+ if (relFromGraph === LOGSEQ_CONFIG_DIR ||
121
+ relFromGraph.startsWith(LOGSEQ_CONFIG_DIR + sep)) {
122
+ throw new Error(`storage(logseq): refusing to operate on logseq/ graph config (${relPath})`);
123
+ }
124
+ return abs;
125
+ }
126
+ async read(path) {
127
+ const abs = this.resolveSafe(path);
128
+ if (!existsSync(abs))
129
+ return null;
130
+ return readFile(abs, 'utf-8');
131
+ }
132
+ async write(path, content, meta) {
133
+ const abs = this.resolveSafe(path);
134
+ await mkdir(dirname(abs), { recursive: true });
135
+ let body = content;
136
+ // Strip YAML frontmatter from the content (if any) — Logseq doesn't
137
+ // recognize it. Move what we can to page-level properties.
138
+ const yaml = extractYamlFrontmatter(body);
139
+ if (yaml) {
140
+ body = yaml.body;
141
+ }
142
+ // Merge supplied frontmatter + extracted YAML into Logseq page-properties
143
+ const merged = { ...(yaml?.fields ?? {}), ...(meta?.frontmatter ?? {}) };
144
+ if (Object.keys(merged).length > 0) {
145
+ body = renderPageProperties(merged) + body;
146
+ }
147
+ // Defensive: refuse to write `id::` block IDs ourselves. Logseq
148
+ // auto-assigns them; if the caller smuggled one in, strip it.
149
+ body = body.replace(/^\s*id::\s*[^\n]+\n/gm, '');
150
+ await writeFile(abs, body, 'utf-8');
151
+ }
152
+ async list(prefix) {
153
+ if (typeof prefix !== 'string') {
154
+ throw new Error('storage(logseq): list prefix must be a string');
155
+ }
156
+ if (prefix.length > 0)
157
+ this.resolveSafe(prefix);
158
+ if (!existsSync(this.graph))
159
+ return [];
160
+ const out = [];
161
+ await walkInto(this.graph, this.graph, prefix, out);
162
+ return out;
163
+ }
164
+ async delete(path) {
165
+ const abs = this.resolveSafe(path);
166
+ if (!existsSync(abs))
167
+ return;
168
+ await rm(abs, { force: true });
169
+ }
170
+ }
171
+ async function walkInto(root, dir, prefix, out) {
172
+ let entries;
173
+ try {
174
+ entries = await readdir(dir, { withFileTypes: true });
175
+ }
176
+ catch {
177
+ return;
178
+ }
179
+ for (const e of entries) {
180
+ // Skip the graph config directory at the root level
181
+ if (e.name === LOGSEQ_CONFIG_DIR && dir === root)
182
+ continue;
183
+ const full = join(dir, e.name);
184
+ const rel = relative(root, full).split(sep).join('/');
185
+ if (e.isDirectory()) {
186
+ if (prefix === '' || rel.startsWith(prefix) || prefix.startsWith(rel + '/')) {
187
+ await walkInto(root, full, prefix, out);
188
+ }
189
+ continue;
190
+ }
191
+ if (!e.isFile())
192
+ continue;
193
+ if (prefix !== '' && !rel.startsWith(prefix))
194
+ continue;
195
+ let size;
196
+ let modifiedAt;
197
+ try {
198
+ const s = await stat(full);
199
+ size = s.size;
200
+ modifiedAt = s.mtime;
201
+ }
202
+ catch {
203
+ // ignore
204
+ }
205
+ const entry = { path: rel };
206
+ if (size !== undefined)
207
+ entry.size = size;
208
+ if (modifiedAt !== undefined)
209
+ entry.modifiedAt = modifiedAt;
210
+ out.push(entry);
211
+ }
212
+ }
213
+ function expandHome(p) {
214
+ if (p.startsWith('~/')) {
215
+ const { homedir } = require('os');
216
+ return join(homedir(), p.slice(2));
217
+ }
218
+ if (p === '~') {
219
+ const { homedir } = require('os');
220
+ return homedir();
221
+ }
222
+ return p;
223
+ }
224
+ /**
225
+ * If `content` starts with a `---` YAML block, parse the block and
226
+ * return the parsed fields plus the body without the YAML. Otherwise
227
+ * return null.
228
+ *
229
+ * Minimal parser — handles `key: value` and `key: [a, b, c]` lines.
230
+ * Anything more complex falls back to dropping the value as a string.
231
+ */
232
+ function extractYamlFrontmatter(content) {
233
+ const match = /^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/.exec(content);
234
+ if (!match)
235
+ return null;
236
+ const [, yamlBody, body] = match;
237
+ const fields = {};
238
+ for (const line of yamlBody.split(/\r?\n/)) {
239
+ if (line.trim().length === 0 || line.trim().startsWith('#'))
240
+ continue;
241
+ const m = /^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
242
+ if (!m)
243
+ continue;
244
+ const [, k, rawV] = m;
245
+ fields[k] = parseYamlScalar(rawV.trim());
246
+ }
247
+ return { fields, body };
248
+ }
249
+ function parseYamlScalar(raw) {
250
+ if (raw === '')
251
+ return '';
252
+ if (raw === 'true')
253
+ return true;
254
+ if (raw === 'false')
255
+ return false;
256
+ if (raw === 'null' || raw === '~')
257
+ return null;
258
+ if (/^-?\d+$/.test(raw))
259
+ return Number(raw);
260
+ if (/^-?\d+\.\d+$/.test(raw))
261
+ return Number(raw);
262
+ // Quoted string
263
+ if ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'"))) {
264
+ try {
265
+ return JSON.parse(raw.replace(/^'/, '"').replace(/'$/, '"'));
266
+ }
267
+ catch {
268
+ return raw.slice(1, -1);
269
+ }
270
+ }
271
+ // Inline array
272
+ if (raw.startsWith('[') && raw.endsWith(']')) {
273
+ return raw
274
+ .slice(1, -1)
275
+ .split(',')
276
+ .map((s) => s.trim())
277
+ .filter((s) => s.length > 0)
278
+ .map(parseYamlScalar);
279
+ }
280
+ return raw;
281
+ }
282
+ /**
283
+ * Render a flat object as Logseq page-level properties:
284
+ *
285
+ * tags:: ai, note
286
+ * created:: 2026-04-28
287
+ *
288
+ * <body follows here>
289
+ */
290
+ function renderPageProperties(fields) {
291
+ const lines = [];
292
+ for (const [k, v] of Object.entries(fields)) {
293
+ lines.push(`${k}:: ${formatLogseqValue(v)}`);
294
+ }
295
+ lines.push('');
296
+ return lines.join('\n');
297
+ }
298
+ function formatLogseqValue(v) {
299
+ if (v === null || v === undefined)
300
+ return '';
301
+ if (typeof v === 'boolean' || typeof v === 'number')
302
+ return String(v);
303
+ if (Array.isArray(v))
304
+ return v.map((x) => formatLogseqValue(x)).join(', ');
305
+ if (typeof v === 'string')
306
+ return v;
307
+ return JSON.stringify(v);
308
+ }
309
+ //# sourceMappingURL=logseq.js.map