@packmind/cli 0.31.0 → 0.32.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 +865 -348
  2. package/package.json +9 -11
package/main.cjs CHANGED
@@ -13,11 +13,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
13
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
14
  var __getProtoOf = Object.getPrototypeOf;
15
15
  var __hasOwnProp = Object.prototype.hasOwnProperty;
16
- var __esm = (fn, res) => function __init() {
17
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ var __esm = (fn, res, err) => function __init() {
17
+ if (err) throw err[0];
18
+ try {
19
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
20
+ } catch (e) {
21
+ throw err = [e], e;
22
+ }
18
23
  };
19
24
  var __commonJS = (cb, mod) => function __require() {
20
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
25
+ try {
26
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
27
+ } catch (e) {
28
+ throw mod = 0, e;
29
+ }
21
30
  };
22
31
  var __export = (target, all) => {
23
32
  for (var name in all)
@@ -234,9 +243,9 @@ var init_ansi_styles = __esm({
234
243
  });
235
244
 
236
245
  // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
237
- function hasFlag(flag7, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
238
- const prefix = flag7.startsWith("-") ? "" : flag7.length === 1 ? "-" : "--";
239
- const position = argv.indexOf(prefix + flag7);
246
+ function hasFlag(flag8, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
247
+ const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
248
+ const position = argv.indexOf(prefix + flag8);
240
249
  const terminatorPosition = argv.indexOf("--");
241
250
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
242
251
  }
@@ -935,7 +944,7 @@ var require_flag = __commonJS({
935
944
  Object.defineProperty(exports2, "__esModule", { value: true });
936
945
  exports2.boolean = void 0;
937
946
  exports2.fullFlag = fullFlag;
938
- exports2.flag = flag7;
947
+ exports2.flag = flag8;
939
948
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
940
949
  var Result = __importStar(require_Result());
941
950
  var findOption_1 = require_findOption();
@@ -1084,7 +1093,7 @@ var require_flag = __commonJS({
1084
1093
  }
1085
1094
  };
1086
1095
  }
1087
- function flag7(config) {
1096
+ function flag8(config) {
1088
1097
  return fullFlag({
1089
1098
  type: types_1.boolean,
1090
1099
  ...config
@@ -1701,12 +1710,12 @@ var require_command = __commonJS({
1701
1710
  return mod && mod.__esModule ? mod : { "default": mod };
1702
1711
  };
1703
1712
  Object.defineProperty(exports2, "__esModule", { value: true });
1704
- exports2.command = command30;
1713
+ exports2.command = command31;
1705
1714
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1706
1715
  var Result = __importStar(require_Result());
1707
1716
  var circuitbreaker_1 = require_circuitbreaker();
1708
1717
  var utils_1 = require_utils();
1709
- function command30(config) {
1718
+ function command31(config) {
1710
1719
  const argEntries = (0, utils_1.entries)(config.args);
1711
1720
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1712
1721
  return {
@@ -2224,9 +2233,9 @@ var require_ms = __commonJS({
2224
2233
  }
2225
2234
  });
2226
2235
 
2227
- // node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/common.js
2236
+ // node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/common.js
2228
2237
  var require_common = __commonJS({
2229
- "node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/common.js"(exports2, module2) {
2238
+ "node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/common.js"(exports2, module2) {
2230
2239
  "use strict";
2231
2240
  function setup(env2) {
2232
2241
  createDebug.debug = createDebug;
@@ -2402,9 +2411,9 @@ var require_common = __commonJS({
2402
2411
  }
2403
2412
  });
2404
2413
 
2405
- // node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/browser.js
2414
+ // node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/browser.js
2406
2415
  var require_browser = __commonJS({
2407
- "node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/browser.js"(exports2, module2) {
2416
+ "node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/browser.js"(exports2, module2) {
2408
2417
  "use strict";
2409
2418
  exports2.formatArgs = formatArgs;
2410
2419
  exports2.save = save;
@@ -2577,10 +2586,10 @@ var require_browser = __commonJS({
2577
2586
  var require_has_flag = __commonJS({
2578
2587
  "node_modules/.pnpm/has-flag@3.0.0/node_modules/has-flag/index.js"(exports2, module2) {
2579
2588
  "use strict";
2580
- module2.exports = (flag7, argv) => {
2589
+ module2.exports = (flag8, argv) => {
2581
2590
  argv = argv || process.argv;
2582
- const prefix = flag7.startsWith("-") ? "" : flag7.length === 1 ? "-" : "--";
2583
- const pos = argv.indexOf(prefix + flag7);
2591
+ const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
2592
+ const pos = argv.indexOf(prefix + flag8);
2584
2593
  const terminatorPos = argv.indexOf("--");
2585
2594
  return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
2586
2595
  };
@@ -2682,9 +2691,9 @@ var require_supports_color = __commonJS({
2682
2691
  }
2683
2692
  });
2684
2693
 
2685
- // node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/node.js
2694
+ // node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/node.js
2686
2695
  var require_node = __commonJS({
2687
- "node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/node.js"(exports2, module2) {
2696
+ "node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/node.js"(exports2, module2) {
2688
2697
  "use strict";
2689
2698
  var tty2 = require("tty");
2690
2699
  var util = require("util");
@@ -2857,9 +2866,9 @@ var require_node = __commonJS({
2857
2866
  }
2858
2867
  });
2859
2868
 
2860
- // node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/index.js
2869
+ // node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/index.js
2861
2870
  var require_src = __commonJS({
2862
- "node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/index.js"(exports2, module2) {
2871
+ "node_modules/.pnpm/debug@4.4.3/node_modules/debug/src/index.js"(exports2, module2) {
2863
2872
  "use strict";
2864
2873
  if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
2865
2874
  module2.exports = require_browser();
@@ -3849,7 +3858,7 @@ var require_package = __commonJS({
3849
3858
  "apps/cli/package.json"(exports2, module2) {
3850
3859
  module2.exports = {
3851
3860
  name: "@packmind/cli",
3852
- version: "0.31.0",
3861
+ version: "0.32.0",
3853
3862
  description: "A command-line interface for Packmind linting and code quality checks",
3854
3863
  private: false,
3855
3864
  bin: {
@@ -3884,14 +3893,19 @@ var require_package = __commonJS({
3884
3893
  "packmind-cli": "ts-node --project tsconfig.app.json src/main.ts"
3885
3894
  },
3886
3895
  dependencies: {
3887
- "@types/inquirer": "^9.0.9",
3896
+ chalk: "^5.6.0",
3897
+ "cmd-ts": "^0.14.3",
3898
+ diff: "^8.0.3",
3888
3899
  dotenv: "^16",
3889
3900
  inquirer: "^13.0.2",
3901
+ "log-update": "^8.0.0",
3890
3902
  minimatch: "^10",
3903
+ open: "^11.0.0",
3891
3904
  semver: "^7.7.4",
3892
- undici: "^7",
3905
+ slug: "^11.0.0",
3906
+ undici: "^7.28.0",
3893
3907
  which: "^4.0.0",
3894
- zod: "^4.3.5"
3908
+ yaml: "^2.8.3"
3895
3909
  },
3896
3910
  devDependencies: {
3897
3911
  "@types/which": "^3.0.4"
@@ -3901,7 +3915,7 @@ var require_package = __commonJS({
3901
3915
  });
3902
3916
 
3903
3917
  // apps/cli/src/main.ts
3904
- var import_cmd_ts40 = __toESM(require_cjs());
3918
+ var import_cmd_ts41 = __toESM(require_cjs());
3905
3919
 
3906
3920
  // apps/cli/src/infra/commands/LinterCommand.ts
3907
3921
  var import_cmd_ts = __toESM(require_cjs());
@@ -4256,27 +4270,27 @@ function validateArtifactFileFormat(filePath, artifactType) {
4256
4270
  return { valid: true };
4257
4271
  }
4258
4272
 
4259
- // packages/types/src/recipes/RecipeId.ts
4260
- var createRecipeId = brandedIdFactory();
4273
+ // packages/types/src/commands/CommandId.ts
4274
+ var createCommandId = brandedIdFactory();
4261
4275
 
4262
- // packages/types/src/recipes/RecipeVersion.ts
4263
- var createRecipeVersionId = brandedIdFactory();
4276
+ // packages/types/src/commands/CommandVersion.ts
4277
+ var createCommandVersionId = brandedIdFactory();
4264
4278
 
4265
- // packages/types/src/recipes/events/CommandCreatedEvent.ts
4279
+ // packages/types/src/commands/events/CommandCreatedEvent.ts
4266
4280
  var CommandCreatedEvent = class extends UserEvent {
4267
4281
  static {
4268
4282
  this.eventName = "recipes.recipe.created";
4269
4283
  }
4270
4284
  };
4271
4285
 
4272
- // packages/types/src/recipes/events/CommandDeletedEvent.ts
4286
+ // packages/types/src/commands/events/CommandDeletedEvent.ts
4273
4287
  var CommandDeletedEvent = class extends UserEvent {
4274
4288
  static {
4275
4289
  this.eventName = "recipes.recipe.deleted";
4276
4290
  }
4277
4291
  };
4278
4292
 
4279
- // packages/types/src/recipes/events/CommandUpdatedEvent.ts
4293
+ // packages/types/src/commands/events/CommandUpdatedEvent.ts
4280
4294
  var CommandUpdatedEvent = class extends UserEvent {
4281
4295
  static {
4282
4296
  this.eventName = "recipes.recipe.updated";
@@ -4445,6 +4459,13 @@ var DeploymentCompletedEvent = class extends UserEvent {
4445
4459
  }
4446
4460
  };
4447
4461
 
4462
+ // packages/types/src/deployments/events/DistributionRecordedEvent.ts
4463
+ var DistributionRecordedEvent = class extends UserEvent {
4464
+ static {
4465
+ this.eventName = "deployments.distribution.recorded";
4466
+ }
4467
+ };
4468
+
4448
4469
  // packages/types/src/deployments/events/PackagesDeletedEvent.ts
4449
4470
  var PackagesDeletedEvent = class extends UserEvent {
4450
4471
  static {
@@ -4478,6 +4499,13 @@ var createGitProviderId = brandedIdFactory();
4478
4499
  // packages/types/src/git/OrganizationGitHubApp.ts
4479
4500
  var createOrganizationGitHubAppId = brandedIdFactory();
4480
4501
 
4502
+ // packages/types/src/git/events/RepositoryTrackingSetEvent.ts
4503
+ var RepositoryTrackingSetEvent = class extends UserEvent {
4504
+ static {
4505
+ this.eventName = "git.repository.tracking-set";
4506
+ }
4507
+ };
4508
+
4481
4509
  // packages/types/src/spaces/SpaceId.ts
4482
4510
  var createSpaceId = brandedIdFactory();
4483
4511
 
@@ -5392,8 +5420,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
5392
5420
  static {
5393
5421
  this.fallbackRuleContent = "adhoc-rule";
5394
5422
  }
5395
- async execute(command30) {
5396
- const { program, fileContent, language } = command30;
5423
+ async execute(command31) {
5424
+ const { program, fileContent, language } = command31;
5397
5425
  const result = await this.linterExecutionUseCase.execute({
5398
5426
  filePath: "cli-single-file",
5399
5427
  fileContent,
@@ -5777,8 +5805,8 @@ var GetGitRemoteUrlUseCase = class {
5777
5805
  constructor(gitRemoteUrlService = new GitService()) {
5778
5806
  this.gitRemoteUrlService = gitRemoteUrlService;
5779
5807
  }
5780
- async execute(command30) {
5781
- const { path: repoPath, origin: origin9 } = command30;
5808
+ async execute(command31) {
5809
+ const { path: repoPath, origin: origin9 } = command31;
5782
5810
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5783
5811
  }
5784
5812
  };
@@ -5930,8 +5958,8 @@ var ListFilesInDirectoryUseCase = class {
5930
5958
  constructor(listFiles = new ListFiles()) {
5931
5959
  this.listFiles = listFiles;
5932
5960
  }
5933
- async execute(command30) {
5934
- const { path: directoryPath, extensions, excludes = [] } = command30;
5961
+ async execute(command31) {
5962
+ const { path: directoryPath, extensions, excludes = [] } = command31;
5935
5963
  const files = await this.listFiles.listFilesInDirectory(
5936
5964
  directoryPath,
5937
5965
  extensions,
@@ -6046,7 +6074,7 @@ var LintFilesAgainstRuleUseCase = class {
6046
6074
  };
6047
6075
  };
6048
6076
  }
6049
- async execute(command30) {
6077
+ async execute(command31) {
6050
6078
  const {
6051
6079
  path: userPath,
6052
6080
  draftMode,
@@ -6055,7 +6083,7 @@ var LintFilesAgainstRuleUseCase = class {
6055
6083
  language,
6056
6084
  diffMode,
6057
6085
  ignorePatterns
6058
- } = command30;
6086
+ } = command31;
6059
6087
  this.logger.debug(
6060
6088
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
6061
6089
  );
@@ -6371,8 +6399,8 @@ var LintFilesAgainstRuleUseCase = class {
6371
6399
  return null;
6372
6400
  }
6373
6401
  }
6374
- async executeProgramsForFile(command30) {
6375
- const result = await this.services.linterExecutionUseCase.execute(command30);
6402
+ async executeProgramsForFile(command31) {
6403
+ const result = await this.services.linterExecutionUseCase.execute(command31);
6376
6404
  return result.violations;
6377
6405
  }
6378
6406
  extractExtensionFromFile(filePath) {
@@ -6395,8 +6423,8 @@ var LintFilesFromConfigUseCase = class {
6395
6423
  this.logger = logger2;
6396
6424
  this.detectionProgramsCache = /* @__PURE__ */ new Map();
6397
6425
  }
6398
- async execute(command30) {
6399
- const { path: userPath, diffMode, ignorePatterns } = command30;
6426
+ async execute(command31) {
6427
+ const { path: userPath, diffMode, ignorePatterns } = command31;
6400
6428
  this.logger.debug(
6401
6429
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
6402
6430
  );
@@ -6656,8 +6684,8 @@ var LintFilesFromConfigUseCase = class {
6656
6684
  return null;
6657
6685
  }
6658
6686
  }
6659
- async executeProgramsForFile(command30) {
6660
- const result = await this.services.linterExecutionUseCase.execute(command30);
6687
+ async executeProgramsForFile(command31) {
6688
+ const result = await this.services.linterExecutionUseCase.execute(command31);
6661
6689
  return result.violations;
6662
6690
  }
6663
6691
  extractExtensionFromFile(filePath) {
@@ -6673,7 +6701,7 @@ var LintFilesFromConfigUseCase = class {
6673
6701
  var NotLoggedInError = class extends Error {
6674
6702
  constructor() {
6675
6703
  super(
6676
- "You're not logged in to Packmind. Please either use the login command or set the PACKMIND_API_KEY_V3 environment variable (from the Settings menu in Packmind)."
6704
+ "You're not logged in to Packmind. Please either use the login command or set the PACKMIND_API_KEY environment variable (from the Settings menu in Packmind)."
6677
6705
  );
6678
6706
  this.name = "NotLoggedInError";
6679
6707
  }
@@ -6833,13 +6861,13 @@ var PackmindHttpClient = class {
6833
6861
  var ChangeProposalGateway = class {
6834
6862
  constructor(httpClient) {
6835
6863
  this.httpClient = httpClient;
6836
- this.batchCreate = async (command30) => {
6864
+ this.batchCreate = async (command31) => {
6837
6865
  const { organizationId } = this.httpClient.getAuthContext();
6838
6866
  return this.httpClient.request(
6839
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/batch`,
6867
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/change-proposals/batch`,
6840
6868
  {
6841
6869
  method: "POST",
6842
- body: { proposals: command30.proposals },
6870
+ body: { proposals: command31.proposals },
6843
6871
  onError: (response) => {
6844
6872
  if (response.status === 404) {
6845
6873
  throw new CommunityEditionError("change proposals");
@@ -6848,29 +6876,29 @@ var ChangeProposalGateway = class {
6848
6876
  }
6849
6877
  );
6850
6878
  };
6851
- this.batchApply = async (command30) => {
6879
+ this.batchApply = async (command31) => {
6852
6880
  const { organizationId } = this.httpClient.getAuthContext();
6853
6881
  return this.httpClient.request(
6854
6882
  `/api/v0/organizations/${organizationId}/playbook/apply`,
6855
6883
  {
6856
6884
  method: "POST",
6857
6885
  body: {
6858
- proposals: command30.proposals,
6859
- message: command30.message,
6860
- ...command30.directUpdate !== void 0 && {
6861
- directUpdate: command30.directUpdate
6886
+ proposals: command31.proposals,
6887
+ message: command31.message,
6888
+ ...command31.directUpdate !== void 0 && {
6889
+ directUpdate: command31.directUpdate
6862
6890
  }
6863
6891
  }
6864
6892
  }
6865
6893
  );
6866
6894
  };
6867
- this.check = async (command30) => {
6895
+ this.check = async (command31) => {
6868
6896
  const { organizationId } = this.httpClient.getAuthContext();
6869
6897
  return this.httpClient.request(
6870
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/check`,
6898
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/change-proposals/check`,
6871
6899
  {
6872
6900
  method: "POST",
6873
- body: { proposals: command30.proposals },
6901
+ body: { proposals: command31.proposals },
6874
6902
  onError: (response) => {
6875
6903
  if (response.status === 404) {
6876
6904
  throw new CommunityEditionError("change proposals");
@@ -6886,13 +6914,13 @@ var ChangeProposalGateway = class {
6886
6914
  var LinterGateway = class {
6887
6915
  constructor(httpClient) {
6888
6916
  this.httpClient = httpClient;
6889
- this.getDraftDetectionProgramsForRule = async (command30) => {
6917
+ this.getDraftDetectionProgramsForRule = async (command31) => {
6890
6918
  const payload = {
6891
- standardSlug: command30.standardSlug,
6892
- ruleId: command30.ruleId
6919
+ standardSlug: command31.standardSlug,
6920
+ ruleId: command31.ruleId
6893
6921
  };
6894
- if (command30.language) {
6895
- payload.language = command30.language;
6922
+ if (command31.language) {
6923
+ payload.language = command31.language;
6896
6924
  }
6897
6925
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
6898
6926
  method: "POST",
@@ -6904,13 +6932,13 @@ var LinterGateway = class {
6904
6932
  }
6905
6933
  });
6906
6934
  };
6907
- this.getActiveDetectionProgramsForRule = async (command30) => {
6935
+ this.getActiveDetectionProgramsForRule = async (command31) => {
6908
6936
  const payload = {
6909
- standardSlug: command30.standardSlug,
6910
- ruleId: command30.ruleId
6937
+ standardSlug: command31.standardSlug,
6938
+ ruleId: command31.ruleId
6911
6939
  };
6912
- if (command30.language) {
6913
- payload.language = command30.language;
6940
+ if (command31.language) {
6941
+ payload.language = command31.language;
6914
6942
  }
6915
6943
  return this.httpClient.request("/api/v0/list-active-detection-program", {
6916
6944
  method: "POST",
@@ -6922,13 +6950,13 @@ var LinterGateway = class {
6922
6950
  }
6923
6951
  });
6924
6952
  };
6925
- this.getDetectionProgramsForPackages = async (command30) => {
6953
+ this.getDetectionProgramsForPackages = async (command31) => {
6926
6954
  const response = await this.httpClient.request(
6927
6955
  "/api/v0/detection-programs-for-packages",
6928
6956
  {
6929
6957
  method: "POST",
6930
6958
  body: {
6931
- packagesSlugs: command30.packagesSlugs
6959
+ packagesSlugs: command31.packagesSlugs
6932
6960
  },
6933
6961
  onError: (response2) => {
6934
6962
  if (response2.status === 404) {
@@ -6939,10 +6967,10 @@ var LinterGateway = class {
6939
6967
  );
6940
6968
  return handleScopeInTargetsResponse(response);
6941
6969
  };
6942
- this.trackLinterExecution = async (command30) => {
6970
+ this.trackLinterExecution = async (command31) => {
6943
6971
  return this.httpClient.request(`/api/v0/track-execution`, {
6944
6972
  method: "POST",
6945
- body: command30
6973
+ body: command31
6946
6974
  });
6947
6975
  };
6948
6976
  }
@@ -6996,27 +7024,27 @@ var SpacesGateway = class {
6996
7024
  var SkillsGateway = class {
6997
7025
  constructor(httpClient) {
6998
7026
  this.httpClient = httpClient;
6999
- this.upload = async (command30) => {
7027
+ this.upload = async (command31) => {
7000
7028
  const { organizationId } = this.httpClient.getAuthContext();
7001
7029
  return this.httpClient.request(
7002
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills/upload`,
7030
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/skills/upload`,
7003
7031
  {
7004
7032
  method: "POST",
7005
- body: command30
7033
+ body: command31
7006
7034
  }
7007
7035
  );
7008
7036
  };
7009
- this.getDefaults = async (command30) => {
7037
+ this.getDefaults = async (command31) => {
7010
7038
  const { organizationId } = this.httpClient.getAuthContext();
7011
7039
  const queryParams = new URLSearchParams();
7012
- if (command30.includeBeta) {
7040
+ if (command31.includeBeta) {
7013
7041
  queryParams.set("includeBeta", "true");
7014
- } else if (command30.cliVersion) {
7015
- queryParams.set("cliVersion", command30.cliVersion);
7042
+ } else if (command31.cliVersion) {
7043
+ queryParams.set("cliVersion", command31.cliVersion);
7016
7044
  }
7017
- if (command30.agents !== void 0) {
7045
+ if (command31.agents !== void 0) {
7018
7046
  queryParams.append("agentsConfigOverride", "true");
7019
- command30.agents.forEach((agent) => {
7047
+ command31.agents.forEach((agent) => {
7020
7048
  queryParams.append("agent", agent);
7021
7049
  });
7022
7050
  }
@@ -7025,10 +7053,10 @@ var SkillsGateway = class {
7025
7053
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
7026
7054
  );
7027
7055
  };
7028
- this.list = async (command30) => {
7056
+ this.list = async (command31) => {
7029
7057
  const { organizationId } = this.httpClient.getAuthContext();
7030
7058
  return this.httpClient.request(
7031
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills`
7059
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/skills`
7032
7060
  );
7033
7061
  };
7034
7062
  }
@@ -7038,22 +7066,24 @@ var SkillsGateway = class {
7038
7066
  var CommandsGateway = class {
7039
7067
  constructor(httpClient) {
7040
7068
  this.httpClient = httpClient;
7041
- this.create = async (command30) => {
7069
+ this.create = async (command31) => {
7042
7070
  const { organizationId } = this.httpClient.getAuthContext();
7043
7071
  return this.httpClient.request(
7044
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`,
7045
- { method: "POST", body: command30 }
7072
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/commands`,
7073
+ { method: "POST", body: command31 }
7046
7074
  );
7047
7075
  };
7048
- this.list = async (command30) => {
7076
+ this.list = async (command31) => {
7049
7077
  const { organizationId } = this.httpClient.getAuthContext();
7050
- const listRecipesResponse = await this.httpClient.request(
7051
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`
7078
+ const listCommandsResponse = await this.httpClient.request(
7079
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/commands`
7052
7080
  );
7053
- if (listRecipesResponse instanceof Array) {
7054
- return { recipes: listRecipesResponse };
7081
+ if (listCommandsResponse instanceof Array) {
7082
+ return { recipes: listCommandsResponse };
7055
7083
  }
7056
- return listRecipesResponse;
7084
+ return {
7085
+ recipes: listCommandsResponse.commands ?? listCommandsResponse.recipes ?? []
7086
+ };
7057
7087
  };
7058
7088
  }
7059
7089
  };
@@ -7089,10 +7119,10 @@ var StandardsGateway = class {
7089
7119
  }
7090
7120
  );
7091
7121
  };
7092
- this.list = async (command30) => {
7122
+ this.list = async (command31) => {
7093
7123
  const { organizationId } = this.httpClient.getAuthContext();
7094
7124
  return this.httpClient.request(
7095
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/standards`
7125
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/standards`
7096
7126
  );
7097
7127
  };
7098
7128
  }
@@ -7103,10 +7133,10 @@ var PackagesGateway = class {
7103
7133
  constructor(apiKey, httpClient) {
7104
7134
  this.apiKey = apiKey;
7105
7135
  this.httpClient = httpClient;
7106
- this.list = async (command30) => {
7136
+ this.list = async (command31) => {
7107
7137
  const { organizationId } = this.httpClient.getAuthContext();
7108
7138
  return this.httpClient.request(
7109
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`
7139
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/packages`
7110
7140
  );
7111
7141
  };
7112
7142
  this.getSummary = async ({
@@ -7118,24 +7148,25 @@ var PackagesGateway = class {
7118
7148
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug6)}`
7119
7149
  );
7120
7150
  };
7121
- this.create = async (command30) => {
7151
+ this.create = async (command31) => {
7122
7152
  const { organizationId } = this.httpClient.getAuthContext();
7153
+ const { recipeIds, ...rest } = command31;
7123
7154
  return this.httpClient.request(
7124
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`,
7155
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/packages`,
7125
7156
  {
7126
7157
  method: "POST",
7127
- body: command30
7158
+ body: { ...rest, commandIds: recipeIds }
7128
7159
  }
7129
7160
  );
7130
7161
  };
7131
- this.addArtefacts = async (command30) => {
7162
+ this.addArtefacts = async (command31) => {
7132
7163
  const { organizationId } = this.httpClient.getAuthContext();
7133
- const { packageId, spaceId } = command30;
7164
+ const { packageId, spaceId, recipeIds, ...rest } = command31;
7134
7165
  return this.httpClient.request(
7135
7166
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
7136
7167
  {
7137
7168
  method: "POST",
7138
- body: command30
7169
+ body: { ...rest, packageId, spaceId, commandIds: recipeIds }
7139
7170
  }
7140
7171
  );
7141
7172
  };
@@ -7146,31 +7177,31 @@ var PackagesGateway = class {
7146
7177
  var DeploymentGateway = class {
7147
7178
  constructor(httpClient) {
7148
7179
  this.httpClient = httpClient;
7149
- this.pull = async (command30) => {
7180
+ this.pull = async (command31) => {
7150
7181
  const { organizationId } = this.httpClient.getAuthContext();
7151
7182
  const queryParams = new URLSearchParams();
7152
- if (command30.packagesSlugs && command30.packagesSlugs.length > 0) {
7153
- command30.packagesSlugs.forEach((slug6) => {
7183
+ if (command31.packagesSlugs && command31.packagesSlugs.length > 0) {
7184
+ command31.packagesSlugs.forEach((slug6) => {
7154
7185
  queryParams.append("packageSlug", slug6);
7155
7186
  });
7156
7187
  }
7157
- if (command30.previousPackagesSlugs && command30.previousPackagesSlugs.length > 0) {
7158
- command30.previousPackagesSlugs.forEach((slug6) => {
7188
+ if (command31.previousPackagesSlugs && command31.previousPackagesSlugs.length > 0) {
7189
+ command31.previousPackagesSlugs.forEach((slug6) => {
7159
7190
  queryParams.append("previousPackageSlug", slug6);
7160
7191
  });
7161
7192
  }
7162
- if (command30.gitRemoteUrl) {
7163
- queryParams.append("gitRemoteUrl", command30.gitRemoteUrl);
7193
+ if (command31.gitRemoteUrl) {
7194
+ queryParams.append("gitRemoteUrl", command31.gitRemoteUrl);
7164
7195
  }
7165
- if (command30.gitBranch) {
7166
- queryParams.append("gitBranch", command30.gitBranch);
7196
+ if (command31.gitBranch) {
7197
+ queryParams.append("gitBranch", command31.gitBranch);
7167
7198
  }
7168
- if (command30.relativePath) {
7169
- queryParams.append("relativePath", command30.relativePath);
7199
+ if (command31.relativePath) {
7200
+ queryParams.append("relativePath", command31.relativePath);
7170
7201
  }
7171
- if (command30.agents !== void 0) {
7202
+ if (command31.agents !== void 0) {
7172
7203
  queryParams.append("agentsConfigOverride", "true");
7173
- command30.agents.forEach((agent) => {
7204
+ command31.agents.forEach((agent) => {
7174
7205
  queryParams.append("agent", agent);
7175
7206
  });
7176
7207
  }
@@ -7178,101 +7209,101 @@ var DeploymentGateway = class {
7178
7209
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
7179
7210
  );
7180
7211
  };
7181
- this.install = async (command30) => {
7212
+ this.install = async (command31) => {
7182
7213
  const { organizationId } = this.httpClient.getAuthContext();
7183
7214
  return this.httpClient.request(
7184
7215
  `/api/v0/organizations/${organizationId}/install`,
7185
7216
  {
7186
7217
  method: "POST",
7187
7218
  body: {
7188
- packagesSlugs: command30.packagesSlugs,
7189
- packmindLockFile: command30.packmindLockFile,
7190
- ...command30.relativePath && { relativePath: command30.relativePath },
7191
- ...command30.agents !== void 0 && { agents: command30.agents }
7219
+ packagesSlugs: command31.packagesSlugs,
7220
+ packmindLockFile: command31.packmindLockFile,
7221
+ ...command31.relativePath && { relativePath: command31.relativePath },
7222
+ ...command31.agents !== void 0 && { agents: command31.agents }
7192
7223
  }
7193
7224
  }
7194
7225
  );
7195
7226
  };
7196
- this.getDeployed = async (command30) => {
7227
+ this.getDeployed = async (command31) => {
7197
7228
  const { organizationId } = this.httpClient.getAuthContext();
7198
7229
  return this.httpClient.request(
7199
7230
  `/api/v0/organizations/${organizationId}/deployed-content`,
7200
7231
  {
7201
7232
  method: "POST",
7202
7233
  body: {
7203
- packagesSlugs: command30.packagesSlugs,
7204
- gitRemoteUrl: command30.gitRemoteUrl,
7205
- gitBranch: command30.gitBranch,
7206
- relativePath: command30.relativePath,
7207
- ...command30.agents !== void 0 && { agents: command30.agents }
7234
+ packagesSlugs: command31.packagesSlugs,
7235
+ gitRemoteUrl: command31.gitRemoteUrl,
7236
+ gitBranch: command31.gitBranch,
7237
+ relativePath: command31.relativePath,
7238
+ ...command31.agents !== void 0 && { agents: command31.agents }
7208
7239
  }
7209
7240
  }
7210
7241
  );
7211
7242
  };
7212
- this.getContentByVersions = async (command30) => {
7243
+ this.getContentByVersions = async (command31) => {
7213
7244
  const { organizationId } = this.httpClient.getAuthContext();
7214
7245
  return this.httpClient.request(
7215
7246
  `/api/v0/organizations/${organizationId}/content-by-versions`,
7216
7247
  {
7217
7248
  method: "POST",
7218
7249
  body: {
7219
- artifacts: command30.artifacts,
7220
- ...command30.agents !== void 0 && { agents: command30.agents }
7250
+ artifacts: command31.artifacts,
7251
+ ...command31.agents !== void 0 && { agents: command31.agents }
7221
7252
  }
7222
7253
  }
7223
7254
  );
7224
7255
  };
7225
- this.notifyDistribution = async (command30) => {
7256
+ this.notifyDistribution = async (command31) => {
7226
7257
  const { organizationId } = this.httpClient.getAuthContext();
7227
7258
  return this.httpClient.request(
7228
7259
  `/api/v0/organizations/${organizationId}/deployments`,
7229
7260
  {
7230
7261
  method: "POST",
7231
- body: command30
7262
+ body: command31
7232
7263
  }
7233
7264
  );
7234
7265
  };
7235
- this.notifyArtefactsDistribution = async (command30) => {
7266
+ this.notifyArtefactsDistribution = async (command31) => {
7236
7267
  const { organizationId } = this.httpClient.getAuthContext();
7237
7268
  return this.httpClient.request(
7238
7269
  `/api/v0/organizations/${organizationId}/deployments/notify-artifacts-distribution`,
7239
7270
  {
7240
7271
  method: "POST",
7241
7272
  body: {
7242
- gitRemoteUrl: command30.gitRemoteUrl,
7243
- gitBranch: command30.gitBranch,
7244
- relativePath: command30.relativePath,
7245
- packmindLockFile: command30.packmindLockFile
7273
+ gitRemoteUrl: command31.gitRemoteUrl,
7274
+ gitBranch: command31.gitBranch,
7275
+ relativePath: command31.relativePath,
7276
+ packmindLockFile: command31.packmindLockFile
7246
7277
  }
7247
7278
  }
7248
7279
  );
7249
7280
  };
7250
- this.renderPlugin = async (command30) => {
7281
+ this.renderPlugin = async (command31) => {
7251
7282
  const { organizationId } = this.httpClient.getAuthContext();
7252
7283
  return this.httpClient.request(
7253
7284
  `/api/v0/organizations/${organizationId}/plugins/render`,
7254
7285
  {
7255
7286
  method: "POST",
7256
7287
  body: {
7257
- packageSlug: command30.packageSlug,
7258
- mode: command30.mode,
7259
- pluginRoot: command30.pluginRoot,
7260
- pluginName: command30.pluginName,
7261
- gitRemoteUrl: command30.gitRemoteUrl,
7262
- gitBranch: command30.gitBranch
7288
+ packageSlug: command31.packageSlug,
7289
+ mode: command31.mode,
7290
+ pluginRoot: command31.pluginRoot,
7291
+ pluginName: command31.pluginName,
7292
+ gitRemoteUrl: command31.gitRemoteUrl,
7293
+ gitBranch: command31.gitBranch
7263
7294
  }
7264
7295
  }
7265
7296
  );
7266
7297
  };
7267
- this.trackPluginDeleted = async (command30) => {
7298
+ this.trackPluginDeleted = async (command31) => {
7268
7299
  const { organizationId } = this.httpClient.getAuthContext();
7269
7300
  return this.httpClient.request(
7270
7301
  `/api/v0/organizations/${organizationId}/plugins/track-deleted`,
7271
7302
  {
7272
7303
  method: "POST",
7273
7304
  body: {
7274
- packageSlug: command30.packageSlug,
7275
- gitRemoteUrl: command30.gitRemoteUrl
7305
+ packageSlug: command31.packageSlug,
7306
+ gitRemoteUrl: command31.gitRemoteUrl
7276
7307
  }
7277
7308
  }
7278
7309
  );
@@ -7284,13 +7315,13 @@ var DeploymentGateway = class {
7284
7315
  );
7285
7316
  };
7286
7317
  }
7287
- async updateRenderModeConfiguration(command30) {
7318
+ async updateRenderModeConfiguration(command31) {
7288
7319
  const { organizationId } = this.httpClient.getAuthContext();
7289
7320
  await this.httpClient.request(
7290
7321
  `/api/v0/organizations/${organizationId}/deployments/renderModeConfiguration`,
7291
7322
  {
7292
7323
  method: "POST",
7293
- body: { activeRenderModes: command30.activeRenderModes }
7324
+ body: { activeRenderModes: command31.activeRenderModes }
7294
7325
  }
7295
7326
  );
7296
7327
  }
@@ -7298,7 +7329,7 @@ var DeploymentGateway = class {
7298
7329
  const { organizationId } = this.httpClient.getAuthContext();
7299
7330
  const typeToPath = {
7300
7331
  standard: "standards",
7301
- command: "recipes",
7332
+ command: "commands",
7302
7333
  skill: "skills"
7303
7334
  };
7304
7335
  const pathSegment = typeToPath[type];
@@ -7333,6 +7364,37 @@ var OrganizationGateway = class {
7333
7364
  }
7334
7365
  };
7335
7366
 
7367
+ // apps/cli/src/infra/repositories/RepositoryTrackingGateway.ts
7368
+ var RepositoryTrackingGateway = class {
7369
+ constructor(httpClient) {
7370
+ this.httpClient = httpClient;
7371
+ this.getTrackedRepository = async ({
7372
+ owner,
7373
+ repo
7374
+ }) => {
7375
+ const { organizationId } = this.httpClient.getAuthContext();
7376
+ const query = new URLSearchParams({ owner, repo }).toString();
7377
+ return this.httpClient.request(
7378
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository?${query}`
7379
+ );
7380
+ };
7381
+ this.setTrackedRepository = async (command31) => {
7382
+ const { organizationId } = this.httpClient.getAuthContext();
7383
+ return this.httpClient.request(
7384
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7385
+ { method: "POST", body: command31 }
7386
+ );
7387
+ };
7388
+ this.updateTrackedBranch = async (command31) => {
7389
+ const { organizationId } = this.httpClient.getAuthContext();
7390
+ return this.httpClient.request(
7391
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7392
+ { method: "PUT", body: command31 }
7393
+ );
7394
+ };
7395
+ }
7396
+ };
7397
+
7336
7398
  // apps/cli/src/infra/repositories/PackmindGateway.ts
7337
7399
  var PackmindGateway = class {
7338
7400
  constructor(apiKey) {
@@ -7347,6 +7409,7 @@ var PackmindGateway = class {
7347
7409
  this.packages = new PackagesGateway(apiKey, this.httpClient);
7348
7410
  this.deployment = new DeploymentGateway(this.httpClient);
7349
7411
  this.organization = new OrganizationGateway(this.httpClient);
7412
+ this.repositoryTracking = new RepositoryTrackingGateway(this.httpClient);
7350
7413
  }
7351
7414
  };
7352
7415
 
@@ -9090,8 +9153,8 @@ var ExecuteLinterProgramsUseCase = class {
9090
9153
  this.linterAstAdapter = linterAstAdapter;
9091
9154
  this.logger = logger2;
9092
9155
  }
9093
- async execute(command30) {
9094
- const { filePath, fileContent, language, programs } = command30;
9156
+ async execute(command31) {
9157
+ const { filePath, fileContent, language, programs } = command31;
9095
9158
  if (programs.length === 0) {
9096
9159
  return {
9097
9160
  file: filePath,
@@ -9687,6 +9750,21 @@ var Cache = class _Cache {
9687
9750
  }
9688
9751
  };
9689
9752
 
9753
+ // packages/feature-flags/src/registry.ts
9754
+ var ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY = "change-proposals-in-webapp";
9755
+ var ORGA_SPACE_MANAGEMENT_FEATURE_KEY = "orga-space-management";
9756
+ var GOVERNANCE_FEATURE_KEY = "governance";
9757
+ var CLI_REPO_TRACKING_FEATURE_KEY = "cli-repo-tracking";
9758
+ var DEFAULT_FEATURE_DOMAIN_MAP = {
9759
+ [ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY]: [
9760
+ "@packmind.com",
9761
+ "@promyze.com"
9762
+ ],
9763
+ [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"],
9764
+ [GOVERNANCE_FEATURE_KEY]: ["joan.racenet@packmind.com"],
9765
+ [CLI_REPO_TRACKING_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9766
+ };
9767
+
9690
9768
  // packages/node-utils/src/database/schemas.ts
9691
9769
  var uuidSchema = {
9692
9770
  id: {
@@ -9741,6 +9819,11 @@ var import_common2 = require("@nestjs/common");
9741
9819
  // packages/node-utils/src/sse/RedisSSEClient.ts
9742
9820
  var import_ioredis2 = __toESM(require("ioredis"));
9743
9821
 
9822
+ // packages/node-utils/src/text/normalizeLineEndings.ts
9823
+ function normalizeLineEndings(content) {
9824
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
9825
+ }
9826
+
9744
9827
  // packages/node-utils/src/text/sectionMerge.ts
9745
9828
  function mergeSectionsIntoFileContent(existingContent, sections) {
9746
9829
  let result = existingContent;
@@ -9910,8 +9993,8 @@ var InstallPackagesUseCase = class {
9910
9993
  constructor(packmindGateway) {
9911
9994
  this.packmindGateway = packmindGateway;
9912
9995
  }
9913
- async execute(command30) {
9914
- const baseDirectory = command30.baseDirectory || process.cwd();
9996
+ async execute(command31) {
9997
+ const baseDirectory = command31.baseDirectory || process.cwd();
9915
9998
  const result = {
9916
9999
  filesCreated: 0,
9917
10000
  filesUpdated: 0,
@@ -9923,12 +10006,12 @@ var InstallPackagesUseCase = class {
9923
10006
  skillDirectoriesDeleted: 0
9924
10007
  };
9925
10008
  const response = await this.packmindGateway.deployment.pull({
9926
- packagesSlugs: command30.packagesSlugs,
9927
- previousPackagesSlugs: command30.previousPackagesSlugs,
9928
- gitRemoteUrl: command30.gitRemoteUrl,
9929
- gitBranch: command30.gitBranch,
9930
- relativePath: command30.relativePath,
9931
- agents: command30.agents
10009
+ packagesSlugs: command31.packagesSlugs,
10010
+ previousPackagesSlugs: command31.previousPackagesSlugs,
10011
+ gitRemoteUrl: command31.gitRemoteUrl,
10012
+ gitBranch: command31.gitBranch,
10013
+ relativePath: command31.relativePath,
10014
+ agents: command31.agents
9932
10015
  });
9933
10016
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
9934
10017
  (file) => file.path !== "packmind.json"
@@ -10303,8 +10386,8 @@ var InstallUseCase = class {
10303
10386
  this.configFileRepository = configFileRepository;
10304
10387
  this.spaceService = spaceService;
10305
10388
  }
10306
- async execute(command30) {
10307
- const baseDirectory = command30.baseDirectory || process.cwd();
10389
+ async execute(command31) {
10390
+ const baseDirectory = command31.baseDirectory || process.cwd();
10308
10391
  const result = {
10309
10392
  filesCreated: 0,
10310
10393
  filesUpdated: 0,
@@ -10334,7 +10417,7 @@ var InstallUseCase = class {
10334
10417
  },
10335
10418
  resolvedAgents: []
10336
10419
  };
10337
- const hasExplicitPackages = command30.packages && command30.packages.length > 0;
10420
+ const hasExplicitPackages = command31.packages && command31.packages.length > 0;
10338
10421
  const configExistedBefore = await this.configFileRepository.configExists(baseDirectory);
10339
10422
  const lockFile = await this.lockFileRepository.read(baseDirectory);
10340
10423
  const config = await this.configFileRepository.readConfig(baseDirectory);
@@ -10354,14 +10437,13 @@ var InstallUseCase = class {
10354
10437
  lockfileVersion: 1,
10355
10438
  packageSlugs: [],
10356
10439
  agents: [],
10357
- artifacts: {},
10358
- ...command30.skipInstalledAt ? {} : { installedAt: (/* @__PURE__ */ new Date()).toISOString() }
10440
+ artifacts: {}
10359
10441
  };
10360
- effectiveLockFile.cliVersion = command30.cliVersion;
10442
+ effectiveLockFile.cliVersion = command31.cliVersion;
10361
10443
  let packagesSlugs;
10362
10444
  let normalizedPackages = [];
10363
10445
  if (hasExplicitPackages) {
10364
- const explicitPackageSlugs = (command30.packages ?? []).map(
10446
+ const explicitPackageSlugs = (command31.packages ?? []).map(
10365
10447
  displayableParsedPackageSlug
10366
10448
  );
10367
10449
  normalizedPackages = await this.normalizePackageSlugs(explicitPackageSlugs);
@@ -10391,8 +10473,8 @@ var InstallUseCase = class {
10391
10473
  }
10392
10474
  return result;
10393
10475
  }
10394
- const installAgents = this.resolveInstallAgents(command30, config);
10395
- const stripPathPrefix = command30.homeAgent ? getAgentHomeDirPrefix(command30.homeAgent) ?? void 0 : void 0;
10476
+ const installAgents = this.resolveInstallAgents(command31, config);
10477
+ const stripPathPrefix = command31.homeAgent ? getAgentHomeDirPrefix(command31.homeAgent) ?? void 0 : void 0;
10396
10478
  const response = await this.packmindGateway.deployment.install({
10397
10479
  packagesSlugs,
10398
10480
  packmindLockFile: effectiveLockFile,
@@ -10532,10 +10614,7 @@ var InstallUseCase = class {
10532
10614
  } catch {
10533
10615
  }
10534
10616
  }
10535
- if (command30.skipInstalledAt) {
10536
- delete lockFileToPersist.installedAt;
10537
- }
10538
- lockFileToPersist.cliVersion = command30.cliVersion;
10617
+ lockFileToPersist.cliVersion = command31.cliVersion;
10539
10618
  if (stripPathPrefix) {
10540
10619
  lockFileToPersist = this.stripLockFileArtifactPaths(
10541
10620
  lockFileToPersist,
@@ -10564,9 +10643,9 @@ var InstallUseCase = class {
10564
10643
  async normalizePackageSlugs(slugs) {
10565
10644
  return normalizePackageSlugs(slugs, this.spaceService);
10566
10645
  }
10567
- resolveInstallAgents(command30, config) {
10568
- if (command30.homeAgent) {
10569
- return [command30.homeAgent];
10646
+ resolveInstallAgents(command31, config) {
10647
+ if (command31.homeAgent) {
10648
+ return [command31.homeAgent];
10570
10649
  }
10571
10650
  return config?.agents;
10572
10651
  }
@@ -10880,8 +10959,8 @@ var UninstallUseCase = class {
10880
10959
  this.spaceService = spaceService;
10881
10960
  this.installUseCase = installUseCase;
10882
10961
  }
10883
- async execute(command30) {
10884
- const baseDirectory = command30.baseDirectory || process.cwd();
10962
+ async execute(command31) {
10963
+ const baseDirectory = command31.baseDirectory || process.cwd();
10885
10964
  const config = await this.configFileRepository.readConfig(baseDirectory);
10886
10965
  if (!config) {
10887
10966
  const configFileExists = await this.configFileRepository.configExists(baseDirectory);
@@ -10895,7 +10974,7 @@ var UninstallUseCase = class {
10895
10974
  );
10896
10975
  }
10897
10976
  const normalized = await normalizePackageSlugs(
10898
- command30.packages,
10977
+ command31.packages,
10899
10978
  this.spaceService
10900
10979
  );
10901
10980
  const notInstalled = normalized.filter((pkg) => !(pkg in config.packages));
@@ -10918,7 +10997,7 @@ ${pkgList}`
10918
10997
  try {
10919
10998
  return await this.installUseCase.execute({
10920
10999
  baseDirectory,
10921
- cliVersion: command30.cliVersion
11000
+ cliVersion: command31.cliVersion
10922
11001
  });
10923
11002
  } catch (error) {
10924
11003
  await this.configFileRepository.updateConfig(
@@ -10960,8 +11039,8 @@ var InstallDefaultSkillsUseCase = class {
10960
11039
  constructor(repositories) {
10961
11040
  this.repositories = repositories;
10962
11041
  }
10963
- async execute(command30) {
10964
- const baseDirectory = command30.baseDirectory || process.cwd();
11042
+ async execute(command31) {
11043
+ const baseDirectory = command31.baseDirectory || process.cwd();
10965
11044
  await this.bootstrapEmptyDirectory(baseDirectory);
10966
11045
  const result = {
10967
11046
  filesCreated: 0,
@@ -10971,24 +11050,24 @@ var InstallDefaultSkillsUseCase = class {
10971
11050
  skippedIncompatibleSkillNames: [],
10972
11051
  incompatibleInstalledSkills: []
10973
11052
  };
10974
- let agents = command30.agents;
11053
+ let agents = command31.agents;
10975
11054
  if (!agents || agents.length === 0) {
10976
11055
  const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
10977
11056
  agents = config?.agents;
10978
11057
  }
10979
11058
  const response = await this.repositories.packmindGateway.skills.getDefaults(
10980
11059
  {
10981
- cliVersion: command30.cliVersion,
10982
- includeBeta: command30.includeBeta,
11060
+ cliVersion: command31.cliVersion,
11061
+ includeBeta: command31.includeBeta,
10983
11062
  agents
10984
11063
  }
10985
11064
  );
10986
11065
  result.skippedSkillsCount = response.skippedSkillsCount;
10987
11066
  const incompatibleInstalledMap = /* @__PURE__ */ new Map();
10988
11067
  const incompatibleSkillDirs = /* @__PURE__ */ new Map();
10989
- if (command30.cliVersion) {
11068
+ if (command31.cliVersion) {
10990
11069
  for (const file of response.fileUpdates.createOrUpdate) {
10991
- if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command30.cliVersion)) {
11070
+ if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command31.cliVersion)) {
10992
11071
  const dir = path9.dirname(file.path);
10993
11072
  const skillName = this.getSkillName(file.content) ?? path9.basename(dir);
10994
11073
  incompatibleSkillDirs.set(dir, skillName);
@@ -10999,9 +11078,9 @@ var InstallDefaultSkillsUseCase = class {
10999
11078
  for (const file of response.fileUpdates.createOrUpdate) {
11000
11079
  try {
11001
11080
  if (!file.content) continue;
11002
- const isIncompatible = command30.cliVersion && (this.isVersionConstraintViolated(
11081
+ const isIncompatible = command31.cliVersion && (this.isVersionConstraintViolated(
11003
11082
  file.content,
11004
- command30.cliVersion
11083
+ command31.cliVersion
11005
11084
  ) || this.isUnderIncompatibleSkillDir(
11006
11085
  file.path,
11007
11086
  incompatibleSkillDirs
@@ -11044,7 +11123,7 @@ var InstallDefaultSkillsUseCase = class {
11044
11123
  await this.mergeLockFileSlice(
11045
11124
  baseDirectory,
11046
11125
  response.lockFileSlice ?? {},
11047
- command30.cliVersion
11126
+ command31.cliVersion
11048
11127
  );
11049
11128
  return result;
11050
11129
  }
@@ -11198,8 +11277,8 @@ var EnsureCliVersionUseCase = class {
11198
11277
  this.lockFileRepository = lockFileRepository;
11199
11278
  this.installDefaultSkillsUseCase = installDefaultSkillsUseCase;
11200
11279
  }
11201
- async execute(command30) {
11202
- const { baseDirectory, currentCliVersion, includeBeta } = command30;
11280
+ async execute(command31) {
11281
+ const { baseDirectory, currentCliVersion, includeBeta } = command31;
11203
11282
  const lockFile = await this.lockFileRepository.read(baseDirectory);
11204
11283
  if (!lockFile) {
11205
11284
  return { kind: "no-lockfile" };
@@ -11235,10 +11314,10 @@ var ListPackagesUseCase = class {
11235
11314
  this.packmindGateway = packmindGateway;
11236
11315
  this.spaceService = spaceService;
11237
11316
  }
11238
- async execute(command30) {
11239
- if (command30.spaceId) {
11317
+ async execute(command31) {
11318
+ if (command31.spaceId) {
11240
11319
  const response = await this.packmindGateway.packages.list({
11241
- spaceId: command30.spaceId
11320
+ spaceId: command31.spaceId
11242
11321
  });
11243
11322
  return response.packages;
11244
11323
  }
@@ -11257,8 +11336,8 @@ var GetPackageSummaryUseCase = class {
11257
11336
  constructor(gateway) {
11258
11337
  this.gateway = gateway;
11259
11338
  }
11260
- async execute(command30) {
11261
- return this.gateway.packages.getSummary(command30);
11339
+ async execute(command31) {
11340
+ return this.gateway.packages.getSummary(command31);
11262
11341
  }
11263
11342
  };
11264
11343
 
@@ -11288,10 +11367,7 @@ function decodeApiKey(apiKey) {
11288
11367
  }
11289
11368
 
11290
11369
  // apps/cli/src/infra/utils/credentials/EnvCredentialsProvider.ts
11291
- var ENV_VAR_NAMES = [
11292
- "PACKMIND_API_KEY",
11293
- "PACKMIND_API_KEY_V3"
11294
- ];
11370
+ var ENV_VAR_NAMES = ["PACKMIND_API_KEY"];
11295
11371
  var EnvCredentialsProvider = class {
11296
11372
  getSourceName() {
11297
11373
  const name = this.findActiveEnvVarName() ?? ENV_VAR_NAMES[0];
@@ -11553,8 +11629,8 @@ var LoginUseCase = class {
11553
11629
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
11554
11630
  };
11555
11631
  }
11556
- async execute(command30) {
11557
- const { host, code: providedCode } = command30;
11632
+ async execute(command31) {
11633
+ const { host, code: providedCode } = command31;
11558
11634
  let code;
11559
11635
  if (providedCode) {
11560
11636
  code = providedCode;
@@ -11936,10 +12012,10 @@ var CheckCliVersionUseCase = class {
11936
12012
  now: deps?.now ?? (() => /* @__PURE__ */ new Date())
11937
12013
  };
11938
12014
  }
11939
- async execute(command30) {
11940
- const cached = this.readFreshCache(command30.currentVersion);
12015
+ async execute(command31) {
12016
+ const cached = this.readFreshCache(command31.currentVersion);
11941
12017
  if (cached) {
11942
- return this.toResult(command30.currentVersion, cached.latestVersion);
12018
+ return this.toResult(command31.currentVersion, cached.latestVersion);
11943
12019
  }
11944
12020
  const fetchPromise = this.deps.fetchLatestVersion(this.deps.fetchFn);
11945
12021
  fetchPromise.catch(() => void 0);
@@ -11957,7 +12033,7 @@ var CheckCliVersionUseCase = class {
11957
12033
  latestVersion,
11958
12034
  checkedAt: this.deps.now()
11959
12035
  });
11960
- return this.toResult(command30.currentVersion, latestVersion);
12036
+ return this.toResult(command31.currentVersion, latestVersion);
11961
12037
  } catch {
11962
12038
  return null;
11963
12039
  }
@@ -12405,10 +12481,10 @@ var ListStandardsUseCase = class {
12405
12481
  this.packmindGateway = packmindGateway;
12406
12482
  this.spaceService = spaceService;
12407
12483
  }
12408
- async execute(command30) {
12409
- if (command30.spaceId) {
12484
+ async execute(command31) {
12485
+ if (command31.spaceId) {
12410
12486
  const response = await this.packmindGateway.standards.list({
12411
- spaceId: command30.spaceId
12487
+ spaceId: command31.spaceId
12412
12488
  });
12413
12489
  return response.standards;
12414
12490
  }
@@ -12428,10 +12504,10 @@ var ListCommandsUseCase = class {
12428
12504
  this.packmindGateway = packmindGateway;
12429
12505
  this.spaceService = spaceService;
12430
12506
  }
12431
- async execute(command30) {
12432
- if (command30.spaceId) {
12507
+ async execute(command31) {
12508
+ if (command31.spaceId) {
12433
12509
  const response = await this.packmindGateway.commands.list({
12434
- spaceId: command30.spaceId
12510
+ spaceId: command31.spaceId
12435
12511
  });
12436
12512
  return response.recipes;
12437
12513
  }
@@ -12451,10 +12527,10 @@ var ListSkillsUseCase = class {
12451
12527
  this.packmindGateway = packmindGateway;
12452
12528
  this.spaceService = spaceService;
12453
12529
  }
12454
- async execute(command30) {
12455
- if (command30.spaceId) {
12530
+ async execute(command31) {
12531
+ if (command31.spaceId) {
12456
12532
  const skills = await this.packmindGateway.skills.list({
12457
- spaceId: command30.spaceId
12533
+ spaceId: command31.spaceId
12458
12534
  });
12459
12535
  return skills.map((s) => ({
12460
12536
  id: s.id,
@@ -12487,11 +12563,6 @@ var import_promises2 = __toESM(require("fs/promises"));
12487
12563
  var import_path3 = __toESM(require("path"));
12488
12564
  var import_minimatch2 = require("minimatch");
12489
12565
 
12490
- // apps/cli/src/application/utils/normalizeLineEndings.ts
12491
- function normalizeLineEndings(content) {
12492
- return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
12493
- }
12494
-
12495
12566
  // apps/cli/src/infra/utils/binaryDetection.ts
12496
12567
  var path15 = __toESM(require("path"));
12497
12568
  var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -12631,8 +12702,8 @@ var UploadSkillUseCase = class {
12631
12702
  constructor(deps) {
12632
12703
  this.deps = deps;
12633
12704
  }
12634
- async execute(command30) {
12635
- const files = await readSkillDirectory(command30.skillPath);
12705
+ async execute(command31) {
12706
+ const files = await readSkillDirectory(command31.skillPath);
12636
12707
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
12637
12708
  throw new Error("SKILL.md not found in skill directory");
12638
12709
  }
@@ -12646,7 +12717,7 @@ var UploadSkillUseCase = class {
12646
12717
  if (totalSize > 10 * 1024 * 1024) {
12647
12718
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
12648
12719
  }
12649
- const space = await this.getSpace(command30.spaceSlug);
12720
+ const space = await this.getSpace(command31.spaceSlug);
12650
12721
  const payload = {
12651
12722
  files: files.map((f) => ({
12652
12723
  path: f.relativePath,
@@ -12658,7 +12729,7 @@ var UploadSkillUseCase = class {
12658
12729
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
12659
12730
  spaceId: createSpaceId(space.id),
12660
12731
  files: payload.files,
12661
- originSkill: command30.originSkill
12732
+ originSkill: command31.originSkill
12662
12733
  });
12663
12734
  return {
12664
12735
  skillId: uploadSkillResponse.skill.id,
@@ -13648,9 +13719,9 @@ var DiffArtefactsUseCase = class {
13648
13719
  new StandardDiffStrategy()
13649
13720
  ];
13650
13721
  }
13651
- async execute(command30) {
13652
- const baseDirectory = command30.baseDirectory || process.cwd();
13653
- const response = await this.fetchContent(command30, baseDirectory);
13722
+ async execute(command31) {
13723
+ const baseDirectory = command31.baseDirectory || process.cwd();
13724
+ const response = await this.fetchContent(command31, baseDirectory);
13654
13725
  const filteredFiles = response.fileUpdates.createOrUpdate.filter(
13655
13726
  (file) => file.path !== "packmind.json"
13656
13727
  );
@@ -13663,7 +13734,7 @@ var DiffArtefactsUseCase = class {
13663
13734
  );
13664
13735
  const prefixedSkillFolders = this.prefixSkillFolders(
13665
13736
  response.skillFolders,
13666
- command30.relativePath
13737
+ command31.relativePath
13667
13738
  );
13668
13739
  const diffs = [];
13669
13740
  for (const file of diffableFiles) {
@@ -13690,7 +13761,7 @@ var DiffArtefactsUseCase = class {
13690
13761
  targetId: response.targetId ? createTargetId(response.targetId) : void 0
13691
13762
  }));
13692
13763
  }
13693
- async fetchContent(command30, baseDirectory) {
13764
+ async fetchContent(command31, baseDirectory) {
13694
13765
  const lockFile = await this.lockFileRepository.read(baseDirectory);
13695
13766
  if (lockFile) {
13696
13767
  try {
@@ -13710,11 +13781,11 @@ var DiffArtefactsUseCase = class {
13710
13781
  }
13711
13782
  }
13712
13783
  return this.packmindGateway.deployment.getDeployed({
13713
- packagesSlugs: command30.packagesSlugs,
13714
- gitRemoteUrl: command30.gitRemoteUrl,
13715
- gitBranch: command30.gitBranch,
13716
- relativePath: command30.relativePath,
13717
- agents: command30.agents
13784
+ packagesSlugs: command31.packagesSlugs,
13785
+ gitRemoteUrl: command31.gitRemoteUrl,
13786
+ gitBranch: command31.gitBranch,
13787
+ relativePath: command31.relativePath,
13788
+ agents: command31.agents
13718
13789
  });
13719
13790
  }
13720
13791
  prefixSkillFolders(skillFolders, relativePath) {
@@ -13738,8 +13809,8 @@ var SubmitDiffsUseCase = class {
13738
13809
  constructor(packmindGateway) {
13739
13810
  this.packmindGateway = packmindGateway;
13740
13811
  }
13741
- async execute(command30) {
13742
- const { groupedDiffs, message } = command30;
13812
+ async execute(command31) {
13813
+ const { groupedDiffs, message } = command31;
13743
13814
  const skipped = [];
13744
13815
  const validDiffs = [];
13745
13816
  for (const group of groupedDiffs) {
@@ -13814,8 +13885,8 @@ var CheckDiffsUseCase = class {
13814
13885
  constructor(packmindGateway) {
13815
13886
  this.packmindGateway = packmindGateway;
13816
13887
  }
13817
- async execute(command30) {
13818
- const { groupedDiffs } = command30;
13888
+ async execute(command31) {
13889
+ const { groupedDiffs } = command31;
13819
13890
  const results = [];
13820
13891
  const validDiffs = [];
13821
13892
  const invalidDiffs = [];
@@ -13913,8 +13984,8 @@ var CliFormatter = class {
13913
13984
  static error(message) {
13914
13985
  return `${source_default.bgRed.bold(CLI_PREFIX2)} ${source_default.red(message)}`;
13915
13986
  }
13916
- static command(command30) {
13917
- return source_default.yellow(command30);
13987
+ static command(command31) {
13988
+ return source_default.yellow(command31);
13918
13989
  }
13919
13990
  static loader(text) {
13920
13991
  return source_default.dim.italic(text);
@@ -14033,6 +14104,101 @@ var CliOutput = class {
14033
14104
  }
14034
14105
  };
14035
14106
 
14107
+ // apps/cli/src/application/useCases/trackRepository/TrackRepositoryUseCase.ts
14108
+ function parseOwnerRepo(gitRemoteUrl) {
14109
+ const match = gitRemoteUrl.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/i);
14110
+ if (!match) {
14111
+ throw new Error(`Unable to parse git remote URL: ${gitRemoteUrl}`);
14112
+ }
14113
+ return {
14114
+ owner: match[1],
14115
+ repo: match[2].replace(/\.git$/, "")
14116
+ };
14117
+ }
14118
+ function parseProviderVendor(gitRemoteUrl) {
14119
+ const normalized = gitRemoteUrl.toLowerCase();
14120
+ if (normalized.includes("github.com")) {
14121
+ return "github";
14122
+ }
14123
+ if (normalized.includes("gitlab.com")) {
14124
+ return "gitlab";
14125
+ }
14126
+ return "unknown";
14127
+ }
14128
+ var TrackRepositoryUseCase = class {
14129
+ constructor(gateway, gitService) {
14130
+ this.gateway = gateway;
14131
+ this.gitService = gitService;
14132
+ }
14133
+ async execute(command31) {
14134
+ const { repoPath, origin: origin9, update, confirm } = command31;
14135
+ const { gitRemoteUrl } = this.gitService.getGitRemoteUrl(repoPath);
14136
+ const { branch } = this.gitService.getCurrentBranch(repoPath);
14137
+ const { owner, repo } = parseOwnerRepo(gitRemoteUrl);
14138
+ const providerVendor = parseProviderVendor(gitRemoteUrl);
14139
+ const { gitRepo: tracked } = await this.gateway.getTrackedRepository({
14140
+ owner,
14141
+ repo
14142
+ });
14143
+ if (update) {
14144
+ if (!tracked) {
14145
+ return { status: "nothing-tracked", owner, repo, branch };
14146
+ }
14147
+ if (tracked.branch === branch) {
14148
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14149
+ }
14150
+ const confirmed2 = await confirm({
14151
+ mode: "update",
14152
+ owner,
14153
+ repo,
14154
+ branch,
14155
+ fromBranch: tracked.branch
14156
+ });
14157
+ if (!confirmed2) {
14158
+ return { status: "cancelled" };
14159
+ }
14160
+ const gitRepo2 = await this.gateway.updateTrackedBranch({
14161
+ owner,
14162
+ repo,
14163
+ branch
14164
+ });
14165
+ return {
14166
+ status: "updated",
14167
+ owner,
14168
+ repo,
14169
+ branch,
14170
+ fromBranch: tracked.branch,
14171
+ gitRepo: gitRepo2
14172
+ };
14173
+ }
14174
+ if (tracked) {
14175
+ if (tracked.branch === branch) {
14176
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14177
+ }
14178
+ return {
14179
+ status: "already-tracked-other-branch",
14180
+ owner,
14181
+ repo,
14182
+ branch,
14183
+ trackedBranch: tracked.branch
14184
+ };
14185
+ }
14186
+ const confirmed = await confirm({ mode: "set", owner, repo, branch });
14187
+ if (!confirmed) {
14188
+ return { status: "cancelled" };
14189
+ }
14190
+ const gitRepo = await this.gateway.setTrackedRepository({
14191
+ owner,
14192
+ repo,
14193
+ branch,
14194
+ origin: origin9,
14195
+ providerVendor,
14196
+ gitRemoteUrl
14197
+ });
14198
+ return { status: "set", owner, repo, branch, gitRepo };
14199
+ }
14200
+ };
14201
+
14036
14202
  // apps/cli/src/PackmindCliHexaFactory.ts
14037
14203
  var PackmindCliHexaFactory = class {
14038
14204
  constructor() {
@@ -14118,7 +14284,11 @@ var PackmindCliHexaFactory = class {
14118
14284
  this.repositories.lockFileRepository
14119
14285
  ),
14120
14286
  submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway),
14121
- checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway)
14287
+ checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway),
14288
+ trackRepository: new TrackRepositoryUseCase(
14289
+ this.repositories.packmindGateway.repositoryTracking,
14290
+ this.services.gitRemoteUrlService
14291
+ )
14122
14292
  };
14123
14293
  }
14124
14294
  };
@@ -14127,24 +14297,29 @@ var PackmindCliHexaFactory = class {
14127
14297
  var origin8 = "PackmindCliHexa";
14128
14298
  var PackmindCliHexa = class {
14129
14299
  constructor(logger2 = new PackmindLogger(origin8)) {
14130
- this.notifyDistribution = async (command30) => {
14300
+ this.notifyDistribution = async (command31) => {
14131
14301
  return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
14132
- command30
14302
+ command31
14133
14303
  );
14134
14304
  };
14135
- this.notifyArtefactsDistribution = async (command30) => {
14305
+ this.notifyArtefactsDistribution = async (command31) => {
14136
14306
  return this.hexa.repositories.packmindGateway.deployment.notifyArtefactsDistribution(
14137
- command30
14307
+ command31
14308
+ );
14309
+ };
14310
+ this.getTrackedRepository = async (command31) => {
14311
+ return this.hexa.repositories.packmindGateway.repositoryTracking.getTrackedRepository(
14312
+ command31
14138
14313
  );
14139
14314
  };
14140
- this.renderPlugin = async (command30) => {
14315
+ this.renderPlugin = async (command31) => {
14141
14316
  return this.hexa.repositories.packmindGateway.deployment.renderPlugin(
14142
- command30
14317
+ command31
14143
14318
  );
14144
14319
  };
14145
- this.trackPluginDeleted = async (command30) => {
14320
+ this.trackPluginDeleted = async (command31) => {
14146
14321
  return this.hexa.repositories.packmindGateway.deployment.trackPluginDeleted(
14147
- command30
14322
+ command31
14148
14323
  );
14149
14324
  };
14150
14325
  this.logger = logger2;
@@ -14167,29 +14342,29 @@ var PackmindCliHexa = class {
14167
14342
  get output() {
14168
14343
  return this.hexa.repositories.output;
14169
14344
  }
14170
- async getGitRemoteUrl(command30) {
14171
- return this.hexa.useCases.getGitRemoteUrl.execute(command30);
14345
+ async getGitRemoteUrl(command31) {
14346
+ return this.hexa.useCases.getGitRemoteUrl.execute(command31);
14172
14347
  }
14173
- async listFilesInDirectory(command30) {
14174
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command30);
14348
+ async listFilesInDirectory(command31) {
14349
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command31);
14175
14350
  }
14176
- async lintFilesAgainstRule(command30) {
14177
- return this.hexa.useCases.lintFilesAgainstRule.execute(command30);
14351
+ async lintFilesAgainstRule(command31) {
14352
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command31);
14178
14353
  }
14179
- async lintFilesFromConfig(command30) {
14180
- return this.hexa.useCases.lintFilesFromConfig.execute(command30);
14354
+ async lintFilesFromConfig(command31) {
14355
+ return this.hexa.useCases.lintFilesFromConfig.execute(command31);
14181
14356
  }
14182
- async installPackages(command30) {
14183
- return this.hexa.useCases.installPackages.execute(command30);
14357
+ async installPackages(command31) {
14358
+ return this.hexa.useCases.installPackages.execute(command31);
14184
14359
  }
14185
- async install(command30) {
14186
- return this.hexa.useCases.install.execute(command30);
14360
+ async install(command31) {
14361
+ return this.hexa.useCases.install.execute(command31);
14187
14362
  }
14188
- async uninstall(command30) {
14189
- return this.hexa.useCases.uninstall.execute(command30);
14363
+ async uninstall(command31) {
14364
+ return this.hexa.useCases.uninstall.execute(command31);
14190
14365
  }
14191
- async diffArtefacts(command30) {
14192
- return this.hexa.useCases.diffArtefacts.execute(command30);
14366
+ async diffArtefacts(command31) {
14367
+ return this.hexa.useCases.diffArtefacts.execute(command31);
14193
14368
  }
14194
14369
  async submitDiffs(groupedDiffs, message) {
14195
14370
  return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
@@ -14197,20 +14372,20 @@ var PackmindCliHexa = class {
14197
14372
  async checkDiffs(groupedDiffs) {
14198
14373
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
14199
14374
  }
14200
- async listPackages(command30) {
14201
- return this.hexa.useCases.listPackages.execute(command30);
14375
+ async listPackages(command31) {
14376
+ return this.hexa.useCases.listPackages.execute(command31);
14202
14377
  }
14203
- async getPackageBySlug(command30) {
14204
- return this.hexa.useCases.getPackageBySlug.execute(command30);
14378
+ async getPackageBySlug(command31) {
14379
+ return this.hexa.useCases.getPackageBySlug.execute(command31);
14205
14380
  }
14206
- async listStandards(command30) {
14207
- return this.hexa.useCases.listStandards.execute(command30);
14381
+ async listStandards(command31) {
14382
+ return this.hexa.useCases.listStandards.execute(command31);
14208
14383
  }
14209
- async listCommands(command30) {
14210
- return this.hexa.useCases.listCommands.execute(command30);
14384
+ async listCommands(command31) {
14385
+ return this.hexa.useCases.listCommands.execute(command31);
14211
14386
  }
14212
- async listSkills(command30) {
14213
- return this.hexa.useCases.listSkills.execute(command30);
14387
+ async listSkills(command31) {
14388
+ return this.hexa.useCases.listSkills.execute(command31);
14214
14389
  }
14215
14390
  async configExists(baseDirectory) {
14216
14391
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -14297,17 +14472,17 @@ var PackmindCliHexa = class {
14297
14472
  directory
14298
14473
  );
14299
14474
  }
14300
- async login(command30) {
14301
- return this.hexa.useCases.login.execute(command30);
14475
+ async login(command31) {
14476
+ return this.hexa.useCases.login.execute(command31);
14302
14477
  }
14303
- async logout(command30) {
14304
- return this.hexa.useCases.logout.execute(command30);
14478
+ async logout(command31) {
14479
+ return this.hexa.useCases.logout.execute(command31);
14305
14480
  }
14306
- async whoami(command30) {
14307
- return this.hexa.useCases.whoami.execute(command30);
14481
+ async whoami(command31) {
14482
+ return this.hexa.useCases.whoami.execute(command31);
14308
14483
  }
14309
- async checkCliVersion(command30) {
14310
- return this.hexa.useCases.checkCliVersion.execute(command30);
14484
+ async checkCliVersion(command31) {
14485
+ return this.hexa.useCases.checkCliVersion.execute(command31);
14311
14486
  }
14312
14487
  getCurrentBranch(repoPath) {
14313
14488
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -14315,19 +14490,22 @@ var PackmindCliHexa = class {
14315
14490
  getGitRemoteUrlFromPath(repoPath) {
14316
14491
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
14317
14492
  }
14318
- async uploadSkill(command30) {
14319
- return this.hexa.useCases.uploadSkill.execute(command30);
14493
+ async uploadSkill(command31) {
14494
+ return this.hexa.useCases.uploadSkill.execute(command31);
14320
14495
  }
14321
- async installDefaultSkills(command30) {
14322
- return this.hexa.useCases.installDefaultSkills.execute(command30);
14496
+ async installDefaultSkills(command31) {
14497
+ return this.hexa.useCases.installDefaultSkills.execute(command31);
14323
14498
  }
14324
- async bootstrapSkillsInitDirectory(command30) {
14499
+ async bootstrapSkillsInitDirectory(command31) {
14325
14500
  return this.hexa.useCases.installDefaultSkills.bootstrapEmptyDirectory(
14326
- command30.baseDirectory
14501
+ command31.baseDirectory
14327
14502
  );
14328
14503
  }
14329
- async ensureCliVersion(command30) {
14330
- return this.hexa.useCases.ensureCliVersion.execute(command30);
14504
+ async ensureCliVersion(command31) {
14505
+ return this.hexa.useCases.ensureCliVersion.execute(command31);
14506
+ }
14507
+ async trackRepository(command31) {
14508
+ return this.hexa.useCases.trackRepository.execute(command31);
14331
14509
  }
14332
14510
  getPackmindGateway() {
14333
14511
  return this.hexa.repositories.packmindGateway;
@@ -14728,7 +14906,7 @@ var lintCommand = (0, import_cmd_ts.command)({
14728
14906
  }),
14729
14907
  continueOnMissingKey: (0, import_cmd_ts.flag)({
14730
14908
  long: "continue-on-missing-key",
14731
- description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY_V3 is not set"
14909
+ description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY is not set"
14732
14910
  }),
14733
14911
  changedFiles: (0, import_cmd_ts.flag)({
14734
14912
  long: "changed-files",
@@ -15083,7 +15261,7 @@ var AgentArtifactDetectionService = class {
15083
15261
 
15084
15262
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15085
15263
  var readline3 = __toESM(require("readline"));
15086
- var inquirer2 = __toESM(require("inquirer"));
15264
+ var inquirer3 = __toESM(require("inquirer"));
15087
15265
 
15088
15266
  // apps/cli/src/infra/commands/config/configAgentsHandler.ts
15089
15267
  var readline2 = __toESM(require("readline"));
@@ -15356,6 +15534,35 @@ function buildSkillsSkippedWarning(configuredAgents) {
15356
15534
  return `Skipping default skills \u2014 your configured agents (${configuredAgents.join(", ")}) do not support skills. Run ${configHint} to add an agent supporting skills (e.g. claude).`;
15357
15535
  }
15358
15536
 
15537
+ // apps/cli/src/infra/commands/trackingPrompts.ts
15538
+ var inquirer2 = __toESM(require("inquirer"));
15539
+ function buildTrackConfirmationMessage(details) {
15540
+ if (details.mode === "update") {
15541
+ return `Change the tracked branch for ${details.owner}/${details.repo} from ${details.fromBranch} to ${details.branch}?`;
15542
+ }
15543
+ return `Track ${details.owner}/${details.repo} on branch ${details.branch}?`;
15544
+ }
15545
+ async function defaultConfirmPrompt(message) {
15546
+ const { confirmed } = await inquirer2.default.prompt([
15547
+ {
15548
+ type: "confirm",
15549
+ name: "confirmed",
15550
+ message,
15551
+ default: true
15552
+ }
15553
+ ]);
15554
+ return confirmed;
15555
+ }
15556
+ function createTrackConfirm(options) {
15557
+ const confirmPrompt = options.confirmPrompt ?? defaultConfirmPrompt;
15558
+ return async (details) => {
15559
+ if (!options.isTTY) {
15560
+ return true;
15561
+ }
15562
+ return confirmPrompt(buildTrackConfirmationMessage(details));
15563
+ };
15564
+ }
15565
+
15359
15566
  // apps/cli/src/infra/commands/initHandler.ts
15360
15567
  async function initHandler(deps) {
15361
15568
  const {
@@ -15367,8 +15574,11 @@ async function initHandler(deps) {
15367
15574
  ensureCliVersion,
15368
15575
  cliVersion,
15369
15576
  isTTY,
15370
- showOnboardHint = true
15577
+ showOnboardHint = true,
15578
+ trackRepository,
15579
+ confirmPrompt
15371
15580
  } = deps;
15581
+ const resolvedIsTTY = isTTY ?? Boolean(process.stdin.isTTY);
15372
15582
  if (ensureCliVersion) {
15373
15583
  try {
15374
15584
  const outcome = await ensureCliVersion({
@@ -15428,6 +15638,14 @@ async function initHandler(deps) {
15428
15638
  }
15429
15639
  }
15430
15640
  }
15641
+ if (resolvedIsTTY && trackRepository) {
15642
+ await offerRepositoryTracking({
15643
+ trackRepository,
15644
+ baseDirectory,
15645
+ isTTY: resolvedIsTTY,
15646
+ confirmPrompt
15647
+ });
15648
+ }
15431
15649
  logConsole("");
15432
15650
  logSuccessConsole("Packmind initialized successfully!");
15433
15651
  if (showOnboardHint) {
@@ -15440,6 +15658,43 @@ async function initHandler(deps) {
15440
15658
  errors: []
15441
15659
  };
15442
15660
  }
15661
+ async function offerRepositoryTracking(deps) {
15662
+ const confirm = createTrackConfirm({
15663
+ isTTY: deps.isTTY,
15664
+ confirmPrompt: deps.confirmPrompt
15665
+ });
15666
+ try {
15667
+ const result = await deps.trackRepository({
15668
+ repoPath: deps.baseDirectory,
15669
+ origin: "init",
15670
+ update: false,
15671
+ confirm
15672
+ });
15673
+ switch (result.status) {
15674
+ case "set":
15675
+ logSuccessConsole(
15676
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
15677
+ );
15678
+ break;
15679
+ case "already-tracked-other-branch":
15680
+ logInfoConsole(
15681
+ `Repository already tracked on branch ${result.trackedBranch}.`
15682
+ );
15683
+ break;
15684
+ case "already-tracked-same-branch":
15685
+ logWarningConsole(
15686
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
15687
+ );
15688
+ break;
15689
+ case "cancelled":
15690
+ case "nothing-tracked":
15691
+ case "updated":
15692
+ default:
15693
+ break;
15694
+ }
15695
+ } catch {
15696
+ }
15697
+ }
15443
15698
 
15444
15699
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15445
15700
  async function bootstrapInstallContext(deps) {
@@ -15585,7 +15840,7 @@ async function promptOrgRenderModes(params) {
15585
15840
  if (useSimplePrompt) {
15586
15841
  confirmed = await confirmWithReadline(`${promptMessage} [Y/n] `);
15587
15842
  } else {
15588
- const answer = await inquirer2.default.prompt([
15843
+ const answer = await inquirer3.default.prompt([
15589
15844
  {
15590
15845
  type: "select",
15591
15846
  name: "confirm",
@@ -15731,23 +15986,129 @@ function mergeInstallResults(results) {
15731
15986
  }
15732
15987
  return merged;
15733
15988
  }
15989
+ function decideDistributionTracking(params) {
15990
+ const { lookup, currentBranch } = params;
15991
+ switch (lookup.status) {
15992
+ case "flag-off":
15993
+ return { action: "record-legacy" };
15994
+ case "unavailable":
15995
+ return { action: "inform" };
15996
+ case "resolved": {
15997
+ const tracked = lookup.trackedGitRepo;
15998
+ if (!tracked) {
15999
+ return { action: "skip", reason: "repo_not_tracked" };
16000
+ }
16001
+ if (tracked.branch !== currentBranch) {
16002
+ return {
16003
+ action: "skip",
16004
+ reason: "wrong_branch",
16005
+ trackedBranch: tracked.branch
16006
+ };
16007
+ }
16008
+ return { action: "record" };
16009
+ }
16010
+ }
16011
+ }
16012
+ var NO_GIT_REPO_CACHE_KEY = "<no-git-repo>";
16013
+ function toRepoRelativePath(dir, gitRoot) {
16014
+ let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
16015
+ if (!relativePath.startsWith("/")) {
16016
+ relativePath = "/" + relativePath;
16017
+ }
16018
+ if (!relativePath.endsWith("/")) {
16019
+ relativePath = relativePath + "/";
16020
+ }
16021
+ return relativePath;
16022
+ }
16023
+ function reportDistributionTrackingDecision(decision, context) {
16024
+ switch (decision.action) {
16025
+ case "skip":
16026
+ if (decision.reason === "repo_not_tracked") {
16027
+ logWarningConsole(
16028
+ `Distribution not recorded \u2014 ${context.owner}/${context.repo} is not tracked in Packmind. Ask an admin to run ${formatCommand(
16029
+ "packmind track"
16030
+ )} to start tracking it.`
16031
+ );
16032
+ } else {
16033
+ logWarningConsole(
16034
+ `Distribution not recorded \u2014 you're on '${context.currentBranch}', but the tracked branch is '${decision.trackedBranch}'. Switch to '${decision.trackedBranch}' to record this distribution.`
16035
+ );
16036
+ }
16037
+ break;
16038
+ case "inform":
16039
+ logInfoConsole(
16040
+ `This folder is not tracked \u2014 distribution not recorded in Packmind.`
16041
+ );
16042
+ break;
16043
+ }
16044
+ }
16045
+ async function resolveTrackingLookup(packmindCliHexa, owner, repo) {
16046
+ try {
16047
+ const { gitRepo } = await packmindCliHexa.getTrackedRepository({
16048
+ owner,
16049
+ repo
16050
+ });
16051
+ return { status: "resolved", trackedGitRepo: gitRepo };
16052
+ } catch (error) {
16053
+ const statusCode = error?.statusCode;
16054
+ if (statusCode === 404) {
16055
+ return { status: "flag-off" };
16056
+ }
16057
+ return { status: "unavailable" };
16058
+ }
16059
+ }
16060
+ async function computeDistributionTrackingDecision(packmindCliHexa, gitRoot) {
16061
+ if (!gitRoot) {
16062
+ const decision2 = { action: "inform" };
16063
+ reportDistributionTrackingDecision(decision2, {});
16064
+ return decision2;
16065
+ }
16066
+ let owner;
16067
+ let repo;
16068
+ let gitBranch;
16069
+ try {
16070
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
16071
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
16072
+ ({ owner, repo } = parseOwnerRepo(gitRemoteUrl));
16073
+ } catch {
16074
+ const decision2 = { action: "inform" };
16075
+ reportDistributionTrackingDecision(decision2, {});
16076
+ return decision2;
16077
+ }
16078
+ const lookup = await resolveTrackingLookup(packmindCliHexa, owner, repo);
16079
+ const decision = decideDistributionTracking({
16080
+ lookup,
16081
+ currentBranch: gitBranch
16082
+ });
16083
+ reportDistributionTrackingDecision(decision, {
16084
+ owner,
16085
+ repo,
16086
+ currentBranch: gitBranch
16087
+ });
16088
+ return decision;
16089
+ }
15734
16090
  async function notifyArtefactsDistributionIfInGitRepo(params) {
15735
- const { packmindCliHexa, dir } = params;
16091
+ const { packmindCliHexa, dir, decisionCache } = params;
15736
16092
  try {
15737
16093
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(dir);
16094
+ const cacheKey = gitRoot ?? NO_GIT_REPO_CACHE_KEY;
16095
+ if (!decisionCache.has(cacheKey)) {
16096
+ decisionCache.set(
16097
+ cacheKey,
16098
+ await computeDistributionTrackingDecision(packmindCliHexa, gitRoot)
16099
+ );
16100
+ }
16101
+ const decision = decisionCache.get(cacheKey);
16102
+ if (!decision || decision.action !== "record" && decision.action !== "record-legacy") {
16103
+ return;
16104
+ }
15738
16105
  if (!gitRoot) return;
15739
16106
  const lockFilePath = path24.join(dir, "packmind-lock.json");
15740
16107
  const content = fs23.readFileSync(lockFilePath, "utf-8");
15741
16108
  const packmindLockFile = JSON.parse(content);
15742
16109
  const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
15743
16110
  const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
15744
- let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
15745
- if (!relativePath.startsWith("/")) {
15746
- relativePath = "/" + relativePath;
15747
- }
15748
- if (!relativePath.endsWith("/")) {
15749
- relativePath = relativePath + "/";
15750
- }
16111
+ const relativePath = toRepoRelativePath(dir, gitRoot);
15751
16112
  await packmindCliHexa.notifyArtefactsDistribution({
15752
16113
  gitRemoteUrl,
15753
16114
  gitBranch,
@@ -15801,8 +16162,7 @@ async function installDefaultSkillsIfAtGitRoot(params) {
15801
16162
  async function installHandler({
15802
16163
  installPath,
15803
16164
  packages,
15804
- status,
15805
- skipInstalledAt
16165
+ status
15806
16166
  }) {
15807
16167
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15808
16168
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
@@ -15880,13 +16240,13 @@ async function installHandler({
15880
16240
  const results = [];
15881
16241
  const thrownErrors = [];
15882
16242
  const multiDir = targetDirs.length > 1;
16243
+ const distributionTrackingCache = /* @__PURE__ */ new Map();
15883
16244
  for (const dir of targetDirs) {
15884
16245
  try {
15885
16246
  const dirHomeAgent = isAgentHomeDirectory(dir) ?? void 0;
15886
16247
  const result = await packmindCliHexa.install({
15887
16248
  baseDirectory: dir,
15888
16249
  packages: packages.length > 0 ? packages : void 0,
15889
- skipInstalledAt,
15890
16250
  cliVersion: CLI_VERSION,
15891
16251
  homeAgent: dirHomeAgent
15892
16252
  });
@@ -15894,7 +16254,8 @@ async function installHandler({
15894
16254
  if (!dirHomeAgent) {
15895
16255
  await notifyArtefactsDistributionIfInGitRepo({
15896
16256
  packmindCliHexa,
15897
- dir
16257
+ dir,
16258
+ decisionCache: distributionTrackingCache
15898
16259
  });
15899
16260
  }
15900
16261
  } catch (error) {
@@ -15967,10 +16328,6 @@ var installCommand = (0, import_cmd_ts2.command)({
15967
16328
  status: (0, import_cmd_ts2.flag)({
15968
16329
  long: "status",
15969
16330
  description: "Show status of all packmind.json files and their packages in the workspace"
15970
- }),
15971
- skipInstalledAt: (0, import_cmd_ts2.flag)({
15972
- long: "skip-installed-at",
15973
- description: "Omit the installedAt timestamp from the packmind-lock.json file"
15974
16331
  })
15975
16332
  },
15976
16333
  handler: installHandler
@@ -16129,9 +16486,9 @@ var logoutCommand = (0, import_cmd_ts5.command)({
16129
16486
  logInfoConsole("No stored credentials file found.");
16130
16487
  }
16131
16488
  logConsole(
16132
- "\nNote: PACKMIND_API_KEY_V3 environment variable is still set."
16489
+ "\nNote: PACKMIND_API_KEY environment variable is still set."
16133
16490
  );
16134
- logConsole("To fully log out, run: unset PACKMIND_API_KEY_V3");
16491
+ logConsole("To fully log out, run: unset PACKMIND_API_KEY");
16135
16492
  }
16136
16493
  } catch (error) {
16137
16494
  logErrorConsole("Failed to remove credentials file.");
@@ -16213,7 +16570,7 @@ No credentials found. Run \`packmind-cli login\` to authenticate.`
16213
16570
  );
16214
16571
  logConsole(`
16215
16572
  Credentials are loaded from (in order of priority):`);
16216
- logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
16573
+ logConsole(` 1. PACKMIND_API_KEY environment variable`);
16217
16574
  logConsole(` 2. ${result.credentialsPath}`);
16218
16575
  process.exit(1);
16219
16576
  }
@@ -16697,15 +17054,15 @@ var CreatePackageUseCase = class {
16697
17054
  this.gateway = gateway;
16698
17055
  this.spaceService = spaceService;
16699
17056
  }
16700
- async execute(command30) {
16701
- const space = await this.getSpace(command30);
17057
+ async execute(command31) {
17058
+ const space = await this.getSpace(command31);
16702
17059
  const result = await this.gateway.packages.create({
16703
17060
  spaceId: space.id,
16704
- name: command30.name,
16705
- description: command30.description ?? "",
17061
+ name: command31.name,
17062
+ description: command31.description ?? "",
16706
17063
  recipeIds: [],
16707
17064
  standardIds: [],
16708
- originSkill: command30.originSkill
17065
+ originSkill: command31.originSkill
16709
17066
  });
16710
17067
  return {
16711
17068
  packageId: result.package.id,
@@ -16714,12 +17071,12 @@ var CreatePackageUseCase = class {
16714
17071
  spaceSlug: space.slug
16715
17072
  };
16716
17073
  }
16717
- async getSpace(command30) {
17074
+ async getSpace(command31) {
16718
17075
  const spaces = await this.spaceService.getSpaces();
16719
- if (command30.spaceSlug) {
16720
- const found = spaces.find((s) => s.slug === command30.spaceSlug);
17076
+ if (command31.spaceSlug) {
17077
+ const found = spaces.find((s) => s.slug === command31.spaceSlug);
16721
17078
  if (!found) {
16722
- throw new Error(`Space '${command30.spaceSlug}' not found.`);
17079
+ throw new Error(`Space '${command31.spaceSlug}' not found.`);
16723
17080
  }
16724
17081
  return found;
16725
17082
  }
@@ -16837,8 +17194,8 @@ var AddToPackageUseCase = class {
16837
17194
  this.gateway = gateway;
16838
17195
  this.spaceService = spaceService;
16839
17196
  }
16840
- async execute(command30) {
16841
- const { packageSlug, spaceSlug, itemType, itemSlugs } = command30;
17197
+ async execute(command31) {
17198
+ const { packageSlug, spaceSlug, itemType, itemSlugs } = command31;
16842
17199
  const space = spaceSlug ? await this.resolveSpaceBySlug(spaceSlug) : await this.spaceService.getDefaultSpace();
16843
17200
  const packages = await this.gateway.packages.list({
16844
17201
  spaceId: space.id
@@ -16859,12 +17216,12 @@ var AddToPackageUseCase = class {
16859
17216
  standardIds: [],
16860
17217
  recipeIds: [],
16861
17218
  skillIds: [],
16862
- originSkill: command30.originSkill
17219
+ originSkill: command31.originSkill
16863
17220
  };
16864
17221
  if (itemType === "standard") {
16865
17222
  addCommand.standardIds = ids.map(createStandardId);
16866
17223
  } else if (itemType === "command") {
16867
- addCommand.recipeIds = ids.map(createRecipeId);
17224
+ addCommand.recipeIds = ids.map(createCommandId);
16868
17225
  } else if (itemType === "skill") {
16869
17226
  addCommand.skillIds = ids.map(createSkillId);
16870
17227
  }
@@ -16911,7 +17268,7 @@ var AddToPackageUseCase = class {
16911
17268
  }
16912
17269
  async findCommandBySlug(slug6, spaceId) {
16913
17270
  const commands = await this.gateway.commands.list({ spaceId });
16914
- return commands.recipes.find((command30) => command30.slug === slug6) ?? null;
17271
+ return commands.recipes.find((command31) => command31.slug === slug6) ?? null;
16915
17272
  }
16916
17273
  async findSkillBySlug(slug6, spaceId) {
16917
17274
  const skills = await this.gateway.skills.list({ spaceId });
@@ -16987,11 +17344,11 @@ async function executeAddToPackage(pkgSlug, spaceSlug, itemType, itemSlugs, useC
16987
17344
  logErrorConsole(message);
16988
17345
  if (error instanceof ItemNotFoundError) {
16989
17346
  const spaceFlag = error.spaceSlug ? ` --space ${error.spaceSlug}` : "";
16990
- const command30 = formatCommand(
17347
+ const command31 = formatCommand(
16991
17348
  `packmind-cli ${error.itemType}s list${spaceFlag}`
16992
17349
  );
16993
17350
  logInfoConsole(
16994
- `Run \`${command30}\` to display available ${error.itemType}s`
17351
+ `Run \`${command31}\` to display available ${error.itemType}s`
16995
17352
  );
16996
17353
  }
16997
17354
  return { success: false, error: message };
@@ -17249,10 +17606,10 @@ ${pkg.name} (${fullSlug}):
17249
17606
  });
17250
17607
  logConsole("");
17251
17608
  }
17252
- if (pkg.recipes && pkg.recipes.length > 0) {
17609
+ if (pkg.commands && pkg.commands.length > 0) {
17253
17610
  logConsole("Commands:");
17254
- pkg.recipes.forEach((recipe) => {
17255
- logConsole(` - ${recipe.name}`);
17611
+ pkg.commands.forEach((command31) => {
17612
+ logConsole(` - ${command31.name}`);
17256
17613
  });
17257
17614
  logConsole("");
17258
17615
  }
@@ -17921,8 +18278,35 @@ function parseLenientStandard(content) {
17921
18278
  return { name, description, rules };
17922
18279
  }
17923
18280
 
18281
+ // packages/skills/src/application/errors/SkillValidationError.ts
18282
+ var SkillValidationError = class _SkillValidationError extends Error {
18283
+ constructor(errors) {
18284
+ const messages = errors.map((e) => e.message).join("; ");
18285
+ super(`Skill validation failed: ${messages}`);
18286
+ this.name = "SkillValidationError";
18287
+ this.errors = errors;
18288
+ Object.setPrototypeOf(this, _SkillValidationError.prototype);
18289
+ }
18290
+ };
18291
+
17924
18292
  // packages/skills/src/application/validator/SkillValidator.ts
17925
18293
  var DESCRIPTION_MAX_LENGTH = 1024;
18294
+ var SKILL_FILE_MAX_CONTENT_LENGTH = 3e5;
18295
+ function validateSkillFileContent(content) {
18296
+ if (content.trim().length === 0) {
18297
+ throw new SkillValidationError([
18298
+ { field: "content", message: "File content cannot be empty" }
18299
+ ]);
18300
+ }
18301
+ if (content.length > SKILL_FILE_MAX_CONTENT_LENGTH) {
18302
+ throw new SkillValidationError([
18303
+ {
18304
+ field: "content",
18305
+ message: `File content exceeds the maximum length of ${SKILL_FILE_MAX_CONTENT_LENGTH} characters`
18306
+ }
18307
+ ]);
18308
+ }
18309
+ }
17926
18310
 
17927
18311
  // packages/skills/src/infra/schemas/SkillSchema.ts
17928
18312
  var import_typeorm2 = require("typeorm");
@@ -18151,15 +18535,18 @@ var import_uuid = require("uuid");
18151
18535
  // packages/skills/src/application/useCases/updateSkill/UpdateSkillUseCase.ts
18152
18536
  var import_slug2 = __toESM(require("slug"));
18153
18537
 
18538
+ // packages/skills/src/application/useCases/updateSkillFileFromUI/UpdateSkillFileFromUIUseCase.ts
18539
+ var import_uuid2 = require("uuid");
18540
+
18154
18541
  // packages/skills/src/application/useCases/uploadSkill/UploadSkillUseCase.ts
18155
18542
  var import_slug3 = __toESM(require("slug"));
18156
- var import_uuid2 = require("uuid");
18543
+ var import_uuid3 = require("uuid");
18157
18544
 
18158
18545
  // packages/skills/src/application/services/SkillService.ts
18159
- var import_uuid3 = require("uuid");
18546
+ var import_uuid4 = require("uuid");
18160
18547
 
18161
18548
  // packages/skills/src/application/services/SkillVersionService.ts
18162
- var import_uuid4 = require("uuid");
18549
+ var import_uuid5 = require("uuid");
18163
18550
 
18164
18551
  // apps/cli/src/application/utils/parseSkillDirectory.ts
18165
18552
  var SKILL_MD_FILENAME2 = "SKILL.md";
@@ -18200,11 +18587,32 @@ function parseSkillDirectory(files) {
18200
18587
  error: `Skill "${name.trim()}" has a description of ${trimmedDescription.length} characters, which exceeds the maximum of ${DESCRIPTION_MAX_LENGTH}. Edit the "description" field in SKILL.md and try again.`
18201
18588
  };
18202
18589
  }
18203
- if (body.trim().length === 0) {
18204
- return {
18205
- success: false,
18206
- error: "SKILL.md body (prompt) cannot be empty."
18207
- };
18590
+ try {
18591
+ validateSkillFileContent(body);
18592
+ } catch (error) {
18593
+ if (error instanceof SkillValidationError) {
18594
+ return {
18595
+ success: false,
18596
+ error: `SKILL.md body (prompt) is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18597
+ };
18598
+ }
18599
+ throw error;
18600
+ }
18601
+ const supportingMdFiles = files.filter(
18602
+ (f) => f.relativePath !== SKILL_MD_FILENAME2 && f.relativePath.endsWith(".md")
18603
+ );
18604
+ for (const mdFile of supportingMdFiles) {
18605
+ try {
18606
+ validateSkillFileContent(mdFile.content);
18607
+ } catch (error) {
18608
+ if (error instanceof SkillValidationError) {
18609
+ return {
18610
+ success: false,
18611
+ error: `File "${mdFile.relativePath}" is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18612
+ };
18613
+ }
18614
+ throw error;
18615
+ }
18208
18616
  }
18209
18617
  const payload = {
18210
18618
  name: name.trim(),
@@ -21766,7 +22174,9 @@ var initCommand = (0, import_cmd_ts38.command)({
21766
22174
  baseDirectory,
21767
22175
  installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
21768
22176
  ensureCliVersion: packmindCliHexa.ensureCliVersion.bind(packmindCliHexa),
21769
- cliVersion: CLI_VERSION5
22177
+ cliVersion: CLI_VERSION5,
22178
+ isTTY: Boolean(process.stdin.isTTY),
22179
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
21770
22180
  });
21771
22181
  if (!result.success) {
21772
22182
  for (const error of result.errors) {
@@ -21777,14 +22187,120 @@ var initCommand = (0, import_cmd_ts38.command)({
21777
22187
  }
21778
22188
  });
21779
22189
 
21780
- // apps/cli/src/infra/commands/UpdateCommand.ts
22190
+ // apps/cli/src/infra/commands/TrackCommand.ts
21781
22191
  var import_cmd_ts39 = __toESM(require_cjs());
22192
+
22193
+ // apps/cli/src/infra/commands/trackHandler.ts
22194
+ async function trackHandler(deps) {
22195
+ const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
22196
+ const confirm = createTrackConfirm({
22197
+ isTTY,
22198
+ confirmPrompt: deps.confirmPrompt
22199
+ });
22200
+ let result;
22201
+ try {
22202
+ result = await deps.trackRepository({
22203
+ repoPath: deps.baseDirectory,
22204
+ origin: "track",
22205
+ update: deps.update,
22206
+ confirm
22207
+ });
22208
+ } catch (error) {
22209
+ handleTrackError(error);
22210
+ return;
22211
+ }
22212
+ switch (result.status) {
22213
+ case "set":
22214
+ logSuccessConsole(
22215
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
22216
+ );
22217
+ process.exit(0);
22218
+ return;
22219
+ case "updated":
22220
+ logSuccessConsole(
22221
+ `Tracked branch for ${result.owner}/${result.repo} changed from ${result.fromBranch} to ${result.branch}.`
22222
+ );
22223
+ process.exit(0);
22224
+ return;
22225
+ case "cancelled":
22226
+ logInfoConsole("No changes made. The tracked branch is unchanged.");
22227
+ process.exit(0);
22228
+ return;
22229
+ case "already-tracked-same-branch":
22230
+ if (deps.update) {
22231
+ logErrorConsole(
22232
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
22233
+ );
22234
+ process.exit(1);
22235
+ } else {
22236
+ logInfoConsole(
22237
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
22238
+ );
22239
+ process.exit(0);
22240
+ }
22241
+ return;
22242
+ case "already-tracked-other-branch":
22243
+ logErrorConsole(
22244
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.trackedBranch}. Run ${formatCommand(
22245
+ "packmind track --update"
22246
+ )} to move it to ${result.branch}.`
22247
+ );
22248
+ process.exit(1);
22249
+ return;
22250
+ case "nothing-tracked":
22251
+ logErrorConsole(
22252
+ `Nothing is tracked yet \u2014 run ${formatCommand("packmind init")} or ${formatCommand("packmind track")} to start tracking.`
22253
+ );
22254
+ process.exit(1);
22255
+ return;
22256
+ }
22257
+ }
22258
+ function handleTrackError(error) {
22259
+ if (error instanceof NotLoggedInError) {
22260
+ logErrorConsole(error.message);
22261
+ process.exit(1);
22262
+ return;
22263
+ }
22264
+ const statusCode = error?.statusCode;
22265
+ if (statusCode === 404) {
22266
+ logErrorConsole("Repository tracking is not available for your account.");
22267
+ process.exit(1);
22268
+ return;
22269
+ }
22270
+ const message = error instanceof Error ? error.message : String(error);
22271
+ logErrorConsole(message);
22272
+ process.exit(1);
22273
+ }
22274
+
22275
+ // apps/cli/src/infra/commands/TrackCommand.ts
22276
+ var trackCommand = (0, import_cmd_ts39.command)({
22277
+ name: "track",
22278
+ description: "Set the repository and branch Packmind tracks for the current project",
22279
+ args: {
22280
+ update: (0, import_cmd_ts39.flag)({
22281
+ long: "update",
22282
+ description: "Move the tracked branch to the current branch (requires an existing tracked branch)"
22283
+ })
22284
+ },
22285
+ handler: async ({ update }) => {
22286
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22287
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22288
+ await trackHandler({
22289
+ update,
22290
+ baseDirectory: process.cwd(),
22291
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
22292
+ });
22293
+ }
22294
+ });
22295
+
22296
+ // apps/cli/src/infra/commands/UpdateCommand.ts
22297
+ var import_cmd_ts40 = __toESM(require_cjs());
21782
22298
  var { version: CLI_VERSION6 } = require_package();
21783
- var updateCommand = (0, import_cmd_ts39.command)({
22299
+ var updateCommand = (0, import_cmd_ts40.command)({
21784
22300
  name: "update",
21785
22301
  description: "Update packmind-cli to the latest version",
21786
22302
  args: {
21787
- check: (0, import_cmd_ts39.flag)({
22303
+ check: (0, import_cmd_ts40.flag)({
21788
22304
  long: "check",
21789
22305
  description: "Only check if a newer version is available without performing the update"
21790
22306
  })
@@ -21842,7 +22358,7 @@ if (args.includes("--version") || args.includes("-v")) {
21842
22358
  logConsole(`packmind-cli version ${CLI_VERSION7}`);
21843
22359
  process.exit(0);
21844
22360
  }
21845
- var app = (0, import_cmd_ts40.subcommands)({
22361
+ var app = (0, import_cmd_ts41.subcommands)({
21846
22362
  name: "packmind-cli",
21847
22363
  description: "Packmind CLI tool",
21848
22364
  cmds: {
@@ -21859,12 +22375,13 @@ var app = (0, import_cmd_ts40.subcommands)({
21859
22375
  skills: skillsCommand,
21860
22376
  spaces: spacesCommand,
21861
22377
  standards: standardsCommand,
22378
+ track: trackCommand,
21862
22379
  uninstall: uninstallCommand,
21863
22380
  update: updateCommand,
21864
22381
  whoami: whoamiCommand
21865
22382
  }
21866
22383
  });
21867
- (0, import_cmd_ts40.run)(app, args).catch((error) => {
22384
+ (0, import_cmd_ts41.run)(app, args).catch((error) => {
21868
22385
  logErrorConsole(error.message);
21869
22386
  process.exit(1);
21870
22387
  });