@mono-labs/cli 0.0.238 → 0.0.243

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 (146) hide show
  1. package/bin/mono.js +1 -1
  2. package/dist/index.js +32 -51
  3. package/dist/lib/app.js +52 -0
  4. package/dist/lib/commands/build-process/boot.js +12 -0
  5. package/dist/lib/commands/build-process/cliFactory.js +145 -0
  6. package/dist/lib/commands/build-process/dataLayer.js +56 -0
  7. package/dist/lib/commands/build-process/index.js +11 -0
  8. package/dist/lib/commands/build-process/readEnv.js +34 -0
  9. package/dist/lib/commands/build-process/runMonoCommand.js +84 -0
  10. package/dist/lib/commands/build-process/runners/processManager.js +45 -0
  11. package/dist/lib/commands/build-process/runners/runBackground.js +46 -0
  12. package/dist/lib/commands/build-process/runners/runForeground.js +52 -0
  13. package/dist/lib/commands/build-process/test.js +32 -0
  14. package/dist/lib/commands/build-process/testflag.js +4 -0
  15. package/dist/lib/commands/build-process/validators.js +17 -0
  16. package/dist/lib/commands/loadFromRoot.js +53 -0
  17. package/dist/lib/commands/prune/index.js +10 -0
  18. package/dist/lib/commands/prune/prune.js +49 -0
  19. package/dist/lib/config.js +6 -0
  20. package/dist/lib/filterUnwantedEnvVars.js +88 -0
  21. package/dist/lib/generateNewEnvList.js +17 -0
  22. package/dist/lib/index.js +49 -0
  23. package/dist/src/cdk/cdk.js +6 -0
  24. package/dist/src/cdk/index.js +17 -0
  25. package/dist/{expo.js → src/expo.js} +18 -34
  26. package/dist/src/index.js +56 -0
  27. package/dist/src/merge-env.js +25 -0
  28. package/dist/{project → src/project}/build-mono-readme.js +11 -20
  29. package/dist/{project → src/project}/generate-readme.js +6 -13
  30. package/dist/{project → src/project}/index.js +4 -12
  31. package/dist/{stack.js → src/stack.js} +2 -2
  32. package/dist/src/tools.js +38 -0
  33. package/dist/types/index.d.ts +50 -9
  34. package/dist/types/lib/app.d.ts +3 -0
  35. package/dist/types/lib/commands/build-process/boot.d.ts +8 -0
  36. package/dist/types/lib/commands/build-process/cliFactory.d.ts +32 -0
  37. package/dist/types/lib/commands/build-process/dataLayer.d.ts +7 -0
  38. package/dist/types/lib/commands/build-process/readEnv.d.ts +1 -0
  39. package/dist/types/lib/commands/build-process/runMonoCommand.d.ts +10 -0
  40. package/dist/types/lib/commands/build-process/runners/processManager.d.ts +5 -0
  41. package/dist/types/lib/commands/build-process/runners/runBackground.d.ts +2 -0
  42. package/dist/types/lib/commands/build-process/runners/runForeground.d.ts +6 -0
  43. package/dist/types/lib/commands/build-process/test.d.ts +1 -0
  44. package/dist/types/lib/commands/build-process/testflag.d.ts +1 -0
  45. package/dist/types/lib/commands/build-process/validators.d.ts +1 -0
  46. package/dist/types/lib/commands/loadFromRoot.d.ts +7 -0
  47. package/dist/types/lib/commands/prune/prune.d.ts +1 -0
  48. package/dist/types/lib/config.d.ts +2 -0
  49. package/dist/types/lib/filterUnwantedEnvVars.d.ts +2 -0
  50. package/dist/types/lib/generateNewEnvList.d.ts +1 -0
  51. package/dist/types/lib/index.d.ts +2 -0
  52. package/dist/types/src/cdk/cdk.d.ts +1 -0
  53. package/dist/types/src/cdk/index.d.ts +1 -0
  54. package/dist/types/src/expo.d.ts +4 -0
  55. package/dist/types/src/index.d.ts +15 -0
  56. package/dist/types/src/project/build-mono-readme.d.ts +1 -0
  57. package/dist/types/src/project/generate-readme.d.ts +1 -0
  58. package/dist/types/{project → src/project}/index.d.ts +1 -1
  59. package/dist/types/src/project/merge-env.d.ts +1 -0
  60. package/dist/types/src/tools.d.ts +3 -0
  61. package/lib/app.ts +58 -0
  62. package/lib/commands/build-process/boot.ts +21 -0
  63. package/lib/commands/build-process/cliFactory.ts +219 -0
  64. package/lib/commands/build-process/dataLayer.ts +61 -0
  65. package/lib/commands/build-process/index.ts +14 -0
  66. package/lib/commands/build-process/readEnv.ts +37 -0
  67. package/lib/commands/build-process/runMonoCommand.ts +97 -0
  68. package/lib/commands/build-process/runners/processManager.ts +42 -0
  69. package/lib/commands/build-process/runners/runBackground.ts +56 -0
  70. package/lib/commands/build-process/runners/runForeground.ts +59 -0
  71. package/lib/commands/build-process/test.ts +42 -0
  72. package/lib/commands/build-process/testflag.ts +1 -0
  73. package/lib/commands/build-process/validators.ts +16 -0
  74. package/lib/commands/loadFromRoot.ts +51 -0
  75. package/lib/commands/prune/index.ts +9 -0
  76. package/lib/commands/prune/prune.ts +50 -0
  77. package/lib/filterUnwantedEnvVars.ts +95 -0
  78. package/lib/generateNewEnvList.ts +17 -0
  79. package/lib/index.ts +59 -0
  80. package/package.json +100 -84
  81. package/src/cdk/cdk.ts +1 -0
  82. package/src/cdk/index.ts +1 -0
  83. package/src/expo-files/filterUnwantedEnvVars.ts +141 -144
  84. package/src/expo.ts +116 -0
  85. package/src/index.ts +39 -42
  86. package/src/merge-env.ts +24 -0
  87. package/src/project/build-mono-readme.ts +460 -514
  88. package/src/project/generate-readme.ts +259 -284
  89. package/src/project/index.ts +134 -144
  90. package/src/stack.ts +54 -55
  91. package/src/tools.ts +39 -0
  92. package/dist/cdk/index.js +0 -55
  93. package/dist/project/merge-env.js +0 -31
  94. package/dist/tools.js +0 -35
  95. package/dist/types/cdk/index.d.ts +0 -2
  96. package/dist/types/expo.d.ts +0 -3
  97. package/dist/types/merge-env.d.ts +0 -1
  98. package/dist/types/tools.d.ts +0 -1
  99. package/lib/app.js +0 -49
  100. package/lib/commands/build-process/boot.js +0 -15
  101. package/lib/commands/build-process/cliFactory.js +0 -163
  102. package/lib/commands/build-process/dataLayer.js +0 -59
  103. package/lib/commands/build-process/index.js +0 -13
  104. package/lib/commands/build-process/readEnv.js +0 -37
  105. package/lib/commands/build-process/runMonoCommand.js +0 -102
  106. package/lib/commands/build-process/runners/processManager.js +0 -38
  107. package/lib/commands/build-process/runners/runBackground.js +0 -60
  108. package/lib/commands/build-process/runners/runForeground.js +0 -60
  109. package/lib/commands/build-process/test.js +0 -50
  110. package/lib/commands/build-process/testflag.js +0 -1
  111. package/lib/commands/build-process/validators.js +0 -17
  112. package/lib/commands/generate/generateSeed.js +0 -223
  113. package/lib/commands/generate/index.js +0 -30
  114. package/lib/commands/loadFromRoot.js +0 -55
  115. package/lib/commands/prune/index.js +0 -12
  116. package/lib/commands/prune/prune.js +0 -50
  117. package/lib/commands/seed/import.js +0 -30
  118. package/lib/commands/seed/index.js +0 -12
  119. package/lib/commands/submit/index.js +0 -38
  120. package/lib/commands/update/eas.js +0 -39
  121. package/lib/commands/update/index.js +0 -87
  122. package/lib/filterUnwantedEnvVars.js +0 -123
  123. package/lib/generateNewEnvList.js +0 -14
  124. package/lib/index.js +0 -58
  125. package/src/cdk/cdk.d.ts +0 -7
  126. package/src/cdk/index.js +0 -59
  127. package/src/expo.d.ts +0 -11
  128. package/src/expo.js +0 -133
  129. package/src/merge-env.js +0 -32
  130. package/src/tools.d.ts +0 -4
  131. package/src/tools.js +0 -36
  132. package/types.d.ts +0 -83
  133. /package/dist/{expo-files → src/expo-files}/filterUnwantedEnvVars.js +0 -0
  134. /package/dist/{loadFromRoot.js → src/loadFromRoot.js} +0 -0
  135. /package/dist/{project → src/project}/build-readme.js +0 -0
  136. /package/dist/{project → src/project}/generate-docs.js +0 -0
  137. /package/dist/{merge-env.js → src/project/merge-env.js} +0 -0
  138. /package/dist/types/{project/build-mono-readme.d.ts → lib/commands/build-process/index.d.ts} +0 -0
  139. /package/dist/types/{project/generate-readme.d.ts → lib/commands/prune/index.d.ts} +0 -0
  140. /package/dist/types/{expo-files → src/expo-files}/filterUnwantedEnvVars.d.ts +0 -0
  141. /package/dist/types/{loadFromRoot.d.ts → src/loadFromRoot.d.ts} +0 -0
  142. /package/dist/types/{project → src}/merge-env.d.ts +0 -0
  143. /package/dist/types/{project → src/project}/build-readme.d.ts +0 -0
  144. /package/dist/types/{project → src/project}/generate-docs.d.ts +0 -0
  145. /package/dist/types/{stack.d.ts → src/stack.d.ts} +0 -0
  146. /package/lib/{config.js → config.ts} +0 -0
