tabletop

star 0

Interactive Markdown document review with visual annotation UI and live agent feedback loop. Opens a browser page for section-level annotations. When the user submits annotations, the agent receives them, responds in-page, and the conversation persists alongside the document. Trigger on: "review this doc", "review this document", "标注这个文档", "帮我审阅这个方案", "review the plan", "交互式审阅", "doc review", "批注这个文件", "标注一下".

yuanhaorannnnnn By yuanhaorannnnnn schedule Updated 6/1/2026

name: Tabletop description: | Interactive Markdown document review with visual annotation UI and live agent feedback loop. Opens a browser page for section-level annotations. When the user submits annotations, the agent receives them, responds in-page, and the conversation persists alongside the document.

Trigger on: "review this doc", "review this document", "标注这个文档", "帮我审阅这个方案", "review the plan", "交互式审阅", "doc review", "批注这个文件", "标注一下".

Doc Review

Workflow

Step 1: Start server + open page

# Pre-check: server.py must exist
test -f ~/.agents/repos/projects/review/server.py || { echo "server.py not found"; exit 1; }
# Start if not already running
lsof -i :8766 >/dev/null 2>&1 || python3 ~/.agents/repos/projects/review/server.py &
open http://localhost:8766/?file=<absolute-path-to-md>

Step 2: Enter review loop

Call the long-poll endpoint and block until the user submits annotations:

curl -s "http://localhost:8766/api/wait?file=<path>" | python3 -c "
import sys, json
state = json.load(sys.stdin)
if state.get('ready'):
    print(json.dumps(state['annotations'], indent=2))
"

When annotations arrive (after up to 120s), read them.

Step 3: Respond to annotations

For each annotation, address it directly. Then post your reply back to the page:

curl -s -X POST "http://localhost:8766/api/reply?file=<path>" \
  -H "Content-Type: application/json" \
  -d '{"text":"<your markdown response>"}'

Step 4: Loop back to Step 2

Go back to /api/wait — the user may annotate again based on your reply. Repeat until the user stops (timeout returns ready: false).

Step 5: Save the review conversation

After the loop ends, save the full conversation as a .review.md alongside the original document:

python3 -c "
import json, pathlib
p = pathlib.Path('<path>')
annos = json.load(open(p.parent / f'{p.stem}.annotations.json'))
reps = json.load(open(p.parent / f'{p.stem}.replies.json'))
with open(p.parent / f'{p.stem}.review.md', 'w') as f:
    f.write(f'# Review: {p.name}\n\n')
    f.write('## Annotations\n\n')
    for a in annos:
        f.write(f'- **[{a[\"sectionTitle\"]}]** {a[\"text\"]}\n')
    f.write('\n## Agent Replies\n\n')
    for r in reps:
        f.write(f'{r[\"text\"]}\n\n---\n')
print(f'Saved to {p.stem}.review.md')
"

File Layout (alongside the reviewed document)

File Contents
<doc>.annotations.json User's section annotations
<doc>.replies.json Agent's replies
<doc>.review.md Combined human-readable review log

Canon 输出边界

读取共享契约:/home/yhr/.agents/repos/agent-skills/references/canon-output-contract.md

  • Review UI state and annotations are review artifacts. Promote accepted decisions, action items, or document risks to Canon; do not copy transient annotation state by default.
  • Canon update-card path, when needed: /media/yhr/2T/Canon/raw/update-cards/<date>-tabletop-<topic>.md.
Install via CLI
npx skills add https://github.com/yuanhaorannnnnn/agent-skills --skill tabletop
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
yuanhaorannnnnn
yuanhaorannnnnn Explore all skills →