@oneciel-ai/claude-any 0.1.74 → 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.
- package/claude_any.py +96 -54
- 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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
8853
|
-
for line in add_channel_spec(values[1]
|
|
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
|
|
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
|
|
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__":
|
|
@@ -12906,13 +12882,42 @@ def has_passthrough_option(passthrough: list[str], *names: str) -> bool:
|
|
|
12906
12882
|
return any(arg in names or any(arg.startswith(name + "=") for name in names) for arg in passthrough)
|
|
12907
12883
|
|
|
12908
12884
|
|
|
12885
|
+
def normalize_channel_passthrough(passthrough: list[str]) -> list[str]:
|
|
12886
|
+
normalized: list[str] = []
|
|
12887
|
+
i = 0
|
|
12888
|
+
while i < len(passthrough):
|
|
12889
|
+
arg = passthrough[i]
|
|
12890
|
+
if arg == "--channels":
|
|
12891
|
+
normalized.append("--dangerously-load-development-channels")
|
|
12892
|
+
i += 1
|
|
12893
|
+
while i < len(passthrough) and is_channel_spec_tagged(passthrough[i]):
|
|
12894
|
+
normalized.append(passthrough[i])
|
|
12895
|
+
i += 1
|
|
12896
|
+
continue
|
|
12897
|
+
if arg.startswith("--channels="):
|
|
12898
|
+
value = arg.split("=", 1)[1].strip()
|
|
12899
|
+
if value:
|
|
12900
|
+
normalized.extend(["--dangerously-load-development-channels", value])
|
|
12901
|
+
else:
|
|
12902
|
+
normalized.append("--dangerously-load-development-channels")
|
|
12903
|
+
i += 1
|
|
12904
|
+
continue
|
|
12905
|
+
normalized.append(arg)
|
|
12906
|
+
i += 1
|
|
12907
|
+
return normalized
|
|
12908
|
+
|
|
12909
|
+
|
|
12909
12910
|
def claude_channel_args(cfg: dict[str, Any], passthrough: list[str]) -> list[str]:
|
|
12910
12911
|
channels = [spec for spec in channel_specs(cfg) if is_channel_spec_tagged(spec)]
|
|
12911
12912
|
if not channels or has_passthrough_option(passthrough, "--channels", "--dangerously-load-development-channels"):
|
|
12912
12913
|
return []
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
|
|
12914
|
+
return ["--dangerously-load-development-channels", *channels]
|
|
12915
|
+
|
|
12916
|
+
|
|
12917
|
+
def claude_channels_requested(cfg: dict[str, Any], passthrough: list[str]) -> bool:
|
|
12918
|
+
if has_passthrough_option(passthrough, "--channels", "--dangerously-load-development-channels"):
|
|
12919
|
+
return True
|
|
12920
|
+
return any(is_channel_spec_tagged(spec) for spec in channel_specs(cfg))
|
|
12916
12921
|
|
|
12917
12922
|
|
|
12918
12923
|
def write_web_tools_mcp_config(cfg: dict[str, Any]) -> Path:
|
|
@@ -13047,6 +13052,29 @@ def npm_latest_package_version(npm: str, package_spec: str, timeout: float = 8.0
|
|
|
13047
13052
|
return out.splitlines()[-1].strip() if out else ""
|
|
13048
13053
|
|
|
13049
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
|
+
|
|
13050
13078
|
def claude_code_current_version(claude: str) -> str:
|
|
13051
13079
|
try:
|
|
13052
13080
|
p = subprocess.run(
|
|
@@ -13071,6 +13099,26 @@ def running_from_npm_package() -> bool:
|
|
|
13071
13099
|
return "/node_modules/@oneciel-ai/claude-any/" in path
|
|
13072
13100
|
|
|
13073
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
|
+
|
|
13074
13122
|
def run_claude_any_update_check(enabled: bool = True) -> bool:
|
|
13075
13123
|
if not enabled:
|
|
13076
13124
|
return False
|
|
@@ -13113,9 +13161,10 @@ def run_claude_any_update_check(enabled: bool = True) -> bool:
|
|
|
13113
13161
|
print(f"Claude Any update exited with {update.returncode}; continuing with current version.", flush=True)
|
|
13114
13162
|
return False
|
|
13115
13163
|
print("Claude Any updated. Restarting with the new version...", flush=True)
|
|
13116
|
-
os.environ["CLAUDE_ANY_SKIP_SELF_UPDATE"] = "1"
|
|
13117
13164
|
try:
|
|
13118
|
-
|
|
13165
|
+
restart_claude_any_after_update(npm)
|
|
13166
|
+
except SystemExit:
|
|
13167
|
+
raise
|
|
13119
13168
|
except Exception as exc:
|
|
13120
13169
|
print(f"Restart failed ({type(exc).__name__}); continuing with the current process.", flush=True)
|
|
13121
13170
|
return True
|
|
@@ -13221,6 +13270,9 @@ def launch_claude(
|
|
|
13221
13270
|
env = os.environ.copy()
|
|
13222
13271
|
env["PATH"] = str(HOME / ".local" / "bin") + os.pathsep + env.get("PATH", "")
|
|
13223
13272
|
launch_env = env_vars(cfg)
|
|
13273
|
+
launch_passthrough = normalize_channel_passthrough(passthrough)
|
|
13274
|
+
if claude_channels_requested(cfg, launch_passthrough):
|
|
13275
|
+
launch_env.pop("CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS", None)
|
|
13224
13276
|
if use_native_anthropic:
|
|
13225
13277
|
for key in (
|
|
13226
13278
|
"ANTHROPIC_BASE_URL",
|
|
@@ -13252,9 +13304,9 @@ def launch_claude(
|
|
|
13252
13304
|
extra_args: list[str] = []
|
|
13253
13305
|
if should_attach_web_search(provider, cfg, web_search_override):
|
|
13254
13306
|
extra_args.extend(["--mcp-config", str(write_duckduckgo_mcp_config(cfg))])
|
|
13255
|
-
if should_append_compat_prompt(provider, cfg) and not has_passthrough_option(
|
|
13307
|
+
if should_append_compat_prompt(provider, cfg) and not has_passthrough_option(launch_passthrough, "--system-prompt"):
|
|
13256
13308
|
extra_args.extend(["--append-system-prompt", NON_ANTHROPIC_COMPAT_PROMPT])
|
|
13257
|
-
extra_args.extend(claude_channel_args(cfg,
|
|
13309
|
+
extra_args.extend(claude_channel_args(cfg, launch_passthrough))
|
|
13258
13310
|
cmd = [
|
|
13259
13311
|
claude,
|
|
13260
13312
|
"--dangerously-skip-permissions",
|
|
@@ -13263,7 +13315,7 @@ def launch_claude(
|
|
|
13263
13315
|
if model:
|
|
13264
13316
|
cmd.extend(["--model", model])
|
|
13265
13317
|
cmd.extend(extra_args)
|
|
13266
|
-
cmd.extend(
|
|
13318
|
+
cmd.extend(launch_passthrough)
|
|
13267
13319
|
return subprocess.call(cmd, env=env)
|
|
13268
13320
|
|
|
13269
13321
|
|
|
@@ -13325,9 +13377,6 @@ Headless setup flags, namespaced to avoid Claude CLI collisions:
|
|
|
13325
13377
|
claude-any --ca-web-fetch Enable fetch MCP
|
|
13326
13378
|
claude-any --ca-no-web-fetch Disable fetch MCP
|
|
13327
13379
|
claude-any --ca-channel SPEC Add an official/approved Claude Code channel
|
|
13328
|
-
claude-any --ca-dev-channel SPEC Add a development channel and enable dev loading
|
|
13329
|
-
claude-any --ca-development-channels on|off
|
|
13330
|
-
Use tagged specs with --dangerously-load-development-channels
|
|
13331
13380
|
claude-any --ca-clear-channels Clear saved channel auto-injection specs
|
|
13332
13381
|
claude-any --ca-no-self-update-check
|
|
13333
13382
|
Skip Claude Any npm self-update check
|
|
@@ -13450,13 +13499,7 @@ def apply_headless_env_config() -> tuple[bool, bool | None, bool | None, bool |
|
|
|
13450
13499
|
if item.strip()
|
|
13451
13500
|
]
|
|
13452
13501
|
for channel_value in dev_channel_values:
|
|
13453
|
-
add_channel_spec(channel_value
|
|
13454
|
-
skip_menu = True
|
|
13455
|
-
dev_channels = os.environ.get("CLAUDE_ANY_DEVELOPMENT_CHANNELS", "").strip().lower()
|
|
13456
|
-
if dev_channels:
|
|
13457
|
-
if dev_channels not in ("on", "off", "true", "false", "1", "0"):
|
|
13458
|
-
raise SystemExit("CLAUDE_ANY_DEVELOPMENT_CHANNELS must be on or off")
|
|
13459
|
-
set_channel_development_enabled(dev_channels in ("on", "true", "1"))
|
|
13502
|
+
add_channel_spec(channel_value)
|
|
13460
13503
|
skip_menu = True
|
|
13461
13504
|
return skip_menu, web_search_override, update_check_override, self_update_check_override, force_menu
|
|
13462
13505
|
|
|
@@ -13875,7 +13918,7 @@ def run_cli(argv: list[str]) -> int:
|
|
|
13875
13918
|
i += 2
|
|
13876
13919
|
else:
|
|
13877
13920
|
i += 1
|
|
13878
|
-
for line in add_channel_spec(value
|
|
13921
|
+
for line in add_channel_spec(value):
|
|
13879
13922
|
print(line)
|
|
13880
13923
|
skip_menu = True
|
|
13881
13924
|
elif arg == "--ca-development-channels" or arg.startswith("--ca-development-channels="):
|
|
@@ -13887,8 +13930,7 @@ def run_cli(argv: list[str]) -> int:
|
|
|
13887
13930
|
i += 2
|
|
13888
13931
|
else:
|
|
13889
13932
|
i += 1
|
|
13890
|
-
|
|
13891
|
-
for line in set_channel_development_enabled(enabled):
|
|
13933
|
+
for line in set_channel_development_enabled(True):
|
|
13892
13934
|
print(line)
|
|
13893
13935
|
skip_menu = True
|
|
13894
13936
|
elif arg == "--ca-clear-channels":
|
package/package.json
CHANGED