@oneciel-ai/claude-any 0.1.38 → 0.1.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,7 +48,7 @@ arguments through unchanged.
48
48
 
49
49
  Credits: One Ciel LLC
50
50
 
51
- Current version: `0.1.38`
51
+ Current version: `0.1.39`
52
52
 
53
53
  ## Why This Exists
54
54
 
@@ -381,6 +381,15 @@ steps under that larger model's supervision.
381
381
 
382
382
  ## Changelog
383
383
 
384
+ ### 0.1.39
385
+
386
+ - **Menu input fixes**: restores terminal line/echo mode before text or number
387
+ prompts, so typed numeric values are visible in the prelaunch UI.
388
+ - **Safer numeric validation**: invalid numeric option input now shows an
389
+ inline message instead of crashing the menu.
390
+ - **Preset visibility**: applied presets report the effective context, reserve,
391
+ output, and timeout values.
392
+
384
393
  ### 0.1.38
385
394
 
386
395
  - **User-selected context windows**: removes the NVIDIA hosted 32K safety cap.
package/claude_any.py CHANGED
@@ -85,7 +85,7 @@ PROVIDER_LABELS = {
85
85
  "self-hosted-nim": "Self Hosted NIM",
86
86
  }
87
87
  APP_NAME = "Claude Any"
88
- VERSION = "0.1.38"
88
+ VERSION = "0.1.39"
89
89
  CREDITS = "Credits: One Ciel LLC"
90
90
 
91
91
  LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
@@ -6282,16 +6282,38 @@ def apply_llm_preset_to_provider(provider: str, pcfg: dict[str, Any], preset_id:
6282
6282
  f"{ui_text('apply_preset', lang)}: {label}",
6283
6283
  f"Provider: {provider}; {ui_text('model_family', lang)}: {model_family_text(family, lang)}",
6284
6284
  ]
6285
- if provider in ("vllm", "self-hosted-nim"):
6286
- server_limit = upstream_model_context_limit(provider, pcfg)
6287
- if server_limit:
6288
- lines.append(f"Server max_model_len: {server_limit}")
6289
- if preset_id in ("long-context-65k", "large-output") and server_limit < 65536:
6290
- lines.append("Long-context preset requires restarting the server with --max-model-len 65536 or higher.")
6291
- lines.append("Client settings were capped to the server-reported context length.")
6292
- elif preset_id in ("long-context-65k", "large-output"):
6293
- lines.append("Could not verify server max_model_len; vLLM/NIM must be started with a matching context limit.")
6294
- return lines
6285
+ if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
6286
+ server_limit = upstream_model_context_limit(provider, pcfg)
6287
+ if server_limit:
6288
+ lines.append(f"Server max_model_len: {server_limit}")
6289
+ if preset_id in ("long-context-65k", "large-output") and server_limit < 65536:
6290
+ lines.append("Long-context preset requires restarting the server with --max-model-len 65536 or higher.")
6291
+ lines.append("Client settings were capped to the server-reported context length.")
6292
+ elif preset_id in ("long-context-65k", "large-output"):
6293
+ lines.append("Could not verify server max_model_len; vLLM/NIM must be started with a matching context limit.")
6294
+ if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
6295
+ lines.append(
6296
+ "Applied options: "
6297
+ f"context_window={pcfg.get('context_window', 'default')}, "
6298
+ f"reserve={pcfg.get('context_reserve_tokens', 'default')}, "
6299
+ f"max_output_tokens={pcfg.get('max_output_tokens', 'default')}, "
6300
+ f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
6301
+ )
6302
+ elif provider in ("ollama", "ollama-cloud"):
6303
+ opts = ollama_extra_options(pcfg)
6304
+ lines.append(
6305
+ "Applied options: "
6306
+ f"num_ctx={ollama_num_ctx_status(pcfg)}, "
6307
+ f"num_predict={opts.get('num_predict', 'default')}, "
6308
+ f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
6309
+ )
6310
+ elif provider == "anthropic":
6311
+ lines.append(
6312
+ "Applied options: "
6313
+ f"max_output_tokens={pcfg.get('max_output_tokens', 'default')}, "
6314
+ f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
6315
+ )
6316
+ return lines
6295
6317
 
6296
6318
 
6297
6319
  def apply_llm_preset_config(provider: str, preset_id: str) -> list[str]:
