@packmind/cli 0.12.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 +195 -38
  2. package/package.json +1 -1
package/main.cjs CHANGED
@@ -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) {
@@ -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.12.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_ts9 = __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
  }
@@ -4195,6 +4195,13 @@ var RuleAddedEvent = class extends UserEvent {
4195
4195
  }
4196
4196
  };
4197
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
+
4198
4205
  // packages/types/src/standards/events/StandardCreatedEvent.ts
4199
4206
  var StandardCreatedEvent = class extends UserEvent {
4200
4207
  static {
@@ -5933,6 +5940,84 @@ var LintFilesLocallyUseCase = class {
5933
5940
  // apps/cli/src/infra/utils/readSkillDirectory.ts
5934
5941
  var import_promises = __toESM(require("fs/promises"));
5935
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;
5936
6021
  async function readSkillDirectory(dirPath) {
5937
6022
  const files = [];
5938
6023
  async function readDir(currentPath, basePath) {
@@ -5943,14 +6028,30 @@ async function readSkillDirectory(dirPath) {
5943
6028
  if (entry.isDirectory()) {
5944
6029
  await readDir(fullPath, basePath);
5945
6030
  } else if (entry.isFile()) {
5946
- const content = await import_promises.default.readFile(fullPath, "utf-8");
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
+ }
5947
6047
  files.push({
5948
6048
  path: fullPath,
5949
- relativePath,
6049
+ relativePath: normalizedPath,
5950
6050
  content,
5951
- size: Buffer.byteLength(content, "utf-8"),
5952
- permissions: "rw-r--r--"
6051
+ size: Buffer.byteLength(content, isBinary ? "base64" : "utf-8"),
6052
+ permissions: "rw-r--r--",
5953
6053
  // Simple default
6054
+ isBase64: isBinary
5954
6055
  });
5955
6056
  }
5956
6057
  }
@@ -6628,6 +6729,12 @@ var PackmindGateway = class {
6628
6729
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
6629
6730
  throw new Error("SKILL.md not found in skill directory");
6630
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
+ }
6631
6738
  const totalSize = files.reduce((sum, f) => sum + f.size, 0);
6632
6739
  if (totalSize > 10 * 1024 * 1024) {
6633
6740
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
@@ -6636,7 +6743,8 @@ var PackmindGateway = class {
6636
6743
  files: files.map((f) => ({
6637
6744
  path: f.relativePath,
6638
6745
  content: f.content,
6639
- permissions: f.permissions || "rw-r--r--"
6746
+ permissions: f.permissions || "rw-r--r--",
6747
+ isBase64: f.isBase64
6640
6748
  }))
6641
6749
  };
6642
6750
  const url = `${host}/api/v0/organizations/${organizationId}/spaces/${spaceId}/skills/upload`;
@@ -6658,12 +6766,19 @@ var PackmindGateway = class {
6658
6766
  }
6659
6767
  } catch {
6660
6768
  }
6769
+ if (response.status === 409) {
6770
+ throw new Error(`Skill already exists: ${errorMsg}`);
6771
+ }
6661
6772
  throw new Error(errorMsg);
6662
6773
  }
6774
+ const isNewSkill = response.status === 201;
6663
6775
  const result = await response.json();
6664
6776
  return {
6665
- skillId: result.id,
6666
- name: result.name,
6777
+ skillId: result.skill.id,
6778
+ name: result.skill.name,
6779
+ version: result.skill.version,
6780
+ isNewSkill,
6781
+ versionCreated: result.versionCreated,
6667
6782
  fileCount: files.length,
6668
6783
  totalSize
6669
6784
  };
@@ -9527,7 +9642,8 @@ var InstallPackagesUseCase = class {
9527
9642
  filesDeleted: 0,
9528
9643
  errors: [],
9529
9644
  recipesCount: 0,
9530
- standardsCount: 0
9645
+ standardsCount: 0,
9646
+ skillsCount: 0
9531
9647
  };
9532
9648
  const response = await this.packmindGateway.getPullData({
9533
9649
  packagesSlugs: command9.packagesSlugs,
@@ -9543,6 +9659,8 @@ var InstallPackagesUseCase = class {
9543
9659
  result.recipesCount++;
9544
9660
  } else if (file.path.includes(".packmind/standards/") && file.path.endsWith(".md")) {
9545
9661
  result.standardsCount++;
9662
+ } else if (file.path.includes(".packmind/skills/") && file.path.endsWith(".md")) {
9663
+ result.skillsCount++;
9546
9664
  }
9547
9665
  }
9548
9666
  try {
@@ -9580,7 +9698,8 @@ var InstallPackagesUseCase = class {
9580
9698
  fullPath,
9581
9699
  file.content,
9582
9700
  fileExists,
9583
- result
9701
+ result,
9702
+ file.isBase64
9584
9703
  );
9585
9704
  } else if (file.sections !== void 0) {
9586
9705
  await this.handleSectionsUpdate(
@@ -9591,7 +9710,17 @@ var InstallPackagesUseCase = class {
9591
9710
  );
9592
9711
  }
9593
9712
  }
9594
- 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
+ }
9595
9724
  if (fileExists) {
9596
9725
  const existingContent = await fs5.readFile(fullPath, "utf-8");
9597
9726
  const commentMarker = this.extractCommentMarker(content);
@@ -11289,9 +11418,12 @@ async function executeInstallForDirectory(directory, deps) {
11289
11418
  previousPackagesSlugs: configPackages
11290
11419
  // Pass for consistency
11291
11420
  });
11292
- log(
11293
- ` Installing ${result.recipesCount} commands and ${result.standardsCount} standards...`
11294
- );
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"}...`);
11295
11427
  log(
11296
11428
  ` added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
11297
11429
  );
@@ -11400,9 +11532,12 @@ async function installPackagesHandler(args2, deps) {
11400
11532
  previousPackagesSlugs: configPackages
11401
11533
  // Pass previous config for change detection
11402
11534
  });
11403
- log(
11404
- `Installing ${result.recipesCount} commands and ${result.standardsCount} standards...`
11405
- );
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"}...`);
11406
11541
  log(
11407
11542
  `
11408
11543
  added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
@@ -12258,11 +12393,14 @@ Credentials are loaded from (in order of priority):`);
12258
12393
  }
12259
12394
  });
