@misterhuydo/sentinel 1.2.0 → 1.2.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "message": "Auto-checkpoint at 2026-03-23T09:22:14.601Z",
3
- "checkpoint_at": "2026-03-23T09:22:14.603Z",
2
+ "message": "Auto-checkpoint at 2026-03-23T09:42:32.547Z",
3
+ "checkpoint_at": "2026-03-23T09:42:32.548Z",
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.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"
@@ -187,6 +187,13 @@ Session context — critical rules:
187
187
  - When handling a new request, call the tools fresh. Do not assume any prior tool result is still current or that any prior step "counts" toward the current task.
188
188
  - The only exception: if the user explicitly asks about something from the history ("what did you find earlier?"), you may reference it — but note it is from a prior session.
189
189
 
190
+ Trust your tool results — never contradict them:
191
+ - If any search_logs call in this response returned total_matches > 0, you HAVE results. Report them.
192
+ - Never say "no results found" or "nothing was found" when a tool result shows total_matches > 0.
193
+ - If one source-specific call returns 0 but a broader call returned matches, use the broader results.
194
+ - A cached result with files_searched=0 is a source-name lookup failure, NOT an absence of log data.
195
+ Treat it as "source not recognised" and fall back to the broad search results you already have.
196
+
190
197
  Avoid redundant tool calls (within a single response only — always run tools fresh for new requests):
191
198
  - If a broad search (e.g. search_logs with no source filter) already returned results in THIS response, do NOT repeat the same search with a source filter to "refine" — use what you already fetched.
192
199
  - If a tool call fails in THIS response, do NOT retry the entire search from scratch. Continue with what succeeded and note the failure.
@@ -201,12 +208,12 @@ Issue identification — before calling create_issue:
201
208
  - Attachments: summarise any files/screenshots the user shared.
202
209
  - Support URL: note any ticket/doc/link the user mentioned.
203
210
  - Identity: always captured automatically from the Slack session.
204
- 3. ALWAYS populate the `findings` field with evidence from this session:
211
+ 3. Populate `findings` with curated evidence only when relevant and concise:
205
212
  - If you ran search_logs, tail_log, ask_codebase, or get_status before creating the issue,
206
- include the relevant results (log excerpts, error counts, timestamps, stack traces, etc.).
207
- - The fix engine reads only the issue file it has no access to the conversation.
208
- Everything it needs to understand and fix the problem must be in the file.
209
- - A `description` with no evidence forces the fix engine to guess. Always attach what you found.
213
+ summarise only the findings directly related to this specific issue.
214
+ - Do NOT paste raw tool output. Summarise: which services, how often, key pattern, 1-3 example lines.
215
+ - If the search returned nothing relevant, or the issue is purely user-described with no log evidence, leave `findings` empty.
216
+ - The fix engine reads only the issue file. Give it signal, not noise 500 words max.
210
217
  4. Before calling the tool, confirm with the user in natural language:
211
218
  e.g. "I'll create an issue for project *1881* — here's what I have: [summary]. Look right?"
212
219
  Wait for their confirmation before proceeding.
@@ -276,11 +283,11 @@ _TOOLS = [
276
283
  "findings": {
277
284
  "type": "string",
278
285
  "description": (
279
- "Evidence gathered during this session: log excerpts, search results, "
280
- "stack traces, error counts, timestamps anything from tool calls that "
281
- "is relevant to the issue. Include this whenever you ran search_logs, "
282
- "tail_log, ask_codebase, or get_status before creating the issue. "
283
- "The fix engine reads the issue file and needs this context to act."
286
+ "A concise, curated summary of evidence directly relevant to this issue — "
287
+ "NOT raw tool output. Include only what the fix engine needs: "
288
+ "key error patterns, affected services, approximate frequency/timestamps, "
289
+ "and 1-3 representative log lines. Omit unrelated results. "
290
+ "Keep under 500 words. Leave empty if no tool results are relevant."
284
291
  ),
285
292
  },
286
293
  },
@@ -1111,9 +1118,15 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
1111
1118
  })
1112
1119
 
1113
1120
  # ── Fallback: search locally-cached log files ──────────────────────────
1121
+ # Reaching here means: live script unavailable OR source filter matched no config files.
1122
+ # A result with files_searched=0 means the source name wasn't recognised — NOT that
1123
+ # there are no log entries. Do not interpret this as "no results found".
1114
1124
  fetched_dir = Path("workspace/fetched")
1115
1125
  if not fetched_dir.exists():
1116
- return json.dumps({"error": "No fetched logs found and fetch_log.sh unavailable"})
1126
+ return json.dumps({
1127
+ "error": "No fetched logs found and fetch_log.sh unavailable",
1128
+ "note": "This is a config/setup problem, not a 'no results' answer.",
1129
+ })
1117
1130
  try:
1118
1131
  pattern = re.compile(query, re.IGNORECASE)
1119
1132
  except re.error as e:
@@ -1134,13 +1147,21 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
1134
1147
  except Exception:
1135
1148
  pass
1136
1149
  total = sum(len(r["matches"]) for r in results)
1137
- return json.dumps({
1150
+ files_searched = len(list(fetched_dir.glob("*.log")))
1151
+ result = {
1138
1152
  "query": query,
1139
1153
  "mode": "cached",
1140
1154
  "total_matches": total,
1141
- "files_searched": len(list(fetched_dir.glob("*.log"))),
1155
+ "files_searched": files_searched,
1142
1156
  "results": results,
1143
- })
1157
+ }
1158
+ if files_searched == 0:
1159
+ result["warning"] = (
1160
+ "No cached log files found for this source filter. "
1161
+ "This means the source name was not recognised — not that there are no log entries. "
1162
+ "Try search_logs without a source filter to search all sources."
1163
+ )
1164
+ return json.dumps(result)
1144
1165
 
1145
1166
  if name == "trigger_poll":
1146
1167
  Path("SENTINEL_POLL_NOW").touch()