@allstak/wizard 0.1.7 → 0.1.8

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 (350) hide show
  1. package/dist/cli.js +8 -0
  2. package/dist/commands/_context.js +4 -2
  3. package/dist/registry/index.js +4 -0
  4. package/dist/util/wizard-version.d.ts +1 -1
  5. package/dist/util/wizard-version.js +1 -1
  6. package/package.json +3 -4
  7. package/dist/api/auth-client.d.ts.map +0 -1
  8. package/dist/api/auth-client.js.map +0 -1
  9. package/dist/api/auth.d.ts.map +0 -1
  10. package/dist/api/auth.js.map +0 -1
  11. package/dist/api/client.d.ts.map +0 -1
  12. package/dist/api/client.js.map +0 -1
  13. package/dist/api/http.d.ts.map +0 -1
  14. package/dist/api/http.js.map +0 -1
  15. package/dist/api/index.d.ts.map +0 -1
  16. package/dist/api/index.js.map +0 -1
  17. package/dist/api/orgs-client.d.ts.map +0 -1
  18. package/dist/api/orgs-client.js.map +0 -1
  19. package/dist/api/projects-client.d.ts.map +0 -1
  20. package/dist/api/projects-client.js.map +0 -1
  21. package/dist/api/setup-doctor-client.d.ts.map +0 -1
  22. package/dist/api/setup-doctor-client.js.map +0 -1
  23. package/dist/api/types.d.ts.map +0 -1
  24. package/dist/api/types.js.map +0 -1
  25. package/dist/certification/fixtures.d.ts.map +0 -1
  26. package/dist/certification/fixtures.js.map +0 -1
  27. package/dist/certification/gates.d.ts.map +0 -1
  28. package/dist/certification/gates.js.map +0 -1
  29. package/dist/certification/index.d.ts.map +0 -1
  30. package/dist/certification/index.js.map +0 -1
  31. package/dist/certification/live-backend.d.ts.map +0 -1
  32. package/dist/certification/live-backend.js.map +0 -1
  33. package/dist/certification/packages.d.ts.map +0 -1
  34. package/dist/certification/packages.js.map +0 -1
  35. package/dist/certification/process.d.ts.map +0 -1
  36. package/dist/certification/process.js.map +0 -1
  37. package/dist/certification/report.d.ts.map +0 -1
  38. package/dist/certification/report.js.map +0 -1
  39. package/dist/certification/runner.d.ts.map +0 -1
  40. package/dist/certification/runner.js.map +0 -1
  41. package/dist/certification/runtime.d.ts.map +0 -1
  42. package/dist/certification/runtime.js.map +0 -1
  43. package/dist/certification/types.d.ts.map +0 -1
  44. package/dist/certification/types.js.map +0 -1
  45. package/dist/cli.d.ts.map +0 -1
  46. package/dist/cli.js.map +0 -1
  47. package/dist/commands/_context.d.ts.map +0 -1
  48. package/dist/commands/_context.js.map +0 -1
  49. package/dist/commands/certify.d.ts.map +0 -1
  50. package/dist/commands/certify.js.map +0 -1
  51. package/dist/commands/config-cmd.d.ts.map +0 -1
  52. package/dist/commands/config-cmd.js.map +0 -1
  53. package/dist/commands/doctor.d.ts.map +0 -1
  54. package/dist/commands/doctor.js.map +0 -1
  55. package/dist/commands/init.d.ts.map +0 -1
  56. package/dist/commands/init.js.map +0 -1
  57. package/dist/commands/list.d.ts.map +0 -1
  58. package/dist/commands/list.js.map +0 -1
  59. package/dist/commands/login.d.ts.map +0 -1
  60. package/dist/commands/login.js.map +0 -1
  61. package/dist/commands/logout.d.ts.map +0 -1
  62. package/dist/commands/logout.js.map +0 -1
  63. package/dist/commands/orgs.d.ts.map +0 -1
  64. package/dist/commands/orgs.js.map +0 -1
  65. package/dist/commands/projects.d.ts.map +0 -1
  66. package/dist/commands/projects.js.map +0 -1
  67. package/dist/commands/repair.d.ts.map +0 -1
  68. package/dist/commands/repair.js.map +0 -1
  69. package/dist/commands/restore.d.ts.map +0 -1
  70. package/dist/commands/restore.js.map +0 -1
  71. package/dist/commands/security-snapshot.d.ts.map +0 -1
  72. package/dist/commands/security-snapshot.js.map +0 -1
  73. package/dist/commands/uninstall.d.ts.map +0 -1
  74. package/dist/commands/uninstall.js.map +0 -1
  75. package/dist/commands/whoami.d.ts.map +0 -1
  76. package/dist/commands/whoami.js.map +0 -1
  77. package/dist/compat/engine.d.ts.map +0 -1
  78. package/dist/compat/engine.js.map +0 -1
  79. package/dist/config/define.d.ts.map +0 -1
  80. package/dist/config/define.js.map +0 -1
  81. package/dist/config/index.d.ts.map +0 -1
  82. package/dist/config/index.js.map +0 -1
  83. package/dist/config/loader.d.ts.map +0 -1
  84. package/dist/config/loader.js.map +0 -1
  85. package/dist/config/migrations.d.ts.map +0 -1
  86. package/dist/config/migrations.js.map +0 -1
  87. package/dist/config/precedence.d.ts.map +0 -1
  88. package/dist/config/precedence.js.map +0 -1
  89. package/dist/config/schema.d.ts.map +0 -1
  90. package/dist/config/schema.js.map +0 -1
  91. package/dist/config/types.d.ts.map +0 -1
  92. package/dist/config/types.js.map +0 -1
  93. package/dist/credentials/encrypted-file.d.ts.map +0 -1
  94. package/dist/credentials/encrypted-file.js.map +0 -1
  95. package/dist/credentials/error.d.ts.map +0 -1
  96. package/dist/credentials/error.js.map +0 -1
  97. package/dist/credentials/index.d.ts.map +0 -1
  98. package/dist/credentials/index.js.map +0 -1
  99. package/dist/credentials/keychain-darwin.d.ts.map +0 -1
  100. package/dist/credentials/keychain-darwin.js.map +0 -1
  101. package/dist/credentials/keychain-linux.d.ts.map +0 -1
  102. package/dist/credentials/keychain-linux.js.map +0 -1
  103. package/dist/credentials/keychain-win.d.ts.map +0 -1
  104. package/dist/credentials/keychain-win.js.map +0 -1
  105. package/dist/credentials/types.d.ts.map +0 -1
  106. package/dist/credentials/types.js.map +0 -1
  107. package/dist/detect/framework.d.ts.map +0 -1
  108. package/dist/detect/framework.js.map +0 -1
  109. package/dist/detect/index.d.ts.map +0 -1
  110. package/dist/detect/index.js.map +0 -1
  111. package/dist/detect/monorepo.d.ts.map +0 -1
  112. package/dist/detect/monorepo.js.map +0 -1
  113. package/dist/detect/package-manager.d.ts.map +0 -1
  114. package/dist/detect/package-manager.js.map +0 -1
  115. package/dist/index.d.ts.map +0 -1
  116. package/dist/index.js.map +0 -1
  117. package/dist/integrations/_scaffold.d.ts.map +0 -1
  118. package/dist/integrations/_scaffold.js.map +0 -1
  119. package/dist/integrations/_shared.d.ts.map +0 -1
  120. package/dist/integrations/_shared.js.map +0 -1
  121. package/dist/integrations/_simple-scaffold.d.ts.map +0 -1
  122. package/dist/integrations/_simple-scaffold.js.map +0 -1
  123. package/dist/integrations/dotnet.d.ts.map +0 -1
  124. package/dist/integrations/dotnet.js.map +0 -1
  125. package/dist/integrations/expo/detect.d.ts.map +0 -1
  126. package/dist/integrations/expo/detect.js.map +0 -1
  127. package/dist/integrations/expo/doctor.d.ts.map +0 -1
  128. package/dist/integrations/expo/doctor.js.map +0 -1
  129. package/dist/integrations/expo/files.d.ts.map +0 -1
  130. package/dist/integrations/expo/files.js.map +0 -1
  131. package/dist/integrations/expo/index.d.ts.map +0 -1
  132. package/dist/integrations/expo/index.js.map +0 -1
  133. package/dist/integrations/expo/manifest.d.ts.map +0 -1
  134. package/dist/integrations/expo/manifest.js.map +0 -1
  135. package/dist/integrations/expo/patch.d.ts.map +0 -1
  136. package/dist/integrations/expo/patch.js.map +0 -1
  137. package/dist/integrations/expo/uninstall.d.ts.map +0 -1
  138. package/dist/integrations/expo/uninstall.js.map +0 -1
  139. package/dist/integrations/expo.d.ts.map +0 -1
  140. package/dist/integrations/expo.js.map +0 -1
  141. package/dist/integrations/fastify/detect.d.ts.map +0 -1
  142. package/dist/integrations/fastify/detect.js.map +0 -1
  143. package/dist/integrations/fastify/doctor.d.ts.map +0 -1
  144. package/dist/integrations/fastify/doctor.js.map +0 -1
  145. package/dist/integrations/fastify/files.d.ts.map +0 -1
  146. package/dist/integrations/fastify/files.js.map +0 -1
  147. package/dist/integrations/fastify/index.d.ts.map +0 -1
  148. package/dist/integrations/fastify/index.js.map +0 -1
  149. package/dist/integrations/fastify/manifest.d.ts.map +0 -1
  150. package/dist/integrations/fastify/manifest.js.map +0 -1
  151. package/dist/integrations/fastify/patch.d.ts.map +0 -1
  152. package/dist/integrations/fastify/patch.js.map +0 -1
  153. package/dist/integrations/fastify/uninstall.d.ts.map +0 -1
  154. package/dist/integrations/fastify/uninstall.js.map +0 -1
  155. package/dist/integrations/fastify.d.ts.map +0 -1
  156. package/dist/integrations/fastify.js.map +0 -1
  157. package/dist/integrations/flutter.d.ts.map +0 -1
  158. package/dist/integrations/flutter.js.map +0 -1
  159. package/dist/integrations/go/index.d.ts.map +0 -1
  160. package/dist/integrations/go/index.js.map +0 -1
  161. package/dist/integrations/go.d.ts.map +0 -1
  162. package/dist/integrations/go.js.map +0 -1
  163. package/dist/integrations/java/index.d.ts.map +0 -1
  164. package/dist/integrations/java/index.js.map +0 -1
  165. package/dist/integrations/java.d.ts.map +0 -1
  166. package/dist/integrations/java.js.map +0 -1
  167. package/dist/integrations/js/detect.d.ts.map +0 -1
  168. package/dist/integrations/js/detect.js.map +0 -1
  169. package/dist/integrations/js/doctor.d.ts.map +0 -1
  170. package/dist/integrations/js/doctor.js.map +0 -1
  171. package/dist/integrations/js/files.d.ts.map +0 -1
  172. package/dist/integrations/js/files.js.map +0 -1
  173. package/dist/integrations/js/index.d.ts.map +0 -1
  174. package/dist/integrations/js/index.js.map +0 -1
  175. package/dist/integrations/js/manifest.d.ts.map +0 -1
  176. package/dist/integrations/js/manifest.js.map +0 -1
  177. package/dist/integrations/js/patch.d.ts.map +0 -1
  178. package/dist/integrations/js/patch.js.map +0 -1
  179. package/dist/integrations/js/uninstall.d.ts.map +0 -1
  180. package/dist/integrations/js/uninstall.js.map +0 -1
  181. package/dist/integrations/nestjs/detect.d.ts.map +0 -1
  182. package/dist/integrations/nestjs/detect.js.map +0 -1
  183. package/dist/integrations/nestjs/doctor.d.ts.map +0 -1
  184. package/dist/integrations/nestjs/doctor.js.map +0 -1
  185. package/dist/integrations/nestjs/files.d.ts.map +0 -1
  186. package/dist/integrations/nestjs/files.js.map +0 -1
  187. package/dist/integrations/nestjs/index.d.ts.map +0 -1
  188. package/dist/integrations/nestjs/index.js.map +0 -1
  189. package/dist/integrations/nestjs/manifest.d.ts.map +0 -1
  190. package/dist/integrations/nestjs/manifest.js.map +0 -1
  191. package/dist/integrations/nestjs/patch.d.ts.map +0 -1
  192. package/dist/integrations/nestjs/patch.js.map +0 -1
  193. package/dist/integrations/nestjs/uninstall.d.ts.map +0 -1
  194. package/dist/integrations/nestjs/uninstall.js.map +0 -1
  195. package/dist/integrations/nestjs.d.ts.map +0 -1
  196. package/dist/integrations/nestjs.js.map +0 -1
  197. package/dist/integrations/next/detect.d.ts.map +0 -1
  198. package/dist/integrations/next/detect.js.map +0 -1
  199. package/dist/integrations/next/doctor.d.ts.map +0 -1
  200. package/dist/integrations/next/doctor.js.map +0 -1
  201. package/dist/integrations/next/files.d.ts.map +0 -1
  202. package/dist/integrations/next/files.js.map +0 -1
  203. package/dist/integrations/next/index.d.ts.map +0 -1
  204. package/dist/integrations/next/index.js.map +0 -1
  205. package/dist/integrations/next/manifest.d.ts.map +0 -1
  206. package/dist/integrations/next/manifest.js.map +0 -1
  207. package/dist/integrations/next/patch.d.ts.map +0 -1
  208. package/dist/integrations/next/patch.js.map +0 -1
  209. package/dist/integrations/next/uninstall.d.ts.map +0 -1
  210. package/dist/integrations/next/uninstall.js.map +0 -1
  211. package/dist/integrations/otel.d.ts.map +0 -1
  212. package/dist/integrations/otel.js.map +0 -1
  213. package/dist/integrations/php.d.ts.map +0 -1
  214. package/dist/integrations/php.js.map +0 -1
  215. package/dist/integrations/python/index.d.ts.map +0 -1
  216. package/dist/integrations/python/index.js.map +0 -1
  217. package/dist/integrations/python.d.ts.map +0 -1
  218. package/dist/integrations/python.js.map +0 -1
  219. package/dist/integrations/react/detect.d.ts.map +0 -1
  220. package/dist/integrations/react/detect.js.map +0 -1
  221. package/dist/integrations/react/doctor.d.ts.map +0 -1
  222. package/dist/integrations/react/doctor.js.map +0 -1
  223. package/dist/integrations/react/files.d.ts.map +0 -1
  224. package/dist/integrations/react/files.js.map +0 -1
  225. package/dist/integrations/react/index.d.ts.map +0 -1
  226. package/dist/integrations/react/index.js.map +0 -1
  227. package/dist/integrations/react/manifest.d.ts.map +0 -1
  228. package/dist/integrations/react/manifest.js.map +0 -1
  229. package/dist/integrations/react/patch.d.ts.map +0 -1
  230. package/dist/integrations/react/patch.js.map +0 -1
  231. package/dist/integrations/react/uninstall.d.ts.map +0 -1
  232. package/dist/integrations/react/uninstall.js.map +0 -1
  233. package/dist/integrations/react-native.d.ts.map +0 -1
  234. package/dist/integrations/react-native.js.map +0 -1
  235. package/dist/integrations/ruby.d.ts.map +0 -1
  236. package/dist/integrations/ruby.js.map +0 -1
  237. package/dist/lifecycle/hooks.d.ts.map +0 -1
  238. package/dist/lifecycle/hooks.js.map +0 -1
  239. package/dist/migrations/builtin/dsn-to-api-key.d.ts.map +0 -1
  240. package/dist/migrations/builtin/dsn-to-api-key.js.map +0 -1
  241. package/dist/migrations/engine.d.ts.map +0 -1
  242. package/dist/migrations/engine.js.map +0 -1
  243. package/dist/migrations/index.d.ts.map +0 -1
  244. package/dist/migrations/index.js.map +0 -1
  245. package/dist/output/human.d.ts.map +0 -1
  246. package/dist/output/human.js.map +0 -1
  247. package/dist/output/index.d.ts.map +0 -1
  248. package/dist/output/index.js.map +0 -1
  249. package/dist/output/json.d.ts.map +0 -1
  250. package/dist/output/json.js.map +0 -1
  251. package/dist/output/types.d.ts.map +0 -1
  252. package/dist/output/types.js.map +0 -1
  253. package/dist/patchers/env-file.d.ts.map +0 -1
  254. package/dist/patchers/env-file.js.map +0 -1
  255. package/dist/patchers/js-ast.d.ts.map +0 -1
  256. package/dist/patchers/js-ast.js.map +0 -1
  257. package/dist/patchers/json-file.d.ts.map +0 -1
  258. package/dist/patchers/json-file.js.map +0 -1
  259. package/dist/patchers/markers.d.ts.map +0 -1
  260. package/dist/patchers/markers.js.map +0 -1
  261. package/dist/patchers/source-block.d.ts.map +0 -1
  262. package/dist/patchers/source-block.js.map +0 -1
  263. package/dist/registry/index.d.ts.map +0 -1
  264. package/dist/registry/index.js.map +0 -1
  265. package/dist/registry/manifest.d.ts.map +0 -1
  266. package/dist/registry/manifest.js.map +0 -1
  267. package/dist/registry/registry.d.ts.map +0 -1
  268. package/dist/registry/registry.js.map +0 -1
  269. package/dist/registry/types.d.ts.map +0 -1
  270. package/dist/registry/types.js.map +0 -1
  271. package/dist/security-snapshot/builder.d.ts.map +0 -1
  272. package/dist/security-snapshot/builder.js.map +0 -1
  273. package/dist/security-snapshot/client.d.ts.map +0 -1
  274. package/dist/security-snapshot/client.js.map +0 -1
  275. package/dist/security-snapshot/index.d.ts.map +0 -1
  276. package/dist/security-snapshot/index.js.map +0 -1
  277. package/dist/security-snapshot/types.d.ts.map +0 -1
  278. package/dist/security-snapshot/types.js.map +0 -1
  279. package/dist/snapshot/restore.d.ts.map +0 -1
  280. package/dist/snapshot/restore.js.map +0 -1
  281. package/dist/snapshot/store.d.ts.map +0 -1
  282. package/dist/snapshot/store.js.map +0 -1
  283. package/dist/sourcemaps/index.d.ts.map +0 -1
  284. package/dist/sourcemaps/index.js.map +0 -1
  285. package/dist/sourcemaps/metro.d.ts.map +0 -1
  286. package/dist/sourcemaps/metro.js.map +0 -1
  287. package/dist/sourcemaps/next.d.ts.map +0 -1
  288. package/dist/sourcemaps/next.js.map +0 -1
  289. package/dist/sourcemaps/provider.d.ts.map +0 -1
  290. package/dist/sourcemaps/provider.js.map +0 -1
  291. package/dist/sourcemaps/vite.d.ts.map +0 -1
  292. package/dist/sourcemaps/vite.js.map +0 -1
  293. package/dist/sourcemaps/webpack.d.ts.map +0 -1
  294. package/dist/sourcemaps/webpack.js.map +0 -1
  295. package/dist/telemetry/cli-wrap.d.ts.map +0 -1
  296. package/dist/telemetry/cli-wrap.js.map +0 -1
  297. package/dist/telemetry/http-provider.d.ts.map +0 -1
  298. package/dist/telemetry/http-provider.js.map +0 -1
  299. package/dist/telemetry/index.d.ts.map +0 -1
  300. package/dist/telemetry/index.js.map +0 -1
  301. package/dist/telemetry/install-id.d.ts.map +0 -1
  302. package/dist/telemetry/install-id.js.map +0 -1
  303. package/dist/telemetry/payload.d.ts.map +0 -1
  304. package/dist/telemetry/payload.js.map +0 -1
  305. package/dist/telemetry/provider.d.ts.map +0 -1
  306. package/dist/telemetry/provider.js.map +0 -1
  307. package/dist/telemetry/runtime.d.ts.map +0 -1
  308. package/dist/telemetry/runtime.js.map +0 -1
  309. package/dist/transaction/tx.d.ts.map +0 -1
  310. package/dist/transaction/tx.js.map +0 -1
  311. package/dist/util/error-codes.d.ts.map +0 -1
  312. package/dist/util/error-codes.js.map +0 -1
  313. package/dist/util/errors.d.ts.map +0 -1
  314. package/dist/util/errors.js.map +0 -1
  315. package/dist/util/log.d.ts.map +0 -1
  316. package/dist/util/log.js.map +0 -1
  317. package/dist/util/paths.d.ts.map +0 -1
  318. package/dist/util/paths.js.map +0 -1
  319. package/dist/util/version.d.ts.map +0 -1
  320. package/dist/util/version.js.map +0 -1
  321. package/dist/util/wizard-version.d.ts.map +0 -1
  322. package/dist/util/wizard-version.js.map +0 -1
  323. package/docs/architecture/README.md +0 -58
  324. package/docs/architecture/dry-run.md +0 -34
  325. package/docs/architecture/integration-lifecycle.md +0 -77
  326. package/docs/architecture/patch-pipeline.md +0 -58
  327. package/docs/architecture/registry.md +0 -52
  328. package/docs/architecture/rollback.md +0 -47
  329. package/docs/architecture/sourcemaps.md +0 -53
  330. package/docs/architecture/stability-levels.md +0 -35
  331. package/docs/architecture/transaction.md +0 -51
  332. package/docs/architecture/v02-bare-react-native-spec.md +0 -92
  333. package/docs/architecture/v02-java-host-fix-spec.md +0 -121
  334. package/docs/architecture/v02-sourcemaps-e2e-spec.md +0 -157
  335. package/docs/beta/README.md +0 -17
  336. package/docs/beta/ci.md +0 -122
  337. package/docs/beta/config.md +0 -124
  338. package/docs/beta/doctor.md +0 -79
  339. package/docs/beta/expo.md +0 -69
  340. package/docs/beta/fastify.md +0 -62
  341. package/docs/beta/known-limitations.md +0 -93
  342. package/docs/beta/nestjs.md +0 -69
  343. package/docs/beta/next.md +0 -76
  344. package/docs/beta/node.md +0 -60
  345. package/docs/beta/privacy.md +0 -99
  346. package/docs/beta/quickstart.md +0 -89
  347. package/docs/beta/react.md +0 -91
  348. package/docs/beta/reliability.md +0 -33
  349. package/docs/beta/restore.md +0 -84
  350. package/docs/beta/troubleshooting.md +0 -133
