opkg 0.5.0 → 0.6.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 (272) hide show
  1. package/README.md +49 -8
  2. package/dist/commands/add.js +11 -276
  3. package/dist/commands/add.js.map +1 -1
  4. package/dist/commands/init.js +73 -145
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/install.js +26 -668
  7. package/dist/commands/install.js.map +1 -1
  8. package/dist/commands/pack.js +10 -137
  9. package/dist/commands/pack.js.map +1 -1
  10. package/dist/commands/push.js +14 -8
  11. package/dist/commands/push.js.map +1 -1
  12. package/dist/commands/save.js +12 -167
  13. package/dist/commands/save.js.map +1 -1
  14. package/dist/commands/status.js +2 -2
  15. package/dist/commands/status.js.map +1 -1
  16. package/dist/commands/uninstall.js +5 -5
  17. package/dist/commands/uninstall.js.map +1 -1
  18. package/dist/constants/index.js +18 -45
  19. package/dist/constants/index.js.map +1 -1
  20. package/dist/constants/workspace.js +9 -0
  21. package/dist/constants/workspace.js.map +1 -0
  22. package/dist/core/add/add-conflict-handler.js +68 -0
  23. package/dist/core/add/add-conflict-handler.js.map +1 -0
  24. package/dist/core/add/add-pipeline.js +137 -0
  25. package/dist/core/add/add-pipeline.js.map +1 -0
  26. package/dist/core/add/package-index-updater.js +62 -33
  27. package/dist/core/add/package-index-updater.js.map +1 -1
  28. package/dist/core/add/platform-path-transformer.js +47 -0
  29. package/dist/core/add/platform-path-transformer.js.map +1 -0
  30. package/dist/core/add/source-collector.js +57 -0
  31. package/dist/core/add/source-collector.js.map +1 -0
  32. package/dist/core/dependency-resolver.js +3 -1
  33. package/dist/core/dependency-resolver.js.map +1 -1
  34. package/dist/core/directory.js +2 -2
  35. package/dist/core/directory.js.map +1 -1
  36. package/dist/core/discovery/file-discovery.js +55 -54
  37. package/dist/core/discovery/file-discovery.js.map +1 -1
  38. package/dist/core/discovery/platform-files-discovery.js +32 -17
  39. package/dist/core/discovery/platform-files-discovery.js.map +1 -1
  40. package/dist/core/install/bulk-install-pipeline.js +199 -0
  41. package/dist/core/install/bulk-install-pipeline.js.map +1 -0
  42. package/dist/core/install/canonical-plan.js +123 -0
  43. package/dist/core/install/canonical-plan.js.map +1 -0
  44. package/dist/core/install/dry-run.js +2 -2
  45. package/dist/core/install/dry-run.js.map +1 -1
  46. package/dist/core/install/index.js +3 -0
  47. package/dist/core/install/index.js.map +1 -0
  48. package/dist/core/install/install-errors.js +41 -0
  49. package/dist/core/install/install-errors.js.map +1 -0
  50. package/dist/core/install/install-flow.js +2 -5
  51. package/dist/core/install/install-flow.js.map +1 -1
  52. package/dist/core/install/install-pipeline.js +228 -0
  53. package/dist/core/install/install-pipeline.js.map +1 -0
  54. package/dist/core/install/install-reporting.js +99 -0
  55. package/dist/core/install/install-reporting.js.map +1 -0
  56. package/dist/core/install/platform-resolution.js +6 -6
  57. package/dist/core/install/platform-resolution.js.map +1 -1
  58. package/dist/core/install/remote-flow.js +67 -1
  59. package/dist/core/install/remote-flow.js.map +1 -1
  60. package/dist/core/openpackage.js +16 -8
  61. package/dist/core/openpackage.js.map +1 -1
  62. package/dist/core/package-context.js +246 -0
  63. package/dist/core/package-context.js.map +1 -0
  64. package/dist/core/package.js +3 -2
  65. package/dist/core/package.js.map +1 -1
  66. package/dist/core/platforms.js +126 -217
  67. package/dist/core/platforms.js.map +1 -1
  68. package/dist/core/registry/registry-rename.js +2 -1
  69. package/dist/core/registry/registry-rename.js.map +1 -1
  70. package/dist/core/registry.js +10 -3
  71. package/dist/core/registry.js.map +1 -1
  72. package/dist/core/remote-pull.js +2 -1
  73. package/dist/core/remote-pull.js.map +1 -1
  74. package/dist/core/save/constants.js +4 -0
  75. package/dist/core/save/constants.js.map +1 -1
  76. package/dist/core/save/name-resolution.js +31 -0
  77. package/dist/core/save/name-resolution.js.map +1 -0
  78. package/dist/core/save/package-detection.js +147 -0
  79. package/dist/core/save/package-detection.js.map +1 -0
  80. package/dist/core/save/package-saver.js +46 -43
  81. package/dist/core/save/package-saver.js.map +1 -1
  82. package/dist/core/save/package-yml-generator.js +50 -71
  83. package/dist/core/save/package-yml-generator.js.map +1 -1
  84. package/dist/core/save/root-save-candidates.js.map +1 -1
  85. package/dist/core/save/save-candidate-loader.js +89 -0
  86. package/dist/core/save/save-candidate-loader.js.map +1 -0
  87. package/dist/core/save/save-conflict-resolution.js +72 -410
  88. package/dist/core/save/save-conflict-resolution.js.map +1 -1
  89. package/dist/core/save/save-conflict-resolver.js +277 -0
  90. package/dist/core/save/save-conflict-resolver.js.map +1 -0
  91. package/dist/core/save/save-pipeline.js +151 -0
  92. package/dist/core/save/save-pipeline.js.map +1 -0
  93. package/dist/core/save/save-types.js +2 -0
  94. package/dist/core/save/save-types.js.map +1 -0
  95. package/dist/core/save/save-yml-resolution.js +77 -39
  96. package/dist/core/save/save-yml-resolution.js.map +1 -1
  97. package/dist/core/save/workspace-rename.js +6 -6
  98. package/dist/core/save/workspace-rename.js.map +1 -1
  99. package/dist/core/scoping/package-scoping.js +13 -1
  100. package/dist/core/scoping/package-scoping.js.map +1 -1
  101. package/dist/core/status/status-file-discovery.js +12 -30
  102. package/dist/core/status/status-file-discovery.js.map +1 -1
  103. package/dist/core/sync/platform-sync.js +7 -4
  104. package/dist/core/sync/platform-sync.js.map +1 -1
  105. package/dist/core/sync/root-files-sync.js +59 -1
  106. package/dist/core/sync/root-files-sync.js.map +1 -1
  107. package/dist/core/uninstall/uninstall-file-discovery.js +1 -2
  108. package/dist/core/uninstall/uninstall-file-discovery.js.map +1 -1
  109. package/dist/types/index.js.map +1 -1
  110. package/dist/utils/file-processing.js +5 -58
  111. package/dist/utils/file-processing.js.map +1 -1
  112. package/dist/utils/index-based-installer.js +15 -33
  113. package/dist/utils/index-based-installer.js.map +1 -1
  114. package/dist/utils/install-file-discovery.js +3 -3
  115. package/dist/utils/install-file-discovery.js.map +1 -1
  116. package/dist/utils/install-orchestrator.js +21 -21
  117. package/dist/utils/install-orchestrator.js.map +1 -1
  118. package/dist/utils/jsonc.js +44 -0
  119. package/dist/utils/jsonc.js.map +1 -0
  120. package/dist/utils/package-copy.js +199 -0
  121. package/dist/utils/package-copy.js.map +1 -0
  122. package/dist/utils/package-filters.js +125 -0
  123. package/dist/utils/package-filters.js.map +1 -0
  124. package/dist/utils/package-index-yml.js +15 -10
  125. package/dist/utils/package-index-yml.js.map +1 -1
  126. package/dist/utils/package-installation.js +4 -113
  127. package/dist/utils/package-installation.js.map +1 -1
  128. package/dist/utils/package-local-files.js +2 -35
  129. package/dist/utils/package-local-files.js.map +1 -1
  130. package/dist/utils/package-management.js +59 -37
  131. package/dist/utils/package-management.js.map +1 -1
  132. package/dist/utils/package-yml.js +24 -0
  133. package/dist/utils/package-yml.js.map +1 -1
  134. package/dist/utils/path-normalization.js +8 -53
  135. package/dist/utils/path-normalization.js.map +1 -1
  136. package/dist/utils/paths.js +17 -9
  137. package/dist/utils/paths.js.map +1 -1
  138. package/dist/utils/platform-file.js +16 -59
  139. package/dist/utils/platform-file.js.map +1 -1
  140. package/dist/utils/platform-mapper.js +29 -41
  141. package/dist/utils/platform-mapper.js.map +1 -1
  142. package/dist/utils/platform-specific-paths.js.map +1 -1
  143. package/dist/utils/platform-utils.js +28 -139
  144. package/dist/utils/platform-utils.js.map +1 -1
  145. package/dist/utils/platform-yaml-merge.js +13 -6
  146. package/dist/utils/platform-yaml-merge.js.map +1 -1
  147. package/dist/utils/registry-entry-filter.js +38 -24
  148. package/dist/utils/registry-entry-filter.js.map +1 -1
  149. package/dist/utils/registry-paths.js +10 -0
  150. package/dist/utils/registry-paths.js.map +1 -0
  151. package/dist/utils/root-file-installer.js +19 -0
  152. package/dist/utils/root-file-installer.js.map +1 -1
  153. package/dist/utils/root-file-registry.js.map +1 -1
  154. package/package.json +3 -2
  155. package/platforms.jsonc +178 -0
  156. package/specs/package/README.md +60 -0
  157. package/specs/package/nested-packages-and-parent-packages.md +79 -0
  158. package/specs/package/package-index-yml.md +171 -0
  159. package/specs/package/package-root-layout.md +78 -0
  160. package/specs/package/registry-payload-and-copy.md +77 -0
  161. package/specs/package/universal-content.md +144 -0
  162. package/specs/platforms.md +193 -0
  163. package/specs/save/README.md +40 -0
  164. package/specs/save/save-conflict-resolution.md +146 -0
  165. package/specs/save/save-file-discovery.md +101 -0
  166. package/specs/save/save-frontmatter-overrides.md +81 -0
  167. package/specs/save/save-modes-inputs.md +53 -0
  168. package/specs/save/save-naming-scoping.md +93 -0
  169. package/specs/save/save-package-detection.md +60 -0
  170. package/specs/save/save-registry-sync.md +126 -0
  171. package/dist/commands/release.js +0 -33
  172. package/dist/commands/release.js.map +0 -1
  173. package/dist/commands/tag.js +0 -311
  174. package/dist/commands/tag.js.map +0 -1
  175. package/dist/commands/update.js +0 -30
  176. package/dist/commands/update.js.map +0 -1
  177. package/dist/core/add/formula-index-updater.js +0 -290
  178. package/dist/core/add/formula-index-updater.js.map +0 -1
  179. package/dist/core/discovery/ai-files-discovery.js +0 -2
  180. package/dist/core/discovery/ai-files-discovery.js.map +0 -1
  181. package/dist/core/discovery/formula-files-discovery.js +0 -14
  182. package/dist/core/discovery/formula-files-discovery.js.map +0 -1
  183. package/dist/core/discovery/index-files-discovery.js +0 -91
  184. package/dist/core/discovery/index-files-discovery.js.map +0 -1
  185. package/dist/core/discovery/md-files-discovery.js +0 -82
  186. package/dist/core/discovery/md-files-discovery.js.map +0 -1
  187. package/dist/core/discovery/package-files-discovery.js +0 -14
  188. package/dist/core/discovery/package-files-discovery.js.map +0 -1
  189. package/dist/core/discovery/platform-discovery.js +0 -84
  190. package/dist/core/discovery/platform-discovery.js.map +0 -1
  191. package/dist/core/discovery/root-files-discovery.js +0 -2
  192. package/dist/core/discovery/root-files-discovery.js.map +0 -1
  193. package/dist/core/formula.js +0 -170
  194. package/dist/core/formula.js.map +0 -1
  195. package/dist/core/git-registry.js +0 -46
  196. package/dist/core/git-registry.js.map +0 -1
  197. package/dist/core/groundzero.js +0 -277
  198. package/dist/core/groundzero.js.map +0 -1
  199. package/dist/core/install/scenario.js +0 -11
  200. package/dist/core/install/scenario.js.map +0 -1
  201. package/dist/core/package-sync.js +0 -219
  202. package/dist/core/package-sync.js.map +0 -1
  203. package/dist/core/save/formula-file-generator.js +0 -167
  204. package/dist/core/save/formula-file-generator.js.map +0 -1
  205. package/dist/core/save/formula-saver.js +0 -52
  206. package/dist/core/save/formula-saver.js.map +0 -1
  207. package/dist/core/save/formula-yml-generator.js +0 -89
  208. package/dist/core/save/formula-yml-generator.js.map +0 -1
  209. package/dist/core/save/formula-yml-versioning.js +0 -108
  210. package/dist/core/save/formula-yml-versioning.js.map +0 -1
  211. package/dist/core/save/generic-file-sync.js +0 -38
  212. package/dist/core/save/generic-file-sync.js.map +0 -1
  213. package/dist/core/save/md-files-sync.js +0 -33
  214. package/dist/core/save/md-files-sync.js.map +0 -1
  215. package/dist/core/save/package-yml-versioning.js +0 -108
  216. package/dist/core/save/package-yml-versioning.js.map +0 -1
  217. package/dist/core/save/platform-sync.js +0 -95
  218. package/dist/core/save/platform-sync.js.map +0 -1
  219. package/dist/core/save/root-files-sync.js +0 -140
  220. package/dist/core/save/root-files-sync.js.map +0 -1
  221. package/dist/core/save/save-candidate-types.js +0 -2
  222. package/dist/core/save/save-candidate-types.js.map +0 -1
  223. package/dist/core/save/save-conflict-types.js +0 -2
  224. package/dist/core/save/save-conflict-types.js.map +0 -1
  225. package/dist/core/save/save-file-discovery.js +0 -5
  226. package/dist/core/save/save-file-discovery.js.map +0 -1
  227. package/dist/core/status-file-discovery.js +0 -175
  228. package/dist/core/status-file-discovery.js.map +0 -1
  229. package/dist/utils/discovery/file-processing.js +0 -156
  230. package/dist/utils/discovery/file-processing.js.map +0 -1
  231. package/dist/utils/discovery/formula-discovery.js +0 -211
  232. package/dist/utils/discovery/formula-discovery.js.map +0 -1
  233. package/dist/utils/discovery/platform-discovery.js +0 -2
  234. package/dist/utils/discovery/platform-discovery.js.map +0 -1
  235. package/dist/utils/formula-discovery.js +0 -102
  236. package/dist/utils/formula-discovery.js.map +0 -1
  237. package/dist/utils/formula-index-yml.js +0 -122
  238. package/dist/utils/formula-index-yml.js.map +0 -1
  239. package/dist/utils/formula-installation.js +0 -110
  240. package/dist/utils/formula-installation.js.map +0 -1
  241. package/dist/utils/formula-local-files.js +0 -38
  242. package/dist/utils/formula-local-files.js.map +0 -1
  243. package/dist/utils/formula-management.js +0 -191
  244. package/dist/utils/formula-management.js.map +0 -1
  245. package/dist/utils/formula-name.js +0 -97
  246. package/dist/utils/formula-name.js.map +0 -1
  247. package/dist/utils/formula-versioning.js +0 -109
  248. package/dist/utils/formula-versioning.js.map +0 -1
  249. package/dist/utils/formula-yml.js +0 -82
  250. package/dist/utils/formula-yml.js.map +0 -1
  251. package/dist/utils/git.js +0 -54
  252. package/dist/utils/git.js.map +0 -1
  253. package/dist/utils/id-based-discovery.js +0 -126
  254. package/dist/utils/id-based-discovery.js.map +0 -1
  255. package/dist/utils/id-based-installer.js +0 -249
  256. package/dist/utils/id-based-installer.js.map +0 -1
  257. package/dist/utils/index-yml-based-installer.js +0 -375
  258. package/dist/utils/index-yml-based-installer.js.map +0 -1
  259. package/dist/utils/index-yml.js +0 -124
  260. package/dist/utils/index-yml.js.map +0 -1
  261. package/dist/utils/md-frontmatter.js +0 -3
  262. package/dist/utils/md-frontmatter.js.map +0 -1
  263. package/dist/utils/package-link-yml.js +0 -92
  264. package/dist/utils/package-link-yml.js.map +0 -1
  265. package/dist/utils/platform-discovery.js +0 -2
  266. package/dist/utils/platform-discovery.js.map +0 -1
  267. package/dist/utils/platform-frontmatter-split.js +0 -15
  268. package/dist/utils/platform-frontmatter-split.js.map +0 -1
  269. package/dist/utils/timestamp-encoder.js +0 -13
  270. package/dist/utils/timestamp-encoder.js.map +0 -1
  271. package/dist/utils/wip-versioning.js +0 -24
  272. package/dist/utils/wip-versioning.js.map +0 -1
