@packmind/cli 0.30.1 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/main.cjs +1740 -1434
  2. package/package.json +9 -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)
@@ -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(string20, substring, replacer) {
375
- let index = string20.indexOf(substring);
383
+ function stringReplaceAll(string16, substring, replacer) {
384
+ let index = string16.indexOf(substring);
376
385
  if (index === -1) {
377
- return string20;
386
+ return string16;
378
387
  }
379
388
  const substringLength = substring.length;
380
389
  let endIndex = 0;
381
390
  let returnValue = "";
382
391
  do {
383
- returnValue += string20.slice(endIndex, index) + substring + replacer;
392
+ returnValue += string16.slice(endIndex, index) + substring + replacer;
384
393
  endIndex = index + substringLength;
385
- index = string20.indexOf(substring, endIndex);
394
+ index = string16.indexOf(substring, endIndex);
386
395
  } while (index !== -1);
387
- returnValue += string20.slice(endIndex);
396
+ returnValue += string16.slice(endIndex);
388
397
  return returnValue;
389
398
  }
390
- function stringEncaseCRLFWithFirstIndex(string20, prefix, postfix, index) {
399
+ function stringEncaseCRLFWithFirstIndex(string16, prefix, postfix, index) {
391
400
  let endIndex = 0;
392
401
  let returnValue = "";
393
402
  do {
394
- const gotCR = string20[index - 1] === "\r";
395
- returnValue += string20.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
403
+ const gotCR = string16[index - 1] === "\r";
404
+ returnValue += string16.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
405
  endIndex = index + 1;
397
- index = string20.indexOf("\n", endIndex);
406
+ index = string16.indexOf("\n", endIndex);
398
407
  } while (index !== -1);
399
- returnValue += string20.slice(endIndex);
408
+ returnValue += string16.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, string20) => {
559
- if (self.level <= 0 || !string20) {
560
- return self[IS_EMPTY] ? "" : string20;
567
+ applyStyle = (self, string16) => {
568
+ if (self.level <= 0 || !string16) {
569
+ return self[IS_EMPTY] ? "" : string16;
561
570
  }
562
571
  let styler = self[STYLER];
563
572
  if (styler === void 0) {
564
- return string20;
573
+ return string16;
565
574
  }
566
575
  const { openAll, closeAll } = styler;
567
- if (string20.includes("\x1B")) {
576
+ if (string16.includes("\x1B")) {
568
577
  while (styler !== void 0) {
569
- string20 = stringReplaceAll(string20, styler.close, styler.open);
578
+ string16 = stringReplaceAll(string16, styler.close, styler.open);
570
579
  styler = styler.parent;
571
580
  }
572
581
  }
573
- const lfIndex = string20.indexOf("\n");
582
+ const lfIndex = string16.indexOf("\n");
574
583
  if (lfIndex !== -1) {
575
- string20 = stringEncaseCRLFWithFirstIndex(string20, closeAll, openAll, lfIndex);
584
+ string16 = stringEncaseCRLFWithFirstIndex(string16, closeAll, openAll, lfIndex);
576
585
  }
577
- return openAll + string20 + closeAll;
586
+ return openAll + string16 + 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 option22 of node.options) {
771
- if (opts.shortNames.includes(option22.key)) {
772
- result.push(option22);
779
+ for (const option18 of node.options) {
780
+ if (opts.shortNames.includes(option18.key)) {
781
+ result.push(option18);
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 = optional18;
854
+ exports2.optional = optional13;
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 optional18(t) {
881
+ function optional13(t) {
873
882
  return {
874
883
  ...t,
875
884
  defaultValue() {
@@ -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 = positional12;
1267
+ exports2.positional = positional9;
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 positional13 = positionals[0];
1299
- if (!positional13) {
1307
+ const positional10 = positionals[0];
1308
+ if (!positional10) {
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(positional13);
1313
- const decoded = await Result.safeAsync(config.type.from(positional13.raw));
1321
+ visitedNodes.add(positional10);
1322
+ const decoded = await Result.safeAsync(config.type.from(positional10.raw));
1314
1323
  if (Result.isErr(decoded)) {
1315
1324
  return Result.err({
1316
1325
  errors: [
1317
1326
  {
1318
- nodes: [positional13],
1327
+ nodes: [positional10],
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 positional12(config) {
1337
+ function positional9(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 option22 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1415
+ const option18 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1407
1416
  errorMessage += `
1408
- Did you mean ${chalk_1.default.italic(option22)}?`;
1417
+ Did you mean ${chalk_1.default.italic(option18)}?`;
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(string20) {
1582
- if (typeof string20 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string20}\``);
1590
+ function stripAnsi(string16) {
1591
+ if (typeof string16 !== "string") {
1592
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string16}\``);
1584
1593
  }
1585
- if (!string20.includes("\x1B") && !string20.includes("\x9B")) {
1586
- return string20;
1594
+ if (!string16.includes("\x1B") && !string16.includes("\x9B")) {
1595
+ return string16;
1587
1596
  }
1588
- return string20.replace(regex, "");
1597
+ return string16.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 = command34;
1713
+ exports2.command = command31;
1705
1714
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1706
1715
  var Result = __importStar(require_Result());
1707
1716
  var circuitbreaker_1 = require_circuitbreaker();
1708
1717
  var utils_1 = require_utils();
1709
- function command34(config) {
1718
+ function command31(config) {
1710
1719
  const argEntries = (0, utils_1.entries)(config.args);
1711
1720
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1712
1721
  return {
@@ -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 option22 of node.options) {
1788
- if (context.visitedNodes.has(option22)) {
1796
+ for (const option18 of node.options) {
1797
+ if (context.visitedNodes.has(option18)) {
1789
1798
  continue;
1790
1799
  }
1791
- unknownArguments.push(option22);
1800
+ unknownArguments.push(option18);
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 = option22;
1879
+ exports2.option = option18;
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 option23 = options[0];
1955
+ const option19 = options[0];
1947
1956
  let rawValue;
1948
1957
  let envPrefix = "";
1949
- if (option23 === null || option23 === void 0 ? void 0 : option23.value) {
1950
- rawValue = option23.value.node.raw;
1958
+ if (option19 === null || option19 === void 0 ? void 0 : option19.value) {
1959
+ rawValue = option19.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 = (option23 === null || option23 === void 0 ? void 0 : option23.type) === "shortOption" ? `-${option23 === null || option23 === void 0 ? void 0 : option23.key}` : `--${config.long}`;
1994
+ const raw = (option19 === null || option19 === void 0 ? void 0 : option19.type) === "shortOption" ? `-${option19 === null || option19 === void 0 ? void 0 : option19.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 option22(config) {
2016
+ function option18(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 option22 of node.options) {
2047
- if (error.nodes.includes(option22)) {
2048
- s += chalk_1.default.red(option22.raw);
2055
+ for (const option18 of node.options) {
2056
+ if (error.nodes.includes(option18)) {
2057
+ s += chalk_1.default.red(option18.raw);
2049
2058
  failed = true;
2050
2059
  } else {
2051
- s += chalk_1.default.dim(option22.raw);
2060
+ s += chalk_1.default.dim(option18.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;
@@ -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, string20] of (0, utils_1.enumerate)(strings)) {
3085
- const chars = [...string20];
3093
+ for (const [stringIndex, string16] of (0, utils_1.enumerate)(strings)) {
3094
+ const chars = [...string16];
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 = restPositionals5;
3227
+ exports2.restPositionals = restPositionals4;
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 positional12 of positionals) {
3242
- visitedNodes.add(positional12);
3243
- const decoded = await Result.safeAsync(config.type.from(positional12.raw));
3250
+ for (const positional9 of positionals) {
3251
+ visitedNodes.add(positional9);
3252
+ const decoded = await Result.safeAsync(config.type.from(positional9.raw));
3244
3253
  if (Result.isOk(decoded)) {
3245
3254
  results.push(decoded.value);
3246
3255
  } else {
3247
3256
  errors.push({
3248
- nodes: [positional12],
3257
+ nodes: [positional9],
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 restPositionals5(config) {
3271
+ function restPositionals4(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 option22 of options) {
3347
- visitedNodes.add(option22);
3355
+ for (const option18 of options) {
3356
+ visitedNodes.add(option18);
3348
3357
  }
3349
3358
  const optionValues = [];
3350
3359
  const errors = [];
3351
- for (const option22 of options) {
3352
- const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option22.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3360
+ for (const option18 of options) {
3361
+ 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"));
3353
3362
  if (Result.isErr(decoded)) {
3354
- errors.push({ nodes: [option22], message: decoded.error.message });
3363
+ errors.push({ nodes: [option18], 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 option22 of options) {
3519
- visitedNodes.add(option22);
3527
+ for (const option18 of options) {
3528
+ visitedNodes.add(option18);
3520
3529
  }
3521
3530
  const optionValues = [];
3522
3531
  const errors = [];
3523
3532
  const flagNodes = [];
3524
- for (const option22 of options) {
3525
- const providedValue = (_a = option22.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3533
+ for (const option18 of options) {
3534
+ const providedValue = (_a = option18.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3526
3535
  if (providedValue === void 0) {
3527
- flagNodes.push(option22);
3536
+ flagNodes.push(option18);
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.30.1",
3861
+ version: "0.32.0",
3853
3862
  description: "A command-line interface for Packmind linting and code quality checks",
3854
3863
  private: false,
3855
3864
  bin: {
@@ -3884,14 +3893,19 @@ var require_package = __commonJS({
3884
3893
  "packmind-cli": "ts-node --project tsconfig.app.json src/main.ts"
3885
3894
  },
3886
3895
  dependencies: {
3887
- "@types/inquirer": "^9.0.9",
3896
+ chalk: "^5.6.0",
3897
+ "cmd-ts": "^0.14.3",
3898
+ diff: "^8.0.3",
3888
3899
  dotenv: "^16",
3889
3900
  inquirer: "^13.0.2",
3901
+ "log-update": "^8.0.0",
3890
3902
  minimatch: "^10",
3903
+ open: "^11.0.0",
3891
3904
  semver: "^7.7.4",
3892
- undici: "^7",
3905
+ slug: "^11.0.0",
3906
+ undici: "^7.28.0",
3893
3907
  which: "^4.0.0",
3894
- zod: "^4.3.5"
3908
+ yaml: "^2.8.3"
3895
3909
  },
3896
3910
  devDependencies: {
3897
3911
  "@types/which": "^3.0.4"
@@ -3901,7 +3915,7 @@ var require_package = __commonJS({
3901
3915
  });
3902
3916
 
3903
3917
  // apps/cli/src/main.ts
3904
- var import_cmd_ts44 = __toESM(require_cjs());
3918
+ var import_cmd_ts41 = __toESM(require_cjs());
3905
3919
 
3906
3920
  // apps/cli/src/infra/commands/LinterCommand.ts
3907
3921
  var import_cmd_ts = __toESM(require_cjs());
@@ -4044,20 +4058,6 @@ var UserJoinedOrganizationEvent = class extends UserEvent {
4044
4058
  }
4045
4059
  };
4046
4060
 
4047
- // packages/types/src/accounts/events/AnonymousTrialStartedEvent.ts
4048
- var AnonymousTrialStartedEvent = class extends UserEvent {
4049
- static {
4050
- this.eventName = "accounts.anonymous-trial.started";
4051
- }
4052
- };
4053
-
4054
- // packages/types/src/accounts/events/AnonymousTrialAccountActivatedEvent.ts
4055
- var AnonymousTrialAccountActivatedEvent = class extends UserEvent {
4056
- static {
4057
- this.eventName = "accounts.anonymous-trial.activated";
4058
- }
4059
- };
4060
-
4061
4061
  // packages/types/src/accounts/events/OrganizationCreatedEvent.ts
4062
4062
  var OrganizationCreatedEvent = class extends UserEvent {
4063
4063
  static {
@@ -4072,10 +4072,6 @@ var UserSignedInEvent = class extends UserEvent {
4072
4072
  }
4073
4073
  };
4074
4074
 
4075
- // packages/types/src/accounts/TrialActivationToken.ts
4076
- var createTrialActivationTokenId = brandedIdFactory();
4077
- var createTrialActivationToken = brandedIdFactory();
4078
-
4079
4075
  // packages/types/src/coding-agent/validation.ts
4080
4076
  var VALID_CODING_AGENTS = [
4081
4077
  "packmind",
@@ -4274,27 +4270,27 @@ function validateArtifactFileFormat(filePath, artifactType) {
4274
4270
  return { valid: true };
4275
4271
  }
4276
4272
 
4277
- // packages/types/src/recipes/RecipeId.ts
4278
- var createRecipeId = brandedIdFactory();
4273
+ // packages/types/src/commands/CommandId.ts
4274
+ var createCommandId = brandedIdFactory();
4279
4275
 
4280
- // packages/types/src/recipes/RecipeVersion.ts
4281
- var createRecipeVersionId = brandedIdFactory();
4276
+ // packages/types/src/commands/CommandVersion.ts
4277
+ var createCommandVersionId = brandedIdFactory();
4282
4278
 
4283
- // packages/types/src/recipes/events/CommandCreatedEvent.ts
4279
+ // packages/types/src/commands/events/CommandCreatedEvent.ts
4284
4280
  var CommandCreatedEvent = class extends UserEvent {
4285
4281
  static {
4286
4282
  this.eventName = "recipes.recipe.created";
4287
4283
  }
4288
4284
  };
4289
4285
 
4290
- // packages/types/src/recipes/events/CommandDeletedEvent.ts
4286
+ // packages/types/src/commands/events/CommandDeletedEvent.ts
4291
4287
  var CommandDeletedEvent = class extends UserEvent {
4292
4288
  static {
4293
4289
  this.eventName = "recipes.recipe.deleted";
4294
4290
  }
4295
4291
  };
4296
4292
 
4297
- // packages/types/src/recipes/events/CommandUpdatedEvent.ts
4293
+ // packages/types/src/commands/events/CommandUpdatedEvent.ts
4298
4294
  var CommandUpdatedEvent = class extends UserEvent {
4299
4295
  static {
4300
4296
  this.eventName = "recipes.recipe.updated";
@@ -4366,7 +4362,8 @@ var CLAUDE_CODE_ADDITIONAL_FIELDS = {
4366
4362
  effort: "effort",
4367
4363
  hooks: "hooks",
4368
4364
  paths: "paths",
4369
- shell: "shell"
4365
+ shell: "shell",
4366
+ "disallowed-tools": "disallowedTools"
4370
4367
  };
4371
4368
  var CAMEL_TO_YAML_KEY = Object.fromEntries(
4372
4369
  Object.entries(CLAUDE_CODE_ADDITIONAL_FIELDS).map(([yaml4, camel]) => [
@@ -4462,6 +4459,13 @@ var DeploymentCompletedEvent = class extends UserEvent {
4462
4459
  }
4463
4460
  };
4464
4461
 
4462
+ // packages/types/src/deployments/events/DistributionRecordedEvent.ts
4463
+ var DistributionRecordedEvent = class extends UserEvent {
4464
+ static {
4465
+ this.eventName = "deployments.distribution.recorded";
4466
+ }
4467
+ };
4468
+
4465
4469
  // packages/types/src/deployments/events/PackagesDeletedEvent.ts
4466
4470
  var PackagesDeletedEvent = class extends UserEvent {
4467
4471
  static {
@@ -4495,6 +4499,13 @@ var createGitProviderId = brandedIdFactory();
4495
4499
  // packages/types/src/git/OrganizationGitHubApp.ts
4496
4500
  var createOrganizationGitHubAppId = brandedIdFactory();
4497
4501
 
4502
+ // packages/types/src/git/events/RepositoryTrackingSetEvent.ts
4503
+ var RepositoryTrackingSetEvent = class extends UserEvent {
4504
+ static {
4505
+ this.eventName = "git.repository.tracking-set";
4506
+ }
4507
+ };
4508
+
4498
4509
  // packages/types/src/spaces/SpaceId.ts
4499
4510
  var createSpaceId = brandedIdFactory();
4500
4511
 
@@ -4547,6 +4558,20 @@ var SpaceVisibilityUpdatedEvent = class extends UserEvent {
4547
4558
  }
4548
4559
  };
4549
4560
 
4561
+ // packages/types/src/spaces/events/SpaceDeletedEvent.ts
4562
+ var SpaceDeletedEvent = class extends UserEvent {
4563
+ static {
4564
+ this.eventName = "spaces.space.deleted";
4565
+ }
4566
+ };
4567
+
4568
+ // packages/types/src/spaces/events/SpaceRenamedEvent.ts
4569
+ var SpaceRenamedEvent = class extends UserEvent {
4570
+ static {
4571
+ this.eventName = "spaces.space.renamed";
4572
+ }
4573
+ };
4574
+
4550
4575
  // packages/types/src/spaces-management/events/PlaybookArtefactMovedEvent.ts
4551
4576
  var PlaybookArtefactMovedEvent = class extends UserEvent {
4552
4577
  static {
@@ -5395,8 +5420,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
5395
5420
  static {
5396
5421
  this.fallbackRuleContent = "adhoc-rule";
5397
5422
  }
5398
- async execute(command34) {
5399
- const { program, fileContent, language } = command34;
5423
+ async execute(command31) {
5424
+ const { program, fileContent, language } = command31;
5400
5425
  const result = await this.linterExecutionUseCase.execute({
5401
5426
  filePath: "cli-single-file",
5402
5427
  fileContent,
@@ -5780,8 +5805,8 @@ var GetGitRemoteUrlUseCase = class {
5780
5805
  constructor(gitRemoteUrlService = new GitService()) {
5781
5806
  this.gitRemoteUrlService = gitRemoteUrlService;
5782
5807
  }
5783
- async execute(command34) {
5784
- const { path: repoPath, origin: origin9 } = command34;
5808
+ async execute(command31) {
5809
+ const { path: repoPath, origin: origin9 } = command31;
5785
5810
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5786
5811
  }
5787
5812
  };
@@ -5933,8 +5958,8 @@ var ListFilesInDirectoryUseCase = class {
5933
5958
  constructor(listFiles = new ListFiles()) {
5934
5959
  this.listFiles = listFiles;
5935
5960
  }
5936
- async execute(command34) {
5937
- const { path: directoryPath, extensions, excludes = [] } = command34;
5961
+ async execute(command31) {
5962
+ const { path: directoryPath, extensions, excludes = [] } = command31;
5938
5963
  const files = await this.listFiles.listFilesInDirectory(
5939
5964
  directoryPath,
5940
5965
  extensions,
@@ -6049,7 +6074,7 @@ var LintFilesAgainstRuleUseCase = class {
6049
6074
  };
6050
6075
  };
6051
6076
  }
6052
- async execute(command34) {
6077
+ async execute(command31) {
6053
6078
  const {
6054
6079
  path: userPath,
6055
6080
  draftMode,
@@ -6058,7 +6083,7 @@ var LintFilesAgainstRuleUseCase = class {
6058
6083
  language,
6059
6084
  diffMode,
6060
6085
  ignorePatterns
6061
- } = command34;
6086
+ } = command31;
6062
6087
  this.logger.debug(
6063
6088
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
6064
6089
  );
@@ -6374,8 +6399,8 @@ var LintFilesAgainstRuleUseCase = class {
6374
6399
  return null;
6375
6400
  }
6376
6401
  }
6377
- async executeProgramsForFile(command34) {
6378
- const result = await this.services.linterExecutionUseCase.execute(command34);
6402
+ async executeProgramsForFile(command31) {
6403
+ const result = await this.services.linterExecutionUseCase.execute(command31);
6379
6404
  return result.violations;
6380
6405
  }
6381
6406
  extractExtensionFromFile(filePath) {
@@ -6398,8 +6423,8 @@ var LintFilesFromConfigUseCase = class {
6398
6423
  this.logger = logger2;
6399
6424
  this.detectionProgramsCache = /* @__PURE__ */ new Map();
6400
6425
  }
6401
- async execute(command34) {
6402
- const { path: userPath, diffMode, ignorePatterns } = command34;
6426
+ async execute(command31) {
6427
+ const { path: userPath, diffMode, ignorePatterns } = command31;
6403
6428
  this.logger.debug(
6404
6429
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
6405
6430
  );
@@ -6659,8 +6684,8 @@ var LintFilesFromConfigUseCase = class {
6659
6684
  return null;
6660
6685
  }
6661
6686
  }
6662
- async executeProgramsForFile(command34) {
6663
- const result = await this.services.linterExecutionUseCase.execute(command34);
6687
+ async executeProgramsForFile(command31) {
6688
+ const result = await this.services.linterExecutionUseCase.execute(command31);
6664
6689
  return result.violations;
6665
6690
  }
6666
6691
  extractExtensionFromFile(filePath) {
@@ -6676,7 +6701,7 @@ var LintFilesFromConfigUseCase = class {
6676
6701
  var NotLoggedInError = class extends Error {
6677
6702
  constructor() {
6678
6703
  super(
6679
- "You're not logged in to Packmind. Please either use the login command or set the PACKMIND_API_KEY_V3 environment variable (from the Settings menu in Packmind)."
6704
+ "You're not logged in to Packmind. Please either use the login command or set the PACKMIND_API_KEY environment variable (from the Settings menu in Packmind)."
6680
6705
  );
6681
6706
  this.name = "NotLoggedInError";
6682
6707
  }
@@ -6836,13 +6861,13 @@ var PackmindHttpClient = class {
6836
6861
  var ChangeProposalGateway = class {
6837
6862
  constructor(httpClient) {
6838
6863
  this.httpClient = httpClient;
6839
- this.batchCreate = async (command34) => {
6864
+ this.batchCreate = async (command31) => {
6840
6865
  const { organizationId } = this.httpClient.getAuthContext();
6841
6866
  return this.httpClient.request(
6842
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/change-proposals/batch`,
6867
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/change-proposals/batch`,
6843
6868
  {
6844
6869
  method: "POST",
6845
- body: { proposals: command34.proposals },
6870
+ body: { proposals: command31.proposals },
6846
6871
  onError: (response) => {
6847
6872
  if (response.status === 404) {
6848
6873
  throw new CommunityEditionError("change proposals");
@@ -6851,29 +6876,29 @@ var ChangeProposalGateway = class {
6851
6876
  }
6852
6877
  );
6853
6878
  };
6854
- this.batchApply = async (command34) => {
6879
+ this.batchApply = async (command31) => {
6855
6880
  const { organizationId } = this.httpClient.getAuthContext();
6856
6881
  return this.httpClient.request(
6857
6882
  `/api/v0/organizations/${organizationId}/playbook/apply`,
6858
6883
  {
6859
6884
  method: "POST",
6860
6885
  body: {
6861
- proposals: command34.proposals,
6862
- message: command34.message,
6863
- ...command34.directUpdate !== void 0 && {
6864
- directUpdate: command34.directUpdate
6886
+ proposals: command31.proposals,
6887
+ message: command31.message,
6888
+ ...command31.directUpdate !== void 0 && {
6889
+ directUpdate: command31.directUpdate
6865
6890
  }
6866
6891
  }
6867
6892
  }
6868
6893
  );
6869
6894
  };
6870
- this.check = async (command34) => {
6895
+ this.check = async (command31) => {
6871
6896
  const { organizationId } = this.httpClient.getAuthContext();
6872
6897
  return this.httpClient.request(
6873
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/change-proposals/check`,
6898
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/change-proposals/check`,
6874
6899
  {
6875
6900
  method: "POST",
6876
- body: { proposals: command34.proposals },
6901
+ body: { proposals: command31.proposals },
6877
6902
  onError: (response) => {
6878
6903
  if (response.status === 404) {
6879
6904
  throw new CommunityEditionError("change proposals");
@@ -6889,13 +6914,13 @@ var ChangeProposalGateway = class {
6889
6914
  var LinterGateway = class {
6890
6915
  constructor(httpClient) {
6891
6916
  this.httpClient = httpClient;
6892
- this.getDraftDetectionProgramsForRule = async (command34) => {
6917
+ this.getDraftDetectionProgramsForRule = async (command31) => {
6893
6918
  const payload = {
6894
- standardSlug: command34.standardSlug,
6895
- ruleId: command34.ruleId
6919
+ standardSlug: command31.standardSlug,
6920
+ ruleId: command31.ruleId
6896
6921
  };
6897
- if (command34.language) {
6898
- payload.language = command34.language;
6922
+ if (command31.language) {
6923
+ payload.language = command31.language;
6899
6924
  }
6900
6925
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
6901
6926
  method: "POST",
@@ -6907,13 +6932,13 @@ var LinterGateway = class {
6907
6932
  }
6908
6933
  });
6909
6934
  };
6910
- this.getActiveDetectionProgramsForRule = async (command34) => {
6935
+ this.getActiveDetectionProgramsForRule = async (command31) => {
6911
6936
  const payload = {
6912
- standardSlug: command34.standardSlug,
6913
- ruleId: command34.ruleId
6937
+ standardSlug: command31.standardSlug,
6938
+ ruleId: command31.ruleId
6914
6939
  };
6915
- if (command34.language) {
6916
- payload.language = command34.language;
6940
+ if (command31.language) {
6941
+ payload.language = command31.language;
6917
6942
  }
6918
6943
  return this.httpClient.request("/api/v0/list-active-detection-program", {
6919
6944
  method: "POST",
@@ -6925,13 +6950,13 @@ var LinterGateway = class {
6925
6950
  }
6926
6951
  });
6927
6952
  };
6928
- this.getDetectionProgramsForPackages = async (command34) => {
6953
+ this.getDetectionProgramsForPackages = async (command31) => {
6929
6954
  const response = await this.httpClient.request(
6930
6955
  "/api/v0/detection-programs-for-packages",
6931
6956
  {
6932
6957
  method: "POST",
6933
6958
  body: {
6934
- packagesSlugs: command34.packagesSlugs
6959
+ packagesSlugs: command31.packagesSlugs
6935
6960
  },
6936
6961
  onError: (response2) => {
6937
6962
  if (response2.status === 404) {
@@ -6942,10 +6967,10 @@ var LinterGateway = class {
6942
6967
  );
6943
6968
  return handleScopeInTargetsResponse(response);
6944
6969
  };
6945
- this.trackLinterExecution = async (command34) => {
6970
+ this.trackLinterExecution = async (command31) => {
6946
6971
  return this.httpClient.request(`/api/v0/track-execution`, {
6947
6972
  method: "POST",
6948
- body: command34
6973
+ body: command31
6949
6974
  });
6950
6975
  };
6951
6976
  }
@@ -6999,27 +7024,27 @@ var SpacesGateway = class {
6999
7024
  var SkillsGateway = class {
7000
7025
  constructor(httpClient) {
7001
7026
  this.httpClient = httpClient;
7002
- this.upload = async (command34) => {
7027
+ this.upload = async (command31) => {
7003
7028
  const { organizationId } = this.httpClient.getAuthContext();
7004
7029
  return this.httpClient.request(
7005
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/skills/upload`,
7030
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/skills/upload`,
7006
7031
  {
7007
7032
  method: "POST",
7008
- body: command34
7033
+ body: command31
7009
7034
  }
7010
7035
  );
7011
7036
  };
7012
- this.getDefaults = async (command34) => {
7037
+ this.getDefaults = async (command31) => {
7013
7038
  const { organizationId } = this.httpClient.getAuthContext();
7014
7039
  const queryParams = new URLSearchParams();
7015
- if (command34.includeBeta) {
7040
+ if (command31.includeBeta) {
7016
7041
  queryParams.set("includeBeta", "true");
7017
- } else if (command34.cliVersion) {
7018
- queryParams.set("cliVersion", command34.cliVersion);
7042
+ } else if (command31.cliVersion) {
7043
+ queryParams.set("cliVersion", command31.cliVersion);
7019
7044
  }
7020
- if (command34.agents !== void 0) {
7045
+ if (command31.agents !== void 0) {
7021
7046
  queryParams.append("agentsConfigOverride", "true");
7022
- command34.agents.forEach((agent) => {
7047
+ command31.agents.forEach((agent) => {
7023
7048
  queryParams.append("agent", agent);
7024
7049
  });
7025
7050
  }
@@ -7028,10 +7053,10 @@ var SkillsGateway = class {
7028
7053
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
7029
7054
  );
7030
7055
  };
7031
- this.list = async (command34) => {
7056
+ this.list = async (command31) => {
7032
7057
  const { organizationId } = this.httpClient.getAuthContext();
7033
7058
  return this.httpClient.request(
7034
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/skills`
7059
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/skills`
7035
7060
  );
7036
7061
  };
7037
7062
  }
@@ -7041,22 +7066,24 @@ var SkillsGateway = class {
7041
7066
  var CommandsGateway = class {
7042
7067
  constructor(httpClient) {
7043
7068
  this.httpClient = httpClient;
7044
- this.create = async (command34) => {
7069
+ this.create = async (command31) => {
7045
7070
  const { organizationId } = this.httpClient.getAuthContext();
7046
7071
  return this.httpClient.request(
7047
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/recipes`,
7048
- { method: "POST", body: command34 }
7072
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/commands`,
7073
+ { method: "POST", body: command31 }
7049
7074
  );
7050
7075
  };
7051
- this.list = async (command34) => {
7076
+ this.list = async (command31) => {
7052
7077
  const { organizationId } = this.httpClient.getAuthContext();
7053
- const listRecipesResponse = await this.httpClient.request(
7054
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/recipes`
7078
+ const listCommandsResponse = await this.httpClient.request(
7079
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/commands`
7055
7080
  );
7056
- if (listRecipesResponse instanceof Array) {
7057
- return { recipes: listRecipesResponse };
7081
+ if (listCommandsResponse instanceof Array) {
7082
+ return { recipes: listCommandsResponse };
7058
7083
  }
7059
- return listRecipesResponse;
7084
+ return {
7085
+ recipes: listCommandsResponse.commands ?? listCommandsResponse.recipes ?? []
7086
+ };
7060
7087
  };
7061
7088
  }
7062
7089
  };
@@ -7092,10 +7119,10 @@ var StandardsGateway = class {
7092
7119
  }
7093
7120
  );
7094
7121
  };
7095
- this.list = async (command34) => {
7122
+ this.list = async (command31) => {
7096
7123
  const { organizationId } = this.httpClient.getAuthContext();
7097
7124
  return this.httpClient.request(
7098
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/standards`
7125
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/standards`
7099
7126
  );
7100
7127
  };
7101
7128
  }
@@ -7106,10 +7133,10 @@ var PackagesGateway = class {
7106
7133
  constructor(apiKey, httpClient) {
7107
7134
  this.apiKey = apiKey;
7108
7135
  this.httpClient = httpClient;
7109
- this.list = async (command34) => {
7136
+ this.list = async (command31) => {
7110
7137
  const { organizationId } = this.httpClient.getAuthContext();
7111
7138
  return this.httpClient.request(
7112
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/packages`
7139
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/packages`
7113
7140
  );
7114
7141
  };
7115
7142
  this.getSummary = async ({
@@ -7121,24 +7148,25 @@ var PackagesGateway = class {
7121
7148
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug6)}`
7122
7149
  );
7123
7150
  };
7124
- this.create = async (command34) => {
7151
+ this.create = async (command31) => {
7125
7152
  const { organizationId } = this.httpClient.getAuthContext();
7153
+ const { recipeIds, ...rest } = command31;
7126
7154
  return this.httpClient.request(
7127
- `/api/v0/organizations/${organizationId}/spaces/${command34.spaceId}/packages`,
7155
+ `/api/v0/organizations/${organizationId}/spaces/${command31.spaceId}/packages`,
7128
7156
  {
7129
7157
  method: "POST",
7130
- body: command34
7158
+ body: { ...rest, commandIds: recipeIds }
7131
7159
  }
7132
7160
  );
7133
7161
  };
7134
- this.addArtefacts = async (command34) => {
7162
+ this.addArtefacts = async (command31) => {
7135
7163
  const { organizationId } = this.httpClient.getAuthContext();
7136
- const { packageId, spaceId } = command34;
7164
+ const { packageId, spaceId, recipeIds, ...rest } = command31;
7137
7165
  return this.httpClient.request(
7138
7166
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
7139
7167
  {
7140
7168
  method: "POST",
7141
- body: command34
7169
+ body: { ...rest, packageId, spaceId, commandIds: recipeIds }
7142
7170
  }
7143
7171
  );
7144
7172
  };
@@ -7149,31 +7177,31 @@ var PackagesGateway = class {
7149
7177
  var DeploymentGateway = class {
7150
7178
  constructor(httpClient) {
7151
7179
  this.httpClient = httpClient;
7152
- this.pull = async (command34) => {
7180
+ this.pull = async (command31) => {
7153
7181
  const { organizationId } = this.httpClient.getAuthContext();
7154
7182
  const queryParams = new URLSearchParams();
7155
- if (command34.packagesSlugs && command34.packagesSlugs.length > 0) {
7156
- command34.packagesSlugs.forEach((slug6) => {
7183
+ if (command31.packagesSlugs && command31.packagesSlugs.length > 0) {
7184
+ command31.packagesSlugs.forEach((slug6) => {
7157
7185
  queryParams.append("packageSlug", slug6);
7158
7186
  });
7159
7187
  }
7160
- if (command34.previousPackagesSlugs && command34.previousPackagesSlugs.length > 0) {
7161
- command34.previousPackagesSlugs.forEach((slug6) => {
7188
+ if (command31.previousPackagesSlugs && command31.previousPackagesSlugs.length > 0) {
7189
+ command31.previousPackagesSlugs.forEach((slug6) => {
7162
7190
  queryParams.append("previousPackageSlug", slug6);
7163
7191
  });
7164
7192
  }
7165
- if (command34.gitRemoteUrl) {
7166
- queryParams.append("gitRemoteUrl", command34.gitRemoteUrl);
7193
+ if (command31.gitRemoteUrl) {
7194
+ queryParams.append("gitRemoteUrl", command31.gitRemoteUrl);
7167
7195
  }
7168
- if (command34.gitBranch) {
7169
- queryParams.append("gitBranch", command34.gitBranch);
7196
+ if (command31.gitBranch) {
7197
+ queryParams.append("gitBranch", command31.gitBranch);
7170
7198
  }
7171
- if (command34.relativePath) {
7172
- queryParams.append("relativePath", command34.relativePath);
7199
+ if (command31.relativePath) {
7200
+ queryParams.append("relativePath", command31.relativePath);
7173
7201
  }
7174
- if (command34.agents !== void 0) {
7202
+ if (command31.agents !== void 0) {
7175
7203
  queryParams.append("agentsConfigOverride", "true");
7176
- command34.agents.forEach((agent) => {
7204
+ command31.agents.forEach((agent) => {
7177
7205
  queryParams.append("agent", agent);
7178
7206
  });
7179
7207
  }
@@ -7181,101 +7209,101 @@ var DeploymentGateway = class {
7181
7209
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
7182
7210
  );
7183
7211
  };
7184
- this.install = async (command34) => {
7212
+ this.install = async (command31) => {
7185
7213
  const { organizationId } = this.httpClient.getAuthContext();
7186
7214
  return this.httpClient.request(
7187
7215
  `/api/v0/organizations/${organizationId}/install`,
7188
7216
  {
7189
7217
  method: "POST",
7190
7218
  body: {
7191
- packagesSlugs: command34.packagesSlugs,
7192
- packmindLockFile: command34.packmindLockFile,
7193
- ...command34.relativePath && { relativePath: command34.relativePath },
7194
- ...command34.agents !== void 0 && { agents: command34.agents }
7219
+ packagesSlugs: command31.packagesSlugs,
7220
+ packmindLockFile: command31.packmindLockFile,
7221
+ ...command31.relativePath && { relativePath: command31.relativePath },
7222
+ ...command31.agents !== void 0 && { agents: command31.agents }
7195
7223
  }
7196
7224
  }
7197
7225
  );
7198
7226
  };
7199
- this.getDeployed = async (command34) => {
7227
+ this.getDeployed = async (command31) => {
7200
7228
  const { organizationId } = this.httpClient.getAuthContext();
7201
7229
  return this.httpClient.request(
7202
7230
  `/api/v0/organizations/${organizationId}/deployed-content`,
7203
7231
  {
7204
7232
  method: "POST",
7205
7233
  body: {
7206
- packagesSlugs: command34.packagesSlugs,
7207
- gitRemoteUrl: command34.gitRemoteUrl,
7208
- gitBranch: command34.gitBranch,
7209
- relativePath: command34.relativePath,
7210
- ...command34.agents !== void 0 && { agents: command34.agents }
7234
+ packagesSlugs: command31.packagesSlugs,
7235
+ gitRemoteUrl: command31.gitRemoteUrl,
7236
+ gitBranch: command31.gitBranch,
7237
+ relativePath: command31.relativePath,
7238
+ ...command31.agents !== void 0 && { agents: command31.agents }
7211
7239
  }
7212
7240
  }
7213
7241
  );
7214
7242
  };
7215
- this.getContentByVersions = async (command34) => {
7243
+ this.getContentByVersions = async (command31) => {
7216
7244
  const { organizationId } = this.httpClient.getAuthContext();
7217
7245
  return this.httpClient.request(
7218
7246
  `/api/v0/organizations/${organizationId}/content-by-versions`,
7219
7247
  {
7220
7248
  method: "POST",
7221
7249
  body: {
7222
- artifacts: command34.artifacts,
7223
- ...command34.agents !== void 0 && { agents: command34.agents }
7250
+ artifacts: command31.artifacts,
7251
+ ...command31.agents !== void 0 && { agents: command31.agents }
7224
7252
  }
7225
7253
  }
7226
7254
  );
7227
7255
  };
7228
- this.notifyDistribution = async (command34) => {
7256
+ this.notifyDistribution = async (command31) => {
7229
7257
  const { organizationId } = this.httpClient.getAuthContext();
7230
7258
  return this.httpClient.request(
7231
7259
  `/api/v0/organizations/${organizationId}/deployments`,
7232
7260
  {
7233
7261
  method: "POST",
7234
- body: command34
7262
+ body: command31
7235
7263
  }
7236
7264
  );
7237
7265
  };
7238
- this.notifyArtefactsDistribution = async (command34) => {
7266
+ this.notifyArtefactsDistribution = async (command31) => {
7239
7267
  const { organizationId } = this.httpClient.getAuthContext();
7240
7268
  return this.httpClient.request(
7241
7269
  `/api/v0/organizations/${organizationId}/deployments/notify-artifacts-distribution`,
7242
7270
  {
7243
7271
  method: "POST",
7244
7272
  body: {
7245
- gitRemoteUrl: command34.gitRemoteUrl,
7246
- gitBranch: command34.gitBranch,
7247
- relativePath: command34.relativePath,
7248
- packmindLockFile: command34.packmindLockFile
7273
+ gitRemoteUrl: command31.gitRemoteUrl,
7274
+ gitBranch: command31.gitBranch,
7275
+ relativePath: command31.relativePath,
7276
+ packmindLockFile: command31.packmindLockFile
7249
7277
  }
7250
7278
  }
7251
7279
  );
7252
7280
  };
7253
- this.renderPlugin = async (command34) => {
7281
+ this.renderPlugin = async (command31) => {
7254
7282
  const { organizationId } = this.httpClient.getAuthContext();
7255
7283
  return this.httpClient.request(
7256
7284
  `/api/v0/organizations/${organizationId}/plugins/render`,
7257
7285
  {
7258
7286
  method: "POST",
7259
7287
  body: {
7260
- packageSlug: command34.packageSlug,
7261
- mode: command34.mode,
7262
- pluginRoot: command34.pluginRoot,
7263
- pluginName: command34.pluginName,
7264
- gitRemoteUrl: command34.gitRemoteUrl,
7265
- gitBranch: command34.gitBranch
7288
+ packageSlug: command31.packageSlug,
7289
+ mode: command31.mode,
7290
+ pluginRoot: command31.pluginRoot,
7291
+ pluginName: command31.pluginName,
7292
+ gitRemoteUrl: command31.gitRemoteUrl,
7293
+ gitBranch: command31.gitBranch
7266
7294
  }
7267
7295
  }
7268
7296
  );
7269
7297
  };
7270
- this.trackPluginDeleted = async (command34) => {
7298
+ this.trackPluginDeleted = async (command31) => {
7271
7299
  const { organizationId } = this.httpClient.getAuthContext();
7272
7300
  return this.httpClient.request(
7273
7301
  `/api/v0/organizations/${organizationId}/plugins/track-deleted`,
7274
7302
  {
7275
7303
  method: "POST",
7276
7304
  body: {
7277
- packageSlug: command34.packageSlug,
7278
- gitRemoteUrl: command34.gitRemoteUrl
7305
+ packageSlug: command31.packageSlug,
7306
+ gitRemoteUrl: command31.gitRemoteUrl
7279
7307
  }
7280
7308
  }
7281
7309
  );
@@ -7287,13 +7315,13 @@ var DeploymentGateway = class {
7287
7315
  );
7288
7316
  };
7289
7317
  }
7290
- async updateRenderModeConfiguration(command34) {
7318
+ async updateRenderModeConfiguration(command31) {
7291
7319
  const { organizationId } = this.httpClient.getAuthContext();
7292
7320
  await this.httpClient.request(
7293
7321
  `/api/v0/organizations/${organizationId}/deployments/renderModeConfiguration`,
7294
7322
  {
7295
7323
  method: "POST",
7296
- body: { activeRenderModes: command34.activeRenderModes }
7324
+ body: { activeRenderModes: command31.activeRenderModes }
7297
7325
  }
7298
7326
  );
7299
7327
  }
@@ -7301,7 +7329,7 @@ var DeploymentGateway = class {
7301
7329
  const { organizationId } = this.httpClient.getAuthContext();
7302
7330
  const typeToPath = {
7303
7331
  standard: "standards",
7304
- command: "recipes",
7332
+ command: "commands",
7305
7333
  skill: "skills"
7306
7334
  };
7307
7335
  const pathSegment = typeToPath[type];
@@ -7336,6 +7364,37 @@ var OrganizationGateway = class {
7336
7364
  }
7337
7365
  };
7338
7366
 
7367
+ // apps/cli/src/infra/repositories/RepositoryTrackingGateway.ts
7368
+ var RepositoryTrackingGateway = class {
7369
+ constructor(httpClient) {
7370
+ this.httpClient = httpClient;
7371
+ this.getTrackedRepository = async ({
7372
+ owner,
7373
+ repo
7374
+ }) => {
7375
+ const { organizationId } = this.httpClient.getAuthContext();
7376
+ const query = new URLSearchParams({ owner, repo }).toString();
7377
+ return this.httpClient.request(
7378
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository?${query}`
7379
+ );
7380
+ };
7381
+ this.setTrackedRepository = async (command31) => {
7382
+ const { organizationId } = this.httpClient.getAuthContext();
7383
+ return this.httpClient.request(
7384
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7385
+ { method: "POST", body: command31 }
7386
+ );
7387
+ };
7388
+ this.updateTrackedBranch = async (command31) => {
7389
+ const { organizationId } = this.httpClient.getAuthContext();
7390
+ return this.httpClient.request(
7391
+ `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7392
+ { method: "PUT", body: command31 }
7393
+ );
7394
+ };
7395
+ }
7396
+ };
7397
+
7339
7398
  // apps/cli/src/infra/repositories/PackmindGateway.ts
7340
7399
  var PackmindGateway = class {
7341
7400
  constructor(apiKey) {
@@ -7350,6 +7409,7 @@ var PackmindGateway = class {
7350
7409
  this.packages = new PackagesGateway(apiKey, this.httpClient);
7351
7410
  this.deployment = new DeploymentGateway(this.httpClient);
7352
7411
  this.organization = new OrganizationGateway(this.httpClient);
7412
+ this.repositoryTracking = new RepositoryTrackingGateway(this.httpClient);
7353
7413
  }
7354
7414
  };
7355
7415
 
@@ -9093,8 +9153,8 @@ var ExecuteLinterProgramsUseCase = class {
9093
9153
  this.linterAstAdapter = linterAstAdapter;
9094
9154
  this.logger = logger2;
9095
9155
  }
9096
- async execute(command34) {
9097
- const { filePath, fileContent, language, programs } = command34;
9156
+ async execute(command31) {
9157
+ const { filePath, fileContent, language, programs } = command31;
9098
9158
  if (programs.length === 0) {
9099
9159
  return {
9100
9160
  file: filePath,
@@ -9690,6 +9750,21 @@ var Cache = class _Cache {
9690
9750
  }
9691
9751
  };
9692
9752
 
9753
+ // packages/feature-flags/src/registry.ts
9754
+ var ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY = "change-proposals-in-webapp";
9755
+ var ORGA_SPACE_MANAGEMENT_FEATURE_KEY = "orga-space-management";
9756
+ var GOVERNANCE_FEATURE_KEY = "governance";
9757
+ var CLI_REPO_TRACKING_FEATURE_KEY = "cli-repo-tracking";
9758
+ var DEFAULT_FEATURE_DOMAIN_MAP = {
9759
+ [ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY]: [
9760
+ "@packmind.com",
9761
+ "@promyze.com"
9762
+ ],
9763
+ [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"],
9764
+ [GOVERNANCE_FEATURE_KEY]: ["joan.racenet@packmind.com"],
9765
+ [CLI_REPO_TRACKING_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9766
+ };
9767
+
9693
9768
  // packages/node-utils/src/database/schemas.ts
9694
9769
  var uuidSchema = {
9695
9770
  id: {
@@ -9744,6 +9819,11 @@ var import_common2 = require("@nestjs/common");
9744
9819
  // packages/node-utils/src/sse/RedisSSEClient.ts
9745
9820
  var import_ioredis2 = __toESM(require("ioredis"));
9746
9821
 
9822
+ // packages/node-utils/src/text/normalizeLineEndings.ts
9823
+ function normalizeLineEndings(content) {
9824
+ return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
9825
+ }
9826
+
9747
9827
  // packages/node-utils/src/text/sectionMerge.ts
9748
9828
  function mergeSectionsIntoFileContent(existingContent, sections) {
9749
9829
  let result = existingContent;
@@ -9913,8 +9993,8 @@ var InstallPackagesUseCase = class {
9913
9993
  constructor(packmindGateway) {
9914
9994
  this.packmindGateway = packmindGateway;
9915
9995
  }
9916
- async execute(command34) {
9917
- const baseDirectory = command34.baseDirectory || process.cwd();
9996
+ async execute(command31) {
9997
+ const baseDirectory = command31.baseDirectory || process.cwd();
9918
9998
  const result = {
9919
9999
  filesCreated: 0,
9920
10000
  filesUpdated: 0,
@@ -9926,12 +10006,12 @@ var InstallPackagesUseCase = class {
9926
10006
  skillDirectoriesDeleted: 0
9927
10007
  };
9928
10008
  const response = await this.packmindGateway.deployment.pull({
9929
- packagesSlugs: command34.packagesSlugs,
9930
- previousPackagesSlugs: command34.previousPackagesSlugs,
9931
- gitRemoteUrl: command34.gitRemoteUrl,
9932
- gitBranch: command34.gitBranch,
9933
- relativePath: command34.relativePath,
9934
- agents: command34.agents
10009
+ packagesSlugs: command31.packagesSlugs,
10010
+ previousPackagesSlugs: command31.previousPackagesSlugs,
10011
+ gitRemoteUrl: command31.gitRemoteUrl,
10012
+ gitBranch: command31.gitBranch,
10013
+ relativePath: command31.relativePath,
10014
+ agents: command31.agents
9935
10015
  });
9936
10016
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
9937
10017
  (file) => file.path !== "packmind.json"
@@ -10306,8 +10386,8 @@ var InstallUseCase = class {
10306
10386
  this.configFileRepository = configFileRepository;
10307
10387
  this.spaceService = spaceService;
10308
10388
  }
10309
- async execute(command34) {
10310
- const baseDirectory = command34.baseDirectory || process.cwd();
10389
+ async execute(command31) {
10390
+ const baseDirectory = command31.baseDirectory || process.cwd();
10311
10391
  const result = {
10312
10392
  filesCreated: 0,
10313
10393
  filesUpdated: 0,
@@ -10337,7 +10417,7 @@ var InstallUseCase = class {
10337
10417
  },
10338
10418
  resolvedAgents: []
10339
10419
  };
10340
- const hasExplicitPackages = command34.packages && command34.packages.length > 0;
10420
+ const hasExplicitPackages = command31.packages && command31.packages.length > 0;
10341
10421
  const configExistedBefore = await this.configFileRepository.configExists(baseDirectory);
10342
10422
  const lockFile = await this.lockFileRepository.read(baseDirectory);
10343
10423
  const config = await this.configFileRepository.readConfig(baseDirectory);
@@ -10357,14 +10437,13 @@ var InstallUseCase = class {
10357
10437
  lockfileVersion: 1,
10358
10438
  packageSlugs: [],
10359
10439
  agents: [],
10360
- artifacts: {},
10361
- ...command34.skipInstalledAt ? {} : { installedAt: (/* @__PURE__ */ new Date()).toISOString() }
10440
+ artifacts: {}
10362
10441
  };
10363
- effectiveLockFile.cliVersion = command34.cliVersion;
10442
+ effectiveLockFile.cliVersion = command31.cliVersion;
10364
10443
  let packagesSlugs;
10365
10444
  let normalizedPackages = [];
10366
10445
  if (hasExplicitPackages) {
10367
- const explicitPackageSlugs = (command34.packages ?? []).map(
10446
+ const explicitPackageSlugs = (command31.packages ?? []).map(
10368
10447
  displayableParsedPackageSlug
10369
10448
  );
10370
10449
  normalizedPackages = await this.normalizePackageSlugs(explicitPackageSlugs);
@@ -10394,8 +10473,8 @@ var InstallUseCase = class {
10394
10473
  }
10395
10474
  return result;
10396
10475
  }
10397
- const installAgents = this.resolveInstallAgents(command34, config);
10398
- const stripPathPrefix = command34.homeAgent ? getAgentHomeDirPrefix(command34.homeAgent) ?? void 0 : void 0;
10476
+ const installAgents = this.resolveInstallAgents(command31, config);
10477
+ const stripPathPrefix = command31.homeAgent ? getAgentHomeDirPrefix(command31.homeAgent) ?? void 0 : void 0;
10399
10478
  const response = await this.packmindGateway.deployment.install({
10400
10479
  packagesSlugs,
10401
10480
  packmindLockFile: effectiveLockFile,
@@ -10535,10 +10614,7 @@ var InstallUseCase = class {
10535
10614
  } catch {
10536
10615
  }
10537
10616
  }
10538
- if (command34.skipInstalledAt) {
10539
- delete lockFileToPersist.installedAt;
10540
- }
10541
- lockFileToPersist.cliVersion = command34.cliVersion;
10617
+ lockFileToPersist.cliVersion = command31.cliVersion;
10542
10618
  if (stripPathPrefix) {
10543
10619
  lockFileToPersist = this.stripLockFileArtifactPaths(
10544
10620
  lockFileToPersist,
@@ -10567,9 +10643,9 @@ var InstallUseCase = class {
10567
10643
  async normalizePackageSlugs(slugs) {
10568
10644
  return normalizePackageSlugs(slugs, this.spaceService);
10569
10645
  }
10570
- resolveInstallAgents(command34, config) {
10571
- if (command34.homeAgent) {
10572
- return [command34.homeAgent];
10646
+ resolveInstallAgents(command31, config) {
10647
+ if (command31.homeAgent) {
10648
+ return [command31.homeAgent];
10573
10649
  }
10574
10650
  return config?.agents;
10575
10651
  }
@@ -10883,8 +10959,8 @@ var UninstallUseCase = class {
10883
10959
  this.spaceService = spaceService;
10884
10960
  this.installUseCase = installUseCase;
10885
10961
  }
10886
- async execute(command34) {
10887
- const baseDirectory = command34.baseDirectory || process.cwd();
10962
+ async execute(command31) {
10963
+ const baseDirectory = command31.baseDirectory || process.cwd();
10888
10964
  const config = await this.configFileRepository.readConfig(baseDirectory);
10889
10965
  if (!config) {
10890
10966
  const configFileExists = await this.configFileRepository.configExists(baseDirectory);
@@ -10898,7 +10974,7 @@ var UninstallUseCase = class {
10898
10974
  );
10899
10975
  }
10900
10976
  const normalized = await normalizePackageSlugs(
10901
- command34.packages,
10977
+ command31.packages,
10902
10978
  this.spaceService
10903
10979
  );
10904
10980
  const notInstalled = normalized.filter((pkg) => !(pkg in config.packages));
@@ -10921,7 +10997,7 @@ ${pkgList}`
10921
10997
  try {
10922
10998
  return await this.installUseCase.execute({
10923
10999
  baseDirectory,
10924
- cliVersion: command34.cliVersion
11000
+ cliVersion: command31.cliVersion
10925
11001
  });
10926
11002
  } catch (error) {
10927
11003
  await this.configFileRepository.updateConfig(
@@ -10963,8 +11039,8 @@ var InstallDefaultSkillsUseCase = class {
10963
11039
  constructor(repositories) {
10964
11040
  this.repositories = repositories;
10965
11041
  }
10966
- async execute(command34) {
10967
- const baseDirectory = command34.baseDirectory || process.cwd();
11042
+ async execute(command31) {
11043
+ const baseDirectory = command31.baseDirectory || process.cwd();
10968
11044
  await this.bootstrapEmptyDirectory(baseDirectory);
10969
11045
  const result = {
10970
11046
  filesCreated: 0,
@@ -10974,24 +11050,24 @@ var InstallDefaultSkillsUseCase = class {
10974
11050
  skippedIncompatibleSkillNames: [],
10975
11051
  incompatibleInstalledSkills: []
10976
11052
  };
10977
- let agents = command34.agents;
11053
+ let agents = command31.agents;
10978
11054
  if (!agents || agents.length === 0) {
10979
11055
  const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
10980
11056
  agents = config?.agents;
10981
11057
  }
10982
11058
  const response = await this.repositories.packmindGateway.skills.getDefaults(
10983
11059
  {
10984
- cliVersion: command34.cliVersion,
10985
- includeBeta: command34.includeBeta,
11060
+ cliVersion: command31.cliVersion,
11061
+ includeBeta: command31.includeBeta,
10986
11062
  agents
10987
11063
  }
10988
11064
  );
10989
11065
  result.skippedSkillsCount = response.skippedSkillsCount;
10990
11066
  const incompatibleInstalledMap = /* @__PURE__ */ new Map();
10991
11067
  const incompatibleSkillDirs = /* @__PURE__ */ new Map();
10992
- if (command34.cliVersion) {
11068
+ if (command31.cliVersion) {
10993
11069
  for (const file of response.fileUpdates.createOrUpdate) {
10994
- if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command34.cliVersion)) {
11070
+ if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command31.cliVersion)) {
10995
11071
  const dir = path9.dirname(file.path);
10996
11072
  const skillName = this.getSkillName(file.content) ?? path9.basename(dir);
10997
11073
  incompatibleSkillDirs.set(dir, skillName);
@@ -11002,9 +11078,9 @@ var InstallDefaultSkillsUseCase = class {
11002
11078
  for (const file of response.fileUpdates.createOrUpdate) {
11003
11079
  try {
11004
11080
  if (!file.content) continue;
11005
- const isIncompatible = command34.cliVersion && (this.isVersionConstraintViolated(
11081
+ const isIncompatible = command31.cliVersion && (this.isVersionConstraintViolated(
11006
11082
  file.content,
11007
- command34.cliVersion
11083
+ command31.cliVersion
11008
11084
  ) || this.isUnderIncompatibleSkillDir(
11009
11085
  file.path,
11010
11086
  incompatibleSkillDirs
@@ -11047,7 +11123,7 @@ var InstallDefaultSkillsUseCase = class {
11047
11123
  await this.mergeLockFileSlice(
11048
11124
  baseDirectory,
11049
11125
  response.lockFileSlice ?? {},
11050
- command34.cliVersion
11126
+ command31.cliVersion
11051
11127
  );
11052
11128
  return result;
11053
11129
  }
@@ -11201,8 +11277,8 @@ var EnsureCliVersionUseCase = class {
11201
11277
  this.lockFileRepository = lockFileRepository;
11202
11278
  this.installDefaultSkillsUseCase = installDefaultSkillsUseCase;
11203
11279
  }
11204
- async execute(command34) {
11205
- const { baseDirectory, currentCliVersion, includeBeta } = command34;
11280
+ async execute(command31) {
11281
+ const { baseDirectory, currentCliVersion, includeBeta } = command31;
11206
11282
  const lockFile = await this.lockFileRepository.read(baseDirectory);
11207
11283
  if (!lockFile) {
11208
11284
  return { kind: "no-lockfile" };
@@ -11238,10 +11314,10 @@ var ListPackagesUseCase = class {
11238
11314
  this.packmindGateway = packmindGateway;
11239
11315
  this.spaceService = spaceService;
11240
11316
  }
11241
- async execute(command34) {
11242
- if (command34.spaceId) {
11317
+ async execute(command31) {
11318
+ if (command31.spaceId) {
11243
11319
  const response = await this.packmindGateway.packages.list({
11244
- spaceId: command34.spaceId
11320
+ spaceId: command31.spaceId
11245
11321
  });
11246
11322
  return response.packages;
11247
11323
  }
@@ -11260,8 +11336,8 @@ var GetPackageSummaryUseCase = class {
11260
11336
  constructor(gateway) {
11261
11337
  this.gateway = gateway;
11262
11338
  }
11263
- async execute(command34) {
11264
- return this.gateway.packages.getSummary(command34);
11339
+ async execute(command31) {
11340
+ return this.gateway.packages.getSummary(command31);
11265
11341
  }
11266
11342
  };
11267
11343
 
@@ -11291,10 +11367,7 @@ function decodeApiKey(apiKey) {
11291
11367
  }
11292
11368
 
11293
11369
  // apps/cli/src/infra/utils/credentials/EnvCredentialsProvider.ts
11294
- var ENV_VAR_NAMES = [
11295
- "PACKMIND_API_KEY",
11296
- "PACKMIND_API_KEY_V3"
11297
- ];
11370
+ var ENV_VAR_NAMES = ["PACKMIND_API_KEY"];
11298
11371
  var EnvCredentialsProvider = class {
11299
11372
  getSourceName() {
11300
11373
  const name = this.findActiveEnvVarName() ?? ENV_VAR_NAMES[0];
@@ -11556,8 +11629,8 @@ var LoginUseCase = class {
11556
11629
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
11557
11630
  };
11558
11631
  }
11559
- async execute(command34) {
11560
- const { host, code: providedCode } = command34;
11632
+ async execute(command31) {
11633
+ const { host, code: providedCode } = command31;
11561
11634
  let code;
11562
11635
  if (providedCode) {
11563
11636
  code = providedCode;
@@ -11939,10 +12012,10 @@ var CheckCliVersionUseCase = class {
11939
12012
  now: deps?.now ?? (() => /* @__PURE__ */ new Date())
11940
12013
  };
11941
12014
  }
11942
- async execute(command34) {
11943
- const cached = this.readFreshCache(command34.currentVersion);
12015
+ async execute(command31) {
12016
+ const cached = this.readFreshCache(command31.currentVersion);
11944
12017
  if (cached) {
11945
- return this.toResult(command34.currentVersion, cached.latestVersion);
12018
+ return this.toResult(command31.currentVersion, cached.latestVersion);
11946
12019
  }
11947
12020
  const fetchPromise = this.deps.fetchLatestVersion(this.deps.fetchFn);
11948
12021
  fetchPromise.catch(() => void 0);
@@ -11960,7 +12033,7 @@ var CheckCliVersionUseCase = class {
11960
12033
  latestVersion,
11961
12034
  checkedAt: this.deps.now()
11962
12035
  });
11963
- return this.toResult(command34.currentVersion, latestVersion);
12036
+ return this.toResult(command31.currentVersion, latestVersion);
11964
12037
  } catch {
11965
12038
  return null;
11966
12039
  }
@@ -12408,10 +12481,10 @@ var ListStandardsUseCase = class {
12408
12481
  this.packmindGateway = packmindGateway;
12409
12482
  this.spaceService = spaceService;
12410
12483
  }
12411
- async execute(command34) {
12412
- if (command34.spaceId) {
12484
+ async execute(command31) {
12485
+ if (command31.spaceId) {
12413
12486
  const response = await this.packmindGateway.standards.list({
12414
- spaceId: command34.spaceId
12487
+ spaceId: command31.spaceId
12415
12488
  });
12416
12489
  return response.standards;
12417
12490
  }
@@ -12431,10 +12504,10 @@ var ListCommandsUseCase = class {
12431
12504
  this.packmindGateway = packmindGateway;
12432
12505
  this.spaceService = spaceService;
12433
12506
  }
12434
- async execute(command34) {
12435
- if (command34.spaceId) {
12507
+ async execute(command31) {
12508
+ if (command31.spaceId) {
12436
12509
  const response = await this.packmindGateway.commands.list({
12437
- spaceId: command34.spaceId
12510
+ spaceId: command31.spaceId
12438
12511
  });
12439
12512
  return response.recipes;
12440
12513
  }
@@ -12454,10 +12527,10 @@ var ListSkillsUseCase = class {
12454
12527
  this.packmindGateway = packmindGateway;
12455
12528
  this.spaceService = spaceService;
12456
12529
  }
12457
- async execute(command34) {
12458
- if (command34.spaceId) {
12530
+ async execute(command31) {
12531
+ if (command31.spaceId) {
12459
12532
  const skills = await this.packmindGateway.skills.list({
12460
- spaceId: command34.spaceId
12533
+ spaceId: command31.spaceId
12461
12534
  });
12462
12535
  return skills.map((s) => ({
12463
12536
  id: s.id,
@@ -12490,11 +12563,6 @@ var import_promises2 = __toESM(require("fs/promises"));
12490
12563
  var import_path3 = __toESM(require("path"));
12491
12564
  var import_minimatch2 = require("minimatch");
12492
12565
 
12493
- // apps/cli/src/application/utils/normalizeLineEndings.ts
12494
- function normalizeLineEndings(content) {
12495
- return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
12496
- }
12497
-
12498
12566
  // apps/cli/src/infra/utils/binaryDetection.ts
12499
12567
  var path15 = __toESM(require("path"));
12500
12568
  var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
@@ -12634,8 +12702,8 @@ var UploadSkillUseCase = class {
12634
12702
  constructor(deps) {
12635
12703
  this.deps = deps;
12636
12704
  }
12637
- async execute(command34) {
12638
- const files = await readSkillDirectory(command34.skillPath);
12705
+ async execute(command31) {
12706
+ const files = await readSkillDirectory(command31.skillPath);
12639
12707
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
12640
12708
  throw new Error("SKILL.md not found in skill directory");
12641
12709
  }
@@ -12649,7 +12717,7 @@ var UploadSkillUseCase = class {
12649
12717
  if (totalSize > 10 * 1024 * 1024) {
12650
12718
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
12651
12719
  }
12652
- const space = await this.getSpace(command34.spaceSlug);
12720
+ const space = await this.getSpace(command31.spaceSlug);
12653
12721
  const payload = {
12654
12722
  files: files.map((f) => ({
12655
12723
  path: f.relativePath,
@@ -12661,7 +12729,7 @@ var UploadSkillUseCase = class {
12661
12729
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
12662
12730
  spaceId: createSpaceId(space.id),
12663
12731
  files: payload.files,
12664
- originSkill: command34.originSkill
12732
+ originSkill: command31.originSkill
12665
12733
  });
12666
12734
  return {
12667
12735
  skillId: uploadSkillResponse.skill.id,
@@ -13651,9 +13719,9 @@ var DiffArtefactsUseCase = class {
13651
13719
  new StandardDiffStrategy()
13652
13720
  ];
13653
13721
  }
13654
- async execute(command34) {
13655
- const baseDirectory = command34.baseDirectory || process.cwd();
13656
- const response = await this.fetchContent(command34, baseDirectory);
13722
+ async execute(command31) {
13723
+ const baseDirectory = command31.baseDirectory || process.cwd();
13724
+ const response = await this.fetchContent(command31, baseDirectory);
13657
13725
  const filteredFiles = response.fileUpdates.createOrUpdate.filter(
13658
13726
  (file) => file.path !== "packmind.json"
13659
13727
  );
@@ -13666,7 +13734,7 @@ var DiffArtefactsUseCase = class {
13666
13734
  );
13667
13735
  const prefixedSkillFolders = this.prefixSkillFolders(
13668
13736
  response.skillFolders,
13669
- command34.relativePath
13737
+ command31.relativePath
13670
13738
  );
13671
13739
  const diffs = [];
13672
13740
  for (const file of diffableFiles) {
@@ -13693,7 +13761,7 @@ var DiffArtefactsUseCase = class {
13693
13761
  targetId: response.targetId ? createTargetId(response.targetId) : void 0
13694
13762
  }));
13695
13763
  }
13696
- async fetchContent(command34, baseDirectory) {
13764
+ async fetchContent(command31, baseDirectory) {
13697
13765
  const lockFile = await this.lockFileRepository.read(baseDirectory);
13698
13766
  if (lockFile) {
13699
13767
  try {
@@ -13713,11 +13781,11 @@ var DiffArtefactsUseCase = class {
13713
13781
  }
13714
13782
  }
13715
13783
  return this.packmindGateway.deployment.getDeployed({
13716
- packagesSlugs: command34.packagesSlugs,
13717
- gitRemoteUrl: command34.gitRemoteUrl,
13718
- gitBranch: command34.gitBranch,
13719
- relativePath: command34.relativePath,
13720
- agents: command34.agents
13784
+ packagesSlugs: command31.packagesSlugs,
13785
+ gitRemoteUrl: command31.gitRemoteUrl,
13786
+ gitBranch: command31.gitBranch,
13787
+ relativePath: command31.relativePath,
13788
+ agents: command31.agents
13721
13789
  });
13722
13790
  }
13723
13791
  prefixSkillFolders(skillFolders, relativePath) {
@@ -13741,8 +13809,8 @@ var SubmitDiffsUseCase = class {
13741
13809
  constructor(packmindGateway) {
13742
13810
  this.packmindGateway = packmindGateway;
13743
13811
  }
13744
- async execute(command34) {
13745
- const { groupedDiffs, message } = command34;
13812
+ async execute(command31) {
13813
+ const { groupedDiffs, message } = command31;
13746
13814
  const skipped = [];
13747
13815
  const validDiffs = [];
13748
13816
  for (const group of groupedDiffs) {
@@ -13817,8 +13885,8 @@ var CheckDiffsUseCase = class {
13817
13885
  constructor(packmindGateway) {
13818
13886
  this.packmindGateway = packmindGateway;
13819
13887
  }
13820
- async execute(command34) {
13821
- const { groupedDiffs } = command34;
13888
+ async execute(command31) {
13889
+ const { groupedDiffs } = command31;
13822
13890
  const results = [];
13823
13891
  const validDiffs = [];
13824
13892
  const invalidDiffs = [];
@@ -13916,8 +13984,8 @@ var CliFormatter = class {
13916
13984
  static error(message) {
13917
13985
  return `${source_default.bgRed.bold(CLI_PREFIX2)} ${source_default.red(message)}`;
13918
13986
  }
13919
- static command(command34) {
13920
- return source_default.yellow(command34);
13987
+ static command(command31) {
13988
+ return source_default.yellow(command31);
13921
13989
  }
13922
13990
  static loader(text) {
13923
13991
  return source_default.dim.italic(text);
@@ -14036,6 +14104,101 @@ var CliOutput = class {
14036
14104
  }
14037
14105
  };
14038
14106
 
14107
+ // apps/cli/src/application/useCases/trackRepository/TrackRepositoryUseCase.ts
14108
+ function parseOwnerRepo(gitRemoteUrl) {
14109
+ const match = gitRemoteUrl.match(/[/:]([^/:]+)\/([^/]+?)(?:\.git)?\/?$/i);
14110
+ if (!match) {
14111
+ throw new Error(`Unable to parse git remote URL: ${gitRemoteUrl}`);
14112
+ }
14113
+ return {
14114
+ owner: match[1],
14115
+ repo: match[2].replace(/\.git$/, "")
14116
+ };
14117
+ }
14118
+ function parseProviderVendor(gitRemoteUrl) {
14119
+ const normalized = gitRemoteUrl.toLowerCase();
14120
+ if (normalized.includes("github.com")) {
14121
+ return "github";
14122
+ }
14123
+ if (normalized.includes("gitlab.com")) {
14124
+ return "gitlab";
14125
+ }
14126
+ return "unknown";
14127
+ }
14128
+ var TrackRepositoryUseCase = class {
14129
+ constructor(gateway, gitService) {
14130
+ this.gateway = gateway;
14131
+ this.gitService = gitService;
14132
+ }
14133
+ async execute(command31) {
14134
+ const { repoPath, origin: origin9, update, confirm } = command31;
14135
+ const { gitRemoteUrl } = this.gitService.getGitRemoteUrl(repoPath);
14136
+ const { branch } = this.gitService.getCurrentBranch(repoPath);
14137
+ const { owner, repo } = parseOwnerRepo(gitRemoteUrl);
14138
+ const providerVendor = parseProviderVendor(gitRemoteUrl);
14139
+ const { gitRepo: tracked } = await this.gateway.getTrackedRepository({
14140
+ owner,
14141
+ repo
14142
+ });
14143
+ if (update) {
14144
+ if (!tracked) {
14145
+ return { status: "nothing-tracked", owner, repo, branch };
14146
+ }
14147
+ if (tracked.branch === branch) {
14148
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14149
+ }
14150
+ const confirmed2 = await confirm({
14151
+ mode: "update",
14152
+ owner,
14153
+ repo,
14154
+ branch,
14155
+ fromBranch: tracked.branch
14156
+ });
14157
+ if (!confirmed2) {
14158
+ return { status: "cancelled" };
14159
+ }
14160
+ const gitRepo2 = await this.gateway.updateTrackedBranch({
14161
+ owner,
14162
+ repo,
14163
+ branch
14164
+ });
14165
+ return {
14166
+ status: "updated",
14167
+ owner,
14168
+ repo,
14169
+ branch,
14170
+ fromBranch: tracked.branch,
14171
+ gitRepo: gitRepo2
14172
+ };
14173
+ }
14174
+ if (tracked) {
14175
+ if (tracked.branch === branch) {
14176
+ return { status: "already-tracked-same-branch", owner, repo, branch };
14177
+ }
14178
+ return {
14179
+ status: "already-tracked-other-branch",
14180
+ owner,
14181
+ repo,
14182
+ branch,
14183
+ trackedBranch: tracked.branch
14184
+ };
14185
+ }
14186
+ const confirmed = await confirm({ mode: "set", owner, repo, branch });
14187
+ if (!confirmed) {
14188
+ return { status: "cancelled" };
14189
+ }
14190
+ const gitRepo = await this.gateway.setTrackedRepository({
14191
+ owner,
14192
+ repo,
14193
+ branch,
14194
+ origin: origin9,
14195
+ providerVendor,
14196
+ gitRemoteUrl
14197
+ });
14198
+ return { status: "set", owner, repo, branch, gitRepo };
14199
+ }
14200
+ };
14201
+
14039
14202
  // apps/cli/src/PackmindCliHexaFactory.ts
14040
14203
  var PackmindCliHexaFactory = class {
14041
14204
  constructor() {
@@ -14121,7 +14284,11 @@ var PackmindCliHexaFactory = class {
14121
14284
  this.repositories.lockFileRepository
14122
14285
  ),
14123
14286
  submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway),
14124
- checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway)
14287
+ checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway),
14288
+ trackRepository: new TrackRepositoryUseCase(
14289
+ this.repositories.packmindGateway.repositoryTracking,
14290
+ this.services.gitRemoteUrlService
14291
+ )
14125
14292
  };
14126
14293
  }
14127
14294
  };
@@ -14130,24 +14297,29 @@ var PackmindCliHexaFactory = class {
14130
14297
  var origin8 = "PackmindCliHexa";
14131
14298
  var PackmindCliHexa = class {
14132
14299
  constructor(logger2 = new PackmindLogger(origin8)) {
14133
- this.notifyDistribution = async (command34) => {
14300
+ this.notifyDistribution = async (command31) => {
14134
14301
  return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
14135
- command34
14302
+ command31
14136
14303
  );
14137
14304
  };
14138
- this.notifyArtefactsDistribution = async (command34) => {
14305
+ this.notifyArtefactsDistribution = async (command31) => {
14139
14306
  return this.hexa.repositories.packmindGateway.deployment.notifyArtefactsDistribution(
14140
- command34
14307
+ command31
14141
14308
  );
14142
14309
  };
14143
- this.renderPlugin = async (command34) => {
14310
+ this.getTrackedRepository = async (command31) => {
14311
+ return this.hexa.repositories.packmindGateway.repositoryTracking.getTrackedRepository(
14312
+ command31
14313
+ );
14314
+ };
14315
+ this.renderPlugin = async (command31) => {
14144
14316
  return this.hexa.repositories.packmindGateway.deployment.renderPlugin(
14145
- command34
14317
+ command31
14146
14318
  );
14147
14319
  };
14148
- this.trackPluginDeleted = async (command34) => {
14320
+ this.trackPluginDeleted = async (command31) => {
14149
14321
  return this.hexa.repositories.packmindGateway.deployment.trackPluginDeleted(
14150
- command34
14322
+ command31
14151
14323
  );
14152
14324
  };
14153
14325
  this.logger = logger2;
@@ -14170,29 +14342,29 @@ var PackmindCliHexa = class {
14170
14342
  get output() {
14171
14343
  return this.hexa.repositories.output;
14172
14344
  }
14173
- async getGitRemoteUrl(command34) {
14174
- return this.hexa.useCases.getGitRemoteUrl.execute(command34);
14345
+ async getGitRemoteUrl(command31) {
14346
+ return this.hexa.useCases.getGitRemoteUrl.execute(command31);
14175
14347
  }
14176
- async listFilesInDirectory(command34) {
14177
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command34);
14348
+ async listFilesInDirectory(command31) {
14349
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command31);
14178
14350
  }
14179
- async lintFilesAgainstRule(command34) {
14180
- return this.hexa.useCases.lintFilesAgainstRule.execute(command34);
14351
+ async lintFilesAgainstRule(command31) {
14352
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command31);
14181
14353
  }
14182
- async lintFilesFromConfig(command34) {
14183
- return this.hexa.useCases.lintFilesFromConfig.execute(command34);
14354
+ async lintFilesFromConfig(command31) {
14355
+ return this.hexa.useCases.lintFilesFromConfig.execute(command31);
14184
14356
  }
14185
- async installPackages(command34) {
14186
- return this.hexa.useCases.installPackages.execute(command34);
14357
+ async installPackages(command31) {
14358
+ return this.hexa.useCases.installPackages.execute(command31);
14187
14359
  }
14188
- async install(command34) {
14189
- return this.hexa.useCases.install.execute(command34);
14360
+ async install(command31) {
14361
+ return this.hexa.useCases.install.execute(command31);
14190
14362
  }
14191
- async uninstall(command34) {
14192
- return this.hexa.useCases.uninstall.execute(command34);
14363
+ async uninstall(command31) {
14364
+ return this.hexa.useCases.uninstall.execute(command31);
14193
14365
  }
14194
- async diffArtefacts(command34) {
14195
- return this.hexa.useCases.diffArtefacts.execute(command34);
14366
+ async diffArtefacts(command31) {
14367
+ return this.hexa.useCases.diffArtefacts.execute(command31);
14196
14368
  }
14197
14369
  async submitDiffs(groupedDiffs, message) {
14198
14370
  return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
@@ -14200,20 +14372,20 @@ var PackmindCliHexa = class {
14200
14372
  async checkDiffs(groupedDiffs) {
14201
14373
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
14202
14374
  }
14203
- async listPackages(command34) {
14204
- return this.hexa.useCases.listPackages.execute(command34);
14375
+ async listPackages(command31) {
14376
+ return this.hexa.useCases.listPackages.execute(command31);
14205
14377
  }
14206
- async getPackageBySlug(command34) {
14207
- return this.hexa.useCases.getPackageBySlug.execute(command34);
14378
+ async getPackageBySlug(command31) {
14379
+ return this.hexa.useCases.getPackageBySlug.execute(command31);
14208
14380
  }
14209
- async listStandards(command34) {
14210
- return this.hexa.useCases.listStandards.execute(command34);
14381
+ async listStandards(command31) {
14382
+ return this.hexa.useCases.listStandards.execute(command31);
14211
14383
  }
14212
- async listCommands(command34) {
14213
- return this.hexa.useCases.listCommands.execute(command34);
14384
+ async listCommands(command31) {
14385
+ return this.hexa.useCases.listCommands.execute(command31);
14214
14386
  }
14215
- async listSkills(command34) {
14216
- return this.hexa.useCases.listSkills.execute(command34);
14387
+ async listSkills(command31) {
14388
+ return this.hexa.useCases.listSkills.execute(command31);
14217
14389
  }
14218
14390
  async configExists(baseDirectory) {
14219
14391
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -14300,17 +14472,17 @@ var PackmindCliHexa = class {
14300
14472
  directory
14301
14473
  );
14302
14474
  }
14303
- async login(command34) {
14304
- return this.hexa.useCases.login.execute(command34);
14475
+ async login(command31) {
14476
+ return this.hexa.useCases.login.execute(command31);
14305
14477
  }
14306
- async logout(command34) {
14307
- return this.hexa.useCases.logout.execute(command34);
14478
+ async logout(command31) {
14479
+ return this.hexa.useCases.logout.execute(command31);
14308
14480
  }
14309
- async whoami(command34) {
14310
- return this.hexa.useCases.whoami.execute(command34);
14481
+ async whoami(command31) {
14482
+ return this.hexa.useCases.whoami.execute(command31);
14311
14483
  }
14312
- async checkCliVersion(command34) {
14313
- return this.hexa.useCases.checkCliVersion.execute(command34);
14484
+ async checkCliVersion(command31) {
14485
+ return this.hexa.useCases.checkCliVersion.execute(command31);
14314
14486
  }
14315
14487
  getCurrentBranch(repoPath) {
14316
14488
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -14318,19 +14490,22 @@ var PackmindCliHexa = class {
14318
14490
  getGitRemoteUrlFromPath(repoPath) {
14319
14491
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
14320
14492
  }
14321
- async uploadSkill(command34) {
14322
- return this.hexa.useCases.uploadSkill.execute(command34);
14493
+ async uploadSkill(command31) {
14494
+ return this.hexa.useCases.uploadSkill.execute(command31);
14323
14495
  }
14324
- async installDefaultSkills(command34) {
14325
- return this.hexa.useCases.installDefaultSkills.execute(command34);
14496
+ async installDefaultSkills(command31) {
14497
+ return this.hexa.useCases.installDefaultSkills.execute(command31);
14326
14498
  }
14327
- async bootstrapSkillsInitDirectory(command34) {
14499
+ async bootstrapSkillsInitDirectory(command31) {
14328
14500
  return this.hexa.useCases.installDefaultSkills.bootstrapEmptyDirectory(
14329
- command34.baseDirectory
14501
+ command31.baseDirectory
14330
14502
  );
14331
14503
  }
14332
- async ensureCliVersion(command34) {
14333
- return this.hexa.useCases.ensureCliVersion.execute(command34);
14504
+ async ensureCliVersion(command31) {
14505
+ return this.hexa.useCases.ensureCliVersion.execute(command31);
14506
+ }
14507
+ async trackRepository(command31) {
14508
+ return this.hexa.useCases.trackRepository.execute(command31);
14334
14509
  }
14335
14510
  getPackmindGateway() {
14336
14511
  return this.hexa.repositories.packmindGateway;
@@ -14675,21 +14850,6 @@ var RuleID = {
14675
14850
  }
14676
14851
  };
14677
14852
 
14678
- // apps/cli/src/infra/commands/customParameters/DiffModeType.ts
14679
- var DiffModeType = {
14680
- from: async (input) => {
14681
- switch (input) {
14682
- case "files":
14683
- return "files" /* FILES */;
14684
- case "lines":
14685
- return "lines" /* LINES */;
14686
- }
14687
- throw new Error(
14688
- `${input} is not a valid value for the --diff option. Expected values are: files, lines`
14689
- );
14690
- }
14691
- };
14692
-
14693
14853
  // apps/cli/src/infra/commands/customParameters/LevelType.ts
14694
14854
  var LevelType = {
14695
14855
  from: async (input) => {
@@ -14746,12 +14906,7 @@ var lintCommand = (0, import_cmd_ts.command)({
14746
14906
  }),
14747
14907
  continueOnMissingKey: (0, import_cmd_ts.flag)({
14748
14908
  long: "continue-on-missing-key",
14749
- description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY_V3 is not set"
14750
- }),
14751
- diff: (0, import_cmd_ts.option)({
14752
- long: "diff",
14753
- description: "[Deprecated: use --changed-files or --changed-lines] Filter violations by git diff (files | lines)",
14754
- type: (0, import_cmd_ts.optional)(DiffModeType)
14909
+ description: "Skip linting and exit with status code 0 if PACKMIND_API_KEY is not set"
14755
14910
  }),
14756
14911
  changedFiles: (0, import_cmd_ts.flag)({
14757
14912
  long: "changed-files",
@@ -14773,16 +14928,6 @@ var lintCommand = (0, import_cmd_ts.command)({
14773
14928
  "Options --changed-files and --changed-lines are mutually exclusive"
14774
14929
  );
14775
14930
  }
14776
- if (args2.diff) {
14777
- const replacement = args2.diff === "files" /* FILES */ ? "--changed-files" : "--changed-lines";
14778
- logWarningConsole(`--diff is deprecated. Use ${replacement} instead.`);
14779
- }
14780
- let diff = args2.diff;
14781
- if (args2.changedFiles) {
14782
- diff = "files" /* FILES */;
14783
- } else if (args2.changedLines) {
14784
- diff = "lines" /* LINES */;
14785
- }
14786
14931
  const packmindLogger = new PackmindLogger(
14787
14932
  "PackmindCLI",
14788
14933
  args2.debug ? "debug" /* DEBUG */ : "info" /* INFO */
@@ -14794,7 +14939,13 @@ var lintCommand = (0, import_cmd_ts.command)({
14794
14939
  resolvePath: (targetPath) => pathModule2.isAbsolute(targetPath) ? targetPath : pathModule2.resolve(process.cwd(), targetPath),
14795
14940
  exit: (code) => process.exit(code)
14796
14941
  };
14797
- await lintHandler({ ...args2, diff }, deps);
14942
+ const handlerArgs = args2;
14943
+ if (args2.changedFiles) {
14944
+ handlerArgs.diff = "files" /* FILES */;
14945
+ } else if (args2.changedLines) {
14946
+ handlerArgs.diff = "lines" /* LINES */;
14947
+ }
14948
+ await lintHandler(handlerArgs, deps);
14798
14949
  }
14799
14950
  });
14800
14951
 
@@ -15110,7 +15261,7 @@ var AgentArtifactDetectionService = class {
15110
15261
 
15111
15262
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15112
15263
  var readline3 = __toESM(require("readline"));
15113
- var inquirer2 = __toESM(require("inquirer"));
15264
+ var inquirer3 = __toESM(require("inquirer"));
15114
15265
 
15115
15266
  // apps/cli/src/infra/commands/config/configAgentsHandler.ts
15116
15267
  var readline2 = __toESM(require("readline"));
@@ -15383,6 +15534,35 @@ function buildSkillsSkippedWarning(configuredAgents) {
15383
15534
  return `Skipping default skills \u2014 your configured agents (${configuredAgents.join(", ")}) do not support skills. Run ${configHint} to add an agent supporting skills (e.g. claude).`;
15384
15535
  }
15385
15536
 
15537
+ // apps/cli/src/infra/commands/trackingPrompts.ts
15538
+ var inquirer2 = __toESM(require("inquirer"));
15539
+ function buildTrackConfirmationMessage(details) {
15540
+ if (details.mode === "update") {
15541
+ return `Change the tracked branch for ${details.owner}/${details.repo} from ${details.fromBranch} to ${details.branch}?`;
15542
+ }
15543
+ return `Track ${details.owner}/${details.repo} on branch ${details.branch}?`;
15544
+ }
15545
+ async function defaultConfirmPrompt(message) {
15546
+ const { confirmed } = await inquirer2.default.prompt([
15547
+ {
15548
+ type: "confirm",
15549
+ name: "confirmed",
15550
+ message,
15551
+ default: true
15552
+ }
15553
+ ]);
15554
+ return confirmed;
15555
+ }
15556
+ function createTrackConfirm(options) {
15557
+ const confirmPrompt = options.confirmPrompt ?? defaultConfirmPrompt;
15558
+ return async (details) => {
15559
+ if (!options.isTTY) {
15560
+ return true;
15561
+ }
15562
+ return confirmPrompt(buildTrackConfirmationMessage(details));
15563
+ };
15564
+ }
15565
+
15386
15566
  // apps/cli/src/infra/commands/initHandler.ts
15387
15567
  async function initHandler(deps) {
15388
15568
  const {
@@ -15394,8 +15574,11 @@ async function initHandler(deps) {
15394
15574
  ensureCliVersion,
15395
15575
  cliVersion,
15396
15576
  isTTY,
15397
- showOnboardHint = true
15577
+ showOnboardHint = true,
15578
+ trackRepository,
15579
+ confirmPrompt
15398
15580
  } = deps;
15581
+ const resolvedIsTTY = isTTY ?? Boolean(process.stdin.isTTY);
15399
15582
  if (ensureCliVersion) {
15400
15583
  try {
15401
15584
  const outcome = await ensureCliVersion({
@@ -15455,6 +15638,14 @@ async function initHandler(deps) {
15455
15638
  }
15456
15639
  }
15457
15640
  }
15641
+ if (resolvedIsTTY && trackRepository) {
15642
+ await offerRepositoryTracking({
15643
+ trackRepository,
15644
+ baseDirectory,
15645
+ isTTY: resolvedIsTTY,
15646
+ confirmPrompt
15647
+ });
15648
+ }
15458
15649
  logConsole("");
15459
15650
  logSuccessConsole("Packmind initialized successfully!");
15460
15651
  if (showOnboardHint) {
@@ -15467,6 +15658,43 @@ async function initHandler(deps) {
15467
15658
  errors: []
15468
15659
  };
15469
15660
  }
15661
+ async function offerRepositoryTracking(deps) {
15662
+ const confirm = createTrackConfirm({
15663
+ isTTY: deps.isTTY,
15664
+ confirmPrompt: deps.confirmPrompt
15665
+ });
15666
+ try {
15667
+ const result = await deps.trackRepository({
15668
+ repoPath: deps.baseDirectory,
15669
+ origin: "init",
15670
+ update: false,
15671
+ confirm
15672
+ });
15673
+ switch (result.status) {
15674
+ case "set":
15675
+ logSuccessConsole(
15676
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
15677
+ );
15678
+ break;
15679
+ case "already-tracked-other-branch":
15680
+ logInfoConsole(
15681
+ `Repository already tracked on branch ${result.trackedBranch}.`
15682
+ );
15683
+ break;
15684
+ case "already-tracked-same-branch":
15685
+ logWarningConsole(
15686
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
15687
+ );
15688
+ break;
15689
+ case "cancelled":
15690
+ case "nothing-tracked":
15691
+ case "updated":
15692
+ default:
15693
+ break;
15694
+ }
15695
+ } catch {
15696
+ }
15697
+ }
15470
15698
 
15471
15699
  // apps/cli/src/infra/commands/bootstrapInstallContext.ts
15472
15700
  async function bootstrapInstallContext(deps) {
@@ -15612,7 +15840,7 @@ async function promptOrgRenderModes(params) {
15612
15840
  if (useSimplePrompt) {
15613
15841
  confirmed = await confirmWithReadline(`${promptMessage} [Y/n] `);
15614
15842
  } else {
15615
- const answer = await inquirer2.default.prompt([
15843
+ const answer = await inquirer3.default.prompt([
15616
15844
  {
15617
15845
  type: "select",
15618
15846
  name: "confirm",
@@ -15758,23 +15986,129 @@ function mergeInstallResults(results) {
15758
15986
  }
15759
15987
  return merged;
15760
15988
  }
15989
+ function decideDistributionTracking(params) {
15990
+ const { lookup, currentBranch } = params;
15991
+ switch (lookup.status) {
15992
+ case "flag-off":
15993
+ return { action: "record-legacy" };
15994
+ case "unavailable":
15995
+ return { action: "inform" };
15996
+ case "resolved": {
15997
+ const tracked = lookup.trackedGitRepo;
15998
+ if (!tracked) {
15999
+ return { action: "skip", reason: "repo_not_tracked" };
16000
+ }
16001
+ if (tracked.branch !== currentBranch) {
16002
+ return {
16003
+ action: "skip",
16004
+ reason: "wrong_branch",
16005
+ trackedBranch: tracked.branch
16006
+ };
16007
+ }
16008
+ return { action: "record" };
16009
+ }
16010
+ }
16011
+ }
16012
+ var NO_GIT_REPO_CACHE_KEY = "<no-git-repo>";
16013
+ function toRepoRelativePath(dir, gitRoot) {
16014
+ let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
16015
+ if (!relativePath.startsWith("/")) {
16016
+ relativePath = "/" + relativePath;
16017
+ }
16018
+ if (!relativePath.endsWith("/")) {
16019
+ relativePath = relativePath + "/";
16020
+ }
16021
+ return relativePath;
16022
+ }
16023
+ function reportDistributionTrackingDecision(decision, context) {
16024
+ switch (decision.action) {
16025
+ case "skip":
16026
+ if (decision.reason === "repo_not_tracked") {
16027
+ logWarningConsole(
16028
+ `Distribution not recorded \u2014 ${context.owner}/${context.repo} is not tracked in Packmind. Ask an admin to run ${formatCommand(
16029
+ "packmind track"
16030
+ )} to start tracking it.`
16031
+ );
16032
+ } else {
16033
+ logWarningConsole(
16034
+ `Distribution not recorded \u2014 you're on '${context.currentBranch}', but the tracked branch is '${decision.trackedBranch}'. Switch to '${decision.trackedBranch}' to record this distribution.`
16035
+ );
16036
+ }
16037
+ break;
16038
+ case "inform":
16039
+ logInfoConsole(
16040
+ `This folder is not tracked \u2014 distribution not recorded in Packmind.`
16041
+ );
16042
+ break;
16043
+ }
16044
+ }
16045
+ async function resolveTrackingLookup(packmindCliHexa, owner, repo) {
16046
+ try {
16047
+ const { gitRepo } = await packmindCliHexa.getTrackedRepository({
16048
+ owner,
16049
+ repo
16050
+ });
16051
+ return { status: "resolved", trackedGitRepo: gitRepo };
16052
+ } catch (error) {
16053
+ const statusCode = error?.statusCode;
16054
+ if (statusCode === 404) {
16055
+ return { status: "flag-off" };
16056
+ }
16057
+ return { status: "unavailable" };
16058
+ }
16059
+ }
16060
+ async function computeDistributionTrackingDecision(packmindCliHexa, gitRoot) {
16061
+ if (!gitRoot) {
16062
+ const decision2 = { action: "inform" };
16063
+ reportDistributionTrackingDecision(decision2, {});
16064
+ return decision2;
16065
+ }
16066
+ let owner;
16067
+ let repo;
16068
+ let gitBranch;
16069
+ try {
16070
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
16071
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
16072
+ ({ owner, repo } = parseOwnerRepo(gitRemoteUrl));
16073
+ } catch {
16074
+ const decision2 = { action: "inform" };
16075
+ reportDistributionTrackingDecision(decision2, {});
16076
+ return decision2;
16077
+ }
16078
+ const lookup = await resolveTrackingLookup(packmindCliHexa, owner, repo);
16079
+ const decision = decideDistributionTracking({
16080
+ lookup,
16081
+ currentBranch: gitBranch
16082
+ });
16083
+ reportDistributionTrackingDecision(decision, {
16084
+ owner,
16085
+ repo,
16086
+ currentBranch: gitBranch
16087
+ });
16088
+ return decision;
16089
+ }
15761
16090
  async function notifyArtefactsDistributionIfInGitRepo(params) {
15762
- const { packmindCliHexa, dir } = params;
16091
+ const { packmindCliHexa, dir, decisionCache } = params;
15763
16092
  try {
15764
16093
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(dir);
16094
+ const cacheKey = gitRoot ?? NO_GIT_REPO_CACHE_KEY;
16095
+ if (!decisionCache.has(cacheKey)) {
16096
+ decisionCache.set(
16097
+ cacheKey,
16098
+ await computeDistributionTrackingDecision(packmindCliHexa, gitRoot)
16099
+ );
16100
+ }
16101
+ const decision = decisionCache.get(cacheKey);
16102
+ if (!decision || decision.action !== "record" && decision.action !== "record-legacy") {
16103
+ return;
16104
+ }
15765
16105
  if (!gitRoot) return;
15766
16106
  const lockFilePath = path24.join(dir, "packmind-lock.json");
15767
16107
  const content = fs23.readFileSync(lockFilePath, "utf-8");
15768
16108
  const packmindLockFile = JSON.parse(content);
15769
16109
  const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
15770
16110
  const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
15771
- let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
15772
- if (!relativePath.startsWith("/")) {
15773
- relativePath = "/" + relativePath;
15774
- }
15775
- if (!relativePath.endsWith("/")) {
15776
- relativePath = relativePath + "/";
15777
- }
16111
+ const relativePath = toRepoRelativePath(dir, gitRoot);
15778
16112
  await packmindCliHexa.notifyArtefactsDistribution({
15779
16113
  gitRemoteUrl,
15780
16114
  gitBranch,
@@ -15828,10 +16162,7 @@ async function installDefaultSkillsIfAtGitRoot(params) {
15828
16162
  async function installHandler({
15829
16163
  installPath,
15830
16164
  packages,
15831
- list,
15832
- show,
15833
- status,
15834
- skipInstalledAt
16165
+ status
15835
16166
  }) {
15836
16167
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15837
16168
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
@@ -15846,17 +16177,6 @@ async function installHandler({
15846
16177
  await statusHandler({}, deps);
15847
16178
  return;
15848
16179
  }
15849
- if (list) {
15850
- logErrorConsole('Command "packmind-cli install --list" has been removed.');
15851
- logConsole(`Use ${formatCommand("packmind-cli packages list")} instead.`);
15852
- process.exit(1);
15853
- }
15854
- if (show) {
15855
- const showCommand = `packmind-cli packages show ${displayableParsedPackageSlug(show)}`;
15856
- logErrorConsole('Command "packmind-cli install --show" has been removed.');
15857
- logConsole(`Use ${formatCommand(showCommand)} instead.`);
15858
- process.exit(1);
15859
- }
15860
16180
  const cwd = installPath ? path24.resolve(process.cwd(), installPath) : process.cwd();
15861
16181
  if (installPath) {
15862
16182
  if (!fs23.existsSync(cwd)) {
@@ -15920,13 +16240,13 @@ async function installHandler({
15920
16240
  const results = [];
15921
16241
  const thrownErrors = [];
15922
16242
  const multiDir = targetDirs.length > 1;
16243
+ const distributionTrackingCache = /* @__PURE__ */ new Map();
15923
16244
  for (const dir of targetDirs) {
15924
16245
  try {
15925
16246
  const dirHomeAgent = isAgentHomeDirectory(dir) ?? void 0;
15926
16247
  const result = await packmindCliHexa.install({
15927
16248
  baseDirectory: dir,
15928
16249
  packages: packages.length > 0 ? packages : void 0,
15929
- skipInstalledAt,
15930
16250
  cliVersion: CLI_VERSION,
15931
16251
  homeAgent: dirHomeAgent
15932
16252
  });
@@ -15934,7 +16254,8 @@ async function installHandler({
15934
16254
  if (!dirHomeAgent) {
15935
16255
  await notifyArtefactsDistributionIfInGitRepo({
15936
16256
  packmindCliHexa,
15937
- dir
16257
+ dir,
16258
+ decisionCache: distributionTrackingCache
15938
16259
  });
15939
16260
  }
15940
16261
  } catch (error) {
@@ -16007,19 +16328,6 @@ var installCommand = (0, import_cmd_ts2.command)({
16007
16328
  status: (0, import_cmd_ts2.flag)({
16008
16329
  long: "status",
16009
16330
  description: "Show status of all packmind.json files and their packages in the workspace"
16010
- }),
16011
- list: (0, import_cmd_ts2.flag)({
16012
- long: "list",
16013
- description: "[Deprecated] List available packages"
16014
- }),
16015
- show: (0, import_cmd_ts2.option)({
16016
- type: (0, import_cmd_ts2.optional)(PackageSlugArgType),
16017
- long: "show",
16018
- description: "[Deprecated] Show details of a specific package"
16019
- }),
16020
- skipInstalledAt: (0, import_cmd_ts2.flag)({
16021
- long: "skip-installed-at",
16022
- description: "Omit the installedAt timestamp from the packmind-lock.json file"
16023
16331
  })
16024
16332
  },
16025
16333
  handler: installHandler
@@ -16178,9 +16486,9 @@ var logoutCommand = (0, import_cmd_ts5.command)({
16178
16486
  logInfoConsole("No stored credentials file found.");
16179
16487
  }
16180
16488
  logConsole(
16181
- "\nNote: PACKMIND_API_KEY_V3 environment variable is still set."
16489
+ "\nNote: PACKMIND_API_KEY environment variable is still set."
16182
16490
  );
16183
- logConsole("To fully log out, run: unset PACKMIND_API_KEY_V3");
16491
+ logConsole("To fully log out, run: unset PACKMIND_API_KEY");
16184
16492
  }
16185
16493
  } catch (error) {
16186
16494
  logErrorConsole("Failed to remove credentials file.");
@@ -16262,7 +16570,7 @@ No credentials found. Run \`packmind-cli login\` to authenticate.`
16262
16570
  );
16263
16571
  logConsole(`
16264
16572
  Credentials are loaded from (in order of priority):`);
16265
- logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
16573
+ logConsole(` 1. PACKMIND_API_KEY environment variable`);
16266
16574
  logConsole(` 2. ${result.credentialsPath}`);
16267
16575
  process.exit(1);
16268
16576
  }
@@ -16280,65 +16588,16 @@ Credentials are loaded from (in order of priority):`);
16280
16588
  });
16281
16589
 
16282
16590
  // apps/cli/src/infra/commands/SkillsCommand.ts
16283
- var import_cmd_ts11 = __toESM(require_cjs());
16284
-
16285
- // apps/cli/src/infra/commands/skills/AddSkillCommand.ts
16286
- var import_cmd_ts8 = __toESM(require_cjs());
16287
-
16288
- // apps/cli/src/infra/commands/sharedOptions.ts
16289
- var import_cmd_ts7 = __toESM(require_cjs());
16290
- var originSkillOption = (0, import_cmd_ts7.option)({
16291
- long: "origin-skill",
16292
- description: "Name of the skill that triggered this command",
16293
- type: (0, import_cmd_ts7.optional)(import_cmd_ts7.string)
16294
- });
16295
-
16296
- // apps/cli/src/infra/commands/customParameters/SpaceSlug.ts
16297
- var SpaceSlug = {
16298
- from: async (input) => {
16299
- return input.startsWith("@") ? input.slice(1) : input;
16300
- }
16301
- };
16302
-
16303
- // apps/cli/src/infra/commands/skills/AddSkillCommand.ts
16304
- var addSkillCommand = (0, import_cmd_ts8.command)({
16305
- name: "add",
16306
- description: "[Deprecated] Add a skill from a local directory to a Packmind organization",
16307
- args: {
16308
- skillPath: (0, import_cmd_ts8.positional)({
16309
- type: import_cmd_ts8.string,
16310
- displayName: "path",
16311
- description: "Path to skill directory containing SKILL.md"
16312
- }),
16313
- space: (0, import_cmd_ts8.option)({
16314
- long: "space",
16315
- description: "Slug of the space in which to add the skill (with or without leading @)",
16316
- type: (0, import_cmd_ts8.optional)(SpaceSlug)
16317
- }),
16318
- originSkill: originSkillOption
16319
- },
16320
- handler: async () => {
16321
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
16322
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
16323
- packmindCliHexa.output.notifyError(
16324
- 'Command "packmind-cli skills add" has been removed.',
16325
- {
16326
- content: 'Use the "playbook add" command instead:',
16327
- exampleCommand: "packmind-cli playbook add .packmind/commands/my-command.md"
16328
- }
16329
- );
16330
- process.exit(1);
16331
- }
16332
- });
16591
+ var import_cmd_ts9 = __toESM(require_cjs());
16333
16592
 
16334
16593
  // apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
16335
- var import_cmd_ts9 = __toESM(require_cjs());
16594
+ var import_cmd_ts7 = __toESM(require_cjs());
16336
16595
  var { version: CLI_VERSION4 } = require_package();
16337
- var installDefaultSkillsCommand = (0, import_cmd_ts9.command)({
16596
+ var installDefaultSkillsCommand = (0, import_cmd_ts7.command)({
16338
16597
  name: "install-default",
16339
16598
  description: "Install default Packmind skills for configured coding agents",
16340
16599
  args: {
16341
- includeBeta: (0, import_cmd_ts9.flag)({
16600
+ includeBeta: (0, import_cmd_ts7.flag)({
16342
16601
  long: "include-beta",
16343
16602
  description: "Include unreleased/beta skills"
16344
16603
  })
@@ -16415,7 +16674,7 @@ var installDefaultSkillsCommand = (0, import_cmd_ts9.command)({
16415
16674
  });
16416
16675
 
16417
16676
  // apps/cli/src/infra/commands/ListSkillsCommand.ts
16418
- var import_cmd_ts10 = __toESM(require_cjs());
16677
+ var import_cmd_ts8 = __toESM(require_cjs());
16419
16678
 
16420
16679
  // apps/cli/src/infra/utils/spaceFilterUtils.ts
16421
16680
  function resolveSpaceFromArgs(spaceArg, spaces) {
@@ -16510,13 +16769,20 @@ ${availableSpaces}`
16510
16769
  }
16511
16770
  }
16512
16771
 
16772
+ // apps/cli/src/infra/commands/customParameters/SpaceSlug.ts
16773
+ var SpaceSlug = {
16774
+ from: async (input) => {
16775
+ return input.startsWith("@") ? input.slice(1) : input;
16776
+ }
16777
+ };
16778
+
16513
16779
  // apps/cli/src/infra/commands/ListSkillsCommand.ts
16514
- var listSkillsCommand = (0, import_cmd_ts10.command)({
16780
+ var listSkillsCommand = (0, import_cmd_ts8.command)({
16515
16781
  name: "list",
16516
16782
  description: "List available skills",
16517
16783
  args: {
16518
- space: (0, import_cmd_ts10.option)({
16519
- type: (0, import_cmd_ts10.optional)(SpaceSlug),
16784
+ space: (0, import_cmd_ts8.option)({
16785
+ type: (0, import_cmd_ts8.optional)(SpaceSlug),
16520
16786
  long: "space",
16521
16787
  description: "Filter skills by space slug"
16522
16788
  })
@@ -16535,53 +16801,20 @@ var listSkillsCommand = (0, import_cmd_ts10.command)({
16535
16801
  });
16536
16802
 
16537
16803
  // apps/cli/src/infra/commands/SkillsCommand.ts
16538
- var skillsCommand = (0, import_cmd_ts11.subcommands)({
16804
+ var skillsCommand = (0, import_cmd_ts9.subcommands)({
16539
16805
  name: "skills",
16540
16806
  description: "Manage skills in your Packmind organization",
16541
16807
  cmds: {
16542
- add: addSkillCommand,
16543
16808
  init: installDefaultSkillsCommand,
16544
16809
  list: listSkillsCommand
16545
16810
  }
16546
16811
  });
16547
16812
 
16548
16813
  // apps/cli/src/infra/commands/StandardsCommand.ts
16549
- var import_cmd_ts14 = __toESM(require_cjs());
16550
-
16551
- // apps/cli/src/infra/commands/CreateStandardCommand.ts
16552
- var import_cmd_ts12 = __toESM(require_cjs());
16553
- var createStandardCommand = (0, import_cmd_ts12.command)({
16554
- name: "create",
16555
- description: "[Deprecated] Create a coding standard from a playbook JSON file or stdin",
16556
- args: {
16557
- file: (0, import_cmd_ts12.positional)({
16558
- displayName: "file",
16559
- description: "Path to the playbook JSON file (reads from stdin if omitted)",
16560
- type: (0, import_cmd_ts12.optional)(import_cmd_ts12.string)
16561
- }),
16562
- space: (0, import_cmd_ts12.option)({
16563
- long: "space",
16564
- description: "Slug of the space in which to create the standard (with or without leading @)",
16565
- type: (0, import_cmd_ts12.optional)(SpaceSlug)
16566
- }),
16567
- originSkill: originSkillOption
16568
- },
16569
- handler: async () => {
16570
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
16571
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
16572
- packmindCliHexa.output.notifyError(
16573
- 'Command "packmind-cli standards create" has been removed.',
16574
- {
16575
- content: 'Use the "playbook add" command instead:',
16576
- exampleCommand: "packmind-cli playbook add .packmind/standards/my-standard.md"
16577
- }
16578
- );
16579
- process.exit(1);
16580
- }
16581
- });
16814
+ var import_cmd_ts11 = __toESM(require_cjs());
16582
16815
 
16583
16816
  // apps/cli/src/infra/commands/ListStandardsCommand.ts
16584
- var import_cmd_ts13 = __toESM(require_cjs());
16817
+ var import_cmd_ts10 = __toESM(require_cjs());
16585
16818
 
16586
16819
  // apps/cli/src/infra/commands/standards/listStandardsHandler.ts
16587
16820
  async function listStandardsHandler(args2, deps) {
@@ -16638,12 +16871,12 @@ ${availableSpaces}`
16638
16871
  }
16639
16872
 
16640
16873
  // apps/cli/src/infra/commands/ListStandardsCommand.ts
16641
- var listStandardsCommand = (0, import_cmd_ts13.command)({
16874
+ var listStandardsCommand = (0, import_cmd_ts10.command)({
16642
16875
  name: "list",
16643
16876
  description: "List available coding standards",
16644
16877
  args: {
16645
- space: (0, import_cmd_ts13.option)({
16646
- type: (0, import_cmd_ts13.optional)(SpaceSlug),
16878
+ space: (0, import_cmd_ts10.option)({
16879
+ type: (0, import_cmd_ts10.optional)(SpaceSlug),
16647
16880
  long: "space",
16648
16881
  description: "Filter standards by space slug"
16649
16882
  })
@@ -16662,52 +16895,19 @@ var listStandardsCommand = (0, import_cmd_ts13.command)({
16662
16895
  });
16663
16896
 
16664
16897
  // apps/cli/src/infra/commands/StandardsCommand.ts
16665
- var standardsCommand = (0, import_cmd_ts14.subcommands)({
16898
+ var standardsCommand = (0, import_cmd_ts11.subcommands)({
16666
16899
  name: "standards",
16667
16900
  description: "Manage coding standards",
16668
16901
  cmds: {
16669
- create: createStandardCommand,
16670
16902
  list: listStandardsCommand
16671
16903
  }
16672
16904
  });
16673
16905
 
16674
16906
  // apps/cli/src/infra/commands/CommandsCommand.ts
16675
- var import_cmd_ts17 = __toESM(require_cjs());
16676
-
16677
- // apps/cli/src/infra/commands/CreateCommandCommand.ts
16678
- var import_cmd_ts15 = __toESM(require_cjs());
16679
- var createCommandCommand = (0, import_cmd_ts15.command)({
16680
- name: "create",
16681
- description: "[Deprecated] Create a command from a playbook JSON file or stdin",
16682
- args: {
16683
- file: (0, import_cmd_ts15.positional)({
16684
- displayName: "file",
16685
- description: "Path to the command playbook JSON file (reads from stdin if omitted)",
16686
- type: (0, import_cmd_ts15.optional)(import_cmd_ts15.string)
16687
- }),
16688
- space: (0, import_cmd_ts15.option)({
16689
- long: "space",
16690
- description: "Slug of the space in which to create the command",
16691
- type: (0, import_cmd_ts15.optional)(SpaceSlug)
16692
- }),
16693
- originSkill: originSkillOption
16694
- },
16695
- handler: async () => {
16696
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
16697
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
16698
- packmindCliHexa.output.notifyError(
16699
- 'Command "packmind-cli commands create" has been removed.',
16700
- {
16701
- content: 'Use the "playbook add" command instead:',
16702
- exampleCommand: "packmind-cli playbook add .packmind/commands/my-command.md"
16703
- }
16704
- );
16705
- process.exit(1);
16706
- }
16707
- });
16907
+ var import_cmd_ts13 = __toESM(require_cjs());
16708
16908
 
16709
16909
  // apps/cli/src/infra/commands/ListCommandsCommand.ts
16710
- var import_cmd_ts16 = __toESM(require_cjs());
16910
+ var import_cmd_ts12 = __toESM(require_cjs());
16711
16911
 
16712
16912
  // apps/cli/src/infra/commands/commands/listCommandsHandler.ts
16713
16913
  async function listCommandsHandler(args2, deps) {
@@ -16763,12 +16963,12 @@ ${availableSpaces}`
16763
16963
  }
16764
16964
 
16765
16965
  // apps/cli/src/infra/commands/ListCommandsCommand.ts
16766
- var listCommandsCommand = (0, import_cmd_ts16.command)({
16966
+ var listCommandsCommand = (0, import_cmd_ts12.command)({
16767
16967
  name: "list",
16768
16968
  description: "List available commands",
16769
16969
  args: {
16770
- space: (0, import_cmd_ts16.option)({
16771
- type: (0, import_cmd_ts16.optional)(SpaceSlug),
16970
+ space: (0, import_cmd_ts12.option)({
16971
+ type: (0, import_cmd_ts12.optional)(SpaceSlug),
16772
16972
  long: "space",
16773
16973
  description: "Filter commands by space slug"
16774
16974
  })
@@ -16785,647 +16985,142 @@ var listCommandsCommand = (0, import_cmd_ts16.command)({
16785
16985
  });
16786
16986
 
16787
16987
  // apps/cli/src/infra/commands/CommandsCommand.ts
16788
- var commandsCommand = (0, import_cmd_ts17.subcommands)({
16988
+ var commandsCommand = (0, import_cmd_ts13.subcommands)({
16789
16989
  name: "commands",
16790
16990
  description: "Manage commands",
16791
16991
  cmds: {
16792
- create: createCommandCommand,
16793
16992
  list: listCommandsCommand
16794
16993
  }
16795
16994
  });
16796
16995
 
16797
- // apps/cli/src/infra/commands/DiffCommand.ts
16798
- var import_cmd_ts18 = __toESM(require_cjs());
16996
+ // apps/cli/src/infra/commands/PackagesCommand.ts
16997
+ var import_cmd_ts19 = __toESM(require_cjs());
16799
16998
 
16800
- // apps/cli/src/infra/commands/playbook/diffArtefactsHandler.ts
16801
- var nodePath = __toESM(require("path"));
16802
- var fs24 = __toESM(require("fs/promises"));
16999
+ // apps/cli/src/infra/commands/CreatePackageCommand.ts
17000
+ var import_cmd_ts15 = __toESM(require_cjs());
16803
17001
 
16804
- // apps/cli/src/infra/utils/diffFormatter.ts
16805
- var import_diff4 = require("diff");
16806
- init_source();
16807
- function formatContentDiff(oldContent, newContent) {
16808
- const changes = (0, import_diff4.diffLines)(oldContent, newContent);
16809
- const lines = [];
16810
- for (const change of changes) {
16811
- const trimmedValue = change.value.replace(/\n$/, "");
16812
- const changeLines = trimmedValue.split("\n");
16813
- if (change.added) {
16814
- for (const line of changeLines) {
16815
- lines.push(source_default.green(` + ${line}`));
16816
- }
16817
- } else if (change.removed) {
16818
- for (const line of changeLines) {
16819
- lines.push(source_default.red(` - ${line}`));
16820
- }
16821
- }
16822
- }
16823
- return {
16824
- lines,
16825
- hasChanges: lines.length > 0
16826
- };
17002
+ // apps/cli/src/infra/commands/packages/createPackageHandler.ts
17003
+ function toExpectedSlug(name) {
17004
+ return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
16827
17005
  }
16828
-
16829
- // apps/cli/src/infra/commands/formatAdditionalPropertyDiff.ts
16830
- function formatAdditionalPropertyDiff(targetId, oldValue, newValue) {
16831
- const displayKey = CAMEL_TO_YAML_KEY[targetId] ?? camelToKebab(targetId);
16832
- const lines = [];
16833
- if (oldValue && oldValue !== "null") {
16834
- lines.push({ type: "removed", text: `${displayKey}: ${oldValue}` });
17006
+ function buildWebappUrl(host, orgSlug, spaceSlug, packageId) {
17007
+ return `${host}/org/${orgSlug}/space/${spaceSlug}/packages/${packageId}`;
17008
+ }
17009
+ async function createPackageHandler(name, description, useCase, originSkill, spaceSlug) {
17010
+ const trimmedName = name.trim();
17011
+ if (!trimmedName) {
17012
+ return { success: false, error: "Package name is required" };
16835
17013
  }
16836
- if (newValue && newValue !== "null") {
16837
- lines.push({ type: "added", text: `${displayKey}: ${newValue}` });
17014
+ try {
17015
+ const result = await useCase.execute({
17016
+ name: trimmedName,
17017
+ description,
17018
+ originSkill,
17019
+ spaceSlug
17020
+ });
17021
+ let webappUrl;
17022
+ const apiKey = loadApiKey();
17023
+ if (apiKey) {
17024
+ const decoded = decodeApiKey(apiKey);
17025
+ if (decoded?.host && decoded?.jwt?.organization?.slug) {
17026
+ webappUrl = buildWebappUrl(
17027
+ decoded.host,
17028
+ decoded.jwt.organization.slug,
17029
+ result.spaceSlug,
17030
+ result.packageId
17031
+ );
17032
+ }
17033
+ }
17034
+ const deduplicated = result.slug !== toExpectedSlug(trimmedName);
17035
+ return {
17036
+ success: true,
17037
+ slug: `@${result.spaceSlug}/${result.slug}`,
17038
+ packageName: result.name,
17039
+ packageId: result.packageId,
17040
+ webappUrl,
17041
+ deduplicated
17042
+ };
17043
+ } catch (e) {
17044
+ return {
17045
+ success: false,
17046
+ error: e instanceof Error ? e.message : "Unknown error"
17047
+ };
16838
17048
  }
16839
- return lines;
16840
17049
  }
16841
17050
 
16842
- // apps/cli/src/infra/commands/playbook/diffArtefactsHandler.ts
16843
- init_source();
16844
- var ARTIFACT_TYPE_LABELS = {
16845
- command: "Command",
16846
- standard: "Standard",
16847
- skill: "Skill"
16848
- };
16849
- function subGroupByChangeContent(diffs) {
16850
- const groups = /* @__PURE__ */ new Map();
16851
- for (const diff of diffs) {
16852
- const key = JSON.stringify({ type: diff.type, payload: diff.payload });
16853
- const group = groups.get(key) ?? [];
16854
- group.push(diff);
16855
- groups.set(key, group);
16856
- }
16857
- return Array.from(groups.values());
16858
- }
16859
- function groupDiffsByArtefact(diffs) {
16860
- const groups = /* @__PURE__ */ new Map();
16861
- for (const diff of diffs) {
16862
- const key = `${diff.artifactType}:${diff.artifactName}`;
16863
- const group = groups.get(key) ?? [];
16864
- group.push(diff);
16865
- groups.set(key, group);
17051
+ // apps/cli/src/application/useCases/CreatePackageUseCase.ts
17052
+ var CreatePackageUseCase = class {
17053
+ constructor(gateway, spaceService) {
17054
+ this.gateway = gateway;
17055
+ this.spaceService = spaceService;
16866
17056
  }
16867
- return groups;
16868
- }
16869
- function formatDiffPayload(diff, log) {
16870
- const payload = diff.payload;
16871
- if (diff.type === "addSkillFile" /* addSkillFile */) {
16872
- const item = payload.item;
16873
- if (item.isBase64) {
16874
- log(source_default.green(" + [binary file]"));
16875
- } else {
16876
- for (const line of item.content.split("\n")) {
16877
- log(source_default.green(` + ${line}`));
16878
- }
16879
- }
16880
- return;
17057
+ async execute(command31) {
17058
+ const space = await this.getSpace(command31);
17059
+ const result = await this.gateway.packages.create({
17060
+ spaceId: space.id,
17061
+ name: command31.name,
17062
+ description: command31.description ?? "",
17063
+ recipeIds: [],
17064
+ standardIds: [],
17065
+ originSkill: command31.originSkill
17066
+ });
17067
+ return {
17068
+ packageId: result.package.id,
17069
+ name: result.package.name,
17070
+ slug: result.package.slug,
17071
+ spaceSlug: space.slug
17072
+ };
16881
17073
  }
16882
- if (diff.type === "deleteSkillFile" /* deleteSkillFile */) {
16883
- const item = payload.item;
16884
- if (item.isBase64) {
16885
- log(source_default.red(" - [binary file]"));
16886
- } else {
16887
- const lines2 = item.content.split("\n");
16888
- const MAX_DELETED_LINES = 3;
16889
- const preview = lines2.slice(0, MAX_DELETED_LINES);
16890
- for (const line of preview) {
16891
- log(source_default.red(` - ${line}`));
16892
- }
16893
- if (lines2.length > MAX_DELETED_LINES) {
16894
- const remaining = lines2.length - MAX_DELETED_LINES;
16895
- log(source_default.red(` ... and ${remaining} more lines deleted`));
17074
+ async getSpace(command31) {
17075
+ const spaces = await this.spaceService.getSpaces();
17076
+ if (command31.spaceSlug) {
17077
+ const found = spaces.find((s) => s.slug === command31.spaceSlug);
17078
+ if (!found) {
17079
+ throw new Error(`Space '${command31.spaceSlug}' not found.`);
16896
17080
  }
17081
+ return found;
16897
17082
  }
16898
- return;
16899
- }
16900
- if (diff.type === "updateSkillFileContent" /* updateSkillFileContent */) {
16901
- const typedPayload = payload;
16902
- if (typedPayload.isBase64) {
16903
- log(source_default.green(" ~ [binary content changed]"));
16904
- return;
16905
- }
16906
- }
16907
- if (diff.type === "addRule" /* addRule */) {
16908
- const item = payload.item;
16909
- log(source_default.green(` + ${item.content}`));
16910
- return;
16911
- }
16912
- if (diff.type === "deleteRule" /* deleteRule */) {
16913
- const item = payload.item;
16914
- log(source_default.red(` - ${item.content}`));
16915
- return;
16916
- }
16917
- if (diff.type === "updateSkillAdditionalProperty" /* updateSkillAdditionalProperty */) {
16918
- const lines2 = formatAdditionalPropertyDiff(
16919
- payload.targetId,
16920
- payload.oldValue,
16921
- payload.newValue
16922
- );
16923
- for (const line of lines2) {
16924
- log(
16925
- line.type === "removed" ? source_default.red(` - ${line.text}`) : source_default.green(` + ${line.text}`)
17083
+ if (spaces.length > 1) {
17084
+ const spaceList = spaces.map((s) => ` - ${s.name} (--space ${s.slug})`).join("\n");
17085
+ throw new Error(
17086
+ `Your organization has multiple spaces. Please specify one using the --space option.
17087
+
17088
+ Available spaces:
17089
+ ${spaceList}`
16926
17090
  );
16927
17091
  }
16928
- return;
16929
- }
16930
- const oldValue = payload.oldValue;
16931
- const newValue = payload.newValue;
16932
- const { lines } = formatContentDiff(oldValue, newValue);
16933
- for (const line of lines) {
16934
- log(line);
17092
+ return spaces[0];
16935
17093
  }
16936
- }
16937
- function formatSubmittedDate(isoDate) {
16938
- const date = new Date(isoDate);
16939
- const datePart = date.toLocaleDateString("en-US", {
16940
- year: "numeric",
16941
- month: "short",
16942
- day: "numeric"
16943
- });
16944
- const timePart = date.toLocaleTimeString("en-US", {
16945
- hour: "numeric",
16946
- minute: "2-digit",
16947
- hour12: true
16948
- });
16949
- return `${datePart} ${timePart}`;
16950
- }
16951
- function buildSubmittedFooter(submittedDiffs) {
16952
- const proposalCount = submittedDiffs.length;
16953
- const proposalWord = proposalCount === 1 ? "change proposal" : "change proposals";
16954
- return `${proposalCount} ${proposalWord} ignored, run \`packmind-cli diff --include-submitted\` to see what's waiting for validation`;
16955
- }
16956
- async function findTargetDirectories(searchPath, packmindCliHexa) {
16957
- const targets = [];
16958
- const exists = await packmindCliHexa.configExists(searchPath);
16959
- if (exists) {
16960
- targets.push(searchPath);
16961
- }
16962
- const descendants = await packmindCliHexa.findDescendantConfigs(searchPath);
16963
- for (const dir of descendants) {
16964
- if (!targets.includes(dir)) {
16965
- targets.push(dir);
16966
- }
16967
- }
16968
- if (targets.length === 0) {
16969
- let currentDir = nodePath.dirname(searchPath);
16970
- while (true) {
16971
- const ancestorExists = await packmindCliHexa.configExists(currentDir);
16972
- if (ancestorExists) {
16973
- targets.push(currentDir);
16974
- break;
16975
- }
16976
- const parentDir = nodePath.dirname(currentDir);
16977
- if (parentDir === currentDir) {
16978
- break;
16979
- }
16980
- currentDir = parentDir;
16981
- }
16982
- }
16983
- return targets;
16984
- }
16985
- function computeRelativePath(targetAbsDir, gitRoot) {
16986
- const rel = nodePath.relative(gitRoot, targetAbsDir);
16987
- if (rel.startsWith("..")) return "/";
16988
- return rel ? `/${rel}/` : "/";
16989
- }
16990
- async function collectGitInfo(deps) {
16991
- const { packmindCliHexa, exit, getCwd } = deps;
16992
- const cwd = getCwd();
16993
- let gitRemoteUrl;
16994
- let gitBranch;
16995
- const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
16996
- if (gitRoot) {
16997
- try {
16998
- gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
16999
- gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
17000
- } catch (err) {
17001
- logWarningConsole(
17002
- `Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
17003
- );
17004
- }
17005
- }
17006
- if (!gitRemoteUrl || !gitBranch || !gitRoot) {
17007
- logErrorConsole(
17008
- "Could not determine git repository info. The diff command requires a git repository with a remote configured."
17009
- );
17010
- exit(1);
17011
- return null;
17012
- }
17013
- return { gitRemoteUrl, gitBranch, gitRoot };
17014
- }
17015
- function extractUniqueAndSortedArtefacts(groups) {
17016
- const typeSortOrder = {
17017
- command: 0,
17018
- skill: 1,
17019
- standard: 2
17020
- };
17021
- const uniqueArtefacts = /* @__PURE__ */ new Map();
17022
- for (const [key, groupDiffs] of groups) {
17023
- if (!uniqueArtefacts.has(key)) {
17024
- uniqueArtefacts.set(key, {
17025
- type: groupDiffs[0].artifactType,
17026
- name: groupDiffs[0].artifactName
17027
- });
17028
- }
17029
- }
17030
- const sortedArtefacts = Array.from(uniqueArtefacts.values()).sort(
17031
- (a, b) => typeSortOrder[a.type] - typeSortOrder[b.type] || a.name.localeCompare(b.name, void 0, { sensitivity: "base" })
17032
- );
17033
- return sortedArtefacts;
17034
- }
17035
- function displayDiffs(params) {
17036
- const {
17037
- diffsToDisplay,
17038
- displayPathMap,
17039
- submittedLookup,
17040
- includeSubmitted,
17041
- unsubmittedItems,
17042
- submittedItems,
17043
- log
17044
- } = params;
17045
- log(formatHeader(`
17046
- Changes found:
17047
- `));
17048
- const groups = groupDiffsByArtefact(diffsToDisplay);
17049
- for (const [, groupDiffs] of groups) {
17050
- const { artifactType, artifactName } = groupDiffs[0];
17051
- const typeLabel = ARTIFACT_TYPE_LABELS[artifactType];
17052
- log(formatBold(`${typeLabel} "${artifactName}"`));
17053
- const subGroups = subGroupByChangeContent(groupDiffs);
17054
- for (const subGroup of subGroups) {
17055
- for (const diff of subGroup) {
17056
- log(` ${formatFilePath(displayPathMap.get(diff) ?? diff.filePath)}`);
17057
- }
17058
- const label = CHANGE_PROPOSAL_TYPE_LABELS[subGroup[0].type] ?? "content changed";
17059
- const checkItem = submittedLookup.get(subGroup[0]);
17060
- if (includeSubmitted && checkItem?.exists && checkItem.createdAt) {
17061
- const dateStr = formatSubmittedDate(checkItem.createdAt);
17062
- const messageSuffix = checkItem.message ? ` "${checkItem.message.length > 50 ? checkItem.message.slice(0, 50) + "..." : checkItem.message}"` : "";
17063
- log(
17064
- ` - ${label} ${source_default.dim(`[already submitted on ${dateStr}${messageSuffix}]`)}`
17065
- );
17066
- } else {
17067
- log(` - ${label}`);
17068
- }
17069
- formatDiffPayload(subGroup[0], log);
17070
- }
17071
- log("");
17072
- }
17073
- const changeCount = diffsToDisplay.length;
17074
- const changeWord = changeCount === 1 ? "change" : "changes";
17075
- const sortedArtefacts = extractUniqueAndSortedArtefacts(groups);
17076
- const artefactCount = sortedArtefacts.length;
17077
- const artefactWord = artefactCount === 1 ? "artefact" : "artefacts";
17078
- const allSubmittedSuffix = includeSubmitted && unsubmittedItems.length === 0 ? " (all already submitted)" : "";
17079
- logWarningConsole(
17080
- `Summary: ${changeCount} ${changeWord} found on ${artefactCount} ${artefactWord}${allSubmittedSuffix}:`
17081
- );
17082
- for (const artefact of sortedArtefacts) {
17083
- const typeLabel = ARTIFACT_TYPE_LABELS[artefact.type];
17084
- const key = `${artefact.type}:${artefact.name}`;
17085
- const artefactDiffs = groups.get(key) ?? [];
17086
- const allDiffsSubmitted = includeSubmitted && artefactDiffs.length > 0 && artefactDiffs.every((d) => submittedLookup.get(d)?.exists);
17087
- const suffix = allDiffsSubmitted ? " (all already submitted)" : "";
17088
- logWarningConsole(`* ${typeLabel} "${artefact.name}"${suffix}`);
17089
- }
17090
- if (!includeSubmitted && submittedItems.length > 0) {
17091
- logInfoConsole(buildSubmittedFooter(submittedItems));
17092
- }
17093
- return changeCount;
17094
- }
17095
- async function diffArtefactsHandler(deps) {
17096
- const { packmindCliHexa, exit, getCwd, log, includeSubmitted } = deps;
17097
- const cwd = getCwd();
17098
- const searchPath = nodePath.resolve(cwd, deps.path ?? ".");
17099
- if (deps.path !== void 0) {
17100
- try {
17101
- await fs24.stat(searchPath);
17102
- } catch {
17103
- logErrorConsole(`Path does not exist: ${searchPath}`);
17104
- exit(1);
17105
- return { diffsFound: 0 };
17106
- }
17107
- }
17108
- let targetDirs;
17109
- try {
17110
- targetDirs = await findTargetDirectories(searchPath, packmindCliHexa);
17111
- } catch (err) {
17112
- logErrorConsole(
17113
- `Failed to discover target directories: ${err instanceof Error ? err.message : String(err)}`
17114
- );
17115
- exit(1);
17116
- return { diffsFound: 0 };
17117
- }
17118
- if (targetDirs.length === 0) {
17119
- const hierarchicalConfig = await packmindCliHexa.readHierarchicalConfig(
17120
- cwd,
17121
- null
17122
- );
17123
- if (!hierarchicalConfig.hasConfigs) {
17124
- logErrorConsole(
17125
- "Not inside a Packmind project. No packmind.json found in the current directory or any parent directory."
17126
- );
17127
- exit(1);
17128
- } else {
17129
- log("No Packmind targets found under the current directory.");
17130
- exit(0);
17131
- }
17132
- return { diffsFound: 0 };
17133
- }
17134
- try {
17135
- const gitInfo = await collectGitInfo(deps);
17136
- if (!gitInfo) {
17137
- return { diffsFound: 0 };
17138
- }
17139
- const { gitRemoteUrl, gitBranch, gitRoot } = gitInfo;
17140
- const targetResults = [];
17141
- for (const targetDir of targetDirs) {
17142
- const config = await packmindCliHexa.readFullConfig(targetDir);
17143
- if (!config) continue;
17144
- const configPackages = Object.keys(config.packages);
17145
- if (configPackages.length === 0) continue;
17146
- const relativePath = computeRelativePath(targetDir, gitRoot);
17147
- const targetRelativePath = nodePath.relative(cwd, targetDir);
17148
- if (targetDirs.length > 1) {
17149
- log("");
17150
- logInfoConsole(`Target: ${targetRelativePath}`);
17151
- }
17152
- const packageCount = configPackages.length;
17153
- const packageWord = packageCount === 1 ? "package" : "packages";
17154
- logInfoConsole(
17155
- `Comparing ${packageCount} ${packageWord}: ${configPackages.join(", ")}...`
17156
- );
17157
- const diffs = await packmindCliHexa.diffArtefacts({
17158
- baseDirectory: targetDir,
17159
- packagesSlugs: configPackages,
17160
- gitRemoteUrl,
17161
- gitBranch,
17162
- relativePath,
17163
- agents: config.agents
17164
- });
17165
- const filterPrefix = nodePath.relative(targetDir, searchPath);
17166
- const filteredDiffs = filterPrefix !== "" && !filterPrefix.startsWith("..") ? diffs.filter(
17167
- (d) => d.filePath === filterPrefix || d.filePath.startsWith(filterPrefix + "/")
17168
- ) : diffs;
17169
- targetResults.push({ targetRelativePath, diffs: filteredDiffs });
17170
- }
17171
- if (targetResults.length === 0) {
17172
- log("No packages configured in any target.");
17173
- exit(0);
17174
- return { diffsFound: 0 };
17175
- }
17176
- const displayPathMap = /* @__PURE__ */ new Map();
17177
- for (const { targetRelativePath, diffs } of targetResults) {
17178
- for (const diff of diffs) {
17179
- displayPathMap.set(
17180
- diff,
17181
- targetRelativePath ? `${targetRelativePath}/${diff.filePath}` : diff.filePath
17182
- );
17183
- }
17184
- }
17185
- const allDiffs = targetResults.flatMap((r) => r.diffs);
17186
- if (allDiffs.length === 0) {
17187
- log("No changes found.");
17188
- exit(0);
17189
- return { diffsFound: 0 };
17190
- }
17191
- const allGroupedDiffs = Array.from(groupDiffsByArtefact(allDiffs).values());
17192
- const checkResult = await packmindCliHexa.checkDiffs(allGroupedDiffs);
17193
- const submittedItems = checkResult.results.filter((r) => r.exists);
17194
- const unsubmittedItems = checkResult.results.filter((r) => !r.exists);
17195
- const diffsToDisplay = includeSubmitted ? allDiffs : unsubmittedItems.map((r) => r.diff);
17196
- const submittedLookup = /* @__PURE__ */ new Map();
17197
- for (const item of checkResult.results) {
17198
- submittedLookup.set(item.diff, item);
17199
- }
17200
- if (diffsToDisplay.length === 0) {
17201
- log("No new changes found.");
17202
- if (submittedItems.length > 0) {
17203
- logInfoConsole(buildSubmittedFooter(submittedItems));
17204
- }
17205
- exit(0);
17206
- return { diffsFound: 0 };
17207
- }
17208
- const changeCount = displayDiffs({
17209
- diffsToDisplay,
17210
- displayPathMap,
17211
- submittedLookup,
17212
- includeSubmitted,
17213
- unsubmittedItems,
17214
- submittedItems,
17215
- log
17216
- });
17217
- exit(0);
17218
- return { diffsFound: changeCount };
17219
- } catch (err) {
17220
- if (err instanceof Error) {
17221
- logErrorConsole(err.message);
17222
- } else {
17223
- logErrorConsole(String(err));
17224
- }
17225
- exit(1);
17226
- return { diffsFound: 0 };
17227
- }
17228
- }
17094
+ };
17229
17095
 
17230
- // apps/cli/src/infra/commands/DiffCommand.ts
17231
- var diffCommand = (0, import_cmd_ts18.command)({
17232
- name: "diff",
17233
- description: "[Deprecated] Use `playbook diff` commands instead. Run for migration guidance",
17234
- args: {
17235
- submit: (0, import_cmd_ts18.flag)({
17236
- long: "submit",
17237
- description: "Submit detected changes as change proposals"
17238
- }),
17239
- includeSubmitted: (0, import_cmd_ts18.flag)({
17240
- long: "include-submitted",
17241
- description: "Include already submitted changes in the output"
17242
- }),
17243
- message: (0, import_cmd_ts18.option)({
17244
- long: "message",
17245
- short: "m",
17246
- description: "Message describing the intent behind the changes (max 1024 chars)",
17247
- type: (0, import_cmd_ts18.optional)(import_cmd_ts18.string)
17248
- }),
17249
- path: (0, import_cmd_ts18.option)({
17250
- long: "path",
17251
- short: "p",
17252
- description: "Path to analyze (relative to current directory)",
17253
- type: (0, import_cmd_ts18.optional)(import_cmd_ts18.string)
17254
- }),
17255
- positionals: (0, import_cmd_ts18.restPositionals)({
17256
- type: import_cmd_ts18.string,
17257
- displayName: "args",
17258
- description: "Subcommand and arguments (e.g., add <path>, remove <path>)"
17259
- })
17260
- },
17261
- handler: async ({ submit, includeSubmitted, message, path: path37, positionals }) => {
17262
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
17263
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
17264
- if (submit) {
17265
- logErrorConsole(
17266
- "Deprecated: `packmind-cli diff --submit` has been removed"
17267
- );
17268
- logInfoConsole("Use the following command instead:");
17269
- let submitCommand = `packmind-cli playbook submit`;
17270
- if (message) {
17271
- submitCommand = `${submitCommand} -m "${message}"`;
17272
- }
17273
- logInfoConsole(` ${formatCommand(submitCommand)}`);
17274
- process.exit(1);
17275
- }
17276
- if (positionals[0] === "add") {
17277
- const addFilePath = path37 && positionals[1] ? `${path37}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
17278
- const addCommand = `packmind-cli playbook add ${addFilePath}`;
17279
- logErrorConsole("Deprecated: `packmind-cli diff add` has been removed");
17280
- logInfoConsole("Use the following command instead:");
17281
- logInfoConsole(` ${formatCommand(addCommand)}`);
17282
- process.exit(1);
17283
- }
17284
- if (positionals[0] === "remove" || positionals[0] === "rm") {
17285
- const removeFilePath = path37 && positionals[1] ? `${path37}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
17286
- const removeCommand = `packmind-cli playbook remove ${removeFilePath}`;
17287
- logErrorConsole(
17288
- "Deprecated: `packmind-cli diff remove` has been removed"
17289
- );
17290
- logInfoConsole("Use the following command instead:");
17291
- logInfoConsole(` ${formatCommand(removeCommand)}`);
17292
- process.exit(1);
17293
- }
17294
- const diffCommand3 = `packmind-cli playbook diff${includeSubmitted ? " --include-submitted" : ""}${path37 ? ` --path ${path37}` : ""}`;
17295
- logErrorConsole("Deprecated: `packmind-cli diff` will be removed");
17296
- logInfoConsole("Use the following command instead:");
17297
- logInfoConsole(` ${formatCommand(diffCommand3)}`);
17298
- await diffArtefactsHandler({
17299
- packmindCliHexa,
17300
- exit: process.exit,
17301
- getCwd: () => process.cwd(),
17302
- log: console.log,
17303
- includeSubmitted,
17304
- path: path37
17305
- });
17306
- }
17096
+ // apps/cli/src/infra/commands/sharedOptions.ts
17097
+ var import_cmd_ts14 = __toESM(require_cjs());
17098
+ var originSkillOption = (0, import_cmd_ts14.option)({
17099
+ long: "origin-skill",
17100
+ description: "Name of the skill that triggered this command",
17101
+ type: (0, import_cmd_ts14.optional)(import_cmd_ts14.string)
17307
17102
  });
17308
17103
 
17309
- // apps/cli/src/infra/commands/PackagesCommand.ts
17310
- var import_cmd_ts23 = __toESM(require_cjs());
17311
-
17312
17104
  // apps/cli/src/infra/commands/CreatePackageCommand.ts
17313
- var import_cmd_ts19 = __toESM(require_cjs());
17314
-
17315
- // apps/cli/src/infra/commands/packages/createPackageHandler.ts
17316
- function toExpectedSlug(name) {
17317
- return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
17318
- }
17319
- function buildWebappUrl(host, orgSlug, spaceSlug, packageId) {
17320
- return `${host}/org/${orgSlug}/space/${spaceSlug}/packages/${packageId}`;
17321
- }
17322
- async function createPackageHandler(name, description, useCase, originSkill, spaceSlug) {
17323
- const trimmedName = name.trim();
17324
- if (!trimmedName) {
17325
- return { success: false, error: "Package name is required" };
17326
- }
17327
- try {
17328
- const result = await useCase.execute({
17329
- name: trimmedName,
17330
- description,
17331
- originSkill,
17332
- spaceSlug
17333
- });
17334
- let webappUrl;
17335
- const apiKey = loadApiKey();
17336
- if (apiKey) {
17337
- const decoded = decodeApiKey(apiKey);
17338
- if (decoded?.host && decoded?.jwt?.organization?.slug) {
17339
- webappUrl = buildWebappUrl(
17340
- decoded.host,
17341
- decoded.jwt.organization.slug,
17342
- result.spaceSlug,
17343
- result.packageId
17344
- );
17345
- }
17346
- }
17347
- const deduplicated = result.slug !== toExpectedSlug(trimmedName);
17348
- return {
17349
- success: true,
17350
- slug: `@${result.spaceSlug}/${result.slug}`,
17351
- packageName: result.name,
17352
- packageId: result.packageId,
17353
- webappUrl,
17354
- deduplicated
17355
- };
17356
- } catch (e) {
17357
- return {
17358
- success: false,
17359
- error: e instanceof Error ? e.message : "Unknown error"
17360
- };
17361
- }
17362
- }
17363
-
17364
- // apps/cli/src/application/useCases/CreatePackageUseCase.ts
17365
- var CreatePackageUseCase = class {
17366
- constructor(gateway, spaceService) {
17367
- this.gateway = gateway;
17368
- this.spaceService = spaceService;
17369
- }
17370
- async execute(command34) {
17371
- const space = await this.getSpace(command34);
17372
- const result = await this.gateway.packages.create({
17373
- spaceId: space.id,
17374
- name: command34.name,
17375
- description: command34.description ?? "",
17376
- recipeIds: [],
17377
- standardIds: [],
17378
- originSkill: command34.originSkill
17379
- });
17380
- return {
17381
- packageId: result.package.id,
17382
- name: result.package.name,
17383
- slug: result.package.slug,
17384
- spaceSlug: space.slug
17385
- };
17386
- }
17387
- async getSpace(command34) {
17388
- const spaces = await this.spaceService.getSpaces();
17389
- if (command34.spaceSlug) {
17390
- const found = spaces.find((s) => s.slug === command34.spaceSlug);
17391
- if (!found) {
17392
- throw new Error(`Space '${command34.spaceSlug}' not found.`);
17393
- }
17394
- return found;
17395
- }
17396
- if (spaces.length > 1) {
17397
- const spaceList = spaces.map((s) => ` - ${s.name} (--space ${s.slug})`).join("\n");
17398
- throw new Error(
17399
- `Your organization has multiple spaces. Please specify one using the --space option.
17400
-
17401
- Available spaces:
17402
- ${spaceList}`
17403
- );
17404
- }
17405
- return spaces[0];
17406
- }
17407
- };
17408
-
17409
- // apps/cli/src/infra/commands/CreatePackageCommand.ts
17410
- var createPackageCommand = (0, import_cmd_ts19.command)({
17105
+ var createPackageCommand = (0, import_cmd_ts15.command)({
17411
17106
  name: "create",
17412
17107
  description: "Create a new package",
17413
17108
  args: {
17414
- name: (0, import_cmd_ts19.positional)({
17109
+ name: (0, import_cmd_ts15.positional)({
17415
17110
  displayName: "name",
17416
17111
  description: "Name of the package to create",
17417
- type: import_cmd_ts19.string
17112
+ type: import_cmd_ts15.string
17418
17113
  }),
17419
- description: (0, import_cmd_ts19.option)({
17114
+ description: (0, import_cmd_ts15.option)({
17420
17115
  long: "description",
17421
17116
  short: "d",
17422
17117
  description: "Description of the package (optional)",
17423
- type: (0, import_cmd_ts19.optional)(import_cmd_ts19.string)
17118
+ type: (0, import_cmd_ts15.optional)(import_cmd_ts15.string)
17424
17119
  }),
17425
- space: (0, import_cmd_ts19.option)({
17120
+ space: (0, import_cmd_ts15.option)({
17426
17121
  long: "space",
17427
17122
  description: "Slug of the space in which to create the package",
17428
- type: (0, import_cmd_ts19.optional)(SpaceSlug)
17123
+ type: (0, import_cmd_ts15.optional)(SpaceSlug)
17429
17124
  }),
17430
17125
  originSkill: originSkillOption
17431
17126
  },
@@ -17479,7 +17174,7 @@ var createPackageCommand = (0, import_cmd_ts19.command)({
17479
17174
  });
17480
17175
 
17481
17176
  // apps/cli/src/infra/commands/AddToPackageCommand.ts
17482
- var import_cmd_ts20 = __toESM(require_cjs());
17177
+ var import_cmd_ts16 = __toESM(require_cjs());
17483
17178
 
17484
17179
  // apps/cli/src/domain/errors/ItemNotFoundError.ts
17485
17180
  var ItemNotFoundError = class extends Error {
@@ -17499,8 +17194,8 @@ var AddToPackageUseCase = class {
17499
17194
  this.gateway = gateway;
17500
17195
  this.spaceService = spaceService;
17501
17196
  }
17502
- async execute(command34) {
17503
- const { packageSlug, spaceSlug, itemType, itemSlugs } = command34;
17197
+ async execute(command31) {
17198
+ const { packageSlug, spaceSlug, itemType, itemSlugs } = command31;
17504
17199
  const space = spaceSlug ? await this.resolveSpaceBySlug(spaceSlug) : await this.spaceService.getDefaultSpace();
17505
17200
  const packages = await this.gateway.packages.list({
17506
17201
  spaceId: space.id
@@ -17521,12 +17216,12 @@ var AddToPackageUseCase = class {
17521
17216
  standardIds: [],
17522
17217
  recipeIds: [],
17523
17218
  skillIds: [],
17524
- originSkill: command34.originSkill
17219
+ originSkill: command31.originSkill
17525
17220
  };
17526
17221
  if (itemType === "standard") {
17527
17222
  addCommand.standardIds = ids.map(createStandardId);
17528
17223
  } else if (itemType === "command") {
17529
- addCommand.recipeIds = ids.map(createRecipeId);
17224
+ addCommand.recipeIds = ids.map(createCommandId);
17530
17225
  } else if (itemType === "skill") {
17531
17226
  addCommand.skillIds = ids.map(createSkillId);
17532
17227
  }
@@ -17573,7 +17268,7 @@ var AddToPackageUseCase = class {
17573
17268
  }
17574
17269
  async findCommandBySlug(slug6, spaceId) {
17575
17270
  const commands = await this.gateway.commands.list({ spaceId });
17576
- return commands.recipes.find((command34) => command34.slug === slug6) ?? null;
17271
+ return commands.recipes.find((command31) => command31.slug === slug6) ?? null;
17577
17272
  }
17578
17273
  async findSkillBySlug(slug6, spaceId) {
17579
17274
  const skills = await this.gateway.skills.list({ spaceId });
@@ -17649,11 +17344,11 @@ async function executeAddToPackage(pkgSlug, spaceSlug, itemType, itemSlugs, useC
17649
17344
  logErrorConsole(message);
17650
17345
  if (error instanceof ItemNotFoundError) {
17651
17346
  const spaceFlag = error.spaceSlug ? ` --space ${error.spaceSlug}` : "";
17652
- const command34 = formatCommand(
17347
+ const command31 = formatCommand(
17653
17348
  `packmind-cli ${error.itemType}s list${spaceFlag}`
17654
17349
  );
17655
17350
  logInfoConsole(
17656
- `Run \`${command34}\` to display available ${error.itemType}s`
17351
+ `Run \`${command31}\` to display available ${error.itemType}s`
17657
17352
  );
17658
17353
  }
17659
17354
  return { success: false, error: message };
@@ -17683,29 +17378,29 @@ async function addToPackageHandler(args2, deps) {
17683
17378
  }
17684
17379
 
17685
17380
  // apps/cli/src/infra/commands/AddToPackageCommand.ts
17686
- var addToPackageCommand = (0, import_cmd_ts20.command)({
17381
+ var addToPackageCommand = (0, import_cmd_ts16.command)({
17687
17382
  name: "add",
17688
17383
  description: "Add standards, commands, or skills to a package",
17689
17384
  args: {
17690
- to: (0, import_cmd_ts20.option)({
17385
+ to: (0, import_cmd_ts16.option)({
17691
17386
  long: "to",
17692
17387
  description: "Target package slug (use @space/package format when multiple spaces exist)",
17693
17388
  type: PackageSlugArgType
17694
17389
  }),
17695
- standards: (0, import_cmd_ts20.multioption)({
17390
+ standards: (0, import_cmd_ts16.multioption)({
17696
17391
  long: "standard",
17697
17392
  description: "Standard slug(s) to add",
17698
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
17393
+ type: (0, import_cmd_ts16.array)(import_cmd_ts16.string)
17699
17394
  }),
17700
- commands: (0, import_cmd_ts20.multioption)({
17395
+ commands: (0, import_cmd_ts16.multioption)({
17701
17396
  long: "command",
17702
17397
  description: "Command slug(s) to add",
17703
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
17398
+ type: (0, import_cmd_ts16.array)(import_cmd_ts16.string)
17704
17399
  }),
17705
- skills: (0, import_cmd_ts20.multioption)({
17400
+ skills: (0, import_cmd_ts16.multioption)({
17706
17401
  long: "skill",
17707
17402
  description: "Skill slug(s) to add",
17708
- type: (0, import_cmd_ts20.array)(import_cmd_ts20.string)
17403
+ type: (0, import_cmd_ts16.array)(import_cmd_ts16.string)
17709
17404
  }),
17710
17405
  originSkill: originSkillOption
17711
17406
  },
@@ -17741,7 +17436,7 @@ var addToPackageCommand = (0, import_cmd_ts20.command)({
17741
17436
  });
17742
17437
 
17743
17438
  // apps/cli/src/infra/commands/listPackagesCommand.ts
17744
- var import_cmd_ts21 = __toESM(require_cjs());
17439
+ var import_cmd_ts17 = __toESM(require_cjs());
17745
17440
 
17746
17441
  // apps/cli/src/infra/commands/packages/listPackagesHandler.ts
17747
17442
  async function listPackagesHandler(args2, deps) {
@@ -17808,12 +17503,12 @@ ${availableSpaces}`
17808
17503
  }
17809
17504
 
17810
17505
  // apps/cli/src/infra/commands/listPackagesCommand.ts
17811
- var listPackagesCommand = (0, import_cmd_ts21.command)({
17506
+ var listPackagesCommand = (0, import_cmd_ts17.command)({
17812
17507
  name: "list",
17813
17508
  description: "List available packages",
17814
17509
  args: {
17815
- space: (0, import_cmd_ts21.option)({
17816
- type: (0, import_cmd_ts21.optional)(SpaceSlug),
17510
+ space: (0, import_cmd_ts17.option)({
17511
+ type: (0, import_cmd_ts17.optional)(SpaceSlug),
17817
17512
  long: "space",
17818
17513
  description: "Filter packages by space slug"
17819
17514
  })
@@ -17830,7 +17525,7 @@ var listPackagesCommand = (0, import_cmd_ts21.command)({
17830
17525
  });
17831
17526
 
17832
17527
  // apps/cli/src/infra/commands/packages/showPackageCommand.ts
17833
- var import_cmd_ts22 = __toESM(require_cjs());
17528
+ var import_cmd_ts18 = __toESM(require_cjs());
17834
17529
 
17835
17530
  // apps/cli/src/infra/commands/packages/showPackageHandler.ts
17836
17531
  function isNotFoundError(err) {
@@ -17907,22 +17602,14 @@ ${pkg.name} (${fullSlug}):
17907
17602
  if (pkg.standards && pkg.standards.length > 0) {
17908
17603
  logConsole("Standards:");
17909
17604
  pkg.standards.forEach((standard) => {
17910
- if (standard.summary) {
17911
- logConsole(` - ${standard.name}: ${standard.summary}`);
17912
- } else {
17913
- logConsole(` - ${standard.name}`);
17914
- }
17605
+ logConsole(` - ${standard.name}`);
17915
17606
  });
17916
17607
  logConsole("");
17917
17608
  }
17918
- if (pkg.recipes && pkg.recipes.length > 0) {
17609
+ if (pkg.commands && pkg.commands.length > 0) {
17919
17610
  logConsole("Commands:");
17920
- pkg.recipes.forEach((recipe) => {
17921
- if (recipe.summary) {
17922
- logConsole(` - ${recipe.name}: ${recipe.summary}`);
17923
- } else {
17924
- logConsole(` - ${recipe.name}`);
17925
- }
17611
+ pkg.commands.forEach((command31) => {
17612
+ logConsole(` - ${command31.name}`);
17926
17613
  });
17927
17614
  logConsole("");
17928
17615
  }
@@ -17950,11 +17637,11 @@ ${pkg.name} (${fullSlug}):
17950
17637
  }
17951
17638
 
17952
17639
  // apps/cli/src/infra/commands/packages/showPackageCommand.ts
17953
- var showPackageCommand = (0, import_cmd_ts22.command)({
17640
+ var showPackageCommand = (0, import_cmd_ts18.command)({
17954
17641
  name: "show",
17955
17642
  description: "Show details of a specific package",
17956
17643
  args: {
17957
- slug: (0, import_cmd_ts22.positional)({
17644
+ slug: (0, import_cmd_ts18.positional)({
17958
17645
  type: PackageSlugArgType,
17959
17646
  displayName: "package",
17960
17647
  description: "Package slug (e.g. backend or @my-space/backend)"
@@ -17968,7 +17655,7 @@ var showPackageCommand = (0, import_cmd_ts22.command)({
17968
17655
  });
17969
17656
 
17970
17657
  // apps/cli/src/infra/commands/PackagesCommand.ts
17971
- var packagesCommand = (0, import_cmd_ts23.subcommands)({
17658
+ var packagesCommand = (0, import_cmd_ts19.subcommands)({
17972
17659
  name: "packages",
17973
17660
  description: "Manage packages",
17974
17661
  cmds: {
@@ -17980,10 +17667,10 @@ var packagesCommand = (0, import_cmd_ts23.subcommands)({
17980
17667
  });
17981
17668
 
17982
17669
  // apps/cli/src/infra/commands/PluginsCommand.ts
17983
- var import_cmd_ts26 = __toESM(require_cjs());
17670
+ var import_cmd_ts22 = __toESM(require_cjs());
17984
17671
 
17985
17672
  // apps/cli/src/infra/commands/plugins/RenderPluginCommand.ts
17986
- var import_cmd_ts24 = __toESM(require_cjs());
17673
+ var import_cmd_ts20 = __toESM(require_cjs());
17987
17674
 
17988
17675
  // apps/cli/src/infra/commands/plugins/renderPluginHandler.ts
17989
17676
  var import_fs22 = require("fs");
@@ -18199,11 +17886,11 @@ async function confirmOverwrite(message) {
18199
17886
  }
18200
17887
 
18201
17888
  // apps/cli/src/infra/commands/plugins/RenderPluginCommand.ts
18202
- var renderPluginCommand = (0, import_cmd_ts24.command)({
17889
+ var renderPluginCommand = (0, import_cmd_ts20.command)({
18203
17890
  name: "render",
18204
17891
  description: "Render a Packmind package as a Claude plugin",
18205
17892
  args: {
18206
- packageSlug: (0, import_cmd_ts24.positional)({
17893
+ packageSlug: (0, import_cmd_ts20.positional)({
18207
17894
  type: PackageSlugArgType,
18208
17895
  displayName: "package-slug",
18209
17896
  description: "Package slug (e.g. security or @my-space/security)"
@@ -18227,7 +17914,7 @@ var renderPluginCommand = (0, import_cmd_ts24.command)({
18227
17914
  });
18228
17915
 
18229
17916
  // apps/cli/src/infra/commands/plugins/DeletePluginCommand.ts
18230
- var import_cmd_ts25 = __toESM(require_cjs());
17917
+ var import_cmd_ts21 = __toESM(require_cjs());
18231
17918
 
18232
17919
  // apps/cli/src/infra/commands/plugins/deletePluginHandler.ts
18233
17920
  var import_fs23 = require("fs");
@@ -18315,11 +18002,11 @@ async function trackDeletion(deps, packageSlug, gitRemoteUrl) {
18315
18002
  }
18316
18003
 
18317
18004
  // apps/cli/src/infra/commands/plugins/DeletePluginCommand.ts
18318
- var deletePluginCommand = (0, import_cmd_ts25.command)({
18005
+ var deletePluginCommand = (0, import_cmd_ts21.command)({
18319
18006
  name: "delete",
18320
18007
  description: "Delete a rendered Packmind plugin from this workspace",
18321
18008
  args: {
18322
- packageSlug: (0, import_cmd_ts25.positional)({
18009
+ packageSlug: (0, import_cmd_ts21.positional)({
18323
18010
  type: PackageSlugArgType,
18324
18011
  displayName: "package-slug",
18325
18012
  description: "Package slug (e.g. security or @my-space/security)"
@@ -18343,7 +18030,7 @@ var deletePluginCommand = (0, import_cmd_ts25.command)({
18343
18030
  });
18344
18031
 
18345
18032
  // apps/cli/src/infra/commands/PluginsCommand.ts
18346
- var pluginsCommand = (0, import_cmd_ts26.subcommands)({
18033
+ var pluginsCommand = (0, import_cmd_ts22.subcommands)({
18347
18034
  name: "plugins",
18348
18035
  description: "Render Packmind packages as Claude plugins",
18349
18036
  cmds: {
@@ -18353,15 +18040,15 @@ var pluginsCommand = (0, import_cmd_ts26.subcommands)({
18353
18040
  });
18354
18041
 
18355
18042
  // apps/cli/src/infra/commands/PlaybookCommand.ts
18356
- var import_cmd_ts33 = __toESM(require_cjs());
18043
+ var import_cmd_ts29 = __toESM(require_cjs());
18357
18044
 
18358
18045
  // apps/cli/src/infra/commands/playbook/AddCommand.ts
18359
18046
  var import_fs24 = require("fs");
18360
- var import_cmd_ts27 = __toESM(require_cjs());
18047
+ var import_cmd_ts23 = __toESM(require_cjs());
18361
18048
 
18362
18049
  // apps/cli/src/infra/repositories/PlaybookLocalRepository.ts
18363
18050
  var crypto = __toESM(require("crypto"));
18364
- var fs25 = __toESM(require("fs"));
18051
+ var fs24 = __toESM(require("fs"));
18365
18052
  var os5 = __toESM(require("os"));
18366
18053
  var path25 = __toESM(require("path"));
18367
18054
  var yaml = __toESM(require("yaml"));
@@ -18417,11 +18104,11 @@ var PlaybookLocalRepository = class {
18417
18104
  return normalized;
18418
18105
  }
18419
18106
  readYaml() {
18420
- if (!fs25.existsSync(this.storagePath)) {
18107
+ if (!fs24.existsSync(this.storagePath)) {
18421
18108
  return { version: 1, changes: [] };
18422
18109
  }
18423
18110
  try {
18424
- const content = fs25.readFileSync(this.storagePath, "utf-8");
18111
+ const content = fs24.readFileSync(this.storagePath, "utf-8");
18425
18112
  const parsed = yaml.parse(content);
18426
18113
  if (!parsed || !Array.isArray(parsed.changes)) {
18427
18114
  return { version: 1, changes: [] };
@@ -18436,13 +18123,13 @@ var PlaybookLocalRepository = class {
18436
18123
  }
18437
18124
  writeYaml(data) {
18438
18125
  const dir = path25.dirname(this.storagePath);
18439
- fs25.mkdirSync(dir, { recursive: true });
18440
- fs25.writeFileSync(this.storagePath, yaml.stringify(data), "utf-8");
18126
+ fs24.mkdirSync(dir, { recursive: true });
18127
+ fs24.writeFileSync(this.storagePath, yaml.stringify(data), "utf-8");
18441
18128
  }
18442
18129
  };
18443
18130
 
18444
18131
  // apps/cli/src/infra/commands/playbook/addHandler.ts
18445
- var fs26 = __toESM(require("fs"));
18132
+ var fs25 = __toESM(require("fs"));
18446
18133
  var path29 = __toESM(require("path"));
18447
18134
  var yaml2 = __toESM(require("yaml"));
18448
18135
 
@@ -18591,8 +18278,35 @@ function parseLenientStandard(content) {
18591
18278
  return { name, description, rules };
18592
18279
  }
18593
18280
 
18281
+ // packages/skills/src/application/errors/SkillValidationError.ts
18282
+ var SkillValidationError = class _SkillValidationError extends Error {
18283
+ constructor(errors) {
18284
+ const messages = errors.map((e) => e.message).join("; ");
18285
+ super(`Skill validation failed: ${messages}`);
18286
+ this.name = "SkillValidationError";
18287
+ this.errors = errors;
18288
+ Object.setPrototypeOf(this, _SkillValidationError.prototype);
18289
+ }
18290
+ };
18291
+
18594
18292
  // packages/skills/src/application/validator/SkillValidator.ts
18595
18293
  var DESCRIPTION_MAX_LENGTH = 1024;
18294
+ var SKILL_FILE_MAX_CONTENT_LENGTH = 3e5;
18295
+ function validateSkillFileContent(content) {
18296
+ if (content.trim().length === 0) {
18297
+ throw new SkillValidationError([
18298
+ { field: "content", message: "File content cannot be empty" }
18299
+ ]);
18300
+ }
18301
+ if (content.length > SKILL_FILE_MAX_CONTENT_LENGTH) {
18302
+ throw new SkillValidationError([
18303
+ {
18304
+ field: "content",
18305
+ message: `File content exceeds the maximum length of ${SKILL_FILE_MAX_CONTENT_LENGTH} characters`
18306
+ }
18307
+ ]);
18308
+ }
18309
+ }
18596
18310
 
18597
18311
  // packages/skills/src/infra/schemas/SkillSchema.ts
18598
18312
  var import_typeorm2 = require("typeorm");
@@ -18821,15 +18535,18 @@ var import_uuid = require("uuid");
18821
18535
  // packages/skills/src/application/useCases/updateSkill/UpdateSkillUseCase.ts
18822
18536
  var import_slug2 = __toESM(require("slug"));
18823
18537
 
18538
+ // packages/skills/src/application/useCases/updateSkillFileFromUI/UpdateSkillFileFromUIUseCase.ts
18539
+ var import_uuid2 = require("uuid");
18540
+
18824
18541
  // packages/skills/src/application/useCases/uploadSkill/UploadSkillUseCase.ts
18825
18542
  var import_slug3 = __toESM(require("slug"));
18826
- var import_uuid2 = require("uuid");
18543
+ var import_uuid3 = require("uuid");
18827
18544
 
18828
18545
  // packages/skills/src/application/services/SkillService.ts
18829
- var import_uuid3 = require("uuid");
18546
+ var import_uuid4 = require("uuid");
18830
18547
 
18831
18548
  // packages/skills/src/application/services/SkillVersionService.ts
18832
- var import_uuid4 = require("uuid");
18549
+ var import_uuid5 = require("uuid");
18833
18550
 
18834
18551
  // apps/cli/src/application/utils/parseSkillDirectory.ts
18835
18552
  var SKILL_MD_FILENAME2 = "SKILL.md";
@@ -18870,11 +18587,32 @@ function parseSkillDirectory(files) {
18870
18587
  error: `Skill "${name.trim()}" has a description of ${trimmedDescription.length} characters, which exceeds the maximum of ${DESCRIPTION_MAX_LENGTH}. Edit the "description" field in SKILL.md and try again.`
18871
18588
  };
18872
18589
  }
18873
- if (body.trim().length === 0) {
18874
- return {
18875
- success: false,
18876
- error: "SKILL.md body (prompt) cannot be empty."
18877
- };
18590
+ try {
18591
+ validateSkillFileContent(body);
18592
+ } catch (error) {
18593
+ if (error instanceof SkillValidationError) {
18594
+ return {
18595
+ success: false,
18596
+ error: `SKILL.md body (prompt) is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18597
+ };
18598
+ }
18599
+ throw error;
18600
+ }
18601
+ const supportingMdFiles = files.filter(
18602
+ (f) => f.relativePath !== SKILL_MD_FILENAME2 && f.relativePath.endsWith(".md")
18603
+ );
18604
+ for (const mdFile of supportingMdFiles) {
18605
+ try {
18606
+ validateSkillFileContent(mdFile.content);
18607
+ } catch (error) {
18608
+ if (error instanceof SkillValidationError) {
18609
+ return {
18610
+ success: false,
18611
+ error: `File "${mdFile.relativePath}" is invalid: ${error.errors.map((e) => e.message).join("; ")}.`
18612
+ };
18613
+ }
18614
+ throw error;
18615
+ }
18878
18616
  }
18879
18617
  const payload = {
18880
18618
  name: name.trim(),
@@ -19103,7 +18841,7 @@ function resolveSkillDirectoryRoot(absolutePath) {
19103
18841
  return path29.dirname(absolutePath);
19104
18842
  }
19105
18843
  try {
19106
- if (fs26.statSync(absolutePath).isDirectory()) {
18844
+ if (fs25.statSync(absolutePath).isDirectory()) {
19107
18845
  return absolutePath;
19108
18846
  }
19109
18847
  } catch {
@@ -19112,7 +18850,7 @@ function resolveSkillDirectoryRoot(absolutePath) {
19112
18850
  let current = path29.dirname(absolutePath);
19113
18851
  const root = path29.parse(current).root;
19114
18852
  while (current !== root) {
19115
- if (fs26.existsSync(path29.join(current, "SKILL.md"))) {
18853
+ if (fs25.existsSync(path29.join(current, "SKILL.md"))) {
19116
18854
  return current;
19117
18855
  }
19118
18856
  current = path29.dirname(current);
@@ -19491,17 +19229,17 @@ function formatSpaceList(spaces) {
19491
19229
  }
19492
19230
 
19493
19231
  // apps/cli/src/infra/commands/playbook/AddCommand.ts
19494
- var addPlaybookCommand = (0, import_cmd_ts27.command)({
19232
+ var addPlaybookCommand = (0, import_cmd_ts23.command)({
19495
19233
  name: "add",
19496
19234
  description: "Stage a local artifact change",
19497
19235
  args: {
19498
- filePath: (0, import_cmd_ts27.positional)({
19499
- type: import_cmd_ts27.string,
19236
+ filePath: (0, import_cmd_ts23.positional)({
19237
+ type: import_cmd_ts23.string,
19500
19238
  displayName: "path",
19501
19239
  description: "Path to the artifact file or directory to stage"
19502
19240
  }),
19503
- space: (0, import_cmd_ts27.option)({
19504
- type: (0, import_cmd_ts27.optional)(SpaceSlug),
19241
+ space: (0, import_cmd_ts23.option)({
19242
+ type: (0, import_cmd_ts23.optional)(SpaceSlug),
19505
19243
  long: "space",
19506
19244
  description: "Target space slug"
19507
19245
  })
@@ -19530,10 +19268,10 @@ var addPlaybookCommand = (0, import_cmd_ts27.command)({
19530
19268
  });
19531
19269
 
19532
19270
  // apps/cli/src/infra/commands/playbook/RmCommand.ts
19533
- var import_cmd_ts28 = __toESM(require_cjs());
19271
+ var import_cmd_ts24 = __toESM(require_cjs());
19534
19272
 
19535
19273
  // apps/cli/src/infra/commands/playbook/rmHandler.ts
19536
- var fs27 = __toESM(require("fs"));
19274
+ var fs26 = __toESM(require("fs"));
19537
19275
  var path30 = __toESM(require("path"));
19538
19276
  function isSkillSupportFile(absolutePath) {
19539
19277
  const normalized = absolutePath.replace(/\\/g, "/");
@@ -19562,7 +19300,7 @@ async function playbookRmHandler(deps) {
19562
19300
  return;
19563
19301
  }
19564
19302
  const absolutePath = path30.resolve(getCwd(), filePath);
19565
- if (!fs27.existsSync(absolutePath)) {
19303
+ if (!fs26.existsSync(absolutePath)) {
19566
19304
  logErrorConsole(`File not found: "${filePath}"`);
19567
19305
  exit(1);
19568
19306
  return;
@@ -19661,13 +19399,13 @@ async function playbookRmHandler(deps) {
19661
19399
  }
19662
19400
 
19663
19401
  // apps/cli/src/infra/commands/playbook/RmCommand.ts
19664
- var rmPlaybookCommand = (0, import_cmd_ts28.command)({
19402
+ var rmPlaybookCommand = (0, import_cmd_ts24.command)({
19665
19403
  name: "rm",
19666
19404
  description: "Stage an artifact for removal",
19667
19405
  aliases: ["remove"],
19668
19406
  args: {
19669
- filePath: (0, import_cmd_ts28.positional)({
19670
- type: import_cmd_ts28.string,
19407
+ filePath: (0, import_cmd_ts24.positional)({
19408
+ type: import_cmd_ts24.string,
19671
19409
  displayName: "path",
19672
19410
  description: "Path to the artifact file or directory to remove"
19673
19411
  })
@@ -19693,7 +19431,7 @@ var rmPlaybookCommand = (0, import_cmd_ts28.command)({
19693
19431
  });
19694
19432
 
19695
19433
  // apps/cli/src/infra/commands/playbook/UnstageCommand.ts
19696
- var import_cmd_ts29 = __toESM(require_cjs());
19434
+ var import_cmd_ts25 = __toESM(require_cjs());
19697
19435
 
19698
19436
  // apps/cli/src/infra/commands/playbook/unstageHandler.ts
19699
19437
  var path31 = __toESM(require("path"));
@@ -19777,17 +19515,17 @@ ${spaceList}`
19777
19515
  }
19778
19516
 
19779
19517
  // apps/cli/src/infra/commands/playbook/UnstageCommand.ts
19780
- var unstagePlaybookCommand = (0, import_cmd_ts29.command)({
19518
+ var unstagePlaybookCommand = (0, import_cmd_ts25.command)({
19781
19519
  name: "unstage",
19782
19520
  description: "Remove a staged change",
19783
19521
  args: {
19784
- filePath: (0, import_cmd_ts29.positional)({
19785
- type: import_cmd_ts29.string,
19522
+ filePath: (0, import_cmd_ts25.positional)({
19523
+ type: import_cmd_ts25.string,
19786
19524
  displayName: "path",
19787
19525
  description: "Path to the artifact file or directory to unstage"
19788
19526
  }),
19789
- space: (0, import_cmd_ts29.option)({
19790
- type: (0, import_cmd_ts29.optional)(SpaceSlug),
19527
+ space: (0, import_cmd_ts25.option)({
19528
+ type: (0, import_cmd_ts25.optional)(SpaceSlug),
19791
19529
  long: "space",
19792
19530
  description: "Target space slug (required when artifact is staged for multiple spaces)"
19793
19531
  })
@@ -19813,7 +19551,7 @@ var unstagePlaybookCommand = (0, import_cmd_ts29.command)({
19813
19551
 
19814
19552
  // apps/cli/src/infra/commands/playbook/StatusCommand.ts
19815
19553
  var import_fs26 = require("fs");
19816
- var import_cmd_ts30 = __toESM(require_cjs());
19554
+ var import_cmd_ts26 = __toESM(require_cjs());
19817
19555
 
19818
19556
  // apps/cli/src/infra/utils/listDirectoryFiles.ts
19819
19557
  var import_fs25 = require("fs");
@@ -20096,7 +19834,7 @@ async function playbookStatusHandler(deps) {
20096
19834
  }
20097
19835
 
20098
19836
  // apps/cli/src/infra/commands/playbook/StatusCommand.ts
20099
- var statusPlaybookCommand = (0, import_cmd_ts30.command)({
19837
+ var statusPlaybookCommand = (0, import_cmd_ts26.command)({
20100
19838
  name: "status",
20101
19839
  description: "Show staged and untracked changes",
20102
19840
  args: {},
@@ -20130,7 +19868,7 @@ var statusPlaybookCommand = (0, import_cmd_ts30.command)({
20130
19868
 
20131
19869
  // apps/cli/src/infra/commands/playbook/SubmitCommand.ts
20132
19870
  var import_fs28 = require("fs");
20133
- var import_cmd_ts31 = __toESM(require_cjs());
19871
+ var import_cmd_ts27 = __toESM(require_cjs());
20134
19872
 
20135
19873
  // apps/cli/src/infra/commands/playbook/submitHandler.ts
20136
19874
  var path35 = __toESM(require("path"));
@@ -20913,6 +20651,31 @@ function logPackageAddGuidance(created, packageSlugs) {
20913
20651
  logInfoConsole(` Available packages: ${packageSlugs.join(", ")}`);
20914
20652
  }
20915
20653
  }
20654
+ async function logReviewUrls(packmindCliHexa, spaceIds) {
20655
+ if (spaceIds.length === 0) return;
20656
+ const buildUrl = resolveUrlBuilder(() => "review-changes/");
20657
+ try {
20658
+ const allSpaces = await packmindCliHexa.getSpaces();
20659
+ const spaceById = new Map(allSpaces.map((s) => [s.id, s]));
20660
+ const urls = [];
20661
+ for (const spaceId of spaceIds) {
20662
+ const spaceSlug = spaceById.get(spaceId)?.slug;
20663
+ if (!spaceSlug) continue;
20664
+ const url = buildUrl(spaceSlug, "");
20665
+ if (url) urls.push(url);
20666
+ }
20667
+ if (urls.length === 0) return;
20668
+ if (urls.length === 1) {
20669
+ logInfoConsole(`Review your change proposals at: ${urls[0]}`);
20670
+ } else {
20671
+ logInfoConsole("Review your change proposals at:");
20672
+ for (const url of urls) {
20673
+ logInfoConsole(` - ${url}`);
20674
+ }
20675
+ }
20676
+ } catch {
20677
+ }
20678
+ }
20916
20679
  async function logRemovedPackagesNotification(packmindCliHexa, packageIds) {
20917
20680
  if (packageIds.size === 0) return;
20918
20681
  try {
@@ -21273,171 +21036,606 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
21273
21036
  }
21274
21037
  }
21275
21038
  }
21276
- if (failedSpaces.length > 0) {
21277
- for (const { spaceId, errors } of failedSpaces) {
21278
- logErrorConsole(
21279
- `Failed to submit to space '${displaySpace2(spaceId)}': ${errors.join(", ")}`
21280
- );
21039
+ if (failedSpaces.length > 0) {
21040
+ for (const { spaceId, errors } of failedSpaces) {
21041
+ logErrorConsole(
21042
+ `Failed to submit to space '${displaySpace2(spaceId)}': ${errors.join(", ")}`
21043
+ );
21044
+ }
21045
+ if (succeededSpaces.length > 0) {
21046
+ logWarningConsole(
21047
+ `Submitted to: ${succeededSpaces.map(displaySpace2).join(", ")}. Run 'packmind playbook submit' again to retry failed spaces.`
21048
+ );
21049
+ }
21050
+ exit(1);
21051
+ return;
21052
+ }
21053
+ await logRemovedPackagesNotification(packmindCliHexa, removalPackageIds);
21054
+ const parts = [];
21055
+ if (totalCreated > 0) {
21056
+ parts.push(`${totalCreated} submitted`);
21057
+ }
21058
+ if (totalSkipped > 0) {
21059
+ parts.push(`${totalSkipped} skipped (already submitted)`);
21060
+ }
21061
+ if (totalCreated > 0 && totalSkipped === 0) {
21062
+ logSuccessConsole(
21063
+ `Submitted ${totalCreated} change proposal${totalCreated !== 1 ? "s" : ""}`
21064
+ );
21065
+ } else if (totalCreated === 0 && totalSkipped > 0) {
21066
+ logWarningConsole(
21067
+ `All proposals were already submitted (${totalSkipped} skipped)`
21068
+ );
21069
+ } else {
21070
+ logSuccessConsole(`Change proposals: ${parts.join(", ")}`);
21071
+ }
21072
+ if (totalCreated > 0) {
21073
+ await logReviewUrls(packmindCliHexa, succeededSpaces);
21074
+ }
21075
+ exit(0);
21076
+ }
21077
+
21078
+ // apps/cli/src/infra/utils/editorMessage.ts
21079
+ var import_child_process3 = require("child_process");
21080
+ var import_fs27 = require("fs");
21081
+ var import_os2 = require("os");
21082
+ var import_path8 = require("path");
21083
+
21084
+ // apps/cli/src/infra/utils/resolveEditor.ts
21085
+ var which = __toESM(require("which"));
21086
+ var EDITOR_NOT_FOUND_MESSAGE = 'No text editor found. Set the EDITOR environment variable to your preferred editor, or pass the message inline with -m "<message>".';
21087
+ var WINDOWS_CANDIDATES = ["notepad"];
21088
+ var UNIX_CANDIDATES = ["nano", "vim", "vi"];
21089
+ function isAvailable(cmd) {
21090
+ try {
21091
+ which.sync(cmd);
21092
+ return true;
21093
+ } catch {
21094
+ return false;
21095
+ }
21096
+ }
21097
+ function resolveEditor(platform = process.platform) {
21098
+ if (process.env.VISUAL) {
21099
+ return process.env.VISUAL;
21100
+ }
21101
+ if (process.env.EDITOR) {
21102
+ return process.env.EDITOR;
21103
+ }
21104
+ const candidates = platform === "win32" ? WINDOWS_CANDIDATES : UNIX_CANDIDATES;
21105
+ for (const candidate of candidates) {
21106
+ if (isAvailable(candidate)) {
21107
+ return candidate;
21108
+ }
21109
+ }
21110
+ throw new Error(EDITOR_NOT_FOUND_MESSAGE);
21111
+ }
21112
+
21113
+ // apps/cli/src/infra/utils/editorMessage.ts
21114
+ var EDITOR_TEMPLATE = `
21115
+ # Enter a message describing the intent behind these changes.
21116
+ # Lines starting with '#' will be ignored.
21117
+ # An empty message aborts the submission.
21118
+ `;
21119
+ function openEditorForMessage(prefill) {
21120
+ const editor = resolveEditor();
21121
+ const tmpFile = (0, import_path8.join)((0, import_os2.tmpdir)(), `packmind-msg-${Date.now()}.txt`);
21122
+ try {
21123
+ (0, import_fs27.writeFileSync)(tmpFile, prefill ?? EDITOR_TEMPLATE, "utf-8");
21124
+ const result = (0, import_child_process3.spawnSync)(editor, [tmpFile], {
21125
+ stdio: "inherit"
21126
+ });
21127
+ if (result.status !== 0) {
21128
+ throw new Error(`Editor exited with status ${result.status}`);
21129
+ }
21130
+ const content = (0, import_fs27.readFileSync)(tmpFile, "utf-8");
21131
+ return content.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
21132
+ } finally {
21133
+ try {
21134
+ (0, import_fs27.unlinkSync)(tmpFile);
21135
+ } catch {
21136
+ }
21137
+ }
21138
+ }
21139
+
21140
+ // apps/cli/src/infra/commands/playbook/safeOpenEditor.ts
21141
+ function safeOpenEditor(prefill) {
21142
+ try {
21143
+ const result = openEditorForMessage(prefill);
21144
+ return result.length > 0 ? result : null;
21145
+ } catch (error) {
21146
+ const message = error instanceof Error ? error.message : String(error);
21147
+ logErrorConsole(`Failed to open editor: ${message}`);
21148
+ return null;
21149
+ }
21150
+ }
21151
+
21152
+ // apps/cli/src/infra/commands/playbook/SubmitCommand.ts
21153
+ var submitPlaybookCommand = (0, import_cmd_ts27.command)({
21154
+ name: "submit",
21155
+ description: "Submit staged changes as proposals",
21156
+ args: {
21157
+ message: (0, import_cmd_ts27.option)({
21158
+ type: (0, import_cmd_ts27.optional)(import_cmd_ts27.string),
21159
+ long: "message",
21160
+ short: "m",
21161
+ description: "Message describing the intent behind the proposed changes"
21162
+ }),
21163
+ noReview: (0, import_cmd_ts27.flag)({
21164
+ long: "no-review",
21165
+ description: "Apply changes directly without creating proposals for review"
21166
+ })
21167
+ },
21168
+ handler: async ({ message, noReview }) => {
21169
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
21170
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
21171
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
21172
+ process.cwd()
21173
+ );
21174
+ const repoRoot = gitRoot ?? process.cwd();
21175
+ const playbookLocalRepository = new PlaybookLocalRepository(repoRoot);
21176
+ const lockFileRepository = new LockFileRepository();
21177
+ await playbookSubmitHandler({
21178
+ packmindCliHexa,
21179
+ playbookLocalRepository,
21180
+ lockFileRepository,
21181
+ cwd: process.cwd(),
21182
+ exit: process.exit,
21183
+ message,
21184
+ noReview,
21185
+ openEditor: safeOpenEditor,
21186
+ unlinkSync: (p) => (0, import_fs28.unlinkSync)(p),
21187
+ rmSync: (p, opts) => (0, import_fs28.rmSync)(p, opts)
21188
+ });
21189
+ }
21190
+ });
21191
+
21192
+ // apps/cli/src/infra/commands/playbook/DiffCommand.ts
21193
+ var import_cmd_ts28 = __toESM(require_cjs());
21194
+
21195
+ // apps/cli/src/infra/commands/playbook/diffArtefactsHandler.ts
21196
+ var nodePath = __toESM(require("path"));
21197
+ var fs27 = __toESM(require("fs/promises"));
21198
+
21199
+ // apps/cli/src/infra/utils/diffFormatter.ts
21200
+ var import_diff4 = require("diff");
21201
+ init_source();
21202
+ function formatContentDiff(oldContent, newContent) {
21203
+ const changes = (0, import_diff4.diffLines)(oldContent, newContent);
21204
+ const lines = [];
21205
+ for (const change of changes) {
21206
+ const trimmedValue = change.value.replace(/\n$/, "");
21207
+ const changeLines = trimmedValue.split("\n");
21208
+ if (change.added) {
21209
+ for (const line of changeLines) {
21210
+ lines.push(source_default.green(` + ${line}`));
21211
+ }
21212
+ } else if (change.removed) {
21213
+ for (const line of changeLines) {
21214
+ lines.push(source_default.red(` - ${line}`));
21215
+ }
21216
+ }
21217
+ }
21218
+ return {
21219
+ lines,
21220
+ hasChanges: lines.length > 0
21221
+ };
21222
+ }
21223
+
21224
+ // apps/cli/src/infra/commands/formatAdditionalPropertyDiff.ts
21225
+ function formatAdditionalPropertyDiff(targetId, oldValue, newValue) {
21226
+ const displayKey = CAMEL_TO_YAML_KEY[targetId] ?? camelToKebab(targetId);
21227
+ const lines = [];
21228
+ if (oldValue && oldValue !== "null") {
21229
+ lines.push({ type: "removed", text: `${displayKey}: ${oldValue}` });
21230
+ }
21231
+ if (newValue && newValue !== "null") {
21232
+ lines.push({ type: "added", text: `${displayKey}: ${newValue}` });
21233
+ }
21234
+ return lines;
21235
+ }
21236
+
21237
+ // apps/cli/src/infra/commands/playbook/diffArtefactsHandler.ts
21238
+ init_source();
21239
+ var ARTIFACT_TYPE_LABELS = {
21240
+ command: "Command",
21241
+ standard: "Standard",
21242
+ skill: "Skill"
21243
+ };
21244
+ function subGroupByChangeContent(diffs) {
21245
+ const groups = /* @__PURE__ */ new Map();
21246
+ for (const diff of diffs) {
21247
+ const key = JSON.stringify({ type: diff.type, payload: diff.payload });
21248
+ const group = groups.get(key) ?? [];
21249
+ group.push(diff);
21250
+ groups.set(key, group);
21251
+ }
21252
+ return Array.from(groups.values());
21253
+ }
21254
+ function groupDiffsByArtefact(diffs) {
21255
+ const groups = /* @__PURE__ */ new Map();
21256
+ for (const diff of diffs) {
21257
+ const key = `${diff.artifactType}:${diff.artifactName}`;
21258
+ const group = groups.get(key) ?? [];
21259
+ group.push(diff);
21260
+ groups.set(key, group);
21261
+ }
21262
+ return groups;
21263
+ }
21264
+ function formatDiffPayload(diff, log) {
21265
+ const payload = diff.payload;
21266
+ if (diff.type === "addSkillFile" /* addSkillFile */) {
21267
+ const item = payload.item;
21268
+ if (item.isBase64) {
21269
+ log(source_default.green(" + [binary file]"));
21270
+ } else {
21271
+ for (const line of item.content.split("\n")) {
21272
+ log(source_default.green(` + ${line}`));
21273
+ }
21274
+ }
21275
+ return;
21276
+ }
21277
+ if (diff.type === "deleteSkillFile" /* deleteSkillFile */) {
21278
+ const item = payload.item;
21279
+ if (item.isBase64) {
21280
+ log(source_default.red(" - [binary file]"));
21281
+ } else {
21282
+ const lines2 = item.content.split("\n");
21283
+ const MAX_DELETED_LINES = 3;
21284
+ const preview = lines2.slice(0, MAX_DELETED_LINES);
21285
+ for (const line of preview) {
21286
+ log(source_default.red(` - ${line}`));
21287
+ }
21288
+ if (lines2.length > MAX_DELETED_LINES) {
21289
+ const remaining = lines2.length - MAX_DELETED_LINES;
21290
+ log(source_default.red(` ... and ${remaining} more lines deleted`));
21291
+ }
21292
+ }
21293
+ return;
21294
+ }
21295
+ if (diff.type === "updateSkillFileContent" /* updateSkillFileContent */) {
21296
+ const typedPayload = payload;
21297
+ if (typedPayload.isBase64) {
21298
+ log(source_default.green(" ~ [binary content changed]"));
21299
+ return;
21281
21300
  }
21282
- if (succeededSpaces.length > 0) {
21283
- logWarningConsole(
21284
- `Submitted to: ${succeededSpaces.map(displaySpace2).join(", ")}. Run 'packmind playbook submit' again to retry failed spaces.`
21301
+ }
21302
+ if (diff.type === "addRule" /* addRule */) {
21303
+ const item = payload.item;
21304
+ log(source_default.green(` + ${item.content}`));
21305
+ return;
21306
+ }
21307
+ if (diff.type === "deleteRule" /* deleteRule */) {
21308
+ const item = payload.item;
21309
+ log(source_default.red(` - ${item.content}`));
21310
+ return;
21311
+ }
21312
+ if (diff.type === "updateSkillAdditionalProperty" /* updateSkillAdditionalProperty */) {
21313
+ const lines2 = formatAdditionalPropertyDiff(
21314
+ payload.targetId,
21315
+ payload.oldValue,
21316
+ payload.newValue
21317
+ );
21318
+ for (const line of lines2) {
21319
+ log(
21320
+ line.type === "removed" ? source_default.red(` - ${line.text}`) : source_default.green(` + ${line.text}`)
21285
21321
  );
21286
21322
  }
21287
- exit(1);
21288
21323
  return;
21289
21324
  }
21290
- await logRemovedPackagesNotification(packmindCliHexa, removalPackageIds);
21291
- const parts = [];
21292
- if (totalCreated > 0) {
21293
- parts.push(`${totalCreated} submitted`);
21325
+ const oldValue = payload.oldValue;
21326
+ const newValue = payload.newValue;
21327
+ const { lines } = formatContentDiff(oldValue, newValue);
21328
+ for (const line of lines) {
21329
+ log(line);
21294
21330
  }
21295
- if (totalSkipped > 0) {
21296
- parts.push(`${totalSkipped} skipped (already submitted)`);
21331
+ }
21332
+ function formatSubmittedDate(isoDate) {
21333
+ const date = new Date(isoDate);
21334
+ const datePart = date.toLocaleDateString("en-US", {
21335
+ year: "numeric",
21336
+ month: "short",
21337
+ day: "numeric"
21338
+ });
21339
+ const timePart = date.toLocaleTimeString("en-US", {
21340
+ hour: "numeric",
21341
+ minute: "2-digit",
21342
+ hour12: true
21343
+ });
21344
+ return `${datePart} ${timePart}`;
21345
+ }
21346
+ function buildSubmittedFooter(submittedDiffs) {
21347
+ const proposalCount = submittedDiffs.length;
21348
+ const proposalWord = proposalCount === 1 ? "change proposal" : "change proposals";
21349
+ return `${proposalCount} ${proposalWord} ignored, run \`packmind-cli diff --include-submitted\` to see what's waiting for validation`;
21350
+ }
21351
+ async function findTargetDirectories(searchPath, packmindCliHexa) {
21352
+ const targets = [];
21353
+ const exists = await packmindCliHexa.configExists(searchPath);
21354
+ if (exists) {
21355
+ targets.push(searchPath);
21297
21356
  }
21298
- if (totalCreated > 0 && totalSkipped === 0) {
21299
- logSuccessConsole(
21300
- `Submitted ${totalCreated} change proposal${totalCreated !== 1 ? "s" : ""}`
21301
- );
21302
- } else if (totalCreated === 0 && totalSkipped > 0) {
21303
- logWarningConsole(
21304
- `All proposals were already submitted (${totalSkipped} skipped)`
21305
- );
21306
- } else {
21307
- logSuccessConsole(`Change proposals: ${parts.join(", ")}`);
21357
+ const descendants = await packmindCliHexa.findDescendantConfigs(searchPath);
21358
+ for (const dir of descendants) {
21359
+ if (!targets.includes(dir)) {
21360
+ targets.push(dir);
21361
+ }
21308
21362
  }
21309
- exit(0);
21310
- }
21311
-
21312
- // apps/cli/src/infra/utils/editorMessage.ts
21313
- var import_child_process3 = require("child_process");
21314
- var import_fs27 = require("fs");
21315
- var import_os2 = require("os");
21316
- var import_path8 = require("path");
21317
-
21318
- // apps/cli/src/infra/utils/resolveEditor.ts
21319
- var which = __toESM(require("which"));
21320
- var EDITOR_NOT_FOUND_MESSAGE = 'No text editor found. Set the EDITOR environment variable to your preferred editor, or pass the message inline with -m "<message>".';
21321
- var WINDOWS_CANDIDATES = ["notepad"];
21322
- var UNIX_CANDIDATES = ["nano", "vim", "vi"];
21323
- function isAvailable(cmd) {
21324
- try {
21325
- which.sync(cmd);
21326
- return true;
21327
- } catch {
21328
- return false;
21363
+ if (targets.length === 0) {
21364
+ let currentDir = nodePath.dirname(searchPath);
21365
+ while (true) {
21366
+ const ancestorExists = await packmindCliHexa.configExists(currentDir);
21367
+ if (ancestorExists) {
21368
+ targets.push(currentDir);
21369
+ break;
21370
+ }
21371
+ const parentDir = nodePath.dirname(currentDir);
21372
+ if (parentDir === currentDir) {
21373
+ break;
21374
+ }
21375
+ currentDir = parentDir;
21376
+ }
21329
21377
  }
21378
+ return targets;
21330
21379
  }
21331
- function resolveEditor(platform = process.platform) {
21332
- if (process.env.VISUAL) {
21333
- return process.env.VISUAL;
21380
+ function computeRelativePath(targetAbsDir, gitRoot) {
21381
+ const rel = nodePath.relative(gitRoot, targetAbsDir);
21382
+ if (rel.startsWith("..")) return "/";
21383
+ return rel ? `/${rel}/` : "/";
21384
+ }
21385
+ async function collectGitInfo(deps) {
21386
+ const { packmindCliHexa, exit, getCwd } = deps;
21387
+ const cwd = getCwd();
21388
+ let gitRemoteUrl;
21389
+ let gitBranch;
21390
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
21391
+ if (gitRoot) {
21392
+ try {
21393
+ gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
21394
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
21395
+ } catch (err) {
21396
+ logWarningConsole(
21397
+ `Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
21398
+ );
21399
+ }
21334
21400
  }
21335
- if (process.env.EDITOR) {
21336
- return process.env.EDITOR;
21401
+ if (!gitRemoteUrl || !gitBranch || !gitRoot) {
21402
+ logErrorConsole(
21403
+ "Could not determine git repository info. The diff command requires a git repository with a remote configured."
21404
+ );
21405
+ exit(1);
21406
+ return null;
21337
21407
  }
21338
- const candidates = platform === "win32" ? WINDOWS_CANDIDATES : UNIX_CANDIDATES;
21339
- for (const candidate of candidates) {
21340
- if (isAvailable(candidate)) {
21341
- return candidate;
21408
+ return { gitRemoteUrl, gitBranch, gitRoot };
21409
+ }
21410
+ function extractUniqueAndSortedArtefacts(groups) {
21411
+ const typeSortOrder = {
21412
+ command: 0,
21413
+ skill: 1,
21414
+ standard: 2
21415
+ };
21416
+ const uniqueArtefacts = /* @__PURE__ */ new Map();
21417
+ for (const [key, groupDiffs] of groups) {
21418
+ if (!uniqueArtefacts.has(key)) {
21419
+ uniqueArtefacts.set(key, {
21420
+ type: groupDiffs[0].artifactType,
21421
+ name: groupDiffs[0].artifactName
21422
+ });
21342
21423
  }
21343
21424
  }
21344
- throw new Error(EDITOR_NOT_FOUND_MESSAGE);
21425
+ const sortedArtefacts = Array.from(uniqueArtefacts.values()).sort(
21426
+ (a, b) => typeSortOrder[a.type] - typeSortOrder[b.type] || a.name.localeCompare(b.name, void 0, { sensitivity: "base" })
21427
+ );
21428
+ return sortedArtefacts;
21345
21429
  }
21346
-
21347
- // apps/cli/src/infra/utils/editorMessage.ts
21348
- var EDITOR_TEMPLATE = `
21349
- # Enter a message describing the intent behind these changes.
21350
- # Lines starting with '#' will be ignored.
21351
- # An empty message aborts the submission.
21352
- `;
21353
- function openEditorForMessage(prefill) {
21354
- const editor = resolveEditor();
21355
- const tmpFile = (0, import_path8.join)((0, import_os2.tmpdir)(), `packmind-msg-${Date.now()}.txt`);
21356
- try {
21357
- (0, import_fs27.writeFileSync)(tmpFile, prefill ?? EDITOR_TEMPLATE, "utf-8");
21358
- const result = (0, import_child_process3.spawnSync)(editor, [tmpFile], {
21359
- stdio: "inherit"
21360
- });
21361
- if (result.status !== 0) {
21362
- throw new Error(`Editor exited with status ${result.status}`);
21430
+ function displayDiffs(params) {
21431
+ const {
21432
+ diffsToDisplay,
21433
+ displayPathMap,
21434
+ submittedLookup,
21435
+ includeSubmitted,
21436
+ unsubmittedItems,
21437
+ submittedItems,
21438
+ log
21439
+ } = params;
21440
+ log(formatHeader(`
21441
+ Changes found:
21442
+ `));
21443
+ const groups = groupDiffsByArtefact(diffsToDisplay);
21444
+ for (const [, groupDiffs] of groups) {
21445
+ const { artifactType, artifactName } = groupDiffs[0];
21446
+ const typeLabel = ARTIFACT_TYPE_LABELS[artifactType];
21447
+ log(formatBold(`${typeLabel} "${artifactName}"`));
21448
+ const subGroups = subGroupByChangeContent(groupDiffs);
21449
+ for (const subGroup of subGroups) {
21450
+ for (const diff of subGroup) {
21451
+ log(` ${formatFilePath(displayPathMap.get(diff) ?? diff.filePath)}`);
21452
+ }
21453
+ const label = CHANGE_PROPOSAL_TYPE_LABELS[subGroup[0].type] ?? "content changed";
21454
+ const checkItem = submittedLookup.get(subGroup[0]);
21455
+ if (includeSubmitted && checkItem?.exists && checkItem.createdAt) {
21456
+ const dateStr = formatSubmittedDate(checkItem.createdAt);
21457
+ const messageSuffix = checkItem.message ? ` "${checkItem.message.length > 50 ? checkItem.message.slice(0, 50) + "..." : checkItem.message}"` : "";
21458
+ log(
21459
+ ` - ${label} ${source_default.dim(`[already submitted on ${dateStr}${messageSuffix}]`)}`
21460
+ );
21461
+ } else {
21462
+ log(` - ${label}`);
21463
+ }
21464
+ formatDiffPayload(subGroup[0], log);
21363
21465
  }
21364
- const content = (0, import_fs27.readFileSync)(tmpFile, "utf-8");
21365
- return content.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
21366
- } finally {
21466
+ log("");
21467
+ }
21468
+ const changeCount = diffsToDisplay.length;
21469
+ const changeWord = changeCount === 1 ? "change" : "changes";
21470
+ const sortedArtefacts = extractUniqueAndSortedArtefacts(groups);
21471
+ const artefactCount = sortedArtefacts.length;
21472
+ const artefactWord = artefactCount === 1 ? "artefact" : "artefacts";
21473
+ const allSubmittedSuffix = includeSubmitted && unsubmittedItems.length === 0 ? " (all already submitted)" : "";
21474
+ logWarningConsole(
21475
+ `Summary: ${changeCount} ${changeWord} found on ${artefactCount} ${artefactWord}${allSubmittedSuffix}:`
21476
+ );
21477
+ for (const artefact of sortedArtefacts) {
21478
+ const typeLabel = ARTIFACT_TYPE_LABELS[artefact.type];
21479
+ const key = `${artefact.type}:${artefact.name}`;
21480
+ const artefactDiffs = groups.get(key) ?? [];
21481
+ const allDiffsSubmitted = includeSubmitted && artefactDiffs.length > 0 && artefactDiffs.every((d) => submittedLookup.get(d)?.exists);
21482
+ const suffix = allDiffsSubmitted ? " (all already submitted)" : "";
21483
+ logWarningConsole(`* ${typeLabel} "${artefact.name}"${suffix}`);
21484
+ }
21485
+ if (!includeSubmitted && submittedItems.length > 0) {
21486
+ logInfoConsole(buildSubmittedFooter(submittedItems));
21487
+ }
21488
+ return changeCount;
21489
+ }
21490
+ async function diffArtefactsHandler(deps) {
21491
+ const { packmindCliHexa, exit, getCwd, log, includeSubmitted } = deps;
21492
+ const cwd = getCwd();
21493
+ const searchPath = nodePath.resolve(cwd, deps.path ?? ".");
21494
+ if (deps.path !== void 0) {
21367
21495
  try {
21368
- (0, import_fs27.unlinkSync)(tmpFile);
21496
+ await fs27.stat(searchPath);
21369
21497
  } catch {
21498
+ logErrorConsole(`Path does not exist: ${searchPath}`);
21499
+ exit(1);
21500
+ return { diffsFound: 0 };
21370
21501
  }
21371
21502
  }
21372
- }
21373
-
21374
- // apps/cli/src/infra/commands/playbook/safeOpenEditor.ts
21375
- function safeOpenEditor(prefill) {
21503
+ let targetDirs;
21376
21504
  try {
21377
- const result = openEditorForMessage(prefill);
21378
- return result.length > 0 ? result : null;
21379
- } catch (error) {
21380
- const message = error instanceof Error ? error.message : String(error);
21381
- logErrorConsole(`Failed to open editor: ${message}`);
21382
- return null;
21505
+ targetDirs = await findTargetDirectories(searchPath, packmindCliHexa);
21506
+ } catch (err) {
21507
+ logErrorConsole(
21508
+ `Failed to discover target directories: ${err instanceof Error ? err.message : String(err)}`
21509
+ );
21510
+ exit(1);
21511
+ return { diffsFound: 0 };
21383
21512
  }
21384
- }
21385
-
21386
- // apps/cli/src/infra/commands/playbook/SubmitCommand.ts
21387
- var submitPlaybookCommand = (0, import_cmd_ts31.command)({
21388
- name: "submit",
21389
- description: "Submit staged changes as proposals",
21390
- args: {
21391
- message: (0, import_cmd_ts31.option)({
21392
- type: (0, import_cmd_ts31.optional)(import_cmd_ts31.string),
21393
- long: "message",
21394
- short: "m",
21395
- description: "Message describing the intent behind the proposed changes"
21396
- }),
21397
- noReview: (0, import_cmd_ts31.flag)({
21398
- long: "no-review",
21399
- description: "Apply changes directly without creating proposals for review"
21400
- })
21401
- },
21402
- handler: async ({ message, noReview }) => {
21403
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
21404
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
21405
- const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
21406
- process.cwd()
21513
+ if (targetDirs.length === 0) {
21514
+ const hierarchicalConfig = await packmindCliHexa.readHierarchicalConfig(
21515
+ cwd,
21516
+ null
21407
21517
  );
21408
- const repoRoot = gitRoot ?? process.cwd();
21409
- const playbookLocalRepository = new PlaybookLocalRepository(repoRoot);
21410
- const lockFileRepository = new LockFileRepository();
21411
- await playbookSubmitHandler({
21412
- packmindCliHexa,
21413
- playbookLocalRepository,
21414
- lockFileRepository,
21415
- cwd: process.cwd(),
21416
- exit: process.exit,
21417
- message,
21418
- noReview,
21419
- openEditor: safeOpenEditor,
21420
- unlinkSync: (p) => (0, import_fs28.unlinkSync)(p),
21421
- rmSync: (p, opts) => (0, import_fs28.rmSync)(p, opts)
21518
+ if (!hierarchicalConfig.hasConfigs) {
21519
+ logErrorConsole(
21520
+ "Not inside a Packmind project. No packmind.json found in the current directory or any parent directory."
21521
+ );
21522
+ exit(1);
21523
+ } else {
21524
+ log("No Packmind targets found under the current directory.");
21525
+ exit(0);
21526
+ }
21527
+ return { diffsFound: 0 };
21528
+ }
21529
+ try {
21530
+ const gitInfo = await collectGitInfo(deps);
21531
+ if (!gitInfo) {
21532
+ return { diffsFound: 0 };
21533
+ }
21534
+ const { gitRemoteUrl, gitBranch, gitRoot } = gitInfo;
21535
+ const targetResults = [];
21536
+ for (const targetDir of targetDirs) {
21537
+ const config = await packmindCliHexa.readFullConfig(targetDir);
21538
+ if (!config) continue;
21539
+ const configPackages = Object.keys(config.packages);
21540
+ if (configPackages.length === 0) continue;
21541
+ const relativePath = computeRelativePath(targetDir, gitRoot);
21542
+ const targetRelativePath = nodePath.relative(cwd, targetDir);
21543
+ if (targetDirs.length > 1) {
21544
+ log("");
21545
+ logInfoConsole(`Target: ${targetRelativePath}`);
21546
+ }
21547
+ const packageCount = configPackages.length;
21548
+ const packageWord = packageCount === 1 ? "package" : "packages";
21549
+ logInfoConsole(
21550
+ `Comparing ${packageCount} ${packageWord}: ${configPackages.join(", ")}...`
21551
+ );
21552
+ const diffs = await packmindCliHexa.diffArtefacts({
21553
+ baseDirectory: targetDir,
21554
+ packagesSlugs: configPackages,
21555
+ gitRemoteUrl,
21556
+ gitBranch,
21557
+ relativePath,
21558
+ agents: config.agents
21559
+ });
21560
+ const filterPrefix = nodePath.relative(targetDir, searchPath);
21561
+ const filteredDiffs = filterPrefix !== "" && !filterPrefix.startsWith("..") ? diffs.filter(
21562
+ (d) => d.filePath === filterPrefix || d.filePath.startsWith(filterPrefix + "/")
21563
+ ) : diffs;
21564
+ targetResults.push({ targetRelativePath, diffs: filteredDiffs });
21565
+ }
21566
+ if (targetResults.length === 0) {
21567
+ log("No packages configured in any target.");
21568
+ exit(0);
21569
+ return { diffsFound: 0 };
21570
+ }
21571
+ const displayPathMap = /* @__PURE__ */ new Map();
21572
+ for (const { targetRelativePath, diffs } of targetResults) {
21573
+ for (const diff of diffs) {
21574
+ displayPathMap.set(
21575
+ diff,
21576
+ targetRelativePath ? `${targetRelativePath}/${diff.filePath}` : diff.filePath
21577
+ );
21578
+ }
21579
+ }
21580
+ const allDiffs = targetResults.flatMap((r) => r.diffs);
21581
+ if (allDiffs.length === 0) {
21582
+ log("No changes found.");
21583
+ exit(0);
21584
+ return { diffsFound: 0 };
21585
+ }
21586
+ const allGroupedDiffs = Array.from(groupDiffsByArtefact(allDiffs).values());
21587
+ const checkResult = await packmindCliHexa.checkDiffs(allGroupedDiffs);
21588
+ const submittedItems = checkResult.results.filter((r) => r.exists);
21589
+ const unsubmittedItems = checkResult.results.filter((r) => !r.exists);
21590
+ const diffsToDisplay = includeSubmitted ? allDiffs : unsubmittedItems.map((r) => r.diff);
21591
+ const submittedLookup = /* @__PURE__ */ new Map();
21592
+ for (const item of checkResult.results) {
21593
+ submittedLookup.set(item.diff, item);
21594
+ }
21595
+ if (diffsToDisplay.length === 0) {
21596
+ log("No new changes found.");
21597
+ if (submittedItems.length > 0) {
21598
+ logInfoConsole(buildSubmittedFooter(submittedItems));
21599
+ }
21600
+ exit(0);
21601
+ return { diffsFound: 0 };
21602
+ }
21603
+ const changeCount = displayDiffs({
21604
+ diffsToDisplay,
21605
+ displayPathMap,
21606
+ submittedLookup,
21607
+ includeSubmitted,
21608
+ unsubmittedItems,
21609
+ submittedItems,
21610
+ log
21422
21611
  });
21612
+ exit(0);
21613
+ return { diffsFound: changeCount };
21614
+ } catch (err) {
21615
+ if (err instanceof Error) {
21616
+ logErrorConsole(err.message);
21617
+ } else {
21618
+ logErrorConsole(String(err));
21619
+ }
21620
+ exit(1);
21621
+ return { diffsFound: 0 };
21423
21622
  }
21424
- });
21623
+ }
21425
21624
 
21426
21625
  // apps/cli/src/infra/commands/playbook/DiffCommand.ts
21427
- var import_cmd_ts32 = __toESM(require_cjs());
21428
- var diffCommand2 = (0, import_cmd_ts32.command)({
21626
+ var diffCommand = (0, import_cmd_ts28.command)({
21429
21627
  name: "diff",
21430
21628
  description: "Show differences between local command files and server content",
21431
21629
  args: {
21432
- includeSubmitted: (0, import_cmd_ts32.flag)({
21630
+ includeSubmitted: (0, import_cmd_ts28.flag)({
21433
21631
  long: "include-submitted",
21434
21632
  description: "Include already submitted changes in the output"
21435
21633
  }),
21436
- path: (0, import_cmd_ts32.option)({
21634
+ path: (0, import_cmd_ts28.option)({
21437
21635
  long: "path",
21438
21636
  short: "p",
21439
21637
  description: "Path to analyze (relative to current directory)",
21440
- type: (0, import_cmd_ts32.optional)(import_cmd_ts32.string)
21638
+ type: (0, import_cmd_ts28.optional)(import_cmd_ts28.string)
21441
21639
  })
21442
21640
  },
21443
21641
  handler: async ({ includeSubmitted, path: path37 }) => {
@@ -21455,24 +21653,24 @@ var diffCommand2 = (0, import_cmd_ts32.command)({
21455
21653
  });
21456
21654
 
21457
21655
  // apps/cli/src/infra/commands/PlaybookCommand.ts
21458
- var playbookCommand = (0, import_cmd_ts33.subcommands)({
21656
+ var playbookCommand = (0, import_cmd_ts29.subcommands)({
21459
21657
  name: "playbook",
21460
21658
  description: "Manage local playbook files and propose changes to your team",
21461
21659
  cmds: {
21462
21660
  add: addPlaybookCommand,
21463
21661
  rm: rmPlaybookCommand,
21464
21662
  unstage: unstagePlaybookCommand,
21465
- diff: diffCommand2,
21663
+ diff: diffCommand,
21466
21664
  status: statusPlaybookCommand,
21467
21665
  submit: submitPlaybookCommand
21468
21666
  }
21469
21667
  });
21470
21668
 
21471
21669
  // apps/cli/src/infra/commands/SpacesCommand.ts
21472
- var import_cmd_ts35 = __toESM(require_cjs());
21670
+ var import_cmd_ts31 = __toESM(require_cjs());
21473
21671
 
21474
21672
  // apps/cli/src/infra/commands/ListSpacesCommand.ts
21475
- var import_cmd_ts34 = __toESM(require_cjs());
21673
+ var import_cmd_ts30 = __toESM(require_cjs());
21476
21674
 
21477
21675
  // apps/cli/src/infra/commands/spaces/listSpacesHandler.ts
21478
21676
  function displaySpace(space) {
@@ -21508,7 +21706,7 @@ async function listSpacesHandler(deps) {
21508
21706
  }
21509
21707
 
21510
21708
  // apps/cli/src/infra/commands/ListSpacesCommand.ts
21511
- var listSpacesCommand = (0, import_cmd_ts34.command)({
21709
+ var listSpacesCommand = (0, import_cmd_ts30.command)({
21512
21710
  name: "list",
21513
21711
  description: "List available spaces in the organization",
21514
21712
  args: {},
@@ -21523,7 +21721,7 @@ var listSpacesCommand = (0, import_cmd_ts34.command)({
21523
21721
  });
21524
21722
 
21525
21723
  // apps/cli/src/infra/commands/SpacesCommand.ts
21526
- var spacesCommand = (0, import_cmd_ts35.subcommands)({
21724
+ var spacesCommand = (0, import_cmd_ts31.subcommands)({
21527
21725
  name: "spaces",
21528
21726
  description: "Manage spaces in your Packmind organization",
21529
21727
  cmds: {
@@ -21532,17 +21730,17 @@ var spacesCommand = (0, import_cmd_ts35.subcommands)({
21532
21730
  });
21533
21731
 
21534
21732
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
21535
- var import_cmd_ts41 = __toESM(require_cjs());
21733
+ var import_cmd_ts37 = __toESM(require_cjs());
21536
21734
 
21537
21735
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
21538
- var import_cmd_ts40 = __toESM(require_cjs());
21736
+ var import_cmd_ts36 = __toESM(require_cjs());
21539
21737
 
21540
21738
  // apps/cli/src/infra/commands/config/ConfigAgentsAddCommand.ts
21541
21739
  var readline5 = __toESM(require("readline"));
21542
- var import_cmd_ts37 = __toESM(require_cjs());
21740
+ var import_cmd_ts33 = __toESM(require_cjs());
21543
21741
 
21544
21742
  // apps/cli/src/infra/commands/customParameters/AgentNamesPositional.ts
21545
- var import_cmd_ts36 = __toESM(require_cjs());
21743
+ var import_cmd_ts32 = __toESM(require_cjs());
21546
21744
 
21547
21745
  // apps/cli/src/infra/commands/customParameters/AgentArgType.ts
21548
21746
  var VALID_AGENTS = Object.keys(CodingAgents).filter(
@@ -21561,7 +21759,7 @@ var AgentArgType = {
21561
21759
  };
21562
21760
 
21563
21761
  // apps/cli/src/infra/commands/customParameters/AgentNamesPositional.ts
21564
- var agentNamesPositional = (0, import_cmd_ts36.restPositionals)({
21762
+ var agentNamesPositional = (0, import_cmd_ts32.restPositionals)({
21565
21763
  type: AgentArgType,
21566
21764
  displayName: "agents",
21567
21765
  description: "Agent identifiers (e.g. claude cursor)"
@@ -21667,12 +21865,12 @@ function createPromptConfirm() {
21667
21865
  });
21668
21866
  });
21669
21867
  }
21670
- var addAgentsCommand = (0, import_cmd_ts37.command)({
21868
+ var addAgentsCommand = (0, import_cmd_ts33.command)({
21671
21869
  name: "add",
21672
21870
  description: "Add coding agents to packmind.json files",
21673
21871
  args: {
21674
- path: (0, import_cmd_ts37.option)({
21675
- type: import_cmd_ts37.string,
21872
+ path: (0, import_cmd_ts33.option)({
21873
+ type: import_cmd_ts33.string,
21676
21874
  short: "p",
21677
21875
  long: "path",
21678
21876
  defaultValue: () => "",
@@ -21698,7 +21896,7 @@ var addAgentsCommand = (0, import_cmd_ts37.command)({
21698
21896
  });
21699
21897
 
21700
21898
  // apps/cli/src/infra/commands/config/ConfigAgentsListCommand.ts
21701
- var import_cmd_ts38 = __toESM(require_cjs());
21899
+ var import_cmd_ts34 = __toESM(require_cjs());
21702
21900
 
21703
21901
  // apps/cli/src/infra/commands/config/agents/listAgentsHandler.ts
21704
21902
  var SOURCE_LABELS = {
@@ -21778,12 +21976,12 @@ async function listAgentsHandler(args2, deps) {
21778
21976
  }
21779
21977
 
21780
21978
  // apps/cli/src/infra/commands/config/ConfigAgentsListCommand.ts
21781
- var listAgentsCommand = (0, import_cmd_ts38.command)({
21979
+ var listAgentsCommand = (0, import_cmd_ts34.command)({
21782
21980
  name: "list",
21783
21981
  description: "List coding agents configured across packmind.json files",
21784
21982
  args: {
21785
- path: (0, import_cmd_ts38.option)({
21786
- type: import_cmd_ts38.string,
21983
+ path: (0, import_cmd_ts34.option)({
21984
+ type: import_cmd_ts34.string,
21787
21985
  short: "p",
21788
21986
  long: "path",
21789
21987
  defaultValue: () => "",
@@ -21807,7 +22005,7 @@ var listAgentsCommand = (0, import_cmd_ts38.command)({
21807
22005
  });
21808
22006
 
21809
22007
  // apps/cli/src/infra/commands/config/ConfigAgentsRemoveCommand.ts
21810
- var import_cmd_ts39 = __toESM(require_cjs());
22008
+ var import_cmd_ts35 = __toESM(require_cjs());
21811
22009
 
21812
22010
  // apps/cli/src/infra/commands/config/agents/removeAgentsHandler.ts
21813
22011
  async function removeAgentsHandler(args2, deps) {
@@ -21890,13 +22088,13 @@ function logConfiguredAgentsHint(configuredAgents) {
21890
22088
  }
21891
22089
 
21892
22090
  // apps/cli/src/infra/commands/config/ConfigAgentsRemoveCommand.ts
21893
- var removeAgentsCommand = (0, import_cmd_ts39.command)({
22091
+ var removeAgentsCommand = (0, import_cmd_ts35.command)({
21894
22092
  name: "rm",
21895
22093
  aliases: ["remove"],
21896
22094
  description: "Remove coding agents from packmind.json files",
21897
22095
  args: {
21898
- path: (0, import_cmd_ts39.option)({
21899
- type: import_cmd_ts39.string,
22096
+ path: (0, import_cmd_ts35.option)({
22097
+ type: import_cmd_ts35.string,
21900
22098
  short: "p",
21901
22099
  long: "path",
21902
22100
  defaultValue: () => "",
@@ -21918,7 +22116,7 @@ var removeAgentsCommand = (0, import_cmd_ts39.command)({
21918
22116
  });
21919
22117
 
21920
22118
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
21921
- var configAgentsSetupCommand = (0, import_cmd_ts40.command)({
22119
+ var configAgentsSetupCommand = (0, import_cmd_ts36.command)({
21922
22120
  name: "setup",
21923
22121
  description: "Configure which coding agents to generate artifacts for",
21924
22122
  args: {},
@@ -21936,7 +22134,7 @@ var configAgentsSetupCommand = (0, import_cmd_ts40.command)({
21936
22134
  });
21937
22135
  }
21938
22136
  });
21939
- var configAgentsCommand = (0, import_cmd_ts40.subcommands)({
22137
+ var configAgentsCommand = (0, import_cmd_ts36.subcommands)({
21940
22138
  name: "agents",
21941
22139
  description: "Manage coding agents configuration",
21942
22140
  cmds: {
@@ -21948,7 +22146,7 @@ var configAgentsCommand = (0, import_cmd_ts40.subcommands)({
21948
22146
  });
21949
22147
 
21950
22148
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
21951
- var configCommand = (0, import_cmd_ts41.subcommands)({
22149
+ var configCommand = (0, import_cmd_ts37.subcommands)({
21952
22150
  name: "config",
21953
22151
  description: "Manage Packmind configuration",
21954
22152
  cmds: {
@@ -21957,9 +22155,9 @@ var configCommand = (0, import_cmd_ts41.subcommands)({
21957
22155
  });
21958
22156
 
21959
22157
  // apps/cli/src/infra/commands/InitCommand.ts
21960
- var import_cmd_ts42 = __toESM(require_cjs());
22158
+ var import_cmd_ts38 = __toESM(require_cjs());
21961
22159
  var { version: CLI_VERSION5 } = require_package();
21962
- var initCommand = (0, import_cmd_ts42.command)({
22160
+ var initCommand = (0, import_cmd_ts38.command)({
21963
22161
  name: "init",
21964
22162
  description: "Initialize Packmind in the current project",
21965
22163
  args: {},
@@ -21976,7 +22174,9 @@ var initCommand = (0, import_cmd_ts42.command)({
21976
22174
  baseDirectory,
21977
22175
  installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
21978
22176
  ensureCliVersion: packmindCliHexa.ensureCliVersion.bind(packmindCliHexa),
21979
- cliVersion: CLI_VERSION5
22177
+ cliVersion: CLI_VERSION5,
22178
+ isTTY: Boolean(process.stdin.isTTY),
22179
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
21980
22180
  });
21981
22181
  if (!result.success) {
21982
22182
  for (const error of result.errors) {
@@ -21987,14 +22187,120 @@ var initCommand = (0, import_cmd_ts42.command)({
21987
22187
  }
21988
22188
  });
21989
22189
 
22190
+ // apps/cli/src/infra/commands/TrackCommand.ts
22191
+ var import_cmd_ts39 = __toESM(require_cjs());
22192
+
22193
+ // apps/cli/src/infra/commands/trackHandler.ts
22194
+ async function trackHandler(deps) {
22195
+ const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
22196
+ const confirm = createTrackConfirm({
22197
+ isTTY,
22198
+ confirmPrompt: deps.confirmPrompt
22199
+ });
22200
+ let result;
22201
+ try {
22202
+ result = await deps.trackRepository({
22203
+ repoPath: deps.baseDirectory,
22204
+ origin: "track",
22205
+ update: deps.update,
22206
+ confirm
22207
+ });
22208
+ } catch (error) {
22209
+ handleTrackError(error);
22210
+ return;
22211
+ }
22212
+ switch (result.status) {
22213
+ case "set":
22214
+ logSuccessConsole(
22215
+ `Packmind now tracks ${result.owner}/${result.repo} on branch ${result.branch}.`
22216
+ );
22217
+ process.exit(0);
22218
+ return;
22219
+ case "updated":
22220
+ logSuccessConsole(
22221
+ `Tracked branch for ${result.owner}/${result.repo} changed from ${result.fromBranch} to ${result.branch}.`
22222
+ );
22223
+ process.exit(0);
22224
+ return;
22225
+ case "cancelled":
22226
+ logInfoConsole("No changes made. The tracked branch is unchanged.");
22227
+ process.exit(0);
22228
+ return;
22229
+ case "already-tracked-same-branch":
22230
+ if (deps.update) {
22231
+ logErrorConsole(
22232
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
22233
+ );
22234
+ process.exit(1);
22235
+ } else {
22236
+ logInfoConsole(
22237
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.branch}.`
22238
+ );
22239
+ process.exit(0);
22240
+ }
22241
+ return;
22242
+ case "already-tracked-other-branch":
22243
+ logErrorConsole(
22244
+ `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.trackedBranch}. Run ${formatCommand(
22245
+ "packmind track --update"
22246
+ )} to move it to ${result.branch}.`
22247
+ );
22248
+ process.exit(1);
22249
+ return;
22250
+ case "nothing-tracked":
22251
+ logErrorConsole(
22252
+ `Nothing is tracked yet \u2014 run ${formatCommand("packmind init")} or ${formatCommand("packmind track")} to start tracking.`
22253
+ );
22254
+ process.exit(1);
22255
+ return;
22256
+ }
22257
+ }
22258
+ function handleTrackError(error) {
22259
+ if (error instanceof NotLoggedInError) {
22260
+ logErrorConsole(error.message);
22261
+ process.exit(1);
22262
+ return;
22263
+ }
22264
+ const statusCode = error?.statusCode;
22265
+ if (statusCode === 404) {
22266
+ logErrorConsole("Repository tracking is not available for your account.");
22267
+ process.exit(1);
22268
+ return;
22269
+ }
22270
+ const message = error instanceof Error ? error.message : String(error);
22271
+ logErrorConsole(message);
22272
+ process.exit(1);
22273
+ }
22274
+
22275
+ // apps/cli/src/infra/commands/TrackCommand.ts
22276
+ var trackCommand = (0, import_cmd_ts39.command)({
22277
+ name: "track",
22278
+ description: "Set the repository and branch Packmind tracks for the current project",
22279
+ args: {
22280
+ update: (0, import_cmd_ts39.flag)({
22281
+ long: "update",
22282
+ description: "Move the tracked branch to the current branch (requires an existing tracked branch)"
22283
+ })
22284
+ },
22285
+ handler: async ({ update }) => {
22286
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22287
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22288
+ await trackHandler({
22289
+ update,
22290
+ baseDirectory: process.cwd(),
22291
+ trackRepository: packmindCliHexa.trackRepository.bind(packmindCliHexa)
22292
+ });
22293
+ }
22294
+ });
22295
+
21990
22296
  // apps/cli/src/infra/commands/UpdateCommand.ts
21991
- var import_cmd_ts43 = __toESM(require_cjs());
22297
+ var import_cmd_ts40 = __toESM(require_cjs());
21992
22298
  var { version: CLI_VERSION6 } = require_package();
21993
- var updateCommand = (0, import_cmd_ts43.command)({
22299
+ var updateCommand = (0, import_cmd_ts40.command)({
21994
22300
  name: "update",
21995
22301
  description: "Update packmind-cli to the latest version",
21996
22302
  args: {
21997
- check: (0, import_cmd_ts43.flag)({
22303
+ check: (0, import_cmd_ts40.flag)({
21998
22304
  long: "check",
21999
22305
  description: "Only check if a newer version is available without performing the update"
22000
22306
  })
@@ -22052,13 +22358,12 @@ if (args.includes("--version") || args.includes("-v")) {
22052
22358
  logConsole(`packmind-cli version ${CLI_VERSION7}`);
22053
22359
  process.exit(0);
22054
22360
  }
22055
- var app = (0, import_cmd_ts44.subcommands)({
22361
+ var app = (0, import_cmd_ts41.subcommands)({
22056
22362
  name: "packmind-cli",
22057
22363
  description: "Packmind CLI tool",
22058
22364
  cmds: {
22059
22365
  commands: commandsCommand,
22060
22366
  config: configCommand,
22061
- diff: diffCommand,
22062
22367
  init: initCommand,
22063
22368
  install: installCommand,
22064
22369
  lint: lintCommand,
@@ -22070,12 +22375,13 @@ var app = (0, import_cmd_ts44.subcommands)({
22070
22375
  skills: skillsCommand,
22071
22376
  spaces: spacesCommand,
22072
22377
  standards: standardsCommand,
22378
+ track: trackCommand,
22073
22379
  uninstall: uninstallCommand,
22074
22380
  update: updateCommand,
22075
22381
  whoami: whoamiCommand
22076
22382
  }
22077
22383
  });
22078
- (0, import_cmd_ts44.run)(app, args).catch((error) => {
22384
+ (0, import_cmd_ts41.run)(app, args).catch((error) => {
22079
22385
  logErrorConsole(error.message);
22080
22386
  process.exit(1);
22081
22387
  });