opkg 0.5.0 → 0.6.1

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 (397) hide show
  1. package/README.md +82 -21
  2. package/dist/commands/add.js +11 -276
  3. package/dist/commands/add.js.map +1 -1
  4. package/dist/commands/duplicate.js +5 -2
  5. package/dist/commands/duplicate.js.map +1 -1
  6. package/dist/commands/init.js +76 -145
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/install.js +30 -671
  9. package/dist/commands/install.js.map +1 -1
  10. package/dist/commands/list.js +9 -3
  11. package/dist/commands/list.js.map +1 -1
  12. package/dist/commands/login.js +58 -0
  13. package/dist/commands/login.js.map +1 -0
  14. package/dist/commands/logout.js +28 -0
  15. package/dist/commands/logout.js.map +1 -0
  16. package/dist/commands/pack.js +10 -137
  17. package/dist/commands/pack.js.map +1 -1
  18. package/dist/commands/pull.js +5 -299
  19. package/dist/commands/pull.js.map +1 -1
  20. package/dist/commands/push.js +5 -239
  21. package/dist/commands/push.js.map +1 -1
  22. package/dist/commands/save.js +29 -168
  23. package/dist/commands/save.js.map +1 -1
  24. package/dist/commands/show.js +18 -5
  25. package/dist/commands/show.js.map +1 -1
  26. package/dist/commands/status.js +21 -8
  27. package/dist/commands/status.js.map +1 -1
  28. package/dist/commands/tui.js +61 -0
  29. package/dist/commands/tui.js.map +1 -0
  30. package/dist/commands/uninstall.js +5 -5
  31. package/dist/commands/uninstall.js.map +1 -1
  32. package/dist/constants/index.js +19 -45
  33. package/dist/constants/index.js.map +1 -1
  34. package/dist/constants/workspace.js +9 -0
  35. package/dist/constants/workspace.js.map +1 -0
  36. package/dist/core/add/add-conflict-handler.js +68 -0
  37. package/dist/core/add/add-conflict-handler.js.map +1 -0
  38. package/dist/core/add/add-pipeline.js +137 -0
  39. package/dist/core/add/add-pipeline.js.map +1 -0
  40. package/dist/core/add/package-index-updater.js +66 -36
  41. package/dist/core/add/package-index-updater.js.map +1 -1
  42. package/dist/core/add/platform-path-transformer.js +47 -0
  43. package/dist/core/add/platform-path-transformer.js.map +1 -0
  44. package/dist/core/add/source-collector.js +57 -0
  45. package/dist/core/add/source-collector.js.map +1 -0
  46. package/dist/core/api-keys.js +6 -2
  47. package/dist/core/api-keys.js.map +1 -1
  48. package/dist/core/auth.js +25 -40
  49. package/dist/core/auth.js.map +1 -1
  50. package/dist/core/config.js +11 -3
  51. package/dist/core/config.js.map +1 -1
  52. package/dist/core/dependency-resolver.js +24 -11
  53. package/dist/core/dependency-resolver.js.map +1 -1
  54. package/dist/core/device-auth.js +81 -0
  55. package/dist/core/device-auth.js.map +1 -0
  56. package/dist/core/directory.js +15 -9
  57. package/dist/core/directory.js.map +1 -1
  58. package/dist/core/discovery/file-discovery.js +55 -54
  59. package/dist/core/discovery/file-discovery.js.map +1 -1
  60. package/dist/core/discovery/platform-files-discovery.js +32 -17
  61. package/dist/core/discovery/platform-files-discovery.js.map +1 -1
  62. package/dist/core/install/bulk-install-pipeline.js +200 -0
  63. package/dist/core/install/bulk-install-pipeline.js.map +1 -0
  64. package/dist/core/install/canonical-plan.js +129 -0
  65. package/dist/core/install/canonical-plan.js.map +1 -0
  66. package/dist/core/install/download-keys.js +2 -2
  67. package/dist/core/install/download-keys.js.map +1 -1
  68. package/dist/core/install/dry-run.js +2 -2
  69. package/dist/core/install/dry-run.js.map +1 -1
  70. package/dist/core/install/index.js +3 -0
  71. package/dist/core/install/index.js.map +1 -0
  72. package/dist/core/install/install-errors.js +41 -0
  73. package/dist/core/install/install-errors.js.map +1 -0
  74. package/dist/core/install/install-flow.js +8 -9
  75. package/dist/core/install/install-flow.js.map +1 -1
  76. package/dist/core/install/install-pipeline.js +296 -0
  77. package/dist/core/install/install-pipeline.js.map +1 -0
  78. package/dist/core/install/install-reporting.js +99 -0
  79. package/dist/core/install/install-reporting.js.map +1 -0
  80. package/dist/core/install/platform-resolution.js +6 -6
  81. package/dist/core/install/platform-resolution.js.map +1 -1
  82. package/dist/core/install/remote-flow.js +84 -7
  83. package/dist/core/install/remote-flow.js.map +1 -1
  84. package/dist/core/install/version-selection.js +25 -8
  85. package/dist/core/install/version-selection.js.map +1 -1
  86. package/dist/core/openpackage.js +22 -14
  87. package/dist/core/openpackage.js.map +1 -1
  88. package/dist/core/package-context.js +246 -0
  89. package/dist/core/package-context.js.map +1 -0
  90. package/dist/core/package.js +73 -9
  91. package/dist/core/package.js.map +1 -1
  92. package/dist/core/platforms.js +126 -217
  93. package/dist/core/platforms.js.map +1 -1
  94. package/dist/core/profiles.js +60 -3
  95. package/dist/core/profiles.js.map +1 -1
  96. package/dist/core/pull/pull-errors.js +62 -0
  97. package/dist/core/pull/pull-errors.js.map +1 -0
  98. package/dist/core/pull/pull-options.js +2 -0
  99. package/dist/core/pull/pull-options.js.map +1 -0
  100. package/dist/core/pull/pull-output.js +50 -0
  101. package/dist/core/pull/pull-output.js.map +1 -0
  102. package/dist/core/pull/pull-pipeline.js +141 -0
  103. package/dist/core/pull/pull-pipeline.js.map +1 -0
  104. package/dist/core/pull/pull-strategies.js +103 -0
  105. package/dist/core/pull/pull-strategies.js.map +1 -0
  106. package/dist/core/pull/pull-types.js +2 -0
  107. package/dist/core/pull/pull-types.js.map +1 -0
  108. package/dist/core/push/push-context.js +95 -0
  109. package/dist/core/push/push-context.js.map +1 -0
  110. package/dist/core/push/push-errors.js +133 -0
  111. package/dist/core/push/push-errors.js.map +1 -0
  112. package/dist/core/push/push-output.js +44 -0
  113. package/dist/core/push/push-output.js.map +1 -0
  114. package/dist/core/push/push-pipeline.js +74 -0
  115. package/dist/core/push/push-pipeline.js.map +1 -0
  116. package/dist/core/push/push-single-file.js +56 -0
  117. package/dist/core/push/push-single-file.js.map +1 -0
  118. package/dist/core/push/push-types.js +2 -0
  119. package/dist/core/push/push-types.js.map +1 -0
  120. package/dist/core/push/push-upload.js +68 -0
  121. package/dist/core/push/push-upload.js.map +1 -0
  122. package/dist/core/registry/registry-rename.js +2 -1
  123. package/dist/core/registry/registry-rename.js.map +1 -1
  124. package/dist/core/registry.js +14 -5
  125. package/dist/core/registry.js.map +1 -1
  126. package/dist/core/remote-pull.js +165 -36
  127. package/dist/core/remote-pull.js.map +1 -1
  128. package/dist/core/save/constants.js +4 -0
  129. package/dist/core/save/constants.js.map +1 -1
  130. package/dist/core/save/name-resolution.js +31 -0
  131. package/dist/core/save/name-resolution.js.map +1 -0
  132. package/dist/core/save/package-detection.js +147 -0
  133. package/dist/core/save/package-detection.js.map +1 -0
  134. package/dist/core/save/package-saver.js +82 -43
  135. package/dist/core/save/package-saver.js.map +1 -1
  136. package/dist/core/save/package-yml-generator.js +51 -71
  137. package/dist/core/save/package-yml-generator.js.map +1 -1
  138. package/dist/core/save/root-save-candidates.js.map +1 -1
  139. package/dist/core/save/save-candidate-loader.js +89 -0
  140. package/dist/core/save/save-candidate-loader.js.map +1 -0
  141. package/dist/core/save/save-conflict-resolution.js +72 -410
  142. package/dist/core/save/save-conflict-resolution.js.map +1 -1
  143. package/dist/core/save/save-conflict-resolver.js +277 -0
  144. package/dist/core/save/save-conflict-resolver.js.map +1 -0
  145. package/dist/core/save/save-pipeline.js +162 -0
  146. package/dist/core/save/save-pipeline.js.map +1 -0
  147. package/dist/core/save/save-single-file.js +124 -0
  148. package/dist/core/save/save-single-file.js.map +1 -0
  149. package/dist/core/save/save-types.js +2 -0
  150. package/dist/core/save/save-types.js.map +1 -0
  151. package/dist/core/save/save-yml-resolution.js +77 -39
  152. package/dist/core/save/save-yml-resolution.js.map +1 -1
  153. package/dist/core/save/workspace-rename.js +6 -6
  154. package/dist/core/save/workspace-rename.js.map +1 -1
  155. package/dist/core/scoping/package-scoping.js +14 -2
  156. package/dist/core/scoping/package-scoping.js.map +1 -1
  157. package/dist/core/status/status-file-discovery.js +12 -30
  158. package/dist/core/status/status-file-discovery.js.map +1 -1
  159. package/dist/core/sync/platform-sync.js +7 -4
  160. package/dist/core/sync/platform-sync.js.map +1 -1
  161. package/dist/core/sync/root-files-sync.js +59 -1
  162. package/dist/core/sync/root-files-sync.js.map +1 -1
  163. package/dist/core/token-store.js +73 -0
  164. package/dist/core/token-store.js.map +1 -0
  165. package/dist/core/uninstall/uninstall-file-discovery.js +1 -2
  166. package/dist/core/uninstall/uninstall-file-discovery.js.map +1 -1
  167. package/dist/index.js +4 -0
  168. package/dist/index.js.map +1 -1
  169. package/dist/tui/app.js +95 -0
  170. package/dist/tui/app.js.map +1 -0
  171. package/dist/tui/components/package-list.js +73 -0
  172. package/dist/tui/components/package-list.js.map +1 -0
  173. package/dist/tui/controller.js +365 -0
  174. package/dist/tui/controller.js.map +1 -0
  175. package/dist/tui/index.js +12 -0
  176. package/dist/tui/index.js.map +1 -0
  177. package/dist/tui/services/file-index.js +64 -0
  178. package/dist/tui/services/file-index.js.map +1 -0
  179. package/dist/tui/services/packages.js +18 -0
  180. package/dist/tui/services/packages.js.map +1 -0
  181. package/dist/tui/services/save.js +21 -0
  182. package/dist/tui/services/save.js.map +1 -0
  183. package/dist/tui/state/app-state.js +15 -0
  184. package/dist/tui/state/app-state.js.map +1 -0
  185. package/dist/tui/state.js +17 -0
  186. package/dist/tui/state.js.map +1 -0
  187. package/dist/tui/types.js +2 -0
  188. package/dist/tui/types.js.map +1 -0
  189. package/dist/tui/views/add-file-modal.js +129 -0
  190. package/dist/tui/views/add-file-modal.js.map +1 -0
  191. package/dist/tui/views/file-preview.js +44 -0
  192. package/dist/tui/views/file-preview.js.map +1 -0
  193. package/dist/tui/views/list-packages.js +73 -0
  194. package/dist/tui/views/list-packages.js.map +1 -0
  195. package/dist/tui/views/main-menu.js +29 -0
  196. package/dist/tui/views/main-menu.js.map +1 -0
  197. package/dist/tui/views/manage-view.js +81 -0
  198. package/dist/tui/views/manage-view.js.map +1 -0
  199. package/dist/tui/views/package-hub.js +120 -0
  200. package/dist/tui/views/package-hub.js.map +1 -0
  201. package/dist/tui/views/placeholder.js +24 -0
  202. package/dist/tui/views/placeholder.js.map +1 -0
  203. package/dist/types/index.js.map +1 -1
  204. package/dist/utils/bun-bootstrap.js +72 -0
  205. package/dist/utils/bun-bootstrap.js.map +1 -0
  206. package/dist/utils/file-processing.js +5 -58
  207. package/dist/utils/file-processing.js.map +1 -1
  208. package/dist/utils/formatters.js +3 -1
  209. package/dist/utils/formatters.js.map +1 -1
  210. package/dist/utils/http-client.js +27 -5
  211. package/dist/utils/http-client.js.map +1 -1
  212. package/dist/utils/index-based-installer.js +40 -35
  213. package/dist/utils/index-based-installer.js.map +1 -1
  214. package/dist/utils/install-file-discovery.js +18 -24
  215. package/dist/utils/install-file-discovery.js.map +1 -1
  216. package/dist/utils/install-orchestrator.js +21 -21
  217. package/dist/utils/install-orchestrator.js.map +1 -1
  218. package/dist/utils/jsonc.js +44 -0
  219. package/dist/utils/jsonc.js.map +1 -0
  220. package/dist/utils/manifest-paths.js +27 -0
  221. package/dist/utils/manifest-paths.js.map +1 -0
  222. package/dist/utils/package-copy.js +199 -0
  223. package/dist/utils/package-copy.js.map +1 -0
  224. package/dist/utils/package-filters.js +125 -0
  225. package/dist/utils/package-filters.js.map +1 -0
  226. package/dist/utils/package-index-yml.js +15 -10
  227. package/dist/utils/package-index-yml.js.map +1 -1
  228. package/dist/utils/package-installation.js +4 -113
  229. package/dist/utils/package-installation.js.map +1 -1
  230. package/dist/utils/package-local-files.js +2 -35
  231. package/dist/utils/package-local-files.js.map +1 -1
  232. package/dist/utils/package-management.js +191 -75
  233. package/dist/utils/package-management.js.map +1 -1
  234. package/dist/utils/package-merge.js +48 -0
  235. package/dist/utils/package-merge.js.map +1 -0
  236. package/dist/utils/package-name.js +29 -0
  237. package/dist/utils/package-name.js.map +1 -1
  238. package/dist/utils/package-versioning.js +16 -4
  239. package/dist/utils/package-versioning.js.map +1 -1
  240. package/dist/utils/package-yml.js +41 -12
  241. package/dist/utils/package-yml.js.map +1 -1
  242. package/dist/utils/path-normalization.js +8 -53
  243. package/dist/utils/path-normalization.js.map +1 -1
  244. package/dist/utils/paths.js +17 -9
  245. package/dist/utils/paths.js.map +1 -1
  246. package/dist/utils/platform-file.js +16 -59
  247. package/dist/utils/platform-file.js.map +1 -1
  248. package/dist/utils/platform-mapper.js +29 -41
  249. package/dist/utils/platform-mapper.js.map +1 -1
  250. package/dist/utils/platform-specific-paths.js.map +1 -1
  251. package/dist/utils/platform-utils.js +28 -139
  252. package/dist/utils/platform-utils.js.map +1 -1
  253. package/dist/utils/platform-yaml-merge.js +13 -6
  254. package/dist/utils/platform-yaml-merge.js.map +1 -1
  255. package/dist/utils/prompts.js +0 -31
  256. package/dist/utils/prompts.js.map +1 -1
  257. package/dist/utils/registry-entry-filter.js +38 -24
  258. package/dist/utils/registry-entry-filter.js.map +1 -1
  259. package/dist/utils/registry-paths.js +48 -0
  260. package/dist/utils/registry-paths.js.map +1 -0
  261. package/dist/utils/root-file-installer.js +19 -0
  262. package/dist/utils/root-file-installer.js.map +1 -1
  263. package/dist/utils/root-file-registry.js.map +1 -1
  264. package/dist/utils/tarball.js +6 -2
  265. package/dist/utils/tarball.js.map +1 -1
  266. package/dist/utils/version-ranges.js +11 -8
  267. package/dist/utils/version-ranges.js.map +1 -1
  268. package/package.json +3 -2
  269. package/platforms.jsonc +178 -0
  270. package/specs/auth/auth-device-flow.md +70 -0
  271. package/specs/install/install-behavior.md +30 -0
  272. package/specs/install/package-yml-canonical.md +21 -1
  273. package/specs/install/version-resolution.md +9 -7
  274. package/specs/login/login-device-flow.md +70 -0
  275. package/specs/package/README.md +60 -0
  276. package/specs/package/nested-packages-and-parent-packages.md +79 -0
  277. package/specs/package/package-index-yml.md +171 -0
  278. package/specs/package/package-root-layout.md +78 -0
  279. package/specs/package/registry-payload-and-copy.md +77 -0
  280. package/specs/package/universal-content.md +144 -0
  281. package/specs/platforms.md +193 -0
  282. package/specs/push/push-behavior.md +38 -10
  283. package/specs/push/push-errors-and-hints.md +19 -6
  284. package/specs/push/push-remote-upload.md +3 -0
  285. package/specs/push/push-scoping.md +14 -22
  286. package/specs/push/push-version-selection.md +18 -16
  287. package/specs/save/README.md +40 -0
  288. package/specs/save/save-conflict-resolution.md +146 -0
  289. package/specs/save/save-file-discovery.md +101 -0
  290. package/specs/save/save-frontmatter-overrides.md +81 -0
  291. package/specs/save/save-modes-inputs.md +55 -0
  292. package/specs/save/save-naming-scoping.md +93 -0
  293. package/specs/save/save-package-detection.md +60 -0
  294. package/specs/save/save-registry-sync.md +126 -0
  295. package/specs/save-pack.md +1 -0
  296. package/dist/commands/release.js +0 -33
  297. package/dist/commands/release.js.map +0 -1
  298. package/dist/commands/tag.js +0 -311
  299. package/dist/commands/tag.js.map +0 -1
  300. package/dist/commands/update.js +0 -30
  301. package/dist/commands/update.js.map +0 -1
  302. package/dist/core/add/formula-index-updater.js +0 -290
  303. package/dist/core/add/formula-index-updater.js.map +0 -1
  304. package/dist/core/discovery/ai-files-discovery.js +0 -2
  305. package/dist/core/discovery/ai-files-discovery.js.map +0 -1
  306. package/dist/core/discovery/formula-files-discovery.js +0 -14
  307. package/dist/core/discovery/formula-files-discovery.js.map +0 -1
  308. package/dist/core/discovery/index-files-discovery.js +0 -91
  309. package/dist/core/discovery/index-files-discovery.js.map +0 -1
  310. package/dist/core/discovery/md-files-discovery.js +0 -82
  311. package/dist/core/discovery/md-files-discovery.js.map +0 -1
  312. package/dist/core/discovery/package-files-discovery.js +0 -14
  313. package/dist/core/discovery/package-files-discovery.js.map +0 -1
  314. package/dist/core/discovery/platform-discovery.js +0 -84
  315. package/dist/core/discovery/platform-discovery.js.map +0 -1
  316. package/dist/core/discovery/root-files-discovery.js +0 -2
  317. package/dist/core/discovery/root-files-discovery.js.map +0 -1
  318. package/dist/core/formula.js +0 -170
  319. package/dist/core/formula.js.map +0 -1
  320. package/dist/core/git-registry.js +0 -46
  321. package/dist/core/git-registry.js.map +0 -1
  322. package/dist/core/groundzero.js +0 -277
  323. package/dist/core/groundzero.js.map +0 -1
  324. package/dist/core/install/scenario.js +0 -11
  325. package/dist/core/install/scenario.js.map +0 -1
  326. package/dist/core/package-sync.js +0 -219
  327. package/dist/core/package-sync.js.map +0 -1
  328. package/dist/core/save/formula-file-generator.js +0 -167
  329. package/dist/core/save/formula-file-generator.js.map +0 -1
  330. package/dist/core/save/formula-saver.js +0 -52
  331. package/dist/core/save/formula-saver.js.map +0 -1
  332. package/dist/core/save/formula-yml-generator.js +0 -89
  333. package/dist/core/save/formula-yml-generator.js.map +0 -1
  334. package/dist/core/save/formula-yml-versioning.js +0 -108
  335. package/dist/core/save/formula-yml-versioning.js.map +0 -1
  336. package/dist/core/save/generic-file-sync.js +0 -38
  337. package/dist/core/save/generic-file-sync.js.map +0 -1
  338. package/dist/core/save/md-files-sync.js +0 -33
  339. package/dist/core/save/md-files-sync.js.map +0 -1
  340. package/dist/core/save/package-yml-versioning.js +0 -108
  341. package/dist/core/save/package-yml-versioning.js.map +0 -1
  342. package/dist/core/save/platform-sync.js +0 -95
  343. package/dist/core/save/platform-sync.js.map +0 -1
  344. package/dist/core/save/root-files-sync.js +0 -140
  345. package/dist/core/save/root-files-sync.js.map +0 -1
  346. package/dist/core/save/save-candidate-types.js +0 -2
  347. package/dist/core/save/save-candidate-types.js.map +0 -1
  348. package/dist/core/save/save-conflict-types.js +0 -2
  349. package/dist/core/save/save-conflict-types.js.map +0 -1
  350. package/dist/core/save/save-file-discovery.js +0 -5
  351. package/dist/core/save/save-file-discovery.js.map +0 -1
  352. package/dist/core/status-file-discovery.js +0 -175
  353. package/dist/core/status-file-discovery.js.map +0 -1
  354. package/dist/utils/discovery/file-processing.js +0 -156
  355. package/dist/utils/discovery/file-processing.js.map +0 -1
  356. package/dist/utils/discovery/formula-discovery.js +0 -211
  357. package/dist/utils/discovery/formula-discovery.js.map +0 -1
  358. package/dist/utils/discovery/platform-discovery.js +0 -2
  359. package/dist/utils/discovery/platform-discovery.js.map +0 -1
  360. package/dist/utils/formula-discovery.js +0 -102
  361. package/dist/utils/formula-discovery.js.map +0 -1
  362. package/dist/utils/formula-index-yml.js +0 -122
  363. package/dist/utils/formula-index-yml.js.map +0 -1
  364. package/dist/utils/formula-installation.js +0 -110
  365. package/dist/utils/formula-installation.js.map +0 -1
  366. package/dist/utils/formula-local-files.js +0 -38
  367. package/dist/utils/formula-local-files.js.map +0 -1
  368. package/dist/utils/formula-management.js +0 -191
  369. package/dist/utils/formula-management.js.map +0 -1
  370. package/dist/utils/formula-name.js +0 -97
  371. package/dist/utils/formula-name.js.map +0 -1
  372. package/dist/utils/formula-versioning.js +0 -109
  373. package/dist/utils/formula-versioning.js.map +0 -1
  374. package/dist/utils/formula-yml.js +0 -82
  375. package/dist/utils/formula-yml.js.map +0 -1
  376. package/dist/utils/git.js +0 -54
  377. package/dist/utils/git.js.map +0 -1
  378. package/dist/utils/id-based-discovery.js +0 -126
  379. package/dist/utils/id-based-discovery.js.map +0 -1
  380. package/dist/utils/id-based-installer.js +0 -249
  381. package/dist/utils/id-based-installer.js.map +0 -1
  382. package/dist/utils/index-yml-based-installer.js +0 -375
  383. package/dist/utils/index-yml-based-installer.js.map +0 -1
  384. package/dist/utils/index-yml.js +0 -124
  385. package/dist/utils/index-yml.js.map +0 -1
  386. package/dist/utils/md-frontmatter.js +0 -3
  387. package/dist/utils/md-frontmatter.js.map +0 -1
  388. package/dist/utils/package-link-yml.js +0 -92
  389. package/dist/utils/package-link-yml.js.map +0 -1
  390. package/dist/utils/platform-discovery.js +0 -2
  391. package/dist/utils/platform-discovery.js.map +0 -1
  392. package/dist/utils/platform-frontmatter-split.js +0 -15
  393. package/dist/utils/platform-frontmatter-split.js.map +0 -1
  394. package/dist/utils/timestamp-encoder.js +0 -13
  395. package/dist/utils/timestamp-encoder.js.map +0 -1
  396. package/dist/utils/wip-versioning.js +0 -24
  397. package/dist/utils/wip-versioning.js.map +0 -1
