@paradigma-inc/flywheel 0.1.53 → 0.1.72

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 +149 -17
  2. package/package.json +4 -2
  3. package/skills/flywheel/SKILL.md +4 -3
  4. package/skills/flywheel/getting-started/flywheel-quickstart.md +4 -4
  5. package/skills/flywheel/references/flywheel-cli-tool-map.md +47 -35
  6. package/skills/flywheel/references/flywheel-mcp-tool-map.md +16 -5
  7. package/skills/flywheel/setting-up-flywheel/claude-code-cli-installation.md +3 -3
  8. package/skills/flywheel/setting-up-flywheel/codex-cli-installation.md +3 -3
  9. package/skills/flywheel/setting-up-flywheel/installation-overview.md +9 -8
  10. package/skills/flywheel/setting-up-flywheel/other-hosts-installation.md +1 -1
  11. package/skills/flywheel/setting-up-flywheel/updating-flywheel-mcp.md +4 -4
  12. package/skills/flywheel-auto/SKILL.md +4 -3
  13. package/skills/flywheel-auto/references/flywheel-cli-tool-map.md +37 -35
  14. package/skills/flywheel-auto/references/flywheel-mcp-tool-map.md +4 -4
  15. package/skills/flywheel-lookahead/SKILL.md +1 -1
  16. package/skills/flywheel-lookahead/references/flywheel-cli-tool-map.md +37 -35
  17. package/skills/flywheel-lookahead/references/flywheel-mcp-tool-map.md +4 -4
  18. package/skills/flywheel-prove/SKILL.md +1 -1
  19. package/skills/flywheel-reproduce/SKILL.md +4 -3
  20. package/skills/flywheel-reproduce/references/flywheel-cli-tool-map.md +37 -35
  21. package/skills/flywheel-reproduce/references/flywheel-mcp-tool-map.md +4 -4
  22. package/skills/flywheel-to-graph/SKILL.md +1 -1
  23. package/skills/flywheel-to-graph/references/flywheel-cli-tool-map.md +37 -35
  24. package/skills/flywheel-to-graph/references/flywheel-mcp-tool-map.md +4 -4
  25. package/skills/flywheel-tree/SKILL.md +1 -1
  26. package/src/agents.mjs +114 -48
  27. package/src/cli.mjs +373 -56
  28. package/src/mcp-writer.mjs +190 -17
  29. package/src/runtime/required-runtime-commands.json +19 -4
  30. package/src/runtime/vendor/flywheel-cli-dist/auth/login.d.ts +1 -0
  31. package/src/runtime/vendor/flywheel-cli-dist/auth/login.js +3 -6
  32. package/src/runtime/vendor/flywheel-cli-dist/auth/login.js.map +1 -1
  33. package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.d.ts +1 -0
  34. package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.js +1 -1
  35. package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.js.map +1 -1
  36. package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.d.ts +27 -0
  37. package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.js +54 -0
  38. package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.js.map +1 -0
  39. package/src/runtime/vendor/flywheel-cli-dist/commands/_artifacts-upload-helpers.d.ts +1 -1
  40. package/src/runtime/vendor/flywheel-cli-dist/commands/_artifacts-upload-helpers.js +6 -5
  41. package/src/runtime/vendor/flywheel-cli-dist/commands/_artifacts-upload-helpers.js.map +1 -1
  42. package/src/runtime/vendor/flywheel-cli-dist/commands/_browser-handoff.d.ts +21 -0
  43. package/src/runtime/vendor/flywheel-cli-dist/commands/_browser-handoff.js +51 -0
  44. package/src/runtime/vendor/flywheel-cli-dist/commands/_browser-handoff.js.map +1 -0
  45. package/src/runtime/vendor/flywheel-cli-dist/commands/_open-url.d.ts +1 -1
  46. package/src/runtime/vendor/flywheel-cli-dist/commands/_open-url.js +6 -3
  47. package/src/runtime/vendor/flywheel-cli-dist/commands/_open-url.js.map +1 -1
  48. package/src/runtime/vendor/flywheel-cli-dist/commands/_secret-param.d.ts +7 -0
  49. package/src/runtime/vendor/flywheel-cli-dist/commands/_secret-param.js +18 -0
  50. package/src/runtime/vendor/flywheel-cli-dist/commands/_secret-param.js.map +1 -0
  51. package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.d.ts +39 -0
  52. package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.js +72 -0
  53. package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.js.map +1 -0
  54. package/src/runtime/vendor/flywheel-cli-dist/commands/account-detach.js +2 -0
  55. package/src/runtime/vendor/flywheel-cli-dist/commands/account-detach.js.map +1 -1
  56. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-add.js +2 -0
  57. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-add.js.map +1 -1
  58. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-remove.js +2 -0
  59. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-remove.js.map +1 -1
  60. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-set-primary.js +2 -0
  61. package/src/runtime/vendor/flywheel-cli-dist/commands/account-emails-set-primary.js.map +1 -1
  62. package/src/runtime/vendor/flywheel-cli-dist/commands/account-get.d.ts +2 -1
  63. package/src/runtime/vendor/flywheel-cli-dist/commands/account-get.js +6 -1
  64. package/src/runtime/vendor/flywheel-cli-dist/commands/account-get.js.map +1 -1
  65. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge-preview.js +2 -0
  66. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge-preview.js.map +1 -1
  67. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge-proof.js +2 -0
  68. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge-proof.js.map +1 -1
  69. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge.js +2 -0
  70. package/src/runtime/vendor/flywheel-cli-dist/commands/account-merge.js.map +1 -1
  71. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.d.ts +2 -0
  72. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.js +11 -0
  73. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.js.map +1 -0
  74. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-set.d.ts +2 -0
  75. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-set.js +60 -0
  76. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-set.js.map +1 -0
  77. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.d.ts +2 -0
  78. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.js +115 -0
  79. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.js.map +1 -0
  80. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.d.ts +2 -0
  81. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.js +12 -0
  82. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.js.map +1 -0
  83. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.d.ts +4 -0
  84. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.js +39 -0
  85. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.js.map +1 -0
  86. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.d.ts +2 -0
  87. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.js +15 -0
  88. package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.js.map +1 -0
  89. package/src/runtime/vendor/flywheel-cli-dist/commands/api-keys-list.d.ts +18 -1
  90. package/src/runtime/vendor/flywheel-cli-dist/commands/api-keys-list.js +38 -5
  91. package/src/runtime/vendor/flywheel-cli-dist/commands/api-keys-list.js.map +1 -1
  92. package/src/runtime/vendor/flywheel-cli-dist/commands/artifacts-delete.js +1 -1
  93. package/src/runtime/vendor/flywheel-cli-dist/commands/artifacts-delete.js.map +1 -1
  94. package/src/runtime/vendor/flywheel-cli-dist/commands/auth-mode.d.ts +4 -0
  95. package/src/runtime/vendor/flywheel-cli-dist/commands/auth-mode.js +42 -0
  96. package/src/runtime/vendor/flywheel-cli-dist/commands/auth-mode.js.map +1 -0
  97. package/src/runtime/vendor/flywheel-cli-dist/commands/auth-status.js +15 -1
  98. package/src/runtime/vendor/flywheel-cli-dist/commands/auth-status.js.map +1 -1
  99. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-grants-list.js +8 -2
  100. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-grants-list.js.map +1 -1
  101. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-grants-request-approval.js +6 -1
  102. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-grants-request-approval.js.map +1 -1
  103. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-release-all.js +18 -7
  104. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-release-all.js.map +1 -1
  105. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-billing-portal.js +8 -4
  106. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-billing-portal.js.map +1 -1
  107. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-purchase.js +8 -4
  108. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-purchase.js.map +1 -1
  109. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-subscribe.js +8 -4
  110. package/src/runtime/vendor/flywheel-cli-dist/commands/credits-subscribe.js.map +1 -1
  111. package/src/runtime/vendor/flywheel-cli-dist/commands/destructive-confirmation.d.ts +2 -0
  112. package/src/runtime/vendor/flywheel-cli-dist/commands/destructive-confirmation.js +7 -0
  113. package/src/runtime/vendor/flywheel-cli-dist/commands/destructive-confirmation.js.map +1 -0
  114. package/src/runtime/vendor/flywheel-cli-dist/commands/enums.d.ts +8 -0
  115. package/src/runtime/vendor/flywheel-cli-dist/commands/enums.js +4 -0
  116. package/src/runtime/vendor/flywheel-cli-dist/commands/enums.js.map +1 -1
  117. package/src/runtime/vendor/flywheel-cli-dist/commands/env.d.ts +0 -4
  118. package/src/runtime/vendor/flywheel-cli-dist/commands/env.js +7 -12
  119. package/src/runtime/vendor/flywheel-cli-dist/commands/env.js.map +1 -1
  120. package/src/runtime/vendor/flywheel-cli-dist/commands/export-history.js +42 -30
  121. package/src/runtime/vendor/flywheel-cli-dist/commands/export-history.js.map +1 -1
  122. package/src/runtime/vendor/flywheel-cli-dist/commands/export-subgraph.js +12 -4
  123. package/src/runtime/vendor/flywheel-cli-dist/commands/export-subgraph.js.map +1 -1
  124. package/src/runtime/vendor/flywheel-cli-dist/commands/github-link.js +9 -14
  125. package/src/runtime/vendor/flywheel-cli-dist/commands/github-link.js.map +1 -1
  126. package/src/runtime/vendor/flywheel-cli-dist/commands/help-format.d.ts +31 -0
  127. package/src/runtime/vendor/flywheel-cli-dist/commands/help-format.js +69 -0
  128. package/src/runtime/vendor/flywheel-cli-dist/commands/help-format.js.map +1 -0
  129. package/src/runtime/vendor/flywheel-cli-dist/commands/help.d.ts +6 -1
  130. package/src/runtime/vendor/flywheel-cli-dist/commands/help.js +226 -124
  131. package/src/runtime/vendor/flywheel-cli-dist/commands/help.js.map +1 -1
  132. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.d.ts +2 -0
  133. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.js +25 -0
  134. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.js.map +1 -0
  135. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.d.ts +1 -0
  136. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.js +6 -0
  137. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.js.map +1 -0
  138. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.d.ts +2 -0
  139. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.js +10 -0
  140. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.js.map +1 -0
  141. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.d.ts +2 -0
  142. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.js +15 -0
  143. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.js.map +1 -0
  144. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.d.ts +2 -0
  145. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.js +8 -0
  146. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.js.map +1 -0
  147. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.d.ts +1 -0
  148. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.js +6 -0
  149. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.js.map +1 -0
  150. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.d.ts +1 -0
  151. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.js +6 -0
  152. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.js.map +1 -0
  153. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.d.ts +2 -0
  154. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.js +8 -0
  155. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.js.map +1 -0
  156. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.d.ts +2 -0
  157. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.js +8 -0
  158. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.js.map +1 -0
  159. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.d.ts +2 -0
  160. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.js +29 -0
  161. package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.js.map +1 -0
  162. package/src/runtime/vendor/flywheel-cli-dist/commands/index.js +36 -6
  163. package/src/runtime/vendor/flywheel-cli-dist/commands/index.js.map +1 -1
  164. package/src/runtime/vendor/flywheel-cli-dist/commands/integrations-huggingface-set.js +7 -3
  165. package/src/runtime/vendor/flywheel-cli-dist/commands/integrations-huggingface-set.js.map +1 -1
  166. package/src/runtime/vendor/flywheel-cli-dist/commands/integrations-wandb-set.js +6 -2
  167. package/src/runtime/vendor/flywheel-cli-dist/commands/integrations-wandb-set.js.map +1 -1
  168. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-add-parent.js +6 -1
  169. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-add-parent.js.map +1 -1
  170. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-delete-bulk.js +2 -0
  171. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-delete-bulk.js.map +1 -1
  172. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-delete.js +2 -0
  173. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-delete.js.map +1 -1
  174. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-remove-parent.js +8 -1
  175. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-remove-parent.js.map +1 -1
  176. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-resolve-slug.js +55 -2
  177. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-resolve-slug.js.map +1 -1
  178. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-list.js +13 -1
  179. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-list.js.map +1 -1
  180. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-set.js +4 -2
  181. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-set.js.map +1 -1
  182. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-show.js +16 -1
  183. package/src/runtime/vendor/flywheel-cli-dist/commands/profile-show.js.map +1 -1
  184. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/account.js +8 -7
  185. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/account.js.map +1 -1
  186. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.d.ts +8 -0
  187. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.js +131 -0
  188. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.js.map +1 -0
  189. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/api-keys.js +8 -2
  190. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/api-keys.js.map +1 -1
  191. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/approval.js +29 -1
  192. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/approval.js.map +1 -1
  193. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/artifacts.js +13 -1
  194. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/artifacts.js.map +1 -1
  195. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/auth.js +2 -2
  196. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/auth.js.map +1 -1
  197. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/budgets.js +11 -2
  198. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/budgets.js.map +1 -1
  199. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/compute.js +2 -2
  200. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/compute.js.map +1 -1
  201. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/credits.js +8 -6
  202. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/credits.js.map +1 -1
  203. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/env.js +7 -5
  204. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/env.js.map +1 -1
  205. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/github.js +6 -14
  206. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/github.js.map +1 -1
  207. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.d.ts +2 -0
  208. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.js +312 -0
  209. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.js.map +1 -0
  210. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/integrations.js +22 -8
  211. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/integrations.js.map +1 -1
  212. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/lifecycle.js +122 -25
  213. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/lifecycle.js.map +1 -1
  214. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/profile.js +2 -2
  215. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/profile.js.map +1 -1
  216. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/resources.js +1 -31
  217. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/resources.js.map +1 -1
  218. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/sharing.js +12 -4
  219. package/src/runtime/vendor/flywheel-cli-dist/commands/registry/sharing.js.map +1 -1
  220. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.d.ts +2 -1
  221. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js +46 -9
  222. package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js.map +1 -1
  223. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-refresh.d.ts +2 -0
  224. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-refresh.js +20 -0
  225. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-refresh.js.map +1 -0
  226. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-resolve.d.ts +2 -0
  227. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-resolve.js +23 -0
  228. package/src/runtime/vendor/flywheel-cli-dist/commands/remote-artifacts-resolve.js.map +1 -0
  229. package/src/runtime/vendor/flywheel-cli-dist/errors.d.ts +15 -0
  230. package/src/runtime/vendor/flywheel-cli-dist/errors.js +16 -1
  231. package/src/runtime/vendor/flywheel-cli-dist/errors.js.map +1 -1
  232. package/src/runtime/vendor/flywheel-cli-dist/http/client.d.ts +1 -0
  233. package/src/runtime/vendor/flywheel-cli-dist/http/client.js +75 -19
  234. package/src/runtime/vendor/flywheel-cli-dist/http/client.js.map +1 -1
  235. package/src/runtime/vendor/flywheel-cli-dist/http/debug.d.ts +3 -0
  236. package/src/runtime/vendor/flywheel-cli-dist/http/debug.js +21 -2
  237. package/src/runtime/vendor/flywheel-cli-dist/http/debug.js.map +1 -1
  238. package/src/runtime/vendor/flywheel-cli-dist/main.js +119 -10
  239. package/src/runtime/vendor/flywheel-cli-dist/main.js.map +1 -1
  240. package/src/runtime/vendor/flywheel-cli-dist/output/format.js +44 -6
  241. package/src/runtime/vendor/flywheel-cli-dist/output/format.js.map +1 -1
  242. package/src/runtime/vendor/manifest.json +82 -10
  243. package/src/setup/base-url.mjs +43 -0
  244. package/src/setup/command.mjs +2 -0
  245. package/src/setup/io/patchers/json.mjs +2 -0
  246. package/src/setup/io/patchers/toml.mjs +7 -1
  247. package/src/setup/io/patchers/yaml.mjs +2 -0
  248. package/src/setup/modes/cli.mjs +72 -24
  249. package/src/setup/modes/mcp-command.mjs +146 -38
  250. package/src/setup/modes/mcp.mjs +26 -1
  251. package/src/setup/resolved-selection-record.mjs +25 -0
  252. package/src/setup/shared/prior-mode-detect.mjs +133 -14
  253. package/src/setup-auth.mjs +3 -2
  254. package/src/skill-installer.mjs +179 -1
  255. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.d.ts +0 -1
  256. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.js +0 -6
  257. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.js.map +0 -1
  258. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-set.d.ts +0 -2
  259. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-set.js +0 -19
  260. package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-set.js.map +0 -1
  261. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.d.ts +0 -2
  262. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.js +0 -7
  263. package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.js.map +0 -1
