@memberjunction/cli 6.1.0-edge.1 → 6.1.0-edge.3

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 (91) hide show
  1. package/LICENSE +180 -4
  2. package/README.md +1 -1
  3. package/dist/commands/artifacts/reclassify.d.ts.map +1 -1
  4. package/dist/commands/artifacts/reclassify.js +2 -1
  5. package/dist/commands/artifacts/reclassify.js.map +1 -1
  6. package/dist/commands/codegen/manifest.d.ts +14 -0
  7. package/dist/commands/codegen/manifest.d.ts.map +1 -1
  8. package/dist/commands/codegen/manifest.js +26 -7
  9. package/dist/commands/codegen/manifest.js.map +1 -1
  10. package/dist/commands/dev/index.d.ts +7 -0
  11. package/dist/commands/dev/index.d.ts.map +1 -0
  12. package/dist/commands/dev/index.js +11 -0
  13. package/dist/commands/dev/index.js.map +1 -0
  14. package/dist/commands/dev/usage.d.ts +7 -0
  15. package/dist/commands/dev/usage.d.ts.map +1 -0
  16. package/dist/commands/dev/usage.js +10 -0
  17. package/dist/commands/dev/usage.js.map +1 -0
  18. package/dist/commands/dev/workspace/clean.d.ts +27 -0
  19. package/dist/commands/dev/workspace/clean.d.ts.map +1 -0
  20. package/dist/commands/dev/workspace/clean.js +87 -0
  21. package/dist/commands/dev/workspace/clean.js.map +1 -0
  22. package/dist/commands/dev/workspace/doctor.d.ts +28 -0
  23. package/dist/commands/dev/workspace/doctor.d.ts.map +1 -0
  24. package/dist/commands/dev/workspace/doctor.js +62 -0
  25. package/dist/commands/dev/workspace/doctor.js.map +1 -0
  26. package/dist/commands/dev/workspace/index.d.ts +60 -0
  27. package/dist/commands/dev/workspace/index.d.ts.map +1 -0
  28. package/dist/commands/dev/workspace/index.js +279 -0
  29. package/dist/commands/dev/workspace/index.js.map +1 -0
  30. package/dist/commands/dev/workspace/status.d.ts +19 -0
  31. package/dist/commands/dev/workspace/status.d.ts.map +1 -0
  32. package/dist/commands/dev/workspace/status.js +46 -0
  33. package/dist/commands/dev/workspace/status.js.map +1 -0
  34. package/dist/lib/cli-plugins.d.ts.map +1 -1
  35. package/dist/lib/cli-plugins.js +5 -0
  36. package/dist/lib/cli-plugins.js.map +1 -1
  37. package/dist/lib/dev-workspace/build.d.ts +180 -0
  38. package/dist/lib/dev-workspace/build.d.ts.map +1 -0
  39. package/dist/lib/dev-workspace/build.js +570 -0
  40. package/dist/lib/dev-workspace/build.js.map +1 -0
  41. package/dist/lib/dev-workspace/clean.d.ts +40 -0
  42. package/dist/lib/dev-workspace/clean.d.ts.map +1 -0
  43. package/dist/lib/dev-workspace/clean.js +193 -0
  44. package/dist/lib/dev-workspace/clean.js.map +1 -0
  45. package/dist/lib/dev-workspace/detect.d.ts +56 -0
  46. package/dist/lib/dev-workspace/detect.d.ts.map +1 -0
  47. package/dist/lib/dev-workspace/detect.js +343 -0
  48. package/dist/lib/dev-workspace/detect.js.map +1 -0
  49. package/dist/lib/dev-workspace/dir-flag.d.ts +23 -0
  50. package/dist/lib/dev-workspace/dir-flag.d.ts.map +1 -0
  51. package/dist/lib/dev-workspace/dir-flag.js +24 -0
  52. package/dist/lib/dev-workspace/dir-flag.js.map +1 -0
  53. package/dist/lib/dev-workspace/doctor.d.ts +96 -0
  54. package/dist/lib/dev-workspace/doctor.d.ts.map +1 -0
  55. package/dist/lib/dev-workspace/doctor.js +400 -0
  56. package/dist/lib/dev-workspace/doctor.js.map +1 -0
  57. package/dist/lib/dev-workspace/lockfile.d.ts +62 -0
  58. package/dist/lib/dev-workspace/lockfile.d.ts.map +1 -0
  59. package/dist/lib/dev-workspace/lockfile.js +456 -0
  60. package/dist/lib/dev-workspace/lockfile.js.map +1 -0
  61. package/dist/lib/dev-workspace/member-installs.d.ts +35 -0
  62. package/dist/lib/dev-workspace/member-installs.d.ts.map +1 -0
  63. package/dist/lib/dev-workspace/member-installs.js +139 -0
  64. package/dist/lib/dev-workspace/member-installs.js.map +1 -0
  65. package/dist/lib/dev-workspace/pnpm.d.ts +29 -0
  66. package/dist/lib/dev-workspace/pnpm.d.ts.map +1 -0
  67. package/dist/lib/dev-workspace/pnpm.js +59 -0
  68. package/dist/lib/dev-workspace/pnpm.js.map +1 -0
  69. package/dist/lib/dev-workspace/status.d.ts +16 -0
  70. package/dist/lib/dev-workspace/status.d.ts.map +1 -0
  71. package/dist/lib/dev-workspace/status.js +185 -0
  72. package/dist/lib/dev-workspace/status.js.map +1 -0
  73. package/dist/lib/dev-workspace/types.d.ts +312 -0
  74. package/dist/lib/dev-workspace/types.d.ts.map +1 -0
  75. package/dist/lib/dev-workspace/types.js +14 -0
  76. package/dist/lib/dev-workspace/types.js.map +1 -0
  77. package/dist/lib/dev-workspace/usage.d.ts +30 -0
  78. package/dist/lib/dev-workspace/usage.d.ts.map +1 -0
  79. package/dist/lib/dev-workspace/usage.js +177 -0
  80. package/dist/lib/dev-workspace/usage.js.map +1 -0
  81. package/dist/lib/dev-workspace/write.d.ts +25 -0
  82. package/dist/lib/dev-workspace/write.d.ts.map +1 -0
  83. package/dist/lib/dev-workspace/write.js +75 -0
  84. package/dist/lib/dev-workspace/write.js.map +1 -0
  85. package/dist/light-commands.d.ts.map +1 -1
  86. package/dist/light-commands.js +7 -0
  87. package/dist/light-commands.js.map +1 -1
  88. package/dist/utils/open-app-context.js +1 -1
  89. package/dist/utils/open-app-context.js.map +1 -1
  90. package/oclif.manifest.json +3432 -3173
  91. package/package.json +22 -22
