@cubis/foundry 0.3.75 → 0.3.77

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 (263) hide show
  1. package/README.md +98 -76
  2. package/dist/cli/commands/register.js +1 -1
  3. package/dist/cli/commands/register.js.map +1 -1
  4. package/dist/cli/core.js +405 -216
  5. package/dist/cli/core.js.map +1 -1
  6. package/dist/cli/init/execute.js +5 -7
  7. package/dist/cli/init/execute.js.map +1 -1
  8. package/dist/cli/workflows/commands.js +2 -2
  9. package/dist/cli/workflows/commands.js.map +1 -1
  10. package/mcp/src/tools/skillTools.test.ts +34 -1
  11. package/package.json +4 -3
  12. package/src/cli/commands/register.ts +1 -1
  13. package/src/cli/core.ts +495 -267
  14. package/src/cli/init/execute.ts +5 -9
  15. package/src/cli/workflows/commands.ts +2 -2
  16. package/workflows/skills/_schema/skill-platform-attributes.json +14 -0
  17. package/workflows/skills/deep-research/SKILL.md +81 -0
  18. package/workflows/skills/deep-research/evals/assertions.md +17 -0
  19. package/workflows/skills/deep-research/evals/evals.json +56 -0
  20. package/workflows/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  21. package/workflows/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  22. package/workflows/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  23. package/workflows/skills/deep-research/references/comparison-checklist.md +57 -0
  24. package/workflows/skills/deep-research/references/research-output.md +69 -0
  25. package/workflows/skills/deep-research/references/source-ladder.md +81 -0
  26. package/workflows/skills/generated/skill-audit.json +20 -2
  27. package/workflows/skills/generated/skill-catalog.json +62 -4
  28. package/workflows/skills/skills_index.json +58 -0
  29. package/workflows/skills/stitch/SKILL.md +79 -0
  30. package/workflows/skills/stitch/evals/assertions.md +45 -0
  31. package/workflows/skills/stitch/evals/evals.json +68 -0
  32. package/workflows/skills/stitch/examples/01-new-screen.md +13 -0
  33. package/workflows/skills/stitch/examples/02-update-existing-screen.md +13 -0
  34. package/workflows/skills/stitch/examples/03-mobile-handoff.md +13 -0
  35. package/workflows/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  36. package/workflows/skills/stitch/examples/05-design-sync-loop.md +16 -0
  37. package/workflows/skills/stitch/references/implementation-patterns.md +20 -0
  38. package/workflows/skills/stitch/references/platform-setup.md +46 -0
  39. package/workflows/skills/stitch/references/update-diff-workflow.md +23 -0
  40. package/workflows/workflows/agent-environment-setup/generated/route-manifest.json +21 -13
  41. package/workflows/workflows/agent-environment-setup/manifest.json +32 -1
  42. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/frontend-specialist.md +10 -2
  43. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/mobile-developer.md +6 -2
  44. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/orchestrator.md +6 -5
  45. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/project-planner.md +4 -3
  46. package/workflows/workflows/agent-environment-setup/platforms/antigravity/agents/researcher.md +8 -4
  47. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/accessibility.toml +2 -0
  48. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/backend.toml +2 -0
  49. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/create.toml +2 -0
  50. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/database.toml +2 -0
  51. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/debug.toml +2 -0
  52. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/devops.toml +2 -0
  53. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/implement-track.toml +2 -0
  54. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/migrate.toml +2 -0
  55. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/mobile.toml +2 -0
  56. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/onboard.toml +2 -0
  57. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/orchestrate.toml +2 -0
  58. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/plan.toml +2 -0
  59. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/refactor.toml +2 -0
  60. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/release.toml +2 -0
  61. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/review.toml +2 -0
  62. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/security.toml +2 -0
  63. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/test.toml +2 -0
  64. package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/vercel.toml +2 -0
  65. package/workflows/workflows/agent-environment-setup/platforms/antigravity/rules/GEMINI.md +14 -8
  66. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/SKILL.md +89 -0
  67. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/evals/assertions.md +17 -0
  68. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/evals/evals.json +56 -0
  69. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  70. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  71. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  72. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/comparison-checklist.md +57 -0
  73. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/research-output.md +69 -0
  74. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/deep-research/references/source-ladder.md +81 -0
  75. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/SKILL.md +87 -0
  76. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/evals/assertions.md +45 -0
  77. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/evals/evals.json +68 -0
  78. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/examples/01-new-screen.md +13 -0
  79. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/examples/02-update-existing-screen.md +13 -0
  80. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/examples/03-mobile-handoff.md +13 -0
  81. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  82. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/examples/05-design-sync-loop.md +16 -0
  83. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/references/implementation-patterns.md +20 -0
  84. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/references/platform-setup.md +46 -0
  85. package/workflows/workflows/agent-environment-setup/platforms/antigravity/skills/stitch/references/update-diff-workflow.md +23 -0
  86. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/create.md +3 -2
  87. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/mobile.md +4 -3
  88. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/onboard.md +3 -3
  89. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/orchestrate.md +2 -2
  90. package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/plan.md +4 -4
  91. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/frontend-specialist.md +10 -2
  92. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/mobile-developer.md +6 -2
  93. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/orchestrator.md +6 -5
  94. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/project-planner.md +4 -3
  95. package/workflows/workflows/agent-environment-setup/platforms/claude/agents/researcher.md +8 -4
  96. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/README.md +15 -0
  97. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/route-research-guard.mjs +39 -0
  98. package/workflows/workflows/agent-environment-setup/platforms/claude/hooks/settings.snippet.json +15 -0
  99. package/workflows/workflows/agent-environment-setup/platforms/claude/rules/CLAUDE.md +16 -8
  100. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/SKILL.md +95 -0
  101. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/evals/assertions.md +17 -0
  102. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/evals/evals.json +56 -0
  103. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  104. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  105. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  106. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/comparison-checklist.md +57 -0
  107. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/research-output.md +69 -0
  108. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/deep-research/references/source-ladder.md +81 -0
  109. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/skills_index.json +58 -0
  110. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/SKILL.md +93 -0
  111. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/evals/assertions.md +45 -0
  112. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/evals/evals.json +68 -0
  113. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/examples/01-new-screen.md +13 -0
  114. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/examples/02-update-existing-screen.md +13 -0
  115. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/examples/03-mobile-handoff.md +13 -0
  116. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  117. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/examples/05-design-sync-loop.md +16 -0
  118. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/references/implementation-patterns.md +20 -0
  119. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/references/platform-setup.md +46 -0
  120. package/workflows/workflows/agent-environment-setup/platforms/claude/skills/stitch/references/update-diff-workflow.md +23 -0
  121. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/create.md +3 -2
  122. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/mobile.md +4 -3
  123. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/onboard.md +3 -3
  124. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/orchestrate.md +2 -2
  125. package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/plan.md +4 -4
  126. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/frontend-specialist.md +10 -2
  127. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/mobile-developer.md +6 -2
  128. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/orchestrator.md +6 -5
  129. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/project-planner.md +4 -3
  130. package/workflows/workflows/agent-environment-setup/platforms/codex/agents/researcher.md +8 -4
  131. package/workflows/workflows/agent-environment-setup/platforms/codex/rules/AGENTS.md +14 -8
  132. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/SKILL.md +89 -0
  133. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/evals/assertions.md +17 -0
  134. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/evals/evals.json +56 -0
  135. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  136. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  137. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  138. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/comparison-checklist.md +57 -0
  139. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/research-output.md +69 -0
  140. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/deep-research/references/source-ladder.md +81 -0
  141. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/SKILL.md +87 -0
  142. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/evals/assertions.md +45 -0
  143. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/evals/evals.json +68 -0
  144. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/examples/01-new-screen.md +13 -0
  145. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/examples/02-update-existing-screen.md +13 -0
  146. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/examples/03-mobile-handoff.md +13 -0
  147. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  148. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/examples/05-design-sync-loop.md +16 -0
  149. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/references/implementation-patterns.md +20 -0
  150. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/references/platform-setup.md +46 -0
  151. package/workflows/workflows/agent-environment-setup/platforms/codex/skills/stitch/references/update-diff-workflow.md +23 -0
  152. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/create.md +3 -2
  153. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/mobile.md +4 -3
  154. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/onboard.md +3 -3
  155. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/orchestrate.md +2 -2
  156. package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/plan.md +4 -4
  157. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/frontend-specialist.md +6 -2
  158. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/mobile-developer.md +6 -2
  159. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/orchestrator.md +6 -5
  160. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/project-planner.md +4 -3
  161. package/workflows/workflows/agent-environment-setup/platforms/copilot/agents/researcher.md +8 -4
  162. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-accessibility.prompt.md +2 -1
  163. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-backend.prompt.md +2 -1
  164. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-create.prompt.md +2 -1
  165. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-database.prompt.md +2 -1
  166. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-debug.prompt.md +2 -1
  167. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-devops.prompt.md +2 -1
  168. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-implement-track.prompt.md +2 -1
  169. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-migrate.prompt.md +2 -1
  170. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-mobile.prompt.md +2 -1
  171. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-onboard.prompt.md +2 -1
  172. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-orchestrate.prompt.md +2 -1
  173. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-plan.prompt.md +2 -1
  174. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-refactor.prompt.md +2 -1
  175. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-release.prompt.md +2 -1
  176. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-review.prompt.md +2 -1
  177. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-security.prompt.md +2 -1
  178. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-test.prompt.md +2 -1
  179. package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-vercel.prompt.md +2 -1
  180. package/workflows/workflows/agent-environment-setup/platforms/copilot/rules/copilot-instructions.md +14 -8
  181. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/SKILL.md +94 -0
  182. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/evals/assertions.md +17 -0
  183. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/evals/evals.json +56 -0
  184. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  185. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  186. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  187. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/comparison-checklist.md +57 -0
  188. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/research-output.md +69 -0
  189. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/deep-research/references/source-ladder.md +81 -0
  190. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/skills_index.json +58 -0
  191. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/SKILL.md +92 -0
  192. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/evals/assertions.md +45 -0
  193. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/evals/evals.json +68 -0
  194. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/examples/01-new-screen.md +13 -0
  195. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/examples/02-update-existing-screen.md +13 -0
  196. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/examples/03-mobile-handoff.md +13 -0
  197. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  198. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/examples/05-design-sync-loop.md +16 -0
  199. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/references/implementation-patterns.md +20 -0
  200. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/references/platform-setup.md +46 -0
  201. package/workflows/workflows/agent-environment-setup/platforms/copilot/skills/stitch/references/update-diff-workflow.md +23 -0
  202. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/create.md +3 -2
  203. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/mobile.md +4 -3
  204. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/onboard.md +3 -3
  205. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/orchestrate.md +2 -2
  206. package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/plan.md +4 -4
  207. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/accessibility.toml +2 -0
  208. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/backend.toml +2 -0
  209. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/create.toml +2 -0
  210. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/database.toml +2 -0
  211. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/debug.toml +2 -0
  212. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/devops.toml +2 -0
  213. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/implement-track.toml +2 -0
  214. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/migrate.toml +2 -0
  215. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/mobile.toml +2 -0
  216. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/onboard.toml +2 -0
  217. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/orchestrate.toml +2 -0
  218. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/plan.toml +2 -0
  219. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/refactor.toml +2 -0
  220. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/release.toml +2 -0
  221. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/review.toml +2 -0
  222. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/security.toml +2 -0
  223. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/test.toml +2 -0
  224. package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/vercel.toml +2 -0
  225. package/workflows/workflows/agent-environment-setup/platforms/gemini/rules/GEMINI.md +14 -8
  226. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/SKILL.md +89 -0
  227. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/evals/assertions.md +17 -0
  228. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/evals/evals.json +56 -0
  229. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/01-latest-docs-check.md +12 -0
  230. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/02-ecosystem-comparison.md +12 -0
  231. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/examples/03-research-to-implementation-handoff.md +12 -0
  232. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/comparison-checklist.md +57 -0
  233. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/research-output.md +69 -0
  234. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/deep-research/references/source-ladder.md +81 -0
  235. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/SKILL.md +87 -0
  236. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/evals/assertions.md +45 -0
  237. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/evals/evals.json +68 -0
  238. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/examples/01-new-screen.md +13 -0
  239. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/examples/02-update-existing-screen.md +13 -0
  240. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/examples/03-mobile-handoff.md +13 -0
  241. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/examples/04-prompt-enhancement.md +21 -0
  242. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/examples/05-design-sync-loop.md +16 -0
  243. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/references/implementation-patterns.md +20 -0
  244. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/references/platform-setup.md +46 -0
  245. package/workflows/workflows/agent-environment-setup/platforms/gemini/skills/stitch/references/update-diff-workflow.md +23 -0
  246. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/create.md +3 -2
  247. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/mobile.md +4 -3
  248. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/onboard.md +3 -3
  249. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/orchestrate.md +2 -2
  250. package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/plan.md +4 -4
  251. package/workflows/workflows/agent-environment-setup/shared/agents/frontend-specialist.md +10 -2
  252. package/workflows/workflows/agent-environment-setup/shared/agents/mobile-developer.md +6 -2
  253. package/workflows/workflows/agent-environment-setup/shared/agents/orchestrator.md +2 -1
  254. package/workflows/workflows/agent-environment-setup/shared/agents/project-planner.md +2 -1
  255. package/workflows/workflows/agent-environment-setup/shared/agents/researcher.md +5 -1
  256. package/workflows/workflows/agent-environment-setup/shared/rules/STEERING.md +44 -13
  257. package/workflows/workflows/agent-environment-setup/shared/rules/overrides/claude.md +2 -0
  258. package/workflows/workflows/agent-environment-setup/shared/rules/overrides/gemini.md +20 -0
  259. package/workflows/workflows/agent-environment-setup/shared/workflows/create.md +3 -2
  260. package/workflows/workflows/agent-environment-setup/shared/workflows/mobile.md +4 -3
  261. package/workflows/workflows/agent-environment-setup/shared/workflows/onboard.md +1 -1
  262. package/workflows/workflows/agent-environment-setup/shared/workflows/orchestrate.md +1 -1
  263. package/workflows/workflows/agent-environment-setup/shared/workflows/plan.md +2 -2
