@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.17

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 (466) hide show
  1. package/README.md +21 -1
  2. package/bin/aiwg.mjs +349 -0
  3. package/dist/src/a2a/agent-card.js +145 -0
  4. package/dist/src/a2a/client.js +411 -0
  5. package/dist/src/a2a/hitl-cli.js +171 -0
  6. package/dist/src/a2a/hitl-driver.js +370 -0
  7. package/dist/src/a2a/hitl.js +181 -0
  8. package/dist/src/a2a/http.js +193 -0
  9. package/dist/src/a2a/jcs.js +128 -0
  10. package/dist/src/a2a/jws.js +187 -0
  11. package/dist/src/a2a/types.js +24 -0
  12. package/dist/src/a2a/webhook.js +240 -0
  13. package/dist/src/activity-log/cli.js +348 -0
  14. package/dist/src/activity-log/parser.js +81 -0
  15. package/dist/src/activity-log/types.js +50 -0
  16. package/dist/src/agents/agent-deployer.js +367 -0
  17. package/dist/src/agents/agent-packager.js +271 -0
  18. package/dist/src/agents/agent-validator.js +271 -0
  19. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  20. package/dist/src/agents/grounding/types.js +12 -0
  21. package/dist/src/agents/index.js +10 -0
  22. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  23. package/dist/src/agents/types.js +7 -0
  24. package/dist/src/api/index.d.ts +10 -0
  25. package/dist/src/api/index.js +10 -0
  26. package/dist/src/artifacts/address-parser.js +73 -0
  27. package/dist/src/artifacts/audit/cli.js +183 -0
  28. package/dist/src/artifacts/audit/drift.js +122 -0
  29. package/dist/src/artifacts/audit/types.js +12 -0
  30. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  31. package/dist/src/artifacts/backends/json-backend.js +129 -0
  32. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  33. package/dist/src/artifacts/browser-export.js +622 -0
  34. package/dist/src/artifacts/capability-resolver.js +94 -0
  35. package/dist/src/artifacts/checksum-manifest.js +91 -0
  36. package/dist/src/artifacts/citation-parser.js +162 -0
  37. package/dist/src/artifacts/cli.js +1462 -0
  38. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  39. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  40. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  41. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  42. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  43. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  44. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  45. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  46. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  47. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  48. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  49. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  51. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  52. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  53. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  54. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  55. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  56. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  57. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  58. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  60. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  61. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  62. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  63. package/dist/src/artifacts/corpus-views/build.js +126 -0
  64. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  65. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  66. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  67. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  68. package/dist/src/artifacts/dep-graph.js +173 -0
  69. package/dist/src/artifacts/discover-facets.js +375 -0
  70. package/dist/src/artifacts/embedding-index.js +354 -0
  71. package/dist/src/artifacts/enrichment/cli.js +240 -0
  72. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  73. package/dist/src/artifacts/enrichment/store.js +90 -0
  74. package/dist/src/artifacts/enrichment/types.js +12 -0
  75. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  76. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  77. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  78. package/dist/src/artifacts/fulltext.js +108 -0
  79. package/dist/src/artifacts/graph-backend.js +51 -0
  80. package/dist/src/artifacts/graph-query.js +247 -0
  81. package/dist/src/artifacts/hybrid-query.js +225 -0
  82. package/dist/src/artifacts/index-builder.js +1089 -0
  83. package/dist/src/artifacts/index-reader.js +112 -0
  84. package/dist/src/artifacts/index-status.js +193 -0
  85. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  86. package/dist/src/artifacts/move.js +154 -0
  87. package/dist/src/artifacts/operational-state.js +239 -0
  88. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  89. package/dist/src/artifacts/query-engine.js +1955 -0
  90. package/dist/src/artifacts/source-graph.js +529 -0
  91. package/dist/src/artifacts/stats.js +169 -0
  92. package/dist/src/artifacts/types.js +606 -0
  93. package/dist/src/artifacts/views/cli.js +293 -0
  94. package/dist/src/artifacts/views/definition.js +170 -0
  95. package/dist/src/artifacts/views/store.js +149 -0
  96. package/dist/src/artifacts/views/types.js +8 -0
  97. package/dist/src/artifacts/watcher.js +255 -0
  98. package/dist/src/catalog/builtin-models.json +636 -0
  99. package/dist/src/catalog/cli.js +228 -0
  100. package/dist/src/catalog/cli.mjs +289 -0
  101. package/dist/src/catalog/index.js +15 -0
  102. package/dist/src/catalog/loader.js +217 -0
  103. package/dist/src/catalog/loader.mjs +251 -0
  104. package/dist/src/catalog/sources.json +41 -0
  105. package/dist/src/catalog/types.js +8 -0
  106. package/dist/src/channel/manager.mjs +504 -0
  107. package/dist/src/cli/agent-spawn.js +178 -0
  108. package/dist/src/cli/cli-extension-loader.js +245 -0
  109. package/dist/src/cli/command-log.js +275 -0
  110. package/dist/src/cli/config-loader.js +232 -0
  111. package/dist/src/cli/env.js +82 -0
  112. package/dist/src/cli/errors.js +150 -0
  113. package/dist/src/cli/find-package-root.js +40 -0
  114. package/dist/src/cli/git-hooks.js +250 -0
  115. package/dist/src/cli/handlers/agentcard.js +206 -0
  116. package/dist/src/cli/handlers/artifacts.js +76 -0
  117. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  118. package/dist/src/cli/handlers/cockpit.js +137 -0
  119. package/dist/src/cli/handlers/command-log.js +37 -0
  120. package/dist/src/cli/handlers/daemon.js +59 -0
  121. package/dist/src/cli/handlers/diagnose.js +300 -0
  122. package/dist/src/cli/handlers/execution-mode.js +105 -0
  123. package/dist/src/cli/handlers/feedback.js +341 -0
  124. package/dist/src/cli/handlers/help.js +147 -0
  125. package/dist/src/cli/handlers/index.js +302 -0
  126. package/dist/src/cli/handlers/init.js +179 -0
  127. package/dist/src/cli/handlers/install.js +129 -0
  128. package/dist/src/cli/handlers/issues.js +46 -0
  129. package/dist/src/cli/handlers/lint.js +42 -0
  130. package/dist/src/cli/handlers/local-executor.js +315 -0
  131. package/dist/src/cli/handlers/marketplace.js +168 -0
  132. package/dist/src/cli/handlers/mc.js +1010 -0
  133. package/dist/src/cli/handlers/models.js +352 -0
  134. package/dist/src/cli/handlers/packages.js +155 -0
  135. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  136. package/dist/src/cli/handlers/ralph.js +575 -0
  137. package/dist/src/cli/handlers/refresh.js +432 -0
  138. package/dist/src/cli/handlers/regenerate.js +336 -0
  139. package/dist/src/cli/handlers/repo-access.js +109 -0
  140. package/dist/src/cli/handlers/run.js +165 -0
  141. package/dist/src/cli/handlers/runtime-info.js +301 -0
  142. package/dist/src/cli/handlers/sandbox.js +197 -0
  143. package/dist/src/cli/handlers/scaffolding.js +149 -0
  144. package/dist/src/cli/handlers/script-runner.js +121 -0
  145. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  146. package/dist/src/cli/handlers/serve.js +1835 -0
  147. package/dist/src/cli/handlers/session.js +348 -0
  148. package/dist/src/cli/handlers/setup.js +440 -0
  149. package/dist/src/cli/handlers/skill-lint.js +367 -0
  150. package/dist/src/cli/handlers/skill-usage.js +74 -0
  151. package/dist/src/cli/handlers/steward.js +567 -0
  152. package/dist/src/cli/handlers/subcommands.js +1702 -0
  153. package/dist/src/cli/handlers/team.js +337 -0
  154. package/dist/src/cli/handlers/types.js +11 -0
  155. package/dist/src/cli/handlers/use.js +2772 -0
  156. package/dist/src/cli/handlers/utilities.js +703 -0
  157. package/dist/src/cli/handlers/version.js +134 -0
  158. package/dist/src/cli/handlers/workspace-context.js +93 -0
  159. package/dist/src/cli/handlers/workspace.js +126 -0
  160. package/dist/src/cli/help-generator.js +178 -0
  161. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  162. package/dist/src/cli/hooks/executor.js +96 -0
  163. package/dist/src/cli/hooks/index.js +15 -0
  164. package/dist/src/cli/hooks/registry.js +143 -0
  165. package/dist/src/cli/hooks/types.js +13 -0
  166. package/dist/src/cli/log.js +492 -0
  167. package/dist/src/cli/project-isolation/detect.js +70 -0
  168. package/dist/src/cli/project-isolation/index.js +7 -0
  169. package/dist/src/cli/project-isolation/signals.js +17 -0
  170. package/dist/src/cli/project-isolation/warning.js +102 -0
  171. package/dist/src/cli/prompt-utils.js +155 -0
  172. package/dist/src/cli/provider-deployment-plan.js +126 -0
  173. package/dist/src/cli/provider-resolution.js +119 -0
  174. package/dist/src/cli/router.js +305 -0
  175. package/dist/src/cli/scope-resolver.js +392 -0
  176. package/dist/src/cli/skill-usage.js +616 -0
  177. package/dist/src/cli/ui.js +224 -0
  178. package/dist/src/cli/watch-service.js +203 -0
  179. package/dist/src/cli/workflow-orchestrator.js +478 -0
  180. package/dist/src/cli/workspace-signals.js +321 -0
  181. package/dist/src/community/footer.js +14 -0
  182. package/dist/src/community/links.js +123 -0
  183. package/dist/src/community/milestones.js +46 -0
  184. package/dist/src/community/nudge-policy.js +93 -0
  185. package/dist/src/config/aiwg-config.js +883 -0
  186. package/dist/src/config/cli.js +703 -0
  187. package/dist/src/config/gitignore.js +156 -0
  188. package/dist/src/config/project-artifacts.js +76 -0
  189. package/dist/src/config/user-config.js +428 -0
  190. package/dist/src/config/user-registry.js +127 -0
  191. package/dist/src/config/workspace.js +276 -0
  192. package/dist/src/contributors/detect.js +39 -0
  193. package/dist/src/contributors/discover.js +172 -0
  194. package/dist/src/contributors/heuristic.js +186 -0
  195. package/dist/src/contributors/index.js +11 -0
  196. package/dist/src/contributors/types.js +13 -0
  197. package/dist/src/contributors/validation.js +116 -0
  198. package/dist/src/data/community.schema.json +43 -0
  199. package/dist/src/data/community.yaml +16 -0
  200. package/dist/src/extensions/capability-index.js +270 -0
  201. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  202. package/dist/src/extensions/commands/definitions.js +3485 -0
  203. package/dist/src/extensions/deployment-registration.js +463 -0
  204. package/dist/src/extensions/index.js +22 -0
  205. package/dist/src/extensions/loader.js +132 -0
  206. package/dist/src/extensions/managed-marker.js +100 -0
  207. package/dist/src/extensions/manifest.js +196 -0
  208. package/dist/src/extensions/project-local-activity.js +114 -0
  209. package/dist/src/extensions/project-local-discovery.js +261 -0
  210. package/dist/src/extensions/project-local-doctor.js +281 -0
  211. package/dist/src/extensions/project-local-gitignore.js +176 -0
  212. package/dist/src/extensions/project-local-paths.js +121 -0
  213. package/dist/src/extensions/project-local-promote.js +218 -0
  214. package/dist/src/extensions/project-local-remove.js +373 -0
  215. package/dist/src/extensions/project-local-scaffold.js +252 -0
  216. package/dist/src/extensions/project-quickref.js +291 -0
  217. package/dist/src/extensions/registry.js +368 -0
  218. package/dist/src/extensions/shadow-resolver.js +271 -0
  219. package/dist/src/extensions/types.js +86 -0
  220. package/dist/src/extensions/upstream-registry.js +195 -0
  221. package/dist/src/extensions/validation.js +631 -0
  222. package/dist/src/features/catalog.js +88 -0
  223. package/dist/src/features/cli.js +197 -0
  224. package/dist/src/features/installer.js +57 -0
  225. package/dist/src/features/paths.js +14 -0
  226. package/dist/src/features/runtime.js +21 -0
  227. package/dist/src/features/status.js +134 -0
  228. package/dist/src/hooks/laziness-detection.js +532 -0
  229. package/dist/src/intake/git-history-analyzer.js +486 -0
  230. package/dist/src/intake/index.js +9 -0
  231. package/dist/src/issues/cli.js +327 -0
  232. package/dist/src/issues/index.js +5 -0
  233. package/dist/src/issues/live.js +154 -0
  234. package/dist/src/issues/local.js +666 -0
  235. package/dist/src/issues/sync.js +143 -0
  236. package/dist/src/issues/types.js +2 -0
  237. package/dist/src/issues/workflows.js +164 -0
  238. package/dist/src/kb/cli.js +173 -0
  239. package/dist/src/lint/cli.js +171 -0
  240. package/dist/src/lint/loader.js +225 -0
  241. package/dist/src/lint/reporters.js +141 -0
  242. package/dist/src/lint/runner.js +364 -0
  243. package/dist/src/lint/types.js +10 -0
  244. package/dist/src/marketplace/cache.js +110 -0
  245. package/dist/src/marketplace/identifier.js +63 -0
  246. package/dist/src/marketplace/registry.js +36 -0
  247. package/dist/src/marketplace/sources/clawhub.js +53 -0
  248. package/dist/src/marketplace/sources/git.js +45 -0
  249. package/dist/src/marketplace/types.js +9 -0
  250. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  251. package/dist/src/mcp/cli.mjs +1197 -0
  252. package/dist/src/mcp/elicitation.mjs +149 -0
  253. package/dist/src/mcp/helpers.mjs +287 -0
  254. package/dist/src/mcp/index.mjs +11 -0
  255. package/dist/src/mcp/profiles.js +263 -0
  256. package/dist/src/mcp/profiles.mjs +360 -0
  257. package/dist/src/mcp/registry.js +376 -0
  258. package/dist/src/mcp/registry.mjs +387 -0
  259. package/dist/src/mcp/server.mjs +633 -0
  260. package/dist/src/mcp/test-simple.mjs +271 -0
  261. package/dist/src/mcp/tools/command-run.mjs +101 -0
  262. package/dist/src/mcp/tools/discovery.mjs +291 -0
  263. package/dist/src/mcp/tools/interaction.mjs +87 -0
  264. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  265. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  266. package/dist/src/memory/cli.js +166 -0
  267. package/dist/src/memory/project-registry.js +282 -0
  268. package/dist/src/metrics/artifact-metrics.js +184 -0
  269. package/dist/src/metrics/context-budget.js +174 -0
  270. package/dist/src/metrics/token-counter.js +133 -0
  271. package/dist/src/models/config-loader.js +228 -0
  272. package/dist/src/models/index.js +22 -0
  273. package/dist/src/models/model-capabilities.v1.json +120 -0
  274. package/dist/src/models/model-catalog.v1.json +96 -0
  275. package/dist/src/models/model-discovery.js +521 -0
  276. package/dist/src/models/provider-models.js +73 -0
  277. package/dist/src/models/provider-policy.js +273 -0
  278. package/dist/src/models/resolver.js +245 -0
  279. package/dist/src/models/router.js +70 -0
  280. package/dist/src/models/types.js +8 -0
  281. package/dist/src/models/wrapper-deployment.js +178 -0
  282. package/dist/src/models/wrapper-route.js +54 -0
  283. package/dist/src/ops/cli.js +268 -0
  284. package/dist/src/ops/registry.js +623 -0
  285. package/dist/src/packages/adapters/clawhub.js +113 -0
  286. package/dist/src/packages/adapters/git.js +153 -0
  287. package/dist/src/packages/adapters/gitea.js +93 -0
  288. package/dist/src/packages/adapters/github.js +69 -0
  289. package/dist/src/packages/adapters/local-cache.js +89 -0
  290. package/dist/src/packages/package-registry.js +143 -0
  291. package/dist/src/packages/registry.js +238 -0
  292. package/dist/src/packages/types.js +11 -0
  293. package/dist/src/plugin/cross-framework-ops.js +475 -0
  294. package/dist/src/plugin/framework-config-loader.js +235 -0
  295. package/dist/src/plugin/framework-detector.js +186 -0
  296. package/dist/src/plugin/framework-isolator.js +341 -0
  297. package/dist/src/plugin/framework-migration.js +371 -0
  298. package/dist/src/plugin/metadata-validator.js +906 -0
  299. package/dist/src/plugin/plugin-installer.js +436 -0
  300. package/dist/src/plugin/plugin-status.js +369 -0
  301. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  302. package/dist/src/plugin/registry-validator.js +344 -0
  303. package/dist/src/plugin/skill-command-translator.js +415 -0
  304. package/dist/src/plugin/workspace-creator.js +189 -0
  305. package/dist/src/plugin/workspace-migrator.js +821 -0
  306. package/dist/src/policy/authorization.js +390 -0
  307. package/dist/src/policy/repo-access.js +215 -0
  308. package/dist/src/provenance/cli.js +16 -0
  309. package/dist/src/providers/capability-matrix.js +300 -0
  310. package/dist/src/providers/capability-matrix.yaml +514 -0
  311. package/dist/src/providers/provider-definitions.js +977 -0
  312. package/dist/src/providers/provider-definitions.mjs +159 -0
  313. package/dist/src/providers/provider-inventory.js +169 -0
  314. package/dist/src/quality/feedback-ab.js +174 -0
  315. package/dist/src/quality/feedback-collector.js +176 -0
  316. package/dist/src/quality/feedback-tracker.js +123 -0
  317. package/dist/src/quality/patterns/adr.json +24 -0
  318. package/dist/src/quality/patterns/sad.json +24 -0
  319. package/dist/src/quality/patterns/test-plan.json +24 -0
  320. package/dist/src/quality/patterns/use-case.json +24 -0
  321. package/dist/src/quality/scoring.js +157 -0
  322. package/dist/src/reflections/cli.js +15 -0
  323. package/dist/src/release/plan.js +139 -0
  324. package/dist/src/research/cache/manager.js +227 -0
  325. package/dist/src/research/clients/arxiv.js +156 -0
  326. package/dist/src/research/clients/base.js +197 -0
  327. package/dist/src/research/clients/crossref.js +112 -0
  328. package/dist/src/research/clients/semantic-scholar.js +126 -0
  329. package/dist/src/research/clients/unpaywall.js +87 -0
  330. package/dist/src/research/index.js +14 -0
  331. package/dist/src/research/query-cli.js +336 -0
  332. package/dist/src/research/services/acquisition.js +313 -0
  333. package/dist/src/research/services/archival.js +225 -0
  334. package/dist/src/research/services/citation.js +279 -0
  335. package/dist/src/research/services/discovery.js +243 -0
  336. package/dist/src/research/services/documentation.js +269 -0
  337. package/dist/src/research/services/index.js +14 -0
  338. package/dist/src/research/services/provenance.js +279 -0
  339. package/dist/src/research/services/quality.js +370 -0
  340. package/dist/src/research/services/types.js +7 -0
  341. package/dist/src/research/storage-cli.js +20 -0
  342. package/dist/src/research/types.js +47 -0
  343. package/dist/src/resources/index.d.ts +2 -0
  344. package/dist/src/resources/index.js +2 -0
  345. package/dist/src/resources/web-release.d.ts +89 -0
  346. package/dist/src/resources/web-release.js +882 -0
  347. package/dist/src/rlm/cache/cli.js +162 -0
  348. package/dist/src/rlm/cache/hash.js +35 -0
  349. package/dist/src/rlm/cache/store.js +170 -0
  350. package/dist/src/rlm/cache/types.js +8 -0
  351. package/dist/src/rlm/cli.js +650 -0
  352. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  353. package/dist/src/serve/agent-router.js +205 -0
  354. package/dist/src/serve/dispatch-router.js +171 -0
  355. package/dist/src/serve/executor-registry.js +715 -0
  356. package/dist/src/serve/mission-conductor.js +177 -0
  357. package/dist/src/serve/orchestrator-adapter.js +113 -0
  358. package/dist/src/serve/orchestrator-override.js +94 -0
  359. package/dist/src/serve/orchestrator-pty.js +133 -0
  360. package/dist/src/serve/pty-bridge.js +799 -0
  361. package/dist/src/serve/sandbox-registry.js +832 -0
  362. package/dist/src/serve/screen-reader.js +228 -0
  363. package/dist/src/serve/stack-adapters.js +68 -0
  364. package/dist/src/serve/telemetry.js +143 -0
  365. package/dist/src/skills/adapters/clawhub.js +250 -0
  366. package/dist/src/skills/adapters/local.js +335 -0
  367. package/dist/src/skills/adapters/openclaw.js +316 -0
  368. package/dist/src/skills/cli.js +334 -0
  369. package/dist/src/skills/registry.js +117 -0
  370. package/dist/src/skills/run.js +259 -0
  371. package/dist/src/skills/runtime.js +94 -0
  372. package/dist/src/skills/types.js +10 -0
  373. package/dist/src/smiths/agentsmith/demo.js +116 -0
  374. package/dist/src/smiths/agentsmith/examples.js +300 -0
  375. package/dist/src/smiths/agentsmith/generator.js +503 -0
  376. package/dist/src/smiths/agentsmith/index.js +11 -0
  377. package/dist/src/smiths/agentsmith/types.js +8 -0
  378. package/dist/src/smiths/commandsmith/example.js +220 -0
  379. package/dist/src/smiths/commandsmith/generator.js +288 -0
  380. package/dist/src/smiths/commandsmith/index.js +41 -0
  381. package/dist/src/smiths/commandsmith/templates.js +296 -0
  382. package/dist/src/smiths/commandsmith/types.js +7 -0
  383. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  384. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  385. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  386. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  387. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  388. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  389. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  390. package/dist/src/smiths/context-pipeline/index.js +30 -0
  391. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  392. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  393. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  394. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  395. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  396. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  397. package/dist/src/smiths/context-pipeline/types.js +23 -0
  398. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  399. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  400. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  401. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  402. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  403. package/dist/src/smiths/hook-bridge/index.js +79 -0
  404. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  405. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  406. package/dist/src/smiths/hook-bridge/types.js +31 -0
  407. package/dist/src/smiths/index.js +39 -0
  408. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  409. package/dist/src/smiths/mcpsmith/example.js +119 -0
  410. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  411. package/dist/src/smiths/mcpsmith/index.js +17 -0
  412. package/dist/src/smiths/mcpsmith/types.js +10 -0
  413. package/dist/src/smiths/platform-paths.js +101 -0
  414. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  415. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  416. package/dist/src/smiths/skillsmith/demo.js +83 -0
  417. package/dist/src/smiths/skillsmith/examples.js +161 -0
  418. package/dist/src/smiths/skillsmith/generator.js +316 -0
  419. package/dist/src/smiths/skillsmith/index.js +12 -0
  420. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  421. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  422. package/dist/src/smiths/skillsmith/types.js +9 -0
  423. package/dist/src/smiths/toolsmith/index.js +10 -0
  424. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  425. package/dist/src/smiths/toolsmith/types.js +8 -0
  426. package/dist/src/storage/backends/fortemi.js +227 -0
  427. package/dist/src/storage/backends/fs.js +134 -0
  428. package/dist/src/storage/backends/logseq.js +309 -0
  429. package/dist/src/storage/backends/obsidian.js +233 -0
  430. package/dist/src/storage/cli.js +468 -0
  431. package/dist/src/storage/config.js +272 -0
  432. package/dist/src/storage/index.js +108 -0
  433. package/dist/src/storage/subsystem-cli.js +201 -0
  434. package/dist/src/storage/types.js +33 -0
  435. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  436. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  437. package/dist/src/testing/corpus/index.js +10 -0
  438. package/dist/src/testing/fixtures/index.js +9 -0
  439. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  440. package/dist/src/testing/generators/index.js +11 -0
  441. package/dist/src/testing/generators/test-case-generator.js +393 -0
  442. package/dist/src/testing/generators/test-code-generator.js +384 -0
  443. package/dist/src/testing/generators/use-case-parser.js +325 -0
  444. package/dist/src/testing/index.js +11 -0
  445. package/dist/src/tracker/capability-protocol.js +118 -0
  446. package/dist/src/update/checker.mjs +396 -0
  447. package/dist/src/update/notifier.mjs +235 -0
  448. package/dist/src/writing/content-diversifier.js +804 -0
  449. package/dist/src/writing/example-generator.js +959 -0
  450. package/dist/src/writing/example-templates.js +99 -0
  451. package/dist/src/writing/pattern-library.js +486 -0
  452. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  453. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  454. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  455. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  456. package/dist/src/writing/patterns/transition-words.json +1285 -0
  457. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  458. package/dist/src/writing/prompt-optimizer.js +660 -0
  459. package/dist/src/writing/prompt-templates.js +583 -0
  460. package/dist/src/writing/scoring-config-loader.js +168 -0
  461. package/dist/src/writing/validation-engine.js +595 -0
  462. package/dist/src/writing/validation-rules.js +380 -0
  463. package/dist/src/writing/voice-analyzer.js +439 -0
  464. package/dist/src/writing/voice-calibration.js +661 -0
  465. package/dist/src/writing/voice-profiles.json +588 -0
  466. package/package.json +64 -9
