opkg 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/README.md +109 -186
  2. package/assets/openpackage_ascii_dark.png +0 -0
  3. package/assets/openpackage_ascii_light.png +0 -0
  4. package/dist/commands/add.js +34 -10
  5. package/dist/commands/add.js.map +1 -1
  6. package/dist/commands/apply.js +16 -0
  7. package/dist/commands/apply.js.map +1 -0
  8. package/dist/commands/delete.js +1 -1
  9. package/dist/commands/delete.js.map +1 -1
  10. package/dist/commands/install.js +177 -8
  11. package/dist/commands/install.js.map +1 -1
  12. package/dist/commands/list.js +2 -2
  13. package/dist/commands/list.js.map +1 -1
  14. package/dist/commands/login.js +1 -1
  15. package/dist/commands/login.js.map +1 -1
  16. package/dist/commands/logout.js +1 -1
  17. package/dist/commands/logout.js.map +1 -1
  18. package/dist/commands/new.js +125 -0
  19. package/dist/commands/new.js.map +1 -0
  20. package/dist/commands/pack.js +7 -13
  21. package/dist/commands/pack.js.map +1 -1
  22. package/dist/commands/pull.js +1 -1
  23. package/dist/commands/pull.js.map +1 -1
  24. package/dist/commands/push.js +1 -1
  25. package/dist/commands/push.js.map +1 -1
  26. package/dist/commands/remove.js +63 -0
  27. package/dist/commands/remove.js.map +1 -0
  28. package/dist/commands/save.js +11 -17
  29. package/dist/commands/save.js.map +1 -1
  30. package/dist/commands/set.js +33 -0
  31. package/dist/commands/set.js.map +1 -0
  32. package/dist/commands/show.js +16 -94
  33. package/dist/commands/show.js.map +1 -1
  34. package/dist/commands/status.js +26 -701
  35. package/dist/commands/status.js.map +1 -1
  36. package/dist/commands/uninstall.js +14 -427
  37. package/dist/commands/uninstall.js.map +1 -1
  38. package/dist/constants/index.js +72 -16
  39. package/dist/constants/index.js.map +1 -1
  40. package/dist/core/add/add-conflict-handler.js +1 -8
  41. package/dist/core/add/add-conflict-handler.js.map +1 -1
  42. package/dist/core/add/add-pipeline.js +12 -10
  43. package/dist/core/add/add-pipeline.js.map +1 -1
  44. package/dist/core/add/add-to-source-pipeline.js +123 -0
  45. package/dist/core/add/add-to-source-pipeline.js.map +1 -0
  46. package/dist/core/add/package-index-updater.js +77 -78
  47. package/dist/core/add/package-index-updater.js.map +1 -1
  48. package/dist/core/add/platform-path-transformer.js +6 -4
  49. package/dist/core/add/platform-path-transformer.js.map +1 -1
  50. package/dist/core/add/source-collector.js +2 -3
  51. package/dist/core/add/source-collector.js.map +1 -1
  52. package/dist/core/apply/apply-pipeline.js +110 -0
  53. package/dist/core/apply/apply-pipeline.js.map +1 -0
  54. package/dist/core/dependency-resolver.js +263 -21
  55. package/dist/core/dependency-resolver.js.map +1 -1
  56. package/dist/core/discovery/file-discovery.js +1 -2
  57. package/dist/core/discovery/file-discovery.js.map +1 -1
  58. package/dist/core/discovery/platform-files-discovery.js +33 -18
  59. package/dist/core/discovery/platform-files-discovery.js.map +1 -1
  60. package/dist/core/flows/flow-executor.js +974 -0
  61. package/dist/core/flows/flow-executor.js.map +1 -0
  62. package/dist/core/flows/flow-inverter.js +442 -0
  63. package/dist/core/flows/flow-inverter.js.map +1 -0
  64. package/dist/core/flows/flow-key-extractor.js +101 -0
  65. package/dist/core/flows/flow-key-extractor.js.map +1 -0
  66. package/dist/core/flows/flow-key-mapper.js +382 -0
  67. package/dist/core/flows/flow-key-mapper.js.map +1 -0
  68. package/dist/core/flows/flow-transforms.js +632 -0
  69. package/dist/core/flows/flow-transforms.js.map +1 -0
  70. package/dist/core/flows/map-pipeline/context.js +73 -0
  71. package/dist/core/flows/map-pipeline/context.js.map +1 -0
  72. package/dist/core/flows/map-pipeline/index.js +156 -0
  73. package/dist/core/flows/map-pipeline/index.js.map +1 -0
  74. package/dist/core/flows/map-pipeline/operations/copy.js +104 -0
  75. package/dist/core/flows/map-pipeline/operations/copy.js.map +1 -0
  76. package/dist/core/flows/map-pipeline/operations/pipe.js +70 -0
  77. package/dist/core/flows/map-pipeline/operations/pipe.js.map +1 -0
  78. package/dist/core/flows/map-pipeline/operations/rename.js +102 -0
  79. package/dist/core/flows/map-pipeline/operations/rename.js.map +1 -0
  80. package/dist/core/flows/map-pipeline/operations/set.js +50 -0
  81. package/dist/core/flows/map-pipeline/operations/set.js.map +1 -0
  82. package/dist/core/flows/map-pipeline/operations/switch.js +79 -0
  83. package/dist/core/flows/map-pipeline/operations/switch.js.map +1 -0
  84. package/dist/core/flows/map-pipeline/operations/transform.js +543 -0
  85. package/dist/core/flows/map-pipeline/operations/transform.js.map +1 -0
  86. package/dist/core/flows/map-pipeline/operations/unset.js +65 -0
  87. package/dist/core/flows/map-pipeline/operations/unset.js.map +1 -0
  88. package/dist/core/flows/map-pipeline/types.js +8 -0
  89. package/dist/core/flows/map-pipeline/types.js.map +1 -0
  90. package/dist/core/flows/map-pipeline/utils.js +278 -0
  91. package/dist/core/flows/map-pipeline/utils.js.map +1 -0
  92. package/dist/core/flows/platform-converter.js +328 -0
  93. package/dist/core/flows/platform-converter.js.map +1 -0
  94. package/dist/core/flows/source-resolver.js +192 -0
  95. package/dist/core/flows/source-resolver.js.map +1 -0
  96. package/dist/core/flows/toml-domain-transforms.js +23 -0
  97. package/dist/core/flows/toml-domain-transforms.js.map +1 -0
  98. package/dist/core/install/bulk-install-pipeline.js +68 -7
  99. package/dist/core/install/bulk-install-pipeline.js.map +1 -1
  100. package/dist/core/install/canonical-plan.js +3 -3
  101. package/dist/core/install/canonical-plan.js.map +1 -1
  102. package/dist/core/install/dry-run.js +3 -3
  103. package/dist/core/install/dry-run.js.map +1 -1
  104. package/dist/core/install/flow-based-installer.js +1158 -0
  105. package/dist/core/install/flow-based-installer.js.map +1 -0
  106. package/dist/core/install/flow-workspace-tracker.js +111 -0
  107. package/dist/core/install/flow-workspace-tracker.js.map +1 -0
  108. package/dist/core/install/format-detector.js +228 -0
  109. package/dist/core/install/format-detector.js.map +1 -0
  110. package/dist/core/install/git-package-loader.js +20 -0
  111. package/dist/core/install/git-package-loader.js.map +1 -0
  112. package/dist/core/install/install-errors.js +1 -1
  113. package/dist/core/install/install-errors.js.map +1 -1
  114. package/dist/core/install/install-flow.js +34 -14
  115. package/dist/core/install/install-flow.js.map +1 -1
  116. package/dist/core/install/install-pipeline.js +52 -17
  117. package/dist/core/install/install-pipeline.js.map +1 -1
  118. package/dist/core/install/install-reporting.js +26 -8
  119. package/dist/core/install/install-reporting.js.map +1 -1
  120. package/dist/core/install/local-source-resolution.js +103 -0
  121. package/dist/core/install/local-source-resolution.js.map +1 -0
  122. package/dist/core/install/marketplace-handler.js +221 -0
  123. package/dist/core/install/marketplace-handler.js.map +1 -0
  124. package/dist/core/install/path-install-pipeline.js +241 -0
  125. package/dist/core/install/path-install-pipeline.js.map +1 -0
  126. package/dist/core/install/path-package-loader.js +116 -0
  127. package/dist/core/install/path-package-loader.js.map +1 -0
  128. package/dist/core/install/plugin-detector.js +72 -0
  129. package/dist/core/install/plugin-detector.js.map +1 -0
  130. package/dist/core/install/plugin-to-universal-converter.js +218 -0
  131. package/dist/core/install/plugin-to-universal-converter.js.map +1 -0
  132. package/dist/core/install/plugin-transformer.js +191 -0
  133. package/dist/core/install/plugin-transformer.js.map +1 -0
  134. package/dist/core/install/version-selection.js +1 -1
  135. package/dist/core/install/version-selection.js.map +1 -1
  136. package/dist/core/openpackage.js +40 -22
  137. package/dist/core/openpackage.js.map +1 -1
  138. package/dist/core/pack/pack-output.js +62 -0
  139. package/dist/core/pack/pack-output.js.map +1 -0
  140. package/dist/core/pack/pack-pipeline.js +186 -0
  141. package/dist/core/pack/pack-pipeline.js.map +1 -0
  142. package/dist/core/package-context.js +45 -70
  143. package/dist/core/package-context.js.map +1 -1
  144. package/dist/core/package-creation.js +203 -0
  145. package/dist/core/package-creation.js.map +1 -0
  146. package/dist/core/package.js +20 -6
  147. package/dist/core/package.js.map +1 -1
  148. package/dist/core/platforms.js +665 -209
  149. package/dist/core/platforms.js.map +1 -1
  150. package/dist/core/push/push-context.js +1 -1
  151. package/dist/core/push/push-context.js.map +1 -1
  152. package/dist/core/push/push-upload.js +2 -2
  153. package/dist/core/push/push-upload.js.map +1 -1
  154. package/dist/core/registry.js +6 -6
  155. package/dist/core/registry.js.map +1 -1
  156. package/dist/core/remote-pull.js +2 -2
  157. package/dist/core/remote-pull.js.map +1 -1
  158. package/dist/core/remove/removal-collector.js +52 -0
  159. package/dist/core/remove/removal-collector.js.map +1 -0
  160. package/dist/core/remove/removal-confirmation.js +39 -0
  161. package/dist/core/remove/removal-confirmation.js.map +1 -0
  162. package/dist/core/remove/remove-from-source-pipeline.js +173 -0
  163. package/dist/core/remove/remove-from-source-pipeline.js.map +1 -0
  164. package/dist/core/save/constants.js +3 -3
  165. package/dist/core/save/constants.js.map +1 -1
  166. package/dist/core/save/flow-based-saver.js +270 -0
  167. package/dist/core/save/flow-based-saver.js.map +1 -0
  168. package/dist/core/save/name-resolution.js +1 -1
  169. package/dist/core/save/name-resolution.js.map +1 -1
  170. package/dist/core/save/package-yml-generator.js +4 -5
  171. package/dist/core/save/package-yml-generator.js.map +1 -1
  172. package/dist/core/save/save-candidate-builder.js +215 -0
  173. package/dist/core/save/save-candidate-builder.js.map +1 -0
  174. package/dist/core/save/save-candidate-loader.js +12 -11
  175. package/dist/core/save/save-candidate-loader.js.map +1 -1
  176. package/dist/core/save/save-conflict-analyzer.js +150 -0
  177. package/dist/core/save/save-conflict-analyzer.js.map +1 -0
  178. package/dist/core/save/save-conflict-resolution.js +28 -14
  179. package/dist/core/save/save-conflict-resolution.js.map +1 -1
  180. package/dist/core/save/save-conflict-resolver.js +31 -275
  181. package/dist/core/save/save-conflict-resolver.js.map +1 -1
  182. package/dist/core/save/save-group-builder.js +52 -0
  183. package/dist/core/save/save-group-builder.js.map +1 -0
  184. package/dist/core/save/save-interactive-resolver.js +190 -0
  185. package/dist/core/save/save-interactive-resolver.js.map +1 -0
  186. package/dist/core/save/save-pipeline.js +58 -34
  187. package/dist/core/save/save-pipeline.js.map +1 -1
  188. package/dist/core/save/save-platform-handler.js +53 -0
  189. package/dist/core/save/save-platform-handler.js.map +1 -0
  190. package/dist/core/save/save-resolution-executor.js +145 -0
  191. package/dist/core/save/save-resolution-executor.js.map +1 -0
  192. package/dist/core/save/save-result-reporter.js +167 -0
  193. package/dist/core/save/save-result-reporter.js.map +1 -0
  194. package/dist/core/save/save-to-source-pipeline.js +154 -0
  195. package/dist/core/save/save-to-source-pipeline.js.map +1 -0
  196. package/dist/core/save/save-versioning.js +4 -4
  197. package/dist/core/save/save-versioning.js.map +1 -1
  198. package/dist/core/save/save-write-coordinator.js +204 -0
  199. package/dist/core/save/save-write-coordinator.js.map +1 -0
  200. package/dist/core/save/save-yml-resolution.js +28 -216
  201. package/dist/core/save/save-yml-resolution.js.map +1 -1
  202. package/dist/core/save/workspace-rename.js +7 -8
  203. package/dist/core/save/workspace-rename.js.map +1 -1
  204. package/dist/core/set/set-output.js +72 -0
  205. package/dist/core/set/set-output.js.map +1 -0
  206. package/dist/core/set/set-pipeline.js +361 -0
  207. package/dist/core/set/set-pipeline.js.map +1 -0
  208. package/dist/core/set/set-types.js +5 -0
  209. package/dist/core/set/set-types.js.map +1 -0
  210. package/dist/core/show/package-resolver.js +257 -0
  211. package/dist/core/show/package-resolver.js.map +1 -0
  212. package/dist/core/show/scope-discovery.js +165 -0
  213. package/dist/core/show/scope-discovery.js.map +1 -0
  214. package/dist/core/show/show-output.js +168 -0
  215. package/dist/core/show/show-output.js.map +1 -0
  216. package/dist/core/show/show-pipeline.js +113 -0
  217. package/dist/core/show/show-pipeline.js.map +1 -0
  218. package/dist/core/show/show-types.js +5 -0
  219. package/dist/core/show/show-types.js.map +1 -0
  220. package/dist/core/source-resolution/dependency-graph.js +104 -0
  221. package/dist/core/source-resolution/dependency-graph.js.map +1 -0
  222. package/dist/core/source-resolution/resolve-mutable-source.js +109 -0
  223. package/dist/core/source-resolution/resolve-mutable-source.js.map +1 -0
  224. package/dist/core/source-resolution/resolve-package-source.js +29 -0
  225. package/dist/core/source-resolution/resolve-package-source.js.map +1 -0
  226. package/dist/core/source-resolution/resolve-registry-version.js +35 -0
  227. package/dist/core/source-resolution/resolve-registry-version.js.map +1 -0
  228. package/dist/core/source-resolution/types.js.map +1 -0
  229. package/dist/core/status/status-file-discovery.js +23 -12
  230. package/dist/core/status/status-file-discovery.js.map +1 -1
  231. package/dist/core/status/status-pipeline.js +134 -0
  232. package/dist/core/status/status-pipeline.js.map +1 -0
  233. package/dist/core/sync/platform-sync-summary.js +27 -0
  234. package/dist/core/sync/platform-sync-summary.js.map +1 -0
  235. package/dist/core/uninstall/flow-aware-uninstaller.js +189 -0
  236. package/dist/core/uninstall/flow-aware-uninstaller.js.map +1 -0
  237. package/dist/core/uninstall/uninstall-file-discovery.js +11 -6
  238. package/dist/core/uninstall/uninstall-file-discovery.js.map +1 -1
  239. package/dist/core/uninstall/uninstall-pipeline.js +141 -0
  240. package/dist/core/uninstall/uninstall-pipeline.js.map +1 -0
  241. package/dist/core/universal-patterns.js +64 -0
  242. package/dist/core/universal-patterns.js.map +1 -0
  243. package/dist/index.js +99 -6
  244. package/dist/index.js.map +1 -1
  245. package/dist/types/flows.js +8 -0
  246. package/dist/types/flows.js.map +1 -0
  247. package/dist/types/index.js +3 -0
  248. package/dist/types/index.js.map +1 -1
  249. package/dist/types/platform-flows.js +8 -0
  250. package/dist/types/platform-flows.js.map +1 -0
  251. package/dist/types/workspace-index.js +6 -0
  252. package/dist/types/workspace-index.js.map +1 -0
  253. package/dist/utils/custom-path-resolution.js +160 -0
  254. package/dist/utils/custom-path-resolution.js.map +1 -0
  255. package/dist/utils/dependency-coverage.js +1 -1
  256. package/dist/utils/dependency-coverage.js.map +1 -1
  257. package/dist/utils/file-processing.js +1 -1
  258. package/dist/utils/flow-index-installer.js +209 -0
  259. package/dist/utils/flow-index-installer.js.map +1 -0
  260. package/dist/utils/formatters.js +47 -1
  261. package/dist/utils/formatters.js.map +1 -1
  262. package/dist/utils/fs.js +17 -0
  263. package/dist/utils/fs.js.map +1 -1
  264. package/dist/utils/git-clone-registry.js +88 -0
  265. package/dist/utils/git-clone-registry.js.map +1 -0
  266. package/dist/utils/git-clone.js +69 -0
  267. package/dist/utils/git-clone.js.map +1 -0
  268. package/dist/utils/git-spec.js +96 -0
  269. package/dist/utils/git-spec.js.map +1 -0
  270. package/dist/utils/http-client.js +7 -0
  271. package/dist/utils/http-client.js.map +1 -1
  272. package/dist/utils/index-based-installer.js +356 -163
  273. package/dist/utils/index-based-installer.js.map +1 -1
  274. package/dist/utils/install-conflict-handler.js +2 -2
  275. package/dist/utils/install-conflict-handler.js.map +1 -1
  276. package/dist/utils/install-file-discovery.js +18 -13
  277. package/dist/utils/install-file-discovery.js.map +1 -1
  278. package/dist/utils/install-helpers.js +43 -20
  279. package/dist/utils/install-helpers.js.map +1 -1
  280. package/dist/utils/jsonc.js +23 -1
  281. package/dist/utils/jsonc.js.map +1 -1
  282. package/dist/utils/manifest-paths.js +1 -1
  283. package/dist/utils/manifest-paths.js.map +1 -1
  284. package/dist/utils/markdown-frontmatter.js +46 -0
  285. package/dist/utils/markdown-frontmatter.js.map +1 -1
  286. package/dist/utils/package-copy.js +5 -103
  287. package/dist/utils/package-copy.js.map +1 -1
  288. package/dist/utils/package-filters.js +9 -105
  289. package/dist/utils/package-filters.js.map +1 -1
  290. package/dist/utils/package-index-yml.js +27 -6
  291. package/dist/utils/package-index-yml.js.map +1 -1
  292. package/dist/utils/package-input.js +98 -0
  293. package/dist/utils/package-input.js.map +1 -0
  294. package/dist/utils/package-management.js +80 -28
  295. package/dist/utils/package-management.js.map +1 -1
  296. package/dist/utils/package-name-resolution.js +327 -0
  297. package/dist/utils/package-name-resolution.js.map +1 -0
  298. package/dist/utils/package-name.js +18 -16
  299. package/dist/utils/package-name.js.map +1 -1
  300. package/dist/utils/package-versioning.js +2 -33
  301. package/dist/utils/package-versioning.js.map +1 -1
  302. package/dist/utils/package-yml.js +19 -28
  303. package/dist/utils/package-yml.js.map +1 -1
  304. package/dist/utils/path-resolution.js +102 -0
  305. package/dist/utils/path-resolution.js.map +1 -0
  306. package/dist/utils/paths.js +6 -6
  307. package/dist/utils/paths.js.map +1 -1
  308. package/dist/utils/platform-file.js +36 -24
  309. package/dist/utils/platform-file.js.map +1 -1
  310. package/dist/utils/platform-mapper.js +222 -68
  311. package/dist/utils/platform-mapper.js.map +1 -1
  312. package/dist/utils/platform-root-files.js +44 -0
  313. package/dist/utils/platform-root-files.js.map +1 -0
  314. package/dist/utils/platform-utils.js +35 -54
  315. package/dist/utils/platform-utils.js.map +1 -1
  316. package/dist/utils/platform-yaml-merge.js +20 -140
  317. package/dist/utils/platform-yaml-merge.js.map +1 -1
  318. package/dist/utils/prompts.js +92 -7
  319. package/dist/utils/prompts.js.map +1 -1
  320. package/dist/utils/registry-entry-filter.js +50 -27
  321. package/dist/utils/registry-entry-filter.js.map +1 -1
  322. package/dist/utils/registry-paths.js +5 -4
  323. package/dist/utils/registry-paths.js.map +1 -1
  324. package/dist/utils/scope-resolution.js +156 -0
  325. package/dist/utils/scope-resolution.js.map +1 -0
  326. package/dist/utils/source-mutability.js +15 -0
  327. package/dist/utils/source-mutability.js.map +1 -0
  328. package/dist/utils/tarball.js +29 -4
  329. package/dist/utils/tarball.js.map +1 -1
  330. package/dist/utils/version-ranges.js +1 -32
  331. package/dist/utils/version-ranges.js.map +1 -1
  332. package/dist/utils/workspace-index-helpers.js +28 -0
  333. package/dist/utils/workspace-index-helpers.js.map +1 -0
  334. package/dist/utils/workspace-index-ownership.js +100 -0
  335. package/dist/utils/workspace-index-ownership.js.map +1 -0
  336. package/dist/utils/workspace-index-yml.js +173 -0
  337. package/dist/utils/workspace-index-yml.js.map +1 -0
  338. package/examples/custom-subdirs-platform.jsonc +157 -0
  339. package/package.json +7 -2
  340. package/platforms.jsonc +531 -84
  341. package/schemas/map-pipeline-v1.json +256 -0
  342. package/schemas/platforms-v1.json +400 -0
  343. package/specs/README.md +88 -0
  344. package/specs/add/README.md +166 -0
  345. package/specs/agents-claude.md +570 -0
  346. package/specs/agents-opencode.md +622 -0
  347. package/specs/apply/README.md +21 -0
  348. package/specs/apply/apply-behavior.md +58 -0
  349. package/specs/apply/apply-command.md +51 -0
  350. package/specs/apply/conflicts.md +41 -0
  351. package/specs/apply/index-effects.md +81 -0
  352. package/specs/architecture.md +107 -0
  353. package/specs/auth/README.md +17 -0
  354. package/specs/auth/auth-http-contract.md +25 -0
  355. package/specs/auth/cli/credentials.md +39 -0
  356. package/specs/auth/cli/login.md +32 -0
  357. package/specs/auth/cli/logout.md +16 -0
  358. package/specs/claude-mcp.md +1065 -0
  359. package/specs/claude-plugins-marketplace.md +363 -0
  360. package/specs/claude-plugins.md +413 -0
  361. package/specs/cli-options.md +52 -0
  362. package/specs/codex-mcp.md +114 -0
  363. package/specs/commands-overview.md +175 -0
  364. package/specs/directory-layout.md +95 -0
  365. package/specs/install/README.md +12 -4
  366. package/specs/install/git-sources.md +230 -0
  367. package/specs/install/install-behavior.md +483 -73
  368. package/specs/install/package-yml-canonical.md +67 -35
  369. package/specs/install/version-resolution.md +69 -115
  370. package/specs/new/README.md +769 -0
  371. package/specs/new/SUMMARY.md +310 -0
  372. package/specs/new/scope-behavior.md +793 -0
  373. package/specs/pack/README.md +77 -0
  374. package/specs/pack/package-name-resolution.md +330 -0
  375. package/specs/package/README.md +18 -17
  376. package/specs/package/nested-packages-and-parent-packages.md +32 -31
  377. package/specs/package/package-index-yml.md +95 -101
  378. package/specs/package/package-root-layout.md +64 -46
  379. package/specs/package/registry-payload-and-copy.md +50 -44
  380. package/specs/package/universal-content.md +33 -56
  381. package/specs/package-sources.md +248 -0
  382. package/specs/platforms/README.md +52 -0
  383. package/specs/platforms/configuration.md +571 -0
  384. package/specs/platforms/detection.md +552 -0
  385. package/specs/platforms/directory-layout.md +599 -0
  386. package/specs/platforms/examples.md +1146 -0
  387. package/specs/platforms/flow-reference.md +1240 -0
  388. package/specs/platforms/flows.md +1488 -0
  389. package/specs/platforms/map-pipeline.md +801 -0
  390. package/specs/platforms/overview.md +349 -0
  391. package/specs/platforms/specification.md +700 -0
  392. package/specs/platforms/troubleshooting.md +697 -0
  393. package/specs/platforms/universal-converter.md +520 -0
  394. package/specs/push/README.md +1 -0
  395. package/specs/push/push-behavior.md +11 -3
  396. package/specs/push/push-remote-upload.md +1 -1
  397. package/specs/push/push-scoping.md +1 -1
  398. package/specs/push/push-version-selection.md +1 -1
  399. package/specs/registry.md +111 -0
  400. package/specs/remove/README.md +257 -0
  401. package/specs/save/README.md +21 -17
  402. package/specs/save/save-conflict-resolution.md +205 -83
  403. package/specs/save/save-file-discovery.md +6 -4
  404. package/specs/save/save-frontmatter-overrides.md +11 -15
  405. package/specs/save/save-modes-inputs.md +9 -39
  406. package/specs/save/save-naming-scoping.md +4 -4
  407. package/specs/save/save-package-detection.md +13 -13
  408. package/specs/save/save-registry-sync.md +16 -106
  409. package/specs/save/save-versioning.md +80 -0
  410. package/specs/scope-management.md +92 -0
  411. package/specs/set/README.md +520 -0
  412. package/specs/set/set-behavior.md +563 -0
  413. package/specs/show/README.md +483 -0
  414. package/specs/show/show-remote.md +494 -0
  415. package/specs/status/README.md +38 -0
  416. package/specs/uninstall/README.md +231 -0
  417. package/dist/commands/duplicate.js +0 -69
  418. package/dist/commands/duplicate.js.map +0 -1
  419. package/dist/commands/init.js +0 -117
  420. package/dist/commands/init.js.map +0 -1
  421. package/dist/commands/prune.js +0 -357
  422. package/dist/commands/prune.js.map +0 -1
  423. package/dist/commands/tui.js +0 -61
  424. package/dist/commands/tui.js.map +0 -1
  425. package/dist/core/install/index.js +0 -3
  426. package/dist/core/install/index.js.map +0 -1
  427. package/dist/core/push/push-single-file.js +0 -56
  428. package/dist/core/push/push-single-file.js.map +0 -1
  429. package/dist/core/save/package-detection.js +0 -147
  430. package/dist/core/save/package-detection.js.map +0 -1
  431. package/dist/core/save/save-single-file.js +0 -124
  432. package/dist/core/save/save-single-file.js.map +0 -1
  433. package/dist/core/token-store.js +0 -73
  434. package/dist/core/token-store.js.map +0 -1
  435. package/dist/tui/app.js +0 -95
  436. package/dist/tui/app.js.map +0 -1
  437. package/dist/tui/components/package-list.js +0 -73
  438. package/dist/tui/components/package-list.js.map +0 -1
  439. package/dist/tui/controller.js +0 -365
  440. package/dist/tui/controller.js.map +0 -1
  441. package/dist/tui/index.js +0 -12
  442. package/dist/tui/index.js.map +0 -1
  443. package/dist/tui/services/file-index.js +0 -64
  444. package/dist/tui/services/file-index.js.map +0 -1
  445. package/dist/tui/services/packages.js +0 -18
  446. package/dist/tui/services/packages.js.map +0 -1
  447. package/dist/tui/services/save.js +0 -21
  448. package/dist/tui/services/save.js.map +0 -1
  449. package/dist/tui/state/app-state.js +0 -15
  450. package/dist/tui/state/app-state.js.map +0 -1
  451. package/dist/tui/state.js +0 -17
  452. package/dist/tui/state.js.map +0 -1
  453. package/dist/tui/types.js.map +0 -1
  454. package/dist/tui/views/add-file-modal.js +0 -129
  455. package/dist/tui/views/add-file-modal.js.map +0 -1
  456. package/dist/tui/views/file-preview.js +0 -44
  457. package/dist/tui/views/file-preview.js.map +0 -1
  458. package/dist/tui/views/list-packages.js +0 -73
  459. package/dist/tui/views/list-packages.js.map +0 -1
  460. package/dist/tui/views/main-menu.js +0 -29
  461. package/dist/tui/views/main-menu.js.map +0 -1
  462. package/dist/tui/views/manage-view.js +0 -81
  463. package/dist/tui/views/manage-view.js.map +0 -1
  464. package/dist/tui/views/package-hub.js +0 -120
  465. package/dist/tui/views/package-hub.js.map +0 -1
  466. package/dist/tui/views/placeholder.js +0 -24
  467. package/dist/tui/views/placeholder.js.map +0 -1
  468. package/dist/utils/bun-bootstrap.js +0 -72
  469. package/dist/utils/bun-bootstrap.js.map +0 -1
  470. package/dist/utils/entity-id.js +0 -19
  471. package/dist/utils/entity-id.js.map +0 -1
  472. package/dist/utils/package-local-files.js +0 -5
  473. package/dist/utils/package-local-files.js.map +0 -1
  474. package/dist/utils/path-matching.js +0 -74
  475. package/dist/utils/path-matching.js.map +0 -1
  476. package/dist/utils/root-file-operations.js +0 -39
  477. package/dist/utils/root-file-operations.js.map +0 -1
  478. package/dist/utils/root-file-transformer.js +0 -27
  479. package/dist/utils/root-file-transformer.js.map +0 -1
  480. package/dist/utils/yaml-frontmatter.js +0 -25
  481. package/dist/utils/yaml-frontmatter.js.map +0 -1
  482. package/specs/auth/auth-device-flow.md +0 -70
  483. package/specs/login/login-device-flow.md +0 -70
  484. package/specs/platforms.md +0 -193
  485. package/specs/save-pack-versioning.md +0 -224
  486. package/specs/save-pack.md +0 -68
  487. /package/dist/{tui → core/source-resolution}/types.js +0 -0