package/dist/cli/core.js CHANGED
@@ -137,17 +137,20 @@ const WORKFLOW_PROFILES = {
137
137
  workflowDirs: [".claude/workflows"],
138
138
  agentDirs: [".claude/agents"],
139
139
  skillDirs: [".claude/skills"],
140
+ hookDirs: [".claude/hooks"],
140
141
  ruleFilesByPriority: ["CLAUDE.md"],
141
142
  },
142
143
  global: {
143
144
  workflowDirs: ["~/.claude/workflows"],
144
145
  agentDirs: ["~/.claude/agents"],
145
146
  skillDirs: ["~/.claude/skills"],
147
+ hookDirs: ["~/.claude/hooks"],
146
148
  ruleFilesByPriority: ["~/.claude/CLAUDE.md"],
147
149
  },
148
150
  detectorPaths: [
149
151
  "CLAUDE.md",
150
152
  ".claude",
153
+ ".claude/hooks",
151
154
  ".claude/rules",
152
155
  ".claude/settings.json",
153
156
  ],
@@ -2379,6 +2382,7 @@ async function recordBundleInstallState({ scope, platform, bundleId, artifacts,
2379
2382
  skills: artifacts.skills.map(toPosixPath),
2380
2383
  commands: (artifacts.commands || []).map(toPosixPath),
2381
2384
  prompts: (artifacts.prompts || []).map(toPosixPath),
2385
+ hooks: (artifacts.hooks || []).map(toPosixPath),
2382
2386
  };
2383
2387
  await writeState(scope, state, cwd);
2384
2388
  }
@@ -2404,6 +2408,7 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
2404
2408
  const skillDirs = Array.isArray(cfg.skillDirs) ? cfg.skillDirs : [];
2405
2409
  const commandDirs = Array.isArray(cfg.commandDirs) ? cfg.commandDirs : [];
2406
2410
  const promptDirs = Array.isArray(cfg.promptDirs) ? cfg.promptDirs : [];
2411
+ const hookDirs = Array.isArray(cfg.hookDirs) ? cfg.hookDirs : [];
2407
2412
  const resolvePreferredDir = async (dirs) => {
2408
2413
  if (dirs.length === 0)
2409
2414
  return null;
@@ -2420,6 +2425,7 @@ async function resolveProfilePaths(profileId, scope, cwd = process.cwd()) {
2420
2425
  skillsDir: await resolvePreferredDir(skillDirs),
2421
2426
  commandsDir: commandDirs[0] ? expandPath(commandDirs[0], cwd) : null,
2422
2427
  promptsDir: promptDirs[0] ? expandPath(promptDirs[0], cwd) : null,
2428
+ hooksDir: hookDirs[0] ? expandPath(hookDirs[0], cwd) : null,
2423
2429
  ruleFilesByPriority: cfg.ruleFilesByPriority.map((filePath) => expandPath(filePath, cwd)),
2424
2430
  };
2425
2431
  }
@@ -2450,6 +2456,7 @@ function resolveProfilePathCandidates(profileId, scope, cwd = process.cwd()) {
2450
2456
  skillsDirs: expandUniquePaths(cfg.skillDirs, cwd),
2451
2457
  commandsDirs: expandUniquePaths(cfg.commandDirs, cwd),
2452
2458
  promptsDirs: expandUniquePaths(cfg.promptDirs, cwd),
2459
+ hooksDirs: expandUniquePaths(cfg.hookDirs, cwd),
2453
2460
  ruleFilesByPriority: expandUniquePaths(cfg.ruleFilesByPriority, cwd),
2454
2461
  };
2455
2462
  }
@@ -2474,6 +2481,7 @@ async function resolveArtifactProfilePaths(profileId, scope, cwd = process.cwd()
2474
2481
  agentsDir: workspacePaths.agentsDir,
2475
2482
  commandsDir: workspacePaths.commandsDir ?? scopedPaths.commandsDir,
2476
2483
  promptsDir: workspacePaths.promptsDir ?? scopedPaths.promptsDir,
2484
+ hooksDir: scopedPaths.hooksDir,
2477
2485
  };
2478
2486
  }
