@packmind/cli 0.33.0 → 0.34.1

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 +872 -491
  2. package/package.json +1 -1
package/main.cjs CHANGED
@@ -243,9 +243,9 @@ var init_ansi_styles = __esm({
243
243
  });
244
244
 
245
245
  // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
246
- function hasFlag(flag8, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
247
- const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
248
- const position = argv.indexOf(prefix + flag8);
246
+ function hasFlag(flag9, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
247
+ const prefix = flag9.startsWith("-") ? "" : flag9.length === 1 ? "-" : "--";
248
+ const position = argv.indexOf(prefix + flag9);
249
249
  const terminatorPosition = argv.indexOf("--");
250
250
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
251
251
  }
@@ -380,32 +380,32 @@ var init_supports_color = __esm({
380
380
  });
381
381
 
382
382
  // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js
383
- function stringReplaceAll(string17, substring, replacer) {
384
- let index = string17.indexOf(substring);
383
+ function stringReplaceAll(string18, substring, replacer) {
384
+ let index = string18.indexOf(substring);
385
385
  if (index === -1) {
386
- return string17;
386
+ return string18;
387
387
  }
388
388
  const substringLength = substring.length;
389
389
  let endIndex = 0;
390
390
  let returnValue = "";
391
391
  do {
392
- returnValue += string17.slice(endIndex, index) + substring + replacer;
392
+ returnValue += string18.slice(endIndex, index) + substring + replacer;
393
393
  endIndex = index + substringLength;
394
- index = string17.indexOf(substring, endIndex);
394
+ index = string18.indexOf(substring, endIndex);
395
395
  } while (index !== -1);
396
- returnValue += string17.slice(endIndex);
396
+ returnValue += string18.slice(endIndex);
397
397
  return returnValue;
398
398
  }
399
- function stringEncaseCRLFWithFirstIndex(string17, prefix, postfix, index) {
399
+ function stringEncaseCRLFWithFirstIndex(string18, prefix, postfix, index) {
400
400
  let endIndex = 0;
401
401
  let returnValue = "";
402
402
  do {
403
- const gotCR = string17[index - 1] === "\r";
404
- returnValue += string17.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
403
+ const gotCR = string18[index - 1] === "\r";
404
+ returnValue += string18.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
405
405
  endIndex = index + 1;
406
- index = string17.indexOf("\n", endIndex);
406
+ index = string18.indexOf("\n", endIndex);
407
407
  } while (index !== -1);
408
- returnValue += string17.slice(endIndex);
408
+ returnValue += string18.slice(endIndex);
409
409
  return returnValue;
410
410
  }
411
411
  var init_utilities = __esm({
@@ -564,26 +564,26 @@ var init_source = __esm({
564
564
  builder[IS_EMPTY] = _isEmpty;
565
565
  return builder;
566
566
  };
567
- applyStyle = (self, string17) => {
568
- if (self.level <= 0 || !string17) {
569
- return self[IS_EMPTY] ? "" : string17;
567
+ applyStyle = (self, string18) => {
568
+ if (self.level <= 0 || !string18) {
569
+ return self[IS_EMPTY] ? "" : string18;
570
570
  }
571
571
  let styler = self[STYLER];
572
572
  if (styler === void 0) {
573
- return string17;
573
+ return string18;
574
574
  }
575
575
  const { openAll, closeAll } = styler;
576
- if (string17.includes("\x1B")) {
576
+ if (string18.includes("\x1B")) {
577
577
  while (styler !== void 0) {
578
- string17 = stringReplaceAll(string17, styler.close, styler.open);
578
+ string18 = stringReplaceAll(string18, styler.close, styler.open);
579
579
  styler = styler.parent;
580
580
  }
581
581
  }
582
- const lfIndex = string17.indexOf("\n");
582
+ const lfIndex = string18.indexOf("\n");
583
583
  if (lfIndex !== -1) {
584
- string17 = stringEncaseCRLFWithFirstIndex(string17, closeAll, openAll, lfIndex);
584
+ string18 = stringEncaseCRLFWithFirstIndex(string18, closeAll, openAll, lfIndex);
585
585
  }
586
- return openAll + string17 + closeAll;
586
+ return openAll + string18 + closeAll;
587
587
  };
588
588
  Object.defineProperties(createChalk.prototype, styles2);
589
589
  chalk = createChalk();
@@ -776,9 +776,9 @@ var require_findOption = __commonJS({
776
776
  continue;
777
777
  }
778
778
  if (node.type === "shortOptions" && opts.shortNames.length) {
779
- for (const option19 of node.options) {
780
- if (opts.shortNames.includes(option19.key)) {
781
- result.push(option19);
779
+ for (const option20 of node.options) {
780
+ if (opts.shortNames.includes(option20.key)) {
781
+ result.push(option20);
782
782
  }
783
783
  }
784
784
  }
@@ -851,7 +851,7 @@ var require_types = __commonJS({
851
851
  "use strict";
852
852
  Object.defineProperty(exports2, "__esModule", { value: true });
853
853
  exports2.boolean = exports2.string = exports2.number = void 0;
854
- exports2.optional = optional14;
854
+ exports2.optional = optional15;
855
855
  exports2.array = array2;
856
856
  var type_1 = require_type();
857
857
  exports2.number = {
@@ -878,7 +878,7 @@ var require_types = __commonJS({
878
878
  return false;
879
879
  }
880
880
  };
881
- function optional14(t) {
881
+ function optional15(t) {
882
882
  return {
883
883
  ...t,
884
884
  defaultValue() {
@@ -944,7 +944,7 @@ var require_flag = __commonJS({
944
944
  Object.defineProperty(exports2, "__esModule", { value: true });
945
945
  exports2.boolean = void 0;
946
946
  exports2.fullFlag = fullFlag;
947
- exports2.flag = flag8;
947
+ exports2.flag = flag9;
948
948
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
949
949
  var Result = __importStar(require_Result());
950
950
  var findOption_1 = require_findOption();
@@ -1093,7 +1093,7 @@ var require_flag = __commonJS({
1093
1093
  }
1094
1094
  };
1095
1095
  }
1096
- function flag8(config) {
1096
+ function flag9(config) {
1097
1097
  return fullFlag({
1098
1098
  type: types_1.boolean,
1099
1099
  ...config
@@ -1388,13 +1388,13 @@ var require_subcommands = __commonJS({
1388
1388
  return mod && mod.__esModule ? mod : { "default": mod };
1389
1389
  };
1390
1390
  Object.defineProperty(exports2, "__esModule", { value: true });
1391
- exports2.subcommands = subcommands11;
1391
+ exports2.subcommands = subcommands12;
1392
1392
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1393
1393
  var didyoumean_1 = __importDefault(require_didYouMean_1_2_1());
1394
1394
  var Result = __importStar(require_Result());
1395
1395
  var circuitbreaker_1 = require_circuitbreaker();
1396
1396
  var positional_1 = require_positional();
1397
- function subcommands11(config) {
1397
+ function subcommands12(config) {
1398
1398
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1399
1399
  const type = {
1400
1400
  async from(str) {
@@ -1412,9 +1412,9 @@ var require_subcommands = __commonJS({
1412
1412
  let errorMessage = "Not a valid subcommand name";
1413
1413
  const closeOptions = (0, didyoumean_1.default)(str, flatMap(commands, (x) => x.names));
1414
1414
  if (closeOptions) {
1415
- const option19 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1415
+ const option20 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1416
1416
  errorMessage += `
1417
- Did you mean ${chalk_1.default.italic(option19)}?`;
1417
+ Did you mean ${chalk_1.default.italic(option20)}?`;
1418
1418
  }
1419
1419
  throw new Error(errorMessage);
1420
1420
  }
@@ -1587,14 +1587,14 @@ var strip_ansi_exports = {};
1587
1587
  __export(strip_ansi_exports, {
1588
1588
  default: () => stripAnsi
1589
1589
  });
1590
- function stripAnsi(string17) {
1591
- if (typeof string17 !== "string") {
1592
- throw new TypeError(`Expected a \`string\`, got \`${typeof string17}\``);
1590
+ function stripAnsi(string18) {
1591
+ if (typeof string18 !== "string") {
1592
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string18}\``);
1593
1593
  }
1594
- if (!string17.includes("\x1B") && !string17.includes("\x9B")) {
1595
- return string17;
1594
+ if (!string18.includes("\x1B") && !string18.includes("\x9B")) {
1595
+ return string18;
1596
1596
  }
1597
- return string17.replace(regex, "");
1597
+ return string18.replace(regex, "");
1598
1598
  }
1599
1599
  var regex;
1600
1600
  var init_strip_ansi = __esm({
@@ -1710,12 +1710,12 @@ var require_command = __commonJS({
1710
1710
  return mod && mod.__esModule ? mod : { "default": mod };
1711
1711
  };
1712
1712
  Object.defineProperty(exports2, "__esModule", { value: true });
1713
- exports2.command = command32;
1713
+ exports2.command = command35;
1714
1714
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1715
1715
  var Result = __importStar(require_Result());
1716
1716
  var circuitbreaker_1 = require_circuitbreaker();
1717
1717
  var utils_1 = require_utils();
1718
- function command32(config) {
1718
+ function command35(config) {
1719
1719
  const argEntries = (0, utils_1.entries)(config.args);
1720
1720
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1721
1721
  return {
@@ -1793,11 +1793,11 @@ var require_command = __commonJS({
1793
1793
  }
1794
1794
  if (node.type === "forcePositional") {
1795
1795
  } else if (node.type === "shortOptions") {
1796
- for (const option19 of node.options) {
1797
- if (context.visitedNodes.has(option19)) {
1796
+ for (const option20 of node.options) {
1797
+ if (context.visitedNodes.has(option20)) {
1798
1798
  continue;
1799
1799
  }
1800
- unknownArguments.push(option19);
1800
+ unknownArguments.push(option20);
1801
1801
  }
1802
1802
  } else {
1803
1803
  unknownArguments.push(node);
@@ -1876,7 +1876,7 @@ var require_option = __commonJS({
1876
1876
  return mod && mod.__esModule ? mod : { "default": mod };
1877
1877
  };
1878
1878
  Object.defineProperty(exports2, "__esModule", { value: true });
1879
- exports2.option = option19;
1879
+ exports2.option = option20;
1880
1880
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1881
1881
  var Result = __importStar(require_Result());
1882
1882
  var findOption_1 = require_findOption();
@@ -1952,11 +1952,11 @@ var require_option = __commonJS({
1952
1952
  const valueFromEnv = config.env ? process.env[config.env] : void 0;
1953
1953
  const defaultValueFn = config.defaultValue || config.type.defaultValue;
1954
1954
  const onMissingFn = config.onMissing || config.type.onMissing;
1955
- const option20 = options[0];
1955
+ const option21 = options[0];
1956
1956
  let rawValue;
1957
1957
  let envPrefix = "";
1958
- if (option20 === null || option20 === void 0 ? void 0 : option20.value) {
1959
- rawValue = option20.value.node.raw;
1958
+ if (option21 === null || option21 === void 0 ? void 0 : option21.value) {
1959
+ rawValue = option21.value.node.raw;
1960
1960
  } else if (valueFromEnv !== void 0) {
1961
1961
  rawValue = valueFromEnv;
1962
1962
  envPrefix = `env[${chalk_1.default.italic(config.env)}]: `;
@@ -1991,7 +1991,7 @@ var require_option = __commonJS({
1991
1991
  });
1992
1992
  }
1993
1993
  } else {
1994
- const raw = (option20 === null || option20 === void 0 ? void 0 : option20.type) === "shortOption" ? `-${option20 === null || option20 === void 0 ? void 0 : option20.key}` : `--${config.long}`;
1994
+ const raw = (option21 === null || option21 === void 0 ? void 0 : option21.type) === "shortOption" ? `-${option21 === null || option21 === void 0 ? void 0 : option21.key}` : `--${config.long}`;
1995
1995
  return Result.err({
1996
1996
  errors: [
1997
1997
  {
@@ -2013,7 +2013,7 @@ var require_option = __commonJS({
2013
2013
  }
2014
2014
  };
2015
2015
  }
2016
- function option19(config) {
2016
+ function option20(config) {
2017
2017
  return fullOption({
2018
2018
  type: types_1.string,
2019
2019
  ...config
@@ -2052,12 +2052,12 @@ var require_errorBox = __commonJS({
2052
2052
  if (node.type === "shortOptions") {
2053
2053
  let failed = false;
2054
2054
  let s = "";
2055
- for (const option19 of node.options) {
2056
- if (error.nodes.includes(option19)) {
2057
- s += chalk_1.default.red(option19.raw);
2055
+ for (const option20 of node.options) {
2056
+ if (error.nodes.includes(option20)) {
2057
+ s += chalk_1.default.red(option20.raw);
2058
2058
  failed = true;
2059
2059
  } else {
2060
- s += chalk_1.default.dim(option19.raw);
2060
+ s += chalk_1.default.dim(option20.raw);
2061
2061
  }
2062
2062
  }
2063
2063
  const prefix = failed ? chalk_1.default.red("-") : chalk_1.default.dim("-");
@@ -2586,10 +2586,10 @@ var require_browser = __commonJS({
2586
2586
  var require_has_flag = __commonJS({
2587
2587
  "node_modules/.pnpm/has-flag@3.0.0/node_modules/has-flag/index.js"(exports2, module2) {
2588
2588
  "use strict";
2589
- module2.exports = (flag8, argv) => {
2589
+ module2.exports = (flag9, argv) => {
2590
2590
  argv = argv || process.argv;
2591
- const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
2592
- const pos = argv.indexOf(prefix + flag8);
2591
+ const prefix = flag9.startsWith("-") ? "" : flag9.length === 1 ? "-" : "--";
2592
+ const pos = argv.indexOf(prefix + flag9);
2593
2593
  const terminatorPos = argv.indexOf("--");
2594
2594
  return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
2595
2595
  };
@@ -3090,8 +3090,8 @@ var require_tokenizer = __commonJS({
3090
3090
  tokens.push(token);
3091
3091
  overallIndex += token.raw.length;
3092
3092
  };
3093
- for (const [stringIndex, string17] of (0, utils_1.enumerate)(strings)) {
3094
- const chars = [...string17];
3093
+ for (const [stringIndex, string18] of (0, utils_1.enumerate)(strings)) {
3094
+ const chars = [...string18];
3095
3095
  for (let i = 0; i < chars.length; i++) {
3096
3096
  if (chars[i] === "-" && chars[i + 1] === "-") {
3097
3097
  push({ type: "longPrefix", raw: "--", index: overallIndex });
@@ -3352,15 +3352,15 @@ var require_multiflag = __commonJS({
3352
3352
  longNames: [config.long],
3353
3353
  shortNames: config.short ? [config.short] : []
3354
3354
  }).filter((x) => !visitedNodes.has(x));
3355
- for (const option19 of options) {
3356
- visitedNodes.add(option19);
3355
+ for (const option20 of options) {
3356
+ visitedNodes.add(option20);
3357
3357
  }
3358
3358
  const optionValues = [];
3359
3359
  const errors = [];
3360
- for (const option19 of options) {
3361
- const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option19.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3360
+ for (const option20 of options) {
3361
+ const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option20.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3362
3362
  if (Result.isErr(decoded)) {
3363
- errors.push({ nodes: [option19], message: decoded.error.message });
3363
+ errors.push({ nodes: [option20], message: decoded.error.message });
3364
3364
  } else {
3365
3365
  optionValues.push(decoded.value);
3366
3366
  }
@@ -3524,16 +3524,16 @@ var require_multioption = __commonJS({
3524
3524
  });
3525
3525
  }
3526
3526
  }
3527
- for (const option19 of options) {
3528
- visitedNodes.add(option19);
3527
+ for (const option20 of options) {
3528
+ visitedNodes.add(option20);
3529
3529
  }
3530
3530
  const optionValues = [];
3531
3531
  const errors = [];
3532
3532
  const flagNodes = [];
3533
- for (const option19 of options) {
3534
- const providedValue = (_a = option19.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3533
+ for (const option20 of options) {
3534
+ const providedValue = (_a = option20.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3535
3535
  if (providedValue === void 0) {
3536
- flagNodes.push(option19);
3536
+ flagNodes.push(option20);
3537
3537
  continue;
3538
3538
  }
3539
3539
  optionValues.push(providedValue);
@@ -3858,7 +3858,7 @@ var require_package = __commonJS({
3858
3858
  "apps/cli/package.json"(exports2, module2) {
3859
3859
  module2.exports = {
3860
3860
  name: "@packmind/cli",
3861
- version: "0.33.0",
3861
+ version: "0.34.1",
3862
3862
  description: "A command-line interface for Packmind linting and code quality checks",
3863
3863
  private: false,
3864
3864
  bin: {
@@ -3915,7 +3915,7 @@ var require_package = __commonJS({
3915
3915
  });
3916
3916
 
3917
3917
  // apps/cli/src/main.ts
3918
- var import_cmd_ts42 = __toESM(require_cjs());
3918
+ var import_cmd_ts46 = __toESM(require_cjs());
3919
3919
 
3920
3920
  // apps/cli/src/infra/commands/LinterCommand.ts
3921
3921
  var import_cmd_ts = __toESM(require_cjs());
@@ -4390,6 +4390,7 @@ var RENDER_MODE_ORDER = [
4390
4390
  "GH_COPILOT" /* GH_COPILOT */,
4391
4391
  "CLAUDE" /* CLAUDE */,
4392
4392
  "CLAUDE_PLUGIN" /* CLAUDE_PLUGIN */,
4393
+ "COPILOT_PLUGIN" /* COPILOT_PLUGIN */,
4393
4394
  "CURSOR" /* CURSOR */,
4394
4395
  "GITLAB_DUO" /* GITLAB_DUO */,
4395
4396
  "CONTINUE" /* CONTINUE */
@@ -4417,6 +4418,9 @@ var RENDER_MODE_TO_CODING_AGENT = {
4417
4418
  ["GH_COPILOT" /* GH_COPILOT */]: CodingAgents.copilot,
4418
4419
  ["CLAUDE" /* CLAUDE */]: CodingAgents.claude,
4419
4420
  ["CLAUDE_PLUGIN" /* CLAUDE_PLUGIN */]: CodingAgents.claude_plugin,
4421
+ // No dedicated CodingAgent/deployer exists yet for the Copilot plugin
4422
+ // format — wiring it up (and populating this entry) is a later task.
4423
+ ["COPILOT_PLUGIN" /* COPILOT_PLUGIN */]: void 0,
4420
4424
  ["CURSOR" /* CURSOR */]: CodingAgents.cursor,
4421
4425
  ["GITLAB_DUO" /* GITLAB_DUO */]: CodingAgents.gitlab_duo,
4422
4426
  ["CONTINUE" /* CONTINUE */]: CodingAgents.continue,
@@ -4424,6 +4428,9 @@ var RENDER_MODE_TO_CODING_AGENT = {
4424
4428
  };
4425
4429
  var CODING_AGENT_TO_RENDER_MODE = Object.entries(RENDER_MODE_TO_CODING_AGENT).reduce(
4426
4430
  (acc, [renderMode, codingAgent]) => {
4431
+ if (codingAgent === void 0) {
4432
+ return acc;
4433
+ }
4427
4434
  acc[codingAgent] = renderMode;
4428
4435
  return acc;
4429
4436
  },
@@ -5327,7 +5334,8 @@ var createMarketplaceId = brandedIdFactory();
5327
5334
  // packages/types/src/marketplaces/MarketplaceDescriptorFilename.ts
5328
5335
  var MARKETPLACE_DESCRIPTOR_PATHS = [
5329
5336
  ".claude-plugin/marketplace.json",
5330
- "marketplace.json"
5337
+ "marketplace.json",
5338
+ ".github/plugin/marketplace.json"
5331
5339
  ];
5332
5340
  var MARKETPLACE_DESCRIPTOR_FILENAME = MARKETPLACE_DESCRIPTOR_PATHS[0];
5333
5341
 
@@ -5511,8 +5519,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
5511
5519
  static {
5512
5520
  this.fallbackRuleContent = "adhoc-rule";
5513
5521
  }
5514
- async execute(command32) {
5515
- const { program, fileContent, language } = command32;
5522
+ async execute(command35) {
5523
+ const { program, fileContent, language } = command35;
5516
5524
  const result = await this.linterExecutionUseCase.execute({
5517
5525
  filePath: "cli-single-file",
5518
5526
  fileContent,
@@ -5559,6 +5567,11 @@ function resolveSkillDirPath(absolutePath) {
5559
5567
 
5560
5568
  // apps/cli/src/application/services/GitService.ts
5561
5569
  var origin = "GitService";
5570
+ var DETACHED_HEAD = "HEAD";
5571
+ var LOCAL_REF_NAMESPACE = "refs/heads";
5572
+ var REMOTE_REF_NAMESPACE = "refs/remotes";
5573
+ var LOCAL_REF_PREFIX = `${LOCAL_REF_NAMESPACE}/`;
5574
+ var REMOTE_REF_PREFIX = `${REMOTE_REF_NAMESPACE}/`;
5562
5575
  var GitService = class {
5563
5576
  constructor(logger2 = new PackmindLogger(origin), gitRunner = (cmd, opts) => {
5564
5577
  const stdout = (0, import_child_process.execSync)(`git ${cmd}`, {
@@ -5571,27 +5584,37 @@ var GitService = class {
5571
5584
  this.gitRunner = gitRunner;
5572
5585
  this.logger = logger2;
5573
5586
  }
5574
- getGitRepositoryRoot(path37) {
5587
+ /**
5588
+ * Runs git and turns an invocation failure into a message the user can act on.
5589
+ *
5590
+ * The raw git stderr is deliberately dropped: every caller prints this message
5591
+ * as-is, and `fatal: not a git repository (or any of the parent directories)`
5592
+ * adds nothing the sentence does not already say. The command name is not
5593
+ * mentioned either — these helpers back `lint`, `install`, `git track`,
5594
+ * `git info` and more, so naming one is wrong for all the others.
5595
+ */
5596
+ runGit(gitCommand2, repoPath, failure) {
5575
5597
  try {
5576
- const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
5577
- cwd: path37
5578
- });
5579
- const gitRoot = stdout.trim();
5580
- this.logger.debug("Resolved git repository root", {
5581
- inputPath: path37,
5582
- gitRoot
5583
- });
5584
- return gitRoot;
5585
- } catch (error) {
5586
- if (error instanceof Error) {
5587
- throw new Error(
5588
- `Failed to get Git repository root. The path '${path37}' does not appear to be inside a Git repository.
5589
- ${error.message}`
5590
- );
5591
- }
5592
- throw new Error("Failed to get Git repository root: Unknown error");
5598
+ return this.gitRunner(gitCommand2, { cwd: repoPath }).stdout;
5599
+ } catch {
5600
+ throw new Error(
5601
+ `${failure}. The path '${repoPath}' does not appear to be inside a Git repository.`
5602
+ );
5593
5603
  }
5594
5604
  }
5605
+ getGitRepositoryRoot(path37) {
5606
+ const stdout = this.runGit(
5607
+ "rev-parse --show-toplevel",
5608
+ path37,
5609
+ "Failed to get Git repository root"
5610
+ );
5611
+ const gitRoot = stdout.trim();
5612
+ this.logger.debug("Resolved git repository root", {
5613
+ inputPath: path37,
5614
+ gitRoot
5615
+ });
5616
+ return gitRoot;
5617
+ }
5595
5618
  tryGetGitRepositoryRoot(path37) {
5596
5619
  try {
5597
5620
  return this.getGitRepositoryRoot(path37);
@@ -5612,82 +5635,117 @@ ${error.message}`
5612
5635
  }
5613
5636
  }
5614
5637
  getCurrentBranch(repoPath) {
5615
- try {
5616
- const { stdout } = this.gitRunner("rev-parse --abbrev-ref HEAD", {
5617
- cwd: repoPath
5618
- });
5619
- const branch = stdout.trim();
5620
- this.logger.debug("Resolved current branch", {
5621
- repoPath,
5622
- branch
5623
- });
5624
- return { branch };
5625
- } catch (error) {
5626
- if (error instanceof Error) {
5627
- throw new Error(
5628
- `Failed to get current Git branch. The path '${repoPath}' does not appear to be inside a Git repository.
5629
- ${error.message}`
5630
- );
5631
- }
5632
- throw new Error("Failed to get current Git branch: Unknown error");
5633
- }
5638
+ const stdout = this.runGit(
5639
+ "rev-parse --abbrev-ref HEAD",
5640
+ repoPath,
5641
+ "Failed to get current Git branch"
5642
+ );
5643
+ const branch = stdout.trim();
5644
+ const detached = branch === DETACHED_HEAD;
5645
+ this.logger.debug("Resolved current branch", {
5646
+ repoPath,
5647
+ branch,
5648
+ detached
5649
+ });
5650
+ return { branch, detached };
5634
5651
  }
5635
5652
  getCurrentBranches(repoPath) {
5636
- try {
5637
- const { stdout } = this.gitRunner("branch -a --contains HEAD", {
5638
- cwd: repoPath
5639
- });
5640
- const branches = this.parseBranches(stdout);
5641
- return { branches };
5642
- } catch (error) {
5643
- if (error instanceof Error) {
5644
- throw new Error(
5645
- `Failed to get Git branches. packmind-cli lint must be run in a Git repository.
5646
- ${error.message}`
5647
- );
5653
+ const stdout = this.runGit(
5654
+ "branch -a --contains HEAD",
5655
+ repoPath,
5656
+ "Failed to get Git branches"
5657
+ );
5658
+ return { branches: this.parseBranches(stdout) };
5659
+ }
5660
+ getAllBranches(repoPath) {
5661
+ const stdout = this.runGit(
5662
+ `for-each-ref --format="%(refname)" ${LOCAL_REF_NAMESPACE} ${REMOTE_REF_NAMESPACE}`,
5663
+ repoPath,
5664
+ "Failed to get Git branches"
5665
+ );
5666
+ return { branches: this.parseRefNames(stdout) };
5667
+ }
5668
+ /**
5669
+ * Local and remote-tracking branches are both accepted: `git track --branch`
5670
+ * does not require the branch to be checked out, only to exist.
5671
+ *
5672
+ * `for-each-ref` is plumbing, so its output is the list of refs and nothing
5673
+ * else. `git branch -a` renders for humans, and every decoration it adds used
5674
+ * to be read as part of the branch name — refusing branches that do exist:
5675
+ * `+ feature` for a branch held by a linked worktree, ANSI escapes under
5676
+ * `color.ui = always`, and every branch on one line under `column.ui = always`
5677
+ * (the last two are forced through a pipe, which is how the CLI runs git).
5678
+ *
5679
+ * The branch name is matched in-process instead of being handed to git: it
5680
+ * comes straight from `--branch`, and interpolating it into the command line
5681
+ * would pass user input to the shell.
5682
+ */
5683
+ branchExists(repoPath, branch) {
5684
+ const { branches } = this.getAllBranches(repoPath);
5685
+ return branches.includes(branch);
5686
+ }
5687
+ /**
5688
+ * Turns full refnames into branch names.
5689
+ *
5690
+ * The remote name is dropped, so a branch that exists only on a remote counts
5691
+ * as existing — what `--branch` promises, since it does not require a local
5692
+ * checkout. `refs/remotes/<remote>/HEAD` is skipped: it is a symref to the
5693
+ * remote's default branch, not a branch of its own.
5694
+ */
5695
+ parseRefNames(forEachRefOutput) {
5696
+ const branchNames = /* @__PURE__ */ new Set();
5697
+ for (const line of forEachRefOutput.split("\n")) {
5698
+ const refName = line.trim();
5699
+ if (refName.startsWith(LOCAL_REF_PREFIX)) {
5700
+ branchNames.add(refName.substring(LOCAL_REF_PREFIX.length));
5701
+ continue;
5702
+ }
5703
+ if (!refName.startsWith(REMOTE_REF_PREFIX)) {
5704
+ continue;
5705
+ }
5706
+ const withoutNamespace = refName.substring(REMOTE_REF_PREFIX.length);
5707
+ const remoteSeparator = withoutNamespace.indexOf("/");
5708
+ if (remoteSeparator === -1) {
5709
+ continue;
5710
+ }
5711
+ const branchName = withoutNamespace.substring(remoteSeparator + 1);
5712
+ if (branchName && branchName !== DETACHED_HEAD) {
5713
+ branchNames.add(branchName);
5648
5714
  }
5649
- throw new Error("Failed to get Git branches: Unknown error");
5650
5715
  }
5716
+ return Array.from(branchNames);
5651
5717
  }
5652
5718
  getGitRemoteUrl(repoPath, origin9) {
5653
- try {
5654
- const { stdout } = this.gitRunner("remote -v", {
5655
- cwd: repoPath
5656
- });
5657
- const remotes = this.parseRemotes(stdout);
5658
- if (remotes.length === 0) {
5659
- throw new Error("No Git remotes found in the repository");
5660
- }
5661
- let selectedRemote;
5662
- if (origin9) {
5663
- const foundRemote = remotes.find((remote) => remote.name === origin9);
5664
- if (!foundRemote) {
5665
- throw new Error(`Remote '${origin9}' not found in repository`);
5666
- }
5667
- selectedRemote = foundRemote.url;
5668
- } else if (remotes.length === 1) {
5669
- selectedRemote = remotes[0].url;
5670
- } else {
5671
- const originRemote = remotes.find((remote) => remote.name === "origin");
5672
- if (!originRemote) {
5673
- throw new Error(
5674
- "Multiple remotes found but no 'origin' remote. Please specify the remote name."
5675
- );
5676
- }
5677
- selectedRemote = originRemote.url;
5678
- }
5679
- return {
5680
- gitRemoteUrl: this.normalizeGitUrl(selectedRemote)
5681
- };
5682
- } catch (error) {
5683
- if (error instanceof Error) {
5719
+ const stdout = this.runGit(
5720
+ "remote -v",
5721
+ repoPath,
5722
+ "Failed to get Git remote URL"
5723
+ );
5724
+ const remotes = this.parseRemotes(stdout);
5725
+ if (remotes.length === 0) {
5726
+ throw new Error("No Git remotes found in the repository");
5727
+ }
5728
+ let selectedRemote;
5729
+ if (origin9) {
5730
+ const foundRemote = remotes.find((remote) => remote.name === origin9);
5731
+ if (!foundRemote) {
5732
+ throw new Error(`Remote '${origin9}' not found in repository`);
5733
+ }
5734
+ selectedRemote = foundRemote.url;
5735
+ } else if (remotes.length === 1) {
5736
+ selectedRemote = remotes[0].url;
5737
+ } else {
5738
+ const originRemote = remotes.find((remote) => remote.name === "origin");
5739
+ if (!originRemote) {
5684
5740
  throw new Error(
5685
- `Failed to get Git remote URL. packmind-cli lint must be run in a Git repository.
5686
- ${error.message}`
5741
+ "Multiple remotes found but no 'origin' remote. Please specify the remote name."
5687
5742
  );
5688
5743
  }
5689
- throw new Error("Failed to get Git remote URL: Unknown error");
5744
+ selectedRemote = originRemote.url;
5690
5745
  }
5746
+ return {
5747
+ gitRemoteUrl: this.normalizeGitUrl(selectedRemote)
5748
+ };
5691
5749
  }
5692
5750
  /**
5693
5751
  * Gets files that have been modified (staged + unstaged) compared to HEAD.
@@ -5896,8 +5954,8 @@ var GetGitRemoteUrlUseCase = class {
5896
5954
  constructor(gitRemoteUrlService = new GitService()) {
5897
5955
  this.gitRemoteUrlService = gitRemoteUrlService;
5898
5956
  }
5899
- async execute(command32) {
5900
- const { path: repoPath, origin: origin9 } = command32;
5957
+ async execute(command35) {
5958
+ const { path: repoPath, origin: origin9 } = command35;
5901
5959
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5902
5960
  }
5903
5961
  };
@@ -6049,8 +6107,8 @@ var ListFilesInDirectoryUseCase = class {
6049
6107
  constructor(listFiles = new ListFiles()) {
6050
6108
  this.listFiles = listFiles;
6051
6109
  }
6052
- async execute(command32) {
6053
- const { path: directoryPath, extensions, excludes = [] } = command32;
6110
+ async execute(command35) {
6111
+ const { path: directoryPath, extensions, excludes = [] } = command35;
6054
6112
  const files = await this.listFiles.listFilesInDirectory(
6055
6113
  directoryPath,
6056
6114
  extensions,
@@ -6165,7 +6223,7 @@ var LintFilesAgainstRuleUseCase = class {
6165
6223
  };
6166
6224
  };
6167
6225
  }
6168
- async execute(command32) {
6226
+ async execute(command35) {
6169
6227
  const {
6170
6228
  path: userPath,
6171
6229
  draftMode,
@@ -6174,7 +6232,7 @@ var LintFilesAgainstRuleUseCase = class {
6174
6232
  language,
6175
6233
  diffMode,
6176
6234
  ignorePatterns
6177
- } = command32;
6235
+ } = command35;
6178
6236
  this.logger.debug(
6179
6237
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
6180
6238
  );
@@ -6490,8 +6548,8 @@ var LintFilesAgainstRuleUseCase = class {
6490
6548
  return null;
6491
6549
  }
6492
6550
  }
6493
- async executeProgramsForFile(command32) {
6494
- const result = await this.services.linterExecutionUseCase.execute(command32);
6551
+ async executeProgramsForFile(command35) {
6552
+ const result = await this.services.linterExecutionUseCase.execute(command35);
6495
6553
  return result.violations;
6496
6554
  }
6497
6555
  extractExtensionFromFile(filePath) {
@@ -6514,8 +6572,8 @@ var LintFilesFromConfigUseCase = class {
6514
6572
  this.logger = logger2;
6515
6573
  this.detectionProgramsCache = /* @__PURE__ */ new Map();
6516
6574
  }
6517
- async execute(command32) {
6518
- const { path: userPath, diffMode, ignorePatterns } = command32;
6575
+ async execute(command35) {
6576
+ const { path: userPath, diffMode, ignorePatterns } = command35;
6519
6577
  this.logger.debug(
6520
6578
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
6521
6579
  );
@@ -6775,8 +6833,8 @@ var LintFilesFromConfigUseCase = class {
6775
6833
  return null;
6776
6834
  }
6777
6835
  }
6778
- async executeProgramsForFile(command32) {
6779
- const result = await this.services.linterExecutionUseCase.execute(command32);
6836
+ async executeProgramsForFile(command35) {
6837
+ const result = await this.services.linterExecutionUseCase.execute(command35);
6780
6838
  return result.violations;
6781
6839
  }
6782
6840
  extractExtensionFromFile(filePath) {
@@ -6952,13 +7010,13 @@ var PackmindHttpClient = class {
6952
7010
  var ChangeProposalGateway = class {
6953
7011
  constructor(httpClient) {
6954
7012
  this.httpClient = httpClient;
6955
- this.batchCreate = async (command32) => {
7013
+ this.batchCreate = async (command35) => {
6956
7014
  const { organizationId } = this.httpClient.getAuthContext();
6957
7015
  return this.httpClient.request(
6958
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/change-proposals/batch`,
7016
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/change-proposals/batch`,
6959
7017
  {
6960
7018
  method: "POST",
6961
- body: { proposals: command32.proposals },
7019
+ body: { proposals: command35.proposals },
6962
7020
  onError: (response) => {
6963
7021
  if (response.status === 404) {
6964
7022
  throw new CommunityEditionError("change proposals");
@@ -6967,29 +7025,29 @@ var ChangeProposalGateway = class {
6967
7025
  }
6968
7026
  );
6969
7027
  };
6970
- this.batchApply = async (command32) => {
7028
+ this.batchApply = async (command35) => {
6971
7029
  const { organizationId } = this.httpClient.getAuthContext();
6972
7030
  return this.httpClient.request(
6973
7031
  `/api/v0/organizations/${organizationId}/playbook/apply`,
6974
7032
  {
6975
7033
  method: "POST",
6976
7034
  body: {
6977
- proposals: command32.proposals,
6978
- message: command32.message,
6979
- ...command32.directUpdate !== void 0 && {
6980
- directUpdate: command32.directUpdate
7035
+ proposals: command35.proposals,
7036
+ message: command35.message,
7037
+ ...command35.directUpdate !== void 0 && {
7038
+ directUpdate: command35.directUpdate
6981
7039
  }
6982
7040
  }
6983
7041
  }
6984
7042
  );
6985
7043
  };
6986
- this.check = async (command32) => {
7044
+ this.check = async (command35) => {
6987
7045
  const { organizationId } = this.httpClient.getAuthContext();
6988
7046
  return this.httpClient.request(
6989
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/change-proposals/check`,
7047
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/change-proposals/check`,
6990
7048
  {
6991
7049
  method: "POST",
6992
- body: { proposals: command32.proposals },
7050
+ body: { proposals: command35.proposals },
6993
7051
  onError: (response) => {
6994
7052
  if (response.status === 404) {
6995
7053
  throw new CommunityEditionError("change proposals");
@@ -7005,13 +7063,13 @@ var ChangeProposalGateway = class {
7005
7063
  var LinterGateway = class {
7006
7064
  constructor(httpClient) {
7007
7065
  this.httpClient = httpClient;
7008
- this.getDraftDetectionProgramsForRule = async (command32) => {
7066
+ this.getDraftDetectionProgramsForRule = async (command35) => {
7009
7067
  const payload = {
7010
- standardSlug: command32.standardSlug,
7011
- ruleId: command32.ruleId
7068
+ standardSlug: command35.standardSlug,
7069
+ ruleId: command35.ruleId
7012
7070
  };
7013
- if (command32.language) {
7014
- payload.language = command32.language;
7071
+ if (command35.language) {
7072
+ payload.language = command35.language;
7015
7073
  }
7016
7074
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
7017
7075
  method: "POST",
@@ -7023,13 +7081,13 @@ var LinterGateway = class {
7023
7081
  }
7024
7082
  });
7025
7083
  };
7026
- this.getActiveDetectionProgramsForRule = async (command32) => {
7084
+ this.getActiveDetectionProgramsForRule = async (command35) => {
7027
7085
  const payload = {
7028
- standardSlug: command32.standardSlug,
7029
- ruleId: command32.ruleId
7086
+ standardSlug: command35.standardSlug,
7087
+ ruleId: command35.ruleId
7030
7088
  };
7031
- if (command32.language) {
7032
- payload.language = command32.language;
7089
+ if (command35.language) {
7090
+ payload.language = command35.language;
7033
7091
  }
7034
7092
  return this.httpClient.request("/api/v0/list-active-detection-program", {
7035
7093
  method: "POST",
@@ -7041,13 +7099,13 @@ var LinterGateway = class {
7041
7099
  }
7042
7100
  });
7043
7101
  };
7044
- this.getDetectionProgramsForPackages = async (command32) => {
7102
+ this.getDetectionProgramsForPackages = async (command35) => {
7045
7103
  const response = await this.httpClient.request(
7046
7104
  "/api/v0/detection-programs-for-packages",
7047
7105
  {
7048
7106
  method: "POST",
7049
7107
  body: {
7050
- packagesSlugs: command32.packagesSlugs
7108
+ packagesSlugs: command35.packagesSlugs
7051
7109
  },
7052
7110
  onError: (response2) => {
7053
7111
  if (response2.status === 404) {
@@ -7058,10 +7116,10 @@ var LinterGateway = class {
7058
7116
  );
7059
7117
  return handleScopeInTargetsResponse(response);
7060
7118
  };
7061
- this.trackLinterExecution = async (command32) => {
7119
+ this.trackLinterExecution = async (command35) => {
7062
7120
  return this.httpClient.request(`/api/v0/track-execution`, {
7063
7121
  method: "POST",
7064
- body: command32
7122
+ body: command35
7065
7123
  });
7066
7124
  };
7067
7125
  }
@@ -7115,27 +7173,27 @@ var SpacesGateway = class {
7115
7173
  var SkillsGateway = class {
7116
7174
  constructor(httpClient) {
7117
7175
  this.httpClient = httpClient;
7118
- this.upload = async (command32) => {
7176
+ this.upload = async (command35) => {
7119
7177
  const { organizationId } = this.httpClient.getAuthContext();
7120
7178
  return this.httpClient.request(
7121
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/skills/upload`,
7179
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/skills/upload`,
7122
7180
  {
7123
7181
  method: "POST",
7124
- body: command32
7182
+ body: command35
7125
7183
  }
7126
7184
  );
7127
7185
  };
7128
- this.getDefaults = async (command32) => {
7186
+ this.getDefaults = async (command35) => {
7129
7187
  const { organizationId } = this.httpClient.getAuthContext();
7130
7188
  const queryParams = new URLSearchParams();
7131
- if (command32.includeBeta) {
7189
+ if (command35.includeBeta) {
7132
7190
  queryParams.set("includeBeta", "true");
7133
- } else if (command32.cliVersion) {
7134
- queryParams.set("cliVersion", command32.cliVersion);
7191
+ } else if (command35.cliVersion) {
7192
+ queryParams.set("cliVersion", command35.cliVersion);
7135
7193
  }
7136
- if (command32.agents !== void 0) {
7194
+ if (command35.agents !== void 0) {
7137
7195
  queryParams.append("agentsConfigOverride", "true");
7138
- command32.agents.forEach((agent) => {
7196
+ command35.agents.forEach((agent) => {
7139
7197
  queryParams.append("agent", agent);
7140
7198
  });
7141
7199
  }
@@ -7144,10 +7202,10 @@ var SkillsGateway = class {
7144
7202
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
7145
7203
  );
7146
7204
  };
7147
- this.list = async (command32) => {
7205
+ this.list = async (command35) => {
7148
7206
  const { organizationId } = this.httpClient.getAuthContext();
7149
7207
  return this.httpClient.request(
7150
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/skills`
7208
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/skills`
7151
7209
  );
7152
7210
  };
7153
7211
  }
@@ -7157,17 +7215,17 @@ var SkillsGateway = class {
7157
7215
  var CommandsGateway = class {
7158
7216
  constructor(httpClient) {
7159
7217
  this.httpClient = httpClient;
7160
- this.create = async (command32) => {
7218
+ this.create = async (command35) => {
7161
7219
  const { organizationId } = this.httpClient.getAuthContext();
7162
7220
  return this.httpClient.request(
7163
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/commands`,
7164
- { method: "POST", body: command32 }
7221
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/commands`,
7222
+ { method: "POST", body: command35 }
7165
7223
  );
7166
7224
  };
7167
- this.list = async (command32) => {
7225
+ this.list = async (command35) => {
7168
7226
  const { organizationId } = this.httpClient.getAuthContext();
7169
7227
  const listCommandsResponse = await this.httpClient.request(
7170
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/commands`
7228
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/commands`
7171
7229
  );
7172
7230
  if (listCommandsResponse instanceof Array) {
7173
7231
  return { recipes: listCommandsResponse };
@@ -7210,10 +7268,10 @@ var StandardsGateway = class {
7210
7268
  }
7211
7269
  );
7212
7270
  };
7213
- this.list = async (command32) => {
7271
+ this.list = async (command35) => {
7214
7272
  const { organizationId } = this.httpClient.getAuthContext();
7215
7273
  return this.httpClient.request(
7216
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/standards`
7274
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/standards`
7217
7275
  );
7218
7276
  };
7219
7277
  }
@@ -7224,10 +7282,10 @@ var PackagesGateway = class {
7224
7282
  constructor(apiKey, httpClient) {
7225
7283
  this.apiKey = apiKey;
7226
7284
  this.httpClient = httpClient;
7227
- this.list = async (command32) => {
7285
+ this.list = async (command35) => {
7228
7286
  const { organizationId } = this.httpClient.getAuthContext();
7229
7287
  return this.httpClient.request(
7230
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/packages`
7288
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/packages`
7231
7289
  );
7232
7290
  };
7233
7291
  this.getSummary = async ({
@@ -7239,20 +7297,20 @@ var PackagesGateway = class {
7239
7297
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug6)}`
7240
7298
  );
7241
7299
  };
7242
- this.create = async (command32) => {
7300
+ this.create = async (command35) => {
7243
7301
  const { organizationId } = this.httpClient.getAuthContext();
7244
- const { recipeIds, ...rest } = command32;
7302
+ const { recipeIds, ...rest } = command35;
7245
7303
  return this.httpClient.request(
7246
- `/api/v0/organizations/${organizationId}/spaces/${command32.spaceId}/packages`,
7304
+ `/api/v0/organizations/${organizationId}/spaces/${command35.spaceId}/packages`,
7247
7305
  {
7248
7306
  method: "POST",
7249
7307
  body: { ...rest, commandIds: recipeIds }
7250
7308
  }
7251
7309
  );
7252
7310
  };
7253
- this.addArtefacts = async (command32) => {
7311
+ this.addArtefacts = async (command35) => {
7254
7312
  const { organizationId } = this.httpClient.getAuthContext();
7255
- const { packageId, spaceId, recipeIds, ...rest } = command32;
7313
+ const { packageId, spaceId, recipeIds, ...rest } = command35;
7256
7314
  return this.httpClient.request(
7257
7315
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
7258
7316
  {
@@ -7268,31 +7326,31 @@ var PackagesGateway = class {
7268
7326
  var DeploymentGateway = class {
7269
7327
  constructor(httpClient) {
7270
7328
  this.httpClient = httpClient;
7271
- this.pull = async (command32) => {
7329
+ this.pull = async (command35) => {
7272
7330
  const { organizationId } = this.httpClient.getAuthContext();
7273
7331
  const queryParams = new URLSearchParams();
7274
- if (command32.packagesSlugs && command32.packagesSlugs.length > 0) {
7275
- command32.packagesSlugs.forEach((slug6) => {
7332
+ if (command35.packagesSlugs && command35.packagesSlugs.length > 0) {
7333
+ command35.packagesSlugs.forEach((slug6) => {
7276
7334
  queryParams.append("packageSlug", slug6);
7277
7335
  });
7278
7336
  }
7279
- if (command32.previousPackagesSlugs && command32.previousPackagesSlugs.length > 0) {
7280
- command32.previousPackagesSlugs.forEach((slug6) => {
7337
+ if (command35.previousPackagesSlugs && command35.previousPackagesSlugs.length > 0) {
7338
+ command35.previousPackagesSlugs.forEach((slug6) => {
7281
7339
  queryParams.append("previousPackageSlug", slug6);
7282
7340
  });
7283
7341
  }
7284
- if (command32.gitRemoteUrl) {
7285
- queryParams.append("gitRemoteUrl", command32.gitRemoteUrl);
7342
+ if (command35.gitRemoteUrl) {
7343
+ queryParams.append("gitRemoteUrl", command35.gitRemoteUrl);
7286
7344
  }
7287
- if (command32.gitBranch) {
7288
- queryParams.append("gitBranch", command32.gitBranch);
7345
+ if (command35.gitBranch) {
7346
+ queryParams.append("gitBranch", command35.gitBranch);
7289
7347
  }
7290
- if (command32.relativePath) {
7291
- queryParams.append("relativePath", command32.relativePath);
7348
+ if (command35.relativePath) {
7349
+ queryParams.append("relativePath", command35.relativePath);
7292
7350
  }
7293
- if (command32.agents !== void 0) {
7351
+ if (command35.agents !== void 0) {
7294
7352
  queryParams.append("agentsConfigOverride", "true");
7295
- command32.agents.forEach((agent) => {
7353
+ command35.agents.forEach((agent) => {
7296
7354
  queryParams.append("agent", agent);
7297
7355
  });
7298
7356
  }
@@ -7300,101 +7358,101 @@ var DeploymentGateway = class {
7300
7358
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
7301
7359
  );
7302
7360
  };
7303
- this.install = async (command32) => {
7361
+ this.install = async (command35) => {
7304
7362
  const { organizationId } = this.httpClient.getAuthContext();
7305
7363
  return this.httpClient.request(
7306
7364
  `/api/v0/organizations/${organizationId}/install`,
7307
7365
  {
7308
7366
  method: "POST",
7309
7367
  body: {
7310
- packagesSlugs: command32.packagesSlugs,
7311
- packmindLockFile: command32.packmindLockFile,
7312
- ...command32.relativePath && { relativePath: command32.relativePath },
7313
- ...command32.agents !== void 0 && { agents: command32.agents }
7368
+ packagesSlugs: command35.packagesSlugs,
7369
+ packmindLockFile: command35.packmindLockFile,
7370
+ ...command35.relativePath && { relativePath: command35.relativePath },
7371
+ ...command35.agents !== void 0 && { agents: command35.agents }
7314
7372
  }
7315
7373
  }
7316
7374
  );
7317
7375
  };
7318
- this.getDeployed = async (command32) => {
7376
+ this.getDeployed = async (command35) => {
7319
7377
  const { organizationId } = this.httpClient.getAuthContext();
7320
7378
  return this.httpClient.request(
7321
7379
  `/api/v0/organizations/${organizationId}/deployed-content`,
7322
7380
  {
7323
7381
  method: "POST",
7324
7382
  body: {
7325
- packagesSlugs: command32.packagesSlugs,
7326
- gitRemoteUrl: command32.gitRemoteUrl,
7327
- gitBranch: command32.gitBranch,
7328
- relativePath: command32.relativePath,
7329
- ...command32.agents !== void 0 && { agents: command32.agents }
7383
+ packagesSlugs: command35.packagesSlugs,
7384
+ gitRemoteUrl: command35.gitRemoteUrl,
7385
+ gitBranch: command35.gitBranch,
7386
+ relativePath: command35.relativePath,
7387
+ ...command35.agents !== void 0 && { agents: command35.agents }
7330
7388
  }
7331
7389
  }
7332
7390
  );
7333
7391
  };
7334
- this.getContentByVersions = async (command32) => {
7392
+ this.getContentByVersions = async (command35) => {
7335
7393
  const { organizationId } = this.httpClient.getAuthContext();
7336
7394
  return this.httpClient.request(
7337
7395
  `/api/v0/organizations/${organizationId}/content-by-versions`,
7338
7396
  {
7339
7397
  method: "POST",
7340
7398
  body: {
7341
- artifacts: command32.artifacts,
7342
- ...command32.agents !== void 0 && { agents: command32.agents }
7399
+ artifacts: command35.artifacts,
7400
+ ...command35.agents !== void 0 && { agents: command35.agents }
7343
7401
  }
7344
7402
  }
7345
7403
  );
7346
7404
  };
7347
- this.notifyDistribution = async (command32) => {
7405
+ this.notifyDistribution = async (command35) => {
7348
7406
  const { organizationId } = this.httpClient.getAuthContext();
7349
7407
  return this.httpClient.request(
7350
7408
  `/api/v0/organizations/${organizationId}/deployments`,
7351
7409
  {
7352
7410
  method: "POST",
7353
- body: command32
7411
+ body: command35
7354
7412
  }
7355
7413
  );
7356
7414
  };
7357
- this.notifyArtefactsDistribution = async (command32) => {
7415
+ this.notifyArtefactsDistribution = async (command35) => {
7358
7416
  const { organizationId } = this.httpClient.getAuthContext();
7359
7417
  return this.httpClient.request(
7360
7418
  `/api/v0/organizations/${organizationId}/deployments/notify-artifacts-distribution`,
7361
7419
  {
7362
7420
  method: "POST",
7363
7421
  body: {
7364
- gitRemoteUrl: command32.gitRemoteUrl,
7365
- gitBranch: command32.gitBranch,
7366
- relativePath: command32.relativePath,
7367
- packmindLockFile: command32.packmindLockFile
7422
+ gitRemoteUrl: command35.gitRemoteUrl,
7423
+ gitBranch: command35.gitBranch,
7424
+ relativePath: command35.relativePath,
7425
+ packmindLockFile: command35.packmindLockFile
7368
7426
  }
7369
7427
  }
7370
7428
  );
7371
7429
  };
7372
- this.renderPlugin = async (command32) => {
7430
+ this.renderPlugin = async (command35) => {
7373
7431
  const { organizationId } = this.httpClient.getAuthContext();
7374
7432
  return this.httpClient.request(
7375
7433
  `/api/v0/organizations/${organizationId}/plugins/render`,
7376
7434
  {
7377
7435
  method: "POST",
7378
7436
  body: {
7379
- packageSlug: command32.packageSlug,
7380
- mode: command32.mode,
7381
- pluginRoot: command32.pluginRoot,
7382
- pluginName: command32.pluginName,
7383
- gitRemoteUrl: command32.gitRemoteUrl,
7384
- gitBranch: command32.gitBranch
7437
+ packageSlug: command35.packageSlug,
7438
+ mode: command35.mode,
7439
+ pluginRoot: command35.pluginRoot,
7440
+ pluginName: command35.pluginName,
7441
+ gitRemoteUrl: command35.gitRemoteUrl,
7442
+ gitBranch: command35.gitBranch
7385
7443
  }
7386
7444
  }
7387
7445
  );
7388
7446
  };
7389
- this.trackPluginDeleted = async (command32) => {
7447
+ this.trackPluginDeleted = async (command35) => {
7390
7448
  const { organizationId } = this.httpClient.getAuthContext();
7391
7449
  return this.httpClient.request(
7392
7450
  `/api/v0/organizations/${organizationId}/plugins/track-deleted`,
7393
7451
  {
7394
7452
  method: "POST",
7395
7453
  body: {
7396
- packageSlug: command32.packageSlug,
7397
- gitRemoteUrl: command32.gitRemoteUrl
7454
+ packageSlug: command35.packageSlug,
7455
+ gitRemoteUrl: command35.gitRemoteUrl
7398
7456
  }
7399
7457
  }
7400
7458
  );
@@ -7406,13 +7464,13 @@ var DeploymentGateway = class {
7406
7464
  );
7407
7465
  };
7408
7466
  }
7409
- async updateRenderModeConfiguration(command32) {
7467
+ async updateRenderModeConfiguration(command35) {
7410
7468
  const { organizationId } = this.httpClient.getAuthContext();
7411
7469
  await this.httpClient.request(
7412
7470
  `/api/v0/organizations/${organizationId}/deployments/renderModeConfiguration`,
7413
7471
  {
7414
7472
  method: "POST",
7415
- body: { activeRenderModes: command32.activeRenderModes }
7473
+ body: { activeRenderModes: command35.activeRenderModes }
7416
7474
  }
7417
7475
  );
7418
7476
  }
@@ -7469,18 +7527,18 @@ var RepositoryTrackingGateway = class {
7469
7527
  `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository?${query}`
7470
7528
  );
7471
7529
  };
7472
- this.setTrackedRepository = async (command32) => {
7530
+ this.setTrackedRepository = async (command35) => {
7473
7531
  const { organizationId } = this.httpClient.getAuthContext();
7474
7532
  return this.httpClient.request(
7475
7533
  `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7476
- { method: "POST", body: command32 }
7534
+ { method: "POST", body: command35 }
7477
7535
  );
7478
7536
  };
7479
- this.updateTrackedBranch = async (command32) => {
7537
+ this.updateTrackedBranch = async (command35) => {
7480
7538
  const { organizationId } = this.httpClient.getAuthContext();
7481
7539
  return this.httpClient.request(
7482
7540
  `/api/v0/organizations/${organizationId}/git/repositories/tracked-repository`,
7483
- { method: "PUT", body: command32 }
7541
+ { method: "PUT", body: command35 }
7484
7542
  );
7485
7543
  };
7486
7544
  this.removeTrackedRepository = async ({ owner, repo }) => {
@@ -9252,8 +9310,8 @@ var ExecuteLinterProgramsUseCase = class {
9252
9310
  this.linterAstAdapter = linterAstAdapter;
9253
9311
  this.logger = logger2;
9254
9312
  }
9255
- async execute(command32) {
9256
- const { filePath, fileContent, language, programs } = command32;
9313
+ async execute(command35) {
9314
+ const { filePath, fileContent, language, programs } = command35;
9257
9315
  if (programs.length === 0) {
9258
9316
  return {
9259
9317
  file: filePath,
@@ -9852,12 +9910,14 @@ var Cache = class _Cache {
9852
9910
  // packages/feature-flags/src/registry.ts
9853
9911
  var ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY = "change-proposals-in-webapp";
9854
9912
  var ORGA_SPACE_MANAGEMENT_FEATURE_KEY = "orga-space-management";
9913
+ var SPACE_NAV_PLUGIN_FIRST_FEATURE_KEY = "space-nav-plugin-first";
9855
9914
  var DEFAULT_FEATURE_DOMAIN_MAP = {
9856
9915
  [ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY]: [
9857
9916
  "@packmind.com",
9858
9917
  "@promyze.com"
9859
9918
  ],
9860
- [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9919
+ [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"],
9920
+ [SPACE_NAV_PLUGIN_FIRST_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9861
9921
  };
9862
9922
 
9863
9923
  // packages/node-utils/src/database/schemas.ts
@@ -10088,8 +10148,8 @@ var InstallPackagesUseCase = class {
10088
10148
  constructor(packmindGateway) {
10089
10149
  this.packmindGateway = packmindGateway;
10090
10150
  }
10091
- async execute(command32) {
10092
- const baseDirectory = command32.baseDirectory || process.cwd();
10151
+ async execute(command35) {
10152
+ const baseDirectory = command35.baseDirectory || process.cwd();
10093
10153
  const result = {
10094
10154
  filesCreated: 0,
10095
10155
  filesUpdated: 0,
@@ -10101,12 +10161,12 @@ var InstallPackagesUseCase = class {
10101
10161
  skillDirectoriesDeleted: 0
10102
10162
  };
10103
10163
  const response = await this.packmindGateway.deployment.pull({
10104
- packagesSlugs: command32.packagesSlugs,
10105
- previousPackagesSlugs: command32.previousPackagesSlugs,
10106
- gitRemoteUrl: command32.gitRemoteUrl,
10107
- gitBranch: command32.gitBranch,
10108
- relativePath: command32.relativePath,
10109
- agents: command32.agents
10164
+ packagesSlugs: command35.packagesSlugs,
10165
+ previousPackagesSlugs: command35.previousPackagesSlugs,
10166
+ gitRemoteUrl: command35.gitRemoteUrl,
10167
+ gitBranch: command35.gitBranch,
10168
+ relativePath: command35.relativePath,
10169
+ agents: command35.agents
10110
10170
  });
10111
10171
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
10112
10172
  (file) => file.path !== "packmind.json"
@@ -10481,8 +10541,8 @@ var InstallUseCase = class {
10481
10541
  this.configFileRepository = configFileRepository;
10482
10542
  this.spaceService = spaceService;
10483
10543
  }
10484
- async execute(command32) {
10485
- const baseDirectory = command32.baseDirectory || process.cwd();
10544
+ async execute(command35) {
10545
+ const baseDirectory = command35.baseDirectory || process.cwd();
10486
10546
  const result = {
10487
10547
  filesCreated: 0,
10488
10548
  filesUpdated: 0,
@@ -10512,7 +10572,7 @@ var InstallUseCase = class {
10512
10572
  },
10513
10573
  resolvedAgents: []
10514
10574
  };
10515
- const hasExplicitPackages = command32.packages && command32.packages.length > 0;
10575
+ const hasExplicitPackages = command35.packages && command35.packages.length > 0;
10516
10576
  const configExistedBefore = await this.configFileRepository.configExists(baseDirectory);
10517
10577
  const lockFile = await this.lockFileRepository.read(baseDirectory);
10518
10578
  const config = await this.configFileRepository.readConfig(baseDirectory);
@@ -10534,11 +10594,11 @@ var InstallUseCase = class {
10534
10594
  agents: [],
10535
10595
  artifacts: {}
10536
10596
  };
10537
- effectiveLockFile.cliVersion = command32.cliVersion;
10597
+ effectiveLockFile.cliVersion = command35.cliVersion;
10538
10598
  let packagesSlugs;
10539
10599
  let normalizedPackages = [];
10540
10600
  if (hasExplicitPackages) {
10541
- const explicitPackageSlugs = (command32.packages ?? []).map(
10601
+ const explicitPackageSlugs = (command35.packages ?? []).map(
10542
10602
  displayableParsedPackageSlug
10543
10603
  );
10544
10604
  normalizedPackages = await this.normalizePackageSlugs(explicitPackageSlugs);
@@ -10568,8 +10628,8 @@ var InstallUseCase = class {
10568
10628
  }
10569
10629
  return result;
10570
10630
  }
10571
- const installAgents = this.resolveInstallAgents(command32, config);
10572
- const stripPathPrefix = command32.homeAgent ? getAgentHomeDirPrefix(command32.homeAgent) ?? void 0 : void 0;
10631
+ const installAgents = this.resolveInstallAgents(command35, config);
10632
+ const stripPathPrefix = command35.homeAgent ? getAgentHomeDirPrefix(command35.homeAgent) ?? void 0 : void 0;
10573
10633
  const response = await this.packmindGateway.deployment.install({
10574
10634
  packagesSlugs,
10575
10635
  packmindLockFile: effectiveLockFile,
@@ -10709,7 +10769,7 @@ var InstallUseCase = class {
10709
10769
  } catch {
10710
10770
  }
10711
10771
  }
10712
- lockFileToPersist.cliVersion = command32.cliVersion;
10772
+ lockFileToPersist.cliVersion = command35.cliVersion;
10713
10773
  if (stripPathPrefix) {
10714
10774
  lockFileToPersist = this.stripLockFileArtifactPaths(
10715
10775
  lockFileToPersist,
@@ -10738,9 +10798,9 @@ var InstallUseCase = class {
10738
10798
  async normalizePackageSlugs(slugs) {
10739
10799
  return normalizePackageSlugs(slugs, this.spaceService);
10740
10800
  }
10741
- resolveInstallAgents(command32, config) {
10742
- if (command32.homeAgent) {
10743
- return [command32.homeAgent];
10801
+ resolveInstallAgents(command35, config) {
10802
+ if (command35.homeAgent) {
10803
+ return [command35.homeAgent];
10744
10804
  }
10745
10805
  return config?.agents;
10746
10806
  }
@@ -11054,8 +11114,8 @@ var UninstallUseCase = class {
11054
11114
  this.spaceService = spaceService;
11055
11115
  this.installUseCase = installUseCase;
11056
11116
  }
11057
- async execute(command32) {
11058
- const baseDirectory = command32.baseDirectory || process.cwd();
11117
+ async execute(command35) {
11118
+ const baseDirectory = command35.baseDirectory || process.cwd();
11059
11119
  const config = await this.configFileRepository.readConfig(baseDirectory);
11060
11120
  if (!config) {
11061
11121
  const configFileExists = await this.configFileRepository.configExists(baseDirectory);
@@ -11069,7 +11129,7 @@ var UninstallUseCase = class {
11069
11129
  );
11070
11130
  }
11071
11131
  const normalized = await normalizePackageSlugs(
11072
- command32.packages,
11132
+ command35.packages,
11073
11133
  this.spaceService
11074
11134
  );
11075
11135
  const notInstalled = normalized.filter((pkg) => !(pkg in config.packages));
@@ -11092,7 +11152,7 @@ ${pkgList}`
11092
11152
  try {
11093
11153
  return await this.installUseCase.execute({
11094
11154
  baseDirectory,
11095
- cliVersion: command32.cliVersion
11155
+ cliVersion: command35.cliVersion
11096
11156
  });
11097
11157
  } catch (error) {
11098
11158
  await this.configFileRepository.updateConfig(
@@ -11134,8 +11194,8 @@ var InstallDefaultSkillsUseCase = class {
11134
11194
  constructor(repositories) {
11135
11195
  this.repositories = repositories;
11136
11196
  }
11137
- async execute(command32) {
11138
- const baseDirectory = command32.baseDirectory || process.cwd();
11197
+ async execute(command35) {
11198
+ const baseDirectory = command35.baseDirectory || process.cwd();
11139
11199
  await this.bootstrapEmptyDirectory(baseDirectory);
11140
11200
  const result = {
11141
11201
  filesCreated: 0,
@@ -11145,24 +11205,24 @@ var InstallDefaultSkillsUseCase = class {
11145
11205
  skippedIncompatibleSkillNames: [],
11146
11206
  incompatibleInstalledSkills: []
11147
11207
  };
11148
- let agents = command32.agents;
11208
+ let agents = command35.agents;
11149
11209
  if (!agents || agents.length === 0) {
11150
11210
  const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
11151
11211
  agents = config?.agents;
11152
11212
  }
11153
11213
  const response = await this.repositories.packmindGateway.skills.getDefaults(
11154
11214
  {
11155
- cliVersion: command32.cliVersion,
11156
- includeBeta: command32.includeBeta,
11215
+ cliVersion: command35.cliVersion,
11216
+ includeBeta: command35.includeBeta,
11157
11217
  agents
11158
11218
  }
11159
11219
  );
11160
11220
  result.skippedSkillsCount = response.skippedSkillsCount;
11161
11221
  const incompatibleInstalledMap = /* @__PURE__ */ new Map();
11162
11222
  const incompatibleSkillDirs = /* @__PURE__ */ new Map();
11163
- if (command32.cliVersion) {
11223
+ if (command35.cliVersion) {
11164
11224
  for (const file of response.fileUpdates.createOrUpdate) {
11165
- if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command32.cliVersion)) {
11225
+ if (path9.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command35.cliVersion)) {
11166
11226
  const dir = path9.dirname(file.path);
11167
11227
  const skillName = this.getSkillName(file.content) ?? path9.basename(dir);
11168
11228
  incompatibleSkillDirs.set(dir, skillName);
@@ -11173,9 +11233,9 @@ var InstallDefaultSkillsUseCase = class {
11173
11233
  for (const file of response.fileUpdates.createOrUpdate) {
11174
11234
  try {
11175
11235
  if (!file.content) continue;
11176
- const isIncompatible = command32.cliVersion && (this.isVersionConstraintViolated(
11236
+ const isIncompatible = command35.cliVersion && (this.isVersionConstraintViolated(
11177
11237
  file.content,
11178
- command32.cliVersion
11238
+ command35.cliVersion
11179
11239
  ) || this.isUnderIncompatibleSkillDir(
11180
11240
  file.path,
11181
11241
  incompatibleSkillDirs
@@ -11218,7 +11278,7 @@ var InstallDefaultSkillsUseCase = class {
11218
11278
  await this.mergeLockFileSlice(
11219
11279
  baseDirectory,
11220
11280
  response.lockFileSlice ?? {},
11221
- command32.cliVersion
11281
+ command35.cliVersion
11222
11282
  );
11223
11283
  return result;
11224
11284
  }
@@ -11372,8 +11432,8 @@ var EnsureCliVersionUseCase = class {
11372
11432
  this.lockFileRepository = lockFileRepository;
11373
11433
  this.installDefaultSkillsUseCase = installDefaultSkillsUseCase;
11374
11434
  }
11375
- async execute(command32) {
11376
- const { baseDirectory, currentCliVersion, includeBeta } = command32;
11435
+ async execute(command35) {
11436
+ const { baseDirectory, currentCliVersion, includeBeta } = command35;
11377
11437
  const lockFile = await this.lockFileRepository.read(baseDirectory);
11378
11438
  if (!lockFile) {
11379
11439
  return { kind: "no-lockfile" };
@@ -11409,10 +11469,10 @@ var ListPackagesUseCase = class {
11409
11469
  this.packmindGateway = packmindGateway;
11410
11470
  this.spaceService = spaceService;
11411
11471
  }
11412
- async execute(command32) {
11413
- if (command32.spaceId) {
11472
+ async execute(command35) {
11473
+ if (command35.spaceId) {
11414
11474
  const response = await this.packmindGateway.packages.list({
11415
- spaceId: command32.spaceId
11475
+ spaceId: command35.spaceId
11416
11476
  });
11417
11477
  return response.packages;
11418
11478
  }
@@ -11431,8 +11491,8 @@ var GetPackageSummaryUseCase = class {
11431
11491
  constructor(gateway) {
11432
11492
  this.gateway = gateway;
11433
11493
  }
11434
- async execute(command32) {
11435
- return this.gateway.packages.getSummary(command32);
11494
+ async execute(command35) {
11495
+ return this.gateway.packages.getSummary(command35);
11436
11496
  }
11437
11497
  };
11438
11498
 
@@ -11724,8 +11784,8 @@ var LoginUseCase = class {
11724
11784
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
11725
11785
  };
11726
11786
  }
11727
- async execute(command32) {
11728
- const { host, code: providedCode } = command32;
11787
+ async execute(command35) {
11788
+ const { host, code: providedCode } = command35;
11729
11789
  let code;
11730
11790
  if (providedCode) {
11731
11791
  code = providedCode;
@@ -12107,10 +12167,10 @@ var CheckCliVersionUseCase = class {
12107
12167
  now: deps?.now ?? (() => /* @__PURE__ */ new Date())
12108
12168
  };
12109
12169
  }
12110
- async execute(command32) {
12111
- const cached = this.readFreshCache(command32.currentVersion);
12170
+ async execute(command35) {
12171
+ const cached = this.readFreshCache(command35.currentVersion);
12112
12172
  if (cached) {
12113
- return this.toResult(command32.currentVersion, cached.latestVersion);
12173
+ return this.toResult(command35.currentVersion, cached.latestVersion);
12114
12174
  }
12115
12175
  const fetchPromise = this.deps.fetchLatestVersion(this.deps.fetchFn);
12116
12176
  fetchPromise.catch(() => void 0);
@@ -12128,7 +12188,7 @@ var CheckCliVersionUseCase = class {
12128
12188
  latestVersion,
12129
12189
  checkedAt: this.deps.now()
12130
12190
  });
12131
- return this.toResult(command32.currentVersion, latestVersion);
12191
+ return this.toResult(command35.currentVersion, latestVersion);
12132
12192
  } catch {
12133
12193
  return null;
12134
12194
  }
@@ -12576,10 +12636,10 @@ var ListStandardsUseCase = class {
12576
12636
  this.packmindGateway = packmindGateway;
12577
12637
  this.spaceService = spaceService;
12578
12638
  }
12579
- async execute(command32) {
12580
- if (command32.spaceId) {
12639
+ async execute(command35) {
12640
+ if (command35.spaceId) {
12581
12641
  const response = await this.packmindGateway.standards.list({
12582
- spaceId: command32.spaceId
12642
+ spaceId: command35.spaceId
12583
12643
  });
12584
12644
  return response.standards;
12585
12645
  }
@@ -12599,10 +12659,10 @@ var ListCommandsUseCase = class {
12599
12659
  this.packmindGateway = packmindGateway;
12600
12660
  this.spaceService = spaceService;
12601
12661
  }
12602
- async execute(command32) {
12603
- if (command32.spaceId) {
12662
+ async execute(command35) {
12663
+ if (command35.spaceId) {
12604
12664
  const response = await this.packmindGateway.commands.list({
12605
- spaceId: command32.spaceId
12665
+ spaceId: command35.spaceId
12606
12666
  });
12607
12667
  return response.recipes;
12608
12668
  }
@@ -12622,10 +12682,10 @@ var ListSkillsUseCase = class {
12622
12682
  this.packmindGateway = packmindGateway;
12623
12683
  this.spaceService = spaceService;
12624
12684
  }
12625
- async execute(command32) {
12626
- if (command32.spaceId) {
12685
+ async execute(command35) {
12686
+ if (command35.spaceId) {
12627
12687
  const skills = await this.packmindGateway.skills.list({
12628
- spaceId: command32.spaceId
12688
+ spaceId: command35.spaceId
12629
12689
  });
12630
12690
  return skills.map((s) => ({
12631
12691
  id: s.id,
@@ -12797,8 +12857,8 @@ var UploadSkillUseCase = class {
12797
12857
  constructor(deps) {
12798
12858
  this.deps = deps;
12799
12859
  }
12800
- async execute(command32) {
12801
- const files = await readSkillDirectory(command32.skillPath);
12860
+ async execute(command35) {
12861
+ const files = await readSkillDirectory(command35.skillPath);
12802
12862
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
12803
12863
  throw new Error("SKILL.md not found in skill directory");
12804
12864
  }
@@ -12812,7 +12872,7 @@ var UploadSkillUseCase = class {
12812
12872
  if (totalSize > 10 * 1024 * 1024) {
12813
12873
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
12814
12874
  }
12815
- const space = await this.getSpace(command32.spaceSlug);
12875
+ const space = await this.getSpace(command35.spaceSlug);
12816
12876
  const payload = {
12817
12877
  files: files.map((f) => ({
12818
12878
  path: f.relativePath,
@@ -12824,7 +12884,7 @@ var UploadSkillUseCase = class {
12824
12884
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
12825
12885
  spaceId: createSpaceId(space.id),
12826
12886
  files: payload.files,
12827
- originSkill: command32.originSkill
12887
+ originSkill: command35.originSkill
12828
12888
  });
12829
12889
  return {
12830
12890
  skillId: uploadSkillResponse.skill.id,
@@ -13433,34 +13493,43 @@ function parsePackmindStandard(content) {
13433
13493
  if (!name) {
13434
13494
  return null;
13435
13495
  }
13496
+ let scopeLineIndex = -1;
13436
13497
  let rulesLineIndex = -1;
13437
13498
  for (let i = nameLineIndex + 1; i < lines.length; i++) {
13438
- if (lines[i].trim() === "## Rules") {
13499
+ const trimmed = lines[i].trim();
13500
+ if (scopeLineIndex < 0 && trimmed === SCOPE_HEADING) {
13501
+ scopeLineIndex = i;
13502
+ } else if (rulesLineIndex < 0 && trimmed === RULES_HEADING) {
13439
13503
  rulesLineIndex = i;
13440
- break;
13441
13504
  }
13442
13505
  }
13506
+ const scopeSection = scopeLineIndex >= 0 ? extractScopeSection(lines, scopeLineIndex + 1, rulesLineIndex < 0) : null;
13507
+ const sectionIndexes = [scopeLineIndex, rulesLineIndex].filter(
13508
+ (index) => index >= 0
13509
+ );
13510
+ const descriptionEnd = sectionIndexes.length ? Math.min(...sectionIndexes) : lines.length;
13443
13511
  const descriptionLines = [];
13444
- let rulesStartIndex = -1;
13445
- if (rulesLineIndex >= 0) {
13446
- for (let i = nameLineIndex + 1; i < rulesLineIndex; i++) {
13447
- descriptionLines.push(lines[i]);
13512
+ let rulesStartIndex = rulesLineIndex >= 0 ? rulesLineIndex + 1 : -1;
13513
+ for (let i = nameLineIndex + 1; i < descriptionEnd; i++) {
13514
+ if (rulesStartIndex < 0 && isRuleBullet(lines[i])) {
13515
+ rulesStartIndex = i;
13516
+ break;
13448
13517
  }
13449
- rulesStartIndex = rulesLineIndex + 1;
13450
- } else {
13451
- for (let i = nameLineIndex + 1; i < lines.length; i++) {
13452
- if (lines[i].startsWith("* ") || lines[i].startsWith("- ")) {
13518
+ descriptionLines.push(lines[i]);
13519
+ }
13520
+ if (rulesStartIndex < 0 && scopeSection) {
13521
+ for (let i = scopeSection.endIndex; i < lines.length; i++) {
13522
+ if (isRuleBullet(lines[i])) {
13453
13523
  rulesStartIndex = i;
13454
13524
  break;
13455
13525
  }
13456
- descriptionLines.push(lines[i]);
13457
13526
  }
13458
13527
  }
13459
13528
  const rules = extractRulesList(lines, rulesStartIndex);
13460
13529
  return {
13461
13530
  name,
13462
13531
  description: descriptionLines.join("\n").trim(),
13463
- scope: "",
13532
+ scope: scopeSection?.value ?? "",
13464
13533
  rules
13465
13534
  };
13466
13535
  }
@@ -13494,12 +13563,30 @@ function parseCopilotStandard(content) {
13494
13563
  return parseIdeStandardBody(body, scope);
13495
13564
  }
13496
13565
  var RULES_FALLBACK = "No rules defined yet.";
13566
+ var SCOPE_HEADING = "## Scope";
13567
+ var RULES_HEADING = "## Rules";
13568
+ function isRuleBullet(line) {
13569
+ return line.startsWith("* ") || line.startsWith("- ");
13570
+ }
13571
+ function extractScopeSection(lines, startIndex, stopAtBullet) {
13572
+ const patterns = [];
13573
+ let index = startIndex;
13574
+ for (; index < lines.length; index++) {
13575
+ const line = lines[index];
13576
+ if (line.startsWith("## ")) break;
13577
+ if (stopAtBullet && isRuleBullet(line)) break;
13578
+ const trimmed = line.trim();
13579
+ if (!trimmed) continue;
13580
+ patterns.push(isRuleBullet(trimmed) ? trimmed.slice(2).trim() : trimmed);
13581
+ }
13582
+ return { value: patterns.join(", "), endIndex: index };
13583
+ }
13497
13584
  function extractRulesList(lines, startIndex) {
13498
13585
  if (startIndex < 0) return [];
13499
13586
  const rules = [];
13500
13587
  for (let i = startIndex; i < lines.length; i++) {
13501
13588
  const line = lines[i];
13502
- if (line.startsWith("* ") || line.startsWith("- ")) {
13589
+ if (isRuleBullet(line)) {
13503
13590
  const content = line.slice(2).trim();
13504
13591
  if (content && content !== RULES_FALLBACK) {
13505
13592
  rules.push(content);
@@ -13550,7 +13637,7 @@ function parseIdeStandardBody(body, scope) {
13550
13637
  const descriptionLines = [];
13551
13638
  let rulesStartIndex = -1;
13552
13639
  for (let i = nameLineIndex + 1; i < lines.length; i++) {
13553
- if (lines[i].startsWith("* ") || lines[i].startsWith("- ")) {
13640
+ if (isRuleBullet(lines[i])) {
13554
13641
  rulesStartIndex = i;
13555
13642
  break;
13556
13643
  }
@@ -13814,9 +13901,9 @@ var DiffArtefactsUseCase = class {
13814
13901
  new StandardDiffStrategy()
13815
13902
  ];
13816
13903
  }
13817
- async execute(command32) {
13818
- const baseDirectory = command32.baseDirectory || process.cwd();
13819
- const response = await this.fetchContent(command32, baseDirectory);
13904
+ async execute(command35) {
13905
+ const baseDirectory = command35.baseDirectory || process.cwd();
13906
+ const response = await this.fetchContent(command35, baseDirectory);
13820
13907
  const filteredFiles = response.fileUpdates.createOrUpdate.filter(
13821
13908
  (file) => file.path !== "packmind.json"
13822
13909
  );
@@ -13829,7 +13916,7 @@ var DiffArtefactsUseCase = class {
13829
13916
  );
13830
13917
  const prefixedSkillFolders = this.prefixSkillFolders(
13831
13918
  response.skillFolders,
13832
- command32.relativePath
13919
+ command35.relativePath
13833
13920
  );
13834
13921
  const diffs = [];
13835
13922
  for (const file of diffableFiles) {
@@ -13856,7 +13943,7 @@ var DiffArtefactsUseCase = class {
13856
13943
  targetId: response.targetId ? createTargetId(response.targetId) : void 0
13857
13944
  }));
13858
13945
  }
13859
- async fetchContent(command32, baseDirectory) {
13946
+ async fetchContent(command35, baseDirectory) {
13860
13947
  const lockFile = await this.lockFileRepository.read(baseDirectory);
13861
13948
  if (lockFile) {
13862
13949
  try {
@@ -13876,11 +13963,11 @@ var DiffArtefactsUseCase = class {
13876
13963
  }
13877
13964
  }
13878
13965
  return this.packmindGateway.deployment.getDeployed({
13879
- packagesSlugs: command32.packagesSlugs,
13880
- gitRemoteUrl: command32.gitRemoteUrl,
13881
- gitBranch: command32.gitBranch,
13882
- relativePath: command32.relativePath,
13883
- agents: command32.agents
13966
+ packagesSlugs: command35.packagesSlugs,
13967
+ gitRemoteUrl: command35.gitRemoteUrl,
13968
+ gitBranch: command35.gitBranch,
13969
+ relativePath: command35.relativePath,
13970
+ agents: command35.agents
13884
13971
  });
13885
13972
  }
13886
13973
  prefixSkillFolders(skillFolders, relativePath) {
@@ -13904,8 +13991,8 @@ var SubmitDiffsUseCase = class {
13904
13991
  constructor(packmindGateway) {
13905
13992
  this.packmindGateway = packmindGateway;
13906
13993
  }
13907
- async execute(command32) {
13908
- const { groupedDiffs, message } = command32;
13994
+ async execute(command35) {
13995
+ const { groupedDiffs, message } = command35;
13909
13996
  const skipped = [];
13910
13997
  const validDiffs = [];
13911
13998
  for (const group of groupedDiffs) {
@@ -13980,8 +14067,8 @@ var CheckDiffsUseCase = class {
13980
14067
  constructor(packmindGateway) {
13981
14068
  this.packmindGateway = packmindGateway;
13982
14069
  }
13983
- async execute(command32) {
13984
- const { groupedDiffs } = command32;
14070
+ async execute(command35) {
14071
+ const { groupedDiffs } = command35;
13985
14072
  const results = [];
13986
14073
  const validDiffs = [];
13987
14074
  const invalidDiffs = [];
@@ -14079,8 +14166,8 @@ var CliFormatter = class {
14079
14166
  static error(message) {
14080
14167
  return `${source_default.bgRed.bold(CLI_PREFIX2)} ${source_default.red(message)}`;
14081
14168
  }
14082
- static command(command32) {
14083
- return source_default.yellow(command32);
14169
+ static command(command35) {
14170
+ return source_default.yellow(command35);
14084
14171
  }
14085
14172
  static loader(text) {
14086
14173
  return source_default.dim.italic(text);
@@ -14225,7 +14312,7 @@ var TrackRepositoryUseCase = class {
14225
14312
  this.gateway = gateway;
14226
14313
  this.gitService = gitService;
14227
14314
  }
14228
- async execute(command32) {
14315
+ async execute(command35) {
14229
14316
  const {
14230
14317
  repoPath,
14231
14318
  origin: origin9,
@@ -14233,12 +14320,18 @@ var TrackRepositoryUseCase = class {
14233
14320
  remove,
14234
14321
  branch: requestedBranch,
14235
14322
  confirm
14236
- } = command32;
14323
+ } = command35;
14237
14324
  const { gitRemoteUrl } = this.gitService.getGitRemoteUrl(repoPath);
14238
- const { branch: currentBranch } = this.gitService.getCurrentBranch(repoPath);
14325
+ const { branch: currentBranch, detached } = this.gitService.getCurrentBranch(repoPath);
14239
14326
  const branch = requestedBranch ?? currentBranch;
14240
14327
  const { owner, repo } = parseOwnerRepo(gitRemoteUrl);
14241
14328
  const providerVendor = parseProviderVendor(gitRemoteUrl);
14329
+ if (detached && !requestedBranch && !remove) {
14330
+ return { status: "detached-head", owner, repo };
14331
+ }
14332
+ if (requestedBranch && !this.gitService.branchExists(repoPath, requestedBranch)) {
14333
+ return { status: "branch-not-found", owner, repo, branch };
14334
+ }
14242
14335
  const { gitRepo: tracked } = await this.gateway.getTrackedRepository({
14243
14336
  owner,
14244
14337
  repo
@@ -14333,6 +14426,45 @@ var TrackRepositoryUseCase = class {
14333
14426
  }
14334
14427
  };
14335
14428
 
14429
+ // apps/cli/src/application/useCases/trackRepository/GetTrackingInfoUseCase.ts
14430
+ var GetTrackingInfoUseCase = class {
14431
+ constructor(gateway, gitService) {
14432
+ this.gateway = gateway;
14433
+ this.gitService = gitService;
14434
+ }
14435
+ async execute({
14436
+ repoPath
14437
+ }) {
14438
+ const { gitRemoteUrl } = this.gitService.getGitRemoteUrl(repoPath);
14439
+ const { branch: currentBranch, detached: currentBranchDetached } = this.gitService.getCurrentBranch(repoPath);
14440
+ const { owner, repo } = parseOwnerRepo(gitRemoteUrl);
14441
+ const { gitRepo } = await this.gateway.getTrackedRepository({
14442
+ owner,
14443
+ repo
14444
+ });
14445
+ if (!gitRepo) {
14446
+ return {
14447
+ status: "not-tracked",
14448
+ owner,
14449
+ repo,
14450
+ currentBranch,
14451
+ currentBranchDetached
14452
+ };
14453
+ }
14454
+ return {
14455
+ status: "tracked",
14456
+ owner,
14457
+ repo,
14458
+ trackedBranch: gitRepo.branch,
14459
+ currentBranch,
14460
+ currentBranchDetached,
14461
+ // Skipped when it is the branch we are on: being on it proves it exists,
14462
+ // and this is the common case, so it saves a git call.
14463
+ trackedBranchExists: gitRepo.branch === currentBranch || this.gitService.branchExists(repoPath, gitRepo.branch)
14464
+ };
14465
+ }
14466
+ };
14467
+
14336
14468
  // apps/cli/src/PackmindCliHexaFactory.ts
14337
14469
  var PackmindCliHexaFactory = class {
14338
14470
  constructor() {
@@ -14422,6 +14554,10 @@ var PackmindCliHexaFactory = class {
14422
14554
  trackRepository: new TrackRepositoryUseCase(
14423
14555
  this.repositories.packmindGateway.repositoryTracking,
14424
14556
  this.services.gitRemoteUrlService
14557
+ ),
14558
+ getTrackingInfo: new GetTrackingInfoUseCase(
14559
+ this.repositories.packmindGateway.repositoryTracking,
14560
+ this.services.gitRemoteUrlService
14425
14561
  )
14426
14562
  };
14427
14563
  }
@@ -14431,29 +14567,29 @@ var PackmindCliHexaFactory = class {
14431
14567
  var origin8 = "PackmindCliHexa";
14432
14568
  var PackmindCliHexa = class {
14433
14569
  constructor(logger2 = new PackmindLogger(origin8)) {
14434
- this.notifyDistribution = async (command32) => {
14570
+ this.notifyDistribution = async (command35) => {
14435
14571
  return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
14436
- command32
14572
+ command35
14437
14573
  );
14438
14574
  };
14439
- this.notifyArtefactsDistribution = async (command32) => {
14575
+ this.notifyArtefactsDistribution = async (command35) => {
14440
14576
  return this.hexa.repositories.packmindGateway.deployment.notifyArtefactsDistribution(
14441
- command32
14577
+ command35
14442
14578
  );
14443
14579
  };
14444
- this.getTrackedRepository = async (command32) => {
14580
+ this.getTrackedRepository = async (command35) => {
14445
14581
  return this.hexa.repositories.packmindGateway.repositoryTracking.getTrackedRepository(
14446
- command32
14582
+ command35
14447
14583
  );
14448
14584
  };
14449
- this.renderPlugin = async (command32) => {
14585
+ this.renderPlugin = async (command35) => {
14450
14586
  return this.hexa.repositories.packmindGateway.deployment.renderPlugin(
14451
- command32
14587
+ command35
14452
14588
  );
14453
14589
  };
14454
- this.trackPluginDeleted = async (command32) => {
14590
+ this.trackPluginDeleted = async (command35) => {
14455
14591
  return this.hexa.repositories.packmindGateway.deployment.trackPluginDeleted(
14456
- command32
14592
+ command35
14457
14593
  );
14458
14594
  };
14459
14595
  this.logger = logger2;
@@ -14476,29 +14612,29 @@ var PackmindCliHexa = class {
14476
14612
  get output() {
14477
14613
  return this.hexa.repositories.output;
14478
14614
  }
14479
- async getGitRemoteUrl(command32) {
14480
- return this.hexa.useCases.getGitRemoteUrl.execute(command32);
14615
+ async getGitRemoteUrl(command35) {
14616
+ return this.hexa.useCases.getGitRemoteUrl.execute(command35);
14481
14617
  }
14482
- async listFilesInDirectory(command32) {
14483
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command32);
14618
+ async listFilesInDirectory(command35) {
14619
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command35);
14484
14620
  }
14485
- async lintFilesAgainstRule(command32) {
14486
- return this.hexa.useCases.lintFilesAgainstRule.execute(command32);
14621
+ async lintFilesAgainstRule(command35) {
14622
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command35);
14487
14623
  }
14488
- async lintFilesFromConfig(command32) {
14489
- return this.hexa.useCases.lintFilesFromConfig.execute(command32);
14624
+ async lintFilesFromConfig(command35) {
14625
+ return this.hexa.useCases.lintFilesFromConfig.execute(command35);
14490
14626
  }
14491
- async installPackages(command32) {
14492
- return this.hexa.useCases.installPackages.execute(command32);
14627
+ async installPackages(command35) {
14628
+ return this.hexa.useCases.installPackages.execute(command35);
14493
14629
  }
14494
- async install(command32) {
14495
- return this.hexa.useCases.install.execute(command32);
14630
+ async install(command35) {
14631
+ return this.hexa.useCases.install.execute(command35);
14496
14632
  }
14497
- async uninstall(command32) {
14498
- return this.hexa.useCases.uninstall.execute(command32);
14633
+ async uninstall(command35) {
14634
+ return this.hexa.useCases.uninstall.execute(command35);
14499
14635
  }
14500
- async diffArtefacts(command32) {
14501
- return this.hexa.useCases.diffArtefacts.execute(command32);
14636
+ async diffArtefacts(command35) {
14637
+ return this.hexa.useCases.diffArtefacts.execute(command35);
14502
14638
  }
14503
14639
  async submitDiffs(groupedDiffs, message) {
14504
14640
  return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
@@ -14506,20 +14642,20 @@ var PackmindCliHexa = class {
14506
14642
  async checkDiffs(groupedDiffs) {
14507
14643
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
14508
14644
  }
14509
- async listPackages(command32) {
14510
- return this.hexa.useCases.listPackages.execute(command32);
14645
+ async listPackages(command35) {
14646
+ return this.hexa.useCases.listPackages.execute(command35);
14511
14647
  }
14512
- async getPackageBySlug(command32) {
14513
- return this.hexa.useCases.getPackageBySlug.execute(command32);
14648
+ async getPackageBySlug(command35) {
14649
+ return this.hexa.useCases.getPackageBySlug.execute(command35);
14514
14650
  }
14515
- async listStandards(command32) {
14516
- return this.hexa.useCases.listStandards.execute(command32);
14651
+ async listStandards(command35) {
14652
+ return this.hexa.useCases.listStandards.execute(command35);
14517
14653
  }
14518
- async listCommands(command32) {
14519
- return this.hexa.useCases.listCommands.execute(command32);
14654
+ async listCommands(command35) {
14655
+ return this.hexa.useCases.listCommands.execute(command35);
14520
14656
  }
14521
- async listSkills(command32) {
14522
- return this.hexa.useCases.listSkills.execute(command32);
14657
+ async listSkills(command35) {
14658
+ return this.hexa.useCases.listSkills.execute(command35);
14523
14659
  }
14524
14660
  async configExists(baseDirectory) {
14525
14661
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -14606,40 +14742,52 @@ var PackmindCliHexa = class {
14606
14742
  directory
14607
14743
  );
14608
14744
  }
14609
- async login(command32) {
14610
- return this.hexa.useCases.login.execute(command32);
14745
+ async login(command35) {
14746
+ return this.hexa.useCases.login.execute(command35);
14611
14747
  }
14612
- async logout(command32) {
14613
- return this.hexa.useCases.logout.execute(command32);
14748
+ async logout(command35) {
14749
+ return this.hexa.useCases.logout.execute(command35);
14614
14750
  }
14615
- async whoami(command32) {
14616
- return this.hexa.useCases.whoami.execute(command32);
14751
+ async whoami(command35) {
14752
+ return this.hexa.useCases.whoami.execute(command35);
14617
14753
  }
14618
- async checkCliVersion(command32) {
14619
- return this.hexa.useCases.checkCliVersion.execute(command32);
14754
+ async checkCliVersion(command35) {
14755
+ return this.hexa.useCases.checkCliVersion.execute(command35);
14620
14756
  }
14621
14757
  getCurrentBranch(repoPath) {
14622
14758
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
14623
14759
  }
14760
+ isDetachedHead(repoPath) {
14761
+ return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).detached;
14762
+ }
14763
+ branchExists(repoPath, branch) {
14764
+ return this.hexa.services.gitRemoteUrlService.branchExists(
14765
+ repoPath,
14766
+ branch
14767
+ );
14768
+ }
14624
14769
  getGitRemoteUrlFromPath(repoPath) {
14625
14770
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
14626
14771
  }
14627
- async uploadSkill(command32) {
14628
- return this.hexa.useCases.uploadSkill.execute(command32);
14772
+ async uploadSkill(command35) {
14773
+ return this.hexa.useCases.uploadSkill.execute(command35);
14629
14774
  }
14630
- async installDefaultSkills(command32) {
14631
- return this.hexa.useCases.installDefaultSkills.execute(command32);
14775
+ async installDefaultSkills(command35) {
14776
+ return this.hexa.useCases.installDefaultSkills.execute(command35);
14632
14777
  }
14633
- async bootstrapSkillsInitDirectory(command32) {
14778
+ async bootstrapSkillsInitDirectory(command35) {
14634
14779
  return this.hexa.useCases.installDefaultSkills.bootstrapEmptyDirectory(
14635
- command32.baseDirectory
14780
+ command35.baseDirectory
14636
14781
  );
14637
14782
  }
14638
- async ensureCliVersion(command32) {
14639
- return this.hexa.useCases.ensureCliVersion.execute(command32);
14783
+ async ensureCliVersion(command35) {
14784
+ return this.hexa.useCases.ensureCliVersion.execute(command35);
14640
14785
  }
14641
- async trackRepository(command32) {
14642
- return this.hexa.useCases.trackRepository.execute(command32);
14786
+ async trackRepository(command35) {
14787
+ return this.hexa.useCases.trackRepository.execute(command35);
14788
+ }
14789
+ async getTrackingInfo(command35) {
14790
+ return this.hexa.useCases.getTrackingInfo.execute(command35);
14643
14791
  }
14644
14792
  getPackmindGateway() {
14645
14793
  return this.hexa.repositories.packmindGateway;
@@ -16125,7 +16273,7 @@ function mergeInstallResults(results) {
16125
16273
  return merged;
16126
16274
  }
16127
16275
  function decideDistributionTracking(params) {
16128
- const { lookup, currentBranch } = params;
16276
+ const { lookup, currentBranch, branchExists, detached } = params;
16129
16277
  switch (lookup.status) {
16130
16278
  case "flag-off":
16131
16279
  return { action: "record-legacy" };
@@ -16137,9 +16285,16 @@ function decideDistributionTracking(params) {
16137
16285
  return { action: "skip", reason: "repo_not_tracked" };
16138
16286
  }
16139
16287
  if (tracked.branch !== currentBranch) {
16288
+ if (!branchExists(tracked.branch)) {
16289
+ return {
16290
+ action: "skip",
16291
+ reason: "tracked_branch_gone",
16292
+ trackedBranch: tracked.branch
16293
+ };
16294
+ }
16140
16295
  return {
16141
16296
  action: "skip",
16142
- reason: "wrong_branch",
16297
+ reason: detached ? "detached_head" : "wrong_branch",
16143
16298
  trackedBranch: tracked.branch
16144
16299
  };
16145
16300
  }
@@ -16164,9 +16319,19 @@ function reportDistributionTrackingDecision(decision, context) {
16164
16319
  if (decision.reason === "repo_not_tracked") {
16165
16320
  logWarningConsole(
16166
16321
  `Distribution not recorded \u2014 ${context.owner}/${context.repo} is not tracked in Packmind. Ask an admin to run ${formatCommand(
16167
- "packmind track"
16322
+ "packmind git track"
16168
16323
  )} to start tracking it.`
16169
16324
  );
16325
+ } else if (decision.reason === "detached_head") {
16326
+ logWarningConsole(
16327
+ `Distribution not recorded \u2014 no branch is checked out here (HEAD is detached), and Packmind records distributions on '${decision.trackedBranch}'. Check that branch out to record this distribution.`
16328
+ );
16329
+ } else if (decision.reason === "tracked_branch_gone") {
16330
+ logWarningConsole(
16331
+ `Distribution not recorded \u2014 the tracked branch '${decision.trackedBranch}' is not in this repository, so nothing is recorded anywhere. Ask an admin to run ${formatCommand(
16332
+ "packmind git track --update"
16333
+ )} to move tracking to '${context.currentBranch}'.`
16334
+ );
16170
16335
  } else {
16171
16336
  logWarningConsole(
16172
16337
  `Distribution not recorded \u2014 you're on '${context.currentBranch}', but the tracked branch is '${decision.trackedBranch}'. Switch to '${decision.trackedBranch}' to record this distribution.`
@@ -16204,9 +16369,11 @@ async function computeDistributionTrackingDecision(packmindCliHexa, gitRoot) {
16204
16369
  let owner;
16205
16370
  let repo;
16206
16371
  let gitBranch;
16372
+ let detached;
16207
16373
  try {
16208
16374
  const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
16209
16375
  gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
16376
+ detached = packmindCliHexa.isDetachedHead(gitRoot);
16210
16377
  ({ owner, repo } = parseOwnerRepo(gitRemoteUrl));
16211
16378
  } catch {
16212
16379
  const decision2 = { action: "inform" };
@@ -16216,7 +16383,15 @@ async function computeDistributionTrackingDecision(packmindCliHexa, gitRoot) {
16216
16383
  const lookup = await resolveTrackingLookup(packmindCliHexa, owner, repo);
16217
16384
  const decision = decideDistributionTracking({
16218
16385
  lookup,
16219
- currentBranch: gitBranch
16386
+ currentBranch: gitBranch,
16387
+ branchExists: (branch) => {
16388
+ try {
16389
+ return packmindCliHexa.branchExists(gitRoot, branch);
16390
+ } catch {
16391
+ return true;
16392
+ }
16393
+ },
16394
+ detached
16220
16395
  });
16221
16396
  reportDistributionTrackingDecision(decision, {
16222
16397
  owner,
@@ -17192,15 +17367,15 @@ var CreatePackageUseCase = class {
17192
17367
  this.gateway = gateway;
17193
17368
  this.spaceService = spaceService;
17194
17369
  }
17195
- async execute(command32) {
17196
- const space = await this.getSpace(command32);
17370
+ async execute(command35) {
17371
+ const space = await this.getSpace(command35);
17197
17372
  const result = await this.gateway.packages.create({
17198
17373
  spaceId: space.id,
17199
- name: command32.name,
17200
- description: command32.description ?? "",
17374
+ name: command35.name,
17375
+ description: command35.description ?? "",
17201
17376
  recipeIds: [],
17202
17377
  standardIds: [],
17203
- originSkill: command32.originSkill
17378
+ originSkill: command35.originSkill
17204
17379
  });
17205
17380
  return {
17206
17381
  packageId: result.package.id,
@@ -17209,12 +17384,12 @@ var CreatePackageUseCase = class {
17209
17384
  spaceSlug: space.slug
17210
17385
  };
17211
17386
  }
17212
- async getSpace(command32) {
17387
+ async getSpace(command35) {
17213
17388
  const spaces = await this.spaceService.getSpaces();
17214
- if (command32.spaceSlug) {
17215
- const found = spaces.find((s) => s.slug === command32.spaceSlug);
17389
+ if (command35.spaceSlug) {
17390
+ const found = spaces.find((s) => s.slug === command35.spaceSlug);
17216
17391
  if (!found) {
17217
- throw new Error(`Space '${command32.spaceSlug}' not found.`);
17392
+ throw new Error(`Space '${command35.spaceSlug}' not found.`);
17218
17393
  }
17219
17394
  return found;
17220
17395
  }
@@ -17332,8 +17507,8 @@ var AddToPackageUseCase = class {
17332
17507
  this.gateway = gateway;
17333
17508
  this.spaceService = spaceService;
17334
17509
  }
17335
- async execute(command32) {
17336
- const { packageSlug, spaceSlug, itemType, itemSlugs } = command32;
17510
+ async execute(command35) {
17511
+ const { packageSlug, spaceSlug, itemType, itemSlugs } = command35;
17337
17512
  const space = spaceSlug ? await this.resolveSpaceBySlug(spaceSlug) : await this.spaceService.getDefaultSpace();
17338
17513
  const packages = await this.gateway.packages.list({
17339
17514
  spaceId: space.id
@@ -17354,7 +17529,7 @@ var AddToPackageUseCase = class {
17354
17529
  standardIds: [],
17355
17530
  recipeIds: [],
17356
17531
  skillIds: [],
17357
- originSkill: command32.originSkill
17532
+ originSkill: command35.originSkill
17358
17533
  };
17359
17534
  if (itemType === "standard") {
17360
17535
  addCommand.standardIds = ids.map(createStandardId);
@@ -17406,7 +17581,7 @@ var AddToPackageUseCase = class {
17406
17581
  }
17407
17582
  async findCommandBySlug(slug6, spaceId) {
17408
17583
  const commands = await this.gateway.commands.list({ spaceId });
17409
- return commands.recipes.find((command32) => command32.slug === slug6) ?? null;
17584
+ return commands.recipes.find((command35) => command35.slug === slug6) ?? null;
17410
17585
  }
17411
17586
  async findSkillBySlug(slug6, spaceId) {
17412
17587
  const skills = await this.gateway.skills.list({ spaceId });
@@ -17482,11 +17657,11 @@ async function executeAddToPackage(pkgSlug, spaceSlug, itemType, itemSlugs, useC
17482
17657
  logErrorConsole(message);
17483
17658
  if (error instanceof ItemNotFoundError) {
17484
17659
  const spaceFlag = error.spaceSlug ? ` --space ${error.spaceSlug}` : "";
17485
- const command32 = formatCommand(
17660
+ const command35 = formatCommand(
17486
17661
  `packmind-cli ${error.itemType}s list${spaceFlag}`
17487
17662
  );
17488
17663
  logInfoConsole(
17489
- `Run \`${command32}\` to display available ${error.itemType}s`
17664
+ `Run \`${command35}\` to display available ${error.itemType}s`
17490
17665
  );
17491
17666
  }
17492
17667
  return { success: false, error: message };
@@ -17746,8 +17921,8 @@ ${pkg.name} (${fullSlug}):
17746
17921
  }
17747
17922
  if (pkg.commands && pkg.commands.length > 0) {
17748
17923
  logConsole("Commands:");
17749
- pkg.commands.forEach((command32) => {
17750
- logConsole(` - ${command32.name}`);
17924
+ pkg.commands.forEach((command35) => {
17925
+ logConsole(` - ${command35.name}`);
17751
17926
  });
17752
17927
  logConsole("");
17753
17928
  }
@@ -17818,19 +17993,34 @@ var import_path6 = require("path");
17818
17993
  var import_fs21 = require("fs");
17819
17994
  var import_path5 = require("path");
17820
17995
  function detectPluginMode(cwd) {
17821
- const marketplace = (0, import_path5.join)(cwd, ".claude-plugin/marketplace.json");
17996
+ const claudeMarketplace = (0, import_path5.join)(cwd, ".claude-plugin/marketplace.json");
17997
+ const copilotMarketplace = (0, import_path5.join)(cwd, ".github/plugin/marketplace.json");
17822
17998
  const standalone = (0, import_path5.join)(cwd, ".claude-plugin/plugin.json");
17823
- if ((0, import_fs21.existsSync)(marketplace)) {
17824
- return { mode: "marketplace", manifestPath: marketplace };
17999
+ if ((0, import_fs21.existsSync)(claudeMarketplace)) {
18000
+ return {
18001
+ mode: "marketplace",
18002
+ vendor: "claude",
18003
+ manifestPath: claudeMarketplace
18004
+ };
18005
+ }
18006
+ if ((0, import_fs21.existsSync)(copilotMarketplace)) {
18007
+ return {
18008
+ mode: "marketplace",
18009
+ vendor: "copilot",
18010
+ manifestPath: copilotMarketplace
18011
+ };
17825
18012
  }
17826
18013
  if ((0, import_fs21.existsSync)(standalone)) {
17827
- return { mode: "standalone", manifestPath: standalone };
18014
+ return { mode: "standalone", vendor: "claude", manifestPath: standalone };
17828
18015
  }
17829
18016
  return { mode: "none" };
17830
18017
  }
18018
+ function stripBom(content) {
18019
+ return content.charCodeAt(0) === 65279 ? content.slice(1) : content;
18020
+ }
17831
18021
  function readMarketplace(path37) {
17832
18022
  const raw = (0, import_fs21.readFileSync)(path37, "utf8");
17833
- const parsed = JSON.parse(raw);
18023
+ const parsed = JSON.parse(stripBom(raw));
17834
18024
  return { ...parsed, plugins: parsed.plugins ?? [] };
17835
18025
  }
17836
18026
  function writeMarketplace(path37, content) {
@@ -17884,7 +18074,7 @@ async function renderPluginHandler(args2, deps) {
17884
18074
  const ctx = detectPluginMode(cwd);
17885
18075
  if (ctx.mode === "none") {
17886
18076
  deps.error(
17887
- "No .claude-plugin/marketplace.json or .claude-plugin/plugin.json found in this directory."
18077
+ "No .claude-plugin/marketplace.json, .github/plugin/marketplace.json, or .claude-plugin/plugin.json found in this directory."
17888
18078
  );
17889
18079
  deps.exit(1);
17890
18080
  return;
@@ -17897,7 +18087,17 @@ async function renderPluginHandler(args2, deps) {
17897
18087
  );
17898
18088
  if (ctx.mode === "marketplace") {
17899
18089
  const manifestPath = ctx.manifestPath;
17900
- const marketplace = readMarketplace(manifestPath);
18090
+ const targetVendor = ctx.vendor === "copilot" ? "github" : "anthropic";
18091
+ let marketplace;
18092
+ try {
18093
+ marketplace = readMarketplace(manifestPath);
18094
+ } catch {
18095
+ deps.error(
18096
+ `${manifestPath} is not valid JSON. Fix the file and try again.`
18097
+ );
18098
+ deps.exit(1);
18099
+ return;
18100
+ }
17901
18101
  const existing = findPluginEntry(marketplace, pluginName);
17902
18102
  if (existing) {
17903
18103
  if (classifySource(existing.source) === "remote") {
@@ -17923,7 +18123,8 @@ async function renderPluginHandler(args2, deps) {
17923
18123
  pluginRoot: existingPluginRoot,
17924
18124
  pluginName,
17925
18125
  gitRemoteUrl,
17926
- gitBranch
18126
+ gitBranch,
18127
+ targetVendor
17927
18128
  });
17928
18129
  writeFiles(cwd, response2.files);
17929
18130
  const nextEntry = {
@@ -17946,7 +18147,8 @@ async function renderPluginHandler(args2, deps) {
17946
18147
  pluginRoot,
17947
18148
  pluginName,
17948
18149
  gitRemoteUrl,
17949
- gitBranch
18150
+ gitBranch,
18151
+ targetVendor
17950
18152
  });
17951
18153
  writeFiles(cwd, response.files);
17952
18154
  const updated = upsertPluginEntry(marketplace, {
@@ -17963,7 +18165,9 @@ async function renderPluginHandler(args2, deps) {
17963
18165
  }
17964
18166
  if (ctx.mode === "standalone") {
17965
18167
  const manifestPath = ctx.manifestPath;
17966
- const manifest = JSON.parse((0, import_fs22.readFileSync)(manifestPath, "utf8"));
18168
+ const manifest = JSON.parse(
18169
+ stripBom((0, import_fs22.readFileSync)(manifestPath, "utf8"))
18170
+ );
17967
18171
  if (manifest.name !== pluginName) {
17968
18172
  deps.error(`The plugin '${pluginName}' is not handled in this repo.`);
17969
18173
  deps.exit(1);
@@ -18062,7 +18266,7 @@ async function deletePluginHandler(args2, deps) {
18062
18266
  const ctx = detectPluginMode(cwd);
18063
18267
  if (ctx.mode === "none") {
18064
18268
  deps.error(
18065
- "No .claude-plugin/marketplace.json or .claude-plugin/plugin.json found in this directory."
18269
+ "No .claude-plugin/marketplace.json, .github/plugin/marketplace.json, or .claude-plugin/plugin.json found in this directory."
18066
18270
  );
18067
18271
  deps.exit(1);
18068
18272
  return;
@@ -18106,7 +18310,9 @@ async function deletePluginHandler(args2, deps) {
18106
18310
  }
18107
18311
  if (ctx.mode === "standalone") {
18108
18312
  const manifestPath = ctx.manifestPath;
18109
- const manifest = JSON.parse((0, import_fs23.readFileSync)(manifestPath, "utf8"));
18313
+ const manifest = JSON.parse(
18314
+ stripBom((0, import_fs23.readFileSync)(manifestPath, "utf8"))
18315
+ );
18110
18316
  if (manifest.name !== pluginName) {
18111
18317
  deps.error(`The plugin '${pluginName}' is not handled in this repo.`);
18112
18318
  deps.exit(1);
@@ -22376,6 +22582,122 @@ var initCommand = (0, import_cmd_ts38.command)({
22376
22582
  // apps/cli/src/infra/commands/TrackCommand.ts
22377
22583
  var import_cmd_ts39 = __toESM(require_cjs());
22378
22584
 
22585
+ // apps/cli/src/infra/commands/removedCommandHandler.ts
22586
+ function reportRemovedCommand(notifyError, removedCommand, replacementCommand, carriedFlags = []) {
22587
+ notifyError(`Command "packmind ${removedCommand}" has been removed.`, {
22588
+ content: `Use the "${replacementCommand}" command instead:`,
22589
+ exampleCommand: [`packmind ${replacementCommand}`, ...carriedFlags].join(
22590
+ " "
22591
+ )
22592
+ });
22593
+ }
22594
+ function removedTrackHandler(deps) {
22595
+ if (deps.remove) {
22596
+ reportRemovedCommand(deps.notifyError, "track --remove", "git untrack");
22597
+ process.exit(1);
22598
+ return;
22599
+ }
22600
+ const carriedFlags = [];
22601
+ if (deps.update) {
22602
+ carriedFlags.push("--update");
22603
+ }
22604
+ if (deps.branch) {
22605
+ carriedFlags.push(`--branch ${deps.branch}`);
22606
+ }
22607
+ reportRemovedCommand(deps.notifyError, "track", "git track", carriedFlags);
22608
+ process.exit(1);
22609
+ }
22610
+ function removedUntrackHandler(deps) {
22611
+ reportRemovedCommand(deps.notifyError, "untrack", "git untrack");
22612
+ process.exit(1);
22613
+ }
22614
+
22615
+ // apps/cli/src/infra/commands/TrackCommand.ts
22616
+ var trackCommand = (0, import_cmd_ts39.command)({
22617
+ name: "track",
22618
+ // Listed in --help on purpose: a stub nobody can discover cannot redirect
22619
+ // anyone. "[Removed]" matches what running it actually says.
22620
+ description: '[Removed] Use "git track" instead',
22621
+ args: {
22622
+ update: (0, import_cmd_ts39.flag)({
22623
+ long: "update",
22624
+ description: "Move the tracked branch to the current branch (requires an existing tracked branch)"
22625
+ }),
22626
+ branch: (0, import_cmd_ts39.option)({
22627
+ type: (0, import_cmd_ts39.optional)(import_cmd_ts39.string),
22628
+ long: "branch",
22629
+ description: "Branch to track (defaults to the branch currently checked out)"
22630
+ }),
22631
+ // Accepted only so the old removal syntax gets the migration message
22632
+ // instead of a raw "unknown arguments" parser error.
22633
+ remove: (0, import_cmd_ts39.flag)({
22634
+ long: "remove",
22635
+ description: 'Removal now lives in the "git untrack" command'
22636
+ })
22637
+ },
22638
+ handler: async ({ update, branch, remove }) => {
22639
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22640
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22641
+ removedTrackHandler({
22642
+ update,
22643
+ branch,
22644
+ remove,
22645
+ notifyError: packmindCliHexa.output.notifyError.bind(
22646
+ packmindCliHexa.output
22647
+ )
22648
+ });
22649
+ }
22650
+ });
22651
+
22652
+ // apps/cli/src/infra/commands/UntrackCommand.ts
22653
+ var import_cmd_ts40 = __toESM(require_cjs());
22654
+ var untrackCommand = (0, import_cmd_ts40.command)({
22655
+ name: "untrack",
22656
+ description: '[Removed] Use "git untrack" instead',
22657
+ args: {},
22658
+ handler: async () => {
22659
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22660
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22661
+ removedUntrackHandler({
22662
+ notifyError: packmindCliHexa.output.notifyError.bind(
22663
+ packmindCliHexa.output
22664
+ )
22665
+ });
22666
+ }
22667
+ });
22668
+
22669
+ // apps/cli/src/infra/commands/UpdateCommand.ts
22670
+ var import_cmd_ts41 = __toESM(require_cjs());
22671
+ var { version: CLI_VERSION6 } = require_package();
22672
+ var updateCommand = (0, import_cmd_ts41.command)({
22673
+ name: "update",
22674
+ description: "Update packmind-cli to the latest version",
22675
+ args: {
22676
+ check: (0, import_cmd_ts41.flag)({
22677
+ long: "check",
22678
+ description: "Only check if a newer version is available without performing the update"
22679
+ })
22680
+ },
22681
+ handler: async ({ check }) => {
22682
+ await updateHandler({
22683
+ currentVersion: CLI_VERSION6,
22684
+ isExecutableMode: hasEmbeddedWasmFiles(),
22685
+ executablePath: process.execPath,
22686
+ scriptPath: require.main?.filename,
22687
+ platform: process.platform,
22688
+ arch: process.arch,
22689
+ fetchFn: fetch,
22690
+ checkOnly: check
22691
+ });
22692
+ }
22693
+ });
22694
+
22695
+ // apps/cli/src/infra/commands/git/gitCommand.ts
22696
+ var import_cmd_ts45 = __toESM(require_cjs());
22697
+
22698
+ // apps/cli/src/infra/commands/git/infoCommand.ts
22699
+ var import_cmd_ts42 = __toESM(require_cjs());
22700
+
22379
22701
  // apps/cli/src/infra/commands/trackingErrors.ts
22380
22702
  function handleTrackingError(error) {
22381
22703
  if (error instanceof NotLoggedInError) {
@@ -22401,6 +22723,65 @@ function handleTrackingError(error) {
22401
22723
  process.exit(1);
22402
22724
  }
22403
22725
 
22726
+ // apps/cli/src/infra/commands/trackingInfoHandler.ts
22727
+ async function trackingInfoHandler(deps) {
22728
+ let result;
22729
+ try {
22730
+ result = await deps.getTrackingInfo({ repoPath: deps.baseDirectory });
22731
+ } catch (error) {
22732
+ handleTrackingError(error);
22733
+ return;
22734
+ }
22735
+ if (result.status === "not-tracked") {
22736
+ logInfoConsole(
22737
+ result.currentBranchDetached ? `${result.owner}/${result.repo} is not tracked in Packmind. No branch is checked out here \u2014 run ${formatCommand(
22738
+ "packmind git track --branch <name>"
22739
+ )} to track one.` : `${result.owner}/${result.repo} is not tracked in Packmind. Run ${formatCommand(
22740
+ "packmind git track"
22741
+ )} to track branch '${result.currentBranch}'.`
22742
+ );
22743
+ process.exit(0);
22744
+ return;
22745
+ }
22746
+ logInfoConsole(
22747
+ `Packmind tracks ${result.owner}/${result.repo} on branch '${result.trackedBranch}'.`
22748
+ );
22749
+ if (result.currentBranch !== result.trackedBranch) {
22750
+ logWarningConsole(mismatchWarning(result));
22751
+ }
22752
+ process.exit(0);
22753
+ }
22754
+ function mismatchWarning(result) {
22755
+ const moveTracking = result.currentBranchDetached ? `${formatCommand("packmind git track --update --branch <name>")} to move tracking to a branch that exists` : `${formatCommand("packmind git track --update")} to move tracking to '${result.currentBranch}'`;
22756
+ if (!result.trackedBranchExists) {
22757
+ return `Branch '${result.trackedBranch}' is not in this repository \u2014 deleted after a merge, or never fetched here \u2014 so no distribution is recorded anywhere. Run ${moveTracking}, or ${formatCommand(
22758
+ "git fetch"
22759
+ )} if the branch is still on the remote.`;
22760
+ }
22761
+ if (result.currentBranchDetached) {
22762
+ return `No branch is checked out here \u2014 HEAD is detached \u2014 so distributions from here are not recorded. Check '${result.trackedBranch}' out to record them, or run ${moveTracking}.`;
22763
+ }
22764
+ return `You are on '${result.currentBranch}', so distributions from here are not recorded. Run ${moveTracking}.`;
22765
+ }
22766
+
22767
+ // apps/cli/src/infra/commands/git/infoCommand.ts
22768
+ var infoCommand = (0, import_cmd_ts42.command)({
22769
+ name: "info",
22770
+ description: "Show whether Packmind tracks the current repository, and on which branch",
22771
+ args: {},
22772
+ handler: async () => {
22773
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
22774
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
22775
+ await trackingInfoHandler({
22776
+ baseDirectory: process.cwd(),
22777
+ getTrackingInfo: packmindCliHexa.getTrackingInfo.bind(packmindCliHexa)
22778
+ });
22779
+ }
22780
+ });
22781
+
22782
+ // apps/cli/src/infra/commands/git/trackCommand.ts
22783
+ var import_cmd_ts43 = __toESM(require_cjs());
22784
+
22404
22785
  // apps/cli/src/infra/commands/trackHandler.ts
22405
22786
  async function trackHandler(deps) {
22406
22787
  const isTTY = deps.isTTY ?? Boolean(process.stdin.isTTY);
@@ -22451,14 +22832,28 @@ async function trackHandler(deps) {
22451
22832
  case "already-tracked-other-branch":
22452
22833
  logErrorConsole(
22453
22834
  `Repository ${result.owner}/${result.repo} is already tracked on branch ${result.trackedBranch}. Run ${formatCommand(
22454
- "packmind track --update"
22835
+ // `--update` alone moves tracking to the checked-out branch, which is
22836
+ // not the target when a branch was named explicitly.
22837
+ deps.branch ? `packmind git track --update --branch ${result.branch}` : "packmind git track --update"
22455
22838
  )} to move it to ${result.branch}.`
22456
22839
  );
22457
22840
  process.exit(1);
22458
22841
  return;
22842
+ case "detached-head":
22843
+ logErrorConsole(
22844
+ `No branch is checked out for ${result.owner}/${result.repo} \u2014 HEAD is detached. Check a branch out, or name one with ${formatCommand("packmind git track --branch <name>")}.`
22845
+ );
22846
+ process.exit(1);
22847
+ return;
22848
+ case "branch-not-found":
22849
+ logErrorConsole(
22850
+ `Branch ${result.branch} does not exist in ${result.owner}/${result.repo}. Check the spelling, or run ${formatCommand("git fetch")} first if the branch only exists on the remote.`
22851
+ );
22852
+ process.exit(1);
22853
+ return;
22459
22854
  case "nothing-tracked":
22460
22855
  logErrorConsole(
22461
- `Nothing is tracked yet \u2014 run ${formatCommand("packmind init")} or ${formatCommand("packmind track")} to start tracking.`
22856
+ `Nothing is tracked yet \u2014 run ${formatCommand("packmind init")} or ${formatCommand("packmind git track")} to start tracking.`
22462
22857
  );
22463
22858
  process.exit(1);
22464
22859
  return;
@@ -22467,19 +22862,19 @@ async function trackHandler(deps) {
22467
22862
  }
22468
22863
  }
22469
22864
 
22470
- // apps/cli/src/infra/commands/TrackCommand.ts
22471
- var trackCommand = (0, import_cmd_ts39.command)({
22865
+ // apps/cli/src/infra/commands/git/trackCommand.ts
22866
+ var trackCommand2 = (0, import_cmd_ts43.command)({
22472
22867
  name: "track",
22473
22868
  description: "Set the repository and branch Packmind tracks for the current project",
22474
22869
  args: {
22475
- update: (0, import_cmd_ts39.flag)({
22870
+ update: (0, import_cmd_ts43.flag)({
22476
22871
  long: "update",
22477
- description: "Move the tracked branch to the current branch (requires an existing tracked branch)"
22872
+ description: "Move the tracked branch to the checked-out branch, or to --branch when it is given (requires an existing tracked branch)"
22478
22873
  }),
22479
- branch: (0, import_cmd_ts39.option)({
22480
- type: (0, import_cmd_ts39.optional)(import_cmd_ts39.string),
22874
+ branch: (0, import_cmd_ts43.option)({
22875
+ type: (0, import_cmd_ts43.optional)(import_cmd_ts43.string),
22481
22876
  long: "branch",
22482
- description: "Branch to track (defaults to the branch currently checked out)"
22877
+ description: "Branch to track instead of the checked-out one; combines with --update to move tracking to it"
22483
22878
  })
22484
22879
  },
22485
22880
  handler: async ({ update, branch }) => {
@@ -22494,8 +22889,8 @@ var trackCommand = (0, import_cmd_ts39.command)({
22494
22889
  }
22495
22890
  });
22496
22891
 
22497
- // apps/cli/src/infra/commands/UntrackCommand.ts
22498
- var import_cmd_ts40 = __toESM(require_cjs());
22892
+ // apps/cli/src/infra/commands/git/untrackCommand.ts
22893
+ var import_cmd_ts44 = __toESM(require_cjs());
22499
22894
 
22500
22895
  // apps/cli/src/infra/commands/untrackHandler.ts
22501
22896
  async function untrackHandler(deps) {
@@ -22537,8 +22932,8 @@ async function untrackHandler(deps) {
22537
22932
  }
22538
22933
  }
22539
22934
 
22540
- // apps/cli/src/infra/commands/UntrackCommand.ts
22541
- var untrackCommand = (0, import_cmd_ts40.command)({
22935
+ // apps/cli/src/infra/commands/git/untrackCommand.ts
22936
+ var untrackCommand2 = (0, import_cmd_ts44.command)({
22542
22937
  name: "untrack",
22543
22938
  description: "Remove Packmind's tracking of the current repository (keeps every recorded distribution)",
22544
22939
  args: {},
@@ -22552,29 +22947,14 @@ var untrackCommand = (0, import_cmd_ts40.command)({
22552
22947
  }
22553
22948
  });
22554
22949
 
22555
- // apps/cli/src/infra/commands/UpdateCommand.ts
22556
- var import_cmd_ts41 = __toESM(require_cjs());
22557
- var { version: CLI_VERSION6 } = require_package();
22558
- var updateCommand = (0, import_cmd_ts41.command)({
22559
- name: "update",
22560
- description: "Update packmind-cli to the latest version",
22561
- args: {
22562
- check: (0, import_cmd_ts41.flag)({
22563
- long: "check",
22564
- description: "Only check if a newer version is available without performing the update"
22565
- })
22566
- },
22567
- handler: async ({ check }) => {
22568
- await updateHandler({
22569
- currentVersion: CLI_VERSION6,
22570
- isExecutableMode: hasEmbeddedWasmFiles(),
22571
- executablePath: process.execPath,
22572
- scriptPath: require.main?.filename,
22573
- platform: process.platform,
22574
- arch: process.arch,
22575
- fetchFn: fetch,
22576
- checkOnly: check
22577
- });
22950
+ // apps/cli/src/infra/commands/git/gitCommand.ts
22951
+ var gitCommand = (0, import_cmd_ts45.subcommands)({
22952
+ name: "git",
22953
+ description: "Manage repository tracking in Packmind",
22954
+ cmds: {
22955
+ info: infoCommand,
22956
+ track: trackCommand2,
22957
+ untrack: untrackCommand2
22578
22958
  }
22579
22959
  });
22580
22960
 
@@ -22617,12 +22997,13 @@ if (args.includes("--version") || args.includes("-v")) {
22617
22997
  logConsole(`packmind-cli version ${CLI_VERSION7}`);
22618
22998
  process.exit(0);
22619
22999
  }
22620
- var app = (0, import_cmd_ts42.subcommands)({
23000
+ var app = (0, import_cmd_ts46.subcommands)({
22621
23001
  name: "packmind-cli",
22622
23002
  description: "Packmind CLI tool",
22623
23003
  cmds: {
22624
23004
  commands: commandsCommand,
22625
23005
  config: configCommand,
23006
+ git: gitCommand,
22626
23007
  init: initCommand,
22627
23008
  install: installCommand,
22628
23009
  lint: lintCommand,
@@ -22641,7 +23022,7 @@ var app = (0, import_cmd_ts42.subcommands)({
22641
23022
  whoami: whoamiCommand
22642
23023
  }
22643
23024
  });
22644
- (0, import_cmd_ts42.run)(app, args).catch((error) => {
23025
+ (0, import_cmd_ts46.run)(app, args).catch((error) => {
22645
23026
  logErrorConsole(error.message);
22646
23027
  process.exit(1);
22647
23028
  });