@@ -1,311 +0,0 @@
1
- import { basename, extname, join } from 'path';
2
- import * as yaml from 'js-yaml';
3
- import { safePrompts } from '../utils/prompts.js';
4
- import { updateMarkdownWithFormulaFrontmatter, parseMarkdownFrontmatter } from '../utils/md-frontmatter.js';
5
- import { readTextFile, writeTextFile, exists, isDirectory, listFiles } from '../utils/fs.js';
6
- import { withErrorHandling, ValidationError, UserCancellationError } from '../utils/errors.js';
7
- import { logger } from '../utils/logger.js';
8
- import { FILE_PATTERNS } from '../constants/index.js';
9
- import { isRootFile } from '../core/sync/root-files-sync.js';
10
- import { addFormulaToRootFile } from '../utils/root-file-operations.js';
11
- import { buildIndexYmlContent } from '../utils/index-yml.js';
12
- /**
13
- * Prompt user for formula override decision
14
- */
15
- async function promptFormulaOverride(filePath, existingFormula, newFormula) {
16
- const fileName = basename(filePath);
17
- const response = await safePrompts({
18
- type: 'select',
19
- name: 'choice',
20
- message: `File '${fileName}' already has formula '${existingFormula}'. How would you like to proceed?`,
21
- choices: [
22
- {
23
- title: 'Skip - Keep existing formula',
24
- value: 'skip',
25
- description: `Keep existing formula '${existingFormula}'`
26
- },
27
- {
28
- title: `Overwrite - Replace with '${newFormula}'`,
29
- value: 'overwrite',
30
- description: `Replace with formula '${newFormula}'`
31
- }
32
- ],
33
- hint: 'Use arrow keys to navigate, Enter to select'
34
- });
35
- return response.choice;
36
- }
37
- /**
38
- * Validate that the path is a markdown file
39
- */
40
- function isMarkdownFile(filePath) {
41
- const ext = extname(filePath).toLowerCase();
42
- return ext === FILE_PATTERNS.MD_FILES || ext === FILE_PATTERNS.MDC_FILES;
43
- }
44
- /**
45
- * Read and parse index.yml file
46
- */
47
- async function readIndexYml(filePath) {
48
- try {
49
- const content = await readTextFile(filePath);
50
- const parsed = yaml.load(content);
51
- return parsed || null;
52
- }
53
- catch (error) {
54
- logger.warn(`Failed to parse index.yml at ${filePath}: ${error}`);
55
- return null;
56
- }
57
- }
58
- /**
59
- * Write formula marker to index.yml file
60
- */
61
- async function writeIndexYml(filePath, marker) {
62
- const yamlContent = buildIndexYmlContent(marker);
63
- await writeTextFile(filePath, yamlContent);
64
- }
65
- /**
66
- * Get all markdown files from the given path
67
- */
68
- async function getMarkdownFiles(targetPath) {
69
- const pathExists = await exists(targetPath);
70
- if (!pathExists) {
71
- throw new ValidationError(`Path does not exist: ${targetPath}`);
72
- }
73
- const isDir = await isDirectory(targetPath);
74
- if (isDir) {
75
- // Directory: get all markdown files in immediate children
76
- const files = await listFiles(targetPath);
77
- const markdownFiles = files
78
- .filter(isMarkdownFile)
79
- .map(file => `${targetPath}/${file}`);
80
- if (markdownFiles.length === 0) {
81
- throw new ValidationError(`No markdown files found in directory: ${targetPath}`);
82
- }
83
- return markdownFiles;
84
- }
85
- else {
86
- // Single file: validate it's a markdown file
87
- if (!isMarkdownFile(targetPath)) {
88
- throw new ValidationError(`File is not a markdown file: ${targetPath}`);
89
- }
90
- return [targetPath];
91
- }
92
- }
93
- /**
94
- * Process a single markdown file
95
- */
96
- async function processMarkdownFile(filePath, formulaName) {
97
- logger.debug(`Processing file: ${filePath}`);
98
- try {
99
- const content = await readTextFile(filePath);
100
- const frontmatter = parseMarkdownFrontmatter(content);
101
- const existingFormulaName = frontmatter?.formula?.name;
102
- if (existingFormulaName) {
103
- if (existingFormulaName === formulaName) {
104
- // Same formula: update without prompt to ensure latest formatting
105
- const updatedContent = updateMarkdownWithFormulaFrontmatter(content, { name: formulaName });
106
- await writeTextFile(filePath, updatedContent);
107
- console.log(`✓ Updated ${basename(filePath)} (same formula, refreshed formatting)`);
108
- return { processed: true };
109
- }
110
- else {
111
- // Different formula: prompt for override
112
- const decision = await promptFormulaOverride(filePath, existingFormulaName, formulaName);
113
- if (decision === 'skip') {
114
- console.log(`⊝ Skipped ${basename(filePath)} (keeping existing formula '${existingFormulaName}')`);
115
- return { processed: false, reason: 'user_skipped' };
116
- }
117
- else {
118
- // Overwrite
119
- const updatedContent = updateMarkdownWithFormulaFrontmatter(content, { name: formulaName });
120
- await writeTextFile(filePath, updatedContent);
121
- console.log(`✓ Updated ${basename(filePath)} (overrode '${existingFormulaName}' with '${formulaName}')`);
122
- return { processed: true };
123
- }
124
- }
125
- }
126
- else {
127
- // No existing formula: add new frontmatter
128
- const updatedContent = updateMarkdownWithFormulaFrontmatter(content, { name: formulaName });
129
- await writeTextFile(filePath, updatedContent);
130
- console.log(`✓ Added formula frontmatter to ${basename(filePath)}`);
131
- return { processed: true };
132
- }
133
- }
134
- catch (error) {
135
- if (error instanceof UserCancellationError) {
136
- throw error; // Re-throw to be handled by withErrorHandling
137
- }
138
- logger.error(`Failed to process file: ${filePath}`, { error });
139
- console.log(`✗ Failed to process ${basename(filePath)}: ${error}`);
140
- return { processed: false, reason: 'error' };
141
- }
142
- }
143
- /**
144
- * Handle adding formula to a directory by operating on index.yml
145
- */
146
- async function tagFormulaToDirectory(formulaName, targetPath) {
147
- const indexPath = join(targetPath, FILE_PATTERNS.INDEX_YML);
148
- if (await exists(indexPath)) {
149
- const parsed = await readIndexYml(indexPath);
150
- const existingName = parsed?.formula?.name;
151
- if (existingName === formulaName) {
152
- // Same formula: update without prompt to ensure latest formatting
153
- await writeIndexYml(indexPath, {
154
- formula: {
155
- name: existingName,
156
- id: parsed?.formula?.id,
157
- platformSpecific: parsed?.formula?.platformSpecific
158
- }
159
- });
160
- console.log(`✓ Updated index.yml (same formula, refreshed formatting)`);
161
- return {
162
- success: true,
163
- filesProcessed: 1,
164
- filesSkipped: 0,
165
- data: {
166
- formulaName,
167
- targetPath,
168
- indexPath
169
- }
170
- };
171
- }
172
- if (existingName && existingName !== formulaName) {
173
- // Different formula: prompt for override
174
- const decision = await promptFormulaOverride(indexPath, existingName, formulaName);
175
- if (decision === 'skip') {
176
- console.log(`⊝ Skipped index.yml (keeping existing formula '${existingName}')`);
177
- return {
178
- success: true,
179
- filesProcessed: 0,
180
- filesSkipped: 1,
181
- data: {
182
- formulaName,
183
- targetPath,
184
- indexPath
185
- }
186
- };
187
- }
188
- else {
189
- // Overwrite
190
- await writeIndexYml(indexPath, {
191
- formula: {
192
- name: formulaName,
193
- id: parsed?.formula?.id,
194
- platformSpecific: parsed?.formula?.platformSpecific
195
- }
196
- });
197
- console.log(`✓ Updated index.yml (overrode '${existingName}' with '${formulaName}')`);
198
- return {
199
- success: true,
200
- filesProcessed: 1,
201
- filesSkipped: 0,
202
- data: {
203
- formulaName,
204
- targetPath,
205
- indexPath
206
- }
207
- };
208
- }
209
- }
210
- }
211
- // No existing index.yml: create new one
212
- await writeIndexYml(indexPath, { formula: { name: formulaName } });
213
- console.log(`✓ Created index.yml with formula '${formulaName}'`);
214
- return {
215
- success: true,
216
- filesProcessed: 1,
217
- filesSkipped: 0,
218
- data: {
219
- formulaName,
220
- targetPath,
221
- indexPath
222
- }
223
- };
224
- }
225
- /**
226
- * Main tag command implementation
227
- */
228
- async function tagFormulaCommand(formulaName, targetPath, options = {}) {
229
- try {
230
- logger.info(`Tagging formula '${formulaName}' to: ${targetPath}`);
231
- // Check if target is a single root file
232
- const pathExists = await exists(targetPath);
233
- const isDir = pathExists && await isDirectory(targetPath);
234
- if (!isDir && isRootFile(targetPath)) {
235
- // Handle single root file
236
- const result = await addFormulaToRootFile(targetPath, formulaName);
237
- return {
238
- success: true,
239
- filesProcessed: result.processed ? 1 : 0,
240
- filesSkipped: result.processed ? 0 : 1,
241
- data: {
242
- formulaName,
243
- targetPath,
244
- filesProcessed: result.processed ? 1 : 0,
245
- filesSkipped: result.processed ? 0 : 1,
246
- isRootFile: true
247
- }
248
- };
249
- }
250
- if (isDir) {
251
- // Handle directory: operate on index.yml only
252
- return await tagFormulaToDirectory(formulaName, targetPath);
253
- }
254
- // Handle regular markdown files (existing logic for single files)
255
- const markdownFiles = await getMarkdownFiles(targetPath);
256
- // Show what we're about to process
257
- console.log(`Found ${markdownFiles.length} markdown file(s) in: ${targetPath}`);
258
- let filesProcessed = 0;
259
- let filesSkipped = 0;
260
- // Process each file
261
- for (let i = 0; i < markdownFiles.length; i++) {
262
- const filePath = markdownFiles[i];
263
- if (markdownFiles.length > 1) {
264
- console.log(`\nProcessing file ${i + 1} of ${markdownFiles.length}: ${basename(filePath)}`);
265
- }
266
- const result = await processMarkdownFile(filePath, formulaName);
267
- if (result.processed) {
268
- filesProcessed++;
269
- }
270
- else {
271
- filesSkipped++;
272
- }
273
- }
274
- return {
275
- success: true,
276
- filesProcessed,
277
- filesSkipped,
278
- data: {
279
- formulaName,
280
- targetPath,
281
- filesProcessed,
282
- filesSkipped
283
- }
284
- };
285
- }
286
- catch (error) {
287
- if (error instanceof UserCancellationError) {
288
- throw error; // Re-throw to be handled by withErrorHandling
289
- }
290
- logger.error('Failed to tag formula to files', { error, formulaName, targetPath });
291
- throw error instanceof Error ? error : new Error(`Tag operation failed: ${error}`);
292
- }
293
- }
294
- /**
295
- * Setup the tag command
296
- */
297
- export function setupTagCommand(program) {
298
- program
299
- .command('tag')
300
- .alias('t')
301
- .argument('<formula-name>', 'formula name to add to markdown files')
302
- .argument('<path>', 'path to markdown file or directory containing markdown files')
303
- .description('Add formula frontmatter to markdown files')
304
- .action(withErrorHandling(async (formulaName, path, options) => {
305
- const result = await tagFormulaCommand(formulaName, path, options);
306
- if (!result.success) {
307
- throw new Error(result.error || 'Tag operation failed');
308
- }
309
- }));
310
- }
311
- //# sourceMappingURL=tag.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tag.js","sourceRoot":"","sources":["../../src/commands/tag.ts"],"names":[],"mappings":"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"}
@@ -1,30 +0,0 @@
1
- import { updatePackage } from '../core/package-sync.js';
2
- import { parsePackageInput } from '../utils/package-name.js';
3
- import { withErrorHandling } from '../utils/errors.js';
4
- async function handleUpdateCommand(packageInput, options) {
5
- const cwd = process.cwd();
6
- const { name } = parsePackageInput(packageInput);
7
- console.log(`🔄 Updating workspace clone for ${name}`);
8
- const result = await updatePackage({
9
- cwd,
10
- packageName: name,
11
- ffOnly: options.ffOnly ?? true
12
- });
13
- const strategyLabel = (options.ffOnly ?? true) ? 'fast-forward only' : 'allow merge';
14
- console.log('\n✓ Workspace updated from registry');
15
- console.log(` • Path: ${result.workspacePath}`);
16
- console.log(` • Branch: ${result.branch}`);
17
- console.log(` • Merge strategy: ${strategyLabel}`);
18
- }
19
- export function setupUpdateCommand(program) {
20
- program
21
- .command('update')
22
- .description('Update a workspace package from the local registry main branch.')
23
- .argument('<package-name>', 'package name to update')
24
- .option('--allow-merge', 'allow merge commits if fast-forward is not possible', false)
25
- .action(withErrorHandling(async (packageName, cmdOptions) => {
26
- const ffOnly = !(cmdOptions.allowMerge ?? false);
27
- await handleUpdateCommand(packageName, { ffOnly });
28
- }));
29
- }
30
- //# sourceMappingURL=update.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAMvD,KAAK,UAAU,mBAAmB,CAAC,YAAoB,EAAE,OAA6B;IACpF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAEjD,OAAO,CAAC,GAAG,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC;QACjC,GAAG;QACH,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;KAC/B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,uBAAuB,aAAa,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,iEAAiE,CAAC;SAC9E,QAAQ,CAAC,gBAAgB,EAAE,wBAAwB,CAAC;SACpD,MAAM,CAAC,eAAe,EAAE,qDAAqD,EAAE,KAAK,CAAC;SACrF,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,WAAmB,EAAE,UAAoC,EAAE,EAAE;QAC5F,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC;QACjD,MAAM,mBAAmB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
@@ -1,290 +0,0 @@
1
- import { dirname, join } from 'path';
2
- import { exists } from '../../utils/fs.js';
3
- import { logger } from '../../utils/logger.js';
4
- import { parseFormulaYml } from '../../utils/formula-yml.js';
5
- import { getFormulaIndexPath, readFormulaIndex, writeFormulaIndex, sortMapping, pruneNestedDirectories } from '../../utils/formula-index-yml.js';
6
- import { buildIndexMappingForFormulaFiles, loadOtherFormulaIndexes } from '../../utils/index-based-installer.js';
7
- import { getLocalFormulaDir } from '../../utils/paths.js';
8
- import { PLATFORM_DIRS } from '../../constants/index.js';
9
- import { parseUniversalPath } from '../../utils/platform-file.js';
10
- import { mapUniversalToPlatform } from '../../utils/platform-mapper.js';
11
- import { isPlatformId } from '../platforms.js';
12
- import { normalizeRegistryPath, isRootRegistryPath, isSkippableRegistryPath, isAllowedRegistryPath } from '../../utils/registry-entry-filter.js';
13
- /**
14
- * Compute the directory key (registry side) to collapse file mappings under.
15
- * Mirrors the grouping behavior used by install/index mapping logic.
16
- */
17
- export function computeDirKeyFromRegistryPath(registryPath) {
18
- const normalized = registryPath.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
19
- const parts = normalized.split('/');
20
- if (parts.length <= 1)
21
- return '';
22
- const universal = new Set(['ai', 'rules', 'commands', 'agents', 'skills']);
23
- if (universal.has(parts[0])) {
24
- if (parts.length >= 2)
25
- return `${parts[0]}/${parts[1]}/`;
26
- return `${parts[0]}/`;
27
- }
28
- const idx = normalized.lastIndexOf('/');
29
- if (idx === -1)
30
- return '';
31
- return normalized.substring(0, idx + 1);
32
- }
33
- /**
34
- * Prune stale keys from previous index that no longer exist in current files.
35
- * File keys are kept only if the exact file path exists in currentFiles.
36
- * Directory keys are kept only if at least one current file path starts with that directory prefix.
37
- */
38
- function pruneStaleKeysByCurrentFiles(previous, currentFiles) {
39
- // Normalize to forward slashes for consistent comparisons
40
- const normalizedCurrent = currentFiles.map(p => p.replace(/\\/g, '/'));
41
- const currentSet = new Set(normalizedCurrent);
42
- const result = {};
43
- for (const [rawKey, values] of Object.entries(previous)) {
44
- const key = rawKey.replace(/\\/g, '/');
45
- if (key.endsWith('/')) {
46
- // Keep dir keys only if at least one current file is under that directory
47
- if (normalizedCurrent.some(p => p.startsWith(key))) {
48
- result[key] = values;
49
- }
50
- }
51
- else {
52
- // Keep file keys only if that exact file still exists
53
- if (currentSet.has(key)) {
54
- result[key] = values;
55
- }
56
- }
57
- }
58
- return result;
59
- }
60
- /**
61
- * Merge new mapping updates with existing index, respecting existing entries.
62
- * For directory keys (ending with /), prunes redundant nested child directories
63
- * to prevent adding subdirectories when a parent directory already exists.
64
- */
65
- function mergeMappingsRespectingExisting(previous, updates) {
66
- const merged = { ...previous };
67
- for (const [key, newVals] of Object.entries(updates)) {
68
- const prevVals = merged[key] || [];
69
- // Union + de-dupe
70
- const union = Array.from(new Set([...prevVals, ...newVals]));
71
- // For directory keys, prune nested child dirs if parent is present
72
- if (key.endsWith('/')) {
73
- merged[key] = pruneNestedDirectories(union).sort();
74
- }
75
- else {
76
- merged[key] = union.sort();
77
- }
78
- }
79
- return sortMapping(merged);
80
- }
81
- /**
82
- * Collapse file entries into directory keys when appropriate.
83
- * Groups file entries by their directory key and automatically collapses them into dir key entries.
84
- * This is universally applied to all eligible groups to ensure consistent index structure.
85
- */
86
- function collapseFileEntriesToDirKeys(mapping) {
87
- const collapsed = {};
88
- const dirKeyGroups = new Map();
89
- // Group file entries by their directory key
90
- for (const [key, values] of Object.entries(mapping)) {
91
- // Skip directory keys (they already end with /)
92
- if (key.endsWith('/')) {
93
- collapsed[key] = values;
94
- continue;
95
- }
96
- const dirKey = computeDirKeyFromRegistryPath(key);
97
- if (!dirKey) {
98
- // No dir key possible, keep as file entry
99
- collapsed[key] = values;
100
- continue;
101
- }
102
- if (!dirKeyGroups.has(dirKey)) {
103
- dirKeyGroups.set(dirKey, []);
104
- }
105
- dirKeyGroups.get(dirKey).push({ key, values });
106
- }
107
- // Process each directory group - always collapse when multiple files share a dir key
108
- for (const [dirKey, entries] of dirKeyGroups.entries()) {
109
- // Collapse: collect all installed directories from file entries
110
- const dirValues = new Set();
111
- for (const entry of entries) {
112
- for (const v of entry.values) {
113
- const d = dirname(v);
114
- if (d && d !== '.') {
115
- const normalized = d.endsWith('/') ? d : `${d}/`;
116
- dirValues.add(normalized);
117
- }
118
- }
119
- }
120
- if (dirValues.size > 0) {
121
- // Replace file entries with a single dir key entry
122
- const pruned = pruneNestedDirectories(Array.from(dirValues));
123
- collapsed[dirKey] = pruned.sort();
124
- }
125
- else {
126
- // No directories found, keep as individual file entries
127
- for (const entry of entries) {
128
- collapsed[entry.key] = entry.values;
129
- }
130
- }
131
- }
132
- return sortMapping(collapsed);
133
- }
134
- /**
135
- * Build a mapping that preserves exact file keys for the provided formulaFiles.
136
- * For universal subdirs, maps to platform-specific installed paths using detected platforms.
137
- * For platform-specific paths (with .platform suffix), only maps to that specific platform.
138
- * For ai/ paths and other non-universal paths, keeps the value as the same path.
139
- *
140
- * Filters files using the same logic as install/save: excludes root files, skippable paths,
141
- * and non-allowed registry paths to match the index building behavior.
142
- *
143
- * Prunes redundant mappings: if platform-specific keys exist (e.g., setup.claude.md),
144
- * their target files are excluded from the universal key (e.g., setup.md) to avoid duplication.
145
- */
146
- function buildExactFileMapping(formulaFiles, platforms) {
147
- const mapping = {};
148
- // Collect platform-specific targets per base universal key (e.g., commands/nestjs/setup.md)
149
- // so we can prune duplicates from the universal key later.
150
- const platformSpecificTargetsByBase = new Map();
151
- const addTargets = (key, values) => {
152
- if (values.size > 0) {
153
- mapping[key] = Array.from(values).sort();
154
- }
155
- };
156
- // First pass: record platform-specific target files keyed by base universal key
157
- for (const file of formulaFiles) {
158
- const normalized = normalizeRegistryPath(file.path);
159
- if (isRootRegistryPath(normalized))
160
- continue;
161
- if (isSkippableRegistryPath(normalized))
162
- continue;
163
- if (!isAllowedRegistryPath(normalized))
164
- continue;
165
- const parsed = parseUniversalPath(normalized);
166
- if (parsed && parsed.platformSuffix && isPlatformId(parsed.platformSuffix)) {
167
- try {
168
- const { absFile } = mapUniversalToPlatform(parsed.platformSuffix, parsed.universalSubdir, parsed.relPath);
169
- const baseKey = `${parsed.universalSubdir}/${parsed.relPath}`;
170
- const set = platformSpecificTargetsByBase.get(baseKey) ?? new Set();
171
- set.add(absFile.replace(/\\/g, '/'));
172
- platformSpecificTargetsByBase.set(baseKey, set);
173
- }
174
- catch {
175
- // Ignore unsupported subdir/platform combinations
176
- }
177
- }
178
- }
179
- // Second pass: build exact mappings and prune universal values that are covered by platform-specific keys
180
- for (const file of formulaFiles) {
181
- const normalized = normalizeRegistryPath(file.path);
182
- if (isRootRegistryPath(normalized))
183
- continue;
184
- if (isSkippableRegistryPath(normalized))
185
- continue;
186
- if (!isAllowedRegistryPath(normalized))
187
- continue;
188
- const key = normalized.replace(/\\/g, '/');
189
- const values = new Set();
190
- if (key.startsWith(`${PLATFORM_DIRS.AI}/`)) {
191
- // ai/ paths: keep as-is
192
- values.add(key);
193
- addTargets(key, values);
194
- continue;
195
- }
196
- const parsed = parseUniversalPath(key);
197
- if (parsed) {
198
- if (parsed.platformSuffix && isPlatformId(parsed.platformSuffix)) {
199
- // Platform-specific registry key → only that platform target
200
- try {
201
- const { absFile } = mapUniversalToPlatform(parsed.platformSuffix, parsed.universalSubdir, parsed.relPath);
202
- values.add(absFile.replace(/\\/g, '/'));
203
- }
204
- catch {
205
- // Ignore unsupported subdir/platform combinations
206
- }
207
- }
208
- else {
209
- // Universal registry key → map to all detected platforms, then prune duplicates
210
- for (const platform of platforms) {
211
- try {
212
- const { absFile } = mapUniversalToPlatform(platform, parsed.universalSubdir, parsed.relPath);
213
- values.add(absFile.replace(/\\/g, '/'));
214
- }
215
- catch {
216
- // Ignore unsupported platforms
217
- }
218
- }
219
- // Prune: if platform-specific keys exist for this base, remove their targets from universal
220
- const baseKey = `${parsed.universalSubdir}/${parsed.relPath}`;
221
- const covered = platformSpecificTargetsByBase.get(baseKey);
222
- if (covered && covered.size > 0) {
223
- for (const target of covered) {
224
- values.delete(target);
225
- }
226
- }
227
- }
228
- }
229
- else {
230
- // Fallback: keep value as the same path
231
- values.add(key);
232
- }
233
- addTargets(key, values);
234
- }
235
- return mapping;
236
- }
237
- export async function buildMappingAndWriteIndex(cwd, formulaName, formulaFiles, platforms, options = {}) {
238
- try {
239
- // Read existing index and other indexes for conflict context
240
- const previousIndex = await readFormulaIndex(cwd, formulaName);
241
- const otherIndexes = await loadOtherFormulaIndexes(cwd, formulaName);
242
- // Resolve version (prefer previous index; otherwise read from formula.yml)
243
- let version = previousIndex?.version || '';
244
- if (!version) {
245
- const formulaDir = getLocalFormulaDir(cwd, formulaName);
246
- const formulaYmlPath = join(formulaDir, 'formula.yml');
247
- if (await exists(formulaYmlPath)) {
248
- try {
249
- const formulaYml = await parseFormulaYml(formulaYmlPath);
250
- version = formulaYml.version;
251
- }
252
- catch (error) {
253
- logger.warn(`Failed to read formula.yml for version: ${error}`);
254
- return;
255
- }
256
- }
257
- }
258
- if (!version) {
259
- logger.debug(`No version found for ${formulaName}, skipping index update`);
260
- return;
261
- }
262
- // Build mapping using same flow as install
263
- let newMapping = await buildIndexMappingForFormulaFiles(cwd, formulaFiles, platforms, previousIndex, otherIndexes);
264
- // Optionally transform mapping:
265
- // - If preserveExactPaths is true: force exact file keys and strip dir keys
266
- // - Otherwise: preserve the planner's dir/file decisions (already respects workspace occupancy)
267
- if (options.preserveExactPaths) {
268
- newMapping = buildExactFileMapping(formulaFiles, platforms);
269
- }
270
- // Prune stale keys from previous index based on current files in .openpackage
271
- // This ensures keys are updated when files/directories are moved or renamed
272
- const currentPaths = formulaFiles.map(f => f.path);
273
- const prunedPreviousFiles = pruneStaleKeysByCurrentFiles(previousIndex?.files || {}, currentPaths);
274
- const previousFilesWithoutDirKeys = Object.fromEntries(Object.entries(prunedPreviousFiles).filter(([key]) => !key.endsWith('/')));
275
- // Merge and write index - respect existing entries (post-pruning) and prune redundant children
276
- const mergedFiles = mergeMappingsRespectingExisting(previousFilesWithoutDirKeys, newMapping);
277
- const indexRecord = {
278
- path: getFormulaIndexPath(cwd, formulaName),
279
- formulaName,
280
- version,
281
- files: mergedFiles
282
- };
283
- await writeFormulaIndex(indexRecord);
284
- logger.debug(`Updated formula.index.yml for ${formulaName}@${version}`);
285
- }
286
- catch (error) {
287
- logger.warn(`Failed to update formula.index.yml for ${formulaName}: ${error}`);
288
- }
289
- }
290
- //# sourceMappingURL=formula-index-updater.js.map