@@ -0,0 +1,178 @@
1
+ {
2
+ // Platform definitions for all supported AI coding platforms
3
+ // Each platform defines its directory structure, root files, and subdirectories
4
+
5
+ "augment": {
6
+ "name": "Augment Code",
7
+ "rootDir": ".augment",
8
+ "subdirs": {
9
+ "rules": {
10
+ "path": "rules",
11
+ "exts": [".md"]
12
+ },
13
+ "commands": {
14
+ "path": "commands",
15
+ "exts": [".md"]
16
+ }
17
+ }
18
+ },
19
+
20
+ "claude": {
21
+ "name": "Claude Code",
22
+ "rootDir": ".claude",
23
+ "rootFile": "CLAUDE.md",
24
+ "aliases": ["claudecode"],
25
+ "subdirs": {
26
+ "commands": {
27
+ "path": "commands",
28
+ "exts": [".md"]
29
+ },
30
+ "agents": {
31
+ "path": "agents",
32
+ "exts": [".md"]
33
+ },
34
+ "skills": {
35
+ "path": "skills"
36
+ }
37
+ }
38
+ },
39
+
40
+ "codex": {
41
+ "name": "Codex CLI",
42
+ "rootDir": ".codex",
43
+ "rootFile": "AGENTS.md",
44
+ "aliases": ["codexcli"],
45
+ "subdirs": {
46
+ "commands": {
47
+ "path": "prompts",
48
+ "exts": [".md"]
49
+ }
50
+ }
51
+ },
52
+
53
+ "cursor": {
54
+ "name": "Cursor",
55
+ "rootDir": ".cursor",
56
+ "rootFile": "AGENTS.md",
57
+ "subdirs": {
58
+ "rules": {
59
+ "path": "rules",
60
+ "exts": [".mdc", ".md"],
61
+ "transformations": [
62
+ {
63
+ "packageExt": ".md",
64
+ "workspaceExt": ".mdc"
65
+ }
66
+ ]
67
+ },
68
+ "commands": {
69
+ "path": "commands",
70
+ "exts": [".md"]
71
+ }
72
+ }
73
+ },
74
+
75
+ "factory": {
76
+ "name": "Factory AI",
77
+ "rootDir": ".factory",
78
+ "rootFile": "AGENTS.md",
79
+ "subdirs": {
80
+ "commands": {
81
+ "path": "commands",
82
+ "exts": [".md"]
83
+ },
84
+ "agents": {
85
+ "path": "droids",
86
+ "exts": [".md"]
87
+ }
88
+ }
89
+ },
90
+
91
+ "kilo": {
92
+ "name": "Kilo Code",
93
+ "rootDir": ".kilocode",
94
+ "rootFile": "AGENTS.md",
95
+ "aliases": ["kilocode"],
96
+ "subdirs": {
97
+ "rules": {
98
+ "path": "rules",
99
+ "exts": [".md"]
100
+ },
101
+ "commands": {
102
+ "path": "workflows",
103
+ "exts": [".md"]
104
+ }
105
+ }
106
+ },
107
+
108
+ "kiro": {
109
+ "name": "Kiro",
110
+ "rootDir": ".kiro",
111
+ "subdirs": {
112
+ "rules": {
113
+ "path": "steering",
114
+ "exts": [".md"]
115
+ }
116
+ }
117
+ },
118
+
119
+ "opencode": {
120
+ "name": "OpenCode",
121
+ "rootDir": ".opencode",
122
+ "rootFile": "AGENTS.md",
123
+ "subdirs": {
124
+ "commands": {
125
+ "path": "command",
126
+ "exts": [".md"]
127
+ },
128
+ "agents": {
129
+ "path": "agent",
130
+ "exts": [".md"]
131
+ }
132
+ }
133
+ },
134
+
135
+ "qwen": {
136
+ "name": "Qwen Code",
137
+ "rootDir": ".qwen",
138
+ "rootFile": "QWEN.md",
139
+ "aliases": ["qwencode"],
140
+ "subdirs": {
141
+ "agents": {
142
+ "path": "agents",
143
+ "exts": [".md"]
144
+ }
145
+ }
146
+ },
147
+
148
+ "roo": {
149
+ "name": "Roo Code",
150
+ "rootDir": ".roo",
151
+ "rootFile": "AGENTS.md",
152
+ "subdirs": {
153
+ "commands": {
154
+ "path": "commands",
155
+ "exts": [".md"]
156
+ }
157
+ }
158
+ },
159
+
160
+ "warp": {
161
+ "name": "Warp",
162
+ "rootDir": ".warp",
163
+ "rootFile": "WARP.md",
164
+ "subdirs": {}
165
+ },
166
+
167
+ "windsurf": {
168
+ "name": "Windsurf",
169
+ "rootDir": ".windsurf",
170
+ "subdirs": {
171
+ "rules": {
172
+ "path": "rules",
173
+ "exts": [".md"]
174
+ }
175
+ }
176
+ }
177
+ }
178
+
@@ -0,0 +1,70 @@
1
+ # opkg login – Device Authorization Flow (RFC 8628)
2
+
3
+ ## Goals
4
+ - Add `opkg login [--profile <name>]` using OAuth 2.0 Device Authorization Grant.
5
+ - Store bearer tokens per profile; keep API-key auth backward compatible.
6
+
7
+ ## Command behavior
8
+ - Syntax: `opkg login [--profile <name>]`
9
+ - Profile: optional; defaults to `default`.
10
+ - Flow:
11
+ 1) Start device authorization → get `device_code`, `user_code`, `verification_uri`, `verification_uri_complete`, `expires_in`, `interval`.
12
+ 2) Print code/URL; attempt to open browser to `verification_uri_complete`.
13
+ 3) Poll token endpoint until success/denied/expired/timeout.
14
+ 4) On success, persist access/refresh tokens to the selected profile.
15
+ 5) On failure, show actionable error and exit non-zero.
16
+
17
+ ## HTTP interactions (backend contract)
18
+ - POST `/auth/device/authorize` (no auth):
19
+ - Body: `{ clientId: 'opkg-cli', scope?: 'openid', deviceName?: 'opkg-cli' }`
20
+ - Response: `{ device_code, user_code, verification_uri, verification_uri_complete, expires_in, interval }`
21
+ - POST `/auth/device/token` (no auth):
22
+ - Body: `{ deviceCode }`
23
+ - Success: `{ access_token, refresh_token, token_type: 'bearer', expires_in }`
24
+ - Error codes (HTTP 400): `authorization_pending`, `slow_down`, `expired_token`, `access_denied`
25
+ - POST `/auth/refresh` (no auth) for refresh flow:
26
+ - Body: `{ refreshToken }`
27
+ - Success: `{ accessToken, refreshToken }`
28
+
29
+ ## CLI storage & auth selection
30
+ - Extend `ProfileCredentials` to include `access_token`, `refresh_token`, `expires_at`, `token_type`.
31
+ - Credentials persisted in the existing profile credentials INI; preserve existing `api_key`.
32
+ - Header selection:
33
+ - Prefer non-expired access token → `Authorization: Bearer <token>`.
34
+ - If expired and refresh token present → call `/auth/refresh`, persist new pair.
35
+ - Fallback: `X-API-Key` if present.
36
+ - If none: instruct user to run `opkg login` or configure API key.
37
+
38
+ ## UX requirements
39
+ - Print user code and verification URL.
40
+ - Open browser best-effort; if it fails, user can manually visit the URL.
41
+ - Poll respecting `interval`; on `slow_down` add +5s each time.
42
+ - Time out when `expires_in` elapses; show “code expired, rerun opkg login.”
43
+ - Errors:
44
+ - `access_denied`: “Access denied. Please restart opkg login.”
45
+ - `expired_token`: “Code expired. Please rerun opkg login.”
46
+
47
+ ## Persistence details
48
+ - `expires_at` derived from `Date.now() + expires_in*1000` or JWT `exp`.
49
+ - When refreshing, keep existing `api_key` intact in the profile record.
50
+
51
+ ## Edge cases & fallbacks
52
+ - If profile missing: create credentials entry when saving tokens.
53
+ - If refresh fails: drop to API key if present; otherwise require login.
54
+ - Platform-specific browser open: `open` (mac), `start` (win), `xdg-open` (linux); ignore failures.
55
+
56
+ ## Logout command
57
+ - Syntax: `opkg logout [--profile <name>]`
58
+ - Requires stored OAuth tokens for the profile; no-op if none.
59
+ - Sends `POST /auth/logout` with bearer auth and `{ refreshToken }` body.
60
+ - On success or failure, clears local token store entry; keeps any configured API key.
61
+ - If profile resolved as direct API key usage, exit with “no OAuth session.”
62
+
63
+ ## Telemetry/logging (minimal)
64
+ - Debug log start/stop of poll, slow_down adjustments, refresh attempts.
65
+ - Do not log tokens.
66
+
67
+ ## Non-goals (future)
68
+ - Device-name flag, headless/no-browser flag.
69
+ - Multi-factor UX in CLI.
70
+
@@ -23,6 +23,9 @@ This document defines the **user-facing behavior** of the `install` command, ass
23
23
  - If `<name>` is **already declared** in `package.yml`: `<spec>` is treated as a **constraint hint** that must be **compatible** with the canonical `package.yml` range (see `package-yml-canonical.md` for rules); resolution still uses the same **local-first with remote-fallback** semantics unless `--local` or `--remote` are set.