@@ -0,0 +1,1488 @@
1
+ # Platform Flows
2
+
3
+ ## What are Flows?
4
+
5
+ **Flows** are declarative transformation rules that define bidirectional mappings between universal package content and platform-specific formats.
6
+
7
+ **Two types of flows:**
8
+ - **Export flows** (`export`): Package → Workspace (used by `install` and `apply`)
9
+ - **Import flows** (`import`): Workspace → Package (used by `save`)
10
+
11
+ **Core concept:** Explicit bidirectional transformations without automatic inversion.
12
+
13
+ ## Flow Types
14
+
15
+ ### Export Flows
16
+
17
+ Transform package files into workspace files (Package → Workspace).
18
+
19
+ **Used by:** `opkg install`, `opkg apply`
20
+
21
+ **Schema:**
22
+ ```typescript
23
+ interface ExportFlow {
24
+ from: string | string[] // Source pattern in package (required)
25
+ to: string | MultiTarget // Target path in workspace (required)
26
+
27
+ // Optional transformation fields
28
+ map?: Operation[] // Map pipeline operations (includes $pipe for transforms)
29
+ pick?: string[] // Extract specific keys
30
+ omit?: string[] // Exclude keys
31
+ path?: string // JSONPath extraction
32
+ embed?: string // Embed under key
33
+ section?: string // TOML/INI section
34
+ when?: Condition // Conditional execution
35
+ merge?: "deep"|"shallow"|"replace"|"composite" // Merge strategy
36
+ namespace?: boolean | string // Namespace isolation
37
+ handler?: string // Custom handler
38
+ }
39
+ ```
40
+
41
+ ### Import Flows
42
+
43
+ Transform workspace files back into package files (Workspace → Package).
44
+
45
+ **Used by:** `opkg save`
46
+
47
+ **Schema:**
48
+ ```typescript
49
+ interface ImportFlow {
50
+ from: string | string[] // Source pattern in workspace (required)
51
+ to: string | MultiTarget // Target path in package (required)
52
+
53
+ // Optional transformation fields (same as export)
54
+ map?: Operation[] // Map pipeline operations (includes $pipe for transforms)
55
+ pick?: string[]
56
+ omit?: string[]
57
+ path?: string
58
+ embed?: string
59
+ section?: string
60
+ when?: Condition
61
+ merge?: "deep"|"shallow"|"replace"|"composite"
62
+ namespace?: boolean | string
63
+ handler?: string
64
+ }
65
+ ```
66
+
67
+ **Key difference:** Import flows only process files tracked in the workspace index (files previously exported).
68
+
69
+ ### Required Fields
70
+
71
+ #### `from` (string)
72
+
73
+ Source file pattern relative to package root.
74
+
75
+ **Simple path:**
76
+ ```jsonc
77
+ { "from": "rules/code-quality.md" }
78
+ ```
79
+
80
+ **Single-level glob:**
81
+ ```jsonc
82
+ { "from": "rules/*.md" } // All .md files in rules/ only (not subdirs)
83
+ ```
84
+
85
+ **Recursive glob:**
86
+ ```jsonc
87
+ { "from": "rules/**/*.md" } // All .md files in rules/ and subdirectories
88
+ { "from": "skills/**/*" } // All files of any type, recursively
89
+ ```
90
+
91
+ **Examples:**
92
+ ```jsonc
93
+ { "from": "config.yaml" } // Single file
94
+ { "from": "rules/*.md" } // Top-level only
95
+ { "from": "rules/**/*.md" } // Recursive with extension filter
96
+ { "from": "skills/**/*" } // All files recursively
97
+ ```
98
+
99
+ **Array with priority (first match wins):**
100
+ ```jsonc
101
+ { "from": ["mcp.jsonc", "mcp.json"] } // Prefer .jsonc, fallback to .json
102
+ ```
103
+
104
+ When an array of patterns is provided:
105
+ - Patterns are tried in order (first = highest priority)
106
+ - First matching pattern is used
107
+ - Subsequent patterns are skipped
108
+ - Warning logged if multiple patterns match
109
+ - Useful for format preferences or platform-specific fallbacks
110
+
111
+ **Array pattern use cases:**
112
+ ```jsonc
113
+ // Format preference
114
+ { "from": ["mcp.jsonc", "mcp.json"] }
115
+
116
+ // Platform-specific fallback
117
+ { "from": ["config.cursor.json", "config.json"] }
118
+
119
+ // Version fallback
120
+ { "from": ["config.v2.yaml", "config.yaml"] }
121
+ ```
122
+
123
+ #### `to` (string | object)
124
+
125
+ Target file path relative to workspace root.
126
+
127
+ **Simple target:**
128
+ ```jsonc
129
+ { "to": ".cursor/rules/*.mdc" } // Single-level glob with extension change
130
+ ```
131
+
132
+ **Recursive target:**
133
+ ```jsonc
134
+ { "to": ".cursor/rules/**/*.mdc" } // Preserves directory structure
135
+ ```
136
+
137
+ **Multi-target object:**
138
+ ```jsonc
139
+ {
140
+ "to": {
141
+ ".cursor/mcp.json": { "namespace": true, "merge": "deep" },
142
+ ".opencode/config.json": { "embed": "mcp", "merge": "deep" },
143
+ ".codex/config.toml": { "section": "mcp", "merge": "deep" }
144
+ }
145
+ }
146
+ ```
147
+
148
+ ## Glob Patterns
149
+
150
+ The flow system supports powerful glob patterns for file matching:
151
+
152
+ ### Single-Level Glob (`*`)
153
+
154
+ Matches files in a single directory level only:
155
+
156
+ ```jsonc
157
+ {
158
+ "from": "rules/*.md",
159
+ "to": ".cursor/rules/*.md"
160
+ }
161
+ ```
162
+
163
+ **Package structure:**
164
+ ```
165
+ rules/
166
+ ├── typescript.md ← Matched
167
+ ├── python.md ← Matched
168
+ └── advanced/
169
+ └── generics.md ← NOT matched (in subdirectory)
170
+ ```
171
+
172
+ **Result:**
173
+ ```
174
+ .cursor/rules/
175
+ ├── typescript.md
176
+ └── python.md
177
+ ```
178
+
179
+ ### Recursive Glob (`**`)
180
+
181
+ Matches files in all subdirectories recursively:
182
+
183
+ ```jsonc
184
+ {
185
+ "from": "rules/**/*.md",
186
+ "to": ".cursor/rules/**/*.md"
187
+ }
188
+ ```
189
+
190
+ **Package structure:**
191
+ ```
192
+ rules/
193
+ ├── typescript.md
194
+ ├── python.md
195
+ └── advanced/
196
+ ├── generics.md
197
+ └── types/
198
+ └── unions.md
199
+ ```
200
+
201
+ **Result (preserves structure):**
202
+ ```
203
+ .cursor/rules/
204
+ ├── typescript.md
205
+ ├── python.md
206
+ └── advanced/
207
+ ├── generics.md
208
+ └── types/
209
+ └── unions.md
210
+ ```
211
+
212
+ **Key features:**
213
+ - `**` means "any number of directories" (including zero)
214
+ - Directory structure is fully preserved in target
215
+ - Relative paths maintained
216
+
217
+ ### All Files Recursively (`**/*`)
218
+
219
+ Matches all files of any type:
220
+
221
+ ```jsonc
222
+ {
223
+ "from": "skills/**/*",
224
+ "to": ".claude/skills/**/*"
225
+ }
226
+ ```
227
+
228
+ **Package structure:**
229
+ ```
230
+ skills/
231
+ ├── code-review/
232
+ │ ├── analyze.md
233
+ │ ├── config.json
234
+ │ └── helpers/
235
+ │ ├── utils.ts
236
+ │ └── types.d.ts
237
+ └── testing/
238
+ └── test-gen.md
239
+ ```
240
+
241
+ **Result (all files copied):**
242
+ ```
243
+ .claude/skills/
244
+ ├── code-review/
245
+ │ ├── analyze.md
246
+ │ ├── config.json
247
+ │ └── helpers/
248
+ │ ├── utils.ts
249
+ │ └── types.d.ts
250
+ └── testing/
251
+ └── test-gen.md
252
+ ```
253
+
254
+ **Use cases:**
255
+ - Mixed file types (`.md`, `.json`, `.ts`, etc.)
256
+ - Complete directory replication
257
+ - Skills, tools, or utility directories
258
+
259
+ ### Extension Mapping with Recursive Globs
260
+
261
+ Change file extensions while preserving structure:
262
+
263
+ ```jsonc
264
+ {
265
+ "from": "rules/**/*.md",
266
+ "to": ".cursor/rules/**/*.mdc"
267
+ }
268
+ ```
269
+
270
+ **Package:**
271
+ ```
272
+ rules/
273
+ ├── typescript.md
274
+ └── advanced/
275
+ └── generics.md
276
+ ```
277
+
278
+ **Result:**
279
+ ```
280
+ .cursor/rules/
281
+ ├── typescript.mdc ← Extension changed
282
+ └── advanced/
283
+ └── generics.mdc ← Extension changed
284
+ ```
285
+
286
+ **Extension mapping rules:**
287
+ - Source extension specified: `/**/*.md`
288
+ - Target extension specified: `/**/*.mdc`
289
+ - All matched files get extension changed
290
+ - Works at any depth
291
+
292
+ ### Common Patterns
293
+
294
+ #### Pattern 1: Recursive Rules with Extension Mapping
295
+ ```jsonc
296
+ {
297
+ "from": "rules/**/*.md",
298
+ "to": ".cursor/rules/**/*.mdc"
299
+ }
300
+ ```
301
+ Use for: Cursor-style rules with nested structure
302
+
303
+ #### Pattern 2: Recursive Commands
304
+ ```jsonc
305
+ {
306
+ "from": "commands/**/*.md",
307
+ "to": ".agent/workflows/**/*.md"
308
+ }
309
+ ```
310
+ Use for: Commands organized in subdirectories
311
+
312
+ #### Pattern 3: Complete Skills Directory
313
+ ```jsonc
314
+ {
315
+ "from": "skills/**/*",
316
+ "to": ".claude/skills/**/*"
317
+ }
318
+ ```
319
+ Use for: Mixed file types with full structure
320
+
321
+ #### Pattern 4: Recursive Agents
322
+ ```jsonc
323
+ {
324
+ "from": "agents/**/*.md",
325
+ "to": ".factory/droids/**/*.md"
326
+ }
327
+ ```
328
+ Use for: Agent definitions with categories
329
+
330
+ ### Glob Matching Behavior
331
+
332
+ #### Empty Matches
333
+
334
+ If no files match the pattern:
335
+ - Flow succeeds with warning
336
+ - No error thrown
337
+ - Warning: "No files matched pattern"
338
+
339
+ ```jsonc
340
+ {
341
+ "from": "nonexistent/**/*.md",
342
+ "to": ".cursor/rules/**/*.md"
343
+ }
344
+ ```
345
+ **Result:** Success, 0 files processed, warning logged
346
+
347
+ #### Case Sensitivity
348
+
349
+ Glob patterns are case-sensitive:
350
+ - `Rules/*.md` ≠ `rules/*.md`
351
+ - `README.md` ≠ `readme.md`
352
+
353
+ #### Hidden Files
354
+
355
+ Glob patterns do NOT match hidden files by default:
356
+ - `.gitignore` not matched by `*`
357
+ - `.config/**/*` not matched by `**/*`
358
+
359
+ To match hidden files explicitly:
360
+ ```jsonc
361
+ { "from": ".config/**/*" }
362
+ ```
363
+
364
+ ### Best Practices
365
+
366
+ #### 1. Use `**` for Nested Structures
367
+
368
+ **Good:**
369
+ ```jsonc
370
+ { "from": "rules/**/*.md" }
371
+ ```
372
+
373
+ **Bad (misses nested files):**
374
+ ```jsonc
375
+ { "from": "rules/*.md" }
376
+ ```
377
+
378
+ #### 2. Match Target Pattern to Source
379
+
380
+ **Good (consistent structure):**
381
+ ```jsonc
382
+ {
383
+ "from": "rules/**/*.md",
384
+ "to": ".cursor/rules/**/*.md"
385
+ }
386
+ ```
387
+
388
+ **Bad (structure mismatch):**
389
+ ```jsonc
390
+ {
391
+ "from": "rules/**/*.md",
392
+ "to": ".cursor/rules/*.md" // Wrong: single-level target
393
+ }
394
+ ```
395
+
396
+ #### 3. Use `**/*` for Mixed Types
397
+
398
+ **Good (all files):**
399
+ ```jsonc
400
+ { "from": "skills/**/*" }
401
+ ```
402
+
403
+ **Bad (only markdown):**
404
+ ```jsonc
405
+ { "from": "skills/**/*.md" }
406
+ ```
407
+
408
+ #### 4. Prefer Recursive Patterns
409
+
410
+ Recommended approach:
411
+ ```jsonc
412
+ { "from": "rules/**/*.md" }
413
+ ```
414
+
415
+ ## Execution Pipeline
416
+
417
+ Flows execute through a multi-stage pipeline:
418
+
419
+ ```
420
+ 1. Load → Read source file, detect format
421
+ 2. Extract → Apply JSONPath if specified
422
+ 3. Filter → Apply pick/omit on keys
423
+ 4. Map → Transform keys/values (includes $pipe operations)
424
+ 5. Namespace → Wrap in namespace if enabled
425
+ 6. Embed → Wrap under key/section if specified
426
+ 7. Merge → Merge with existing target
427
+ 8. Write → Serialize and write to disk
428
+ ```
429
+
430
+ ### Stage 1: Load
431
+
432
+ **Auto-detects format** from extension or content:
433
+ - `.json`, `.jsonc` → JSON parser
434
+ - `.yaml`, `.yml` → YAML parser
435
+ - `.toml` → TOML parser
436
+ - `.md` → Markdown with frontmatter parser
437
+
438
+ **Example:**
439
+ ```yaml
440
+ # Source: config.yaml
441
+ theme: dark
442
+ fontSize: 14
443
+ ```
444
+
445
+ ### Stage 2: Extract (optional)
446
+
447
+ Apply **JSONPath** to extract subset:
448
+
449
+ ```jsonc
450
+ {
451
+ "from": "config.yaml",
452
+ "to": ".cursor/config.json",
453
+ "path": "$.editor" // Extract only editor config
454
+ }
455
+ ```
456
+
457
+ ```yaml
458
+ # Source
459
+ editor:
460
+ theme: dark
461
+ fontSize: 14
462
+ terminal:
463
+ shell: bash
464
+ ```
465
+
466
+ **Result after extraction:**
467
+ ```json
468
+ {
469
+ "theme": "dark",
470
+ "fontSize": 14
471
+ }
472
+ ```
473
+
474
+ ### Stage 3: Filter (optional)
475
+
476
+ **Pick** (whitelist) specific keys:
477
+ ```jsonc
478
+ {
479
+ "pick": ["theme", "fontSize"] // Only include these keys
480
+ }
481
+ ```
482
+
483
+ **Omit** (blacklist) specific keys:
484
+ ```jsonc
485
+ {
486
+ "omit": ["internal", "debug"] // Exclude these keys
487
+ }
488
+ ```
489
+
490
+ **Cannot use both** `pick` and `omit` in same flow.
491
+
492
+ ### Stage 4: Map (optional)
493
+
494
+ Transform document fields using a **MongoDB-inspired pipeline**:
495
+
496
+ ```jsonc
497
+ {
498
+ "map": [
499
+ { "$set": { "name": "$$filename" } },
500
+ { "$rename": { "mcp": "mcpServers" } },
501
+ { "$unset": "deprecated" }
502
+ ]
503
+ }
504
+ ```
505
+
506
+ **Map Pipeline** is an array of operations that execute sequentially on the document:
507
+
508
+ **Seven core operations:**
509
+ 1. **`$set`** - Set field values (supports context variables like `$$filename`)
510
+ 2. **`$rename`** - Rename fields (supports wildcards)
511
+ 3. **`$unset`** - Remove fields
512
+ 4. **`$switch`** - Pattern-based value replacement
513
+ 5. **`$pipeline`** - Multi-step field transformation (MongoDB-aligned)
514
+ 6. **`$copy`** - Copy field with optional transformation
515
+ 7. **`$pipe`** - Apply transform registry operations (format conversions, validations)
516
+
517
+ **Example transformation:**
518
+ ```jsonc
519
+ {
520
+ "map": [
521
+ { "$set": { "name": "$$filename" } },
522
+ {
523
+ "$switch": {
524
+ "field": "model",
525
+ "cases": [
526
+ { "pattern": "anthropic/claude-sonnet-*", "value": "sonnet" }
527
+ ],
528
+ "default": "inherit"
529
+ }
530
+ }
531
+ ]
532
+ }
533
+ ```
534
+
535
+ **Before:**
536
+ ```yaml
537
+ model: anthropic/claude-sonnet-4-20250514
538
+ ```
539
+
540
+ **After:**
541
+ ```yaml
542
+ name: code-reviewer
543
+ model: sonnet
544
+ ```
545
+
546
+ See [Map Pipeline](./map-pipeline.md) for complete operation reference and [Flow Reference](./flow-reference.md#map-pipeline) for usage in flows.
547
+
548
+ ### Stage 5: Transform (optional)
549
+
550
+ Apply **transform registry operations** using the `$pipe` operation within the map pipeline:
551
+
552
+ ```jsonc
553
+ {
554
+ "map": [
555
+ { "$rename": { "old": "new" } },
556
+ { "$pipe": ["json-to-toml"] } // Apply transforms from registry
557
+ ]
558
+ }
559
+ ```
560
+
561
+ **Available transforms:**
562
+ - Format converters: `jsonc`, `yaml`, `toml`, `json-to-toml`, `toml-to-json`, `xml`, `ini`
563
+ - Filtering: `filter-comments`, `filter-empty`, `filter-null`
564
+ - Markdown: `sections`, `frontmatter`, `body`
565
+ - Validation: `validate`, `validate-schema(path)`
566
+
567
+ See [Map Pipeline](./map-pipeline.md#7-pipe---apply-transform-registry-operations) for `$pipe` details and
568
+ [Flow Reference](./flow-reference.md#built-in-transforms) for all available transforms.
569
+
570
+ ### Stage 6: Namespace (optional)
571
+
572
+ Wrap content under package-specific namespace:
573
+
574
+ ```jsonc
575
+ {
576
+ "namespace": true // or string for custom namespace key
577
+ }
578
+ ```
579
+
580
+ **Before:**
581
+ ```json
582
+ { "servers": { "db": {} } }
583
+ ```
584
+
585
+ **After:**
586
+ ```json
587
+ {
588
+ "packages": {
589
+ "@user/package-name": {
590
+ "servers": { "db": {} }
591
+ }
592
+ }
593
+ }
594
+ ```
595
+
596
+ **Purpose:** Prevent collisions when multiple packages target same file.
597
+
598
+ ### Stage 7: Embed (optional)
599
+
600
+ Wrap content under specified key:
601
+
602
+ **JSON embedding:**
603
+ ```jsonc
604
+ {
605
+ "embed": "mcp"
606
+ }
607
+ ```
608
+
609
+ ```json
610
+ // Before: { "servers": {} }
611
+ // After: { "mcp": { "servers": {} } }
612
+ ```
613
+
614
+ **TOML sections:**
615
+ ```jsonc
616
+ {
617
+ "section": "mcp_servers"
618
+ }
619
+ ```
620
+
621
+ ```toml
622
+ # Before: [servers]
623
+ # After: [mcp_servers]
624
+ ```
625
+
626
+ ### Stage 8: Merge
627
+
628
+ Combine with existing target file:
629
+
630
+ **Strategies:**
631
+ - `"deep"` - Recursively merge nested objects (default for objects)
632
+ - `"shallow"` - Merge only top-level keys
633
+ - `"replace"` - Overwrite entire file (default for arrays/primitives)
634
+
635
+ ```jsonc
636
+ {
637
+ "merge": "deep"
638
+ }
639
+ ```
640
+
641
+ **Existing target:**
642
+ ```json
643
+ { "servers": { "db": {} } }
644
+ ```
645
+
646
+ **Source content:**
647
+ ```json
648
+ { "servers": { "api": {} } }
649
+ ```
650
+
651
+ **Result:**
652
+ ```json
653
+ {
654
+ "servers": {
655
+ "db": {}, // Preserved from target
656
+ "api": {} // Added from source
657
+ }
658
+ }
659
+ ```
660
+
661
+ ### Stage 9: Write
662
+
663
+ Serialize to target format and write to disk:
664
+ - Detects target format from extension
665
+ - Creates directories as needed
666
+ - Atomic write (temp file + rename)
667
+
668
+ ## Format Conversion
669
+
670
+ Automatic bidirectional conversion between formats:
671
+
672
+ ### YAML to JSON
673
+
674
+ ```jsonc
675
+ {
676
+ "from": "config.yaml",
677
+ "to": ".cursor/config.json"
678
+ }
679
+ ```
680
+
681
+ **Source (YAML):**
682
+ ```yaml
683
+ theme: dark
684
+ fontSize: 14
685
+ ```
686
+
687
+ **Target (JSON):**
688
+ ```json
689
+ {
690
+ "theme": "dark",
691
+ "fontSize": 14
692
+ }
693
+ ```
694
+
695
+ ### JSONC to JSON
696
+
697
+ ```jsonc
698
+ {
699
+ "from": "settings.jsonc",
700
+ "to": ".cursor/settings.json"
701
+ }
702
+ ```
703
+
704
+ Comments are automatically stripped:
705
+
706
+ **Source (JSONC):**
707
+ ```jsonc
708
+ {
709
+ // User theme
710
+ "theme": "dark"
711
+ }
712
+ ```
713
+
714
+ **Target (JSON):**
715
+ ```json
716
+ {
717
+ "theme": "dark"
718
+ }
719
+ ```
720
+
721
+ ### JSON to TOML
722
+
723
+ ```jsonc
724
+ {
725
+ "from": "config.json",
726
+ "to": ".codex/config.toml"
727
+ }
728
+ ```
729
+
730
+ **Source (JSON):**
731
+ ```json
732
+ {
733
+ "server": {
734
+ "host": "localhost",
735
+ "port": 3000
736
+ }
737
+ }
738
+ ```
739
+
740
+ **Target (TOML):**
741
+ ```toml
742
+ [server]
743
+ host = "localhost"
744
+ port = 3000
745
+ ```
746
+
747
+ ### Markdown Frontmatter
748
+
749
+ Transforms YAML frontmatter while preserving body:
750
+
751
+ ```jsonc
752
+ {
753
+ "from": "agents/**/*.md",
754
+ "to": ".claude/agents/**/*.md",
755
+ "map": {
756
+ "role": "type"
757
+ }
758
+ }
759
+ ```
760
+
761
+ **Source:**
762
+ ```markdown
763
+ ---
764
+ role: assistant
765
+ model: claude-sonnet-4
766
+ ---
767
+ # Agent Instructions
768
+ Help users with code reviews.
769
+ ```
770
+
771
+ **Target:**
772
+ ```markdown
773
+ ---
774
+ type: assistant
775
+ model: claude-sonnet-4
776
+ ---
777
+ # Agent Instructions
778
+ Help users with code reviews.
779
+ ```
780
+
781
+ **Body is unchanged.**
782
+
783
+ ## Merge Strategies
784
+
785
+ ### Deep Merge
786
+
787
+ Recursively merge nested structures:
788
+
789
+ ```jsonc
790
+ { "merge": "deep" }
791
+ ```
792
+
793
+ **Use when:**
794
+ - Composing configurations from multiple packages
795
+ - Preserving existing nested settings
796
+ - Adding keys at any depth
797
+
798
+ **Example:**
799
+ ```json
800
+ // Target (existing)
801
+ { "editor": { "theme": "dark", "fontSize": 12 } }
802
+
803
+ // Source (new)
804
+ { "editor": { "fontSize": 14, "tabSize": 2 } }
805
+
806
+ // Result
807
+ { "editor": { "theme": "dark", "fontSize": 14, "tabSize": 2 } }
808
+ ```
809
+
810
+ ### Shallow Merge
811
+
812
+ Merge only top-level keys:
813
+
814
+ ```jsonc
815
+ { "merge": "shallow" }
816
+ ```
817
+
818
+ **Use when:**
819
+ - Replacing entire nested objects
820
+ - Avoiding deep merge complexity
821
+ - Clear ownership of nested structures
822
+
823
+ **Example:**
824
+ ```json
825
+ // Target (existing)
826
+ { "editor": { "theme": "dark" }, "terminal": { "shell": "bash" } }
827
+
828
+ // Source (new)
829
+ { "editor": { "fontSize": 14 } }
830
+
831
+ // Result
832
+ { "editor": { "fontSize": 14 }, "terminal": { "shell": "bash" } }
833
+ ```
834
+
835
+ Note: `editor` object replaced entirely, `terminal` preserved.
836
+
837
+ ### Replace
838
+
839
+ Completely overwrite target:
840
+
841
+ ```jsonc
842
+ { "merge": "replace" }
843
+ ```
844
+
845
+ **Use when:**
846
+ - Source is authoritative
847
+ - Target should be discarded
848
+ - No composition needed
849
+
850
+ **Example:**
851
+ ```json
852
+ // Target (existing) - ignored
853
+ { "old": "config" }
854
+
855
+ // Source (new)
856
+ { "new": "config" }
857
+
858
+ // Result
859
+ { "new": "config" }
860
+ ```
861
+
862
+
863
+ ### Composite
864
+
865
+ Compose multiple package contributions using delimiters:
866
+
867
+ ```jsonc
868
+ { "merge": "composite" }
869
+ ```
870
+
871
+ **Use when:**
872
+ - Multiple packages contribute to same text file
873
+ - Each package needs its own section
874
+ - Sections should be independently updatable
875
+ - Content outside package sections must be preserved
876
+
877
+ **Supported formats:**
878
+ - Markdown files with HTML comment delimiters
879
+ - Any text-based format with comment support
880
+
881
+ **Example:**
882
+ ```markdown
883
+ // Target (existing)
884
+ # Instructions
885
+
886
+ <!-- package: @user/package-a -->
887
+ Instructions from Package A
888
+ <!-- -->
889
+
890
+ // Source (new package @user/package-b)
891
+ Instructions from Package B
892
+
893
+ // Result
894
+ # Instructions
895
+
896
+ <!-- package: @user/package-a -->
897
+ Instructions from Package A
898
+ <!-- -->
899
+
900
+ <!-- package: @user/package-b -->
901
+ Instructions from Package B
902
+ <!-- -->
903
+ ```
904
+
905
+ **Update behavior:**
906
+ ```markdown
907
+ // Target (existing)
908
+ <!-- package: @user/package-a -->
909
+ Old instructions from Package A
910
+ <!-- -->
911
+
912
+ <!-- package: @user/package-b -->
913
+ Instructions from Package B
914
+ <!-- -->
915
+
916
+ // Source (updated package @user/package-a)
917
+ New instructions from Package A
918
+
919
+ // Result
920
+ <!-- package: @user/package-a -->
921
+ New instructions from Package A
922
+ <!-- -->
923
+
924
+ <!-- package: @user/package-b -->
925
+ Instructions from Package B
926
+ <!-- -->
927
+ ```
928
+
929
+ **Key features:**
930
+ - Each package's content wrapped in `<!-- package: name -->` ... `<!-- -->` markers
931
+ - Updates replace only that package's section
932
+ - Other packages' sections preserved
933
+ - Manual edits outside markers preserved
934
+ - Uninstalling removes only that package's section
935
+
936
+ **Common use cases:**
937
+ - Root files (AGENTS.md, CLAUDE.md, QWEN.md, WARP.md)
938
+ - Shared instruction files
939
+ - Multi-package documentation
940
+ - Composable configuration narratives
941
+
942
+ ### Priority-Based Merging
943
+
944
+ When multiple packages write to same file:
945
+
946
+ **Priority order:**
947
+ 1. Workspace content (highest)
948
+ 2. Direct dependencies
949
+ 3. Nested dependencies (shallower = higher priority)
950
+
951
+ **Conflicts:**
952
+ - Last writer wins (by priority)
953
+ - Warnings logged with package info
954
+
955
+ **Example:**
956
+ ```
957
+ Package A (direct): { "servers": { "db": { "host": "localhost" } } }
958
+ Package B (direct): { "servers": { "db": { "port": 5432 } } }
959
+
960
+ Result: { "servers": { "db": { "host": "localhost", "port": 5432 } } }
961
+ Warning: "Package B merging with Package A in .cursor/mcp.json"
962
+ ```
963
+
964
+ ## Key Tracking for Uninstall
965
+
966
+ When flows use `merge: 'deep'` or `merge: 'shallow'`, the system automatically tracks which keys each package contributes to the target file. This enables precise removal during uninstall.
967
+
968
+ ### How It Works
969
+
970
+ **During installation:**
971
+ 1. Flow executes and merges content into target file
972
+ 2. System extracts all top-level and nested keys written
973
+ 3. Keys stored in workspace index with dot notation
974
+ 4. Keys represent **transformed** paths (after `map` operations)
975
+
976
+ **During uninstall:**
977
+ 1. Read tracked keys from workspace index
978
+ 2. Load target file
979
+ 3. Remove only the tracked keys
980
+ 4. Clean up empty parent objects
981
+ 5. Delete file if empty, otherwise save updated content
982
+
983
+ ### Example: Key Transformation
984
+
985
+ Flow with key transformation:
986
+
987
+ ```jsonc
988
+ {
989
+ "from": "mcp.jsonc",
990
+ "to": ".opencode/opencode.json",
991
+ "map": {
992
+ "mcpServers.*": "mcp.*" // Transform keys!
993
+ },
994
+ "merge": "deep"
995
+ }
996
+ ```
997
+
998
+ **Package source:**
999
+ ```json
1000
+ {
1001
+ "mcpServers": {
1002
+ "server1": { "url": "http://localhost:3000" },
1003
+ "server2": { "url": "http://localhost:4000" }
1004
+ }
1005
+ }
1006
+ ```
1007
+
1008
+ **Workspace index (after install):**
1009
+ ```yaml
1010
+ files:
1011
+ mcp.jsonc:
1012
+ - target: .opencode/opencode.json
1013
+ merge: deep
1014
+ keys:
1015
+ - mcp.server1 # Note: transformed key, not mcpServers.server1
1016
+ - mcp.server2
1017
+ ```
1018
+
1019
+ **Target file after install:**
1020
+ ```json
1021
+ {
1022
+ "mcp": {
1023
+ "server1": { "url": "http://localhost:3000" },
1024
+ "server2": { "url": "http://localhost:4000" }
1025
+ }
1026
+ }
1027
+ ```
1028
+
1029
+ **On uninstall:**
1030
+ - Keys `mcp.server1` and `mcp.server2` are removed
1031
+ - If no other packages contributed to `mcp`, the entire object is removed
1032
+ - Other top-level keys in the file are preserved
1033
+
1034
+ ### Why Track Transformed Keys?
1035
+
1036
+ **The challenge:** Flows can transform keys using `map`:
1037
+ - `servers.*` → `database.*`
1038
+ - `config.*` → `settings.*`
1039
+ - `mcpServers.*` → `mcp.*`
1040
+
1041
+ **The solution:** Track the **output** keys (after transformation), not the input keys. This works regardless of transformation complexity and allows precise removal without needing the original source.
1042
+
1043
+ ### When Keys Are Tracked
1044
+
1045
+ **Keys tracked when:**
1046
+ - ✅ Flow uses `merge: 'deep'`
1047
+ - ✅ Flow uses `merge: 'shallow'`
1048
+ - ✅ Target file will be shared by multiple packages
1049
+
1050
+ **Keys NOT tracked when:**
1051
+ - ❌ `merge: 'replace'` - entire file owned by one package
1052
+ - ❌ `merge: 'composite'` - delimiter-based tracking used
1053
+ - ❌ Simple file copy - no merge involved
1054
+
1055
+ ### Key Notation
1056
+
1057
+ Keys use dot notation for nested paths:
1058
+
1059
+ ```
1060
+ mcp.server1 → { mcp: { server1: {...} } }
1061
+ editor.fontSize → { editor: { fontSize: 14 } }
1062
+ servers.db.host → { servers: { db: { host: "..." } } }
1063
+ ```
1064
+
1065
+ ### Parent Cleanup
1066
+
1067
+ When removing keys, empty parent objects are automatically cleaned up:
1068
+
1069
+ ```json
1070
+ // Before uninstall
1071
+ {
1072
+ "mcp": {
1073
+ "server1": { "url": "..." },
1074
+ "server2": { "url": "..." }
1075
+ },
1076
+ "other": { "config": "..." }
1077
+ }
1078
+
1079
+ // After uninstalling package with keys [mcp.server1, mcp.server2]
1080
+ {
1081
+ "other": { "config": "..." }
1082
+ }
1083
+ // Note: entire "mcp" object removed because it became empty
1084
+ ```
1085
+
1086
+ ### Multi-Package Scenarios
1087
+
1088
+ When multiple packages contribute to the same file:
1089
+
1090
+ **Package A installed:**
1091
+ ```json
1092
+ { "mcp": { "server1": {...}, "server2": {...} } }
1093
+ ```
1094
+
1095
+ **Package B installed (same file, different keys):**
1096
+ ```json
1097
+ { "mcp": { "server1": {...}, "server2": {...}, "server3": {...} } }
1098
+ ```
1099
+
1100
+ **Uninstall Package A:**
1101
+ - Only removes keys tracked for Package A
1102
+ - Package B's keys remain intact
1103
+ - File not deleted because content remains
1104
+
1105
+ **Index tracking:**
1106
+ ```yaml
1107
+ packages:
1108
+ package-a:
1109
+ files:
1110
+ mcp.jsonc:
1111
+ - target: .opencode/opencode.json
1112
+ merge: deep
1113
+ keys: [mcp.server1, mcp.server2]
1114
+
1115
+ package-b:
1116
+ files:
1117
+ mcp.jsonc:
1118
+ - target: .opencode/opencode.json
1119
+ merge: deep
1120
+ keys: [mcp.server3]
1121
+ ```
1122
+
1123
+ See [Uninstall](../uninstall/README.md) for complete uninstall behavior.
1124
+
1125
+ ## Conditional Execution
1126
+
1127
+ Execute flows based on conditions:
1128
+
1129
+ ### Platform Check
1130
+
1131
+ ```jsonc
1132
+ {
1133
+ "from": "mcp.jsonc",
1134
+ "to": ".cursor/mcp.json",
1135
+ "when": { "platform": "cursor" }
1136
+ }
1137
+ ```
1138
+
1139
+ Flow executes only if Cursor platform is detected.
1140
+
1141
+ ### File Existence
1142
+
1143
+ ```jsonc
1144
+ {
1145
+ "from": "config.yaml",
1146
+ "to": ".cursor/config.json",
1147
+ "when": { "exists": ".cursor" }
1148
+ }
1149
+ ```
1150
+
1151
+ Flow executes only if `.cursor` directory exists.
1152
+
1153
+ ### Key Check
1154
+
1155
+ ```jsonc
1156
+ {
1157
+ "from": "settings.jsonc",
1158
+ "to": ".cursor/settings.json",
1159
+ "when": { "key": "cursor" }
1160
+ }
1161
+ ```
1162
+
1163
+ Flow executes only if source has `cursor` key.
1164
+
1165
+ ### Value Check
1166
+
1167
+ ```jsonc
1168
+ {
1169
+ "from": "config.yaml",
1170
+ "to": ".cursor/dev.json",
1171
+ "when": {
1172
+ "key": "env",
1173
+ "equals": "development"
1174
+ }
1175
+ }
1176
+ ```
1177
+
1178
+ Flow executes only if `env === "development"`.
1179
+
1180
+ ### Composite Conditions
1181
+
1182
+ **AND condition:**
1183
+ ```jsonc
1184
+ {
1185
+ "when": {
1186
+ "and": [
1187
+ { "platform": "cursor" },
1188
+ { "exists": "mcp.jsonc" }
1189
+ ]
1190
+ }
1191
+ }
1192
+ ```
1193
+
1194
+ **OR condition:**
1195
+ ```jsonc
1196
+ {
1197
+ "when": {
1198
+ "or": [
1199
+ { "platform": "cursor" },
1200
+ { "platform": "claude" }
1201
+ ]
1202
+ }
1203
+ }
1204
+ ```
1205
+
1206
+ ## Multi-Target Flows
1207
+
1208
+ One source file can flow to multiple targets with different transforms:
1209
+
1210
+ ```jsonc
1211
+ {
1212
+ "from": "mcp.jsonc",
1213
+ "to": {
1214
+ ".cursor/mcp.json": {
1215
+ "namespace": true,
1216
+ "merge": "deep"
1217
+ },
1218
+ ".opencode/opencode.json": {
1219
+ "embed": "mcp",
1220
+ "merge": "deep"
1221
+ },
1222
+ ".codex/config.toml": {
1223
+ "path": "$.servers",
1224
+ "section": "mcp_servers",
1225
+ "merge": "deep"
1226
+ }
1227
+ }
1228
+ }
1229
+ ```
1230
+
1231
+ **Behavior:**
1232
+ - Source parsed once
1233
+ - Each target gets independent transformation
1234
+ - Failures isolated per target
1235
+
1236
+ ## Namespace Isolation
1237
+
1238
+ Prevent package collisions:
1239
+
1240
+ ```jsonc
1241
+ {
1242
+ "from": "mcp.jsonc",
1243
+ "to": ".cursor/mcp.json",
1244
+ "namespace": true,
1245
+ "merge": "deep"
1246
+ }
1247
+ ```
1248
+
1249
+ **Package A content:**
1250
+ ```json
1251
+ { "servers": { "db": {} } }
1252
+ ```
1253
+
1254
+ **Package B content:**
1255
+ ```json
1256
+ { "servers": { "api": {} } }
1257
+ ```
1258
+
1259
+ **Result:**
1260
+ ```json
1261
+ {
1262
+ "packages": {
1263
+ "@user/package-a": {
1264
+ "servers": { "db": {} }
1265
+ },
1266
+ "@user/package-b": {
1267
+ "servers": { "api": {} }
1268
+ }
1269
+ }
1270
+ }
1271
+ ```
1272
+
1273
+ **Custom namespace key:**
1274
+ ```jsonc
1275
+ { "namespace": "extensions" }
1276
+ ```
1277
+
1278
+ ```json
1279
+ {
1280
+ "extensions": {
1281
+ "@user/package-a": { /* ... */ }
1282
+ }
1283
+ }
1284
+ ```
1285
+
1286
+ ## Performance Optimizations
1287
+
1288
+ ### Simple File Copy Bypass
1289
+
1290
+ Flows with no transforms skip pipeline:
1291
+
1292
+ ```jsonc
1293
+ {
1294
+ "from": "rules/**/*.md",
1295
+ "to": ".cursor/rules/**/*.mdc"
1296
+ }
1297
+ ```
1298
+
1299
+ **Optimized:** Direct file copy for simple extension changes, no content parsing.
1300
+
1301
+ ### Parser Caching
1302
+
1303
+ Format parsers cached per file type within execution context.
1304
+
1305
+ ### Single Source Parse
1306
+
1307
+ Multi-target flows parse source once:
1308
+
1309
+ ```jsonc
1310
+ {
1311
+ "from": "config.yaml",
1312
+ "to": {
1313
+ ".cursor/config.json": {},
1314
+ ".claude/config.json": {}
1315
+ }
1316
+ }
1317
+ ```
1318
+
1319
+ **Optimized:** YAML parsed once, serialized twice.
1320
+
1321
+ ### Lazy Evaluation
1322
+
1323
+ Conditional flows evaluated before loading source:
1324
+
1325
+ ```jsonc
1326
+ {
1327
+ "from": "large-file.json",
1328
+ "to": ".cursor/config.json",
1329
+ "when": { "platform": "claude" } // False for Cursor
1330
+ }
1331
+ ```
1332
+
1333
+ **Optimized:** File not loaded if condition false.
1334
+
1335
+ ## Error Handling
1336
+
1337
+ ### Parse Errors
1338
+
1339
+ ```
1340
+ Error: Failed to parse config.yaml: Invalid YAML syntax at line 5
1341
+ ```
1342
+
1343
+ **Solution:** Fix source file syntax.
1344
+
1345
+ ### Transform Errors
1346
+
1347
+ ```
1348
+ Error: Transform 'unknown-transform' not found in pipe
1349
+ Available: [jsonc, yaml, toml, merge, ...]
1350
+ ```
1351
+
1352
+ **Solution:** Use valid transform name from built-ins.
1353
+
1354
+ ### Path Errors
1355
+
1356
+ ```
1357
+ Error: JSONPath '$.invalid..path' is invalid
1358
+ ```
1359
+
1360
+ **Solution:** Fix JSONPath syntax.
1361
+
1362
+ ### Merge Conflicts
1363
+
1364
+ ```
1365
+ Warning: Package @user/b overwrites content from @user/a in .cursor/mcp.json
1366
+ ```
1367
+
1368
+ **Solution:** Check priority order or use namespace isolation.
1369
+
1370
+ ## Best Practices
1371
+
1372
+ ### 1. Start Simple
1373
+
1374
+ ```jsonc
1375
+ {
1376
+ "from": "rules/*.md",
1377
+ "to": ".cursor/rules/*.md"
1378
+ }
1379
+ ```
1380
+
1381
+ Add transforms only when needed.
1382
+
1383
+ ### 2. Test Incrementally
1384
+
1385
+ ```bash
1386
+ opkg install @user/package --dry-run
1387
+ ```
1388
+
1389
+ Preview changes before applying.
1390
+
1391
+ ### 3. Use Merge for Composition
1392
+
1393
+ ```jsonc
1394
+ {
1395
+ "from": "mcp.jsonc",
1396
+ "to": ".cursor/mcp.json",
1397
+ "merge": "deep"
1398
+ }
1399
+ ```
1400
+
1401
+ Allow multiple packages to compose content.
1402
+
1403
+ ### 4. Isolate with Namespaces
1404
+
1405
+ ```jsonc
1406
+ {
1407
+ "namespace": true,
1408
+ "merge": "deep"
1409
+ }
1410
+ ```
1411
+
1412
+ Prevent unintended conflicts.
1413
+
1414
+ ### 5. Document Complex Flows
1415
+
1416
+ ```jsonc
1417
+ {
1418
+ // Transform MCP config for Cursor with namespacing
1419
+ "from": "mcp.jsonc",
1420
+ "to": ".cursor/mcp.json",
1421
+ "namespace": true,
1422
+ "merge": "deep"
1423
+ }
1424
+ ```
1425
+
1426
+ ## Export/Import Architecture
1427
+
1428
+ ### Explicit Bidirectional Flows
1429
+
1430
+ Instead of automatic flow inversion, OpenPackage uses **explicit export and import flows**:
1431
+
1432
+ **Export flow (package → workspace):**
1433
+ ```jsonc
1434
+ {
1435
+ "export": [
1436
+ {
1437
+ "from": ["mcp.jsonc", "mcp.json"],
1438
+ "to": ".claude/.mcp.json",
1439
+ "map": [
1440
+ { "$rename": { "mcp": "mcpServers" } }
1441
+ ]
1442
+ }
1443
+ ]
1444
+ }
1445
+ ```
1446
+
1447
+ **Import flow (workspace → package):**
1448
+ ```jsonc
1449
+ {
1450
+ "import": [
1451
+ {
1452
+ "from": [".claude/.mcp.json", ".claude/mcp.json"],
1453
+ "to": "mcp.jsonc",
1454
+ "map": [{ "$rename": { "mcpServers": "mcp" } }]
1455
+ }
1456
+ ]
1457
+ }
1458
+ ```
1459
+
1460
+ ### Benefits of Explicit Flows
1461
+
1462
+ 1. **No inversion complexity** - Both directions explicitly defined
1463
+ 2. **Asymmetric transforms** - Different logic per direction (e.g., add metadata on export, strip on import)
1464
+ 3. **Array patterns both ways** - Full support for format preferences in both directions
1465
+ 4. **Lossy transforms** - Can use transforms that can't be automatically inverted
1466
+ 5. **Clear intent** - Reading config shows exactly what happens in each direction
1467
+
1468
+ ### Universal Converter
1469
+
1470
+ The **Universal Platform Converter** allows installing platform-specific packages to any platform using **import flows** instead of flow inversion.
1471
+
1472
+ **Example scenario:**
1473
+ - Install a Claude Code plugin (with `.claude/` directories)
1474
+ - To Cursor platform (needs `.cursor/` directories)
1475
+ - System uses Claude's **import flows** to convert `.claude/` → universal
1476
+ - Then applies Cursor's **export flows** to convert universal → `.cursor/`
1477
+
1478
+ **No flow inversion needed** - Import flows are explicitly defined for this purpose.
1479
+
1480
+ **See:** [Universal Converter](./universal-converter.md) for complete details on cross-platform conversion.
1481
+
1482
+ ## Next Steps
1483
+
1484
+ - **View complete flow options:** See [Flow Reference](./flow-reference.md)
1485
+ - **Cross-platform conversion:** See [Universal Converter](./universal-converter.md)
1486
+ - **See practical examples:** See [Examples](./examples.md)
1487
+ - **Learn key mapping:** See [Flow Reference](./flow-reference.md#key-mapping)
1488
+ - **Debug flows:** See [Troubleshooting](./troubleshooting.md)