@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,29 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { CLIPluginRegistry } from '@memberjunction/cli-core';
3
+ import { loadAllCliPlugins } from '../lib/cli-plugins.js';
4
+ import { emitUsage, renderDomainMap } from '../lib/usage-render.js';
5
+ /**
6
+ * Tier-1 progressive disclosure (plan §5, the linearis model). Returns a compact
7
+ * domain map — each domain + one-line summary + runtime class — so an agent
8
+ * discovers the CLI's surface in ~200 tokens instead of pulling the full ~13k
9
+ * command tree. The guidance string tells the agent to run `mj <domain> usage`
10
+ * before invoking, rather than guessing flags.
11
+ */
12
+ export default class Usage extends Command {
13
+ static { this.description = 'List mj command domains (AI-agent-friendly, tier-1 progressive disclosure). Then run `mj <domain> usage`.'; }
14
+ static { this.examples = [
15
+ `<%= config.bin %> <%= command.id %>`,
16
+ `<%= config.bin %> <%= command.id %> --format=json`,
17
+ ]; }
18
+ static { this.flags = {
19
+ format: Flags.string({ options: ['text', 'json', 'md'], default: 'text', description: 'Output format' }),
20
+ }; }
21
+ async run() {
22
+ const { flags } = await this.parse(Usage);
23
+ await loadAllCliPlugins(process.cwd());
24
+ const map = CLIPluginRegistry.BuildDomainMap();
25
+ const result = CLIPluginRegistry.AsResult('usage', { guidance: map.guidance, domains: map.domains });
26
+ emitUsage((m) => this.log(m), flags.format, result, renderDomainMap(map));
27
+ }
28
+ }
29
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/commands/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,OAAO;aACjC,gBAAW,GAAG,2GAA2G,CAAC;aAE1H,aAAQ,GAAG;QAChB,qCAAqC;QACrC,mDAAmD;KACpD,CAAC;aAEK,UAAK,GAAG;QACb,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;KACzG,CAAC;IAEF,KAAK,CAAC,GAAG;QACP,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACvC,MAAM,GAAG,GAAG,iBAAiB,CAAC,cAAc,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACrG,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,MAAgB,EAAE,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IACtF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"prerun.d.ts","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAInC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,QAAQ,CAoCxB,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"prerun.d.ts","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAInC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,QAAQ,CAoExB,CAAC;AAcF,eAAe,IAAI,CAAC"}
@@ -1,14 +1,48 @@
1
1
  import figlet from 'figlet';
2
2
  import { LIGHT_COMMANDS } from '../light-commands.js';
