@oneciel-ai/claude-any 0.1.75 → 0.1.76

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/claude_any.py +58 -48
  2. package/package.json +1 -1
package/claude_any.py CHANGED
@@ -102,7 +102,7 @@ OFFICIAL_CHANNEL_PLUGINS = {
102
102
  "fakechat": "plugin:fakechat@claude-plugins-official",
103
103
  }
104
104
  APP_NAME = "Claude Any"
105
- VERSION = "0.1.75"
105
+ VERSION = "0.1.76"
106
106
  CREDITS = "Credits: One Ciel LLC"
107
107
 
108
108
  LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
@@ -8763,25 +8763,16 @@ def is_channel_spec_tagged(spec: str) -> bool:
8763
8763
  return spec.startswith("plugin:") or spec.startswith("server:")
8764
8764
 
8765
8765
 
8766
- def channel_development_enabled(cfg: dict[str, Any] | None = None) -> bool:
8767
- cfg = cfg or load_config()
8768
- return bool(cfg.setdefault("claude_code", {}).get("development_channels", False))
8769
-
8770
-
8771
8766
  def channel_status_text(cfg: dict[str, Any] | None = None) -> str:
8772
8767
  cfg = cfg or load_config()
8773
8768
  channels = channel_specs(cfg)
8774
8769
  if not channels:
8775
8770
  return "off"
8776
- suffix = "; dev" if channel_development_enabled(cfg) else ""
8777
- return f"{len(channels)} channel{'s' if len(channels) != 1 else ''}{suffix}"
8771
+ return f"{len(channels)} channel{'s' if len(channels) != 1 else ''}"
8778
8772
 
8779
8773
 
8780
8774
  def set_channel_development_enabled(enabled: bool) -> list[str]:
8781
- cfg = load_config()
8782
- cfg.setdefault("claude_code", {})["development_channels"] = bool(enabled)
8783
- save_config(cfg)
8784
- return [f"Development channels: {'on' if enabled else 'off'}."]
8775
+ return ["Channel wake delivery is always enabled by Claude Any."]
8785
8776
 
8786
8777
 
8787
8778
  def add_channel_spec(spec: str, *, development: bool = False) -> list[str]:
@@ -8796,13 +8787,8 @@ def add_channel_spec(spec: str, *, development: bool = False) -> list[str]:
8796
8787
  if spec not in channels:
8797
8788
  channels.append(spec)
8798
8789
  cc["channels"] = channels
8799
- if development:
8800
- cc["development_channels"] = True
8801
8790
  save_config(cfg)
8802
- lines = [f"Channel added: {spec}."]
8803
- if development:
8804
- lines.append("Development channels: on.")
8805
- return lines
8791
+ return [f"Channel added: {spec}."]
8806
8792
 
8807
8793
 
8808
8794
  def remove_channel_spec(spec: str) -> list[str]:
@@ -8833,7 +8819,6 @@ def cmd_channels(args: argparse.Namespace) -> None:
8833
8819
  for spec in channel_specs(cfg):
8834
8820
  if spec not in OFFICIAL_CHANNEL_PLUGINS.values():
8835
8821
  print(f" * custom {spec}")
8836
- print(f"development_channels: {'on' if channel_development_enabled(cfg) else 'off'}")
8837
8822
  return
8838
8823
  head = values[0].strip().lower()
8839
8824
  if head in ("on", "enable", "add"):
@@ -8844,13 +8829,12 @@ def cmd_channels(args: argparse.Namespace) -> None:
8844
8829
  return
8845
8830
  if head in ("dev", "development"):
8846
8831
  if len(values) >= 2 and values[1].lower() in ("on", "off", "true", "false", "1", "0"):
8847
- enabled = values[1].lower() in ("on", "true", "1")
8848
- for line in set_channel_development_enabled(enabled):
8832
+ for line in set_channel_development_enabled(True):
8849
8833
  print(line)
8850
8834
  return
8851
8835
  if len(values) < 2:
8852
- raise SystemExit("Usage: claude-any channels dev CHANNEL_SPEC | claude-any channels dev on|off")
8853
- for line in add_channel_spec(values[1], development=True):
8836
+ raise SystemExit("Usage: claude-any channels add CHANNEL_SPEC")
8837
+ for line in add_channel_spec(values[1]):
8854
8838
  print(line)
