@packmind/cli 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main.cjs +308 -36
- 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.0",
|
|
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"
|
|
@@ -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
|
);
|
|
@@ -12261,7 +12295,7 @@ function isNotLoggedInError(error) {
|
|
|
12261
12295
|
}
|
|
12262
12296
|
async function lintHandler(args2, deps) {
|
|
12263
12297
|
const {
|
|
12264
|
-
path:
|
|
12298
|
+
path: path22,
|
|
12265
12299
|
draft,
|
|
12266
12300
|
rule,
|
|
12267
12301
|
language,
|
|
@@ -12282,7 +12316,7 @@ async function lintHandler(args2, deps) {
|
|
|
12282
12316
|
throw new Error("option --rule is required to use --draft mode");
|
|
12283
12317
|
}
|
|
12284
12318
|
const startedAt = Date.now();
|
|
12285
|
-
const targetPath =
|
|
12319
|
+
const targetPath = path22 ?? ".";
|
|
12286
12320
|
const absolutePath = resolvePath(targetPath);
|
|
12287
12321
|
if (diff) {
|
|
12288
12322
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(absolutePath);
|
|
@@ -12565,7 +12599,7 @@ function extractWasmFiles() {
|
|
|
12565
12599
|
// apps/cli/src/main.ts
|
|
12566
12600
|
var import_dotenv = require("dotenv");
|
|
12567
12601
|
var fs19 = __toESM(require("fs"));
|
|
12568
|
-
var
|
|
12602
|
+
var path21 = __toESM(require("path"));
|
|
12569
12603
|
|
|
12570
12604
|
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
12571
12605
|
var import_cmd_ts2 = __toESM(require_cjs());
|
|
@@ -13736,7 +13770,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
13736
13770
|
output.write("\n");
|
|
13737
13771
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
13738
13772
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
13739
|
-
return new Promise((
|
|
13773
|
+
return new Promise((resolve9) => {
|
|
13740
13774
|
rl.question(
|
|
13741
13775
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
13742
13776
|
(answer) => {
|
|
@@ -13747,7 +13781,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
13747
13781
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
13748
13782
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
13749
13783
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
13750
|
-
|
|
13784
|
+
resolve9(selectedAgents);
|
|
13751
13785
|
}
|
|
13752
13786
|
);
|
|
13753
13787
|
});
|
|
@@ -14660,10 +14694,10 @@ var import_fs20 = require("fs");
|
|
|
14660
14694
|
var import_cmd_ts19 = __toESM(require_cjs());
|
|
14661
14695
|
|
|
14662
14696
|
// apps/cli/src/infra/utils/diffFormatter.ts
|
|
14663
|
-
var
|
|
14697
|
+
var import_diff4 = require("diff");
|
|
14664
14698
|
init_source();
|
|
14665
14699
|
function formatContentDiff(oldContent, newContent) {
|
|
14666
|
-
const changes = (0,
|
|
14700
|
+
const changes = (0, import_diff4.diffLines)(oldContent, newContent);
|
|
14667
14701
|
const lines = [];
|
|
14668
14702
|
for (const change of changes) {
|
|
14669
14703
|
const trimmedValue = change.value.replace(/\n$/, "");
|
|
@@ -15299,6 +15333,9 @@ function parseSkillDirectory(files) {
|
|
|
15299
15333
|
if (typeof properties.allowedTools === "string") {
|
|
15300
15334
|
payload.allowedTools = properties.allowedTools;
|
|
15301
15335
|
}
|
|
15336
|
+
if (properties.metadata != null && typeof properties.metadata === "object") {
|
|
15337
|
+
payload.metadata = properties.metadata;
|
|
15338
|
+
}
|
|
15302
15339
|
const supportingFiles = files.filter(
|
|
15303
15340
|
(f) => f.relativePath !== SKILL_MD_FILENAME
|
|
15304
15341
|
);
|
|
@@ -15427,7 +15464,7 @@ async function diffAddHandler(deps) {
|
|
|
15427
15464
|
};
|
|
15428
15465
|
const result = await packmindCliHexa.submitDiffs([[diff]], message);
|
|
15429
15466
|
for (const err of result.errors) {
|
|
15430
|
-
logErrorConsole(`Failed to submit "${err.name}": ${err.message}`);
|
|
15467
|
+
logErrorConsole(`Failed to submit addition "${err.name}": ${err.message}`);
|
|
15431
15468
|
}
|
|
15432
15469
|
const summaryParts = [];
|
|
15433
15470
|
if (result.submitted > 0) {
|
|
@@ -15524,6 +15561,213 @@ function isErrnoException(err) {
|
|
|
15524
15561
|
return err instanceof Error && "code" in err;
|
|
15525
15562
|
}
|
|
15526
15563
|
|
|
15564
|
+
// apps/cli/src/infra/commands/diffRemoveHandler.ts
|
|
15565
|
+
var path18 = __toESM(require("path"));
|
|
15566
|
+
var ARTIFACT_TYPE_LABELS2 = {
|
|
15567
|
+
command: "command",
|
|
15568
|
+
standard: "standard",
|
|
15569
|
+
skill: "skill"
|
|
15570
|
+
};
|
|
15571
|
+
async function diffRemoveHandler(deps) {
|
|
15572
|
+
const {
|
|
15573
|
+
packmindCliHexa,
|
|
15574
|
+
filePath,
|
|
15575
|
+
message: messageFlag,
|
|
15576
|
+
exit,
|
|
15577
|
+
getCwd,
|
|
15578
|
+
existsSync: existsSync25,
|
|
15579
|
+
unlinkSync: unlinkSync5,
|
|
15580
|
+
rmSync: rmSync2
|
|
15581
|
+
} = deps;
|
|
15582
|
+
if (!filePath) {
|
|
15583
|
+
logErrorConsole(
|
|
15584
|
+
'Missing file path. Usage: packmind-cli diff remove <path> -m "message"'
|
|
15585
|
+
);
|
|
15586
|
+
exit(1);
|
|
15587
|
+
return;
|
|
15588
|
+
}
|
|
15589
|
+
const cwd = getCwd();
|
|
15590
|
+
const absolutePath = path18.resolve(cwd, filePath);
|
|
15591
|
+
const artefactResult = resolveArtefactFromPath(absolutePath);
|
|
15592
|
+
if (!artefactResult) {
|
|
15593
|
+
logErrorConsole(
|
|
15594
|
+
`Unsupported file path: ${absolutePath}. File must be in a recognized artefact directory (command, standard, or skill).`
|
|
15595
|
+
);
|
|
15596
|
+
exit(1);
|
|
15597
|
+
return;
|
|
15598
|
+
}
|
|
15599
|
+
const matchPath = artefactResult.artifactType === "skill" ? absolutePath.endsWith("SKILL.md") ? absolutePath : path18.join(absolutePath, "SKILL.md") : absolutePath;
|
|
15600
|
+
const skillDirPath = artefactResult.artifactType === "skill" ? absolutePath.endsWith("SKILL.md") ? path18.dirname(absolutePath) : absolutePath : void 0;
|
|
15601
|
+
const existsCheckPath = skillDirPath ?? absolutePath;
|
|
15602
|
+
if (!existsSync25(existsCheckPath)) {
|
|
15603
|
+
logErrorConsole(`File or directory does not exist: ${filePath}`);
|
|
15604
|
+
exit(1);
|
|
15605
|
+
return;
|
|
15606
|
+
}
|
|
15607
|
+
let configPackages;
|
|
15608
|
+
let configAgents;
|
|
15609
|
+
try {
|
|
15610
|
+
const fullConfig = await packmindCliHexa.readFullConfig(cwd);
|
|
15611
|
+
if (fullConfig) {
|
|
15612
|
+
configPackages = Object.keys(fullConfig.packages);
|
|
15613
|
+
configAgents = fullConfig.agents;
|
|
15614
|
+
} else {
|
|
15615
|
+
configPackages = [];
|
|
15616
|
+
}
|
|
15617
|
+
} catch (err) {
|
|
15618
|
+
logErrorConsole("Failed to parse packmind.json");
|
|
15619
|
+
if (err instanceof Error) {
|
|
15620
|
+
logErrorConsole(err.message);
|
|
15621
|
+
} else {
|
|
15622
|
+
logErrorConsole(String(err));
|
|
15623
|
+
}
|
|
15624
|
+
logErrorConsole(
|
|
15625
|
+
"\n\u{1F4A1} Please fix the packmind.json file or delete it to continue."
|
|
15626
|
+
);
|
|
15627
|
+
exit(1);
|
|
15628
|
+
return;
|
|
15629
|
+
}
|
|
15630
|
+
if (configPackages.length === 0) {
|
|
15631
|
+
logErrorConsole(
|
|
15632
|
+
"No packages configured. Configure packages in packmind.json first."
|
|
15633
|
+
);
|
|
15634
|
+
exit(1);
|
|
15635
|
+
return;
|
|
15636
|
+
}
|
|
15637
|
+
let gitRemoteUrl;
|
|
15638
|
+
let gitBranch;
|
|
15639
|
+
let relativePath;
|
|
15640
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
15641
|
+
if (gitRoot) {
|
|
15642
|
+
try {
|
|
15643
|
+
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
15644
|
+
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
15645
|
+
relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
15646
|
+
if (!relativePath.startsWith("/")) {
|
|
15647
|
+
relativePath = "/" + relativePath;
|
|
15648
|
+
}
|
|
15649
|
+
if (!relativePath.endsWith("/")) {
|
|
15650
|
+
relativePath = relativePath + "/";
|
|
15651
|
+
}
|
|
15652
|
+
} catch (err) {
|
|
15653
|
+
logErrorConsole(
|
|
15654
|
+
`Failed to collect git info: ${err instanceof Error ? err.message : String(err)}`
|
|
15655
|
+
);
|
|
15656
|
+
}
|
|
15657
|
+
}
|
|
15658
|
+
if (!gitRemoteUrl || !gitBranch || !relativePath) {
|
|
15659
|
+
logErrorConsole(
|
|
15660
|
+
"\n\u274C Could not determine git repository info. The diff command requires a git repository with a remote configured."
|
|
15661
|
+
);
|
|
15662
|
+
exit(1);
|
|
15663
|
+
return;
|
|
15664
|
+
}
|
|
15665
|
+
const deployedContent = await packmindCliHexa.getPackmindGateway().deployment.getDeployed({
|
|
15666
|
+
packagesSlugs: configPackages,
|
|
15667
|
+
gitRemoteUrl,
|
|
15668
|
+
gitBranch,
|
|
15669
|
+
relativePath,
|
|
15670
|
+
agents: configAgents
|
|
15671
|
+
});
|
|
15672
|
+
const relativeToGitRoot = matchPath.startsWith(gitRoot) ? matchPath.slice(gitRoot.length) : matchPath;
|
|
15673
|
+
let normalizedFilePath = normalizePath(relativeToGitRoot);
|
|
15674
|
+
if (normalizedFilePath.startsWith("/")) {
|
|
15675
|
+
normalizedFilePath = normalizedFilePath.slice(1);
|
|
15676
|
+
}
|
|
15677
|
+
const deployedFile = deployedContent.fileUpdates.createOrUpdate.find(
|
|
15678
|
+
(file) => normalizePath(file.path) === normalizedFilePath
|
|
15679
|
+
);
|
|
15680
|
+
if (!deployedFile) {
|
|
15681
|
+
const artifactTypeLabel = ARTIFACT_TYPE_LABELS2[artefactResult.artifactType];
|
|
15682
|
+
logErrorConsole(`This ${artifactTypeLabel} does not come from Packmind`);
|
|
15683
|
+
exit(1);
|
|
15684
|
+
return;
|
|
15685
|
+
}
|
|
15686
|
+
if (!deployedFile.artifactId || !deployedFile.spaceId) {
|
|
15687
|
+
logErrorConsole(
|
|
15688
|
+
"Missing artifact metadata. Cannot create change proposal for removal."
|
|
15689
|
+
);
|
|
15690
|
+
exit(1);
|
|
15691
|
+
return;
|
|
15692
|
+
}
|
|
15693
|
+
if (!deployedContent.targetId || !deployedContent.packageIds) {
|
|
15694
|
+
logErrorConsole(
|
|
15695
|
+
"Missing target or package information. Cannot create change proposal for removal."
|
|
15696
|
+
);
|
|
15697
|
+
exit(1);
|
|
15698
|
+
return;
|
|
15699
|
+
}
|
|
15700
|
+
let message;
|
|
15701
|
+
if (messageFlag !== void 0) {
|
|
15702
|
+
const validation = validateMessage(messageFlag);
|
|
15703
|
+
if (!validation.valid) {
|
|
15704
|
+
logErrorConsole(validation.error);
|
|
15705
|
+
exit(1);
|
|
15706
|
+
return;
|
|
15707
|
+
}
|
|
15708
|
+
message = validation.message;
|
|
15709
|
+
} else if (process.stdin.isTTY) {
|
|
15710
|
+
const editorMessage = openEditorForMessage();
|
|
15711
|
+
const validation = validateMessage(editorMessage);
|
|
15712
|
+
if (!validation.valid) {
|
|
15713
|
+
logErrorConsole(
|
|
15714
|
+
"Aborting submission: empty message. Use -m to provide a message."
|
|
15715
|
+
);
|
|
15716
|
+
exit(1);
|
|
15717
|
+
return;
|
|
15718
|
+
}
|
|
15719
|
+
message = validation.message;
|
|
15720
|
+
} else {
|
|
15721
|
+
logErrorConsole(
|
|
15722
|
+
'Non-interactive mode requires -m flag. Usage: packmind-cli diff remove <path> -m "your message"'
|
|
15723
|
+
);
|
|
15724
|
+
exit(1);
|
|
15725
|
+
return;
|
|
15726
|
+
}
|
|
15727
|
+
const changeProposalType = artefactResult.artifactType === "standard" ? "removeStandard" /* removeStandard */ : artefactResult.artifactType === "command" ? "removeCommand" /* removeCommand */ : "removeSkill" /* removeSkill */;
|
|
15728
|
+
const diff = {
|
|
15729
|
+
filePath: absolutePath,
|
|
15730
|
+
type: changeProposalType,
|
|
15731
|
+
payload: {
|
|
15732
|
+
targetId: deployedContent.targetId,
|
|
15733
|
+
packageIds: deployedContent.packageIds
|
|
15734
|
+
},
|
|
15735
|
+
artifactName: deployedFile.artifactName || artefactResult.artifactType,
|
|
15736
|
+
artifactType: artefactResult.artifactType,
|
|
15737
|
+
artifactId: deployedFile.artifactId,
|
|
15738
|
+
spaceId: deployedFile.spaceId
|
|
15739
|
+
};
|
|
15740
|
+
const result = await packmindCliHexa.submitDiffs([[diff]], message);
|
|
15741
|
+
for (const err of result.errors) {
|
|
15742
|
+
logErrorConsole(`Failed to submit removal "${err.name}": ${err.message}`);
|
|
15743
|
+
}
|
|
15744
|
+
if (result.errors.length > 0) {
|
|
15745
|
+
exit(1);
|
|
15746
|
+
return;
|
|
15747
|
+
}
|
|
15748
|
+
if (result.submitted > 0) {
|
|
15749
|
+
logSuccessConsole("Change proposal for removal submitted successfully");
|
|
15750
|
+
} else if (result.alreadySubmitted > 0) {
|
|
15751
|
+
logWarningConsole("Change proposal for removal already submitted");
|
|
15752
|
+
}
|
|
15753
|
+
try {
|
|
15754
|
+
if (skillDirPath) {
|
|
15755
|
+
rmSync2(skillDirPath, { recursive: true });
|
|
15756
|
+
logSuccessConsole(`Directory deleted: ${skillDirPath}`);
|
|
15757
|
+
} else {
|
|
15758
|
+
unlinkSync5(absolutePath);
|
|
15759
|
+
logSuccessConsole(`File deleted: ${filePath}`);
|
|
15760
|
+
}
|
|
15761
|
+
} catch (err) {
|
|
15762
|
+
logErrorConsole(
|
|
15763
|
+
`Failed to delete file: ${err instanceof Error ? err.message : String(err)}`
|
|
15764
|
+
);
|
|
15765
|
+
exit(1);
|
|
15766
|
+
return;
|
|
15767
|
+
}
|
|
15768
|
+
exit(0);
|
|
15769
|
+
}
|
|
15770
|
+
|
|
15527
15771
|
// apps/cli/src/infra/commands/DiffCommand.ts
|
|
15528
15772
|
var diffCommand = (0, import_cmd_ts19.command)({
|
|
15529
15773
|
name: "diff",
|
|
@@ -15546,7 +15790,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
15546
15790
|
positionals: (0, import_cmd_ts19.restPositionals)({
|
|
15547
15791
|
type: import_cmd_ts19.string,
|
|
15548
15792
|
displayName: "args",
|
|
15549
|
-
description: "Subcommand and arguments (e.g., add <path>)"
|
|
15793
|
+
description: "Subcommand and arguments (e.g., add <path>, remove <path>)"
|
|
15550
15794
|
})
|
|
15551
15795
|
},
|
|
15552
15796
|
handler: async ({ submit, includeSubmitted, message, positionals }) => {
|
|
@@ -15564,6 +15808,19 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
15564
15808
|
});
|
|
15565
15809
|
return;
|
|
15566
15810
|
}
|
|
15811
|
+
if (positionals[0] === "remove" || positionals[0] === "rm") {
|
|
15812
|
+
await diffRemoveHandler({
|
|
15813
|
+
packmindCliHexa,
|
|
15814
|
+
filePath: positionals[1],
|
|
15815
|
+
message,
|
|
15816
|
+
exit: process.exit,
|
|
15817
|
+
getCwd: () => process.cwd(),
|
|
15818
|
+
existsSync: (p) => (0, import_fs20.existsSync)(p),
|
|
15819
|
+
unlinkSync: (p) => (0, import_fs20.unlinkSync)(p),
|
|
15820
|
+
rmSync: (p, opts) => (0, import_fs20.rmSync)(p, opts)
|
|
15821
|
+
});
|
|
15822
|
+
return;
|
|
15823
|
+
}
|
|
15567
15824
|
await diffArtefactsHandler({
|
|
15568
15825
|
packmindCliHexa,
|
|
15569
15826
|
exit: process.exit,
|
|
@@ -15951,7 +16208,7 @@ var import_cmd_ts24 = __toESM(require_cjs());
|
|
|
15951
16208
|
|
|
15952
16209
|
// apps/cli/src/application/services/AgentArtifactDetectionService.ts
|
|
15953
16210
|
var fs18 = __toESM(require("fs/promises"));
|
|
15954
|
-
var
|
|
16211
|
+
var path19 = __toESM(require("path"));
|
|
15955
16212
|
var AGENT_ARTIFACT_CHECKS = [
|
|
15956
16213
|
{ agent: "claude", paths: [".claude"] },
|
|
15957
16214
|
{ agent: "cursor", paths: [".cursor"] },
|
|
@@ -15969,7 +16226,7 @@ var AgentArtifactDetectionService = class {
|
|
|
15969
16226
|
const detected = [];
|
|
15970
16227
|
for (const check of AGENT_ARTIFACT_CHECKS) {
|
|
15971
16228
|
for (const relativePath of check.paths) {
|
|
15972
|
-
const fullPath =
|
|
16229
|
+
const fullPath = path19.join(baseDirectory, relativePath);
|
|
15973
16230
|
const exists = await this.pathExists(fullPath);
|
|
15974
16231
|
if (exists) {
|
|
15975
16232
|
detected.push({
|
|
@@ -16066,7 +16323,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
16066
16323
|
output.write("\n");
|
|
16067
16324
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
16068
16325
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
16069
|
-
return new Promise((
|
|
16326
|
+
return new Promise((resolve9) => {
|
|
16070
16327
|
rl.question(
|
|
16071
16328
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
16072
16329
|
(answer) => {
|
|
@@ -16075,7 +16332,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
16075
16332
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
16076
16333
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
16077
16334
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
16078
|
-
|
|
16335
|
+
resolve9(selectedAgents);
|
|
16079
16336
|
}
|
|
16080
16337
|
);
|
|
16081
16338
|
});
|
|
@@ -16334,6 +16591,14 @@ function isLocalNpmPackage(scriptPath) {
|
|
|
16334
16591
|
if (!scriptPath) return false;
|
|
16335
16592
|
return scriptPath.includes(import_path5.default.join("node_modules", "@packmind", "cli"));
|
|
16336
16593
|
}
|
|
16594
|
+
function isHomebrewInstall(executablePath) {
|
|
16595
|
+
try {
|
|
16596
|
+
const realPath = (0, import_fs21.realpathSync)(executablePath);
|
|
16597
|
+
return realPath.includes("/Cellar/");
|
|
16598
|
+
} catch {
|
|
16599
|
+
return false;
|
|
16600
|
+
}
|
|
16601
|
+
}
|
|
16337
16602
|
async function updateHandler(deps) {
|
|
16338
16603
|
const execBasename = import_path5.default.basename(deps.executablePath).replace(/\.exe$/, "");
|
|
16339
16604
|
const jsRuntimes = ["node", "bun", "deno"];
|
|
@@ -16350,6 +16615,13 @@ async function updateHandler(deps) {
|
|
|
16350
16615
|
process.exit(1);
|
|
16351
16616
|
return;
|
|
16352
16617
|
}
|
|
16618
|
+
if (isHomebrewInstall(deps.executablePath)) {
|
|
16619
|
+
logInfoConsole(
|
|
16620
|
+
"This CLI was installed via Homebrew.\nTo update, run: brew upgrade packmind-cli"
|
|
16621
|
+
);
|
|
16622
|
+
process.exit(0);
|
|
16623
|
+
return;
|
|
16624
|
+
}
|
|
16353
16625
|
logInfoConsole(
|
|
16354
16626
|
`Current version: ${deps.currentVersion} (${deps.isExecutableMode ? "standalone executable" : "npm package"})`
|
|
16355
16627
|
);
|
|
@@ -16431,12 +16703,12 @@ function findEnvFile() {
|
|
|
16431
16703
|
const currentDir = process.cwd();
|
|
16432
16704
|
const gitService = new GitService();
|
|
16433
16705
|
const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
|
|
16434
|
-
const filesystemRoot =
|
|
16706
|
+
const filesystemRoot = path21.parse(currentDir).root;
|
|
16435
16707
|
const stopDir = gitRoot ?? filesystemRoot;
|
|
16436
16708
|
let searchDir = currentDir;
|
|
16437
|
-
let parentDir =
|
|
16709
|
+
let parentDir = path21.dirname(searchDir);
|
|
16438
16710
|
while (searchDir !== parentDir) {
|
|
16439
|
-
const envPath2 =
|
|
16711
|
+
const envPath2 = path21.join(searchDir, ".env");
|
|
16440
16712
|
if (fs19.existsSync(envPath2)) {
|
|
16441
16713
|
return envPath2;
|
|
16442
16714
|
}
|
|
@@ -16444,7 +16716,7 @@ function findEnvFile() {
|
|
|
16444
16716
|
return null;
|
|
16445
16717
|
}
|
|
16446
16718
|
searchDir = parentDir;
|
|
16447
|
-
parentDir =
|
|
16719
|
+
parentDir = path21.dirname(searchDir);
|
|
16448
16720
|
}
|
|
16449
16721
|
return null;
|
|
16450
16722
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@packmind/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
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",
|