Agent Instructions #

This project uses bd (beads) for issue tracking. Run bd prime for full workflow context.

Architecture in one line: Issues live in a local Dolt database (.beads/dolt/); cross-machine sync uses bd dolt push/pull (a git-compatible protocol), stored under refs/dolt/data on your git remote — separate from refs/heads/* where your code lives. .beads/issues.jsonl is a passive export, not the wire protocol.

See SYNC_CONCEPTS.md for the one-screen overview and anti-patterns (don't treat JSONL as the source of truth; don't bd import during normal operation; don't reach for third-party Dolt hosting before trying the default).

Quick Reference #

bd ready              # Find available work
bd show <id>          # View issue details
bd update <id> --claim  # Claim work atomically
bd close <id>         # Complete work
bd dolt push          # Push beads data to remote

Non-Interactive Shell Commands #

ALWAYS use non-interactive flags with file operations to avoid hanging on confirmation prompts.

Shell commands like cp, mv, and rm may be aliased to include -i (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input.

Use these forms instead:

# Force overwrite without prompting
cp -f source dest           # NOT: cp source dest
mv -f source dest           # NOT: mv source dest
rm -f file                  # NOT: rm file

# For recursive operations
rm -rf directory            # NOT: rm -r directory
cp -rf source dest          # NOT: cp -r source dest

Other commands that may prompt:

  • scp - use -o BatchMode=yes for non-interactive
  • ssh - use -o BatchMode=yes to fail instead of prompting
  • apt-get - use -y flag
  • brew - use HOMEBREW_NO_AUTO_UPDATE=1 env var

Beads Issue Tracker #

This project uses bd (beads) for issue tracking. Run bd prime to see full workflow context and commands.

Quick Reference #

bd ready              # Find available work
bd show <id>          # View issue details
bd update <id> --claim  # Claim work
bd close <id>         # Complete work

Rules #

  • Use bd for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
  • Run bd prime for detailed command reference and session close protocol
  • Use bd remember for persistent knowledge — do NOT use MEMORY.md files

Architecture in one line: issues live in a local Dolt DB; sync uses refs/dolt/data on your git remote; .beads/issues.jsonl is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.

Session Completion #

When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.

MANDATORY WORKFLOW:

  1. File issues for remaining work - Create issues for anything that needs follow-up
  2. Run quality gates (if code changed) - Tests, linters, builds
  3. Update issue status - Close finished work, update in-progress items
  4. PUSH TO REMOTE - This is MANDATORY:
    git pull --rebase
    git push
    git status  # MUST show "up to date with origin"
    
  5. Clean up - Clear stashes, prune remote branches
  6. Verify - All changes committed AND pushed
  7. Hand off - Provide context for next session

CRITICAL RULES:

  • Work is NOT complete until git push succeeds
  • NEVER stop before pushing - that leaves work stranded locally
  • NEVER say "ready to push when you are" - YOU must push
  • If push fails, resolve and retry until it succeeds

Beads Issue Tracker #

Use Beads (bd) for durable task tracking in repositories that include it. Use the beads skill at .agents/skills/beads/SKILL.md (project install) or ~/.agents/skills/beads/SKILL.md (global install) for Beads workflow guidance, then use the bd CLI for issue operations.

Quick Reference #

bd ready                # Find available work
bd show <id>            # View issue details
bd update <id> --claim  # Claim work
bd close <id>           # Complete work
bd prime                # Refresh Beads context

Rules #

  • Use bd for all task tracking; do not create markdown TODO lists.
  • Run bd prime when Beads context is missing or stale.
  • Keep persistent project memory in Beads via bd remember; do not create ad hoc memory files.

Project Guide & Tech Stack #

Tech Stack #

  • Runtime: Deno 2.x (use deno install, deno task, etc., NEVER use npx or npm directly unless necessary)
  • Framework: Svelte 5 (uses Runes like $state, $derived, $effect)
  • Virtualization: @tanstack/svelte-virtual (replaces old @tutorlatin/svelte-tiny-virtual-list)
  • Styling: Tailwind CSS v4

Virtualization Guidelines (TanStack Virtual) #

When implementing list/timeline virtualization, follow these patterns to prevent bugs and Svelte 5 compilation warnings:

  1. Reactivity & Options Updates: To avoid Svelte 5 "capturing local state" warnings, initialize the virtualizer with count: 0 and update it reactively using $effect and $virtualizer.setOptions(...):

    let parentRef = $state<HTMLDivElement | null>(null);
    
    const virtualizer = createVirtualizer({
    	count: 0,
    	getScrollElement: () => parentRef,
    	estimateSize: () => 44,
    	overscan: 5
    });
    
    $effect(() => {
    	$virtualizer.setOptions({
    		count: items.length,
    		getScrollElement: () => parentRef,
    		estimateSize: () => 44,
    		overscan: 5
    	});
    });
    
  2. Dynamic Height Measurement: Always provide getItemKey using a unique identifier (like post/thread URI) to prevent cache collisions when the list changes. Use a Svelte action use:measureElement to measure DOM nodes dynamically:

    const measureElement = (node: HTMLElement) => {
    	$virtualizer.measureElement(node);
    };
    

    And in the markup, set data-index and use the action:

    <div
    	data-index={virtualItem.index}
    	use:measureElement
    	style="position: absolute; top: 0; left: 0; width: 100%; transform: translateY({virtualItem.start}px);"
    >
    	<!-- content -->
    </div>
    
  3. Reactive Scrolling: To scroll to a target index reactively, use an $effect:

    $effect(() => {
    	if (scrollToIndex !== undefined) {
    		$virtualizer.scrollToIndex(scrollToIndex);
    	}
    });