@packmind/cli 0.15.0 → 0.16.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.
- package/main.cjs +1162 -679
- package/package.json +14 -1
package/main.cjs
CHANGED
|
@@ -371,32 +371,32 @@ var init_supports_color = __esm({
|
|
|
371
371
|
});
|
|
372
372
|
|
|
373
373
|
// node_modules/chalk/source/utilities.js
|
|
374
|
-
function stringReplaceAll(
|
|
375
|
-
let index =
|
|
374
|
+
function stringReplaceAll(string10, substring, replacer) {
|
|
375
|
+
let index = string10.indexOf(substring);
|
|
376
376
|
if (index === -1) {
|
|
377
|
-
return
|
|
377
|
+
return string10;
|
|
378
378
|
}
|
|
379
379
|
const substringLength = substring.length;
|
|
380
380
|
let endIndex = 0;
|
|
381
381
|
let returnValue = "";
|
|
382
382
|
do {
|
|
383
|
-
returnValue +=
|
|
383
|
+
returnValue += string10.slice(endIndex, index) + substring + replacer;
|
|
384
384
|
endIndex = index + substringLength;
|
|
385
|
-
index =
|
|
385
|
+
index = string10.indexOf(substring, endIndex);
|
|
386
386
|
} while (index !== -1);
|
|
387
|
-
returnValue +=
|
|
387
|
+
returnValue += string10.slice(endIndex);
|
|
388
388
|
return returnValue;
|
|
389
389
|
}
|
|
390
|
-
function stringEncaseCRLFWithFirstIndex(
|
|
390
|
+
function stringEncaseCRLFWithFirstIndex(string10, prefix, postfix, index) {
|
|
391
391
|
let endIndex = 0;
|
|
392
392
|
let returnValue = "";
|
|
393
393
|
do {
|
|
394
|
-
const gotCR =
|
|
395
|
-
returnValue +=
|
|
394
|
+
const gotCR = string10[index - 1] === "\r";
|
|
395
|
+
returnValue += string10.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
396
396
|
endIndex = index + 1;
|
|
397
|
-
index =
|
|
397
|
+
index = string10.indexOf("\n", endIndex);
|
|
398
398
|
} while (index !== -1);
|
|
399
|
-
returnValue +=
|
|
399
|
+
returnValue += string10.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,
|
|
559
|
-
if (self.level <= 0 || !
|
|
560
|
-
return self[IS_EMPTY] ? "" :
|
|
558
|
+
applyStyle = (self, string10) => {
|
|
559
|
+
if (self.level <= 0 || !string10) {
|
|
560
|
+
return self[IS_EMPTY] ? "" : string10;
|
|
561
561
|
}
|
|
562
562
|
let styler = self[STYLER];
|
|
563
563
|
if (styler === void 0) {
|
|
564
|
-
return
|
|
564
|
+
return string10;
|
|
565
565
|
}
|
|
566
566
|
const { openAll, closeAll } = styler;
|
|
567
|
-
if (
|
|
567
|
+
if (string10.includes("\x1B")) {
|
|
568
568
|
while (styler !== void 0) {
|
|
569
|
-
|
|
569
|
+
string10 = stringReplaceAll(string10, styler.close, styler.open);
|
|
570
570
|
styler = styler.parent;
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
|
-
const lfIndex =
|
|
573
|
+
const lfIndex = string10.indexOf("\n");
|
|
574
574
|
if (lfIndex !== -1) {
|
|
575
|
-
|
|
575
|
+
string10 = stringEncaseCRLFWithFirstIndex(string10, closeAll, openAll, lfIndex);
|
|
576
576
|
}
|
|
577
|
-
return openAll +
|
|
577
|
+
return openAll + string10 + 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
|
|
771
|
-
if (opts.shortNames.includes(
|
|
772
|
-
result.push(
|
|
770
|
+
for (const option6 of node.options) {
|
|
771
|
+
if (opts.shortNames.includes(option6.key)) {
|
|
772
|
+
result.push(option6);
|
|
773
773
|
}
|
|
774
774
|
}
|
|
775
775
|
}
|
|
@@ -843,7 +843,7 @@ var require_types = __commonJS({
|
|
|
843
843
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
844
844
|
exports2.boolean = exports2.string = exports2.number = void 0;
|
|
845
845
|
exports2.optional = optional4;
|
|
846
|
-
exports2.array =
|
|
846
|
+
exports2.array = array3;
|
|
847
847
|
var type_1 = require_type();
|
|
848
848
|
exports2.number = {
|
|
849
849
|
async from(str) {
|
|
@@ -877,7 +877,7 @@ var require_types = __commonJS({
|
|
|
877
877
|
}
|
|
878
878
|
};
|
|
879
879
|
}
|
|
880
|
-
function
|
|
880
|
+
function array3(t) {
|
|
881
881
|
return {
|
|
882
882
|
...t,
|
|
883
883
|
async from(inputs) {
|
|
@@ -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 =
|
|
1382
|
+
exports2.subcommands = subcommands7;
|
|
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
|
|
1388
|
+
function subcommands7(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
|
|
1406
|
+
const option6 = Array.isArray(closeOptions) ? closeOptions[0] : closeOptions;
|
|
1407
1407
|
errorMessage += `
|
|
1408
|
-
Did you mean ${chalk_1.default.italic(
|
|
1408
|
+
Did you mean ${chalk_1.default.italic(option6)}?`;
|
|
1409
1409
|
}
|
|
1410
1410
|
throw new Error(errorMessage);
|
|
1411
1411
|
}
|
|
@@ -1526,9 +1526,9 @@ Did you mean ${chalk_1.default.italic(option5)}?`;
|
|
|
1526
1526
|
}
|
|
1527
1527
|
};
|
|
1528
1528
|
}
|
|
1529
|
-
function flatMap(
|
|
1529
|
+
function flatMap(array3, f) {
|
|
1530
1530
|
const rs = [];
|
|
1531
|
-
for (const item of
|
|
1531
|
+
for (const item of array3) {
|
|
1532
1532
|
rs.push(...f(item));
|
|
1533
1533
|
}
|
|
1534
1534
|
return rs;
|
|
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
|
|
|
1578
1578
|
__export(strip_ansi_exports, {
|
|
1579
1579
|
default: () => stripAnsi
|
|
1580
1580
|
});
|
|
1581
|
-
function stripAnsi(
|
|
1582
|
-
if (typeof
|
|
1583
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof
|
|
1581
|
+
function stripAnsi(string10) {
|
|
1582
|
+
if (typeof string10 !== "string") {
|
|
1583
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string10}\``);
|
|
1584
1584
|
}
|
|
1585
|
-
return
|
|
1585
|
+
return string10.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 =
|
|
1701
|
+
exports2.command = command20;
|
|
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
|
|
1706
|
+
function command20(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
|
|
1785
|
-
if (context.visitedNodes.has(
|
|
1784
|
+
for (const option6 of node.options) {
|
|
1785
|
+
if (context.visitedNodes.has(option6)) {
|
|
1786
1786
|
continue;
|
|
1787
1787
|
}
|
|
1788
|
-
unknownArguments.push(
|
|
1788
|
+
unknownArguments.push(option6);
|
|
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 =
|
|
1867
|
+
exports2.option = option6;
|
|
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
|
|
1943
|
+
const option7 = options[0];
|
|
1944
1944
|
let rawValue;
|
|
1945
1945
|
let envPrefix = "";
|
|
1946
|
-
if (
|
|
1947
|
-
rawValue =
|
|
1946
|
+
if (option7 === null || option7 === void 0 ? void 0 : option7.value) {
|
|
1947
|
+
rawValue = option7.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 = (
|
|
1982
|
+
const raw = (option7 === null || option7 === void 0 ? void 0 : option7.type) === "shortOption" ? `-${option7 === null || option7 === void 0 ? void 0 : option7.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
|
|
2004
|
+
function option6(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
|
|
2044
|
-
if (error.nodes.includes(
|
|
2045
|
-
s += chalk_1.default.red(
|
|
2043
|
+
for (const option6 of node.options) {
|
|
2044
|
+
if (error.nodes.includes(option6)) {
|
|
2045
|
+
s += chalk_1.default.red(option6.raw);
|
|
2046
2046
|
failed = true;
|
|
2047
2047
|
} else {
|
|
2048
|
-
s += chalk_1.default.dim(
|
|
2048
|
+
s += chalk_1.default.dim(option6.raw);
|
|
2049
2049
|
}
|
|
2050
2050
|
}
|
|
2051
2051
|
const prefix = failed ? chalk_1.default.red("-") : chalk_1.default.dim("-");
|
|
@@ -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,
|
|
3088
|
-
const chars = [...
|
|
3087
|
+
for (const [stringIndex, string10] of (0, utils_1.enumerate)(strings)) {
|
|
3088
|
+
const chars = [...string10];
|
|
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 });
|
|
@@ -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
|
|
3350
|
-
visitedNodes.add(
|
|
3349
|
+
for (const option6 of options) {
|
|
3350
|
+
visitedNodes.add(option6);
|
|
3351
3351
|
}
|
|
3352
3352
|
const optionValues = [];
|
|
3353
3353
|
const errors = [];
|
|
3354
|
-
for (const
|
|
3355
|
-
const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a =
|
|
3354
|
+
for (const option6 of options) {
|
|
3355
|
+
const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option6.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: [
|
|
3357
|
+
errors.push({ nodes: [option6], message: decoded.error.message });
|
|
3358
3358
|
} else {
|
|
3359
3359
|
optionValues.push(decoded.value);
|
|
3360
3360
|
}
|
|
@@ -3427,11 +3427,11 @@ var require_multioption = __commonJS({
|
|
|
3427
3427
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
3428
3428
|
};
|
|
3429
3429
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3430
|
-
exports2.multioption =
|
|
3430
|
+
exports2.multioption = multioption3;
|
|
3431
3431
|
var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
|
|
3432
3432
|
var Result = __importStar(require_Result());
|
|
3433
3433
|
var findOption_1 = require_findOption();
|
|
3434
|
-
function
|
|
3434
|
+
function multioption3(config) {
|
|
3435
3435
|
return {
|
|
3436
3436
|
helpTopics() {
|
|
3437
3437
|
var _a, _b;
|
|
@@ -3518,16 +3518,16 @@ var require_multioption = __commonJS({
|
|
|
3518
3518
|
});
|
|
3519
3519
|
}
|
|
3520
3520
|
}
|
|
3521
|
-
for (const
|
|
3522
|
-
visitedNodes.add(
|
|
3521
|
+
for (const option6 of options) {
|
|
3522
|
+
visitedNodes.add(option6);
|
|
3523
3523
|
}
|
|
3524
3524
|
const optionValues = [];
|
|
3525
3525
|
const errors = [];
|
|
3526
3526
|
const flagNodes = [];
|
|
3527
|
-
for (const
|
|
3528
|
-
const providedValue = (_a =
|
|
3527
|
+
for (const option6 of options) {
|
|
3528
|
+
const providedValue = (_a = option6.value) === null || _a === void 0 ? void 0 : _a.node.raw;
|
|
3529
3529
|
if (providedValue === void 0) {
|
|
3530
|
-
flagNodes.push(
|
|
3530
|
+
flagNodes.push(option6);
|
|
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.
|
|
3855
|
+
version: "0.16.0",
|
|
3856
3856
|
description: "A command-line interface for Packmind linting and code quality checks",
|
|
3857
3857
|
private: false,
|
|
3858
3858
|
bin: {
|
|
@@ -3895,7 +3895,7 @@ var require_package = __commonJS({
|
|
|
3895
3895
|
});
|
|
3896
3896
|
|
|
3897
3897
|
// apps/cli/src/main.ts
|
|
3898
|
-
var
|
|
3898
|
+
var import_cmd_ts25 = __toESM(require_cjs());
|
|
3899
3899
|
|
|
3900
3900
|
// apps/cli/src/infra/commands/LinterCommand.ts
|
|
3901
3901
|
var import_cmd_ts = __toESM(require_cjs());
|
|
@@ -4003,6 +4003,9 @@ var createOrganizationId = brandedIdFactory();
|
|
|
4003
4003
|
// packages/types/src/accounts/User.ts
|
|
4004
4004
|
var createUserId = brandedIdFactory();
|
|
4005
4005
|
|
|
4006
|
+
// packages/types/src/accounts/UserMetadata.ts
|
|
4007
|
+
var createUserMetadataId = brandedIdFactory();
|
|
4008
|
+
|
|
4006
4009
|
// packages/types/src/events/PackmindEvent.ts
|
|
4007
4010
|
var PackmindEvent = class {
|
|
4008
4011
|
constructor(payload) {
|
|
@@ -4060,6 +4063,41 @@ var OrganizationCreatedEvent = class extends UserEvent {
|
|
|
4060
4063
|
var createTrialActivationTokenId = brandedIdFactory();
|
|
4061
4064
|
var createTrialActivationToken = brandedIdFactory();
|
|
4062
4065
|
|
|
4066
|
+
// packages/types/src/coding-agent/validation.ts
|
|
4067
|
+
var VALID_CODING_AGENTS = [
|
|
4068
|
+
"packmind",
|
|
4069
|
+
"junie",
|
|
4070
|
+
"claude",
|
|
4071
|
+
"cursor",
|
|
4072
|
+
"copilot",
|
|
4073
|
+
"agents_md",
|
|
4074
|
+
"gitlab_duo",
|
|
4075
|
+
"continue"
|
|
4076
|
+
];
|
|
4077
|
+
function isValidCodingAgent(value) {
|
|
4078
|
+
return VALID_CODING_AGENTS.includes(value);
|
|
4079
|
+
}
|
|
4080
|
+
function validateAgentsWithWarnings(agents) {
|
|
4081
|
+
if (agents === void 0 || agents === null) {
|
|
4082
|
+
return { validAgents: null, invalidAgents: [] };
|
|
4083
|
+
}
|
|
4084
|
+
if (!Array.isArray(agents)) {
|
|
4085
|
+
return { validAgents: null, invalidAgents: [] };
|
|
4086
|
+
}
|
|
4087
|
+
const validAgents = [];
|
|
4088
|
+
const invalidAgents = [];
|
|
4089
|
+
for (const agent of agents) {
|
|
4090
|
+
if (typeof agent === "string") {
|
|
4091
|
+
if (isValidCodingAgent(agent)) {
|
|
4092
|
+
validAgents.push(agent);
|
|
4093
|
+
} else {
|
|
4094
|
+
invalidAgents.push(agent);
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
return { validAgents, invalidAgents };
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4063
4101
|
// packages/types/src/recipes/RecipeId.ts
|
|
4064
4102
|
var createRecipeId = brandedIdFactory();
|
|
4065
4103
|
|
|
@@ -4908,8 +4946,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
|
|
|
4908
4946
|
static {
|
|
4909
4947
|
this.fallbackRuleContent = "adhoc-rule";
|
|
4910
4948
|
}
|
|
4911
|
-
async execute(
|
|
4912
|
-
const { program, fileContent, language } =
|
|
4949
|
+
async execute(command20) {
|
|
4950
|
+
const { program, fileContent, language } = command20;
|
|
4913
4951
|
const result = await this.linterExecutionUseCase.execute({
|
|
4914
4952
|
filePath: "cli-single-file",
|
|
4915
4953
|
fileContent,
|
|
@@ -4959,30 +4997,30 @@ var GitService = class {
|
|
|
4959
4997
|
this.gitRunner = gitRunner;
|
|
4960
4998
|
this.logger = logger2;
|
|
4961
4999
|
}
|
|
4962
|
-
getGitRepositoryRoot(
|
|
5000
|
+
getGitRepositoryRoot(path14) {
|
|
4963
5001
|
try {
|
|
4964
5002
|
const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
|
|
4965
|
-
cwd:
|
|
5003
|
+
cwd: path14
|
|
4966
5004
|
});
|
|
4967
5005
|
const gitRoot = stdout.trim();
|
|
4968
5006
|
this.logger.debug("Resolved git repository root", {
|
|
4969
|
-
inputPath:
|
|
5007
|
+
inputPath: path14,
|
|
4970
5008
|
gitRoot
|
|
4971
5009
|
});
|
|
4972
5010
|
return gitRoot;
|
|
4973
5011
|
} catch (error) {
|
|
4974
5012
|
if (error instanceof Error) {
|
|
4975
5013
|
throw new Error(
|
|
4976
|
-
`Failed to get Git repository root. The path '${
|
|
5014
|
+
`Failed to get Git repository root. The path '${path14}' does not appear to be inside a Git repository.
|
|
4977
5015
|
${error.message}`
|
|
4978
5016
|
);
|
|
4979
5017
|
}
|
|
4980
5018
|
throw new Error("Failed to get Git repository root: Unknown error");
|
|
4981
5019
|
}
|
|
4982
5020
|
}
|
|
4983
|
-
tryGetGitRepositoryRoot(
|
|
5021
|
+
tryGetGitRepositoryRoot(path14) {
|
|
4984
5022
|
try {
|
|
4985
|
-
return this.getGitRepositoryRoot(
|
|
5023
|
+
return this.getGitRepositoryRoot(path14);
|
|
4986
5024
|
} catch {
|
|
4987
5025
|
return null;
|
|
4988
5026
|
}
|
|
@@ -5289,8 +5327,8 @@ var GetGitRemoteUrlUseCase = class {
|
|
|
5289
5327
|
constructor(gitRemoteUrlService = new GitService()) {
|
|
5290
5328
|
this.gitRemoteUrlService = gitRemoteUrlService;
|
|
5291
5329
|
}
|
|
5292
|
-
async execute(
|
|
5293
|
-
const { path: repoPath, origin: origin9 } =
|
|
5330
|
+
async execute(command20) {
|
|
5331
|
+
const { path: repoPath, origin: origin9 } = command20;
|
|
5294
5332
|
return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin9);
|
|
5295
5333
|
}
|
|
5296
5334
|
};
|
|
@@ -5432,8 +5470,8 @@ var ListFilesInDirectoryUseCase = class {
|
|
|
5432
5470
|
constructor(listFiles = new ListFiles()) {
|
|
5433
5471
|
this.listFiles = listFiles;
|
|
5434
5472
|
}
|
|
5435
|
-
async execute(
|
|
5436
|
-
const { path: directoryPath, extensions, excludes = [] } =
|
|
5473
|
+
async execute(command20) {
|
|
5474
|
+
const { path: directoryPath, extensions, excludes = [] } = command20;
|
|
5437
5475
|
const files = await this.listFiles.listFilesInDirectory(
|
|
5438
5476
|
directoryPath,
|
|
5439
5477
|
extensions,
|
|
@@ -5527,7 +5565,7 @@ var LintFilesAgainstRuleUseCase = class {
|
|
|
5527
5565
|
}
|
|
5528
5566
|
return pattern;
|
|
5529
5567
|
}
|
|
5530
|
-
async execute(
|
|
5568
|
+
async execute(command20) {
|
|
5531
5569
|
const {
|
|
5532
5570
|
path: userPath,
|
|
5533
5571
|
draftMode,
|
|
@@ -5535,7 +5573,7 @@ var LintFilesAgainstRuleUseCase = class {
|
|
|
5535
5573
|
ruleId,
|
|
5536
5574
|
language,
|
|
5537
5575
|
diffMode
|
|
5538
|
-
} =
|
|
5576
|
+
} = command20;
|
|
5539
5577
|
this.logger.debug(
|
|
5540
5578
|
`Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
|
|
5541
5579
|
);
|
|
@@ -5707,6 +5745,11 @@ var LintFilesAgainstRuleUseCase = class {
|
|
|
5707
5745
|
this.logger.debug(
|
|
5708
5746
|
`Retrieved detection programs: targetsCount=${detectionPrograms.targets.length}`
|
|
5709
5747
|
);
|
|
5748
|
+
this.repositories.packmindGateway.linter.trackLinterExecution({
|
|
5749
|
+
targetCount: 1,
|
|
5750
|
+
standardCount: 1
|
|
5751
|
+
}).catch(() => {
|
|
5752
|
+
});
|
|
5710
5753
|
const violations = [];
|
|
5711
5754
|
for (const file of files) {
|
|
5712
5755
|
const fileViolations = [];
|
|
@@ -5848,8 +5891,8 @@ var LintFilesAgainstRuleUseCase = class {
|
|
|
5848
5891
|
return null;
|
|
5849
5892
|
}
|
|
5850
5893
|
}
|
|
5851
|
-
async executeProgramsForFile(
|
|
5852
|
-
const result = await this.services.linterExecutionUseCase.execute(
|
|
5894
|
+
async executeProgramsForFile(command20) {
|
|
5895
|
+
const result = await this.services.linterExecutionUseCase.execute(command20);
|
|
5853
5896
|
return result.violations;
|
|
5854
5897
|
}
|
|
5855
5898
|
extractExtensionFromFile(filePath) {
|
|
@@ -5906,8 +5949,8 @@ var LintFilesFromConfigUseCase = class {
|
|
|
5906
5949
|
}
|
|
5907
5950
|
return pattern;
|
|
5908
5951
|
}
|
|
5909
|
-
async execute(
|
|
5910
|
-
const { path: userPath, diffMode } =
|
|
5952
|
+
async execute(command20) {
|
|
5953
|
+
const { path: userPath, diffMode } = command20;
|
|
5911
5954
|
this.logger.debug(
|
|
5912
5955
|
`Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
|
|
5913
5956
|
);
|
|
@@ -6084,6 +6127,11 @@ var LintFilesFromConfigUseCase = class {
|
|
|
6084
6127
|
});
|
|
6085
6128
|
}
|
|
6086
6129
|
}
|
|
6130
|
+
this.repositories.packmindGateway.linter.trackLinterExecution({
|
|
6131
|
+
targetCount: allConfigs.configs.length,
|
|
6132
|
+
standardCount: allStandardsChecked.size
|
|
6133
|
+
}).catch(() => {
|
|
6134
|
+
});
|
|
6087
6135
|
let filteredViolations = violations;
|
|
6088
6136
|
if (diffMode === "lines" /* LINES */ && modifiedLines) {
|
|
6089
6137
|
filteredViolations = this.services.diffViolationFilterService.filterByLines(
|
|
@@ -6151,8 +6199,8 @@ var LintFilesFromConfigUseCase = class {
|
|
|
6151
6199
|
return null;
|
|
6152
6200
|
}
|
|
6153
6201
|
}
|
|
6154
|
-
async executeProgramsForFile(
|
|
6155
|
-
const result = await this.services.linterExecutionUseCase.execute(
|
|
6202
|
+
async executeProgramsForFile(command20) {
|
|
6203
|
+
const result = await this.services.linterExecutionUseCase.execute(command20);
|
|
6156
6204
|
return result.violations;
|
|
6157
6205
|
}
|
|
6158
6206
|
extractExtensionFromFile(filePath) {
|
|
@@ -6218,10 +6266,10 @@ var PackmindHttpClient = class {
|
|
|
6218
6266
|
return null;
|
|
6219
6267
|
}
|
|
6220
6268
|
}
|
|
6221
|
-
async request(
|
|
6269
|
+
async request(path14, options = {}) {
|
|
6222
6270
|
const { host } = this.getAuthContext();
|
|
6223
6271
|
const { method = "GET", body } = options;
|
|
6224
|
-
const url = `${host}${
|
|
6272
|
+
const url = `${host}${path14}`;
|
|
6225
6273
|
try {
|
|
6226
6274
|
const response = await fetch(url, {
|
|
6227
6275
|
method,
|
|
@@ -6278,13 +6326,13 @@ var CommunityEditionError = class extends Error {
|
|
|
6278
6326
|
var LinterGateway = class {
|
|
6279
6327
|
constructor(httpClient) {
|
|
6280
6328
|
this.httpClient = httpClient;
|
|
6281
|
-
this.getDraftDetectionProgramsForRule = async (
|
|
6329
|
+
this.getDraftDetectionProgramsForRule = async (command20) => {
|
|
6282
6330
|
const payload = {
|
|
6283
|
-
standardSlug:
|
|
6284
|
-
ruleId:
|
|
6331
|
+
standardSlug: command20.standardSlug,
|
|
6332
|
+
ruleId: command20.ruleId
|
|
6285
6333
|
};
|
|
6286
|
-
if (
|
|
6287
|
-
payload.language =
|
|
6334
|
+
if (command20.language) {
|
|
6335
|
+
payload.language = command20.language;
|
|
6288
6336
|
}
|
|
6289
6337
|
return this.httpClient.request("/api/v0/list-draft-detection-program", {
|
|
6290
6338
|
method: "POST",
|
|
@@ -6296,13 +6344,13 @@ var LinterGateway = class {
|
|
|
6296
6344
|
}
|
|
6297
6345
|
});
|
|
6298
6346
|
};
|
|
6299
|
-
this.getActiveDetectionProgramsForRule = async (
|
|
6347
|
+
this.getActiveDetectionProgramsForRule = async (command20) => {
|
|
6300
6348
|
const payload = {
|
|
6301
|
-
standardSlug:
|
|
6302
|
-
ruleId:
|
|
6349
|
+
standardSlug: command20.standardSlug,
|
|
6350
|
+
ruleId: command20.ruleId
|
|
6303
6351
|
};
|
|
6304
|
-
if (
|
|
6305
|
-
payload.language =
|
|
6352
|
+
if (command20.language) {
|
|
6353
|
+
payload.language = command20.language;
|
|
6306
6354
|
}
|
|
6307
6355
|
return this.httpClient.request("/api/v0/list-active-detection-program", {
|
|
6308
6356
|
method: "POST",
|
|
@@ -6314,13 +6362,13 @@ var LinterGateway = class {
|
|
|
6314
6362
|
}
|
|
6315
6363
|
});
|
|
6316
6364
|
};
|
|
6317
|
-
this.getDetectionProgramsForPackages = async (
|
|
6365
|
+
this.getDetectionProgramsForPackages = async (command20) => {
|
|
6318
6366
|
const response = await this.httpClient.request(
|
|
6319
6367
|
"/api/v0/detection-programs-for-packages",
|
|
6320
6368
|
{
|
|
6321
6369
|
method: "POST",
|
|
6322
6370
|
body: {
|
|
6323
|
-
packagesSlugs:
|
|
6371
|
+
packagesSlugs: command20.packagesSlugs
|
|
6324
6372
|
},
|
|
6325
6373
|
onError: (response2) => {
|
|
6326
6374
|
if (response2.status === 404) {
|
|
@@ -6331,6 +6379,12 @@ var LinterGateway = class {
|
|
|
6331
6379
|
);
|
|
6332
6380
|
return handleScopeInTargetsResponse(response);
|
|
6333
6381
|
};
|
|
6382
|
+
this.trackLinterExecution = async (command20) => {
|
|
6383
|
+
return this.httpClient.request(`/api/v0/track-execution`, {
|
|
6384
|
+
method: "POST",
|
|
6385
|
+
body: command20
|
|
6386
|
+
});
|
|
6387
|
+
};
|
|
6334
6388
|
}
|
|
6335
6389
|
};
|
|
6336
6390
|
function handleScopeInTargetsResponse(response) {
|
|
@@ -6386,33 +6440,39 @@ var SpacesGateway = class {
|
|
|
6386
6440
|
var SkillsGateway = class {
|
|
6387
6441
|
constructor(httpClient) {
|
|
6388
6442
|
this.httpClient = httpClient;
|
|
6389
|
-
this.upload = async (
|
|
6443
|
+
this.upload = async (command20) => {
|
|
6390
6444
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6391
6445
|
return this.httpClient.request(
|
|
6392
|
-
`/api/v0/organizations/${organizationId}/spaces/${
|
|
6446
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/skills/upload`,
|
|
6393
6447
|
{
|
|
6394
6448
|
method: "POST",
|
|
6395
|
-
body:
|
|
6449
|
+
body: command20
|
|
6396
6450
|
}
|
|
6397
6451
|
);
|
|
6398
6452
|
};
|
|
6399
|
-
this.getDefaults = async (
|
|
6453
|
+
this.getDefaults = async (command20) => {
|
|
6400
6454
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6401
6455
|
const queryParams = new URLSearchParams();
|
|
6402
|
-
if (
|
|
6456
|
+
if (command20.includeBeta) {
|
|
6403
6457
|
queryParams.set("includeBeta", "true");
|
|
6404
|
-
} else if (
|
|
6405
|
-
queryParams.set("cliVersion",
|
|
6458
|
+
} else if (command20.cliVersion) {
|
|
6459
|
+
queryParams.set("cliVersion", command20.cliVersion);
|
|
6460
|
+
}
|
|
6461
|
+
if (command20.agents !== void 0) {
|
|
6462
|
+
queryParams.append("agentsConfigOverride", "true");
|
|
6463
|
+
command20.agents.forEach((agent) => {
|
|
6464
|
+
queryParams.append("agent", agent);
|
|
6465
|
+
});
|
|
6406
6466
|
}
|
|
6407
6467
|
const queryString = queryParams.toString();
|
|
6408
6468
|
return this.httpClient.request(
|
|
6409
6469
|
`/api/v0/organizations/${organizationId}/skills/default${queryString ? `?${queryString}` : ""}`
|
|
6410
6470
|
);
|
|
6411
6471
|
};
|
|
6412
|
-
this.list = async (
|
|
6472
|
+
this.list = async (command20) => {
|
|
6413
6473
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6414
6474
|
return this.httpClient.request(
|
|
6415
|
-
`/api/v0/organizations/${organizationId}/spaces/${
|
|
6475
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/skills`
|
|
6416
6476
|
);
|
|
6417
6477
|
};
|
|
6418
6478
|
}
|
|
@@ -6420,25 +6480,24 @@ var SkillsGateway = class {
|
|
|
6420
6480
|
|
|
6421
6481
|
// apps/cli/src/infra/repositories/CommandsGateway.ts
|
|
6422
6482
|
var CommandsGateway = class {
|
|
6423
|
-
constructor(httpClient
|
|
6483
|
+
constructor(httpClient) {
|
|
6424
6484
|
this.httpClient = httpClient;
|
|
6425
|
-
this.
|
|
6426
|
-
this.create = async (spaceId, data) => {
|
|
6485
|
+
this.create = async (command20) => {
|
|
6427
6486
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6428
6487
|
return this.httpClient.request(
|
|
6429
|
-
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/recipes`,
|
|
6430
|
-
{ method: "POST", body:
|
|
6488
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/recipes`,
|
|
6489
|
+
{ method: "POST", body: command20 }
|
|
6431
6490
|
);
|
|
6432
6491
|
};
|
|
6433
|
-
this.list = async () => {
|
|
6434
|
-
const space = await this.spaces.getGlobal();
|
|
6492
|
+
this.list = async (command20) => {
|
|
6435
6493
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6436
|
-
const
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
}
|
|
6494
|
+
const listRecipesResponse = await this.httpClient.request(
|
|
6495
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/recipes`
|
|
6496
|
+
);
|
|
6497
|
+
if (listRecipesResponse instanceof Array) {
|
|
6498
|
+
return { recipes: listRecipesResponse };
|
|
6499
|
+
}
|
|
6500
|
+
return listRecipesResponse;
|
|
6442
6501
|
};
|
|
6443
6502
|
}
|
|
6444
6503
|
};
|
|
@@ -6475,374 +6534,101 @@ var StandardsGateway = class {
|
|
|
6475
6534
|
}
|
|
6476
6535
|
);
|
|
6477
6536
|
};
|
|
6478
|
-
this.list = async () => {
|
|
6479
|
-
const space = await this.spaces.getGlobal();
|
|
6537
|
+
this.list = async (command20) => {
|
|
6480
6538
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
slug: s.slug,
|
|
6485
|
-
name: s.name,
|
|
6486
|
-
description: s.description
|
|
6487
|
-
}));
|
|
6539
|
+
return this.httpClient.request(
|
|
6540
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/standards`
|
|
6541
|
+
);
|
|
6488
6542
|
};
|
|
6489
6543
|
}
|
|
6490
6544
|
};
|
|
6491
6545
|
|
|
6492
6546
|
// apps/cli/src/infra/repositories/PackagesGateway.ts
|
|
6493
|
-
function decodeJwt(jwt) {
|
|
6494
|
-
try {
|
|
6495
|
-
const parts = jwt.split(".");
|
|
6496
|
-
if (parts.length !== 3) {
|
|
6497
|
-
return null;
|
|
6498
|
-
}
|
|
6499
|
-
const payload = JSON.parse(
|
|
6500
|
-
Buffer.from(parts[1], "base64").toString("utf-8")
|
|
6501
|
-
);
|
|
6502
|
-
return payload;
|
|
6503
|
-
} catch {
|
|
6504
|
-
return null;
|
|
6505
|
-
}
|
|
6506
|
-
}
|
|
6507
|
-
function decodeApiKey(apiKey) {
|
|
6508
|
-
if (!apiKey) {
|
|
6509
|
-
return {
|
|
6510
|
-
payload: { host: "", jwt: "" },
|
|
6511
|
-
isValid: false,
|
|
6512
|
-
error: "NOT_LOGGED_IN"
|
|
6513
|
-
};
|
|
6514
|
-
}
|
|
6515
|
-
try {
|
|
6516
|
-
const trimmedKey = apiKey.trim();
|
|
6517
|
-
const jsonString = Buffer.from(trimmedKey, "base64").toString("utf-8");
|
|
6518
|
-
const payload = JSON.parse(jsonString);
|
|
6519
|
-
if (!payload.host || typeof payload.host !== "string") {
|
|
6520
|
-
return {
|
|
6521
|
-
payload,
|
|
6522
|
-
isValid: false,
|
|
6523
|
-
error: "Invalid API key: missing or invalid host field"
|
|
6524
|
-
};
|
|
6525
|
-
}
|
|
6526
|
-
if (!payload.jwt || typeof payload.jwt !== "string") {
|
|
6527
|
-
return {
|
|
6528
|
-
payload,
|
|
6529
|
-
isValid: false,
|
|
6530
|
-
error: "Invalid API key: missing or invalid jwt field"
|
|
6531
|
-
};
|
|
6532
|
-
}
|
|
6533
|
-
return {
|
|
6534
|
-
payload,
|
|
6535
|
-
isValid: true
|
|
6536
|
-
};
|
|
6537
|
-
} catch (error) {
|
|
6538
|
-
return {
|
|
6539
|
-
payload: { host: "", jwt: "" },
|
|
6540
|
-
isValid: false,
|
|
6541
|
-
error: `Failed to decode API key: ${error}`
|
|
6542
|
-
};
|
|
6543
|
-
}
|
|
6544
|
-
}
|
|
6545
6547
|
var PackagesGateway = class {
|
|
6546
6548
|
constructor(apiKey, httpClient) {
|
|
6547
6549
|
this.apiKey = apiKey;
|
|
6548
6550
|
this.httpClient = httpClient;
|
|
6549
6551
|
this.list = async () => {
|
|
6550
|
-
const
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
}
|
|
6555
|
-
throw new Error(`Invalid API key: ${decodedApiKey.error}`);
|
|
6556
|
-
}
|
|
6557
|
-
const { host, jwt } = decodedApiKey.payload;
|
|
6558
|
-
const jwtPayload = decodeJwt(jwt);
|
|
6559
|
-
if (!jwtPayload?.organization?.id) {
|
|
6560
|
-
throw new Error("Invalid API key: missing organizationId in JWT");
|
|
6561
|
-
}
|
|
6562
|
-
const organizationId = jwtPayload.organization.id;
|
|
6563
|
-
const url = `${host}/api/v0/organizations/${organizationId}/packages`;
|
|
6564
|
-
try {
|
|
6565
|
-
const response = await fetch(url, {
|
|
6566
|
-
method: "GET",
|
|
6567
|
-
headers: {
|
|
6568
|
-
"Content-Type": "application/json",
|
|
6569
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
6570
|
-
}
|
|
6571
|
-
});
|
|
6572
|
-
if (!response.ok) {
|
|
6573
|
-
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
6574
|
-
try {
|
|
6575
|
-
const errorBody = await response.json();
|
|
6576
|
-
if (errorBody && errorBody.message) {
|
|
6577
|
-
errorMsg = `${errorBody.message}`;
|
|
6578
|
-
}
|
|
6579
|
-
} catch {
|
|
6580
|
-
}
|
|
6581
|
-
const error = new Error(errorMsg);
|
|
6582
|
-
error.statusCode = response.status;
|
|
6583
|
-
throw error;
|
|
6584
|
-
}
|
|
6585
|
-
const result = await response.json();
|
|
6586
|
-
return result.packages;
|
|
6587
|
-
} catch (error) {
|
|
6588
|
-
const err = error;
|
|
6589
|
-
const code = err?.code || err?.cause?.code;
|
|
6590
|
-
if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
|
|
6591
|
-
throw new Error(
|
|
6592
|
-
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
6593
|
-
);
|
|
6594
|
-
}
|
|
6595
|
-
throw new Error(
|
|
6596
|
-
`Failed to list packages: Error: ${err?.message || JSON.stringify(error)}`
|
|
6597
|
-
);
|
|
6598
|
-
}
|
|
6552
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6553
|
+
return this.httpClient.request(
|
|
6554
|
+
`/api/v0/organizations/${organizationId}/packages`
|
|
6555
|
+
);
|
|
6599
6556
|
};
|
|
6600
|
-
this.getSummary = async ({
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
throw new Error("Invalid API key: missing organizationId in JWT");
|
|
6614
|
-
}
|
|
6615
|
-
const organizationId = jwtPayload.organization.id;
|
|
6616
|
-
const url = `${host}/api/v0/organizations/${organizationId}/packages/${encodeURIComponent(slug)}`;
|
|
6617
|
-
try {
|
|
6618
|
-
const response = await fetch(url, {
|
|
6619
|
-
method: "GET",
|
|
6620
|
-
headers: {
|
|
6621
|
-
"Content-Type": "application/json",
|
|
6622
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
6623
|
-
}
|
|
6624
|
-
});
|
|
6625
|
-
if (!response.ok) {
|
|
6626
|
-
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
6627
|
-
try {
|
|
6628
|
-
const errorBody = await response.json();
|
|
6629
|
-
if (errorBody && errorBody.message) {
|
|
6630
|
-
errorMsg = `${errorBody.message}`;
|
|
6631
|
-
}
|
|
6632
|
-
} catch {
|
|
6633
|
-
}
|
|
6634
|
-
const error = new Error(errorMsg);
|
|
6635
|
-
error.statusCode = response.status;
|
|
6636
|
-
throw error;
|
|
6637
|
-
}
|
|
6638
|
-
const result = await response.json();
|
|
6639
|
-
return result;
|
|
6640
|
-
} catch (error) {
|
|
6641
|
-
const err = error;
|
|
6642
|
-
const code = err?.code || err?.cause?.code;
|
|
6643
|
-
if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
|
|
6644
|
-
throw new Error(
|
|
6645
|
-
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
6646
|
-
);
|
|
6557
|
+
this.getSummary = async ({ slug }) => {
|
|
6558
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6559
|
+
return this.httpClient.request(
|
|
6560
|
+
`/api/v0/organizations/${organizationId}/packages/${encodeURIComponent(slug)}`
|
|
6561
|
+
);
|
|
6562
|
+
};
|
|
6563
|
+
this.create = async (command20) => {
|
|
6564
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6565
|
+
return this.httpClient.request(
|
|
6566
|
+
`/api/v0/organizations/${organizationId}/spaces/${command20.spaceId}/packages`,
|
|
6567
|
+
{
|
|
6568
|
+
method: "POST",
|
|
6569
|
+
body: command20
|
|
6647
6570
|
}
|
|
6648
|
-
|
|
6649
|
-
`Failed to get package '${slug}': Error: ${err?.message || JSON.stringify(error)}`
|
|
6650
|
-
);
|
|
6651
|
-
}
|
|
6571
|
+
);
|
|
6652
6572
|
};
|
|
6653
|
-
this.
|
|
6573
|
+
this.addArtefacts = async (command20) => {
|
|
6654
6574
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
6655
|
-
const
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6575
|
+
const { packageId, spaceId } = command20;
|
|
6576
|
+
return this.httpClient.request(
|
|
6577
|
+
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/${packageId}/add-artifacts`,
|
|
6578
|
+
{
|
|
6579
|
+
method: "POST",
|
|
6580
|
+
body: command20
|
|
6581
|
+
}
|
|
6582
|
+
);
|
|
6660
6583
|
};
|
|
6661
6584
|
}
|
|
6662
6585
|
};
|
|
6663
6586
|
|
|
6664
6587
|
// apps/cli/src/infra/repositories/DeploymentGateway.ts
|
|
6665
|
-
function decodeJwt2(jwt) {
|
|
6666
|
-
try {
|
|
6667
|
-
const parts = jwt.split(".");
|
|
6668
|
-
if (parts.length !== 3) {
|
|
6669
|
-
return null;
|
|
6670
|
-
}
|
|
6671
|
-
const payload = JSON.parse(
|
|
6672
|
-
Buffer.from(parts[1], "base64").toString("utf-8")
|
|
6673
|
-
);
|
|
6674
|
-
return payload;
|
|
6675
|
-
} catch {
|
|
6676
|
-
return null;
|
|
6677
|
-
}
|
|
6678
|
-
}
|
|
6679
|
-
function decodeApiKey2(apiKey) {
|
|
6680
|
-
if (!apiKey) {
|
|
6681
|
-
return {
|
|
6682
|
-
payload: { host: "", jwt: "" },
|
|
6683
|
-
isValid: false,
|
|
6684
|
-
error: "NOT_LOGGED_IN"
|
|
6685
|
-
};
|
|
6686
|
-
}
|
|
6687
|
-
try {
|
|
6688
|
-
const trimmedKey = apiKey.trim();
|
|
6689
|
-
const jsonString = Buffer.from(trimmedKey, "base64").toString("utf-8");
|
|
6690
|
-
const payload = JSON.parse(jsonString);
|
|
6691
|
-
if (!payload.host || typeof payload.host !== "string") {
|
|
6692
|
-
return {
|
|
6693
|
-
payload,
|
|
6694
|
-
isValid: false,
|
|
6695
|
-
error: "Invalid API key: missing or invalid host field"
|
|
6696
|
-
};
|
|
6697
|
-
}
|
|
6698
|
-
if (!payload.jwt || typeof payload.jwt !== "string") {
|
|
6699
|
-
return {
|
|
6700
|
-
payload,
|
|
6701
|
-
isValid: false,
|
|
6702
|
-
error: "Invalid API key: missing or invalid jwt field"
|
|
6703
|
-
};
|
|
6704
|
-
}
|
|
6705
|
-
return {
|
|
6706
|
-
payload,
|
|
6707
|
-
isValid: true
|
|
6708
|
-
};
|
|
6709
|
-
} catch (error) {
|
|
6710
|
-
return {
|
|
6711
|
-
payload: { host: "", jwt: "" },
|
|
6712
|
-
isValid: false,
|
|
6713
|
-
error: `Failed to decode API key: ${error}`
|
|
6714
|
-
};
|
|
6715
|
-
}
|
|
6716
|
-
}
|
|
6717
6588
|
var DeploymentGateway = class {
|
|
6718
|
-
constructor(
|
|
6719
|
-
this.
|
|
6720
|
-
this.pull = async (
|
|
6721
|
-
const
|
|
6722
|
-
if (!decodedApiKey.isValid) {
|
|
6723
|
-
if (decodedApiKey.error === "NOT_LOGGED_IN") {
|
|
6724
|
-
throw new NotLoggedInError();
|
|
6725
|
-
}
|
|
6726
|
-
throw new Error(`Invalid API key: ${decodedApiKey.error}`);
|
|
6727
|
-
}
|
|
6728
|
-
const { host, jwt } = decodedApiKey.payload;
|
|
6729
|
-
const jwtPayload = decodeJwt2(jwt);
|
|
6730
|
-
if (!jwtPayload?.organization?.id) {
|
|
6731
|
-
throw new Error("Invalid API key: missing organizationId in JWT");
|
|
6732
|
-
}
|
|
6733
|
-
const organizationId = jwtPayload.organization.id;
|
|
6589
|
+
constructor(httpClient) {
|
|
6590
|
+
this.httpClient = httpClient;
|
|
6591
|
+
this.pull = async (command20) => {
|
|
6592
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6734
6593
|
const queryParams = new URLSearchParams();
|
|
6735
|
-
if (
|
|
6736
|
-
|
|
6594
|
+
if (command20.packagesSlugs && command20.packagesSlugs.length > 0) {
|
|
6595
|
+
command20.packagesSlugs.forEach((slug) => {
|
|
6737
6596
|
queryParams.append("packageSlug", slug);
|
|
6738
6597
|
});
|
|
6739
6598
|
}
|
|
6740
|
-
if (
|
|
6741
|
-
|
|
6599
|
+
if (command20.previousPackagesSlugs && command20.previousPackagesSlugs.length > 0) {
|
|
6600
|
+
command20.previousPackagesSlugs.forEach((slug) => {
|
|
6742
6601
|
queryParams.append("previousPackageSlug", slug);
|
|
6743
6602
|
});
|
|
6744
6603
|
}
|
|
6745
|
-
if (
|
|
6746
|
-
queryParams.append("gitRemoteUrl",
|
|
6604
|
+
if (command20.gitRemoteUrl) {
|
|
6605
|
+
queryParams.append("gitRemoteUrl", command20.gitRemoteUrl);
|
|
6747
6606
|
}
|
|
6748
|
-
if (
|
|
6749
|
-
queryParams.append("gitBranch",
|
|
6607
|
+
if (command20.gitBranch) {
|
|
6608
|
+
queryParams.append("gitBranch", command20.gitBranch);
|
|
6750
6609
|
}
|
|
6751
|
-
if (
|
|
6752
|
-
queryParams.append("relativePath",
|
|
6610
|
+
if (command20.relativePath) {
|
|
6611
|
+
queryParams.append("relativePath", command20.relativePath);
|
|
6753
6612
|
}
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6758
|
-
headers: {
|
|
6759
|
-
"Content-Type": "application/json",
|
|
6760
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
6761
|
-
}
|
|
6613
|
+
if (command20.agents !== void 0) {
|
|
6614
|
+
queryParams.append("agentsConfigOverride", "true");
|
|
6615
|
+
command20.agents.forEach((agent) => {
|
|
6616
|
+
queryParams.append("agent", agent);
|
|
6762
6617
|
});
|
|
6763
|
-
if (!response.ok) {
|
|
6764
|
-
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
6765
|
-
try {
|
|
6766
|
-
const errorBody = await response.json();
|
|
6767
|
-
if (errorBody && errorBody.message) {
|
|
6768
|
-
errorMsg = `${errorBody.message}`;
|
|
6769
|
-
}
|
|
6770
|
-
} catch {
|
|
6771
|
-
}
|
|
6772
|
-
const error = new Error(errorMsg);
|
|
6773
|
-
error.statusCode = response.status;
|
|
6774
|
-
throw error;
|
|
6775
|
-
}
|
|
6776
|
-
const result = await response.json();
|
|
6777
|
-
return result;
|
|
6778
|
-
} catch (error) {
|
|
6779
|
-
const err = error;
|
|
6780
|
-
const code = err?.code || err?.cause?.code;
|
|
6781
|
-
if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
|
|
6782
|
-
throw new Error(
|
|
6783
|
-
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
6784
|
-
);
|
|
6785
|
-
}
|
|
6786
|
-
throw new Error(
|
|
6787
|
-
`Failed to fetch content: Error: ${err?.message || JSON.stringify(error)}`
|
|
6788
|
-
);
|
|
6789
6618
|
}
|
|
6619
|
+
return this.httpClient.request(
|
|
6620
|
+
`/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
|
|
6621
|
+
);
|
|
6790
6622
|
};
|
|
6791
|
-
this.notifyDistribution = async (
|
|
6792
|
-
const
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
|
|
6796
|
-
}
|
|
6797
|
-
throw new Error(`Invalid API key: ${decodedApiKey.error}`);
|
|
6798
|
-
}
|
|
6799
|
-
const { host, jwt } = decodedApiKey.payload;
|
|
6800
|
-
const jwtPayload = decodeJwt2(jwt);
|
|
6801
|
-
if (!jwtPayload?.organization?.id) {
|
|
6802
|
-
throw new Error("Invalid API key: missing organizationId in JWT");
|
|
6803
|
-
}
|
|
6804
|
-
const organizationId = jwtPayload.organization.id;
|
|
6805
|
-
const url = `${host}/api/v0/organizations/${organizationId}/deployments`;
|
|
6806
|
-
const payload = {
|
|
6807
|
-
distributedPackages: params.distributedPackages,
|
|
6808
|
-
gitRemoteUrl: params.gitRemoteUrl,
|
|
6809
|
-
gitBranch: params.gitBranch,
|
|
6810
|
-
relativePath: params.relativePath
|
|
6811
|
-
};
|
|
6812
|
-
try {
|
|
6813
|
-
const response = await fetch(url, {
|
|
6623
|
+
this.notifyDistribution = async (command20) => {
|
|
6624
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6625
|
+
return this.httpClient.request(
|
|
6626
|
+
`/api/v0/organizations/${organizationId}/deployments`,
|
|
6627
|
+
{
|
|
6814
6628
|
method: "POST",
|
|
6815
|
-
|
|
6816
|
-
"Content-Type": "application/json",
|
|
6817
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
6818
|
-
},
|
|
6819
|
-
body: JSON.stringify(payload)
|
|
6820
|
-
});
|
|
6821
|
-
if (!response.ok) {
|
|
6822
|
-
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
6823
|
-
try {
|
|
6824
|
-
const errorBody = await response.json();
|
|
6825
|
-
if (errorBody && errorBody.message) {
|
|
6826
|
-
errorMsg = `${errorBody.message}`;
|
|
6827
|
-
}
|
|
6828
|
-
} catch {
|
|
6829
|
-
}
|
|
6830
|
-
throw new Error(errorMsg);
|
|
6831
|
-
}
|
|
6832
|
-
const result = await response.json();
|
|
6833
|
-
return result;
|
|
6834
|
-
} catch (error) {
|
|
6835
|
-
const err = error;
|
|
6836
|
-
const code = err?.code || err?.cause?.code;
|
|
6837
|
-
if (code === "ECONNREFUSED" || code === "ENOTFOUND" || err?.name === "FetchError" || typeof err?.message === "string" && (err.message.includes("Failed to fetch") || err.message.includes("network") || err.message.includes("NetworkError"))) {
|
|
6838
|
-
throw new Error(
|
|
6839
|
-
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
6840
|
-
);
|
|
6629
|
+
body: command20
|
|
6841
6630
|
}
|
|
6842
|
-
|
|
6843
|
-
`Failed to notify distribution: Error: ${err?.message || JSON.stringify(error)}`
|
|
6844
|
-
);
|
|
6845
|
-
}
|
|
6631
|
+
);
|
|
6846
6632
|
};
|
|
6847
6633
|
}
|
|
6848
6634
|
};
|
|
@@ -6856,10 +6642,10 @@ var PackmindGateway = class {
|
|
|
6856
6642
|
this.mcp = new McpGateway(this.httpClient);
|
|
6857
6643
|
this.spaces = new SpacesGateway(this.httpClient);
|
|
6858
6644
|
this.skills = new SkillsGateway(this.httpClient);
|
|
6859
|
-
this.commands = new CommandsGateway(this.httpClient
|
|
6645
|
+
this.commands = new CommandsGateway(this.httpClient);
|
|
6860
6646
|
this.standards = new StandardsGateway(this.httpClient, this.spaces);
|
|
6861
6647
|
this.packages = new PackagesGateway(apiKey, this.httpClient);
|
|
6862
|
-
this.deployment = new DeploymentGateway(
|
|
6648
|
+
this.deployment = new DeploymentGateway(this.httpClient);
|
|
6863
6649
|
}
|
|
6864
6650
|
};
|
|
6865
6651
|
|
|
@@ -8603,8 +8389,8 @@ var ExecuteLinterProgramsUseCase = class {
|
|
|
8603
8389
|
this.linterAstAdapter = linterAstAdapter;
|
|
8604
8390
|
this.logger = logger2;
|
|
8605
8391
|
}
|
|
8606
|
-
async execute(
|
|
8607
|
-
const { filePath, fileContent, language, programs } =
|
|
8392
|
+
async execute(command20) {
|
|
8393
|
+
const { filePath, fileContent, language, programs } = command20;
|
|
8608
8394
|
if (programs.length === 0) {
|
|
8609
8395
|
return {
|
|
8610
8396
|
file: filePath,
|
|
@@ -9281,8 +9067,8 @@ var InstallPackagesUseCase = class {
|
|
|
9281
9067
|
constructor(packmindGateway) {
|
|
9282
9068
|
this.packmindGateway = packmindGateway;
|
|
9283
9069
|
}
|
|
9284
|
-
async execute(
|
|
9285
|
-
const baseDirectory =
|
|
9070
|
+
async execute(command20) {
|
|
9071
|
+
const baseDirectory = command20.baseDirectory || process.cwd();
|
|
9286
9072
|
const result = {
|
|
9287
9073
|
filesCreated: 0,
|
|
9288
9074
|
filesUpdated: 0,
|
|
@@ -9294,14 +9080,18 @@ var InstallPackagesUseCase = class {
|
|
|
9294
9080
|
skillDirectoriesDeleted: 0
|
|
9295
9081
|
};
|
|
9296
9082
|
const response = await this.packmindGateway.deployment.pull({
|
|
9297
|
-
packagesSlugs:
|
|
9298
|
-
previousPackagesSlugs:
|
|
9299
|
-
gitRemoteUrl:
|
|
9300
|
-
gitBranch:
|
|
9301
|
-
relativePath:
|
|
9083
|
+
packagesSlugs: command20.packagesSlugs,
|
|
9084
|
+
previousPackagesSlugs: command20.previousPackagesSlugs,
|
|
9085
|
+
gitRemoteUrl: command20.gitRemoteUrl,
|
|
9086
|
+
gitBranch: command20.gitBranch,
|
|
9087
|
+
relativePath: command20.relativePath,
|
|
9088
|
+
agents: command20.agents
|
|
9302
9089
|
});
|
|
9090
|
+
const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
|
|
9091
|
+
(file) => file.path !== "packmind.json"
|
|
9092
|
+
);
|
|
9303
9093
|
const uniqueFilesMap = /* @__PURE__ */ new Map();
|
|
9304
|
-
for (const file of
|
|
9094
|
+
for (const file of filteredCreateOrUpdate) {
|
|
9305
9095
|
uniqueFilesMap.set(file.path, file);
|
|
9306
9096
|
}
|
|
9307
9097
|
const uniqueFiles = Array.from(uniqueFilesMap.values());
|
|
@@ -9361,7 +9151,8 @@ var InstallPackagesUseCase = class {
|
|
|
9361
9151
|
fullPath,
|
|
9362
9152
|
file.sections,
|
|
9363
9153
|
fileExists,
|
|
9364
|
-
result
|
|
9154
|
+
result,
|
|
9155
|
+
baseDirectory
|
|
9365
9156
|
);
|
|
9366
9157
|
}
|
|
9367
9158
|
}
|
|
@@ -9398,7 +9189,7 @@ var InstallPackagesUseCase = class {
|
|
|
9398
9189
|
result.filesCreated++;
|
|
9399
9190
|
}
|
|
9400
9191
|
}
|
|
9401
|
-
async handleSectionsUpdate(fullPath, sections, fileExists, result) {
|
|
9192
|
+
async handleSectionsUpdate(fullPath, sections, fileExists, result, baseDirectory) {
|
|
9402
9193
|
let currentContent = "";
|
|
9403
9194
|
if (fileExists) {
|
|
9404
9195
|
currentContent = await fs4.readFile(fullPath, "utf-8");
|
|
@@ -9411,6 +9202,7 @@ var InstallPackagesUseCase = class {
|
|
|
9411
9202
|
if (this.isEffectivelyEmpty(mergedContent) && fileExists) {
|
|
9412
9203
|
await fs4.unlink(fullPath);
|
|
9413
9204
|
result.filesDeleted++;
|
|
9205
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
9414
9206
|
} else {
|
|
9415
9207
|
await fs4.writeFile(fullPath, mergedContent, "utf-8");
|
|
9416
9208
|
if (fileExists) {
|
|
@@ -9427,9 +9219,11 @@ var InstallPackagesUseCase = class {
|
|
|
9427
9219
|
if (stat4?.isDirectory()) {
|
|
9428
9220
|
await fs4.rm(fullPath, { recursive: true, force: true });
|
|
9429
9221
|
result.filesDeleted++;
|
|
9222
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
9430
9223
|
} else if (stat4?.isFile()) {
|
|
9431
9224
|
await fs4.unlink(fullPath);
|
|
9432
9225
|
result.filesDeleted++;
|
|
9226
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
9433
9227
|
}
|
|
9434
9228
|
}
|
|
9435
9229
|
async fileExists(filePath) {
|
|
@@ -9509,6 +9303,7 @@ ${endMarker}`;
|
|
|
9509
9303
|
const fileCount = await this.countFilesInDirectory(fullPath);
|
|
9510
9304
|
await fs4.rm(fullPath, { recursive: true, force: true });
|
|
9511
9305
|
deletedFilesCount += fileCount;
|
|
9306
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
9512
9307
|
} catch {
|
|
9513
9308
|
}
|
|
9514
9309
|
}
|
|
@@ -9530,26 +9325,60 @@ ${endMarker}`;
|
|
|
9530
9325
|
}
|
|
9531
9326
|
return count;
|
|
9532
9327
|
}
|
|
9328
|
+
/**
|
|
9329
|
+
* Checks if a directory is empty (has no entries).
|
|
9330
|
+
*/
|
|
9331
|
+
async isDirectoryEmpty(dirPath) {
|
|
9332
|
+
try {
|
|
9333
|
+
const entries = await fs4.readdir(dirPath);
|
|
9334
|
+
return entries.length === 0;
|
|
9335
|
+
} catch {
|
|
9336
|
+
return false;
|
|
9337
|
+
}
|
|
9338
|
+
}
|
|
9339
|
+
/**
|
|
9340
|
+
* Removes empty parent directories from fullPath up to (but not including) baseDirectory.
|
|
9341
|
+
* Stops when encountering a non-empty directory or reaching baseDirectory.
|
|
9342
|
+
*/
|
|
9343
|
+
async removeEmptyParentDirectories(fullPath, baseDirectory) {
|
|
9344
|
+
const normalizedBase = path5.resolve(baseDirectory);
|
|
9345
|
+
let currentDir = path5.dirname(path5.resolve(fullPath));
|
|
9346
|
+
while (currentDir.startsWith(normalizedBase + path5.sep) && currentDir !== normalizedBase) {
|
|
9347
|
+
const isEmpty = await this.isDirectoryEmpty(currentDir);
|
|
9348
|
+
if (!isEmpty) break;
|
|
9349
|
+
try {
|
|
9350
|
+
await fs4.rmdir(currentDir);
|
|
9351
|
+
} catch {
|
|
9352
|
+
break;
|
|
9353
|
+
}
|
|
9354
|
+
currentDir = path5.dirname(currentDir);
|
|
9355
|
+
}
|
|
9356
|
+
}
|
|
9533
9357
|
};
|
|
9534
9358
|
|
|
9535
9359
|
// apps/cli/src/application/useCases/InstallDefaultSkillsUseCase.ts
|
|
9536
9360
|
var fs5 = __toESM(require("fs/promises"));
|
|
9537
9361
|
var path6 = __toESM(require("path"));
|
|
9538
9362
|
var InstallDefaultSkillsUseCase = class {
|
|
9539
|
-
constructor(
|
|
9540
|
-
this.
|
|
9363
|
+
constructor(repositories) {
|
|
9364
|
+
this.repositories = repositories;
|
|
9541
9365
|
}
|
|
9542
|
-
async execute(
|
|
9543
|
-
const baseDirectory =
|
|
9366
|
+
async execute(command20) {
|
|
9367
|
+
const baseDirectory = command20.baseDirectory || process.cwd();
|
|
9544
9368
|
const result = {
|
|
9545
9369
|
filesCreated: 0,
|
|
9546
9370
|
filesUpdated: 0,
|
|
9547
9371
|
errors: []
|
|
9548
9372
|
};
|
|
9549
|
-
const
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9373
|
+
const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
|
|
9374
|
+
const agents = config?.agents;
|
|
9375
|
+
const response = await this.repositories.packmindGateway.skills.getDefaults(
|
|
9376
|
+
{
|
|
9377
|
+
cliVersion: command20.cliVersion,
|
|
9378
|
+
includeBeta: command20.includeBeta,
|
|
9379
|
+
agents
|
|
9380
|
+
}
|
|
9381
|
+
);
|
|
9553
9382
|
try {
|
|
9554
9383
|
for (const file of response.fileUpdates.createOrUpdate) {
|
|
9555
9384
|
try {
|
|
@@ -9601,7 +9430,8 @@ var ListPackagesUseCase = class {
|
|
|
9601
9430
|
this.packmindGateway = packmindGateway;
|
|
9602
9431
|
}
|
|
9603
9432
|
async execute() {
|
|
9604
|
-
|
|
9433
|
+
const listPackagesResponse = await this.packmindGateway.packages.list({});
|
|
9434
|
+
return listPackagesResponse.packages;
|
|
9605
9435
|
}
|
|
9606
9436
|
};
|
|
9607
9437
|
|
|
@@ -9610,8 +9440,8 @@ var GetPackageSummaryUseCase = class {
|
|
|
9610
9440
|
constructor(gateway) {
|
|
9611
9441
|
this.gateway = gateway;
|
|
9612
9442
|
}
|
|
9613
|
-
async execute(
|
|
9614
|
-
return this.gateway.packages.getSummary(
|
|
9443
|
+
async execute(command20) {
|
|
9444
|
+
return this.gateway.packages.getSummary(command20);
|
|
9615
9445
|
}
|
|
9616
9446
|
};
|
|
9617
9447
|
|
|
@@ -9621,7 +9451,7 @@ var import_open = __toESM(require("open"));
|
|
|
9621
9451
|
var readline = __toESM(require("readline"));
|
|
9622
9452
|
|
|
9623
9453
|
// apps/cli/src/infra/utils/credentials/decodeApiKey.ts
|
|
9624
|
-
function
|
|
9454
|
+
function decodeApiKey(apiKey) {
|
|
9625
9455
|
try {
|
|
9626
9456
|
const jsonString = Buffer.from(apiKey.trim(), "base64").toString("utf-8");
|
|
9627
9457
|
const apiKeyPayload = JSON.parse(jsonString);
|
|
@@ -9655,7 +9485,7 @@ var EnvCredentialsProvider = class {
|
|
|
9655
9485
|
if (!apiKey) {
|
|
9656
9486
|
return null;
|
|
9657
9487
|
}
|
|
9658
|
-
const decoded =
|
|
9488
|
+
const decoded = decodeApiKey(apiKey);
|
|
9659
9489
|
if (!decoded) {
|
|
9660
9490
|
return null;
|
|
9661
9491
|
}
|
|
@@ -9707,7 +9537,7 @@ var FileCredentialsProvider = class {
|
|
|
9707
9537
|
if (!credentials.apiKey) {
|
|
9708
9538
|
return null;
|
|
9709
9539
|
}
|
|
9710
|
-
const decoded =
|
|
9540
|
+
const decoded = decodeApiKey(credentials.apiKey);
|
|
9711
9541
|
if (!decoded) {
|
|
9712
9542
|
return null;
|
|
9713
9543
|
}
|
|
@@ -9802,10 +9632,10 @@ async function defaultPromptForCode() {
|
|
|
9802
9632
|
input: process.stdin,
|
|
9803
9633
|
output: process.stdout
|
|
9804
9634
|
});
|
|
9805
|
-
return new Promise((
|
|
9635
|
+
return new Promise((resolve7) => {
|
|
9806
9636
|
rl.question("Enter the login code from the browser: ", (answer) => {
|
|
9807
9637
|
rl.close();
|
|
9808
|
-
|
|
9638
|
+
resolve7(answer.trim());
|
|
9809
9639
|
});
|
|
9810
9640
|
});
|
|
9811
9641
|
}
|
|
@@ -9839,7 +9669,7 @@ async function defaultExchangeCodeForApiKey(code, host) {
|
|
|
9839
9669
|
return await response.json();
|
|
9840
9670
|
}
|
|
9841
9671
|
function defaultStartCallbackServer() {
|
|
9842
|
-
return new Promise((
|
|
9672
|
+
return new Promise((resolve7, reject) => {
|
|
9843
9673
|
let timeoutId = null;
|
|
9844
9674
|
const server = http.createServer((req, res) => {
|
|
9845
9675
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -9852,7 +9682,7 @@ function defaultStartCallbackServer() {
|
|
|
9852
9682
|
if (timeoutId) {
|
|
9853
9683
|
clearTimeout(timeoutId);
|
|
9854
9684
|
}
|
|
9855
|
-
|
|
9685
|
+
resolve7(code);
|
|
9856
9686
|
setImmediate(() => {
|
|
9857
9687
|
server.close();
|
|
9858
9688
|
});
|
|
@@ -9890,8 +9720,8 @@ var LoginUseCase = class {
|
|
|
9890
9720
|
startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
|
|
9891
9721
|
};
|
|
9892
9722
|
}
|
|
9893
|
-
async execute(
|
|
9894
|
-
const { host, code: providedCode } =
|
|
9723
|
+
async execute(command20) {
|
|
9724
|
+
const { host, code: providedCode } = command20;
|
|
9895
9725
|
let code;
|
|
9896
9726
|
if (providedCode) {
|
|
9897
9727
|
code = providedCode;
|
|
@@ -9929,8 +9759,8 @@ var LogoutUseCase = class {
|
|
|
9929
9759
|
constructor(deps) {
|
|
9930
9760
|
this.deps = {
|
|
9931
9761
|
getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
|
|
9932
|
-
fileExists: deps?.fileExists ?? ((
|
|
9933
|
-
deleteFile: deps?.deleteFile ?? ((
|
|
9762
|
+
fileExists: deps?.fileExists ?? ((path14) => fs7.existsSync(path14)),
|
|
9763
|
+
deleteFile: deps?.deleteFile ?? ((path14) => fs7.unlinkSync(path14)),
|
|
9934
9764
|
hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
|
|
9935
9765
|
};
|
|
9936
9766
|
}
|
|
@@ -9990,8 +9820,8 @@ var SetupMcpUseCase = class {
|
|
|
9990
9820
|
constructor(deps) {
|
|
9991
9821
|
this.deps = deps;
|
|
9992
9822
|
}
|
|
9993
|
-
async execute(
|
|
9994
|
-
const { agentTypes } =
|
|
9823
|
+
async execute(command20) {
|
|
9824
|
+
const { agentTypes } = command20;
|
|
9995
9825
|
const [tokenResult, urlResult] = await Promise.all([
|
|
9996
9826
|
this.deps.gateway.mcp.getToken({}),
|
|
9997
9827
|
this.deps.gateway.mcp.getUrl({})
|
|
@@ -10062,9 +9892,9 @@ var McpConfigService = class {
|
|
|
10062
9892
|
return JSON.stringify(mcpConfig, null, 2);
|
|
10063
9893
|
}
|
|
10064
9894
|
installClaudeMcp(config) {
|
|
10065
|
-
const
|
|
9895
|
+
const command20 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
|
|
10066
9896
|
try {
|
|
10067
|
-
(0, import_child_process2.execSync)(
|
|
9897
|
+
(0, import_child_process2.execSync)(command20, { stdio: "pipe" });
|
|
10068
9898
|
return { success: true };
|
|
10069
9899
|
} catch (error) {
|
|
10070
9900
|
const execError = error;
|
|
@@ -10209,12 +10039,11 @@ var ConfigFileRepository = class {
|
|
|
10209
10039
|
];
|
|
10210
10040
|
}
|
|
10211
10041
|
async writeConfig(baseDirectory, config) {
|
|
10212
|
-
const configPath =
|
|
10213
|
-
|
|
10214
|
-
await fs9.writeFile(configPath, configContent, "utf-8");
|
|
10042
|
+
const configPath = this.getConfigPath(baseDirectory);
|
|
10043
|
+
await this.writeConfigToPath(configPath, config);
|
|
10215
10044
|
}
|
|
10216
10045
|
async configExists(baseDirectory) {
|
|
10217
|
-
const configPath =
|
|
10046
|
+
const configPath = this.getConfigPath(baseDirectory);
|
|
10218
10047
|
try {
|
|
10219
10048
|
await fs9.access(configPath);
|
|
10220
10049
|
return true;
|
|
@@ -10223,15 +10052,29 @@ var ConfigFileRepository = class {
|
|
|
10223
10052
|
}
|
|
10224
10053
|
}
|
|
10225
10054
|
async readConfig(baseDirectory) {
|
|
10226
|
-
const configPath =
|
|
10055
|
+
const configPath = this.getConfigPath(baseDirectory);
|
|
10227
10056
|
try {
|
|
10228
10057
|
const configContent = await fs9.readFile(configPath, "utf-8");
|
|
10229
|
-
const
|
|
10230
|
-
if (!
|
|
10058
|
+
const rawConfig = JSON.parse(configContent);
|
|
10059
|
+
if (!rawConfig.packages || typeof rawConfig.packages !== "object") {
|
|
10231
10060
|
throw new Error(
|
|
10232
10061
|
"Invalid packmind.json structure. Expected { packages: { ... } }"
|
|
10233
10062
|
);
|
|
10234
10063
|
}
|
|
10064
|
+
const { validAgents, invalidAgents } = validateAgentsWithWarnings(
|
|
10065
|
+
rawConfig.agents
|
|
10066
|
+
);
|
|
10067
|
+
if (invalidAgents.length > 0) {
|
|
10068
|
+
logWarningConsole(
|
|
10069
|
+
`Invalid agent(s) in ${configPath}: ${invalidAgents.join(", ")}. Valid agents are: packmind, junie, claude, cursor, copilot, agents_md, gitlab_duo, continue`
|
|
10070
|
+
);
|
|
10071
|
+
}
|
|
10072
|
+
const config = {
|
|
10073
|
+
packages: rawConfig.packages
|
|
10074
|
+
};
|
|
10075
|
+
if (validAgents !== null) {
|
|
10076
|
+
config.agents = validAgents;
|
|
10077
|
+
}
|
|
10235
10078
|
return config;
|
|
10236
10079
|
} catch (error) {
|
|
10237
10080
|
if (error.code === "ENOENT") {
|
|
@@ -10244,46 +10087,56 @@ var ConfigFileRepository = class {
|
|
|
10244
10087
|
return null;
|
|
10245
10088
|
}
|
|
10246
10089
|
}
|
|
10090
|
+
getConfigPath(directory) {
|
|
10091
|
+
return path9.join(directory, this.CONFIG_FILENAME);
|
|
10092
|
+
}
|
|
10093
|
+
async writeConfigToPath(configPath, config) {
|
|
10094
|
+
const configContent = JSON.stringify(config, null, 2) + "\n";
|
|
10095
|
+
await fs9.writeFile(configPath, configContent, "utf-8");
|
|
10096
|
+
}
|
|
10247
10097
|
/**
|
|
10248
10098
|
* Recursively finds all directories containing packmind.json in descendant folders.
|
|
10249
10099
|
* Excludes common build/dependency directories (node_modules, .git, dist, etc.)
|
|
10250
|
-
*
|
|
10251
|
-
* @param directory - The root directory to search from
|
|
10252
|
-
* @returns Array of directory paths that contain a packmind.json file
|
|
10253
10100
|
*/
|
|
10254
10101
|
async findDescendantConfigs(directory) {
|
|
10255
10102
|
const normalizedDir = normalizePath(path9.resolve(directory));
|
|
10103
|
+
return this.searchDescendantsRecursively(normalizedDir);
|
|
10104
|
+
}
|
|
10105
|
+
async searchDescendantsRecursively(currentDir) {
|
|
10106
|
+
const entries = await this.tryReadDirectory(currentDir);
|
|
10107
|
+
if (!entries) {
|
|
10108
|
+
return [];
|
|
10109
|
+
}
|
|
10256
10110
|
const results = [];
|
|
10257
|
-
const
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
entries = await fs9.readdir(currentDir, { withFileTypes: true });
|
|
10261
|
-
} catch {
|
|
10262
|
-
return;
|
|
10111
|
+
for (const entry of entries) {
|
|
10112
|
+
if (!entry.isDirectory() || this.isExcludedDirectory(entry.name)) {
|
|
10113
|
+
continue;
|
|
10263
10114
|
}
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
if (this.EXCLUDED_DIRECTORIES.includes(entry.name)) {
|
|
10269
|
-
continue;
|
|
10270
|
-
}
|
|
10271
|
-
const entryPath = normalizePath(path9.join(currentDir, entry.name));
|
|
10272
|
-
const config = await this.readConfig(entryPath);
|
|
10273
|
-
if (config) {
|
|
10274
|
-
results.push(entryPath);
|
|
10275
|
-
}
|
|
10276
|
-
await searchRecursively(entryPath);
|
|
10115
|
+
const entryPath = normalizePath(path9.join(currentDir, entry.name));
|
|
10116
|
+
const config = await this.readConfig(entryPath);
|
|
10117
|
+
if (config) {
|
|
10118
|
+
results.push(entryPath);
|
|
10277
10119
|
}
|
|
10278
|
-
|
|
10279
|
-
|
|
10120
|
+
const nestedResults = await this.searchDescendantsRecursively(entryPath);
|
|
10121
|
+
results.push(...nestedResults);
|
|
10122
|
+
}
|
|
10280
10123
|
return results;
|
|
10281
10124
|
}
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10125
|
+
async tryReadDirectory(directory) {
|
|
10126
|
+
try {
|
|
10127
|
+
return await fs9.readdir(directory, { withFileTypes: true });
|
|
10128
|
+
} catch {
|
|
10129
|
+
return null;
|
|
10130
|
+
}
|
|
10131
|
+
}
|
|
10132
|
+
isExcludedDirectory(name) {
|
|
10133
|
+
return this.EXCLUDED_DIRECTORIES.includes(name);
|
|
10134
|
+
}
|
|
10135
|
+
/**
|
|
10136
|
+
* Reads all packmind.json files from startDirectory up to stopDirectory (inclusive)
|
|
10137
|
+
* and merges their package configurations.
|
|
10138
|
+
*
|
|
10139
|
+
* @param startDirectory - Directory to start searching from (typically the lint target)
|
|
10287
10140
|
* @param stopDirectory - Directory to stop searching at (typically git repo root), or null to walk to filesystem root
|
|
10288
10141
|
* @returns Merged configuration from all found packmind.json files
|
|
10289
10142
|
*/
|
|
@@ -10327,28 +10180,33 @@ var ConfigFileRepository = class {
|
|
|
10327
10180
|
/**
|
|
10328
10181
|
* Finds all packmind.json files in the tree (both ancestors and descendants)
|
|
10329
10182
|
* and returns each config with its target path.
|
|
10330
|
-
*
|
|
10331
|
-
* @param startDirectory - Directory to start searching from (typically the lint target)
|
|
10332
|
-
* @param stopDirectory - Directory to stop ancestor search at (typically git repo root), also used as base for descendants search
|
|
10333
|
-
* @returns All configs found with their target paths
|
|
10334
10183
|
*/
|
|
10335
10184
|
async findAllConfigsInTree(startDirectory, stopDirectory) {
|
|
10336
10185
|
const normalizedStart = normalizePath(path9.resolve(startDirectory));
|
|
10337
10186
|
const normalizedStop = stopDirectory ? normalizePath(path9.resolve(stopDirectory)) : null;
|
|
10338
10187
|
const basePath = normalizedStop ?? normalizedStart;
|
|
10188
|
+
const searchRoot = normalizedStop ?? normalizedStart;
|
|
10339
10189
|
const configsMap = /* @__PURE__ */ new Map();
|
|
10340
|
-
|
|
10190
|
+
await this.collectAncestorConfigs(
|
|
10191
|
+
normalizedStart,
|
|
10192
|
+
normalizedStop,
|
|
10193
|
+
basePath,
|
|
10194
|
+
configsMap
|
|
10195
|
+
);
|
|
10196
|
+
await this.collectDescendantConfigs(searchRoot, basePath, configsMap);
|
|
10197
|
+
await this.collectRootConfigIfMissing(searchRoot, basePath, configsMap);
|
|
10198
|
+
const configs = Array.from(configsMap.values());
|
|
10199
|
+
return {
|
|
10200
|
+
configs,
|
|
10201
|
+
hasConfigs: configs.length > 0,
|
|
10202
|
+
basePath
|
|
10203
|
+
};
|
|
10204
|
+
}
|
|
10205
|
+
async collectAncestorConfigs(startDir, stopDir, basePath, configsMap) {
|
|
10206
|
+
let currentDir = startDir;
|
|
10341
10207
|
while (true) {
|
|
10342
|
-
|
|
10343
|
-
if (
|
|
10344
|
-
const targetPath = this.computeRelativeTargetPath(currentDir, basePath);
|
|
10345
|
-
configsMap.set(currentDir, {
|
|
10346
|
-
targetPath,
|
|
10347
|
-
absoluteTargetPath: currentDir,
|
|
10348
|
-
packages: config.packages
|
|
10349
|
-
});
|
|
10350
|
-
}
|
|
10351
|
-
if (normalizedStop !== null && currentDir === normalizedStop) {
|
|
10208
|
+
await this.addConfigToMap(currentDir, basePath, configsMap);
|
|
10209
|
+
if (stopDir !== null && currentDir === stopDir) {
|
|
10352
10210
|
break;
|
|
10353
10211
|
}
|
|
10354
10212
|
const parentDir = normalizePath(path9.dirname(currentDir));
|
|
@@ -10357,42 +10215,34 @@ var ConfigFileRepository = class {
|
|
|
10357
10215
|
}
|
|
10358
10216
|
currentDir = parentDir;
|
|
10359
10217
|
}
|
|
10360
|
-
|
|
10218
|
+
}
|
|
10219
|
+
async collectDescendantConfigs(searchRoot, basePath, configsMap) {
|
|
10361
10220
|
const descendantDirs = await this.findDescendantConfigs(searchRoot);
|
|
10362
10221
|
for (const descendantDir of descendantDirs) {
|
|
10363
10222
|
const normalizedDescendantDir = normalizePath(descendantDir);
|
|
10364
10223
|
if (configsMap.has(normalizedDescendantDir)) {
|
|
10365
10224
|
continue;
|
|
10366
10225
|
}
|
|
10367
|
-
|
|
10368
|
-
if (config) {
|
|
10369
|
-
const targetPath = this.computeRelativeTargetPath(
|
|
10370
|
-
normalizedDescendantDir,
|
|
10371
|
-
basePath
|
|
10372
|
-
);
|
|
10373
|
-
configsMap.set(normalizedDescendantDir, {
|
|
10374
|
-
targetPath,
|
|
10375
|
-
absoluteTargetPath: normalizedDescendantDir,
|
|
10376
|
-
packages: config.packages
|
|
10377
|
-
});
|
|
10378
|
-
}
|
|
10226
|
+
await this.addConfigToMap(normalizedDescendantDir, basePath, configsMap);
|
|
10379
10227
|
}
|
|
10228
|
+
}
|
|
10229
|
+
async collectRootConfigIfMissing(searchRoot, basePath, configsMap) {
|
|
10380
10230
|
if (!configsMap.has(searchRoot)) {
|
|
10381
|
-
|
|
10382
|
-
if (rootConfig) {
|
|
10383
|
-
configsMap.set(searchRoot, {
|
|
10384
|
-
targetPath: "/",
|
|
10385
|
-
absoluteTargetPath: searchRoot,
|
|
10386
|
-
packages: rootConfig.packages
|
|
10387
|
-
});
|
|
10388
|
-
}
|
|
10231
|
+
await this.addConfigToMap(searchRoot, basePath, configsMap);
|
|
10389
10232
|
}
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
}
|
|
10233
|
+
}
|
|
10234
|
+
async addConfigToMap(directory, basePath, configsMap) {
|
|
10235
|
+
const config = await this.readConfig(directory);
|
|
10236
|
+
if (!config) {
|
|
10237
|
+
return;
|
|
10238
|
+
}
|
|
10239
|
+
const targetPath = this.computeRelativeTargetPath(directory, basePath);
|
|
10240
|
+
configsMap.set(directory, {
|
|
10241
|
+
targetPath,
|
|
10242
|
+
absoluteTargetPath: directory,
|
|
10243
|
+
packages: config.packages,
|
|
10244
|
+
agents: config.agents
|
|
10245
|
+
});
|
|
10396
10246
|
}
|
|
10397
10247
|
computeRelativeTargetPath(absolutePath, basePath) {
|
|
10398
10248
|
const normalizedAbsolute = normalizePath(absolutePath);
|
|
@@ -10403,6 +10253,91 @@ var ConfigFileRepository = class {
|
|
|
10403
10253
|
const relativePath = normalizedAbsolute.substring(normalizedBase.length);
|
|
10404
10254
|
return relativePath.startsWith("/") ? relativePath : "/" + relativePath;
|
|
10405
10255
|
}
|
|
10256
|
+
/**
|
|
10257
|
+
* Adds new packages to an existing packmind.json while preserving property order.
|
|
10258
|
+
* If the file doesn't exist, creates a new one with default order (packages first).
|
|
10259
|
+
*
|
|
10260
|
+
* Uses JavaScript's built-in property order preservation: JSON.parse() preserves
|
|
10261
|
+
* insertion order for string keys, and mutating the existing object maintains
|
|
10262
|
+
* that order when JSON.stringify() outputs it.
|
|
10263
|
+
*/
|
|
10264
|
+
async addPackagesToConfig(baseDirectory, newPackageSlugs) {
|
|
10265
|
+
const configPath = this.getConfigPath(baseDirectory);
|
|
10266
|
+
const rawContent = await this.tryReadFile(configPath);
|
|
10267
|
+
if (!rawContent) {
|
|
10268
|
+
const newConfig = this.createConfigWithPackages(newPackageSlugs);
|
|
10269
|
+
await this.writeConfigToPath(configPath, newConfig);
|
|
10270
|
+
return;
|
|
10271
|
+
}
|
|
10272
|
+
let parsed;
|
|
10273
|
+
try {
|
|
10274
|
+
parsed = JSON.parse(rawContent);
|
|
10275
|
+
} catch {
|
|
10276
|
+
const newConfig = this.createConfigWithPackages(newPackageSlugs);
|
|
10277
|
+
await this.writeConfigToPath(configPath, newConfig);
|
|
10278
|
+
return;
|
|
10279
|
+
}
|
|
10280
|
+
if (!parsed.packages || typeof parsed.packages !== "object") {
|
|
10281
|
+
parsed.packages = {};
|
|
10282
|
+
}
|
|
10283
|
+
const packages = parsed.packages;
|
|
10284
|
+
for (const slug of newPackageSlugs) {
|
|
10285
|
+
if (!(slug in packages)) {
|
|
10286
|
+
packages[slug] = "*";
|
|
10287
|
+
}
|
|
10288
|
+
}
|
|
10289
|
+
await this.writeConfigToPath(configPath, parsed);
|
|
10290
|
+
}
|
|
10291
|
+
/**
|
|
10292
|
+
* Updates a specific field in packmind.json while preserving property order.
|
|
10293
|
+
* If the file doesn't exist, creates a new one with default packages and the field.
|
|
10294
|
+
*/
|
|
10295
|
+
async updateConfig(baseDirectory, field, value) {
|
|
10296
|
+
const configPath = this.getConfigPath(baseDirectory);
|
|
10297
|
+
const rawContent = await this.tryReadFile(configPath);
|
|
10298
|
+
if (!rawContent) {
|
|
10299
|
+
const newConfig = { packages: {}, [field]: value };
|
|
10300
|
+
await this.writeConfigToPath(configPath, newConfig);
|
|
10301
|
+
return;
|
|
10302
|
+
}
|
|
10303
|
+
let parsed;
|
|
10304
|
+
try {
|
|
10305
|
+
parsed = JSON.parse(rawContent);
|
|
10306
|
+
} catch {
|
|
10307
|
+
const newConfig = { packages: {}, [field]: value };
|
|
10308
|
+
await this.writeConfigToPath(configPath, newConfig);
|
|
10309
|
+
return;
|
|
10310
|
+
}
|
|
10311
|
+
if (!parsed.packages || typeof parsed.packages !== "object") {
|
|
10312
|
+
parsed.packages = {};
|
|
10313
|
+
}
|
|
10314
|
+
parsed[field] = value;
|
|
10315
|
+
await this.writeConfigToPath(configPath, parsed);
|
|
10316
|
+
}
|
|
10317
|
+
/**
|
|
10318
|
+
* Updates the agents configuration in packmind.json.
|
|
10319
|
+
* Convenience wrapper around updateConfig for the agents field.
|
|
10320
|
+
*/
|
|
10321
|
+
async updateAgentsConfig(baseDirectory, agents) {
|
|
10322
|
+
return this.updateConfig(baseDirectory, "agents", agents);
|
|
10323
|
+
}
|
|
10324
|
+
async tryReadFile(filePath) {
|
|
10325
|
+
try {
|
|
10326
|
+
return await fs9.readFile(filePath, "utf-8");
|
|
10327
|
+
} catch (error) {
|
|
10328
|
+
if (error.code === "ENOENT") {
|
|
10329
|
+
return null;
|
|
10330
|
+
}
|
|
10331
|
+
throw error;
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
createConfigWithPackages(slugs) {
|
|
10335
|
+
const packages = {};
|
|
10336
|
+
for (const slug of slugs) {
|
|
10337
|
+
packages[slug] = "*";
|
|
10338
|
+
}
|
|
10339
|
+
return { packages };
|
|
10340
|
+
}
|
|
10406
10341
|
};
|
|
10407
10342
|
|
|
10408
10343
|
// apps/cli/src/application/useCases/ListStandardsUseCase.ts
|
|
@@ -10411,7 +10346,11 @@ var ListStandardsUseCase = class {
|
|
|
10411
10346
|
this.packmindGateway = packmindGateway;
|
|
10412
10347
|
}
|
|
10413
10348
|
async execute() {
|
|
10414
|
-
|
|
10349
|
+
const globalSpace = await this.packmindGateway.spaces.getGlobal();
|
|
10350
|
+
const listStandardsResponse = await this.packmindGateway.standards.list({
|
|
10351
|
+
spaceId: globalSpace.id
|
|
10352
|
+
});
|
|
10353
|
+
return listStandardsResponse.standards;
|
|
10415
10354
|
}
|
|
10416
10355
|
};
|
|
10417
10356
|
|
|
@@ -10421,7 +10360,11 @@ var ListCommandsUseCase = class {
|
|
|
10421
10360
|
this.packmindGateway = packmindGateway;
|
|
10422
10361
|
}
|
|
10423
10362
|
async execute() {
|
|
10424
|
-
|
|
10363
|
+
const space = await this.packmindGateway.spaces.getGlobal();
|
|
10364
|
+
const listCommandsResponse = await this.packmindGateway.commands.list({
|
|
10365
|
+
spaceId: space.id
|
|
10366
|
+
});
|
|
10367
|
+
return listCommandsResponse.recipes;
|
|
10425
10368
|
}
|
|
10426
10369
|
};
|
|
10427
10370
|
|
|
@@ -10582,8 +10525,8 @@ var UploadSkillUseCase = class {
|
|
|
10582
10525
|
constructor(deps) {
|
|
10583
10526
|
this.deps = deps;
|
|
10584
10527
|
}
|
|
10585
|
-
async execute(
|
|
10586
|
-
const files = await readSkillDirectory(
|
|
10528
|
+
async execute(command20) {
|
|
10529
|
+
const files = await readSkillDirectory(command20.skillPath);
|
|
10587
10530
|
if (!files.find((f) => f.relativePath === "SKILL.md")) {
|
|
10588
10531
|
throw new Error("SKILL.md not found in skill directory");
|
|
10589
10532
|
}
|
|
@@ -10652,9 +10595,7 @@ var PackmindCliHexaFactory = class {
|
|
|
10652
10595
|
installPackages: new InstallPackagesUseCase(
|
|
10653
10596
|
this.repositories.packmindGateway
|
|
10654
10597
|
),
|
|
10655
|
-
installDefaultSkills: new InstallDefaultSkillsUseCase(
|
|
10656
|
-
this.repositories.packmindGateway
|
|
10657
|
-
),
|
|
10598
|
+
installDefaultSkills: new InstallDefaultSkillsUseCase(this.repositories),
|
|
10658
10599
|
listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
|
|
10659
10600
|
getPackageBySlug: new GetPackageSummaryUseCase(
|
|
10660
10601
|
this.repositories.packmindGateway
|
|
@@ -10682,6 +10623,11 @@ var PackmindCliHexaFactory = class {
|
|
|
10682
10623
|
var origin8 = "PackmindCliHexa";
|
|
10683
10624
|
var PackmindCliHexa = class {
|
|
10684
10625
|
constructor(logger2 = new PackmindLogger(origin8)) {
|
|
10626
|
+
this.notifyDistribution = async (command20) => {
|
|
10627
|
+
return this.hexa.repositories.packmindGateway.deployment.notifyDistribution(
|
|
10628
|
+
command20
|
|
10629
|
+
);
|
|
10630
|
+
};
|
|
10685
10631
|
this.logger = logger2;
|
|
10686
10632
|
try {
|
|
10687
10633
|
this.hexa = new PackmindCliHexaFactory();
|
|
@@ -10699,38 +10645,38 @@ var PackmindCliHexa = class {
|
|
|
10699
10645
|
this.logger.info("Destroying PackmindCliHexa");
|
|
10700
10646
|
this.logger.info("PackmindCliHexa destroyed");
|
|
10701
10647
|
}
|
|
10702
|
-
async getGitRemoteUrl(
|
|
10703
|
-
return this.hexa.useCases.getGitRemoteUrl.execute(
|
|
10648
|
+
async getGitRemoteUrl(command20) {
|
|
10649
|
+
return this.hexa.useCases.getGitRemoteUrl.execute(command20);
|
|
10704
10650
|
}
|
|
10705
|
-
async executeSingleFileAst(
|
|
10706
|
-
return this.hexa.useCases.executeSingleFileAst.execute(
|
|
10651
|
+
async executeSingleFileAst(command20) {
|
|
10652
|
+
return this.hexa.useCases.executeSingleFileAst.execute(command20);
|
|
10707
10653
|
}
|
|
10708
|
-
async listFilesInDirectory(
|
|
10709
|
-
return this.hexa.useCases.listFilesInDirectoryUseCase.execute(
|
|
10654
|
+
async listFilesInDirectory(command20) {
|
|
10655
|
+
return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command20);
|
|
10710
10656
|
}
|
|
10711
|
-
async lintFilesAgainstRule(
|
|
10712
|
-
return this.hexa.useCases.lintFilesAgainstRule.execute(
|
|
10657
|
+
async lintFilesAgainstRule(command20) {
|
|
10658
|
+
return this.hexa.useCases.lintFilesAgainstRule.execute(command20);
|
|
10713
10659
|
}
|
|
10714
|
-
async lintFilesFromConfig(
|
|
10715
|
-
return this.hexa.useCases.lintFilesFromConfig.execute(
|
|
10660
|
+
async lintFilesFromConfig(command20) {
|
|
10661
|
+
return this.hexa.useCases.lintFilesFromConfig.execute(command20);
|
|
10716
10662
|
}
|
|
10717
|
-
async installPackages(
|
|
10718
|
-
return this.hexa.useCases.installPackages.execute(
|
|
10663
|
+
async installPackages(command20) {
|
|
10664
|
+
return this.hexa.useCases.installPackages.execute(command20);
|
|
10719
10665
|
}
|
|
10720
|
-
async listPackages(
|
|
10721
|
-
return this.hexa.useCases.listPackages.execute(
|
|
10666
|
+
async listPackages(command20) {
|
|
10667
|
+
return this.hexa.useCases.listPackages.execute(command20);
|
|
10722
10668
|
}
|
|
10723
|
-
async getPackageBySlug(
|
|
10724
|
-
return this.hexa.useCases.getPackageBySlug.execute(
|
|
10669
|
+
async getPackageBySlug(command20) {
|
|
10670
|
+
return this.hexa.useCases.getPackageBySlug.execute(command20);
|
|
10725
10671
|
}
|
|
10726
|
-
async listStandards(
|
|
10727
|
-
return this.hexa.useCases.listStandards.execute(
|
|
10672
|
+
async listStandards(command20) {
|
|
10673
|
+
return this.hexa.useCases.listStandards.execute(command20);
|
|
10728
10674
|
}
|
|
10729
|
-
async listCommands(
|
|
10730
|
-
return this.hexa.useCases.listCommands.execute(
|
|
10675
|
+
async listCommands(command20) {
|
|
10676
|
+
return this.hexa.useCases.listCommands.execute(command20);
|
|
10731
10677
|
}
|
|
10732
|
-
async listSkills(
|
|
10733
|
-
return this.hexa.useCases.listSkills.execute(
|
|
10678
|
+
async listSkills(command20) {
|
|
10679
|
+
return this.hexa.useCases.listSkills.execute(command20);
|
|
10734
10680
|
}
|
|
10735
10681
|
async configExists(baseDirectory) {
|
|
10736
10682
|
return await this.hexa.repositories.configFileRepository.configExists(
|
|
@@ -10741,7 +10687,7 @@ var PackmindCliHexa = class {
|
|
|
10741
10687
|
const config = await this.hexa.repositories.configFileRepository.readConfig(
|
|
10742
10688
|
baseDirectory
|
|
10743
10689
|
);
|
|
10744
|
-
if (!config) return
|
|
10690
|
+
if (!config) return { packages: {} };
|
|
10745
10691
|
const hasNonWildcardVersions = Object.values(config.packages).some(
|
|
10746
10692
|
(version) => version !== "*"
|
|
10747
10693
|
);
|
|
@@ -10750,16 +10696,44 @@ var PackmindCliHexa = class {
|
|
|
10750
10696
|
"Package versions are not supported yet, getting the latest version"
|
|
10751
10697
|
);
|
|
10752
10698
|
}
|
|
10753
|
-
return
|
|
10699
|
+
return config;
|
|
10700
|
+
}
|
|
10701
|
+
/**
|
|
10702
|
+
* Reads the full packmind.json configuration including agents.
|
|
10703
|
+
* Returns null if no config file exists.
|
|
10704
|
+
*/
|
|
10705
|
+
async readFullConfig(baseDirectory) {
|
|
10706
|
+
return this.hexa.repositories.configFileRepository.readConfig(
|
|
10707
|
+
baseDirectory
|
|
10708
|
+
);
|
|
10754
10709
|
}
|
|
10755
10710
|
async writeConfig(baseDirectory, packagesSlugs) {
|
|
10756
10711
|
const packages = {};
|
|
10757
10712
|
packagesSlugs.forEach((slug) => {
|
|
10758
10713
|
packages[slug] = "*";
|
|
10759
10714
|
});
|
|
10715
|
+
const existingConfig = await this.hexa.repositories.configFileRepository.readConfig(
|
|
10716
|
+
baseDirectory
|
|
10717
|
+
);
|
|
10760
10718
|
await this.hexa.repositories.configFileRepository.writeConfig(
|
|
10761
10719
|
baseDirectory,
|
|
10762
|
-
{
|
|
10720
|
+
{
|
|
10721
|
+
...existingConfig,
|
|
10722
|
+
packages
|
|
10723
|
+
}
|
|
10724
|
+
);
|
|
10725
|
+
}
|
|
10726
|
+
/**
|
|
10727
|
+
* Adds new packages to an existing packmind.json while preserving property order.
|
|
10728
|
+
* If the file doesn't exist, creates a new one with default order (packages first).
|
|
10729
|
+
*
|
|
10730
|
+
* @param baseDirectory - The directory containing packmind.json
|
|
10731
|
+
* @param newPackageSlugs - Array of package slugs to add
|
|
10732
|
+
*/
|
|
10733
|
+
async addPackagesToConfig(baseDirectory, newPackageSlugs) {
|
|
10734
|
+
return this.hexa.repositories.configFileRepository.addPackagesToConfig(
|
|
10735
|
+
baseDirectory,
|
|
10736
|
+
newPackageSlugs
|
|
10763
10737
|
);
|
|
10764
10738
|
}
|
|
10765
10739
|
async readHierarchicalConfig(startDirectory, stopDirectory) {
|
|
@@ -10789,17 +10763,17 @@ var PackmindCliHexa = class {
|
|
|
10789
10763
|
directory
|
|
10790
10764
|
);
|
|
10791
10765
|
}
|
|
10792
|
-
async login(
|
|
10793
|
-
return this.hexa.useCases.login.execute(
|
|
10766
|
+
async login(command20) {
|
|
10767
|
+
return this.hexa.useCases.login.execute(command20);
|
|
10794
10768
|
}
|
|
10795
|
-
async logout(
|
|
10796
|
-
return this.hexa.useCases.logout.execute(
|
|
10769
|
+
async logout(command20) {
|
|
10770
|
+
return this.hexa.useCases.logout.execute(command20);
|
|
10797
10771
|
}
|
|
10798
|
-
async whoami(
|
|
10799
|
-
return this.hexa.useCases.whoami.execute(
|
|
10772
|
+
async whoami(command20) {
|
|
10773
|
+
return this.hexa.useCases.whoami.execute(command20);
|
|
10800
10774
|
}
|
|
10801
|
-
async setupMcp(
|
|
10802
|
-
return this.hexa.useCases.setupMcp.execute(
|
|
10775
|
+
async setupMcp(command20) {
|
|
10776
|
+
return this.hexa.useCases.setupMcp.execute(command20);
|
|
10803
10777
|
}
|
|
10804
10778
|
getCurrentBranch(repoPath) {
|
|
10805
10779
|
return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
|
|
@@ -10807,16 +10781,11 @@ var PackmindCliHexa = class {
|
|
|
10807
10781
|
getGitRemoteUrlFromPath(repoPath) {
|
|
10808
10782
|
return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
|
|
10809
10783
|
}
|
|
10810
|
-
async
|
|
10811
|
-
return this.hexa.
|
|
10812
|
-
command16
|
|
10813
|
-
);
|
|
10814
|
-
}
|
|
10815
|
-
async uploadSkill(command16) {
|
|
10816
|
-
return this.hexa.useCases.uploadSkill.execute(command16);
|
|
10784
|
+
async uploadSkill(command20) {
|
|
10785
|
+
return this.hexa.useCases.uploadSkill.execute(command20);
|
|
10817
10786
|
}
|
|
10818
|
-
async installDefaultSkills(
|
|
10819
|
-
return this.hexa.useCases.installDefaultSkills.execute(
|
|
10787
|
+
async installDefaultSkills(command20) {
|
|
10788
|
+
return this.hexa.useCases.installDefaultSkills.execute(command20);
|
|
10820
10789
|
}
|
|
10821
10790
|
getPackmindGateway() {
|
|
10822
10791
|
return this.hexa.repositories.packmindGateway;
|
|
@@ -10893,7 +10862,7 @@ function isNotLoggedInError(error) {
|
|
|
10893
10862
|
}
|
|
10894
10863
|
async function lintHandler(args2, deps) {
|
|
10895
10864
|
const {
|
|
10896
|
-
path:
|
|
10865
|
+
path: path14,
|
|
10897
10866
|
draft,
|
|
10898
10867
|
rule,
|
|
10899
10868
|
language,
|
|
@@ -10913,7 +10882,7 @@ async function lintHandler(args2, deps) {
|
|
|
10913
10882
|
throw new Error("option --rule is required to use --draft mode");
|
|
10914
10883
|
}
|
|
10915
10884
|
const startedAt = Date.now();
|
|
10916
|
-
const targetPath =
|
|
10885
|
+
const targetPath = path14 ?? ".";
|
|
10917
10886
|
const absolutePath = resolvePath(targetPath);
|
|
10918
10887
|
if (diff) {
|
|
10919
10888
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(absolutePath);
|
|
@@ -11164,8 +11133,8 @@ function extractWasmFiles() {
|
|
|
11164
11133
|
|
|
11165
11134
|
// apps/cli/src/main.ts
|
|
11166
11135
|
var import_dotenv = require("dotenv");
|
|
11167
|
-
var
|
|
11168
|
-
var
|
|
11136
|
+
var fs16 = __toESM(require("fs"));
|
|
11137
|
+
var path13 = __toESM(require("path"));
|
|
11169
11138
|
|
|
11170
11139
|
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
11171
11140
|
var import_cmd_ts2 = __toESM(require_cjs());
|
|
@@ -11176,7 +11145,7 @@ function buildPackageUrl(host, orgSlug, packageId) {
|
|
|
11176
11145
|
}
|
|
11177
11146
|
var { version: CLI_VERSION } = require_package();
|
|
11178
11147
|
async function notifyDistributionIfInGitRepo(params) {
|
|
11179
|
-
const { packmindCliHexa, cwd, packages, log } = params;
|
|
11148
|
+
const { packmindCliHexa, cwd, packages, log, agents } = params;
|
|
11180
11149
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
11181
11150
|
if (!gitRoot) {
|
|
11182
11151
|
return false;
|
|
@@ -11195,7 +11164,8 @@ async function notifyDistributionIfInGitRepo(params) {
|
|
|
11195
11164
|
distributedPackages: packages,
|
|
11196
11165
|
gitRemoteUrl,
|
|
11197
11166
|
gitBranch,
|
|
11198
|
-
relativePath
|
|
11167
|
+
relativePath,
|
|
11168
|
+
agents
|
|
11199
11169
|
});
|
|
11200
11170
|
log("Successfully notified Packmind of the new distribution");
|
|
11201
11171
|
return true;
|
|
@@ -11246,7 +11216,7 @@ async function listPackagesHandler(_args, deps) {
|
|
|
11246
11216
|
let urlBuilder = null;
|
|
11247
11217
|
const apiKey = loadApiKey();
|
|
11248
11218
|
if (apiKey) {
|
|
11249
|
-
const decoded =
|
|
11219
|
+
const decoded = decodeApiKey(apiKey);
|
|
11250
11220
|
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
11251
11221
|
if (decoded?.host && orgSlug) {
|
|
11252
11222
|
urlBuilder = (id) => buildPackageUrl(decoded.host, orgSlug, id);
|
|
@@ -11407,8 +11377,15 @@ ${uniqueCount} unique ${packageWord} currently installed.`);
|
|
|
11407
11377
|
async function executeInstallForDirectory(directory, deps) {
|
|
11408
11378
|
const { packmindCliHexa, log } = deps;
|
|
11409
11379
|
let configPackages;
|
|
11380
|
+
let configAgents;
|
|
11410
11381
|
try {
|
|
11411
|
-
|
|
11382
|
+
const fullConfig = await packmindCliHexa.readFullConfig(directory);
|
|
11383
|
+
if (fullConfig) {
|
|
11384
|
+
configPackages = Object.keys(fullConfig.packages);
|
|
11385
|
+
configAgents = fullConfig.agents;
|
|
11386
|
+
} else {
|
|
11387
|
+
configPackages = [];
|
|
11388
|
+
}
|
|
11412
11389
|
} catch (err) {
|
|
11413
11390
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
11414
11391
|
return {
|
|
@@ -11438,8 +11415,10 @@ async function executeInstallForDirectory(directory, deps) {
|
|
|
11438
11415
|
const result = await packmindCliHexa.installPackages({
|
|
11439
11416
|
baseDirectory: directory,
|
|
11440
11417
|
packagesSlugs: configPackages,
|
|
11441
|
-
previousPackagesSlugs: configPackages
|
|
11418
|
+
previousPackagesSlugs: configPackages,
|
|
11442
11419
|
// Pass for consistency
|
|
11420
|
+
agents: configAgents
|
|
11421
|
+
// Pass agents from config if present
|
|
11443
11422
|
});
|
|
11444
11423
|
const parts = [];
|
|
11445
11424
|
if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
|
|
@@ -11467,6 +11446,7 @@ async function executeInstallForDirectory(directory, deps) {
|
|
|
11467
11446
|
packmindCliHexa,
|
|
11468
11447
|
cwd: directory,
|
|
11469
11448
|
packages: configPackages,
|
|
11449
|
+
agents: configAgents,
|
|
11470
11450
|
log: () => {
|
|
11471
11451
|
}
|
|
11472
11452
|
});
|
|
@@ -11495,10 +11475,25 @@ async function installPackagesHandler(args2, deps) {
|
|
|
11495
11475
|
const { packagesSlugs } = args2;
|
|
11496
11476
|
const cwd = getCwd();
|
|
11497
11477
|
let configPackages;
|
|
11478
|
+
let configAgents;
|
|
11498
11479
|
let configFileExists = false;
|
|
11499
11480
|
try {
|
|
11500
11481
|
configFileExists = await packmindCliHexa.configExists(cwd);
|
|
11501
|
-
|
|
11482
|
+
const fullConfig = await packmindCliHexa.readFullConfig(cwd);
|
|
11483
|
+
if (fullConfig) {
|
|
11484
|
+
const hasNonWildcardVersions = Object.values(fullConfig.packages).some(
|
|
11485
|
+
(version) => version !== "*"
|
|
11486
|
+
);
|
|
11487
|
+
if (hasNonWildcardVersions) {
|
|
11488
|
+
logWarningConsole(
|
|
11489
|
+
"Package versions are not supported yet, getting the latest version"
|
|
11490
|
+
);
|
|
11491
|
+
}
|
|
11492
|
+
configPackages = Object.keys(fullConfig.packages);
|
|
11493
|
+
configAgents = fullConfig.agents;
|
|
11494
|
+
} else {
|
|
11495
|
+
configPackages = [];
|
|
11496
|
+
}
|
|
11502
11497
|
} catch (err) {
|
|
11503
11498
|
error("ERROR Failed to parse packmind.json");
|
|
11504
11499
|
if (err instanceof Error) {
|
|
@@ -11575,7 +11570,9 @@ async function installPackagesHandler(args2, deps) {
|
|
|
11575
11570
|
// Pass previous config for change detection
|
|
11576
11571
|
gitRemoteUrl,
|
|
11577
11572
|
gitBranch,
|
|
11578
|
-
relativePath
|
|
11573
|
+
relativePath,
|
|
11574
|
+
agents: configAgents
|
|
11575
|
+
// Pass agents from config if present (overrides org-level)
|
|
11579
11576
|
});
|
|
11580
11577
|
const parts = [];
|
|
11581
11578
|
if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
|
|
@@ -11602,16 +11599,27 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
|
|
|
11602
11599
|
notificationSent: false
|
|
11603
11600
|
};
|
|
11604
11601
|
}
|
|
11602
|
+
const newPackages = packagesSlugs.filter(
|
|
11603
|
+
(slug) => !configPackages.includes(slug)
|
|
11604
|
+
);
|
|
11605
|
+
if (newPackages.length > 0) {
|
|
11606
|
+
await packmindCliHexa.addPackagesToConfig(cwd, newPackages);
|
|
11607
|
+
}
|
|
11605
11608
|
let notificationSent = false;
|
|
11606
11609
|
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
|
|
11607
11610
|
notificationSent = await notifyDistributionIfInGitRepo({
|
|
11608
11611
|
packmindCliHexa,
|
|
11609
11612
|
cwd,
|
|
11610
11613
|
packages: allPackages,
|
|
11614
|
+
agents: configAgents,
|
|
11611
11615
|
log
|
|
11612
11616
|
});
|
|
11613
11617
|
}
|
|
11614
|
-
await installDefaultSkillsIfAtGitRoot({
|
|
11618
|
+
await installDefaultSkillsIfAtGitRoot({
|
|
11619
|
+
packmindCliHexa,
|
|
11620
|
+
cwd,
|
|
11621
|
+
log
|
|
11622
|
+
});
|
|
11615
11623
|
return {
|
|
11616
11624
|
filesCreated: result.filesCreated,
|
|
11617
11625
|
filesUpdated: result.filesUpdated,
|
|
@@ -11708,7 +11716,8 @@ async function uninstallPackagesHandler(args2, deps) {
|
|
|
11708
11716
|
let configFileExists = false;
|
|
11709
11717
|
try {
|
|
11710
11718
|
configFileExists = await packmindCliHexa.configExists(cwd);
|
|
11711
|
-
|
|
11719
|
+
const config = await packmindCliHexa.readConfig(cwd);
|
|
11720
|
+
configPackages = config.packages;
|
|
11712
11721
|
} catch (err) {
|
|
11713
11722
|
error("\u274C Failed to read packmind.json");
|
|
11714
11723
|
if (err instanceof Error) {
|
|
@@ -11723,7 +11732,7 @@ async function uninstallPackagesHandler(args2, deps) {
|
|
|
11723
11732
|
packagesUninstalled: []
|
|
11724
11733
|
};
|
|
11725
11734
|
}
|
|
11726
|
-
if (configPackages.length === 0) {
|
|
11735
|
+
if (Object.keys(configPackages).length === 0) {
|
|
11727
11736
|
if (configFileExists) {
|
|
11728
11737
|
error("\u274C packmind.json is empty.");
|
|
11729
11738
|
} else {
|
|
@@ -11739,10 +11748,10 @@ async function uninstallPackagesHandler(args2, deps) {
|
|
|
11739
11748
|
};
|
|
11740
11749
|
}
|
|
11741
11750
|
const packagesToUninstall = packagesSlugs.filter(
|
|
11742
|
-
(slug) => configPackages
|
|
11751
|
+
(slug) => slug in configPackages
|
|
11743
11752
|
);
|
|
11744
11753
|
const notInstalledPackages = packagesSlugs.filter(
|
|
11745
|
-
(slug) => !
|
|
11754
|
+
(slug) => !(slug in configPackages)
|
|
11746
11755
|
);
|
|
11747
11756
|
if (notInstalledPackages.length > 0) {
|
|
11748
11757
|
const packageWord = notInstalledPackages.length === 1 ? "package" : "packages";
|
|
@@ -11768,7 +11777,7 @@ async function uninstallPackagesHandler(args2, deps) {
|
|
|
11768
11777
|
log(
|
|
11769
11778
|
`Uninstalling ${packageCount} ${packageWord}: ${packagesToUninstall.join(", ")}...`
|
|
11770
11779
|
);
|
|
11771
|
-
const remainingPackages = configPackages.filter(
|
|
11780
|
+
const remainingPackages = Object.keys(configPackages).filter(
|
|
11772
11781
|
(pkg) => !packagesToUninstall.includes(pkg)
|
|
11773
11782
|
);
|
|
11774
11783
|
let filesDeleted = 0;
|
|
@@ -11777,7 +11786,7 @@ async function uninstallPackagesHandler(args2, deps) {
|
|
|
11777
11786
|
const result = await packmindCliHexa.installPackages({
|
|
11778
11787
|
baseDirectory: cwd,
|
|
11779
11788
|
packagesSlugs: [],
|
|
11780
|
-
previousPackagesSlugs: configPackages
|
|
11789
|
+
previousPackagesSlugs: Object.keys(configPackages)
|
|
11781
11790
|
});
|
|
11782
11791
|
log(`
|
|
11783
11792
|
removed ${result.filesDeleted} files`);
|
|
@@ -11797,7 +11806,7 @@ removed ${result.filesDeleted} files`);
|
|
|
11797
11806
|
const result = await packmindCliHexa.installPackages({
|
|
11798
11807
|
baseDirectory: cwd,
|
|
11799
11808
|
packagesSlugs: remainingPackages,
|
|
11800
|
-
previousPackagesSlugs: configPackages
|
|
11809
|
+
previousPackagesSlugs: Object.keys(configPackages)
|
|
11801
11810
|
});
|
|
11802
11811
|
if (result.recipesCount > 0 || result.standardsCount > 0) {
|
|
11803
11812
|
log(
|
|
@@ -12244,10 +12253,10 @@ var AgentDetectionService = class {
|
|
|
12244
12253
|
const continueDir = path11.join(this.projectDir, ".continue");
|
|
12245
12254
|
return fs11.existsSync(continueDir);
|
|
12246
12255
|
}
|
|
12247
|
-
isCommandAvailable(
|
|
12256
|
+
isCommandAvailable(command20) {
|
|
12248
12257
|
try {
|
|
12249
12258
|
const whichCommand = process.platform === "win32" ? "where" : "which";
|
|
12250
|
-
(0, import_child_process3.execSync)(`${whichCommand} ${
|
|
12259
|
+
(0, import_child_process3.execSync)(`${whichCommand} ${command20}`, { stdio: "pipe" });
|
|
12251
12260
|
return true;
|
|
12252
12261
|
} catch {
|
|
12253
12262
|
return false;
|
|
@@ -12296,7 +12305,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
12296
12305
|
output.write("\n");
|
|
12297
12306
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
12298
12307
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
12299
|
-
return new Promise((
|
|
12308
|
+
return new Promise((resolve7) => {
|
|
12300
12309
|
rl.question(
|
|
12301
12310
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
12302
12311
|
(answer) => {
|
|
@@ -12307,7 +12316,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
12307
12316
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
12308
12317
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
12309
12318
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
12310
|
-
|
|
12319
|
+
resolve7(selectedAgents);
|
|
12311
12320
|
}
|
|
12312
12321
|
);
|
|
12313
12322
|
});
|
|
@@ -12564,7 +12573,7 @@ async function listSkillsHandler(deps) {
|
|
|
12564
12573
|
let urlBuilder = null;
|
|
12565
12574
|
const apiKey = loadApiKey();
|
|
12566
12575
|
if (apiKey) {
|
|
12567
|
-
const decoded =
|
|
12576
|
+
const decoded = decodeApiKey(apiKey);
|
|
12568
12577
|
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
12569
12578
|
if (decoded?.host && orgSlug) {
|
|
12570
12579
|
urlBuilder = (slug) => buildSkillUrl(decoded.host, orgSlug, slug);
|
|
@@ -12815,7 +12824,7 @@ async function listStandardsHandler(deps) {
|
|
|
12815
12824
|
let urlBuilder = null;
|
|
12816
12825
|
const apiKey = loadApiKey();
|
|
12817
12826
|
if (apiKey) {
|
|
12818
|
-
const decoded =
|
|
12827
|
+
const decoded = decodeApiKey(apiKey);
|
|
12819
12828
|
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
12820
12829
|
if (decoded?.host && orgSlug) {
|
|
12821
12830
|
urlBuilder = (id) => buildStandardUrl(decoded.host, orgSlug, id);
|
|
@@ -12972,7 +12981,7 @@ async function createCommandHandler(filePath, useCase) {
|
|
|
12972
12981
|
let webappUrl;
|
|
12973
12982
|
const apiKey = loadApiKey();
|
|
12974
12983
|
if (apiKey) {
|
|
12975
|
-
const decoded =
|
|
12984
|
+
const decoded = decodeApiKey(apiKey);
|
|
12976
12985
|
if (decoded?.host && decoded?.jwt?.organization?.slug) {
|
|
12977
12986
|
webappUrl = buildWebappUrl(
|
|
12978
12987
|
decoded.host,
|
|
@@ -13002,7 +13011,8 @@ var CreateCommandFromPlaybookUseCase = class {
|
|
|
13002
13011
|
}
|
|
13003
13012
|
async execute(playbook) {
|
|
13004
13013
|
const space = await this.gateway.spaces.getGlobal();
|
|
13005
|
-
const
|
|
13014
|
+
const command20 = await this.gateway.commands.create({
|
|
13015
|
+
spaceId: space.id,
|
|
13006
13016
|
name: playbook.name,
|
|
13007
13017
|
summary: playbook.summary,
|
|
13008
13018
|
whenToUse: playbook.whenToUse,
|
|
@@ -13014,9 +13024,9 @@ var CreateCommandFromPlaybookUseCase = class {
|
|
|
13014
13024
|
}))
|
|
13015
13025
|
});
|
|
13016
13026
|
return {
|
|
13017
|
-
commandId:
|
|
13018
|
-
name:
|
|
13019
|
-
slug:
|
|
13027
|
+
commandId: command20.id,
|
|
13028
|
+
name: command20.name,
|
|
13029
|
+
slug: command20.slug
|
|
13020
13030
|
};
|
|
13021
13031
|
}
|
|
13022
13032
|
};
|
|
@@ -13084,7 +13094,7 @@ async function listCommandsHandler(deps) {
|
|
|
13084
13094
|
let urlBuilder = null;
|
|
13085
13095
|
const apiKey = loadApiKey();
|
|
13086
13096
|
if (apiKey) {
|
|
13087
|
-
const decoded =
|
|
13097
|
+
const decoded = decodeApiKey(apiKey);
|
|
13088
13098
|
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
13089
13099
|
if (decoded?.host && orgSlug) {
|
|
13090
13100
|
urlBuilder = (id) => buildCommandUrl(decoded.host, orgSlug, id);
|
|
@@ -13143,7 +13153,7 @@ var commandsCommand = (0, import_cmd_ts17.subcommands)({
|
|
|
13143
13153
|
});
|
|
13144
13154
|
|
|
13145
13155
|
// apps/cli/src/infra/commands/PackagesCommand.ts
|
|
13146
|
-
var
|
|
13156
|
+
var import_cmd_ts21 = __toESM(require_cjs());
|
|
13147
13157
|
|
|
13148
13158
|
// apps/cli/src/infra/commands/CreatePackageCommand.ts
|
|
13149
13159
|
var import_cmd_ts18 = __toESM(require_cjs());
|
|
@@ -13165,7 +13175,7 @@ async function createPackageHandler(name, description, useCase) {
|
|
|
13165
13175
|
let webappUrl;
|
|
13166
13176
|
const apiKey = loadApiKey();
|
|
13167
13177
|
if (apiKey) {
|
|
13168
|
-
const decoded =
|
|
13178
|
+
const decoded = decodeApiKey(apiKey);
|
|
13169
13179
|
if (decoded?.host && decoded?.jwt?.organization?.slug) {
|
|
13170
13180
|
webappUrl = buildWebappUrl2(
|
|
13171
13181
|
decoded.host,
|
|
@@ -13194,16 +13204,19 @@ var CreatePackageUseCase = class {
|
|
|
13194
13204
|
constructor(gateway) {
|
|
13195
13205
|
this.gateway = gateway;
|
|
13196
13206
|
}
|
|
13197
|
-
async execute(
|
|
13207
|
+
async execute(command20) {
|
|
13198
13208
|
const space = await this.gateway.spaces.getGlobal();
|
|
13199
|
-
const result = await this.gateway.packages.create(
|
|
13200
|
-
|
|
13201
|
-
|
|
13209
|
+
const result = await this.gateway.packages.create({
|
|
13210
|
+
spaceId: space.id,
|
|
13211
|
+
name: command20.name,
|
|
13212
|
+
description: command20.description ?? "",
|
|
13213
|
+
recipeIds: [],
|
|
13214
|
+
standardIds: []
|
|
13202
13215
|
});
|
|
13203
13216
|
return {
|
|
13204
|
-
packageId: result.id,
|
|
13205
|
-
name: result.name,
|
|
13206
|
-
slug: result.slug
|
|
13217
|
+
packageId: result.package.id,
|
|
13218
|
+
name: result.package.name,
|
|
13219
|
+
slug: result.package.slug
|
|
13207
13220
|
};
|
|
13208
13221
|
}
|
|
13209
13222
|
};
|
|
@@ -13264,35 +13277,503 @@ var createPackageCommand = (0, import_cmd_ts18.command)({
|
|
|
13264
13277
|
}
|
|
13265
13278
|
});
|
|
13266
13279
|
|
|
13280
|
+
// apps/cli/src/infra/commands/AddToPackageCommand.ts
|
|
13281
|
+
var import_cmd_ts19 = __toESM(require_cjs());
|
|
13282
|
+
|
|
13283
|
+
// apps/cli/src/domain/errors/ItemNotFoundError.ts
|
|
13284
|
+
var ItemNotFoundError = class extends Error {
|
|
13285
|
+
constructor(itemType, slug) {
|
|
13286
|
+
super(`${itemType} '${slug}' not found`);
|
|
13287
|
+
this.itemType = itemType;
|
|
13288
|
+
this.slug = slug;
|
|
13289
|
+
this.name = "ItemNotFoundError";
|
|
13290
|
+
}
|
|
13291
|
+
};
|
|
13292
|
+
|
|
13293
|
+
// apps/cli/src/application/useCases/AddToPackageUseCase.ts
|
|
13294
|
+
var AddToPackageUseCase = class {
|
|
13295
|
+
constructor(gateway) {
|
|
13296
|
+
this.gateway = gateway;
|
|
13297
|
+
}
|
|
13298
|
+
async execute(command20) {
|
|
13299
|
+
const { packageSlug, itemType, itemSlugs } = command20;
|
|
13300
|
+
const space = await this.gateway.spaces.getGlobal();
|
|
13301
|
+
const packages = await this.gateway.packages.list({});
|
|
13302
|
+
const pkg = packages.packages.find((pkg2) => pkg2.slug === packageSlug);
|
|
13303
|
+
if (!pkg) {
|
|
13304
|
+
throw new ItemNotFoundError("package", packageSlug);
|
|
13305
|
+
}
|
|
13306
|
+
const { ids, idToSlugMap } = await this.resolveSlugsToIds(
|
|
13307
|
+
itemType,
|
|
13308
|
+
itemSlugs
|
|
13309
|
+
);
|
|
13310
|
+
const addCommand = {
|
|
13311
|
+
packageId: pkg.id,
|
|
13312
|
+
spaceId: space.id,
|
|
13313
|
+
standardIds: [],
|
|
13314
|
+
recipeIds: [],
|
|
13315
|
+
skillIds: []
|
|
13316
|
+
};
|
|
13317
|
+
if (itemType === "standard") {
|
|
13318
|
+
addCommand.standardIds = ids.map(createStandardId);
|
|
13319
|
+
} else if (itemType === "command") {
|
|
13320
|
+
addCommand.recipeIds = ids.map(createRecipeId);
|
|
13321
|
+
} else if (itemType === "skill") {
|
|
13322
|
+
addCommand.skillIds = ids.map(createSkillId);
|
|
13323
|
+
}
|
|
13324
|
+
const result = await this.gateway.packages.addArtefacts(addCommand);
|
|
13325
|
+
const typeKey = itemType === "command" ? "commands" : `${itemType}s`;
|
|
13326
|
+
const addedIds = result.added[typeKey];
|
|
13327
|
+
const skippedIds = result.skipped[typeKey];
|
|
13328
|
+
return {
|
|
13329
|
+
added: addedIds.map((id) => idToSlugMap.get(id) ?? id),
|
|
13330
|
+
skipped: skippedIds.map((id) => idToSlugMap.get(id) ?? id)
|
|
13331
|
+
};
|
|
13332
|
+
}
|
|
13333
|
+
async resolveSlugsToIds(itemType, slugs) {
|
|
13334
|
+
const ids = [];
|
|
13335
|
+
const idToSlugMap = /* @__PURE__ */ new Map();
|
|
13336
|
+
const globalSpace = await this.gateway.spaces.getGlobal();
|
|
13337
|
+
for (const slug of slugs) {
|
|
13338
|
+
let item = null;
|
|
13339
|
+
if (itemType === "standard") {
|
|
13340
|
+
item = await this.findStandardBySlug(slug, globalSpace.id);
|
|
13341
|
+
} else if (itemType === "command") {
|
|
13342
|
+
item = await this.findCommandBySlug(slug, globalSpace.id);
|
|
13343
|
+
} else if (itemType === "skill") {
|
|
13344
|
+
item = await this.findSkillBySlug(slug, globalSpace.id);
|
|
13345
|
+
}
|
|
13346
|
+
if (!item) {
|
|
13347
|
+
throw new ItemNotFoundError(itemType, slug);
|
|
13348
|
+
}
|
|
13349
|
+
ids.push(item.id);
|
|
13350
|
+
idToSlugMap.set(item.id, slug);
|
|
13351
|
+
}
|
|
13352
|
+
return { ids, idToSlugMap };
|
|
13353
|
+
}
|
|
13354
|
+
async findStandardBySlug(slug, spaceId) {
|
|
13355
|
+
const standards = await this.gateway.standards.list({ spaceId });
|
|
13356
|
+
return standards.standards.find((skill) => skill.slug === slug) ?? null;
|
|
13357
|
+
}
|
|
13358
|
+
async findCommandBySlug(slug, spaceId) {
|
|
13359
|
+
const commands = await this.gateway.commands.list({ spaceId });
|
|
13360
|
+
return commands.recipes.find((command20) => command20.slug === slug) ?? null;
|
|
13361
|
+
}
|
|
13362
|
+
async findSkillBySlug(slug, spaceId) {
|
|
13363
|
+
const skills = await this.gateway.skills.list({ spaceId });
|
|
13364
|
+
return skills.find((skill) => skill.slug === slug) ?? null;
|
|
13365
|
+
}
|
|
13366
|
+
};
|
|
13367
|
+
|
|
13368
|
+
// apps/cli/src/infra/commands/addToPackageHandler.ts
|
|
13369
|
+
function pluralize(singular, count) {
|
|
13370
|
+
return count === 1 ? singular : `${singular}s`;
|
|
13371
|
+
}
|
|
13372
|
+
function formatItemType(itemType, count) {
|
|
13373
|
+
return pluralize(itemType.charAt(0).toUpperCase() + itemType.slice(1), count);
|
|
13374
|
+
}
|
|
13375
|
+
function formatItemList(items) {
|
|
13376
|
+
return items.map((item) => `"${item}"`).join(", ");
|
|
13377
|
+
}
|
|
13378
|
+
async function addToPackageHandler(packageSlug, itemType, itemSlugs, useCase) {
|
|
13379
|
+
if (itemSlugs.length === 0) {
|
|
13380
|
+
return { success: false, error: "No items provided to add" };
|
|
13381
|
+
}
|
|
13382
|
+
try {
|
|
13383
|
+
const result = await useCase.execute({ packageSlug, itemType, itemSlugs });
|
|
13384
|
+
if (result.added.length) {
|
|
13385
|
+
logSuccessConsole(
|
|
13386
|
+
`${formatItemType(itemType, result.added.length)} ${formatItemList(result.added)} added to "${packageSlug}"`
|
|
13387
|
+
);
|
|
13388
|
+
logSuccessConsole(
|
|
13389
|
+
`Run \`packmind-cli install ${packageSlug}\` to install the ${pluralize(itemType, result.added.length)}`
|
|
13390
|
+
);
|
|
13391
|
+
}
|
|
13392
|
+
if (result.skipped.length) {
|
|
13393
|
+
logWarningConsole(
|
|
13394
|
+
`${formatItemType(itemType, result.skipped.length)} ${formatItemList(result.skipped)} already in "${packageSlug}" (skipped)`
|
|
13395
|
+
);
|
|
13396
|
+
}
|
|
13397
|
+
return { success: true, added: result.added, skipped: result.skipped };
|
|
13398
|
+
} catch (error) {
|
|
13399
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13400
|
+
logErrorConsole(message);
|
|
13401
|
+
if (error instanceof ItemNotFoundError) {
|
|
13402
|
+
logInfoConsole(
|
|
13403
|
+
`Run \`packmind-cli ${error.itemType}s list\` to display available ${error.itemType}s`
|
|
13404
|
+
);
|
|
13405
|
+
}
|
|
13406
|
+
return { success: false, error: message };
|
|
13407
|
+
}
|
|
13408
|
+
}
|
|
13409
|
+
|
|
13410
|
+
// apps/cli/src/infra/commands/AddToPackageCommand.ts
|
|
13411
|
+
var addToPackageCommand = (0, import_cmd_ts19.command)({
|
|
13412
|
+
name: "add",
|
|
13413
|
+
description: "Add standards, commands, or skills to a package",
|
|
13414
|
+
args: {
|
|
13415
|
+
to: (0, import_cmd_ts19.option)({
|
|
13416
|
+
long: "to",
|
|
13417
|
+
description: "Target package slug",
|
|
13418
|
+
type: import_cmd_ts19.string
|
|
13419
|
+
}),
|
|
13420
|
+
standards: (0, import_cmd_ts19.multioption)({
|
|
13421
|
+
long: "standard",
|
|
13422
|
+
description: "Standard slug(s) to add",
|
|
13423
|
+
type: (0, import_cmd_ts19.array)(import_cmd_ts19.string)
|
|
13424
|
+
}),
|
|
13425
|
+
commands: (0, import_cmd_ts19.multioption)({
|
|
13426
|
+
long: "command",
|
|
13427
|
+
description: "Command slug(s) to add",
|
|
13428
|
+
type: (0, import_cmd_ts19.array)(import_cmd_ts19.string)
|
|
13429
|
+
}),
|
|
13430
|
+
skills: (0, import_cmd_ts19.multioption)({
|
|
13431
|
+
long: "skill",
|
|
13432
|
+
description: "Skill slug(s) to add",
|
|
13433
|
+
type: (0, import_cmd_ts19.array)(import_cmd_ts19.string)
|
|
13434
|
+
})
|
|
13435
|
+
},
|
|
13436
|
+
handler: async ({ to, standards, commands, skills }) => {
|
|
13437
|
+
const standardSlugs = standards ?? [];
|
|
13438
|
+
const commandSlugs = commands ?? [];
|
|
13439
|
+
const skillSlugs = skills ?? [];
|
|
13440
|
+
const itemTypes = [
|
|
13441
|
+
{ type: "standard", slugs: standardSlugs },
|
|
13442
|
+
{ type: "command", slugs: commandSlugs },
|
|
13443
|
+
{ type: "skill", slugs: skillSlugs }
|
|
13444
|
+
].filter((t) => t.slugs.length > 0);
|
|
13445
|
+
if (itemTypes.length === 0) {
|
|
13446
|
+
logErrorConsole(
|
|
13447
|
+
"Error: At least one --standard, --command, or --skill is required"
|
|
13448
|
+
);
|
|
13449
|
+
process.exit(1);
|
|
13450
|
+
}
|
|
13451
|
+
if (itemTypes.length > 1) {
|
|
13452
|
+
logErrorConsole(
|
|
13453
|
+
"Cannot add standards, commands, and skills simultaneously. Use dedicated commands for each artefact."
|
|
13454
|
+
);
|
|
13455
|
+
process.exit(1);
|
|
13456
|
+
}
|
|
13457
|
+
const { type: itemType, slugs: itemSlugs } = itemTypes[0];
|
|
13458
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
13459
|
+
const hexa = new PackmindCliHexa(packmindLogger);
|
|
13460
|
+
const gateway = hexa.getPackmindGateway();
|
|
13461
|
+
const useCase = new AddToPackageUseCase(gateway);
|
|
13462
|
+
const result = await addToPackageHandler(to, itemType, itemSlugs, useCase);
|
|
13463
|
+
if (!result.success) {
|
|
13464
|
+
process.exit(1);
|
|
13465
|
+
}
|
|
13466
|
+
}
|
|
13467
|
+
});
|
|
13468
|
+
|
|
13469
|
+
// apps/cli/src/infra/commands/listPackagesCommand.ts
|
|
13470
|
+
var import_cmd_ts20 = __toESM(require_cjs());
|
|
13471
|
+
var listPackagesCommand = (0, import_cmd_ts20.command)({
|
|
13472
|
+
name: "list",
|
|
13473
|
+
description: "List available packages",
|
|
13474
|
+
args: {},
|
|
13475
|
+
handler: async () => {
|
|
13476
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
13477
|
+
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
13478
|
+
const deps = {
|
|
13479
|
+
packmindCliHexa,
|
|
13480
|
+
exit: process.exit,
|
|
13481
|
+
getCwd: () => process.cwd(),
|
|
13482
|
+
log: console.log,
|
|
13483
|
+
error: console.error
|
|
13484
|
+
};
|
|
13485
|
+
await listPackagesHandler({}, deps);
|
|
13486
|
+
}
|
|
13487
|
+
});
|
|
13488
|
+
|
|
13267
13489
|
// apps/cli/src/infra/commands/PackagesCommand.ts
|
|
13268
|
-
var packagesCommand = (0,
|
|
13490
|
+
var packagesCommand = (0, import_cmd_ts21.subcommands)({
|
|
13269
13491
|
name: "packages",
|
|
13270
13492
|
description: "Manage packages",
|
|
13271
13493
|
cmds: {
|
|
13272
|
-
create: createPackageCommand
|
|
13494
|
+
create: createPackageCommand,
|
|
13495
|
+
add: addToPackageCommand,
|
|
13496
|
+
list: listPackagesCommand
|
|
13273
13497
|
}
|
|
13274
13498
|
});
|
|
13275
13499
|
|
|
13276
|
-
// apps/cli/src/
|
|
13500
|
+
// apps/cli/src/infra/commands/config/ConfigCommand.ts
|
|
13501
|
+
var import_cmd_ts23 = __toESM(require_cjs());
|
|
13502
|
+
|
|
13503
|
+
// apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
|
|
13504
|
+
var import_cmd_ts22 = __toESM(require_cjs());
|
|
13505
|
+
|
|
13506
|
+
// apps/cli/src/application/services/AgentArtifactDetectionService.ts
|
|
13507
|
+
var fs15 = __toESM(require("fs/promises"));
|
|
13508
|
+
var path12 = __toESM(require("path"));
|
|
13509
|
+
var AGENT_ARTIFACT_CHECKS = [
|
|
13510
|
+
{ agent: "claude", paths: [".claude"] },
|
|
13511
|
+
{ agent: "cursor", paths: [".cursor"] },
|
|
13512
|
+
{
|
|
13513
|
+
agent: "copilot",
|
|
13514
|
+
paths: [".github/copilot-instructions.md", ".github/instructions"]
|
|
13515
|
+
},
|
|
13516
|
+
{ agent: "continue", paths: [".continue"] },
|
|
13517
|
+
{ agent: "junie", paths: [".junie", ".junie.md"] },
|
|
13518
|
+
{ agent: "agents_md", paths: ["AGENTS.md"] },
|
|
13519
|
+
{ agent: "gitlab_duo", paths: [".gitlab"] }
|
|
13520
|
+
];
|
|
13521
|
+
var AgentArtifactDetectionService = class {
|
|
13522
|
+
async detectAgentArtifacts(baseDirectory) {
|
|
13523
|
+
const detected = [];
|
|
13524
|
+
for (const check of AGENT_ARTIFACT_CHECKS) {
|
|
13525
|
+
for (const relativePath of check.paths) {
|
|
13526
|
+
const fullPath = path12.join(baseDirectory, relativePath);
|
|
13527
|
+
const exists = await this.pathExists(fullPath);
|
|
13528
|
+
if (exists) {
|
|
13529
|
+
detected.push({
|
|
13530
|
+
agent: check.agent,
|
|
13531
|
+
artifactPath: fullPath
|
|
13532
|
+
});
|
|
13533
|
+
break;
|
|
13534
|
+
}
|
|
13535
|
+
}
|
|
13536
|
+
}
|
|
13537
|
+
return detected;
|
|
13538
|
+
}
|
|
13539
|
+
async pathExists(filePath) {
|
|
13540
|
+
try {
|
|
13541
|
+
await fs15.access(filePath);
|
|
13542
|
+
return true;
|
|
13543
|
+
} catch {
|
|
13544
|
+
return false;
|
|
13545
|
+
}
|
|
13546
|
+
}
|
|
13547
|
+
};
|
|
13548
|
+
|
|
13549
|
+
// apps/cli/src/infra/commands/config/configAgentsHandler.ts
|
|
13550
|
+
var readline3 = __toESM(require("readline"));
|
|
13551
|
+
var inquirer2 = __toESM(require("inquirer"));
|
|
13552
|
+
var SELECTABLE_AGENTS = [
|
|
13553
|
+
"claude",
|
|
13554
|
+
"cursor",
|
|
13555
|
+
"copilot",
|
|
13556
|
+
"agents_md",
|
|
13557
|
+
"continue",
|
|
13558
|
+
"junie",
|
|
13559
|
+
"gitlab_duo"
|
|
13560
|
+
];
|
|
13561
|
+
var AGENT_DISPLAY_NAMES = {
|
|
13562
|
+
packmind: "Packmind",
|
|
13563
|
+
claude: "Claude Code",
|
|
13564
|
+
cursor: "Cursor",
|
|
13565
|
+
copilot: "GitHub Copilot",
|
|
13566
|
+
continue: "Continue.dev",
|
|
13567
|
+
junie: "Junie",
|
|
13568
|
+
agents_md: "AGENTS.md",
|
|
13569
|
+
gitlab_duo: "GitLab Duo"
|
|
13570
|
+
};
|
|
13571
|
+
async function promptAgentsWithReadline2(choices) {
|
|
13572
|
+
const input = process.stdin;
|
|
13573
|
+
const output = process.stdout;
|
|
13574
|
+
const rl = readline3.createInterface({
|
|
13575
|
+
input,
|
|
13576
|
+
output
|
|
13577
|
+
});
|
|
13578
|
+
output.write("\nSelect coding agents to generate artifacts for:\n");
|
|
13579
|
+
choices.forEach((choice, index) => {
|
|
13580
|
+
const marker = choice.checked ? "*" : " ";
|
|
13581
|
+
output.write(` ${index + 1}. [${marker}] ${choice.name}
|
|
13582
|
+
`);
|
|
13583
|
+
});
|
|
13584
|
+
output.write("\n");
|
|
13585
|
+
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
13586
|
+
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
13587
|
+
return new Promise((resolve7) => {
|
|
13588
|
+
rl.question(
|
|
13589
|
+
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
13590
|
+
(answer) => {
|
|
13591
|
+
rl.close();
|
|
13592
|
+
const trimmed = answer.trim();
|
|
13593
|
+
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
13594
|
+
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
13595
|
+
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
13596
|
+
resolve7(selectedAgents);
|
|
13597
|
+
}
|
|
13598
|
+
);
|
|
13599
|
+
});
|
|
13600
|
+
}
|
|
13601
|
+
async function configAgentsHandler(deps) {
|
|
13602
|
+
const { configRepository, agentDetectionService, baseDirectory } = deps;
|
|
13603
|
+
const isTTY = deps.isTTY ?? process.stdin.isTTY;
|
|
13604
|
+
const useSimplePrompt = process.env.PACKMIND_SIMPLE_PROMPT === "1" || !isTTY;
|
|
13605
|
+
const existingConfig = await configRepository.readConfig(baseDirectory);
|
|
13606
|
+
let preselectedAgents;
|
|
13607
|
+
if (existingConfig?.agents && existingConfig.agents.length > 0) {
|
|
13608
|
+
preselectedAgents = new Set(
|
|
13609
|
+
existingConfig.agents.filter(
|
|
13610
|
+
(agent) => SELECTABLE_AGENTS.includes(agent)
|
|
13611
|
+
)
|
|
13612
|
+
);
|
|
13613
|
+
} else {
|
|
13614
|
+
const detectedArtifacts = await agentDetectionService.detectAgentArtifacts(baseDirectory);
|
|
13615
|
+
preselectedAgents = new Set(detectedArtifacts.map((a) => a.agent));
|
|
13616
|
+
}
|
|
13617
|
+
const choices = SELECTABLE_AGENTS.map((agent) => ({
|
|
13618
|
+
name: AGENT_DISPLAY_NAMES[agent],
|
|
13619
|
+
value: agent,
|
|
13620
|
+
checked: preselectedAgents.has(agent)
|
|
13621
|
+
}));
|
|
13622
|
+
let selectedAgents;
|
|
13623
|
+
if (useSimplePrompt) {
|
|
13624
|
+
selectedAgents = await promptAgentsWithReadline2(choices);
|
|
13625
|
+
} else {
|
|
13626
|
+
const result = await inquirer2.default.prompt([
|
|
13627
|
+
{
|
|
13628
|
+
type: "checkbox",
|
|
13629
|
+
name: "selectedAgents",
|
|
13630
|
+
message: "Select coding agents to generate artifacts for:",
|
|
13631
|
+
choices
|
|
13632
|
+
}
|
|
13633
|
+
]);
|
|
13634
|
+
selectedAgents = result.selectedAgents;
|
|
13635
|
+
}
|
|
13636
|
+
await configRepository.updateAgentsConfig(baseDirectory, selectedAgents);
|
|
13637
|
+
const agentNames = selectedAgents.map((a) => AGENT_DISPLAY_NAMES[a]);
|
|
13638
|
+
if (selectedAgents.length === 0) {
|
|
13639
|
+
logInfoConsole(
|
|
13640
|
+
"No agents selected. Only packmind artifacts will be generated."
|
|
13641
|
+
);
|
|
13642
|
+
} else {
|
|
13643
|
+
logSuccessConsole(
|
|
13644
|
+
`Configuration saved. Artifacts will be generated for: ${agentNames.join(", ")}`
|
|
13645
|
+
);
|
|
13646
|
+
}
|
|
13647
|
+
}
|
|
13648
|
+
|
|
13649
|
+
// apps/cli/src/infra/commands/config/ConfigAgentsCommand.ts
|
|
13650
|
+
var configAgentsCommand = (0, import_cmd_ts22.command)({
|
|
13651
|
+
name: "agents",
|
|
13652
|
+
description: "Configure which coding agents to generate artifacts for",
|
|
13653
|
+
args: {},
|
|
13654
|
+
handler: async () => {
|
|
13655
|
+
const configRepository = new ConfigFileRepository();
|
|
13656
|
+
const agentDetectionService = new AgentArtifactDetectionService();
|
|
13657
|
+
const baseDirectory = process.cwd();
|
|
13658
|
+
await configAgentsHandler({
|
|
13659
|
+
configRepository,
|
|
13660
|
+
agentDetectionService,
|
|
13661
|
+
baseDirectory
|
|
13662
|
+
});
|
|
13663
|
+
}
|
|
13664
|
+
});
|
|
13665
|
+
|
|
13666
|
+
// apps/cli/src/infra/commands/config/ConfigCommand.ts
|
|
13667
|
+
var configCommand = (0, import_cmd_ts23.subcommands)({
|
|
13668
|
+
name: "config",
|
|
13669
|
+
description: "Manage Packmind configuration",
|
|
13670
|
+
cmds: {
|
|
13671
|
+
agents: configAgentsCommand
|
|
13672
|
+
}
|
|
13673
|
+
});
|
|
13674
|
+
|
|
13675
|
+
// apps/cli/src/infra/commands/InitCommand.ts
|
|
13676
|
+
var import_cmd_ts24 = __toESM(require_cjs());
|
|
13677
|
+
|
|
13678
|
+
// apps/cli/src/infra/commands/initHandler.ts
|
|
13679
|
+
async function initHandler(deps) {
|
|
13680
|
+
const {
|
|
13681
|
+
configRepository,
|
|
13682
|
+
agentDetectionService,
|
|
13683
|
+
baseDirectory,
|
|
13684
|
+
installDefaultSkills,
|
|
13685
|
+
cliVersion,
|
|
13686
|
+
isTTY
|
|
13687
|
+
} = deps;
|
|
13688
|
+
const configAgentsDeps = {
|
|
13689
|
+
configRepository,
|
|
13690
|
+
agentDetectionService,
|
|
13691
|
+
baseDirectory,
|
|
13692
|
+
isTTY
|
|
13693
|
+
};
|
|
13694
|
+
await configAgentsHandler(configAgentsDeps);
|
|
13695
|
+
logInfoConsole("Installing default skills...");
|
|
13696
|
+
const result = await installDefaultSkills({
|
|
13697
|
+
includeBeta: false,
|
|
13698
|
+
cliVersion
|
|
13699
|
+
});
|
|
13700
|
+
if (result.errors.length > 0) {
|
|
13701
|
+
return {
|
|
13702
|
+
success: false,
|
|
13703
|
+
errors: result.errors
|
|
13704
|
+
};
|
|
13705
|
+
}
|
|
13706
|
+
const totalFiles = result.filesCreated + result.filesUpdated;
|
|
13707
|
+
if (totalFiles === 0) {
|
|
13708
|
+
logInfoConsole("Default skills are already up to date.");
|
|
13709
|
+
} else {
|
|
13710
|
+
logSuccessConsole("Default skills installed successfully!");
|
|
13711
|
+
if (result.filesCreated > 0) {
|
|
13712
|
+
logInfoConsole(` Files created: ${result.filesCreated}`);
|
|
13713
|
+
}
|
|
13714
|
+
if (result.filesUpdated > 0) {
|
|
13715
|
+
logInfoConsole(` Files updated: ${result.filesUpdated}`);
|
|
13716
|
+
}
|
|
13717
|
+
}
|
|
13718
|
+
logConsole("");
|
|
13719
|
+
logSuccessConsole("Packmind initialized successfully!");
|
|
13720
|
+
logInfoConsole(
|
|
13721
|
+
`Next step: Run ${formatCommand("/packmind-onboard")} in your AI agent to onboard the project`
|
|
13722
|
+
);
|
|
13723
|
+
return {
|
|
13724
|
+
success: true,
|
|
13725
|
+
errors: []
|
|
13726
|
+
};
|
|
13727
|
+
}
|
|
13728
|
+
|
|
13729
|
+
// apps/cli/src/infra/commands/InitCommand.ts
|
|
13277
13730
|
var { version: CLI_VERSION3 } = require_package();
|
|
13731
|
+
var initCommand = (0, import_cmd_ts24.command)({
|
|
13732
|
+
name: "init",
|
|
13733
|
+
description: "Initialize Packmind in the current project",
|
|
13734
|
+
args: {},
|
|
13735
|
+
handler: async () => {
|
|
13736
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
13737
|
+
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
13738
|
+
const configRepository = new ConfigFileRepository();
|
|
13739
|
+
const agentDetectionService = new AgentArtifactDetectionService();
|
|
13740
|
+
const baseDirectory = process.cwd();
|
|
13741
|
+
const result = await initHandler({
|
|
13742
|
+
configRepository,
|
|
13743
|
+
agentDetectionService,
|
|
13744
|
+
baseDirectory,
|
|
13745
|
+
installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
|
|
13746
|
+
cliVersion: CLI_VERSION3
|
|
13747
|
+
});
|
|
13748
|
+
if (!result.success) {
|
|
13749
|
+
for (const error of result.errors) {
|
|
13750
|
+
logErrorConsole(`Error: ${error}`);
|
|
13751
|
+
}
|
|
13752
|
+
process.exit(1);
|
|
13753
|
+
}
|
|
13754
|
+
}
|
|
13755
|
+
});
|
|
13756
|
+
|
|
13757
|
+
// apps/cli/src/main.ts
|
|
13758
|
+
var { version: CLI_VERSION4 } = require_package();
|
|
13278
13759
|
function findEnvFile() {
|
|
13279
13760
|
const currentDir = process.cwd();
|
|
13280
13761
|
const gitService = new GitService();
|
|
13281
13762
|
const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
|
|
13282
|
-
const filesystemRoot =
|
|
13763
|
+
const filesystemRoot = path13.parse(currentDir).root;
|
|
13283
13764
|
const stopDir = gitRoot ?? filesystemRoot;
|
|
13284
13765
|
let searchDir = currentDir;
|
|
13285
|
-
let parentDir =
|
|
13766
|
+
let parentDir = path13.dirname(searchDir);
|
|
13286
13767
|
while (searchDir !== parentDir) {
|
|
13287
|
-
const envPath2 =
|
|
13288
|
-
if (
|
|
13768
|
+
const envPath2 = path13.join(searchDir, ".env");
|
|
13769
|
+
if (fs16.existsSync(envPath2)) {
|
|
13289
13770
|
return envPath2;
|
|
13290
13771
|
}
|
|
13291
13772
|
if (searchDir === stopDir) {
|
|
13292
13773
|
return null;
|
|
13293
13774
|
}
|
|
13294
13775
|
searchDir = parentDir;
|
|
13295
|
-
parentDir =
|
|
13776
|
+
parentDir = path13.dirname(searchDir);
|
|
13296
13777
|
}
|
|
13297
13778
|
return null;
|
|
13298
13779
|
}
|
|
@@ -13309,29 +13790,31 @@ if (hasEmbeddedWasmFiles()) {
|
|
|
13309
13790
|
}
|
|
13310
13791
|
var args = process.argv.slice(2);
|
|
13311
13792
|
if (args.includes("--version") || args.includes("-v")) {
|
|
13312
|
-
logConsole(`packmind-cli version ${
|
|
13793
|
+
logConsole(`packmind-cli version ${CLI_VERSION4}`);
|
|
13313
13794
|
process.exit(0);
|
|
13314
13795
|
}
|
|
13315
|
-
var app = (0,
|
|
13796
|
+
var app = (0, import_cmd_ts25.subcommands)({
|
|
13316
13797
|
name: "packmind-cli",
|
|
13317
13798
|
description: "Packmind CLI tool",
|
|
13318
13799
|
cmds: {
|
|
13319
|
-
|
|
13800
|
+
commands: commandsCommand,
|
|
13801
|
+
config: configCommand,
|
|
13802
|
+
init: initCommand,
|
|
13320
13803
|
install: installCommand,
|
|
13321
|
-
|
|
13322
|
-
remove: uninstallCommand,
|
|
13323
|
-
// Alias for uninstall
|
|
13804
|
+
lint: lintCommand,
|
|
13324
13805
|
login: loginCommand,
|
|
13325
13806
|
logout: logoutCommand,
|
|
13326
|
-
|
|
13807
|
+
packages: packagesCommand,
|
|
13808
|
+
remove: uninstallCommand,
|
|
13809
|
+
// Alias for uninstall
|
|
13327
13810
|
"setup-mcp": setupMcpCommand,
|
|
13328
13811
|
skills: skillsCommand,
|
|
13329
13812
|
standards: standardsCommand,
|
|
13330
|
-
|
|
13331
|
-
|
|
13813
|
+
uninstall: uninstallCommand,
|
|
13814
|
+
whoami: whoamiCommand
|
|
13332
13815
|
}
|
|
13333
13816
|
});
|
|
13334
|
-
(0,
|
|
13817
|
+
(0, import_cmd_ts25.run)(app, args).catch((error) => {
|
|
13335
13818
|
logErrorConsole(error.message);
|
|
13336
13819
|
process.exit(1);
|
|
13337
13820
|
});
|