@packmind/cli 0.7.0 → 0.8.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 (2) hide show
  1. package/main.cjs +1001 -371
  2. package/package.json +1 -1
package/main.cjs CHANGED
@@ -371,32 +371,32 @@ var init_supports_color = __esm({
371
371
  });
372
372
 
373
373
  // node_modules/chalk/source/utilities.js
374
- function stringReplaceAll(string4, substring, replacer) {
375
- let index = string4.indexOf(substring);
374
+ function stringReplaceAll(string5, substring, replacer) {
375
+ let index = string5.indexOf(substring);
376
376
  if (index === -1) {
377
- return string4;
377
+ return string5;
378
378
  }
379
379
  const substringLength = substring.length;
380
380
  let endIndex = 0;
381
381
  let returnValue = "";
382
382
  do {
383
- returnValue += string4.slice(endIndex, index) + substring + replacer;
383
+ returnValue += string5.slice(endIndex, index) + substring + replacer;
384
384
  endIndex = index + substringLength;
385
- index = string4.indexOf(substring, endIndex);
385
+ index = string5.indexOf(substring, endIndex);
386
386
  } while (index !== -1);
387
- returnValue += string4.slice(endIndex);
387
+ returnValue += string5.slice(endIndex);
388
388
  return returnValue;
389
389
  }
390
- function stringEncaseCRLFWithFirstIndex(string4, prefix, postfix, index) {
390
+ function stringEncaseCRLFWithFirstIndex(string5, prefix, postfix, index) {
391
391
  let endIndex = 0;
392
392
  let returnValue = "";
393
393
  do {
394
- const gotCR = string4[index - 1] === "\r";
395
- returnValue += string4.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
394
+ const gotCR = string5[index - 1] === "\r";
395
+ returnValue += string5.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
396
  endIndex = index + 1;
397
- index = string4.indexOf("\n", endIndex);
397
+ index = string5.indexOf("\n", endIndex);
398
398
  } while (index !== -1);
399
- returnValue += string4.slice(endIndex);
399
+ returnValue += string5.slice(endIndex);
400
400
  return returnValue;
401
401
  }
402
402
  var init_utilities = __esm({
@@ -555,26 +555,26 @@ var init_source = __esm({
555
555
  builder[IS_EMPTY] = _isEmpty;
556
556
  return builder;
557
557
  };
558
- applyStyle = (self, string4) => {
559
- if (self.level <= 0 || !string4) {
560
- return self[IS_EMPTY] ? "" : string4;
558
+ applyStyle = (self, string5) => {
559
+ if (self.level <= 0 || !string5) {
560
+ return self[IS_EMPTY] ? "" : string5;
561
561
  }
562
562
  let styler = self[STYLER];
563
563
  if (styler === void 0) {
564
- return string4;
564
+ return string5;
565
565
  }
566
566
  const { openAll, closeAll } = styler;
567
- if (string4.includes("\x1B")) {
567
+ if (string5.includes("\x1B")) {
568
568
  while (styler !== void 0) {
569
- string4 = stringReplaceAll(string4, styler.close, styler.open);
569
+ string5 = stringReplaceAll(string5, styler.close, styler.open);
570
570
  styler = styler.parent;
571
571
  }
572
572
  }
573
- const lfIndex = string4.indexOf("\n");
573
+ const lfIndex = string5.indexOf("\n");
574
574
  if (lfIndex !== -1) {
575
- string4 = stringEncaseCRLFWithFirstIndex(string4, closeAll, openAll, lfIndex);
575
+ string5 = stringEncaseCRLFWithFirstIndex(string5, closeAll, openAll, lfIndex);
576
576
  }
577
- return openAll + string4 + closeAll;
577
+ return openAll + string5 + closeAll;
578
578
  };
579
579
  Object.defineProperties(createChalk.prototype, styles2);
580
580
  chalk = createChalk();
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
1578
1578
  __export(strip_ansi_exports, {
1579
1579
  default: () => stripAnsi
1580
1580
  });
1581
- function stripAnsi(string4) {
1582
- if (typeof string4 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string4}\``);
1581
+ function stripAnsi(string5) {
1582
+ if (typeof string5 !== "string") {
1583
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string5}\``);
1584
1584
  }
1585
- return string4.replace(regex, "");
1585
+ return string5.replace(regex, "");
1586
1586
  }
1587
1587
  var regex;
1588
1588
  var init_strip_ansi = __esm({
@@ -1698,12 +1698,12 @@ var require_command = __commonJS({
1698
1698
  return mod && mod.__esModule ? mod : { "default": mod };
1699
1699
  };
1700
1700
  Object.defineProperty(exports2, "__esModule", { value: true });
1701
- exports2.command = command7;
1701
+ exports2.command = command8;
1702
1702
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1703
1703
  var Result = __importStar(require_Result());
1704
1704
  var circuitbreaker_1 = require_circuitbreaker();
1705
1705
  var utils_1 = require_utils();
1706
- function command7(config) {
1706
+ function command8(config) {
1707
1707
  const argEntries = (0, utils_1.entries)(config.args);
1708
1708
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1709
1709
  return {
@@ -3084,8 +3084,8 @@ var require_tokenizer = __commonJS({
3084
3084
  tokens.push(token);
3085
3085
  overallIndex += token.raw.length;
3086
3086
  };
3087
- for (const [stringIndex, string4] of (0, utils_1.enumerate)(strings)) {
3088
- const chars = [...string4];
3087
+ for (const [stringIndex, string5] of (0, utils_1.enumerate)(strings)) {
3088
+ const chars = [...string5];
3089
3089
  for (let i = 0; i < chars.length; i++) {
3090
3090
  if (chars[i] === "-" && chars[i + 1] === "-") {
3091
3091
  push({ type: "longPrefix", raw: "--", index: overallIndex });
@@ -3218,7 +3218,7 @@ var require_restPositionals = __commonJS({
3218
3218
  };
3219
3219
  }();
3220
3220
  Object.defineProperty(exports2, "__esModule", { value: true });
3221
- exports2.restPositionals = restPositionals2;
3221
+ exports2.restPositionals = restPositionals3;
3222
3222
  var Result = __importStar(require_Result());
3223
3223
  var types_1 = require_types();
3224
3224
  function fullRestPositionals(config) {
@@ -3262,7 +3262,7 @@ var require_restPositionals = __commonJS({
3262
3262
  }
3263
3263
  };
3264
3264
  }
3265
- function restPositionals2(config) {
3265
+ function restPositionals3(config) {
3266
3266
  return fullRestPositionals({
3267
3267
  type: types_1.string,
3268
3268
  ...config
@@ -3852,7 +3852,7 @@ var require_package = __commonJS({
3852
3852
  "apps/cli/package.json"(exports2, module2) {
3853
3853
  module2.exports = {
3854
3854
  name: "@packmind/cli",
3855
- version: "0.7.0",
3855
+ version: "0.8.0",
3856
3856
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3857
  private: false,
3858
3858
  bin: {
@@ -3894,7 +3894,7 @@ var require_package = __commonJS({
3894
3894
  });
3895
3895
 
3896
3896
  // apps/cli/src/main.ts
3897
- var import_cmd_ts7 = __toESM(require_cjs());
3897
+ var import_cmd_ts8 = __toESM(require_cjs());
3898
3898
 
3899
3899
  // apps/cli/src/infra/commands/LinterCommand.ts
3900
3900
  var import_cmd_ts = __toESM(require_cjs());
@@ -4092,12 +4092,6 @@ var DEFAULT_ACTIVE_RENDER_MODES = normalizeRenderModes([
4092
4092
  "AGENTS_MD" /* AGENTS_MD */
4093
4093
  ]);
4094
4094
 
4095
- // packages/types/src/deployments/RecipesDeploymentId.ts
4096
- var createRecipesDeploymentId = brandedIdFactory();
4097
-
4098
- // packages/types/src/deployments/StandardsDeploymentId.ts
4099
- var createStandardsDeploymentId = brandedIdFactory();
4100
-
4101
4095
  // packages/types/src/deployments/PackagesDeploymentId.ts
4102
4096
  var createPackagesDeploymentId = brandedIdFactory();
4103
4097
 
@@ -4693,8 +4687,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4693
4687
  static {
4694
4688
  this.fallbackRuleContent = "adhoc-rule";
4695
4689
  }
4696
- async execute(command7) {
4697
- const { program, fileContent, language } = command7;
4690
+ async execute(command8) {
4691
+ const { program, fileContent, language } = command8;
4698
4692
  const result = await this.linterExecutionUseCase.execute({
4699
4693
  filePath: "cli-single-file",
4700
4694
  fileContent,
@@ -4772,6 +4766,27 @@ ${error.message}`
4772
4766
  return null;
4773
4767
  }
4774
4768
  }
4769
+ getCurrentBranch(repoPath) {
4770
+ try {
4771
+ const { stdout } = this.gitRunner("rev-parse --abbrev-ref HEAD", {
4772
+ cwd: repoPath
4773
+ });
4774
+ const branch = stdout.trim();
4775
+ this.logger.debug("Resolved current branch", {
4776
+ repoPath,
4777
+ branch
4778
+ });
4779
+ return { branch };
4780
+ } catch (error) {
4781
+ if (error instanceof Error) {
4782
+ throw new Error(
4783
+ `Failed to get current Git branch. The path '${repoPath}' does not appear to be inside a Git repository.
4784
+ ${error.message}`
4785
+ );
4786
+ }
4787
+ throw new Error("Failed to get current Git branch: Unknown error");
4788
+ }
4789
+ }
4775
4790
  getCurrentBranches(repoPath) {
4776
4791
  try {
4777
4792
  const { stdout } = this.gitRunner("branch -a --contains HEAD", {
@@ -4870,19 +4885,7 @@ ${error.message}`
4870
4885
  return Array.from(branchNames);
4871
4886
  }
4872
4887
  normalizeGitUrl(url) {
4873
- const sshMatch = url.match(/^git@([^:]+):(.+)$/);
4874
- if (sshMatch) {
4875
- const [, host, urlPath] = sshMatch;
4876
- const cleanPath = urlPath.replace(/\.git$/, "");
4877
- return `${host}/${cleanPath}`;
4878
- }
4879
- const httpsMatch = url.match(/^https?:\/\/([^/]+)\/(.+)$/);
4880
- if (httpsMatch) {
4881
- const [, host, urlPath] = httpsMatch;
4882
- const cleanPath = urlPath.replace(/\.git$/, "");
4883
- return `${host}/${cleanPath}`;
4884
- }
4885
- return url;
4888
+ return url.replace(/\.git$/, "");
4886
4889
  }
4887
4890
  /**
4888
4891
  * Gets files that have been modified (staged + unstaged) compared to HEAD.
@@ -5053,8 +5056,8 @@ var GetGitRemoteUrlUseCase = class {
5053
5056
  constructor(gitRemoteUrlService = new GitService()) {
5054
5057
  this.gitRemoteUrlService = gitRemoteUrlService;
5055
5058
  }
5056
- async execute(command7) {
5057
- const { path: repoPath, origin: origin11 } = command7;
5059
+ async execute(command8) {
5060
+ const { path: repoPath, origin: origin11 } = command8;
5058
5061
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin11);
5059
5062
  }
5060
5063
  };
@@ -5154,8 +5157,8 @@ var ListFilesInDirectoryUseCase = class {
5154
5157
  constructor(listFiles = new ListFiles()) {
5155
5158
  this.listFiles = listFiles;
5156
5159
  }
5157
- async execute(command7) {
5158
- const { path: directoryPath, extensions, excludes = [] } = command7;
5160
+ async execute(command8) {
5161
+ const { path: directoryPath, extensions, excludes = [] } = command8;
5159
5162
  const files = await this.listFiles.listFilesInDirectory(
5160
5163
  directoryPath,
5161
5164
  extensions,
@@ -5240,7 +5243,7 @@ var LintFilesInDirectoryUseCase = class {
5240
5243
  }
5241
5244
  return pattern;
5242
5245
  }
5243
- async execute(command7) {
5246
+ async execute(command8) {
5244
5247
  const {
5245
5248
  path: userPath,
5246
5249
  draftMode,
@@ -5248,7 +5251,7 @@ var LintFilesInDirectoryUseCase = class {
5248
5251
  ruleId,
5249
5252
  language,
5250
5253
  diffMode
5251
- } = command7;
5254
+ } = command8;
5252
5255
  this.logger.debug(
5253
5256
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
5254
5257
  );
@@ -5567,8 +5570,8 @@ var LintFilesInDirectoryUseCase = class {
5567
5570
  return null;
5568
5571
  }
5569
5572
  }
5570
- async executeProgramsForFile(command7) {
5571
- const result = await this.services.linterExecutionUseCase.execute(command7);
5573
+ async executeProgramsForFile(command8) {
5574
+ const result = await this.services.linterExecutionUseCase.execute(command8);
5572
5575
  return result.violations;
5573
5576
  }
5574
5577
  extractExtensionFromFile(filePath) {
@@ -5625,8 +5628,8 @@ var LintFilesLocallyUseCase = class {
5625
5628
  }
5626
5629
  return pattern;
5627
5630
  }
5628
- async execute(command7) {
5629
- const { path: userPath, diffMode } = command7;
5631
+ async execute(command8) {
5632
+ const { path: userPath, diffMode } = command8;
5630
5633
  this.logger.debug(
5631
5634
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
5632
5635
  );
@@ -5868,8 +5871,8 @@ var LintFilesLocallyUseCase = class {
5868
5871
  return null;
5869
5872
  }
5870
5873
  }
5871
- async executeProgramsForFile(command7) {
5872
- const result = await this.services.linterExecutionUseCase.execute(command7);
5874
+ async executeProgramsForFile(command8) {
5875
+ const result = await this.services.linterExecutionUseCase.execute(command8);
5873
5876
  return result.violations;
5874
5877
  }
5875
5878
  extractExtensionFromFile(filePath) {
@@ -5957,7 +5960,7 @@ function decodeApiKey(apiKey) {
5957
5960
  var PackmindGateway = class {
5958
5961
  constructor(apiKey) {
5959
5962
  this.apiKey = apiKey;
5960
- this.getPullData = async (command7) => {
5963
+ this.getPullData = async (command8) => {
5961
5964
  const decodedApiKey = decodeApiKey(this.apiKey);
5962
5965
  if (!decodedApiKey.isValid) {
5963
5966
  if (decodedApiKey.error === "NOT_LOGGED_IN") {
@@ -5972,11 +5975,16 @@ var PackmindGateway = class {
5972
5975
  }
5973
5976
  const organizationId = jwtPayload.organization.id;
5974
5977
  const queryParams = new URLSearchParams();
5975
- if (command7.packagesSlugs && command7.packagesSlugs.length > 0) {
5976
- command7.packagesSlugs.forEach((slug) => {
5978
+ if (command8.packagesSlugs && command8.packagesSlugs.length > 0) {
5979
+ command8.packagesSlugs.forEach((slug) => {
5977
5980
  queryParams.append("packageSlug", slug);
5978
5981
  });
5979
5982
  }
5983
+ if (command8.previousPackagesSlugs && command8.previousPackagesSlugs.length > 0) {
5984
+ command8.previousPackagesSlugs.forEach((slug) => {
5985
+ queryParams.append("previousPackageSlug", slug);
5986
+ });
5987
+ }
5980
5988
  const url = `${host}/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`;
5981
5989
  try {
5982
5990
  const response = await fetch(url, {
@@ -6457,6 +6465,62 @@ var PackmindGateway = class {
6457
6465
  );
6458
6466
  }
6459
6467
  };
6468
+ this.notifyDistribution = async (params) => {
6469
+ const decodedApiKey = decodeApiKey(this.apiKey);
6470
+ if (!decodedApiKey.isValid) {
6471
+ if (decodedApiKey.error === "NOT_LOGGED_IN") {
6472
+ throw new NotLoggedInError();
6473
+ }
6474
+ throw new Error(`Invalid API key: ${decodedApiKey.error}`);
6475
+ }
6476
+ const { host, jwt } = decodedApiKey.payload;
6477
+ const jwtPayload = decodeJwt(jwt);
6478
+ if (!jwtPayload?.organization?.id) {
6479
+ throw new Error("Invalid API key: missing organizationId in JWT");
6480
+ }
6481
+ const organizationId = jwtPayload.organization.id;
6482
+ const url = `${host}/api/v0/organizations/${organizationId}/deployments`;
6483
+ const payload = {
6484
+ distributedPackages: params.distributedPackages,
6485
+ gitRemoteUrl: params.gitRemoteUrl,
6486
+ gitBranch: params.gitBranch,
6487
+ relativePath: params.relativePath
6488
+ };
6489
+ try {
6490
+ const response = await fetch(url, {
6491
+ method: "POST",
6492
+ headers: {
6493
+ "Content-Type": "application/json",
6494
+ Authorization: `Bearer ${this.apiKey}`
6495
+ },
6496
+ body: JSON.stringify(payload)
6497
+ });
6498
+ if (!response.ok) {
6499
+ let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
6500
+ try {
6501
+ const errorBody = await response.json();
6502
+ if (errorBody && errorBody.message) {
6503
+ errorMsg = `${errorBody.message}`;
6504
+ }
6505
+ } catch {
6506
+ }
6507
+ throw new Error(errorMsg);
6508
+ }
6509
+ const result = await response.json();
6510
+ return result;
6511
+ } catch (error) {
6512
+ const err = error;
6513
+ const code = err?.code || err?.cause?.code;
6514
+ if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
6515
+ throw new Error(
6516
+ `Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
6517
+ );
6518
+ }
6519
+ throw new Error(
6520
+ `Failed to notify distribution: Error: ${err?.message || JSON.stringify(error)}`
6521
+ );
6522
+ }
6523
+ };
6460
6524
  }
6461
6525
  };
6462
6526
 
@@ -8200,8 +8264,8 @@ var ExecuteLinterProgramsUseCase = class {
8200
8264
  this.linterAstAdapter = linterAstAdapter;
8201
8265
  this.logger = logger2;
8202
8266
  }
8203
- async execute(command7) {
8204
- const { filePath, fileContent, language, programs } = command7;
8267
+ async execute(command8) {
8268
+ const { filePath, fileContent, language, programs } = command8;
8205
8269
  if (programs.length === 0) {
8206
8270
  return {
8207
8271
  file: filePath,
@@ -9271,15 +9335,15 @@ ${sectionBlock}
9271
9335
  return result;
9272
9336
  }
9273
9337
 
9274
- // apps/cli/src/application/useCases/PullDataUseCase.ts
9338
+ // apps/cli/src/application/useCases/InstallPackagesUseCase.ts
9275
9339
  var fs4 = __toESM(require("fs/promises"));
9276
9340
  var path5 = __toESM(require("path"));
9277
- var PullDataUseCase = class {
9341
+ var InstallPackagesUseCase = class {
9278
9342
  constructor(packmindGateway) {
9279
9343
  this.packmindGateway = packmindGateway;
9280
9344
  }
9281
- async execute(command7) {
9282
- const baseDirectory = command7.baseDirectory || process.cwd();
9345
+ async execute(command8) {
9346
+ const baseDirectory = command8.baseDirectory || process.cwd();
9283
9347
  const result = {
9284
9348
  filesCreated: 0,
9285
9349
  filesUpdated: 0,
@@ -9289,7 +9353,8 @@ var PullDataUseCase = class {
9289
9353
  standardsCount: 0
9290
9354
  };
9291
9355
  const response = await this.packmindGateway.getPullData({
9292
- packagesSlugs: command7.packagesSlugs
9356
+ packagesSlugs: command8.packagesSlugs,
9357
+ previousPackagesSlugs: command8.previousPackagesSlugs
9293
9358
  });
9294
9359
  const uniqueFilesMap = /* @__PURE__ */ new Map();
9295
9360
  for (const file of response.fileUpdates.createOrUpdate) {
@@ -9324,7 +9389,7 @@ var PullDataUseCase = class {
9324
9389
  }
9325
9390
  } catch (error) {
9326
9391
  const errorMsg = error instanceof Error ? error.message : String(error);
9327
- result.errors.push(`Failed to pull data: ${errorMsg}`);
9392
+ result.errors.push(`Failed to install packages: ${errorMsg}`);
9328
9393
  }
9329
9394
  return result;
9330
9395
  }
@@ -9363,8 +9428,10 @@ var PullDataUseCase = class {
9363
9428
  commentMarker
9364
9429
  );
9365
9430
  }
9366
- await fs4.writeFile(fullPath, finalContent, "utf-8");
9367
- result.filesUpdated++;
9431
+ if (existingContent !== finalContent) {
9432
+ await fs4.writeFile(fullPath, finalContent, "utf-8");
9433
+ result.filesUpdated++;
9434
+ }
9368
9435
  } else {
9369
9436
  await fs4.writeFile(fullPath, content, "utf-8");
9370
9437
  result.filesCreated++;
@@ -9379,11 +9446,13 @@ var PullDataUseCase = class {
9379
9446
  currentContent,
9380
9447
  sections
9381
9448
  );
9382
- await fs4.writeFile(fullPath, mergedContent, "utf-8");
9383
- if (fileExists) {
9384
- result.filesUpdated++;
9385
- } else {
9386
- result.filesCreated++;
9449
+ if (currentContent !== mergedContent) {
9450
+ await fs4.writeFile(fullPath, mergedContent, "utf-8");
9451
+ if (fileExists) {
9452
+ result.filesUpdated++;
9453
+ } else {
9454
+ result.filesCreated++;
9455
+ }
9387
9456
  }
9388
9457
  }
9389
9458
  async deleteFile(baseDirectory, filePath, result) {
@@ -9464,8 +9533,8 @@ var GetPackageSummaryUseCase = class {
9464
9533
  constructor(gateway) {
9465
9534
  this.gateway = gateway;
9466
9535
  }
9467
- async execute(command7) {
9468
- return this.gateway.getPackageSummary(command7);
9536
+ async execute(command8) {
9537
+ return this.gateway.getPackageSummary(command8);
9469
9538
  }
9470
9539
  };
9471
9540
 
@@ -9743,8 +9812,8 @@ var LoginUseCase = class {
9743
9812
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
9744
9813
  };
9745
9814
  }
9746
- async execute(command7) {
9747
- const { host, code: providedCode } = command7;
9815
+ async execute(command8) {
9816
+ const { host, code: providedCode } = command8;
9748
9817
  let code;
9749
9818
  if (providedCode) {
9750
9819
  code = providedCode;
@@ -9841,8 +9910,8 @@ var SetupMcpUseCase = class {
9841
9910
  constructor(deps) {
9842
9911
  this.deps = deps;
9843
9912
  }
9844
- async execute(command7) {
9845
- const { agentTypes } = command7;
9913
+ async execute(command8) {
9914
+ const { agentTypes } = command8;
9846
9915
  const [tokenResult, urlResult] = await Promise.all([
9847
9916
  this.deps.gateway.getMcpToken({}),
9848
9917
  this.deps.gateway.getMcpUrl({})
@@ -9911,9 +9980,9 @@ var McpConfigService = class {
9911
9980
  return JSON.stringify(mcpConfig, null, 2);
9912
9981
  }
9913
9982
  installClaudeMcp(config) {
9914
- const command7 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
9983
+ const command8 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
9915
9984
  try {
9916
- (0, import_child_process2.execSync)(command7, { stdio: "pipe" });
9985
+ (0, import_child_process2.execSync)(command8, { stdio: "pipe" });
9917
9986
  return { success: true };
9918
9987
  } catch (error) {
9919
9988
  const execError = error;
@@ -10274,7 +10343,9 @@ var PackmindCliHexaFactory = class {
10274
10343
  this.repositories,
10275
10344
  this.logger
10276
10345
  ),
10277
- pullData: new PullDataUseCase(this.repositories.packmindGateway),
10346
+ installPackages: new InstallPackagesUseCase(
10347
+ this.repositories.packmindGateway
10348
+ ),
10278
10349
  listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
10279
10350
  getPackageBySlug: new GetPackageSummaryUseCase(
10280
10351
  this.repositories.packmindGateway
@@ -10311,44 +10382,29 @@ var PackmindCliHexa = class {
10311
10382
  this.logger.info("Destroying PackmindCliHexa");
10312
10383
  this.logger.info("PackmindCliHexa destroyed");
10313
10384
  }
10314
- async getGitRemoteUrl(command7) {
10315
- return this.hexa.useCases.getGitRemoteUrl.execute(command7);
10385
+ async getGitRemoteUrl(command8) {
10386
+ return this.hexa.useCases.getGitRemoteUrl.execute(command8);
10316
10387
  }
10317
- async executeSingleFileAst(command7) {
10318
- return this.hexa.useCases.executeSingleFileAst.execute(command7);
10388
+ async executeSingleFileAst(command8) {
10389
+ return this.hexa.useCases.executeSingleFileAst.execute(command8);
10319
10390
  }
10320
- async listFilesInDirectory(command7) {
10321
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command7);
10391
+ async listFilesInDirectory(command8) {
10392
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command8);
10322
10393
  }
10323
- async lintFilesInDirectory(command7) {
10324
- return this.hexa.useCases.lintFilesInDirectory.execute(command7);
10394
+ async lintFilesInDirectory(command8) {
10395
+ return this.hexa.useCases.lintFilesInDirectory.execute(command8);
10325
10396
  }
10326
- async lintFilesLocally(command7) {
10327
- return this.hexa.useCases.lintFilesLocally.execute(command7);
10397
+ async lintFilesLocally(command8) {
10398
+ return this.hexa.useCases.lintFilesLocally.execute(command8);
10328
10399
  }
10329
- async pullData(command7) {
10330
- return this.hexa.useCases.pullData.execute(command7);
10400
+ async installPackages(command8) {
10401
+ return this.hexa.useCases.installPackages.execute(command8);
10331
10402
  }
10332
- async listPackages(command7) {
10333
- return this.hexa.useCases.listPackages.execute(command7);
10403
+ async listPackages(command8) {
10404
+ return this.hexa.useCases.listPackages.execute(command8);
10334
10405
  }
10335
- async getPackageBySlug(command7) {
10336
- return this.hexa.useCases.getPackageBySlug.execute(command7);
10337
- }
10338
- async writeConfig(baseDirectory, packagesSlugs) {
10339
- const config = {
10340
- packages: packagesSlugs.reduce(
10341
- (acc, slug) => {
10342
- acc[slug] = "*";
10343
- return acc;
10344
- },
10345
- {}
10346
- )
10347
- };
10348
- await this.hexa.repositories.configFileRepository.writeConfig(
10349
- baseDirectory,
10350
- config
10351
- );
10406
+ async getPackageBySlug(command8) {
10407
+ return this.hexa.useCases.getPackageBySlug.execute(command8);
10352
10408
  }
10353
10409
  async readConfig(baseDirectory) {
10354
10410
  const config = await this.hexa.repositories.configFileRepository.readConfig(
@@ -10365,6 +10421,16 @@ var PackmindCliHexa = class {
10365
10421
  }
10366
10422
  return Object.keys(config.packages);
10367
10423
  }
10424
+ async writeConfig(baseDirectory, packagesSlugs) {
10425
+ const packages = {};
10426
+ packagesSlugs.forEach((slug) => {
10427
+ packages[slug] = "*";
10428
+ });
10429
+ await this.hexa.repositories.configFileRepository.writeConfig(
10430
+ baseDirectory,
10431
+ { packages }
10432
+ );
10433
+ }
10368
10434
  async readHierarchicalConfig(startDirectory, stopDirectory) {
10369
10435
  return this.hexa.repositories.configFileRepository.readHierarchicalConfig(
10370
10436
  startDirectory,
@@ -10376,6 +10442,12 @@ var PackmindCliHexa = class {
10376
10442
  directory
10377
10443
  );
10378
10444
  }
10445
+ async findAllConfigsInTree(startDirectory, stopDirectory) {
10446
+ return this.hexa.repositories.configFileRepository.findAllConfigsInTree(
10447
+ startDirectory,
10448
+ stopDirectory
10449
+ );
10450
+ }
10379
10451
  async getGitRepositoryRoot(directory) {
10380
10452
  return this.hexa.services.gitRemoteUrlService.getGitRepositoryRoot(
10381
10453
  directory
@@ -10386,17 +10458,26 @@ var PackmindCliHexa = class {
10386
10458
  directory
10387
10459
  );
10388
10460
  }
10389
- async login(command7) {
10390
- return this.hexa.useCases.login.execute(command7);
10461
+ async login(command8) {
10462
+ return this.hexa.useCases.login.execute(command8);
10463
+ }
10464
+ async logout(command8) {
10465
+ return this.hexa.useCases.logout.execute(command8);
10391
10466
  }
10392
- async logout(command7) {
10393
- return this.hexa.useCases.logout.execute(command7);
10467
+ async whoami(command8) {
10468
+ return this.hexa.useCases.whoami.execute(command8);
10394
10469
  }
10395
- async whoami(command7) {
10396
- return this.hexa.useCases.whoami.execute(command7);
10470
+ async setupMcp(command8) {
10471
+ return this.hexa.useCases.setupMcp.execute(command8);
10397
10472
  }
10398
- async setupMcp(command7) {
10399
- return this.hexa.useCases.setupMcp.execute(command7);
10473
+ getCurrentBranch(repoPath) {
10474
+ return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
10475
+ }
10476
+ getGitRemoteUrlFromPath(repoPath) {
10477
+ return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
10478
+ }
10479
+ async notifyDistribution(command8) {
10480
+ return this.hexa.repositories.packmindGateway.notifyDistribution(command8);
10400
10481
  }
10401
10482
  };
10402
10483
 
@@ -10707,264 +10788,770 @@ function extractWasmFiles() {
10707
10788
 
10708
10789
  // apps/cli/src/main.ts
10709
10790
  var import_dotenv = require("dotenv");
10710
- var fs10 = __toESM(require("fs"));
10791
+ var fs11 = __toESM(require("fs"));
10711
10792
  var path10 = __toESM(require("path"));
10712
10793
 
10713
- // apps/cli/src/infra/commands/PullCommand.ts
10794
+ // apps/cli/src/infra/commands/InstallCommand.ts
10714
10795
  var import_cmd_ts2 = __toESM(require_cjs());
10715
- var pullCommand = (0, import_cmd_ts2.command)({
10716
- name: "pull",
10717
- description: "Pull recipes and standards from specified packages and save them to the current directory",
10718
- args: {
10719
- list: (0, import_cmd_ts2.flag)({
10720
- long: "list",
10721
- description: "List available packages"
10722
- }),
10723
- show: (0, import_cmd_ts2.option)({
10724
- type: import_cmd_ts2.string,
10725
- long: "show",
10726
- description: "Show details of a specific package",
10727
- defaultValue: () => ""
10728
- }),
10729
- packagesSlugs: (0, import_cmd_ts2.restPositionals)({
10730
- type: import_cmd_ts2.string,
10731
- displayName: "packages",
10732
- description: "Package slugs to pull content from (e.g., backend frontend)"
10733
- })
10734
- },
10735
- handler: async ({ list, show, packagesSlugs }) => {
10736
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
10737
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
10738
- if (list) {
10739
- try {
10740
- console.log("Fetching available packages...\n");
10741
- const packages = await packmindCliHexa.listPackages({});
10742
- if (packages.length === 0) {
10743
- console.log("No packages found.");
10744
- process.exit(0);
10745
- }
10746
- const sortedPackages = [...packages].sort(
10747
- (a, b) => a.slug.localeCompare(b.slug)
10748
- );
10749
- console.log("Available packages:\n");
10750
- sortedPackages.forEach((pkg, index) => {
10751
- console.log(`- ${formatSlug(pkg.slug)}`);
10752
- console.log(` ${formatLabel("Name:")} ${pkg.name}`);
10753
- if (pkg.description) {
10754
- const descriptionLines = pkg.description.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
10755
- const [firstLine, ...restLines] = descriptionLines;
10756
- console.log(` ${formatLabel("Description:")} ${firstLine}`);
10757
- restLines.forEach((line) => {
10758
- console.log(` ${line}`);
10759
- });
10760
- }
10761
- if (index < sortedPackages.length - 1) {
10762
- console.log("");
10763
- }
10796
+
10797
+ // apps/cli/src/infra/commands/installPackagesHandler.ts
10798
+ async function listPackagesHandler(_args, deps) {
10799
+ const { packmindCliHexa, exit, log, error } = deps;
10800
+ try {
10801
+ log("Fetching available packages...\n");
10802
+ const packages = await packmindCliHexa.listPackages({});
10803
+ if (packages.length === 0) {
10804
+ log("No packages found.");
10805
+ exit(0);
10806
+ return;
10807
+ }
10808
+ const sortedPackages = [...packages].sort(
10809
+ (a, b) => a.slug.localeCompare(b.slug)
10810
+ );
10811
+ log("Available packages:\n");
10812
+ sortedPackages.forEach((pkg, index) => {
10813
+ log(`- ${formatSlug(pkg.slug)}`);
10814
+ log(` ${formatLabel("Name:")} ${pkg.name}`);
10815
+ if (pkg.description) {
10816
+ const descriptionLines = pkg.description.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
10817
+ const [firstLine, ...restLines] = descriptionLines;
10818
+ log(` ${formatLabel("Description:")} ${firstLine}`);
10819
+ restLines.forEach((line) => {
10820
+ log(` ${line}`);
10764
10821
  });
10765
- const exampleSlug = formatSlug(sortedPackages[0].slug);
10766
- console.log("\nHow to install a package:\n");
10767
- console.log(` $ packmind-cli install ${exampleSlug}`);
10768
- process.exit(0);
10769
- } catch (error) {
10770
- console.error("\n\u274C Failed to list packages:");
10771
- if (error instanceof Error) {
10772
- console.error(` ${error.message}`);
10773
- } else {
10774
- console.error(` ${String(error)}`);
10775
- }
10776
- process.exit(1);
10777
10822
  }
10823
+ if (index < sortedPackages.length - 1) {
10824
+ log("");
10825
+ }
10826
+ });
10827
+ const exampleSlug = formatSlug(sortedPackages[0].slug);
10828
+ log("\nHow to install a package:\n");
10829
+ log(` $ packmind-cli install ${exampleSlug}`);
10830
+ exit(0);
10831
+ } catch (err) {
10832
+ error("\n\u274C Failed to list packages:");
10833
+ if (err instanceof Error) {
10834
+ error(` ${err.message}`);
10835
+ } else {
10836
+ error(` ${String(err)}`);
10778
10837
  }
10779
- if (show) {
10780
- try {
10781
- console.log(`Fetching package details for '${show}'...
10838
+ exit(1);
10839
+ }
10840
+ }
10841
+ async function showPackageHandler(args2, deps) {
10842
+ const { packmindCliHexa, exit, log, error } = deps;
10843
+ const { slug } = args2;
10844
+ try {
10845
+ log(`Fetching package details for '${slug}'...
10782
10846
  `);
10783
- const pkg = await packmindCliHexa.getPackageBySlug({ slug: show });
10784
- console.log(`${pkg.name} (${pkg.slug}):
10847
+ const pkg = await packmindCliHexa.getPackageBySlug({ slug });
10848
+ log(`${pkg.name} (${pkg.slug}):
10785
10849
  `);
10786
- if (pkg.description) {
10787
- console.log(`${pkg.description}
10850
+ if (pkg.description) {
10851
+ log(`${pkg.description}
10788
10852
  `);
10853
+ }
10854
+ if (pkg.standards && pkg.standards.length > 0) {
10855
+ log("Standards:");
10856
+ pkg.standards.forEach((standard) => {
10857
+ if (standard.summary) {
10858
+ log(` - ${standard.name}: ${standard.summary}`);
10859
+ } else {
10860
+ log(` - ${standard.name}`);
10789
10861
  }
10790
- if (pkg.standards && pkg.standards.length > 0) {
10791
- console.log("Standards:");
10792
- pkg.standards.forEach((standard) => {
10793
- if (standard.summary) {
10794
- console.log(` - ${standard.name}: ${standard.summary}`);
10795
- } else {
10796
- console.log(` - ${standard.name}`);
10797
- }
10798
- });
10799
- console.log("");
10800
- }
10801
- if (pkg.recipes && pkg.recipes.length > 0) {
10802
- console.log("Recipes:");
10803
- pkg.recipes.forEach((recipe) => {
10804
- if (recipe.summary) {
10805
- console.log(` - ${recipe.name}: ${recipe.summary}`);
10806
- } else {
10807
- console.log(` - ${recipe.name}`);
10808
- }
10809
- });
10810
- console.log("");
10811
- }
10812
- process.exit(0);
10813
- } catch (error) {
10814
- console.error("\n\u274C Failed to fetch package details:");
10815
- if (error instanceof Error) {
10816
- console.error(` ${error.message}`);
10862
+ });
10863
+ log("");
10864
+ }
10865
+ if (pkg.recipes && pkg.recipes.length > 0) {
10866
+ log("Recipes:");
10867
+ pkg.recipes.forEach((recipe) => {
10868
+ if (recipe.summary) {
10869
+ log(` - ${recipe.name}: ${recipe.summary}`);
10817
10870
  } else {
10818
- console.error(` ${String(error)}`);
10871
+ log(` - ${recipe.name}`);
10819
10872
  }
10820
- process.exit(1);
10821
- }
10873
+ });
10874
+ log("");
10822
10875
  }
10823
- let configPackages;
10824
- let configExists = false;
10825
- try {
10826
- configPackages = await packmindCliHexa.readConfig(process.cwd());
10827
- configExists = configPackages.length > 0;
10828
- } catch (error) {
10829
- console.error("ERROR Failed to parse packmind.json");
10830
- if (error instanceof Error) {
10831
- console.error(`ERROR ${error.message}`);
10832
- } else {
10833
- console.error(`ERROR ${String(error)}`);
10876
+ exit(0);
10877
+ } catch (err) {
10878
+ error("\n\u274C Failed to fetch package details:");
10879
+ if (err instanceof Error) {
10880
+ error(` ${err.message}`);
10881
+ } else {
10882
+ error(` ${String(err)}`);
10883
+ }
10884
+ exit(1);
10885
+ }
10886
+ }
10887
+ function formatOverviewRow(configPath, packages, pathColumnWidth) {
10888
+ const paddedPath = configPath.padEnd(pathColumnWidth);
10889
+ if (packages.length === 0) {
10890
+ return `${paddedPath} <no packages>`;
10891
+ }
10892
+ const sortedPackages = [...packages].sort((a, b) => a.localeCompare(b));
10893
+ return `${paddedPath} ${sortedPackages.join(", ")}`;
10894
+ }
10895
+ function computeDisplayPath(targetPath) {
10896
+ const normalizedPath = targetPath === "/" ? "" : targetPath;
10897
+ return `.${normalizedPath}/packmind.json`;
10898
+ }
10899
+ async function statusHandler(_args, deps) {
10900
+ const { packmindCliHexa, exit, getCwd, log, error } = deps;
10901
+ const cwd = getCwd();
10902
+ try {
10903
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
10904
+ const basePath = gitRoot ?? cwd;
10905
+ const result = await packmindCliHexa.findAllConfigsInTree(cwd, basePath);
10906
+ if (!result.hasConfigs) {
10907
+ log("No packmind.json available in this workspace.");
10908
+ exit(0);
10909
+ return {
10910
+ configs: [],
10911
+ basePath
10912
+ };
10913
+ }
10914
+ const sortedConfigs = [...result.configs].sort(
10915
+ (a, b) => a.targetPath.localeCompare(b.targetPath)
10916
+ );
10917
+ const displayPaths = sortedConfigs.map(
10918
+ (config) => computeDisplayPath(config.targetPath)
10919
+ );
10920
+ const maxPathLength = Math.max(
10921
+ ...displayPaths.map((p) => p.length),
10922
+ "packmind.json".length
10923
+ );
10924
+ log("Workspace packages status\n");
10925
+ const header = "packmind.json".padEnd(maxPathLength) + " Packages";
10926
+ const separator = "-".repeat(header.length + 20);
10927
+ log(header);
10928
+ log(separator);
10929
+ const allPackages = /* @__PURE__ */ new Set();
10930
+ sortedConfigs.forEach((config, index) => {
10931
+ const displayPath = displayPaths[index];
10932
+ const packages = Object.keys(config.packages);
10933
+ packages.forEach((pkg) => allPackages.add(pkg));
10934
+ log(formatOverviewRow(displayPath, packages, maxPathLength));
10935
+ });
10936
+ const uniqueCount = allPackages.size;
10937
+ const packageWord = uniqueCount === 1 ? "package" : "packages";
10938
+ log(`
10939
+ ${uniqueCount} unique ${packageWord} currently installed.`);
10940
+ exit(0);
10941
+ return {
10942
+ configs: sortedConfigs,
10943
+ basePath
10944
+ };
10945
+ } catch (err) {
10946
+ error("\n\u274C Failed to get workspace overview:");
10947
+ if (err instanceof Error) {
10948
+ error(` ${err.message}`);
10949
+ } else {
10950
+ error(` ${String(err)}`);
10951
+ }
10952
+ exit(1);
10953
+ return {
10954
+ configs: [],
10955
+ basePath: cwd
10956
+ };
10957
+ }
10958
+ }
10959
+ async function executeInstallForDirectory(directory, deps) {
10960
+ const { packmindCliHexa, log } = deps;
10961
+ let configPackages;
10962
+ try {
10963
+ configPackages = await packmindCliHexa.readConfig(directory);
10964
+ } catch (err) {
10965
+ const errorMessage = err instanceof Error ? err.message : String(err);
10966
+ return {
10967
+ success: false,
10968
+ filesCreated: 0,
10969
+ filesUpdated: 0,
10970
+ filesDeleted: 0,
10971
+ notificationSent: false,
10972
+ errorMessage: `Failed to parse packmind.json: ${errorMessage}`
10973
+ };
10974
+ }
10975
+ if (configPackages.length === 0) {
10976
+ return {
10977
+ success: true,
10978
+ filesCreated: 0,
10979
+ filesUpdated: 0,
10980
+ filesDeleted: 0,
10981
+ notificationSent: false
10982
+ };
10983
+ }
10984
+ try {
10985
+ const packageCount = configPackages.length;
10986
+ const packageWord = packageCount === 1 ? "package" : "packages";
10987
+ log(
10988
+ ` Fetching ${packageCount} ${packageWord}: ${configPackages.join(", ")}...`
10989
+ );
10990
+ const result = await packmindCliHexa.installPackages({
10991
+ baseDirectory: directory,
10992
+ packagesSlugs: configPackages,
10993
+ previousPackagesSlugs: configPackages
10994
+ // Pass for consistency
10995
+ });
10996
+ log(
10997
+ ` Installing ${result.recipesCount} recipes and ${result.standardsCount} standards...`
10998
+ );
10999
+ log(
11000
+ ` added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
11001
+ );
11002
+ if (result.errors.length > 0) {
11003
+ return {
11004
+ success: false,
11005
+ filesCreated: result.filesCreated,
11006
+ filesUpdated: result.filesUpdated,
11007
+ filesDeleted: result.filesDeleted,
11008
+ notificationSent: false,
11009
+ errorMessage: result.errors.join(", ")
11010
+ };
11011
+ }
11012
+ let notificationSent = false;
11013
+ if (result.filesCreated > 0 || result.filesUpdated > 0) {
11014
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(directory);
11015
+ if (gitRoot) {
11016
+ try {
11017
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
11018
+ const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
11019
+ let relativePath = directory.startsWith(gitRoot) ? directory.slice(gitRoot.length) : "/";
11020
+ if (!relativePath.startsWith("/")) {
11021
+ relativePath = "/" + relativePath;
11022
+ }
11023
+ if (!relativePath.endsWith("/")) {
11024
+ relativePath = relativePath + "/";
11025
+ }
11026
+ await packmindCliHexa.notifyDistribution({
11027
+ distributedPackages: configPackages,
11028
+ gitRemoteUrl,
11029
+ gitBranch,
11030
+ relativePath
11031
+ });
11032
+ notificationSent = true;
11033
+ } catch {
11034
+ }
10834
11035
  }
10835
- console.error(
10836
- "\n\u{1F4A1} Please fix the packmind.json file or delete it to continue."
10837
- );
10838
- process.exit(1);
10839
11036
  }
10840
- const allPackages = [.../* @__PURE__ */ new Set([...configPackages, ...packagesSlugs])];
10841
- if (allPackages.length === 0) {
10842
- logWarningConsole("config packmind.json not found");
10843
- console.log(
10844
- "Usage: packmind-cli install <package-slug> [package-slug...]"
10845
- );
10846
- console.log(" packmind-cli install --list");
10847
- console.log("");
10848
- console.log("Examples:");
10849
- console.log(" packmind-cli install backend");
10850
- console.log(" packmind-cli install backend frontend");
10851
- console.log(" packmind-cli install --list # Show available packages");
10852
- console.log("");
10853
- console.log("Install recipes and standards from the specified packages.");
10854
- process.exit(0);
10855
- }
10856
- if (!configExists && packagesSlugs.length > 0) {
10857
- console.log("INFO initializing packmind.json");
11037
+ return {
11038
+ success: true,
11039
+ filesCreated: result.filesCreated,
11040
+ filesUpdated: result.filesUpdated,
11041
+ filesDeleted: result.filesDeleted,
11042
+ notificationSent
11043
+ };
11044
+ } catch (err) {
11045
+ const errorMessage = err instanceof Error ? err.message : String(err);
11046
+ return {
11047
+ success: false,
11048
+ filesCreated: 0,
11049
+ filesUpdated: 0,
11050
+ filesDeleted: 0,
11051
+ notificationSent: false,
11052
+ errorMessage
11053
+ };
11054
+ }
11055
+ }
11056
+ async function installPackagesHandler(args2, deps) {
11057
+ const { packmindCliHexa, exit, getCwd, log, error } = deps;
11058
+ const { packagesSlugs } = args2;
11059
+ const cwd = getCwd();
11060
+ let configPackages;
11061
+ let configExists = false;
11062
+ try {
11063
+ configPackages = await packmindCliHexa.readConfig(cwd);
11064
+ configExists = configPackages.length > 0;
11065
+ } catch (err) {
11066
+ error("ERROR Failed to parse packmind.json");
11067
+ if (err instanceof Error) {
11068
+ error(`ERROR ${err.message}`);
11069
+ } else {
11070
+ error(`ERROR ${String(err)}`);
10858
11071
  }
10859
- try {
10860
- const packageCount = allPackages.length;
10861
- const packageWord = packageCount === 1 ? "package" : "packages";
10862
- console.log(
10863
- `Fetching ${packageCount} ${packageWord}: ${allPackages.join(", ")}...`
10864
- );
10865
- const result = await packmindCliHexa.pullData({
10866
- baseDirectory: process.cwd(),
10867
- packagesSlugs: allPackages
10868
- });
10869
- console.log(
10870
- `Installing ${result.recipesCount} recipes and ${result.standardsCount} standards...`
10871
- );
10872
- console.log(
10873
- `
11072
+ error("\n\u{1F4A1} Please fix the packmind.json file or delete it to continue.");
11073
+ exit(1);
11074
+ return {
11075
+ filesCreated: 0,
11076
+ filesUpdated: 0,
11077
+ filesDeleted: 0,
11078
+ notificationSent: false
11079
+ };
11080
+ }
11081
+ const allPackages = [.../* @__PURE__ */ new Set([...configPackages, ...packagesSlugs])];
11082
+ if (allPackages.length === 0) {
11083
+ logWarningConsole("config packmind.json not found");
11084
+ log("Usage: packmind-cli install <package-slug> [package-slug...]");
11085
+ log(" packmind-cli install --list");
11086
+ log("");
11087
+ log("Examples:");
11088
+ log(" packmind-cli install backend");
11089
+ log(" packmind-cli install backend frontend");
11090
+ log(" packmind-cli install --list # Show available packages");
11091
+ log("");
11092
+ log("Install recipes and standards from the specified packages.");
11093
+ exit(0);
11094
+ return {
11095
+ filesCreated: 0,
11096
+ filesUpdated: 0,
11097
+ filesDeleted: 0,
11098
+ notificationSent: false
11099
+ };
11100
+ }
11101
+ if (!configExists && packagesSlugs.length > 0) {
11102
+ log("INFO initializing packmind.json");
11103
+ }
11104
+ try {
11105
+ const packageCount = allPackages.length;
11106
+ const packageWord = packageCount === 1 ? "package" : "packages";
11107
+ log(
11108
+ `Fetching ${packageCount} ${packageWord}: ${allPackages.join(", ")}...`
11109
+ );
11110
+ const result = await packmindCliHexa.installPackages({
11111
+ baseDirectory: cwd,
11112
+ packagesSlugs: allPackages,
11113
+ previousPackagesSlugs: configPackages
11114
+ // Pass previous config for change detection
11115
+ });
11116
+ log(
11117
+ `Installing ${result.recipesCount} recipes and ${result.standardsCount} standards...`
11118
+ );
11119
+ log(
11120
+ `
10874
11121
  added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
10875
- );
10876
- if (result.errors.length > 0) {
10877
- console.log("\n\u26A0\uFE0F Errors encountered:");
10878
- result.errors.forEach((error) => {
10879
- console.log(` - ${error}`);
10880
- });
10881
- process.exit(1);
11122
+ );
11123
+ if (result.errors.length > 0) {
11124
+ log("\n\u26A0\uFE0F Errors encountered:");
11125
+ result.errors.forEach((err) => {
11126
+ log(` - ${err}`);
11127
+ });
11128
+ exit(1);
11129
+ return {
11130
+ filesCreated: result.filesCreated,
11131
+ filesUpdated: result.filesUpdated,
11132
+ filesDeleted: result.filesDeleted,
11133
+ notificationSent: false
11134
+ };
11135
+ }
11136
+ let notificationSent = false;
11137
+ if (result.filesCreated > 0 || result.filesUpdated > 0) {
11138
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
11139
+ if (gitRoot) {
11140
+ try {
11141
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
11142
+ const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
11143
+ let relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
11144
+ if (!relativePath.startsWith("/")) {
11145
+ relativePath = "/" + relativePath;
11146
+ }
11147
+ if (!relativePath.endsWith("/")) {
11148
+ relativePath = relativePath + "/";
11149
+ }
11150
+ await packmindCliHexa.notifyDistribution({
11151
+ distributedPackages: allPackages,
11152
+ gitRemoteUrl,
11153
+ gitBranch,
11154
+ relativePath
11155
+ });
11156
+ log("Successfully notified Packmind of the new distribution");
11157
+ notificationSent = true;
11158
+ } catch {
11159
+ }
10882
11160
  }
10883
- await packmindCliHexa.writeConfig(process.cwd(), allPackages);
10884
- } catch (error) {
10885
- console.error("\n\u274C Failed to install content:");
10886
- if (error instanceof Error) {
10887
- const errorObj = error;
10888
- if (errorObj.statusCode === 404) {
10889
- console.error(` ${errorObj.message}`);
10890
- if (configExists && configPackages.length > 0) {
10891
- const missingPackages = allPackages.filter(
10892
- (pkg) => configPackages.includes(pkg)
11161
+ }
11162
+ return {
11163
+ filesCreated: result.filesCreated,
11164
+ filesUpdated: result.filesUpdated,
11165
+ filesDeleted: result.filesDeleted,
11166
+ notificationSent
11167
+ };
11168
+ } catch (err) {
11169
+ error("\n\u274C Failed to install content:");
11170
+ if (err instanceof Error) {
11171
+ const errorObj = err;
11172
+ if (errorObj.statusCode === 404) {
11173
+ error(` ${errorObj.message}`);
11174
+ if (configExists && configPackages.length > 0) {
11175
+ const missingPackages = allPackages.filter(
11176
+ (pkg) => configPackages.includes(pkg)
11177
+ );
11178
+ if (missingPackages.length > 0) {
11179
+ error(
11180
+ "\n\u{1F4A1} Either remove the following package(s) from packmind.json:"
10893
11181
  );
10894
- if (missingPackages.length > 0) {
10895
- console.error(
10896
- "\n\u{1F4A1} Either remove the following package(s) from packmind.json:"
10897
- );
10898
- missingPackages.forEach((pkg) => {
10899
- console.error(` "${pkg}"`);
10900
- });
10901
- console.error(" Or ensure that:");
10902
- console.error(
10903
- " - The package slug exists and is correctly spelled"
10904
- );
10905
- console.error(" - The package exists in your organization");
10906
- console.error(" - You have the correct API key configured");
10907
- } else {
10908
- console.error("\n\u{1F4A1} Troubleshooting tips:");
10909
- console.error(
10910
- " - Check if the package slug exists and is correctly spelled"
10911
- );
10912
- console.error(
10913
- " - Check that the package exists in your organization"
10914
- );
10915
- console.error(
10916
- " - Ensure you have the correct API key configured"
10917
- );
10918
- }
11182
+ missingPackages.forEach((pkg) => {
11183
+ error(` "${pkg}"`);
11184
+ });
11185
+ error(" Or ensure that:");
11186
+ error(" - The package slug exists and is correctly spelled");
11187
+ error(" - The package exists in your organization");
11188
+ error(" - You have the correct API key configured");
10919
11189
  } else {
10920
- console.error("\n\u{1F4A1} Troubleshooting tips:");
10921
- console.error(
11190
+ error("\n\u{1F4A1} Troubleshooting tips:");
11191
+ error(
10922
11192
  " - Check if the package slug exists and is correctly spelled"
10923
11193
  );
10924
- console.error(
10925
- " - Check that the package exists in your organization"
10926
- );
10927
- console.error(
10928
- " - Ensure you have the correct API key configured"
10929
- );
11194
+ error(" - Check that the package exists in your organization");
11195
+ error(" - Ensure you have the correct API key configured");
10930
11196
  }
10931
11197
  } else {
10932
- console.error(` ${errorObj.message}`);
10933
- const apiErrorObj = error;
10934
- if (apiErrorObj.response?.data?.message) {
10935
- console.error(`
10936
- Details: ${apiErrorObj.response.data.message}`);
10937
- }
10938
- console.error("\n\u{1F4A1} Troubleshooting tips:");
10939
- console.error(" - Verify that the package slugs are correct");
10940
- console.error(
10941
- " - Check that the packages exist in your organization"
11198
+ error("\n\u{1F4A1} Troubleshooting tips:");
11199
+ error(
11200
+ " - Check if the package slug exists and is correctly spelled"
10942
11201
  );
10943
- console.error(" - Ensure you have the correct API key configured");
11202
+ error(" - Check that the package exists in your organization");
11203
+ error(" - Ensure you have the correct API key configured");
10944
11204
  }
10945
11205
  } else {
10946
- console.error(` ${String(error)}`);
11206
+ error(` ${errorObj.message}`);
11207
+ const apiErrorObj = err;
11208
+ if (apiErrorObj.response?.data?.message) {
11209
+ error(`
11210
+ Details: ${apiErrorObj.response.data.message}`);
11211
+ }
11212
+ error("\n\u{1F4A1} Troubleshooting tips:");
11213
+ error(" - Verify that the package slugs are correct");
11214
+ error(" - Check that the packages exist in your organization");
11215
+ error(" - Ensure you have the correct API key configured");
10947
11216
  }
10948
- process.exit(1);
11217
+ } else {
11218
+ error(` ${String(err)}`);
10949
11219
  }
11220
+ exit(1);
11221
+ return {
11222
+ filesCreated: 0,
11223
+ filesUpdated: 0,
11224
+ filesDeleted: 0,
11225
+ notificationSent: false
11226
+ };
11227
+ }
11228
+ }
11229
+ async function uninstallPackagesHandler(args2, deps) {
11230
+ const { packmindCliHexa, exit, getCwd, log, error } = deps;
11231
+ const { packagesSlugs } = args2;
11232
+ const cwd = getCwd();
11233
+ if (!packagesSlugs || packagesSlugs.length === 0) {
11234
+ error("\u274C No packages specified.");
11235
+ log("");
11236
+ log("Usage: packmind-cli uninstall <package-slug> [package-slug...]");
11237
+ log(" packmind-cli remove <package-slug> [package-slug...]");
11238
+ log("");
11239
+ log("Examples:");
11240
+ log(" packmind-cli uninstall backend");
11241
+ log(" packmind-cli remove backend frontend");
11242
+ exit(1);
11243
+ return {
11244
+ filesDeleted: 0,
11245
+ packagesUninstalled: []
11246
+ };
11247
+ }
11248
+ let configPackages;
11249
+ try {
11250
+ configPackages = await packmindCliHexa.readConfig(cwd);
11251
+ } catch (err) {
11252
+ error("\u274C Failed to read packmind.json");
11253
+ if (err instanceof Error) {
11254
+ error(` ${err.message}`);
11255
+ } else {
11256
+ error(` ${String(err)}`);
11257
+ }
11258
+ error("\n\u{1F4A1} Please fix the packmind.json file or delete it to continue.");
11259
+ exit(1);
11260
+ return {
11261
+ filesDeleted: 0,
11262
+ packagesUninstalled: []
11263
+ };
11264
+ }
11265
+ if (configPackages.length === 0) {
11266
+ error("\u274C No packmind.json found in current directory.");
11267
+ log("");
11268
+ log("\u{1F4A1} There are no packages to uninstall.");
11269
+ log(" To install packages, run: packmind-cli install <package-slug>");
11270
+ exit(1);
11271
+ return {
11272
+ filesDeleted: 0,
11273
+ packagesUninstalled: []
11274
+ };
11275
+ }
11276
+ const packagesToUninstall = packagesSlugs.filter(
11277
+ (slug) => configPackages.includes(slug)
11278
+ );
11279
+ const notInstalledPackages = packagesSlugs.filter(
11280
+ (slug) => !configPackages.includes(slug)
11281
+ );
11282
+ if (notInstalledPackages.length > 0) {
11283
+ const packageWord = notInstalledPackages.length === 1 ? "package" : "packages";
11284
+ log(
11285
+ `\u26A0\uFE0F Warning: The following ${packageWord} ${notInstalledPackages.length === 1 ? "is" : "are"} not installed:`
11286
+ );
11287
+ notInstalledPackages.forEach((pkg) => {
11288
+ log(` - ${pkg}`);
11289
+ });
11290
+ log("");
11291
+ }
11292
+ if (packagesToUninstall.length === 0) {
11293
+ error("\u274C No packages to uninstall.");
11294
+ exit(1);
11295
+ return {
11296
+ filesDeleted: 0,
11297
+ packagesUninstalled: []
11298
+ };
11299
+ }
11300
+ try {
11301
+ const packageCount = packagesToUninstall.length;
11302
+ const packageWord = packageCount === 1 ? "package" : "packages";
11303
+ log(
11304
+ `Uninstalling ${packageCount} ${packageWord}: ${packagesToUninstall.join(", ")}...`
11305
+ );
11306
+ const remainingPackages = configPackages.filter(
11307
+ (pkg) => !packagesToUninstall.includes(pkg)
11308
+ );
11309
+ const result = await packmindCliHexa.installPackages({
11310
+ baseDirectory: cwd,
11311
+ packagesSlugs: remainingPackages,
11312
+ previousPackagesSlugs: configPackages
11313
+ });
11314
+ if (result.recipesCount > 0 || result.standardsCount > 0) {
11315
+ log(
11316
+ `Removing ${result.recipesCount} recipes and ${result.standardsCount} standards...`
11317
+ );
11318
+ }
11319
+ log(`
11320
+ removed ${result.filesDeleted} files`);
11321
+ if (result.errors.length > 0) {
11322
+ log("\n\u26A0\uFE0F Errors encountered:");
11323
+ result.errors.forEach((err) => {
11324
+ log(` - ${err}`);
11325
+ });
11326
+ exit(1);
11327
+ return {
11328
+ filesDeleted: result.filesDeleted,
11329
+ packagesUninstalled: packagesToUninstall
11330
+ };
11331
+ }
11332
+ await packmindCliHexa.writeConfig(cwd, remainingPackages);
11333
+ log("");
11334
+ if (packagesToUninstall.length === 1) {
11335
+ log(`\u2713 Package '${packagesToUninstall[0]}' has been uninstalled.`);
11336
+ } else {
11337
+ log(`\u2713 ${packagesToUninstall.length} packages have been uninstalled.`);
11338
+ }
11339
+ if (remainingPackages.length === 0) {
11340
+ log("");
11341
+ log("\u{1F4A1} All packages have been uninstalled.");
11342
+ log(" Your packmind.json still exists but contains no packages.");
11343
+ }
11344
+ return {
11345
+ filesDeleted: result.filesDeleted,
11346
+ packagesUninstalled: packagesToUninstall
11347
+ };
11348
+ } catch (err) {
11349
+ error("\n\u274C Failed to uninstall packages:");
11350
+ if (err instanceof Error) {
11351
+ error(` ${err.message}`);
11352
+ } else {
11353
+ error(` ${String(err)}`);
11354
+ }
11355
+ exit(1);
11356
+ return {
11357
+ filesDeleted: 0,
11358
+ packagesUninstalled: []
11359
+ };
11360
+ }
11361
+ }
11362
+ async function recursiveInstallHandler(_args, deps) {
11363
+ const { packmindCliHexa, exit, getCwd, log, error } = deps;
11364
+ const cwd = getCwd();
11365
+ const result = {
11366
+ directoriesProcessed: 0,
11367
+ totalFilesCreated: 0,
11368
+ totalFilesUpdated: 0,
11369
+ totalFilesDeleted: 0,
11370
+ totalNotifications: 0,
11371
+ errors: []
11372
+ };
11373
+ try {
11374
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
11375
+ const basePath = gitRoot ?? cwd;
11376
+ const allConfigs = await packmindCliHexa.findAllConfigsInTree(
11377
+ cwd,
11378
+ basePath
11379
+ );
11380
+ if (!allConfigs.hasConfigs) {
11381
+ log("No packmind.json files found in this repository.");
11382
+ log("");
11383
+ log("Usage: packmind-cli install -r");
11384
+ log("");
11385
+ log(
11386
+ "This command requires at least one packmind.json file in the repository."
11387
+ );
11388
+ log("Create a packmind.json file first:");
11389
+ log("");
11390
+ log(" packmind-cli install <package-slug>");
11391
+ exit(0);
11392
+ return result;
11393
+ }
11394
+ const sortedConfigs = [...allConfigs.configs].sort(
11395
+ (a, b) => a.targetPath.localeCompare(b.targetPath)
11396
+ );
11397
+ log(`Found ${sortedConfigs.length} packmind.json file(s) to process
11398
+ `);
11399
+ for (const config of sortedConfigs) {
11400
+ const displayPath = computeDisplayPath(config.targetPath);
11401
+ log(`Installing in ${displayPath}...`);
11402
+ const installResult = await executeInstallForDirectory(
11403
+ config.absoluteTargetPath,
11404
+ { packmindCliHexa, getCwd, log, error }
11405
+ );
11406
+ result.directoriesProcessed++;
11407
+ result.totalFilesCreated += installResult.filesCreated;
11408
+ result.totalFilesUpdated += installResult.filesUpdated;
11409
+ result.totalFilesDeleted += installResult.filesDeleted;
11410
+ if (installResult.notificationSent) {
11411
+ result.totalNotifications++;
11412
+ }
11413
+ if (!installResult.success && installResult.errorMessage) {
11414
+ result.errors.push({
11415
+ directory: displayPath,
11416
+ message: installResult.errorMessage
11417
+ });
11418
+ error(` Error: ${installResult.errorMessage}`);
11419
+ }
11420
+ log("");
11421
+ }
11422
+ const dirWord = result.directoriesProcessed === 1 ? "directory" : "directories";
11423
+ log(
11424
+ `Summary: ${result.directoriesProcessed} ${dirWord} processed, ${result.totalFilesCreated} files added, ${result.totalFilesUpdated} changed, ${result.totalFilesDeleted} removed`
11425
+ );
11426
+ if (result.totalNotifications > 0) {
11427
+ const distWord = result.totalNotifications === 1 ? "distribution" : "distributions";
11428
+ log(`Notified Packmind of ${result.totalNotifications} ${distWord}`);
11429
+ }
11430
+ if (result.errors.length > 0) {
11431
+ log("");
11432
+ log(`\u26A0\uFE0F ${result.errors.length} error(s) encountered:`);
11433
+ result.errors.forEach((err) => {
11434
+ log(` - ${err.directory}: ${err.message}`);
11435
+ });
11436
+ exit(1);
11437
+ return result;
11438
+ }
11439
+ exit(0);
11440
+ return result;
11441
+ } catch (err) {
11442
+ error("\n\u274C Failed to run recursive install:");
11443
+ if (err instanceof Error) {
11444
+ error(` ${err.message}`);
11445
+ } else {
11446
+ error(` ${String(err)}`);
11447
+ }
11448
+ exit(1);
11449
+ return result;
11450
+ }
11451
+ }
11452
+
11453
+ // apps/cli/src/infra/commands/InstallCommand.ts
11454
+ var installCommand = (0, import_cmd_ts2.command)({
11455
+ name: "install",
11456
+ description: "Install recipes and standards from specified packages and save them to the current directory",
11457
+ aliases: ["pull"],
11458
+ args: {
11459
+ list: (0, import_cmd_ts2.flag)({
11460
+ long: "list",
11461
+ description: "List available packages"
11462
+ }),
11463
+ status: (0, import_cmd_ts2.flag)({
11464
+ long: "status",
11465
+ description: "Show status of all packmind.json files and their packages in the workspace"
11466
+ }),
11467
+ recursive: (0, import_cmd_ts2.flag)({
11468
+ short: "r",
11469
+ long: "recursive",
11470
+ description: "Install packages for all packmind.json files found in the git repository"
11471
+ }),
11472
+ show: (0, import_cmd_ts2.option)({
11473
+ type: import_cmd_ts2.string,
11474
+ long: "show",
11475
+ description: "Show details of a specific package",
11476
+ defaultValue: () => ""
11477
+ }),
11478
+ packagesSlugs: (0, import_cmd_ts2.restPositionals)({
11479
+ type: import_cmd_ts2.string,
11480
+ displayName: "packages",
11481
+ description: "Package slugs to install (e.g., backend frontend)"
11482
+ })
11483
+ },
11484
+ handler: async ({ list, status, recursive, show, packagesSlugs }) => {
11485
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
11486
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
11487
+ const deps = {
11488
+ packmindCliHexa,
11489
+ exit: process.exit,
11490
+ getCwd: () => process.cwd(),
11491
+ log: console.log,
11492
+ error: console.error
11493
+ };
11494
+ if (list) {
11495
+ await listPackagesHandler({}, deps);
11496
+ return;
11497
+ }
11498
+ if (status) {
11499
+ await statusHandler({}, deps);
11500
+ return;
11501
+ }
11502
+ if (show) {
11503
+ await showPackageHandler({ slug: show }, deps);
11504
+ return;
11505
+ }
11506
+ if (recursive) {
11507
+ await recursiveInstallHandler({}, deps);
11508
+ return;
11509
+ }
11510
+ await installPackagesHandler({ packagesSlugs }, deps);
10950
11511
  }
10951
11512
  });
10952
11513
 
10953
- // apps/cli/src/infra/commands/LoginCommand.ts
11514
+ // apps/cli/src/infra/commands/UninstallCommand.ts
10954
11515
  var import_cmd_ts3 = __toESM(require_cjs());
11516
+ var uninstallCommand = (0, import_cmd_ts3.command)({
11517
+ name: "uninstall",
11518
+ description: "Uninstall packages and remove their recipes and standards from the current directory",
11519
+ args: {
11520
+ packagesSlugs: (0, import_cmd_ts3.restPositionals)({
11521
+ type: import_cmd_ts3.string,
11522
+ displayName: "packages",
11523
+ description: "Package slugs to uninstall (e.g., backend frontend)"
11524
+ })
11525
+ },
11526
+ handler: async ({ packagesSlugs }) => {
11527
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
11528
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
11529
+ const deps = {
11530
+ packmindCliHexa,
11531
+ exit: process.exit,
11532
+ getCwd: () => process.cwd(),
11533
+ log: console.log,
11534
+ error: console.error
11535
+ };
11536
+ await uninstallPackagesHandler({ packagesSlugs }, deps);
11537
+ }
11538
+ });
11539
+
11540
+ // apps/cli/src/infra/commands/LoginCommand.ts
11541
+ var import_cmd_ts4 = __toESM(require_cjs());
10955
11542
  var DEFAULT_HOST = "https://app.packmind.ai";
10956
- var loginCommand = (0, import_cmd_ts3.command)({
11543
+ var loginCommand = (0, import_cmd_ts4.command)({
10957
11544
  name: "login",
10958
11545
  description: "Authenticate with Packmind by logging in through the browser",
10959
11546
  args: {
10960
- host: (0, import_cmd_ts3.option)({
10961
- type: import_cmd_ts3.string,
11547
+ host: (0, import_cmd_ts4.option)({
11548
+ type: import_cmd_ts4.string,
10962
11549
  long: "host",
10963
11550
  description: "Packmind server URL (default: https://app.packmind.com)",
10964
11551
  defaultValue: () => DEFAULT_HOST
10965
11552
  }),
10966
- code: (0, import_cmd_ts3.option)({
10967
- type: (0, import_cmd_ts3.optional)(import_cmd_ts3.string),
11553
+ code: (0, import_cmd_ts4.option)({
11554
+ type: (0, import_cmd_ts4.optional)(import_cmd_ts4.string),
10968
11555
  long: "code",
10969
11556
  description: "Login code from the web interface (skips browser authentication)"
10970
11557
  })
@@ -11008,8 +11595,8 @@ Credentials saved to: ${result.credentialsPath}`);
11008
11595
  });
11009
11596
 
11010
11597
  // apps/cli/src/infra/commands/LogoutCommand.ts
11011
- var import_cmd_ts4 = __toESM(require_cjs());
11012
- var logoutCommand = (0, import_cmd_ts4.command)({
11598
+ var import_cmd_ts5 = __toESM(require_cjs());
11599
+ var logoutCommand = (0, import_cmd_ts5.command)({
11013
11600
  name: "logout",
11014
11601
  description: "Clear stored credentials and log out",
11015
11602
  args: {},
@@ -11046,7 +11633,7 @@ var logoutCommand = (0, import_cmd_ts4.command)({
11046
11633
  });
11047
11634
 
11048
11635
  // apps/cli/src/infra/commands/WhoamiCommand.ts
11049
- var import_cmd_ts5 = __toESM(require_cjs());
11636
+ var import_cmd_ts6 = __toESM(require_cjs());
11050
11637
  function formatExpiresAt(expiresAt) {
11051
11638
  const now = /* @__PURE__ */ new Date();
11052
11639
  if (expiresAt < now) {
@@ -11082,7 +11669,7 @@ Host: ${result.host}`);
11082
11669
  console.log("\nRun `packmind-cli login` to re-authenticate.");
11083
11670
  }
11084
11671
  }
11085
- var whoamiCommand = (0, import_cmd_ts5.command)({
11672
+ var whoamiCommand = (0, import_cmd_ts6.command)({
11086
11673
  name: "whoami",
11087
11674
  description: "Show current authentication status and credentials info",
11088
11675
  args: {},
@@ -11115,7 +11702,9 @@ Credentials are loaded from (in order of priority):`);
11115
11702
  });
11116
11703
 
11117
11704
  // apps/cli/src/infra/commands/SetupMcpCommand.ts
11118
- var import_cmd_ts6 = __toESM(require_cjs());
11705
+ var import_cmd_ts7 = __toESM(require_cjs());
11706
+ var fs10 = __toESM(require("fs"));
11707
+ var readline2 = __toESM(require("readline"));
11119
11708
  var inquirer = __toESM(require("inquirer"));
11120
11709
 
11121
11710
  // apps/cli/src/application/services/AgentDetectionService.ts
@@ -11151,10 +11740,10 @@ var AgentDetectionService = class {
11151
11740
  const vscodeDir = path9.join(this.projectDir, ".vscode");
11152
11741
  return fs9.existsSync(vscodeDir);
11153
11742
  }
11154
- isCommandAvailable(command7) {
11743
+ isCommandAvailable(command8) {
11155
11744
  try {
11156
11745
  const whichCommand = process.platform === "win32" ? "where" : "which";
11157
- (0, import_child_process3.execSync)(`${whichCommand} ${command7}`, { stdio: "pipe" });
11746
+ (0, import_child_process3.execSync)(`${whichCommand} ${command8}`, { stdio: "pipe" });
11158
11747
  return true;
11159
11748
  } catch {
11160
11749
  return false;
@@ -11185,12 +11774,44 @@ var ALL_AGENTS2 = [
11185
11774
  { type: "cursor", name: "Cursor" },
11186
11775
  { type: "vscode", name: "VS Code" }
11187
11776
  ];
11188
- var setupMcpCommand = (0, import_cmd_ts6.command)({
11777
+ async function promptAgentsWithReadline(choices) {
11778
+ const input = fs10.createReadStream("/dev/tty");
11779
+ const output = fs10.createWriteStream("/dev/tty");
11780
+ const rl = readline2.createInterface({
11781
+ input,
11782
+ output
11783
+ });
11784
+ output.write("Select agents to configure:\n");
11785
+ choices.forEach((choice, index) => {
11786
+ const marker = choice.checked ? "*" : " ";
11787
+ output.write(` ${index + 1}. [${marker}] ${choice.name}
11788
+ `);
11789
+ });
11790
+ output.write("\n");
11791
+ const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
11792
+ const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
11793
+ return new Promise((resolve6) => {
11794
+ rl.question(
11795
+ `Enter numbers separated by commas (default: ${defaultValue}): `,
11796
+ (answer) => {
11797
+ rl.close();
11798
+ input.destroy();
11799
+ output.destroy();
11800
+ const trimmed = answer.trim();
11801
+ const numbersStr = trimmed === "" ? defaultValue : trimmed;
11802
+ const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
11803
+ const selectedAgents = numbers.map((n) => choices[n - 1].value);
11804
+ resolve6(selectedAgents);
11805
+ }
11806
+ );
11807
+ });
11808
+ }
11809
+ var setupMcpCommand = (0, import_cmd_ts7.command)({
11189
11810
  name: "setup-mcp",
11190
11811
  description: "Configure MCP (Model Context Protocol) for AI coding agents",
11191
11812
  args: {
11192
- targets: (0, import_cmd_ts6.multioption)({
11193
- type: (0, import_cmd_ts6.array)(AgentArgType),
11813
+ targets: (0, import_cmd_ts7.multioption)({
11814
+ type: (0, import_cmd_ts7.array)(AgentArgType),
11194
11815
  long: "target",
11195
11816
  short: "t",
11196
11817
  description: "Target agent(s) to configure (copilot, cursor, or claude). Can be specified multiple times. If omitted, interactive mode is used."
@@ -11236,14 +11857,21 @@ Credentials are loaded from (in order of priority):`);
11236
11857
  value: agentInfo.type,
11237
11858
  checked: detectedTypes.has(agentInfo.type)
11238
11859
  }));
11239
- const { selectedAgents: promptedAgents } = await inquirer.default.prompt([
11240
- {
11241
- type: "checkbox",
11242
- name: "selectedAgents",
11243
- message: "Select agents to configure (use space to select):",
11244
- choices
11245
- }
11246
- ]);
11860
+ let promptedAgents;
11861
+ const useSimplePrompt = process.env.PACKMIND_SIMPLE_PROMPT === "1" || !process.stdin.isTTY;
11862
+ if (useSimplePrompt) {
11863
+ promptedAgents = await promptAgentsWithReadline(choices);
11864
+ } else {
11865
+ const result2 = await inquirer.default.prompt([
11866
+ {
11867
+ type: "checkbox",
11868
+ name: "selectedAgents",
11869
+ message: "Select agents to configure (use space to select):",
11870
+ choices
11871
+ }
11872
+ ]);
11873
+ promptedAgents = result2.selectedAgents;
11874
+ }
11247
11875
  if (promptedAgents.length === 0) {
11248
11876
  console.log("\nNo agents selected. Exiting.");
11249
11877
  process.exit(0);
@@ -11320,7 +11948,7 @@ function findEnvFile() {
11320
11948
  let parentDir = path10.dirname(searchDir);
11321
11949
  while (searchDir !== parentDir) {
11322
11950
  const envPath2 = path10.join(searchDir, ".env");
11323
- if (fs10.existsSync(envPath2)) {
11951
+ if (fs11.existsSync(envPath2)) {
11324
11952
  return envPath2;
11325
11953
  }
11326
11954
  if (searchDir === stopDir) {
@@ -11347,20 +11975,22 @@ if (args.includes("--version") || args.includes("-v")) {
11347
11975
  console.log(`packmind-cli version ${CLI_VERSION}`);
11348
11976
  process.exit(0);
11349
11977
  }
11350
- var app = (0, import_cmd_ts7.subcommands)({
11978
+ var app = (0, import_cmd_ts8.subcommands)({
11351
11979
  name: "packmind-cli",
11352
11980
  description: "Packmind CLI tool",
11353
11981
  cmds: {
11354
11982
  lint: lintCommand,
11355
- pull: pullCommand,
11356
- install: pullCommand,
11983
+ install: installCommand,
11984
+ uninstall: uninstallCommand,
11985
+ remove: uninstallCommand,
11986
+ // Alias for uninstall
11357
11987
  login: loginCommand,
11358
11988
  logout: logoutCommand,
11359
11989
  whoami: whoamiCommand,
11360
11990
  "setup-mcp": setupMcpCommand
11361
11991
  }
11362
11992
  });
11363
- (0, import_cmd_ts7.run)(app, args).catch((error) => {
11993
+ (0, import_cmd_ts8.run)(app, args).catch((error) => {
11364
11994
  logErrorConsole(error.message);
11365
11995
  process.exit(1);
11366
11996
  });