@packmind/cli 0.20.0 → 0.21.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 +344 -43
- package/package.json +3 -3
package/main.cjs
CHANGED
|
@@ -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.21.1",
|
|
3856
3856
|
description: "A command-line interface for Packmind linting and code quality checks",
|
|
3857
3857
|
private: false,
|
|
3858
3858
|
bin: {
|
|
@@ -3887,6 +3887,7 @@ var require_package = __commonJS({
|
|
|
3887
3887
|
},
|
|
3888
3888
|
dependencies: {
|
|
3889
3889
|
"@types/inquirer": "^9.0.9",
|
|
3890
|
+
diff: "^8.0.3",
|
|
3890
3891
|
inquirer: "^13.0.2",
|
|
3891
3892
|
zod: "^4.3.5",
|
|
3892
3893
|
semver: "^6.3.1"
|
|
@@ -5034,9 +5035,9 @@ var CHANGE_PROPOSAL_TYPE_LABELS = {
|
|
|
5034
5035
|
["createStandard" /* createStandard */]: "New standard",
|
|
5035
5036
|
["createCommand" /* createCommand */]: "New command",
|
|
5036
5037
|
["createSkill" /* createSkill */]: "New skill",
|
|
5037
|
-
["removeStandard" /* removeStandard */]: "
|
|
5038
|
-
["removeCommand" /* removeCommand */]: "
|
|
5039
|
-
["removeSkill" /* removeSkill */]: "
|
|
5038
|
+
["removeStandard" /* removeStandard */]: "Removed",
|
|
5039
|
+
["removeCommand" /* removeCommand */]: "Removed",
|
|
5040
|
+
["removeSkill" /* removeSkill */]: "Removed"
|
|
5040
5041
|
};
|
|
5041
5042
|
|
|
5042
5043
|
// packages/types/src/playbookChangeManagement/events/ChangeProposalAcceptedEvent.ts
|
|
@@ -5060,6 +5061,39 @@ var ChangeProposalSubmittedEvent = class extends UserEvent {
|
|
|
5060
5061
|
}
|
|
5061
5062
|
};
|
|
5062
5063
|
|
|
5064
|
+
// packages/types/src/playbookChangeManagement/applier/DiffService.ts
|
|
5065
|
+
var import_diff = require("diff");
|
|
5066
|
+
|
|
5067
|
+
// packages/types/src/playbookChangeManagement/applier/types.ts
|
|
5068
|
+
var STANDARD_CHANGE_TYPES = [
|
|
5069
|
+
"updateStandardName" /* updateStandardName */,
|
|
5070
|
+
"updateStandardScope" /* updateStandardScope */,
|
|
5071
|
+
"updateStandardDescription" /* updateStandardDescription */,
|
|
5072
|
+
"addRule" /* addRule */,
|
|
5073
|
+
"updateRule" /* updateRule */,
|
|
5074
|
+
"deleteRule" /* deleteRule */,
|
|
5075
|
+
"removeStandard" /* removeStandard */
|
|
5076
|
+
];
|
|
5077
|
+
var RECIPE_CHANGE_TYPES = [
|
|
5078
|
+
"updateCommandName" /* updateCommandName */,
|
|
5079
|
+
"updateCommandDescription" /* updateCommandDescription */,
|
|
5080
|
+
"removeCommand" /* removeCommand */
|
|
5081
|
+
];
|
|
5082
|
+
var SKILL_CHANGE_TYPES = [
|
|
5083
|
+
"updateSkillName" /* updateSkillName */,
|
|
5084
|
+
"updateSkillDescription" /* updateSkillDescription */,
|
|
5085
|
+
"updateSkillPrompt" /* updateSkillPrompt */,
|
|
5086
|
+
"updateSkillMetadata" /* updateSkillMetadata */,
|
|
5087
|
+
"updateSkillLicense" /* updateSkillLicense */,
|
|
5088
|
+
"updateSkillCompatibility" /* updateSkillCompatibility */,
|
|
5089
|
+
"updateSkillAllowedTools" /* updateSkillAllowedTools */,
|
|
5090
|
+
"addSkillFile" /* addSkillFile */,
|
|
5091
|
+
"updateSkillFileContent" /* updateSkillFileContent */,
|
|
5092
|
+
"updateSkillFilePermissions" /* updateSkillFilePermissions */,
|
|
5093
|
+
"deleteSkillFile" /* deleteSkillFile */,
|
|
5094
|
+
"removeSkill" /* removeSkill */
|
|
5095
|
+
];
|
|
5096
|
+
|
|
5063
5097
|
// apps/cli/src/application/useCases/ExecuteSingleFileAstUseCase.ts
|
|
5064
5098
|
var ExecuteSingleFileAstUseCase = class _ExecuteSingleFileAstUseCase {
|
|
5065
5099
|
constructor(linterExecutionUseCase) {
|
|
@@ -5123,30 +5157,30 @@ var GitService = class {
|
|
|
5123
5157
|
this.gitRunner = gitRunner;
|
|
5124
5158
|
this.logger = logger2;
|
|
5125
5159
|
}
|
|
5126
|
-
getGitRepositoryRoot(
|
|
5160
|
+
getGitRepositoryRoot(path22) {
|
|
5127
5161
|
try {
|
|
5128
5162
|
const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
|
|
5129
|
-
cwd:
|
|
5163
|
+
cwd: path22
|
|
5130
5164
|
});
|
|
5131
5165
|
const gitRoot = stdout.trim();
|
|
5132
5166
|
this.logger.debug("Resolved git repository root", {
|
|
5133
|
-
inputPath:
|
|
5167
|
+
inputPath: path22,
|
|
5134
5168
|
gitRoot
|
|
5135
5169
|
});
|
|
5136
5170
|
return gitRoot;
|
|
5137
5171
|
} catch (error) {
|
|
5138
5172
|
if (error instanceof Error) {
|
|
5139
5173
|
throw new Error(
|
|
5140
|
-
`Failed to get Git repository root. The path '${
|
|
5174
|
+
`Failed to get Git repository root. The path '${path22}' does not appear to be inside a Git repository.
|
|
5141
5175
|
${error.message}`
|
|
5142
5176
|
);
|
|
5143
5177
|
}
|
|
5144
5178
|
throw new Error("Failed to get Git repository root: Unknown error");
|
|
5145
5179
|
}
|
|
5146
5180
|
}
|
|
5147
|
-
tryGetGitRepositoryRoot(
|
|
5181
|
+
tryGetGitRepositoryRoot(path22) {
|
|
5148
5182
|
try {
|
|
5149
|
-
return this.getGitRepositoryRoot(
|
|
5183
|
+
return this.getGitRepositoryRoot(path22);
|
|
5150
5184
|
} catch {
|
|
5151
5185
|
return null;
|
|
5152
5186
|
}
|
|
@@ -6400,10 +6434,10 @@ var PackmindHttpClient = class {
|
|
|
6400
6434
|
return null;
|
|
6401
6435
|
}
|
|
6402
6436
|
}
|
|
6403
|
-
async request(
|
|
6437
|
+
async request(path22, options = {}) {
|
|
6404
6438
|
const { host } = this.getAuthContext();
|
|
6405
6439
|
const { method = "GET", body } = options;
|
|
6406
|
-
const url = `${host}${
|
|
6440
|
+
const url = `${host}${path22}`;
|
|
6407
6441
|
try {
|
|
6408
6442
|
const response = await fetch(url, {
|
|
6409
6443
|
method,
|
|
@@ -9924,10 +9958,10 @@ async function defaultPromptForCode() {
|
|
|
9924
9958
|
input: process.stdin,
|
|
9925
9959
|
output: process.stdout
|
|
9926
9960
|
});
|
|
9927
|
-
return new Promise((
|
|
9961
|
+
return new Promise((resolve9) => {
|
|
9928
9962
|
rl.question("Enter the login code from the browser: ", (answer) => {
|
|
9929
9963
|
rl.close();
|
|
9930
|
-
|
|
9964
|
+
resolve9(answer.trim());
|
|
9931
9965
|
});
|
|
9932
9966
|
});
|
|
9933
9967
|
}
|
|
@@ -9961,7 +9995,7 @@ async function defaultExchangeCodeForApiKey(code, host) {
|
|
|
9961
9995
|
return await response.json();
|
|
9962
9996
|
}
|
|
9963
9997
|
function defaultStartCallbackServer() {
|
|
9964
|
-
return new Promise((
|
|
9998
|
+
return new Promise((resolve9, reject) => {
|
|
9965
9999
|
let timeoutId = null;
|
|
9966
10000
|
const server = http.createServer((req, res) => {
|
|
9967
10001
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -9974,7 +10008,7 @@ function defaultStartCallbackServer() {
|
|
|
9974
10008
|
if (timeoutId) {
|
|
9975
10009
|
clearTimeout(timeoutId);
|
|
9976
10010
|
}
|
|
9977
|
-
|
|
10011
|
+
resolve9(code);
|
|
9978
10012
|
setImmediate(() => {
|
|
9979
10013
|
server.close();
|
|
9980
10014
|
});
|
|
@@ -10051,8 +10085,8 @@ var LogoutUseCase = class {
|
|
|
10051
10085
|
constructor(deps) {
|
|
10052
10086
|
this.deps = {
|
|
10053
10087
|
getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
|
|
10054
|
-
fileExists: deps?.fileExists ?? ((
|
|
10055
|
-
deleteFile: deps?.deleteFile ?? ((
|
|
10088
|
+
fileExists: deps?.fileExists ?? ((path22) => fs7.existsSync(path22)),
|
|
10089
|
+
deleteFile: deps?.deleteFile ?? ((path22) => fs7.unlinkSync(path22)),
|
|
10056
10090
|
hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
|
|
10057
10091
|
};
|
|
10058
10092
|
}
|
|
@@ -10865,7 +10899,7 @@ var UploadSkillUseCase = class {
|
|
|
10865
10899
|
};
|
|
10866
10900
|
|
|
10867
10901
|
// apps/cli/src/application/useCases/diffStrategies/CommandDiffStrategy.ts
|
|
10868
|
-
var
|
|
10902
|
+
var import_diff2 = require("diff");
|
|
10869
10903
|
var fs11 = __toESM(require("fs/promises"));
|
|
10870
10904
|
var path12 = __toESM(require("path"));
|
|
10871
10905
|
|
|
@@ -10903,7 +10937,7 @@ var CommandDiffStrategy = class {
|
|
|
10903
10937
|
}
|
|
10904
10938
|
const serverBody = stripFrontmatter(file.content);
|
|
10905
10939
|
const localBody = stripFrontmatter(localContent);
|
|
10906
|
-
const changes = (0,
|
|
10940
|
+
const changes = (0, import_diff2.diffLines)(serverBody, localBody);
|
|
10907
10941
|
const hasDifferences = changes.some(
|
|
10908
10942
|
(change) => change.added || change.removed
|
|
10909
10943
|
);
|
|
@@ -10928,7 +10962,7 @@ var CommandDiffStrategy = class {
|
|
|
10928
10962
|
};
|
|
10929
10963
|
|
|
10930
10964
|
// apps/cli/src/application/useCases/diffStrategies/SkillDiffStrategy.ts
|
|
10931
|
-
var
|
|
10965
|
+
var import_diff3 = require("diff");
|
|
10932
10966
|
var fs12 = __toESM(require("fs/promises"));
|
|
10933
10967
|
var path13 = __toESM(require("path"));
|
|
10934
10968
|
var SkillDiffStrategy = class {
|
|
@@ -11000,7 +11034,7 @@ var SkillDiffStrategy = class {
|
|
|
11000
11034
|
if (!serverParsed || !localParsed) {
|
|
11001
11035
|
const serverBody = stripFrontmatter(file.content);
|
|
11002
11036
|
const localBody = stripFrontmatter(localContent);
|
|
11003
|
-
const changes = (0,
|
|
11037
|
+
const changes = (0, import_diff3.diffLines)(serverBody, localBody);
|
|
11004
11038
|
const hasDifferences = changes.some(
|
|
11005
11039
|
(change) => change.added || change.removed
|
|
11006
11040
|
);
|
|
@@ -11761,7 +11795,7 @@ var DiffArtefactsUseCase = class {
|
|
|
11761
11795
|
diffs.push(...newFileDiffs);
|
|
11762
11796
|
}
|
|
11763
11797
|
}
|
|
11764
|
-
return diffs;
|
|
11798
|
+
return diffs.map((diff) => ({ ...diff, targetId: response.targetId }));
|
|
11765
11799
|
}
|
|
11766
11800
|
prefixSkillFolders(skillFolders, relativePath) {
|
|
11767
11801
|
if (!relativePath) return skillFolders;
|
|
@@ -11835,7 +11869,8 @@ var SubmitDiffsUseCase = class {
|
|
|
11835
11869
|
artefactId: CREATION_TYPES.has(diff.type) ? null : diff.artifactId,
|
|
11836
11870
|
payload: diff.payload,
|
|
11837
11871
|
captureMode: "commit" /* commit */,
|
|
11838
|
-
message
|
|
11872
|
+
message,
|
|
11873
|
+
targetId: diff.targetId
|
|
11839
11874
|
}))
|
|
11840
11875
|
});
|
|
11841
11876
|
submitted += response.created;
|
|
@@ -11888,7 +11923,8 @@ var CheckDiffsUseCase = class {
|
|
|
11888
11923
|
artefactId: diff.artifactId,
|
|
11889
11924
|
payload: diff.payload,
|
|
11890
11925
|
captureMode: "commit" /* commit */,
|
|
11891
|
-
message: ""
|
|
11926
|
+
message: "",
|
|
11927
|
+
targetId: diff.targetId
|
|
11892
11928
|
}))
|
|
11893
11929
|
});
|
|
11894
11930
|
for (const result of response.results) {
|
|
@@ -12261,7 +12297,7 @@ function isNotLoggedInError(error) {
|
|
|
12261
12297
|
}
|
|
12262
12298
|
async function lintHandler(args2, deps) {
|
|
12263
12299
|
const {
|
|
12264
|
-
path:
|
|
12300
|
+
path: path22,
|
|
12265
12301
|
draft,
|
|
12266
12302
|
rule,
|
|
12267
12303
|
language,
|
|
@@ -12282,7 +12318,7 @@ async function lintHandler(args2, deps) {
|
|
|
12282
12318
|
throw new Error("option --rule is required to use --draft mode");
|
|
12283
12319
|
}
|
|
12284
12320
|
const startedAt = Date.now();
|
|
12285
|
-
const targetPath =
|
|
12321
|
+
const targetPath = path22 ?? ".";
|
|
12286
12322
|
const absolutePath = resolvePath(targetPath);
|
|
12287
12323
|
if (diff) {
|
|
12288
12324
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(absolutePath);
|
|
@@ -12565,7 +12601,7 @@ function extractWasmFiles() {
|
|
|
12565
12601
|
// apps/cli/src/main.ts
|
|
12566
12602
|
var import_dotenv = require("dotenv");
|
|
12567
12603
|
var fs19 = __toESM(require("fs"));
|
|
12568
|
-
var
|
|
12604
|
+
var path21 = __toESM(require("path"));
|
|
12569
12605
|
|
|
12570
12606
|
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
12571
12607
|
var import_cmd_ts2 = __toESM(require_cjs());
|
|
@@ -13736,7 +13772,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
13736
13772
|
output.write("\n");
|
|
13737
13773
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
13738
13774
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
13739
|
-
return new Promise((
|
|
13775
|
+
return new Promise((resolve9) => {
|
|
13740
13776
|
rl.question(
|
|
13741
13777
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
13742
13778
|
(answer) => {
|
|
@@ -13747,7 +13783,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
13747
13783
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
13748
13784
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
13749
13785
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
13750
|
-
|
|
13786
|
+
resolve9(selectedAgents);
|
|
13751
13787
|
}
|
|
13752
13788
|
);
|
|
13753
13789
|
});
|
|
@@ -14660,10 +14696,10 @@ var import_fs20 = require("fs");
|
|
|
14660
14696
|
var import_cmd_ts19 = __toESM(require_cjs());
|
|
14661
14697
|
|
|
14662
14698
|
// apps/cli/src/infra/utils/diffFormatter.ts
|
|
14663
|
-
var
|
|
14699
|
+
var import_diff4 = require("diff");
|
|
14664
14700
|
init_source();
|
|
14665
14701
|
function formatContentDiff(oldContent, newContent) {
|
|
14666
|
-
const changes = (0,
|
|
14702
|
+
const changes = (0, import_diff4.diffLines)(oldContent, newContent);
|
|
14667
14703
|
const lines = [];
|
|
14668
14704
|
for (const change of changes) {
|
|
14669
14705
|
const trimmedValue = change.value.replace(/\n$/, "");
|
|
@@ -15299,6 +15335,9 @@ function parseSkillDirectory(files) {
|
|
|
15299
15335
|
if (typeof properties.allowedTools === "string") {
|
|
15300
15336
|
payload.allowedTools = properties.allowedTools;
|
|
15301
15337
|
}
|
|
15338
|
+
if (properties.metadata != null && typeof properties.metadata === "object") {
|
|
15339
|
+
payload.metadata = properties.metadata;
|
|
15340
|
+
}
|
|
15302
15341
|
const supportingFiles = files.filter(
|
|
15303
15342
|
(f) => f.relativePath !== SKILL_MD_FILENAME
|
|
15304
15343
|
);
|
|
@@ -15420,14 +15459,38 @@ async function diffAddHandler(deps) {
|
|
|
15420
15459
|
return;
|
|
15421
15460
|
}
|
|
15422
15461
|
const space = await packmindCliHexa.getPackmindGateway().spaces.getGlobal();
|
|
15462
|
+
let targetId;
|
|
15463
|
+
try {
|
|
15464
|
+
const cwd = getCwd();
|
|
15465
|
+
const fullConfig = await packmindCliHexa.readFullConfig(cwd);
|
|
15466
|
+
const configPackages = fullConfig ? Object.keys(fullConfig.packages) : [];
|
|
15467
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
15468
|
+
if (gitRoot && configPackages.length > 0) {
|
|
15469
|
+
const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
15470
|
+
const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
15471
|
+
let relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
15472
|
+
if (!relativePath.startsWith("/")) relativePath = "/" + relativePath;
|
|
15473
|
+
if (!relativePath.endsWith("/")) relativePath = relativePath + "/";
|
|
15474
|
+
const deployedContent = await packmindCliHexa.getPackmindGateway().deployment.getDeployed({
|
|
15475
|
+
packagesSlugs: configPackages,
|
|
15476
|
+
gitRemoteUrl,
|
|
15477
|
+
gitBranch,
|
|
15478
|
+
relativePath,
|
|
15479
|
+
agents: fullConfig?.agents
|
|
15480
|
+
});
|
|
15481
|
+
targetId = deployedContent.targetId;
|
|
15482
|
+
}
|
|
15483
|
+
} catch {
|
|
15484
|
+
}
|
|
15423
15485
|
const diff = {
|
|
15424
15486
|
...diffResult.diff,
|
|
15425
15487
|
filePath: absolutePath,
|
|
15426
|
-
spaceId: space.id
|
|
15488
|
+
spaceId: space.id,
|
|
15489
|
+
targetId
|
|
15427
15490
|
};
|
|
15428
15491
|
const result = await packmindCliHexa.submitDiffs([[diff]], message);
|
|
15429
15492
|
for (const err of result.errors) {
|
|
15430
|
-
logErrorConsole(`Failed to submit "${err.name}": ${err.message}`);
|
|
15493
|
+
logErrorConsole(`Failed to submit addition "${err.name}": ${err.message}`);
|
|
15431
15494
|
}
|
|
15432
15495
|
const summaryParts = [];
|
|
15433
15496
|
if (result.submitted > 0) {
|
|
@@ -15524,6 +15587,216 @@ function isErrnoException(err) {
|
|
|
15524
15587
|
return err instanceof Error && "code" in err;
|
|
15525
15588
|
}
|
|
15526
15589
|
|
|
15590
|
+
// apps/cli/src/infra/commands/diffRemoveHandler.ts
|
|
15591
|
+
var path18 = __toESM(require("path"));
|
|
15592
|
+
var ARTIFACT_TYPE_LABELS2 = {
|
|
15593
|
+
command: "command",
|
|
15594
|
+
standard: "standard",
|
|
15595
|
+
skill: "skill"
|
|
15596
|
+
};
|
|
15597
|
+
async function diffRemoveHandler(deps) {
|
|
15598
|
+
const {
|
|
15599
|
+
packmindCliHexa,
|
|
15600
|
+
filePath,
|
|
15601
|
+
message: messageFlag,
|
|
15602
|
+
exit,
|
|
15603
|
+
getCwd,
|
|
15604
|
+
existsSync: existsSync25,
|
|
15605
|
+
unlinkSync: unlinkSync5,
|
|
15606
|
+
rmSync: rmSync2
|
|
15607
|
+
} = deps;
|
|
15608
|
+
if (!filePath) {
|
|
15609
|
+
logErrorConsole(
|
|
15610
|
+
'Missing file path. Usage: packmind-cli diff remove <path> -m "message"'
|
|
15611
|
+
);
|
|
15612
|
+
exit(1);
|
|
15613
|
+
return;
|
|
15614
|
+
}
|
|
15615
|
+
const cwd = getCwd();
|
|
15616
|
+
const absolutePath = path18.resolve(cwd, filePath);
|
|
15617
|
+
const artefactResult = resolveArtefactFromPath(absolutePath);
|
|
15618
|
+
if (!artefactResult) {
|
|
15619
|
+
logErrorConsole(
|
|
15620
|
+
`Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
|
|
15621
|
+
);
|
|
15622
|
+
exit(1);
|
|
15623
|
+
return;
|
|
15624
|
+
}
|
|
15625
|
+
const matchPath = artefactResult.artifactType === "skill" ? absolutePath.endsWith("SKILL.md") ? absolutePath : path18.join(absolutePath, "SKILL.md") : absolutePath;
|
|
15626
|
+
const skillDirPath = artefactResult.artifactType === "skill" ? absolutePath.endsWith("SKILL.md") ? path18.dirname(absolutePath) : absolutePath : void 0;
|
|
15627
|
+
const existsCheckPath = skillDirPath ?? absolutePath;
|
|
15628
|
+
if (!existsSync25(existsCheckPath)) {
|
|
15629
|
+
logErrorConsole(`File or directory does not exist: ${filePath}`);
|
|
15630
|
+
exit(1);
|
|
15631
|
+
return;
|
|
15632
|
+
}
|
|
15633
|
+
let configPackages;
|
|
15634
|
+
let configAgents;
|
|
15635
|
+
try {
|
|
15636
|
+
const fullConfig = await packmindCliHexa.readFullConfig(cwd);
|
|
15637
|
+
if (fullConfig) {
|
|
15638
|
+
configPackages = Object.keys(fullConfig.packages);
|
|
15639
|
+
configAgents = fullConfig.agents;
|
|
15640
|
+
} else {
|
|
15641
|
+
configPackages = [];
|
|
15642
|
+
}
|
|
15643
|
+
} catch (err) {
|
|
15644
|
+
logErrorConsole("Failed to parse packmind.json");
|
|
15645
|
+
if (err instanceof Error) {
|
|
15646
|
+
logErrorConsole(err.message);
|
|
15647
|
+
} else {
|
|
15648
|
+
logErrorConsole(String(err));
|
|
15649
|
+
}
|
|
15650
|
+
logErrorConsole(
|
|
15651
|
+
"\n\u{1F4A1} Please fix the packmind.json file or delete it to continue."
|
|
15652
|
+
);
|
|
15653
|
+
exit(1);
|
|
15654
|
+
return;
|
|
15655
|
+
}
|
|
15656
|
+
if (configPackages.length === 0) {
|
|
15657
|
+
logErrorConsole(
|
|
15658
|
+
"No packages configured. Configure packages in packmind.json first."
|
|
15659
|
+
);
|
|
15660
|
+
exit(1);
|
|
15661
|
+
return;
|
|
15662
|
+
}
|
|
15663
|
+
let gitRemoteUrl;
|
|
15664
|
+
let gitBranch;
|
|
15665
|
+
let relativePath;
|
|
15666
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
15667
|
+
if (gitRoot) {
|
|
15668
|
+
try {
|
|
15669
|
+
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
15670
|
+
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
15671
|
+
relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
15672
|
+
if (!relativePath.startsWith("/")) {
|
|
15673
|
+
relativePath = "/" + relativePath;
|
|
15674
|
+
}
|
|
15675
|
+
if (!relativePath.endsWith("/")) {
|
|
15676
|
+
relativePath = relativePath + "/";
|
|
15677
|
+
}
|
|
15678
|
+
} catch (err) {
|
|
15679
|
+
logErrorConsole(
|
|
15680
|
+
`Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
|
|
15681
|
+
);
|
|
15682
|
+
}
|
|
15683
|
+
}
|
|
15684
|
+
if (!gitRemoteUrl || !gitBranch || !relativePath) {
|
|
15685
|
+
logErrorConsole(
|
|
15686
|
+
"\n\u274C Could not determine git repository info. The diff command requires a git repository with a remote configured."
|
|
15687
|
+
);
|
|
15688
|
+
exit(1);
|
|
15689
|
+
return;
|
|
15690
|
+
}
|
|
15691
|
+
const deployedContent = await packmindCliHexa.getPackmindGateway().deployment.getDeployed({
|
|
15692
|
+
packagesSlugs: configPackages,
|
|
15693
|
+
gitRemoteUrl,
|
|
15694
|
+
gitBranch,
|
|
15695
|
+
relativePath,
|
|
15696
|
+
agents: configAgents
|
|
15697
|
+
});
|
|
15698
|
+
const relativeToGitRoot = matchPath.startsWith(gitRoot) ? matchPath.slice(gitRoot.length) : matchPath;
|
|
15699
|
+
let normalizedFilePath = normalizePath(relativeToGitRoot);
|
|
15700
|
+
if (normalizedFilePath.startsWith("/")) {
|
|
15701
|
+
normalizedFilePath = normalizedFilePath.slice(1);
|
|
15702
|
+
}
|
|
15703
|
+
const relativePathPrefix = relativePath.startsWith("/") ? relativePath.slice(1) : relativePath;
|
|
15704
|
+
const filePathForComparison = relativePathPrefix.length > 0 && normalizedFilePath.startsWith(relativePathPrefix) ? normalizedFilePath.slice(relativePathPrefix.length) : normalizedFilePath;
|
|
15705
|
+
const deployedFile = deployedContent.fileUpdates.createOrUpdate.find(
|
|
15706
|
+
(file) => normalizePath(file.path) === filePathForComparison
|
|
15707
|
+
);
|
|
15708
|
+
if (!deployedFile) {
|
|
15709
|
+
const artifactTypeLabel = ARTIFACT_TYPE_LABELS2[artefactResult.artifactType];
|
|
15710
|
+
logErrorConsole(`This ${artifactTypeLabel} does not come from Packmind`);
|
|
15711
|
+
exit(1);
|
|
15712
|
+
return;
|
|
15713
|
+
}
|
|
15714
|
+
if (!deployedFile.artifactId || !deployedFile.spaceId) {
|
|
15715
|
+
logErrorConsole(
|
|
15716
|
+
"Missing artifact metadata. Cannot create change proposal for removal."
|
|
15717
|
+
);
|
|
15718
|
+
exit(1);
|
|
15719
|
+
return;
|
|
15720
|
+
}
|
|
15721
|
+
if (!deployedContent.targetId || !deployedFile.packageIds) {
|
|
15722
|
+
logErrorConsole(
|
|
15723
|
+
"Missing target or package information. Cannot create change proposal for removal."
|
|
15724
|
+
);
|
|
15725
|
+
exit(1);
|
|
15726
|
+
return;
|
|
15727
|
+
}
|
|
15728
|
+
let message;
|
|
15729
|
+
if (messageFlag !== void 0) {
|
|
15730
|
+
const validation = validateMessage(messageFlag);
|
|
15731
|
+
if (!validation.valid) {
|
|
15732
|
+
logErrorConsole(validation.error);
|
|
15733
|
+
exit(1);
|
|
15734
|
+
return;
|
|
15735
|
+
}
|
|
15736
|
+
message = validation.message;
|
|
15737
|
+
} else if (process.stdin.isTTY) {
|
|
15738
|
+
const editorMessage = openEditorForMessage();
|
|
15739
|
+
const validation = validateMessage(editorMessage);
|
|
15740
|
+
if (!validation.valid) {
|
|
15741
|
+
logErrorConsole(
|
|
15742
|
+
"Aborting submission: empty message. Use -m to provide a message."
|
|
15743
|
+
);
|
|
15744
|
+
exit(1);
|
|
15745
|
+
return;
|
|
15746
|
+
}
|
|
15747
|
+
message = validation.message;
|
|
15748
|
+
} else {
|
|
15749
|
+
logErrorConsole(
|
|
15750
|
+
'Non-interactive mode requires -m flag. Usage: packmind-cli diff remove <path> -m "your message"'
|
|
15751
|
+
);
|
|
15752
|
+
exit(1);
|
|
15753
|
+
return;
|
|
15754
|
+
}
|
|
15755
|
+
const changeProposalType = artefactResult.artifactType === "standard" ? "removeStandard" /* removeStandard */ : artefactResult.artifactType === "command" ? "removeCommand" /* removeCommand */ : "removeSkill" /* removeSkill */;
|
|
15756
|
+
const diff = {
|
|
15757
|
+
filePath: absolutePath,
|
|
15758
|
+
type: changeProposalType,
|
|
15759
|
+
payload: {
|
|
15760
|
+
targetId: deployedContent.targetId,
|
|
15761
|
+
packageIds: deployedFile.packageIds.map(createPackageId)
|
|
15762
|
+
},
|
|
15763
|
+
artifactName: deployedFile.artifactName || artefactResult.artifactType,
|
|
15764
|
+
artifactType: artefactResult.artifactType,
|
|
15765
|
+
artifactId: deployedFile.artifactId,
|
|
15766
|
+
spaceId: deployedFile.spaceId,
|
|
15767
|
+
targetId: deployedContent.targetId
|
|
15768
|
+
};
|
|
15769
|
+
const result = await packmindCliHexa.submitDiffs([[diff]], message);
|
|
15770
|
+
for (const err of result.errors) {
|
|
15771
|
+
logErrorConsole(`Failed to submit removal "${err.name}": ${err.message}`);
|
|
15772
|
+
}
|
|
15773
|
+
if (result.errors.length > 0) {
|
|
15774
|
+
exit(1);
|
|
15775
|
+
return;
|
|
15776
|
+
}
|
|
15777
|
+
if (result.submitted > 0) {
|
|
15778
|
+
logSuccessConsole("Change proposal for removal submitted successfully");
|
|
15779
|
+
} else if (result.alreadySubmitted > 0) {
|
|
15780
|
+
logWarningConsole("Change proposal for removal already submitted");
|
|
15781
|
+
}
|
|
15782
|
+
try {
|
|
15783
|
+
if (skillDirPath) {
|
|
15784
|
+
rmSync2(skillDirPath, { recursive: true });
|
|
15785
|
+
logSuccessConsole(`Directory deleted: ${skillDirPath}`);
|
|
15786
|
+
} else {
|
|
15787
|
+
unlinkSync5(absolutePath);
|
|
15788
|
+
logSuccessConsole(`File deleted: ${filePath}`);
|
|
15789
|
+
}
|
|
15790
|
+
} catch (err) {
|
|
15791
|
+
logErrorConsole(
|
|
15792
|
+
`Failed to delete file: ${err instanceof Error ? err.message : String(err)}`
|
|
15793
|
+
);
|
|
15794
|
+
exit(1);
|
|
15795
|
+
return;
|
|
15796
|
+
}
|
|
15797
|
+
exit(0);
|
|
15798
|
+
}
|
|
15799
|
+
|
|
15527
15800
|
// apps/cli/src/infra/commands/DiffCommand.ts
|
|
15528
15801
|
var diffCommand = (0, import_cmd_ts19.command)({
|
|
15529
15802
|
name: "diff",
|
|
@@ -15546,7 +15819,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
15546
15819
|
positionals: (0, import_cmd_ts19.restPositionals)({
|
|
15547
15820
|
type: import_cmd_ts19.string,
|
|
15548
15821
|
displayName: "args",
|
|
15549
|
-
description: "Subcommand and arguments (e.g., add <path>)"
|
|
15822
|
+
description: "Subcommand and arguments (e.g., add <path>, remove <path>)"
|
|
15550
15823
|
})
|
|
15551
15824
|
},
|
|
15552
15825
|
handler: async ({ submit, includeSubmitted, message, positionals }) => {
|
|
@@ -15564,6 +15837,19 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
15564
15837
|
});
|
|
15565
15838
|
return;
|
|
15566
15839
|
}
|
|
15840
|
+
if (positionals[0] === "remove" || positionals[0] === "rm") {
|
|
15841
|
+
await diffRemoveHandler({
|
|
15842
|
+
packmindCliHexa,
|
|
15843
|
+
filePath: positionals[1],
|
|
15844
|
+
message,
|
|
15845
|
+
exit: process.exit,
|
|
15846
|
+
getCwd: () => process.cwd(),
|
|
15847
|
+
existsSync: (p) => (0, import_fs20.existsSync)(p),
|
|
15848
|
+
unlinkSync: (p) => (0, import_fs20.unlinkSync)(p),
|
|
15849
|
+
rmSync: (p, opts) => (0, import_fs20.rmSync)(p, opts)
|
|
15850
|
+
});
|
|
15851
|
+
return;
|
|
15852
|
+
}
|
|
15567
15853
|
await diffArtefactsHandler({
|
|
15568
15854
|
packmindCliHexa,
|
|
15569
15855
|
exit: process.exit,
|
|
@@ -15951,7 +16237,7 @@ var import_cmd_ts24 = __toESM(require_cjs());
|
|
|
15951
16237
|
|
|
15952
16238
|
// apps/cli/src/application/services/AgentArtifactDetectionService.ts
|
|
15953
16239
|
var fs18 = __toESM(require("fs/promises"));
|
|
15954
|
-
var
|
|
16240
|
+
var path19 = __toESM(require("path"));
|
|
15955
16241
|
var AGENT_ARTIFACT_CHECKS = [
|
|
15956
16242
|
{ agent: "claude", paths: [".claude"] },
|
|
15957
16243
|
{ agent: "cursor", paths: [".cursor"] },
|
|
@@ -15969,7 +16255,7 @@ var AgentArtifactDetectionService = class {
|
|
|
15969
16255
|
const detected = [];
|
|
15970
16256
|
for (const check of AGENT_ARTIFACT_CHECKS) {
|
|
15971
16257
|
for (const relativePath of check.paths) {
|
|
15972
|
-
const fullPath =
|
|
16258
|
+
const fullPath = path19.join(baseDirectory, relativePath);
|
|
15973
16259
|
const exists = await this.pathExists(fullPath);
|
|
15974
16260
|
if (exists) {
|
|
15975
16261
|
detected.push({
|
|
@@ -16066,7 +16352,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
16066
16352
|
output.write("\n");
|
|
16067
16353
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
16068
16354
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
16069
|
-
return new Promise((
|
|
16355
|
+
return new Promise((resolve9) => {
|
|
16070
16356
|
rl.question(
|
|
16071
16357
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
16072
16358
|
(answer) => {
|
|
@@ -16075,7 +16361,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
16075
16361
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
16076
16362
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
16077
16363
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
16078
|
-
|
|
16364
|
+
resolve9(selectedAgents);
|
|
16079
16365
|
}
|
|
16080
16366
|
);
|
|
16081
16367
|
});
|
|
@@ -16334,6 +16620,14 @@ function isLocalNpmPackage(scriptPath) {
|
|
|
16334
16620
|
if (!scriptPath) return false;
|
|
16335
16621
|
return scriptPath.includes(import_path5.default.join("node_modules", "@packmind", "cli"));
|
|
16336
16622
|
}
|
|
16623
|
+
function isHomebrewInstall(executablePath) {
|
|
16624
|
+
try {
|
|
16625
|
+
const realPath = (0, import_fs21.realpathSync)(executablePath);
|
|
16626
|
+
return realPath.includes("/Cellar/");
|
|
16627
|
+
} catch {
|
|
16628
|
+
return false;
|
|
16629
|
+
}
|
|
16630
|
+
}
|
|
16337
16631
|
async function updateHandler(deps) {
|
|
16338
16632
|
const execBasename = import_path5.default.basename(deps.executablePath).replace(/\.exe$/, "");
|
|
16339
16633
|
const jsRuntimes = ["node", "bun", "deno"];
|
|
@@ -16350,6 +16644,13 @@ async function updateHandler(deps) {
|
|
|
16350
16644
|
process.exit(1);
|
|
16351
16645
|
return;
|
|
16352
16646
|
}
|
|
16647
|
+
if (isHomebrewInstall(deps.executablePath)) {
|
|
16648
|
+
logInfoConsole(
|
|
16649
|
+
"This CLI was installed via Homebrew.\nTo update, run: brew upgrade packmind-cli"
|
|
16650
|
+
);
|
|
16651
|
+
process.exit(0);
|
|
16652
|
+
return;
|
|
16653
|
+
}
|
|
16353
16654
|
logInfoConsole(
|
|
16354
16655
|
`Current version: ${deps.currentVersion} (${deps.isExecutableMode ? "standalone executable" : "npm package"})`
|
|
16355
16656
|
);
|
|
@@ -16431,12 +16732,12 @@ function findEnvFile() {
|
|
|
16431
16732
|
const currentDir = process.cwd();
|
|
16432
16733
|
const gitService = new GitService();
|
|
16433
16734
|
const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
|
|
16434
|
-
const filesystemRoot =
|
|
16735
|
+
const filesystemRoot = path21.parse(currentDir).root;
|
|
16435
16736
|
const stopDir = gitRoot ?? filesystemRoot;
|
|
16436
16737
|
let searchDir = currentDir;
|
|
16437
|
-
let parentDir =
|
|
16738
|
+
let parentDir = path21.dirname(searchDir);
|
|
16438
16739
|
while (searchDir !== parentDir) {
|
|
16439
|
-
const envPath2 =
|
|
16740
|
+
const envPath2 = path21.join(searchDir, ".env");
|
|
16440
16741
|
if (fs19.existsSync(envPath2)) {
|
|
16441
16742
|
return envPath2;
|
|
16442
16743
|
}
|
|
@@ -16444,7 +16745,7 @@ function findEnvFile() {
|
|
|
16444
16745
|
return null;
|
|
16445
16746
|
}
|
|
16446
16747
|
searchDir = parentDir;
|
|
16447
|
-
parentDir =
|
|
16748
|
+
parentDir = path21.dirname(searchDir);
|
|
16448
16749
|
}
|
|
16449
16750
|
return null;
|
|
16450
16751
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@packmind/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.1",
|
|
4
4
|
"description": "A command-line interface for Packmind linting and code quality checks",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"axios": "1.13.5",
|
|
48
48
|
"bcrypt": "6.0.0",
|
|
49
49
|
"bullmq": "5.63.0",
|
|
50
|
-
"diff": "8.0.3",
|
|
50
|
+
"diff": "^8.0.3",
|
|
51
51
|
"dotenv": "16.4.7",
|
|
52
|
-
"express": "5.1
|
|
52
|
+
"express": "5.2.1",
|
|
53
53
|
"inquirer": "^13.0.2",
|
|
54
54
|
"minimatch": "9.0.3",
|
|
55
55
|
"open": "11.0.0",
|