@@ -11,366 +11,341 @@
11
11
  // - Keep raw yarn workspace commands for reference
12
12
  // - Emphasize `yarn mono` as the primary interface
13
13
 
14
- import { promises as fs } from 'node:fs';
15
- import path from 'node:path';
16
- import { generateDocsIndex } from './generate-docs.js';
14
+ import { promises as fs } from 'node:fs'
15
+ import path from 'node:path'
16
+ import { generateDocsIndex } from './generate-docs'
17
17
 
18
18
  interface PackageInfo {
19
- name: string;
20
- dir: string;
21
- scripts: Record<string, string>;
19
+ name: string
20
+ dir: string
21
+ scripts: Record<string, string>
22
22
  }
23
23
 
24
24
  // ----------------- config -----------------
25
25
  // Always use the working directory as the root for all file actions
26
- const REPO_ROOT = path.resolve(process.cwd());
27
- const ROOT_PKG_JSON = path.join(REPO_ROOT, 'package.json');
28
- const OUTPUT_PATH = path.join(REPO_ROOT, 'docs', 'workspaces.md');
26
+ const REPO_ROOT = path.resolve(process.cwd())
27
+ const ROOT_PKG_JSON = path.join(REPO_ROOT, 'package.json')
28
+ const OUTPUT_PATH = path.join(REPO_ROOT, 'docs', 'workspaces.md')
29
29
 
