@packmind/cli 0.35.0 → 0.35.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 +191 -263
  2. package/package.json +1 -1
package/main.cjs CHANGED
@@ -3858,7 +3858,7 @@ var require_package = __commonJS({
3858
3858
  "apps/cli/package.json"(exports2, module2) {
3859
3859
  module2.exports = {
3860
3860
  name: "@packmind/cli",
3861
- version: "0.35.0",
3861
+ version: "0.35.1",
3862
3862
  description: "A command-line interface for Packmind linting and code quality checks",
3863
3863
  private: false,
3864
3864
  bin: {
@@ -3994,32 +3994,10 @@ var PackmindLogger = class {
3994
3994
  if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
3995
3995
  this.logger.info(message, meta);
3996
3996
  }
3997
- http(message, meta) {
3998
- if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
3999
- this.logger.http(message, meta);
4000
- }
4001
- verbose(message, meta) {
4002
- if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
4003
- this.logger.verbose(message, meta);
4004
- }
4005
3997
  debug(message, meta) {
4006
3998
  if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
4007
3999
  this.logger.debug(message, meta);
4008
4000
  }
4009
- silly(message, meta) {
4010
- if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
4011
- this.logger.silly(message, meta);
4012
- }
4013
- log(level, message, meta) {
4014
- if (this.currentLevel === "silent" /* SILENT */ || !this.logger) return;
4015
- this.logger.log(level, message, meta);
4016
- }
4017
- setLevel(level) {
4018
- this.currentLevel = level;
4019
- if (level !== "silent" /* SILENT */ && this.logger) {
4020
- this.logger.level = level;
4021
- }
4022
- }
4023
4001
  getName() {
4024
4002
  return this.name;
4025
4003
  }
@@ -4521,6 +4499,9 @@ var PluginRenderedEvent = class extends UserEvent {
4521
4499
  }
4522
4500
  };
4523
4501
 
4502
+ // packages/types/src/edition/PackmindEdition.ts
4503
+ var PACKMIND_EDITION_HEADER = "Packmind-Edition";
4504
+
4524
4505
  // packages/types/src/git/GitRepoId.ts
4525
4506
  var createGitRepoId = brandedIdFactory();
4526
4507
 
@@ -6931,8 +6912,48 @@ var CommunityEditionError = class extends Error {
6931
6912
  }
6932
6913
  };
6933
6914
  function isCommunityEditionError(tbd) {
6934
- return tbd.isCommunityEditionError;
6915
+ return typeof tbd === "object" && tbd !== null && tbd.isCommunityEditionError === true;
6916
+ }
6917
+
6918
+ // apps/cli/src/infra/http/packmindEdition.ts
6919
+ var KNOWN_EDITIONS = {
6920
+ enterprise: true,
6921
+ community: true
6922
+ };
6923
+ var LEGACY_EDITIONS = {
6924
+ cloud: "enterprise",
6925
+ oss: "community"
6926
+ };
6927
+ function parsePackmindEdition(value) {
6928
+ if (typeof value !== "string") {
6929
+ return null;
6930
+ }
6931
+ if (Object.prototype.hasOwnProperty.call(KNOWN_EDITIONS, value)) {
6932
+ return value;
6933
+ }
6934
+ return Object.prototype.hasOwnProperty.call(LEGACY_EDITIONS, value) ? LEGACY_EDITIONS[value] : null;
6935
+ }
6936
+ function readPackmindEdition(response) {
6937
+ return parsePackmindEdition(response.headers.get(PACKMIND_EDITION_HEADER));
6935
6938
  }
6939
+ function throwIfFeatureAbsent(response, edition, feature) {
6940
+ if (response.status !== 404) {
6941
+ return;
6942
+ }
6943
+ if (edition === "community") {
6944
+ throw new CommunityEditionError(feature);
6945
+ }
6946
+ if (edition === null) {
6947
+ throw unstatedEditionError(feature);
6948
+ }
6949
+ }
6950
+ var unstatedEditionError = (feature) => {
6951
+ const error = new Error(
6952
+ `The "${feature}" feature answered 404 and this Packmind server does not state which edition it runs. The feature is not part of Packmind Community Edition; on an Enterprise deployment, check that the space and organization still exist.`
6953
+ );
6954
+ error.statusCode = 404;
6955
+ return error;
6956
+ };
6936
6957
 
6937
6958
  // apps/cli/src/infra/http/PackmindHttpClient.ts
6938
6959
  var import_undici = require("undici");
@@ -7033,7 +7054,7 @@ var PackmindHttpClient = class {
7033
7054
  });
7034
7055
  if (!response.ok) {
7035
7056
  if (options.onError) {
7036
- options.onError(response);
7057
+ options.onError(response, await this.resolveEdition(response));
7037
7058
  }
7038
7059
  let errorMsg = `API request failed: ${response.status} ${response.statusText}`;
7039
7060
  try {
@@ -7065,6 +7086,43 @@ var PackmindHttpClient = class {
7065
7086
  );
7066
7087
  }
7067
7088
  }
7089
+ /**
7090
+ * The edition behind a failed response, for callers whose route means
7091
+ * different things per edition.
7092
+ *
7093
+ * Falls back to /auth/me, which has carried `edition` since well before the
7094
+ * header and answers it even unauthenticated, so a server too old to set the
7095
+ * header can still be identified rather than guessed at. Asked once per
7096
+ * client, and only for a 404 — the one status whose meaning depends on the
7097
+ * edition, and the only reason to spend a request here.
7098
+ */
7099
+ async resolveEdition(response) {
7100
+ const fromHeader = readPackmindEdition(response);
7101
+ if (fromHeader !== null || response.status !== 404) {
7102
+ return fromHeader;
7103
+ }
7104
+ if (this.editionFromAuthMe === void 0) {
7105
+ this.editionFromAuthMe = await this.fetchEditionFromAuthMe();
7106
+ }
7107
+ return this.editionFromAuthMe;
7108
+ }
7109
+ async fetchEditionFromAuthMe() {
7110
+ try {
7111
+ const { host } = this.getAuthContext();
7112
+ const response = await fetch(`${host}/api/v0/auth/me`, {
7113
+ headers: {
7114
+ Authorization: `Bearer ${this.apiKey}`,
7115
+ "User-Agent": `packmind-cli:${import_package.version}`
7116
+ },
7117
+ // @ts-expect-error — Node.js fetch (undici) accepts a dispatcher option not present in the DOM types
7118
+ dispatcher
7119
+ });
7120
+ const body = await response.json();
7121
+ return parsePackmindEdition(body?.edition);
7122
+ } catch {
7123
+ return null;
7124
+ }
7125
+ }
7068
7126
  };
7069
7127
 
7070
7128
  // apps/cli/src/infra/repositories/ChangeProposalGateway.ts
@@ -7078,10 +7136,8 @@ var ChangeProposalGateway = class {
7078
7136
  {
7079
7137
  method: "POST",
7080
7138
  body: { proposals: command35.proposals },
7081
- onError: (response) => {
7082
- if (response.status === 404) {
7083
- throw new CommunityEditionError("change proposals");
7084
- }
7139
+ onError: (response, edition) => {
7140
+ throwIfFeatureAbsent(response, edition, "change proposals");
7085
7141
  }
7086
7142
  }
7087
7143
  );
@@ -7109,10 +7165,8 @@ var ChangeProposalGateway = class {
7109
7165
  {
7110
7166
  method: "POST",
7111
7167
  body: { proposals: command35.proposals },
7112
- onError: (response) => {
7113
- if (response.status === 404) {
7114
- throw new CommunityEditionError("change proposals");
7115
- }
7168
+ onError: (response, edition) => {
7169
+ throwIfFeatureAbsent(response, edition, "change proposals");
7116
7170
  }
7117
7171
  }
7118
7172
  );
@@ -7135,10 +7189,12 @@ var LinterGateway = class {
7135
7189
  return this.httpClient.request("/api/v0/list-draft-detection-program", {
7136
7190
  method: "POST",
7137
7191
  body: payload,
7138
- onError: (response) => {
7139
- if (response.status === 404) {
7140
- throw new CommunityEditionError("local linting with packages");
7141
- }
7192
+ onError: (response, edition) => {
7193
+ throwIfFeatureAbsent(
7194
+ response,
7195
+ edition,
7196
+ "local linting with packages"
7197
+ );
7142
7198
  }
7143
7199
  });
7144
7200
  };
@@ -7153,10 +7209,12 @@ var LinterGateway = class {
7153
7209
  return this.httpClient.request("/api/v0/list-active-detection-program", {
7154
7210
  method: "POST",
7155
7211
  body: payload,
7156
- onError: (response) => {
7157
- if (response.status === 404) {
7158
- throw new CommunityEditionError("local linting with packages");
7159
- }
7212
+ onError: (response, edition) => {
7213
+ throwIfFeatureAbsent(
7214
+ response,
7215
+ edition,
7216
+ "local linting with packages"
7217
+ );
7160
7218
  }
7161
7219
  });
7162
7220
  };
@@ -7168,19 +7226,27 @@ var LinterGateway = class {
7168
7226
  body: {
7169
7227
  packagesSlugs: command35.packagesSlugs
7170
7228
  },
7171
- onError: (response2) => {
7172
- if (response2.status === 404) {
7173
- throw new CommunityEditionError("local linting with packages");
7174
- }
7229
+ onError: (response2, edition) => {
7230
+ throwIfFeatureAbsent(
7231
+ response2,
7232
+ edition,
7233
+ "local linting with packages"
7234
+ );
7175
7235
  }
7176
7236
  }
7177
7237
  );
7178
7238
  return handleScopeInTargetsResponse(response);
7179
7239
  };
7240
+ // The last route on the stubbed linter controller. Both callers discard
7241
+ // whatever this rejects with, so the error only ever has to be the honest
7242
+ // one rather than a 404 dressed up as something else.
7180
7243
  this.trackLinterExecution = async (command35) => {
7181
7244
  return this.httpClient.request(`/api/v0/track-execution`, {
7182
7245
  method: "POST",
7183
- body: command35
7246
+ body: command35,
7247
+ onError: (response, edition) => {
7248
+ throwIfFeatureAbsent(response, edition, "linter execution tracking");
7249
+ }
7184
7250
  });
7185
7251
  };
7186
7252
  }
@@ -7213,11 +7279,11 @@ var SpacesGateway = class {
7213
7279
  );
7214
7280
  };
7215
7281
  }
7216
- async getSpaceBySlug(slug6) {
7282
+ async getSpaceBySlug(slug5) {
7217
7283
  const { organizationId } = this.httpClient.getAuthContext();
7218
7284
  try {
7219
7285
  return await this.httpClient.request(
7220
- `/api/v0/organizations/${organizationId}/spaces/${slug6}`
7286
+ `/api/v0/organizations/${organizationId}/spaces/${slug5}`
7221
7287
  );
7222
7288
  } catch (error) {
7223
7289
  if (error.statusCode === 404) return null;
@@ -7350,12 +7416,12 @@ var PackagesGateway = class {
7350
7416
  );
7351
7417
  };
7352
7418
  this.getSummary = async ({
7353
- slug: slug6,
7419
+ slug: slug5,
7354
7420
  spaceId
7355
7421
  }) => {
7356
7422
  const { organizationId } = this.httpClient.getAuthContext();
7357
7423
  return this.httpClient.request(
7358
- `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug6)}`
7424
+ `/api/v0/organizations/${organizationId}/spaces/${spaceId}/packages/summary/${encodeURIComponent(slug5)}`
7359
7425
  );
7360
7426
  };
7361
7427
  this.create = async (command35) => {
@@ -7391,13 +7457,13 @@ var DeploymentGateway = class {
7391
7457
  const { organizationId } = this.httpClient.getAuthContext();
7392
7458
  const queryParams = new URLSearchParams();
7393
7459
  if (command35.packagesSlugs && command35.packagesSlugs.length > 0) {
7394
- command35.packagesSlugs.forEach((slug6) => {
7395
- queryParams.append("packageSlug", slug6);
7460
+ command35.packagesSlugs.forEach((slug5) => {
7461
+ queryParams.append("packageSlug", slug5);
7396
7462
  });
7397
7463
  }
7398
7464
  if (command35.previousPackagesSlugs && command35.previousPackagesSlugs.length > 0) {
7399
- command35.previousPackagesSlugs.forEach((slug6) => {
7400
- queryParams.append("previousPackageSlug", slug6);
7465
+ command35.previousPackagesSlugs.forEach((slug5) => {
7466
+ queryParams.append("previousPackageSlug", slug5);
7401
7467
  });
7402
7468
  }
7403
7469
  if (command35.gitRemoteUrl) {
@@ -9219,12 +9285,6 @@ var ParserRegistry = class {
9219
9285
  this.parsers.set(language, parser);
9220
9286
  return parser;
9221
9287
  }
9222
- getAvailableParsers() {
9223
- return Object.keys(this.parserClasses);
9224
- }
9225
- clearCache() {
9226
- this.parsers.clear();
9227
- }
9228
9288
  };
9229
9289
 
9230
9290
  // packages/linter-ast/src/application/ConsoleLogRemovalService.ts
@@ -9242,7 +9302,7 @@ var ConsoleLogRemovalService = class {
9242
9302
  async removeConsoleLogStatements(sourceCode, language) {
9243
9303
  if (language !== "JAVASCRIPT" /* JAVASCRIPT */) {
9244
9304
  throw new Error(
9245
- `ConsoleRemovalService only supports JAVASCRIPT, received: ${language}`
9305
+ `ConsoleLogRemovalService only supports JAVASCRIPT, received: ${language}`
9246
9306
  );
9247
9307
  }
9248
9308
  try {
@@ -9362,9 +9422,6 @@ var LinterAstAdapter = class {
9362
9422
  }
9363
9423
  };
9364
9424
 
9365
- // packages/linter-ast/src/parsers/TypeScriptTSXParser.ts
9366
- var TreeSitter17 = __toESM(require("web-tree-sitter"));
9367
-
9368
9425
  // packages/linter-execution/src/application/useCases/ExecuteLinterProgramsUseCase.ts
9369
9426
  var origin4 = "ExecuteLinterProgramsUseCase";
9370
9427
  var ExecuteLinterProgramsUseCase = class {
@@ -9747,10 +9804,6 @@ var Configuration = class _Configuration {
9747
9804
  this.initialized = true;
9748
9805
  this.logger.info("Configuration initialization completed");
9749
9806
  }
9750
- static async getConfigWithDefault(key, defaultValue) {
9751
- const value = await _Configuration.getConfig(key);
9752
- return value ?? defaultValue;
9753
- }
9754
9807
  static async getConfig(key, env2 = process.env, logger2) {
9755
9808
  const instance = _Configuration.getInstance(logger2);
9756
9809
  instance.logger.info("Getting configuration value", { key });
@@ -9807,11 +9860,6 @@ var Cache = class _Cache {
9807
9860
  )) {
9808
9861
  this.logger = logger2;
9809
9862
  this.initialized = false;
9810
- this.connectionConfig = {
9811
- host: "redis",
9812
- port: 6379,
9813
- maxRetriesPerRequest: 3
9814
- };
9815
9863
  }
9816
9864
  static {
9817
9865
  // Default cache expiration time in seconds (5 minutes)
@@ -9958,30 +10006,19 @@ var Cache = class _Cache {
9958
10006
  }
9959
10007
  this.initialized = false;
9960
10008
  }
9961
- /**
9962
- * Get cache statistics (for monitoring/debugging)
9963
- */
9964
- async getStats() {
9965
- return {
9966
- connected: this.client?.status === "ready",
9967
- initialized: this.initialized
9968
- };
9969
- }
9970
10009
  };
9971
10010
 
9972
10011
  // packages/feature-flags/src/registry.ts
9973
10012
  var ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY = "change-proposals-in-webapp";
9974
10013
  var ORGA_SPACE_MANAGEMENT_FEATURE_KEY = "orga-space-management";
9975
10014
  var SPACE_NAV_PLUGIN_FIRST_FEATURE_KEY = "space-nav-plugin-first";
9976
- var COPILOT_MARKETPLACE_FEATURE_KEY = "copilot-marketplace";
9977
10015
  var DEFAULT_FEATURE_DOMAIN_MAP = {
9978
10016
  [ADD_CHANGE_PROPOSALS_IN_WEBAPP_FEATURE_KEY]: [
9979
10017
  "@packmind.com",
9980
10018
  "@promyze.com"
9981
10019
  ],
9982
10020
  [ORGA_SPACE_MANAGEMENT_FEATURE_KEY]: ["@packmind.com", "@promyze.com"],
9983
- [SPACE_NAV_PLUGIN_FIRST_FEATURE_KEY]: ["@packmind.com", "@promyze.com"],
9984
- [COPILOT_MARKETPLACE_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
10021
+ [SPACE_NAV_PLUGIN_FIRST_FEATURE_KEY]: ["@packmind.com", "@promyze.com"]
9985
10022
  };
9986
10023
 
9987
10024
  // packages/node-utils/src/database/schemas.ts
@@ -10042,6 +10079,7 @@ var import_nodemailer = __toESM(require("nodemailer"));
10042
10079
  var import_common = require("@nestjs/common");
10043
10080
 
10044
10081
  // packages/node-utils/src/repositories/AbstractRepository.ts
10082
+ var import_typeorm2 = require("typeorm");
10045
10083
  var import_common2 = require("@nestjs/common");
10046
10084
 
10047
10085
  // packages/node-utils/src/sse/RedisSSEClient.ts
@@ -10534,7 +10572,7 @@ async function normalizePackageSlugs(slugs, spaceService) {
10534
10572
  }
10535
10573
  const defaultSpace = await spaceService.getDefaultSpace();
10536
10574
  return slugs.map(
10537
- (slug6) => slug6.startsWith("@") ? slug6 : `@${defaultSpace.slug}/${slug6}`
10575
+ (slug5) => slug5.startsWith("@") ? slug5 : `@${defaultSpace.slug}/${slug5}`
10538
10576
  );
10539
10577
  }
10540
10578
 
@@ -10585,8 +10623,8 @@ function isFullParsedPackageSlug(tbd) {
10585
10623
  const asFullParsedPackageSlug = tbd;
10586
10624
  return asFullParsedPackageSlug.spaceSlug !== void 0 && asFullParsedPackageSlug.packageSlug !== void 0;
10587
10625
  }
10588
- function parsePackageSlug(slug6) {
10589
- const slugs = slug6.split("/");
10626
+ function parsePackageSlug(slug5) {
10627
+ const slugs = slug5.split("/");
10590
10628
  if (slugs.length === 1) {
10591
10629
  return { packageSlug: slugs[0] };
10592
10630
  }
@@ -10862,7 +10900,7 @@ var InstallUseCase = class {
10862
10900
  const configAfter = await this.configFileRepository.readConfig(baseDirectory);
10863
10901
  const slugsAfter = new Set(Object.keys(configAfter?.packages ?? {}));
10864
10902
  result.packagesAdded = [...slugsAfter].filter(
10865
- (slug6) => !slugsBefore.has(slug6)
10903
+ (slug5) => !slugsBefore.has(slug5)
10866
10904
  );
10867
10905
  result.configCreated = !configExistedBefore && slugsAfter.size > 0;
10868
10906
  }
@@ -10902,7 +10940,7 @@ var InstallUseCase = class {
10902
10940
  if (originalSlugs.length === 0) return [];
10903
10941
  const normalizedSlugs = await this.normalizePackageSlugs(originalSlugs);
10904
10942
  const hasChanges = normalizedSlugs.some(
10905
- (slug6, i) => slug6 !== originalSlugs[i]
10943
+ (slug5, i) => slug5 !== originalSlugs[i]
10906
10944
  );
10907
10945
  if (hasChanges) {
10908
10946
  const normalizedPackagesMap = {};
@@ -10942,9 +10980,9 @@ var InstallUseCase = class {
10942
10980
  }
10943
10981
  async computeJoinSpaceUrl(missingAccessSlugs) {
10944
10982
  const spaceSlugs = /* @__PURE__ */ new Set();
10945
- for (const slug6 of missingAccessSlugs) {
10946
- if (slug6.startsWith("@")) {
10947
- const spaceSlug2 = slug6.slice(1).split("/")[0];
10983
+ for (const slug5 of missingAccessSlugs) {
10984
+ if (slug5.startsWith("@")) {
10985
+ const spaceSlug2 = slug5.slice(1).split("/")[0];
10948
10986
  spaceSlugs.add(spaceSlug2);
10949
10987
  }
10950
10988
  }
@@ -11739,12 +11777,6 @@ var CredentialsService = class {
11739
11777
  const credentials = this.loadCredentials();
11740
11778
  return credentials?.apiKey ?? "";
11741
11779
  }
11742
- /**
11743
- * Checks if any provider has credentials available
11744
- */
11745
- hasCredentials() {
11746
- return this.providers.some((provider) => provider.hasCredentials());
11747
- }
11748
11780
  };
11749
11781
  var defaultCredentialsService = new CredentialsService();
11750
11782
  function loadApiKey() {
@@ -12525,9 +12557,9 @@ var ConfigFileRepository = class {
12525
12557
  }
12526
12558
  const mergedPackages = {};
12527
12559
  for (const config of configs) {
12528
- for (const [slug6, version2] of Object.entries(config.packages)) {
12529
- if (!(slug6 in mergedPackages)) {
12530
- mergedPackages[slug6] = version2;
12560
+ for (const [slug5, version2] of Object.entries(config.packages)) {
12561
+ if (!(slug5 in mergedPackages)) {
12562
+ mergedPackages[slug5] = version2;
12531
12563
  }
12532
12564
  }
12533
12565
  }
@@ -12641,9 +12673,9 @@ var ConfigFileRepository = class {
12641
12673
  parsed.packages = {};
12642
12674
  }
12643
12675
  const packages = parsed.packages;
12644
- for (const slug6 of newPackageSlugs) {
12645
- if (!(slug6 in packages)) {
12646
- packages[slug6] = "*";
12676
+ for (const slug5 of newPackageSlugs) {
12677
+ if (!(slug5 in packages)) {
12678
+ packages[slug5] = "*";
12647
12679
  }
12648
12680
  }
12649
12681
  await this.writeConfigToPath(configPath, parsed);
@@ -12710,8 +12742,8 @@ var ConfigFileRepository = class {
12710
12742
  }
12711
12743
  createConfigWithPackages(slugs) {
12712
12744
  const packages = {};
12713
- for (const slug6 of slugs) {
12714
- packages[slug6] = "*";
12745
+ for (const slug5 of slugs) {
12746
+ packages[slug5] = "*";
12715
12747
  }
12716
12748
  return { packages };
12717
12749
  }
@@ -14342,8 +14374,8 @@ var SpaceService = class {
14342
14374
  }
14343
14375
  return defaultSpace;
14344
14376
  }
14345
- async getSpaceBySlug(slug6) {
14346
- return this.spaceGateway.getSpaceBySlug(slug6);
14377
+ async getSpaceBySlug(slug5) {
14378
+ return this.spaceGateway.getSpaceBySlug(slug5);
14347
14379
  }
14348
14380
  getApiContext() {
14349
14381
  return this.spaceGateway.getApiContext();
@@ -14379,9 +14411,6 @@ var CliFormatter = class {
14379
14411
  static subHeader(title) {
14380
14412
  return source_default.bold(title);
14381
14413
  }
14382
- static slug(slug6) {
14383
- return source_default.blue.bold(slug6);
14384
- }
14385
14414
  static label(label) {
14386
14415
  return source_default.dim(label);
14387
14416
  }
@@ -14803,31 +14832,15 @@ var PackmindCliHexa = class {
14803
14832
  throw error;
14804
14833
  }
14805
14834
  }
14806
- /**
14807
- * Destroys the DeploymentsHexa and cleans up resources
14808
- */
14809
- destroy() {
14810
- this.logger.info("Destroying PackmindCliHexa");
14811
- this.logger.info("PackmindCliHexa destroyed");
14812
- }
14813
14835
  get output() {
14814
14836
  return this.hexa.repositories.output;
14815
14837
  }
14816
- async getGitRemoteUrl(command35) {
14817
- return this.hexa.useCases.getGitRemoteUrl.execute(command35);
14818
- }
14819
- async listFilesInDirectory(command35) {
14820
- return this.hexa.useCases.listFilesInDirectoryUseCase.execute(command35);
14821
- }
14822
14838
  async lintFilesAgainstRule(command35) {
14823
14839
  return this.hexa.useCases.lintFilesAgainstRule.execute(command35);
14824
14840
  }
14825
14841
  async lintFilesFromConfig(command35) {
14826
14842
  return this.hexa.useCases.lintFilesFromConfig.execute(command35);
14827
14843
  }
14828
- async installPackages(command35) {
14829
- return this.hexa.useCases.installPackages.execute(command35);
14830
- }
14831
14844
  async install(command35) {
14832
14845
  return this.hexa.useCases.install.execute(command35);
14833
14846
  }
@@ -14837,9 +14850,6 @@ var PackmindCliHexa = class {
14837
14850
  async diffArtefacts(command35) {
14838
14851
  return this.hexa.useCases.diffArtefacts.execute(command35);
14839
14852
  }
14840
- async submitDiffs(groupedDiffs, message) {
14841
- return this.hexa.useCases.submitDiffs.execute({ groupedDiffs, message });
14842
- }
14843
14853
  async checkDiffs(groupedDiffs) {
14844
14854
  return this.hexa.useCases.checkDiffs.execute({ groupedDiffs });
14845
14855
  }
@@ -14863,21 +14873,6 @@ var PackmindCliHexa = class {
14863
14873
  baseDirectory
14864
14874
  );
14865
14875
  }
14866
- async readConfig(baseDirectory) {
14867
- const config = await this.hexa.repositories.configFileRepository.readConfig(
14868
- baseDirectory
14869
- );
14870
- if (!config) return { packages: {} };
14871
- const hasNonWildcardVersions = Object.values(config.packages).some(
14872
- (version2) => version2 !== "*"
14873
- );
14874
- if (hasNonWildcardVersions) {
14875
- logWarningConsole(
14876
- "Package versions are not supported yet, getting the latest version"
14877
- );
14878
- }
14879
- return config;
14880
- }
14881
14876
  /**
14882
14877
  * Reads the full packmind.json configuration including agents.
14883
14878
  * Returns null if no config file exists.
@@ -14887,35 +14882,6 @@ var PackmindCliHexa = class {
14887
14882
  baseDirectory
14888
14883
  );
14889
14884
  }
14890
- async writeConfig(baseDirectory, packagesSlugs) {
14891
- const packages = {};
14892
- packagesSlugs.forEach((slug6) => {
14893
- packages[slug6] = "*";
14894
- });
14895
- const existingConfig = await this.hexa.repositories.configFileRepository.readConfig(
14896
- baseDirectory
14897
- );
14898
- await this.hexa.repositories.configFileRepository.writeConfig(
14899
- baseDirectory,
14900
- {
14901
- ...existingConfig,
14902
- packages
14903
- }
14904
- );
14905
- }
14906
- /**
14907
- * Adds new packages to an existing packmind.json while preserving property order.
14908
- * If the file doesn't exist, creates a new one with default order (packages first).
14909
- *
14910
- * @param baseDirectory - The directory containing packmind.json
14911
- * @param newPackageSlugs - Array of package slugs to add
14912
- */
14913
- async addPackagesToConfig(baseDirectory, newPackageSlugs) {
14914
- return this.hexa.repositories.configFileRepository.addPackagesToConfig(
14915
- baseDirectory,
14916
- newPackageSlugs
14917
- );
14918
- }
14919
14885
  async readHierarchicalConfig(startDirectory, stopDirectory) {
14920
14886
  return this.hexa.repositories.configFileRepository.readHierarchicalConfig(
14921
14887
  startDirectory,
@@ -14933,11 +14899,6 @@ var PackmindCliHexa = class {
14933
14899
  stopDirectory
14934
14900
  );
14935
14901
  }
14936
- async getGitRepositoryRoot(directory) {
14937
- return this.hexa.services.gitRemoteUrlService.getGitRepositoryRoot(
14938
- directory
14939
- );
14940
- }
14941
14902
  async tryGetGitRepositoryRoot(directory) {
14942
14903
  return this.hexa.services.gitRemoteUrlService.tryGetGitRepositoryRoot(
14943
14904
  directory
@@ -14970,9 +14931,6 @@ var PackmindCliHexa = class {
14970
14931
  getGitRemoteUrlFromPath(repoPath) {
14971
14932
  return this.hexa.services.gitRemoteUrlService.getGitRemoteUrl(repoPath).gitRemoteUrl;
14972
14933
  }
14973
- async uploadSkill(command35) {
14974
- return this.hexa.useCases.uploadSkill.execute(command35);
14975
- }
14976
14934
  async installDefaultSkills(command35) {
14977
14935
  return this.hexa.useCases.installDefaultSkills.execute(command35);
14978
14936
  }
@@ -14999,35 +14957,6 @@ var PackmindCliHexa = class {
14999
14957
  async getSpaces() {
15000
14958
  return this.hexa.services.spaceService.getSpaces();
15001
14959
  }
15002
- /**
15003
- * Normalizes package slugs to the `@space-slug/package-slug` format.
15004
- * Unprefixed slugs are resolved against the organization's default space.
15005
- * Already-prefixed slugs (`@space/pkg`) are returned as-is.
15006
- * Throws if there are multiple spaces and any slug is unprefixed.
15007
- */
15008
- async normalizePackageSlugs(slugs) {
15009
- if (slugs.length === 0) return [];
15010
- const hasUnprefixed = slugs.some((s) => !s.startsWith("@"));
15011
- if (!hasUnprefixed) return slugs;
15012
- let spaces;
15013
- try {
15014
- spaces = await this.getSpaces();
15015
- } catch {
15016
- logWarningConsole(
15017
- "Your Packmind instance is outdated and needs to be updated. It will not be supported in the v1 release of the Packmind CLI."
15018
- );
15019
- return slugs;
15020
- }
15021
- if (spaces.length > 1) {
15022
- throw new Error(
15023
- `Your organization has multiple spaces. Please specify the space for each package using the @space/package format (e.g. @${spaces[0].slug}/my-package).`
15024
- );
15025
- }
15026
- const defaultSpace = await this.getDefaultSpace();
15027
- return slugs.map(
15028
- (slug6) => slug6.startsWith("@") ? slug6 : `@${defaultSpace.slug}/${slug6}`
15029
- );
15030
- }
15031
14960
  getSpaceService() {
15032
14961
  return this.hexa.services.spaceService;
15033
14962
  }
@@ -16477,7 +16406,7 @@ function mergeInstallResults(results) {
16477
16406
  function decideDistributionTracking(params) {
16478
16407
  const { lookup, currentBranch, branchExists, detached } = params;
16479
16408
  switch (lookup.status) {
16480
- case "flag-off":
16409
+ case "tracking-unsupported":
16481
16410
  return { action: "record-legacy" };
16482
16411
  case "unavailable":
16483
16412
  return { action: "inform" };
@@ -16557,7 +16486,7 @@ async function resolveTrackingLookup(packmindCliHexa, owner, repo) {
16557
16486
  } catch (error) {
16558
16487
  const statusCode = error?.statusCode;
16559
16488
  if (statusCode === 404) {
16560
- return { status: "flag-off" };
16489
+ return { status: "tracking-unsupported" };
16561
16490
  }
16562
16491
  return { status: "unavailable" };
16563
16492
  }
@@ -17199,8 +17128,8 @@ var import_cmd_ts8 = __toESM(require_cjs());
17199
17128
  // apps/cli/src/infra/utils/spaceFilterUtils.ts
17200
17129
  function resolveSpaceFromArgs(spaceArg, spaces) {
17201
17130
  if (!spaceArg) return null;
17202
- const slug6 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
17203
- return spaces.find((s) => s.slug === slug6) ?? null;
17131
+ const slug5 = spaceArg.startsWith("@") ? spaceArg.slice(1) : spaceArg;
17132
+ return spaces.find((s) => s.slug === slug5) ?? null;
17204
17133
  }
17205
17134
 
17206
17135
  // apps/cli/src/infra/utils/urlBuilderUtils.ts
@@ -17266,7 +17195,7 @@ ${availableSpaces}`
17266
17195
  exit(0);
17267
17196
  return;
17268
17197
  }
17269
- const buildUrl = resolveUrlBuilder((slug6) => `skills/${slug6}/files`);
17198
+ const buildUrl = resolveUrlBuilder((slug5) => `skills/${slug5}/files`);
17270
17199
  const groups = groupArtefactBySpaces(skills, spaces);
17271
17200
  packmindCliHexa.output.listScopedArtefacts(
17272
17201
  `\u{1F4CB} Skills (${skills.length})`,
@@ -17698,11 +17627,11 @@ var import_cmd_ts16 = __toESM(require_cjs());
17698
17627
 
17699
17628
  // apps/cli/src/domain/errors/ItemNotFoundError.ts
17700
17629
  var ItemNotFoundError = class extends Error {
17701
- constructor(itemType, slug6, spaceSlug) {
17702
- const message = spaceSlug ? `${itemType} '${slug6}' not found in space '@${spaceSlug}'` : `${itemType} '${slug6}' not found`;
17630
+ constructor(itemType, slug5, spaceSlug) {
17631
+ const message = spaceSlug ? `${itemType} '${slug5}' not found in space '@${spaceSlug}'` : `${itemType} '${slug5}' not found`;
17703
17632
  super(message);
17704
17633
  this.itemType = itemType;
17705
- this.slug = slug6;
17634
+ this.slug = slug5;
17706
17635
  this.spaceSlug = spaceSlug;
17707
17636
  this.name = "ItemNotFoundError";
17708
17637
  }
@@ -17765,34 +17694,34 @@ var AddToPackageUseCase = class {
17765
17694
  async resolveSlugsToIds(itemType, slugs, spaceId, spaceSlug) {
17766
17695
  const ids = [];
17767
17696
  const idToSlugMap = /* @__PURE__ */ new Map();
17768
- for (const slug6 of slugs) {
17697
+ for (const slug5 of slugs) {
17769
17698
  let item = null;
17770
17699
  if (itemType === "standard") {
17771
- item = await this.findStandardBySlug(slug6, spaceId);
17700
+ item = await this.findStandardBySlug(slug5, spaceId);
17772
17701
  } else if (itemType === "command") {
17773
- item = await this.findCommandBySlug(slug6, spaceId);
17702
+ item = await this.findCommandBySlug(slug5, spaceId);
17774
17703
  } else if (itemType === "skill") {
17775
- item = await this.findSkillBySlug(slug6, spaceId);
17704
+ item = await this.findSkillBySlug(slug5, spaceId);
17776
17705
  }
17777
17706
  if (!item) {
17778
- throw new ItemNotFoundError(itemType, slug6, spaceSlug);
17707
+ throw new ItemNotFoundError(itemType, slug5, spaceSlug);
17779
17708
  }
17780
17709
  ids.push(item.id);
17781
- idToSlugMap.set(item.id, slug6);
17710
+ idToSlugMap.set(item.id, slug5);
17782
17711
  }
17783
17712
  return { ids, idToSlugMap };
17784
17713
  }
17785
- async findStandardBySlug(slug6, spaceId) {
17714
+ async findStandardBySlug(slug5, spaceId) {
17786
17715
  const standards = await this.gateway.standards.list({ spaceId });
17787
- return standards.standards.find((standard) => standard.slug === slug6) ?? null;
17716
+ return standards.standards.find((standard) => standard.slug === slug5) ?? null;
17788
17717
  }
17789
- async findCommandBySlug(slug6, spaceId) {
17718
+ async findCommandBySlug(slug5, spaceId) {
17790
17719
  const commands = await this.gateway.commands.list({ spaceId });
17791
- return commands.recipes.find((command35) => command35.slug === slug6) ?? null;
17720
+ return commands.recipes.find((command35) => command35.slug === slug5) ?? null;
17792
17721
  }
17793
- async findSkillBySlug(slug6, spaceId) {
17722
+ async findSkillBySlug(slug5, spaceId) {
17794
17723
  const skills = await this.gateway.skills.list({ spaceId });
17795
- return skills.find((skill) => skill.slug === slug6) ?? null;
17724
+ return skills.find((skill) => skill.slug === slug5) ?? null;
17796
17725
  }
17797
17726
  };
17798
17727
 
@@ -18051,10 +17980,10 @@ var import_cmd_ts18 = __toESM(require_cjs());
18051
17980
  function isNotFoundError(err) {
18052
17981
  return err instanceof Error && err.message.includes("does not exist");
18053
17982
  }
18054
- async function resolvePackage(slug6, packmindCliHexa) {
17983
+ async function resolvePackage(slug5, packmindCliHexa) {
18055
17984
  const allSpaces = await packmindCliHexa.getSpaces();
18056
- if (isFullParsedPackageSlug(slug6)) {
18057
- const { spaceSlug, packageSlug } = slug6;
17985
+ if (isFullParsedPackageSlug(slug5)) {
17986
+ const { spaceSlug, packageSlug } = slug5;
18058
17987
  const matchedSpace = allSpaces.find((s) => s.slug === spaceSlug);
18059
17988
  if (!matchedSpace) {
18060
17989
  throw new Error(`Space '@${spaceSlug}' not found.`);
@@ -18078,7 +18007,7 @@ async function resolvePackage(slug6, packmindCliHexa) {
18078
18007
  const results = await Promise.allSettled(
18079
18008
  allSpaces.map(async (space) => ({
18080
18009
  pkg: await packmindCliHexa.getPackageBySlug({
18081
- slug: slug6.packageSlug,
18010
+ slug: slug5.packageSlug,
18082
18011
  spaceId: space.id
18083
18012
  }),
18084
18013
  spaceSlug: space.slug
@@ -18092,17 +18021,17 @@ async function resolvePackage(slug6, packmindCliHexa) {
18092
18021
  if (realError) {
18093
18022
  throw realError.reason;
18094
18023
  }
18095
- throw new Error(`Package '${slug6.packageSlug}' not found in any space.`);
18024
+ throw new Error(`Package '${slug5.packageSlug}' not found in any space.`);
18096
18025
  }
18097
18026
  if (matches.length > 1) {
18098
- const example = `@${matches[0].spaceSlug}/${slug6.packageSlug}`;
18027
+ const example = `@${matches[0].spaceSlug}/${slug5.packageSlug}`;
18099
18028
  throw new Error(
18100
- `Package '${slug6.packageSlug}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
18029
+ `Package '${slug5.packageSlug}' exists in multiple spaces (${matches.map((m) => `@${m.spaceSlug}`).join(", ")}). Please specify the space using the @space/package format (e.g. ${example}).`
18101
18030
  );
18102
18031
  }
18103
18032
  return {
18104
18033
  pkg: matches[0].pkg,
18105
- fullSlug: `@${matches[0].spaceSlug}/${slug6.packageSlug}`
18034
+ fullSlug: `@${matches[0].spaceSlug}/${slug5.packageSlug}`
18106
18035
  };
18107
18036
  }
18108
18037
  async function showPackageHandler(args2, deps) {
@@ -18167,10 +18096,10 @@ var showPackageCommand = (0, import_cmd_ts18.command)({
18167
18096
  description: "Package slug (e.g. backend or @my-space/backend)"
18168
18097
  })
18169
18098
  },
18170
- handler: async ({ slug: slug6 }) => {
18099
+ handler: async ({ slug: slug5 }) => {
18171
18100
  const packmindLogger = new PackmindLogger("PackmindCLI", "info" /* INFO */);
18172
18101
  const packmindCliHexa = new PackmindCliHexa(packmindLogger);
18173
- await showPackageHandler({ slug: slug6 }, { packmindCliHexa, exit: process.exit });
18102
+ await showPackageHandler({ slug: slug5 }, { packmindCliHexa, exit: process.exit });
18174
18103
  }
18175
18104
  });
18176
18105
 
@@ -18750,8 +18679,8 @@ function extractFilenameSlug(filePath) {
18750
18679
  }
18751
18680
  return basename4;
18752
18681
  }
18753
- function humanizeSlug(slug6) {
18754
- const words = slug6.replace(/[-_]/g, " ");
18682
+ function humanizeSlug(slug5) {
18683
+ const words = slug5.replace(/[-_]/g, " ");
18755
18684
  return words.charAt(0).toUpperCase() + words.slice(1);
18756
18685
  }
18757
18686
 
@@ -18861,8 +18790,8 @@ function validateSkillFileContent(content) {
18861
18790
  }
18862
18791
 
18863
18792
  // packages/skills/src/infra/schemas/SkillSchema.ts
18864
- var import_typeorm2 = require("typeorm");
18865
- var SkillSchema = new import_typeorm2.EntitySchema({
18793
+ var import_typeorm3 = require("typeorm");
18794
+ var SkillSchema = new import_typeorm3.EntitySchema({
18866
18795
  name: "Skill",
18867
18796
  tableName: "skills",
18868
18797
  columns: {
@@ -18950,8 +18879,8 @@ var SkillSchema = new import_typeorm2.EntitySchema({
18950
18879
  });
18951
18880
 
18952
18881
  // packages/skills/src/infra/schemas/SkillVersionSchema.ts
18953
- var import_typeorm3 = require("typeorm");
18954
- var SkillVersionSchema = new import_typeorm3.EntitySchema({
18882
+ var import_typeorm4 = require("typeorm");
18883
+ var SkillVersionSchema = new import_typeorm4.EntitySchema({
18955
18884
  name: "SkillVersion",
18956
18885
  tableName: "skill_versions",
18957
18886
  columns: {
@@ -19032,8 +18961,8 @@ var SkillVersionSchema = new import_typeorm3.EntitySchema({
19032
18961
  });
19033
18962
 
19034
18963
  // packages/skills/src/infra/schemas/SkillFileSchema.ts
19035
- var import_typeorm4 = require("typeorm");
19036
- var SkillFileSchema = new import_typeorm4.EntitySchema({
18964
+ var import_typeorm5 = require("typeorm");
18965
+ var SkillFileSchema = new import_typeorm5.EntitySchema({
19037
18966
  name: "SkillFile",
19038
18967
  tableName: "skill_files",
19039
18968
  columns: {
@@ -19084,14 +19013,11 @@ var import_slug = __toESM(require("slug"));
19084
19013
  // packages/skills/src/application/useCases/saveSkillVersion/SaveSkillVersionUseCase.ts
19085
19014
  var import_uuid = require("uuid");
19086
19015
 
19087
- // packages/skills/src/application/useCases/updateSkill/UpdateSkillUseCase.ts
19088
- var import_slug2 = __toESM(require("slug"));
19089
-
19090
19016
  // packages/skills/src/application/useCases/updateSkillFileFromUI/UpdateSkillFileFromUIUseCase.ts
19091
19017
  var import_uuid2 = require("uuid");
19092
19018
 
19093
19019
  // packages/skills/src/application/useCases/uploadSkill/UploadSkillUseCase.ts
19094
- var import_slug3 = __toESM(require("slug"));
19020
+ var import_slug2 = __toESM(require("slug"));
19095
19021
  var import_uuid3 = require("uuid");
19096
19022
 
19097
19023
  // packages/skills/src/application/services/SkillService.ts
@@ -19277,14 +19203,14 @@ function findLockFileEntryAndFileForPath(normalizedFilePath, artifacts) {
19277
19203
  }
19278
19204
 
19279
19205
  // apps/cli/src/infra/commands/playbook/add/linkExistingArtifact.ts
19280
- var import_slug4 = __toESM(require("slug"));
19206
+ var import_slug3 = __toESM(require("slug"));
19281
19207
  async function resolveExistingArtifact(packmindCliHexa, artifactType, spaceId, artifactName) {
19282
19208
  const artifacts = await listArtifactsForSpace(
19283
19209
  packmindCliHexa,
19284
19210
  artifactType,
19285
19211
  spaceId
19286
19212
  );
19287
- const match = artifacts.find((a) => (0, import_slug4.default)(a.name) === (0, import_slug4.default)(artifactName));
19213
+ const match = artifacts.find((a) => (0, import_slug3.default)(a.name) === (0, import_slug3.default)(artifactName));
19288
19214
  return match ? { id: match.id, name: match.name } : null;
19289
19215
  }
19290
19216
  async function listArtifactsForSpace(packmindCliHexa, artifactType, spaceId) {
@@ -19321,7 +19247,7 @@ function adoptArtifactIntoLockFile({
19321
19247
  agents: [],
19322
19248
  artifacts: {}
19323
19249
  };
19324
- const key = `user:${artifact.type}:${(0, import_slug4.default)(artifact.name)}`;
19250
+ const key = `user:${artifact.type}:${(0, import_slug3.default)(artifact.name)}`;
19325
19251
  const existing = base.artifacts[key];
19326
19252
  const normalized = normalizePath2(relativeFilePath);
19327
19253
  const files = existing ? [...existing.files] : [];
@@ -20444,9 +20370,9 @@ var import_cmd_ts27 = __toESM(require_cjs());
20444
20370
  var path35 = __toESM(require("path"));
20445
20371
 
20446
20372
  // apps/cli/src/infra/commands/playbook/submit/duplicateNameChecker.ts
20447
- var import_slug5 = __toESM(require("slug"));
20373
+ var import_slug4 = __toESM(require("slug"));
20448
20374
  function duplicateNameKey(entry) {
20449
- return `${entry.spaceId}:${entry.artifactType}:${(0, import_slug5.default)(entry.artifactName)}`;
20375
+ return `${entry.spaceId}:${entry.artifactType}:${(0, import_slug4.default)(entry.artifactName)}`;
20450
20376
  }
20451
20377
  async function checkForDuplicateNames(createdEntries, packmindGateway) {
20452
20378
  const errors = [];
@@ -20460,7 +20386,7 @@ async function checkForDuplicateNames(createdEntries, packmindGateway) {
20460
20386
  for (const [, entries] of groups) {
20461
20387
  const seen = /* @__PURE__ */ new Map();
20462
20388
  for (const entry of entries) {
20463
- const sluggedName = (0, import_slug5.default)(entry.artifactName);
20389
+ const sluggedName = (0, import_slug4.default)(entry.artifactName);
20464
20390
  if (seen.has(sluggedName)) {
20465
20391
  errors.push({
20466
20392
  spaceId: entry.spaceId,
@@ -20494,9 +20420,9 @@ async function checkForDuplicateNames(createdEntries, packmindGateway) {
20494
20420
  });
20495
20421
  existingNames = response.map((s) => s.name);
20496
20422
  }
20497
- const existingNamesSlugged = new Set(existingNames.map((n) => (0, import_slug5.default)(n)));
20423
+ const existingNamesSlugged = new Set(existingNames.map((n) => (0, import_slug4.default)(n)));
20498
20424
  for (const entry of entries) {
20499
- if (existingNamesSlugged.has((0, import_slug5.default)(entry.artifactName))) {
20425
+ if (existingNamesSlugged.has((0, import_slug4.default)(entry.artifactName))) {
20500
20426
  errors.push({
20501
20427
  spaceId: entry.spaceId,
20502
20428
  artifactType: entry.artifactType,
@@ -22917,7 +22843,9 @@ function handleTrackingError(error) {
22917
22843
  }
22918
22844
  const statusCode = error?.statusCode;
22919
22845
  if (statusCode === 404) {
22920
- logErrorConsole("Repository tracking is not available for your account.");
22846
+ logErrorConsole(
22847
+ "Repository tracking is not available on this Packmind server. Ask your administrator to update it."
22848
+ );
22921
22849
  process.exit(1);
22922
22850
  return;
22923
22851
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@packmind/cli",
3
- "version": "0.35.0",
3
+ "version": "0.35.1",
4
4
  "description": "A command-line interface for Packmind linting and code quality checks",
5
5
  "private": false,
6
6
  "bin": {