@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -1
  3. package/bin/aiwg.mjs +349 -0
  4. package/dist/src/a2a/agent-card.js +145 -0
  5. package/dist/src/a2a/client.js +411 -0
  6. package/dist/src/a2a/hitl-cli.js +171 -0
  7. package/dist/src/a2a/hitl-driver.js +370 -0
  8. package/dist/src/a2a/hitl.js +181 -0
  9. package/dist/src/a2a/http.js +193 -0
  10. package/dist/src/a2a/jcs.js +128 -0
  11. package/dist/src/a2a/jws.js +187 -0
  12. package/dist/src/a2a/types.js +24 -0
  13. package/dist/src/a2a/webhook.js +240 -0
  14. package/dist/src/activity-log/cli.js +348 -0
  15. package/dist/src/activity-log/parser.js +81 -0
  16. package/dist/src/activity-log/types.js +50 -0
  17. package/dist/src/agents/agent-deployer.js +367 -0
  18. package/dist/src/agents/agent-packager.js +271 -0
  19. package/dist/src/agents/agent-validator.js +271 -0
  20. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  21. package/dist/src/agents/grounding/types.js +12 -0
  22. package/dist/src/agents/index.js +10 -0
  23. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  24. package/dist/src/agents/types.js +7 -0
  25. package/dist/src/api/index.d.ts +10 -0
  26. package/dist/src/api/index.js +10 -0
  27. package/dist/src/artifacts/address-parser.js +73 -0
  28. package/dist/src/artifacts/audit/cli.js +183 -0
  29. package/dist/src/artifacts/audit/drift.js +122 -0
  30. package/dist/src/artifacts/audit/types.js +12 -0
  31. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  32. package/dist/src/artifacts/backends/json-backend.js +129 -0
  33. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  34. package/dist/src/artifacts/browser-export.js +622 -0
  35. package/dist/src/artifacts/capability-resolver.js +94 -0
  36. package/dist/src/artifacts/checksum-manifest.js +91 -0
  37. package/dist/src/artifacts/citation-parser.js +162 -0
  38. package/dist/src/artifacts/cli.js +1486 -0
  39. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  40. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  41. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  42. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  43. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  44. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  45. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  46. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  47. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  48. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  49. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  51. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  52. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  53. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  54. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  55. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  56. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  57. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  58. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  60. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  61. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  62. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  63. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  64. package/dist/src/artifacts/corpus-views/build.js +126 -0
  65. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  66. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  67. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  68. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  69. package/dist/src/artifacts/dep-graph.js +173 -0
  70. package/dist/src/artifacts/discover-facets.js +375 -0
  71. package/dist/src/artifacts/embedding-index.js +354 -0
  72. package/dist/src/artifacts/enrichment/cli.js +240 -0
  73. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  74. package/dist/src/artifacts/enrichment/store.js +90 -0
  75. package/dist/src/artifacts/enrichment/types.js +12 -0
  76. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  77. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  78. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  79. package/dist/src/artifacts/fulltext.js +108 -0
  80. package/dist/src/artifacts/graph-backend.js +51 -0
  81. package/dist/src/artifacts/graph-query.js +247 -0
  82. package/dist/src/artifacts/hybrid-query.js +225 -0
  83. package/dist/src/artifacts/index-builder.js +1089 -0
  84. package/dist/src/artifacts/index-reader.js +112 -0
  85. package/dist/src/artifacts/index-status.js +193 -0
  86. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  87. package/dist/src/artifacts/move.js +154 -0
  88. package/dist/src/artifacts/operational-state.js +239 -0
  89. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  90. package/dist/src/artifacts/query-engine.js +1955 -0
  91. package/dist/src/artifacts/source-graph.js +529 -0
  92. package/dist/src/artifacts/stats.js +169 -0
  93. package/dist/src/artifacts/types.js +606 -0
  94. package/dist/src/artifacts/views/cli.js +293 -0
  95. package/dist/src/artifacts/views/definition.js +170 -0
  96. package/dist/src/artifacts/views/store.js +149 -0
  97. package/dist/src/artifacts/views/types.js +8 -0
  98. package/dist/src/artifacts/watcher.js +255 -0
  99. package/dist/src/catalog/builtin-models.json +636 -0
  100. package/dist/src/catalog/cli.js +228 -0
  101. package/dist/src/catalog/cli.mjs +289 -0
  102. package/dist/src/catalog/index.js +15 -0
  103. package/dist/src/catalog/loader.js +217 -0
  104. package/dist/src/catalog/loader.mjs +251 -0
  105. package/dist/src/catalog/sources.json +41 -0
  106. package/dist/src/catalog/types.js +8 -0
  107. package/dist/src/channel/manager.mjs +504 -0
  108. package/dist/src/cli/agent-spawn.js +178 -0
  109. package/dist/src/cli/cli-extension-loader.js +245 -0
  110. package/dist/src/cli/command-log.js +275 -0
  111. package/dist/src/cli/config-loader.js +232 -0
  112. package/dist/src/cli/env.js +82 -0
  113. package/dist/src/cli/errors.js +150 -0
  114. package/dist/src/cli/find-package-root.js +40 -0
  115. package/dist/src/cli/git-hooks.js +250 -0
  116. package/dist/src/cli/handlers/agentcard.js +206 -0
  117. package/dist/src/cli/handlers/artifacts.js +76 -0
  118. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  119. package/dist/src/cli/handlers/cockpit.js +137 -0
  120. package/dist/src/cli/handlers/command-log.js +37 -0
  121. package/dist/src/cli/handlers/daemon.js +59 -0
  122. package/dist/src/cli/handlers/diagnose.js +300 -0
  123. package/dist/src/cli/handlers/execution-mode.js +105 -0
  124. package/dist/src/cli/handlers/feedback.js +341 -0
  125. package/dist/src/cli/handlers/help.js +147 -0
  126. package/dist/src/cli/handlers/index.js +302 -0
  127. package/dist/src/cli/handlers/init.js +179 -0
  128. package/dist/src/cli/handlers/install.js +129 -0
  129. package/dist/src/cli/handlers/issues.js +46 -0
  130. package/dist/src/cli/handlers/lint.js +42 -0
  131. package/dist/src/cli/handlers/local-executor.js +315 -0
  132. package/dist/src/cli/handlers/marketplace.js +168 -0
  133. package/dist/src/cli/handlers/mc.js +1010 -0
  134. package/dist/src/cli/handlers/models.js +352 -0
  135. package/dist/src/cli/handlers/packages.js +155 -0
  136. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  137. package/dist/src/cli/handlers/ralph.js +575 -0
  138. package/dist/src/cli/handlers/refresh.js +432 -0
  139. package/dist/src/cli/handlers/regenerate.js +336 -0
  140. package/dist/src/cli/handlers/repo-access.js +109 -0
  141. package/dist/src/cli/handlers/run.js +165 -0
  142. package/dist/src/cli/handlers/runtime-info.js +301 -0
  143. package/dist/src/cli/handlers/sandbox.js +197 -0
  144. package/dist/src/cli/handlers/scaffolding.js +149 -0
  145. package/dist/src/cli/handlers/script-runner.js +121 -0
  146. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  147. package/dist/src/cli/handlers/serve.js +1835 -0
  148. package/dist/src/cli/handlers/session.js +348 -0
  149. package/dist/src/cli/handlers/setup.js +440 -0
  150. package/dist/src/cli/handlers/skill-lint.js +367 -0
  151. package/dist/src/cli/handlers/skill-usage.js +74 -0
  152. package/dist/src/cli/handlers/steward.js +567 -0
  153. package/dist/src/cli/handlers/subcommands.js +1702 -0
  154. package/dist/src/cli/handlers/team.js +337 -0
  155. package/dist/src/cli/handlers/types.js +11 -0
  156. package/dist/src/cli/handlers/use.js +2772 -0
  157. package/dist/src/cli/handlers/utilities.js +703 -0
  158. package/dist/src/cli/handlers/version.js +134 -0
  159. package/dist/src/cli/handlers/workspace-context.js +93 -0
  160. package/dist/src/cli/handlers/workspace.js +126 -0
  161. package/dist/src/cli/help-generator.js +178 -0
  162. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  163. package/dist/src/cli/hooks/executor.js +96 -0
  164. package/dist/src/cli/hooks/index.js +15 -0
  165. package/dist/src/cli/hooks/registry.js +143 -0
  166. package/dist/src/cli/hooks/types.js +13 -0
  167. package/dist/src/cli/log.js +492 -0
  168. package/dist/src/cli/project-isolation/detect.js +70 -0
  169. package/dist/src/cli/project-isolation/index.js +7 -0
  170. package/dist/src/cli/project-isolation/signals.js +17 -0
  171. package/dist/src/cli/project-isolation/warning.js +102 -0
  172. package/dist/src/cli/prompt-utils.js +155 -0
  173. package/dist/src/cli/provider-deployment-plan.js +126 -0
  174. package/dist/src/cli/provider-resolution.js +119 -0
  175. package/dist/src/cli/router.js +305 -0
  176. package/dist/src/cli/scope-resolver.js +392 -0
  177. package/dist/src/cli/skill-usage.js +616 -0
  178. package/dist/src/cli/ui.js +224 -0
  179. package/dist/src/cli/watch-service.js +203 -0
  180. package/dist/src/cli/workflow-orchestrator.js +478 -0
  181. package/dist/src/cli/workspace-signals.js +321 -0
  182. package/dist/src/community/footer.js +14 -0
  183. package/dist/src/community/links.js +123 -0
  184. package/dist/src/community/milestones.js +46 -0
  185. package/dist/src/community/nudge-policy.js +93 -0
  186. package/dist/src/config/aiwg-config.js +883 -0
  187. package/dist/src/config/cli.js +703 -0
  188. package/dist/src/config/gitignore.js +156 -0
  189. package/dist/src/config/project-artifacts.js +76 -0
  190. package/dist/src/config/user-config.js +428 -0
  191. package/dist/src/config/user-registry.js +127 -0
  192. package/dist/src/config/workspace.js +276 -0
  193. package/dist/src/contributors/detect.js +39 -0
  194. package/dist/src/contributors/discover.js +172 -0
  195. package/dist/src/contributors/heuristic.js +186 -0
  196. package/dist/src/contributors/index.js +11 -0
  197. package/dist/src/contributors/types.js +13 -0
  198. package/dist/src/contributors/validation.js +116 -0
  199. package/dist/src/data/community.schema.json +43 -0
  200. package/dist/src/data/community.yaml +16 -0
  201. package/dist/src/extensions/capability-index.js +270 -0
  202. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  203. package/dist/src/extensions/commands/definitions.js +3485 -0
  204. package/dist/src/extensions/deployment-registration.js +463 -0
  205. package/dist/src/extensions/index.js +22 -0
  206. package/dist/src/extensions/loader.js +132 -0
  207. package/dist/src/extensions/managed-marker.js +100 -0
  208. package/dist/src/extensions/manifest.js +196 -0
  209. package/dist/src/extensions/project-local-activity.js +114 -0
  210. package/dist/src/extensions/project-local-discovery.js +261 -0
  211. package/dist/src/extensions/project-local-doctor.js +281 -0
  212. package/dist/src/extensions/project-local-gitignore.js +176 -0
  213. package/dist/src/extensions/project-local-paths.js +121 -0
  214. package/dist/src/extensions/project-local-promote.js +218 -0
  215. package/dist/src/extensions/project-local-remove.js +373 -0
  216. package/dist/src/extensions/project-local-scaffold.js +252 -0
  217. package/dist/src/extensions/project-quickref.js +291 -0
  218. package/dist/src/extensions/registry.js +368 -0
  219. package/dist/src/extensions/shadow-resolver.js +271 -0
  220. package/dist/src/extensions/types.js +86 -0
  221. package/dist/src/extensions/upstream-registry.js +195 -0
  222. package/dist/src/extensions/validation.js +631 -0
  223. package/dist/src/features/catalog.js +88 -0
  224. package/dist/src/features/cli.js +197 -0
  225. package/dist/src/features/installer.js +57 -0
  226. package/dist/src/features/paths.js +14 -0
  227. package/dist/src/features/runtime.js +21 -0
  228. package/dist/src/features/status.js +134 -0
  229. package/dist/src/hooks/laziness-detection.js +532 -0
  230. package/dist/src/intake/git-history-analyzer.js +486 -0
  231. package/dist/src/intake/index.js +9 -0
  232. package/dist/src/issues/cli.js +327 -0
  233. package/dist/src/issues/index.js +5 -0
  234. package/dist/src/issues/live.js +154 -0
  235. package/dist/src/issues/local.js +666 -0
  236. package/dist/src/issues/sync.js +143 -0
  237. package/dist/src/issues/types.js +2 -0
  238. package/dist/src/issues/workflows.js +164 -0
  239. package/dist/src/kb/cli.js +173 -0
  240. package/dist/src/lint/cli.js +171 -0
  241. package/dist/src/lint/loader.js +225 -0
  242. package/dist/src/lint/reporters.js +141 -0
  243. package/dist/src/lint/runner.js +364 -0
  244. package/dist/src/lint/types.js +10 -0
  245. package/dist/src/marketplace/cache.js +110 -0
  246. package/dist/src/marketplace/identifier.js +63 -0
  247. package/dist/src/marketplace/registry.js +36 -0
  248. package/dist/src/marketplace/sources/clawhub.js +53 -0
  249. package/dist/src/marketplace/sources/git.js +45 -0
  250. package/dist/src/marketplace/types.js +9 -0
  251. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  252. package/dist/src/mcp/cli.mjs +1197 -0
  253. package/dist/src/mcp/elicitation.mjs +149 -0
  254. package/dist/src/mcp/helpers.mjs +287 -0
  255. package/dist/src/mcp/index.mjs +11 -0
  256. package/dist/src/mcp/profiles.js +263 -0
  257. package/dist/src/mcp/profiles.mjs +360 -0
  258. package/dist/src/mcp/registry.js +376 -0
  259. package/dist/src/mcp/registry.mjs +387 -0
  260. package/dist/src/mcp/server.mjs +633 -0
  261. package/dist/src/mcp/test-simple.mjs +271 -0
  262. package/dist/src/mcp/tools/command-run.mjs +101 -0
  263. package/dist/src/mcp/tools/discovery.mjs +291 -0
  264. package/dist/src/mcp/tools/interaction.mjs +87 -0
  265. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  266. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  267. package/dist/src/memory/cli.js +166 -0
  268. package/dist/src/memory/project-registry.js +282 -0
  269. package/dist/src/metrics/artifact-metrics.js +184 -0
  270. package/dist/src/metrics/context-budget.js +174 -0
  271. package/dist/src/metrics/token-counter.js +133 -0
  272. package/dist/src/models/config-loader.js +228 -0
  273. package/dist/src/models/index.js +22 -0
  274. package/dist/src/models/model-capabilities.v1.json +120 -0
  275. package/dist/src/models/model-catalog.v1.json +96 -0
  276. package/dist/src/models/model-discovery.js +521 -0
  277. package/dist/src/models/provider-models.js +73 -0
  278. package/dist/src/models/provider-policy.js +273 -0
  279. package/dist/src/models/resolver.js +245 -0
  280. package/dist/src/models/router.js +70 -0
  281. package/dist/src/models/types.js +8 -0
  282. package/dist/src/models/wrapper-deployment.js +178 -0
  283. package/dist/src/models/wrapper-route.js +54 -0
  284. package/dist/src/ops/cli.js +268 -0
  285. package/dist/src/ops/registry.js +623 -0
  286. package/dist/src/packages/adapters/clawhub.js +113 -0
  287. package/dist/src/packages/adapters/git.js +153 -0
  288. package/dist/src/packages/adapters/gitea.js +93 -0
  289. package/dist/src/packages/adapters/github.js +69 -0
  290. package/dist/src/packages/adapters/local-cache.js +89 -0
  291. package/dist/src/packages/package-registry.js +143 -0
  292. package/dist/src/packages/registry.js +238 -0
  293. package/dist/src/packages/types.js +11 -0
  294. package/dist/src/plugin/cross-framework-ops.js +475 -0
  295. package/dist/src/plugin/framework-config-loader.js +235 -0
  296. package/dist/src/plugin/framework-detector.js +186 -0
  297. package/dist/src/plugin/framework-isolator.js +341 -0
  298. package/dist/src/plugin/framework-migration.js +371 -0
  299. package/dist/src/plugin/metadata-validator.js +906 -0
  300. package/dist/src/plugin/plugin-installer.js +436 -0
  301. package/dist/src/plugin/plugin-status.js +369 -0
  302. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  303. package/dist/src/plugin/registry-validator.js +344 -0
  304. package/dist/src/plugin/skill-command-translator.js +415 -0
  305. package/dist/src/plugin/workspace-creator.js +189 -0
  306. package/dist/src/plugin/workspace-migrator.js +821 -0
  307. package/dist/src/policy/authorization.js +390 -0
  308. package/dist/src/policy/repo-access.js +215 -0
  309. package/dist/src/provenance/cli.js +16 -0
  310. package/dist/src/providers/capability-matrix.js +300 -0
  311. package/dist/src/providers/capability-matrix.yaml +514 -0
  312. package/dist/src/providers/provider-definitions.js +977 -0
  313. package/dist/src/providers/provider-definitions.mjs +159 -0
  314. package/dist/src/providers/provider-inventory.js +169 -0
  315. package/dist/src/quality/feedback-ab.js +174 -0
  316. package/dist/src/quality/feedback-collector.js +176 -0
  317. package/dist/src/quality/feedback-tracker.js +123 -0
  318. package/dist/src/quality/patterns/adr.json +24 -0
  319. package/dist/src/quality/patterns/sad.json +24 -0
  320. package/dist/src/quality/patterns/test-plan.json +24 -0
  321. package/dist/src/quality/patterns/use-case.json +24 -0
  322. package/dist/src/quality/scoring.js +157 -0
  323. package/dist/src/reflections/cli.js +15 -0
  324. package/dist/src/release/plan.js +139 -0
  325. package/dist/src/research/cache/manager.js +227 -0
  326. package/dist/src/research/clients/arxiv.js +156 -0
  327. package/dist/src/research/clients/base.js +197 -0
  328. package/dist/src/research/clients/crossref.js +112 -0
  329. package/dist/src/research/clients/semantic-scholar.js +126 -0
  330. package/dist/src/research/clients/unpaywall.js +87 -0
  331. package/dist/src/research/index.js +14 -0
  332. package/dist/src/research/query-cli.js +336 -0
  333. package/dist/src/research/services/acquisition.js +313 -0
  334. package/dist/src/research/services/archival.js +225 -0
  335. package/dist/src/research/services/citation.js +279 -0
  336. package/dist/src/research/services/discovery.js +243 -0
  337. package/dist/src/research/services/documentation.js +269 -0
  338. package/dist/src/research/services/index.js +14 -0
  339. package/dist/src/research/services/provenance.js +279 -0
  340. package/dist/src/research/services/quality.js +370 -0
  341. package/dist/src/research/services/types.js +7 -0
  342. package/dist/src/research/storage-cli.js +20 -0
  343. package/dist/src/research/types.js +47 -0
  344. package/dist/src/resources/index.d.ts +2 -0
  345. package/dist/src/resources/index.js +2 -0
  346. package/dist/src/resources/web-release.d.ts +89 -0
  347. package/dist/src/resources/web-release.js +886 -0
  348. package/dist/src/rlm/cache/cli.js +162 -0
  349. package/dist/src/rlm/cache/hash.js +35 -0
  350. package/dist/src/rlm/cache/store.js +170 -0
  351. package/dist/src/rlm/cache/types.js +8 -0
  352. package/dist/src/rlm/cli.js +650 -0
  353. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  354. package/dist/src/serve/agent-router.js +205 -0
  355. package/dist/src/serve/dispatch-router.js +171 -0
  356. package/dist/src/serve/executor-registry.js +715 -0
  357. package/dist/src/serve/mission-conductor.js +177 -0
  358. package/dist/src/serve/orchestrator-adapter.js +113 -0
  359. package/dist/src/serve/orchestrator-override.js +94 -0
  360. package/dist/src/serve/orchestrator-pty.js +133 -0
  361. package/dist/src/serve/pty-bridge.js +799 -0
  362. package/dist/src/serve/sandbox-registry.js +832 -0
  363. package/dist/src/serve/screen-reader.js +228 -0
  364. package/dist/src/serve/stack-adapters.js +68 -0
  365. package/dist/src/serve/telemetry.js +143 -0
  366. package/dist/src/skills/adapters/clawhub.js +250 -0
  367. package/dist/src/skills/adapters/local.js +335 -0
  368. package/dist/src/skills/adapters/openclaw.js +316 -0
  369. package/dist/src/skills/cli.js +334 -0
  370. package/dist/src/skills/registry.js +117 -0
  371. package/dist/src/skills/run.js +259 -0
  372. package/dist/src/skills/runtime.js +94 -0
  373. package/dist/src/skills/types.js +10 -0
  374. package/dist/src/smiths/agentsmith/demo.js +116 -0
  375. package/dist/src/smiths/agentsmith/examples.js +300 -0
  376. package/dist/src/smiths/agentsmith/generator.js +503 -0
  377. package/dist/src/smiths/agentsmith/index.js +11 -0
  378. package/dist/src/smiths/agentsmith/types.js +8 -0
  379. package/dist/src/smiths/commandsmith/example.js +220 -0
  380. package/dist/src/smiths/commandsmith/generator.js +288 -0
  381. package/dist/src/smiths/commandsmith/index.js +41 -0
  382. package/dist/src/smiths/commandsmith/templates.js +296 -0
  383. package/dist/src/smiths/commandsmith/types.js +7 -0
  384. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  385. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  386. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  387. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  388. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  389. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  390. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  391. package/dist/src/smiths/context-pipeline/index.js +30 -0
  392. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  393. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  394. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  395. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  396. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  397. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  398. package/dist/src/smiths/context-pipeline/types.js +23 -0
  399. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  400. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  401. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  402. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  403. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  404. package/dist/src/smiths/hook-bridge/index.js +79 -0
  405. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  406. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  407. package/dist/src/smiths/hook-bridge/types.js +31 -0
  408. package/dist/src/smiths/index.js +39 -0
  409. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  410. package/dist/src/smiths/mcpsmith/example.js +119 -0
  411. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  412. package/dist/src/smiths/mcpsmith/index.js +17 -0
  413. package/dist/src/smiths/mcpsmith/types.js +10 -0
  414. package/dist/src/smiths/platform-paths.js +101 -0
  415. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  416. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  417. package/dist/src/smiths/skillsmith/demo.js +83 -0
  418. package/dist/src/smiths/skillsmith/examples.js +161 -0
  419. package/dist/src/smiths/skillsmith/generator.js +316 -0
  420. package/dist/src/smiths/skillsmith/index.js +12 -0
  421. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  422. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  423. package/dist/src/smiths/skillsmith/types.js +9 -0
  424. package/dist/src/smiths/toolsmith/index.js +10 -0
  425. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  426. package/dist/src/smiths/toolsmith/types.js +8 -0
  427. package/dist/src/storage/backends/fortemi.js +227 -0
  428. package/dist/src/storage/backends/fs.js +134 -0
  429. package/dist/src/storage/backends/logseq.js +309 -0
  430. package/dist/src/storage/backends/obsidian.js +233 -0
  431. package/dist/src/storage/cli.js +468 -0
  432. package/dist/src/storage/config.js +272 -0
  433. package/dist/src/storage/index.js +108 -0
  434. package/dist/src/storage/subsystem-cli.js +201 -0
  435. package/dist/src/storage/types.js +33 -0
  436. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  437. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  438. package/dist/src/testing/corpus/index.js +10 -0
  439. package/dist/src/testing/fixtures/index.js +9 -0
  440. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  441. package/dist/src/testing/generators/index.js +11 -0
  442. package/dist/src/testing/generators/test-case-generator.js +393 -0
  443. package/dist/src/testing/generators/test-code-generator.js +384 -0
  444. package/dist/src/testing/generators/use-case-parser.js +325 -0
  445. package/dist/src/testing/index.js +11 -0
  446. package/dist/src/tracker/capability-protocol.js +118 -0
  447. package/dist/src/update/checker.mjs +396 -0
  448. package/dist/src/update/notifier.mjs +235 -0
  449. package/dist/src/writing/content-diversifier.js +804 -0
  450. package/dist/src/writing/example-generator.js +959 -0
  451. package/dist/src/writing/example-templates.js +99 -0
  452. package/dist/src/writing/pattern-library.js +486 -0
  453. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  454. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  455. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  456. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  457. package/dist/src/writing/patterns/transition-words.json +1285 -0
  458. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  459. package/dist/src/writing/prompt-optimizer.js +660 -0
  460. package/dist/src/writing/prompt-templates.js +583 -0
  461. package/dist/src/writing/scoring-config-loader.js +168 -0
  462. package/dist/src/writing/validation-engine.js +595 -0
  463. package/dist/src/writing/validation-rules.js +380 -0
  464. package/dist/src/writing/voice-analyzer.js +439 -0
  465. package/dist/src/writing/voice-calibration.js +661 -0
  466. package/dist/src/writing/voice-profiles.json +588 -0
  467. package/package.json +65 -9