30
30
  // ----------------- helpers -----------------
31
31
  async function exists(p: string): Promise<boolean> {
32
- // Always resolve path relative to working directory
33
- const absPath = path.resolve(process.cwd(), p);
34
- try {
35
- await fs.access(absPath);
36
- return true;
37
- } catch {
38
- return false;
39
- }
32
+ // Always resolve path relative to working directory
33
+ const absPath = path.resolve(process.cwd(), p)
34
+ try {
35
+ await fs.access(absPath)
36
+ return true
37
+ } catch {
38
+ return false
39
+ }
40
40
  }
41
41
 
42
42
  function isObject(v: unknown): v is Record<string, unknown> {
43
- return v !== null && typeof v === 'object' && !Array.isArray(v);
43
+ return v !== null && typeof v === 'object' && !Array.isArray(v)
44
44
  }
45
45
 
46
46
  function toPosix(p: string): string {
47
- return p.split(path.sep).join('/');
47
+ return p.split(path.sep).join('/')
48
48
  }
49
49
 
50
50
  function mdEscapeInline(s: string): string {
51
- return String(s ?? '').replaceAll('`', '\`');
51
+ return String(s ?? '').replaceAll('`', '\`')
52
52
  }
53
53
 
54
54
  function slugifyForGithubAnchor(title: string): string {
55
- return String(title ?? '')
56
- .trim()
57
- .toLowerCase()
58
- .replace(/[^\w\s-]/g, '')
59
- .replace(/\s+/g, '-')
60
- .replace(/-+/g, '-');
55
+ return String(title ?? '')
56
+ .trim()
57
+ .toLowerCase()
58
+ .replace(/[^\w\s-]/g, '')
59
+ .replace(/\s+/g, '-')
60
+ .replace(/-+/g, '-')
61
61
  }
