@memberjunction/cli 5.41.0 → 5.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/commands/bundle/index.d.ts +1 -0
  2. package/dist/commands/bundle/index.d.ts.map +1 -1
  3. package/dist/commands/bundle/index.js +7 -1
  4. package/dist/commands/bundle/index.js.map +1 -1
  5. package/dist/commands/codegen/index.d.ts +6 -16
  6. package/dist/commands/codegen/index.d.ts.map +1 -1
  7. package/dist/commands/codegen/index.js +6 -90
  8. package/dist/commands/codegen/index.js.map +1 -1
  9. package/dist/commands/codegen/usage.d.ts +7 -0
  10. package/dist/commands/codegen/usage.d.ts.map +1 -0
  11. package/dist/commands/codegen/usage.js +10 -0
  12. package/dist/commands/codegen/usage.js.map +1 -0
  13. package/dist/commands/install/claude.d.ts +35 -0
  14. package/dist/commands/install/claude.d.ts.map +1 -0
  15. package/dist/commands/install/claude.js +108 -0
  16. package/dist/commands/install/claude.js.map +1 -0
  17. package/dist/commands/install/index.d.ts +1 -0
  18. package/dist/commands/install/index.d.ts.map +1 -1
  19. package/dist/commands/install/index.js +4 -0
  20. package/dist/commands/install/index.js.map +1 -1
  21. package/dist/commands/migrate/convert.d.ts +59 -12
  22. package/dist/commands/migrate/convert.d.ts.map +1 -1
  23. package/dist/commands/migrate/convert.js +294 -21
  24. package/dist/commands/migrate/convert.js.map +1 -1
  25. package/dist/commands/migrate/rebake.d.ts +41 -0
  26. package/dist/commands/migrate/rebake.d.ts.map +1 -0
  27. package/dist/commands/migrate/rebake.js +193 -0
  28. package/dist/commands/migrate/rebake.js.map +1 -0
  29. package/dist/commands/plugin/add.d.ts +18 -0
  30. package/dist/commands/plugin/add.d.ts.map +1 -0
  31. package/dist/commands/plugin/add.js +53 -0
  32. package/dist/commands/plugin/add.js.map +1 -0
  33. package/dist/commands/sync/pull.d.ts +6 -26
  34. package/dist/commands/sync/pull.d.ts.map +1 -1
  35. package/dist/commands/sync/pull.js +6 -281
  36. package/dist/commands/sync/pull.js.map +1 -1
  37. package/dist/commands/sync/push.d.ts +8 -19
  38. package/dist/commands/sync/push.d.ts.map +1 -1
  39. package/dist/commands/sync/push.js +8 -328
  40. package/dist/commands/sync/push.js.map +1 -1
  41. package/dist/commands/sync/usage.d.ts +7 -0
  42. package/dist/commands/sync/usage.d.ts.map +1 -0
  43. package/dist/commands/sync/usage.js +10 -0
  44. package/dist/commands/sync/usage.js.map +1 -0
  45. package/dist/commands/update/claude.d.ts +37 -0
  46. package/dist/commands/update/claude.d.ts.map +1 -0
  47. package/dist/commands/update/claude.js +90 -0
  48. package/dist/commands/update/claude.js.map +1 -0
  49. package/dist/commands/usage.d.ts +17 -0
  50. package/dist/commands/usage.d.ts.map +1 -0
  51. package/dist/commands/usage.js +29 -0
  52. package/dist/commands/usage.js.map +1 -0
  53. package/dist/hooks/prerun.d.ts.map +1 -1
  54. package/dist/hooks/prerun.js +49 -8
  55. package/dist/hooks/prerun.js.map +1 -1
  56. package/dist/lib/claude-pack/ManagedBlockEditor.d.ts +40 -0
  57. package/dist/lib/claude-pack/ManagedBlockEditor.d.ts.map +1 -0
  58. package/dist/lib/claude-pack/ManagedBlockEditor.js +127 -0
  59. package/dist/lib/claude-pack/ManagedBlockEditor.js.map +1 -0
  60. package/dist/lib/claude-pack/PackFetcher.d.ts +86 -0
  61. package/dist/lib/claude-pack/PackFetcher.d.ts.map +1 -0
  62. package/dist/lib/claude-pack/PackFetcher.js +163 -0
  63. package/dist/lib/claude-pack/PackFetcher.js.map +1 -0
  64. package/dist/lib/claude-pack/PackInstaller.d.ts +62 -0
  65. package/dist/lib/claude-pack/PackInstaller.d.ts.map +1 -0
  66. package/dist/lib/claude-pack/PackInstaller.js +197 -0
  67. package/dist/lib/claude-pack/PackInstaller.js.map +1 -0
  68. package/dist/lib/claude-pack/PackMerger.d.ts +61 -0
  69. package/dist/lib/claude-pack/PackMerger.d.ts.map +1 -0
  70. package/dist/lib/claude-pack/PackMerger.js +315 -0
  71. package/dist/lib/claude-pack/PackMerger.js.map +1 -0
  72. package/dist/lib/claude-pack/PackOutputFormatter.d.ts +29 -0
  73. package/dist/lib/claude-pack/PackOutputFormatter.d.ts.map +1 -0
  74. package/dist/lib/claude-pack/PackOutputFormatter.js +82 -0
  75. package/dist/lib/claude-pack/PackOutputFormatter.js.map +1 -0
  76. package/dist/lib/claude-pack/PackPaths.d.ts +80 -0
  77. package/dist/lib/claude-pack/PackPaths.d.ts.map +1 -0
  78. package/dist/lib/claude-pack/PackPaths.js +182 -0
  79. package/dist/lib/claude-pack/PackPaths.js.map +1 -0
  80. package/dist/lib/claude-pack/PackTypes.d.ts +124 -0
  81. package/dist/lib/claude-pack/PackTypes.d.ts.map +1 -0
  82. package/dist/lib/claude-pack/PackTypes.js +32 -0
  83. package/dist/lib/claude-pack/PackTypes.js.map +1 -0
  84. package/dist/lib/claude-pack/SettingsMerger.d.ts +47 -0
  85. package/dist/lib/claude-pack/SettingsMerger.d.ts.map +1 -0
  86. package/dist/lib/claude-pack/SettingsMerger.js +163 -0
  87. package/dist/lib/claude-pack/SettingsMerger.js.map +1 -0
  88. package/dist/lib/cli-plugins.d.ts +16 -0
  89. package/dist/lib/cli-plugins.d.ts.map +1 -0
  90. package/dist/lib/cli-plugins.js +26 -0
  91. package/dist/lib/cli-plugins.js.map +1 -0
  92. package/dist/lib/domain-usage-command.d.ts +16 -0
  93. package/dist/lib/domain-usage-command.d.ts.map +1 -0
  94. package/dist/lib/domain-usage-command.js +23 -0
  95. package/dist/lib/domain-usage-command.js.map +1 -0
  96. package/dist/lib/usage-render.d.ts +14 -0
  97. package/dist/lib/usage-render.d.ts.map +1 -0
  98. package/dist/lib/usage-render.js +64 -0
  99. package/dist/lib/usage-render.js.map +1 -0
  100. package/dist/light-commands.d.ts.map +1 -1
  101. package/dist/light-commands.js +11 -0
  102. package/dist/light-commands.js.map +1 -1
  103. package/oclif.manifest.json +815 -135
  104. package/package.json +17 -15
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Output formatters for `mj install:claude` and `mj update:claude`.
3
+ *
4
+ * Two shapes:
5
+ * - `formatPretty(result)` — human-readable colored summary for terminals
6
+ * - `formatJson(result)` — machine-readable schema from plan §7.5
7
+ *
8
+ * Lives in `lib/claude-pack/` (not in the command files) because both commands
9
+ * use the same renderer.
10
+ */
11
+ import chalk from 'chalk';
12
+ /** Plain `--json` output. */
13
+ export function formatJson(result) {
14
+ return JSON.stringify(result, null, 2);
15
+ }
16
+ /**
17
+ * Multi-line colored summary for terminals. Sections:
18
+ *
19
+ * ✓ Claude Code pack v5.1.0 installed (MJ v5.33.0)
20
+ * added: N
21
+ * <list>
22
+ * updated: N
23
+ * <list>
24
+ * skipped: N (truncated to first few)
25
+ * warnings: N
26
+ * <list>
27
+ *
28
+ * Failure mode: a red banner + the errors[] list.
29
+ */
30
+ export function formatPretty(result) {
31
+ const lines = [];
32
+ if (!result.ok) {
33
+ lines.push(chalk.red.bold('✗ Claude Code pack operation failed.'));
34
+ if (result.actions.errors.length > 0) {
35
+ lines.push(chalk.red('errors:'));
36
+ for (const err of result.actions.errors) {
37
+ lines.push(chalk.red(` - ${err}`));
38
+ }
39
+ }
40
+ if (result.warnings.length > 0) {
41
+ lines.push(chalk.yellow('warnings:'));
42
+ for (const w of result.warnings) {
43
+ lines.push(chalk.yellow(` - ${w}`));
44
+ }
45
+ }
46
+ return lines.join('\n');
47
+ }
48
+ const version = result.packVersion ? `v${result.packVersion}` : '(check only)';
49
+ const mjLabel = result.installedMJVersion
50
+ ? `for MJ v${result.installedMJVersion}`
51
+ : 'no local MJ detected';
52
+ lines.push(chalk.green.bold(`✓ Claude Code pack ${version} ${mjLabel}`));
53
+ appendBucket(lines, 'added', result.actions.added, chalk.green);
54
+ appendBucket(lines, 'updated', result.actions.updated, chalk.cyan);
55
+ appendBucket(lines, 'skipped', result.actions.skipped, chalk.dim, 5);
56
+ if (result.notes.length > 0) {
57
+ lines.push(chalk.cyan(`notes (${result.notes.length}):`));
58
+ for (const n of result.notes) {
59
+ lines.push(chalk.cyan(` - ${n}`));
60
+ }
61
+ }
62
+ if (result.warnings.length > 0) {
63
+ lines.push(chalk.yellow(`warnings (${result.warnings.length}):`));
64
+ for (const w of result.warnings) {
65
+ lines.push(chalk.yellow(` - ${w}`));
66
+ }
67
+ }
68
+ return lines.join('\n');
69
+ }
70
+ function appendBucket(lines, label, entries, color, maxList = Number.POSITIVE_INFINITY) {
71
+ if (entries.length === 0)
72
+ return;
73
+ lines.push(color(`${label} (${entries.length}):`));
74
+ const shown = entries.slice(0, maxList);
75
+ for (const e of shown) {
76
+ lines.push(color(` - ${e}`));
77
+ }
78
+ if (entries.length > shown.length) {
79
+ lines.push(color(` … ${entries.length - shown.length} more`));
80
+ }
81
+ }
82
+ //# sourceMappingURL=PackOutputFormatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackOutputFormatter.js","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackOutputFormatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Path helpers for the Claude Code pack install / update flow.
3
+ *
4
+ * Pure path math + a small `package.json`-reading helper for detecting the
5
+ * MJ major version a user's project is on. No network, no FS mutation.
6
+ *
7
+ * @see plans/claude-install-pack.md §3.2 (target layout), §6.4 (paths per rule)
8
+ */
9
+ /**
10
+ * Every file/directory in a user's project that the pack writes to or
11
+ * reads from. Built from a single `targetDir` so callers don't have to
12
+ * `path.join` repeatedly.
13
+ */
14
+ export interface TargetPaths {
15
+ /** The root directory we're installing into. */
16
+ Root: string;
17
+ /** `<Root>/CLAUDE.md` — root instructions file. */
18
+ ClaudeMd: string;
19
+ /** `<Root>/package.json` — used for MJ major detection. */
20
+ PackageJson: string;
21
+ /** `<Root>/.claude/` — the Claude Code config root. */
22
+ ClaudeDir: string;
23
+ /** `<Root>/.claude/settings.json` — settings file we merge into. */
24
+ SettingsJson: string;
25
+ /** `<Root>/.claude/mj/` — the fully-managed bundle directory. */
26
+ MjDir: string;
27
+ /** `<Root>/.claude/mj/VERSION` — pack version stamp. */
28
+ VersionFile: string;
29
+ /** `<Root>/.claude/mj/MANIFEST.json` — checksums of the installed pack. */
30
+ ManifestFile: string;
31
+ /** `<Root>/.claude/commands/` — curated commands directory. */
32
+ CommandsDir: string;
33
+ /** `<Root>/.claude/skills/` — curated skills directory. */
34
+ SkillsDir: string;
35
+ }
36
+ /** Compute every target path for a given install directory. */
37
+ export declare function targetPathsFor(targetDir: string): TargetPaths;
38
+ /**
39
+ * When `--from <path>` is used, the path may point at either:
40
+ * - the **MJ repo root** (we look for `templates/claude-pack/dist/v{N}/` underneath), or
41
+ * - an **already-unpacked dist directory** (we use it directly).
42
+ *
43
+ * Returns the resolved root of the pack contents, or null if neither shape works.
44
+ */
45
+ export declare function resolveLocalPackRoot(fromPath: string, mjMajor: string): string | null;
46
+ /**
47
+ * Strip the leading `^` / `~` / `>=` / etc. and extract the first numeric
48
+ * component. Returns `null` if the string isn't a recognizable semver.
49
+ *
50
+ * Accepts: `5.33.0`, `^5.33.0`, `~5.33.0`, `>=5.33.0`, `5`, `v5.33.0`.
51
+ * Rejects: empty, `next`, `latest`, `*`, anything without a leading digit
52
+ * after the strip.
53
+ */
54
+ export declare function parseSemverMajor(version: string): string | null;
55
+ /**
56
+ * Detect the MJ major version installed in the user's project. Reads
57
+ * `<dir>/package.json` and looks at any `@memberjunction/*` entry in
58
+ * `dependencies` or `devDependencies`. Falls back to scanning
59
+ * `<dir>/apps/*\/package.json` and `<dir>/packages/*\/package.json` for
60
+ * distribution-style workspace installs whose root has no direct @mj deps.
61
+ *
62
+ * Returns `null` if no MJ dependency is declared anywhere reachable (e.g.,
63
+ * a fresh `mj install` that hasn't run `npm install` yet, or a non-MJ project).
64
+ */
65
+ export declare function detectMJMajor(targetDir: string): string | null;
66
+ /**
67
+ * Detect the full MJ semver string (e.g. `5.33.0`) installed in the user's
68
+ * project. Same scan order as {@link detectMJMajor} — root, then workspace
69
+ * subdirs. Returns the bare semver with any `^`/`~`/`>=` prefix stripped,
70
+ * or `null` if nothing is reachable.
71
+ */
72
+ export declare function detectMJVersionString(targetDir: string): string | null;
73
+ /**
74
+ * Build the remote URL prefix for a given MJ major and git ref.
75
+ *
76
+ * `ref` defaults to `main`. Callers that want pinned-to-tag behavior should
77
+ * pass the tag explicitly (e.g. `v5.33.0`) — see plan §8.5.
78
+ */
79
+ export declare function buildRemoteUrlPrefix(mjMajor: string, ref?: string): string;
80
+ //# sourceMappingURL=PackPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackPaths.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackPaths.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAgB7D;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBrF;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAO/D;AAkED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM9D;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMtE;AASD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAe,GAAG,MAAM,CAElF"}
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Path helpers for the Claude Code pack install / update flow.
3
+ *
4
+ * Pure path math + a small `package.json`-reading helper for detecting the
5
+ * MJ major version a user's project is on. No network, no FS mutation.
6
+ *
7
+ * @see plans/claude-install-pack.md §3.2 (target layout), §6.4 (paths per rule)
8
+ */
9
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
10
+ import path from 'node:path';
11
+ /** Compute every target path for a given install directory. */
12
+ export function targetPathsFor(targetDir) {
13
+ const root = path.resolve(targetDir);
14
+ const claudeDir = path.join(root, '.claude');
15
+ const mjDir = path.join(claudeDir, 'mj');
16
+ return {
17
+ Root: root,
18
+ ClaudeMd: path.join(root, 'CLAUDE.md'),
19
+ PackageJson: path.join(root, 'package.json'),
20
+ ClaudeDir: claudeDir,
21
+ SettingsJson: path.join(claudeDir, 'settings.json'),
22
+ MjDir: mjDir,
23
+ VersionFile: path.join(mjDir, 'VERSION'),
24
+ ManifestFile: path.join(mjDir, 'MANIFEST.json'),
25
+ CommandsDir: path.join(claudeDir, 'commands'),
26
+ SkillsDir: path.join(claudeDir, 'skills'),
27
+ };
28
+ }
29
+ // ---------------------------------------------------------------------------
30
+ // Pack source paths (when loading from a local copy of the MJ repo)
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * When `--from <path>` is used, the path may point at either:
34
+ * - the **MJ repo root** (we look for `templates/claude-pack/dist/v{N}/` underneath), or
35
+ * - an **already-unpacked dist directory** (we use it directly).
36
+ *
37
+ * Returns the resolved root of the pack contents, or null if neither shape works.
38
+ */
39
+ export function resolveLocalPackRoot(fromPath, mjMajor) {
40
+ const abs = path.resolve(fromPath);
41
+ // Shape A: MJ repo root — look for templates/claude-pack/dist/v{N}/
42
+ const repoCandidate = path.join(abs, 'templates', 'claude-pack', 'dist', `v${mjMajor}`);
43
+ if (existsSync(path.join(repoCandidate, 'CLAUDE.md'))) {
44
+ return repoCandidate;
45
+ }
46
+ // Shape B: already-unpacked dist — must contain CLAUDE.md + .claude/mj/VERSION
47
+ if (existsSync(path.join(abs, 'CLAUDE.md')) &&
48
+ existsSync(path.join(abs, '.claude', 'mj', 'VERSION'))) {
49
+ return abs;
50
+ }
51
+ return null;
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // MJ major version detection
55
+ // ---------------------------------------------------------------------------
56
+ /**
57
+ * Strip the leading `^` / `~` / `>=` / etc. and extract the first numeric
58
+ * component. Returns `null` if the string isn't a recognizable semver.
59
+ *
60
+ * Accepts: `5.33.0`, `^5.33.0`, `~5.33.0`, `>=5.33.0`, `5`, `v5.33.0`.
61
+ * Rejects: empty, `next`, `latest`, `*`, anything without a leading digit
62
+ * after the strip.
63
+ */
64
+ export function parseSemverMajor(version) {
65
+ const trimmed = version.trim();
66
+ if (!trimmed)
67
+ return null;
68
+ // Strip common range/prefix chars: ^ ~ >= <= = > < v
69
+ const stripped = trimmed.replace(/^(\^|~|>=|<=|>|<|=|v)+/, '');
70
+ const match = stripped.match(/^(\d+)(?:\.|$)/);
71
+ return match ? match[1] : null;
72
+ }
73
+ /**
74
+ * Workspace subdirectories that distribution-style `mj install` outputs
75
+ * place @memberjunction/* deps under (e.g. `apps/MJAPI`, `apps/MJExplorer`,
76
+ * and any custom `packages/*` packages). When the root `package.json` is
77
+ * a workspace shell with no direct @mj deps, we walk one level into each
78
+ * of these subdirs to find them.
79
+ */
80
+ const WORKSPACE_SUBDIRS = ['apps', 'packages'];
81
+ /**
82
+ * Collect every `@memberjunction/*` dep entry visible to a target install dir.
83
+ *
84
+ * Looks at:
85
+ * 1. `<dir>/package.json`
86
+ * 2. `<dir>/apps/*\/package.json`
87
+ * 3. `<dir>/packages/*\/package.json`
88
+ *
89
+ * The walk-the-workspaces fallback is needed for distribution-style installs
90
+ * (the output of `mj install`), where the root `package.json` is a workspace
91
+ * shell — `@memberjunction/*` deps live in `apps/MJAPI/package.json`,
92
+ * `apps/MJExplorer/package.json`, etc. Source-style monorepo checkouts and
93
+ * simple consumer projects all keep deps at the root, where step 1 finds them.
94
+ *
95
+ * Returned in iteration order (root first, then alphabetical subdir order)
96
+ * so the FIRST entry found drives single-answer functions like
97
+ * {@link detectMJMajor}. Returns an empty array when no MJ deps are visible
98
+ * anywhere reachable.
99
+ */
100
+ function collectMJDeps(targetDir) {
101
+ const candidates = [path.join(targetDir, 'package.json')];
102
+ for (const subdir of WORKSPACE_SUBDIRS) {
103
+ const dir = path.join(targetDir, subdir);
104
+ let entries;
105
+ try {
106
+ entries = readdirSync(dir);
107
+ }
108
+ catch {
109
+ continue;
110
+ }
111
+ entries.sort();
112
+ for (const entry of entries) {
113
+ candidates.push(path.join(dir, entry, 'package.json'));
114
+ }
115
+ }
116
+ const collected = [];
117
+ for (const pkgPath of candidates) {
118
+ if (!existsSync(pkgPath))
119
+ continue;
120
+ let pkg;
121
+ try {
122
+ pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
123
+ }
124
+ catch {
125
+ continue;
126
+ }
127
+ const deps = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
128
+ for (const [name, version] of Object.entries(deps)) {
129
+ if (name.startsWith('@memberjunction/')) {
130
+ collected.push({ name, version });
131
+ }
132
+ }
133
+ }
134
+ return collected;
135
+ }
136
+ /**
137
+ * Detect the MJ major version installed in the user's project. Reads
138
+ * `<dir>/package.json` and looks at any `@memberjunction/*` entry in
139
+ * `dependencies` or `devDependencies`. Falls back to scanning
140
+ * `<dir>/apps/*\/package.json` and `<dir>/packages/*\/package.json` for
141
+ * distribution-style workspace installs whose root has no direct @mj deps.
142
+ *
143
+ * Returns `null` if no MJ dependency is declared anywhere reachable (e.g.,
144
+ * a fresh `mj install` that hasn't run `npm install` yet, or a non-MJ project).
145
+ */
146
+ export function detectMJMajor(targetDir) {
147
+ for (const { version } of collectMJDeps(targetDir)) {
148
+ const major = parseSemverMajor(version);
149
+ if (major)
150
+ return major;
151
+ }
152
+ return null;
153
+ }
154
+ /**
155
+ * Detect the full MJ semver string (e.g. `5.33.0`) installed in the user's
156
+ * project. Same scan order as {@link detectMJMajor} — root, then workspace
157
+ * subdirs. Returns the bare semver with any `^`/`~`/`>=` prefix stripped,
158
+ * or `null` if nothing is reachable.
159
+ */
160
+ export function detectMJVersionString(targetDir) {
161
+ for (const { version } of collectMJDeps(targetDir)) {
162
+ const stripped = version.replace(/^(\^|~|>=|<=|>|<|=|v)+/, '');
163
+ if (/^\d+\./.test(stripped))
164
+ return stripped;
165
+ }
166
+ return null;
167
+ }
168
+ // ---------------------------------------------------------------------------
169
+ // Remote URL construction
170
+ // ---------------------------------------------------------------------------
171
+ /** Default GitHub raw URL prefix for the pack's `dist/` tree. */
172
+ const DEFAULT_RAW_BASE = 'https://raw.githubusercontent.com/MemberJunction/MJ';
173
+ /**
174
+ * Build the remote URL prefix for a given MJ major and git ref.
175
+ *
176
+ * `ref` defaults to `main`. Callers that want pinned-to-tag behavior should
177
+ * pass the tag explicitly (e.g. `v5.33.0`) — see plan §8.5.
178
+ */
179
+ export function buildRemoteUrlPrefix(mjMajor, ref = 'main') {
180
+ return `${DEFAULT_RAW_BASE}/${ref}/templates/claude-pack/dist/v${mjMajor}/`;
181
+ }
182
+ //# sourceMappingURL=PackPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackPaths.js","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackPaths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Shared types for the Claude Code pack install / update flow.
3
+ *
4
+ * The build pipeline in `templates/claude-pack/build-pack.mjs` (Milestone 1)
5
+ * emits a `MANIFEST.json` that this package consumes — its shape is the
6
+ * authoritative contract between the two.
7
+ *
8
+ * @see plans/claude-install-pack.md §5.2 (manifest format), §6.4 (merge rules),
9
+ * §7.4 (flags), §7.5 (JSON output)
10
+ */
11
+ /** One file entry inside a pack's `MANIFEST.json`. */
12
+ export interface ManifestEntry {
13
+ /** Pack-relative POSIX path, e.g. `.claude/mj/core.md`. */
14
+ path: string;
15
+ /** Byte length of the file as shipped. */
16
+ bytes: number;
17
+ /** Hex sha256 digest of the file bytes. */
18
+ sha256: string;
19
+ }
20
+ /** Top-level shape of `.claude/mj/MANIFEST.json`. */
21
+ export interface Manifest {
22
+ /** Pack semver, e.g. `5.1.0`. */
23
+ packVersion: string;
24
+ /** MJ major version, e.g. `5`. */
25
+ mjMajor: string;
26
+ /**
27
+ * Public URL prefix used as the base for over-the-wire fetches.
28
+ * Example: `https://raw.githubusercontent.com/MemberJunction/MJ/main/templates/claude-pack/dist/v5/`
29
+ */
30
+ remoteUrlPrefix: string;
31
+ files: ManifestEntry[];
32
+ }
33
+ /**
34
+ * Outcome bucket for a single file/path during install or update.
35
+ *
36
+ * Mirrors the `actions` keys in the JSON output (§7.5).
37
+ */
38
+ export type FileOutcome = 'added' | 'updated' | 'skipped' | 'error';
39
+ /**
40
+ * Per-file result emitted by the merger. The `reason` is a human-readable
41
+ * explanation surfaced in `--verbose` output and warnings.
42
+ */
43
+ export interface FileMergeResult {
44
+ path: string;
45
+ outcome: FileOutcome;
46
+ reason?: string;
47
+ }
48
+ /**
49
+ * Bucketed view of every file the operation touched. Drives both the
50
+ * human-readable summary and the `--json` output (§7.5).
51
+ */
52
+ export interface ActionLog {
53
+ added: string[];
54
+ updated: string[];
55
+ skipped: string[];
56
+ errors: string[];
57
+ }
58
+ /**
59
+ * Full result object — the shape returned to callers and serialized for
60
+ * `--json`. Matches the schema in §7.5 of the plan.
61
+ *
62
+ * **`warnings` vs `notes`**: a `warning` flags a state the caller may want to
63
+ * act on (no local pack, customized file would be overwritten, etc.); a
64
+ * `note` is purely informational status (`Pack is up to date`,
65
+ * `Update available: v5.1 → v5.2`). Older versions of this type collapsed
66
+ * both into `warnings`, which made successful `--check` runs look like
67
+ * something was wrong. `notes` is always present (empty array if none),
68
+ * keeping `--json` consumers happy.
69
+ */
70
+ export interface InstallResult {
71
+ ok: boolean;
72
+ packVersion: string;
73
+ /** MJ semver detected in the target dir (e.g. `5.33.0`), or `null` if undetectable. */
74
+ installedMJVersion: string | null;
75
+ actions: ActionLog;
76
+ warnings: string[];
77
+ notes: string[];
78
+ }
79
+ /** Empty action log helper — exported to avoid `{} as ActionLog` casts. */
80
+ export declare function emptyActionLog(): ActionLog;
81
+ /** Apply a single file's outcome to the rolling action log. */
82
+ export declare function recordOutcome(log: ActionLog, result: FileMergeResult): void;
83
+ /**
84
+ * A pack can be sourced from the network (raw.githubusercontent.com),
85
+ * from a local path on disk (for `--from <path>` or `--offline`), or from
86
+ * an already-installed copy (the user's existing `.claude/mj/`).
87
+ */
88
+ export type PackSource = {
89
+ kind: 'remote';
90
+ baseUrl: string;
91
+ ref: string;
92
+ } | {
93
+ kind: 'local';
94
+ rootDir: string;
95
+ };
96
+ /**
97
+ * The `__mj_managed` block embedded inside a user's `.claude/settings.json`.
98
+ * `keys` lists the dotted paths the MJ pack owns; the merger uses this to
99
+ * know what it's allowed to rewrite vs what belongs to the user.
100
+ *
101
+ * @see plans/claude-install-pack.md §10.2
102
+ */
103
+ export interface ManagedSettingsMeta {
104
+ /** Pack semver that last wrote this block. */
105
+ version: string;
106
+ /** MJ major the pack was built for. */
107
+ mjMajor?: string;
108
+ /** Dotted paths in `settings.json` that MJ manages. */
109
+ keys: string[];
110
+ }
111
+ /**
112
+ * Parsed shape of the `<!-- MJ-MANAGED:CLAUDE-PACK START … -->`…`<!-- MJ-MANAGED:CLAUDE-PACK END -->`
113
+ * block in a user's root `CLAUDE.md`. `before` and `after` together with the
114
+ * rewritten block reconstitute the full file.
115
+ */
116
+ export interface ManagedBlock {
117
+ before: string;
118
+ /** The contents between START and END markers (exclusive of marker lines). */
119
+ body: string;
120
+ after: string;
121
+ /** Attributes parsed off the START marker, e.g. `version=5.1.0` and `mj-major=5`. */
122
+ attrs: Record<string, string>;
123
+ }
124
+ //# sourceMappingURL=PackTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackTypes.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAMD;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAMD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,IAAI,SAAS,CAE1C;AAeD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAG3E;AAMD;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAMvC;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAMD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,qFAAqF;IACrF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Shared types for the Claude Code pack install / update flow.
3
+ *
4
+ * The build pipeline in `templates/claude-pack/build-pack.mjs` (Milestone 1)
5
+ * emits a `MANIFEST.json` that this package consumes — its shape is the
6
+ * authoritative contract between the two.
7
+ *
8
+ * @see plans/claude-install-pack.md §5.2 (manifest format), §6.4 (merge rules),
9
+ * §7.4 (flags), §7.5 (JSON output)
10
+ */
11
+ /** Empty action log helper — exported to avoid `{} as ActionLog` casts. */
12
+ export function emptyActionLog() {
13
+ return { added: [], updated: [], skipped: [], errors: [] };
14
+ }
15
+ /**
16
+ * Maps the per-file outcome to its bucket in `ActionLog`. The singular form
17
+ * (`'error'`) maps to the plural bucket name (`errors`) — kept this way
18
+ * because the JSON contract in §7.5 specifies `errors` (a list) while the
19
+ * outcome enum reads more naturally in singular form per record.
20
+ */
21
+ const OUTCOME_TO_BUCKET = {
22
+ added: 'added',
23
+ updated: 'updated',
24
+ skipped: 'skipped',
25
+ error: 'errors',
26
+ };
27
+ /** Apply a single file's outcome to the rolling action log. */
28
+ export function recordOutcome(log, result) {
29
+ const bucket = OUTCOME_TO_BUCKET[result.outcome];
30
+ log[bucket].push(result.reason ? `${result.path} (${result.reason})` : result.path);
31
+ }
32
+ //# sourceMappingURL=PackTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackTypes.js","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackTypes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAwFH,2EAA2E;AAC3E,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;GAKG;AACH,MAAM,iBAAiB,GAAyC;IAC9D,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,QAAQ;CAChB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAAC,GAAc,EAAE,MAAuB;IACnE,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Deep-merge for `.claude/settings.json`.
3
+ *
4
+ * The pack ships a baseline `settings.json` with a top-level
5
+ * `__mj_managed: { version, mjMajor?, keys: ["permissions.allow", "env.MJ_CLAUDE_PACK", ...] }`
6
+ * block. `keys` lists the dotted JSON paths the pack owns.
7
+ *
8
+ * The merger:
9
+ * 1. Deep-clones the user's existing settings as the starting point
10
+ * 2. For each path in `__mj_managed.keys`, merges the pack's value into the
11
+ * user's:
12
+ * - Arrays → union, deduped, user entries first then pack entries
13
+ * - Objects → recursive merge (per-key)
14
+ * - Primitives → pack wins (rare in practice — primitives shouldn't
15
+ * really be managed keys, but the rule keeps the merger total)
16
+ * 3. Replaces `__mj_managed` wholesale with the pack's block (so version
17
+ * and mjMajor stamps update on every merge)
18
+ * 4. Leaves every user key outside `__mj_managed.keys` completely alone
19
+ *
20
+ * @see plans/claude-install-pack.md §10.2
21
+ */
22
+ import type { ManagedSettingsMeta } from './PackTypes.js';
23
+ export declare class SettingsMergeError extends Error {
24
+ constructor(message: string);
25
+ }
26
+ export interface MergeSettingsOptions {
27
+ /** User's existing settings.json contents. Use `{}` when the file is absent. */
28
+ Existing: Record<string, unknown>;
29
+ /** The pack baseline (rendered from settings.template.json). Must contain `__mj_managed.keys`. */
30
+ Pack: Record<string, unknown>;
31
+ }
32
+ export interface MergeSettingsResult {
33
+ /** The merged settings JSON, ready to write back. */
34
+ Result: Record<string, unknown>;
35
+ /**
36
+ * True if the merged result differs from `Existing`. Lets the caller
37
+ * skip an FS write when nothing changed.
38
+ */
39
+ Changed: boolean;
40
+ }
41
+ export declare function mergeSettings(opts: MergeSettingsOptions): MergeSettingsResult;
42
+ /** Read the `__mj_managed` block out of a settings object, or null if absent. */
43
+ export declare function readManagedMeta(settings: Record<string, unknown>): ManagedSettingsMeta | null;
44
+ export declare function getAtPath(obj: Record<string, unknown>, dottedPath: string): unknown;
45
+ export declare function setAtPath(obj: Record<string, unknown>, dottedPath: string, value: unknown): void;
46
+ export declare function isPlainObject(v: unknown): v is Record<string, unknown>;
47
+ //# sourceMappingURL=SettingsMerger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsMerger.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/SettingsMerger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAM1D,qBAAa,kBAAmB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI9B;AAMD,MAAM,WAAW,oBAAoB;IACjC,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,kGAAkG;IAClG,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAChC,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,mBAAmB,CAuB7E;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,GAAG,IAAI,CAY7F;AA8CD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAQnF;AAED,wBAAgB,SAAS,CACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,GACf,IAAI,CAaN;AAMD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtE"}