@packmind/cli 0.13.1 → 0.14.1

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 +1142 -290
  2. package/package.json +3 -2
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(string6, substring, replacer) {
375
- let index = string6.indexOf(substring);
374
+ function stringReplaceAll(string8, substring, replacer) {
375
+ let index = string8.indexOf(substring);
376
376
  if (index === -1) {
377
- return string6;
377
+ return string8;
378
378
  }
379
379
  const substringLength = substring.length;
380
380
  let endIndex = 0;
381
381
  let returnValue = "";
382
382
  do {
383
- returnValue += string6.slice(endIndex, index) + substring + replacer;
383
+ returnValue += string8.slice(endIndex, index) + substring + replacer;
384
384
  endIndex = index + substringLength;
385
- index = string6.indexOf(substring, endIndex);
385
+ index = string8.indexOf(substring, endIndex);
386
386
  } while (index !== -1);
387
- returnValue += string6.slice(endIndex);
387
+ returnValue += string8.slice(endIndex);
388
388
  return returnValue;
389
389
  }
390
- function stringEncaseCRLFWithFirstIndex(string6, prefix, postfix, index) {
390
+ function stringEncaseCRLFWithFirstIndex(string8, prefix, postfix, index) {
391
391
  let endIndex = 0;
392
392
  let returnValue = "";
393
393
  do {
394
- const gotCR = string6[index - 1] === "\r";
395
- returnValue += string6.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
394
+ const gotCR = string8[index - 1] === "\r";
395
+ returnValue += string8.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
396
  endIndex = index + 1;
397
- index = string6.indexOf("\n", endIndex);
397
+ index = string8.indexOf("\n", endIndex);
398
398
  } while (index !== -1);
399
- returnValue += string6.slice(endIndex);
399
+ returnValue += string8.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, string6) => {
559
- if (self.level <= 0 || !string6) {
560
- return self[IS_EMPTY] ? "" : string6;
558
+ applyStyle = (self, string8) => {
559
+ if (self.level <= 0 || !string8) {
560
+ return self[IS_EMPTY] ? "" : string8;
561
561
  }
562
562
  let styler = self[STYLER];
563
563
  if (styler === void 0) {
564
- return string6;
564
+ return string8;
565
565
  }
566
566
  const { openAll, closeAll } = styler;
567
- if (string6.includes("\x1B")) {
567
+ if (string8.includes("\x1B")) {
568
568
  while (styler !== void 0) {
569
- string6 = stringReplaceAll(string6, styler.close, styler.open);
569
+ string8 = stringReplaceAll(string8, styler.close, styler.open);
570
570
  styler = styler.parent;
571
571
  }
572
572
  }
573
- const lfIndex = string6.indexOf("\n");
573
+ const lfIndex = string8.indexOf("\n");
574
574
  if (lfIndex !== -1) {
575
- string6 = stringEncaseCRLFWithFirstIndex(string6, closeAll, openAll, lfIndex);
575
+ string8 = stringEncaseCRLFWithFirstIndex(string8, closeAll, openAll, lfIndex);
576
576
  }
577
- return openAll + string6 + closeAll;
577
+ return openAll + string8 + closeAll;
578
578
  };
579
579
  Object.defineProperties(createChalk.prototype, styles2);
580
580
  chalk = createChalk();
@@ -1255,7 +1255,7 @@ var require_positional = __commonJS({
1255
1255
  return mod && mod.__esModule ? mod : { "default": mod };
1256
1256
  };
1257
1257
  Object.defineProperty(exports2, "__esModule", { value: true });
1258
- exports2.positional = positional3;
1258
+ exports2.positional = positional5;
1259
1259
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1260
1260
  var Result = __importStar(require_Result());
1261
1261
  var types_1 = require_types();
@@ -1295,8 +1295,8 @@ var require_positional = __commonJS({
1295
1295
  var _a2;
1296
1296
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
1297
1297
  const defaultValueFn = (_a2 = config.defaultValue) !== null && _a2 !== void 0 ? _a2 : config.type.defaultValue;
1298
- const positional4 = positionals[0];
1299
- if (!positional4) {
1298
+ const positional6 = positionals[0];
1299
+ if (!positional6) {
1300
1300
  if (defaultValueFn) {
1301
1301
  return Result.ok(defaultValueFn());
1302
1302
  }
@@ -1309,13 +1309,13 @@ var require_positional = __commonJS({
1309
1309
  ]
1310
1310
  });
1311
1311
  }
1312
- visitedNodes.add(positional4);
1313
- const decoded = await Result.safeAsync(config.type.from(positional4.raw));
1312
+ visitedNodes.add(positional6);
1313
+ const decoded = await Result.safeAsync(config.type.from(positional6.raw));
1314
1314
  if (Result.isErr(decoded)) {
1315
1315
  return Result.err({
1316
1316
  errors: [
1317
1317
  {
1318
- nodes: [positional4],
1318
+ nodes: [positional6],
1319
1319
  message: decoded.error.message
1320
1320
  }
1321
1321
  ]
@@ -1325,7 +1325,7 @@ var require_positional = __commonJS({
1325
1325
  }
1326
1326
  };
1327
1327
  }
1328
- function positional3(config) {
1328
+ function positional5(config) {
1329
1329
  return fullPositional({
1330
1330
  type: types_1.string,
1331
1331
  ...config
@@ -1379,13 +1379,13 @@ var require_subcommands = __commonJS({
1379
1379
  return mod && mod.__esModule ? mod : { "default": mod };
1380
1380
  };
1381
1381
  Object.defineProperty(exports2, "__esModule", { value: true });
1382
- exports2.subcommands = subcommands3;
1382
+ exports2.subcommands = subcommands5;
1383
1383
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1384
1384
  var didyoumean_1 = __importDefault(require_didYouMean_1_2_1());
1385
1385
  var Result = __importStar(require_Result());
1386
1386
  var circuitbreaker_1 = require_circuitbreaker();
1387
1387
  var positional_1 = require_positional();
1388
- function subcommands3(config) {
1388
+ function subcommands5(config) {
1389
1389
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1390
1390
  const type = {
1391
1391
  async from(str) {
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
1578
1578
  __export(strip_ansi_exports, {
1579
1579
  default: () => stripAnsi
1580
1580
  });
1581
- function stripAnsi(string6) {
1582
- if (typeof string6 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string6}\``);
1581
+ function stripAnsi(string8) {
1582
+ if (typeof string8 !== "string") {
1583
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string8}\``);
1584
1584
  }
1585
- return string6.replace(regex, "");
1585
+ return string8.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 = command9;
1701
+ exports2.command = command12;
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 command9(config) {
1706
+ function command12(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, string6] of (0, utils_1.enumerate)(strings)) {
3088
- const chars = [...string6];
3087
+ for (const [stringIndex, string8] of (0, utils_1.enumerate)(strings)) {
3088
+ const chars = [...string8];
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 });
@@ -3241,14 +3241,14 @@ var require_restPositionals = __commonJS({
3241
3241
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
3242
3242
  const results = [];
3243
3243
  const errors = [];
3244
- for (const positional3 of positionals) {
3245
- visitedNodes.add(positional3);
3246
- const decoded = await Result.safeAsync(config.type.from(positional3.raw));
3244
+ for (const positional5 of positionals) {
3245
+ visitedNodes.add(positional5);
3246
+ const decoded = await Result.safeAsync(config.type.from(positional5.raw));
3247
3247
  if (Result.isOk(decoded)) {
3248
3248
  results.push(decoded.value);
3249
3249
  } else {
3250
3250
  errors.push({
3251
- nodes: [positional3],
3251
+ nodes: [positional5],
3252
3252
  message: decoded.error.message
3253
3253
  });
3254
3254
  }
@@ -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.13.1",
3855
+ version: "0.14.1",
3856
3856
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3857
  private: false,
3858
3858
  bin: {
@@ -3887,14 +3887,15 @@ var require_package = __commonJS({
3887
3887
  },
3888
3888
  dependencies: {
3889
3889
  "@types/inquirer": "^9.0.9",
3890
- inquirer: "^13.0.2"
3890
+ inquirer: "^13.0.2",
3891
+ zod: "^4.3.5"
3891
3892
  }
3892
3893
  };
3893
3894
  }
3894
3895
  });
3895
3896
 
3896
3897
  // apps/cli/src/main.ts
3897
- var import_cmd_ts10 = __toESM(require_cjs());
3898
+ var import_cmd_ts15 = __toESM(require_cjs());
3898
3899
 
3899
3900
  // apps/cli/src/infra/commands/LinterCommand.ts
3900
3901
  var import_cmd_ts = __toESM(require_cjs());
@@ -4048,6 +4049,13 @@ var AnonymousTrialAccountActivatedEvent = class extends UserEvent {
4048
4049
  }
4049
4050
  };
4050
4051
 
4052
+ // packages/types/src/accounts/events/OrganizationCreatedEvent.ts
4053
+ var OrganizationCreatedEvent = class extends UserEvent {
4054
+ static {
4055
+ this.eventName = "accounts.organization.created";
4056
+ }
4057
+ };
4058
+
4051
4059
  // packages/types/src/accounts/TrialActivationToken.ts
4052
4060
  var createTrialActivationTokenId = brandedIdFactory();
4053
4061
  var createTrialActivationToken = brandedIdFactory();
@@ -4735,6 +4743,17 @@ function createUserContextChangeEvent(userId, organizationId, changeType, role)
4735
4743
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
4736
4744
  };
4737
4745
  }
4746
+ function createDistributionStatusChangeEvent(distributionId, status, organizationId) {
4747
+ return {
4748
+ type: "DISTRIBUTION_STATUS_CHANGE",
4749
+ data: {
4750
+ distributionId,
4751
+ status,
4752
+ organizationId
4753
+ },
4754
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
4755
+ };
4756
+ }
4738
4757
 
4739
4758
  // apps/cli/src/application/useCases/ExecuteSingleFileAstUseCase.ts
4740
4759
  var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
@@ -4747,8 +4766,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4747
4766
  static {
4748
4767
  this.fallbackRuleContent = "adhoc-rule";
4749
4768
  }
4750
- async execute(command9) {
4751
- const { program, fileContent, language } = command9;
4769
+ async execute(command12) {
4770
+ const { program, fileContent, language } = command12;
4752
4771
  const result = await this.linterExecutionUseCase.execute({
4753
4772
  filePath: "cli-single-file",
4754
4773
  fileContent,
@@ -4798,30 +4817,30 @@ var GitService = class {
4798
4817
  this.gitRunner = gitRunner;
4799
4818
  this.logger = logger2;
4800
4819
  }
4801
- getGitRepositoryRoot(path12) {
4820
+ getGitRepositoryRoot(path13) {
4802
4821
  try {
4803
4822
  const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
4804
- cwd: path12
4823
+ cwd: path13
4805
4824
  });
4806
4825
  const gitRoot = stdout.trim();
4807
4826
  this.logger.debug("Resolved git repository root", {
4808
- inputPath: path12,
4827
+ inputPath: path13,
4809
4828
  gitRoot
4810
4829
  });
4811
4830
  return gitRoot;
4812
4831
  } catch (error) {
4813
4832
  if (error instanceof Error) {
4814
4833
  throw new Error(
4815
- `Failed to get Git repository root. The path '${path12}' does not appear to be inside a Git repository.
4834
+ `Failed to get Git repository root. The path '${path13}' does not appear to be inside a Git repository.
4816
4835
  ${error.message}`
4817
4836
  );
4818
4837
  }
4819
4838
  throw new Error("Failed to get Git repository root: Unknown error");
4820
4839
  }
4821
4840
  }
4822
- tryGetGitRepositoryRoot(path12) {
4841
+ tryGetGitRepositoryRoot(path13) {
4823
4842
  try {
4824
- return this.getGitRepositoryRoot(path12);
4843
+ return this.getGitRepositoryRoot(path13);
4825
4844
  } catch {
4826
4845
  return null;
4827
4846
  }
@@ -5128,8 +5147,8 @@ var GetGitRemoteUrlUseCase = class {
5128
5147
  constructor(gitRemoteUrlService = new GitService()) {
5129
5148
  this.gitRemoteUrlService = gitRemoteUrlService;
5130
5149
  }
5131
- async execute(command9) {
5132
- const { path: repoPath, origin: origin11 } = command9;
5150
+ async execute(command12) {
5151
+ const { path: repoPath, origin: origin11 } = command12;
5133
5152
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin11);
5134
5153
  }
5135
5154
  };
@@ -5137,6 +5156,42 @@ var GetGitRemoteUrlUseCase = class {
5137
5156
  // apps/cli/src/application/services/ListFiles.ts
5138
5157
  var fs = __toESM(require("fs/promises"));
5139
5158
  var path2 = __toESM(require("path"));
5159
+
5160
+ // apps/cli/src/infra/utils/consoleLogger.ts
5161
+ init_source();
5162
+ var CLI_PREFIX = "packmind-cli";
5163
+ function logConsole(message, logger2 = console) {
5164
+ logger2.log(message);
5165
+ }
5166
+ function logWarningConsole(message, logger2 = console) {
5167
+ logger2.warn(source_default.bgYellow.bold(CLI_PREFIX), source_default.yellow(message));
5168
+ }
5169
+ function logInfoConsole(message, logger2 = console) {
5170
+ logger2.log(source_default.bgBlue.bold(CLI_PREFIX), source_default.blue(message));
5171
+ }
5172
+ function logErrorConsole(message, logger2 = console) {
5173
+ logger2.error(source_default.bgRed.bold(CLI_PREFIX), source_default.red(message));
5174
+ }
5175
+ function logSuccessConsole(message, logger2 = console) {
5176
+ logger2.log(source_default.bgGreen.bold(CLI_PREFIX), source_default.green.bold(message));
5177
+ }
5178
+ function formatSlug(text) {
5179
+ return source_default.blue.bold(text);
5180
+ }
5181
+ function formatLabel(text) {
5182
+ return source_default.dim(text);
5183
+ }
5184
+ function formatError(text) {
5185
+ return source_default.red(text);
5186
+ }
5187
+ function formatBold(text) {
5188
+ return source_default.bold(text);
5189
+ }
5190
+ function formatFilePath(text) {
5191
+ return source_default.underline.gray(text);
5192
+ }
5193
+
5194
+ // apps/cli/src/application/services/ListFiles.ts
5140
5195
  var ListFiles = class {
5141
5196
  async listFilesInDirectory(directoryPath, extensions, excludes = [], skipHidden = true) {
5142
5197
  const results = [];
@@ -5184,7 +5239,7 @@ var ListFiles = class {
5184
5239
  }
5185
5240
  }
5186
5241
  } catch (error) {
5187
- console.error(`Error reading directory ${directoryPath}:`, error);
5242
+ logErrorConsole(`Error reading directory ${directoryPath}: ${error}`);
5188
5243
  }
5189
5244
  }
5190
5245
  shouldExcludePath(filePath, excludes) {
@@ -5218,7 +5273,7 @@ var ListFiles = class {
5218
5273
  try {
5219
5274
  return await fs.readFile(filePath, "utf-8");
5220
5275
  } catch (error) {
5221
- console.error(`Error reading file ${filePath}:`, error);
5276
+ logErrorConsole(`Error reading file ${filePath}: ${error}`);
5222
5277
  throw error;
5223
5278
  }
5224
5279
  }
@@ -5229,8 +5284,8 @@ var ListFilesInDirectoryUseCase = class {
5229
5284
  constructor(listFiles = new ListFiles()) {
5230
5285
  this.listFiles = listFiles;
5231
5286
  }
5232
- async execute(command9) {
5233
- const { path: directoryPath, extensions, excludes = [] } = command9;
5287
+ async execute(command12) {
5288
+ const { path: directoryPath, extensions, excludes = [] } = command12;
5234
5289
  const files = await this.listFiles.listFilesInDirectory(
5235
5290
  directoryPath,
5236
5291
  extensions,
@@ -5245,7 +5300,7 @@ var ListFilesInDirectoryUseCase = class {
5245
5300
  content
5246
5301
  });
5247
5302
  } catch (error) {
5248
- console.error(`Error reading file ${file.path}:`, error);
5303
+ logErrorConsole(`Error reading file ${file.path}: ${error}`);
5249
5304
  }
5250
5305
  }
5251
5306
  return filesWithContent;
@@ -5263,6 +5318,23 @@ var LintFilesInDirectoryUseCase = class {
5263
5318
  this.repositories = repositories;
5264
5319
  this.logger = logger2;
5265
5320
  }
5321
+ /**
5322
+ * Parses a scope string from the API into an array of patterns.
5323
+ * Handles comma-separated patterns and various edge cases.
5324
+ *
5325
+ * @param scope - The scope string from API (can be null, empty, or comma-separated)
5326
+ * @returns Array of scope patterns, or empty array if no valid scope
5327
+ */
5328
+ parseScopeString(scope) {
5329
+ if (!scope) {
5330
+ return [];
5331
+ }
5332
+ const trimmedScope = scope.trim();
5333
+ if (trimmedScope === "") {
5334
+ return [];
5335
+ }
5336
+ return trimmedScope.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0);
5337
+ }
5266
5338
  fileMatchesScope(filePath, scopePatterns) {
5267
5339
  if (!scopePatterns || scopePatterns.length === 0) {
5268
5340
  return true;
@@ -5315,7 +5387,7 @@ var LintFilesInDirectoryUseCase = class {
5315
5387
  }
5316
5388
  return pattern;
5317
5389
  }
5318
- async execute(command9) {
5390
+ async execute(command12) {
5319
5391
  const {
5320
5392
  path: userPath,
5321
5393
  draftMode,
@@ -5323,7 +5395,7 @@ var LintFilesInDirectoryUseCase = class {
5323
5395
  ruleId,
5324
5396
  language,
5325
5397
  diffMode
5326
- } = command9;
5398
+ } = command12;
5327
5399
  this.logger.debug(
5328
5400
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
5329
5401
  );
@@ -5432,7 +5504,7 @@ var LintFilesInDirectoryUseCase = class {
5432
5504
  {
5433
5505
  name: standardSlug,
5434
5506
  slug: standardSlug,
5435
- scope: draftProgramsResult.scope ? [draftProgramsResult.scope] : [],
5507
+ scope: this.parseScopeString(draftProgramsResult.scope),
5436
5508
  rules: [
5437
5509
  {
5438
5510
  content: draftProgramsResult.ruleContent || "Draft Rule",
@@ -5470,7 +5542,7 @@ var LintFilesInDirectoryUseCase = class {
5470
5542
  {
5471
5543
  name: standardSlug,
5472
5544
  slug: standardSlug,
5473
- scope: activeProgramsResult.scope ? [activeProgramsResult.scope] : [],
5545
+ scope: this.parseScopeString(activeProgramsResult.scope),
5474
5546
  rules: [
5475
5547
  {
5476
5548
  content: activeProgramsResult.ruleContent || "Active Rule",
@@ -5544,7 +5616,7 @@ var LintFilesInDirectoryUseCase = class {
5544
5616
  activeProgram.language
5545
5617
  );
5546
5618
  if (!programLanguage) {
5547
- console.error(
5619
+ logErrorConsole(
5548
5620
  `Unsupported language "${activeProgram.language}" for file ${file.path}`
5549
5621
  );
5550
5622
  continue;
@@ -5562,7 +5634,7 @@ var LintFilesInDirectoryUseCase = class {
5562
5634
  });
5563
5635
  programsByLanguage.set(programLanguage, programsForLanguage);
5564
5636
  } catch (error) {
5565
- console.error(
5637
+ logErrorConsole(
5566
5638
  `Error preparing program for file ${file.path}: ${error}`
5567
5639
  );
5568
5640
  }
@@ -5585,13 +5657,13 @@ var LintFilesInDirectoryUseCase = class {
5585
5657
  });
5586
5658
  fileViolations.push(...result);
5587
5659
  } catch (error) {
5588
- console.error(
5660
+ logErrorConsole(
5589
5661
  `Error executing programs for file ${file.path} (${language2}): ${error}`
5590
5662
  );
5591
5663
  }
5592
5664
  }
5593
5665
  } catch (error) {
5594
- console.error(
5666
+ logErrorConsole(
5595
5667
  `Error reading file content for ${file.path}: ${error}`
5596
5668
  );
5597
5669
  }
@@ -5642,8 +5714,8 @@ var LintFilesInDirectoryUseCase = class {
5642
5714
  return null;
5643
5715
  }
5644
5716
  }
5645
- async executeProgramsForFile(command9) {
5646
- const result = await this.services.linterExecutionUseCase.execute(command9);
5717
+ async executeProgramsForFile(command12) {
5718
+ const result = await this.services.linterExecutionUseCase.execute(command12);
5647
5719
  return result.violations;
5648
5720
  }
5649
5721
  extractExtensionFromFile(filePath) {
@@ -5700,8 +5772,8 @@ var LintFilesLocallyUseCase = class {
5700
5772
  }
5701
5773
  return pattern;
5702
5774
  }
5703
- async execute(command9) {
5704
- const { path: userPath, diffMode } = command9;
5775
+ async execute(command12) {
5776
+ const { path: userPath, diffMode } = command12;
5705
5777
  this.logger.debug(
5706
5778
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
5707
5779
  );
@@ -5836,7 +5908,7 @@ var LintFilesLocallyUseCase = class {
5836
5908
  });
5837
5909
  programsByLanguage.set(programLanguage, programsForLanguage);
5838
5910
  } catch (error) {
5839
- console.error(
5911
+ logErrorConsole(
5840
5912
  `Error preparing program for file ${file.path}: ${error}`
5841
5913
  );
5842
5914
  }
@@ -5860,13 +5932,13 @@ var LintFilesLocallyUseCase = class {
5860
5932
  });
5861
5933
  fileViolations.push(...result);
5862
5934
  } catch (error) {
5863
- console.error(
5935
+ logErrorConsole(
5864
5936
  `Error executing programs for file ${file.path} (${language}): ${error}`
5865
5937
  );
5866
5938
  }
5867
5939
  }
5868
5940
  } catch (error) {
5869
- console.error(
5941
+ logErrorConsole(
5870
5942
  `Error reading file content for ${file.path}: ${error}`
5871
5943
  );
5872
5944
  }
@@ -5943,8 +6015,8 @@ var LintFilesLocallyUseCase = class {
5943
6015
  return null;
5944
6016
  }
5945
6017
  }
5946
- async executeProgramsForFile(command9) {
5947
- const result = await this.services.linterExecutionUseCase.execute(command9);
6018
+ async executeProgramsForFile(command12) {
6019
+ const result = await this.services.linterExecutionUseCase.execute(command12);
5948
6020
  return result.violations;
5949
6021
  }
5950
6022
  extractExtensionFromFile(filePath) {
@@ -6110,6 +6182,93 @@ var NotLoggedInError = class extends Error {
6110
6182
  }
6111
6183
  };
6112
6184
 
6185
+ // apps/cli/src/infra/http/PackmindHttpClient.ts
6186
+ var PackmindHttpClient = class {
6187
+ constructor(apiKey) {
6188
+ this.apiKey = apiKey;
6189
+ }
6190
+ getAuthContext() {
6191
+ if (!this.apiKey) {
6192
+ throw new NotLoggedInError();
6193
+ }
6194
+ let decoded;
6195
+ try {
6196
+ const decodedString = Buffer.from(this.apiKey, "base64").toString(
6197
+ "utf-8"
6198
+ );
6199
+ decoded = JSON.parse(decodedString);
6200
+ } catch {
6201
+ throw new Error("Invalid API key");
6202
+ }
6203
+ const jwtPayload = this.decodeJwt(decoded.jwt);
6204
+ const organizationId = jwtPayload?.organization?.id;
6205
+ if (!organizationId) {
6206
+ throw new Error("Invalid API key: missing organizationId");
6207
+ }
6208
+ return {
6209
+ host: decoded.host,
6210
+ jwt: decoded.jwt,
6211
+ organizationId
6212
+ };
6213
+ }
6214
+ decodeJwt(jwt) {
6215
+ try {
6216
+ const parts = jwt.split(".");
6217
+ if (parts.length !== 3) {
6218
+ return null;
6219
+ }
6220
+ const payloadBase64 = parts[1];
6221
+ const payloadString = Buffer.from(payloadBase64, "base64").toString(
6222
+ "utf-8"
6223
+ );
6224
+ return JSON.parse(payloadString);
6225
+ } catch {
6226
+ return null;
6227
+ }
6228
+ }
6229
+ async request(path13, options = {}) {
6230
+ const { host } = this.getAuthContext();
6231
+ const { method = "GET", body } = options;
6232
+ const url = `${host}${path13}`;
6233
+ try {
6234
+ const response = await fetch(url, {
6235
+ method,
6236
+ headers: {
6237
+ "Content-Type": "application/json",
6238
+ Authorization: `Bearer ${this.apiKey}`
6239
+ },
6240
+ ...body ? { body: JSON.stringify(body) } : {}
6241
+ });
6242
+ if (!response.ok) {
6243
+ let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
6244
+ try {
6245
+ const errorBody = await response.json();
6246
+ if (errorBody?.message) {
6247
+ errorMsg = errorBody.message;
6248
+ }
6249
+ } catch {
6250
+ }
6251
+ const error = new Error(errorMsg);
6252
+ error.statusCode = response.status;
6253
+ throw error;
6254
+ }
6255
+ return response.json();
6256
+ } catch (error) {
6257
+ const err = error;
6258
+ if (err.statusCode) throw error;
6259
+ const code = err?.code || err?.cause?.code;
6260
+ 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"))) {
6261
+ throw new Error(
6262
+ `Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
6263
+ );
6264
+ }
6265
+ throw new Error(
6266
+ `Request failed: ${err?.message || JSON.stringify(error)}`
6267
+ );
6268
+ }
6269
+ }
6270
+ };
6271
+
6113
6272
  // apps/cli/src/infra/repositories/PackmindGateway.ts
6114
6273
  function decodeJwt(jwt) {
6115
6274
  try {
@@ -6166,7 +6325,7 @@ function decodeApiKey(apiKey) {
6166
6325
  var PackmindGateway = class {
6167
6326
  constructor(apiKey) {
6168
6327
  this.apiKey = apiKey;
6169
- this.getPullData = async (command9) => {
6328
+ this.getPullData = async (command12) => {
6170
6329
  const decodedApiKey = decodeApiKey(this.apiKey);
6171
6330
  if (!decodedApiKey.isValid) {
6172
6331
  if (decodedApiKey.error === "NOT_LOGGED_IN") {
@@ -6181,16 +6340,25 @@ var PackmindGateway = class {
6181
6340
  }
6182
6341
  const organizationId = jwtPayload.organization.id;
6183
6342
  const queryParams = new URLSearchParams();
6184
- if (command9.packagesSlugs && command9.packagesSlugs.length > 0) {
6185
- command9.packagesSlugs.forEach((slug) => {
6343
+ if (command12.packagesSlugs && command12.packagesSlugs.length > 0) {
6344
+ command12.packagesSlugs.forEach((slug) => {
6186
6345
  queryParams.append("packageSlug", slug);
6187
6346
  });
6188
6347
  }
6189
- if (command9.previousPackagesSlugs && command9.previousPackagesSlugs.length > 0) {
6190
- command9.previousPackagesSlugs.forEach((slug) => {
6348
+ if (command12.previousPackagesSlugs && command12.previousPackagesSlugs.length > 0) {
6349
+ command12.previousPackagesSlugs.forEach((slug) => {
6191
6350
  queryParams.append("previousPackageSlug", slug);
6192
6351
  });
6193
6352
  }
6353
+ if (command12.gitRemoteUrl) {
6354
+ queryParams.append("gitRemoteUrl", command12.gitRemoteUrl);
6355
+ }
6356
+ if (command12.gitBranch) {
6357
+ queryParams.append("gitBranch", command12.gitBranch);
6358
+ }
6359
+ if (command12.relativePath) {
6360
+ queryParams.append("relativePath", command12.relativePath);
6361
+ }
6194
6362
  const url = `${host}/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`;
6195
6363
  try {
6196
6364
  const response = await fetch(url, {
@@ -6727,7 +6895,7 @@ var PackmindGateway = class {
6727
6895
  );
6728
6896
  }
6729
6897
  };
6730
- this.uploadSkill = async (command9) => {
6898
+ this.uploadSkill = async (command12) => {
6731
6899
  const decodedApiKey = decodeApiKey(this.apiKey);
6732
6900
  if (!decodedApiKey.isValid) {
6733
6901
  if (decodedApiKey.error === "NOT_LOGGED_IN") {
@@ -6755,7 +6923,7 @@ var PackmindGateway = class {
6755
6923
  }
6756
6924
  const space = await spaceResponse.json();
6757
6925
  const spaceId = space.id;
6758
- const files = await readSkillDirectory(command9.skillPath);
6926
+ const files = await readSkillDirectory(command12.skillPath);
6759
6927
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
6760
6928
  throw new Error("SKILL.md not found in skill directory");
6761
6929
  }
@@ -6825,6 +6993,96 @@ var PackmindGateway = class {
6825
6993
  );
6826
6994
  }
6827
6995
  };
6996
+ this.getDefaultSkills = async () => {
6997
+ const decodedApiKey = decodeApiKey(this.apiKey);
6998
+ if (!decodedApiKey.isValid) {
6999
+ if (decodedApiKey.error === "NOT_LOGGED_IN") {
7000
+ throw new NotLoggedInError();
7001
+ }
7002
+ throw new Error(`Invalid API key: ${decodedApiKey.error}`);
7003
+ }
7004
+ const { host, jwt } = decodedApiKey.payload;
7005
+ const jwtPayload = decodeJwt(jwt);
7006
+ if (!jwtPayload?.organization?.id) {
7007
+ throw new Error("Invalid API key: missing organizationId in JWT");
7008
+ }
7009
+ const organizationId = jwtPayload.organization.id;
7010
+ const url = `${host}/api/v0/organizations/${organizationId}/skills/default`;
7011
+ try {
7012
+ const response = await fetch(url, {
7013
+ method: "GET",
7014
+ headers: {
7015
+ "Content-Type": "application/json",
7016
+ Authorization: `Bearer ${this.apiKey}`
7017
+ }
7018
+ });
7019
+ if (!response.ok) {
7020
+ let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
7021
+ try {
7022
+ const errorBody = await response.json();
7023
+ if (errorBody?.message) {
7024
+ errorMsg = errorBody.message;
7025
+ }
7026
+ } catch {
7027
+ }
7028
+ throw new Error(errorMsg);
7029
+ }
7030
+ const result = await response.json();
7031
+ return result;
7032
+ } catch (error) {
7033
+ const err = error;
7034
+ const code = err?.code || err?.cause?.code;
7035
+ 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"))) {
7036
+ throw new Error(
7037
+ `Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
7038
+ );
7039
+ }
7040
+ throw new Error(
7041
+ `Failed to get default skills: Error: ${err?.message || JSON.stringify(error)}`
7042
+ );
7043
+ }
7044
+ };
7045
+ this.getGlobalSpace = async () => {
7046
+ const { organizationId } = this.httpClient.getAuthContext();
7047
+ return this.httpClient.request(
7048
+ `/api/v0/organizations/${organizationId}/spaces/global`
7049
+ );
7050
+ };
7051
+ this.createStandardInSpace = async (spaceId, data) => {
7052
+ const { organizationId } = this.httpClient.getAuthContext();
7053
+ return this.httpClient.request(
7054
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards`,
7055
+ { method: "POST", body: data }
7056
+ );
7057
+ };
7058
+ this.getRulesForStandard = async (spaceId, standardId) => {
7059
+ const { organizationId } = this.httpClient.getAuthContext();
7060
+ return this.httpClient.request(
7061
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards/${standardId}/rules`
7062
+ );
7063
+ };
7064
+ this.addExampleToRule = async (spaceId, standardId, ruleId, example) => {
7065
+ const { organizationId } = this.httpClient.getAuthContext();
7066
+ await this.httpClient.request(
7067
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards/${standardId}/rules/${ruleId}/examples`,
7068
+ {
7069
+ method: "POST",
7070
+ body: {
7071
+ lang: example.language,
7072
+ positive: example.positive,
7073
+ negative: example.negative
7074
+ }
7075
+ }
7076
+ );
7077
+ };
7078
+ this.createCommand = async (spaceId, data) => {
7079
+ const { organizationId } = this.httpClient.getAuthContext();
7080
+ return this.httpClient.request(
7081
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/recipes`,
7082
+ { method: "POST", body: data }
7083
+ );
7084
+ };
7085
+ this.httpClient = new PackmindHttpClient(apiKey);
6828
7086
  }
6829
7087
  };
6830
7088
 
@@ -8568,8 +8826,8 @@ var ExecuteLinterProgramsUseCase = class {
8568
8826
  this.linterAstAdapter = linterAstAdapter;
8569
8827
  this.logger = logger2;
8570
8828
  }
8571
- async execute(command9) {
8572
- const { filePath, fileContent, language, programs } = command9;
8829
+ async execute(command12) {
8830
+ const { filePath, fileContent, language, programs } = command12;
8573
8831
  if (programs.length === 0) {
8574
8832
  return {
8575
8833
  file: filePath,
@@ -9573,6 +9831,51 @@ var SSEEventPublisher = class _SSEEventPublisher {
9573
9831
  throw error;
9574
9832
  }
9575
9833
  }
9834
+ /**
9835
+ * Publish a distribution status change event for cache invalidation
9836
+ * This triggers React Query to refetch the distribution data when status changes
9837
+ */
9838
+ static async publishDistributionStatusChangeEvent(distributionId, status, organizationId) {
9839
+ _SSEEventPublisher.logger.info(
9840
+ "Publishing distribution status change event",
9841
+ {
9842
+ distributionId,
9843
+ status,
9844
+ organizationId
9845
+ }
9846
+ );
9847
+ try {
9848
+ const event = createDistributionStatusChangeEvent(
9849
+ distributionId,
9850
+ status,
9851
+ organizationId
9852
+ );
9853
+ await _SSEEventPublisher.publishEvent(
9854
+ "DISTRIBUTION_STATUS_CHANGE",
9855
+ [organizationId],
9856
+ event
9857
+ );
9858
+ _SSEEventPublisher.logger.debug(
9859
+ "Successfully published distribution status change event",
9860
+ {
9861
+ distributionId,
9862
+ status,
9863
+ organizationId
9864
+ }
9865
+ );
9866
+ } catch (error) {
9867
+ _SSEEventPublisher.logger.error(
9868
+ "Failed to publish distribution status change event",
9869
+ {
9870
+ distributionId,
9871
+ status,
9872
+ organizationId,
9873
+ error: error instanceof Error ? error.message : String(error)
9874
+ }
9875
+ );
9876
+ throw error;
9877
+ }
9878
+ }
9576
9879
  /**
9577
9880
  * Generic method to publish any SSE event type to Redis pub/sub
9578
9881
  */
@@ -9657,6 +9960,11 @@ ${sectionBlock}
9657
9960
  return result;
9658
9961
  }
9659
9962
 
9963
+ // packages/node-utils/src/text/urlUtils.ts
9964
+ function removeTrailingSlash(url) {
9965
+ return url.endsWith("/") ? url.slice(0, -1) : url;
9966
+ }
9967
+
9660
9968
  // apps/cli/src/application/useCases/InstallPackagesUseCase.ts
9661
9969
  var fs5 = __toESM(require("fs/promises"));
9662
9970
  var path6 = __toESM(require("path"));
@@ -9664,8 +9972,8 @@ var InstallPackagesUseCase = class {
9664
9972
  constructor(packmindGateway) {
9665
9973
  this.packmindGateway = packmindGateway;
9666
9974
  }
9667
- async execute(command9) {
9668
- const baseDirectory = command9.baseDirectory || process.cwd();
9975
+ async execute(command12) {
9976
+ const baseDirectory = command12.baseDirectory || process.cwd();
9669
9977
  const result = {
9670
9978
  filesCreated: 0,
9671
9979
  filesUpdated: 0,
@@ -9673,11 +9981,15 @@ var InstallPackagesUseCase = class {
9673
9981
  errors: [],
9674
9982
  recipesCount: 0,
9675
9983
  standardsCount: 0,
9676
- skillsCount: 0
9984
+ skillsCount: 0,
9985
+ skillDirectoriesDeleted: 0
9677
9986
  };
9678
9987
  const response = await this.packmindGateway.getPullData({
9679
- packagesSlugs: command9.packagesSlugs,
9680
- previousPackagesSlugs: command9.previousPackagesSlugs
9988
+ packagesSlugs: command12.packagesSlugs,
9989
+ previousPackagesSlugs: command12.previousPackagesSlugs,
9990
+ gitRemoteUrl: command12.gitRemoteUrl,
9991
+ gitBranch: command12.gitBranch,
9992
+ relativePath: command12.relativePath
9681
9993
  });
9682
9994
  const uniqueFilesMap = /* @__PURE__ */ new Map();
9683
9995
  for (const file of response.fileUpdates.createOrUpdate) {
@@ -9694,6 +10006,10 @@ var InstallPackagesUseCase = class {
9694
10006
  }
9695
10007
  }
9696
10008
  try {
10009
+ result.skillDirectoriesDeleted = await this.deleteSkillFolders(
10010
+ baseDirectory,
10011
+ response.skillFolders
10012
+ );
9697
10013
  for (const file of uniqueFiles) {
9698
10014
  try {
9699
10015
  await this.createOrUpdateFile(baseDirectory, file, result);
@@ -9871,6 +10187,98 @@ ${endMarker}`;
9871
10187
  escapeRegex(str) {
9872
10188
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9873
10189
  }
10190
+ /**
10191
+ * Deletes all skill folders before recreating them with fresh content.
10192
+ * Returns the count of files that were actually deleted.
10193
+ */
10194
+ async deleteSkillFolders(baseDirectory, folders) {
10195
+ let deletedFilesCount = 0;
10196
+ for (const folder of folders) {
10197
+ const fullPath = path6.join(baseDirectory, folder);
10198
+ try {
10199
+ await fs5.access(fullPath);
10200
+ const fileCount = await this.countFilesInDirectory(fullPath);
10201
+ await fs5.rm(fullPath, { recursive: true, force: true });
10202
+ deletedFilesCount += fileCount;
10203
+ } catch {
10204
+ }
10205
+ }
10206
+ return deletedFilesCount;
10207
+ }
10208
+ /**
10209
+ * Recursively counts all files in a directory.
10210
+ */
10211
+ async countFilesInDirectory(dirPath) {
10212
+ let count = 0;
10213
+ const entries = await fs5.readdir(dirPath, { withFileTypes: true });
10214
+ for (const entry of entries) {
10215
+ const entryPath = path6.join(dirPath, entry.name);
10216
+ if (entry.isDirectory()) {
10217
+ count += await this.countFilesInDirectory(entryPath);
10218
+ } else {
10219
+ count++;
10220
+ }
10221
+ }
10222
+ return count;
10223
+ }
10224
+ };
10225
+
10226
+ // apps/cli/src/application/useCases/InstallDefaultSkillsUseCase.ts
10227
+ var fs6 = __toESM(require("fs/promises"));
10228
+ var path7 = __toESM(require("path"));
10229
+ var InstallDefaultSkillsUseCase = class {
10230
+ constructor(packmindGateway) {
10231
+ this.packmindGateway = packmindGateway;
10232
+ }
10233
+ async execute(command12) {
10234
+ const baseDirectory = command12.baseDirectory || process.cwd();
10235
+ const result = {
10236
+ filesCreated: 0,
10237
+ filesUpdated: 0,
10238
+ errors: []
10239
+ };
10240
+ const response = await this.packmindGateway.getDefaultSkills({});
10241
+ try {
10242
+ for (const file of response.fileUpdates.createOrUpdate) {
10243
+ try {
10244
+ await this.createOrUpdateFile(baseDirectory, file, result);
10245
+ } catch (error) {
10246
+ const errorMsg = error instanceof Error ? error.message : String(error);
10247
+ result.errors.push(
10248
+ `Failed to create/update ${file.path}: ${errorMsg}`
10249
+ );
10250
+ }
10251
+ }
10252
+ } catch (error) {
10253
+ const errorMsg = error instanceof Error ? error.message : String(error);
10254
+ result.errors.push(`Failed to install default skills: ${errorMsg}`);
10255
+ }
10256
+ return result;
10257
+ }
10258
+ async createOrUpdateFile(baseDirectory, file, result) {
10259
+ const fullPath = path7.join(baseDirectory, file.path);
10260
+ const directory = path7.dirname(fullPath);
10261
+ await fs6.mkdir(directory, { recursive: true });
10262
+ const fileExists = await this.fileExists(fullPath);
10263
+ if (fileExists) {
10264
+ const existingContent = await fs6.readFile(fullPath, "utf-8");
10265
+ if (existingContent !== file.content) {
10266
+ await fs6.writeFile(fullPath, file.content, "utf-8");
10267
+ result.filesUpdated++;
10268
+ }
10269
+ } else {
10270
+ await fs6.writeFile(fullPath, file.content, "utf-8");
10271
+ result.filesCreated++;
10272
+ }
10273
+ }
10274
+ async fileExists(filePath) {
10275
+ try {
10276
+ await fs6.access(filePath);
10277
+ return true;
10278
+ } catch {
10279
+ return false;
10280
+ }
10281
+ }
9874
10282
  };
9875
10283
 
9876
10284
  // apps/cli/src/application/useCases/ListPackagesUseCase.ts
@@ -9888,8 +10296,8 @@ var GetPackageSummaryUseCase = class {
9888
10296
  constructor(gateway) {
9889
10297
  this.gateway = gateway;
9890
10298
  }
9891
- async execute(command9) {
9892
- return this.gateway.getPackageSummary(command9);
10299
+ async execute(command12) {
10300
+ return this.gateway.getPackageSummary(command12);
9893
10301
  }
9894
10302
  };
9895
10303
 
@@ -9949,13 +10357,13 @@ var EnvCredentialsProvider = class {
9949
10357
  };
9950
10358
 
9951
10359
  // apps/cli/src/infra/utils/credentials/FileCredentialsProvider.ts
9952
- var fs6 = __toESM(require("fs"));
9953
- var path7 = __toESM(require("path"));
10360
+ var fs7 = __toESM(require("fs"));
10361
+ var path8 = __toESM(require("path"));
9954
10362
  var os2 = __toESM(require("os"));
9955
10363
  var CREDENTIALS_DIR = ".packmind";
9956
10364
  var CREDENTIALS_FILE = "credentials.json";
9957
10365
  function getCredentialsPath() {
9958
- return path7.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
10366
+ return path8.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
9959
10367
  }
9960
10368
  var FileCredentialsProvider = class {
9961
10369
  getSourceName() {
@@ -9963,11 +10371,11 @@ var FileCredentialsProvider = class {
9963
10371
  }
9964
10372
  hasCredentials() {
9965
10373
  const credentialsPath = getCredentialsPath();
9966
- if (!fs6.existsSync(credentialsPath)) {
10374
+ if (!fs7.existsSync(credentialsPath)) {
9967
10375
  return false;
9968
10376
  }
9969
10377
  try {
9970
- const content = fs6.readFileSync(credentialsPath, "utf-8");
10378
+ const content = fs7.readFileSync(credentialsPath, "utf-8");
9971
10379
  const credentials = JSON.parse(content);
9972
10380
  return !!credentials.apiKey;
9973
10381
  } catch {
@@ -9976,11 +10384,11 @@ var FileCredentialsProvider = class {
9976
10384
  }
9977
10385
  loadCredentials() {
9978
10386
  const credentialsPath = getCredentialsPath();
9979
- if (!fs6.existsSync(credentialsPath)) {
10387
+ if (!fs7.existsSync(credentialsPath)) {
9980
10388
  return null;
9981
10389
  }
9982
10390
  try {
9983
- const content = fs6.readFileSync(credentialsPath, "utf-8");
10391
+ const content = fs7.readFileSync(credentialsPath, "utf-8");
9984
10392
  const credentials = JSON.parse(content);
9985
10393
  if (!credentials.apiKey) {
9986
10394
  return null;
@@ -10003,13 +10411,13 @@ var FileCredentialsProvider = class {
10003
10411
  }
10004
10412
  };
10005
10413
  function saveCredentials(apiKey) {
10006
- const credentialsDir = path7.join(os2.homedir(), CREDENTIALS_DIR);
10007
- if (!fs6.existsSync(credentialsDir)) {
10008
- fs6.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
10414
+ const credentialsDir = path8.join(os2.homedir(), CREDENTIALS_DIR);
10415
+ if (!fs7.existsSync(credentialsDir)) {
10416
+ fs7.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
10009
10417
  }
10010
10418
  const credentialsPath = getCredentialsPath();
10011
10419
  const credentials = { apiKey };
10012
- fs6.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
10420
+ fs7.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
10013
10421
  mode: 384
10014
10422
  });
10015
10423
  }
@@ -10088,7 +10496,8 @@ async function defaultPromptForCode() {
10088
10496
  });
10089
10497
  }
10090
10498
  async function defaultExchangeCodeForApiKey(code, host) {
10091
- const url = `${host}/api/v0/auth/cli-login-exchange`;
10499
+ const normalizedHost = removeTrailingSlash(host);
10500
+ const url = `${normalizedHost}/api/v0/auth/cli-login-exchange`;
10092
10501
  const response = await fetch(url, {
10093
10502
  method: "POST",
10094
10503
  headers: {
@@ -10167,15 +10576,16 @@ var LoginUseCase = class {
10167
10576
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
10168
10577
  };
10169
10578
  }
10170
- async execute(command9) {
10171
- const { host, code: providedCode } = command9;
10579
+ async execute(command12) {
10580
+ const { host, code: providedCode } = command12;
10172
10581
  let code;
10173
10582
  if (providedCode) {
10174
10583
  code = providedCode;
10175
10584
  } else {
10176
10585
  const callbackPromise = this.deps.startCallbackServer();
10177
10586
  const callbackUrl = `http://127.0.0.1:${CALLBACK_PORT}`;
10178
- const loginUrl = `${host}/cli-login?callback_url=${encodeURIComponent(callbackUrl)}`;
10587
+ const normalizedHost = removeTrailingSlash(host);
10588
+ const loginUrl = `${normalizedHost}/cli-login?callback_url=${encodeURIComponent(callbackUrl)}`;
10179
10589
  try {
10180
10590
  await this.deps.openBrowser(loginUrl);
10181
10591
  } catch {
@@ -10199,14 +10609,14 @@ var LoginUseCase = class {
10199
10609
  };
10200
10610
 
10201
10611
  // apps/cli/src/application/useCases/LogoutUseCase.ts
10202
- var fs7 = __toESM(require("fs"));
10612
+ var fs8 = __toESM(require("fs"));
10203
10613
  var ENV_VAR_NAME2 = "PACKMIND_API_KEY_V3";
10204
10614
  var LogoutUseCase = class {
10205
10615
  constructor(deps) {
10206
10616
  this.deps = {
10207
10617
  getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
10208
- fileExists: deps?.fileExists ?? ((path12) => fs7.existsSync(path12)),
10209
- deleteFile: deps?.deleteFile ?? ((path12) => fs7.unlinkSync(path12)),
10618
+ fileExists: deps?.fileExists ?? ((path13) => fs8.existsSync(path13)),
10619
+ deleteFile: deps?.deleteFile ?? ((path13) => fs8.unlinkSync(path13)),
10210
10620
  hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
10211
10621
  };
10212
10622
  }
@@ -10266,8 +10676,8 @@ var SetupMcpUseCase = class {
10266
10676
  constructor(deps) {
10267
10677
  this.deps = deps;
10268
10678
  }
10269
- async execute(command9) {
10270
- const { agentTypes } = command9;
10679
+ async execute(command12) {
10680
+ const { agentTypes } = command12;
10271
10681
  const [tokenResult, urlResult] = await Promise.all([
10272
10682
  this.deps.gateway.getMcpToken({}),
10273
10683
  this.deps.gateway.getMcpUrl({})
@@ -10302,8 +10712,8 @@ var SetupMcpUseCase = class {
10302
10712
  };
10303
10713
 
10304
10714
  // apps/cli/src/application/services/McpConfigService.ts
10305
- var fs8 = __toESM(require("fs"));
10306
- var path8 = __toESM(require("path"));
10715
+ var fs9 = __toESM(require("fs"));
10716
+ var path9 = __toESM(require("path"));
10307
10717
  var os3 = __toESM(require("os"));
10308
10718
  var import_child_process2 = require("child_process");
10309
10719
  var McpConfigService = class {
@@ -10338,9 +10748,9 @@ var McpConfigService = class {
10338
10748
  return JSON.stringify(mcpConfig, null, 2);
10339
10749
  }
10340
10750
  installClaudeMcp(config) {
10341
- const command9 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10751
+ const command12 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10342
10752
  try {
10343
- (0, import_child_process2.execSync)(command9, { stdio: "pipe" });
10753
+ (0, import_child_process2.execSync)(command12, { stdio: "pipe" });
10344
10754
  return { success: true };
10345
10755
  } catch (error) {
10346
10756
  const execError = error;
@@ -10350,11 +10760,11 @@ var McpConfigService = class {
10350
10760
  }
10351
10761
  installCursorMcp(config) {
10352
10762
  try {
10353
- const cursorConfigPath = path8.join(os3.homedir(), ".cursor", "mcp.json");
10763
+ const cursorConfigPath = path9.join(os3.homedir(), ".cursor", "mcp.json");
10354
10764
  const cursorConfig = this.buildCursorConfig(config);
10355
10765
  const existingConfig = this.readExistingJsonConfig(cursorConfigPath);
10356
10766
  const mergedConfig = this.mergeConfig(existingConfig, cursorConfig);
10357
- fs8.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
10767
+ fs9.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
10358
10768
  return { success: true };
10359
10769
  } catch (error) {
10360
10770
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10363,15 +10773,15 @@ var McpConfigService = class {
10363
10773
  }
10364
10774
  installVSCodeMcp(config) {
10365
10775
  try {
10366
- const vscodeDir = path8.join(this.projectDir, ".vscode");
10367
- if (!fs8.existsSync(vscodeDir)) {
10368
- fs8.mkdirSync(vscodeDir, { recursive: true });
10776
+ const vscodeDir = path9.join(this.projectDir, ".vscode");
10777
+ if (!fs9.existsSync(vscodeDir)) {
10778
+ fs9.mkdirSync(vscodeDir, { recursive: true });
10369
10779
  }
10370
- const vscodeConfigPath = path8.join(vscodeDir, "mcp.json");
10780
+ const vscodeConfigPath = path9.join(vscodeDir, "mcp.json");
10371
10781
  const vscodeConfig = this.buildVSCodeConfig(config);
10372
10782
  const existingConfig = this.readExistingJsonConfig(vscodeConfigPath);
10373
10783
  const mergedConfig = this.mergeVSCodeConfig(existingConfig, vscodeConfig);
10374
- fs8.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
10784
+ fs9.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
10375
10785
  return { success: true };
10376
10786
  } catch (error) {
10377
10787
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10380,14 +10790,14 @@ var McpConfigService = class {
10380
10790
  }
10381
10791
  installContinueMcp(config) {
10382
10792
  try {
10383
- const continueDir = path8.join(this.projectDir, ".continue");
10384
- const mcpServersDir = path8.join(continueDir, "mcpServers");
10385
- if (!fs8.existsSync(mcpServersDir)) {
10386
- fs8.mkdirSync(mcpServersDir, { recursive: true });
10793
+ const continueDir = path9.join(this.projectDir, ".continue");
10794
+ const mcpServersDir = path9.join(continueDir, "mcpServers");
10795
+ if (!fs9.existsSync(mcpServersDir)) {
10796
+ fs9.mkdirSync(mcpServersDir, { recursive: true });
10387
10797
  }
10388
- const continueConfigPath = path8.join(mcpServersDir, "packmind.yaml");
10798
+ const continueConfigPath = path9.join(mcpServersDir, "packmind.yaml");
10389
10799
  const continueConfig = this.buildContinueYamlConfig(config);
10390
- fs8.writeFileSync(continueConfigPath, continueConfig);
10800
+ fs9.writeFileSync(continueConfigPath, continueConfig);
10391
10801
  return { success: true };
10392
10802
  } catch (error) {
10393
10803
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10435,8 +10845,8 @@ mcpServers:
10435
10845
  }
10436
10846
  readExistingJsonConfig(filePath) {
10437
10847
  try {
10438
- if (fs8.existsSync(filePath)) {
10439
- const content = fs8.readFileSync(filePath, "utf-8");
10848
+ if (fs9.existsSync(filePath)) {
10849
+ const content = fs9.readFileSync(filePath, "utf-8");
10440
10850
  return JSON.parse(content);
10441
10851
  }
10442
10852
  } catch {
@@ -10469,41 +10879,8 @@ mcpServers:
10469
10879
  };
10470
10880
 
10471
10881
  // apps/cli/src/infra/repositories/ConfigFileRepository.ts
10472
- var fs9 = __toESM(require("fs/promises"));
10473
- var path9 = __toESM(require("path"));
10474
-
10475
- // apps/cli/src/infra/utils/consoleLogger.ts
10476
- init_source();
10477
- var CLI_PREFIX = "packmind-cli";
10478
- function logWarningConsole(message) {
10479
- console.warn(source_default.bgYellow.bold(CLI_PREFIX), source_default.yellow(message));
10480
- }
10481
- function logInfoConsole(message) {
10482
- console.log(source_default.bgBlue.bold(CLI_PREFIX), source_default.blue(message));
10483
- }
10484
- function logErrorConsole(message) {
10485
- console.error(source_default.bgRed.bold(CLI_PREFIX), source_default.red(message));
10486
- }
10487
- function logSuccessConsole(message) {
10488
- console.log(source_default.bgGreen.bold(CLI_PREFIX), source_default.green.bold(message));
10489
- }
10490
- function formatSlug(text) {
10491
- return source_default.blue.bold(text);
10492
- }
10493
- function formatLabel(text) {
10494
- return source_default.dim(text);
10495
- }
10496
- function formatError(text) {
10497
- return source_default.red(text);
10498
- }
10499
- function formatBold(text) {
10500
- return source_default.bold(text);
10501
- }
10502
- function formatFilePath(text) {
10503
- return source_default.underline.gray(text);
10504
- }
10505
-
10506
- // apps/cli/src/infra/repositories/ConfigFileRepository.ts
10882
+ var fs10 = __toESM(require("fs/promises"));
10883
+ var path10 = __toESM(require("path"));
10507
10884
  var ConfigFileRepository = class {
10508
10885
  constructor() {
10509
10886
  this.CONFIG_FILENAME = "packmind.json";
@@ -10518,23 +10895,23 @@ var ConfigFileRepository = class {
10518
10895
  ];
10519
10896
  }
10520
10897
  async writeConfig(baseDirectory, config) {
10521
- const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10898
+ const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
10522
10899
  const configContent = JSON.stringify(config, null, 2) + "\n";
10523
- await fs9.writeFile(configPath, configContent, "utf-8");
10900
+ await fs10.writeFile(configPath, configContent, "utf-8");
10524
10901
  }
10525
10902
  async configExists(baseDirectory) {
10526
- const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10903
+ const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
10527
10904
  try {
10528
- await fs9.access(configPath);
10905
+ await fs10.access(configPath);
10529
10906
  return true;
10530
10907
  } catch {
10531
10908
  return false;
10532
10909
  }
10533
10910
  }
10534
10911
  async readConfig(baseDirectory) {
10535
- const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10912
+ const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
10536
10913
  try {
10537
- const configContent = await fs9.readFile(configPath, "utf-8");
10914
+ const configContent = await fs10.readFile(configPath, "utf-8");
10538
10915
  const config = JSON.parse(configContent);
10539
10916
  if (!config.packages || typeof config.packages !== "object") {
10540
10917
  throw new Error(
@@ -10561,12 +10938,12 @@ var ConfigFileRepository = class {
10561
10938
  * @returns Array of directory paths that contain a packmind.json file
10562
10939
  */
10563
10940
  async findDescendantConfigs(directory) {
10564
- const normalizedDir = normalizePath(path9.resolve(directory));
10941
+ const normalizedDir = normalizePath(path10.resolve(directory));
10565
10942
  const results = [];
10566
10943
  const searchRecursively = async (currentDir) => {
10567
10944
  let entries;
10568
10945
  try {
10569
- entries = await fs9.readdir(currentDir, { withFileTypes: true });
10946
+ entries = await fs10.readdir(currentDir, { withFileTypes: true });
10570
10947
  } catch {
10571
10948
  return;
10572
10949
  }
@@ -10577,7 +10954,7 @@ var ConfigFileRepository = class {
10577
10954
  if (this.EXCLUDED_DIRECTORIES.includes(entry.name)) {
10578
10955
  continue;
10579
10956
  }
10580
- const entryPath = normalizePath(path9.join(currentDir, entry.name));
10957
+ const entryPath = normalizePath(path10.join(currentDir, entry.name));
10581
10958
  const config = await this.readConfig(entryPath);
10582
10959
  if (config) {
10583
10960
  results.push(entryPath);
@@ -10599,21 +10976,21 @@ var ConfigFileRepository = class {
10599
10976
  async readHierarchicalConfig(startDirectory, stopDirectory) {
10600
10977
  const configs = [];
10601
10978
  const configPaths = [];
10602
- const normalizedStart = normalizePath(path9.resolve(startDirectory));
10603
- const normalizedStop = stopDirectory ? normalizePath(path9.resolve(stopDirectory)) : null;
10979
+ const normalizedStart = normalizePath(path10.resolve(startDirectory));
10980
+ const normalizedStop = stopDirectory ? normalizePath(path10.resolve(stopDirectory)) : null;
10604
10981
  let currentDir = normalizedStart;
10605
10982
  while (true) {
10606
10983
  const config = await this.readConfig(currentDir);
10607
10984
  if (config) {
10608
10985
  configs.push(config);
10609
10986
  configPaths.push(
10610
- normalizePath(path9.join(currentDir, this.CONFIG_FILENAME))
10987
+ normalizePath(path10.join(currentDir, this.CONFIG_FILENAME))
10611
10988
  );
10612
10989
  }
10613
10990
  if (normalizedStop !== null && currentDir === normalizedStop) {
10614
10991
  break;
10615
10992
  }
10616
- const parentDir = normalizePath(path9.dirname(currentDir));
10993
+ const parentDir = normalizePath(path10.dirname(currentDir));
10617
10994
  if (parentDir === currentDir) {
10618
10995
  break;
10619
10996
  }
@@ -10642,8 +11019,8 @@ var ConfigFileRepository = class {
10642
11019
  * @returns All configs found with their target paths
10643
11020
  */
10644
11021
  async findAllConfigsInTree(startDirectory, stopDirectory) {
10645
- const normalizedStart = normalizePath(path9.resolve(startDirectory));
10646
- const normalizedStop = stopDirectory ? normalizePath(path9.resolve(stopDirectory)) : null;
11022
+ const normalizedStart = normalizePath(path10.resolve(startDirectory));
11023
+ const normalizedStop = stopDirectory ? normalizePath(path10.resolve(stopDirectory)) : null;
10647
11024
  const basePath = normalizedStop ?? normalizedStart;
10648
11025
  const configsMap = /* @__PURE__ */ new Map();
10649
11026
  let currentDir = normalizedStart;
@@ -10660,7 +11037,7 @@ var ConfigFileRepository = class {
10660
11037
  if (normalizedStop !== null && currentDir === normalizedStop) {
10661
11038
  break;
10662
11039
  }
10663
- const parentDir = normalizePath(path9.dirname(currentDir));
11040
+ const parentDir = normalizePath(path10.dirname(currentDir));
10664
11041
  if (parentDir === currentDir) {
10665
11042
  break;
10666
11043
  }
@@ -10747,6 +11124,9 @@ var PackmindCliHexaFactory = class {
10747
11124
  installPackages: new InstallPackagesUseCase(
10748
11125
  this.repositories.packmindGateway
10749
11126
  ),
11127
+ installDefaultSkills: new InstallDefaultSkillsUseCase(
11128
+ this.repositories.packmindGateway
11129
+ ),
10750
11130
  listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
10751
11131
  getPackageBySlug: new GetPackageSummaryUseCase(
10752
11132
  this.repositories.packmindGateway
@@ -10783,29 +11163,29 @@ var PackmindCliHexa = class {
10783
11163
  this.logger.info("Destroying PackmindCliHexa");
10784
11164
  this.logger.info("PackmindCliHexa destroyed");
10785
11165
  }
10786
- async getGitRemoteUrl(command9) {
10787
- return this.hexa.useCases.getGitRemoteUrl.execute(command9);
11166
+ async getGitRemoteUrl(command12) {
11167
+ return this.hexa.useCases.getGitRemoteUrl.execute(command12);
10788
11168
  }
10789
- async executeSingleFileAst(command9) {
10790
- return this.hexa.useCases.executeSingleFileAst.execute(command9);
11169
+ async executeSingleFileAst(command12) {
11170
+ return this.hexa.useCases.executeSingleFileAst.execute(command12);
10791
11171
  }
10792
- async listFilesInDirectory(command9) {
10793
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command9);
11172
+ async listFilesInDirectory(command12) {
11173
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command12);
10794
11174
  }
10795
- async lintFilesInDirectory(command9) {
10796
- return this.hexa.useCases.lintFilesInDirectory.execute(command9);
11175
+ async lintFilesInDirectory(command12) {
11176
+ return this.hexa.useCases.lintFilesInDirectory.execute(command12);
10797
11177
  }
10798
- async lintFilesLocally(command9) {
10799
- return this.hexa.useCases.lintFilesLocally.execute(command9);
11178
+ async lintFilesLocally(command12) {
11179
+ return this.hexa.useCases.lintFilesLocally.execute(command12);
10800
11180
  }
10801
- async installPackages(command9) {
10802
- return this.hexa.useCases.installPackages.execute(command9);
11181
+ async installPackages(command12) {
11182
+ return this.hexa.useCases.installPackages.execute(command12);
10803
11183
  }
10804
- async listPackages(command9) {
10805
- return this.hexa.useCases.listPackages.execute(command9);
11184
+ async listPackages(command12) {
11185
+ return this.hexa.useCases.listPackages.execute(command12);
10806
11186
  }
10807
- async getPackageBySlug(command9) {
10808
- return this.hexa.useCases.getPackageBySlug.execute(command9);
11187
+ async getPackageBySlug(command12) {
11188
+ return this.hexa.useCases.getPackageBySlug.execute(command12);
10809
11189
  }
10810
11190
  async configExists(baseDirectory) {
10811
11191
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -10864,17 +11244,17 @@ var PackmindCliHexa = class {
10864
11244
  directory
10865
11245
  );
10866
11246
  }
10867
- async login(command9) {
10868
- return this.hexa.useCases.login.execute(command9);
11247
+ async login(command12) {
11248
+ return this.hexa.useCases.login.execute(command12);
10869
11249
  }
10870
- async logout(command9) {
10871
- return this.hexa.useCases.logout.execute(command9);
11250
+ async logout(command12) {
11251
+ return this.hexa.useCases.logout.execute(command12);
10872
11252
  }
10873
- async whoami(command9) {
10874
- return this.hexa.useCases.whoami.execute(command9);
11253
+ async whoami(command12) {
11254
+ return this.hexa.useCases.whoami.execute(command12);
10875
11255
  }
10876
- async setupMcp(command9) {
10877
- return this.hexa.useCases.setupMcp.execute(command9);
11256
+ async setupMcp(command12) {
11257
+ return this.hexa.useCases.setupMcp.execute(command12);
10878
11258
  }
10879
11259
  getCurrentBranch(repoPath) {
10880
11260
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -10882,11 +11262,17 @@ var PackmindCliHexa = class {
10882
11262
  getGitRemoteUrlFromPath(repoPath) {
10883
11263
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
10884
11264
  }
10885
- async notifyDistribution(command9) {
10886
- return this.hexa.repositories.packmindGateway.notifyDistribution(command9);
11265
+ async notifyDistribution(command12) {
11266
+ return this.hexa.repositories.packmindGateway.notifyDistribution(command12);
10887
11267
  }
10888
- async uploadSkill(command9) {
10889
- return this.hexa.repositories.packmindGateway.uploadSkill(command9);
11268
+ async uploadSkill(command12) {
11269
+ return this.hexa.repositories.packmindGateway.uploadSkill(command12);
11270
+ }
11271
+ async installDefaultSkills(command12) {
11272
+ return this.hexa.useCases.installDefaultSkills.execute(command12);
11273
+ }
11274
+ getPackmindGateway() {
11275
+ return this.hexa.repositories.packmindGateway;
10890
11276
  }
10891
11277
  };
10892
11278
 
@@ -10899,7 +11285,7 @@ var IDELintLogger = class {
10899
11285
  }
10900
11286
  logViolation(violation) {
10901
11287
  violation.violations.forEach(({ line, character, standard, rule }) => {
10902
- console.log(
11288
+ logConsole(
10903
11289
  `${violation.file}:${line}:${character}:error:@${standard}/${rule}`
10904
11290
  );
10905
11291
  });
@@ -10925,9 +11311,9 @@ var HumanReadableLogger = class {
10925
11311
  }
10926
11312
  }
10927
11313
  logViolation(violation) {
10928
- console.log(formatFilePath(violation.file));
11314
+ logConsole(formatFilePath(violation.file));
10929
11315
  violation.violations.forEach(({ line, character, standard, rule }) => {
10930
- console.log(
11316
+ logConsole(
10931
11317
  formatError(` ${line}:${character} error @${standard}/${rule}`)
10932
11318
  );
10933
11319
  });
@@ -10943,7 +11329,7 @@ function isNotLoggedInError(error) {
10943
11329
  }
10944
11330
  async function lintHandler(args2, deps) {
10945
11331
  const {
10946
- path: path12,
11332
+ path: path13,
10947
11333
  draft,
10948
11334
  rule,
10949
11335
  language,
@@ -10963,7 +11349,7 @@ async function lintHandler(args2, deps) {
10963
11349
  throw new Error("option --rule is required to use --draft mode");
10964
11350
  }
10965
11351
  const startedAt = Date.now();
10966
- const targetPath = path12 ?? ".";
11352
+ const targetPath = path13 ?? ".";
10967
11353
  const hasArguments = !!(draft || rule || language);
10968
11354
  const absolutePath = resolvePath(targetPath);
10969
11355
  if (diff) {
@@ -11220,8 +11606,8 @@ function extractWasmFiles() {
11220
11606
 
11221
11607
  // apps/cli/src/main.ts
11222
11608
  var import_dotenv = require("dotenv");
11223
- var fs12 = __toESM(require("fs"));
11224
- var path11 = __toESM(require("path"));
11609
+ var fs15 = __toESM(require("fs"));
11610
+ var path12 = __toESM(require("path"));
11225
11611
 
11226
11612
  // apps/cli/src/infra/commands/InstallCommand.ts
11227
11613
  var import_cmd_ts2 = __toESM(require_cjs());
@@ -11255,6 +11641,31 @@ async function notifyDistributionIfInGitRepo(params) {
11255
11641
  return false;
11256
11642
  }
11257
11643
  }
11644
+ async function installDefaultSkillsIfAtGitRoot(params) {
11645
+ const { packmindCliHexa, cwd, log } = params;
11646
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
11647
+ if (!gitRoot || cwd !== gitRoot) {
11648
+ return;
11649
+ }
11650
+ try {
11651
+ log("\nInstalling default skills...");
11652
+ const skillsResult = await packmindCliHexa.installDefaultSkills({});
11653
+ if (skillsResult.errors.length > 0) {
11654
+ skillsResult.errors.forEach((err) => {
11655
+ log(` Warning: ${err}`);
11656
+ });
11657
+ }
11658
+ const totalSkillFiles = skillsResult.filesCreated + skillsResult.filesUpdated;
11659
+ if (totalSkillFiles > 0) {
11660
+ log(
11661
+ `Default skills: added ${skillsResult.filesCreated} files, changed ${skillsResult.filesUpdated} files`
11662
+ );
11663
+ } else if (skillsResult.errors.length === 0) {
11664
+ log("Default skills are already up to date");
11665
+ }
11666
+ } catch {
11667
+ }
11668
+ }
11258
11669
  async function listPackagesHandler(_args, deps) {
11259
11670
  const { packmindCliHexa, exit, log, error } = deps;
11260
11671
  try {
@@ -11472,8 +11883,9 @@ async function executeInstallForDirectory(directory, deps) {
11472
11883
  errorMessage: result.errors.join(", ")
11473
11884
  };
11474
11885
  }
11886
+ const skillDirsDeleted = result.skillDirectoriesDeleted || 0;
11475
11887
  let notificationSent = false;
11476
- if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0) {
11888
+ if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
11477
11889
  notificationSent = await notifyDistributionIfInGitRepo({
11478
11890
  packmindCliHexa,
11479
11891
  cwd: directory,
@@ -11486,7 +11898,7 @@ async function executeInstallForDirectory(directory, deps) {
11486
11898
  success: true,
11487
11899
  filesCreated: result.filesCreated,
11488
11900
  filesUpdated: result.filesUpdated,
11489
- filesDeleted: result.filesDeleted,
11901
+ filesDeleted: result.filesDeleted + skillDirsDeleted,
11490
11902
  notificationSent
11491
11903
  };
11492
11904
  } catch (err) {
@@ -11561,11 +11973,32 @@ async function installPackagesHandler(args2, deps) {
11561
11973
  log(
11562
11974
  `Fetching ${packageCount} ${packageWord}: ${allPackages.join(", ")}...`
11563
11975
  );
11976
+ let gitRemoteUrl;
11977
+ let gitBranch;
11978
+ let relativePath;
11979
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
11980
+ if (gitRoot) {
11981
+ try {
11982
+ gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
11983
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
11984
+ relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
11985
+ if (!relativePath.startsWith("/")) {
11986
+ relativePath = "/" + relativePath;
11987
+ }
11988
+ if (!relativePath.endsWith("/")) {
11989
+ relativePath = relativePath + "/";
11990
+ }
11991
+ } catch {
11992
+ }
11993
+ }
11564
11994
  const result = await packmindCliHexa.installPackages({
11565
11995
  baseDirectory: cwd,
11566
11996
  packagesSlugs: allPackages,
11567
- previousPackagesSlugs: configPackages
11997
+ previousPackagesSlugs: configPackages,
11568
11998
  // Pass previous config for change detection
11999
+ gitRemoteUrl,
12000
+ gitBranch,
12001
+ relativePath
11569
12002
  });
11570
12003
  const parts = [];
11571
12004
  if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
@@ -11573,9 +12006,11 @@ async function installPackagesHandler(args2, deps) {
11573
12006
  parts.push(`${result.standardsCount} standards`);
11574
12007
  if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
11575
12008
  log(`Installing ${parts.join(", ") || "artifacts"}...`);
12009
+ const skillDirsDeleted = result.skillDirectoriesDeleted || 0;
12010
+ const totalDeleted = result.filesDeleted + skillDirsDeleted;
11576
12011
  log(
11577
12012
  `
11578
- added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
12013
+ added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${totalDeleted} files`
11579
12014
  );
11580
12015
  if (result.errors.length > 0) {
11581
12016
  log("\n\u26A0\uFE0F Errors encountered:");
@@ -11586,12 +12021,12 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
11586
12021
  return {
11587
12022
  filesCreated: result.filesCreated,
11588
12023
  filesUpdated: result.filesUpdated,
11589
- filesDeleted: result.filesDeleted,
12024
+ filesDeleted: totalDeleted,
11590
12025
  notificationSent: false
11591
12026
  };
11592
12027
  }
11593
12028
  let notificationSent = false;
11594
- if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0) {
12029
+ if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
11595
12030
  notificationSent = await notifyDistributionIfInGitRepo({
11596
12031
  packmindCliHexa,
11597
12032
  cwd,
@@ -11599,10 +12034,11 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
11599
12034
  log
11600
12035
  });
11601
12036
  }
12037
+ await installDefaultSkillsIfAtGitRoot({ packmindCliHexa, cwd, log });
11602
12038
  return {
11603
12039
  filesCreated: result.filesCreated,
11604
12040
  filesUpdated: result.filesUpdated,
11605
- filesDeleted: result.filesDeleted,
12041
+ filesDeleted: totalDeleted,
11606
12042
  notificationSent
11607
12043
  };
11608
12044
  } catch (err) {
@@ -12050,10 +12486,11 @@ var loginCommand = (0, import_cmd_ts4.command)({
12050
12486
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
12051
12487
  try {
12052
12488
  if (!code) {
12053
- console.log("\nOpening browser for authentication...");
12054
- console.log(
12489
+ logConsole("\nOpening browser for authentication...");
12490
+ const normalizedHost = removeTrailingSlash(host);
12491
+ logConsole(
12055
12492
  `
12056
- If the browser doesn't open, visit: ${host}/cli-login?callback_url=${encodeURIComponent("http://127.0.0.1:19284")}
12493
+ If the browser doesn't open, visit: ${normalizedHost}/cli-login?callback_url=${encodeURIComponent("http://127.0.0.1:19284")}
12057
12494
  `
12058
12495
  );
12059
12496
  logInfoConsole("Waiting for browser authentication...");
@@ -12061,9 +12498,9 @@ If the browser doesn't open, visit: ${host}/cli-login?callback_url=${encodeURICo
12061
12498
  logInfoConsole("Exchanging code for API key...");
12062
12499
  const result = await packmindCliHexa.login({ host, code });
12063
12500
  logSuccessConsole("Login successful!");
12064
- console.log(`
12501
+ logConsole(`
12065
12502
  Credentials saved to: ${result.credentialsPath}`);
12066
- console.log(
12503
+ logConsole(
12067
12504
  "\nYou can now use packmind-cli commands with your authenticated account."
12068
12505
  );
12069
12506
  } catch (error) {
@@ -12094,20 +12531,20 @@ var logoutCommand = (0, import_cmd_ts5.command)({
12094
12531
  }
12095
12532
  if (result.hadCredentialsFile) {
12096
12533
  logSuccessConsole("Logged out successfully.");
12097
- console.log(`Removed credentials from: ${result.credentialsPath}`);
12534
+ logConsole(`Removed credentials from: ${result.credentialsPath}`);
12098
12535
  }
12099
12536
  if (result.hasEnvVar) {
12100
12537
  if (!result.hadCredentialsFile) {
12101
12538
  logInfoConsole("No stored credentials file found.");
12102
12539
  }
12103
- console.log(
12540
+ logConsole(
12104
12541
  "\nNote: PACKMIND_API_KEY_V3 environment variable is still set."
12105
12542
  );
12106
- console.log("To fully log out, run: unset PACKMIND_API_KEY_V3");
12543
+ logConsole("To fully log out, run: unset PACKMIND_API_KEY_V3");
12107
12544
  }
12108
12545
  } catch (error) {
12109
12546
  logErrorConsole("Failed to remove credentials file.");
12110
- console.log(
12547
+ logConsole(
12111
12548
  `Error: ${error instanceof Error ? error.message : String(error)}`
12112
12549
  );
12113
12550
  process.exit(1);
@@ -12136,20 +12573,20 @@ function formatExpiresAt(expiresAt) {
12136
12573
  return "Expires soon";
12137
12574
  }
12138
12575
  function displayAuthInfo(result) {
12139
- console.log(`
12576
+ logConsole(`
12140
12577
  Host: ${result.host}`);
12141
12578
  if (result.organizationName) {
12142
- console.log(`Organization: ${result.organizationName}`);
12579
+ logConsole(`Organization: ${result.organizationName}`);
12143
12580
  }
12144
12581
  if (result.userName) {
12145
- console.log(`User: ${result.userName}`);
12582
+ logConsole(`User: ${result.userName}`);
12146
12583
  }
12147
12584
  if (result.expiresAt) {
12148
- console.log(formatExpiresAt(result.expiresAt));
12585
+ logConsole(formatExpiresAt(result.expiresAt));
12149
12586
  }
12150
12587
  logInfoConsole(`Source: ${result.source}`);
12151
12588
  if (result.isExpired) {
12152
- console.log("\nRun `packmind-cli login` to re-authenticate.");
12589
+ logConsole("\nRun `packmind-cli login` to re-authenticate.");
12153
12590
  }
12154
12591
  }
12155
12592
  var whoamiCommand = (0, import_cmd_ts6.command)({
@@ -12162,14 +12599,14 @@ var whoamiCommand = (0, import_cmd_ts6.command)({
12162
12599
  const result = await packmindCliHexa.whoami({});
12163
12600
  if (!result.isAuthenticated) {
12164
12601
  logErrorConsole("Not authenticated");
12165
- console.log(
12602
+ logConsole(
12166
12603
  `
12167
12604
  No credentials found. Run \`packmind-cli login\` to authenticate.`
12168
12605
  );
12169
- console.log(`
12606
+ logConsole(`
12170
12607
  Credentials are loaded from (in order of priority):`);
12171
- console.log(` 1. PACKMIND_API_KEY_V3 environment variable`);
12172
- console.log(` 2. ${result.credentialsPath}`);
12608
+ logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
12609
+ logConsole(` 2. ${result.credentialsPath}`);
12173
12610
  process.exit(1);
12174
12611
  }
12175
12612
  if (result.isExpired) {
@@ -12186,13 +12623,13 @@ Credentials are loaded from (in order of priority):`);
12186
12623
 
12187
12624
  // apps/cli/src/infra/commands/SetupMcpCommand.ts
12188
12625
  var import_cmd_ts7 = __toESM(require_cjs());
12189
- var fs11 = __toESM(require("fs"));
12626
+ var fs12 = __toESM(require("fs"));
12190
12627
  var readline2 = __toESM(require("readline"));
12191
12628
  var inquirer = __toESM(require("inquirer"));
12192
12629
 
12193
12630
  // apps/cli/src/application/services/AgentDetectionService.ts
12194
- var fs10 = __toESM(require("fs"));
12195
- var path10 = __toESM(require("path"));
12631
+ var fs11 = __toESM(require("fs"));
12632
+ var path11 = __toESM(require("path"));
12196
12633
  var os4 = __toESM(require("os"));
12197
12634
  var import_child_process3 = require("child_process");
12198
12635
  var AgentDetectionService = class {
@@ -12219,21 +12656,21 @@ var AgentDetectionService = class {
12219
12656
  return this.isCommandAvailable("claude");
12220
12657
  }
12221
12658
  isCursorAvailable() {
12222
- const cursorConfigDir = path10.join(os4.homedir(), ".cursor");
12223
- return fs10.existsSync(cursorConfigDir);
12659
+ const cursorConfigDir = path11.join(os4.homedir(), ".cursor");
12660
+ return fs11.existsSync(cursorConfigDir);
12224
12661
  }
12225
12662
  isVSCodeAvailable() {
12226
- const vscodeDir = path10.join(this.projectDir, ".vscode");
12227
- return fs10.existsSync(vscodeDir);
12663
+ const vscodeDir = path11.join(this.projectDir, ".vscode");
12664
+ return fs11.existsSync(vscodeDir);
12228
12665
  }
12229
12666
  isContinueAvailable() {
12230
- const continueDir = path10.join(this.projectDir, ".continue");
12231
- return fs10.existsSync(continueDir);
12667
+ const continueDir = path11.join(this.projectDir, ".continue");
12668
+ return fs11.existsSync(continueDir);
12232
12669
  }
12233
- isCommandAvailable(command9) {
12670
+ isCommandAvailable(command12) {
12234
12671
  try {
12235
12672
  const whichCommand = process.platform === "win32" ? "where" : "which";
12236
- (0, import_child_process3.execSync)(`${whichCommand} ${command9}`, { stdio: "pipe" });
12673
+ (0, import_child_process3.execSync)(`${whichCommand} ${command12}`, { stdio: "pipe" });
12237
12674
  return true;
12238
12675
  } catch {
12239
12676
  return false;
@@ -12267,8 +12704,8 @@ var ALL_AGENTS2 = [
12267
12704
  { type: "continue", name: "Continue.dev" }
12268
12705
  ];
12269
12706
  async function promptAgentsWithReadline(choices) {
12270
- const input = fs11.createReadStream("/dev/tty");
12271
- const output = fs11.createWriteStream("/dev/tty");
12707
+ const input = fs12.createReadStream("/dev/tty");
12708
+ const output = fs12.createWriteStream("/dev/tty");
12272
12709
  const rl = readline2.createInterface({
12273
12710
  input,
12274
12711
  output
@@ -12313,18 +12750,18 @@ var setupMcpCommand = (0, import_cmd_ts7.command)({
12313
12750
  const credentials = loadCredentials();
12314
12751
  if (!credentials) {
12315
12752
  logErrorConsole("Not authenticated");
12316
- console.log("\nNo credentials found. You can authenticate by either:");
12317
- console.log(" 1. Running `packmind-cli login`");
12318
- console.log(" 2. Setting PACKMIND_API_KEY_V3 environment variable");
12319
- console.log(`
12753
+ logConsole("\nNo credentials found. You can authenticate by either:");
12754
+ logConsole(" 1. Running `packmind-cli login`");
12755
+ logConsole(" 2. Setting PACKMIND_API_KEY_V3 environment variable");
12756
+ logConsole(`
12320
12757
  Credentials are loaded from (in order of priority):`);
12321
- console.log(` 1. PACKMIND_API_KEY_V3 environment variable`);
12322
- console.log(` 2. ${getCredentialsPath()}`);
12758
+ logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
12759
+ logConsole(` 2. ${getCredentialsPath()}`);
12323
12760
  process.exit(1);
12324
12761
  }
12325
12762
  if (credentials.isExpired) {
12326
12763
  logErrorConsole("Credentials expired");
12327
- console.log("\nRun `packmind-cli login` to re-authenticate.");
12764
+ logConsole("\nRun `packmind-cli login` to re-authenticate.");
12328
12765
  process.exit(1);
12329
12766
  }
12330
12767
  const agentDetectionService = new AgentDetectionService();
@@ -12332,16 +12769,16 @@ Credentials are loaded from (in order of priority):`);
12332
12769
  if (targets.length > 0) {
12333
12770
  selectedAgents = targets.map((t) => agentArgToType[t]);
12334
12771
  } else {
12335
- console.log("\nDetecting installed AI agents...\n");
12772
+ logConsole("\nDetecting installed AI agents...\n");
12336
12773
  const detectedAgents = agentDetectionService.detectAgents();
12337
12774
  if (detectedAgents.length > 0) {
12338
- console.log("Found agents:");
12775
+ logConsole("Found agents:");
12339
12776
  detectedAgents.forEach((detectedAgent) => {
12340
- console.log(` - ${detectedAgent.name}`);
12777
+ logConsole(` - ${detectedAgent.name}`);
12341
12778
  });
12342
- console.log("");
12779
+ logConsole("");
12343
12780
  } else {
12344
- console.log("No supported agents detected.\n");
12781
+ logConsole("No supported agents detected.\n");
12345
12782
  }
12346
12783
  const detectedTypes = new Set(detectedAgents.map((a) => a.type));
12347
12784
  const choices = ALL_AGENTS2.map((agentInfo) => ({
@@ -12365,12 +12802,12 @@ Credentials are loaded from (in order of priority):`);
12365
12802
  promptedAgents = result2.selectedAgents;
12366
12803
  }
12367
12804
  if (promptedAgents.length === 0) {
12368
- console.log("\nNo agents selected. Exiting.");
12805
+ logConsole("\nNo agents selected. Exiting.");
12369
12806
  process.exit(0);
12370
12807
  }
12371
12808
  selectedAgents = promptedAgents;
12372
12809
  }
12373
- console.log("\nFetching MCP configuration...\n");
12810
+ logConsole("\nFetching MCP configuration...\n");
12374
12811
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
12375
12812
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
12376
12813
  let result;
@@ -12379,14 +12816,14 @@ Credentials are loaded from (in order of priority):`);
12379
12816
  } catch (error) {
12380
12817
  logErrorConsole("Failed to fetch MCP configuration from server.");
12381
12818
  if (error instanceof Error) {
12382
- console.log(` ${error.message}`);
12819
+ logConsole(` ${error.message}`);
12383
12820
  }
12384
12821
  process.exit(1);
12385
12822
  }
12386
12823
  let successCount = 0;
12387
12824
  const failedAgents = [];
12388
12825
  for (const agentResult of result.results) {
12389
- console.log(`Installing MCP for ${agentResult.agentName}...`);
12826
+ logConsole(`Installing MCP for ${agentResult.agentName}...`);
12390
12827
  if (agentResult.success) {
12391
12828
  logSuccessConsole(` ${agentResult.agentName} configured successfully`);
12392
12829
  successCount++;
@@ -12398,27 +12835,27 @@ Credentials are loaded from (in order of priority):`);
12398
12835
  });
12399
12836
  }
12400
12837
  }
12401
- console.log("");
12838
+ logConsole("");
12402
12839
  if (failedAgents.length > 0) {
12403
12840
  for (const failed of failedAgents) {
12404
12841
  logWarningConsole(`Failed to configure ${failed.name}:`);
12405
- console.log(`
12842
+ logConsole(`
12406
12843
  Error: ${failed.error}`);
12407
12844
  if (failed.error.includes("ENOENT") || failed.error.includes("not found") || failed.error.includes("command not found")) {
12408
- console.log(
12845
+ logConsole(
12409
12846
  `
12410
12847
  Hint: Make sure the agent CLI is installed and available in your PATH.`
12411
12848
  );
12412
12849
  }
12413
- console.log(`
12850
+ logConsole(`
12414
12851
  Manual configuration:`);
12415
- console.log(result.manualConfigJson);
12416
- console.log("");
12852
+ logConsole(result.manualConfigJson ?? "undefined");
12853
+ logConsole("");
12417
12854
  }
12418
12855
  }
12419
12856
  if (successCount > 0) {
12420
12857
  const agentWord = successCount === 1 ? "agent" : "agents";
12421
- console.log(
12858
+ logConsole(
12422
12859
  formatBold(`Done! MCP configured for ${successCount} ${agentWord}.`)
12423
12860
  );
12424
12861
  }
@@ -12429,7 +12866,7 @@ Credentials are loaded from (in order of priority):`);
12429
12866
  });
12430
12867
 
12431
12868
  // apps/cli/src/infra/commands/SkillsCommand.ts
12432
- var import_cmd_ts9 = __toESM(require_cjs());
12869
+ var import_cmd_ts10 = __toESM(require_cjs());
12433
12870
 
12434
12871
  // apps/cli/src/infra/commands/skills/AddSkillCommand.ts
12435
12872
  var import_cmd_ts8 = __toESM(require_cjs());
@@ -12479,12 +12916,425 @@ var addSkillCommand = (0, import_cmd_ts8.command)({
12479
12916
  }
12480
12917
  });
12481
12918
 
12919
+ // apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
12920
+ var import_cmd_ts9 = __toESM(require_cjs());
12921
+ var installDefaultSkillsCommand = (0, import_cmd_ts9.command)({
12922
+ name: "install-default",
12923
+ description: "Install default Packmind skills for configured coding agents",
12924
+ args: {},
12925
+ handler: async () => {
12926
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
12927
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
12928
+ try {
12929
+ logInfoConsole("Installing default skills...");
12930
+ const result = await packmindCliHexa.installDefaultSkills({});
12931
+ if (result.errors.length > 0) {
12932
+ for (const error of result.errors) {
12933
+ logErrorConsole(`Error: ${error}`);
12934
+ }
12935
+ process.exit(1);
12936
+ }
12937
+ const totalFiles = result.filesCreated + result.filesUpdated;
12938
+ if (totalFiles === 0) {
12939
+ logInfoConsole("Default skills are already up to date.");
12940
+ } else {
12941
+ logSuccessConsole("Default skills installed successfully!");
12942
+ if (result.filesCreated > 0) {
12943
+ logInfoConsole(` Files created: ${result.filesCreated}`);
12944
+ }
12945
+ if (result.filesUpdated > 0) {
12946
+ logInfoConsole(` Files updated: ${result.filesUpdated}`);
12947
+ }
12948
+ }
12949
+ } catch (error) {
12950
+ if (error instanceof Error) {
12951
+ logErrorConsole(`Installation failed: ${error.message}`);
12952
+ } else {
12953
+ logErrorConsole(`Installation failed: ${String(error)}`);
12954
+ }
12955
+ process.exit(1);
12956
+ }
12957
+ }
12958
+ });
12959
+
12482
12960
  // apps/cli/src/infra/commands/SkillsCommand.ts
12483
- var skillsCommand = (0, import_cmd_ts9.subcommands)({
12961
+ var skillsCommand = (0, import_cmd_ts10.subcommands)({
12484
12962
  name: "skills",
12485
12963
  description: "Manage skills in your Packmind organization",
12486
12964
  cmds: {
12487
- add: addSkillCommand
12965
+ add: addSkillCommand,
12966
+ init: installDefaultSkillsCommand
12967
+ }
12968
+ });
12969
+
12970
+ // apps/cli/src/infra/commands/StandardsCommand.ts
12971
+ var import_cmd_ts12 = __toESM(require_cjs());
12972
+
12973
+ // apps/cli/src/infra/commands/CreateStandardCommand.ts
12974
+ var import_cmd_ts11 = __toESM(require_cjs());
12975
+
12976
+ // apps/cli/src/infra/utils/readPlaybookFile.ts
12977
+ var fs13 = __toESM(require("fs/promises"));
12978
+
12979
+ // apps/cli/src/domain/entities/PlaybookDTO.ts
12980
+ var import_zod = require("zod");
12981
+ var playbookRuleExampleSchema = import_zod.z.object({
12982
+ positive: import_zod.z.string().describe("Valid example of the rule"),
12983
+ negative: import_zod.z.string().describe("Invalid example of the rule"),
12984
+ language: import_zod.z.string().describe("Programming language")
12985
+ });
12986
+ var playbookRuleSchema = import_zod.z.object({
12987
+ content: import_zod.z.string().min(1).describe("Rule description starting with action verb"),
12988
+ examples: playbookRuleExampleSchema.optional()
12989
+ });
12990
+ var playbookDTOSchema = import_zod.z.object({
12991
+ name: import_zod.z.string().min(1).describe("Standard name"),
12992
+ description: import_zod.z.string().min(1).describe("Standard description"),
12993
+ scope: import_zod.z.string().min(1).describe("Standard scope/context"),
12994
+ rules: import_zod.z.array(playbookRuleSchema).min(1).describe("Array of rules (minimum 1)")
12995
+ });
12996
+
12997
+ // apps/cli/src/infra/utils/playbookValidator.ts
12998
+ function validatePlaybook(data) {
12999
+ const result = playbookDTOSchema.safeParse(data);
13000
+ if (!result.success) {
13001
+ const errorList = result.error.issues;
13002
+ return {
13003
+ isValid: false,
13004
+ errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
13005
+ };
13006
+ }
13007
+ return {
13008
+ isValid: true,
13009
+ data: result.data
13010
+ };
13011
+ }
13012
+
13013
+ // apps/cli/src/infra/utils/readPlaybookFile.ts
13014
+ async function readPlaybookFile(filePath) {
13015
+ try {
13016
+ const content = await fs13.readFile(filePath, "utf-8");
13017
+ let parsed;
13018
+ try {
13019
+ parsed = JSON.parse(content);
13020
+ } catch (e) {
13021
+ return {
13022
+ isValid: false,
13023
+ errors: [
13024
+ `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
13025
+ ]
13026
+ };
13027
+ }
13028
+ return validatePlaybook(parsed);
13029
+ } catch (e) {
13030
+ return {
13031
+ isValid: false,
13032
+ errors: [
13033
+ `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
13034
+ ]
13035
+ };
13036
+ }
13037
+ }
13038
+
13039
+ // apps/cli/src/infra/commands/createStandardHandler.ts
13040
+ async function createStandardHandler(filePath, useCase) {
13041
+ const readResult = await readPlaybookFile(filePath);
13042
+ if (!readResult.isValid) {
13043
+ return {
13044
+ success: false,
13045
+ error: `Validation failed: ${readResult.errors?.join(", ")}`
13046
+ };
13047
+ }
13048
+ if (!readResult.data) {
13049
+ return {
13050
+ success: false,
13051
+ error: "Failed to read playbook data"
13052
+ };
13053
+ }
13054
+ try {
13055
+ const result = await useCase.execute(readResult.data);
13056
+ return {
13057
+ success: true,
13058
+ standardId: result.standardId,
13059
+ standardName: result.name
13060
+ };
13061
+ } catch (e) {
13062
+ return {
13063
+ success: false,
13064
+ error: `Error creating standard: ${e instanceof Error ? e.message : "Unknown error"}`
13065
+ };
13066
+ }
13067
+ }
13068
+
13069
+ // apps/cli/src/application/useCases/CreateStandardFromPlaybookUseCase.ts
13070
+ var CreateStandardFromPlaybookUseCase = class {
13071
+ constructor(gateway) {
13072
+ this.gateway = gateway;
13073
+ }
13074
+ async execute(playbook) {
13075
+ const space = await this.gateway.getGlobalSpace();
13076
+ const standard = await this.gateway.createStandardInSpace(space.id, {
13077
+ name: playbook.name,
13078
+ description: playbook.description,
13079
+ scope: playbook.scope,
13080
+ rules: playbook.rules
13081
+ });
13082
+ const rulesWithExamples = playbook.rules.filter((r) => r.examples);
13083
+ if (rulesWithExamples.length > 0) {
13084
+ const createdRules = await this.gateway.getRulesForStandard(
13085
+ space.id,
13086
+ standard.id
13087
+ );
13088
+ for (let i = 0; i < playbook.rules.length; i++) {
13089
+ const rule = playbook.rules[i];
13090
+ if (rule.examples && createdRules[i]) {
13091
+ try {
13092
+ await this.gateway.addExampleToRule(
13093
+ space.id,
13094
+ standard.id,
13095
+ createdRules[i].id,
13096
+ rule.examples
13097
+ );
13098
+ } catch {
13099
+ }
13100
+ }
13101
+ }
13102
+ }
13103
+ return { standardId: standard.id, name: standard.name };
13104
+ }
13105
+ };
13106
+
13107
+ // apps/cli/src/infra/commands/CreateStandardCommand.ts
13108
+ var createStandardCommand = (0, import_cmd_ts11.command)({
13109
+ name: "create",
13110
+ description: "Create a coding standard from a playbook JSON file",
13111
+ args: {
13112
+ file: (0, import_cmd_ts11.positional)({
13113
+ displayName: "file",
13114
+ description: "Path to the playbook JSON file",
13115
+ type: import_cmd_ts11.string
13116
+ })
13117
+ },
13118
+ handler: async ({ file }) => {
13119
+ try {
13120
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
13121
+ const hexa = new PackmindCliHexa(packmindLogger);
13122
+ const gateway = hexa.getPackmindGateway();
13123
+ const useCase = new CreateStandardFromPlaybookUseCase(gateway);
13124
+ const result = await createStandardHandler(file, useCase);
13125
+ if (result.success) {
13126
+ logSuccessConsole(
13127
+ `Standard "${result.standardName}" created successfully (ID: ${result.standardId})`
13128
+ );
13129
+ process.exit(0);
13130
+ } else {
13131
+ logErrorConsole(`Failed to create standard: ${result.error}`);
13132
+ process.exit(1);
13133
+ }
13134
+ } catch (e) {
13135
+ logErrorConsole(
13136
+ `Error: ${e instanceof Error ? e.message : "Unknown error"}`
13137
+ );
13138
+ process.exit(1);
13139
+ }
13140
+ }
13141
+ });
13142
+
13143
+ // apps/cli/src/infra/commands/StandardsCommand.ts
13144
+ var standardsCommand = (0, import_cmd_ts12.subcommands)({
13145
+ name: "standards",
13146
+ description: "Manage coding standards",
13147
+ cmds: {
13148
+ create: createStandardCommand
13149
+ }
13150
+ });
13151
+
13152
+ // apps/cli/src/infra/commands/CommandsCommand.ts
13153
+ var import_cmd_ts14 = __toESM(require_cjs());
13154
+
13155
+ // apps/cli/src/infra/commands/CreateCommandCommand.ts
13156
+ var import_cmd_ts13 = __toESM(require_cjs());
13157
+
13158
+ // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
13159
+ var fs14 = __toESM(require("fs/promises"));
13160
+
13161
+ // apps/cli/src/domain/entities/CommandPlaybookDTO.ts
13162
+ var import_zod2 = require("zod");
13163
+ var commandStepSchema = import_zod2.z.object({
13164
+ name: import_zod2.z.string().min(1).describe("Step name/title"),
13165
+ description: import_zod2.z.string().min(1).describe("Step description with implementation details"),
13166
+ codeSnippet: import_zod2.z.string().optional().describe("Optional code snippet demonstrating the step")
13167
+ });
13168
+ var commandPlaybookDTOSchema = import_zod2.z.object({
13169
+ name: import_zod2.z.string().min(1).describe("Command name"),
13170
+ summary: import_zod2.z.string().min(1).describe("Command summary describing intent and value"),
13171
+ whenToUse: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe("Array of scenarios when this command is applicable (minimum 1)"),
13172
+ contextValidationCheckpoints: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe(
13173
+ "Array of checkpoints to validate context before implementation (minimum 1)"
13174
+ ),
13175
+ steps: import_zod2.z.array(commandStepSchema).min(1).describe("Array of implementation steps (minimum 1)")
13176
+ });
13177
+
13178
+ // apps/cli/src/infra/utils/commandPlaybookValidator.ts
13179
+ function validateCommandPlaybook(data) {
13180
+ const result = commandPlaybookDTOSchema.safeParse(data);
13181
+ if (!result.success) {
13182
+ const errorList = result.error.issues;
13183
+ return {
13184
+ isValid: false,
13185
+ errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
13186
+ };
13187
+ }
13188
+ return {
13189
+ isValid: true,
13190
+ data: result.data
13191
+ };
13192
+ }
13193
+
13194
+ // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
13195
+ async function readCommandPlaybookFile(filePath) {
13196
+ try {
13197
+ const content = await fs14.readFile(filePath, "utf-8");
13198
+ let parsed;
13199
+ try {
13200
+ parsed = JSON.parse(content);
13201
+ } catch (e) {
13202
+ return {
13203
+ isValid: false,
13204
+ errors: [
13205
+ `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
13206
+ ]
13207
+ };
13208
+ }
13209
+ return validateCommandPlaybook(parsed);
13210
+ } catch (e) {
13211
+ return {
13212
+ isValid: false,
13213
+ errors: [
13214
+ `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
13215
+ ]
13216
+ };
13217
+ }
13218
+ }
13219
+
13220
+ // apps/cli/src/infra/commands/createCommandHandler.ts
13221
+ function buildWebappUrl(host, orgSlug, commandId) {
13222
+ return `${host}/org/${orgSlug}/space/global/commands/${commandId}`;
13223
+ }
13224
+ async function createCommandHandler(filePath, useCase) {
13225
+ const readResult = await readCommandPlaybookFile(filePath);
13226
+ if (!readResult.isValid) {
13227
+ return {
13228
+ success: false,
13229
+ error: `Validation failed: ${readResult.errors?.join(", ")}`
13230
+ };
13231
+ }
13232
+ if (!readResult.data) {
13233
+ return {
13234
+ success: false,
13235
+ error: "Failed to read command playbook data"
13236
+ };
13237
+ }
13238
+ try {
13239
+ const result = await useCase.execute(readResult.data);
13240
+ let webappUrl;
13241
+ const apiKey = loadApiKey();
13242
+ if (apiKey) {
13243
+ const decoded = decodeApiKey2(apiKey);
13244
+ if (decoded?.host && decoded?.jwt?.organization?.slug) {
13245
+ webappUrl = buildWebappUrl(
13246
+ decoded.host,
13247
+ decoded.jwt.organization.slug,
13248
+ result.commandId
13249
+ );
13250
+ }
13251
+ }
13252
+ return {
13253
+ success: true,
13254
+ commandId: result.commandId,
13255
+ commandName: result.name,
13256
+ webappUrl
13257
+ };
13258
+ } catch (e) {
13259
+ return {
13260
+ success: false,
13261
+ error: `Error creating command: ${e instanceof Error ? e.message : "Unknown error"}`
13262
+ };
13263
+ }
13264
+ }
13265
+
13266
+ // apps/cli/src/application/useCases/CreateCommandFromPlaybookUseCase.ts
13267
+ var CreateCommandFromPlaybookUseCase = class {
13268
+ constructor(gateway) {
13269
+ this.gateway = gateway;
13270
+ }
13271
+ async execute(playbook) {
13272
+ const space = await this.gateway.getGlobalSpace();
13273
+ const command12 = await this.gateway.createCommand(space.id, {
13274
+ name: playbook.name,
13275
+ summary: playbook.summary,
13276
+ whenToUse: playbook.whenToUse,
13277
+ contextValidationCheckpoints: playbook.contextValidationCheckpoints,
13278
+ steps: playbook.steps.map((step) => ({
13279
+ name: step.name,
13280
+ description: step.description,
13281
+ codeSnippet: step.codeSnippet
13282
+ }))
13283
+ });
13284
+ return {
13285
+ commandId: command12.id,
13286
+ name: command12.name,
13287
+ slug: command12.slug
13288
+ };
13289
+ }
13290
+ };
13291
+
13292
+ // apps/cli/src/infra/commands/CreateCommandCommand.ts
13293
+ var createCommandCommand = (0, import_cmd_ts13.command)({
13294
+ name: "create",
13295
+ description: "Create a command from a playbook JSON file",
13296
+ args: {
13297
+ file: (0, import_cmd_ts13.positional)({
13298
+ displayName: "file",
13299
+ description: "Path to the command playbook JSON file",
13300
+ type: import_cmd_ts13.string
13301
+ })
13302
+ },
13303
+ handler: async ({ file }) => {
13304
+ try {
13305
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
13306
+ const hexa = new PackmindCliHexa(packmindLogger);
13307
+ const gateway = hexa.getPackmindGateway();
13308
+ const useCase = new CreateCommandFromPlaybookUseCase(gateway);
13309
+ const result = await createCommandHandler(file, useCase);
13310
+ if (result.success) {
13311
+ logSuccessConsole(
13312
+ `Command "${result.commandName}" created successfully (ID: ${result.commandId})`
13313
+ );
13314
+ if (result.webappUrl) {
13315
+ logConsole("");
13316
+ logConsole(`View it in the webapp: ${result.webappUrl}`);
13317
+ }
13318
+ process.exit(0);
13319
+ } else {
13320
+ logErrorConsole(`Failed to create command: ${result.error}`);
13321
+ process.exit(1);
13322
+ }
13323
+ } catch (e) {
13324
+ logErrorConsole(
13325
+ `Error: ${e instanceof Error ? e.message : "Unknown error"}`
13326
+ );
13327
+ process.exit(1);
13328
+ }
13329
+ }
13330
+ });
13331
+
13332
+ // apps/cli/src/infra/commands/CommandsCommand.ts
13333
+ var commandsCommand = (0, import_cmd_ts14.subcommands)({
13334
+ name: "commands",
13335
+ description: "Manage commands",
13336
+ cmds: {
13337
+ create: createCommandCommand
12488
13338
  }
12489
13339
  });
12490
13340
 
@@ -12494,20 +13344,20 @@ function findEnvFile() {
12494
13344
  const currentDir = process.cwd();
12495
13345
  const gitService = new GitService();
12496
13346
  const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
12497
- const filesystemRoot = path11.parse(currentDir).root;
13347
+ const filesystemRoot = path12.parse(currentDir).root;
12498
13348
  const stopDir = gitRoot ?? filesystemRoot;
12499
13349
  let searchDir = currentDir;
12500
- let parentDir = path11.dirname(searchDir);
13350
+ let parentDir = path12.dirname(searchDir);
12501
13351
  while (searchDir !== parentDir) {
12502
- const envPath2 = path11.join(searchDir, ".env");
12503
- if (fs12.existsSync(envPath2)) {
13352
+ const envPath2 = path12.join(searchDir, ".env");
13353
+ if (fs15.existsSync(envPath2)) {
12504
13354
  return envPath2;
12505
13355
  }
12506
13356
  if (searchDir === stopDir) {
12507
13357
  return null;
12508
13358
  }
12509
13359
  searchDir = parentDir;
12510
- parentDir = path11.dirname(searchDir);
13360
+ parentDir = path12.dirname(searchDir);
12511
13361
  }
12512
13362
  return null;
12513
13363
  }
@@ -12524,10 +13374,10 @@ if (hasEmbeddedWasmFiles()) {
12524
13374
  }
12525
13375
  var args = process.argv.slice(2);
12526
13376
  if (args.includes("--version") || args.includes("-v")) {
12527
- console.log(`packmind-cli version ${CLI_VERSION}`);
13377
+ logConsole(`packmind-cli version ${CLI_VERSION}`);
12528
13378
  process.exit(0);
12529
13379
  }
12530
- var app = (0, import_cmd_ts10.subcommands)({
13380
+ var app = (0, import_cmd_ts15.subcommands)({
12531
13381
  name: "packmind-cli",
12532
13382
  description: "Packmind CLI tool",
12533
13383
  cmds: {
@@ -12540,10 +13390,12 @@ var app = (0, import_cmd_ts10.subcommands)({
12540
13390
  logout: logoutCommand,
12541
13391
  whoami: whoamiCommand,
12542
13392
  "setup-mcp": setupMcpCommand,
12543
- skills: skillsCommand
13393
+ skills: skillsCommand,
13394
+ standards: standardsCommand,
13395
+ commands: commandsCommand
12544
13396
  }
12545
13397
  });
12546
- (0, import_cmd_ts10.run)(app, args).catch((error) => {
13398
+ (0, import_cmd_ts15.run)(app, args).catch((error) => {
12547
13399
  logErrorConsole(error.message);
12548
13400
  process.exit(1);
12549
13401
  });