@packmind/cli 0.16.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/main.cjs +2243 -452
  2. package/package.json +2 -1
package/main.cjs CHANGED
@@ -234,9 +234,9 @@ var init_ansi_styles = __esm({
234
234
  });
235
235
 
236
236
  // node_modules/chalk/source/vendor/supports-color/index.js
237
- function hasFlag(flag4, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
238
- const prefix = flag4.startsWith("-") ? "" : flag4.length === 1 ? "-" : "--";
239
- const position = argv.indexOf(prefix + flag4);
237
+ function hasFlag(flag5, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
238
+ const prefix = flag5.startsWith("-") ? "" : flag5.length === 1 ? "-" : "--";
239
+ const position = argv.indexOf(prefix + flag5);
240
240
  const terminatorPosition = argv.indexOf("--");
241
241
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
242
242
  }
@@ -371,32 +371,32 @@ var init_supports_color = __esm({
371
371
  });
372
372
 
373
373
  // node_modules/chalk/source/utilities.js
374
- function stringReplaceAll(string11, substring, replacer) {
375
- let index = string11.indexOf(substring);
374
+ function stringReplaceAll(string12, substring, replacer) {
375
+ let index = string12.indexOf(substring);
376
376
  if (index === -1) {
377
- return string11;
377
+ return string12;
378
378
  }
379
379
  const substringLength = substring.length;
380
380
  let endIndex = 0;
381
381
  let returnValue = "";
382
382
  do {
383
- returnValue += string11.slice(endIndex, index) + substring + replacer;
383
+ returnValue += string12.slice(endIndex, index) + substring + replacer;
384
384
  endIndex = index + substringLength;
385
- index = string11.indexOf(substring, endIndex);
385
+ index = string12.indexOf(substring, endIndex);
386
386
  } while (index !== -1);
387
- returnValue += string11.slice(endIndex);
387
+ returnValue += string12.slice(endIndex);
388
388
  return returnValue;
389
389
  }
390
- function stringEncaseCRLFWithFirstIndex(string11, prefix, postfix, index) {
390
+ function stringEncaseCRLFWithFirstIndex(string12, prefix, postfix, index) {
391
391
  let endIndex = 0;
392
392
  let returnValue = "";
393
393
  do {
394
- const gotCR = string11[index - 1] === "\r";
395
- returnValue += string11.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
394
+ const gotCR = string12[index - 1] === "\r";
395
+ returnValue += string12.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
396
  endIndex = index + 1;
397
- index = string11.indexOf("\n", endIndex);
397
+ index = string12.indexOf("\n", endIndex);
398
398
  } while (index !== -1);
399
- returnValue += string11.slice(endIndex);
399
+ returnValue += string12.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, string11) => {
559
- if (self.level <= 0 || !string11) {
560
- return self[IS_EMPTY] ? "" : string11;
558
+ applyStyle = (self, string12) => {
559
+ if (self.level <= 0 || !string12) {
560
+ return self[IS_EMPTY] ? "" : string12;
561
561
  }
562
562
  let styler = self[STYLER];
563
563
  if (styler === void 0) {
564
- return string11;
564
+ return string12;
565
565
  }
566
566
  const { openAll, closeAll } = styler;
567
- if (string11.includes("\x1B")) {
567
+ if (string12.includes("\x1B")) {
568
568
  while (styler !== void 0) {
569
- string11 = stringReplaceAll(string11, styler.close, styler.open);
569
+ string12 = stringReplaceAll(string12, styler.close, styler.open);
570
570
  styler = styler.parent;
571
571
  }
572
572
  }
573
- const lfIndex = string11.indexOf("\n");
573
+ const lfIndex = string12.indexOf("\n");
574
574
  if (lfIndex !== -1) {
575
- string11 = stringEncaseCRLFWithFirstIndex(string11, closeAll, openAll, lfIndex);
575
+ string12 = stringEncaseCRLFWithFirstIndex(string12, closeAll, openAll, lfIndex);
576
576
  }
577
- return openAll + string11 + closeAll;
577
+ return openAll + string12 + closeAll;
578
578
  };
579
579
  Object.defineProperties(createChalk.prototype, styles2);
580
580
  chalk = createChalk();
@@ -767,9 +767,9 @@ var require_findOption = __commonJS({
767
767
  continue;
768
768
  }
769
769
  if (node.type === "shortOptions" && opts.shortNames.length) {
770
- for (const option7 of node.options) {
771
- if (opts.shortNames.includes(option7.key)) {
772
- result.push(option7);
770
+ for (const option8 of node.options) {
771
+ if (opts.shortNames.includes(option8.key)) {
772
+ result.push(option8);
773
773
  }
774
774
  }
775
775
  }
@@ -842,7 +842,7 @@ var require_types = __commonJS({
842
842
  "use strict";
843
843
  Object.defineProperty(exports2, "__esModule", { value: true });
844
844
  exports2.boolean = exports2.string = exports2.number = void 0;
845
- exports2.optional = optional5;
845
+ exports2.optional = optional8;
846
846
  exports2.array = array3;
847
847
  var type_1 = require_type();
848
848
  exports2.number = {
@@ -869,7 +869,7 @@ var require_types = __commonJS({
869
869
  return false;
870
870
  }
871
871
  };
872
- function optional5(t) {
872
+ function optional8(t) {
873
873
  return {
874
874
  ...t,
875
875
  defaultValue() {
@@ -935,7 +935,7 @@ var require_flag = __commonJS({
935
935
  Object.defineProperty(exports2, "__esModule", { value: true });
936
936
  exports2.boolean = void 0;
937
937
  exports2.fullFlag = fullFlag;
938
- exports2.flag = flag4;
938
+ exports2.flag = flag5;
939
939
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
940
940
  var Result = __importStar(require_Result());
941
941
  var findOption_1 = require_findOption();
@@ -1084,7 +1084,7 @@ var require_flag = __commonJS({
1084
1084
  }
1085
1085
  };
1086
1086
  }
1087
- function flag4(config) {
1087
+ function flag5(config) {
1088
1088
  return fullFlag({
1089
1089
  type: types_1.boolean,
1090
1090
  ...config
@@ -1403,9 +1403,9 @@ var require_subcommands = __commonJS({
1403
1403
  let errorMessage = "Not a valid subcommand name";
1404
1404
  const closeOptions = (0, didyoumean_1.default)(str, flatMap(commands, (x) => x.names));
1405
1405
  if (closeOptions) {
1406
- const option7 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1406
+ const option8 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1407
1407
  errorMessage += `
1408
- Did you mean ${chalk_1.default.italic(option7)}?`;
1408
+ Did you mean ${chalk_1.default.italic(option8)}?`;
1409
1409
  }
1410
1410
  throw new Error(errorMessage);
1411
1411
  }
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
1578
1578
  __export(strip_ansi_exports, {
1579
1579
  default: () => stripAnsi
1580
1580
  });
1581
- function stripAnsi(string11) {
1582
- if (typeof string11 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string11}\``);
1581
+ function stripAnsi(string12) {
1582
+ if (typeof string12 !== "string") {
1583
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string12}\``);
1584
1584
  }
1585
- return string11.replace(regex, "");
1585
+ return string12.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 = command20;
1701
+ exports2.command = command21;
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 command20(config) {
1706
+ function command21(config) {
1707
1707
  const argEntries = (0, utils_1.entries)(config.args);
1708
1708
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1709
1709
  return {
@@ -1781,11 +1781,11 @@ var require_command = __commonJS({
1781
1781
  }
1782
1782
  if (node.type === "forcePositional") {
1783
1783
  } else if (node.type === "shortOptions") {
1784
- for (const option7 of node.options) {
1785
- if (context.visitedNodes.has(option7)) {
1784
+ for (const option8 of node.options) {
1785
+ if (context.visitedNodes.has(option8)) {
1786
1786
  continue;
1787
1787
  }
1788
- unknownArguments.push(option7);
1788
+ unknownArguments.push(option8);
1789
1789
  }
1790
1790
  } else {
1791
1791
  unknownArguments.push(node);
@@ -1864,7 +1864,7 @@ var require_option = __commonJS({
1864
1864
  return mod && mod.__esModule ? mod : { "default": mod };
1865
1865
  };
1866
1866
  Object.defineProperty(exports2, "__esModule", { value: true });
1867
- exports2.option = option7;
1867
+ exports2.option = option8;
1868
1868
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1869
1869
  var Result = __importStar(require_Result());
1870
1870
  var findOption_1 = require_findOption();
@@ -1940,11 +1940,11 @@ var require_option = __commonJS({
1940
1940
  const valueFromEnv = config.env ? process.env[config.env] : void 0;
1941
1941
  const defaultValueFn = config.defaultValue || config.type.defaultValue;
1942
1942
  const onMissingFn = config.onMissing || config.type.onMissing;
1943
- const option8 = options[0];
1943
+ const option9 = options[0];
1944
1944
  let rawValue;
1945
1945
  let envPrefix = "";
1946
- if (option8 === null || option8 === void 0 ? void 0 : option8.value) {
1947
- rawValue = option8.value.node.raw;
1946
+ if (option9 === null || option9 === void 0 ? void 0 : option9.value) {
1947
+ rawValue = option9.value.node.raw;
1948
1948
  } else if (valueFromEnv !== void 0) {
1949
1949
  rawValue = valueFromEnv;
1950
1950
  envPrefix = `env[${chalk_1.default.italic(config.env)}]: `;
@@ -1979,7 +1979,7 @@ var require_option = __commonJS({
1979
1979
  });
1980
1980
  }
1981
1981
  } else {
1982
- const raw = (option8 === null || option8 === void 0 ? void 0 : option8.type) === "shortOption" ? `-${option8 === null || option8 === void 0 ? void 0 : option8.key}` : `--${config.long}`;
1982
+ const raw = (option9 === null || option9 === void 0 ? void 0 : option9.type) === "shortOption" ? `-${option9 === null || option9 === void 0 ? void 0 : option9.key}` : `--${config.long}`;
1983
1983
  return Result.err({
1984
1984
  errors: [
1985
1985
  {
@@ -2001,7 +2001,7 @@ var require_option = __commonJS({
2001
2001
  }
2002
2002
  };
2003
2003
  }
2004
- function option7(config) {
2004
+ function option8(config) {
2005
2005
  return fullOption({
2006
2006
  type: types_1.string,
2007
2007
  ...config
@@ -2040,12 +2040,12 @@ var require_errorBox = __commonJS({
2040
2040
  if (node.type === "shortOptions") {
2041
2041
  let failed = false;
2042
2042
  let s = "";
2043
- for (const option7 of node.options) {
2044
- if (error.nodes.includes(option7)) {
2045
- s += chalk_1.default.red(option7.raw);
2043
+ for (const option8 of node.options) {
2044
+ if (error.nodes.includes(option8)) {
2045
+ s += chalk_1.default.red(option8.raw);
2046
2046
  failed = true;
2047
2047
  } else {
2048
- s += chalk_1.default.dim(option7.raw);
2048
+ s += chalk_1.default.dim(option8.raw);
2049
2049
  }
2050
2050
  }
2051
2051
  const prefix = failed ? chalk_1.default.red("-") : chalk_1.default.dim("-");
@@ -2574,9 +2574,9 @@ var require_browser = __commonJS({
2574
2574
  var require_has_flag = __commonJS({
2575
2575
  "node_modules/has-flag/index.js"(exports2, module2) {
2576
2576
  "use strict";
2577
- module2.exports = (flag4, argv = process.argv) => {
2578
- const prefix = flag4.startsWith("-") ? "" : flag4.length === 1 ? "-" : "--";
2579
- const position = argv.indexOf(prefix + flag4);
2577
+ module2.exports = (flag5, argv = process.argv) => {
2578
+ const prefix = flag5.startsWith("-") ? "" : flag5.length === 1 ? "-" : "--";
2579
+ const position = argv.indexOf(prefix + flag5);
2580
2580
  const terminatorPosition = argv.indexOf("--");
2581
2581
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
2582
2582
  };
@@ -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, string11] of (0, utils_1.enumerate)(strings)) {
3088
- const chars = [...string11];
3087
+ for (const [stringIndex, string12] of (0, utils_1.enumerate)(strings)) {
3088
+ const chars = [...string12];
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 });
@@ -3346,15 +3346,15 @@ var require_multiflag = __commonJS({
3346
3346
  longNames: [config.long],
3347
3347
  shortNames: config.short ? [config.short] : []
3348
3348
  }).filter((x) => !visitedNodes.has(x));
3349
- for (const option7 of options) {
3350
- visitedNodes.add(option7);
3349
+ for (const option8 of options) {
3350
+ visitedNodes.add(option8);
3351
3351
  }
3352
3352
  const optionValues = [];
3353
3353
  const errors = [];
3354
- for (const option7 of options) {
3355
- const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option7.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3354
+ for (const option8 of options) {
3355
+ const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option8.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3356
3356
  if (Result.isErr(decoded)) {
3357
- errors.push({ nodes: [option7], message: decoded.error.message });
3357
+ errors.push({ nodes: [option8], message: decoded.error.message });
3358
3358
  } else {
3359
3359
  optionValues.push(decoded.value);
3360
3360
  }
@@ -3518,16 +3518,16 @@ var require_multioption = __commonJS({
3518
3518
  });
3519
3519
  }
3520
3520
  }
3521
- for (const option7 of options) {
3522
- visitedNodes.add(option7);
3521
+ for (const option8 of options) {
3522
+ visitedNodes.add(option8);
3523
3523
  }
3524
3524
  const optionValues = [];
3525
3525
  const errors = [];
3526
3526
  const flagNodes = [];
3527
- for (const option7 of options) {
3528
- const providedValue = (_a = option7.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3527
+ for (const option8 of options) {
3528
+ const providedValue = (_a = option8.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3529
3529
  if (providedValue === void 0) {
3530
- flagNodes.push(option7);
3530
+ flagNodes.push(option8);
3531
3531
  continue;
3532
3532
  }
3533
3533
  optionValues.push(providedValue);
@@ -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.16.1",
3855
+ version: "0.18.0",
3856
3856
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3857
  private: false,
3858
3858
  bin: {
@@ -3895,7 +3895,7 @@ var require_package = __commonJS({
3895
3895
  });
3896
3896
 
3897
3897
  // apps/cli/src/main.ts
3898
- var import_cmd_ts26 = __toESM(require_cjs());
3898
+ var import_cmd_ts27 = __toESM(require_cjs());
3899
3899
 
3900
3900
  // apps/cli/src/infra/commands/LinterCommand.ts
3901
3901
  var import_cmd_ts = __toESM(require_cjs());
@@ -4059,6 +4059,13 @@ var OrganizationCreatedEvent = class extends UserEvent {
4059
4059
  }
4060
4060
  };
4061
4061
 
4062
+ // packages/types/src/accounts/events/UserSignedInEvent.ts
4063
+ var UserSignedInEvent = class extends UserEvent {
4064
+ static {
4065
+ this.eventName = "accounts.user.signed-in";
4066
+ }
4067
+ };
4068
+
4062
4069
  // packages/types/src/accounts/TrialActivationToken.ts
4063
4070
  var createTrialActivationTokenId = brandedIdFactory();
4064
4071
  var createTrialActivationToken = brandedIdFactory();
@@ -4969,6 +4976,29 @@ var createAIProviderId = brandedIdFactory();
4969
4976
  // packages/types/src/playbookChangeManagement/ChangeProposalId.ts
4970
4977
  var createChangeProposalId = brandedIdFactory();
4971
4978
 
4979
+ // packages/types/src/playbookChangeManagement/ChangeProposalTypeLabels.ts
4980
+ var CHANGE_PROPOSAL_TYPE_LABELS = {
4981
+ ["updateCommandName" /* updateCommandName */]: "Name",
4982
+ ["updateCommandDescription" /* updateCommandDescription */]: "Instructions updated",
4983
+ ["updateStandardName" /* updateStandardName */]: "Name",
4984
+ ["updateStandardDescription" /* updateStandardDescription */]: "Description",
4985
+ ["updateStandardScope" /* updateStandardScope */]: "Scope",
4986
+ ["addRule" /* addRule */]: "Rule (add)",
4987
+ ["updateRule" /* updateRule */]: "Rule (update)",
4988
+ ["deleteRule" /* deleteRule */]: "Rule (delete)",
4989
+ ["updateSkillName" /* updateSkillName */]: "Name",
4990
+ ["updateSkillDescription" /* updateSkillDescription */]: "Description",
4991
+ ["updateSkillPrompt" /* updateSkillPrompt */]: "Prompt",
4992
+ ["updateSkillMetadata" /* updateSkillMetadata */]: "Metadata",
4993
+ ["updateSkillLicense" /* updateSkillLicense */]: "License",
4994
+ ["updateSkillCompatibility" /* updateSkillCompatibility */]: "Compatibility",
4995
+ ["updateSkillAllowedTools" /* updateSkillAllowedTools */]: "Allowed Tools",
4996
+ ["addSkillFile" /* addSkillFile */]: "File (add)",
4997
+ ["updateSkillFileContent" /* updateSkillFileContent */]: "File content",
4998
+ ["updateSkillFilePermissions" /* updateSkillFilePermissions */]: "File permissions",
4999
+ ["deleteSkillFile" /* deleteSkillFile */]: "File (delete)"
5000
+ };
5001
+
4972
5002
  // apps/cli/src/application/useCases/ExecuteSingleFileAstUseCase.ts
4973
5003
  var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4974
5004
  constructor(linterExecutionUseCase) {
@@ -4980,8 +5010,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4980
5010
  static {
4981
5011
  this.fallbackRuleContent = "adhoc-rule";
4982
5012
  }
4983
- async execute(command20) {
4984
- const { program, fileContent, language } = command20;
5013
+ async execute(command21) {
5014
+ const { program, fileContent, language } = command21;
4985
5015
  const result = await this.linterExecutionUseCase.execute({
4986
5016
  filePath: "cli-single-file",
4987
5017
  fileContent,
@@ -4992,7 +5022,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4992
5022
  ruleContent: _ExecuteSingleFileAstUseCase.fallbackRuleContent,
4993
5023
  standardSlug: _ExecuteSingleFileAstUseCase.fallbackStandardSlug,
4994
5024
  sourceCodeState: "AST",
4995
- language
5025
+ language,
5026
+ severity: "error" /* ERROR */
4996
5027
  }
4997
5028
  ]
4998
5029
  });
@@ -5031,30 +5062,30 @@ var GitService = class {
5031
5062
  this.gitRunner = gitRunner;
5032
5063
  this.logger = logger2;
5033
5064
  }
5034
- getGitRepositoryRoot(path14) {
5065
+ getGitRepositoryRoot(path18) {
5035
5066
  try {
5036
5067
  const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
5037
- cwd: path14
5068
+ cwd: path18
5038
5069
  });
5039
5070
  const gitRoot = stdout.trim();
5040
5071
  this.logger.debug("Resolved git repository root", {
5041
- inputPath: path14,
5072
+ inputPath: path18,
5042
5073
  gitRoot
5043
5074
  });
5044
5075
  return gitRoot;
5045
5076
  } catch (error) {
5046
5077
  if (error instanceof Error) {
5047
5078
  throw new Error(
5048
- `Failed to get Git repository root. The path '${path14}' does not appear to be inside a Git repository.
5079
+ `Failed to get Git repository root. The path '${path18}' does not appear to be inside a Git repository.
5049
5080
  ${error.message}`
5050
5081
  );
5051
5082
  }
5052
5083
  throw new Error("Failed to get Git repository root: Unknown error");
5053
5084
  }
5054
5085
  }
5055
- tryGetGitRepositoryRoot(path14) {
5086
+ tryGetGitRepositoryRoot(path18) {
5056
5087
  try {
5057
- return this.getGitRepositoryRoot(path14);
5088
+ return this.getGitRepositoryRoot(path18);
5058
5089
  } catch {
5059
5090
  return null;
5060
5091
  }
@@ -5361,8 +5392,8 @@ var GetGitRemoteUrlUseCase = class {
5361
5392
  constructor(gitRemoteUrlService = new GitService()) {
5362
5393
  this.gitRemoteUrlService = gitRemoteUrlService;
5363
5394
  }
5364
- async execute(command20) {
5365
- const { path: repoPath, origin: origin9 } = command20;
5395
+ async execute(command21) {
5396
+ const { path: repoPath, origin: origin9 } = command21;
5366
5397
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5367
5398
  }
5368
5399
  };
@@ -5398,6 +5429,9 @@ function formatLabel(text) {
5398
5429
  function formatError(text) {
5399
5430
  return source_default.red(text);
5400
5431
  }
5432
+ function formatWarning(text) {
5433
+ return source_default.yellow(text);
5434
+ }
5401
5435
  function formatBold(text) {
5402
5436
  return source_default.bold(text);
5403
5437
  }
@@ -5504,8 +5538,8 @@ var ListFilesInDirectoryUseCase = class {
5504
5538
  constructor(listFiles = new ListFiles()) {
5505
5539
  this.listFiles = listFiles;
5506
5540
  }
5507
- async execute(command20) {
5508
- const { path: directoryPath, extensions, excludes = [] } = command20;
5541
+ async execute(command21) {
5542
+ const { path: directoryPath, extensions, excludes = [] } = command21;
5509
5543
  const files = await this.listFiles.listFilesInDirectory(
5510
5544
  directoryPath,
5511
5545
  extensions,
@@ -5552,6 +5586,17 @@ var LintFilesAgainstRuleUseCase = class {
5552
5586
  this.services = services;
5553
5587
  this.repositories = repositories;
5554
5588
  this.logger = logger2;
5589
+ this.mapToActiveDetectionProgram = (item, fallbackLanguage) => {
5590
+ return {
5591
+ language: item.language ?? fallbackLanguage,
5592
+ severity: item.severity,
5593
+ detectionProgram: {
5594
+ mode: item.mode,
5595
+ code: item.code,
5596
+ sourceCodeState: item.sourceCodeState
5597
+ }
5598
+ };
5599
+ };
5555
5600
  }
5556
5601
  fileMatchesTargetAndScope(filePath, targetPath, scopePatterns) {
5557
5602
  if (!scopePatterns || scopePatterns.length === 0) {
@@ -5599,7 +5644,7 @@ var LintFilesAgainstRuleUseCase = class {
5599
5644
  }
5600
5645
  return pattern;
5601
5646
  }
5602
- async execute(command20) {
5647
+ async execute(command21) {
5603
5648
  const {
5604
5649
  path: userPath,
5605
5650
  draftMode,
@@ -5607,7 +5652,7 @@ var LintFilesAgainstRuleUseCase = class {
5607
5652
  ruleId,
5608
5653
  language,
5609
5654
  diffMode
5610
- } = command20;
5655
+ } = command21;
5611
5656
  this.logger.debug(
5612
5657
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
5613
5658
  );
@@ -5715,14 +5760,7 @@ var LintFilesAgainstRuleUseCase = class {
5715
5760
  {
5716
5761
  content: draftProgramsResult.ruleContent || "Draft Rule",
5717
5762
  activeDetectionPrograms: draftProgramsResult.programs.map(
5718
- (program) => ({
5719
- language: program.language,
5720
- detectionProgram: {
5721
- mode: program.mode,
5722
- code: program.code,
5723
- sourceCodeState: program.sourceCodeState
5724
- }
5725
- })
5763
+ (item) => this.mapToActiveDetectionProgram(item, language)
5726
5764
  )
5727
5765
  }
5728
5766
  ]
@@ -5759,14 +5797,7 @@ var LintFilesAgainstRuleUseCase = class {
5759
5797
  {
5760
5798
  content: activeProgramsResult.ruleContent || "Active Rule",
5761
5799
  activeDetectionPrograms: activeProgramsResult.programs.map(
5762
- (program) => ({
5763
- language: program.language,
5764
- detectionProgram: {
5765
- mode: program.mode,
5766
- code: program.code,
5767
- sourceCodeState: program.sourceCodeState
5768
- }
5769
- })
5800
+ (item) => this.mapToActiveDetectionProgram(item, language)
5770
5801
  )
5771
5802
  }
5772
5803
  ]
@@ -5842,7 +5873,8 @@ var LintFilesAgainstRuleUseCase = class {
5842
5873
  ruleContent: rule.content,
5843
5874
  standardSlug: standard.slug,
5844
5875
  sourceCodeState: activeProgram.detectionProgram.sourceCodeState,
5845
- language: fileLanguage
5876
+ language: fileLanguage,
5877
+ severity: activeProgram.severity ?? "error" /* ERROR */
5846
5878
  });
5847
5879
  programsByLanguage.set(programLanguage, programsForLanguage);
5848
5880
  } catch (error) {
@@ -5925,8 +5957,8 @@ var LintFilesAgainstRuleUseCase = class {
5925
5957
  return null;
5926
5958
  }
5927
5959
  }
5928
- async executeProgramsForFile(command20) {
5929
- const result = await this.services.linterExecutionUseCase.execute(command20);
5960
+ async executeProgramsForFile(command21) {
5961
+ const result = await this.services.linterExecutionUseCase.execute(command21);
5930
5962
  return result.violations;
5931
5963
  }
5932
5964
  extractExtensionFromFile(filePath) {
@@ -5983,8 +6015,8 @@ var LintFilesFromConfigUseCase = class {
5983
6015
  }
5984
6016
  return pattern;
5985
6017
  }
5986
- async execute(command20) {
5987
- const { path: userPath, diffMode } = command20;
6018
+ async execute(command21) {
6019
+ const { path: userPath, diffMode } = command21;
5988
6020
  this.logger.debug(
5989
6021
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
5990
6022
  );
@@ -6088,6 +6120,7 @@ var LintFilesFromConfigUseCase = class {
6088
6120
  allConfigs.configs
6089
6121
  );
6090
6122
  const programsByLanguage = /* @__PURE__ */ new Map();
6123
+ const seenPrograms = /* @__PURE__ */ new Set();
6091
6124
  for (const targetConfig of matchingTargets) {
6092
6125
  const detectionPrograms = await this.getDetectionProgramsForTarget(targetConfig);
6093
6126
  for (const target of detectionPrograms.targets) {
@@ -6109,13 +6142,19 @@ var LintFilesFromConfigUseCase = class {
6109
6142
  if (!programLanguage || programLanguage !== fileLanguage) {
6110
6143
  continue;
6111
6144
  }
6145
+ const programKey = `${standard.slug}:${rule.content}:${activeProgram.language}`;
6146
+ if (seenPrograms.has(programKey)) {
6147
+ continue;
6148
+ }
6149
+ seenPrograms.add(programKey);
6112
6150
  const programsForLanguage = programsByLanguage.get(programLanguage) ?? [];
6113
6151
  programsForLanguage.push({
6114
6152
  code: activeProgram.detectionProgram.code,
6115
6153
  ruleContent: rule.content,
6116
6154
  standardSlug: standard.slug,
6117
6155
  sourceCodeState: activeProgram.detectionProgram.sourceCodeState,
6118
- language: fileLanguage
6156
+ language: fileLanguage,
6157
+ severity: activeProgram.severity ?? "error" /* ERROR */
6119
6158
  });
6120
6159
  programsByLanguage.set(programLanguage, programsForLanguage);
6121
6160
  } catch (error) {
@@ -6233,8 +6272,8 @@ var LintFilesFromConfigUseCase = class {
6233
6272
  return null;
6234
6273
  }
6235
6274
  }
6236
- async executeProgramsForFile(command20) {
6237
- const result = await this.services.linterExecutionUseCase.execute(command20);
6275
+ async executeProgramsForFile(command21) {
6276
+ const result = await this.services.linterExecutionUseCase.execute(command21);
6238
6277
  return result.violations;
6239
6278
  }
6240
6279
  extractExtensionFromFile(filePath) {
@@ -6300,10 +6339,10 @@ var PackmindHttpClient = class {
6300
6339
  return null;
6301
6340
  }
6302
6341
  }
6303
- async request(path14, options = {}) {
6342
+ async request(path18, options = {}) {
6304
6343
  const { host } = this.getAuthContext();
6305
6344
  const { method = "GET", body } = options;
6306
- const url = `${host}${path14}`;
6345
+ const url = `${host}${path18}`;
6307
6346
  try {
6308
6347
  const response = await fetch(url, {
6309
6348
  method,
@@ -6346,6 +6385,33 @@ var PackmindHttpClient = class {
6346
6385
  }
6347
6386
  };
6348
6387
 
6388
+ // apps/cli/src/infra/repositories/ChangeProposalGateway.ts
6389
+ var ChangeProposalGateway = class {
6390
+ constructor(httpClient) {
6391
+ this.httpClient = httpClient;
6392
+ this.batchCreate = async (command21) => {
6393
+ const { organizationId } = this.httpClient.getAuthContext();
6394
+ return this.httpClient.request(
6395
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/change-proposals/batch`,
6396
+ {
6397
+ method: "POST",
6398
+ body: { proposals: command21.proposals }
6399
+ }
6400
+ );
6401
+ };
6402
+ this.check = async (command21) => {
6403
+ const { organizationId } = this.httpClient.getAuthContext();
6404
+ return this.httpClient.request(
6405
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/change-proposals/check`,
6406
+ {
6407
+ method: "POST",
6408
+ body: { proposals: command21.proposals }
6409
+ }
6410
+ );
6411
+ };
6412
+ }
6413
+ };
6414
+
6349
6415
  // apps/cli/src/domain/errors/CommunityEditionError.ts
6350
6416
  var CommunityEditionError = class extends Error {
6351
6417
  constructor(feature) {
@@ -6360,13 +6426,13 @@ var CommunityEditionError = class extends Error {
6360
6426
  var LinterGateway = class {
6361
6427
  constructor(httpClient) {
6362
6428
  this.httpClient = httpClient;
6363
- this.getDraftDetectionProgramsForRule = async (command20) => {
6429
+ this.getDraftDetectionProgramsForRule = async (command21) => {
6364
6430
  const payload = {
6365
- standardSlug: command20.standardSlug,
6366
- ruleId: command20.ruleId
6431
+ standardSlug: command21.standardSlug,
6432
+ ruleId: command21.ruleId
6367
6433
  };
6368
- if (command20.language) {
6369
- payload.language = command20.language;
6434
+ if (command21.language) {
6435
+ payload.language = command21.language;
6370
6436
  }
6371
6437
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
6372
6438
  method: "POST",
@@ -6378,13 +6444,13 @@ var LinterGateway = class {
6378
6444
  }
6379
6445
  });
6380
6446
  };
6381
- this.getActiveDetectionProgramsForRule = async (command20) => {
6447
+ this.getActiveDetectionProgramsForRule = async (command21) => {
6382
6448
  const payload = {
6383
- standardSlug: command20.standardSlug,
6384
- ruleId: command20.ruleId
6449
+ standardSlug: command21.standardSlug,
6450
+ ruleId: command21.ruleId
6385
6451
  };
6386
- if (command20.language) {
6387
- payload.language = command20.language;
6452
+ if (command21.language) {
6453
+ payload.language = command21.language;
6388
6454
  }
6389
6455
  return this.httpClient.request("/api/v0/list-active-detection-program", {
6390
6456
  method: "POST",
@@ -6396,13 +6462,13 @@ var LinterGateway = class {
6396
6462
  }
6397
6463
  });
6398
6464
  };
6399
- this.getDetectionProgramsForPackages = async (command20) => {
6465
+ this.getDetectionProgramsForPackages = async (command21) => {
6400
6466
  const response = await this.httpClient.request(
6401
6467
  "/api/v0/detection-programs-for-packages",
6402
6468
  {
6403
6469
  method: "POST",
6404
6470
  body: {
6405
- packagesSlugs: command20.packagesSlugs
6471
+ packagesSlugs: command21.packagesSlugs
6406
6472
  },
6407
6473
  onError: (response2) => {
6408
6474
  if (response2.status === 404) {
@@ -6413,10 +6479,10 @@ var LinterGateway = class {
6413
6479
  );
6414
6480
  return handleScopeInTargetsResponse(response);
6415
6481
  };
6416
- this.trackLinterExecution = async (command20) => {
6482
+ this.trackLinterExecution = async (command21) => {
6417
6483
  return this.httpClient.request(`/api/v0/track-execution`, {
6418
6484
  method: "POST",
6419
- body: command20
6485
+ body: command21
6420
6486
  });
6421
6487
  };
6422
6488
  }
@@ -6474,27 +6540,27 @@ var SpacesGateway = class {
6474
6540
  var SkillsGateway = class {
6475
6541
  constructor(httpClient) {
6476
6542
  this.httpClient = httpClient;
6477
- this.upload = async (command20) => {
6543
+ this.upload = async (command21) => {
6478
6544
  const { organizationId } = this.httpClient.getAuthContext();
6479
6545
  return this.httpClient.request(
6480
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/skills/upload`,
6546
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/skills/upload`,
6481
6547
  {
6482
6548
  method: "POST",
6483
- body: command20
6549
+ body: command21
6484
6550
  }
6485
6551
  );
6486
6552
  };
6487
- this.getDefaults = async (command20) => {
6553
+ this.getDefaults = async (command21) => {
6488
6554
  const { organizationId } = this.httpClient.getAuthContext();
6489
6555
  const queryParams = new URLSearchParams();
6490
- if (command20.includeBeta) {
6556
+ if (command21.includeBeta) {
6491
6557
  queryParams.set("includeBeta", "true");
6492
- } else if (command20.cliVersion) {
6493
- queryParams.set("cliVersion", command20.cliVersion);
6558
+ } else if (command21.cliVersion) {
6559
+ queryParams.set("cliVersion", command21.cliVersion);
6494
6560
  }
6495
- if (command20.agents !== void 0) {
6561
+ if (command21.agents !== void 0) {
6496
6562
  queryParams.append("agentsConfigOverride", "true");
6497
- command20.agents.forEach((agent) => {
6563
+ command21.agents.forEach((agent) => {
6498
6564
  queryParams.append("agent", agent);
6499
6565
  });
6500
6566
  }
@@ -6503,10 +6569,10 @@ var SkillsGateway = class {
6503
6569
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
6504
6570
  );
6505
6571
  };
6506
- this.list = async (command20) => {
6572
+ this.list = async (command21) => {
6507
6573
  const { organizationId } = this.httpClient.getAuthContext();
6508
6574
  return this.httpClient.request(
6509
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/skills`
6575
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/skills`
6510
6576
  );
6511
6577
  };
6512
6578
  }
@@ -6516,17 +6582,17 @@ var SkillsGateway = class {
6516
6582
  var CommandsGateway = class {
6517
6583
  constructor(httpClient) {
6518
6584
  this.httpClient = httpClient;
6519
- this.create = async (command20) => {
6585
+ this.create = async (command21) => {
6520
6586
  const { organizationId } = this.httpClient.getAuthContext();
6521
6587
  return this.httpClient.request(
6522
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/recipes`,
6523
- { method: "POST", body: command20 }
6588
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/recipes`,
6589
+ { method: "POST", body: command21 }
6524
6590
  );
6525
6591
  };
6526
- this.list = async (command20) => {
6592
+ this.list = async (command21) => {
6527
6593
  const { organizationId } = this.httpClient.getAuthContext();
6528
6594
  const listRecipesResponse = await this.httpClient.request(
6529
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/recipes`
6595
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/recipes`
6530
6596
  );
6531
6597
  if (listRecipesResponse instanceof Array) {
6532
6598
  return { recipes: listRecipesResponse };
@@ -6568,10 +6634,10 @@ var StandardsGateway = class {
6568
6634
  }
6569
6635
  );
6570
6636
  };
6571
- this.list = async (command20) => {
6637
+ this.list = async (command21) => {
6572
6638
  const { organizationId } = this.httpClient.getAuthContext();
6573
6639
  return this.httpClient.request(
6574
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/standards`
6640
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/standards`
6575
6641
  );
6576
6642
  };
6577
6643
  }
@@ -6594,24 +6660,24 @@ var PackagesGateway = class {
6594
6660
  `/api/v0/organizations/${organizationId}/packages/${encodeURIComponent(slug)}`
6595
6661
  );
6596
6662
  };
6597
- this.create = async (command20) => {
6663
+ this.create = async (command21) => {
6598
6664
  const { organizationId } = this.httpClient.getAuthContext();
6599
6665
  return this.httpClient.request(
6600
- `/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/packages`,
6666
+ `/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/packages`,
6601
6667
  {
6602
6668
  method: "POST",
6603
- body: command20
6669
+ body: command21
6604
6670
  }
6605
6671
  );
6606
6672
  };
6607
- this.addArtefacts = async (command20) => {
6673
+ this.addArtefacts = async (command21) => {
6608
6674
  const { organizationId } = this.httpClient.getAuthContext();
6609
- const { packageId, spaceId } = command20;
6675
+ const { packageId, spaceId } = command21;
6610
6676
  return this.httpClient.request(
6611
6677
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
6612
6678
  {
6613
6679
  method: "POST",
6614
- body: command20
6680
+ body: command21
6615
6681
  }
6616
6682
  );
6617
6683
  };
@@ -6622,31 +6688,31 @@ var PackagesGateway = class {
6622
6688
  var DeploymentGateway = class {
6623
6689
  constructor(httpClient) {
6624
6690
  this.httpClient = httpClient;
6625
- this.pull = async (command20) => {
6691
+ this.pull = async (command21) => {
6626
6692
  const { organizationId } = this.httpClient.getAuthContext();
6627
6693
  const queryParams = new URLSearchParams();
6628
- if (command20.packagesSlugs && command20.packagesSlugs.length > 0) {
6629
- command20.packagesSlugs.forEach((slug) => {
6694
+ if (command21.packagesSlugs && command21.packagesSlugs.length > 0) {
6695
+ command21.packagesSlugs.forEach((slug) => {
6630
6696
  queryParams.append("packageSlug", slug);
6631
6697
  });
6632
6698
  }
6633
- if (command20.previousPackagesSlugs && command20.previousPackagesSlugs.length > 0) {
6634
- command20.previousPackagesSlugs.forEach((slug) => {
6699
+ if (command21.previousPackagesSlugs && command21.previousPackagesSlugs.length > 0) {
6700
+ command21.previousPackagesSlugs.forEach((slug) => {
6635
6701
  queryParams.append("previousPackageSlug", slug);
6636
6702
  });
6637
6703
  }
6638
- if (command20.gitRemoteUrl) {
6639
- queryParams.append("gitRemoteUrl", command20.gitRemoteUrl);
6704
+ if (command21.gitRemoteUrl) {
6705
+ queryParams.append("gitRemoteUrl", command21.gitRemoteUrl);
6640
6706
  }
6641
- if (command20.gitBranch) {
6642
- queryParams.append("gitBranch", command20.gitBranch);
6707
+ if (command21.gitBranch) {
6708
+ queryParams.append("gitBranch", command21.gitBranch);
6643
6709
  }
6644
- if (command20.relativePath) {
6645
- queryParams.append("relativePath", command20.relativePath);
6710
+ if (command21.relativePath) {
6711
+ queryParams.append("relativePath", command21.relativePath);
6646
6712
  }
6647
- if (command20.agents !== void 0) {
6713
+ if (command21.agents !== void 0) {
6648
6714
  queryParams.append("agentsConfigOverride", "true");
6649
- command20.agents.forEach((agent) => {
6715
+ command21.agents.forEach((agent) => {
6650
6716
  queryParams.append("agent", agent);
6651
6717
  });
6652
6718
  }
@@ -6654,13 +6720,29 @@ var DeploymentGateway = class {
6654
6720
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
6655
6721
  );
6656
6722
  };
6657
- this.notifyDistribution = async (command20) => {
6723
+ this.getDeployed = async (command21) => {
6724
+ const { organizationId } = this.httpClient.getAuthContext();
6725
+ return this.httpClient.request(
6726
+ `/api/v0/organizations/${organizationId}/deployed-content`,
6727
+ {
6728
+ method: "POST",
6729
+ body: {
6730
+ packagesSlugs: command21.packagesSlugs,
6731
+ gitRemoteUrl: command21.gitRemoteUrl,
6732
+ gitBranch: command21.gitBranch,
6733
+ relativePath: command21.relativePath,
6734
+ ...command21.agents !== void 0 && { agents: command21.agents }
6735
+ }
6736
+ }
6737
+ );
6738
+ };
6739
+ this.notifyDistribution = async (command21) => {
6658
6740
  const { organizationId } = this.httpClient.getAuthContext();
6659
6741
  return this.httpClient.request(
6660
6742
  `/api/v0/organizations/${organizationId}/deployments`,
6661
6743
  {
6662
6744
  method: "POST",
6663
- body: command20
6745
+ body: command21
6664
6746
  }
6665
6747
  );
6666
6748
  };
@@ -6678,6 +6760,7 @@ var PackmindGateway = class {
6678
6760
  constructor(apiKey) {
6679
6761
  this.apiKey = apiKey;
6680
6762
  this.httpClient = new PackmindHttpClient(apiKey);
6763
+ this.changeProposals = new ChangeProposalGateway(this.httpClient);
6681
6764
  this.linter = new LinterGateway(this.httpClient);
6682
6765
  this.mcp = new McpGateway(this.httpClient);
6683
6766
  this.spaces = new SpacesGateway(this.httpClient);
@@ -8429,8 +8512,8 @@ var ExecuteLinterProgramsUseCase = class {
8429
8512
  this.linterAstAdapter = linterAstAdapter;
8430
8513
  this.logger = logger2;
8431
8514
  }
8432
- async execute(command20) {
8433
- const { filePath, fileContent, language, programs } = command20;
8515
+ async execute(command21) {
8516
+ const { filePath, fileContent, language, programs } = command21;
8434
8517
  if (programs.length === 0) {
8435
8518
  return {
8436
8519
  file: filePath,
@@ -8573,7 +8656,8 @@ var ExecuteLinterProgramsUseCase = class {
8573
8656
  line,
8574
8657
  character,
8575
8658
  rule: ruleName,
8576
- standard: program.standardSlug
8659
+ standard: program.standardSlug,
8660
+ severity: program.severity
8577
8661
  };
8578
8662
  }
8579
8663
  isViolationLike(value) {
@@ -9100,15 +9184,114 @@ function removeTrailingSlash(url) {
9100
9184
  return url.endsWith("/") ? url.slice(0, -1) : url;
9101
9185
  }
9102
9186
 
9187
+ // packages/node-utils/src/skillMd/parseSkillMdContent.ts
9188
+ var import_yaml = require("yaml");
9189
+ var FRONTMATTER_DELIMITER = "---";
9190
+ function serializeSkillMetadata(fields) {
9191
+ const sorted = Object.keys(fields).sort((a, b) => a.localeCompare(b)).reduce(
9192
+ (acc, key) => {
9193
+ acc[key] = fields[key];
9194
+ return acc;
9195
+ },
9196
+ {}
9197
+ );
9198
+ return JSON.stringify(sorted);
9199
+ }
9200
+ function parseSkillMdContent(content) {
9201
+ try {
9202
+ const trimmed = content.trim();
9203
+ if (!trimmed.startsWith(FRONTMATTER_DELIMITER)) {
9204
+ return null;
9205
+ }
9206
+ const afterOpening = trimmed.slice(FRONTMATTER_DELIMITER.length);
9207
+ const closingIndex = afterOpening.indexOf(`
9208
+ ${FRONTMATTER_DELIMITER}`);
9209
+ if (closingIndex === -1) {
9210
+ return null;
9211
+ }
9212
+ const frontmatter = afterOpening.slice(0, closingIndex).trim();
9213
+ const body = afterOpening.slice(closingIndex + FRONTMATTER_DELIMITER.length + 1).trim();
9214
+ const parsed = (0, import_yaml.parse)(frontmatter);
9215
+ if (parsed === null || typeof parsed !== "object") {
9216
+ return null;
9217
+ }
9218
+ const { "allowed-tools": allowedTools, ...rest } = parsed;
9219
+ const properties = {
9220
+ ...rest,
9221
+ ...allowedTools !== void 0 && { allowedTools }
9222
+ };
9223
+ return { properties, body };
9224
+ } catch {
9225
+ return null;
9226
+ }
9227
+ }
9228
+
9229
+ // packages/node-utils/src/skillMd/parseSkillMd.ts
9230
+ function parseSkillMd(content) {
9231
+ const parsed = parseSkillMdContent(content);
9232
+ if (!parsed) {
9233
+ return null;
9234
+ }
9235
+ const { properties, body } = parsed;
9236
+ const name = String(properties["name"] ?? "");
9237
+ const description = String(properties["description"] ?? "");
9238
+ const license = String(properties["license"] ?? "");
9239
+ const compatibility = String(properties["compatibility"] ?? "");
9240
+ const allowedTools = String(properties["allowedTools"] ?? "");
9241
+ const metadata = properties["metadata"];
9242
+ const metadataJson = metadata != null && typeof metadata === "object" ? serializeSkillMetadata(metadata) : "{}";
9243
+ return {
9244
+ name,
9245
+ description,
9246
+ body,
9247
+ license,
9248
+ compatibility,
9249
+ allowedTools,
9250
+ metadataJson
9251
+ };
9252
+ }
9253
+
9103
9254
  // apps/cli/src/application/useCases/InstallPackagesUseCase.ts
9104
9255
  var fs4 = __toESM(require("fs/promises"));
9105
9256
  var path5 = __toESM(require("path"));
9257
+
9258
+ // apps/cli/src/infra/utils/permissions.ts
9259
+ var DEFAULT_PERMISSIONS = "rw-r--r--";
9260
+ function supportsUnixPermissions() {
9261
+ return process.platform !== "win32";
9262
+ }
9263
+ function modeToPermissionString(mode) {
9264
+ const perms = mode & 511;
9265
+ const chars = "rwx";
9266
+ let result = "";
9267
+ for (let i = 8; i >= 0; i--) {
9268
+ result += perms & 1 << i ? chars[(8 - i) % 3] : "-";
9269
+ }
9270
+ return result;
9271
+ }
9272
+ function modeToPermissionStringOrDefault(mode) {
9273
+ if (!supportsUnixPermissions()) {
9274
+ return DEFAULT_PERMISSIONS;
9275
+ }
9276
+ return modeToPermissionString(mode);
9277
+ }
9278
+ function parsePermissionString(permString) {
9279
+ let mode = 0;
9280
+ for (let i = 0; i < 9; i++) {
9281
+ if (permString[i] !== "-") {
9282
+ mode |= 1 << 8 - i;
9283
+ }
9284
+ }
9285
+ return mode;
9286
+ }
9287
+
9288
+ // apps/cli/src/application/useCases/InstallPackagesUseCase.ts
9106
9289
  var InstallPackagesUseCase = class {
9107
9290
  constructor(packmindGateway) {
9108
9291
  this.packmindGateway = packmindGateway;
9109
9292
  }
9110
- async execute(command20) {
9111
- const baseDirectory = command20.baseDirectory || process.cwd();
9293
+ async execute(command21) {
9294
+ const baseDirectory = command21.baseDirectory || process.cwd();
9112
9295
  const result = {
9113
9296
  filesCreated: 0,
9114
9297
  filesUpdated: 0,
@@ -9120,12 +9303,12 @@ var InstallPackagesUseCase = class {
9120
9303
  skillDirectoriesDeleted: 0
9121
9304
  };
9122
9305
  const response = await this.packmindGateway.deployment.pull({
9123
- packagesSlugs: command20.packagesSlugs,
9124
- previousPackagesSlugs: command20.previousPackagesSlugs,
9125
- gitRemoteUrl: command20.gitRemoteUrl,
9126
- gitBranch: command20.gitBranch,
9127
- relativePath: command20.relativePath,
9128
- agents: command20.agents
9306
+ packagesSlugs: command21.packagesSlugs,
9307
+ previousPackagesSlugs: command21.previousPackagesSlugs,
9308
+ gitRemoteUrl: command21.gitRemoteUrl,
9309
+ gitBranch: command21.gitBranch,
9310
+ relativePath: command21.relativePath,
9311
+ agents: command21.agents
9129
9312
  });
9130
9313
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
9131
9314
  (file) => file.path !== "packmind.json"
@@ -9151,7 +9334,12 @@ var InstallPackagesUseCase = class {
9151
9334
  );
9152
9335
  for (const file of uniqueFiles) {
9153
9336
  try {
9154
- await this.createOrUpdateFile(baseDirectory, file, result);
9337
+ await this.createOrUpdateFile(
9338
+ baseDirectory,
9339
+ file,
9340
+ result,
9341
+ file.skillFilePermissions
9342
+ );
9155
9343
  } catch (error) {
9156
9344
  const errorMsg = error instanceof Error ? error.message : String(error);
9157
9345
  result.errors.push(
@@ -9173,7 +9361,7 @@ var InstallPackagesUseCase = class {
9173
9361
  }
9174
9362
  return result;
9175
9363
  }
9176
- async createOrUpdateFile(baseDirectory, file, result) {
9364
+ async createOrUpdateFile(baseDirectory, file, result, skillFilePermissions) {
9177
9365
  const fullPath = path5.join(baseDirectory, file.path);
9178
9366
  const directory = path5.dirname(fullPath);
9179
9367
  await fs4.mkdir(directory, { recursive: true });
@@ -9195,6 +9383,9 @@ var InstallPackagesUseCase = class {
9195
9383
  baseDirectory
9196
9384
  );
9197
9385
  }
9386
+ if (skillFilePermissions && supportsUnixPermissions()) {
9387
+ await fs4.chmod(fullPath, parsePermissionString(skillFilePermissions));
9388
+ }
9198
9389
  }
9199
9390
  async handleFullContentUpdate(fullPath, content, fileExists, result, isBase64) {
9200
9391
  if (isBase64) {
@@ -9255,12 +9446,12 @@ var InstallPackagesUseCase = class {
9255
9446
  }
9256
9447
  async deleteFile(baseDirectory, filePath, result) {
9257
9448
  const fullPath = path5.join(baseDirectory, filePath);
9258
- const stat4 = await fs4.stat(fullPath).catch(() => null);
9259
- if (stat4?.isDirectory()) {
9449
+ const stat5 = await fs4.stat(fullPath).catch(() => null);
9450
+ if (stat5?.isDirectory()) {
9260
9451
  await fs4.rm(fullPath, { recursive: true, force: true });
9261
9452
  result.filesDeleted++;
9262
9453
  await this.removeEmptyParentDirectories(fullPath, baseDirectory);
9263
- } else if (stat4?.isFile()) {
9454
+ } else if (stat5?.isFile()) {
9264
9455
  await fs4.unlink(fullPath);
9265
9456
  result.filesDeleted++;
9266
9457
  await this.removeEmptyParentDirectories(fullPath, baseDirectory);
@@ -9403,8 +9594,8 @@ var InstallDefaultSkillsUseCase = class {
9403
9594
  constructor(repositories) {
9404
9595
  this.repositories = repositories;
9405
9596
  }
9406
- async execute(command20) {
9407
- const baseDirectory = command20.baseDirectory || process.cwd();
9597
+ async execute(command21) {
9598
+ const baseDirectory = command21.baseDirectory || process.cwd();
9408
9599
  const result = {
9409
9600
  filesCreated: 0,
9410
9601
  filesUpdated: 0,
@@ -9414,8 +9605,8 @@ var InstallDefaultSkillsUseCase = class {
9414
9605
  const agents = config?.agents;
9415
9606
  const response = await this.repositories.packmindGateway.skills.getDefaults(
9416
9607
  {
9417
- cliVersion: command20.cliVersion,
9418
- includeBeta: command20.includeBeta,
9608
+ cliVersion: command21.cliVersion,
9609
+ includeBeta: command21.includeBeta,
9419
9610
  agents
9420
9611
  }
9421
9612
  );
@@ -9480,8 +9671,8 @@ var GetPackageSummaryUseCase = class {
9480
9671
  constructor(gateway) {
9481
9672
  this.gateway = gateway;
9482
9673
  }
9483
- async execute(command20) {
9484
- return this.gateway.packages.getSummary(command20);
9674
+ async execute(command21) {
9675
+ return this.gateway.packages.getSummary(command21);
9485
9676
  }
9486
9677
  };
9487
9678
 
@@ -9760,8 +9951,8 @@ var LoginUseCase = class {
9760
9951
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
9761
9952
  };
9762
9953
  }
9763
- async execute(command20) {
9764
- const { host, code: providedCode } = command20;
9954
+ async execute(command21) {
9955
+ const { host, code: providedCode } = command21;
9765
9956
  let code;
9766
9957
  if (providedCode) {
9767
9958
  code = providedCode;
@@ -9799,8 +9990,8 @@ var LogoutUseCase = class {
9799
9990
  constructor(deps) {
9800
9991
  this.deps = {
9801
9992
  getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
9802
- fileExists: deps?.fileExists ?? ((path14) => fs7.existsSync(path14)),
9803
- deleteFile: deps?.deleteFile ?? ((path14) => fs7.unlinkSync(path14)),
9993
+ fileExists: deps?.fileExists ?? ((path18) => fs7.existsSync(path18)),
9994
+ deleteFile: deps?.deleteFile ?? ((path18) => fs7.unlinkSync(path18)),
9804
9995
  hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
9805
9996
  };
9806
9997
  }
@@ -9860,8 +10051,8 @@ var SetupMcpUseCase = class {
9860
10051
  constructor(deps) {
9861
10052
  this.deps = deps;
9862
10053
  }
9863
- async execute(command20) {
9864
- const { agentTypes } = command20;
10054
+ async execute(command21) {
10055
+ const { agentTypes } = command21;
9865
10056
  const [tokenResult, urlResult] = await Promise.all([
9866
10057
  this.deps.gateway.mcp.getToken({}),
9867
10058
  this.deps.gateway.mcp.getUrl({})
@@ -9932,9 +10123,9 @@ var McpConfigService = class {
9932
10123
  return JSON.stringify(mcpConfig, null, 2);
9933
10124
  }
9934
10125
  installClaudeMcp(config) {
9935
- const command20 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10126
+ const command21 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
9936
10127
  try {
9937
- (0, import_child_process2.execSync)(command20, { stdio: "pipe" });
10128
+ (0, import_child_process2.execSync)(command21, { stdio: "pipe" });
9938
10129
  return { success: true };
9939
10130
  } catch (error) {
9940
10131
  const execError = error;
@@ -10430,16 +10621,9 @@ var ListSkillsUseCase = class {
10430
10621
  var import_promises = __toESM(require("fs/promises"));
10431
10622
  var import_path2 = __toESM(require("path"));
10432
10623
  var import_minimatch3 = require("minimatch");
10433
- function normalizePath2(filePath) {
10434
- let normalized = filePath.replace(/\\/g, "/");
10435
- if (normalized.startsWith("/") || normalized.startsWith("\\")) {
10436
- normalized = normalized.substring(1);
10437
- }
10438
- return normalized;
10439
- }
10440
- function normalizeLineEndings(content) {
10441
- return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
10442
- }
10624
+
10625
+ // apps/cli/src/infra/utils/binaryDetection.ts
10626
+ var path10 = __toESM(require("path"));
10443
10627
  var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
10444
10628
  // Images
10445
10629
  ".png",
@@ -10497,7 +10681,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
10497
10681
  ".sqlite3"
10498
10682
  ]);
10499
10683
  function isBinaryExtension(filePath) {
10500
- const ext = import_path2.default.extname(filePath).toLowerCase();
10684
+ const ext = path10.extname(filePath).toLowerCase();
10501
10685
  return BINARY_EXTENSIONS.has(ext);
10502
10686
  }
10503
10687
  function isBinaryBuffer(buffer) {
@@ -10506,6 +10690,18 @@ function isBinaryBuffer(buffer) {
10506
10690
  function isBinaryFile(filePath, buffer) {
10507
10691
  return isBinaryExtension(filePath) || isBinaryBuffer(buffer);
10508
10692
  }
10693
+
10694
+ // apps/cli/src/infra/utils/readSkillDirectory.ts
10695
+ function normalizePath2(filePath) {
10696
+ let normalized = filePath.replace(/\\/g, "/");
10697
+ if (normalized.startsWith("/") || normalized.startsWith("\\")) {
10698
+ normalized = normalized.substring(1);
10699
+ }
10700
+ return normalized;
10701
+ }
10702
+ function normalizeLineEndings(content) {
10703
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
10704
+ }
10509
10705
  var MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
10510
10706
  var MAX_FILE_SIZE_MB = 10;
10511
10707
  var BLACKLIST_PATTERNS = ["**/.DS_Store"];
@@ -10528,9 +10724,9 @@ async function readSkillDirectory(dirPath) {
10528
10724
  if (entry.isDirectory()) {
10529
10725
  await readDir(fullPath, basePath);
10530
10726
  } else if (entry.isFile()) {
10531
- const stat4 = await import_promises.default.stat(fullPath);
10532
- if (stat4.size > MAX_FILE_SIZE_BYTES) {
10533
- const fileSizeMB = (stat4.size / (1024 * 1024)).toFixed(2);
10727
+ const stat5 = await import_promises.default.stat(fullPath);
10728
+ if (stat5.size > MAX_FILE_SIZE_BYTES) {
10729
+ const fileSizeMB = (stat5.size / (1024 * 1024)).toFixed(2);
10534
10730
  throw new Error(
10535
10731
  `File "${relativePath}" is ${fileSizeMB} MB which exceeds the maximum allowed size of ${MAX_FILE_SIZE_MB} MB per file.`
10536
10732
  );
@@ -10549,8 +10745,7 @@ async function readSkillDirectory(dirPath) {
10549
10745
  relativePath: normalizedPath,
10550
10746
  content,
10551
10747
  size: Buffer.byteLength(content, isBinary ? "base64" : "utf-8"),
10552
- permissions: "rw-r--r--",
10553
- // Simple default
10748
+ permissions: modeToPermissionStringOrDefault(stat5.mode),
10554
10749
  isBase64: isBinary
10555
10750
  });
10556
10751
  }
@@ -10565,8 +10760,8 @@ var UploadSkillUseCase = class {
10565
10760
  constructor(deps) {
10566
10761
  this.deps = deps;
10567
10762
  }
10568
- async execute(command20) {
10569
- const files = await readSkillDirectory(command20.skillPath);
10763
+ async execute(command21) {
10764
+ const files = await readSkillDirectory(command21.skillPath);
10570
10765
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
10571
10766
  throw new Error("SKILL.md not found in skill directory");
10572
10767
  }
@@ -10592,7 +10787,7 @@ var UploadSkillUseCase = class {
10592
10787
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
10593
10788
  spaceId: createSpaceId(space.id),
10594
10789
  files: payload.files,
10595
- originSkill: command20.originSkill
10790
+ originSkill: command21.originSkill
10596
10791
  });
10597
10792
  return {
10598
10793
  skillId: uploadSkillResponse.skill.id,
@@ -10606,121 +10801,1072 @@ var UploadSkillUseCase = class {
10606
10801
  }
10607
10802
  };
10608
10803
 
10609
- // apps/cli/src/PackmindCliHexaFactory.ts
10610
- var PackmindCliHexaFactory = class {
10611
- constructor() {
10612
- this.repositories = {
10613
- packmindGateway: new PackmindGateway(loadApiKey()),
10614
- configFileRepository: new ConfigFileRepository()
10615
- };
10616
- this.services = {
10617
- listFiles: new ListFiles(),
10618
- gitRemoteUrlService: new GitService(),
10619
- linterExecutionUseCase: new ExecuteLinterProgramsUseCase(),
10620
- diffViolationFilterService: new DiffViolationFilterService()
10621
- };
10622
- this.useCases = {
10623
- executeSingleFileAst: new ExecuteSingleFileAstUseCase(
10624
- this.services.linterExecutionUseCase
10625
- ),
10626
- getGitRemoteUrl: new GetGitRemoteUrlUseCase(),
10627
- listFilesInDirectoryUseCase: new ListFilesInDirectoryUseCase(),
10628
- lintFilesAgainstRule: new LintFilesAgainstRuleUseCase(
10629
- this.services,
10630
- this.repositories
10631
- ),
10632
- lintFilesFromConfig: new LintFilesFromConfigUseCase(
10633
- this.services,
10634
- this.repositories
10635
- ),
10636
- installPackages: new InstallPackagesUseCase(
10637
- this.repositories.packmindGateway
10638
- ),
10639
- installDefaultSkills: new InstallDefaultSkillsUseCase(this.repositories),
10640
- listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
10641
- getPackageBySlug: new GetPackageSummaryUseCase(
10642
- this.repositories.packmindGateway
10643
- ),
10644
- login: new LoginUseCase(),
10645
- logout: new LogoutUseCase(),
10646
- whoami: new WhoamiUseCase(),
10647
- setupMcp: new SetupMcpUseCase({
10648
- gateway: this.repositories.packmindGateway,
10649
- mcpConfigService: new McpConfigService()
10650
- }),
10651
- listStandards: new ListStandardsUseCase(
10652
- this.repositories.packmindGateway
10653
- ),
10654
- listCommands: new ListCommandsUseCase(this.repositories.packmindGateway),
10655
- listSkills: new ListSkillsUseCase(this.repositories.packmindGateway),
10656
- uploadSkill: new UploadSkillUseCase({
10657
- gateway: this.repositories.packmindGateway
10658
- })
10659
- };
10804
+ // apps/cli/src/application/useCases/diffStrategies/CommandDiffStrategy.ts
10805
+ var import_diff = require("diff");
10806
+ var fs11 = __toESM(require("fs/promises"));
10807
+ var path12 = __toESM(require("path"));
10808
+
10809
+ // apps/cli/src/application/utils/stripFrontmatter.ts
10810
+ var FRONTMATTER_DELIMITER2 = "---";
10811
+ function stripFrontmatter(content) {
10812
+ if (!content.startsWith(`${FRONTMATTER_DELIMITER2}
10813
+ `)) {
10814
+ return content;
10815
+ }
10816
+ const contentAfterOpening = content.slice(FRONTMATTER_DELIMITER2.length + 1);
10817
+ const closingIndex = contentAfterOpening.indexOf(
10818
+ `
10819
+ ${FRONTMATTER_DELIMITER2}`
10820
+ );
10821
+ if (closingIndex === -1) {
10822
+ return content;
10660
10823
  }
10661
- };
10824
+ return contentAfterOpening.slice(closingIndex + FRONTMATTER_DELIMITER2.length + 1).trimStart();
10825
+ }
10662
10826
 
10663
- // apps/cli/src/PackmindCliHexa.ts
10664
- var origin8 = "PackmindCliHexa";
10665
- var PackmindCliHexa = class {
10666
- constructor(logger2 = new PackmindLogger(origin8)) {
10667
- this.notifyDistribution = async (command20) => {
10668
- return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
10669
- command20
10670
- );
10671
- };
10672
- this.logger = logger2;
10827
+ // apps/cli/src/application/useCases/diffStrategies/CommandDiffStrategy.ts
10828
+ var CommandDiffStrategy = class {
10829
+ supports(file) {
10830
+ return file.artifactType === "command";
10831
+ }
10832
+ async diff(file, baseDirectory) {
10833
+ const fullPath = path12.join(baseDirectory, file.path);
10834
+ let localContent;
10673
10835
  try {
10674
- this.hexa = new PackmindCliHexaFactory();
10675
- } catch (error) {
10676
- this.logger.error("Failed to initialize PackmindCliHexa", {
10677
- error: error instanceof Error ? error.message : String(error)
10678
- });
10679
- throw error;
10836
+ localContent = await fs11.readFile(fullPath, "utf-8");
10837
+ } catch {
10838
+ return [];
10680
10839
  }
10840
+ const serverBody = stripFrontmatter(file.content);
10841
+ const localBody = stripFrontmatter(localContent);
10842
+ const changes = (0, import_diff.diffLines)(serverBody, localBody);
10843
+ const hasDifferences = changes.some(
10844
+ (change) => change.added || change.removed
10845
+ );
10846
+ if (!hasDifferences) {
10847
+ return [];
10848
+ }
10849
+ return [
10850
+ {
10851
+ filePath: file.path,
10852
+ type: "updateCommandDescription" /* updateCommandDescription */,
10853
+ payload: {
10854
+ oldValue: serverBody,
10855
+ newValue: localBody
10856
+ },
10857
+ artifactName: file.artifactName,
10858
+ artifactType: file.artifactType,
10859
+ artifactId: file.artifactId,
10860
+ spaceId: file.spaceId
10861
+ }
10862
+ ];
10681
10863
  }
10682
- /**
10683
- * Destroys the DeploymentsHexa and cleans up resources
10684
- */
10685
- destroy() {
10686
- this.logger.info("Destroying PackmindCliHexa");
10687
- this.logger.info("PackmindCliHexa destroyed");
10688
- }
10689
- async getGitRemoteUrl(command20) {
10690
- return this.hexa.useCases.getGitRemoteUrl.execute(command20);
10864
+ };
10865
+
10866
+ // apps/cli/src/application/useCases/diffStrategies/SkillDiffStrategy.ts
10867
+ var import_diff2 = require("diff");
10868
+ var fs12 = __toESM(require("fs/promises"));
10869
+ var path13 = __toESM(require("path"));
10870
+ var SkillDiffStrategy = class {
10871
+ supports(file) {
10872
+ return file.artifactType === "skill";
10691
10873
  }
10692
- async executeSingleFileAst(command20) {
10693
- return this.hexa.useCases.executeSingleFileAst.execute(command20);
10874
+ async diff(file, baseDirectory, context) {
10875
+ if (file.path.endsWith("/SKILL.md")) {
10876
+ return this.diffSkillMd(file, baseDirectory);
10877
+ }
10878
+ return this.diffSkillFile(file, baseDirectory, context?.skillFolders ?? []);
10694
10879
  }
10695
- async listFilesInDirectory(command20) {
10696
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command20);
10880
+ async diffNewFiles(skillFolders, serverFiles, baseDirectory) {
10881
+ const diffs = [];
10882
+ for (const folder of skillFolders) {
10883
+ const folderPath = path13.join(baseDirectory, folder);
10884
+ const localFiles = await this.listFilesRecursively(folderPath);
10885
+ const serverPathsInFolder = new Set(
10886
+ serverFiles.filter((f) => f.path.startsWith(folder + "/")).map((f) => f.path)
10887
+ );
10888
+ const skillMdFile = serverFiles.find(
10889
+ (f) => f.path === `${folder}/SKILL.md` && f.artifactType === "skill"
10890
+ );
10891
+ if (!skillMdFile) {
10892
+ continue;
10893
+ }
10894
+ for (const relativePath of localFiles) {
10895
+ if (relativePath === "SKILL.md") {
10896
+ continue;
10897
+ }
10898
+ const filePath = `${folder}/${relativePath}`;
10899
+ if (serverPathsInFolder.has(filePath)) {
10900
+ continue;
10901
+ }
10902
+ const fullPath = path13.join(baseDirectory, filePath);
10903
+ const localRead = await this.tryReadFileBinaryAware(fullPath);
10904
+ if (localRead === null) {
10905
+ continue;
10906
+ }
10907
+ const permissions = await this.tryGetPermissions(fullPath) ?? "rw-r--r--";
10908
+ diffs.push({
10909
+ filePath,
10910
+ type: "addSkillFile" /* addSkillFile */,
10911
+ payload: {
10912
+ item: {
10913
+ path: relativePath,
10914
+ content: localRead.content,
10915
+ permissions,
10916
+ isBase64: localRead.isBase64
10917
+ }
10918
+ },
10919
+ artifactName: skillMdFile.artifactName,
10920
+ artifactType: "skill",
10921
+ artifactId: skillMdFile.artifactId,
10922
+ spaceId: skillMdFile.spaceId
10923
+ });
10924
+ }
10925
+ }
10926
+ return diffs;
10697
10927
  }
10698
- async lintFilesAgainstRule(command20) {
10699
- return this.hexa.useCases.lintFilesAgainstRule.execute(command20);
10928
+ async diffSkillMd(file, baseDirectory) {
10929
+ const fullPath = path13.join(baseDirectory, file.path);
10930
+ const localContent = await this.tryReadFile(fullPath);
10931
+ if (localContent === null) {
10932
+ return [];
10933
+ }
10934
+ const serverParsed = parseSkillMd(file.content);
10935
+ const localParsed = parseSkillMd(localContent);
10936
+ if (!serverParsed || !localParsed) {
10937
+ const serverBody = stripFrontmatter(file.content);
10938
+ const localBody = stripFrontmatter(localContent);
10939
+ const changes = (0, import_diff2.diffLines)(serverBody, localBody);
10940
+ const hasDifferences = changes.some(
10941
+ (change) => change.added || change.removed
10942
+ );
10943
+ if (!hasDifferences) {
10944
+ return [];
10945
+ }
10946
+ return [
10947
+ {
10948
+ filePath: file.path,
10949
+ type: "updateSkillPrompt" /* updateSkillPrompt */,
10950
+ payload: { oldValue: serverBody, newValue: localBody },
10951
+ artifactName: file.artifactName,
10952
+ artifactType: file.artifactType,
10953
+ artifactId: file.artifactId,
10954
+ spaceId: file.spaceId
10955
+ }
10956
+ ];
10957
+ }
10958
+ const baseDiff = {
10959
+ filePath: file.path,
10960
+ artifactName: file.artifactName,
10961
+ artifactType: file.artifactType,
10962
+ artifactId: file.artifactId,
10963
+ spaceId: file.spaceId
10964
+ };
10965
+ const checks = [
10966
+ this.checkUpdateSkillName(serverParsed, localParsed, baseDiff),
10967
+ this.checkUpdateSkillDescription(serverParsed, localParsed, baseDiff),
10968
+ this.checkUpdateSkillPrompt(serverParsed, localParsed, baseDiff),
10969
+ this.checkUpdateSkillMetadata(serverParsed, localParsed, baseDiff),
10970
+ this.checkUpdateSkillLicense(serverParsed, localParsed, baseDiff),
10971
+ this.checkUpdateSkillCompatibility(serverParsed, localParsed, baseDiff),
10972
+ this.checkUpdateSkillAllowedTools(serverParsed, localParsed, baseDiff)
10973
+ ];
10974
+ return checks.filter((d) => d !== null);
10700
10975
  }
10701
- async lintFilesFromConfig(command20) {
10702
- return this.hexa.useCases.lintFilesFromConfig.execute(command20);
10976
+ async diffSkillFile(file, baseDirectory, skillFolders) {
10977
+ if (!file.skillFileId) {
10978
+ return [];
10979
+ }
10980
+ const skillFileId = createSkillFileId(file.skillFileId);
10981
+ const fullPath = path13.join(baseDirectory, file.path);
10982
+ const localRead = await this.tryReadFileBinaryAware(fullPath);
10983
+ const fileRelativePath = this.computeRelativePath(file.path, skillFolders);
10984
+ if (localRead === null) {
10985
+ return [
10986
+ {
10987
+ filePath: file.path,
10988
+ type: "deleteSkillFile" /* deleteSkillFile */,
10989
+ payload: {
10990
+ targetId: skillFileId,
10991
+ item: {
10992
+ id: skillFileId,
10993
+ path: fileRelativePath,
10994
+ content: file.content,
10995
+ permissions: file.skillFilePermissions ?? "read",
10996
+ isBase64: file.isBase64 ?? false
10997
+ }
10998
+ },
10999
+ artifactName: file.artifactName,
11000
+ artifactType: file.artifactType,
11001
+ artifactId: file.artifactId,
11002
+ spaceId: file.spaceId
11003
+ }
11004
+ ];
11005
+ }
11006
+ const baseDiff = {
11007
+ filePath: file.path,
11008
+ artifactName: file.artifactName,
11009
+ artifactType: file.artifactType,
11010
+ artifactId: file.artifactId,
11011
+ spaceId: file.spaceId
11012
+ };
11013
+ const checks = await Promise.all([
11014
+ this.checkUpdateSkillFileContent(
11015
+ file,
11016
+ localRead.content,
11017
+ localRead.isBase64,
11018
+ skillFileId,
11019
+ baseDiff
11020
+ ),
11021
+ this.checkUpdateSkillFilePermissions(
11022
+ file,
11023
+ fullPath,
11024
+ skillFileId,
11025
+ baseDiff
11026
+ )
11027
+ ]);
11028
+ return checks.filter((d) => d !== null);
10703
11029
  }
10704
- async installPackages(command20) {
10705
- return this.hexa.useCases.installPackages.execute(command20);
11030
+ checkUpdateSkillName(serverParsed, localParsed, baseDiff) {
11031
+ if (serverParsed.name === localParsed.name) {
11032
+ return null;
11033
+ }
11034
+ return {
11035
+ ...baseDiff,
11036
+ type: "updateSkillName" /* updateSkillName */,
11037
+ payload: { oldValue: serverParsed.name, newValue: localParsed.name }
11038
+ };
10706
11039
  }
10707
- async listPackages(command20) {
10708
- return this.hexa.useCases.listPackages.execute(command20);
11040
+ checkUpdateSkillDescription(serverParsed, localParsed, baseDiff) {
11041
+ if (serverParsed.description === localParsed.description) {
11042
+ return null;
11043
+ }
11044
+ return {
11045
+ ...baseDiff,
11046
+ type: "updateSkillDescription" /* updateSkillDescription */,
11047
+ payload: {
11048
+ oldValue: serverParsed.description,
11049
+ newValue: localParsed.description
11050
+ }
11051
+ };
10709
11052
  }
10710
- async getPackageBySlug(command20) {
10711
- return this.hexa.useCases.getPackageBySlug.execute(command20);
11053
+ checkUpdateSkillPrompt(serverParsed, localParsed, baseDiff) {
11054
+ if (serverParsed.body === localParsed.body) {
11055
+ return null;
11056
+ }
11057
+ return {
11058
+ ...baseDiff,
11059
+ type: "updateSkillPrompt" /* updateSkillPrompt */,
11060
+ payload: { oldValue: serverParsed.body, newValue: localParsed.body }
11061
+ };
10712
11062
  }
10713
- async listStandards(command20) {
10714
- return this.hexa.useCases.listStandards.execute(command20);
11063
+ checkUpdateSkillMetadata(serverParsed, localParsed, baseDiff) {
11064
+ if (serverParsed.metadataJson === localParsed.metadataJson) {
11065
+ return null;
11066
+ }
11067
+ return {
11068
+ ...baseDiff,
11069
+ type: "updateSkillMetadata" /* updateSkillMetadata */,
11070
+ payload: {
11071
+ oldValue: serverParsed.metadataJson,
11072
+ newValue: localParsed.metadataJson
11073
+ }
11074
+ };
10715
11075
  }
10716
- async listCommands(command20) {
10717
- return this.hexa.useCases.listCommands.execute(command20);
11076
+ checkUpdateSkillLicense(serverParsed, localParsed, baseDiff) {
11077
+ if (serverParsed.license === localParsed.license) {
11078
+ return null;
11079
+ }
11080
+ return {
11081
+ ...baseDiff,
11082
+ type: "updateSkillLicense" /* updateSkillLicense */,
11083
+ payload: {
11084
+ oldValue: serverParsed.license,
11085
+ newValue: localParsed.license
11086
+ }
11087
+ };
10718
11088
  }
10719
- async listSkills(command20) {
10720
- return this.hexa.useCases.listSkills.execute(command20);
11089
+ checkUpdateSkillCompatibility(serverParsed, localParsed, baseDiff) {
11090
+ if (serverParsed.compatibility === localParsed.compatibility) {
11091
+ return null;
11092
+ }
11093
+ return {
11094
+ ...baseDiff,
11095
+ type: "updateSkillCompatibility" /* updateSkillCompatibility */,
11096
+ payload: {
11097
+ oldValue: serverParsed.compatibility,
11098
+ newValue: localParsed.compatibility
11099
+ }
11100
+ };
10721
11101
  }
10722
- async configExists(baseDirectory) {
10723
- return await this.hexa.repositories.configFileRepository.configExists(
11102
+ checkUpdateSkillAllowedTools(serverParsed, localParsed, baseDiff) {
11103
+ if (serverParsed.allowedTools === localParsed.allowedTools) {
11104
+ return null;
11105
+ }
11106
+ return {
11107
+ ...baseDiff,
11108
+ type: "updateSkillAllowedTools" /* updateSkillAllowedTools */,
11109
+ payload: {
11110
+ oldValue: serverParsed.allowedTools,
11111
+ newValue: localParsed.allowedTools
11112
+ }
11113
+ };
11114
+ }
11115
+ checkUpdateSkillFileContent(file, localContent, localIsBase64, skillFileId, baseDiff) {
11116
+ const isBinary = localIsBase64 || (file.isBase64 ?? false);
11117
+ if (isBinary) {
11118
+ if (localContent === file.content) {
11119
+ return null;
11120
+ }
11121
+ return {
11122
+ ...baseDiff,
11123
+ type: "updateSkillFileContent" /* updateSkillFileContent */,
11124
+ payload: {
11125
+ targetId: skillFileId,
11126
+ oldValue: file.content,
11127
+ newValue: localContent,
11128
+ isBase64: true
11129
+ }
11130
+ };
11131
+ }
11132
+ if (localContent === file.content) {
11133
+ return null;
11134
+ }
11135
+ return {
11136
+ ...baseDiff,
11137
+ type: "updateSkillFileContent" /* updateSkillFileContent */,
11138
+ payload: {
11139
+ targetId: skillFileId,
11140
+ oldValue: file.content,
11141
+ newValue: localContent,
11142
+ isBase64: false
11143
+ }
11144
+ };
11145
+ }
11146
+ async checkUpdateSkillFilePermissions(file, fullPath, skillFileId, baseDiff) {
11147
+ if (!file.skillFilePermissions) {
11148
+ return null;
11149
+ }
11150
+ const localPermissions = await this.tryGetPermissions(fullPath);
11151
+ if (!localPermissions || localPermissions === file.skillFilePermissions) {
11152
+ return null;
11153
+ }
11154
+ return {
11155
+ ...baseDiff,
11156
+ type: "updateSkillFilePermissions" /* updateSkillFilePermissions */,
11157
+ payload: {
11158
+ targetId: skillFileId,
11159
+ oldValue: file.skillFilePermissions,
11160
+ newValue: localPermissions
11161
+ }
11162
+ };
11163
+ }
11164
+ async tryReadFile(filePath) {
11165
+ try {
11166
+ return await fs12.readFile(filePath, "utf-8");
11167
+ } catch {
11168
+ return null;
11169
+ }
11170
+ }
11171
+ async tryReadFileBinaryAware(filePath) {
11172
+ try {
11173
+ const buffer = await fs12.readFile(filePath);
11174
+ if (isBinaryFile(filePath, buffer)) {
11175
+ return { content: buffer.toString("base64"), isBase64: true };
11176
+ }
11177
+ return { content: buffer.toString("utf-8"), isBase64: false };
11178
+ } catch {
11179
+ return null;
11180
+ }
11181
+ }
11182
+ async listFilesRecursively(dirPath, prefix = "") {
11183
+ let entries;
11184
+ try {
11185
+ entries = await fs12.readdir(dirPath);
11186
+ } catch {
11187
+ return [];
11188
+ }
11189
+ const files = [];
11190
+ for (const entry of entries) {
11191
+ const fullPath = path13.join(dirPath, entry);
11192
+ const stat5 = await this.tryStatFile(fullPath);
11193
+ if (!stat5) {
11194
+ continue;
11195
+ }
11196
+ const relativePath = prefix ? `${prefix}/${entry}` : entry;
11197
+ if (stat5.isDirectory) {
11198
+ const subFiles = await this.listFilesRecursively(
11199
+ fullPath,
11200
+ relativePath
11201
+ );
11202
+ files.push(...subFiles);
11203
+ } else {
11204
+ files.push(relativePath);
11205
+ }
11206
+ }
11207
+ return files;
11208
+ }
11209
+ async tryStatFile(filePath) {
11210
+ try {
11211
+ const stat5 = await fs12.stat(filePath);
11212
+ return { isDirectory: stat5.isDirectory() };
11213
+ } catch {
11214
+ return null;
11215
+ }
11216
+ }
11217
+ async tryGetPermissions(filePath) {
11218
+ try {
11219
+ const stat5 = await fs12.stat(filePath);
11220
+ return modeToPermissionStringOrDefault(stat5.mode);
11221
+ } catch {
11222
+ return null;
11223
+ }
11224
+ }
11225
+ computeRelativePath(filePath, skillFolders) {
11226
+ const skillFolder = skillFolders.find((f) => filePath.startsWith(f + "/"));
11227
+ if (skillFolder) {
11228
+ return filePath.slice(skillFolder.length + 1);
11229
+ }
11230
+ return filePath.split("/").slice(3).join("/");
11231
+ }
11232
+ };
11233
+
11234
+ // apps/cli/src/application/useCases/diffStrategies/StandardDiffStrategy.ts
11235
+ var fs13 = __toESM(require("fs/promises"));
11236
+ var path14 = __toESM(require("path"));
11237
+
11238
+ // apps/cli/src/application/utils/parseStandardMd.ts
11239
+ var DEPLOYER_PARSERS = [
11240
+ { pattern: ".packmind/standards/", parse: parsePackmindStandard },
11241
+ { pattern: ".claude/rules/packmind/standard-", parse: parseClaudeStandard },
11242
+ { pattern: ".cursor/rules/packmind/standard-", parse: parseCursorStandard },
11243
+ {
11244
+ pattern: ".continue/rules/packmind/standard-",
11245
+ parse: parseContinueStandard
11246
+ },
11247
+ { pattern: ".github/instructions/packmind-", parse: parseCopilotStandard }
11248
+ ];
11249
+ function parseStandardMd(content, filePath) {
11250
+ const deployer = DEPLOYER_PARSERS.find((d) => filePath.includes(d.pattern));
11251
+ if (!deployer) {
11252
+ return null;
11253
+ }
11254
+ return deployer.parse(content);
11255
+ }
11256
+ function parsePackmindStandard(content) {
11257
+ const lines = content.split("\n");
11258
+ let name = null;
11259
+ let nameLineIndex = -1;
11260
+ for (let i = 0; i < lines.length; i++) {
11261
+ if (lines[i].startsWith("# ") && !lines[i].startsWith("## ")) {
11262
+ const extracted = lines[i].slice(2).trim();
11263
+ if (extracted) {
11264
+ name = extracted;
11265
+ nameLineIndex = i;
11266
+ break;
11267
+ }
11268
+ }
11269
+ }
11270
+ if (!name) {
11271
+ return null;
11272
+ }
11273
+ let rulesLineIndex = -1;
11274
+ for (let i = nameLineIndex + 1; i < lines.length; i++) {
11275
+ if (lines[i].trim() === "## Rules") {
11276
+ rulesLineIndex = i;
11277
+ break;
11278
+ }
11279
+ }
11280
+ const descriptionLines = [];
11281
+ let rulesStartIndex = -1;
11282
+ if (rulesLineIndex >= 0) {
11283
+ for (let i = nameLineIndex + 1; i < rulesLineIndex; i++) {
11284
+ descriptionLines.push(lines[i]);
11285
+ }
11286
+ rulesStartIndex = rulesLineIndex + 1;
11287
+ } else {
11288
+ for (let i = nameLineIndex + 1; i < lines.length; i++) {
11289
+ if (lines[i].startsWith("* ") || lines[i].startsWith("- ")) {
11290
+ rulesStartIndex = i;
11291
+ break;
11292
+ }
11293
+ descriptionLines.push(lines[i]);
11294
+ }
11295
+ }
11296
+ const rules = extractRulesList(lines, rulesStartIndex);
11297
+ return {
11298
+ name,
11299
+ description: descriptionLines.join("\n").trim(),
11300
+ scope: "",
11301
+ rules
11302
+ };
11303
+ }
11304
+ function parseClaudeStandard(content) {
11305
+ const { frontmatter, body } = extractFrontmatter(content);
11306
+ const scope = extractScopeFromKey(frontmatter, "paths");
11307
+ const parsed = parseIdeStandardBody(body, scope);
11308
+ if (!parsed) return null;
11309
+ return addFrontmatterFields(parsed, frontmatter);
11310
+ }
11311
+ function parseCursorStandard(content) {
11312
+ const { frontmatter, body } = extractFrontmatter(content);
11313
+ const scope = extractScopeFromKey(frontmatter, "globs");
11314
+ return parseIdeStandardBody(body, scope);
11315
+ }
11316
+ function parseContinueStandard(content) {
11317
+ const { frontmatter, body } = extractFrontmatter(content);
11318
+ const scope = extractScopeFromKey(frontmatter, "globs");
11319
+ const parsed = parseIdeStandardBody(body, scope);
11320
+ if (!parsed) return null;
11321
+ return addFrontmatterFields(parsed, frontmatter);
11322
+ }
11323
+ function parseCopilotStandard(content) {
11324
+ const { frontmatter, body } = extractFrontmatter(content);
11325
+ const rawScope = extractFrontmatterValue(frontmatter, "applyTo");
11326
+ let scope = "";
11327
+ if (rawScope) {
11328
+ const stripped = rawScope.replace(/(?:^['"])|(?:['"]$)/g, "");
11329
+ scope = stripped === "**" ? "" : stripped;
11330
+ }
11331
+ return parseIdeStandardBody(body, scope);
11332
+ }
11333
+ var RULES_FALLBACK = "No rules defined yet.";
11334
+ function extractRulesList(lines, startIndex) {
11335
+ if (startIndex < 0) return [];
11336
+ const rules = [];
11337
+ for (let i = startIndex; i < lines.length; i++) {
11338
+ const line = lines[i];
11339
+ if (line.startsWith("* ") || line.startsWith("- ")) {
11340
+ const content = line.slice(2).trim();
11341
+ if (content && content !== RULES_FALLBACK) {
11342
+ rules.push(content);
11343
+ }
11344
+ } else if (line.startsWith("Full standard is available")) {
11345
+ break;
11346
+ } else if (line.startsWith("## ")) {
11347
+ break;
11348
+ }
11349
+ }
11350
+ return rules;
11351
+ }
11352
+ function extractFrontmatter(content) {
11353
+ const match = content.match(/^---\n([\s\S]*?)\n---\n?/);
11354
+ if (!match) {
11355
+ return { frontmatter: "", body: content };
11356
+ }
11357
+ return {
11358
+ frontmatter: match[1],
11359
+ body: content.slice(match[0].length)
11360
+ };
11361
+ }
11362
+ function parseIdeStandardBody(body, scope) {
11363
+ const lines = body.split("\n");
11364
+ let name = null;
11365
+ let nameLineIndex = -1;
11366
+ for (let i = 0; i < lines.length; i++) {
11367
+ if (lines[i].startsWith("## Standard: ")) {
11368
+ const extracted = lines[i].slice("## Standard: ".length).trim();
11369
+ if (extracted) {
11370
+ name = extracted;
11371
+ nameLineIndex = i;
11372
+ break;
11373
+ }
11374
+ }
11375
+ }
11376
+ if (!name) {
11377
+ return null;
11378
+ }
11379
+ const descriptionLines = [];
11380
+ let rulesStartIndex = -1;
11381
+ for (let i = nameLineIndex + 1; i < lines.length; i++) {
11382
+ if (lines[i].startsWith("* ") || lines[i].startsWith("- ")) {
11383
+ rulesStartIndex = i;
11384
+ break;
11385
+ }
11386
+ if (lines[i].startsWith("Full standard is available")) break;
11387
+ descriptionLines.push(lines[i]);
11388
+ }
11389
+ let description = descriptionLines.join("\n").trim();
11390
+ if (description.endsWith(" :")) {
11391
+ description = description.slice(0, -2).trim();
11392
+ }
11393
+ const rules = extractRulesList(lines, rulesStartIndex);
11394
+ return { name, description, scope, rules };
11395
+ }
11396
+ function addFrontmatterFields(parsed, frontmatter) {
11397
+ const fmName = extractFrontmatterValue(frontmatter, "name");
11398
+ const fmDescription = extractFrontmatterValue(frontmatter, "description");
11399
+ return {
11400
+ ...parsed,
11401
+ ...fmName ? { frontmatterName: fmName } : {},
11402
+ ...fmDescription ? { frontmatterDescription: fmDescription } : {}
11403
+ };
11404
+ }
11405
+ function extractFrontmatterValue(frontmatter, key) {
11406
+ if (!frontmatter) return "";
11407
+ for (const line of frontmatter.split("\n")) {
11408
+ const trimmed = line.trim();
11409
+ if (trimmed.startsWith(`${key}:`)) {
11410
+ const raw = trimmed.slice(key.length + 1).trim();
11411
+ return stripYamlQuotes(raw);
11412
+ }
11413
+ }
11414
+ return "";
11415
+ }
11416
+ function stripYamlQuotes(value) {
11417
+ if (value.startsWith("'") && value.endsWith("'") && value.length >= 2) {
11418
+ return value.slice(1, -1).replace(/''/g, "'");
11419
+ }
11420
+ if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) {
11421
+ return value.slice(1, -1);
11422
+ }
11423
+ return value;
11424
+ }
11425
+ function extractScopeFromKey(frontmatter, key) {
11426
+ const rawValue = extractFrontmatterValue(frontmatter, key);
11427
+ if (!rawValue) return "";
11428
+ return normalizeScopeValue(rawValue);
11429
+ }
11430
+ function normalizeScopeValue(rawValue) {
11431
+ if (!rawValue) return "";
11432
+ if (rawValue.startsWith("[")) {
11433
+ const inner = rawValue.slice(1, -1);
11434
+ const items = inner.split(",").map((item) => item.trim().replace(/(?:^["'])|(?:["']$)/g, ""));
11435
+ return items.join(", ");
11436
+ }
11437
+ return rawValue.replace(/(?:^["'])|(?:["']$)/g, "");
11438
+ }
11439
+
11440
+ // apps/cli/src/application/useCases/diffStrategies/StandardDiffStrategy.ts
11441
+ var StandardDiffStrategy = class {
11442
+ supports(file) {
11443
+ return file.artifactType === "standard";
11444
+ }
11445
+ async diff(file, baseDirectory) {
11446
+ const fullPath = path14.join(baseDirectory, file.path);
11447
+ let localContent;
11448
+ try {
11449
+ localContent = await fs13.readFile(fullPath, "utf-8");
11450
+ } catch {
11451
+ return [];
11452
+ }
11453
+ const serverParsed = parseStandardMd(file.content, file.path);
11454
+ const localParsed = parseStandardMd(localContent, file.path);
11455
+ if (!serverParsed || !localParsed) {
11456
+ return [];
11457
+ }
11458
+ const diffs = [];
11459
+ const diffBase = {
11460
+ filePath: file.path,
11461
+ artifactName: file.artifactName,
11462
+ artifactType: file.artifactType,
11463
+ artifactId: file.artifactId,
11464
+ spaceId: file.spaceId
11465
+ };
11466
+ if (serverParsed.frontmatterName && localParsed.frontmatterName && serverParsed.frontmatterName !== localParsed.frontmatterName) {
11467
+ diffs.push({
11468
+ ...diffBase,
11469
+ type: "updateStandardName" /* updateStandardName */,
11470
+ payload: {
11471
+ oldValue: serverParsed.frontmatterName,
11472
+ newValue: localParsed.frontmatterName
11473
+ }
11474
+ });
11475
+ }
11476
+ if (serverParsed.name !== localParsed.name) {
11477
+ diffs.push({
11478
+ ...diffBase,
11479
+ type: "updateStandardName" /* updateStandardName */,
11480
+ payload: {
11481
+ oldValue: serverParsed.name,
11482
+ newValue: localParsed.name
11483
+ }
11484
+ });
11485
+ }
11486
+ if (serverParsed.frontmatterDescription && localParsed.frontmatterDescription && serverParsed.frontmatterDescription !== localParsed.frontmatterDescription) {
11487
+ diffs.push({
11488
+ ...diffBase,
11489
+ type: "updateStandardDescription" /* updateStandardDescription */,
11490
+ payload: {
11491
+ oldValue: serverParsed.frontmatterDescription,
11492
+ newValue: localParsed.frontmatterDescription
11493
+ }
11494
+ });
11495
+ }
11496
+ if (serverParsed.description !== localParsed.description) {
11497
+ diffs.push({
11498
+ ...diffBase,
11499
+ type: "updateStandardDescription" /* updateStandardDescription */,
11500
+ payload: {
11501
+ oldValue: serverParsed.description,
11502
+ newValue: localParsed.description
11503
+ }
11504
+ });
11505
+ }
11506
+ if (serverParsed.scope !== localParsed.scope) {
11507
+ diffs.push({
11508
+ ...diffBase,
11509
+ type: "updateStandardScope" /* updateStandardScope */,
11510
+ payload: {
11511
+ oldValue: serverParsed.scope,
11512
+ newValue: localParsed.scope
11513
+ }
11514
+ });
11515
+ }
11516
+ const serverRules = new Set(serverParsed.rules);
11517
+ const localRules = new Set(localParsed.rules);
11518
+ for (const rule of serverRules) {
11519
+ if (!localRules.has(rule)) {
11520
+ const ruleId = createRuleId("unresolved");
11521
+ diffs.push({
11522
+ ...diffBase,
11523
+ type: "deleteRule" /* deleteRule */,
11524
+ payload: {
11525
+ targetId: ruleId,
11526
+ item: { id: ruleId, content: rule }
11527
+ }
11528
+ });
11529
+ }
11530
+ }
11531
+ for (const rule of localRules) {
11532
+ if (!serverRules.has(rule)) {
11533
+ diffs.push({
11534
+ ...diffBase,
11535
+ type: "addRule" /* addRule */,
11536
+ payload: {
11537
+ item: { content: rule }
11538
+ }
11539
+ });
11540
+ }
11541
+ }
11542
+ return diffs;
11543
+ }
11544
+ };
11545
+
11546
+ // apps/cli/src/application/useCases/DiffArtefactsUseCase.ts
11547
+ var DiffArtefactsUseCase = class {
11548
+ constructor(packmindGateway) {
11549
+ this.packmindGateway = packmindGateway;
11550
+ this.strategies = [
11551
+ new CommandDiffStrategy(),
11552
+ new SkillDiffStrategy(),
11553
+ new StandardDiffStrategy()
11554
+ ];
11555
+ }
11556
+ async execute(command21) {
11557
+ const baseDirectory = command21.baseDirectory || process.cwd();
11558
+ const response = await this.packmindGateway.deployment.getDeployed({
11559
+ packagesSlugs: command21.packagesSlugs,
11560
+ gitRemoteUrl: command21.gitRemoteUrl,
11561
+ gitBranch: command21.gitBranch,
11562
+ relativePath: command21.relativePath,
11563
+ agents: command21.agents
11564
+ });
11565
+ const filteredFiles = response.fileUpdates.createOrUpdate.filter(
11566
+ (file) => file.path !== "packmind.json"
11567
+ );
11568
+ const uniqueFilesMap = /* @__PURE__ */ new Map();
11569
+ for (const file of filteredFiles) {
11570
+ uniqueFilesMap.set(file.path, file);
11571
+ }
11572
+ const diffableFiles = Array.from(uniqueFilesMap.values()).filter(
11573
+ (file) => !!file.artifactType && !!file.artifactName && file.content !== void 0
11574
+ );
11575
+ const prefixedSkillFolders = this.prefixSkillFolders(
11576
+ response.skillFolders,
11577
+ command21.relativePath
11578
+ );
11579
+ const diffs = [];
11580
+ for (const file of diffableFiles) {
11581
+ const strategy = this.strategies.find((s) => s.supports(file));
11582
+ if (strategy) {
11583
+ const fileDiffs = await strategy.diff(file, baseDirectory, {
11584
+ skillFolders: prefixedSkillFolders
11585
+ });
11586
+ diffs.push(...fileDiffs);
11587
+ }
11588
+ }
11589
+ for (const strategy of this.strategies) {
11590
+ if (strategy.diffNewFiles) {
11591
+ const newFileDiffs = await strategy.diffNewFiles(
11592
+ prefixedSkillFolders,
11593
+ diffableFiles,
11594
+ baseDirectory
11595
+ );
11596
+ diffs.push(...newFileDiffs);
11597
+ }
11598
+ }
11599
+ return diffs;
11600
+ }
11601
+ prefixSkillFolders(skillFolders, relativePath) {
11602
+ if (!relativePath) return skillFolders;
11603
+ let normalized = relativePath;
11604
+ while (normalized.startsWith("/")) normalized = normalized.slice(1);
11605
+ while (normalized.endsWith("/")) normalized = normalized.slice(0, -1);
11606
+ if (!normalized) return skillFolders;
11607
+ return skillFolders.map((folder) => `${normalized}/${folder}`);
11608
+ }
11609
+ };
11610
+
11611
+ // apps/cli/src/application/useCases/SubmitDiffsUseCase.ts
11612
+ var SUPPORTED_ARTIFACT_TYPES = /* @__PURE__ */ new Set(["command", "skill", "standard"]);
11613
+ var SubmitDiffsUseCase = class {
11614
+ constructor(packmindGateway) {
11615
+ this.packmindGateway = packmindGateway;
11616
+ }
11617
+ async execute(command21) {
11618
+ const { groupedDiffs, message } = command21;
11619
+ const skipped = [];
11620
+ const validDiffs = [];
11621
+ for (const group of groupedDiffs) {
11622
+ const firstDiff = group[0];
11623
+ if (!firstDiff) {
11624
+ continue;
11625
+ }
11626
+ if (!SUPPORTED_ARTIFACT_TYPES.has(firstDiff.artifactType)) {
11627
+ skipped.push({
11628
+ name: firstDiff.artifactName,
11629
+ reason: "Only commands, skills, and standards are supported"
11630
+ });
11631
+ continue;
11632
+ }
11633
+ for (const diff of group) {
11634
+ if (!diff.artifactId || !diff.spaceId) {
11635
+ skipped.push({
11636
+ name: diff.artifactName,
11637
+ reason: "Missing artifact metadata"
11638
+ });
11639
+ continue;
11640
+ }
11641
+ validDiffs.push(diff);
11642
+ }
11643
+ }
11644
+ const diffsBySpaceId = /* @__PURE__ */ new Map();
11645
+ for (const diff of validDiffs) {
11646
+ const existing = diffsBySpaceId.get(diff.spaceId) ?? [];
11647
+ existing.push(diff);
11648
+ diffsBySpaceId.set(diff.spaceId, existing);
11649
+ }
11650
+ let submitted = 0;
11651
+ let alreadySubmitted = 0;
11652
+ const errors = [];
11653
+ for (const [spaceId, diffs] of diffsBySpaceId) {
11654
+ const response = await this.packmindGateway.changeProposals.batchCreate({
11655
+ spaceId,
11656
+ proposals: diffs.map((diff) => ({
11657
+ type: diff.type,
11658
+ artefactId: diff.artifactId,
11659
+ payload: diff.payload,
11660
+ captureMode: "commit" /* commit */,
11661
+ message
11662
+ }))
11663
+ });
11664
+ submitted += response.created;
11665
+ alreadySubmitted += response.skipped;
11666
+ for (const error of response.errors) {
11667
+ errors.push({
11668
+ name: diffs[error.index].artifactName,
11669
+ message: error.message,
11670
+ code: error.code,
11671
+ artifactType: diffs[error.index].artifactType
11672
+ });
11673
+ }
11674
+ }
11675
+ return { submitted, alreadySubmitted, skipped, errors };
11676
+ }
11677
+ };
11678
+
11679
+ // apps/cli/src/application/useCases/CheckDiffsUseCase.ts
11680
+ var SUPPORTED_ARTIFACT_TYPES2 = /* @__PURE__ */ new Set(["command", "skill", "standard"]);
11681
+ var CheckDiffsUseCase = class {
11682
+ constructor(packmindGateway) {
11683
+ this.packmindGateway = packmindGateway;
11684
+ }
11685
+ async execute(command21) {
11686
+ const { groupedDiffs } = command21;
11687
+ const results = [];
11688
+ const validDiffs = [];
11689
+ const invalidDiffs = [];
11690
+ for (const group of groupedDiffs) {
11691
+ for (const diff of group) {
11692
+ if (!SUPPORTED_ARTIFACT_TYPES2.has(diff.artifactType) || !diff.artifactId || !diff.spaceId) {
11693
+ invalidDiffs.push(diff);
11694
+ continue;
11695
+ }
11696
+ validDiffs.push(diff);
11697
+ }
11698
+ }
11699
+ const diffsBySpaceId = /* @__PURE__ */ new Map();
11700
+ for (const diff of validDiffs) {
11701
+ const existing = diffsBySpaceId.get(diff.spaceId) ?? [];
11702
+ existing.push(diff);
11703
+ diffsBySpaceId.set(diff.spaceId, existing);
11704
+ }
11705
+ const checkedMap = /* @__PURE__ */ new Map();
11706
+ for (const [spaceId, diffs] of diffsBySpaceId) {
11707
+ const response = await this.packmindGateway.changeProposals.check({
11708
+ spaceId,
11709
+ proposals: diffs.map((diff) => ({
11710
+ type: diff.type,
11711
+ artefactId: diff.artifactId,
11712
+ payload: diff.payload,
11713
+ captureMode: "commit" /* commit */,
11714
+ message: ""
11715
+ }))
11716
+ });
11717
+ for (const result of response.results) {
11718
+ const diff = diffs[result.index];
11719
+ checkedMap.set(diff, {
11720
+ diff,
11721
+ exists: result.exists,
11722
+ createdAt: result.createdAt,
11723
+ message: result.message
11724
+ });
11725
+ }
11726
+ }
11727
+ for (const group of groupedDiffs) {
11728
+ for (const diff of group) {
11729
+ const checked = checkedMap.get(diff);
11730
+ if (checked) {
11731
+ results.push(checked);
11732
+ } else {
11733
+ results.push({ diff, exists: false, createdAt: null, message: null });
11734
+ }
11735
+ }
11736
+ }
11737
+ return { results };
11738
+ }
11739
+ };
11740
+
11741
+ // apps/cli/src/PackmindCliHexaFactory.ts
11742
+ var PackmindCliHexaFactory = class {
11743
+ constructor() {
11744
+ this.repositories = {
11745
+ packmindGateway: new PackmindGateway(loadApiKey()),
11746
+ configFileRepository: new ConfigFileRepository()
11747
+ };
11748
+ this.services = {
11749
+ listFiles: new ListFiles(),
11750
+ gitRemoteUrlService: new GitService(),
11751
+ linterExecutionUseCase: new ExecuteLinterProgramsUseCase(),
11752
+ diffViolationFilterService: new DiffViolationFilterService()
11753
+ };
11754
+ this.useCases = {
11755
+ executeSingleFileAst: new ExecuteSingleFileAstUseCase(
11756
+ this.services.linterExecutionUseCase
11757
+ ),
11758
+ getGitRemoteUrl: new GetGitRemoteUrlUseCase(),
11759
+ listFilesInDirectoryUseCase: new ListFilesInDirectoryUseCase(),
11760
+ lintFilesAgainstRule: new LintFilesAgainstRuleUseCase(
11761
+ this.services,
11762
+ this.repositories
11763
+ ),
11764
+ lintFilesFromConfig: new LintFilesFromConfigUseCase(
11765
+ this.services,
11766
+ this.repositories
11767
+ ),
11768
+ installPackages: new InstallPackagesUseCase(
11769
+ this.repositories.packmindGateway
11770
+ ),
11771
+ installDefaultSkills: new InstallDefaultSkillsUseCase(this.repositories),
11772
+ listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
11773
+ getPackageBySlug: new GetPackageSummaryUseCase(
11774
+ this.repositories.packmindGateway
11775
+ ),
11776
+ login: new LoginUseCase(),
11777
+ logout: new LogoutUseCase(),
11778
+ whoami: new WhoamiUseCase(),
11779
+ setupMcp: new SetupMcpUseCase({
11780
+ gateway: this.repositories.packmindGateway,
11781
+ mcpConfigService: new McpConfigService()
11782
+ }),
11783
+ listStandards: new ListStandardsUseCase(
11784
+ this.repositories.packmindGateway
11785
+ ),
11786
+ listCommands: new ListCommandsUseCase(this.repositories.packmindGateway),
11787
+ listSkills: new ListSkillsUseCase(this.repositories.packmindGateway),
11788
+ uploadSkill: new UploadSkillUseCase({
11789
+ gateway: this.repositories.packmindGateway
11790
+ }),
11791
+ diffArtefacts: new DiffArtefactsUseCase(
11792
+ this.repositories.packmindGateway
11793
+ ),
11794
+ submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway),
11795
+ checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway)
11796
+ };
11797
+ }
11798
+ };
11799
+
11800
+ // apps/cli/src/PackmindCliHexa.ts
11801
+ var origin8 = "PackmindCliHexa";
11802
+ var PackmindCliHexa = class {
11803
+ constructor(logger2 = new PackmindLogger(origin8)) {
11804
+ this.notifyDistribution = async (command21) => {
11805
+ return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
11806
+ command21
11807
+ );
11808
+ };
11809
+ this.logger = logger2;
11810
+ try {
11811
+ this.hexa = new PackmindCliHexaFactory();
11812
+ } catch (error) {
11813
+ this.logger.error("Failed to initialize PackmindCliHexa", {
11814
+ error: error instanceof Error ? error.message : String(error)
11815
+ });
11816
+ throw error;
11817
+ }
11818
+ }
11819
+ /**
11820
+ * Destroys the DeploymentsHexa and cleans up resources
11821
+ */
11822
+ destroy() {
11823
+ this.logger.info("Destroying PackmindCliHexa");
11824
+ this.logger.info("PackmindCliHexa destroyed");
11825
+ }
11826
+ async getGitRemoteUrl(command21) {
11827
+ return this.hexa.useCases.getGitRemoteUrl.execute(command21);
11828
+ }
11829
+ async executeSingleFileAst(command21) {
11830
+ return this.hexa.useCases.executeSingleFileAst.execute(command21);
11831
+ }
11832
+ async listFilesInDirectory(command21) {
11833
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command21);
11834
+ }
11835
+ async lintFilesAgainstRule(command21) {
11836
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command21);
11837
+ }
11838
+ async lintFilesFromConfig(command21) {
11839
+ return this.hexa.useCases.lintFilesFromConfig.execute(command21);
11840
+ }
11841
+ async installPackages(command21) {
11842
+ return this.hexa.useCases.installPackages.execute(command21);
11843
+ }
11844
+ async diffArtefacts(command21) {
11845
+ return this.hexa.useCases.diffArtefacts.execute(command21);
11846
+ }
11847
+ async submitDiffs(groupedDiffs, message) {
11848
+ return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
11849
+ }
11850
+ async checkDiffs(groupedDiffs) {
11851
+ return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
11852
+ }
11853
+ async listPackages(command21) {
11854
+ return this.hexa.useCases.listPackages.execute(command21);
11855
+ }
11856
+ async getPackageBySlug(command21) {
11857
+ return this.hexa.useCases.getPackageBySlug.execute(command21);
11858
+ }
11859
+ async listStandards(command21) {
11860
+ return this.hexa.useCases.listStandards.execute(command21);
11861
+ }
11862
+ async listCommands(command21) {
11863
+ return this.hexa.useCases.listCommands.execute(command21);
11864
+ }
11865
+ async listSkills(command21) {
11866
+ return this.hexa.useCases.listSkills.execute(command21);
11867
+ }
11868
+ async configExists(baseDirectory) {
11869
+ return await this.hexa.repositories.configFileRepository.configExists(
10724
11870
  baseDirectory
10725
11871
  );
10726
11872
  }
@@ -10804,17 +11950,17 @@ var PackmindCliHexa = class {
10804
11950
  directory
10805
11951
  );
10806
11952
  }
10807
- async login(command20) {
10808
- return this.hexa.useCases.login.execute(command20);
11953
+ async login(command21) {
11954
+ return this.hexa.useCases.login.execute(command21);
10809
11955
  }
10810
- async logout(command20) {
10811
- return this.hexa.useCases.logout.execute(command20);
11956
+ async logout(command21) {
11957
+ return this.hexa.useCases.logout.execute(command21);
10812
11958
  }
10813
- async whoami(command20) {
10814
- return this.hexa.useCases.whoami.execute(command20);
11959
+ async whoami(command21) {
11960
+ return this.hexa.useCases.whoami.execute(command21);
10815
11961
  }
10816
- async setupMcp(command20) {
10817
- return this.hexa.useCases.setupMcp.execute(command20);
11962
+ async setupMcp(command21) {
11963
+ return this.hexa.useCases.setupMcp.execute(command21);
10818
11964
  }
10819
11965
  getCurrentBranch(repoPath) {
10820
11966
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -10822,11 +11968,11 @@ var PackmindCliHexa = class {
10822
11968
  getGitRemoteUrlFromPath(repoPath) {
10823
11969
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
10824
11970
  }
10825
- async uploadSkill(command20) {
10826
- return this.hexa.useCases.uploadSkill.execute(command20);
11971
+ async uploadSkill(command21) {
11972
+ return this.hexa.useCases.uploadSkill.execute(command21);
10827
11973
  }
10828
- async installDefaultSkills(command20) {
10829
- return this.hexa.useCases.installDefaultSkills.execute(command20);
11974
+ async installDefaultSkills(command21) {
11975
+ return this.hexa.useCases.installDefaultSkills.execute(command21);
10830
11976
  }
10831
11977
  getPackmindGateway() {
10832
11978
  return this.hexa.repositories.packmindGateway;
@@ -10858,39 +12004,70 @@ var IDELintLogger = class {
10858
12004
  });
10859
12005
  }
10860
12006
  logViolation(violation) {
10861
- violation.violations.forEach(({ line, character, standard, rule }) => {
10862
- logConsole(
10863
- `${violation.file}:${line}:${character}:error:@${standard}/${rule}`
10864
- );
10865
- });
12007
+ violation.violations.forEach(
12008
+ ({ line, character, standard, rule, severity }) => {
12009
+ const label = (severity ?? "error" /* ERROR */) === "warning" /* WARNING */ ? "warning" : "error";
12010
+ logConsole(
12011
+ `${violation.file}:${line}:${character}:${label}:@${standard}/${rule}`
12012
+ );
12013
+ }
12014
+ );
10866
12015
  }
10867
12016
  };
10868
12017
 
10869
12018
  // apps/cli/src/infra/repositories/HumanReadableLogger.ts
10870
12019
  var HumanReadableLogger = class {
12020
+ effectiveSeverity(s) {
12021
+ return s ?? "error" /* ERROR */;
12022
+ }
10871
12023
  logViolations(violations) {
10872
12024
  violations.forEach((violation) => {
10873
12025
  this.logViolation(violation);
10874
12026
  });
10875
- if (violations.length > 0) {
10876
- const totalViolationCount = violations.reduce(
10877
- (acc, violation) => acc + violation.violations.length,
10878
- 0
10879
- );
12027
+ if (violations.length === 0) {
12028
+ logSuccessConsole(`\u2705 No violations found`);
12029
+ return;
12030
+ }
12031
+ const allDetails = violations.flatMap((v) => v.violations);
12032
+ const errorCount = allDetails.filter(
12033
+ (d) => this.effectiveSeverity(d.severity) === "error" /* ERROR */
12034
+ ).length;
12035
+ const warningCount = allDetails.filter(
12036
+ (d) => this.effectiveSeverity(d.severity) === "warning" /* WARNING */
12037
+ ).length;
12038
+ const errorFileCount = violations.filter(
12039
+ (v) => v.violations.some(
12040
+ (d) => this.effectiveSeverity(d.severity) === "error" /* ERROR */
12041
+ )
12042
+ ).length;
12043
+ const warningFileCount = violations.filter(
12044
+ (v) => v.violations.some(
12045
+ (d) => this.effectiveSeverity(d.severity) === "warning" /* WARNING */
12046
+ )
12047
+ ).length;
12048
+ if (errorCount > 0) {
10880
12049
  logErrorConsole(
10881
- `\u274C Found ${formatBold(String(totalViolationCount))} violation(s) in ${formatBold(String(violations.length))} file(s)`
12050
+ `\u274C Found ${formatBold(String(errorCount))} error(s) in ${formatBold(String(errorFileCount))} file(s)`
12051
+ );
12052
+ }
12053
+ if (warningCount > 0) {
12054
+ logWarningConsole(
12055
+ `\u26A0\uFE0F Found ${formatBold(String(warningCount))} warning(s) in ${formatBold(String(warningFileCount))} file(s)`
10882
12056
  );
10883
- } else {
10884
- logSuccessConsole(`\u2705 No violations found`);
10885
12057
  }
10886
12058
  }
10887
12059
  logViolation(violation) {
10888
12060
  logConsole(formatFilePath(violation.file));
10889
- violation.violations.forEach(({ line, character, standard, rule }) => {
10890
- logConsole(
10891
- formatError(` ${line}:${character} error @${standard}/${rule}`)
10892
- );
10893
- });
12061
+ violation.violations.forEach(
12062
+ ({ line, character, standard, rule, severity }) => {
12063
+ const effective = this.effectiveSeverity(severity);
12064
+ const label = effective === "warning" /* WARNING */ ? "warning" : "error";
12065
+ const format = effective === "warning" /* WARNING */ ? formatWarning : formatError;
12066
+ logConsole(
12067
+ format(` ${line}:${character} ${label} @${standard}/${rule}`)
12068
+ );
12069
+ }
12070
+ );
10894
12071
  }
10895
12072
  };
10896
12073
 
@@ -10898,19 +12075,24 @@ var HumanReadableLogger = class {
10898
12075
  var pathModule = __toESM(require("path"));
10899
12076
 
10900
12077
  // apps/cli/src/infra/commands/lintHandler.ts
12078
+ var SEVERITY_LEVELS = {
12079
+ ["warning" /* WARNING */]: 0,
12080
+ ["error" /* ERROR */]: 1
12081
+ };
10901
12082
  function isNotLoggedInError(error) {
10902
12083
  return error instanceof NotLoggedInError;
10903
12084
  }
10904
12085
  async function lintHandler(args2, deps) {
10905
12086
  const {
10906
- path: path14,
12087
+ path: path18,
10907
12088
  draft,
10908
12089
  rule,
10909
12090
  language,
10910
12091
  logger: logger2,
10911
12092
  continueOnError,
10912
12093
  continueOnMissingKey,
10913
- diff
12094
+ diff,
12095
+ level
10914
12096
  } = args2;
10915
12097
  const {
10916
12098
  packmindCliHexa,
@@ -10923,7 +12105,7 @@ async function lintHandler(args2, deps) {
10923
12105
  throw new Error("option --rule is required to use --draft mode");
10924
12106
  }
10925
12107
  const startedAt = Date.now();
10926
- const targetPath = path14 ?? ".";
12108
+ const targetPath = path18 ?? ".";
10927
12109
  const absolutePath = resolvePath(targetPath);
10928
12110
  if (diff) {
10929
12111
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(absolutePath);
@@ -10978,14 +12160,27 @@ async function lintHandler(args2, deps) {
10978
12160
  }
10979
12161
  throw error;
10980
12162
  }
12163
+ const effectiveSeverity = (s) => s ?? "error" /* ERROR */;
12164
+ const filteredViolations = level ? violations.map((v) => ({
12165
+ ...v,
12166
+ violations: v.violations.filter(
12167
+ (d) => SEVERITY_LEVELS[effectiveSeverity(d.severity)] >= SEVERITY_LEVELS[level]
12168
+ )
12169
+ })).filter((v) => v.violations.length > 0) : violations;
10981
12170
  (logger2 === "ide" /* ide */ ? ideLintLogger : humanReadableLogger).logViolations(
10982
- violations
12171
+ filteredViolations
12172
+ );
12173
+ const hasErrors = filteredViolations.some(
12174
+ (v) => v.violations.some(
12175
+ (d) => effectiveSeverity(d.severity) === "error" /* ERROR */
12176
+ )
10983
12177
  );
10984
12178
  const durationSeconds = (Date.now() - startedAt) / 1e3;
10985
- logInfoConsole(`Lint completed in ${durationSeconds.toFixed(2)}s`);
10986
- if (violations.length > 0 && !continueOnError) {
12179
+ if (hasErrors && !continueOnError) {
12180
+ logErrorConsole(`Lint failed in ${durationSeconds.toFixed(2)}s`);
10987
12181
  exit(1);
10988
12182
  } else {
12183
+ logInfoConsole(`Lint completed in ${durationSeconds.toFixed(2)}s`);
10989
12184
  exit(0);
10990
12185
  }
10991
12186
  }
@@ -11031,6 +12226,19 @@ var DiffModeType = {
11031
12226
  );
11032
12227
  }
11033
12228
  };
12229
+ var LevelType = {
12230
+ from: async (input) => {
12231
+ switch (input) {
12232
+ case "error":
12233
+ return "error" /* ERROR */;
12234
+ case "warning":
12235
+ return "warning" /* WARNING */;
12236
+ }
12237
+ throw new Error(
12238
+ `${input} is not a valid value for the --level option. Expected values are: error, warning`
12239
+ );
12240
+ }
12241
+ };
11034
12242
  var lintCommand = (0, import_cmd_ts.command)({
11035
12243
  name: "lint",
11036
12244
  description: "Lint code at the specified path",
@@ -11085,6 +12293,11 @@ var lintCommand = (0, import_cmd_ts.command)({
11085
12293
  changedLines: (0, import_cmd_ts.flag)({
11086
12294
  long: "changed-lines",
11087
12295
  description: "Only lint lines that have changed"
12296
+ }),
12297
+ level: (0, import_cmd_ts.option)({
12298
+ long: "level",
12299
+ description: "Minimum severity level to display (error | warning)",
12300
+ type: (0, import_cmd_ts.optional)(LevelType)
11088
12301
  })
11089
12302
  },
11090
12303
  handler: async (args2) => {
@@ -11174,8 +12387,8 @@ function extractWasmFiles() {
11174
12387
 
11175
12388
  // apps/cli/src/main.ts
11176
12389
  var import_dotenv = require("dotenv");
11177
- var fs16 = __toESM(require("fs"));
11178
- var path13 = __toESM(require("path"));
12390
+ var fs19 = __toESM(require("fs"));
12391
+ var path17 = __toESM(require("path"));
11179
12392
 
11180
12393
  // apps/cli/src/infra/commands/InstallCommand.ts
11181
12394
  var import_cmd_ts2 = __toESM(require_cjs());
@@ -12250,13 +13463,13 @@ Credentials are loaded from (in order of priority):`);
12250
13463
 
12251
13464
  // apps/cli/src/infra/commands/SetupMcpCommand.ts
12252
13465
  var import_cmd_ts7 = __toESM(require_cjs());
12253
- var fs12 = __toESM(require("fs"));
13466
+ var fs15 = __toESM(require("fs"));
12254
13467
  var readline2 = __toESM(require("readline"));
12255
13468
  var inquirer = __toESM(require("inquirer"));
12256
13469
 
12257
13470
  // apps/cli/src/application/services/AgentDetectionService.ts
12258
- var fs11 = __toESM(require("fs"));
12259
- var path11 = __toESM(require("path"));
13471
+ var fs14 = __toESM(require("fs"));
13472
+ var path15 = __toESM(require("path"));
12260
13473
  var os4 = __toESM(require("os"));
12261
13474
  var import_child_process3 = require("child_process");
12262
13475
  var AgentDetectionService = class {
@@ -12283,21 +13496,21 @@ var AgentDetectionService = class {
12283
13496
  return this.isCommandAvailable("claude");
12284
13497
  }
12285
13498
  isCursorAvailable() {
12286
- const cursorConfigDir = path11.join(os4.homedir(), ".cursor");
12287
- return fs11.existsSync(cursorConfigDir);
13499
+ const cursorConfigDir = path15.join(os4.homedir(), ".cursor");
13500
+ return fs14.existsSync(cursorConfigDir);
12288
13501
  }
12289
13502
  isVSCodeAvailable() {
12290
- const vscodeDir = path11.join(this.projectDir, ".vscode");
12291
- return fs11.existsSync(vscodeDir);
13503
+ const vscodeDir = path15.join(this.projectDir, ".vscode");
13504
+ return fs14.existsSync(vscodeDir);
12292
13505
  }
12293
13506
  isContinueAvailable() {
12294
- const continueDir = path11.join(this.projectDir, ".continue");
12295
- return fs11.existsSync(continueDir);
13507
+ const continueDir = path15.join(this.projectDir, ".continue");
13508
+ return fs14.existsSync(continueDir);
12296
13509
  }
12297
- isCommandAvailable(command20) {
13510
+ isCommandAvailable(command21) {
12298
13511
  try {
12299
13512
  const whichCommand = process.platform === "win32" ? "where" : "which";
12300
- (0, import_child_process3.execSync)(`${whichCommand} ${command20}`, { stdio: "pipe" });
13513
+ (0, import_child_process3.execSync)(`${whichCommand} ${command21}`, { stdio: "pipe" });
12301
13514
  return true;
12302
13515
  } catch {
12303
13516
  return false;
@@ -12331,8 +13544,8 @@ var ALL_AGENTS2 = [
12331
13544
  { type: "continue", name: "Continue.dev" }
12332
13545
  ];
12333
13546
  async function promptAgentsWithReadline(choices) {
12334
- const input = fs12.createReadStream("/dev/tty");
12335
- const output = fs12.createWriteStream("/dev/tty");
13547
+ const input = fs15.createReadStream("/dev/tty");
13548
+ const output = fs15.createWriteStream("/dev/tty");
12336
13549
  const rl = readline2.createInterface({
12337
13550
  input,
12338
13551
  output
@@ -12700,7 +13913,7 @@ var import_cmd_ts15 = __toESM(require_cjs());
12700
13913
  var import_cmd_ts13 = __toESM(require_cjs());
12701
13914
 
12702
13915
  // apps/cli/src/infra/utils/readPlaybookFile.ts
12703
- var fs13 = __toESM(require("fs/promises"));
13916
+ var fs16 = __toESM(require("fs/promises"));
12704
13917
 
12705
13918
  // apps/cli/src/domain/entities/PlaybookDTO.ts
12706
13919
  var import_zod = require("zod");
@@ -12737,34 +13950,68 @@ function validatePlaybook(data) {
12737
13950
  }
12738
13951
 
12739
13952
  // apps/cli/src/infra/utils/readPlaybookFile.ts
13953
+ function parseAndValidatePlaybook(content) {
13954
+ let parsed;
13955
+ try {
13956
+ parsed = JSON.parse(content);
13957
+ } catch (e) {
13958
+ return {
13959
+ isValid: false,
13960
+ errors: [
13961
+ `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
13962
+ ]
13963
+ };
13964
+ }
13965
+ return validatePlaybook(parsed);
13966
+ }
12740
13967
  async function readPlaybookFile(filePath) {
12741
13968
  try {
12742
- const content = await fs13.readFile(filePath, "utf-8");
12743
- let parsed;
13969
+ const content = await fs16.readFile(filePath, "utf-8");
13970
+ return parseAndValidatePlaybook(content);
13971
+ } catch (e) {
13972
+ return {
13973
+ isValid: false,
13974
+ errors: [
13975
+ `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
13976
+ ]
13977
+ };
13978
+ }
13979
+ }
13980
+
13981
+ // apps/cli/src/infra/utils/readStdin.ts
13982
+ async function readStdin(input = process.stdin) {
13983
+ if ("isTTY" in input && input.isTTY) {
13984
+ throw new Error(
13985
+ "No piped input detected. Please provide content via stdin or specify a file path."
13986
+ );
13987
+ }
13988
+ const chunks = [];
13989
+ for await (const chunk of input) {
13990
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
13991
+ }
13992
+ const content = Buffer.concat(chunks).toString("utf-8").trim();
13993
+ if (!content) {
13994
+ throw new Error("Stdin is empty. Please provide JSON content via pipe.");
13995
+ }
13996
+ return content;
13997
+ }
13998
+
13999
+ // apps/cli/src/infra/commands/createStandardHandler.ts
14000
+ async function createStandardHandler(filePath, useCase, originSkill) {
14001
+ let readResult;
14002
+ if (filePath) {
14003
+ readResult = await readPlaybookFile(filePath);
14004
+ } else {
12744
14005
  try {
12745
- parsed = JSON.parse(content);
14006
+ const content = await readStdin();
14007
+ readResult = parseAndValidatePlaybook(content);
12746
14008
  } catch (e) {
12747
14009
  return {
12748
- isValid: false,
12749
- errors: [
12750
- `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
12751
- ]
14010
+ success: false,
14011
+ error: e instanceof Error ? e.message : "Failed to read from stdin"
12752
14012
  };
12753
14013
  }
12754
- return validatePlaybook(parsed);
12755
- } catch (e) {
12756
- return {
12757
- isValid: false,
12758
- errors: [
12759
- `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
12760
- ]
12761
- };
12762
14014
  }
12763
- }
12764
-
12765
- // apps/cli/src/infra/commands/createStandardHandler.ts
12766
- async function createStandardHandler(filePath, useCase, originSkill) {
12767
- const readResult = await readPlaybookFile(filePath);
12768
14015
  if (!readResult.isValid) {
12769
14016
  return {
12770
14017
  success: false,
@@ -12825,12 +14072,12 @@ var CreateStandardFromPlaybookUseCase = class {
12825
14072
  // apps/cli/src/infra/commands/CreateStandardCommand.ts
12826
14073
  var createStandardCommand = (0, import_cmd_ts13.command)({
12827
14074
  name: "create",
12828
- description: "Create a coding standard from a playbook JSON file",
14075
+ description: "Create a coding standard from a playbook JSON file or stdin",
12829
14076
  args: {
12830
14077
  file: (0, import_cmd_ts13.positional)({
12831
14078
  displayName: "file",
12832
- description: "Path to the playbook JSON file",
12833
- type: import_cmd_ts13.string
14079
+ description: "Path to the playbook JSON file (reads from stdin if omitted)",
14080
+ type: (0, import_cmd_ts13.optional)(import_cmd_ts13.string)
12834
14081
  }),
12835
14082
  originSkill: originSkillOption
12836
14083
  },
@@ -12955,7 +14202,7 @@ var import_cmd_ts18 = __toESM(require_cjs());
12955
14202
  var import_cmd_ts16 = __toESM(require_cjs());
12956
14203
 
12957
14204
  // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
12958
- var fs14 = __toESM(require("fs/promises"));
14205
+ var fs17 = __toESM(require("fs/promises"));
12959
14206
 
12960
14207
  // apps/cli/src/domain/entities/CommandPlaybookDTO.ts
12961
14208
  var import_zod2 = require("zod");
@@ -12991,21 +14238,24 @@ function validateCommandPlaybook(data) {
12991
14238
  }
12992
14239
 
12993
14240
  // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
14241
+ function parseAndValidateCommandPlaybook(content) {
14242
+ let parsed;
14243
+ try {
14244
+ parsed = JSON.parse(content);
14245
+ } catch (e) {
14246
+ return {
14247
+ isValid: false,
14248
+ errors: [
14249
+ `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
14250
+ ]
14251
+ };
14252
+ }
14253
+ return validateCommandPlaybook(parsed);
14254
+ }
12994
14255
  async function readCommandPlaybookFile(filePath) {
12995
14256
  try {
12996
- const content = await fs14.readFile(filePath, "utf-8");
12997
- let parsed;
12998
- try {
12999
- parsed = JSON.parse(content);
13000
- } catch (e) {
13001
- return {
13002
- isValid: false,
13003
- errors: [
13004
- `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
13005
- ]
13006
- };
13007
- }
13008
- return validateCommandPlaybook(parsed);
14257
+ const content = await fs17.readFile(filePath, "utf-8");
14258
+ return parseAndValidateCommandPlaybook(content);
13009
14259
  } catch (e) {
13010
14260
  return {
13011
14261
  isValid: false,
@@ -13021,7 +14271,20 @@ function buildWebappUrl(host, orgSlug, commandId) {
13021
14271
  return `${host}/org/${orgSlug}/space/global/commands/${commandId}`;
13022
14272
  }
13023
14273
  async function createCommandHandler(filePath, useCase, originSkill) {
13024
- const readResult = await readCommandPlaybookFile(filePath);
14274
+ let readResult;
14275
+ if (filePath) {
14276
+ readResult = await readCommandPlaybookFile(filePath);
14277
+ } else {
14278
+ try {
14279
+ const content = await readStdin();
14280
+ readResult = parseAndValidateCommandPlaybook(content);
14281
+ } catch (e) {
14282
+ return {
14283
+ success: false,
14284
+ error: e instanceof Error ? e.message : "Failed to read from stdin"
14285
+ };
14286
+ }
14287
+ }
13025
14288
  if (!readResult.isValid) {
13026
14289
  return {
13027
14290
  success: false,
@@ -13072,7 +14335,7 @@ var CreateCommandFromPlaybookUseCase = class {
13072
14335
  }
13073
14336
  async execute(playbook) {
13074
14337
  const space = await this.gateway.spaces.getGlobal();
13075
- const command20 = await this.gateway.commands.create({
14338
+ const command21 = await this.gateway.commands.create({
13076
14339
  spaceId: space.id,
13077
14340
  name: playbook.name,
13078
14341
  summary: playbook.summary,
@@ -13086,9 +14349,9 @@ var CreateCommandFromPlaybookUseCase = class {
13086
14349
  originSkill: playbook.originSkill
13087
14350
  });
13088
14351
  return {
13089
- commandId: command20.id,
13090
- name: command20.name,
13091
- slug: command20.slug
14352
+ commandId: command21.id,
14353
+ name: command21.name,
14354
+ slug: command21.slug
13092
14355
  };
13093
14356
  }
13094
14357
  };
@@ -13096,12 +14359,12 @@ var CreateCommandFromPlaybookUseCase = class {
13096
14359
  // apps/cli/src/infra/commands/CreateCommandCommand.ts
13097
14360
  var createCommandCommand = (0, import_cmd_ts16.command)({
13098
14361
  name: "create",
13099
- description: "Create a command from a playbook JSON file",
14362
+ description: "Create a command from a playbook JSON file or stdin",
13100
14363
  args: {
13101
14364
  file: (0, import_cmd_ts16.positional)({
13102
14365
  displayName: "file",
13103
- description: "Path to the command playbook JSON file",
13104
- type: import_cmd_ts16.string
14366
+ description: "Path to the command playbook JSON file (reads from stdin if omitted)",
14367
+ type: (0, import_cmd_ts16.optional)(import_cmd_ts16.string)
13105
14368
  }),
13106
14369
  originSkill: originSkillOption
13107
14370
  },
@@ -13215,11 +14478,538 @@ var commandsCommand = (0, import_cmd_ts18.subcommands)({
13215
14478
  }
13216
14479
  });
13217
14480
 
14481
+ // apps/cli/src/infra/commands/DiffCommand.ts
14482
+ var import_cmd_ts19 = __toESM(require_cjs());
14483
+
14484
+ // apps/cli/src/infra/utils/diffFormatter.ts
14485
+ var import_diff3 = require("diff");
14486
+ init_source();
14487
+ function formatContentDiff(oldContent, newContent) {
14488
+ const changes = (0, import_diff3.diffLines)(oldContent, newContent);
14489
+ const lines = [];
14490
+ for (const change of changes) {
14491
+ const trimmedValue = change.value.replace(/\n$/, "");
14492
+ const changeLines = trimmedValue.split("\n");
14493
+ if (change.added) {
14494
+ for (const line of changeLines) {
14495
+ lines.push(source_default.green(` + ${line}`));
14496
+ }
14497
+ } else if (change.removed) {
14498
+ for (const line of changeLines) {
14499
+ lines.push(source_default.red(` - ${line}`));
14500
+ }
14501
+ }
14502
+ }
14503
+ return {
14504
+ lines,
14505
+ hasChanges: lines.length > 0
14506
+ };
14507
+ }
14508
+
14509
+ // apps/cli/src/infra/utils/editorMessage.ts
14510
+ var import_child_process4 = require("child_process");
14511
+ var import_fs19 = require("fs");
14512
+ var import_os2 = require("os");
14513
+ var import_path4 = require("path");
14514
+ var MAX_MESSAGE_LENGTH = 1024;
14515
+ var EDITOR_TEMPLATE = `
14516
+ # Enter a message describing the intent behind these changes.
14517
+ # Lines starting with '#' will be ignored.
14518
+ # An empty message aborts the submission.
14519
+ `;
14520
+ function openEditorForMessage() {
14521
+ const tmpFile = (0, import_path4.join)((0, import_os2.tmpdir)(), `packmind-msg-${Date.now()}.txt`);
14522
+ try {
14523
+ (0, import_fs19.writeFileSync)(tmpFile, EDITOR_TEMPLATE, "utf-8");
14524
+ const editor = process.env.EDITOR || process.env.VISUAL || "vi";
14525
+ const result = (0, import_child_process4.spawnSync)(editor, [tmpFile], {
14526
+ stdio: "inherit"
14527
+ });
14528
+ if (result.status !== 0) {
14529
+ throw new Error(`Editor exited with status ${result.status}`);
14530
+ }
14531
+ const content = (0, import_fs19.readFileSync)(tmpFile, "utf-8");
14532
+ return content.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
14533
+ } finally {
14534
+ try {
14535
+ (0, import_fs19.unlinkSync)(tmpFile);
14536
+ } catch {
14537
+ }
14538
+ }
14539
+ }
14540
+ function validateMessage(message) {
14541
+ const trimmed = message.trim();
14542
+ if (trimmed.length === 0) {
14543
+ return { valid: false, error: "Message cannot be empty." };
14544
+ }
14545
+ if (trimmed.length > MAX_MESSAGE_LENGTH) {
14546
+ return {
14547
+ valid: false,
14548
+ error: `Message exceeds maximum length of ${MAX_MESSAGE_LENGTH} characters (got ${trimmed.length}).`
14549
+ };
14550
+ }
14551
+ return { valid: true, message: trimmed };
14552
+ }
14553
+
14554
+ // apps/cli/src/infra/commands/diffArtefactsHandler.ts
14555
+ init_source();
14556
+ var ARTIFACT_TYPE_LABELS = {
14557
+ command: "Command",
14558
+ standard: "Standard",
14559
+ skill: "Skill"
14560
+ };
14561
+ function subGroupByChangeContent(diffs) {
14562
+ const groups = /* @__PURE__ */ new Map();
14563
+ for (const diff of diffs) {
14564
+ const key = JSON.stringify({ type: diff.type, payload: diff.payload });
14565
+ const group = groups.get(key) ?? [];
14566
+ group.push(diff);
14567
+ groups.set(key, group);
14568
+ }
14569
+ return Array.from(groups.values());
14570
+ }
14571
+ function groupDiffsByArtefact(diffs) {
14572
+ const groups = /* @__PURE__ */ new Map();
14573
+ for (const diff of diffs) {
14574
+ const key = `${diff.artifactType}:${diff.artifactName}`;
14575
+ const group = groups.get(key) ?? [];
14576
+ group.push(diff);
14577
+ groups.set(key, group);
14578
+ }
14579
+ return groups;
14580
+ }
14581
+ function formatDiffPayload(diff, log) {
14582
+ const payload = diff.payload;
14583
+ if (diff.type === "addSkillFile" /* addSkillFile */) {
14584
+ const item = payload.item;
14585
+ if (item.isBase64) {
14586
+ log(source_default.green(" + [binary file]"));
14587
+ } else {
14588
+ for (const line of item.content.split("\n")) {
14589
+ log(source_default.green(` + ${line}`));
14590
+ }
14591
+ }
14592
+ return;
14593
+ }
14594
+ if (diff.type === "deleteSkillFile" /* deleteSkillFile */) {
14595
+ const item = payload.item;
14596
+ if (item.isBase64) {
14597
+ log(source_default.red(" - [binary file]"));
14598
+ } else {
14599
+ const lines2 = item.content.split("\n");
14600
+ const MAX_DELETED_LINES = 3;
14601
+ const preview = lines2.slice(0, MAX_DELETED_LINES);
14602
+ for (const line of preview) {
14603
+ log(source_default.red(` - ${line}`));
14604
+ }
14605
+ if (lines2.length > MAX_DELETED_LINES) {
14606
+ const remaining = lines2.length - MAX_DELETED_LINES;
14607
+ log(source_default.red(` ... and ${remaining} more lines deleted`));
14608
+ }
14609
+ }
14610
+ return;
14611
+ }
14612
+ if (diff.type === "updateSkillFileContent" /* updateSkillFileContent */) {
14613
+ const typedPayload = payload;
14614
+ if (typedPayload.isBase64) {
14615
+ log(source_default.green(" ~ [binary content changed]"));
14616
+ return;
14617
+ }
14618
+ }
14619
+ if (diff.type === "addRule" /* addRule */) {
14620
+ const item = payload.item;
14621
+ log(source_default.green(` + ${item.content}`));
14622
+ return;
14623
+ }
14624
+ if (diff.type === "deleteRule" /* deleteRule */) {
14625
+ const item = payload.item;
14626
+ log(source_default.red(` - ${item.content}`));
14627
+ return;
14628
+ }
14629
+ const oldValue = payload.oldValue;
14630
+ const newValue = payload.newValue;
14631
+ const { lines } = formatContentDiff(oldValue, newValue);
14632
+ for (const line of lines) {
14633
+ log(line);
14634
+ }
14635
+ }
14636
+ function formatSubmittedDate(isoDate) {
14637
+ const date = new Date(isoDate);
14638
+ const datePart = date.toLocaleDateString("en-US", {
14639
+ year: "numeric",
14640
+ month: "short",
14641
+ day: "numeric"
14642
+ });
14643
+ const timePart = date.toLocaleTimeString("en-US", {
14644
+ hour: "numeric",
14645
+ minute: "2-digit",
14646
+ hour12: true
14647
+ });
14648
+ return `${datePart} ${timePart}`;
14649
+ }
14650
+ function buildSubmittedFooter(submittedDiffs) {
14651
+ const proposalCount = submittedDiffs.length;
14652
+ const proposalWord = proposalCount === 1 ? "change proposal" : "change proposals";
14653
+ return `${proposalCount} ${proposalWord} ignored, run \`packmind-cli diff --include-submitted\` to see what's waiting for validation`;
14654
+ }
14655
+ async function readConfigAndPackages(deps) {
14656
+ const { packmindCliHexa, exit, getCwd, log, error } = deps;
14657
+ const cwd = getCwd();
14658
+ let configPackages;
14659
+ let configAgents;
14660
+ try {
14661
+ const fullConfig = await packmindCliHexa.readFullConfig(cwd);
14662
+ if (fullConfig) {
14663
+ configPackages = Object.keys(fullConfig.packages);
14664
+ configAgents = fullConfig.agents;
14665
+ } else {
14666
+ configPackages = [];
14667
+ }
14668
+ } catch (err) {
14669
+ error("ERROR Failed to parse packmind.json");
14670
+ if (err instanceof Error) {
14671
+ error(`ERROR ${err.message}`);
14672
+ } else {
14673
+ error(`ERROR ${String(err)}`);
14674
+ }
14675
+ error("\n\u{1F4A1} Please fix the packmind.json file or delete it to continue.");
14676
+ exit(1);
14677
+ return null;
14678
+ }
14679
+ if (configPackages.length === 0) {
14680
+ log("Usage: packmind-cli diff");
14681
+ log("");
14682
+ log("Compare local command files against the server.");
14683
+ log("Configure packages in packmind.json first.");
14684
+ exit(0);
14685
+ return null;
14686
+ }
14687
+ return { configPackages, configAgents };
14688
+ }
14689
+ async function collectGitInfo(deps) {
14690
+ const { packmindCliHexa, exit, getCwd, error } = deps;
14691
+ const cwd = getCwd();
14692
+ let gitRemoteUrl;
14693
+ let gitBranch;
14694
+ let relativePath;
14695
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
14696
+ if (gitRoot) {
14697
+ try {
14698
+ gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
14699
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
14700
+ relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
14701
+ if (!relativePath.startsWith("/")) {
14702
+ relativePath = "/" + relativePath;
14703
+ }
14704
+ if (!relativePath.endsWith("/")) {
14705
+ relativePath = relativePath + "/";
14706
+ }
14707
+ } catch (err) {
14708
+ logWarningConsole(
14709
+ `Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
14710
+ );
14711
+ }
14712
+ }
14713
+ if (!gitRemoteUrl || !gitBranch || !relativePath) {
14714
+ error(
14715
+ "\n\u274C Could not determine git repository info. The diff command requires a git repository with a remote configured."
14716
+ );
14717
+ exit(1);
14718
+ return null;
14719
+ }
14720
+ return { gitRemoteUrl, gitBranch, relativePath };
14721
+ }
14722
+ async function handleSubmission(params) {
14723
+ const { packmindCliHexa, unsubmittedItems, messageFlag, exit } = params;
14724
+ const unsubmittedDiffs = unsubmittedItems.map((r) => r.diff);
14725
+ if (unsubmittedDiffs.length === 0) {
14726
+ logInfoConsole("All changes already submitted.");
14727
+ return false;
14728
+ }
14729
+ let message;
14730
+ if (messageFlag !== void 0) {
14731
+ const validation = validateMessage(messageFlag);
14732
+ if (!validation.valid) {
14733
+ logErrorConsole(validation.error);
14734
+ exit(1);
14735
+ return true;
14736
+ }
14737
+ message = validation.message;
14738
+ } else if (process.stdin.isTTY) {
14739
+ const editorMessage = openEditorForMessage();
14740
+ const validation = validateMessage(editorMessage);
14741
+ if (!validation.valid) {
14742
+ logErrorConsole(
14743
+ "Aborting submission: empty message. Use -m to provide a message."
14744
+ );
14745
+ exit(1);
14746
+ return true;
14747
+ }
14748
+ message = validation.message;
14749
+ } else {
14750
+ logErrorConsole(
14751
+ 'Non-interactive mode requires -m flag. Use: packmind-cli diff --submit -m "your message"'
14752
+ );
14753
+ exit(1);
14754
+ return true;
14755
+ }
14756
+ const groupedUnsubmitted = Array.from(
14757
+ groupDiffsByArtefact(unsubmittedDiffs).values()
14758
+ );
14759
+ const result = await packmindCliHexa.submitDiffs(groupedUnsubmitted, message);
14760
+ for (const err of result.errors) {
14761
+ if (err.code === "ChangeProposalPayloadMismatchError") {
14762
+ logErrorConsole(
14763
+ `Failed to submit "${err.name}": ${err.artifactType ?? "artifact"} is outdated, please run \`packmind-cli install\` to update it`
14764
+ );
14765
+ } else {
14766
+ logErrorConsole(`Failed to submit "${err.name}": ${err.message}`);
14767
+ }
14768
+ }
14769
+ if (result.submitted > 0) {
14770
+ const truncatedMessage = message.length > 50 ? message.slice(0, 50) + "..." : message;
14771
+ logInfoConsole(`Message: "${truncatedMessage}"`);
14772
+ }
14773
+ const summaryParts = [];
14774
+ if (result.submitted > 0) {
14775
+ summaryParts.push(`${result.submitted} submitted`);
14776
+ }
14777
+ if (result.alreadySubmitted > 0) {
14778
+ summaryParts.push(`${result.alreadySubmitted} already submitted`);
14779
+ }
14780
+ if (result.errors.length > 0) {
14781
+ const errorWord = result.errors.length === 1 ? "error" : "errors";
14782
+ summaryParts.push(`${result.errors.length} ${errorWord}`);
14783
+ }
14784
+ if (summaryParts.length > 0) {
14785
+ const summaryMessage = `Summary: ${summaryParts.join(", ")}`;
14786
+ if (result.errors.length === 0 && result.alreadySubmitted === 0) {
14787
+ logSuccessConsole(summaryMessage);
14788
+ } else if (result.errors.length > 0 && result.submitted > 0 || result.alreadySubmitted > 0) {
14789
+ logWarningConsole(summaryMessage);
14790
+ } else {
14791
+ logErrorConsole(summaryMessage);
14792
+ }
14793
+ }
14794
+ return false;
14795
+ }
14796
+ function extractUniqueAndSortedArtefacts(groups) {
14797
+ const typeSortOrder = {
14798
+ command: 0,
14799
+ skill: 1,
14800
+ standard: 2
14801
+ };
14802
+ const uniqueArtefacts = /* @__PURE__ */ new Map();
14803
+ for (const [key, groupDiffs] of groups) {
14804
+ if (!uniqueArtefacts.has(key)) {
14805
+ uniqueArtefacts.set(key, {
14806
+ type: groupDiffs[0].artifactType,
14807
+ name: groupDiffs[0].artifactName
14808
+ });
14809
+ }
14810
+ }
14811
+ const sortedArtefacts = Array.from(uniqueArtefacts.values()).sort(
14812
+ (a, b) => typeSortOrder[a.type] - typeSortOrder[b.type] || a.name.localeCompare(b.name, void 0, { sensitivity: "base" })
14813
+ );
14814
+ return sortedArtefacts;
14815
+ }
14816
+ function displayDiffs(params) {
14817
+ const {
14818
+ diffsToDisplay,
14819
+ submittedLookup,
14820
+ includeSubmitted,
14821
+ unsubmittedItems,
14822
+ submittedItems,
14823
+ log
14824
+ } = params;
14825
+ log(formatHeader(`
14826
+ Changes found:
14827
+ `));
14828
+ const groups = groupDiffsByArtefact(diffsToDisplay);
14829
+ for (const [, groupDiffs] of groups) {
14830
+ const { artifactType, artifactName } = groupDiffs[0];
14831
+ const typeLabel = ARTIFACT_TYPE_LABELS[artifactType];
14832
+ log(formatBold(`${typeLabel} "${artifactName}"`));
14833
+ const subGroups = subGroupByChangeContent(groupDiffs);
14834
+ for (const subGroup of subGroups) {
14835
+ for (const diff of subGroup) {
14836
+ log(` ${formatFilePath(diff.filePath)}`);
14837
+ }
14838
+ const label = CHANGE_PROPOSAL_TYPE_LABELS[subGroup[0].type] ?? "content changed";
14839
+ const checkItem = submittedLookup.get(subGroup[0]);
14840
+ if (includeSubmitted && checkItem?.exists && checkItem.createdAt) {
14841
+ const dateStr = formatSubmittedDate(checkItem.createdAt);
14842
+ const messageSuffix = checkItem.message ? ` "${checkItem.message.length > 50 ? checkItem.message.slice(0, 50) + "..." : checkItem.message}"` : "";
14843
+ log(
14844
+ ` - ${label} ${source_default.dim(`[already submitted on ${dateStr}${messageSuffix}]`)}`
14845
+ );
14846
+ } else {
14847
+ log(` - ${label}`);
14848
+ }
14849
+ formatDiffPayload(subGroup[0], log);
14850
+ }
14851
+ log("");
14852
+ }
14853
+ const changeCount = diffsToDisplay.length;
14854
+ const changeWord = changeCount === 1 ? "change" : "changes";
14855
+ const sortedArtefacts = extractUniqueAndSortedArtefacts(groups);
14856
+ const artefactCount = sortedArtefacts.length;
14857
+ const artefactWord = artefactCount === 1 ? "artefact" : "artefacts";
14858
+ const allSubmittedSuffix = includeSubmitted && unsubmittedItems.length === 0 ? " (all already submitted)" : "";
14859
+ logWarningConsole(
14860
+ `Summary: ${changeCount} ${changeWord} found on ${artefactCount} ${artefactWord}${allSubmittedSuffix}:`
14861
+ );
14862
+ for (const artefact of sortedArtefacts) {
14863
+ const typeLabel = ARTIFACT_TYPE_LABELS[artefact.type];
14864
+ const key = `${artefact.type}:${artefact.name}`;
14865
+ const artefactDiffs = groups.get(key) ?? [];
14866
+ const allDiffsSubmitted = includeSubmitted && artefactDiffs.length > 0 && artefactDiffs.every((d) => submittedLookup.get(d)?.exists);
14867
+ const suffix = allDiffsSubmitted ? " (all already submitted)" : "";
14868
+ logWarningConsole(`* ${typeLabel} "${artefact.name}"${suffix}`);
14869
+ }
14870
+ if (!includeSubmitted && submittedItems.length > 0) {
14871
+ logInfoConsole(buildSubmittedFooter(submittedItems));
14872
+ }
14873
+ return changeCount;
14874
+ }
14875
+ async function diffArtefactsHandler(deps) {
14876
+ const {
14877
+ packmindCliHexa,
14878
+ exit,
14879
+ getCwd,
14880
+ log,
14881
+ error,
14882
+ submit,
14883
+ includeSubmitted,
14884
+ message: messageFlag
14885
+ } = deps;
14886
+ const cwd = getCwd();
14887
+ const config = await readConfigAndPackages(deps);
14888
+ if (!config) {
14889
+ return { diffsFound: 0 };
14890
+ }
14891
+ const { configPackages, configAgents } = config;
14892
+ try {
14893
+ const gitInfo = await collectGitInfo(deps);
14894
+ if (!gitInfo) {
14895
+ return { diffsFound: 0 };
14896
+ }
14897
+ const { gitRemoteUrl, gitBranch, relativePath } = gitInfo;
14898
+ const packageCount = configPackages.length;
14899
+ const packageWord = packageCount === 1 ? "package" : "packages";
14900
+ logInfoConsole(
14901
+ `Comparing ${packageCount} ${packageWord}: ${configPackages.join(", ")}...`
14902
+ );
14903
+ const diffs = await packmindCliHexa.diffArtefacts({
14904
+ baseDirectory: cwd,
14905
+ packagesSlugs: configPackages,
14906
+ gitRemoteUrl,
14907
+ gitBranch,
14908
+ relativePath,
14909
+ agents: configAgents
14910
+ });
14911
+ if (diffs.length === 0) {
14912
+ log("No changes found.");
14913
+ if (submit) {
14914
+ logInfoConsole("No changes to submit.");
14915
+ }
14916
+ exit(0);
14917
+ return { diffsFound: 0 };
14918
+ }
14919
+ const allGroupedDiffs = Array.from(groupDiffsByArtefact(diffs).values());
14920
+ const checkResult = await packmindCliHexa.checkDiffs(allGroupedDiffs);
14921
+ const submittedItems = checkResult.results.filter((r) => r.exists);
14922
+ const unsubmittedItems = checkResult.results.filter((r) => !r.exists);
14923
+ const diffsToDisplay = includeSubmitted ? diffs : unsubmittedItems.map((r) => r.diff);
14924
+ const submittedLookup = /* @__PURE__ */ new Map();
14925
+ for (const item of checkResult.results) {
14926
+ submittedLookup.set(item.diff, item);
14927
+ }
14928
+ if (diffsToDisplay.length === 0) {
14929
+ log("No new changes found.");
14930
+ if (submittedItems.length > 0) {
14931
+ logInfoConsole(buildSubmittedFooter(submittedItems));
14932
+ }
14933
+ if (submit) {
14934
+ logInfoConsole("All changes already submitted.");
14935
+ }
14936
+ exit(0);
14937
+ return { diffsFound: 0 };
14938
+ }
14939
+ const changeCount = displayDiffs({
14940
+ diffsToDisplay,
14941
+ submittedLookup,
14942
+ includeSubmitted,
14943
+ unsubmittedItems,
14944
+ submittedItems,
14945
+ log
14946
+ });
14947
+ if (submit) {
14948
+ const aborted = await handleSubmission({
14949
+ packmindCliHexa,
14950
+ unsubmittedItems,
14951
+ messageFlag,
14952
+ exit
14953
+ });
14954
+ if (aborted) {
14955
+ return { diffsFound: changeCount };
14956
+ }
14957
+ }
14958
+ exit(0);
14959
+ return { diffsFound: changeCount };
14960
+ } catch (err) {
14961
+ error("\n\u274C Failed to diff:");
14962
+ if (err instanceof Error) {
14963
+ error(` ${err.message}`);
14964
+ } else {
14965
+ error(` ${String(err)}`);
14966
+ }
14967
+ exit(1);
14968
+ return { diffsFound: 0 };
14969
+ }
14970
+ }
14971
+
14972
+ // apps/cli/src/infra/commands/DiffCommand.ts
14973
+ var diffCommand = (0, import_cmd_ts19.command)({
14974
+ name: "diff",
14975
+ description: "Show differences between local command files and server content",
14976
+ args: {
14977
+ submit: (0, import_cmd_ts19.flag)({
14978
+ long: "submit",
14979
+ description: "Submit detected changes as change proposals"
14980
+ }),
14981
+ includeSubmitted: (0, import_cmd_ts19.flag)({
14982
+ long: "include-submitted",
14983
+ description: "Include already submitted changes in the output"
14984
+ }),
14985
+ message: (0, import_cmd_ts19.option)({
14986
+ long: "message",
14987
+ short: "m",
14988
+ description: "Message describing the intent behind the changes (max 1024 chars)",
14989
+ type: (0, import_cmd_ts19.optional)(import_cmd_ts19.string)
14990
+ })
14991
+ },
14992
+ handler: async ({ submit, includeSubmitted, message }) => {
14993
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
14994
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
14995
+ await diffArtefactsHandler({
14996
+ packmindCliHexa,
14997
+ exit: process.exit,
14998
+ getCwd: () => process.cwd(),
14999
+ log: console.log,
15000
+ error: console.error,
15001
+ submit,
15002
+ includeSubmitted,
15003
+ message
15004
+ });
15005
+ }
15006
+ });
15007
+
13218
15008
  // apps/cli/src/infra/commands/PackagesCommand.ts
13219
- var import_cmd_ts22 = __toESM(require_cjs());
15009
+ var import_cmd_ts23 = __toESM(require_cjs());
13220
15010
 
13221
15011
  // apps/cli/src/infra/commands/CreatePackageCommand.ts
13222
- var import_cmd_ts19 = __toESM(require_cjs());
15012
+ var import_cmd_ts20 = __toESM(require_cjs());
13223
15013
 
13224
15014
  // apps/cli/src/infra/commands/createPackageHandler.ts
13225
15015
  function buildWebappUrl2(host, orgSlug, packageId) {
@@ -13268,15 +15058,15 @@ var CreatePackageUseCase = class {
13268
15058
  constructor(gateway) {
13269
15059
  this.gateway = gateway;
13270
15060
  }
13271
- async execute(command20) {
15061
+ async execute(command21) {
13272
15062
  const space = await this.gateway.spaces.getGlobal();
13273
15063
  const result = await this.gateway.packages.create({
13274
15064
  spaceId: space.id,
13275
- name: command20.name,
13276
- description: command20.description ?? "",
15065
+ name: command21.name,
15066
+ description: command21.description ?? "",
13277
15067
  recipeIds: [],
13278
15068
  standardIds: [],
13279
- originSkill: command20.originSkill
15069
+ originSkill: command21.originSkill
13280
15070
  });
13281
15071
  return {
13282
15072
  packageId: result.package.id,
@@ -13287,20 +15077,20 @@ var CreatePackageUseCase = class {
13287
15077
  };
13288
15078
 
13289
15079
  // apps/cli/src/infra/commands/CreatePackageCommand.ts
13290
- var createPackageCommand = (0, import_cmd_ts19.command)({
15080
+ var createPackageCommand = (0, import_cmd_ts20.command)({
13291
15081
  name: "create",
13292
15082
  description: "Create a new package",
13293
15083
  args: {
13294
- name: (0, import_cmd_ts19.positional)({
15084
+ name: (0, import_cmd_ts20.positional)({
13295
15085
  displayName: "name",
13296
15086
  description: "Name of the package to create",
13297
- type: import_cmd_ts19.string
15087
+ type: import_cmd_ts20.string
13298
15088
  }),
13299
- description: (0, import_cmd_ts19.option)({
15089
+ description: (0, import_cmd_ts20.option)({
13300
15090
  long: "description",
13301
15091
  short: "d",
13302
15092
  description: "Description of the package (optional)",
13303
- type: (0, import_cmd_ts19.optional)(import_cmd_ts19.string)
15093
+ type: (0, import_cmd_ts20.optional)(import_cmd_ts20.string)
13304
15094
  }),
13305
15095
  originSkill: originSkillOption
13306
15096
  },
@@ -13349,7 +15139,7 @@ var createPackageCommand = (0, import_cmd_ts19.command)({
13349
15139
  });
13350
15140
 
13351
15141
  // apps/cli/src/infra/commands/AddToPackageCommand.ts
13352
- var import_cmd_ts20 = __toESM(require_cjs());
15142
+ var import_cmd_ts21 = __toESM(require_cjs());
13353
15143
 
13354
15144
  // apps/cli/src/domain/errors/ItemNotFoundError.ts
13355
15145
  var ItemNotFoundError = class extends Error {
@@ -13366,8 +15156,8 @@ var AddToPackageUseCase = class {
13366
15156
  constructor(gateway) {
13367
15157
  this.gateway = gateway;
13368
15158
  }
13369
- async execute(command20) {
13370
- const { packageSlug, itemType, itemSlugs } = command20;
15159
+ async execute(command21) {
15160
+ const { packageSlug, itemType, itemSlugs } = command21;
13371
15161
  const space = await this.gateway.spaces.getGlobal();
13372
15162
  const packages = await this.gateway.packages.list({});
13373
15163
  const pkg = packages.packages.find((pkg2) => pkg2.slug === packageSlug);
@@ -13384,7 +15174,7 @@ var AddToPackageUseCase = class {
13384
15174
  standardIds: [],
13385
15175
  recipeIds: [],
13386
15176
  skillIds: [],
13387
- originSkill: command20.originSkill
15177
+ originSkill: command21.originSkill
13388
15178
  };
13389
15179
  if (itemType === "standard") {
13390
15180
  addCommand.standardIds = ids.map(createStandardId);
@@ -13429,7 +15219,7 @@ var AddToPackageUseCase = class {
13429
15219
  }
13430
15220
  async findCommandBySlug(slug, spaceId) {
13431
15221
  const commands = await this.gateway.commands.list({ spaceId });
13432
- return commands.recipes.find((command20) => command20.slug === slug) ?? null;
15222
+ return commands.recipes.find((command21) => command21.slug === slug) ?? null;
13433
15223
  }
13434
15224
  async findSkillBySlug(slug, spaceId) {
13435
15225
  const skills = await this.gateway.skills.list({ spaceId });
@@ -13485,29 +15275,29 @@ async function addToPackageHandler(packageSlug, itemType, itemSlugs, useCase, or
13485
15275
  }
13486
15276
 
13487
15277
  // apps/cli/src/infra/commands/AddToPackageCommand.ts
13488
- var addToPackageCommand = (0, import_cmd_ts20.command)({
15278
+ var addToPackageCommand = (0, import_cmd_ts21.command)({
13489
15279
  name: "add",
13490
15280
  description: "Add standards, commands, or skills to a package",
13491
15281
  args: {
13492
- to: (0, import_cmd_ts20.option)({
15282
+ to: (0, import_cmd_ts21.option)({
13493
15283
  long: "to",
13494
15284
  description: "Target package slug",
13495
- type: import_cmd_ts20.string
15285
+ type: import_cmd_ts21.string
13496
15286
  }),
13497
- standards: (0, import_cmd_ts20.multioption)({
15287
+ standards: (0, import_cmd_ts21.multioption)({
13498
15288
  long: "standard",
13499
15289
  description: "Standard slug(s) to add",
13500
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
15290
+ type: (0, import_cmd_ts21.array)(import_cmd_ts21.string)
13501
15291
  }),
13502
- commands: (0, import_cmd_ts20.multioption)({
15292
+ commands: (0, import_cmd_ts21.multioption)({
13503
15293
  long: "command",
13504
15294
  description: "Command slug(s) to add",
13505
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
15295
+ type: (0, import_cmd_ts21.array)(import_cmd_ts21.string)
13506
15296
  }),
13507
- skills: (0, import_cmd_ts20.multioption)({
15297
+ skills: (0, import_cmd_ts21.multioption)({
13508
15298
  long: "skill",
13509
15299
  description: "Skill slug(s) to add",
13510
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
15300
+ type: (0, import_cmd_ts21.array)(import_cmd_ts21.string)
13511
15301
  }),
13512
15302
  originSkill: originSkillOption
13513
15303
  },
@@ -13551,8 +15341,8 @@ var addToPackageCommand = (0, import_cmd_ts20.command)({
13551
15341
  });
13552
15342
 
13553
15343
  // apps/cli/src/infra/commands/listPackagesCommand.ts
13554
- var import_cmd_ts21 = __toESM(require_cjs());
13555
- var listPackagesCommand = (0, import_cmd_ts21.command)({
15344
+ var import_cmd_ts22 = __toESM(require_cjs());
15345
+ var listPackagesCommand = (0, import_cmd_ts22.command)({
13556
15346
  name: "list",
13557
15347
  description: "List available packages",
13558
15348
  args: {},
@@ -13571,7 +15361,7 @@ var listPackagesCommand = (0, import_cmd_ts21.command)({
13571
15361
  });
13572
15362
 
13573
15363
  // apps/cli/src/infra/commands/PackagesCommand.ts
13574
- var packagesCommand = (0, import_cmd_ts22.subcommands)({
15364
+ var packagesCommand = (0, import_cmd_ts23.subcommands)({
13575
15365
  name: "packages",
13576
15366
  description: "Manage packages",
13577
15367
  cmds: {
@@ -13582,14 +15372,14 @@ var packagesCommand = (0, import_cmd_ts22.subcommands)({
13582
15372
  });
13583
15373
 
13584
15374
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
13585
- var import_cmd_ts24 = __toESM(require_cjs());
15375
+ var import_cmd_ts25 = __toESM(require_cjs());
13586
15376
 
13587
15377
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
13588
- var import_cmd_ts23 = __toESM(require_cjs());
15378
+ var import_cmd_ts24 = __toESM(require_cjs());
13589
15379
 
13590
15380
  // apps/cli/src/application/services/AgentArtifactDetectionService.ts
13591
- var fs15 = __toESM(require("fs/promises"));
13592
- var path12 = __toESM(require("path"));
15381
+ var fs18 = __toESM(require("fs/promises"));
15382
+ var path16 = __toESM(require("path"));
13593
15383
  var AGENT_ARTIFACT_CHECKS = [
13594
15384
  { agent: "claude", paths: [".claude"] },
13595
15385
  { agent: "cursor", paths: [".cursor"] },
@@ -13607,7 +15397,7 @@ var AgentArtifactDetectionService = class {
13607
15397
  const detected = [];
13608
15398
  for (const check of AGENT_ARTIFACT_CHECKS) {
13609
15399
  for (const relativePath of check.paths) {
13610
- const fullPath = path12.join(baseDirectory, relativePath);
15400
+ const fullPath = path16.join(baseDirectory, relativePath);
13611
15401
  const exists = await this.pathExists(fullPath);
13612
15402
  if (exists) {
13613
15403
  detected.push({
@@ -13622,7 +15412,7 @@ var AgentArtifactDetectionService = class {
13622
15412
  }
13623
15413
  async pathExists(filePath) {
13624
15414
  try {
13625
- await fs15.access(filePath);
15415
+ await fs18.access(filePath);
13626
15416
  return true;
13627
15417
  } catch {
13628
15418
  return false;
@@ -13745,7 +15535,7 @@ async function getPreselectedAgents(deps) {
13745
15535
  }
13746
15536
 
13747
15537
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
13748
- var configAgentsCommand = (0, import_cmd_ts23.command)({
15538
+ var configAgentsCommand = (0, import_cmd_ts24.command)({
13749
15539
  name: "agents",
13750
15540
  description: "Configure which coding agents to generate artifacts for",
13751
15541
  args: {},
@@ -13765,7 +15555,7 @@ var configAgentsCommand = (0, import_cmd_ts23.command)({
13765
15555
  });
13766
15556
 
13767
15557
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
13768
- var configCommand = (0, import_cmd_ts24.subcommands)({
15558
+ var configCommand = (0, import_cmd_ts25.subcommands)({
13769
15559
  name: "config",
13770
15560
  description: "Manage Packmind configuration",
13771
15561
  cmds: {
@@ -13774,7 +15564,7 @@ var configCommand = (0, import_cmd_ts24.subcommands)({
13774
15564
  });
13775
15565
 
13776
15566
  // apps/cli/src/infra/commands/InitCommand.ts
13777
- var import_cmd_ts25 = __toESM(require_cjs());
15567
+ var import_cmd_ts26 = __toESM(require_cjs());
13778
15568
 
13779
15569
  // apps/cli/src/infra/commands/initHandler.ts
13780
15570
  async function initHandler(deps) {
@@ -13831,7 +15621,7 @@ async function initHandler(deps) {
13831
15621
 
13832
15622
  // apps/cli/src/infra/commands/InitCommand.ts
13833
15623
  var { version: CLI_VERSION3 } = require_package();
13834
- var initCommand = (0, import_cmd_ts25.command)({
15624
+ var initCommand = (0, import_cmd_ts26.command)({
13835
15625
  name: "init",
13836
15626
  description: "Initialize Packmind in the current project",
13837
15627
  args: {},
@@ -13864,20 +15654,20 @@ function findEnvFile() {
13864
15654
  const currentDir = process.cwd();
13865
15655
  const gitService = new GitService();
13866
15656
  const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
13867
- const filesystemRoot = path13.parse(currentDir).root;
15657
+ const filesystemRoot = path17.parse(currentDir).root;
13868
15658
  const stopDir = gitRoot ?? filesystemRoot;
13869
15659
  let searchDir = currentDir;
13870
- let parentDir = path13.dirname(searchDir);
15660
+ let parentDir = path17.dirname(searchDir);
13871
15661
  while (searchDir !== parentDir) {
13872
- const envPath2 = path13.join(searchDir, ".env");
13873
- if (fs16.existsSync(envPath2)) {
15662
+ const envPath2 = path17.join(searchDir, ".env");
15663
+ if (fs19.existsSync(envPath2)) {
13874
15664
  return envPath2;
13875
15665
  }
13876
15666
  if (searchDir === stopDir) {
13877
15667
  return null;
13878
15668
  }
13879
15669
  searchDir = parentDir;
13880
- parentDir = path13.dirname(searchDir);
15670
+ parentDir = path17.dirname(searchDir);
13881
15671
  }
13882
15672
  return null;
13883
15673
  }
@@ -13897,12 +15687,13 @@ if (args.includes("--version") || args.includes("-v")) {
13897
15687
  logConsole(`packmind-cli version ${CLI_VERSION4}`);
13898
15688
  process.exit(0);
13899
15689
  }
13900
- var app = (0, import_cmd_ts26.subcommands)({
15690
+ var app = (0, import_cmd_ts27.subcommands)({
13901
15691
  name: "packmind-cli",
13902
15692
  description: "Packmind CLI tool",
13903
15693
  cmds: {
13904
15694
  commands: commandsCommand,
13905
15695
  config: configCommand,
15696
+ diff: diffCommand,
13906
15697
  init: initCommand,
13907
15698
  install: installCommand,
13908
15699
  lint: lintCommand,
@@ -13918,7 +15709,7 @@ var app = (0, import_cmd_ts26.subcommands)({
13918
15709
  whoami: whoamiCommand
13919
15710
  }
13920
15711
  });
13921
- (0, import_cmd_ts26.run)(app, args).catch((error) => {
15712
+ (0, import_cmd_ts27.run)(app, args).catch((error) => {
13922
15713
  logErrorConsole(error.message);
13923
15714
  process.exit(1);
13924
15715
  });