@packmind/cli 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/main.cjs +1800 -1196
  2. package/package.json +2 -2
package/main.cjs CHANGED
@@ -234,9 +234,9 @@ var init_ansi_styles = __esm({
234
234
  });
235
235
 
236
236
  // node_modules/chalk/source/vendor/supports-color/index.js
237
- function hasFlag(flag7, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
238
- const prefix = flag7.startsWith("-") ? "" : flag7.length === 1 ? "-" : "--";
239
- const position = argv.indexOf(prefix + flag7);
237
+ function hasFlag(flag8, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
238
+ const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
239
+ const position = argv.indexOf(prefix + flag8);
240
240
  const terminatorPosition = argv.indexOf("--");
241
241
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
242
242
  }
@@ -371,32 +371,32 @@ var init_supports_color = __esm({
371
371
  });
372
372
 
373
373
  // node_modules/chalk/source/utilities.js
374
- function stringReplaceAll(string18, substring, replacer) {
375
- let index = string18.indexOf(substring);
374
+ function stringReplaceAll(string21, substring, replacer) {
375
+ let index = string21.indexOf(substring);
376
376
  if (index === -1) {
377
- return string18;
377
+ return string21;
378
378
  }
379
379
  const substringLength = substring.length;
380
380
  let endIndex = 0;
381
381
  let returnValue = "";
382
382
  do {
383
- returnValue += string18.slice(endIndex, index) + substring + replacer;
383
+ returnValue += string21.slice(endIndex, index) + substring + replacer;
384
384
  endIndex = index + substringLength;
385
- index = string18.indexOf(substring, endIndex);
385
+ index = string21.indexOf(substring, endIndex);
386
386
  } while (index !== -1);
387
- returnValue += string18.slice(endIndex);
387
+ returnValue += string21.slice(endIndex);
388
388
  return returnValue;
389
389
  }
390
- function stringEncaseCRLFWithFirstIndex(string18, prefix, postfix, index) {
390
+ function stringEncaseCRLFWithFirstIndex(string21, prefix, postfix, index) {
391
391
  let endIndex = 0;
392
392
  let returnValue = "";
393
393
  do {
394
- const gotCR = string18[index - 1] === "\r";
395
- returnValue += string18.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
394
+ const gotCR = string21[index - 1] === "\r";
395
+ returnValue += string21.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
396
396
  endIndex = index + 1;
397
- index = string18.indexOf("\n", endIndex);
397
+ index = string21.indexOf("\n", endIndex);
398
398
  } while (index !== -1);
399
- returnValue += string18.slice(endIndex);
399
+ returnValue += string21.slice(endIndex);
400
400
  return returnValue;
401
401
  }
402
402
  var init_utilities = __esm({
@@ -555,26 +555,26 @@ var init_source = __esm({
555
555
  builder[IS_EMPTY] = _isEmpty;
556
556
  return builder;
557
557
  };
558
- applyStyle = (self, string18) => {
559
- if (self.level <= 0 || !string18) {
560
- return self[IS_EMPTY] ? "" : string18;
558
+ applyStyle = (self, string21) => {
559
+ if (self.level <= 0 || !string21) {
560
+ return self[IS_EMPTY] ? "" : string21;
561
561
  }
562
562
  let styler = self[STYLER];
563
563
  if (styler === void 0) {
564
- return string18;
564
+ return string21;
565
565
  }
566
566
  const { openAll, closeAll } = styler;
567
- if (string18.includes("\x1B")) {
567
+ if (string21.includes("\x1B")) {
568
568
  while (styler !== void 0) {
569
- string18 = stringReplaceAll(string18, styler.close, styler.open);
569
+ string21 = stringReplaceAll(string21, styler.close, styler.open);
570
570
  styler = styler.parent;
571
571
  }
572
572
  }
573
- const lfIndex = string18.indexOf("\n");
573
+ const lfIndex = string21.indexOf("\n");
574
574
  if (lfIndex !== -1) {
575
- string18 = stringEncaseCRLFWithFirstIndex(string18, closeAll, openAll, lfIndex);
575
+ string21 = stringEncaseCRLFWithFirstIndex(string21, closeAll, openAll, lfIndex);
576
576
  }
577
- return openAll + string18 + closeAll;
577
+ return openAll + string21 + closeAll;
578
578
  };
579
579
  Object.defineProperties(createChalk.prototype, styles2);
580
580
  chalk = createChalk();
@@ -767,9 +767,9 @@ var require_findOption = __commonJS({
767
767
  continue;
768
768
  }
769
769
  if (node.type === "shortOptions" && opts.shortNames.length) {
770
- for (const option19 of node.options) {
771
- if (opts.shortNames.includes(option19.key)) {
772
- result.push(option19);
770
+ for (const option22 of node.options) {
771
+ if (opts.shortNames.includes(option22.key)) {
772
+ result.push(option22);
773
773
  }
774
774
  }
775
775
  }
@@ -935,7 +935,7 @@ var require_flag = __commonJS({
935
935
  Object.defineProperty(exports2, "__esModule", { value: true });
936
936
  exports2.boolean = void 0;
937
937
  exports2.fullFlag = fullFlag;
938
- exports2.flag = flag7;
938
+ exports2.flag = flag8;
939
939
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
940
940
  var Result = __importStar(require_Result());
941
941
  var findOption_1 = require_findOption();
@@ -1084,7 +1084,7 @@ var require_flag = __commonJS({
1084
1084
  }
1085
1085
  };
1086
1086
  }
1087
- function flag7(config) {
1087
+ function flag8(config) {
1088
1088
  return fullFlag({
1089
1089
  type: types_1.boolean,
1090
1090
  ...config
@@ -1379,13 +1379,13 @@ var require_subcommands = __commonJS({
1379
1379
  return mod && mod.__esModule ? mod : { "default": mod };
1380
1380
  };
1381
1381
  Object.defineProperty(exports2, "__esModule", { value: true });
1382
- exports2.subcommands = subcommands9;
1382
+ exports2.subcommands = subcommands10;
1383
1383
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1384
1384
  var didyoumean_1 = __importDefault(require_didYouMean_1_2_1());
1385
1385
  var Result = __importStar(require_Result());
1386
1386
  var circuitbreaker_1 = require_circuitbreaker();
1387
1387
  var positional_1 = require_positional();
1388
- function subcommands9(config) {
1388
+ function subcommands10(config) {
1389
1389
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1390
1390
  const type = {
1391
1391
  async from(str) {
@@ -1403,9 +1403,9 @@ var require_subcommands = __commonJS({
1403
1403
  let errorMessage = "Not a valid subcommand name";
1404
1404
  const closeOptions = (0, didyoumean_1.default)(str, flatMap(commands, (x) => x.names));
1405
1405
  if (closeOptions) {
1406
- const option19 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1406
+ const option22 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
1407
1407
  errorMessage += `
1408
- Did you mean ${chalk_1.default.italic(option19)}?`;
1408
+ Did you mean ${chalk_1.default.italic(option22)}?`;
1409
1409
  }
1410
1410
  throw new Error(errorMessage);
1411
1411
  }
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
1578
1578
  __export(strip_ansi_exports, {
1579
1579
  default: () => stripAnsi
1580
1580
  });
1581
- function stripAnsi(string18) {
1582
- if (typeof string18 !== "string") {
1583
- throw new TypeError(`Expected a \`string\`, got \`${typeof string18}\``);
1581
+ function stripAnsi(string21) {
1582
+ if (typeof string21 !== "string") {
1583
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string21}\``);
1584
1584
  }
1585
- return string18.replace(regex, "");
1585
+ return string21.replace(regex, "");
1586
1586
  }
1587
1587
  var regex;
1588
1588
  var init_strip_ansi = __esm({
@@ -1698,12 +1698,12 @@ var require_command = __commonJS({
1698
1698
  return mod && mod.__esModule ? mod : { "default": mod };
1699
1699
  };
1700
1700
  Object.defineProperty(exports2, "__esModule", { value: true });
1701
- exports2.command = command30;
1701
+ exports2.command = command33;
1702
1702
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1703
1703
  var Result = __importStar(require_Result());
1704
1704
  var circuitbreaker_1 = require_circuitbreaker();
1705
1705
  var utils_1 = require_utils();
1706
- function command30(config) {
1706
+ function command33(config) {
1707
1707
  const argEntries = (0, utils_1.entries)(config.args);
1708
1708
  const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
1709
1709
  return {
@@ -1781,11 +1781,11 @@ var require_command = __commonJS({
1781
1781
  }
1782
1782
  if (node.type === "forcePositional") {
1783
1783
  } else if (node.type === "shortOptions") {
1784
- for (const option19 of node.options) {
1785
- if (context.visitedNodes.has(option19)) {
1784
+ for (const option22 of node.options) {
1785
+ if (context.visitedNodes.has(option22)) {
1786
1786
  continue;
1787
1787
  }
1788
- unknownArguments.push(option19);
1788
+ unknownArguments.push(option22);
1789
1789
  }
1790
1790
  } else {
1791
1791
  unknownArguments.push(node);
@@ -1864,7 +1864,7 @@ var require_option = __commonJS({
1864
1864
  return mod && mod.__esModule ? mod : { "default": mod };
1865
1865
  };
1866
1866
  Object.defineProperty(exports2, "__esModule", { value: true });
1867
- exports2.option = option19;
1867
+ exports2.option = option22;
1868
1868
  var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
1869
1869
  var Result = __importStar(require_Result());
1870
1870
  var findOption_1 = require_findOption();
@@ -1940,11 +1940,11 @@ var require_option = __commonJS({
1940
1940
  const valueFromEnv = config.env ? process.env[config.env] : void 0;
1941
1941
  const defaultValueFn = config.defaultValue || config.type.defaultValue;
1942
1942
  const onMissingFn = config.onMissing || config.type.onMissing;
1943
- const option20 = options[0];
1943
+ const option23 = options[0];
1944
1944
  let rawValue;
1945
1945
  let envPrefix = "";
1946
- if (option20 === null || option20 === void 0 ? void 0 : option20.value) {
1947
- rawValue = option20.value.node.raw;
1946
+ if (option23 === null || option23 === void 0 ? void 0 : option23.value) {
1947
+ rawValue = option23.value.node.raw;
1948
1948
  } else if (valueFromEnv !== void 0) {
1949
1949
  rawValue = valueFromEnv;
1950
1950
  envPrefix = `env[${chalk_1.default.italic(config.env)}]: `;
@@ -1979,7 +1979,7 @@ var require_option = __commonJS({
1979
1979
  });
1980
1980
  }
1981
1981
  } else {
1982
- const raw = (option20 === null || option20 === void 0 ? void 0 : option20.type) === "shortOption" ? `-${option20 === null || option20 === void 0 ? void 0 : option20.key}` : `--${config.long}`;
1982
+ const raw = (option23 === null || option23 === void 0 ? void 0 : option23.type) === "shortOption" ? `-${option23 === null || option23 === void 0 ? void 0 : option23.key}` : `--${config.long}`;
1983
1983
  return Result.err({
1984
1984
  errors: [
1985
1985
  {
@@ -2001,7 +2001,7 @@ var require_option = __commonJS({
2001
2001
  }
2002
2002
  };
2003
2003
  }
2004
- function option19(config) {
2004
+ function option22(config) {
2005
2005
  return fullOption({
2006
2006
  type: types_1.string,
2007
2007
  ...config
@@ -2040,12 +2040,12 @@ var require_errorBox = __commonJS({
2040
2040
  if (node.type === "shortOptions") {
2041
2041
  let failed = false;
2042
2042
  let s = "";
2043
- for (const option19 of node.options) {
2044
- if (error.nodes.includes(option19)) {
2045
- s += chalk_1.default.red(option19.raw);
2043
+ for (const option22 of node.options) {
2044
+ if (error.nodes.includes(option22)) {
2045
+ s += chalk_1.default.red(option22.raw);
2046
2046
  failed = true;
2047
2047
  } else {
2048
- s += chalk_1.default.dim(option19.raw);
2048
+ s += chalk_1.default.dim(option22.raw);
2049
2049
  }
2050
2050
  }
2051
2051
  const prefix = failed ? chalk_1.default.red("-") : chalk_1.default.dim("-");
@@ -2574,9 +2574,9 @@ var require_browser = __commonJS({
2574
2574
  var require_has_flag = __commonJS({
2575
2575
  "node_modules/has-flag/index.js"(exports2, module2) {
2576
2576
  "use strict";
2577
- module2.exports = (flag7, argv = process.argv) => {
2578
- const prefix = flag7.startsWith("-") ? "" : flag7.length === 1 ? "-" : "--";
2579
- const position = argv.indexOf(prefix + flag7);
2577
+ module2.exports = (flag8, argv = process.argv) => {
2578
+ const prefix = flag8.startsWith("-") ? "" : flag8.length === 1 ? "-" : "--";
2579
+ const position = argv.indexOf(prefix + flag8);
2580
2580
  const terminatorPosition = argv.indexOf("--");
2581
2581
  return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
2582
2582
  };
@@ -3084,8 +3084,8 @@ var require_tokenizer = __commonJS({
3084
3084
  tokens.push(token);
3085
3085
  overallIndex += token.raw.length;
3086
3086
  };
3087
- for (const [stringIndex, string18] of (0, utils_1.enumerate)(strings)) {
3088
- const chars = [...string18];
3087
+ for (const [stringIndex, string21] of (0, utils_1.enumerate)(strings)) {
3088
+ const chars = [...string21];
3089
3089
  for (let i = 0; i < chars.length; i++) {
3090
3090
  if (chars[i] === "-" && chars[i + 1] === "-") {
3091
3091
  push({ type: "longPrefix", raw: "--", index: overallIndex });
@@ -3218,7 +3218,7 @@ var require_restPositionals = __commonJS({
3218
3218
  };
3219
3219
  }();
3220
3220
  Object.defineProperty(exports2, "__esModule", { value: true });
3221
- exports2.restPositionals = restPositionals4;
3221
+ exports2.restPositionals = restPositionals5;
3222
3222
  var Result = __importStar(require_Result());
3223
3223
  var types_1 = require_types();
3224
3224
  function fullRestPositionals(config) {
@@ -3262,7 +3262,7 @@ var require_restPositionals = __commonJS({
3262
3262
  }
3263
3263
  };
3264
3264
  }
3265
- function restPositionals4(config) {
3265
+ function restPositionals5(config) {
3266
3266
  return fullRestPositionals({
3267
3267
  type: types_1.string,
3268
3268
  ...config
@@ -3346,15 +3346,15 @@ var require_multiflag = __commonJS({
3346
3346
  longNames: [config.long],
3347
3347
  shortNames: config.short ? [config.short] : []
3348
3348
  }).filter((x) => !visitedNodes.has(x));
3349
- for (const option19 of options) {
3350
- visitedNodes.add(option19);
3349
+ for (const option22 of options) {
3350
+ visitedNodes.add(option22);
3351
3351
  }
3352
3352
  const optionValues = [];
3353
3353
  const errors = [];
3354
- for (const option19 of options) {
3355
- 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"));
3354
+ for (const option22 of options) {
3355
+ const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option22.value) === null || _a === void 0 ? void 0 : _a.node.raw) !== null && _b !== void 0 ? _b : "true"));
3356
3356
  if (Result.isErr(decoded)) {
3357
- errors.push({ nodes: [option19], message: decoded.error.message });
3357
+ errors.push({ nodes: [option22], message: decoded.error.message });
3358
3358
  } else {
3359
3359
  optionValues.push(decoded.value);
3360
3360
  }
@@ -3518,16 +3518,16 @@ var require_multioption = __commonJS({
3518
3518
  });
3519
3519
  }
3520
3520
  }
3521
- for (const option19 of options) {
3522
- visitedNodes.add(option19);
3521
+ for (const option22 of options) {
3522
+ visitedNodes.add(option22);
3523
3523
  }
3524
3524
  const optionValues = [];
3525
3525
  const errors = [];
3526
3526
  const flagNodes = [];
3527
- for (const option19 of options) {
3528
- const providedValue = (_a = option19.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3527
+ for (const option22 of options) {
3528
+ const providedValue = (_a = option22.value) === null || _a === void 0 ? void 0 : _a.node.raw;
3529
3529
  if (providedValue === void 0) {
3530
- flagNodes.push(option19);
3530
+ flagNodes.push(option22);
3531
3531
  continue;
3532
3532
  }
3533
3533
  optionValues.push(providedValue);
@@ -3852,7 +3852,7 @@ var require_package = __commonJS({
3852
3852
  "apps/cli/package.json"(exports2, module2) {
3853
3853
  module2.exports = {
3854
3854
  name: "@packmind/cli",
3855
- version: "0.24.0",
3855
+ version: "0.25.0",
3856
3856
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3857
  private: false,
3858
3858
  bin: {
@@ -3891,14 +3891,14 @@ var require_package = __commonJS({
3891
3891
  diff: "^8.0.3",
3892
3892
  inquirer: "^13.0.2",
3893
3893
  zod: "^4.3.5",
3894
- semver: "^6.3.1"
3894
+ semver: "^7.7.4"
3895
3895
  }
3896
3896
  };
3897
3897
  }
3898
3898
  });
3899
3899
 
3900
3900
  // apps/cli/src/main.ts
3901
- var import_cmd_ts38 = __toESM(require_cjs());
3901
+ var import_cmd_ts42 = __toESM(require_cjs());
3902
3902
 
3903
3903
  // apps/cli/src/infra/commands/LinterCommand.ts
3904
3904
  var import_cmd_ts = __toESM(require_cjs());
@@ -4082,7 +4082,9 @@ var VALID_CODING_AGENTS = [
4082
4082
  "copilot",
4083
4083
  "agents_md",
4084
4084
  "gitlab_duo",
4085
- "continue"
4085
+ "continue",
4086
+ "opencode",
4087
+ "codex"
4086
4088
  ];
4087
4089
  function isValidCodingAgent(value) {
4088
4090
  return VALID_CODING_AGENTS.includes(value);
@@ -4117,7 +4119,9 @@ var CodingAgents = {
4117
4119
  copilot: "copilot",
4118
4120
  agents_md: "agents_md",
4119
4121
  gitlab_duo: "gitlab_duo",
4120
- continue: "continue"
4122
+ continue: "continue",
4123
+ opencode: "opencode",
4124
+ codex: "codex"
4121
4125
  };
4122
4126
 
4123
4127
  // packages/types/src/coding-agent/CodingAgentArtefactPaths.ts
@@ -4151,6 +4155,16 @@ var CODING_AGENT_ARTEFACT_PATHS = {
4151
4155
  command: "",
4152
4156
  standard: "",
4153
4157
  skill: ".gitlab/duo/skills/"
4158
+ },
4159
+ opencode: {
4160
+ command: ".opencode/commands/",
4161
+ standard: "",
4162
+ skill: ".opencode/skills/"
4163
+ },
4164
+ codex: {
4165
+ command: "",
4166
+ standard: "",
4167
+ skill: ".agents/skills/"
4154
4168
  }
4155
4169
  };
4156
4170
 
@@ -4316,6 +4330,8 @@ var createTargetId = brandedIdFactory();
4316
4330
  var REQUIRED_RENDER_MODE = "PACKMIND" /* PACKMIND */;
4317
4331
  var RENDER_MODE_ORDER = [
4318
4332
  "PACKMIND" /* PACKMIND */,
4333
+ "CODEX" /* CODEX */,
4334
+ "OPENCODE" /* OPENCODE */,
4319
4335
  "AGENTS_MD" /* AGENTS_MD */,
4320
4336
  "JUNIE" /* JUNIE */,
4321
4337
  "GH_COPILOT" /* GH_COPILOT */,
@@ -4341,13 +4357,15 @@ var DEFAULT_ACTIVE_RENDER_MODES = normalizeRenderModes([
4341
4357
  // packages/types/src/deployments/RenderModeCodingAgentMapping.ts
4342
4358
  var RENDER_MODE_TO_CODING_AGENT = {
4343
4359
  ["PACKMIND" /* PACKMIND */]: CodingAgents.packmind,
4360
+ ["OPENCODE" /* OPENCODE */]: CodingAgents.opencode,
4344
4361
  ["AGENTS_MD" /* AGENTS_MD */]: CodingAgents.agents_md,
4345
4362
  ["JUNIE" /* JUNIE */]: CodingAgents.junie,
4346
4363
  ["GH_COPILOT" /* GH_COPILOT */]: CodingAgents.copilot,
4347
4364
  ["CLAUDE" /* CLAUDE */]: CodingAgents.claude,
4348
4365
  ["CURSOR" /* CURSOR */]: CodingAgents.cursor,
4349
4366
  ["GITLAB_DUO" /* GITLAB_DUO */]: CodingAgents.gitlab_duo,
4350
- ["CONTINUE" /* CONTINUE */]: CodingAgents.continue
4367
+ ["CONTINUE" /* CONTINUE */]: CodingAgents.continue,
4368
+ ["CODEX" /* CODEX */]: CodingAgents.codex
4351
4369
  };
4352
4370
  var CODING_AGENT_TO_RENDER_MODE = Object.entries(RENDER_MODE_TO_CODING_AGENT).reduce(
4353
4371
  (acc, [renderMode, codingAgent]) => {
@@ -5257,8 +5275,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
5257
5275
  static {
5258
5276
  this.fallbackRuleContent = "adhoc-rule";
5259
5277
  }
5260
- async execute(command30) {
5261
- const { program, fileContent, language } = command30;
5278
+ async execute(command33) {
5279
+ const { program, fileContent, language } = command33;
5262
5280
  const result = await this.linterExecutionUseCase.execute({
5263
5281
  filePath: "cli-single-file",
5264
5282
  fileContent,
@@ -5317,30 +5335,30 @@ var GitService = class {
5317
5335
  this.gitRunner = gitRunner;
5318
5336
  this.logger = logger2;
5319
5337
  }
5320
- getGitRepositoryRoot(path33) {
5338
+ getGitRepositoryRoot(path36) {
5321
5339
  try {
5322
5340
  const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
5323
- cwd: path33
5341
+ cwd: path36
5324
5342
  });
5325
5343
  const gitRoot = stdout.trim();
5326
5344
  this.logger.debug("Resolved git repository root", {
5327
- inputPath: path33,
5345
+ inputPath: path36,
5328
5346
  gitRoot
5329
5347
  });
5330
5348
  return gitRoot;
5331
5349
  } catch (error) {
5332
5350
  if (error instanceof Error) {
5333
5351
  throw new Error(
5334
- `Failed to get Git repository root. The path '${path33}' does not appear to be inside a Git repository.
5352
+ `Failed to get Git repository root. The path '${path36}' does not appear to be inside a Git repository.
5335
5353
  ${error.message}`
5336
5354
  );
5337
5355
  }
5338
5356
  throw new Error("Failed to get Git repository root: Unknown error");
5339
5357
  }
5340
5358
  }
5341
- tryGetGitRepositoryRoot(path33) {
5359
+ tryGetGitRepositoryRoot(path36) {
5342
5360
  try {
5343
- return this.getGitRepositoryRoot(path33);
5361
+ return this.getGitRepositoryRoot(path36);
5344
5362
  } catch {
5345
5363
  return null;
5346
5364
  }
@@ -5642,8 +5660,8 @@ var GetGitRemoteUrlUseCase = class {
5642
5660
  constructor(gitRemoteUrlService = new GitService()) {
5643
5661
  this.gitRemoteUrlService = gitRemoteUrlService;
5644
5662
  }
5645
- async execute(command30) {
5646
- const { path: repoPath, origin: origin9 } = command30;
5663
+ async execute(command33) {
5664
+ const { path: repoPath, origin: origin9 } = command33;
5647
5665
  return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
5648
5666
  }
5649
5667
  };
@@ -5795,8 +5813,8 @@ var ListFilesInDirectoryUseCase = class {
5795
5813
  constructor(listFiles = new ListFiles()) {
5796
5814
  this.listFiles = listFiles;
5797
5815
  }
5798
- async execute(command30) {
5799
- const { path: directoryPath, extensions, excludes = [] } = command30;
5816
+ async execute(command33) {
5817
+ const { path: directoryPath, extensions, excludes = [] } = command33;
5800
5818
  const files = await this.listFiles.listFilesInDirectory(
5801
5819
  directoryPath,
5802
5820
  extensions,
@@ -5911,7 +5929,7 @@ var LintFilesAgainstRuleUseCase = class {
5911
5929
  };
5912
5930
  };
5913
5931
  }
5914
- async execute(command30) {
5932
+ async execute(command33) {
5915
5933
  const {
5916
5934
  path: userPath,
5917
5935
  draftMode,
@@ -5920,7 +5938,7 @@ var LintFilesAgainstRuleUseCase = class {
5920
5938
  language,
5921
5939
  diffMode,
5922
5940
  ignorePatterns
5923
- } = command30;
5941
+ } = command33;
5924
5942
  this.logger.debug(
5925
5943
  `Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
5926
5944
  );
@@ -6236,8 +6254,8 @@ var LintFilesAgainstRuleUseCase = class {
6236
6254
  return null;
6237
6255
  }
6238
6256
  }
6239
- async executeProgramsForFile(command30) {
6240
- const result = await this.services.linterExecutionUseCase.execute(command30);
6257
+ async executeProgramsForFile(command33) {
6258
+ const result = await this.services.linterExecutionUseCase.execute(command33);
6241
6259
  return result.violations;
6242
6260
  }
6243
6261
  extractExtensionFromFile(filePath) {
@@ -6260,8 +6278,8 @@ var LintFilesFromConfigUseCase = class {
6260
6278
  this.logger = logger2;
6261
6279
  this.detectionProgramsCache = /* @__PURE__ */ new Map();
6262
6280
  }
6263
- async execute(command30) {
6264
- const { path: userPath, diffMode, ignorePatterns } = command30;
6281
+ async execute(command33) {
6282
+ const { path: userPath, diffMode, ignorePatterns } = command33;
6265
6283
  this.logger.debug(
6266
6284
  `Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
6267
6285
  );
@@ -6521,8 +6539,8 @@ var LintFilesFromConfigUseCase = class {
6521
6539
  return null;
6522
6540
  }
6523
6541
  }
6524
- async executeProgramsForFile(command30) {
6525
- const result = await this.services.linterExecutionUseCase.execute(command30);
6542
+ async executeProgramsForFile(command33) {
6543
+ const result = await this.services.linterExecutionUseCase.execute(command33);
6526
6544
  return result.violations;
6527
6545
  }
6528
6546
  extractExtensionFromFile(filePath) {
@@ -6546,6 +6564,22 @@ var NotLoggedInError = class extends Error {
6546
6564
 
6547
6565
  // apps/cli/src/infra/http/PackmindHttpClient.ts
6548
6566
  var import_package = __toESM(require_package());
6567
+
6568
+ // apps/cli/src/domain/errors/CommunityEditionError.ts
6569
+ var CommunityEditionError = class extends Error {
6570
+ constructor(feature) {
6571
+ super(
6572
+ `The "${feature}" feature is not available in Packmind Community Edition.`
6573
+ );
6574
+ this.isCommunityEditionError = true;
6575
+ this.name = "CommunityEditionError";
6576
+ }
6577
+ };
6578
+ function isCommunityEditionError(tbd) {
6579
+ return tbd.isCommunityEditionError;
6580
+ }
6581
+
6582
+ // apps/cli/src/infra/http/PackmindHttpClient.ts
6549
6583
  var PackmindHttpClient = class {
6550
6584
  constructor(apiKey) {
6551
6585
  this.apiKey = apiKey;
@@ -6589,10 +6623,10 @@ var PackmindHttpClient = class {
6589
6623
  return null;
6590
6624
  }
6591
6625
  }
6592
- async request(path33, options = {}) {
6626
+ async request(path36, options = {}) {
6593
6627
  const { host } = this.getAuthContext();
6594
6628
  const { method = "GET", body } = options;
6595
- const url = `${host}${path33}`;
6629
+ const url = `${host}${path36}`;
6596
6630
  try {
6597
6631
  const response = await fetch(url, {
6598
6632
  method,
@@ -6621,6 +6655,9 @@ var PackmindHttpClient = class {
6621
6655
  }
6622
6656
  return response.json();
6623
6657
  } catch (error) {
6658
+ if (isCommunityEditionError(error)) {
6659
+ throw error;
6660
+ }
6624
6661
  const err = error;
6625
6662
  if (err.statusCode) throw error;
6626
6663
  const code = err?.code || err?.cause?.code;
@@ -6636,27 +6673,17 @@ var PackmindHttpClient = class {
6636
6673
  }
6637
6674
  };
6638
6675
 
6639
- // apps/cli/src/domain/errors/CommunityEditionError.ts
6640
- var CommunityEditionError = class extends Error {
6641
- constructor(feature) {
6642
- super(
6643
- `The "${feature}" feature is not available in Packmind Community Edition.`
6644
- );
6645
- this.name = "CommunityEditionError";
6646
- }
6647
- };
6648
-
6649
6676
  // apps/cli/src/infra/repositories/ChangeProposalGateway.ts
6650
6677
  var ChangeProposalGateway = class {
6651
6678
  constructor(httpClient) {
6652
6679
  this.httpClient = httpClient;
6653
- this.batchCreate = async (command30) => {
6680
+ this.batchCreate = async (command33) => {
6654
6681
  const { organizationId } = this.httpClient.getAuthContext();
6655
6682
  return this.httpClient.request(
6656
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/batch`,
6683
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/change-proposals/batch`,
6657
6684
  {
6658
6685
  method: "POST",
6659
- body: { proposals: command30.proposals },
6686
+ body: { proposals: command33.proposals },
6660
6687
  onError: (response) => {
6661
6688
  if (response.status === 404) {
6662
6689
  throw new CommunityEditionError("change proposals");
@@ -6665,13 +6692,29 @@ var ChangeProposalGateway = class {
6665
6692
  }
6666
6693
  );
6667
6694
  };
6668
- this.check = async (command30) => {
6695
+ this.batchApply = async (command33) => {
6696
+ const { organizationId } = this.httpClient.getAuthContext();
6697
+ return this.httpClient.request(
6698
+ `/api/v0/organizations/${organizationId}/playbook/apply`,
6699
+ {
6700
+ method: "POST",
6701
+ body: {
6702
+ proposals: command33.proposals,
6703
+ message: command33.message,
6704
+ ...command33.directUpdate !== void 0 && {
6705
+ directUpdate: command33.directUpdate
6706
+ }
6707
+ }
6708
+ }
6709
+ );
6710
+ };
6711
+ this.check = async (command33) => {
6669
6712
  const { organizationId } = this.httpClient.getAuthContext();
6670
6713
  return this.httpClient.request(
6671
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/change-proposals/check`,
6714
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/change-proposals/check`,
6672
6715
  {
6673
6716
  method: "POST",
6674
- body: { proposals: command30.proposals },
6717
+ body: { proposals: command33.proposals },
6675
6718
  onError: (response) => {
6676
6719
  if (response.status === 404) {
6677
6720
  throw new CommunityEditionError("change proposals");
@@ -6687,13 +6730,13 @@ var ChangeProposalGateway = class {
6687
6730
  var LinterGateway = class {
6688
6731
  constructor(httpClient) {
6689
6732
  this.httpClient = httpClient;
6690
- this.getDraftDetectionProgramsForRule = async (command30) => {
6733
+ this.getDraftDetectionProgramsForRule = async (command33) => {
6691
6734
  const payload = {
6692
- standardSlug: command30.standardSlug,
6693
- ruleId: command30.ruleId
6735
+ standardSlug: command33.standardSlug,
6736
+ ruleId: command33.ruleId
6694
6737
  };
6695
- if (command30.language) {
6696
- payload.language = command30.language;
6738
+ if (command33.language) {
6739
+ payload.language = command33.language;
6697
6740
  }
6698
6741
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
6699
6742
  method: "POST",
@@ -6705,13 +6748,13 @@ var LinterGateway = class {
6705
6748
  }
6706
6749
  });
6707
6750
  };
6708
- this.getActiveDetectionProgramsForRule = async (command30) => {
6751
+ this.getActiveDetectionProgramsForRule = async (command33) => {
6709
6752
  const payload = {
6710
- standardSlug: command30.standardSlug,
6711
- ruleId: command30.ruleId
6753
+ standardSlug: command33.standardSlug,
6754
+ ruleId: command33.ruleId
6712
6755
  };
6713
- if (command30.language) {
6714
- payload.language = command30.language;
6756
+ if (command33.language) {
6757
+ payload.language = command33.language;
6715
6758
  }
6716
6759
  return this.httpClient.request("/api/v0/list-active-detection-program", {
6717
6760
  method: "POST",
@@ -6723,13 +6766,13 @@ var LinterGateway = class {
6723
6766
  }
6724
6767
  });
6725
6768
  };
6726
- this.getDetectionProgramsForPackages = async (command30) => {
6769
+ this.getDetectionProgramsForPackages = async (command33) => {
6727
6770
  const response = await this.httpClient.request(
6728
6771
  "/api/v0/detection-programs-for-packages",
6729
6772
  {
6730
6773
  method: "POST",
6731
6774
  body: {
6732
- packagesSlugs: command30.packagesSlugs
6775
+ packagesSlugs: command33.packagesSlugs
6733
6776
  },
6734
6777
  onError: (response2) => {
6735
6778
  if (response2.status === 404) {
@@ -6740,10 +6783,10 @@ var LinterGateway = class {
6740
6783
  );
6741
6784
  return handleScopeInTargetsResponse(response);
6742
6785
  };
6743
- this.trackLinterExecution = async (command30) => {
6786
+ this.trackLinterExecution = async (command33) => {
6744
6787
  return this.httpClient.request(`/api/v0/track-execution`, {
6745
6788
  method: "POST",
6746
- body: command30
6789
+ body: command33
6747
6790
  });
6748
6791
  };
6749
6792
  }
@@ -6801,27 +6844,27 @@ var SpacesGateway = class {
6801
6844
  var SkillsGateway = class {
6802
6845
  constructor(httpClient) {
6803
6846
  this.httpClient = httpClient;
6804
- this.upload = async (command30) => {
6847
+ this.upload = async (command33) => {
6805
6848
  const { organizationId } = this.httpClient.getAuthContext();
6806
6849
  return this.httpClient.request(
6807
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills/upload`,
6850
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/skills/upload`,
6808
6851
  {
6809
6852
  method: "POST",
6810
- body: command30
6853
+ body: command33
6811
6854
  }
6812
6855
  );
6813
6856
  };
6814
- this.getDefaults = async (command30) => {
6857
+ this.getDefaults = async (command33) => {
6815
6858
  const { organizationId } = this.httpClient.getAuthContext();
6816
6859
  const queryParams = new URLSearchParams();
6817
- if (command30.includeBeta) {
6860
+ if (command33.includeBeta) {
6818
6861
  queryParams.set("includeBeta", "true");
6819
- } else if (command30.cliVersion) {
6820
- queryParams.set("cliVersion", command30.cliVersion);
6862
+ } else if (command33.cliVersion) {
6863
+ queryParams.set("cliVersion", command33.cliVersion);
6821
6864
  }
6822
- if (command30.agents !== void 0) {
6865
+ if (command33.agents !== void 0) {
6823
6866
  queryParams.append("agentsConfigOverride", "true");
6824
- command30.agents.forEach((agent) => {
6867
+ command33.agents.forEach((agent) => {
6825
6868
  queryParams.append("agent", agent);
6826
6869
  });
6827
6870
  }
@@ -6830,10 +6873,10 @@ var SkillsGateway = class {
6830
6873
  `/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
6831
6874
  );
6832
6875
  };
6833
- this.list = async (command30) => {
6876
+ this.list = async (command33) => {
6834
6877
  const { organizationId } = this.httpClient.getAuthContext();
6835
6878
  return this.httpClient.request(
6836
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/skills`
6879
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/skills`
6837
6880
  );
6838
6881
  };
6839
6882
  }
@@ -6843,17 +6886,17 @@ var SkillsGateway = class {
6843
6886
  var CommandsGateway = class {
6844
6887
  constructor(httpClient) {
6845
6888
  this.httpClient = httpClient;
6846
- this.create = async (command30) => {
6889
+ this.create = async (command33) => {
6847
6890
  const { organizationId } = this.httpClient.getAuthContext();
6848
6891
  return this.httpClient.request(
6849
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`,
6850
- { method: "POST", body: command30 }
6892
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/recipes`,
6893
+ { method: "POST", body: command33 }
6851
6894
  );
6852
6895
  };
6853
- this.list = async (command30) => {
6896
+ this.list = async (command33) => {
6854
6897
  const { organizationId } = this.httpClient.getAuthContext();
6855
6898
  const listRecipesResponse = await this.httpClient.request(
6856
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/recipes`
6899
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/recipes`
6857
6900
  );
6858
6901
  if (listRecipesResponse instanceof Array) {
6859
6902
  return { recipes: listRecipesResponse };
@@ -6894,10 +6937,10 @@ var StandardsGateway = class {
6894
6937
  }
6895
6938
  );
6896
6939
  };
6897
- this.list = async (command30) => {
6940
+ this.list = async (command33) => {
6898
6941
  const { organizationId } = this.httpClient.getAuthContext();
6899
6942
  return this.httpClient.request(
6900
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/standards`
6943
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/standards`
6901
6944
  );
6902
6945
  };
6903
6946
  }
@@ -6908,39 +6951,39 @@ var PackagesGateway = class {
6908
6951
  constructor(apiKey, httpClient) {
6909
6952
  this.apiKey = apiKey;
6910
6953
  this.httpClient = httpClient;
6911
- this.list = async (command30) => {
6954
+ this.list = async (command33) => {
6912
6955
  const { organizationId } = this.httpClient.getAuthContext();
6913
6956
  return this.httpClient.request(
6914
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`
6957
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/packages`
6915
6958
  );
6916
6959
  };
6917
6960
  this.getSummary = async ({
6918
- slug: slug2,
6961
+ slug: slug3,
6919
6962
  spaceId
6920
6963
  }) => {
6921
6964
  const { organizationId } = this.httpClient.getAuthContext();
6922
6965
  return this.httpClient.request(
6923
- `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug2)}`
6966
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug3)}`
6924
6967
  );
6925
6968
  };
6926
- this.create = async (command30) => {
6969
+ this.create = async (command33) => {
6927
6970
  const { organizationId } = this.httpClient.getAuthContext();
6928
6971
  return this.httpClient.request(
6929
- `/api/v0/organizations/${organizationId}/spaces/${command30.spaceId}/packages`,
6972
+ `/api/v0/organizations/${organizationId}/spaces/${command33.spaceId}/packages`,
6930
6973
  {
6931
6974
  method: "POST",
6932
- body: command30
6975
+ body: command33
6933
6976
  }
6934
6977
  );
6935
6978
  };
6936
- this.addArtefacts = async (command30) => {
6979
+ this.addArtefacts = async (command33) => {
6937
6980
  const { organizationId } = this.httpClient.getAuthContext();
6938
- const { packageId, spaceId } = command30;
6981
+ const { packageId, spaceId } = command33;
6939
6982
  return this.httpClient.request(
6940
6983
  `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
6941
6984
  {
6942
6985
  method: "POST",
6943
- body: command30
6986
+ body: command33
6944
6987
  }
6945
6988
  );
6946
6989
  };
@@ -6951,31 +6994,31 @@ var PackagesGateway = class {
6951
6994
  var DeploymentGateway = class {
6952
6995
  constructor(httpClient) {
6953
6996
  this.httpClient = httpClient;
6954
- this.pull = async (command30) => {
6997
+ this.pull = async (command33) => {
6955
6998
  const { organizationId } = this.httpClient.getAuthContext();
6956
6999
  const queryParams = new URLSearchParams();
6957
- if (command30.packagesSlugs && command30.packagesSlugs.length > 0) {
6958
- command30.packagesSlugs.forEach((slug2) => {
6959
- queryParams.append("packageSlug", slug2);
7000
+ if (command33.packagesSlugs && command33.packagesSlugs.length > 0) {
7001
+ command33.packagesSlugs.forEach((slug3) => {
7002
+ queryParams.append("packageSlug", slug3);
6960
7003
  });
6961
7004
  }
6962
- if (command30.previousPackagesSlugs && command30.previousPackagesSlugs.length > 0) {
6963
- command30.previousPackagesSlugs.forEach((slug2) => {
6964
- queryParams.append("previousPackageSlug", slug2);
7005
+ if (command33.previousPackagesSlugs && command33.previousPackagesSlugs.length > 0) {
7006
+ command33.previousPackagesSlugs.forEach((slug3) => {
7007
+ queryParams.append("previousPackageSlug", slug3);
6965
7008
  });
6966
7009
  }
6967
- if (command30.gitRemoteUrl) {
6968
- queryParams.append("gitRemoteUrl", command30.gitRemoteUrl);
7010
+ if (command33.gitRemoteUrl) {
7011
+ queryParams.append("gitRemoteUrl", command33.gitRemoteUrl);
6969
7012
  }
6970
- if (command30.gitBranch) {
6971
- queryParams.append("gitBranch", command30.gitBranch);
7013
+ if (command33.gitBranch) {
7014
+ queryParams.append("gitBranch", command33.gitBranch);
6972
7015
  }
6973
- if (command30.relativePath) {
6974
- queryParams.append("relativePath", command30.relativePath);
7016
+ if (command33.relativePath) {
7017
+ queryParams.append("relativePath", command33.relativePath);
6975
7018
  }
6976
- if (command30.agents !== void 0) {
7019
+ if (command33.agents !== void 0) {
6977
7020
  queryParams.append("agentsConfigOverride", "true");
6978
- command30.agents.forEach((agent) => {
7021
+ command33.agents.forEach((agent) => {
6979
7022
  queryParams.append("agent", agent);
6980
7023
  });
6981
7024
  }
@@ -6983,42 +7026,42 @@ var DeploymentGateway = class {
6983
7026
  `/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
6984
7027
  );
6985
7028
  };
6986
- this.getDeployed = async (command30) => {
7029
+ this.getDeployed = async (command33) => {
6987
7030
  const { organizationId } = this.httpClient.getAuthContext();
6988
7031
  return this.httpClient.request(
6989
7032
  `/api/v0/organizations/${organizationId}/deployed-content`,
6990
7033
  {
6991
7034
  method: "POST",
6992
7035
  body: {
6993
- packagesSlugs: command30.packagesSlugs,
6994
- gitRemoteUrl: command30.gitRemoteUrl,
6995
- gitBranch: command30.gitBranch,
6996
- relativePath: command30.relativePath,
6997
- ...command30.agents !== void 0 && { agents: command30.agents }
7036
+ packagesSlugs: command33.packagesSlugs,
7037
+ gitRemoteUrl: command33.gitRemoteUrl,
7038
+ gitBranch: command33.gitBranch,
7039
+ relativePath: command33.relativePath,
7040
+ ...command33.agents !== void 0 && { agents: command33.agents }
6998
7041
  }
6999
7042
  }
7000
7043
  );
7001
7044
  };
7002
- this.getContentByVersions = async (command30) => {
7045
+ this.getContentByVersions = async (command33) => {
7003
7046
  const { organizationId } = this.httpClient.getAuthContext();
7004
7047
  return this.httpClient.request(
7005
7048
  `/api/v0/organizations/${organizationId}/content-by-versions`,
7006
7049
  {
7007
7050
  method: "POST",
7008
7051
  body: {
7009
- artifacts: command30.artifacts,
7010
- ...command30.agents !== void 0 && { agents: command30.agents }
7052
+ artifacts: command33.artifacts,
7053
+ ...command33.agents !== void 0 && { agents: command33.agents }
7011
7054
  }
7012
7055
  }
7013
7056
  );
7014
7057
  };
7015
- this.notifyDistribution = async (command30) => {
7058
+ this.notifyDistribution = async (command33) => {
7016
7059
  const { organizationId } = this.httpClient.getAuthContext();
7017
7060
  return this.httpClient.request(
7018
7061
  `/api/v0/organizations/${organizationId}/deployments`,
7019
7062
  {
7020
7063
  method: "POST",
7021
- body: command30
7064
+ body: command33
7022
7065
  }
7023
7066
  );
7024
7067
  };
@@ -7029,6 +7072,18 @@ var DeploymentGateway = class {
7029
7072
  );
7030
7073
  };
7031
7074
  }
7075
+ async getLatestVersion(type, id, spaceId) {
7076
+ const { organizationId } = this.httpClient.getAuthContext();
7077
+ const typeToPath = {
7078
+ standard: "standards",
7079
+ command: "recipes",
7080
+ skill: "skills"
7081
+ };
7082
+ const pathSegment = typeToPath[type];
7083
+ return this.httpClient.request(
7084
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/${pathSegment}/${id}/latest-version`
7085
+ );
7086
+ }
7032
7087
  };
7033
7088
 
7034
7089
  // apps/cli/src/infra/repositories/PackmindGateway.ts
@@ -8788,8 +8843,8 @@ var ExecuteLinterProgramsUseCase = class {
8788
8843
  this.linterAstAdapter = linterAstAdapter;
8789
8844
  this.logger = logger2;
8790
8845
  }
8791
- async execute(command30) {
8792
- const { filePath, fileContent, language, programs } = command30;
8846
+ async execute(command33) {
8847
+ const { filePath, fileContent, language, programs } = command33;
8793
8848
  if (programs.length === 0) {
8794
8849
  return {
8795
8850
  file: filePath,
@@ -9575,8 +9630,8 @@ var InstallPackagesUseCase = class {
9575
9630
  constructor(packmindGateway) {
9576
9631
  this.packmindGateway = packmindGateway;
9577
9632
  }
9578
- async execute(command30) {
9579
- const baseDirectory = command30.baseDirectory || process.cwd();
9633
+ async execute(command33) {
9634
+ const baseDirectory = command33.baseDirectory || process.cwd();
9580
9635
  const result = {
9581
9636
  filesCreated: 0,
9582
9637
  filesUpdated: 0,
@@ -9588,12 +9643,12 @@ var InstallPackagesUseCase = class {
9588
9643
  skillDirectoriesDeleted: 0
9589
9644
  };
9590
9645
  const response = await this.packmindGateway.deployment.pull({
9591
- packagesSlugs: command30.packagesSlugs,
9592
- previousPackagesSlugs: command30.previousPackagesSlugs,
9593
- gitRemoteUrl: command30.gitRemoteUrl,
9594
- gitBranch: command30.gitBranch,
9595
- relativePath: command30.relativePath,
9596
- agents: command30.agents
9646
+ packagesSlugs: command33.packagesSlugs,
9647
+ previousPackagesSlugs: command33.previousPackagesSlugs,
9648
+ gitRemoteUrl: command33.gitRemoteUrl,
9649
+ gitBranch: command33.gitBranch,
9650
+ relativePath: command33.relativePath,
9651
+ agents: command33.agents
9597
9652
  });
9598
9653
  const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
9599
9654
  (file) => file.path !== "packmind.json"
@@ -9731,12 +9786,12 @@ var InstallPackagesUseCase = class {
9731
9786
  }
9732
9787
  async deleteFile(baseDirectory, filePath, result) {
9733
9788
  const fullPath = path6.join(baseDirectory, filePath);
9734
- const stat8 = await fs4.stat(fullPath).catch(() => null);
9735
- if (stat8?.isDirectory()) {
9789
+ const stat9 = await fs4.stat(fullPath).catch(() => null);
9790
+ if (stat9?.isDirectory()) {
9736
9791
  await fs4.rm(fullPath, { recursive: true, force: true });
9737
9792
  result.filesDeleted++;
9738
9793
  await this.removeEmptyParentDirectories(fullPath, baseDirectory);
9739
- } else if (stat8?.isFile()) {
9794
+ } else if (stat9?.isFile()) {
9740
9795
  await fs4.unlink(fullPath);
9741
9796
  result.filesDeleted++;
9742
9797
  await this.removeEmptyParentDirectories(fullPath, baseDirectory);
@@ -9875,34 +9930,66 @@ ${endMarker}`;
9875
9930
  // apps/cli/src/application/useCases/InstallDefaultSkillsUseCase.ts
9876
9931
  var fs5 = __toESM(require("fs/promises"));
9877
9932
  var path7 = __toESM(require("path"));
9933
+ var import_semver = __toESM(require("semver"));
9878
9934
  var InstallDefaultSkillsUseCase = class {
9879
9935
  constructor(repositories) {
9880
9936
  this.repositories = repositories;
9881
9937
  }
9882
- async execute(command30) {
9883
- const baseDirectory = command30.baseDirectory || process.cwd();
9938
+ async execute(command33) {
9939
+ const baseDirectory = command33.baseDirectory || process.cwd();
9884
9940
  const result = {
9885
9941
  filesCreated: 0,
9886
9942
  filesUpdated: 0,
9887
9943
  errors: [],
9888
- skippedSkillsCount: 0
9944
+ skippedSkillsCount: 0,
9945
+ skippedIncompatibleSkillNames: [],
9946
+ incompatibleInstalledSkills: []
9889
9947
  };
9890
9948
  const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
9891
9949
  const agents = config?.agents;
9892
9950
  const response = await this.repositories.packmindGateway.skills.getDefaults(
9893
9951
  {
9894
- cliVersion: command30.cliVersion,
9895
- includeBeta: command30.includeBeta,
9952
+ cliVersion: command33.cliVersion,
9953
+ includeBeta: command33.includeBeta,
9896
9954
  agents
9897
9955
  }
9898
9956
  );
9899
9957
  result.skippedSkillsCount = response.skippedSkillsCount;
9958
+ const incompatibleInstalledMap = /* @__PURE__ */ new Map();
9959
+ const incompatibleSkillDirs = /* @__PURE__ */ new Map();
9960
+ if (command33.cliVersion) {
9961
+ for (const file of response.fileUpdates.createOrUpdate) {
9962
+ if (path7.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command33.cliVersion)) {
9963
+ const dir = path7.dirname(file.path);
9964
+ const skillName = this.getSkillName(file.content) ?? path7.basename(dir);
9965
+ incompatibleSkillDirs.set(dir, skillName);
9966
+ }
9967
+ }
9968
+ }
9900
9969
  try {
9901
9970
  for (const file of response.fileUpdates.createOrUpdate) {
9902
9971
  try {
9903
- if (file.content) {
9904
- await this.createOrUpdateFile(baseDirectory, file, result);
9972
+ if (!file.content) continue;
9973
+ const isIncompatible = command33.cliVersion && (this.isVersionConstraintViolated(
9974
+ file.content,
9975
+ command33.cliVersion
9976
+ ) || incompatibleSkillDirs.has(path7.dirname(file.path)));
9977
+ if (isIncompatible) {
9978
+ const skillName = this.getSkillName(file.content) ?? incompatibleSkillDirs.get(path7.dirname(file.path)) ?? path7.basename(file.path);
9979
+ const fullPath = path7.join(baseDirectory, file.path);
9980
+ const fileAlreadyInstalled = await this.fileExists(fullPath);
9981
+ if (fileAlreadyInstalled) {
9982
+ const paths = incompatibleInstalledMap.get(skillName) ?? [];
9983
+ paths.push(file.path);
9984
+ incompatibleInstalledMap.set(skillName, paths);
9985
+ } else {
9986
+ if (!result.skippedIncompatibleSkillNames.includes(skillName)) {
9987
+ result.skippedIncompatibleSkillNames.push(skillName);
9988
+ }
9989
+ }
9990
+ continue;
9905
9991
  }
9992
+ await this.createOrUpdateFile(baseDirectory, file, result);
9906
9993
  } catch (error) {
9907
9994
  const errorMsg = error instanceof Error ? error.message : String(error);
9908
9995
  result.errors.push(
@@ -9914,6 +10001,14 @@ var InstallDefaultSkillsUseCase = class {
9914
10001
  const errorMsg = error instanceof Error ? error.message : String(error);
9915
10002
  result.errors.push(`Failed to install default skills: ${errorMsg}`);
9916
10003
  }
10004
+ result.incompatibleInstalledSkills = Array.from(
10005
+ incompatibleInstalledMap.entries()
10006
+ ).map(
10007
+ ([skillName, filePaths]) => ({
10008
+ skillName,
10009
+ filePaths
10010
+ })
10011
+ );
9917
10012
  return result;
9918
10013
  }
9919
10014
  async createOrUpdateFile(baseDirectory, file, result) {
@@ -9940,6 +10035,28 @@ var InstallDefaultSkillsUseCase = class {
9940
10035
  return false;
9941
10036
  }
9942
10037
  }
10038
+ /**
10039
+ * Returns true if the skill's `metadata.packmind-cli-version` constraint
10040
+ * is present AND the given CLI version does NOT satisfy it (i.e. the skill
10041
+ * is meant for an older CLI version than the one running).
10042
+ */
10043
+ isVersionConstraintViolated(content, cliVersion) {
10044
+ const parsed = parseSkillMdContent(content);
10045
+ if (!parsed) return false;
10046
+ const metadata = parsed.properties["metadata"];
10047
+ if (!metadata) return false;
10048
+ const constraint = metadata["packmind-cli-version"];
10049
+ if (!constraint) return false;
10050
+ const normalizedVersion = cliVersion.replace("-next", "");
10051
+ return !import_semver.default.satisfies(normalizedVersion, constraint);
10052
+ }
10053
+ /** Extracts the `name` field from the skill frontmatter, or returns null. */
10054
+ getSkillName(content) {
10055
+ const parsed = parseSkillMdContent(content);
10056
+ if (!parsed) return null;
10057
+ const name = parsed.properties["name"];
10058
+ return typeof name === "string" ? name : null;
10059
+ }
9943
10060
  };
9944
10061
 
9945
10062
  // apps/cli/src/application/useCases/ListPackagesUseCase.ts
@@ -9948,10 +10065,10 @@ var ListPackagesUseCase = class {
9948
10065
  this.packmindGateway = packmindGateway;
9949
10066
  this.spaceService = spaceService;
9950
10067
  }
9951
- async execute(command30) {
9952
- if (command30.spaceId) {
10068
+ async execute(command33) {
10069
+ if (command33.spaceId) {
9953
10070
  const response = await this.packmindGateway.packages.list({
9954
- spaceId: command30.spaceId
10071
+ spaceId: command33.spaceId
9955
10072
  });
9956
10073
  return response.packages;
9957
10074
  }
@@ -9970,8 +10087,8 @@ var GetPackageSummaryUseCase = class {
9970
10087
  constructor(gateway) {
9971
10088
  this.gateway = gateway;
9972
10089
  }
9973
- async execute(command30) {
9974
- return this.gateway.packages.getSummary(command30);
10090
+ async execute(command33) {
10091
+ return this.gateway.packages.getSummary(command33);
9975
10092
  }
9976
10093
  };
9977
10094
 
@@ -10162,10 +10279,10 @@ async function defaultPromptForCode() {
10162
10279
  input: process.stdin,
10163
10280
  output: process.stdout
10164
10281
  });
10165
- return new Promise((resolve13) => {
10282
+ return new Promise((resolve14) => {
10166
10283
  rl.question("Enter the login code from the browser: ", (answer) => {
10167
10284
  rl.close();
10168
- resolve13(answer.trim());
10285
+ resolve14(answer.trim());
10169
10286
  });
10170
10287
  });
10171
10288
  }
@@ -10199,7 +10316,7 @@ async function defaultExchangeCodeForApiKey(code, host) {
10199
10316
  return await response.json();
10200
10317
  }
10201
10318
  function defaultStartCallbackServer() {
10202
- return new Promise((resolve13, reject) => {
10319
+ return new Promise((resolve14, reject) => {
10203
10320
  let timeoutId = null;
10204
10321
  const server = http.createServer((req, res) => {
10205
10322
  res.setHeader("Access-Control-Allow-Origin", "*");
@@ -10212,7 +10329,7 @@ function defaultStartCallbackServer() {
10212
10329
  if (timeoutId) {
10213
10330
  clearTimeout(timeoutId);
10214
10331
  }
10215
- resolve13(code);
10332
+ resolve14(code);
10216
10333
  setImmediate(() => {
10217
10334
  server.close();
10218
10335
  });
@@ -10250,8 +10367,8 @@ var LoginUseCase = class {
10250
10367
  startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
10251
10368
  };
10252
10369
  }
10253
- async execute(command30) {
10254
- const { host, code: providedCode } = command30;
10370
+ async execute(command33) {
10371
+ const { host, code: providedCode } = command33;
10255
10372
  let code;
10256
10373
  if (providedCode) {
10257
10374
  code = providedCode;
@@ -10289,8 +10406,8 @@ var LogoutUseCase = class {
10289
10406
  constructor(deps) {
10290
10407
  this.deps = {
10291
10408
  getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
10292
- fileExists: deps?.fileExists ?? ((path33) => fs7.existsSync(path33)),
10293
- deleteFile: deps?.deleteFile ?? ((path33) => fs7.unlinkSync(path33)),
10409
+ fileExists: deps?.fileExists ?? ((path36) => fs7.existsSync(path36)),
10410
+ deleteFile: deps?.deleteFile ?? ((path36) => fs7.unlinkSync(path36)),
10294
10411
  hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
10295
10412
  };
10296
10413
  }
@@ -10340,7 +10457,7 @@ var WhoamiUseCase = class {
10340
10457
  };
10341
10458
 
10342
10459
  // apps/cli/src/application/useCases/CheckCliVersionUseCase.ts
10343
- var import_semver2 = __toESM(require("semver"));
10460
+ var import_semver3 = __toESM(require("semver"));
10344
10461
 
10345
10462
  // apps/cli/src/infra/commands/updateHandler.ts
10346
10463
  var import_path2 = __toESM(require("path"));
@@ -10348,7 +10465,7 @@ var import_child_process2 = require("child_process");
10348
10465
  var import_fs19 = require("fs");
10349
10466
  var import_promises = require("stream/promises");
10350
10467
  var import_stream = require("stream");
10351
- var import_semver = __toESM(require("semver"));
10468
+ var import_semver2 = __toESM(require("semver"));
10352
10469
  var GITHUB_REPO = "PackmindHub/packmind";
10353
10470
  var NPM_PACKAGE = "@packmind/cli";
10354
10471
  function getPlatformAssetSuffix(platform, arch) {
@@ -10391,7 +10508,7 @@ async function fetchLatestVersionFromGitHub(fetchFn) {
10391
10508
  const cliReleases = releases.filter((r) => r.tag_name?.startsWith("release-cli/")).map((r) => ({
10392
10509
  ...r,
10393
10510
  version: r.tag_name.replace("release-cli/", "")
10394
- })).filter((r) => import_semver.default.valid(r.version)).sort((a, b) => import_semver.default.rcompare(a.version, b.version));
10511
+ })).filter((r) => import_semver2.default.valid(r.version)).sort((a, b) => import_semver2.default.rcompare(a.version, b.version));
10395
10512
  if (cliReleases.length === 0) {
10396
10513
  throw new Error("No CLI release found on GitHub");
10397
10514
  }
@@ -10522,7 +10639,7 @@ async function updateHandler(deps) {
10522
10639
  process.exit(1);
10523
10640
  return;
10524
10641
  }
10525
- if (!import_semver.default.gt(latestVersion, deps.currentVersion)) {
10642
+ if (!import_semver2.default.gt(latestVersion, deps.currentVersion)) {
10526
10643
  logSuccessConsole(`Already up to date (v${deps.currentVersion})`);
10527
10644
  return;
10528
10645
  }
@@ -10569,7 +10686,7 @@ var CheckCliVersionUseCase = class {
10569
10686
  timeoutMs: deps?.timeoutMs ?? VERSION_CHECK_TIMEOUT_MS
10570
10687
  };
10571
10688
  }
10572
- async execute(command30) {
10689
+ async execute(command33) {
10573
10690
  try {
10574
10691
  const latestVersion = await Promise.race([
10575
10692
  this.deps.fetchLatestVersion(this.deps.fetchFn),
@@ -10580,9 +10697,9 @@ var CheckCliVersionUseCase = class {
10580
10697
  )
10581
10698
  )
10582
10699
  ]);
10583
- const updateAvailable = import_semver2.default.gt(latestVersion, command30.currentVersion);
10700
+ const updateAvailable = import_semver3.default.gt(latestVersion, command33.currentVersion);
10584
10701
  return {
10585
- currentVersion: command30.currentVersion,
10702
+ currentVersion: command33.currentVersion,
10586
10703
  latestVersion,
10587
10704
  updateAvailable
10588
10705
  };
@@ -10603,8 +10720,8 @@ var SetupMcpUseCase = class {
10603
10720
  constructor(deps) {
10604
10721
  this.deps = deps;
10605
10722
  }
10606
- async execute(command30) {
10607
- const { agentTypes } = command30;
10723
+ async execute(command33) {
10724
+ const { agentTypes } = command33;
10608
10725
  const [tokenResult, urlResult] = await Promise.all([
10609
10726
  this.deps.gateway.mcp.getToken({}),
10610
10727
  this.deps.gateway.mcp.getUrl({})
@@ -10675,9 +10792,9 @@ var McpConfigService = class {
10675
10792
  return JSON.stringify(mcpConfig, null, 2);
10676
10793
  }
10677
10794
  installClaudeMcp(config) {
10678
- const command30 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10795
+ const command33 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
10679
10796
  try {
10680
- (0, import_child_process3.execSync)(command30, { stdio: "pipe" });
10797
+ (0, import_child_process3.execSync)(command33, { stdio: "pipe" });
10681
10798
  return { success: true };
10682
10799
  } catch (error) {
10683
10800
  const execError = error;
@@ -10948,9 +11065,9 @@ var ConfigFileRepository = class {
10948
11065
  }
10949
11066
  const mergedPackages = {};
10950
11067
  for (const config of configs) {
10951
- for (const [slug2, version2] of Object.entries(config.packages)) {
10952
- if (!(slug2 in mergedPackages)) {
10953
- mergedPackages[slug2] = version2;
11068
+ for (const [slug3, version2] of Object.entries(config.packages)) {
11069
+ if (!(slug3 in mergedPackages)) {
11070
+ mergedPackages[slug3] = version2;
10954
11071
  }
10955
11072
  }
10956
11073
  }
@@ -11064,9 +11181,9 @@ var ConfigFileRepository = class {
11064
11181
  parsed.packages = {};
11065
11182
  }
11066
11183
  const packages = parsed.packages;
11067
- for (const slug2 of newPackageSlugs) {
11068
- if (!(slug2 in packages)) {
11069
- packages[slug2] = "*";
11184
+ for (const slug3 of newPackageSlugs) {
11185
+ if (!(slug3 in packages)) {
11186
+ packages[slug3] = "*";
11070
11187
  }
11071
11188
  }
11072
11189
  await this.writeConfigToPath(configPath, parsed);
@@ -11104,6 +11221,23 @@ var ConfigFileRepository = class {
11104
11221
  async updateAgentsConfig(baseDirectory, agents) {
11105
11222
  return this.updateConfig(baseDirectory, "agents", agents);
11106
11223
  }
11224
+ /**
11225
+ * Removes the agents field from packmind.json entirely.
11226
+ * Used when all agents have been removed to avoid writing an empty array.
11227
+ */
11228
+ async deleteAgentsConfig(baseDirectory) {
11229
+ const configPath = this.getConfigPath(baseDirectory);
11230
+ const rawContent = await this.tryReadFile(configPath);
11231
+ if (!rawContent) return;
11232
+ let parsed;
11233
+ try {
11234
+ parsed = JSON.parse(rawContent);
11235
+ } catch {
11236
+ return;
11237
+ }
11238
+ delete parsed["agents"];
11239
+ await this.writeConfigToPath(configPath, parsed);
11240
+ }
11107
11241
  async tryReadFile(filePath) {
11108
11242
  try {
11109
11243
  return await fs9.readFile(filePath, "utf-8");
@@ -11116,8 +11250,8 @@ var ConfigFileRepository = class {
11116
11250
  }
11117
11251
  createConfigWithPackages(slugs) {
11118
11252
  const packages = {};
11119
- for (const slug2 of slugs) {
11120
- packages[slug2] = "*";
11253
+ for (const slug3 of slugs) {
11254
+ packages[slug3] = "*";
11121
11255
  }
11122
11256
  return { packages };
11123
11257
  }
@@ -11169,14 +11303,14 @@ var ListStandardsUseCase = class {
11169
11303
  this.packmindGateway = packmindGateway;
11170
11304
  this.spaceService = spaceService;
11171
11305
  }
11172
- async execute(command30) {
11173
- if (command30.spaceId) {
11306
+ async execute(command33) {
11307
+ if (command33.spaceId) {
11174
11308
  const response = await this.packmindGateway.standards.list({
11175
- spaceId: command30.spaceId
11309
+ spaceId: command33.spaceId
11176
11310
  });
11177
11311
  return response.standards.map((s) => ({
11178
11312
  ...s,
11179
- spaceId: command30.spaceId
11313
+ spaceId: command33.spaceId
11180
11314
  }));
11181
11315
  }
11182
11316
  const spaces = await this.spaceService.getSpaces();
@@ -11197,10 +11331,10 @@ var ListCommandsUseCase = class {
11197
11331
  this.packmindGateway = packmindGateway;
11198
11332
  this.spaceService = spaceService;
11199
11333
  }
11200
- async execute(command30) {
11201
- if (command30.spaceId) {
11334
+ async execute(command33) {
11335
+ if (command33.spaceId) {
11202
11336
  const response = await this.packmindGateway.commands.list({
11203
- spaceId: command30.spaceId
11337
+ spaceId: command33.spaceId
11204
11338
  });
11205
11339
  return response.recipes;
11206
11340
  }
@@ -11220,16 +11354,16 @@ var ListSkillsUseCase = class {
11220
11354
  this.packmindGateway = packmindGateway;
11221
11355
  this.spaceService = spaceService;
11222
11356
  }
11223
- async execute(command30) {
11224
- if (command30.spaceId) {
11357
+ async execute(command33) {
11358
+ if (command33.spaceId) {
11225
11359
  const skills = await this.packmindGateway.skills.list({
11226
- spaceId: command30.spaceId
11360
+ spaceId: command33.spaceId
11227
11361
  });
11228
11362
  return skills.map((s) => ({
11229
11363
  slug: s.slug,
11230
11364
  name: s.name,
11231
11365
  description: s.description,
11232
- spaceId: command30.spaceId
11366
+ spaceId: command33.spaceId
11233
11367
  }));
11234
11368
  }
11235
11369
  const spaces = await this.spaceService.getSpaces();
@@ -11358,9 +11492,9 @@ async function readSkillDirectory(dirPath) {
11358
11492
  if (entry.isDirectory()) {
11359
11493
  await readDir(fullPath, basePath);
11360
11494
  } else if (entry.isFile()) {
11361
- const stat8 = await import_promises2.default.stat(fullPath);
11362
- if (stat8.size > MAX_FILE_SIZE_BYTES) {
11363
- const fileSizeMB = (stat8.size / (1024 * 1024)).toFixed(2);
11495
+ const stat9 = await import_promises2.default.stat(fullPath);
11496
+ if (stat9.size > MAX_FILE_SIZE_BYTES) {
11497
+ const fileSizeMB = (stat9.size / (1024 * 1024)).toFixed(2);
11364
11498
  throw new Error(
11365
11499
  `File "${relativePath}" is ${fileSizeMB} MB which exceeds the maximum allowed size of ${MAX_FILE_SIZE_MB} MB per file.`
11366
11500
  );
@@ -11379,7 +11513,7 @@ async function readSkillDirectory(dirPath) {
11379
11513
  relativePath: normalizedPath,
11380
11514
  content,
11381
11515
  size: Buffer.byteLength(content, isBinary ? "base64" : "utf-8"),
11382
- permissions: modeToPermissionStringOrDefault(stat8.mode),
11516
+ permissions: modeToPermissionStringOrDefault(stat9.mode),
11383
11517
  isBase64: isBinary
11384
11518
  });
11385
11519
  }
@@ -11394,8 +11528,8 @@ var UploadSkillUseCase = class {
11394
11528
  constructor(deps) {
11395
11529
  this.deps = deps;
11396
11530
  }
11397
- async execute(command30) {
11398
- const files = await readSkillDirectory(command30.skillPath);
11531
+ async execute(command33) {
11532
+ const files = await readSkillDirectory(command33.skillPath);
11399
11533
  if (!files.find((f) => f.relativePath === "SKILL.md")) {
11400
11534
  throw new Error("SKILL.md not found in skill directory");
11401
11535
  }
@@ -11409,7 +11543,7 @@ var UploadSkillUseCase = class {
11409
11543
  if (totalSize > 10 * 1024 * 1024) {
11410
11544
  throw new Error(`Skill size (${totalSize} bytes) exceeds 10MB limit`);
11411
11545
  }
11412
- const space = await this.getSpace(command30.spaceSlug);
11546
+ const space = await this.getSpace(command33.spaceSlug);
11413
11547
  const payload = {
11414
11548
  files: files.map((f) => ({
11415
11549
  path: f.relativePath,
@@ -11421,7 +11555,7 @@ var UploadSkillUseCase = class {
11421
11555
  const uploadSkillResponse = await this.deps.gateway.skills.upload({
11422
11556
  spaceId: createSpaceId(space.id),
11423
11557
  files: payload.files,
11424
- originSkill: command30.originSkill
11558
+ originSkill: command33.originSkill
11425
11559
  });
11426
11560
  return {
11427
11561
  skillId: uploadSkillResponse.skill.id,
@@ -11462,27 +11596,6 @@ ${spaceList}`
11462
11596
  var import_diff2 = require("diff");
11463
11597
  var fs12 = __toESM(require("fs/promises"));
11464
11598
  var path15 = __toESM(require("path"));
11465
-
11466
- // apps/cli/src/application/utils/stripFrontmatter.ts
11467
- var FRONTMATTER_DELIMITER2 = "---";
11468
- function stripFrontmatter(content) {
11469
- content = normalizeLineEndings(content);
11470
- if (!content.startsWith(`${FRONTMATTER_DELIMITER2}
11471
- `)) {
11472
- return content;
11473
- }
11474
- const contentAfterOpening = content.slice(FRONTMATTER_DELIMITER2.length + 1);
11475
- const closingIndex = contentAfterOpening.indexOf(
11476
- `
11477
- ${FRONTMATTER_DELIMITER2}`
11478
- );
11479
- if (closingIndex === -1) {
11480
- return content;
11481
- }
11482
- return contentAfterOpening.slice(closingIndex + FRONTMATTER_DELIMITER2.length + 1).trimStart();
11483
- }
11484
-
11485
- // apps/cli/src/application/useCases/diffStrategies/CommandDiffStrategy.ts
11486
11599
  var CommandDiffStrategy = class {
11487
11600
  supports(file) {
11488
11601
  return file.artifactType === "command";
@@ -11495,9 +11608,7 @@ var CommandDiffStrategy = class {
11495
11608
  } catch {
11496
11609
  return [];
11497
11610
  }
11498
- const serverBody = stripFrontmatter(file.content);
11499
- const localBody = stripFrontmatter(localContent);
11500
- const changes = (0, import_diff2.diffLines)(serverBody, localBody);
11611
+ const changes = (0, import_diff2.diffLines)(file.content, localContent);
11501
11612
  const hasDifferences = changes.some(
11502
11613
  (change) => change.added || change.removed
11503
11614
  );
@@ -11509,8 +11620,8 @@ var CommandDiffStrategy = class {
11509
11620
  filePath: file.path,
11510
11621
  type: "updateCommandDescription" /* updateCommandDescription */,
11511
11622
  payload: {
11512
- oldValue: serverBody,
11513
- newValue: localBody
11623
+ oldValue: file.content,
11624
+ newValue: localContent
11514
11625
  },
11515
11626
  artifactName: file.artifactName,
11516
11627
  artifactType: file.artifactType,
@@ -11525,6 +11636,27 @@ var CommandDiffStrategy = class {
11525
11636
  var import_diff3 = require("diff");
11526
11637
  var fs13 = __toESM(require("fs/promises"));
11527
11638
  var path16 = __toESM(require("path"));
11639
+
11640
+ // apps/cli/src/application/utils/stripFrontmatter.ts
11641
+ var FRONTMATTER_DELIMITER2 = "---";
11642
+ function stripFrontmatter(content) {
11643
+ content = normalizeLineEndings(content);
11644
+ if (!content.startsWith(`${FRONTMATTER_DELIMITER2}
11645
+ `)) {
11646
+ return content;
11647
+ }
11648
+ const contentAfterOpening = content.slice(FRONTMATTER_DELIMITER2.length + 1);
11649
+ const closingIndex = contentAfterOpening.indexOf(
11650
+ `
11651
+ ${FRONTMATTER_DELIMITER2}`
11652
+ );
11653
+ if (closingIndex === -1) {
11654
+ return content;
11655
+ }
11656
+ return contentAfterOpening.slice(closingIndex + FRONTMATTER_DELIMITER2.length + 1).trimStart();
11657
+ }
11658
+
11659
+ // apps/cli/src/application/useCases/diffStrategies/SkillDiffStrategy.ts
11528
11660
  var SkillDiffStrategy = class {
11529
11661
  supports(file) {
11530
11662
  return file.artifactType === "skill";
@@ -11877,12 +12009,12 @@ var SkillDiffStrategy = class {
11877
12009
  const files = [];
11878
12010
  for (const entry of entries) {
11879
12011
  const fullPath = path16.join(dirPath, entry);
11880
- const stat8 = await this.tryStatFile(fullPath);
11881
- if (!stat8) {
12012
+ const stat9 = await this.tryStatFile(fullPath);
12013
+ if (!stat9) {
11882
12014
  continue;
11883
12015
  }
11884
12016
  const relativePath = prefix ? `${prefix}/${entry}` : entry;
11885
- if (stat8.isDirectory) {
12017
+ if (stat9.isDirectory) {
11886
12018
  const subFiles = await this.listFilesRecursively(
11887
12019
  fullPath,
11888
12020
  relativePath
@@ -11896,16 +12028,16 @@ var SkillDiffStrategy = class {
11896
12028
  }
11897
12029
  async tryStatFile(filePath) {
11898
12030
  try {
11899
- const stat8 = await fs13.stat(filePath);
11900
- return { isDirectory: stat8.isDirectory() };
12031
+ const stat9 = await fs13.stat(filePath);
12032
+ return { isDirectory: stat9.isDirectory() };
11901
12033
  } catch {
11902
12034
  return null;
11903
12035
  }
11904
12036
  }
11905
12037
  async tryGetPermissions(filePath) {
11906
12038
  try {
11907
- const stat8 = await fs13.stat(filePath);
11908
- return modeToPermissionStringOrDefault(stat8.mode);
12039
+ const stat9 = await fs13.stat(filePath);
12040
+ return modeToPermissionStringOrDefault(stat9.mode);
11909
12041
  } catch {
11910
12042
  return null;
11911
12043
  }
@@ -11947,8 +12079,12 @@ var AGENT_PARSERS = {
11947
12079
  cursor: parseCursorStandard,
11948
12080
  continue: parseContinueStandard,
11949
12081
  copilot: parseCopilotStandard,
11950
- gitlab_duo: () => null
12082
+ gitlab_duo: () => null,
11951
12083
  // single-file agent: standards can't be parsed individually
12084
+ opencode: () => null,
12085
+ // single-file agent: standards are embedded in AGENTS.md
12086
+ codex: () => null
12087
+ // single-file agent: standards are embedded in AGENTS.md
11952
12088
  };
11953
12089
  function parseStandardMdForAgent(content, agent) {
11954
12090
  return AGENT_PARSERS[agent](content);
@@ -12066,7 +12202,14 @@ function parseIdeStandardBody(body, scope) {
12066
12202
  let name = null;
12067
12203
  let nameLineIndex = -1;
12068
12204
  for (let i = 0; i < lines.length; i++) {
12069
- if (lines[i].startsWith("## Standard: ")) {
12205
+ if (lines[i].startsWith("# Standard: ")) {
12206
+ const extracted = lines[i].slice("# Standard: ".length).trim();
12207
+ if (extracted) {
12208
+ name = extracted;
12209
+ nameLineIndex = i;
12210
+ break;
12211
+ }
12212
+ } else if (lines[i].startsWith("## Standard: ")) {
12070
12213
  const extracted = lines[i].slice("## Standard: ".length).trim();
12071
12214
  if (extracted) {
12072
12215
  name = extracted;
@@ -12345,9 +12488,9 @@ var DiffArtefactsUseCase = class {
12345
12488
  new StandardDiffStrategy()
12346
12489
  ];
12347
12490
  }
12348
- async execute(command30) {
12349
- const baseDirectory = command30.baseDirectory || process.cwd();
12350
- const response = await this.fetchContent(command30, baseDirectory);
12491
+ async execute(command33) {
12492
+ const baseDirectory = command33.baseDirectory || process.cwd();
12493
+ const response = await this.fetchContent(command33, baseDirectory);
12351
12494
  const filteredFiles = response.fileUpdates.createOrUpdate.filter(
12352
12495
  (file) => file.path !== "packmind.json"
12353
12496
  );
@@ -12360,7 +12503,7 @@ var DiffArtefactsUseCase = class {
12360
12503
  );
12361
12504
  const prefixedSkillFolders = this.prefixSkillFolders(
12362
12505
  response.skillFolders,
12363
- command30.relativePath
12506
+ command33.relativePath
12364
12507
  );
12365
12508
  const diffs = [];
12366
12509
  for (const file of diffableFiles) {
@@ -12387,7 +12530,7 @@ var DiffArtefactsUseCase = class {
12387
12530
  targetId: response.targetId ? createTargetId(response.targetId) : void 0
12388
12531
  }));
12389
12532
  }
12390
- async fetchContent(command30, baseDirectory) {
12533
+ async fetchContent(command33, baseDirectory) {
12391
12534
  const lockFile = await this.lockFileRepository.read(baseDirectory);
12392
12535
  if (lockFile) {
12393
12536
  try {
@@ -12407,11 +12550,11 @@ var DiffArtefactsUseCase = class {
12407
12550
  }
12408
12551
  }
12409
12552
  return this.packmindGateway.deployment.getDeployed({
12410
- packagesSlugs: command30.packagesSlugs,
12411
- gitRemoteUrl: command30.gitRemoteUrl,
12412
- gitBranch: command30.gitBranch,
12413
- relativePath: command30.relativePath,
12414
- agents: command30.agents
12553
+ packagesSlugs: command33.packagesSlugs,
12554
+ gitRemoteUrl: command33.gitRemoteUrl,
12555
+ gitBranch: command33.gitBranch,
12556
+ relativePath: command33.relativePath,
12557
+ agents: command33.agents
12415
12558
  });
12416
12559
  }
12417
12560
  prefixSkillFolders(skillFolders, relativePath) {
@@ -12435,8 +12578,8 @@ var SubmitDiffsUseCase = class {
12435
12578
  constructor(packmindGateway) {
12436
12579
  this.packmindGateway = packmindGateway;
12437
12580
  }
12438
- async execute(command30) {
12439
- const { groupedDiffs, message } = command30;
12581
+ async execute(command33) {
12582
+ const { groupedDiffs, message } = command33;
12440
12583
  const skipped = [];
12441
12584
  const validDiffs = [];
12442
12585
  for (const group of groupedDiffs) {
@@ -12511,8 +12654,8 @@ var CheckDiffsUseCase = class {
12511
12654
  constructor(packmindGateway) {
12512
12655
  this.packmindGateway = packmindGateway;
12513
12656
  }
12514
- async execute(command30) {
12515
- const { groupedDiffs } = command30;
12657
+ async execute(command33) {
12658
+ const { groupedDiffs } = command33;
12516
12659
  const results = [];
12517
12660
  const validDiffs = [];
12518
12661
  const invalidDiffs = [];
@@ -12665,9 +12808,9 @@ var PackmindCliHexaFactory = class {
12665
12808
  var origin8 = "PackmindCliHexa";
12666
12809
  var PackmindCliHexa = class {
12667
12810
  constructor(logger2 = new PackmindLogger(origin8)) {
12668
- this.notifyDistribution = async (command30) => {
12811
+ this.notifyDistribution = async (command33) => {
12669
12812
  return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
12670
- command30
12813
+ command33
12671
12814
  );
12672
12815
  };
12673
12816
  this.logger = logger2;
@@ -12687,23 +12830,23 @@ var PackmindCliHexa = class {
12687
12830
  this.logger.info("Destroying PackmindCliHexa");
12688
12831
  this.logger.info("PackmindCliHexa destroyed");
12689
12832
  }
12690
- async getGitRemoteUrl(command30) {
12691
- return this.hexa.useCases.getGitRemoteUrl.execute(command30);
12833
+ async getGitRemoteUrl(command33) {
12834
+ return this.hexa.useCases.getGitRemoteUrl.execute(command33);
12692
12835
  }
12693
- async listFilesInDirectory(command30) {
12694
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command30);
12836
+ async listFilesInDirectory(command33) {
12837
+ return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command33);
12695
12838
  }
12696
- async lintFilesAgainstRule(command30) {
12697
- return this.hexa.useCases.lintFilesAgainstRule.execute(command30);
12839
+ async lintFilesAgainstRule(command33) {
12840
+ return this.hexa.useCases.lintFilesAgainstRule.execute(command33);
12698
12841
  }
12699
- async lintFilesFromConfig(command30) {
12700
- return this.hexa.useCases.lintFilesFromConfig.execute(command30);
12842
+ async lintFilesFromConfig(command33) {
12843
+ return this.hexa.useCases.lintFilesFromConfig.execute(command33);
12701
12844
  }
12702
- async installPackages(command30) {
12703
- return this.hexa.useCases.installPackages.execute(command30);
12845
+ async installPackages(command33) {
12846
+ return this.hexa.useCases.installPackages.execute(command33);
12704
12847
  }
12705
- async diffArtefacts(command30) {
12706
- return this.hexa.useCases.diffArtefacts.execute(command30);
12848
+ async diffArtefacts(command33) {
12849
+ return this.hexa.useCases.diffArtefacts.execute(command33);
12707
12850
  }
12708
12851
  async submitDiffs(groupedDiffs, message) {
12709
12852
  return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
@@ -12711,20 +12854,20 @@ var PackmindCliHexa = class {
12711
12854
  async checkDiffs(groupedDiffs) {
12712
12855
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
12713
12856
  }
12714
- async listPackages(command30) {
12715
- return this.hexa.useCases.listPackages.execute(command30);
12857
+ async listPackages(command33) {
12858
+ return this.hexa.useCases.listPackages.execute(command33);
12716
12859
  }
12717
- async getPackageBySlug(command30) {
12718
- return this.hexa.useCases.getPackageBySlug.execute(command30);
12860
+ async getPackageBySlug(command33) {
12861
+ return this.hexa.useCases.getPackageBySlug.execute(command33);
12719
12862
  }
12720
- async listStandards(command30) {
12721
- return this.hexa.useCases.listStandards.execute(command30);
12863
+ async listStandards(command33) {
12864
+ return this.hexa.useCases.listStandards.execute(command33);
12722
12865
  }
12723
- async listCommands(command30) {
12724
- return this.hexa.useCases.listCommands.execute(command30);
12866
+ async listCommands(command33) {
12867
+ return this.hexa.useCases.listCommands.execute(command33);
12725
12868
  }
12726
- async listSkills(command30) {
12727
- return this.hexa.useCases.listSkills.execute(command30);
12869
+ async listSkills(command33) {
12870
+ return this.hexa.useCases.listSkills.execute(command33);
12728
12871
  }
12729
12872
  async configExists(baseDirectory) {
12730
12873
  return await this.hexa.repositories.configFileRepository.configExists(
@@ -12757,8 +12900,8 @@ var PackmindCliHexa = class {
12757
12900
  }
12758
12901
  async writeConfig(baseDirectory, packagesSlugs) {
12759
12902
  const packages = {};
12760
- packagesSlugs.forEach((slug2) => {
12761
- packages[slug2] = "*";
12903
+ packagesSlugs.forEach((slug3) => {
12904
+ packages[slug3] = "*";
12762
12905
  });
12763
12906
  const existingConfig = await this.hexa.repositories.configFileRepository.readConfig(
12764
12907
  baseDirectory
@@ -12811,20 +12954,20 @@ var PackmindCliHexa = class {
12811
12954
  directory
12812
12955
  );
12813
12956
  }
12814
- async login(command30) {
12815
- return this.hexa.useCases.login.execute(command30);
12957
+ async login(command33) {
12958
+ return this.hexa.useCases.login.execute(command33);
12816
12959
  }
12817
- async logout(command30) {
12818
- return this.hexa.useCases.logout.execute(command30);
12960
+ async logout(command33) {
12961
+ return this.hexa.useCases.logout.execute(command33);
12819
12962
  }
12820
- async whoami(command30) {
12821
- return this.hexa.useCases.whoami.execute(command30);
12963
+ async whoami(command33) {
12964
+ return this.hexa.useCases.whoami.execute(command33);
12822
12965
  }
12823
- async checkCliVersion(command30) {
12824
- return this.hexa.useCases.checkCliVersion.execute(command30);
12966
+ async checkCliVersion(command33) {
12967
+ return this.hexa.useCases.checkCliVersion.execute(command33);
12825
12968
  }
12826
- async setupMcp(command30) {
12827
- return this.hexa.useCases.setupMcp.execute(command30);
12969
+ async setupMcp(command33) {
12970
+ return this.hexa.useCases.setupMcp.execute(command33);
12828
12971
  }
12829
12972
  getCurrentBranch(repoPath) {
12830
12973
  return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
@@ -12832,11 +12975,11 @@ var PackmindCliHexa = class {
12832
12975
  getGitRemoteUrlFromPath(repoPath) {
12833
12976
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
12834
12977
  }
12835
- async uploadSkill(command30) {
12836
- return this.hexa.useCases.uploadSkill.execute(command30);
12978
+ async uploadSkill(command33) {
12979
+ return this.hexa.useCases.uploadSkill.execute(command33);
12837
12980
  }
12838
- async installDefaultSkills(command30) {
12839
- return this.hexa.useCases.installDefaultSkills.execute(command30);
12981
+ async installDefaultSkills(command33) {
12982
+ return this.hexa.useCases.installDefaultSkills.execute(command33);
12840
12983
  }
12841
12984
  getPackmindGateway() {
12842
12985
  return this.hexa.repositories.packmindGateway;
@@ -12873,7 +13016,7 @@ var PackmindCliHexa = class {
12873
13016
  }
12874
13017
  const defaultSpace = await this.getDefaultSpace();
12875
13018
  return slugs.map(
12876
- (slug2) => slug2.startsWith("@") ? slug2 : `@${defaultSpace.slug}/${slug2}`
13019
+ (slug3) => slug3.startsWith("@") ? slug3 : `@${defaultSpace.slug}/${slug3}`
12877
13020
  );
12878
13021
  }
12879
13022
  getSpaceService() {
@@ -13016,7 +13159,7 @@ function isNotLoggedInError(error) {
13016
13159
  }
13017
13160
  async function lintHandler(args2, deps) {
13018
13161
  const {
13019
- path: path33,
13162
+ path: path36,
13020
13163
  draft,
13021
13164
  rule,
13022
13165
  language,
@@ -13038,7 +13181,7 @@ async function lintHandler(args2, deps) {
13038
13181
  throw new Error("option --rule is required to use --draft mode");
13039
13182
  }
13040
13183
  const startedAt = Date.now();
13041
- const targetPath = path33 ?? ".";
13184
+ const targetPath = path36 ?? ".";
13042
13185
  const absolutePath = resolvePath(targetPath);
13043
13186
  let stats;
13044
13187
  try {
@@ -13360,8 +13503,8 @@ function extractWasmFiles() {
13360
13503
 
13361
13504
  // apps/cli/src/main.ts
13362
13505
  var import_dotenv = require("dotenv");
13363
- var fs26 = __toESM(require("fs"));
13364
- var path32 = __toESM(require("path"));
13506
+ var fs27 = __toESM(require("fs"));
13507
+ var path35 = __toESM(require("path"));
13365
13508
 
13366
13509
  // apps/cli/src/infra/commands/InstallCommand.ts
13367
13510
  var import_cmd_ts2 = __toESM(require_cjs());
@@ -13372,14 +13515,14 @@ var path19 = __toESM(require("path"));
13372
13515
  var { version: CLI_VERSION } = require_package();
13373
13516
  async function notifyDistributionIfInGitRepo(params) {
13374
13517
  const { packmindCliHexa, cwd, packages, log, agents } = params;
13375
- const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
13376
- if (!gitRoot) {
13518
+ const resolvedGitRoot = params.gitRoot ?? await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
13519
+ if (!resolvedGitRoot) {
13377
13520
  return false;
13378
13521
  }
13379
13522
  try {
13380
- const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
13381
- const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
13382
- let relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
13523
+ const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(resolvedGitRoot);
13524
+ const gitBranch = packmindCliHexa.getCurrentBranch(resolvedGitRoot);
13525
+ let relativePath = cwd.startsWith(resolvedGitRoot) ? cwd.slice(resolvedGitRoot.length) : "/";
13383
13526
  if (!relativePath.startsWith("/")) {
13384
13527
  relativePath = "/" + relativePath;
13385
13528
  }
@@ -13531,6 +13674,24 @@ async function executeInstallForDirectory(directory, deps) {
13531
13674
  };
13532
13675
  }
13533
13676
  const normalizedConfigPackages = await packmindCliHexa.normalizePackageSlugs(configPackages);
13677
+ let gitRemoteUrl;
13678
+ let gitBranch;
13679
+ let relativePath;
13680
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(directory);
13681
+ if (gitRoot) {
13682
+ try {
13683
+ gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
13684
+ gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
13685
+ relativePath = directory.startsWith(gitRoot) ? directory.slice(gitRoot.length) : "/";
13686
+ if (!relativePath.startsWith("/")) {
13687
+ relativePath = "/" + relativePath;
13688
+ }
13689
+ if (!relativePath.endsWith("/")) {
13690
+ relativePath = relativePath + "/";
13691
+ }
13692
+ } catch {
13693
+ }
13694
+ }
13534
13695
  try {
13535
13696
  const packageCount = normalizedConfigPackages.length;
13536
13697
  const packageWord = packageCount === 1 ? "package" : "packages";
@@ -13542,6 +13703,9 @@ async function executeInstallForDirectory(directory, deps) {
13542
13703
  packagesSlugs: normalizedConfigPackages,
13543
13704
  previousPackagesSlugs: normalizedConfigPackages,
13544
13705
  // Pass for consistency
13706
+ gitRemoteUrl,
13707
+ gitBranch,
13708
+ relativePath,
13545
13709
  agents: configAgents
13546
13710
  // Pass agents from config if present
13547
13711
  });
@@ -13565,7 +13729,7 @@ async function executeInstallForDirectory(directory, deps) {
13565
13729
  };
13566
13730
  }
13567
13731
  const configSlugsWereNormalized = configPackages.some(
13568
- (slug2, i) => slug2 !== normalizedConfigPackages[i]
13732
+ (slug3, i) => slug3 !== normalizedConfigPackages[i]
13569
13733
  );
13570
13734
  if (configSlugsWereNormalized) {
13571
13735
  await packmindCliHexa.writeConfig(directory, normalizedConfigPackages);
@@ -13579,7 +13743,8 @@ async function executeInstallForDirectory(directory, deps) {
13579
13743
  packages: normalizedConfigPackages,
13580
13744
  agents: configAgents,
13581
13745
  log: () => {
13582
- }
13746
+ },
13747
+ gitRoot: gitRoot ?? void 0
13583
13748
  });
13584
13749
  }
13585
13750
  return {
@@ -13609,8 +13774,8 @@ async function installPackagesHandler(args2, deps) {
13609
13774
  if (args2.path) {
13610
13775
  const resolvedPath = path19.resolve(rawCwd, args2.path);
13611
13776
  try {
13612
- const stat8 = await fs17.stat(resolvedPath);
13613
- if (!stat8.isDirectory()) {
13777
+ const stat9 = await fs17.stat(resolvedPath);
13778
+ if (!stat9.isDirectory()) {
13614
13779
  logErrorConsole(`Path is not a directory: ${resolvedPath}`);
13615
13780
  exit(1);
13616
13781
  return {
@@ -13778,10 +13943,10 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
13778
13943
  };
13779
13944
  }
13780
13945
  const configSlugsWereNormalized = configPackages.some(
13781
- (slug2, i) => slug2 !== normalizedConfigSlugs[i]
13946
+ (slug3, i) => slug3 !== normalizedConfigSlugs[i]
13782
13947
  );
13783
13948
  const newPackages = normalizedNewSlugs.filter(
13784
- (slug2) => !normalizedConfigSlugs.includes(slug2)
13949
+ (slug3) => !normalizedConfigSlugs.includes(slug3)
13785
13950
  );
13786
13951
  if (configSlugsWereNormalized) {
13787
13952
  await packmindCliHexa.writeConfig(cwd, allPackages);
@@ -13961,7 +14126,7 @@ async function uninstallPackagesHandler(args2, deps) {
13961
14126
  originalKey
13962
14127
  );
13963
14128
  });
13964
- const packagesToUninstall = normalizedRequestedSlugs.filter((slug2) => normalizedToOriginalConfigKey.has(slug2)).map((slug2) => normalizedToOriginalConfigKey.get(slug2));
14129
+ const packagesToUninstall = normalizedRequestedSlugs.filter((slug3) => normalizedToOriginalConfigKey.has(slug3)).map((slug3) => normalizedToOriginalConfigKey.get(slug3));
13965
14130
  const notInstalledPackages = packagesSlugs.filter(
13966
14131
  (_, i) => !normalizedToOriginalConfigKey.has(normalizedRequestedSlugs[i])
13967
14132
  );
@@ -14093,8 +14258,8 @@ async function recursiveInstallHandler(args2, deps) {
14093
14258
  if (args2.path) {
14094
14259
  const resolvedPath = path19.resolve(cwd, args2.path);
14095
14260
  try {
14096
- const stat8 = await fs17.stat(resolvedPath);
14097
- if (!stat8.isDirectory()) {
14261
+ const stat9 = await fs17.stat(resolvedPath);
14262
+ if (!stat9.isDirectory()) {
14098
14263
  logErrorConsole(`Path is not a directory: ${resolvedPath}`);
14099
14264
  exit(1);
14100
14265
  return result;
@@ -14194,8 +14359,8 @@ async function recursiveInstallHandler(args2, deps) {
14194
14359
  // apps/cli/src/infra/utils/spaceFilterUtils.ts
14195
14360
  function resolveSpaceFromArgs(spaceArg, spaces) {
14196
14361
  if (!spaceArg) return null;
14197
- const slug2 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
14198
- return spaces.find((s) => s.slug === slug2) ?? null;
14362
+ const slug3 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
14363
+ return spaces.find((s) => s.slug === slug3) ?? null;
14199
14364
  }
14200
14365
 
14201
14366
  // apps/cli/src/infra/utils/urlBuilderUtils.ts
@@ -14305,20 +14470,20 @@ async function listPackagesHandler(args2, deps) {
14305
14470
  }
14306
14471
 
14307
14472
  // apps/cli/src/infra/utils/packageSlugUtils.ts
14308
- function parsePackageSlug(slug2) {
14309
- if (!slug2.startsWith("@")) return null;
14310
- const slash = slug2.indexOf("/", 1);
14473
+ function parsePackageSlug(slug3) {
14474
+ if (!slug3.startsWith("@")) return null;
14475
+ const slash = slug3.indexOf("/", 1);
14311
14476
  if (slash === -1) return null;
14312
- return { spaceSlug: slug2.slice(1, slash), pkgSlug: slug2.slice(slash + 1) };
14477
+ return { spaceSlug: slug3.slice(1, slash), pkgSlug: slug3.slice(slash + 1) };
14313
14478
  }
14314
14479
 
14315
14480
  // apps/cli/src/infra/commands/packages/showPackageHandler.ts
14316
14481
  function isNotFoundError(err) {
14317
14482
  return err instanceof Error && err.message.includes("does not exist");
14318
14483
  }
14319
- async function resolvePackage(slug2, packmindCliHexa) {
14484
+ async function resolvePackage(slug3, packmindCliHexa) {
14320
14485
  const allSpaces = await packmindCliHexa.getSpaces();
14321
- const parsed = parsePackageSlug(slug2);
14486
+ const parsed = parsePackageSlug(slug3);
14322
14487
  if (parsed) {
14323
14488
  const { spaceSlug, pkgSlug } = parsed;
14324
14489
  const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
@@ -14344,7 +14509,7 @@ async function resolvePackage(slug2, packmindCliHexa) {
14344
14509
  const results = await Promise.allSettled(
14345
14510
  allSpaces.map(async (space) => ({
14346
14511
  pkg: await packmindCliHexa.getPackageBySlug({
14347
- slug: slug2,
14512
+ slug: slug3,
14348
14513
  spaceId: space.id
14349
14514
  }),
14350
14515
  spaceSlug: space.slug
@@ -14358,17 +14523,17 @@ async function resolvePackage(slug2, packmindCliHexa) {
14358
14523
  if (realError) {
14359
14524
  throw realError.reason;
14360
14525
  }
14361
- throw new Error(`Package '${slug2}' not found in any space.`);
14526
+ throw new Error(`Package '${slug3}' not found in any space.`);
14362
14527
  }
14363
14528
  if (matches.length > 1) {
14364
- const example = `@${matches[0].spaceSlug}/${slug2}`;
14529
+ const example = `@${matches[0].spaceSlug}/${slug3}`;
14365
14530
  throw new Error(
14366
- `Package '${slug2}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
14531
+ `Package '${slug3}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
14367
14532
  );
14368
14533
  }
14369
14534
  return {
14370
14535
  pkg: matches[0].pkg,
14371
- fullSlug: `@${matches[0].spaceSlug}/${slug2}`
14536
+ fullSlug: `@${matches[0].spaceSlug}/${slug3}`
14372
14537
  };
14373
14538
  }
14374
14539
  async function showPackageHandler(args2, deps) {
@@ -14548,7 +14713,7 @@ var installCommand = (0, import_cmd_ts2.command)({
14548
14713
  description: "Package slugs to install (e.g., backend frontend)"
14549
14714
  })
14550
14715
  },
14551
- handler: async ({ list, status, recursive, path: path33, show, packagesSlugs }) => {
14716
+ handler: async ({ list, status, recursive, path: path36, show, packagesSlugs }) => {
14552
14717
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
14553
14718
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
14554
14719
  const repoRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
@@ -14582,17 +14747,17 @@ var installCommand = (0, import_cmd_ts2.command)({
14582
14747
  logWarningConsole(
14583
14748
  "\u26A0\uFE0F The --recursive flag is deprecated. Install is now recursive by default."
14584
14749
  );
14585
- await recursiveInstallHandler({ path: path33 || void 0 }, deps);
14750
+ await recursiveInstallHandler({ path: path36 || void 0 }, deps);
14586
14751
  return;
14587
14752
  }
14588
14753
  if (packagesSlugs.length > 0) {
14589
14754
  await installPackagesHandler(
14590
- { packagesSlugs, path: path33 || void 0 },
14755
+ { packagesSlugs, path: path36 || void 0 },
14591
14756
  deps
14592
14757
  );
14593
14758
  return;
14594
14759
  }
14595
- await recursiveInstallHandler({ path: path33 || void 0 }, deps);
14760
+ await recursiveInstallHandler({ path: path36 || void 0 }, deps);
14596
14761
  }
14597
14762
  });
14598
14763
 
@@ -14852,10 +15017,10 @@ var AgentDetectionService = class {
14852
15017
  const continueDir = path21.join(this.projectDir, ".continue");
14853
15018
  return fs19.existsSync(continueDir);
14854
15019
  }
14855
- isCommandAvailable(command30) {
15020
+ isCommandAvailable(command33) {
14856
15021
  try {
14857
15022
  const whichCommand = process.platform === "win32" ? "where" : "which";
14858
- (0, import_child_process4.execSync)(`${whichCommand} ${command30}`, { stdio: "pipe" });
15023
+ (0, import_child_process4.execSync)(`${whichCommand} ${command33}`, { stdio: "pipe" });
14859
15024
  return true;
14860
15025
  } catch {
14861
15026
  return false;
@@ -14864,7 +15029,9 @@ var AgentDetectionService = class {
14864
15029
  };
14865
15030
 
14866
15031
  // apps/cli/src/infra/commands/customParameters/AgentArgType.ts
14867
- var VALID_AGENTS = ["copilot", "cursor", "claude", "continue"];
15032
+ var VALID_AGENTS = Object.keys(CodingAgents).filter(
15033
+ (a) => a !== "packmind"
15034
+ );
14868
15035
  var agentArgToType = {
14869
15036
  copilot: "vscode",
14870
15037
  cursor: "cursor",
@@ -14906,7 +15073,7 @@ async function promptAgentsWithReadline(choices) {
14906
15073
  output.write("\n");
14907
15074
  const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
14908
15075
  const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
14909
- return new Promise((resolve13) => {
15076
+ return new Promise((resolve14) => {
14910
15077
  rl.question(
14911
15078
  `Enter numbers separated by commas (default: ${defaultValue}): `,
14912
15079
  (answer) => {
@@ -14917,7 +15084,7 @@ async function promptAgentsWithReadline(choices) {
14917
15084
  const numbersStr = trimmed === "" ? defaultValue : trimmed;
14918
15085
  const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
14919
15086
  const selectedAgents = numbers.map((n) => choices[n - 1].value);
14920
- resolve13(selectedAgents);
15087
+ resolve14(selectedAgents);
14921
15088
  }
14922
15089
  );
14923
15090
  });
@@ -14954,7 +15121,7 @@ Credentials are loaded from (in order of priority):`);
14954
15121
  const agentDetectionService = new AgentDetectionService();
14955
15122
  let selectedAgents;
14956
15123
  if (targets.length > 0) {
14957
- selectedAgents = targets.map((t) => agentArgToType[t]);
15124
+ selectedAgents = targets.map((t) => agentArgToType[t]).filter((a) => a !== void 0);
14958
15125
  } else {
14959
15126
  logConsole("\nDetecting installed AI agents...\n");
14960
15127
  const detectedAgents = agentDetectionService.detectAgents();
@@ -15076,7 +15243,7 @@ var SpaceSlug = {
15076
15243
  // apps/cli/src/infra/commands/skills/AddSkillCommand.ts
15077
15244
  var addSkillCommand = (0, import_cmd_ts9.command)({
15078
15245
  name: "add",
15079
- description: "Add a skill from a local directory to a Packmind organization",
15246
+ description: "[Deprecated] Add a skill from a local directory to a Packmind organization",
15080
15247
  args: {
15081
15248
  skillPath: (0, import_cmd_ts9.positional)({
15082
15249
  type: import_cmd_ts9.string,
@@ -15090,47 +15257,63 @@ var addSkillCommand = (0, import_cmd_ts9.command)({
15090
15257
  }),
15091
15258
  originSkill: originSkillOption
15092
15259
  },
15093
- handler: async ({ skillPath, space, originSkill }) => {
15094
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15095
- const packmindCliHexa = new PackmindCliHexa(packmindLogger);
15096
- try {
15097
- logInfoConsole(`Uploading skill from ${skillPath}...`);
15098
- const result = await packmindCliHexa.uploadSkill({
15099
- skillPath,
15100
- originSkill,
15101
- spaceSlug: space ?? void 0
15102
- });
15103
- if (result.isNewSkill) {
15104
- logSuccessConsole("Skill created successfully!");
15105
- } else if (!result.versionCreated) {
15106
- logInfoConsole(
15107
- `Skill content is identical to version ${result.version}, no new version created.`
15260
+ handler: async () => {
15261
+ logErrorConsole('Command "packmind-cli skills add" has been removed.');
15262
+ logConsole(
15263
+ `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15264
+ );
15265
+ process.exit(1);
15266
+ }
15267
+ });
15268
+
15269
+ // apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
15270
+ var import_cmd_ts10 = __toESM(require_cjs());
15271
+ var readline3 = __toESM(require("readline"));
15272
+
15273
+ // apps/cli/src/infra/commands/skills/incompatibleSkillsHandler.ts
15274
+ var fs21 = __toESM(require("fs/promises"));
15275
+ var path22 = __toESM(require("path"));
15276
+ async function handleIncompatibleInstalledSkills(skills, baseDirectory, confirm) {
15277
+ const skillNames = skills.map((s) => s.skillName).join(", ");
15278
+ logWarningConsole(
15279
+ `The following skill(s) are installed but are not compatible with this version of packmind-cli: ${skillNames}`
15280
+ );
15281
+ logInfoConsole("These skills will be deleted.");
15282
+ const confirmed = await confirm();
15283
+ if (!confirmed) {
15284
+ logInfoConsole("Deletion cancelled.");
15285
+ return;
15286
+ }
15287
+ for (const skill of skills) {
15288
+ const skillRootDirs = skill.filePaths.filter((p) => path22.basename(p) === "SKILL.md").map((p) => path22.dirname(p));
15289
+ for (const dir of skillRootDirs) {
15290
+ try {
15291
+ await fs21.rm(path22.join(baseDirectory, dir), {
15292
+ recursive: true,
15293
+ force: true
15294
+ });
15295
+ } catch (error) {
15296
+ logErrorConsole(
15297
+ `Failed to delete skill folder "${dir}": ${error instanceof Error ? error.message : String(error)}`
15108
15298
  );
15109
- } else {
15110
- logSuccessConsole(`Skill updated to version ${result.version}!`);
15111
15299
  }
15112
- logInfoConsole(` Name: ${result.name}`);
15113
- logInfoConsole(` Version: ${result.version}`);
15114
- logInfoConsole(` Files: ${result.fileCount}`);
15115
- logInfoConsole(
15116
- ` Total size: ${(result.totalSize / 1024).toFixed(2)} KB`
15117
- );
15118
- } catch (error) {
15119
- const message = error instanceof Error ? error.message : String(error);
15120
- logErrorConsole(`Upload failed: ${message}`);
15121
- if (message.includes("Multiple spaces found")) {
15122
- logConsole(
15123
- `
15124
- Example: ${formatCommand(`packmind-cli skills add --space <slug> ${skillPath}`)}`
15125
- );
15300
+ }
15301
+ for (const relativePath of skill.filePaths) {
15302
+ if (!skillRootDirs.some((dir) => relativePath.startsWith(dir + "/"))) {
15303
+ try {
15304
+ await fs21.unlink(path22.join(baseDirectory, relativePath));
15305
+ } catch (error) {
15306
+ logErrorConsole(
15307
+ `Failed to delete "${relativePath}": ${error instanceof Error ? error.message : String(error)}`
15308
+ );
15309
+ }
15126
15310
  }
15127
- process.exit(1);
15128
15311
  }
15129
15312
  }
15130
- });
15313
+ logSuccessConsole(`Incompatible skill(s) deleted: ${skillNames}`);
15314
+ }
15131
15315
 
15132
15316
  // apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
15133
- var import_cmd_ts10 = __toESM(require_cjs());
15134
15317
  var { version: CLI_VERSION3 } = require_package();
15135
15318
  var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15136
15319
  name: "install-default",
@@ -15146,15 +15329,30 @@ var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15146
15329
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
15147
15330
  try {
15148
15331
  logInfoConsole("Installing default skills...");
15332
+ const baseDirectory = process.cwd();
15149
15333
  const result = await packmindCliHexa.installDefaultSkills({
15150
15334
  includeBeta,
15151
- cliVersion: includeBeta ? void 0 : CLI_VERSION3
15335
+ cliVersion: includeBeta ? void 0 : CLI_VERSION3,
15336
+ baseDirectory
15152
15337
  });
15153
15338
  if (result.skippedSkillsCount > 0) {
15154
15339
  logWarningConsole(
15155
15340
  `${result.skippedSkillsCount} skill(s) were skipped because they require a newer version of packmind-cli. Run "${formatCommand("packmind-cli update")}" to get the latest version.`
15156
15341
  );
15157
15342
  }
15343
+ if (result.skippedIncompatibleSkillNames.length > 0) {
15344
+ for (const skillName of result.skippedIncompatibleSkillNames) {
15345
+ logWarningConsole(
15346
+ `Skill "${skillName}" was not installed because it is not compatible with this version of packmind-cli.`
15347
+ );
15348
+ }
15349
+ }
15350
+ if (result.incompatibleInstalledSkills.length > 0) {
15351
+ await handleIncompatibleInstalledSkillsWithPrompt(
15352
+ result.incompatibleInstalledSkills,
15353
+ baseDirectory
15354
+ );
15355
+ }
15158
15356
  if (result.errors.length > 0) {
15159
15357
  for (const error of result.errors) {
15160
15358
  logErrorConsole(`Error: ${error}`);
@@ -15183,6 +15381,25 @@ var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15183
15381
  }
15184
15382
  }
15185
15383
  });
15384
+ async function handleIncompatibleInstalledSkillsWithPrompt(skills, baseDirectory) {
15385
+ await handleIncompatibleInstalledSkills(
15386
+ skills,
15387
+ baseDirectory,
15388
+ () => promptConfirmation("Confirm deletion? [y/N]: ")
15389
+ );
15390
+ }
15391
+ async function promptConfirmation(question) {
15392
+ const rl = readline3.createInterface({
15393
+ input: process.stdin,
15394
+ output: process.stdout
15395
+ });
15396
+ return new Promise((resolve14) => {
15397
+ rl.question(question, (answer) => {
15398
+ rl.close();
15399
+ resolve14(answer.trim().toLowerCase() === "y");
15400
+ });
15401
+ });
15402
+ }
15186
15403
 
15187
15404
  // apps/cli/src/infra/commands/ListSkillsCommand.ts
15188
15405
  var import_cmd_ts11 = __toESM(require_cjs());
@@ -15268,7 +15485,7 @@ async function listSkillsHandler(args2, deps) {
15268
15485
  }
15269
15486
  logConsole(formatHeader(`\u{1F4CB} Skills (${skills.length})
15270
15487
  `));
15271
- const buildUrl = resolveUrlBuilder((slug2) => `skills/${slug2}/files`);
15488
+ const buildUrl = resolveUrlBuilder((slug3) => `skills/${slug3}/files`);
15272
15489
  displayGroupedSkills(skills, spaces, buildUrl);
15273
15490
  exit(0);
15274
15491
  } catch (err) {
@@ -15318,249 +15535,35 @@ var import_cmd_ts15 = __toESM(require_cjs());
15318
15535
 
15319
15536
  // apps/cli/src/infra/commands/CreateStandardCommand.ts
15320
15537
  var import_cmd_ts13 = __toESM(require_cjs());
15321
-
15322
- // apps/cli/src/infra/utils/readPlaybookFile.ts
15323
- var fs21 = __toESM(require("fs/promises"));
15324
-
15325
- // apps/cli/src/domain/entities/PlaybookDTO.ts
15326
- var import_zod = require("zod");
15327
- var playbookRuleExampleSchema = import_zod.z.object({
15328
- positive: import_zod.z.string().describe("Valid example of the rule"),
15329
- negative: import_zod.z.string().describe("Invalid example of the rule"),
15330
- language: import_zod.z.string().describe("Programming language")
15331
- });
15332
- var playbookRuleSchema = import_zod.z.object({
15333
- content: import_zod.z.string().min(1).describe("Rule description starting with action verb"),
15334
- examples: playbookRuleExampleSchema.optional()
15335
- });
15336
- var playbookDTOSchema = import_zod.z.object({
15337
- name: import_zod.z.string().min(1).describe("Standard name"),
15338
- description: import_zod.z.string().min(1).describe("Standard description"),
15339
- scope: import_zod.z.string().min(1).describe("Standard scope/context"),
15340
- rules: import_zod.z.array(playbookRuleSchema).min(1).describe("Array of rules (minimum 1)")
15538
+ var createStandardCommand = (0, import_cmd_ts13.command)({
15539
+ name: "create",
15540
+ description: "[Deprecated] Create a coding standard from a playbook JSON file or stdin",
15541
+ args: {
15542
+ file: (0, import_cmd_ts13.positional)({
15543
+ displayName: "file",
15544
+ description: "Path to the playbook JSON file (reads from stdin if omitted)",
15545
+ type: (0, import_cmd_ts13.optional)(import_cmd_ts13.string)
15546
+ }),
15547
+ space: (0, import_cmd_ts13.option)({
15548
+ long: "space",
15549
+ description: "Slug of the space in which to create the standard (with or without leading @)",
15550
+ type: (0, import_cmd_ts13.optional)(SpaceSlug)
15551
+ }),
15552
+ originSkill: originSkillOption
15553
+ },
15554
+ handler: async () => {
15555
+ logErrorConsole(
15556
+ 'Command "packmind-cli standards create" has been removed.'
15557
+ );
15558
+ logConsole(
15559
+ `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15560
+ );
15561
+ process.exit(1);
15562
+ }
15341
15563
  });
15342
15564
 
15343
- // apps/cli/src/infra/utils/playbookValidator.ts
15344
- function validatePlaybook(data) {
15345
- const result = playbookDTOSchema.safeParse(data);
15346
- if (!result.success) {
15347
- const errorList = result.error.issues;
15348
- return {
15349
- isValid: false,
15350
- errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
15351
- };
15352
- }
15353
- return {
15354
- isValid: true,
15355
- data: result.data
15356
- };
15357
- }
15358
-
15359
- // apps/cli/src/infra/utils/readPlaybookFile.ts
15360
- function parseAndValidatePlaybook(content) {
15361
- let parsed;
15362
- try {
15363
- parsed = JSON.parse(content);
15364
- } catch (e) {
15365
- return {
15366
- isValid: false,
15367
- errors: [
15368
- `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
15369
- ]
15370
- };
15371
- }
15372
- return validatePlaybook(parsed);
15373
- }
15374
- async function readPlaybookFile(filePath) {
15375
- try {
15376
- const content = await fs21.readFile(filePath, "utf-8");
15377
- return parseAndValidatePlaybook(content);
15378
- } catch (e) {
15379
- return {
15380
- isValid: false,
15381
- errors: [
15382
- `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
15383
- ]
15384
- };
15385
- }
15386
- }
15387
-
15388
- // apps/cli/src/infra/utils/readStdin.ts
15389
- async function readStdin(input = process.stdin) {
15390
- if ("isTTY" in input && input.isTTY) {
15391
- throw new Error(
15392
- "No piped input detected. Please provide content via stdin or specify a file path."
15393
- );
15394
- }
15395
- const chunks = [];
15396
- for await (const chunk of input) {
15397
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
15398
- }
15399
- const content = Buffer.concat(chunks).toString("utf-8").trim();
15400
- if (!content) {
15401
- throw new Error("Stdin is empty. Please provide JSON content via pipe.");
15402
- }
15403
- return content;
15404
- }
15405
-
15406
- // apps/cli/src/infra/commands/standards/createStandardHandler.ts
15407
- async function createStandardHandler(filePath, useCase, originSkill, spaceSlug) {
15408
- let readResult;
15409
- if (filePath) {
15410
- readResult = await readPlaybookFile(filePath);
15411
- } else {
15412
- try {
15413
- const content = await readStdin();
15414
- readResult = parseAndValidatePlaybook(content);
15415
- } catch (e) {
15416
- return {
15417
- success: false,
15418
- error: e instanceof Error ? e.message : "Failed to read from stdin"
15419
- };
15420
- }
15421
- }
15422
- if (!readResult.isValid) {
15423
- return {
15424
- success: false,
15425
- error: `Validation failed: ${readResult.errors?.join(", ")}`
15426
- };
15427
- }
15428
- if (!readResult.data) {
15429
- return {
15430
- success: false,
15431
- error: "Failed to read playbook data"
15432
- };
15433
- }
15434
- try {
15435
- const result = await useCase.execute({
15436
- ...readResult.data,
15437
- originSkill,
15438
- spaceSlug
15439
- });
15440
- return {
15441
- success: true,
15442
- standardId: result.standardId,
15443
- standardName: result.name
15444
- };
15445
- } catch (e) {
15446
- return {
15447
- success: false,
15448
- error: `Error creating standard: ${e instanceof Error ? e.message : "Unknown error"}`
15449
- };
15450
- }
15451
- }
15452
-
15453
- // apps/cli/src/application/utils/spaceUtils.ts
15454
- function resolveSpace(spaces, slug2) {
15455
- const normalizedSlug = slug2?.replace(/^@/, "");
15456
- if (normalizedSlug) {
15457
- const found = spaces.find((s) => s.slug === normalizedSlug);
15458
- if (!found) {
15459
- const spaceList = spaces.map((s) => ` - ${s.slug} (${s.name})`).join("\n");
15460
- throw new Error(
15461
- `Space "${normalizedSlug}" not found. Available spaces:
15462
- ${spaceList}`
15463
- );
15464
- }
15465
- return found;
15466
- }
15467
- if (spaces.length > 1) {
15468
- const spaceList = spaces.map((s) => ` - ${s.slug} (${s.name})`).join("\n");
15469
- throw new Error(
15470
- `Multiple spaces found. Please specify one using --space:
15471
- ${spaceList}`
15472
- );
15473
- }
15474
- return spaces[0];
15475
- }
15476
-
15477
- // apps/cli/src/application/useCases/CreateStandardFromPlaybookUseCase.ts
15478
- var CreateStandardFromPlaybookUseCase = class {
15479
- constructor(gateway, spaceService) {
15480
- this.gateway = gateway;
15481
- this.spaceService = spaceService;
15482
- }
15483
- async execute(playbook) {
15484
- const spaces = await this.spaceService.getSpaces();
15485
- const space = resolveSpace(spaces, playbook.spaceSlug);
15486
- const standard = await this.gateway.standards.create(space.id, {
15487
- name: playbook.name,
15488
- description: playbook.description,
15489
- scope: playbook.scope,
15490
- rules: playbook.rules.map((r) => ({
15491
- content: r.content,
15492
- examples: r.examples ? [
15493
- {
15494
- lang: r.examples.language,
15495
- positive: r.examples.positive,
15496
- negative: r.examples.negative
15497
- }
15498
- ] : void 0
15499
- })),
15500
- originSkill: playbook.originSkill
15501
- });
15502
- return { standardId: standard.id, name: standard.name };
15503
- }
15504
- };
15505
-
15506
- // apps/cli/src/infra/commands/CreateStandardCommand.ts
15507
- var createStandardCommand = (0, import_cmd_ts13.command)({
15508
- name: "create",
15509
- description: "Create a coding standard from a playbook JSON file or stdin",
15510
- args: {
15511
- file: (0, import_cmd_ts13.positional)({
15512
- displayName: "file",
15513
- description: "Path to the playbook JSON file (reads from stdin if omitted)",
15514
- type: (0, import_cmd_ts13.optional)(import_cmd_ts13.string)
15515
- }),
15516
- space: (0, import_cmd_ts13.option)({
15517
- long: "space",
15518
- description: "Slug of the space in which to create the standard (with or without leading @)",
15519
- type: (0, import_cmd_ts13.optional)(SpaceSlug)
15520
- }),
15521
- originSkill: originSkillOption
15522
- },
15523
- handler: async ({ file, space, originSkill }) => {
15524
- try {
15525
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15526
- const hexa = new PackmindCliHexa(packmindLogger);
15527
- const gateway = hexa.getPackmindGateway();
15528
- const useCase = new CreateStandardFromPlaybookUseCase(
15529
- gateway,
15530
- hexa.getSpaceService()
15531
- );
15532
- const result = await createStandardHandler(
15533
- file,
15534
- useCase,
15535
- originSkill,
15536
- space ?? void 0
15537
- );
15538
- if (result.success) {
15539
- logSuccessConsole(
15540
- `Standard "${result.standardName}" created successfully (ID: ${result.standardId})`
15541
- );
15542
- process.exit(0);
15543
- } else {
15544
- logErrorConsole(`Failed to create standard: ${result.error}`);
15545
- if (result.error?.includes("Multiple spaces found")) {
15546
- logConsole(
15547
- `
15548
- Example: ${formatCommand(`packmind-cli standards create --space <slug> ${file ?? "<file>"}`)}`
15549
- );
15550
- }
15551
- process.exit(1);
15552
- }
15553
- } catch (e) {
15554
- logErrorConsole(
15555
- `Error: ${e instanceof Error ? e.message : "Unknown error"}`
15556
- );
15557
- process.exit(1);
15558
- }
15559
- }
15560
- });
15561
-
15562
- // apps/cli/src/infra/commands/ListStandardsCommand.ts
15563
- var import_cmd_ts14 = __toESM(require_cjs());
15565
+ // apps/cli/src/infra/commands/ListStandardsCommand.ts
15566
+ var import_cmd_ts14 = __toESM(require_cjs());
15564
15567
 
15565
15568
  // apps/cli/src/infra/commands/standards/listStandardsHandler.ts
15566
15569
  function groupStandardsBySpace(standards, spaces) {
@@ -15692,171 +15695,9 @@ var import_cmd_ts18 = __toESM(require_cjs());
15692
15695
 
15693
15696
  // apps/cli/src/infra/commands/CreateCommandCommand.ts
15694
15697
  var import_cmd_ts16 = __toESM(require_cjs());
15695
-
15696
- // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
15697
- var fs22 = __toESM(require("fs/promises"));
15698
-
15699
- // apps/cli/src/domain/entities/CommandPlaybookDTO.ts
15700
- var import_zod2 = require("zod");
15701
- var commandStepSchema = import_zod2.z.object({
15702
- name: import_zod2.z.string().min(1).describe("Step name/title"),
15703
- description: import_zod2.z.string().min(1).describe("Step description with implementation details"),
15704
- codeSnippet: import_zod2.z.string().optional().describe("Optional code snippet demonstrating the step")
15705
- });
15706
- var commandPlaybookDTOSchema = import_zod2.z.object({
15707
- name: import_zod2.z.string().min(1).describe("Command name"),
15708
- summary: import_zod2.z.string().min(1).describe("Command summary describing intent and value"),
15709
- whenToUse: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe("Array of scenarios when this command is applicable (minimum 1)"),
15710
- contextValidationCheckpoints: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe(
15711
- "Array of checkpoints to validate context before implementation (minimum 1)"
15712
- ),
15713
- steps: import_zod2.z.array(commandStepSchema).min(1).describe("Array of implementation steps (minimum 1)")
15714
- });
15715
-
15716
- // apps/cli/src/infra/utils/commandPlaybookValidator.ts
15717
- function validateCommandPlaybook(data) {
15718
- const result = commandPlaybookDTOSchema.safeParse(data);
15719
- if (!result.success) {
15720
- const errorList = result.error.issues;
15721
- return {
15722
- isValid: false,
15723
- errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
15724
- };
15725
- }
15726
- return {
15727
- isValid: true,
15728
- data: result.data
15729
- };
15730
- }
15731
-
15732
- // apps/cli/src/infra/utils/readCommandPlaybookFile.ts
15733
- function parseAndValidateCommandPlaybook(content) {
15734
- let parsed;
15735
- try {
15736
- parsed = JSON.parse(content);
15737
- } catch (e) {
15738
- return {
15739
- isValid: false,
15740
- errors: [
15741
- `Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
15742
- ]
15743
- };
15744
- }
15745
- return validateCommandPlaybook(parsed);
15746
- }
15747
- async function readCommandPlaybookFile(filePath) {
15748
- try {
15749
- const content = await fs22.readFile(filePath, "utf-8");
15750
- return parseAndValidateCommandPlaybook(content);
15751
- } catch (e) {
15752
- return {
15753
- isValid: false,
15754
- errors: [
15755
- `Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
15756
- ]
15757
- };
15758
- }
15759
- }
15760
-
15761
- // apps/cli/src/infra/commands/commands/createCommandHandler.ts
15762
- function buildWebappUrl(host, orgSlug, spaceSlug, commandId) {
15763
- return `${host}/org/${orgSlug}/space/${spaceSlug}/commands/${commandId}`;
15764
- }
15765
- async function createCommandHandler(filePath, useCase, originSkill, spaceSlug) {
15766
- let readResult;
15767
- if (filePath) {
15768
- readResult = await readCommandPlaybookFile(filePath);
15769
- } else {
15770
- try {
15771
- const content = await readStdin();
15772
- readResult = parseAndValidateCommandPlaybook(content);
15773
- } catch (e) {
15774
- return {
15775
- success: false,
15776
- error: e instanceof Error ? e.message : "Failed to read from stdin"
15777
- };
15778
- }
15779
- }
15780
- if (!readResult.isValid) {
15781
- return {
15782
- success: false,
15783
- error: `Validation failed: ${readResult.errors?.join(", ")}`
15784
- };
15785
- }
15786
- if (!readResult.data) {
15787
- return {
15788
- success: false,
15789
- error: "Failed to read command playbook data"
15790
- };
15791
- }
15792
- try {
15793
- const result = await useCase.execute({
15794
- ...readResult.data,
15795
- originSkill,
15796
- spaceSlug
15797
- });
15798
- let webappUrl;
15799
- const apiKey = loadApiKey();
15800
- if (apiKey) {
15801
- const decoded = decodeApiKey(apiKey);
15802
- if (decoded?.host && decoded?.jwt?.organization?.slug) {
15803
- webappUrl = buildWebappUrl(
15804
- decoded.host,
15805
- decoded.jwt.organization.slug,
15806
- result.spaceSlug,
15807
- result.commandId
15808
- );
15809
- }
15810
- }
15811
- return {
15812
- success: true,
15813
- commandId: result.commandId,
15814
- commandName: result.name,
15815
- webappUrl
15816
- };
15817
- } catch (e) {
15818
- return {
15819
- success: false,
15820
- error: `Error creating command: ${e instanceof Error ? e.message : "Unknown error"}`
15821
- };
15822
- }
15823
- }
15824
-
15825
- // apps/cli/src/application/useCases/CreateCommandFromPlaybookUseCase.ts
15826
- var CreateCommandFromPlaybookUseCase = class {
15827
- constructor(gateway, spaceService) {
15828
- this.gateway = gateway;
15829
- this.spaceService = spaceService;
15830
- }
15831
- async execute(playbook) {
15832
- const spaces = await this.spaceService.getSpaces();
15833
- const space = resolveSpace(spaces, playbook.spaceSlug);
15834
- const command30 = await this.gateway.commands.create({
15835
- spaceId: space.id,
15836
- name: playbook.name,
15837
- summary: playbook.summary,
15838
- whenToUse: playbook.whenToUse,
15839
- contextValidationCheckpoints: playbook.contextValidationCheckpoints,
15840
- steps: playbook.steps.map((step) => ({
15841
- name: step.name,
15842
- description: step.description,
15843
- codeSnippet: step.codeSnippet
15844
- })),
15845
- originSkill: playbook.originSkill
15846
- });
15847
- return {
15848
- commandId: command30.id,
15849
- name: command30.name,
15850
- slug: command30.slug,
15851
- spaceSlug: space.slug
15852
- };
15853
- }
15854
- };
15855
-
15856
- // apps/cli/src/infra/commands/CreateCommandCommand.ts
15857
15698
  var createCommandCommand = (0, import_cmd_ts16.command)({
15858
15699
  name: "create",
15859
- description: "Create a command from a playbook JSON file or stdin",
15700
+ description: "[Deprecated] Create a command from a playbook JSON file or stdin",
15860
15701
  args: {
15861
15702
  file: (0, import_cmd_ts16.positional)({
15862
15703
  displayName: "file",
@@ -15870,46 +15711,12 @@ var createCommandCommand = (0, import_cmd_ts16.command)({
15870
15711
  }),
15871
15712
  originSkill: originSkillOption
15872
15713
  },
15873
- handler: async ({ file, space, originSkill }) => {
15874
- try {
15875
- const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15876
- const hexa = new PackmindCliHexa(packmindLogger);
15877
- const gateway = hexa.getPackmindGateway();
15878
- const useCase = new CreateCommandFromPlaybookUseCase(
15879
- gateway,
15880
- hexa.getSpaceService()
15881
- );
15882
- const result = await createCommandHandler(
15883
- file,
15884
- useCase,
15885
- originSkill,
15886
- space ?? void 0
15887
- );
15888
- if (result.success) {
15889
- logSuccessConsole(
15890
- `Command "${result.commandName}" created successfully (ID: ${result.commandId})`
15891
- );
15892
- if (result.webappUrl) {
15893
- logConsole("");
15894
- logConsole(`View it in the webapp: ${result.webappUrl}`);
15895
- }
15896
- process.exit(0);
15897
- } else {
15898
- logErrorConsole(`Failed to create command: ${result.error}`);
15899
- if (result.error?.includes("Multiple spaces found")) {
15900
- logConsole(
15901
- `
15902
- Example: ${formatCommand(`packmind-cli commands create --space <slug> ${file ?? "<file>"}`)}`
15903
- );
15904
- }
15905
- process.exit(1);
15906
- }
15907
- } catch (e) {
15908
- logErrorConsole(
15909
- `Error: ${e instanceof Error ? e.message : "Unknown error"}`
15910
- );
15911
- process.exit(1);
15912
- }
15714
+ handler: async () => {
15715
+ logErrorConsole('Command "packmind-cli commands create" has been removed.');
15716
+ logConsole(
15717
+ `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15718
+ );
15719
+ process.exit(1);
15913
15720
  }
15914
15721
  });
15915
15722
 
@@ -16038,7 +15845,7 @@ var import_cmd_ts19 = __toESM(require_cjs());
16038
15845
 
16039
15846
  // apps/cli/src/infra/commands/playbook/diffArtefactsHandler.ts
16040
15847
  var nodePath = __toESM(require("path"));
16041
- var fs23 = __toESM(require("fs/promises"));
15848
+ var fs22 = __toESM(require("fs/promises"));
16042
15849
 
16043
15850
  // apps/cli/src/infra/utils/diffFormatter.ts
16044
15851
  var import_diff4 = require("diff");
@@ -16322,7 +16129,7 @@ async function diffArtefactsHandler(deps) {
16322
16129
  const searchPath = nodePath.resolve(cwd, deps.path ?? ".");
16323
16130
  if (deps.path !== void 0) {
16324
16131
  try {
16325
- await fs23.stat(searchPath);
16132
+ await fs22.stat(searchPath);
16326
16133
  } catch {
16327
16134
  logErrorConsole(`Path does not exist: ${searchPath}`);
16328
16135
  exit(1);
@@ -16478,7 +16285,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
16478
16285
  description: "Subcommand and arguments (e.g., add <path>, remove <path>)"
16479
16286
  })
16480
16287
  },
16481
- handler: async ({ submit, includeSubmitted, message, path: path33, positionals }) => {
16288
+ handler: async ({ submit, includeSubmitted, message, path: path36, positionals }) => {
16482
16289
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
16483
16290
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
16484
16291
  if (submit) {
@@ -16494,7 +16301,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
16494
16301
  process.exit(1);
16495
16302
  }
16496
16303
  if (positionals[0] === "add") {
16497
- const addFilePath = path33 && positionals[1] ? `${path33}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
16304
+ const addFilePath = path36 && positionals[1] ? `${path36}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
16498
16305
  const addCommand = `packmind-cli playbook add ${addFilePath}`;
16499
16306
  logErrorConsole("Deprecated: `packmind-cli diff add` has been removed");
16500
16307
  logInfoConsole("Use the following command instead:");
@@ -16502,7 +16309,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
16502
16309
  process.exit(1);
16503
16310
  }
16504
16311
  if (positionals[0] === "remove" || positionals[0] === "rm") {
16505
- const removeFilePath = path33 && positionals[1] ? `${path33}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
16312
+ const removeFilePath = path36 && positionals[1] ? `${path36}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
16506
16313
  const removeCommand = `packmind-cli playbook remove ${removeFilePath}`;
16507
16314
  logErrorConsole(
16508
16315
  "Deprecated: `packmind-cli diff remove` has been removed"
@@ -16511,7 +16318,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
16511
16318
  logInfoConsole(` ${formatCommand(removeCommand)}`);
16512
16319
  process.exit(1);
16513
16320
  }
16514
- const diffCommand3 = `packmind-cli playbook diff${includeSubmitted ? " --include-submitted" : ""}${path33 ? ` --path ${path33}` : ""}`;
16321
+ const diffCommand3 = `packmind-cli playbook diff${includeSubmitted ? " --include-submitted" : ""}${path36 ? ` --path ${path36}` : ""}`;
16515
16322
  logErrorConsole("Deprecated: `packmind-cli diff` will be removed");
16516
16323
  logInfoConsole("Use the following command instead:");
16517
16324
  logInfoConsole(` ${formatCommand(diffCommand3)}`);
@@ -16521,7 +16328,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
16521
16328
  getCwd: () => process.cwd(),
16522
16329
  log: console.log,
16523
16330
  includeSubmitted,
16524
- path: path33
16331
+ path: path36
16525
16332
  });
16526
16333
  }
16527
16334
  });
@@ -16536,7 +16343,7 @@ var import_cmd_ts20 = __toESM(require_cjs());
16536
16343
  function toExpectedSlug(name) {
16537
16344
  return name.toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
16538
16345
  }
16539
- function buildWebappUrl2(host, orgSlug, spaceSlug, packageId) {
16346
+ function buildWebappUrl(host, orgSlug, spaceSlug, packageId) {
16540
16347
  return `${host}/org/${orgSlug}/space/${spaceSlug}/packages/${packageId}`;
16541
16348
  }
16542
16349
  async function createPackageHandler(name, description, useCase, originSkill, spaceSlug) {
@@ -16556,7 +16363,7 @@ async function createPackageHandler(name, description, useCase, originSkill, spa
16556
16363
  if (apiKey) {
16557
16364
  const decoded = decodeApiKey(apiKey);
16558
16365
  if (decoded?.host && decoded?.jwt?.organization?.slug) {
16559
- webappUrl = buildWebappUrl2(
16366
+ webappUrl = buildWebappUrl(
16560
16367
  decoded.host,
16561
16368
  decoded.jwt.organization.slug,
16562
16369
  result.spaceSlug,
@@ -16587,15 +16394,15 @@ var CreatePackageUseCase = class {
16587
16394
  this.gateway = gateway;
16588
16395
  this.spaceService = spaceService;
16589
16396
  }
16590
- async execute(command30) {
16591
- const space = await this.getSpace(command30);
16397
+ async execute(command33) {
16398
+ const space = await this.getSpace(command33);
16592
16399
  const result = await this.gateway.packages.create({
16593
16400
  spaceId: space.id,
16594
- name: command30.name,
16595
- description: command30.description ?? "",
16401
+ name: command33.name,
16402
+ description: command33.description ?? "",
16596
16403
  recipeIds: [],
16597
16404
  standardIds: [],
16598
- originSkill: command30.originSkill
16405
+ originSkill: command33.originSkill
16599
16406
  });
16600
16407
  return {
16601
16408
  packageId: result.package.id,
@@ -16604,12 +16411,12 @@ var CreatePackageUseCase = class {
16604
16411
  spaceSlug: space.slug
16605
16412
  };
16606
16413
  }
16607
- async getSpace(command30) {
16414
+ async getSpace(command33) {
16608
16415
  const spaces = await this.spaceService.getSpaces();
16609
- if (command30.spaceSlug) {
16610
- const found = spaces.find((s) => s.slug === command30.spaceSlug);
16416
+ if (command33.spaceSlug) {
16417
+ const found = spaces.find((s) => s.slug === command33.spaceSlug);
16611
16418
  if (!found) {
16612
- throw new Error(`Space '${command30.spaceSlug}' not found.`);
16419
+ throw new Error(`Space '${command33.spaceSlug}' not found.`);
16613
16420
  }
16614
16421
  return found;
16615
16422
  }
@@ -16703,11 +16510,11 @@ var import_cmd_ts21 = __toESM(require_cjs());
16703
16510
 
16704
16511
  // apps/cli/src/domain/errors/ItemNotFoundError.ts
16705
16512
  var ItemNotFoundError = class extends Error {
16706
- constructor(itemType, slug2, spaceSlug) {
16707
- const message = spaceSlug ? `${itemType} '${slug2}' not found in space '@${spaceSlug}'` : `${itemType} '${slug2}' not found`;
16513
+ constructor(itemType, slug3, spaceSlug) {
16514
+ const message = spaceSlug ? `${itemType} '${slug3}' not found in space '@${spaceSlug}'` : `${itemType} '${slug3}' not found`;
16708
16515
  super(message);
16709
16516
  this.itemType = itemType;
16710
- this.slug = slug2;
16517
+ this.slug = slug3;
16711
16518
  this.spaceSlug = spaceSlug;
16712
16519
  this.name = "ItemNotFoundError";
16713
16520
  }
@@ -16719,8 +16526,8 @@ var AddToPackageUseCase = class {
16719
16526
  this.gateway = gateway;
16720
16527
  this.spaceService = spaceService;
16721
16528
  }
16722
- async execute(command30) {
16723
- const { packageSlug, spaceSlug, itemType, itemSlugs } = command30;
16529
+ async execute(command33) {
16530
+ const { packageSlug, spaceSlug, itemType, itemSlugs } = command33;
16724
16531
  const space = spaceSlug ? await this.resolveSpaceBySlug(spaceSlug) : await this.spaceService.getDefaultSpace();
16725
16532
  const packages = await this.gateway.packages.list({
16726
16533
  spaceId: space.id
@@ -16741,7 +16548,7 @@ var AddToPackageUseCase = class {
16741
16548
  standardIds: [],
16742
16549
  recipeIds: [],
16743
16550
  skillIds: [],
16744
- originSkill: command30.originSkill
16551
+ originSkill: command33.originSkill
16745
16552
  };
16746
16553
  if (itemType === "standard") {
16747
16554
  addCommand.standardIds = ids.map(createStandardId);
@@ -16770,34 +16577,34 @@ var AddToPackageUseCase = class {
16770
16577
  async resolveSlugsToIds(itemType, slugs, spaceId, spaceSlug) {
16771
16578
  const ids = [];
16772
16579
  const idToSlugMap = /* @__PURE__ */ new Map();
16773
- for (const slug2 of slugs) {
16580
+ for (const slug3 of slugs) {
16774
16581
  let item = null;
16775
16582
  if (itemType === "standard") {
16776
- item = await this.findStandardBySlug(slug2, spaceId);
16583
+ item = await this.findStandardBySlug(slug3, spaceId);
16777
16584
  } else if (itemType === "command") {
16778
- item = await this.findCommandBySlug(slug2, spaceId);
16585
+ item = await this.findCommandBySlug(slug3, spaceId);
16779
16586
  } else if (itemType === "skill") {
16780
- item = await this.findSkillBySlug(slug2, spaceId);
16587
+ item = await this.findSkillBySlug(slug3, spaceId);
16781
16588
  }
16782
16589
  if (!item) {
16783
- throw new ItemNotFoundError(itemType, slug2, spaceSlug);
16590
+ throw new ItemNotFoundError(itemType, slug3, spaceSlug);
16784
16591
  }
16785
16592
  ids.push(item.id);
16786
- idToSlugMap.set(item.id, slug2);
16593
+ idToSlugMap.set(item.id, slug3);
16787
16594
  }
16788
16595
  return { ids, idToSlugMap };
16789
16596
  }
16790
- async findStandardBySlug(slug2, spaceId) {
16597
+ async findStandardBySlug(slug3, spaceId) {
16791
16598
  const standards = await this.gateway.standards.list({ spaceId });
16792
- return standards.standards.find((standard) => standard.slug === slug2) ?? null;
16599
+ return standards.standards.find((standard) => standard.slug === slug3) ?? null;
16793
16600
  }
16794
- async findCommandBySlug(slug2, spaceId) {
16601
+ async findCommandBySlug(slug3, spaceId) {
16795
16602
  const commands = await this.gateway.commands.list({ spaceId });
16796
- return commands.recipes.find((command30) => command30.slug === slug2) ?? null;
16603
+ return commands.recipes.find((command33) => command33.slug === slug3) ?? null;
16797
16604
  }
16798
- async findSkillBySlug(slug2, spaceId) {
16605
+ async findSkillBySlug(slug3, spaceId) {
16799
16606
  const skills = await this.gateway.skills.list({ spaceId });
16800
- return skills.find((skill) => skill.slug === slug2) ?? null;
16607
+ return skills.find((skill) => skill.slug === slug3) ?? null;
16801
16608
  }
16802
16609
  };
16803
16610
 
@@ -16871,11 +16678,11 @@ async function executeAddToPackage(pkgSlug, spaceSlug, itemType, itemSlugs, useC
16871
16678
  logErrorConsole(message);
16872
16679
  if (error instanceof ItemNotFoundError) {
16873
16680
  const spaceFlag = error.spaceSlug ? ` --space ${error.spaceSlug}` : "";
16874
- const command30 = formatCommand(
16681
+ const command33 = formatCommand(
16875
16682
  `packmind-cli ${error.itemType}s list${spaceFlag}`
16876
16683
  );
16877
16684
  logInfoConsole(
16878
- `Run \`${command30}\` to display available ${error.itemType}s`
16685
+ `Run \`${command33}\` to display available ${error.itemType}s`
16879
16686
  );
16880
16687
  }
16881
16688
  return { success: false, error: message };
@@ -16993,10 +16800,10 @@ var showPackageCommand = (0, import_cmd_ts23.command)({
16993
16800
  description: "Package slug (e.g. backend or @my-space/backend)"
16994
16801
  })
16995
16802
  },
16996
- handler: async ({ slug: slug2 }) => {
16803
+ handler: async ({ slug: slug3 }) => {
16997
16804
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
16998
16805
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
16999
- await showPackageHandler({ slug: slug2 }, { packmindCliHexa, exit: process.exit });
16806
+ await showPackageHandler({ slug: slug3 }, { packmindCliHexa, exit: process.exit });
17000
16807
  }
17001
16808
  });
17002
16809
 
@@ -17020,13 +16827,13 @@ var import_fs21 = require("fs");
17020
16827
  var import_cmd_ts25 = __toESM(require_cjs());
17021
16828
 
17022
16829
  // apps/cli/src/infra/commands/playbook/addHandler.ts
17023
- var fs24 = __toESM(require("fs"));
17024
- var path25 = __toESM(require("path"));
16830
+ var fs23 = __toESM(require("fs"));
16831
+ var path26 = __toESM(require("path"));
17025
16832
  var yaml2 = __toESM(require("yaml"));
17026
16833
  var import_slug = __toESM(require("slug"));
17027
16834
 
17028
16835
  // apps/cli/src/application/utils/parseCommandFile.ts
17029
- var path22 = __toESM(require("path"));
16836
+ var path23 = __toESM(require("path"));
17030
16837
  var FRONTMATTER_DELIMITER3 = "---";
17031
16838
  function parseCommandFile(content, filePath) {
17032
16839
  content = normalizeLineEndings(content);
@@ -17082,16 +16889,16 @@ function stripYamlQuotes2(value) {
17082
16889
  return value;
17083
16890
  }
17084
16891
  function extractFilenameSlug(filePath) {
17085
- let basename2 = path22.basename(filePath);
17086
- if (basename2.endsWith(".prompt.md")) {
17087
- basename2 = basename2.slice(0, -".prompt.md".length);
17088
- } else if (basename2.endsWith(".md")) {
17089
- basename2 = basename2.slice(0, -".md".length);
16892
+ let basename4 = path23.basename(filePath);
16893
+ if (basename4.endsWith(".prompt.md")) {
16894
+ basename4 = basename4.slice(0, -".prompt.md".length);
16895
+ } else if (basename4.endsWith(".md")) {
16896
+ basename4 = basename4.slice(0, -".md".length);
17090
16897
  }
17091
- return basename2;
16898
+ return basename4;
17092
16899
  }
17093
- function humanizeSlug(slug2) {
17094
- const words = slug2.replace(/[-_]/g, " ");
16900
+ function humanizeSlug(slug3) {
16901
+ const words = slug3.replace(/[-_]/g, " ");
17095
16902
  return words.charAt(0).toUpperCase() + words.slice(1);
17096
16903
  }
17097
16904
 
@@ -17249,7 +17056,7 @@ function parseSkillDirectory(files) {
17249
17056
  }
17250
17057
 
17251
17058
  // apps/cli/src/application/utils/findNearestConfigDir.ts
17252
- var path23 = __toESM(require("path"));
17059
+ var path24 = __toESM(require("path"));
17253
17060
  async function findNearestConfigDir(startDir, packmindCliHexa) {
17254
17061
  let current = startDir;
17255
17062
  while (true) {
@@ -17257,7 +17064,7 @@ async function findNearestConfigDir(startDir, packmindCliHexa) {
17257
17064
  if (exists) {
17258
17065
  return current;
17259
17066
  }
17260
- const parent = path23.dirname(current);
17067
+ const parent = path24.dirname(current);
17261
17068
  if (parent === current) {
17262
17069
  return null;
17263
17070
  }
@@ -17266,7 +17073,7 @@ async function findNearestConfigDir(startDir, packmindCliHexa) {
17266
17073
  }
17267
17074
 
17268
17075
  // apps/cli/src/application/utils/resolveDeployedContext.ts
17269
- var path24 = __toESM(require("path"));
17076
+ var path25 = __toESM(require("path"));
17270
17077
  async function resolveDeployedContext(packmindCliHexa, targetDir) {
17271
17078
  try {
17272
17079
  const space = await packmindCliHexa.getDefaultSpace();
@@ -17278,7 +17085,7 @@ async function resolveDeployedContext(packmindCliHexa, targetDir) {
17278
17085
  }
17279
17086
  const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
17280
17087
  const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
17281
- const rel = path24.relative(gitRoot, targetDir);
17088
+ const rel = path25.relative(gitRoot, targetDir);
17282
17089
  const relativePath = rel.startsWith("..") ? "/" : rel ? `/${rel}/` : "/";
17283
17090
  const deployedContent = await packmindCliHexa.getPackmindGateway().deployment.getDeployed({
17284
17091
  packagesSlugs: configPackages,
@@ -17343,19 +17150,19 @@ async function fetchDeployedFiles(gateway, lockFile) {
17343
17150
 
17344
17151
  // apps/cli/src/infra/commands/playbook/addHandler.ts
17345
17152
  async function tryStageRemovedFromLockFile(resolvedPath, deps) {
17346
- const fileDir = path25.dirname(resolvedPath);
17153
+ const fileDir = path26.dirname(resolvedPath);
17347
17154
  const targetDir = await findNearestConfigDir(fileDir, deps.packmindCliHexa);
17348
17155
  if (!targetDir) return false;
17349
17156
  const lockFile = await deps.lockFileRepository.read(targetDir);
17350
17157
  if (!lockFile) return false;
17351
- const normalizedPath = normalizePath2(path25.relative(targetDir, resolvedPath));
17158
+ const normalizedPath = normalizePath2(path26.relative(targetDir, resolvedPath));
17352
17159
  const lockEntry = findLockFileEntryForPath(
17353
17160
  normalizedPath,
17354
17161
  lockFile.artifacts
17355
17162
  );
17356
17163
  if (!lockEntry) return false;
17357
17164
  const gitRoot = await deps.packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
17358
- const configDir = gitRoot ? normalizePath2(path25.relative(gitRoot, targetDir)) : "";
17165
+ const configDir = gitRoot ? normalizePath2(path26.relative(gitRoot, targetDir)) : "";
17359
17166
  const deployedContext = await resolveDeployedContext(
17360
17167
  deps.packmindCliHexa,
17361
17168
  targetDir
@@ -17379,27 +17186,30 @@ async function tryStageRemovedFromLockFile(resolvedPath, deps) {
17379
17186
  logSuccessConsole(
17380
17187
  `Staged "${lockEntry.name}" (${lockEntry.type}, removed) to playbook${spaceInfo}`
17381
17188
  );
17189
+ logInfoConsole(
17190
+ `Run ${formatLabel("packmind playbook submit")} when you're ready to publish your changes.`
17191
+ );
17382
17192
  deps.exit(0);
17383
17193
  return true;
17384
17194
  }
17385
17195
  function resolveSkillDirectoryRoot(absolutePath) {
17386
17196
  if (absolutePath.endsWith("SKILL.md")) {
17387
- return path25.dirname(absolutePath);
17197
+ return path26.dirname(absolutePath);
17388
17198
  }
17389
17199
  try {
17390
- if (fs24.statSync(absolutePath).isDirectory()) {
17200
+ if (fs23.statSync(absolutePath).isDirectory()) {
17391
17201
  return absolutePath;
17392
17202
  }
17393
17203
  } catch {
17394
17204
  return absolutePath;
17395
17205
  }
17396
- let current = path25.dirname(absolutePath);
17397
- const root = path25.parse(current).root;
17206
+ let current = path26.dirname(absolutePath);
17207
+ const root = path26.parse(current).root;
17398
17208
  while (current !== root) {
17399
- if (fs24.existsSync(path25.join(current, "SKILL.md"))) {
17209
+ if (fs23.existsSync(path26.join(current, "SKILL.md"))) {
17400
17210
  return current;
17401
17211
  }
17402
- current = path25.dirname(current);
17212
+ current = path26.dirname(current);
17403
17213
  }
17404
17214
  return absolutePath;
17405
17215
  }
@@ -17410,7 +17220,7 @@ async function playbookAddHandler(deps) {
17410
17220
  spaceSlug,
17411
17221
  exit,
17412
17222
  cwd,
17413
- readFile: readFile12,
17223
+ readFile: readFile10,
17414
17224
  readSkillDirectory: readSkillDirectory2,
17415
17225
  playbookLocalRepository,
17416
17226
  lockFileRepository
@@ -17422,17 +17232,17 @@ async function playbookAddHandler(deps) {
17422
17232
  exit(1);
17423
17233
  return;
17424
17234
  }
17425
- const absolutePath = path25.resolve(cwd, filePath);
17235
+ const absolutePath = path26.resolve(cwd, filePath);
17426
17236
  let artifactType;
17427
17237
  let codingAgent;
17428
17238
  const earlyTargetDir = await findNearestConfigDir(
17429
- path25.dirname(absolutePath),
17239
+ path26.dirname(absolutePath),
17430
17240
  packmindCliHexa
17431
17241
  );
17432
17242
  const earlyLockFile = earlyTargetDir ? await lockFileRepository.read(earlyTargetDir) : null;
17433
17243
  if (earlyLockFile && earlyTargetDir) {
17434
17244
  const normalizedForLookup = normalizePath2(
17435
- path25.relative(earlyTargetDir, absolutePath)
17245
+ path26.relative(earlyTargetDir, absolutePath)
17436
17246
  );
17437
17247
  const lockResult = findLockFileEntryAndFileForPath(
17438
17248
  normalizedForLookup,
@@ -17512,7 +17322,7 @@ async function playbookAddHandler(deps) {
17512
17322
  localContent = skillMdFile?.content ?? serializedContent;
17513
17323
  } else {
17514
17324
  try {
17515
- localContent = readFile12(absolutePath);
17325
+ localContent = readFile10(absolutePath);
17516
17326
  } catch (err) {
17517
17327
  const staged = await tryStageRemovedFromLockFile(absolutePath, {
17518
17328
  packmindCliHexa,
@@ -17566,7 +17376,7 @@ Content goes here...`
17566
17376
  return;
17567
17377
  }
17568
17378
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
17569
- const configDir = gitRoot ? normalizePath2(path25.relative(gitRoot, targetDir)) : "";
17379
+ const configDir = gitRoot ? normalizePath2(path26.relative(gitRoot, targetDir)) : "";
17570
17380
  const deployedContext = await resolveDeployedContext(
17571
17381
  packmindCliHexa,
17572
17382
  targetDir
@@ -17574,11 +17384,21 @@ Content goes here...`
17574
17384
  const targetId = deployedContext?.targetId ?? earlyLockFile?.targetId;
17575
17385
  const normalizedFilePath = (() => {
17576
17386
  const refPath = artifactType === "skill" && skillDirPath ? skillDirPath : absolutePath;
17577
- return normalizePath2(path25.relative(targetDir, refPath));
17387
+ return normalizePath2(path26.relative(targetDir, refPath));
17578
17388
  })();
17579
17389
  let spaceId;
17580
17390
  let spaceName;
17581
17391
  const allSpaces = await packmindCliHexa.getSpaces();
17392
+ const existingLockEntry = earlyLockFile && findLockFileEntryForPath(normalizedFilePath, earlyLockFile.artifacts);
17393
+ if (existingLockEntry && !spaceSlug && !allSpaces.some((s) => s.id === existingLockEntry.spaceId)) {
17394
+ logErrorConsole(
17395
+ `Cannot add changes to this ${artifactType}: the space it belongs to is not available to you.
17396
+ Use --space to stage it as a new artifact in an accessible space:
17397
+ ${formatSpaceList(allSpaces)}`
17398
+ );
17399
+ exit(1);
17400
+ return;
17401
+ }
17582
17402
  if (spaceSlug) {
17583
17403
  const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
17584
17404
  if (!matchedSpace) {
@@ -17595,7 +17415,6 @@ ${formatSpaceList(allSpaces)}`
17595
17415
  spaceId = allSpaces[0].id;
17596
17416
  spaceName = allSpaces[0].name;
17597
17417
  } else {
17598
- const existingLockEntry = earlyLockFile && findLockFileEntryForPath(normalizedFilePath, earlyLockFile.artifacts);
17599
17418
  if (existingLockEntry) {
17600
17419
  spaceId = existingLockEntry.spaceId;
17601
17420
  spaceName = allSpaces.find((s) => s.id === spaceId)?.name;
@@ -17620,11 +17439,34 @@ Example: packmind-cli playbook add --space ${allSpaces[0].slug} <path>`
17620
17439
  changeType = "updated";
17621
17440
  }
17622
17441
  }
17623
- if (changeType === "created") {
17442
+ if (changeType === "updated" && existingLockEntry) {
17624
17443
  try {
17625
- const existingNames = await listExistingArtifactNames(
17626
- packmindCliHexa,
17627
- artifactType,
17444
+ const packmindGateway = packmindCliHexa.getPackmindGateway();
17445
+ const { version: remoteVersion } = await packmindGateway.deployment.getLatestVersion(
17446
+ existingLockEntry.type,
17447
+ existingLockEntry.id,
17448
+ existingLockEntry.spaceId
17449
+ );
17450
+ if (existingLockEntry.version < remoteVersion) {
17451
+ logErrorConsole(
17452
+ `"${artifactName}" is outdated (local: v${existingLockEntry.version}, remote: v${remoteVersion}).
17453
+ Run ${formatLabel("packmind-cli install")} to update before making changes.`
17454
+ );
17455
+ exit(1);
17456
+ return;
17457
+ }
17458
+ } catch (err) {
17459
+ const errorMessage = err instanceof Error ? err.message : String(err);
17460
+ logErrorConsole(`Failed to check artifact version: ${errorMessage}`);
17461
+ exit(1);
17462
+ return;
17463
+ }
17464
+ }
17465
+ if (changeType === "created") {
17466
+ try {
17467
+ const existingNames = await listExistingArtifactNames(
17468
+ packmindCliHexa,
17469
+ artifactType,
17628
17470
  spaceId
17629
17471
  );
17630
17472
  const nameExists = existingNames.some(
@@ -17657,7 +17499,7 @@ Example: packmind-cli playbook add --space ${allSpaces[0].slug} <path>`
17657
17499
  );
17658
17500
  const allMatch = skillDeployedFiles.length > 0 && skillDeployedFiles.length === skillFiles.length && skillDeployedFiles.every((deployed) => {
17659
17501
  const localFile = skillFiles.find(
17660
- (f) => normalizePath2(path25.join(normalizedFilePath, f.relativePath)) === normalizePath2(deployed.path)
17502
+ (f) => normalizePath2(path26.join(normalizedFilePath, f.relativePath)) === normalizePath2(deployed.path)
17661
17503
  );
17662
17504
  return localFile && deployed.content?.trim() === localFile.content.trim() && (!deployed.skillFilePermissions || deployed.skillFilePermissions === localFile.permissions);
17663
17505
  });
@@ -17694,6 +17536,9 @@ Example: packmind-cli playbook add --space ${allSpaces[0].slug} <path>`
17694
17536
  logSuccessConsole(
17695
17537
  `Staged "${artifactName}" (${artifactType}, ${changeType}) to playbook${spaceInfo}. ${formatLabel(codingAgent)}`
17696
17538
  );
17539
+ logInfoConsole(
17540
+ `Run ${formatLabel("packmind playbook submit")} when you're ready to publish your changes.`
17541
+ );
17697
17542
  exit(0);
17698
17543
  }
17699
17544
  async function listExistingArtifactNames(packmindCliHexa, artifactType, spaceId) {
@@ -17766,7 +17611,8 @@ var addPlaybookCommand = (0, import_cmd_ts25.command)({
17766
17611
  var import_cmd_ts26 = __toESM(require_cjs());
17767
17612
 
17768
17613
  // apps/cli/src/infra/commands/playbook/rmHandler.ts
17769
- var path26 = __toESM(require("path"));
17614
+ var fs24 = __toESM(require("fs"));
17615
+ var path27 = __toESM(require("path"));
17770
17616
  function isSkillSupportFile(absolutePath) {
17771
17617
  const normalized = absolutePath.replace(/\\/g, "/");
17772
17618
  const skillDirMatch = normalized.match(/\/skills\/[^/]+\//);
@@ -17793,9 +17639,14 @@ async function playbookRmHandler(deps) {
17793
17639
  exit(1);
17794
17640
  return;
17795
17641
  }
17796
- const absolutePath = path26.resolve(getCwd(), filePath);
17642
+ const absolutePath = path27.resolve(getCwd(), filePath);
17643
+ if (!fs24.existsSync(absolutePath)) {
17644
+ logErrorConsole(`File not found: "${filePath}"`);
17645
+ exit(1);
17646
+ return;
17647
+ }
17797
17648
  const targetDir = await findNearestConfigDir(
17798
- path26.dirname(absolutePath),
17649
+ path27.dirname(absolutePath),
17799
17650
  packmindCliHexa
17800
17651
  );
17801
17652
  if (!targetDir) {
@@ -17812,7 +17663,7 @@ async function playbookRmHandler(deps) {
17812
17663
  return;
17813
17664
  }
17814
17665
  const normalizedForLookup = normalizePath2(
17815
- path26.relative(targetDir, absolutePath)
17666
+ path27.relative(targetDir, absolutePath)
17816
17667
  );
17817
17668
  const lockResult = findLockFileEntryAndFileForPath(
17818
17669
  normalizedForLookup,
@@ -17834,7 +17685,7 @@ async function playbookRmHandler(deps) {
17834
17685
  }
17835
17686
  const resolvedAbsolutePath = artifactType === "skill" ? resolveSkillDirPath(absolutePath) : absolutePath;
17836
17687
  const normalizedFilePath = normalizePath2(
17837
- path26.relative(targetDir, resolvedAbsolutePath)
17688
+ path27.relative(targetDir, resolvedAbsolutePath)
17838
17689
  );
17839
17690
  const lockEntry = findLockFileEntryAndFileForPath(normalizedFilePath, lockFile.artifacts)?.entry ?? lockResult.entry;
17840
17691
  if (!lockEntry) {
@@ -17852,9 +17703,17 @@ async function playbookRmHandler(deps) {
17852
17703
  return;
17853
17704
  }
17854
17705
  const allSpaces = await packmindCliHexa.getSpaces();
17855
- const spaceName = allSpaces.find((s) => s.id === lockEntry.spaceId)?.name;
17706
+ const matchingSpace = allSpaces.find((s) => s.id === lockEntry.spaceId);
17707
+ if (!matchingSpace) {
17708
+ logErrorConsole(
17709
+ `Cannot remove this ${lockEntry.type}: the space it belongs to is not available to you`
17710
+ );
17711
+ exit(1);
17712
+ return;
17713
+ }
17714
+ const spaceName = matchingSpace.name;
17856
17715
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
17857
- const configDir = gitRoot ? normalizePath2(path26.relative(gitRoot, targetDir)) : "";
17716
+ const configDir = gitRoot ? normalizePath2(path27.relative(gitRoot, targetDir)) : "";
17858
17717
  const deployedContext = await resolveDeployedContext(
17859
17718
  packmindCliHexa,
17860
17719
  targetDir
@@ -17915,7 +17774,7 @@ var rmPlaybookCommand = (0, import_cmd_ts26.command)({
17915
17774
  var import_cmd_ts27 = __toESM(require_cjs());
17916
17775
 
17917
17776
  // apps/cli/src/infra/commands/playbook/unstageHandler.ts
17918
- var path27 = __toESM(require("path"));
17777
+ var path28 = __toESM(require("path"));
17919
17778
  async function playbookUnstageHandler(deps) {
17920
17779
  const {
17921
17780
  packmindCliHexa,
@@ -17933,10 +17792,10 @@ async function playbookUnstageHandler(deps) {
17933
17792
  return;
17934
17793
  }
17935
17794
  const cwd = getCwd();
17936
- const absolutePath = path27.resolve(cwd, filePath);
17795
+ const absolutePath = path28.resolve(cwd, filePath);
17937
17796
  const resolvedPath = resolveSkillDirPath(absolutePath);
17938
17797
  const configDir = await findNearestConfigDir(
17939
- path27.dirname(resolvedPath),
17798
+ path28.dirname(resolvedPath),
17940
17799
  packmindCliHexa
17941
17800
  );
17942
17801
  if (!configDir) {
@@ -17949,10 +17808,10 @@ async function playbookUnstageHandler(deps) {
17949
17808
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
17950
17809
  const baseDir = gitRoot ?? configDir;
17951
17810
  const normalizedFilePath = normalizePath2(
17952
- path27.relative(baseDir, resolvedPath)
17811
+ path28.relative(baseDir, resolvedPath)
17953
17812
  );
17954
17813
  const matchingEntries = playbookLocalRepository.getChanges().filter((c) => {
17955
- const fullEntryPath = c.configDir ? normalizePath2(path27.join(c.configDir, c.filePath)) : c.filePath;
17814
+ const fullEntryPath = c.configDir ? normalizePath2(path28.join(c.configDir, c.filePath)) : c.filePath;
17956
17815
  return fullEntryPath === normalizedFilePath;
17957
17816
  });
17958
17817
  if (matchingEntries.length === 0) {
@@ -18036,15 +17895,15 @@ var import_cmd_ts28 = __toESM(require_cjs());
18036
17895
 
18037
17896
  // apps/cli/src/infra/utils/listDirectoryFiles.ts
18038
17897
  var import_fs22 = require("fs");
18039
- var path28 = __toESM(require("path"));
17898
+ var path29 = __toESM(require("path"));
18040
17899
  function listDirectoryFiles(dirPath) {
18041
17900
  const results = [];
18042
17901
  const entries = (0, import_fs22.readdirSync)(dirPath, { withFileTypes: true });
18043
17902
  for (const entry of entries) {
18044
- const fullPath = path28.join(dirPath, entry.name);
17903
+ const fullPath = path29.join(dirPath, entry.name);
18045
17904
  if (entry.isDirectory()) {
18046
17905
  for (const nested of listDirectoryFiles(fullPath)) {
18047
- results.push(path28.join(entry.name, nested));
17906
+ results.push(path29.join(entry.name, nested));
18048
17907
  }
18049
17908
  } else if (entry.isFile()) {
18050
17909
  results.push(entry.name);
@@ -18054,7 +17913,7 @@ function listDirectoryFiles(dirPath) {
18054
17913
  }
18055
17914
 
18056
17915
  // apps/cli/src/infra/commands/playbook/statusHandler.ts
18057
- var path29 = __toESM(require("path"));
17916
+ var path30 = __toESM(require("path"));
18058
17917
 
18059
17918
  // apps/cli/src/infra/utils/stringUtils.ts
18060
17919
  function capitalize(s) {
@@ -18089,7 +17948,7 @@ function groupStagedChanges(changes, cwd, gitRoot) {
18089
17948
  const changeType = change.changeType ?? "updated";
18090
17949
  const key = `${change.artifactType}:${change.artifactName}:${changeType}`;
18091
17950
  const rootRelativePath = change.configDir ? `${change.configDir}/${change.filePath}` : change.filePath;
18092
- const displayPath = gitRoot ? normalizePath2(path29.relative(cwd, path29.join(gitRoot, rootRelativePath))) : rootRelativePath;
17951
+ const displayPath = gitRoot ? normalizePath2(path30.relative(cwd, path30.join(gitRoot, rootRelativePath))) : rootRelativePath;
18093
17952
  const existing = groups.get(key);
18094
17953
  if (existing) {
18095
17954
  existing.filePaths.push(displayPath);
@@ -18130,7 +17989,7 @@ async function playbookStatusHandler(deps) {
18130
17989
  lockFileRepository,
18131
17990
  cwd,
18132
17991
  exit,
18133
- readFile: readFile12,
17992
+ readFile: readFile10,
18134
17993
  listDirectoryFiles: listDirectoryFiles2,
18135
17994
  getFileMode
18136
17995
  } = deps;
@@ -18147,12 +18006,12 @@ async function playbookStatusHandler(deps) {
18147
18006
  const fallbackConfigDir = await findNearestConfigDir(cwd, packmindCliHexa);
18148
18007
  const configDirs = /* @__PURE__ */ new Set([...stagedByConfigDir.keys()]);
18149
18008
  if (fallbackConfigDir && !configDirs.has("__cwd__")) {
18150
- const rel = gitRoot ? normalizePath2(path29.relative(gitRoot, fallbackConfigDir)) : "";
18009
+ const rel = gitRoot ? normalizePath2(path30.relative(gitRoot, fallbackConfigDir)) : "";
18151
18010
  if (!configDirs.has(rel)) configDirs.add(rel);
18152
18011
  }
18153
18012
  const descendantDirs = await packmindCliHexa.findDescendantConfigs(cwd);
18154
18013
  for (const descendantDir of descendantDirs) {
18155
- const rel = gitRoot ? normalizePath2(path29.relative(gitRoot, descendantDir)) : normalizePath2(path29.relative(cwd, descendantDir));
18014
+ const rel = gitRoot ? normalizePath2(path30.relative(gitRoot, descendantDir)) : normalizePath2(path30.relative(cwd, descendantDir));
18156
18015
  if (!configDirs.has(rel)) configDirs.add(rel);
18157
18016
  }
18158
18017
  for (const configDirKey of configDirs) {
@@ -18160,7 +18019,7 @@ async function playbookStatusHandler(deps) {
18160
18019
  if (configDirKey === "__cwd__") {
18161
18020
  projectDir = fallbackConfigDir;
18162
18021
  } else if (gitRoot) {
18163
- projectDir = path29.join(gitRoot, configDirKey);
18022
+ projectDir = path30.join(gitRoot, configDirKey);
18164
18023
  } else {
18165
18024
  continue;
18166
18025
  }
@@ -18185,11 +18044,11 @@ async function playbookStatusHandler(deps) {
18185
18044
  continue;
18186
18045
  }
18187
18046
  const displayPath = normalizePath2(
18188
- path29.relative(cwd, path29.join(projectDir, deployedFile.path))
18047
+ path30.relative(cwd, path30.join(projectDir, deployedFile.path))
18189
18048
  );
18190
18049
  let localContent;
18191
18050
  try {
18192
- localContent = readFile12(path29.join(projectDir, deployedFile.path));
18051
+ localContent = readFile10(path30.join(projectDir, deployedFile.path));
18193
18052
  } catch {
18194
18053
  const artifact = findArtifactForFile(
18195
18054
  deployedFile.path,
@@ -18218,7 +18077,7 @@ async function playbookStatusHandler(deps) {
18218
18077
  });
18219
18078
  }
18220
18079
  } else if (deployedFile.skillFilePermissions && getFileMode) {
18221
- const localMode = getFileMode(path29.join(projectDir, deployedFile.path));
18080
+ const localMode = getFileMode(path30.join(projectDir, deployedFile.path));
18222
18081
  if (localMode !== null) {
18223
18082
  const localPermissions = modeToPermissionStringOrDefault(localMode);
18224
18083
  if (localPermissions !== deployedFile.skillFilePermissions) {
@@ -18247,13 +18106,13 @@ async function playbookStatusHandler(deps) {
18247
18106
  (f) => normalizePath2(f.path).endsWith("/SKILL.md")
18248
18107
  );
18249
18108
  if (!skillMdFile) continue;
18250
- const skillDir = normalizePath2(path29.dirname(skillMdFile.path));
18109
+ const skillDir = normalizePath2(path30.dirname(skillMdFile.path));
18251
18110
  if (targetStagedPaths.has(skillDir) || targetSkillDirPaths.some(
18252
18111
  (staged) => skillDir === staged || skillDir.startsWith(staged + "/")
18253
18112
  )) {
18254
18113
  continue;
18255
18114
  }
18256
- const absoluteSkillDir = path29.join(projectDir, skillDir);
18115
+ const absoluteSkillDir = path30.join(projectDir, skillDir);
18257
18116
  let localFiles;
18258
18117
  try {
18259
18118
  localFiles = listDirectoryFiles2(absoluteSkillDir);
@@ -18262,11 +18121,11 @@ async function playbookStatusHandler(deps) {
18262
18121
  }
18263
18122
  for (const localRelPath of localFiles) {
18264
18123
  const normalizedLocalPath = normalizePath2(
18265
- path29.join(skillDir, localRelPath)
18124
+ path30.join(skillDir, localRelPath)
18266
18125
  );
18267
18126
  if (!deployedPathSet.has(normalizedLocalPath)) {
18268
18127
  const displayPath = normalizePath2(
18269
- path29.relative(cwd, path29.join(projectDir, normalizedLocalPath))
18128
+ path30.relative(cwd, path30.join(projectDir, normalizedLocalPath))
18270
18129
  );
18271
18130
  untrackedChanges.push({
18272
18131
  artifactName: entry.name,
@@ -18354,7 +18213,97 @@ var import_path5 = require("path");
18354
18213
  var import_cmd_ts29 = __toESM(require_cjs());
18355
18214
 
18356
18215
  // apps/cli/src/infra/commands/playbook/submitHandler.ts
18357
- var path30 = __toESM(require("path"));
18216
+ var path32 = __toESM(require("path"));
18217
+
18218
+ // apps/cli/src/infra/commands/playbook/submit/duplicateNameChecker.ts
18219
+ var import_slug2 = __toESM(require("slug"));
18220
+ async function checkForDuplicateNames(createdEntries, packmindGateway) {
18221
+ const errors = [];
18222
+ const groups = /* @__PURE__ */ new Map();
18223
+ for (const entry of createdEntries) {
18224
+ const key = `${entry.spaceId}:${entry.artifactType}`;
18225
+ const existing = groups.get(key) ?? [];
18226
+ existing.push(entry);
18227
+ groups.set(key, existing);
18228
+ }
18229
+ for (const [, entries] of groups) {
18230
+ const seen = /* @__PURE__ */ new Map();
18231
+ for (const entry of entries) {
18232
+ const sluggedName = (0, import_slug2.default)(entry.artifactName);
18233
+ if (seen.has(sluggedName)) {
18234
+ errors.push(
18235
+ `A ${entry.artifactType} named "${entry.artifactName}" is staged multiple times. Remove the duplicate with "playbook unstage" or rename the artifact.`
18236
+ );
18237
+ } else {
18238
+ seen.set(sluggedName, entry.artifactName);
18239
+ }
18240
+ }
18241
+ }
18242
+ for (const [key, entries] of groups) {
18243
+ const [rawSpaceId, artifactType] = key.split(":");
18244
+ const typedSpaceId = rawSpaceId;
18245
+ try {
18246
+ let existingNames = [];
18247
+ if (artifactType === "standard") {
18248
+ const response = await packmindGateway.standards.list({
18249
+ spaceId: typedSpaceId
18250
+ });
18251
+ existingNames = response.standards.map((s) => s.name);
18252
+ } else if (artifactType === "command") {
18253
+ const response = await packmindGateway.commands.list({
18254
+ spaceId: typedSpaceId
18255
+ });
18256
+ existingNames = response.recipes.map((r) => r.name);
18257
+ } else if (artifactType === "skill") {
18258
+ const response = await packmindGateway.skills.list({
18259
+ spaceId: typedSpaceId
18260
+ });
18261
+ existingNames = response.map((s) => s.name);
18262
+ }
18263
+ const existingNamesSlugged = new Set(existingNames.map((n) => (0, import_slug2.default)(n)));
18264
+ for (const entry of entries) {
18265
+ if (existingNamesSlugged.has((0, import_slug2.default)(entry.artifactName))) {
18266
+ errors.push(
18267
+ `A ${entry.artifactType} named "${entry.artifactName}" already exists in this space. Use "playbook unstage" to remove it or rename the artifact.`
18268
+ );
18269
+ }
18270
+ }
18271
+ } catch {
18272
+ }
18273
+ }
18274
+ return errors;
18275
+ }
18276
+
18277
+ // apps/cli/src/infra/commands/playbook/submit/targetContextResolver.ts
18278
+ var path31 = __toESM(require("path"));
18279
+ async function createTargetContextResolver(deps) {
18280
+ const { lockFileRepository, cwd, packmindCliHexa } = deps;
18281
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
18282
+ const cache = /* @__PURE__ */ new Map();
18283
+ return {
18284
+ getTargetContext: async (entry) => {
18285
+ const key = entry.configDir ?? "__cwd__";
18286
+ if (cache.has(key)) return cache.get(key);
18287
+ let projectDir;
18288
+ if (entry.configDir !== void 0 && gitRoot) {
18289
+ projectDir = path31.join(gitRoot, entry.configDir);
18290
+ } else {
18291
+ projectDir = await findNearestConfigDir(cwd, packmindCliHexa);
18292
+ }
18293
+ const lockFile = projectDir ? await lockFileRepository.read(projectDir) : null;
18294
+ const deployedFiles = lockFile && Object.keys(lockFile.artifacts).length > 0 ? await fetchDeployedFiles(
18295
+ packmindCliHexa.getPackmindGateway(),
18296
+ lockFile
18297
+ ) : [];
18298
+ const ctx = { lockFile, deployedFiles, projectDir };
18299
+ cache.set(key, ctx);
18300
+ return ctx;
18301
+ },
18302
+ getCachedContext: (configDir) => cache.get(configDir ?? "__cwd__")
18303
+ };
18304
+ }
18305
+
18306
+ // apps/cli/src/infra/commands/playbook/submit/proposalBuilder.ts
18358
18307
  var yaml3 = __toESM(require("yaml"));
18359
18308
 
18360
18309
  // apps/cli/src/application/utils/artifactComparison.ts
@@ -18553,20 +18502,7 @@ function compareSkillDefinitionFields(local, deployed) {
18553
18502
  return changes;
18554
18503
  }
18555
18504
 
18556
- // apps/cli/src/infra/commands/playbook/submitHandler.ts
18557
- function buildEditorPrefill(changes) {
18558
- const lines = [
18559
- "",
18560
- "# Changes to be submitted:",
18561
- ...changes.map(
18562
- (c) => `# - ${capitalize(c.artifactType)} "${c.artifactName}" ${c.changeType ?? "updated"}`
18563
- )
18564
- ];
18565
- return lines.join("\n");
18566
- }
18567
- function stripCommentLines(text) {
18568
- return text.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
18569
- }
18505
+ // apps/cli/src/infra/commands/playbook/submit/proposalBuilder.ts
18570
18506
  function resolveArtifactIdFromLockFile(filePath, lockFile) {
18571
18507
  if (!lockFile) return null;
18572
18508
  const normalized = normalizePath2(filePath);
@@ -18850,134 +18786,9 @@ function findDeployedContentForPath(filePath, deployedFiles) {
18850
18786
  const match = deployedFiles.find((f) => normalizePath2(f.path) === normalized);
18851
18787
  return match?.content ?? null;
18852
18788
  }
18853
- async function checkForDuplicateNames(createdEntries, packmindGateway) {
18854
- const errors = [];
18855
- const groups = /* @__PURE__ */ new Map();
18856
- for (const entry of createdEntries) {
18857
- const key = `${entry.spaceId}:${entry.artifactType}`;
18858
- const existing = groups.get(key) ?? [];
18859
- existing.push(entry);
18860
- groups.set(key, existing);
18861
- }
18862
- for (const [, entries] of groups) {
18863
- const seen = /* @__PURE__ */ new Map();
18864
- for (const entry of entries) {
18865
- const lowerName = entry.artifactName.toLowerCase();
18866
- if (seen.has(lowerName)) {
18867
- errors.push(
18868
- `A ${entry.artifactType} named "${entry.artifactName}" is staged multiple times. Remove the duplicate with "playbook unstage" or rename the artifact.`
18869
- );
18870
- } else {
18871
- seen.set(lowerName, entry.artifactName);
18872
- }
18873
- }
18874
- }
18875
- for (const [key, entries] of groups) {
18876
- const [rawSpaceId, artifactType] = key.split(":");
18877
- const typedSpaceId = rawSpaceId;
18878
- try {
18879
- let existingNames = [];
18880
- if (artifactType === "standard") {
18881
- const response = await packmindGateway.standards.list({
18882
- spaceId: typedSpaceId
18883
- });
18884
- existingNames = response.standards.map((s) => s.name);
18885
- } else if (artifactType === "command") {
18886
- const response = await packmindGateway.commands.list({
18887
- spaceId: typedSpaceId
18888
- });
18889
- existingNames = response.recipes.map((r) => r.name);
18890
- } else if (artifactType === "skill") {
18891
- const response = await packmindGateway.skills.list({
18892
- spaceId: typedSpaceId
18893
- });
18894
- existingNames = response.map((s) => s.name);
18895
- }
18896
- const existingNamesLower = new Set(
18897
- existingNames.map((n) => n.toLowerCase())
18898
- );
18899
- for (const entry of entries) {
18900
- if (existingNamesLower.has(entry.artifactName.toLowerCase())) {
18901
- errors.push(
18902
- `A ${entry.artifactType} named "${entry.artifactName}" already exists in this space. Use "playbook unstage" to remove it or rename the artifact.`
18903
- );
18904
- }
18905
- }
18906
- } catch {
18907
- }
18908
- }
18909
- return errors;
18910
- }
18911
- async function playbookSubmitHandler(deps) {
18912
- const {
18913
- packmindCliHexa,
18914
- playbookLocalRepository,
18915
- lockFileRepository,
18916
- cwd,
18917
- exit,
18918
- message,
18919
- openEditor
18920
- } = deps;
18921
- const changes = playbookLocalRepository.getChanges();
18922
- if (changes.length === 0) {
18923
- logConsole("Nothing to submit.");
18924
- exit(0);
18925
- return;
18926
- }
18927
- let resolvedMessage;
18928
- if (message) {
18929
- resolvedMessage = message;
18930
- } else {
18931
- const prefill = buildEditorPrefill(changes);
18932
- const editorResult = openEditor(prefill);
18933
- if (!editorResult) {
18934
- logErrorConsole("Aborting: empty message.");
18935
- exit(1);
18936
- return;
18937
- }
18938
- const stripped = stripCommentLines(editorResult);
18939
- if (!stripped) {
18940
- logErrorConsole("Aborting: empty message.");
18941
- exit(1);
18942
- return;
18943
- }
18944
- resolvedMessage = stripped;
18945
- }
18946
- const createdEntries = changes.filter((c) => c.changeType === "created");
18947
- if (createdEntries.length > 0) {
18948
- const duplicateErrors = await checkForDuplicateNames(
18949
- createdEntries,
18950
- packmindCliHexa.getPackmindGateway()
18951
- );
18952
- if (duplicateErrors.length > 0) {
18953
- for (const error of duplicateErrors) {
18954
- logErrorConsole(error);
18955
- }
18956
- exit(1);
18957
- return;
18958
- }
18959
- }
18960
- const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
18961
- const targetContextCache = /* @__PURE__ */ new Map();
18962
- async function getTargetContext(entry) {
18963
- const key = entry.configDir ?? "__cwd__";
18964
- if (targetContextCache.has(key)) return targetContextCache.get(key);
18965
- let projectDir;
18966
- if (entry.configDir !== void 0 && gitRoot) {
18967
- projectDir = path30.join(gitRoot, entry.configDir);
18968
- } else {
18969
- projectDir = await findNearestConfigDir(cwd, packmindCliHexa);
18970
- }
18971
- const lockFile = projectDir ? await lockFileRepository.read(projectDir) : null;
18972
- const deployedFiles = lockFile && Object.keys(lockFile.artifacts).length > 0 ? await fetchDeployedFiles(
18973
- packmindCliHexa.getPackmindGateway(),
18974
- lockFile
18975
- ) : [];
18976
- const ctx = { lockFile, deployedFiles, projectDir };
18977
- targetContextCache.set(key, ctx);
18978
- return ctx;
18979
- }
18980
- const allProposals = [];
18789
+ async function buildProposals(changes, getTargetContext) {
18790
+ const proposals = [];
18791
+ const updateSources = /* @__PURE__ */ new Map();
18981
18792
  for (const entry of changes) {
18982
18793
  const ctx = await getTargetContext(entry);
18983
18794
  if (!entry.targetId && ctx.lockFile?.targetId) {
@@ -18986,13 +18797,13 @@ async function playbookSubmitHandler(deps) {
18986
18797
  if (entry.changeType === "created") {
18987
18798
  switch (entry.artifactType) {
18988
18799
  case "standard":
18989
- allProposals.push(...buildCreatedStandardProposals(entry));
18800
+ proposals.push(...buildCreatedStandardProposals(entry));
18990
18801
  break;
18991
18802
  case "command":
18992
- allProposals.push(...buildCreatedCommandProposals(entry));
18803
+ proposals.push(...buildCreatedCommandProposals(entry));
18993
18804
  break;
18994
18805
  case "skill":
18995
- allProposals.push(...buildCreatedSkillProposals(entry));
18806
+ proposals.push(...buildCreatedSkillProposals(entry));
18996
18807
  break;
18997
18808
  }
18998
18809
  } else if (entry.changeType === "removed") {
@@ -19006,9 +18817,7 @@ async function playbookSubmitHandler(deps) {
19006
18817
  );
19007
18818
  continue;
19008
18819
  }
19009
- allProposals.push(
19010
- ...buildRemovedProposals(entry, artifactId, ctx.lockFile)
19011
- );
18820
+ proposals.push(...buildRemovedProposals(entry, artifactId, ctx.lockFile));
19012
18821
  } else {
19013
18822
  const artifactId = resolveArtifactIdFromLockFile(
19014
18823
  entry.filePath,
@@ -19020,6 +18829,21 @@ async function playbookSubmitHandler(deps) {
19020
18829
  );
19021
18830
  continue;
19022
18831
  }
18832
+ const existing = updateSources.get(artifactId);
18833
+ if (existing) {
18834
+ existing.entries.push({
18835
+ filePath: entry.filePath,
18836
+ codingAgent: entry.codingAgent
18837
+ });
18838
+ } else {
18839
+ updateSources.set(artifactId, {
18840
+ artifactName: entry.artifactName,
18841
+ artifactType: entry.artifactType,
18842
+ entries: [
18843
+ { filePath: entry.filePath, codingAgent: entry.codingAgent }
18844
+ ]
18845
+ });
18846
+ }
19023
18847
  const deployedContent = findDeployedContentForPath(
19024
18848
  entry.filePath,
19025
18849
  ctx.deployedFiles
@@ -19032,7 +18856,7 @@ async function playbookSubmitHandler(deps) {
19032
18856
  }
19033
18857
  switch (entry.artifactType) {
19034
18858
  case "standard":
19035
- allProposals.push(
18859
+ proposals.push(
19036
18860
  ...buildUpdatedStandardProposals(
19037
18861
  entry,
19038
18862
  artifactId,
@@ -19041,56 +18865,352 @@ async function playbookSubmitHandler(deps) {
19041
18865
  );
19042
18866
  break;
19043
18867
  case "command":
19044
- allProposals.push(
18868
+ proposals.push(
19045
18869
  ...buildUpdatedCommandProposals(entry, artifactId, deployedContent)
19046
18870
  );
19047
18871
  break;
19048
18872
  case "skill":
19049
- allProposals.push(
18873
+ proposals.push(
19050
18874
  ...buildUpdatedSkillProposals(entry, artifactId, ctx.deployedFiles)
19051
18875
  );
19052
18876
  break;
19053
18877
  }
19054
18878
  }
19055
18879
  }
19056
- if (allProposals.length === 0) {
19057
- logConsole(
19058
- "Nothing to submit \u2014 no changes detected compared to deployed versions."
19059
- );
19060
- for (const entry of changes) {
19061
- playbookLocalRepository.removeChange(entry.filePath, entry.spaceId);
18880
+ const conflicts = [];
18881
+ for (const source of updateSources.values()) {
18882
+ if (source.entries.length > 1) {
18883
+ conflicts.push(source);
19062
18884
  }
19063
- exit(0);
19064
- return;
19065
18885
  }
19066
- const filePathsBySpaceId = /* @__PURE__ */ new Map();
19067
- for (const entry of changes) {
19068
- const existing = filePathsBySpaceId.get(entry.spaceId) ?? /* @__PURE__ */ new Set();
19069
- existing.add(entry.filePath);
19070
- filePathsBySpaceId.set(entry.spaceId, existing);
18886
+ return { proposals, conflicts };
18887
+ }
18888
+
18889
+ // apps/cli/src/infra/commands/playbook/submit/submitLogger.ts
18890
+ async function fetchAvailablePackageSlugs(packmindCliHexa, spaceIds) {
18891
+ try {
18892
+ const allSpaces = await packmindCliHexa.getSpaces();
18893
+ const relevantSpaces = allSpaces.filter(
18894
+ (s) => spaceIds.includes(s.id)
18895
+ );
18896
+ const packagesBySpace = await Promise.all(
18897
+ relevantSpaces.map(async (space) => ({
18898
+ space,
18899
+ packages: await packmindCliHexa.listPackages({
18900
+ spaceId: space.id
18901
+ })
18902
+ }))
18903
+ );
18904
+ const multipleSpaces = relevantSpaces.length > 1;
18905
+ return packagesBySpace.flatMap(
18906
+ ({ space, packages }) => packages.map(
18907
+ (pkg) => multipleSpaces ? `@${space.slug}/${pkg.slug}` : pkg.slug
18908
+ )
18909
+ );
18910
+ } catch {
18911
+ return [];
19071
18912
  }
19072
- const proposalsBySpaceId = /* @__PURE__ */ new Map();
18913
+ }
18914
+ function logPackageAddGuidance(created, packageSlugs) {
18915
+ const { standards, commands, skills } = created;
18916
+ const totalCount = standards.length + commands.length + skills.length;
18917
+ if (totalCount === 0) return;
18918
+ const pkgPlaceholder = packageSlugs.length === 1 ? packageSlugs[0] : "<package-slug>";
18919
+ if (totalCount === 1) {
18920
+ logInfoConsole("To add the created artifact to a package, run:");
18921
+ if (standards.length === 1) {
18922
+ logInfoConsole(
18923
+ ` ${formatCommand(`\`packmind-cli packages add --to ${pkgPlaceholder} --standard ${standards[0].slug}\``)}`
18924
+ );
18925
+ } else if (commands.length === 1) {
18926
+ logInfoConsole(
18927
+ ` ${formatCommand(`\`packmind-cli packages add --to ${pkgPlaceholder} --command ${commands[0].slug}\``)}`
18928
+ );
18929
+ } else if (skills.length === 1) {
18930
+ logInfoConsole(
18931
+ ` ${formatCommand(`\`packmind-cli packages add --to ${pkgPlaceholder} --skill ${skills[0].slug}\``)}`
18932
+ );
18933
+ }
18934
+ } else {
18935
+ logInfoConsole(
18936
+ `To add the created artifacts to a package, use ${formatCommand(`\`packmind-cli packages add --to ${pkgPlaceholder} --standard <artifact-slug>\``)} for each artifact.`
18937
+ );
18938
+ }
18939
+ if (packageSlugs.length > 1) {
18940
+ logInfoConsole(` Available packages: ${packageSlugs.join(", ")}`);
18941
+ }
18942
+ }
18943
+ async function logRemovedPackagesNotification(packmindCliHexa, packageIds) {
18944
+ if (packageIds.size === 0) return;
18945
+ try {
18946
+ const [allPackages, allSpaces] = await Promise.all([
18947
+ packmindCliHexa.listPackages({}),
18948
+ packmindCliHexa.getSpaces()
18949
+ ]);
18950
+ const affectedPackages = allPackages.filter(
18951
+ (pkg) => packageIds.has(pkg.id)
18952
+ );
18953
+ if (affectedPackages.length === 0) return;
18954
+ const buildUrl = resolveUrlBuilder((id) => `packages/${id}`);
18955
+ const spaceById = new Map(allSpaces.map((s) => [s.id, s]));
18956
+ logWarningConsole(
18957
+ "Some changes could not be applied: playbook submit does not allow remove artefacts. Review the following affected packages:"
18958
+ );
18959
+ for (const pkg of affectedPackages) {
18960
+ const space = spaceById.get(pkg.spaceId);
18961
+ const spaceSlug = space?.slug ?? "";
18962
+ const url = buildUrl(spaceSlug, pkg.id);
18963
+ if (url) {
18964
+ logInfoConsole(` - ${pkg.name}: ${url}`);
18965
+ } else {
18966
+ logInfoConsole(` - ${pkg.name}`);
18967
+ }
18968
+ }
18969
+ } catch {
18970
+ }
18971
+ }
18972
+ var formatCount = (items, noun) => items.length > 0 ? `${items.length} ${noun}${items.length !== 1 ? "s" : ""}` : null;
18973
+ var collectParts = (counts) => [
18974
+ formatCount(counts.standards, "standard"),
18975
+ formatCount(counts.commands, "command"),
18976
+ formatCount(counts.skills, "skill")
18977
+ ].filter((p) => p !== null);
18978
+
18979
+ // apps/cli/src/infra/commands/playbook/submitHandler.ts
18980
+ function buildEditorPrefill(changes) {
18981
+ const lines = [
18982
+ "",
18983
+ "# Changes to be submitted:",
18984
+ ...changes.map(
18985
+ (c) => `# - ${capitalize(c.artifactType)} "${c.artifactName}" ${c.changeType ?? "updated"}`
18986
+ )
18987
+ ];
18988
+ return lines.join("\n");
18989
+ }
18990
+ function stripCommentLines(text) {
18991
+ return text.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
18992
+ }
18993
+ async function playbookSubmitHandler(deps) {
18994
+ const {
18995
+ packmindCliHexa,
18996
+ playbookLocalRepository,
18997
+ lockFileRepository,
18998
+ cwd,
18999
+ exit,
19000
+ message,
19001
+ noReview,
19002
+ openEditor
19003
+ } = deps;
19004
+ const changes = playbookLocalRepository.getChanges();
19005
+ if (changes.length === 0) {
19006
+ logConsole("Nothing to submit.");
19007
+ exit(0);
19008
+ return;
19009
+ }
19010
+ let resolvedMessage;
19011
+ if (message) {
19012
+ resolvedMessage = message;
19013
+ } else if (noReview) {
19014
+ resolvedMessage = "";
19015
+ } else {
19016
+ const prefill = buildEditorPrefill(changes);
19017
+ const editorResult = openEditor(prefill);
19018
+ if (!editorResult) {
19019
+ logErrorConsole("Aborting: empty message.");
19020
+ exit(1);
19021
+ return;
19022
+ }
19023
+ const stripped = stripCommentLines(editorResult);
19024
+ if (!stripped) {
19025
+ logErrorConsole("Aborting: empty message.");
19026
+ exit(1);
19027
+ return;
19028
+ }
19029
+ resolvedMessage = stripped;
19030
+ }
19031
+ const createdEntries = changes.filter((c) => c.changeType === "created");
19032
+ if (createdEntries.length > 0) {
19033
+ const duplicateErrors = await checkForDuplicateNames(
19034
+ createdEntries,
19035
+ packmindCliHexa.getPackmindGateway()
19036
+ );
19037
+ if (duplicateErrors.length > 0) {
19038
+ for (const error of duplicateErrors) {
19039
+ logErrorConsole(error);
19040
+ }
19041
+ exit(1);
19042
+ return;
19043
+ }
19044
+ }
19045
+ const resolver = await createTargetContextResolver({
19046
+ lockFileRepository,
19047
+ cwd,
19048
+ packmindCliHexa
19049
+ });
19050
+ const { proposals: allProposals, conflicts } = await buildProposals(
19051
+ changes,
19052
+ resolver.getTargetContext
19053
+ );
19054
+ if (conflicts.length > 0) {
19055
+ for (const conflict of conflicts) {
19056
+ const agents = conflict.entries.map((e) => e.codingAgent).join(", ");
19057
+ const paths = conflict.entries.map((e) => ` - ${e.filePath} (${e.codingAgent})`).join("\n");
19058
+ logErrorConsole(
19059
+ `${capitalize(conflict.artifactType)} "${conflict.artifactName}" is modified from multiple agents (${agents}):
19060
+ ${paths}
19061
+ Only one agent version can be submitted at a time. Use "playbook unstage" to remove one.`
19062
+ );
19063
+ }
19064
+ exit(1);
19065
+ return;
19066
+ }
19067
+ if (allProposals.length === 0) {
19068
+ logConsole(
19069
+ "Nothing to submit \u2014 no changes detected compared to deployed versions."
19070
+ );
19071
+ for (const entry of changes) {
19072
+ playbookLocalRepository.removeChange(entry.filePath, entry.spaceId);
19073
+ }
19074
+ exit(0);
19075
+ return;
19076
+ }
19077
+ const removalPackageIds = /* @__PURE__ */ new Set();
19078
+ for (const proposal of allProposals) {
19079
+ if (proposal.type === "removeStandard" /* removeStandard */ || proposal.type === "removeCommand" /* removeCommand */ || proposal.type === "removeSkill" /* removeSkill */) {
19080
+ const payload = proposal.payload;
19081
+ for (const id of payload.packageIds) {
19082
+ removalPackageIds.add(id);
19083
+ }
19084
+ }
19085
+ }
19086
+ const filePathsBySpaceId = /* @__PURE__ */ new Map();
19087
+ for (const entry of changes) {
19088
+ const existing = filePathsBySpaceId.get(entry.spaceId) ?? /* @__PURE__ */ new Set();
19089
+ existing.add(entry.filePath);
19090
+ filePathsBySpaceId.set(entry.spaceId, existing);
19091
+ }
19092
+ const proposalsBySpaceId = /* @__PURE__ */ new Map();
19073
19093
  for (const proposal of allProposals) {
19074
19094
  const existing = proposalsBySpaceId.get(proposal.spaceId) ?? [];
19075
19095
  existing.push(proposal);
19076
19096
  proposalsBySpaceId.set(proposal.spaceId, existing);
19077
19097
  }
19078
19098
  const packmindGateway = packmindCliHexa.getPackmindGateway();
19079
- let totalCreated = 0;
19080
- let totalSkipped = 0;
19081
- let hasErrors = false;
19082
- for (const [spaceId, proposals] of proposalsBySpaceId) {
19083
- const response = await packmindGateway.changeProposals.batchCreate({
19084
- spaceId,
19085
- proposals: proposals.map((p) => ({
19099
+ if (noReview) {
19100
+ const applyProposals = allProposals.map(
19101
+ (p) => ({
19102
+ spaceId: p.spaceId,
19086
19103
  type: p.type,
19087
19104
  artefactId: p.artefactId,
19088
19105
  payload: p.payload,
19089
- captureMode: "commit" /* commit */,
19090
- message: resolvedMessage,
19091
19106
  targetId: p.targetId ?? ""
19092
- }))
19093
- });
19107
+ })
19108
+ );
19109
+ if (applyProposals.length === 0) {
19110
+ logConsole("Nothing to apply directly.");
19111
+ exit(0);
19112
+ return;
19113
+ }
19114
+ let response;
19115
+ try {
19116
+ response = await packmindGateway.changeProposals.batchApply({
19117
+ proposals: applyProposals,
19118
+ message: resolvedMessage,
19119
+ directUpdate: true
19120
+ });
19121
+ } catch (error) {
19122
+ const err = error;
19123
+ if (err.statusCode === 422) {
19124
+ logErrorConsole("Failed to apply changes: a conflict was detected.");
19125
+ logInfoConsole(
19126
+ "This usually means the artifact was modified since your last pull.\nRun `packmind pull` to sync your local state, then retry."
19127
+ );
19128
+ } else {
19129
+ logErrorConsole(`Failed to apply changes: ${err.message}`);
19130
+ }
19131
+ exit(1);
19132
+ return;
19133
+ }
19134
+ if (!response.success) {
19135
+ logErrorConsole(`Failed to apply changes: ${response.error.message}`);
19136
+ logInfoConsole(
19137
+ "Your playbook has not been modified. Fix the issue and retry."
19138
+ );
19139
+ exit(1);
19140
+ return;
19141
+ }
19142
+ for (const [spaceId, filePaths] of filePathsBySpaceId) {
19143
+ for (const filePath of filePaths) {
19144
+ playbookLocalRepository.removeChange(filePath, spaceId);
19145
+ }
19146
+ }
19147
+ await logRemovedPackagesNotification(packmindCliHexa, removalPackageIds);
19148
+ const createdParts = collectParts(response.created);
19149
+ const updatedParts = collectParts(response.updated);
19150
+ const messageParts = [];
19151
+ if (createdParts.length > 0)
19152
+ messageParts.push(`${createdParts.join(", ")} created`);
19153
+ if (updatedParts.length > 0)
19154
+ messageParts.push(`${updatedParts.join(", ")} updated`);
19155
+ if (messageParts.length > 0) {
19156
+ logSuccessConsole(messageParts.join(", "));
19157
+ } else {
19158
+ logInfoConsole("No changes were applied.");
19159
+ }
19160
+ const createTypes = /* @__PURE__ */ new Set([
19161
+ "createStandard" /* createStandard */,
19162
+ "createCommand" /* createCommand */,
19163
+ "createSkill" /* createSkill */
19164
+ ]);
19165
+ const createdSpaceIds = [
19166
+ ...new Set(
19167
+ applyProposals.filter((p) => createTypes.has(p.type)).map((p) => p.spaceId)
19168
+ )
19169
+ ];
19170
+ const packageSlugs = await fetchAvailablePackageSlugs(
19171
+ packmindCliHexa,
19172
+ createdSpaceIds
19173
+ );
19174
+ logPackageAddGuidance(response.created, packageSlugs);
19175
+ exit(0);
19176
+ return;
19177
+ }
19178
+ const spaceNameById = /* @__PURE__ */ new Map();
19179
+ for (const change of changes) {
19180
+ if (change.spaceName && !spaceNameById.has(change.spaceId)) {
19181
+ spaceNameById.set(change.spaceId, change.spaceName);
19182
+ }
19183
+ }
19184
+ const displaySpace2 = (id) => spaceNameById.get(id) ?? id;
19185
+ let totalCreated = 0;
19186
+ let totalSkipped = 0;
19187
+ const succeededSpaces = [];
19188
+ const failedSpaces = [];
19189
+ for (const [spaceId, proposals] of proposalsBySpaceId) {
19190
+ let response;
19191
+ try {
19192
+ response = await packmindGateway.changeProposals.batchCreate({
19193
+ spaceId,
19194
+ proposals: proposals.map((p) => ({
19195
+ type: p.type,
19196
+ artefactId: p.artefactId,
19197
+ payload: p.payload,
19198
+ captureMode: "commit" /* commit */,
19199
+ message: resolvedMessage,
19200
+ targetId: p.targetId ?? ""
19201
+ }))
19202
+ });
19203
+ } catch (error) {
19204
+ if (isCommunityEditionError(error)) {
19205
+ logErrorConsole(error.message);
19206
+ logInfoConsole(
19207
+ `Run ${formatCommand("`packmind-cli playbook submit --no-review`")} to apply changes directly.`
19208
+ );
19209
+ exit(1);
19210
+ return;
19211
+ }
19212
+ throw error;
19213
+ }
19094
19214
  totalCreated += response.created;
19095
19215
  totalSkipped += response.skipped;
19096
19216
  if (response.errors.length > 0) {
@@ -19111,10 +19231,10 @@ async function playbookSubmitHandler(deps) {
19111
19231
  (c) => c.changeType === "removed"
19112
19232
  );
19113
19233
  for (const entry of removedEntries) {
19114
- const entryCtx = targetContextCache.get(entry.configDir ?? "__cwd__");
19234
+ const entryCtx = resolver.getCachedContext(entry.configDir);
19115
19235
  if (!entryCtx?.projectDir) continue;
19116
19236
  try {
19117
- const fullPath = path30.join(entryCtx.projectDir, entry.filePath);
19237
+ const fullPath = path32.join(entryCtx.projectDir, entry.filePath);
19118
19238
  if (entry.artifactType === "skill") {
19119
19239
  deps.rmSync(fullPath, { recursive: true });
19120
19240
  } else {
@@ -19124,12 +19244,13 @@ async function playbookSubmitHandler(deps) {
19124
19244
  }
19125
19245
  }
19126
19246
  } else {
19127
- hasErrors = true;
19128
- for (const error of response.errors) {
19129
- logErrorConsole(`Error: ${error.message}`);
19130
- }
19247
+ failedSpaces.push({
19248
+ spaceId,
19249
+ errors: response.errors.map((e) => e.message)
19250
+ });
19131
19251
  }
19132
19252
  } else {
19253
+ succeededSpaces.push(spaceId);
19133
19254
  const filePaths = filePathsBySpaceId.get(spaceId) ?? /* @__PURE__ */ new Set();
19134
19255
  for (const filePath of filePaths) {
19135
19256
  playbookLocalRepository.removeChange(filePath, spaceId);
@@ -19138,10 +19259,10 @@ async function playbookSubmitHandler(deps) {
19138
19259
  (c) => c.changeType === "removed" && filePaths.has(c.filePath)
19139
19260
  );
19140
19261
  for (const entry of removedEntries) {
19141
- const entryCtx = targetContextCache.get(entry.configDir ?? "__cwd__");
19262
+ const entryCtx = resolver.getCachedContext(entry.configDir);
19142
19263
  if (!entryCtx?.projectDir) continue;
19143
19264
  try {
19144
- const fullPath = path30.join(entryCtx.projectDir, entry.filePath);
19265
+ const fullPath = path32.join(entryCtx.projectDir, entry.filePath);
19145
19266
  if (entry.artifactType === "skill") {
19146
19267
  deps.rmSync(fullPath, { recursive: true });
19147
19268
  } else {
@@ -19152,17 +19273,21 @@ async function playbookSubmitHandler(deps) {
19152
19273
  }
19153
19274
  }
19154
19275
  }
19155
- if (hasErrors) {
19156
- if (totalCreated > 0) {
19276
+ if (failedSpaces.length > 0) {
19277
+ for (const { spaceId, errors } of failedSpaces) {
19278
+ logErrorConsole(
19279
+ `Failed to submit to space '${displaySpace2(spaceId)}': ${errors.join(", ")}`
19280
+ );
19281
+ }
19282
+ if (succeededSpaces.length > 0) {
19157
19283
  logWarningConsole(
19158
- `Partially submitted: ${totalCreated} succeeded, some failed`
19284
+ `Submitted to: ${succeededSpaces.map(displaySpace2).join(", ")}. Run 'packmind playbook submit' again to retry failed spaces.`
19159
19285
  );
19160
- } else {
19161
- logErrorConsole("Proposals failed to submit");
19162
19286
  }
19163
19287
  exit(1);
19164
19288
  return;
19165
19289
  }
19290
+ await logRemovedPackagesNotification(packmindCliHexa, removalPackageIds);
19166
19291
  const parts = [];
19167
19292
  if (totalCreated > 0) {
19168
19293
  parts.push(`${totalCreated} submitted`);
@@ -19212,9 +19337,13 @@ var submitPlaybookCommand = (0, import_cmd_ts29.command)({
19212
19337
  long: "message",
19213
19338
  short: "m",
19214
19339
  description: "Message describing the intent behind the proposed changes"
19340
+ }),
19341
+ noReview: (0, import_cmd_ts29.flag)({
19342
+ long: "no-review",
19343
+ description: "Apply changes directly without creating proposals for review"
19215
19344
  })
19216
19345
  },
19217
- handler: async ({ message }) => {
19346
+ handler: async ({ message, noReview }) => {
19218
19347
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
19219
19348
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
19220
19349
  const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
@@ -19230,6 +19359,7 @@ var submitPlaybookCommand = (0, import_cmd_ts29.command)({
19230
19359
  cwd: process.cwd(),
19231
19360
  exit: process.exit,
19232
19361
  message,
19362
+ noReview,
19233
19363
  openEditor: (prefill) => openEditorForMessage(prefill),
19234
19364
  unlinkSync: (p) => (0, import_fs24.unlinkSync)(p),
19235
19365
  rmSync: (p, opts) => (0, import_fs24.rmSync)(p, opts)
@@ -19254,7 +19384,7 @@ var diffCommand2 = (0, import_cmd_ts30.command)({
19254
19384
  type: (0, import_cmd_ts30.optional)(import_cmd_ts30.string)
19255
19385
  })
19256
19386
  },
19257
- handler: async ({ includeSubmitted, path: path33 }) => {
19387
+ handler: async ({ includeSubmitted, path: path36 }) => {
19258
19388
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
19259
19389
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
19260
19390
  await diffArtefactsHandler({
@@ -19263,7 +19393,7 @@ var diffCommand2 = (0, import_cmd_ts30.command)({
19263
19393
  getCwd: () => process.cwd(),
19264
19394
  log: console.log,
19265
19395
  includeSubmitted,
19266
- path: path33
19396
+ path: path36
19267
19397
  });
19268
19398
  }
19269
19399
  });
@@ -19346,14 +19476,14 @@ var spacesCommand = (0, import_cmd_ts33.subcommands)({
19346
19476
  });
19347
19477
 
19348
19478
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
19349
- var import_cmd_ts35 = __toESM(require_cjs());
19479
+ var import_cmd_ts39 = __toESM(require_cjs());
19350
19480
 
19351
19481
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
19352
- var import_cmd_ts34 = __toESM(require_cjs());
19482
+ var import_cmd_ts38 = __toESM(require_cjs());
19353
19483
 
19354
19484
  // apps/cli/src/application/services/AgentArtifactDetectionService.ts
19355
19485
  var fs25 = __toESM(require("fs/promises"));
19356
- var path31 = __toESM(require("path"));
19486
+ var path33 = __toESM(require("path"));
19357
19487
  var AGENT_ARTIFACT_CHECKS = [
19358
19488
  { agent: "claude", paths: [".claude"] },
19359
19489
  { agent: "cursor", paths: [".cursor"] },
@@ -19364,21 +19494,33 @@ var AGENT_ARTIFACT_CHECKS = [
19364
19494
  { agent: "continue", paths: [".continue"] },
19365
19495
  { agent: "junie", paths: [".junie", ".junie.md"] },
19366
19496
  { agent: "agents_md", paths: ["AGENTS.md"] },
19367
- { agent: "gitlab_duo", paths: [".gitlab/duo"] }
19497
+ { agent: "gitlab_duo", paths: [".gitlab/duo"] },
19498
+ { agent: "opencode", paths: [".opencode"] },
19499
+ { agent: "codex", paths: [".agents/skills"], recursive: true }
19368
19500
  ];
19369
19501
  var AgentArtifactDetectionService = class {
19370
19502
  async detectAgentArtifacts(baseDirectory) {
19371
19503
  const detected = [];
19372
19504
  for (const check of AGENT_ARTIFACT_CHECKS) {
19373
- for (const relativePath of check.paths) {
19374
- const fullPath = path31.join(baseDirectory, relativePath);
19375
- const exists = await this.pathExists(fullPath);
19376
- if (exists) {
19505
+ if (check.recursive) {
19506
+ const found = await this.findRecursive(baseDirectory, check.paths);
19507
+ if (found) {
19377
19508
  detected.push({
19378
19509
  agent: check.agent,
19379
- artifactPath: fullPath
19510
+ artifactPath: found
19380
19511
  });
19381
- break;
19512
+ }
19513
+ } else {
19514
+ for (const relativePath of check.paths) {
19515
+ const fullPath = path33.join(baseDirectory, relativePath);
19516
+ const exists = await this.pathExists(fullPath);
19517
+ if (exists) {
19518
+ detected.push({
19519
+ agent: check.agent,
19520
+ artifactPath: fullPath
19521
+ });
19522
+ break;
19523
+ }
19382
19524
  }
19383
19525
  }
19384
19526
  }
@@ -19392,19 +19534,83 @@ var AgentArtifactDetectionService = class {
19392
19534
  return false;
19393
19535
  }
19394
19536
  }
19537
+ async findRecursive(baseDirectory, targetPaths) {
19538
+ const queue = [baseDirectory];
19539
+ while (queue.length > 0) {
19540
+ const currentDir = queue.shift();
19541
+ for (const targetPath of targetPaths) {
19542
+ const fullPath = path33.join(currentDir, targetPath);
19543
+ if (await this.pathExists(fullPath)) {
19544
+ return fullPath;
19545
+ }
19546
+ }
19547
+ try {
19548
+ const entries = await fs25.readdir(currentDir, { withFileTypes: true });
19549
+ for (const entry of entries) {
19550
+ if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
19551
+ queue.push(path33.join(currentDir, entry.name));
19552
+ }
19553
+ }
19554
+ } catch {
19555
+ }
19556
+ }
19557
+ return null;
19558
+ }
19395
19559
  };
19396
19560
 
19397
19561
  // apps/cli/src/infra/commands/config/configAgentsHandler.ts
19398
- var readline3 = __toESM(require("readline"));
19562
+ var readline4 = __toESM(require("readline"));
19399
19563
  var inquirer2 = __toESM(require("inquirer"));
19564
+
19565
+ // apps/cli/src/infra/commands/config/agents/agentsHandlerUtils.ts
19566
+ var path34 = __toESM(require("path"));
19567
+ var fs26 = __toESM(require("fs/promises"));
19568
+ function getRelativePath(dir, startDirectory) {
19569
+ if (dir === startDirectory) return "./packmind.json";
19570
+ return "./" + path34.relative(startDirectory, dir) + "/packmind.json";
19571
+ }
19572
+ async function resolveStartDirectory(args2, getCwd, exit) {
19573
+ let startDirectory = getCwd();
19574
+ if (args2.path) {
19575
+ const resolvedPath = path34.resolve(getCwd(), args2.path);
19576
+ try {
19577
+ const stat9 = await fs26.stat(resolvedPath);
19578
+ if (!stat9.isDirectory()) {
19579
+ logErrorConsole(`Path is not a directory: ${resolvedPath}`);
19580
+ exit(1);
19581
+ return void 0;
19582
+ }
19583
+ startDirectory = resolvedPath;
19584
+ } catch {
19585
+ logErrorConsole(`Path does not exist: ${resolvedPath}`);
19586
+ exit(1);
19587
+ return void 0;
19588
+ }
19589
+ }
19590
+ return startDirectory;
19591
+ }
19592
+ async function fetchOrgDefaultAgents(deploymentGateway) {
19593
+ try {
19594
+ const result = await deploymentGateway.getRenderModeConfiguration({});
19595
+ if (result.configuration) {
19596
+ return result.configuration.activeRenderModes.map((mode) => RENDER_MODE_TO_CODING_AGENT[mode]).filter((agent) => agent !== void 0);
19597
+ }
19598
+ } catch {
19599
+ }
19600
+ return [];
19601
+ }
19602
+
19603
+ // apps/cli/src/infra/commands/config/configAgentsHandler.ts
19400
19604
  var SELECTABLE_AGENTS = [
19401
- "claude",
19402
- "cursor",
19403
- "copilot",
19404
19605
  "agents_md",
19606
+ "claude",
19607
+ "codex",
19405
19608
  "continue",
19609
+ "copilot",
19610
+ "cursor",
19611
+ "gitlab_duo",
19406
19612
  "junie",
19407
- "gitlab_duo"
19613
+ "opencode"
19408
19614
  ];
19409
19615
  var AGENT_DISPLAY_NAMES = {
19410
19616
  packmind: "Packmind",
@@ -19414,7 +19620,9 @@ var AGENT_DISPLAY_NAMES = {
19414
19620
  continue: "Continue.dev",
19415
19621
  junie: "Junie",
19416
19622
  agents_md: "AGENTS.md",
19417
- gitlab_duo: "GitLab Duo"
19623
+ gitlab_duo: "GitLab Duo",
19624
+ opencode: "OpenCode",
19625
+ codex: "Codex"
19418
19626
  };
19419
19627
  async function configAgentsHandler(deps) {
19420
19628
  const { configRepository, baseDirectory } = deps;
@@ -19435,12 +19643,21 @@ async function configAgentsHandler(deps) {
19435
19643
  type: "checkbox",
19436
19644
  name: "selectedAgents",
19437
19645
  message: "Select coding agents to generate artifacts for:",
19438
- choices
19646
+ choices,
19647
+ pageSize: 15,
19648
+ loop: false
19439
19649
  }
19440
19650
  ]);
19441
19651
  selectedAgents = result.selectedAgents;
19442
19652
  }
19443
19653
  await configRepository.updateAgentsConfig(baseDirectory, selectedAgents);
19654
+ if (selectedAgents.length > 0) {
19655
+ await propagateAgentsToDescendants(
19656
+ configRepository,
19657
+ baseDirectory,
19658
+ selectedAgents
19659
+ );
19660
+ }
19444
19661
  const agentNames = selectedAgents.map((a) => AGENT_DISPLAY_NAMES[a]);
19445
19662
  if (selectedAgents.length === 0) {
19446
19663
  logInfoConsole(
@@ -19455,7 +19672,7 @@ async function configAgentsHandler(deps) {
19455
19672
  async function promptAgentsWithReadline2(choices) {
19456
19673
  const input = process.stdin;
19457
19674
  const output = process.stdout;
19458
- const rl = readline3.createInterface({
19675
+ const rl = readline4.createInterface({
19459
19676
  input,
19460
19677
  output
19461
19678
  });
@@ -19468,7 +19685,7 @@ async function promptAgentsWithReadline2(choices) {
19468
19685
  output.write("\n");
19469
19686
  const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
19470
19687
  const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
19471
- return new Promise((resolve13) => {
19688
+ return new Promise((resolve14) => {
19472
19689
  rl.question(
19473
19690
  `Enter numbers separated by commas (default: ${defaultValue}): `,
19474
19691
  (answer) => {
@@ -19477,7 +19694,7 @@ async function promptAgentsWithReadline2(choices) {
19477
19694
  const numbersStr = trimmed === "" ? defaultValue : trimmed;
19478
19695
  const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
19479
19696
  const selectedAgents = numbers.map((n) => choices[n - 1].value);
19480
- resolve13(selectedAgents);
19697
+ resolve14(selectedAgents);
19481
19698
  }
19482
19699
  );
19483
19700
  });
@@ -19507,10 +19724,387 @@ async function getPreselectedAgents(deps) {
19507
19724
  }
19508
19725
  return /* @__PURE__ */ new Set();
19509
19726
  }
19727
+ async function propagateAgentsToDescendants(configRepository, baseDirectory, selectedAgents) {
19728
+ const descendantDirs = await configRepository.findDescendantConfigs(baseDirectory);
19729
+ for (const dir of descendantDirs) {
19730
+ const config = await configRepository.readConfig(dir);
19731
+ if (config === null) continue;
19732
+ const existingAgents = config.agents ?? [];
19733
+ const toAdd = selectedAgents.filter((a) => !existingAgents.includes(a));
19734
+ if (toAdd.length > 0) {
19735
+ const mergedAgents = [...existingAgents, ...toAdd];
19736
+ await configRepository.updateAgentsConfig(dir, mergedAgents);
19737
+ const relPath = getRelativePath(dir, baseDirectory);
19738
+ logSuccessConsole(`Updated ${relPath}`);
19739
+ }
19740
+ }
19741
+ }
19742
+
19743
+ // apps/cli/src/infra/commands/config/ConfigAgentsAddCommand.ts
19744
+ var readline5 = __toESM(require("readline"));
19745
+ var import_cmd_ts35 = __toESM(require_cjs());
19746
+
19747
+ // apps/cli/src/infra/commands/customParameters/AgentNamesPositional.ts
19748
+ var import_cmd_ts34 = __toESM(require_cjs());
19749
+ var agentNamesPositional = (0, import_cmd_ts34.restPositionals)({
19750
+ type: AgentArgType,
19751
+ displayName: "agents",
19752
+ description: "Agent identifiers (e.g. claude cursor)"
19753
+ });
19754
+
19755
+ // apps/cli/src/infra/commands/config/agents/addAgentsHandler.ts
19756
+ async function addAgentsHandler(args2, deps) {
19757
+ const { configRepository, exit, getCwd } = deps;
19758
+ if (args2.agentNames.length === 0) {
19759
+ logErrorConsole("No agents specified.");
19760
+ logConsole(`Agent identifiers: ${SELECTABLE_AGENTS.join(", ")}`);
19761
+ exit(1);
19762
+ return;
19763
+ }
19764
+ const invalidAgents = args2.agentNames.filter(
19765
+ (n) => !SELECTABLE_AGENTS.includes(n)
19766
+ );
19767
+ if (invalidAgents.length > 0) {
19768
+ logErrorConsole(`Unknown agent(s): ${invalidAgents.join(", ")}`);
19769
+ logConsole(`Agent identifiers: ${SELECTABLE_AGENTS.join(", ")}`);
19770
+ exit(1);
19771
+ return;
19772
+ }
19773
+ const agentsToAdd = [...new Set(args2.agentNames)];
19774
+ const startDirectory = await resolveStartDirectory(args2, getCwd, exit);
19775
+ if (!startDirectory) return;
19776
+ const descendantDirs = await configRepository.findDescendantConfigs(startDirectory);
19777
+ const allDirs = [startDirectory, ...descendantDirs];
19778
+ const validEntries = [];
19779
+ for (const dir of allDirs) {
19780
+ const config = await configRepository.readConfig(dir);
19781
+ if (config !== null) validEntries.push({ dir, config });
19782
+ }
19783
+ if (validEntries.length === 0) {
19784
+ logWarningConsole("No packmind.json files found.");
19785
+ exit(0);
19786
+ return;
19787
+ }
19788
+ const filesWithoutLocalAgents = validEntries.filter(
19789
+ (entry) => entry.config.agents === void 0
19790
+ );
19791
+ if (filesWithoutLocalAgents.length > 0 && deps.deploymentGateway) {
19792
+ const orgAgents = await fetchOrgDefaultAgents(deps.deploymentGateway);
19793
+ if (orgAgents.length > 0) {
19794
+ const filePaths = filesWithoutLocalAgents.map((entry) => ` ${getRelativePath(entry.dir, getCwd())}`).join("\n");
19795
+ const message = `The following file(s) currently use organization-level agent settings:
19796
+ ${filePaths}
19797
+
19798
+ Organization agents currently active: ${orgAgents.join(", ")}
19799
+
19800
+ By adding agent(s) manually, you will override the organization configuration
19801
+ for these file(s). After this change:
19802
+ - Only the agent(s) you add will be configured locally.
19803
+ - Organization-level settings will NO LONGER apply to these file(s).
19804
+ - Any future changes to organization agents will NOT affect these file(s).
19805
+
19806
+ To restore organization settings later, remove all local agents with: packmind-cli config agents rm <agent1> <agent2> ...`;
19807
+ logWarningConsole(message);
19808
+ const confirmed = await deps.promptConfirm("Do you want to proceed?");
19809
+ if (!confirmed) {
19810
+ logConsole("Aborted.");
19811
+ exit(0);
19812
+ return;
19813
+ }
19814
+ }
19815
+ }
19816
+ let anyUpdated = false;
19817
+ for (const { dir, config } of validEntries) {
19818
+ const relPath = getRelativePath(dir, getCwd());
19819
+ const existingAgents = config.agents ?? [];
19820
+ const alreadyPresent = agentsToAdd.filter(
19821
+ (a) => existingAgents.includes(a)
19822
+ );
19823
+ const toAdd = agentsToAdd.filter((a) => !existingAgents.includes(a));
19824
+ for (const agent of alreadyPresent) {
19825
+ logWarningConsole(`Agent ${agent} already configured in ${relPath}`);
19826
+ }
19827
+ if (toAdd.length > 0) {
19828
+ const mergedAgents = [...existingAgents, ...toAdd];
19829
+ await configRepository.updateAgentsConfig(dir, mergedAgents);
19830
+ logSuccessConsole(`Updated ${relPath}`);
19831
+ anyUpdated = true;
19832
+ }
19833
+ }
19834
+ if (anyUpdated) {
19835
+ logInfoConsole(
19836
+ `Run "${formatCommand("packmind install")}" to apply changes and deploy agent artifacts.`
19837
+ );
19838
+ }
19839
+ exit(0);
19840
+ }
19841
+
19842
+ // apps/cli/src/infra/commands/config/ConfigAgentsAddCommand.ts
19843
+ function createPromptConfirm() {
19844
+ return (message) => new Promise((resolve14) => {
19845
+ const rl = readline5.createInterface({
19846
+ input: process.stdin,
19847
+ output: process.stdout
19848
+ });
19849
+ rl.question(`${message} (y/N) `, (answer) => {
19850
+ rl.close();
19851
+ resolve14(answer.toLowerCase() === "y");
19852
+ });
19853
+ });
19854
+ }
19855
+ var addAgentsCommand = (0, import_cmd_ts35.command)({
19856
+ name: "add",
19857
+ description: "Add coding agents to packmind.json files",
19858
+ args: {
19859
+ path: (0, import_cmd_ts35.option)({
19860
+ type: import_cmd_ts35.string,
19861
+ short: "p",
19862
+ long: "path",
19863
+ defaultValue: () => "",
19864
+ description: "Run in the specified directory (recursive within that path)"
19865
+ }),
19866
+ agentNames: agentNamesPositional
19867
+ },
19868
+ handler: async ({ path: pathArg, agentNames }) => {
19869
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
19870
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
19871
+ const configRepository = new ConfigFileRepository();
19872
+ await addAgentsHandler(
19873
+ { agentNames, path: pathArg || void 0 },
19874
+ {
19875
+ configRepository,
19876
+ deploymentGateway: packmindCliHexa.getPackmindGateway().deployment,
19877
+ exit: process.exit,
19878
+ getCwd: () => process.cwd(),
19879
+ promptConfirm: createPromptConfirm()
19880
+ }
19881
+ );
19882
+ }
19883
+ });
19884
+
19885
+ // apps/cli/src/infra/commands/config/ConfigAgentsListCommand.ts
19886
+ var import_cmd_ts36 = __toESM(require_cjs());
19887
+
19888
+ // apps/cli/src/infra/commands/config/agents/listAgentsHandler.ts
19889
+ var SOURCE_LABELS = {
19890
+ local: "packmind.json",
19891
+ organization: "Organization settings"
19892
+ };
19893
+ function formatMatrix(files, agents) {
19894
+ const pathColumnWidth = Math.max(...files.map((f) => f.path.length)) + 2;
19895
+ const columnWidth = Math.max(...agents.map((a) => a.length), 1) + 2;
19896
+ const lines = [];
19897
+ const header = "".padEnd(pathColumnWidth) + agents.map((a) => formatBold(a.padEnd(columnWidth))).join("") + formatBold("source (packmind.json or Organization settings)");
19898
+ lines.push(header);
19899
+ for (const file of files) {
19900
+ const agentSet = new Set(file.agents);
19901
+ const row = formatFilePath(file.path) + "".padEnd(pathColumnWidth - file.path.length) + agents.map((a) => (agentSet.has(a) ? "\u2713" : "-").padEnd(columnWidth)).join("") + SOURCE_LABELS[file.source];
19902
+ lines.push(row);
19903
+ }
19904
+ return lines;
19905
+ }
19906
+ async function listAgentsHandler(args2, deps) {
19907
+ const { configRepository, exit, getCwd } = deps;
19908
+ const startDirectory = await resolveStartDirectory(args2, getCwd, exit);
19909
+ if (!startDirectory) return;
19910
+ const descendantDirs = await configRepository.findDescendantConfigs(startDirectory);
19911
+ const allDirs = [startDirectory, ...descendantDirs];
19912
+ const fileConfigs = [];
19913
+ for (const dir of allDirs) {
19914
+ const config = await configRepository.readConfig(dir);
19915
+ if (config === null) continue;
19916
+ fileConfigs.push({
19917
+ path: getRelativePath(dir, getCwd()),
19918
+ agents: config.agents ?? [],
19919
+ source: config.agents !== void 0 ? "local" : "organization"
19920
+ });
19921
+ }
19922
+ if (fileConfigs.length === 0) {
19923
+ logWarningConsole("No packmind.json files found.");
19924
+ exit(0);
19925
+ return;
19926
+ }
19927
+ const filesWithoutAgents = fileConfigs.filter(
19928
+ (f) => f.source === "organization"
19929
+ );
19930
+ if (filesWithoutAgents.length > 0 && deps.deploymentGateway) {
19931
+ const orgAgents = await fetchOrgDefaultAgents(deps.deploymentGateway);
19932
+ if (orgAgents.length > 0) {
19933
+ for (const file of filesWithoutAgents) {
19934
+ file.agents = orgAgents;
19935
+ }
19936
+ }
19937
+ }
19938
+ const allAgents = [
19939
+ ...new Set(fileConfigs.flatMap((f) => f.agents))
19940
+ ].sort((a, b) => a.localeCompare(b));
19941
+ const sortedFiles = [...fileConfigs].sort((a, b) => {
19942
+ const depthA = a.path.split("/").length;
19943
+ const depthB = b.path.split("/").length;
19944
+ if (depthA !== depthB) return depthA - depthB;
19945
+ return a.path.localeCompare(b.path);
19946
+ });
19947
+ if (allAgents.length === 0) {
19948
+ logConsole("\nNo agents configured in any packmind.json file.\n");
19949
+ for (const file of sortedFiles) {
19950
+ logConsole(` ${formatFilePath(file.path)}`);
19951
+ }
19952
+ logConsole("");
19953
+ exit(0);
19954
+ return;
19955
+ }
19956
+ logConsole("");
19957
+ const lines = formatMatrix(sortedFiles, allAgents);
19958
+ for (const line of lines) {
19959
+ logConsole(line);
19960
+ }
19961
+ logConsole("");
19962
+ exit(0);
19963
+ }
19964
+
19965
+ // apps/cli/src/infra/commands/config/ConfigAgentsListCommand.ts
19966
+ var listAgentsCommand = (0, import_cmd_ts36.command)({
19967
+ name: "list",
19968
+ description: "List coding agents configured across packmind.json files",
19969
+ args: {
19970
+ path: (0, import_cmd_ts36.option)({
19971
+ type: import_cmd_ts36.string,
19972
+ short: "p",
19973
+ long: "path",
19974
+ defaultValue: () => "",
19975
+ description: "Run in the specified directory (recursive within that path)"
19976
+ })
19977
+ },
19978
+ handler: async ({ path: pathArg }) => {
19979
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
19980
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
19981
+ const configRepository = new ConfigFileRepository();
19982
+ await listAgentsHandler(
19983
+ { path: pathArg || void 0 },
19984
+ {
19985
+ configRepository,
19986
+ deploymentGateway: packmindCliHexa.getPackmindGateway().deployment,
19987
+ exit: process.exit,
19988
+ getCwd: () => process.cwd()
19989
+ }
19990
+ );
19991
+ }
19992
+ });
19993
+
19994
+ // apps/cli/src/infra/commands/config/ConfigAgentsRemoveCommand.ts
19995
+ var import_cmd_ts37 = __toESM(require_cjs());
19996
+
19997
+ // apps/cli/src/infra/commands/config/agents/removeAgentsHandler.ts
19998
+ async function removeAgentsHandler(args2, deps) {
19999
+ const { configRepository, exit, getCwd } = deps;
20000
+ const startDirectory = await resolveStartDirectory(args2, getCwd, exit);
20001
+ if (!startDirectory) return;
20002
+ const descendantDirs = await configRepository.findDescendantConfigs(startDirectory);
20003
+ const allDirs = [startDirectory, ...descendantDirs];
20004
+ const validEntries = [];
20005
+ for (const dir of allDirs) {
20006
+ const config = await configRepository.readConfig(dir);
20007
+ if (config !== null) validEntries.push({ dir, config });
20008
+ }
20009
+ if (validEntries.length === 0) {
20010
+ logWarningConsole("No packmind.json files found.");
20011
+ exit(0);
20012
+ return;
20013
+ }
20014
+ const configuredAgents = [
20015
+ ...new Set(validEntries.flatMap(({ config }) => config.agents ?? []))
20016
+ ].sort((a, b) => a.localeCompare(b));
20017
+ if (args2.agentNames.length === 0) {
20018
+ logErrorConsole("No agents specified.");
20019
+ logConfiguredAgentsHint(configuredAgents);
20020
+ exit(1);
20021
+ return;
20022
+ }
20023
+ const invalidAgents = args2.agentNames.filter(
20024
+ (n) => !SELECTABLE_AGENTS.includes(n)
20025
+ );
20026
+ if (invalidAgents.length > 0) {
20027
+ logErrorConsole(`Unknown agent(s): ${invalidAgents.join(", ")}`);
20028
+ logConfiguredAgentsHint(configuredAgents);
20029
+ exit(1);
20030
+ return;
20031
+ }
20032
+ const agentsToRemove = args2.agentNames;
20033
+ let anyUpdated = false;
20034
+ for (const { dir, config } of validEntries) {
20035
+ const relPath = getRelativePath(dir, getCwd());
20036
+ const existingAgents = config.agents ?? [];
20037
+ const notPresent = agentsToRemove.filter(
20038
+ (a) => !existingAgents.includes(a)
20039
+ );
20040
+ const toRemove = agentsToRemove.filter((a) => existingAgents.includes(a));
20041
+ for (const agent of notPresent) {
20042
+ logWarningConsole(`Agent ${agent} not configured in ${relPath}`);
20043
+ }
20044
+ if (toRemove.length > 0) {
20045
+ const remainingAgents = existingAgents.filter(
20046
+ (a) => !toRemove.includes(a)
20047
+ );
20048
+ if (remainingAgents.length === 0) {
20049
+ await configRepository.deleteAgentsConfig(dir);
20050
+ logWarningConsole(
20051
+ `${relPath} now has no agents configured \u2014 organization settings will be used.`
20052
+ );
20053
+ } else {
20054
+ await configRepository.updateAgentsConfig(dir, remainingAgents);
20055
+ }
20056
+ logSuccessConsole(`Updated ${relPath}`);
20057
+ anyUpdated = true;
20058
+ }
20059
+ }
20060
+ if (anyUpdated) {
20061
+ logInfoConsole(
20062
+ `Run "${formatCommand("packmind install")}" to apply changes and remove agent artifacts.`
20063
+ );
20064
+ }
20065
+ exit(0);
20066
+ }
20067
+ function logConfiguredAgentsHint(configuredAgents) {
20068
+ if (configuredAgents.length > 0) {
20069
+ logConsole(`Configured agents: ${configuredAgents.join(", ")}`);
20070
+ } else {
20071
+ logConsole(
20072
+ "No agents are currently configured in any packmind.json file \u2014 all projects use organization settings."
20073
+ );
20074
+ }
20075
+ }
20076
+
20077
+ // apps/cli/src/infra/commands/config/ConfigAgentsRemoveCommand.ts
20078
+ var removeAgentsCommand = (0, import_cmd_ts37.command)({
20079
+ name: "rm",
20080
+ aliases: ["remove"],
20081
+ description: "Remove coding agents from packmind.json files",
20082
+ args: {
20083
+ path: (0, import_cmd_ts37.option)({
20084
+ type: import_cmd_ts37.string,
20085
+ short: "p",
20086
+ long: "path",
20087
+ defaultValue: () => "",
20088
+ description: "Run in the specified directory (recursive within that path)"
20089
+ }),
20090
+ agentNames: agentNamesPositional
20091
+ },
20092
+ handler: async ({ path: pathArg, agentNames }) => {
20093
+ const configRepository = new ConfigFileRepository();
20094
+ await removeAgentsHandler(
20095
+ { agentNames, path: pathArg || void 0 },
20096
+ {
20097
+ configRepository,
20098
+ exit: process.exit,
20099
+ getCwd: () => process.cwd()
20100
+ }
20101
+ );
20102
+ }
20103
+ });
19510
20104
 
19511
20105
  // apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
19512
- var configAgentsCommand = (0, import_cmd_ts34.command)({
19513
- name: "agents",
20106
+ var configAgentsSetupCommand = (0, import_cmd_ts38.command)({
20107
+ name: "setup",
19514
20108
  description: "Configure which coding agents to generate artifacts for",
19515
20109
  args: {},
19516
20110
  handler: async () => {
@@ -19527,9 +20121,19 @@ var configAgentsCommand = (0, import_cmd_ts34.command)({
19527
20121
  });
19528
20122
  }
19529
20123
  });
20124
+ var configAgentsCommand = (0, import_cmd_ts38.subcommands)({
20125
+ name: "agents",
20126
+ description: "Manage coding agents configuration",
20127
+ cmds: {
20128
+ setup: configAgentsSetupCommand,
20129
+ add: addAgentsCommand,
20130
+ list: listAgentsCommand,
20131
+ rm: removeAgentsCommand
20132
+ }
20133
+ });
19530
20134
 
19531
20135
  // apps/cli/src/infra/commands/config/ConfigCommand.ts
19532
- var configCommand = (0, import_cmd_ts35.subcommands)({
20136
+ var configCommand = (0, import_cmd_ts39.subcommands)({
19533
20137
  name: "config",
19534
20138
  description: "Manage Packmind configuration",
19535
20139
  cmds: {
@@ -19538,7 +20142,7 @@ var configCommand = (0, import_cmd_ts35.subcommands)({
19538
20142
  });
19539
20143
 
19540
20144
  // apps/cli/src/infra/commands/InitCommand.ts
19541
- var import_cmd_ts36 = __toESM(require_cjs());
20145
+ var import_cmd_ts40 = __toESM(require_cjs());
19542
20146
 
19543
20147
  // apps/cli/src/infra/commands/initHandler.ts
19544
20148
  async function initHandler(deps) {
@@ -19600,7 +20204,7 @@ async function initHandler(deps) {
19600
20204
 
19601
20205
  // apps/cli/src/infra/commands/InitCommand.ts
19602
20206
  var { version: CLI_VERSION4 } = require_package();
19603
- var initCommand = (0, import_cmd_ts36.command)({
20207
+ var initCommand = (0, import_cmd_ts40.command)({
19604
20208
  name: "init",
19605
20209
  description: "Initialize Packmind in the current project",
19606
20210
  args: {},
@@ -19628,13 +20232,13 @@ var initCommand = (0, import_cmd_ts36.command)({
19628
20232
  });
19629
20233
 
19630
20234
  // apps/cli/src/infra/commands/UpdateCommand.ts
19631
- var import_cmd_ts37 = __toESM(require_cjs());
20235
+ var import_cmd_ts41 = __toESM(require_cjs());
19632
20236
  var { version: CLI_VERSION5 } = require_package();
19633
- var updateCommand = (0, import_cmd_ts37.command)({
20237
+ var updateCommand = (0, import_cmd_ts41.command)({
19634
20238
  name: "update",
19635
20239
  description: "Update packmind-cli to the latest version",
19636
20240
  args: {
19637
- check: (0, import_cmd_ts37.flag)({
20241
+ check: (0, import_cmd_ts41.flag)({
19638
20242
  long: "check",
19639
20243
  description: "Only check if a newer version is available without performing the update"
19640
20244
  })
@@ -19659,20 +20263,20 @@ function findEnvFile() {
19659
20263
  const currentDir = process.cwd();
19660
20264
  const gitService = new GitService();
19661
20265
  const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
19662
- const filesystemRoot = path32.parse(currentDir).root;
20266
+ const filesystemRoot = path35.parse(currentDir).root;
19663
20267
  const stopDir = gitRoot ?? filesystemRoot;
19664
20268
  let searchDir = currentDir;
19665
- let parentDir = path32.dirname(searchDir);
20269
+ let parentDir = path35.dirname(searchDir);
19666
20270
  while (searchDir !== parentDir) {
19667
- const envPath2 = path32.join(searchDir, ".env");
19668
- if (fs26.existsSync(envPath2)) {
20271
+ const envPath2 = path35.join(searchDir, ".env");
20272
+ if (fs27.existsSync(envPath2)) {
19669
20273
  return envPath2;
19670
20274
  }
19671
20275
  if (searchDir === stopDir) {
19672
20276
  return null;
19673
20277
  }
19674
20278
  searchDir = parentDir;
19675
- parentDir = path32.dirname(searchDir);
20279
+ parentDir = path35.dirname(searchDir);
19676
20280
  }
19677
20281
  return null;
19678
20282
  }
@@ -19692,7 +20296,7 @@ if (args.includes("--version") || args.includes("-v")) {
19692
20296
  logConsole(`packmind-cli version ${CLI_VERSION6}`);
19693
20297
  process.exit(0);
19694
20298
  }
19695
- var app = (0, import_cmd_ts38.subcommands)({
20299
+ var app = (0, import_cmd_ts42.subcommands)({
19696
20300
  name: "packmind-cli",
19697
20301
  description: "Packmind CLI tool",
19698
20302
  cmds: {
@@ -19715,7 +20319,7 @@ var app = (0, import_cmd_ts38.subcommands)({
19715
20319
  whoami: whoamiCommand
19716
20320
  }
19717
20321
  });
19718
- (0, import_cmd_ts38.run)(app, args).catch((error) => {
20322
+ (0, import_cmd_ts42.run)(app, args).catch((error) => {
19719
20323
  logErrorConsole(error.message);
19720
20324
  process.exit(1);
19721
20325
  });