@packmind/cli 0.31.0 → 0.33.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 +1336 -559
  2. package/package.json +10 -12
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
  }
@@ -371,32 +380,32 @@ var init_supports_color = __esm({
371
380
  });
372
381
 
373
382
  // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js
374
- function stringReplaceAll(string16, substring, replacer) {
375
- let index = string16.indexOf(substring);
383
+ function stringReplaceAll(string17, substring, replacer) {
384
+ let index = string17.indexOf(substring);
376
385
  if (index === -1) {
377
- return string16;
386
+ return string17;
378
387
  }
379
388
  const substringLength = substring.length;
380
389
  let endIndex = 0;
381
390
  let returnValue = "";
382
391
  do {
383
- returnValue += string16.slice(endIndex, index) + substring + replacer;
392
+ returnValue += string17.slice(endIndex, index) + substring + replacer;
384
393
  endIndex = index + substringLength;
385
- index = string16.indexOf(substring, endIndex);
394
+ index = string17.indexOf(substring, endIndex);
386
395
  } while (index !== -1);
387
- returnValue += string16.slice(endIndex);
396
+ returnValue += string17.slice(endIndex);
388
397
  return returnValue;
389
398
  }
390
- function stringEncaseCRLFWithFirstIndex(string16, prefix, postfix, index) {
399
+ function stringEncaseCRLFWithFirstIndex(string17, prefix, postfix, index) {
391
400
  let endIndex = 0;
392
401
  let returnValue = "";
393
402
  do {
394
- const gotCR = string16[index - 1] === "\r";
395
- returnValue += string16.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
403
+ const gotCR = string17[index - 1] === "\r";
404
+ returnValue += string17.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
405
  endIndex = index + 1;
397
- index = string16.indexOf("\n", endIndex);
406
+ index = string17.indexOf("\n", endIndex);
398
407
  } while (index !== -1);
399
- returnValue += string16.slice(endIndex);
408
+ returnValue += string17.slice(endIndex);
400
409
  return returnValue;
401
410
  }
402
411
  var init_utilities = __esm({
@@ -555,26 +564,26 @@ var init_source = __esm({
555
564
  builder[IS_EMPTY] = _isEmpty;
556
565
  return builder;
557
566
  };
558
- applyStyle = (self, string16) => {
559
- if (self.level <= 0 || !string16) {
560
- return self[IS_EMPTY] ? "" : string16;
567
+ applyStyle = (self, string17) => {
568
+ if (self.level <= 0 || !string17) {
569
+ return self[IS_EMPTY] ? "" : string17;
561
570
  }
562
571
  let styler = self[STYLER];
563
572
  if (styler === void 0) {
564
- return string16;
573
+ return string17;
565
574
  }
566
575
  const { openAll, closeAll } = styler;
567
- if (string16.includes("\x1B")) {
576
+ if (string17.includes("\x1B")) {
568
577
  while (styler !== void 0) {
569
- string16 = stringReplaceAll(string16, styler.close, styler.open);
578
+ string17 = stringReplaceAll(string17, styler.close, styler.open);
570
579
  styler = styler.parent;
571
580
  }
572
581
  }
573
- const lfIndex = string16.indexOf("\n");
582
+ const lfIndex = string17.indexOf("\n");
574
583
  if (lfIndex !== -1) {
575
- string16 = stringEncaseCRLFWithFirstIndex(string16, closeAll, openAll, lfIndex);
584
+ string17 = stringEncaseCRLFWithFirstIndex(string17, closeAll, openAll, lfIndex);
576
585
  }
577
- return openAll + string16 + closeAll;
586
+ return openAll + string17 + closeAll;
578
587
  };
579
588
  Object.defineProperties(createChalk.prototype, styles2);
580
589
  chalk = createChalk();
@@ -767,9 +776,9 @@ var require_findOption = __commonJS({
767
776
  continue;
768
777
  }
769
778
  if (node.type === "shortOptions" && opts.shortNames.length) {
770
- for (const option18 of node.options) {
771
- if (opts.shortNames.includes(option18.key)) {
772
- result.push(option18);
779
+ for (const option19 of node.options) {
780
+ if (opts.shortNames.includes(option19.key)) {
781
+ result.push(option19);
773
782
  }
774
783
  }
775
784
  }
@@ -842,7 +851,7 @@ var require_types = __commonJS({
842
851
  "use strict";
843
852
  Object.defineProperty(exports2, "__esModule", { value: true });
844
853
  exports2.boolean = exports2.string = exports2.number = void 0;
845
- exports2.optional = optional13;
854
+ exports2.optional = optional14;
846
855
  exports2.array = array2;
847
856
  var type_1 = require_type();
848
857
  exports2.number = {
@@ -869,7 +878,7 @@ var require_types = __commonJS({
869
878
  return false;
870
879
  }
871
880
  };
872
- function optional13(t) {
881
+ function optional14(t) {
873
882
  return {
874
883
  ...t,
875
884
  defaultValue() {
@@ -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
@@ -1255,7 +1264,7 @@ var require_positional = __commonJS({
1255
1264
  return mod && mod.__esModule ? mod : { "default": mod };
1256
1265
  };
1257
1266
  Object.defineProperty(exports2, "__esModule", { value: true });
1258
- exports2.positional = positional9;
1267
+ exports2.positional = positional8;
1259
1268
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1260
1269
  var Result = __importStar(require_Result());
1261
1270
  var types_1 = require_types();
@@ -1295,8 +1304,8 @@ var require_positional = __commonJS({
1295
1304
  var _a2;
1296
1305
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
1297
1306
  const defaultValueFn = (_a2 = config.defaultValue) !== null && _a2 !== void 0 ? _a2 : config.type.defaultValue;
1298
- const positional10 = positionals[0];
1299
- if (!positional10) {
1307
+ const positional9 = positionals[0];
1308
+ if (!positional9) {
1300
1309
  if (defaultValueFn) {
1301
1310
  return Result.ok(defaultValueFn());
1302
1311
  }
@@ -1309,13 +1318,13 @@ var require_positional = __commonJS({
1309
1318
  ]
1310
1319
  });
1311
1320
  }
1312
- visitedNodes.add(positional10);
1313
- const decoded = await Result.safeAsync(config.type.from(positional10.raw));
1321
+ visitedNodes.add(positional9);
1322
+ const decoded = await Result.safeAsync(config.type.from(positional9.raw));
1314
1323
  if (Result.isErr(decoded)) {
1315
1324
  return Result.err({
1316
1325
  errors: [
1317
1326
  {
1318
- nodes: [positional10],
1327
+ nodes: [positional9],
1319
1328
  message: decoded.error.message
1320
1329
  }
1321
1330
  ]
@@ -1325,7 +1334,7 @@ var require_positional = __commonJS({
1325
1334
  }
1326
1335
  };
1327
1336
  }
1328
- function positional9(config) {
1337
+ function positional8(config) {
1329
1338
  return fullPositional({
1330
1339
  type: types_1.string,
1331
1340
  ...config
@@ -1403,9 +1412,9 @@ var require_subcommands = __commonJS({
1403
1412
  let errorMessage = "Not a valid subcommand name";
1404
1413
  const closeOptions = (0, didyoumean_1.default)(str, flatMap(commands, (x) => x.names));
1405
1414
  if (closeOptions) {
1406
- const option18 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1415
+ const option19 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1407
1416
  errorMessage += `
1408
- Did you mean ${chalk_1.default.italic(option18)}?`;
1417
+ Did you mean ${chalk_1.default.italic(option19)}?`;
1409
1418
  }
1410
1419
  throw new Error(errorMessage);
1411
1420
  }
@@ -1578,14 +1587,14 @@ var strip_ansi_exports = {};
1578
1587
  __export(strip_ansi_exports, {
1579
1588
  default: () => stripAnsi
1580
1589
  });
1581
- function stripAnsi(string16) {
1582
- if (typeof string16 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string16}\``);
1590
+ function stripAnsi(string17) {
1591
+ if (typeof string17 !== "string") {
1592
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string17}\``);
1584
1593
  }
1585
- if (!string16.includes("\x1B") && !string16.includes("\x9B")) {
1586
- return string16;
1594
+ if (!string17.includes("\x1B") && !string17.includes("\x9B")) {
1595
+ return string17;
1587
1596
  }
1588
- return string16.replace(regex, "");
1597
+ return string17.replace(regex, "");
1589
1598
  }
1590
1599
  var regex;
1591
1600
  var init_strip_ansi = __esm({
@@ -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 = command32;
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 command32(config) {
1710
1719
  const argEntries = (0, utils_1.entries)(config.args);
1711
1720
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1712
1721
  return {
@@ -1784,11 +1793,11 @@ var require_command = __commonJS({
1784
1793
  }
1785
1794
  if (node.type === "forcePositional") {
1786
1795
  } else if (node.type === "shortOptions") {
1787
- for (const option18 of node.options) {
1788
- if (context.visitedNodes.has(option18)) {
1796
+ for (const option19 of node.options) {
1797
+ if (context.visitedNodes.has(option19)) {
1789
1798
  continue;
1790
1799
  }
1791
- unknownArguments.push(option18);
1800
+ unknownArguments.push(option19);
1792
1801
  }
1793
1802
  } else {
1794
1803
  unknownArguments.push(node);
@@ -1867,7 +1876,7 @@ var require_option = __commonJS({
1867
1876
  return mod && mod.__esModule ? mod : { "default": mod };
1868
1877
  };
1869
1878
  Object.defineProperty(exports2, "__esModule", { value: true });
1870
- exports2.option = option18;
1879
+ exports2.option = option19;
1871
1880
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1872
1881
  var Result = __importStar(require_Result());
1873
1882
  var findOption_1 = require_findOption();
@@ -1943,11 +1952,11 @@ var require_option = __commonJS({
1943
1952
  const valueFromEnv = config.env ? process.env[config.env] : void 0;
1944
1953
  const defaultValueFn = config.defaultValue || config.type.defaultValue;
1945
1954
  const onMissingFn = config.onMissing || config.type.onMissing;
1946
- const option19 = options[0];
1955
+ const option20 = options[0];
1947
1956
  let rawValue;
1948
1957
  let envPrefix = "";
1949
- if (option19 === null || option19 === void 0 ? void 0 : option19.value) {
1950
- rawValue = option19.value.node.raw;
1958
+ if (option20 === null || option20 === void 0 ? void 0 : option20.value) {
1959
+ rawValue = option20.value.node.raw;
1951
1960
  } else if (valueFromEnv !== void 0) {
1952
1961
  rawValue = valueFromEnv;
1953
1962
  envPrefix = `env[${chalk_1.default.italic(config.env)}]: `;
@@ -1982,7 +1991,7 @@ var require_option = __commonJS({
1982
1991
  });
1983
1992
  }
1984
1993
  } else {
1985
- const raw = (option19 === null || option19 === void 0 ? void 0 : option19.type) === "shortOption" ? `-${option19 === null || option19 === void 0 ? void 0 : option19.key}` : `--${config.long}`;
1994
+ const raw = (option20 === null || option20 === void 0 ? void 0 : option20.type) === "shortOption" ? `-${option20 === null || option20 === void 0 ? void 0 : option20.key}` : `--${config.long}`;
1986
1995
  return Result.err({
1987
1996
  errors: [
1988
1997
  {
@@ -2004,7 +2013,7 @@ var require_option = __commonJS({
2004
2013
  }
2005
2014
  };
2006
2015
  }
2007
- function option18(config) {
2016
+ function option19(config) {
2008
2017
  return fullOption({
2009
2018
  type: types_1.string,
2010
2019
  ...config
@@ -2043,12 +2052,12 @@ var require_errorBox = __commonJS({
2043
2052
  if (node.type === "shortOptions") {
2044
2053
  let failed = false;
2045
2054
  let s = "";
2046
- for (const option18 of node.options) {
2047
- if (error.nodes.includes(option18)) {
2048
- s += chalk_1.default.red(option18.raw);
2055
+ for (const option19 of node.options) {
2056
+ if (error.nodes.includes(option19)) {
2057
+ s += chalk_1.default.red(option19.raw);
2049
2058
  failed = true;
2050
2059
  } else {
2051
- s += chalk_1.default.dim(option18.raw);
2060
+ s += chalk_1.default.dim(option19.raw);
2052
2061
  }
2053
2062
  }
2054
2063
  const prefix = failed ? chalk_1.default.red("-") : chalk_1.default.dim("-");
@@ -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();
@@ -3081,8 +3090,8 @@ var require_tokenizer = __commonJS({
3081
3090
  tokens.push(token);
3082
3091
  overallIndex += token.raw.length;
3083
3092
  };
3084
- for (const [stringIndex, string16] of (0, utils_1.enumerate)(strings)) {
3085
- const chars = [...string16];
3093
+ for (const [stringIndex, string17] of (0, utils_1.enumerate)(strings)) {
3094
+ const chars = [...string17];
3086
3095
  for (let i = 0; i < chars.length; i++) {
3087
3096
  if (chars[i] === "-" && chars[i + 1] === "-") {
3088
3097
  push({ type: "longPrefix", raw: "--", index: overallIndex });
@@ -3215,7 +3224,7 @@ var require_restPositionals = __commonJS({
3215
3224
  };
3216
3225
  })();
3217
3226
  Object.defineProperty(exports2, "__esModule", { value: true });
3218
- exports2.restPositionals = restPositionals4;
3227
+ exports2.restPositionals = restPositionals5;
3219
3228
  var Result = __importStar(require_Result());
3220
3229
  var types_1 = require_types();
3221
3230
  function fullRestPositionals(config) {
@@ -3238,14 +3247,14 @@ var require_restPositionals = __commonJS({
3238
3247
  const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
3239
3248
  const results = [];
3240
3249
  const errors = [];
3241
- for (const positional9 of positionals) {
3242
- visitedNodes.add(positional9);
3243
- const decoded = await Result.safeAsync(config.type.from(positional9.raw));
3250
+ for (const positional8 of positionals) {
3251
+ visitedNodes.add(positional8);
3252
+ const decoded = await Result.safeAsync(config.type.from(positional8.raw));
3244
3253
  if (Result.isOk(decoded)) {
3245
3254
  results.push(decoded.value);
3246
3255
  } else {
3247
3256
  errors.push({
3248
- nodes: [positional9],
3257
+ nodes: [positional8],
3249
3258
  message: decoded.error.message
3250
3259
  });
3251
3260
  }
@@ -3259,7 +3268,7 @@ var require_restPositionals = __commonJS({
3259
3268
  }
3260
3269
  };
3261
3270
  }
3262
- function restPositionals4(config) {
3271
+ function restPositionals5(config) {
3263
3272
  return fullRestPositionals({
3264
3273
  type: types_1.string,
3265
3274
  ...config
@@ -3343,15 +3352,15 @@ var require_multiflag = __commonJS({
3343
3352
  longNames: [config.long],
3344
3353
  shortNames: config.short ? [config.short] : []
3345
3354
  }).filter((x) => !visitedNodes.has(x));
3346
- for (const option18 of options) {
3347
- visitedNodes.add(option18);
3355
+ for (const option19 of options) {
3356
+ visitedNodes.add(option19);
3348
3357
  }
3349
3358
  const optionValues = [];
3350
3359
  const errors = [];
3351
- for (const option18 of options) {
3352
- const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option18.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3360
+ for (const option19 of options) {
3361
+ const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option19.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3353
3362
  if (Result.isErr(decoded)) {
3354
- errors.push({ nodes: [option18], message: decoded.error.message });
3363
+ errors.push({ nodes: [option19], message: decoded.error.message });
3355
3364
  } else {
3356
3365
  optionValues.push(decoded.value);
3357
3366
  }
@@ -3515,16 +3524,16 @@ var require_multioption = __commonJS({
3515
3524
  });
3516
3525
  }
3517
3526
  }
3518
- for (const option18 of options) {
3519
- visitedNodes.add(option18);
3527
+ for (const option19 of options) {
3528
+ visitedNodes.add(option19);
3520
3529
  }
3521
3530
  const optionValues = [];
3522
3531
  const errors = [];
3523
3532
  const flagNodes = [];
3524
- for (const option18 of options) {
3525
- const providedValue = (_a = option18.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3533
+ for (const option19 of options) {
3534
+ const providedValue = (_a = option19.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3526
3535
  if (providedValue === void 0) {
3527
- flagNodes.push(option18);
3536
+ flagNodes.push(option19);
3528
3537
  continue;
3529
3538
  }
3530
3539
  optionValues.push(providedValue);
@@ -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.33.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",
3890
- minimatch: "^10",
3901
+ "log-update": "^8.0.0",
3902
+ minimatch: "^10.2.6",
3903
+ open: "^11.0.0",
3891
3904
  semver: "^7.7.4",
3892
- undici: "^7",
3905
+ slug: "^11.0.0",
3906
+ undici: "^7.29.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_ts42 = __toESM(require_cjs());
3905
3919
 
3906
3920
  // apps/cli/src/infra/commands/LinterCommand.ts
3907
3921
  var import_cmd_ts = __toESM(require_cjs());
@@ -4030,6 +4044,10 @@ var PackmindEvent = class {
4030
4044
  var UserEvent = class extends PackmindEvent {
4031
4045
  };
4032
4046
 
4047
+ // packages/types/src/events/SystemEvent.ts
4048
+ var SystemEvent = class extends PackmindEvent {
4049
+ };
4050
+
4033
4051
  // packages/types/src/accounts/events/UserSignedUpEvent.ts
4034
4052
  var UserSignedUpEvent = class extends UserEvent {
4035
4053
  static {
@@ -4256,27 +4274,27 @@ function validateArtifactFileFormat(filePath, artifactType) {
4256
4274
  return { valid: true };
4257
4275
  }
4258
4276
 
4259
- // packages/types/src/recipes/RecipeId.ts
4260
- var createRecipeId = brandedIdFactory();
4277
+ // packages/types/src/commands/CommandId.ts
4278
+ var createCommandId = brandedIdFactory();
4261
4279
 
4262
- // packages/types/src/recipes/RecipeVersion.ts
4263
- var createRecipeVersionId = brandedIdFactory();
4280
+ // packages/types/src/commands/CommandVersion.ts
4281
+ var createCommandVersionId = brandedIdFactory();
4264
4282
 
4265
- // packages/types/src/recipes/events/CommandCreatedEvent.ts
4283
+ // packages/types/src/commands/events/CommandCreatedEvent.ts
4266
4284
  var CommandCreatedEvent = class extends UserEvent {
4267
4285
  static {
4268
4286
  this.eventName = "recipes.recipe.created";
4269
4287
  }
4270
4288
  };
4271
4289
 
4272
- // packages/types/src/recipes/events/CommandDeletedEvent.ts
4290
+ // packages/types/src/commands/events/CommandDeletedEvent.ts
4273
4291
  var CommandDeletedEvent = class extends UserEvent {
4274
4292
  static {
4275
4293
  this.eventName = "recipes.recipe.deleted";
4276
4294
  }
4277
4295
  };
4278
4296
 
4279
- // packages/types/src/recipes/events/CommandUpdatedEvent.ts
4297
+ // packages/types/src/commands/events/CommandUpdatedEvent.ts
4280
4298
  var CommandUpdatedEvent = class extends UserEvent {
4281
4299
  static {
4282
4300
  this.eventName = "recipes.recipe.updated";
@@ -4445,6 +4463,13 @@ var DeploymentCompletedEvent = class extends UserEvent {
4445
4463
  }
4446
4464
  };
4447
4465
 
4466
+ // packages/types/src/deployments/events/DistributionRecordedEvent.ts
4467
+ var DistributionRecordedEvent = class extends UserEvent {
4468
+ static {
4469
+ this.eventName = "deployments.distribution.recorded";
4470
+ }
4471
+ };
4472
+
4448
4473
  // packages/types/src/deployments/events/PackagesDeletedEvent.ts
4449
4474
  var PackagesDeletedEvent = class extends UserEvent {
4450
4475
  static {
@@ -4478,6 +4503,20 @@ var createGitProviderId = brandedIdFactory();
4478
4503
  // packages/types/src/git/OrganizationGitHubApp.ts
4479
4504
  var createOrganizationGitHubAppId = brandedIdFactory();
4480
4505
 
4506
+ // packages/types/src/git/events/RepositoryTrackingRemovedEvent.ts
4507
+ var RepositoryTrackingRemovedEvent = class extends UserEvent {
4508
+ static {
4509
+ this.eventName = "git.repository.tracking-removed";
4510
+ }
4511
+ };
4512
+
4513
+ // packages/types/src/git/events/RepositoryTrackingSetEvent.ts
4514
+ var RepositoryTrackingSetEvent = class extends UserEvent {
4515
+ static {
4516
+ this.eventName = "git.repository.tracking-set";
4517
+ }
4518
+ };
4519
+
4481
4520
  // packages/types/src/spaces/SpaceId.ts
4482
4521
  var createSpaceId = brandedIdFactory();
4483
4522
 
@@ -5282,6 +5321,86 @@ var LLM_PROVIDER_METADATA = {
5282
5321
  // packages/types/src/llm/AIProviderId.ts
5283
5322
  var createAIProviderId = brandedIdFactory();
5284
5323
 
5324
+ // packages/types/src/marketplaces/MarketplaceId.ts
5325
+ var createMarketplaceId = brandedIdFactory();
5326
+
5327
+ // packages/types/src/marketplaces/MarketplaceDescriptorFilename.ts
5328
+ var MARKETPLACE_DESCRIPTOR_PATHS = [
5329
+ ".claude-plugin/marketplace.json",
5330
+ "marketplace.json"
5331
+ ];
5332
+ var MARKETPLACE_DESCRIPTOR_FILENAME = MARKETPLACE_DESCRIPTOR_PATHS[0];
5333
+
5334
+ // packages/types/src/marketplaces/MarketplaceDistributionId.ts
5335
+ var createMarketplaceDistributionId = brandedIdFactory();
5336
+
5337
+ // packages/types/src/marketplaces/PluginInstallationId.ts
5338
+ var createPluginInstallationId = brandedIdFactory();
5339
+
5340
+ // packages/types/src/marketplaces/errors/GitProviderTokenInvalidError.ts
5341
+ var GitProviderTokenInvalidError = class _GitProviderTokenInvalidError extends Error {
5342
+ static {
5343
+ /**
5344
+ * Exact verbatim user-facing message defined by the feature spec.
5345
+ * Do not modify without coordinating with the spec / docs.
5346
+ */
5347
+ this.USER_FACING_MESSAGE = "The package could not be published. Reason: Invalid or expired Git token.";
5348
+ }
5349
+ constructor() {
5350
+ super(_GitProviderTokenInvalidError.USER_FACING_MESSAGE);
5351
+ this.name = "GitProviderTokenInvalidError";
5352
+ }
5353
+ };
5354
+
5355
+ // packages/types/src/marketplaces/events/MarketplaceLinkedEvent.ts
5356
+ var MarketplaceLinkedEvent = class extends UserEvent {
5357
+ static {
5358
+ this.eventName = "deployments.marketplace.linked";
5359
+ }
5360
+ };
5361
+
5362
+ // packages/types/src/marketplaces/events/MarketplacePluginRemovalInitiatedEvent.ts
5363
+ var MarketplacePluginRemovalInitiatedEvent = class extends UserEvent {
5364
+ static {
5365
+ this.eventName = "deployments.distribution.retired";
5366
+ }
5367
+ };
5368
+
5369
+ // packages/types/src/marketplaces/events/MarketplaceUnlinkedEvent.ts
5370
+ var MarketplaceUnlinkedEvent = class extends UserEvent {
5371
+ static {
5372
+ this.eventName = "deployments.marketplace.unlinked";
5373
+ }
5374
+ };
5375
+
5376
+ // packages/types/src/marketplaces/events/PluginInstallTrackedEvent.ts
5377
+ var PluginInstallTrackedEvent = class extends SystemEvent {
5378
+ static {
5379
+ this.eventName = "deployments.plugin.install-tracked";
5380
+ }
5381
+ };
5382
+
5383
+ // packages/types/src/marketplaces/events/PluginPublishAttemptedEvent.ts
5384
+ var PluginPublishAttemptedEvent = class extends UserEvent {
5385
+ static {
5386
+ this.eventName = "deployments.plugin.publish-attempted";
5387
+ }
5388
+ };
5389
+
5390
+ // packages/types/src/marketplaces/events/PluginPublishFailedEvent.ts
5391
+ var PluginPublishFailedEvent = class extends UserEvent {
5392
+ static {
5393
+ this.eventName = "deployments.plugin.publish-failed";
5394
+ }
5395
+ };
5396
+
5397
+ // packages/types/src/marketplaces/events/PluginPublishedEvent.ts
5398
+ var PluginPublishedEvent = class extends UserEvent {
5399
+ static {
5400
+ this.eventName = "deployments.plugin.published";
5401
+ }
5402
+ };
5403
+
5285
5404
  // packages/types/src/playbookChangeManagement/ChangeProposalId.ts
5286
5405
  var createChangeProposalId = brandedIdFactory();
5287
5406
 
@@ -5392,8 +5511,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
5392
5511
  static {
5393
5512
  this.fallbackRuleContent = "adhoc-rule";
5394
5513
  }
5395
- async execute(command30) {
5396
- const { program, fileContent, language } = command30;
5514
+ async execute(command32) {
5515
+ const { program, fileContent, language } = command32;
5397
5516
  const result = await this.linterExecutionUseCase.execute({
5398
5517
  filePath: "cli-single-file",
5399
5518
  fileContent,
@@ -5777,8 +5896,8 @@ var GetGitRemoteUrlUseCase = class {
5777
5896
  constructor(gitRemoteUrlService = new GitService()) {
5778
5897
  this.gitRemoteUrlService = gitRemoteUrlService;
5779
5898
  }
5780
- async execute(command30) {
5781
- const { path: repoPath, origin: origin9 } = command30;
5899
+ async execute(command32) {
5900
+ const { path: repoPath, origin: origin9 } = command32;
5782
5901
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5783
5902
  }
5784
5903
  };
@@ -5930,8 +6049,8 @@ var ListFilesInDirectoryUseCase = class {
5930
6049
  constructor(listFiles = new ListFiles()) {
5931
6050
  this.listFiles = listFiles;
5932
6051
  }
5933
- async execute(command30) {
5934
- const { path: directoryPath, extensions, excludes = [] } = command30;
6052
+ async execute(command32) {
6053
+ const { path: directoryPath, extensions, excludes = [] } = command32;
5935
6054
  const files = await this.listFiles.listFilesInDirectory(
5936
6055
  directoryPath,
5937
6056
  extensions,
@@ -6046,7 +6165,7 @@ var LintFilesAgainstRuleUseCase = class {
6046
6165
  };
6047
6166
  };
6048
6167
  }
6049
- async execute(command30) {
6168
+ async execute(command32) {
6050
6169
  const {
6051
6170
  path: userPath,
6052
6171
  draftMode,
@@ -6055,7 +6174,7 @@ var LintFilesAgainstRuleUseCase = class {
6055
6174
  language,
6056
6175
  diffMode,
6057
6176
  ignorePatterns
6058
- } = command30;
6177
+ } = command32;
6059
6178
  this.logger.debug(
6060
6179
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
6061
6180
  );
@@ -6371,8 +6490,8 @@ var LintFilesAgainstRuleUseCase = class {
6371
6490
  return null;
6372
6491
  }
6373
6492
  }
6374
- async executeProgramsForFile(command30) {
6375
- const result = await this.services.linterExecutionUseCase.execute(command30);
6493
+ async executeProgramsForFile(command32) {
6494
+ const result = await this.services.linterExecutionUseCase.execute(command32);
6376
6495
  return result.violations;
6377
6496
  }
6378
6497
  extractExtensionFromFile(filePath) {
@@ -6395,8 +6514,8 @@ var LintFilesFromConfigUseCase = class {
6395
6514
  this.logger = logger2;
6396
6515
  this.detectionProgramsCache = /* @__PURE__ */ new Map();
6397
6516
  }
6398
- async execute(command30) {
6399
- const { path: userPath, diffMode, ignorePatterns } = command30;
6517
+ async execute(command32) {
6518
+ const { path: userPath, diffMode, ignorePatterns } = command32;
6400
6519
  this.logger.debug(
6401
6520
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
6402
6521
  );
@@ -6656,8 +6775,8 @@ var LintFilesFromConfigUseCase = class {
6656
6775
  return null;
6657
6776
  }
6658
6777
  }
6659
- async executeProgramsForFile(command30) {
6660
- const result = await this.services.linterExecutionUseCase.execute(command30);
6778
+ async executeProgramsForFile(command32) {
6779
+ const result = await this.services.linterExecutionUseCase.execute(command32);
6661
6780
  return result.violations;
6662
6781
  }
6663
6782
  extractExtensionFromFile(filePath) {
@@ -6673,7 +6792,7 @@ var LintFilesFromConfigUseCase = class {
6673
6792
  var NotLoggedInError = class extends Error {
6674
6793
  constructor() {
6675
6794
  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)."
6795
+ "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
6796
  );
6678
6797
  this.name = "NotLoggedInError";
6679
6798
  }
@@ -6833,13 +6952,13 @@ var PackmindHttpClient = class {
6833
6952
  var ChangeProposalGateway = class {
6834
6953
  constructor(httpClient) {
6835
6954
  this.httpClient = httpClient;
6836
- this.batchCreate = async (command30) => {
6955
+ this.batchCreate = async (command32) => {
6837
6956
  const { organizationId } = this.httpClient.getAuthContext();
6838
6957
  return this.httpClient.request(
6839
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/batch`,
6958
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/change-proposals/batch`,
6840
6959
  {
6841
6960
  method: "POST",
6842
- body: { proposals: command30.proposals },
6961
+ body: { proposals: command32.proposals },
6843
6962
  onError: (response) => {
6844
6963
  if (response.status === 404) {
6845
6964
  throw new CommunityEditionError("change proposals");
@@ -6848,29 +6967,29 @@ var ChangeProposalGateway = class {
6848
6967
  }
6849
6968
  );
6850
6969
  };
6851
- this.batchApply = async (command30) => {
6970
+ this.batchApply = async (command32) => {
6852
6971
  const { organizationId } = this.httpClient.getAuthContext();
6853
6972
  return this.httpClient.request(
6854
6973
  `/api/v0/organizations/${organizationId}/playbook/apply`,
6855
6974
  {
6856
6975
  method: "POST",
6857
6976
  body: {
6858
- proposals: command30.proposals,
6859
- message: command30.message,
6860
- ...command30.directUpdate !== void 0 && {
6861
- directUpdate: command30.directUpdate
6977
+ proposals: command32.proposals,
6978
+ message: command32.message,
6979
+ ...command32.directUpdate !== void 0 && {
6980
+ directUpdate: command32.directUpdate
6862
6981
  }
6863
6982
  }
6864
6983
  }
6865
6984
  );
6866
6985
  };
6867
- this.check = async (command30) => {
6986
+ this.check = async (command32) => {
6868
6987
  const { organizationId } = this.httpClient.getAuthContext();
6869
6988
  return this.httpClient.request(
6870
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/check`,
6989
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/change-proposals/check`,
6871
6990
  {
6872
6991
  method: "POST",
6873
- body: { proposals: command30.proposals },
6992
+ body: { proposals: command32.proposals },
6874
6993
  onError: (response) => {
6875
6994
  if (response.status === 404) {
6876
6995
  throw new CommunityEditionError("change proposals");
@@ -6886,13 +7005,13 @@ var ChangeProposalGateway = class {
6886
7005
  var LinterGateway = class {
6887
7006
  constructor(httpClient) {
6888
7007
  this.httpClient = httpClient;
6889
- this.getDraftDetectionProgramsForRule = async (command30) => {
7008
+ this.getDraftDetectionProgramsForRule = async (command32) => {
6890
7009
  const payload = {
6891
- standardSlug: command30.standardSlug,
6892
- ruleId: command30.ruleId
7010
+ standardSlug: command32.standardSlug,
7011
+ ruleId: command32.ruleId
6893
7012
  };
6894
- if (command30.language) {
6895
- payload.language = command30.language;
7013
+ if (command32.language) {
7014
+ payload.language = command32.language;
6896
7015
  }
6897
7016
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
6898
7017
  method: "POST",
@@ -6904,13 +7023,13 @@ var LinterGateway = class {
6904
7023
  }
6905
7024
  });
6906
7025
  };
6907
- this.getActiveDetectionProgramsForRule = async (command30) => {
7026
+ this.getActiveDetectionProgramsForRule = async (command32) => {
6908
7027
  const payload = {
6909
- standardSlug: command30.standardSlug,
6910
- ruleId: command30.ruleId
7028
+ standardSlug: command32.standardSlug,
7029
+ ruleId: command32.ruleId
6911
7030
  };
6912
- if (command30.language) {
6913
- payload.language = command30.language;
7031
+ if (command32.language) {
7032
+ payload.language = command32.language;
6914
7033
  }
6915
7034
  return this.httpClient.request("/api/v0/list-active-detection-program", {
6916
7035
  method: "POST",
@@ -6922,13 +7041,13 @@ var LinterGateway = class {
6922
7041
  }
6923
7042
  });
6924
7043
  };
6925
- this.getDetectionProgramsForPackages = async (command30) => {
7044
+ this.getDetectionProgramsForPackages = async (command32) => {
6926
7045
  const response = await this.httpClient.request(
6927
7046
  "/api/v0/detection-programs-for-packages",
6928
7047
  {
6929
7048
  method: "POST",
6930
7049
  body: {
6931
- packagesSlugs: command30.packagesSlugs
7050
+ packagesSlugs: command32.packagesSlugs
6932
7051
  },
6933
7052
  onError: (response2) => {
6934
7053
  if (response2.status === 404) {
@@ -6939,10 +7058,10 @@ var LinterGateway = class {
6939
7058
  );
6940
7059
  return handleScopeInTargetsResponse(response);
6941
7060
  };
6942
- this.trackLinterExecution = async (command30) => {
7061
+ this.trackLinterExecution = async (command32) => {
6943
7062
  return this.httpClient.request(`/api/v0/track-execution`, {
6944
7063
  method: "POST",
6945
- body: command30
7064
+ body: command32
6946
7065
  });
6947
7066
  };
6948
7067
  }
@@ -6996,27 +7115,27 @@ var SpacesGateway = class {
6996
7115
  var SkillsGateway = class {
6997
7116
  constructor(httpClient) {
6998
7117
  this.httpClient = httpClient;
6999
- this.upload = async (command30) => {
7118
+ this.upload = async (command32) => {
7000
7119
  const { organizationId } = this.httpClient.getAuthContext();
7001
7120
  return this.httpClient.request(
7002
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills/upload`,
7121
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/skills/upload`,
7003
7122
  {
7004
7123
  method: "POST",
7005
- body: command30
7124
+ body: command32
7006
7125
  }
7007
7126
  );
7008
7127
  };
7009
- this.getDefaults = async (command30) => {
7128
+ this.getDefaults = async (command32) => {
7010
7129
  const { organizationId } = this.httpClient.getAuthContext();
7011
7130
  const queryParams = new URLSearchParams();
7012
- if (command30.includeBeta) {
7131
+ if (command32.includeBeta) {
7013
7132
  queryParams.set("includeBeta", "true");
7014
- } else if (command30.cliVersion) {
7015
- queryParams.set("cliVersion", command30.cliVersion);
7133
+ } else if (command32.cliVersion) {
7134
+ queryParams.set("cliVersion", command32.cliVersion);
7016
7135
  }
7017
- if (command30.agents !== void 0) {
7136
+ if (command32.agents !== void 0) {
7018
7137
  queryParams.append("agentsConfigOverride", "true");
7019
- command30.agents.forEach((agent) => {
7138
+ command32.agents.forEach((agent) => {
7020
7139
  queryParams.append("agent", agent);
7021
7140
  });
7022
7141
  }
@@ -7025,10 +7144,10 @@ var SkillsGateway = class {
7025
7144
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
7026
7145
  );
7027
7146
  };
7028
- this.list = async (command30) => {
7147
+ this.list = async (command32) => {
7029
7148
  const { organizationId } = this.httpClient.getAuthContext();
7030
7149
  return this.httpClient.request(
7031
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills`
7150
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/skills`
7032
7151
  );
7033
7152
  };
7034
7153
  }
@@ -7038,22 +7157,24 @@ var SkillsGateway = class {
7038
7157
  var CommandsGateway = class {
7039
7158
  constructor(httpClient) {
7040
7159
  this.httpClient = httpClient;
7041
- this.create = async (command30) => {
7160
+ this.create = async (command32) => {
7042
7161
  const { organizationId } = this.httpClient.getAuthContext();
7043
7162
  return this.httpClient.request(
7044
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`,
7045
- { method: "POST", body: command30 }
7163
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/commands`,
7164
+ { method: "POST", body: command32 }
7046
7165
  );
7047
7166
  };
7048
- this.list = async (command30) => {
7167
+ this.list = async (command32) => {
7049
7168
  const { organizationId } = this.httpClient.getAuthContext();
7050
- const listRecipesResponse = await this.httpClient.request(
7051
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`
7169
+ const listCommandsResponse = await this.httpClient.request(
7170
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/commands`
7052
7171
  );
7053
- if (listRecipesResponse instanceof Array) {
7054
- return { recipes: listRecipesResponse };
7172
+ if (listCommandsResponse instanceof Array) {
7173
+ return { recipes: listCommandsResponse };
7055
7174
  }
7056
- return listRecipesResponse;
7175
+ return {
7176
+ recipes: listCommandsResponse.commands ?? listCommandsResponse.recipes ?? []
7177
+ };
7057
7178
  };
7058
7179
  }
7059
7180
  };
@@ -7089,10 +7210,10 @@ var StandardsGateway = class {
7089
7210
  }
7090
7211
  );
7091
7212
  };
7092
- this.list = async (command30) => {
7213
+ this.list = async (command32) => {
7093
7214
  const { organizationId } = this.httpClient.getAuthContext();
7094
7215
  return this.httpClient.request(
7095
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/standards`
7216
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/standards`
7096
7217
  );
7097
7218
  };
7098
7219
  }
@@ -7103,10 +7224,10 @@ var PackagesGateway = class {
7103
7224
  constructor(apiKey, httpClient) {
7104
7225
  this.apiKey = apiKey;
7105
7226
  this.httpClient = httpClient;
7106
- this.list = async (command30) => {
7227
+ this.list = async (command32) => {
7107
7228
  const { organizationId } = this.httpClient.getAuthContext();
7108
7229
  return this.httpClient.request(
7109
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`
7230
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/packages`
7110
7231
  );
7111
7232
  };
7112
7233
  this.getSummary = async ({
@@ -7118,24 +7239,25 @@ var PackagesGateway = class {
7118
7239
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug6)}`
7119
7240
  );
7120
7241
  };
7121
- this.create = async (command30) => {
7242
+ this.create = async (command32) => {
7122
7243
  const { organizationId } = this.httpClient.getAuthContext();
7244
+ const { recipeIds, ...rest } = command32;
7123
7245
  return this.httpClient.request(
7124
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`,
7246
+ `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/packages`,
7125
7247
  {
7126
7248
  method: "POST",
7127
- body: command30
7249
+ body: { ...rest, commandIds: recipeIds }
7128
7250
  }
7129
7251
  );
7130
7252
  };
7131
- this.addArtefacts = async (command30) => {
7253
+ this.addArtefacts = async (command32) => {
7132
7254
  const { organizationId } = this.httpClient.getAuthContext();
7133
- const { packageId, spaceId } = command30;
7255
+ const { packageId, spaceId, recipeIds, ...rest } = command32;
7134
7256
  return this.httpClient.request(
7135
7257
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
7136
7258
  {
7137
7259
  method: "POST",
7138
- body: command30
7260
+ body: { ...rest, packageId, spaceId, commandIds: recipeIds }
7139
7261
  }
7140
7262
  );
7141
7263
  };
@@ -7146,31 +7268,31 @@ var PackagesGateway = class {
7146
7268
  var DeploymentGateway = class {
7147
7269
  constructor(httpClient) {
7148
7270
  this.httpClient = httpClient;
7149
- this.pull = async (command30) => {
7271
+ this.pull = async (command32) => {
7150
7272
  const { organizationId } = this.httpClient.getAuthContext();
7151
7273
  const queryParams = new URLSearchParams();
7152
- if (command30.packagesSlugs && command30.packagesSlugs.length > 0) {
7153
- command30.packagesSlugs.forEach((slug6) => {
7274
+ if (command32.packagesSlugs && command32.packagesSlugs.length > 0) {
7275
+ command32.packagesSlugs.forEach((slug6) => {
7154
7276
  queryParams.append("packageSlug", slug6);
7155
7277
  });
7156
7278
  }
7157
- if (command30.previousPackagesSlugs && command30.previousPackagesSlugs.length > 0) {
7158
- command30.previousPackagesSlugs.forEach((slug6) => {
7279
+ if (command32.previousPackagesSlugs && command32.previousPackagesSlugs.length > 0) {
7280
+ command32.previousPackagesSlugs.forEach((slug6) => {
7159
7281
  queryParams.append("previousPackageSlug", slug6);
7160
7282
  });
7161
7283
  }
7162
- if (command30.gitRemoteUrl) {
7163
- queryParams.append("gitRemoteUrl", command30.gitRemoteUrl);
7284
+ if (command32.gitRemoteUrl) {
7285
+ queryParams.append("gitRemoteUrl", command32.gitRemoteUrl);
7164
7286
  }
7165
- if (command30.gitBranch) {
7166
- queryParams.append("gitBranch", command30.gitBranch);
7287
+ if (command32.gitBranch) {
7288
+ queryParams.append("gitBranch", command32.gitBranch);
7167
7289
  }
7168
- if (command30.relativePath) {
7169
- queryParams.append("relativePath", command30.relativePath);
7290
+ if (command32.relativePath) {
7291
+ queryParams.append("relativePath", command32.relativePath);
7170
7292
  }
7171
- if (command30.agents !== void 0) {
7293
+ if (command32.agents !== void 0) {
7172
7294
  queryParams.append("agentsConfigOverride", "true");
7173
- command30.agents.forEach((agent) => {
7295
+ command32.agents.forEach((agent) => {
7174
7296
  queryParams.append("agent", agent);
7175
7297
  });
7176
7298
  }
@@ -7178,101 +7300,101 @@ var DeploymentGateway = class {
7178
7300
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
7179
7301
  );
7180
7302
  };
7181
- this.install = async (command30) => {
7303
+ this.install = async (command32) => {
7182
7304
  const { organizationId } = this.httpClient.getAuthContext();
7183
7305
  return this.httpClient.request(
7184
7306
  `/api/v0/organizations/${organizationId}/install`,
7185
7307
  {
7186
7308
  method: "POST",
7187
7309
  body: {
7188
- packagesSlugs: command30.packagesSlugs,
7189
- packmindLockFile: command30.packmindLockFile,
7190
- ...command30.relativePath && { relativePath: command30.relativePath },
7191
- ...command30.agents !== void 0 && { agents: command30.agents }
7310
+ packagesSlugs: command32.packagesSlugs,
7311
+ packmindLockFile: command32.packmindLockFile,
7312
+ ...command32.relativePath && { relativePath: command32.relativePath },
7313
+ ...command32.agents !== void 0 && { agents: command32.agents }
7192
7314
  }
7193
7315
  }
7194
7316
  );
7195
7317
  };
7196
- this.getDeployed = async (command30) => {
7318
+ this.getDeployed = async (command32) => {
7197
7319
  const { organizationId } = this.httpClient.getAuthContext();
7198
7320
  return this.httpClient.request(
7199
7321
  `/api/v0/organizations/${organizationId}/deployed-content`,
7200
7322
  {
7201
7323
  method: "POST",
7202
7324
  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 }
7325
+ packagesSlugs: command32.packagesSlugs,
7326
+ gitRemoteUrl: command32.gitRemoteUrl,
7327
+ gitBranch: command32.gitBranch,
7328
+ relativePath: command32.relativePath,
7329
+ ...command32.agents !== void 0 && { agents: command32.agents }
7208
7330
  }
7209
7331
  }
7210
7332
  );
7211
7333
  };
7212
- this.getContentByVersions = async (command30) => {
7334
+ this.getContentByVersions = async (command32) => {
7213
7335
  const { organizationId } = this.httpClient.getAuthContext();
7214
7336
  return this.httpClient.request(
7215
7337
  `/api/v0/organizations/${organizationId}/content-by-versions`,
7216
7338
  {
7217
7339
  method: "POST",
7218
7340
  body: {
7219
- artifacts: command30.artifacts,
7220
- ...command30.agents !== void 0 && { agents: command30.agents }
7341
+ artifacts: command32.artifacts,
7342
+ ...command32.agents !== void 0 && { agents: command32.agents }
7221
7343
  }
7222
7344
  }
7223
7345
  );
7224
7346
  };
7225
- this.notifyDistribution = async (command30) => {
7347
+ this.notifyDistribution = async (command32) => {
7226
7348
  const { organizationId } = this.httpClient.getAuthContext();
7227
7349
  return this.httpClient.request(
7228
7350
  `/api/v0/organizations/${organizationId}/deployments`,
7229
7351
  {
7230
7352
  method: "POST",
7231
- body: command30
7353
+ body: command32
7232
7354
  }
7233
7355
  );
7234
7356
  };
7235
- this.notifyArtefactsDistribution = async (command30) => {
7357
+ this.notifyArtefactsDistribution = async (command32) => {
7236
7358
  const { organizationId } = this.httpClient.getAuthContext();
7237
7359
  return this.httpClient.request(
7238
7360
  `/api/v0/organizations/${organizationId}/deployments/notify-artifacts-distribution`,
7239
7361
  {
7240
7362
  method: "POST",
7241
7363
  body: {
7242
- gitRemoteUrl: command30.gitRemoteUrl,
7243
- gitBranch: command30.gitBranch,
7244
- relativePath: command30.relativePath,
7245
- packmindLockFile: command30.packmindLockFile
7364
+ gitRemoteUrl: command32.gitRemoteUrl,
7365
+ gitBranch: command32.gitBranch,
7366
+ relativePath: command32.relativePath,
7367
+ packmindLockFile: command32.packmindLockFile
7246
7368
  }
7247
7369
  }
7248
7370
  );
7249
7371
  };
7250
- this.renderPlugin = async (command30) => {
7372
+ this.renderPlugin = async (command32) => {
7251
7373
  const { organizationId } = this.httpClient.getAuthContext();
7252
7374
  return this.httpClient.request(
7253
7375
  `/api/v0/organizations/${organizationId}/plugins/render`,
7254
7376
  {
7255
7377
  method: "POST",
7256
7378
  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
7379
+ packageSlug: command32.packageSlug,
7380
+ mode: command32.mode,
7381
+ pluginRoot: command32.pluginRoot,
7382
+ pluginName: command32.pluginName,
7383
+ gitRemoteUrl: command32.gitRemoteUrl,
7384
+ gitBranch: command32.gitBranch
7263
7385
  }
7264
7386
  }
7265
7387
  );
7266
7388
  };
7267
- this.trackPluginDeleted = async (command30) => {
7389
+ this.trackPluginDeleted = async (command32) => {
7268
7390
  const { organizationId } = this.httpClient.getAuthContext();
7269
7391
  return this.httpClient.request(
7270
7392
  `/api/v0/organizations/${organizationId}/plugins/track-deleted`,
7271
7393
  {
7272
7394
  method: "POST",
7273
7395
  body: {
7274
- packageSlug: command30.packageSlug,
7275
- gitRemoteUrl: command30.gitRemoteUrl
7396
+ packageSlug: command32.packageSlug,
7397
+ gitRemoteUrl: command32.gitRemoteUrl
7276
7398
  }
7277
7399
  }
7278
7400
  );
@@ -7284,13 +7406,13 @@ var DeploymentGateway = class {
7284
7406
  );
7285
7407
  };
7286
7408
  }
7287
- async updateRenderModeConfiguration(command30) {
7409
+ async updateRenderModeConfiguration(command32) {
7288
7410
  const { organizationId } = this.httpClient.getAuthContext();
7289
7411
  await this.httpClient.request(
7290
7412
  `/api/v0/organizations/${organizationId}/deployments/renderModeConfiguration`,
7291
7413
  {
7292
7414
  method: "POST",
7293
- body: { activeRenderModes: command30.activeRenderModes }
7415
+ body: { activeRenderModes: command32.activeRenderModes }
7294
7416
  }
7295
7417
  );
7296
7418
  }
@@ -7298,7 +7420,7 @@ var DeploymentGateway = class {
7298
7420
  const { organizationId } = this.httpClient.getAuthContext();
7299
7421
  const typeToPath = {
7300
7422
  standard: "standards",
7301
- command: "recipes",
7423
+ command: "commands",
7302
7424
  skill: "skills"
7303
7425
  };
7304
7426
  const pathSegment = typeToPath[type];
@@ -7333,6 +7455,45 @@ var OrganizationGateway = class {
7333
7455
  }
7334
7456
  };
7335
7457
 
7458
+ // apps/cli/src/infra/repositories/RepositoryTrackingGateway.ts
7459
+ var RepositoryTrackingGateway = class {
7460
+ constructor(httpClient) {
7461
+ this.httpClient = httpClient;
7462
+ this.getTrackedRepository = async ({
7463
+ owner,
7464
+ repo
7465
+ }) => {
7466
+ const { organizationId } = this.httpClient.getAuthContext();
7467
+ const query = new URLSearchParams({ owner, repo }).toString();
7468
+ return this.httpClient.request(
7469
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository?${query}`
7470
+ );
7471
+ };
7472
+ this.setTrackedRepository = async (command32) => {
7473
+ const { organizationId } = this.httpClient.getAuthContext();
7474
+ return this.httpClient.request(
7475
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7476
+ { method: "POST", body: command32 }
7477
+ );
7478
+ };
7479
+ this.updateTrackedBranch = async (command32) => {
7480
+ const { organizationId } = this.httpClient.getAuthContext();
7481
+ return this.httpClient.request(
7482
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7483
+ { method: "PUT", body: command32 }
7484
+ );
7485
+ };
7486
+ this.removeTrackedRepository = async ({ owner, repo }) => {
7487
+ const { organizationId } = this.httpClient.getAuthContext();
7488
+ const query = new URLSearchParams({ owner, repo }).toString();
7489
+ return this.httpClient.request(
7490
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository?${query}`,
7491
+ { method: "DELETE" }
7492
+ );
7493
+ };
7494
+ }
7495
+ };
7496
+
7336
7497
  // apps/cli/src/infra/repositories/PackmindGateway.ts
7337
7498
  var PackmindGateway = class {
7338
7499
  constructor(apiKey) {
@@ -7347,6 +7508,7 @@ var PackmindGateway = class {
7347
7508
  this.packages = new PackagesGateway(apiKey, this.httpClient);
7348
7509
  this.deployment = new DeploymentGateway(this.httpClient);
7349
7510
  this.organization = new OrganizationGateway(this.httpClient);
7511
+ this.repositoryTracking = new RepositoryTrackingGateway(this.httpClient);
7350
7512
  }
7351
7513
  };
7352
7514
 
@@ -9090,8 +9252,8 @@ var ExecuteLinterProgramsUseCase = class {
9090
9252
  this.linterAstAdapter = linterAstAdapter;
9091
9253
  this.logger = logger2;
9092
9254
  }
9093
- async execute(command30) {
9094
- const { filePath, fileContent, language, programs } = command30;
9255
+ async execute(command32) {
9256
+ const { filePath, fileContent, language, programs } = command32;
9095
9257
  if (programs.length === 0) {
9096
9258
  return {
9097
9259
  file: filePath,
@@ -9687,6 +9849,17 @@ var Cache = class _Cache {
9687
9849
  }
9688
9850
  };
9689
9851
 
9852
+ // packages/feature-flags/src/registry.ts
9853
+ var ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY = "change-proposals-in-webapp";
9854
+ var ORGA_SPACE_MANAGEMENT_FEATURE_KEY = "orga-space-management";
9855
+ var DEFAULT_FEATURE_DOMAIN_MAP = {
9856
+ [ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY]: [
9857
+ "@packmind.com",
9858
+ "@promyze.com"
9859
+ ],
9860
+ [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9861
+ };
9862
+
9690
9863
  // packages/node-utils/src/database/schemas.ts
9691
9864
  var uuidSchema = {
9692
9865
  id: {
@@ -9741,6 +9914,11 @@ var import_common2 = require("@nestjs/common");
9741
9914
  // packages/node-utils/src/sse/RedisSSEClient.ts
9742
9915
  var import_ioredis2 = __toESM(require("ioredis"));
9743
9916
 
9917
+ // packages/node-utils/src/text/normalizeLineEndings.ts
9918
+ function normalizeLineEndings(content) {
9919
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
9920
+ }
9921
+
9744
9922
  // packages/node-utils/src/text/sectionMerge.ts
9745
9923
  function mergeSectionsIntoFileContent(existingContent, sections) {
9746
9924
  let result = existingContent;
@@ -9910,8 +10088,8 @@ var InstallPackagesUseCase = class {
9910
10088
  constructor(packmindGateway) {
9911
10089
  this.packmindGateway = packmindGateway;
9912
10090
  }
9913
- async execute(command30) {
9914
- const baseDirectory = command30.baseDirectory || process.cwd();
10091
+ async execute(command32) {
10092
+ const baseDirectory = command32.baseDirectory || process.cwd();
9915
10093
  const result = {
9916
10094
  filesCreated: 0,
9917
10095
  filesUpdated: 0,
@@ -9923,12 +10101,12 @@ var InstallPackagesUseCase = class {
9923
10101
  skillDirectoriesDeleted: 0
9924
10102
  };
9925
10103
  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
10104
+ packagesSlugs: command32.packagesSlugs,
10105
+ previousPackagesSlugs: command32.previousPackagesSlugs,
10106
+ gitRemoteUrl: command32.gitRemoteUrl,
10107
+ gitBranch: command32.gitBranch,
10108
+ relativePath: command32.relativePath,
10109
+ agents: command32.agents
9932
10110
  });
9933
10111
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
9934
10112
  (file) => file.path !== "packmind.json"
@@ -10303,8 +10481,8 @@ var InstallUseCase = class {
10303
10481
  this.configFileRepository = configFileRepository;
10304
10482
  this.spaceService = spaceService;
10305
10483
  }
10306
- async execute(command30) {
10307
- const baseDirectory = command30.baseDirectory || process.cwd();
10484
+ async execute(command32) {
10485
+ const baseDirectory = command32.baseDirectory || process.cwd();
10308
10486
  const result = {
10309
10487
  filesCreated: 0,
10310
10488
  filesUpdated: 0,
@@ -10334,7 +10512,7 @@ var InstallUseCase = class {
10334
10512
  },
10335
10513
  resolvedAgents: []
10336
10514
  };
10337
- const hasExplicitPackages = command30.packages && command30.packages.length > 0;
10515
+ const hasExplicitPackages = command32.packages && command32.packages.length > 0;
10338
10516
  const configExistedBefore = await this.configFileRepository.configExists(baseDirectory);
10339
10517
  const lockFile = await this.lockFileRepository.read(baseDirectory);
10340
10518
  const config = await this.configFileRepository.readConfig(baseDirectory);
@@ -10354,14 +10532,13 @@ var InstallUseCase = class {
10354
10532
  lockfileVersion: 1,
10355
10533
  packageSlugs: [],
10356
10534
  agents: [],
10357
- artifacts: {},
10358
- ...command30.skipInstalledAt ? {} : { installedAt: (/* @__PURE__ */ new Date()).toISOString() }
10535
+ artifacts: {}
10359
10536
  };
10360
- effectiveLockFile.cliVersion = command30.cliVersion;
10537
+ effectiveLockFile.cliVersion = command32.cliVersion;
10361
10538
  let packagesSlugs;
10362
10539
  let normalizedPackages = [];
10363
10540
  if (hasExplicitPackages) {
10364
- const explicitPackageSlugs = (command30.packages ?? []).map(
10541
+ const explicitPackageSlugs = (command32.packages ?? []).map(
10365
10542
  displayableParsedPackageSlug
10366
10543
  );
10367
10544
  normalizedPackages = await this.normalizePackageSlugs(explicitPackageSlugs);
@@ -10391,8 +10568,8 @@ var InstallUseCase = class {
10391
10568
  }
10392
10569
  return result;
10393
10570
  }
10394
- const installAgents = this.resolveInstallAgents(command30, config);
10395
- const stripPathPrefix = command30.homeAgent ? getAgentHomeDirPrefix(command30.homeAgent) ?? void 0 : void 0;
10571
+ const installAgents = this.resolveInstallAgents(command32, config);
10572
+ const stripPathPrefix = command32.homeAgent ? getAgentHomeDirPrefix(command32.homeAgent) ?? void 0 : void 0;
10396
10573
  const response = await this.packmindGateway.deployment.install({
10397
10574
  packagesSlugs,
10398
10575
  packmindLockFile: effectiveLockFile,
@@ -10532,10 +10709,7 @@ var InstallUseCase = class {
10532
10709
  } catch {
10533
10710
  }
10534
10711
  }
10535
- if (command30.skipInstalledAt) {
10536
- delete lockFileToPersist.installedAt;
10537
- }
10538
- lockFileToPersist.cliVersion = command30.cliVersion;
10712
+ lockFileToPersist.cliVersion = command32.cliVersion;
10539
10713
  if (stripPathPrefix) {
10540
10714
  lockFileToPersist = this.stripLockFileArtifactPaths(
10541
10715
  lockFileToPersist,
@@ -10564,9 +10738,9 @@ var InstallUseCase = class {
10564
10738
  async normalizePackageSlugs(slugs) {
10565
10739
  return normalizePackageSlugs(slugs, this.spaceService);
10566
10740
  }
10567
- resolveInstallAgents(command30, config) {
10568
- if (command30.homeAgent) {
10569
- return [command30.homeAgent];
10741
+ resolveInstallAgents(command32, config) {
10742
+ if (command32.homeAgent) {
10743
+ return [command32.homeAgent];
10570
10744
  }
10571
10745
  return config?.agents;
10572
10746
  }
@@ -10880,8 +11054,8 @@ var UninstallUseCase = class {
10880
11054
  this.spaceService = spaceService;
10881
11055
  this.installUseCase = installUseCase;
10882
11056
  }
10883
- async execute(command30) {
10884
- const baseDirectory = command30.baseDirectory || process.cwd();
11057
+ async execute(command32) {
11058
+ const baseDirectory = command32.baseDirectory || process.cwd();
10885
11059
  const config = await this.configFileRepository.readConfig(baseDirectory);
10886
11060
  if (!config) {
10887
11061
  const configFileExists = await this.configFileRepository.configExists(baseDirectory);
@@ -10895,7 +11069,7 @@ var UninstallUseCase = class {
10895
11069
  );
10896
11070
  }
10897
11071
  const normalized = await normalizePackageSlugs(
10898
- command30.packages,
11072
+ command32.packages,
10899
11073
  this.spaceService
10900
11074
  );
10901
11075
  const notInstalled = normalized.filter((pkg) => !(pkg in config.packages));
@@ -10918,7 +11092,7 @@ ${pkgList}`
10918
11092
  try {
10919
11093
  return await this.installUseCase.execute({
10920
11094
  baseDirectory,
10921
- cliVersion: command30.cliVersion
11095
+ cliVersion: command32.cliVersion
10922
11096
  });
10923
11097
  } catch (error) {
10924
11098
  await this.configFileRepository.updateConfig(
@@ -10960,8 +11134,8 @@ var InstallDefaultSkillsUseCase = class {
10960
11134
  constructor(repositories) {
10961
11135
  this.repositories = repositories;
10962
11136
  }
10963
- async execute(command30) {
10964
- const baseDirectory = command30.baseDirectory || process.cwd();
11137
+ async execute(command32) {
11138
+ const baseDirectory = command32.baseDirectory || process.cwd();
10965
11139
  await this.bootstrapEmptyDirectory(baseDirectory);
10966
11140
  const result = {
10967
11141
  filesCreated: 0,
@@ -10971,24 +11145,24 @@ var InstallDefaultSkillsUseCase = class {
10971
11145
  skippedIncompatibleSkillNames: [],
10972
11146
  incompatibleInstalledSkills: []
10973
11147
  };
10974
- let agents = command30.agents;
11148
+ let agents = command32.agents;
10975
11149
  if (!agents || agents.length === 0) {
10976
11150
  const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
10977
11151
  agents = config?.agents;
10978
11152
  }
10979
11153
  const response = await this.repositories.packmindGateway.skills.getDefaults(
10980
11154
  {
10981
- cliVersion: command30.cliVersion,
10982
- includeBeta: command30.includeBeta,
11155
+ cliVersion: command32.cliVersion,
11156
+ includeBeta: command32.includeBeta,
10983
11157
  agents
10984
11158
  }
10985
11159
  );
10986
11160
  result.skippedSkillsCount = response.skippedSkillsCount;
10987
11161
  const incompatibleInstalledMap = /* @__PURE__ */ new Map();
10988
11162
  const incompatibleSkillDirs = /* @__PURE__ */ new Map();
10989
- if (command30.cliVersion) {
11163
+ if (command32.cliVersion) {
10990
11164
  for (const file of response.fileUpdates.createOrUpdate) {
10991
- if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command30.cliVersion)) {
11165
+ if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command32.cliVersion)) {
10992
11166
  const dir = path9.dirname(file.path);
10993
11167
  const skillName = this.getSkillName(file.content) ?? path9.basename(dir);
10994
11168
  incompatibleSkillDirs.set(dir, skillName);
@@ -10999,9 +11173,9 @@ var InstallDefaultSkillsUseCase = class {
10999
11173
  for (const file of response.fileUpdates.createOrUpdate) {
11000
11174
  try {
11001
11175
  if (!file.content) continue;
11002
- const isIncompatible = command30.cliVersion && (this.isVersionConstraintViolated(
11176
+ const isIncompatible = command32.cliVersion && (this.isVersionConstraintViolated(
11003
11177
  file.content,
11004
- command30.cliVersion
11178
+ command32.cliVersion
11005
11179
  ) || this.isUnderIncompatibleSkillDir(
11006
11180
  file.path,
11007
11181
  incompatibleSkillDirs
@@ -11044,7 +11218,7 @@ var InstallDefaultSkillsUseCase = class {
11044
11218
  await this.mergeLockFileSlice(
11045
11219
  baseDirectory,
11046
11220
  response.lockFileSlice ?? {},
11047
- command30.cliVersion
11221
+ command32.cliVersion
11048
11222
  );
11049
11223
  return result;
11050
11224
  }
@@ -11198,8 +11372,8 @@ var EnsureCliVersionUseCase = class {
11198
11372
  this.lockFileRepository = lockFileRepository;
11199
11373
  this.installDefaultSkillsUseCase = installDefaultSkillsUseCase;
11200
11374
  }
11201
- async execute(command30) {
11202
- const { baseDirectory, currentCliVersion, includeBeta } = command30;
11375
+ async execute(command32) {
11376
+ const { baseDirectory, currentCliVersion, includeBeta } = command32;
11203
11377
  const lockFile = await this.lockFileRepository.read(baseDirectory);
11204
11378
  if (!lockFile) {
11205
11379
  return { kind: "no-lockfile" };
@@ -11235,10 +11409,10 @@ var ListPackagesUseCase = class {
11235
11409
  this.packmindGateway = packmindGateway;
11236
11410
  this.spaceService = spaceService;
11237
11411
  }
11238
- async execute(command30) {
11239
- if (command30.spaceId) {
11412
+ async execute(command32) {
11413
+ if (command32.spaceId) {
11240
11414
  const response = await this.packmindGateway.packages.list({
11241
- spaceId: command30.spaceId
11415
+ spaceId: command32.spaceId
11242
11416
  });
11243
11417
  return response.packages;
11244
11418
  }
@@ -11257,8 +11431,8 @@ var GetPackageSummaryUseCase = class {
11257
11431
  constructor(gateway) {
11258
11432
  this.gateway = gateway;
11259
11433
  }
11260
- async execute(command30) {
11261
- return this.gateway.packages.getSummary(command30);
11434
+ async execute(command32) {
11435
+ return this.gateway.packages.getSummary(command32);
11262
11436
  }
11263
11437
  };
11264
11438
 
@@ -11288,10 +11462,7 @@ function decodeApiKey(apiKey) {
11288
11462
  }
11289
11463
 
11290
11464
  // apps/cli/src/infra/utils/credentials/EnvCredentialsProvider.ts
11291
- var ENV_VAR_NAMES = [
11292
- "PACKMIND_API_KEY",
11293
- "PACKMIND_API_KEY_V3"
11294
- ];
11465
+ var ENV_VAR_NAMES = ["PACKMIND_API_KEY"];
11295
11466
  var EnvCredentialsProvider = class {
11296
11467
  getSourceName() {
11297
11468
  const name = this.findActiveEnvVarName() ?? ENV_VAR_NAMES[0];
@@ -11553,8 +11724,8 @@ var LoginUseCase = class {
11553
11724
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
11554
11725
  };
11555
11726
  }
11556
- async execute(command30) {
11557
- const { host, code: providedCode } = command30;
11727
+ async execute(command32) {
11728
+ const { host, code: providedCode } = command32;
11558
11729
  let code;
11559
11730
  if (providedCode) {
11560
11731
  code = providedCode;
@@ -11936,10 +12107,10 @@ var CheckCliVersionUseCase = class {
11936
12107
  now: deps?.now ?? (() => /* @__PURE__ */ new Date())
11937
12108
  };
11938
12109
  }
11939
- async execute(command30) {
11940
- const cached = this.readFreshCache(command30.currentVersion);
12110
+ async execute(command32) {
12111
+ const cached = this.readFreshCache(command32.currentVersion);
11941
12112
  if (cached) {
11942
- return this.toResult(command30.currentVersion, cached.latestVersion);
12113
+ return this.toResult(command32.currentVersion, cached.latestVersion);
11943
12114
  }
11944
12115
  const fetchPromise = this.deps.fetchLatestVersion(this.deps.fetchFn);
11945
12116
  fetchPromise.catch(() => void 0);
@@ -11957,7 +12128,7 @@ var CheckCliVersionUseCase = class {
11957
12128
  latestVersion,
11958
12129
  checkedAt: this.deps.now()
11959
12130
  });
11960
- return this.toResult(command30.currentVersion, latestVersion);
12131
+ return this.toResult(command32.currentVersion, latestVersion);
11961
12132
  } catch {
11962
12133
  return null;
11963
12134
  }
@@ -12405,10 +12576,10 @@ var ListStandardsUseCase = class {
12405
12576
  this.packmindGateway = packmindGateway;
12406
12577
  this.spaceService = spaceService;
12407
12578
  }
12408
- async execute(command30) {
12409
- if (command30.spaceId) {
12579
+ async execute(command32) {
12580
+ if (command32.spaceId) {
12410
12581
  const response = await this.packmindGateway.standards.list({
12411
- spaceId: command30.spaceId
12582
+ spaceId: command32.spaceId
12412
12583
  });
12413
12584
  return response.standards;
12414
12585
  }
@@ -12428,10 +12599,10 @@ var ListCommandsUseCase = class {
12428
12599
  this.packmindGateway = packmindGateway;
12429
12600
  this.spaceService = spaceService;
12430
12601
  }
12431
- async execute(command30) {
12432
- if (command30.spaceId) {
12602
+ async execute(command32) {
12603
+ if (command32.spaceId) {
12433
12604
  const response = await this.packmindGateway.commands.list({
12434
- spaceId: command30.spaceId
12605
+ spaceId: command32.spaceId
12435
12606
  });
12436
12607
  return response.recipes;
12437
12608
  }
@@ -12451,10 +12622,10 @@ var ListSkillsUseCase = class {
12451
12622
  this.packmindGateway = packmindGateway;
12452
12623
  this.spaceService = spaceService;
12453
12624
  }
12454
- async execute(command30) {
12455
- if (command30.spaceId) {
12625
+ async execute(command32) {
12626
+ if (command32.spaceId) {
12456
12627
  const skills = await this.packmindGateway.skills.list({
12457
- spaceId: command30.spaceId
12628
+ spaceId: command32.spaceId
12458
12629
  });
12459
12630
  return skills.map((s) => ({
12460
12631
  id: s.id,
@@ -12487,11 +12658,6 @@ var import_promises2 = __toESM(require("fs/promises"));
12487
12658
  var import_path3 = __toESM(require("path"));
12488
12659
  var import_minimatch2 = require("minimatch");
12489
12660
 
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
12661
  // apps/cli/src/infra/utils/binaryDetection.ts
12496
12662
  var path15 = __toESM(require("path"));
12497
12663
  var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -12631,8 +12797,8 @@ var UploadSkillUseCase = class {
12631
12797
  constructor(deps) {
12632
12798
  this.deps = deps;
12633
12799
  }
12634
- async execute(command30) {
12635
- const files = await readSkillDirectory(command30.skillPath);
12800
+ async execute(command32) {
12801
+ const files = await readSkillDirectory(command32.skillPath);
12636
12802
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
12637
12803
  throw new Error("SKILL.md not found in skill directory");
12638
12804
  }
@@ -12646,7 +12812,7 @@ var UploadSkillUseCase = class {
12646
12812
  if (totalSize > 10 * 1024 * 1024) {
12647
12813
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
12648
12814
  }
12649
- const space = await this.getSpace(command30.spaceSlug);
12815
+ const space = await this.getSpace(command32.spaceSlug);
12650
12816
  const payload = {
12651
12817
  files: files.map((f) => ({
12652
12818
  path: f.relativePath,
@@ -12658,7 +12824,7 @@ var UploadSkillUseCase = class {
12658
12824
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
12659
12825
  spaceId: createSpaceId(space.id),
12660
12826
  files: payload.files,
12661
- originSkill: command30.originSkill
12827
+ originSkill: command32.originSkill
12662
12828
  });
12663
12829
  return {
12664
12830
  skillId: uploadSkillResponse.skill.id,
@@ -13648,9 +13814,9 @@ var DiffArtefactsUseCase = class {
13648
13814
  new StandardDiffStrategy()
13649
13815
  ];
13650
13816
  }
13651
- async execute(command30) {
13652
- const baseDirectory = command30.baseDirectory || process.cwd();
13653
- const response = await this.fetchContent(command30, baseDirectory);
13817
+ async execute(command32) {
13818
+ const baseDirectory = command32.baseDirectory || process.cwd();
13819
+ const response = await this.fetchContent(command32, baseDirectory);
13654
13820
  const filteredFiles = response.fileUpdates.createOrUpdate.filter(
13655
13821
  (file) => file.path !== "packmind.json"
13656
13822
  );
@@ -13663,7 +13829,7 @@ var DiffArtefactsUseCase = class {
13663
13829
  );
13664
13830
  const prefixedSkillFolders = this.prefixSkillFolders(
13665
13831
  response.skillFolders,
13666
- command30.relativePath
13832
+ command32.relativePath
13667
13833
  );
13668
13834
  const diffs = [];
13669
13835
  for (const file of diffableFiles) {
@@ -13690,7 +13856,7 @@ var DiffArtefactsUseCase = class {
13690
13856
  targetId: response.targetId ? createTargetId(response.targetId) : void 0
13691
13857
  }));
13692
13858
  }
13693
- async fetchContent(command30, baseDirectory) {
13859
+ async fetchContent(command32, baseDirectory) {
13694
13860
  const lockFile = await this.lockFileRepository.read(baseDirectory);
13695
13861
  if (lockFile) {
13696
13862
  try {
@@ -13710,11 +13876,11 @@ var DiffArtefactsUseCase = class {
13710
13876
  }
13711
13877
  }
13712
13878
  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
13879
+ packagesSlugs: command32.packagesSlugs,
13880
+ gitRemoteUrl: command32.gitRemoteUrl,
13881
+ gitBranch: command32.gitBranch,
13882
+ relativePath: command32.relativePath,
13883
+ agents: command32.agents
13718
13884
  });
13719
13885
  }
13720
13886
  prefixSkillFolders(skillFolders, relativePath) {
@@ -13738,8 +13904,8 @@ var SubmitDiffsUseCase = class {
13738
13904
  constructor(packmindGateway) {
13739
13905
  this.packmindGateway = packmindGateway;
13740
13906
  }
13741
- async execute(command30) {
13742
- const { groupedDiffs, message } = command30;
13907
+ async execute(command32) {
13908
+ const { groupedDiffs, message } = command32;
13743
13909
  const skipped = [];
13744
13910
  const validDiffs = [];
13745
13911
  for (const group of groupedDiffs) {
@@ -13814,8 +13980,8 @@ var CheckDiffsUseCase = class {
13814
13980
  constructor(packmindGateway) {
13815
13981
  this.packmindGateway = packmindGateway;
13816
13982
  }
13817
- async execute(command30) {
13818
- const { groupedDiffs } = command30;
13983
+ async execute(command32) {
13984
+ const { groupedDiffs } = command32;
13819
13985
  const results = [];
13820
13986
  const validDiffs = [];
13821
13987
  const invalidDiffs = [];
@@ -13913,8 +14079,8 @@ var CliFormatter = class {
13913
14079
  static error(message) {
13914
14080
  return `${source_default.bgRed.bold(CLI_PREFIX2)} ${source_default.red(message)}`;
13915
14081
  }
13916
- static command(command30) {
13917
- return source_default.yellow(command30);
14082
+ static command(command32) {
14083
+ return source_default.yellow(command32);
13918
14084
  }
13919
14085
  static loader(text) {
13920
14086
  return source_default.dim.italic(text);
@@ -14033,6 +14199,140 @@ var CliOutput = class {
14033
14199
  }
14034
14200
  };
14035
14201
 
14202
+ // apps/cli/src/application/useCases/trackRepository/TrackRepositoryUseCase.ts
14203
+ function parseOwnerRepo(gitRemoteUrl) {
14204
+ const match = gitRemoteUrl.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/i);
14205
+ if (!match) {
14206
+ throw new Error(`Unable to parse git remote URL: ${gitRemoteUrl}`);
14207
+ }
14208
+ return {
14209
+ owner: match[1],
14210
+ repo: match[2].replace(/\.git$/, "")
14211
+ };
14212
+ }
14213
+ function parseProviderVendor(gitRemoteUrl) {
14214
+ const normalized = gitRemoteUrl.toLowerCase();
14215
+ if (normalized.includes("github.com")) {
14216
+ return "github";
14217
+ }
14218
+ if (normalized.includes("gitlab.com")) {
14219
+ return "gitlab";
14220
+ }
14221
+ return "unknown";
14222
+ }
14223
+ var TrackRepositoryUseCase = class {
14224
+ constructor(gateway, gitService) {
14225
+ this.gateway = gateway;
14226
+ this.gitService = gitService;
14227
+ }
14228
+ async execute(command32) {
14229
+ const {
14230
+ repoPath,
14231
+ origin: origin9,
14232
+ update,
14233
+ remove,
14234
+ branch: requestedBranch,
14235
+ confirm
14236
+ } = command32;
14237
+ const { gitRemoteUrl } = this.gitService.getGitRemoteUrl(repoPath);
14238
+ const { branch: currentBranch } = this.gitService.getCurrentBranch(repoPath);
14239
+ const branch = requestedBranch ?? currentBranch;
14240
+ const { owner, repo } = parseOwnerRepo(gitRemoteUrl);
14241
+ const providerVendor = parseProviderVendor(gitRemoteUrl);
14242
+ const { gitRepo: tracked } = await this.gateway.getTrackedRepository({
14243
+ owner,
14244
+ repo
14245
+ });
14246
+ if (remove) {
14247
+ if (tracked) {
14248
+ const confirmed2 = await confirm({
14249
+ mode: "remove",
14250
+ owner,
14251
+ repo,
14252
+ branch: tracked.branch
14253
+ });
14254
+ if (!confirmed2) {
14255
+ return { status: "cancelled" };
14256
+ }
14257
+ }
14258
+ const response = await this.gateway.removeTrackedRepository({
14259
+ owner,
14260
+ repo
14261
+ });
14262
+ if (response.status === "not-tracked") {
14263
+ return {
14264
+ status: "not-tracked",
14265
+ owner,
14266
+ repo,
14267
+ organizationName: response.organizationName
14268
+ };
14269
+ }
14270
+ return {
14271
+ status: "removed",
14272
+ owner,
14273
+ repo,
14274
+ branch: response.gitRepo.branch
14275
+ };
14276
+ }
14277
+ if (update) {
14278
+ if (!tracked) {
14279
+ return { status: "nothing-tracked", owner, repo, branch };
14280
+ }
14281
+ if (tracked.branch === branch) {
14282
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14283
+ }
14284
+ const confirmed2 = await confirm({
14285
+ mode: "update",
14286
+ owner,
14287
+ repo,
14288
+ branch,
14289
+ fromBranch: tracked.branch
14290
+ });
14291
+ if (!confirmed2) {
14292
+ return { status: "cancelled" };
14293
+ }
14294
+ const gitRepo2 = await this.gateway.updateTrackedBranch({
14295
+ owner,
14296
+ repo,
14297
+ branch
14298
+ });
14299
+ return {
14300
+ status: "updated",
14301
+ owner,
14302
+ repo,
14303
+ branch,
14304
+ fromBranch: tracked.branch,
14305
+ gitRepo: gitRepo2
14306
+ };
14307
+ }
14308
+ if (tracked) {
14309
+ if (tracked.branch === branch) {
14310
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14311
+ }
14312
+ return {
14313
+ status: "already-tracked-other-branch",
14314
+ owner,
14315
+ repo,
14316
+ branch,
14317
+ trackedBranch: tracked.branch
14318
+ };
14319
+ }
14320
+ const confirmed = await confirm({ mode: "set", owner, repo, branch });
14321
+ if (!confirmed) {
14322
+ return { status: "cancelled" };
14323
+ }
14324
+ const gitRepo = await this.gateway.setTrackedRepository({
14325
+ owner,
14326
+ repo,
14327
+ branch,
14328
+ origin: origin9,
14329
+ providerVendor,
14330
+ gitRemoteUrl
14331
+ });
14332
+ return { status: "set", owner, repo, branch, gitRepo };
14333
+ }
14334
+ };
14335
+
14036
14336
  // apps/cli/src/PackmindCliHexaFactory.ts
14037
14337
  var PackmindCliHexaFactory = class {
14038
14338
  constructor() {
@@ -14118,7 +14418,11 @@ var PackmindCliHexaFactory = class {
14118
14418
  this.repositories.lockFileRepository
14119
14419
  ),
14120
14420
  submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway),
14121
- checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway)
14421
+ checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway),
14422
+ trackRepository: new TrackRepositoryUseCase(
14423
+ this.repositories.packmindGateway.repositoryTracking,
14424
+ this.services.gitRemoteUrlService
14425
+ )
14122
14426
  };
14123
14427
  }
14124
14428
  };
@@ -14127,24 +14431,29 @@ var PackmindCliHexaFactory = class {
14127
14431
  var origin8 = "PackmindCliHexa";
14128
14432
  var PackmindCliHexa = class {
14129
14433
  constructor(logger2 = new PackmindLogger(origin8)) {
14130
- this.notifyDistribution = async (command30) => {
14434
+ this.notifyDistribution = async (command32) => {
14131
14435
  return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
14132
- command30
14436
+ command32
14133
14437
  );
14134
14438
  };
14135
- this.notifyArtefactsDistribution = async (command30) => {
14439
+ this.notifyArtefactsDistribution = async (command32) => {
14136
14440
  return this.hexa.repositories.packmindGateway.deployment.notifyArtefactsDistribution(
14137
- command30
14441
+ command32
14442
+ );
14443
+ };
14444
+ this.getTrackedRepository = async (command32) => {
14445
+ return this.hexa.repositories.packmindGateway.repositoryTracking.getTrackedRepository(
14446
+ command32
14138
14447
  );
14139
14448
  };
14140
- this.renderPlugin = async (command30) => {
14449
+ this.renderPlugin = async (command32) => {
14141
14450
  return this.hexa.repositories.packmindGateway.deployment.renderPlugin(
14142
- command30
14451
+ command32
14143
14452
  );
14144
14453
  };
14145
- this.trackPluginDeleted = async (command30) => {
14454
+ this.trackPluginDeleted = async (command32) => {
14146
14455
  return this.hexa.repositories.packmindGateway.deployment.trackPluginDeleted(
14147
- command30
14456
+ command32
14148
14457
  );
14149
14458
  };
14150
14459
  this.logger = logger2;
@@ -14167,29 +14476,29 @@ var PackmindCliHexa = class {
14167
14476
  get output() {
14168
14477
  return this.hexa.repositories.output;
14169
14478
  }
14170
- async getGitRemoteUrl(command30) {
14171
- return this.hexa.useCases.getGitRemoteUrl.execute(command30);
14479
+ async getGitRemoteUrl(command32) {
14480
+ return this.hexa.useCases.getGitRemoteUrl.execute(command32);
14172
14481
  }
14173
- async listFilesInDirectory(command30) {
14174
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command30);
14482
+ async listFilesInDirectory(command32) {
14483
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command32);
14175
14484
  }
14176
- async lintFilesAgainstRule(command30) {
14177
- return this.hexa.useCases.lintFilesAgainstRule.execute(command30);
14485
+ async lintFilesAgainstRule(command32) {
14486
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command32);
14178
14487
  }
14179
- async lintFilesFromConfig(command30) {
14180
- return this.hexa.useCases.lintFilesFromConfig.execute(command30);
14488
+ async lintFilesFromConfig(command32) {
14489
+ return this.hexa.useCases.lintFilesFromConfig.execute(command32);
14181
14490
  }
14182
- async installPackages(command30) {
14183
- return this.hexa.useCases.installPackages.execute(command30);
14491
+ async installPackages(command32) {
14492
+ return this.hexa.useCases.installPackages.execute(command32);
14184
14493
  }
14185
- async install(command30) {
14186
- return this.hexa.useCases.install.execute(command30);
14494
+ async install(command32) {
14495
+ return this.hexa.useCases.install.execute(command32);
14187
14496
  }
14188
- async uninstall(command30) {
14189
- return this.hexa.useCases.uninstall.execute(command30);
14497
+ async uninstall(command32) {
14498
+ return this.hexa.useCases.uninstall.execute(command32);
14190
14499
  }
14191
- async diffArtefacts(command30) {
14192
- return this.hexa.useCases.diffArtefacts.execute(command30);
14500
+ async diffArtefacts(command32) {
14501
+ return this.hexa.useCases.diffArtefacts.execute(command32);
14193
14502
  }
14194
14503
  async submitDiffs(groupedDiffs, message) {
14195
14504
  return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
@@ -14197,20 +14506,20 @@ var PackmindCliHexa = class {
14197
14506
  async checkDiffs(groupedDiffs) {
14198
14507
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
14199
14508
  }
14200
- async listPackages(command30) {
14201
- return this.hexa.useCases.listPackages.execute(command30);
14509
+ async listPackages(command32) {
14510
+ return this.hexa.useCases.listPackages.execute(command32);
14202
14511
  }
14203
- async getPackageBySlug(command30) {
14204
- return this.hexa.useCases.getPackageBySlug.execute(command30);
14512
+ async getPackageBySlug(command32) {
14513
+ return this.hexa.useCases.getPackageBySlug.execute(command32);
14205
14514
  }
14206
- async listStandards(command30) {
14207
- return this.hexa.useCases.listStandards.execute(command30);
14515
+ async listStandards(command32) {
14516
+ return this.hexa.useCases.listStandards.execute(command32);
14208
14517
  }
14209
- async listCommands(command30) {
14210
- return this.hexa.useCases.listCommands.execute(command30);
14518
+ async listCommands(command32) {
14519
+ return this.hexa.useCases.listCommands.execute(command32);
14211
14520
  }
14212
- async listSkills(command30) {
14213
- return this.hexa.useCases.listSkills.execute(command30);
14521
+ async listSkills(command32) {
14522
+ return this.hexa.useCases.listSkills.execute(command32);
14214
14523
  }
14215
14524
  async configExists(baseDirectory) {
14216
14525
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -14297,17 +14606,17 @@ var PackmindCliHexa = class {
14297
14606
  directory
14298
14607
  );
14299
14608
  }
14300
- async login(command30) {
14301
- return this.hexa.useCases.login.execute(command30);
14609
+ async login(command32) {
14610
+ return this.hexa.useCases.login.execute(command32);
14302
14611
  }
14303
- async logout(command30) {
14304
- return this.hexa.useCases.logout.execute(command30);
14612
+ async logout(command32) {
14613
+ return this.hexa.useCases.logout.execute(command32);
14305
14614
  }
14306
- async whoami(command30) {
14307
- return this.hexa.useCases.whoami.execute(command30);
14615
+ async whoami(command32) {
14616
+ return this.hexa.useCases.whoami.execute(command32);
14308
14617
  }
14309
- async checkCliVersion(command30) {
14310
- return this.hexa.useCases.checkCliVersion.execute(command30);
14618
+ async checkCliVersion(command32) {
14619
+ return this.hexa.useCases.checkCliVersion.execute(command32);
14311
14620
  }
14312
14621
  getCurrentBranch(repoPath) {
14313
14622
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -14315,19 +14624,22 @@ var PackmindCliHexa = class {
14315
14624
  getGitRemoteUrlFromPath(repoPath) {
14316
14625
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
14317
14626
  }
14318
- async uploadSkill(command30) {
14319
- return this.hexa.useCases.uploadSkill.execute(command30);
14627
+ async uploadSkill(command32) {
14628
+ return this.hexa.useCases.uploadSkill.execute(command32);
14320
14629
  }
14321
- async installDefaultSkills(command30) {
14322
- return this.hexa.useCases.installDefaultSkills.execute(command30);
14630
+ async installDefaultSkills(command32) {
14631
+ return this.hexa.useCases.installDefaultSkills.execute(command32);
14323
14632
  }
14324
- async bootstrapSkillsInitDirectory(command30) {
14633
+ async bootstrapSkillsInitDirectory(command32) {
14325
14634
  return this.hexa.useCases.installDefaultSkills.bootstrapEmptyDirectory(
14326
- command30.baseDirectory
14635
+ command32.baseDirectory
14327
14636
  );
14328
14637
  }
14329
- async ensureCliVersion(command30) {
14330
- return this.hexa.useCases.ensureCliVersion.execute(command30);
14638
+ async ensureCliVersion(command32) {
14639
+ return this.hexa.useCases.ensureCliVersion.execute(command32);
14640
+ }
14641
+ async trackRepository(command32) {
14642
+ return this.hexa.useCases.trackRepository.execute(command32);
14331
14643
  }
14332
14644
  getPackmindGateway() {
14333
14645
  return this.hexa.repositories.packmindGateway;
@@ -14728,7 +15040,7 @@ var lintCommand = (0, import_cmd_ts.command)({
14728
15040
  }),
14729
15041
  continueOnMissingKey: (0, import_cmd_ts.flag)({
14730
15042
  long: "continue-on-missing-key",
14731
- description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY_V3 is not set"
15043
+ description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY is not set"
14732
15044
  }),
14733
15045
  changedFiles: (0, import_cmd_ts.flag)({
14734
15046
  long: "changed-files",
@@ -15083,7 +15395,7 @@ var AgentArtifactDetectionService = class {
15083
15395
 
15084
15396
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15085
15397
  var readline3 = __toESM(require("readline"));
15086
- var inquirer2 = __toESM(require("inquirer"));
15398
+ var inquirer3 = __toESM(require("inquirer"));
15087
15399
 
15088
15400
  // apps/cli/src/infra/commands/config/configAgentsHandler.ts
15089
15401
  var readline2 = __toESM(require("readline"));
@@ -15356,6 +15668,38 @@ function buildSkillsSkippedWarning(configuredAgents) {
15356
15668
  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
15669
  }
15358
15670
 
15671
+ // apps/cli/src/infra/commands/trackingPrompts.ts
15672
+ var inquirer2 = __toESM(require("inquirer"));
15673
+ function buildTrackConfirmationMessage(details) {
15674
+ if (details.mode === "remove") {
15675
+ return `Stop tracking ${details.owner}/${details.repo}? Packmind currently tracks branch ${details.branch}.`;
15676
+ }
15677
+ if (details.mode === "update") {
15678
+ return `Change the tracked branch for ${details.owner}/${details.repo} from ${details.fromBranch} to ${details.branch}?`;
15679
+ }
15680
+ return `Track ${details.owner}/${details.repo} on branch ${details.branch}?`;
15681
+ }
15682
+ async function defaultConfirmPrompt(message) {
15683
+ const { confirmed } = await inquirer2.default.prompt([
15684
+ {
15685
+ type: "confirm",
15686
+ name: "confirmed",
15687
+ message,
15688
+ default: false
15689
+ }
15690
+ ]);
15691
+ return confirmed;
15692
+ }
15693
+ function createTrackConfirm(options) {
15694
+ const confirmPrompt = options.confirmPrompt ?? defaultConfirmPrompt;
15695
+ return async (details) => {
15696
+ if (!options.isTTY) {
15697
+ return true;
15698
+ }
15699
+ return confirmPrompt(buildTrackConfirmationMessage(details));
15700
+ };
15701
+ }
15702
+
15359
15703
  // apps/cli/src/infra/commands/initHandler.ts
15360
15704
  async function initHandler(deps) {
15361
15705
  const {
@@ -15367,8 +15711,11 @@ async function initHandler(deps) {
15367
15711
  ensureCliVersion,
15368
15712
  cliVersion,
15369
15713
  isTTY,
15370
- showOnboardHint = true
15714
+ showOnboardHint = true,
15715
+ trackRepository,
15716
+ confirmPrompt
15371
15717
  } = deps;
15718
+ const resolvedIsTTY = isTTY ?? Boolean(process.stdin.isTTY);
15372
15719
  if (ensureCliVersion) {
15373
15720
  try {
15374
15721
  const outcome = await ensureCliVersion({
@@ -15428,6 +15775,14 @@ async function initHandler(deps) {
15428
15775
  }
15429
15776
  }
15430
15777
  }
15778
+ if (resolvedIsTTY && trackRepository) {
15779
+ await offerRepositoryTracking({
15780
+ trackRepository,
15781
+ baseDirectory,
15782
+ isTTY: resolvedIsTTY,
15783
+ confirmPrompt
15784
+ });
15785
+ }
15431
15786
  logConsole("");
15432
15787
  logSuccessConsole("Packmind initialized successfully!");
15433
15788
  if (showOnboardHint) {
@@ -15440,6 +15795,44 @@ async function initHandler(deps) {
15440
15795
  errors: []
15441
15796
  };
15442
15797
  }
15798
+ async function offerRepositoryTracking(deps) {
15799
+ const confirm = createTrackConfirm({
15800
+ isTTY: deps.isTTY,
15801
+ confirmPrompt: deps.confirmPrompt
15802
+ });
15803
+ try {
15804
+ const result = await deps.trackRepository({
15805
+ repoPath: deps.baseDirectory,
15806
+ origin: "init",
15807
+ update: false,
15808
+ remove: false,
15809
+ confirm
15810
+ });
15811
+ switch (result.status) {
15812
+ case "set":
15813
+ logSuccessConsole(
15814
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
15815
+ );
15816
+ break;
15817
+ case "already-tracked-other-branch":
15818
+ logInfoConsole(
15819
+ `Repository already tracked on branch ${result.trackedBranch}.`
15820
+ );
15821
+ break;
15822
+ case "already-tracked-same-branch":
15823
+ logWarningConsole(
15824
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
15825
+ );
15826
+ break;
15827
+ case "cancelled":
15828
+ case "nothing-tracked":
15829
+ case "updated":
15830
+ default:
15831
+ break;
15832
+ }
15833
+ } catch {
15834
+ }
15835
+ }
15443
15836
 
15444
15837
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15445
15838
  async function bootstrapInstallContext(deps) {
@@ -15585,7 +15978,7 @@ async function promptOrgRenderModes(params) {
15585
15978
  if (useSimplePrompt) {
15586
15979
  confirmed = await confirmWithReadline(`${promptMessage} [Y/n] `);
15587
15980
  } else {
15588
- const answer = await inquirer2.default.prompt([
15981
+ const answer = await inquirer3.default.prompt([
15589
15982
  {
15590
15983
  type: "select",
15591
15984
  name: "confirm",
@@ -15731,23 +16124,129 @@ function mergeInstallResults(results) {
15731
16124
  }
15732
16125
  return merged;
15733
16126
  }
16127
+ function decideDistributionTracking(params) {
16128
+ const { lookup, currentBranch } = params;
16129
+ switch (lookup.status) {
16130
+ case "flag-off":
16131
+ return { action: "record-legacy" };
16132
+ case "unavailable":
16133
+ return { action: "inform" };
16134
+ case "resolved": {
16135
+ const tracked = lookup.trackedGitRepo;
16136
+ if (!tracked) {
16137
+ return { action: "skip", reason: "repo_not_tracked" };
16138
+ }
16139
+ if (tracked.branch !== currentBranch) {
16140
+ return {
16141
+ action: "skip",
16142
+ reason: "wrong_branch",
16143
+ trackedBranch: tracked.branch
16144
+ };
16145
+ }
16146
+ return { action: "record" };
16147
+ }
16148
+ }
16149
+ }
16150
+ var NO_GIT_REPO_CACHE_KEY = "<no-git-repo>";
16151
+ function toRepoRelativePath(dir, gitRoot) {
16152
+ let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
16153
+ if (!relativePath.startsWith("/")) {
16154
+ relativePath = "/" + relativePath;
16155
+ }
16156
+ if (!relativePath.endsWith("/")) {
16157
+ relativePath = relativePath + "/";
16158
+ }
16159
+ return relativePath;
16160
+ }
16161
+ function reportDistributionTrackingDecision(decision, context) {
16162
+ switch (decision.action) {
16163
+ case "skip":
16164
+ if (decision.reason === "repo_not_tracked") {
16165
+ logWarningConsole(
16166
+ `Distribution not recorded \u2014 ${context.owner}/${context.repo} is not tracked in Packmind. Ask an admin to run ${formatCommand(
16167
+ "packmind track"
16168
+ )} to start tracking it.`
16169
+ );
16170
+ } else {
16171
+ logWarningConsole(
16172
+ `Distribution not recorded \u2014 you're on '${context.currentBranch}', but the tracked branch is '${decision.trackedBranch}'. Switch to '${decision.trackedBranch}' to record this distribution.`
16173
+ );
16174
+ }
16175
+ break;
16176
+ case "inform":
16177
+ logInfoConsole(
16178
+ `This folder is not tracked \u2014 distribution not recorded in Packmind.`
16179
+ );
16180
+ break;
16181
+ }
16182
+ }
16183
+ async function resolveTrackingLookup(packmindCliHexa, owner, repo) {
16184
+ try {
16185
+ const { gitRepo } = await packmindCliHexa.getTrackedRepository({
16186
+ owner,
16187
+ repo
16188
+ });
16189
+ return { status: "resolved", trackedGitRepo: gitRepo };
16190
+ } catch (error) {
16191
+ const statusCode = error?.statusCode;
16192
+ if (statusCode === 404) {
16193
+ return { status: "flag-off" };
16194
+ }
16195
+ return { status: "unavailable" };
16196
+ }
16197
+ }
16198
+ async function computeDistributionTrackingDecision(packmindCliHexa, gitRoot) {
16199
+ if (!gitRoot) {
16200
+ const decision2 = { action: "inform" };
16201
+ reportDistributionTrackingDecision(decision2, {});
16202
+ return decision2;
16203
+ }
16204
+ let owner;
16205
+ let repo;
16206
+ let gitBranch;
16207
+ try {
16208
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
16209
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
16210
+ ({ owner, repo } = parseOwnerRepo(gitRemoteUrl));
16211
+ } catch {
16212
+ const decision2 = { action: "inform" };
16213
+ reportDistributionTrackingDecision(decision2, {});
16214
+ return decision2;
16215
+ }
16216
+ const lookup = await resolveTrackingLookup(packmindCliHexa, owner, repo);
16217
+ const decision = decideDistributionTracking({
16218
+ lookup,
16219
+ currentBranch: gitBranch
16220
+ });
16221
+ reportDistributionTrackingDecision(decision, {
16222
+ owner,
16223
+ repo,
16224
+ currentBranch: gitBranch
16225
+ });
16226
+ return decision;
16227
+ }
15734
16228
  async function notifyArtefactsDistributionIfInGitRepo(params) {
15735
- const { packmindCliHexa, dir } = params;
16229
+ const { packmindCliHexa, dir, decisionCache } = params;
15736
16230
  try {
15737
16231
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(dir);
16232
+ const cacheKey = gitRoot ?? NO_GIT_REPO_CACHE_KEY;
16233
+ if (!decisionCache.has(cacheKey)) {
16234
+ decisionCache.set(
16235
+ cacheKey,
16236
+ await computeDistributionTrackingDecision(packmindCliHexa, gitRoot)
16237
+ );
16238
+ }
16239
+ const decision = decisionCache.get(cacheKey);
16240
+ if (!decision || decision.action !== "record" && decision.action !== "record-legacy") {
16241
+ return;
16242
+ }
15738
16243
  if (!gitRoot) return;
15739
16244
  const lockFilePath = path24.join(dir, "packmind-lock.json");
15740
16245
  const content = fs23.readFileSync(lockFilePath, "utf-8");
15741
16246
  const packmindLockFile = JSON.parse(content);
15742
16247
  const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
15743
16248
  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
- }
16249
+ const relativePath = toRepoRelativePath(dir, gitRoot);
15751
16250
  await packmindCliHexa.notifyArtefactsDistribution({
15752
16251
  gitRemoteUrl,
15753
16252
  gitBranch,
@@ -15801,8 +16300,7 @@ async function installDefaultSkillsIfAtGitRoot(params) {
15801
16300
  async function installHandler({
15802
16301
  installPath,
15803
16302
  packages,
15804
- status,
15805
- skipInstalledAt
16303
+ status
15806
16304
  }) {
15807
16305
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15808
16306
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
@@ -15880,13 +16378,13 @@ async function installHandler({
15880
16378
  const results = [];
15881
16379
  const thrownErrors = [];
15882
16380
  const multiDir = targetDirs.length > 1;
16381
+ const distributionTrackingCache = /* @__PURE__ */ new Map();
15883
16382
  for (const dir of targetDirs) {
15884
16383
  try {
15885
16384
  const dirHomeAgent = isAgentHomeDirectory(dir) ?? void 0;
15886
16385
  const result = await packmindCliHexa.install({
15887
16386
  baseDirectory: dir,
15888
16387
  packages: packages.length > 0 ? packages : void 0,
15889
- skipInstalledAt,
15890
16388
  cliVersion: CLI_VERSION,
15891
16389
  homeAgent: dirHomeAgent
15892
16390
  });
@@ -15894,7 +16392,8 @@ async function installHandler({
15894
16392
  if (!dirHomeAgent) {
15895
16393
  await notifyArtefactsDistributionIfInGitRepo({
15896
16394
  packmindCliHexa,
15897
- dir
16395
+ dir,
16396
+ decisionCache: distributionTrackingCache
15898
16397
  });
15899
16398
  }
15900
16399
  } catch (error) {
@@ -15967,10 +16466,6 @@ var installCommand = (0, import_cmd_ts2.command)({
15967
16466
  status: (0, import_cmd_ts2.flag)({
15968
16467
  long: "status",
15969
16468
  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
16469
  })
15975
16470
  },
15976
16471
  handler: installHandler
@@ -16129,9 +16624,9 @@ var logoutCommand = (0, import_cmd_ts5.command)({
16129
16624
  logInfoConsole("No stored credentials file found.");
16130
16625
  }
16131
16626
  logConsole(
16132
- "\nNote: PACKMIND_API_KEY_V3 environment variable is still set."
16627
+ "\nNote: PACKMIND_API_KEY environment variable is still set."
16133
16628
  );
16134
- logConsole("To fully log out, run: unset PACKMIND_API_KEY_V3");
16629
+ logConsole("To fully log out, run: unset PACKMIND_API_KEY");
16135
16630
  }
16136
16631
  } catch (error) {
16137
16632
  logErrorConsole("Failed to remove credentials file.");
@@ -16213,7 +16708,7 @@ No credentials found. Run \`packmind-cli login\` to authenticate.`
16213
16708
  );
16214
16709
  logConsole(`
16215
16710
  Credentials are loaded from (in order of priority):`);
16216
- logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
16711
+ logConsole(` 1. PACKMIND_API_KEY environment variable`);
16217
16712
  logConsole(` 2. ${result.credentialsPath}`);
16218
16713
  process.exit(1);
16219
16714
  }
@@ -16697,15 +17192,15 @@ var CreatePackageUseCase = class {
16697
17192
  this.gateway = gateway;
16698
17193
  this.spaceService = spaceService;
16699
17194
  }
16700
- async execute(command30) {
16701
- const space = await this.getSpace(command30);
17195
+ async execute(command32) {
17196
+ const space = await this.getSpace(command32);
16702
17197
  const result = await this.gateway.packages.create({
16703
17198
  spaceId: space.id,
16704
- name: command30.name,
16705
- description: command30.description ?? "",
17199
+ name: command32.name,
17200
+ description: command32.description ?? "",
16706
17201
  recipeIds: [],
16707
17202
  standardIds: [],
16708
- originSkill: command30.originSkill
17203
+ originSkill: command32.originSkill
16709
17204
  });
16710
17205
  return {
16711
17206
  packageId: result.package.id,
@@ -16714,12 +17209,12 @@ var CreatePackageUseCase = class {
16714
17209
  spaceSlug: space.slug
16715
17210
  };
16716
17211
  }
16717
- async getSpace(command30) {
17212
+ async getSpace(command32) {
16718
17213
  const spaces = await this.spaceService.getSpaces();
16719
- if (command30.spaceSlug) {
16720
- const found = spaces.find((s) => s.slug === command30.spaceSlug);
17214
+ if (command32.spaceSlug) {
17215
+ const found = spaces.find((s) => s.slug === command32.spaceSlug);
16721
17216
  if (!found) {
16722
- throw new Error(`Space '${command30.spaceSlug}' not found.`);
17217
+ throw new Error(`Space '${command32.spaceSlug}' not found.`);
16723
17218
  }
16724
17219
  return found;
16725
17220
  }
@@ -16837,8 +17332,8 @@ var AddToPackageUseCase = class {
16837
17332
  this.gateway = gateway;
16838
17333
  this.spaceService = spaceService;
16839
17334
  }
16840
- async execute(command30) {
16841
- const { packageSlug, spaceSlug, itemType, itemSlugs } = command30;
17335
+ async execute(command32) {
17336
+ const { packageSlug, spaceSlug, itemType, itemSlugs } = command32;
16842
17337
  const space = spaceSlug ? await this.resolveSpaceBySlug(spaceSlug) : await this.spaceService.getDefaultSpace();
16843
17338
  const packages = await this.gateway.packages.list({
16844
17339
  spaceId: space.id
@@ -16859,12 +17354,12 @@ var AddToPackageUseCase = class {
16859
17354
  standardIds: [],
16860
17355
  recipeIds: [],
16861
17356
  skillIds: [],
16862
- originSkill: command30.originSkill
17357
+ originSkill: command32.originSkill
16863
17358
  };
16864
17359
  if (itemType === "standard") {
16865
17360
  addCommand.standardIds = ids.map(createStandardId);
16866
17361
  } else if (itemType === "command") {
16867
- addCommand.recipeIds = ids.map(createRecipeId);
17362
+ addCommand.recipeIds = ids.map(createCommandId);
16868
17363
  } else if (itemType === "skill") {
16869
17364
  addCommand.skillIds = ids.map(createSkillId);
16870
17365
  }
@@ -16911,7 +17406,7 @@ var AddToPackageUseCase = class {
16911
17406
  }
16912
17407
  async findCommandBySlug(slug6, spaceId) {
16913
17408
  const commands = await this.gateway.commands.list({ spaceId });
16914
- return commands.recipes.find((command30) => command30.slug === slug6) ?? null;
17409
+ return commands.recipes.find((command32) => command32.slug === slug6) ?? null;
16915
17410
  }
16916
17411
  async findSkillBySlug(slug6, spaceId) {
16917
17412
  const skills = await this.gateway.skills.list({ spaceId });
@@ -16987,11 +17482,11 @@ async function executeAddToPackage(pkgSlug, spaceSlug, itemType, itemSlugs, useC
16987
17482
  logErrorConsole(message);
16988
17483
  if (error instanceof ItemNotFoundError) {
16989
17484
  const spaceFlag = error.spaceSlug ? ` --space ${error.spaceSlug}` : "";
16990
- const command30 = formatCommand(
17485
+ const command32 = formatCommand(
16991
17486
  `packmind-cli ${error.itemType}s list${spaceFlag}`
16992
17487
  );
16993
17488
  logInfoConsole(
16994
- `Run \`${command30}\` to display available ${error.itemType}s`
17489
+ `Run \`${command32}\` to display available ${error.itemType}s`
16995
17490
  );
16996
17491
  }
16997
17492
  return { success: false, error: message };
@@ -17249,10 +17744,10 @@ ${pkg.name} (${fullSlug}):
17249
17744
  });
17250
17745
  logConsole("");
17251
17746
  }
17252
- if (pkg.recipes && pkg.recipes.length > 0) {
17747
+ if (pkg.commands && pkg.commands.length > 0) {
17253
17748
  logConsole("Commands:");
17254
- pkg.recipes.forEach((recipe) => {
17255
- logConsole(` - ${recipe.name}`);
17749
+ pkg.commands.forEach((command32) => {
17750
+ logConsole(` - ${command32.name}`);
17256
17751
  });
17257
17752
  logConsole("");
17258
17753
  }
@@ -17771,7 +18266,7 @@ var PlaybookLocalRepository = class {
17771
18266
  }
17772
18267
  };
17773
18268
 
17774
- // apps/cli/src/infra/commands/playbook/addHandler.ts
18269
+ // apps/cli/src/infra/commands/playbook/add/stageSinglePath.ts
17775
18270
  var fs25 = __toESM(require("fs"));
17776
18271
  var path29 = __toESM(require("path"));
17777
18272
  var yaml2 = __toESM(require("yaml"));
@@ -17921,8 +18416,35 @@ function parseLenientStandard(content) {
17921
18416
  return { name, description, rules };
17922
18417
  }
17923
18418
 
18419
+ // packages/skills/src/application/errors/SkillValidationError.ts
18420
+ var SkillValidationError = class _SkillValidationError extends Error {
18421
+ constructor(errors) {
18422
+ const messages = errors.map((e) => e.message).join("; ");
18423
+ super(`Skill validation failed: ${messages}`);
18424
+ this.name = "SkillValidationError";
18425
+ this.errors = errors;
18426
+ Object.setPrototypeOf(this, _SkillValidationError.prototype);
18427
+ }
18428
+ };
18429
+
17924
18430
  // packages/skills/src/application/validator/SkillValidator.ts
17925
18431
  var DESCRIPTION_MAX_LENGTH = 1024;
18432
+ var SKILL_FILE_MAX_CONTENT_LENGTH = 3e5;
18433
+ function validateSkillFileContent(content) {
18434
+ if (content.trim().length === 0) {
18435
+ throw new SkillValidationError([
18436
+ { field: "content", message: "File content cannot be empty" }
18437
+ ]);
18438
+ }
18439
+ if (content.length > SKILL_FILE_MAX_CONTENT_LENGTH) {
18440
+ throw new SkillValidationError([
18441
+ {
18442
+ field: "content",
18443
+ message: `File content exceeds the maximum length of ${SKILL_FILE_MAX_CONTENT_LENGTH} characters`
18444
+ }
18445
+ ]);
18446
+ }
18447
+ }
17926
18448
 
17927
18449
  // packages/skills/src/infra/schemas/SkillSchema.ts
17928
18450
  var import_typeorm2 = require("typeorm");
@@ -18151,15 +18673,18 @@ var import_uuid = require("uuid");
18151
18673
  // packages/skills/src/application/useCases/updateSkill/UpdateSkillUseCase.ts
18152
18674
  var import_slug2 = __toESM(require("slug"));
18153
18675
 
18676
+ // packages/skills/src/application/useCases/updateSkillFileFromUI/UpdateSkillFileFromUIUseCase.ts
18677
+ var import_uuid2 = require("uuid");
18678
+
18154
18679
  // packages/skills/src/application/useCases/uploadSkill/UploadSkillUseCase.ts
18155
18680
  var import_slug3 = __toESM(require("slug"));
18156
- var import_uuid2 = require("uuid");
18681
+ var import_uuid3 = require("uuid");
18157
18682
 
18158
18683
  // packages/skills/src/application/services/SkillService.ts
18159
- var import_uuid3 = require("uuid");
18684
+ var import_uuid4 = require("uuid");
18160
18685
 
18161
18686
  // packages/skills/src/application/services/SkillVersionService.ts
18162
- var import_uuid4 = require("uuid");
18687
+ var import_uuid5 = require("uuid");
18163
18688
 
18164
18689
  // apps/cli/src/application/utils/parseSkillDirectory.ts
18165
18690
  var SKILL_MD_FILENAME2 = "SKILL.md";
@@ -18200,11 +18725,32 @@ function parseSkillDirectory(files) {
18200
18725
  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
18726
  };
18202
18727
  }
18203
- if (body.trim().length === 0) {
18204
- return {
18205
- success: false,
18206
- error: "SKILL.md body (prompt) cannot be empty."
18207
- };
18728
+ try {
18729
+ validateSkillFileContent(body);
18730
+ } catch (error) {
18731
+ if (error instanceof SkillValidationError) {
18732
+ return {
18733
+ success: false,
18734
+ error: `SKILL.md body (prompt) is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18735
+ };
18736
+ }
18737
+ throw error;
18738
+ }
18739
+ const supportingMdFiles = files.filter(
18740
+ (f) => f.relativePath !== SKILL_MD_FILENAME2 && f.relativePath.endsWith(".md")
18741
+ );
18742
+ for (const mdFile of supportingMdFiles) {
18743
+ try {
18744
+ validateSkillFileContent(mdFile.content);
18745
+ } catch (error) {
18746
+ if (error instanceof SkillValidationError) {
18747
+ return {
18748
+ success: false,
18749
+ error: `File "${mdFile.relativePath}" is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18750
+ };
18751
+ }
18752
+ throw error;
18753
+ }
18208
18754
  }
18209
18755
  const payload = {
18210
18756
  name: name.trim(),
@@ -18384,7 +18930,7 @@ function adoptArtifactIntoLockFile({
18384
18930
  };
18385
18931
  }
18386
18932
 
18387
- // apps/cli/src/infra/commands/playbook/addHandler.ts
18933
+ // apps/cli/src/infra/commands/playbook/add/stageSinglePath.ts
18388
18934
  async function tryStageRemovedFromLockFile(resolvedPath, deps) {
18389
18935
  const fileDir = path29.dirname(resolvedPath);
18390
18936
  const targetDir = await findNearestConfigDir(fileDir, deps.packmindCliHexa);
@@ -18422,10 +18968,6 @@ async function tryStageRemovedFromLockFile(resolvedPath, deps) {
18422
18968
  logSuccessConsole(
18423
18969
  `Staged "${lockEntry.name}" (${lockEntry.type}, removed) to playbook${spaceInfo}`
18424
18970
  );
18425
- logInfoConsole(
18426
- `Run ${formatLabel("packmind playbook submit")} when you're ready to publish your changes.`
18427
- );
18428
- deps.exit(0);
18429
18971
  return true;
18430
18972
  }
18431
18973
  function resolveSkillDirectoryRoot(absolutePath) {
@@ -18449,25 +18991,17 @@ function resolveSkillDirectoryRoot(absolutePath) {
18449
18991
  }
18450
18992
  return absolutePath;
18451
18993
  }
18452
- async function playbookAddHandler(deps) {
18994
+ async function stageSinglePath(deps) {
18453
18995
  const {
18454
18996
  packmindCliHexa,
18455
18997
  filePath,
18456
18998
  spaceSlug,
18457
- exit,
18458
18999
  cwd,
18459
19000
  readFile: readFile11,
18460
19001
  readSkillDirectory: readSkillDirectory2,
18461
19002
  playbookLocalRepository,
18462
19003
  lockFileRepository
18463
19004
  } = deps;
18464
- if (!filePath) {
18465
- logErrorConsole(
18466
- "Missing file path. Usage: packmind-cli playbook add <path>"
18467
- );
18468
- exit(1);
18469
- return;
18470
- }
18471
19005
  const absolutePath = path29.resolve(cwd, filePath);
18472
19006
  let artifactType;
18473
19007
  let codingAgent;
@@ -18491,11 +19025,11 @@ async function playbookAddHandler(deps) {
18491
19025
  } else {
18492
19026
  const artefactResult = resolveArtefactFromPath(absolutePath);
18493
19027
  if (!artefactResult) {
18494
- logErrorConsole(
18495
- `Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
18496
- );
18497
- exit(1);
18498
- return;
19028
+ return {
19029
+ status: "failed",
19030
+ filePath,
19031
+ message: `Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
19032
+ };
18499
19033
  }
18500
19034
  artifactType = artefactResult.artifactType;
18501
19035
  codingAgent = artefactResult.codingAgent;
@@ -18503,11 +19037,11 @@ async function playbookAddHandler(deps) {
18503
19037
  } else {
18504
19038
  const artefactResult = resolveArtefactFromPath(absolutePath);
18505
19039
  if (!artefactResult) {
18506
- logErrorConsole(
18507
- `Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
18508
- );
18509
- exit(1);
18510
- return;
19040
+ return {
19041
+ status: "failed",
19042
+ filePath,
19043
+ message: `Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
19044
+ };
18511
19045
  }
18512
19046
  artifactType = artefactResult.artifactType;
18513
19047
  codingAgent = artefactResult.codingAgent;
@@ -18517,9 +19051,7 @@ async function playbookAddHandler(deps) {
18517
19051
  artifactType
18518
19052
  );
18519
19053
  if (!formatValidation.valid) {
18520
- logErrorConsole(formatValidation.reason);
18521
- exit(1);
18522
- return;
19054
+ return { status: "failed", filePath, message: formatValidation.reason };
18523
19055
  }
18524
19056
  let localContent;
18525
19057
  let artifactName;
@@ -18537,21 +19069,20 @@ async function playbookAddHandler(deps) {
18537
19069
  packmindCliHexa,
18538
19070
  lockFileRepository,
18539
19071
  playbookLocalRepository,
18540
- codingAgent,
18541
- exit
19072
+ codingAgent
18542
19073
  });
18543
- if (staged) return;
19074
+ if (staged) return { status: "staged", filePath, artifactType };
18544
19075
  const errorMessage = err instanceof Error ? err.message : String(err);
18545
- logErrorConsole(`Failed to read skill directory: ${errorMessage}`);
18546
- exit(1);
18547
- return;
19076
+ return {
19077
+ status: "failed",
19078
+ filePath,
19079
+ message: `Failed to read skill directory: ${errorMessage}`
19080
+ };
18548
19081
  }
18549
19082
  skillFiles = files;
18550
19083
  const parseResult = parseSkillDirectory(files);
18551
19084
  if (!parseResult.success) {
18552
- logErrorConsole(parseResult.error);
18553
- exit(1);
18554
- return;
19085
+ return { status: "failed", filePath, message: parseResult.error };
18555
19086
  }
18556
19087
  artifactName = parseResult.payload.name;
18557
19088
  serializedContent = yaml2.stringify(parseResult.payload);
@@ -18565,21 +19096,24 @@ async function playbookAddHandler(deps) {
18565
19096
  packmindCliHexa,
18566
19097
  lockFileRepository,
18567
19098
  playbookLocalRepository,
18568
- codingAgent,
18569
- exit
19099
+ codingAgent
18570
19100
  });
18571
- if (staged) return;
19101
+ if (staged) return { status: "staged", filePath, artifactType };
18572
19102
  const errorMessage = err instanceof Error ? err.message : String(err);
18573
- logErrorConsole(`Failed to read file: ${errorMessage}`);
18574
- exit(1);
18575
- return;
19103
+ return {
19104
+ status: "failed",
19105
+ filePath,
19106
+ message: `Failed to read file: ${errorMessage}`
19107
+ };
18576
19108
  }
18577
19109
  if (artifactType === "command") {
18578
19110
  const parseResult = parseCommandFile(localContent, absolutePath);
18579
19111
  if (!parseResult.success) {
18580
- logErrorConsole(`Failed to parse command file: ${parseResult.error}`);
18581
- exit(1);
18582
- return;
19112
+ return {
19113
+ status: "failed",
19114
+ filePath,
19115
+ message: `Failed to parse command file: ${parseResult.error}`
19116
+ };
18583
19117
  }
18584
19118
  artifactName = parseResult.parsed.name;
18585
19119
  } else {
@@ -18589,15 +19123,15 @@ async function playbookAddHandler(deps) {
18589
19123
  } else {
18590
19124
  const lenient = parseLenientStandard(localContent);
18591
19125
  if (!lenient) {
18592
- logErrorConsole(
18593
- `${filePath} is not a valid artifact. Expected format:
19126
+ return {
19127
+ status: "failed",
19128
+ filePath,
19129
+ message: `Not a valid artifact. Expected format:
18594
19130
 
18595
19131
  # My standard name
18596
19132
 
18597
19133
  Content goes here...`
18598
- );
18599
- exit(1);
18600
- return;
19134
+ };
18601
19135
  }
18602
19136
  artifactName = lenient.name;
18603
19137
  }
@@ -18606,11 +19140,11 @@ Content goes here...`
18606
19140
  }
18607
19141
  const targetDir = earlyTargetDir;
18608
19142
  if (!targetDir) {
18609
- logErrorConsole(
18610
- "Not inside a Packmind project. No packmind.json found in any parent directory."
18611
- );
18612
- exit(1);
18613
- return;
19143
+ return {
19144
+ status: "failed",
19145
+ filePath,
19146
+ message: "Not inside a Packmind project. No packmind.json found in any parent directory."
19147
+ };
18614
19148
  }
18615
19149
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
18616
19150
  const configDir = gitRoot ? normalizePath2(path29.relative(gitRoot, targetDir)) : void 0;
@@ -18628,23 +19162,23 @@ Content goes here...`
18628
19162
  const allSpaces = await packmindCliHexa.getSpaces();
18629
19163
  const existingLockEntry = earlyLockFile && findLockFileEntryForPath(normalizedFilePath, earlyLockFile.artifacts);
18630
19164
  if (existingLockEntry && !spaceSlug && !allSpaces.some((s) => s.id === existingLockEntry.spaceId)) {
18631
- logErrorConsole(
18632
- `Cannot add changes to this ${artifactType}: the space it belongs to is not available to you.
19165
+ return {
19166
+ status: "failed",
19167
+ filePath,
19168
+ message: `Cannot add changes to this ${artifactType}: the space it belongs to is not available to you.
18633
19169
  Use --space to stage it as a new artifact in an accessible space:
18634
19170
  ${formatSpaceList(allSpaces)}`
18635
- );
18636
- exit(1);
18637
- return;
19171
+ };
18638
19172
  }
18639
19173
  if (spaceSlug) {
18640
19174
  const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
18641
19175
  if (!matchedSpace) {
18642
- logErrorConsole(
18643
- `Space "@${spaceSlug}" not found. Available spaces:
19176
+ return {
19177
+ status: "failed",
19178
+ filePath,
19179
+ message: `Space "@${spaceSlug}" not found. Available spaces:
18644
19180
  ${formatSpaceList(allSpaces)}`
18645
- );
18646
- exit(1);
18647
- return;
19181
+ };
18648
19182
  }
18649
19183
  spaceId = matchedSpace.id;
18650
19184
  spaceName = matchedSpace.name;
@@ -18656,14 +19190,14 @@ ${formatSpaceList(allSpaces)}`
18656
19190
  spaceId = existingLockEntry.spaceId;
18657
19191
  spaceName = allSpaces.find((s) => s.id === spaceId)?.name;
18658
19192
  } else {
18659
- logErrorConsole(
18660
- `Multiple spaces found. Use --space to specify the target space:
19193
+ return {
19194
+ status: "failed",
19195
+ filePath,
19196
+ message: `Multiple spaces found. Use --space to specify the target space:
18661
19197
  ${formatSpaceList(allSpaces)}
18662
19198
 
18663
19199
  Example: packmind-cli playbook add --space ${allSpaces[0].slug} <path>`
18664
- );
18665
- exit(1);
18666
- return;
19200
+ };
18667
19201
  }
18668
19202
  }
18669
19203
  let changeType = "created";
@@ -18677,12 +19211,12 @@ Example: packmind-cli playbook add --space ${allSpaces[0].slug} <path>`
18677
19211
  }
18678
19212
  }
18679
19213
  if (changeType === "created" && earlyLockFile && earlyLockFile.agents.length > 0 && !earlyLockFile.agents.includes(codingAgent)) {
18680
- logErrorConsole(
18681
- `Cannot add this ${artifactType}: it is rendered for the "${codingAgent}" agent, which is not in your configured agents (${earlyLockFile.agents.join(", ")}).
19214
+ return {
19215
+ status: "failed",
19216
+ filePath,
19217
+ message: `Cannot add this ${artifactType}: it is rendered for the "${codingAgent}" agent, which is not in your configured agents (${earlyLockFile.agents.join(", ")}).
18682
19218
  This file is no longer managed by Packmind. Re-add "${codingAgent}" to your agents and run ${formatLabel("packmind-cli install")} to manage it again, or delete the file if it is no longer needed.`
18683
- );
18684
- exit(1);
18685
- return;
19219
+ };
18686
19220
  }
18687
19221
  if (changeType === "updated" && existingLockEntry) {
18688
19222
  try {
@@ -18693,18 +19227,20 @@ This file is no longer managed by Packmind. Re-add "${codingAgent}" to your agen
18693
19227
  existingLockEntry.spaceId
18694
19228
  );
18695
19229
  if (existingLockEntry.version < remoteVersion) {
18696
- logErrorConsole(
18697
- `"${artifactName}" is outdated (local: v${existingLockEntry.version}, remote: v${remoteVersion}).
19230
+ return {
19231
+ status: "failed",
19232
+ filePath,
19233
+ message: `"${artifactName}" is outdated (local: v${existingLockEntry.version}, remote: v${remoteVersion}).
18698
19234
  Run ${formatLabel("packmind-cli install")} to update before making changes.`
18699
- );
18700
- exit(1);
18701
- return;
19235
+ };
18702
19236
  }
18703
19237
  } catch (err) {
18704
19238
  const errorMessage = err instanceof Error ? err.message : String(err);
18705
- logErrorConsole(`Failed to check artifact version: ${errorMessage}`);
18706
- exit(1);
18707
- return;
19239
+ return {
19240
+ status: "failed",
19241
+ filePath,
19242
+ message: `Failed to check artifact version: ${errorMessage}`
19243
+ };
18708
19244
  }
18709
19245
  }
18710
19246
  if (changeType === "created") {
@@ -18718,11 +19254,11 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
18718
19254
  );
18719
19255
  } catch (err) {
18720
19256
  const errorMessage = err instanceof Error ? err.message : String(err);
18721
- logErrorConsole(
18722
- `Failed to check for existing ${artifactType}s: ${errorMessage}`
18723
- );
18724
- exit(1);
18725
- return;
19257
+ return {
19258
+ status: "failed",
19259
+ filePath,
19260
+ message: `Failed to check for existing ${artifactType}s: ${errorMessage}`
19261
+ };
18726
19262
  }
18727
19263
  if (existingArtifact) {
18728
19264
  let remoteVersion;
@@ -18735,11 +19271,11 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
18735
19271
  ));
18736
19272
  } catch (err) {
18737
19273
  const errorMessage = err instanceof Error ? err.message : String(err);
18738
- logErrorConsole(
18739
- `Failed to link "${existingArtifact.name}" to the existing ${artifactType}: ${errorMessage}`
18740
- );
18741
- exit(1);
18742
- return;
19274
+ return {
19275
+ status: "failed",
19276
+ filePath,
19277
+ message: `Failed to link "${existingArtifact.name}" to the existing ${artifactType}: ${errorMessage}`
19278
+ };
18743
19279
  }
18744
19280
  const adoptedFilePath = artifactType === "skill" ? `${normalizedFilePath}/SKILL.md` : normalizedFilePath;
18745
19281
  activeLockFile = adoptArtifactIntoLockFile({
@@ -18779,8 +19315,7 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
18779
19315
  });
18780
19316
  if (allMatch) {
18781
19317
  logInfoConsole("Already up to date \u2014 local content matches deployed.");
18782
- exit(0);
18783
- return;
19318
+ return { status: "skipped", filePath, artifactType };
18784
19319
  }
18785
19320
  } else {
18786
19321
  const deployedFile = deployedFiles.find(
@@ -18788,8 +19323,7 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
18788
19323
  );
18789
19324
  if (deployedFile && deployedFile.content?.trim() === localContent.trim()) {
18790
19325
  logInfoConsole("Already up to date \u2014 local content matches deployed.");
18791
- exit(0);
18792
- return;
19326
+ return { status: "skipped", filePath, artifactType };
18793
19327
  }
18794
19328
  }
18795
19329
  }
@@ -18810,25 +19344,55 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
18810
19344
  logSuccessConsole(
18811
19345
  `Staged "${artifactName}" (${artifactType}, ${changeType}) to playbook${spaceInfo}. ${formatLabel(codingAgent)}`
18812
19346
  );
18813
- logInfoConsole(
18814
- `Run ${formatLabel("packmind playbook submit")} when you're ready to publish your changes.`
18815
- );
18816
- exit(0);
19347
+ return { status: "staged", filePath, artifactType };
18817
19348
  }
18818
19349
  function formatSpaceList(spaces) {
18819
19350
  const maxSlugLength = Math.max(...spaces.map((s) => s.slug.length));
18820
19351
  return spaces.map((s) => ` ${s.slug.padEnd(maxSlugLength)} (${s.name})`).join("\n");
18821
19352
  }
18822
19353
 
19354
+ // apps/cli/src/infra/commands/playbook/addHandler.ts
19355
+ async function playbookAddHandler(deps) {
19356
+ const { filePaths, exit, ...rest } = deps;
19357
+ if (filePaths.length === 0) {
19358
+ logErrorConsole(
19359
+ "No path provided. Usage: packmind-cli playbook add <paths...>"
19360
+ );
19361
+ exit(1);
19362
+ return;
19363
+ }
19364
+ const outcomes = [];
19365
+ for (const filePath of filePaths) {
19366
+ const outcome = await stageSinglePath({ ...rest, filePath });
19367
+ outcomes.push(outcome);
19368
+ if (outcome.status === "failed") {
19369
+ logErrorConsole(`${filePath}: ${outcome.message ?? "failed to stage"}`);
19370
+ }
19371
+ }
19372
+ const failedCount = outcomes.filter((o) => o.status === "failed").length;
19373
+ const stagedCount = outcomes.filter((o) => o.status === "staged").length;
19374
+ if (filePaths.length > 1) {
19375
+ logInfoConsole(
19376
+ `${stagedCount} staged, ${failedCount} failed of ${filePaths.length}.`
19377
+ );
19378
+ }
19379
+ if (stagedCount > 0) {
19380
+ logInfoConsole(
19381
+ `Run ${formatLabel("packmind playbook submit")} when you're ready to publish your changes.`
19382
+ );
19383
+ }
19384
+ exit(failedCount > 0 ? 1 : 0);
19385
+ }
19386
+
18823
19387
  // apps/cli/src/infra/commands/playbook/AddCommand.ts
18824
19388
  var addPlaybookCommand = (0, import_cmd_ts23.command)({
18825
19389
  name: "add",
18826
- description: "Stage a local artifact change",
19390
+ description: "Stage one or more local artifact changes",
18827
19391
  args: {
18828
- filePath: (0, import_cmd_ts23.positional)({
19392
+ filePaths: (0, import_cmd_ts23.restPositionals)({
18829
19393
  type: import_cmd_ts23.string,
18830
- displayName: "path",
18831
- description: "Path to the artifact file or directory to stage"
19394
+ displayName: "paths",
19395
+ description: "Paths to the artifact files or directories to stage"
18832
19396
  }),
18833
19397
  space: (0, import_cmd_ts23.option)({
18834
19398
  type: (0, import_cmd_ts23.optional)(SpaceSlug),
@@ -18836,7 +19400,7 @@ var addPlaybookCommand = (0, import_cmd_ts23.command)({
18836
19400
  description: "Target space slug"
18837
19401
  })
18838
19402
  },
18839
- handler: async ({ filePath, space }) => {
19403
+ handler: async ({ filePaths, space }) => {
18840
19404
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
18841
19405
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
18842
19406
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
@@ -18847,7 +19411,7 @@ var addPlaybookCommand = (0, import_cmd_ts23.command)({
18847
19411
  const lockFileRepository = new LockFileRepository();
18848
19412
  await playbookAddHandler({
18849
19413
  packmindCliHexa,
18850
- filePath,
19414
+ filePaths,
18851
19415
  spaceSlug: space,
18852
19416
  exit: process.exit,
18853
19417
  cwd: process.cwd(),
@@ -19467,6 +20031,9 @@ var path35 = __toESM(require("path"));
19467
20031
 
19468
20032
  // apps/cli/src/infra/commands/playbook/submit/duplicateNameChecker.ts
19469
20033
  var import_slug5 = __toESM(require("slug"));
20034
+ function duplicateNameKey(entry) {
20035
+ return `${entry.spaceId}:${entry.artifactType}:${(0, import_slug5.default)(entry.artifactName)}`;
20036
+ }
19470
20037
  async function checkForDuplicateNames(createdEntries, packmindGateway) {
19471
20038
  const errors = [];
19472
20039
  const groups = /* @__PURE__ */ new Map();
@@ -19481,9 +20048,12 @@ async function checkForDuplicateNames(createdEntries, packmindGateway) {
19481
20048
  for (const entry of entries) {
19482
20049
  const sluggedName = (0, import_slug5.default)(entry.artifactName);
19483
20050
  if (seen.has(sluggedName)) {
19484
- errors.push(
19485
- `A ${entry.artifactType} named "${entry.artifactName}" is staged multiple times. Remove the duplicate with "playbook unstage" or rename the artifact.`
19486
- );
20051
+ errors.push({
20052
+ spaceId: entry.spaceId,
20053
+ artifactType: entry.artifactType,
20054
+ artifactName: entry.artifactName,
20055
+ message: `A ${entry.artifactType} named "${entry.artifactName}" is staged multiple times. Remove the duplicate with "playbook unstage" or rename the artifact.`
20056
+ });
19487
20057
  } else {
19488
20058
  seen.set(sluggedName, entry.artifactName);
19489
20059
  }
@@ -19513,9 +20083,12 @@ async function checkForDuplicateNames(createdEntries, packmindGateway) {
19513
20083
  const existingNamesSlugged = new Set(existingNames.map((n) => (0, import_slug5.default)(n)));
19514
20084
  for (const entry of entries) {
19515
20085
  if (existingNamesSlugged.has((0, import_slug5.default)(entry.artifactName))) {
19516
- errors.push(
19517
- `A ${entry.artifactType} named "${entry.artifactName}" already exists in this space. Use "playbook unstage" to remove it or rename the artifact.`
19518
- );
20086
+ errors.push({
20087
+ spaceId: entry.spaceId,
20088
+ artifactType: entry.artifactType,
20089
+ artifactName: entry.artifactName,
20090
+ message: `A ${entry.artifactType} named "${entry.artifactName}" already exists in this space. Use "playbook unstage" to remove it or rename the artifact.`
20091
+ });
19519
20092
  }
19520
20093
  }
19521
20094
  } catch {
@@ -20335,13 +20908,42 @@ async function playbookSubmitHandler(deps) {
20335
20908
  exit(0);
20336
20909
  return;
20337
20910
  }
20911
+ const createdEntries = changes.filter((c) => c.changeType === "created");
20912
+ const conflictingKeys = /* @__PURE__ */ new Set();
20913
+ if (createdEntries.length > 0) {
20914
+ const duplicateErrors = await checkForDuplicateNames(
20915
+ createdEntries,
20916
+ packmindCliHexa.getPackmindGateway()
20917
+ );
20918
+ for (const error of duplicateErrors) {
20919
+ logErrorConsole(error.message);
20920
+ conflictingKeys.add(duplicateNameKey(error));
20921
+ }
20922
+ }
20923
+ const submittableChanges = changes.filter(
20924
+ (c) => !(c.changeType === "created" && conflictingKeys.has(duplicateNameKey(c)))
20925
+ );
20926
+ const conflictCount = changes.length - submittableChanges.length;
20927
+ const reportSkippedConflicts = () => {
20928
+ if (conflictCount === 0) return;
20929
+ logInfoConsole(
20930
+ `${conflictCount} change${conflictCount !== 1 ? "s were" : " was"} skipped and remain${conflictCount !== 1 ? "" : "s"} staged. Rename them and run \`packmind playbook submit\` again.`
20931
+ );
20932
+ };
20933
+ if (submittableChanges.length === 0) {
20934
+ logErrorConsole(
20935
+ "Nothing to submit: every staged change has a name conflict."
20936
+ );
20937
+ exit(1);
20938
+ return;
20939
+ }
20338
20940
  let resolvedMessage;
20339
20941
  if (message) {
20340
20942
  resolvedMessage = message;
20341
20943
  } else if (noReview) {
20342
20944
  resolvedMessage = "";
20343
20945
  } else {
20344
- const prefill = buildEditorPrefill(changes);
20946
+ const prefill = buildEditorPrefill(submittableChanges);
20345
20947
  const editorResult = openEditor(prefill);
20346
20948
  if (!editorResult) {
20347
20949
  logErrorConsole("Aborting: empty message.");
@@ -20356,20 +20958,6 @@ async function playbookSubmitHandler(deps) {
20356
20958
  }
20357
20959
  resolvedMessage = stripped;
20358
20960
  }
20359
- const createdEntries = changes.filter((c) => c.changeType === "created");
20360
- if (createdEntries.length > 0) {
20361
- const duplicateErrors = await checkForDuplicateNames(
20362
- createdEntries,
20363
- packmindCliHexa.getPackmindGateway()
20364
- );
20365
- if (duplicateErrors.length > 0) {
20366
- for (const error of duplicateErrors) {
20367
- logErrorConsole(error);
20368
- }
20369
- exit(1);
20370
- return;
20371
- }
20372
- }
20373
20961
  const resolver = await createTargetContextResolver({
20374
20962
  lockFileRepository,
20375
20963
  cwd,
@@ -20379,7 +20967,7 @@ async function playbookSubmitHandler(deps) {
20379
20967
  proposals: allProposals,
20380
20968
  conflicts,
20381
20969
  skipped
20382
- } = await buildProposals(changes, resolver.getTargetContext);
20970
+ } = await buildProposals(submittableChanges, resolver.getTargetContext);
20383
20971
  const descriptionErrors = validateProposalSkillDescriptions(allProposals);
20384
20972
  if (descriptionErrors.length > 0) {
20385
20973
  for (const error of descriptionErrors) {
@@ -20423,10 +21011,11 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20423
21011
  logConsole(
20424
21012
  "Nothing to submit \u2014 no changes detected compared to deployed versions."
20425
21013
  );
20426
- for (const entry of changes) {
21014
+ for (const entry of submittableChanges) {
20427
21015
  playbookLocalRepository.removeChange(entry.filePath, entry.spaceId);
20428
21016
  }
20429
- exit(0);
21017
+ reportSkippedConflicts();
21018
+ exit(conflictCount > 0 ? 1 : 0);
20430
21019
  return;
20431
21020
  }
20432
21021
  const removalPackageIds = /* @__PURE__ */ new Set();
@@ -20439,7 +21028,7 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20439
21028
  }
20440
21029
  }
20441
21030
  const filePathsBySpaceId = /* @__PURE__ */ new Map();
20442
- for (const entry of changes) {
21031
+ for (const entry of submittableChanges) {
20443
21032
  const existing = filePathsBySpaceId.get(entry.spaceId) ?? /* @__PURE__ */ new Set();
20444
21033
  existing.add(entry.filePath);
20445
21034
  filePathsBySpaceId.set(entry.spaceId, existing);
@@ -20463,7 +21052,8 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20463
21052
  );
20464
21053
  if (applyProposals.length === 0) {
20465
21054
  logConsole("Nothing to apply directly.");
20466
- exit(0);
21055
+ reportSkippedConflicts();
21056
+ exit(conflictCount > 0 ? 1 : 0);
20467
21057
  return;
20468
21058
  }
20469
21059
  let response;
@@ -20527,11 +21117,12 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20527
21117
  createdSpaceIds
20528
21118
  );
20529
21119
  logPackageAddGuidance(response.created, packageSlugs);
20530
- exit(0);
21120
+ reportSkippedConflicts();
21121
+ exit(conflictCount > 0 ? 1 : 0);
20531
21122
  return;
20532
21123
  }
20533
21124
  const spaceNameById = /* @__PURE__ */ new Map();
20534
- for (const change of changes) {
21125
+ for (const change of submittableChanges) {
20535
21126
  if (change.spaceName && !spaceNameById.has(change.spaceId)) {
20536
21127
  spaceNameById.set(change.spaceId, change.spaceName);
20537
21128
  }
@@ -20570,7 +21161,9 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20570
21161
  totalSkipped += response.skipped;
20571
21162
  if (response.errors.length > 0) {
20572
21163
  const filePaths = filePathsBySpaceId.get(spaceId) ?? /* @__PURE__ */ new Set();
20573
- const spaceChanges = changes.filter((c) => filePaths.has(c.filePath));
21164
+ const spaceChanges = submittableChanges.filter(
21165
+ (c) => filePaths.has(c.filePath)
21166
+ );
20574
21167
  const allRemovals = spaceChanges.length > 0 && spaceChanges.every((c) => c.changeType === "removed");
20575
21168
  const allSpaceNotFound = response.errors.every(
20576
21169
  (e) => e.code === "SpaceNotFoundError"
@@ -20610,7 +21203,7 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20610
21203
  for (const filePath of filePaths) {
20611
21204
  playbookLocalRepository.removeChange(filePath, spaceId);
20612
21205
  }
20613
- const removedEntries = changes.filter(
21206
+ const removedEntries = submittableChanges.filter(
20614
21207
  (c) => c.changeType === "removed" && filePaths.has(c.filePath)
20615
21208
  );
20616
21209
  for (const entry of removedEntries) {
@@ -20664,7 +21257,8 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
20664
21257
  if (totalCreated > 0) {
20665
21258
  await logReviewUrls(packmindCliHexa, succeededSpaces);
20666
21259
  }
20667
- exit(0);
21260
+ reportSkippedConflicts();
21261
+ exit(conflictCount > 0 ? 1 : 0);
20668
21262
  }
20669
21263
 
20670
21264
  // apps/cli/src/infra/utils/editorMessage.ts
@@ -21766,7 +22360,9 @@ var initCommand = (0, import_cmd_ts38.command)({
21766
22360
  baseDirectory,
21767
22361
  installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
21768
22362
  ensureCliVersion: packmindCliHexa.ensureCliVersion.bind(packmindCliHexa),
21769
- cliVersion: CLI_VERSION5
22363
+ cliVersion: CLI_VERSION5,
22364
+ isTTY: Boolean(process.stdin.isTTY),
22365
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
21770
22366
  });
21771
22367
  if (!result.success) {
21772
22368
  for (const error of result.errors) {
@@ -21777,14 +22373,193 @@ var initCommand = (0, import_cmd_ts38.command)({
21777
22373
  }
21778
22374
  });
21779
22375
 
21780
- // apps/cli/src/infra/commands/UpdateCommand.ts
22376
+ // apps/cli/src/infra/commands/TrackCommand.ts
21781
22377
  var import_cmd_ts39 = __toESM(require_cjs());
22378
+
22379
+ // apps/cli/src/infra/commands/trackingErrors.ts
22380
+ function handleTrackingError(error) {
22381
+ if (error instanceof NotLoggedInError) {
22382
+ logErrorConsole(error.message);
22383
+ process.exit(1);
22384
+ return;
22385
+ }
22386
+ const statusCode = error?.statusCode;
22387
+ if (statusCode === 404) {
22388
+ logErrorConsole("Repository tracking is not available for your account.");
22389
+ process.exit(1);
22390
+ return;
22391
+ }
22392
+ if (statusCode === 403) {
22393
+ logErrorConsole(
22394
+ "Only organization admins can change which repository Packmind tracks. Ask an admin of your organization to run this command."
22395
+ );
22396
+ process.exit(1);
22397
+ return;
22398
+ }
22399
+ const message = error instanceof Error ? error.message : String(error);
22400
+ logErrorConsole(message);
22401
+ process.exit(1);
22402
+ }
22403
+
22404
+ // apps/cli/src/infra/commands/trackHandler.ts
22405
+ async function trackHandler(deps) {
22406
+ const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
22407
+ const confirm = createTrackConfirm({
22408
+ isTTY,
22409
+ confirmPrompt: deps.confirmPrompt
22410
+ });
22411
+ let result;
22412
+ try {
22413
+ result = await deps.trackRepository({
22414
+ repoPath: deps.baseDirectory,
22415
+ origin: "track",
22416
+ update: deps.update,
22417
+ remove: false,
22418
+ branch: deps.branch,
22419
+ confirm
22420
+ });
22421
+ } catch (error) {
22422
+ handleTrackingError(error);
22423
+ return;
22424
+ }
22425
+ switch (result.status) {
22426
+ case "set":
22427
+ logSuccessConsole(
22428
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
22429
+ );
22430
+ process.exit(0);
22431
+ return;
22432
+ case "updated":
22433
+ logSuccessConsole(
22434
+ `Tracked branch for ${result.owner}/${result.repo} changed from ${result.fromBranch} to ${result.branch}.`
22435
+ );
22436
+ process.exit(0);
22437
+ return;
22438
+ case "cancelled":
22439
+ logInfoConsole("No changes made. The tracked branch is unchanged.");
22440
+ process.exit(0);
22441
+ return;
22442
+ // The desired state is already in place, whether or not --update was
22443
+ // passed, so both spellings succeed. Exit codes follow one rule: 0 when
22444
+ // the desired state holds, 1 when it cannot be reached.
22445
+ case "already-tracked-same-branch":
22446
+ logInfoConsole(
22447
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
22448
+ );
22449
+ process.exit(0);
22450
+ return;
22451
+ case "already-tracked-other-branch":
22452
+ logErrorConsole(
22453
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.trackedBranch}. Run ${formatCommand(
22454
+ "packmind track --update"
22455
+ )} to move it to ${result.branch}.`
22456
+ );
22457
+ process.exit(1);
22458
+ return;
22459
+ case "nothing-tracked":
22460
+ logErrorConsole(
22461
+ `Nothing is tracked yet \u2014 run ${formatCommand("packmind init")} or ${formatCommand("packmind track")} to start tracking.`
22462
+ );
22463
+ process.exit(1);
22464
+ return;
22465
+ default:
22466
+ return;
22467
+ }
22468
+ }
22469
+
22470
+ // apps/cli/src/infra/commands/TrackCommand.ts
22471
+ var trackCommand = (0, import_cmd_ts39.command)({
22472
+ name: "track",
22473
+ description: "Set the repository and branch Packmind tracks for the current project",
22474
+ args: {
22475
+ update: (0, import_cmd_ts39.flag)({
22476
+ long: "update",
22477
+ description: "Move the tracked branch to the current branch (requires an existing tracked branch)"
22478
+ }),
22479
+ branch: (0, import_cmd_ts39.option)({
22480
+ type: (0, import_cmd_ts39.optional)(import_cmd_ts39.string),
22481
+ long: "branch",
22482
+ description: "Branch to track (defaults to the branch currently checked out)"
22483
+ })
22484
+ },
22485
+ handler: async ({ update, branch }) => {
22486
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22487
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22488
+ await trackHandler({
22489
+ update,
22490
+ branch,
22491
+ baseDirectory: process.cwd(),
22492
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
22493
+ });
22494
+ }
22495
+ });
22496
+
22497
+ // apps/cli/src/infra/commands/UntrackCommand.ts
22498
+ var import_cmd_ts40 = __toESM(require_cjs());
22499
+
22500
+ // apps/cli/src/infra/commands/untrackHandler.ts
22501
+ async function untrackHandler(deps) {
22502
+ const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
22503
+ const confirm = createTrackConfirm({
22504
+ isTTY,
22505
+ confirmPrompt: deps.confirmPrompt
22506
+ });
22507
+ let result;
22508
+ try {
22509
+ result = await deps.trackRepository({
22510
+ repoPath: deps.baseDirectory,
22511
+ origin: "track",
22512
+ update: false,
22513
+ remove: true,
22514
+ confirm
22515
+ });
22516
+ } catch (error) {
22517
+ handleTrackingError(error);
22518
+ return;
22519
+ }
22520
+ switch (result.status) {
22521
+ case "removed":
22522
+ logSuccessConsole(
22523
+ `Packmind no longer tracks ${result.owner}/${result.repo}. Distributions recorded on branch ${result.branch} are kept and reappear if you track it again.`
22524
+ );
22525
+ process.exit(0);
22526
+ return;
22527
+ case "not-tracked":
22528
+ logWarningConsole(
22529
+ `Repository is not tracked in '${result.organizationName}' organization`
22530
+ );
22531
+ process.exit(0);
22532
+ return;
22533
+ default:
22534
+ logInfoConsole("No changes made. The tracked branch is unchanged.");
22535
+ process.exit(0);
22536
+ return;
22537
+ }
22538
+ }
22539
+
22540
+ // apps/cli/src/infra/commands/UntrackCommand.ts
22541
+ var untrackCommand = (0, import_cmd_ts40.command)({
22542
+ name: "untrack",
22543
+ description: "Remove Packmind's tracking of the current repository (keeps every recorded distribution)",
22544
+ args: {},
22545
+ handler: async () => {
22546
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22547
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22548
+ await untrackHandler({
22549
+ baseDirectory: process.cwd(),
22550
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
22551
+ });
22552
+ }
22553
+ });
22554
+
22555
+ // apps/cli/src/infra/commands/UpdateCommand.ts
22556
+ var import_cmd_ts41 = __toESM(require_cjs());
21782
22557
  var { version: CLI_VERSION6 } = require_package();
21783
- var updateCommand = (0, import_cmd_ts39.command)({
22558
+ var updateCommand = (0, import_cmd_ts41.command)({
21784
22559
  name: "update",
21785
22560
  description: "Update packmind-cli to the latest version",
21786
22561
  args: {
21787
- check: (0, import_cmd_ts39.flag)({
22562
+ check: (0, import_cmd_ts41.flag)({
21788
22563
  long: "check",
21789
22564
  description: "Only check if a newer version is available without performing the update"
21790
22565
  })
@@ -21842,7 +22617,7 @@ if (args.includes("--version") || args.includes("-v")) {
21842
22617
  logConsole(`packmind-cli version ${CLI_VERSION7}`);
21843
22618
  process.exit(0);
21844
22619
  }
21845
- var app = (0, import_cmd_ts40.subcommands)({
22620
+ var app = (0, import_cmd_ts42.subcommands)({
21846
22621
  name: "packmind-cli",
21847
22622
  description: "Packmind CLI tool",
21848
22623
  cmds: {
@@ -21859,12 +22634,14 @@ var app = (0, import_cmd_ts40.subcommands)({
21859
22634
  skills: skillsCommand,
21860
22635
  spaces: spacesCommand,
21861
22636
  standards: standardsCommand,
22637
+ track: trackCommand,
21862
22638
  uninstall: uninstallCommand,
22639
+ untrack: untrackCommand,
21863
22640
  update: updateCommand,
21864
22641
  whoami: whoamiCommand
21865
22642
  }
21866
22643
  });
21867
- (0, import_cmd_ts40.run)(app, args).catch((error) => {
22644
+ (0, import_cmd_ts42.run)(app, args).catch((error) => {
21868
22645
  logErrorConsole(error.message);
21869
22646
  process.exit(1);
21870
22647
  });