12260
12395
 
12261
- // apps/cli/src/infra/commands/UploadSkillCommand.ts
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
12262
12400
  var import_cmd_ts8 = __toESM(require_cjs());
12263
- var uploadSkillCommand = (0, import_cmd_ts8.command)({
12264
- name: "upload-skill",
12265
- description: "Upload a skill from a local directory to a Packmind organization",
12401
+ var addSkillCommand = (0, import_cmd_ts8.command)({
12402
+ name: "add",
12403
+ description: "Add a skill from a local directory to a Packmind organization",
12266
12404
  args: {
12267
12405
  skillPath: (0, import_cmd_ts8.positional)({
12268
12406
  type: import_cmd_ts8.string,
@@ -12280,11 +12418,21 @@ var uploadSkillCommand = (0, import_cmd_ts8.command)({
12280
12418
  organizationId: "",
12281
12419
  userId: ""
12282
12420
  });
12283
- logSuccessConsole("Skill uploaded successfully!");
12284
- console.log(` Skill ID: ${result.skillId}`);
12285
- console.log(` Name: ${result.name}`);
12286
- console.log(` Files: ${result.fileCount}`);
12287
- console.log(` Total size: ${(result.totalSize / 1024).toFixed(2)} KB`);
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
+ );
12288
12436
  } catch (error) {
12289
12437
  if (error instanceof Error) {
12290
12438
  logErrorConsole(`Upload failed: ${error.message}`);
@@ -12296,6 +12444,15 @@ var uploadSkillCommand = (0, import_cmd_ts8.command)({
12296
12444
  }
12297
12445
  });
12298
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
+
12299
12456
  // apps/cli/src/main.ts
12300
12457
  var { version: CLI_VERSION } = require_package();
12301
12458
  function findEnvFile() {
@@ -12335,7 +12492,7 @@ if (args.includes("--version") || args.includes("-v")) {
12335
12492
  console.log(`packmind-cli version ${CLI_VERSION}`);
12336
12493
  process.exit(0);
12337
12494
  }
12338
- var app = (0, import_cmd_ts9.subcommands)({
12495
+ var app = (0, import_cmd_ts10.subcommands)({
12339
12496
  name: "packmind-cli",
12340
12497
  description: "Packmind CLI tool",
12341
12498
  cmds: {
@@ -12348,10 +12505,10 @@ var app = (0, import_cmd_ts9.subcommands)({
12348
12505
  logout: logoutCommand,
12349
12506
  whoami: whoamiCommand,
12350
12507
  "setup-mcp": setupMcpCommand,
12351
- "upload-skill": uploadSkillCommand
12508
+ skills: skillsCommand
12352
12509
  }
12353
12510
  });
12354
- (0, import_cmd_ts9.run)(app, args).catch((error) => {
12511
+ (0, import_cmd_ts10.run)(app, args).catch((error) => {
12355
12512
  logErrorConsole(error.message);
12356
12513
  process.exit(1);
12357
12514
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@packmind/cli",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "A command-line interface for Packmind linting and code quality checks",
5
5
  "private": false,
6
6
  "bin": {