3
3
  const hook = async function (options) {
4
+ const argv = options.argv ?? [];
5
+ // Machine-readable output must keep stdout clean — suppress the banner AND the
6
+ // userAgent line entirely for `--format=json|md` and `--no-banner` (plan §1a/D4).
7
+ const formatArg = (() => {
8
+ const eq = argv.find((a) => a.startsWith('--format='));
9
+ if (eq)
10
+ return eq.slice('--format='.length);
11
+ const i = argv.indexOf('--format');
12
+ return i >= 0 ? argv[i + 1] : undefined;
13
+ })();
14
+ const machineFormat = formatArg === 'json' || formatArg === 'md';
15
+ const noBanner = argv.includes('--no-banner');
16
+ // `--no-banner` is global chrome — every command renders the banner, so suppressing
17
+ // it must work on ANY command, including those not yet migrated to BaseCLIPlugin
18
+ // (which don't declare the flag and would otherwise fail oclif's strict parser with
19
+ // "Nonexistent flag"). Signal suppression to MJCLIRuntimeHost via env (so migrated
20
+ // commands still gate their runtime advisory) and strip the flag from argv in place
21
+ // so the per-command parser never sees an undeclared flag.
22
+ if (noBanner) {
23
+ process.env.MJ_CLI_NO_BANNER = '1';
24
+ for (let i = argv.length - 1; i >= 0; i--) {
25
+ if (argv[i] === '--no-banner')
26
+ argv.splice(i, 1);
27
+ }
28
+ }
4
29
  // Skip banners if --quiet flag is present (or appears to be present)
5
- if (options.argv?.some((arg) => arg === '--quiet' || (/^-[^-]+/.test(arg) && arg.includes('q')))) {
30
+ if (machineFormat || noBanner || argv.some((arg) => arg === '--quiet' || (/^-[^-]+/.test(arg) && arg.includes('q')))) {
31
+ // Still conditionally load bootstrap below — just no decorative output.
32
+ return await maybeLoadBootstrap(options);
33
+ }
34
+ // Skip banners entirely when --json is requested — the contract for --json
35
+ // is that stdout is parseable JSON, and any banner above it breaks
36
+ // `mj … --json | jq`. This early-return also skips the userAgent line below.
37
+ if (options.argv?.some((arg) => arg === '--json')) {
6
38
  return;
7
39
  }
8
40
  // Suppress the large figlet banner for hot-path, frequently-run commands (e.g. `mj sync *`)
9
- // where it's pure scrollback cost. The compact userAgent line below still prints.
41
+ // and the agent-facing usage commands, where it's pure scrollback cost. The
42
+ // compact userAgent line below still prints.
10
43
  const commandIdForBanner = options.Command.id ?? '';
11
- const showFiglet = !commandIdForBanner.startsWith('sync');
44
+ const isUsageCommand = commandIdForBanner === 'usage' || commandIdForBanner.endsWith('usage');
45
+ const showFiglet = !commandIdForBanner.startsWith('sync') && !isUsageCommand;
12
46
  if (showFiglet) {
13
47
  options.context.log(process.stdout.columns >= 81
14
48
  ? figlet.textSync('MemberJunction', {
@@ -20,16 +54,23 @@ const hook = async function (options) {
20
54
  })
21
55
  : '~ M e m b e r J u n c t i o n ~');
22
56
  }
23
- if (options.Command.id !== 'version') {
57
+ // The agent-facing usage commands (`mj usage`, `mj <domain> usage`) are meant to
58
+ // be a terse domain map — skip the userAgent line so text-mode stdout stays clean.
59
+ if (options.Command.id !== 'version' && !isUsageCommand) {
24
60
  options.context.log(options.config.userAgent + '\n');
25
61
  }
26
- // Conditionally load MJ bootstrap for heavy commands.
27
- // Light commands (version, help, bump, migrate, clean, install, dbdoc/*)
28
- // skip the ~1,400 class registrations for instant startup.
62
+ await maybeLoadBootstrap(options);
63
+ };
64
+ /**
65
+ * Conditionally load MJ bootstrap for heavy commands. Light commands (version,
66
+ * help, bump, migrate, clean, install, dbdoc/*, usage/*) skip the ~1,400 class
67
+ * registrations for instant startup.
68
+ */
69
+ async function maybeLoadBootstrap(options) {
29
70
  const commandId = options.Command.id ?? '';
30
71
  if (!LIGHT_COMMANDS.has(commandId)) {
31
72
  await import('@memberjunction/server-bootstrap-lite/mj-class-registrations');
32
73
  }
33
- };
74
+ }
34
75
  export default hook;
35
76
  //# sourceMappingURL=prerun.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,IAAI,GAAmB,KAAK,WAAW,OAAO;IAClD,qEAAqE;IACrE,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjG,OAAO;IACT,CAAC;IAED,4FAA4F;IAC5F,kFAAkF;IAClF,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IACpD,MAAM,UAAU,GAAG,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAE1D,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE;YAC1B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE;gBAChC,IAAI,EAAE,UAAU;gBAChB,gBAAgB,EAAE,SAAS;gBAC3B,cAAc,EAAE,SAAS;gBACzB,KAAK,EAAE,GAAG;gBACV,eAAe,EAAE,IAAI;aACtB,CAAC;YACJ,CAAC,CAAC,iCAAiC,CACtC,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,sDAAsD;IACtD,yEAAyE;IACzE,2DAA2D;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,8DAA8D,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,IAAI,GAAmB,KAAK,WAAW,OAAO;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;IAEhC,+EAA+E;IAC/E,kFAAkF;IAClF,MAAM,SAAS,GAAG,CAAC,GAAuB,EAAE;QAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1C,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,aAAa,GAAG,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,IAAI,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAE9C,oFAAoF;IACpF,iFAAiF;IACjF,oFAAoF;IACpF,mFAAmF;IACnF,oFAAoF;IACpF,2DAA2D;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,GAAG,CAAC;QACnC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa;gBAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,IAAI,aAAa,IAAI,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrH,wEAAwE;QACxE,OAAO,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,2EAA2E;IAC3E,mEAAmE;IACnE,6EAA6E;IAC7E,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IAED,4FAA4F;IAC5F,4EAA4E;IAC5E,6CAA6C;IAC7C,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IACpD,MAAM,cAAc,GAAG,kBAAkB,KAAK,OAAO,IAAI,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9F,MAAM,UAAU,GAAG,CAAC,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC;IAE7E,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,OAAO,CAAC,GAAG,CACjB,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE;YAC1B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE;gBAChC,IAAI,EAAE,UAAU;gBAChB,gBAAgB,EAAE,SAAS;gBAC3B,cAAc,EAAE,SAAS;gBACzB,KAAK,EAAE,GAAG;gBACV,eAAe,EAAE,IAAI;aACtB,CAAC;YACJ,CAAC,CAAC,iCAAiC,CACtC,CAAC;IACJ,CAAC;IAED,iFAAiF;IACjF,mFAAmF;IACnF,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;QACxD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,OAAqC;IACrE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,8DAA8D,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,eAAe,IAAI,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Parse + rewrite the MJ-managed block in a user's `CLAUDE.md`.
3
+ *
4
+ * The block is delimited by HTML comment markers:
5
+ * <!-- MJ-MANAGED:CLAUDE-PACK START key=value key=value -->
6
+ * ... managed content ...
7
+ * <!-- MJ-MANAGED:CLAUDE-PACK END -->
8
+ *
9
+ * Everything before and after the block is the user's free section and must
10
+ * never be touched.
11
+ *
12
+ * @see plans/claude-install-pack.md §3.3, §6.4 (CLAUDE.md row), §10.4
13
+ */
14
+ import type { ManagedBlock } from './PackTypes.js';
15
+ export declare class ManagedBlockError extends Error {
16
+ constructor(message: string);
17
+ }
18
+ /**
19
+ * Find the managed block in a CLAUDE.md file. Returns `null` when no markers
20
+ * are present (caller should handle the "file exists but unmanaged" case).
21
+ * Throws `ManagedBlockError` when markers are malformed (e.g. END before
22
+ * START, only one marker present, multiple START markers).
23
+ */
24
+ export declare function parseManagedBlock(content: string): ManagedBlock | null;
25
+ /**
26
+ * Replace the managed block in `content` with `newBody`, updating attributes
27
+ * on the START marker.
28
+ *
29
+ * Throws `ManagedBlockError` if no managed block is present — callers should
30
+ * use `wrapWithManagedBlock` for the first-install case.
31
+ */
32
+ export declare function rewriteManagedBlock(content: string, newBody: string, newAttrs: Record<string, string>): string;
33
+ /**
34
+ * Wrap arbitrary `content` with a managed block, placing the block at the
35
+ * top and the original content below (as the user's free section).
36
+ *
37
+ * If `content` is empty, the result is just the rendered managed block.
38
+ */
39
+ export declare function wrapWithManagedBlock(content: string, body: string, attrs: Record<string, string>): string;
40
+ //# sourceMappingURL=ManagedBlockEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManagedBlockEditor.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/ManagedBlockEditor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAenD,qBAAa,iBAAkB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI9B;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAiCtE;AA0BD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,MAAM,CAMR;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAKR"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Parse + rewrite the MJ-managed block in a user's `CLAUDE.md`.
3
+ *
4
+ * The block is delimited by HTML comment markers:
5
+ * <!-- MJ-MANAGED:CLAUDE-PACK START key=value key=value -->
6
+ * ... managed content ...
7
+ * <!-- MJ-MANAGED:CLAUDE-PACK END -->
8
+ *
9
+ * Everything before and after the block is the user's free section and must
10
+ * never be touched.
11
+ *
12
+ * @see plans/claude-install-pack.md §3.3, §6.4 (CLAUDE.md row), §10.4
13
+ */
14
+ // ---------------------------------------------------------------------------
15
+ // Marker constants
16
+ // ---------------------------------------------------------------------------
17
+ /** Match a START marker line and capture the attribute string. */
18
+ const START_RE = /<!--\s*MJ-MANAGED:CLAUDE-PACK\s+START\s*([^>]*?)\s*-->/;
19
+ /** Match an END marker line. */
20
+ const END_RE = /<!--\s*MJ-MANAGED:CLAUDE-PACK\s+END\s*-->/;
21
+ // ---------------------------------------------------------------------------
22
+ // Errors
23
+ // ---------------------------------------------------------------------------
24
+ export class ManagedBlockError extends Error {
25
+ constructor(message) {
26
+ super(message);
27
+ this.name = 'ManagedBlockError';
28
+ }
29
+ }
30
+ // ---------------------------------------------------------------------------
31
+ // Parse
32
+ // ---------------------------------------------------------------------------
33
+ /**
34
+ * Find the managed block in a CLAUDE.md file. Returns `null` when no markers
35
+ * are present (caller should handle the "file exists but unmanaged" case).
36
+ * Throws `ManagedBlockError` when markers are malformed (e.g. END before
37
+ * START, only one marker present, multiple START markers).
38
+ */
39
+ export function parseManagedBlock(content) {
40
+ const startMatch = START_RE.exec(content);
41
+ const endMatch = END_RE.exec(content);
42
+ if (!startMatch && !endMatch)
43
+ return null;
44
+ if (!startMatch) {
45
+ throw new ManagedBlockError('CLAUDE.md has MJ-MANAGED END marker without a matching START.');
46
+ }
47
+ if (!endMatch) {
48
+ throw new ManagedBlockError('CLAUDE.md has MJ-MANAGED START marker without a matching END.');
49
+ }
50
+ if (endMatch.index < startMatch.index) {
51
+ throw new ManagedBlockError('CLAUDE.md has MJ-MANAGED END marker before its START marker.');
52
+ }
53
+ // Detect a second START marker — that's a corrupted file we won't auto-fix.
54
+ const secondStart = START_RE.exec(content.slice(startMatch.index + startMatch[0].length));
55
+ if (secondStart) {
56
+ throw new ManagedBlockError('CLAUDE.md has multiple MJ-MANAGED START markers; expected exactly one.');
57
+ }
58
+ const before = content.slice(0, startMatch.index);
59
+ const bodyStart = startMatch.index + startMatch[0].length;
60
+ const bodyEnd = endMatch.index;
61
+ const body = content.slice(bodyStart, bodyEnd);
62
+ const after = content.slice(endMatch.index + endMatch[0].length);
63
+ const attrs = parseAttrs(startMatch[1]);
64
+ return { before, body, after, attrs };
65
+ }
66
+ /**
67
+ * Parse `key=value key2=value2` attribute strings from a START marker.
68
+ *
69
+ * Supports unquoted values without spaces (which is what build-pack.mjs emits).
70
+ * Returns an empty record for an empty attribute string.
71
+ */
72
+ function parseAttrs(raw) {
73
+ const out = {};
74
+ const trimmed = raw.trim();
75
+ if (!trimmed)
76
+ return out;
77
+ for (const pair of trimmed.split(/\s+/)) {
78
+ const eq = pair.indexOf('=');
79
+ if (eq <= 0)
80
+ continue; // skip malformed pairs silently
81
+ const key = pair.slice(0, eq);
82
+ const value = pair.slice(eq + 1);
83
+ out[key] = value;
84
+ }
85
+ return out;
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // Rewrite
89
+ // ---------------------------------------------------------------------------
90
+ /**
91
+ * Replace the managed block in `content` with `newBody`, updating attributes
92
+ * on the START marker.
93
+ *
94
+ * Throws `ManagedBlockError` if no managed block is present — callers should
95
+ * use `wrapWithManagedBlock` for the first-install case.
96
+ */
97
+ export function rewriteManagedBlock(content, newBody, newAttrs) {
98
+ const block = parseManagedBlock(content);
99
+ if (!block) {
100
+ throw new ManagedBlockError('Cannot rewrite — no managed block found in content.');
101
+ }
102
+ return block.before + formatStartMarker(newAttrs) + newBody + formatEndMarker() + block.after;
103
+ }
104
+ /**
105
+ * Wrap arbitrary `content` with a managed block, placing the block at the
106
+ * top and the original content below (as the user's free section).
107
+ *
108
+ * If `content` is empty, the result is just the rendered managed block.
109
+ */
110
+ export function wrapWithManagedBlock(content, body, attrs) {
111
+ const startMarker = formatStartMarker(attrs);
112
+ const endMarker = formatEndMarker();
113
+ const trailing = content.length > 0 ? '\n\n' + content : '\n';
114
+ return startMarker + body + endMarker + trailing;
115
+ }
116
+ function formatStartMarker(attrs) {
117
+ const attrString = Object.entries(attrs)
118
+ .map(([k, v]) => `${k}=${v}`)
119
+ .join(' ');
120
+ return attrString
121
+ ? `<!-- MJ-MANAGED:CLAUDE-PACK START ${attrString} -->`
122
+ : `<!-- MJ-MANAGED:CLAUDE-PACK START -->`;
123
+ }
124
+ function formatEndMarker() {
125
+ return `<!-- MJ-MANAGED:CLAUDE-PACK END -->`;
126
+ }
127
+ //# sourceMappingURL=ManagedBlockEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ManagedBlockEditor.js","sourceRoot":"","sources":["../../../src/lib/claude-pack/ManagedBlockEditor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Fetches a Claude Code pack from `raw.githubusercontent.com`, verifies sha256
3
+ * against the manifest, and handles the tag→main ref-fallback per plan §8.5.
4
+ *
5
+ * Design notes:
6
+ * - HTTP transport is injected via `HttpGetter` so tests can plug in a mock
7
+ * without `vi.mock('node:https')`. Production uses `realHttpGet` (a thin
8
+ * wrapper over `node:https`).
9
+ * - No tokens, no auth headers — `raw.githubusercontent.com` is public
10
+ * (plan §7.7). The fetcher never includes credentials.
11
+ * - No caching here. The orchestrator decides whether to re-fetch.
12
+ *
13
+ * @see plans/claude-install-pack.md §5.2 (manifest), §6.3, §8.5 (ref fallback)
14
+ */
15
+ import type { Manifest } from './PackTypes.js';
16
+ /**
17
+ * Response body is typed as `Uint8Array` (Buffer's superclass) so this type
18
+ * stays portable across Node typings versions that vary in how strictly they
19
+ * model Buffer's ArrayBuffer parameter. `Buffer.concat` and `createHash`
20
+ * both accept `Uint8Array` directly.
21
+ */
22
+ export interface HttpResponse {
23
+ statusCode: number;
24
+ body: Uint8Array;
25
+ }
26
+ /** Promise-based GET. Production = node:https; tests = mock. */
27
+ export type HttpGetter = (url: string) => Promise<HttpResponse>;
28
+ /**
29
+ * Real production fetcher using `node:https`.
30
+ *
31
+ * Implementation note: builds the response body via manual Uint8Array
32
+ * concatenation instead of `Buffer.concat()` — the latter's return type
33
+ * (`Buffer`) doesn't cleanly assign to `Uint8Array` in the strict @types/node
34
+ * generics that ship with v20+, even though Buffer extends Uint8Array.
35
+ */
36
+ export declare const realHttpGet: HttpGetter;
37
+ export declare class PackFetchError extends Error {
38
+ url?: string;
39
+ statusCode?: number;
40
+ constructor(message: string, url?: string, statusCode?: number);
41
+ }
42
+ export declare class PackChecksumError extends Error {
43
+ path: string;
44
+ expected: string;
45
+ actual: string;
46
+ constructor(message: string, path: string, expected: string, actual: string);
47
+ }
48
+ export interface FetchPackOptions {
49
+ /** MJ major version (e.g. `5`). Required — used to locate `dist/v{N}/`. */
50
+ Major: string;
51
+ /**
52
+ * Git ref to fetch from. Defaults to `'main'`. If a specific tag is given
53
+ * and it 404s, the fetcher transparently falls back to `'main'`.
54
+ */
55
+ Ref?: string;
56
+ /** Injected HTTP getter — test seam. Defaults to `realHttpGet`. */
57
+ HttpGet?: HttpGetter;
58
+ /** Progress callback for verbose mode. */
59
+ OnProgress?: (message: string) => void;
60
+ /**
61
+ * When true, fetch only the manifest and skip the per-file downloads.
62
+ * Used by `mj update:claude --check` to compare versions without paying
63
+ * for content the caller won't write. The returned `Files` map is empty.
64
+ */
65
+ ManifestOnly?: boolean;
66
+ }
67
+ export interface FetchedPack {
68
+ /** Parsed MANIFEST.json. */
69
+ Manifest: Manifest;
70
+ /**
71
+ * Pack file contents keyed by manifest path (e.g. `.claude/mj/core.md`).
72
+ * Bytes verified against the manifest's sha256 before insertion.
73
+ */
74
+ Files: Map<string, Uint8Array>;
75
+ /** Which ref was actually used (after fallback). */
76
+ RefUsed: string;
77
+ /** The full base URL the fetcher ultimately read from. */
78
+ BaseUrl: string;
79
+ }
80
+ /**
81
+ * Fetch a pack: manifest first, then every file listed in it, verifying
82
+ * sha256 along the way. Falls back from a specific tag to `main` if the
83
+ * manifest 404s.
84
+ */
85
+ export declare function fetchPack(opts: FetchPackOptions): Promise<FetchedPack>;
86
+ //# sourceMappingURL=PackFetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackFetcher.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackFetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,gBAAgB,CAAC;AAO9D;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,CAAC;CACpB;AAED,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAEhE;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,UAcpB,CAAC;AAiBP,qBAAa,cAAe,SAAQ,KAAK;IACD,GAAG,CAAC,EAAE,MAAM;IAAS,UAAU,CAAC,EAAE,MAAM;gBAAhE,OAAO,EAAE,MAAM,EAAS,GAAG,CAAC,EAAE,MAAM,EAAS,UAAU,CAAC,EAAE,MAAM;CAI/E;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAG7B,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,MAAM;IAChB,MAAM,EAAE,MAAM;gBAHrB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM;CAK5B;AAMD,MAAM,WAAW,gBAAgB;IAC7B,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,WAAW;IACxB,4BAA4B;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB;;;OAGG;IACH,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC/B,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;CACnB;AAMD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiC5E"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Fetches a Claude Code pack from `raw.githubusercontent.com`, verifies sha256
3
+ * against the manifest, and handles the tag→main ref-fallback per plan §8.5.
4
+ *
5
+ * Design notes:
6
+ * - HTTP transport is injected via `HttpGetter` so tests can plug in a mock
7
+ * without `vi.mock('node:https')`. Production uses `realHttpGet` (a thin
8
+ * wrapper over `node:https`).
9
+ * - No tokens, no auth headers — `raw.githubusercontent.com` is public
10
+ * (plan §7.7). The fetcher never includes credentials.
11
+ * - No caching here. The orchestrator decides whether to re-fetch.
12
+ *
13
+ * @see plans/claude-install-pack.md §5.2 (manifest), §6.3, §8.5 (ref fallback)
14
+ */
15
+ import { createHash } from 'node:crypto';
16
+ import https from 'node:https';
17
+ import { buildRemoteUrlPrefix } from './PackPaths.js';
18
+ /**
19
+ * Real production fetcher using `node:https`.
20
+ *
21
+ * Implementation note: builds the response body via manual Uint8Array
22
+ * concatenation instead of `Buffer.concat()` — the latter's return type
23
+ * (`Buffer`) doesn't cleanly assign to `Uint8Array` in the strict @types/node
24
+ * generics that ship with v20+, even though Buffer extends Uint8Array.
25
+ */
26
+ export const realHttpGet = (url) => new Promise((resolve, reject) => {
27
+ const req = https.get(url, (res) => {
28
+ const chunks = [];
29
+ res.on('data', (chunk) => chunks.push(chunk));
30
+ res.on('end', () => {
31
+ resolve({ statusCode: res.statusCode ?? 0, body: concatBytes(chunks) });
32
+ });
33
+ res.on('error', reject);
34
+ });
35
+ req.on('error', reject);
36
+ req.setTimeout(30_000, () => {
37
+ req.destroy(new Error(`Timed out after 30s fetching ${url}`));
38
+ });
39
+ });
40
+ function concatBytes(chunks) {
41
+ const total = chunks.reduce((s, c) => s + c.byteLength, 0);
42
+ const out = new Uint8Array(total);
43
+ let offset = 0;
44
+ for (const c of chunks) {
45
+ out.set(c, offset);
46
+ offset += c.byteLength;
47
+ }
48
+ return out;
49
+ }
50
+ // ---------------------------------------------------------------------------
51
+ // Errors
52
+ // ---------------------------------------------------------------------------
53
+ export class PackFetchError extends Error {
54
+ constructor(message, url, statusCode) {
55
+ super(message);
56
+ this.url = url;
57
+ this.statusCode = statusCode;
58
+ this.name = 'PackFetchError';
59
+ }
60
+ }
61
+ export class PackChecksumError extends Error {
62
+ constructor(message, path, expected, actual) {
63
+ super(message);
64
+ this.path = path;
65
+ this.expected = expected;
66
+ this.actual = actual;
67
+ this.name = 'PackChecksumError';
68
+ }
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Main entry point
72
+ // ---------------------------------------------------------------------------
73
+ /**
74
+ * Fetch a pack: manifest first, then every file listed in it, verifying
75
+ * sha256 along the way. Falls back from a specific tag to `main` if the
76
+ * manifest 404s.
77
+ */
78
+ export async function fetchPack(opts) {
79
+ const httpGet = opts.HttpGet ?? realHttpGet;
80
+ const requestedRef = opts.Ref ?? 'main';
81
+ const onProgress = opts.OnProgress ?? (() => { });
82
+ const { manifest, refUsed, baseUrl } = await fetchManifestWithFallback(opts.Major, requestedRef, httpGet, onProgress);
83
+ const files = new Map();
84
+ if (opts.ManifestOnly) {
85
+ return { Manifest: manifest, Files: files, RefUsed: refUsed, BaseUrl: baseUrl };
86
+ }
87
+ for (const entry of manifest.files) {
88
+ const url = baseUrl + entry.path;
89
+ onProgress(`fetching ${entry.path}`);
90
+ const res = await httpGet(url);
91
+ if (res.statusCode !== 200) {
92
+ throw new PackFetchError(`Failed to fetch ${entry.path}: HTTP ${res.statusCode}`, url, res.statusCode);
93
+ }
94
+ verifyChecksum(entry, res.body);
95
+ files.set(entry.path, res.body);
96
+ }
97
+ return { Manifest: manifest, Files: files, RefUsed: refUsed, BaseUrl: baseUrl };
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Internals
101
+ // ---------------------------------------------------------------------------
102
+ async function fetchManifestWithFallback(major, requestedRef, httpGet, onProgress) {
103
+ const tryRef = async (ref) => {
104
+ const baseUrl = buildRemoteUrlPrefix(major, ref);
105
+ const manifestUrl = baseUrl + '.claude/mj/MANIFEST.json';
106
+ onProgress(`fetching manifest from ref=${ref}`);
107
+ const res = await httpGet(manifestUrl);
108
+ return { res, baseUrl, manifestUrl };
109
+ };
110
+ // First attempt: requested ref
111
+ const first = await tryRef(requestedRef);
112
+ if (first.res.statusCode === 200) {
113
+ return {
114
+ manifest: parseManifest(first.res.body, first.manifestUrl),
115
+ refUsed: requestedRef,
116
+ baseUrl: first.baseUrl,
117
+ };
118
+ }
119
+ // Fallback: try `main` if we weren't already on it AND the failure was 404.
120
+ // Other status codes (5xx, network errors) propagate immediately —
121
+ // fallback is for "this tag doesn't have the pack yet", not for "the
122
+ // network is broken".
123
+ if (first.res.statusCode === 404 && requestedRef !== 'main') {
124
+ onProgress(`ref ${requestedRef} 404; falling back to main`);
125
+ const second = await tryRef('main');
126
+ if (second.res.statusCode === 200) {
127
+ return {
128
+ manifest: parseManifest(second.res.body, second.manifestUrl),
129
+ refUsed: 'main',
130
+ baseUrl: second.baseUrl,
131
+ };
132
+ }
133
+ throw new PackFetchError(`Failed to fetch manifest from both ${requestedRef} and main (HTTP ${second.res.statusCode})`, second.manifestUrl, second.res.statusCode);
134
+ }
135
+ throw new PackFetchError(`Failed to fetch manifest from ${requestedRef}: HTTP ${first.res.statusCode}`, first.manifestUrl, first.res.statusCode);
136
+ }
137
+ function parseManifest(body, url) {
138
+ let raw;
139
+ try {
140
+ raw = JSON.parse(new TextDecoder('utf-8').decode(body));
141
+ }
142
+ catch (err) {
143
+ throw new PackFetchError(`Manifest at ${url} is not valid JSON: ${err.message}`, url);
144
+ }
145
+ if (!raw ||
146
+ typeof raw !== 'object' ||
147
+ typeof raw.packVersion !== 'string' ||
148
+ typeof raw.mjMajor !== 'string' ||
149
+ !Array.isArray(raw.files)) {
150
+ throw new PackFetchError(`Manifest at ${url} has the wrong shape`, url);
151
+ }
152
+ return raw;
153
+ }
154
+ function verifyChecksum(entry, body) {
155
+ const actual = createHash('sha256').update(body).digest('hex');
156
+ if (actual !== entry.sha256) {
157
+ throw new PackChecksumError(`Checksum mismatch for ${entry.path}: expected ${entry.sha256}, got ${actual}`, entry.path, entry.sha256, actual);
158
+ }
159
+ if (body.length !== entry.bytes) {
160
+ throw new PackChecksumError(`Size mismatch for ${entry.path}: expected ${entry.bytes} bytes, got ${body.length}`, entry.path, String(entry.bytes), String(body.length));
161
+ }
162
+ }
163
+ //# sourceMappingURL=PackFetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackFetcher.js","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackFetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Top-level orchestrator for `mj install:claude` and `mj update:claude`.
3
+ *
4
+ * Composes:
5
+ * - source resolution (remote via PackFetcher, or local via PackPaths)
6
+ * - MJ-major detection and the cross-major guard
7
+ * - the --check fast path (compare versions without touching the FS)
8
+ * - the merge (PackMerger) and InstallResult assembly
9
+ *
10
+ * The CLI command files thinly wrap this with flag parsing + output rendering.
11
+ *
12
+ * @see plans/claude-install-pack.md §6.3, §6.5, §7.4, §7.5
13
+ */
14
+ import { type HttpGetter } from './PackFetcher.js';
15
+ import { buildRemoteUrlPrefix } from './PackPaths.js';
16
+ import { type InstallResult } from './PackTypes.js';
17
+ export interface InstallPackOptions {
18
+ /** Absolute or relative target directory (default: process.cwd()). */
19
+ TargetDir: string;
20
+ /** Override the detected MJ major. Useful when target dir has no MJ deps yet. */
21
+ Major?: string;
22
+ /** Git ref to fetch from (branch or tag). Default: `'main'`. */
23
+ Ref?: string;
24
+ /**
25
+ * Use a local pack source instead of fetching. Accepts an MJ repo root
26
+ * (looks under `templates/claude-pack/dist/v{N}/`) or an already-unpacked
27
+ * dist directory.
28
+ */
29
+ FromPath?: string;
30
+ /** Forbid network — requires FromPath. */
31
+ Offline?: boolean;
32
+ /** Don't write anything, just compute the action plan. */
33
+ DryRun?: boolean;
34
+ /** Overwrite user-customized commands/skills (skip prompts). */
35
+ Force?: boolean;
36
+ /** Skip the seed of `.claude/commands/`. */
37
+ SkipCommands?: boolean;
38
+ /** Skip the seed of `.claude/skills/`. */
39
+ SkipSkills?: boolean;
40
+ /** Skip the `.claude/settings.json` deep-merge. */
41
+ SkipSettings?: boolean;
42
+ /** update:claude only — resync commands. */
43
+ RefreshCommands?: boolean;
44
+ /** update:claude only — resync skills. */
45
+ RefreshSkills?: boolean;
46
+ /** update:claude only — don't write; compare versions and return. */
47
+ CheckOnly?: boolean;
48
+ /**
49
+ * update:claude only — required when the remote pack's major differs from
50
+ * the local MJ install's major. Without this flag, the installer refuses
51
+ * the cross-major migration as a guardrail.
52
+ */
53
+ AllowMajor?: boolean;
54
+ /** Injected HTTP getter (tests). Defaults to real `node:https`. */
55
+ HttpGet?: HttpGetter;
56
+ /** Progress callback for verbose mode. */
57
+ OnProgress?: (message: string) => void;
58
+ }
59
+ export declare function installPack(opts: InstallPackOptions): Promise<InstallResult>;
60
+ /** Re-export the default raw URL prefix for tests / verbose logging. */
61
+ export { buildRemoteUrlPrefix };
62
+ //# sourceMappingURL=PackInstaller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PackInstaller.d.ts","sourceRoot":"","sources":["../../../src/lib/claude-pack/PackInstaller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,EAAa,KAAK,UAAU,EAAkB,MAAM,kBAAkB,CAAC;AAE9E,OAAO,EACH,oBAAoB,EAIvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAGH,KAAK,aAAa,EAErB,MAAM,gBAAgB,CAAC;AAMxB,MAAM,WAAW,kBAAkB;IAC/B,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mDAAmD;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0CAA0C;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mEAAmE;IACnE,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAMD,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CA2ElF;AA8ID,wEAAwE;AACxE,OAAO,EAAE,oBAAoB,EAAE,CAAC"}