@@ -0,0 +1,62 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import path from 'node:path';
3
+ import { ResolveDirSource, WORKSPACE_DIR_ENV_VAR } from '../../../lib/dev-workspace/dir-flag.js';
4
+ import { CollectDoctorReport, DoctorHasFailures, RenderDoctor } from '../../../lib/dev-workspace/doctor.js';
5
+ import { GetPnpmVersion } from '../../../lib/dev-workspace/pnpm.js';
6
+ /**
7
+ * CLI command: `mj dev workspace doctor`.
8
+ *
9
+ * Read-only health check for a generated cross-repo workspace: prints one
10
+ * PASS/WARN/FAIL/SKIP line per check and exits non-zero when any check FAILS, so
11
+ * it can gate a script. It writes nothing, deletes nothing and makes no network
12
+ * call — every fix it finds is printed as a command for the user to run.
13
+ *
14
+ * The check `status` cannot do is the one-copy census: it reads the parent's pnpm
15
+ * virtual store and fails when more than one version of a must-be-single-copy
16
+ * package (Angular, RxJS, zone.js, MJ core/global) is installed there.
17
+ */
18
+ export default class DevWorkspaceDoctor extends Command {
19
+ static { this.description = 'Health-check the generated cross-repo pnpm workspace at a parent directory: workspace files, sentinel, ' +
20
+ 'pnpm pin vs. active version, member directories, detected-but-unlisted repos, members carrying a standalone ' +
21
+ 'install, and a one-copy census of the parent package store (more than one @angular/core, rxjs, zone.js or ' +
22
+ 'MJ core/global is a FAIL). Prints PASS/WARN/FAIL per check and exits non-zero on any FAIL. Read-only.'; }
23
+ static { this.examples = [
24
+ '<%= config.bin %> dev workspace doctor',
25
+ '<%= config.bin %> dev workspace doctor --dir ~/code/bluecypress',
26
+ `MJ_DEV_WORKSPACE_DIR=~/code/bluecypress <%= config.bin %> dev workspace doctor`,
27
+ ]; }
28
+ static { this.flags = {
29
+ dir: Flags.string({
30
+ description: `Parent directory holding the sibling repo clones (env: ${WORKSPACE_DIR_ENV_VAR})`,
31
+ env: WORKSPACE_DIR_ENV_VAR,
32
+ default: '.',
33
+ }),
34
+ }; }
35
+ async run() {
36
+ const { flags } = await this.parse(DevWorkspaceDoctor);
37
+ const parentDir = path.resolve(flags.dir);
38
+ const dirSource = ResolveDirSource(this.argv, process.env[WORKSPACE_DIR_ENV_VAR]);
39
+ const report = await this.collectReport(parentDir, dirSource);
40
+ this.log('');
41
+ this.log(RenderDoctor(report));
42
+ if (DoctorHasFailures(report)) {
43
+ this.exit(1);
44
+ }
45
+ }
46
+ /**
47
+ * Probes the active pnpm version (the one spawn in this command) and collects the
48
+ * report. Collection errors — an unreadable store, a parent that does not exist —
49
+ * become a clean CLI error rather than a stack trace; `this.error` never returns.
50
+ */
51
+ async collectReport(parentDir, dirSource) {
52
+ try {
53
+ const activePnpm = await GetPnpmVersion(parentDir);
54
+ return CollectDoctorReport(parentDir, activePnpm, dirSource);
55
+ }
56
+ catch (error) {
57
+ const message = error instanceof Error ? error.message : String(error);
58
+ return this.error(message);
59
+ }
60
+ }
61
+ }
62
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../../src/commands/dev/workspace/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,YAAY,EAAqB,MAAM,sCAAsC,CAAC;AAC/H,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGpE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;aAC9C,gBAAW,GAChB,yGAAyG;QACzG,8GAA8G;QAC9G,4GAA4G;QAC5G,uGAAuG,CAAC;aAEnG,aAAQ,GAAG;QAChB,wCAAwC;QACxC,iEAAiE;QACjE,gFAAgF;KACjF,CAAC;aAEK,UAAK,GAAG;QACb,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,0DAA0D,qBAAqB,GAAG;YAC/F,GAAG,EAAE,qBAAqB;YAC1B,OAAO,EAAE,GAAG;SACb,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAElF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9D,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/B,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,aAAa,CAAC,SAAiB,EAAE,SAAoB;QACjE,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;YACnD,OAAO,mBAAmB,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj dev workspace`.
4
+ *
5
+ * Generates the four ephemeral files that join sibling repo checkouts into a
6
+ * single pnpm workspace at their common parent directory (pnpm-workspace.yaml,
7
+ * .npmrc, package.json, turbo.json), then runs `pnpm install` there.
8
+ *
9
+ * Automates what was previously a hand-run setup: writing those files yourself and
10
+ * keeping them in step as repos come and go.
11
+ * Linking only — app REGISTRATION into a running host is deliberately phase 2.
12
+ */
13
+ export default class DevWorkspace extends Command {
14
+ static description: string;
15
+ static examples: string[];
16
+ static flags: {
17
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
18
+ include: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
19
+ exclude: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
20
+ install: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
21
+ force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
22
+ 'clean-members': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
23
+ verbose: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
24
+ };
25
+ run(): Promise<void>;
26
+ /** Resolves the member set: detected candidates plus --include, minus --exclude. */
27
+ private selectMembers;
28
+ /**
29
+ * Builds every file's content (pure builders) and logs each resolution decision.
30
+ * The sentinel comes last and records the names of the files alongside it, so its
31
+ * inventory is true by construction rather than by a constant kept in step.
32
+ */
33
+ private buildFiles;
34
+ /**
35
+ * Logs where a member's workspace globs came from — and warns LOUDLY when the
36
+ * member has its own pnpm-workspace.yaml that yielded nothing usable, because a
37
+ * silent packages/* fallback is exactly the #3795 failure: an install that
38
+ * succeeds while the member's real packages resolve from the registry.
39
+ */
40
+ private reportMemberGlobs;
41
+ /**
42
+ * Detects members carrying standalone installs (root or nested node_modules —
43
+ * depth-independent, per the field's 290-trees lesson on #3795) and removes
44
+ * them before the parent install, honoring --clean-members/--no-clean-members
45
+ * or asking interactively. A skip always states the exact consequence.
46
+ */
47
+ private handleStandaloneInstalls;
48
+ /** Decides one member's cleanup: an explicit flag wins; otherwise ask when interactive, skip loudly when not. */
49
+ private shouldCleanMember;
50
+ /**
51
+ * Reports every absorption decision the manifest build made: pins, hoists,
52
+ * patches, family overrides, drops and skips — loud conflicts, dim counts,
53
+ * itemized detail behind --verbose. A derivation that dropped something and
54
+ * said nothing is the #3795 disease; this method is why it cannot recur.
55
+ */
56
+ private reportManifestAssembly;
57
+ /** The dropped/skipped half of the assembly report: @types, workspace: drops, superseded pins, lockfile skips. */
58
+ private reportManifestDrops;
59
+ }
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/dev/workspace/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAwB7C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,OAAO;IAC/C,MAAM,CAAC,WAAW,SAKgF;IAElG,MAAM,CAAC,QAAQ,WAMb;IAEF,MAAM,CAAC,KAAK;;;;;;;;MA8BV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC1B,oFAAoF;IACpF,OAAO,CAAC,aAAa;IA4BrB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAuBlB;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;;;;OAKG;YACW,wBAAwB;IA6BtC,iHAAiH;YACnG,iBAAiB;IAkB/B;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAyB9B,kHAAkH;IAClH,OAAO,CAAC,mBAAmB;CAmB5B"}
@@ -0,0 +1,279 @@
1
+ import { confirm } from '@inquirer/prompts';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import chalk from 'chalk';
4
+ import path from 'node:path';
5
+ import { BuildNpmrc, BuildRootPackageJson, BuildSentinel, BuildShellPeerGuidance, BuildWorkspaceYaml, PickTurboJson, } from '../../../lib/dev-workspace/build.js';
6
+ import { DetectCandidates, LoadRepo } from '../../../lib/dev-workspace/detect.js';
7
+ import { WORKSPACE_DIR_ENV_VAR } from '../../../lib/dev-workspace/dir-flag.js';
8
+ import { FindMemberInstallTrees, IsInsideDirectory, RemoveMemberInstallTrees } from '../../../lib/dev-workspace/member-installs.js';
9
+ import { RunPnpmInstall } from '../../../lib/dev-workspace/pnpm.js';
10
+ import { AssertParentDirSafe, SENTINEL_FILE_NAME, WriteWorkspaceFiles } from '../../../lib/dev-workspace/write.js';
11
+ /** Renders one conflict's decision for a warn line. */
12
+ function describeConflict(conflict) {
13
+ const losers = conflict.Losers.map((l) => `${l.Version} (${l.Repo})`).join(', ');
14
+ return `kept ${conflict.Winner.Version} (${conflict.Winner.Repo}), dropped ${losers}`;
15
+ }
16
+ /**
17
+ * CLI command: `mj dev workspace`.
18
+ *
19
+ * Generates the four ephemeral files that join sibling repo checkouts into a
20
+ * single pnpm workspace at their common parent directory (pnpm-workspace.yaml,
21
+ * .npmrc, package.json, turbo.json), then runs `pnpm install` there.
22
+ *
23
+ * Automates what was previously a hand-run setup: writing those files yourself and
24
+ * keeping them in step as repos come and go.
25
+ * Linking only — app REGISTRATION into a running host is deliberately phase 2.
26
+ */
27
+ export default class DevWorkspace extends Command {
28
+ static { this.description = 'Join sibling repo clones into one pnpm workspace: writes pnpm-workspace.yaml, .npmrc, package.json, ' +
29
+ 'turbo.json and the .mj-dev-workspace.json sentinel at their common parent, then runs pnpm install there. ' +
30
+ 'Members are the parent\'s immediate subdirectories carrying an mj-app.json, a @mj-biz-apps package, or the ' +
31
+ 'MJ monorepo root name. Existing files are never overwritten without --force (which keeps a .bak of each). ' +
32
+ 'Generated files are ephemeral — never commit them; tear them down with `dev workspace clean`.'; }
33
+ static { this.examples = [
34
+ '<%= config.bin %> dev workspace --dir ~/code/bluecypress',
35
+ '<%= config.bin %> dev workspace --dir ~/code/bluecypress --exclude bizapps-sonar',
36
+ '<%= config.bin %> dev workspace --dir ~/code/bluecypress --include bizapps-common --include bizapps-tasks',
37
+ '<%= config.bin %> dev workspace --dir ~/code/bluecypress --no-install --force',
38
+ 'MJ_DEV_WORKSPACE_DIR=~/code/bluecypress <%= config.bin %> dev workspace',
39
+ ]; }
40
+ static { this.flags = {
41
+ dir: Flags.string({
42
+ description: `Parent directory holding the sibling repo clones (must NOT itself be a git repo; env: ${WORKSPACE_DIR_ENV_VAR})`,
43
+ env: WORKSPACE_DIR_ENV_VAR,
44
+ default: '.',
45
+ }),
46
+ include: Flags.string({
47
+ multiple: true,
48
+ description: 'Repo directory name to include as a member (repeatable; adds to the detected set)',
49
+ }),
50
+ exclude: Flags.string({
51
+ multiple: true,
52
+ description: 'Repo directory name to exclude from the members (repeatable)',
53
+ }),
54
+ install: Flags.boolean({
55
+ description: 'Run `pnpm install` at the parent after generating (disable with --no-install)',
56
+ default: true,
57
+ allowNo: true,
58
+ }),
59
+ force: Flags.boolean({
60
+ description: 'Overwrite existing workspace files at the parent (a .bak copy of each is kept)',
61
+ default: false,
62
+ }),
63
+ 'clean-members': Flags.boolean({
64
+ description: 'Remove members\' standalone node_modules trees (root AND nested, depth-independent) before the parent ' +
65
+ 'install; --no-clean-members keeps them. Without either flag, an interactive run asks per member.',
66
+ allowNo: true,
67
+ }),
68
+ verbose: Flags.boolean({ char: 'v', description: 'Show detailed output' }),
69
+ }; }
70
+ async run() {
71
+ const { flags } = await this.parse(DevWorkspace);
72
+ const parentDir = path.resolve(flags.dir);
73
+ try {
74
+ AssertParentDirSafe(parentDir);
75
+ const members = this.selectMembers(parentDir, flags.include ?? [], flags.exclude ?? []);
76
+ await this.handleStandaloneInstalls(parentDir, members, flags['clean-members']);
77
+ const files = this.buildFiles(parentDir, members, flags.verbose);
78
+ const result = WriteWorkspaceFiles(parentDir, files, flags.force);
79
+ for (const backup of result.BackedUp) {
80
+ this.log(chalk.yellow(`Backed up existing file to ${backup}`));
81
+ }
82
+ this.log(chalk.green(`Wrote ${result.Written.join(', ')} at ${parentDir}`));
83
+ for (const line of BuildShellPeerGuidance()) {
84
+ this.log(chalk.dim(line));
85
+ }
86
+ if (flags.install) {
87
+ this.log(chalk.bold('\nRunning pnpm install...'));
88
+ await RunPnpmInstall(parentDir);
89
+ this.log(chalk.green('pnpm install completed'));
90
+ }
91
+ else {
92
+ this.log(chalk.dim('Skipped pnpm install (--no-install); run `pnpm install` at the parent when ready.'));
93
+ }
94
+ this.log(chalk.dim(`\nBuild any package from the parent: pnpm --filter <package-name> run build`));
95
+ this.log(chalk.dim(`(members whose package.json pins npm refuse in-place pnpm runs — drive those from the parent with --filter until they migrate)`));
96
+ this.log(chalk.dim(`Check the result any time with: ${this.config.bin} dev workspace status --dir ${parentDir}`));
97
+ this.log(chalk.dim(`Tear it back down with: ${this.config.bin} dev workspace clean --dir ${parentDir}`));
98
+ }
99
+ catch (error) {
100
+ const message = error instanceof Error ? error.message : String(error);
101
+ this.error(message);
102
+ }
103
+ }
104
+ /** Resolves the member set: detected candidates plus --include, minus --exclude. */
105
+ selectMembers(parentDir, include, exclude) {
106
+ const members = new Map();
107
+ for (const candidate of DetectCandidates(parentDir)) {
108
+ members.set(candidate.Name, candidate);
109
+ }
110
+ for (const name of include) {
111
+ if (members.has(name))
112
+ continue;
113
+ const repo = LoadRepo(parentDir, name);
114
+ if (repo === null) {
115
+ throw new Error(`--include ${name}: ${path.join(parentDir, name)} has no package.json — not a repo checkout`);
116
+ }
117
+ this.warn(`${name} was not detected as a candidate — including it anyway (--include)`);
118
+ members.set(name, repo);
119
+ }
120
+ for (const name of exclude) {
121
+ if (!members.delete(name))
122
+ this.warn(`--exclude ${name}: not in the member set, ignoring`);
123
+ }
124
+ if (members.size === 0) {
125
+ throw new Error(`No member repos at ${parentDir}. Candidates are sibling dirs with an mj-app.json, @mj-biz-apps packages, or the MJ monorepo; use --include to add others.`);
126
+ }
127
+ const selected = [...members.values()].sort((a, b) => a.Name.localeCompare(b.Name));
128
+ for (const member of selected) {
129
+ const why = member.Reasons.length > 0 ? member.Reasons.join(', ') : 'included via --include';
130
+ this.log(`${chalk.green('member')} ${member.Name} ${chalk.dim(`(${why})`)}`);
131
+ }
132
+ return selected;
133
+ }
134
+ /**
135
+ * Builds every file's content (pure builders) and logs each resolution decision.
136
+ * The sentinel comes last and records the names of the files alongside it, so its
137
+ * inventory is true by construction rather than by a constant kept in step.
138
+ */
139
+ buildFiles(parentDir, members, verbose) {
140
+ const memberNames = members.map((m) => m.Name);
141
+ const rootPkg = BuildRootPackageJson(path.basename(parentDir), members);
142
+ for (const conflict of rootPkg.Conflicts) {
143
+ this.warn(`devDependency conflict on ${conflict.Package}: ${describeConflict(conflict)}`);
144
+ }
145
+ this.log(chalk.dim(`packageManager pin ${rootPkg.Pin} from ${rootPkg.PinSource}`));
146
+ const turbo = PickTurboJson(members);
147
+ this.log(chalk.dim(`turbo.json copied from ${turbo.Source}`));
148
+ for (const member of members) {
149
+ this.reportMemberGlobs(member);
150
+ }
151
+ this.reportManifestAssembly(rootPkg.Report, verbose);
152
+ const workspaceFiles = [
153
+ { Name: 'pnpm-workspace.yaml', Content: BuildWorkspaceYaml(members) },
154
+ { Name: '.npmrc', Content: BuildNpmrc() },
155
+ { Name: 'package.json', Content: rootPkg.Content },
156
+ { Name: 'turbo.json', Content: turbo.Content },
157
+ ];
158
+ const written = [...workspaceFiles.map((f) => f.Name), SENTINEL_FILE_NAME];
159
+ return [...workspaceFiles, { Name: SENTINEL_FILE_NAME, Content: BuildSentinel(written, memberNames) }];
160
+ }
161
+ /**
162
+ * Logs where a member's workspace globs came from — and warns LOUDLY when the
163
+ * member has its own pnpm-workspace.yaml that yielded nothing usable, because a
164
+ * silent packages/* fallback is exactly the #3795 failure: an install that
165
+ * succeeds while the member's real packages resolve from the registry.
166
+ */
167
+ reportMemberGlobs(member) {
168
+ for (const glob of member.UnsupportedGlobs) {
169
+ this.warn(`${member.Name} glob '${glob}' has an unsupported shape (only fixed paths, trailing /* and trailing /** ` +
170
+ `are expanded) — its packages are NOT enumerated for workspace:* overrides`);
171
+ }
172
+ if (member.WorkspaceGlobsSource === 'workspace-yaml-without-packages-globs') {
173
+ this.warn(`${member.Name} has its own pnpm-workspace.yaml but it yielded NO globs rooted under packages/ — ` +
174
+ `assuming ${member.Name}/packages/*. If that repo keeps packages anywhere else, they will NOT be ` +
175
+ `linked into this workspace (they would resolve from the registry instead). Check ${member.Name}/pnpm-workspace.yaml.`);
176
+ return;
177
+ }
178
+ if (member.WorkspaceGlobsSource === 'member-workspace-yaml') {
179
+ this.log(chalk.dim(`${member.Name} contributes ${member.WorkspaceGlobs.length} workspace globs from its own pnpm-workspace.yaml`));
180
+ }
181
+ }
182
+ /**
183
+ * Detects members carrying standalone installs (root or nested node_modules —
184
+ * depth-independent, per the field's 290-trees lesson on #3795) and removes
185
+ * them before the parent install, honoring --clean-members/--no-clean-members
186
+ * or asking interactively. A skip always states the exact consequence.
187
+ */
188
+ async handleStandaloneInstalls(parentDir, members, cleanFlag) {
189
+ for (const member of members) {
190
+ if (!IsInsideDirectory(parentDir, member.Path)) {
191
+ // possible via --include with a path-like name; never enumerate such a member for deletion
192
+ this.warn(`${member.Name} lives outside the parent directory (${member.Path}) — excluded from standalone-install cleanup entirely.`);
193
+ continue;
194
+ }
195
+ const scan = FindMemberInstallTrees(member.Path);
196
+ for (const dir of scan.UnreadableDirs) {
197
+ this.warn(`${member.Name}: could not read ${dir} while scanning for standalone installs — skipped, anything under it was not scanned`);
198
+ }
199
+ if (scan.Trees.length === 0)
200
+ continue;
201
+ const clean = await this.shouldCleanMember(member.Name, scan.Trees.length, cleanFlag);
202
+ if (!clean) {
203
+ this.warn(`${member.Name}: keeping its standalone install (${scan.Trees.length} node_modules tree(s)). After the parent ` +
204
+ `install those trees hold symlinks into a store the parent does not manage — expect dangling links and ` +
205
+ `TS2307 'Cannot find module' errors that look like missing dependencies. Re-run with --clean-members to remove them.`);
206
+ continue;
207
+ }
208
+ const result = RemoveMemberInstallTrees(scan.Trees);
209
+ for (const skip of result.Skipped) {
210
+ this.warn(`${member.Name}: NOT removed — ${skip.Path}: ${skip.Reason}`);
211
+ }
212
+ this.log(chalk.green(`${member.Name}: removed ${result.Removed.length} standalone node_modules tree(s)`));
213
+ }
214
+ }
215
+ /** Decides one member's cleanup: an explicit flag wins; otherwise ask when interactive, skip loudly when not. */
216
+ async shouldCleanMember(name, treeCount, cleanFlag) {
217
+ if (cleanFlag !== undefined)
218
+ return cleanFlag;
219
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
220
+ this.warn(`${name} has a standalone install (${treeCount} node_modules tree(s)) and this run is non-interactive ` +
221
+ `with no --clean-members/--no-clean-members given — leaving it in place.`);
222
+ return false;
223
+ }
224
+ this.log(`${name} has a standalone install (${treeCount} node_modules tree${treeCount === 1 ? '' : 's'}).`);
225
+ this.log(` keep it → its old trees resolve against a store the parent install does not manage: two copies of shared packages, dangling symlinks, phantom 'Cannot find module' errors`);
226
+ this.log(` remove it → ${name} builds only through this workspace until you run a plain install inside it again (one command to switch back)`);
227
+ return confirm({
228
+ message: `Remove ${name}'s standalone install before the parent install?`,
229
+ default: true,
230
+ });
231
+ }
232
+ /**
233
+ * Reports every absorption decision the manifest build made: pins, hoists,
234
+ * patches, family overrides, drops and skips — loud conflicts, dim counts,
235
+ * itemized detail behind --verbose. A derivation that dropped something and
236
+ * said nothing is the #3795 disease; this method is why it cannot recur.
237
+ */
238
+ reportManifestAssembly(report, verbose) {
239
+ this.log(chalk.dim(`pnpm.overrides: ${report.LockfilePinCount} lockfile-derived pin(s), ${report.HoistedOverrideCount} hoisted ` +
240
+ `member override(s), ${report.FamilyOverrideCount} workspace:* family override(s); ${report.Patches.length} patch(es) hoisted`));
241
+ for (const patch of report.Patches) {
242
+ this.log(chalk.dim(` patch ${patch.Package} -> ${patch.Path} (from ${patch.Repo})`));
243
+ }
244
+ for (const conflict of [...report.PinConflicts, ...report.BlockConflicts]) {
245
+ this.warn(`override conflict on ${conflict.Package}: ${describeConflict(conflict)}`);
246
+ }
247
+ for (const unsupported of report.UnsupportedLockfiles) {
248
+ this.warn(`${unsupported.Repo} commits ${unsupported.File} with lockfileVersion ${unsupported.Version} — a format this ` +
249
+ `derivation cannot read, so that member contributes NO pins; its ranges resolve freshly at the parent`);
250
+ }
251
+ for (const dup of report.DuplicateFamilyPackages) {
252
+ this.warn(`package ${dup.Package} is provided by ${dup.Repos.join(' AND ')} — the link target is decided by sort order; use --exclude to drop one`);
253
+ }
254
+ this.reportManifestDrops(report, verbose);
255
+ }
256
+ /** The dropped/skipped half of the assembly report: @types, workspace: drops, superseded pins, lockfile skips. */
257
+ reportManifestDrops(report, verbose) {
258
+ if (report.SkippedTypesDevDeps.length > 0) {
259
+ const detail = verbose ? `: ${report.SkippedTypesDevDeps.join(', ')}` : '';
260
+ this.log(chalk.dim(`devDependency union: skipped ${report.SkippedTypesDevDeps.length} @types/* package(s) — duplicate @types are a nominal-type break${detail}`));
261
+ }
262
+ for (const dropped of report.DroppedWorkspaceDevDeps) {
263
+ this.warn(`devDependency ${dropped.Package} (${dropped.Repo}) uses workspace: but NO member provides it — dropped from the parent manifest`);
264
+ }
265
+ if (report.SupersededPins.length > 0) {
266
+ const detail = verbose ? `: ${report.SupersededPins.join(', ')}` : '';
267
+ this.log(chalk.dim(`${report.SupersededPins.length} lockfile-derived pin(s) superseded by member overrides or workspace:* family overrides${detail}`));
268
+ }
269
+ if (report.LockfileSkips.length === 0)
270
+ return;
271
+ this.log(chalk.dim(`lockfile pin derivation skipped ${report.LockfileSkips.length} entr(y/ies) (workspace links / non-semver)${verbose ? ':' : ' — --verbose lists them'}`));
272
+ if (!verbose)
273
+ return;
274
+ for (const { Repo, Skip } of report.LockfileSkips) {
275
+ this.log(chalk.dim(` ${Repo}: ${Skip.Name}@${Skip.Version} — ${Skip.Reason}`));
276
+ }
277
+ }
278
+ }
279
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/dev/workspace/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Command } from '@oclif/core';
2
+ /**
3
+ * CLI command: `mj dev workspace status`.
4
+ *
5
+ * Reports the state of a generated cross-repo workspace at the parent
6
+ * directory: which of the four generated files exist, whether a lockfile and
7
+ * node_modules exist, whether the sentinel manifest is present, the member list
8
+ * versus the candidates detected on disk, how `--dir` was resolved, and whether
9
+ * the active pnpm version matches the generated pin. Read-only — writes nothing.
10
+ */
11
+ export default class DevWorkspaceStatus extends Command {
12
+ static description: string;
13
+ static examples: string[];
14
+ static flags: {
15
+ dir: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../src/commands/dev/workspace/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAM7C;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;IACrD,MAAM,CAAC,WAAW,SAE2F;IAE7G,MAAM,CAAC,QAAQ,WAIb;IAEF,MAAM,CAAC,KAAK;;MAMV;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAe3B"}
@@ -0,0 +1,46 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import path from 'node:path';
3
+ import { ResolveDirSource, WORKSPACE_DIR_ENV_VAR } from '../../../lib/dev-workspace/dir-flag.js';
4
+ import { GetPnpmVersion } from '../../../lib/dev-workspace/pnpm.js';
5
+ import { CollectWorkspaceStatus, RenderStatus } from '../../../lib/dev-workspace/status.js';
6
+ /**
7
+ * CLI command: `mj dev workspace status`.
8
+ *
9
+ * Reports the state of a generated cross-repo workspace at the parent
10
+ * directory: which of the four generated files exist, whether a lockfile and
11
+ * node_modules exist, whether the sentinel manifest is present, the member list
12
+ * versus the candidates detected on disk, how `--dir` was resolved, and whether
13
+ * the active pnpm version matches the generated pin. Read-only — writes nothing.
14
+ */
15
+ export default class DevWorkspaceStatus extends Command {
16
+ static { this.description = 'Report the state of the generated cross-repo pnpm workspace at a parent directory: generated files, ' +
17
+ 'lockfile, node_modules, sentinel presence, members vs. detected candidates, and the pnpm pin. Read-only.'; }
18
+ static { this.examples = [
19
+ '<%= config.bin %> dev workspace status',
20
+ '<%= config.bin %> dev workspace status --dir ~/code/bluecypress',
21
+ `MJ_DEV_WORKSPACE_DIR=~/code/bluecypress <%= config.bin %> dev workspace status`,
22
+ ]; }
23
+ static { this.flags = {
24
+ dir: Flags.string({
25
+ description: `Parent directory holding the sibling repo clones (env: ${WORKSPACE_DIR_ENV_VAR})`,
26
+ env: WORKSPACE_DIR_ENV_VAR,
27
+ default: '.',
28
+ }),
29
+ }; }
30
+ async run() {
31
+ const { flags } = await this.parse(DevWorkspaceStatus);
32
+ const parentDir = path.resolve(flags.dir);
33
+ const dirSource = ResolveDirSource(this.argv, process.env[WORKSPACE_DIR_ENV_VAR]);
34
+ try {
35
+ const activePnpm = await GetPnpmVersion(parentDir);
36
+ const status = CollectWorkspaceStatus(parentDir, activePnpm, dirSource);
37
+ this.log('');
38
+ this.log(RenderStatus(status));
39
+ }
40
+ catch (error) {
41
+ const message = error instanceof Error ? error.message : String(error);
42
+ this.error(message);
43
+ }
44
+ }
45
+ }
46
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/commands/dev/workspace/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAE5F;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,OAAO;aAC9C,gBAAW,GAChB,sGAAsG;QACtG,0GAA0G,CAAC;aAEtG,aAAQ,GAAG;QAChB,wCAAwC;QACxC,iEAAiE;QACjE,gFAAgF;KACjF,CAAC;aAEK,UAAK,GAAG;QACb,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC;YAChB,WAAW,EAAE,0DAA0D,qBAAqB,GAAG;YAC/F,GAAG,EAAE,qBAAqB;YAC1B,OAAO,EAAE,GAAG;SACb,CAAC;KACH,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAElF,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YACxE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-plugins.d.ts","sourceRoot":"","sources":["../../src/lib/cli-plugins.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CASzF"}
1
+ {"version":3,"file":"cli-plugins.d.ts","sourceRoot":"","sources":["../../src/lib/cli-plugins.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAazF"}
@@ -1,4 +1,5 @@
1
1
  import { CLIPluginRegistry } from '@memberjunction/cli-core';
2
+ import { RegisterDevWorkspaceUsage } from './dev-workspace/usage.js';
2
3
  /**
3
4
  * Loads all CLI plugins so their `@RegisterClass(BaseCLIPlugin, …)` decorators
4
5
  * populate the ClassFactory — the basis for the `mj usage` / `mj <domain> usage`
@@ -16,6 +17,10 @@ import { CLIPluginRegistry } from '@memberjunction/cli-core';
16
17
  export async function loadAllCliPlugins(searchFrom = process.cwd()) {
17
18
  await import('@memberjunction/metadata-sync/plugins');
18
19
  await import('@memberjunction/codegen-lib/plugins');
20
+ // The `dev` domain ships inside this CLI as plain oclif commands (they must stay
21
+ // bootstrap-free), so it declares its usage through CLIPluginRegistry.RegisterUsage
22
+ // on import rather than through a plugin's `static Usage`.
23
+ RegisterDevWorkspaceUsage();
19
24
  const { failed } = await CLIPluginRegistry.LoadPluginsFromConfig(searchFrom);
20
25
  // Surface (don't swallow) any third-party plugin that failed to load. stderr
21
26
  // keeps stdout clean for `--format=json` consumers.
@@ -1 +1 @@
1
- {"version":3,"file":"cli-plugins.js","sourceRoot":"","sources":["../../src/lib/cli-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAAqB,OAAO,CAAC,GAAG,EAAE;IACxE,MAAM,MAAM,CAAC,uCAAuC,CAAC,CAAC;IACtD,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC;IACpD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC7E,6EAA6E;IAC7E,oDAAoD;IACpD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"cli-plugins.js","sourceRoot":"","sources":["../../src/lib/cli-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAErE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAAqB,OAAO,CAAC,GAAG,EAAE;IACxE,MAAM,MAAM,CAAC,uCAAuC,CAAC,CAAC;IACtD,MAAM,MAAM,CAAC,qCAAqC,CAAC,CAAC;IACpD,iFAAiF;IACjF,oFAAoF;IACpF,2DAA2D;IAC3D,yBAAyB,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,iBAAiB,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC7E,6EAA6E;IAC7E,oDAAoD;IACpD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}