@packmind/cli 0.17.0 → 0.19.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 +643 -220
- package/package.json +1 -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(string12, substring, replacer) {
|
|
375
|
+
let index = string12.indexOf(substring);
|
|
376
376
|
if (index === -1) {
|
|
377
|
-
return
|
|
377
|
+
return string12;
|
|
378
378
|
}
|
|
379
379
|
const substringLength = substring.length;
|
|
380
380
|
let endIndex = 0;
|
|
381
381
|
let returnValue = "";
|
|
382
382
|
do {
|
|
383
|
-
returnValue +=
|
|
383
|
+
returnValue += string12.slice(endIndex, index) + substring + replacer;
|
|
384
384
|
endIndex = index + substringLength;
|
|
385
|
-
index =
|
|
385
|
+
index = string12.indexOf(substring, endIndex);
|
|
386
386
|
} while (index !== -1);
|
|
387
|
-
returnValue +=
|
|
387
|
+
returnValue += string12.slice(endIndex);
|
|
388
388
|
return returnValue;
|
|
389
389
|
}
|
|
390
|
-
function stringEncaseCRLFWithFirstIndex(
|
|
390
|
+
function stringEncaseCRLFWithFirstIndex(string12, prefix, postfix, index) {
|
|
391
391
|
let endIndex = 0;
|
|
392
392
|
let returnValue = "";
|
|
393
393
|
do {
|
|
394
|
-
const gotCR =
|
|
395
|
-
returnValue +=
|
|
394
|
+
const gotCR = string12[index - 1] === "\r";
|
|
395
|
+
returnValue += string12.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
396
396
|
endIndex = index + 1;
|
|
397
|
-
index =
|
|
397
|
+
index = string12.indexOf("\n", endIndex);
|
|
398
398
|
} while (index !== -1);
|
|
399
|
-
returnValue +=
|
|
399
|
+
returnValue += string12.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, string12) => {
|
|
559
|
+
if (self.level <= 0 || !string12) {
|
|
560
|
+
return self[IS_EMPTY] ? "" : string12;
|
|
561
561
|
}
|
|
562
562
|
let styler = self[STYLER];
|
|
563
563
|
if (styler === void 0) {
|
|
564
|
-
return
|
|
564
|
+
return string12;
|
|
565
565
|
}
|
|
566
566
|
const { openAll, closeAll } = styler;
|
|
567
|
-
if (
|
|
567
|
+
if (string12.includes("\x1B")) {
|
|
568
568
|
while (styler !== void 0) {
|
|
569
|
-
|
|
569
|
+
string12 = stringReplaceAll(string12, styler.close, styler.open);
|
|
570
570
|
styler = styler.parent;
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
|
-
const lfIndex =
|
|
573
|
+
const lfIndex = string12.indexOf("\n");
|
|
574
574
|
if (lfIndex !== -1) {
|
|
575
|
-
|
|
575
|
+
string12 = stringEncaseCRLFWithFirstIndex(string12, closeAll, openAll, lfIndex);
|
|
576
576
|
}
|
|
577
|
-
return openAll +
|
|
577
|
+
return openAll + string12 + 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 option8 of node.options) {
|
|
771
|
+
if (opts.shortNames.includes(option8.key)) {
|
|
772
|
+
result.push(option8);
|
|
773
773
|
}
|
|
774
774
|
}
|
|
775
775
|
}
|
|
@@ -842,7 +842,7 @@ var require_types = __commonJS({
|
|
|
842
842
|
"use strict";
|
|
843
843
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
844
844
|
exports2.boolean = exports2.string = exports2.number = void 0;
|
|
845
|
-
exports2.optional =
|
|
845
|
+
exports2.optional = optional8;
|
|
846
846
|
exports2.array = array3;
|
|
847
847
|
var type_1 = require_type();
|
|
848
848
|
exports2.number = {
|
|
@@ -869,7 +869,7 @@ var require_types = __commonJS({
|
|
|
869
869
|
return false;
|
|
870
870
|
}
|
|
871
871
|
};
|
|
872
|
-
function
|
|
872
|
+
function optional8(t) {
|
|
873
873
|
return {
|
|
874
874
|
...t,
|
|
875
875
|
defaultValue() {
|
|
@@ -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 option8 = 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(option8)}?`;
|
|
1409
1409
|
}
|
|
1410
1410
|
throw new Error(errorMessage);
|
|
1411
1411
|
}
|
|
@@ -1578,11 +1578,11 @@ var strip_ansi_exports = {};
|
|
|
1578
1578
|
__export(strip_ansi_exports, {
|
|
1579
1579
|
default: () => stripAnsi
|
|
1580
1580
|
});
|
|
1581
|
-
function stripAnsi(
|
|
1582
|
-
if (typeof
|
|
1583
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof
|
|
1581
|
+
function stripAnsi(string12) {
|
|
1582
|
+
if (typeof string12 !== "string") {
|
|
1583
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string12}\``);
|
|
1584
1584
|
}
|
|
1585
|
-
return
|
|
1585
|
+
return string12.replace(regex, "");
|
|
1586
1586
|
}
|
|
1587
1587
|
var regex;
|
|
1588
1588
|
var init_strip_ansi = __esm({
|
|
@@ -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 option8 of node.options) {
|
|
1785
|
+
if (context.visitedNodes.has(option8)) {
|
|
1786
1786
|
continue;
|
|
1787
1787
|
}
|
|
1788
|
-
unknownArguments.push(
|
|
1788
|
+
unknownArguments.push(option8);
|
|
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 = option8;
|
|
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 option9 = options[0];
|
|
1944
1944
|
let rawValue;
|
|
1945
1945
|
let envPrefix = "";
|
|
1946
|
-
if (
|
|
1947
|
-
rawValue =
|
|
1946
|
+
if (option9 === null || option9 === void 0 ? void 0 : option9.value) {
|
|
1947
|
+
rawValue = option9.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 = (option9 === null || option9 === void 0 ? void 0 : option9.type) === "shortOption" ? `-${option9 === null || option9 === void 0 ? void 0 : option9.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 option8(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 option8 of node.options) {
|
|
2044
|
+
if (error.nodes.includes(option8)) {
|
|
2045
|
+
s += chalk_1.default.red(option8.raw);
|
|
2046
2046
|
failed = true;
|
|
2047
2047
|
} else {
|
|
2048
|
-
s += chalk_1.default.dim(
|
|
2048
|
+
s += chalk_1.default.dim(option8.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, string12] of (0, utils_1.enumerate)(strings)) {
|
|
3088
|
+
const chars = [...string12];
|
|
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 option8 of options) {
|
|
3350
|
+
visitedNodes.add(option8);
|
|
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 option8 of options) {
|
|
3355
|
+
const decoded = await Result.safeAsync(flag_1.boolean.from((_b = (_a = option8.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: [option8], message: decoded.error.message });
|
|
3358
3358
|
} else {
|
|
3359
3359
|
optionValues.push(decoded.value);
|
|
3360
3360
|
}
|
|
@@ -3518,16 +3518,16 @@ var require_multioption = __commonJS({
|
|
|
3518
3518
|
});
|
|
3519
3519
|
}
|
|
3520
3520
|
}
|
|
3521
|
-
for (const
|
|
3522
|
-
visitedNodes.add(
|
|
3521
|
+
for (const option8 of options) {
|
|
3522
|
+
visitedNodes.add(option8);
|
|
3523
3523
|
}
|
|
3524
3524
|
const optionValues = [];
|
|
3525
3525
|
const errors = [];
|
|
3526
3526
|
const flagNodes = [];
|
|
3527
|
-
for (const
|
|
3528
|
-
const providedValue = (_a =
|
|
3527
|
+
for (const option8 of options) {
|
|
3528
|
+
const providedValue = (_a = option8.value) === null || _a === void 0 ? void 0 : _a.node.raw;
|
|
3529
3529
|
if (providedValue === void 0) {
|
|
3530
|
-
flagNodes.push(
|
|
3530
|
+
flagNodes.push(option8);
|
|
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.19.0",
|
|
3856
3856
|
description: "A command-line interface for Packmind linting and code quality checks",
|
|
3857
3857
|
private: false,
|
|
3858
3858
|
bin: {
|
|
@@ -6399,6 +6399,16 @@ var ChangeProposalGateway = class {
|
|
|
6399
6399
|
}
|
|
6400
6400
|
);
|
|
6401
6401
|
};
|
|
6402
|
+
this.check = async (command21) => {
|
|
6403
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6404
|
+
return this.httpClient.request(
|
|
6405
|
+
`/api/v0/organizations/${organizationId}/spaces/${command21.spaceId}/change-proposals/check`,
|
|
6406
|
+
{
|
|
6407
|
+
method: "POST",
|
|
6408
|
+
body: { proposals: command21.proposals }
|
|
6409
|
+
}
|
|
6410
|
+
);
|
|
6411
|
+
};
|
|
6402
6412
|
}
|
|
6403
6413
|
};
|
|
6404
6414
|
|
|
@@ -11427,6 +11437,70 @@ function normalizeScopeValue(rawValue) {
|
|
|
11427
11437
|
return rawValue.replace(/(?:^["'])|(?:["']$)/g, "");
|
|
11428
11438
|
}
|
|
11429
11439
|
|
|
11440
|
+
// apps/cli/src/application/utils/ruleSimilarity.ts
|
|
11441
|
+
var DEFAULT_SIMILARITY_THRESHOLD = 0.5;
|
|
11442
|
+
function matchUpdatedRules(deletedRules, addedRules, threshold = DEFAULT_SIMILARITY_THRESHOLD) {
|
|
11443
|
+
const updates = [];
|
|
11444
|
+
const usedDeleted = /* @__PURE__ */ new Set();
|
|
11445
|
+
const usedAdded = /* @__PURE__ */ new Set();
|
|
11446
|
+
const pairs = [];
|
|
11447
|
+
for (let d = 0; d < deletedRules.length; d++) {
|
|
11448
|
+
for (let a = 0; a < addedRules.length; a++) {
|
|
11449
|
+
const score = combinedSimilarity(deletedRules[d], addedRules[a]);
|
|
11450
|
+
if (score >= threshold) {
|
|
11451
|
+
pairs.push({ deletedIdx: d, addedIdx: a, score });
|
|
11452
|
+
}
|
|
11453
|
+
}
|
|
11454
|
+
}
|
|
11455
|
+
pairs.sort((a, b) => b.score - a.score);
|
|
11456
|
+
for (const pair of pairs) {
|
|
11457
|
+
if (usedDeleted.has(pair.deletedIdx) || usedAdded.has(pair.addedIdx))
|
|
11458
|
+
continue;
|
|
11459
|
+
usedDeleted.add(pair.deletedIdx);
|
|
11460
|
+
usedAdded.add(pair.addedIdx);
|
|
11461
|
+
updates.push({
|
|
11462
|
+
oldValue: deletedRules[pair.deletedIdx],
|
|
11463
|
+
newValue: addedRules[pair.addedIdx]
|
|
11464
|
+
});
|
|
11465
|
+
}
|
|
11466
|
+
const remainingDeleted = deletedRules.filter((_, i) => !usedDeleted.has(i));
|
|
11467
|
+
const remainingAdded = addedRules.filter((_, i) => !usedAdded.has(i));
|
|
11468
|
+
return { updates, remainingDeleted, remainingAdded };
|
|
11469
|
+
}
|
|
11470
|
+
function jaccardSimilarity(a, b) {
|
|
11471
|
+
const setA = new Set(a.toLowerCase().split(/\s+/).filter(Boolean));
|
|
11472
|
+
const setB = new Set(b.toLowerCase().split(/\s+/).filter(Boolean));
|
|
11473
|
+
if (setA.size === 0 && setB.size === 0) return 1;
|
|
11474
|
+
const intersection = new Set([...setA].filter((word) => setB.has(word)));
|
|
11475
|
+
const union = /* @__PURE__ */ new Set([...setA, ...setB]);
|
|
11476
|
+
return intersection.size / union.size;
|
|
11477
|
+
}
|
|
11478
|
+
function combinedSimilarity(a, b) {
|
|
11479
|
+
return Math.max(levenshteinSimilarity(a, b), jaccardSimilarity(a, b));
|
|
11480
|
+
}
|
|
11481
|
+
function levenshteinSimilarity(a, b) {
|
|
11482
|
+
const maxLen = Math.max(a.length, b.length);
|
|
11483
|
+
if (maxLen === 0) return 1;
|
|
11484
|
+
const matrix = [];
|
|
11485
|
+
for (let i = 0; i <= a.length; i++) {
|
|
11486
|
+
matrix[i] = [i];
|
|
11487
|
+
}
|
|
11488
|
+
for (let j = 0; j <= b.length; j++) {
|
|
11489
|
+
matrix[0][j] = j;
|
|
11490
|
+
}
|
|
11491
|
+
for (let i = 1; i <= a.length; i++) {
|
|
11492
|
+
for (let j = 1; j <= b.length; j++) {
|
|
11493
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
11494
|
+
matrix[i][j] = Math.min(
|
|
11495
|
+
matrix[i - 1][j] + 1,
|
|
11496
|
+
matrix[i][j - 1] + 1,
|
|
11497
|
+
matrix[i - 1][j - 1] + cost
|
|
11498
|
+
);
|
|
11499
|
+
}
|
|
11500
|
+
}
|
|
11501
|
+
return 1 - matrix[a.length][b.length] / maxLen;
|
|
11502
|
+
}
|
|
11503
|
+
|
|
11430
11504
|
// apps/cli/src/application/useCases/diffStrategies/StandardDiffStrategy.ts
|
|
11431
11505
|
var StandardDiffStrategy = class {
|
|
11432
11506
|
supports(file) {
|
|
@@ -11505,29 +11579,45 @@ var StandardDiffStrategy = class {
|
|
|
11505
11579
|
}
|
|
11506
11580
|
const serverRules = new Set(serverParsed.rules);
|
|
11507
11581
|
const localRules = new Set(localParsed.rules);
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11582
|
+
const deletedRules = [...serverRules].filter(
|
|
11583
|
+
(rule) => !localRules.has(rule)
|
|
11584
|
+
);
|
|
11585
|
+
const addedRules = [...localRules].filter((rule) => !serverRules.has(rule));
|
|
11586
|
+
const { updates, remainingDeleted, remainingAdded } = matchUpdatedRules(
|
|
11587
|
+
deletedRules,
|
|
11588
|
+
addedRules
|
|
11589
|
+
);
|
|
11590
|
+
for (const update of updates) {
|
|
11591
|
+
const ruleId = createRuleId("unresolved");
|
|
11592
|
+
diffs.push({
|
|
11593
|
+
...diffBase,
|
|
11594
|
+
type: "updateRule" /* updateRule */,
|
|
11595
|
+
payload: {
|
|
11596
|
+
targetId: ruleId,
|
|
11597
|
+
oldValue: update.oldValue,
|
|
11598
|
+
newValue: update.newValue
|
|
11599
|
+
}
|
|
11600
|
+
});
|
|
11520
11601
|
}
|
|
11521
|
-
for (const rule of
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
}
|
|
11529
|
-
}
|
|
11530
|
-
}
|
|
11602
|
+
for (const rule of remainingDeleted) {
|
|
11603
|
+
const ruleId = createRuleId("unresolved");
|
|
11604
|
+
diffs.push({
|
|
11605
|
+
...diffBase,
|
|
11606
|
+
type: "deleteRule" /* deleteRule */,
|
|
11607
|
+
payload: {
|
|
11608
|
+
targetId: ruleId,
|
|
11609
|
+
item: { id: ruleId, content: rule }
|
|
11610
|
+
}
|
|
11611
|
+
});
|
|
11612
|
+
}
|
|
11613
|
+
for (const rule of remainingAdded) {
|
|
11614
|
+
diffs.push({
|
|
11615
|
+
...diffBase,
|
|
11616
|
+
type: "addRule" /* addRule */,
|
|
11617
|
+
payload: {
|
|
11618
|
+
item: { content: rule }
|
|
11619
|
+
}
|
|
11620
|
+
});
|
|
11531
11621
|
}
|
|
11532
11622
|
return diffs;
|
|
11533
11623
|
}
|
|
@@ -11605,7 +11695,7 @@ var SubmitDiffsUseCase = class {
|
|
|
11605
11695
|
this.packmindGateway = packmindGateway;
|
|
11606
11696
|
}
|
|
11607
11697
|
async execute(command21) {
|
|
11608
|
-
const { groupedDiffs } = command21;
|
|
11698
|
+
const { groupedDiffs, message } = command21;
|
|
11609
11699
|
const skipped = [];
|
|
11610
11700
|
const validDiffs = [];
|
|
11611
11701
|
for (const group of groupedDiffs) {
|
|
@@ -11647,7 +11737,8 @@ var SubmitDiffsUseCase = class {
|
|
|
11647
11737
|
type: diff.type,
|
|
11648
11738
|
artefactId: diff.artifactId,
|
|
11649
11739
|
payload: diff.payload,
|
|
11650
|
-
captureMode: "commit" /* commit
|
|
11740
|
+
captureMode: "commit" /* commit */,
|
|
11741
|
+
message
|
|
11651
11742
|
}))
|
|
11652
11743
|
});
|
|
11653
11744
|
submitted += response.created;
|
|
@@ -11665,6 +11756,68 @@ var SubmitDiffsUseCase = class {
|
|
|
11665
11756
|
}
|
|
11666
11757
|
};
|
|
11667
11758
|
|
|
11759
|
+
// apps/cli/src/application/useCases/CheckDiffsUseCase.ts
|
|
11760
|
+
var SUPPORTED_ARTIFACT_TYPES2 = /* @__PURE__ */ new Set(["command", "skill", "standard"]);
|
|
11761
|
+
var CheckDiffsUseCase = class {
|
|
11762
|
+
constructor(packmindGateway) {
|
|
11763
|
+
this.packmindGateway = packmindGateway;
|
|
11764
|
+
}
|
|
11765
|
+
async execute(command21) {
|
|
11766
|
+
const { groupedDiffs } = command21;
|
|
11767
|
+
const results = [];
|
|
11768
|
+
const validDiffs = [];
|
|
11769
|
+
const invalidDiffs = [];
|
|
11770
|
+
for (const group of groupedDiffs) {
|
|
11771
|
+
for (const diff of group) {
|
|
11772
|
+
if (!SUPPORTED_ARTIFACT_TYPES2.has(diff.artifactType) || !diff.artifactId || !diff.spaceId) {
|
|
11773
|
+
invalidDiffs.push(diff);
|
|
11774
|
+
continue;
|
|
11775
|
+
}
|
|
11776
|
+
validDiffs.push(diff);
|
|
11777
|
+
}
|
|
11778
|
+
}
|
|
11779
|
+
const diffsBySpaceId = /* @__PURE__ */ new Map();
|
|
11780
|
+
for (const diff of validDiffs) {
|
|
11781
|
+
const existing = diffsBySpaceId.get(diff.spaceId) ?? [];
|
|
11782
|
+
existing.push(diff);
|
|
11783
|
+
diffsBySpaceId.set(diff.spaceId, existing);
|
|
11784
|
+
}
|
|
11785
|
+
const checkedMap = /* @__PURE__ */ new Map();
|
|
11786
|
+
for (const [spaceId, diffs] of diffsBySpaceId) {
|
|
11787
|
+
const response = await this.packmindGateway.changeProposals.check({
|
|
11788
|
+
spaceId,
|
|
11789
|
+
proposals: diffs.map((diff) => ({
|
|
11790
|
+
type: diff.type,
|
|
11791
|
+
artefactId: diff.artifactId,
|
|
11792
|
+
payload: diff.payload,
|
|
11793
|
+
captureMode: "commit" /* commit */,
|
|
11794
|
+
message: ""
|
|
11795
|
+
}))
|
|
11796
|
+
});
|
|
11797
|
+
for (const result of response.results) {
|
|
11798
|
+
const diff = diffs[result.index];
|
|
11799
|
+
checkedMap.set(diff, {
|
|
11800
|
+
diff,
|
|
11801
|
+
exists: result.exists,
|
|
11802
|
+
createdAt: result.createdAt,
|
|
11803
|
+
message: result.message
|
|
11804
|
+
});
|
|
11805
|
+
}
|
|
11806
|
+
}
|
|
11807
|
+
for (const group of groupedDiffs) {
|
|
11808
|
+
for (const diff of group) {
|
|
11809
|
+
const checked = checkedMap.get(diff);
|
|
11810
|
+
if (checked) {
|
|
11811
|
+
results.push(checked);
|
|
11812
|
+
} else {
|
|
11813
|
+
results.push({ diff, exists: false, createdAt: null, message: null });
|
|
11814
|
+
}
|
|
11815
|
+
}
|
|
11816
|
+
}
|
|
11817
|
+
return { results };
|
|
11818
|
+
}
|
|
11819
|
+
};
|
|
11820
|
+
|
|
11668
11821
|
// apps/cli/src/PackmindCliHexaFactory.ts
|
|
11669
11822
|
var PackmindCliHexaFactory = class {
|
|
11670
11823
|
constructor() {
|
|
@@ -11718,7 +11871,8 @@ var PackmindCliHexaFactory = class {
|
|
|
11718
11871
|
diffArtefacts: new DiffArtefactsUseCase(
|
|
11719
11872
|
this.repositories.packmindGateway
|
|
11720
11873
|
),
|
|
11721
|
-
submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway)
|
|
11874
|
+
submitDiffs: new SubmitDiffsUseCase(this.repositories.packmindGateway),
|
|
11875
|
+
checkDiffs: new CheckDiffsUseCase(this.repositories.packmindGateway)
|
|
11722
11876
|
};
|
|
11723
11877
|
}
|
|
11724
11878
|
};
|
|
@@ -11770,8 +11924,11 @@ var PackmindCliHexa = class {
|
|
|
11770
11924
|
async diffArtefacts(command21) {
|
|
11771
11925
|
return this.hexa.useCases.diffArtefacts.execute(command21);
|
|
11772
11926
|
}
|
|
11773
|
-
async submitDiffs(groupedDiffs) {
|
|
11774
|
-
return this.hexa.useCases.submitDiffs.execute({ groupedDiffs });
|
|
11927
|
+
async submitDiffs(groupedDiffs, message) {
|
|
11928
|
+
return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
|
|
11929
|
+
}
|
|
11930
|
+
async checkDiffs(groupedDiffs) {
|
|
11931
|
+
return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
|
|
11775
11932
|
}
|
|
11776
11933
|
async listPackages(command21) {
|
|
11777
11934
|
return this.hexa.useCases.listPackages.execute(command21);
|
|
@@ -13873,21 +14030,24 @@ function validatePlaybook(data) {
|
|
|
13873
14030
|
}
|
|
13874
14031
|
|
|
13875
14032
|
// apps/cli/src/infra/utils/readPlaybookFile.ts
|
|
14033
|
+
function parseAndValidatePlaybook(content) {
|
|
14034
|
+
let parsed;
|
|
14035
|
+
try {
|
|
14036
|
+
parsed = JSON.parse(content);
|
|
14037
|
+
} catch (e) {
|
|
14038
|
+
return {
|
|
14039
|
+
isValid: false,
|
|
14040
|
+
errors: [
|
|
14041
|
+
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
14042
|
+
]
|
|
14043
|
+
};
|
|
14044
|
+
}
|
|
14045
|
+
return validatePlaybook(parsed);
|
|
14046
|
+
}
|
|
13876
14047
|
async function readPlaybookFile(filePath) {
|
|
13877
14048
|
try {
|
|
13878
14049
|
const content = await fs16.readFile(filePath, "utf-8");
|
|
13879
|
-
|
|
13880
|
-
try {
|
|
13881
|
-
parsed = JSON.parse(content);
|
|
13882
|
-
} catch (e) {
|
|
13883
|
-
return {
|
|
13884
|
-
isValid: false,
|
|
13885
|
-
errors: [
|
|
13886
|
-
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13887
|
-
]
|
|
13888
|
-
};
|
|
13889
|
-
}
|
|
13890
|
-
return validatePlaybook(parsed);
|
|
14050
|
+
return parseAndValidatePlaybook(content);
|
|
13891
14051
|
} catch (e) {
|
|
13892
14052
|
return {
|
|
13893
14053
|
isValid: false,
|
|
@@ -13898,9 +14058,40 @@ async function readPlaybookFile(filePath) {
|
|
|
13898
14058
|
}
|
|
13899
14059
|
}
|
|
13900
14060
|
|
|
14061
|
+
// apps/cli/src/infra/utils/readStdin.ts
|
|
14062
|
+
async function readStdin(input = process.stdin) {
|
|
14063
|
+
if ("isTTY" in input && input.isTTY) {
|
|
14064
|
+
throw new Error(
|
|
14065
|
+
"No piped input detected. Please provide content via stdin or specify a file path."
|
|
14066
|
+
);
|
|
14067
|
+
}
|
|
14068
|
+
const chunks = [];
|
|
14069
|
+
for await (const chunk of input) {
|
|
14070
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
14071
|
+
}
|
|
14072
|
+
const content = Buffer.concat(chunks).toString("utf-8").trim();
|
|
14073
|
+
if (!content) {
|
|
14074
|
+
throw new Error("Stdin is empty. Please provide JSON content via pipe.");
|
|
14075
|
+
}
|
|
14076
|
+
return content;
|
|
14077
|
+
}
|
|
14078
|
+
|
|
13901
14079
|
// apps/cli/src/infra/commands/createStandardHandler.ts
|
|
13902
14080
|
async function createStandardHandler(filePath, useCase, originSkill) {
|
|
13903
|
-
|
|
14081
|
+
let readResult;
|
|
14082
|
+
if (filePath) {
|
|
14083
|
+
readResult = await readPlaybookFile(filePath);
|
|
14084
|
+
} else {
|
|
14085
|
+
try {
|
|
14086
|
+
const content = await readStdin();
|
|
14087
|
+
readResult = parseAndValidatePlaybook(content);
|
|
14088
|
+
} catch (e) {
|
|
14089
|
+
return {
|
|
14090
|
+
success: false,
|
|
14091
|
+
error: e instanceof Error ? e.message : "Failed to read from stdin"
|
|
14092
|
+
};
|
|
14093
|
+
}
|
|
14094
|
+
}
|
|
13904
14095
|
if (!readResult.isValid) {
|
|
13905
14096
|
return {
|
|
13906
14097
|
success: false,
|
|
@@ -13961,12 +14152,12 @@ var CreateStandardFromPlaybookUseCase = class {
|
|
|
13961
14152
|
// apps/cli/src/infra/commands/CreateStandardCommand.ts
|
|
13962
14153
|
var createStandardCommand = (0, import_cmd_ts13.command)({
|
|
13963
14154
|
name: "create",
|
|
13964
|
-
description: "Create a coding standard from a playbook JSON file",
|
|
14155
|
+
description: "Create a coding standard from a playbook JSON file or stdin",
|
|
13965
14156
|
args: {
|
|
13966
14157
|
file: (0, import_cmd_ts13.positional)({
|
|
13967
14158
|
displayName: "file",
|
|
13968
|
-
description: "Path to the playbook JSON file",
|
|
13969
|
-
type: import_cmd_ts13.string
|
|
14159
|
+
description: "Path to the playbook JSON file (reads from stdin if omitted)",
|
|
14160
|
+
type: (0, import_cmd_ts13.optional)(import_cmd_ts13.string)
|
|
13970
14161
|
}),
|
|
13971
14162
|
originSkill: originSkillOption
|
|
13972
14163
|
},
|
|
@@ -14127,21 +14318,24 @@ function validateCommandPlaybook(data) {
|
|
|
14127
14318
|
}
|
|
14128
14319
|
|
|
14129
14320
|
// apps/cli/src/infra/utils/readCommandPlaybookFile.ts
|
|
14321
|
+
function parseAndValidateCommandPlaybook(content) {
|
|
14322
|
+
let parsed;
|
|
14323
|
+
try {
|
|
14324
|
+
parsed = JSON.parse(content);
|
|
14325
|
+
} catch (e) {
|
|
14326
|
+
return {
|
|
14327
|
+
isValid: false,
|
|
14328
|
+
errors: [
|
|
14329
|
+
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
14330
|
+
]
|
|
14331
|
+
};
|
|
14332
|
+
}
|
|
14333
|
+
return validateCommandPlaybook(parsed);
|
|
14334
|
+
}
|
|
14130
14335
|
async function readCommandPlaybookFile(filePath) {
|
|
14131
14336
|
try {
|
|
14132
14337
|
const content = await fs17.readFile(filePath, "utf-8");
|
|
14133
|
-
|
|
14134
|
-
try {
|
|
14135
|
-
parsed = JSON.parse(content);
|
|
14136
|
-
} catch (e) {
|
|
14137
|
-
return {
|
|
14138
|
-
isValid: false,
|
|
14139
|
-
errors: [
|
|
14140
|
-
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
14141
|
-
]
|
|
14142
|
-
};
|
|
14143
|
-
}
|
|
14144
|
-
return validateCommandPlaybook(parsed);
|
|
14338
|
+
return parseAndValidateCommandPlaybook(content);
|
|
14145
14339
|
} catch (e) {
|
|
14146
14340
|
return {
|
|
14147
14341
|
isValid: false,
|
|
@@ -14157,7 +14351,20 @@ function buildWebappUrl(host, orgSlug, commandId) {
|
|
|
14157
14351
|
return `${host}/org/${orgSlug}/space/global/commands/${commandId}`;
|
|
14158
14352
|
}
|
|
14159
14353
|
async function createCommandHandler(filePath, useCase, originSkill) {
|
|
14160
|
-
|
|
14354
|
+
let readResult;
|
|
14355
|
+
if (filePath) {
|
|
14356
|
+
readResult = await readCommandPlaybookFile(filePath);
|
|
14357
|
+
} else {
|
|
14358
|
+
try {
|
|
14359
|
+
const content = await readStdin();
|
|
14360
|
+
readResult = parseAndValidateCommandPlaybook(content);
|
|
14361
|
+
} catch (e) {
|
|
14362
|
+
return {
|
|
14363
|
+
success: false,
|
|
14364
|
+
error: e instanceof Error ? e.message : "Failed to read from stdin"
|
|
14365
|
+
};
|
|
14366
|
+
}
|
|
14367
|
+
}
|
|
14161
14368
|
if (!readResult.isValid) {
|
|
14162
14369
|
return {
|
|
14163
14370
|
success: false,
|
|
@@ -14232,12 +14439,12 @@ var CreateCommandFromPlaybookUseCase = class {
|
|
|
14232
14439
|
// apps/cli/src/infra/commands/CreateCommandCommand.ts
|
|
14233
14440
|
var createCommandCommand = (0, import_cmd_ts16.command)({
|
|
14234
14441
|
name: "create",
|
|
14235
|
-
description: "Create a command from a playbook JSON file",
|
|
14442
|
+
description: "Create a command from a playbook JSON file or stdin",
|
|
14236
14443
|
args: {
|
|
14237
14444
|
file: (0, import_cmd_ts16.positional)({
|
|
14238
14445
|
displayName: "file",
|
|
14239
|
-
description: "Path to the command playbook JSON file",
|
|
14240
|
-
type: import_cmd_ts16.string
|
|
14446
|
+
description: "Path to the command playbook JSON file (reads from stdin if omitted)",
|
|
14447
|
+
type: (0, import_cmd_ts16.optional)(import_cmd_ts16.string)
|
|
14241
14448
|
}),
|
|
14242
14449
|
originSkill: originSkillOption
|
|
14243
14450
|
},
|
|
@@ -14379,6 +14586,51 @@ function formatContentDiff(oldContent, newContent) {
|
|
|
14379
14586
|
};
|
|
14380
14587
|
}
|
|
14381
14588
|
|
|
14589
|
+
// apps/cli/src/infra/utils/editorMessage.ts
|
|
14590
|
+
var import_child_process4 = require("child_process");
|
|
14591
|
+
var import_fs19 = require("fs");
|
|
14592
|
+
var import_os2 = require("os");
|
|
14593
|
+
var import_path4 = require("path");
|
|
14594
|
+
var MAX_MESSAGE_LENGTH = 1024;
|
|
14595
|
+
var EDITOR_TEMPLATE = `
|
|
14596
|
+
# Enter a message describing the intent behind these changes.
|
|
14597
|
+
# Lines starting with '#' will be ignored.
|
|
14598
|
+
# An empty message aborts the submission.
|
|
14599
|
+
`;
|
|
14600
|
+
function openEditorForMessage() {
|
|
14601
|
+
const tmpFile = (0, import_path4.join)((0, import_os2.tmpdir)(), `packmind-msg-${Date.now()}.txt`);
|
|
14602
|
+
try {
|
|
14603
|
+
(0, import_fs19.writeFileSync)(tmpFile, EDITOR_TEMPLATE, "utf-8");
|
|
14604
|
+
const editor = process.env.EDITOR || process.env.VISUAL || "vi";
|
|
14605
|
+
const result = (0, import_child_process4.spawnSync)(editor, [tmpFile], {
|
|
14606
|
+
stdio: "inherit"
|
|
14607
|
+
});
|
|
14608
|
+
if (result.status !== 0) {
|
|
14609
|
+
throw new Error(`Editor exited with status ${result.status}`);
|
|
14610
|
+
}
|
|
14611
|
+
const content = (0, import_fs19.readFileSync)(tmpFile, "utf-8");
|
|
14612
|
+
return content.split("\n").filter((line) => !line.startsWith("#")).join("\n").trim();
|
|
14613
|
+
} finally {
|
|
14614
|
+
try {
|
|
14615
|
+
(0, import_fs19.unlinkSync)(tmpFile);
|
|
14616
|
+
} catch {
|
|
14617
|
+
}
|
|
14618
|
+
}
|
|
14619
|
+
}
|
|
14620
|
+
function validateMessage(message) {
|
|
14621
|
+
const trimmed = message.trim();
|
|
14622
|
+
if (trimmed.length === 0) {
|
|
14623
|
+
return { valid: false, error: "Message cannot be empty." };
|
|
14624
|
+
}
|
|
14625
|
+
if (trimmed.length > MAX_MESSAGE_LENGTH) {
|
|
14626
|
+
return {
|
|
14627
|
+
valid: false,
|
|
14628
|
+
error: `Message exceeds maximum length of ${MAX_MESSAGE_LENGTH} characters (got ${trimmed.length}).`
|
|
14629
|
+
};
|
|
14630
|
+
}
|
|
14631
|
+
return { valid: true, message: trimmed };
|
|
14632
|
+
}
|
|
14633
|
+
|
|
14382
14634
|
// apps/cli/src/infra/commands/diffArtefactsHandler.ts
|
|
14383
14635
|
init_source();
|
|
14384
14636
|
var ARTIFACT_TYPE_LABELS = {
|
|
@@ -14461,8 +14713,27 @@ function formatDiffPayload(diff, log) {
|
|
|
14461
14713
|
log(line);
|
|
14462
14714
|
}
|
|
14463
14715
|
}
|
|
14464
|
-
|
|
14465
|
-
const
|
|
14716
|
+
function formatSubmittedDate(isoDate) {
|
|
14717
|
+
const date = new Date(isoDate);
|
|
14718
|
+
const datePart = date.toLocaleDateString("en-US", {
|
|
14719
|
+
year: "numeric",
|
|
14720
|
+
month: "short",
|
|
14721
|
+
day: "numeric"
|
|
14722
|
+
});
|
|
14723
|
+
const timePart = date.toLocaleTimeString("en-US", {
|
|
14724
|
+
hour: "numeric",
|
|
14725
|
+
minute: "2-digit",
|
|
14726
|
+
hour12: true
|
|
14727
|
+
});
|
|
14728
|
+
return `${datePart} ${timePart}`;
|
|
14729
|
+
}
|
|
14730
|
+
function buildSubmittedFooter(submittedDiffs) {
|
|
14731
|
+
const proposalCount = submittedDiffs.length;
|
|
14732
|
+
const proposalWord = proposalCount === 1 ? "change proposal" : "change proposals";
|
|
14733
|
+
return `${proposalCount} ${proposalWord} ignored, run \`packmind-cli diff --include-submitted\` to see what's waiting for validation`;
|
|
14734
|
+
}
|
|
14735
|
+
async function readConfigAndPackages(deps) {
|
|
14736
|
+
const { packmindCliHexa, exit, getCwd, log, error } = deps;
|
|
14466
14737
|
const cwd = getCwd();
|
|
14467
14738
|
let configPackages;
|
|
14468
14739
|
let configAgents;
|
|
@@ -14483,7 +14754,7 @@ async function diffArtefactsHandler(deps) {
|
|
|
14483
14754
|
}
|
|
14484
14755
|
error("\n\u{1F4A1} Please fix the packmind.json file or delete it to continue.");
|
|
14485
14756
|
exit(1);
|
|
14486
|
-
return
|
|
14757
|
+
return null;
|
|
14487
14758
|
}
|
|
14488
14759
|
if (configPackages.length === 0) {
|
|
14489
14760
|
log("Usage: packmind-cli diff");
|
|
@@ -14491,37 +14762,219 @@ async function diffArtefactsHandler(deps) {
|
|
|
14491
14762
|
log("Compare local command files against the server.");
|
|
14492
14763
|
log("Configure packages in packmind.json first.");
|
|
14493
14764
|
exit(0);
|
|
14494
|
-
return
|
|
14765
|
+
return null;
|
|
14495
14766
|
}
|
|
14496
|
-
|
|
14497
|
-
|
|
14498
|
-
|
|
14499
|
-
|
|
14500
|
-
|
|
14501
|
-
|
|
14502
|
-
|
|
14503
|
-
|
|
14504
|
-
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14508
|
-
|
|
14509
|
-
|
|
14510
|
-
|
|
14511
|
-
|
|
14512
|
-
} catch (err) {
|
|
14513
|
-
logWarningConsole(
|
|
14514
|
-
`Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
|
|
14515
|
-
);
|
|
14767
|
+
return { configPackages, configAgents };
|
|
14768
|
+
}
|
|
14769
|
+
async function collectGitInfo(deps) {
|
|
14770
|
+
const { packmindCliHexa, exit, getCwd, error } = deps;
|
|
14771
|
+
const cwd = getCwd();
|
|
14772
|
+
let gitRemoteUrl;
|
|
14773
|
+
let gitBranch;
|
|
14774
|
+
let relativePath;
|
|
14775
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
14776
|
+
if (gitRoot) {
|
|
14777
|
+
try {
|
|
14778
|
+
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
14779
|
+
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
14780
|
+
relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
14781
|
+
if (!relativePath.startsWith("/")) {
|
|
14782
|
+
relativePath = "/" + relativePath;
|
|
14516
14783
|
}
|
|
14784
|
+
if (!relativePath.endsWith("/")) {
|
|
14785
|
+
relativePath = relativePath + "/";
|
|
14786
|
+
}
|
|
14787
|
+
} catch (err) {
|
|
14788
|
+
logWarningConsole(
|
|
14789
|
+
`Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
|
|
14790
|
+
);
|
|
14791
|
+
}
|
|
14792
|
+
}
|
|
14793
|
+
if (!gitRemoteUrl || !gitBranch || !relativePath) {
|
|
14794
|
+
error(
|
|
14795
|
+
"\n\u274C Could not determine git repository info. The diff command requires a git repository with a remote configured."
|
|
14796
|
+
);
|
|
14797
|
+
exit(1);
|
|
14798
|
+
return null;
|
|
14799
|
+
}
|
|
14800
|
+
return { gitRemoteUrl, gitBranch, relativePath };
|
|
14801
|
+
}
|
|
14802
|
+
async function handleSubmission(params) {
|
|
14803
|
+
const { packmindCliHexa, unsubmittedItems, messageFlag, exit } = params;
|
|
14804
|
+
const unsubmittedDiffs = unsubmittedItems.map((r) => r.diff);
|
|
14805
|
+
if (unsubmittedDiffs.length === 0) {
|
|
14806
|
+
logInfoConsole("All changes already submitted.");
|
|
14807
|
+
return false;
|
|
14808
|
+
}
|
|
14809
|
+
let message;
|
|
14810
|
+
if (messageFlag !== void 0) {
|
|
14811
|
+
const validation = validateMessage(messageFlag);
|
|
14812
|
+
if (!validation.valid) {
|
|
14813
|
+
logErrorConsole(validation.error);
|
|
14814
|
+
exit(1);
|
|
14815
|
+
return true;
|
|
14517
14816
|
}
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14817
|
+
message = validation.message;
|
|
14818
|
+
} else if (process.stdin.isTTY) {
|
|
14819
|
+
const editorMessage = openEditorForMessage();
|
|
14820
|
+
const validation = validateMessage(editorMessage);
|
|
14821
|
+
if (!validation.valid) {
|
|
14822
|
+
logErrorConsole(
|
|
14823
|
+
"Aborting submission: empty message. Use -m to provide a message."
|
|
14521
14824
|
);
|
|
14522
14825
|
exit(1);
|
|
14826
|
+
return true;
|
|
14827
|
+
}
|
|
14828
|
+
message = validation.message;
|
|
14829
|
+
} else {
|
|
14830
|
+
logErrorConsole(
|
|
14831
|
+
'Non-interactive mode requires -m flag. Use: packmind-cli diff --submit -m "your message"'
|
|
14832
|
+
);
|
|
14833
|
+
exit(1);
|
|
14834
|
+
return true;
|
|
14835
|
+
}
|
|
14836
|
+
const groupedUnsubmitted = Array.from(
|
|
14837
|
+
groupDiffsByArtefact(unsubmittedDiffs).values()
|
|
14838
|
+
);
|
|
14839
|
+
const result = await packmindCliHexa.submitDiffs(groupedUnsubmitted, message);
|
|
14840
|
+
for (const err of result.errors) {
|
|
14841
|
+
if (err.code === "ChangeProposalPayloadMismatchError") {
|
|
14842
|
+
logErrorConsole(
|
|
14843
|
+
`Failed to submit "${err.name}": ${err.artifactType ?? "artifact"} is outdated, please run \`packmind-cli install\` to update it`
|
|
14844
|
+
);
|
|
14845
|
+
} else {
|
|
14846
|
+
logErrorConsole(`Failed to submit "${err.name}": ${err.message}`);
|
|
14847
|
+
}
|
|
14848
|
+
}
|
|
14849
|
+
if (result.submitted > 0) {
|
|
14850
|
+
const truncatedMessage = message.length > 50 ? message.slice(0, 50) + "..." : message;
|
|
14851
|
+
logInfoConsole(`Message: "${truncatedMessage}"`);
|
|
14852
|
+
}
|
|
14853
|
+
const summaryParts = [];
|
|
14854
|
+
if (result.submitted > 0) {
|
|
14855
|
+
summaryParts.push(`${result.submitted} submitted`);
|
|
14856
|
+
}
|
|
14857
|
+
if (result.alreadySubmitted > 0) {
|
|
14858
|
+
summaryParts.push(`${result.alreadySubmitted} already submitted`);
|
|
14859
|
+
}
|
|
14860
|
+
if (result.errors.length > 0) {
|
|
14861
|
+
const errorWord = result.errors.length === 1 ? "error" : "errors";
|
|
14862
|
+
summaryParts.push(`${result.errors.length} ${errorWord}`);
|
|
14863
|
+
}
|
|
14864
|
+
if (summaryParts.length > 0) {
|
|
14865
|
+
const summaryMessage = `Summary: ${summaryParts.join(", ")}`;
|
|
14866
|
+
if (result.errors.length === 0 && result.alreadySubmitted === 0) {
|
|
14867
|
+
logSuccessConsole(summaryMessage);
|
|
14868
|
+
} else if (result.errors.length > 0 && result.submitted > 0 || result.alreadySubmitted > 0) {
|
|
14869
|
+
logWarningConsole(summaryMessage);
|
|
14870
|
+
} else {
|
|
14871
|
+
logErrorConsole(summaryMessage);
|
|
14872
|
+
}
|
|
14873
|
+
}
|
|
14874
|
+
return false;
|
|
14875
|
+
}
|
|
14876
|
+
function extractUniqueAndSortedArtefacts(groups) {
|
|
14877
|
+
const typeSortOrder = {
|
|
14878
|
+
command: 0,
|
|
14879
|
+
skill: 1,
|
|
14880
|
+
standard: 2
|
|
14881
|
+
};
|
|
14882
|
+
const uniqueArtefacts = /* @__PURE__ */ new Map();
|
|
14883
|
+
for (const [key, groupDiffs] of groups) {
|
|
14884
|
+
if (!uniqueArtefacts.has(key)) {
|
|
14885
|
+
uniqueArtefacts.set(key, {
|
|
14886
|
+
type: groupDiffs[0].artifactType,
|
|
14887
|
+
name: groupDiffs[0].artifactName
|
|
14888
|
+
});
|
|
14889
|
+
}
|
|
14890
|
+
}
|
|
14891
|
+
const sortedArtefacts = Array.from(uniqueArtefacts.values()).sort(
|
|
14892
|
+
(a, b) => typeSortOrder[a.type] - typeSortOrder[b.type] || a.name.localeCompare(b.name, void 0, { sensitivity: "base" })
|
|
14893
|
+
);
|
|
14894
|
+
return sortedArtefacts;
|
|
14895
|
+
}
|
|
14896
|
+
function displayDiffs(params) {
|
|
14897
|
+
const {
|
|
14898
|
+
diffsToDisplay,
|
|
14899
|
+
submittedLookup,
|
|
14900
|
+
includeSubmitted,
|
|
14901
|
+
unsubmittedItems,
|
|
14902
|
+
submittedItems,
|
|
14903
|
+
log
|
|
14904
|
+
} = params;
|
|
14905
|
+
log(formatHeader(`
|
|
14906
|
+
Changes found:
|
|
14907
|
+
`));
|
|
14908
|
+
const groups = groupDiffsByArtefact(diffsToDisplay);
|
|
14909
|
+
for (const [, groupDiffs] of groups) {
|
|
14910
|
+
const { artifactType, artifactName } = groupDiffs[0];
|
|
14911
|
+
const typeLabel = ARTIFACT_TYPE_LABELS[artifactType];
|
|
14912
|
+
log(formatBold(`${typeLabel} "${artifactName}"`));
|
|
14913
|
+
const subGroups = subGroupByChangeContent(groupDiffs);
|
|
14914
|
+
for (const subGroup of subGroups) {
|
|
14915
|
+
for (const diff of subGroup) {
|
|
14916
|
+
log(` ${formatFilePath(diff.filePath)}`);
|
|
14917
|
+
}
|
|
14918
|
+
const label = CHANGE_PROPOSAL_TYPE_LABELS[subGroup[0].type] ?? "content changed";
|
|
14919
|
+
const checkItem = submittedLookup.get(subGroup[0]);
|
|
14920
|
+
if (includeSubmitted && checkItem?.exists && checkItem.createdAt) {
|
|
14921
|
+
const dateStr = formatSubmittedDate(checkItem.createdAt);
|
|
14922
|
+
const messageSuffix = checkItem.message ? ` "${checkItem.message.length > 50 ? checkItem.message.slice(0, 50) + "..." : checkItem.message}"` : "";
|
|
14923
|
+
log(
|
|
14924
|
+
` - ${label} ${source_default.dim(`[already submitted on ${dateStr}${messageSuffix}]`)}`
|
|
14925
|
+
);
|
|
14926
|
+
} else {
|
|
14927
|
+
log(` - ${label}`);
|
|
14928
|
+
}
|
|
14929
|
+
formatDiffPayload(subGroup[0], log);
|
|
14930
|
+
}
|
|
14931
|
+
log("");
|
|
14932
|
+
}
|
|
14933
|
+
const changeCount = diffsToDisplay.length;
|
|
14934
|
+
const changeWord = changeCount === 1 ? "change" : "changes";
|
|
14935
|
+
const sortedArtefacts = extractUniqueAndSortedArtefacts(groups);
|
|
14936
|
+
const artefactCount = sortedArtefacts.length;
|
|
14937
|
+
const artefactWord = artefactCount === 1 ? "artefact" : "artefacts";
|
|
14938
|
+
const allSubmittedSuffix = includeSubmitted && unsubmittedItems.length === 0 ? " (all already submitted)" : "";
|
|
14939
|
+
logWarningConsole(
|
|
14940
|
+
`Summary: ${changeCount} ${changeWord} found on ${artefactCount} ${artefactWord}${allSubmittedSuffix}:`
|
|
14941
|
+
);
|
|
14942
|
+
for (const artefact of sortedArtefacts) {
|
|
14943
|
+
const typeLabel = ARTIFACT_TYPE_LABELS[artefact.type];
|
|
14944
|
+
const key = `${artefact.type}:${artefact.name}`;
|
|
14945
|
+
const artefactDiffs = groups.get(key) ?? [];
|
|
14946
|
+
const allDiffsSubmitted = includeSubmitted && artefactDiffs.length > 0 && artefactDiffs.every((d) => submittedLookup.get(d)?.exists);
|
|
14947
|
+
const suffix = allDiffsSubmitted ? " (all already submitted)" : "";
|
|
14948
|
+
logWarningConsole(`* ${typeLabel} "${artefact.name}"${suffix}`);
|
|
14949
|
+
}
|
|
14950
|
+
if (!includeSubmitted && submittedItems.length > 0) {
|
|
14951
|
+
logInfoConsole(buildSubmittedFooter(submittedItems));
|
|
14952
|
+
}
|
|
14953
|
+
return changeCount;
|
|
14954
|
+
}
|
|
14955
|
+
async function diffArtefactsHandler(deps) {
|
|
14956
|
+
const {
|
|
14957
|
+
packmindCliHexa,
|
|
14958
|
+
exit,
|
|
14959
|
+
getCwd,
|
|
14960
|
+
log,
|
|
14961
|
+
error,
|
|
14962
|
+
submit,
|
|
14963
|
+
includeSubmitted,
|
|
14964
|
+
message: messageFlag
|
|
14965
|
+
} = deps;
|
|
14966
|
+
const cwd = getCwd();
|
|
14967
|
+
const config = await readConfigAndPackages(deps);
|
|
14968
|
+
if (!config) {
|
|
14969
|
+
return { diffsFound: 0 };
|
|
14970
|
+
}
|
|
14971
|
+
const { configPackages, configAgents } = config;
|
|
14972
|
+
try {
|
|
14973
|
+
const gitInfo = await collectGitInfo(deps);
|
|
14974
|
+
if (!gitInfo) {
|
|
14523
14975
|
return { diffsFound: 0 };
|
|
14524
14976
|
}
|
|
14977
|
+
const { gitRemoteUrl, gitBranch, relativePath } = gitInfo;
|
|
14525
14978
|
const packageCount = configPackages.length;
|
|
14526
14979
|
const packageWord = packageCount === 1 ? "package" : "packages";
|
|
14527
14980
|
logInfoConsole(
|
|
@@ -14543,85 +14996,43 @@ async function diffArtefactsHandler(deps) {
|
|
|
14543
14996
|
exit(0);
|
|
14544
14997
|
return { diffsFound: 0 };
|
|
14545
14998
|
}
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
const
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14553
|
-
|
|
14554
|
-
const subGroups = subGroupByChangeContent(groupDiffs);
|
|
14555
|
-
for (const subGroup of subGroups) {
|
|
14556
|
-
for (const diff of subGroup) {
|
|
14557
|
-
log(` ${formatFilePath(diff.filePath)}`);
|
|
14558
|
-
}
|
|
14559
|
-
const label = CHANGE_PROPOSAL_TYPE_LABELS[subGroup[0].type] ?? "content changed";
|
|
14560
|
-
log(` - ${label}`);
|
|
14561
|
-
formatDiffPayload(subGroup[0], log);
|
|
14562
|
-
}
|
|
14563
|
-
log("");
|
|
14999
|
+
const allGroupedDiffs = Array.from(groupDiffsByArtefact(diffs).values());
|
|
15000
|
+
const checkResult = await packmindCliHexa.checkDiffs(allGroupedDiffs);
|
|
15001
|
+
const submittedItems = checkResult.results.filter((r) => r.exists);
|
|
15002
|
+
const unsubmittedItems = checkResult.results.filter((r) => !r.exists);
|
|
15003
|
+
const diffsToDisplay = includeSubmitted ? diffs : unsubmittedItems.map((r) => r.diff);
|
|
15004
|
+
const submittedLookup = /* @__PURE__ */ new Map();
|
|
15005
|
+
for (const item of checkResult.results) {
|
|
15006
|
+
submittedLookup.set(item.diff, item);
|
|
14564
15007
|
}
|
|
14565
|
-
|
|
14566
|
-
|
|
14567
|
-
|
|
14568
|
-
|
|
14569
|
-
skill: 1,
|
|
14570
|
-
standard: 2
|
|
14571
|
-
};
|
|
14572
|
-
const uniqueArtefacts = /* @__PURE__ */ new Map();
|
|
14573
|
-
for (const [key, groupDiffs] of groups) {
|
|
14574
|
-
if (!uniqueArtefacts.has(key)) {
|
|
14575
|
-
uniqueArtefacts.set(key, {
|
|
14576
|
-
type: groupDiffs[0].artifactType,
|
|
14577
|
-
name: groupDiffs[0].artifactName
|
|
14578
|
-
});
|
|
15008
|
+
if (diffsToDisplay.length === 0) {
|
|
15009
|
+
log("No new changes found.");
|
|
15010
|
+
if (submittedItems.length > 0) {
|
|
15011
|
+
logInfoConsole(buildSubmittedFooter(submittedItems));
|
|
14579
15012
|
}
|
|
15013
|
+
if (submit) {
|
|
15014
|
+
logInfoConsole("All changes already submitted.");
|
|
15015
|
+
}
|
|
15016
|
+
exit(0);
|
|
15017
|
+
return { diffsFound: 0 };
|
|
14580
15018
|
}
|
|
14581
|
-
const
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
);
|
|
14589
|
-
for (const artefact of sortedArtefacts) {
|
|
14590
|
-
const typeLabel = ARTIFACT_TYPE_LABELS[artefact.type];
|
|
14591
|
-
logWarningConsole(`* ${typeLabel} "${artefact.name}"`);
|
|
14592
|
-
}
|
|
15019
|
+
const changeCount = displayDiffs({
|
|
15020
|
+
diffsToDisplay,
|
|
15021
|
+
submittedLookup,
|
|
15022
|
+
includeSubmitted,
|
|
15023
|
+
unsubmittedItems,
|
|
15024
|
+
submittedItems,
|
|
15025
|
+
log
|
|
15026
|
+
});
|
|
14593
15027
|
if (submit) {
|
|
14594
|
-
const
|
|
14595
|
-
|
|
14596
|
-
|
|
14597
|
-
|
|
14598
|
-
|
|
14599
|
-
|
|
14600
|
-
|
|
14601
|
-
|
|
14602
|
-
logErrorConsole(`Failed to submit "${err.name}": ${err.message}`);
|
|
14603
|
-
}
|
|
14604
|
-
}
|
|
14605
|
-
const summaryParts = [];
|
|
14606
|
-
if (result.submitted > 0) {
|
|
14607
|
-
summaryParts.push(`${result.submitted} submitted`);
|
|
14608
|
-
}
|
|
14609
|
-
if (result.alreadySubmitted > 0) {
|
|
14610
|
-
summaryParts.push(`${result.alreadySubmitted} already submitted`);
|
|
14611
|
-
}
|
|
14612
|
-
if (result.errors.length > 0) {
|
|
14613
|
-
const errorWord = result.errors.length === 1 ? "error" : "errors";
|
|
14614
|
-
summaryParts.push(`${result.errors.length} ${errorWord}`);
|
|
14615
|
-
}
|
|
14616
|
-
if (summaryParts.length > 0) {
|
|
14617
|
-
const summaryMessage = `Summary: ${summaryParts.join(", ")}`;
|
|
14618
|
-
if (result.errors.length === 0 && result.alreadySubmitted === 0) {
|
|
14619
|
-
logSuccessConsole(summaryMessage);
|
|
14620
|
-
} else if (result.errors.length > 0 && result.submitted > 0 || result.alreadySubmitted > 0) {
|
|
14621
|
-
logWarningConsole(summaryMessage);
|
|
14622
|
-
} else {
|
|
14623
|
-
logErrorConsole(summaryMessage);
|
|
14624
|
-
}
|
|
15028
|
+
const aborted = await handleSubmission({
|
|
15029
|
+
packmindCliHexa,
|
|
15030
|
+
unsubmittedItems,
|
|
15031
|
+
messageFlag,
|
|
15032
|
+
exit
|
|
15033
|
+
});
|
|
15034
|
+
if (aborted) {
|
|
15035
|
+
return { diffsFound: changeCount };
|
|
14625
15036
|
}
|
|
14626
15037
|
}
|
|
14627
15038
|
exit(0);
|
|
@@ -14646,9 +15057,19 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
14646
15057
|
submit: (0, import_cmd_ts19.flag)({
|
|
14647
15058
|
long: "submit",
|
|
14648
15059
|
description: "Submit detected changes as change proposals"
|
|
15060
|
+
}),
|
|
15061
|
+
includeSubmitted: (0, import_cmd_ts19.flag)({
|
|
15062
|
+
long: "include-submitted",
|
|
15063
|
+
description: "Include already submitted changes in the output"
|
|
15064
|
+
}),
|
|
15065
|
+
message: (0, import_cmd_ts19.option)({
|
|
15066
|
+
long: "message",
|
|
15067
|
+
short: "m",
|
|
15068
|
+
description: "Message describing the intent behind the changes (max 1024 chars)",
|
|
15069
|
+
type: (0, import_cmd_ts19.optional)(import_cmd_ts19.string)
|
|
14649
15070
|
})
|
|
14650
15071
|
},
|
|
14651
|
-
handler: async ({ submit }) => {
|
|
15072
|
+
handler: async ({ submit, includeSubmitted, message }) => {
|
|
14652
15073
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
14653
15074
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
14654
15075
|
await diffArtefactsHandler({
|
|
@@ -14657,7 +15078,9 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
14657
15078
|
getCwd: () => process.cwd(),
|
|
14658
15079
|
log: console.log,
|
|
14659
15080
|
error: console.error,
|
|
14660
|
-
submit
|
|
15081
|
+
submit,
|
|
15082
|
+
includeSubmitted,
|
|
15083
|
+
message
|
|
14661
15084
|
});
|
|
14662
15085
|
}
|
|
14663
15086
|
});
|