@pie-element/cli 0.1.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 (255) hide show
  1. package/.compatibility/report.json +2491 -0
  2. package/.turbo/turbo-build.log +1 -0
  3. package/CHANGELOG.md +8 -0
  4. package/README.md +240 -0
  5. package/REFACTORING.md +131 -0
  6. package/bin/dev.js +5 -0
  7. package/bin/run.js +5 -0
  8. package/dist/commands/dev/demo/index.d.ts +33 -0
  9. package/dist/commands/dev/demo/index.d.ts.map +1 -0
  10. package/dist/commands/dev/demo/index.js +274 -0
  11. package/dist/commands/dev/demo/index.js.map +1 -0
  12. package/dist/commands/dev/test-bundler.d.ts +18 -0
  13. package/dist/commands/dev/test-bundler.d.ts.map +1 -0
  14. package/dist/commands/dev/test-bundler.js +284 -0
  15. package/dist/commands/dev/test-bundler.js.map +1 -0
  16. package/dist/commands/mathquill/migrate.d.ts +20 -0
  17. package/dist/commands/mathquill/migrate.d.ts.map +1 -0
  18. package/dist/commands/mathquill/migrate.js +240 -0
  19. package/dist/commands/mathquill/migrate.js.map +1 -0
  20. package/dist/commands/mathquill/status.d.ts +20 -0
  21. package/dist/commands/mathquill/status.d.ts.map +1 -0
  22. package/dist/commands/mathquill/status.js +231 -0
  23. package/dist/commands/mathquill/status.js.map +1 -0
  24. package/dist/commands/packages/create-controllers.d.ts +13 -0
  25. package/dist/commands/packages/create-controllers.d.ts.map +1 -0
  26. package/dist/commands/packages/create-controllers.js +103 -0
  27. package/dist/commands/packages/create-controllers.js.map +1 -0
  28. package/dist/commands/packages/create-lib-react.d.ts +17 -0
  29. package/dist/commands/packages/create-lib-react.d.ts.map +1 -0
  30. package/dist/commands/packages/create-lib-react.js +228 -0
  31. package/dist/commands/packages/create-lib-react.js.map +1 -0
  32. package/dist/commands/packages/create-react-elements.d.ts +16 -0
  33. package/dist/commands/packages/create-react-elements.d.ts.map +1 -0
  34. package/dist/commands/packages/create-react-elements.js +259 -0
  35. package/dist/commands/packages/create-react-elements.js.map +1 -0
  36. package/dist/commands/packages/enable-publishing.d.ts +11 -0
  37. package/dist/commands/packages/enable-publishing.d.ts.map +1 -0
  38. package/dist/commands/packages/enable-publishing.js +117 -0
  39. package/dist/commands/packages/enable-publishing.js.map +1 -0
  40. package/dist/commands/packages/init-synced-elements.d.ts +16 -0
  41. package/dist/commands/packages/init-synced-elements.d.ts.map +1 -0
  42. package/dist/commands/packages/init-synced-elements.js +204 -0
  43. package/dist/commands/packages/init-synced-elements.js.map +1 -0
  44. package/dist/commands/upstream/analyze-esm.d.ts +59 -0
  45. package/dist/commands/upstream/analyze-esm.d.ts.map +1 -0
  46. package/dist/commands/upstream/analyze-esm.js +1481 -0
  47. package/dist/commands/upstream/analyze-esm.js.map +1 -0
  48. package/dist/commands/upstream/check.d.ts +15 -0
  49. package/dist/commands/upstream/check.d.ts.map +1 -0
  50. package/dist/commands/upstream/check.js +165 -0
  51. package/dist/commands/upstream/check.js.map +1 -0
  52. package/dist/commands/upstream/deps.d.ts +15 -0
  53. package/dist/commands/upstream/deps.d.ts.map +1 -0
  54. package/dist/commands/upstream/deps.js +174 -0
  55. package/dist/commands/upstream/deps.js.map +1 -0
  56. package/dist/commands/upstream/sync-mathquill.d.ts +12 -0
  57. package/dist/commands/upstream/sync-mathquill.d.ts.map +1 -0
  58. package/dist/commands/upstream/sync-mathquill.js +97 -0
  59. package/dist/commands/upstream/sync-mathquill.js.map +1 -0
  60. package/dist/commands/upstream/sync.d.ts +25 -0
  61. package/dist/commands/upstream/sync.d.ts.map +1 -0
  62. package/dist/commands/upstream/sync.js +552 -0
  63. package/dist/commands/upstream/sync.js.map +1 -0
  64. package/dist/commands/upstream/track.d.ts +15 -0
  65. package/dist/commands/upstream/track.d.ts.map +1 -0
  66. package/dist/commands/upstream/track.js +115 -0
  67. package/dist/commands/upstream/track.js.map +1 -0
  68. package/dist/commands/upstream/update.d.ts +15 -0
  69. package/dist/commands/upstream/update.d.ts.map +1 -0
  70. package/dist/commands/upstream/update.js +98 -0
  71. package/dist/commands/upstream/update.js.map +1 -0
  72. package/dist/commands/verify/controllers.d.ts +12 -0
  73. package/dist/commands/verify/controllers.d.ts.map +1 -0
  74. package/dist/commands/verify/controllers.js +138 -0
  75. package/dist/commands/verify/controllers.js.map +1 -0
  76. package/dist/commands/verify/react-build.d.ts +13 -0
  77. package/dist/commands/verify/react-build.d.ts.map +1 -0
  78. package/dist/commands/verify/react-build.js +135 -0
  79. package/dist/commands/verify/react-build.js.map +1 -0
  80. package/dist/index.d.ts +2 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +2 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/lib/mathquill/extension-generator.d.ts +9 -0
  85. package/dist/lib/mathquill/extension-generator.d.ts.map +1 -0
  86. package/dist/lib/mathquill/extension-generator.js +107 -0
  87. package/dist/lib/mathquill/extension-generator.js.map +1 -0
  88. package/dist/lib/mathquill/khan-extractor.d.ts +16 -0
  89. package/dist/lib/mathquill/khan-extractor.d.ts.map +1 -0
  90. package/dist/lib/mathquill/khan-extractor.js +148 -0
  91. package/dist/lib/mathquill/khan-extractor.js.map +1 -0
  92. package/dist/lib/mathquill/learnosity-extractor.d.ts +15 -0
  93. package/dist/lib/mathquill/learnosity-extractor.d.ts.map +1 -0
  94. package/dist/lib/mathquill/learnosity-extractor.js +170 -0
  95. package/dist/lib/mathquill/learnosity-extractor.js.map +1 -0
  96. package/dist/lib/mathquill/migration-orchestrator.d.ts +77 -0
  97. package/dist/lib/mathquill/migration-orchestrator.d.ts.map +1 -0
  98. package/dist/lib/mathquill/migration-orchestrator.js +391 -0
  99. package/dist/lib/mathquill/migration-orchestrator.js.map +1 -0
  100. package/dist/lib/mathquill/package-updater.d.ts +9 -0
  101. package/dist/lib/mathquill/package-updater.d.ts.map +1 -0
  102. package/dist/lib/mathquill/package-updater.js +103 -0
  103. package/dist/lib/mathquill/package-updater.js.map +1 -0
  104. package/dist/lib/mathquill/pie-extractor.d.ts +14 -0
  105. package/dist/lib/mathquill/pie-extractor.d.ts.map +1 -0
  106. package/dist/lib/mathquill/pie-extractor.js +167 -0
  107. package/dist/lib/mathquill/pie-extractor.js.map +1 -0
  108. package/dist/lib/upstream/repo-utils.d.ts +9 -0
  109. package/dist/lib/upstream/repo-utils.d.ts.map +1 -0
  110. package/dist/lib/upstream/repo-utils.js +10 -0
  111. package/dist/lib/upstream/repo-utils.js.map +1 -0
  112. package/dist/lib/upstream/sync-compatibility.d.ts +29 -0
  113. package/dist/lib/upstream/sync-compatibility.d.ts.map +1 -0
  114. package/dist/lib/upstream/sync-compatibility.js +70 -0
  115. package/dist/lib/upstream/sync-compatibility.js.map +1 -0
  116. package/dist/lib/upstream/sync-constants.d.ts +50 -0
  117. package/dist/lib/upstream/sync-constants.d.ts.map +1 -0
  118. package/dist/lib/upstream/sync-constants.js +66 -0
  119. package/dist/lib/upstream/sync-constants.js.map +1 -0
  120. package/dist/lib/upstream/sync-controllers-strategy.d.ts +18 -0
  121. package/dist/lib/upstream/sync-controllers-strategy.d.ts.map +1 -0
  122. package/dist/lib/upstream/sync-controllers-strategy.js +243 -0
  123. package/dist/lib/upstream/sync-controllers-strategy.js.map +1 -0
  124. package/dist/lib/upstream/sync-demo-metadata.d.ts +15 -0
  125. package/dist/lib/upstream/sync-demo-metadata.d.ts.map +1 -0
  126. package/dist/lib/upstream/sync-demo-metadata.js +165 -0
  127. package/dist/lib/upstream/sync-demo-metadata.js.map +1 -0
  128. package/dist/lib/upstream/sync-dev-exports.d.ts +13 -0
  129. package/dist/lib/upstream/sync-dev-exports.d.ts.map +1 -0
  130. package/dist/lib/upstream/sync-dev-exports.js +115 -0
  131. package/dist/lib/upstream/sync-dev-exports.js.map +1 -0
  132. package/dist/lib/upstream/sync-externals.d.ts +29 -0
  133. package/dist/lib/upstream/sync-externals.d.ts.map +1 -0
  134. package/dist/lib/upstream/sync-externals.js +164 -0
  135. package/dist/lib/upstream/sync-externals.js.map +1 -0
  136. package/dist/lib/upstream/sync-filesystem.d.ts +21 -0
  137. package/dist/lib/upstream/sync-filesystem.d.ts.map +1 -0
  138. package/dist/lib/upstream/sync-filesystem.js +64 -0
  139. package/dist/lib/upstream/sync-filesystem.js.map +1 -0
  140. package/dist/lib/upstream/sync-imports.d.ts +284 -0
  141. package/dist/lib/upstream/sync-imports.d.ts.map +1 -0
  142. package/dist/lib/upstream/sync-imports.js +816 -0
  143. package/dist/lib/upstream/sync-imports.js.map +1 -0
  144. package/dist/lib/upstream/sync-mathquill.d.ts +19 -0
  145. package/dist/lib/upstream/sync-mathquill.d.ts.map +1 -0
  146. package/dist/lib/upstream/sync-mathquill.js +160 -0
  147. package/dist/lib/upstream/sync-mathquill.js.map +1 -0
  148. package/dist/lib/upstream/sync-package-json.d.ts +28 -0
  149. package/dist/lib/upstream/sync-package-json.d.ts.map +1 -0
  150. package/dist/lib/upstream/sync-package-json.js +66 -0
  151. package/dist/lib/upstream/sync-package-json.js.map +1 -0
  152. package/dist/lib/upstream/sync-package-manager.d.ts +50 -0
  153. package/dist/lib/upstream/sync-package-manager.d.ts.map +1 -0
  154. package/dist/lib/upstream/sync-package-manager.js +570 -0
  155. package/dist/lib/upstream/sync-package-manager.js.map +1 -0
  156. package/dist/lib/upstream/sync-pielib-strategy.d.ts +26 -0
  157. package/dist/lib/upstream/sync-pielib-strategy.d.ts.map +1 -0
  158. package/dist/lib/upstream/sync-pielib-strategy.js +345 -0
  159. package/dist/lib/upstream/sync-pielib-strategy.js.map +1 -0
  160. package/dist/lib/upstream/sync-react-strategy.d.ts +54 -0
  161. package/dist/lib/upstream/sync-react-strategy.d.ts.map +1 -0
  162. package/dist/lib/upstream/sync-react-strategy.js +733 -0
  163. package/dist/lib/upstream/sync-react-strategy.js.map +1 -0
  164. package/dist/lib/upstream/sync-strategy.d.ts +49 -0
  165. package/dist/lib/upstream/sync-strategy.d.ts.map +1 -0
  166. package/dist/lib/upstream/sync-strategy.js +2 -0
  167. package/dist/lib/upstream/sync-strategy.js.map +1 -0
  168. package/dist/lib/upstream/sync-summary.d.ts +20 -0
  169. package/dist/lib/upstream/sync-summary.d.ts.map +1 -0
  170. package/dist/lib/upstream/sync-summary.js +157 -0
  171. package/dist/lib/upstream/sync-summary.js.map +1 -0
  172. package/dist/lib/upstream/sync-transforms.d.ts +60 -0
  173. package/dist/lib/upstream/sync-transforms.d.ts.map +1 -0
  174. package/dist/lib/upstream/sync-transforms.js +97 -0
  175. package/dist/lib/upstream/sync-transforms.js.map +1 -0
  176. package/dist/lib/upstream/sync-vite-config.d.ts +13 -0
  177. package/dist/lib/upstream/sync-vite-config.d.ts.map +1 -0
  178. package/dist/lib/upstream/sync-vite-config.js +231 -0
  179. package/dist/lib/upstream/sync-vite-config.js.map +1 -0
  180. package/dist/utils/compatibility.d.ts +129 -0
  181. package/dist/utils/compatibility.d.ts.map +1 -0
  182. package/dist/utils/compatibility.js +44 -0
  183. package/dist/utils/compatibility.js.map +1 -0
  184. package/dist/utils/conversion.d.ts +25 -0
  185. package/dist/utils/conversion.d.ts.map +1 -0
  186. package/dist/utils/conversion.js +123 -0
  187. package/dist/utils/conversion.js.map +1 -0
  188. package/dist/utils/git.d.ts +7 -0
  189. package/dist/utils/git.d.ts.map +1 -0
  190. package/dist/utils/git.js +63 -0
  191. package/dist/utils/git.js.map +1 -0
  192. package/dist/utils/logger.d.ts +29 -0
  193. package/dist/utils/logger.d.ts.map +1 -0
  194. package/dist/utils/logger.js +63 -0
  195. package/dist/utils/logger.js.map +1 -0
  196. package/dist/utils/package-json.d.ts +12 -0
  197. package/dist/utils/package-json.d.ts.map +1 -0
  198. package/dist/utils/package-json.js +29 -0
  199. package/dist/utils/package-json.js.map +1 -0
  200. package/package.json +59 -0
  201. package/packages/cli/bin/dev.js +5 -0
  202. package/packages/cli/bin/run.js +5 -0
  203. package/src/commands/dev/demo/index.ts +313 -0
  204. package/src/commands/dev/test-bundler.ts +345 -0
  205. package/src/commands/mathquill/migrate.ts +269 -0
  206. package/src/commands/mathquill/status.ts +267 -0
  207. package/src/commands/packages/create-controllers.ts +127 -0
  208. package/src/commands/packages/create-lib-react.ts +279 -0
  209. package/src/commands/packages/create-react-elements.ts +306 -0
  210. package/src/commands/packages/enable-publishing.ts +161 -0
  211. package/src/commands/packages/init-synced-elements.ts +259 -0
  212. package/src/commands/upstream/README.md +444 -0
  213. package/src/commands/upstream/analyze-esm.ts +1973 -0
  214. package/src/commands/upstream/check.ts +228 -0
  215. package/src/commands/upstream/deps.ts +222 -0
  216. package/src/commands/upstream/sync-mathquill.ts +108 -0
  217. package/src/commands/upstream/sync.ts +687 -0
  218. package/src/commands/upstream/track.ts +145 -0
  219. package/src/commands/upstream/update.ts +110 -0
  220. package/src/commands/verify/controllers.ts +166 -0
  221. package/src/commands/verify/react-build.ts +171 -0
  222. package/src/index.ts +1 -0
  223. package/src/lib/mathquill/extension-generator.ts +111 -0
  224. package/src/lib/mathquill/khan-extractor.ts +175 -0
  225. package/src/lib/mathquill/learnosity-extractor.ts +198 -0
  226. package/src/lib/mathquill/migration-orchestrator.ts +513 -0
  227. package/src/lib/mathquill/package-updater.ts +120 -0
  228. package/src/lib/mathquill/pie-extractor.ts +194 -0
  229. package/src/lib/upstream/repo-utils.ts +18 -0
  230. package/src/lib/upstream/sync-compatibility.ts +89 -0
  231. package/src/lib/upstream/sync-constants.ts +77 -0
  232. package/src/lib/upstream/sync-controllers-strategy.ts +291 -0
  233. package/src/lib/upstream/sync-demo-metadata.ts +199 -0
  234. package/src/lib/upstream/sync-dev-exports.ts +151 -0
  235. package/src/lib/upstream/sync-externals.ts +159 -0
  236. package/src/lib/upstream/sync-filesystem.ts +87 -0
  237. package/src/lib/upstream/sync-imports.ts +992 -0
  238. package/src/lib/upstream/sync-mathquill.ts +194 -0
  239. package/src/lib/upstream/sync-package-json.ts +86 -0
  240. package/src/lib/upstream/sync-package-manager.ts +694 -0
  241. package/src/lib/upstream/sync-pielib-strategy.ts +441 -0
  242. package/src/lib/upstream/sync-react-strategy.ts +945 -0
  243. package/src/lib/upstream/sync-strategy.ts +61 -0
  244. package/src/lib/upstream/sync-summary.ts +194 -0
  245. package/src/lib/upstream/sync-transforms.ts +154 -0
  246. package/src/lib/upstream/sync-vite-config.ts +243 -0
  247. package/src/types/es-module-lexer.d.ts +4 -0
  248. package/src/utils/compatibility.ts +182 -0
  249. package/src/utils/conversion.ts +153 -0
  250. package/src/utils/git.ts +63 -0
  251. package/src/utils/logger.ts +69 -0
  252. package/src/utils/package-json.ts +43 -0
  253. package/tests/sync-package-manager.test.ts +112 -0
  254. package/tests/transform-assign-props.test.ts +101 -0
  255. package/tsconfig.json +15 -0
