Skip to content

Release 0.6.2 — probe-adapter + Copilot profile#6

Merged
pbean merged 4 commits into
mainfrom
release/0.6.2
Jun 21, 2026
Merged

Release 0.6.2 — probe-adapter + Copilot profile#6
pbean merged 4 commits into
mainfrom
release/0.6.2

Conversation

@pbean

@pbean pbean commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

0.6.2

Added

  • bmad-auto probe-adapter (alias collect-adapter-data) — self-service command that collects + sanitizes everything needed to finalize a CLI adapter profile (hook payload shape, transcript location/format, token-usage schema) through one audited PII sanitizer. Default zero-launch scan; opt-in --probe live capture.
  • GitHub Copilot CLI profile — bundled copilot profile (Copilot CLI ≥ 2026-02): -i launch, VS Code-compatible Stop hook, --allow-all-tools. Pending live E2E and a usage_parser.

Docs

Release mechanics

  • Version stamped to 0.6.2 across all manifests + uv.lock; CHANGELOG curated. TUI unchanged → screenshots/demo not regenerated. On merge to main, the Release workflow auto-creates the v0.6.2 tag + GitHub release.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added bmad-auto probe-adapter command to collect and sanitize CLI adapter profile data, with optional live probe mode for capturing hook behavior
    • Added GitHub Copilot CLI integration support
  • Documentation

    • Added comprehensive adapter authoring guide for finalizing CLI profiles
    • Updated contribution guidelines with new adapter workflow

pbean and others added 4 commits June 21, 2026 08:58
Bundle a copilot.toml profile for the GitHub Copilot CLI (GA since
2026-02): -i interactive launch, --allow-all-tools/--allow-all-paths
bypass, prompt loads SKILL.md directly (no native skill discovery),
skills shared in .agents/skills with codex/gemini.

Add the copilot-settings-json hook dialect: handlers are stored directly
in the event list (no 'hooks' wrapper), configs are versioned, and
timeouts are seconds. merge_hooks now dedupes both the wrapped and bare
handler shapes so re-runs stay idempotent across all dialects. Hooks
register under VS Code-compatible PascalCase names so Copilot emits the
snake_case payloads the shared relay reads.

Marked pending live E2E verification in docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…data

Add `bmad-auto probe-adapter` (alias `collect-adapter-data`): a self-service
command that pulls and sanitizes everything a maintainer needs to finalize a
generic-adapter CLI profile — hook payload shape, transcript location/format,
and the token-usage schema for a usage_parser.

