@mono-labs/cli 0.0.206 → 0.0.208

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.
@@ -1,36 +1,33 @@
1
1
  "use strict";
2
- // scripts/generate-readme.ts
3
- // Node >= 18 recommended
4
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
5
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
4
  };
7
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ // scripts/generate-readme.mjs
7
+ // Node >= 18 recommended
8
8
  const node_fs_1 = require("node:fs");
9
9
  const node_path_1 = __importDefault(require("node:path"));
10
10
  const generate_docs_js_1 = require("./generate-docs.js");
11
- /* -------------------------------------------------------------------------- */
12
- /* Path helpers */
13
- /* -------------------------------------------------------------------------- */
14
- // Always use the working directory as the root for all file actions
15
11
  const REPO_ROOT = node_path_1.default.resolve(process.cwd());
16
12
  const MONO_DIR = node_path_1.default.join(REPO_ROOT, '.mono');
17
13
  const ROOT_PKG_JSON = node_path_1.default.join(REPO_ROOT, 'package.json');
18
14
  const OUTPUT_PATH = node_path_1.default.join(REPO_ROOT, 'docs');
19
15
  const OUTPUT_README = node_path_1.default.join(OUTPUT_PATH, 'command-line.md');
20
- /* -------------------------------------------------------------------------- */
21
- /* Utils */
22
- /* -------------------------------------------------------------------------- */
23
16
  async function ensureParentDir(filePath) {
24
- // Always resolve parent dir relative to working directory
25
- const dir = node_path_1.default.resolve(process.cwd(), node_path_1.default.dirname(filePath));
17
+ const dir = node_path_1.default.dirname(filePath);
18
+ console.log(`[ensureParentDir] Ensuring directory:`, dir);
26
19
  await node_fs_1.promises.mkdir(dir, { recursive: true });
27
20
  }
21
+ // ---------- utils ----------
28
22
  async function exists(p) {
29
23
  try {
30
24
  await node_fs_1.promises.access(p);
25
+ // Log existence check
26
+ console.log(`[exists] Path exists:`, p);
31
27
  return true;
32
28
  }
33
29
  catch {
30
+ console.log(`[exists] Path does NOT exist:`, p);
34
31
  return false;
35
32
  }
36
33
  }
@@ -41,110 +38,135 @@ function toPosix(p) {
41
38
  return p.split(node_path_1.default.sep).join('/');
42
39
  }
43
40
  async function readJson(filePath) {
44
- // Always resolve filePath relative to working directory
45
- const absPath = node_path_1.default.resolve(process.cwd(), filePath);
46
- const raw = await node_fs_1.promises.readFile(absPath, 'utf8');
47
- return JSON.parse(raw);
41
+ console.log(`[readJson] Reading JSON file:`, filePath);
42
+ const raw = await node_fs_1.promises.readFile(filePath, 'utf8');
43
+ try {
44
+ const parsed = JSON.parse(raw);
45
+ console.log(`[readJson] Successfully parsed:`, filePath);
46
+ return parsed;
47
+ }
48
+ catch (err) {
49
+ console.error(`[readJson] Failed to parse JSON:`, filePath, err);
50
+ throw err;
51
+ }
48
52
  }
49
53
  async function listDir(dir) {
50
- // Always resolve dir relative to working directory
51
- const absDir = node_path_1.default.resolve(process.cwd(), dir);
52
- return node_fs_1.promises.readdir(absDir, { withFileTypes: true });
54
+ console.log(`[listDir] Listing directory:`, dir);
55
+ const entries = await node_fs_1.promises.readdir(dir, { withFileTypes: true });
56
+ console.log(`[listDir] Found ${entries.length} entries in:`, dir);
57
+ return entries;
53
58
  }
54
59
  function normalizeWorkspacePatterns(workspacesField) {
55
60
  if (Array.isArray(workspacesField))
56
61
  return workspacesField;
57
62
  if (isObject(workspacesField) &&
58
- Array.isArray(workspacesField.packages)) {
63
+ Array.isArray(workspacesField.packages))
59
64
  return workspacesField.packages;
60
- }
61
65
  return [];
62
66
  }
63
- function mdEscapeInline(value) {
64
- return String(value ?? '').replaceAll('`', '\\`');
67
+ function mdEscapeInline(s) {
68
+ return String(s ?? '').replaceAll('`', '\`');
65
69
  }
66
70
  function indentLines(s, spaces = 2) {
67
71
  const pad = ' '.repeat(spaces);
68
- return s
72
+ return String(s ?? '')
69
73
  .split('\n')
70
- .map((line) => pad + line)
74
+ .map((l) => pad + l)
71
75
  .join('\n');
72
76
  }
73
- /* -------------------------------------------------------------------------- */
74
- /* Workspace glob pattern expansion */
75
- /* -------------------------------------------------------------------------- */
77
+ // ---------- workspace glob matching (supports *, **, and plain segments) ----------
76
78
  function matchSegment(patternSeg, name) {
77
79
  if (patternSeg === '*')
78
80
  return true;
79
81
  if (!patternSeg.includes('*'))
80
82
  return patternSeg === name;
81
83
  const escaped = patternSeg.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
82
- const regex = new RegExp(`^${escaped.replaceAll('*', '.*')}$`);
84
+ const regex = new RegExp('^' + escaped.replaceAll('*', '.*') + '$');
83
85
  return regex.test(name);
84
86
  }
85
87
  async function expandWorkspacePattern(root, pattern) {
86
- const segments = toPosix(pattern).split('/').filter(Boolean);
87
- async function expandFrom(dir, index) {
88
- // Always resolve dir relative to working directory
89
- const absDir = node_path_1.default.resolve(process.cwd(), dir);
90
- if (index >= segments.length)
91
- return [absDir];
92
- const seg = segments[index];
88
+ console.log(`[expandWorkspacePattern] Expanding pattern:`, pattern, `from root:`, root);
89
+ const segs = toPosix(pattern).split('/').filter(Boolean);
90
+ async function expandFrom(dir, segIndex) {
91
+ console.log(`[expandFrom] Directory:`, dir, `Segment index:`, segIndex);
92
+ if (segIndex >= segs.length)
93
+ return [dir];
94
+ const seg = segs[segIndex];
95
+ console.log(`[expandFrom] Segment:`, seg);
93
96
  if (seg === '**') {
94
97
  const results = [];
95
- results.push(...(await expandFrom(absDir, index + 1)));
98
+ results.push(...(await expandFrom(dir, segIndex + 1)));
96
99
  const entries = await node_fs_1.promises
97
- .readdir(absDir, { withFileTypes: true })
100
+ .readdir(dir, { withFileTypes: true })
98
101
  .catch(() => []);
99
- for (const entry of entries) {
100
- if (!entry.isDirectory())
102
+ console.log(`[expandFrom] '**' entries in ${dir}:`, entries.map((e) => e.name));
103
+ for (const e of entries) {
104
+ if (!e.isDirectory())
101
105
  continue;
102
- results.push(...(await expandFrom(node_path_1.default.join(absDir, entry.name), index)));
106
+ console.log(`[expandFrom] Recursing into subdir:`, node_path_1.default.join(dir, e.name));
107
+ results.push(...(await expandFrom(node_path_1.default.join(dir, e.name), segIndex)));
103
108
  }
104
109
  return results;
105
110
  }
106
111
  const entries = await node_fs_1.promises
107
- .readdir(absDir, { withFileTypes: true })
112
+ .readdir(dir, { withFileTypes: true })
108
113
  .catch(() => []);
114
+ console.log(`[expandFrom] Entries in ${dir}:`, entries.map((e) => e.name));
109
115
  const results = [];
110
- for (const entry of entries) {
111
- if (!entry.isDirectory())
116
+ for (const e of entries) {
117
+ if (!e.isDirectory())
112
118
  continue;
113
- if (!matchSegment(seg, entry.name))
119
+ if (!matchSegment(seg, e.name))
114
120
  continue;
115
- results.push(...(await expandFrom(node_path_1.default.join(absDir, entry.name), index + 1)));
121
+ console.log(`[expandFrom] Matched segment '${seg}' with directory:`, e.name);
122
+ results.push(...(await expandFrom(node_path_1.default.join(dir, e.name), segIndex + 1)));
116
123
  }
117
124
  return results;
118
125
  }
119
126
  const dirs = await expandFrom(root, 0);
127
+ console.log(`[expandWorkspacePattern] Expanded directories:`, dirs);
120
128
  const pkgDirs = [];
121
129
  for (const d of dirs) {
122
- if (await exists(node_path_1.default.join(d, 'package.json'))) {
130
+ const pkgPath = node_path_1.default.join(d, 'package.json');
131
+ if (await exists(pkgPath)) {
132
+ console.log(`[expandWorkspacePattern] Found package.json:`, pkgPath);
123
133
  pkgDirs.push(d);
124
134
  }
135
+ else {
136
+ console.log(`[expandWorkspacePattern] No package.json in:`, d);
137
+ }
125
138
  }
126
- return Array.from(new Set(pkgDirs));
139
+ console.log(`[expandWorkspacePattern] Final package directories:`, pkgDirs);
140
+ return [...new Set(pkgDirs)];
127
141
  }
128
- async function findWorkspacePackageDirs(repoRoot, patterns) {
142
+ async function findWorkspacePackageDirs(repoRoot, workspacePatterns) {
143
+ console.log(`[findWorkspacePackageDirs] repoRoot:`, repoRoot, `workspacePatterns:`, workspacePatterns);
129
144
  const dirs = [];
130
- for (const pat of patterns) {
131
- dirs.push(...(await expandWorkspacePattern(repoRoot, pat)));
145
+ for (const pat of workspacePatterns) {
146
+ console.log(`[findWorkspacePackageDirs] Expanding pattern:`, pat);
147
+ const expanded = await expandWorkspacePattern(repoRoot, pat);
148
+ console.log(`[findWorkspacePackageDirs] Expanded dirs for pattern '${pat}':`, expanded);
149
+ dirs.push(...expanded);
132
150
  }
133
- return Array.from(new Set(dirs));
151
+ const uniqueDirs = [...new Set(dirs)];
152
+ console.log(`[findWorkspacePackageDirs] Final unique package dirs:`, uniqueDirs);
153
+ return uniqueDirs;
134
154
  }
135
- /* -------------------------------------------------------------------------- */
136
- /* .mono configuration */
137
- /* -------------------------------------------------------------------------- */
155
+ // ---------- .mono parsing ----------
138
156
  async function readMonoConfig() {
139
- // Always resolve configPath relative to working directory
140
- const configPath = node_path_1.default.resolve(process.cwd(), node_path_1.default.join(MONO_DIR, 'config.json'));
141
- if (!(await exists(configPath)))
157
+ const configPath = node_path_1.default.join(MONO_DIR, 'config.json');
158
+ console.log(`[readMonoConfig] Looking for mono config at:`, configPath);
159
+ if (!(await exists(configPath))) {
160
+ console.log(`[readMonoConfig] No mono config found.`);
142
161
  return null;
162
+ }
143
163
  try {
144
164
  const config = await readJson(configPath);
165
+ console.log(`[readMonoConfig] Loaded mono config.`);
145
166
  return { path: configPath, config };
146
167
  }
147
- catch {
168
+ catch (err) {
169
+ console.error(`[readMonoConfig] Failed to load mono config:`, err);
148
170
  return null;
149
171
  }
150
172
  }
@@ -152,44 +174,52 @@ function commandNameFromFile(filePath) {
152
174
  return node_path_1.default.basename(filePath).replace(/\.json$/i, '');
153
175
  }
154
176
  async function readMonoCommands() {
155
- // Always resolve MONO_DIR relative to working directory
156
- const monoDirAbs = node_path_1.default.resolve(process.cwd(), MONO_DIR);
157
- if (!(await exists(monoDirAbs)))
177
+ console.log(`[readMonoCommands] Reading mono commands from:`, MONO_DIR);
178
+ if (!(await exists(MONO_DIR))) {
179
+ console.log(`[readMonoCommands] Mono directory does not exist.`);
158
180
  return [];
159
- const entries = await listDir(monoDirAbs);
181
+ }
182
+ const entries = await listDir(MONO_DIR);
160
183
  const jsonFiles = entries
161
- .filter((e) => e.isFile() && e.name.endsWith('.json'))
162
- .map((e) => node_path_1.default.join(monoDirAbs, e.name))
163
- .filter((p) => node_path_1.default.basename(p) !== 'config.json');
184
+ .filter((e) => e.isFile() && e.name.toLowerCase().endsWith('.json'))
185
+ .map((e) => node_path_1.default.join(MONO_DIR, e.name))
186
+ .filter((p) => node_path_1.default.basename(p).toLowerCase() !== 'config.json');
187
+ console.log(`[readMonoCommands] Found JSON files:`, jsonFiles);
164
188
  const commands = [];
165
189
  for (const file of jsonFiles) {
166
190
  try {
167
- const json = await readJson(file);
191
+ console.log(`[readMonoCommands] Reading command file:`, file);
192
+ const j = await readJson(file);
168
193
  commands.push({
169
194
  name: commandNameFromFile(file),
170
195
  file,
171
- json,
196
+ json: j,
172
197
  });
198
+ console.log(`[readMonoCommands] Successfully loaded command:`, commandNameFromFile(file));
173
199
  }
174
- catch {
175
- /* ignore invalid JSON */
200
+ catch (err) {
201
+ console.error(`[readMonoCommands] Failed to load command file:`, file, err);
202
+ // skip invalid json
176
203
  }
177
204
  }
178
- return commands.sort((a, b) => a.name.localeCompare(b.name));
205
+ commands.sort((a, b) => a.name.localeCompare(b.name));
206
+ console.log(`[readMonoCommands] Final sorted commands:`, commands.map((c) => c.name));
207
+ return commands;
179
208
  }
180
- /* -------------------------------------------------------------------------- */
181
- /* Options schema parsing */
182
- /* -------------------------------------------------------------------------- */
183
209
  function parseOptionsSchema(optionsObj) {
210
+ // New structure supports:
211
+ // - optionKey: { type: "string", default, options: [], allowAll, shortcut, description }
212
+ // - boolean toggle: { shortcut, description } (no type)
184
213
  if (!isObject(optionsObj))
185
214
  return [];
186
215
  const entries = Object.entries(optionsObj).map(([key, raw]) => {
187
216
  const o = isObject(raw) ? raw : {};
188
- const hasType = typeof o.type === 'string' && o.type.length > 0;
217
+ const hasType = typeof o.type === 'string' && o.type.trim().length > 0;
218
+ const isBoolToggle = !hasType; // in your examples, booleans omit `type`
189
219
  return {
190
220
  key,
191
- kind: hasType ? 'value' : 'boolean',
192
- type: hasType ? o.type : 'boolean',
221
+ kind: isBoolToggle ? 'boolean' : 'value',
222
+ type: hasType ? String(o.type) : 'boolean',
193
223
  description: typeof o.description === 'string' ? o.description : '',
194
224
  shortcut: typeof o.shortcut === 'string' ? o.shortcut : '',
195
225
  default: o.default,
@@ -197,81 +227,274 @@ function parseOptionsSchema(optionsObj) {
197
227
  allowAll: o.allowAll === true,
198
228
  };
199
229
  });
200
- return entries.sort((a, b) => a.key.localeCompare(b.key));
230
+ entries.sort((a, b) => a.key.localeCompare(b.key));
231
+ return entries;
201
232
  }
202
- /* -------------------------------------------------------------------------- */
203
- /* Formatting */
204
- /* -------------------------------------------------------------------------- */
205
233
  function buildUsageExample(commandName, cmdJson, options) {
206
- const arg = cmdJson.argument;
234
+ const arg = cmdJson?.argument;
207
235
  const hasArg = isObject(arg);
208
- const parts = [`yarn mono ${commandName}`];
209
- if (hasArg)
210
- parts.push(`<${commandName}-arg>`);
236
+ const argToken = hasArg ? `<${commandName}-arg>` : '';
237
+ // choose a representative value option to show
211
238
  const valueOpts = options.filter((o) => o.kind === 'value');
212
239
  const boolOpts = options.filter((o) => o.kind === 'boolean');
240
+ const exampleParts = [`yarn mono ${commandName}`];
241
+ if (argToken)
242
+ exampleParts.push(argToken);
243
+ // include at most 2 value options and 1 boolean in the example for readability
213
244
  for (const o of valueOpts.slice(0, 2)) {
214
- const value = o.default !== undefined ?
215
- String(o.default)
216
- : (o.allowed?.[0] ?? '<value>');
217
- parts.push(`--${o.key} ${value}`);
245
+ const flag = `--${o.key}`;
246
+ const val = o.default !== undefined ? o.default : (o.allowed?.[0] ?? '<value>');
247
+ exampleParts.push(`${flag} ${val}`);
218
248
  }
219
- if (boolOpts[0]) {
220
- parts.push(`--${boolOpts[0].key}`);
249
+ if (boolOpts.length) {
250
+ exampleParts.push(`--${boolOpts[0].key}`);
221
251
  }
222
- return parts.join(' ');
252
+ return exampleParts.join(' ');
223
253
  }
224
- /* -------------------------------------------------------------------------- */
225
- /* Main */
226
- /* -------------------------------------------------------------------------- */
227
- async function main() {
228
- // Always resolve all paths relative to working directory
229
- if (!(await exists(ROOT_PKG_JSON))) {
230
- throw new Error(`Missing ${ROOT_PKG_JSON}`);
254
+ function formatMonoConfigSection(monoConfig) {
255
+ const lines = [];
256
+ lines.push('## Mono configuration');
257
+ lines.push('');
258
+ if (!monoConfig) {
259
+ lines.push('_No `.mono/config.json` found._');
260
+ return lines.join('\n');
261
+ }
262
+ const c = monoConfig.config;
263
+ lines.push(`Source: \`${toPosix(node_path_1.default.relative(REPO_ROOT, monoConfig.path))}\``);
264
+ lines.push('');
265
+ if (Array.isArray(c.envMap) && c.envMap.length) {
266
+ lines.push('### envMap');
267
+ lines.push('');
268
+ lines.push('- ' + c.envMap.map((x) => `\`${mdEscapeInline(x)}\``).join(', '));
269
+ lines.push('');
270
+ }
271
+ const pkgMaps = c?.workspace?.packageMaps;
272
+ if (pkgMaps && isObject(pkgMaps) && Object.keys(pkgMaps).length) {
273
+ lines.push('### Workspace aliases (packageMaps)');
274
+ lines.push('');
275
+ const entries = Object.entries(pkgMaps).sort(([a], [b]) => a.localeCompare(b));
276
+ for (const [alias, target] of entries) {
277
+ lines.push(`- \`${mdEscapeInline(alias)}\` → \`${mdEscapeInline(String(target))}\``);
278
+ }
279
+ lines.push('');
280
+ }
281
+ const pre = c?.workspace?.preactions;
282
+ if (Array.isArray(pre) && pre.length) {
283
+ lines.push('### Global preactions');
284
+ lines.push('');
285
+ lines.push('```bash');
286
+ for (const p of pre)
287
+ lines.push(String(p));
288
+ lines.push('```');
289
+ lines.push('');
231
290
  }
291
+ if (typeof c.prodFlag === 'string' && c.prodFlag.trim()) {
292
+ lines.push('### prodFlag');
293
+ lines.push('');
294
+ lines.push(`Production flag keyword: \`${mdEscapeInline(c.prodFlag.trim())}\``);
295
+ lines.push('');
296
+ }
297
+ return lines.join('\n');
298
+ }
299
+ function formatMonoCommandsSection(commands) {
300
+ const lines = [];
301
+ lines.push('## Mono commands');
302
+ lines.push('');
303
+ lines.push('Generated from `.mono/*.json` (excluding `config.json`). Each filename becomes a command:');
304
+ lines.push('');
305
+ lines.push('```bash');
306
+ lines.push('yarn mono <command> [argument] [--options]');
307
+ lines.push('```');
308
+ lines.push('');
309
+ if (!commands.length) {
310
+ lines.push('_No mono command JSON files found._');
311
+ return lines.join('\n');
312
+ }
313
+ // Index
314
+ lines.push('### Command index');
315
+ lines.push('');
316
+ for (const c of commands) {
317
+ const desc = typeof c.json?.description === 'string' ? c.json.description.trim() : '';
318
+ const suffix = desc ? ` — ${desc}` : '';
319
+ lines.push(`- [\`${mdEscapeInline(c.name)}\`](#mono-command-${mdEscapeInline(c.name).toLowerCase()})${suffix}`);
320
+ }
321
+ lines.push('');
322
+ for (const c of commands) {
323
+ const j = c.json || {};
324
+ const rel = toPosix(node_path_1.default.relative(REPO_ROOT, c.file));
325
+ const anchor = `mono-command-${c.name.toLowerCase()}`;
326
+ const desc = typeof j.description === 'string' ? j.description.trim() : '';
327
+ const arg = j.argument;
328
+ const options = parseOptionsSchema(j.options);
329
+ lines.push('---');
330
+ lines.push(`### Mono command: ${c.name}`);
331
+ lines.push(`<a id="${anchor}"></a>`);
332
+ lines.push('');
333
+ lines.push(`Source: \`${rel}\``);
334
+ lines.push('');
335
+ if (desc) {
336
+ lines.push(`**Description:** ${mdEscapeInline(desc)}`);
337
+ lines.push('');
338
+ }
339
+ // Usage
340
+ lines.push('**Usage**');
341
+ lines.push('');
342
+ lines.push('```bash');
343
+ lines.push(`yarn mono ${c.name}${isObject(arg) ? ` <${c.name}-arg>` : ''} [--options]`);
344
+ lines.push('```');
345
+ lines.push('');
346
+ lines.push('Example:');
347
+ lines.push('');
348
+ lines.push('```bash');
349
+ lines.push(buildUsageExample(c.name, j, options));
350
+ lines.push('```');
351
+ lines.push('');
352
+ // Argument
353
+ if (isObject(arg)) {
354
+ lines.push('**Argument**');
355
+ lines.push('');
356
+ const bits = [];
357
+ if (typeof arg.type === 'string')
358
+ bits.push(`type: \`${mdEscapeInline(arg.type)}\``);
359
+ if (arg.default !== undefined)
360
+ bits.push(`default: \`${mdEscapeInline(String(arg.default))}\``);
361
+ if (typeof arg.description === 'string')
362
+ bits.push(mdEscapeInline(arg.description));
363
+ lines.push(`- ${bits.join(' • ') || '_(no details)_'} `);
364
+ lines.push('');
365
+ }
366
+ // Options
367
+ if (options.length) {
368
+ lines.push('**Options**');
369
+ lines.push('');
370
+ lines.push('| Option | Type | Shortcut | Default | Allowed | Notes |');
371
+ lines.push('|---|---:|:---:|---:|---|---|');
372
+ for (const o of options) {
373
+ const optCol = o.kind === 'boolean' ?
374
+ `\`--${mdEscapeInline(o.key)}\``
375
+ : `\`--${mdEscapeInline(o.key)} <${mdEscapeInline(o.key)}>\``;
376
+ const typeCol = `\`${mdEscapeInline(o.type)}\``;
377
+ const shortCol = o.shortcut ? `\`-${mdEscapeInline(o.shortcut)}\`` : '';
378
+ const defCol = o.default !== undefined ? `\`${mdEscapeInline(o.default)}\`` : '';
379
+ const allowedCol = o.allowed ?
380
+ o.allowed.map((x) => `\`${mdEscapeInline(x)}\``).join(', ')
381
+ : '';
382
+ const notes = [
383
+ o.allowAll ? 'allowAll' : '',
384
+ o.description ? mdEscapeInline(o.description) : '',
385
+ ]
386
+ .filter(Boolean)
387
+ .join(' • ');
388
+ lines.push(`| ${optCol} | ${typeCol} | ${shortCol} | ${defCol} | ${allowedCol} | ${notes} |`);
389
+ }
390
+ lines.push('');
391
+ }
392
+ // Environments
393
+ if (j.environments &&
394
+ isObject(j.environments) &&
395
+ Object.keys(j.environments).length) {
396
+ lines.push('**Environment Variables**');
397
+ lines.push('');
398
+ const envs = Object.entries(j.environments).sort(([a], [b]) => a.localeCompare(b));
399
+ for (const [envName, envObj] of envs) {
400
+ lines.push(`- \`${mdEscapeInline(envName)}\``);
401
+ if (isObject(envObj) && Object.keys(envObj).length) {
402
+ const kv = Object.entries(envObj).sort(([a], [b]) => a.localeCompare(b));
403
+ lines.push(indentLines(kv
404
+ .map(([k, v]) => `- \`${mdEscapeInline(k)}\` = \`${mdEscapeInline(String(v))}\``)
405
+ .join('\n'), 2));
406
+ }
407
+ }
408
+ lines.push('');
409
+ }
410
+ // preactions/actions
411
+ if (Array.isArray(j.preactions) && j.preactions.length) {
412
+ lines.push('**Preactions**');
413
+ lines.push('');
414
+ lines.push('```bash');
415
+ for (const p of j.preactions)
416
+ lines.push(String(p));
417
+ lines.push('```');
418
+ lines.push('');
419
+ }
420
+ if (Array.isArray(j.actions) && j.actions.length) {
421
+ lines.push('**Actions**');
422
+ lines.push('');
423
+ lines.push('```bash');
424
+ for (const a of j.actions)
425
+ lines.push(String(a));
426
+ lines.push('```');
427
+ lines.push('');
428
+ }
429
+ }
430
+ return lines.join('\n');
431
+ }
432
+ function collectScripts(packages) {
433
+ const scriptToPackages = new Map();
434
+ for (const p of packages) {
435
+ for (const scriptName of Object.keys(p.scripts || {})) {
436
+ if (!scriptToPackages.has(scriptName))
437
+ scriptToPackages.set(scriptName, []);
438
+ scriptToPackages.get(scriptName).push(p.name);
439
+ }
440
+ }
441
+ return scriptToPackages;
442
+ }
443
+ // ---------- main ----------
444
+ async function main() {
445
+ if (!(await exists(ROOT_PKG_JSON)))
446
+ throw new Error(`Missing: ${ROOT_PKG_JSON}`);
232
447
  await ensureParentDir(OUTPUT_PATH);
233
448
  const rootPkg = await readJson(ROOT_PKG_JSON);
234
449
  const workspacePatterns = normalizeWorkspacePatterns(rootPkg.workspaces);
235
450
  const monoConfig = await readMonoConfig();
236
451
  const monoCommands = await readMonoCommands();
237
452
  const pkgDirs = await findWorkspacePackageDirs(REPO_ROOT, workspacePatterns);
453
+ console.log(`[main] Package directories found:`, pkgDirs);
238
454
  const packages = [];
239
455
  for (const dir of pkgDirs) {
240
456
  try {
241
- const pkg = await readJson(node_path_1.default.join(dir, 'package.json'));
457
+ const pkgPath = node_path_1.default.join(dir, 'package.json');
458
+ console.log(`[main] Reading package.json:`, pkgPath);
459
+ const pj = await readJson(pkgPath);
242
460
  packages.push({
243
- name: pkg.name ??
244
- toPosix(node_path_1.default.relative(REPO_ROOT, dir)) ??
461
+ name: pj.name ||
462
+ toPosix(node_path_1.default.relative(REPO_ROOT, dir)) ||
245
463
  node_path_1.default.basename(dir),
246
464
  dir,
247
- scripts: pkg.scripts ?? {},
465
+ scripts: pj.scripts || {},
248
466
  });
467
+ console.log(`[main] Loaded package:`, pj.name || dir);
249
468
  }
250
- catch {
251
- /* ignore */
469
+ catch (err) {
470
+ console.error(`[main] Failed to load package.json for:`, dir, err);
471
+ // skip
252
472
  }
253
473
  }
254
474
  const parts = [];
255
475
  parts.push(`# Mono Command-Line Reference
256
476
 
257
- > Generated by \`scripts/generate-readme.ts\`.
477
+ > Generated by \`scripts/generate-readme.mjs\`.
478
+ > Update \`.mono/config.json\`, \`.mono/*.json\`, and workspace package scripts to change this output.
258
479
 
259
480
  `);
260
- // Reuse your existing formatters here
261
- // (unchanged logic, now fully typed)
262
- const docsIndex = await (0, generate_docs_js_1.generateDocsIndex)({
481
+ parts.push(formatMonoConfigSection(monoConfig));
482
+ parts.push('');
483
+ parts.push(formatMonoCommandsSection(monoCommands));
484
+ parts.push('');
485
+ const val = await (0, generate_docs_js_1.generateDocsIndex)({
263
486
  docsDir: node_path_1.default.join(REPO_ROOT, 'docs'),
264
487
  excludeFile: 'command-line.md',
265
488
  });
266
- parts.push(docsIndex);
489
+ val.split('\n').forEach((line) => parts.push(line));
267
490
  await ensureParentDir(OUTPUT_README);
268
491
  await node_fs_1.promises.writeFile(OUTPUT_README, parts.join('\n'), 'utf8');
269
- console.log(`Generated: ${OUTPUT_README}`);
270
- console.log(`- mono config: ${monoConfig ? 'yes' : 'no'}`);
271
- console.log(`- mono commands: ${monoCommands.length}`);
272
- console.log(`- workspace packages: ${packages.length}`);
492
+ console.log(`[main] Generated: ${OUTPUT_README}`);
493
+ console.log(`[main] mono config: ${monoConfig ? 'yes' : 'no'}`);
494
+ console.log(`[main] mono commands: ${monoCommands.length}`);
495
+ console.log(`[main] workspace packages: ${packages.length}`);
273
496
  }
274
497
  main().catch((err) => {
275
- console.error(err instanceof Error ? err.stack : err);
276
- process.exit(1);
498
+ console.error(err?.stack || String(err));
499
+ process.exitCode = 1;
277
500
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-labs/cli",
3
- "version": "0.0.206",
3
+ "version": "0.0.208",
4
4
  "description": "A CLI tool for building and deploying projects",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types.d.ts",