62
62
 
63
63
  async function readJson<T = any>(filePath: string): Promise<T> {
64
- // Always resolve filePath relative to working directory
65
- const absPath = path.resolve(process.cwd(), filePath);
66
- const raw = await fs.readFile(absPath, 'utf8');
67
- return JSON.parse(raw);
64
+ // Always resolve filePath relative to working directory
65
+ const absPath = path.resolve(process.cwd(), filePath)
66
+ const raw = await fs.readFile(absPath, 'utf8')
67
+ return JSON.parse(raw)
68
68
  }
69
69
 
70
70
  function normalizeWorkspacePatterns(workspacesField: unknown): string[] {
71
- if (Array.isArray(workspacesField)) return workspacesField as string[];
72
- if (
73
- isObject(workspacesField) &&
74
- Array.isArray((workspacesField as any).packages)
75
- )
76
- return (workspacesField as any).packages;
77
- return [];
71
+ if (Array.isArray(workspacesField)) return workspacesField as string[]
72
+ if (isObject(workspacesField) && Array.isArray((workspacesField as any).packages))
73
+ return (workspacesField as any).packages
74
+ return []
78
75
  }
79
76
 
80
77
  // ----------------- glob expansion -----------------
81
78
  function matchSegment(patternSeg: string, name: string): boolean {
82
- if (patternSeg === '*') return true;
83
- if (!patternSeg.includes('*')) return patternSeg === name;
79
+ if (patternSeg === '*') return true
80
+ if (!patternSeg.includes('*')) return patternSeg === name
84
81
 
85
- const escaped = patternSeg.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
86
- const regex = new RegExp('^' + escaped.replaceAll('*', '.*') + '$');
87
- return regex.test(name);
82
+ const escaped = patternSeg.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
83
+ const regex = new RegExp('^' + escaped.replaceAll('*', '.*') + '$')
84
+ return regex.test(name)
88
85
  }
89
86
 
90
- async function expandWorkspacePattern(
91
- root: string,
92
- pattern: string
93
- ): Promise<string[]> {
94
- const segs = toPosix(pattern).split('/').filter(Boolean);
95
-
96
- async function expandFrom(dir: string, segIndex: number): Promise<string[]> {
97
- // Always resolve dir relative to working directory
98
- const absDir = path.resolve(process.cwd(), dir);
99
- if (segIndex >= segs.length) return [absDir];
100
-
101
- const seg = segs[segIndex];
102
-
103
- if (seg === '**') {
104
- const results: string[] = [];
105
- results.push(...(await expandFrom(absDir, segIndex + 1)));
106
-
107
- const entries = await fs
108
- .readdir(absDir, { withFileTypes: true })
109
- .catch(() => []);
110
- for (const e of entries) {
111
- if (e.isDirectory()) {
112
- results.push(
113
- ...(await expandFrom(path.join(absDir, e.name), segIndex))
114
- );
115
- }
116
- }
117
- return results;
118
- }
119
-
120
- const entries = await fs
121
- .readdir(absDir, { withFileTypes: true })
122
- .catch(() => []);
123
- const results: string[] = [];
124
- for (const e of entries) {
125
- if (e.isDirectory() && matchSegment(seg, e.name)) {
126
- results.push(
127
- ...(await expandFrom(path.join(absDir, e.name), segIndex + 1))
128
- );
129
- }
130
- }
131
- return results;
132
- }
133
-
134
- return [...new Set(await expandFrom(root, 0))];
87
+ async function expandWorkspacePattern(root: string, pattern: string): Promise<string[]> {
88
+ const segs = toPosix(pattern).split('/').filter(Boolean)
89
+
90
+ async function expandFrom(dir: string, segIndex: number): Promise<string[]> {
91
+ // Always resolve dir relative to working directory
92
+ const absDir = path.resolve(process.cwd(), dir)
93
+ if (segIndex >= segs.length) return [absDir]
94
+
95
+ const seg = segs[segIndex]
96
+
97
+ if (seg === '**') {
98
+ const results: string[] = []
99
+ results.push(...(await expandFrom(absDir, segIndex + 1)))
100
+
101
+ const entries = await fs.readdir(absDir, { withFileTypes: true }).catch(() => [])
102
+ for (const e of entries) {
103
+ if (e.isDirectory()) {
104
+ results.push(...(await expandFrom(path.join(absDir, e.name), segIndex)))
105
+ }
106
+ }
107
+ return results
108
+ }
109
+
110
+ const entries = await fs.readdir(absDir, { withFileTypes: true }).catch(() => [])
111
+ const results: string[] = []
112
+ for (const e of entries) {
113
+ if (e.isDirectory() && matchSegment(seg, e.name)) {
114
+ results.push(...(await expandFrom(path.join(absDir, e.name), segIndex + 1)))
115
+ }
116
+ }
117
+ return results
118
+ }
119
+
120
+ return [...new Set(await expandFrom(root, 0))]
135
121
  }
136
122
 
137
123
  async function findWorkspaceRoots(
138
- repoRoot: string,
139
- workspacePatterns: string[]
124
+ repoRoot: string,
125
+ workspacePatterns: string[]
140
126
  ): Promise<string[]> {
141
- const roots: string[] = [];
142
- for (const pat of workspacePatterns) {
143
- const expandedDirs = await expandWorkspacePattern(repoRoot, pat);
144
- roots.push(...expandedDirs);
145
- }
146
- return [...new Set(roots)];
127
+ const roots: string[] = []
128
+ for (const pat of workspacePatterns) {
129
+ const expandedDirs = await expandWorkspacePattern(repoRoot, pat)
130
+ roots.push(...expandedDirs)
131
+ }
132
+ return [...new Set(roots)]
147
133
  }
148
134
 
149
135
  // ----------------- package discovery -----------------
150
136
  const SKIP_DIRS = new Set([
151
- 'node_modules',
152
- '.git',
153
- '.next',
154
- 'dist',
155
- 'build',
156
- 'out',
157
- 'coverage',
158
- '.turbo',
159
- ]);
160
-
161
- async function findPackageJsonFilesRecursive(
162
- startDir: string
163
- ): Promise<string[]> {
164
- const found: string[] = [];
165
-
166
- async function walk(dir: string): Promise<void> {
167
- // Always resolve dir relative to working directory
168
- const absDir = path.resolve(process.cwd(), dir);
169
- const entries = await fs
170
- .readdir(absDir, { withFileTypes: true })
171
- .catch(() => []);
172
- for (const e of entries) {
173
- const full = path.join(absDir, e.name);
174
- if (e.isDirectory()) {
175
- if (!SKIP_DIRS.has(e.name)) await walk(full);
176
- } else if (e.isFile() && e.name === 'package.json') {
177
- found.push(full);
178
- }
179
- }
180
- }
181
-
182
- await walk(startDir);
183
- return found;
137
+ 'node_modules',
138
+ '.git',
139
+ '.next',
140
+ 'dist',
141
+ 'build',
142
+ 'out',
143
+ 'coverage',
144
+ '.turbo',
145
+ ])
146
+
147
+ async function findPackageJsonFilesRecursive(startDir: string): Promise<string[]> {
148
+ const found: string[] = []
149
+
150
+ async function walk(dir: string): Promise<void> {
151
+ // Always resolve dir relative to working directory
152
+ const absDir = path.resolve(process.cwd(), dir)
153
+ const entries = await fs.readdir(absDir, { withFileTypes: true }).catch(() => [])
154
+ for (const e of entries) {
155
+ const full = path.join(absDir, e.name)
156
+ if (e.isDirectory()) {
157
+ if (!SKIP_DIRS.has(e.name)) await walk(full)
158
+ } else if (e.isFile() && e.name === 'package.json') {
159
+ found.push(full)
160
+ }
161
+ }
162
+ }
163
+
164
+ await walk(startDir)
165
+ return found
184
166
  }
185
167
 
186
- async function collectPackagesFromWorkspaceRoots(
187
- workspaceRoots: string[]
188
- ): Promise<PackageInfo[]> {
189
- const pkgJsonFiles: string[] = [];
190
-
191
- for (const root of workspaceRoots) {
192
- if (await exists(root)) {
193
- pkgJsonFiles.push(...(await findPackageJsonFilesRecursive(root)));
194
- }
195
- }
196
-
197
- const packages: PackageInfo[] = [];
198
- for (const file of [...new Set(pkgJsonFiles)]) {
199
- if (path.resolve(file) === path.resolve(ROOT_PKG_JSON)) continue;
200
-
201
- try {
202
- const pj = await readJson<any>(file);
203
- const dir = path.dirname(file);
204
- packages.push({
205
- name: pj.name || toPosix(path.relative(REPO_ROOT, dir)),
206
- dir,
207
- scripts:
208
- isObject(pj.scripts) ? (pj.scripts as Record<string, string>) : {},
209
- });
210
- } catch {}
211
- }
212
-
213
- const seen = new Set<string>();
214
- return packages
215
- .sort((a, b) => a.name.localeCompare(b.name))
216
- .filter((p) => (seen.has(p.name) ? false : seen.add(p.name)));
168
+ async function collectPackagesFromWorkspaceRoots(workspaceRoots: string[]): Promise<PackageInfo[]> {
169
+ const pkgJsonFiles: string[] = []
170
+
171
+ for (const root of workspaceRoots) {
172
+ if (await exists(root)) {
173
+ pkgJsonFiles.push(...(await findPackageJsonFilesRecursive(root)))
174
+ }
175
+ }
176
+
177
+ const packages: PackageInfo[] = []
178
+ for (const file of [...new Set(pkgJsonFiles)]) {
179
+ if (path.resolve(file) === path.resolve(ROOT_PKG_JSON)) continue
180
+
181
+ try {
182
+ const pj = await readJson<any>(file)
183
+ const dir = path.dirname(file)
184
+ packages.push({
185
+ name: pj.name || toPosix(path.relative(REPO_ROOT, dir)),
186
+ dir,
187
+ scripts: isObject(pj.scripts) ? (pj.scripts as Record<string, string>) : {},
188
+ })
189
+ } catch {}
190
+ }
191
+
192
+ const seen = new Set<string>()
193
+ return packages
194
+ .sort((a, b) => a.name.localeCompare(b.name))
195
+ .filter((p) => (seen.has(p.name) ? false : seen.add(p.name)))
217
196
  }
218
197
 
219
198
  // ----------------- classification -----------------
220
199
  function classifyPackage(pkg: PackageInfo): string {
221
- const p = toPosix(pkg.dir);
222
- if (p.startsWith('apps/')) return 'Apps';
223
- if (p.startsWith('packages/')) return 'Libraries';
224
- return 'Other';
200
+ const p = toPosix(pkg.dir)
201
+ if (p.startsWith('apps/')) return 'Apps'
202
+ if (p.startsWith('packages/')) return 'Libraries'
203
+ return 'Other'
225
204
  }
226
205
  // ----------------- markdown generation -----------------
227
206
  function formatQuickStart(pkgMgr: string): string[] {
228
- return [
229
- '# 🗂️ Workspace Overview',
230
- '',
231
- 'This document explains how to run and discover commands in this monorepo.',
232
- '',
233
- '---',
234
- '',
235
- '## 🚀 Quick Start',
236
- '',
237
- 'Most developers only need the following:',
238
- '',
239
- '```bash',
240
- `${pkgMgr} dev`,
241
- `${pkgMgr} serve`,
242
- `${pkgMgr} mobile`,
243
- `${pkgMgr} help`,
244
- '```',
245
- '',
246
- 'Use `yarn mono` whenever possible. It handles environment setup,',
247
- 'workspace routing, and service coordination automatically.',
248
- '',
249
- '---',
250
- '',
251
- ];
207
+ return [
208
+ '# 🗂️ Workspace Overview',
209
+ '',
210
+ 'This document explains how to run and discover commands in this monorepo.',
211
+ '',
212
+ '---',
213
+ '',
214
+ '## 🚀 Quick Start',
215
+ '',
216
+ 'Most developers only need the following:',
217
+ '',
218
+ '```bash',
219
+ `${pkgMgr} dev`,
220
+ `${pkgMgr} serve`,
221
+ `${pkgMgr} mobile`,
222
+ `${pkgMgr} help`,
223
+ '```',
224
+ '',
225
+ 'Use `yarn mono` whenever possible. It handles environment setup,',
226
+ 'workspace routing, and service coordination automatically.',
227
+ '',
228
+ '---',
229
+ '',
230
+ ]
252
231
  }
253
232
 
254
233
  function formatReferenceIntro(): string[] {
255
- return [
256
- '## 📖 Reference',
257
- '',
258
- 'This section lists all workspace packages and their available scripts.',
259
- '',
260
- 'Use this when:',
261
- '- Debugging',
262
- '- Working on internal libraries',
263
- '- Running CI or low-level tooling',
264
- '',
265
- ];
234
+ return [
235
+ '## 📖 Reference',
236
+ '',
237
+ 'This section lists all workspace packages and their available scripts.',
238
+ '',
239
+ 'Use this when:',
240
+ '- Debugging',
241
+ '- Working on internal libraries',
242
+ '- Running CI or low-level tooling',
243
+ '',
244
+ ]
266
245
  }
267
246
 
268
247
  function formatIndex(packages: PackageInfo[]): string[] {
269
- const groups: Record<string, PackageInfo[]> = {};
270
- for (const p of packages) {
271
- const g = classifyPackage(p);
272
- groups[g] ||= [];
273
- groups[g].push(p);
274
- }
275
-
276
- const lines: string[] = ['## Workspace Index', ''];
277
- for (const group of Object.keys(groups)) {
278
- lines.push(`### ${group}`);
279
- lines.push('');
280
- for (const p of groups[group]) {
281
- lines.push(
282
- `- [\`${mdEscapeInline(p.name)}\`](#${slugifyForGithubAnchor(p.name)})`
283
- );
284
- }
285
- lines.push('');
286
- }
287
- return lines;
248
+ const groups: Record<string, PackageInfo[]> = {}
249
+ for (const p of packages) {
250
+ const g = classifyPackage(p)
251
+ groups[g] ||= []
252
+ groups[g].push(p)
253
+ }
254
+
255
+ const lines: string[] = ['## Workspace Index', '']
256
+ for (const group of Object.keys(groups)) {
257
+ lines.push(`### ${group}`)
258
+ lines.push('')
259
+ for (const p of groups[group]) {
260
+ lines.push(`- [\`${mdEscapeInline(p.name)}\`](#${slugifyForGithubAnchor(p.name)})`)
261
+ }
262
+ lines.push('')
263
+ }
264
+ return lines
288
265
  }
289
266
 
290
267
  function formatPackages(packages: PackageInfo[]): string[] {
291
- const lines: string[] = [];
292
-
293
- for (const p of packages) {
294
- lines.push(`### ${p.name}`);
295
- lines.push('');
296
- lines.push(`_Location: \`${toPosix(path.relative(REPO_ROOT, p.dir))}\`_`);
297
- lines.push('');
298
-
299
- const scripts = Object.keys(p.scripts).sort();
300
- if (!scripts.length) {
301
- lines.push('_No scripts defined._');
302
- lines.push('');
303
- continue;
304
- }
305
-
306
- lines.push('| Script | Recommended |');
307
- lines.push('|------|-------------|');
308
- for (const s of scripts) {
309
- lines.push(`| \`${s}\` | \`yarn mono ${p.name} ${s}\` |`);
310
- }
311
- lines.push('');
312
- lines.push('<details>');
313
- lines.push('<summary>Raw yarn workspace commands</summary>');
314
- lines.push('');
315
- for (const s of scripts) {
316
- lines.push(`- \`yarn workspace ${p.name} ${s}\``);
317
- }
318
- lines.push('</details>');
319
- lines.push('');
320
- }
321
-
322
- return lines;
268
+ const lines: string[] = []
269
+
270
+ for (const p of packages) {
271
+ lines.push(`### ${p.name}`)
272
+ lines.push('')
273
+ lines.push(`_Location: \`${toPosix(path.relative(REPO_ROOT, p.dir))}\`_`)
274
+ lines.push('')
275
+
276
+ const scripts = Object.keys(p.scripts).sort()
277
+ if (!scripts.length) {
278
+ lines.push('_No scripts defined._')
279
+ lines.push('')
280
+ continue
281
+ }
282
+
283
+ lines.push('| Script | Recommended |')
284
+ lines.push('|------|-------------|')
285
+ for (const s of scripts) {
286
+ lines.push(`| \`${s}\` | \`yarn mono ${p.name} ${s}\` |`)
287
+ }
288
+ lines.push('')
289
+ lines.push('<details>')
290
+ lines.push('<summary>Raw yarn workspace commands</summary>')
291
+ lines.push('')
292
+ for (const s of scripts) {
293
+ lines.push(`- \`yarn workspace ${p.name} ${s}\``)
294
+ }
295
+ lines.push('</details>')
296
+ lines.push('')
297
+ }
298
+
299
+ return lines
323
300
  }
324
301
 
325
302
  async function ensureParentDir(filePath: string): Promise<void> {
326
- // Always resolve parent dir relative to working directory
327
- const dir = path.resolve(process.cwd(), path.dirname(filePath));
328
- await fs.mkdir(dir, { recursive: true });
303
+ // Always resolve parent dir relative to working directory
304
+ const dir = path.resolve(process.cwd(), path.dirname(filePath))
305
+ await fs.mkdir(dir, { recursive: true })
329
306
  }
330
307
 
331
308
  // ----------------- main -----------------
332
309
  async function main(): Promise<void> {
333
- // Always resolve all paths relative to working directory
334
- if (!(await exists(ROOT_PKG_JSON))) {
335
- throw new Error('Root package.json not found');
336
- }
310
+ // Always resolve all paths relative to working directory
311
+ if (!(await exists(ROOT_PKG_JSON))) {
312
+ throw new Error('Root package.json not found')
313
+ }
337
314
 
338
- const rootPkg = await readJson<any>(ROOT_PKG_JSON);
339
- const workspacePatterns = normalizeWorkspacePatterns(rootPkg.workspaces);
315
+ const rootPkg = await readJson<any>(ROOT_PKG_JSON)
316
+ const workspacePatterns = normalizeWorkspacePatterns(rootPkg.workspaces)
340
317
 
341
- const pkgMgr = `${(rootPkg.packageManager || 'yarn').split('@')[0]} mono`;
318
+ const pkgMgr = `${(rootPkg.packageManager || 'yarn').split('@')[0]} mono`
342
319
 
343
- const workspaceRoots = await findWorkspaceRoots(REPO_ROOT, workspacePatterns);
344
- const fallbackRoots = ['packages', 'apps'].map((p) =>
345
- path.join(REPO_ROOT, p)
346
- );
347
- const roots = workspaceRoots.length ? workspaceRoots : fallbackRoots;
320
+ const workspaceRoots = await findWorkspaceRoots(REPO_ROOT, workspacePatterns)
321
+ const fallbackRoots = ['packages', 'apps'].map((p) => path.join(REPO_ROOT, p))
322
+ const roots = workspaceRoots.length ? workspaceRoots : fallbackRoots
348
323
 
349
- const packages = await collectPackagesFromWorkspaceRoots(roots);
324
+ const packages = await collectPackagesFromWorkspaceRoots(roots)
350
325
 
351
- const lines: string[] = [];
352
- lines.push(...formatQuickStart(pkgMgr));
353
- lines.push(...formatReferenceIntro());
354
- lines.push(...formatIndex(packages));
355
- lines.push('## Packages');
356
- lines.push('');
357
- lines.push(...formatPackages(packages));
326
+ const lines: string[] = []
327
+ lines.push(...formatQuickStart(pkgMgr))
328
+ lines.push(...formatReferenceIntro())
329
+ lines.push(...formatIndex(packages))
330
+ lines.push('## Packages')
331
+ lines.push('')
332
+ lines.push(...formatPackages(packages))
358
333
 
359
- const val = await generateDocsIndex({
360
- docsDir: path.join(REPO_ROOT, 'docs'),
361
- excludeFile: 'workspaces.md',
362
- });
334
+ const val = await generateDocsIndex({
335
+ docsDir: path.join(REPO_ROOT, 'docs'),
336
+ excludeFile: 'workspaces.md',
337
+ })
363
338
 
364
- val.split('\n').forEach((line) => lines.push(line));
339
+ val.split('\n').forEach((line) => lines.push(line))
365
340
 
366
- await ensureParentDir(OUTPUT_PATH);
367
- await fs.writeFile(OUTPUT_PATH, lines.join('\n'), 'utf8');
341
+ await ensureParentDir(OUTPUT_PATH)
342
+ await fs.writeFile(OUTPUT_PATH, lines.join('\n'), 'utf8')
368
343
 
369
- console.log(`✅ Generated ${OUTPUT_PATH}`);
370
- console.log(`📦 Packages found: ${packages.length}`);
344
+ console.log(`✅ Generated ${OUTPUT_PATH}`)
345
+ console.log(`📦 Packages found: ${packages.length}`)
371
346
  }
372
347
 
373
348
  main().catch((err) => {
374
- console.error(err);
375
- process.exitCode = 1;
376
- });
349
+ console.error(err)
350
+ process.exitCode = 1
351
+ })