@@ -0,0 +1,623 @@
1
+ /**
2
+ * Ops Workspace Registry
3
+ *
4
+ * Manages the ops.yaml file in the user config directory.
5
+ * Tracks workspace definitions, repo locations, and cross-repo wiring.
6
+ *
7
+ * @implements #544
8
+ */
9
+ import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
10
+ import { resolve, dirname, basename, sep } from 'path';
11
+ import { homedir } from 'os';
12
+ import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
13
+ import { execSync } from 'child_process';
14
+ import { resolveConfigDir } from '../config/user-config.js';
15
+ import { resolveWorkspace } from '../config/workspace.js';
16
+ import { projectAiwgPath } from '../config/project-artifacts.js';
17
+ /**
18
+ * Extension type abbreviations
19
+ */
20
+ const EXTENSION_NAMES = {
21
+ sys: 'sysops',
22
+ it: 'itops',
23
+ dev: 'devops',
24
+ stream: 'streamops',
25
+ };
26
+ /**
27
+ * Adapt an existing ops workspace to the canonical general workspace shape.
28
+ *
29
+ * The adapter is intentionally side-effect free: `.aiwg/aiwg.config` is the
30
+ * canonical persisted manifest, while the user-level ops registry remains a
31
+ * specialization/compatibility source rather than a second authorization
32
+ * format.
33
+ *
34
+ * @implements #1764
35
+ */
36
+ export function opsWorkspaceToWorkspaceConfig(name, workspace, allowed = ['read', 'write', 'commit', 'push', 'issue-comment']) {
37
+ return {
38
+ workspace: {
39
+ name,
40
+ root: workspace.home,
41
+ },
42
+ repos: Object.entries(workspace.repos).map(([repoName, repo]) => ({
43
+ name: repoName,
44
+ path: repo.path,
45
+ allowed: [...allowed],
46
+ })),
47
+ };
48
+ }
49
+ /**
50
+ * Default empty registry
51
+ */
52
+ const DEFAULT_REGISTRY = {
53
+ apiVersion: 'aiwg.io/v1',
54
+ kind: 'OpsRegistry',
55
+ defaultWorkspace: 'default',
56
+ workspaces: {},
57
+ };
58
+ /**
59
+ * Ops workspace registry manager
60
+ */
61
+ export class OpsRegistry {
62
+ configDir;
63
+ registryPath;
64
+ constructor(configDirOverride) {
65
+ this.configDir = resolveConfigDir(configDirOverride);
66
+ this.registryPath = resolve(this.configDir, 'ops.json');
67
+ }
68
+ /**
69
+ * Load the ops registry, creating defaults if missing
70
+ */
71
+ async load() {
72
+ if (!existsSync(this.registryPath)) {
73
+ return { ...DEFAULT_REGISTRY, workspaces: {} };
74
+ }
75
+ try {
76
+ const content = await readFile(this.registryPath, 'utf-8');
77
+ const parsed = JSON.parse(content);
78
+ return {
79
+ ...DEFAULT_REGISTRY,
80
+ ...parsed,
81
+ workspaces: parsed.workspaces ? { ...parsed.workspaces } : {},
82
+ };
83
+ }
84
+ catch {
85
+ return { ...DEFAULT_REGISTRY, workspaces: {} };
86
+ }
87
+ }
88
+ /**
89
+ * Save the ops registry
90
+ */
91
+ async save(data) {
92
+ await mkdir(this.configDir, { recursive: true });
93
+ await writeFile(this.registryPath, JSON.stringify(data, null, 2), 'utf-8');
94
+ }
95
+ /**
96
+ * Initialize a new ops workspace
97
+ */
98
+ async initWorkspace(opts) {
99
+ const data = await this.load();
100
+ // Check for existing workspace
101
+ if (data.workspaces[opts.name]) {
102
+ throw new Error(`Workspace "${opts.name}" already exists. Use a different name or remove the existing workspace.`);
103
+ }
104
+ // Resolve home directory
105
+ const opsHome = opts.home || resolve(homedir(), 'ops', opts.name);
106
+ // Refuse to create nested ops workspaces — walk up from the parent of
107
+ // opsHome looking for OpsInventory.yaml. Sibling layout is required.
108
+ const enclosing = findEnclosingOpsWorkspace(opsHome);
109
+ if (enclosing) {
110
+ const suggested = resolve(dirname(enclosing), opts.name);
111
+ throw new Error(`${enclosing} is already an ops workspace.\n` +
112
+ `Ops workspaces must be siblings of one another, not nested.\n` +
113
+ `Suggested location: ${suggested}`);
114
+ }
115
+ // Build workspace
116
+ const workspace = {
117
+ home: opsHome,
118
+ mode: opts.mode,
119
+ repos: {},
120
+ };
121
+ if (opts.from && opts.mode === 'multi-repo' && opts.extensions.length > 1) {
122
+ throw new Error('--from <url> requires single-repo mode or exactly one extension. ' +
123
+ 'Use --mode single-repo, or pass --ext with a single value.');
124
+ }
125
+ if (opts.mode === 'multi-repo') {
126
+ // Create separate repo for each extension
127
+ for (const ext of opts.extensions) {
128
+ const fullName = EXTENSION_NAMES[ext] || ext;
129
+ const repoName = opts.prefix ? `${opts.prefix}-${fullName}` : fullName;
130
+ const repoPath = resolve(opsHome, repoName);
131
+ const provisioned = await provisionRepo(repoPath, opts.from, !!opts.silent);
132
+ workspace.repos[repoName] = {
133
+ path: repoPath,
134
+ remote: provisioned.remote,
135
+ extensions: [ext],
136
+ };
137
+ // Seed OpsInventory stub (only if missing — never overwrite)
138
+ await seedInventory(repoPath, repoName, ext);
139
+ if (!opts.silent)
140
+ console.log(` ${provisioned.action} ${repoName} at ${repoPath}`);
141
+ }
142
+ }
143
+ else {
144
+ // Single-repo mode: one repo, subdirectories per domain
145
+ const repoName = opts.prefix ? `${opts.prefix}-ops` : 'ops';
146
+ const repoPath = resolve(opsHome, repoName);
147
+ const provisioned = await provisionRepo(repoPath, opts.from, !!opts.silent);
148
+ // Create subdirectories for each extension
149
+ for (const ext of opts.extensions) {
150
+ const fullName = EXTENSION_NAMES[ext] || ext;
151
+ const subDir = resolve(repoPath, fullName);
152
+ await mkdir(subDir, { recursive: true });
153
+ await seedInventory(subDir, fullName, ext);
154
+ }
155
+ workspace.repos[repoName] = {
156
+ path: repoPath,
157
+ remote: provisioned.remote,
158
+ extensions: opts.extensions,
159
+ };
160
+ if (!opts.silent)
161
+ console.log(` ${provisioned.action} ${repoName} at ${repoPath}`);
162
+ }
163
+ // Register workspace
164
+ data.workspaces[opts.name] = workspace;
165
+ if (Object.keys(data.workspaces).length === 1) {
166
+ data.defaultWorkspace = opts.name;
167
+ }
168
+ await this.save(data);
169
+ // Post-init summary
170
+ console.log('');
171
+ console.log(`Workspace "${opts.name}" initialized`);
172
+ console.log(` Mode: ${opts.mode}`);
173
+ console.log(` Home: ${opsHome}`);
174
+ console.log(` Extensions: ${opts.extensions.join(', ')}`);
175
+ console.log(` Repos: ${Object.keys(workspace.repos).join(', ')}`);
176
+ console.log(` Registry: ${this.registryPath}`);
177
+ if (opts.provider) {
178
+ console.log('');
179
+ console.log(`Remote push to ${opts.provider} requested — use 'aiwg ops push' to push repos.`);
180
+ }
181
+ }
182
+ /**
183
+ * Show workspace status
184
+ */
185
+ async showStatus(showAll) {
186
+ const data = await this.load();
187
+ if (Object.keys(data.workspaces).length === 0) {
188
+ console.log('No ops workspaces registered.');
189
+ console.log('Run "aiwg ops init" to create one.');
190
+ return;
191
+ }
192
+ const workspaces = showAll
193
+ ? Object.entries(data.workspaces)
194
+ : [[data.defaultWorkspace, data.workspaces[data.defaultWorkspace]]].filter(([, ws]) => ws !== undefined);
195
+ for (const [name, ws] of workspaces) {
196
+ const workspace = ws;
197
+ const isDefault = name === data.defaultWorkspace;
198
+ console.log(`${isDefault ? '* ' : ' '}${name} (${workspace.mode})`);
199
+ console.log(` Home: ${workspace.home}`);
200
+ for (const [repoName, repo] of Object.entries(workspace.repos)) {
201
+ const exists = existsSync(repo.path);
202
+ const hasGit = exists && existsSync(resolve(repo.path, '.git'));
203
+ const status = !exists ? 'MISSING' : !hasGit ? 'NO GIT' : 'OK';
204
+ console.log(` ${repoName}: ${status} — ${repo.path}`);
205
+ }
206
+ console.log('');
207
+ }
208
+ }
209
+ /**
210
+ * Switch active workspace
211
+ */
212
+ async switchWorkspace(name) {
213
+ const data = await this.load();
214
+ if (!data.workspaces[name]) {
215
+ const available = Object.keys(data.workspaces).join(', ') || '(none)';
216
+ throw new Error(`Workspace "${name}" not found. Available: ${available}`);
217
+ }
218
+ data.defaultWorkspace = name;
219
+ await this.save(data);
220
+ console.log(`Active workspace: ${name}`);
221
+ }
222
+ /**
223
+ * List all registered workspaces
224
+ */
225
+ async listWorkspaces() {
226
+ const data = await this.load();
227
+ if (Object.keys(data.workspaces).length === 0) {
228
+ console.log('No ops workspaces registered.');
229
+ return;
230
+ }
231
+ console.log('Registered workspaces:\n');
232
+ for (const [name, ws] of Object.entries(data.workspaces)) {
233
+ const isDefault = name === data.defaultWorkspace;
234
+ const repoCount = Object.keys(ws.repos).length;
235
+ console.log(` ${isDefault ? '*' : ' '} ${name} — ${ws.mode}, ${repoCount} repo(s), ${ws.home}`);
236
+ }
237
+ }
238
+ /**
239
+ * Adopt an existing local clone as a repo entry under a workspace.
240
+ *
241
+ * Detects the git remote, seeds OpsInventory.yaml only if missing
242
+ * (never overwrites an existing inventory), and registers the repo.
243
+ * Refuses to register a path nested inside another registered repo.
244
+ */
245
+ async adoptRepo(repoPath, opts = {}) {
246
+ const absPath = resolve(repoPath);
247
+ if (!existsSync(absPath)) {
248
+ throw new Error(`Path does not exist: ${absPath}`);
249
+ }
250
+ if (!statSync(absPath).isDirectory()) {
251
+ throw new Error(`Path is not a directory: ${absPath}`);
252
+ }
253
+ const data = await this.load();
254
+ // Refuse if this path is nested inside another registered repo
255
+ for (const ws of Object.values(data.workspaces)) {
256
+ for (const repo of Object.values(ws.repos)) {
257
+ const registered = resolve(repo.path);
258
+ if (registered !== absPath && absPath.startsWith(registered + sep)) {
259
+ throw new Error(`Refusing to adopt: ${absPath} is nested inside registered repo ${registered}.`);
260
+ }
261
+ }
262
+ }
263
+ const workspaceName = opts.workspace ?? 'default';
264
+ if (!data.workspaces[workspaceName]) {
265
+ data.workspaces[workspaceName] = {
266
+ home: dirname(absPath),
267
+ mode: 'multi-repo',
268
+ repos: {},
269
+ };
270
+ }
271
+ const ws = data.workspaces[workspaceName];
272
+ const remote = readGitRemote(absPath);
273
+ let repoName = opts.name ?? basename(absPath);
274
+ let suffix = 2;
275
+ while (ws.repos[repoName]) {
276
+ // Same path already registered? Treat as idempotent.
277
+ if (resolve(ws.repos[repoName].path) === absPath) {
278
+ if (!opts.silent)
279
+ console.log(` Already registered: ${repoName} -> ${absPath}`);
280
+ return { workspace: workspaceName, repoName };
281
+ }
282
+ repoName = `${opts.name ?? basename(absPath)}-${suffix++}`;
283
+ }
284
+ // Seed OpsInventory.yaml only if missing — never overwrite existing.
285
+ const inventoryPath = resolve(absPath, 'OpsInventory.yaml');
286
+ if (!existsSync(inventoryPath)) {
287
+ const ext = (opts.extensions && opts.extensions[0]) ?? 'sys';
288
+ await seedInventory(absPath, repoName, ext);
289
+ }
290
+ ws.repos[repoName] = {
291
+ path: absPath,
292
+ remote,
293
+ extensions: opts.extensions ?? [],
294
+ };
295
+ if (Object.keys(data.workspaces).length === 1) {
296
+ data.defaultWorkspace = workspaceName;
297
+ }
298
+ await this.save(data);
299
+ if (!opts.silent) {
300
+ console.log(`Adopted ${repoName} at ${absPath} into workspace "${workspaceName}".`);
301
+ if (remote)
302
+ console.log(` Remote: ${remote}`);
303
+ }
304
+ return { workspace: workspaceName, repoName };
305
+ }
306
+ /**
307
+ * Walk the given roots looking for ops-workspace candidates.
308
+ *
309
+ * A candidate is any directory containing `OpsInventory.yaml`. Skips
310
+ * `node_modules`, `.git`, and other obvious noise. Candidates nested
311
+ * inside another candidate are dropped (siblings-only by design — see
312
+ * #935).
313
+ */
314
+ async discoverWorkspaces(opts = {}) {
315
+ const roots = (opts.roots && opts.roots.length > 0 ? opts.roots : [homedir()]).map((r) => resolve(r));
316
+ const maxDepth = opts.maxDepth ?? 3;
317
+ const data = await this.load();
318
+ const registeredPaths = new Set();
319
+ for (const ws of Object.values(data.workspaces)) {
320
+ for (const repo of Object.values(ws.repos)) {
321
+ registeredPaths.add(resolve(repo.path));
322
+ }
323
+ }
324
+ const found = [];
325
+ const seen = new Set();
326
+ const skipNames = new Set([
327
+ 'node_modules',
328
+ '.git',
329
+ '.aiwg', // walk past, never into
330
+ '.cache',
331
+ '.npm',
332
+ '.yarn',
333
+ '.pnpm-store',
334
+ '.venv',
335
+ 'venv',
336
+ 'dist',
337
+ 'build',
338
+ 'target',
339
+ ]);
340
+ const walk = async (dir, depth) => {
341
+ if (depth > maxDepth)
342
+ return;
343
+ if (seen.has(dir))
344
+ return;
345
+ seen.add(dir);
346
+ // Marker check at this level
347
+ if (existsSync(resolve(dir, 'OpsInventory.yaml'))) {
348
+ found.push({
349
+ path: dir,
350
+ name: basename(dir),
351
+ remote: readGitRemote(dir),
352
+ alreadyRegistered: registeredPaths.has(dir),
353
+ marker: 'OpsInventory.yaml',
354
+ });
355
+ // Don't descend further — workspaces shouldn't nest.
356
+ return;
357
+ }
358
+ let entries;
359
+ try {
360
+ entries = await readdir(dir);
361
+ }
362
+ catch {
363
+ return;
364
+ }
365
+ for (const entry of entries) {
366
+ if (entry.startsWith('.') && entry !== '.aiwg') {
367
+ // Allow hidden roots only in narrow cases; skip the rest.
368
+ if (skipNames.has(entry))
369
+ continue;
370
+ if (entry === '.git')
371
+ continue;
372
+ }
373
+ if (skipNames.has(entry))
374
+ continue;
375
+ const child = resolve(dir, entry);
376
+ let isDir = false;
377
+ try {
378
+ isDir = statSync(child).isDirectory();
379
+ }
380
+ catch {
381
+ continue;
382
+ }
383
+ if (!isDir)
384
+ continue;
385
+ await walk(child, depth + 1);
386
+ }
387
+ };
388
+ for (const root of roots) {
389
+ if (!existsSync(root))
390
+ continue;
391
+ await walk(root, 0);
392
+ }
393
+ // Drop nested candidates (deeper paths whose ancestor is also a candidate)
394
+ found.sort((a, b) => a.path.length - b.path.length);
395
+ const kept = [];
396
+ for (const cand of found) {
397
+ const nested = kept.some((k) => cand.path !== k.path && cand.path.startsWith(k.path + sep));
398
+ if (!nested)
399
+ kept.push(cand);
400
+ }
401
+ return kept;
402
+ }
403
+ /**
404
+ * Register discovered candidates as a workspace in the registry.
405
+ *
406
+ * Creates a single multi-repo workspace and adds each candidate as a
407
+ * repo entry. Skips candidates whose path is already registered.
408
+ */
409
+ async registerDiscovered(workspaceName, candidates) {
410
+ if (candidates.length === 0)
411
+ return { added: 0, skipped: 0 };
412
+ const data = await this.load();
413
+ if (!data.workspaces[workspaceName]) {
414
+ data.workspaces[workspaceName] = {
415
+ home: dirname(candidates[0].path),
416
+ mode: 'multi-repo',
417
+ repos: {},
418
+ };
419
+ }
420
+ const ws = data.workspaces[workspaceName];
421
+ let added = 0;
422
+ let skipped = 0;
423
+ for (const cand of candidates) {
424
+ if (cand.alreadyRegistered) {
425
+ skipped++;
426
+ continue;
427
+ }
428
+ // Avoid clobbering an existing repo entry of the same name
429
+ let repoName = cand.name;
430
+ let suffix = 2;
431
+ while (ws.repos[repoName]) {
432
+ repoName = `${cand.name}-${suffix++}`;
433
+ }
434
+ ws.repos[repoName] = {
435
+ path: cand.path,
436
+ remote: cand.remote,
437
+ extensions: [],
438
+ };
439
+ added++;
440
+ }
441
+ if (Object.keys(data.workspaces).length === 1) {
442
+ data.defaultWorkspace = workspaceName;
443
+ }
444
+ await this.save(data);
445
+ return { added, skipped };
446
+ }
447
+ /**
448
+ * Push workspace repos to remote (always private)
449
+ */
450
+ async pushWorkspace(workspaceName) {
451
+ const data = await this.load();
452
+ const name = workspaceName || data.defaultWorkspace;
453
+ const workspace = data.workspaces[name];
454
+ if (!workspace) {
455
+ throw new Error(`Workspace "${name}" not found`);
456
+ }
457
+ let canonical = null;
458
+ const canonicalConfigPath = projectAiwgPath(workspace.home, 'aiwg.config');
459
+ let canonicalDeclared = false;
460
+ if (existsSync(canonicalConfigPath)) {
461
+ try {
462
+ const raw = JSON.parse(readFileSync(canonicalConfigPath, 'utf8'));
463
+ canonicalDeclared = Array.isArray(raw.repos);
464
+ }
465
+ catch (error) {
466
+ console.log(` Refusing workspace push — invalid canonical config: ${error instanceof Error ? error.message : String(error)}`);
467
+ return;
468
+ }
469
+ }
470
+ if (canonicalDeclared) {
471
+ try {
472
+ canonical = await resolveWorkspace(workspace.home, workspace.home);
473
+ }
474
+ catch (error) {
475
+ console.log(` Refusing workspace push — canonical workspace resolution failed: ${error instanceof Error ? error.message : String(error)}`);
476
+ return;
477
+ }
478
+ }
479
+ for (const [repoName, repo] of Object.entries(workspace.repos)) {
480
+ if (!existsSync(repo.path)) {
481
+ console.log(` Skipping ${repoName} — path does not exist`);
482
+ continue;
483
+ }
484
+ const member = canonical?.members.find((candidate) => resolve(candidate.path) === resolve(repo.path));
485
+ if (canonical && !member) {
486
+ console.log(` Skipping ${repoName} — denied: path is not listed in workspace config`);
487
+ continue;
488
+ }
489
+ if (member && !member.allowed.includes('push')) {
490
+ console.log(` Skipping ${repoName} — denied: workspace member does not allow push`);
491
+ continue;
492
+ }
493
+ const remote = member?.remotes.primary ?? (repo.remote ? 'origin' : undefined);
494
+ const branch = member?.delivery.default_branch ?? 'main';
495
+ if (remote) {
496
+ console.log(` Pushing ${repoName} to ${remote}/${branch}...`);
497
+ try {
498
+ execSync(`git push ${shellEscape(remote)} ${shellEscape(branch)}`, {
499
+ cwd: repo.path,
500
+ stdio: 'pipe',
501
+ });
502
+ console.log(` ${repoName}: pushed`);
503
+ }
504
+ catch (err) {
505
+ console.log(` ${repoName}: push failed — ${err instanceof Error ? err.message : String(err)}`);
506
+ }
507
+ }
508
+ else {
509
+ console.log(` ${repoName}: no remote configured`);
510
+ }
511
+ }
512
+ }
513
+ }
514
+ /**
515
+ * Provision a repo at `repoPath`. Order of preference:
516
+ * 1. Pre-existing `.git` at the path → adopt (read remote, no init/clone).
517
+ * 2. `--from <url>` provided and target is empty → `git clone`.
518
+ * 3. Fallback → `mkdir` + `git init`.
519
+ *
520
+ * Returns the action taken and the resolved remote URL (if any).
521
+ */
522
+ async function provisionRepo(repoPath, fromUrl, silent) {
523
+ // Case 1: existing .git at the path → adopt in place.
524
+ if (existsSync(resolve(repoPath, '.git'))) {
525
+ return { action: 'Adopted', remote: readGitRemote(repoPath) };
526
+ }
527
+ // Case 2: --from URL → clone (only if target is empty or doesn't exist).
528
+ if (fromUrl) {
529
+ const exists = existsSync(repoPath);
530
+ if (exists) {
531
+ // Refuse to clone over a non-empty existing dir to avoid surprise overwrites.
532
+ let entries = [];
533
+ try {
534
+ entries = readdirSync(repoPath);
535
+ }
536
+ catch {
537
+ // ignore
538
+ }
539
+ if (entries.filter((e) => !e.startsWith('.')).length > 0) {
540
+ throw new Error(`Refusing to clone into non-empty directory: ${repoPath}. Move or remove it first.`);
541
+ }
542
+ }
543
+ await mkdir(dirname(repoPath), { recursive: true });
544
+ execSync(`git clone ${shellEscape(fromUrl)} ${shellEscape(repoPath)}`, { stdio: silent ? 'pipe' : 'inherit' });
545
+ return { action: 'Cloned', remote: readGitRemote(repoPath) };
546
+ }
547
+ // Case 3: fresh init.
548
+ await mkdir(repoPath, { recursive: true });
549
+ execSync('git init', { cwd: repoPath, stdio: 'pipe' });
550
+ return { action: 'Created', remote: undefined };
551
+ }
552
+ /**
553
+ * Minimal shell escaping for git URLs and paths passed via execSync.
554
+ * URLs are URL-encoded already, but paths may contain spaces.
555
+ */
556
+ function shellEscape(s) {
557
+ if (/^[A-Za-z0-9_@:./~+,=-]+$/.test(s))
558
+ return s;
559
+ return `'${s.replace(/'/g, "'\\''")}'`;
560
+ }
561
+ /**
562
+ * Return the `origin` remote URL for a git repo rooted at `dirPath`, or
563
+ * undefined if not a git repo or no origin configured.
564
+ */
565
+ function readGitRemote(dirPath) {
566
+ if (!existsSync(resolve(dirPath, '.git')))
567
+ return undefined;
568
+ try {
569
+ const out = execSync('git config --get remote.origin.url', {
570
+ cwd: dirPath,
571
+ stdio: ['ignore', 'pipe', 'ignore'],
572
+ })
573
+ .toString()
574
+ .trim();
575
+ return out || undefined;
576
+ }
577
+ catch {
578
+ return undefined;
579
+ }
580
+ }
581
+ /**
582
+ * Walk up from targetPath's parent looking for an enclosing ops workspace.
583
+ * Returns the path of the enclosing workspace, or null if none found.
584
+ *
585
+ * Marker: OpsInventory.yaml (the file the ops scaffolder seeds at workspace
586
+ * root). `.aiwg/` is intentionally not used as a marker since AIWG project
587
+ * roots routinely contain `.aiwg/aiwg.config` without being ops workspaces.
588
+ */
589
+ function findEnclosingOpsWorkspace(targetPath) {
590
+ const resolved = resolve(targetPath);
591
+ let current = dirname(resolved);
592
+ // Stop walking when dirname() no longer advances (filesystem root).
593
+ while (true) {
594
+ if (existsSync(resolve(current, 'OpsInventory.yaml'))) {
595
+ return current;
596
+ }
597
+ const parent = dirname(current);
598
+ if (parent === current)
599
+ return null;
600
+ current = parent;
601
+ }
602
+ }
603
+ /**
604
+ * Seed an OpsInventory.yaml stub in a repo or subdirectory
605
+ */
606
+ async function seedInventory(dirPath, name, extension) {
607
+ const inventoryPath = resolve(dirPath, 'OpsInventory.yaml');
608
+ if (existsSync(inventoryPath))
609
+ return;
610
+ const fullName = EXTENSION_NAMES[extension] || extension;
611
+ const content = `apiVersion: aiwg.io/v1
612
+ kind: OpsInventory
613
+ metadata:
614
+ name: ${name}
615
+ domain: ${fullName}
616
+ created: ${new Date().toISOString().split('T')[0]}
617
+
618
+ # Add hosts, services, and resources below
619
+ inventory: []
620
+ `;
621
+ await writeFile(inventoryPath, content, 'utf-8');
622
+ }
623
+ //# sourceMappingURL=registry.js.map