@oneciel-ai/claude-any 0.1.44 → 0.1.45

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.44`
51
+ Current version: `0.1.45`
52
52
 
53
53
  ## Why This Exists
54
54
 
@@ -381,6 +381,13 @@ steps under that larger model's supervision.
381
381
 
382
382
  ## Changelog
383
383
 
384
+ ### 0.1.45
385
+
386
+ - **Interactive npm self-update check**: npm-installed `claude-any` now checks
387
+ the npm registry before launch. If a newer version exists, it asks whether to
388
+ run `npm update -g @oneciel-ai/claude-any`, then restarts into the updated
389
+ version. Non-interactive/headless runs are not interrupted.
390
+
384
391
  ### 0.1.44
385
392
 
386
393
  - **Statusline split**: turning Rate Limit status off now hides only RPM,
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.44"
88
+ VERSION = "0.1.45"
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}
@@ -8727,9 +8727,9 @@ def write_duckduckgo_mcp_config(cfg: dict[str, Any]) -> Path:
8727
8727
  return path
8728
8728
 
8729
8729
 
8730
- def run_claude_update_check(claude: str, enabled: bool = True) -> None:
8731
- if not enabled:
8732
- return
8730
+ def run_claude_update_check(claude: str, enabled: bool = True) -> None:
8731
+ if not enabled:
8732
+ return
8733
8733
  if os.environ.get("CLAUDE_ANY_SKIP_CLAUDE_UPDATE") == "1":
8734
8734
  return
8735
8735
  print("Checking Claude Code update before launch...", flush=True)
@@ -8754,10 +8754,96 @@ def run_claude_update_check(claude: str, enabled: bool = True) -> None:
8754
8754
  out = (p.stdout or "").strip()
8755
8755
  if out:
8756
8756
  print(out, flush=True)
8757
- if p.returncode != 0:
8758
- print(f"Claude Code update check exited with {p.returncode}; continuing.", flush=True)
8759
-
8760
-
8757
+ if p.returncode != 0:
8758
+ print(f"Claude Code update check exited with {p.returncode}; continuing.", flush=True)
8759
+
8760
+
8761
+ def parse_version_tuple(value: str) -> tuple[int, ...]:
8762
+ parts: list[int] = []
8763
+ for item in re.split(r"[^0-9]+", value.strip()):
8764
+ if item:
8765
+ parts.append(int(item))
8766
+ return tuple(parts)
8767
+
8768
+
8769
+ def version_newer(latest: str, current: str) -> bool:
8770
+ left = list(parse_version_tuple(latest))
8771
+ right = list(parse_version_tuple(current))
8772
+ size = max(len(left), len(right), 1)
8773
+ left.extend([0] * (size - len(left)))
8774
+ right.extend([0] * (size - len(right)))
8775
+ return tuple(left) > tuple(right)
8776
+
8777
+
8778
+ def running_from_npm_package() -> bool:
8779
+ if os.environ.get("CLAUDE_ANY_NPM_MODE") is not None:
8780
+ return True
8781
+ path = str(Path(__file__).resolve()).replace("\\", "/")
8782
+ return "/node_modules/@oneciel-ai/claude-any/" in path
8783
+
8784
+
8785
+ def run_claude_any_update_check(enabled: bool = True) -> bool:
8786
+ if not enabled:
8787
+ return False
8788
+ if os.environ.get("CLAUDE_ANY_SKIP_SELF_UPDATE") == "1":
8789
+ return False
8790
+ if env_bool(os.environ.get("CLAUDE_ANY_SELF_UPDATE_CHECK")) is False:
8791
+ return False
8792
+ if not running_from_npm_package():
8793
+ return False
8794
+ if not (sys.stdin.isatty() and sys.stdout.isatty()):
8795
+ return False
8796
+ npm = find_executable("npm")
8797
+ if not npm:
8798
+ return False
8799
+ try:
8800
+ p = subprocess.run(
8801
+ [npm, "view", "@oneciel-ai/claude-any@latest", "version"],
8802
+ text=True,
8803
+ stdout=subprocess.PIPE,
8804
+ stderr=subprocess.DEVNULL,
8805
+ timeout=8,
8806
+ )
8807
+ except Exception:
8808
+ return False
8809
+ if p.returncode != 0:
8810
+ return False
8811
+ latest = (p.stdout or "").strip().splitlines()[-1].strip() if (p.stdout or "").strip() else ""
8812
+ if not latest or not version_newer(latest, VERSION):
8813
+ return False
8814
+ print(f"Claude Any update available: {VERSION} -> {latest}", flush=True)
8815
+ answer = input("Update now with npm? [y/N] ").strip().lower()
8816
+ if answer not in ("y", "yes"):
8817
+ return False
8818
+ try:
8819
+ update = subprocess.run(
8820
+ [npm, "update", "-g", "@oneciel-ai/claude-any"],
8821
+ text=True,
8822
+ stdout=subprocess.PIPE,
8823
+ stderr=subprocess.STDOUT,
8824
+ timeout=300,
8825
+ )
8826
+ except subprocess.TimeoutExpired:
8827
+ print("Claude Any update timed out; continuing with current version.", flush=True)
8828
+ return False
8829
+ except Exception as exc:
8830
+ print(f"Claude Any update failed ({type(exc).__name__}); continuing.", flush=True)
8831
+ return False
8832
+ out = (update.stdout or "").strip()
8833
+ if out:
8834
+ print(out, flush=True)
8835
+ if update.returncode != 0:
8836
+ print(f"Claude Any update exited with {update.returncode}; continuing with current version.", flush=True)
8837
+ return False
8838
+ print("Claude Any updated. Restarting with the new version...", flush=True)
8839
+ os.environ["CLAUDE_ANY_SKIP_SELF_UPDATE"] = "1"
8840
+ try:
8841
+ os.execv(sys.executable, [sys.executable, *sys.argv])
8842
+ except Exception as exc:
8843
+ print(f"Restart failed ({type(exc).__name__}); continuing with the current process.", flush=True)
8844
+ return True
8845
+
8846
+
8761
8847
  def launch_claude(
8762
8848
  passthrough: list[str],
8763
8849
  skip_menu: bool = False,
@@ -8765,7 +8851,9 @@ def launch_claude(
8765
8851
  web_search_override: bool | None = None,
8766
8852
  disable_skills_override: bool | None = None,
8767
8853
  update_check: bool = True,
8854
+ self_update_check: bool = True,
8768
8855
  ) -> int:
8856
+ run_claude_any_update_check(enabled=self_update_check)
8769
8857
  rc = run_prelaunch_menu(passthrough, skip_menu=skip_menu, force_menu=force_menu)
8770
8858
  if rc == 10:
8771
8859
  return 0
@@ -8895,10 +8983,12 @@ Headless setup flags, namespaced to avoid Claude CLI collisions:
8895
8983
  claude-any --ca-no-web-search Disable DuckDuckGo MCP for this launch
8896
8984
  claude-any --ca-web-fetch Enable fetch MCP
8897
8985
  claude-any --ca-no-web-fetch Disable fetch MCP
8898
- claude-any --ca-disable-skills Disable Claude Code skills for this launch
8899
- claude-any --ca-enable-skills Keep Claude Code skills enabled for this launch
8900
- claude-any --ca-no-update-check Skip Claude Code update check for this launch
8901
- claude-any --ca-stop Stop router/proxy
8986
+ claude-any --ca-disable-skills Disable Claude Code skills for this launch
8987
+ claude-any --ca-enable-skills Keep Claude Code skills enabled for this launch
8988
+ claude-any --ca-no-self-update-check
8989
+ Skip Claude Any npm self-update check
8990
+ claude-any --ca-no-update-check Skip Claude Code update check for this launch
8991
+ claude-any --ca-stop Stop router/proxy
8902
8992
  claude-any -- Pass all following args directly to Claude Code
8903
8993
 
8904
8994
  Provider names: anthropic, ollama, ollama-cloud, vllm, nvidia-hosted, self-hosted-nim
@@ -8930,12 +9020,13 @@ def pop_headless_env_file_args(argv: list[str]) -> list[str]:
8930
9020
  return cleaned
8931
9021
 
8932
9022
 
8933
- def apply_headless_env_config() -> tuple[bool, bool | None, bool | None, bool | None, bool]:
9023
+ def apply_headless_env_config() -> tuple[bool, bool | None, bool | None, bool | None, bool | None, bool]:
8934
9024
  skip_menu = os.environ.get("CLAUDE_ANY_SKIP_MENU") == "1"
8935
9025
  force_menu = bool(env_bool(os.environ.get("CLAUDE_ANY_FORCE_MENU"), False))
8936
9026
  web_search_override = env_bool(os.environ.get("CLAUDE_ANY_WEB_SEARCH"))
8937
9027
  disable_skills_override = env_bool(os.environ.get("CLAUDE_ANY_DISABLE_SKILLS"))
8938
9028
  update_check_override = env_bool(os.environ.get("CLAUDE_ANY_UPDATE_CHECK"))
9029
+ self_update_check_override = env_bool(os.environ.get("CLAUDE_ANY_SELF_UPDATE_CHECK"))
8939
9030
  language = os.environ.get("CLAUDE_ANY_LANGUAGE", "").strip()
8940
9031
  if language:
8941
9032
  cmd_language(argparse.Namespace(value=language))
@@ -8999,7 +9090,7 @@ def apply_headless_env_config() -> tuple[bool, bool | None, bool | None, bool |
8999
9090
  if ollama_values:
9000
9091
  cmd_ollama_options(argparse.Namespace(values=ollama_values))
9001
9092
  skip_menu = True
9002
- return skip_menu, web_search_override, disable_skills_override, update_check_override, force_menu
9093
+ return skip_menu, web_search_override, disable_skills_override, update_check_override, self_update_check_override, force_menu
9003
9094
 
9004
9095
 
9005
9096
  def run_cli(argv: list[str]) -> int:
@@ -9093,10 +9184,13 @@ def run_cli(argv: list[str]) -> int:
9093
9184
  return 0
9094
9185
 
9095
9186
  passthrough: list[str] = []
9096
- skip_menu, web_search_override, disable_skills_override, update_check_override, force_menu = apply_headless_env_config()
9187
+ skip_menu, web_search_override, disable_skills_override, update_check_override, self_update_check_override, force_menu = apply_headless_env_config()
9097
9188
  update_check = True
9098
9189
  if update_check_override is not None:
9099
9190
  update_check = update_check_override
9191
+ self_update_check = True
9192
+ if self_update_check_override is not None:
9193
+ self_update_check = self_update_check_override
9100
9194
  i = 0
9101
9195
  while i < len(argv):
9102
9196
  arg = argv[i]
@@ -9353,10 +9447,14 @@ def run_cli(argv: list[str]) -> int:
9353
9447
  disable_skills_override = False
9354
9448
  skip_menu = True
9355
9449
  i += 1
9356
- elif arg == "--ca-no-update-check":
9357
- update_check = False
9358
- skip_menu = True
9359
- i += 1
9450
+ elif arg == "--ca-no-update-check":
9451
+ update_check = False
9452
+ skip_menu = True
9453
+ i += 1
9454
+ elif arg == "--ca-no-self-update-check":
9455
+ self_update_check = False
9456
+ skip_menu = True
9457
+ i += 1
9360
9458
  elif arg == "--ca-status":
9361
9459
  cmd_status(argparse.Namespace())
9362
9460
  return 0
@@ -9373,10 +9471,11 @@ def run_cli(argv: list[str]) -> int:
9373
9471
  passthrough,
9374
9472
  skip_menu=skip_menu,
9375
9473
  force_menu=force_menu,
9376
- web_search_override=web_search_override,
9377
- disable_skills_override=disable_skills_override,
9378
- update_check=update_check,
9379
- )
9474
+ web_search_override=web_search_override,
9475
+ disable_skills_override=disable_skills_override,
9476
+ update_check=update_check,
9477
+ self_update_check=self_update_check,
9478
+ )
9380
9479
 
9381
9480
 
9382
9481
  def cmd_cli(args: argparse.Namespace) -> None:
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.44`
50
+ 現在のバージョン: `0.1.45`
51
51
 
