Skip to content

Latest commit

 

History

History
151 lines (101 loc) · 8.23 KB

File metadata and controls

151 lines (101 loc) · 8.23 KB

AGENTS.md

This file provides guidance to AI agents when working with code in this repository.

What This Is

Time Machine Inspector is a macOS desktop app built with Tauri v1. It inspects Apple Time Machine backups and shows what changed between snapshots. The frontend is Svelte 4 + TypeScript; the backend is Rust. macOS Full Disk Access is required at runtime.

Commands

deno task dev        # Start dev mode (Tauri + Vite)
deno task dev:web    # Frontend only (no Tauri, browser)
deno task build      # Production build
deno task lint       # svelte-check + eslint + prettier check
deno task format     # eslint --fix + prettier --write
deno task test       # cargo test (Rust only)

Run a single Rust test:

cargo test --manifest-path ./src-tauri/Cargo.toml <test_name>

Architecture

Tauri IPC bridge

Rust #[command] functions in src-tauri/src/ are exposed to the frontend via Tauri's invoke_handler. In dev mode, main.rs runs tauri_specta::ts::export(...) which regenerates bindings.ts at the project root — this file is the auto-generated TypeScript type layer for all IPC commands.

src/lib/commands.ts wraps the generated bindings in a Proxy that automatically calls errorPopup on any IPC error, so all frontend IPC calls go through commands.<methodName>(...).

Rust backend modules

File Responsibility
main.rs Tauri setup, menu, error_popup command, specta export
cmd.rs Core IPC commands: load_backup_list, get_backup, backups_info; shared state (DestinationsState, LoadedBackups)
listbackups.rs Calls tmutil to enumerate destinations and backups
destinationinfo.rs destinationinfo command — reads Time Machine plist for destination metadata
compare.rs Diffs two backup snapshots (the heavy computation)
dir_map.rs Tree structure holding per-directory size deltas

Shared mutable state is stored in Tauri-managed Mutex structs (DestinationsState, LoadedBackups) and accessed via State<'_> in async commands.

Frontend state

src/page/page.ts holds Svelte stores for the currently viewed backup (page), loaded backup infos (backupInfos), the drill-down path (selectedPath), and the rendered directory map (pageMap). The backups store triggers a reload of backupInfos on every set.

Bindings regeneration

bindings.ts is only regenerated when running deno task dev (debug builds). After adding or changing a #[command] signature in Rust, run deno task dev once to refresh the file before touching frontend code.

Release Process

  1. Update CHANGELOG.md
  2. Bump version in src-tauri/Cargo.toml
  3. Run cargo check --manifest-path src-tauri/Cargo.toml to sync Cargo.lock
  4. Tag v#.#.# — GitHub Actions builds and publishes the release

<CRITICAL_INSTRUCTION>

BACKLOG WORKFLOW INSTRUCTIONS

This project uses Backlog.md MCP for all task and project management.

CRITICAL RESOURCE: Read backlog://workflow/overview to understand when and how to use Backlog for this project.

  • First time working here? Read the overview resource IMMEDIATELY to learn the workflow
  • Already familiar? You should have the overview cached ("## Backlog.md Overview (MCP)")
  • When to read it: BEFORE creating tasks, or when you're unsure whether to track work

Key MCP Commands

Command Purpose
task_create Create a new task (status defaults to "To Do")
task_edit Edit metadata, check ACs, update notes, change status
task_view View full task details
task_search Find tasks by keyword
task_list List tasks with optional filters
task_complete Moves task to backlog/completed/ — only use for cleanup, not for marking done

Task Lifecycle

  1. Create: task_create — new task in backlog/tasks/
  2. Start: task_edit(status: "In Progress") — mark as active
  3. Done: task_edit(status: "Done") — mark finished, stays in backlog/tasks/ (visible on kanban)
  4. Archive: task_complete — moves to backlog/completed/ (use only when explicitly cleaning up)

IMPORTANT: Use task_edit(status: "Done") to mark tasks as done. Do NOT use task_complete unless the user explicitly asks to archive/clean up — it removes the task from the kanban.

Preventing ID Collisions

Backlog.md does NOT enforce ID uniqueness on the filesystem. If two task files declare the same id: in their frontmatter, task_view/task_search silently resolve to whichever has the newer updated_date, hiding the other from the kanban and MCP lookups. This is how TASK-341 ended up with two owners (iOS-sync vs. Plex umbrella) in commit 89ff249.

Before creating any task, ALWAYS:

  1. Run task_list (or rg "^id: TASK-" backlog/tasks/ backlog/archive/tasks/ backlog/completed/) to find the highest existing ID.
  2. Let task_create auto-assign the next ID — never set id: manually in frontmatter or filenames.
  3. For subtasks, pass parentTaskId to task_create so Backlog.md generates the hierarchical ID (e.g., TASK-342.1) for you.

Detecting a collision:

rg -N "^id: " backlog/tasks/ backlog/archive/tasks/ backlog/completed/ \
  | awk -F': ' '{print $NF}' | sort | uniq -d

Resolving a collision: the MCP has no rename/change-id operation. Renumbering requires: (1) git mv the file to a new filename with the new ID; (2) edit the frontmatter id: field; (3) edit parent_task_id: if the task is a subtask whose parent was also renumbered (this field is NOT settable via task_edit); (4) edit dependencies: arrays in other tasks that reference the old ID; (5) verify with rg "^id: TASK-OLD$" backlog/tasks/ returning zero results.

Cross-Branch Task Scanning (disabled)

check_active_branches and remote_operations are both disabled in backlog/config.yml. With worktrees, these features scan other branches and pull in tasks that were already completed/archived on main but still exist in backlog/tasks/ on older branches — bloating the kanban with ghost tasks. Do not re-enable without accounting for worktree branch divergence.

Multiline Field Gotcha

The finalSummary, description, implementationNotes, and planSet MCP parameters are single-line JSON strings. Literal \n sequences are NOT interpreted as newlines — they render as the two characters \ n in the markdown file. To write multiline content:

  • Use task_edit with the field for short single-paragraph content
  • For multiline content, edit the task markdown file directly with the file editing tool (the file path is shown in task_view output)

Backlog MCP Parameter Reference (Common Pitfalls)

task_edit parameter names are different from task_create:

Operation task_create param task_edit param
Task ID — (auto-assigned) id (NOT taskId)
Title title title
Description description description
Acceptance Criteria acceptanceCriteria acceptanceCriteriaSet (replaces all), acceptanceCriteriaAdd, acceptanceCriteriaRemove, acceptanceCriteriaCheck, acceptanceCriteriaUncheck
Dependencies dependencies dependencies
Parent Task parentTaskId not supported — edit parent_task_id: in the markdown frontmatter directly
Status status status
Notes notesAppend, notesSet, notesClear
Plan planAppend, planSet, planClear
Final Summary finalSummary, finalSummaryAppend
References references references, addReferences, removeReferences
Documentation documentation documentation, addDocumentation, removeDocumentation

Common error: Using taskId instead of id, or acceptanceCriteria instead of acceptanceCriteriaSet in task_edit calls. Always use id and the acceptanceCriteria* variant names, and task_edit cannot re-parent — edit the file's parent_task_id: frontmatter directly when a parent ID changes.

The overview resource contains additional detail on decision frameworks, search-first workflow, and guides for task creation, execution, and completion.

</CRITICAL_INSTRUCTION>