@@ -0,0 +1,666 @@
1
+ import { constants } from 'fs';
2
+ import { mkdir, open, readFile, readdir, rename, unlink, writeFile } from 'fs/promises';
3
+ import { basename, dirname, join, relative, resolve, sep } from 'path';
4
+ import { hostname } from 'os';
5
+ import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
6
+ import { projectAiwgPath } from '../config/project-artifacts.js';
7
+ const DEFAULT_PREFIX = 'ISSUE';
8
+ const DEFAULT_PADDING = 4;
9
+ const VALID_STATUSES = new Set(['open', 'closed', 'archived']);
10
+ const VALID_TYPES = new Set(['bug', 'feature', 'research', 'task', 'epic']);
11
+ const VALID_PRIORITIES = new Set(['P0', 'P1', 'P2', 'P3']);
12
+ const VALID_EVENT_TYPES = new Set([
13
+ 'created',
14
+ 'comment',
15
+ 'status_changed',
16
+ 'label_added',
17
+ 'label_removed',
18
+ 'linked',
19
+ 'cycle_status',
20
+ 'closed',
21
+ ]);
22
+ export class LocalIssueProviderError extends Error {
23
+ }
24
+ export class LocalIssueLockError extends LocalIssueProviderError {
25
+ }
26
+ export class LocalIssueLockManager {
27
+ locksDir;
28
+ waitMs;
29
+ pollMs;
30
+ constructor(root, options = {}) {
31
+ this.locksDir = join(resolve(root), 'locks');
32
+ this.waitMs = options.waitMs ?? 2000;
33
+ this.pollMs = options.pollMs ?? 10;
34
+ }
35
+ async withIssueLock(issueId, operation, fn) {
36
+ return this.withLock(issueId + '.lock', operation, fn);
37
+ }
38
+ async withIdLock(operation, fn) {
39
+ return this.withLock('next-id.lock', operation, fn);
40
+ }
41
+ async withIndexLock(operation, fn) {
42
+ return this.withLock('index.lock', operation, fn);
43
+ }
44
+ async withLock(name, operation, fn) {
45
+ await mkdir(this.locksDir, { recursive: true });
46
+ const lockPath = join(this.locksDir, name);
47
+ const payload = {
48
+ pid: process.pid,
49
+ hostname: hostname(),
50
+ created_at: new Date().toISOString(),
51
+ operation,
52
+ };
53
+ const handle = await this.acquire(lockPath, payload);
54
+ try {
55
+ return await fn();
56
+ }
57
+ finally {
58
+ await handle.close();
59
+ await unlink(lockPath).catch(() => undefined);
60
+ }
61
+ }
62
+ async acquire(lockPath, payload) {
63
+ const started = Date.now();
64
+ let existing = '';
65
+ while (true) {
66
+ try {
67
+ const handle = await open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
68
+ await handle.writeFile(JSON.stringify(payload, null, 2));
69
+ await handle.sync();
70
+ return handle;
71
+ }
72
+ catch (error) {
73
+ if (!isNodeError(error) || error.code !== 'EEXIST')
74
+ throw error;
75
+ existing = await readFile(lockPath, 'utf-8').catch(() => '');
76
+ if (Date.now() - started >= this.waitMs) {
77
+ throw new LocalIssueLockError('local issue lock already exists at ' + lockPath + (existing ? ': ' + existing : ''));
78
+ }
79
+ await sleep(this.pollMs);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ export class LocalIssueProviderCore {
85
+ root;
86
+ lockManager;
87
+ constructor(root) {
88
+ this.root = resolve(root);
89
+ this.lockManager = new LocalIssueLockManager(this.root);
90
+ }
91
+ async init(options = {}) {
92
+ await this.ensureLayout();
93
+ const existing = await this.readConfigIfExists();
94
+ if (existing)
95
+ return existing;
96
+ const config = {
97
+ provider: 'local',
98
+ issue_key: {
99
+ prefix: normalizePrefix(options.prefix ?? (await suggestLocalIssuePrefix(this.projectRoot()))?.prefix ?? DEFAULT_PREFIX),
100
+ padding: options.padding ?? DEFAULT_PADDING,
101
+ next: 1,
102
+ },
103
+ };
104
+ validateConfig(config);
105
+ await atomicWrite(this.path('config.json'), `${JSON.stringify(config, null, 2)}\n`);
106
+ await atomicWrite(this.path('next-id'), '1\n');
107
+ await this.rebuildIssueIndex();
108
+ return config;
109
+ }
110
+ async createIssue(input) {
111
+ await this.init();
112
+ const id = await this.allocateIssueId();
113
+ const now = new Date().toISOString();
114
+ const fields = {
115
+ id,
116
+ status: 'open',
117
+ title: requireNonEmpty(input.title, 'title'),
118
+ type: input.type ?? 'task',
119
+ priority: input.priority ?? 'P2',
120
+ labels: normalizeStringArray(input.labels ?? []),
121
+ assignees: normalizeStringArray(input.assignees ?? []),
122
+ created_at: now,
123
+ updated_at: now,
124
+ closed_at: null,
125
+ links: { external: [], parent: null, children: [], related: [] },
126
+ source: { provider: 'local', external_id: null, external_url: null },
127
+ };
128
+ validateIssueFields(fields);
129
+ const record = { fields, body: input.body ?? '' };
130
+ await this.lockManager.withIssueLock(id, 'create issue', async () => {
131
+ await atomicWrite(this.itemPath(id), serializeIssueMarkdown(record));
132
+ await this.appendEventUnlocked(id, {
133
+ type: 'created',
134
+ author: input.author ?? 'operator',
135
+ body: input.body,
136
+ });
137
+ });
138
+ await this.rebuildIssueIndex();
139
+ return record;
140
+ }
141
+ async importIssue(input) {
142
+ await this.init();
143
+ const id = await this.allocateIssueId();
144
+ const now = new Date().toISOString();
145
+ const createdAt = input.created_at ?? input.updated_at ?? now;
146
+ const updatedAt = input.updated_at ?? createdAt;
147
+ const status = input.status === 'closed' ? 'closed' : 'open';
148
+ const fields = {
149
+ id,
150
+ status,
151
+ title: requireNonEmpty(input.title, 'title'),
152
+ type: 'task',
153
+ priority: 'P2',
154
+ labels: normalizeStringArray(input.labels ?? []),
155
+ assignees: normalizeStringArray(input.assignees ?? []),
156
+ created_at: createdAt,
157
+ updated_at: updatedAt,
158
+ closed_at: status === 'closed' ? updatedAt : null,
159
+ links: { external: input.external_url ? [input.external_url] : [], parent: null, children: [], related: [] },
160
+ source: { provider: input.provider, external_id: requireNonEmpty(input.external_id, 'external id'), external_url: input.external_url ?? null },
161
+ };
162
+ validateIssueFields(fields);
163
+ const record = { fields, body: input.body ?? '' };
164
+ await this.lockManager.withIssueLock(id, 'import external issue', async () => {
165
+ await atomicWrite(this.itemPath(id), serializeIssueMarkdown(record));
166
+ await this.appendEventUnlocked(id, {
167
+ type: 'created',
168
+ author: input.provider,
169
+ created_at: createdAt,
170
+ body: input.body,
171
+ data: { external_id: input.external_id, external_url: input.external_url ?? null, provider: input.provider },
172
+ });
173
+ for (const comment of input.comments ?? []) {
174
+ await this.appendEventUnlocked(id, {
175
+ type: 'comment',
176
+ author: comment.author,
177
+ created_at: comment.created_at,
178
+ body: comment.body,
179
+ data: {
180
+ ...(comment.external_id ? { external_comment_id: comment.external_id } : {}),
181
+ ...(comment.updated_at ? { external_updated_at: comment.updated_at } : {}),
182
+ provider: input.provider,
183
+ },
184
+ });
185
+ }
186
+ });
187
+ await this.rebuildIssueIndex();
188
+ return this.getIssue(id, { body: true, comments: 'all' });
189
+ }
190
+ async applyCommentIdMappings(id, mappings) {
191
+ const normalized = normalizeIssueId(id);
192
+ const byEventId = new Map(mappings.map((mapping) => [mapping.local_event_id, mapping.external_comment_id]));
193
+ await this.lockManager.withIssueLock(normalized, 'apply external comment id mappings', async () => {
194
+ await this.readIssue(normalized);
195
+ const raw = await readFile(this.eventPath(normalized), 'utf-8').catch((error) => {
196
+ if (isNodeError(error) && error.code === 'ENOENT')
197
+ return '';
198
+ throw error;
199
+ });
200
+ const events = raw
201
+ .split(/\r?\n/)
202
+ .filter((line) => line.trim().length > 0)
203
+ .map((line) => JSON.parse(line));
204
+ let changed = false;
205
+ const updated = events.map((event) => {
206
+ const externalCommentId = byEventId.get(event.event_id);
207
+ if (!externalCommentId)
208
+ return event;
209
+ changed = true;
210
+ return {
211
+ ...event,
212
+ data: {
213
+ ...(event.data ?? {}),
214
+ external_comment_id: externalCommentId,
215
+ },
216
+ };
217
+ });
218
+ if (changed) {
219
+ await atomicWrite(this.eventPath(normalized), updated.map((event) => JSON.stringify(event)).join('\n') + '\n');
220
+ }
221
+ });
222
+ return this.readEvents(normalized, 'all');
223
+ }
224
+ async getIssue(id, options = { body: true, comments: 'all' }) {
225
+ const normalized = normalizeIssueId(id);
226
+ const record = await this.readIssue(normalized);
227
+ const events = await this.readEvents(normalized, options.comments ?? 'all');
228
+ return {
229
+ fields: record.fields,
230
+ body: options.body === false ? '' : record.body,
231
+ events,
232
+ };
233
+ }
234
+ async listIssues(options = {}) {
235
+ const index = await this.readIndexOrRebuild();
236
+ const offset = options.cursor ? Number.parseInt(options.cursor, 10) : 0;
237
+ const limit = options.limit ?? 50;
238
+ if (!Number.isInteger(offset) || offset < 0) {
239
+ throw new LocalIssueProviderError(`invalid issue list cursor: ${options.cursor}`);
240
+ }
241
+ const filtered = index.issues.filter((issue) => matchesFilter(issue, options.filter));
242
+ const issues = filtered.slice(offset, offset + limit);
243
+ const nextOffset = offset + issues.length;
244
+ return {
245
+ issues,
246
+ nextCursor: nextOffset < filtered.length ? String(nextOffset) : null,
247
+ };
248
+ }
249
+ async updateIssueFields(id, patch) {
250
+ const normalized = normalizeIssueId(id);
251
+ const updated = await this.lockManager.withIssueLock(normalized, 'update issue fields', async () => {
252
+ const current = await this.readIssue(normalized);
253
+ const nextFields = {
254
+ ...current.fields,
255
+ ...patch,
256
+ updated_at: new Date().toISOString(),
257
+ };
258
+ if (patch.status === 'closed' && !nextFields.closed_at) {
259
+ nextFields.closed_at = nextFields.updated_at;
260
+ }
261
+ if (patch.status && patch.status !== 'closed') {
262
+ nextFields.closed_at = null;
263
+ }
264
+ validateIssueFields(nextFields);
265
+ const next = { fields: nextFields, body: current.body };
266
+ await atomicWrite(this.itemPath(normalized), serializeIssueMarkdown(next));
267
+ if (patch.status && patch.status !== current.fields.status) {
268
+ await this.appendEventUnlocked(normalized, {
269
+ type: 'status_changed',
270
+ author: 'operator',
271
+ data: { from: current.fields.status, to: patch.status },
272
+ });
273
+ }
274
+ return next;
275
+ });
276
+ await this.rebuildIssueIndex();
277
+ return updated;
278
+ }
279
+ async appendIssueEvent(id, event) {
280
+ const normalized = normalizeIssueId(id);
281
+ const appended = await this.lockManager.withIssueLock(normalized, `append ${event.type} event`, async () => {
282
+ await this.readIssue(normalized);
283
+ const result = await this.appendEventUnlocked(normalized, event);
284
+ await this.touchIssueUpdatedAt(normalized, result.created_at);
285
+ return result;
286
+ });
287
+ await this.rebuildIssueIndex();
288
+ return appended;
289
+ }
290
+ async commentIssue(id, body, options = {}) {
291
+ return this.appendIssueEvent(id, {
292
+ type: options.type ?? 'comment',
293
+ author: options.author ?? 'operator',
294
+ body,
295
+ });
296
+ }
297
+ async closeIssue(id, options = {}) {
298
+ const normalized = normalizeIssueId(id);
299
+ const closed = await this.lockManager.withIssueLock(normalized, 'close issue', async () => {
300
+ const current = await this.readIssue(normalized);
301
+ const now = new Date().toISOString();
302
+ const next = {
303
+ fields: {
304
+ ...current.fields,
305
+ status: 'closed',
306
+ updated_at: now,
307
+ closed_at: now,
308
+ },
309
+ body: current.body,
310
+ };
311
+ await atomicWrite(this.itemPath(normalized), serializeIssueMarkdown(next));
312
+ await this.appendEventUnlocked(normalized, {
313
+ type: 'closed',
314
+ author: options.author ?? 'operator',
315
+ body: options.reason,
316
+ });
317
+ return next;
318
+ });
319
+ await this.rebuildIssueIndex();
320
+ return closed;
321
+ }
322
+ async getIssueThreadSince(id, since) {
323
+ const events = await this.readEvents(normalizeIssueId(id), 'all');
324
+ const sinceTime = Date.parse(since);
325
+ if (!Number.isNaN(sinceTime)) {
326
+ return events.filter((event) => Date.parse(event.created_at) > sinceTime);
327
+ }
328
+ const idx = events.findIndex((event) => event.event_id === since);
329
+ return idx >= 0 ? events.slice(idx + 1) : events;
330
+ }
331
+ async rebuildIssueIndex() {
332
+ await this.ensureLayout();
333
+ return this.lockManager.withIndexLock('rebuild issue index', async () => {
334
+ const itemDir = this.path('items');
335
+ const entries = await readdir(itemDir, { withFileTypes: true }).catch(() => []);
336
+ const issues = [];
337
+ for (const entry of entries) {
338
+ if (!entry.isFile() || !entry.name.endsWith('.md'))
339
+ continue;
340
+ const record = parseIssueMarkdown(await readFile(join(itemDir, entry.name), 'utf-8'));
341
+ issues.push({
342
+ id: record.fields.id,
343
+ title: record.fields.title,
344
+ status: record.fields.status,
345
+ type: record.fields.type,
346
+ priority: record.fields.priority,
347
+ labels: record.fields.labels,
348
+ assignees: record.fields.assignees,
349
+ updated_at: record.fields.updated_at,
350
+ closed_at: record.fields.closed_at,
351
+ path: `items/${entry.name}`,
352
+ });
353
+ }
354
+ issues.sort((a, b) => a.id.localeCompare(b.id));
355
+ const index = {
356
+ provider: 'local',
357
+ rebuilt_at: new Date().toISOString(),
358
+ issues,
359
+ };
360
+ await atomicWrite(this.path('index/issues.index.json'), `${JSON.stringify(index, null, 2)}\n`);
361
+ return index;
362
+ });
363
+ }
364
+ async ensureLayout() {
365
+ await mkdir(this.path('items'), { recursive: true });
366
+ await mkdir(this.path('events/bodies'), { recursive: true });
367
+ await mkdir(this.path('index'), { recursive: true });
368
+ await mkdir(this.path('locks'), { recursive: true });
369
+ }
370
+ async allocateIssueId() {
371
+ return this.lockManager.withIdLock('allocate issue id', async () => {
372
+ const config = await this.readConfig();
373
+ const nextFromFile = await readFile(this.path('next-id'), 'utf-8')
374
+ .then((raw) => Number.parseInt(raw.trim(), 10))
375
+ .catch(() => config.issue_key.next);
376
+ const next = Number.isInteger(nextFromFile) && nextFromFile > 0 ? nextFromFile : config.issue_key.next;
377
+ const id = `${config.issue_key.prefix}-${String(next).padStart(config.issue_key.padding, '0')}`;
378
+ const updated = {
379
+ ...config,
380
+ issue_key: { ...config.issue_key, next: next + 1 },
381
+ };
382
+ await atomicWrite(this.path('config.json'), `${JSON.stringify(updated, null, 2)}\n`);
383
+ await atomicWrite(this.path('next-id'), `${next + 1}\n`);
384
+ return id;
385
+ });
386
+ }
387
+ async readConfigIfExists() {
388
+ const raw = await readFile(this.path('config.json'), 'utf-8').catch((error) => {
389
+ if (isNodeError(error) && error.code === 'ENOENT')
390
+ return null;
391
+ throw error;
392
+ });
393
+ if (raw === null)
394
+ return null;
395
+ const config = JSON.parse(raw);
396
+ validateConfig(config);
397
+ return config;
398
+ }
399
+ async readConfig() {
400
+ const config = await this.readConfigIfExists();
401
+ if (!config)
402
+ throw new LocalIssueProviderError('local issues are not initialized');
403
+ return config;
404
+ }
405
+ async readIndexOrRebuild() {
406
+ const raw = await readFile(this.path('index/issues.index.json'), 'utf-8').catch((error) => {
407
+ if (isNodeError(error) && error.code === 'ENOENT')
408
+ return null;
409
+ throw error;
410
+ });
411
+ if (!raw)
412
+ return this.rebuildIssueIndex();
413
+ return JSON.parse(raw);
414
+ }
415
+ async readIssue(id) {
416
+ const raw = await readFile(this.itemPath(id), 'utf-8').catch((error) => {
417
+ if (isNodeError(error) && error.code === 'ENOENT') {
418
+ throw new LocalIssueProviderError(`local issue not found: ${id}`);
419
+ }
420
+ throw error;
421
+ });
422
+ const record = parseIssueMarkdown(raw);
423
+ if (record.fields.id !== id) {
424
+ throw new LocalIssueProviderError(`issue id mismatch: path ${id}, frontmatter ${record.fields.id}`);
425
+ }
426
+ return record;
427
+ }
428
+ async touchIssueUpdatedAt(id, updatedAt) {
429
+ const current = await this.readIssue(id);
430
+ const next = {
431
+ fields: { ...current.fields, updated_at: updatedAt },
432
+ body: current.body,
433
+ };
434
+ validateIssueFields(next.fields);
435
+ await atomicWrite(this.itemPath(id), serializeIssueMarkdown(next));
436
+ }
437
+ async appendEventUnlocked(id, input) {
438
+ if (!VALID_EVENT_TYPES.has(input.type)) {
439
+ throw new LocalIssueProviderError(`invalid local issue event type: ${input.type}`);
440
+ }
441
+ const eventId = createEventId();
442
+ const createdAt = input.created_at ?? new Date().toISOString();
443
+ let bodyPath = input.body_path;
444
+ if (input.body !== undefined && input.body.length > 0) {
445
+ bodyPath = `events/bodies/${eventId}.md`;
446
+ await atomicWrite(this.path(bodyPath), input.body);
447
+ }
448
+ const event = {
449
+ event_id: eventId,
450
+ issue_id: id,
451
+ type: input.type,
452
+ author: requireNonEmpty(input.author, 'event author'),
453
+ created_at: createdAt,
454
+ ...(bodyPath ? { body_path: bodyPath } : {}),
455
+ ...(input.data ? { data: input.data } : {}),
456
+ };
457
+ await appendJsonLineSynced(this.eventPath(id), event);
458
+ return event;
459
+ }
460
+ async readEvents(id, comments) {
461
+ const raw = await readFile(this.eventPath(id), 'utf-8').catch((error) => {
462
+ if (isNodeError(error) && error.code === 'ENOENT')
463
+ return '';
464
+ throw error;
465
+ });
466
+ const events = raw
467
+ .split(/\r?\n/)
468
+ .filter((line) => line.trim().length > 0)
469
+ .map((line) => JSON.parse(line));
470
+ const selected = selectEvents(events, comments);
471
+ return Promise.all(selected.map(async (event) => {
472
+ if (!event.body_path)
473
+ return event;
474
+ const body = await readFile(this.path(event.body_path), 'utf-8').catch(() => undefined);
475
+ return body === undefined ? event : { ...event, body };
476
+ }));
477
+ }
478
+ itemPath(id) {
479
+ return this.path(`items/${id}.md`);
480
+ }
481
+ eventPath(id) {
482
+ return this.path(`events/${id}.jsonl`);
483
+ }
484
+ projectRoot() {
485
+ const parent = dirname(this.root);
486
+ return basename(parent) === '.aiwg' ? dirname(parent) : dirname(this.root);
487
+ }
488
+ path(relPath) {
489
+ const abs = resolve(this.root, relPath);
490
+ if (abs !== this.root && !abs.startsWith(this.root + sep)) {
491
+ throw new LocalIssueProviderError(`local issue path escapes root: ${relPath}`);
492
+ }
493
+ return abs;
494
+ }
495
+ }
496
+ export function parseIssueMarkdown(content) {
497
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
498
+ if (!match) {
499
+ throw new LocalIssueProviderError('local issue markdown must start with YAML frontmatter');
500
+ }
501
+ const fields = parseYaml(match[1]);
502
+ validateIssueFields(fields);
503
+ return { fields, body: match[2] ?? '' };
504
+ }
505
+ export function serializeIssueMarkdown(issue) {
506
+ validateIssueFields(issue.fields);
507
+ return `---\n${stringifyYaml(issue.fields).trimEnd()}\n---\n${issue.body}`;
508
+ }
509
+ function validateConfig(config) {
510
+ if (config.provider !== 'local')
511
+ throw new LocalIssueProviderError('local issue config provider must be "local"');
512
+ normalizePrefix(config.issue_key?.prefix);
513
+ if (!Number.isInteger(config.issue_key.padding) || config.issue_key.padding < 1) {
514
+ throw new LocalIssueProviderError('local issue config padding must be a positive integer');
515
+ }
516
+ if (!Number.isInteger(config.issue_key.next) || config.issue_key.next < 1) {
517
+ throw new LocalIssueProviderError('local issue config next must be a positive integer');
518
+ }
519
+ }
520
+ function validateIssueFields(fields) {
521
+ normalizeIssueId(fields.id);
522
+ requireNonEmpty(fields.title, 'issue title');
523
+ if (!VALID_STATUSES.has(fields.status))
524
+ throw new LocalIssueProviderError(`invalid issue status: ${fields.status}`);
525
+ if (!VALID_TYPES.has(fields.type))
526
+ throw new LocalIssueProviderError(`invalid issue type: ${fields.type}`);
527
+ if (!VALID_PRIORITIES.has(fields.priority))
528
+ throw new LocalIssueProviderError(`invalid issue priority: ${fields.priority}`);
529
+ fields.labels = normalizeStringArray(fields.labels);
530
+ fields.assignees = normalizeStringArray(fields.assignees);
531
+ requireIsoTimestamp(fields.created_at, 'created_at');
532
+ requireIsoTimestamp(fields.updated_at, 'updated_at');
533
+ if (fields.closed_at !== null)
534
+ requireIsoTimestamp(fields.closed_at, 'closed_at');
535
+ if (!fields.links || !Array.isArray(fields.links.external) || !Array.isArray(fields.links.children) || !Array.isArray(fields.links.related)) {
536
+ throw new LocalIssueProviderError('issue links must include external, children, and related arrays');
537
+ }
538
+ if (fields.links.parent !== null && typeof fields.links.parent !== 'string') {
539
+ throw new LocalIssueProviderError('issue links.parent must be a string or null');
540
+ }
541
+ if (!fields.source || !fields.source.provider || !('external_id' in fields.source)) {
542
+ throw new LocalIssueProviderError('issue source metadata is required');
543
+ }
544
+ }
545
+ function matchesFilter(issue, filter) {
546
+ if (!filter)
547
+ return true;
548
+ if (filter.status && !includesOne(filter.status, issue.status))
549
+ return false;
550
+ if (filter.type && !includesOne(filter.type, issue.type))
551
+ return false;
552
+ if (filter.priority && !includesOne(filter.priority, issue.priority))
553
+ return false;
554
+ if (filter.labels && !filter.labels.every((label) => issue.labels.includes(label)))
555
+ return false;
556
+ if (filter.assignee && !issue.assignees.includes(filter.assignee))
557
+ return false;
558
+ if (filter.search) {
559
+ const haystack = `${issue.id} ${issue.title} ${issue.labels.join(' ')}`.toLowerCase();
560
+ if (!haystack.includes(filter.search.toLowerCase()))
561
+ return false;
562
+ }
563
+ return true;
564
+ }
565
+ function includesOne(value, candidate) {
566
+ return Array.isArray(value) ? value.includes(candidate) : value === candidate;
567
+ }
568
+ function selectEvents(events, comments) {
569
+ if (comments === undefined || comments === 'all')
570
+ return events;
571
+ const n = typeof comments === 'number' ? comments : Number.parseInt(comments.replace(/^last:/, ''), 10);
572
+ if (!Number.isInteger(n) || n < 0) {
573
+ throw new LocalIssueProviderError(`invalid comments selector: ${comments}`);
574
+ }
575
+ return events.slice(Math.max(0, events.length - n));
576
+ }
577
+ function normalizePrefix(prefix) {
578
+ const normalized = requireNonEmpty(prefix, 'issue key prefix').toUpperCase();
579
+ if (!/^[A-Z][A-Z0-9]*$/.test(normalized)) {
580
+ throw new LocalIssueProviderError(`invalid issue key prefix: ${prefix}`);
581
+ }
582
+ return normalized;
583
+ }
584
+ function normalizeIssueId(id) {
585
+ const normalized = requireNonEmpty(id, 'issue id').toUpperCase();
586
+ if (!/^[A-Z][A-Z0-9]*-\d+$/.test(normalized)) {
587
+ throw new LocalIssueProviderError(`invalid local issue id: ${id}`);
588
+ }
589
+ return normalized;
590
+ }
591
+ function normalizeStringArray(value) {
592
+ if (!Array.isArray(value))
593
+ throw new LocalIssueProviderError('expected string array');
594
+ return value.map((item) => requireNonEmpty(String(item), 'array item'));
595
+ }
596
+ function requireNonEmpty(value, field) {
597
+ if (typeof value !== 'string' || value.trim().length === 0) {
598
+ throw new LocalIssueProviderError(`${field} must be a non-empty string`);
599
+ }
600
+ return value.trim();
601
+ }
602
+ function requireIsoTimestamp(value, field) {
603
+ if (typeof value !== 'string' || Number.isNaN(Date.parse(value))) {
604
+ throw new LocalIssueProviderError(`${field} must be an ISO timestamp`);
605
+ }
606
+ }
607
+ function createEventId() {
608
+ const random = Math.random().toString(36).slice(2, 10);
609
+ return `evt-${Date.now().toString(36)}-${random}`;
610
+ }
611
+ async function atomicWrite(path, content) {
612
+ await mkdir(dirname(path), { recursive: true });
613
+ const temp = join(dirname(path), `.${basename(path)}.${process.pid}.${Date.now()}.tmp`);
614
+ await writeFile(temp, content, 'utf-8');
615
+ await rename(temp, path);
616
+ }
617
+ async function appendJsonLineSynced(path, value) {
618
+ await mkdir(dirname(path), { recursive: true });
619
+ const handle = await open(path, 'a');
620
+ try {
621
+ await handle.write(`${JSON.stringify(value)}\n`);
622
+ await handle.sync();
623
+ }
624
+ finally {
625
+ await handle.close();
626
+ }
627
+ }
628
+ function isNodeError(error) {
629
+ return error instanceof Error && 'code' in error;
630
+ }
631
+ function sleep(ms) {
632
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
633
+ }
634
+ export async function suggestLocalIssuePrefix(projectRoot) {
635
+ const packageJsonPath = join(resolve(projectRoot), 'package.json');
636
+ const rawPackage = await readFile(packageJsonPath, 'utf-8').catch(() => null);
637
+ if (rawPackage) {
638
+ const parsed = JSON.parse(rawPackage);
639
+ const prefix = prefixFromName(parsed.name);
640
+ if (prefix)
641
+ return { prefix, source: 'package.json#name' };
642
+ }
643
+ const fromDirectory = prefixFromName(basename(resolve(projectRoot)));
644
+ return fromDirectory ? { prefix: fromDirectory, source: 'directory' } : null;
645
+ }
646
+ function prefixFromName(name) {
647
+ if (!name)
648
+ return null;
649
+ const withoutScope = name.includes('/') ? name.split('/').pop() ?? name : name;
650
+ const initials = withoutScope
651
+ .split(/[^A-Za-z0-9]+/)
652
+ .filter(Boolean)
653
+ .map((part) => part[0])
654
+ .join('');
655
+ const candidate = (initials.length >= 2 ? initials : withoutScope).replace(/[^A-Za-z0-9]/g, '').toUpperCase();
656
+ if (!candidate || !/^[A-Z][A-Z0-9]*$/.test(candidate))
657
+ return null;
658
+ return candidate.slice(0, 12);
659
+ }
660
+ export function localIssueRoot(projectRoot) {
661
+ return projectAiwgPath(resolve(projectRoot), 'issues');
662
+ }
663
+ export function localIssueRelativePath(projectRoot, absPath) {
664
+ return relative(resolve(projectRoot), absPath).split(sep).join('/');
665
+ }
666
+ //# sourceMappingURL=local.js.map