52
52
  ## 作られた理由
53
53
 
@@ -351,6 +351,13 @@ Windows/Linux 管理、クリーンアップスクリプト、定期的なセキ
351
351
 
352
352
  ## 変更履歴
353
353
 
354
+ ### 0.1.45
355
+
356
+ - **対話型 npm self-update check**: npm でインストールされた `claude-any` は起動前に
357
+ npm registry の最新バージョンを確認します。新しいバージョンがあれば
358
+ `npm update -g @oneciel-ai/claude-any` を実行するか確認し、更新後に新しい
359
+ バージョンで再起動します。non-interactive/headless 実行は止めません。
360
+
354
361
  ### 0.1.44
355
362
 
356
363
  - **Statusline split**: Rate Limit status を off にした場合、RPM、server-limit、
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.44`
50
+ 현재 버전: `0.1.45`
51
51
 
52
52
  ## 왜 만들었나
53
53
 
@@ -351,6 +351,13 @@ Windows 이벤트 로그 리뷰, 바이러스/랜섬웨어 침입 시도 정리,
351
351
 
352
352
  ## 변경 이력
353
353
 
354
+ ### 0.1.45
355
+
356
+ - **대화형 npm self-update check**: npm으로 설치된 `claude-any`는 실행 전 npm
357
+ registry의 최신 버전을 확인합니다. 새 버전이 있으면 `npm update -g
358
+ @oneciel-ai/claude-any` 실행 여부를 묻고, 업데이트 후 새 버전으로 재시작합니다.
359
+ non-interactive/headless 실행은 중단하지 않습니다.
360
+
354
361
  ### 0.1.44
355
362
 
356
363
  - **Statusline 분리**: Rate Limit status를 off로 바꾸면 RPM, server-limit,
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.44`
50
+ 当前版本: `0.1.45`
51
51
 
52
52
  ## 为什么存在
53
53
 
@@ -337,6 +337,13 @@ Hermes 格式模型或部分较旧的 Qwen tool template。
337
337
 
338
338
  ## 更新日志
339
339
 
340
+ ### 0.1.45
341
+
342
+ - **交互式 npm self-update check**:通过 npm 安装的 `claude-any` 会在启动前检查
343
+ npm registry 的最新版本。如果有新版本,会询问是否运行 `npm update -g
344
+ @oneciel-ai/claude-any`,更新后重新启动到新版本。non-interactive/headless
345
+ 运行不会被打断。
346
+
340
347
  ### 0.1.44
341
348
 
342
349
  - **Statusline split**:关闭 Rate Limit status 后只隐藏 RPM、server-limit 和
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.44`
13
+ Current version: `0.1.45`
14
14
 
15
15
  ## Install
16
16
 
@@ -376,6 +376,7 @@ export CLAUDE_ANY_STREAM_WORD_CHUNKING=off
376
376
  export CLAUDE_ANY_WEB_SEARCH=on
377
377
  export CLAUDE_ANY_WEB_FETCH=on
378
378
  export CLAUDE_ANY_DISABLE_SKILLS=off
379
+ export CLAUDE_ANY_SELF_UPDATE_CHECK=off
379
380
  export CLAUDE_ANY_UPDATE_CHECK=off
380
381
  claude-any -p "Reply with OK only." --output-format text
381
382
  ```
@@ -400,6 +401,7 @@ CLAUDE_ANY_STREAM_WORD_CHUNKING=off
400
401
  CLAUDE_ANY_WEB_SEARCH=on
401
402
  CLAUDE_ANY_WEB_FETCH=on
402
403
  CLAUDE_ANY_DISABLE_SKILLS=off
404
+ CLAUDE_ANY_SELF_UPDATE_CHECK=off
403
405
  CLAUDE_ANY_UPDATE_CHECK=off
404
406
  ```
405
407
 
@@ -472,6 +474,7 @@ Common Claude Any setup flags:
472
474
  | `--ca-web-search` / `--ca-no-web-search` | Force-enable or disable web-search MCP for this launch. |
473
475
  | `--ca-web-fetch` / `--ca-no-web-fetch` | Enable or disable fetch MCP for web page content. |
474
476
  | `--ca-disable-skills` / `--ca-enable-skills` | Control Claude Code skills for this launch. |
477
+ | `--ca-no-self-update-check` | Skip the Claude Any npm self-update check. |
475
478
  | `--ca-no-update-check` | Skip the Claude Code update check. |
476
479
  | `--ca-status` | Print status and exit. |
477
480
  | `--ca-stop` | Stop managed router services and exit. |
@@ -482,8 +485,13 @@ Notes for automation:
482
485
  - `--ca-api-key` and `--ca-set-api-key` are available for direct key passing,
483
486
  but prefer the environment-variable forms in shared scripts and terminals.
484
487
  - `claude-any stop` is safe to run before scripted tests to remove stale
485
- router/proxy processes.
486
- - Use `claude-any test 60 auto` for a quick readiness check and reserve
488
+ router/proxy processes.
489
+ - npm-installed interactive launches check the npm registry for a newer
490
+ Claude Any version and ask before running `npm update -g
491
+ @oneciel-ai/claude-any`. Headless/non-TTY launches are not interrupted; set
492
+ `CLAUDE_ANY_SELF_UPDATE_CHECK=off` or pass `--ca-no-self-update-check` to
493
+ disable it explicitly.
494
+ - Use `claude-any test 60 auto` for a quick readiness check and reserve
487
495
  `claude-any test 180 full` for deeper provider validation.
488
496
  - Headless flags persist in `~/.config/claude-any/config.json`, so the next
489
497
  interactive launch starts from the same provider/model settings.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneciel-ai/claude-any",
3
- "version": "0.1.44",
3
+ "version": "0.1.45",
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",