24
24
  - If `<name>` is **not declared**: `<spec>` is treated as the **initial version range** to store in `package.yml`, and resolution uses the **local-first with remote-fallback** policy under that range (or strictly local / remote when the corresponding flags are set).
25
25
 
26
+ - **`opkg install <name>/<registry-path>`** and **`opkg install <name>@<spec>/<registry-path>`**
27
+ - **Meaning**: Install only the specified registry-relative path(s) for `<name>` (e.g. `.openpackage/universal/prompts/foo.md`, `workspace/agents.md`). The path must be an **exact registry path** (no globs) and applies only to the **root dependency** being installed.
28
+
26
29
  Other flags (`--dev`, `--remote`, `--platforms`, `--dry-run`, `--stable`, conflicts) keep their existing semantics unless overridden below.
27
30
 
28
31
  ---
@@ -70,6 +73,7 @@ Other flags (`--dev`, `--remote`, `--platforms`, `--dry-run`, `--stable`, confli
70
73
  - **Install `<name>@<selectedVersion>`**.
71
74
  - **Add to `package.yml`**:
72
75
  - Default range is **caret based on the stable base** of the selected version (e.g. `^1.0.1` for `1.0.1-000fz8.a3k`), unless later overridden by a global policy.
76
+ - When the selected version is **unversioned** (manifest omits `version`, represented internally as `0.0.0`), persist the entry **without a `version` field** in `packages` / `dev-packages` (do **not** write `0.0.0`).
73
77
 
74
78
  - **Case B – `opkg install <name>@<spec>`**:
75
79
  - Treat `<spec>` as the **initial canonical range**:
@@ -100,6 +104,32 @@ Other flags (`--dev`, `--remote`, `--platforms`, `--dry-run`, `--stable`, confli
100
104
  - If compatible (according to rules in `package-yml-canonical.md`), proceed as above.
101
105
  - If incompatible, **fail with a clear error** instructing the user to edit `package.yml` instead of using CLI-only overrides.
102
106
 
107
+ ### 3.4 Registry-path / single-file installs
108
+
109
+ - **Inputs**:
110
+ - `opkg install <name>/<registry-path>` (optionally with `@<spec>`).
111
+ - `<registry-path>` is a registry-relative file path (no globs, exact match against registry entries).
112
+
113
+ - **Behavior – fresh dependency**:
114
+ - Resolve the version using the same policies as §3.1 (respecting `<spec>` if provided).
115
+ - Install only the specified registry path(s), including root files only when they are explicitly listed.
116
+ - Persist a new `files: [<registry-path>, ...]` list for the dependency in `package.yml` alongside the chosen range.
117
+ - If the requested path does not exist in the selected version, the install **warns and skips the package** (no files written, counts as `skipped`).
118
+
119
+ - **Behavior – existing dependency with `files` already in `package.yml`**:
120
+ - `opkg install <name>` (no new path):
121
+ - Re-installs the stored subset.
122
+ - In an interactive TTY and non-`--dry-run`, prompt: **switch to full install?** If accepted, clears the `files` list and performs a full install; otherwise keeps the subset.
123
+ - In non-interactive or `--dry-run`, keep the stored subset automatically (no prompt).
124
+ - `opkg install <name>/<registry-path>`:
125
+ - Adds the new path to the stored `files` list (deduped), then installs that combined subset.
126
+
127
+ - **Behavior – existing dependency without `files` (full install)**:
128
+ - Path-based install attempts are **rejected** with a clear error. To install a subset, uninstall first (or remove the dependency) and re-install with a path, or edit `package.yml` manually to add `files`.
129
+
130
+ - **Switching back to full**:
131
+ - Accept the prompt described above, or delete the `files` field for the dependency in `package.yml` (or uninstall/reinstall without a path).
132
+
103
133
  ---
104
134
 
105
135
  ### 3.3 Selection summary UX (local vs remote)
@@ -50,6 +50,7 @@ The aim is to make behavior predictable and avoid “CLI overrides” that silen
50
50
  - If only WIP/pre-release exists, the policy may:
51
51
  - Use an **exact WIP version** in `package.yml`, or
52
52
  - Use a range that explicitly includes that pre-release.
53
+ - If the selected version is **unversioned** (manifest omits `version`, represented as `0.0.0` internally), persist the dependency entry **without a `version` field** (bare name), rather than writing `0.0.0`.
53
54
 
54
55
  - **Case B – `opkg install <name>@<spec>`**:
55
56
  - `<spec>` is treated as the **initial canonical range** for `<name>`.
@@ -175,7 +176,26 @@ The aim is to make behavior predictable and avoid “CLI overrides” that silen
175
176
 
176
177
  ---
177
178
 
178
- ## 6. Summary invariants
179
+ ## 6. Partial installs via `files`
180
+
181
+ - **Meaning**:
182
+ - `files` is an optional array of **registry-relative paths** on a dependency entry (`packages` or `dev-packages`).
183
+ - When present, the dependency is treated as a **partial install**: only the listed registry paths are installed (root files are included only if explicitly listed).
184
+
185
+ - **Canonical behavior**:
186
+ - Fresh installs invoked with registry-path syntax (`opkg install <name>/<registry-path>`) **persist** a deduped, normalized `files` list for that dependency.
187
+ - Re-installs with an existing `files` list **reuse** that list as canonical; a TTY prompt may offer to clear it to switch back to a full install.
188
+ - Supplying a new path via CLI for a dependency that already has `files` **adds** the path (deduped) before install.
189
+ - Removing the `files` field (or setting it to `null`/empty) returns the dependency to **full-install semantics**.
190
+ - If a dependency is currently full (no `files`), a path-based install attempt is **rejected**; convert to partial by editing `package.yml` or reinstalling after removal.
191
+
192
+ - **Matching rules**:
193
+ - Paths in `files` are **exact registry paths** (no globs) and are normalized when persisted.
194
+ - These paths apply to the **root dependency only**; transitive dependencies remain governed by their own manifests.
195
+
196
+ ---
197
+
198
+ ## 7. Summary invariants
179
199
 
180
200
  - **I1 – Canonical intent**:
181
201
  - For direct dependencies, **`package.yml` is always the source of truth**.
@@ -16,12 +16,15 @@ The goal is to implement **“latest in range from local+remote”** determinist
16
16
  - **Constraint**:
17
17
  - A string understood by `version-ranges` (exact, caret, tilde, wildcard, comparison).
18
18
  - Examples: `1.2.3`, `^1.2.0`, `~2.0.1`, `>=3.0.0 <4.0.0`, `*`, `latest`.
19
+ - When a dependency entry in `package.yml` omits `version`, the effective constraint is treated as `*` (wildcard).
19
20
  - **Local versions**:
20
21
  - Semver versions discoverable via `listPackageVersions(name)` from the **local registry**.
21
- - Includes both **stable** and **WIP/pre-release** versions, e.g. `1.2.3`, `1.2.3-000fz8.a3k`.
22
+ - May include a `0.0.0` entry when the package has no `version` in `package.yml`.
23
+ - Includes both **stable** and **WIP/pre-release** semver versions, e.g. `1.2.3`, `1.2.3-000fz8.a3k`.
22
24
  - **Remote versions**:
23
25
  - Semver versions discoverable via remote metadata APIs (e.g. via `fetchRemotePackageMetadata` / registry metadata).
24
- - Also includes both **stable** and **WIP/pre-release** versions.
26
+ - May include a `0.0.0` entry when the remote package has no versioned releases yet.
27
+ - Only includes **stable** semver versions.
25
28
 
26
29
  ---
27
30
 
@@ -67,9 +70,8 @@ The goal is to implement **“latest in range from local+remote”** determinist
67
70
  - Versions are deduped by their **full semver string** (`1.2.3-000fz8.a3k` vs `1.2.3` are distinct).
68
71
 
69
72
  - **Ordering**:
70
- - For selection, versions are sorted in **descending semver order**:
71
- - Use `semver.compare(b, a)` semantics.
72
- - **Pre-releases and WIPs** are ordered according to standard semver rules.
73
+ - Use standard semver descending order for selection (`semver.compare(b, a)` semantics).
74
+ - `0.0.0` participates as a normal semver version (it will naturally sort below any higher version).
73
75
 
74
76
  ---
75
77
 
@@ -102,12 +104,12 @@ Given `available: string[]` and a parsed constraint:
102
104
 
103
105
  - **If constraint is `wildcard` / `latest`** (default behavior):
104
106
  - Use `semver.maxSatisfying(available, '*', { includePrerelease: true })` to find the **highest semver version**.
105
- - **Select the single highest version**, regardless of whether it is stable or WIP/pre-release.
107
+ - **Select the single highest semver version**, stable or WIP/pre-release (if only `0.0.0` exists, it is selected).
106
108
  - If the selected version is a pre-release/WIP, the CLI should make that explicit in its output.
107
109
 
108
110
  - **If constraint is `caret`, `tilde`, or `comparison`** (default behavior):
109
111
  - Use `semver.maxSatisfying(available, range, { includePrerelease: true })` to find the **highest satisfying version**.
110
- - **Select that version** (stable or pre-release/WIP).
112
+ - **Select that version** (stable or pre-release/WIP). `0.0.0` satisfies ranges according to standard semver rules.
111
113
  - No additional "downgrade WIP to stable" heuristic is applied; WIP/pre-release versions are first-class semver versions for resolution purposes.
112
114
 
113
115
  - **With `--stable` flag**:
@@ -0,0 +1,70 @@
1
+ # opkg login – Device Authorization Flow (RFC 8628)
2
+
3
+ ## Goals
4
+ - Add `opkg login [--profile <name>]` using OAuth 2.0 Device Authorization Grant.
5
+ - Store bearer tokens per profile; keep API-key auth backward compatible.
6
+
7
+ ## Command behavior
8
+ - Syntax: `opkg login [--profile <name>]`
9
+ - Profile: optional; defaults to `default`.
10
+ - Flow:
11
+ 1) Start device authorization → get `device_code`, `user_code`, `verification_uri`, `verification_uri_complete`, `expires_in`, `interval`.
12
+ 2) Print code/URL; attempt to open browser to `verification_uri_complete`.
13
+ 3) Poll token endpoint until success/denied/expired/timeout.
14
+ 4) On success, persist access/refresh tokens to the selected profile.
15
+ 5) On failure, show actionable error and exit non-zero.
16
+
17
+ ## HTTP interactions (backend contract)
18
+ - POST `/auth/device/authorize` (no auth):
19
+ - Body: `{ clientId: 'opkg-cli', scope?: 'openid', deviceName?: 'opkg-cli' }`
20
+ - Response: `{ device_code, user_code, verification_uri, verification_uri_complete, expires_in, interval }`
21
+ - POST `/auth/device/token` (no auth):
22
+ - Body: `{ deviceCode }`
23
+ - Success: `{ access_token, refresh_token, token_type: 'bearer', expires_in }`
24
+ - Error codes (HTTP 400): `authorization_pending`, `slow_down`, `expired_token`, `access_denied`
25
+ - POST `/auth/refresh` (no auth) for refresh flow:
26
+ - Body: `{ refreshToken }`
27
+ - Success: `{ accessToken, refreshToken }`
28
+
29
+ ## CLI storage & auth selection
30
+ - Extend `ProfileCredentials` to include `access_token`, `refresh_token`, `expires_at`, `token_type`.
31
+ - Credentials persisted in the existing profile credentials INI; preserve existing `api_key`.
32
+ - Header selection:
33
+ - Prefer non-expired access token → `Authorization: Bearer <token>`.
34
+ - If expired and refresh token present → call `/auth/refresh`, persist new pair.
35
+ - Fallback: `X-API-Key` if present.
36
+ - If none: instruct user to run `opkg login` or configure API key.
37
+
38
+ ## UX requirements
39
+ - Print user code and verification URL.
40
+ - Open browser best-effort; if it fails, user can manually visit the URL.
41
+ - Poll respecting `interval`; on `slow_down` add +5s each time.
42
+ - Time out when `expires_in` elapses; show “code expired, rerun opkg login.”
43
+ - Errors:
44
+ - `access_denied`: “Access denied. Please restart opkg login.”
45
+ - `expired_token`: “Code expired. Please rerun opkg login.”
46
+
47
+ ## Persistence details
48
+ - `expires_at` derived from `Date.now() + expires_in*1000` or JWT `exp`.
49
+ - When refreshing, keep existing `api_key` intact in the profile record.
50
+
51
+ ## Edge cases & fallbacks
52
+ - If profile missing: create credentials entry when saving tokens.
53
+ - If refresh fails: drop to API key if present; otherwise require login.
54
+ - Platform-specific browser open: `open` (mac), `start` (win), `xdg-open` (linux); ignore failures.
55
+
56
+ ## Logout command
57
+ - Syntax: `opkg logout [--profile <name>]`
58
+ - Requires stored OAuth tokens for the profile; no-op if none.
59
+ - Sends `POST /auth/logout` with bearer auth and `{ refreshToken }` body.
60
+ - On success or failure, clears local token store entry; keeps any configured API key.
61
+ - If profile resolved as direct API key usage, exit with “no OAuth session.”
62
+
63
+ ## Telemetry/logging (minimal)
64
+ - Debug log start/stop of poll, slow_down adjustments, refresh attempts.
65
+ - Do not log tokens.
66
+
67
+ ## Non-goals (future)
68
+ - Device-name flag, headless/no-browser flag.
69
+ - Multi-factor UX in CLI.
70
+
@@ -0,0 +1,60 @@
1
+ ### Canonical Universal Package Structure
2
+
3
+ This directory contains the canonical on-disk structure spec for OpenPackage packages, split into focused documents:
4
+
5
+ - **Root layout**: `package-root-layout.md` – Package directory structure and content types
6
+ - **Universal content**: `universal-content.md` – Platform-normalized content under `.openpackage/`
7
+ - **Package index**: `package-index-yml.md` – File mapping and `package.index.yml` structure
8
+ - **Registry payload and 1:1 copy rules**: `registry-payload-and-copy.md` – What gets included in packages
9
+ - **Nested packages and parent packages**: `nested-packages-and-parent-packages.md` – Multi-package workspaces
10
+
11
+ ---
12
+
13
+ #### Core Concept: Package Root
14
+
15
+ A **package root** is any directory containing `.openpackage/package.yml`. This applies to:
16
+
17
+ - **Workspace root package**: `cwd/` is the package root
18
+ - **Nested packages**: `cwd/.openpackage/packages/<name>/` is the package root
19
+ - **Registry copies**: `~/.openpackage/registry/<name>/<version>/` is the package root
20
+
21
+ All package roots have **identical internal structure**:
22
+
23
+ ```text
24
+ <package-root>/
25
+ .openpackage/
26
+ package.yml # marks this as a package
27
+ package.index.yml # install index (not in registry)
28
+ commands/ # universal content
29
+ rules/
30
+ agents/
31
+ skills/
32
+ <root-dir>/ # root-level content (outside .openpackage/)
33
+ AGENTS.md # root files
34
+ README.md
35
+ ```
36
+
37
+ ---
38
+
39
+ #### Two Types of Content
40
+
41
+ | Type | Location | Example |
42
+ |------|----------|---------|
43
+ | **Universal content** | `.openpackage/<subdir>/` | `.openpackage/commands/test.md` |
44
+ | **Root-level content** | At package root (outside `.openpackage/`) | `<dir>/helper.md`, `AGENTS.md` |
45
+
46
+ **Universal content** is mapped to platform-specific paths during install.
47
+ **Root-level content** is copied 1:1 without transformation.
48
+
49
+ ---
50
+
51
+ #### Design Goal
52
+
53
+ A package directory can be **moved or copied 1:1** between:
54
+
55
+ - Workspace root packages (`cwd/`)
56
+ - Nested workspace packages (`cwd/.openpackage/packages/<name>/`)
57
+ - Local registry copies (`~/.openpackage/registry/<name>/<version>/`)
58
+
59
+ …while preserving the same internal layout and invariants.
60
+
@@ -0,0 +1,79 @@
1
+ ### Nested Packages and Parent Packages
2
+
3
+ #### Workspace Structure with Nested Packages
4
+
5
+ ```text
6
+ <workspace-root>/ # root package (package root = cwd/)
7
+ .openpackage/
8
+ package.yml # root package manifest
9
+ package.index.yml # root package index
10
+ commands/ # root package universal content
11
+ shared-command.md
12
+ rules/
13
+ shared-rule.md
14
+ <root-dir>/ # root package root-level content (any directory)
15
+ workspace-helper.md
16
+ AGENTS.md # root package root file
17
+ packages/ # nested packages directory (workspace root only)
18
+ alpha/ # nested package (package root = .openpackage/packages/alpha/)
19
+ .openpackage/
20
+ package.yml
21
+ package.index.yml
22
+ commands/
23
+ alpha-command.md
24
+ <root-dir>/ # nested package root-level content
25
+ alpha-helper.md
26
+ beta/ # nested package (package root = .openpackage/packages/beta/)
27
+ .openpackage/
28
+ package.yml
29
+ package.index.yml
30
+ rules/
31
+ beta-rule.md
32
+ ```
33
+
34
+ ---
35
+
36
+ #### Key Rules
37
+
38
+ - Each `packages/<name>/` directory is its **own canonical package root**, with:
39
+ - Its own `.openpackage/package.yml` (marks it as a package)
40
+ - Its own `.openpackage/` content directory
41
+ - Its own root-level content (outside `.openpackage/`)
42
+
43
+ - The **parent root package never inlines** `packages/<name>/` into its own payload.
44
+
45
+ - Registry entries for `alpha` and `beta` are created **independently** from their respective package roots.
46
+
47
+ - **Only the workspace root package** can have a `packages/` directory. Nested packages cannot have further nested packages.
48
+
49
+ ---
50
+
51
+ #### Package Root Locations
52
+
53
+ | Package Type | Package Root Path |
54
+ |--------------|-------------------|
55
+ | Workspace root | `cwd/` |
56
+ | Nested `alpha` | `cwd/.openpackage/packages/alpha/` |
57
+ | Nested `beta` | `cwd/.openpackage/packages/beta/` |
58
+
59
+ ---
60
+
61
+ #### Identical Internal Structure
62
+
63
+ Both root and nested packages have **identical internal structure**:
64
+
65
+ ```text
66
+ <package-root>/
67
+ .openpackage/
68
+ package.yml
69
+ package.index.yml
70
+ <universal-subdirs>/
71
+ <root-level-content>/
72
+ <root-files>
73
+ ```
74
+
75
+ This uniformity ensures packages can be:
76
+ - Moved between workspace root and nested locations
77
+ - Copied to/from registry without structural changes
78
+ - Processed by the same code paths regardless of location
79
+