@packmind/cli 0.11.0 → 0.13.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 +608 -246
  2. package/package.json +1 -1
package/main.cjs CHANGED
@@ -371,32 +371,32 @@ var init_supports_color = __esm({
371
371
  });
372
372
 
373
373
  // node_modules/chalk/source/utilities.js
374
- function stringReplaceAll(string5, substring, replacer) {
375
- let index = string5.indexOf(substring);
374
+ function stringReplaceAll(string6, substring, replacer) {
375
+ let index = string6.indexOf(substring);
376
376
  if (index === -1) {
377
- return string5;
377
+ return string6;
378
378
  }
379
379
  const substringLength = substring.length;
380
380
  let endIndex = 0;
381
381
  let returnValue = "";
382
382
  do {
383
- returnValue += string5.slice(endIndex, index) + substring + replacer;
383
+ returnValue += string6.slice(endIndex, index) + substring + replacer;
384
384
  endIndex = index + substringLength;
385
- index = string5.indexOf(substring, endIndex);
385
+ index = string6.indexOf(substring, endIndex);
386
386
  } while (index !== -1);
387
- returnValue += string5.slice(endIndex);
387
+ returnValue += string6.slice(endIndex);
388
388
  return returnValue;
389
389
  }
390
- function stringEncaseCRLFWithFirstIndex(string5, prefix, postfix, index) {
390
+ function stringEncaseCRLFWithFirstIndex(string6, prefix, postfix, index) {
391
391
  let endIndex = 0;
392
392
  let returnValue = "";
393
393
  do {
394
- const gotCR = string5[index - 1] === "\r";
395
- returnValue += string5.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
394
+ const gotCR = string6[index - 1] === "\r";
395
+ returnValue += string6.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
396
  endIndex = index + 1;
397
- index = string5.indexOf("\n", endIndex);
397
+ index = string6.indexOf("\n", endIndex);
398
398
  } while (index !== -1);
399
- returnValue += string5.slice(endIndex);
399
+ returnValue += string6.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, string5) => {
559
- if (self.level <= 0 || !string5) {
560
- return self[IS_EMPTY] ? "" : string5;
558
+ applyStyle = (self, string6) => {
559
+ if (self.level <= 0 || !string6) {
560
+ return self[IS_EMPTY] ? "" : string6;
561
561
  }
562
562
  let styler = self[STYLER];
563
563
  if (styler === void 0) {
564
- return string5;
564
+ return string6;
565
565
  }
566
566
  const { openAll, closeAll } = styler;
567
- if (string5.includes("\x1B")) {
567
+ if (string6.includes("\x1B")) {
568
568
  while (styler !== void 0) {
569
- string5 = stringReplaceAll(string5, styler.close, styler.open);
569
+ string6 = stringReplaceAll(string6, styler.close, styler.open);
570
570
  styler = styler.parent;
571
571
  }
572
572
  }
573
- const lfIndex = string5.indexOf("\n");
573
+ const lfIndex = string6.indexOf("\n");
574
574
  if (lfIndex !== -1) {
575
- string5 = stringEncaseCRLFWithFirstIndex(string5, closeAll, openAll, lfIndex);
575
+ string6 = stringEncaseCRLFWithFirstIndex(string6, closeAll, openAll, lfIndex);
576
576
  }
577
- return openAll + string5 + closeAll;
577
+ return openAll + string6 + closeAll;
578
578
  };
579
579
  Object.defineProperties(createChalk.prototype, styles2);
580
580
  chalk = createChalk();
@@ -1255,7 +1255,7 @@ var require_positional = __commonJS({
1255
1255
  return mod && mod.__esModule ? mod : { "default": mod };
1256
1256
  };
1257
1257
  Object.defineProperty(exports2, "__esModule", { value: true });
1258
- exports2.positional = positional2;
1258
+ exports2.positional = positional3;
1259
1259
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1260
1260
  var Result = __importStar(require_Result());
1261
1261
  var types_1 = require_types();
@@ -1295,8 +1295,8 @@ var require_positional = __commonJS({
1295
1295
  var _a2;
1296
1296
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
1297
1297
  const defaultValueFn = (_a2 = config.defaultValue) !== null && _a2 !== void 0 ? _a2 : config.type.defaultValue;
1298
- const positional3 = positionals[0];
1299
- if (!positional3) {
1298
+ const positional4 = positionals[0];
1299
+ if (!positional4) {
1300
1300
  if (defaultValueFn) {
1301
1301
  return Result.ok(defaultValueFn());
1302
1302
  }
@@ -1309,13 +1309,13 @@ var require_positional = __commonJS({
1309
1309
  ]
1310
1310
  });
1311
1311
  }
1312
- visitedNodes.add(positional3);
1313
- const decoded = await Result.safeAsync(config.type.from(positional3.raw));
1312
+ visitedNodes.add(positional4);
1313
+ const decoded = await Result.safeAsync(config.type.from(positional4.raw));
1314
1314
  if (Result.isErr(decoded)) {
1315
1315
  return Result.err({
1316
1316
  errors: [
1317
1317
  {
1318
- nodes: [positional3],
1318
+ nodes: [positional4],
1319
1319
  message: decoded.error.message
1320
1320
  }
1321
1321
  ]
@@ -1325,7 +1325,7 @@ var require_positional = __commonJS({
1325
1325
  }
1326
1326
  };
1327
1327
  }
1328
- function positional2(config) {
1328
+ function positional3(config) {
1329
1329
  return fullPositional({
1330
1330
  type: types_1.string,
1331
1331
  ...config
@@ -1379,13 +1379,13 @@ var require_subcommands = __commonJS({
1379
1379
  return mod && mod.__esModule ? mod : { "default": mod };
1380
1380
  };
1381
1381
  Object.defineProperty(exports2, "__esModule", { value: true });
1382
- exports2.subcommands = subcommands2;
1382
+ exports2.subcommands = subcommands3;
1383
1383
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1384
1384
  var didyoumean_1 = __importDefault(require_didYouMean_1_2_1());
1385
1385
  var Result = __importStar(require_Result());
1386
1386
  var circuitbreaker_1 = require_circuitbreaker();
1387
1387
  var positional_1 = require_positional();
1388
- function subcommands2(config) {
1388
+ function subcommands3(config) {
1389
1389
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1390
1390
  const type = {
1391
1391
  async from(str) {
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
1578
1578
  __export(strip_ansi_exports, {
1579
1579
  default: () => stripAnsi
1580
1580
  });
1581
- function stripAnsi(string5) {
1582
- if (typeof string5 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string5}\``);
1581
+ function stripAnsi(string6) {
1582
+ if (typeof string6 !== "string") {
1583
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string6}\``);
1584
1584
  }
1585
- return string5.replace(regex, "");
1585
+ return string6.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 = command8;
1701
+ exports2.command = command9;
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 command8(config) {
1706
+ function command9(config) {
1707
1707
  const argEntries = (0, utils_1.entries)(config.args);
1708
1708
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1709
1709
  return {
@@ -3084,8 +3084,8 @@ var require_tokenizer = __commonJS({
3084
3084
  tokens.push(token);
3085
3085
  overallIndex += token.raw.length;
3086
3086
  };
3087
- for (const [stringIndex, string5] of (0, utils_1.enumerate)(strings)) {
3088
- const chars = [...string5];
3087
+ for (const [stringIndex, string6] of (0, utils_1.enumerate)(strings)) {
3088
+ const chars = [...string6];
3089
3089
  for (let i = 0; i < chars.length; i++) {
3090
3090
  if (chars[i] === "-" && chars[i + 1] === "-") {
3091
3091
  push({ type: "longPrefix", raw: "--", index: overallIndex });
@@ -3241,14 +3241,14 @@ var require_restPositionals = __commonJS({
3241
3241
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
3242
3242
  const results = [];
3243
3243
  const errors = [];
3244
- for (const positional2 of positionals) {
3245
- visitedNodes.add(positional2);
3246
- const decoded = await Result.safeAsync(config.type.from(positional2.raw));
3244
+ for (const positional3 of positionals) {
3245
+ visitedNodes.add(positional3);
3246
+ const decoded = await Result.safeAsync(config.type.from(positional3.raw));
3247
3247
  if (Result.isOk(decoded)) {
3248
3248
  results.push(decoded.value);
3249
3249
  } else {
3250
3250
  errors.push({
3251
- nodes: [positional2],
3251
+ nodes: [positional3],
3252
3252
  message: decoded.error.message
3253
3253
  });
3254
3254
  }
@@ -3852,7 +3852,7 @@ var require_package = __commonJS({
3852
3852
  "apps/cli/package.json"(exports2, module2) {
3853
3853
  module2.exports = {
3854
3854
  name: "@packmind/cli",
3855
- version: "0.11.0",
3855
+ version: "0.13.0",
3856
3856
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3857
  private: false,
3858
3858
  bin: {
@@ -3894,7 +3894,7 @@ var require_package = __commonJS({
3894
3894
  });
3895
3895
 
3896
3896
  // apps/cli/src/main.ts
3897
- var import_cmd_ts8 = __toESM(require_cjs());
3897
+ var import_cmd_ts10 = __toESM(require_cjs());
3898
3898
 
3899
3899
  // apps/cli/src/infra/commands/LinterCommand.ts
3900
3900
  var import_cmd_ts = __toESM(require_cjs());
@@ -4021,28 +4021,28 @@ var UserEvent = class extends PackmindEvent {
4021
4021
  };
4022
4022
 
4023
4023
  // packages/types/src/accounts/events/UserSignedUpEvent.ts
4024
- var UserSignedUpEvent = class extends PackmindEvent {
4024
+ var UserSignedUpEvent = class extends UserEvent {
4025
4025
  static {
4026
- this.eventName = "accounts.user.signed_up";
4026
+ this.eventName = "accounts.user.signed-up";
4027
4027
  }
4028
4028
  };
4029
4029
 
4030
4030
  // packages/types/src/accounts/events/UserJoinedOrganizationEvent.ts
4031
- var UserJoinedOrganizationEvent = class extends PackmindEvent {
4031
+ var UserJoinedOrganizationEvent = class extends UserEvent {
4032
4032
  static {
4033
- this.eventName = "accounts.user.joined_organization";
4033
+ this.eventName = "accounts.user.joined-organization";
4034
4034
  }
4035
4035
  };
4036
4036
 
4037
4037
  // packages/types/src/accounts/events/AnonymousTrialStartedEvent.ts
4038
- var AnonymousTrialStartedEvent = class extends PackmindEvent {
4038
+ var AnonymousTrialStartedEvent = class extends UserEvent {
4039
4039
  static {
4040
4040
  this.eventName = "accounts.anonymous-trial.started";
4041
4041
  }
4042
4042
  };
4043
4043
 
4044
4044
  // packages/types/src/accounts/events/AnonymousTrialAccountActivatedEvent.ts
4045
- var AnonymousTrialAccountActivatedEvent = class extends PackmindEvent {
4045
+ var AnonymousTrialAccountActivatedEvent = class extends UserEvent {
4046
4046
  static {
4047
4047
  this.eventName = "accounts.anonymous-trial.activated";
4048
4048
  }
@@ -4082,6 +4082,33 @@ var CommandUpdatedEvent = class extends UserEvent {
4082
4082
  // packages/types/src/skills/SkillId.ts
4083
4083
  var createSkillId = brandedIdFactory();
4084
4084
 
4085
+ // packages/types/src/skills/SkillVersionId.ts
4086
+ var createSkillVersionId = brandedIdFactory();
4087
+
4088
+ // packages/types/src/skills/SkillFileId.ts
4089
+ var createSkillFileId = brandedIdFactory();
4090
+
4091
+ // packages/types/src/skills/events/SkillCreatedEvent.ts
4092
+ var SkillCreatedEvent = class extends UserEvent {
4093
+ static {
4094
+ this.eventName = "skills.skill.created";
4095
+ }
4096
+ };
4097
+
4098
+ // packages/types/src/skills/events/SkillUpdatedEvent.ts
4099
+ var SkillUpdatedEvent = class extends UserEvent {
4100
+ static {
4101
+ this.eventName = "skills.skill.updated";
4102
+ }
4103
+ };
4104
+
4105
+ // packages/types/src/skills/events/SkillDeletedEvent.ts
4106
+ var SkillDeletedEvent = class extends UserEvent {
4107
+ static {
4108
+ this.eventName = "skills.skill.deleted";
4109
+ }
4110
+ };
4111
+
4085
4112
  // packages/types/src/deployments/TargetId.ts
4086
4113
  var createTargetId = brandedIdFactory();
4087
4114
 
@@ -4168,6 +4195,13 @@ var RuleAddedEvent = class extends UserEvent {
4168
4195
  }
4169
4196
  };
4170
4197
 
4198
+ // packages/types/src/standards/events/RuleUpdatedEvent.ts
4199
+ var RuleUpdatedEvent = class extends UserEvent {
4200
+ static {
4201
+ this.eventName = "standards.rule.updated";
4202
+ }
4203
+ };
4204
+
4171
4205
  // packages/types/src/standards/events/StandardCreatedEvent.ts
4172
4206
  var StandardCreatedEvent = class extends UserEvent {
4173
4207
  static {
@@ -4706,8 +4740,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
4706
4740
  static {
4707
4741
  this.fallbackRuleContent = "adhoc-rule";
4708
4742
  }
4709
- async execute(command8) {
4710
- const { program, fileContent, language } = command8;
4743
+ async execute(command9) {
4744
+ const { program, fileContent, language } = command9;
4711
4745
  const result = await this.linterExecutionUseCase.execute({
4712
4746
  filePath: "cli-single-file",
4713
4747
  fileContent,
@@ -4745,30 +4779,30 @@ var GitService = class {
4745
4779
  this.gitRunner = gitRunner;
4746
4780
  this.logger = logger2;
4747
4781
  }
4748
- getGitRepositoryRoot(path11) {
4782
+ getGitRepositoryRoot(path12) {
4749
4783
  try {
4750
4784
  const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
4751
- cwd: path11
4785
+ cwd: path12
4752
4786
  });
4753
4787
  const gitRoot = stdout.trim();
4754
4788
  this.logger.debug("Resolved git repository root", {
4755
- inputPath: path11,
4789
+ inputPath: path12,
4756
4790
  gitRoot
4757
4791
  });
4758
4792
  return gitRoot;
4759
4793
  } catch (error) {
4760
4794
  if (error instanceof Error) {
4761
4795
  throw new Error(
4762
- `Failed to get Git repository root. The path '${path11}' does not appear to be inside a Git repository.
4796
+ `Failed to get Git repository root. The path '${path12}' does not appear to be inside a Git repository.
4763
4797
  ${error.message}`
4764
4798
  );
4765
4799
  }
4766
4800
  throw new Error("Failed to get Git repository root: Unknown error");
4767
4801
  }
4768
4802
  }
4769
- tryGetGitRepositoryRoot(path11) {
4803
+ tryGetGitRepositoryRoot(path12) {
4770
4804
  try {
4771
- return this.getGitRepositoryRoot(path11);
4805
+ return this.getGitRepositoryRoot(path12);
4772
4806
  } catch {
4773
4807
  return null;
4774
4808
  }
@@ -5075,8 +5109,8 @@ var GetGitRemoteUrlUseCase = class {
5075
5109
  constructor(gitRemoteUrlService = new GitService()) {
5076
5110
  this.gitRemoteUrlService = gitRemoteUrlService;
5077
5111
  }
5078
- async execute(command8) {
5079
- const { path: repoPath, origin: origin11 } = command8;
5112
+ async execute(command9) {
5113
+ const { path: repoPath, origin: origin11 } = command9;
5080
5114
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin11);
5081
5115
  }
5082
5116
  };
@@ -5176,8 +5210,8 @@ var ListFilesInDirectoryUseCase = class {
5176
5210
  constructor(listFiles = new ListFiles()) {
5177
5211
  this.listFiles = listFiles;
5178
5212
  }
5179
- async execute(command8) {
5180
- const { path: directoryPath, extensions, excludes = [] } = command8;
5213
+ async execute(command9) {
5214
+ const { path: directoryPath, extensions, excludes = [] } = command9;
5181
5215
  const files = await this.listFiles.listFilesInDirectory(
5182
5216
  directoryPath,
5183
5217
  extensions,
@@ -5262,7 +5296,7 @@ var LintFilesInDirectoryUseCase = class {
5262
5296
  }
5263
5297
  return pattern;
5264
5298
  }
5265
- async execute(command8) {
5299
+ async execute(command9) {
5266
5300
  const {
5267
5301
  path: userPath,
5268
5302
  draftMode,
@@ -5270,7 +5304,7 @@ var LintFilesInDirectoryUseCase = class {
5270
5304
  ruleId,
5271
5305
  language,
5272
5306
  diffMode
5273
- } = command8;
5307
+ } = command9;
5274
5308
  this.logger.debug(
5275
5309
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
5276
5310
  );
@@ -5589,8 +5623,8 @@ var LintFilesInDirectoryUseCase = class {
5589
5623
  return null;
5590
5624
  }
5591
5625
  }
5592
- async executeProgramsForFile(command8) {
5593
- const result = await this.services.linterExecutionUseCase.execute(command8);
5626
+ async executeProgramsForFile(command9) {
5627
+ const result = await this.services.linterExecutionUseCase.execute(command9);
5594
5628
  return result.violations;
5595
5629
  }
5596
5630
  extractExtensionFromFile(filePath) {
@@ -5647,8 +5681,8 @@ var LintFilesLocallyUseCase = class {
5647
5681
  }
5648
5682
  return pattern;
5649
5683
  }
5650
- async execute(command8) {
5651
- const { path: userPath, diffMode } = command8;
5684
+ async execute(command9) {
5685
+ const { path: userPath, diffMode } = command9;
5652
5686
  this.logger.debug(
5653
5687
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
5654
5688
  );
@@ -5890,8 +5924,8 @@ var LintFilesLocallyUseCase = class {
5890
5924
  return null;
5891
5925
  }
5892
5926
  }
5893
- async executeProgramsForFile(command8) {
5894
- const result = await this.services.linterExecutionUseCase.execute(command8);
5927
+ async executeProgramsForFile(command9) {
5928
+ const result = await this.services.linterExecutionUseCase.execute(command9);
5895
5929
  return result.violations;
5896
5930
  }
5897
5931
  extractExtensionFromFile(filePath) {
@@ -5903,6 +5937,129 @@ var LintFilesLocallyUseCase = class {
5903
5937
  }
5904
5938
  };
5905
5939
 
5940
+ // apps/cli/src/infra/utils/readSkillDirectory.ts
5941
+ var import_promises = __toESM(require("fs/promises"));
5942
+ var import_path = __toESM(require("path"));
5943
+ function normalizePath(filePath) {
5944
+ let normalized = filePath.replace(/\\/g, "/");
5945
+ if (normalized.startsWith("/") || normalized.startsWith("\\")) {
5946
+ normalized = normalized.substring(1);
5947
+ }
5948
+ return normalized;
5949
+ }
5950
+ function normalizeLineEndings(content) {
5951
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
5952
+ }
5953
+ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
5954
+ // Images
5955
+ ".png",
5956
+ ".jpg",
5957
+ ".jpeg",
5958
+ ".gif",
5959
+ ".bmp",
5960
+ ".ico",
5961
+ ".webp",
5962
+ ".tiff",
5963
+ ".tif",
5964
+ ".heic",
5965
+ ".heif",
5966
+ ".avif",
5967
+ // Documents
5968
+ ".pdf",
5969
+ // Archives
5970
+ ".zip",
5971
+ ".tar",
5972
+ ".gz",
5973
+ ".rar",
5974
+ ".7z",
5975
+ ".bz2",
5976
+ ".xz",
5977
+ // Audio
5978
+ ".mp3",
5979
+ ".wav",
5980
+ ".ogg",
5981
+ ".flac",
5982
+ ".m4a",
5983
+ ".aac",
5984
+ // Video
5985
+ ".mp4",
5986
+ ".avi",
5987
+ ".mkv",
5988
+ ".mov",
5989
+ ".webm",
5990
+ ".wmv",
5991
+ // Executables/Libraries
5992
+ ".exe",
5993
+ ".dll",
5994
+ ".so",
5995
+ ".dylib",
5996
+ // Fonts
5997
+ ".ttf",
5998
+ ".otf",
5999
+ ".woff",
6000
+ ".woff2",
6001
+ ".eot",
6002
+ // Other binary formats
6003
+ ".bin",
6004
+ ".dat",
6005
+ ".db",
6006
+ ".sqlite",
6007
+ ".sqlite3"
6008
+ ]);
6009
+ function isBinaryExtension(filePath) {
6010
+ const ext = import_path.default.extname(filePath).toLowerCase();
6011
+ return BINARY_EXTENSIONS.has(ext);
6012
+ }
6013
+ function isBinaryBuffer(buffer) {
6014
+ return buffer.subarray(0, 8e3).includes(0);
6015
+ }
6016
+ function isBinaryFile(filePath, buffer) {
6017
+ return isBinaryExtension(filePath) || isBinaryBuffer(buffer);
6018
+ }
6019
+ var MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
6020
+ var MAX_FILE_SIZE_MB = 10;
6021
+ async function readSkillDirectory(dirPath) {
6022
+ const files = [];
6023
+ async function readDir(currentPath, basePath) {
6024
+ const entries = await import_promises.default.readdir(currentPath, { withFileTypes: true });
6025
+ for (const entry of entries) {
6026
+ const fullPath = import_path.default.join(currentPath, entry.name);
6027
+ const relativePath = import_path.default.relative(basePath, fullPath);
6028
+ if (entry.isDirectory()) {
6029
+ await readDir(fullPath, basePath);
6030
+ } else if (entry.isFile()) {
6031
+ const stat4 = await import_promises.default.stat(fullPath);
6032
+ if (stat4.size > MAX_FILE_SIZE_BYTES) {
6033
+ const fileSizeMB = (stat4.size / (1024 * 1024)).toFixed(2);
6034
+ throw new Error(
6035
+ `File "${relativePath}" is ${fileSizeMB} MB which exceeds the maximum allowed size of ${MAX_FILE_SIZE_MB} MB per file.`
6036
+ );
6037
+ }
6038
+ const buffer = await import_promises.default.readFile(fullPath);
6039
+ const isBinary = isBinaryFile(fullPath, buffer);
6040
+ const normalizedPath = normalizePath(relativePath);
6041
+ let content;
6042
+ if (isBinary) {
6043
+ content = buffer.toString("base64");
6044
+ } else {
6045
+ content = normalizeLineEndings(buffer.toString("utf-8"));
6046
+ }
6047
+ files.push({
6048
+ path: fullPath,
6049
+ relativePath: normalizedPath,
6050
+ content,
6051
+ size: Buffer.byteLength(content, isBinary ? "base64" : "utf-8"),
6052
+ permissions: "rw-r--r--",
6053
+ // Simple default
6054
+ isBase64: isBinary
6055
+ });
6056
+ }
6057
+ }
6058
+ }
6059
+ await readDir(dirPath, dirPath);
6060
+ return files;
6061
+ }
6062
+
5906
6063
  // apps/cli/src/domain/errors/CommunityEditionError.ts
5907
6064
  var CommunityEditionError = class extends Error {
5908
6065
  constructor(feature) {
@@ -5979,7 +6136,7 @@ function decodeApiKey(apiKey) {
5979
6136
  var PackmindGateway = class {
5980
6137
  constructor(apiKey) {
5981
6138
  this.apiKey = apiKey;
5982
- this.getPullData = async (command8) => {
6139
+ this.getPullData = async (command9) => {
5983
6140
  const decodedApiKey = decodeApiKey(this.apiKey);
5984
6141
  if (!decodedApiKey.isValid) {
5985
6142
  if (decodedApiKey.error === "NOT_LOGGED_IN") {
@@ -5994,13 +6151,13 @@ var PackmindGateway = class {
5994
6151
  }
5995
6152
  const organizationId = jwtPayload.organization.id;
5996
6153
  const queryParams = new URLSearchParams();
5997
- if (command8.packagesSlugs && command8.packagesSlugs.length > 0) {
5998
- command8.packagesSlugs.forEach((slug) => {
6154
+ if (command9.packagesSlugs && command9.packagesSlugs.length > 0) {
6155
+ command9.packagesSlugs.forEach((slug) => {
5999
6156
  queryParams.append("packageSlug", slug);
6000
6157
  });
6001
6158
  }
6002
- if (command8.previousPackagesSlugs && command8.previousPackagesSlugs.length > 0) {
6003
- command8.previousPackagesSlugs.forEach((slug) => {
6159
+ if (command9.previousPackagesSlugs && command9.previousPackagesSlugs.length > 0) {
6160
+ command9.previousPackagesSlugs.forEach((slug) => {
6004
6161
  queryParams.append("previousPackageSlug", slug);
6005
6162
  });
6006
6163
  }
@@ -6540,6 +6697,104 @@ var PackmindGateway = class {
6540
6697
  );
6541
6698
  }
6542
6699
  };
6700
+ this.uploadSkill = async (command9) => {
6701
+ const decodedApiKey = decodeApiKey(this.apiKey);
6702
+ if (!decodedApiKey.isValid) {
6703
+ if (decodedApiKey.error === "NOT_LOGGED_IN") {
6704
+ throw new NotLoggedInError();
6705
+ }
6706
+ throw new Error(`Invalid API key: ${decodedApiKey.error}`);
6707
+ }
6708
+ const { host, jwt } = decodedApiKey.payload;
6709
+ const jwtPayload = decodeJwt(jwt);
6710
+ if (!jwtPayload?.organization?.id) {
6711
+ throw new Error("Invalid API key: missing organizationId in JWT");
6712
+ }
6713
+ const organizationId = jwtPayload.organization.id;
6714
+ const spacesUrl = `${host}/api/v0/organizations/${organizationId}/spaces/global`;
6715
+ const spaceResponse = await fetch(spacesUrl, {
6716
+ method: "GET",
6717
+ headers: {
6718
+ Authorization: `Bearer ${this.apiKey}`
6719
+ }
6720
+ });
6721
+ if (!spaceResponse.ok) {
6722
+ throw new Error(
6723
+ `Failed to resolve global space: ${spaceResponse.status} ${spaceResponse.statusText}`
6724
+ );
6725
+ }
6726
+ const space = await spaceResponse.json();
6727
+ const spaceId = space.id;
6728
+ const files = await readSkillDirectory(command9.skillPath);
6729
+ if (!files.find((f) => f.relativePath === "SKILL.md")) {
6730
+ throw new Error("SKILL.md not found in skill directory");
6731
+ }
6732
+ const MAX_FILES = 100;
6733
+ if (files.length > MAX_FILES) {
6734
+ throw new Error(
6735
+ `Skill contains ${files.length} files, but maximum allowed is ${MAX_FILES}`
6736
+ );
6737
+ }
6738
+ const totalSize = files.reduce((sum, f) => sum + f.size, 0);
6739
+ if (totalSize > 10 * 1024 * 1024) {
6740
+ throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
6741
+ }
6742
+ const payload = {
6743
+ files: files.map((f) => ({
6744
+ path: f.relativePath,
6745
+ content: f.content,
6746
+ permissions: f.permissions || "rw-r--r--",
6747
+ isBase64: f.isBase64
6748
+ }))
6749
+ };
6750
+ const url = `${host}/api/v0/organizations/${organizationId}/spaces/${spaceId}/skills/upload`;
6751
+ try {
6752
+ const response = await fetch(url, {
6753
+ method: "POST",
6754
+ headers: {
6755
+ "Content-Type": "application/json",
6756
+ Authorization: `Bearer ${this.apiKey}`
6757
+ },
6758
+ body: JSON.stringify(payload)
6759
+ });
6760
+ if (!response.ok) {
6761
+ let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
6762
+ try {
6763
+ const errorBody = await response.json();
6764
+ if (errorBody?.message) {
6765
+ errorMsg = errorBody.message;
6766
+ }
6767
+ } catch {
6768
+ }
6769
+ if (response.status === 409) {
6770
+ throw new Error(`Skill already exists: ${errorMsg}`);
6771
+ }
6772
+ throw new Error(errorMsg);
6773
+ }
6774
+ const isNewSkill = response.status === 201;
6775
+ const result = await response.json();
6776
+ return {
6777
+ skillId: result.skill.id,
6778
+ name: result.skill.name,
6779
+ version: result.skill.version,
6780
+ isNewSkill,
6781
+ versionCreated: result.versionCreated,
6782
+ fileCount: files.length,
6783
+ totalSize
6784
+ };
6785
+ } catch (error) {
6786
+ const err = error;
6787
+ const code = err?.code || err?.cause?.code;
6788
+ if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
6789
+ throw new Error(
6790
+ `Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
6791
+ );
6792
+ }
6793
+ throw new Error(
6794
+ `Failed to upload skill: Error: ${err?.message || JSON.stringify(error)}`
6795
+ );
6796
+ }
6797
+ };
6543
6798
  }
6544
6799
  };
6545
6800
 
@@ -6625,7 +6880,7 @@ var ParserInitializationError = class extends Error {
6625
6880
  };
6626
6881
 
6627
6882
  // packages/linter-ast/src/core/BaseParser.ts
6628
- var import_path = require("path");
6883
+ var import_path2 = require("path");
6629
6884
  var import_fs = require("fs");
6630
6885
  var BaseParser = class _BaseParser {
6631
6886
  constructor() {
@@ -6649,20 +6904,20 @@ var BaseParser = class _BaseParser {
6649
6904
  if (_BaseParser.externalWasmDirectory) {
6650
6905
  paths.push(_BaseParser.externalWasmDirectory);
6651
6906
  }
6652
- const execDir = process.argv[0] ? (0, import_path.dirname)(process.argv[0]) : process.cwd();
6653
- const scriptDir = require.main?.filename ? (0, import_path.dirname)(require.main.filename) : process.cwd();
6907
+ const execDir = process.argv[0] ? (0, import_path2.dirname)(process.argv[0]) : process.cwd();
6908
+ const scriptDir = require.main?.filename ? (0, import_path2.dirname)(require.main.filename) : process.cwd();
6654
6909
  paths.push(
6655
6910
  // Next to the main script (for npm packages like @packmind/scan)
6656
6911
  scriptDir,
6657
- (0, import_path.join)(scriptDir, "tree-sitter"),
6912
+ (0, import_path2.join)(scriptDir, "tree-sitter"),
6658
6913
  // Next to the Bun executable in tree-sitter/ subdirectory
6659
- (0, import_path.join)(execDir, "tree-sitter"),
6914
+ (0, import_path2.join)(execDir, "tree-sitter"),
6660
6915
  // Fallback paths
6661
- (0, import_path.join)(process.cwd(), "tree-sitter"),
6662
- (0, import_path.join)(process.cwd(), "dist/apps/cli-executables/tree-sitter"),
6663
- (0, import_path.resolve)(__dirname, "tree-sitter"),
6664
- (0, import_path.resolve)(__dirname, "../../res"),
6665
- (0, import_path.resolve)(__dirname, "../../../packages/linter-ast/res")
6916
+ (0, import_path2.join)(process.cwd(), "tree-sitter"),
6917
+ (0, import_path2.join)(process.cwd(), "dist/apps/cli-executables/tree-sitter"),
6918
+ (0, import_path2.resolve)(__dirname, "tree-sitter"),
6919
+ (0, import_path2.resolve)(__dirname, "../../res"),
6920
+ (0, import_path2.resolve)(__dirname, "../../../packages/linter-ast/res")
6666
6921
  );
6667
6922
  return paths;
6668
6923
  }
@@ -6673,12 +6928,12 @@ var BaseParser = class _BaseParser {
6673
6928
  const wasmDirs = _BaseParser.getTreeSitterWasmPaths();
6674
6929
  return (fileName) => {
6675
6930
  for (const dir of wasmDirs) {
6676
- const fullPath = (0, import_path.join)(dir, fileName);
6931
+ const fullPath = (0, import_path2.join)(dir, fileName);
6677
6932
  if ((0, import_fs.existsSync)(fullPath)) {
6678
6933
  return fullPath;
6679
6934
  }
6680
6935
  }
6681
- return (0, import_path.join)(process.cwd(), fileName);
6936
+ return (0, import_path2.join)(process.cwd(), fileName);
6682
6937
  };
6683
6938
  }
6684
6939
  /**
@@ -6687,15 +6942,15 @@ var BaseParser = class _BaseParser {
6687
6942
  static getLanguageWasmPaths(languageName) {
6688
6943
  const wasmDirs = _BaseParser.getTreeSitterWasmPaths();
6689
6944
  const wasmFileName = `tree-sitter-${languageName}.wasm`;
6690
- return wasmDirs.map((dir) => (0, import_path.join)(dir, wasmFileName)).concat([
6945
+ return wasmDirs.map((dir) => (0, import_path2.join)(dir, wasmFileName)).concat([
6691
6946
  // Additional fallback paths
6692
- (0, import_path.resolve)(__dirname, `tree-sitter/${wasmFileName}`),
6693
- (0, import_path.resolve)(__dirname, wasmFileName),
6694
- (0, import_path.resolve)(__dirname, `res/${wasmFileName}`),
6695
- (0, import_path.resolve)(__dirname, `../../res/${wasmFileName}`),
6696
- (0, import_path.resolve)(__dirname, `../res/${wasmFileName}`),
6697
- (0, import_path.resolve)(__dirname, `../../../packages/linter-ast/res/${wasmFileName}`),
6698
- (0, import_path.join)(process.cwd(), `packages/linter-ast/res/${wasmFileName}`)
6947
+ (0, import_path2.resolve)(__dirname, `tree-sitter/${wasmFileName}`),
6948
+ (0, import_path2.resolve)(__dirname, wasmFileName),
6949
+ (0, import_path2.resolve)(__dirname, `res/${wasmFileName}`),
6950
+ (0, import_path2.resolve)(__dirname, `../../res/${wasmFileName}`),
6951
+ (0, import_path2.resolve)(__dirname, `../res/${wasmFileName}`),
6952
+ (0, import_path2.resolve)(__dirname, `../../../packages/linter-ast/res/${wasmFileName}`),
6953
+ (0, import_path2.join)(process.cwd(), `packages/linter-ast/res/${wasmFileName}`)
6699
6954
  ]);
6700
6955
  }
6701
6956
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -8283,8 +8538,8 @@ var ExecuteLinterProgramsUseCase = class {
8283
8538
  this.linterAstAdapter = linterAstAdapter;
8284
8539
  this.logger = logger2;
8285
8540
  }
8286
- async execute(command8) {
8287
- const { filePath, fileContent, language, programs } = command8;
8541
+ async execute(command9) {
8542
+ const { filePath, fileContent, language, programs } = command9;
8288
8543
  if (programs.length === 0) {
8289
8544
  return {
8290
8545
  file: filePath,
@@ -8437,10 +8692,10 @@ var ExecuteLinterProgramsUseCase = class {
8437
8692
  return typeof line === "number" && Number.isInteger(line) && line >= 0;
8438
8693
  }
8439
8694
  extractRuleName(ruleContent) {
8440
- if (!ruleContent.includes("/")) {
8441
- return ruleContent;
8695
+ if (ruleContent.endsWith(".js") && ruleContent.includes("/")) {
8696
+ return ruleContent.split("/").pop()?.replace(".js", "") ?? ruleContent;
8442
8697
  }
8443
- return ruleContent.split("/").pop()?.replace(".js", "") ?? ruleContent;
8698
+ return ruleContent;
8444
8699
  }
8445
8700
  filterProgramsByLanguage(programs, fileLanguage) {
8446
8701
  const filtered = programs.filter((p) => p.language === fileLanguage);
@@ -9373,25 +9628,26 @@ ${sectionBlock}
9373
9628
  }
9374
9629
 
9375
9630
  // apps/cli/src/application/useCases/InstallPackagesUseCase.ts
9376
- var fs4 = __toESM(require("fs/promises"));
9377
- var path5 = __toESM(require("path"));
9631
+ var fs5 = __toESM(require("fs/promises"));
9632
+ var path6 = __toESM(require("path"));
9378
9633
  var InstallPackagesUseCase = class {
9379
9634
  constructor(packmindGateway) {
9380
9635
  this.packmindGateway = packmindGateway;
9381
9636
  }
9382
- async execute(command8) {
9383
- const baseDirectory = command8.baseDirectory || process.cwd();
9637
+ async execute(command9) {
9638
+ const baseDirectory = command9.baseDirectory || process.cwd();
9384
9639
  const result = {
9385
9640
  filesCreated: 0,
9386
9641
  filesUpdated: 0,
9387
9642
  filesDeleted: 0,
9388
9643
  errors: [],
9389
9644
  recipesCount: 0,
9390
- standardsCount: 0
9645
+ standardsCount: 0,
9646
+ skillsCount: 0
9391
9647
  };
9392
9648
  const response = await this.packmindGateway.getPullData({
9393
- packagesSlugs: command8.packagesSlugs,
9394
- previousPackagesSlugs: command8.previousPackagesSlugs
9649
+ packagesSlugs: command9.packagesSlugs,
9650
+ previousPackagesSlugs: command9.previousPackagesSlugs
9395
9651
  });
9396
9652
  const uniqueFilesMap = /* @__PURE__ */ new Map();
9397
9653
  for (const file of response.fileUpdates.createOrUpdate) {
@@ -9403,6 +9659,8 @@ var InstallPackagesUseCase = class {
9403
9659
  result.recipesCount++;
9404
9660
  } else if (file.path.includes(".packmind/standards/") && file.path.endsWith(".md")) {
9405
9661
  result.standardsCount++;
9662
+ } else if (file.path.includes(".packmind/skills/") && file.path.endsWith(".md")) {
9663
+ result.skillsCount++;
9406
9664
  }
9407
9665
  }
9408
9666
  try {
@@ -9431,16 +9689,17 @@ var InstallPackagesUseCase = class {
9431
9689
  return result;
9432
9690
  }
9433
9691
  async createOrUpdateFile(baseDirectory, file, result) {
9434
- const fullPath = path5.join(baseDirectory, file.path);
9435
- const directory = path5.dirname(fullPath);
9436
- await fs4.mkdir(directory, { recursive: true });
9692
+ const fullPath = path6.join(baseDirectory, file.path);
9693
+ const directory = path6.dirname(fullPath);
9694
+ await fs5.mkdir(directory, { recursive: true });
9437
9695
  const fileExists = await this.fileExists(fullPath);
9438
9696
  if (file.content !== void 0) {
9439
9697
  await this.handleFullContentUpdate(
9440
9698
  fullPath,
9441
9699
  file.content,
9442
9700
  fileExists,
9443
- result
9701
+ result,
9702
+ file.isBase64
9444
9703
  );
9445
9704
  } else if (file.sections !== void 0) {
9446
9705
  await this.handleSectionsUpdate(
@@ -9451,9 +9710,19 @@ var InstallPackagesUseCase = class {
9451
9710
  );
9452
9711
  }
9453
9712
  }
9454
- async handleFullContentUpdate(fullPath, content, fileExists, result) {
9713
+ async handleFullContentUpdate(fullPath, content, fileExists, result, isBase64) {
9714
+ if (isBase64) {
9715
+ const buffer = Buffer.from(content, "base64");
9716
+ await fs5.writeFile(fullPath, buffer);
9717
+ if (fileExists) {
9718
+ result.filesUpdated++;
9719
+ } else {
9720
+ result.filesCreated++;
9721
+ }
9722
+ return;
9723
+ }
9455
9724
  if (fileExists) {
9456
- const existingContent = await fs4.readFile(fullPath, "utf-8");
9725
+ const existingContent = await fs5.readFile(fullPath, "utf-8");
9457
9726
  const commentMarker = this.extractCommentMarker(content);
9458
9727
  let finalContent;
9459
9728
  if (!commentMarker) {
@@ -9466,18 +9735,18 @@ var InstallPackagesUseCase = class {
9466
9735
  );
9467
9736
  }
9468
9737
  if (existingContent !== finalContent) {
9469
- await fs4.writeFile(fullPath, finalContent, "utf-8");
9738
+ await fs5.writeFile(fullPath, finalContent, "utf-8");
9470
9739
  result.filesUpdated++;
9471
9740
  }
9472
9741
  } else {
9473
- await fs4.writeFile(fullPath, content, "utf-8");
9742
+ await fs5.writeFile(fullPath, content, "utf-8");
9474
9743
  result.filesCreated++;
9475
9744
  }
9476
9745
  }
9477
9746
  async handleSectionsUpdate(fullPath, sections, fileExists, result) {
9478
9747
  let currentContent = "";
9479
9748
  if (fileExists) {
9480
- currentContent = await fs4.readFile(fullPath, "utf-8");
9749
+ currentContent = await fs5.readFile(fullPath, "utf-8");
9481
9750
  }
9482
9751
  const mergedContent = mergeSectionsIntoFileContent(
9483
9752
  currentContent,
@@ -9485,10 +9754,10 @@ var InstallPackagesUseCase = class {
9485
9754
  );
9486
9755
  if (currentContent !== mergedContent) {
9487
9756
  if (this.isEffectivelyEmpty(mergedContent) && fileExists) {
9488
- await fs4.unlink(fullPath);
9757
+ await fs5.unlink(fullPath);
9489
9758
  result.filesDeleted++;
9490
9759
  } else {
9491
- await fs4.writeFile(fullPath, mergedContent, "utf-8");
9760
+ await fs5.writeFile(fullPath, mergedContent, "utf-8");
9492
9761
  if (fileExists) {
9493
9762
  result.filesUpdated++;
9494
9763
  } else {
@@ -9498,19 +9767,19 @@ var InstallPackagesUseCase = class {
9498
9767
  }
9499
9768
  }
9500
9769
  async deleteFile(baseDirectory, filePath, result) {
9501
- const fullPath = path5.join(baseDirectory, filePath);
9502
- const stat4 = await fs4.stat(fullPath).catch(() => null);
9770
+ const fullPath = path6.join(baseDirectory, filePath);
9771
+ const stat4 = await fs5.stat(fullPath).catch(() => null);
9503
9772
  if (stat4?.isDirectory()) {
9504
- await fs4.rm(fullPath, { recursive: true, force: true });
9773
+ await fs5.rm(fullPath, { recursive: true, force: true });
9505
9774
  result.filesDeleted++;
9506
9775
  } else if (stat4?.isFile()) {
9507
- await fs4.unlink(fullPath);
9776
+ await fs5.unlink(fullPath);
9508
9777
  result.filesDeleted++;
9509
9778
  }
9510
9779
  }
9511
9780
  async fileExists(filePath) {
9512
9781
  try {
9513
- await fs4.access(filePath);
9782
+ await fs5.access(filePath);
9514
9783
  return true;
9515
9784
  } catch {
9516
9785
  return false;
@@ -9589,8 +9858,8 @@ var GetPackageSummaryUseCase = class {
9589
9858
  constructor(gateway) {
9590
9859
  this.gateway = gateway;
9591
9860
  }
9592
- async execute(command8) {
9593
- return this.gateway.getPackageSummary(command8);
9861
+ async execute(command9) {
9862
+ return this.gateway.getPackageSummary(command9);
9594
9863
  }
9595
9864
  };
9596
9865
 
@@ -9650,13 +9919,13 @@ var EnvCredentialsProvider = class {
9650
9919
  };
9651
9920
 
9652
9921
  // apps/cli/src/infra/utils/credentials/FileCredentialsProvider.ts
9653
- var fs5 = __toESM(require("fs"));
9654
- var path6 = __toESM(require("path"));
9922
+ var fs6 = __toESM(require("fs"));
9923
+ var path7 = __toESM(require("path"));
9655
9924
  var os2 = __toESM(require("os"));
9656
9925
  var CREDENTIALS_DIR = ".packmind";
9657
9926
  var CREDENTIALS_FILE = "credentials.json";
9658
9927
  function getCredentialsPath() {
9659
- return path6.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
9928
+ return path7.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
9660
9929
  }
9661
9930
  var FileCredentialsProvider = class {
9662
9931
  getSourceName() {
@@ -9664,11 +9933,11 @@ var FileCredentialsProvider = class {
9664
9933
  }
9665
9934
  hasCredentials() {
9666
9935
  const credentialsPath = getCredentialsPath();
9667
- if (!fs5.existsSync(credentialsPath)) {
9936
+ if (!fs6.existsSync(credentialsPath)) {
9668
9937
  return false;
9669
9938
  }
9670
9939
  try {
9671
- const content = fs5.readFileSync(credentialsPath, "utf-8");
9940
+ const content = fs6.readFileSync(credentialsPath, "utf-8");
9672
9941
  const credentials = JSON.parse(content);
9673
9942
  return !!credentials.apiKey;
9674
9943
  } catch {
@@ -9677,11 +9946,11 @@ var FileCredentialsProvider = class {
9677
9946
  }
9678
9947
  loadCredentials() {
9679
9948
  const credentialsPath = getCredentialsPath();
9680
- if (!fs5.existsSync(credentialsPath)) {
9949
+ if (!fs6.existsSync(credentialsPath)) {
9681
9950
  return null;
9682
9951
  }
9683
9952
  try {
9684
- const content = fs5.readFileSync(credentialsPath, "utf-8");
9953
+ const content = fs6.readFileSync(credentialsPath, "utf-8");
9685
9954
  const credentials = JSON.parse(content);
9686
9955
  if (!credentials.apiKey) {
9687
9956
  return null;
@@ -9704,13 +9973,13 @@ var FileCredentialsProvider = class {
9704
9973
  }
9705
9974
  };
9706
9975
  function saveCredentials(apiKey) {
9707
- const credentialsDir = path6.join(os2.homedir(), CREDENTIALS_DIR);
9708
- if (!fs5.existsSync(credentialsDir)) {
9709
- fs5.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
9976
+ const credentialsDir = path7.join(os2.homedir(), CREDENTIALS_DIR);
9977
+ if (!fs6.existsSync(credentialsDir)) {
9978
+ fs6.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
9710
9979
  }
9711
9980
  const credentialsPath = getCredentialsPath();
9712
9981
  const credentials = { apiKey };
9713
- fs5.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
9982
+ fs6.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
9714
9983
  mode: 384
9715
9984
  });
9716
9985
  }
@@ -9868,8 +10137,8 @@ var LoginUseCase = class {
9868
10137
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
9869
10138
  };
9870
10139
  }
9871
- async execute(command8) {
9872
- const { host, code: providedCode } = command8;
10140
+ async execute(command9) {
10141
+ const { host, code: providedCode } = command9;
9873
10142
  let code;
9874
10143
  if (providedCode) {
9875
10144
  code = providedCode;
@@ -9900,14 +10169,14 @@ var LoginUseCase = class {
9900
10169
  };
9901
10170
 
9902
10171
  // apps/cli/src/application/useCases/LogoutUseCase.ts
9903
- var fs6 = __toESM(require("fs"));
10172
+ var fs7 = __toESM(require("fs"));
9904
10173
  var ENV_VAR_NAME2 = "PACKMIND_API_KEY_V3";
9905
10174
  var LogoutUseCase = class {
9906
10175
  constructor(deps) {
9907
10176
  this.deps = {
9908
10177
  getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
9909
- fileExists: deps?.fileExists ?? ((path11) => fs6.existsSync(path11)),
9910
- deleteFile: deps?.deleteFile ?? ((path11) => fs6.unlinkSync(path11)),
10178
+ fileExists: deps?.fileExists ?? ((path12) => fs7.existsSync(path12)),
10179
+ deleteFile: deps?.deleteFile ?? ((path12) => fs7.unlinkSync(path12)),
9911
10180
  hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
9912
10181
  };
9913
10182
  }
@@ -9967,8 +10236,8 @@ var SetupMcpUseCase = class {
9967
10236
  constructor(deps) {
9968
10237
  this.deps = deps;
9969
10238
  }
9970
- async execute(command8) {
9971
- const { agentTypes } = command8;
10239
+ async execute(command9) {
10240
+ const { agentTypes } = command9;
9972
10241
  const [tokenResult, urlResult] = await Promise.all([
9973
10242
  this.deps.gateway.getMcpToken({}),
9974
10243
  this.deps.gateway.getMcpUrl({})
@@ -10003,8 +10272,8 @@ var SetupMcpUseCase = class {
10003
10272
  };
10004
10273
 
10005
10274
  // apps/cli/src/application/services/McpConfigService.ts
10006
- var fs7 = __toESM(require("fs"));
10007
- var path7 = __toESM(require("path"));
10275
+ var fs8 = __toESM(require("fs"));
10276
+ var path8 = __toESM(require("path"));
10008
10277
  var os3 = __toESM(require("os"));
10009
10278
  var import_child_process2 = require("child_process");
10010
10279
  var McpConfigService = class {
@@ -10039,9 +10308,9 @@ var McpConfigService = class {
10039
10308
  return JSON.stringify(mcpConfig, null, 2);
10040
10309
  }
10041
10310
  installClaudeMcp(config) {
10042
- const command8 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10311
+ const command9 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10043
10312
  try {
10044
- (0, import_child_process2.execSync)(command8, { stdio: "pipe" });
10313
+ (0, import_child_process2.execSync)(command9, { stdio: "pipe" });
10045
10314
  return { success: true };
10046
10315
  } catch (error) {
10047
10316
  const execError = error;
@@ -10051,11 +10320,11 @@ var McpConfigService = class {
10051
10320
  }
10052
10321
  installCursorMcp(config) {
10053
10322
  try {
10054
- const cursorConfigPath = path7.join(os3.homedir(), ".cursor", "mcp.json");
10323
+ const cursorConfigPath = path8.join(os3.homedir(), ".cursor", "mcp.json");
10055
10324
  const cursorConfig = this.buildCursorConfig(config);
10056
10325
  const existingConfig = this.readExistingJsonConfig(cursorConfigPath);
10057
10326
  const mergedConfig = this.mergeConfig(existingConfig, cursorConfig);
10058
- fs7.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
10327
+ fs8.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
10059
10328
  return { success: true };
10060
10329
  } catch (error) {
10061
10330
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10064,15 +10333,15 @@ var McpConfigService = class {
10064
10333
  }
10065
10334
  installVSCodeMcp(config) {
10066
10335
  try {
10067
- const vscodeDir = path7.join(this.projectDir, ".vscode");
10068
- if (!fs7.existsSync(vscodeDir)) {
10069
- fs7.mkdirSync(vscodeDir, { recursive: true });
10336
+ const vscodeDir = path8.join(this.projectDir, ".vscode");
10337
+ if (!fs8.existsSync(vscodeDir)) {
10338
+ fs8.mkdirSync(vscodeDir, { recursive: true });
10070
10339
  }
10071
- const vscodeConfigPath = path7.join(vscodeDir, "mcp.json");
10340
+ const vscodeConfigPath = path8.join(vscodeDir, "mcp.json");
10072
10341
  const vscodeConfig = this.buildVSCodeConfig(config);
10073
10342
  const existingConfig = this.readExistingJsonConfig(vscodeConfigPath);
10074
10343
  const mergedConfig = this.mergeVSCodeConfig(existingConfig, vscodeConfig);
10075
- fs7.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
10344
+ fs8.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
10076
10345
  return { success: true };
10077
10346
  } catch (error) {
10078
10347
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10081,14 +10350,14 @@ var McpConfigService = class {
10081
10350
  }
10082
10351
  installContinueMcp(config) {
10083
10352
  try {
10084
- const continueDir = path7.join(this.projectDir, ".continue");
10085
- const mcpServersDir = path7.join(continueDir, "mcpServers");
10086
- if (!fs7.existsSync(mcpServersDir)) {
10087
- fs7.mkdirSync(mcpServersDir, { recursive: true });
10353
+ const continueDir = path8.join(this.projectDir, ".continue");
10354
+ const mcpServersDir = path8.join(continueDir, "mcpServers");
10355
+ if (!fs8.existsSync(mcpServersDir)) {
10356
+ fs8.mkdirSync(mcpServersDir, { recursive: true });
10088
10357
  }
10089
- const continueConfigPath = path7.join(mcpServersDir, "packmind.yaml");
10358
+ const continueConfigPath = path8.join(mcpServersDir, "packmind.yaml");
10090
10359
  const continueConfig = this.buildContinueYamlConfig(config);
10091
- fs7.writeFileSync(continueConfigPath, continueConfig);
10360
+ fs8.writeFileSync(continueConfigPath, continueConfig);
10092
10361
  return { success: true };
10093
10362
  } catch (error) {
10094
10363
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -10136,8 +10405,8 @@ mcpServers:
10136
10405
  }
10137
10406
  readExistingJsonConfig(filePath) {
10138
10407
  try {
10139
- if (fs7.existsSync(filePath)) {
10140
- const content = fs7.readFileSync(filePath, "utf-8");
10408
+ if (fs8.existsSync(filePath)) {
10409
+ const content = fs8.readFileSync(filePath, "utf-8");
10141
10410
  return JSON.parse(content);
10142
10411
  }
10143
10412
  } catch {
@@ -10170,8 +10439,8 @@ mcpServers:
10170
10439
  };
10171
10440
 
10172
10441
  // apps/cli/src/infra/repositories/ConfigFileRepository.ts
10173
- var fs8 = __toESM(require("fs/promises"));
10174
- var path8 = __toESM(require("path"));
10442
+ var fs9 = __toESM(require("fs/promises"));
10443
+ var path9 = __toESM(require("path"));
10175
10444
 
10176
10445
  // apps/cli/src/infra/utils/consoleLogger.ts
10177
10446
  init_source();
@@ -10219,23 +10488,23 @@ var ConfigFileRepository = class {
10219
10488
  ];
10220
10489
  }
10221
10490
  async writeConfig(baseDirectory, config) {
10222
- const configPath = path8.join(baseDirectory, this.CONFIG_FILENAME);
10491
+ const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10223
10492
  const configContent = JSON.stringify(config, null, 2) + "\n";
10224
- await fs8.writeFile(configPath, configContent, "utf-8");
10493
+ await fs9.writeFile(configPath, configContent, "utf-8");
10225
10494
  }
10226
10495
  async configExists(baseDirectory) {
10227
- const configPath = path8.join(baseDirectory, this.CONFIG_FILENAME);
10496
+ const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10228
10497
  try {
10229
- await fs8.access(configPath);
10498
+ await fs9.access(configPath);
10230
10499
  return true;
10231
10500
  } catch {
10232
10501
  return false;
10233
10502
  }
10234
10503
  }
10235
10504
  async readConfig(baseDirectory) {
10236
- const configPath = path8.join(baseDirectory, this.CONFIG_FILENAME);
10505
+ const configPath = path9.join(baseDirectory, this.CONFIG_FILENAME);
10237
10506
  try {
10238
- const configContent = await fs8.readFile(configPath, "utf-8");
10507
+ const configContent = await fs9.readFile(configPath, "utf-8");
10239
10508
  const config = JSON.parse(configContent);
10240
10509
  if (!config.packages || typeof config.packages !== "object") {
10241
10510
  throw new Error(
@@ -10262,12 +10531,12 @@ var ConfigFileRepository = class {
10262
10531
  * @returns Array of directory paths that contain a packmind.json file
10263
10532
  */
10264
10533
  async findDescendantConfigs(directory) {
10265
- const normalizedDir = path8.resolve(directory);
10534
+ const normalizedDir = path9.resolve(directory);
10266
10535
  const results = [];
10267
10536
  const searchRecursively = async (currentDir) => {
10268
10537
  let entries;
10269
10538
  try {
10270
- entries = await fs8.readdir(currentDir, { withFileTypes: true });
10539
+ entries = await fs9.readdir(currentDir, { withFileTypes: true });
10271
10540
  } catch {
10272
10541
  return;
10273
10542
  }
@@ -10278,7 +10547,7 @@ var ConfigFileRepository = class {
10278
10547
  if (this.EXCLUDED_DIRECTORIES.includes(entry.name)) {
10279
10548
  continue;
10280
10549
  }
10281
- const entryPath = path8.join(currentDir, entry.name);
10550
+ const entryPath = path9.join(currentDir, entry.name);
10282
10551
  const config = await this.readConfig(entryPath);
10283
10552
  if (config) {
10284
10553
  results.push(entryPath);
@@ -10300,19 +10569,19 @@ var ConfigFileRepository = class {
10300
10569
  async readHierarchicalConfig(startDirectory, stopDirectory) {
10301
10570
  const configs = [];
10302
10571
  const configPaths = [];
10303
- const normalizedStart = path8.resolve(startDirectory);
10304
- const normalizedStop = stopDirectory ? path8.resolve(stopDirectory) : null;
10572
+ const normalizedStart = path9.resolve(startDirectory);
10573
+ const normalizedStop = stopDirectory ? path9.resolve(stopDirectory) : null;
10305
10574
  let currentDir = normalizedStart;
10306
10575
  while (true) {
10307
10576
  const config = await this.readConfig(currentDir);
10308
10577
  if (config) {
10309
10578
  configs.push(config);
10310
- configPaths.push(path8.join(currentDir, this.CONFIG_FILENAME));
10579
+ configPaths.push(path9.join(currentDir, this.CONFIG_FILENAME));
10311
10580
  }
10312
10581
  if (normalizedStop !== null && currentDir === normalizedStop) {
10313
10582
  break;
10314
10583
  }
10315
- const parentDir = path8.dirname(currentDir);
10584
+ const parentDir = path9.dirname(currentDir);
10316
10585
  if (parentDir === currentDir) {
10317
10586
  break;
10318
10587
  }
@@ -10341,8 +10610,8 @@ var ConfigFileRepository = class {
10341
10610
  * @returns All configs found with their target paths
10342
10611
  */
10343
10612
  async findAllConfigsInTree(startDirectory, stopDirectory) {
10344
- const normalizedStart = path8.resolve(startDirectory);
10345
- const normalizedStop = stopDirectory ? path8.resolve(stopDirectory) : null;
10613
+ const normalizedStart = path9.resolve(startDirectory);
10614
+ const normalizedStop = stopDirectory ? path9.resolve(stopDirectory) : null;
10346
10615
  const basePath = normalizedStop ?? normalizedStart;
10347
10616
  const configsMap = /* @__PURE__ */ new Map();
10348
10617
  let currentDir = normalizedStart;
@@ -10359,7 +10628,7 @@ var ConfigFileRepository = class {
10359
10628
  if (normalizedStop !== null && currentDir === normalizedStop) {
10360
10629
  break;
10361
10630
  }
10362
- const parentDir = path8.dirname(currentDir);
10631
+ const parentDir = path9.dirname(currentDir);
10363
10632
  if (parentDir === currentDir) {
10364
10633
  break;
10365
10634
  }
@@ -10479,29 +10748,29 @@ var PackmindCliHexa = class {
10479
10748
  this.logger.info("Destroying PackmindCliHexa");
10480
10749
  this.logger.info("PackmindCliHexa destroyed");
10481
10750
  }
10482
- async getGitRemoteUrl(command8) {
10483
- return this.hexa.useCases.getGitRemoteUrl.execute(command8);
10751
+ async getGitRemoteUrl(command9) {
10752
+ return this.hexa.useCases.getGitRemoteUrl.execute(command9);
10484
10753
  }
10485
- async executeSingleFileAst(command8) {
10486
- return this.hexa.useCases.executeSingleFileAst.execute(command8);
10754
+ async executeSingleFileAst(command9) {
10755
+ return this.hexa.useCases.executeSingleFileAst.execute(command9);
10487
10756
  }
10488
- async listFilesInDirectory(command8) {
10489
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command8);
10757
+ async listFilesInDirectory(command9) {
10758
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command9);
10490
10759
  }
10491
- async lintFilesInDirectory(command8) {
10492
- return this.hexa.useCases.lintFilesInDirectory.execute(command8);
10760
+ async lintFilesInDirectory(command9) {
10761
+ return this.hexa.useCases.lintFilesInDirectory.execute(command9);
10493
10762
  }
10494
- async lintFilesLocally(command8) {
10495
- return this.hexa.useCases.lintFilesLocally.execute(command8);
10763
+ async lintFilesLocally(command9) {
10764
+ return this.hexa.useCases.lintFilesLocally.execute(command9);
10496
10765
  }
10497
- async installPackages(command8) {
10498
- return this.hexa.useCases.installPackages.execute(command8);
10766
+ async installPackages(command9) {
10767
+ return this.hexa.useCases.installPackages.execute(command9);
10499
10768
  }
10500
- async listPackages(command8) {
10501
- return this.hexa.useCases.listPackages.execute(command8);
10769
+ async listPackages(command9) {
10770
+ return this.hexa.useCases.listPackages.execute(command9);
10502
10771
  }
10503
- async getPackageBySlug(command8) {
10504
- return this.hexa.useCases.getPackageBySlug.execute(command8);
10772
+ async getPackageBySlug(command9) {
10773
+ return this.hexa.useCases.getPackageBySlug.execute(command9);
10505
10774
  }
10506
10775
  async configExists(baseDirectory) {
10507
10776
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -10560,17 +10829,17 @@ var PackmindCliHexa = class {
10560
10829
  directory
10561
10830
  );
10562
10831
  }
10563
- async login(command8) {
10564
- return this.hexa.useCases.login.execute(command8);
10832
+ async login(command9) {
10833
+ return this.hexa.useCases.login.execute(command9);
10565
10834
  }
10566
- async logout(command8) {
10567
- return this.hexa.useCases.logout.execute(command8);
10835
+ async logout(command9) {
10836
+ return this.hexa.useCases.logout.execute(command9);
10568
10837
  }
10569
- async whoami(command8) {
10570
- return this.hexa.useCases.whoami.execute(command8);
10838
+ async whoami(command9) {
10839
+ return this.hexa.useCases.whoami.execute(command9);
10571
10840
  }
10572
- async setupMcp(command8) {
10573
- return this.hexa.useCases.setupMcp.execute(command8);
10841
+ async setupMcp(command9) {
10842
+ return this.hexa.useCases.setupMcp.execute(command9);
10574
10843
  }
10575
10844
  getCurrentBranch(repoPath) {
10576
10845
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -10578,8 +10847,11 @@ var PackmindCliHexa = class {
10578
10847
  getGitRemoteUrlFromPath(repoPath) {
10579
10848
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
10580
10849
  }
10581
- async notifyDistribution(command8) {
10582
- return this.hexa.repositories.packmindGateway.notifyDistribution(command8);
10850
+ async notifyDistribution(command9) {
10851
+ return this.hexa.repositories.packmindGateway.notifyDistribution(command9);
10852
+ }
10853
+ async uploadSkill(command9) {
10854
+ return this.hexa.repositories.packmindGateway.uploadSkill(command9);
10583
10855
  }
10584
10856
  };
10585
10857
 
@@ -10636,7 +10908,7 @@ function isNotLoggedInError(error) {
10636
10908
  }
10637
10909
  async function lintHandler(args2, deps) {
10638
10910
  const {
10639
- path: path11,
10911
+ path: path12,
10640
10912
  draft,
10641
10913
  rule,
10642
10914
  language,
@@ -10656,14 +10928,14 @@ async function lintHandler(args2, deps) {
10656
10928
  throw new Error("option --rule is required to use --draft mode");
10657
10929
  }
10658
10930
  const startedAt = Date.now();
10659
- const targetPath = path11 ?? ".";
10931
+ const targetPath = path12 ?? ".";
10660
10932
  const hasArguments = !!(draft || rule || language);
10661
10933
  const absolutePath = resolvePath(targetPath);
10662
10934
  if (diff) {
10663
10935
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(absolutePath);
10664
10936
  if (!gitRoot) {
10665
10937
  throw new Error(
10666
- "The --diff option requires the project to be in a Git repository"
10938
+ "The --changed-files and --changed-lines options require the project to be in a Git repository"
10667
10939
  );
10668
10940
  }
10669
10941
  }
@@ -10703,15 +10975,15 @@ async function lintHandler(args2, deps) {
10703
10975
  }
10704
10976
  } catch (error) {
10705
10977
  if (isNotLoggedInError(error) && continueOnMissingKey) {
10706
- console.warn(
10978
+ logWarningConsole(
10707
10979
  "Warning: Not logged in to Packmind, linting is skipped. Run `packmind-cli login` to authenticate."
10708
10980
  );
10709
10981
  exit(0);
10710
10982
  return;
10711
10983
  }
10712
10984
  if (error instanceof CommunityEditionError) {
10713
- console.log(`packmind-cli ${error.message}`);
10714
- console.log("Linting skipped.");
10985
+ logInfoConsole(`packmind-cli ${error.message}`);
10986
+ logInfoConsole("Linting skipped.");
10715
10987
  exit(0);
10716
10988
  return;
10717
10989
  }
@@ -10721,7 +10993,7 @@ async function lintHandler(args2, deps) {
10721
10993
  violations
10722
10994
  );
10723
10995
  const durationSeconds = (Date.now() - startedAt) / 1e3;
10724
- console.log(`Lint completed in ${durationSeconds.toFixed(2)}s`);
10996
+ logInfoConsole(`Lint completed in ${durationSeconds.toFixed(2)}s`);
10725
10997
  if (violations.length > 0 && !continueOnError) {
10726
10998
  exit(1);
10727
10999
  } else {
@@ -10814,11 +11086,34 @@ var lintCommand = (0, import_cmd_ts.command)({
10814
11086
  }),
10815
11087
  diff: (0, import_cmd_ts.option)({
10816
11088
  long: "diff",
10817
- description: "Filter violations by git diff (files | lines)",
11089
+ description: "[Deprecated: use --changed-files or --changed-lines] Filter violations by git diff (files | lines)",
10818
11090
  type: (0, import_cmd_ts.optional)(DiffModeType)
11091
+ }),
11092
+ changedFiles: (0, import_cmd_ts.flag)({
11093
+ long: "changed-files",
11094
+ description: "Only lint files that have changed"
11095
+ }),
11096
+ changedLines: (0, import_cmd_ts.flag)({
11097
+ long: "changed-lines",
11098
+ description: "Only lint lines that have changed"
10819
11099
  })
10820
11100
  },
10821
11101
  handler: async (args2) => {
11102
+ if (args2.changedFiles && args2.changedLines) {
11103
+ throw new Error(
11104
+ "Options --changed-files and --changed-lines are mutually exclusive"
11105
+ );
11106
+ }
11107
+ if (args2.diff) {
11108
+ const replacement = args2.diff === "files" /* FILES */ ? "--changed-files" : "--changed-lines";
11109
+ logWarningConsole(`--diff is deprecated. Use ${replacement} instead.`);
11110
+ }
11111
+ let diff = args2.diff;
11112
+ if (args2.changedFiles) {
11113
+ diff = "files" /* FILES */;
11114
+ } else if (args2.changedLines) {
11115
+ diff = "lines" /* LINES */;
11116
+ }
10822
11117
  const packmindLogger = new PackmindLogger(
10823
11118
  "PackmindCLI",
10824
11119
  args2.debug ? "debug" /* DEBUG */ : "info" /* INFO */
@@ -10830,13 +11125,13 @@ var lintCommand = (0, import_cmd_ts.command)({
10830
11125
  resolvePath: (targetPath) => pathModule.isAbsolute(targetPath) ? targetPath : pathModule.resolve(process.cwd(), targetPath),
10831
11126
  exit: (code) => process.exit(code)
10832
11127
  };
10833
- await lintHandler(args2, deps);
11128
+ await lintHandler({ ...args2, diff }, deps);
10834
11129
  }
10835
11130
  });
10836
11131
 
10837
11132
  // apps/cli/src/wasm-runtime.ts
10838
11133
  var import_fs18 = require("fs");
10839
- var import_path2 = require("path");
11134
+ var import_path3 = require("path");
10840
11135
  var import_os = require("os");
10841
11136
 
10842
11137
  // apps/cli/src/embedded-wasm.ts
@@ -10870,12 +11165,12 @@ function extractWasmFiles() {
10870
11165
  if (wasmExtractedDir && (0, import_fs18.existsSync)(wasmExtractedDir)) {
10871
11166
  return wasmExtractedDir;
10872
11167
  }
10873
- const tempDir = (0, import_path2.join)((0, import_os.tmpdir)(), `packmind-wasm-${process.pid}`);
11168
+ const tempDir = (0, import_path3.join)((0, import_os.tmpdir)(), `packmind-wasm-${process.pid}`);
10874
11169
  if (!(0, import_fs18.existsSync)(tempDir)) {
10875
11170
  (0, import_fs18.mkdirSync)(tempDir, { recursive: true });
10876
11171
  }
10877
11172
  for (const [filename, base64Data] of Object.entries(EMBEDDED_WASM_FILES)) {
10878
- const wasmPath = (0, import_path2.join)(tempDir, filename);
11173
+ const wasmPath = (0, import_path3.join)(tempDir, filename);
10879
11174
  if ((0, import_fs18.existsSync)(wasmPath)) {
10880
11175
  continue;
10881
11176
  }
@@ -10890,8 +11185,8 @@ function extractWasmFiles() {
10890
11185
 
10891
11186
  // apps/cli/src/main.ts
10892
11187
  var import_dotenv = require("dotenv");
10893
- var fs11 = __toESM(require("fs"));
10894
- var path10 = __toESM(require("path"));
11188
+ var fs12 = __toESM(require("fs"));
11189
+ var path11 = __toESM(require("path"));
10895
11190
 
10896
11191
  // apps/cli/src/infra/commands/InstallCommand.ts
10897
11192
  var import_cmd_ts2 = __toESM(require_cjs());
@@ -11123,9 +11418,12 @@ async function executeInstallForDirectory(directory, deps) {
11123
11418
  previousPackagesSlugs: configPackages
11124
11419
  // Pass for consistency
11125
11420
  });
11126
- log(
11127
- ` Installing ${result.recipesCount} commands and ${result.standardsCount} standards...`
11128
- );
11421
+ const parts = [];
11422
+ if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
11423
+ if (result.standardsCount > 0)
11424
+ parts.push(`${result.standardsCount} standards`);
11425
+ if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
11426
+ log(` Installing ${parts.join(", ") || "artifacts"}...`);
11129
11427
  log(
11130
11428
  ` added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
11131
11429
  );
@@ -11234,9 +11532,12 @@ async function installPackagesHandler(args2, deps) {
11234
11532
  previousPackagesSlugs: configPackages
11235
11533
  // Pass previous config for change detection
11236
11534
  });
11237
- log(
11238
- `Installing ${result.recipesCount} commands and ${result.standardsCount} standards...`
11239
- );
11535
+ const parts = [];
11536
+ if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
11537
+ if (result.standardsCount > 0)
11538
+ parts.push(`${result.standardsCount} standards`);
11539
+ if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
11540
+ log(`Installing ${parts.join(", ") || "artifacts"}...`);
11240
11541
  log(
11241
11542
  `
11242
11543
  added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
@@ -11850,13 +12151,13 @@ Credentials are loaded from (in order of priority):`);
11850
12151
 
11851
12152
  // apps/cli/src/infra/commands/SetupMcpCommand.ts
11852
12153
  var import_cmd_ts7 = __toESM(require_cjs());
11853
- var fs10 = __toESM(require("fs"));
12154
+ var fs11 = __toESM(require("fs"));
11854
12155
  var readline2 = __toESM(require("readline"));
11855
12156
  var inquirer = __toESM(require("inquirer"));
11856
12157
 
11857
12158
  // apps/cli/src/application/services/AgentDetectionService.ts
11858
- var fs9 = __toESM(require("fs"));
11859
- var path9 = __toESM(require("path"));
12159
+ var fs10 = __toESM(require("fs"));
12160
+ var path10 = __toESM(require("path"));
11860
12161
  var os4 = __toESM(require("os"));
11861
12162
  var import_child_process3 = require("child_process");
11862
12163
  var AgentDetectionService = class {
@@ -11883,21 +12184,21 @@ var AgentDetectionService = class {
11883
12184
  return this.isCommandAvailable("claude");
11884
12185
  }
11885
12186
  isCursorAvailable() {
11886
- const cursorConfigDir = path9.join(os4.homedir(), ".cursor");
11887
- return fs9.existsSync(cursorConfigDir);
12187
+ const cursorConfigDir = path10.join(os4.homedir(), ".cursor");
12188
+ return fs10.existsSync(cursorConfigDir);
11888
12189
  }
11889
12190
  isVSCodeAvailable() {
11890
- const vscodeDir = path9.join(this.projectDir, ".vscode");
11891
- return fs9.existsSync(vscodeDir);
12191
+ const vscodeDir = path10.join(this.projectDir, ".vscode");
12192
+ return fs10.existsSync(vscodeDir);
11892
12193
  }
11893
12194
  isContinueAvailable() {
11894
- const continueDir = path9.join(this.projectDir, ".continue");
11895
- return fs9.existsSync(continueDir);
12195
+ const continueDir = path10.join(this.projectDir, ".continue");
12196
+ return fs10.existsSync(continueDir);
11896
12197
  }
11897
- isCommandAvailable(command8) {
12198
+ isCommandAvailable(command9) {
11898
12199
  try {
11899
12200
  const whichCommand = process.platform === "win32" ? "where" : "which";
11900
- (0, import_child_process3.execSync)(`${whichCommand} ${command8}`, { stdio: "pipe" });
12201
+ (0, import_child_process3.execSync)(`${whichCommand} ${command9}`, { stdio: "pipe" });
11901
12202
  return true;
11902
12203
  } catch {
11903
12204
  return false;
@@ -11931,8 +12232,8 @@ var ALL_AGENTS2 = [
11931
12232
  { type: "continue", name: "Continue.dev" }
11932
12233
  ];
11933
12234
  async function promptAgentsWithReadline(choices) {
11934
- const input = fs10.createReadStream("/dev/tty");
11935
- const output = fs10.createWriteStream("/dev/tty");
12235
+ const input = fs11.createReadStream("/dev/tty");
12236
+ const output = fs11.createWriteStream("/dev/tty");
11936
12237
  const rl = readline2.createInterface({
11937
12238
  input,
11938
12239
  output
@@ -12092,26 +12393,86 @@ Credentials are loaded from (in order of priority):`);
12092
12393
  }
12093
12394
  });
12094
12395
 
12396
+ // apps/cli/src/infra/commands/SkillsCommand.ts
12397
+ var import_cmd_ts9 = __toESM(require_cjs());
12398
+
12399
+ // apps/cli/src/infra/commands/skills/AddSkillCommand.ts
12400
+ var import_cmd_ts8 = __toESM(require_cjs());
12401
+ var addSkillCommand = (0, import_cmd_ts8.command)({
12402
+ name: "add",
12403
+ description: "Add a skill from a local directory to a Packmind organization",
12404
+ args: {
12405
+ skillPath: (0, import_cmd_ts8.positional)({
12406
+ type: import_cmd_ts8.string,
12407
+ displayName: "path",
12408
+ description: "Path to skill directory containing SKILL.md"
12409
+ })
12410
+ },
12411
+ handler: async ({ skillPath }) => {
12412
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
12413
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
12414
+ try {
12415
+ logInfoConsole(`Uploading skill from ${skillPath}...`);
12416
+ const result = await packmindCliHexa.uploadSkill({
12417
+ skillPath,
12418
+ organizationId: "",
12419
+ userId: ""
12420
+ });
12421
+ if (result.isNewSkill) {
12422
+ logSuccessConsole("Skill created successfully!");
12423
+ } else if (!result.versionCreated) {
12424
+ logInfoConsole(
12425
+ `Skill content is identical to version ${result.version}, no new version created.`
12426
+ );
12427
+ } else {
12428
+ logSuccessConsole(`Skill updated to version ${result.version}!`);
12429
+ }
12430
+ logInfoConsole(` Name: ${result.name}`);
12431
+ logInfoConsole(` Version: ${result.version}`);
12432
+ logInfoConsole(` Files: ${result.fileCount}`);
12433
+ logInfoConsole(
12434
+ ` Total size: ${(result.totalSize / 1024).toFixed(2)} KB`
12435
+ );
12436
+ } catch (error) {
12437
+ if (error instanceof Error) {
12438
+ logErrorConsole(`Upload failed: ${error.message}`);
12439
+ } else {
12440
+ logErrorConsole(`Upload failed: ${String(error)}`);
12441
+ }
12442
+ process.exit(1);
12443
+ }
12444
+ }
12445
+ });
12446
+
12447
+ // apps/cli/src/infra/commands/SkillsCommand.ts
12448
+ var skillsCommand = (0, import_cmd_ts9.subcommands)({
12449
+ name: "skills",
12450
+ description: "Manage skills in your Packmind organization",
12451
+ cmds: {
12452
+ add: addSkillCommand
12453
+ }
12454
+ });
12455
+
12095
12456
  // apps/cli/src/main.ts
12096
12457
  var { version: CLI_VERSION } = require_package();
12097
12458
  function findEnvFile() {
12098
12459
  const currentDir = process.cwd();
12099
12460
  const gitService = new GitService();
12100
12461
  const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
12101
- const filesystemRoot = path10.parse(currentDir).root;
12462
+ const filesystemRoot = path11.parse(currentDir).root;
12102
12463
  const stopDir = gitRoot ?? filesystemRoot;
12103
12464
  let searchDir = currentDir;
12104
- let parentDir = path10.dirname(searchDir);
12465
+ let parentDir = path11.dirname(searchDir);
12105
12466
  while (searchDir !== parentDir) {
12106
- const envPath2 = path10.join(searchDir, ".env");
12107
- if (fs11.existsSync(envPath2)) {
12467
+ const envPath2 = path11.join(searchDir, ".env");
12468
+ if (fs12.existsSync(envPath2)) {
12108
12469
  return envPath2;
12109
12470
  }
12110
12471
  if (searchDir === stopDir) {
12111
12472
  return null;
12112
12473
  }
12113
12474
  searchDir = parentDir;
12114
- parentDir = path10.dirname(searchDir);
12475
+ parentDir = path11.dirname(searchDir);
12115
12476
  }
12116
12477
  return null;
12117
12478
  }
@@ -12131,7 +12492,7 @@ if (args.includes("--version") || args.includes("-v")) {
12131
12492
  console.log(`packmind-cli version ${CLI_VERSION}`);
12132
12493
  process.exit(0);
12133
12494
  }
12134
- var app = (0, import_cmd_ts8.subcommands)({
12495
+ var app = (0, import_cmd_ts10.subcommands)({
12135
12496
  name: "packmind-cli",
12136
12497
  description: "Packmind CLI tool",
12137
12498
  cmds: {
@@ -12143,10 +12504,11 @@ var app = (0, import_cmd_ts8.subcommands)({
12143
12504
  login: loginCommand,
12144
12505
  logout: logoutCommand,
12145
12506
  whoami: whoamiCommand,
12146
- "setup-mcp": setupMcpCommand
12507
+ "setup-mcp": setupMcpCommand,
12508
+ skills: skillsCommand
12147
12509
  }
12148
12510
  });
12149
- (0, import_cmd_ts8.run)(app, args).catch((error) => {
12511
+ (0, import_cmd_ts10.run)(app, args).catch((error) => {
12150
12512
  logErrorConsole(error.message);
12151
12513
  process.exit(1);
12152
12514
  });