@@ -1,58 +0,0 @@
1
- # @allstak/wizard — architecture docs
2
-
3
- These docs explain how the wizard is built so contributors can extend it without
4
- re-reading the entire codebase.
5
-
6
- | Doc | What it covers |
7
- |-----|----------------|
8
- | [registry.md](./registry.md) | How integrations are discovered, registered, and surfaced |
9
- | [integration-lifecycle.md](./integration-lifecycle.md) | The 7-step contract every integration implements |
10
- | [patch-pipeline.md](./patch-pipeline.md) | How a patch flows from `init` to disk (or dry-run diff) |
11
- | [transaction.md](./transaction.md) | The transactional file-mutation core |
12
- | [rollback.md](./rollback.md) | In-memory rollback (per-run) + persistent snapshots (cross-run) |
13
- | [dry-run.md](./dry-run.md) | What `--dry-run` does (and what it does NOT touch) |
14
- | [sourcemaps.md](./sourcemaps.md) | Source-map provider abstraction (vite/webpack/next/metro) |
15
- | [stability-levels.md](./stability-levels.md) | stable / beta / experimental / unsupported semantics |
16
-
17
- ## High-level
18
-
19
- ```
20
- ┌──────────────────────────┐
21
- │ CLI (commander) │
22
- │ - parses argv │
23
- │ - picks reporter │
24
- └────────────┬─────────────┘
25
-
26
-
27
- ┌──────────────────────────────────────────┐
28
- │ Command (init / doctor / repair / ...) │
29
- │ - buildContext() │
30
- │ - bootstrap registries │
31
- │ - drive integration lifecycle │
32
- └────┬─────────────┬──────────────┬────────┘
33
- │ │ │
34
- ▼ ▼ ▼
35
- ┌─────────┐ ┌────────────┐ ┌────────────────┐
36
- │ Compat │ │ Integration │ │ SnapshotStore │
37
- │ engine │ │ (react/...) │ │ Transaction │
38
- └─────────┘ │ - manifest │ │ - rollback │
39
- │ - detect │ └────────────────┘
40
- │ - patch │
41
- │ - … │
42
- └────┬─────────┘
43
-
44
- ┌────────────────────┐
45
- │ Patchers (env, JS-AST,│
46
- │ source-block, JSON) │
47
- └────────────────────┘
48
-
49
-
50
- ┌────────────────────┐
51
- │ SourceMap providers│
52
- │ (vite/webpack/ │
53
- │ next/metro) │
54
- └────────────────────┘
55
- ```
56
-
57
- Layers are linearly stacked — the CLI never reaches into a patcher directly,
58
- and patchers never know which integration is using them.
@@ -1,34 +0,0 @@
1
- # Dry-run
2
-
3
- `--dry-run` shows the user what the wizard _would_ do without touching disk.
4
-
5
- ## What it does
6
-
7
- 1. `Transaction` records every `tx.write()` / `tx.delete()` call as a
8
- `PlannedDiff` entry but **does not** open files for writing.
9
- 2. `SnapshotStore.begin()` is invoked but its `commit()` is replaced by
10
- `abort()` — no backup directory is created.
11
- 3. The reporter's `diff()` method emits the planned changes (human-readable
12
- table or `diff` array in `--json`).
13
- 4. Package-manager `install` / `uninstall` calls are also short-circuited:
14
- `runPackageInstall` prints `(dry-run) would run: ...` and returns.
15
-
16
- ## What it does NOT touch
17
-
18
- - `node_modules/` — never installed during dry-run.
19
- - `package.json` — not read or written for diff purposes (we only inspect
20
- installed deps via the existing snapshot of detection).
21
- - Network — the connectivity probe in `doctor` is the only outbound HTTP
22
- the wizard makes; `init` itself is offline.
23
-
24
- ## Edge cases
25
-
26
- - A dry-run on a project that has _never_ been patched produces a `+ create`
27
- diff for every file the wizard would create, plus `~ modify` for every
28
- file it would change.
29
- - A dry-run on a fully-patched project produces an empty diff (idempotent
30
- re-runs are byte-identical, so `Transaction.write()` short-circuits when
31
- `code === before`).
32
- - A dry-run with `--experimental` allows scaffolded integrations to run
33
- their (no-op) patch, useful for verifying the plan output of integrations
34
- not yet validated.
@@ -1,77 +0,0 @@
1
- # Integration lifecycle
2
-
3
- Every integration implements the same 7-step contract. The orchestrator calls
4
- them in this order during `init`:
5
-
6
- ```
7
- detect → plan → (confirm) → install → patch → validate
8
- ```
9
-
10
- And these reverse / maintenance ops:
11
-
12
- ```
13
- uninstall · repair · doctor
14
- ```
15
-
16
- ## Steps
17
-
18
- ### `detect(ctx) → CompatibilityCheck`
19
-
20
- Read-only. Reports whether this integration can run on the current project.
21
- Should return `{ ok: false, reason: ... }` for unsupported versions, missing
22
- deps, etc.
23
-
24
- **Convention:** delegate to `evaluateCompatibility(manifest, packageJson)`
25
- from `src/compat/engine.ts`. Do not inline semver checks.
26
-
27
- ### `plan(ctx) → string[]`
28
-
29
- Read-only. Returns an ordered list of human-readable lines describing what
30
- `patch()` will do. Printed before the user confirms (or always in `--dry-run`).
31
-
32
- ### `install(ctx)`
33
-
34
- Runs the package-manager install. Outside the transaction — package managers
35
- own their own atomicity. `--skip-deps` makes this a no-op.
36
-
37
- ### `patch(ctx, tx)`
38
-
39
- The only step that mutates files. Always called inside a `Transaction`. Must
40
- be **idempotent**: re-running `patch()` over an already-patched project must
41
- produce byte-identical output (verified by tests).
42
-
43
- ### `validate(ctx) → DoctorReport`
44
-
45
- Read-only post-install verification. Currently delegates to `doctor(ctx)`. In
46
- v0.2 will gain optional live event-ingestion verification.
47
-
48
- ### `uninstall(ctx, tx)`
49
-
50
- Reverse of `patch()`. Must remove every file mutation and uninstall the SDK
51
- package. Uses managed-block markers to scope removal.
52
-
53
- ### `repair(ctx, tx)`
54
-
55
- Re-runs `patch()` over an existing setup to fix drift (e.g. someone deleted
56
- the env block by hand). `--skip-deps` is implicit.
57
-
58
- ### `doctor(ctx) → DoctorReport`
59
-
60
- Pure read. Inspects the project state and reports per-check status (`pass` /
61
- `warn` / `fail` / `skip`) plus a summary (`ok` / `degraded` / `broken`).
62
-
63
- ## Lifecycle hooks
64
-
65
- Around `install`, `patch`, and rollback, the orchestrator emits events on the
66
- context's `LifecycleEmitter`:
67
-
68
- - `beforeInstall` / `afterInstall`
69
- - `beforePatch` / `afterPatch`
70
- - `beforeRollback` / `afterRollback`
71
- - `beforeUninstall` / `afterUninstall`
72
-
73
- `before*` errors abort the run. `after*` errors are logged but swallowed.
74
- Hook subscribers receive `{ integration, ts, dryRun, data?, error? }`.
75
-
76
- Use cases: telemetry providers (currently `noopTelemetry` — see
77
- `src/telemetry/provider.ts`), audit logging, metrics, plugin extensions.
@@ -1,58 +0,0 @@
1
- # Patch pipeline
2
-
3
- How a single `init` invocation flows from CLI to disk.
4
-
5
- ```
6
- argv
7
-
8
-
9
- parseCli()
10
- │ reporter = createReporter(json ? 'json' : 'human')
11
-
12
- runInit({ ... reporter })
13
- │ bootstrapRegistry() / bootstrapSourceMaps() / bootstrapMigrations()
14
-
15
- ├─► buildContext() — projectRoot, framework detection, lifecycle emitter
16
-
17
- ├─► registry.require(id) — pick the integration
18
-
19
- ├─► integ.detect(ctx) — compat engine; throws E_COMPAT on failure
20
-
21
- ├─► stability gate — experimental? require --experimental; beta? warn
22
-
23
- ├─► integ.plan(ctx) — print plan; prompt for confirmation unless -y
24
-
25
- ├─► lifecycle.beforeInstall
26
- ├─► integ.install(ctx) — package-manager invocation (skipped on --skip-deps)
27
- ├─► lifecycle.afterInstall
28
-
29
- ├─► snapshotStore.begin(...) — opens persistent backup directory
30
- ├─► tx = new Transaction({ snapshotWriter, dryRun })
31
-
32
- ├─► lifecycle.beforePatch
33
- ├─► tx.run(() => integ.patch(ctx, tx))
34
- │ │
35
- │ ├─► writeStandardEnv() ───► patchEnvFile()
36
- │ ├─► patchJsModule(entry, ...)
37
- │ ├─► appendManagedBlock(entry, ...)
38
- │ └─► sourceMapRegistry.get('vite').wire(ctx, tx)
39
-
40
- ├─► lifecycle.afterPatch
41
-
42
- ├─► snapshotStore.prune(keep)
43
- ├─► integ.validate(ctx) — runs doctor, prints report
44
- └─► reporter.finalize({ outcome, durationMs, data: { doctor }})
45
- ```
46
-
47
- ## Where to extend
48
-
49
- | Want to add | Touch |
50
- |-------------|-------|
51
- | New integration | `src/integrations/<id>/` + `bootstrapRegistry()` |
52
- | New version rule | `src/integrations/<id>/manifest.ts:compatibility` |
53
- | New file mutation kind | `src/patchers/` |
54
- | New bundler source-map provider | `src/sourcemaps/` + `bootstrapSourceMaps()` |
55
- | New env-var migration | `src/migrations/builtin/` + `bootstrapMigrations()` |
56
- | New CLI command | `src/commands/` + `src/cli.ts` |
57
- | New output mode | `src/output/` + `createReporter()` |
58
- | New telemetry sink | `src/telemetry/provider.ts:setTelemetryProvider()` + lifecycle subscriptions |
@@ -1,52 +0,0 @@
1
- # Registry
2
-
3
- ## What it is
4
-
5
- A single in-memory map from `IntegrationId` → `Integration`. Integrations
6
- register themselves at boot via `bootstrapRegistry()`. The CLI is integration-
7
- agnostic — every command accepts `-i <id>`, looks the integration up in the
8
- registry, and drives the lifecycle.
9
-
10
- ## Contract
11
-
12
- Every integration exposes:
13
-
14
- - `id: IntegrationId` — must match the value in its `manifest.id`.
15
- - `manifest: IntegrationManifest` — machine-readable metadata (versions,
16
- capabilities, files, stability level). Surfaced via `allstak-wizard list`,
17
- `allstak-wizard list --json`, and the programmatic API.
18
- - Seven lifecycle methods: `detect`, `plan`, `install`, `patch`, `validate`,
19
- `uninstall`, `repair`, `doctor`. See `integration-lifecycle.md`.
20
-
21
- ## Adding a new integration
22
-
23
- 1. Pick an `IntegrationId` (add to the union in `src/detect/framework.ts`).
24
- 2. Create `src/integrations/<id>/` with:
25
- - `manifest.ts` — fill in stability, capabilities, compatibility, files.
26
- - `files.ts` — file-locator helpers (no logic).
27
- - `detect.ts` — calls `evaluateCompatibility(manifest, packageJson)` from
28
- the compat engine. Don't inline `meetsMinimum(...)` — central rules only.
29
- - `patch.ts` — install + env + entry + source-map wiring.
30
- - `uninstall.ts` — reverse of `patch.ts`.
31
- - `doctor.ts` — read-only health check.
32
- - `index.ts` — composes the `Integration` object.
33
- 3. Register in `src/registry/index.ts:bootstrapRegistry()`.
34
- 4. Add a fixture under `fixtures/<id>-*/` if the patch path is non-trivial.
35
- 5. Write tests under `test/integration-<id>.test.mts`.
36
-
37
- If the integration is not yet validated end-to-end, set
38
- `manifest.stability = 'experimental'` and use `simpleScaffold(...)` to keep
39
- the boilerplate small.
40
-
41
- ## Stability gating
42
-
43
- The orchestrator gates on `manifest.stability`:
44
-
45
- - `stable` — runs without warning.
46
- - `beta` — runs but emits a warning line.
47
- - `experimental` — refuses to run patching unless `--experimental` is passed.
48
- - `unsupported` — `detect()` is expected to throw `UnsupportedFrameworkError`
49
- and the integration acts as documentation only.
50
-
51
- This single-source gating means integrations don't need to repeat the warning
52
- or the refusal logic — just declare your stability level in the manifest.
@@ -1,47 +0,0 @@
1
- # Rollback
2
-
3
- The wizard has **two** rollback layers with different scopes:
4
-
5
- ## 1. In-memory transactional rollback (per-run)
6
-
7
- `Transaction` snapshots every touched file on first write. If `tx.run(work)`
8
- throws — or a syntax validator rejects a write — the transaction restores
9
- each file in reverse order and re-throws the error wrapped in
10
- `TransactionAbortedError`.
11
-
12
- Scope: lasts for one wizard invocation. Does not survive process exit.
13
-
14
- ## 2. Persistent snapshots (cross-run)
15
-
16
- `SnapshotStore` writes a backup directory at
17
- `<projectRoot>/.allstak-wizard/backups/<timestamp>--<integration>--<random>/`
18
- containing:
19
-
20
- - `manifest.json` — schema-versioned record of what changed (path, kind,
21
- size).
22
- - `files/<rel-path>` — the exact pre-image bytes for each modified file.
23
- - `files/<rel-path>.allstak-deleted` — empty marker for files that did not
24
- exist before the run (so `wizard restore` knows to delete them).
25
-
26
- Scope: lives on disk until `SnapshotStore.prune(keep)` removes it (default
27
- retention is 10 most recent runs in `init.ts`).
28
-
29
- ## What persistent snapshots are for
30
-
31
- - Support / debugging — "show me what the wizard changed yesterday."
32
- - Future `wizard restore` command (v0.2) — point-in-time restore of any
33
- backed-up run.
34
- - Audit trail when a CI pipeline re-runs the wizard on shared infra.
35
-
36
- Snapshots are NOT used by the in-process rollback path — that has its own
37
- in-memory pre-image. Two layers, one purpose: make every wizard run safe
38
- both _during_ execution and _after_ commit.
39
-
40
- ## Failure modes
41
-
42
- - If a snapshot directory cannot be written (permissions, full disk), the
43
- wizard logs a warning and continues — the transactional rollback path is
44
- unaffected because it doesn't depend on the persistent store.
45
- - If the wizard process is killed mid-write (SIGKILL), in-memory rollback is
46
- lost. The persistent snapshot for that run is partial: `manifest.json` was
47
- not yet written, so `SnapshotStore.list()` ignores the directory.
@@ -1,53 +0,0 @@
1
- # Source-map providers
2
-
3
- Source-map wiring used to live inside each integration's `patch()` method,
4
- which made it hard to reuse the Vite plugin wiring for a Vue/Solid integration
5
- later. v0.1.1 extracted it into a `SourceMapProvider` abstraction.
6
-
7
- ## Provider contract
8
-
9
- ```ts
10
- interface SourceMapProvider {
11
- id: 'vite' | 'webpack' | 'next' | 'metro';
12
- title: string;
13
- pluginPackage: string;
14
- detect(ctx): Promise<boolean>;
15
- wire(ctx, tx): Promise<void>;
16
- unwire(ctx, tx): Promise<void>;
17
- status(ctx): Promise<SourceMapStatus>;
18
- }
19
- ```
20
-
21
- Each provider is registered on `sourceMapRegistry` via
22
- `bootstrapSourceMaps()`. Integrations look providers up by id rather than
23
- constructing them inline:
24
-
25
- ```ts
26
- const vite = sourceMapRegistry.get('vite');
27
- if (vite && (await vite.detect(ctx))) await vite.wire(ctx, tx);
28
- ```
29
-
30
- ## Status semantics
31
-
32
- `status(ctx)` returns one of:
33
-
34
- - `wired` — the plugin import is present and active.
35
- - `missing` — the bundler exists but the plugin is not wired.
36
- - `drifted` — the plugin is partially wired (e.g. import added but plugin
37
- not invoked); doctor surfaces this as a warning with a `reason`.
38
-
39
- ## Current providers
40
-
41
- | Provider | Status |
42
- |---|---|
43
- | `vite` | Validated. AST imports + managed-block hint in `vite.config.*`. |
44
- | `next` | Validated. Managed-block hint in `next.config.*` (no AST mutation — Next configs vary too much). |
45
- | `webpack` | Scaffolded. Managed-block hint only; AST mutation deferred (Webpack factory configs are too varied). |
46
- | `metro` | **Inert in v0.1.** `detect()` returns false; wire/unwire are no-ops. v0.2 will replace with real Gradle hook + iOS post-build. |
47
-
48
- ## Adding a provider
49
-
50
- 1. Create `src/sourcemaps/<bundler>.ts` exporting a `SourceMapProvider`.
51
- 2. Register in `src/sourcemaps/index.ts:bootstrapSourceMaps()`.
52
- 3. The integration's `patch.ts` needs no change beyond looking the provider
53
- up by id.
@@ -1,35 +0,0 @@
1
- # Stability levels
2
-
3
- Replaces the binary `validated: boolean` flag. Every integration declares one
4
- of four stability levels in its `manifest.stability`:
5
-
6
- | Level | Behaviour | Doctor | When to use |
7
- |-------|-----------|--------|-------------|
8
- | `stable` | Runs without warning. | All checks must pass. | Fully validated end-to-end, fixture-tested, CLI-smoke-tested. |
9
- | `beta` | Runs but emits a warning line citing the manifest's `stabilityNote`. | Same checks as stable, but `degraded` summary acceptable. | Implementation complete, missing one of: live event ingestion, native build, multi-version matrix. |
10
- | `experimental` | Refuses to run patching unless `--experimental` is passed. | Always reports `broken` to surface the gap. | Scaffolded — install + env writing only. Framework wiring deferred. |
11
- | `unsupported` | `detect()` throws `UnsupportedFrameworkError` regardless of flags. | Always reports `broken`. | Intentionally refused (e.g. bare React Native in v0.1). |
12
-
13
- ## Why four levels, not two
14
-
15
- A binary flag forced us to either lie ("validated") or refuse to register
16
- (can't surface to `list`). The four-level model lets us:
17
-
18
- - Be honest about what is and isn't tested (`beta` is real, validated, but
19
- not yet at parity with `stable` on one axis).
20
- - Let users opt into experimental integrations without flipping a global
21
- feature flag.
22
- - Keep `unsupported` integrations in the registry as documentation — they
23
- show up in `list`, throw a clear pointer to manual setup, and prevent
24
- accidental partial-support.
25
-
26
- ## Where the gating lives
27
-
28
- `src/integrations/_scaffold.ts` handles the gating uniformly. Integrations
29
- declare their level in the manifest; `buildScaffold()` derives the right
30
- behaviour. `src/commands/init.ts` inspects `integration.manifest.stability`
31
- to decide whether to print the beta warning or refuse without
32
- `--experimental`.
33
-
34
- This means contributors adding a new integration only need to set one field
35
- to control the user-facing behaviour — never edit the orchestrator.
@@ -1,51 +0,0 @@
1
- # Transaction
2
-
3
- `src/transaction/tx.ts`. Ensures every wizard run is atomic with respect to
4
- the user's source tree.
5
-
6
- ## Contract
7
-
8
- A `Transaction`:
9
-
10
- 1. **Snapshots** every file before its first write (in-memory pre-image).
11
- 2. **Writes** the new content via `tx.write(path, content, validator?)`.
12
- 3. Optionally runs a **syntax validator** on the new content; a thrown error
13
- triggers immediate rollback of the file.
14
- 4. On success, **commits** — pre-images are dropped from memory but the
15
- `SnapshotWriter` flushes them to `.allstak-wizard/backups/` for audit.
16
- 5. On any thrown error inside `tx.run(work)`, **rolls back** all writes in
17
- reverse order, then re-throws as `TransactionAbortedError`.
18
-
19
- ## Semantics
20
-
21
- - The same path written multiple times only snapshots once (the first call
22
- captures the true pre-image).
23
- - Newly created files are restored to non-existence on rollback (we delete the
24
- newly-created file).
25
- - `tx.delete(path)` is staged the same way: snapshot the deleted content,
26
- remove from disk, restore on rollback.
27
- - `dryRun: true` records the planned diff but skips disk I/O entirely. Both
28
- rollback and snapshot persistence become no-ops.
29
-
30
- ## Usage pattern
31
-
32
- ```ts
33
- const tx = new Transaction({ cwd, dryRun, snapshotWriter });
34
- await tx.run(async () => {
35
- await tx.write(envPath, newEnvContent);
36
- await patchJsModule(tx, entryPath, (mod) => ensureImport(mod, ...));
37
- await appendManagedBlock(tx, entryPath, '...', { style: 'slash', validateJs: true });
38
- });
39
- // On exception inside the body, ALL three writes are rolled back.
40
- ```
41
-
42
- ## Why a custom transaction layer
43
-
44
- We considered `git worktree` / `git stash` for atomicity but rejected it:
45
-
46
- - Many AllStak users run the wizard in CI on a clean worktree where there's
47
- nothing to stash and no `.git` to query.
48
- - Wizard ops touch a small set of well-known files, not arbitrary trees — a
49
- custom transactional layer is ~150 LoC and has zero external deps.
50
- - We want syntax validation on writes (re-parse the file with magicast) which
51
- would be awkward to express through git plumbing.
@@ -1,92 +0,0 @@
1
- # v0.2 spec — Bare React Native integration
2
-
3
- **Status:** UNSUPPORTED in v0.1.x — wizard refuses with `UnsupportedFrameworkError`.
4
-
5
- This spec is what v0.2 must implement before `react-native` flips from `unsupported` to `experimental` (and eventually `beta`).
6
-
7
- ---
8
-
9
- ## Why bare RN is hard
10
-
11
- Bare RN integration is the only wizard target that touches **three** ecosystems at once:
12
-
13
- 1. JavaScript / TypeScript source (entry file wrap).
14
- 2. **iOS native** — Podfile + AppDelegate.swift modifications, CocoaPods install.
15
- 3. **Android native** — settings.gradle + app/build.gradle, Gradle plugin classpath, AndroidManifest.
16
-
17
- Any one of these going wrong bricks `xcodebuild` or `./gradlew assembleDebug`. Wizard cannot validate that without running real device builds, which the v0.1.x test infrastructure does not have.
18
-
19
- Expo (config-plugin path) is a strict subset of this surface and is already partially scaffolded (`stability: experimental`).
20
-
21
- ---
22
-
23
- ## Validation matrix v0.2 must pass
24
-
25
- Before flipping `stability` from `unsupported`:
26
-
27
- | Path | Validation |
28
- |------|------------|
29
- | Patch idempotency | `init` → `init` produces byte-identical project (already a wizard invariant; just needs a fixture to assert against). |
30
- | iOS sim build | `npx react-native run-ios` succeeds on iOS 16/17/18 simulators against a fresh fixture; AllStak crash hook captured a synthetic crash. |
31
- | Android emu build | `npx react-native run-android` succeeds against API 31/33/34 emulators. |
32
- | Hermes source-map round-trip | A symbolicated stack frame from a bundled-and-uploaded JS file resolves on the dashboard. |
33
- | Uninstall | After `init` then `uninstall`, both `xcodebuild` and `gradlew assembleDebug` still pass; no dangling Pod or Gradle entries. |
34
- | Repair | After hand-deleting our managed Podfile region, `repair` reinstates it without touching any other Podfile content. |
35
- | New Architecture (Fabric / TurboModules) | If the project enables `newArchEnabled=true`, the integration must not regress build. |
36
-
37
- The v0.1.x repo already supports Fixture-based testing in `fixtures/`. v0.2 needs a `fixtures/react-native-bare/` (and matching `react-native-expo/`) plus a CI runner that has Xcode + Android emulator access.
38
-
39
- ---
40
-
41
- ## Files the integration patches
42
-
43
- ### iOS
44
-
45
- - `ios/Podfile` — append (inside the project's main target):
46
- ```ruby
47
- pod 'AllStakRN', :path => '../node_modules/@allstak/react-native'
48
- ```
49
- - `ios/<App>/AppDelegate.{m,mm,swift}` — call `[AllStak start]` from `application:didFinishLaunchingWithOptions:`.
50
- - Wizard MUST detect Obj-C vs Swift AppDelegate and choose the right insertion.
51
- - All insertions wrapped in markers (`// >>> allstak-wizard:v1 ...`).
52
-
53
- ### Android
54
-
55
- - `android/settings.gradle` — append `include ':allstak-react-native'` and the matching `project(...)` line.
56
- - `android/app/build.gradle` — `dependencies { implementation project(':allstak-react-native') }`.
57
- - `android/app/src/main/java/.../MainApplication.{java,kt}` — register the package in `getPackages()`.
58
- - Wizard MUST read `org.gradle.jvmargs` to detect Hermes and conditionally wire the source-map post-build hook from `allstak-react-native/build-hooks/allstak-sourcemaps.gradle`.
59
-
60
- ### JavaScript
61
-
62
- - `index.js` / `App.tsx` — wrap root component in `<AllStakProvider>` (same pattern as `react`).
63
- - `metro.config.js` — extend `transformer.hermesParser` only when needed; default leave alone.
64
-
65
- ---
66
-
67
- ## Open questions for v0.2 design
68
-
69
- 1. **Does `pod install` run inside the wizard's transaction?** Recommendation: NO. Pod install mutates `Podfile.lock` and the `Pods/` tree atomically; rolling that back is not feasible. The wizard should print "Pods updated; run `pod install` once more if you see linker errors" and let the user own that step.
70
- 2. **Does the integration block on a connected emulator?** Recommendation: NO. The wizard is offline-first; users can run `react-native run-ios` themselves. Integration tests in CI gate on emulator presence.
71
- 3. **Expo bare workflow** (post-`expo prebuild`) — is this `expo` integration (config-plugin path) or `react-native` (bare path)? Recommendation: detect `npx expo prebuild` evidence (presence of `ios/` AND a `app.json` with `expo` key) and offer the user a choice.
72
- 4. **Old Architecture vs New Architecture** — wizard reads `android/gradle.properties:newArchEnabled`. If true, the integration must include the Fabric component registration (a more involved Gradle change). v0.2 might gate this behind `--experimental` even after the rest of bare RN is `beta`.
73
-
74
- ---
75
-
76
- ## Wizard-side plumbing already in place
77
-
78
- These already exist and don't need re-work:
79
-
80
- - The `react-native` integration object refuses cleanly with a clear `UnsupportedFrameworkError` and pointer to manual docs.
81
- - The `IntegrationManifest` has `wire-native-ios` / `wire-native-android` capabilities to declare in v0.2.
82
- - `Transaction` + `SnapshotStore` already handle the JS-side patches transactionally.
83
-
84
- ---
85
-
86
- ## Recommended ticket breakdown
87
-
88
- 1. **RN-1** Add `fixtures/react-native-bare/` with a minimal RN 0.74 + 0.75 + 0.76 project. CI runner with Xcode + Android emu (use macOS GitHub-hosted runner for iOS, Ubuntu + Android emulator for Android).
89
- 2. **RN-2** Implement `src/integrations/react-native-bare/` (renamed from current placeholder) with `manifest`/`detect`/`patch`/`uninstall`/`doctor`. Reuse `_shared.ts` and `_scaffold.ts`.
90
- 3. **RN-3** Native patchers: `src/patchers/podfile.ts`, `src/patchers/gradle.ts`, `src/patchers/appdelegate.ts`. Each writes through `Transaction` with a parser-based syntax check.
91
- 4. **RN-4** End-to-end `pod install` + `gradle assembleDebug` smoke in CI gated to RN-2.
92
- 5. **RN-5** Hermes source-map upload roundtrip — depends on the source-maps E2E spec landing first.