@@ -0,0 +1,228 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { existsSync } from 'node:fs';
3
+ import { readdir } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { getCurrentCommit, getFileModifiedDate } from '../../utils/git.js';
6
+ import { Logger } from '../../utils/logger.js';
7
+ import { DEFAULT_PATHS } from '../../lib/upstream/sync-constants.js';
8
+ import { formatRepoNotFound } from '../../lib/upstream/repo-utils.js';
9
+
10
+ interface CheckConfig {
11
+ pieElements: string;
12
+ pieLib: string;
13
+ pieElementsNg: string;
14
+ elements?: string[];
15
+ verbose: boolean;
16
+ }
17
+
18
+ interface FileChange {
19
+ element: string;
20
+ file: string;
21
+ upstreamPath: string;
22
+ localPath: string;
23
+ upstreamModified: Date;
24
+ localModified: Date;
25
+ upstreamSize: number;
26
+ localSize: number;
27
+ }
28
+
29
+ interface CheckResult {
30
+ elementsChecked: number;
31
+ filesChecked: number;
32
+ potentialChanges: FileChange[];
33
+ errors: string[];
34
+ warnings: string[];
35
+ }
36
+
37
+ export default class Check extends Command {
38
+ static override description = 'Check for changes in upstream pie-elements repository';
39
+
40
+ static override examples = [
41
+ '<%= config.bin %> <%= command.id %>',
42
+ '<%= config.bin %> <%= command.id %> --verbose',
43
+ '<%= config.bin %> <%= command.id %> --element multiple-choice',
44
+ ];
45
+
46
+ static override flags = {
47
+ verbose: Flags.boolean({
48
+ char: 'v',
49
+ description: 'Show detailed output',
50
+ default: false,
51
+ }),
52
+ element: Flags.string({
53
+ description: 'Check only specified element',
54
+ }),
55
+ };
56
+
57
+ private logger!: Logger;
58
+
59
+ public async run(): Promise<void> {
60
+ const { flags } = await this.parse(Check);
61
+
62
+ this.logger = new Logger(flags.verbose);
63
+
64
+ const config: CheckConfig = {
65
+ pieElements: DEFAULT_PATHS.PIE_ELEMENTS,
66
+ pieLib: DEFAULT_PATHS.PIE_LIB,
67
+ pieElementsNg: DEFAULT_PATHS.PIE_ELEMENTS_NG,
68
+ elements: flags.element ? [flags.element] : undefined,
69
+ verbose: flags.verbose,
70
+ };
71
+
72
+ const result = await this.checkUpstream(config);
73
+
74
+ // Display results
75
+ this.displayResults(result);
76
+
77
+ if (result.errors.length > 0) {
78
+ this.error('Check completed with errors');
79
+ }
80
+ }
81
+
82
+ private async checkUpstream(config: CheckConfig): Promise<CheckResult> {
83
+ const result: CheckResult = {
84
+ elementsChecked: 0,
85
+ filesChecked: 0,
86
+ potentialChanges: [],
87
+ errors: [],
88
+ warnings: [],
89
+ };
90
+
91
+ this.logger.info('šŸ” Checking upstream changes...');
92
+ this.logger.info(` pie-elements: ${config.pieElements}`);
93
+ this.logger.info(` pie-lib: ${config.pieLib}`);
94
+ this.logger.info(` pie-elements-ng: ${config.pieElementsNg}\n`);
95
+
96
+ // Verify upstream repos exist
97
+ if (!existsSync(config.pieElements)) {
98
+ result.errors.push(formatRepoNotFound('pie-elements', config.pieElements));
99
+ return result;
100
+ }
101
+ if (!existsSync(config.pieLib)) {
102
+ result.errors.push(formatRepoNotFound('pie-lib', config.pieLib));
103
+ return result;
104
+ }
105
+
106
+ // Get commit info
107
+ const pieElementsCommit = getCurrentCommit(config.pieElements);
108
+ const pieLibCommit = getCurrentCommit(config.pieLib);
109
+ const pieElementsNgCommit = getCurrentCommit(config.pieElementsNg);
110
+
111
+ this.logger.info('šŸ“Š Repository Commits:');
112
+ this.logger.info(` pie-elements: ${pieElementsCommit.substring(0, 8)}`);
113
+ this.logger.info(` pie-lib: ${pieLibCommit.substring(0, 8)}`);
114
+ this.logger.info(` pie-elements-ng: ${pieElementsNgCommit.substring(0, 8)}\n`);
115
+
116
+ // Check controllers
117
+ await this.checkControllers(config, result);
118
+
119
+ return result;
120
+ }
121
+
122
+ private async checkControllers(config: CheckConfig, result: CheckResult): Promise<void> {
123
+ this.logger.info('šŸ“¦ Checking controllers...\n');
124
+
125
+ const upstreamElementsDir = join(config.pieElements, 'packages');
126
+ const localElementsDir = join(config.pieElementsNg, 'packages/elements-react');
127
+
128
+ // Get list of elements that exist in both repos
129
+ const upstreamPackages = await readdir(upstreamElementsDir);
130
+ const localPackages = existsSync(localElementsDir) ? await readdir(localElementsDir) : [];
131
+
132
+ for (const pkg of upstreamPackages) {
133
+ // Skip if filtering by element
134
+ if (config.elements && !config.elements.includes(pkg)) {
135
+ continue;
136
+ }
137
+
138
+ // Skip if not in local repo
139
+ if (!localPackages.includes(pkg)) {
140
+ this.logger.debug(` Skipping ${pkg} (not in local repo)`);
141
+ continue;
142
+ }
143
+
144
+ result.elementsChecked++;
145
+
146
+ // Check controller file
147
+ const upstreamController = join(upstreamElementsDir, pkg, 'controller/src/index.js');
148
+ const localController = join(localElementsDir, pkg, 'src/controller/index.ts');
149
+
150
+ if (!existsSync(upstreamController)) {
151
+ this.logger.debug(` No controller found for ${pkg}`);
152
+ continue;
153
+ }
154
+
155
+ if (!existsSync(localController)) {
156
+ result.warnings.push(`Local controller missing for ${pkg}`);
157
+ continue;
158
+ }
159
+
160
+ result.filesChecked++;
161
+
162
+ // Compare modification dates
163
+ const upstreamDate = getFileModifiedDate(upstreamController, config.pieElements);
164
+ const localDate = getFileModifiedDate(localController, config.pieElementsNg);
165
+
166
+ if (upstreamDate > localDate) {
167
+ const stat = await import('node:fs/promises').then((m) => m.stat);
168
+ const upstreamStat = await stat(upstreamController);
169
+ const localStat = await stat(localController);
170
+
171
+ result.potentialChanges.push({
172
+ element: pkg,
173
+ file: 'controller',
174
+ upstreamPath: upstreamController,
175
+ localPath: localController,
176
+ upstreamModified: upstreamDate,
177
+ localModified: localDate,
178
+ upstreamSize: upstreamStat.size,
179
+ localSize: localStat.size,
180
+ });
181
+ }
182
+ }
183
+ }
184
+
185
+ private displayResults(result: CheckResult): void {
186
+ this.logger.section('\nšŸ“‹ Check Results');
187
+
188
+ this.logger.info(` Elements checked: ${result.elementsChecked}`);
189
+ this.logger.info(` Files checked: ${result.filesChecked}`);
190
+ this.logger.info(` Potential changes: ${result.potentialChanges.length}`);
191
+
192
+ if (result.potentialChanges.length > 0) {
193
+ this.logger.section('\nāš ļø Potential Changes');
194
+ for (const change of result.potentialChanges) {
195
+ this.logger.info(`\n ${change.element} - ${change.file}`);
196
+ this.logger.info(` Upstream: ${change.upstreamModified.toISOString()}`);
197
+ this.logger.info(` Local: ${change.localModified.toISOString()}`);
198
+ this.logger.info(` Size diff: ${change.upstreamSize - change.localSize} bytes`);
199
+ }
200
+
201
+ this.logger.section('\nšŸ’” Next Steps');
202
+ this.logger.info(' Review the changes with:');
203
+ for (const change of result.potentialChanges.slice(0, 3)) {
204
+ this.logger.info(
205
+ ` git log --oneline --since="${change.localModified.toISOString()}" -- packages/${change.element}/controller/src/index.js`
206
+ );
207
+ }
208
+ this.logger.info('\n Then sync with:');
209
+ this.logger.info(` bun run cli upstream:sync --element <element-name>\n`);
210
+ } else {
211
+ this.logger.success('\nāœ… No changes detected - all elements are up to date\n');
212
+ }
213
+
214
+ if (result.warnings.length > 0) {
215
+ this.logger.section('\nāš ļø Warnings');
216
+ for (const warning of result.warnings) {
217
+ this.logger.warn(` ${warning}`);
218
+ }
219
+ }
220
+
221
+ if (result.errors.length > 0) {
222
+ this.logger.section('\nāŒ Errors');
223
+ for (const error of result.errors) {
224
+ this.logger.error(` ${error}`);
225
+ }
226
+ }
227
+ }
228
+ }
@@ -0,0 +1,222 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { Logger } from '../../utils/logger.js';
3
+ import { loadPackageJson, type PackageJson } from '../../utils/package-json.js';
4
+ import { existsSync } from 'node:fs';
5
+
6
+ interface DependencyReport {
7
+ library: string;
8
+ pieElements?: string;
9
+ pieLib?: string;
10
+ pieElementsNg?: string;
11
+ status: 'ok' | 'outdated' | 'missing' | 'newer' | 'not-used-upstream';
12
+ recommendation?: string;
13
+ }
14
+
15
+ // Libraries we care about tracking
16
+ const TRACKED_DEPS = [
17
+ // Math rendering
18
+ 'mathjax-full',
19
+ 'mathlive',
20
+
21
+ // Sanitization
22
+ 'dompurify',
23
+
24
+ // Rich text
25
+ '@tiptap/core',
26
+ '@tiptap/pm',
27
+ '@tiptap/starter-kit',
28
+ '@tiptap/extension-image',
29
+ '@tiptap/extension-link',
30
+ '@tiptap/extension-table',
31
+ '@tiptap/extension-task-list',
32
+
33
+ // PIE framework
34
+ '@pie-framework/pie-player-events',
35
+ '@pie-framework/pie-configure-events',
36
+
37
+ // Utilities (note: lodash is replaced with lodash-es during sync)
38
+ 'lodash-es',
39
+ 'uuid',
40
+ ];
41
+
42
+ export default class Deps extends Command {
43
+ static override description = 'Compare dependencies with upstream and suggest updates';
44
+
45
+ static override examples = ['<%= config.bin %> <%= command.id %>'];
46
+
47
+ static override flags = {
48
+ verbose: Flags.boolean({
49
+ char: 'v',
50
+ description: 'Show detailed output',
51
+ default: false,
52
+ }),
53
+ };
54
+
55
+ private logger = new Logger();
56
+
57
+ public async run(): Promise<void> {
58
+ const { flags } = await this.parse(Deps);
59
+
60
+ this.logger = new Logger(flags.verbose);
61
+
62
+ this.logger.section('šŸ“¦ Dependency Check Report');
63
+
64
+ // Read all package.json files
65
+ const pieElementsPkg = await this.loadPackage('../pie-elements/package.json');
66
+ const pieLibPkg = await this.loadPackage('../pie-lib/package.json');
67
+ const pieElementsNgPkg = await this.loadPackage('./package.json');
68
+
69
+ if (!pieElementsPkg) {
70
+ this.error('Could not load pie-elements package.json');
71
+ }
72
+ if (!pieLibPkg) {
73
+ this.error('Could not load pie-lib package.json');
74
+ }
75
+ if (!pieElementsNgPkg) {
76
+ this.error('Could not load pie-elements-ng package.json');
77
+ }
78
+
79
+ const reports: DependencyReport[] = [];
80
+
81
+ for (const dep of TRACKED_DEPS) {
82
+ const report: DependencyReport = {
83
+ library: dep,
84
+ pieElements: this.getDep(pieElementsPkg, dep),
85
+ pieLib: this.getDep(pieLibPkg, dep),
86
+ pieElementsNg: this.getDep(pieElementsNgPkg, dep),
87
+ status: 'ok',
88
+ };
89
+
90
+ // Determine status
91
+ const upstreamVersion = report.pieElements || report.pieLib;
92
+ const currentVersion = report.pieElementsNg;
93
+
94
+ if (!upstreamVersion && !currentVersion) {
95
+ report.status = 'not-used-upstream';
96
+ continue; // Skip reporting
97
+ }
98
+
99
+ if (!currentVersion && upstreamVersion) {
100
+ report.status = 'missing';
101
+ report.recommendation = `Install ${dep}@${upstreamVersion}`;
102
+ } else if (currentVersion && upstreamVersion && currentVersion !== upstreamVersion) {
103
+ const comparison = this.compareVersions(currentVersion, upstreamVersion);
104
+ if (comparison < 0) {
105
+ report.status = 'outdated';
106
+ report.recommendation = `Update from ${currentVersion} to ${upstreamVersion}`;
107
+ } else if (comparison > 0) {
108
+ report.status = 'newer';
109
+ report.recommendation = `Already on newer version (${currentVersion} > ${upstreamVersion})`;
110
+ } else {
111
+ report.status = 'ok';
112
+ }
113
+ }
114
+
115
+ reports.push(report);
116
+ }
117
+
118
+ // Print summary table
119
+ this.log(
120
+ 'ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”'
121
+ );
122
+ this.log(
123
+ '│ Library │ pie-elements │ pie-lib │ pie-elem-ng │ Status │'
124
+ );
125
+ this.log(
126
+ 'ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤'
127
+ );
128
+
129
+ for (const r of reports) {
130
+ if (r.status === 'not-used-upstream') continue;
131
+
132
+ const lib = r.library.padEnd(39);
133
+ const pe = (r.pieElements || '-').padEnd(12);
134
+ const pl = (r.pieLib || '-').padEnd(12);
135
+ const peng = (r.pieElementsNg || '-').padEnd(12);
136
+
137
+ let statusIcon = 'āœ…';
138
+ if (r.status === 'outdated') statusIcon = 'āš ļø ';
139
+ else if (r.status === 'missing') statusIcon = 'āŒ';
140
+ else if (r.status === 'newer') statusIcon = 'šŸ†™';
141
+
142
+ this.log(`│ ${lib} │ ${pe} │ ${pl} │ ${peng} │ ${statusIcon} │`);
143
+ }
144
+
145
+ this.log(
146
+ 'ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜'
147
+ );
148
+
149
+ // Print actionable recommendations
150
+ const actionable = reports.filter(
151
+ (r) => r.recommendation && r.status !== 'ok' && r.status !== 'newer'
152
+ );
153
+
154
+ if (actionable.length > 0) {
155
+ this.logger.section('\nšŸ”§ Recommended Actions');
156
+ for (const r of actionable) {
157
+ this.logger.info(` ${r.recommendation}`);
158
+ }
159
+ this.log('');
160
+ }
161
+
162
+ const newer = reports.filter((r) => r.status === 'newer');
163
+ if (newer.length > 0) {
164
+ this.logger.info('ā„¹ļø Libraries where pie-elements-ng is ahead:\n');
165
+ for (const r of newer) {
166
+ this.logger.info(
167
+ ` ${r.library}: ${r.pieElementsNg} (upstream: ${r.pieElements || r.pieLib || '-'})`
168
+ );
169
+ }
170
+ this.log('');
171
+ }
172
+
173
+ const allOk = reports.filter((r) => r.status === 'ok');
174
+ if (actionable.length === 0 && newer.length === 0) {
175
+ this.logger.success('\nāœ… All dependencies in sync!');
176
+ } else {
177
+ this.logger.info(
178
+ `\nšŸ“Š Summary: ${allOk.length} in sync, ${actionable.length} need updates, ${newer.length} ahead\n`
179
+ );
180
+ }
181
+ }
182
+
183
+ private async loadPackage(path: string): Promise<PackageJson | null> {
184
+ try {
185
+ if (!existsSync(path)) {
186
+ return null;
187
+ }
188
+ return await loadPackageJson(path);
189
+ } catch (error) {
190
+ this.logger.error(`Error loading ${path}: ${error}`);
191
+ return null;
192
+ }
193
+ }
194
+
195
+ private getDep(pkg: PackageJson | null, name: string): string | undefined {
196
+ if (!pkg) return undefined;
197
+ return pkg.dependencies?.[name] || pkg.devDependencies?.[name];
198
+ }
199
+
200
+ private cleanVersion(version: string): string {
201
+ // Remove ^, ~, >=, etc. for comparison
202
+ return version.replace(/^[\^~>=<]+/, '');
203
+ }
204
+
205
+ private compareVersions(v1: string, v2: string): number {
206
+ const clean1 = this.cleanVersion(v1);
207
+ const clean2 = this.cleanVersion(v2);
208
+
209
+ const parts1 = clean1.split('.').map(Number);
210
+ const parts2 = clean2.split('.').map(Number);
211
+
212
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
213
+ const n1 = parts1[i] || 0;
214
+ const n2 = parts2[i] || 0;
215
+
216
+ if (n1 > n2) return 1;
217
+ if (n1 < n2) return -1;
218
+ }
219
+
220
+ return 0;
221
+ }
222
+ }
@@ -0,0 +1,108 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { Logger } from '../../utils/logger.js';
3
+ import { syncMathQuill } from '../../lib/upstream/sync-mathquill.js';
4
+ import { join } from 'node:path';
5
+ import { existsSync } from 'node:fs';
6
+
7
+ export default class SyncMathQuill extends Command {
8
+ static description = `Sync MathQuill fork from upstream
9
+
10
+ Syncs the PIE MathQuill fork sources from ../mathquill to packages/shared/mathquill
11
+ and regenerates the concatenated bundle.
12
+
13
+ This command:
14
+ 1. Copies source files (JS, CSS, fonts) from upstream
15
+ 2. Regenerates the legacy/mathquill-bundle.js from sources
16
+ 3. Copies documentation files (README, CHANGELOG)
17
+
18
+ After running this command, you should:
19
+ 1. Review changes in packages/shared/mathquill
20
+ 2. Update version in package.json if needed
21
+ 3. Run: bun run build (in mathquill package)
22
+ 4. Test with consuming packages (math-input, math-inline)
23
+ `;
24
+
25
+ static examples = [
26
+ '$ pie upstream:sync-mathquill',
27
+ '$ pie upstream:sync-mathquill --upstream-path /path/to/mathquill',
28
+ '$ pie upstream:sync-mathquill --dry-run',
29
+ ];
30
+
31
+ static flags = {
32
+ 'upstream-path': Flags.string({
33
+ description: 'Path to upstream mathquill repository',
34
+ default: '../mathquill',
35
+ }),
36
+ 'dry-run': Flags.boolean({
37
+ description: 'Show what would be synced without making changes',
38
+ default: false,
39
+ }),
40
+ verbose: Flags.boolean({
41
+ char: 'v',
42
+ description: 'Show detailed output',
43
+ default: false,
44
+ }),
45
+ };
46
+
47
+ async run(): Promise<void> {
48
+ const { flags } = await this.parse(SyncMathQuill);
49
+ const logger = new Logger(flags.verbose);
50
+
51
+ // Resolve paths
52
+ const workspaceRoot = process.cwd();
53
+ const upstreamMathQuillPath = join(workspaceRoot, flags['upstream-path']);
54
+ const sharedMathQuillPath = join(workspaceRoot, 'packages/shared/mathquill');
55
+
56
+ // Validate paths
57
+ if (!existsSync(upstreamMathQuillPath)) {
58
+ logger.error(`āŒ Upstream MathQuill not found at: ${upstreamMathQuillPath}`);
59
+ logger.info(` Specify the correct path with --upstream-path`);
60
+ this.exit(1);
61
+ }
62
+
63
+ if (!existsSync(sharedMathQuillPath)) {
64
+ logger.error(`āŒ Shared MathQuill package not found at: ${sharedMathQuillPath}`);
65
+ logger.info(` Run this command from the workspace root`);
66
+ this.exit(1);
67
+ }
68
+
69
+ logger.section('šŸ”„ Syncing MathQuill from Upstream');
70
+ logger.info(` Upstream: ${upstreamMathQuillPath}`);
71
+ logger.info(` Target: ${sharedMathQuillPath}\n`);
72
+
73
+ if (flags['dry-run']) {
74
+ logger.warn('šŸƒ DRY RUN MODE - No changes will be made\n');
75
+ logger.info('Would sync:');
76
+ logger.info(' • Core JavaScript files (intro.js, outro.js, tree.js, etc.)');
77
+ logger.info(' • Service modules (services/)');
78
+ logger.info(' • Command modules (commands/)');
79
+ logger.info(' • CSS stylesheets (css/)');
80
+ logger.info(' • Font files (fonts/)');
81
+ logger.info(' • Documentation (README.md, CHANGELOG.md)');
82
+ logger.info('\nWould regenerate:');
83
+ logger.info(' • src/legacy/mathquill-bundle.js (concatenated IIFE bundle)');
84
+ return;
85
+ }
86
+
87
+ // Perform sync
88
+ const success = await syncMathQuill({
89
+ upstreamMathQuillPath,
90
+ sharedMathQuillPath,
91
+ logger,
92
+ });
93
+
94
+ if (!success) {
95
+ logger.error('\nāŒ MathQuill sync failed');
96
+ this.exit(1);
97
+ }
98
+
99
+ // Success message
100
+ logger.section('āœ… MathQuill Sync Complete');
101
+ logger.info('\nNext steps:');
102
+ logger.info(' 1. Review changes: git diff packages/shared/mathquill');
103
+ logger.info(' 2. Update version: packages/shared/mathquill/package.json');
104
+ logger.info(' 3. Build package: cd packages/shared/mathquill && bun run build');
105
+ logger.info(' 4. Test packages: bun run build (in math-input, math-inline, math-templated)');
106
+ logger.info(' 5. Commit changes: git add packages/shared/mathquill && git commit');
107
+ }
108
+ }