strip_comments(content) removes [//]: # (...) link-reference comments and
<!-- ... --> HTML comments from document content, while preserving agent
range markers (<!-- agent:* -->). Comment patterns inside fenced code blocks
and inline backtick spans are not treated as comment syntax.
compute(doc) reads the on-disk snapshot for doc, waits for stable content
via wait_for_stable_content, strips comments from both sides, and returns a
unified diff (5-line context, header snapshot→document) or None when
there are no changes. Stale-snapshot recovery fires before emitting a diff:
if the delta contains only completed assistant/user exchanges with an empty
trailing user block, the snapshot is synced to the document and None is returned.
wait_for_stable_content(doc, previous) polls the document file until the
last inserted line looks complete (not mid-word/mid-URL) or up to 12 × 500 ms
rechecks (~6 s). Three consecutive identical reads constitute “stable”.
is_stale_snapshot(snapshot, document) returns true when the document is a
superset of the snapshot, the extra content contains at least one ## Assistant
block, and the trailing ## User block is empty.
run(file, wait) is the CLI entry point for the diff subcommand. When wait
is true it runs truncation detection first, then calls compute and prints
the result to stdout.
annotate_diff(diff_text) transforms a unified diff into an annotated format
with content-source markers: [agent], [user+], [user-], [user~].
Returns None if the diff is empty. Pure function, no I/O.
classify_diff(diff_text) classifies a unified diff into a DiffType with a
human-readable reason string. Types: Approval (single word: go/yes/do/ok/continue),
SimpleQuestion (single added line ending with ?), BoundaryArtifact (only
(HEAD) or boundary UUID changes), Annotation (edits within agent content),
StructuralChange (only deletions/reorgs), MultiTopic (multiple unrelated
added blocks), ContentAddition (general new content).
Comment stripping is idempotent: calling strip_comments twice yields the same
result as calling it once.
Agent markers are always preserved by strip_comments; the skill can rely on
their presence in the stripped output.
compute never writes to the document file; it may write to the snapshot file
only during stale-snapshot recovery. A copy-on-read guard compares the snapshot
file’s mtime at read time against its mtime before recovery write — if an
external process modified the snapshot mid-diff, recovery is skipped.
compute returns None (no diff) if and only if there are no meaningful
content changes after comment stripping.
wait_for_stable_content always terminates: the MAX_RECHECKS bound guarantees
it returns within ~6 s regardless of file activity.
looks_truncated never returns true for empty strings, markdown headings,
slash commands, or fenced code fences. Single characters (including alphanumeric)
are always treated as truncated — the stability check confirms completion.
Callers of compute can assume: Some(diff) → there is user-visible content
to respond to; None → skip the response cycle.
classify_diff is pure and deterministic: same diff text always yields the same
DiffType and reason. It operates only on the diff string, never reads files.
classify_content_addition: general new content → DiffType::ContentAddition
classify_annotation: colon-appended edit to agent line → DiffType::Annotation
parse_slash_commands(diff): extracts slash commands from added lines in a unified diff
with guards against: code fences (``` / ~~~), blockquotes (>), HTML comments, and
non-added lines. Returns a vec of command strings (e.g. ["/clear", "/agent-doc foo.md"]).
detect_prompt_preset_requests(diff): extracts ordered preset <name> / presets <a>, <b>
directives from user-added diff lines, ignoring code fences and blockquotes.
extract_prompt_preset_requests_from_text(text): text-mode companion used by orchestration
task extraction for batch-level preset directives outside unified diffs.
parse_slash_commands_simple: single added /clear line → ["/clear"]
parse_slash_commands_ignores_fenced: /cmd inside a ``` block → empty
extract_imperative_directives(diff): finds added user directive lines like do #id,
run tests, build + install, commit + push, or pending-item prose like
[#id] Fix the cross-repo ..., skipping code fences and blockquotes
diff_contains_imperative_directive(diff): true when the diff contains either an explicit
imperative directive line or a one-word approval like go
classify_prompt_bearing_changes(diff): extracts ordered user-authored changes that need
prompt-aware handling. Each item is typed as prompt_target, content_edit,
recovery_artifact, or boundary_artifact.
extract_required_response_blocks_multiple_prompts: changed exchange tail with two prompt
starts → both blocks returned oldest-first
extract_required_response_blocks_preserves_code_fence_context: prompt block followed by an
added fenced code block → returned block keeps the fence content intact
format_prompt_bearing_changes_mentions_turn_completeness: rendered section includes the
“do not stop at the newest question” contract plus edit/artifact handling guidance
extract_required_response_blocks(diff): extracts ordered user request blocks from added
diff lines (for example ❯ prompts, questions, or imperative directives) so prompt builders
can restate the full changed exchange tail instead of anchoring only on the newest question
format_required_response_targets(diff): compatibility wrapper that returns only the
prompt_target blocks from classify_prompt_bearing_changes
format_prompt_bearing_changes(diff): renders the typed change list into a prompt-ready
section with explicit turn-completeness and edit/artifact instructions
text_line_looks_like_prompt_target("❯ **Verification:** passed") → false;
known assistant response labels are recognized after optional prompt glyph,
list marker, and markdown emphasis normalization.
True when the change is entirely a managed-component state mutation:
queue activity toggle, queue body item (add/strike), backlog item line,
or done item line. These edits are routine session bookkeeping, not
real user prompts, so the Claude Code auto-loop guard treats them as
non-blocking. Plan: #ccloopguard.
Return the slash commands when every substantive added diff line is a slash
command outside fences and blockquotes. Returns None for mixed prompt text,
fenced examples, blockquotes, or diffs with no slash commands.