@hermespilot/link 0.7.5-beta.0 → 0.7.6

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.
@@ -2314,6 +2314,9 @@ function resolveHermesProfilesDir() {
2314
2314
  function resolveHermesConfigPath(profileName = "default") {
2315
2315
  return path3.join(resolveHermesProfileDir(profileName), "config.yaml");
2316
2316
  }
2317
+ function resolveHermesEnvPath(profileName = "default") {
2318
+ return path3.join(resolveHermesProfileDir(profileName), ".env");
2319
+ }
2317
2320
  async function readHermesSessionsDir(profileName = "default", configPath = resolveHermesConfigPath(profileName)) {
2318
2321
  const profileDir = resolveHermesProfileDir(profileName);
2319
2322
  const { config } = await readHermesConfigDocument(configPath);
@@ -2618,16 +2621,20 @@ async function saveHermesModelConfig(input, profileName = "default", configPath
2618
2621
  const shouldUpdateReasoningEffort = input.reasoningEffort !== void 0;
2619
2622
  const { document, config, existingRaw } = await readHermesConfigDocument(configPath);
2620
2623
  const providers = ensureProvidersRecordWithLegacyMigration(config);
2621
- const originalModelId = input.originalModelId?.trim() || normalized.id;
2624
+ const originalModelId = input.originalModelId?.trim();
2622
2625
  const originalProvider = input.originalProvider?.trim();
2623
2626
  const originalBaseUrl = input.originalBaseUrl?.trim();
2624
2627
  const originalApiMode = input.originalApiMode?.trim();
2625
- const existingProviderKey = findProviderConfigKeyByModelIdentity(providers, {
2626
- id: originalModelId,
2628
+ const originalIdentity = {
2629
+ id: originalModelId || normalized.id,
2627
2630
  provider: originalProvider,
2628
2631
  baseUrl: originalBaseUrl,
2629
2632
  apiMode: originalApiMode
2630
- }) ?? (originalProvider && originalBaseUrl ? findProviderConfigKeyByEndpoint(providers, {
2633
+ };
2634
+ const hasOriginalIdentity = Boolean(
2635
+ originalModelId || originalProvider || originalBaseUrl || originalApiMode
2636
+ );
2637
+ const existingProviderKey = (hasOriginalIdentity ? findProviderConfigKeyByModelIdentity(providers, originalIdentity) : null) ?? (originalProvider && originalBaseUrl ? findProviderConfigKeyByEndpoint(providers, {
2631
2638
  provider: originalProvider,
2632
2639
  baseUrl: originalBaseUrl,
2633
2640
  apiMode: originalApiMode
@@ -2647,7 +2654,7 @@ async function saveHermesModelConfig(input, profileName = "default", configPath
2647
2654
  await writeHermesEnvValue(profileName, keyEnv, normalized.apiKey);
2648
2655
  }
2649
2656
  writeProviderEndpointConfig(entry, normalized, keyEnv);
2650
- ensureEntryModelConfig(entry, originalModelId, normalized.id);
2657
+ ensureEntryModelConfig(entry, originalIdentity.id, normalized.id);
2651
2658
  writeEntryModelContextLength(entry, normalized.id, normalized.contextLength);
2652
2659
  writeEntryModelSupportsVision(entry, normalized.id, input.supportsVision);
2653
2660
  if (shouldUpdateReasoningEffort) {
@@ -2662,15 +2669,29 @@ async function saveHermesModelConfig(input, profileName = "default", configPath
2662
2669
  const currentDefaultConfig = readModelConfig(modelConfig);
2663
2670
  const currentDefault = currentDefaultConfig.model;
2664
2671
  const currentDefaultReasoningEffort = readProfileReasoningEffort(config);
2665
- if (normalized.setDefault || !currentDefault || currentDefault === originalModelId) {
2666
- if (normalized.setDefault && currentDefault && currentDefault !== normalized.id && currentDefault !== originalModelId) {
2672
+ const currentDefaultMatchesOriginal = hasOriginalIdentity && modelConfigMatchesModelIdentity(currentDefaultConfig, originalIdentity);
2673
+ const currentDefaultMatchesNext = modelConfigMatchesModelIdentity(
2674
+ currentDefaultConfig,
2675
+ {
2676
+ id: normalized.id,
2677
+ provider: providerKey,
2678
+ baseUrl: normalized.baseUrl,
2679
+ apiMode: inferApiMode(
2680
+ providerKey,
2681
+ normalized.baseUrl,
2682
+ normalized.apiMode
2683
+ )
2684
+ }
2685
+ );
2686
+ if (normalized.setDefault || !currentDefault || currentDefaultMatchesOriginal) {
2687
+ if (normalized.setDefault && currentDefault && !currentDefaultMatchesNext && !currentDefaultMatchesOriginal) {
2667
2688
  retainModelDefaultAsProvider(providers, {
2668
2689
  ...currentDefaultConfig,
2669
2690
  ...currentDefaultReasoningEffort ? { reasoningEffort: currentDefaultReasoningEffort } : {}
2670
2691
  });
2671
2692
  }
2672
- const defaultKeyEnv = keyEnv ?? (currentDefault === originalModelId ? currentDefaultConfig.keyEnv : void 0);
2673
- const defaultApiKey = normalized.apiKey ?? (!defaultKeyEnv && currentDefault === originalModelId ? currentDefaultConfig.apiKey : void 0);
2693
+ const defaultKeyEnv = keyEnv ?? (currentDefaultMatchesOriginal ? currentDefaultConfig.keyEnv : void 0);
2694
+ const defaultApiKey = normalized.apiKey ?? (!defaultKeyEnv && currentDefaultMatchesOriginal ? currentDefaultConfig.apiKey : void 0);
2674
2695
  writeDefaultModelConfig(modelConfig, {
2675
2696
  ...normalized,
2676
2697
  provider: providerKey,
@@ -2858,7 +2879,12 @@ async function saveHermesModelDefaults(input, profileName = "default", configPat
2858
2879
  const modelConfig = ensureRecord(config, "model");
2859
2880
  const currentDefaultConfig = readModelConfig(modelConfig);
2860
2881
  const currentDefaultReasoningEffort = readProfileReasoningEffort(config);
2861
- if (currentDefaultConfig.model && currentDefaultConfig.model !== selected.id) {
2882
+ if (currentDefaultConfig.model && !modelConfigMatchesModelIdentity(currentDefaultConfig, {
2883
+ id: selected.id,
2884
+ provider: selected.provider,
2885
+ baseUrl: selected.baseUrl,
2886
+ apiMode: selected.apiMode
2887
+ })) {
2862
2888
  retainModelDefaultAsProvider(providers, {
2863
2889
  ...currentDefaultConfig,
2864
2890
  ...currentDefaultReasoningEffort ? { reasoningEffort: currentDefaultReasoningEffort } : {}
@@ -2923,7 +2949,9 @@ async function readHermesProfilePermissions(profileName = "default", configPath
2923
2949
  }
2924
2950
  async function saveHermesProfilePermissions(profileName, input, configPath = resolveHermesConfigPath(profileName)) {
2925
2951
  const { document, config, existingRaw } = await readHermesConfigDocument(configPath);
2952
+ let configTouched = false;
2926
2953
  if (input.approvals) {
2954
+ configTouched = true;
2927
2955
  const approvals = ensureRecord(config, "approvals");
2928
2956
  if (input.approvals.mode !== void 0) {
2929
2957
  approvals.mode = normalizeApprovalMode(input.approvals.mode);
@@ -2939,6 +2967,7 @@ async function saveHermesProfilePermissions(profileName, input, configPath = res
2939
2967
  }
2940
2968
  }
2941
2969
  if (input.terminal) {
2970
+ configTouched = true;
2942
2971
  const terminal = ensureRecord(config, "terminal");
2943
2972
  if (input.terminal.backend !== void 0) {
2944
2973
  terminal.backend = normalizeTerminalBackend(input.terminal.backend);
@@ -2968,7 +2997,24 @@ async function saveHermesProfilePermissions(profileName, input, configPath = res
2968
2997
  terminal.container_persistent = input.terminal.containerPersistent;
2969
2998
  }
2970
2999
  }
3000
+ let envChanged = false;
3001
+ if (input.sudo) {
3002
+ if (input.sudo.clear) {
3003
+ envChanged = await deleteHermesEnvValue(profileName, "SUDO_PASSWORD") || envChanged;
3004
+ const terminal = toRecord(config.terminal);
3005
+ if (terminal.sudo_password !== void 0) {
3006
+ delete terminal.sudo_password;
3007
+ configTouched = true;
3008
+ }
3009
+ }
3010
+ if (input.sudo.password !== void 0) {
3011
+ const password = normalizeSudoPassword(input.sudo.password);
3012
+ await writeHermesEnvValue(profileName, "SUDO_PASSWORD", password);
3013
+ envChanged = true;
3014
+ }
3015
+ }
2971
3016
  if (input.toolsets) {
3017
+ configTouched = true;
2972
3018
  const env = await readHermesEnvFile(profileName);
2973
3019
  const currentPermissions = profilePermissionsFromConfig(
2974
3020
  profileName,
@@ -2996,16 +3042,16 @@ async function saveHermesProfilePermissions(profileName, input, configPath = res
2996
3042
  }
2997
3043
  platformToolsets.api_server = next;
2998
3044
  }
2999
- const backupPath = await writeHermesConfigDocument({
3045
+ const backupPath = configTouched ? await writeHermesConfigDocument({
3000
3046
  configPath,
3001
3047
  document,
3002
3048
  config,
3003
3049
  existingRaw
3004
- });
3050
+ }) : null;
3005
3051
  return {
3006
3052
  ...await readHermesProfilePermissions(profileName, configPath),
3007
3053
  backupPath,
3008
- requiresGatewayReload: true,
3054
+ requiresGatewayReload: configTouched || envChanged,
3009
3055
  restartHint: PROFILE_PERMISSIONS_RESTART_HINT
3010
3056
  };
3011
3057
  }
@@ -3472,6 +3518,11 @@ function providerConfigToLegacyEntry(providerKey, entry) {
3472
3518
  }
3473
3519
  function ensureProvidersRecordWithLegacyMigration(config) {
3474
3520
  const providers = ensureRecord(config, "providers");
3521
+ for (const [key, rawEntry] of Object.entries(providers)) {
3522
+ const entry = toRecord(rawEntry);
3523
+ normalizeProviderCredentialReference(entry);
3524
+ providers[key] = entry;
3525
+ }
3475
3526
  const customProviders = Array.isArray(config.custom_providers) ? config.custom_providers : [];
3476
3527
  for (const rawEntry of customProviders) {
3477
3528
  const entry = toRecord(rawEntry);
@@ -3609,7 +3660,7 @@ function legacyEntryToProviderConfig(entry, baseUrl) {
3609
3660
  const apiKey = readString2(entry.api_key);
3610
3661
  const keyEnv = readString2(entry.key_env) ?? parseEnvReference(apiKey);
3611
3662
  if (keyEnv) {
3612
- next.key_env = keyEnv;
3663
+ next.api_key = `\${${keyEnv}}`;
3613
3664
  } else if (apiKey) {
3614
3665
  next.api_key = apiKey;
3615
3666
  }
@@ -3643,6 +3694,15 @@ function legacyEntryToProviderConfig(entry, baseUrl) {
3643
3694
  }
3644
3695
  return next;
3645
3696
  }
3697
+ function normalizeProviderCredentialReference(entry) {
3698
+ const apiKey = readString2(entry.api_key);
3699
+ const keyEnv = readString2(entry.key_env) ?? parseEnvReference(apiKey);
3700
+ if (!keyEnv) {
3701
+ return;
3702
+ }
3703
+ entry.api_key = `\${${keyEnv}}`;
3704
+ delete entry.key_env;
3705
+ }
3646
3706
  function normalizeEntryModelsMap(entry) {
3647
3707
  const models = entry.models;
3648
3708
  if (typeof models === "object" && models !== null && !Array.isArray(models)) {
@@ -3780,8 +3840,8 @@ function writeProviderEndpointConfig(entry, input, keyEnv) {
3780
3840
  delete entry.contextLength;
3781
3841
  }
3782
3842
  if (keyEnv) {
3783
- entry.key_env = keyEnv;
3784
- delete entry.api_key;
3843
+ entry.api_key = `\${${keyEnv}}`;
3844
+ delete entry.key_env;
3785
3845
  } else {
3786
3846
  delete entry.key_env;
3787
3847
  }
@@ -4041,22 +4101,18 @@ function managedModelPreferenceScore(model) {
4041
4101
  return (model.isDefault ? 1e3 : 0) + (model.credentialState === "configured" ? 200 : 0) + (model.credentialState === "missing" ? 50 : 0) + (model.source === "auth_store" ? 100 : 0) + (model.credentialSource !== "unknown" ? 40 : 0) + (model.isReadOnly ? 10 : 0);
4042
4102
  }
4043
4103
  function matchesDefaultModelConfig(input) {
4044
- if (!input.defaultModel || input.id !== input.defaultModel) {
4045
- return false;
4046
- }
4047
- const defaultApiMode = input.modelConfig.apiMode?.trim();
4048
- if (defaultApiMode && input.apiMode !== defaultApiMode) {
4104
+ if (!input.defaultModel) {
4049
4105
  return false;
4050
4106
  }
4051
- const defaultBaseUrl = input.modelConfig.baseUrl;
4052
- if (defaultBaseUrl?.trim()) {
4053
- return normalizeBaseUrl(input.baseUrl) === normalizeBaseUrl(defaultBaseUrl);
4054
- }
4055
- const defaultProvider = input.modelConfig.provider?.trim();
4056
- if (defaultProvider) {
4057
- return input.provider === defaultProvider;
4058
- }
4059
- return true;
4107
+ return modelConfigMatchesModelIdentity(
4108
+ { ...input.modelConfig, model: input.defaultModel },
4109
+ {
4110
+ id: input.id,
4111
+ provider: input.provider,
4112
+ baseUrl: input.baseUrl,
4113
+ apiMode: input.apiMode
4114
+ }
4115
+ );
4060
4116
  }
4061
4117
  function providerEntryMatchesManagedModel(entry, model) {
4062
4118
  const providerName = readString2(entry.name) ?? readString2(entry.provider_name) ?? readString2(entry.provider_key) ?? "Custom Provider";
@@ -4266,6 +4322,29 @@ function resolveCompressionModel(config, models) {
4266
4322
  function findManagedModelById(models, id) {
4267
4323
  return models.find((model) => model.id === id);
4268
4324
  }
4325
+ function modelConfigMatchesModelIdentity(modelConfig, input) {
4326
+ if (modelConfig.model !== input.id) {
4327
+ return false;
4328
+ }
4329
+ const provider = input.provider?.trim();
4330
+ const configProvider = modelConfig.provider?.trim();
4331
+ if (provider && configProvider && configProvider !== provider) {
4332
+ return false;
4333
+ }
4334
+ const baseUrl = input.baseUrl?.trim();
4335
+ if (baseUrl !== void 0 && normalizeBaseUrl(modelConfig.baseUrl ?? "") !== normalizeBaseUrl(baseUrl)) {
4336
+ return false;
4337
+ }
4338
+ const apiMode = input.apiMode?.trim();
4339
+ if (apiMode) {
4340
+ const providerForApiMode = configProvider ?? provider ?? "default";
4341
+ const configBaseUrl = modelConfig.baseUrl ?? baseUrl ?? "";
4342
+ if (inferApiMode(providerForApiMode, configBaseUrl, modelConfig.apiMode) !== apiMode) {
4343
+ return false;
4344
+ }
4345
+ }
4346
+ return true;
4347
+ }
4269
4348
  function findManagedModel(models, input) {
4270
4349
  const provider = input.provider?.trim();
4271
4350
  const baseUrl = input.baseUrl?.trim();
@@ -4430,7 +4509,7 @@ function retainModelDefaultAsProvider(providers, model) {
4430
4509
  writeEntryModelSupportsVision(entry, id, model.supportsVision);
4431
4510
  }
4432
4511
  if (model.keyEnv) {
4433
- entry.key_env = model.keyEnv;
4512
+ entry.api_key = `\${${model.keyEnv}}`;
4434
4513
  } else if (model.apiKey) {
4435
4514
  entry.api_key = model.apiKey;
4436
4515
  }
@@ -4891,6 +4970,7 @@ function readPositiveInteger(value) {
4891
4970
  function profilePermissionsFromConfig(profileName, configPath, config, env) {
4892
4971
  const approvals = toRecord(config.approvals);
4893
4972
  const terminal = toRecord(config.terminal);
4973
+ const envPath = resolveHermesEnvPath(profileName);
4894
4974
  const platformToolsets = toRecord(config.platform_toolsets);
4895
4975
  const apiServerToolsets = readStringList(platformToolsets.api_server);
4896
4976
  const hasExplicitToolsets = apiServerToolsets.some(
@@ -4904,6 +4984,7 @@ function profilePermissionsFromConfig(profileName, configPath, config, env) {
4904
4984
  return {
4905
4985
  profileName,
4906
4986
  configPath,
4987
+ envPath,
4907
4988
  approvals: {
4908
4989
  mode: readApprovalMode(approvals.mode),
4909
4990
  timeout: readPositiveInteger(approvals.timeout) ?? 60,
@@ -4917,6 +4998,11 @@ function profilePermissionsFromConfig(profileName, configPath, config, env) {
4917
4998
  containerDisk: readPositiveInteger(terminal.container_disk) ?? null,
4918
4999
  containerPersistent: terminal.container_persistent !== false
4919
5000
  },
5001
+ sudo: {
5002
+ configured: isEnvValueConfigured(env.SUDO_PASSWORD) || isEnvValueConfigured(readString2(terminal.sudo_password)),
5003
+ envKey: "SUDO_PASSWORD",
5004
+ envPath
5005
+ },
4920
5006
  toolsets: {
4921
5007
  items: PROFILE_PERMISSION_TOOLSETS.map((toolset) => {
4922
5008
  const configState = readToolsetConfigState(toolset.key, config, env);
@@ -5119,6 +5205,15 @@ function normalizeCronApprovalMode(value) {
5119
5205
  }
5120
5206
  throw new Error("approvals.cron_mode must be deny or approve");
5121
5207
  }
5208
+ function normalizeSudoPassword(value) {
5209
+ if (!value) {
5210
+ throw new Error("sudo.password must be non-empty");
5211
+ }
5212
+ if (value.includes("\n") || value.includes("\r") || value.includes("\0")) {
5213
+ throw new Error("sudo.password must not contain line breaks");
5214
+ }
5215
+ return value;
5216
+ }
5122
5217
  function normalizeTerminalBackend(value) {
5123
5218
  const backend = value.trim().toLowerCase();
5124
5219
  if (TERMINAL_BACKENDS.has(backend)) {
@@ -5876,7 +5971,7 @@ async function readHermesApiServerEnvOverrides(profileName) {
5876
5971
  };
5877
5972
  }
5878
5973
  async function readHermesEnvFile(profileName) {
5879
- const envPath = path3.join(resolveHermesProfileDir(profileName), ".env");
5974
+ const envPath = resolveHermesEnvPath(profileName);
5880
5975
  const raw = await readFile2(envPath, "utf8").catch((error) => {
5881
5976
  if (isNodeError3(error, "ENOENT")) {
5882
5977
  return "";
@@ -5900,7 +5995,7 @@ async function readHermesEnvFile(profileName) {
5900
5995
  return values;
5901
5996
  }
5902
5997
  async function writeHermesEnvValue(profileName, key, value) {
5903
- const envPath = path3.join(resolveHermesProfileDir(profileName), ".env");
5998
+ const envPath = resolveHermesEnvPath(profileName);
5904
5999
  const existingRaw = await readFile2(envPath, "utf8").catch(
5905
6000
  (error) => {
5906
6001
  if (isNodeError3(error, "ENOENT")) {
@@ -5935,8 +6030,32 @@ async function writeHermesEnvValue(profileName, key, value) {
5935
6030
  }
5936
6031
  await atomicWriteFilePreservingMetadata(envPath, nextRaw);
5937
6032
  }
6033
+ async function deleteHermesEnvValue(profileName, key) {
6034
+ const envPath = resolveHermesEnvPath(profileName);
6035
+ const raw = await readFile2(envPath, "utf8").catch((error) => {
6036
+ if (isNodeError3(error, "ENOENT")) {
6037
+ return "";
6038
+ }
6039
+ throw error;
6040
+ });
6041
+ if (!raw) {
6042
+ return false;
6043
+ }
6044
+ const keyPattern = new RegExp(`^(?:export\\s+)?${escapeRegExp(key)}=`, "u");
6045
+ const lines = raw.split(/\r?\n/u);
6046
+ const nextLines = lines.filter((line) => !keyPattern.test(line.trim()));
6047
+ const nextRaw = nextLines.join("\n").replace(/\n*$/u, "\n");
6048
+ if (nextRaw === raw) {
6049
+ return false;
6050
+ }
6051
+ await atomicWriteFilePreservingMetadata(`${envPath}.bak.${Date.now()}`, raw, {
6052
+ metadataSourcePath: envPath
6053
+ });
6054
+ await atomicWriteFilePreservingMetadata(envPath, nextRaw);
6055
+ return true;
6056
+ }
5938
6057
  async function writeHermesApiServerEnv(profileName, config, options = {}) {
5939
- const envPath = path3.join(resolveHermesProfileDir(profileName), ".env");
6058
+ const envPath = resolveHermesEnvPath(profileName);
5940
6059
  const existingRaw = await readFile2(envPath, "utf8").catch(
5941
6060
  (error) => {
5942
6061
  if (isNodeError3(error, "ENOENT")) {
@@ -5960,7 +6079,7 @@ async function writeHermesApiServerEnv(profileName, config, options = {}) {
5960
6079
  );
5961
6080
  }
5962
6081
  async function writeHermesEnvValues(profileName, values, existingRaw) {
5963
- const envPath = path3.join(resolveHermesProfileDir(profileName), ".env");
6082
+ const envPath = resolveHermesEnvPath(profileName);
5964
6083
  const raw = existingRaw ?? await readFile2(envPath, "utf8").catch((error) => {
5965
6084
  if (isNodeError3(error, "ENOENT")) {
5966
6085
  return "";
@@ -6454,7 +6573,7 @@ function isConversationMissingError(error) {
6454
6573
  }
6455
6574
 
6456
6575
  // src/constants.ts
6457
- var LINK_VERSION = "0.7.5-beta.0";
6576
+ var LINK_VERSION = "0.7.6";
6458
6577
  var LINK_COMMAND = "hermeslink";
6459
6578
  var LINK_DEFAULT_PORT = 52379;
6460
6579
  var LINK_RUNTIME_DIR_NAME = ".hermeslink";
@@ -25802,7 +25921,9 @@ function registerModelConfigRoutes(router, options) {
25802
25921
  const body = await readJsonBody(ctx.req);
25803
25922
  try {
25804
25923
  const result = await saveHermesModelConfig(readModelConfigInput(body));
25805
- ctx.body = shouldReloadGatewayAfterModelConfigChange(body) ? await reloadGatewayAfterModelConfigChange(result, {
25924
+ ctx.body = shouldReloadGatewayAfterModelConfigChange(body, {
25925
+ defaultReload: true
25926
+ }) ? await reloadGatewayAfterModelConfigChange(result, {
25806
25927
  paths,
25807
25928
  logger
25808
25929
  }) : markModelConfigAppliedWithoutGatewayReload(result);
@@ -25848,7 +25969,9 @@ function registerModelConfigRoutes(router, options) {
25848
25969
  readModelConfigInput(body),
25849
25970
  ctx.params.name
25850
25971
  );
25851
- ctx.body = shouldReloadGatewayAfterModelConfigChange(body) ? await reloadGatewayAfterProfileModelConfigChange(result, {
25972
+ ctx.body = shouldReloadGatewayAfterModelConfigChange(body, {
25973
+ defaultReload: true
25974
+ }) ? await reloadGatewayAfterProfileModelConfigChange(result, {
25852
25975
  paths,
25853
25976
  logger,
25854
25977
  profileName: ctx.params.name
@@ -26001,15 +26124,20 @@ function readModelConfigImportInput(body) {
26001
26124
  setDefault: readBoolean3(body.set_default ?? body.setDefault)
26002
26125
  };
26003
26126
  }
26004
- function shouldReloadGatewayAfterModelConfigChange(body) {
26005
- const explicit = readBoolean3(body.reload_gateway ?? body.reloadGateway) ?? (readBoolean3(body.skip_gateway_reload ?? body.skipGatewayReload) === true ? false : void 0);
26006
- return explicit ?? false;
26127
+ function shouldReloadGatewayAfterModelConfigChange(body, options = {}) {
26128
+ if (readBoolean3(body.skip_gateway_reload ?? body.skipGatewayReload) === true) {
26129
+ return false;
26130
+ }
26131
+ if (readBoolean3(body.reload_gateway ?? body.reloadGateway) === true) {
26132
+ return true;
26133
+ }
26134
+ return options.defaultReload === true;
26007
26135
  }
26008
26136
  function markModelConfigAppliedWithoutGatewayReload(result) {
26009
26137
  return {
26010
26138
  ...result,
26011
26139
  requiresGatewayReload: false,
26012
- restartHint: "\u6A21\u578B\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002\u65B0\u7684 Run \u4F1A\u76F4\u63A5\u8BFB\u53D6\u6700\u65B0\u914D\u7F6E\uFF0C\u65E0\u9700\u91CD\u8F7D Hermes Gateway\u3002"
26140
+ restartHint: "\u6A21\u578B\u914D\u7F6E\u5DF2\u4FDD\u5B58\uFF0C\u5DF2\u6309\u8BF7\u6C42\u8DF3\u8FC7 Hermes Gateway \u91CD\u8F7D\u3002\u82E5\u521A\u4FEE\u6539 API Key\u3001Base URL \u6216 API Mode\uFF0C\u8BF7\u624B\u52A8\u91CD\u8F7D Gateway \u540E\u518D\u5F00\u59CB\u65B0\u7684 Run\u3002"
26013
26141
  };
26014
26142
  }
26015
26143
  function toModelConfigHttpError(error) {
@@ -27310,6 +27438,17 @@ function readProfilePermissionsInput(body) {
27310
27438
  )
27311
27439
  };
27312
27440
  }
27441
+ const sudo = readOptionalObject(body, "sudo");
27442
+ if (sudo) {
27443
+ const clear = readBoolean3(sudo.clear ?? sudo.remove ?? sudo.delete);
27444
+ const sudoInput = {
27445
+ password: readRawString(sudo, "password") ?? readRawString(sudo, "sudo_password") ?? readRawString(sudo, "sudoPassword") ?? void 0,
27446
+ clear: clear === true ? true : void 0
27447
+ };
27448
+ if (sudoInput.password !== void 0 || sudoInput.clear !== void 0) {
27449
+ input.sudo = sudoInput;
27450
+ }
27451
+ }
27313
27452
  const toolsets = readOptionalObject(body, "toolsets");
27314
27453
  if (toolsets) {
27315
27454
  input.toolsets = {
@@ -27343,6 +27482,10 @@ function readOptionalObject(body, key) {
27343
27482
  }
27344
27483
  return value;
27345
27484
  }
27485
+ function readRawString(body, key) {
27486
+ const value = body[key];
27487
+ return typeof value === "string" ? value : null;
27488
+ }
27346
27489
  function readStringListValue(value, field) {
27347
27490
  if (value === void 0) {
27348
27491
  return null;
package/dist/cli/index.js CHANGED
@@ -53,7 +53,7 @@ import {
53
53
  stopDaemonProcess,
54
54
  summarizeUsageProbeEnsure,
55
55
  translate
56
- } from "../chunk-E7KAHPLU.js";
56
+ } from "../chunk-P54DBGLE.js";
57
57
 
58
58
  // src/cli/index.ts
59
59
  import { Command } from "commander";
package/dist/http/app.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createApp
3
- } from "../chunk-E7KAHPLU.js";
3
+ } from "../chunk-P54DBGLE.js";
4
4
  export {
5
5
  createApp
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hermespilot/link",
3
- "version": "0.7.5-beta.0",
3
+ "version": "0.7.6",
4
4
  "private": false,
5
5
  "description": "Hermes Link companion service and CLI for connecting hermes-agent through HermesPilot",
6
6
  "license": "MIT",