@misterhuydo/sentinel 1.5.0 → 1.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/sentinel",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"
@@ -2877,6 +2877,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2877
2877
  # Only inject API key when Claude Pro is NOT preferred for heavy tasks
2878
2878
  if cfg.anthropic_api_key and not cfg.claude_pro_for_tasks:
2879
2879
  env["ANTHROPIC_API_KEY"] = cfg.anthropic_api_key
2880
+ api_env = {**env, "ANTHROPIC_API_KEY": cfg.anthropic_api_key} if cfg.anthropic_api_key else None
2880
2881
 
2881
2882
  # Build project context block (all repos this Sentinel instance manages)
2882
2883
  _project_name = _read_project_name(Path("."))
@@ -2927,15 +2928,33 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2927
2928
  f"{_mode_instruction}\n\n"
2928
2929
  f"Question / Task: {question}"
2929
2930
  )
2931
+ from .fix_engine import _is_auth_error
2932
+ skip_perms = os.getuid() != 0
2933
+ # OAuth attempt: no --bare so the stored OAuth session is used naturally
2934
+ oauth_cmd = (
2935
+ [cfg.claude_code_bin, "--dangerously-skip-permissions", "--print", prompt]
2936
+ if skip_perms else
2937
+ [cfg.claude_code_bin, "--print", prompt]
2938
+ )
2939
+ # API key fallback: --bare forces API-key-only auth (no OAuth/hooks)
2940
+ api_cmd = (
2941
+ [cfg.claude_code_bin, "--dangerously-skip-permissions", "--bare", "--print", prompt]
2942
+ if skip_perms else
2943
+ [cfg.claude_code_bin, "--bare", "--print", prompt]
2944
+ )
2945
+ run_kwargs = dict(capture_output=True, text=True, timeout=300,
2946
+ cwd=str(local_path), stdin=subprocess.DEVNULL)
2930
2947
  try:
2931
- r = subprocess.run(
2932
- ([cfg.claude_code_bin, "--dangerously-skip-permissions", "--bare", "--print", prompt]
2933
- if os.getuid() != 0 else
2934
- [cfg.claude_code_bin, "--bare", "--print", prompt]),
2935
- capture_output=True, text=True, timeout=300, env=env,
2936
- cwd=str(local_path), stdin=subprocess.DEVNULL,
2937
- )
2948
+ r = subprocess.run(oauth_cmd, env=env, **run_kwargs)
2938
2949
  output = (r.stdout or "").strip()
2950
+ auth_failed = _is_auth_error(output) or _is_auth_error(r.stderr or "")
2951
+
2952
+ # Silent fallback: OAuth session expired — retry with API key
2953
+ if auth_failed and api_env:
2954
+ logger.warning("ask_codebase/%s: OAuth session issue — retrying with API key", repo_name)
2955
+ r = subprocess.run(api_cmd, env=api_env, **run_kwargs)
2956
+ output = (r.stdout or "").strip()
2957
+
2939
2958
  logger.info("Boss ask_codebase %s mode=%s rc=%d len=%d", repo_name, mode, r.returncode, len(output))
2940
2959
  if r.returncode != 0 and not output:
2941
2960
  raw_err = (r.stderr or "")