@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,240 @@
1
+ // A2A push-notification webhook receiver — verifies HMAC-SHA256 signatures
2
+ // using the Stripe-style `X-AIWG-Signature: t=<ts>,v1=<hmac>` header, rejects
3
+ // stale timestamps (replay protection), and deduplicates by event-id
4
+ // (idempotency).
5
+ //
6
+ // The webhook is the push-based alternative to SSE described in
7
+ // roctinam/agentic-sandbox issue #211. The executor signs the raw request
8
+ // body with a per-config secret (registered via
9
+ // A2AClient.createPushNotificationConfig) and POSTs StreamResponse-shaped
10
+ // payloads to the AIWG receiver URL.
11
+ //
12
+ // This module is HTTP-framework-agnostic. The serve.ts wiring adapts Hono
13
+ // requests to `verifyWebhookSignature`; tests can call the same function
14
+ // directly with synthesized Buffers.
15
+ //
16
+ // @issue #1256
17
+ import { createHmac, timingSafeEqual } from 'node:crypto';
18
+ /** Header name (case-insensitive). */
19
+ export const SIGNATURE_HEADER = 'x-aiwg-signature';
20
+ /** Five minutes — RFC 8941 timestamp tolerance. */
21
+ export const DEFAULT_TIMESTAMP_TOLERANCE_SECONDS = 300;
22
+ /** Idempotency cache size. Old entries are evicted FIFO. */
23
+ export const DEFAULT_IDEMPOTENCY_CAPACITY = 4096;
24
+ /**
25
+ * Verify the `X-AIWG-Signature` header against the raw request body.
26
+ *
27
+ * Stripe-style format:
28
+ * `X-AIWG-Signature: t=1700000000,v1=<hex hmac-sha256>`
29
+ *
30
+ * The HMAC is computed over `t=<timestamp>.<raw body>` (the timestamp and
31
+ * a literal dot, prepended to the body). Multiple `v1=` entries may be
32
+ * present in a single header (during a key rotation); any match accepts.
33
+ */
34
+ export async function verifyWebhookSignature(signature, body, configId, opts) {
35
+ if (!signature) {
36
+ return { ok: false, code: 'signature_missing', detail: 'missing X-AIWG-Signature header' };
37
+ }
38
+ const parsed = parseSignatureHeader(signature);
39
+ if (!parsed) {
40
+ return { ok: false, code: 'signature_malformed', detail: 'X-AIWG-Signature did not parse' };
41
+ }
42
+ const tolerance = opts.toleranceSeconds ?? DEFAULT_TIMESTAMP_TOLERANCE_SECONDS;
43
+ const now = opts.now ? opts.now() : Math.floor(Date.now() / 1000);
44
+ if (Math.abs(now - parsed.timestamp) > tolerance) {
45
+ return {
46
+ ok: false,
47
+ code: 'timestamp_skew',
48
+ detail: `timestamp skew ${Math.abs(now - parsed.timestamp)}s exceeds tolerance ${tolerance}s`,
49
+ };
50
+ }
51
+ const secret = await opts.lookupSecret(configId);
52
+ if (!secret) {
53
+ return { ok: false, code: 'secret_unknown', detail: `no secret registered for configId='${configId}'` };
54
+ }
55
+ const signedPayload = `${parsed.timestamp}.${body.toString('utf8')}`;
56
+ const expected = createHmac('sha256', secret).update(signedPayload).digest('hex');
57
+ for (const candidate of parsed.v1) {
58
+ if (constantTimeHexEqual(candidate, expected)) {
59
+ return { ok: true, timestamp: parsed.timestamp };
60
+ }
61
+ }
62
+ return { ok: false, code: 'signature_mismatch', detail: 'no v1 signature matched' };
63
+ }
64
+ /** Parse `t=...,v1=...,(v1=...,)*` into structured fields. */
65
+ export function parseSignatureHeader(header) {
66
+ const parts = header.split(',').map(s => s.trim()).filter(Boolean);
67
+ let timestamp = null;
68
+ const v1 = [];
69
+ for (const p of parts) {
70
+ const eq = p.indexOf('=');
71
+ if (eq <= 0)
72
+ return null;
73
+ const key = p.slice(0, eq);
74
+ const value = p.slice(eq + 1);
75
+ if (key === 't') {
76
+ const n = Number(value);
77
+ if (!Number.isFinite(n))
78
+ return null;
79
+ timestamp = n;
80
+ }
81
+ else if (key === 'v1') {
82
+ if (!/^[0-9a-f]+$/i.test(value))
83
+ return null;
84
+ v1.push(value);
85
+ }
86
+ // ignore unknown keys forward-compat
87
+ }
88
+ if (timestamp === null || v1.length === 0)
89
+ return null;
90
+ return { timestamp, v1 };
91
+ }
92
+ function constantTimeHexEqual(a, b) {
93
+ if (a.length !== b.length)
94
+ return false;
95
+ const ab = Buffer.from(a, 'hex');
96
+ const bb = Buffer.from(b, 'hex');
97
+ if (ab.length !== bb.length || ab.length === 0)
98
+ return false;
99
+ return timingSafeEqual(ab, bb);
100
+ }
101
+ // ── idempotency cache ──────────────────────────────────────────────────
102
+ /**
103
+ * Bounded FIFO event-id deduper. The first call with a given id returns
104
+ * true; subsequent calls return false until the id falls out of the
105
+ * window.
106
+ *
107
+ * Subscribers MUST dedupe per the spec — the executor's delivery worker
108
+ * retries on non-2xx responses, so a flaky downstream handler will
109
+ * receive the same event-id multiple times.
110
+ */
111
+ export class IdempotencyCache {
112
+ capacity;
113
+ seen = new Set();
114
+ order = [];
115
+ constructor(capacity = DEFAULT_IDEMPOTENCY_CAPACITY) {
116
+ this.capacity = Math.max(16, capacity);
117
+ }
118
+ /** Returns true if `id` is new (and stores it); false if it's a duplicate. */
119
+ markFresh(id) {
120
+ if (this.seen.has(id))
121
+ return false;
122
+ this.seen.add(id);
123
+ this.order.push(id);
124
+ while (this.order.length > this.capacity) {
125
+ const evicted = this.order.shift();
126
+ if (evicted !== undefined)
127
+ this.seen.delete(evicted);
128
+ }
129
+ return true;
130
+ }
131
+ size() {
132
+ return this.seen.size;
133
+ }
134
+ }
135
+ export class PushSecretRegistry {
136
+ entries = new Map();
137
+ register(entry) {
138
+ this.entries.set(entry.configId, entry);
139
+ }
140
+ lookup(configId) {
141
+ return this.entries.get(configId) ?? null;
142
+ }
143
+ unregister(configId) {
144
+ return this.entries.delete(configId);
145
+ }
146
+ /** Test/debug helper. */
147
+ size() {
148
+ return this.entries.size;
149
+ }
150
+ }
151
+ /**
152
+ * One-shot processor: takes a raw webhook request (configId + body +
153
+ * signature header + event-id header), verifies, dedupes, routes.
154
+ *
155
+ * Returns the status code and body the HTTP layer should emit. The HTTP
156
+ * adapter (serve.ts) is responsible for reading the raw body bytes
157
+ * BEFORE any JSON parsing — the signature is computed over raw bytes
158
+ * (whitespace-sensitive).
159
+ */
160
+ export async function handleWebhook(configId, body, signature, eventId, opts) {
161
+ if (!configId) {
162
+ return {
163
+ status: 400,
164
+ body: errorBody('aiwg.webhook_config_missing', 'configId query parameter missing'),
165
+ };
166
+ }
167
+ if (!eventId) {
168
+ return {
169
+ status: 400,
170
+ body: errorBody('aiwg.webhook_event_id_missing', 'event-id header missing'),
171
+ };
172
+ }
173
+ // Verify signature first — never touch the body's contents until the
174
+ // HMAC has been checked.
175
+ const verification = await verifyWebhookSignature(signature, body, configId, {
176
+ lookupSecret: id => {
177
+ const entry = opts.registry.lookup(id);
178
+ return entry ? entry.secret : null;
179
+ },
180
+ ...(opts.toleranceSeconds !== undefined ? { toleranceSeconds: opts.toleranceSeconds } : {}),
181
+ ...(opts.now ? { now: opts.now } : {}),
182
+ });
183
+ if (!verification.ok) {
184
+ return {
185
+ status: verification.code === 'timestamp_skew'
186
+ ? 401
187
+ : verification.code === 'secret_unknown'
188
+ ? 404
189
+ : 401,
190
+ body: errorBody(`aiwg.webhook_${verification.code}`, verification.detail ?? ''),
191
+ };
192
+ }
193
+ // Idempotency check — duplicate event-ids are accepted with 200 but
194
+ // not re-routed. The executor's retry logic depends on a 2xx response
195
+ // to mark delivery complete; failing here would cause infinite retry.
196
+ const fresh = opts.idempotency.markFresh(eventId);
197
+ if (!fresh) {
198
+ return { status: 200, body: { ok: true, deduped: true } };
199
+ }
200
+ // Route the verified payload. Errors thrown here become 500 so the
201
+ // executor will retry — pick the abstraction carefully on the
202
+ // mission-state side.
203
+ const entry = opts.registry.lookup(configId);
204
+ if (!entry) {
205
+ // Edge case: secret was unregistered between verify and route.
206
+ return {
207
+ status: 404,
208
+ body: errorBody('aiwg.webhook_secret_unknown', `configId='${configId}' no longer registered`),
209
+ };
210
+ }
211
+ let parsed;
212
+ try {
213
+ parsed = JSON.parse(body.toString('utf8'));
214
+ }
215
+ catch (e) {
216
+ return {
217
+ status: 400,
218
+ body: errorBody('aiwg.webhook_body_not_json', e.message),
219
+ };
220
+ }
221
+ try {
222
+ await opts.route(entry, parsed);
223
+ }
224
+ catch (e) {
225
+ return {
226
+ status: 500,
227
+ body: errorBody('aiwg.webhook_route_failed', e.message),
228
+ };
229
+ }
230
+ return { status: 200, body: { ok: true } };
231
+ }
232
+ function errorBody(code, detail) {
233
+ return {
234
+ type: 'about:blank',
235
+ title: 'Webhook rejected',
236
+ code,
237
+ detail,
238
+ };
239
+ }
240
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Activity Log CLI — `aiwg activity-log <subcommand>`
3
+ *
4
+ * Subcommands:
5
+ * show [--since DATE] [--operation OP] [--limit N]
6
+ * append <operation> "<summary>"
7
+ * stats
8
+ *
9
+ * Persists through `resolveStorage('activity_log')` per #964 — the
10
+ * physical destination is `.aiwg/activity.log` on the default `fs`
11
+ * backend, byte-identical to the legacy `echo >> .aiwg/activity.log`
12
+ * pattern documented in the activity-log skill.
13
+ *
14
+ * @design @.aiwg/architecture/storage-design.md (§4, §8.2)
15
+ * @issue #934
16
+ * @issue #964
17
+ */
18
+ import { ACTIVITY_OPERATIONS, formatEntry, formatUtcTimestamp, isActivityOperation, } from './types.js';
19
+ import { parseLog, parseUtcDate } from './parser.js';
20
+ import { resolveStorage } from '../storage/index.js';
21
+ const LOG_PATH = 'activity.log';
22
+ const DEFAULT_LIMIT = 20;
23
+ export async function main(args) {
24
+ const subcommand = args[0];
25
+ const subArgs = args.slice(1);
26
+ switch (subcommand) {
27
+ case 'show':
28
+ await handleShow(subArgs);
29
+ break;
30
+ case 'append':
31
+ await handleAppend(subArgs);
32
+ break;
33
+ case 'stats':
34
+ await handleStats();
35
+ break;
36
+ case 'rotate':
37
+ await handleRotate(subArgs);
38
+ break;
39
+ default:
40
+ printUsage();
41
+ if (subcommand) {
42
+ throw new Error(`Unknown activity-log subcommand: ${subcommand}`);
43
+ }
44
+ }
45
+ }
46
+ async function handleShow(args) {
47
+ const opts = parseShowArgs(args);
48
+ const adapter = await resolveStorage('activity_log');
49
+ const entries = await readEntries(adapter);
50
+ let filtered = entries;
51
+ if (opts.since) {
52
+ const since = opts.since;
53
+ filtered = filtered.filter((e) => e.timestamp >= since);
54
+ }
55
+ if (opts.operation) {
56
+ filtered = filtered.filter((e) => e.operation === opts.operation);
57
+ }
58
+ // Newest first
59
+ filtered.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
60
+ if (filtered.length > opts.limit) {
61
+ filtered = filtered.slice(0, opts.limit);
62
+ }
63
+ if (filtered.length === 0) {
64
+ console.log('No activity log entries match the filters.');
65
+ return;
66
+ }
67
+ for (const entry of filtered) {
68
+ console.log(formatEntry(entry));
69
+ }
70
+ }
71
+ async function handleAppend(args) {
72
+ if (args.length < 2) {
73
+ throw new Error(`Usage: aiwg activity-log append <operation> "<summary>"\n` +
74
+ ` Valid operations: ${ACTIVITY_OPERATIONS.join(', ')}`);
75
+ }
76
+ const op = args[0];
77
+ const summary = args.slice(1).join(' ').trim();
78
+ if (!isActivityOperation(op)) {
79
+ throw new Error(`Invalid operation "${op}". Valid operations: ${ACTIVITY_OPERATIONS.join(', ')}`);
80
+ }
81
+ if (summary.length === 0) {
82
+ throw new Error('Summary must be a non-empty string');
83
+ }
84
+ if (summary.length > 120) {
85
+ // Soft limit per the activity-log rule. Warn but don't refuse —
86
+ // the rule says "≤120 characters" but doesn't promise rejection.
87
+ console.warn(`warning: summary is ${summary.length} chars (rule recommends ≤120)`);
88
+ }
89
+ // #975: honor AIWG_SKIP_ACTIVITY_LOG=1 per the activity-log rule.
90
+ if (isActivityLogSkipped()) {
91
+ return;
92
+ }
93
+ const adapter = await resolveStorage('activity_log');
94
+ const newLine = formatEntry({ timestamp: new Date(), operation: op, summary });
95
+ // #976: prefer atomic append when the backend supports it. The fs
96
+ // backend uses fs.appendFile (O_APPEND) so concurrent appenders don't
97
+ // race with each other. Fall back to read-then-write for backends
98
+ // that don't expose append (e.g., Notion, AnythingLLM, Fortemi) —
99
+ // those backends have their own concurrency models anyway.
100
+ if (typeof adapter.append === 'function') {
101
+ // Append guarantees no read-modify-write race. We need to ensure the
102
+ // existing log ends with a newline before our line; do that with a
103
+ // single-byte preamble append when needed.
104
+ const existing = (await adapter.read(LOG_PATH)) ?? '';
105
+ if (existing.length > 0 && !existing.endsWith('\n')) {
106
+ await adapter.append(LOG_PATH, '\n');
107
+ }
108
+ await adapter.append(LOG_PATH, newLine + '\n');
109
+ }
110
+ else {
111
+ const existing = (await adapter.read(LOG_PATH)) ?? '';
112
+ const trailing = existing.length === 0 || existing.endsWith('\n') ? '' : '\n';
113
+ await adapter.write(LOG_PATH, existing + trailing + newLine + '\n');
114
+ }
115
+ console.log(`Entry appended to .aiwg/activity.log:\n ${newLine}`);
116
+ }
117
+ /**
118
+ * Returns true when AIWG_SKIP_ACTIVITY_LOG is set (per the activity-log
119
+ * rule's documented opt-out). Accepts "1", "true" (case-insensitive),
120
+ * or any non-empty value other than "0"/"false".
121
+ */
122
+ function isActivityLogSkipped() {
123
+ const raw = process.env['AIWG_SKIP_ACTIVITY_LOG'];
124
+ if (!raw)
125
+ return false;
126
+ const v = raw.toLowerCase().trim();
127
+ if (v === '0' || v === 'false' || v === '')
128
+ return false;
129
+ return true;
130
+ }
131
+ async function handleStats() {
132
+ const adapter = await resolveStorage('activity_log');
133
+ const entries = await readEntries(adapter);
134
+ if (entries.length === 0) {
135
+ console.log('Activity log is empty.');
136
+ return;
137
+ }
138
+ const counts = new Map();
139
+ for (const op of ACTIVITY_OPERATIONS)
140
+ counts.set(op, 0);
141
+ for (const e of entries)
142
+ counts.set(e.operation, (counts.get(e.operation) ?? 0) + 1);
143
+ const sorted = [...entries].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
144
+ const first = sorted[0].timestamp;
145
+ const last = sorted[sorted.length - 1].timestamp;
146
+ const days = Math.max(1, Math.ceil((last.getTime() - first.getTime()) / 86_400_000) + 1);
147
+ console.log(`Activity Log Statistics`);
148
+ console.log(`Log file: .aiwg/activity.log`);
149
+ console.log(`Date range: ${formatUtcTimestamp(first).slice(0, 10)} → ${formatUtcTimestamp(last).slice(0, 10)} (${days} day${days === 1 ? '' : 's'})`);
150
+ console.log(`Total entries: ${entries.length}`);
151
+ console.log('');
152
+ console.log(`By operation:`);
153
+ // Sort by count desc, then by op name asc for stability
154
+ const ranked = [...counts.entries()]
155
+ .filter(([, n]) => n > 0)
156
+ .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
157
+ const maxCount = ranked[0]?.[1] ?? 1;
158
+ for (const [op, n] of ranked) {
159
+ const pct = Math.round((n / entries.length) * 100);
160
+ const barLen = Math.max(1, Math.round((n / maxCount) * 20));
161
+ const bar = '█'.repeat(barLen);
162
+ console.log(` ${op.padEnd(8)} ${String(n).padStart(3)} ${bar.padEnd(20)} ${pct}%`);
163
+ }
164
+ }
165
+ async function handleRotate(args) {
166
+ const opts = parseRotateArgs(args);
167
+ const adapter = await resolveStorage('activity_log');
168
+ const existing = (await adapter.read(LOG_PATH)) ?? '';
169
+ const entries = parseLog(existing);
170
+ if (entries.length === 0) {
171
+ throw new Error('Nothing to rotate: the activity log is empty (or contains no parseable entries).');
172
+ }
173
+ // Decide what stays inline vs what goes to archive
174
+ const sortedAsc = [...entries].sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
175
+ const { kept, archived } = splitForRotation(sortedAsc, opts.keepLast);
176
+ if (archived.length === 0) {
177
+ throw new Error(`Nothing to archive: --keep-last would retain all ${entries.length} entries inline.`);
178
+ }
179
+ // Determine archive destination (subsystem-relative)
180
+ const stamp = formatArchiveStamp(new Date());
181
+ const archivePath = opts.to ?? `archive/activity-log/${stamp}.log`;
182
+ // Refuse to overwrite an existing archive
183
+ const existingArchive = await adapter.read(archivePath);
184
+ if (existingArchive !== null) {
185
+ throw new Error(`Refusing to overwrite existing archive: ${archivePath}\n` +
186
+ ` Either pass --to <other-path> or remove the existing archive first.`);
187
+ }
188
+ // Write archive (full historical content, oldest-first to match log order)
189
+ const archiveBody = archived.map((e) => formatEntry(e)).join('\n') + '\n';
190
+ await adapter.write(archivePath, archiveBody);
191
+ // Rewrite the live log with the retained tail
192
+ const liveBody = kept.length > 0 ? kept.map((e) => formatEntry(e)).join('\n') + '\n' : '';
193
+ await adapter.write(LOG_PATH, liveBody);
194
+ // Append a rotate-record entry to the live log (also exercises the
195
+ // append path so concurrent-write protection still applies).
196
+ const recordSummary = `activity-log rotated, archived ${archived.length} entries to ${archivePath}`;
197
+ if (typeof adapter.append === 'function') {
198
+ await adapter.append(LOG_PATH, formatEntry({ timestamp: new Date(), operation: 'archive', summary: recordSummary }) + '\n');
199
+ }
200
+ else {
201
+ const live = (await adapter.read(LOG_PATH)) ?? '';
202
+ const trailing = live.length === 0 || live.endsWith('\n') ? '' : '\n';
203
+ await adapter.write(LOG_PATH, live +
204
+ trailing +
205
+ formatEntry({ timestamp: new Date(), operation: 'archive', summary: recordSummary }) +
206
+ '\n');
207
+ }
208
+ console.log(`Rotated activity log:`);
209
+ console.log(` Archived ${archived.length} entr${archived.length === 1 ? 'y' : 'ies'} to ${archivePath}`);
210
+ console.log(` Retained ${kept.length} entr${kept.length === 1 ? 'y' : 'ies'} inline`);
211
+ }
212
+ function parseRotateArgs(args) {
213
+ const opts = {};
214
+ for (let i = 0; i < args.length; i++) {
215
+ const a = args[i];
216
+ if (a === '--keep-last') {
217
+ const v = args[++i];
218
+ if (!v)
219
+ throw new Error(`--keep-last requires a value (e.g., 90d or 1000)`);
220
+ opts.keepLast = parseKeepLast(v);
221
+ }
222
+ else if (a === '--to') {
223
+ const v = args[++i];
224
+ if (!v)
225
+ throw new Error(`--to requires a path`);
226
+ opts.to = v;
227
+ }
228
+ else {
229
+ throw new Error(`Unknown flag: ${a}`);
230
+ }
231
+ }
232
+ return opts;
233
+ }
234
+ function parseKeepLast(raw) {
235
+ const dur = /^(\d+)d$/.exec(raw);
236
+ if (dur)
237
+ return { kind: 'duration_ms', ms: Number(dur[1]) * 86_400_000 };
238
+ const cnt = /^(\d+)$/.exec(raw);
239
+ if (cnt) {
240
+ const n = Number(cnt[1]);
241
+ if (n <= 0)
242
+ throw new Error(`--keep-last count must be positive (got ${raw})`);
243
+ return { kind: 'count', n };
244
+ }
245
+ throw new Error(`--keep-last must be <N>d or <N> (got ${JSON.stringify(raw)})`);
246
+ }
247
+ function splitForRotation(sortedAsc, keepLast) {
248
+ if (!keepLast) {
249
+ return { kept: [], archived: sortedAsc };
250
+ }
251
+ if (keepLast.kind === 'count') {
252
+ if (sortedAsc.length <= keepLast.n) {
253
+ return { kept: [...sortedAsc], archived: [] };
254
+ }
255
+ const cut = sortedAsc.length - keepLast.n;
256
+ return {
257
+ archived: sortedAsc.slice(0, cut),
258
+ kept: sortedAsc.slice(cut),
259
+ };
260
+ }
261
+ // duration_ms
262
+ const cutoff = Date.now() - keepLast.ms;
263
+ const kept = [];
264
+ const archived = [];
265
+ for (const e of sortedAsc) {
266
+ if (e.timestamp.getTime() >= cutoff)
267
+ kept.push(e);
268
+ else
269
+ archived.push(e);
270
+ }
271
+ return { kept, archived };
272
+ }
273
+ function formatArchiveStamp(d) {
274
+ // YYYYMMDD-HHMMSS UTC — sortable, unique to the second
275
+ const y = d.getUTCFullYear();
276
+ const mo = String(d.getUTCMonth() + 1).padStart(2, '0');
277
+ const da = String(d.getUTCDate()).padStart(2, '0');
278
+ const h = String(d.getUTCHours()).padStart(2, '0');
279
+ const mi = String(d.getUTCMinutes()).padStart(2, '0');
280
+ const s = String(d.getUTCSeconds()).padStart(2, '0');
281
+ return `${y}${mo}${da}-${h}${mi}${s}`;
282
+ }
283
+ // ── helpers ──────────────────────────────────────────────────────────
284
+ async function readEntries(adapter) {
285
+ const content = await adapter.read(LOG_PATH);
286
+ if (content === null)
287
+ return [];
288
+ return parseLog(content);
289
+ }
290
+ function parseShowArgs(args) {
291
+ const opts = { limit: DEFAULT_LIMIT };
292
+ for (let i = 0; i < args.length; i++) {
293
+ const a = args[i];
294
+ if (a === '--since') {
295
+ const v = args[++i];
296
+ const d = parseUtcDate(v);
297
+ if (!d)
298
+ throw new Error(`--since must be YYYY-MM-DD (got ${JSON.stringify(v)})`);
299
+ opts.since = d;
300
+ }
301
+ else if (a === '--operation') {
302
+ const v = args[++i];
303
+ if (!isActivityOperation(v)) {
304
+ throw new Error(`--operation must be one of ${ACTIVITY_OPERATIONS.join(', ')} (got ${JSON.stringify(v)})`);
305
+ }
306
+ opts.operation = v;
307
+ }
308
+ else if (a === '--limit') {
309
+ const v = Number(args[++i]);
310
+ if (!Number.isFinite(v) || v <= 0) {
311
+ throw new Error(`--limit must be a positive integer`);
312
+ }
313
+ opts.limit = Math.floor(v);
314
+ }
315
+ else {
316
+ throw new Error(`Unknown flag: ${a}`);
317
+ }
318
+ }
319
+ return opts;
320
+ }
321
+ function printUsage() {
322
+ console.log(`Usage: aiwg activity-log <subcommand>
323
+
324
+ Subcommands:
325
+ show [--since YYYY-MM-DD] [--operation OP] [--limit N]
326
+ append <operation> "<summary>"
327
+ stats
328
+ rotate [--keep-last <Nd|N>] [--to <path>]
329
+
330
+ Operations: ${ACTIVITY_OPERATIONS.join(', ')}
331
+
332
+ Examples:
333
+ aiwg activity-log show
334
+ aiwg activity-log show --since 2026-04-01 --operation deploy
335
+ aiwg activity-log show --limit 5
336
+ aiwg activity-log append create ".aiwg/requirements/UC-007 created"
337
+ aiwg activity-log stats
338
+ aiwg activity-log rotate # archive everything
339
+ aiwg activity-log rotate --keep-last 90d # archive entries older than 90 days
340
+ aiwg activity-log rotate --keep-last 1000 # keep last 1000 entries inline
341
+
342
+ Environment:
343
+ AIWG_SKIP_ACTIVITY_LOG=1 suppress append (per the activity-log rule)
344
+
345
+ The log persists at .aiwg/activity.log on the default fs backend.
346
+ Configure .aiwg/storage.config to route to an external backend (#934).`);
347
+ }
348
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Activity Log Parser
3
+ *
4
+ * Parses `.aiwg/activity.log` lines into structured entries. Lines that
5
+ * don't match the expected format are silently skipped (the log is
6
+ * append-only and may contain malformed entries from older tooling or
7
+ * manual edits).
8
+ *
9
+ * @issue #934
10
+ * @issue #964
11
+ */
12
+ import { isActivityOperation } from './types.js';
13
+ /**
14
+ * Pattern: `## [YYYY-MM-DD HH:MM] <operation> | <summary>`
15
+ *
16
+ * Match groups:
17
+ * 1: full timestamp (`YYYY-MM-DD HH:MM`)
18
+ * 2: operation token
19
+ * 3: summary
20
+ */
21
+ const LINE_PATTERN = /^##\s+\[(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2})\]\s+([a-z]+)\s+\|\s+(.+?)\s*$/;
22
+ /**
23
+ * Parse a single log line. Returns null when the line doesn't match the
24
+ * canonical format or the operation token is unknown.
25
+ */
26
+ export function parseLine(line) {
27
+ const m = LINE_PATTERN.exec(line);
28
+ if (!m)
29
+ return null;
30
+ const [, rawTimestamp, op, summary] = m;
31
+ if (!isActivityOperation(op))
32
+ return null;
33
+ const timestamp = parseUtcTimestamp(rawTimestamp);
34
+ if (!timestamp)
35
+ return null;
36
+ return { timestamp, rawTimestamp, operation: op, summary };
37
+ }
38
+ /**
39
+ * Parse the entire log content into entries. Skips blank lines and
40
+ * lines that don't match the canonical format.
41
+ */
42
+ export function parseLog(content) {
43
+ const out = [];
44
+ for (const line of content.split('\n')) {
45
+ if (line.trim().length === 0)
46
+ continue;
47
+ const entry = parseLine(line);
48
+ if (entry)
49
+ out.push(entry);
50
+ }
51
+ return out;
52
+ }
53
+ /**
54
+ * Parse a `YYYY-MM-DD HH:MM` UTC timestamp into a Date. Returns null on
55
+ * malformed input.
56
+ */
57
+ export function parseUtcTimestamp(raw) {
58
+ const m = /^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2})$/.exec(raw);
59
+ if (!m)
60
+ return null;
61
+ const [, y, mo, d, h, mi] = m;
62
+ const date = new Date(Date.UTC(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), 0));
63
+ if (Number.isNaN(date.getTime()))
64
+ return null;
65
+ return date;
66
+ }
67
+ /**
68
+ * Parse a `YYYY-MM-DD` date (interpreted as UTC midnight). Returns null
69
+ * on malformed input. Used by `--since` filtering.
70
+ */
71
+ export function parseUtcDate(raw) {
72
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw);
73
+ if (!m)
74
+ return null;
75
+ const [, y, mo, d] = m;
76
+ const date = new Date(Date.UTC(Number(y), Number(mo) - 1, Number(d), 0, 0, 0));
77
+ if (Number.isNaN(date.getTime()))
78
+ return null;
79
+ return date;
80
+ }
81
+ //# sourceMappingURL=parser.js.map