@misterhuydo/sentinel 1.0.47 → 1.0.49

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/.cairn/.hint-lock CHANGED
@@ -1 +1 @@
1
- 2026-03-22T05:33:05.646Z
1
+ 2026-03-22T09:54:45.729Z
@@ -1,6 +1,6 @@
1
1
  {
2
- "message": "Auto-checkpoint at 2026-03-22T05:48:46.579Z",
3
- "checkpoint_at": "2026-03-22T05:48:46.580Z",
2
+ "message": "Auto-checkpoint at 2026-03-22T09:57:48.597Z",
3
+ "checkpoint_at": "2026-03-22T09:57:48.598Z",
4
4
  "active_files": [],
5
5
  "notes": [],
6
6
  "mtime_snapshot": {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/sentinel",
3
- "version": "1.0.47",
3
+ "version": "1.0.49",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"
@@ -276,6 +276,37 @@ _TOOLS = [
276
276
  },
277
277
  },
278
278
  },
279
+ {
280
+ "name": "fetch_logs",
281
+ "description": (
282
+ "Run fetch_log.sh for one or all configured log sources to pull the latest logs "
283
+ "from remote servers right now. Use for: 'fetch logs', 'run fetch_log.sh', "
284
+ "'grab latest logs from SSOLWA', 'try fetch_log.sh for STS', "
285
+ "'pull logs from server', 'get fresh logs'."
286
+ ),
287
+ "input_schema": {
288
+ "type": "object",
289
+ "properties": {
290
+ "source": {
291
+ "type": "string",
292
+ "description": "Log source name to fetch (partial match, e.g. 'SSOLWA'). Omit to fetch all.",
293
+ },
294
+ "debug": {
295
+ "type": "boolean",
296
+ "description": "Run fetch_log.sh with --debug flag to show SSH/grep details",
297
+ "default": False,
298
+ },
299
+ "tail": {
300
+ "type": "integer",
301
+ "description": "Override TAIL lines (how many log lines to fetch)",
302
+ },
303
+ "grep_filter": {
304
+ "type": "string",
305
+ "description": "Override GREP_FILTER (regex). Pass 'none' to disable filtering.",
306
+ },
307
+ },
308
+ },
309
+ },
279
310
  ]
280
311
 
281
312
 
@@ -584,6 +615,60 @@ def _run_tool(name: str, inputs: dict, cfg_loader, store) -> str:
584
615
  logger.info("Boss: pull_config %s → %s", d.name, res["status"])
585
616
  return json.dumps({"results": results})
586
617
 
618
+ if name == "fetch_logs":
619
+ source_filter = inputs.get("source", "").lower()
620
+ debug = bool(inputs.get("debug", False))
621
+ tail_override = inputs.get("tail")
622
+ grep_override = inputs.get("grep_filter", "")
623
+
624
+ # Find fetch_log.sh relative to this file
625
+ script = Path(__file__).resolve().parent.parent / "scripts" / "fetch_log.sh"
626
+ if not script.exists():
627
+ return json.dumps({"error": f"fetch_log.sh not found at {script}"})
628
+
629
+ log_cfg_dir = Path("config") / "log-configs"
630
+ if not log_cfg_dir.exists():
631
+ return json.dumps({"error": "config/log-configs/ not found"})
632
+
633
+ props_files = sorted(log_cfg_dir.glob("*.properties"))
634
+ if source_filter:
635
+ props_files = [p for p in props_files if source_filter in p.stem.lower()]
636
+ if not props_files:
637
+ return json.dumps({"error": f"No log-config found matching '{source_filter}'"})
638
+
639
+ results = []
640
+ for props in props_files:
641
+ env = os.environ.copy()
642
+ if tail_override:
643
+ env["TAIL"] = str(tail_override)
644
+ if grep_override:
645
+ env["GREP_FILTER"] = grep_override
646
+
647
+ cmd = ["bash", str(script)]
648
+ if debug:
649
+ cmd.append("--debug")
650
+ cmd.append(str(props))
651
+
652
+ try:
653
+ r = subprocess.run(
654
+ cmd, capture_output=True, text=True, timeout=120, env=env,
655
+ )
656
+ output = (r.stdout or "").strip()
657
+ stderr = (r.stderr or "").strip()
658
+ results.append({
659
+ "source": props.stem,
660
+ "returncode": r.returncode,
661
+ "output": output[-2000:] if output else "",
662
+ "stderr": stderr[-1000:] if stderr else "",
663
+ })
664
+ logger.info("Boss fetch_logs %s rc=%d", props.stem, r.returncode)
665
+ except subprocess.TimeoutExpired:
666
+ results.append({"source": props.stem, "error": "timed out after 120s"})
667
+ except Exception as e:
668
+ results.append({"source": props.stem, "error": str(e)})
669
+
670
+ return json.dumps({"fetched": len(results), "results": results})
671
+
587
672
  return json.dumps({"error": f"unknown tool: {name}"})
588
673
 
589
674
 
@@ -656,7 +741,7 @@ async def _handle_with_cli(
656
741
  try:
657
742
  result = subprocess.run(
658
743
  [cfg.claude_code_bin, "--print", prompt],
659
- capture_output=True, text=True, timeout=60, env=env,
744
+ capture_output=True, text=True, timeout=180, env=env,
660
745
  )
661
746
  output = (result.stdout or "").strip()
662
747
  except Exception as e:
@@ -13,8 +13,10 @@ MAILS=you@yourdomain.com
13
13
  SEND_HEALTH=disabled
14
14
  REPORT_INTERVAL_HOURS=1
15
15
 
16
- # GitHub token for opening PRs (required when AUTO_PUBLISH=false)
17
- GITHUB_TOKEN=<github-pat>
16
+ # GitHub token for opening PRs (when AUTO_PUBLISH=false).
17
+ # Usually set once in the workspace sentinel.properties and shared across all projects.
18
+ # Uncomment here only if this project needs a different token.
19
+ # GITHUB_TOKEN=<github-pat>
18
20
 
19
21
  # State DB and workspace paths (relative to this project dir)
20
22
  STATE_DB=./sentinel.db
@@ -10,6 +10,10 @@ SMTP_PORT=587
10
10
  SMTP_USER=sentinel@yourdomain.com
11
11
  SMTP_PASSWORD=<app-password>
12
12
 
13
+ # GitHub token for opening PRs (when AUTO_PUBLISH=false).
14
+ # Shared across all projects — override per-project in config/sentinel.properties if needed.
15
+ GITHUB_TOKEN=<github-pat>
16
+
13
17
  # Fix confidence threshold (0.0 - 1.0)
14
18
  FIX_CONFIDENCE_THRESHOLD=0.7
15
19