@packmind/cli 0.26.0 → 0.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/main.cjs +404 -305
  2. package/package.json +2 -1
package/main.cjs CHANGED
@@ -1582,6 +1582,9 @@ function stripAnsi(string21) {
1582
1582
  if (typeof string21 !== "string") {
1583
1583
  throw new TypeError(`Expected a \`string\`, got \`${typeof string21}\``);
1584
1584
  }
1585
+ if (!string21.includes("\x1B") && !string21.includes("\x9B")) {
1586
+ return string21;
1587
+ }
1585
1588
  return string21.replace(regex, "");
1586
1589
  }
1587
1590
  var regex;
@@ -3852,7 +3855,7 @@ var require_package = __commonJS({
3852
3855
  "apps/cli/package.json"(exports2, module2) {
3853
3856
  module2.exports = {
3854
3857
  name: "@packmind/cli",
3855
- version: "0.26.0",
3858
+ version: "0.26.1",
3856
3859
  description: "A command-line interface for Packmind linting and code quality checks",
3857
3860
  private: false,
3858
3861
  bin: {
@@ -4448,6 +4451,20 @@ var SpaceMembersRoleUpdatedEvent = class extends UserEvent {
4448
4451
  }
4449
4452
  };
4450
4453
 
4454
+ // packages/types/src/spaces/events/SpacePinnedEvent.ts
4455
+ var SpacePinnedEvent = class extends UserEvent {
4456
+ static {
4457
+ this.eventName = "spaces.space.pinned";
4458
+ }
4459
+ };
4460
+
4461
+ // packages/types/src/spaces/events/SpaceUnpinnedEvent.ts
4462
+ var SpaceUnpinnedEvent = class extends UserEvent {
4463
+ static {
4464
+ this.eventName = "spaces.space.unpinned";
4465
+ }
4466
+ };
4467
+
4451
4468
  // packages/types/src/spaces/events/SpaceVisibilityUpdatedEvent.ts
4452
4469
  var SpaceVisibilityUpdatedEvent = class extends UserEvent {
4453
4470
  static {
@@ -10569,9 +10586,12 @@ var InstallDefaultSkillsUseCase = class {
10569
10586
  const isIncompatible = command33.cliVersion && (this.isVersionConstraintViolated(
10570
10587
  file.content,
10571
10588
  command33.cliVersion
10572
- ) || incompatibleSkillDirs.has(path8.dirname(file.path)));
10589
+ ) || this.isUnderIncompatibleSkillDir(
10590
+ file.path,
10591
+ incompatibleSkillDirs
10592
+ ));
10573
10593
  if (isIncompatible) {
10574
- const skillName = this.getSkillName(file.content) ?? incompatibleSkillDirs.get(path8.dirname(file.path)) ?? path8.basename(file.path);
10594
+ const skillName = this.getSkillName(file.content) ?? this.getSkillNameForPath(file.path, incompatibleSkillDirs) ?? path8.basename(file.path);
10575
10595
  const fullPath = path8.join(baseDirectory, file.path);
10576
10596
  const fileAlreadyInstalled = await this.fileExists(fullPath);
10577
10597
  if (fileAlreadyInstalled) {
@@ -10631,6 +10651,25 @@ var InstallDefaultSkillsUseCase = class {
10631
10651
  return false;
10632
10652
  }
10633
10653
  }
10654
+ /**
10655
+ * Returns true if the given file path is inside one of the incompatible skill
10656
+ * directories, including nested subdirectories (e.g. `scripts/`).
10657
+ */
10658
+ isUnderIncompatibleSkillDir(filePath, incompatibleSkillDirs) {
10659
+ return this.getSkillNameForPath(filePath, incompatibleSkillDirs) !== null;
10660
+ }
10661
+ /**
10662
+ * Returns the skill name for the given file path by finding the incompatible
10663
+ * skill directory that contains it (including nested subdirectories).
10664
+ */
10665
+ getSkillNameForPath(filePath, incompatibleSkillDirs) {
10666
+ for (const [dir, skillName] of incompatibleSkillDirs.entries()) {
10667
+ if (filePath === dir || filePath.startsWith(dir + "/") || filePath.startsWith(dir + path8.sep)) {
10668
+ return skillName;
10669
+ }
10670
+ }
10671
+ return null;
10672
+ }
10634
10673
  /**
10635
10674
  * Returns true if the skill's `metadata.packmind-cli-version` constraint
10636
10675
  * is present AND the given CLI version does NOT satisfy it (i.e. the skill
@@ -11904,17 +11943,12 @@ var ListStandardsUseCase = class {
11904
11943
  const response = await this.packmindGateway.standards.list({
11905
11944
  spaceId: command33.spaceId
11906
11945
  });
11907
- return response.standards.map((s) => ({
11908
- ...s,
11909
- spaceId: command33.spaceId
11910
- }));
11946
+ return response.standards;
11911
11947
  }
11912
11948
  const spaces = await this.spaceService.getSpaces();
11913
11949
  const results = await Promise.all(
11914
11950
  spaces.map(
11915
- (space) => this.packmindGateway.standards.list({ spaceId: space.id }).then(
11916
- (r) => r.standards.map((s) => ({ ...s, spaceId: space.id }))
11917
- )
11951
+ (space) => this.packmindGateway.standards.list({ spaceId: space.id }).then((r) => r.standards)
11918
11952
  )
11919
11953
  );
11920
11954
  return results.flat();
@@ -11959,7 +11993,7 @@ var ListSkillsUseCase = class {
11959
11993
  slug: s.slug,
11960
11994
  name: s.name,
11961
11995
  description: s.description,
11962
- spaceId: command33.spaceId
11996
+ spaceId: s.spaceId
11963
11997
  }));
11964
11998
  }
11965
11999
  const spaces = await this.spaceService.getSpaces();
@@ -12068,7 +12102,11 @@ function normalizePath3(filePath) {
12068
12102
  }
12069
12103
  var MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024;
12070
12104
  var MAX_FILE_SIZE_MB = 10;
12071
- var BLACKLIST_PATTERNS = ["**/.DS_Store"];
12105
+ var BLACKLIST_PATTERNS = [
12106
+ "**/.DS_Store",
12107
+ "**/node_modules",
12108
+ "**/node_modules/**"
12109
+ ];
12072
12110
  function isBlacklisted(relativePath) {
12073
12111
  const normalizedPath = relativePath.replace(/\\/g, "/");
12074
12112
  return BLACKLIST_PATTERNS.some(
@@ -13332,13 +13370,151 @@ var SpaceService = class {
13332
13370
  }
13333
13371
  };
13334
13372
 
13373
+ // apps/cli/src/infra/repositories/CliOutput.ts
13374
+ init_source();
13375
+ var import_log_update = __toESM(require("log-update"));
13376
+ var CLI_PREFIX2 = "packmind-cli";
13377
+ var CliFormatter = class {
13378
+ static success(message) {
13379
+ return `${source_default.bgGreen.bold(CLI_PREFIX2)} ${source_default.green.bold(message)}`;
13380
+ }
13381
+ static info(message) {
13382
+ return `${source_default.bgBlue.bold(CLI_PREFIX2)} ${source_default.blue(message)}`;
13383
+ }
13384
+ static warning(message) {
13385
+ return `${source_default.bgYellow.bold(CLI_PREFIX2)} ${source_default.yellow.bold(message)}`;
13386
+ }
13387
+ static error(message) {
13388
+ return `${source_default.bgRed.bold(CLI_PREFIX2)} ${source_default.red(message)}`;
13389
+ }
13390
+ static command(command33) {
13391
+ return source_default.yellow(command33);
13392
+ }
13393
+ static loader(text) {
13394
+ return source_default.dim.italic(text);
13395
+ }
13396
+ static header(title) {
13397
+ return source_default.bold.underline(title);
13398
+ }
13399
+ static subHeader(title) {
13400
+ return source_default.bold(title);
13401
+ }
13402
+ static slug(slug3) {
13403
+ return source_default.blue.bold(slug3);
13404
+ }
13405
+ static label(label) {
13406
+ return source_default.dim(label);
13407
+ }
13408
+ };
13409
+ var CliOutput = class {
13410
+ constructor(logger2 = console) {
13411
+ this.logger = logger2;
13412
+ }
13413
+ notifySuccess(message, help) {
13414
+ this.notifyMessage(
13415
+ CliFormatter.success(message),
13416
+ (msg) => this.logger.log(msg),
13417
+ help
13418
+ );
13419
+ }
13420
+ notifyInfo(message, help) {
13421
+ this.notifyMessage(
13422
+ CliFormatter.info(message),
13423
+ (msg) => this.logger.log(msg),
13424
+ help
13425
+ );
13426
+ }
13427
+ notifyWarning(message, help) {
13428
+ this.notifyMessage(
13429
+ CliFormatter.warning(message),
13430
+ (msg) => this.logger.warn(msg),
13431
+ help
13432
+ );
13433
+ }
13434
+ notifyError(message, help) {
13435
+ this.notifyMessage(
13436
+ CliFormatter.error(message),
13437
+ (msg) => this.logger.error(msg),
13438
+ help
13439
+ );
13440
+ }
13441
+ showLoader(message) {
13442
+ this.logger.log(CliFormatter.loader(message));
13443
+ }
13444
+ async withLoader(message, loader) {
13445
+ (0, import_log_update.default)(CliFormatter.loader(message));
13446
+ try {
13447
+ return loader();
13448
+ } finally {
13449
+ import_log_update.default.clear();
13450
+ }
13451
+ }
13452
+ showArtefact(artefact, help) {
13453
+ this.logger.log(CliFormatter.label(artefact.slug));
13454
+ this.logger.log(CliFormatter.header(artefact.title));
13455
+ if (artefact.url) {
13456
+ this.logger.log(CliFormatter.label(artefact.url));
13457
+ }
13458
+ this.logger.log("");
13459
+ if (artefact.description) {
13460
+ this.logger.log(artefact.description);
13461
+ }
13462
+ this.logger.log("");
13463
+ this.displayHelp((msg) => this.logger.log(msg), help);
13464
+ }
13465
+ listArtefacts(title, artefacts, help) {
13466
+ this.logger.log(CliFormatter.header(title));
13467
+ this.logger.log("");
13468
+ this.displayList(artefacts);
13469
+ this.displayHelp((msg) => this.logger.log(msg), help);
13470
+ }
13471
+ listScopedArtefacts(title, scopedArtefacts, help) {
13472
+ this.logger.log(CliFormatter.header(title));
13473
+ this.logger.log("");
13474
+ for (const { title: title2, artefacts } of scopedArtefacts) {
13475
+ this.logger.log(CliFormatter.subHeader(title2));
13476
+ this.logger.log("");
13477
+ this.displayList(artefacts);
13478
+ }
13479
+ this.displayHelp((msg) => this.logger.log(msg), help);
13480
+ }
13481
+ notifyMessage(message, output, help) {
13482
+ output(message);
13483
+ this.displayHelp(output, help);
13484
+ }
13485
+ displayList(artefacts) {
13486
+ for (const artefact of artefacts) {
13487
+ this.logger.log(`- ${CliFormatter.label(artefact.slug)}`);
13488
+ this.logger.log(` Name: ${CliFormatter.header(artefact.title)}`);
13489
+ if (artefact.url) {
13490
+ this.logger.log(` ${CliFormatter.label(artefact.url)}`);
13491
+ }
13492
+ this.logger.log("");
13493
+ }
13494
+ }
13495
+ displayHelp(output, help) {
13496
+ if (help) {
13497
+ output(help.content);
13498
+ if (help.exampleCommand) {
13499
+ output(`
13500
+ Example: ${CliFormatter.command(help.exampleCommand)}`);
13501
+ }
13502
+ if (help.command) {
13503
+ output(`
13504
+ ${CliFormatter.command(help.command)}`);
13505
+ }
13506
+ }
13507
+ }
13508
+ };
13509
+
13335
13510
  // apps/cli/src/PackmindCliHexaFactory.ts
13336
13511
  var PackmindCliHexaFactory = class {
13337
13512
  constructor() {
13338
13513
  this.repositories = {
13339
13514
  packmindGateway: new PackmindGateway(loadApiKey()),
13340
13515
  configFileRepository: new ConfigFileRepository(),
13341
- lockFileRepository: new LockFileRepository()
13516
+ lockFileRepository: new LockFileRepository(),
13517
+ output: new CliOutput()
13342
13518
  };
13343
13519
  this.services = {
13344
13520
  listFiles: new ListFiles(),
@@ -13449,6 +13625,9 @@ var PackmindCliHexa = class {
13449
13625
  this.logger.info("Destroying PackmindCliHexa");
13450
13626
  this.logger.info("PackmindCliHexa destroyed");
13451
13627
  }
13628
+ get output() {
13629
+ return this.hexa.repositories.output;
13630
+ }
13452
13631
  async getGitRemoteUrl(command33) {
13453
13632
  return this.hexa.useCases.getGitRemoteUrl.execute(command33);
13454
13633
  }
@@ -14211,6 +14390,7 @@ ${uniqueCount} unique ${packageWord} currently installed.`);
14211
14390
  }
14212
14391
 
14213
14392
  // apps/cli/src/infra/commands/InstallCommand.ts
14393
+ var { version: CLI_VERSION } = require_package();
14214
14394
  function findSubDirectoriesWithPackmindJson(dirPath, recursive) {
14215
14395
  const result = [];
14216
14396
  let entries;
@@ -14320,6 +14500,34 @@ async function notifyArtefactsDistributionIfInGitRepo(params) {
14320
14500
  } catch {
14321
14501
  }
14322
14502
  }
14503
+ async function installDefaultSkillsIfAtGitRoot(params) {
14504
+ const { packmindCliHexa, cwd } = params;
14505
+ const gitRoot = await packmindCliHexa.tryGetGitRepositoryRoot(cwd);
14506
+ if (!gitRoot || cwd !== gitRoot) {
14507
+ return;
14508
+ }
14509
+ try {
14510
+ logConsole("\nInstalling default skills...");
14511
+ const skillsResult = await packmindCliHexa.installDefaultSkills({
14512
+ cliVersion: CLI_VERSION,
14513
+ baseDirectory: cwd
14514
+ });
14515
+ if (skillsResult.errors.length > 0) {
14516
+ skillsResult.errors.forEach((err) => {
14517
+ logWarningConsole(`Warning: ${err}`);
14518
+ });
14519
+ }
14520
+ const totalSkillFiles = skillsResult.filesCreated + skillsResult.filesUpdated;
14521
+ if (totalSkillFiles > 0) {
14522
+ logConsole(
14523
+ `Default skills: added ${skillsResult.filesCreated} files, changed ${skillsResult.filesUpdated} files`
14524
+ );
14525
+ } else if (skillsResult.errors.length === 0) {
14526
+ logConsole("Default skills are already up to date");
14527
+ }
14528
+ } catch {
14529
+ }
14530
+ }
14323
14531
  async function installHandler({
14324
14532
  installPath,
14325
14533
  packages,
@@ -14412,6 +14620,7 @@ async function installHandler({
14412
14620
  logWarningConsole(warning);
14413
14621
  }
14414
14622
  logConsole(buildInstallSummary(combined));
14623
+ await installDefaultSkillsIfAtGitRoot({ packmindCliHexa, cwd });
14415
14624
  const allErrors = [...combined.errors, ...thrownErrors];
14416
14625
  if (allErrors.length > 0) {
14417
14626
  logWarningConsole(`Encountered ${allErrors.length} error(s):`);
@@ -14627,7 +14836,7 @@ function displayVersionNotice(result) {
14627
14836
  }
14628
14837
 
14629
14838
  // apps/cli/src/infra/commands/WhoamiCommand.ts
14630
- var { version: CLI_VERSION } = require_package();
14839
+ var { version: CLI_VERSION2 } = require_package();
14631
14840
  function formatExpiresAt(expiresAt) {
14632
14841
  const now = /* @__PURE__ */ new Date();
14633
14842
  if (expiresAt < now) {
@@ -14671,7 +14880,7 @@ var whoamiCommand = (0, import_cmd_ts6.command)({
14671
14880
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
14672
14881
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
14673
14882
  const versionCheckPromise = packmindCliHexa.checkCliVersion({
14674
- currentVersion: CLI_VERSION
14883
+ currentVersion: CLI_VERSION2
14675
14884
  });
14676
14885
  const result = await packmindCliHexa.whoami({});
14677
14886
  if (!result.isAuthenticated) {
@@ -14986,9 +15195,14 @@ var addSkillCommand = (0, import_cmd_ts9.command)({
14986
15195
  originSkill: originSkillOption
14987
15196
  },
14988
15197
  handler: async () => {
14989
- logErrorConsole('Command "packmind-cli skills add" has been removed.');
14990
- logConsole(
14991
- `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15198
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15199
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
15200
+ packmindCliHexa.output.notifyError(
15201
+ 'Command "packmind-cli skills add" has been removed.',
15202
+ {
15203
+ content: 'Use the "playbook add" command instead:',
15204
+ exampleCommand: "packmind-cli playbook add .packmind/commands/my-command.md"
15205
+ }
14992
15206
  );
14993
15207
  process.exit(1);
14994
15208
  }
@@ -15042,7 +15256,7 @@ async function handleIncompatibleInstalledSkills(skills, baseDirectory, confirm)
15042
15256
  }
15043
15257
 
15044
15258
  // apps/cli/src/infra/commands/skills/InstallDefaultSkillsCommand.ts
15045
- var { version: CLI_VERSION2 } = require_package();
15259
+ var { version: CLI_VERSION3 } = require_package();
15046
15260
  var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15047
15261
  name: "install-default",
15048
15262
  description: "Install default Packmind skills for configured coding agents",
@@ -15060,7 +15274,7 @@ var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15060
15274
  const baseDirectory = process.cwd();
15061
15275
  const result = await packmindCliHexa.installDefaultSkills({
15062
15276
  includeBeta,
15063
- cliVersion: includeBeta ? void 0 : CLI_VERSION2,
15277
+ cliVersion: includeBeta ? void 0 : CLI_VERSION3,
15064
15278
  baseDirectory
15065
15279
  });
15066
15280
  if (result.skippedSkillsCount > 0) {
@@ -15068,13 +15282,6 @@ var installDefaultSkillsCommand = (0, import_cmd_ts10.command)({
15068
15282
  `${result.skippedSkillsCount} skill(s) were skipped because they require a newer version of packmind-cli. Run "${formatCommand("packmind-cli update")}" to get the latest version.`
15069
15283
  );
15070
15284
  }
15071
- if (result.skippedIncompatibleSkillNames.length > 0) {
15072
- for (const skillName of result.skippedIncompatibleSkillNames) {
15073
- logWarningConsole(
15074
- `Skill "${skillName}" was not installed because it is not compatible with this version of packmind-cli.`
15075
- );
15076
- }
15077
- }
15078
15285
  if (result.incompatibleInstalledSkills.length > 0) {
15079
15286
  await handleIncompatibleInstalledSkillsWithPrompt(
15080
15287
  result.incompatibleInstalledSkills,
@@ -15149,93 +15356,78 @@ function resolveUrlBuilder(buildArtifactPath) {
15149
15356
  return (spaceSlug, artifactId) => `${decoded.host}/org/${orgSlug}/space/${spaceSlug}/${buildArtifactPath(artifactId)}`;
15150
15357
  }
15151
15358
 
15152
- // apps/cli/src/infra/commands/skills/listSkillsHandler.ts
15153
- function groupSkillsBySpace(skills, spaces) {
15154
- const spaceMap = new Map(
15359
+ // apps/cli/src/infra/utils/groupArtefactsBySpaces.ts
15360
+ function groupArtefactBySpaces(artefacts, spaces) {
15361
+ const spacesById = new Map(
15155
15362
  spaces.map((s) => [s.id, s])
15156
15363
  );
15157
- const groupsMap = /* @__PURE__ */ new Map();
15158
- const orphaned = [];
15159
- for (const skill of skills) {
15160
- const space = spaceMap.get(skill.spaceId);
15161
- if (!space) {
15162
- orphaned.push(skill);
15163
- continue;
15164
- }
15165
- let group = groupsMap.get(space.id);
15166
- if (!group) {
15167
- group = { space, items: [] };
15168
- groupsMap.set(space.id, group);
15169
- }
15170
- group.items.push(skill);
15171
- }
15172
- const groups = [...groupsMap.values()].sort(
15173
- (a, b) => a.space.name.localeCompare(b.space.name)
15174
- );
15175
- return { groups, orphaned };
15176
- }
15177
- function displayGroupedSkills(skills, spaces, buildUrl) {
15178
- const { groups, orphaned } = groupSkillsBySpace(skills, spaces);
15179
- for (const { space, items } of groups) {
15180
- logConsole(`Space "${space.name}":
15181
- `);
15182
- for (const skill of [...items].sort(
15183
- (a, b) => a.slug.localeCompare(b.slug)
15184
- )) {
15185
- logConsole(` ${formatSlug(skill.slug)}`);
15186
- logConsole(` ${formatLabel("Name:")} ${skill.name}`);
15187
- if (skill.description) {
15188
- const descriptionLines = skill.description.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
15189
- const firstLine = descriptionLines[0];
15190
- if (firstLine) {
15191
- const truncated = firstLine.length > 80 ? firstLine.slice(0, 77) + "..." : firstLine;
15192
- logConsole(` ${formatLabel("Desc:")} ${truncated}`);
15193
- }
15194
- }
15195
- const url = buildUrl(space.slug, skill.slug);
15196
- if (url) {
15197
- logConsole(` ${formatLabel("Link:")} ${url}`);
15198
- }
15199
- logConsole("");
15364
+ const groupedArtefacts = artefacts.reduce((acc, artefact) => {
15365
+ const space = spacesById.get(artefact.spaceId);
15366
+ if (space) {
15367
+ const group = acc.get(artefact.spaceId) ?? { space, artefacts: [] };
15368
+ acc.set(artefact.spaceId, {
15369
+ space,
15370
+ artefacts: [...group.artefacts, artefact]
15371
+ });
15200
15372
  }
15201
- }
15202
- for (const skill of [...orphaned].sort(
15203
- (a, b) => a.slug.localeCompare(b.slug)
15204
- )) {
15205
- logConsole(` ${formatSlug(skill.slug)}`);
15206
- logConsole(` ${formatLabel("Name:")} ${skill.name}`);
15207
- logConsole("");
15208
- }
15373
+ return acc;
15374
+ }, /* @__PURE__ */ new Map());
15375
+ return [...groupedArtefacts.values()].map(({ space, artefacts: artefacts2 }) => ({
15376
+ space,
15377
+ artefacts: [...artefacts2].sort((a, b) => a.slug.localeCompare(b.slug))
15378
+ })).sort((a, b) => a.space.name.localeCompare(b.space.name));
15209
15379
  }
15380
+
15381
+ // apps/cli/src/infra/commands/skills/listSkillsHandler.ts
15210
15382
  async function listSkillsHandler(args2, deps) {
15211
15383
  const { packmindCliHexa, exit } = deps;
15212
15384
  try {
15213
- logConsole("Fetching skills...\n");
15214
- const spaces = await packmindCliHexa.getSpaces();
15385
+ const spaces = await packmindCliHexa.output.withLoader(
15386
+ "Fetching spaces",
15387
+ () => packmindCliHexa.getSpaces()
15388
+ );
15215
15389
  const matchedSpace = resolveSpaceFromArgs(args2.space, spaces);
15216
15390
  if (args2.space && !matchedSpace) {
15217
- logErrorConsole(`Space "@${args2.space}" not found.`);
15391
+ const availableSpaces = spaces.map((s) => ` - @${s.slug}`).join("\n");
15392
+ packmindCliHexa.output.notifyError(`Space "@${args2.space}" not found.`, {
15393
+ content: `Available spaces:
15394
+ ${availableSpaces}`
15395
+ });
15218
15396
  exit(1);
15219
15397
  return;
15220
15398
  }
15221
- const skills = await packmindCliHexa.listSkills(
15222
- matchedSpace ? { spaceId: matchedSpace.id } : {}
15399
+ const skills = await packmindCliHexa.output.withLoader(
15400
+ "Fetching skills",
15401
+ () => packmindCliHexa.listSkills(
15402
+ matchedSpace ? { spaceId: matchedSpace.id } : {}
15403
+ )
15223
15404
  );
15224
15405
  if (skills.length === 0) {
15225
- logConsole(
15406
+ packmindCliHexa.output.notifyInfo(
15226
15407
  matchedSpace ? `No skills found in space "@${matchedSpace.slug}".` : "No skills found."
15227
15408
  );
15228
15409
  exit(0);
15229
15410
  return;
15230
15411
  }
15231
- logConsole(formatHeader(`\u{1F4CB} Skills (${skills.length})
15232
- `));
15233
15412
  const buildUrl = resolveUrlBuilder((slug3) => `skills/${slug3}/files`);
15234
- displayGroupedSkills(skills, spaces, buildUrl);
15413
+ const groups = groupArtefactBySpaces(skills, spaces);
15414
+ packmindCliHexa.output.listScopedArtefacts(
15415
+ `\u{1F4CB} Skills (${skills.length})`,
15416
+ groups.map(({ space, artefacts }) => ({
15417
+ title: `Space: ${space.name}`,
15418
+ artefacts: artefacts.map((skill) => ({
15419
+ title: skill.name,
15420
+ slug: skill.slug,
15421
+ description: skill.description ?? void 0,
15422
+ url: buildUrl(space.slug, skill.slug)
15423
+ }))
15424
+ }))
15425
+ );
15235
15426
  exit(0);
15236
15427
  } catch (err) {
15237
- logErrorConsole("Failed to list skills:");
15238
- logErrorConsole(err instanceof Error ? err.message : String(err));
15428
+ packmindCliHexa.output.notifyError("Failed to list skills:", {
15429
+ content: err instanceof Error ? err.message : String(err)
15430
+ });
15239
15431
  exit(1);
15240
15432
  }
15241
15433
  }
@@ -15297,11 +15489,14 @@ var createStandardCommand = (0, import_cmd_ts13.command)({
15297
15489
  originSkill: originSkillOption
15298
15490
  },
15299
15491
  handler: async () => {
15300
- logErrorConsole(
15301
- 'Command "packmind-cli standards create" has been removed.'
15302
- );
15303
- logConsole(
15304
- `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15492
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15493
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
15494
+ packmindCliHexa.output.notifyError(
15495
+ 'Command "packmind-cli standards create" has been removed.',
15496
+ {
15497
+ content: 'Use the "playbook add" command instead:',
15498
+ exampleCommand: "packmind-cli playbook add .packmind/standards/my-standard.md"
15499
+ }
15305
15500
  );
15306
15501
  process.exit(1);
15307
15502
  }
@@ -15311,92 +15506,55 @@ var createStandardCommand = (0, import_cmd_ts13.command)({
15311
15506
  var import_cmd_ts14 = __toESM(require_cjs());
15312
15507
 
15313
15508
  // apps/cli/src/infra/commands/standards/listStandardsHandler.ts
15314
- function groupStandardsBySpace(standards, spaces) {
15315
- const spaceMap = new Map(
15316
- spaces.map((s) => [s.id, s])
15317
- );
15318
- const groupsMap = /* @__PURE__ */ new Map();
15319
- const orphaned = [];
15320
- for (const standard of standards) {
15321
- const space = spaceMap.get(standard.spaceId);
15322
- if (!space) {
15323
- orphaned.push(standard);
15324
- continue;
15325
- }
15326
- let group = groupsMap.get(space.id);
15327
- if (!group) {
15328
- group = { space, items: [] };
15329
- groupsMap.set(space.id, group);
15330
- }
15331
- group.items.push(standard);
15332
- }
15333
- const groups = [...groupsMap.values()].sort(
15334
- (a, b) => a.space.name.localeCompare(b.space.name)
15335
- );
15336
- return { groups, orphaned };
15337
- }
15338
- function displayGroupedStandards(standards, spaces, buildUrl) {
15339
- const { groups, orphaned } = groupStandardsBySpace(standards, spaces);
15340
- for (const { space, items } of groups) {
15341
- logConsole(`Space "${space.name}":
15342
- `);
15343
- for (const standard of [...items].sort(
15344
- (a, b) => a.slug.localeCompare(b.slug)
15345
- )) {
15346
- logConsole(` ${formatSlug(standard.slug)}`);
15347
- logConsole(` ${formatLabel("Name:")} ${standard.name}`);
15348
- if (standard.description) {
15349
- const descriptionLines = standard.description.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
15350
- const firstLine = descriptionLines[0];
15351
- if (firstLine) {
15352
- const truncated = firstLine.length > 80 ? firstLine.slice(0, 77) + "..." : firstLine;
15353
- logConsole(` ${formatLabel("Desc:")} ${truncated}`);
15354
- }
15355
- }
15356
- const url = buildUrl(space.slug, standard.id);
15357
- if (url) {
15358
- logConsole(` ${formatLabel("Link:")} ${url}`);
15359
- }
15360
- logConsole("");
15361
- }
15362
- }
15363
- for (const standard of [...orphaned].sort(
15364
- (a, b) => a.slug.localeCompare(b.slug)
15365
- )) {
15366
- logConsole(` ${formatSlug(standard.slug)}`);
15367
- logConsole(` ${formatLabel("Name:")} ${standard.name}`);
15368
- logConsole("");
15369
- }
15370
- }
15371
15509
  async function listStandardsHandler(args2, deps) {
15372
15510
  const { packmindCliHexa, exit } = deps;
15373
15511
  try {
15374
- logConsole("Fetching standards...\n");
15375
- const spaces = await packmindCliHexa.getSpaces();
15512
+ const spaces = await packmindCliHexa.output.withLoader(
15513
+ "Fetching spaces",
15514
+ () => packmindCliHexa.getSpaces()
15515
+ );
15376
15516
  const matchedSpace = resolveSpaceFromArgs(args2.space, spaces);
15377
15517
  if (args2.space && !matchedSpace) {
15378
- logErrorConsole(`Space "@${args2.space}" not found.`);
15518
+ const availableSpaces = spaces.map((space) => ` - @${space.slug}`).join("\n");
15519
+ packmindCliHexa.output.notifyError(`Space "@${args2.space}" not found.`, {
15520
+ content: `Available spaces:
15521
+ ${availableSpaces}`
15522
+ });
15379
15523
  exit(1);
15380
15524
  return;
15381
15525
  }
15382
- const standards = await packmindCliHexa.listStandards(
15383
- matchedSpace ? { spaceId: matchedSpace.id } : {}
15526
+ const standards = await packmindCliHexa.output.withLoader(
15527
+ "Fetching standards",
15528
+ () => packmindCliHexa.listStandards(
15529
+ matchedSpace ? { spaceId: matchedSpace.id } : {}
15530
+ )
15384
15531
  );
15385
15532
  if (standards.length === 0) {
15386
- logConsole(
15533
+ packmindCliHexa.output.notifyInfo(
15387
15534
  matchedSpace ? `No standards found in space "@${matchedSpace.slug}".` : "No standards found."
15388
15535
  );
15389
15536
  exit(0);
15390
15537
  return;
15391
15538
  }
15392
- logConsole(formatHeader(`\u{1F4CB} Standards (${standards.length})
15393
- `));
15539
+ const groupedStandards = groupArtefactBySpaces(standards, spaces);
15394
15540
  const buildUrl = resolveUrlBuilder((id) => `standards/${id}/summary`);
15395
- displayGroupedStandards(standards, spaces, buildUrl);
15541
+ const scopedArtefacts = groupedStandards.map(({ space, artefacts }) => ({
15542
+ title: `Space: ${space.name}`,
15543
+ artefacts: artefacts.map((s) => ({
15544
+ title: s.name,
15545
+ slug: s.slug,
15546
+ url: buildUrl(space.slug, s.id)
15547
+ }))
15548
+ }));
15549
+ packmindCliHexa.output.listScopedArtefacts(
15550
+ `\u{1F4CB} Standards (${standards.length})`,
15551
+ scopedArtefacts
15552
+ );
15396
15553
  exit(0);
15397
15554
  } catch (err) {
15398
- logErrorConsole("Failed to list standards:");
15399
- logErrorConsole(err instanceof Error ? err.message : String(err));
15555
+ packmindCliHexa.output.notifyError("Failed to list standards:", {
15556
+ content: err instanceof Error ? err.message : String(err)
15557
+ });
15400
15558
  exit(1);
15401
15559
  }
15402
15560
  }
@@ -15457,9 +15615,14 @@ var createCommandCommand = (0, import_cmd_ts16.command)({
15457
15615
  originSkill: originSkillOption
15458
15616
  },
15459
15617
  handler: async () => {
15460
- logErrorConsole('Command "packmind-cli commands create" has been removed.');
15461
- logConsole(
15462
- `Use ${formatCommand("packmind-cli playbook add <path>")} instead.`
15618
+ const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
15619
+ const packmindCliHexa = new PackmindCliHexa(packmindLogger);
15620
+ packmindCliHexa.output.notifyError(
15621
+ 'Command "packmind-cli commands create" has been removed.',
15622
+ {
15623
+ content: 'Use the "playbook add" command instead:',
15624
+ exampleCommand: "packmind-cli playbook add .packmind/commands/my-command.md"
15625
+ }
15463
15626
  );
15464
15627
  process.exit(1);
15465
15628
  }
@@ -15469,86 +15632,54 @@ var createCommandCommand = (0, import_cmd_ts16.command)({
15469
15632
  var import_cmd_ts17 = __toESM(require_cjs());
15470
15633
 
15471
15634
  // apps/cli/src/infra/commands/commands/listCommandsHandler.ts
15472
- function groupCommandsBySpace(commands, spaces) {
15473
- const spaceMap = new Map(
15474
- spaces.map((s) => [s.id, s])
15475
- );
15476
- const groupsMap = /* @__PURE__ */ new Map();
15477
- const orphaned = [];
15478
- for (const cmd of commands) {
15479
- const space = spaceMap.get(cmd.spaceId);
15480
- if (!space) {
15481
- orphaned.push(cmd);
15482
- continue;
15483
- }
15484
- let group = groupsMap.get(space.id);
15485
- if (!group) {
15486
- group = { space, cmds: [] };
15487
- groupsMap.set(space.id, group);
15488
- }
15489
- group.cmds.push(cmd);
15490
- }
15491
- const groups = [...groupsMap.values()].sort(
15492
- (a, b) => a.space.name.localeCompare(b.space.name)
15493
- );
15494
- return { groups, orphaned };
15495
- }
15496
- function displayGroupedCommands(commands, spaces, buildUrl) {
15497
- const { groups, orphaned } = groupCommandsBySpace(commands, spaces);
15498
- for (const { space, cmds } of groups) {
15499
- logConsole(`Space "${space.name}":
15500
- `);
15501
- for (const cmd of [...cmds].sort((a, b) => a.slug.localeCompare(b.slug))) {
15502
- logConsole(` ${formatSlug(cmd.slug)}`);
15503
- logConsole(` ${formatLabel("Name:")} ${cmd.name}`);
15504
- const url = buildUrl(space.slug, cmd.id);
15505
- if (url) {
15506
- logConsole(` ${formatLabel("Link:")} ${url}`);
15507
- }
15508
- logConsole("");
15509
- }
15510
- }
15511
- for (const cmd of [...orphaned].sort(
15512
- (a, b) => a.slug.localeCompare(b.slug)
15513
- )) {
15514
- logConsole(` ${formatSlug(cmd.slug)}`);
15515
- logConsole(` ${formatLabel("Name:")} ${cmd.name}`);
15516
- logConsole("");
15517
- }
15518
- }
15519
15635
  async function listCommandsHandler(args2, deps) {
15520
15636
  const { packmindCliHexa, exit } = deps;
15521
15637
  try {
15522
- logConsole("Fetching commands...\n");
15523
- const spaces = await packmindCliHexa.getSpaces();
15638
+ const spaces = await packmindCliHexa.output.withLoader(
15639
+ "Fetching spaces",
15640
+ () => packmindCliHexa.getSpaces()
15641
+ );
15524
15642
  const matchedSpace = resolveSpaceFromArgs(args2.space, spaces);
15525
15643
  if (args2.space && !matchedSpace) {
15526
- logErrorConsole(`Space "@${args2.space}" not found.`);
15644
+ const availableSpaces = spaces.map((space) => ` - @${space.slug}`).join("\n");
15645
+ packmindCliHexa.output.notifyError(`Space "@${args2.space}" not found.`, {
15646
+ content: `Available spaces:
15647
+ ${availableSpaces}`
15648
+ });
15527
15649
  exit(1);
15528
15650
  return;
15529
15651
  }
15530
- const commands = await packmindCliHexa.listCommands(
15531
- matchedSpace ? { spaceId: matchedSpace.id } : {}
15652
+ const commands = await packmindCliHexa.output.withLoader(
15653
+ "Fetching commands",
15654
+ () => packmindCliHexa.listCommands(
15655
+ matchedSpace ? { spaceId: matchedSpace.id } : {}
15656
+ )
15532
15657
  );
15533
15658
  if (commands.length === 0) {
15534
- logConsole(
15659
+ packmindCliHexa.output.notifyInfo(
15535
15660
  matchedSpace ? `No commands found in space "@${matchedSpace.slug}".` : "No commands found."
15536
15661
  );
15537
15662
  exit(0);
15538
15663
  return;
15539
15664
  }
15540
- logConsole(formatHeader(`\u{1F4CB} Commands (${commands.length})
15541
- `));
15665
+ const groupedCommands = groupArtefactBySpaces(commands, spaces);
15542
15666
  const buildUrl = resolveUrlBuilder((id) => `commands/${id}`);
15543
- displayGroupedCommands(commands, spaces, buildUrl);
15667
+ packmindCliHexa.output.listScopedArtefacts(
15668
+ `\u{1F4CB} Commands (${commands.length})`,
15669
+ groupedCommands.map(({ space, artefacts }) => ({
15670
+ title: `Space: ${space.name}`,
15671
+ artefacts: artefacts.map((cmd) => ({
15672
+ title: cmd.name,
15673
+ slug: cmd.slug,
15674
+ url: buildUrl(space.slug, cmd.id)
15675
+ }))
15676
+ }))
15677
+ );
15544
15678
  exit(0);
15545
15679
  } catch (err) {
15546
- logErrorConsole("Failed to list commands:");
15547
- if (err instanceof Error) {
15548
- logErrorConsole(err.message);
15549
- } else {
15550
- logErrorConsole(String(err));
15551
- }
15680
+ packmindCliHexa.output.notifyError("Failed to list commands:", {
15681
+ content: err instanceof Error ? err.message : String(err)
15682
+ });
15552
15683
  exit(1);
15553
15684
  }
15554
15685
  }
@@ -16541,97 +16672,65 @@ var addToPackageCommand = (0, import_cmd_ts21.command)({
16541
16672
  var import_cmd_ts22 = __toESM(require_cjs());
16542
16673
 
16543
16674
  // 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
16675
  async function listPackagesHandler(args2, deps) {
16595
16676
  const { packmindCliHexa, exit } = deps;
16596
16677
  try {
16597
- logInfoConsole("Fetching available packages...");
16598
- const allSpaces = await packmindCliHexa.getSpaces();
16678
+ const allSpaces = await packmindCliHexa.output.withLoader(
16679
+ "Fetching spaces",
16680
+ () => packmindCliHexa.getSpaces()
16681
+ );
16599
16682
  if (!allSpaces || allSpaces.length === 0) {
16600
16683
  throw new Error("Unable to list organization spaces.");
16601
16684
  }
16602
16685
  const matchedSpace = resolveSpaceFromArgs(args2.space, allSpaces);
16603
16686
  if (args2.space && !matchedSpace) {
16604
- logErrorConsole(`Space "@${args2.space}" not found.`);
16605
- logInfoConsole(
16606
- `Available spaces: ${allSpaces.map((s) => `@${s.slug}`).join(", ")}`
16607
- );
16687
+ const availableSpaces = allSpaces.map((s) => ` - @${s.slug}`).join("\n");
16688
+ packmindCliHexa.output.notifyError(`Space "@${args2.space}" not found.`, {
16689
+ content: `Available spaces:
16690
+ ${availableSpaces}`
16691
+ });
16608
16692
  exit(1);
16609
16693
  return;
16610
16694
  }
16611
- const packages = await packmindCliHexa.listPackages(
16612
- matchedSpace ? { spaceId: matchedSpace.id } : {}
16695
+ const packages = await packmindCliHexa.output.withLoader(
16696
+ "Fetching packages",
16697
+ () => packmindCliHexa.listPackages(
16698
+ matchedSpace ? { spaceId: matchedSpace.id } : {}
16699
+ )
16613
16700
  );
16614
16701
  const spaces = matchedSpace ? [matchedSpace] : allSpaces;
16615
16702
  if (packages.length === 0) {
16616
- logConsole(
16703
+ packmindCliHexa.output.notifyInfo(
16617
16704
  matchedSpace ? `No packages found in space "@${matchedSpace.slug}".` : "No packages found."
16618
16705
  );
16619
16706
  exit(0);
16620
16707
  return;
16621
16708
  }
16622
16709
  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}`)}`);
16710
+ const groups = groupArtefactBySpaces(packages, spaces);
16711
+ const scopedArtefacts = groups.map(({ space, artefacts }) => ({
16712
+ title: `Space: ${space.name}`,
16713
+ artefacts: artefacts.map((pkg) => ({
16714
+ title: pkg.name,
16715
+ slug: `@${space.slug}/${pkg.slug}`,
16716
+ description: pkg.description,
16717
+ url: buildUrl(space.slug, pkg.id)
16718
+ }))
16719
+ }));
16720
+ const firstSlug = scopedArtefacts[0]?.artefacts[0]?.slug ?? `@${packages[0].slug}`;
16721
+ packmindCliHexa.output.listScopedArtefacts(
16722
+ `\u{1F4E6} Packages (${packages.length})`,
16723
+ scopedArtefacts,
16724
+ {
16725
+ content: "How to install a package:",
16726
+ exampleCommand: `packmind-cli install ${firstSlug}`
16727
+ }
16728
+ );
16627
16729
  exit(0);
16628
16730
  } catch (err) {
16629
- logErrorConsole("Failed to list packages:");
16630
- if (err instanceof Error) {
16631
- logErrorConsole(err.message);
16632
- } else {
16633
- logErrorConsole(String(err));
16634
- }
16731
+ packmindCliHexa.output.notifyError("Failed to list packages:", {
16732
+ content: err instanceof Error ? err.message : String(err)
16733
+ });
16635
16734
  exit(1);
16636
16735
  }
16637
16736
  }
@@ -20273,7 +20372,7 @@ async function initHandler(deps) {
20273
20372
  }
20274
20373
 
20275
20374
  // apps/cli/src/infra/commands/InitCommand.ts
20276
- var { version: CLI_VERSION3 } = require_package();
20375
+ var { version: CLI_VERSION4 } = require_package();
20277
20376
  var initCommand = (0, import_cmd_ts40.command)({
20278
20377
  name: "init",
20279
20378
  description: "Initialize Packmind in the current project",
@@ -20290,7 +20389,7 @@ var initCommand = (0, import_cmd_ts40.command)({
20290
20389
  packmindGateway: packmindCliHexa.getPackmindGateway(),
20291
20390
  baseDirectory,
20292
20391
  installDefaultSkills: packmindCliHexa.installDefaultSkills.bind(packmindCliHexa),
20293
- cliVersion: CLI_VERSION3
20392
+ cliVersion: CLI_VERSION4
20294
20393
  });
20295
20394
  if (!result.success) {
20296
20395
  for (const error of result.errors) {
@@ -20303,7 +20402,7 @@ var initCommand = (0, import_cmd_ts40.command)({
20303
20402
 
20304
20403
  // apps/cli/src/infra/commands/UpdateCommand.ts
20305
20404
  var import_cmd_ts41 = __toESM(require_cjs());
20306
- var { version: CLI_VERSION4 } = require_package();
20405
+ var { version: CLI_VERSION5 } = require_package();
20307
20406
  var updateCommand = (0, import_cmd_ts41.command)({
20308
20407
  name: "update",
20309
20408
  description: "Update packmind-cli to the latest version",
@@ -20315,7 +20414,7 @@ var updateCommand = (0, import_cmd_ts41.command)({
20315
20414
  },
20316
20415
  handler: async ({ check }) => {
20317
20416
  await updateHandler({
20318
- currentVersion: CLI_VERSION4,
20417
+ currentVersion: CLI_VERSION5,
20319
20418
  isExecutableMode: hasEmbeddedWasmFiles(),
20320
20419
  executablePath: process.execPath,
20321
20420
  scriptPath: require.main?.filename,
@@ -20328,7 +20427,7 @@ var updateCommand = (0, import_cmd_ts41.command)({
20328
20427
  });
20329
20428
 
20330
20429
  // apps/cli/src/main.ts
20331
- var { version: CLI_VERSION5 } = require_package();
20430
+ var { version: CLI_VERSION6 } = require_package();
20332
20431
  function findEnvFile() {
20333
20432
  const currentDir = process.cwd();
20334
20433
  const gitService = new GitService();
@@ -20363,7 +20462,7 @@ if (hasEmbeddedWasmFiles()) {
20363
20462
  }
20364
20463
  var args = process.argv.slice(2);
20365
20464
  if (args.includes("--version") || args.includes("-v")) {
20366
- logConsole(`packmind-cli version ${CLI_VERSION5}`);
20465
+ logConsole(`packmind-cli version ${CLI_VERSION6}`);
20367
20466
  process.exit(0);
20368
20467
  }
20369
20468
  var app = (0, import_cmd_ts42.subcommands)({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@packmind/cli",
3
- "version": "0.26.0",
3
+ "version": "0.26.1",
4
4
  "description": "A command-line interface for Packmind linting and code quality checks",
5
5
  "private": false,
6
6
  "bin": {
@@ -52,6 +52,7 @@
52
52
  "dotenv": "16.4.7",
53
53
  "express": "5.2.1",
54
54
  "inquirer": "^13.0.2",
55
+ "log-update": "8.0.0",
55
56
  "minimatch": "10.2.4",
56
57
  "open": "11.0.0",
57
58
  "semver": "^7.7.4",