@@ -6489,9 +6511,9 @@ def llm_option_panel_rows(provider: str, pcfg: dict[str, Any], lang: str | None
6489
6511
  add("Rate limit RPM", "rate_limit_rpm", pcfg.get("rate_limit_rpm", 40))
6490
6512
  add("Rate limit status", "rate_limit_status", "on" if bool(pcfg.get("rate_limit_status", True)) else "off")
6491
6513
  else:
6492
- if provider in ("vllm", "self-hosted-nim"):
6493
- add("Context window", "context_window", pcfg.get("context_window", "default"))
6494
- add("Context reserve", "context_reserve_tokens", pcfg.get("context_reserve_tokens", "default"))
6514
+ if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
6515
+ add("Context window", "context_window", pcfg.get("context_window", "default"))
6516
+ add("Context reserve", "context_reserve_tokens", pcfg.get("context_reserve_tokens", "default"))
6495
6517
  add("Max output tokens", "max_output_tokens", pcfg.get("max_output_tokens", "default"))
6496
6518
  if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
6497
6519
  add("Timeout ms", "request_timeout_ms", pcfg.get("request_timeout_ms", "default"))
@@ -6532,13 +6554,38 @@ def llm_option_prompt_default(provider: str, pcfg: dict[str, Any], key: str) ->
6532
6554
  return "" if value is None else str(value)
6533
6555
 
6534
6556
 
6535
- def set_llm_option_config(provider: str, key: str, raw_value: str) -> list[str]:
6557
+ def set_llm_option_config(provider: str, key: str, raw_value: str) -> list[str]:
6536
6558
  cfg = load_config()
6537
6559
  pcfg = cfg["providers"][provider]
6538
- value = raw_value.strip()
6539
- if not value:
6540
- return ["Option unchanged."]
6541
- clear_words = ("default", "unset", "none", "null")
6560
+ value = raw_value.strip()
6561
+ if not value:
6562
+ return ["Option unchanged."]
6563
+ numeric_keys = {
6564
+ "context_window",
6565
+ "context",
6566
+ "max_model_len",
6567
+ "context_reserve_tokens",
6568
+ "reserve",
6569
+ "max_output_tokens",
6570
+ "max_tokens",
6571
+ "maxtoken",
6572
+ "max_token",
6573
+ "num_ctx_min",
6574
+ "num_ctx_max",
6575
+ "num_predict",
6576
+ "timeout",
6577
+ "timeout_ms",
6578
+ "request_timeout",
6579
+ "request_timeout_ms",
6580
+ "rate_limit",
6581
+ "rate_limit_rpm",
6582
+ "rpm",
6583
+ "top_k",
6584
+ }
6585
+ if key in numeric_keys and value.lower() not in ("default", "unset", "none", "null", "0"):
6586
+ if not re.fullmatch(r"\d+", value):
6587
+ return [f"{key}: enter digits only, or use default/unset to clear."]
6588
+ clear_words = ("default", "unset", "none", "null")
6542
6589
  token = f"unset:{key}" if value.lower() in clear_words else f"{key}={value}"
6543
6590
  if provider in ("ollama", "ollama-cloud"):
6544
6591
  apply_ollama_option(pcfg, token)
@@ -8116,14 +8163,16 @@ def render_prelaunch_screen(
8116
8163
  return False
8117
8164
 
8118
8165
 
8119
- def prompt_menu_value(prompt: str, default: str = "", secret: bool = False) -> str:
8120
- label = f"{prompt}"
8121
- if default:
8122
- label += f" [{default}]"
8123
- label += ": "
8124
- if sys.stdout.isatty():
8125
- sys.stdout.write("\033[?25h")
8126
- sys.stdout.flush()
8166
+ def prompt_menu_value(prompt: str, default: str = "", secret: bool = False, restore_tty: Callable[[], None] | None = None, raw_tty: Callable[[], None] | None = None) -> str:
8167
+ label = f"{prompt}"
8168
+ if default:
8169
+ label += f" [{default}]"
8170
+ label += ": "
8171
+ if restore_tty:
8172
+ restore_tty()
8173
+ if sys.stdout.isatty():
8174
+ sys.stdout.write("\033[?25h")
8175
+ sys.stdout.flush()
8127
8176
  sys.stdout.write("\n" + ansi(label, "1;38;5;208"))
8128
8177
  sys.stdout.flush()
8129
8178
  try:
@@ -8131,12 +8180,14 @@ def prompt_menu_value(prompt: str, default: str = "", secret: bool = False) -> s
8131
8180
  value = getpass.getpass("")
8132
8181
  else:
8133
8182
  value = input()
8134
- finally:
8135
- if sys.stdout.isatty():
8136
- sys.stdout.write("\033[?25l")
8137
- sys.stdout.flush()
8138
- value = value.strip()
8139
- return value or default
8183
+ finally:
8184
+ if sys.stdout.isatty():
8185
+ sys.stdout.write("\033[?25l")
8186
+ sys.stdout.flush()
8187
+ if raw_tty:
8188
+ raw_tty()
8189
+ value = value.strip()
8190
+ return value or default
8140
8191
 
8141
8192
 
8142
8193
  def portable_provider_menu() -> int:
@@ -8168,22 +8219,23 @@ def portable_prelaunch_menu() -> int:
8168
8219
  enable_ansi()
8169
8220
  main_idx = 7 if settings_ready_except_api_key() else 0
8170
8221
  panel: str | None = None
8171
- panel_idx = 0
8172
- panel_rows: list[str] = []
8173
- panel_values: list[str] = []
8222
+ panel_idx = 0
8223
+ panel_rows: list[str] = []
8224
+ panel_values: list[str] = []
8225
+ panel_last_idx: dict[str, int] = {}
8174
8226
  checks = preflight_lines()
8175
8227
  messages: list[str] = []
8176
8228
  first_render = True
8177
8229
 
8178
- def open_panel(name: str) -> None:
8179
- nonlocal panel, panel_idx, panel_rows, panel_values, messages, first_render
8180
- cfg = load_config()
8181
- provider, pcfg = get_current_provider(cfg)
8182
- panel = name
8183
- panel_idx = 0
8184
- if name == "language":
8185
- panel_rows, panel_values = language_panel_rows(cfg)
8186
- panel_idx = panel_values.index(cfg.get("language", "en"))
8230
+ def open_panel(name: str) -> None:
8231
+ nonlocal panel, panel_idx, panel_rows, panel_values, messages, first_render
8232
+ cfg = load_config()
8233
+ provider, pcfg = get_current_provider(cfg)
8234
+ panel = name
8235
+ panel_idx = panel_last_idx.get(name, 0)
8236
+ if name == "language":
8237
+ panel_rows, panel_values = language_panel_rows(cfg)
8238
+ panel_idx = panel_values.index(cfg.get("language", "en"))
8187
8239
  elif name == "provider":
8188
8240
  panel_rows, panel_values = provider_panel_rows(cfg)
8189
8241
  panel_idx = panel_values.index(provider)
@@ -8205,15 +8257,19 @@ def portable_prelaunch_menu() -> int:
8205
8257
  panel_rows, panel_values = [f"Advisor model list failed: {type(exc).__name__}: {exc}", "+ Custom advisor model id..."], []
8206
8258
  elif name == "test":
8207
8259
  panel_rows, panel_values = ["Run compatibility test", "Back"], ["run", "back"]
8208
- elif name == "options":
8209
- panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8210
- elif name == "preset":
8211
- panel_rows, panel_values = llm_preset_panel_rows(provider, pcfg, cfg.get("language", "en"))
8212
-
8213
- def close_panel(next_idx: int | None = None) -> None:
8214
- nonlocal panel, panel_idx, panel_rows, panel_values, main_idx
8215
- panel = None
8216
- panel_idx = 0
8260
+ elif name == "options":
8261
+ panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8262
+ elif name == "preset":
8263
+ panel_rows, panel_values = llm_preset_panel_rows(provider, pcfg, cfg.get("language", "en"))
8264
+ if panel_rows:
8265
+ panel_idx = max(0, min(panel_idx, len(panel_rows) - 1))
8266
+
8267
+ def close_panel(next_idx: int | None = None) -> None:
8268
+ nonlocal panel, panel_idx, panel_rows, panel_values, main_idx
8269
+ if panel:
8270
+ panel_last_idx[panel] = panel_idx
8271
+ panel = None
8272
+ panel_idx = 0
8217
8273
  panel_rows = []
8218
8274
  panel_values = []
8219
8275
  if next_idx is not None:
@@ -8236,20 +8292,43 @@ def portable_prelaunch_menu() -> int:
8236
8292
  termios.tcsetattr(fd, termios.TCSANOW, new)
8237
8293
  except Exception:
8238
8294
  fd = -1
8239
- if sys.stdout.isatty():
8240
- sys.stdout.write("\033[?25l")
8241
- sys.stdout.flush()
8242
- try:
8295
+ if sys.stdout.isatty():
8296
+ sys.stdout.write("\033[?25l")
8297
+ sys.stdout.flush()
8298
+ def restore_line_mode() -> None:
8299
+ if old_settings is not None and fd >= 0:
8300
+ try:
8301
+ import termios
8302
+ termios.tcsetattr(fd, termios.TCSANOW, old_settings)
8303
+ except Exception:
8304
+ pass
8305
+
8306
+ def restore_raw_mode() -> None:
8307
+ if old_settings is not None and fd >= 0:
8308
+ try:
8309
+ import termios
8310
+ new = termios.tcgetattr(fd)
8311
+ new[3] = new[3] & ~(termios.ECHO | termios.ICANON)
8312
+ new[6][termios.VMIN] = 1
8313
+ new[6][termios.VTIME] = 0
8314
+ termios.tcsetattr(fd, termios.TCSANOW, new)
8315
+ except Exception:
8316
+ pass
8317
+
8318
+ try:
8243
8319
  while True:
8244
8320
  first_render = render_prelaunch_screen(main_idx, panel, panel_idx, panel_rows, checks, messages, first_render)
8245
8321
  key = read_menu_key(fd) if fd >= 0 else read_menu_key()
8246
- if panel:
8247
- if key in ("up", "k"):
8248
- panel_idx = (panel_idx - 1) % max(1, len(panel_rows))
8249
- continue
8250
- if key in ("down", "j"):
8251
- panel_idx = (panel_idx + 1) % max(1, len(panel_rows))
8252
- continue
8322
+ if panel:
8323
+ panel_name = panel
8324
+ if key in ("up", "k"):
8325
+ panel_idx = (panel_idx - 1) % max(1, len(panel_rows))
8326
+ panel_last_idx[panel_name] = panel_idx
8327
+ continue
8328
+ if key in ("down", "j"):
8329
+ panel_idx = (panel_idx + 1) % max(1, len(panel_rows))
8330
+ panel_last_idx[panel_name] = panel_idx
8331
+ continue
8253
8332
  if key in ("esc", "left", "q"):
8254
8333
  close_panel()
8255
8334
  continue
@@ -8274,7 +8353,7 @@ def portable_prelaunch_menu() -> int:
8274
8353
  close_panel()
8275
8354
  continue
8276
8355
  if value == "__custom__" or panel_idx >= len(panel_values):
8277
- model_value = prompt_menu_value("Model id or alias")
8356
+ model_value = prompt_menu_value("Model id or alias", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8278
8357
  else:
8279
8358
  model_value = value
8280
8359
  if model_value:
@@ -8286,7 +8365,7 @@ def portable_prelaunch_menu() -> int:
8286
8365
  close_panel()
8287
8366
  continue
8288
8367
  if value == "__custom__" or panel_idx >= len(panel_values):
8289
- advisor_value = prompt_menu_value("Advisor model id", "deepseek-v4-pro")
8368
+ advisor_value = prompt_menu_value("Advisor model id", "deepseek-v4-pro", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8290
8369
  else:
8291
8370
  advisor_value = value
8292
8371
  messages = set_advisor_model_config(advisor_value)
@@ -8296,7 +8375,7 @@ def portable_prelaunch_menu() -> int:
8296
8375
  if value == "back":
8297
8376
  close_panel()
8298
8377
  elif value == "input":
8299
- key_value = prompt_menu_value(f"API key for {provider}", secret=True)
8378
+ key_value = prompt_menu_value(f"API key for {provider}", secret=True, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8300
8379
  if key_value:
8301
8380
  messages = store_api_key_config(provider, key_value)
8302
8381
  refresh_checks()
@@ -8307,7 +8386,7 @@ def portable_prelaunch_menu() -> int:
8307
8386
  "nvidia-hosted": "NVIDIA_API_KEY",
8308
8387
  "ollama-cloud": "OLLAMA_API_KEY",
8309
8388
  }.get(provider, "API_KEY")
8310
- env_name = prompt_menu_value("Environment variable name", default_env)
8389
+ env_name = prompt_menu_value("Environment variable name", default_env, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8311
8390
  key_value = os.environ.get(env_name, "").strip()
8312
8391
  if key_value:
8313
8392
  messages = store_api_key_config(provider, key_value)
@@ -8320,7 +8399,7 @@ def portable_prelaunch_menu() -> int:
8320
8399
  if not key_value:
8321
8400
  messages = ["Clipboard did not contain readable text."]
8322
8401
  else:
8323
- confirm = prompt_menu_value(f"Clipboard contains {mask_secret(key_value)}. Store it? y/N")
8402
+ confirm = prompt_menu_value(f"Clipboard contains {mask_secret(key_value)}. Store it? y/N", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8324
8403
  if confirm.lower().startswith("y"):
8325
8404
  messages = store_api_key_config(provider, key_value)
8326
8405
  else:
@@ -8336,7 +8415,7 @@ def portable_prelaunch_menu() -> int:
8336
8415
  close_panel(4)
8337
8416
  elif value == "edit":
8338
8417
  default = pcfg.get("base_url") or default_base_url(provider)
8339
- url = prompt_menu_value(f"Base URL for {provider}", default)
8418
+ url = prompt_menu_value(f"Base URL for {provider}", default, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8340
8419
  if url:
8341
8420
  messages = set_base_url_config(provider, url)
8342
8421
  refresh_checks()
@@ -8365,21 +8444,27 @@ def portable_prelaunch_menu() -> int:
8365
8444
  messages = set_llm_option_config(provider, value, "false" if current else "true")
8366
8445
  except Exception as exc:
8367
8446
  messages = [f"Option update failed: {type(exc).__name__}: {exc}"]
8368
- refresh_checks()
8369
- cfg = load_config()
8370
- provider, pcfg = get_current_provider(cfg)
8371
- panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8372
- else:
8373
- default = llm_option_prompt_default(provider, pcfg, value)
8374
- entered = prompt_menu_value(f"{value} for {provider} (default/unset clears)", default)
8447
+ refresh_checks()
8448
+ cfg = load_config()
8449
+ provider, pcfg = get_current_provider(cfg)
8450
+ old_idx = panel_idx
8451
+ panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8452
+ panel_idx = max(0, min(old_idx, len(panel_rows) - 1))
8453
+ panel_last_idx["options"] = panel_idx
8454
+ else:
8455
+ default = llm_option_prompt_default(provider, pcfg, value)
8456
+ entered = prompt_menu_value(f"{value} for {provider} (default/unset clears)", default, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
8375
8457
  try:
8376
8458
  messages = set_llm_option_config(provider, value, entered)
8377
8459
  except Exception as exc:
8378
8460
  messages = [f"Option update failed: {type(exc).__name__}: {exc}"]
8379
- refresh_checks()
8380
- cfg = load_config()
8381
- provider, pcfg = get_current_provider(cfg)
8382
- panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8461
+ refresh_checks()
8462
+ cfg = load_config()
8463
+ provider, pcfg = get_current_provider(cfg)
8464
+ old_idx = panel_idx
8465
+ panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8466
+ panel_idx = max(0, min(old_idx, len(panel_rows) - 1))
8467
+ panel_last_idx["options"] = panel_idx
8383
8468
  elif panel == "preset":
8384
8469
  if value == "back":
8385
8470
  open_panel("options")
@@ -8391,12 +8476,14 @@ def portable_prelaunch_menu() -> int:
8391
8476
  except Exception as exc:
8392
8477
  messages = [f"Preset failed: {type(exc).__name__}: {exc}"]
8393
8478
  refresh_checks()
8394
- cfg = load_config()
8395
- provider, pcfg = get_current_provider(cfg)
8396
- panel = "options"
8397
- panel_idx = 0
8398
- panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8399
- continue
8479
+ cfg = load_config()
8480
+ provider, pcfg = get_current_provider(cfg)
8481
+ panel = "options"
8482
+ panel_idx = panel_last_idx.get("options", 0)
8483
+ panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
8484
+ panel_idx = max(0, min(panel_idx, len(panel_rows) - 1))
8485
+ panel_last_idx["options"] = panel_idx
8486
+ continue
8400
8487
 
8401
8488
  if key in ("up", "k"):
8402
8489
  main_idx = (main_idx - 1) % 10
package/docs/README.ja.md CHANGED
@@ -47,7 +47,7 @@ vLLM、NVIDIA hosted、self-hosted NIM を選択し、通常の Claude Code 引
47
47
 
48
48
  Credits: One Ciel LLC
49
49
 
50
- 現在のバージョン: `0.1.38`
50
+ 現在のバージョン: `0.1.39`
51
51
 
52
52
  ## 作られた理由
53
53
 
@@ -351,6 +351,15 @@ Windows/Linux 管理、クリーンアップスクリプト、定期的なセキ
351
351
 
352
352
  ## 変更履歴
353
353
 
354
+ ### 0.1.39
355
+
356
+ - **メニュー入力修正**: テキスト/数字プロンプトの前に terminal line/echo mode を
357
+ 復元し、prelaunch UI で入力した数字が見えるようにしました。
358
+ - **数字検証の安定化**: 数字オプションへ不正な文字を入れてもメニューが
359
+ クラッシュせず、案内メッセージを表示します。
360
+ - **プリセット表示改善**: preset 適用後に実際の context、reserve、output、
361
+ timeout 値をメッセージに表示します。
362
+
354
363
  ### 0.1.38
355
364
 
356
365
  - **ユーザー選択の context window を優先**: NVIDIA hosted の 32K safety cap を
package/docs/README.ko.md CHANGED
@@ -47,7 +47,7 @@ NVIDIA hosted, self-hosted NIM을 선택하고, Claude Code의 일반 인자는
47
47
 
48
48
  Credits: One Ciel LLC
49
49
 
50
- 현재 버전: `0.1.38`
50
+ 현재 버전: `0.1.39`
51
51
 
52
52
  ## 왜 만들었나
53
53
 
@@ -351,6 +351,15 @@ Windows 이벤트 로그 리뷰, 바이러스/랜섬웨어 침입 시도 정리,
351
351
 
352
352
  ## 변경 이력
353
353
 
354
+ ### 0.1.39
355
+
356
+ - **메뉴 입력 수정**: 텍스트/숫자 프롬프트 전에 터미널 line/echo 모드를 복구하여
357
+ prelaunch UI에서 입력한 숫자가 보이게 했습니다.
358
+ - **숫자 검증 안정화**: 숫자 옵션에 잘못된 문자를 넣어도 메뉴가 크래시되지 않고
359
+ 안내 메시지를 표시합니다.
360
+ - **프리셋 표시 개선**: preset 적용 후 실제 context, reserve, output, timeout 값을
361
+ 메시지에 표시합니다.
362
+
354
363
  ### 0.1.38
355
364
 
356
365
  - **사용자 선택 context window 우선**: NVIDIA hosted 32K safety cap을 제거했습니다.
package/docs/README.zh.md CHANGED
@@ -47,7 +47,7 @@ NIM,并把普通 Claude Code 参数原样传递。
47
47
 
48
48
  Credits: One Ciel LLC
49
49
 
50
- 当前版本: `0.1.38`
50
+ 当前版本: `0.1.39`
51
51
 
52
52
  ## 为什么存在
53
53
 
@@ -337,6 +337,14 @@ Hermes 格式模型或部分较旧的 Qwen tool template。
337
337
 
338
338
  ## 更新日志
339
339
 
340
+ ### 0.1.39
341
+
342
+ - **菜单输入修复**:在文本/数字提示前恢复 terminal line/echo mode,
343
+ prelaunch UI 中输入的数字现在可见。
344
+ - **数字校验更稳**:数字选项输入非法字符时不再让菜单崩溃,而是显示提示消息。
345
+ - **Preset 可见性**:应用 preset 后会显示实际 context、reserve、output、
346
+ timeout 值。
347
+
340
348
  ### 0.1.38
341
349
 
342
350
  - **优先使用用户选择的 context window**:移除 NVIDIA hosted 的 32K safety cap。
package/docs/manual.md CHANGED
@@ -10,7 +10,7 @@ Code starts, while passing normal Claude Code arguments through unchanged.
10
10
 
11
11
  Credits: One Ciel LLC
12
12
 
13
- Current version: `0.1.38`
13
+ Current version: `0.1.39`
14
14
 
15
15
  ## Install
16
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneciel-ai/claude-any",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "Claude Code provider selector for Anthropic, Ollama, Ollama Cloud, vLLM, NVIDIA hosted, and self-hosted NIM.",
5
5
  "license": "MIT",
6
6
  "author": "One Ciel LLC",