@packmind/cli 0.13.1 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main.cjs +1142 -290
- package/package.json +3 -2
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(string8, substring, replacer) {
|
|
375
|
+
let index = string8.indexOf(substring);
|
|
376
376
|
if (index === -1) {
|
|
377
|
-
return
|
|
377
|
+
return string8;
|
|
378
378
|
}
|
|
379
379
|
const substringLength = substring.length;
|
|
380
380
|
let endIndex = 0;
|
|
381
381
|
let returnValue = "";
|
|
382
382
|
do {
|
|
383
|
-
returnValue +=
|
|
383
|
+
returnValue += string8.slice(endIndex, index) + substring + replacer;
|
|
384
384
|
endIndex = index + substringLength;
|
|
385
|
-
index =
|
|
385
|
+
index = string8.indexOf(substring, endIndex);
|
|
386
386
|
} while (index !== -1);
|
|
387
|
-
returnValue +=
|
|
387
|
+
returnValue += string8.slice(endIndex);
|
|
388
388
|
return returnValue;
|
|
389
389
|
}
|
|
390
|
-
function stringEncaseCRLFWithFirstIndex(
|
|
390
|
+
function stringEncaseCRLFWithFirstIndex(string8, prefix, postfix, index) {
|
|
391
391
|
let endIndex = 0;
|
|
392
392
|
let returnValue = "";
|
|
393
393
|
do {
|
|
394
|
-
const gotCR =
|
|
395
|
-
returnValue +=
|
|
394
|
+
const gotCR = string8[index - 1] === "\r";
|
|
395
|
+
returnValue += string8.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
|
|
396
396
|
endIndex = index + 1;
|
|
397
|
-
index =
|
|
397
|
+
index = string8.indexOf("\n", endIndex);
|
|
398
398
|
} while (index !== -1);
|
|
399
|
-
returnValue +=
|
|
399
|
+
returnValue += string8.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, string8) => {
|
|
559
|
+
if (self.level <= 0 || !string8) {
|
|
560
|
+
return self[IS_EMPTY] ? "" : string8;
|
|
561
561
|
}
|
|
562
562
|
let styler = self[STYLER];
|
|
563
563
|
if (styler === void 0) {
|
|
564
|
-
return
|
|
564
|
+
return string8;
|
|
565
565
|
}
|
|
566
566
|
const { openAll, closeAll } = styler;
|
|
567
|
-
if (
|
|
567
|
+
if (string8.includes("\x1B")) {
|
|
568
568
|
while (styler !== void 0) {
|
|
569
|
-
|
|
569
|
+
string8 = stringReplaceAll(string8, styler.close, styler.open);
|
|
570
570
|
styler = styler.parent;
|
|
571
571
|
}
|
|
572
572
|
}
|
|
573
|
-
const lfIndex =
|
|
573
|
+
const lfIndex = string8.indexOf("\n");
|
|
574
574
|
if (lfIndex !== -1) {
|
|
575
|
-
|
|
575
|
+
string8 = stringEncaseCRLFWithFirstIndex(string8, closeAll, openAll, lfIndex);
|
|
576
576
|
}
|
|
577
|
-
return openAll +
|
|
577
|
+
return openAll + string8 + closeAll;
|
|
578
578
|
};
|
|
579
579
|
Object.defineProperties(createChalk.prototype, styles2);
|
|
580
580
|
chalk = createChalk();
|
|
@@ -1255,7 +1255,7 @@ var require_positional = __commonJS({
|
|
|
1255
1255
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
1256
1256
|
};
|
|
1257
1257
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1258
|
-
exports2.positional =
|
|
1258
|
+
exports2.positional = positional5;
|
|
1259
1259
|
var chalk_1 = __importDefault((init_source(), __toCommonJS(source_exports)));
|
|
1260
1260
|
var Result = __importStar(require_Result());
|
|
1261
1261
|
var types_1 = require_types();
|
|
@@ -1295,8 +1295,8 @@ var require_positional = __commonJS({
|
|
|
1295
1295
|
var _a2;
|
|
1296
1296
|
const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
|
|
1297
1297
|
const defaultValueFn = (_a2 = config.defaultValue) !== null && _a2 !== void 0 ? _a2 : config.type.defaultValue;
|
|
1298
|
-
const
|
|
1299
|
-
if (!
|
|
1298
|
+
const positional6 = positionals[0];
|
|
1299
|
+
if (!positional6) {
|
|
1300
1300
|
if (defaultValueFn) {
|
|
1301
1301
|
return Result.ok(defaultValueFn());
|
|
1302
1302
|
}
|
|
@@ -1309,13 +1309,13 @@ var require_positional = __commonJS({
|
|
|
1309
1309
|
]
|
|
1310
1310
|
});
|
|
1311
1311
|
}
|
|
1312
|
-
visitedNodes.add(
|
|
1313
|
-
const decoded = await Result.safeAsync(config.type.from(
|
|
1312
|
+
visitedNodes.add(positional6);
|
|
1313
|
+
const decoded = await Result.safeAsync(config.type.from(positional6.raw));
|
|
1314
1314
|
if (Result.isErr(decoded)) {
|
|
1315
1315
|
return Result.err({
|
|
1316
1316
|
errors: [
|
|
1317
1317
|
{
|
|
1318
|
-
nodes: [
|
|
1318
|
+
nodes: [positional6],
|
|
1319
1319
|
message: decoded.error.message
|
|
1320
1320
|
}
|
|
1321
1321
|
]
|
|
@@ -1325,7 +1325,7 @@ var require_positional = __commonJS({
|
|
|
1325
1325
|
}
|
|
1326
1326
|
};
|
|
1327
1327
|
}
|
|
1328
|
-
function
|
|
1328
|
+
function positional5(config) {
|
|
1329
1329
|
return fullPositional({
|
|
1330
1330
|
type: types_1.string,
|
|
1331
1331
|
...config
|
|
@@ -1379,13 +1379,13 @@ var require_subcommands = __commonJS({
|
|
|
1379
1379
|
return mod && mod.__esModule ? mod : { "default": mod };
|
|
1380
1380
|
};
|
|
1381
1381
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
1382
|
-
exports2.subcommands =
|
|
1382
|
+
exports2.subcommands = subcommands5;
|
|
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 subcommands5(config) {
|
|
1389
1389
|
const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
|
|
1390
1390
|
const type = {
|
|
1391
1391
|
async from(str) {
|
|
@@ -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(string8) {
|
|
1582
|
+
if (typeof string8 !== "string") {
|
|
1583
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof string8}\``);
|
|
1584
1584
|
}
|
|
1585
|
-
return
|
|
1585
|
+
return string8.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 = command12;
|
|
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 command12(config) {
|
|
1707
1707
|
const argEntries = (0, utils_1.entries)(config.args);
|
|
1708
1708
|
const circuitbreaker = (0, circuitbreaker_1.createCircuitBreaker)(!!config.version);
|
|
1709
1709
|
return {
|
|
@@ -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, string8] of (0, utils_1.enumerate)(strings)) {
|
|
3088
|
+
const chars = [...string8];
|
|
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 });
|
|
@@ -3241,14 +3241,14 @@ var require_restPositionals = __commonJS({
|
|
|
3241
3241
|
const positionals = nodes.filter((node) => node.type === "positionalArgument" && !visitedNodes.has(node));
|
|
3242
3242
|
const results = [];
|
|
3243
3243
|
const errors = [];
|
|
3244
|
-
for (const
|
|
3245
|
-
visitedNodes.add(
|
|
3246
|
-
const decoded = await Result.safeAsync(config.type.from(
|
|
3244
|
+
for (const positional5 of positionals) {
|
|
3245
|
+
visitedNodes.add(positional5);
|
|
3246
|
+
const decoded = await Result.safeAsync(config.type.from(positional5.raw));
|
|
3247
3247
|
if (Result.isOk(decoded)) {
|
|
3248
3248
|
results.push(decoded.value);
|
|
3249
3249
|
} else {
|
|
3250
3250
|
errors.push({
|
|
3251
|
-
nodes: [
|
|
3251
|
+
nodes: [positional5],
|
|
3252
3252
|
message: decoded.error.message
|
|
3253
3253
|
});
|
|
3254
3254
|
}
|
|
@@ -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.14.1",
|
|
3856
3856
|
description: "A command-line interface for Packmind linting and code quality checks",
|
|
3857
3857
|
private: false,
|
|
3858
3858
|
bin: {
|
|
@@ -3887,14 +3887,15 @@ var require_package = __commonJS({
|
|
|
3887
3887
|
},
|
|
3888
3888
|
dependencies: {
|
|
3889
3889
|
"@types/inquirer": "^9.0.9",
|
|
3890
|
-
inquirer: "^13.0.2"
|
|
3890
|
+
inquirer: "^13.0.2",
|
|
3891
|
+
zod: "^4.3.5"
|
|
3891
3892
|
}
|
|
3892
3893
|
};
|
|
3893
3894
|
}
|
|
3894
3895
|
});
|
|
3895
3896
|
|
|
3896
3897
|
// apps/cli/src/main.ts
|
|
3897
|
-
var
|
|
3898
|
+
var import_cmd_ts15 = __toESM(require_cjs());
|
|
3898
3899
|
|
|
3899
3900
|
// apps/cli/src/infra/commands/LinterCommand.ts
|
|
3900
3901
|
var import_cmd_ts = __toESM(require_cjs());
|
|
@@ -4048,6 +4049,13 @@ var AnonymousTrialAccountActivatedEvent = class extends UserEvent {
|
|
|
4048
4049
|
}
|
|
4049
4050
|
};
|
|
4050
4051
|
|
|
4052
|
+
// packages/types/src/accounts/events/OrganizationCreatedEvent.ts
|
|
4053
|
+
var OrganizationCreatedEvent = class extends UserEvent {
|
|
4054
|
+
static {
|
|
4055
|
+
this.eventName = "accounts.organization.created";
|
|
4056
|
+
}
|
|
4057
|
+
};
|
|
4058
|
+
|
|
4051
4059
|
// packages/types/src/accounts/TrialActivationToken.ts
|
|
4052
4060
|
var createTrialActivationTokenId = brandedIdFactory();
|
|
4053
4061
|
var createTrialActivationToken = brandedIdFactory();
|
|
@@ -4735,6 +4743,17 @@ function createUserContextChangeEvent(userId, organizationId, changeType, role)
|
|
|
4735
4743
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4736
4744
|
};
|
|
4737
4745
|
}
|
|
4746
|
+
function createDistributionStatusChangeEvent(distributionId, status, organizationId) {
|
|
4747
|
+
return {
|
|
4748
|
+
type: "DISTRIBUTION_STATUS_CHANGE",
|
|
4749
|
+
data: {
|
|
4750
|
+
distributionId,
|
|
4751
|
+
status,
|
|
4752
|
+
organizationId
|
|
4753
|
+
},
|
|
4754
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
4755
|
+
};
|
|
4756
|
+
}
|
|
4738
4757
|
|
|
4739
4758
|
// apps/cli/src/application/useCases/ExecuteSingleFileAstUseCase.ts
|
|
4740
4759
|
var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
|
|
@@ -4747,8 +4766,8 @@ var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
|
|
|
4747
4766
|
static {
|
|
4748
4767
|
this.fallbackRuleContent = "adhoc-rule";
|
|
4749
4768
|
}
|
|
4750
|
-
async execute(
|
|
4751
|
-
const { program, fileContent, language } =
|
|
4769
|
+
async execute(command12) {
|
|
4770
|
+
const { program, fileContent, language } = command12;
|
|
4752
4771
|
const result = await this.linterExecutionUseCase.execute({
|
|
4753
4772
|
filePath: "cli-single-file",
|
|
4754
4773
|
fileContent,
|
|
@@ -4798,30 +4817,30 @@ var GitService = class {
|
|
|
4798
4817
|
this.gitRunner = gitRunner;
|
|
4799
4818
|
this.logger = logger2;
|
|
4800
4819
|
}
|
|
4801
|
-
getGitRepositoryRoot(
|
|
4820
|
+
getGitRepositoryRoot(path13) {
|
|
4802
4821
|
try {
|
|
4803
4822
|
const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
|
|
4804
|
-
cwd:
|
|
4823
|
+
cwd: path13
|
|
4805
4824
|
});
|
|
4806
4825
|
const gitRoot = stdout.trim();
|
|
4807
4826
|
this.logger.debug("Resolved git repository root", {
|
|
4808
|
-
inputPath:
|
|
4827
|
+
inputPath: path13,
|
|
4809
4828
|
gitRoot
|
|
4810
4829
|
});
|
|
4811
4830
|
return gitRoot;
|
|
4812
4831
|
} catch (error) {
|
|
4813
4832
|
if (error instanceof Error) {
|
|
4814
4833
|
throw new Error(
|
|
4815
|
-
`Failed to get Git repository root. The path '${
|
|
4834
|
+
`Failed to get Git repository root. The path '${path13}' does not appear to be inside a Git repository.
|
|
4816
4835
|
${error.message}`
|
|
4817
4836
|
);
|
|
4818
4837
|
}
|
|
4819
4838
|
throw new Error("Failed to get Git repository root: Unknown error");
|
|
4820
4839
|
}
|
|
4821
4840
|
}
|
|
4822
|
-
tryGetGitRepositoryRoot(
|
|
4841
|
+
tryGetGitRepositoryRoot(path13) {
|
|
4823
4842
|
try {
|
|
4824
|
-
return this.getGitRepositoryRoot(
|
|
4843
|
+
return this.getGitRepositoryRoot(path13);
|
|
4825
4844
|
} catch {
|
|
4826
4845
|
return null;
|
|
4827
4846
|
}
|
|
@@ -5128,8 +5147,8 @@ var GetGitRemoteUrlUseCase = class {
|
|
|
5128
5147
|
constructor(gitRemoteUrlService = new GitService()) {
|
|
5129
5148
|
this.gitRemoteUrlService = gitRemoteUrlService;
|
|
5130
5149
|
}
|
|
5131
|
-
async execute(
|
|
5132
|
-
const { path: repoPath, origin: origin11 } =
|
|
5150
|
+
async execute(command12) {
|
|
5151
|
+
const { path: repoPath, origin: origin11 } = command12;
|
|
5133
5152
|
return this.gitRemoteUrlService.getGitRemoteUrl(repoPath, origin11);
|
|
5134
5153
|
}
|
|
5135
5154
|
};
|
|
@@ -5137,6 +5156,42 @@ var GetGitRemoteUrlUseCase = class {
|
|
|
5137
5156
|
// apps/cli/src/application/services/ListFiles.ts
|
|
5138
5157
|
var fs = __toESM(require("fs/promises"));
|
|
5139
5158
|
var path2 = __toESM(require("path"));
|
|
5159
|
+
|
|
5160
|
+
// apps/cli/src/infra/utils/consoleLogger.ts
|
|
5161
|
+
init_source();
|
|
5162
|
+
var CLI_PREFIX = "packmind-cli";
|
|
5163
|
+
function logConsole(message, logger2 = console) {
|
|
5164
|
+
logger2.log(message);
|
|
5165
|
+
}
|
|
5166
|
+
function logWarningConsole(message, logger2 = console) {
|
|
5167
|
+
logger2.warn(source_default.bgYellow.bold(CLI_PREFIX), source_default.yellow(message));
|
|
5168
|
+
}
|
|
5169
|
+
function logInfoConsole(message, logger2 = console) {
|
|
5170
|
+
logger2.log(source_default.bgBlue.bold(CLI_PREFIX), source_default.blue(message));
|
|
5171
|
+
}
|
|
5172
|
+
function logErrorConsole(message, logger2 = console) {
|
|
5173
|
+
logger2.error(source_default.bgRed.bold(CLI_PREFIX), source_default.red(message));
|
|
5174
|
+
}
|
|
5175
|
+
function logSuccessConsole(message, logger2 = console) {
|
|
5176
|
+
logger2.log(source_default.bgGreen.bold(CLI_PREFIX), source_default.green.bold(message));
|
|
5177
|
+
}
|
|
5178
|
+
function formatSlug(text) {
|
|
5179
|
+
return source_default.blue.bold(text);
|
|
5180
|
+
}
|
|
5181
|
+
function formatLabel(text) {
|
|
5182
|
+
return source_default.dim(text);
|
|
5183
|
+
}
|
|
5184
|
+
function formatError(text) {
|
|
5185
|
+
return source_default.red(text);
|
|
5186
|
+
}
|
|
5187
|
+
function formatBold(text) {
|
|
5188
|
+
return source_default.bold(text);
|
|
5189
|
+
}
|
|
5190
|
+
function formatFilePath(text) {
|
|
5191
|
+
return source_default.underline.gray(text);
|
|
5192
|
+
}
|
|
5193
|
+
|
|
5194
|
+
// apps/cli/src/application/services/ListFiles.ts
|
|
5140
5195
|
var ListFiles = class {
|
|
5141
5196
|
async listFilesInDirectory(directoryPath, extensions, excludes = [], skipHidden = true) {
|
|
5142
5197
|
const results = [];
|
|
@@ -5184,7 +5239,7 @@ var ListFiles = class {
|
|
|
5184
5239
|
}
|
|
5185
5240
|
}
|
|
5186
5241
|
} catch (error) {
|
|
5187
|
-
|
|
5242
|
+
logErrorConsole(`Error reading directory ${directoryPath}: ${error}`);
|
|
5188
5243
|
}
|
|
5189
5244
|
}
|
|
5190
5245
|
shouldExcludePath(filePath, excludes) {
|
|
@@ -5218,7 +5273,7 @@ var ListFiles = class {
|
|
|
5218
5273
|
try {
|
|
5219
5274
|
return await fs.readFile(filePath, "utf-8");
|
|
5220
5275
|
} catch (error) {
|
|
5221
|
-
|
|
5276
|
+
logErrorConsole(`Error reading file ${filePath}: ${error}`);
|
|
5222
5277
|
throw error;
|
|
5223
5278
|
}
|
|
5224
5279
|
}
|
|
@@ -5229,8 +5284,8 @@ var ListFilesInDirectoryUseCase = class {
|
|
|
5229
5284
|
constructor(listFiles = new ListFiles()) {
|
|
5230
5285
|
this.listFiles = listFiles;
|
|
5231
5286
|
}
|
|
5232
|
-
async execute(
|
|
5233
|
-
const { path: directoryPath, extensions, excludes = [] } =
|
|
5287
|
+
async execute(command12) {
|
|
5288
|
+
const { path: directoryPath, extensions, excludes = [] } = command12;
|
|
5234
5289
|
const files = await this.listFiles.listFilesInDirectory(
|
|
5235
5290
|
directoryPath,
|
|
5236
5291
|
extensions,
|
|
@@ -5245,7 +5300,7 @@ var ListFilesInDirectoryUseCase = class {
|
|
|
5245
5300
|
content
|
|
5246
5301
|
});
|
|
5247
5302
|
} catch (error) {
|
|
5248
|
-
|
|
5303
|
+
logErrorConsole(`Error reading file ${file.path}: ${error}`);
|
|
5249
5304
|
}
|
|
5250
5305
|
}
|
|
5251
5306
|
return filesWithContent;
|
|
@@ -5263,6 +5318,23 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5263
5318
|
this.repositories = repositories;
|
|
5264
5319
|
this.logger = logger2;
|
|
5265
5320
|
}
|
|
5321
|
+
/**
|
|
5322
|
+
* Parses a scope string from the API into an array of patterns.
|
|
5323
|
+
* Handles comma-separated patterns and various edge cases.
|
|
5324
|
+
*
|
|
5325
|
+
* @param scope - The scope string from API (can be null, empty, or comma-separated)
|
|
5326
|
+
* @returns Array of scope patterns, or empty array if no valid scope
|
|
5327
|
+
*/
|
|
5328
|
+
parseScopeString(scope) {
|
|
5329
|
+
if (!scope) {
|
|
5330
|
+
return [];
|
|
5331
|
+
}
|
|
5332
|
+
const trimmedScope = scope.trim();
|
|
5333
|
+
if (trimmedScope === "") {
|
|
5334
|
+
return [];
|
|
5335
|
+
}
|
|
5336
|
+
return trimmedScope.split(",").map((pattern) => pattern.trim()).filter((pattern) => pattern.length > 0);
|
|
5337
|
+
}
|
|
5266
5338
|
fileMatchesScope(filePath, scopePatterns) {
|
|
5267
5339
|
if (!scopePatterns || scopePatterns.length === 0) {
|
|
5268
5340
|
return true;
|
|
@@ -5315,7 +5387,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5315
5387
|
}
|
|
5316
5388
|
return pattern;
|
|
5317
5389
|
}
|
|
5318
|
-
async execute(
|
|
5390
|
+
async execute(command12) {
|
|
5319
5391
|
const {
|
|
5320
5392
|
path: userPath,
|
|
5321
5393
|
draftMode,
|
|
@@ -5323,7 +5395,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5323
5395
|
ruleId,
|
|
5324
5396
|
language,
|
|
5325
5397
|
diffMode
|
|
5326
|
-
} =
|
|
5398
|
+
} = command12;
|
|
5327
5399
|
this.logger.debug(
|
|
5328
5400
|
`Starting linting: path="${userPath}", draftMode=${!!draftMode}, standardSlug="${standardSlug || "N/A"}", ruleId="${ruleId || "N/A"}", language="${language || "N/A"}", diffMode="${diffMode ?? "none"}"`
|
|
5329
5401
|
);
|
|
@@ -5432,7 +5504,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5432
5504
|
{
|
|
5433
5505
|
name: standardSlug,
|
|
5434
5506
|
slug: standardSlug,
|
|
5435
|
-
scope:
|
|
5507
|
+
scope: this.parseScopeString(draftProgramsResult.scope),
|
|
5436
5508
|
rules: [
|
|
5437
5509
|
{
|
|
5438
5510
|
content: draftProgramsResult.ruleContent || "Draft Rule",
|
|
@@ -5470,7 +5542,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5470
5542
|
{
|
|
5471
5543
|
name: standardSlug,
|
|
5472
5544
|
slug: standardSlug,
|
|
5473
|
-
scope:
|
|
5545
|
+
scope: this.parseScopeString(activeProgramsResult.scope),
|
|
5474
5546
|
rules: [
|
|
5475
5547
|
{
|
|
5476
5548
|
content: activeProgramsResult.ruleContent || "Active Rule",
|
|
@@ -5544,7 +5616,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5544
5616
|
activeProgram.language
|
|
5545
5617
|
);
|
|
5546
5618
|
if (!programLanguage) {
|
|
5547
|
-
|
|
5619
|
+
logErrorConsole(
|
|
5548
5620
|
`Unsupported language "${activeProgram.language}" for file ${file.path}`
|
|
5549
5621
|
);
|
|
5550
5622
|
continue;
|
|
@@ -5562,7 +5634,7 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5562
5634
|
});
|
|
5563
5635
|
programsByLanguage.set(programLanguage, programsForLanguage);
|
|
5564
5636
|
} catch (error) {
|
|
5565
|
-
|
|
5637
|
+
logErrorConsole(
|
|
5566
5638
|
`Error preparing program for file ${file.path}: ${error}`
|
|
5567
5639
|
);
|
|
5568
5640
|
}
|
|
@@ -5585,13 +5657,13 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5585
5657
|
});
|
|
5586
5658
|
fileViolations.push(...result);
|
|
5587
5659
|
} catch (error) {
|
|
5588
|
-
|
|
5660
|
+
logErrorConsole(
|
|
5589
5661
|
`Error executing programs for file ${file.path} (${language2}): ${error}`
|
|
5590
5662
|
);
|
|
5591
5663
|
}
|
|
5592
5664
|
}
|
|
5593
5665
|
} catch (error) {
|
|
5594
|
-
|
|
5666
|
+
logErrorConsole(
|
|
5595
5667
|
`Error reading file content for ${file.path}: ${error}`
|
|
5596
5668
|
);
|
|
5597
5669
|
}
|
|
@@ -5642,8 +5714,8 @@ var LintFilesInDirectoryUseCase = class {
|
|
|
5642
5714
|
return null;
|
|
5643
5715
|
}
|
|
5644
5716
|
}
|
|
5645
|
-
async executeProgramsForFile(
|
|
5646
|
-
const result = await this.services.linterExecutionUseCase.execute(
|
|
5717
|
+
async executeProgramsForFile(command12) {
|
|
5718
|
+
const result = await this.services.linterExecutionUseCase.execute(command12);
|
|
5647
5719
|
return result.violations;
|
|
5648
5720
|
}
|
|
5649
5721
|
extractExtensionFromFile(filePath) {
|
|
@@ -5700,8 +5772,8 @@ var LintFilesLocallyUseCase = class {
|
|
|
5700
5772
|
}
|
|
5701
5773
|
return pattern;
|
|
5702
5774
|
}
|
|
5703
|
-
async execute(
|
|
5704
|
-
const { path: userPath, diffMode } =
|
|
5775
|
+
async execute(command12) {
|
|
5776
|
+
const { path: userPath, diffMode } = command12;
|
|
5705
5777
|
this.logger.debug(
|
|
5706
5778
|
`Starting local linting: path="${userPath}", diffMode="${diffMode ?? "none"}"`
|
|
5707
5779
|
);
|
|
@@ -5836,7 +5908,7 @@ var LintFilesLocallyUseCase = class {
|
|
|
5836
5908
|
});
|
|
5837
5909
|
programsByLanguage.set(programLanguage, programsForLanguage);
|
|
5838
5910
|
} catch (error) {
|
|
5839
|
-
|
|
5911
|
+
logErrorConsole(
|
|
5840
5912
|
`Error preparing program for file ${file.path}: ${error}`
|
|
5841
5913
|
);
|
|
5842
5914
|
}
|
|
@@ -5860,13 +5932,13 @@ var LintFilesLocallyUseCase = class {
|
|
|
5860
5932
|
});
|
|
5861
5933
|
fileViolations.push(...result);
|
|
5862
5934
|
} catch (error) {
|
|
5863
|
-
|
|
5935
|
+
logErrorConsole(
|
|
5864
5936
|
`Error executing programs for file ${file.path} (${language}): ${error}`
|
|
5865
5937
|
);
|
|
5866
5938
|
}
|
|
5867
5939
|
}
|
|
5868
5940
|
} catch (error) {
|
|
5869
|
-
|
|
5941
|
+
logErrorConsole(
|
|
5870
5942
|
`Error reading file content for ${file.path}: ${error}`
|
|
5871
5943
|
);
|
|
5872
5944
|
}
|
|
@@ -5943,8 +6015,8 @@ var LintFilesLocallyUseCase = class {
|
|
|
5943
6015
|
return null;
|
|
5944
6016
|
}
|
|
5945
6017
|
}
|
|
5946
|
-
async executeProgramsForFile(
|
|
5947
|
-
const result = await this.services.linterExecutionUseCase.execute(
|
|
6018
|
+
async executeProgramsForFile(command12) {
|
|
6019
|
+
const result = await this.services.linterExecutionUseCase.execute(command12);
|
|
5948
6020
|
return result.violations;
|
|
5949
6021
|
}
|
|
5950
6022
|
extractExtensionFromFile(filePath) {
|
|
@@ -6110,6 +6182,93 @@ var NotLoggedInError = class extends Error {
|
|
|
6110
6182
|
}
|
|
6111
6183
|
};
|
|
6112
6184
|
|
|
6185
|
+
// apps/cli/src/infra/http/PackmindHttpClient.ts
|
|
6186
|
+
var PackmindHttpClient = class {
|
|
6187
|
+
constructor(apiKey) {
|
|
6188
|
+
this.apiKey = apiKey;
|
|
6189
|
+
}
|
|
6190
|
+
getAuthContext() {
|
|
6191
|
+
if (!this.apiKey) {
|
|
6192
|
+
throw new NotLoggedInError();
|
|
6193
|
+
}
|
|
6194
|
+
let decoded;
|
|
6195
|
+
try {
|
|
6196
|
+
const decodedString = Buffer.from(this.apiKey, "base64").toString(
|
|
6197
|
+
"utf-8"
|
|
6198
|
+
);
|
|
6199
|
+
decoded = JSON.parse(decodedString);
|
|
6200
|
+
} catch {
|
|
6201
|
+
throw new Error("Invalid API key");
|
|
6202
|
+
}
|
|
6203
|
+
const jwtPayload = this.decodeJwt(decoded.jwt);
|
|
6204
|
+
const organizationId = jwtPayload?.organization?.id;
|
|
6205
|
+
if (!organizationId) {
|
|
6206
|
+
throw new Error("Invalid API key: missing organizationId");
|
|
6207
|
+
}
|
|
6208
|
+
return {
|
|
6209
|
+
host: decoded.host,
|
|
6210
|
+
jwt: decoded.jwt,
|
|
6211
|
+
organizationId
|
|
6212
|
+
};
|
|
6213
|
+
}
|
|
6214
|
+
decodeJwt(jwt) {
|
|
6215
|
+
try {
|
|
6216
|
+
const parts = jwt.split(".");
|
|
6217
|
+
if (parts.length !== 3) {
|
|
6218
|
+
return null;
|
|
6219
|
+
}
|
|
6220
|
+
const payloadBase64 = parts[1];
|
|
6221
|
+
const payloadString = Buffer.from(payloadBase64, "base64").toString(
|
|
6222
|
+
"utf-8"
|
|
6223
|
+
);
|
|
6224
|
+
return JSON.parse(payloadString);
|
|
6225
|
+
} catch {
|
|
6226
|
+
return null;
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
async request(path13, options = {}) {
|
|
6230
|
+
const { host } = this.getAuthContext();
|
|
6231
|
+
const { method = "GET", body } = options;
|
|
6232
|
+
const url = `${host}${path13}`;
|
|
6233
|
+
try {
|
|
6234
|
+
const response = await fetch(url, {
|
|
6235
|
+
method,
|
|
6236
|
+
headers: {
|
|
6237
|
+
"Content-Type": "application/json",
|
|
6238
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
6239
|
+
},
|
|
6240
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
6241
|
+
});
|
|
6242
|
+
if (!response.ok) {
|
|
6243
|
+
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
6244
|
+
try {
|
|
6245
|
+
const errorBody = await response.json();
|
|
6246
|
+
if (errorBody?.message) {
|
|
6247
|
+
errorMsg = errorBody.message;
|
|
6248
|
+
}
|
|
6249
|
+
} catch {
|
|
6250
|
+
}
|
|
6251
|
+
const error = new Error(errorMsg);
|
|
6252
|
+
error.statusCode = response.status;
|
|
6253
|
+
throw error;
|
|
6254
|
+
}
|
|
6255
|
+
return response.json();
|
|
6256
|
+
} catch (error) {
|
|
6257
|
+
const err = error;
|
|
6258
|
+
if (err.statusCode) throw error;
|
|
6259
|
+
const code = err?.code || err?.cause?.code;
|
|
6260
|
+
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"))) {
|
|
6261
|
+
throw new Error(
|
|
6262
|
+
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
6263
|
+
);
|
|
6264
|
+
}
|
|
6265
|
+
throw new Error(
|
|
6266
|
+
`Request failed: ${err?.message || JSON.stringify(error)}`
|
|
6267
|
+
);
|
|
6268
|
+
}
|
|
6269
|
+
}
|
|
6270
|
+
};
|
|
6271
|
+
|
|
6113
6272
|
// apps/cli/src/infra/repositories/PackmindGateway.ts
|
|
6114
6273
|
function decodeJwt(jwt) {
|
|
6115
6274
|
try {
|
|
@@ -6166,7 +6325,7 @@ function decodeApiKey(apiKey) {
|
|
|
6166
6325
|
var PackmindGateway = class {
|
|
6167
6326
|
constructor(apiKey) {
|
|
6168
6327
|
this.apiKey = apiKey;
|
|
6169
|
-
this.getPullData = async (
|
|
6328
|
+
this.getPullData = async (command12) => {
|
|
6170
6329
|
const decodedApiKey = decodeApiKey(this.apiKey);
|
|
6171
6330
|
if (!decodedApiKey.isValid) {
|
|
6172
6331
|
if (decodedApiKey.error === "NOT_LOGGED_IN") {
|
|
@@ -6181,16 +6340,25 @@ var PackmindGateway = class {
|
|
|
6181
6340
|
}
|
|
6182
6341
|
const organizationId = jwtPayload.organization.id;
|
|
6183
6342
|
const queryParams = new URLSearchParams();
|
|
6184
|
-
if (
|
|
6185
|
-
|
|
6343
|
+
if (command12.packagesSlugs && command12.packagesSlugs.length > 0) {
|
|
6344
|
+
command12.packagesSlugs.forEach((slug) => {
|
|
6186
6345
|
queryParams.append("packageSlug", slug);
|
|
6187
6346
|
});
|
|
6188
6347
|
}
|
|
6189
|
-
if (
|
|
6190
|
-
|
|
6348
|
+
if (command12.previousPackagesSlugs && command12.previousPackagesSlugs.length > 0) {
|
|
6349
|
+
command12.previousPackagesSlugs.forEach((slug) => {
|
|
6191
6350
|
queryParams.append("previousPackageSlug", slug);
|
|
6192
6351
|
});
|
|
6193
6352
|
}
|
|
6353
|
+
if (command12.gitRemoteUrl) {
|
|
6354
|
+
queryParams.append("gitRemoteUrl", command12.gitRemoteUrl);
|
|
6355
|
+
}
|
|
6356
|
+
if (command12.gitBranch) {
|
|
6357
|
+
queryParams.append("gitBranch", command12.gitBranch);
|
|
6358
|
+
}
|
|
6359
|
+
if (command12.relativePath) {
|
|
6360
|
+
queryParams.append("relativePath", command12.relativePath);
|
|
6361
|
+
}
|
|
6194
6362
|
const url = `${host}/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`;
|
|
6195
6363
|
try {
|
|
6196
6364
|
const response = await fetch(url, {
|
|
@@ -6727,7 +6895,7 @@ var PackmindGateway = class {
|
|
|
6727
6895
|
);
|
|
6728
6896
|
}
|
|
6729
6897
|
};
|
|
6730
|
-
this.uploadSkill = async (
|
|
6898
|
+
this.uploadSkill = async (command12) => {
|
|
6731
6899
|
const decodedApiKey = decodeApiKey(this.apiKey);
|
|
6732
6900
|
if (!decodedApiKey.isValid) {
|
|
6733
6901
|
if (decodedApiKey.error === "NOT_LOGGED_IN") {
|
|
@@ -6755,7 +6923,7 @@ var PackmindGateway = class {
|
|
|
6755
6923
|
}
|
|
6756
6924
|
const space = await spaceResponse.json();
|
|
6757
6925
|
const spaceId = space.id;
|
|
6758
|
-
const files = await readSkillDirectory(
|
|
6926
|
+
const files = await readSkillDirectory(command12.skillPath);
|
|
6759
6927
|
if (!files.find((f) => f.relativePath === "SKILL.md")) {
|
|
6760
6928
|
throw new Error("SKILL.md not found in skill directory");
|
|
6761
6929
|
}
|
|
@@ -6825,6 +6993,96 @@ var PackmindGateway = class {
|
|
|
6825
6993
|
);
|
|
6826
6994
|
}
|
|
6827
6995
|
};
|
|
6996
|
+
this.getDefaultSkills = async () => {
|
|
6997
|
+
const decodedApiKey = decodeApiKey(this.apiKey);
|
|
6998
|
+
if (!decodedApiKey.isValid) {
|
|
6999
|
+
if (decodedApiKey.error === "NOT_LOGGED_IN") {
|
|
7000
|
+
throw new NotLoggedInError();
|
|
7001
|
+
}
|
|
7002
|
+
throw new Error(`Invalid API key: ${decodedApiKey.error}`);
|
|
7003
|
+
}
|
|
7004
|
+
const { host, jwt } = decodedApiKey.payload;
|
|
7005
|
+
const jwtPayload = decodeJwt(jwt);
|
|
7006
|
+
if (!jwtPayload?.organization?.id) {
|
|
7007
|
+
throw new Error("Invalid API key: missing organizationId in JWT");
|
|
7008
|
+
}
|
|
7009
|
+
const organizationId = jwtPayload.organization.id;
|
|
7010
|
+
const url = `${host}/api/v0/organizations/${organizationId}/skills/default`;
|
|
7011
|
+
try {
|
|
7012
|
+
const response = await fetch(url, {
|
|
7013
|
+
method: "GET",
|
|
7014
|
+
headers: {
|
|
7015
|
+
"Content-Type": "application/json",
|
|
7016
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
7017
|
+
}
|
|
7018
|
+
});
|
|
7019
|
+
if (!response.ok) {
|
|
7020
|
+
let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
|
|
7021
|
+
try {
|
|
7022
|
+
const errorBody = await response.json();
|
|
7023
|
+
if (errorBody?.message) {
|
|
7024
|
+
errorMsg = errorBody.message;
|
|
7025
|
+
}
|
|
7026
|
+
} catch {
|
|
7027
|
+
}
|
|
7028
|
+
throw new Error(errorMsg);
|
|
7029
|
+
}
|
|
7030
|
+
const result = await response.json();
|
|
7031
|
+
return result;
|
|
7032
|
+
} catch (error) {
|
|
7033
|
+
const err = error;
|
|
7034
|
+
const code = err?.code || err?.cause?.code;
|
|
7035
|
+
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"))) {
|
|
7036
|
+
throw new Error(
|
|
7037
|
+
`Packmind server is not accessible at ${host}. Please check your network connection or the server URL.`
|
|
7038
|
+
);
|
|
7039
|
+
}
|
|
7040
|
+
throw new Error(
|
|
7041
|
+
`Failed to get default skills: Error: ${err?.message || JSON.stringify(error)}`
|
|
7042
|
+
);
|
|
7043
|
+
}
|
|
7044
|
+
};
|
|
7045
|
+
this.getGlobalSpace = async () => {
|
|
7046
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7047
|
+
return this.httpClient.request(
|
|
7048
|
+
`/api/v0/organizations/${organizationId}/spaces/global`
|
|
7049
|
+
);
|
|
7050
|
+
};
|
|
7051
|
+
this.createStandardInSpace = async (spaceId, data) => {
|
|
7052
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7053
|
+
return this.httpClient.request(
|
|
7054
|
+
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards`,
|
|
7055
|
+
{ method: "POST", body: data }
|
|
7056
|
+
);
|
|
7057
|
+
};
|
|
7058
|
+
this.getRulesForStandard = async (spaceId, standardId) => {
|
|
7059
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7060
|
+
return this.httpClient.request(
|
|
7061
|
+
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards/${standardId}/rules`
|
|
7062
|
+
);
|
|
7063
|
+
};
|
|
7064
|
+
this.addExampleToRule = async (spaceId, standardId, ruleId, example) => {
|
|
7065
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7066
|
+
await this.httpClient.request(
|
|
7067
|
+
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/standards/${standardId}/rules/${ruleId}/examples`,
|
|
7068
|
+
{
|
|
7069
|
+
method: "POST",
|
|
7070
|
+
body: {
|
|
7071
|
+
lang: example.language,
|
|
7072
|
+
positive: example.positive,
|
|
7073
|
+
negative: example.negative
|
|
7074
|
+
}
|
|
7075
|
+
}
|
|
7076
|
+
);
|
|
7077
|
+
};
|
|
7078
|
+
this.createCommand = async (spaceId, data) => {
|
|
7079
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7080
|
+
return this.httpClient.request(
|
|
7081
|
+
`/api/v0/organizations/${organizationId}/spaces/${spaceId}/recipes`,
|
|
7082
|
+
{ method: "POST", body: data }
|
|
7083
|
+
);
|
|
7084
|
+
};
|
|
7085
|
+
this.httpClient = new PackmindHttpClient(apiKey);
|
|
6828
7086
|
}
|
|
6829
7087
|
};
|
|
6830
7088
|
|
|
@@ -8568,8 +8826,8 @@ var ExecuteLinterProgramsUseCase = class {
|
|
|
8568
8826
|
this.linterAstAdapter = linterAstAdapter;
|
|
8569
8827
|
this.logger = logger2;
|
|
8570
8828
|
}
|
|
8571
|
-
async execute(
|
|
8572
|
-
const { filePath, fileContent, language, programs } =
|
|
8829
|
+
async execute(command12) {
|
|
8830
|
+
const { filePath, fileContent, language, programs } = command12;
|
|
8573
8831
|
if (programs.length === 0) {
|
|
8574
8832
|
return {
|
|
8575
8833
|
file: filePath,
|
|
@@ -9573,6 +9831,51 @@ var SSEEventPublisher = class _SSEEventPublisher {
|
|
|
9573
9831
|
throw error;
|
|
9574
9832
|
}
|
|
9575
9833
|
}
|
|
9834
|
+
/**
|
|
9835
|
+
* Publish a distribution status change event for cache invalidation
|
|
9836
|
+
* This triggers React Query to refetch the distribution data when status changes
|
|
9837
|
+
*/
|
|
9838
|
+
static async publishDistributionStatusChangeEvent(distributionId, status, organizationId) {
|
|
9839
|
+
_SSEEventPublisher.logger.info(
|
|
9840
|
+
"Publishing distribution status change event",
|
|
9841
|
+
{
|
|
9842
|
+
distributionId,
|
|
9843
|
+
status,
|
|
9844
|
+
organizationId
|
|
9845
|
+
}
|
|
9846
|
+
);
|
|
9847
|
+
try {
|
|
9848
|
+
const event = createDistributionStatusChangeEvent(
|
|
9849
|
+
distributionId,
|
|
9850
|
+
status,
|
|
9851
|
+
organizationId
|
|
9852
|
+
);
|
|
9853
|
+
await _SSEEventPublisher.publishEvent(
|
|
9854
|
+
"DISTRIBUTION_STATUS_CHANGE",
|
|
9855
|
+
[organizationId],
|
|
9856
|
+
event
|
|
9857
|
+
);
|
|
9858
|
+
_SSEEventPublisher.logger.debug(
|
|
9859
|
+
"Successfully published distribution status change event",
|
|
9860
|
+
{
|
|
9861
|
+
distributionId,
|
|
9862
|
+
status,
|
|
9863
|
+
organizationId
|
|
9864
|
+
}
|
|
9865
|
+
);
|
|
9866
|
+
} catch (error) {
|
|
9867
|
+
_SSEEventPublisher.logger.error(
|
|
9868
|
+
"Failed to publish distribution status change event",
|
|
9869
|
+
{
|
|
9870
|
+
distributionId,
|
|
9871
|
+
status,
|
|
9872
|
+
organizationId,
|
|
9873
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9874
|
+
}
|
|
9875
|
+
);
|
|
9876
|
+
throw error;
|
|
9877
|
+
}
|
|
9878
|
+
}
|
|
9576
9879
|
/**
|
|
9577
9880
|
* Generic method to publish any SSE event type to Redis pub/sub
|
|
9578
9881
|
*/
|
|
@@ -9657,6 +9960,11 @@ ${sectionBlock}
|
|
|
9657
9960
|
return result;
|
|
9658
9961
|
}
|
|
9659
9962
|
|
|
9963
|
+
// packages/node-utils/src/text/urlUtils.ts
|
|
9964
|
+
function removeTrailingSlash(url) {
|
|
9965
|
+
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
9966
|
+
}
|
|
9967
|
+
|
|
9660
9968
|
// apps/cli/src/application/useCases/InstallPackagesUseCase.ts
|
|
9661
9969
|
var fs5 = __toESM(require("fs/promises"));
|
|
9662
9970
|
var path6 = __toESM(require("path"));
|
|
@@ -9664,8 +9972,8 @@ var InstallPackagesUseCase = class {
|
|
|
9664
9972
|
constructor(packmindGateway) {
|
|
9665
9973
|
this.packmindGateway = packmindGateway;
|
|
9666
9974
|
}
|
|
9667
|
-
async execute(
|
|
9668
|
-
const baseDirectory =
|
|
9975
|
+
async execute(command12) {
|
|
9976
|
+
const baseDirectory = command12.baseDirectory || process.cwd();
|
|
9669
9977
|
const result = {
|
|
9670
9978
|
filesCreated: 0,
|
|
9671
9979
|
filesUpdated: 0,
|
|
@@ -9673,11 +9981,15 @@ var InstallPackagesUseCase = class {
|
|
|
9673
9981
|
errors: [],
|
|
9674
9982
|
recipesCount: 0,
|
|
9675
9983
|
standardsCount: 0,
|
|
9676
|
-
skillsCount: 0
|
|
9984
|
+
skillsCount: 0,
|
|
9985
|
+
skillDirectoriesDeleted: 0
|
|
9677
9986
|
};
|
|
9678
9987
|
const response = await this.packmindGateway.getPullData({
|
|
9679
|
-
packagesSlugs:
|
|
9680
|
-
previousPackagesSlugs:
|
|
9988
|
+
packagesSlugs: command12.packagesSlugs,
|
|
9989
|
+
previousPackagesSlugs: command12.previousPackagesSlugs,
|
|
9990
|
+
gitRemoteUrl: command12.gitRemoteUrl,
|
|
9991
|
+
gitBranch: command12.gitBranch,
|
|
9992
|
+
relativePath: command12.relativePath
|
|
9681
9993
|
});
|
|
9682
9994
|
const uniqueFilesMap = /* @__PURE__ */ new Map();
|
|
9683
9995
|
for (const file of response.fileUpdates.createOrUpdate) {
|
|
@@ -9694,6 +10006,10 @@ var InstallPackagesUseCase = class {
|
|
|
9694
10006
|
}
|
|
9695
10007
|
}
|
|
9696
10008
|
try {
|
|
10009
|
+
result.skillDirectoriesDeleted = await this.deleteSkillFolders(
|
|
10010
|
+
baseDirectory,
|
|
10011
|
+
response.skillFolders
|
|
10012
|
+
);
|
|
9697
10013
|
for (const file of uniqueFiles) {
|
|
9698
10014
|
try {
|
|
9699
10015
|
await this.createOrUpdateFile(baseDirectory, file, result);
|
|
@@ -9871,6 +10187,98 @@ ${endMarker}`;
|
|
|
9871
10187
|
escapeRegex(str) {
|
|
9872
10188
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9873
10189
|
}
|
|
10190
|
+
/**
|
|
10191
|
+
* Deletes all skill folders before recreating them with fresh content.
|
|
10192
|
+
* Returns the count of files that were actually deleted.
|
|
10193
|
+
*/
|
|
10194
|
+
async deleteSkillFolders(baseDirectory, folders) {
|
|
10195
|
+
let deletedFilesCount = 0;
|
|
10196
|
+
for (const folder of folders) {
|
|
10197
|
+
const fullPath = path6.join(baseDirectory, folder);
|
|
10198
|
+
try {
|
|
10199
|
+
await fs5.access(fullPath);
|
|
10200
|
+
const fileCount = await this.countFilesInDirectory(fullPath);
|
|
10201
|
+
await fs5.rm(fullPath, { recursive: true, force: true });
|
|
10202
|
+
deletedFilesCount += fileCount;
|
|
10203
|
+
} catch {
|
|
10204
|
+
}
|
|
10205
|
+
}
|
|
10206
|
+
return deletedFilesCount;
|
|
10207
|
+
}
|
|
10208
|
+
/**
|
|
10209
|
+
* Recursively counts all files in a directory.
|
|
10210
|
+
*/
|
|
10211
|
+
async countFilesInDirectory(dirPath) {
|
|
10212
|
+
let count = 0;
|
|
10213
|
+
const entries = await fs5.readdir(dirPath, { withFileTypes: true });
|
|
10214
|
+
for (const entry of entries) {
|
|
10215
|
+
const entryPath = path6.join(dirPath, entry.name);
|
|
10216
|
+
if (entry.isDirectory()) {
|
|
10217
|
+
count += await this.countFilesInDirectory(entryPath);
|
|
10218
|
+
} else {
|
|
10219
|
+
count++;
|
|
10220
|
+
}
|
|
10221
|
+
}
|
|
10222
|
+
return count;
|
|
10223
|
+
}
|
|
10224
|
+
};
|
|
10225
|
+
|
|
10226
|
+
// apps/cli/src/application/useCases/InstallDefaultSkillsUseCase.ts
|
|
10227
|
+
var fs6 = __toESM(require("fs/promises"));
|
|
10228
|
+
var path7 = __toESM(require("path"));
|
|
10229
|
+
var InstallDefaultSkillsUseCase = class {
|
|
10230
|
+
constructor(packmindGateway) {
|
|
10231
|
+
this.packmindGateway = packmindGateway;
|
|
10232
|
+
}
|
|
10233
|
+
async execute(command12) {
|
|
10234
|
+
const baseDirectory = command12.baseDirectory || process.cwd();
|
|
10235
|
+
const result = {
|
|
10236
|
+
filesCreated: 0,
|
|
10237
|
+
filesUpdated: 0,
|
|
10238
|
+
errors: []
|
|
10239
|
+
};
|
|
10240
|
+
const response = await this.packmindGateway.getDefaultSkills({});
|
|
10241
|
+
try {
|
|
10242
|
+
for (const file of response.fileUpdates.createOrUpdate) {
|
|
10243
|
+
try {
|
|
10244
|
+
await this.createOrUpdateFile(baseDirectory, file, result);
|
|
10245
|
+
} catch (error) {
|
|
10246
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10247
|
+
result.errors.push(
|
|
10248
|
+
`Failed to create/update ${file.path}: ${errorMsg}`
|
|
10249
|
+
);
|
|
10250
|
+
}
|
|
10251
|
+
}
|
|
10252
|
+
} catch (error) {
|
|
10253
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10254
|
+
result.errors.push(`Failed to install default skills: ${errorMsg}`);
|
|
10255
|
+
}
|
|
10256
|
+
return result;
|
|
10257
|
+
}
|
|
10258
|
+
async createOrUpdateFile(baseDirectory, file, result) {
|
|
10259
|
+
const fullPath = path7.join(baseDirectory, file.path);
|
|
10260
|
+
const directory = path7.dirname(fullPath);
|
|
10261
|
+
await fs6.mkdir(directory, { recursive: true });
|
|
10262
|
+
const fileExists = await this.fileExists(fullPath);
|
|
10263
|
+
if (fileExists) {
|
|
10264
|
+
const existingContent = await fs6.readFile(fullPath, "utf-8");
|
|
10265
|
+
if (existingContent !== file.content) {
|
|
10266
|
+
await fs6.writeFile(fullPath, file.content, "utf-8");
|
|
10267
|
+
result.filesUpdated++;
|
|
10268
|
+
}
|
|
10269
|
+
} else {
|
|
10270
|
+
await fs6.writeFile(fullPath, file.content, "utf-8");
|
|
10271
|
+
result.filesCreated++;
|
|
10272
|
+
}
|
|
10273
|
+
}
|
|
10274
|
+
async fileExists(filePath) {
|
|
10275
|
+
try {
|
|
10276
|
+
await fs6.access(filePath);
|
|
10277
|
+
return true;
|
|
10278
|
+
} catch {
|
|
10279
|
+
return false;
|
|
10280
|
+
}
|
|
10281
|
+
}
|
|
9874
10282
|
};
|
|
9875
10283
|
|
|
9876
10284
|
// apps/cli/src/application/useCases/ListPackagesUseCase.ts
|
|
@@ -9888,8 +10296,8 @@ var GetPackageSummaryUseCase = class {
|
|
|
9888
10296
|
constructor(gateway) {
|
|
9889
10297
|
this.gateway = gateway;
|
|
9890
10298
|
}
|
|
9891
|
-
async execute(
|
|
9892
|
-
return this.gateway.getPackageSummary(
|
|
10299
|
+
async execute(command12) {
|
|
10300
|
+
return this.gateway.getPackageSummary(command12);
|
|
9893
10301
|
}
|
|
9894
10302
|
};
|
|
9895
10303
|
|
|
@@ -9949,13 +10357,13 @@ var EnvCredentialsProvider = class {
|
|
|
9949
10357
|
};
|
|
9950
10358
|
|
|
9951
10359
|
// apps/cli/src/infra/utils/credentials/FileCredentialsProvider.ts
|
|
9952
|
-
var
|
|
9953
|
-
var
|
|
10360
|
+
var fs7 = __toESM(require("fs"));
|
|
10361
|
+
var path8 = __toESM(require("path"));
|
|
9954
10362
|
var os2 = __toESM(require("os"));
|
|
9955
10363
|
var CREDENTIALS_DIR = ".packmind";
|
|
9956
10364
|
var CREDENTIALS_FILE = "credentials.json";
|
|
9957
10365
|
function getCredentialsPath() {
|
|
9958
|
-
return
|
|
10366
|
+
return path8.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
|
|
9959
10367
|
}
|
|
9960
10368
|
var FileCredentialsProvider = class {
|
|
9961
10369
|
getSourceName() {
|
|
@@ -9963,11 +10371,11 @@ var FileCredentialsProvider = class {
|
|
|
9963
10371
|
}
|
|
9964
10372
|
hasCredentials() {
|
|
9965
10373
|
const credentialsPath = getCredentialsPath();
|
|
9966
|
-
if (!
|
|
10374
|
+
if (!fs7.existsSync(credentialsPath)) {
|
|
9967
10375
|
return false;
|
|
9968
10376
|
}
|
|
9969
10377
|
try {
|
|
9970
|
-
const content =
|
|
10378
|
+
const content = fs7.readFileSync(credentialsPath, "utf-8");
|
|
9971
10379
|
const credentials = JSON.parse(content);
|
|
9972
10380
|
return !!credentials.apiKey;
|
|
9973
10381
|
} catch {
|
|
@@ -9976,11 +10384,11 @@ var FileCredentialsProvider = class {
|
|
|
9976
10384
|
}
|
|
9977
10385
|
loadCredentials() {
|
|
9978
10386
|
const credentialsPath = getCredentialsPath();
|
|
9979
|
-
if (!
|
|
10387
|
+
if (!fs7.existsSync(credentialsPath)) {
|
|
9980
10388
|
return null;
|
|
9981
10389
|
}
|
|
9982
10390
|
try {
|
|
9983
|
-
const content =
|
|
10391
|
+
const content = fs7.readFileSync(credentialsPath, "utf-8");
|
|
9984
10392
|
const credentials = JSON.parse(content);
|
|
9985
10393
|
if (!credentials.apiKey) {
|
|
9986
10394
|
return null;
|
|
@@ -10003,13 +10411,13 @@ var FileCredentialsProvider = class {
|
|
|
10003
10411
|
}
|
|
10004
10412
|
};
|
|
10005
10413
|
function saveCredentials(apiKey) {
|
|
10006
|
-
const credentialsDir =
|
|
10007
|
-
if (!
|
|
10008
|
-
|
|
10414
|
+
const credentialsDir = path8.join(os2.homedir(), CREDENTIALS_DIR);
|
|
10415
|
+
if (!fs7.existsSync(credentialsDir)) {
|
|
10416
|
+
fs7.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
|
|
10009
10417
|
}
|
|
10010
10418
|
const credentialsPath = getCredentialsPath();
|
|
10011
10419
|
const credentials = { apiKey };
|
|
10012
|
-
|
|
10420
|
+
fs7.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
|
|
10013
10421
|
mode: 384
|
|
10014
10422
|
});
|
|
10015
10423
|
}
|
|
@@ -10088,7 +10496,8 @@ async function defaultPromptForCode() {
|
|
|
10088
10496
|
});
|
|
10089
10497
|
}
|
|
10090
10498
|
async function defaultExchangeCodeForApiKey(code, host) {
|
|
10091
|
-
const
|
|
10499
|
+
const normalizedHost = removeTrailingSlash(host);
|
|
10500
|
+
const url = `${normalizedHost}/api/v0/auth/cli-login-exchange`;
|
|
10092
10501
|
const response = await fetch(url, {
|
|
10093
10502
|
method: "POST",
|
|
10094
10503
|
headers: {
|
|
@@ -10167,15 +10576,16 @@ var LoginUseCase = class {
|
|
|
10167
10576
|
startCallbackServer: deps?.startCallbackServer ?? defaultStartCallbackServer
|
|
10168
10577
|
};
|
|
10169
10578
|
}
|
|
10170
|
-
async execute(
|
|
10171
|
-
const { host, code: providedCode } =
|
|
10579
|
+
async execute(command12) {
|
|
10580
|
+
const { host, code: providedCode } = command12;
|
|
10172
10581
|
let code;
|
|
10173
10582
|
if (providedCode) {
|
|
10174
10583
|
code = providedCode;
|
|
10175
10584
|
} else {
|
|
10176
10585
|
const callbackPromise = this.deps.startCallbackServer();
|
|
10177
10586
|
const callbackUrl = `http://127.0.0.1:${CALLBACK_PORT}`;
|
|
10178
|
-
const
|
|
10587
|
+
const normalizedHost = removeTrailingSlash(host);
|
|
10588
|
+
const loginUrl = `${normalizedHost}/cli-login?callback_url=${encodeURIComponent(callbackUrl)}`;
|
|
10179
10589
|
try {
|
|
10180
10590
|
await this.deps.openBrowser(loginUrl);
|
|
10181
10591
|
} catch {
|
|
@@ -10199,14 +10609,14 @@ var LoginUseCase = class {
|
|
|
10199
10609
|
};
|
|
10200
10610
|
|
|
10201
10611
|
// apps/cli/src/application/useCases/LogoutUseCase.ts
|
|
10202
|
-
var
|
|
10612
|
+
var fs8 = __toESM(require("fs"));
|
|
10203
10613
|
var ENV_VAR_NAME2 = "PACKMIND_API_KEY_V3";
|
|
10204
10614
|
var LogoutUseCase = class {
|
|
10205
10615
|
constructor(deps) {
|
|
10206
10616
|
this.deps = {
|
|
10207
10617
|
getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
|
|
10208
|
-
fileExists: deps?.fileExists ?? ((
|
|
10209
|
-
deleteFile: deps?.deleteFile ?? ((
|
|
10618
|
+
fileExists: deps?.fileExists ?? ((path13) => fs8.existsSync(path13)),
|
|
10619
|
+
deleteFile: deps?.deleteFile ?? ((path13) => fs8.unlinkSync(path13)),
|
|
10210
10620
|
hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
|
|
10211
10621
|
};
|
|
10212
10622
|
}
|
|
@@ -10266,8 +10676,8 @@ var SetupMcpUseCase = class {
|
|
|
10266
10676
|
constructor(deps) {
|
|
10267
10677
|
this.deps = deps;
|
|
10268
10678
|
}
|
|
10269
|
-
async execute(
|
|
10270
|
-
const { agentTypes } =
|
|
10679
|
+
async execute(command12) {
|
|
10680
|
+
const { agentTypes } = command12;
|
|
10271
10681
|
const [tokenResult, urlResult] = await Promise.all([
|
|
10272
10682
|
this.deps.gateway.getMcpToken({}),
|
|
10273
10683
|
this.deps.gateway.getMcpUrl({})
|
|
@@ -10302,8 +10712,8 @@ var SetupMcpUseCase = class {
|
|
|
10302
10712
|
};
|
|
10303
10713
|
|
|
10304
10714
|
// apps/cli/src/application/services/McpConfigService.ts
|
|
10305
|
-
var
|
|
10306
|
-
var
|
|
10715
|
+
var fs9 = __toESM(require("fs"));
|
|
10716
|
+
var path9 = __toESM(require("path"));
|
|
10307
10717
|
var os3 = __toESM(require("os"));
|
|
10308
10718
|
var import_child_process2 = require("child_process");
|
|
10309
10719
|
var McpConfigService = class {
|
|
@@ -10338,9 +10748,9 @@ var McpConfigService = class {
|
|
|
10338
10748
|
return JSON.stringify(mcpConfig, null, 2);
|
|
10339
10749
|
}
|
|
10340
10750
|
installClaudeMcp(config) {
|
|
10341
|
-
const
|
|
10751
|
+
const command12 = `claude mcp add --transport http packmind ${config.url} --header "Authorization: Bearer ${config.accessToken}"`;
|
|
10342
10752
|
try {
|
|
10343
|
-
(0, import_child_process2.execSync)(
|
|
10753
|
+
(0, import_child_process2.execSync)(command12, { stdio: "pipe" });
|
|
10344
10754
|
return { success: true };
|
|
10345
10755
|
} catch (error) {
|
|
10346
10756
|
const execError = error;
|
|
@@ -10350,11 +10760,11 @@ var McpConfigService = class {
|
|
|
10350
10760
|
}
|
|
10351
10761
|
installCursorMcp(config) {
|
|
10352
10762
|
try {
|
|
10353
|
-
const cursorConfigPath =
|
|
10763
|
+
const cursorConfigPath = path9.join(os3.homedir(), ".cursor", "mcp.json");
|
|
10354
10764
|
const cursorConfig = this.buildCursorConfig(config);
|
|
10355
10765
|
const existingConfig = this.readExistingJsonConfig(cursorConfigPath);
|
|
10356
10766
|
const mergedConfig = this.mergeConfig(existingConfig, cursorConfig);
|
|
10357
|
-
|
|
10767
|
+
fs9.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
10358
10768
|
return { success: true };
|
|
10359
10769
|
} catch (error) {
|
|
10360
10770
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10363,15 +10773,15 @@ var McpConfigService = class {
|
|
|
10363
10773
|
}
|
|
10364
10774
|
installVSCodeMcp(config) {
|
|
10365
10775
|
try {
|
|
10366
|
-
const vscodeDir =
|
|
10367
|
-
if (!
|
|
10368
|
-
|
|
10776
|
+
const vscodeDir = path9.join(this.projectDir, ".vscode");
|
|
10777
|
+
if (!fs9.existsSync(vscodeDir)) {
|
|
10778
|
+
fs9.mkdirSync(vscodeDir, { recursive: true });
|
|
10369
10779
|
}
|
|
10370
|
-
const vscodeConfigPath =
|
|
10780
|
+
const vscodeConfigPath = path9.join(vscodeDir, "mcp.json");
|
|
10371
10781
|
const vscodeConfig = this.buildVSCodeConfig(config);
|
|
10372
10782
|
const existingConfig = this.readExistingJsonConfig(vscodeConfigPath);
|
|
10373
10783
|
const mergedConfig = this.mergeVSCodeConfig(existingConfig, vscodeConfig);
|
|
10374
|
-
|
|
10784
|
+
fs9.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
10375
10785
|
return { success: true };
|
|
10376
10786
|
} catch (error) {
|
|
10377
10787
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10380,14 +10790,14 @@ var McpConfigService = class {
|
|
|
10380
10790
|
}
|
|
10381
10791
|
installContinueMcp(config) {
|
|
10382
10792
|
try {
|
|
10383
|
-
const continueDir =
|
|
10384
|
-
const mcpServersDir =
|
|
10385
|
-
if (!
|
|
10386
|
-
|
|
10793
|
+
const continueDir = path9.join(this.projectDir, ".continue");
|
|
10794
|
+
const mcpServersDir = path9.join(continueDir, "mcpServers");
|
|
10795
|
+
if (!fs9.existsSync(mcpServersDir)) {
|
|
10796
|
+
fs9.mkdirSync(mcpServersDir, { recursive: true });
|
|
10387
10797
|
}
|
|
10388
|
-
const continueConfigPath =
|
|
10798
|
+
const continueConfigPath = path9.join(mcpServersDir, "packmind.yaml");
|
|
10389
10799
|
const continueConfig = this.buildContinueYamlConfig(config);
|
|
10390
|
-
|
|
10800
|
+
fs9.writeFileSync(continueConfigPath, continueConfig);
|
|
10391
10801
|
return { success: true };
|
|
10392
10802
|
} catch (error) {
|
|
10393
10803
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10435,8 +10845,8 @@ mcpServers:
|
|
|
10435
10845
|
}
|
|
10436
10846
|
readExistingJsonConfig(filePath) {
|
|
10437
10847
|
try {
|
|
10438
|
-
if (
|
|
10439
|
-
const content =
|
|
10848
|
+
if (fs9.existsSync(filePath)) {
|
|
10849
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
10440
10850
|
return JSON.parse(content);
|
|
10441
10851
|
}
|
|
10442
10852
|
} catch {
|
|
@@ -10469,41 +10879,8 @@ mcpServers:
|
|
|
10469
10879
|
};
|
|
10470
10880
|
|
|
10471
10881
|
// apps/cli/src/infra/repositories/ConfigFileRepository.ts
|
|
10472
|
-
var
|
|
10473
|
-
var
|
|
10474
|
-
|
|
10475
|
-
// apps/cli/src/infra/utils/consoleLogger.ts
|
|
10476
|
-
init_source();
|
|
10477
|
-
var CLI_PREFIX = "packmind-cli";
|
|
10478
|
-
function logWarningConsole(message) {
|
|
10479
|
-
console.warn(source_default.bgYellow.bold(CLI_PREFIX), source_default.yellow(message));
|
|
10480
|
-
}
|
|
10481
|
-
function logInfoConsole(message) {
|
|
10482
|
-
console.log(source_default.bgBlue.bold(CLI_PREFIX), source_default.blue(message));
|
|
10483
|
-
}
|
|
10484
|
-
function logErrorConsole(message) {
|
|
10485
|
-
console.error(source_default.bgRed.bold(CLI_PREFIX), source_default.red(message));
|
|
10486
|
-
}
|
|
10487
|
-
function logSuccessConsole(message) {
|
|
10488
|
-
console.log(source_default.bgGreen.bold(CLI_PREFIX), source_default.green.bold(message));
|
|
10489
|
-
}
|
|
10490
|
-
function formatSlug(text) {
|
|
10491
|
-
return source_default.blue.bold(text);
|
|
10492
|
-
}
|
|
10493
|
-
function formatLabel(text) {
|
|
10494
|
-
return source_default.dim(text);
|
|
10495
|
-
}
|
|
10496
|
-
function formatError(text) {
|
|
10497
|
-
return source_default.red(text);
|
|
10498
|
-
}
|
|
10499
|
-
function formatBold(text) {
|
|
10500
|
-
return source_default.bold(text);
|
|
10501
|
-
}
|
|
10502
|
-
function formatFilePath(text) {
|
|
10503
|
-
return source_default.underline.gray(text);
|
|
10504
|
-
}
|
|
10505
|
-
|
|
10506
|
-
// apps/cli/src/infra/repositories/ConfigFileRepository.ts
|
|
10882
|
+
var fs10 = __toESM(require("fs/promises"));
|
|
10883
|
+
var path10 = __toESM(require("path"));
|
|
10507
10884
|
var ConfigFileRepository = class {
|
|
10508
10885
|
constructor() {
|
|
10509
10886
|
this.CONFIG_FILENAME = "packmind.json";
|
|
@@ -10518,23 +10895,23 @@ var ConfigFileRepository = class {
|
|
|
10518
10895
|
];
|
|
10519
10896
|
}
|
|
10520
10897
|
async writeConfig(baseDirectory, config) {
|
|
10521
|
-
const configPath =
|
|
10898
|
+
const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
|
|
10522
10899
|
const configContent = JSON.stringify(config, null, 2) + "\n";
|
|
10523
|
-
await
|
|
10900
|
+
await fs10.writeFile(configPath, configContent, "utf-8");
|
|
10524
10901
|
}
|
|
10525
10902
|
async configExists(baseDirectory) {
|
|
10526
|
-
const configPath =
|
|
10903
|
+
const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
|
|
10527
10904
|
try {
|
|
10528
|
-
await
|
|
10905
|
+
await fs10.access(configPath);
|
|
10529
10906
|
return true;
|
|
10530
10907
|
} catch {
|
|
10531
10908
|
return false;
|
|
10532
10909
|
}
|
|
10533
10910
|
}
|
|
10534
10911
|
async readConfig(baseDirectory) {
|
|
10535
|
-
const configPath =
|
|
10912
|
+
const configPath = path10.join(baseDirectory, this.CONFIG_FILENAME);
|
|
10536
10913
|
try {
|
|
10537
|
-
const configContent = await
|
|
10914
|
+
const configContent = await fs10.readFile(configPath, "utf-8");
|
|
10538
10915
|
const config = JSON.parse(configContent);
|
|
10539
10916
|
if (!config.packages || typeof config.packages !== "object") {
|
|
10540
10917
|
throw new Error(
|
|
@@ -10561,12 +10938,12 @@ var ConfigFileRepository = class {
|
|
|
10561
10938
|
* @returns Array of directory paths that contain a packmind.json file
|
|
10562
10939
|
*/
|
|
10563
10940
|
async findDescendantConfigs(directory) {
|
|
10564
|
-
const normalizedDir = normalizePath(
|
|
10941
|
+
const normalizedDir = normalizePath(path10.resolve(directory));
|
|
10565
10942
|
const results = [];
|
|
10566
10943
|
const searchRecursively = async (currentDir) => {
|
|
10567
10944
|
let entries;
|
|
10568
10945
|
try {
|
|
10569
|
-
entries = await
|
|
10946
|
+
entries = await fs10.readdir(currentDir, { withFileTypes: true });
|
|
10570
10947
|
} catch {
|
|
10571
10948
|
return;
|
|
10572
10949
|
}
|
|
@@ -10577,7 +10954,7 @@ var ConfigFileRepository = class {
|
|
|
10577
10954
|
if (this.EXCLUDED_DIRECTORIES.includes(entry.name)) {
|
|
10578
10955
|
continue;
|
|
10579
10956
|
}
|
|
10580
|
-
const entryPath = normalizePath(
|
|
10957
|
+
const entryPath = normalizePath(path10.join(currentDir, entry.name));
|
|
10581
10958
|
const config = await this.readConfig(entryPath);
|
|
10582
10959
|
if (config) {
|
|
10583
10960
|
results.push(entryPath);
|
|
@@ -10599,21 +10976,21 @@ var ConfigFileRepository = class {
|
|
|
10599
10976
|
async readHierarchicalConfig(startDirectory, stopDirectory) {
|
|
10600
10977
|
const configs = [];
|
|
10601
10978
|
const configPaths = [];
|
|
10602
|
-
const normalizedStart = normalizePath(
|
|
10603
|
-
const normalizedStop = stopDirectory ? normalizePath(
|
|
10979
|
+
const normalizedStart = normalizePath(path10.resolve(startDirectory));
|
|
10980
|
+
const normalizedStop = stopDirectory ? normalizePath(path10.resolve(stopDirectory)) : null;
|
|
10604
10981
|
let currentDir = normalizedStart;
|
|
10605
10982
|
while (true) {
|
|
10606
10983
|
const config = await this.readConfig(currentDir);
|
|
10607
10984
|
if (config) {
|
|
10608
10985
|
configs.push(config);
|
|
10609
10986
|
configPaths.push(
|
|
10610
|
-
normalizePath(
|
|
10987
|
+
normalizePath(path10.join(currentDir, this.CONFIG_FILENAME))
|
|
10611
10988
|
);
|
|
10612
10989
|
}
|
|
10613
10990
|
if (normalizedStop !== null && currentDir === normalizedStop) {
|
|
10614
10991
|
break;
|
|
10615
10992
|
}
|
|
10616
|
-
const parentDir = normalizePath(
|
|
10993
|
+
const parentDir = normalizePath(path10.dirname(currentDir));
|
|
10617
10994
|
if (parentDir === currentDir) {
|
|
10618
10995
|
break;
|
|
10619
10996
|
}
|
|
@@ -10642,8 +11019,8 @@ var ConfigFileRepository = class {
|
|
|
10642
11019
|
* @returns All configs found with their target paths
|
|
10643
11020
|
*/
|
|
10644
11021
|
async findAllConfigsInTree(startDirectory, stopDirectory) {
|
|
10645
|
-
const normalizedStart = normalizePath(
|
|
10646
|
-
const normalizedStop = stopDirectory ? normalizePath(
|
|
11022
|
+
const normalizedStart = normalizePath(path10.resolve(startDirectory));
|
|
11023
|
+
const normalizedStop = stopDirectory ? normalizePath(path10.resolve(stopDirectory)) : null;
|
|
10647
11024
|
const basePath = normalizedStop ?? normalizedStart;
|
|
10648
11025
|
const configsMap = /* @__PURE__ */ new Map();
|
|
10649
11026
|
let currentDir = normalizedStart;
|
|
@@ -10660,7 +11037,7 @@ var ConfigFileRepository = class {
|
|
|
10660
11037
|
if (normalizedStop !== null && currentDir === normalizedStop) {
|
|
10661
11038
|
break;
|
|
10662
11039
|
}
|
|
10663
|
-
const parentDir = normalizePath(
|
|
11040
|
+
const parentDir = normalizePath(path10.dirname(currentDir));
|
|
10664
11041
|
if (parentDir === currentDir) {
|
|
10665
11042
|
break;
|
|
10666
11043
|
}
|
|
@@ -10747,6 +11124,9 @@ var PackmindCliHexaFactory = class {
|
|
|
10747
11124
|
installPackages: new InstallPackagesUseCase(
|
|
10748
11125
|
this.repositories.packmindGateway
|
|
10749
11126
|
),
|
|
11127
|
+
installDefaultSkills: new InstallDefaultSkillsUseCase(
|
|
11128
|
+
this.repositories.packmindGateway
|
|
11129
|
+
),
|
|
10750
11130
|
listPackages: new ListPackagesUseCase(this.repositories.packmindGateway),
|
|
10751
11131
|
getPackageBySlug: new GetPackageSummaryUseCase(
|
|
10752
11132
|
this.repositories.packmindGateway
|
|
@@ -10783,29 +11163,29 @@ var PackmindCliHexa = class {
|
|
|
10783
11163
|
this.logger.info("Destroying PackmindCliHexa");
|
|
10784
11164
|
this.logger.info("PackmindCliHexa destroyed");
|
|
10785
11165
|
}
|
|
10786
|
-
async getGitRemoteUrl(
|
|
10787
|
-
return this.hexa.useCases.getGitRemoteUrl.execute(
|
|
11166
|
+
async getGitRemoteUrl(command12) {
|
|
11167
|
+
return this.hexa.useCases.getGitRemoteUrl.execute(command12);
|
|
10788
11168
|
}
|
|
10789
|
-
async executeSingleFileAst(
|
|
10790
|
-
return this.hexa.useCases.executeSingleFileAst.execute(
|
|
11169
|
+
async executeSingleFileAst(command12) {
|
|
11170
|
+
return this.hexa.useCases.executeSingleFileAst.execute(command12);
|
|
10791
11171
|
}
|
|
10792
|
-
async listFilesInDirectory(
|
|
10793
|
-
return this.hexa.useCases.listFilesInDirectoryUseCase.execute(
|
|
11172
|
+
async listFilesInDirectory(command12) {
|
|
11173
|
+
return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command12);
|
|
10794
11174
|
}
|
|
10795
|
-
async lintFilesInDirectory(
|
|
10796
|
-
return this.hexa.useCases.lintFilesInDirectory.execute(
|
|
11175
|
+
async lintFilesInDirectory(command12) {
|
|
11176
|
+
return this.hexa.useCases.lintFilesInDirectory.execute(command12);
|
|
10797
11177
|
}
|
|
10798
|
-
async lintFilesLocally(
|
|
10799
|
-
return this.hexa.useCases.lintFilesLocally.execute(
|
|
11178
|
+
async lintFilesLocally(command12) {
|
|
11179
|
+
return this.hexa.useCases.lintFilesLocally.execute(command12);
|
|
10800
11180
|
}
|
|
10801
|
-
async installPackages(
|
|
10802
|
-
return this.hexa.useCases.installPackages.execute(
|
|
11181
|
+
async installPackages(command12) {
|
|
11182
|
+
return this.hexa.useCases.installPackages.execute(command12);
|
|
10803
11183
|
}
|
|
10804
|
-
async listPackages(
|
|
10805
|
-
return this.hexa.useCases.listPackages.execute(
|
|
11184
|
+
async listPackages(command12) {
|
|
11185
|
+
return this.hexa.useCases.listPackages.execute(command12);
|
|
10806
11186
|
}
|
|
10807
|
-
async getPackageBySlug(
|
|
10808
|
-
return this.hexa.useCases.getPackageBySlug.execute(
|
|
11187
|
+
async getPackageBySlug(command12) {
|
|
11188
|
+
return this.hexa.useCases.getPackageBySlug.execute(command12);
|
|
10809
11189
|
}
|
|
10810
11190
|
async configExists(baseDirectory) {
|
|
10811
11191
|
return await this.hexa.repositories.configFileRepository.configExists(
|
|
@@ -10864,17 +11244,17 @@ var PackmindCliHexa = class {
|
|
|
10864
11244
|
directory
|
|
10865
11245
|
);
|
|
10866
11246
|
}
|
|
10867
|
-
async login(
|
|
10868
|
-
return this.hexa.useCases.login.execute(
|
|
11247
|
+
async login(command12) {
|
|
11248
|
+
return this.hexa.useCases.login.execute(command12);
|
|
10869
11249
|
}
|
|
10870
|
-
async logout(
|
|
10871
|
-
return this.hexa.useCases.logout.execute(
|
|
11250
|
+
async logout(command12) {
|
|
11251
|
+
return this.hexa.useCases.logout.execute(command12);
|
|
10872
11252
|
}
|
|
10873
|
-
async whoami(
|
|
10874
|
-
return this.hexa.useCases.whoami.execute(
|
|
11253
|
+
async whoami(command12) {
|
|
11254
|
+
return this.hexa.useCases.whoami.execute(command12);
|
|
10875
11255
|
}
|
|
10876
|
-
async setupMcp(
|
|
10877
|
-
return this.hexa.useCases.setupMcp.execute(
|
|
11256
|
+
async setupMcp(command12) {
|
|
11257
|
+
return this.hexa.useCases.setupMcp.execute(command12);
|
|
10878
11258
|
}
|
|
10879
11259
|
getCurrentBranch(repoPath) {
|
|
10880
11260
|
return this.hexa.services.gitRemoteUrlService.getCurrentBranch(repoPath).branch;
|
|
@@ -10882,11 +11262,17 @@ var PackmindCliHexa = class {
|
|
|
10882
11262
|
getGitRemoteUrlFromPath(repoPath) {
|
|
10883
11263
|
return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
|
|
10884
11264
|
}
|
|
10885
|
-
async notifyDistribution(
|
|
10886
|
-
return this.hexa.repositories.packmindGateway.notifyDistribution(
|
|
11265
|
+
async notifyDistribution(command12) {
|
|
11266
|
+
return this.hexa.repositories.packmindGateway.notifyDistribution(command12);
|
|
10887
11267
|
}
|
|
10888
|
-
async uploadSkill(
|
|
10889
|
-
return this.hexa.repositories.packmindGateway.uploadSkill(
|
|
11268
|
+
async uploadSkill(command12) {
|
|
11269
|
+
return this.hexa.repositories.packmindGateway.uploadSkill(command12);
|
|
11270
|
+
}
|
|
11271
|
+
async installDefaultSkills(command12) {
|
|
11272
|
+
return this.hexa.useCases.installDefaultSkills.execute(command12);
|
|
11273
|
+
}
|
|
11274
|
+
getPackmindGateway() {
|
|
11275
|
+
return this.hexa.repositories.packmindGateway;
|
|
10890
11276
|
}
|
|
10891
11277
|
};
|
|
10892
11278
|
|
|
@@ -10899,7 +11285,7 @@ var IDELintLogger = class {
|
|
|
10899
11285
|
}
|
|
10900
11286
|
logViolation(violation) {
|
|
10901
11287
|
violation.violations.forEach(({ line, character, standard, rule }) => {
|
|
10902
|
-
|
|
11288
|
+
logConsole(
|
|
10903
11289
|
`${violation.file}:${line}:${character}:error:@${standard}/${rule}`
|
|
10904
11290
|
);
|
|
10905
11291
|
});
|
|
@@ -10925,9 +11311,9 @@ var HumanReadableLogger = class {
|
|
|
10925
11311
|
}
|
|
10926
11312
|
}
|
|
10927
11313
|
logViolation(violation) {
|
|
10928
|
-
|
|
11314
|
+
logConsole(formatFilePath(violation.file));
|
|
10929
11315
|
violation.violations.forEach(({ line, character, standard, rule }) => {
|
|
10930
|
-
|
|
11316
|
+
logConsole(
|
|
10931
11317
|
formatError(` ${line}:${character} error @${standard}/${rule}`)
|
|
10932
11318
|
);
|
|
10933
11319
|
});
|
|
@@ -10943,7 +11329,7 @@ function isNotLoggedInError(error) {
|
|
|
10943
11329
|
}
|
|
10944
11330
|
async function lintHandler(args2, deps) {
|
|
10945
11331
|
const {
|
|
10946
|
-
path:
|
|
11332
|
+
path: path13,
|
|
10947
11333
|
draft,
|
|
10948
11334
|
rule,
|
|
10949
11335
|
language,
|
|
@@ -10963,7 +11349,7 @@ async function lintHandler(args2, deps) {
|
|
|
10963
11349
|
throw new Error("option --rule is required to use --draft mode");
|
|
10964
11350
|
}
|
|
10965
11351
|
const startedAt = Date.now();
|
|
10966
|
-
const targetPath =
|
|
11352
|
+
const targetPath = path13 ?? ".";
|
|
10967
11353
|
const hasArguments = !!(draft || rule || language);
|
|
10968
11354
|
const absolutePath = resolvePath(targetPath);
|
|
10969
11355
|
if (diff) {
|
|
@@ -11220,8 +11606,8 @@ function extractWasmFiles() {
|
|
|
11220
11606
|
|
|
11221
11607
|
// apps/cli/src/main.ts
|
|
11222
11608
|
var import_dotenv = require("dotenv");
|
|
11223
|
-
var
|
|
11224
|
-
var
|
|
11609
|
+
var fs15 = __toESM(require("fs"));
|
|
11610
|
+
var path12 = __toESM(require("path"));
|
|
11225
11611
|
|
|
11226
11612
|
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
11227
11613
|
var import_cmd_ts2 = __toESM(require_cjs());
|
|
@@ -11255,6 +11641,31 @@ async function notifyDistributionIfInGitRepo(params) {
|
|
|
11255
11641
|
return false;
|
|
11256
11642
|
}
|
|
11257
11643
|
}
|
|
11644
|
+
async function installDefaultSkillsIfAtGitRoot(params) {
|
|
11645
|
+
const { packmindCliHexa, cwd, log } = params;
|
|
11646
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
11647
|
+
if (!gitRoot || cwd !== gitRoot) {
|
|
11648
|
+
return;
|
|
11649
|
+
}
|
|
11650
|
+
try {
|
|
11651
|
+
log("\nInstalling default skills...");
|
|
11652
|
+
const skillsResult = await packmindCliHexa.installDefaultSkills({});
|
|
11653
|
+
if (skillsResult.errors.length > 0) {
|
|
11654
|
+
skillsResult.errors.forEach((err) => {
|
|
11655
|
+
log(` Warning: ${err}`);
|
|
11656
|
+
});
|
|
11657
|
+
}
|
|
11658
|
+
const totalSkillFiles = skillsResult.filesCreated + skillsResult.filesUpdated;
|
|
11659
|
+
if (totalSkillFiles > 0) {
|
|
11660
|
+
log(
|
|
11661
|
+
`Default skills: added ${skillsResult.filesCreated} files, changed ${skillsResult.filesUpdated} files`
|
|
11662
|
+
);
|
|
11663
|
+
} else if (skillsResult.errors.length === 0) {
|
|
11664
|
+
log("Default skills are already up to date");
|
|
11665
|
+
}
|
|
11666
|
+
} catch {
|
|
11667
|
+
}
|
|
11668
|
+
}
|
|
11258
11669
|
async function listPackagesHandler(_args, deps) {
|
|
11259
11670
|
const { packmindCliHexa, exit, log, error } = deps;
|
|
11260
11671
|
try {
|
|
@@ -11472,8 +11883,9 @@ async function executeInstallForDirectory(directory, deps) {
|
|
|
11472
11883
|
errorMessage: result.errors.join(", ")
|
|
11473
11884
|
};
|
|
11474
11885
|
}
|
|
11886
|
+
const skillDirsDeleted = result.skillDirectoriesDeleted || 0;
|
|
11475
11887
|
let notificationSent = false;
|
|
11476
|
-
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0) {
|
|
11888
|
+
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
|
|
11477
11889
|
notificationSent = await notifyDistributionIfInGitRepo({
|
|
11478
11890
|
packmindCliHexa,
|
|
11479
11891
|
cwd: directory,
|
|
@@ -11486,7 +11898,7 @@ async function executeInstallForDirectory(directory, deps) {
|
|
|
11486
11898
|
success: true,
|
|
11487
11899
|
filesCreated: result.filesCreated,
|
|
11488
11900
|
filesUpdated: result.filesUpdated,
|
|
11489
|
-
filesDeleted: result.filesDeleted,
|
|
11901
|
+
filesDeleted: result.filesDeleted + skillDirsDeleted,
|
|
11490
11902
|
notificationSent
|
|
11491
11903
|
};
|
|
11492
11904
|
} catch (err) {
|
|
@@ -11561,11 +11973,32 @@ async function installPackagesHandler(args2, deps) {
|
|
|
11561
11973
|
log(
|
|
11562
11974
|
`Fetching ${packageCount} ${packageWord}: ${allPackages.join(", ")}...`
|
|
11563
11975
|
);
|
|
11976
|
+
let gitRemoteUrl;
|
|
11977
|
+
let gitBranch;
|
|
11978
|
+
let relativePath;
|
|
11979
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
11980
|
+
if (gitRoot) {
|
|
11981
|
+
try {
|
|
11982
|
+
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
11983
|
+
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
11984
|
+
relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
11985
|
+
if (!relativePath.startsWith("/")) {
|
|
11986
|
+
relativePath = "/" + relativePath;
|
|
11987
|
+
}
|
|
11988
|
+
if (!relativePath.endsWith("/")) {
|
|
11989
|
+
relativePath = relativePath + "/";
|
|
11990
|
+
}
|
|
11991
|
+
} catch {
|
|
11992
|
+
}
|
|
11993
|
+
}
|
|
11564
11994
|
const result = await packmindCliHexa.installPackages({
|
|
11565
11995
|
baseDirectory: cwd,
|
|
11566
11996
|
packagesSlugs: allPackages,
|
|
11567
|
-
previousPackagesSlugs: configPackages
|
|
11997
|
+
previousPackagesSlugs: configPackages,
|
|
11568
11998
|
// Pass previous config for change detection
|
|
11999
|
+
gitRemoteUrl,
|
|
12000
|
+
gitBranch,
|
|
12001
|
+
relativePath
|
|
11569
12002
|
});
|
|
11570
12003
|
const parts = [];
|
|
11571
12004
|
if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
|
|
@@ -11573,9 +12006,11 @@ async function installPackagesHandler(args2, deps) {
|
|
|
11573
12006
|
parts.push(`${result.standardsCount} standards`);
|
|
11574
12007
|
if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
|
|
11575
12008
|
log(`Installing ${parts.join(", ") || "artifacts"}...`);
|
|
12009
|
+
const skillDirsDeleted = result.skillDirectoriesDeleted || 0;
|
|
12010
|
+
const totalDeleted = result.filesDeleted + skillDirsDeleted;
|
|
11576
12011
|
log(
|
|
11577
12012
|
`
|
|
11578
|
-
added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${
|
|
12013
|
+
added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${totalDeleted} files`
|
|
11579
12014
|
);
|
|
11580
12015
|
if (result.errors.length > 0) {
|
|
11581
12016
|
log("\n\u26A0\uFE0F Errors encountered:");
|
|
@@ -11586,12 +12021,12 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
|
|
|
11586
12021
|
return {
|
|
11587
12022
|
filesCreated: result.filesCreated,
|
|
11588
12023
|
filesUpdated: result.filesUpdated,
|
|
11589
|
-
filesDeleted:
|
|
12024
|
+
filesDeleted: totalDeleted,
|
|
11590
12025
|
notificationSent: false
|
|
11591
12026
|
};
|
|
11592
12027
|
}
|
|
11593
12028
|
let notificationSent = false;
|
|
11594
|
-
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0) {
|
|
12029
|
+
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
|
|
11595
12030
|
notificationSent = await notifyDistributionIfInGitRepo({
|
|
11596
12031
|
packmindCliHexa,
|
|
11597
12032
|
cwd,
|
|
@@ -11599,10 +12034,11 @@ added ${result.filesCreated} files, changed ${result.filesUpdated} files, remove
|
|
|
11599
12034
|
log
|
|
11600
12035
|
});
|
|
11601
12036
|
}
|
|
12037
|
+
await installDefaultSkillsIfAtGitRoot({ packmindCliHexa, cwd, log });
|
|
11602
12038
|
return {
|
|
11603
12039
|
filesCreated: result.filesCreated,
|
|
11604
12040
|
filesUpdated: result.filesUpdated,
|
|
11605
|
-
filesDeleted:
|
|
12041
|
+
filesDeleted: totalDeleted,
|
|
11606
12042
|
notificationSent
|
|
11607
12043
|
};
|
|
11608
12044
|
} catch (err) {
|
|
@@ -12050,10 +12486,11 @@ var loginCommand = (0, import_cmd_ts4.command)({
|
|
|
12050
12486
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
12051
12487
|
try {
|
|
12052
12488
|
if (!code) {
|
|
12053
|
-
|
|
12054
|
-
|
|
12489
|
+
logConsole("\nOpening browser for authentication...");
|
|
12490
|
+
const normalizedHost = removeTrailingSlash(host);
|
|
12491
|
+
logConsole(
|
|
12055
12492
|
`
|
|
12056
|
-
If the browser doesn't open, visit: ${
|
|
12493
|
+
If the browser doesn't open, visit: ${normalizedHost}/cli-login?callback_url=${encodeURIComponent("http://127.0.0.1:19284")}
|
|
12057
12494
|
`
|
|
12058
12495
|
);
|
|
12059
12496
|
logInfoConsole("Waiting for browser authentication...");
|
|
@@ -12061,9 +12498,9 @@ If the browser doesn't open, visit: ${host}/cli-login?callback_url=${encodeURICo
|
|
|
12061
12498
|
logInfoConsole("Exchanging code for API key...");
|
|
12062
12499
|
const result = await packmindCliHexa.login({ host, code });
|
|
12063
12500
|
logSuccessConsole("Login successful!");
|
|
12064
|
-
|
|
12501
|
+
logConsole(`
|
|
12065
12502
|
Credentials saved to: ${result.credentialsPath}`);
|
|
12066
|
-
|
|
12503
|
+
logConsole(
|
|
12067
12504
|
"\nYou can now use packmind-cli commands with your authenticated account."
|
|
12068
12505
|
);
|
|
12069
12506
|
} catch (error) {
|
|
@@ -12094,20 +12531,20 @@ var logoutCommand = (0, import_cmd_ts5.command)({
|
|
|
12094
12531
|
}
|
|
12095
12532
|
if (result.hadCredentialsFile) {
|
|
12096
12533
|
logSuccessConsole("Logged out successfully.");
|
|
12097
|
-
|
|
12534
|
+
logConsole(`Removed credentials from: ${result.credentialsPath}`);
|
|
12098
12535
|
}
|
|
12099
12536
|
if (result.hasEnvVar) {
|
|
12100
12537
|
if (!result.hadCredentialsFile) {
|
|
12101
12538
|
logInfoConsole("No stored credentials file found.");
|
|
12102
12539
|
}
|
|
12103
|
-
|
|
12540
|
+
logConsole(
|
|
12104
12541
|
"\nNote: PACKMIND_API_KEY_V3 environment variable is still set."
|
|
12105
12542
|
);
|
|
12106
|
-
|
|
12543
|
+
logConsole("To fully log out, run: unset PACKMIND_API_KEY_V3");
|
|
12107
12544
|
}
|
|
12108
12545
|
} catch (error) {
|
|
12109
12546
|
logErrorConsole("Failed to remove credentials file.");
|
|
12110
|
-
|
|
12547
|
+
logConsole(
|
|
12111
12548
|
`Error: ${error instanceof Error ? error.message : String(error)}`
|
|
12112
12549
|
);
|
|
12113
12550
|
process.exit(1);
|
|
@@ -12136,20 +12573,20 @@ function formatExpiresAt(expiresAt) {
|
|
|
12136
12573
|
return "Expires soon";
|
|
12137
12574
|
}
|
|
12138
12575
|
function displayAuthInfo(result) {
|
|
12139
|
-
|
|
12576
|
+
logConsole(`
|
|
12140
12577
|
Host: ${result.host}`);
|
|
12141
12578
|
if (result.organizationName) {
|
|
12142
|
-
|
|
12579
|
+
logConsole(`Organization: ${result.organizationName}`);
|
|
12143
12580
|
}
|
|
12144
12581
|
if (result.userName) {
|
|
12145
|
-
|
|
12582
|
+
logConsole(`User: ${result.userName}`);
|
|
12146
12583
|
}
|
|
12147
12584
|
if (result.expiresAt) {
|
|
12148
|
-
|
|
12585
|
+
logConsole(formatExpiresAt(result.expiresAt));
|
|
12149
12586
|
}
|
|
12150
12587
|
logInfoConsole(`Source: ${result.source}`);
|
|
12151
12588
|
if (result.isExpired) {
|
|
12152
|
-
|
|
12589
|
+
logConsole("\nRun `packmind-cli login` to re-authenticate.");
|
|
12153
12590
|
}
|
|
12154
12591
|
}
|
|
12155
12592
|
var whoamiCommand = (0, import_cmd_ts6.command)({
|
|
@@ -12162,14 +12599,14 @@ var whoamiCommand = (0, import_cmd_ts6.command)({
|
|
|
12162
12599
|
const result = await packmindCliHexa.whoami({});
|
|
12163
12600
|
if (!result.isAuthenticated) {
|
|
12164
12601
|
logErrorConsole("Not authenticated");
|
|
12165
|
-
|
|
12602
|
+
logConsole(
|
|
12166
12603
|
`
|
|
12167
12604
|
No credentials found. Run \`packmind-cli login\` to authenticate.`
|
|
12168
12605
|
);
|
|
12169
|
-
|
|
12606
|
+
logConsole(`
|
|
12170
12607
|
Credentials are loaded from (in order of priority):`);
|
|
12171
|
-
|
|
12172
|
-
|
|
12608
|
+
logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
|
|
12609
|
+
logConsole(` 2. ${result.credentialsPath}`);
|
|
12173
12610
|
process.exit(1);
|
|
12174
12611
|
}
|
|
12175
12612
|
if (result.isExpired) {
|
|
@@ -12186,13 +12623,13 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12186
12623
|
|
|
12187
12624
|
// apps/cli/src/infra/commands/SetupMcpCommand.ts
|
|
12188
12625
|
var import_cmd_ts7 = __toESM(require_cjs());
|
|
12189
|
-
var
|
|
12626
|
+
var fs12 = __toESM(require("fs"));
|
|
12190
12627
|
var readline2 = __toESM(require("readline"));
|
|
12191
12628
|
var inquirer = __toESM(require("inquirer"));
|
|
12192
12629
|
|
|
12193
12630
|
// apps/cli/src/application/services/AgentDetectionService.ts
|
|
12194
|
-
var
|
|
12195
|
-
var
|
|
12631
|
+
var fs11 = __toESM(require("fs"));
|
|
12632
|
+
var path11 = __toESM(require("path"));
|
|
12196
12633
|
var os4 = __toESM(require("os"));
|
|
12197
12634
|
var import_child_process3 = require("child_process");
|
|
12198
12635
|
var AgentDetectionService = class {
|
|
@@ -12219,21 +12656,21 @@ var AgentDetectionService = class {
|
|
|
12219
12656
|
return this.isCommandAvailable("claude");
|
|
12220
12657
|
}
|
|
12221
12658
|
isCursorAvailable() {
|
|
12222
|
-
const cursorConfigDir =
|
|
12223
|
-
return
|
|
12659
|
+
const cursorConfigDir = path11.join(os4.homedir(), ".cursor");
|
|
12660
|
+
return fs11.existsSync(cursorConfigDir);
|
|
12224
12661
|
}
|
|
12225
12662
|
isVSCodeAvailable() {
|
|
12226
|
-
const vscodeDir =
|
|
12227
|
-
return
|
|
12663
|
+
const vscodeDir = path11.join(this.projectDir, ".vscode");
|
|
12664
|
+
return fs11.existsSync(vscodeDir);
|
|
12228
12665
|
}
|
|
12229
12666
|
isContinueAvailable() {
|
|
12230
|
-
const continueDir =
|
|
12231
|
-
return
|
|
12667
|
+
const continueDir = path11.join(this.projectDir, ".continue");
|
|
12668
|
+
return fs11.existsSync(continueDir);
|
|
12232
12669
|
}
|
|
12233
|
-
isCommandAvailable(
|
|
12670
|
+
isCommandAvailable(command12) {
|
|
12234
12671
|
try {
|
|
12235
12672
|
const whichCommand = process.platform === "win32" ? "where" : "which";
|
|
12236
|
-
(0, import_child_process3.execSync)(`${whichCommand} ${
|
|
12673
|
+
(0, import_child_process3.execSync)(`${whichCommand} ${command12}`, { stdio: "pipe" });
|
|
12237
12674
|
return true;
|
|
12238
12675
|
} catch {
|
|
12239
12676
|
return false;
|
|
@@ -12267,8 +12704,8 @@ var ALL_AGENTS2 = [
|
|
|
12267
12704
|
{ type: "continue", name: "Continue.dev" }
|
|
12268
12705
|
];
|
|
12269
12706
|
async function promptAgentsWithReadline(choices) {
|
|
12270
|
-
const input =
|
|
12271
|
-
const output =
|
|
12707
|
+
const input = fs12.createReadStream("/dev/tty");
|
|
12708
|
+
const output = fs12.createWriteStream("/dev/tty");
|
|
12272
12709
|
const rl = readline2.createInterface({
|
|
12273
12710
|
input,
|
|
12274
12711
|
output
|
|
@@ -12313,18 +12750,18 @@ var setupMcpCommand = (0, import_cmd_ts7.command)({
|
|
|
12313
12750
|
const credentials = loadCredentials();
|
|
12314
12751
|
if (!credentials) {
|
|
12315
12752
|
logErrorConsole("Not authenticated");
|
|
12316
|
-
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12753
|
+
logConsole("\nNo credentials found. You can authenticate by either:");
|
|
12754
|
+
logConsole(" 1. Running `packmind-cli login`");
|
|
12755
|
+
logConsole(" 2. Setting PACKMIND_API_KEY_V3 environment variable");
|
|
12756
|
+
logConsole(`
|
|
12320
12757
|
Credentials are loaded from (in order of priority):`);
|
|
12321
|
-
|
|
12322
|
-
|
|
12758
|
+
logConsole(` 1. PACKMIND_API_KEY_V3 environment variable`);
|
|
12759
|
+
logConsole(` 2. ${getCredentialsPath()}`);
|
|
12323
12760
|
process.exit(1);
|
|
12324
12761
|
}
|
|
12325
12762
|
if (credentials.isExpired) {
|
|
12326
12763
|
logErrorConsole("Credentials expired");
|
|
12327
|
-
|
|
12764
|
+
logConsole("\nRun `packmind-cli login` to re-authenticate.");
|
|
12328
12765
|
process.exit(1);
|
|
12329
12766
|
}
|
|
12330
12767
|
const agentDetectionService = new AgentDetectionService();
|
|
@@ -12332,16 +12769,16 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12332
12769
|
if (targets.length > 0) {
|
|
12333
12770
|
selectedAgents = targets.map((t) => agentArgToType[t]);
|
|
12334
12771
|
} else {
|
|
12335
|
-
|
|
12772
|
+
logConsole("\nDetecting installed AI agents...\n");
|
|
12336
12773
|
const detectedAgents = agentDetectionService.detectAgents();
|
|
12337
12774
|
if (detectedAgents.length > 0) {
|
|
12338
|
-
|
|
12775
|
+
logConsole("Found agents:");
|
|
12339
12776
|
detectedAgents.forEach((detectedAgent) => {
|
|
12340
|
-
|
|
12777
|
+
logConsole(` - ${detectedAgent.name}`);
|
|
12341
12778
|
});
|
|
12342
|
-
|
|
12779
|
+
logConsole("");
|
|
12343
12780
|
} else {
|
|
12344
|
-
|
|
12781
|
+
logConsole("No supported agents detected.\n");
|
|
12345
12782
|
}
|
|
12346
12783
|
const detectedTypes = new Set(detectedAgents.map((a) => a.type));
|
|
12347
12784
|
const choices = ALL_AGENTS2.map((agentInfo) => ({
|
|
@@ -12365,12 +12802,12 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12365
12802
|
promptedAgents = result2.selectedAgents;
|
|
12366
12803
|
}
|
|
12367
12804
|
if (promptedAgents.length === 0) {
|
|
12368
|
-
|
|
12805
|
+
logConsole("\nNo agents selected. Exiting.");
|
|
12369
12806
|
process.exit(0);
|
|
12370
12807
|
}
|
|
12371
12808
|
selectedAgents = promptedAgents;
|
|
12372
12809
|
}
|
|
12373
|
-
|
|
12810
|
+
logConsole("\nFetching MCP configuration...\n");
|
|
12374
12811
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
12375
12812
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
12376
12813
|
let result;
|
|
@@ -12379,14 +12816,14 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12379
12816
|
} catch (error) {
|
|
12380
12817
|
logErrorConsole("Failed to fetch MCP configuration from server.");
|
|
12381
12818
|
if (error instanceof Error) {
|
|
12382
|
-
|
|
12819
|
+
logConsole(` ${error.message}`);
|
|
12383
12820
|
}
|
|
12384
12821
|
process.exit(1);
|
|
12385
12822
|
}
|
|
12386
12823
|
let successCount = 0;
|
|
12387
12824
|
const failedAgents = [];
|
|
12388
12825
|
for (const agentResult of result.results) {
|
|
12389
|
-
|
|
12826
|
+
logConsole(`Installing MCP for ${agentResult.agentName}...`);
|
|
12390
12827
|
if (agentResult.success) {
|
|
12391
12828
|
logSuccessConsole(` ${agentResult.agentName} configured successfully`);
|
|
12392
12829
|
successCount++;
|
|
@@ -12398,27 +12835,27 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12398
12835
|
});
|
|
12399
12836
|
}
|
|
12400
12837
|
}
|
|
12401
|
-
|
|
12838
|
+
logConsole("");
|
|
12402
12839
|
if (failedAgents.length > 0) {
|
|
12403
12840
|
for (const failed of failedAgents) {
|
|
12404
12841
|
logWarningConsole(`Failed to configure ${failed.name}:`);
|
|
12405
|
-
|
|
12842
|
+
logConsole(`
|
|
12406
12843
|
Error: ${failed.error}`);
|
|
12407
12844
|
if (failed.error.includes("ENOENT") || failed.error.includes("not found") || failed.error.includes("command not found")) {
|
|
12408
|
-
|
|
12845
|
+
logConsole(
|
|
12409
12846
|
`
|
|
12410
12847
|
Hint: Make sure the agent CLI is installed and available in your PATH.`
|
|
12411
12848
|
);
|
|
12412
12849
|
}
|
|
12413
|
-
|
|
12850
|
+
logConsole(`
|
|
12414
12851
|
Manual configuration:`);
|
|
12415
|
-
|
|
12416
|
-
|
|
12852
|
+
logConsole(result.manualConfigJson ?? "undefined");
|
|
12853
|
+
logConsole("");
|
|
12417
12854
|
}
|
|
12418
12855
|
}
|
|
12419
12856
|
if (successCount > 0) {
|
|
12420
12857
|
const agentWord = successCount === 1 ? "agent" : "agents";
|
|
12421
|
-
|
|
12858
|
+
logConsole(
|
|
12422
12859
|
formatBold(`Done! MCP configured for ${successCount} ${agentWord}.`)
|
|
12423
12860
|
);
|
|
12424
12861
|
}
|
|
@@ -12429,7 +12866,7 @@ Credentials are loaded from (in order of priority):`);
|
|
|
12429
12866
|
});
|
|
12430
12867
|
|
|
12431
12868
|
// apps/cli/src/infra/commands/SkillsCommand.ts
|
|
12432
|
-
var
|
|
12869
|
+
var import_cmd_ts10 = __toESM(require_cjs());
|
|
12433
12870
|
|
|
12434
12871
|
// apps/cli/src/infra/commands/skills/AddSkillCommand.ts
|
|
12435
12872
|
var import_cmd_ts8 = __toESM(require_cjs());
|
|
@@ -12479,12 +12916,425 @@ var addSkillCommand = (0, import_cmd_ts8.command)({
|
|
|
12479
12916
|
}
|
|
12480
12917
|
});
|
|
12481
12918
|
|
|
12919
|
+
// apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
|
|
12920
|
+
var import_cmd_ts9 = __toESM(require_cjs());
|
|
12921
|
+
var installDefaultSkillsCommand = (0, import_cmd_ts9.command)({
|
|
12922
|
+
name: "install-default",
|
|
12923
|
+
description: "Install default Packmind skills for configured coding agents",
|
|
12924
|
+
args: {},
|
|
12925
|
+
handler: async () => {
|
|
12926
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
12927
|
+
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
12928
|
+
try {
|
|
12929
|
+
logInfoConsole("Installing default skills...");
|
|
12930
|
+
const result = await packmindCliHexa.installDefaultSkills({});
|
|
12931
|
+
if (result.errors.length > 0) {
|
|
12932
|
+
for (const error of result.errors) {
|
|
12933
|
+
logErrorConsole(`Error: ${error}`);
|
|
12934
|
+
}
|
|
12935
|
+
process.exit(1);
|
|
12936
|
+
}
|
|
12937
|
+
const totalFiles = result.filesCreated + result.filesUpdated;
|
|
12938
|
+
if (totalFiles === 0) {
|
|
12939
|
+
logInfoConsole("Default skills are already up to date.");
|
|
12940
|
+
} else {
|
|
12941
|
+
logSuccessConsole("Default skills installed successfully!");
|
|
12942
|
+
if (result.filesCreated > 0) {
|
|
12943
|
+
logInfoConsole(` Files created: ${result.filesCreated}`);
|
|
12944
|
+
}
|
|
12945
|
+
if (result.filesUpdated > 0) {
|
|
12946
|
+
logInfoConsole(` Files updated: ${result.filesUpdated}`);
|
|
12947
|
+
}
|
|
12948
|
+
}
|
|
12949
|
+
} catch (error) {
|
|
12950
|
+
if (error instanceof Error) {
|
|
12951
|
+
logErrorConsole(`Installation failed: ${error.message}`);
|
|
12952
|
+
} else {
|
|
12953
|
+
logErrorConsole(`Installation failed: ${String(error)}`);
|
|
12954
|
+
}
|
|
12955
|
+
process.exit(1);
|
|
12956
|
+
}
|
|
12957
|
+
}
|
|
12958
|
+
});
|
|
12959
|
+
|
|
12482
12960
|
// apps/cli/src/infra/commands/SkillsCommand.ts
|
|
12483
|
-
var skillsCommand = (0,
|
|
12961
|
+
var skillsCommand = (0, import_cmd_ts10.subcommands)({
|
|
12484
12962
|
name: "skills",
|
|
12485
12963
|
description: "Manage skills in your Packmind organization",
|
|
12486
12964
|
cmds: {
|
|
12487
|
-
add: addSkillCommand
|
|
12965
|
+
add: addSkillCommand,
|
|
12966
|
+
init: installDefaultSkillsCommand
|
|
12967
|
+
}
|
|
12968
|
+
});
|
|
12969
|
+
|
|
12970
|
+
// apps/cli/src/infra/commands/StandardsCommand.ts
|
|
12971
|
+
var import_cmd_ts12 = __toESM(require_cjs());
|
|
12972
|
+
|
|
12973
|
+
// apps/cli/src/infra/commands/CreateStandardCommand.ts
|
|
12974
|
+
var import_cmd_ts11 = __toESM(require_cjs());
|
|
12975
|
+
|
|
12976
|
+
// apps/cli/src/infra/utils/readPlaybookFile.ts
|
|
12977
|
+
var fs13 = __toESM(require("fs/promises"));
|
|
12978
|
+
|
|
12979
|
+
// apps/cli/src/domain/entities/PlaybookDTO.ts
|
|
12980
|
+
var import_zod = require("zod");
|
|
12981
|
+
var playbookRuleExampleSchema = import_zod.z.object({
|
|
12982
|
+
positive: import_zod.z.string().describe("Valid example of the rule"),
|
|
12983
|
+
negative: import_zod.z.string().describe("Invalid example of the rule"),
|
|
12984
|
+
language: import_zod.z.string().describe("Programming language")
|
|
12985
|
+
});
|
|
12986
|
+
var playbookRuleSchema = import_zod.z.object({
|
|
12987
|
+
content: import_zod.z.string().min(1).describe("Rule description starting with action verb"),
|
|
12988
|
+
examples: playbookRuleExampleSchema.optional()
|
|
12989
|
+
});
|
|
12990
|
+
var playbookDTOSchema = import_zod.z.object({
|
|
12991
|
+
name: import_zod.z.string().min(1).describe("Standard name"),
|
|
12992
|
+
description: import_zod.z.string().min(1).describe("Standard description"),
|
|
12993
|
+
scope: import_zod.z.string().min(1).describe("Standard scope/context"),
|
|
12994
|
+
rules: import_zod.z.array(playbookRuleSchema).min(1).describe("Array of rules (minimum 1)")
|
|
12995
|
+
});
|
|
12996
|
+
|
|
12997
|
+
// apps/cli/src/infra/utils/playbookValidator.ts
|
|
12998
|
+
function validatePlaybook(data) {
|
|
12999
|
+
const result = playbookDTOSchema.safeParse(data);
|
|
13000
|
+
if (!result.success) {
|
|
13001
|
+
const errorList = result.error.issues;
|
|
13002
|
+
return {
|
|
13003
|
+
isValid: false,
|
|
13004
|
+
errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
13005
|
+
};
|
|
13006
|
+
}
|
|
13007
|
+
return {
|
|
13008
|
+
isValid: true,
|
|
13009
|
+
data: result.data
|
|
13010
|
+
};
|
|
13011
|
+
}
|
|
13012
|
+
|
|
13013
|
+
// apps/cli/src/infra/utils/readPlaybookFile.ts
|
|
13014
|
+
async function readPlaybookFile(filePath) {
|
|
13015
|
+
try {
|
|
13016
|
+
const content = await fs13.readFile(filePath, "utf-8");
|
|
13017
|
+
let parsed;
|
|
13018
|
+
try {
|
|
13019
|
+
parsed = JSON.parse(content);
|
|
13020
|
+
} catch (e) {
|
|
13021
|
+
return {
|
|
13022
|
+
isValid: false,
|
|
13023
|
+
errors: [
|
|
13024
|
+
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13025
|
+
]
|
|
13026
|
+
};
|
|
13027
|
+
}
|
|
13028
|
+
return validatePlaybook(parsed);
|
|
13029
|
+
} catch (e) {
|
|
13030
|
+
return {
|
|
13031
|
+
isValid: false,
|
|
13032
|
+
errors: [
|
|
13033
|
+
`Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13034
|
+
]
|
|
13035
|
+
};
|
|
13036
|
+
}
|
|
13037
|
+
}
|
|
13038
|
+
|
|
13039
|
+
// apps/cli/src/infra/commands/createStandardHandler.ts
|
|
13040
|
+
async function createStandardHandler(filePath, useCase) {
|
|
13041
|
+
const readResult = await readPlaybookFile(filePath);
|
|
13042
|
+
if (!readResult.isValid) {
|
|
13043
|
+
return {
|
|
13044
|
+
success: false,
|
|
13045
|
+
error: `Validation failed: ${readResult.errors?.join(", ")}`
|
|
13046
|
+
};
|
|
13047
|
+
}
|
|
13048
|
+
if (!readResult.data) {
|
|
13049
|
+
return {
|
|
13050
|
+
success: false,
|
|
13051
|
+
error: "Failed to read playbook data"
|
|
13052
|
+
};
|
|
13053
|
+
}
|
|
13054
|
+
try {
|
|
13055
|
+
const result = await useCase.execute(readResult.data);
|
|
13056
|
+
return {
|
|
13057
|
+
success: true,
|
|
13058
|
+
standardId: result.standardId,
|
|
13059
|
+
standardName: result.name
|
|
13060
|
+
};
|
|
13061
|
+
} catch (e) {
|
|
13062
|
+
return {
|
|
13063
|
+
success: false,
|
|
13064
|
+
error: `Error creating standard: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13065
|
+
};
|
|
13066
|
+
}
|
|
13067
|
+
}
|
|
13068
|
+
|
|
13069
|
+
// apps/cli/src/application/useCases/CreateStandardFromPlaybookUseCase.ts
|
|
13070
|
+
var CreateStandardFromPlaybookUseCase = class {
|
|
13071
|
+
constructor(gateway) {
|
|
13072
|
+
this.gateway = gateway;
|
|
13073
|
+
}
|
|
13074
|
+
async execute(playbook) {
|
|
13075
|
+
const space = await this.gateway.getGlobalSpace();
|
|
13076
|
+
const standard = await this.gateway.createStandardInSpace(space.id, {
|
|
13077
|
+
name: playbook.name,
|
|
13078
|
+
description: playbook.description,
|
|
13079
|
+
scope: playbook.scope,
|
|
13080
|
+
rules: playbook.rules
|
|
13081
|
+
});
|
|
13082
|
+
const rulesWithExamples = playbook.rules.filter((r) => r.examples);
|
|
13083
|
+
if (rulesWithExamples.length > 0) {
|
|
13084
|
+
const createdRules = await this.gateway.getRulesForStandard(
|
|
13085
|
+
space.id,
|
|
13086
|
+
standard.id
|
|
13087
|
+
);
|
|
13088
|
+
for (let i = 0; i < playbook.rules.length; i++) {
|
|
13089
|
+
const rule = playbook.rules[i];
|
|
13090
|
+
if (rule.examples && createdRules[i]) {
|
|
13091
|
+
try {
|
|
13092
|
+
await this.gateway.addExampleToRule(
|
|
13093
|
+
space.id,
|
|
13094
|
+
standard.id,
|
|
13095
|
+
createdRules[i].id,
|
|
13096
|
+
rule.examples
|
|
13097
|
+
);
|
|
13098
|
+
} catch {
|
|
13099
|
+
}
|
|
13100
|
+
}
|
|
13101
|
+
}
|
|
13102
|
+
}
|
|
13103
|
+
return { standardId: standard.id, name: standard.name };
|
|
13104
|
+
}
|
|
13105
|
+
};
|
|
13106
|
+
|
|
13107
|
+
// apps/cli/src/infra/commands/CreateStandardCommand.ts
|
|
13108
|
+
var createStandardCommand = (0, import_cmd_ts11.command)({
|
|
13109
|
+
name: "create",
|
|
13110
|
+
description: "Create a coding standard from a playbook JSON file",
|
|
13111
|
+
args: {
|
|
13112
|
+
file: (0, import_cmd_ts11.positional)({
|
|
13113
|
+
displayName: "file",
|
|
13114
|
+
description: "Path to the playbook JSON file",
|
|
13115
|
+
type: import_cmd_ts11.string
|
|
13116
|
+
})
|
|
13117
|
+
},
|
|
13118
|
+
handler: async ({ file }) => {
|
|
13119
|
+
try {
|
|
13120
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
13121
|
+
const hexa = new PackmindCliHexa(packmindLogger);
|
|
13122
|
+
const gateway = hexa.getPackmindGateway();
|
|
13123
|
+
const useCase = new CreateStandardFromPlaybookUseCase(gateway);
|
|
13124
|
+
const result = await createStandardHandler(file, useCase);
|
|
13125
|
+
if (result.success) {
|
|
13126
|
+
logSuccessConsole(
|
|
13127
|
+
`Standard "${result.standardName}" created successfully (ID: ${result.standardId})`
|
|
13128
|
+
);
|
|
13129
|
+
process.exit(0);
|
|
13130
|
+
} else {
|
|
13131
|
+
logErrorConsole(`Failed to create standard: ${result.error}`);
|
|
13132
|
+
process.exit(1);
|
|
13133
|
+
}
|
|
13134
|
+
} catch (e) {
|
|
13135
|
+
logErrorConsole(
|
|
13136
|
+
`Error: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13137
|
+
);
|
|
13138
|
+
process.exit(1);
|
|
13139
|
+
}
|
|
13140
|
+
}
|
|
13141
|
+
});
|
|
13142
|
+
|
|
13143
|
+
// apps/cli/src/infra/commands/StandardsCommand.ts
|
|
13144
|
+
var standardsCommand = (0, import_cmd_ts12.subcommands)({
|
|
13145
|
+
name: "standards",
|
|
13146
|
+
description: "Manage coding standards",
|
|
13147
|
+
cmds: {
|
|
13148
|
+
create: createStandardCommand
|
|
13149
|
+
}
|
|
13150
|
+
});
|
|
13151
|
+
|
|
13152
|
+
// apps/cli/src/infra/commands/CommandsCommand.ts
|
|
13153
|
+
var import_cmd_ts14 = __toESM(require_cjs());
|
|
13154
|
+
|
|
13155
|
+
// apps/cli/src/infra/commands/CreateCommandCommand.ts
|
|
13156
|
+
var import_cmd_ts13 = __toESM(require_cjs());
|
|
13157
|
+
|
|
13158
|
+
// apps/cli/src/infra/utils/readCommandPlaybookFile.ts
|
|
13159
|
+
var fs14 = __toESM(require("fs/promises"));
|
|
13160
|
+
|
|
13161
|
+
// apps/cli/src/domain/entities/CommandPlaybookDTO.ts
|
|
13162
|
+
var import_zod2 = require("zod");
|
|
13163
|
+
var commandStepSchema = import_zod2.z.object({
|
|
13164
|
+
name: import_zod2.z.string().min(1).describe("Step name/title"),
|
|
13165
|
+
description: import_zod2.z.string().min(1).describe("Step description with implementation details"),
|
|
13166
|
+
codeSnippet: import_zod2.z.string().optional().describe("Optional code snippet demonstrating the step")
|
|
13167
|
+
});
|
|
13168
|
+
var commandPlaybookDTOSchema = import_zod2.z.object({
|
|
13169
|
+
name: import_zod2.z.string().min(1).describe("Command name"),
|
|
13170
|
+
summary: import_zod2.z.string().min(1).describe("Command summary describing intent and value"),
|
|
13171
|
+
whenToUse: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe("Array of scenarios when this command is applicable (minimum 1)"),
|
|
13172
|
+
contextValidationCheckpoints: import_zod2.z.array(import_zod2.z.string().min(1)).min(1).describe(
|
|
13173
|
+
"Array of checkpoints to validate context before implementation (minimum 1)"
|
|
13174
|
+
),
|
|
13175
|
+
steps: import_zod2.z.array(commandStepSchema).min(1).describe("Array of implementation steps (minimum 1)")
|
|
13176
|
+
});
|
|
13177
|
+
|
|
13178
|
+
// apps/cli/src/infra/utils/commandPlaybookValidator.ts
|
|
13179
|
+
function validateCommandPlaybook(data) {
|
|
13180
|
+
const result = commandPlaybookDTOSchema.safeParse(data);
|
|
13181
|
+
if (!result.success) {
|
|
13182
|
+
const errorList = result.error.issues;
|
|
13183
|
+
return {
|
|
13184
|
+
isValid: false,
|
|
13185
|
+
errors: errorList.map((e) => `${e.path.join(".")}: ${e.message}`)
|
|
13186
|
+
};
|
|
13187
|
+
}
|
|
13188
|
+
return {
|
|
13189
|
+
isValid: true,
|
|
13190
|
+
data: result.data
|
|
13191
|
+
};
|
|
13192
|
+
}
|
|
13193
|
+
|
|
13194
|
+
// apps/cli/src/infra/utils/readCommandPlaybookFile.ts
|
|
13195
|
+
async function readCommandPlaybookFile(filePath) {
|
|
13196
|
+
try {
|
|
13197
|
+
const content = await fs14.readFile(filePath, "utf-8");
|
|
13198
|
+
let parsed;
|
|
13199
|
+
try {
|
|
13200
|
+
parsed = JSON.parse(content);
|
|
13201
|
+
} catch (e) {
|
|
13202
|
+
return {
|
|
13203
|
+
isValid: false,
|
|
13204
|
+
errors: [
|
|
13205
|
+
`Invalid JSON: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13206
|
+
]
|
|
13207
|
+
};
|
|
13208
|
+
}
|
|
13209
|
+
return validateCommandPlaybook(parsed);
|
|
13210
|
+
} catch (e) {
|
|
13211
|
+
return {
|
|
13212
|
+
isValid: false,
|
|
13213
|
+
errors: [
|
|
13214
|
+
`Failed to read file: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13215
|
+
]
|
|
13216
|
+
};
|
|
13217
|
+
}
|
|
13218
|
+
}
|
|
13219
|
+
|
|
13220
|
+
// apps/cli/src/infra/commands/createCommandHandler.ts
|
|
13221
|
+
function buildWebappUrl(host, orgSlug, commandId) {
|
|
13222
|
+
return `${host}/org/${orgSlug}/space/global/commands/${commandId}`;
|
|
13223
|
+
}
|
|
13224
|
+
async function createCommandHandler(filePath, useCase) {
|
|
13225
|
+
const readResult = await readCommandPlaybookFile(filePath);
|
|
13226
|
+
if (!readResult.isValid) {
|
|
13227
|
+
return {
|
|
13228
|
+
success: false,
|
|
13229
|
+
error: `Validation failed: ${readResult.errors?.join(", ")}`
|
|
13230
|
+
};
|
|
13231
|
+
}
|
|
13232
|
+
if (!readResult.data) {
|
|
13233
|
+
return {
|
|
13234
|
+
success: false,
|
|
13235
|
+
error: "Failed to read command playbook data"
|
|
13236
|
+
};
|
|
13237
|
+
}
|
|
13238
|
+
try {
|
|
13239
|
+
const result = await useCase.execute(readResult.data);
|
|
13240
|
+
let webappUrl;
|
|
13241
|
+
const apiKey = loadApiKey();
|
|
13242
|
+
if (apiKey) {
|
|
13243
|
+
const decoded = decodeApiKey2(apiKey);
|
|
13244
|
+
if (decoded?.host && decoded?.jwt?.organization?.slug) {
|
|
13245
|
+
webappUrl = buildWebappUrl(
|
|
13246
|
+
decoded.host,
|
|
13247
|
+
decoded.jwt.organization.slug,
|
|
13248
|
+
result.commandId
|
|
13249
|
+
);
|
|
13250
|
+
}
|
|
13251
|
+
}
|
|
13252
|
+
return {
|
|
13253
|
+
success: true,
|
|
13254
|
+
commandId: result.commandId,
|
|
13255
|
+
commandName: result.name,
|
|
13256
|
+
webappUrl
|
|
13257
|
+
};
|
|
13258
|
+
} catch (e) {
|
|
13259
|
+
return {
|
|
13260
|
+
success: false,
|
|
13261
|
+
error: `Error creating command: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13262
|
+
};
|
|
13263
|
+
}
|
|
13264
|
+
}
|
|
13265
|
+
|
|
13266
|
+
// apps/cli/src/application/useCases/CreateCommandFromPlaybookUseCase.ts
|
|
13267
|
+
var CreateCommandFromPlaybookUseCase = class {
|
|
13268
|
+
constructor(gateway) {
|
|
13269
|
+
this.gateway = gateway;
|
|
13270
|
+
}
|
|
13271
|
+
async execute(playbook) {
|
|
13272
|
+
const space = await this.gateway.getGlobalSpace();
|
|
13273
|
+
const command12 = await this.gateway.createCommand(space.id, {
|
|
13274
|
+
name: playbook.name,
|
|
13275
|
+
summary: playbook.summary,
|
|
13276
|
+
whenToUse: playbook.whenToUse,
|
|
13277
|
+
contextValidationCheckpoints: playbook.contextValidationCheckpoints,
|
|
13278
|
+
steps: playbook.steps.map((step) => ({
|
|
13279
|
+
name: step.name,
|
|
13280
|
+
description: step.description,
|
|
13281
|
+
codeSnippet: step.codeSnippet
|
|
13282
|
+
}))
|
|
13283
|
+
});
|
|
13284
|
+
return {
|
|
13285
|
+
commandId: command12.id,
|
|
13286
|
+
name: command12.name,
|
|
13287
|
+
slug: command12.slug
|
|
13288
|
+
};
|
|
13289
|
+
}
|
|
13290
|
+
};
|
|
13291
|
+
|
|
13292
|
+
// apps/cli/src/infra/commands/CreateCommandCommand.ts
|
|
13293
|
+
var createCommandCommand = (0, import_cmd_ts13.command)({
|
|
13294
|
+
name: "create",
|
|
13295
|
+
description: "Create a command from a playbook JSON file",
|
|
13296
|
+
args: {
|
|
13297
|
+
file: (0, import_cmd_ts13.positional)({
|
|
13298
|
+
displayName: "file",
|
|
13299
|
+
description: "Path to the command playbook JSON file",
|
|
13300
|
+
type: import_cmd_ts13.string
|
|
13301
|
+
})
|
|
13302
|
+
},
|
|
13303
|
+
handler: async ({ file }) => {
|
|
13304
|
+
try {
|
|
13305
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
13306
|
+
const hexa = new PackmindCliHexa(packmindLogger);
|
|
13307
|
+
const gateway = hexa.getPackmindGateway();
|
|
13308
|
+
const useCase = new CreateCommandFromPlaybookUseCase(gateway);
|
|
13309
|
+
const result = await createCommandHandler(file, useCase);
|
|
13310
|
+
if (result.success) {
|
|
13311
|
+
logSuccessConsole(
|
|
13312
|
+
`Command "${result.commandName}" created successfully (ID: ${result.commandId})`
|
|
13313
|
+
);
|
|
13314
|
+
if (result.webappUrl) {
|
|
13315
|
+
logConsole("");
|
|
13316
|
+
logConsole(`View it in the webapp: ${result.webappUrl}`);
|
|
13317
|
+
}
|
|
13318
|
+
process.exit(0);
|
|
13319
|
+
} else {
|
|
13320
|
+
logErrorConsole(`Failed to create command: ${result.error}`);
|
|
13321
|
+
process.exit(1);
|
|
13322
|
+
}
|
|
13323
|
+
} catch (e) {
|
|
13324
|
+
logErrorConsole(
|
|
13325
|
+
`Error: ${e instanceof Error ? e.message : "Unknown error"}`
|
|
13326
|
+
);
|
|
13327
|
+
process.exit(1);
|
|
13328
|
+
}
|
|
13329
|
+
}
|
|
13330
|
+
});
|
|
13331
|
+
|
|
13332
|
+
// apps/cli/src/infra/commands/CommandsCommand.ts
|
|
13333
|
+
var commandsCommand = (0, import_cmd_ts14.subcommands)({
|
|
13334
|
+
name: "commands",
|
|
13335
|
+
description: "Manage commands",
|
|
13336
|
+
cmds: {
|
|
13337
|
+
create: createCommandCommand
|
|
12488
13338
|
}
|
|
12489
13339
|
});
|
|
12490
13340
|
|
|
@@ -12494,20 +13344,20 @@ function findEnvFile() {
|
|
|
12494
13344
|
const currentDir = process.cwd();
|
|
12495
13345
|
const gitService = new GitService();
|
|
12496
13346
|
const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
|
|
12497
|
-
const filesystemRoot =
|
|
13347
|
+
const filesystemRoot = path12.parse(currentDir).root;
|
|
12498
13348
|
const stopDir = gitRoot ?? filesystemRoot;
|
|
12499
13349
|
let searchDir = currentDir;
|
|
12500
|
-
let parentDir =
|
|
13350
|
+
let parentDir = path12.dirname(searchDir);
|
|
12501
13351
|
while (searchDir !== parentDir) {
|
|
12502
|
-
const envPath2 =
|
|
12503
|
-
if (
|
|
13352
|
+
const envPath2 = path12.join(searchDir, ".env");
|
|
13353
|
+
if (fs15.existsSync(envPath2)) {
|
|
12504
13354
|
return envPath2;
|
|
12505
13355
|
}
|
|
12506
13356
|
if (searchDir === stopDir) {
|
|
12507
13357
|
return null;
|
|
12508
13358
|
}
|
|
12509
13359
|
searchDir = parentDir;
|
|
12510
|
-
parentDir =
|
|
13360
|
+
parentDir = path12.dirname(searchDir);
|
|
12511
13361
|
}
|
|
12512
13362
|
return null;
|
|
12513
13363
|
}
|
|
@@ -12524,10 +13374,10 @@ if (hasEmbeddedWasmFiles()) {
|
|
|
12524
13374
|
}
|
|
12525
13375
|
var args = process.argv.slice(2);
|
|
12526
13376
|
if (args.includes("--version") || args.includes("-v")) {
|
|
12527
|
-
|
|
13377
|
+
logConsole(`packmind-cli version ${CLI_VERSION}`);
|
|
12528
13378
|
process.exit(0);
|
|
12529
13379
|
}
|
|
12530
|
-
var app = (0,
|
|
13380
|
+
var app = (0, import_cmd_ts15.subcommands)({
|
|
12531
13381
|
name: "packmind-cli",
|
|
12532
13382
|
description: "Packmind CLI tool",
|
|
12533
13383
|
cmds: {
|
|
@@ -12540,10 +13390,12 @@ var app = (0, import_cmd_ts10.subcommands)({
|
|
|
12540
13390
|
logout: logoutCommand,
|
|
12541
13391
|
whoami: whoamiCommand,
|
|
12542
13392
|
"setup-mcp": setupMcpCommand,
|
|
12543
|
-
skills: skillsCommand
|
|
13393
|
+
skills: skillsCommand,
|
|
13394
|
+
standards: standardsCommand,
|
|
13395
|
+
commands: commandsCommand
|
|
12544
13396
|
}
|
|
12545
13397
|
});
|
|
12546
|
-
(0,
|
|
13398
|
+
(0, import_cmd_ts15.run)(app, args).catch((error) => {
|
|
12547
13399
|
logErrorConsole(error.message);
|
|
12548
13400
|
process.exit(1);
|
|
12549
13401
|
});
|