package/src/cli.mjs CHANGED
@@ -2,18 +2,21 @@ import { Command } from "commander";
2
2
  import { checkbox, select } from "@inquirer/prompts";
3
3
  import ora from "ora";
4
4
  import pc from "picocolors";
5
- import { readFile } from "node:fs/promises";
5
+ import { access, readFile, rm } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
 
8
8
  import {
9
9
  ALL_HOST_NAMES,
10
10
  SERVER_NAME,
11
11
  SETUP_HOST_NAMES,
12
+ SKILL_ONLY_HOST_NAMES,
12
13
  detectHosts,
13
14
  getHost,
15
+ isSkillOnlyHost,
14
16
  normalizeHosts,
15
17
  } from "./agents.mjs";
16
18
  import {
19
+ readEntryServerUrl,
17
20
  readNamedConfigEntry,
18
21
  readJsonConfig,
19
22
  readTomlServerEntry,
@@ -28,10 +31,13 @@ import {
28
31
  listBundledSkills,
29
32
  partitionInstallSkillHosts,
30
33
  removeInstalledSkillsForHosts,
34
+ resolveInstalledSkillDir,
35
+ resolveFlywheelInstalledMarkerPath,
31
36
  SUPPORTED_INSTALL_SKILL_HOSTS,
32
37
  resolvePackageRoot,
33
38
  } from "./skill-installer.mjs";
34
39
  import { normalizeSetupAuthMode } from "./setup-auth.mjs";
40
+ import { resolveSetupBaseUrl } from "./setup/base-url.mjs";
35
41
  import { runSetupRouter } from "./setup/command.mjs";
36
42
  import { SetupModeUsageError } from "./setup/mode.mjs";
37
43
  import { runCliSetupMode } from "./setup/modes/cli.mjs";
@@ -42,11 +48,17 @@ import {
42
48
  import { findFlywheelMcpEntryNames } from "./setup/shared/prior-mode-detect.mjs";
43
49
  import { renderSetupSummary } from "./setup/shared/summary.mjs";
44
50
 
51
+ async function pathExists(targetPath) {
52
+ try {
53
+ await access(targetPath);
54
+ return true;
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+
45
60
  export { buildGuidedSkillInstallPrompt };
46
61
 
47
- const INSTALL_SKILL_BASE_URL = "https://flywheel.paradigma.inc";
48
- const DEFAULT_BASE_URL =
49
- process.env.FLYWHEEL_PUBLIC_BASE_URL || INSTALL_SKILL_BASE_URL;
50
62
  const log = {
51
63
  info: (message) => console.log(pc.cyan(message)),
52
64
  warn: (message) => console.log(pc.yellow(`⚠ ${message}`)),
@@ -62,6 +74,12 @@ const CHECKBOX_THEME = {
62
74
  },
63
75
  };
64
76
 
77
+ function hostChoiceDescription({ detected = false, configured = false } = {}) {
78
+ if (configured) return "Already has a Flywheel entry for this scope.";
79
+ if (detected) return "Detected on this machine.";
80
+ return "Supported host; select it if you use it here.";
81
+ }
82
+
65
83
  function normalizeBaseUrl(value) {
66
84
  const normalized = String(value || "").trim();
67
85
  let parsedUrl;
@@ -95,9 +113,12 @@ function normalizeAuthMode(value) {
95
113
  function selectedHostsFromOptions(options) {
96
114
  const hosts = [];
97
115
  if (options.claude) hosts.push("claude");
116
+ if (options.cursor) hosts.push("cursor");
117
+ if (options.universal) hosts.push("universal");
118
+ if (options.antigravity) hosts.push("antigravity");
98
119
  if (options.opencode) hosts.push("opencode");
99
120
  if (options.codex) hosts.push("codex");
100
- if (options.cursor) hosts.push("cursor");
121
+ if (options.gemini) hosts.push("gemini");
101
122
  if (options.piMono) hosts.push("pi-mono");
102
123
  if (options.hermesAgent) hosts.push("hermes-agent");
103
124
  if (options.openclaw) hosts.push("openclaw");
@@ -109,6 +130,9 @@ const UNINSTALL_OPTION_KEY_BY_HOST = Object.freeze({
109
130
  codex: "codex",
110
131
  opencode: "opencode",
111
132
  cursor: "cursor",
133
+ gemini: "gemini",
134
+ universal: "universal",
135
+ antigravity: "antigravity",
112
136
  "pi-mono": "piMono",
113
137
  "hermes-agent": "hermesAgent",
114
138
  openclaw: "openclaw",
@@ -167,6 +191,9 @@ async function isAlreadyConfigured(hostName, scope, serverName) {
167
191
 
168
192
  async function readExistingServerState(hostName, scope, serverName) {
169
193
  const host = getHost(hostName);
194
+ if (isSkillOnlyHost(host)) {
195
+ return { exists: false, url: null, mcpPath: null };
196
+ }
170
197
  const mcpPath = await resolveMcpPath(mcpCandidatesForScope(host, scope));
171
198
 
172
199
  if (host.mcp.configType === "toml") {
@@ -181,7 +208,7 @@ async function readExistingServerState(hostName, scope, serverName) {
181
208
  const entry = readNamedConfigEntry(existing, host.mcp.configKey, serverName);
182
209
  return {
183
210
  exists: entry !== null,
184
- url: typeof entry?.url === "string" ? entry.url : null,
211
+ url: readEntryServerUrl(entry),
185
212
  mcpPath,
186
213
  };
187
214
  }
@@ -202,6 +229,11 @@ async function promptHosts(
202
229
  return {
203
230
  name: SETUP_HOST_NAMES[hostName],
204
231
  value: hostName,
232
+ short: SETUP_HOST_NAMES[hostName],
233
+ description: hostChoiceDescription({
234
+ detected: detected.includes(hostName),
235
+ configured,
236
+ }),
205
237
  checked: detected.includes(hostName),
206
238
  disabled:
207
239
  disableAlreadyConfigured && configured
@@ -272,15 +304,23 @@ export function buildSetupModePromptConfig() {
272
304
  message: "How should your agent access Flywheel?",
273
305
  choices: [
274
306
  {
275
- name: `MCP + bundled skills\n ${pc.dim("Agent calls Flywheel tools via MCP protocol to manage nodes, artifacts, and compute")}`,
307
+ name: "MCP + bundled skills",
276
308
  value: "mcp",
309
+ short: "MCP + skills",
310
+ description:
311
+ "Configure MCP tools plus bundled skills for supported AI hosts.",
277
312
  },
278
313
  {
279
- name: `CLI + bundled skills\n ${pc.dim("Agent shells out to the flywheel binary to manage nodes, artifacts, and compute")}`,
314
+ name: "CLI + bundled skills",
280
315
  value: "cli",
316
+ short: "CLI + skills",
317
+ description:
318
+ "Install bundled skills for agents that call the flywheel binary.",
281
319
  },
282
320
  ],
283
321
  default: "mcp",
322
+ loop: false,
323
+ pageSize: 4,
284
324
  theme: CHECKBOX_THEME,
285
325
  };
286
326
  }
@@ -289,7 +329,19 @@ async function promptSetupMode() {
289
329
  return await select(buildSetupModePromptConfig());
290
330
  }
291
331
 
292
- function validateCliModeSkillFlags(options) {
332
+ /**
333
+ * Validate the flag combination for --mode cli. Rejections raise
334
+ * `SetupModeUsageError` so the top-level handler reports them as usage
335
+ * errors (exit code 2) and not as operational failures.
336
+ *
337
+ * `--oauth` controls the MCP config written in --mode mcp (it omits the
338
+ * Authorization header so the IDE can discover MCP 2.0 OAuth instead).
339
+ * --mode cli writes no MCP config at all, so there is nothing for --oauth
340
+ * to modify. Silently accepting it would look successful but still fall
341
+ * back to API-key auth in the runtime config — a misconfiguration. Reject
342
+ * it up front with guidance toward the correct invocation.
343
+ */
344
+ function validateCliModeFlags(options) {
293
345
  if (options.installSkill && options.skipSkill) {
294
346
  throw new SetupModeUsageError(
295
347
  "--install-skill and --skip-skill cannot be used together.",
@@ -302,12 +354,19 @@ function validateCliModeSkillFlags(options) {
302
354
  "--skip-skill is not supported with --mode cli; use --mode mcp --skip-skill for MCP-only setup.",
303
355
  );
304
356
  }
357
+ if (options.oauth === true) {
358
+ throw new SetupModeUsageError(
359
+ "--oauth is not supported with --mode cli. --oauth only affects the MCP config written by --mode mcp; re-run with --mode mcp --oauth, or drop --oauth for a CLI-mode setup.",
360
+ );
361
+ }
305
362
  }
306
363
 
307
364
  async function runCliModeCommand(options) {
308
- validateCliModeSkillFlags(options);
365
+ validateCliModeFlags(options);
309
366
  const scope = options.project ? "project" : "global";
310
- const baseUrl = normalizeBaseUrl(options.baseUrl || DEFAULT_BASE_URL);
367
+ const baseUrl = normalizeBaseUrl(
368
+ resolveSetupBaseUrl({ explicitBaseUrl: options.baseUrl }),
369
+ );
311
370
  const serverUrl = `${baseUrl}/mcp-server`;
312
371
  const serverName = normalizeServerName(options.name || SERVER_NAME);
313
372
  const hosts = await resolveHosts(options, scope, serverName, {
@@ -380,7 +439,8 @@ async function runCliModeCommand(options) {
380
439
 
381
440
  async function runSetupCommandViaRouter(options) {
382
441
  return await runSetupRouter(options, {
383
- isInteractive: process.stdin.isTTY === true && process.stdout.isTTY === true,
442
+ isInteractive:
443
+ process.stdin.isTTY === true && process.stdout.isTTY === true,
384
444
  promptMode: promptSetupMode,
385
445
  runMcpMode: async () =>
386
446
  await runMcpModeCommand(options, {
@@ -460,8 +520,12 @@ function readConfigSection(config, configKey) {
460
520
 
461
521
  function parseTomlServerNames(tomlText) {
462
522
  const serverNames = new Set();
463
- for (const line of String(tomlText || "").replace(/\r\n/g, "\n").split("\n")) {
464
- const match = line.trim().match(/^\[mcp_servers\.([A-Za-z0-9_-]+)\](?:\s*#.*)?$/);
523
+ for (const line of String(tomlText || "")
524
+ .replace(/\r\n/g, "\n")
525
+ .split("\n")) {
526
+ const match = line
527
+ .trim()
528
+ .match(/^\[mcp_servers\.([A-Za-z0-9_-]+)\](?:\s*#.*)?$/);
465
529
  if (!match) {
466
530
  continue;
467
531
  }
@@ -484,6 +548,9 @@ function isLikelyFlywheelMcpUrl(url) {
484
548
 
485
549
  async function listHostMcpEntries(hostName, scope) {
486
550
  const host = getHost(hostName);
551
+ if (isSkillOnlyHost(host)) {
552
+ return [];
553
+ }
487
554
  const filePath = await resolveMcpPath(mcpCandidatesForScope(host, scope));
488
555
 
489
556
  if (host.mcp.configType === "toml") {
@@ -514,10 +581,13 @@ async function listHostMcpEntries(hostName, scope) {
514
581
  : await readJsonConfig(filePath);
515
582
  const section = readConfigSection(config, host.mcp.configKey);
516
583
  return Object.entries(section)
517
- .filter(([, entry]) => entry && typeof entry === "object" && !Array.isArray(entry))
584
+ .filter(
585
+ ([, entry]) =>
586
+ entry && typeof entry === "object" && !Array.isArray(entry),
587
+ )
518
588
  .map(([serverName, entry]) => ({
519
589
  serverName,
520
- url: typeof entry.url === "string" ? entry.url : null,
590
+ url: readEntryServerUrl(entry),
521
591
  }));
522
592
  }
523
593
 
@@ -525,7 +595,9 @@ async function resolveHostsWithRemainingFlywheelMcpEntries({ scope }) {
525
595
  const remainingHosts = [];
526
596
  for (const hostName of SUPPORTED_INSTALL_SKILL_HOSTS) {
527
597
  // eslint-disable-next-line no-await-in-loop
528
- const hostEntries = await listHostMcpEntries(hostName, scope).catch(() => []);
598
+ const hostEntries = await listHostMcpEntries(hostName, scope).catch(
599
+ () => [],
600
+ );
529
601
  if (hostEntries.some((entry) => isLikelyFlywheelMcpUrl(entry.url))) {
530
602
  remainingHosts.push(hostName);
531
603
  }
@@ -533,14 +605,68 @@ async function resolveHostsWithRemainingFlywheelMcpEntries({ scope }) {
533
605
  return remainingHosts;
534
606
  }
535
607
 
608
+ /**
609
+ * Determine which non-uninstalled hosts still claim bundled skill artifacts
610
+ * via their install marker, and therefore must keep their (possibly shared)
611
+ * skill directories intact.
612
+ *
613
+ * The install marker (`.flywheel-installed-by-<host>`) is written by
614
+ * `installBundledSkillForHosts` for any host whose install path produces no
615
+ * MCP entry:
616
+ *
617
+ * - skill-only hosts (universal, antigravity): marker always written.
618
+ * - MCP-capable hosts (codex, opencode, cursor, claude, pi-mono, openclaw,
619
+ * gemini): marker written ONLY when the host was installed via
620
+ * `--mode cli`, because CLI-mode installs write no MCP entry.
621
+ *
622
+ * A marker at a skill-root is therefore the unambiguous "this host still
623
+ * owns these skills" signal for both categories. Narrowing the retain pass
624
+ * to skill-only hosts would let `uninstall --universal` silently wipe the
625
+ * shared `.agents/skills/` dir out from under a still-installed CLI-mode
626
+ * codex. Using dir existence alone would over-retain for hosts that never
627
+ * installed anything. The per-host marker resolves both.
628
+ *
629
+ * `excludedHostNames` is the list of hosts currently being uninstalled;
630
+ * their markers will be removed and their artifacts are expected to go, so
631
+ * they are excluded from retention here.
632
+ */
633
+ async function resolveSkillOnlyHostsRetainingArtifacts({
634
+ scope,
635
+ excludedHostNames = [],
636
+ }) {
637
+ const excluded = new Set(excludedHostNames);
638
+ const retained = [];
639
+ for (const hostName of SUPPORTED_INSTALL_SKILL_HOSTS) {
640
+ if (excluded.has(hostName)) continue;
641
+ let markerPath;
642
+ try {
643
+ markerPath = resolveFlywheelInstalledMarkerPath(
644
+ process.cwd(),
645
+ hostName,
646
+ scope,
647
+ );
648
+ } catch {
649
+ // Host isn't registered with the flywheel skill installer; no marker
650
+ // to consult, nothing to retain.
651
+ continue;
652
+ }
653
+ // eslint-disable-next-line no-await-in-loop
654
+ const markerExists = await pathExists(markerPath);
655
+ if (markerExists) {
656
+ retained.push(hostName);
657
+ }
658
+ }
659
+ return retained;
660
+ }
661
+
536
662
  async function findFlywheelServerNamesOnHost(hostName, scope) {
537
663
  // Mirror setup's prior-mode detector: walk every MCP entry on the host and
538
664
  // keep those whose URL is Flywheel-identifying (hostname contains "flywheel"
539
665
  // or path === /mcp-server with a matching target origin). Uninstall must
540
- // catch renamed/drifted entries (e.g. `[mcp_servers.flywheel-staging]`) that
541
- // setup already detects; otherwise a user whose host has a non-default entry
542
- // name is stuck between setup ("already installed") and uninstall ("not
543
- // configured").
666
+ // catch renamed or drifted entries (e.g. a non-default TOML section name
667
+ // under `[mcp_servers.*]`) that setup already detects; otherwise a user
668
+ // whose host has a non-default entry name is stuck between setup ("already
669
+ // installed") and uninstall ("not configured").
544
670
  return await findFlywheelMcpEntryNames({ hostName, scope }).catch(() => []);
545
671
  }
546
672
 
@@ -574,10 +700,92 @@ async function isConfiguredForUninstallScope(
574
700
  { explicitServerName },
575
701
  );
576
702
  if (targets.length > 0) return true;
703
+ // Skill-only hosts and CLI-mode MCP-capable hosts never write an MCP
704
+ // entry, so the sweep above finds nothing for them. Fall back to the
705
+ // install marker: if this host wrote its own ownership marker in the
706
+ // selected scope, it IS configured for the purposes of the uninstall
707
+ // prompt.
708
+ if (SUPPORTED_INSTALL_SKILL_HOSTS.includes(hostName)) {
709
+ try {
710
+ const markerPath = resolveFlywheelInstalledMarkerPath(
711
+ process.cwd(),
712
+ hostName,
713
+ singleScope,
714
+ );
715
+ // eslint-disable-next-line no-await-in-loop
716
+ if (await pathExists(markerPath)) return true;
717
+ } catch {
718
+ // Host isn't registered with the skill installer; nothing to check.
719
+ }
720
+ }
577
721
  }
578
722
  return false;
579
723
  }
580
724
 
725
+ /**
726
+ * Public wrapper exposing the uninstall-eligibility check used by the
727
+ * interactive prompt. Returns true when the host has either a Flywheel MCP
728
+ * entry OR a Flywheel install marker in the requested scope. Exported so
729
+ * tests can verify that skill-only hosts surface as configurable in the
730
+ * prompt even though they write no MCP entry.
731
+ */
732
+ export async function isHostConfiguredForUninstall({
733
+ hostName,
734
+ scope = "project",
735
+ serverName = SERVER_NAME,
736
+ } = {}) {
737
+ // Mirror `runUninstallCommand`'s derivation: only treat the caller's
738
+ // `serverName` as "explicit" when it differs from the package default.
739
+ // An explicit name short-circuits the Flywheel-identifying sweep in
740
+ // `resolveUninstallServerNamesForHost`, which the default-named case
741
+ // needs to run so drifted entries (and the marker fallback for
742
+ // skill-only / CLI-mode hosts) are reachable.
743
+ const explicitServerName =
744
+ typeof serverName === "string" &&
745
+ serverName.length > 0 &&
746
+ serverName !== SERVER_NAME
747
+ ? serverName
748
+ : null;
749
+ return isConfiguredForUninstallScope(hostName, scope, { explicitServerName });
750
+ }
751
+
752
+ /**
753
+ * Remove every Flywheel install marker for the requested hosts across the
754
+ * requested scopes. Exported and implemented as a standalone helper so it
755
+ * can run independently of bundled-skill discovery: a package with a
756
+ * missing or trimmed `skills/` directory must still be able to uninstall
757
+ * cleanly, otherwise stale markers leak into later prompt-eligibility,
758
+ * retention, and prior-mode-detection logic. `rm ..., { force: true }`
759
+ * makes the operation idempotent — hosts that never wrote a marker (e.g.
760
+ * MCP-capable hosts installed only via `--mode mcp`) are silent no-ops.
761
+ *
762
+ * Hosts not registered with the Flywheel skill installer are skipped
763
+ * rather than throwing, so callers can pass the full uninstall host list
764
+ * without pre-filtering.
765
+ */
766
+ export async function cleanupHostInstallMarkers({
767
+ cwd = process.cwd(),
768
+ scopes = ["project"],
769
+ hostNames = [],
770
+ } = {}) {
771
+ for (const singleScope of scopes) {
772
+ for (const hostName of hostNames) {
773
+ let markerPath;
774
+ try {
775
+ markerPath = resolveFlywheelInstalledMarkerPath(
776
+ cwd,
777
+ hostName,
778
+ singleScope,
779
+ );
780
+ } catch {
781
+ continue;
782
+ }
783
+ // eslint-disable-next-line no-await-in-loop
784
+ await rm(markerPath, { force: true });
785
+ }
786
+ }
787
+ }
788
+
581
789
  async function promptUninstallScope(defaultScope) {
582
790
  try {
583
791
  return await select({
@@ -674,6 +882,14 @@ async function resolveUninstallTargets(options, { explicitServerName }) {
674
882
 
675
883
  async function removeHostConfig(hostName, scope, serverName) {
676
884
  const host = getHost(hostName);
885
+ if (isSkillOnlyHost(host)) {
886
+ return {
887
+ host: host.displayName,
888
+ scope,
889
+ filePath: null,
890
+ status: "not present",
891
+ };
892
+ }
677
893
  const filePath = await resolveMcpPath(mcpCandidatesForScope(host, scope));
678
894
 
679
895
  if (host.mcp.configType === "toml") {
@@ -733,7 +949,8 @@ async function runUninstallCommand(options) {
733
949
  // Resolve the concrete server name(s) to remove at the host/scope level.
734
950
  // When --name was not given, this iterates every Flywheel-identifying
735
951
  // entry (matching setup's prior-mode detector) so renamed or drifted
736
- // entries (e.g. `[mcp_servers.flywheel-staging]`) are actually cleared.
952
+ // entries (non-default TOML section names under `[mcp_servers.*]`) are
953
+ // actually cleared.
737
954
  // eslint-disable-next-line no-await-in-loop
738
955
  const targetNames = await resolveUninstallServerNamesForHost(
739
956
  host,
@@ -743,10 +960,16 @@ async function runUninstallCommand(options) {
743
960
  if (targetNames.length === 0) {
744
961
  // eslint-disable-next-line no-await-in-loop
745
962
  const hostForDisplay = getHost(host);
746
- // eslint-disable-next-line no-await-in-loop
747
- const filePath = await resolveMcpPath(
748
- mcpCandidatesForScope(hostForDisplay, singleScope),
749
- );
963
+ // Skill-only hosts (universal, antigravity) have no MCP surface
964
+ // at all `host.mcp` is null, so dereferencing `projectPaths` via
965
+ // `mcpCandidatesForScope` throws. Report the absence without
966
+ // consulting a path that doesn't exist for them.
967
+ const filePath = isSkillOnlyHost(hostForDisplay)
968
+ ? null
969
+ : // eslint-disable-next-line no-await-in-loop
970
+ await resolveMcpPath(
971
+ mcpCandidatesForScope(hostForDisplay, singleScope),
972
+ );
750
973
  mcpResults.push({
751
974
  host: hostForDisplay.displayName,
752
975
  scope: singleScope,
@@ -774,12 +997,28 @@ async function runUninstallCommand(options) {
774
997
  if (bundledSkillNames.length > 0) {
775
998
  const skillSpinner = ora("Removing Flywheel bundled skills...").start();
776
999
  for (const singleScope of scopes) {
777
- // Prevent deleting shared skill directories while non-selected hosts
778
- // mapped to the same location still have Flywheel MCP entries.
1000
+ // Retain any skill directory still claimed by a non-uninstalled host.
1001
+ // Two signals combine: (a) MCP-backed hosts whose Flywheel entries
1002
+ // survived the MCP-removal pass above, and (b) any host with bundled
1003
+ // skill artifacts still on disk (including skill-only hosts like
1004
+ // universal/antigravity, which never advertise themselves via MCP
1005
+ // entries). Without (b), uninstalling one MCP host would silently
1006
+ // wipe a shared `.agents/skills/<skill>/` that another host still
1007
+ // relies on.
779
1008
  // eslint-disable-next-line no-await-in-loop
780
- const configuredRetainHostNames = await resolveHostsWithRemainingFlywheelMcpEntries({
1009
+ const mcpRetained = await resolveHostsWithRemainingFlywheelMcpEntries({
781
1010
  scope: singleScope,
782
1011
  });
1012
+ // eslint-disable-next-line no-await-in-loop
1013
+ const skillOnlyRetained = await resolveSkillOnlyHostsRetainingArtifacts(
1014
+ {
1015
+ scope: singleScope,
1016
+ excludedHostNames: supportedHosts,
1017
+ },
1018
+ );
1019
+ const configuredRetainHostNames = [
1020
+ ...new Set([...mcpRetained, ...skillOnlyRetained]),
1021
+ ];
783
1022
  skillSpinner.text = `Removing bundled skills from ${supportedHosts.length} host(s) (${singleScope})...`;
784
1023
  // eslint-disable-next-line no-await-in-loop
785
1024
  bundledSkillResults.push(
@@ -794,10 +1033,25 @@ async function runUninstallCommand(options) {
794
1033
  }
795
1034
  skillSpinner.succeed("Bundled skill uninstall complete");
796
1035
  }
1036
+
1037
+ // Install-marker cleanup runs independently of bundled-skill discovery.
1038
+ // A broken or trimmed package (missing `skills/`) can leave
1039
+ // `bundledSkillNames` empty — the skill-removal pass above legitimately
1040
+ // no-ops in that case, but the ownership markers must still be cleared,
1041
+ // otherwise a later `uninstall`/`setup` would treat the uninstalled
1042
+ // host as still owning shared skill dirs (wrong retention) or as a
1043
+ // prior CLI install (false cross-mode conflict).
1044
+ await cleanupHostInstallMarkers({
1045
+ cwd: process.cwd(),
1046
+ scopes,
1047
+ hostNames: supportedHosts,
1048
+ });
797
1049
  }
798
1050
 
799
1051
  log.blank();
800
- log.plain(pc.green("✔ Flywheel uninstall complete (MCP entries and bundled skills)"));
1052
+ log.plain(
1053
+ pc.green("✔ Flywheel uninstall complete (MCP entries and bundled skills)"),
1054
+ );
801
1055
  log.blank();
802
1056
  for (const result of mcpResults) {
803
1057
  const icon = result.status === "removed" ? pc.green("-") : pc.dim("~");
@@ -830,11 +1084,13 @@ async function runUninstallCommand(options) {
830
1084
  }
831
1085
  }
832
1086
 
833
- const sortedGroups = [...groupedSkillResults.values()].sort((left, right) => {
834
- const leftKey = `${left.hostName}:${left.scope}`;
835
- const rightKey = `${right.hostName}:${right.scope}`;
836
- return leftKey.localeCompare(rightKey);
837
- });
1087
+ const sortedGroups = [...groupedSkillResults.values()].sort(
1088
+ (left, right) => {
1089
+ const leftKey = `${left.hostName}:${left.scope}`;
1090
+ const rightKey = `${right.hostName}:${right.scope}`;
1091
+ return leftKey.localeCompare(rightKey);
1092
+ },
1093
+ );
838
1094
  for (const groupedResult of sortedGroups) {
839
1095
  log.plain(
840
1096
  ` ${pc.bold(getHost(groupedResult.hostName).displayName)} ${pc.dim(`(${groupedResult.scope})`)}`,
@@ -850,7 +1106,9 @@ async function runUninstallCommand(options) {
850
1106
  entry.status === "retained" && Array.isArray(entry.retainedHostNames)
851
1107
  ? ` (shared with configured host(s): ${entry.retainedHostNames.join(", ")})`
852
1108
  : "";
853
- log.plain(` ${icon} ${entry.status}${retainedSuffix}: ${entry.skillNames.join(", ")}`);
1109
+ log.plain(
1110
+ ` ${icon} ${entry.status}${retainedSuffix}: ${entry.skillNames.join(", ")}`,
1111
+ );
854
1112
  log.plain(` ${pc.dim(entry.installedSkillDir)}`);
855
1113
  }
856
1114
  }
@@ -861,7 +1119,9 @@ async function runUninstallCommand(options) {
861
1119
  log.plain(
862
1120
  ` ${pc.bold(getHost(unsupportedHostName).displayName)} ${pc.dim(`(${singleScope})`)}`,
863
1121
  );
864
- log.plain(` ${pc.dim("~")} skill uninstall not supported (MCP-only host)`);
1122
+ log.plain(
1123
+ ` ${pc.dim("~")} skill uninstall not supported (MCP-only host)`,
1124
+ );
865
1125
  }
866
1126
  }
867
1127
  log.blank();
@@ -882,15 +1142,32 @@ Examples:
882
1142
  ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode mcp --auth-mode device --codex --project")}
883
1143
  ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode cli --codex --project")}
884
1144
  ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode mcp --yes --codex --claude --cursor")}
885
- ${pc.green(
886
- "npx --yes @paradigma-inc/flywheel uninstall --scope all --hosts codex,claude,opencode,cursor,pi-mono,hermes-agent,openclaw",
887
- )}
1145
+ ${pc.green("npx --yes @paradigma-inc/flywheel uninstall --yes --scope all")}
888
1146
  `,
889
1147
  );
890
1148
 
891
1149
  program
892
1150
  .command("setup")
893
1151
  .description("Set up Flywheel for your AI coding host")
1152
+ .addHelpText(
1153
+ "before",
1154
+ `${pc.bold(pc.cyan("✻ Flywheel Setup"))}
1155
+
1156
+ Configure the Flywheel CLI, MCP host entries, and bundled skills without changing command names or setup modes.
1157
+ `,
1158
+ )
1159
+ .optionsGroup("Hosts:")
1160
+ .option("--claude", "Set up for Claude Code")
1161
+ .option("--cursor", "Set up for Cursor")
1162
+ .option("--universal", "Set up for Universal (.agents/skills)")
1163
+ .option("--antigravity", "Set up for Antigravity (.agent/skills)")
1164
+ .option("--opencode", "Set up for OpenCode")
1165
+ .option("--codex", "Set up for Codex")
1166
+ .option("--gemini", "Set up for Gemini CLI")
1167
+ .option("--pi-mono", "Set up for Pi (pi-mono)")
1168
+ .option("--hermes-agent", "Set up for Hermes Agent")
1169
+ .option("--openclaw", "Set up for OpenClaw")
1170
+ .optionsGroup("Mode:")
894
1171
  .option(
895
1172
  "--mode <mode>",
896
1173
  "Install mode: mcp | cli (required in non-interactive; prompted in TTY, default: mcp)",
@@ -899,50 +1176,78 @@ Examples:
899
1176
  )
900
1177
  .option("--mcp", "Alias for --mode mcp")
901
1178
  .option("--cli", "Alias for --mode cli")
902
- .option("--claude", "Set up for Claude Code")
903
- .option("--opencode", "Set up for OpenCode")
904
- .option("--codex", "Set up for Codex")
905
- .option("--cursor", "Set up for Cursor")
906
- .option("--pi-mono", "Set up for Pi (pi-mono)")
907
- .option("--hermes-agent", "Set up for Hermes Agent")
908
- .option("--openclaw", "Set up for OpenClaw")
1179
+ .optionsGroup("Scope:")
909
1180
  .option(
910
1181
  "-p, --project",
911
1182
  "Configure for current project instead of globally",
912
1183
  )
913
- .option("-y, --yes", "Skip host selection prompts")
914
- .option("--force", "Reconcile prior install mode automatically via uninstall")
1184
+ .option("-y, --yes", "Skip confirmation prompts")
1185
+ .optionsGroup("Authentication:")
915
1186
  .option("--api-key <key>", "Use API key authentication")
1187
+ .option("--oauth", "Use OAuth endpoint (IDE handles auth flow)")
1188
+ .optionsGroup("Skills:")
1189
+ .option("--install-skill", "Install or refresh the bundled Flywheel skills")
1190
+ .option("--skip-skill", "Skip bundled skill installation (MCP-only setup)")
1191
+ .optionsGroup("Advanced:")
916
1192
  .option(
917
1193
  "--auth-mode <mode>",
918
- "Authentication mode: auto | loopback | device (default: auto)",
1194
+ "API-key mint flow: auto | loopback | device (default: auto)",
919
1195
  normalizeAuthMode,
920
1196
  "auto",
921
1197
  )
922
- .option("--install-skill", "Install or refresh the bundled Flywheel skills")
923
- .option("--skip-skill", "Skip bundled skill installation (MCP-only setup)")
924
1198
  .option(
925
1199
  "--base-url <url>",
926
- `Public Flywheel origin used for setup and MCP config (default: ${DEFAULT_BASE_URL})`,
1200
+ `Public Flywheel origin used for setup and MCP config (default: ${resolveSetupBaseUrl()})`,
927
1201
  )
928
1202
  .option("--name <name>", `MCP server name (default: ${SERVER_NAME})`)
1203
+ .option(
1204
+ "--force",
1205
+ "Reconcile prior install mode automatically via uninstall",
1206
+ )
1207
+ .addHelpText(
1208
+ "after",
1209
+ `
1210
+ Examples:
1211
+ ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode mcp --install-skill")}
1212
+ ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode mcp --skip-skill --codex --project")}
1213
+ ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode cli --codex --project")}
1214
+
1215
+ Next steps:
1216
+ ${pc.green("flywheel help")}
1217
+ ${pc.green("flywheel auth:status")}
1218
+ `,
1219
+ )
929
1220
  .action(async (options) => {
930
1221
  await runSetupCommandViaRouter(options);
931
1222
  });
932
1223
 
933
1224
  program
934
1225
  .command("uninstall")
935
- .description("Remove Flywheel MCP entries and bundled skills from selected hosts")
1226
+ .description(
1227
+ "Remove Flywheel MCP entries and bundled skills from selected hosts",
1228
+ )
1229
+ .addHelpText(
1230
+ "before",
1231
+ `${pc.bold(pc.cyan("✻ Flywheel Uninstall"))}
1232
+
1233
+ Remove Flywheel MCP entries and bundled skills from selected hosts without changing command names or uninstall scopes.
1234
+ `,
1235
+ )
1236
+ .optionsGroup("Hosts:")
936
1237
  .option("--claude", "Uninstall for Claude Code")
1238
+ .option("--cursor", "Uninstall for Cursor")
1239
+ .option("--universal", "Uninstall bundled skills from .agents/skills")
1240
+ .option("--antigravity", "Uninstall bundled skills from .agent/skills")
937
1241
  .option("--opencode", "Uninstall for OpenCode")
938
1242
  .option("--codex", "Uninstall for Codex")
939
- .option("--cursor", "Uninstall for Cursor")
1243
+ .option("--gemini", "Uninstall for Gemini CLI")
940
1244
  .option("--pi-mono", "Uninstall for Pi (pi-mono)")
941
1245
  .option("--hermes-agent", "Uninstall for Hermes Agent")
942
1246
  .option("--openclaw", "Uninstall for OpenClaw")
1247
+ .optionsGroup("Selection:")
943
1248
  .option(
944
1249
  "--hosts <list>",
945
- "Comma-separated: codex,claude,opencode,cursor,pi-mono,hermes-agent,openclaw",
1250
+ "Comma-separated: claude,cursor,universal,antigravity,opencode,codex,gemini,pi-mono,hermes-agent,openclaw",
946
1251
  )
947
1252
  .option("--scope <scope>", "all | global | project")
948
1253
  .option(
@@ -950,6 +1255,18 @@ Examples:
950
1255
  `MCP server name to remove (default: ${SERVER_NAME})`,
951
1256
  )
952
1257
  .option("-y, --yes", "Skip uninstall selection prompts")
1258
+ .addHelpText(
1259
+ "after",
1260
+ `
1261
+ Examples:
1262
+ ${pc.green("npx --yes @paradigma-inc/flywheel uninstall --codex --scope project")}
1263
+ ${pc.green("npx --yes @paradigma-inc/flywheel uninstall --hosts claude,codex --scope all --yes")}
1264
+
1265
+ Next steps:
1266
+ ${pc.green("flywheel help setup")}
1267
+ ${pc.green("npx --yes @paradigma-inc/flywheel setup --mode mcp")}
1268
+ `,
1269
+ )
953
1270
  .action(async (options) => {
954
1271
  await runUninstallCommand(options);
955
1272
  });