@packmind/cli 0.25.0 → 0.26.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 +1499 -1429
- package/package.json +2 -2
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.26.0",
|
|
3856
3856
|
description: "A command-line interface for Packmind linting and code quality checks",
|
|
3857
3857
|
private: false,
|
|
3858
3858
|
bin: {
|
|
@@ -4427,6 +4427,34 @@ var SpaceCreatedEvent = class extends UserEvent {
|
|
|
4427
4427
|
}
|
|
4428
4428
|
};
|
|
4429
4429
|
|
|
4430
|
+
// packages/types/src/spaces/events/SpaceMembersAddedEvent.ts
|
|
4431
|
+
var SpaceMembersAddedEvent = class extends UserEvent {
|
|
4432
|
+
static {
|
|
4433
|
+
this.eventName = "spaces.space.members-added";
|
|
4434
|
+
}
|
|
4435
|
+
};
|
|
4436
|
+
|
|
4437
|
+
// packages/types/src/spaces/events/SpaceMembersRemovedEvent.ts
|
|
4438
|
+
var SpaceMembersRemovedEvent = class extends UserEvent {
|
|
4439
|
+
static {
|
|
4440
|
+
this.eventName = "spaces.space.members-removed";
|
|
4441
|
+
}
|
|
4442
|
+
};
|
|
4443
|
+
|
|
4444
|
+
// packages/types/src/spaces/events/SpaceMembersRoleUpdatedEvent.ts
|
|
4445
|
+
var SpaceMembersRoleUpdatedEvent = class extends UserEvent {
|
|
4446
|
+
static {
|
|
4447
|
+
this.eventName = "spaces.space.members-role-updated";
|
|
4448
|
+
}
|
|
4449
|
+
};
|
|
4450
|
+
|
|
4451
|
+
// packages/types/src/spaces/events/SpaceVisibilityUpdatedEvent.ts
|
|
4452
|
+
var SpaceVisibilityUpdatedEvent = class extends UserEvent {
|
|
4453
|
+
static {
|
|
4454
|
+
this.eventName = "spaces.space.visibility-updated";
|
|
4455
|
+
}
|
|
4456
|
+
};
|
|
4457
|
+
|
|
4430
4458
|
// packages/types/src/spaces-management/events/PlaybookArtefactMovedEvent.ts
|
|
4431
4459
|
var PlaybookArtefactMovedEvent = class extends UserEvent {
|
|
4432
4460
|
static {
|
|
@@ -5335,30 +5363,30 @@ var GitService = class {
|
|
|
5335
5363
|
this.gitRunner = gitRunner;
|
|
5336
5364
|
this.logger = logger2;
|
|
5337
5365
|
}
|
|
5338
|
-
getGitRepositoryRoot(
|
|
5366
|
+
getGitRepositoryRoot(path37) {
|
|
5339
5367
|
try {
|
|
5340
5368
|
const { stdout } = this.gitRunner("rev-parse --show-toplevel", {
|
|
5341
|
-
cwd:
|
|
5369
|
+
cwd: path37
|
|
5342
5370
|
});
|
|
5343
5371
|
const gitRoot = stdout.trim();
|
|
5344
5372
|
this.logger.debug("Resolved git repository root", {
|
|
5345
|
-
inputPath:
|
|
5373
|
+
inputPath: path37,
|
|
5346
5374
|
gitRoot
|
|
5347
5375
|
});
|
|
5348
5376
|
return gitRoot;
|
|
5349
5377
|
} catch (error) {
|
|
5350
5378
|
if (error instanceof Error) {
|
|
5351
5379
|
throw new Error(
|
|
5352
|
-
`Failed to get Git repository root. The path '${
|
|
5380
|
+
`Failed to get Git repository root. The path '${path37}' does not appear to be inside a Git repository.
|
|
5353
5381
|
${error.message}`
|
|
5354
5382
|
);
|
|
5355
5383
|
}
|
|
5356
5384
|
throw new Error("Failed to get Git repository root: Unknown error");
|
|
5357
5385
|
}
|
|
5358
5386
|
}
|
|
5359
|
-
tryGetGitRepositoryRoot(
|
|
5387
|
+
tryGetGitRepositoryRoot(path37) {
|
|
5360
5388
|
try {
|
|
5361
|
-
return this.getGitRepositoryRoot(
|
|
5389
|
+
return this.getGitRepositoryRoot(path37);
|
|
5362
5390
|
} catch {
|
|
5363
5391
|
return null;
|
|
5364
5392
|
}
|
|
@@ -6623,10 +6651,10 @@ var PackmindHttpClient = class {
|
|
|
6623
6651
|
return null;
|
|
6624
6652
|
}
|
|
6625
6653
|
}
|
|
6626
|
-
async request(
|
|
6654
|
+
async request(path37, options = {}) {
|
|
6627
6655
|
const { host } = this.getAuthContext();
|
|
6628
6656
|
const { method = "GET", body } = options;
|
|
6629
|
-
const url = `${host}${
|
|
6657
|
+
const url = `${host}${path37}`;
|
|
6630
6658
|
try {
|
|
6631
6659
|
const response = await fetch(url, {
|
|
6632
6660
|
method,
|
|
@@ -6838,6 +6866,21 @@ var SpacesGateway = class {
|
|
|
6838
6866
|
);
|
|
6839
6867
|
};
|
|
6840
6868
|
}
|
|
6869
|
+
async getSpaceBySlug(slug3) {
|
|
6870
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
6871
|
+
try {
|
|
6872
|
+
return await this.httpClient.request(
|
|
6873
|
+
`/api/v0/organizations/${organizationId}/spaces/${slug3}`
|
|
6874
|
+
);
|
|
6875
|
+
} catch (error) {
|
|
6876
|
+
if (error.statusCode === 404) return null;
|
|
6877
|
+
throw error;
|
|
6878
|
+
}
|
|
6879
|
+
}
|
|
6880
|
+
getApiContext() {
|
|
6881
|
+
const { host, organizationId } = this.httpClient.getAuthContext();
|
|
6882
|
+
return { host, organizationId };
|
|
6883
|
+
}
|
|
6841
6884
|
};
|
|
6842
6885
|
|
|
6843
6886
|
// apps/cli/src/infra/repositories/SkillsGateway.ts
|
|
@@ -7026,6 +7069,21 @@ var DeploymentGateway = class {
|
|
|
7026
7069
|
`/api/v0/organizations/${organizationId}/pull?${queryParams.toString()}`
|
|
7027
7070
|
);
|
|
7028
7071
|
};
|
|
7072
|
+
this.install = async (command33) => {
|
|
7073
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7074
|
+
return this.httpClient.request(
|
|
7075
|
+
`/api/v0/organizations/${organizationId}/install`,
|
|
7076
|
+
{
|
|
7077
|
+
method: "POST",
|
|
7078
|
+
body: {
|
|
7079
|
+
packagesSlugs: command33.packagesSlugs,
|
|
7080
|
+
packmindLockFile: command33.packmindLockFile,
|
|
7081
|
+
...command33.relativePath && { relativePath: command33.relativePath },
|
|
7082
|
+
...command33.agents !== void 0 && { agents: command33.agents }
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
);
|
|
7086
|
+
};
|
|
7029
7087
|
this.getDeployed = async (command33) => {
|
|
7030
7088
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
7031
7089
|
return this.httpClient.request(
|
|
@@ -7065,6 +7123,21 @@ var DeploymentGateway = class {
|
|
|
7065
7123
|
}
|
|
7066
7124
|
);
|
|
7067
7125
|
};
|
|
7126
|
+
this.notifyArtefactsDistribution = async (command33) => {
|
|
7127
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7128
|
+
return this.httpClient.request(
|
|
7129
|
+
`/api/v0/organizations/${organizationId}/deployments/notify-artifacts-distribution`,
|
|
7130
|
+
{
|
|
7131
|
+
method: "POST",
|
|
7132
|
+
body: {
|
|
7133
|
+
gitRemoteUrl: command33.gitRemoteUrl,
|
|
7134
|
+
gitBranch: command33.gitBranch,
|
|
7135
|
+
relativePath: command33.relativePath,
|
|
7136
|
+
packmindLockFile: command33.packmindLockFile
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
);
|
|
7140
|
+
};
|
|
7068
7141
|
this.getRenderModeConfiguration = async () => {
|
|
7069
7142
|
const { organizationId } = this.httpClient.getAuthContext();
|
|
7070
7143
|
return this.httpClient.request(
|
|
@@ -7086,6 +7159,24 @@ var DeploymentGateway = class {
|
|
|
7086
7159
|
}
|
|
7087
7160
|
};
|
|
7088
7161
|
|
|
7162
|
+
// apps/cli/src/infra/repositories/OrganizationGateway.ts
|
|
7163
|
+
var OrganizationGateway = class {
|
|
7164
|
+
constructor(httpClient) {
|
|
7165
|
+
this.httpClient = httpClient;
|
|
7166
|
+
}
|
|
7167
|
+
async getOrganization() {
|
|
7168
|
+
const { organizationId } = this.httpClient.getAuthContext();
|
|
7169
|
+
const organizations = await this.httpClient.request(
|
|
7170
|
+
"/api/v0/organizations"
|
|
7171
|
+
);
|
|
7172
|
+
const org = organizations.find((o) => o.id === organizationId);
|
|
7173
|
+
if (!org) {
|
|
7174
|
+
throw new Error(`Organization ${organizationId} not found`);
|
|
7175
|
+
}
|
|
7176
|
+
return org;
|
|
7177
|
+
}
|
|
7178
|
+
};
|
|
7179
|
+
|
|
7089
7180
|
// apps/cli/src/infra/repositories/PackmindGateway.ts
|
|
7090
7181
|
var PackmindGateway = class {
|
|
7091
7182
|
constructor(apiKey) {
|
|
@@ -7100,6 +7191,7 @@ var PackmindGateway = class {
|
|
|
7100
7191
|
this.standards = new StandardsGateway(this.httpClient);
|
|
7101
7192
|
this.packages = new PackagesGateway(apiKey, this.httpClient);
|
|
7102
7193
|
this.deployment = new DeploymentGateway(this.httpClient);
|
|
7194
|
+
this.organization = new OrganizationGateway(this.httpClient);
|
|
7103
7195
|
}
|
|
7104
7196
|
};
|
|
7105
7197
|
|
|
@@ -9927,69 +10019,150 @@ ${endMarker}`;
|
|
|
9927
10019
|
}
|
|
9928
10020
|
};
|
|
9929
10021
|
|
|
9930
|
-
// apps/cli/src/application/useCases/
|
|
10022
|
+
// apps/cli/src/application/useCases/InstallUseCase.ts
|
|
9931
10023
|
var fs5 = __toESM(require("fs/promises"));
|
|
9932
10024
|
var path7 = __toESM(require("path"));
|
|
9933
|
-
|
|
9934
|
-
|
|
9935
|
-
|
|
9936
|
-
|
|
10025
|
+
|
|
10026
|
+
// apps/cli/src/application/utils/normalizePackageSlugs.ts
|
|
10027
|
+
async function normalizePackageSlugs(slugs, spaceService) {
|
|
10028
|
+
const hasUnprefixed = slugs.some((s) => !s.startsWith("@"));
|
|
10029
|
+
if (!hasUnprefixed) return slugs;
|
|
10030
|
+
const spaces = await spaceService.getSpaces();
|
|
10031
|
+
if (spaces.length > 1) {
|
|
10032
|
+
throw new Error(
|
|
10033
|
+
`Your organization has multiple spaces. Please specify the space for each package using the @space/package format (e.g. @${spaces[0].slug}/my-package).`
|
|
10034
|
+
);
|
|
10035
|
+
}
|
|
10036
|
+
const defaultSpace = await spaceService.getDefaultSpace();
|
|
10037
|
+
return slugs.map(
|
|
10038
|
+
(slug3) => slug3.startsWith("@") ? slug3 : `@${defaultSpace.slug}/${slug3}`
|
|
10039
|
+
);
|
|
10040
|
+
}
|
|
10041
|
+
|
|
10042
|
+
// apps/cli/src/application/useCases/InstallUseCase.ts
|
|
10043
|
+
var InstallUseCase = class {
|
|
10044
|
+
constructor(packmindGateway, lockFileRepository, configFileRepository, spaceService) {
|
|
10045
|
+
this.packmindGateway = packmindGateway;
|
|
10046
|
+
this.lockFileRepository = lockFileRepository;
|
|
10047
|
+
this.configFileRepository = configFileRepository;
|
|
10048
|
+
this.spaceService = spaceService;
|
|
9937
10049
|
}
|
|
9938
10050
|
async execute(command33) {
|
|
9939
10051
|
const baseDirectory = command33.baseDirectory || process.cwd();
|
|
9940
10052
|
const result = {
|
|
9941
10053
|
filesCreated: 0,
|
|
9942
10054
|
filesUpdated: 0,
|
|
10055
|
+
filesDeleted: 0,
|
|
10056
|
+
contentFilesChanged: 0,
|
|
9943
10057
|
errors: [],
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
10058
|
+
recipesCount: 0,
|
|
10059
|
+
standardsCount: 0,
|
|
10060
|
+
commandsCount: 0,
|
|
10061
|
+
skillsCount: 0,
|
|
10062
|
+
recipesRemoved: 0,
|
|
10063
|
+
standardsRemoved: 0,
|
|
10064
|
+
commandsRemoved: 0,
|
|
10065
|
+
skillsRemoved: 0,
|
|
10066
|
+
skillDirectoriesDeleted: 0,
|
|
10067
|
+
missingAccess: []
|
|
9947
10068
|
};
|
|
9948
|
-
const
|
|
9949
|
-
const
|
|
9950
|
-
const
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
10069
|
+
const hasExplicitPackages = command33.packages && command33.packages.length > 0;
|
|
10070
|
+
const lockFile = await this.lockFileRepository.read(baseDirectory);
|
|
10071
|
+
const config = await this.configFileRepository.readConfig(baseDirectory);
|
|
10072
|
+
if (!config && !hasExplicitPackages) {
|
|
10073
|
+
const configFileExists = await this.configFileRepository.configExists(baseDirectory);
|
|
10074
|
+
if (configFileExists) {
|
|
10075
|
+
throw new Error(
|
|
10076
|
+
"packmind.json exists but could not be parsed. Please fix the JSON syntax errors and try again."
|
|
10077
|
+
);
|
|
9955
10078
|
}
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
10079
|
+
throw new Error(
|
|
10080
|
+
"No packmind.json found in this directory. Run `packmind-cli install <@space/package>` first to install your packages."
|
|
10081
|
+
);
|
|
10082
|
+
}
|
|
10083
|
+
const effectiveLockFile = lockFile ?? {
|
|
10084
|
+
lockfileVersion: 1,
|
|
10085
|
+
packageSlugs: [],
|
|
10086
|
+
agents: [],
|
|
10087
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10088
|
+
artifacts: {}
|
|
10089
|
+
};
|
|
10090
|
+
let packagesSlugs;
|
|
10091
|
+
let normalizedPackages = [];
|
|
10092
|
+
if (hasExplicitPackages) {
|
|
10093
|
+
normalizedPackages = await this.normalizePackageSlugs(command33.packages);
|
|
10094
|
+
await this.validatePackageAccess(normalizedPackages);
|
|
10095
|
+
const normalizedConfigPackages = config ? await this.normalizeAndSaveConfigPackages(baseDirectory, config) : [];
|
|
10096
|
+
packagesSlugs = [
|
|
10097
|
+
.../* @__PURE__ */ new Set([...normalizedConfigPackages, ...normalizedPackages])
|
|
10098
|
+
];
|
|
10099
|
+
} else {
|
|
10100
|
+
packagesSlugs = await this.normalizeAndSaveConfigPackages(
|
|
10101
|
+
baseDirectory,
|
|
10102
|
+
config
|
|
10103
|
+
);
|
|
10104
|
+
}
|
|
10105
|
+
if (packagesSlugs.length === 0) {
|
|
10106
|
+
try {
|
|
10107
|
+
for (const entry of Object.values(effectiveLockFile.artifacts)) {
|
|
10108
|
+
for (const file of entry.files) {
|
|
10109
|
+
await this.deleteFile(baseDirectory, file.path, result);
|
|
10110
|
+
}
|
|
9966
10111
|
}
|
|
10112
|
+
await this.deleteFile(baseDirectory, "packmind-lock.json", result);
|
|
10113
|
+
} catch (error) {
|
|
10114
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10115
|
+
result.errors.push(`Failed to clean up artifacts: ${errorMsg}`);
|
|
10116
|
+
}
|
|
10117
|
+
return result;
|
|
10118
|
+
}
|
|
10119
|
+
const response = await this.packmindGateway.deployment.install({
|
|
10120
|
+
packagesSlugs,
|
|
10121
|
+
packmindLockFile: effectiveLockFile,
|
|
10122
|
+
agents: config?.agents
|
|
10123
|
+
});
|
|
10124
|
+
result.missingAccess = response.missingAccess;
|
|
10125
|
+
if (result.missingAccess.length > 0) {
|
|
10126
|
+
result.joinSpaceUrl = await this.computeJoinSpaceUrl(
|
|
10127
|
+
result.missingAccess
|
|
10128
|
+
);
|
|
10129
|
+
}
|
|
10130
|
+
const filteredCreateOrUpdate = response.fileUpdates.createOrUpdate.filter(
|
|
10131
|
+
(file) => file.path !== "packmind.json"
|
|
10132
|
+
);
|
|
10133
|
+
const uniqueFilesMap = /* @__PURE__ */ new Map();
|
|
10134
|
+
for (const file of filteredCreateOrUpdate) {
|
|
10135
|
+
uniqueFilesMap.set(file.path, file);
|
|
10136
|
+
}
|
|
10137
|
+
const uniqueFiles = Array.from(uniqueFilesMap.values());
|
|
10138
|
+
for (const file of uniqueFiles) {
|
|
10139
|
+
if (file.path.includes(".packmind/recipes/") && file.path.endsWith(".md")) {
|
|
10140
|
+
result.recipesCount++;
|
|
10141
|
+
} else if (file.path.includes(".packmind/standards/") && file.path.endsWith(".md")) {
|
|
10142
|
+
result.standardsCount++;
|
|
10143
|
+
} else if (file.path.includes(".packmind/commands/") && file.path.endsWith(".md")) {
|
|
10144
|
+
result.commandsCount++;
|
|
10145
|
+
} else if (file.path.includes(".packmind/skills/") && file.path.endsWith(".md")) {
|
|
10146
|
+
result.skillsCount++;
|
|
9967
10147
|
}
|
|
9968
10148
|
}
|
|
9969
10149
|
try {
|
|
9970
|
-
|
|
10150
|
+
result.skillDirectoriesDeleted = await this.deleteSkillFolders(
|
|
10151
|
+
baseDirectory,
|
|
10152
|
+
response.skillFolders
|
|
10153
|
+
);
|
|
10154
|
+
for (const file of uniqueFiles) {
|
|
9971
10155
|
try {
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
if (fileAlreadyInstalled) {
|
|
9982
|
-
const paths = incompatibleInstalledMap.get(skillName) ?? [];
|
|
9983
|
-
paths.push(file.path);
|
|
9984
|
-
incompatibleInstalledMap.set(skillName, paths);
|
|
9985
|
-
} else {
|
|
9986
|
-
if (!result.skippedIncompatibleSkillNames.includes(skillName)) {
|
|
9987
|
-
result.skippedIncompatibleSkillNames.push(skillName);
|
|
9988
|
-
}
|
|
9989
|
-
}
|
|
9990
|
-
continue;
|
|
10156
|
+
const changesBefore = result.filesCreated + result.filesUpdated;
|
|
10157
|
+
await this.createOrUpdateFile(
|
|
10158
|
+
baseDirectory,
|
|
10159
|
+
file,
|
|
10160
|
+
result,
|
|
10161
|
+
file.skillFilePermissions
|
|
10162
|
+
);
|
|
10163
|
+
if (result.filesCreated + result.filesUpdated > changesBefore && this.isContentFile(file.path)) {
|
|
10164
|
+
result.contentFilesChanged++;
|
|
9991
10165
|
}
|
|
9992
|
-
await this.createOrUpdateFile(baseDirectory, file, result);
|
|
9993
10166
|
} catch (error) {
|
|
9994
10167
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
9995
10168
|
result.errors.push(
|
|
@@ -9997,46 +10170,469 @@ var InstallDefaultSkillsUseCase = class {
|
|
|
9997
10170
|
);
|
|
9998
10171
|
}
|
|
9999
10172
|
}
|
|
10173
|
+
for (const file of response.fileUpdates.delete) {
|
|
10174
|
+
try {
|
|
10175
|
+
const deletedBefore = result.filesDeleted;
|
|
10176
|
+
await this.deleteFile(baseDirectory, file.path, result);
|
|
10177
|
+
if (result.filesDeleted > deletedBefore) {
|
|
10178
|
+
if (file.path.includes(".packmind/standards/") && file.path.endsWith(".md")) {
|
|
10179
|
+
result.standardsRemoved++;
|
|
10180
|
+
result.contentFilesChanged++;
|
|
10181
|
+
} else if (file.path.includes(".packmind/commands/") && file.path.endsWith(".md")) {
|
|
10182
|
+
result.commandsRemoved++;
|
|
10183
|
+
result.contentFilesChanged++;
|
|
10184
|
+
} else if (file.path.includes(".packmind/skills/") && file.path.endsWith(".md")) {
|
|
10185
|
+
result.skillsRemoved++;
|
|
10186
|
+
result.contentFilesChanged++;
|
|
10187
|
+
} else if (file.path.includes(".packmind/recipes/") && file.path.endsWith(".md")) {
|
|
10188
|
+
result.recipesRemoved++;
|
|
10189
|
+
result.contentFilesChanged++;
|
|
10190
|
+
}
|
|
10191
|
+
}
|
|
10192
|
+
} catch (error) {
|
|
10193
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10194
|
+
result.errors.push(`Failed to delete ${file.path}: ${errorMsg}`);
|
|
10195
|
+
}
|
|
10196
|
+
}
|
|
10000
10197
|
} catch (error) {
|
|
10001
10198
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10002
|
-
result.errors.push(`Failed to install
|
|
10199
|
+
result.errors.push(`Failed to install packages: ${errorMsg}`);
|
|
10200
|
+
}
|
|
10201
|
+
if (normalizedPackages.length > 0) {
|
|
10202
|
+
await this.configFileRepository.addPackagesToConfig(
|
|
10203
|
+
baseDirectory,
|
|
10204
|
+
normalizedPackages
|
|
10205
|
+
);
|
|
10003
10206
|
}
|
|
10004
|
-
result.incompatibleInstalledSkills = Array.from(
|
|
10005
|
-
incompatibleInstalledMap.entries()
|
|
10006
|
-
).map(
|
|
10007
|
-
([skillName, filePaths]) => ({
|
|
10008
|
-
skillName,
|
|
10009
|
-
filePaths
|
|
10010
|
-
})
|
|
10011
|
-
);
|
|
10012
10207
|
return result;
|
|
10013
10208
|
}
|
|
10014
|
-
async
|
|
10209
|
+
async normalizePackageSlugs(slugs) {
|
|
10210
|
+
return normalizePackageSlugs(slugs, this.spaceService);
|
|
10211
|
+
}
|
|
10212
|
+
async normalizeAndSaveConfigPackages(baseDirectory, config) {
|
|
10213
|
+
const originalSlugs = Object.keys(config.packages);
|
|
10214
|
+
if (originalSlugs.length === 0) return [];
|
|
10215
|
+
const normalizedSlugs = await this.normalizePackageSlugs(originalSlugs);
|
|
10216
|
+
const hasChanges = normalizedSlugs.some(
|
|
10217
|
+
(slug3, i) => slug3 !== originalSlugs[i]
|
|
10218
|
+
);
|
|
10219
|
+
if (hasChanges) {
|
|
10220
|
+
const normalizedPackagesMap = {};
|
|
10221
|
+
for (let i = 0; i < normalizedSlugs.length; i++) {
|
|
10222
|
+
normalizedPackagesMap[normalizedSlugs[i]] = config.packages[originalSlugs[i]];
|
|
10223
|
+
}
|
|
10224
|
+
await this.configFileRepository.updateConfig(
|
|
10225
|
+
baseDirectory,
|
|
10226
|
+
"packages",
|
|
10227
|
+
normalizedPackagesMap
|
|
10228
|
+
);
|
|
10229
|
+
}
|
|
10230
|
+
return normalizedSlugs;
|
|
10231
|
+
}
|
|
10232
|
+
async validatePackageAccess(packages) {
|
|
10233
|
+
const userSpaces = await this.spaceService.getSpaces();
|
|
10234
|
+
const userSpaceSlugs = new Set(userSpaces.map((s) => s.slug));
|
|
10235
|
+
const { host } = this.spaceService.getApiContext();
|
|
10236
|
+
const errors = [];
|
|
10237
|
+
for (const pkg of packages) {
|
|
10238
|
+
const spaceSlug = pkg.startsWith("@") ? pkg.slice(1).split("/")[0] : null;
|
|
10239
|
+
if (!spaceSlug || userSpaceSlugs.has(spaceSlug)) continue;
|
|
10240
|
+
const space = await this.spaceService.getSpaceBySlug(spaceSlug);
|
|
10241
|
+
if (!space || space.type === "private" /* private */) {
|
|
10242
|
+
errors.push(`Package ${pkg} does not exist.`);
|
|
10243
|
+
} else {
|
|
10244
|
+
const organization = await this.packmindGateway.organization.getOrganization();
|
|
10245
|
+
const joinUrl = `${host}/org/${organization.slug}/spaces/${spaceSlug}/join`;
|
|
10246
|
+
errors.push(
|
|
10247
|
+
`You don't have access to space @${spaceSlug}. It is a public space \u2014 you can join at: ${joinUrl}`
|
|
10248
|
+
);
|
|
10249
|
+
}
|
|
10250
|
+
}
|
|
10251
|
+
if (errors.length > 0) {
|
|
10252
|
+
throw new Error(errors.join("\n"));
|
|
10253
|
+
}
|
|
10254
|
+
}
|
|
10255
|
+
async computeJoinSpaceUrl(missingAccessSlugs) {
|
|
10256
|
+
const spaceSlugs = /* @__PURE__ */ new Set();
|
|
10257
|
+
for (const slug3 of missingAccessSlugs) {
|
|
10258
|
+
if (slug3.startsWith("@")) {
|
|
10259
|
+
const spaceSlug2 = slug3.slice(1).split("/")[0];
|
|
10260
|
+
spaceSlugs.add(spaceSlug2);
|
|
10261
|
+
}
|
|
10262
|
+
}
|
|
10263
|
+
if (spaceSlugs.size !== 1) return void 0;
|
|
10264
|
+
const [spaceSlug] = spaceSlugs;
|
|
10265
|
+
const space = await this.spaceService.getSpaceBySlug(spaceSlug);
|
|
10266
|
+
if (!space || space.type !== "open" /* open */) return void 0;
|
|
10267
|
+
const organization = await this.packmindGateway.organization.getOrganization();
|
|
10268
|
+
const { host } = this.spaceService.getApiContext();
|
|
10269
|
+
return `${host}/org/${organization.slug}/spaces/${spaceSlug}/join`;
|
|
10270
|
+
}
|
|
10271
|
+
async createOrUpdateFile(baseDirectory, file, result, skillFilePermissions) {
|
|
10015
10272
|
const fullPath = path7.join(baseDirectory, file.path);
|
|
10016
10273
|
const directory = path7.dirname(fullPath);
|
|
10017
10274
|
await fs5.mkdir(directory, { recursive: true });
|
|
10018
10275
|
const fileExists = await this.fileExists(fullPath);
|
|
10276
|
+
if (file.content !== void 0) {
|
|
10277
|
+
await this.handleFullContentUpdate(
|
|
10278
|
+
fullPath,
|
|
10279
|
+
file.content,
|
|
10280
|
+
fileExists,
|
|
10281
|
+
result,
|
|
10282
|
+
file.isBase64
|
|
10283
|
+
);
|
|
10284
|
+
} else if (file.sections !== void 0) {
|
|
10285
|
+
await this.handleSectionsUpdate(
|
|
10286
|
+
fullPath,
|
|
10287
|
+
file.sections,
|
|
10288
|
+
fileExists,
|
|
10289
|
+
result,
|
|
10290
|
+
baseDirectory
|
|
10291
|
+
);
|
|
10292
|
+
}
|
|
10293
|
+
if (skillFilePermissions && supportsUnixPermissions()) {
|
|
10294
|
+
await fs5.chmod(fullPath, parsePermissionString(skillFilePermissions));
|
|
10295
|
+
}
|
|
10296
|
+
}
|
|
10297
|
+
async handleFullContentUpdate(fullPath, content, fileExists, result, isBase64) {
|
|
10298
|
+
if (isBase64) {
|
|
10299
|
+
const buffer = Buffer.from(content, "base64");
|
|
10300
|
+
await fs5.writeFile(fullPath, buffer);
|
|
10301
|
+
if (fileExists) {
|
|
10302
|
+
result.filesUpdated++;
|
|
10303
|
+
} else {
|
|
10304
|
+
result.filesCreated++;
|
|
10305
|
+
}
|
|
10306
|
+
return;
|
|
10307
|
+
}
|
|
10019
10308
|
if (fileExists) {
|
|
10020
10309
|
const existingContent = await fs5.readFile(fullPath, "utf-8");
|
|
10021
|
-
|
|
10022
|
-
|
|
10310
|
+
const commentMarker = this.extractCommentMarker(content);
|
|
10311
|
+
let finalContent;
|
|
10312
|
+
if (!commentMarker) {
|
|
10313
|
+
finalContent = content;
|
|
10314
|
+
} else {
|
|
10315
|
+
finalContent = this.mergeContentWithMarkers(
|
|
10316
|
+
existingContent,
|
|
10317
|
+
content,
|
|
10318
|
+
commentMarker
|
|
10319
|
+
);
|
|
10320
|
+
}
|
|
10321
|
+
if (existingContent !== finalContent) {
|
|
10322
|
+
await fs5.writeFile(fullPath, finalContent, "utf-8");
|
|
10023
10323
|
result.filesUpdated++;
|
|
10024
10324
|
}
|
|
10025
10325
|
} else {
|
|
10026
|
-
await fs5.writeFile(fullPath,
|
|
10326
|
+
await fs5.writeFile(fullPath, content, "utf-8");
|
|
10027
10327
|
result.filesCreated++;
|
|
10028
10328
|
}
|
|
10029
10329
|
}
|
|
10030
|
-
async fileExists
|
|
10031
|
-
|
|
10032
|
-
|
|
10033
|
-
|
|
10034
|
-
} catch {
|
|
10035
|
-
return false;
|
|
10330
|
+
async handleSectionsUpdate(fullPath, sections, fileExists, result, baseDirectory) {
|
|
10331
|
+
let currentContent = "";
|
|
10332
|
+
if (fileExists) {
|
|
10333
|
+
currentContent = await fs5.readFile(fullPath, "utf-8");
|
|
10036
10334
|
}
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10335
|
+
const mergedContent = mergeSectionsIntoFileContent(
|
|
10336
|
+
currentContent,
|
|
10337
|
+
sections
|
|
10338
|
+
);
|
|
10339
|
+
if (currentContent !== mergedContent) {
|
|
10340
|
+
if (this.isEffectivelyEmpty(mergedContent) && fileExists) {
|
|
10341
|
+
await fs5.unlink(fullPath);
|
|
10342
|
+
result.filesDeleted++;
|
|
10343
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
10344
|
+
} else {
|
|
10345
|
+
await fs5.writeFile(fullPath, mergedContent, "utf-8");
|
|
10346
|
+
if (fileExists) {
|
|
10347
|
+
result.filesUpdated++;
|
|
10348
|
+
} else {
|
|
10349
|
+
result.filesCreated++;
|
|
10350
|
+
}
|
|
10351
|
+
}
|
|
10352
|
+
}
|
|
10353
|
+
}
|
|
10354
|
+
async deleteFile(baseDirectory, filePath, result) {
|
|
10355
|
+
const fullPath = path7.join(baseDirectory, filePath);
|
|
10356
|
+
const stat9 = await fs5.stat(fullPath).catch(() => null);
|
|
10357
|
+
if (stat9?.isDirectory()) {
|
|
10358
|
+
await fs5.rm(fullPath, { recursive: true, force: true });
|
|
10359
|
+
result.filesDeleted++;
|
|
10360
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
10361
|
+
} else if (stat9?.isFile()) {
|
|
10362
|
+
await fs5.unlink(fullPath);
|
|
10363
|
+
result.filesDeleted++;
|
|
10364
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
10365
|
+
}
|
|
10366
|
+
}
|
|
10367
|
+
isContentFile(filePath) {
|
|
10368
|
+
return (filePath.includes(".packmind/standards/") || filePath.includes(".packmind/commands/") || filePath.includes(".packmind/skills/") || filePath.includes(".packmind/recipes/")) && filePath.endsWith(".md");
|
|
10369
|
+
}
|
|
10370
|
+
async fileExists(filePath) {
|
|
10371
|
+
try {
|
|
10372
|
+
await fs5.access(filePath);
|
|
10373
|
+
return true;
|
|
10374
|
+
} catch {
|
|
10375
|
+
return false;
|
|
10376
|
+
}
|
|
10377
|
+
}
|
|
10378
|
+
extractCommentMarker(content) {
|
|
10379
|
+
const startMarkerPattern = /<!--\s*start:\s*([^-]+?)\s*-->/;
|
|
10380
|
+
const match = content.match(startMarkerPattern);
|
|
10381
|
+
return match ? match[1].trim() : null;
|
|
10382
|
+
}
|
|
10383
|
+
mergeContentWithMarkers(existingContent, newContent, commentMarker) {
|
|
10384
|
+
const startMarker = `<!-- start: ${commentMarker} -->`;
|
|
10385
|
+
const endMarker = `<!-- end: ${commentMarker} -->`;
|
|
10386
|
+
const newSectionPattern = new RegExp(
|
|
10387
|
+
`${this.escapeRegex(startMarker)}([\\s\\S]*?)${this.escapeRegex(endMarker)}`
|
|
10388
|
+
);
|
|
10389
|
+
const newSectionMatch = newContent.match(newSectionPattern);
|
|
10390
|
+
const newSectionContent = newSectionMatch ? newSectionMatch[1].trim() : newContent;
|
|
10391
|
+
const existingSectionPattern = new RegExp(
|
|
10392
|
+
`${this.escapeRegex(startMarker)}[\\s\\S]*?${this.escapeRegex(endMarker)}`,
|
|
10393
|
+
"g"
|
|
10394
|
+
);
|
|
10395
|
+
if (existingSectionPattern.test(existingContent)) {
|
|
10396
|
+
return existingContent.replace(
|
|
10397
|
+
existingSectionPattern,
|
|
10398
|
+
`${startMarker}
|
|
10399
|
+
${newSectionContent}
|
|
10400
|
+
${endMarker}`
|
|
10401
|
+
);
|
|
10402
|
+
} else {
|
|
10403
|
+
return `${existingContent}
|
|
10404
|
+
${startMarker}
|
|
10405
|
+
${newSectionContent}
|
|
10406
|
+
${endMarker}`;
|
|
10407
|
+
}
|
|
10408
|
+
}
|
|
10409
|
+
isEffectivelyEmpty(content) {
|
|
10410
|
+
const withoutEmptySections = content.replace(
|
|
10411
|
+
/<!--\s*start:\s*[^-]+?\s*-->\s*<!--\s*end:\s*[^-]+?\s*-->/g,
|
|
10412
|
+
""
|
|
10413
|
+
);
|
|
10414
|
+
return withoutEmptySections.trim() === "";
|
|
10415
|
+
}
|
|
10416
|
+
escapeRegex(str) {
|
|
10417
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
10418
|
+
}
|
|
10419
|
+
async deleteSkillFolders(baseDirectory, folders) {
|
|
10420
|
+
let deletedFilesCount = 0;
|
|
10421
|
+
for (const folder of folders) {
|
|
10422
|
+
const fullPath = path7.join(baseDirectory, folder);
|
|
10423
|
+
try {
|
|
10424
|
+
await fs5.access(fullPath);
|
|
10425
|
+
const fileCount = await this.countFilesInDirectory(fullPath);
|
|
10426
|
+
await fs5.rm(fullPath, { recursive: true, force: true });
|
|
10427
|
+
deletedFilesCount += fileCount;
|
|
10428
|
+
await this.removeEmptyParentDirectories(fullPath, baseDirectory);
|
|
10429
|
+
} catch {
|
|
10430
|
+
}
|
|
10431
|
+
}
|
|
10432
|
+
return deletedFilesCount;
|
|
10433
|
+
}
|
|
10434
|
+
async countFilesInDirectory(dirPath) {
|
|
10435
|
+
let count = 0;
|
|
10436
|
+
const entries = await fs5.readdir(dirPath, { withFileTypes: true });
|
|
10437
|
+
for (const entry of entries) {
|
|
10438
|
+
const entryPath = path7.join(dirPath, entry.name);
|
|
10439
|
+
if (entry.isDirectory()) {
|
|
10440
|
+
count += await this.countFilesInDirectory(entryPath);
|
|
10441
|
+
} else {
|
|
10442
|
+
count++;
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
return count;
|
|
10446
|
+
}
|
|
10447
|
+
async isDirectoryEmpty(dirPath) {
|
|
10448
|
+
try {
|
|
10449
|
+
const entries = await fs5.readdir(dirPath);
|
|
10450
|
+
return entries.length === 0;
|
|
10451
|
+
} catch {
|
|
10452
|
+
return false;
|
|
10453
|
+
}
|
|
10454
|
+
}
|
|
10455
|
+
async removeEmptyParentDirectories(fullPath, baseDirectory) {
|
|
10456
|
+
const normalizedBase = path7.resolve(baseDirectory);
|
|
10457
|
+
let currentDir = path7.dirname(path7.resolve(fullPath));
|
|
10458
|
+
while (currentDir.startsWith(normalizedBase + path7.sep) && currentDir !== normalizedBase) {
|
|
10459
|
+
const isEmpty = await this.isDirectoryEmpty(currentDir);
|
|
10460
|
+
if (!isEmpty) break;
|
|
10461
|
+
try {
|
|
10462
|
+
await fs5.rmdir(currentDir);
|
|
10463
|
+
} catch {
|
|
10464
|
+
break;
|
|
10465
|
+
}
|
|
10466
|
+
currentDir = path7.dirname(currentDir);
|
|
10467
|
+
}
|
|
10468
|
+
}
|
|
10469
|
+
};
|
|
10470
|
+
|
|
10471
|
+
// apps/cli/src/application/useCases/UninstallUseCase.ts
|
|
10472
|
+
var UninstallUseCase = class {
|
|
10473
|
+
constructor(configFileRepository, spaceService, installUseCase) {
|
|
10474
|
+
this.configFileRepository = configFileRepository;
|
|
10475
|
+
this.spaceService = spaceService;
|
|
10476
|
+
this.installUseCase = installUseCase;
|
|
10477
|
+
}
|
|
10478
|
+
async execute(command33) {
|
|
10479
|
+
const baseDirectory = command33.baseDirectory || process.cwd();
|
|
10480
|
+
const config = await this.configFileRepository.readConfig(baseDirectory);
|
|
10481
|
+
if (!config) {
|
|
10482
|
+
const configFileExists = await this.configFileRepository.configExists(baseDirectory);
|
|
10483
|
+
if (configFileExists) {
|
|
10484
|
+
throw new Error(
|
|
10485
|
+
"packmind.json exists but could not be parsed. Please fix the JSON syntax errors and try again."
|
|
10486
|
+
);
|
|
10487
|
+
}
|
|
10488
|
+
throw new Error(
|
|
10489
|
+
"No packmind.json found in this directory. Run `packmind-cli install <@space/package>` first to install your packages."
|
|
10490
|
+
);
|
|
10491
|
+
}
|
|
10492
|
+
const normalized = await normalizePackageSlugs(
|
|
10493
|
+
command33.packages,
|
|
10494
|
+
this.spaceService
|
|
10495
|
+
);
|
|
10496
|
+
const notInstalled = normalized.filter((pkg) => !(pkg in config.packages));
|
|
10497
|
+
if (notInstalled.length > 0) {
|
|
10498
|
+
const pkgList = notInstalled.map((p) => ` - ${p}`).join("\n");
|
|
10499
|
+
throw new Error(
|
|
10500
|
+
`The following package${notInstalled.length > 1 ? "s are" : " is"} not installed:
|
|
10501
|
+
${pkgList}`
|
|
10502
|
+
);
|
|
10503
|
+
}
|
|
10504
|
+
const updatedPackages = { ...config.packages };
|
|
10505
|
+
for (const pkg of normalized) {
|
|
10506
|
+
delete updatedPackages[pkg];
|
|
10507
|
+
}
|
|
10508
|
+
await this.configFileRepository.updateConfig(
|
|
10509
|
+
baseDirectory,
|
|
10510
|
+
"packages",
|
|
10511
|
+
updatedPackages
|
|
10512
|
+
);
|
|
10513
|
+
try {
|
|
10514
|
+
return await this.installUseCase.execute({ baseDirectory });
|
|
10515
|
+
} catch (error) {
|
|
10516
|
+
await this.configFileRepository.updateConfig(
|
|
10517
|
+
baseDirectory,
|
|
10518
|
+
"packages",
|
|
10519
|
+
config.packages
|
|
10520
|
+
);
|
|
10521
|
+
throw error;
|
|
10522
|
+
}
|
|
10523
|
+
}
|
|
10524
|
+
};
|
|
10525
|
+
|
|
10526
|
+
// apps/cli/src/application/useCases/InstallDefaultSkillsUseCase.ts
|
|
10527
|
+
var fs6 = __toESM(require("fs/promises"));
|
|
10528
|
+
var path8 = __toESM(require("path"));
|
|
10529
|
+
var import_semver = __toESM(require("semver"));
|
|
10530
|
+
var InstallDefaultSkillsUseCase = class {
|
|
10531
|
+
constructor(repositories) {
|
|
10532
|
+
this.repositories = repositories;
|
|
10533
|
+
}
|
|
10534
|
+
async execute(command33) {
|
|
10535
|
+
const baseDirectory = command33.baseDirectory || process.cwd();
|
|
10536
|
+
const result = {
|
|
10537
|
+
filesCreated: 0,
|
|
10538
|
+
filesUpdated: 0,
|
|
10539
|
+
errors: [],
|
|
10540
|
+
skippedSkillsCount: 0,
|
|
10541
|
+
skippedIncompatibleSkillNames: [],
|
|
10542
|
+
incompatibleInstalledSkills: []
|
|
10543
|
+
};
|
|
10544
|
+
const config = await this.repositories.configFileRepository.readConfig(baseDirectory);
|
|
10545
|
+
const agents = config?.agents;
|
|
10546
|
+
const response = await this.repositories.packmindGateway.skills.getDefaults(
|
|
10547
|
+
{
|
|
10548
|
+
cliVersion: command33.cliVersion,
|
|
10549
|
+
includeBeta: command33.includeBeta,
|
|
10550
|
+
agents
|
|
10551
|
+
}
|
|
10552
|
+
);
|
|
10553
|
+
result.skippedSkillsCount = response.skippedSkillsCount;
|
|
10554
|
+
const incompatibleInstalledMap = /* @__PURE__ */ new Map();
|
|
10555
|
+
const incompatibleSkillDirs = /* @__PURE__ */ new Map();
|
|
10556
|
+
if (command33.cliVersion) {
|
|
10557
|
+
for (const file of response.fileUpdates.createOrUpdate) {
|
|
10558
|
+
if (path8.basename(file.path) === "SKILL.md" && file.content && this.isVersionConstraintViolated(file.content, command33.cliVersion)) {
|
|
10559
|
+
const dir = path8.dirname(file.path);
|
|
10560
|
+
const skillName = this.getSkillName(file.content) ?? path8.basename(dir);
|
|
10561
|
+
incompatibleSkillDirs.set(dir, skillName);
|
|
10562
|
+
}
|
|
10563
|
+
}
|
|
10564
|
+
}
|
|
10565
|
+
try {
|
|
10566
|
+
for (const file of response.fileUpdates.createOrUpdate) {
|
|
10567
|
+
try {
|
|
10568
|
+
if (!file.content) continue;
|
|
10569
|
+
const isIncompatible = command33.cliVersion && (this.isVersionConstraintViolated(
|
|
10570
|
+
file.content,
|
|
10571
|
+
command33.cliVersion
|
|
10572
|
+
) || incompatibleSkillDirs.has(path8.dirname(file.path)));
|
|
10573
|
+
if (isIncompatible) {
|
|
10574
|
+
const skillName = this.getSkillName(file.content) ?? incompatibleSkillDirs.get(path8.dirname(file.path)) ?? path8.basename(file.path);
|
|
10575
|
+
const fullPath = path8.join(baseDirectory, file.path);
|
|
10576
|
+
const fileAlreadyInstalled = await this.fileExists(fullPath);
|
|
10577
|
+
if (fileAlreadyInstalled) {
|
|
10578
|
+
const paths = incompatibleInstalledMap.get(skillName) ?? [];
|
|
10579
|
+
paths.push(file.path);
|
|
10580
|
+
incompatibleInstalledMap.set(skillName, paths);
|
|
10581
|
+
} else {
|
|
10582
|
+
if (!result.skippedIncompatibleSkillNames.includes(skillName)) {
|
|
10583
|
+
result.skippedIncompatibleSkillNames.push(skillName);
|
|
10584
|
+
}
|
|
10585
|
+
}
|
|
10586
|
+
continue;
|
|
10587
|
+
}
|
|
10588
|
+
await this.createOrUpdateFile(baseDirectory, file, result);
|
|
10589
|
+
} catch (error) {
|
|
10590
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10591
|
+
result.errors.push(
|
|
10592
|
+
`Failed to create/update ${file.path}: ${errorMsg}`
|
|
10593
|
+
);
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
} catch (error) {
|
|
10597
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
10598
|
+
result.errors.push(`Failed to install default skills: ${errorMsg}`);
|
|
10599
|
+
}
|
|
10600
|
+
result.incompatibleInstalledSkills = Array.from(
|
|
10601
|
+
incompatibleInstalledMap.entries()
|
|
10602
|
+
).map(
|
|
10603
|
+
([skillName, filePaths]) => ({
|
|
10604
|
+
skillName,
|
|
10605
|
+
filePaths
|
|
10606
|
+
})
|
|
10607
|
+
);
|
|
10608
|
+
return result;
|
|
10609
|
+
}
|
|
10610
|
+
async createOrUpdateFile(baseDirectory, file, result) {
|
|
10611
|
+
const fullPath = path8.join(baseDirectory, file.path);
|
|
10612
|
+
const directory = path8.dirname(fullPath);
|
|
10613
|
+
await fs6.mkdir(directory, { recursive: true });
|
|
10614
|
+
const fileExists = await this.fileExists(fullPath);
|
|
10615
|
+
if (fileExists) {
|
|
10616
|
+
const existingContent = await fs6.readFile(fullPath, "utf-8");
|
|
10617
|
+
if (existingContent !== file.content) {
|
|
10618
|
+
await fs6.writeFile(fullPath, file.content, "utf-8");
|
|
10619
|
+
result.filesUpdated++;
|
|
10620
|
+
}
|
|
10621
|
+
} else {
|
|
10622
|
+
await fs6.writeFile(fullPath, file.content, "utf-8");
|
|
10623
|
+
result.filesCreated++;
|
|
10624
|
+
}
|
|
10625
|
+
}
|
|
10626
|
+
async fileExists(filePath) {
|
|
10627
|
+
try {
|
|
10628
|
+
await fs6.access(filePath);
|
|
10629
|
+
return true;
|
|
10630
|
+
} catch {
|
|
10631
|
+
return false;
|
|
10632
|
+
}
|
|
10633
|
+
}
|
|
10634
|
+
/**
|
|
10635
|
+
* Returns true if the skill's `metadata.packmind-cli-version` constraint
|
|
10040
10636
|
* is present AND the given CLI version does NOT satisfy it (i.e. the skill
|
|
10041
10637
|
* is meant for an older CLI version than the one running).
|
|
10042
10638
|
*/
|
|
@@ -10148,13 +10744,13 @@ var EnvCredentialsProvider = class {
|
|
|
10148
10744
|
};
|
|
10149
10745
|
|
|
10150
10746
|
// apps/cli/src/infra/utils/credentials/FileCredentialsProvider.ts
|
|
10151
|
-
var
|
|
10152
|
-
var
|
|
10747
|
+
var fs7 = __toESM(require("fs"));
|
|
10748
|
+
var path9 = __toESM(require("path"));
|
|
10153
10749
|
var os2 = __toESM(require("os"));
|
|
10154
10750
|
var CREDENTIALS_DIR = ".packmind";
|
|
10155
10751
|
var CREDENTIALS_FILE = "credentials.json";
|
|
10156
10752
|
function getCredentialsPath() {
|
|
10157
|
-
return
|
|
10753
|
+
return path9.join(os2.homedir(), CREDENTIALS_DIR, CREDENTIALS_FILE);
|
|
10158
10754
|
}
|
|
10159
10755
|
var FileCredentialsProvider = class {
|
|
10160
10756
|
getSourceName() {
|
|
@@ -10162,11 +10758,11 @@ var FileCredentialsProvider = class {
|
|
|
10162
10758
|
}
|
|
10163
10759
|
hasCredentials() {
|
|
10164
10760
|
const credentialsPath = getCredentialsPath();
|
|
10165
|
-
if (!
|
|
10761
|
+
if (!fs7.existsSync(credentialsPath)) {
|
|
10166
10762
|
return false;
|
|
10167
10763
|
}
|
|
10168
10764
|
try {
|
|
10169
|
-
const content =
|
|
10765
|
+
const content = fs7.readFileSync(credentialsPath, "utf-8");
|
|
10170
10766
|
const credentials = JSON.parse(content);
|
|
10171
10767
|
return !!credentials.apiKey;
|
|
10172
10768
|
} catch {
|
|
@@ -10175,11 +10771,11 @@ var FileCredentialsProvider = class {
|
|
|
10175
10771
|
}
|
|
10176
10772
|
loadCredentials() {
|
|
10177
10773
|
const credentialsPath = getCredentialsPath();
|
|
10178
|
-
if (!
|
|
10774
|
+
if (!fs7.existsSync(credentialsPath)) {
|
|
10179
10775
|
return null;
|
|
10180
10776
|
}
|
|
10181
10777
|
try {
|
|
10182
|
-
const content =
|
|
10778
|
+
const content = fs7.readFileSync(credentialsPath, "utf-8");
|
|
10183
10779
|
const credentials = JSON.parse(content);
|
|
10184
10780
|
if (!credentials.apiKey) {
|
|
10185
10781
|
return null;
|
|
@@ -10202,13 +10798,13 @@ var FileCredentialsProvider = class {
|
|
|
10202
10798
|
}
|
|
10203
10799
|
};
|
|
10204
10800
|
function saveCredentials(apiKey) {
|
|
10205
|
-
const credentialsDir =
|
|
10206
|
-
if (!
|
|
10207
|
-
|
|
10801
|
+
const credentialsDir = path9.join(os2.homedir(), CREDENTIALS_DIR);
|
|
10802
|
+
if (!fs7.existsSync(credentialsDir)) {
|
|
10803
|
+
fs7.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
|
|
10208
10804
|
}
|
|
10209
10805
|
const credentialsPath = getCredentialsPath();
|
|
10210
10806
|
const credentials = { apiKey };
|
|
10211
|
-
|
|
10807
|
+
fs7.writeFileSync(credentialsPath, JSON.stringify(credentials, null, 2), {
|
|
10212
10808
|
mode: 384
|
|
10213
10809
|
});
|
|
10214
10810
|
}
|
|
@@ -10279,10 +10875,10 @@ async function defaultPromptForCode() {
|
|
|
10279
10875
|
input: process.stdin,
|
|
10280
10876
|
output: process.stdout
|
|
10281
10877
|
});
|
|
10282
|
-
return new Promise((
|
|
10878
|
+
return new Promise((resolve15) => {
|
|
10283
10879
|
rl.question("Enter the login code from the browser: ", (answer) => {
|
|
10284
10880
|
rl.close();
|
|
10285
|
-
|
|
10881
|
+
resolve15(answer.trim());
|
|
10286
10882
|
});
|
|
10287
10883
|
});
|
|
10288
10884
|
}
|
|
@@ -10316,7 +10912,7 @@ async function defaultExchangeCodeForApiKey(code, host) {
|
|
|
10316
10912
|
return await response.json();
|
|
10317
10913
|
}
|
|
10318
10914
|
function defaultStartCallbackServer() {
|
|
10319
|
-
return new Promise((
|
|
10915
|
+
return new Promise((resolve15, reject) => {
|
|
10320
10916
|
let timeoutId = null;
|
|
10321
10917
|
const server = http.createServer((req, res) => {
|
|
10322
10918
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -10329,7 +10925,7 @@ function defaultStartCallbackServer() {
|
|
|
10329
10925
|
if (timeoutId) {
|
|
10330
10926
|
clearTimeout(timeoutId);
|
|
10331
10927
|
}
|
|
10332
|
-
|
|
10928
|
+
resolve15(code);
|
|
10333
10929
|
setImmediate(() => {
|
|
10334
10930
|
server.close();
|
|
10335
10931
|
});
|
|
@@ -10400,14 +10996,14 @@ var LoginUseCase = class {
|
|
|
10400
10996
|
};
|
|
10401
10997
|
|
|
10402
10998
|
// apps/cli/src/application/useCases/LogoutUseCase.ts
|
|
10403
|
-
var
|
|
10999
|
+
var fs8 = __toESM(require("fs"));
|
|
10404
11000
|
var ENV_VAR_NAME2 = "PACKMIND_API_KEY_V3";
|
|
10405
11001
|
var LogoutUseCase = class {
|
|
10406
11002
|
constructor(deps) {
|
|
10407
11003
|
this.deps = {
|
|
10408
11004
|
getCredentialsPath: deps?.getCredentialsPath ?? getCredentialsPath,
|
|
10409
|
-
fileExists: deps?.fileExists ?? ((
|
|
10410
|
-
deleteFile: deps?.deleteFile ?? ((
|
|
11005
|
+
fileExists: deps?.fileExists ?? ((path37) => fs8.existsSync(path37)),
|
|
11006
|
+
deleteFile: deps?.deleteFile ?? ((path37) => fs8.unlinkSync(path37)),
|
|
10411
11007
|
hasEnvVar: deps?.hasEnvVar ?? (() => !!process.env[ENV_VAR_NAME2])
|
|
10412
11008
|
};
|
|
10413
11009
|
}
|
|
@@ -10756,8 +11352,8 @@ var SetupMcpUseCase = class {
|
|
|
10756
11352
|
};
|
|
10757
11353
|
|
|
10758
11354
|
// apps/cli/src/application/services/McpConfigService.ts
|
|
10759
|
-
var
|
|
10760
|
-
var
|
|
11355
|
+
var fs9 = __toESM(require("fs"));
|
|
11356
|
+
var path11 = __toESM(require("path"));
|
|
10761
11357
|
var os3 = __toESM(require("os"));
|
|
10762
11358
|
var import_child_process3 = require("child_process");
|
|
10763
11359
|
var McpConfigService = class {
|
|
@@ -10804,11 +11400,11 @@ var McpConfigService = class {
|
|
|
10804
11400
|
}
|
|
10805
11401
|
installCursorMcp(config) {
|
|
10806
11402
|
try {
|
|
10807
|
-
const cursorConfigPath =
|
|
11403
|
+
const cursorConfigPath = path11.join(os3.homedir(), ".cursor", "mcp.json");
|
|
10808
11404
|
const cursorConfig = this.buildCursorConfig(config);
|
|
10809
11405
|
const existingConfig = this.readExistingJsonConfig(cursorConfigPath);
|
|
10810
11406
|
const mergedConfig = this.mergeConfig(existingConfig, cursorConfig);
|
|
10811
|
-
|
|
11407
|
+
fs9.writeFileSync(cursorConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
10812
11408
|
return { success: true };
|
|
10813
11409
|
} catch (error) {
|
|
10814
11410
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10817,15 +11413,15 @@ var McpConfigService = class {
|
|
|
10817
11413
|
}
|
|
10818
11414
|
installVSCodeMcp(config) {
|
|
10819
11415
|
try {
|
|
10820
|
-
const vscodeDir =
|
|
10821
|
-
if (!
|
|
10822
|
-
|
|
11416
|
+
const vscodeDir = path11.join(this.projectDir, ".vscode");
|
|
11417
|
+
if (!fs9.existsSync(vscodeDir)) {
|
|
11418
|
+
fs9.mkdirSync(vscodeDir, { recursive: true });
|
|
10823
11419
|
}
|
|
10824
|
-
const vscodeConfigPath =
|
|
11420
|
+
const vscodeConfigPath = path11.join(vscodeDir, "mcp.json");
|
|
10825
11421
|
const vscodeConfig = this.buildVSCodeConfig(config);
|
|
10826
11422
|
const existingConfig = this.readExistingJsonConfig(vscodeConfigPath);
|
|
10827
11423
|
const mergedConfig = this.mergeVSCodeConfig(existingConfig, vscodeConfig);
|
|
10828
|
-
|
|
11424
|
+
fs9.writeFileSync(vscodeConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
10829
11425
|
return { success: true };
|
|
10830
11426
|
} catch (error) {
|
|
10831
11427
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10834,14 +11430,14 @@ var McpConfigService = class {
|
|
|
10834
11430
|
}
|
|
10835
11431
|
installContinueMcp(config) {
|
|
10836
11432
|
try {
|
|
10837
|
-
const continueDir =
|
|
10838
|
-
const mcpServersDir =
|
|
10839
|
-
if (!
|
|
10840
|
-
|
|
11433
|
+
const continueDir = path11.join(this.projectDir, ".continue");
|
|
11434
|
+
const mcpServersDir = path11.join(continueDir, "mcpServers");
|
|
11435
|
+
if (!fs9.existsSync(mcpServersDir)) {
|
|
11436
|
+
fs9.mkdirSync(mcpServersDir, { recursive: true });
|
|
10841
11437
|
}
|
|
10842
|
-
const continueConfigPath =
|
|
11438
|
+
const continueConfigPath = path11.join(mcpServersDir, "packmind.yaml");
|
|
10843
11439
|
const continueConfig = this.buildContinueYamlConfig(config);
|
|
10844
|
-
|
|
11440
|
+
fs9.writeFileSync(continueConfigPath, continueConfig);
|
|
10845
11441
|
return { success: true };
|
|
10846
11442
|
} catch (error) {
|
|
10847
11443
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -10889,8 +11485,8 @@ mcpServers:
|
|
|
10889
11485
|
}
|
|
10890
11486
|
readExistingJsonConfig(filePath) {
|
|
10891
11487
|
try {
|
|
10892
|
-
if (
|
|
10893
|
-
const content =
|
|
11488
|
+
if (fs9.existsSync(filePath)) {
|
|
11489
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
10894
11490
|
return JSON.parse(content);
|
|
10895
11491
|
}
|
|
10896
11492
|
} catch {
|
|
@@ -10923,8 +11519,8 @@ mcpServers:
|
|
|
10923
11519
|
};
|
|
10924
11520
|
|
|
10925
11521
|
// apps/cli/src/infra/repositories/ConfigFileRepository.ts
|
|
10926
|
-
var
|
|
10927
|
-
var
|
|
11522
|
+
var fs10 = __toESM(require("fs/promises"));
|
|
11523
|
+
var path12 = __toESM(require("path"));
|
|
10928
11524
|
var ConfigFileRepository = class {
|
|
10929
11525
|
constructor() {
|
|
10930
11526
|
this.CONFIG_FILENAME = "packmind.json";
|
|
@@ -10945,7 +11541,7 @@ var ConfigFileRepository = class {
|
|
|
10945
11541
|
async configExists(baseDirectory) {
|
|
10946
11542
|
const configPath = this.getConfigPath(baseDirectory);
|
|
10947
11543
|
try {
|
|
10948
|
-
await
|
|
11544
|
+
await fs10.access(configPath);
|
|
10949
11545
|
return true;
|
|
10950
11546
|
} catch {
|
|
10951
11547
|
return false;
|
|
@@ -10954,7 +11550,7 @@ var ConfigFileRepository = class {
|
|
|
10954
11550
|
async readConfig(baseDirectory) {
|
|
10955
11551
|
const configPath = this.getConfigPath(baseDirectory);
|
|
10956
11552
|
try {
|
|
10957
|
-
const configContent = await
|
|
11553
|
+
const configContent = await fs10.readFile(configPath, "utf-8");
|
|
10958
11554
|
const rawConfig = JSON.parse(configContent);
|
|
10959
11555
|
if (!rawConfig.packages || typeof rawConfig.packages !== "object") {
|
|
10960
11556
|
throw new Error(
|
|
@@ -10988,18 +11584,18 @@ var ConfigFileRepository = class {
|
|
|
10988
11584
|
}
|
|
10989
11585
|
}
|
|
10990
11586
|
getConfigPath(directory) {
|
|
10991
|
-
return
|
|
11587
|
+
return path12.join(directory, this.CONFIG_FILENAME);
|
|
10992
11588
|
}
|
|
10993
11589
|
async writeConfigToPath(configPath, config) {
|
|
10994
11590
|
const configContent = JSON.stringify(config, null, 2) + "\n";
|
|
10995
|
-
await
|
|
11591
|
+
await fs10.writeFile(configPath, configContent, "utf-8");
|
|
10996
11592
|
}
|
|
10997
11593
|
/**
|
|
10998
11594
|
* Recursively finds all directories containing packmind.json in descendant folders.
|
|
10999
11595
|
* Excludes common build/dependency directories (node_modules, .git, dist, etc.)
|
|
11000
11596
|
*/
|
|
11001
11597
|
async findDescendantConfigs(directory) {
|
|
11002
|
-
const normalizedDir = normalizePath2(
|
|
11598
|
+
const normalizedDir = normalizePath2(path12.resolve(directory));
|
|
11003
11599
|
return this.searchDescendantsRecursively(normalizedDir);
|
|
11004
11600
|
}
|
|
11005
11601
|
async searchDescendantsRecursively(currentDir) {
|
|
@@ -11012,7 +11608,7 @@ var ConfigFileRepository = class {
|
|
|
11012
11608
|
if (!entry.isDirectory() || this.isExcludedDirectory(entry.name)) {
|
|
11013
11609
|
continue;
|
|
11014
11610
|
}
|
|
11015
|
-
const entryPath = normalizePath2(
|
|
11611
|
+
const entryPath = normalizePath2(path12.join(currentDir, entry.name));
|
|
11016
11612
|
const config = await this.readConfig(entryPath);
|
|
11017
11613
|
if (config) {
|
|
11018
11614
|
results.push(entryPath);
|
|
@@ -11024,7 +11620,7 @@ var ConfigFileRepository = class {
|
|
|
11024
11620
|
}
|
|
11025
11621
|
async tryReadDirectory(directory) {
|
|
11026
11622
|
try {
|
|
11027
|
-
return await
|
|
11623
|
+
return await fs10.readdir(directory, { withFileTypes: true });
|
|
11028
11624
|
} catch {
|
|
11029
11625
|
return null;
|
|
11030
11626
|
}
|
|
@@ -11043,21 +11639,21 @@ var ConfigFileRepository = class {
|
|
|
11043
11639
|
async readHierarchicalConfig(startDirectory, stopDirectory) {
|
|
11044
11640
|
const configs = [];
|
|
11045
11641
|
const configPaths = [];
|
|
11046
|
-
const normalizedStart = normalizePath2(
|
|
11047
|
-
const normalizedStop = stopDirectory ? normalizePath2(
|
|
11642
|
+
const normalizedStart = normalizePath2(path12.resolve(startDirectory));
|
|
11643
|
+
const normalizedStop = stopDirectory ? normalizePath2(path12.resolve(stopDirectory)) : null;
|
|
11048
11644
|
let currentDir = normalizedStart;
|
|
11049
11645
|
while (true) {
|
|
11050
11646
|
const config = await this.readConfig(currentDir);
|
|
11051
11647
|
if (config) {
|
|
11052
11648
|
configs.push(config);
|
|
11053
11649
|
configPaths.push(
|
|
11054
|
-
normalizePath2(
|
|
11650
|
+
normalizePath2(path12.join(currentDir, this.CONFIG_FILENAME))
|
|
11055
11651
|
);
|
|
11056
11652
|
}
|
|
11057
11653
|
if (normalizedStop !== null && currentDir === normalizedStop) {
|
|
11058
11654
|
break;
|
|
11059
11655
|
}
|
|
11060
|
-
const parentDir = normalizePath2(
|
|
11656
|
+
const parentDir = normalizePath2(path12.dirname(currentDir));
|
|
11061
11657
|
if (parentDir === currentDir) {
|
|
11062
11658
|
break;
|
|
11063
11659
|
}
|
|
@@ -11082,8 +11678,8 @@ var ConfigFileRepository = class {
|
|
|
11082
11678
|
* and returns each config with its target path.
|
|
11083
11679
|
*/
|
|
11084
11680
|
async findAllConfigsInTree(startDirectory, stopDirectory) {
|
|
11085
|
-
const normalizedStart = normalizePath2(
|
|
11086
|
-
const normalizedStop = stopDirectory ? normalizePath2(
|
|
11681
|
+
const normalizedStart = normalizePath2(path12.resolve(startDirectory));
|
|
11682
|
+
const normalizedStop = stopDirectory ? normalizePath2(path12.resolve(stopDirectory)) : null;
|
|
11087
11683
|
const basePath = normalizedStop ?? normalizedStart;
|
|
11088
11684
|
const searchRoot = normalizedStop ?? normalizedStart;
|
|
11089
11685
|
const configsMap = /* @__PURE__ */ new Map();
|
|
@@ -11109,7 +11705,7 @@ var ConfigFileRepository = class {
|
|
|
11109
11705
|
if (stopDir !== null && currentDir === stopDir) {
|
|
11110
11706
|
break;
|
|
11111
11707
|
}
|
|
11112
|
-
const parentDir = normalizePath2(
|
|
11708
|
+
const parentDir = normalizePath2(path12.dirname(currentDir));
|
|
11113
11709
|
if (parentDir === currentDir) {
|
|
11114
11710
|
break;
|
|
11115
11711
|
}
|
|
@@ -11240,7 +11836,7 @@ var ConfigFileRepository = class {
|
|
|
11240
11836
|
}
|
|
11241
11837
|
async tryReadFile(filePath) {
|
|
11242
11838
|
try {
|
|
11243
|
-
return await
|
|
11839
|
+
return await fs10.readFile(filePath, "utf-8");
|
|
11244
11840
|
} catch (error) {
|
|
11245
11841
|
if (error.code === "ENOENT") {
|
|
11246
11842
|
return null;
|
|
@@ -11258,8 +11854,8 @@ var ConfigFileRepository = class {
|
|
|
11258
11854
|
};
|
|
11259
11855
|
|
|
11260
11856
|
// apps/cli/src/infra/repositories/LockFileRepository.ts
|
|
11261
|
-
var
|
|
11262
|
-
var
|
|
11857
|
+
var fs11 = __toESM(require("fs/promises"));
|
|
11858
|
+
var path13 = __toESM(require("path"));
|
|
11263
11859
|
var LockFileRepository = class {
|
|
11264
11860
|
constructor() {
|
|
11265
11861
|
this.LOCK_FILENAME = "packmind-lock.json";
|
|
@@ -11267,7 +11863,7 @@ var LockFileRepository = class {
|
|
|
11267
11863
|
async read(baseDirectory) {
|
|
11268
11864
|
const lockFilePath = this.getLockFilePath(baseDirectory);
|
|
11269
11865
|
try {
|
|
11270
|
-
const content = await
|
|
11866
|
+
const content = await fs11.readFile(lockFilePath, "utf-8");
|
|
11271
11867
|
const parsed = JSON.parse(content);
|
|
11272
11868
|
if (!this.isValidLockFile(parsed)) {
|
|
11273
11869
|
logWarningConsole(`Malformed lock file: ${lockFilePath}`);
|
|
@@ -11293,7 +11889,7 @@ var LockFileRepository = class {
|
|
|
11293
11889
|
return typeof obj.installedAt === "string" && Array.isArray(obj.packageSlugs) && Array.isArray(obj.agents) && (obj.targetId === void 0 || typeof obj.targetId === "string") && typeof obj.artifacts === "object" && obj.artifacts !== null && !Array.isArray(obj.artifacts);
|
|
11294
11890
|
}
|
|
11295
11891
|
getLockFilePath(baseDirectory) {
|
|
11296
|
-
return
|
|
11892
|
+
return path13.join(baseDirectory, this.LOCK_FILENAME);
|
|
11297
11893
|
}
|
|
11298
11894
|
};
|
|
11299
11895
|
|
|
@@ -11394,7 +11990,7 @@ function normalizeLineEndings(content) {
|
|
|
11394
11990
|
}
|
|
11395
11991
|
|
|
11396
11992
|
// apps/cli/src/infra/utils/binaryDetection.ts
|
|
11397
|
-
var
|
|
11993
|
+
var path14 = __toESM(require("path"));
|
|
11398
11994
|
var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
11399
11995
|
// Images
|
|
11400
11996
|
".png",
|
|
@@ -11452,7 +12048,7 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
11452
12048
|
".sqlite3"
|
|
11453
12049
|
]);
|
|
11454
12050
|
function isBinaryExtension(filePath) {
|
|
11455
|
-
const ext =
|
|
12051
|
+
const ext = path14.extname(filePath).toLowerCase();
|
|
11456
12052
|
return BINARY_EXTENSIONS.has(ext);
|
|
11457
12053
|
}
|
|
11458
12054
|
function isBinaryBuffer(buffer) {
|
|
@@ -11594,17 +12190,17 @@ ${spaceList}`
|
|
|
11594
12190
|
|
|
11595
12191
|
// apps/cli/src/application/useCases/diffStrategies/CommandDiffStrategy.ts
|
|
11596
12192
|
var import_diff2 = require("diff");
|
|
11597
|
-
var
|
|
11598
|
-
var
|
|
12193
|
+
var fs13 = __toESM(require("fs/promises"));
|
|
12194
|
+
var path16 = __toESM(require("path"));
|
|
11599
12195
|
var CommandDiffStrategy = class {
|
|
11600
12196
|
supports(file) {
|
|
11601
12197
|
return file.artifactType === "command";
|
|
11602
12198
|
}
|
|
11603
12199
|
async diff(file, baseDirectory) {
|
|
11604
|
-
const fullPath =
|
|
12200
|
+
const fullPath = path16.join(baseDirectory, file.path);
|
|
11605
12201
|
let localContent;
|
|
11606
12202
|
try {
|
|
11607
|
-
localContent = await
|
|
12203
|
+
localContent = await fs13.readFile(fullPath, "utf-8");
|
|
11608
12204
|
} catch {
|
|
11609
12205
|
return [];
|
|
11610
12206
|
}
|
|
@@ -11634,8 +12230,8 @@ var CommandDiffStrategy = class {
|
|
|
11634
12230
|
|
|
11635
12231
|
// apps/cli/src/application/useCases/diffStrategies/SkillDiffStrategy.ts
|
|
11636
12232
|
var import_diff3 = require("diff");
|
|
11637
|
-
var
|
|
11638
|
-
var
|
|
12233
|
+
var fs14 = __toESM(require("fs/promises"));
|
|
12234
|
+
var path17 = __toESM(require("path"));
|
|
11639
12235
|
|
|
11640
12236
|
// apps/cli/src/application/utils/stripFrontmatter.ts
|
|
11641
12237
|
var FRONTMATTER_DELIMITER2 = "---";
|
|
@@ -11670,7 +12266,7 @@ var SkillDiffStrategy = class {
|
|
|
11670
12266
|
async diffNewFiles(skillFolders, serverFiles, baseDirectory) {
|
|
11671
12267
|
const diffs = [];
|
|
11672
12268
|
for (const folder of skillFolders) {
|
|
11673
|
-
const folderPath =
|
|
12269
|
+
const folderPath = path17.join(baseDirectory, folder);
|
|
11674
12270
|
const localFiles = await this.listFilesRecursively(folderPath);
|
|
11675
12271
|
const serverPathsInFolder = new Set(
|
|
11676
12272
|
serverFiles.filter((f) => f.path.startsWith(folder + "/")).map((f) => f.path)
|
|
@@ -11689,7 +12285,7 @@ var SkillDiffStrategy = class {
|
|
|
11689
12285
|
if (serverPathsInFolder.has(filePath)) {
|
|
11690
12286
|
continue;
|
|
11691
12287
|
}
|
|
11692
|
-
const fullPath =
|
|
12288
|
+
const fullPath = path17.join(baseDirectory, filePath);
|
|
11693
12289
|
const localRead = await this.tryReadFileBinaryAware(fullPath);
|
|
11694
12290
|
if (localRead === null) {
|
|
11695
12291
|
continue;
|
|
@@ -11716,7 +12312,7 @@ var SkillDiffStrategy = class {
|
|
|
11716
12312
|
return diffs;
|
|
11717
12313
|
}
|
|
11718
12314
|
async diffSkillMd(file, baseDirectory) {
|
|
11719
|
-
const fullPath =
|
|
12315
|
+
const fullPath = path17.join(baseDirectory, file.path);
|
|
11720
12316
|
const localContent = await this.tryReadFile(fullPath);
|
|
11721
12317
|
if (localContent === null) {
|
|
11722
12318
|
return [];
|
|
@@ -11773,7 +12369,7 @@ var SkillDiffStrategy = class {
|
|
|
11773
12369
|
return [];
|
|
11774
12370
|
}
|
|
11775
12371
|
const skillFileId = createSkillFileId(file.skillFileId);
|
|
11776
|
-
const fullPath =
|
|
12372
|
+
const fullPath = path17.join(baseDirectory, file.path);
|
|
11777
12373
|
const localRead = await this.tryReadFileBinaryAware(fullPath);
|
|
11778
12374
|
const fileRelativePath = this.computeRelativePath(file.path, skillFolders);
|
|
11779
12375
|
if (localRead === null) {
|
|
@@ -11983,14 +12579,14 @@ var SkillDiffStrategy = class {
|
|
|
11983
12579
|
}
|
|
11984
12580
|
async tryReadFile(filePath) {
|
|
11985
12581
|
try {
|
|
11986
|
-
return await
|
|
12582
|
+
return await fs14.readFile(filePath, "utf-8");
|
|
11987
12583
|
} catch {
|
|
11988
12584
|
return null;
|
|
11989
12585
|
}
|
|
11990
12586
|
}
|
|
11991
12587
|
async tryReadFileBinaryAware(filePath) {
|
|
11992
12588
|
try {
|
|
11993
|
-
const buffer = await
|
|
12589
|
+
const buffer = await fs14.readFile(filePath);
|
|
11994
12590
|
if (isBinaryFile(filePath, buffer)) {
|
|
11995
12591
|
return { content: buffer.toString("base64"), isBase64: true };
|
|
11996
12592
|
}
|
|
@@ -12002,13 +12598,13 @@ var SkillDiffStrategy = class {
|
|
|
12002
12598
|
async listFilesRecursively(dirPath, prefix = "") {
|
|
12003
12599
|
let entries;
|
|
12004
12600
|
try {
|
|
12005
|
-
entries = await
|
|
12601
|
+
entries = await fs14.readdir(dirPath);
|
|
12006
12602
|
} catch {
|
|
12007
12603
|
return [];
|
|
12008
12604
|
}
|
|
12009
12605
|
const files = [];
|
|
12010
12606
|
for (const entry of entries) {
|
|
12011
|
-
const fullPath =
|
|
12607
|
+
const fullPath = path17.join(dirPath, entry);
|
|
12012
12608
|
const stat9 = await this.tryStatFile(fullPath);
|
|
12013
12609
|
if (!stat9) {
|
|
12014
12610
|
continue;
|
|
@@ -12028,7 +12624,7 @@ var SkillDiffStrategy = class {
|
|
|
12028
12624
|
}
|
|
12029
12625
|
async tryStatFile(filePath) {
|
|
12030
12626
|
try {
|
|
12031
|
-
const stat9 = await
|
|
12627
|
+
const stat9 = await fs14.stat(filePath);
|
|
12032
12628
|
return { isDirectory: stat9.isDirectory() };
|
|
12033
12629
|
} catch {
|
|
12034
12630
|
return null;
|
|
@@ -12036,7 +12632,7 @@ var SkillDiffStrategy = class {
|
|
|
12036
12632
|
}
|
|
12037
12633
|
async tryGetPermissions(filePath) {
|
|
12038
12634
|
try {
|
|
12039
|
-
const stat9 = await
|
|
12635
|
+
const stat9 = await fs14.stat(filePath);
|
|
12040
12636
|
return modeToPermissionStringOrDefault(stat9.mode);
|
|
12041
12637
|
} catch {
|
|
12042
12638
|
return null;
|
|
@@ -12052,8 +12648,8 @@ var SkillDiffStrategy = class {
|
|
|
12052
12648
|
};
|
|
12053
12649
|
|
|
12054
12650
|
// apps/cli/src/application/useCases/diffStrategies/StandardDiffStrategy.ts
|
|
12055
|
-
var
|
|
12056
|
-
var
|
|
12651
|
+
var fs15 = __toESM(require("fs/promises"));
|
|
12652
|
+
var path18 = __toESM(require("path"));
|
|
12057
12653
|
|
|
12058
12654
|
// apps/cli/src/application/utils/parseStandardMd.ts
|
|
12059
12655
|
var DEPLOYER_PARSERS = [
|
|
@@ -12361,10 +12957,10 @@ var StandardDiffStrategy = class {
|
|
|
12361
12957
|
return file.artifactType === "standard";
|
|
12362
12958
|
}
|
|
12363
12959
|
async diff(file, baseDirectory) {
|
|
12364
|
-
const fullPath =
|
|
12960
|
+
const fullPath = path18.join(baseDirectory, file.path);
|
|
12365
12961
|
let localContent;
|
|
12366
12962
|
try {
|
|
12367
|
-
localContent = await
|
|
12963
|
+
localContent = await fs15.readFile(fullPath, "utf-8");
|
|
12368
12964
|
} catch {
|
|
12369
12965
|
return [];
|
|
12370
12966
|
}
|
|
@@ -12728,6 +13324,12 @@ var SpaceService = class {
|
|
|
12728
13324
|
}
|
|
12729
13325
|
return defaultSpace;
|
|
12730
13326
|
}
|
|
13327
|
+
async getSpaceBySlug(slug3) {
|
|
13328
|
+
return this.spaceGateway.getSpaceBySlug(slug3);
|
|
13329
|
+
}
|
|
13330
|
+
getApiContext() {
|
|
13331
|
+
return this.spaceGateway.getApiContext();
|
|
13332
|
+
}
|
|
12731
13333
|
};
|
|
12732
13334
|
|
|
12733
13335
|
// apps/cli/src/PackmindCliHexaFactory.ts
|
|
@@ -12745,6 +13347,12 @@ var PackmindCliHexaFactory = class {
|
|
|
12745
13347
|
diffViolationFilterService: new DiffViolationFilterService(),
|
|
12746
13348
|
spaceService: new SpaceService(this.repositories.packmindGateway.spaces)
|
|
12747
13349
|
};
|
|
13350
|
+
const installUseCase = new InstallUseCase(
|
|
13351
|
+
this.repositories.packmindGateway,
|
|
13352
|
+
this.repositories.lockFileRepository,
|
|
13353
|
+
this.repositories.configFileRepository,
|
|
13354
|
+
this.services.spaceService
|
|
13355
|
+
);
|
|
12748
13356
|
this.useCases = {
|
|
12749
13357
|
executeSingleFileAst: new ExecuteSingleFileAstUseCase(
|
|
12750
13358
|
this.services.linterExecutionUseCase
|
|
@@ -12762,6 +13370,12 @@ var PackmindCliHexaFactory = class {
|
|
|
12762
13370
|
installPackages: new InstallPackagesUseCase(
|
|
12763
13371
|
this.repositories.packmindGateway
|
|
12764
13372
|
),
|
|
13373
|
+
install: installUseCase,
|
|
13374
|
+
uninstall: new UninstallUseCase(
|
|
13375
|
+
this.repositories.configFileRepository,
|
|
13376
|
+
this.services.spaceService,
|
|
13377
|
+
installUseCase
|
|
13378
|
+
),
|
|
12765
13379
|
installDefaultSkills: new InstallDefaultSkillsUseCase(this.repositories),
|
|
12766
13380
|
listPackages: new ListPackagesUseCase(
|
|
12767
13381
|
this.repositories.packmindGateway,
|
|
@@ -12813,6 +13427,11 @@ var PackmindCliHexa = class {
|
|
|
12813
13427
|
command33
|
|
12814
13428
|
);
|
|
12815
13429
|
};
|
|
13430
|
+
this.notifyArtefactsDistribution = async (command33) => {
|
|
13431
|
+
return this.hexa.repositories.packmindGateway.deployment.notifyArtefactsDistribution(
|
|
13432
|
+
command33
|
|
13433
|
+
);
|
|
13434
|
+
};
|
|
12816
13435
|
this.logger = logger2;
|
|
12817
13436
|
try {
|
|
12818
13437
|
this.hexa = new PackmindCliHexaFactory();
|
|
@@ -12845,6 +13464,12 @@ var PackmindCliHexa = class {
|
|
|
12845
13464
|
async installPackages(command33) {
|
|
12846
13465
|
return this.hexa.useCases.installPackages.execute(command33);
|
|
12847
13466
|
}
|
|
13467
|
+
async install(command33) {
|
|
13468
|
+
return this.hexa.useCases.install.execute(command33);
|
|
13469
|
+
}
|
|
13470
|
+
async uninstall(command33) {
|
|
13471
|
+
return this.hexa.useCases.uninstall.execute(command33);
|
|
13472
|
+
}
|
|
12848
13473
|
async diffArtefacts(command33) {
|
|
12849
13474
|
return this.hexa.useCases.diffArtefacts.execute(command33);
|
|
12850
13475
|
}
|
|
@@ -13103,31 +13728,31 @@ var HumanReadableLogger = class {
|
|
|
13103
13728
|
var pathModule2 = __toESM(require("path"));
|
|
13104
13729
|
|
|
13105
13730
|
// apps/cli/src/infra/commands/lintHandler.ts
|
|
13106
|
-
var
|
|
13731
|
+
var fs17 = __toESM(require("fs/promises"));
|
|
13107
13732
|
var pathModule = __toESM(require("path"));
|
|
13108
13733
|
|
|
13109
13734
|
// apps/cli/src/application/services/PackmindIgnoreReader.ts
|
|
13110
|
-
var
|
|
13111
|
-
var
|
|
13735
|
+
var fs16 = __toESM(require("fs/promises"));
|
|
13736
|
+
var path19 = __toESM(require("path"));
|
|
13112
13737
|
var IGNORE_FILENAME = ".packmindignore";
|
|
13113
13738
|
var PackmindIgnoreReader = class {
|
|
13114
13739
|
async readIgnorePatterns(startDirectory, stopDirectory) {
|
|
13115
13740
|
const patterns = [];
|
|
13116
|
-
const normalizedStart =
|
|
13117
|
-
const normalizedStop = stopDirectory ?
|
|
13741
|
+
const normalizedStart = path19.resolve(startDirectory);
|
|
13742
|
+
const normalizedStop = stopDirectory ? path19.resolve(stopDirectory) : null;
|
|
13118
13743
|
if (normalizedStop === null) {
|
|
13119
|
-
const ignoreFile =
|
|
13744
|
+
const ignoreFile = path19.join(normalizedStart, IGNORE_FILENAME);
|
|
13120
13745
|
return this.parseIgnoreFile(ignoreFile);
|
|
13121
13746
|
}
|
|
13122
13747
|
let currentDir = normalizedStart;
|
|
13123
13748
|
while (true) {
|
|
13124
|
-
const ignoreFile =
|
|
13749
|
+
const ignoreFile = path19.join(currentDir, IGNORE_FILENAME);
|
|
13125
13750
|
const filePatterns = await this.parseIgnoreFile(ignoreFile);
|
|
13126
13751
|
patterns.push(...filePatterns);
|
|
13127
13752
|
if (currentDir === normalizedStop) {
|
|
13128
13753
|
break;
|
|
13129
13754
|
}
|
|
13130
|
-
const parentDir =
|
|
13755
|
+
const parentDir = path19.dirname(currentDir);
|
|
13131
13756
|
if (parentDir === currentDir) {
|
|
13132
13757
|
break;
|
|
13133
13758
|
}
|
|
@@ -13138,7 +13763,7 @@ var PackmindIgnoreReader = class {
|
|
|
13138
13763
|
async parseIgnoreFile(filePath) {
|
|
13139
13764
|
let content;
|
|
13140
13765
|
try {
|
|
13141
|
-
content = await
|
|
13766
|
+
content = await fs16.readFile(filePath, "utf-8");
|
|
13142
13767
|
} catch (err) {
|
|
13143
13768
|
if (err.code === "ENOENT") {
|
|
13144
13769
|
return [];
|
|
@@ -13159,7 +13784,7 @@ function isNotLoggedInError(error) {
|
|
|
13159
13784
|
}
|
|
13160
13785
|
async function lintHandler(args2, deps) {
|
|
13161
13786
|
const {
|
|
13162
|
-
path:
|
|
13787
|
+
path: path37,
|
|
13163
13788
|
draft,
|
|
13164
13789
|
rule,
|
|
13165
13790
|
language,
|
|
@@ -13181,11 +13806,11 @@ async function lintHandler(args2, deps) {
|
|
|
13181
13806
|
throw new Error("option --rule is required to use --draft mode");
|
|
13182
13807
|
}
|
|
13183
13808
|
const startedAt = Date.now();
|
|
13184
|
-
const targetPath =
|
|
13809
|
+
const targetPath = path37 ?? ".";
|
|
13185
13810
|
const absolutePath = resolvePath(targetPath);
|
|
13186
13811
|
let stats;
|
|
13187
13812
|
try {
|
|
13188
|
-
stats = await
|
|
13813
|
+
stats = await fs17.stat(absolutePath);
|
|
13189
13814
|
} catch (err) {
|
|
13190
13815
|
const isNotFound = err.code === "ENOENT";
|
|
13191
13816
|
const message = isNotFound ? `File or directory "${absolutePath}" does not exist` : `Cannot access "${absolutePath}": ${err.message}`;
|
|
@@ -13503,72 +14128,15 @@ function extractWasmFiles() {
|
|
|
13503
14128
|
|
|
13504
14129
|
// apps/cli/src/main.ts
|
|
13505
14130
|
var import_dotenv = require("dotenv");
|
|
13506
|
-
var
|
|
13507
|
-
var
|
|
14131
|
+
var fs28 = __toESM(require("fs"));
|
|
14132
|
+
var path36 = __toESM(require("path"));
|
|
13508
14133
|
|
|
13509
14134
|
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
13510
14135
|
var import_cmd_ts2 = __toESM(require_cjs());
|
|
14136
|
+
var path20 = __toESM(require("path"));
|
|
14137
|
+
var fs18 = __toESM(require("fs"));
|
|
13511
14138
|
|
|
13512
14139
|
// apps/cli/src/infra/commands/installPackagesHandler.ts
|
|
13513
|
-
var fs17 = __toESM(require("fs/promises"));
|
|
13514
|
-
var path19 = __toESM(require("path"));
|
|
13515
|
-
var { version: CLI_VERSION } = require_package();
|
|
13516
|
-
async function notifyDistributionIfInGitRepo(params) {
|
|
13517
|
-
const { packmindCliHexa, cwd, packages, log, agents } = params;
|
|
13518
|
-
const resolvedGitRoot = params.gitRoot ?? await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
13519
|
-
if (!resolvedGitRoot) {
|
|
13520
|
-
return false;
|
|
13521
|
-
}
|
|
13522
|
-
try {
|
|
13523
|
-
const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(resolvedGitRoot);
|
|
13524
|
-
const gitBranch = packmindCliHexa.getCurrentBranch(resolvedGitRoot);
|
|
13525
|
-
let relativePath = cwd.startsWith(resolvedGitRoot) ? cwd.slice(resolvedGitRoot.length) : "/";
|
|
13526
|
-
if (!relativePath.startsWith("/")) {
|
|
13527
|
-
relativePath = "/" + relativePath;
|
|
13528
|
-
}
|
|
13529
|
-
if (!relativePath.endsWith("/")) {
|
|
13530
|
-
relativePath = relativePath + "/";
|
|
13531
|
-
}
|
|
13532
|
-
await packmindCliHexa.notifyDistribution({
|
|
13533
|
-
distributedPackages: packages,
|
|
13534
|
-
gitRemoteUrl,
|
|
13535
|
-
gitBranch,
|
|
13536
|
-
relativePath,
|
|
13537
|
-
agents
|
|
13538
|
-
});
|
|
13539
|
-
log("Successfully notified Packmind of the new distribution");
|
|
13540
|
-
return true;
|
|
13541
|
-
} catch {
|
|
13542
|
-
return false;
|
|
13543
|
-
}
|
|
13544
|
-
}
|
|
13545
|
-
async function installDefaultSkillsIfAtGitRoot(params) {
|
|
13546
|
-
const { packmindCliHexa, cwd, log } = params;
|
|
13547
|
-
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
13548
|
-
if (!gitRoot || cwd !== gitRoot) {
|
|
13549
|
-
return;
|
|
13550
|
-
}
|
|
13551
|
-
try {
|
|
13552
|
-
log("\nInstalling default skills...");
|
|
13553
|
-
const skillsResult = await packmindCliHexa.installDefaultSkills({
|
|
13554
|
-
cliVersion: CLI_VERSION
|
|
13555
|
-
});
|
|
13556
|
-
if (skillsResult.errors.length > 0) {
|
|
13557
|
-
skillsResult.errors.forEach((err) => {
|
|
13558
|
-
log(` Warning: ${err}`);
|
|
13559
|
-
});
|
|
13560
|
-
}
|
|
13561
|
-
const totalSkillFiles = skillsResult.filesCreated + skillsResult.filesUpdated;
|
|
13562
|
-
if (totalSkillFiles > 0) {
|
|
13563
|
-
log(
|
|
13564
|
-
`Default skills: added ${skillsResult.filesCreated} files, changed ${skillsResult.filesUpdated} files`
|
|
13565
|
-
);
|
|
13566
|
-
} else if (skillsResult.errors.length === 0) {
|
|
13567
|
-
log("Default skills are already up to date");
|
|
13568
|
-
}
|
|
13569
|
-
} catch {
|
|
13570
|
-
}
|
|
13571
|
-
}
|
|
13572
14140
|
function formatOverviewRow(configPath, packages, pathColumnWidth) {
|
|
13573
14141
|
const paddedPath = configPath.padEnd(pathColumnWidth);
|
|
13574
14142
|
if (packages.length === 0) {
|
|
@@ -13641,1150 +14209,310 @@ ${uniqueCount} unique ${packageWord} currently installed.`);
|
|
|
13641
14209
|
};
|
|
13642
14210
|
}
|
|
13643
14211
|
}
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
14212
|
+
|
|
14213
|
+
// apps/cli/src/infra/commands/InstallCommand.ts
|
|
14214
|
+
function findSubDirectoriesWithPackmindJson(dirPath, recursive) {
|
|
14215
|
+
const result = [];
|
|
14216
|
+
let entries;
|
|
13648
14217
|
try {
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
configAgents = fullConfig.agents;
|
|
13653
|
-
} else {
|
|
13654
|
-
configPackages = [];
|
|
13655
|
-
}
|
|
13656
|
-
} catch (err) {
|
|
13657
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
13658
|
-
return {
|
|
13659
|
-
success: false,
|
|
13660
|
-
filesCreated: 0,
|
|
13661
|
-
filesUpdated: 0,
|
|
13662
|
-
filesDeleted: 0,
|
|
13663
|
-
notificationSent: false,
|
|
13664
|
-
errorMessage: `Failed to parse packmind.json: ${errorMessage}`
|
|
13665
|
-
};
|
|
13666
|
-
}
|
|
13667
|
-
if (configPackages.length === 0) {
|
|
13668
|
-
return {
|
|
13669
|
-
success: true,
|
|
13670
|
-
filesCreated: 0,
|
|
13671
|
-
filesUpdated: 0,
|
|
13672
|
-
filesDeleted: 0,
|
|
13673
|
-
notificationSent: false
|
|
13674
|
-
};
|
|
13675
|
-
}
|
|
13676
|
-
const normalizedConfigPackages = await packmindCliHexa.normalizePackageSlugs(configPackages);
|
|
13677
|
-
let gitRemoteUrl;
|
|
13678
|
-
let gitBranch;
|
|
13679
|
-
let relativePath;
|
|
13680
|
-
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(directory);
|
|
13681
|
-
if (gitRoot) {
|
|
13682
|
-
try {
|
|
13683
|
-
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
13684
|
-
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
13685
|
-
relativePath = directory.startsWith(gitRoot) ? directory.slice(gitRoot.length) : "/";
|
|
13686
|
-
if (!relativePath.startsWith("/")) {
|
|
13687
|
-
relativePath = "/" + relativePath;
|
|
13688
|
-
}
|
|
13689
|
-
if (!relativePath.endsWith("/")) {
|
|
13690
|
-
relativePath = relativePath + "/";
|
|
13691
|
-
}
|
|
13692
|
-
} catch {
|
|
13693
|
-
}
|
|
14218
|
+
entries = fs18.readdirSync(dirPath, { withFileTypes: true });
|
|
14219
|
+
} catch {
|
|
14220
|
+
return result;
|
|
13694
14221
|
}
|
|
13695
|
-
|
|
13696
|
-
|
|
13697
|
-
const
|
|
13698
|
-
|
|
13699
|
-
|
|
13700
|
-
);
|
|
13701
|
-
const result = await packmindCliHexa.installPackages({
|
|
13702
|
-
baseDirectory: directory,
|
|
13703
|
-
packagesSlugs: normalizedConfigPackages,
|
|
13704
|
-
previousPackagesSlugs: normalizedConfigPackages,
|
|
13705
|
-
// Pass for consistency
|
|
13706
|
-
gitRemoteUrl,
|
|
13707
|
-
gitBranch,
|
|
13708
|
-
relativePath,
|
|
13709
|
-
agents: configAgents
|
|
13710
|
-
// Pass agents from config if present
|
|
13711
|
-
});
|
|
13712
|
-
const parts = [];
|
|
13713
|
-
if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
|
|
13714
|
-
if (result.standardsCount > 0)
|
|
13715
|
-
parts.push(`${result.standardsCount} standards`);
|
|
13716
|
-
if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
|
|
13717
|
-
log(` Installing ${parts.join(", ") || "artifacts"}...`);
|
|
13718
|
-
log(
|
|
13719
|
-
` added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${result.filesDeleted} files`
|
|
13720
|
-
);
|
|
13721
|
-
if (result.errors.length > 0) {
|
|
13722
|
-
return {
|
|
13723
|
-
success: false,
|
|
13724
|
-
filesCreated: result.filesCreated,
|
|
13725
|
-
filesUpdated: result.filesUpdated,
|
|
13726
|
-
filesDeleted: result.filesDeleted,
|
|
13727
|
-
notificationSent: false,
|
|
13728
|
-
errorMessage: result.errors.join(", ")
|
|
13729
|
-
};
|
|
13730
|
-
}
|
|
13731
|
-
const configSlugsWereNormalized = configPackages.some(
|
|
13732
|
-
(slug3, i) => slug3 !== normalizedConfigPackages[i]
|
|
13733
|
-
);
|
|
13734
|
-
if (configSlugsWereNormalized) {
|
|
13735
|
-
await packmindCliHexa.writeConfig(directory, normalizedConfigPackages);
|
|
14222
|
+
for (const entry of entries) {
|
|
14223
|
+
if (!entry.isDirectory()) continue;
|
|
14224
|
+
const subDir = path20.join(dirPath, entry.name);
|
|
14225
|
+
if (fs18.existsSync(path20.join(subDir, "packmind.json"))) {
|
|
14226
|
+
result.push(subDir);
|
|
13736
14227
|
}
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
|
|
13740
|
-
notificationSent = await notifyDistributionIfInGitRepo({
|
|
13741
|
-
packmindCliHexa,
|
|
13742
|
-
cwd: directory,
|
|
13743
|
-
packages: normalizedConfigPackages,
|
|
13744
|
-
agents: configAgents,
|
|
13745
|
-
log: () => {
|
|
13746
|
-
},
|
|
13747
|
-
gitRoot: gitRoot ?? void 0
|
|
13748
|
-
});
|
|
14228
|
+
if (recursive) {
|
|
14229
|
+
result.push(...findSubDirectoriesWithPackmindJson(subDir, true));
|
|
13749
14230
|
}
|
|
13750
|
-
return {
|
|
13751
|
-
success: true,
|
|
13752
|
-
filesCreated: result.filesCreated,
|
|
13753
|
-
filesUpdated: result.filesUpdated,
|
|
13754
|
-
filesDeleted: result.filesDeleted + skillDirsDeleted,
|
|
13755
|
-
notificationSent
|
|
13756
|
-
};
|
|
13757
|
-
} catch (err) {
|
|
13758
|
-
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
13759
|
-
return {
|
|
13760
|
-
success: false,
|
|
13761
|
-
filesCreated: 0,
|
|
13762
|
-
filesUpdated: 0,
|
|
13763
|
-
filesDeleted: 0,
|
|
13764
|
-
notificationSent: false,
|
|
13765
|
-
errorMessage
|
|
13766
|
-
};
|
|
13767
14231
|
}
|
|
14232
|
+
return result;
|
|
13768
14233
|
}
|
|
13769
|
-
|
|
13770
|
-
const
|
|
13771
|
-
|
|
13772
|
-
|
|
13773
|
-
|
|
13774
|
-
|
|
13775
|
-
|
|
13776
|
-
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
|
|
13795
|
-
|
|
13796
|
-
|
|
13797
|
-
|
|
13798
|
-
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
|
|
13803
|
-
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
|
|
13820
|
-
|
|
13821
|
-
|
|
13822
|
-
|
|
13823
|
-
}
|
|
13824
|
-
|
|
13825
|
-
|
|
13826
|
-
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
|
|
13834
|
-
filesUpdated: 0,
|
|
13835
|
-
filesDeleted: 0,
|
|
13836
|
-
notificationSent: false
|
|
13837
|
-
};
|
|
13838
|
-
}
|
|
13839
|
-
let normalizedNewSlugs;
|
|
13840
|
-
let normalizedConfigSlugs;
|
|
14234
|
+
function mergeInstallResults(results) {
|
|
14235
|
+
const merged = {
|
|
14236
|
+
filesCreated: 0,
|
|
14237
|
+
filesUpdated: 0,
|
|
14238
|
+
filesDeleted: 0,
|
|
14239
|
+
contentFilesChanged: 0,
|
|
14240
|
+
errors: [],
|
|
14241
|
+
recipesCount: 0,
|
|
14242
|
+
standardsCount: 0,
|
|
14243
|
+
commandsCount: 0,
|
|
14244
|
+
skillsCount: 0,
|
|
14245
|
+
recipesRemoved: 0,
|
|
14246
|
+
standardsRemoved: 0,
|
|
14247
|
+
commandsRemoved: 0,
|
|
14248
|
+
skillsRemoved: 0,
|
|
14249
|
+
skillDirectoriesDeleted: 0,
|
|
14250
|
+
missingAccess: [],
|
|
14251
|
+
joinSpaceUrl: void 0
|
|
14252
|
+
};
|
|
14253
|
+
for (const r of results) {
|
|
14254
|
+
merged.filesCreated += r.filesCreated;
|
|
14255
|
+
merged.filesUpdated += r.filesUpdated;
|
|
14256
|
+
merged.filesDeleted += r.filesDeleted;
|
|
14257
|
+
merged.contentFilesChanged += r.contentFilesChanged;
|
|
14258
|
+
merged.errors.push(...r.errors);
|
|
14259
|
+
merged.recipesCount += r.recipesCount;
|
|
14260
|
+
merged.standardsCount += r.standardsCount;
|
|
14261
|
+
merged.commandsCount += r.commandsCount;
|
|
14262
|
+
merged.skillsCount += r.skillsCount;
|
|
14263
|
+
merged.recipesRemoved += r.recipesRemoved;
|
|
14264
|
+
merged.standardsRemoved += r.standardsRemoved;
|
|
14265
|
+
merged.commandsRemoved += r.commandsRemoved;
|
|
14266
|
+
merged.skillsRemoved += r.skillsRemoved;
|
|
14267
|
+
merged.skillDirectoriesDeleted += r.skillDirectoriesDeleted;
|
|
14268
|
+
merged.missingAccess.push(...r.missingAccess);
|
|
14269
|
+
}
|
|
14270
|
+
merged.missingAccess = [...new Set(merged.missingAccess)];
|
|
14271
|
+
const urlsFromResultsWithMissingAccess = results.filter((r) => r.missingAccess.length > 0).map((r) => r.joinSpaceUrl);
|
|
14272
|
+
const uniqueUrls = new Set(urlsFromResultsWithMissingAccess.filter(Boolean));
|
|
14273
|
+
if (uniqueUrls.size === 1 && !urlsFromResultsWithMissingAccess.some((u) => u === void 0)) {
|
|
14274
|
+
merged.joinSpaceUrl = [...uniqueUrls][0];
|
|
14275
|
+
}
|
|
14276
|
+
return merged;
|
|
14277
|
+
}
|
|
14278
|
+
function buildInstallSummary(result) {
|
|
14279
|
+
const contentParts = [
|
|
14280
|
+
result.standardsCount > 0 ? `${result.standardsCount} ${result.standardsCount === 1 ? "standard" : "standards"}` : null,
|
|
14281
|
+
result.commandsCount > 0 ? `${result.commandsCount} ${result.commandsCount === 1 ? "command" : "commands"}` : null,
|
|
14282
|
+
result.skillsCount > 0 ? `${result.skillsCount} ${result.skillsCount === 1 ? "skill" : "skills"}` : null,
|
|
14283
|
+
result.recipesCount > 0 ? `${result.recipesCount} ${result.recipesCount === 1 ? "recipe" : "recipes"}` : null
|
|
14284
|
+
].filter(Boolean);
|
|
14285
|
+
const contentChanged = result.contentFilesChanged > 0;
|
|
14286
|
+
if (!contentChanged && contentParts.length === 0) {
|
|
14287
|
+
return "\u2705 Nothing to install";
|
|
14288
|
+
}
|
|
14289
|
+
if (!contentChanged) {
|
|
14290
|
+
return `\u2705 Already up to date \u2014 ${contentParts.join(", ")}`;
|
|
14291
|
+
}
|
|
14292
|
+
if (contentParts.length === 0) {
|
|
14293
|
+
return "\u2705 Packages removed";
|
|
14294
|
+
}
|
|
14295
|
+
return `\u2705 Synced ${contentParts.join(", ")}`;
|
|
14296
|
+
}
|
|
14297
|
+
async function notifyArtefactsDistributionIfInGitRepo(params) {
|
|
14298
|
+
const { packmindCliHexa, dir } = params;
|
|
13841
14299
|
try {
|
|
13842
|
-
|
|
13843
|
-
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13850
|
-
|
|
13851
|
-
|
|
13852
|
-
};
|
|
13853
|
-
}
|
|
13854
|
-
const allPackages = [
|
|
13855
|
-
.../* @__PURE__ */ new Set([...normalizedConfigSlugs, ...normalizedNewSlugs])
|
|
13856
|
-
];
|
|
13857
|
-
if (allPackages.length === 0) {
|
|
13858
|
-
if (configFileExists) {
|
|
13859
|
-
logWarningConsole(
|
|
13860
|
-
"config packmind.json is empty, no packages to install"
|
|
13861
|
-
);
|
|
13862
|
-
} else {
|
|
13863
|
-
logWarningConsole("config packmind.json not found");
|
|
14300
|
+
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(dir);
|
|
14301
|
+
if (!gitRoot) return;
|
|
14302
|
+
const lockFilePath = path20.join(dir, "packmind-lock.json");
|
|
14303
|
+
const content = fs18.readFileSync(lockFilePath, "utf-8");
|
|
14304
|
+
const packmindLockFile = JSON.parse(content);
|
|
14305
|
+
const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
14306
|
+
const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
14307
|
+
let relativePath = dir.startsWith(gitRoot) ? dir.slice(gitRoot.length) : "/";
|
|
14308
|
+
if (!relativePath.startsWith("/")) {
|
|
14309
|
+
relativePath = "/" + relativePath;
|
|
13864
14310
|
}
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
log("");
|
|
13868
|
-
log("Examples:");
|
|
13869
|
-
log(" packmind-cli install backend");
|
|
13870
|
-
log(" packmind-cli install backend frontend");
|
|
13871
|
-
log(" packmind-cli install --list # Show available packages");
|
|
13872
|
-
log("");
|
|
13873
|
-
log("Install commands and standards from the specified packages.");
|
|
13874
|
-
exit(0);
|
|
13875
|
-
return {
|
|
13876
|
-
filesCreated: 0,
|
|
13877
|
-
filesUpdated: 0,
|
|
13878
|
-
filesDeleted: 0,
|
|
13879
|
-
notificationSent: false
|
|
13880
|
-
};
|
|
13881
|
-
}
|
|
13882
|
-
if (!configFileExists && packagesSlugs.length > 0) {
|
|
13883
|
-
log("INFO initializing packmind.json");
|
|
13884
|
-
}
|
|
13885
|
-
try {
|
|
13886
|
-
const packageCount = allPackages.length;
|
|
13887
|
-
const packageWord = packageCount === 1 ? "package" : "packages";
|
|
13888
|
-
log(
|
|
13889
|
-
`Fetching ${packageCount} ${packageWord}: ${allPackages.join(", ")}...`
|
|
13890
|
-
);
|
|
13891
|
-
let gitRemoteUrl;
|
|
13892
|
-
let gitBranch;
|
|
13893
|
-
let relativePath;
|
|
13894
|
-
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
13895
|
-
if (gitRoot) {
|
|
13896
|
-
try {
|
|
13897
|
-
gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
13898
|
-
gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
13899
|
-
relativePath = cwd.startsWith(gitRoot) ? cwd.slice(gitRoot.length) : "/";
|
|
13900
|
-
if (!relativePath.startsWith("/")) {
|
|
13901
|
-
relativePath = "/" + relativePath;
|
|
13902
|
-
}
|
|
13903
|
-
if (!relativePath.endsWith("/")) {
|
|
13904
|
-
relativePath = relativePath + "/";
|
|
13905
|
-
}
|
|
13906
|
-
} catch {
|
|
13907
|
-
}
|
|
14311
|
+
if (!relativePath.endsWith("/")) {
|
|
14312
|
+
relativePath = relativePath + "/";
|
|
13908
14313
|
}
|
|
13909
|
-
|
|
13910
|
-
baseDirectory: cwd,
|
|
13911
|
-
packagesSlugs: allPackages,
|
|
13912
|
-
previousPackagesSlugs: normalizedConfigSlugs,
|
|
13913
|
-
// Pass previous config for change detection
|
|
14314
|
+
await packmindCliHexa.notifyArtefactsDistribution({
|
|
13914
14315
|
gitRemoteUrl,
|
|
13915
14316
|
gitBranch,
|
|
13916
14317
|
relativePath,
|
|
13917
|
-
|
|
13918
|
-
// Pass agents from config if present (overrides org-level)
|
|
13919
|
-
});
|
|
13920
|
-
const parts = [];
|
|
13921
|
-
if (result.recipesCount > 0) parts.push(`${result.recipesCount} commands`);
|
|
13922
|
-
if (result.standardsCount > 0)
|
|
13923
|
-
parts.push(`${result.standardsCount} standards`);
|
|
13924
|
-
if (result.skillsCount > 0) parts.push(`${result.skillsCount} skills`);
|
|
13925
|
-
log(`Installing ${parts.join(", ") || "artifacts"}...`);
|
|
13926
|
-
const skillDirsDeleted = result.skillDirectoriesDeleted || 0;
|
|
13927
|
-
const totalDeleted = result.filesDeleted + skillDirsDeleted;
|
|
13928
|
-
log(
|
|
13929
|
-
`
|
|
13930
|
-
added ${result.filesCreated} files, changed ${result.filesUpdated} files, removed ${totalDeleted} files`
|
|
13931
|
-
);
|
|
13932
|
-
if (result.errors.length > 0) {
|
|
13933
|
-
log("\n\u26A0\uFE0F Errors encountered:");
|
|
13934
|
-
result.errors.forEach((err) => {
|
|
13935
|
-
log(` - ${err}`);
|
|
13936
|
-
});
|
|
13937
|
-
exit(1);
|
|
13938
|
-
return {
|
|
13939
|
-
filesCreated: result.filesCreated,
|
|
13940
|
-
filesUpdated: result.filesUpdated,
|
|
13941
|
-
filesDeleted: totalDeleted,
|
|
13942
|
-
notificationSent: false
|
|
13943
|
-
};
|
|
13944
|
-
}
|
|
13945
|
-
const configSlugsWereNormalized = configPackages.some(
|
|
13946
|
-
(slug3, i) => slug3 !== normalizedConfigSlugs[i]
|
|
13947
|
-
);
|
|
13948
|
-
const newPackages = normalizedNewSlugs.filter(
|
|
13949
|
-
(slug3) => !normalizedConfigSlugs.includes(slug3)
|
|
13950
|
-
);
|
|
13951
|
-
if (configSlugsWereNormalized) {
|
|
13952
|
-
await packmindCliHexa.writeConfig(cwd, allPackages);
|
|
13953
|
-
} else if (newPackages.length > 0) {
|
|
13954
|
-
await packmindCliHexa.addPackagesToConfig(cwd, newPackages);
|
|
13955
|
-
}
|
|
13956
|
-
let notificationSent = false;
|
|
13957
|
-
if (result.filesCreated > 0 || result.filesUpdated > 0 || result.filesDeleted > 0 || skillDirsDeleted > 0) {
|
|
13958
|
-
notificationSent = await notifyDistributionIfInGitRepo({
|
|
13959
|
-
packmindCliHexa,
|
|
13960
|
-
cwd,
|
|
13961
|
-
packages: allPackages,
|
|
13962
|
-
agents: configAgents,
|
|
13963
|
-
log
|
|
13964
|
-
});
|
|
13965
|
-
}
|
|
13966
|
-
await installDefaultSkillsIfAtGitRoot({
|
|
13967
|
-
packmindCliHexa,
|
|
13968
|
-
cwd,
|
|
13969
|
-
log
|
|
14318
|
+
packmindLockFile
|
|
13970
14319
|
});
|
|
13971
|
-
|
|
13972
|
-
deps.playbookLocalRepository.clearAll();
|
|
13973
|
-
}
|
|
13974
|
-
return {
|
|
13975
|
-
filesCreated: result.filesCreated,
|
|
13976
|
-
filesUpdated: result.filesUpdated,
|
|
13977
|
-
filesDeleted: totalDeleted,
|
|
13978
|
-
notificationSent
|
|
13979
|
-
};
|
|
13980
|
-
} catch (err) {
|
|
13981
|
-
error("\n\u274C Failed to install content:");
|
|
13982
|
-
if (err instanceof Error) {
|
|
13983
|
-
const errorObj = err;
|
|
13984
|
-
if (errorObj.statusCode === 400) {
|
|
13985
|
-
error(` ${errorObj.message}`);
|
|
13986
|
-
error("\n\u{1F4A1} This is a validation error. Please check:");
|
|
13987
|
-
error(" - The command syntax is correct");
|
|
13988
|
-
error(" - You have provided at least one package slug");
|
|
13989
|
-
error(" - Your packmind.json file contains valid package slugs");
|
|
13990
|
-
} else if (errorObj.statusCode === 404) {
|
|
13991
|
-
error(` ${errorObj.message}`);
|
|
13992
|
-
if (configFileExists && configPackages.length > 0) {
|
|
13993
|
-
const missingPackages = allPackages.filter(
|
|
13994
|
-
(pkg) => configPackages.includes(pkg)
|
|
13995
|
-
);
|
|
13996
|
-
if (missingPackages.length > 0) {
|
|
13997
|
-
error(
|
|
13998
|
-
"\n\u{1F4A1} Either remove the following package(s) from packmind.json:"
|
|
13999
|
-
);
|
|
14000
|
-
missingPackages.forEach((pkg) => {
|
|
14001
|
-
error(` "${pkg}"`);
|
|
14002
|
-
});
|
|
14003
|
-
error(" Or ensure that:");
|
|
14004
|
-
error(" - The package slug exists and is correctly spelled");
|
|
14005
|
-
error(" - The package exists in your organization");
|
|
14006
|
-
error(" - You have the correct API key configured");
|
|
14007
|
-
} else {
|
|
14008
|
-
error("\n\u{1F4A1} Troubleshooting tips:");
|
|
14009
|
-
error(
|
|
14010
|
-
" - Check if the package slug exists and is correctly spelled"
|
|
14011
|
-
);
|
|
14012
|
-
error(" - Check that the package exists in your organization");
|
|
14013
|
-
error(" - Ensure you have the correct API key configured");
|
|
14014
|
-
}
|
|
14015
|
-
} else {
|
|
14016
|
-
error("\n\u{1F4A1} Troubleshooting tips:");
|
|
14017
|
-
error(
|
|
14018
|
-
" - Check if the package slug exists and is correctly spelled"
|
|
14019
|
-
);
|
|
14020
|
-
error(" - Check that the package exists in your organization");
|
|
14021
|
-
error(" - Ensure you have the correct API key configured");
|
|
14022
|
-
}
|
|
14023
|
-
} else {
|
|
14024
|
-
error(` ${errorObj.message}`);
|
|
14025
|
-
const apiErrorObj = err;
|
|
14026
|
-
if (apiErrorObj.response?.data?.message) {
|
|
14027
|
-
error(`
|
|
14028
|
-
Details: ${apiErrorObj.response.data.message}`);
|
|
14029
|
-
}
|
|
14030
|
-
error("\n\u{1F4A1} Troubleshooting tips:");
|
|
14031
|
-
error(" - Verify that the package slugs are correct");
|
|
14032
|
-
error(" - Check that the packages exist in your organization");
|
|
14033
|
-
error(" - Ensure you have the correct API key configured");
|
|
14034
|
-
}
|
|
14035
|
-
} else {
|
|
14036
|
-
error(` ${String(err)}`);
|
|
14037
|
-
}
|
|
14038
|
-
exit(1);
|
|
14039
|
-
return {
|
|
14040
|
-
filesCreated: 0,
|
|
14041
|
-
filesUpdated: 0,
|
|
14042
|
-
filesDeleted: 0,
|
|
14043
|
-
notificationSent: false
|
|
14044
|
-
};
|
|
14320
|
+
} catch {
|
|
14045
14321
|
}
|
|
14046
14322
|
}
|
|
14047
|
-
async function
|
|
14048
|
-
|
|
14049
|
-
|
|
14050
|
-
|
|
14051
|
-
|
|
14052
|
-
|
|
14053
|
-
|
|
14054
|
-
|
|
14055
|
-
|
|
14056
|
-
|
|
14057
|
-
|
|
14058
|
-
log(" packmind-cli uninstall backend");
|
|
14059
|
-
log(" packmind-cli remove backend frontend");
|
|
14060
|
-
exit(1);
|
|
14061
|
-
return {
|
|
14062
|
-
filesDeleted: 0,
|
|
14063
|
-
packagesUninstalled: []
|
|
14064
|
-
};
|
|
14065
|
-
}
|
|
14066
|
-
let configPackages;
|
|
14067
|
-
let configAgents;
|
|
14068
|
-
let configFileExists = false;
|
|
14069
|
-
try {
|
|
14070
|
-
configFileExists = await packmindCliHexa.configExists(cwd);
|
|
14071
|
-
const fullConfig = await packmindCliHexa.readFullConfig(cwd);
|
|
14072
|
-
if (fullConfig) {
|
|
14073
|
-
configPackages = fullConfig.packages;
|
|
14074
|
-
configAgents = fullConfig.agents;
|
|
14075
|
-
} else {
|
|
14076
|
-
configPackages = {};
|
|
14077
|
-
}
|
|
14078
|
-
} catch (err) {
|
|
14079
|
-
error("\u274C Failed to read packmind.json");
|
|
14080
|
-
if (err instanceof Error) {
|
|
14081
|
-
error(` ${err.message}`);
|
|
14082
|
-
} else {
|
|
14083
|
-
error(` ${String(err)}`);
|
|
14084
|
-
}
|
|
14085
|
-
error("\n\u{1F4A1} Please fix the packmind.json file or delete it to continue.");
|
|
14086
|
-
exit(1);
|
|
14087
|
-
return {
|
|
14088
|
-
filesDeleted: 0,
|
|
14089
|
-
packagesUninstalled: []
|
|
14090
|
-
};
|
|
14091
|
-
}
|
|
14092
|
-
if (Object.keys(configPackages).length === 0) {
|
|
14093
|
-
if (configFileExists) {
|
|
14094
|
-
error("\u274C packmind.json is empty.");
|
|
14095
|
-
} else {
|
|
14096
|
-
error("\u274C No packmind.json found in current directory.");
|
|
14097
|
-
}
|
|
14098
|
-
log("");
|
|
14099
|
-
log("\u{1F4A1} There are no packages to uninstall.");
|
|
14100
|
-
log(" To install packages, run: packmind-cli install <package-slug>");
|
|
14101
|
-
exit(1);
|
|
14102
|
-
return {
|
|
14103
|
-
filesDeleted: 0,
|
|
14104
|
-
packagesUninstalled: []
|
|
14105
|
-
};
|
|
14106
|
-
}
|
|
14107
|
-
let normalizedRequestedSlugs;
|
|
14108
|
-
let normalizedConfigSlugs;
|
|
14109
|
-
try {
|
|
14110
|
-
normalizedRequestedSlugs = await packmindCliHexa.normalizePackageSlugs(packagesSlugs);
|
|
14111
|
-
normalizedConfigSlugs = await packmindCliHexa.normalizePackageSlugs(
|
|
14112
|
-
Object.keys(configPackages)
|
|
14113
|
-
);
|
|
14114
|
-
} catch (err) {
|
|
14115
|
-
error(`\u274C ${err instanceof Error ? err.message : String(err)}`);
|
|
14116
|
-
exit(1);
|
|
14117
|
-
return {
|
|
14118
|
-
filesDeleted: 0,
|
|
14119
|
-
packagesUninstalled: []
|
|
14120
|
-
};
|
|
14121
|
-
}
|
|
14122
|
-
const normalizedToOriginalConfigKey = /* @__PURE__ */ new Map();
|
|
14123
|
-
Object.keys(configPackages).forEach((originalKey, index) => {
|
|
14124
|
-
normalizedToOriginalConfigKey.set(
|
|
14125
|
-
normalizedConfigSlugs[index],
|
|
14126
|
-
originalKey
|
|
14127
|
-
);
|
|
14128
|
-
});
|
|
14129
|
-
const packagesToUninstall = normalizedRequestedSlugs.filter((slug3) => normalizedToOriginalConfigKey.has(slug3)).map((slug3) => normalizedToOriginalConfigKey.get(slug3));
|
|
14130
|
-
const notInstalledPackages = packagesSlugs.filter(
|
|
14131
|
-
(_, i) => !normalizedToOriginalConfigKey.has(normalizedRequestedSlugs[i])
|
|
14132
|
-
);
|
|
14133
|
-
if (notInstalledPackages.length > 0) {
|
|
14134
|
-
const packageWord = notInstalledPackages.length === 1 ? "package" : "packages";
|
|
14135
|
-
log(
|
|
14136
|
-
`\u26A0\uFE0F Warning: The following ${packageWord} ${notInstalledPackages.length === 1 ? "is" : "are"} not installed:`
|
|
14137
|
-
);
|
|
14138
|
-
notInstalledPackages.forEach((pkg) => {
|
|
14139
|
-
log(` - ${pkg}`);
|
|
14140
|
-
});
|
|
14141
|
-
log("");
|
|
14142
|
-
}
|
|
14143
|
-
if (packagesToUninstall.length === 0) {
|
|
14144
|
-
error("\u274C No packages to uninstall.");
|
|
14145
|
-
exit(1);
|
|
14146
|
-
return {
|
|
14147
|
-
filesDeleted: 0,
|
|
14148
|
-
packagesUninstalled: []
|
|
14149
|
-
};
|
|
14150
|
-
}
|
|
14151
|
-
try {
|
|
14152
|
-
const packageCount = packagesToUninstall.length;
|
|
14153
|
-
const packageWord = packageCount === 1 ? "package" : "packages";
|
|
14154
|
-
log(
|
|
14155
|
-
`Uninstalling ${packageCount} ${packageWord}: ${packagesToUninstall.join(", ")}...`
|
|
14156
|
-
);
|
|
14157
|
-
const remainingPackages = Object.keys(configPackages).filter(
|
|
14158
|
-
(pkg) => !packagesToUninstall.includes(pkg)
|
|
14159
|
-
);
|
|
14160
|
-
let filesDeleted = 0;
|
|
14161
|
-
if (remainingPackages.length === 0) {
|
|
14162
|
-
log("Removing all packages and cleaning up...");
|
|
14163
|
-
const result = await packmindCliHexa.installPackages({
|
|
14164
|
-
baseDirectory: cwd,
|
|
14165
|
-
packagesSlugs: [],
|
|
14166
|
-
previousPackagesSlugs: Object.keys(configPackages),
|
|
14167
|
-
agents: configAgents
|
|
14168
|
-
});
|
|
14169
|
-
log(`
|
|
14170
|
-
removed ${result.filesDeleted} files`);
|
|
14171
|
-
if (result.errors.length > 0) {
|
|
14172
|
-
log("\n\u26A0\uFE0F Errors encountered:");
|
|
14173
|
-
result.errors.forEach((err) => {
|
|
14174
|
-
log(` - ${err}`);
|
|
14175
|
-
});
|
|
14176
|
-
exit(1);
|
|
14177
|
-
return {
|
|
14178
|
-
filesDeleted: result.filesDeleted,
|
|
14179
|
-
packagesUninstalled: packagesToUninstall
|
|
14180
|
-
};
|
|
14181
|
-
}
|
|
14182
|
-
filesDeleted = result.filesDeleted;
|
|
14183
|
-
} else {
|
|
14184
|
-
const result = await packmindCliHexa.installPackages({
|
|
14185
|
-
baseDirectory: cwd,
|
|
14186
|
-
packagesSlugs: remainingPackages,
|
|
14187
|
-
previousPackagesSlugs: Object.keys(configPackages),
|
|
14188
|
-
agents: configAgents
|
|
14189
|
-
});
|
|
14190
|
-
if (result.recipesCount > 0 || result.standardsCount > 0) {
|
|
14191
|
-
log(
|
|
14192
|
-
`Removing ${result.recipesCount} commands and ${result.standardsCount} standards...`
|
|
14193
|
-
);
|
|
14194
|
-
}
|
|
14195
|
-
log(`
|
|
14196
|
-
removed ${result.filesDeleted} files`);
|
|
14197
|
-
if (result.errors.length > 0) {
|
|
14198
|
-
log("\n\u26A0\uFE0F Errors encountered:");
|
|
14199
|
-
result.errors.forEach((err) => {
|
|
14200
|
-
log(` - ${err}`);
|
|
14201
|
-
});
|
|
14202
|
-
exit(1);
|
|
14203
|
-
return {
|
|
14204
|
-
filesDeleted: result.filesDeleted,
|
|
14205
|
-
packagesUninstalled: packagesToUninstall
|
|
14206
|
-
};
|
|
14207
|
-
}
|
|
14208
|
-
filesDeleted = result.filesDeleted;
|
|
14209
|
-
}
|
|
14210
|
-
await packmindCliHexa.writeConfig(cwd, remainingPackages);
|
|
14211
|
-
await notifyDistributionIfInGitRepo({
|
|
14323
|
+
async function installHandler({
|
|
14324
|
+
installPath,
|
|
14325
|
+
packages,
|
|
14326
|
+
list,
|
|
14327
|
+
show,
|
|
14328
|
+
status
|
|
14329
|
+
}) {
|
|
14330
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
14331
|
+
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
14332
|
+
if (status) {
|
|
14333
|
+
const deps = {
|
|
14212
14334
|
packmindCliHexa,
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
log
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
|
|
14219
|
-
|
|
14220
|
-
} else {
|
|
14221
|
-
log(`\u2713 ${packagesToUninstall.length} packages have been uninstalled.`);
|
|
14222
|
-
}
|
|
14223
|
-
if (remainingPackages.length === 0) {
|
|
14224
|
-
log("");
|
|
14225
|
-
log("\u{1F4A1} All packages have been uninstalled.");
|
|
14226
|
-
log(" Your packmind.json still exists but contains no packages.");
|
|
14227
|
-
}
|
|
14228
|
-
return {
|
|
14229
|
-
filesDeleted,
|
|
14230
|
-
packagesUninstalled: packagesToUninstall
|
|
14231
|
-
};
|
|
14232
|
-
} catch (err) {
|
|
14233
|
-
error("\n\u274C Failed to uninstall packages:");
|
|
14234
|
-
if (err instanceof Error) {
|
|
14235
|
-
error(` ${err.message}`);
|
|
14236
|
-
} else {
|
|
14237
|
-
error(` ${String(err)}`);
|
|
14238
|
-
}
|
|
14239
|
-
exit(1);
|
|
14240
|
-
return {
|
|
14241
|
-
filesDeleted: 0,
|
|
14242
|
-
packagesUninstalled: []
|
|
14243
|
-
};
|
|
14244
|
-
}
|
|
14245
|
-
}
|
|
14246
|
-
async function recursiveInstallHandler(args2, deps) {
|
|
14247
|
-
const { packmindCliHexa, exit, getCwd, log, error } = deps;
|
|
14248
|
-
const cwd = getCwd();
|
|
14249
|
-
const result = {
|
|
14250
|
-
directoriesProcessed: 0,
|
|
14251
|
-
totalFilesCreated: 0,
|
|
14252
|
-
totalFilesUpdated: 0,
|
|
14253
|
-
totalFilesDeleted: 0,
|
|
14254
|
-
totalNotifications: 0,
|
|
14255
|
-
errors: []
|
|
14256
|
-
};
|
|
14257
|
-
let startDirectory = cwd;
|
|
14258
|
-
if (args2.path) {
|
|
14259
|
-
const resolvedPath = path19.resolve(cwd, args2.path);
|
|
14260
|
-
try {
|
|
14261
|
-
const stat9 = await fs17.stat(resolvedPath);
|
|
14262
|
-
if (!stat9.isDirectory()) {
|
|
14263
|
-
logErrorConsole(`Path is not a directory: ${resolvedPath}`);
|
|
14264
|
-
exit(1);
|
|
14265
|
-
return result;
|
|
14266
|
-
}
|
|
14267
|
-
startDirectory = resolvedPath;
|
|
14268
|
-
} catch {
|
|
14269
|
-
logErrorConsole(`Path does not exist: ${resolvedPath}`);
|
|
14270
|
-
exit(1);
|
|
14271
|
-
return result;
|
|
14272
|
-
}
|
|
14273
|
-
}
|
|
14274
|
-
try {
|
|
14275
|
-
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
14276
|
-
const basePath = args2.path ? startDirectory : gitRoot ?? cwd;
|
|
14277
|
-
const allConfigs = await packmindCliHexa.findAllConfigsInTree(
|
|
14278
|
-
startDirectory,
|
|
14279
|
-
basePath
|
|
14280
|
-
);
|
|
14281
|
-
if (!allConfigs.hasConfigs) {
|
|
14282
|
-
log("No packmind.json files found in this repository.");
|
|
14283
|
-
log("");
|
|
14284
|
-
log("Usage: packmind-cli install");
|
|
14285
|
-
log("");
|
|
14286
|
-
log(
|
|
14287
|
-
"This command requires at least one packmind.json file in the repository."
|
|
14288
|
-
);
|
|
14289
|
-
log("Create a packmind.json file first:");
|
|
14290
|
-
log("");
|
|
14291
|
-
log(" packmind-cli install <package-slug>");
|
|
14292
|
-
exit(0);
|
|
14293
|
-
return result;
|
|
14294
|
-
}
|
|
14295
|
-
const sortedConfigs = [...allConfigs.configs].sort(
|
|
14296
|
-
(a, b) => a.targetPath.localeCompare(b.targetPath)
|
|
14297
|
-
);
|
|
14298
|
-
log(`Found ${sortedConfigs.length} packmind.json file(s) to process
|
|
14299
|
-
`);
|
|
14300
|
-
for (const config of sortedConfigs) {
|
|
14301
|
-
const displayPath = args2.path ? computeDisplayPath(
|
|
14302
|
-
config.absoluteTargetPath === cwd ? "/" : config.absoluteTargetPath.startsWith(cwd + "/") ? config.absoluteTargetPath.slice(cwd.length) : config.targetPath
|
|
14303
|
-
) : computeDisplayPath(config.targetPath);
|
|
14304
|
-
log(`Installing in ${displayPath}...`);
|
|
14305
|
-
const installResult = await executeInstallForDirectory(
|
|
14306
|
-
config.absoluteTargetPath,
|
|
14307
|
-
{ packmindCliHexa, getCwd, log, error }
|
|
14308
|
-
);
|
|
14309
|
-
result.directoriesProcessed++;
|
|
14310
|
-
result.totalFilesCreated += installResult.filesCreated;
|
|
14311
|
-
result.totalFilesUpdated += installResult.filesUpdated;
|
|
14312
|
-
result.totalFilesDeleted += installResult.filesDeleted;
|
|
14313
|
-
if (installResult.notificationSent) {
|
|
14314
|
-
result.totalNotifications++;
|
|
14315
|
-
}
|
|
14316
|
-
if (!installResult.success && installResult.errorMessage) {
|
|
14317
|
-
result.errors.push({
|
|
14318
|
-
directory: displayPath,
|
|
14319
|
-
message: installResult.errorMessage
|
|
14320
|
-
});
|
|
14321
|
-
error(` Error: ${installResult.errorMessage}`);
|
|
14322
|
-
}
|
|
14323
|
-
log("");
|
|
14324
|
-
}
|
|
14325
|
-
const dirWord = result.directoriesProcessed === 1 ? "directory" : "directories";
|
|
14326
|
-
log(
|
|
14327
|
-
`Summary: ${result.directoriesProcessed} ${dirWord} processed, ${result.totalFilesCreated} files added, ${result.totalFilesUpdated} changed, ${result.totalFilesDeleted} removed`
|
|
14328
|
-
);
|
|
14329
|
-
if (result.totalNotifications > 0) {
|
|
14330
|
-
const distWord = result.totalNotifications === 1 ? "distribution" : "distributions";
|
|
14331
|
-
log(`Notified Packmind of ${result.totalNotifications} ${distWord}`);
|
|
14332
|
-
}
|
|
14333
|
-
if (result.errors.length > 0) {
|
|
14334
|
-
log("");
|
|
14335
|
-
log(`\u26A0\uFE0F ${result.errors.length} error(s) encountered:`);
|
|
14336
|
-
result.errors.forEach((err) => {
|
|
14337
|
-
log(` - ${err.directory}: ${err.message}`);
|
|
14338
|
-
});
|
|
14339
|
-
exit(1);
|
|
14340
|
-
return result;
|
|
14341
|
-
}
|
|
14342
|
-
if (deps.playbookLocalRepository) {
|
|
14343
|
-
deps.playbookLocalRepository.clearAll();
|
|
14344
|
-
}
|
|
14345
|
-
exit(0);
|
|
14346
|
-
return result;
|
|
14347
|
-
} catch (err) {
|
|
14348
|
-
error("\n\u274C Failed to run recursive install:");
|
|
14349
|
-
if (err instanceof Error) {
|
|
14350
|
-
error(` ${err.message}`);
|
|
14351
|
-
} else {
|
|
14352
|
-
error(` ${String(err)}`);
|
|
14353
|
-
}
|
|
14354
|
-
exit(1);
|
|
14355
|
-
return result;
|
|
14356
|
-
}
|
|
14357
|
-
}
|
|
14358
|
-
|
|
14359
|
-
// apps/cli/src/infra/utils/spaceFilterUtils.ts
|
|
14360
|
-
function resolveSpaceFromArgs(spaceArg, spaces) {
|
|
14361
|
-
if (!spaceArg) return null;
|
|
14362
|
-
const slug3 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
|
|
14363
|
-
return spaces.find((s) => s.slug === slug3) ?? null;
|
|
14364
|
-
}
|
|
14365
|
-
|
|
14366
|
-
// apps/cli/src/infra/utils/urlBuilderUtils.ts
|
|
14367
|
-
function resolveUrlBuilder(buildArtifactPath) {
|
|
14368
|
-
const apiKey = loadApiKey();
|
|
14369
|
-
if (!apiKey) return () => null;
|
|
14370
|
-
const decoded = decodeApiKey(apiKey);
|
|
14371
|
-
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
14372
|
-
if (!decoded?.host || !orgSlug) return () => null;
|
|
14373
|
-
return (spaceSlug, artifactId) => `${decoded.host}/org/${orgSlug}/space/${spaceSlug}/${buildArtifactPath(artifactId)}`;
|
|
14374
|
-
}
|
|
14375
|
-
|
|
14376
|
-
// apps/cli/src/infra/commands/packages/listPackagesHandler.ts
|
|
14377
|
-
function logPackageEntry(pkg, fullSlug, spaceSlug, buildUrl) {
|
|
14378
|
-
logConsole(`- ${formatSlug(fullSlug)}`);
|
|
14379
|
-
logConsole(` ${formatLabel("Name:")} ${pkg.name}`);
|
|
14380
|
-
const url = buildUrl(spaceSlug, pkg.id);
|
|
14381
|
-
if (url) {
|
|
14382
|
-
logConsole(` ${formatLabel("Link:")} ${url}`);
|
|
14383
|
-
}
|
|
14384
|
-
if (pkg.description) {
|
|
14385
|
-
const lines = pkg.description.trim().split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
14386
|
-
const [first, ...rest] = lines;
|
|
14387
|
-
logConsole(` ${formatLabel("Description:")} ${first}`);
|
|
14388
|
-
rest.forEach((l) => logConsole(` ${l}`));
|
|
14389
|
-
}
|
|
14390
|
-
}
|
|
14391
|
-
function groupPackagesBySpace(packages, spaces) {
|
|
14392
|
-
const spaceMap = new Map(
|
|
14393
|
-
spaces.map((s) => [s.id, s])
|
|
14394
|
-
);
|
|
14395
|
-
const groupsMap = /* @__PURE__ */ new Map();
|
|
14396
|
-
for (const pkg of packages) {
|
|
14397
|
-
const space = spaceMap.get(pkg.spaceId);
|
|
14398
|
-
if (!space) {
|
|
14399
|
-
continue;
|
|
14400
|
-
}
|
|
14401
|
-
let group = groupsMap.get(space.id);
|
|
14402
|
-
if (!group) {
|
|
14403
|
-
group = { space, pkgs: [] };
|
|
14404
|
-
groupsMap.set(space.id, group);
|
|
14405
|
-
}
|
|
14406
|
-
group.pkgs.push(pkg);
|
|
14407
|
-
}
|
|
14408
|
-
return [...groupsMap.values()].sort(
|
|
14409
|
-
(a, b) => a.space.name.localeCompare(b.space.name)
|
|
14410
|
-
);
|
|
14411
|
-
}
|
|
14412
|
-
function displayGroupedPackages(packages, spaces, buildUrl) {
|
|
14413
|
-
const groups = groupPackagesBySpace(packages, spaces);
|
|
14414
|
-
let firstSlug = null;
|
|
14415
|
-
for (const { space, pkgs } of groups) {
|
|
14416
|
-
logConsole(`Space "${space.name}":
|
|
14417
|
-
`);
|
|
14418
|
-
for (const pkg of [...pkgs].sort((a, b) => a.slug.localeCompare(b.slug))) {
|
|
14419
|
-
const fullSlug = `@${space.slug}/${pkg.slug}`;
|
|
14420
|
-
firstSlug ??= fullSlug;
|
|
14421
|
-
logPackageEntry(pkg, fullSlug, space.slug, buildUrl);
|
|
14422
|
-
logConsole("");
|
|
14423
|
-
}
|
|
14424
|
-
}
|
|
14425
|
-
return firstSlug ?? formatSlug(packages[0].slug);
|
|
14426
|
-
}
|
|
14427
|
-
async function listPackagesHandler(args2, deps) {
|
|
14428
|
-
const { packmindCliHexa, exit } = deps;
|
|
14429
|
-
try {
|
|
14430
|
-
logInfoConsole("Fetching available packages...");
|
|
14431
|
-
const allSpaces = await packmindCliHexa.getSpaces();
|
|
14432
|
-
if (!allSpaces || allSpaces.length === 0) {
|
|
14433
|
-
throw new Error("Unable to list organization spaces.");
|
|
14434
|
-
}
|
|
14435
|
-
const matchedSpace = resolveSpaceFromArgs(args2.space, allSpaces);
|
|
14436
|
-
if (args2.space && !matchedSpace) {
|
|
14437
|
-
logErrorConsole(`Space "@${args2.space}" not found.`);
|
|
14438
|
-
logInfoConsole(
|
|
14439
|
-
`Available spaces: ${allSpaces.map((s) => `@${s.slug}`).join(", ")}`
|
|
14440
|
-
);
|
|
14441
|
-
exit(1);
|
|
14442
|
-
return;
|
|
14443
|
-
}
|
|
14444
|
-
const packages = await packmindCliHexa.listPackages(
|
|
14445
|
-
matchedSpace ? { spaceId: matchedSpace.id } : {}
|
|
14446
|
-
);
|
|
14447
|
-
const spaces = matchedSpace ? [matchedSpace] : allSpaces;
|
|
14448
|
-
if (packages.length === 0) {
|
|
14449
|
-
logConsole(
|
|
14450
|
-
matchedSpace ? `No packages found in space "@${matchedSpace.slug}".` : "No packages found."
|
|
14451
|
-
);
|
|
14452
|
-
exit(0);
|
|
14453
|
-
return;
|
|
14454
|
-
}
|
|
14455
|
-
const buildUrl = resolveUrlBuilder((id) => `packages/${id}`);
|
|
14456
|
-
logConsole("\nAvailable packages:\n");
|
|
14457
|
-
const exampleSlug = displayGroupedPackages(packages, spaces, buildUrl);
|
|
14458
|
-
logConsole("How to install a package:\n");
|
|
14459
|
-
logConsole(` ${formatCommand(`packmind-cli install ${exampleSlug}`)}`);
|
|
14460
|
-
exit(0);
|
|
14461
|
-
} catch (err) {
|
|
14462
|
-
logErrorConsole("Failed to list packages:");
|
|
14463
|
-
if (err instanceof Error) {
|
|
14464
|
-
logErrorConsole(err.message);
|
|
14465
|
-
} else {
|
|
14466
|
-
logErrorConsole(String(err));
|
|
14467
|
-
}
|
|
14468
|
-
exit(1);
|
|
14469
|
-
}
|
|
14470
|
-
}
|
|
14471
|
-
|
|
14472
|
-
// apps/cli/src/infra/utils/packageSlugUtils.ts
|
|
14473
|
-
function parsePackageSlug(slug3) {
|
|
14474
|
-
if (!slug3.startsWith("@")) return null;
|
|
14475
|
-
const slash = slug3.indexOf("/", 1);
|
|
14476
|
-
if (slash === -1) return null;
|
|
14477
|
-
return { spaceSlug: slug3.slice(1, slash), pkgSlug: slug3.slice(slash + 1) };
|
|
14478
|
-
}
|
|
14479
|
-
|
|
14480
|
-
// apps/cli/src/infra/commands/packages/showPackageHandler.ts
|
|
14481
|
-
function isNotFoundError(err) {
|
|
14482
|
-
return err instanceof Error && err.message.includes("does not exist");
|
|
14483
|
-
}
|
|
14484
|
-
async function resolvePackage(slug3, packmindCliHexa) {
|
|
14485
|
-
const allSpaces = await packmindCliHexa.getSpaces();
|
|
14486
|
-
const parsed = parsePackageSlug(slug3);
|
|
14487
|
-
if (parsed) {
|
|
14488
|
-
const { spaceSlug, pkgSlug } = parsed;
|
|
14489
|
-
const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
|
|
14490
|
-
if (!matchedSpace) {
|
|
14491
|
-
throw new Error(`Space '@${spaceSlug}' not found.`);
|
|
14492
|
-
}
|
|
14493
|
-
let pkg;
|
|
14494
|
-
try {
|
|
14495
|
-
pkg = await packmindCliHexa.getPackageBySlug({
|
|
14496
|
-
slug: pkgSlug,
|
|
14497
|
-
spaceId: matchedSpace.id
|
|
14498
|
-
});
|
|
14499
|
-
} catch (err) {
|
|
14500
|
-
if (isNotFoundError(err)) {
|
|
14501
|
-
throw new Error(
|
|
14502
|
-
`Package '${pkgSlug}' not found in space '@${spaceSlug}'.`
|
|
14503
|
-
);
|
|
14504
|
-
}
|
|
14505
|
-
throw err;
|
|
14506
|
-
}
|
|
14507
|
-
return { pkg, fullSlug: `@${spaceSlug}/${pkgSlug}` };
|
|
14508
|
-
}
|
|
14509
|
-
const results = await Promise.allSettled(
|
|
14510
|
-
allSpaces.map(async (space) => ({
|
|
14511
|
-
pkg: await packmindCliHexa.getPackageBySlug({
|
|
14512
|
-
slug: slug3,
|
|
14513
|
-
spaceId: space.id
|
|
14514
|
-
}),
|
|
14515
|
-
spaceSlug: space.slug
|
|
14516
|
-
}))
|
|
14517
|
-
);
|
|
14518
|
-
const matches = results.filter(
|
|
14519
|
-
(r) => r.status === "fulfilled"
|
|
14520
|
-
).map((r) => r.value);
|
|
14521
|
-
if (matches.length === 0) {
|
|
14522
|
-
const realError = results.filter((r) => r.status === "rejected").find((r) => !isNotFoundError(r.reason));
|
|
14523
|
-
if (realError) {
|
|
14524
|
-
throw realError.reason;
|
|
14525
|
-
}
|
|
14526
|
-
throw new Error(`Package '${slug3}' not found in any space.`);
|
|
14527
|
-
}
|
|
14528
|
-
if (matches.length > 1) {
|
|
14529
|
-
const example = `@${matches[0].spaceSlug}/${slug3}`;
|
|
14530
|
-
throw new Error(
|
|
14531
|
-
`Package '${slug3}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
|
|
14532
|
-
);
|
|
14533
|
-
}
|
|
14534
|
-
return {
|
|
14535
|
-
pkg: matches[0].pkg,
|
|
14536
|
-
fullSlug: `@${matches[0].spaceSlug}/${slug3}`
|
|
14537
|
-
};
|
|
14538
|
-
}
|
|
14539
|
-
async function showPackageHandler(args2, deps) {
|
|
14540
|
-
const { packmindCliHexa, exit } = deps;
|
|
14541
|
-
try {
|
|
14542
|
-
logInfoConsole(`Fetching package details for '${args2.slug}'...`);
|
|
14543
|
-
const { pkg, fullSlug } = await resolvePackage(args2.slug, packmindCliHexa);
|
|
14544
|
-
logConsole(`
|
|
14545
|
-
${pkg.name} (${fullSlug}):
|
|
14546
|
-
`);
|
|
14547
|
-
if (pkg.description) {
|
|
14548
|
-
logConsole(`${pkg.description}
|
|
14549
|
-
`);
|
|
14550
|
-
}
|
|
14551
|
-
if (pkg.standards && pkg.standards.length > 0) {
|
|
14552
|
-
logConsole("Standards:");
|
|
14553
|
-
pkg.standards.forEach((standard) => {
|
|
14554
|
-
if (standard.summary) {
|
|
14555
|
-
logConsole(` - ${standard.name}: ${standard.summary}`);
|
|
14556
|
-
} else {
|
|
14557
|
-
logConsole(` - ${standard.name}`);
|
|
14558
|
-
}
|
|
14559
|
-
});
|
|
14560
|
-
logConsole("");
|
|
14561
|
-
}
|
|
14562
|
-
if (pkg.recipes && pkg.recipes.length > 0) {
|
|
14563
|
-
logConsole("Commands:");
|
|
14564
|
-
pkg.recipes.forEach((recipe) => {
|
|
14565
|
-
if (recipe.summary) {
|
|
14566
|
-
logConsole(` - ${recipe.name}: ${recipe.summary}`);
|
|
14567
|
-
} else {
|
|
14568
|
-
logConsole(` - ${recipe.name}`);
|
|
14569
|
-
}
|
|
14570
|
-
});
|
|
14571
|
-
logConsole("");
|
|
14572
|
-
}
|
|
14573
|
-
if (pkg.skills && pkg.skills.length > 0) {
|
|
14574
|
-
logConsole("Skills:");
|
|
14575
|
-
pkg.skills.forEach((skill) => {
|
|
14576
|
-
if (skill.summary) {
|
|
14577
|
-
logConsole(` - ${skill.name}: ${skill.summary}`);
|
|
14578
|
-
} else {
|
|
14579
|
-
logConsole(` - ${skill.name}`);
|
|
14580
|
-
}
|
|
14581
|
-
});
|
|
14582
|
-
logConsole("");
|
|
14583
|
-
}
|
|
14584
|
-
exit(0);
|
|
14585
|
-
} catch (err) {
|
|
14586
|
-
logErrorConsole("Failed to fetch package details:");
|
|
14587
|
-
if (err instanceof Error) {
|
|
14588
|
-
logErrorConsole(err.message);
|
|
14589
|
-
} else {
|
|
14590
|
-
logErrorConsole(String(err));
|
|
14591
|
-
}
|
|
14592
|
-
exit(1);
|
|
14593
|
-
}
|
|
14594
|
-
}
|
|
14595
|
-
|
|
14596
|
-
// apps/cli/src/infra/repositories/PlaybookLocalRepository.ts
|
|
14597
|
-
var crypto = __toESM(require("crypto"));
|
|
14598
|
-
var fs18 = __toESM(require("fs"));
|
|
14599
|
-
var os4 = __toESM(require("os"));
|
|
14600
|
-
var path20 = __toESM(require("path"));
|
|
14601
|
-
var yaml = __toESM(require("yaml"));
|
|
14602
|
-
var PlaybookLocalRepository = class {
|
|
14603
|
-
constructor(repoRoot) {
|
|
14604
|
-
const normalized = this.normalizeRepoRoot(repoRoot);
|
|
14605
|
-
const hash = crypto.createHash("md5").update(normalized).digest("hex");
|
|
14606
|
-
this.storagePath = path20.join(
|
|
14607
|
-
os4.homedir(),
|
|
14608
|
-
".packmind",
|
|
14609
|
-
hash,
|
|
14610
|
-
"playbook.yaml"
|
|
14611
|
-
);
|
|
14612
|
-
}
|
|
14613
|
-
addChange(entry) {
|
|
14614
|
-
const data = this.readYaml();
|
|
14615
|
-
const existingIndex = data.changes.findIndex(
|
|
14616
|
-
(c) => c.filePath === entry.filePath && c.spaceId === entry.spaceId
|
|
14617
|
-
);
|
|
14618
|
-
if (existingIndex >= 0) {
|
|
14619
|
-
data.changes[existingIndex] = entry;
|
|
14620
|
-
} else {
|
|
14621
|
-
data.changes.push(entry);
|
|
14622
|
-
}
|
|
14623
|
-
this.writeYaml(data);
|
|
14624
|
-
}
|
|
14625
|
-
removeChange(filePath, spaceId) {
|
|
14626
|
-
const data = this.readYaml();
|
|
14627
|
-
const initialLength = data.changes.length;
|
|
14628
|
-
data.changes = data.changes.filter(
|
|
14629
|
-
(c) => !(c.filePath === filePath && c.spaceId === spaceId)
|
|
14630
|
-
);
|
|
14631
|
-
if (data.changes.length === initialLength) {
|
|
14632
|
-
return false;
|
|
14633
|
-
}
|
|
14634
|
-
this.writeYaml(data);
|
|
14635
|
-
return true;
|
|
14636
|
-
}
|
|
14637
|
-
getChanges() {
|
|
14638
|
-
return this.readYaml().changes;
|
|
14335
|
+
exit: process.exit,
|
|
14336
|
+
getCwd: () => process.cwd(),
|
|
14337
|
+
log: console.log,
|
|
14338
|
+
error: console.error
|
|
14339
|
+
};
|
|
14340
|
+
await statusHandler({}, deps);
|
|
14341
|
+
return;
|
|
14639
14342
|
}
|
|
14640
|
-
|
|
14641
|
-
|
|
14642
|
-
|
|
14643
|
-
)
|
|
14343
|
+
if (list) {
|
|
14344
|
+
logErrorConsole('Command "packmind-cli install --list" has been removed.');
|
|
14345
|
+
logConsole(`Use ${formatCommand("packmind-cli packages list")} instead.`);
|
|
14346
|
+
process.exit(1);
|
|
14644
14347
|
}
|
|
14645
|
-
|
|
14646
|
-
|
|
14348
|
+
if (show) {
|
|
14349
|
+
const showCommand = `packmind-cli packages show ${show}`;
|
|
14350
|
+
logErrorConsole('Command "packmind-cli install --show" has been removed.');
|
|
14351
|
+
logConsole(`Use ${formatCommand(showCommand)} instead.`);
|
|
14352
|
+
process.exit(1);
|
|
14647
14353
|
}
|
|
14648
|
-
|
|
14649
|
-
|
|
14650
|
-
|
|
14651
|
-
|
|
14354
|
+
const cwd = installPath ? path20.resolve(process.cwd(), installPath) : process.cwd();
|
|
14355
|
+
if (installPath) {
|
|
14356
|
+
if (!fs18.existsSync(cwd)) {
|
|
14357
|
+
logErrorConsole(`Path does not exist: ${cwd}`);
|
|
14358
|
+
process.exit(1);
|
|
14359
|
+
return;
|
|
14360
|
+
}
|
|
14361
|
+
if (!fs18.statSync(cwd).isDirectory()) {
|
|
14362
|
+
logErrorConsole(`Path is not a directory: ${cwd}`);
|
|
14363
|
+
process.exit(1);
|
|
14364
|
+
return;
|
|
14365
|
+
}
|
|
14652
14366
|
}
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
|
|
14367
|
+
let targetDirs;
|
|
14368
|
+
if (installPath) {
|
|
14369
|
+
targetDirs = findSubDirectoriesWithPackmindJson(cwd, false);
|
|
14370
|
+
} else if (packages.length > 0) {
|
|
14371
|
+
targetDirs = [cwd];
|
|
14372
|
+
} else {
|
|
14373
|
+
targetDirs = [];
|
|
14374
|
+
if (fs18.existsSync(path20.join(cwd, "packmind.json"))) {
|
|
14375
|
+
targetDirs.push(cwd);
|
|
14656
14376
|
}
|
|
14377
|
+
targetDirs.push(...findSubDirectoriesWithPackmindJson(cwd, true));
|
|
14378
|
+
}
|
|
14379
|
+
if (targetDirs.length === 0) {
|
|
14380
|
+
targetDirs = [cwd];
|
|
14381
|
+
}
|
|
14382
|
+
const results = [];
|
|
14383
|
+
const thrownErrors = [];
|
|
14384
|
+
const multiDir = targetDirs.length > 1;
|
|
14385
|
+
for (const dir of targetDirs) {
|
|
14657
14386
|
try {
|
|
14658
|
-
const
|
|
14659
|
-
|
|
14660
|
-
|
|
14661
|
-
|
|
14662
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
14666
|
-
|
|
14387
|
+
const result = await packmindCliHexa.install({
|
|
14388
|
+
baseDirectory: dir,
|
|
14389
|
+
packages: packages.length > 0 ? packages : void 0
|
|
14390
|
+
});
|
|
14391
|
+
results.push(result);
|
|
14392
|
+
await notifyArtefactsDistributionIfInGitRepo({
|
|
14393
|
+
packmindCliHexa,
|
|
14394
|
+
dir
|
|
14395
|
+
});
|
|
14396
|
+
} catch (error) {
|
|
14397
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14398
|
+
thrownErrors.push(
|
|
14399
|
+
multiDir ? `[${dir}] install failed: ${errorMessage}` : `install failed: ${errorMessage}`
|
|
14667
14400
|
);
|
|
14668
|
-
return { version: 1, changes: [] };
|
|
14669
14401
|
}
|
|
14670
14402
|
}
|
|
14671
|
-
|
|
14672
|
-
|
|
14673
|
-
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
|
|
14403
|
+
const combined = mergeInstallResults(results);
|
|
14404
|
+
if (combined.missingAccess.length > 0) {
|
|
14405
|
+
let warning = `\u26A0\uFE0F You don't have access to the following packages (their artifacts were preserved from the lock file):
|
|
14406
|
+
` + combined.missingAccess.map((s) => ` - ${s}`).join("\n");
|
|
14407
|
+
if (combined.joinSpaceUrl) {
|
|
14408
|
+
warning += `
|
|
14677
14409
|
|
|
14678
|
-
|
|
14410
|
+
\u{1F449} Join the space to get access: ${combined.joinSpaceUrl}`;
|
|
14411
|
+
}
|
|
14412
|
+
logWarningConsole(warning);
|
|
14413
|
+
}
|
|
14414
|
+
logConsole(buildInstallSummary(combined));
|
|
14415
|
+
const allErrors = [...combined.errors, ...thrownErrors];
|
|
14416
|
+
if (allErrors.length > 0) {
|
|
14417
|
+
logWarningConsole(`Encountered ${allErrors.length} error(s):`);
|
|
14418
|
+
allErrors.forEach((err) => logErrorConsole(` - ${err}`));
|
|
14419
|
+
}
|
|
14420
|
+
if (thrownErrors.length > 0) {
|
|
14421
|
+
process.exit(1);
|
|
14422
|
+
}
|
|
14423
|
+
}
|
|
14679
14424
|
var installCommand = (0, import_cmd_ts2.command)({
|
|
14680
14425
|
name: "install",
|
|
14681
|
-
description: "Install packages and save their artifacts locally",
|
|
14682
14426
|
aliases: ["pull"],
|
|
14427
|
+
description: "Install packages and save their artifacts locally",
|
|
14683
14428
|
args: {
|
|
14684
|
-
|
|
14685
|
-
|
|
14686
|
-
|
|
14429
|
+
installPath: (0, import_cmd_ts2.option)({
|
|
14430
|
+
type: import_cmd_ts2.string,
|
|
14431
|
+
short: "p",
|
|
14432
|
+
long: "path",
|
|
14433
|
+
defaultValue: () => "",
|
|
14434
|
+
description: "Run install in the specified directory instead of the current directory"
|
|
14435
|
+
}),
|
|
14436
|
+
packages: (0, import_cmd_ts2.restPositionals)({
|
|
14437
|
+
type: import_cmd_ts2.string,
|
|
14438
|
+
displayName: "packages",
|
|
14439
|
+
description: "Package slugs to install (e.g. @my-space/my-package)"
|
|
14687
14440
|
}),
|
|
14688
14441
|
status: (0, import_cmd_ts2.flag)({
|
|
14689
14442
|
long: "status",
|
|
14690
14443
|
description: "Show status of all packmind.json files and their packages in the workspace"
|
|
14691
14444
|
}),
|
|
14692
|
-
|
|
14693
|
-
|
|
14694
|
-
|
|
14695
|
-
description: "[Deprecated] Install is now recursive by default. This flag will be removed in a future version."
|
|
14696
|
-
}),
|
|
14697
|
-
path: (0, import_cmd_ts2.option)({
|
|
14698
|
-
type: import_cmd_ts2.string,
|
|
14699
|
-
short: "p",
|
|
14700
|
-
long: "path",
|
|
14701
|
-
defaultValue: () => "",
|
|
14702
|
-
description: "Run install in the specified directory (recursive within that path)"
|
|
14445
|
+
list: (0, import_cmd_ts2.flag)({
|
|
14446
|
+
long: "list",
|
|
14447
|
+
description: "[Deprecated] List available packages"
|
|
14703
14448
|
}),
|
|
14704
14449
|
show: (0, import_cmd_ts2.option)({
|
|
14705
14450
|
type: import_cmd_ts2.string,
|
|
14706
14451
|
long: "show",
|
|
14707
|
-
description: "Show details of a specific package",
|
|
14452
|
+
description: "[Deprecated] Show details of a specific package",
|
|
14708
14453
|
defaultValue: () => ""
|
|
14709
|
-
}),
|
|
14710
|
-
packagesSlugs: (0, import_cmd_ts2.restPositionals)({
|
|
14711
|
-
type: import_cmd_ts2.string,
|
|
14712
|
-
displayName: "packages",
|
|
14713
|
-
description: "Package slugs to install (e.g., backend frontend)"
|
|
14714
14454
|
})
|
|
14715
14455
|
},
|
|
14716
|
-
handler:
|
|
14717
|
-
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
14718
|
-
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
14719
|
-
const repoRoot = await packmindCliHexa.tryGetGitRepositoryRoot(
|
|
14720
|
-
process.cwd()
|
|
14721
|
-
);
|
|
14722
|
-
const playbookLocalRepository = repoRoot ? new PlaybookLocalRepository(repoRoot) : void 0;
|
|
14723
|
-
const deps = {
|
|
14724
|
-
packmindCliHexa,
|
|
14725
|
-
exit: process.exit,
|
|
14726
|
-
getCwd: () => process.cwd(),
|
|
14727
|
-
log: console.log,
|
|
14728
|
-
error: console.error,
|
|
14729
|
-
playbookLocalRepository
|
|
14730
|
-
};
|
|
14731
|
-
if (list) {
|
|
14732
|
-
await listPackagesHandler({}, deps);
|
|
14733
|
-
return;
|
|
14734
|
-
}
|
|
14735
|
-
if (status) {
|
|
14736
|
-
await statusHandler({}, deps);
|
|
14737
|
-
return;
|
|
14738
|
-
}
|
|
14739
|
-
if (show) {
|
|
14740
|
-
await showPackageHandler(
|
|
14741
|
-
{ slug: show },
|
|
14742
|
-
{ packmindCliHexa, exit: process.exit }
|
|
14743
|
-
);
|
|
14744
|
-
return;
|
|
14745
|
-
}
|
|
14746
|
-
if (recursive) {
|
|
14747
|
-
logWarningConsole(
|
|
14748
|
-
"\u26A0\uFE0F The --recursive flag is deprecated. Install is now recursive by default."
|
|
14749
|
-
);
|
|
14750
|
-
await recursiveInstallHandler({ path: path36 || void 0 }, deps);
|
|
14751
|
-
return;
|
|
14752
|
-
}
|
|
14753
|
-
if (packagesSlugs.length > 0) {
|
|
14754
|
-
await installPackagesHandler(
|
|
14755
|
-
{ packagesSlugs, path: path36 || void 0 },
|
|
14756
|
-
deps
|
|
14757
|
-
);
|
|
14758
|
-
return;
|
|
14759
|
-
}
|
|
14760
|
-
await recursiveInstallHandler({ path: path36 || void 0 }, deps);
|
|
14761
|
-
}
|
|
14456
|
+
handler: installHandler
|
|
14762
14457
|
});
|
|
14763
14458
|
|
|
14764
14459
|
// apps/cli/src/infra/commands/UninstallCommand.ts
|
|
14765
14460
|
var import_cmd_ts3 = __toESM(require_cjs());
|
|
14461
|
+
function buildUninstallSummary(result) {
|
|
14462
|
+
const removedParts = [
|
|
14463
|
+
result.standardsRemoved > 0 ? `${result.standardsRemoved} ${result.standardsRemoved === 1 ? "standard" : "standards"}` : null,
|
|
14464
|
+
result.commandsRemoved > 0 ? `${result.commandsRemoved} ${result.commandsRemoved === 1 ? "command" : "commands"}` : null,
|
|
14465
|
+
result.skillsRemoved > 0 ? `${result.skillsRemoved} ${result.skillsRemoved === 1 ? "skill" : "skills"}` : null,
|
|
14466
|
+
result.recipesRemoved > 0 ? `${result.recipesRemoved} ${result.recipesRemoved === 1 ? "recipe" : "recipes"}` : null
|
|
14467
|
+
].filter(Boolean);
|
|
14468
|
+
if (removedParts.length === 0) {
|
|
14469
|
+
return "\u2705 Package removed";
|
|
14470
|
+
}
|
|
14471
|
+
return `\u2705 Removed ${removedParts.join(", ")}`;
|
|
14472
|
+
}
|
|
14766
14473
|
var uninstallCommand = (0, import_cmd_ts3.command)({
|
|
14767
14474
|
name: "uninstall",
|
|
14768
|
-
description: "Uninstall packages and
|
|
14475
|
+
description: "Uninstall packages and sync artifacts. Specify package slugs (e.g. @my-space/my-package) to uninstall.",
|
|
14769
14476
|
aliases: ["remove"],
|
|
14770
14477
|
args: {
|
|
14771
|
-
|
|
14478
|
+
packages: (0, import_cmd_ts3.restPositionals)({
|
|
14772
14479
|
type: import_cmd_ts3.string,
|
|
14773
14480
|
displayName: "packages",
|
|
14774
|
-
description: "Package slugs to uninstall (e.g
|
|
14481
|
+
description: "Package slugs to uninstall (e.g. @my-space/my-package)"
|
|
14775
14482
|
})
|
|
14776
14483
|
},
|
|
14777
|
-
handler: async ({
|
|
14484
|
+
handler: async ({ packages }) => {
|
|
14485
|
+
if (packages.length === 0) {
|
|
14486
|
+
logErrorConsole("Please specify at least one package to uninstall.");
|
|
14487
|
+
process.exit(1);
|
|
14488
|
+
}
|
|
14778
14489
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
14779
14490
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
14780
|
-
|
|
14781
|
-
packmindCliHexa
|
|
14782
|
-
|
|
14783
|
-
|
|
14784
|
-
|
|
14785
|
-
|
|
14786
|
-
|
|
14787
|
-
|
|
14491
|
+
try {
|
|
14492
|
+
const result = await packmindCliHexa.uninstall({
|
|
14493
|
+
baseDirectory: process.cwd(),
|
|
14494
|
+
packages
|
|
14495
|
+
});
|
|
14496
|
+
if (result.missingAccess.length > 0) {
|
|
14497
|
+
let warning = `\u26A0\uFE0F You don't have access to the following packages (their artifacts were preserved from the lock file):
|
|
14498
|
+
` + result.missingAccess.map((s) => ` - ${s}`).join("\n");
|
|
14499
|
+
if (result.joinSpaceUrl) {
|
|
14500
|
+
warning += `
|
|
14501
|
+
|
|
14502
|
+
\u{1F449} Join the space to get access: ${result.joinSpaceUrl}`;
|
|
14503
|
+
}
|
|
14504
|
+
logWarningConsole(warning);
|
|
14505
|
+
}
|
|
14506
|
+
logConsole(buildUninstallSummary(result));
|
|
14507
|
+
if (result.errors.length > 0) {
|
|
14508
|
+
logWarningConsole(`Encountered ${result.errors.length} error(s):`);
|
|
14509
|
+
result.errors.forEach((err) => logErrorConsole(` - ${err}`));
|
|
14510
|
+
}
|
|
14511
|
+
} catch (error) {
|
|
14512
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
14513
|
+
logErrorConsole(`uninstall failed: ${errorMessage}`);
|
|
14514
|
+
process.exit(1);
|
|
14515
|
+
}
|
|
14788
14516
|
}
|
|
14789
14517
|
});
|
|
14790
14518
|
|
|
@@ -14899,7 +14627,7 @@ function displayVersionNotice(result) {
|
|
|
14899
14627
|
}
|
|
14900
14628
|
|
|
14901
14629
|
// apps/cli/src/infra/commands/WhoamiCommand.ts
|
|
14902
|
-
var { version:
|
|
14630
|
+
var { version: CLI_VERSION } = require_package();
|
|
14903
14631
|
function formatExpiresAt(expiresAt) {
|
|
14904
14632
|
const now = /* @__PURE__ */ new Date();
|
|
14905
14633
|
if (expiresAt < now) {
|
|
@@ -14943,7 +14671,7 @@ var whoamiCommand = (0, import_cmd_ts6.command)({
|
|
|
14943
14671
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
14944
14672
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
14945
14673
|
const versionCheckPromise = packmindCliHexa.checkCliVersion({
|
|
14946
|
-
currentVersion:
|
|
14674
|
+
currentVersion: CLI_VERSION
|
|
14947
14675
|
});
|
|
14948
14676
|
const result = await packmindCliHexa.whoami({});
|
|
14949
14677
|
if (!result.isAuthenticated) {
|
|
@@ -14980,7 +14708,7 @@ var inquirer = __toESM(require("inquirer"));
|
|
|
14980
14708
|
// apps/cli/src/application/services/AgentDetectionService.ts
|
|
14981
14709
|
var fs19 = __toESM(require("fs"));
|
|
14982
14710
|
var path21 = __toESM(require("path"));
|
|
14983
|
-
var
|
|
14711
|
+
var os4 = __toESM(require("os"));
|
|
14984
14712
|
var import_child_process4 = require("child_process");
|
|
14985
14713
|
var AgentDetectionService = class {
|
|
14986
14714
|
constructor(projectDir = process.cwd()) {
|
|
@@ -15006,7 +14734,7 @@ var AgentDetectionService = class {
|
|
|
15006
14734
|
return this.isCommandAvailable("claude");
|
|
15007
14735
|
}
|
|
15008
14736
|
isCursorAvailable() {
|
|
15009
|
-
const cursorConfigDir = path21.join(
|
|
14737
|
+
const cursorConfigDir = path21.join(os4.homedir(), ".cursor");
|
|
15010
14738
|
return fs19.existsSync(cursorConfigDir);
|
|
15011
14739
|
}
|
|
15012
14740
|
isVSCodeAvailable() {
|
|
@@ -15073,7 +14801,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
15073
14801
|
output.write("\n");
|
|
15074
14802
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
15075
14803
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
15076
|
-
return new Promise((
|
|
14804
|
+
return new Promise((resolve15) => {
|
|
15077
14805
|
rl.question(
|
|
15078
14806
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
15079
14807
|
(answer) => {
|
|
@@ -15084,7 +14812,7 @@ async function promptAgentsWithReadline(choices) {
|
|
|
15084
14812
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
15085
14813
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
15086
14814
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
15087
|
-
|
|
14815
|
+
resolve15(selectedAgents);
|
|
15088
14816
|
}
|
|
15089
14817
|
);
|
|
15090
14818
|
});
|
|
@@ -15314,7 +15042,7 @@ async function handleIncompatibleInstalledSkills(skills, baseDirectory, confirm)
|
|
|
15314
15042
|
}
|
|
15315
15043
|
|
|
15316
15044
|
// apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
|
|
15317
|
-
var { version:
|
|
15045
|
+
var { version: CLI_VERSION2 } = require_package();
|
|
15318
15046
|
var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
|
|
15319
15047
|
name: "install-default",
|
|
15320
15048
|
description: "Install default Packmind skills for configured coding agents",
|
|
@@ -15332,7 +15060,7 @@ var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
|
|
|
15332
15060
|
const baseDirectory = process.cwd();
|
|
15333
15061
|
const result = await packmindCliHexa.installDefaultSkills({
|
|
15334
15062
|
includeBeta,
|
|
15335
|
-
cliVersion: includeBeta ? void 0 :
|
|
15063
|
+
cliVersion: includeBeta ? void 0 : CLI_VERSION2,
|
|
15336
15064
|
baseDirectory
|
|
15337
15065
|
});
|
|
15338
15066
|
if (result.skippedSkillsCount > 0) {
|
|
@@ -15393,10 +15121,10 @@ async function promptConfirmation(question) {
|
|
|
15393
15121
|
input: process.stdin,
|
|
15394
15122
|
output: process.stdout
|
|
15395
15123
|
});
|
|
15396
|
-
return new Promise((
|
|
15124
|
+
return new Promise((resolve15) => {
|
|
15397
15125
|
rl.question(question, (answer) => {
|
|
15398
15126
|
rl.close();
|
|
15399
|
-
|
|
15127
|
+
resolve15(answer.trim().toLowerCase() === "y");
|
|
15400
15128
|
});
|
|
15401
15129
|
});
|
|
15402
15130
|
}
|
|
@@ -15404,6 +15132,23 @@ async function promptConfirmation(question) {
|
|
|
15404
15132
|
// apps/cli/src/infra/commands/ListSkillsCommand.ts
|
|
15405
15133
|
var import_cmd_ts11 = __toESM(require_cjs());
|
|
15406
15134
|
|
|
15135
|
+
// apps/cli/src/infra/utils/spaceFilterUtils.ts
|
|
15136
|
+
function resolveSpaceFromArgs(spaceArg, spaces) {
|
|
15137
|
+
if (!spaceArg) return null;
|
|
15138
|
+
const slug3 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
|
|
15139
|
+
return spaces.find((s) => s.slug === slug3) ?? null;
|
|
15140
|
+
}
|
|
15141
|
+
|
|
15142
|
+
// apps/cli/src/infra/utils/urlBuilderUtils.ts
|
|
15143
|
+
function resolveUrlBuilder(buildArtifactPath) {
|
|
15144
|
+
const apiKey = loadApiKey();
|
|
15145
|
+
if (!apiKey) return () => null;
|
|
15146
|
+
const decoded = decodeApiKey(apiKey);
|
|
15147
|
+
const orgSlug = decoded?.jwt?.organization?.slug;
|
|
15148
|
+
if (!decoded?.host || !orgSlug) return () => null;
|
|
15149
|
+
return (spaceSlug, artifactId) => `${decoded.host}/org/${orgSlug}/space/${spaceSlug}/${buildArtifactPath(artifactId)}`;
|
|
15150
|
+
}
|
|
15151
|
+
|
|
15407
15152
|
// apps/cli/src/infra/commands/skills/listSkillsHandler.ts
|
|
15408
15153
|
function groupSkillsBySpace(skills, spaces) {
|
|
15409
15154
|
const spaceMap = new Map(
|
|
@@ -16011,6 +15756,21 @@ async function findTargetDirectories(searchPath, packmindCliHexa) {
|
|
|
16011
15756
|
targets.push(dir);
|
|
16012
15757
|
}
|
|
16013
15758
|
}
|
|
15759
|
+
if (targets.length === 0) {
|
|
15760
|
+
let currentDir = nodePath.dirname(searchPath);
|
|
15761
|
+
while (true) {
|
|
15762
|
+
const ancestorExists = await packmindCliHexa.configExists(currentDir);
|
|
15763
|
+
if (ancestorExists) {
|
|
15764
|
+
targets.push(currentDir);
|
|
15765
|
+
break;
|
|
15766
|
+
}
|
|
15767
|
+
const parentDir = nodePath.dirname(currentDir);
|
|
15768
|
+
if (parentDir === currentDir) {
|
|
15769
|
+
break;
|
|
15770
|
+
}
|
|
15771
|
+
currentDir = parentDir;
|
|
15772
|
+
}
|
|
15773
|
+
}
|
|
16014
15774
|
return targets;
|
|
16015
15775
|
}
|
|
16016
15776
|
function computeRelativePath(targetAbsDir, gitRoot) {
|
|
@@ -16193,7 +15953,11 @@ async function diffArtefactsHandler(deps) {
|
|
|
16193
15953
|
relativePath,
|
|
16194
15954
|
agents: config.agents
|
|
16195
15955
|
});
|
|
16196
|
-
|
|
15956
|
+
const filterPrefix = nodePath.relative(targetDir, searchPath);
|
|
15957
|
+
const filteredDiffs = filterPrefix !== "" && !filterPrefix.startsWith("..") ? diffs.filter(
|
|
15958
|
+
(d) => d.filePath === filterPrefix || d.filePath.startsWith(filterPrefix + "/")
|
|
15959
|
+
) : diffs;
|
|
15960
|
+
targetResults.push({ targetRelativePath, diffs: filteredDiffs });
|
|
16197
15961
|
}
|
|
16198
15962
|
if (targetResults.length === 0) {
|
|
16199
15963
|
log("No packages configured in any target.");
|
|
@@ -16285,7 +16049,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
16285
16049
|
description: "Subcommand and arguments (e.g., add <path>, remove <path>)"
|
|
16286
16050
|
})
|
|
16287
16051
|
},
|
|
16288
|
-
handler: async ({ submit, includeSubmitted, message, path:
|
|
16052
|
+
handler: async ({ submit, includeSubmitted, message, path: path37, positionals }) => {
|
|
16289
16053
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
16290
16054
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
16291
16055
|
if (submit) {
|
|
@@ -16301,7 +16065,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
16301
16065
|
process.exit(1);
|
|
16302
16066
|
}
|
|
16303
16067
|
if (positionals[0] === "add") {
|
|
16304
|
-
const addFilePath =
|
|
16068
|
+
const addFilePath = path37 && positionals[1] ? `${path37}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
|
|
16305
16069
|
const addCommand = `packmind-cli playbook add ${addFilePath}`;
|
|
16306
16070
|
logErrorConsole("Deprecated: `packmind-cli diff add` has been removed");
|
|
16307
16071
|
logInfoConsole("Use the following command instead:");
|
|
@@ -16309,7 +16073,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
16309
16073
|
process.exit(1);
|
|
16310
16074
|
}
|
|
16311
16075
|
if (positionals[0] === "remove" || positionals[0] === "rm") {
|
|
16312
|
-
const removeFilePath =
|
|
16076
|
+
const removeFilePath = path37 && positionals[1] ? `${path37}/${positionals[1]}`.replace(/\/+/g, "/") : positionals[1];
|
|
16313
16077
|
const removeCommand = `packmind-cli playbook remove ${removeFilePath}`;
|
|
16314
16078
|
logErrorConsole(
|
|
16315
16079
|
"Deprecated: `packmind-cli diff remove` has been removed"
|
|
@@ -16318,7 +16082,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
16318
16082
|
logInfoConsole(` ${formatCommand(removeCommand)}`);
|
|
16319
16083
|
process.exit(1);
|
|
16320
16084
|
}
|
|
16321
|
-
const diffCommand3 = `packmind-cli playbook diff${includeSubmitted ? " --include-submitted" : ""}${
|
|
16085
|
+
const diffCommand3 = `packmind-cli playbook diff${includeSubmitted ? " --include-submitted" : ""}${path37 ? ` --path ${path37}` : ""}`;
|
|
16322
16086
|
logErrorConsole("Deprecated: `packmind-cli diff` will be removed");
|
|
16323
16087
|
logInfoConsole("Use the following command instead:");
|
|
16324
16088
|
logInfoConsole(` ${formatCommand(diffCommand3)}`);
|
|
@@ -16328,7 +16092,7 @@ var diffCommand = (0, import_cmd_ts19.command)({
|
|
|
16328
16092
|
getCwd: () => process.cwd(),
|
|
16329
16093
|
log: console.log,
|
|
16330
16094
|
includeSubmitted,
|
|
16331
|
-
path:
|
|
16095
|
+
path: path37
|
|
16332
16096
|
});
|
|
16333
16097
|
}
|
|
16334
16098
|
});
|
|
@@ -16608,6 +16372,14 @@ var AddToPackageUseCase = class {
|
|
|
16608
16372
|
}
|
|
16609
16373
|
};
|
|
16610
16374
|
|
|
16375
|
+
// apps/cli/src/infra/utils/packageSlugUtils.ts
|
|
16376
|
+
function parsePackageSlug(slug3) {
|
|
16377
|
+
if (!slug3.startsWith("@")) return null;
|
|
16378
|
+
const slash = slug3.indexOf("/", 1);
|
|
16379
|
+
if (slash === -1) return null;
|
|
16380
|
+
return { spaceSlug: slug3.slice(1, slash), pkgSlug: slug3.slice(slash + 1) };
|
|
16381
|
+
}
|
|
16382
|
+
|
|
16611
16383
|
// apps/cli/src/infra/commands/packages/addToPackageHandler.ts
|
|
16612
16384
|
function pluralize(singular, count) {
|
|
16613
16385
|
return count === 1 ? singular : `${singular}s`;
|
|
@@ -16755,18 +16527,116 @@ var addToPackageCommand = (0, import_cmd_ts21.command)({
|
|
|
16755
16527
|
);
|
|
16756
16528
|
process.exit(1);
|
|
16757
16529
|
}
|
|
16758
|
-
const { type: itemType, slugs: itemSlugs } = itemTypes[0];
|
|
16759
|
-
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
16760
|
-
const hexa = new PackmindCliHexa(packmindLogger);
|
|
16761
|
-
await addToPackageHandler(
|
|
16762
|
-
{ to, itemType, itemSlugs, originSkill },
|
|
16763
|
-
{ hexa, exit: process.exit }
|
|
16764
|
-
);
|
|
16530
|
+
const { type: itemType, slugs: itemSlugs } = itemTypes[0];
|
|
16531
|
+
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
16532
|
+
const hexa = new PackmindCliHexa(packmindLogger);
|
|
16533
|
+
await addToPackageHandler(
|
|
16534
|
+
{ to, itemType, itemSlugs, originSkill },
|
|
16535
|
+
{ hexa, exit: process.exit }
|
|
16536
|
+
);
|
|
16537
|
+
}
|
|
16538
|
+
});
|
|
16539
|
+
|
|
16540
|
+
// apps/cli/src/infra/commands/listPackagesCommand.ts
|
|
16541
|
+
var import_cmd_ts22 = __toESM(require_cjs());
|
|
16542
|
+
|
|
16543
|
+
// apps/cli/src/infra/commands/packages/listPackagesHandler.ts
|
|
16544
|
+
function logPackageEntry(pkg, fullSlug, spaceSlug, buildUrl) {
|
|
16545
|
+
logConsole(`- ${formatSlug(fullSlug)}`);
|
|
16546
|
+
logConsole(` ${formatLabel("Name:")} ${pkg.name}`);
|
|
16547
|
+
const url = buildUrl(spaceSlug, pkg.id);
|
|
16548
|
+
if (url) {
|
|
16549
|
+
logConsole(` ${formatLabel("Link:")} ${url}`);
|
|
16550
|
+
}
|
|
16551
|
+
if (pkg.description) {
|
|
16552
|
+
const lines = pkg.description.trim().split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
|
|
16553
|
+
const [first, ...rest] = lines;
|
|
16554
|
+
logConsole(` ${formatLabel("Description:")} ${first}`);
|
|
16555
|
+
rest.forEach((l) => logConsole(` ${l}`));
|
|
16556
|
+
}
|
|
16557
|
+
}
|
|
16558
|
+
function groupPackagesBySpace(packages, spaces) {
|
|
16559
|
+
const spaceMap = new Map(
|
|
16560
|
+
spaces.map((s) => [s.id, s])
|
|
16561
|
+
);
|
|
16562
|
+
const groupsMap = /* @__PURE__ */ new Map();
|
|
16563
|
+
for (const pkg of packages) {
|
|
16564
|
+
const space = spaceMap.get(pkg.spaceId);
|
|
16565
|
+
if (!space) {
|
|
16566
|
+
continue;
|
|
16567
|
+
}
|
|
16568
|
+
let group = groupsMap.get(space.id);
|
|
16569
|
+
if (!group) {
|
|
16570
|
+
group = { space, pkgs: [] };
|
|
16571
|
+
groupsMap.set(space.id, group);
|
|
16572
|
+
}
|
|
16573
|
+
group.pkgs.push(pkg);
|
|
16574
|
+
}
|
|
16575
|
+
return [...groupsMap.values()].sort(
|
|
16576
|
+
(a, b) => a.space.name.localeCompare(b.space.name)
|
|
16577
|
+
);
|
|
16578
|
+
}
|
|
16579
|
+
function displayGroupedPackages(packages, spaces, buildUrl) {
|
|
16580
|
+
const groups = groupPackagesBySpace(packages, spaces);
|
|
16581
|
+
let firstSlug = null;
|
|
16582
|
+
for (const { space, pkgs } of groups) {
|
|
16583
|
+
logConsole(`Space "${space.name}":
|
|
16584
|
+
`);
|
|
16585
|
+
for (const pkg of [...pkgs].sort((a, b) => a.slug.localeCompare(b.slug))) {
|
|
16586
|
+
const fullSlug = `@${space.slug}/${pkg.slug}`;
|
|
16587
|
+
firstSlug ??= fullSlug;
|
|
16588
|
+
logPackageEntry(pkg, fullSlug, space.slug, buildUrl);
|
|
16589
|
+
logConsole("");
|
|
16590
|
+
}
|
|
16591
|
+
}
|
|
16592
|
+
return firstSlug ?? formatSlug(packages[0].slug);
|
|
16593
|
+
}
|
|
16594
|
+
async function listPackagesHandler(args2, deps) {
|
|
16595
|
+
const { packmindCliHexa, exit } = deps;
|
|
16596
|
+
try {
|
|
16597
|
+
logInfoConsole("Fetching available packages...");
|
|
16598
|
+
const allSpaces = await packmindCliHexa.getSpaces();
|
|
16599
|
+
if (!allSpaces || allSpaces.length === 0) {
|
|
16600
|
+
throw new Error("Unable to list organization spaces.");
|
|
16601
|
+
}
|
|
16602
|
+
const matchedSpace = resolveSpaceFromArgs(args2.space, allSpaces);
|
|
16603
|
+
if (args2.space && !matchedSpace) {
|
|
16604
|
+
logErrorConsole(`Space "@${args2.space}" not found.`);
|
|
16605
|
+
logInfoConsole(
|
|
16606
|
+
`Available spaces: ${allSpaces.map((s) => `@${s.slug}`).join(", ")}`
|
|
16607
|
+
);
|
|
16608
|
+
exit(1);
|
|
16609
|
+
return;
|
|
16610
|
+
}
|
|
16611
|
+
const packages = await packmindCliHexa.listPackages(
|
|
16612
|
+
matchedSpace ? { spaceId: matchedSpace.id } : {}
|
|
16613
|
+
);
|
|
16614
|
+
const spaces = matchedSpace ? [matchedSpace] : allSpaces;
|
|
16615
|
+
if (packages.length === 0) {
|
|
16616
|
+
logConsole(
|
|
16617
|
+
matchedSpace ? `No packages found in space "@${matchedSpace.slug}".` : "No packages found."
|
|
16618
|
+
);
|
|
16619
|
+
exit(0);
|
|
16620
|
+
return;
|
|
16621
|
+
}
|
|
16622
|
+
const buildUrl = resolveUrlBuilder((id) => `packages/${id}`);
|
|
16623
|
+
logConsole("\nAvailable packages:\n");
|
|
16624
|
+
const exampleSlug = displayGroupedPackages(packages, spaces, buildUrl);
|
|
16625
|
+
logConsole("How to install a package:\n");
|
|
16626
|
+
logConsole(` ${formatCommand(`packmind-cli install ${exampleSlug}`)}`);
|
|
16627
|
+
exit(0);
|
|
16628
|
+
} catch (err) {
|
|
16629
|
+
logErrorConsole("Failed to list packages:");
|
|
16630
|
+
if (err instanceof Error) {
|
|
16631
|
+
logErrorConsole(err.message);
|
|
16632
|
+
} else {
|
|
16633
|
+
logErrorConsole(String(err));
|
|
16634
|
+
}
|
|
16635
|
+
exit(1);
|
|
16765
16636
|
}
|
|
16766
|
-
}
|
|
16637
|
+
}
|
|
16767
16638
|
|
|
16768
16639
|
// apps/cli/src/infra/commands/listPackagesCommand.ts
|
|
16769
|
-
var import_cmd_ts22 = __toESM(require_cjs());
|
|
16770
16640
|
var listPackagesCommand = (0, import_cmd_ts22.command)({
|
|
16771
16641
|
name: "list",
|
|
16772
16642
|
description: "List available packages",
|
|
@@ -16790,6 +16660,124 @@ var listPackagesCommand = (0, import_cmd_ts22.command)({
|
|
|
16790
16660
|
|
|
16791
16661
|
// apps/cli/src/infra/commands/packages/showPackageCommand.ts
|
|
16792
16662
|
var import_cmd_ts23 = __toESM(require_cjs());
|
|
16663
|
+
|
|
16664
|
+
// apps/cli/src/infra/commands/packages/showPackageHandler.ts
|
|
16665
|
+
function isNotFoundError(err) {
|
|
16666
|
+
return err instanceof Error && err.message.includes("does not exist");
|
|
16667
|
+
}
|
|
16668
|
+
async function resolvePackage(slug3, packmindCliHexa) {
|
|
16669
|
+
const allSpaces = await packmindCliHexa.getSpaces();
|
|
16670
|
+
const parsed = parsePackageSlug(slug3);
|
|
16671
|
+
if (parsed) {
|
|
16672
|
+
const { spaceSlug, pkgSlug } = parsed;
|
|
16673
|
+
const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
|
|
16674
|
+
if (!matchedSpace) {
|
|
16675
|
+
throw new Error(`Space '@${spaceSlug}' not found.`);
|
|
16676
|
+
}
|
|
16677
|
+
let pkg;
|
|
16678
|
+
try {
|
|
16679
|
+
pkg = await packmindCliHexa.getPackageBySlug({
|
|
16680
|
+
slug: pkgSlug,
|
|
16681
|
+
spaceId: matchedSpace.id
|
|
16682
|
+
});
|
|
16683
|
+
} catch (err) {
|
|
16684
|
+
if (isNotFoundError(err)) {
|
|
16685
|
+
throw new Error(
|
|
16686
|
+
`Package '${pkgSlug}' not found in space '@${spaceSlug}'.`
|
|
16687
|
+
);
|
|
16688
|
+
}
|
|
16689
|
+
throw err;
|
|
16690
|
+
}
|
|
16691
|
+
return { pkg, fullSlug: `@${spaceSlug}/${pkgSlug}` };
|
|
16692
|
+
}
|
|
16693
|
+
const results = await Promise.allSettled(
|
|
16694
|
+
allSpaces.map(async (space) => ({
|
|
16695
|
+
pkg: await packmindCliHexa.getPackageBySlug({
|
|
16696
|
+
slug: slug3,
|
|
16697
|
+
spaceId: space.id
|
|
16698
|
+
}),
|
|
16699
|
+
spaceSlug: space.slug
|
|
16700
|
+
}))
|
|
16701
|
+
);
|
|
16702
|
+
const matches = results.filter(
|
|
16703
|
+
(r) => r.status === "fulfilled"
|
|
16704
|
+
).map((r) => r.value);
|
|
16705
|
+
if (matches.length === 0) {
|
|
16706
|
+
const realError = results.filter((r) => r.status === "rejected").find((r) => !isNotFoundError(r.reason));
|
|
16707
|
+
if (realError) {
|
|
16708
|
+
throw realError.reason;
|
|
16709
|
+
}
|
|
16710
|
+
throw new Error(`Package '${slug3}' not found in any space.`);
|
|
16711
|
+
}
|
|
16712
|
+
if (matches.length > 1) {
|
|
16713
|
+
const example = `@${matches[0].spaceSlug}/${slug3}`;
|
|
16714
|
+
throw new Error(
|
|
16715
|
+
`Package '${slug3}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
|
|
16716
|
+
);
|
|
16717
|
+
}
|
|
16718
|
+
return {
|
|
16719
|
+
pkg: matches[0].pkg,
|
|
16720
|
+
fullSlug: `@${matches[0].spaceSlug}/${slug3}`
|
|
16721
|
+
};
|
|
16722
|
+
}
|
|
16723
|
+
async function showPackageHandler(args2, deps) {
|
|
16724
|
+
const { packmindCliHexa, exit } = deps;
|
|
16725
|
+
try {
|
|
16726
|
+
logInfoConsole(`Fetching package details for '${args2.slug}'...`);
|
|
16727
|
+
const { pkg, fullSlug } = await resolvePackage(args2.slug, packmindCliHexa);
|
|
16728
|
+
logConsole(`
|
|
16729
|
+
${pkg.name} (${fullSlug}):
|
|
16730
|
+
`);
|
|
16731
|
+
if (pkg.description) {
|
|
16732
|
+
logConsole(`${pkg.description}
|
|
16733
|
+
`);
|
|
16734
|
+
}
|
|
16735
|
+
if (pkg.standards && pkg.standards.length > 0) {
|
|
16736
|
+
logConsole("Standards:");
|
|
16737
|
+
pkg.standards.forEach((standard) => {
|
|
16738
|
+
if (standard.summary) {
|
|
16739
|
+
logConsole(` - ${standard.name}: ${standard.summary}`);
|
|
16740
|
+
} else {
|
|
16741
|
+
logConsole(` - ${standard.name}`);
|
|
16742
|
+
}
|
|
16743
|
+
});
|
|
16744
|
+
logConsole("");
|
|
16745
|
+
}
|
|
16746
|
+
if (pkg.recipes && pkg.recipes.length > 0) {
|
|
16747
|
+
logConsole("Commands:");
|
|
16748
|
+
pkg.recipes.forEach((recipe) => {
|
|
16749
|
+
if (recipe.summary) {
|
|
16750
|
+
logConsole(` - ${recipe.name}: ${recipe.summary}`);
|
|
16751
|
+
} else {
|
|
16752
|
+
logConsole(` - ${recipe.name}`);
|
|
16753
|
+
}
|
|
16754
|
+
});
|
|
16755
|
+
logConsole("");
|
|
16756
|
+
}
|
|
16757
|
+
if (pkg.skills && pkg.skills.length > 0) {
|
|
16758
|
+
logConsole("Skills:");
|
|
16759
|
+
pkg.skills.forEach((skill) => {
|
|
16760
|
+
if (skill.summary) {
|
|
16761
|
+
logConsole(` - ${skill.name}: ${skill.summary}`);
|
|
16762
|
+
} else {
|
|
16763
|
+
logConsole(` - ${skill.name}`);
|
|
16764
|
+
}
|
|
16765
|
+
});
|
|
16766
|
+
logConsole("");
|
|
16767
|
+
}
|
|
16768
|
+
exit(0);
|
|
16769
|
+
} catch (err) {
|
|
16770
|
+
logErrorConsole("Failed to fetch package details:");
|
|
16771
|
+
if (err instanceof Error) {
|
|
16772
|
+
logErrorConsole(err.message);
|
|
16773
|
+
} else {
|
|
16774
|
+
logErrorConsole(String(err));
|
|
16775
|
+
}
|
|
16776
|
+
exit(1);
|
|
16777
|
+
}
|
|
16778
|
+
}
|
|
16779
|
+
|
|
16780
|
+
// apps/cli/src/infra/commands/packages/showPackageCommand.ts
|
|
16793
16781
|
var showPackageCommand = (0, import_cmd_ts23.command)({
|
|
16794
16782
|
name: "show",
|
|
16795
16783
|
description: "Show details of a specific package",
|
|
@@ -16826,14 +16814,96 @@ var import_cmd_ts31 = __toESM(require_cjs());
|
|
|
16826
16814
|
var import_fs21 = require("fs");
|
|
16827
16815
|
var import_cmd_ts25 = __toESM(require_cjs());
|
|
16828
16816
|
|
|
16829
|
-
// apps/cli/src/infra/
|
|
16817
|
+
// apps/cli/src/infra/repositories/PlaybookLocalRepository.ts
|
|
16818
|
+
var crypto = __toESM(require("crypto"));
|
|
16830
16819
|
var fs23 = __toESM(require("fs"));
|
|
16831
|
-
var
|
|
16820
|
+
var os5 = __toESM(require("os"));
|
|
16821
|
+
var path23 = __toESM(require("path"));
|
|
16822
|
+
var yaml = __toESM(require("yaml"));
|
|
16823
|
+
var PlaybookLocalRepository = class {
|
|
16824
|
+
constructor(repoRoot) {
|
|
16825
|
+
const normalized = this.normalizeRepoRoot(repoRoot);
|
|
16826
|
+
const hash = crypto.createHash("md5").update(normalized).digest("hex");
|
|
16827
|
+
this.storagePath = path23.join(
|
|
16828
|
+
os5.homedir(),
|
|
16829
|
+
".packmind",
|
|
16830
|
+
hash,
|
|
16831
|
+
"playbook.yaml"
|
|
16832
|
+
);
|
|
16833
|
+
}
|
|
16834
|
+
addChange(entry) {
|
|
16835
|
+
const data = this.readYaml();
|
|
16836
|
+
const existingIndex = data.changes.findIndex(
|
|
16837
|
+
(c) => c.filePath === entry.filePath && c.spaceId === entry.spaceId
|
|
16838
|
+
);
|
|
16839
|
+
if (existingIndex >= 0) {
|
|
16840
|
+
data.changes[existingIndex] = entry;
|
|
16841
|
+
} else {
|
|
16842
|
+
data.changes.push(entry);
|
|
16843
|
+
}
|
|
16844
|
+
this.writeYaml(data);
|
|
16845
|
+
}
|
|
16846
|
+
removeChange(filePath, spaceId) {
|
|
16847
|
+
const data = this.readYaml();
|
|
16848
|
+
const initialLength = data.changes.length;
|
|
16849
|
+
data.changes = data.changes.filter(
|
|
16850
|
+
(c) => !(c.filePath === filePath && c.spaceId === spaceId)
|
|
16851
|
+
);
|
|
16852
|
+
if (data.changes.length === initialLength) {
|
|
16853
|
+
return false;
|
|
16854
|
+
}
|
|
16855
|
+
this.writeYaml(data);
|
|
16856
|
+
return true;
|
|
16857
|
+
}
|
|
16858
|
+
getChanges() {
|
|
16859
|
+
return this.readYaml().changes;
|
|
16860
|
+
}
|
|
16861
|
+
getChange(filePath, spaceId) {
|
|
16862
|
+
return this.readYaml().changes.find(
|
|
16863
|
+
(c) => c.filePath === filePath && c.spaceId === spaceId
|
|
16864
|
+
) ?? null;
|
|
16865
|
+
}
|
|
16866
|
+
clearAll() {
|
|
16867
|
+
this.writeYaml({ version: 1, changes: [] });
|
|
16868
|
+
}
|
|
16869
|
+
normalizeRepoRoot(repoRoot) {
|
|
16870
|
+
let normalized = repoRoot.replace(/\\/g, "/");
|
|
16871
|
+
normalized = normalized.replace(/\/$/, "");
|
|
16872
|
+
return normalized;
|
|
16873
|
+
}
|
|
16874
|
+
readYaml() {
|
|
16875
|
+
if (!fs23.existsSync(this.storagePath)) {
|
|
16876
|
+
return { version: 1, changes: [] };
|
|
16877
|
+
}
|
|
16878
|
+
try {
|
|
16879
|
+
const content = fs23.readFileSync(this.storagePath, "utf-8");
|
|
16880
|
+
const parsed = yaml.parse(content);
|
|
16881
|
+
if (!parsed || !Array.isArray(parsed.changes)) {
|
|
16882
|
+
return { version: 1, changes: [] };
|
|
16883
|
+
}
|
|
16884
|
+
return { version: 1, changes: parsed.changes };
|
|
16885
|
+
} catch {
|
|
16886
|
+
logWarningConsole(
|
|
16887
|
+
`Corrupted playbook file: ${this.storagePath}. Treating as empty.`
|
|
16888
|
+
);
|
|
16889
|
+
return { version: 1, changes: [] };
|
|
16890
|
+
}
|
|
16891
|
+
}
|
|
16892
|
+
writeYaml(data) {
|
|
16893
|
+
const dir = path23.dirname(this.storagePath);
|
|
16894
|
+
fs23.mkdirSync(dir, { recursive: true });
|
|
16895
|
+
fs23.writeFileSync(this.storagePath, yaml.stringify(data), "utf-8");
|
|
16896
|
+
}
|
|
16897
|
+
};
|
|
16898
|
+
|
|
16899
|
+
// apps/cli/src/infra/commands/playbook/addHandler.ts
|
|
16900
|
+
var fs24 = __toESM(require("fs"));
|
|
16901
|
+
var path27 = __toESM(require("path"));
|
|
16832
16902
|
var yaml2 = __toESM(require("yaml"));
|
|
16833
16903
|
var import_slug = __toESM(require("slug"));
|
|
16834
16904
|
|
|
16835
16905
|
// apps/cli/src/application/utils/parseCommandFile.ts
|
|
16836
|
-
var
|
|
16906
|
+
var path24 = __toESM(require("path"));
|
|
16837
16907
|
var FRONTMATTER_DELIMITER3 = "---";
|
|
16838
16908
|
function parseCommandFile(content, filePath) {
|
|
16839
16909
|
content = normalizeLineEndings(content);
|
|
@@ -16889,7 +16959,7 @@ function stripYamlQuotes2(value) {
|
|
|
16889
16959
|
return value;
|
|
16890
16960
|
}
|
|
16891
16961
|
function extractFilenameSlug(filePath) {
|
|
16892
|
-
let basename4 =
|
|
16962
|
+
let basename4 = path24.basename(filePath);
|
|
16893
16963
|
if (basename4.endsWith(".prompt.md")) {
|
|
16894
16964
|
basename4 = basename4.slice(0, -".prompt.md".length);
|
|
16895
16965
|
} else if (basename4.endsWith(".md")) {
|
|
@@ -17056,7 +17126,7 @@ function parseSkillDirectory(files) {
|
|
|
17056
17126
|
}
|
|
17057
17127
|
|
|
17058
17128
|
// apps/cli/src/application/utils/findNearestConfigDir.ts
|
|
17059
|
-
var
|
|
17129
|
+
var path25 = __toESM(require("path"));
|
|
17060
17130
|
async function findNearestConfigDir(startDir, packmindCliHexa) {
|
|
17061
17131
|
let current = startDir;
|
|
17062
17132
|
while (true) {
|
|
@@ -17064,7 +17134,7 @@ async function findNearestConfigDir(startDir, packmindCliHexa) {
|
|
|
17064
17134
|
if (exists) {
|
|
17065
17135
|
return current;
|
|
17066
17136
|
}
|
|
17067
|
-
const parent =
|
|
17137
|
+
const parent = path25.dirname(current);
|
|
17068
17138
|
if (parent === current) {
|
|
17069
17139
|
return null;
|
|
17070
17140
|
}
|
|
@@ -17073,7 +17143,7 @@ async function findNearestConfigDir(startDir, packmindCliHexa) {
|
|
|
17073
17143
|
}
|
|
17074
17144
|
|
|
17075
17145
|
// apps/cli/src/application/utils/resolveDeployedContext.ts
|
|
17076
|
-
var
|
|
17146
|
+
var path26 = __toESM(require("path"));
|
|
17077
17147
|
async function resolveDeployedContext(packmindCliHexa, targetDir) {
|
|
17078
17148
|
try {
|
|
17079
17149
|
const space = await packmindCliHexa.getDefaultSpace();
|
|
@@ -17085,7 +17155,7 @@ async function resolveDeployedContext(packmindCliHexa, targetDir) {
|
|
|
17085
17155
|
}
|
|
17086
17156
|
const gitRemoteUrl = packmindCliHexa.getGitRemoteUrlFromPath(gitRoot);
|
|
17087
17157
|
const gitBranch = packmindCliHexa.getCurrentBranch(gitRoot);
|
|
17088
|
-
const rel =
|
|
17158
|
+
const rel = path26.relative(gitRoot, targetDir);
|
|
17089
17159
|
const relativePath = rel.startsWith("..") ? "/" : rel ? `/${rel}/` : "/";
|
|
17090
17160
|
const deployedContent = await packmindCliHexa.getPackmindGateway().deployment.getDeployed({
|
|
17091
17161
|
packagesSlugs: configPackages,
|
|
@@ -17150,19 +17220,19 @@ async function fetchDeployedFiles(gateway, lockFile) {
|
|
|
17150
17220
|
|
|
17151
17221
|
// apps/cli/src/infra/commands/playbook/addHandler.ts
|
|
17152
17222
|
async function tryStageRemovedFromLockFile(resolvedPath, deps) {
|
|
17153
|
-
const fileDir =
|
|
17223
|
+
const fileDir = path27.dirname(resolvedPath);
|
|
17154
17224
|
const targetDir = await findNearestConfigDir(fileDir, deps.packmindCliHexa);
|
|
17155
17225
|
if (!targetDir) return false;
|
|
17156
17226
|
const lockFile = await deps.lockFileRepository.read(targetDir);
|
|
17157
17227
|
if (!lockFile) return false;
|
|
17158
|
-
const normalizedPath = normalizePath2(
|
|
17228
|
+
const normalizedPath = normalizePath2(path27.relative(targetDir, resolvedPath));
|
|
17159
17229
|
const lockEntry = findLockFileEntryForPath(
|
|
17160
17230
|
normalizedPath,
|
|
17161
17231
|
lockFile.artifacts
|
|
17162
17232
|
);
|
|
17163
17233
|
if (!lockEntry) return false;
|
|
17164
17234
|
const gitRoot = await deps.packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
|
|
17165
|
-
const configDir = gitRoot ? normalizePath2(
|
|
17235
|
+
const configDir = gitRoot ? normalizePath2(path27.relative(gitRoot, targetDir)) : "";
|
|
17166
17236
|
const deployedContext = await resolveDeployedContext(
|
|
17167
17237
|
deps.packmindCliHexa,
|
|
17168
17238
|
targetDir
|
|
@@ -17194,22 +17264,22 @@ async function tryStageRemovedFromLockFile(resolvedPath, deps) {
|
|
|
17194
17264
|
}
|
|
17195
17265
|
function resolveSkillDirectoryRoot(absolutePath) {
|
|
17196
17266
|
if (absolutePath.endsWith("SKILL.md")) {
|
|
17197
|
-
return
|
|
17267
|
+
return path27.dirname(absolutePath);
|
|
17198
17268
|
}
|
|
17199
17269
|
try {
|
|
17200
|
-
if (
|
|
17270
|
+
if (fs24.statSync(absolutePath).isDirectory()) {
|
|
17201
17271
|
return absolutePath;
|
|
17202
17272
|
}
|
|
17203
17273
|
} catch {
|
|
17204
17274
|
return absolutePath;
|
|
17205
17275
|
}
|
|
17206
|
-
let current =
|
|
17207
|
-
const root =
|
|
17276
|
+
let current = path27.dirname(absolutePath);
|
|
17277
|
+
const root = path27.parse(current).root;
|
|
17208
17278
|
while (current !== root) {
|
|
17209
|
-
if (
|
|
17279
|
+
if (fs24.existsSync(path27.join(current, "SKILL.md"))) {
|
|
17210
17280
|
return current;
|
|
17211
17281
|
}
|
|
17212
|
-
current =
|
|
17282
|
+
current = path27.dirname(current);
|
|
17213
17283
|
}
|
|
17214
17284
|
return absolutePath;
|
|
17215
17285
|
}
|
|
@@ -17220,7 +17290,7 @@ async function playbookAddHandler(deps) {
|
|
|
17220
17290
|
spaceSlug,
|
|
17221
17291
|
exit,
|
|
17222
17292
|
cwd,
|
|
17223
|
-
readFile:
|
|
17293
|
+
readFile: readFile11,
|
|
17224
17294
|
readSkillDirectory: readSkillDirectory2,
|
|
17225
17295
|
playbookLocalRepository,
|
|
17226
17296
|
lockFileRepository
|
|
@@ -17232,17 +17302,17 @@ async function playbookAddHandler(deps) {
|
|
|
17232
17302
|
exit(1);
|
|
17233
17303
|
return;
|
|
17234
17304
|
}
|
|
17235
|
-
const absolutePath =
|
|
17305
|
+
const absolutePath = path27.resolve(cwd, filePath);
|
|
17236
17306
|
let artifactType;
|
|
17237
17307
|
let codingAgent;
|
|
17238
17308
|
const earlyTargetDir = await findNearestConfigDir(
|
|
17239
|
-
|
|
17309
|
+
path27.dirname(absolutePath),
|
|
17240
17310
|
packmindCliHexa
|
|
17241
17311
|
);
|
|
17242
17312
|
const earlyLockFile = earlyTargetDir ? await lockFileRepository.read(earlyTargetDir) : null;
|
|
17243
17313
|
if (earlyLockFile && earlyTargetDir) {
|
|
17244
17314
|
const normalizedForLookup = normalizePath2(
|
|
17245
|
-
|
|
17315
|
+
path27.relative(earlyTargetDir, absolutePath)
|
|
17246
17316
|
);
|
|
17247
17317
|
const lockResult = findLockFileEntryAndFileForPath(
|
|
17248
17318
|
normalizedForLookup,
|
|
@@ -17322,7 +17392,7 @@ async function playbookAddHandler(deps) {
|
|
|
17322
17392
|
localContent = skillMdFile?.content ?? serializedContent;
|
|
17323
17393
|
} else {
|
|
17324
17394
|
try {
|
|
17325
|
-
localContent =
|
|
17395
|
+
localContent = readFile11(absolutePath);
|
|
17326
17396
|
} catch (err) {
|
|
17327
17397
|
const staged = await tryStageRemovedFromLockFile(absolutePath, {
|
|
17328
17398
|
packmindCliHexa,
|
|
@@ -17376,7 +17446,7 @@ Content goes here...`
|
|
|
17376
17446
|
return;
|
|
17377
17447
|
}
|
|
17378
17448
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
|
|
17379
|
-
const configDir = gitRoot ? normalizePath2(
|
|
17449
|
+
const configDir = gitRoot ? normalizePath2(path27.relative(gitRoot, targetDir)) : "";
|
|
17380
17450
|
const deployedContext = await resolveDeployedContext(
|
|
17381
17451
|
packmindCliHexa,
|
|
17382
17452
|
targetDir
|
|
@@ -17384,7 +17454,7 @@ Content goes here...`
|
|
|
17384
17454
|
const targetId = deployedContext?.targetId ?? earlyLockFile?.targetId;
|
|
17385
17455
|
const normalizedFilePath = (() => {
|
|
17386
17456
|
const refPath = artifactType === "skill" && skillDirPath ? skillDirPath : absolutePath;
|
|
17387
|
-
return normalizePath2(
|
|
17457
|
+
return normalizePath2(path27.relative(targetDir, refPath));
|
|
17388
17458
|
})();
|
|
17389
17459
|
let spaceId;
|
|
17390
17460
|
let spaceName;
|
|
@@ -17499,7 +17569,7 @@ Run ${formatLabel("packmind-cli install")} to update before making changes.`
|
|
|
17499
17569
|
);
|
|
17500
17570
|
const allMatch = skillDeployedFiles.length > 0 && skillDeployedFiles.length === skillFiles.length && skillDeployedFiles.every((deployed) => {
|
|
17501
17571
|
const localFile = skillFiles.find(
|
|
17502
|
-
(f) => normalizePath2(
|
|
17572
|
+
(f) => normalizePath2(path27.join(normalizedFilePath, f.relativePath)) === normalizePath2(deployed.path)
|
|
17503
17573
|
);
|
|
17504
17574
|
return localFile && deployed.content?.trim() === localFile.content.trim() && (!deployed.skillFilePermissions || deployed.skillFilePermissions === localFile.permissions);
|
|
17505
17575
|
});
|
|
@@ -17611,8 +17681,8 @@ var addPlaybookCommand = (0, import_cmd_ts25.command)({
|
|
|
17611
17681
|
var import_cmd_ts26 = __toESM(require_cjs());
|
|
17612
17682
|
|
|
17613
17683
|
// apps/cli/src/infra/commands/playbook/rmHandler.ts
|
|
17614
|
-
var
|
|
17615
|
-
var
|
|
17684
|
+
var fs25 = __toESM(require("fs"));
|
|
17685
|
+
var path28 = __toESM(require("path"));
|
|
17616
17686
|
function isSkillSupportFile(absolutePath) {
|
|
17617
17687
|
const normalized = absolutePath.replace(/\\/g, "/");
|
|
17618
17688
|
const skillDirMatch = normalized.match(/\/skills\/[^/]+\//);
|
|
@@ -17639,14 +17709,14 @@ async function playbookRmHandler(deps) {
|
|
|
17639
17709
|
exit(1);
|
|
17640
17710
|
return;
|
|
17641
17711
|
}
|
|
17642
|
-
const absolutePath =
|
|
17643
|
-
if (!
|
|
17712
|
+
const absolutePath = path28.resolve(getCwd(), filePath);
|
|
17713
|
+
if (!fs25.existsSync(absolutePath)) {
|
|
17644
17714
|
logErrorConsole(`File not found: "${filePath}"`);
|
|
17645
17715
|
exit(1);
|
|
17646
17716
|
return;
|
|
17647
17717
|
}
|
|
17648
17718
|
const targetDir = await findNearestConfigDir(
|
|
17649
|
-
|
|
17719
|
+
path28.dirname(absolutePath),
|
|
17650
17720
|
packmindCliHexa
|
|
17651
17721
|
);
|
|
17652
17722
|
if (!targetDir) {
|
|
@@ -17663,7 +17733,7 @@ async function playbookRmHandler(deps) {
|
|
|
17663
17733
|
return;
|
|
17664
17734
|
}
|
|
17665
17735
|
const normalizedForLookup = normalizePath2(
|
|
17666
|
-
|
|
17736
|
+
path28.relative(targetDir, absolutePath)
|
|
17667
17737
|
);
|
|
17668
17738
|
const lockResult = findLockFileEntryAndFileForPath(
|
|
17669
17739
|
normalizedForLookup,
|
|
@@ -17685,7 +17755,7 @@ async function playbookRmHandler(deps) {
|
|
|
17685
17755
|
}
|
|
17686
17756
|
const resolvedAbsolutePath = artifactType === "skill" ? resolveSkillDirPath(absolutePath) : absolutePath;
|
|
17687
17757
|
const normalizedFilePath = normalizePath2(
|
|
17688
|
-
|
|
17758
|
+
path28.relative(targetDir, resolvedAbsolutePath)
|
|
17689
17759
|
);
|
|
17690
17760
|
const lockEntry = findLockFileEntryAndFileForPath(normalizedFilePath, lockFile.artifacts)?.entry ?? lockResult.entry;
|
|
17691
17761
|
if (!lockEntry) {
|
|
@@ -17713,7 +17783,7 @@ async function playbookRmHandler(deps) {
|
|
|
17713
17783
|
}
|
|
17714
17784
|
const spaceName = matchingSpace.name;
|
|
17715
17785
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(targetDir);
|
|
17716
|
-
const configDir = gitRoot ? normalizePath2(
|
|
17786
|
+
const configDir = gitRoot ? normalizePath2(path28.relative(gitRoot, targetDir)) : "";
|
|
17717
17787
|
const deployedContext = await resolveDeployedContext(
|
|
17718
17788
|
packmindCliHexa,
|
|
17719
17789
|
targetDir
|
|
@@ -17774,7 +17844,7 @@ var rmPlaybookCommand = (0, import_cmd_ts26.command)({
|
|
|
17774
17844
|
var import_cmd_ts27 = __toESM(require_cjs());
|
|
17775
17845
|
|
|
17776
17846
|
// apps/cli/src/infra/commands/playbook/unstageHandler.ts
|
|
17777
|
-
var
|
|
17847
|
+
var path29 = __toESM(require("path"));
|
|
17778
17848
|
async function playbookUnstageHandler(deps) {
|
|
17779
17849
|
const {
|
|
17780
17850
|
packmindCliHexa,
|
|
@@ -17792,10 +17862,10 @@ async function playbookUnstageHandler(deps) {
|
|
|
17792
17862
|
return;
|
|
17793
17863
|
}
|
|
17794
17864
|
const cwd = getCwd();
|
|
17795
|
-
const absolutePath =
|
|
17865
|
+
const absolutePath = path29.resolve(cwd, filePath);
|
|
17796
17866
|
const resolvedPath = resolveSkillDirPath(absolutePath);
|
|
17797
17867
|
const configDir = await findNearestConfigDir(
|
|
17798
|
-
|
|
17868
|
+
path29.dirname(resolvedPath),
|
|
17799
17869
|
packmindCliHexa
|
|
17800
17870
|
);
|
|
17801
17871
|
if (!configDir) {
|
|
@@ -17808,10 +17878,10 @@ async function playbookUnstageHandler(deps) {
|
|
|
17808
17878
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
17809
17879
|
const baseDir = gitRoot ?? configDir;
|
|
17810
17880
|
const normalizedFilePath = normalizePath2(
|
|
17811
|
-
|
|
17881
|
+
path29.relative(baseDir, resolvedPath)
|
|
17812
17882
|
);
|
|
17813
17883
|
const matchingEntries = playbookLocalRepository.getChanges().filter((c) => {
|
|
17814
|
-
const fullEntryPath = c.configDir ? normalizePath2(
|
|
17884
|
+
const fullEntryPath = c.configDir ? normalizePath2(path29.join(c.configDir, c.filePath)) : c.filePath;
|
|
17815
17885
|
return fullEntryPath === normalizedFilePath;
|
|
17816
17886
|
});
|
|
17817
17887
|
if (matchingEntries.length === 0) {
|
|
@@ -17895,15 +17965,15 @@ var import_cmd_ts28 = __toESM(require_cjs());
|
|
|
17895
17965
|
|
|
17896
17966
|
// apps/cli/src/infra/utils/listDirectoryFiles.ts
|
|
17897
17967
|
var import_fs22 = require("fs");
|
|
17898
|
-
var
|
|
17968
|
+
var path30 = __toESM(require("path"));
|
|
17899
17969
|
function listDirectoryFiles(dirPath) {
|
|
17900
17970
|
const results = [];
|
|
17901
17971
|
const entries = (0, import_fs22.readdirSync)(dirPath, { withFileTypes: true });
|
|
17902
17972
|
for (const entry of entries) {
|
|
17903
|
-
const fullPath =
|
|
17973
|
+
const fullPath = path30.join(dirPath, entry.name);
|
|
17904
17974
|
if (entry.isDirectory()) {
|
|
17905
17975
|
for (const nested of listDirectoryFiles(fullPath)) {
|
|
17906
|
-
results.push(
|
|
17976
|
+
results.push(path30.join(entry.name, nested));
|
|
17907
17977
|
}
|
|
17908
17978
|
} else if (entry.isFile()) {
|
|
17909
17979
|
results.push(entry.name);
|
|
@@ -17913,7 +17983,7 @@ function listDirectoryFiles(dirPath) {
|
|
|
17913
17983
|
}
|
|
17914
17984
|
|
|
17915
17985
|
// apps/cli/src/infra/commands/playbook/statusHandler.ts
|
|
17916
|
-
var
|
|
17986
|
+
var path31 = __toESM(require("path"));
|
|
17917
17987
|
|
|
17918
17988
|
// apps/cli/src/infra/utils/stringUtils.ts
|
|
17919
17989
|
function capitalize(s) {
|
|
@@ -17948,7 +18018,7 @@ function groupStagedChanges(changes, cwd, gitRoot) {
|
|
|
17948
18018
|
const changeType = change.changeType ?? "updated";
|
|
17949
18019
|
const key = `${change.artifactType}:${change.artifactName}:${changeType}`;
|
|
17950
18020
|
const rootRelativePath = change.configDir ? `${change.configDir}/${change.filePath}` : change.filePath;
|
|
17951
|
-
const displayPath = gitRoot ? normalizePath2(
|
|
18021
|
+
const displayPath = gitRoot ? normalizePath2(path31.relative(cwd, path31.join(gitRoot, rootRelativePath))) : rootRelativePath;
|
|
17952
18022
|
const existing = groups.get(key);
|
|
17953
18023
|
if (existing) {
|
|
17954
18024
|
existing.filePaths.push(displayPath);
|
|
@@ -17989,7 +18059,7 @@ async function playbookStatusHandler(deps) {
|
|
|
17989
18059
|
lockFileRepository,
|
|
17990
18060
|
cwd,
|
|
17991
18061
|
exit,
|
|
17992
|
-
readFile:
|
|
18062
|
+
readFile: readFile11,
|
|
17993
18063
|
listDirectoryFiles: listDirectoryFiles2,
|
|
17994
18064
|
getFileMode
|
|
17995
18065
|
} = deps;
|
|
@@ -18006,12 +18076,12 @@ async function playbookStatusHandler(deps) {
|
|
|
18006
18076
|
const fallbackConfigDir = await findNearestConfigDir(cwd, packmindCliHexa);
|
|
18007
18077
|
const configDirs = /* @__PURE__ */ new Set([...stagedByConfigDir.keys()]);
|
|
18008
18078
|
if (fallbackConfigDir && !configDirs.has("__cwd__")) {
|
|
18009
|
-
const rel = gitRoot ? normalizePath2(
|
|
18079
|
+
const rel = gitRoot ? normalizePath2(path31.relative(gitRoot, fallbackConfigDir)) : "";
|
|
18010
18080
|
if (!configDirs.has(rel)) configDirs.add(rel);
|
|
18011
18081
|
}
|
|
18012
18082
|
const descendantDirs = await packmindCliHexa.findDescendantConfigs(cwd);
|
|
18013
18083
|
for (const descendantDir of descendantDirs) {
|
|
18014
|
-
const rel = gitRoot ? normalizePath2(
|
|
18084
|
+
const rel = gitRoot ? normalizePath2(path31.relative(gitRoot, descendantDir)) : normalizePath2(path31.relative(cwd, descendantDir));
|
|
18015
18085
|
if (!configDirs.has(rel)) configDirs.add(rel);
|
|
18016
18086
|
}
|
|
18017
18087
|
for (const configDirKey of configDirs) {
|
|
@@ -18019,7 +18089,7 @@ async function playbookStatusHandler(deps) {
|
|
|
18019
18089
|
if (configDirKey === "__cwd__") {
|
|
18020
18090
|
projectDir = fallbackConfigDir;
|
|
18021
18091
|
} else if (gitRoot) {
|
|
18022
|
-
projectDir =
|
|
18092
|
+
projectDir = path31.join(gitRoot, configDirKey);
|
|
18023
18093
|
} else {
|
|
18024
18094
|
continue;
|
|
18025
18095
|
}
|
|
@@ -18044,11 +18114,11 @@ async function playbookStatusHandler(deps) {
|
|
|
18044
18114
|
continue;
|
|
18045
18115
|
}
|
|
18046
18116
|
const displayPath = normalizePath2(
|
|
18047
|
-
|
|
18117
|
+
path31.relative(cwd, path31.join(projectDir, deployedFile.path))
|
|
18048
18118
|
);
|
|
18049
18119
|
let localContent;
|
|
18050
18120
|
try {
|
|
18051
|
-
localContent =
|
|
18121
|
+
localContent = readFile11(path31.join(projectDir, deployedFile.path));
|
|
18052
18122
|
} catch {
|
|
18053
18123
|
const artifact = findArtifactForFile(
|
|
18054
18124
|
deployedFile.path,
|
|
@@ -18077,7 +18147,7 @@ async function playbookStatusHandler(deps) {
|
|
|
18077
18147
|
});
|
|
18078
18148
|
}
|
|
18079
18149
|
} else if (deployedFile.skillFilePermissions && getFileMode) {
|
|
18080
|
-
const localMode = getFileMode(
|
|
18150
|
+
const localMode = getFileMode(path31.join(projectDir, deployedFile.path));
|
|
18081
18151
|
if (localMode !== null) {
|
|
18082
18152
|
const localPermissions = modeToPermissionStringOrDefault(localMode);
|
|
18083
18153
|
if (localPermissions !== deployedFile.skillFilePermissions) {
|
|
@@ -18106,13 +18176,13 @@ async function playbookStatusHandler(deps) {
|
|
|
18106
18176
|
(f) => normalizePath2(f.path).endsWith("/SKILL.md")
|
|
18107
18177
|
);
|
|
18108
18178
|
if (!skillMdFile) continue;
|
|
18109
|
-
const skillDir = normalizePath2(
|
|
18179
|
+
const skillDir = normalizePath2(path31.dirname(skillMdFile.path));
|
|
18110
18180
|
if (targetStagedPaths.has(skillDir) || targetSkillDirPaths.some(
|
|
18111
18181
|
(staged) => skillDir === staged || skillDir.startsWith(staged + "/")
|
|
18112
18182
|
)) {
|
|
18113
18183
|
continue;
|
|
18114
18184
|
}
|
|
18115
|
-
const absoluteSkillDir =
|
|
18185
|
+
const absoluteSkillDir = path31.join(projectDir, skillDir);
|
|
18116
18186
|
let localFiles;
|
|
18117
18187
|
try {
|
|
18118
18188
|
localFiles = listDirectoryFiles2(absoluteSkillDir);
|
|
@@ -18121,11 +18191,11 @@ async function playbookStatusHandler(deps) {
|
|
|
18121
18191
|
}
|
|
18122
18192
|
for (const localRelPath of localFiles) {
|
|
18123
18193
|
const normalizedLocalPath = normalizePath2(
|
|
18124
|
-
|
|
18194
|
+
path31.join(skillDir, localRelPath)
|
|
18125
18195
|
);
|
|
18126
18196
|
if (!deployedPathSet.has(normalizedLocalPath)) {
|
|
18127
18197
|
const displayPath = normalizePath2(
|
|
18128
|
-
|
|
18198
|
+
path31.relative(cwd, path31.join(projectDir, normalizedLocalPath))
|
|
18129
18199
|
);
|
|
18130
18200
|
untrackedChanges.push({
|
|
18131
18201
|
artifactName: entry.name,
|
|
@@ -18213,7 +18283,7 @@ var import_path5 = require("path");
|
|
|
18213
18283
|
var import_cmd_ts29 = __toESM(require_cjs());
|
|
18214
18284
|
|
|
18215
18285
|
// apps/cli/src/infra/commands/playbook/submitHandler.ts
|
|
18216
|
-
var
|
|
18286
|
+
var path33 = __toESM(require("path"));
|
|
18217
18287
|
|
|
18218
18288
|
// apps/cli/src/infra/commands/playbook/submit/duplicateNameChecker.ts
|
|
18219
18289
|
var import_slug2 = __toESM(require("slug"));
|
|
@@ -18275,7 +18345,7 @@ async function checkForDuplicateNames(createdEntries, packmindGateway) {
|
|
|
18275
18345
|
}
|
|
18276
18346
|
|
|
18277
18347
|
// apps/cli/src/infra/commands/playbook/submit/targetContextResolver.ts
|
|
18278
|
-
var
|
|
18348
|
+
var path32 = __toESM(require("path"));
|
|
18279
18349
|
async function createTargetContextResolver(deps) {
|
|
18280
18350
|
const { lockFileRepository, cwd, packmindCliHexa } = deps;
|
|
18281
18351
|
const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
|
|
@@ -18286,7 +18356,7 @@ async function createTargetContextResolver(deps) {
|
|
|
18286
18356
|
if (cache.has(key)) return cache.get(key);
|
|
18287
18357
|
let projectDir;
|
|
18288
18358
|
if (entry.configDir !== void 0 && gitRoot) {
|
|
18289
|
-
projectDir =
|
|
18359
|
+
projectDir = path32.join(gitRoot, entry.configDir);
|
|
18290
18360
|
} else {
|
|
18291
18361
|
projectDir = await findNearestConfigDir(cwd, packmindCliHexa);
|
|
18292
18362
|
}
|
|
@@ -19234,7 +19304,7 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
|
|
|
19234
19304
|
const entryCtx = resolver.getCachedContext(entry.configDir);
|
|
19235
19305
|
if (!entryCtx?.projectDir) continue;
|
|
19236
19306
|
try {
|
|
19237
|
-
const fullPath =
|
|
19307
|
+
const fullPath = path33.join(entryCtx.projectDir, entry.filePath);
|
|
19238
19308
|
if (entry.artifactType === "skill") {
|
|
19239
19309
|
deps.rmSync(fullPath, { recursive: true });
|
|
19240
19310
|
} else {
|
|
@@ -19262,7 +19332,7 @@ Only one agent version can be submitted at a time. Use "playbook unstage" to rem
|
|
|
19262
19332
|
const entryCtx = resolver.getCachedContext(entry.configDir);
|
|
19263
19333
|
if (!entryCtx?.projectDir) continue;
|
|
19264
19334
|
try {
|
|
19265
|
-
const fullPath =
|
|
19335
|
+
const fullPath = path33.join(entryCtx.projectDir, entry.filePath);
|
|
19266
19336
|
if (entry.artifactType === "skill") {
|
|
19267
19337
|
deps.rmSync(fullPath, { recursive: true });
|
|
19268
19338
|
} else {
|
|
@@ -19384,7 +19454,7 @@ var diffCommand2 = (0, import_cmd_ts30.command)({
|
|
|
19384
19454
|
type: (0, import_cmd_ts30.optional)(import_cmd_ts30.string)
|
|
19385
19455
|
})
|
|
19386
19456
|
},
|
|
19387
|
-
handler: async ({ includeSubmitted, path:
|
|
19457
|
+
handler: async ({ includeSubmitted, path: path37 }) => {
|
|
19388
19458
|
const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
|
|
19389
19459
|
const packmindCliHexa = new PackmindCliHexa(packmindLogger);
|
|
19390
19460
|
await diffArtefactsHandler({
|
|
@@ -19393,7 +19463,7 @@ var diffCommand2 = (0, import_cmd_ts30.command)({
|
|
|
19393
19463
|
getCwd: () => process.cwd(),
|
|
19394
19464
|
log: console.log,
|
|
19395
19465
|
includeSubmitted,
|
|
19396
|
-
path:
|
|
19466
|
+
path: path37
|
|
19397
19467
|
});
|
|
19398
19468
|
}
|
|
19399
19469
|
});
|
|
@@ -19482,8 +19552,8 @@ var import_cmd_ts39 = __toESM(require_cjs());
|
|
|
19482
19552
|
var import_cmd_ts38 = __toESM(require_cjs());
|
|
19483
19553
|
|
|
19484
19554
|
// apps/cli/src/application/services/AgentArtifactDetectionService.ts
|
|
19485
|
-
var
|
|
19486
|
-
var
|
|
19555
|
+
var fs26 = __toESM(require("fs/promises"));
|
|
19556
|
+
var path34 = __toESM(require("path"));
|
|
19487
19557
|
var AGENT_ARTIFACT_CHECKS = [
|
|
19488
19558
|
{ agent: "claude", paths: [".claude"] },
|
|
19489
19559
|
{ agent: "cursor", paths: [".cursor"] },
|
|
@@ -19512,7 +19582,7 @@ var AgentArtifactDetectionService = class {
|
|
|
19512
19582
|
}
|
|
19513
19583
|
} else {
|
|
19514
19584
|
for (const relativePath of check.paths) {
|
|
19515
|
-
const fullPath =
|
|
19585
|
+
const fullPath = path34.join(baseDirectory, relativePath);
|
|
19516
19586
|
const exists = await this.pathExists(fullPath);
|
|
19517
19587
|
if (exists) {
|
|
19518
19588
|
detected.push({
|
|
@@ -19528,7 +19598,7 @@ var AgentArtifactDetectionService = class {
|
|
|
19528
19598
|
}
|
|
19529
19599
|
async pathExists(filePath) {
|
|
19530
19600
|
try {
|
|
19531
|
-
await
|
|
19601
|
+
await fs26.access(filePath);
|
|
19532
19602
|
return true;
|
|
19533
19603
|
} catch {
|
|
19534
19604
|
return false;
|
|
@@ -19539,16 +19609,16 @@ var AgentArtifactDetectionService = class {
|
|
|
19539
19609
|
while (queue.length > 0) {
|
|
19540
19610
|
const currentDir = queue.shift();
|
|
19541
19611
|
for (const targetPath of targetPaths) {
|
|
19542
|
-
const fullPath =
|
|
19612
|
+
const fullPath = path34.join(currentDir, targetPath);
|
|
19543
19613
|
if (await this.pathExists(fullPath)) {
|
|
19544
19614
|
return fullPath;
|
|
19545
19615
|
}
|
|
19546
19616
|
}
|
|
19547
19617
|
try {
|
|
19548
|
-
const entries = await
|
|
19618
|
+
const entries = await fs26.readdir(currentDir, { withFileTypes: true });
|
|
19549
19619
|
for (const entry of entries) {
|
|
19550
19620
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
19551
|
-
queue.push(
|
|
19621
|
+
queue.push(path34.join(currentDir, entry.name));
|
|
19552
19622
|
}
|
|
19553
19623
|
}
|
|
19554
19624
|
} catch {
|
|
@@ -19563,18 +19633,18 @@ var readline4 = __toESM(require("readline"));
|
|
|
19563
19633
|
var inquirer2 = __toESM(require("inquirer"));
|
|
19564
19634
|
|
|
19565
19635
|
// apps/cli/src/infra/commands/config/agents/agentsHandlerUtils.ts
|
|
19566
|
-
var
|
|
19567
|
-
var
|
|
19636
|
+
var path35 = __toESM(require("path"));
|
|
19637
|
+
var fs27 = __toESM(require("fs/promises"));
|
|
19568
19638
|
function getRelativePath(dir, startDirectory) {
|
|
19569
19639
|
if (dir === startDirectory) return "./packmind.json";
|
|
19570
|
-
return "./" +
|
|
19640
|
+
return "./" + path35.relative(startDirectory, dir) + "/packmind.json";
|
|
19571
19641
|
}
|
|
19572
19642
|
async function resolveStartDirectory(args2, getCwd, exit) {
|
|
19573
19643
|
let startDirectory = getCwd();
|
|
19574
19644
|
if (args2.path) {
|
|
19575
|
-
const resolvedPath =
|
|
19645
|
+
const resolvedPath = path35.resolve(getCwd(), args2.path);
|
|
19576
19646
|
try {
|
|
19577
|
-
const stat9 = await
|
|
19647
|
+
const stat9 = await fs27.stat(resolvedPath);
|
|
19578
19648
|
if (!stat9.isDirectory()) {
|
|
19579
19649
|
logErrorConsole(`Path is not a directory: ${resolvedPath}`);
|
|
19580
19650
|
exit(1);
|
|
@@ -19685,7 +19755,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
19685
19755
|
output.write("\n");
|
|
19686
19756
|
const preselected = choices.map((c, i) => c.checked ? i + 1 : null).filter((i) => i !== null);
|
|
19687
19757
|
const defaultValue = preselected.length > 0 ? preselected.join(",") : "1,2,3";
|
|
19688
|
-
return new Promise((
|
|
19758
|
+
return new Promise((resolve15) => {
|
|
19689
19759
|
rl.question(
|
|
19690
19760
|
`Enter numbers separated by commas (default: ${defaultValue}): `,
|
|
19691
19761
|
(answer) => {
|
|
@@ -19694,7 +19764,7 @@ async function promptAgentsWithReadline2(choices) {
|
|
|
19694
19764
|
const numbersStr = trimmed === "" ? defaultValue : trimmed;
|
|
19695
19765
|
const numbers = numbersStr.split(",").map((s) => parseInt(s.trim(), 10)).filter((n) => !isNaN(n) && n >= 1 && n <= choices.length);
|
|
19696
19766
|
const selectedAgents = numbers.map((n) => choices[n - 1].value);
|
|
19697
|
-
|
|
19767
|
+
resolve15(selectedAgents);
|
|
19698
19768
|
}
|
|
19699
19769
|
);
|
|
19700
19770
|
});
|
|
@@ -19841,14 +19911,14 @@ To restore organization settings later, remove all local agents with: packmind-c
|
|
|
19841
19911
|
|
|
19842
19912
|
// apps/cli/src/infra/commands/config/ConfigAgentsAddCommand.ts
|
|
19843
19913
|
function createPromptConfirm() {
|
|
19844
|
-
return (message) => new Promise((
|
|
19914
|
+
return (message) => new Promise((resolve15) => {
|
|
19845
19915
|
const rl = readline5.createInterface({
|
|
19846
19916
|
input: process.stdin,
|
|
19847
19917
|
output: process.stdout
|
|
19848
19918
|
});
|
|
19849
19919
|
rl.question(`${message} (y/N) `, (answer) => {
|
|
19850
19920
|
rl.close();
|
|
19851
|
-
|
|
19921
|
+
resolve15(answer.toLowerCase() === "y");
|
|
19852
19922
|
});
|
|
19853
19923
|
});
|
|
19854
19924
|
}
|
|
@@ -20203,7 +20273,7 @@ async function initHandler(deps) {
|
|
|
20203
20273
|
}
|
|
20204
20274
|
|
|
20205
20275
|
// apps/cli/src/infra/commands/InitCommand.ts
|
|
20206
|
-
var { version:
|
|
20276
|
+
var { version: CLI_VERSION3 } = require_package();
|
|
20207
20277
|
var initCommand = (0, import_cmd_ts40.command)({
|
|
20208
20278
|
name: "init",
|
|
20209
20279
|
description: "Initialize Packmind in the current project",
|
|
@@ -20220,7 +20290,7 @@ var initCommand = (0, import_cmd_ts40.command)({
|
|
|
20220
20290
|
packmindGateway: packmindCliHexa.getPackmindGateway(),
|
|
20221
20291
|
baseDirectory,
|
|
20222
20292
|
installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
|
|
20223
|
-
cliVersion:
|
|
20293
|
+
cliVersion: CLI_VERSION3
|
|
20224
20294
|
});
|
|
20225
20295
|
if (!result.success) {
|
|
20226
20296
|
for (const error of result.errors) {
|
|
@@ -20233,7 +20303,7 @@ var initCommand = (0, import_cmd_ts40.command)({
|
|
|
20233
20303
|
|
|
20234
20304
|
// apps/cli/src/infra/commands/UpdateCommand.ts
|
|
20235
20305
|
var import_cmd_ts41 = __toESM(require_cjs());
|
|
20236
|
-
var { version:
|
|
20306
|
+
var { version: CLI_VERSION4 } = require_package();
|
|
20237
20307
|
var updateCommand = (0, import_cmd_ts41.command)({
|
|
20238
20308
|
name: "update",
|
|
20239
20309
|
description: "Update packmind-cli to the latest version",
|
|
@@ -20245,7 +20315,7 @@ var updateCommand = (0, import_cmd_ts41.command)({
|
|
|
20245
20315
|
},
|
|
20246
20316
|
handler: async ({ check }) => {
|
|
20247
20317
|
await updateHandler({
|
|
20248
|
-
currentVersion:
|
|
20318
|
+
currentVersion: CLI_VERSION4,
|
|
20249
20319
|
isExecutableMode: hasEmbeddedWasmFiles(),
|
|
20250
20320
|
executablePath: process.execPath,
|
|
20251
20321
|
scriptPath: require.main?.filename,
|
|
@@ -20258,25 +20328,25 @@ var updateCommand = (0, import_cmd_ts41.command)({
|
|
|
20258
20328
|
});
|
|
20259
20329
|
|
|
20260
20330
|
// apps/cli/src/main.ts
|
|
20261
|
-
var { version:
|
|
20331
|
+
var { version: CLI_VERSION5 } = require_package();
|
|
20262
20332
|
function findEnvFile() {
|
|
20263
20333
|
const currentDir = process.cwd();
|
|
20264
20334
|
const gitService = new GitService();
|
|
20265
20335
|
const gitRoot = gitService.getGitRepositoryRootSync(currentDir);
|
|
20266
|
-
const filesystemRoot =
|
|
20336
|
+
const filesystemRoot = path36.parse(currentDir).root;
|
|
20267
20337
|
const stopDir = gitRoot ?? filesystemRoot;
|
|
20268
20338
|
let searchDir = currentDir;
|
|
20269
|
-
let parentDir =
|
|
20339
|
+
let parentDir = path36.dirname(searchDir);
|
|
20270
20340
|
while (searchDir !== parentDir) {
|
|
20271
|
-
const envPath2 =
|
|
20272
|
-
if (
|
|
20341
|
+
const envPath2 = path36.join(searchDir, ".env");
|
|
20342
|
+
if (fs28.existsSync(envPath2)) {
|
|
20273
20343
|
return envPath2;
|
|
20274
20344
|
}
|
|
20275
20345
|
if (searchDir === stopDir) {
|
|
20276
20346
|
return null;
|
|
20277
20347
|
}
|
|
20278
20348
|
searchDir = parentDir;
|
|
20279
|
-
parentDir =
|
|
20349
|
+
parentDir = path36.dirname(searchDir);
|
|
20280
20350
|
}
|
|
20281
20351
|
return null;
|
|
20282
20352
|
}
|
|
@@ -20293,7 +20363,7 @@ if (hasEmbeddedWasmFiles()) {
|
|
|
20293
20363
|
}
|
|
20294
20364
|
var args = process.argv.slice(2);
|
|
20295
20365
|
if (args.includes("--version") || args.includes("-v")) {
|
|
20296
|
-
logConsole(`packmind-cli version ${
|
|
20366
|
+
logConsole(`packmind-cli version ${CLI_VERSION5}`);
|
|
20297
20367
|
process.exit(0);
|
|
20298
20368
|
}
|
|
20299
20369
|
var app = (0, import_cmd_ts42.subcommands)({
|