@misterhuydo/sentinel 1.5.31 → 1.5.32
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 +1 @@
|
|
|
1
|
-
__version__ = "1.5.
|
|
1
|
+
__version__ = "1.5.32"
|
|
@@ -34,7 +34,7 @@ from .git_manager import _git_env
|
|
|
34
34
|
|
|
35
35
|
logger = logging.getLogger(__name__)
|
|
36
36
|
|
|
37
|
-
_META_PREFIXES = ("REPO:", "TYPE:", "SUBMITTED_BY:", "SUBMITTED_AT:", "RUN_AT:", "NOTIFY:", "ORIGIN_CHANNEL:")
|
|
37
|
+
_META_PREFIXES = ("REPO:", "TYPE:", "SUBMITTED_BY:", "SUBMITTED_AT:", "RUN_AT:", "NOTIFY:", "ORIGIN_CHANNEL:", "SKIP_TESTS:")
|
|
38
38
|
_TASK_TIMEOUT = 900 # 15 minutes
|
|
39
39
|
|
|
40
40
|
|
|
@@ -51,6 +51,7 @@ class RepoTask:
|
|
|
51
51
|
timestamp: str = ""
|
|
52
52
|
run_at: datetime | None = None # UTC; task is held until this time if set
|
|
53
53
|
origin_channel: str = "" # Slack channel ID where task was requested (DM or group)
|
|
54
|
+
skip_tests: bool = False # skip test suite (safe for trivial/non-logic changes)
|
|
54
55
|
|
|
55
56
|
def __post_init__(self):
|
|
56
57
|
if not self.fingerprint:
|
|
@@ -62,6 +63,20 @@ class RepoTask:
|
|
|
62
63
|
|
|
63
64
|
def _build_repo_prompt(task: RepoTask, repo: RepoConfig) -> str:
|
|
64
65
|
submitted = f"Requested by: <@{task.submitter_user_id}>" if task.submitter_user_id else ""
|
|
66
|
+
if task.skip_tests:
|
|
67
|
+
test_instruction = (
|
|
68
|
+
"4. The user explicitly requested to skip tests — syntax check only, "
|
|
69
|
+
"do NOT run the test suite."
|
|
70
|
+
)
|
|
71
|
+
else:
|
|
72
|
+
test_instruction = (
|
|
73
|
+
"4. After making your changes, run: git diff HEAD to review the diff, then decide:\n"
|
|
74
|
+
" - If ALL changes are non-logic (log statements, comments, string literals,\n"
|
|
75
|
+
" config values, whitespace/formatting): syntax check only — skip the test suite.\n"
|
|
76
|
+
" - If ANY logic changed (conditionals, data flow, new/removed code paths,\n"
|
|
77
|
+
" method behaviour): run the full test suite (mvn test / npm test / gradlew test)\n"
|
|
78
|
+
" and commit only if it passes."
|
|
79
|
+
)
|
|
65
80
|
return (
|
|
66
81
|
f"You are implementing a requested change in the repository at {repo.local_path}.\n"
|
|
67
82
|
f"Repository: {repo.repo_name}\n"
|
|
@@ -76,7 +91,7 @@ def _build_repo_prompt(task: RepoTask, repo: RepoConfig) -> str:
|
|
|
76
91
|
f" before making any changes.\n"
|
|
77
92
|
f"2. Implement the requested change following the repo's existing code style.\n"
|
|
78
93
|
f"3. Syntax/compile check modified files.\n"
|
|
79
|
-
f"
|
|
94
|
+
f"{test_instruction}\n"
|
|
80
95
|
f"5. Commit all changes:\n"
|
|
81
96
|
f" git add -A\n"
|
|
82
97
|
f" git commit -m \"{task.task_type}(<scope>): <concise summary> [sentinel-task]\"\n"
|
|
@@ -347,6 +362,7 @@ def drop_repo_task(
|
|
|
347
362
|
notify_user_ids: list | None = None,
|
|
348
363
|
run_at: datetime | None = None,
|
|
349
364
|
origin_channel: str = "",
|
|
365
|
+
skip_tests: bool = False,
|
|
350
366
|
) -> Path:
|
|
351
367
|
"""Drop a repo task file into <project_dir>/repo-tasks/.
|
|
352
368
|
|
|
@@ -372,6 +388,8 @@ def drop_repo_task(
|
|
|
372
388
|
lines.append(f"NOTIFY: {','.join(notify_user_ids)}")
|
|
373
389
|
if origin_channel:
|
|
374
390
|
lines.append(f"ORIGIN_CHANNEL: {origin_channel}")
|
|
391
|
+
if skip_tests:
|
|
392
|
+
lines.append("SKIP_TESTS: true")
|
|
375
393
|
lines += ["", description]
|
|
376
394
|
fpath.write_text("\n".join(lines), encoding="utf-8")
|
|
377
395
|
if run_at:
|
|
@@ -404,6 +422,7 @@ def scan_repo_tasks(project_dir: Path) -> list[RepoTask]:
|
|
|
404
422
|
notify_user_ids: list = []
|
|
405
423
|
run_at: datetime | None = None
|
|
406
424
|
origin_channel = ""
|
|
425
|
+
skip_tests = False
|
|
407
426
|
body_start = 0
|
|
408
427
|
|
|
409
428
|
for i, line in enumerate(lines):
|
|
@@ -434,6 +453,9 @@ def scan_repo_tasks(project_dir: Path) -> list[RepoTask]:
|
|
|
434
453
|
elif upper.startswith("ORIGIN_CHANNEL:"):
|
|
435
454
|
origin_channel = stripped[15:].strip()
|
|
436
455
|
body_start = i + 1
|
|
456
|
+
elif upper.startswith("SKIP_TESTS:"):
|
|
457
|
+
skip_tests = stripped[11:].strip().lower() in ("true", "yes", "1")
|
|
458
|
+
body_start = i + 1
|
|
437
459
|
elif any(upper.startswith(p) for p in _META_PREFIXES) or not stripped:
|
|
438
460
|
body_start = i + 1
|
|
439
461
|
else:
|
|
@@ -469,6 +491,7 @@ def scan_repo_tasks(project_dir: Path) -> list[RepoTask]:
|
|
|
469
491
|
notify_user_ids=notify_user_ids,
|
|
470
492
|
run_at=run_at,
|
|
471
493
|
origin_channel=origin_channel,
|
|
494
|
+
skip_tests=skip_tests,
|
|
472
495
|
))
|
|
473
496
|
logger.info("Found repo task: %s → %s (type=%s)", f.name, repo_name, task_type)
|
|
474
497
|
|
|
@@ -116,6 +116,9 @@ BEFORE CALLING dev_task OR repo_task — GATHER A COMPLETE SPEC:
|
|
|
116
116
|
Ask follow-up questions until you have enough to write an unambiguous task description.
|
|
117
117
|
Typical questions to resolve:
|
|
118
118
|
- For repo_task: which repo exactly? (confirm if multiple match)
|
|
119
|
+
- For repo_task: Claude Code auto-judges whether to run tests by inspecting its own diff.
|
|
120
|
+
Only set skip_tests=true when the user explicitly says "skip tests", "don't run tests",
|
|
121
|
+
or similar — never set it on your own judgment.
|
|
119
122
|
- What exactly should happen? (specific behaviour, not vague intent)
|
|
120
123
|
- Any config values, credentials, or external dependencies involved?
|
|
121
124
|
- How should it be triggered? (schedule, event, API call, etc.)
|
|
@@ -532,6 +535,10 @@ When to act vs. when to ask:
|
|
|
532
535
|
- Explaining a tool ("what does X do?") → explain naturally, then offer to run it if relevant.
|
|
533
536
|
- NEVER gate investigation on user approval. If diagnosing a problem, run all relevant read tools
|
|
534
537
|
first, then present findings. Asking "Want me to look?" wastes a round trip.
|
|
538
|
+
- NEVER answer from session memory alone when the question is about current state (commits,
|
|
539
|
+
tasks, fixes, releases). Always call get_status or list_recent_commits first to verify live
|
|
540
|
+
state. Session memory is a snapshot — tasks complete, commits land, queues drain between turns.
|
|
541
|
+
If you remember "task X was in-flight", check whether it finished before telling the user to wait.
|
|
535
542
|
- Prefer filter_logs over search_logs when synced logs are available — it's instant and never causes session timeout.
|
|
536
543
|
Use search_logs only when the user explicitly wants live/real-time data or synced logs are not yet available.
|
|
537
544
|
- If a tool call will take a moment (search, fetch, pull), prefix your reply with a brief "working" line ending in "..." before the results, e.g. "Searching SSOLWA for TryDig activity..." then the actual output.
|
|
@@ -916,6 +923,15 @@ _TOOLS = [
|
|
|
916
923
|
"If omitted the task runs immediately on the next poll cycle."
|
|
917
924
|
),
|
|
918
925
|
},
|
|
926
|
+
"skip_tests": {
|
|
927
|
+
"type": "boolean",
|
|
928
|
+
"description": (
|
|
929
|
+
"Only set to true when the user explicitly requests skipping tests "
|
|
930
|
+
"(e.g. 'skip tests', 'don\\'t run tests', 'just commit it'). "
|
|
931
|
+
"When false (default), Claude Code automatically decides whether to run "
|
|
932
|
+
"tests by inspecting its own diff — non-logic changes skip tests on their own."
|
|
933
|
+
),
|
|
934
|
+
},
|
|
919
935
|
},
|
|
920
936
|
"required": ["repo_name", "description"],
|
|
921
937
|
},
|
|
@@ -2473,6 +2489,8 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2473
2489
|
if not _project_dirs:
|
|
2474
2490
|
return json.dumps({"error": "No project directory found."})
|
|
2475
2491
|
|
|
2492
|
+
skip_tests = bool(inputs.get("skip_tests", False))
|
|
2493
|
+
|
|
2476
2494
|
from .repo_task_engine import drop_repo_task as _drop_repo_task
|
|
2477
2495
|
task_file = _drop_repo_task(
|
|
2478
2496
|
_project_dirs[0],
|
|
@@ -2483,6 +2501,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2483
2501
|
notify_user_ids=notify_ids,
|
|
2484
2502
|
run_at=run_at_dt,
|
|
2485
2503
|
origin_channel=channel,
|
|
2504
|
+
skip_tests=skip_tests,
|
|
2486
2505
|
)
|
|
2487
2506
|
logger.info(
|
|
2488
2507
|
"Boss repo_task: dropped %s for user %s (repo=%s, run_at=%s)",
|