- default zero-launch SCAN; opt-in `--probe` live capture in an ephemeral
  mkdtemp workspace (rmtree'd in a finally)
- single audited PII chokepoint (sanitize.py): counts/keys pass through, leaf
  strings kept only if identifier-shaped, paths/prose/emails redacted
- packaged full-payload capture hook gated on BMAD_AUTO_PROBE_CAPTURE_DIR
- registers via the existing install.merge_hooks (broadened HOOK_MARKER to
  match either bmad-auto hook script, keeping merges idempotent)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- new docs/adapter-authoring-guide.md: finalizing a CLI profile with
  probe-adapter (scan vs probe, PII model, walkthrough, copilot example)
- add probe-adapter to the README + FEATURES command references
- add the missing copilot row to the README profile table
- link the guide from docs/README.md and CONTRIBUTING.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds bmad-auto probe-adapter (collect-adapter-data) command backed by a new probe.py SCAN/PROBE engine and a stdlib-only PII sanitize.py module. Introduces a standalone capture hook script, a bundled Copilot CLI profile with matching install.py hook wiring, and bumps the package to v0.6.2 with full changelog and adapter authoring documentation.

Changes

probe-adapter Command + Copilot Profile Release

Layer / File(s) Summary
PII sanitization module
src/automator/sanitize.py, tests/test_sanitize.py
Adds stdlib-only sanitize.py with redact_home, looks_like_identifier, recursive scrub_json (depth-guarded), scrub_text (line-capped), and scrub_event_payload. Tests cover all redaction rules including identifier pass-through, list-length preservation, and depth sentinel.
Probe capture hook script
src/automator/data/bmad_auto_probe_hook.py, tests/test_probe_hook.py
Adds a standalone hook script gated on BMAD_AUTO_PROBE_CAPTURE_DIR that defensively parses stdin JSON and atomically writes *.signal.json + *.payload.json per event. Subprocess tests verify file emission, conversation_id fallback, empty-stdin tolerance, and packaged-source parity.
Probe engine: data models, SCAN/PROBE logic, and rendering
src/automator/probe.py, tests/test_probe.py
Adds probe.py with six dataclasses, run_version_help, discover_transcript, infer_token_schema, _hooks_registered, scan, probe (tmux orchestration with _ProbeLauncher/_collect_captures), _log_tail, render_markdown, and render_json. Tests cover schema inference, transcript discovery, hook registration, CLI exit codes, output file generation, JSON block parsing, and PII scrub-through.
CLI probe-adapter subcommand wiring
src/automator/cli.py
Adds cmd_probe handler that builds hints, resolves profiles with --binary fallback, dispatches to probe/scan, renders Markdown plus optional JSON, and wires all flags via a new probe-adapter / collect-adapter-data argparse subparser.
Copilot profile + install wiring
src/automator/data/profiles/copilot.toml, src/automator/install.py, src/automator/adapters/profile.py, tests/test_install.py
Adds copilot.toml with PascalCase hook events and copilot-settings-json dialect. Updates install.py with generalized HOOK_MARKER, COPILOT_HOOK_TIMEOUT_SEC, versioned settings init, and idempotent merge_hooks for the Copilot handler list shape. Changes HOOK_DIALECTS from a set to a dict. Tests cover entry shape, idempotency, prompt rendering, and full install_into flow.
Version bump and documentation
pyproject.toml, src/automator/__init__.py, module.yaml, .claude-plugin/marketplace.json, src/automator/data/skills/bmad-auto-setup/assets/module.yaml, CHANGELOG.md, README.md, CONTRIBUTING.md, docs/...
Bumps version to 0.6.2 across all manifests. Adds CHANGELOG 0.6.2 section, extends README command table and Copilot profile row, updates CONTRIBUTING and feature docs, and adds the complete docs/adapter-authoring-guide.md covering SCAN/PROBE modes, PII model, workflow, flags reference, and Copilot worked example.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant cli as cmd_probe (cli.py)
    participant probe as probe.py
    participant sanitize as sanitize.py
    participant tmux
    participant ProbeHook as bmad_auto_probe_hook.py

    User->>cli: bmad-auto probe-adapter <cli> [--probe]
    cli->>probe: scan(cli, profile, hints)
    probe->>probe: run_version_help → FlagFinding
    probe->>probe: discover_transcript → TranscriptFinding
    probe->>probe: infer_token_schema → TokenSchema
    probe-->>cli: ProfileFinding (SCAN)

    User->>cli: bmad-auto probe-adapter <cli> --probe
    cli->>probe: probe(cli, profile, hints)
    probe->>tmux: new-session, set BMAD_AUTO_PROBE_CAPTURE_DIR
    tmux->>ProbeHook: Stop / SessionStart events fired
    ProbeHook->>ProbeHook: atomic write *.signal.json + *.payload.json
    probe->>probe: _collect_captures → EventCapture[]
    probe->>sanitize: scrub_event_payload(raw_payload)
    sanitize-->>probe: scrubbed payload
    probe->>probe: discover_transcript + infer_token_schema
    probe->>tmux: kill-session, rm temp dir
    probe-->>cli: ProfileFinding (PROBE)
    cli->>User: Markdown report (+ optional JSON block)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 A rabbit hops in with a probe and a scan,
Sniffing out hooks wherever they ran,
PII gets scrubbed with a swift little paw,
Copilot now joins without flaw!
probe-adapter ships, version bumped with a cheer —
The adapter guide's open, new profiles appear. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main changes: release version 0.6.2 introducing the probe-adapter command and Copilot profile support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/0.6.2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@augmentcode

augmentcode Bot commented Jun 21, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR releases bmad-auto v0.6.2 with a new self-service adapter profiling tool and a bundled GitHub Copilot CLI profile.

Changes:

  • Added bmad-auto probe-adapter (alias collect-adapter-data) to scan/probe hook payloads, transcript discovery, and token-usage schema extraction.
  • Implemented a single PII-scrubbing chokepoint (src/automator/sanitize.py) and integrated it into probe report rendering.
  • Added a dedicated full-payload capture hook script (bmad_auto_probe_hook.py) used only during opt-in live probes.
  • Bundled a new copilot CLI profile and added copilot-settings-json as a supported hook dialect.
  • Extended hook installation/merge logic to support Copilot’s settings schema and maintain idempotent hook registration.
  • Added an adapter authoring guide and updated command/profile documentation accordingly.
  • Bumped versions/manifests to 0.6.2 and curated the CHANGELOG.
  • Added tests covering Copilot hook merging, scan/report plumbing, transcript discovery, schema inference, and sanitizer behavior.

Technical Notes: Probe mode uses an ephemeral workspace + tmux launch to capture real hook payloads; scan mode avoids launching the CLI and relies on on-disk conventions.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 5 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/automator/probe.py
hook_src = resources.files("automator.data").joinpath(PROBE_HOOK_NAME)
hook_path = tmpdir / PROBE_HOOK_NAME
hook_path.write_text(hook_src.read_text(encoding="utf-8"), encoding="utf-8")
registrations = {

@augmentcode augmentcode Bot Jun 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/automator/probe.py:525 builds registrations so the capture hook receives {canonical} as argv, but later code treats argv_event as the native event key (breaking non-identity maps like Gemini AfterAgent → Stop and yielding ?/mislabeling in the report). Other locations where this applies: src/automator/data/bmad_auto_probe_hook.py:44.

Severity: medium

Other Locations
  • src/automator/data/bmad_auto_probe_hook.py:44

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/automator/probe.py
missing = "tmux" if not shutil.which("tmux") else binary
finding.warnings.append(f"{missing} not on PATH — cannot probe; falling back to scan")
scanned = scan(cli=cli, profile=profile, project=project, hints=hints)
scanned.mode = "probe"

@augmentcode augmentcode Bot Jun 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/automator/probe.py:511 falls back to scan() when tmux/binary is missing but then forces mode = "probe", which makes render_markdown() take the probe branch and hide declared events / show “no hook payloads captured”. This can confuse users who actually got a scan result due to missing prerequisites.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/automator/probe.py
"""
paths: set[str] = set()
scanned = 0
for entry in _jsonl_entries(path):

@augmentcode augmentcode Bot Jun 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/automator/probe.py:307 iterates transcripts via _jsonl_entries(path) only, but discover_transcript() can select a *.json transcript (e.g., via --session-dir fallback), which will silently scan 0 entries and omit schema/candidates. That makes the “token usage schema” section inaccurate for JSON transcripts.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/automator/probe.py

# CLI flags
out.append("## CLI flags")
out.append(_fmt_kv("launch_args / bypass_args", "see profile (rendered verbatim below)"))

@augmentcode augmentcode Bot Jun 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/automator/probe.py:649 says launch/bypass args are “rendered verbatim below”, but the report never actually prints the profile’s launch_args / bypass_args. This mismatch can mislead users reading the report output.

Severity: low

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Comment thread src/automator/cli.py

if args.out:
out_path = Path(args.out)
out_path.write_text(report, encoding="utf-8")

@augmentcode augmentcode Bot Jun 21, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/automator/cli.py:930 writes the --out report with Path.write_text() but doesn’t handle OSError (missing parent dir, permissions, etc.), so probe-adapter may crash with a traceback instead of returning a clean failure. That’s especially painful since the report content is otherwise already assembled and paste-safe.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/automator/cli.py`:
- Around line 903-912: The success message printed on line 907 (ok: unknown
profile...) will be displayed even when --probe is subsequently used and will
fail, creating contradictory output. Gate this print statement to only execute
when args.probe is False, so the "ok" message is not printed in scenarios where
the --probe check will immediately fail due to the unknown profile. This keeps
the CLI output consistent by avoiding success messages that are followed by
guaranteed failure.

In `@src/automator/install.py`:
- Around line 31-35: The HOOK_MARKER constant uses a broad substring match of
"bmad_auto" which can incorrectly identify unrelated commands as already-managed
hooks. Replace the substring-based marker approach with explicit matching for
the exact managed hook script basenames: bmad_auto_hook.py and
bmad_auto_probe_hook.py. Update all locations where HOOK_MARKER is used
(including lines 81-85 referenced in the comment) to check for these specific
script names instead of a substring match, ensuring the deduplication logic only
applies to the actual managed hook scripts and remains idempotent.

In `@src/automator/probe.py`:
- Around line 525-528: The registrations dictionary is passing the canonical
event name in the probe hook command string, but _collect_captures() expects to
receive the native event name as argv_event to perform the canonical lookup via
events_map.get(native). In the f-string that builds the command for each
registration entry, replace the use of canonical with native as the argument
passed to the hook_path command.
- Around line 602-605: The warning message being appended to finding.warnings in
this code block directly embeds the raw tmpdir path without sanitization, which
can leak sensitive filesystem information. Apply the appropriate path
sanitization function to the tmpdir variable before including it in the f-string
message passed to the append method. This ensures the warning message follows
the same sanitization contract as other parts of the report.
- Around line 507-512: When the tmux or binary check fails in the conditional
block starting with if not shutil.which("tmux"), a warning is appended to the
finding object but then discarded because the function returns the scanned
object instead. To preserve the downgrade reason, transfer the warning message
from finding.warnings to scanned.warnings before returning scanned, ensuring
users see why probe mode fell back to scan mode.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d5ada323-5d87-4db6-9c40-58eff1f438fb

📥 Commits

Reviewing files that changed from the base of the PR and between c1b4edd and 319c334.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (22)
  • .claude-plugin/marketplace.json
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • docs/FEATURES.md
  • docs/README.md
  • docs/adapter-authoring-guide.md
  • module.yaml
  • pyproject.toml
  • src/automator/__init__.py
  • src/automator/adapters/profile.py
  • src/automator/cli.py
  • src/automator/data/bmad_auto_probe_hook.py
  • src/automator/data/profiles/copilot.toml
  • src/automator/data/skills/bmad-auto-setup/assets/module.yaml
  • src/automator/install.py
  • src/automator/probe.py
  • src/automator/sanitize.py
  • tests/test_install.py
  • tests/test_probe.py
  • tests/test_probe_hook.py
  • tests/test_sanitize.py

Comment thread src/automator/cli.py
Comment on lines +903 to +912
except ProfileError as e:
if not args.binary:
print(f"FAIL: {e}", file=sys.stderr)
return 1
print(f" ok: unknown profile {args.cli!r}; reduced report from --binary {args.binary}")

if args.probe:
if profile is None:
print("FAIL: --probe needs a known profile (its hook dialect/events)", file=sys.stderr)
return 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid printing a success message right before guaranteed --probe failure.

With unknown profile + --binary + --probe, Line 907 prints an “ok” message before Line 911 fails. Gate that message to non-probe mode to keep CLI output consistent.

Proposed fix
     except ProfileError as e:
         if not args.binary:
             print(f"FAIL: {e}", file=sys.stderr)
             return 1
-        print(f"  ok: unknown profile {args.cli!r}; reduced report from --binary {args.binary}")
+        if not args.probe:
+            print(f"  ok: unknown profile {args.cli!r}; reduced report from --binary {args.binary}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
except ProfileError as e:
if not args.binary:
print(f"FAIL: {e}", file=sys.stderr)
return 1
print(f" ok: unknown profile {args.cli!r}; reduced report from --binary {args.binary}")
if args.probe:
if profile is None:
print("FAIL: --probe needs a known profile (its hook dialect/events)", file=sys.stderr)
return 1
except ProfileError as e:
if not args.binary:
print(f"FAIL: {e}", file=sys.stderr)
return 1
if not args.probe:
print(f" ok: unknown profile {args.cli!r}; reduced report from --binary {args.binary}")
if args.probe:
if profile is None:
print("FAIL: --probe needs a known profile (its hook dialect/events)", file=sys.stderr)
return 1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/automator/cli.py` around lines 903 - 912, The success message printed on
line 907 (ok: unknown profile...) will be displayed even when --probe is
subsequently used and will fail, creating contradictory output. Gate this print
statement to only execute when args.probe is False, so the "ok" message is not
printed in scenarios where the --probe check will immediately fail due to the
unknown profile. This keeps the CLI output consistent by avoiding success
messages that are followed by guaranteed failure.

Comment thread src/automator/install.py
Comment on lines +31 to 35
# Dedup marker: matches any bmad-auto-managed hook command — both the signal
# relay (bmad_auto_hook.py) and the probe-adapter capture hook
# (bmad_auto_probe_hook.py) — so merge_hooks stays idempotent for either.
HOOK_MARKER = "bmad_auto"
GEMINI_HOOK_TIMEOUT_MS = 60_000

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Narrow the dedupe marker to exact managed hook script names.

The current substring marker is too broad and can treat unrelated commands as already-managed, which can skip required hook registration for an event. Match explicit script basenames (relay/probe) instead of any bmad_auto substring.

Suggested fix
-HOOK_MARKER = "bmad_auto"
+HOOK_MARKERS = ("bmad_auto_hook.py", "bmad_auto_probe_hook.py")
@@
-        already = any(
-            HOOK_MARKER in handler.get("command", "")
+        already = any(
+            any(marker in handler.get("command", "") for marker in HOOK_MARKERS)
             for entry in matchers
             if isinstance(entry, dict)
             for handler in (entry, *entry.get("hooks", []))
             if isinstance(handler, dict)
         )

Also applies to: 81-85

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/automator/install.py` around lines 31 - 35, The HOOK_MARKER constant uses
a broad substring match of "bmad_auto" which can incorrectly identify unrelated
commands as already-managed hooks. Replace the substring-based marker approach
with explicit matching for the exact managed hook script basenames:
bmad_auto_hook.py and bmad_auto_probe_hook.py. Update all locations where
HOOK_MARKER is used (including lines 81-85 referenced in the comment) to check
for these specific script names instead of a substring match, ensuring the
deduplication logic only applies to the actual managed hook scripts and remains
idempotent.

Comment thread src/automator/probe.py
Comment on lines +507 to +512
if not shutil.which("tmux") or not shutil.which(binary):
missing = "tmux" if not shutil.which("tmux") else binary
finding.warnings.append(f"{missing} not on PATH — cannot probe; falling back to scan")
scanned = scan(cli=cli, profile=profile, project=project, hints=hints)
scanned.mode = "probe"
return scanned

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the downgrade reason when --probe falls back to scan.

The tmux/binary-missing warning is appended to finding and then discarded by returning scanned, so users can lose the actual reason probe mode didn’t run.

Proposed fix
     if not shutil.which("tmux") or not shutil.which(binary):
         missing = "tmux" if not shutil.which("tmux") else binary
-        finding.warnings.append(f"{missing} not on PATH — cannot probe; falling back to scan")
+        fallback_warning = f"{missing} not on PATH — cannot probe; falling back to scan"
         scanned = scan(cli=cli, profile=profile, project=project, hints=hints)
         scanned.mode = "probe"
+        scanned.warnings.insert(0, fallback_warning)
         return scanned
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if not shutil.which("tmux") or not shutil.which(binary):
missing = "tmux" if not shutil.which("tmux") else binary
finding.warnings.append(f"{missing} not on PATH — cannot probe; falling back to scan")
scanned = scan(cli=cli, profile=profile, project=project, hints=hints)
scanned.mode = "probe"
return scanned
if not shutil.which("tmux") or not shutil.which(binary):
missing = "tmux" if not shutil.which("tmux") else binary
fallback_warning = f"{missing} not on PATH — cannot probe; falling back to scan"
scanned = scan(cli=cli, profile=profile, project=project, hints=hints)
scanned.mode = "probe"
scanned.warnings.insert(0, fallback_warning)
return scanned
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/automator/probe.py` around lines 507 - 512, When the tmux or binary check
fails in the conditional block starting with if not shutil.which("tmux"), a
warning is appended to the finding object but then discarded because the
function returns the scanned object instead. To preserve the downgrade reason,
transfer the warning message from finding.warnings to scanned.warnings before
returning scanned, ensuring users see why probe mode fell back to scan mode.

Comment thread src/automator/probe.py
Comment on lines +525 to +528
registrations = {
native: f"python3 {shlex.quote(str(hook_path))} {canonical}"
for native, canonical in profile.hooks.events.items()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pass the native event name into the probe hook command.

_collect_captures() treats argv_event as the native key and resolves canonical via events_map.get(native), but registration currently injects canonical into argv. This breaks native→canonical pairing when names differ.

Proposed fix
-        registrations = {
-            native: f"python3 {shlex.quote(str(hook_path))} {canonical}"
-            for native, canonical in profile.hooks.events.items()
-        }
+        registrations = {
+            native: f"python3 {shlex.quote(str(hook_path))} {shlex.quote(native)}"
+            for native in profile.hooks.events
+        }

Also applies to: 472-477

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/automator/probe.py` around lines 525 - 528, The registrations dictionary
is passing the canonical event name in the probe hook command string, but
_collect_captures() expects to receive the native event name as argv_event to
perform the canonical lookup via events_map.get(native). In the f-string that
builds the command for each registration entry, replace the use of canonical
with native as the argument passed to the hook_path command.

Comment thread src/automator/probe.py
Comment on lines +602 to +605
finding.warnings.append(
f"--keep-temp: RAW probe data retained at {tmpdir} — DO NOT SHARE; "
"delete it after inspection"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Sanitize the --keep-temp path before adding it to warnings.

This warning currently embeds a raw filesystem path in the report, bypassing the sanitizer contract and potentially leaking home-directory data.

Proposed fix
         if keep_temp:
+            safe_tmpdir = sanitize.redact_home(str(tmpdir))
             finding.warnings.append(
-                f"--keep-temp: RAW probe data retained at {tmpdir} — DO NOT SHARE; "
+                f"--keep-temp: RAW probe data retained at {safe_tmpdir} — DO NOT SHARE; "
                 "delete it after inspection"
             )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
finding.warnings.append(
f"--keep-temp: RAW probe data retained at {tmpdir} — DO NOT SHARE; "
"delete it after inspection"
)
if keep_temp:
safe_tmpdir = sanitize.redact_home(str(tmpdir))
finding.warnings.append(
f"--keep-temp: RAW probe data retained at {safe_tmpdir} — DO NOT SHARE; "
"delete it after inspection"
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/automator/probe.py` around lines 602 - 605, The warning message being
appended to finding.warnings in this code block directly embeds the raw tmpdir
path without sanitization, which can leak sensitive filesystem information.
Apply the appropriate path sanitization function to the tmpdir variable before
including it in the f-string message passed to the append method. This ensures
the warning message follows the same sanitization contract as other parts of the
report.

@pbean pbean merged commit 90ed250 into main Jun 21, 2026
7 checks passed
@pbean pbean deleted the release/0.6.2 branch June 21, 2026 17:20
This was referenced Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant