eai-cli 0.0.0-bootstrap.0

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 (690) hide show
  1. package/LICENSE +183 -0
  2. package/NOTICE +4 -0
  3. package/README.md +14 -0
  4. package/dist/commands/agent.d.ts +3 -0
  5. package/dist/commands/agent.d.ts.map +1 -0
  6. package/dist/commands/agent.js +69 -0
  7. package/dist/commands/agent.js.map +1 -0
  8. package/dist/commands/blocks.d.ts +3 -0
  9. package/dist/commands/blocks.d.ts.map +1 -0
  10. package/dist/commands/blocks.js +249 -0
  11. package/dist/commands/blocks.js.map +1 -0
  12. package/dist/commands/chat.d.ts +6 -0
  13. package/dist/commands/chat.d.ts.map +1 -0
  14. package/dist/commands/chat.js +105 -0
  15. package/dist/commands/chat.js.map +1 -0
  16. package/dist/commands/deploy.d.ts +36 -0
  17. package/dist/commands/deploy.d.ts.map +1 -0
  18. package/dist/commands/deploy.js +712 -0
  19. package/dist/commands/deploy.js.map +1 -0
  20. package/dist/commands/dev.d.ts +15 -0
  21. package/dist/commands/dev.d.ts.map +1 -0
  22. package/dist/commands/dev.js +133 -0
  23. package/dist/commands/dev.js.map +1 -0
  24. package/dist/commands/docs.d.ts +6 -0
  25. package/dist/commands/docs.d.ts.map +1 -0
  26. package/dist/commands/docs.js +118 -0
  27. package/dist/commands/docs.js.map +1 -0
  28. package/dist/commands/env.d.ts +10 -0
  29. package/dist/commands/env.d.ts.map +1 -0
  30. package/dist/commands/env.js +200 -0
  31. package/dist/commands/env.js.map +1 -0
  32. package/dist/commands/errors.d.ts +3 -0
  33. package/dist/commands/errors.d.ts.map +1 -0
  34. package/dist/commands/errors.js +72 -0
  35. package/dist/commands/errors.js.map +1 -0
  36. package/dist/commands/gofer.d.ts +3 -0
  37. package/dist/commands/gofer.d.ts.map +1 -0
  38. package/dist/commands/gofer.js +134 -0
  39. package/dist/commands/gofer.js.map +1 -0
  40. package/dist/commands/init.d.ts +14 -0
  41. package/dist/commands/init.d.ts.map +1 -0
  42. package/dist/commands/init.js +1437 -0
  43. package/dist/commands/init.js.map +1 -0
  44. package/dist/commands/login.d.ts +7 -0
  45. package/dist/commands/login.d.ts.map +1 -0
  46. package/dist/commands/login.js +117 -0
  47. package/dist/commands/login.js.map +1 -0
  48. package/dist/commands/provision.d.ts +6 -0
  49. package/dist/commands/provision.d.ts.map +1 -0
  50. package/dist/commands/provision.js +855 -0
  51. package/dist/commands/provision.js.map +1 -0
  52. package/dist/commands/publicapi.d.ts +6 -0
  53. package/dist/commands/publicapi.d.ts.map +1 -0
  54. package/dist/commands/publicapi.js +184 -0
  55. package/dist/commands/publicapi.js.map +1 -0
  56. package/dist/commands/resources.d.ts +38 -0
  57. package/dist/commands/resources.d.ts.map +1 -0
  58. package/dist/commands/resources.js +1010 -0
  59. package/dist/commands/resources.js.map +1 -0
  60. package/dist/commands/runtime.d.ts +3 -0
  61. package/dist/commands/runtime.d.ts.map +1 -0
  62. package/dist/commands/runtime.js +78 -0
  63. package/dist/commands/runtime.js.map +1 -0
  64. package/dist/commands/template.d.ts +3 -0
  65. package/dist/commands/template.d.ts.map +1 -0
  66. package/dist/commands/template.js +365 -0
  67. package/dist/commands/template.js.map +1 -0
  68. package/dist/commands/tenant.d.ts +45 -0
  69. package/dist/commands/tenant.d.ts.map +1 -0
  70. package/dist/commands/tenant.js +1036 -0
  71. package/dist/commands/tenant.js.map +1 -0
  72. package/dist/commands/types.d.ts +130 -0
  73. package/dist/commands/types.d.ts.map +1 -0
  74. package/dist/commands/types.js +1636 -0
  75. package/dist/commands/types.js.map +1 -0
  76. package/dist/commands/update.d.ts +13 -0
  77. package/dist/commands/update.d.ts.map +1 -0
  78. package/dist/commands/update.js +163 -0
  79. package/dist/commands/update.js.map +1 -0
  80. package/dist/commands/user.d.ts +6 -0
  81. package/dist/commands/user.d.ts.map +1 -0
  82. package/dist/commands/user.js +359 -0
  83. package/dist/commands/user.js.map +1 -0
  84. package/dist/commands/verify.d.ts +40 -0
  85. package/dist/commands/verify.d.ts.map +1 -0
  86. package/dist/commands/verify.js +1442 -0
  87. package/dist/commands/verify.js.map +1 -0
  88. package/dist/commands/vertical.d.ts +24 -0
  89. package/dist/commands/vertical.d.ts.map +1 -0
  90. package/dist/commands/vertical.js +301 -0
  91. package/dist/commands/vertical.js.map +1 -0
  92. package/dist/commands/whoami.d.ts +6 -0
  93. package/dist/commands/whoami.d.ts.map +1 -0
  94. package/dist/commands/whoami.js +73 -0
  95. package/dist/commands/whoami.js.map +1 -0
  96. package/dist/commands/workflow.d.ts +6 -0
  97. package/dist/commands/workflow.d.ts.map +1 -0
  98. package/dist/commands/workflow.js +400 -0
  99. package/dist/commands/workflow.js.map +1 -0
  100. package/dist/index.d.ts +10 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +272 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/lib/agent-guide.d.ts +24 -0
  105. package/dist/lib/agent-guide.d.ts.map +1 -0
  106. package/dist/lib/agent-guide.js +155 -0
  107. package/dist/lib/agent-guide.js.map +1 -0
  108. package/dist/lib/api.d.ts +338 -0
  109. package/dist/lib/api.d.ts.map +1 -0
  110. package/dist/lib/api.js +991 -0
  111. package/dist/lib/api.js.map +1 -0
  112. package/dist/lib/auth.d.ts +65 -0
  113. package/dist/lib/auth.d.ts.map +1 -0
  114. package/dist/lib/auth.js +592 -0
  115. package/dist/lib/auth.js.map +1 -0
  116. package/dist/lib/azure-cli.d.ts +6 -0
  117. package/dist/lib/azure-cli.d.ts.map +1 -0
  118. package/dist/lib/azure-cli.js +13 -0
  119. package/dist/lib/azure-cli.js.map +1 -0
  120. package/dist/lib/block-catalog-normalize.d.ts +47 -0
  121. package/dist/lib/block-catalog-normalize.d.ts.map +1 -0
  122. package/dist/lib/block-catalog-normalize.js +355 -0
  123. package/dist/lib/block-catalog-normalize.js.map +1 -0
  124. package/dist/lib/block-catalog-types.d.ts +111 -0
  125. package/dist/lib/block-catalog-types.d.ts.map +1 -0
  126. package/dist/lib/block-catalog-types.js +41 -0
  127. package/dist/lib/block-catalog-types.js.map +1 -0
  128. package/dist/lib/block-catalog-utils.d.ts +7 -0
  129. package/dist/lib/block-catalog-utils.d.ts.map +1 -0
  130. package/dist/lib/block-catalog-utils.js +47 -0
  131. package/dist/lib/block-catalog-utils.js.map +1 -0
  132. package/dist/lib/block-catalog-validation.d.ts +5 -0
  133. package/dist/lib/block-catalog-validation.d.ts.map +1 -0
  134. package/dist/lib/block-catalog-validation.js +112 -0
  135. package/dist/lib/block-catalog-validation.js.map +1 -0
  136. package/dist/lib/block-catalog.d.ts +3 -0
  137. package/dist/lib/block-catalog.d.ts.map +1 -0
  138. package/dist/lib/block-catalog.js +284 -0
  139. package/dist/lib/block-catalog.js.map +1 -0
  140. package/dist/lib/cloud-env.d.ts +25 -0
  141. package/dist/lib/cloud-env.d.ts.map +1 -0
  142. package/dist/lib/cloud-env.js +79 -0
  143. package/dist/lib/cloud-env.js.map +1 -0
  144. package/dist/lib/config.d.ts +116 -0
  145. package/dist/lib/config.d.ts.map +1 -0
  146. package/dist/lib/config.js +195 -0
  147. package/dist/lib/config.js.map +1 -0
  148. package/dist/lib/context.d.ts +43 -0
  149. package/dist/lib/context.d.ts.map +1 -0
  150. package/dist/lib/context.js +68 -0
  151. package/dist/lib/context.js.map +1 -0
  152. package/dist/lib/error-codes.d.ts +56 -0
  153. package/dist/lib/error-codes.d.ts.map +1 -0
  154. package/dist/lib/error-codes.js +211 -0
  155. package/dist/lib/error-codes.js.map +1 -0
  156. package/dist/lib/error-guidance/catalog.d.ts +648 -0
  157. package/dist/lib/error-guidance/catalog.d.ts.map +1 -0
  158. package/dist/lib/error-guidance/catalog.js +940 -0
  159. package/dist/lib/error-guidance/catalog.js.map +1 -0
  160. package/dist/lib/error-guidance/match.d.ts +3 -0
  161. package/dist/lib/error-guidance/match.d.ts.map +1 -0
  162. package/dist/lib/error-guidance/match.js +46 -0
  163. package/dist/lib/error-guidance/match.js.map +1 -0
  164. package/dist/lib/error-guidance/render.d.ts +5 -0
  165. package/dist/lib/error-guidance/render.d.ts.map +1 -0
  166. package/dist/lib/error-guidance/render.js +92 -0
  167. package/dist/lib/error-guidance/render.js.map +1 -0
  168. package/dist/lib/error-guidance/types.d.ts +76 -0
  169. package/dist/lib/error-guidance/types.d.ts.map +1 -0
  170. package/dist/lib/error-guidance/types.js +2 -0
  171. package/dist/lib/error-guidance/types.js.map +1 -0
  172. package/dist/lib/error-guidance/validate.d.ts +3 -0
  173. package/dist/lib/error-guidance/validate.d.ts.map +1 -0
  174. package/dist/lib/error-guidance/validate.js +59 -0
  175. package/dist/lib/error-guidance/validate.js.map +1 -0
  176. package/dist/lib/gofer-installer.d.ts +32 -0
  177. package/dist/lib/gofer-installer.d.ts.map +1 -0
  178. package/dist/lib/gofer-installer.js +589 -0
  179. package/dist/lib/gofer-installer.js.map +1 -0
  180. package/dist/lib/gofer-refresh.d.ts +46 -0
  181. package/dist/lib/gofer-refresh.d.ts.map +1 -0
  182. package/dist/lib/gofer-refresh.js +536 -0
  183. package/dist/lib/gofer-refresh.js.map +1 -0
  184. package/dist/lib/next-route-exports.d.ts +6 -0
  185. package/dist/lib/next-route-exports.d.ts.map +1 -0
  186. package/dist/lib/next-route-exports.js +127 -0
  187. package/dist/lib/next-route-exports.js.map +1 -0
  188. package/dist/lib/npm.d.ts +2 -0
  189. package/dist/lib/npm.d.ts.map +1 -0
  190. package/dist/lib/npm.js +4 -0
  191. package/dist/lib/npm.js.map +1 -0
  192. package/dist/lib/object-type-defaults.d.ts +4 -0
  193. package/dist/lib/object-type-defaults.d.ts.map +1 -0
  194. package/dist/lib/object-type-defaults.js +72 -0
  195. package/dist/lib/object-type-defaults.js.map +1 -0
  196. package/dist/lib/output.d.ts +35 -0
  197. package/dist/lib/output.d.ts.map +1 -0
  198. package/dist/lib/output.js +166 -0
  199. package/dist/lib/output.js.map +1 -0
  200. package/dist/lib/profile.d.ts +52 -0
  201. package/dist/lib/profile.d.ts.map +1 -0
  202. package/dist/lib/profile.js +116 -0
  203. package/dist/lib/profile.js.map +1 -0
  204. package/dist/lib/project-manifest.d.ts +42 -0
  205. package/dist/lib/project-manifest.d.ts.map +1 -0
  206. package/dist/lib/project-manifest.js +191 -0
  207. package/dist/lib/project-manifest.js.map +1 -0
  208. package/dist/lib/resourceapi-bundle.d.ts +33 -0
  209. package/dist/lib/resourceapi-bundle.d.ts.map +1 -0
  210. package/dist/lib/resourceapi-bundle.js +79 -0
  211. package/dist/lib/resourceapi-bundle.js.map +1 -0
  212. package/dist/lib/runtime-contract.d.ts +84 -0
  213. package/dist/lib/runtime-contract.d.ts.map +1 -0
  214. package/dist/lib/runtime-contract.js +318 -0
  215. package/dist/lib/runtime-contract.js.map +1 -0
  216. package/dist/lib/schema-builder.d.ts +28 -0
  217. package/dist/lib/schema-builder.d.ts.map +1 -0
  218. package/dist/lib/schema-builder.js +69 -0
  219. package/dist/lib/schema-builder.js.map +1 -0
  220. package/dist/lib/tenant-context.d.ts +127 -0
  221. package/dist/lib/tenant-context.d.ts.map +1 -0
  222. package/dist/lib/tenant-context.js +573 -0
  223. package/dist/lib/tenant-context.js.map +1 -0
  224. package/dist/lib/update-check.d.ts +52 -0
  225. package/dist/lib/update-check.d.ts.map +1 -0
  226. package/dist/lib/update-check.js +271 -0
  227. package/dist/lib/update-check.js.map +1 -0
  228. package/dist/lib/update-maintenance.d.ts +15 -0
  229. package/dist/lib/update-maintenance.d.ts.map +1 -0
  230. package/dist/lib/update-maintenance.js +187 -0
  231. package/dist/lib/update-maintenance.js.map +1 -0
  232. package/dist/lib/utils.d.ts +23 -0
  233. package/dist/lib/utils.d.ts.map +1 -0
  234. package/dist/lib/utils.js +48 -0
  235. package/dist/lib/utils.js.map +1 -0
  236. package/dist/lib/workflow-provisioning.d.ts +54 -0
  237. package/dist/lib/workflow-provisioning.d.ts.map +1 -0
  238. package/dist/lib/workflow-provisioning.js +281 -0
  239. package/dist/lib/workflow-provisioning.js.map +1 -0
  240. package/package.json +51 -0
  241. package/resources/gofer/.gofer-version +7 -0
  242. package/resources/gofer/agents-skills/0_gofer_start/SKILL.md +1287 -0
  243. package/resources/gofer/agents-skills/0a_problem_validation/SKILL.md +429 -0
  244. package/resources/gofer/agents-skills/10_gofer_cloud/SKILL.md +635 -0
  245. package/resources/gofer/agents-skills/1_gofer_research/SKILL.md +1159 -0
  246. package/resources/gofer/agents-skills/2_gofer_specify/SKILL.md +860 -0
  247. package/resources/gofer/agents-skills/3_gofer_plan/SKILL.md +886 -0
  248. package/resources/gofer/agents-skills/4_gofer_tasks/SKILL.md +748 -0
  249. package/resources/gofer/agents-skills/5_gofer_implement/SKILL.md +924 -0
  250. package/resources/gofer/agents-skills/6_gofer_validate/SKILL.md +2269 -0
  251. package/resources/gofer/agents-skills/7_gofer_save/SKILL.md +423 -0
  252. package/resources/gofer/agents-skills/7a_stakeholder_comms/SKILL.md +508 -0
  253. package/resources/gofer/agents-skills/8_gofer_branding/SKILL.md +315 -0
  254. package/resources/gofer/agents-skills/9_gofer_tests/SKILL.md +558 -0
  255. package/resources/gofer/agents-skills/gofer_bootstrap_workspace/SKILL.md +148 -0
  256. package/resources/gofer/agents-skills/gofer_check_workspace/SKILL.md +119 -0
  257. package/resources/gofer/agents-skills/gofer_constitution/SKILL.md +612 -0
  258. package/resources/gofer/agents-skills/gofer_diagnose/SKILL.md +114 -0
  259. package/resources/gofer/agents-skills/gofer_eai_first_run/SKILL.md +397 -0
  260. package/resources/gofer/agents-skills/gofer_hydrate/SKILL.md +561 -0
  261. package/resources/gofer/agents-skills/gofer_personality/SKILL.md +44 -0
  262. package/resources/gofer/agents-skills/gofer_plan/SKILL.md +40 -0
  263. package/resources/gofer/agents-skills/gofer_side/SKILL.md +45 -0
  264. package/resources/gofer/agents-skills/gofer_spec_summary/SKILL.md +112 -0
  265. package/resources/gofer/agents-skills/gofer_tdd/SKILL.md +112 -0
  266. package/resources/gofer/agents-skills/gofer_vocabulary/SKILL.md +112 -0
  267. package/resources/gofer/agents-skills/gofer_zoom_out/SKILL.md +112 -0
  268. package/resources/gofer/bash-scripts/check-context-health.sh +365 -0
  269. package/resources/gofer/bash-scripts/check-persona-pack.sh +81 -0
  270. package/resources/gofer/bash-scripts/check-prerequisites.sh +168 -0
  271. package/resources/gofer/bash-scripts/common.sh +192 -0
  272. package/resources/gofer/bash-scripts/create-new-feature.sh +260 -0
  273. package/resources/gofer/bash-scripts/install-optional-tools.sh +270 -0
  274. package/resources/gofer/bash-scripts/log-stage.sh +224 -0
  275. package/resources/gofer/bash-scripts/mark-task-complete.sh +74 -0
  276. package/resources/gofer/bash-scripts/pipeline-state.sh +306 -0
  277. package/resources/gofer/bash-scripts/read-failed-approaches.sh +114 -0
  278. package/resources/gofer/bash-scripts/read-session-memories.sh +96 -0
  279. package/resources/gofer/bash-scripts/save-checkpoint.sh +407 -0
  280. package/resources/gofer/bash-scripts/setup-plan.sh +62 -0
  281. package/resources/gofer/bash-scripts/sync-implementation-status.sh +47 -0
  282. package/resources/gofer/bash-scripts/update-agent-context.sh +772 -0
  283. package/resources/gofer/bash-scripts/validate-artifact.sh +335 -0
  284. package/resources/gofer/bash-scripts/verify-task.sh +384 -0
  285. package/resources/gofer/bash-scripts/write-failed-approach.sh +110 -0
  286. package/resources/gofer/bash-scripts/write-periodic-checkpoint.sh +128 -0
  287. package/resources/gofer/bash-scripts/write-session-memory.sh +118 -0
  288. package/resources/gofer/claude-agents/assumption-tracker.md +168 -0
  289. package/resources/gofer/claude-agents/business-metrics-analyzer.md +169 -0
  290. package/resources/gofer/claude-agents/business-problem-validator.md +168 -0
  291. package/resources/gofer/claude-agents/codebase-analyzer.md +124 -0
  292. package/resources/gofer/claude-agents/codebase-locator.md +95 -0
  293. package/resources/gofer/claude-agents/codebase-pattern-finder.md +180 -0
  294. package/resources/gofer/claude-agents/comms-writer.md +158 -0
  295. package/resources/gofer/claude-agents/engineer-review.md +169 -0
  296. package/resources/gofer/claude-agents/implement-bug-triangulator.md +94 -0
  297. package/resources/gofer/claude-agents/implement-code-review-council.md +89 -0
  298. package/resources/gofer/claude-agents/implement-doc-writer.md +89 -0
  299. package/resources/gofer/claude-agents/implement-error-hardener.md +84 -0
  300. package/resources/gofer/claude-agents/implement-performance-explorer.md +95 -0
  301. package/resources/gofer/claude-agents/implement-test-diversifier.md +82 -0
  302. package/resources/gofer/claude-agents/implement-variant-generator.md +80 -0
  303. package/resources/gofer/claude-agents/multi-perspective-judge.md +114 -0
  304. package/resources/gofer/claude-agents/plan-api-comparator.md +90 -0
  305. package/resources/gofer/claude-agents/plan-architecture-diverger.md +100 -0
  306. package/resources/gofer/claude-agents/plan-data-model-stress-tester.md +95 -0
  307. package/resources/gofer/claude-agents/plan-migration-path-finder.md +95 -0
  308. package/resources/gofer/claude-agents/plan-refactor-rewrite-advisor.md +97 -0
  309. package/resources/gofer/claude-agents/research-dependency-evaluator.md +106 -0
  310. package/resources/gofer/claude-agents/research-horizon-scanner.md +100 -0
  311. package/resources/gofer/claude-agents/research-market-scanner.md +137 -0
  312. package/resources/gofer/claude-agents/research-perspective-multiplier.md +102 -0
  313. package/resources/gofer/claude-agents/scope-creep-detector.md +152 -0
  314. package/resources/gofer/claude-agents/specify-ambiguity-detector.md +95 -0
  315. package/resources/gofer/claude-agents/specify-journey-stress-tester.md +92 -0
  316. package/resources/gofer/claude-agents/tasks-cross-cutting-scanner.md +91 -0
  317. package/resources/gofer/claude-agents/tasks-rollback-planner.md +89 -0
  318. package/resources/gofer/claude-agents/validate-security-red-team.md +102 -0
  319. package/resources/gofer/claude-agents/validation-correctness.md +103 -0
  320. package/resources/gofer/claude-agents/validation-integration.md +129 -0
  321. package/resources/gofer/claude-agents/validation-performance.md +120 -0
  322. package/resources/gofer/claude-agents/validation-security.md +115 -0
  323. package/resources/gofer/claude-agents/validation-standards.md +151 -0
  324. package/resources/gofer/claude-agents/validation-test-quality.md +146 -0
  325. package/resources/gofer/claude-agents/visual-bounded-context-writer.md +40 -0
  326. package/resources/gofer/claude-agents/visual-c4-writer.md +45 -0
  327. package/resources/gofer/claude-agents/visual-erd-writer.md +34 -0
  328. package/resources/gofer/claude-agents/visual-heatmap-writer.md +63 -0
  329. package/resources/gofer/claude-agents/visual-risk-writer.md +64 -0
  330. package/resources/gofer/claude-commands/0_gofer_start.md +1282 -0
  331. package/resources/gofer/claude-commands/0a_problem_validation.md +424 -0
  332. package/resources/gofer/claude-commands/10_gofer_cloud.md +630 -0
  333. package/resources/gofer/claude-commands/1_gofer_research.md +1154 -0
  334. package/resources/gofer/claude-commands/2_gofer_specify.md +855 -0
  335. package/resources/gofer/claude-commands/3_gofer_plan.md +881 -0
  336. package/resources/gofer/claude-commands/4_gofer_tasks.md +743 -0
  337. package/resources/gofer/claude-commands/5_gofer_implement.md +919 -0
  338. package/resources/gofer/claude-commands/6_gofer_validate.md +2264 -0
  339. package/resources/gofer/claude-commands/7_gofer_save.md +418 -0
  340. package/resources/gofer/claude-commands/7a_stakeholder_comms.md +503 -0
  341. package/resources/gofer/claude-commands/8_gofer_branding.md +310 -0
  342. package/resources/gofer/claude-commands/9_gofer_tests.md +553 -0
  343. package/resources/gofer/claude-commands/gofer_bootstrap_workspace.md +143 -0
  344. package/resources/gofer/claude-commands/gofer_check_workspace.md +114 -0
  345. package/resources/gofer/claude-commands/gofer_constitution.md +607 -0
  346. package/resources/gofer/claude-commands/gofer_diagnose.md +109 -0
  347. package/resources/gofer/claude-commands/gofer_eai_first_run.md +392 -0
  348. package/resources/gofer/claude-commands/gofer_hydrate.md +556 -0
  349. package/resources/gofer/claude-commands/gofer_personality.md +39 -0
  350. package/resources/gofer/claude-commands/gofer_plan.md +35 -0
  351. package/resources/gofer/claude-commands/gofer_side.md +40 -0
  352. package/resources/gofer/claude-commands/gofer_spec_summary.md +107 -0
  353. package/resources/gofer/claude-commands/gofer_tdd.md +107 -0
  354. package/resources/gofer/claude-commands/gofer_vocabulary.md +107 -0
  355. package/resources/gofer/claude-commands/gofer_zoom_out.md +107 -0
  356. package/resources/gofer/claude-skills/eai-gofer/SKILL.md +56 -0
  357. package/resources/gofer/commands/.gitkeep +0 -0
  358. package/resources/gofer/commands/0_gofer_start.md +1299 -0
  359. package/resources/gofer/commands/0a_problem_validation.md +405 -0
  360. package/resources/gofer/commands/10_gofer_cloud.md +611 -0
  361. package/resources/gofer/commands/1_gofer_research.md +1135 -0
  362. package/resources/gofer/commands/2_gofer_specify.md +836 -0
  363. package/resources/gofer/commands/3_gofer_plan.md +862 -0
  364. package/resources/gofer/commands/4_gofer_tasks.md +724 -0
  365. package/resources/gofer/commands/5_gofer_implement.md +900 -0
  366. package/resources/gofer/commands/6_gofer_validate.md +2245 -0
  367. package/resources/gofer/commands/7_gofer_save.md +399 -0
  368. package/resources/gofer/commands/7a_stakeholder_comms.md +484 -0
  369. package/resources/gofer/commands/8_gofer_branding.md +291 -0
  370. package/resources/gofer/commands/9_gofer_tests.md +534 -0
  371. package/resources/gofer/commands/gofer_bootstrap_workspace.md +159 -0
  372. package/resources/gofer/commands/gofer_check_workspace.md +130 -0
  373. package/resources/gofer/commands/gofer_constitution.md +588 -0
  374. package/resources/gofer/commands/gofer_diagnose.md +89 -0
  375. package/resources/gofer/commands/gofer_eai_first_run.md +392 -0
  376. package/resources/gofer/commands/gofer_hydrate.md +537 -0
  377. package/resources/gofer/commands/gofer_personality.md +61 -0
  378. package/resources/gofer/commands/gofer_plan.md +51 -0
  379. package/resources/gofer/commands/gofer_side.md +56 -0
  380. package/resources/gofer/commands/gofer_spec_summary.md +87 -0
  381. package/resources/gofer/commands/gofer_tdd.md +87 -0
  382. package/resources/gofer/commands/gofer_vocabulary.md +87 -0
  383. package/resources/gofer/commands/gofer_zoom_out.md +87 -0
  384. package/resources/gofer/copilot-instructions/gofer-cost.instructions.md +13 -0
  385. package/resources/gofer/copilot-instructions/language-server.instructions.md +49 -0
  386. package/resources/gofer/copilot-instructions/typescript.instructions.md +47 -0
  387. package/resources/gofer/copilot-instructions/vscode-extension.instructions.md +46 -0
  388. package/resources/gofer/copilot-prompts/0_gofer_start.prompt.md +1308 -0
  389. package/resources/gofer/copilot-prompts/0a_problem_validation.prompt.md +429 -0
  390. package/resources/gofer/copilot-prompts/10_gofer_cloud.prompt.md +644 -0
  391. package/resources/gofer/copilot-prompts/1_gofer_research.prompt.md +1177 -0
  392. package/resources/gofer/copilot-prompts/2_gofer_specify.prompt.md +878 -0
  393. package/resources/gofer/copilot-prompts/3_gofer_plan.prompt.md +904 -0
  394. package/resources/gofer/copilot-prompts/4_gofer_tasks.prompt.md +766 -0
  395. package/resources/gofer/copilot-prompts/5_gofer_implement.prompt.md +942 -0
  396. package/resources/gofer/copilot-prompts/6_gofer_validate.prompt.md +2277 -0
  397. package/resources/gofer/copilot-prompts/7_gofer_save.prompt.md +433 -0
  398. package/resources/gofer/copilot-prompts/7a_stakeholder_comms.prompt.md +516 -0
  399. package/resources/gofer/copilot-prompts/8_gofer_branding.prompt.md +323 -0
  400. package/resources/gofer/copilot-prompts/9_gofer_tests.prompt.md +566 -0
  401. package/resources/gofer/copilot-prompts/gofer_bootstrap_workspace.prompt.md +161 -0
  402. package/resources/gofer/copilot-prompts/gofer_check_workspace.prompt.md +132 -0
  403. package/resources/gofer/copilot-prompts/gofer_constitution.prompt.md +621 -0
  404. package/resources/gofer/copilot-prompts/gofer_diagnose.prompt.md +127 -0
  405. package/resources/gofer/copilot-prompts/gofer_eai_first_run.prompt.md +410 -0
  406. package/resources/gofer/copilot-prompts/gofer_hydrate.prompt.md +571 -0
  407. package/resources/gofer/copilot-prompts/gofer_personality.prompt.md +57 -0
  408. package/resources/gofer/copilot-prompts/gofer_plan.prompt.md +53 -0
  409. package/resources/gofer/copilot-prompts/gofer_side.prompt.md +58 -0
  410. package/resources/gofer/copilot-prompts/gofer_spec_summary.prompt.md +125 -0
  411. package/resources/gofer/copilot-prompts/gofer_tdd.prompt.md +125 -0
  412. package/resources/gofer/copilot-prompts/gofer_vocabulary.prompt.md +125 -0
  413. package/resources/gofer/copilot-prompts/gofer_zoom_out.prompt.md +125 -0
  414. package/resources/gofer/gemini/agents/assumption-tracker.md +171 -0
  415. package/resources/gofer/gemini/agents/business-metrics-analyzer.md +172 -0
  416. package/resources/gofer/gemini/agents/business-problem-validator.md +171 -0
  417. package/resources/gofer/gemini/agents/codebase-analyzer.md +127 -0
  418. package/resources/gofer/gemini/agents/codebase-locator.md +98 -0
  419. package/resources/gofer/gemini/agents/codebase-pattern-finder.md +183 -0
  420. package/resources/gofer/gemini/agents/comms-writer.md +161 -0
  421. package/resources/gofer/gemini/agents/engineer-review.md +172 -0
  422. package/resources/gofer/gemini/agents/implement-bug-triangulator.md +97 -0
  423. package/resources/gofer/gemini/agents/implement-code-review-council.md +92 -0
  424. package/resources/gofer/gemini/agents/implement-doc-writer.md +92 -0
  425. package/resources/gofer/gemini/agents/implement-error-hardener.md +87 -0
  426. package/resources/gofer/gemini/agents/implement-performance-explorer.md +98 -0
  427. package/resources/gofer/gemini/agents/implement-test-diversifier.md +85 -0
  428. package/resources/gofer/gemini/agents/implement-variant-generator.md +83 -0
  429. package/resources/gofer/gemini/agents/multi-perspective-judge.md +117 -0
  430. package/resources/gofer/gemini/agents/plan-api-comparator.md +93 -0
  431. package/resources/gofer/gemini/agents/plan-architecture-diverger.md +103 -0
  432. package/resources/gofer/gemini/agents/plan-data-model-stress-tester.md +98 -0
  433. package/resources/gofer/gemini/agents/plan-migration-path-finder.md +98 -0
  434. package/resources/gofer/gemini/agents/plan-refactor-rewrite-advisor.md +100 -0
  435. package/resources/gofer/gemini/agents/research-dependency-evaluator.md +109 -0
  436. package/resources/gofer/gemini/agents/research-horizon-scanner.md +103 -0
  437. package/resources/gofer/gemini/agents/research-market-scanner.md +140 -0
  438. package/resources/gofer/gemini/agents/research-perspective-multiplier.md +105 -0
  439. package/resources/gofer/gemini/agents/scope-creep-detector.md +155 -0
  440. package/resources/gofer/gemini/agents/specify-ambiguity-detector.md +98 -0
  441. package/resources/gofer/gemini/agents/specify-journey-stress-tester.md +95 -0
  442. package/resources/gofer/gemini/agents/tasks-cross-cutting-scanner.md +94 -0
  443. package/resources/gofer/gemini/agents/tasks-rollback-planner.md +92 -0
  444. package/resources/gofer/gemini/agents/validate-security-red-team.md +105 -0
  445. package/resources/gofer/gemini/agents/validation-correctness.md +106 -0
  446. package/resources/gofer/gemini/agents/validation-integration.md +132 -0
  447. package/resources/gofer/gemini/agents/validation-performance.md +123 -0
  448. package/resources/gofer/gemini/agents/validation-security.md +118 -0
  449. package/resources/gofer/gemini/agents/validation-standards.md +154 -0
  450. package/resources/gofer/gemini/agents/validation-test-quality.md +149 -0
  451. package/resources/gofer/gemini/agents/visual-bounded-context-writer.md +40 -0
  452. package/resources/gofer/gemini/agents/visual-c4-writer.md +44 -0
  453. package/resources/gofer/gemini/agents/visual-erd-writer.md +36 -0
  454. package/resources/gofer/gemini/agents/visual-heatmap-writer.md +63 -0
  455. package/resources/gofer/gemini/agents/visual-risk-writer.md +64 -0
  456. package/resources/gofer/gemini/commands/gofer/.gitkeep +0 -0
  457. package/resources/gofer/gemini/commands/gofer/0_gofer_start.md +1282 -0
  458. package/resources/gofer/gemini/commands/gofer/0_gofer_start.toml +2 -0
  459. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.md +424 -0
  460. package/resources/gofer/gemini/commands/gofer/0a_problem_validation.toml +2 -0
  461. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.md +630 -0
  462. package/resources/gofer/gemini/commands/gofer/10_gofer_cloud.toml +2 -0
  463. package/resources/gofer/gemini/commands/gofer/1_gofer_research.md +1154 -0
  464. package/resources/gofer/gemini/commands/gofer/1_gofer_research.toml +2 -0
  465. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.md +855 -0
  466. package/resources/gofer/gemini/commands/gofer/2_gofer_specify.toml +2 -0
  467. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.md +881 -0
  468. package/resources/gofer/gemini/commands/gofer/3_gofer_plan.toml +2 -0
  469. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.md +743 -0
  470. package/resources/gofer/gemini/commands/gofer/4_gofer_tasks.toml +2 -0
  471. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.md +919 -0
  472. package/resources/gofer/gemini/commands/gofer/5_gofer_implement.toml +2 -0
  473. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.md +2264 -0
  474. package/resources/gofer/gemini/commands/gofer/6_gofer_validate.toml +2 -0
  475. package/resources/gofer/gemini/commands/gofer/7_gofer_save.md +418 -0
  476. package/resources/gofer/gemini/commands/gofer/7_gofer_save.toml +2 -0
  477. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.md +503 -0
  478. package/resources/gofer/gemini/commands/gofer/7a_stakeholder_comms.toml +2 -0
  479. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.md +310 -0
  480. package/resources/gofer/gemini/commands/gofer/8_gofer_branding.toml +2 -0
  481. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.md +553 -0
  482. package/resources/gofer/gemini/commands/gofer/9_gofer_tests.toml +2 -0
  483. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.md +143 -0
  484. package/resources/gofer/gemini/commands/gofer/gofer_bootstrap_workspace.toml +2 -0
  485. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.md +114 -0
  486. package/resources/gofer/gemini/commands/gofer/gofer_check_workspace.toml +2 -0
  487. package/resources/gofer/gemini/commands/gofer/gofer_constitution.md +607 -0
  488. package/resources/gofer/gemini/commands/gofer/gofer_constitution.toml +2 -0
  489. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.md +109 -0
  490. package/resources/gofer/gemini/commands/gofer/gofer_diagnose.toml +2 -0
  491. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.md +392 -0
  492. package/resources/gofer/gemini/commands/gofer/gofer_eai_first_run.toml +2 -0
  493. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.md +556 -0
  494. package/resources/gofer/gemini/commands/gofer/gofer_hydrate.toml +2 -0
  495. package/resources/gofer/gemini/commands/gofer/gofer_personality.md +39 -0
  496. package/resources/gofer/gemini/commands/gofer/gofer_personality.toml +2 -0
  497. package/resources/gofer/gemini/commands/gofer/gofer_plan.md +35 -0
  498. package/resources/gofer/gemini/commands/gofer/gofer_plan.toml +2 -0
  499. package/resources/gofer/gemini/commands/gofer/gofer_side.md +40 -0
  500. package/resources/gofer/gemini/commands/gofer/gofer_side.toml +2 -0
  501. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.md +107 -0
  502. package/resources/gofer/gemini/commands/gofer/gofer_spec_summary.toml +2 -0
  503. package/resources/gofer/gemini/commands/gofer/gofer_tdd.md +107 -0
  504. package/resources/gofer/gemini/commands/gofer/gofer_tdd.toml +2 -0
  505. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.md +107 -0
  506. package/resources/gofer/gemini/commands/gofer/gofer_vocabulary.toml +2 -0
  507. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.md +107 -0
  508. package/resources/gofer/gemini/commands/gofer/gofer_zoom_out.toml +2 -0
  509. package/resources/gofer/gemini/commands/gofer/manifest.json +32 -0
  510. package/resources/gofer/gemini/extension.json +16 -0
  511. package/resources/gofer/github-agents/gofer-business.agent.md +20 -0
  512. package/resources/gofer/github-agents/gofer-implement.agent.md +15 -0
  513. package/resources/gofer/github-agents/gofer-plan.agent.md +15 -0
  514. package/resources/gofer/github-agents/gofer-research.agent.md +15 -0
  515. package/resources/gofer/github-agents/gofer-validate.agent.md +10 -0
  516. package/resources/gofer/github-skills/eai-gofer/SKILL.md +56 -0
  517. package/resources/gofer/hook-scripts/agent-stop.mjs +655 -0
  518. package/resources/gofer/hook-scripts/log-stage-launch-time.mjs +77 -0
  519. package/resources/gofer/hook-scripts/post-tool-use.mjs +333 -0
  520. package/resources/gofer/hook-scripts/queued-input.mjs +188 -0
  521. package/resources/gofer/hook-scripts/session-lifecycle.mjs +93 -0
  522. package/resources/gofer/hook-scripts/user-prompt-submit.mjs +228 -0
  523. package/resources/gofer/instruction-templates/base/agents-base.md +37 -0
  524. package/resources/gofer/instruction-templates/base/claude-base.md +7 -0
  525. package/resources/gofer/instruction-templates/base/copilot-base.md +26 -0
  526. package/resources/gofer/instruction-templates/gofer/gofer-claude.md +5 -0
  527. package/resources/gofer/instruction-templates/gofer/gofer-copilot.md +9 -0
  528. package/resources/gofer/instruction-templates/languages/generic.md +7 -0
  529. package/resources/gofer/instruction-templates/languages/go.md +8 -0
  530. package/resources/gofer/instruction-templates/languages/java.md +8 -0
  531. package/resources/gofer/instruction-templates/languages/python.md +9 -0
  532. package/resources/gofer/instruction-templates/languages/rust.md +9 -0
  533. package/resources/gofer/instruction-templates/languages/typescript.md +19 -0
  534. package/resources/gofer/instruction-templates/workflow/principles.md +52 -0
  535. package/resources/gofer/memory/constitution.md +391 -0
  536. package/resources/gofer/memory/context-profiles.yaml +74 -0
  537. package/resources/gofer/memory/decisions/000-use-adr-for-decisions.md +67 -0
  538. package/resources/gofer/memory/decisions/001-di-framework.md +190 -0
  539. package/resources/gofer/memory/decisions/002-module-extraction.md +305 -0
  540. package/resources/gofer/memory/decisions/003-error-handling.md +368 -0
  541. package/resources/gofer/memory/decisions/004-cache-eviction.md +436 -0
  542. package/resources/gofer/memory/decisions/005-constants-management.md +520 -0
  543. package/resources/gofer/memory/decisions/README.md +129 -0
  544. package/resources/gofer/memory/diagrams/di-container.mmd +321 -0
  545. package/resources/gofer/memory/diagrams/extension-activation.mmd +184 -0
  546. package/resources/gofer/memory/diagrams/module-dependencies.mmd +264 -0
  547. package/resources/gofer/memory/gofer-model-policy.yaml +97 -0
  548. package/resources/gofer/memory/lessons.md +46 -0
  549. package/resources/gofer/node-scripts/canonical-descriptions.mjs +86 -0
  550. package/resources/gofer/node-scripts/check-version-alignment.mjs +131 -0
  551. package/resources/gofer/node-scripts/codex-doctor.mjs +425 -0
  552. package/resources/gofer/node-scripts/generate-commands.mjs +1366 -0
  553. package/resources/gofer/node-scripts/generate-issues.js +563 -0
  554. package/resources/gofer/node-scripts/gofer-closed-loop-audit.mjs +893 -0
  555. package/resources/gofer/node-scripts/gofer-loop-audit.mjs +541 -0
  556. package/resources/gofer/node-scripts/gofer-performance-report.mjs +306 -0
  557. package/resources/gofer/node-scripts/gofer-workspace-bootstrap.mjs +56 -0
  558. package/resources/gofer/node-scripts/gofer-workspace-check.mjs +56 -0
  559. package/resources/gofer/node-scripts/lib/ai-leverage-tagger.mjs +103 -0
  560. package/resources/gofer/node-scripts/lib/assemble-stakeholder-pack.mjs +114 -0
  561. package/resources/gofer/node-scripts/lib/marp-deck.mjs +87 -0
  562. package/resources/gofer/node-scripts/lib/mermaid-tabular-fallback.mjs +264 -0
  563. package/resources/gofer/node-scripts/lib/render-visual.mjs +54 -0
  564. package/resources/gofer/node-scripts/lib/validate-aliases.mjs +85 -0
  565. package/resources/gofer/node-scripts/lib/visual-counts.mjs +44 -0
  566. package/resources/gofer/node-scripts/lib/visual-pass-pipeline.mjs +134 -0
  567. package/resources/gofer/node-scripts/mermaid-export.mjs +72 -0
  568. package/resources/gofer/node-scripts/package-agent-plugin.mjs +940 -0
  569. package/resources/gofer/node-scripts/parse-stage-command.mjs +211 -0
  570. package/resources/gofer/node-scripts/schemas/.gitkeep +0 -0
  571. package/resources/gofer/node-scripts/schemas/stage-command.schema.json +72 -0
  572. package/resources/gofer/node-scripts/sync-extension-resources.mjs +110 -0
  573. package/resources/gofer/node-scripts/workspace-bootstrap-lib.mjs +1166 -0
  574. package/resources/gofer/powershell-scripts/install-optional-tools.ps1 +214 -0
  575. package/resources/gofer/references/platform/README.md +17 -0
  576. package/resources/gofer/references/platform/deployment-repo.md +9 -0
  577. package/resources/gofer/references/platform/eai-app-template.md +45 -0
  578. package/resources/gofer/references/platform/eai-config-driven-ui.md +156 -0
  579. package/resources/gofer/references/platform/eai-error-catalog.yaml +197 -0
  580. package/resources/gofer/references/platform/eai-repo-contract.md +134 -0
  581. package/resources/gofer/references/platform/eai-service-patterns.md +56 -0
  582. package/resources/gofer/references/platform/eai.md +85 -0
  583. package/resources/gofer/references/platform/vertical-template.md +49 -0
  584. package/resources/gofer/specify-commands/.gitkeep +0 -0
  585. package/resources/gofer/specify-commands/0_gofer_start.md +1299 -0
  586. package/resources/gofer/specify-commands/0a_problem_validation.md +405 -0
  587. package/resources/gofer/specify-commands/10_gofer_cloud.md +611 -0
  588. package/resources/gofer/specify-commands/1_gofer_research.md +1135 -0
  589. package/resources/gofer/specify-commands/2_gofer_specify.md +836 -0
  590. package/resources/gofer/specify-commands/3_gofer_plan.md +862 -0
  591. package/resources/gofer/specify-commands/4_gofer_tasks.md +724 -0
  592. package/resources/gofer/specify-commands/5_gofer_implement.md +900 -0
  593. package/resources/gofer/specify-commands/6_gofer_validate.md +2245 -0
  594. package/resources/gofer/specify-commands/7_gofer_save.md +399 -0
  595. package/resources/gofer/specify-commands/7a_stakeholder_comms.md +484 -0
  596. package/resources/gofer/specify-commands/8_gofer_branding.md +291 -0
  597. package/resources/gofer/specify-commands/9_gofer_tests.md +534 -0
  598. package/resources/gofer/specify-commands/gofer_bootstrap_workspace.md +159 -0
  599. package/resources/gofer/specify-commands/gofer_check_workspace.md +130 -0
  600. package/resources/gofer/specify-commands/gofer_constitution.md +588 -0
  601. package/resources/gofer/specify-commands/gofer_diagnose.md +89 -0
  602. package/resources/gofer/specify-commands/gofer_eai_first_run.md +392 -0
  603. package/resources/gofer/specify-commands/gofer_hydrate.md +537 -0
  604. package/resources/gofer/specify-commands/gofer_personality.md +61 -0
  605. package/resources/gofer/specify-commands/gofer_plan.md +51 -0
  606. package/resources/gofer/specify-commands/gofer_side.md +56 -0
  607. package/resources/gofer/specify-commands/gofer_spec_summary.md +87 -0
  608. package/resources/gofer/specify-commands/gofer_tdd.md +87 -0
  609. package/resources/gofer/specify-commands/gofer_vocabulary.md +87 -0
  610. package/resources/gofer/specify-commands/gofer_zoom_out.md +87 -0
  611. package/resources/gofer/system-skills/0_gofer_start/SKILL.md +1287 -0
  612. package/resources/gofer/system-skills/0a_problem_validation/SKILL.md +429 -0
  613. package/resources/gofer/system-skills/10_gofer_cloud/SKILL.md +635 -0
  614. package/resources/gofer/system-skills/1_gofer_research/SKILL.md +1159 -0
  615. package/resources/gofer/system-skills/2_gofer_specify/SKILL.md +860 -0
  616. package/resources/gofer/system-skills/3_gofer_plan/SKILL.md +886 -0
  617. package/resources/gofer/system-skills/4_gofer_tasks/SKILL.md +748 -0
  618. package/resources/gofer/system-skills/5_gofer_implement/SKILL.md +924 -0
  619. package/resources/gofer/system-skills/6_gofer_validate/SKILL.md +2269 -0
  620. package/resources/gofer/system-skills/7_gofer_save/SKILL.md +423 -0
  621. package/resources/gofer/system-skills/7a_stakeholder_comms/SKILL.md +508 -0
  622. package/resources/gofer/system-skills/8_gofer_branding/SKILL.md +315 -0
  623. package/resources/gofer/system-skills/9_gofer_tests/SKILL.md +558 -0
  624. package/resources/gofer/system-skills/gofer_bootstrap_workspace/SKILL.md +148 -0
  625. package/resources/gofer/system-skills/gofer_check_workspace/SKILL.md +119 -0
  626. package/resources/gofer/system-skills/gofer_constitution/SKILL.md +612 -0
  627. package/resources/gofer/system-skills/gofer_diagnose/SKILL.md +114 -0
  628. package/resources/gofer/system-skills/gofer_eai_first_run/SKILL.md +397 -0
  629. package/resources/gofer/system-skills/gofer_hydrate/SKILL.md +561 -0
  630. package/resources/gofer/system-skills/gofer_personality/SKILL.md +44 -0
  631. package/resources/gofer/system-skills/gofer_plan/SKILL.md +40 -0
  632. package/resources/gofer/system-skills/gofer_side/SKILL.md +45 -0
  633. package/resources/gofer/system-skills/gofer_spec_summary/SKILL.md +112 -0
  634. package/resources/gofer/system-skills/gofer_tdd/SKILL.md +112 -0
  635. package/resources/gofer/system-skills/gofer_vocabulary/SKILL.md +112 -0
  636. package/resources/gofer/system-skills/gofer_zoom_out/SKILL.md +112 -0
  637. package/resources/gofer/templates/agent-file-template.md +28 -0
  638. package/resources/gofer/templates/assumptions-template.md +94 -0
  639. package/resources/gofer/templates/audit-history-template.md +35 -0
  640. package/resources/gofer/templates/brand/brand-profile-template.json +45 -0
  641. package/resources/gofer/templates/brand/document-style-template.md +50 -0
  642. package/resources/gofer/templates/brand/marp-theme-template.css +58 -0
  643. package/resources/gofer/templates/brownfield-analysis.md +44 -0
  644. package/resources/gofer/templates/business-metrics-template.md +120 -0
  645. package/resources/gofer/templates/business-owner-summary-template.md +83 -0
  646. package/resources/gofer/templates/checklist-template.md +40 -0
  647. package/resources/gofer/templates/ciso-security-summary-template.md +70 -0
  648. package/resources/gofer/templates/context-bundle-template.md +76 -0
  649. package/resources/gofer/templates/contract-pack-template.md +109 -0
  650. package/resources/gofer/templates/cto-architecture-summary-template.md +83 -0
  651. package/resources/gofer/templates/discovery-template.md +92 -0
  652. package/resources/gofer/templates/eai-preflight-template.md +144 -0
  653. package/resources/gofer/templates/goal-ledger-template.json +69 -0
  654. package/resources/gofer/templates/gofer-model-policy.yaml +97 -0
  655. package/resources/gofer/templates/issues-template.md +106 -0
  656. package/resources/gofer/templates/journey/base-journey.md +95 -0
  657. package/resources/gofer/templates/journey/industry-variants.yaml +277 -0
  658. package/resources/gofer/templates/loop-contract-template.json +68 -0
  659. package/resources/gofer/templates/plan-template.md +215 -0
  660. package/resources/gofer/templates/problem-brief-template.md +85 -0
  661. package/resources/gofer/templates/proposal-review-template.md +79 -0
  662. package/resources/gofer/templates/research-template.md +222 -0
  663. package/resources/gofer/templates/reuse-scan-template.md +43 -0
  664. package/resources/gofer/templates/sequence-diagrams/option-spectrum.yaml +178 -0
  665. package/resources/gofer/templates/service-fit-matrix-template.md +29 -0
  666. package/resources/gofer/templates/session-handoff-template.md +172 -0
  667. package/resources/gofer/templates/spec-summary-template.md +118 -0
  668. package/resources/gofer/templates/spec-template.md +196 -0
  669. package/resources/gofer/templates/stakeholder-comms-template.md +330 -0
  670. package/resources/gofer/templates/stakeholder-review-index-template.md +54 -0
  671. package/resources/gofer/templates/tasks-template.md +323 -0
  672. package/resources/gofer/templates/ui-approval-template.md +32 -0
  673. package/resources/gofer/templates/ui-preview-brief-template.md +65 -0
  674. package/resources/gofer/templates/ui-review-log-template.md +11 -0
  675. package/resources/gofer/templates/visuals/.gitkeep +0 -0
  676. package/resources/gofer/templates/visuals/bounded-context-map.md +19 -0
  677. package/resources/gofer/templates/visuals/bounded-context-template.md +47 -0
  678. package/resources/gofer/templates/visuals/c4-container-template.md +38 -0
  679. package/resources/gofer/templates/visuals/c4-container.md +20 -0
  680. package/resources/gofer/templates/visuals/c4-context-template.md +46 -0
  681. package/resources/gofer/templates/visuals/capability-heatmap-template.md +54 -0
  682. package/resources/gofer/templates/visuals/data-model-erd-template.md +41 -0
  683. package/resources/gofer/templates/visuals/erd.md +19 -0
  684. package/resources/gofer/templates/visuals/impact-canvas.md +40 -0
  685. package/resources/gofer/templates/visuals/risk-heatmap-template.md +51 -0
  686. package/resources/gofer/templates/visuals/roi-projection.md +17 -0
  687. package/resources/gofer/templates/visuals/value-stream-asis.md +16 -0
  688. package/resources/gofer/templates/visuals/value-stream-tobe.md +18 -0
  689. package/resources/gofer/templates/working-backwards-prfaq-template.md +165 -0
  690. package/resources/linked-sources.json +25 -0
