@maximoai/maximo-syntax-cli 0.1.39 → 0.1.40

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/dist/cli.mjs +143 -31
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -108074,6 +108074,8 @@ async function populateOAuthAccountInfoIfNeeded() {
108074
108074
  emailAddress: profile.account.email,
108075
108075
  organizationUuid: profile.organization.uuid,
108076
108076
  displayName: profile.account.display_name || undefined,
108077
+ username: profile.account.username || undefined,
108078
+ profilePhotoUrl: profile.account.profile_photo_url || undefined,
108077
108079
  hasExtraUsageEnabled: profile.organization.has_extra_usage_enabled ?? false,
108078
108080
  billingType: profile.organization.billing_type ?? undefined,
108079
108081
  accountCreatedAt: profile.account.created_at,
@@ -108089,6 +108091,8 @@ function storeOAuthAccountInfo({
108089
108091
  emailAddress,
108090
108092
  organizationUuid,
108091
108093
  displayName,
108094
+ username,
108095
+ profilePhotoUrl,
108092
108096
  hasExtraUsageEnabled,
108093
108097
  billingType,
108094
108098
  accountCreatedAt,
@@ -108106,8 +108110,14 @@ function storeOAuthAccountInfo({
108106
108110
  if (displayName) {
108107
108111
  accountInfo.displayName = displayName;
108108
108112
  }
108113
+ if (username) {
108114
+ accountInfo.username = username;
108115
+ }
108116
+ if (profilePhotoUrl) {
108117
+ accountInfo.profilePhotoUrl = profilePhotoUrl;
108118
+ }
108109
108119
  saveGlobalConfig((current) => {
108110
- if (current.oauthAccount?.accountUuid === accountInfo.accountUuid && current.oauthAccount?.emailAddress === accountInfo.emailAddress && current.oauthAccount?.organizationUuid === accountInfo.organizationUuid && current.oauthAccount?.displayName === accountInfo.displayName && current.oauthAccount?.hasExtraUsageEnabled === accountInfo.hasExtraUsageEnabled && current.oauthAccount?.billingType === accountInfo.billingType && current.oauthAccount?.accountCreatedAt === accountInfo.accountCreatedAt && current.oauthAccount?.subscriptionCreatedAt === accountInfo.subscriptionCreatedAt) {
108120
+ if (current.oauthAccount?.accountUuid === accountInfo.accountUuid && current.oauthAccount?.emailAddress === accountInfo.emailAddress && current.oauthAccount?.organizationUuid === accountInfo.organizationUuid && current.oauthAccount?.displayName === accountInfo.displayName && current.oauthAccount?.username === accountInfo.username && current.oauthAccount?.profilePhotoUrl === accountInfo.profilePhotoUrl && current.oauthAccount?.hasExtraUsageEnabled === accountInfo.hasExtraUsageEnabled && current.oauthAccount?.billingType === accountInfo.billingType && current.oauthAccount?.accountCreatedAt === accountInfo.accountCreatedAt && current.oauthAccount?.subscriptionCreatedAt === accountInfo.subscriptionCreatedAt) {
108111
108121
  return current;
108112
108122
  }
108113
108123
  return { ...current, oauthAccount: accountInfo };
@@ -108831,6 +108841,7 @@ async function refreshMyTabulonAccount({
108831
108841
  emailAddress: context2?.user?.email || previous?.emailAddress,
108832
108842
  displayName: context2?.user?.display_name || previous?.displayName,
108833
108843
  username: context2?.user?.username || previous?.username,
108844
+ profilePhotoUrl: context2?.user?.profile_photo_url || previous?.profilePhotoUrl,
108834
108845
  workspaceId: context2?.workspace?.id || previous?.workspaceId,
108835
108846
  workspaceName: context2?.workspace?.name || previous?.workspaceName,
108836
108847
  codingPlanActive: typeof plan.active === "boolean" ? plan.active : previous?.codingPlanActive ?? true,
@@ -108856,6 +108867,7 @@ function persistMyTabulonState(apiKey, baseUrl, models, account) {
108856
108867
  openAIModel: undefined,
108857
108868
  mytabulonDefaultModel: defaultModel,
108858
108869
  mytabulonAccount: account,
108870
+ maximoAccount: undefined,
108859
108871
  cencoriApiKey: undefined
108860
108872
  }));
108861
108873
  }
@@ -108900,7 +108912,8 @@ function persistCencoriState(apiKey, baseUrl, model) {
108900
108912
  openAIModel: model ?? current.openAIModel,
108901
108913
  openCodePlan: undefined,
108902
108914
  mytabulonDefaultModel: undefined,
108903
- mytabulonAccount: undefined
108915
+ mytabulonAccount: undefined,
108916
+ maximoAccount: undefined
108904
108917
  }));
108905
108918
  }
108906
108919
  async function configureCencoriProvider(apiKey) {
@@ -108954,6 +108967,7 @@ function persistExternalProviderState({
108954
108967
  cencoriApiKey: undefined,
108955
108968
  mytabulonDefaultModel: undefined,
108956
108969
  mytabulonAccount: undefined,
108970
+ maximoAccount: undefined,
108957
108971
  oauthAccount: undefined
108958
108972
  }));
108959
108973
  }
@@ -111323,6 +111337,32 @@ function containsImageContent(value) {
111323
111337
  return true;
111324
111338
  return containsImageContent(record2.content) || containsImageContent(record2.message);
111325
111339
  }
111340
+ function errorText(value) {
111341
+ if (value instanceof Error)
111342
+ return value.message;
111343
+ return typeof value === "string" ? value : "";
111344
+ }
111345
+ function isOpenAIUserAbort(error41, signal) {
111346
+ if (signal?.aborted && /timed out/i.test(errorText(signal.reason)))
111347
+ return false;
111348
+ if (signal?.aborted)
111349
+ return true;
111350
+ if (/timed out/i.test(errorText(error41)))
111351
+ return false;
111352
+ return error41 instanceof Error && error41.name === "AbortError";
111353
+ }
111354
+ function throwOpenAICompatibleHttpError(response, errorBody) {
111355
+ let parsed;
111356
+ try {
111357
+ parsed = JSON.parse(errorBody);
111358
+ } catch {
111359
+ parsed = undefined;
111360
+ }
111361
+ const record2 = parsed && typeof parsed === "object" ? parsed : undefined;
111362
+ const nested = record2?.error && typeof record2.error === "object" ? record2.error : record2;
111363
+ const display = `OpenAI-compatible API error ${response.status}: ${errorBody}`;
111364
+ throw new APIError(response.status, { ...nested ?? {}, message: display }, display, response.headers);
111365
+ }
111326
111366
 
111327
111367
  class OpenAIShimMessages {
111328
111368
  defaultHeaders;
@@ -111452,15 +111492,27 @@ class OpenAIShimMessages {
111452
111492
  headers["HTTP-Referer"] = "https://maximoai.co";
111453
111493
  headers["X-OpenRouter-Title"] = "Maximo Syntax";
111454
111494
  }
111455
- const response = await fetch(`${request.baseUrl}/chat/completions`, {
111456
- method: "POST",
111457
- headers,
111458
- body: JSON.stringify(body),
111459
- signal: options?.signal
111460
- });
111495
+ let response;
111496
+ try {
111497
+ response = await fetch(`${request.baseUrl}/chat/completions`, {
111498
+ method: "POST",
111499
+ headers,
111500
+ body: JSON.stringify(body),
111501
+ signal: options?.signal
111502
+ });
111503
+ } catch (error41) {
111504
+ if (isOpenAIUserAbort(error41, options?.signal))
111505
+ throw error41;
111506
+ if (error41 instanceof APIError)
111507
+ throw error41;
111508
+ throw new APIConnectionError({
111509
+ message: error41 instanceof Error ? error41.message : "fetch failed",
111510
+ cause: error41 instanceof Error ? error41 : undefined
111511
+ });
111512
+ }
111461
111513
  if (!response.ok) {
111462
111514
  const errorBody = await response.text().catch(() => "unknown error");
111463
- throw new Error(`OpenAI-compatible API error ${response.status}: ${errorBody}`);
111515
+ throwOpenAICompatibleHttpError(response, errorBody);
111464
111516
  }
111465
111517
  return response;
111466
111518
  }
@@ -111565,6 +111617,7 @@ function createOpenAIShimClient(options) {
111565
111617
  }
111566
111618
  var TOOL_RESULT_IMAGE_PLACEHOLDER = "[Tool returned an image.]", OpenAIShimStream;
111567
111619
  var init_openaiShim = __esm(() => {
111620
+ init_sdk();
111568
111621
  init_providerConfig();
111569
111622
  OpenAIShimStream = class OpenAIShimStream {
111570
111623
  generator;
@@ -124011,7 +124064,7 @@ var init_metadata = __esm(() => {
124011
124064
  isMaximoAiAuth: isMaximoAISubscriber(),
124012
124065
  version: "99.0.0",
124013
124066
  versionBase: getVersionBase(),
124014
- buildTime: "2026-08-23T12:37:37.196Z",
124067
+ buildTime: "2026-08-30T20:30:34.525Z",
124015
124068
  deploymentEnvironment: env3.detectDeploymentEnvironment(),
124016
124069
  ...isEnvTruthy(process.env.GITHUB_ACTIONS) && {
124017
124070
  githubEventName: process.env.GITHUB_EVENT_NAME,
@@ -177659,6 +177712,61 @@ function isPersistentRetryEnabled() {
177659
177712
  function isTransientCapacityError(error42) {
177660
177713
  return is529Error(error42) || error42 instanceof APIError && error42.status === 429;
177661
177714
  }
177715
+ function providerErrorBlob(error42) {
177716
+ if (error42 == null)
177717
+ return "";
177718
+ if (typeof error42 === "string")
177719
+ return error42;
177720
+ if (error42 instanceof Error) {
177721
+ const extra = "error" in error42 && error42.error != null ? JSON.stringify(error42.error) : "";
177722
+ return `${error42.message} ${extra}`;
177723
+ }
177724
+ try {
177725
+ return JSON.stringify(error42);
177726
+ } catch {
177727
+ return String(error42);
177728
+ }
177729
+ }
177730
+ function isTransientProviderRateLimit(error42) {
177731
+ const blob2 = providerErrorBlob(error42);
177732
+ return /token_limit_exceeded/i.test(blob2) || /tokens per minute limit/i.test(blob2) || /OpenAI-compatible API error 429/i.test(blob2);
177733
+ }
177734
+ function isUserAbortError(error42) {
177735
+ if (error42 instanceof APIUserAbortError)
177736
+ return true;
177737
+ return error42 instanceof Error && error42.name === "AbortError";
177738
+ }
177739
+ function isGenericTransientProviderError(error42) {
177740
+ if (error42 == null || isUserAbortError(error42))
177741
+ return false;
177742
+ if (error42 instanceof APIError)
177743
+ return false;
177744
+ if (error42 instanceof TypeError)
177745
+ return true;
177746
+ const blob2 = providerErrorBlob(error42);
177747
+ return /fetch failed/i.test(blob2) || /failed to fetch/i.test(blob2) || /ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|ENETUNREACH|EHOSTUNREACH/i.test(blob2) || /socket hang up|UND_ERR|timed out/i.test(blob2) || /OpenAI-compatible API error (429|408|409|5\d\d)/i.test(blob2) || /token_limit_exceeded/i.test(blob2);
177748
+ }
177749
+ function asSystemRetryError(error42) {
177750
+ if (error42 instanceof APIError)
177751
+ return error42;
177752
+ const message = error42 instanceof Error ? error42.message : String(error42);
177753
+ const statusMatch = /OpenAI-compatible API error (\d{3})/.exec(message);
177754
+ const status = statusMatch ? Number(statusMatch[1]) : undefined;
177755
+ if (status) {
177756
+ return new APIError(status, { message }, message, new globalThis.Headers);
177757
+ }
177758
+ return new APIConnectionError({
177759
+ message,
177760
+ cause: error42 instanceof Error ? error42 : undefined
177761
+ });
177762
+ }
177763
+ function isRetryableApiFailure(error42) {
177764
+ if (isUserAbortError(error42))
177765
+ return false;
177766
+ if (error42 instanceof APIError)
177767
+ return shouldRetry(error42);
177768
+ return isGenericTransientProviderError(error42);
177769
+ }
177662
177770
  function isStaleConnectionError(error42) {
177663
177771
  if (!(error42 instanceof APIConnectionError)) {
177664
177772
  return false;
@@ -177760,7 +177868,7 @@ async function* withRetry(getClient, operation, options2) {
177760
177868
  throw new CannotRetryError(error42, retryContext);
177761
177869
  }
177762
177870
  const handledCloudAuthError = handleAwsCredentialError(error42) || handleGcpCredentialError(error42);
177763
- if (!handledCloudAuthError && (!(error42 instanceof APIError) || !shouldRetry(error42))) {
177871
+ if (!handledCloudAuthError && !isRetryableApiFailure(error42)) {
177764
177872
  throw new CannotRetryError(error42, retryContext);
177765
177873
  }
177766
177874
  if (error42 instanceof APIError) {
@@ -177796,6 +177904,9 @@ async function* withRetry(getClient, operation, options2) {
177796
177904
  delayMs = Math.min(getRetryDelay(persistentAttempt, retryAfter, PERSISTENT_MAX_BACKOFF_MS), PERSISTENT_RESET_CAP_MS);
177797
177905
  } else {
177798
177906
  delayMs = getRetryDelay(attempt, retryAfter);
177907
+ if (isTransientProviderRateLimit(error42)) {
177908
+ delayMs = Math.max(delayMs, RATE_LIMIT_MIN_DELAY_MS);
177909
+ }
177799
177910
  }
177800
177911
  const reportedAttempt = persistent ? persistentAttempt : attempt;
177801
177912
  logEvent("tengu_api_retry", {
@@ -177818,9 +177929,7 @@ async function* withRetry(getClient, operation, options2) {
177818
177929
  while (remaining > 0) {
177819
177930
  if (options2.signal?.aborted)
177820
177931
  throw new APIUserAbortError;
177821
- if (error42 instanceof APIError) {
177822
- yield createSystemAPIErrorMessage(error42, remaining, reportedAttempt, maxRetries);
177823
- }
177932
+ yield createSystemAPIErrorMessage(asSystemRetryError(error42), remaining, reportedAttempt, maxRetries);
177824
177933
  const chunk = Math.min(remaining, HEARTBEAT_INTERVAL_MS);
177825
177934
  await sleep2(chunk, options2.signal, { abortError });
177826
177935
  remaining -= chunk;
@@ -177828,9 +177937,7 @@ async function* withRetry(getClient, operation, options2) {
177828
177937
  if (attempt >= maxRetries)
177829
177938
  attempt = maxRetries;
177830
177939
  } else {
177831
- if (error42 instanceof APIError) {
177832
- yield createSystemAPIErrorMessage(error42, delayMs, attempt, maxRetries);
177833
- }
177940
+ yield createSystemAPIErrorMessage(asSystemRetryError(error42), delayMs, attempt, maxRetries);
177834
177941
  await sleep2(delayMs, options2.signal, { abortError });
177835
177942
  }
177836
177943
  }
@@ -177965,6 +178072,8 @@ function shouldRetry(error42) {
177965
178072
  if (error42.status === 409)
177966
178073
  return true;
177967
178074
  if (error42.status === 429) {
178075
+ if (isTransientProviderRateLimit(error42))
178076
+ return true;
177968
178077
  return !isMaximoAISubscriber() || isEnterpriseSubscriber();
177969
178078
  }
177970
178079
  if (error42.status === 401) {
@@ -178009,7 +178118,7 @@ function getRateLimitResetDelayMs(error42) {
178009
178118
  return null;
178010
178119
  return Math.min(delayMs, PERSISTENT_RESET_CAP_MS);
178011
178120
  }
178012
- var abortError = () => new APIUserAbortError, DEFAULT_MAX_RETRIES = 10, FLOOR_OUTPUT_TOKENS = 3000, MAX_529_RETRIES = 3, BASE_DELAY_MS = 500, FOREGROUND_529_RETRY_SOURCES, PERSISTENT_MAX_BACKOFF_MS, PERSISTENT_RESET_CAP_MS, HEARTBEAT_INTERVAL_MS = 30000, CannotRetryError, FallbackTriggeredError, DEFAULT_FAST_MODE_FALLBACK_HOLD_MS, SHORT_RETRY_THRESHOLD_MS, MIN_COOLDOWN_MS;
178121
+ var abortError = () => new APIUserAbortError, DEFAULT_MAX_RETRIES = 10, FLOOR_OUTPUT_TOKENS = 3000, MAX_529_RETRIES = 3, BASE_DELAY_MS = 500, FOREGROUND_529_RETRY_SOURCES, PERSISTENT_MAX_BACKOFF_MS, PERSISTENT_RESET_CAP_MS, HEARTBEAT_INTERVAL_MS = 30000, RATE_LIMIT_MIN_DELAY_MS = 2000, CannotRetryError, FallbackTriggeredError, DEFAULT_FAST_MODE_FALLBACK_HOLD_MS, SHORT_RETRY_THRESHOLD_MS, MIN_COOLDOWN_MS;
178013
178122
  var init_withRetry = __esm(() => {
178014
178123
  init_sdk();
178015
178124
  init_aws();
@@ -274589,6 +274698,7 @@ async function performLogout({
274589
274698
  updated.openAIProvider = undefined;
274590
274699
  updated.mytabulonDefaultModel = undefined;
274591
274700
  updated.mytabulonAccount = undefined;
274701
+ updated.maximoAccount = undefined;
274592
274702
  updated.openCodePlan = undefined;
274593
274703
  updated.cencoriApiKey = undefined;
274594
274704
  updated.openAIModel = undefined;
@@ -276787,7 +276897,7 @@ import { access as access3, writeFile as writeFile13 } from "fs/promises";
276787
276897
  import { homedir as homedir22 } from "os";
276788
276898
  import { join as join65 } from "path";
276789
276899
  function getCurrentRealVersion() {
276790
- return "0.1.39";
276900
+ return "0.1.40";
276791
276901
  }
276792
276902
  async function getRolloutConfig() {
276793
276903
  try {
@@ -278193,6 +278303,8 @@ async function installOAuthTokens(tokens) {
278193
278303
  emailAddress: profile.account.email,
278194
278304
  organizationUuid: profile.organization.uuid,
278195
278305
  displayName: profile.account.display_name || undefined,
278306
+ username: profile.account.username || undefined,
278307
+ profilePhotoUrl: profile.account.profile_photo_url || undefined,
278196
278308
  hasExtraUsageEnabled: profile.organization.has_extra_usage_enabled ?? undefined,
278197
278309
  billingType: profile.organization.billing_type ?? undefined,
278198
278310
  subscriptionCreatedAt: profile.organization.subscription_created_at ?? undefined,
@@ -366809,7 +366921,7 @@ function getAnthropicEnvMetadata() {
366809
366921
  function getBuildAgeMinutes() {
366810
366922
  if (false)
366811
366923
  ;
366812
- const buildTime = new Date("2026-08-23T12:37:37.196Z").getTime();
366924
+ const buildTime = new Date("2026-08-30T20:30:34.525Z").getTime();
366813
366925
  if (isNaN(buildTime))
366814
366926
  return;
366815
366927
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -380607,11 +380719,11 @@ function normalizeMessagesForAPI(messages, tools = []) {
380607
380719
  if (!isSyntheticApiErrorMessage(msg)) {
380608
380720
  continue;
380609
380721
  }
380610
- const errorText = Array.isArray(msg.message.content) && msg.message.content[0]?.type === "text" ? msg.message.content[0].text : undefined;
380611
- if (!errorText) {
380722
+ const errorText2 = Array.isArray(msg.message.content) && msg.message.content[0]?.type === "text" ? msg.message.content[0].text : undefined;
380723
+ if (!errorText2) {
380612
380724
  continue;
380613
380725
  }
380614
- const blockTypesToStrip = errorToBlockTypes[errorText];
380726
+ const blockTypesToStrip = errorToBlockTypes[errorText2];
380615
380727
  if (!blockTypesToStrip) {
380616
380728
  continue;
380617
380729
  }
@@ -432998,7 +433110,7 @@ function getRecentActivitySync() {
432998
433110
  return cachedActivity;
432999
433111
  }
433000
433112
  function getLogoDisplayData() {
433001
- const version2 = process.env.DEMO_VERSION ?? "0.1.39" ?? "99.0.0";
433113
+ const version2 = process.env.DEMO_VERSION ?? "0.1.40" ?? "99.0.0";
433002
433114
  const serverUrl = getDirectConnectServerUrl();
433003
433115
  const displayPath = process.env.DEMO_VERSION ? "/code/maximo" : getDisplayPath(getCwd());
433004
433116
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -462463,7 +462575,7 @@ var init_bridge_kick = __esm(() => {
462463
462575
  var call57 = async () => {
462464
462576
  return {
462465
462577
  type: "text",
462466
- value: `${"99.0.0"} (built ${"2026-08-23T12:37:37.196Z"})`
462578
+ value: `${"99.0.0"} (built ${"2026-08-30T20:30:34.525Z"})`
462467
462579
  };
462468
462580
  }, version2, version_default;
462469
462581
  var init_version = __esm(() => {
@@ -536996,7 +537108,7 @@ function SetupRow({ children }) {
536996
537108
  }
536997
537109
  function WelcomeV2() {
536998
537110
  const { columns } = useTerminalSize();
536999
- const version3 = "0.1.39";
537111
+ const version3 = "0.1.40";
537000
537112
  const width = Math.max(48, Math.min(columns || 92, 92));
537001
537113
  const stacked = width < OCTOPUS_COMPACT_WIDTH + 42;
537002
537114
  return /* @__PURE__ */ jsx_runtime479.jsx(ThemedBox_default, {
@@ -553002,14 +553114,14 @@ async function startMCPServer(cwd3, debug2, verbose) {
553002
553114
  } catch (error42) {
553003
553115
  logError2(error42);
553004
553116
  const parts = error42 instanceof Error ? getErrorParts(error42) : [String(error42)];
553005
- const errorText = parts.filter(Boolean).join(`
553117
+ const errorText2 = parts.filter(Boolean).join(`
553006
553118
  `).trim() || "Error";
553007
553119
  return {
553008
553120
  isError: true,
553009
553121
  content: [
553010
553122
  {
553011
553123
  type: "text",
553012
- text: errorText
553124
+ text: errorText2
553013
553125
  }
553014
553126
  ]
553015
553127
  };
@@ -556932,7 +557044,7 @@ Usage: maximo --remote "your task description"`, () => gracefulShutdown(1));
556932
557044
  pendingHookMessages
556933
557045
  }, renderAndRun);
556934
557046
  }
556935
- }).version("0.1.39 (Maximo Syntax)", "-v, --version", "Output the version number");
557047
+ }).version("0.1.40 (Maximo Syntax)", "-v, --version", "Output the version number");
556936
557048
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
556937
557049
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
556938
557050
  if (canUserConfigureAdvisor()) {
@@ -557471,7 +557583,7 @@ function validateProviderEnvOrExit() {
557471
557583
  async function main2() {
557472
557584
  const args = process.argv.slice(2);
557473
557585
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
557474
- console.log(`${"0.1.39"} (Maximo Syntax)`);
557586
+ console.log(`${"0.1.40"} (Maximo Syntax)`);
557475
557587
  return;
557476
557588
  }
557477
557589
  validateProviderEnvOrExit();
@@ -557548,4 +557660,4 @@ async function main2() {
557548
557660
  }
557549
557661
  main2();
557550
557662
 
557551
- //# debugId=8818C1A459D7EBB064756E2164756E21
557663
+ //# debugId=B2B7B0786EC5C8EB64756E2164756E21
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maximoai/maximo-syntax-cli",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "description": "Maximo Syntax CLI - A powerful AI-powered command-line interface for code development with any LLM",
5
5
  "type": "module",
6
6
  "bin": {