Skip to main content

Module diff

Module diff 

Source
Expand description

§Module: diff

§Spec

  • 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).

§Agentic Contracts

  • 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.

§Evals

  • strip_html_comment: "before\n<!-- a comment -->\nafter\n" → "before\nafter\n"
  • strip_multiline_html_comment: multiline <!-- ... --> on its own lines → stripped with surrounding newlines preserved
  • strip_link_ref_comment: "[//]: # (note)\n" on its own line → removed entirely
  • preserve_agent_markers: <!-- agent:status --> and <!-- /agent:status --> → unchanged
  • strip_inline_comment: inline <!-- note --> in middle of line → comment removed, surrounding text retained
  • strip_preserves_comment_syntax_in_fenced_code_block: <!-- not a comment --> inside triple-backtick fence → unchanged
  • strip_preserves_comment_syntax_in_inline_backticks: `<!--` in inline code → not treated as comment start
  • strip_backtick_comment_before_agent_marker: `<!--` text followed by <!-- /agent:exchange --> → agent marker not consumed
  • stale_snapshot_detects_completed_exchange: snapshot + completed assistant/user cycle with empty trailing user block → is_stale_snapshot returns true
  • stale_snapshot_false_when_user_has_new_content: trailing ## User block has text → is_stale_snapshot returns false
  • stale_snapshot_ignores_comments_in_detection: scratch comments between exchanges → still detected as stale
  • copy_on_read_guard_skips_recovery_when_snapshot_modified: mtime comparison logic — same mtime allows recovery, different mtime blocks it, both-None allows it
  • compute_stale_snapshot_recovery_proceeds_when_unmodified: stale snapshot (base + completed exchange) → recovery fires, returns None, snapshot synced
  • compute_stale_recovery_updates_snapshot_to_current_document: after recovery, snapshot content matches document
  • compute_returns_diff_when_user_adds_content: user adds new content → returns diff containing the addition
  • compute_returns_none_when_no_changes: identical snapshot and document → returns None
  • diff_detects_user_edits_after_stream_write: snapshot saved post-stream, user adds line → compute returns Some(diff) containing new text
  • diff_no_change_when_document_matches_snapshot: document identical to snapshot → compute returns None
  • truncated_mid_sentence: line ending mid-word → looks_truncated returns true
  • not_truncated_complete_sentence: line ending with . → looks_truncated returns false
  • not_truncated_single_word_command: bare word like "release" → looks_truncated returns false
  • truncated_single_chars: single characters like "A", "S", "1" → looks_truncated returns true (stability check required)
  • wait_for_stable_content_returns_immediately_when_complete: already-complete content → returns in < 500 ms
  • annotate_diff_additions: added lines get [user+] markers
  • annotate_diff_removals: removed lines get [user-] markers
  • annotate_diff_modifications: paired add/remove with similar content get [user~] markers
  • annotate_diff_context: context lines get [agent] markers
  • annotate_diff_empty: empty diff returns None
  • classify_approval: single added word “go” → DiffType::Approval
  • classify_approval_case_insensitive: “Yes” → DiffType::Approval
  • classify_simple_question: single added line “what is X?” → DiffType::SimpleQuestion
  • classify_boundary_artifact: only (HEAD) marker change → DiffType::BoundaryArtifact
  • classify_boundary_uuid: only boundary UUID change → DiffType::BoundaryArtifact
  • classify_structural_change: only deletions → DiffType::StructuralChange
  • classify_multi_topic: multiple separated added blocks → DiffType::MultiTopic
  • 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
  • parse_slash_commands_ignores_blockquote: > /cmd → empty
  • parse_slash_commands_ignores_context_lines: /cmd on context line ( ) → empty
  • parse_slash_commands_ignores_removed_lines: /cmd on removed line (-) → empty
  • parse_slash_commands_with_args: /agent-doc foo.md → ["/agent-doc foo.md"]
  • parse_slash_commands_requires_letter_after_slash: / , //comment → empty
  • detect_prompt_preset_requests_from_diff: added preset #1 and presets release-check, #2 lines → ordered unique preset names returned
  • extract_prompt_preset_requests_from_text_ignores_fences_and_blockquotes
  • 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.

Structs§

DiffClassification
Result of classifying a unified diff.
OrchestrationRequest
Structured natural-language orchestration request detected from the diff.
ParsedSlashCommands
Result of classifying slash commands from a diff.
PromptBearingChange
Ordered user-authored change that the harness should surface to the agent.

Enums§

DiffType
Classification of a user diff for skill routing.
OrchestrationRequestMode
Supported orchestration modes surfaced through preflight.
PromptBearingChangeKind
Canonical classification for user-authored prompt-bearing changes in a diff.

Functions§

annotate_diff
Annotate a unified diff with content-source markers.
change_is_managed_state_only
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.
classify_diff
Classify a unified diff into a DiffType with a human-readable reason.
classify_prompt_bearing_changes
detect_exchange_compaction_request
Detect whether the user explicitly requested exchange compaction in added diff lines.
detect_orchestration_request
Detect a natural-language orchestration request from user-added diff lines.
detect_prompt_preset_requests
Extract ordered unique prompt preset references from user-added diff lines.
detect_queue_trigger
Detect whether the user wrote do queue or run queue in an added diff line.
diff_contains_imperative_directive
Returns true when the diff contains an imperative work directive or a one-word approval that authorizes the next step.
extract_imperative_directives
Extract imperative user directives from added lines in a unified diff.
extract_inline_annotations
Extract user additions that appear within agent content (inline annotations).
extract_prompt_preset_requests_from_text
Extract ordered unique prompt preset references from plain text.
extract_required_response_blocks
Extract ordered user-authored request blocks from added diff lines.
first_bare_prompt_prefix_target
Return the first prompt-bearing line that should have had a ❯ prefix but did not.
format_prompt_bearing_changes
Render all prompt-bearing changes as a prompt-ready section.
format_required_response_targets
Render extracted request blocks as a prompt-ready turn-completeness section.
is_builtin_command
Returns true if the command is a Claude Code built-in (not invocable via Skill tool).
is_stale_snapshot
Detect whether the diff between snapshot and document is a stale snapshot (previous cycle wrote the response but didn’t update the snapshot).
line_looks_like_fresh_prompt_after_response
line_looks_like_markdown_list_item
line_looks_like_plain_response_after_prompt
line_looks_like_prompt_prefix_repair_start
line_looks_like_targeted_prompt_prefix_repair_start
parse_slash_command_only_added_diff
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.
parse_slash_commands
Extract slash commands from user-added lines in a unified diff.
parse_slash_commands_classified
Like parse_slash_commands but classifies results into skill vs built-in commands.
prompt_change_is_already_answered
prompt_change_is_answered_by_later_response
prompt_prefix_normalization_targets
Return the prompt-bearing exchange lines that must carry a ❯ prefix.
strip_comments
Strip comments from document content for diff comparison.
suppress_inactive_queue_additions
Return a copy of diff with user-added lines inside the current agent:queue component removed.
synthetic_added_lines_diff
Build a minimal unified diff from an in-memory prompt body.
text_line_looks_like_prompt_target
unified_diff_from_contents
Build a unified diff directly from two content strings after comment stripping.