8855
8839
  return
8856
8840
  if head in ("off", "disable", "remove", "rm"):
@@ -12138,16 +12122,13 @@ def advisor_model_panel_rows(provider: str, pcfg: dict[str, Any]) -> tuple[list[
12138
12122
 
12139
12123
  def channel_panel_rows(cfg: dict[str, Any]) -> tuple[list[str], list[str]]:
12140
12124
  channels = channel_specs(cfg)
12141
- dev_enabled = channel_development_enabled(cfg)
12142
12125
  rows: list[str] = []
12143
12126
  values: list[str] = []
12144
- rows.append(f"Development channel loading [{'on' if dev_enabled else 'off'}]")
12145
- values.append("__toggle_dev__")
12146
12127
  for name, spec in OFFICIAL_CHANNEL_PLUGINS.items():
12147
12128
  mark = "*" if spec in channels else " "
12148
12129
  rows.append(f"{mark} {name:<10} {spec}")
12149
12130
  values.append(spec)
12150
- rows.append("+ Add development/custom channel...")
12131
+ rows.append("+ Add custom channel...")
12151
12132
  values.append("__add_custom__")
12152
12133
  if channels:
12153
12134
  rows.append("- Remove channel...")
@@ -12683,15 +12664,10 @@ def portable_prelaunch_menu() -> int:
12683
12664
  elif panel == "channels":
12684
12665
  if value == "back":
12685
12666
  close_panel()
12686
- elif value == "__toggle_dev__":
12687
- messages = set_channel_development_enabled(not channel_development_enabled(cfg))
12688
- cfg = load_config()
12689
- panel_rows, panel_values = channel_panel_rows(cfg)
12690
- panel_idx = 0
12691
12667
  elif value == "__add_custom__":
12692
12668
  spec = prompt_menu_value("Channel spec (for example plugin:ainet@local or server:ainet)", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
12693
12669
  if spec:
12694
- messages = add_channel_spec(spec, development=True)
12670
+ messages = add_channel_spec(spec)
12695
12671
  cfg = load_config()
12696
12672
  panel_rows, panel_values = channel_panel_rows(cfg)
12697
12673
  elif value == "__remove__":
@@ -13076,6 +13052,29 @@ def npm_latest_package_version(npm: str, package_spec: str, timeout: float = 8.0
13076
13052
  return out.splitlines()[-1].strip() if out else ""
13077
13053
 
13078
13054
 
13055
+ def npm_global_package_root(npm: str, package_name: str = "@oneciel-ai/claude-any", timeout: float = 8.0) -> Path | None:
13056
+ try:
13057
+ p = subprocess.run(
13058
+ [npm, "root", "-g"],
13059
+ text=True,
13060
+ stdout=subprocess.PIPE,
13061
+ stderr=subprocess.DEVNULL,
13062
+ timeout=timeout,
13063
+ )
13064
+ except Exception:
13065
+ return None
13066
+ if p.returncode != 0:
13067
+ return None
13068
+ root = (p.stdout or "").strip()
13069
+ if not root:
13070
+ return None
13071
+ package_path = Path(root)
13072
+ for part in package_name.split("/"):
13073
+ if part:
13074
+ package_path /= part
13075
+ return package_path
13076
+
13077
+
13079
13078
  def claude_code_current_version(claude: str) -> str:
13080
13079
  try:
13081
13080
  p = subprocess.run(
@@ -13100,6 +13099,26 @@ def running_from_npm_package() -> bool:
13100
13099
  return "/node_modules/@oneciel-ai/claude-any/" in path
13101
13100
 
13102
13101
 
13102
+ def claude_any_restart_user_args() -> list[str]:
13103
+ args = list(sys.argv[1:])
13104
+ if args and args[0] == "cli":
13105
+ return args[1:]
13106
+ return args
13107
+
13108
+
13109
+ def restart_claude_any_after_update(npm: str) -> None:
13110
+ os.environ["CLAUDE_ANY_SKIP_SELF_UPDATE"] = "1"
13111
+ user_args = claude_any_restart_user_args()
13112
+ package_root = npm_global_package_root(npm)
13113
+ package_script = package_root / "claude_any.py" if package_root else None
13114
+ if package_script and package_script.exists():
13115
+ os.execv(sys.executable, [sys.executable, str(package_script), "cli", *user_args])
13116
+ launcher = find_executable("claude-any")
13117
+ if launcher:
13118
+ raise SystemExit(subprocess.call([launcher, *user_args], env=os.environ.copy()))
13119
+ os.execv(sys.executable, [sys.executable, *sys.argv])
13120
+
13121
+
13103
13122
  def run_claude_any_update_check(enabled: bool = True) -> bool:
13104
13123
  if not enabled:
13105
13124
  return False
@@ -13142,9 +13161,10 @@ def run_claude_any_update_check(enabled: bool = True) -> bool:
13142
13161
  print(f"Claude Any update exited with {update.returncode}; continuing with current version.", flush=True)
13143
13162
  return False
13144
13163
  print("Claude Any updated. Restarting with the new version...", flush=True)
13145
- os.environ["CLAUDE_ANY_SKIP_SELF_UPDATE"] = "1"
13146
13164
  try:
13147
- os.execv(sys.executable, [sys.executable, *sys.argv])
13165
+ restart_claude_any_after_update(npm)
13166
+ except SystemExit:
13167
+ raise
13148
13168
  except Exception as exc:
13149
13169
  print(f"Restart failed ({type(exc).__name__}); continuing with the current process.", flush=True)
13150
13170
  return True
@@ -13357,9 +13377,6 @@ Headless setup flags, namespaced to avoid Claude CLI collisions:
13357
13377
  claude-any --ca-web-fetch Enable fetch MCP
13358
13378
  claude-any --ca-no-web-fetch Disable fetch MCP
13359
13379
  claude-any --ca-channel SPEC Add an official/approved Claude Code channel
13360
- claude-any --ca-dev-channel SPEC Add a development channel and enable dev loading
13361
- claude-any --ca-development-channels on|off
13362
- Use tagged specs with --dangerously-load-development-channels
13363
13380
  claude-any --ca-clear-channels Clear saved channel auto-injection specs
13364
13381
  claude-any --ca-no-self-update-check
13365
13382
  Skip Claude Any npm self-update check
@@ -13482,13 +13499,7 @@ def apply_headless_env_config() -> tuple[bool, bool | None, bool | None, bool |
13482
13499
  if item.strip()
13483
13500
  ]
13484
13501
  for channel_value in dev_channel_values:
13485
- add_channel_spec(channel_value, development=True)
13486
- skip_menu = True
13487
- dev_channels = os.environ.get("CLAUDE_ANY_DEVELOPMENT_CHANNELS", "").strip().lower()
13488
- if dev_channels:
13489
- if dev_channels not in ("on", "off", "true", "false", "1", "0"):
13490
- raise SystemExit("CLAUDE_ANY_DEVELOPMENT_CHANNELS must be on or off")
13491
- set_channel_development_enabled(dev_channels in ("on", "true", "1"))
13502
+ add_channel_spec(channel_value)
13492
13503
  skip_menu = True
13493
13504
  return skip_menu, web_search_override, update_check_override, self_update_check_override, force_menu
13494
13505
 
@@ -13907,7 +13918,7 @@ def run_cli(argv: list[str]) -> int:
13907
13918
  i += 2
13908
13919
  else:
13909
13920
  i += 1
13910
- for line in add_channel_spec(value, development=True):
13921
+ for line in add_channel_spec(value):
13911
13922
  print(line)
13912
13923
  skip_menu = True
13913
13924
  elif arg == "--ca-development-channels" or arg.startswith("--ca-development-channels="):
@@ -13919,8 +13930,7 @@ def run_cli(argv: list[str]) -> int:
13919
13930
  i += 2
13920
13931
  else:
13921
13932
  i += 1
13922
- enabled = value.strip().lower() in ("on", "enable", "enabled", "true", "1")
13923
- for line in set_channel_development_enabled(enabled):
13933
+ for line in set_channel_development_enabled(True):
13924
13934
  print(line)
13925
13935
  skip_menu = True
13926
13936
  elif arg == "--ca-clear-channels":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneciel-ai/claude-any",
3
- "version": "0.1.75",
3
+ "version": "0.1.76",
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",