2479
2487
  async function listBundleIds() {
@@ -3783,8 +3791,8 @@ async function persistManagedCredentialsEnv({ envVarNames, dryRun = false }) {
3783
3791
  function resolvePostmanMcpDefinitionPath({ platform, scope, cwd = process.cwd(), }) {
3784
3792
  return path.join(resolveMcpRootPath({ scope, cwd }), platform, `${POSTMAN_SKILL_ID}.json`);
3785
3793
  }
3786
- function resolveStitchMcpDefinitionPath({ scope, cwd = process.cwd() }) {
3787
- return path.join(resolveMcpRootPath({ scope, cwd }), "antigravity", "stitch.json");
3794
+ function resolveStitchMcpDefinitionPath({ platform, scope, cwd = process.cwd(), }) {
3795
+ return path.join(resolveMcpRootPath({ scope, cwd }), platform, "stitch.json");
3788
3796
  }
3789
3797
  function buildPostmanAuthHeader({ apiKeyEnvVar = POSTMAN_API_KEY_ENV_VAR, apiKey = null, }) {
3790
3798
  const normalizedApiKey = normalizePostmanApiKey(apiKey);
@@ -4347,13 +4355,16 @@ async function removeGeneratedArtifactIfExists({ targetPath, dryRun = false }) {
4347
4355
  path: targetPath,
4348
4356
  };
4349
4357
  }
4350
- async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mcpUrl, includePostmanMcp = true, stitchApiKeyEnvVar, stitchMcpUrl, includeStitchMcp = false, includeFoundryMcp = true, includePlaywrightMcp = false, foundryRuntime = "local", dryRun = false, cwd = process.cwd(), }) {
4358
+ async function applyPostmanMcpForPlatform({ platform, mcpScope, includePostmanMcp = false, includeStitchMcp = false, includeFoundryMcp = true, includePlaywrightMcp = false, foundryRuntime = "local", dryRun = false, cwd = process.cwd(), }) {
4351
4359
  const workspaceRoot = findWorkspaceRoot(cwd);
4352
4360
  const warnings = [];
4353
4361
  const foundryScope = mcpScope === "global" ? "global" : "project";
4354
4362
  const normalizedFoundryRuntime = normalizeMcpRuntime(foundryRuntime, "local");
4355
- const resolvedPostmanApiKey = normalizePostmanApiKey(process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR]);
4356
- const resolvedStitchApiKey = normalizePostmanApiKey(process.env[stitchApiKeyEnvVar || STITCH_API_KEY_ENV_VAR]);
4363
+ const cleanupLegacyServers = (servers) => {
4364
+ delete servers[POSTMAN_SKILL_ID];
4365
+ delete servers[STITCH_MCP_SERVER_ID];
4366
+ return servers;
4367
+ };
4357
4368
  let foundryDockerPort = DEFAULT_MCP_DOCKER_HOST_PORT;
4358
4369
  if (includeFoundryMcp && normalizedFoundryRuntime === "docker") {
4359
4370
  const runningPort = await resolveDockerContainerHostPort({
@@ -4381,13 +4392,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4381
4392
  !Array.isArray(next.mcpServers)
4382
4393
  ? { ...next.mcpServers }
4383
4394
  : {};
4384
- if (includePostmanMcp) {
4385
- mcpServers[POSTMAN_SKILL_ID] = buildGeminiPostmanServer({
4386
- apiKeyEnvVar,
4387
- apiKey: resolvedPostmanApiKey,
4388
- mcpUrl,
4389
- });
4390
- }
4395
+ cleanupLegacyServers(mcpServers);
4391
4396
  if (includeFoundryMcp) {
4392
4397
  mcpServers[FOUNDRY_MCP_SERVER_ID] = buildGeminiFoundryServer({
4393
4398
  scope: foundryScope,
@@ -4398,13 +4403,6 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4398
4403
  else {
4399
4404
  delete mcpServers[FOUNDRY_MCP_SERVER_ID];
4400
4405
  }
4401
- if (includeStitchMcp) {
4402
- mcpServers[STITCH_MCP_SERVER_ID] = buildGeminiStitchServer({
4403
- apiKeyEnvVar: stitchApiKeyEnvVar,
4404
- apiKey: resolvedStitchApiKey,
4405
- mcpUrl: stitchMcpUrl,
4406
- });
4407
- }
4408
4406
  if (includePlaywrightMcp) {
4409
4407
  mcpServers[PLAYWRIGHT_MCP_SERVER_ID] = buildGeminiPlaywrightServer();
4410
4408
  }
@@ -4435,13 +4433,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4435
4433
  !Array.isArray(next.mcpServers)
4436
4434
  ? { ...next.mcpServers }
4437
4435
  : {};
4438
- if (includePostmanMcp) {
4439
- mcpServers[POSTMAN_SKILL_ID] = buildCopilotCliPostmanServer({
4440
- apiKeyEnvVar,
4441
- apiKey: resolvedPostmanApiKey,
4442
- mcpUrl,
4443
- });
4444
- }
4436
+ cleanupLegacyServers(mcpServers);
4445
4437
  if (includeFoundryMcp) {
4446
4438
  mcpServers[FOUNDRY_MCP_SERVER_ID] = buildCopilotCliFoundryServer({
4447
4439
  scope: foundryScope,
@@ -4464,13 +4456,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4464
4456
  !Array.isArray(next.servers)
4465
4457
  ? { ...next.servers }
4466
4458
  : {};
4467
- if (includePostmanMcp) {
4468
- servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
4469
- apiKeyEnvVar,
4470
- apiKey: resolvedPostmanApiKey,
4471
- mcpUrl,
4472
- });
4473
- }
4459
+ cleanupLegacyServers(servers);
4474
4460
  if (includeFoundryMcp) {
4475
4461
  servers[FOUNDRY_MCP_SERVER_ID] = buildVsCodeFoundryServer({
4476
4462
  scope: foundryScope,
@@ -4517,13 +4503,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4517
4503
  !Array.isArray(next.servers)
4518
4504
  ? { ...next.servers }
4519
4505
  : {};
4520
- if (includePostmanMcp) {
4521
- servers[POSTMAN_SKILL_ID] = buildVsCodePostmanServer({
4522
- apiKeyEnvVar,
4523
- apiKey: resolvedPostmanApiKey,
4524
- mcpUrl,
4525
- });
4526
- }
4506
+ cleanupLegacyServers(servers);
4527
4507
  if (includeFoundryMcp) {
4528
4508
  servers[FOUNDRY_MCP_SERVER_ID] = buildVsCodeFoundryServer({
4529
4509
  scope: foundryScope,
@@ -4566,6 +4546,12 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4566
4546
  catch {
4567
4547
  // Best effort. Add will still run and becomes source of truth.
4568
4548
  }
4549
+ try {
4550
+ await execFile("codex", ["mcp", "remove", STITCH_MCP_SERVER_ID], { cwd });
4551
+ }
4552
+ catch {
4553
+ // Best effort. Add will still run and becomes source of truth.
4554
+ }
4569
4555
  try {
4570
4556
  await execFile("codex", ["mcp", "remove", FOUNDRY_MCP_SERVER_ID], {
4571
4557
  cwd,
@@ -4574,41 +4560,13 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4574
4560
  catch {
4575
4561
  // Best effort. Add will still run and becomes source of truth.
4576
4562
  }
4577
- if (includePostmanMcp) {
4578
- try {
4579
- await execFile("codex", [
4580
- "mcp",
4581
- "add",
4582
- POSTMAN_SKILL_ID,
4583
- "--url",
4584
- mcpUrl,
4585
- "--bearer-token-env-var",
4586
- apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR,
4587
- ], { cwd });
4588
- const postmanToken = normalizePostmanApiKey(process.env[apiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR]);
4589
- const postmanPatch = await patchCodexPostmanHttpHeaders({
4590
- configPath: codexConfigPath,
4591
- mcpUrl,
4592
- bearerToken: postmanToken,
4593
- dryRun: false,
4594
- });
4595
- if (postmanPatch.action === "patched") {
4596
- warnings.push("Codex Postman MCP config patched to static Authorization header for startup reliability.");
4597
- }
4598
- if (postmanPatch.warnings?.length) {
4599
- warnings.push(...postmanPatch.warnings);
4600
- }
4601
- }
4602
- catch (error) {
4603
- warnings.push(`Failed to register Postman MCP via Codex CLI. Ensure 'codex' is installed and rerun. (${error.message})`);
4604
- return {
4605
- kind: "codex-cli",
4606
- scope: mcpScope,
4607
- path: codexConfigPath,
4608
- action: "failed",
4609
- warnings,
4610
- };
4611
- }
4563
+ try {
4564
+ await execFile("codex", ["mcp", "remove", PLAYWRIGHT_MCP_SERVER_ID], {
4565
+ cwd,
4566
+ });
4567
+ }
4568
+ catch {
4569
+ // Best effort. Add will still run and becomes source of truth.
4612
4570
  }
4613
4571
  if (includeFoundryMcp) {
4614
4572
  try {
@@ -4636,6 +4594,14 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4636
4594
  warnings.push(`Failed to register ${FOUNDRY_MCP_SERVER_ID} MCP via Codex CLI. Ensure 'cbx' and 'codex' are installed and rerun. (${error.message})`);
4637
4595
  }
4638
4596
  }
4597
+ if (includePlaywrightMcp) {
4598
+ try {
4599
+ await execFile("codex", ["mcp", "add", PLAYWRIGHT_MCP_SERVER_ID, "--url", PLAYWRIGHT_MCP_URL], { cwd });
4600
+ }
4601
+ catch (error) {
4602
+ warnings.push(`Failed to register ${PLAYWRIGHT_MCP_SERVER_ID} MCP via Codex CLI. Ensure 'codex' is installed and rerun. (${error.message})`);
4603
+ }
4604
+ }
4639
4605
  return {
4640
4606
  kind: "codex-cli",
4641
4607
  scope: mcpScope,
@@ -4657,6 +4623,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4657
4623
  !Array.isArray(next.mcpServers)
4658
4624
  ? { ...next.mcpServers }
4659
4625
  : {};
4626
+ cleanupLegacyServers(mcpServers);
4660
4627
  if (includeFoundryMcp) {
4661
4628
  if (normalizedFoundryRuntime === "docker") {
4662
4629
  mcpServers[FOUNDRY_MCP_SERVER_ID] = {
@@ -4700,7 +4667,7 @@ async function applyPostmanMcpForPlatform({ platform, mcpScope, apiKeyEnvVar, mc
4700
4667
  path: null,
4701
4668
  action: "skipped",
4702
4669
  warnings: [
4703
- `Unsupported platform '${platform}' for Postman MCP installation.`,
4670
+ `Unsupported platform '${platform}' for Foundry MCP installation.`,
4704
4671
  ],
4705
4672
  };
4706
4673
  }
@@ -4735,11 +4702,24 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4735
4702
  throw new Error("Inline API keys are no longer allowed. Use environment variables and --env-var profiles (for example POSTMAN_API_KEY_* and STITCH_API_KEY_*).");
4736
4703
  }
4737
4704
  const stitchRequested = Boolean(options.stitch);
4705
+ const playwrightRequested = Boolean(options.playwright);
4738
4706
  const postmanRequested = Boolean(options.postman) ||
4739
4707
  hasWorkspaceOption ||
4740
4708
  options.postmanMode !== undefined;
4741
- const foundryOnlyRequested = options.foundryMcp === true && !postmanRequested && !stitchRequested;
4742
- const enabled = postmanRequested || stitchRequested || foundryOnlyRequested;
4709
+ const stitchEnabled = stitchRequested;
4710
+ const gatewayRequested = postmanRequested || stitchEnabled;
4711
+ const foundryMcpRequested = options.foundryMcp === true;
4712
+ const foundryMcpEnabled = options.foundryMcp === false && !gatewayRequested
4713
+ ? false
4714
+ : foundryMcpRequested || gatewayRequested;
4715
+ const foundryOnlyRequested = foundryMcpRequested &&
4716
+ !postmanRequested &&
4717
+ !stitchRequested &&
4718
+ !playwrightRequested;
4719
+ const enabled = postmanRequested ||
4720
+ stitchRequested ||
4721
+ playwrightRequested ||
4722
+ foundryOnlyRequested;
4743
4723
  if (!enabled)
4744
4724
  return { enabled: false };
4745
4725
  const requestedPostmanMode = postmanRequested
@@ -4758,20 +4738,19 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4758
4738
  : null;
4759
4739
  let mcpScope = requestedMcpScope?.scope || "project";
4760
4740
  const warnings = [];
4741
+ if (options.foundryMcp === false && gatewayRequested) {
4742
+ warnings.push("Ignoring --no-foundry-mcp because Postman/Stitch now route through the Cubis Foundry MCP gateway.");
4743
+ }
4761
4744
  if (requestedMcpScope?.warning) {
4762
4745
  warnings.push(requestedMcpScope.warning);
4763
4746
  }
4764
- const stitchEnabled = stitchRequested ||
4765
- (platform === "antigravity" &&
4766
- options.stitchDefaultForAntigravity !== false);
4767
4747
  const envStitchApiKey = normalizePostmanApiKey(process.env[STITCH_API_KEY_ENV_VAR]);
4768
- const requestedRuntime = normalizeMcpRuntime(options.mcpRuntime, DEFAULT_MCP_RUNTIME);
4748
+ const requestedRuntime = normalizeMcpRuntime(options.mcpRuntime, foundryMcpEnabled ? DEFAULT_MCP_RUNTIME : "local");
4769
4749
  const requestedFallback = normalizeMcpFallback(options.mcpFallback, DEFAULT_MCP_FALLBACK);
4770
4750
  const requestedImage = normalizePostmanApiKey(options.mcpImage) || DEFAULT_MCP_DOCKER_IMAGE;
4771
4751
  const requestedUpdatePolicy = normalizeMcpUpdatePolicy(options.mcpUpdatePolicy, DEFAULT_MCP_UPDATE_POLICY);
4772
4752
  const mcpBuildLocal = Boolean(options.mcpBuildLocal);
4773
- const mcpToolSync = options.mcpToolSync !== false;
4774
- const foundryMcpEnabled = options.foundryMcp !== false;
4753
+ const mcpToolSync = options.mcpToolSync !== false && (postmanRequested || stitchEnabled);
4775
4754
  const canPrompt = !options.yes && !options.dryRun && !process.env.CI && process.stdin.isTTY;
4776
4755
  if (postmanRequested && canPrompt && !hasWorkspaceOption) {
4777
4756
  const workspaceSelection = await promptPostmanWorkspaceSelection({
@@ -4782,10 +4761,10 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4782
4761
  warnings.push(...workspaceSelection.warnings);
4783
4762
  workspaceSelectionSource = "interactive";
4784
4763
  }
4785
- let effectiveRuntime = requestedRuntime;
4786
- let runtimeSkipped = false;
4787
- let dockerImageAction = "not-requested";
4788
- if (requestedRuntime === "docker") {
4764
+ let effectiveRuntime = foundryMcpEnabled ? requestedRuntime : null;
4765
+ let runtimeSkipped = !foundryMcpEnabled;
4766
+ let dockerImageAction = foundryMcpEnabled ? "not-requested" : "not-needed";
4767
+ if (foundryMcpEnabled && requestedRuntime === "docker") {
4789
4768
  const dockerAvailable = await checkDockerAvailable({ cwd });
4790
4769
  if (!dockerAvailable) {
4791
4770
  if (requestedFallback === "fail") {
@@ -4852,10 +4831,10 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4852
4831
  generatedAt: new Date().toISOString(),
4853
4832
  mcp: {
4854
4833
  scope: mcpScope,
4855
- server: postmanRequested
4856
- ? POSTMAN_SKILL_ID
4857
- : stitchEnabled
4858
- ? STITCH_MCP_SERVER_ID
4834
+ server: foundryMcpEnabled || gatewayRequested
4835
+ ? FOUNDRY_MCP_SERVER_ID
4836
+ : playwrightRequested
4837
+ ? PLAYWRIGHT_MCP_SERVER_ID
4859
4838
  : FOUNDRY_MCP_SERVER_ID,
4860
4839
  platform,
4861
4840
  runtime: requestedRuntime,
@@ -4896,11 +4875,19 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4896
4875
  mcpUrl: STITCH_MCP_URL,
4897
4876
  };
4898
4877
  }
4878
+ if (playwrightRequested) {
4879
+ cbxConfig.playwright = {
4880
+ enabled: true,
4881
+ server: PLAYWRIGHT_MCP_SERVER_ID,
4882
+ mcpUrl: PLAYWRIGHT_MCP_URL,
4883
+ };
4884
+ }
4899
4885
  return {
4900
4886
  enabled: true,
4901
4887
  postmanEnabled: postmanRequested,
4902
4888
  apiKeySource,
4903
4889
  stitchEnabled,
4890
+ playwrightEnabled: playwrightRequested,
4904
4891
  stitchApiKeySource,
4905
4892
  mcpRuntime: requestedRuntime,
4906
4893
  effectiveMcpRuntime: runtimeSkipped ? null : effectiveRuntime,
@@ -4921,7 +4908,7 @@ async function resolvePostmanInstallSelection({ platform, scope, options, cwd =
4921
4908
  cbxConfigPath,
4922
4909
  };
4923
4910
  }
4924
- async function configurePostmanInstallArtifacts({ platform, scope, profilePaths, postmanSelection, overwrite = false, dryRun = false, cwd = process.cwd(), }) {
4911
+ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths, postmanSelection, overwrite = false, persistCredentials = true, dryRun = false, cwd = process.cwd(), }) {
4925
4912
  if (!postmanSelection?.enabled)
4926
4913
  return null;
4927
4914
  const shouldInstallPostman = Boolean(postmanSelection.postmanEnabled);
@@ -5041,42 +5028,26 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
5041
5028
  });
5042
5029
  gitIgnoreResults.push(mcpIgnore);
5043
5030
  }
5044
- let mcpDefinitionPath = null;
5045
- let mcpDefinitionResult = null;
5031
+ const legacyDefinitionCleanupResults = [];
5046
5032
  if (shouldInstallPostman) {
5047
- mcpDefinitionPath = resolvePostmanMcpDefinitionPath({
5048
- platform,
5049
- scope: postmanSelection.mcpScope,
5050
- cwd,
5051
- });
5052
- const mcpDefinitionContent = `${JSON.stringify(buildPostmanMcpDefinition({
5053
- apiKeyEnvVar: effectiveApiKeyEnvVar,
5054
- apiKey: envApiKey,
5055
- mcpUrl: effectiveMcpUrl,
5056
- }), null, 2)}\n`;
5057
- mcpDefinitionResult = await writeGeneratedArtifact({
5058
- destination: mcpDefinitionPath,
5059
- content: mcpDefinitionContent,
5033
+ legacyDefinitionCleanupResults.push(await removeGeneratedArtifactIfExists({
5034
+ targetPath: resolvePostmanMcpDefinitionPath({
5035
+ platform,
5036
+ scope: postmanSelection.mcpScope,
5037
+ cwd,
5038
+ }),
5060
5039
  dryRun,
5061
- });
5040
+ }));
5062
5041
  }
5063
- let stitchMcpDefinitionPath = null;
5064
- let stitchMcpDefinitionResult = null;
5065
5042
  if (shouldInstallStitch) {
5066
- stitchMcpDefinitionPath = resolveStitchMcpDefinitionPath({
5067
- scope: postmanSelection.mcpScope,
5068
- cwd,
5069
- });
5070
- const stitchMcpDefinitionContent = `${JSON.stringify(buildStitchMcpDefinition({
5071
- apiKeyEnvVar: effectiveStitchApiKeyEnvVar,
5072
- apiKey: envStitchApiKey,
5073
- mcpUrl: effectiveStitchMcpUrl,
5074
- }), null, 2)}\n`;
5075
- stitchMcpDefinitionResult = await writeGeneratedArtifact({
5076
- destination: stitchMcpDefinitionPath,
5077
- content: stitchMcpDefinitionContent,
5043
+ legacyDefinitionCleanupResults.push(await removeGeneratedArtifactIfExists({
5044
+ targetPath: resolveStitchMcpDefinitionPath({
5045
+ platform,
5046
+ scope: postmanSelection.mcpScope,
5047
+ cwd,
5048
+ }),
5078
5049
  dryRun,
5079
- });
5050
+ }));
5080
5051
  }
5081
5052
  const mcpRuntimeResult = postmanSelection.runtimeSkipped
5082
5053
  ? {
@@ -5131,6 +5102,21 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
5131
5102
  dryRun,
5132
5103
  })
5133
5104
  : null;
5105
+ const credentialEnvVarNames = [];
5106
+ if (persistCredentials && shouldInstallPostman && effectiveApiKeySource === "env") {
5107
+ credentialEnvVarNames.push(effectiveApiKeyEnvVar || POSTMAN_API_KEY_ENV_VAR);
5108
+ }
5109
+ if (persistCredentials &&
5110
+ shouldInstallStitch &&
5111
+ effectiveStitchApiKeySource === "env") {
5112
+ credentialEnvVarNames.push(effectiveStitchApiKeyEnvVar || STITCH_API_KEY_ENV_VAR);
5113
+ }
5114
+ const persistedCredentials = credentialEnvVarNames.length > 0
5115
+ ? await persistManagedCredentialsEnv({
5116
+ envVarNames: [...new Set(credentialEnvVarNames)],
5117
+ dryRun,
5118
+ })
5119
+ : null;
5134
5120
  return {
5135
5121
  enabled: true,
5136
5122
  mcpScope: postmanSelection.mcpScope,
@@ -5144,10 +5130,14 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
5144
5130
  mcpToolSync: postmanSelection.mcpToolSync,
5145
5131
  foundryMcpEnabled: postmanSelection.foundryMcpEnabled,
5146
5132
  postmanEnabled: shouldInstallPostman,
5133
+ playwrightEnabled: Boolean(postmanSelection.playwrightEnabled),
5147
5134
  postmanMode: shouldInstallPostman && effectiveMcpUrl
5148
5135
  ? resolvePostmanModeFromUrl(effectiveMcpUrl, DEFAULT_POSTMAN_INSTALL_MODE)
5149
5136
  : null,
5150
5137
  postmanMcpUrl: shouldInstallPostman ? effectiveMcpUrl : null,
5138
+ playwrightMcpUrl: postmanSelection.playwrightEnabled
5139
+ ? PLAYWRIGHT_MCP_URL
5140
+ : null,
5151
5141
  apiKeySource: effectiveApiKeySource,
5152
5142
  stitchApiKeySource: effectiveStitchApiKeySource,
5153
5143
  defaultWorkspaceId: effectiveDefaultWorkspaceId,
@@ -5155,13 +5145,11 @@ async function configurePostmanInstallArtifacts({ platform, scope, profilePaths,
5155
5145
  cbxConfigPath: postmanSelection.cbxConfigPath,
5156
5146
  cbxConfigResult,
5157
5147
  gitIgnoreResults,
5158
- mcpDefinitionPath,
5159
- mcpDefinitionResult,
5160
- stitchMcpDefinitionPath,
5161
- stitchMcpDefinitionResult,
5148
+ legacyDefinitionCleanupResults,
5162
5149
  mcpRuntimeResult,
5163
5150
  mcpCatalogSyncResults,
5164
5151
  legacySkillMcpCleanup,
5152
+ persistedCredentials,
5165
5153
  };
5166
5154
  }
5167
5155
  function resolveMcpScopeFromConfigDocument(configValue, fallbackScope) {
@@ -5179,50 +5167,50 @@ function resolveMcpScopeFromConfigDocument(configValue, fallbackScope) {
5179
5167
  }
5180
5168
  async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dryRun = false, cwd = process.cwd(), }) {
5181
5169
  const warnings = [];
5182
- const postmanState = ensureCredentialServiceState(configValue, "postman");
5170
+ const storedPostmanState = parseStoredPostmanConfig(configValue);
5171
+ const postmanEnabled = Boolean(storedPostmanState);
5172
+ const postmanState = storedPostmanState ||
5173
+ parseStoredCredentialServiceConfig({ service: "postman", rawService: {} });
5183
5174
  const stitchState = parseStoredStitchConfig(configValue);
5184
- const postmanApiKeyEnvVar = normalizePostmanApiKey(postmanState.apiKeyEnvVar) ||
5185
- POSTMAN_API_KEY_ENV_VAR;
5186
- const postmanMcpUrl = postmanState.mcpUrl || POSTMAN_MCP_URL;
5175
+ const postmanApiKeyEnvVar = postmanEnabled
5176
+ ? normalizePostmanApiKey(postmanState.apiKeyEnvVar) ||
5177
+ POSTMAN_API_KEY_ENV_VAR
5178
+ : POSTMAN_API_KEY_ENV_VAR;
5179
+ const postmanMcpUrl = postmanEnabled
5180
+ ? postmanState.mcpUrl || POSTMAN_MCP_URL
5181
+ : POSTMAN_MCP_URL;
5187
5182
  const stitchEnabled = Boolean(stitchState);
5188
- const playwrightEnabled = Boolean(configValue?.playwright);
5183
+ const playwrightConfig = configValue?.playwright &&
5184
+ typeof configValue.playwright === "object" &&
5185
+ !Array.isArray(configValue.playwright)
5186
+ ? configValue.playwright
5187
+ : null;
5188
+ const playwrightEnabled = Boolean(playwrightConfig?.enabled ?? configValue?.playwright);
5189
+ const playwrightMcpUrl = String(playwrightConfig?.mcpUrl || PLAYWRIGHT_MCP_URL).trim() ||
5190
+ PLAYWRIGHT_MCP_URL;
5189
5191
  const stitchApiKeyEnvVar = normalizePostmanApiKey(stitchState?.apiKeyEnvVar) || STITCH_API_KEY_ENV_VAR;
5190
5192
  const stitchMcpUrl = stitchState?.mcpUrl || STITCH_MCP_URL;
5191
5193
  const foundryRuntime = normalizeMcpRuntime(configValue?.mcp?.effectiveRuntime || configValue?.mcp?.runtime, "local");
5192
- const resolvedPostmanApiKey = normalizePostmanApiKey(process.env[postmanApiKeyEnvVar]);
5193
- const resolvedStitchApiKey = normalizePostmanApiKey(process.env[stitchApiKeyEnvVar]);
5194
- const mcpDefinitionPath = resolvePostmanMcpDefinitionPath({
5195
- platform,
5196
- scope: mcpScope,
5197
- cwd,
5198
- });
5199
- const mcpDefinitionContent = `${JSON.stringify(buildPostmanMcpDefinition({
5200
- apiKeyEnvVar: postmanApiKeyEnvVar,
5201
- apiKey: resolvedPostmanApiKey,
5202
- mcpUrl: postmanMcpUrl,
5203
- }), null, 2)}\n`;
5204
- const mcpDefinitionResult = await writeGeneratedArtifact({
5205
- destination: mcpDefinitionPath,
5206
- content: mcpDefinitionContent,
5207
- dryRun,
5208
- });
5209
- let stitchMcpDefinitionPath = null;
5210
- let stitchMcpDefinitionResult = null;
5194
+ const legacyDefinitionCleanupResults = [];
5195
+ if (postmanEnabled && platform) {
5196
+ legacyDefinitionCleanupResults.push(await removeGeneratedArtifactIfExists({
5197
+ targetPath: resolvePostmanMcpDefinitionPath({
5198
+ platform,
5199
+ scope: mcpScope,
5200
+ cwd,
5201
+ }),
5202
+ dryRun,
5203
+ }));
5204
+ }
5211
5205
  if (stitchEnabled) {
5212
- stitchMcpDefinitionPath = resolveStitchMcpDefinitionPath({
5213
- scope: mcpScope,
5214
- cwd,
5215
- });
5216
- const stitchMcpDefinitionContent = `${JSON.stringify(buildStitchMcpDefinition({
5217
- apiKeyEnvVar: stitchApiKeyEnvVar,
5218
- apiKey: resolvedStitchApiKey,
5219
- mcpUrl: stitchMcpUrl,
5220
- }), null, 2)}\n`;
5221
- stitchMcpDefinitionResult = await writeGeneratedArtifact({
5222
- destination: stitchMcpDefinitionPath,
5223
- content: stitchMcpDefinitionContent,
5206
+ legacyDefinitionCleanupResults.push(await removeGeneratedArtifactIfExists({
5207
+ targetPath: resolveStitchMcpDefinitionPath({
5208
+ platform,
5209
+ scope: mcpScope,
5210
+ cwd,
5211
+ }),
5224
5212
  dryRun,
5225
- });
5213
+ }));
5226
5214
  }
5227
5215
  let mcpRuntimeResult = null;
5228
5216
  if (!platform) {
@@ -5234,6 +5222,7 @@ async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dr
5234
5222
  mcpScope,
5235
5223
  apiKeyEnvVar: postmanApiKeyEnvVar,
5236
5224
  mcpUrl: postmanMcpUrl,
5225
+ includePostmanMcp: postmanEnabled,
5237
5226
  stitchApiKeyEnvVar,
5238
5227
  stitchMcpUrl,
5239
5228
  includeStitchMcp: stitchEnabled,
@@ -5246,10 +5235,10 @@ async function applyPostmanConfigArtifacts({ platform, mcpScope, configValue, dr
5246
5235
  warnings.push(...(mcpRuntimeResult.warnings || []));
5247
5236
  }
5248
5237
  return {
5249
- mcpDefinitionPath,
5250
- mcpDefinitionResult,
5251
- stitchMcpDefinitionPath,
5252
- stitchMcpDefinitionResult,
5238
+ postmanEnabled,
5239
+ playwrightEnabled,
5240
+ playwrightMcpUrl: playwrightEnabled ? playwrightMcpUrl : null,
5241
+ legacyDefinitionCleanupResults,
5253
5242
  mcpRuntimeResult,
5254
5243
  warnings,
5255
5244
  };
@@ -5509,6 +5498,11 @@ async function installBundleArtifacts({ bundleId, manifest, platform, scope, ove
5509
5498
  platformSpec.prompts.length > 0) {
5510
5499
  await mkdir(profilePaths.promptsDir, { recursive: true });
5511
5500
  }
5501
+ if (profilePaths.hooksDir &&
5502
+ Array.isArray(platformSpec.hooks) &&
5503
+ platformSpec.hooks.some((entry) => typeof entry?.file === "string")) {
5504
+ await mkdir(profilePaths.hooksDir, { recursive: true });
5505
+ }
5512
5506
  }
5513
5507
  const bundleRoot = path.join(agentAssetsRoot(), "workflows", bundleId);
5514
5508
  const platformRoot = path.join(bundleRoot, "platforms", platform);
@@ -5520,6 +5514,7 @@ async function installBundleArtifacts({ bundleId, manifest, platform, scope, ove
5520
5514
  skills: [],
5521
5515
  commands: [],
5522
5516
  prompts: [],
5517
+ hooks: [],
5523
5518
  };
5524
5519
  // Bind useSymlinks into copyArtifact so every call site inherits it
5525
5520
  const copyArt = (args) => copyArtifact({ ...args, useSymlinks });
@@ -5613,6 +5608,35 @@ async function installBundleArtifacts({ bundleId, manifest, platform, scope, ove
5613
5608
  else
5614
5609
  installed.push(destination);
5615
5610
  }
5611
+ const hookFiles = Array.isArray(platformSpec.hooks)
5612
+ ? platformSpec.hooks
5613
+ .map((entry) => typeof entry === "string"
5614
+ ? entry
5615
+ : typeof entry?.file === "string"
5616
+ ? entry.file
5617
+ : null)
5618
+ .filter(Boolean)
5619
+ : [];
5620
+ for (const hookFile of hookFiles) {
5621
+ if (!profilePaths.hooksDir)
5622
+ continue;
5623
+ const source = path.join(platformRoot, "hooks", hookFile);
5624
+ const destination = path.join(profilePaths.hooksDir, path.basename(hookFile));
5625
+ if (!(await pathExists(source))) {
5626
+ throw new Error(`Missing hook source file: ${source}`);
5627
+ }
5628
+ const result = await copyArt({
5629
+ source,
5630
+ destination,
5631
+ overwrite,
5632
+ dryRun,
5633
+ });
5634
+ artifacts.hooks.push(destination);
5635
+ if (result.action === "skipped" || result.action === "would-skip")
5636
+ skipped.push(destination);
5637
+ else
5638
+ installed.push(destination);
5639
+ }
5616
5640
  if (shouldInstallPlatformSkills) {
5617
5641
  const agentSkillDependencies = await resolvePlatformAgentSkillDependencies({
5618
5642
  platformRoot,
@@ -5837,6 +5861,20 @@ async function removeBundleArtifacts({ bundleId, manifest, platform, scope, prof
5837
5861
  if (await safeRemove(destination, dryRun))
5838
5862
  removed.push(destination);
5839
5863
  }
5864
+ for (const hookEntry of platformSpec.hooks || []) {
5865
+ if (!profilePaths.hooksDir)
5866
+ continue;
5867
+ const hookFile = typeof hookEntry === "string"
5868
+ ? hookEntry
5869
+ : typeof hookEntry?.file === "string"
5870
+ ? hookEntry.file
5871
+ : null;
5872
+ if (!hookFile)
5873
+ continue;
5874
+ const destination = path.join(profilePaths.hooksDir, path.basename(hookFile));
5875
+ if (await safeRemove(destination, dryRun))
5876
+ removed.push(destination);
5877
+ }
5840
5878
  const skillIds = await resolveInstallSkillIds({
5841
5879
  platformSpec,
5842
5880
  extraSkillIds: [],
@@ -5989,11 +6027,14 @@ function printPostmanSetupSummary({ postmanSetup }) {
5989
6027
  return;
5990
6028
  console.log("\nMCP setup:");
5991
6029
  console.log(`- MCP scope: ${postmanSetup.mcpScope}`);
6030
+ if (postmanSetup.playwrightEnabled) {
6031
+ console.log(`- Playwright MCP: enabled (${postmanSetup.playwrightMcpUrl || PLAYWRIGHT_MCP_URL})`);
6032
+ }
5992
6033
  if (postmanSetup.postmanEnabled && postmanSetup.postmanMode) {
5993
6034
  console.log(`- Postman mode: ${postmanSetup.postmanMode}`);
5994
6035
  }
5995
6036
  if (postmanSetup.postmanEnabled && postmanSetup.postmanMcpUrl) {
5996
- console.log(`- Postman MCP URL: ${postmanSetup.postmanMcpUrl}`);
6037
+ console.log(`- Postman upstream MCP URL: ${postmanSetup.postmanMcpUrl}`);
5997
6038
  }
5998
6039
  console.log(`- Config file: ${postmanSetup.cbxConfigResult.action} (${postmanSetup.cbxConfigPath})`);
5999
6040
  console.log(`- MCP runtime (requested): ${postmanSetup.mcpRuntime}`);
@@ -6004,7 +6045,7 @@ function printPostmanSetupSummary({ postmanSetup }) {
6004
6045
  console.log(`- MCP build local: ${postmanSetup.mcpBuildLocal ? "yes" : "no"}`);
6005
6046
  console.log(`- MCP image prepare: ${postmanSetup.dockerImageAction}`);
6006
6047
  console.log(`- MCP tool sync: ${postmanSetup.mcpToolSync ? "enabled" : "disabled"}`);
6007
- console.log(`- Foundry MCP side-by-side: ${postmanSetup.foundryMcpEnabled ? (postmanSetup.effectiveMcpRuntime === "docker" ? "enabled (docker endpoint)" : "enabled (cbx mcp serve)") : "disabled"}`);
6048
+ console.log(`- Foundry MCP gateway: ${postmanSetup.foundryMcpEnabled ? (postmanSetup.effectiveMcpRuntime === "docker" ? "enabled (docker endpoint)" : "enabled (cbx mcp serve)") : "disabled"}`);
6008
6049
  if (postmanSetup.postmanEnabled) {
6009
6050
  console.log(`- Postman API key source: ${postmanSetup.apiKeySource}`);
6010
6051
  }
@@ -6017,12 +6058,8 @@ function printPostmanSetupSummary({ postmanSetup }) {
6017
6058
  for (const ignoreResult of postmanSetup.gitIgnoreResults || []) {
6018
6059
  console.log(`- .gitignore (${ignoreResult.filePath}): ${ignoreResult.action}`);
6019
6060
  }
6020
- if (postmanSetup.mcpDefinitionPath && postmanSetup.mcpDefinitionResult) {
6021
- console.log(`- Managed MCP definition (${postmanSetup.mcpDefinitionPath}): ${postmanSetup.mcpDefinitionResult.action}`);
6022
- }
6023
- if (postmanSetup.stitchMcpDefinitionPath &&
6024
- postmanSetup.stitchMcpDefinitionResult) {
6025
- console.log(`- Managed Stitch MCP definition (${postmanSetup.stitchMcpDefinitionPath}): ${postmanSetup.stitchMcpDefinitionResult.action}`);
6061
+ for (const cleanupResult of postmanSetup.legacyDefinitionCleanupResults || []) {
6062
+ console.log(`- Legacy direct MCP cleanup (${cleanupResult.path}): ${cleanupResult.action}`);
6026
6063
  }
6027
6064
  if (postmanSetup.mcpRuntimeResult) {
6028
6065
  console.log(`- Platform MCP target (${postmanSetup.mcpRuntimeResult.path || "n/a"}): ${postmanSetup.mcpRuntimeResult.action}`);
@@ -6037,6 +6074,13 @@ function printPostmanSetupSummary({ postmanSetup }) {
6037
6074
  }
6038
6075
  }
6039
6076
  }
6077
+ if (postmanSetup.persistedCredentials) {
6078
+ console.log(`- Credential vault (${postmanSetup.persistedCredentials.envPath}): ${postmanSetup.persistedCredentials.action}`);
6079
+ console.log(`- Credential vars: ${postmanSetup.persistedCredentials.persisted.length > 0 ? postmanSetup.persistedCredentials.persisted.join(", ") : "(none)"}`);
6080
+ if (postmanSetup.persistedCredentials.missing.length > 0) {
6081
+ console.log(`- Missing credential vars: ${postmanSetup.persistedCredentials.missing.join(", ")}`);
6082
+ }
6083
+ }
6040
6084
  if (postmanSetup.legacySkillMcpCleanup) {
6041
6085
  console.log(`- Legacy skill mcp.json cleanup (${postmanSetup.legacySkillMcpCleanup.path}): ${postmanSetup.legacySkillMcpCleanup.action}`);
6042
6086
  }
@@ -6328,9 +6372,10 @@ function withInstallOptions(command) {
6328
6372
  .option("--scope <scope>", "install scope: project (global is accepted but coerced to project)", "project")
6329
6373
  .option("-b, --bundle <bundle>", "bundle id (default: agent-environment-setup)")
6330
6374
  .option("--overwrite", "overwrite existing files")
6331
- .option("--postman", "optional: install Postman skill and generate cbx_config.json")
6375
+ .option("--postman", "optional: configure Postman profiles and gateway-backed Foundry MCP wiring")
6332
6376
  .option("--postman-mode <mode>", "Postman MCP mode for --postman: minimal|code|full (default: full)")
6333
- .option("--stitch", "optional: include Stitch MCP profile/config alongside Postman")
6377
+ .option("--stitch", "optional: configure Stitch profiles and gateway-backed Foundry MCP wiring")
6378
+ .option("--playwright", "optional: include Playwright MCP server wiring")
6334
6379
  .option("--postman-api-key <key>", "deprecated: inline key mode is disabled. Use env vars + profiles.")
6335
6380
  .option("--postman-workspace-id <id|null>", "optional: set default Postman workspace ID (use 'null' for no default)")
6336
6381
  .option("--stitch-api-key <key>", "deprecated: inline key mode is disabled. Use env vars + profiles.")
@@ -6342,10 +6387,10 @@ function withInstallOptions(command) {
6342
6387
  .option("--mcp-build-local", "build MCP Docker image from local package mcp/ directory instead of pulling")
6343
6388
  .option("--mcp-tool-sync", "enable automatic MCP tool catalog sync (default: enabled)")
6344
6389
  .option("--no-mcp-tool-sync", "disable automatic MCP tool catalog sync")
6345
- .option("--no-foundry-mcp", "disable side-by-side cubis-foundry MCP registration during --postman setup")
6390
+ .option("--no-foundry-mcp", "deprecated: Postman/Stitch always use Cubis Foundry MCP gateway wiring")
6346
6391
  .option("--terminal-integration", "Antigravity only: enable terminal verification integration (prompts for verifier when interactive)")
6347
6392
  .option("--terminal-verifier <provider>", "Antigravity only: verifier provider (codex|gemini). Implies --terminal-integration.")
6348
- .option("--skill-profile <profile>", "skill install profile: core|web-backend|full (default: core)", DEFAULT_SKILL_PROFILE)
6393
+ .option("--skill-profile <profile>", "skill install profile: core|web-backend|full", DEFAULT_SKILL_PROFILE)
6349
6394
  .option("--all-skills", "alias for --skill-profile full")
6350
6395
  .option("--target <path>", "install into target project directory instead of cwd")
6351
6396
  .option("--link", "create symlinks instead of copies (edits in source are instantly reflected)")
@@ -6618,6 +6663,7 @@ async function performWorkflowInstall(options, { postmanSelectionOverride = null
6618
6663
  profilePaths: installResult.profilePaths,
6619
6664
  postmanSelection,
6620
6665
  overwrite: Boolean(options.overwrite),
6666
+ persistCredentials: !options.initWizardMode,
6621
6667
  dryRun,
6622
6668
  cwd,
6623
6669
  });
@@ -7370,14 +7416,16 @@ async function runWorkflowRemoveAll(options) {
7370
7416
  dryRun,
7371
7417
  records: removedRecords,
7372
7418
  });
7373
- if (platform === "antigravity") {
7374
- await removePathRecord({
7375
- targetPath: resolveStitchMcpDefinitionPath({ scope, cwd }),
7376
- category: `${platform}/${scope}/stitch-mcp-definition`,
7377
- dryRun,
7378
- records: removedRecords,
7379
- });
7380
- }
7419
+ await removePathRecord({
7420
+ targetPath: resolveStitchMcpDefinitionPath({
7421
+ platform,
7422
+ scope,
7423
+ cwd,
7424
+ }),
7425
+ category: `${platform}/${scope}/stitch-mcp-definition`,
7426
+ dryRun,
7427
+ records: removedRecords,
7428
+ });
7381
7429
  const runtimeResults = await removePlatformMcpRuntimeTargets({
7382
7430
  platform,
7383
7431
  scope,
@@ -7651,7 +7699,7 @@ function prepareConfigDocument(existingValue, { scope, generatedBy }) {
7651
7699
  next.mcp = {};
7652
7700
  next.mcp.scope = scope;
7653
7701
  if (!next.mcp.server)
7654
- next.mcp.server = POSTMAN_SKILL_ID;
7702
+ next.mcp.server = FOUNDRY_MCP_SERVER_ID;
7655
7703
  return next;
7656
7704
  }
7657
7705
  function ensureCredentialServiceState(configValue, service) {
@@ -7880,26 +7928,127 @@ function migrateInlineCredentialsInConfig(configValue) {
7880
7928
  changed: JSON.stringify(next) !== JSON.stringify(configValue || {}),
7881
7929
  };
7882
7930
  }
7883
- async function collectInlineHeaderFindings({ scope, cwd = process.cwd() }) {
7931
+ function resolveCredentialLeakScanTargets({ scope, cwd = process.cwd() }) {
7932
+ const workspaceRoot = findWorkspaceRoot(cwd);
7933
+ const targets = new Set([
7934
+ resolveLegacyPostmanConfigPath({ scope, cwd }),
7935
+ scope === "global"
7936
+ ? path.join(os.homedir(), ".gemini", "settings.json")
7937
+ : path.join(workspaceRoot, ".gemini", "settings.json"),
7938
+ scope === "global"
7939
+ ? path.join(os.homedir(), ".claude", "mcp.json")
7940
+ : path.join(workspaceRoot, ".mcp.json"),
7941
+ scope === "global"
7942
+ ? path.join(os.homedir(), ".copilot", "mcp-config.json")
7943
+ : path.join(workspaceRoot, ".vscode", "mcp.json"),
7944
+ ]);
7945
+ if (scope === "global") {
7946
+ targets.add(path.join(os.homedir(), ".codex", "config.toml"));
7947
+ }
7948
+ for (const platform of Object.keys(WORKFLOW_PROFILES)) {
7949
+ targets.add(resolvePostmanMcpDefinitionPath({ platform, scope, cwd }));
7950
+ targets.add(resolveStitchMcpDefinitionPath({ platform, scope, cwd }));
7951
+ }
7952
+ return [...targets];
7953
+ }
7954
+ function collectCredentialLeakMatches(raw) {
7955
+ const matches = [];
7956
+ const patterns = [
7957
+ {
7958
+ id: "inline-apiKey-field",
7959
+ pattern: /"apiKey"\s*:\s*"(?!\$\{)[^"]+/i,
7960
+ },
7961
+ {
7962
+ id: "inline-bearer-header-json",
7963
+ pattern: /"Authorization"\s*:\s*"Bearer\s+(?!\$\{)[^"]+/i,
7964
+ },
7965
+ {
7966
+ id: "inline-bearer-header-toml",
7967
+ pattern: /http_headers\s*=\s*\{[^}]*Authorization\s*=\s*"Bearer\s+(?!\$\{)[^"]+/is,
7968
+ },
7969
+ {
7970
+ id: "inline-stitch-header-arg",
7971
+ pattern: /X-Goog-Api-Key:(?!\s*\$\{[A-Za-z_][A-Za-z0-9_]*\})\s*[^"\n]+/i,
7972
+ },
7973
+ {
7974
+ id: "inline-stitch-header-json",
7975
+ pattern: /"X-Goog-Api-Key"\s*:\s*"(?!\$\{)[^"]+/i,
7976
+ },
7977
+ ];
7978
+ for (const { id, pattern } of patterns) {
7979
+ if (pattern.test(raw)) {
7980
+ matches.push(id);
7981
+ }
7982
+ }
7983
+ return matches;
7984
+ }
7985
+ async function collectCredentialLeakFindings({ scope, cwd = process.cwd() }) {
7884
7986
  const findings = [];
7885
- const stitchDefinitionPath = resolveStitchMcpDefinitionPath({ scope, cwd });
7886
- const geminiSettingsPath = scope === "global"
7887
- ? path.join(os.homedir(), ".gemini", "settings.json")
7888
- : path.join(findWorkspaceRoot(cwd), ".gemini", "settings.json");
7889
- const scanFile = async (filePath) => {
7987
+ for (const filePath of resolveCredentialLeakScanTargets({ scope, cwd })) {
7890
7988
  if (!(await pathExists(filePath)))
7891
- return;
7989
+ continue;
7892
7990
  const raw = await readFile(filePath, "utf8");
7893
- const unsafeStitchHeader = /X-Goog-Api-Key:(?!\s*\$\{[A-Za-z_][A-Za-z0-9_]*\})\s*[^"\n]+/i;
7894
- const unsafeBearerHeader = /"Authorization"\s*:\s*"Bearer\s+(?!\$\{)[^"]+/i;
7895
- if (unsafeStitchHeader.test(raw) || unsafeBearerHeader.test(raw)) {
7896
- findings.push(filePath);
7991
+ const matches = collectCredentialLeakMatches(raw);
7992
+ if (matches.length > 0) {
7993
+ findings.push({ filePath, matches });
7897
7994
  }
7898
- };
7899
- await scanFile(stitchDefinitionPath);
7900
- await scanFile(geminiSettingsPath);
7995
+ }
7901
7996
  return findings;
7902
7997
  }
7998
+ async function cleanupLegacyDirectCredentialArtifacts({ scope, dryRun = false, cwd = process.cwd(), }) {
7999
+ const workspaceRoot = findWorkspaceRoot(cwd);
8000
+ const cleanupResults = [];
8001
+ const legacyServerIds = [POSTMAN_SKILL_ID, STITCH_MCP_SERVER_ID];
8002
+ cleanupResults.push(await removeMcpRuntimeEntriesJson({
8003
+ filePath: scope === "global"
8004
+ ? path.join(os.homedir(), ".gemini", "settings.json")
8005
+ : path.join(workspaceRoot, ".gemini", "settings.json"),
8006
+ keyName: "mcpServers",
8007
+ serverIds: legacyServerIds,
8008
+ dryRun,
8009
+ }));
8010
+ cleanupResults.push(await removeMcpRuntimeEntriesJson({
8011
+ filePath: scope === "global"
8012
+ ? path.join(os.homedir(), ".claude", "mcp.json")
8013
+ : path.join(workspaceRoot, ".mcp.json"),
8014
+ keyName: "mcpServers",
8015
+ serverIds: legacyServerIds,
8016
+ dryRun,
8017
+ }));
8018
+ if (scope === "global") {
8019
+ cleanupResults.push(await removeMcpRuntimeEntriesJson({
8020
+ filePath: path.join(os.homedir(), ".copilot", "mcp-config.json"),
8021
+ keyName: "mcpServers",
8022
+ serverIds: legacyServerIds,
8023
+ dryRun,
8024
+ }));
8025
+ cleanupResults.push(await removeMcpRuntimeEntriesCodexToml({
8026
+ filePath: path.join(os.homedir(), ".codex", "config.toml"),
8027
+ serverIds: legacyServerIds,
8028
+ dryRun,
8029
+ cwd,
8030
+ }));
8031
+ }
8032
+ else {
8033
+ cleanupResults.push(await removeMcpRuntimeEntriesJson({
8034
+ filePath: path.join(workspaceRoot, ".vscode", "mcp.json"),
8035
+ keyName: "servers",
8036
+ serverIds: legacyServerIds,
8037
+ dryRun,
8038
+ }));
8039
+ }
8040
+ for (const platform of Object.keys(WORKFLOW_PROFILES)) {
8041
+ cleanupResults.push(await removeGeneratedArtifactIfExists({
8042
+ targetPath: resolvePostmanMcpDefinitionPath({ platform, scope, cwd }),
8043
+ dryRun,
8044
+ }));
8045
+ cleanupResults.push(await removeGeneratedArtifactIfExists({
8046
+ targetPath: resolveStitchMcpDefinitionPath({ platform, scope, cwd }),
8047
+ dryRun,
8048
+ }));
8049
+ }
8050
+ return cleanupResults.filter((item) => item.action !== "missing" && item.action !== "unchanged");
8051
+ }
7903
8052
  async function runWorkflowConfigKeysList(options) {
7904
8053
  try {
7905
8054
  const opts = resolveActionOptions(options);
@@ -8126,6 +8275,7 @@ async function runWorkflowConfigKeysMigrateInline(options) {
8126
8275
  const scopeArg = readCliOptionFromArgv("--scope");
8127
8276
  const scope = normalizeMcpScope(scopeArg ?? opts.scope, "global");
8128
8277
  const dryRun = hasCliFlag("--dry-run") || Boolean(opts.dryRun);
8278
+ await loadManagedCredentialsEnv();
8129
8279
  const { configPath, existing, existingValue } = await loadConfigForScope({
8130
8280
  scope,
8131
8281
  cwd,
@@ -8140,6 +8290,21 @@ async function runWorkflowConfigKeysMigrateInline(options) {
8140
8290
  existingExists: existing.exists,
8141
8291
  dryRun,
8142
8292
  });
8293
+ const cleanupResults = await cleanupLegacyDirectCredentialArtifacts({
8294
+ scope,
8295
+ dryRun,
8296
+ cwd,
8297
+ });
8298
+ const platform = normalizePlatform(result.next?.mcp?.platform);
8299
+ const secureArtifacts = platform && WORKFLOW_PROFILES[platform]
8300
+ ? await applyPostmanConfigArtifacts({
8301
+ platform,
8302
+ mcpScope: resolveMcpScopeFromConfigDocument(result.next, scope),
8303
+ configValue: result.next,
8304
+ dryRun,
8305
+ cwd,
8306
+ })
8307
+ : null;
8143
8308
  console.log(`Config file: ${configPath}`);
8144
8309
  console.log(`Action: ${action}`);
8145
8310
  console.log(`Inline key fields found: ${result.findings.length}`);
@@ -8154,6 +8319,19 @@ async function runWorkflowConfigKeysMigrateInline(options) {
8154
8319
  console.log(`- ${envVar}`);
8155
8320
  }
8156
8321
  }
8322
+ console.log(`Legacy direct MCP cleanup actions: ${cleanupResults.length}`);
8323
+ for (const cleanup of cleanupResults) {
8324
+ console.log(`- ${cleanup.action} ${cleanup.path}`);
8325
+ }
8326
+ if (secureArtifacts?.mcpRuntimeResult) {
8327
+ console.log(`Secure platform MCP target: ${secureArtifacts.mcpRuntimeResult.action} (${secureArtifacts.mcpRuntimeResult.path || "n/a"})`);
8328
+ }
8329
+ for (const cleanup of secureArtifacts?.legacyDefinitionCleanupResults || []) {
8330
+ console.log(`- ${cleanup.action} ${cleanup.path}`);
8331
+ }
8332
+ for (const warning of secureArtifacts?.warnings || []) {
8333
+ console.log(`Warning: ${warning}`);
8334
+ }
8157
8335
  }
8158
8336
  catch (error) {
8159
8337
  if (error?.name === "ExitPromptError") {
@@ -8170,6 +8348,7 @@ async function runWorkflowConfigKeysDoctor(options) {
8170
8348
  const cwd = process.cwd();
8171
8349
  const scopeArg = readCliOptionFromArgv("--scope");
8172
8350
  const scope = normalizeMcpScope(scopeArg ?? opts.scope, "global");
8351
+ await loadManagedCredentialsEnv();
8173
8352
  const { configPath, existing, existingValue } = await loadConfigForScope({
8174
8353
  scope,
8175
8354
  cwd,
@@ -8180,15 +8359,15 @@ async function runWorkflowConfigKeysDoctor(options) {
8180
8359
  return;
8181
8360
  }
8182
8361
  const configFindings = collectInlineCredentialFindings(existingValue);
8183
- const artifactFindings = await collectInlineHeaderFindings({ scope, cwd });
8362
+ const artifactFindings = await collectCredentialLeakFindings({ scope, cwd });
8184
8363
  const migrationPreview = migrateInlineCredentialsInConfig(existingValue);
8185
8364
  console.log(`Inline key findings: ${configFindings.length}`);
8186
8365
  for (const finding of configFindings) {
8187
8366
  console.log(`- ${finding.path}`);
8188
8367
  }
8189
- console.log(`Unsafe header findings: ${artifactFindings.length}`);
8190
- for (const filePath of artifactFindings) {
8191
- console.log(`- ${filePath}`);
8368
+ console.log(`Credential leak findings: ${artifactFindings.length}`);
8369
+ for (const finding of artifactFindings) {
8370
+ console.log(`- ${finding.filePath} [${finding.matches.join(", ")}]`);
8192
8371
  }
8193
8372
  if (migrationPreview.requiredEnvVars.length > 0) {
8194
8373
  console.log("Expected env vars:");
@@ -8202,7 +8381,7 @@ async function runWorkflowConfigKeysDoctor(options) {
8202
8381
  else {
8203
8382
  console.log("Doctor result: issues detected. Run `cbx workflows config keys migrate-inline --scope " +
8204
8383
  scope +
8205
- "` and reinstall with `--overwrite`.");
8384
+ "` to scrub keys and reapply secure Foundry MCP wiring.");
8206
8385
  }
8207
8386
  }
8208
8387
  catch (error) {
@@ -8392,6 +8571,7 @@ async function runWorkflowConfig(options) {
8392
8571
  if (!next.mcp || typeof next.mcp !== "object" || Array.isArray(next.mcp)) {
8393
8572
  next.mcp = {};
8394
8573
  }
8574
+ next.mcp.server = FOUNDRY_MCP_SERVER_ID;
8395
8575
  if (hasMcpRuntimeOption) {
8396
8576
  next.mcp.runtime = mcpRuntime;
8397
8577
  next.mcp.effectiveRuntime = mcpRuntime;
@@ -8455,10 +8635,9 @@ async function runWorkflowConfig(options) {
8455
8635
  console.log(`postman.mode: ${effectivePostmanMode}`);
8456
8636
  console.log(`postman.mcpUrl: ${effectivePostmanState.mcpUrl}`);
8457
8637
  if (postmanArtifacts) {
8458
- console.log(`postman.definition: ${postmanArtifacts.mcpDefinitionResult.action} (${postmanArtifacts.mcpDefinitionPath})`);
8459
- if (postmanArtifacts.stitchMcpDefinitionPath &&
8460
- postmanArtifacts.stitchMcpDefinitionResult) {
8461
- console.log(`stitch.definition: ${postmanArtifacts.stitchMcpDefinitionResult.action} (${postmanArtifacts.stitchMcpDefinitionPath})`);
8638
+ for (const cleanupResult of postmanArtifacts.legacyDefinitionCleanupResults ||
8639
+ []) {
8640
+ console.log(`legacy.definition.cleanup: ${cleanupResult.action} (${cleanupResult.path})`);
8462
8641
  }
8463
8642
  if (postmanArtifacts.mcpRuntimeResult) {
8464
8643
  console.log(`platform.mcp.target: ${postmanArtifacts.mcpRuntimeResult.action} (${postmanArtifacts.mcpRuntimeResult.path || "n/a"})`);
@@ -9554,7 +9733,12 @@ function normalizeInitPlatforms(value) {
9554
9733
  return normalized;
9555
9734
  }
9556
9735
  function normalizeInitMcpSelections(value) {
9557
- const allowed = new Set(["cubis-foundry", "postman", "stitch"]);
9736
+ const allowed = new Set([
9737
+ "cubis-foundry",
9738
+ "postman",
9739
+ "stitch",
9740
+ "playwright",
9741
+ ]);
9558
9742
  const items = Array.isArray(value) ? value : parseCsvOption(value);
9559
9743
  const normalized = [];
9560
9744
  for (const item of items) {
@@ -9653,7 +9837,7 @@ async function runInitWizard(options) {
9653
9837
  if (selections.platforms.length === 0) {
9654
9838
  throw new Error("No platforms selected.");
9655
9839
  }
9656
- const runtimeSelectableMcp = selections.selectedMcps.length > 0;
9840
+ const runtimeSelectableMcp = selections.selectedMcps.some((item) => item !== "playwright");
9657
9841
  if (runtimeSelectableMcp && isInteractive) {
9658
9842
  const runtimeSelection = await promptInitMcpRuntime({
9659
9843
  defaultRuntime: selections.mcpRuntime,
@@ -9791,9 +9975,14 @@ async function runInitWizard(options) {
9791
9975
  }
9792
9976
  }
9793
9977
  if (emitJson) {
9978
+ const sanitizedSelections = {
9979
+ ...selections,
9980
+ postmanApiKey: selections.postmanApiKey ? "***REDACTED***" : null,
9981
+ stitchApiKey: selections.stitchApiKey ? "***REDACTED***" : null,
9982
+ };
9794
9983
  console.log(JSON.stringify({
9795
9984
  dryRun,
9796
- selections,
9985
+ selections: sanitizedSelections,
9797
9986
  results,
9798
9987
  persistedCredentials,
9799
9988
  }, null, 2));