@@ -0,0 +1,1442 @@
1
+ /**
2
+ * eai verify — run platform connectivity checks.
3
+ * eai doctor — comprehensive diagnostics with fix suggestions.
4
+ */
5
+ import { Command } from "commander";
6
+ import { randomUUID } from "node:crypto";
7
+ import { access } from "node:fs/promises";
8
+ import { createRequire } from "node:module";
9
+ import { join } from "node:path";
10
+ import ora from "ora";
11
+ import chalk from "chalk";
12
+ import { findProjectRoot, loadEnvFile, loadObjectTypes, } from "../lib/config.js";
13
+ import { isAuthenticated, loadTokens } from "../lib/auth.js";
14
+ import { PlatformAPIClient } from "../lib/api.js";
15
+ import { normalizeTenantEntries, resolveActiveTenantContext, resolvePublicApiUrl, } from "../lib/tenant-context.js";
16
+ import { isRecord } from "../lib/utils.js";
17
+ import * as out from "../lib/output.js";
18
+ import { ErrorCode, exitWithError } from "../lib/error-codes.js";
19
+ import { findGuidance } from "../lib/error-guidance/match.js";
20
+ import { compareVersions, fetchLatestRelease } from "../lib/update-check.js";
21
+ import { readGoferBundleMetadata } from "../lib/gofer-refresh.js";
22
+ import { resolveProjectManifest } from "../lib/project-manifest.js";
23
+ import { isDefaultTemplateSource, resolveTemplateClonePlan } from "./init.js";
24
+ const require = createRequire(import.meta.url);
25
+ const pkg = require("../../package.json");
26
+ const DEFAULT_TEMPLATE_SOURCE = "https://github.com/eai-tools/eai-app-template.git";
27
+ async function loadVerifyEnvironment(options) {
28
+ const root = await findProjectRoot();
29
+ if (!root) {
30
+ exitWithError(ErrorCode.E001);
31
+ }
32
+ const envVars = await loadEnvFile(root);
33
+ const env = { ...envVars, ...process.env };
34
+ let publicApiUrl = await resolvePublicApiUrl(root);
35
+ let tenantId = options?.tenantId;
36
+ if (tenantId) {
37
+ const activeContext = await resolveActiveTenantContext({
38
+ projectRoot: root,
39
+ publicApiUrl,
40
+ tenantId,
41
+ interactive: false,
42
+ forceRefresh: true,
43
+ });
44
+ tenantId = activeContext.activeTenant.id;
45
+ publicApiUrl = activeContext.publicApiUrl;
46
+ }
47
+ else {
48
+ try {
49
+ const activeContext = await resolveActiveTenantContext({
50
+ projectRoot: root,
51
+ publicApiUrl,
52
+ interactive: false,
53
+ });
54
+ tenantId = activeContext.activeTenant.id;
55
+ }
56
+ catch {
57
+ tenantId = undefined;
58
+ }
59
+ }
60
+ return {
61
+ root,
62
+ env,
63
+ publicApiUrl,
64
+ tenantId,
65
+ workflowId: env.WORKFLOW_DEFAULT_ID ||
66
+ Object.keys(env)
67
+ .filter((key) => key.startsWith("WORKFLOW_") && key.endsWith("_ID"))
68
+ .map((key) => env[key])
69
+ .find(Boolean),
70
+ };
71
+ }
72
+ function extractTenantIdOption(options) {
73
+ if (typeof options?.tenantId === "string" && options.tenantId.trim()) {
74
+ return options.tenantId.trim();
75
+ }
76
+ const parentTenantId = verifyCommand.opts()?.tenantId;
77
+ if (typeof parentTenantId === "string" && parentTenantId.trim()) {
78
+ return parentTenantId.trim();
79
+ }
80
+ const equalsArg = process.argv.find((arg) => arg.startsWith("--tenant-id="));
81
+ if (equalsArg) {
82
+ return equalsArg.slice("--tenant-id=".length).trim();
83
+ }
84
+ const index = process.argv.indexOf("--tenant-id");
85
+ if (index >= 0 && process.argv[index + 1]) {
86
+ return process.argv[index + 1].trim();
87
+ }
88
+ return undefined;
89
+ }
90
+ async function parseJsonBody(res) {
91
+ const text = await res.text();
92
+ if (!text) {
93
+ return null;
94
+ }
95
+ try {
96
+ return JSON.parse(text);
97
+ }
98
+ catch {
99
+ throw new Error(`Expected JSON response but received: ${text.slice(0, 120)}`);
100
+ }
101
+ }
102
+ function addCheck(checks, check) {
103
+ checks.push(check);
104
+ }
105
+ function summarizeChecks(checks) {
106
+ return checks.reduce((summary, check) => {
107
+ summary[check.status]++;
108
+ return summary;
109
+ }, {
110
+ passed: 0,
111
+ failed: 0,
112
+ skipped: 0,
113
+ });
114
+ }
115
+ function describeShape(value) {
116
+ if (Array.isArray(value)) {
117
+ return "array";
118
+ }
119
+ if (isRecord(value)) {
120
+ return `object keys: ${Object.keys(value).join(", ") || "(none)"}`;
121
+ }
122
+ if (value === null) {
123
+ return "null";
124
+ }
125
+ return typeof value;
126
+ }
127
+ function extractSchemaTypeCount(payload) {
128
+ if (!isRecord(payload)) {
129
+ return 0;
130
+ }
131
+ if (Array.isArray(payload.objectTypes)) {
132
+ return payload.objectTypes.length;
133
+ }
134
+ if (Array.isArray(payload.object_types)) {
135
+ return payload.object_types.length;
136
+ }
137
+ if (!Array.isArray(payload.docs)) {
138
+ return 0;
139
+ }
140
+ return payload.docs.filter((value) => isRecord(value) &&
141
+ (value.status === "published" ||
142
+ (value.publishedAt !== null && value.publishedAt !== undefined))).length;
143
+ }
144
+ function renderContractAudit(report) {
145
+ out.heading("Platform Call Audit");
146
+ out.info(`PublicAPI: ${report.publicApiUrl}`);
147
+ if (report.tenantId) {
148
+ out.info(`Tenant: ${report.tenantId}`);
149
+ }
150
+ if (report.workflowId) {
151
+ out.info(`Workflow: ${report.workflowId}`);
152
+ }
153
+ out.blank();
154
+ for (const check of report.checks) {
155
+ const icon = check.status === "passed"
156
+ ? out.symbols.success
157
+ : check.status === "failed"
158
+ ? out.symbols.error
159
+ : out.symbols.warning;
160
+ out.info(`${icon} ${check.label}`);
161
+ out.dim(` ${check.method} ${check.endpoint}`);
162
+ out.dim(` ${check.details}`);
163
+ }
164
+ out.blank();
165
+ if (report.summary.failed === 0) {
166
+ out.success(`${report.summary.passed} passed, ${report.summary.skipped} skipped`);
167
+ }
168
+ else {
169
+ out.warn(`${report.summary.passed} passed, ${report.summary.failed} failed, ${report.summary.skipped} skipped`);
170
+ }
171
+ }
172
+ function collectPublishedStorageBackends(objectTypesByScope) {
173
+ const backends = new Set();
174
+ const invalid = new Set();
175
+ const allowed = new Set(["postgresql", "documentdb", "blob", "search"]);
176
+ for (const types of Object.values(objectTypesByScope)) {
177
+ for (const objectType of types) {
178
+ if (objectType.status && objectType.status !== "published") {
179
+ continue;
180
+ }
181
+ if (!objectType.storageBackend) {
182
+ continue;
183
+ }
184
+ backends.add(objectType.storageBackend);
185
+ if (!allowed.has(objectType.storageBackend)) {
186
+ invalid.add(objectType.storageBackend);
187
+ }
188
+ }
189
+ }
190
+ return {
191
+ backends: [...backends].sort(),
192
+ invalid: [...invalid].sort(),
193
+ };
194
+ }
195
+ export async function runContractAudit(options) {
196
+ const context = await loadVerifyEnvironment({ tenantId: options.tenantId });
197
+ const checks = [];
198
+ let remoteObjectTypeCount = null;
199
+ const workflowId = options.workflowId || context.workflowId;
200
+ const stage = options.stage || "chat";
201
+ const client = context.tenantId
202
+ ? new PlatformAPIClient(context.publicApiUrl, context.tenantId)
203
+ : null;
204
+ const systemClient = new PlatformAPIClient(context.publicApiUrl, "system");
205
+ // Public API health
206
+ try {
207
+ const start = Date.now();
208
+ const res = await fetch(`${context.publicApiUrl}/health`, {
209
+ signal: AbortSignal.timeout(10_000),
210
+ });
211
+ const latency = Date.now() - start;
212
+ if (res.ok || res.status === 404) {
213
+ addCheck(checks, {
214
+ id: "health",
215
+ label: "PublicAPI health",
216
+ method: "GET",
217
+ endpoint: "/health",
218
+ status: "passed",
219
+ details: `Reachable in ${latency}ms (status ${res.status})`,
220
+ });
221
+ }
222
+ else {
223
+ addCheck(checks, {
224
+ id: "health",
225
+ label: "PublicAPI health",
226
+ method: "GET",
227
+ endpoint: "/health",
228
+ status: "failed",
229
+ details: `Unexpected status ${res.status}`,
230
+ });
231
+ }
232
+ }
233
+ catch (err) {
234
+ addCheck(checks, {
235
+ id: "health",
236
+ label: "PublicAPI health",
237
+ method: "GET",
238
+ endpoint: "/health",
239
+ status: "failed",
240
+ details: err instanceof Error ? err.message : String(err),
241
+ });
242
+ }
243
+ const authenticated = await isAuthenticated();
244
+ const tokens = await loadTokens();
245
+ addCheck(checks, {
246
+ id: "auth",
247
+ label: "Authentication token",
248
+ method: "LOCAL",
249
+ endpoint: "~/.eai/tokens.json or EAI_ACCESS_TOKEN",
250
+ status: authenticated ? "passed" : "failed",
251
+ details: authenticated
252
+ ? `Authenticated as ${tokens?.upn || (process.env.EAI_ACCESS_TOKEN ? "injected access token" : "user")}`
253
+ : "Not authenticated. Run `eai login` or set EAI_ACCESS_TOKEN.",
254
+ });
255
+ try {
256
+ const localTypes = await loadObjectTypes(context.root);
257
+ const backendSummary = collectPublishedStorageBackends(localTypes);
258
+ if (backendSummary.invalid.length > 0) {
259
+ throw new Error(`Unsupported storageBackend value(s): ${backendSummary.invalid.join(", ")}. Use postgresql, documentdb, blob, or search.`);
260
+ }
261
+ addCheck(checks, {
262
+ id: "backend-config",
263
+ label: "Local backend contract",
264
+ method: "LOCAL",
265
+ endpoint: "src/eai.config/object-types.ts",
266
+ status: "passed",
267
+ details: backendSummary.backends.length > 0
268
+ ? `Published local backends: ${backendSummary.backends.join(", ")}`
269
+ : "No explicit storageBackend declarations found; default PostgreSQL routing remains valid.",
270
+ });
271
+ }
272
+ catch (err) {
273
+ addCheck(checks, {
274
+ id: "backend-config",
275
+ label: "Local backend contract",
276
+ method: "LOCAL",
277
+ endpoint: "src/eai.config/object-types.ts",
278
+ status: "failed",
279
+ details: err instanceof Error ? err.message : String(err),
280
+ });
281
+ }
282
+ if (!authenticated) {
283
+ const skippedDueToAuth = [
284
+ [
285
+ "current-user",
286
+ "Tenant membership contract",
287
+ "GET",
288
+ "/v4/platform/users/{oid}/memberships",
289
+ ],
290
+ [
291
+ "object-types",
292
+ "Object Types list contract",
293
+ "GET",
294
+ "/v4/data/resources/object-types",
295
+ ],
296
+ ["schema", "Schema contract", "GET", "/v4/data/resources/schema/{tenantId}"],
297
+ ];
298
+ for (const [id, label, method, endpoint] of skippedDueToAuth) {
299
+ addCheck(checks, {
300
+ id,
301
+ label,
302
+ method,
303
+ endpoint,
304
+ status: "skipped",
305
+ details: "Skipped because authentication is required.",
306
+ });
307
+ }
308
+ }
309
+ else if (!context.tenantId || !client) {
310
+ const skippedDueToTenant = [
311
+ [
312
+ "current-user",
313
+ "Tenant membership contract",
314
+ "GET",
315
+ "/v4/platform/users/{oid}/memberships",
316
+ ],
317
+ [
318
+ "object-types",
319
+ "Object Types list contract",
320
+ "GET",
321
+ "/v4/data/resources/object-types",
322
+ ],
323
+ ["schema", "Schema contract", "GET", "/v4/data/resources/schema/{tenantId}"],
324
+ ];
325
+ for (const [id, label, method, endpoint] of skippedDueToTenant) {
326
+ addCheck(checks, {
327
+ id,
328
+ label,
329
+ method,
330
+ endpoint,
331
+ status: "skipped",
332
+ details: "Skipped because no active tenant is selected. Run `eai tenant select`.",
333
+ });
334
+ }
335
+ }
336
+ else {
337
+ try {
338
+ const res = await systemClient.getUserMemberships(tokens?.oid || "");
339
+ if (!res.ok) {
340
+ throw new Error(`HTTP ${res.status}`);
341
+ }
342
+ const payload = await parseJsonBody(res);
343
+ const tenantEntries = normalizeTenantEntries(payload);
344
+ if (tenantEntries.length === 0) {
345
+ throw new Error("Expected tenant membership entries in response");
346
+ }
347
+ addCheck(checks, {
348
+ id: "current-user",
349
+ label: "Tenant membership contract",
350
+ method: "GET",
351
+ endpoint: "/v4/platform/users/{oid}/memberships",
352
+ status: "passed",
353
+ details: `Tenant entries: ${tenantEntries.length}`,
354
+ });
355
+ }
356
+ catch (err) {
357
+ addCheck(checks, {
358
+ id: "current-user",
359
+ label: "Tenant membership contract",
360
+ method: "GET",
361
+ endpoint: "/v4/platform/users/{oid}/memberships",
362
+ status: "failed",
363
+ details: err instanceof Error ? err.message : String(err),
364
+ });
365
+ }
366
+ try {
367
+ const res = await client.getPublishedObjectTypes({ limit: 1 });
368
+ if (!res.ok) {
369
+ throw new Error(`HTTP ${res.status}`);
370
+ }
371
+ const payload = await parseJsonBody(res);
372
+ if (!isRecord(payload) || !Array.isArray(payload.docs)) {
373
+ throw new Error("Expected docs[] in Object Types response");
374
+ }
375
+ addCheck(checks, {
376
+ id: "object-types",
377
+ label: "Object Types list contract",
378
+ method: "GET",
379
+ endpoint: "/v4/data/resources/object-types",
380
+ status: "passed",
381
+ details: `Response includes docs[] (${payload.docs.length} item(s) in sample)`,
382
+ });
383
+ remoteObjectTypeCount = payload.docs.length;
384
+ }
385
+ catch (err) {
386
+ addCheck(checks, {
387
+ id: "object-types",
388
+ label: "Object Types list contract",
389
+ method: "GET",
390
+ endpoint: "/v4/data/resources/object-types",
391
+ status: "failed",
392
+ details: err instanceof Error ? err.message : String(err),
393
+ });
394
+ }
395
+ try {
396
+ const res = await client.getSchema();
397
+ if (!res.ok) {
398
+ throw new Error(`HTTP ${res.status}`);
399
+ }
400
+ const payload = await parseJsonBody(res);
401
+ const typeCount = extractSchemaTypeCount(payload);
402
+ remoteObjectTypeCount = remoteObjectTypeCount ?? typeCount;
403
+ if (typeCount === 0 &&
404
+ (!isRecord(payload) || !Array.isArray(payload.docs))) {
405
+ throw new Error("Expected published Object Types in response");
406
+ }
407
+ addCheck(checks, {
408
+ id: "schema",
409
+ label: "Schema contract",
410
+ method: "GET",
411
+ endpoint: `/v4/data/resources/schema/${context.tenantId}`,
412
+ status: "passed",
413
+ details: `Published schema present (${typeCount} published type(s))`,
414
+ });
415
+ }
416
+ catch (err) {
417
+ addCheck(checks, {
418
+ id: "schema",
419
+ label: "Schema contract",
420
+ method: "GET",
421
+ endpoint: `/v4/data/resources/schema/${context.tenantId}`,
422
+ status: "failed",
423
+ details: err instanceof Error ? err.message : String(err),
424
+ });
425
+ }
426
+ }
427
+ if (authenticated && client && options.resourceType) {
428
+ if (remoteObjectTypeCount === 0) {
429
+ addCheck(checks, {
430
+ id: "resource-list",
431
+ label: "Resource list contract",
432
+ method: "GET",
433
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}",
434
+ status: "skipped",
435
+ details: "Skipped because the active tenant has no published Object Types remotely.",
436
+ });
437
+ addCheck(checks, {
438
+ id: "resource-query",
439
+ label: "Resource query contract",
440
+ method: "POST",
441
+ endpoint: "/v4/data/resources/{tenantId}/query",
442
+ status: "skipped",
443
+ details: "Skipped because the active tenant has no published Object Types remotely.",
444
+ });
445
+ addCheck(checks, {
446
+ id: "resource-cursor",
447
+ label: "Resource cursor contract",
448
+ method: "GET",
449
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}?cursor=...",
450
+ status: "skipped",
451
+ details: "Skipped because the active tenant has no published Object Types remotely.",
452
+ });
453
+ addCheck(checks, {
454
+ id: "resource-aggregate",
455
+ label: "Resource aggregate contract",
456
+ method: "POST",
457
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}/aggregate",
458
+ status: "skipped",
459
+ details: "Skipped because the active tenant has no published Object Types remotely.",
460
+ });
461
+ }
462
+ else {
463
+ let resourceListPayload = null;
464
+ try {
465
+ const res = await client.listResources(options.resourceType, {
466
+ limit: 1,
467
+ page: 1,
468
+ });
469
+ if (!res.ok) {
470
+ throw new Error(`HTTP ${res.status}`);
471
+ }
472
+ const payload = await parseJsonBody(res);
473
+ if (!isRecord(payload) || !Array.isArray(payload.docs)) {
474
+ throw new Error("Expected docs[] in list response");
475
+ }
476
+ resourceListPayload = payload;
477
+ addCheck(checks, {
478
+ id: "resource-list",
479
+ label: "Resource list contract",
480
+ method: "GET",
481
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}`,
482
+ status: "passed",
483
+ details: `docs[] present (${payload.docs.length} item(s) in sample)`,
484
+ });
485
+ }
486
+ catch (err) {
487
+ addCheck(checks, {
488
+ id: "resource-list",
489
+ label: "Resource list contract",
490
+ method: "GET",
491
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}`,
492
+ status: "failed",
493
+ details: err instanceof Error ? err.message : String(err),
494
+ });
495
+ }
496
+ const nextCursor = typeof resourceListPayload?.nextCursor === "string"
497
+ ? resourceListPayload.nextCursor
498
+ : null;
499
+ if (!nextCursor) {
500
+ addCheck(checks, {
501
+ id: "resource-cursor",
502
+ label: "Resource cursor contract",
503
+ method: "GET",
504
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}?cursor=...`,
505
+ status: "skipped",
506
+ details: "Skipped because the sample list response did not return a nextCursor.",
507
+ });
508
+ }
509
+ else {
510
+ try {
511
+ const res = await client.listResources(options.resourceType, {
512
+ limit: 1,
513
+ cursor: nextCursor,
514
+ });
515
+ if (!res.ok) {
516
+ throw new Error(`HTTP ${res.status}`);
517
+ }
518
+ const payload = await parseJsonBody(res);
519
+ if (!isRecord(payload) ||
520
+ (!("nextCursor" in payload) && !("docs" in payload))) {
521
+ throw new Error("Expected docs[] and optional nextCursor in cursor list response");
522
+ }
523
+ addCheck(checks, {
524
+ id: "resource-cursor",
525
+ label: "Resource cursor contract",
526
+ method: "GET",
527
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}?cursor=...`,
528
+ status: "passed",
529
+ details: `Cursor-aware list response shape: ${describeShape(payload)}`,
530
+ });
531
+ }
532
+ catch (err) {
533
+ addCheck(checks, {
534
+ id: "resource-cursor",
535
+ label: "Resource cursor contract",
536
+ method: "GET",
537
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}?cursor=...`,
538
+ status: "failed",
539
+ details: err instanceof Error ? err.message : String(err),
540
+ });
541
+ }
542
+ }
543
+ try {
544
+ const res = await client.queryResources({
545
+ object_types: [options.resourceType],
546
+ limit: 1,
547
+ });
548
+ if (!res.ok) {
549
+ throw new Error(`HTTP ${res.status}`);
550
+ }
551
+ const payload = await parseJsonBody(res);
552
+ if (!isRecord(payload)) {
553
+ throw new Error(`Expected object, received ${describeShape(payload)}`);
554
+ }
555
+ addCheck(checks, {
556
+ id: "resource-query",
557
+ label: "Resource query contract",
558
+ method: "POST",
559
+ endpoint: `/v4/data/resources/${context.tenantId}/query`,
560
+ status: "passed",
561
+ details: describeShape(payload),
562
+ });
563
+ }
564
+ catch (err) {
565
+ addCheck(checks, {
566
+ id: "resource-query",
567
+ label: "Resource query contract",
568
+ method: "POST",
569
+ endpoint: `/v4/data/resources/${context.tenantId}/query`,
570
+ status: "failed",
571
+ details: err instanceof Error ? err.message : String(err),
572
+ });
573
+ }
574
+ try {
575
+ const res = await client.aggregateResources(options.resourceType, {
576
+ groupBy: ["id"],
577
+ metrics: {
578
+ count: { function: "count" },
579
+ },
580
+ limit: 1,
581
+ });
582
+ if (!res.ok) {
583
+ throw new Error(`HTTP ${res.status}`);
584
+ }
585
+ const payload = await parseJsonBody(res);
586
+ if (!isRecord(payload) || !Array.isArray(payload.rows)) {
587
+ throw new Error("Expected rows[] in aggregate response");
588
+ }
589
+ addCheck(checks, {
590
+ id: "resource-aggregate",
591
+ label: "Resource aggregate contract",
592
+ method: "POST",
593
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}/aggregate`,
594
+ status: "passed",
595
+ details: `rows[] present (${payload.rows.length} row(s) in sample)`,
596
+ });
597
+ }
598
+ catch (err) {
599
+ addCheck(checks, {
600
+ id: "resource-aggregate",
601
+ label: "Resource aggregate contract",
602
+ method: "POST",
603
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}/aggregate`,
604
+ status: "failed",
605
+ details: err instanceof Error ? err.message : String(err),
606
+ });
607
+ }
608
+ }
609
+ }
610
+ else {
611
+ addCheck(checks, {
612
+ id: "resource-list",
613
+ label: "Resource list contract",
614
+ method: "GET",
615
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}",
616
+ status: "skipped",
617
+ details: "Provide --resource-type to exercise list/query contracts.",
618
+ });
619
+ addCheck(checks, {
620
+ id: "resource-query",
621
+ label: "Resource query contract",
622
+ method: "POST",
623
+ endpoint: "/v4/data/resources/{tenantId}/query",
624
+ status: "skipped",
625
+ details: "Provide --resource-type to exercise query contract.",
626
+ });
627
+ addCheck(checks, {
628
+ id: "resource-cursor",
629
+ label: "Resource cursor contract",
630
+ method: "GET",
631
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}?cursor=...",
632
+ status: "skipped",
633
+ details: "Provide --resource-type to exercise cursor contract.",
634
+ });
635
+ addCheck(checks, {
636
+ id: "resource-aggregate",
637
+ label: "Resource aggregate contract",
638
+ method: "POST",
639
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}/aggregate",
640
+ status: "skipped",
641
+ details: "Provide --resource-type to exercise aggregate contract.",
642
+ });
643
+ }
644
+ if (authenticated && client && options.resourceType && options.resourceId) {
645
+ if (remoteObjectTypeCount === 0) {
646
+ addCheck(checks, {
647
+ id: "resource-get",
648
+ label: "Resource get contract",
649
+ method: "GET",
650
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}/{id}",
651
+ status: "skipped",
652
+ details: "Skipped because the active tenant has no published Object Types remotely.",
653
+ });
654
+ }
655
+ else {
656
+ try {
657
+ const res = await client.getResource(options.resourceType, options.resourceId);
658
+ if (!res.ok) {
659
+ throw new Error(`HTTP ${res.status}`);
660
+ }
661
+ const payload = await parseJsonBody(res);
662
+ if (!isRecord(payload) ||
663
+ !("id" in payload) ||
664
+ !("data" in payload) ||
665
+ typeof payload.version !== "number") {
666
+ throw new Error("Expected id, data, and numeric version in resource payload");
667
+ }
668
+ addCheck(checks, {
669
+ id: "resource-get",
670
+ label: "Resource get contract",
671
+ method: "GET",
672
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}/${options.resourceId}`,
673
+ status: "passed",
674
+ details: "Resource payload includes id, data, and version",
675
+ });
676
+ }
677
+ catch (err) {
678
+ addCheck(checks, {
679
+ id: "resource-get",
680
+ label: "Resource get contract",
681
+ method: "GET",
682
+ endpoint: `/v4/data/resources/${context.tenantId}/${options.resourceType}/${options.resourceId}`,
683
+ status: "failed",
684
+ details: err instanceof Error ? err.message : String(err),
685
+ });
686
+ }
687
+ }
688
+ }
689
+ else {
690
+ addCheck(checks, {
691
+ id: "resource-get",
692
+ label: "Resource get contract",
693
+ method: "GET",
694
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}/{id}",
695
+ status: "skipped",
696
+ details: "Provide both --resource-type and --resource-id to exercise get/update version contract.",
697
+ });
698
+ }
699
+ if (authenticated && options.tenantRecordId) {
700
+ try {
701
+ const res = await systemClient.getUserMemberships(tokens?.oid || "");
702
+ if (!res.ok) {
703
+ throw new Error(`HTTP ${res.status}`);
704
+ }
705
+ const payload = await parseJsonBody(res);
706
+ const tenantEntries = normalizeTenantEntries(payload);
707
+ const tenant = tenantEntries.find((entry) => entry.tenant.id === options.tenantRecordId ||
708
+ entry.tenant.slug === options.tenantRecordId);
709
+ if (!tenant) {
710
+ throw new Error("Requested tenant was not found in the current tenant-admin memberships");
711
+ }
712
+ addCheck(checks, {
713
+ id: "tenant-info",
714
+ label: "Tenant info resolution",
715
+ method: "GET",
716
+ endpoint: "/v4/platform/users/{oid}/memberships",
717
+ status: "passed",
718
+ details: `Resolved ${tenant.tenant.displayName} (${tenant.tenant.slug})`,
719
+ });
720
+ }
721
+ catch (err) {
722
+ addCheck(checks, {
723
+ id: "tenant-info",
724
+ label: "Tenant info resolution",
725
+ method: "GET",
726
+ endpoint: "/v4/platform/users/{oid}/memberships",
727
+ status: "failed",
728
+ details: err instanceof Error ? err.message : String(err),
729
+ });
730
+ }
731
+ }
732
+ else {
733
+ addCheck(checks, {
734
+ id: "tenant-info",
735
+ label: "Tenant info resolution",
736
+ method: "GET",
737
+ endpoint: "/v4/platform/users/{oid}/memberships",
738
+ status: "skipped",
739
+ details: "Provide --tenant-record to exercise tenant info lookup.",
740
+ });
741
+ }
742
+ if (authenticated && options.userEmail) {
743
+ try {
744
+ const res = await systemClient.lookupUserByEmail(options.userEmail);
745
+ if (!res.ok) {
746
+ throw new Error(`HTTP ${res.status}`);
747
+ }
748
+ const payload = await parseJsonBody(res);
749
+ if (!isRecord(payload)) {
750
+ throw new Error(`Expected object, received ${describeShape(payload)}`);
751
+ }
752
+ const userId = typeof payload.id === "string"
753
+ ? payload.id
754
+ : isRecord(payload.user) && typeof payload.user.id === "string"
755
+ ? payload.user.id
756
+ : null;
757
+ if (!userId) {
758
+ throw new Error("Expected direct id or payload.user.id in lookup response");
759
+ }
760
+ addCheck(checks, {
761
+ id: "user-lookup",
762
+ label: "User lookup contract",
763
+ method: "GET",
764
+ endpoint: "/v4/platform/users/by-email?email=...",
765
+ status: "passed",
766
+ details: `${describeShape(payload)} (resolved user id ${userId})`,
767
+ });
768
+ }
769
+ catch (err) {
770
+ addCheck(checks, {
771
+ id: "user-lookup",
772
+ label: "User lookup contract",
773
+ method: "GET",
774
+ endpoint: "/v4/platform/users/by-email?email=...",
775
+ status: "failed",
776
+ details: err instanceof Error ? err.message : String(err),
777
+ });
778
+ }
779
+ }
780
+ else {
781
+ addCheck(checks, {
782
+ id: "user-lookup",
783
+ label: "User lookup contract",
784
+ method: "GET",
785
+ endpoint: "/v4/platform/users/by-email?email=...",
786
+ status: "skipped",
787
+ details: "Provide --user-email to exercise user lookup.",
788
+ });
789
+ }
790
+ if (authenticated && client && options.includeChat) {
791
+ if (!workflowId) {
792
+ addCheck(checks, {
793
+ id: "chat-send",
794
+ label: "Chat send contract",
795
+ method: "POST",
796
+ endpoint: "/v4/ai/chat/{tenantId}/{workflowId}/{stage}",
797
+ status: "skipped",
798
+ details: "Provide --workflow or WORKFLOW_*_ID to exercise chat.",
799
+ });
800
+ }
801
+ else {
802
+ try {
803
+ const res = await client.sendChat(workflowId, stage, options.chatMessage || "Smoke test from `eai verify calls`", randomUUID());
804
+ if (!res.ok) {
805
+ throw new Error(`HTTP ${res.status}`);
806
+ }
807
+ const payload = await parseJsonBody(res);
808
+ if (!isRecord(payload) ||
809
+ (typeof payload.response !== "string" &&
810
+ typeof payload.message !== "string")) {
811
+ throw new Error("Expected response or message string in chat payload");
812
+ }
813
+ addCheck(checks, {
814
+ id: "chat-send",
815
+ label: "Chat send contract",
816
+ method: "POST",
817
+ endpoint: `/v4/ai/chat/${context.tenantId}/${workflowId}/${stage}`,
818
+ status: "passed",
819
+ details: "Chat response payload includes response/message text",
820
+ });
821
+ }
822
+ catch (err) {
823
+ addCheck(checks, {
824
+ id: "chat-send",
825
+ label: "Chat send contract",
826
+ method: "POST",
827
+ endpoint: `/v4/ai/chat/${context.tenantId || "{tenantId}"}/${workflowId}/${stage}`,
828
+ status: "failed",
829
+ details: err instanceof Error ? err.message : String(err),
830
+ });
831
+ }
832
+ }
833
+ }
834
+ else {
835
+ addCheck(checks, {
836
+ id: "chat-send",
837
+ label: "Chat send contract",
838
+ method: "POST",
839
+ endpoint: "/v4/ai/chat/{tenantId}/{workflowId}/{stage}",
840
+ status: "skipped",
841
+ details: "Opt in with --include-chat. This creates a conversation record.",
842
+ });
843
+ }
844
+ const intentionallySkipped = [
845
+ {
846
+ id: "resource-mutations",
847
+ label: "Resource create/update/delete contracts",
848
+ method: "POST/PUT/DELETE",
849
+ endpoint: "/v4/data/resources/{tenantId}/{objectType}[/{id}]",
850
+ details: "Not auto-executed because they mutate data.",
851
+ },
852
+ {
853
+ id: "document-contracts",
854
+ label: "Document upload/classify/index contracts",
855
+ method: "POST",
856
+ endpoint: "/v4/data/documents/*",
857
+ details: "Not auto-executed because they upload files or trigger indexing.",
858
+ },
859
+ {
860
+ id: "user-provisioning",
861
+ label: "User provisioning contracts",
862
+ method: "POST",
863
+ endpoint: "/v4/identity/me/provision and /v4/platform/tenants/{tenantId}/users/{oid}/provision",
864
+ details: "Not auto-executed because they change tenant membership.",
865
+ },
866
+ {
867
+ id: "tenant-create",
868
+ label: "Tenant create contract",
869
+ method: "POST",
870
+ endpoint: "/v4/platform/tenants",
871
+ details: "Not auto-executed because it creates tenants.",
872
+ },
873
+ {
874
+ id: "chat-stream",
875
+ label: "Chat stream contract",
876
+ method: "POST",
877
+ endpoint: "/v4/ai/chat/stream/{tenantId}/{workflowId}/{stage}",
878
+ details: "Not auto-executed because it requires streaming response handling.",
879
+ },
880
+ ];
881
+ for (const check of intentionallySkipped) {
882
+ addCheck(checks, {
883
+ ...check,
884
+ status: "skipped",
885
+ });
886
+ }
887
+ return {
888
+ generatedAt: new Date().toISOString(),
889
+ publicApiUrl: context.publicApiUrl,
890
+ tenantId: context.tenantId,
891
+ workflowId,
892
+ checks,
893
+ summary: summarizeChecks(checks),
894
+ };
895
+ }
896
+ export const verifyCommand = new Command("verify")
897
+ .description("Run platform connectivity checks")
898
+ .option("--tenant-id <id>", "Run read-only connectivity checks against a specific tenant ID")
899
+ .addHelpText("after", `
900
+ Examples:
901
+ $ eai verify
902
+ $ eai verify --tenant-id <tenantId>
903
+ $ eai verify calls --format json
904
+
905
+ Use 'eai verify' for a quick health check.
906
+ Use 'eai verify calls' when you need to inspect the exact API contracts the CLI depends on.
907
+ `)
908
+ .action(async (options) => {
909
+ let environment;
910
+ try {
911
+ environment = await loadVerifyEnvironment({
912
+ tenantId: extractTenantIdOption(options),
913
+ });
914
+ }
915
+ catch (err) {
916
+ out.error(err instanceof Error ? err.message : String(err));
917
+ process.exit(1);
918
+ }
919
+ const { root, publicApiUrl, tenantId } = environment;
920
+ out.heading("Platform Connectivity Checks");
921
+ out.blank();
922
+ const client = new PlatformAPIClient(publicApiUrl, tenantId || "unknown");
923
+ let passed = 0;
924
+ let failed = 0;
925
+ // Check 1: PublicAPI reachable
926
+ const apiSpinner = ora("PublicAPI gateway").start();
927
+ try {
928
+ const start = Date.now();
929
+ const res = await fetch(`${publicApiUrl}/health`, {
930
+ signal: AbortSignal.timeout(10_000),
931
+ });
932
+ const latency = Date.now() - start;
933
+ if (res.ok || res.status === 404) {
934
+ // 404 is fine — means server is up, just no /health endpoint
935
+ apiSpinner.succeed(`PublicAPI reachable (${latency}ms)`);
936
+ passed++;
937
+ }
938
+ else {
939
+ apiSpinner.fail(`PublicAPI returned ${res.status}`);
940
+ failed++;
941
+ }
942
+ }
943
+ catch (err) {
944
+ apiSpinner.fail(`PublicAPI not reachable: ${err instanceof Error ? err.message : String(err)}`);
945
+ failed++;
946
+ }
947
+ // Check 2: Auth token
948
+ const authSpinner = ora("Authentication").start();
949
+ const authenticated = await isAuthenticated();
950
+ if (authenticated) {
951
+ const tokens = await loadTokens();
952
+ authSpinner.succeed(`Authenticated as ${tokens?.upn || "user"}`);
953
+ passed++;
954
+ }
955
+ else {
956
+ authSpinner.warn("Not authenticated — run `eai login`");
957
+ failed++;
958
+ }
959
+ // Check 3: Platform service connectivity
960
+ if (authenticated && tenantId) {
961
+ const cfgSpinner = ora("Platform service").start();
962
+ try {
963
+ const res = await client.getPublishedObjectTypes({ limit: 1 });
964
+ if (res.ok) {
965
+ cfgSpinner.succeed("Platform service reachable");
966
+ passed++;
967
+ }
968
+ else {
969
+ cfgSpinner.fail(`Platform service returned ${res.status}`);
970
+ failed++;
971
+ }
972
+ }
973
+ catch (err) {
974
+ cfgSpinner.fail(`Platform service not reachable: ${err instanceof Error ? err.message : String(err)}`);
975
+ failed++;
976
+ }
977
+ }
978
+ // Check 4: Data service (schema)
979
+ if (authenticated && tenantId) {
980
+ const resSpinner = ora("Data service (schema)").start();
981
+ try {
982
+ const res = await client.getSchema();
983
+ if (res.ok) {
984
+ const schema = (await res.json());
985
+ const typeCount = Array.isArray(schema?.object_types)
986
+ ? schema.object_types.length
987
+ : schema?.objectTypes?.length || 0;
988
+ resSpinner.succeed(`Data service reachable — ${typeCount} published types`);
989
+ passed++;
990
+ }
991
+ else {
992
+ // Surface the server's reason code/message (e.g. RESOURCEAPI_INSTALL_REGISTRY_NO_MATCH)
993
+ // instead of only the status — and add actionable guidance when we recognise it, so a
994
+ // tenant-provisioning issue is not mistaken for a transient outage.
995
+ let code;
996
+ let message;
997
+ try {
998
+ const body = (await res.json());
999
+ if (typeof body?.code === "string")
1000
+ code = body.code;
1001
+ if (typeof body?.message === "string")
1002
+ message = body.message;
1003
+ }
1004
+ catch {
1005
+ // non-JSON body — the status alone is the signal
1006
+ }
1007
+ resSpinner.fail(`Data service returned ${res.status}${code ? ` [${code}]` : ""}${message ? ` — ${message}` : ""}`);
1008
+ const guidance = findGuidance({
1009
+ status: res.status,
1010
+ serverCode: code,
1011
+ message: message ?? code,
1012
+ });
1013
+ if (guidance) {
1014
+ out.info(guidance.title);
1015
+ if (!guidance.retry.allowed && guidance.retry.stopWhen[0]) {
1016
+ out.info(guidance.retry.stopWhen[0]);
1017
+ }
1018
+ }
1019
+ failed++;
1020
+ }
1021
+ }
1022
+ catch (err) {
1023
+ resSpinner.fail(`Data service not reachable: ${err instanceof Error ? err.message : String(err)}`);
1024
+ failed++;
1025
+ }
1026
+ }
1027
+ // Check 5: Local Object Types
1028
+ const typesSpinner = ora("Local Object Types").start();
1029
+ try {
1030
+ const types = await loadObjectTypes(root);
1031
+ const totalTypes = Object.values(types).reduce((sum, t) => sum + t.length, 0);
1032
+ const tenantKeys = Object.keys(types);
1033
+ typesSpinner.succeed(`${totalTypes} types across ${tenantKeys.length} tenant scope(s)`);
1034
+ passed++;
1035
+ }
1036
+ catch (err) {
1037
+ typesSpinner.fail(`No Object Types found: ${err instanceof Error ? err.message : String(err)}`);
1038
+ failed++;
1039
+ }
1040
+ // Summary
1041
+ out.blank();
1042
+ if (failed === 0) {
1043
+ out.success(`All ${passed} checks passed`);
1044
+ }
1045
+ else {
1046
+ out.warn(`${passed} passed, ${failed} failed`);
1047
+ }
1048
+ });
1049
+ verifyCommand
1050
+ .command("storage")
1051
+ .description("Verify storage status and doctor contracts")
1052
+ .option("--tenant-id <id>", "Tenant ID to verify")
1053
+ .option("--format <format>", "Output format (text|json)", "text")
1054
+ .option("--json", "Output raw JSON (deprecated, use --format json)", false)
1055
+ .action(async (options) => {
1056
+ let context;
1057
+ try {
1058
+ context = await loadVerifyEnvironment({
1059
+ tenantId: extractTenantIdOption(options),
1060
+ });
1061
+ }
1062
+ catch (err) {
1063
+ out.error(err instanceof Error ? err.message : String(err));
1064
+ process.exit(1);
1065
+ }
1066
+ const client = new PlatformAPIClient(context.publicApiUrl, context.tenantId || "unknown");
1067
+ const checks = [];
1068
+ const statusResponse = await client.getResourceStorageStatus();
1069
+ if (statusResponse.ok) {
1070
+ const payload = (await statusResponse.json());
1071
+ checks.push({
1072
+ id: "storage-status",
1073
+ status: "passed",
1074
+ details: `${payload.objectTypes?.length || 0} object type route(s) returned`,
1075
+ payload,
1076
+ });
1077
+ }
1078
+ else {
1079
+ checks.push({
1080
+ id: "storage-status",
1081
+ status: "failed",
1082
+ details: `${statusResponse.status} ${statusResponse.statusText}`,
1083
+ });
1084
+ }
1085
+ const doctorResponse = await client.getResourceStorageDoctor();
1086
+ if (doctorResponse.ok) {
1087
+ const payload = (await doctorResponse.json());
1088
+ checks.push({
1089
+ id: "storage-doctor",
1090
+ status: payload.healthy ? "passed" : "failed",
1091
+ details: payload.healthy
1092
+ ? "Storage doctor healthy"
1093
+ : "Storage doctor reported issues",
1094
+ payload,
1095
+ });
1096
+ }
1097
+ else {
1098
+ checks.push({
1099
+ id: "storage-doctor",
1100
+ status: "failed",
1101
+ details: `${doctorResponse.status} ${doctorResponse.statusText}`,
1102
+ });
1103
+ }
1104
+ const failed = checks.filter((check) => check.status === "failed").length;
1105
+ const report = {
1106
+ generatedAt: new Date().toISOString(),
1107
+ publicApiUrl: context.publicApiUrl,
1108
+ tenantId: context.tenantId,
1109
+ checks,
1110
+ summary: { passed: checks.length - failed, failed, skipped: 0 },
1111
+ };
1112
+ if (options.json || options.format === "json") {
1113
+ out.json(report);
1114
+ return;
1115
+ }
1116
+ out.heading("Storage Verification");
1117
+ for (const check of checks) {
1118
+ if (check.status === "passed") {
1119
+ out.success(`${check.id}: ${check.details}`);
1120
+ }
1121
+ else {
1122
+ out.error(`${check.id}: ${check.details}`);
1123
+ }
1124
+ }
1125
+ if (failed > 0) {
1126
+ process.exit(1);
1127
+ }
1128
+ });
1129
+ verifyCommand
1130
+ .command("calls")
1131
+ .description("Audit platform-facing API call contracts used by the CLI")
1132
+ .option("--tenant-id <id>", "Tenant ID to use for read-only resource and schema checks")
1133
+ .option("--resource-type <type>", "Resource type to probe with list/query/get checks")
1134
+ .option("--resource-id <id>", "Specific resource ID to fetch during contract audit")
1135
+ .option("--workflow <id>", "Workflow ID to use for chat smoke test")
1136
+ .option("--stage <stage>", "Chat stage to use when --include-chat is enabled", "chat")
1137
+ .option("--tenant-record <id>", "Tenant record ID to use for tenant info lookup")
1138
+ .option("--user-email <email>", "Email address to use for user lookup contract check")
1139
+ .option("--include-chat", "Execute a non-streaming chat request (creates a conversation)", false)
1140
+ .option("--chat-message <message>", "Message to send when probing chat", "Smoke test from `eai verify calls`")
1141
+ .option("--format <format>", "Output format (text|json)", "text")
1142
+ .option("--json", "Output raw JSON (deprecated, use --format json)", false)
1143
+ .action(async (options) => {
1144
+ if (options.json) {
1145
+ options.format = "json";
1146
+ }
1147
+ let report;
1148
+ try {
1149
+ report = await runContractAudit({
1150
+ tenantId: extractTenantIdOption(options),
1151
+ resourceType: options.resourceType,
1152
+ resourceId: options.resourceId,
1153
+ workflowId: options.workflow,
1154
+ stage: options.stage,
1155
+ tenantRecordId: options.tenantRecord,
1156
+ userEmail: options.userEmail,
1157
+ includeChat: options.includeChat,
1158
+ chatMessage: options.chatMessage,
1159
+ });
1160
+ }
1161
+ catch (err) {
1162
+ out.error(err instanceof Error ? err.message : String(err));
1163
+ process.exit(1);
1164
+ }
1165
+ if (options.format === "json") {
1166
+ out.json(report);
1167
+ return;
1168
+ }
1169
+ renderContractAudit(report);
1170
+ if (report.summary.failed > 0) {
1171
+ process.exit(1);
1172
+ }
1173
+ });
1174
+ // ─── eai doctor ────────────────────────────────────────────────────────────
1175
+ function describeReleaseChannel(channel) {
1176
+ if (channel === "npmjs") {
1177
+ return "npmjs";
1178
+ }
1179
+ return "static registry fallback";
1180
+ }
1181
+ function describeTemplateSnapshot(template) {
1182
+ if (template.displaySource) {
1183
+ return template.displaySource;
1184
+ }
1185
+ if (template.commit && template.repo) {
1186
+ return `${template.repo}@${template.commit.slice(0, 7)}`;
1187
+ }
1188
+ return template.repo || "unknown";
1189
+ }
1190
+ async function renderDoctorUpdateStatus(root) {
1191
+ out.blank();
1192
+ out.heading("Update Status");
1193
+ out.blank();
1194
+ const currentCliVersion = pkg.version;
1195
+ out.success(`Installed CLI version: ${chalk.dim(currentCliVersion)}`);
1196
+ const latestRelease = await fetchLatestRelease();
1197
+ if (!latestRelease) {
1198
+ out.warn("Could not determine the latest published CLI release from npmjs or the EAI static registry fallback right now.");
1199
+ }
1200
+ else if (compareVersions(latestRelease.version, currentCliVersion) > 0) {
1201
+ out.warn(`Published CLI available: ${latestRelease.version} ${chalk.dim(`(${describeReleaseChannel(latestRelease.channel)})`)}`);
1202
+ out.dim(` Run: ${chalk.cyan("eai update")}`);
1203
+ }
1204
+ else {
1205
+ out.success(`Published CLI channel is current: ${latestRelease.version} ${chalk.dim(`(${describeReleaseChannel(latestRelease.channel)})`)}`);
1206
+ }
1207
+ const resolvedManifest = await resolveProjectManifest(root);
1208
+ const manifest = resolvedManifest.manifest;
1209
+ if (!manifest) {
1210
+ out.info("No `.eai-manifest.json` found yet. Run `eai gofer refresh --check` once to adopt the current Gofer-managed asset snapshot safely.");
1211
+ out.info("Template and UI component drift is not auto-merged yet; use `eai template check` before copying changes manually.");
1212
+ return;
1213
+ }
1214
+ if (resolvedManifest.source === "inferred-init-commit") {
1215
+ out.info("Using template provenance inferred from the original `eai init` scaffold commit because this project does not yet record template provenance in `.eai-manifest.json`.");
1216
+ }
1217
+ else if (resolvedManifest.source === "inferred-project-structure") {
1218
+ out.info("Using template provenance inferred from this legacy EAI scaffold because this project does not yet record template provenance in `.eai-manifest.json`.");
1219
+ }
1220
+ if (manifest.cli?.version) {
1221
+ if (manifest.cli.version === currentCliVersion) {
1222
+ out.success(`Project manifest CLI snapshot: ${manifest.cli.version}`);
1223
+ }
1224
+ else {
1225
+ out.info(`Project manifest CLI snapshot: ${manifest.cli.version} ${chalk.dim(`(current CLI: ${currentCliVersion})`)}`);
1226
+ }
1227
+ }
1228
+ else {
1229
+ out.info("Project manifest does not yet record a CLI snapshot.");
1230
+ }
1231
+ if (manifest.gofer) {
1232
+ const bundledGofer = await readGoferBundleMetadata();
1233
+ const projectLabel = manifest.gofer.bundle?.describe ||
1234
+ manifest.gofer.bundle?.commit ||
1235
+ "unknown";
1236
+ const bundledLabel = bundledGofer.describe || bundledGofer.commit || "unknown";
1237
+ if (bundledGofer.commit &&
1238
+ manifest.gofer.bundle?.commit &&
1239
+ bundledGofer.commit !== manifest.gofer.bundle.commit) {
1240
+ out.warn(`Available Gofer assets differ from this project: ${projectLabel} -> ${bundledLabel}`);
1241
+ out.dim(` Preview: ${chalk.cyan("eai gofer refresh --check")}`);
1242
+ }
1243
+ else {
1244
+ out.success(`Gofer-managed asset snapshot: ${projectLabel}`);
1245
+ }
1246
+ }
1247
+ else {
1248
+ out.info("Gofer-managed assets are not tracked yet. Run `eai gofer refresh --check` to preview a safe refresh.");
1249
+ }
1250
+ if (!manifest.template) {
1251
+ out.info("Template provenance is not recorded for this project.");
1252
+ return;
1253
+ }
1254
+ const bundledTemplate = resolveTemplateClonePlan(DEFAULT_TEMPLATE_SOURCE);
1255
+ const projectTemplateLabel = describeTemplateSnapshot(manifest.template);
1256
+ const bundledTemplateLabel = describeTemplateSnapshot({
1257
+ repo: bundledTemplate.cloneSource,
1258
+ commit: bundledTemplate.pinnedCommit,
1259
+ displaySource: bundledTemplate.displaySource,
1260
+ });
1261
+ if (manifest.template.repo &&
1262
+ !isDefaultTemplateSource(manifest.template.repo) &&
1263
+ manifest.template.repo !== bundledTemplate.cloneSource) {
1264
+ out.info(`Project template source: ${projectTemplateLabel}`);
1265
+ out.info(`Current bundled default template: ${bundledTemplateLabel}`);
1266
+ out.info("This project was initialized from a different template source, so template or UI updates still need manual review.");
1267
+ out.dim(` Preview: ${chalk.cyan("eai template check")}`);
1268
+ return;
1269
+ }
1270
+ if (manifest.template.commit &&
1271
+ bundledTemplate.pinnedCommit &&
1272
+ manifest.template.commit !== bundledTemplate.pinnedCommit) {
1273
+ out.warn(`Bundled default template has changed since init: ${projectTemplateLabel} → ${bundledTemplateLabel}`);
1274
+ out.info("The CLI does not auto-merge template or UI component updates into existing repos yet. Review `eai template check` before applying those changes manually.");
1275
+ return;
1276
+ }
1277
+ out.success(`Template snapshot: ${projectTemplateLabel}`);
1278
+ }
1279
+ export const doctorCommand = new Command("doctor")
1280
+ .description("Diagnose common issues and suggest fixes")
1281
+ .option("--fix", "Attempt to fix issues automatically", false)
1282
+ .option("--check-updates", "Report CLI release status plus Gofer/template drift for the current project", false)
1283
+ .addHelpText("after", `
1284
+ Examples:
1285
+ $ eai doctor
1286
+ $ eai doctor --check-updates
1287
+
1288
+ Notes:
1289
+ - \`eai update\` upgrades the installed CLI package only.
1290
+ - \`eai gofer refresh --check\` previews safe repo-local Gofer asset updates.
1291
+ - \`eai template check\` previews app-template and UI drift without writing files.
1292
+ - Template and UI component changes are not auto-merged into existing repos yet.
1293
+ `)
1294
+ .action(async (options) => {
1295
+ const issues = [];
1296
+ out.heading("EAI Platform Health Check");
1297
+ out.blank();
1298
+ // 1. Project detection
1299
+ const root = await findProjectRoot();
1300
+ if (!root) {
1301
+ out.error("Not in an EAI project directory.");
1302
+ exitWithError(ErrorCode.E001);
1303
+ }
1304
+ out.success(`Project root: ${chalk.dim(root)}`);
1305
+ // 2. Local app env file (optional for CLI platform operations)
1306
+ try {
1307
+ await access(join(root, ".env.local"));
1308
+ out.success(".env.local found for local app runtime");
1309
+ }
1310
+ catch {
1311
+ out.info(".env.local not found — CLI auth and tenant selection use stored login context");
1312
+ }
1313
+ // 3. PublicAPI resolution
1314
+ const envVars = await loadEnvFile(root);
1315
+ const publicApiUrl = await resolvePublicApiUrl(root);
1316
+ const publicApiSource = envVars.BASE_URL_PUBLIC_API || process.env.BASE_URL_PUBLIC_API
1317
+ ? "environment"
1318
+ : "stored login/default";
1319
+ out.success(`PublicAPI URL resolved (${publicApiSource}): ${chalk.dim(publicApiUrl)}`);
1320
+ // 4. Auth status
1321
+ const authenticated = await isAuthenticated();
1322
+ if (authenticated) {
1323
+ const tokens = await loadTokens();
1324
+ out.success(`Authenticated as ${tokens?.upn || "user"}`);
1325
+ }
1326
+ else {
1327
+ issues.push({
1328
+ severity: "warn",
1329
+ message: "Not authenticated",
1330
+ fix: "Run `eai login` to authenticate with Entra CIAM",
1331
+ });
1332
+ out.warn("Not authenticated");
1333
+ }
1334
+ // 5. Active tenant selection
1335
+ if (authenticated) {
1336
+ try {
1337
+ const tenantContext = await resolveActiveTenantContext({
1338
+ projectRoot: root,
1339
+ publicApiUrl,
1340
+ interactive: false,
1341
+ });
1342
+ out.success(`Active tenant selected: ${tenantContext.activeTenant.displayName} ${chalk.dim(`(${tenantContext.activeTenant.id})`)}`);
1343
+ }
1344
+ catch (err) {
1345
+ issues.push({
1346
+ severity: "warn",
1347
+ message: err instanceof Error ? err.message : String(err),
1348
+ fix: "Run `eai tenant list` to inspect memberships, then `eai tenant select` to choose one",
1349
+ });
1350
+ out.warn(err instanceof Error ? err.message : String(err));
1351
+ }
1352
+ }
1353
+ // 6. Object types loadable
1354
+ try {
1355
+ const types = await loadObjectTypes(root);
1356
+ const totalTypes = Object.values(types).reduce((sum, t) => sum + t.length, 0);
1357
+ out.success(`Object Types: ${totalTypes} defined`);
1358
+ }
1359
+ catch (err) {
1360
+ issues.push({
1361
+ severity: "warn",
1362
+ message: `Object Types not loadable: ${err instanceof Error ? err.message : String(err)}`,
1363
+ fix: "Check src/eai.config/object-types.ts for syntax errors",
1364
+ });
1365
+ out.warn("Object Types not loadable");
1366
+ }
1367
+ // 7. Deployment workflow exists
1368
+ try {
1369
+ await access(join(root, ".github", "workflows", "deploy-demo.yml"));
1370
+ out.success("Deployment workflow exists");
1371
+ }
1372
+ catch {
1373
+ issues.push({
1374
+ severity: "warn",
1375
+ message: "deploy-demo.yml not found",
1376
+ fix: "Run `eai deploy setup` to generate the workflow",
1377
+ });
1378
+ out.warn("deploy-demo.yml not found");
1379
+ }
1380
+ // 8. node_modules exists
1381
+ try {
1382
+ await access(join(root, "node_modules"));
1383
+ out.success("Dependencies installed");
1384
+ }
1385
+ catch {
1386
+ issues.push({
1387
+ severity: "error",
1388
+ message: "node_modules not found",
1389
+ fix: "Run `npm install`",
1390
+ });
1391
+ out.error("Dependencies not installed");
1392
+ }
1393
+ // 9. Platform SDK available
1394
+ try {
1395
+ await access(join(root, "packages", "platform-sdk"));
1396
+ out.success("Platform SDK present");
1397
+ }
1398
+ catch {
1399
+ try {
1400
+ await access(join(root, "node_modules", "@enterpriseaigroup", "platform-sdk"));
1401
+ out.success("Platform SDK installed");
1402
+ }
1403
+ catch {
1404
+ try {
1405
+ await access(join(root, "node_modules", "@eai-tools", "platform-sdk"));
1406
+ out.success("Legacy Platform SDK installed");
1407
+ }
1408
+ catch {
1409
+ issues.push({
1410
+ severity: "warn",
1411
+ message: "Platform SDK not found",
1412
+ fix: "Restore local packages/platform-sdk; the shared package is not promoted yet.",
1413
+ });
1414
+ out.warn("Platform SDK not found");
1415
+ }
1416
+ }
1417
+ }
1418
+ if (options.checkUpdates) {
1419
+ await renderDoctorUpdateStatus(root);
1420
+ }
1421
+ // Summary
1422
+ out.blank();
1423
+ if (issues.length === 0) {
1424
+ out.success("No issues found. Your project is healthy!");
1425
+ }
1426
+ else {
1427
+ out.heading(`${issues.length} issue(s) found`);
1428
+ out.blank();
1429
+ for (const issue of issues) {
1430
+ const icon = issue.severity === "error"
1431
+ ? out.symbols.error
1432
+ : issue.severity === "warn"
1433
+ ? out.symbols.warning
1434
+ : out.symbols.info;
1435
+ out.info(`${icon} ${issue.message}`);
1436
+ if (issue.fix) {
1437
+ out.dim(` Fix: ${issue.fix}`);
1438
+ }
1439
+ }
1440
+ }
1441
+ });
1442
+ //# sourceMappingURL=verify.js.map