diff --git a/src/void_tools/cli.py b/src/void_tools/cli.py index e8c1bb1..add6206 100644 --- a/src/void_tools/cli.py +++ b/src/void_tools/cli.py @@ -6,6 +6,7 @@ import sys import os import json import yaml +import hashlib from atproto import models from void_tools.client import get_client @@ -104,6 +105,13 @@ def cmd_sync(args): { "action": "post", "posts": ["Standalone post"] + }, + { + "action": "annotate", + "target_id": "notif_0", + "text": "Internal context or observation about this post.", + "motivation": "commenting", + "quote": "optional exact text to highlight" } ] } @@ -137,12 +145,11 @@ def cmd_dispatch(args): for act in actions: action_type = act.get("action") - posts = act.get("posts", []) - if not posts: - continue - if action_type == "post": + posts = act.get("posts", []) + if not posts: + continue print("Dispatching standalone post/thread...") root_ref = None parent_ref = None @@ -184,6 +191,54 @@ def cmd_dispatch(args): except Exception as e: print(f"Error replying to {target_uri}: {e}") + + elif action_type == "annotate": + target_id = act.get("target_id") + text = act.get("text") + + if target_id not in mapping: + print(f"Error: target_id {target_id} not found in mapping. Skipping annotation.") + continue + if not text: + print("Error: annotation requires 'text' field. Skipping.") + continue + + target_uri = mapping[target_id] + print(f"Dispatching annotation to {target_uri}...") + + try: + source_hash = hashlib.sha256(target_uri.encode()).hexdigest() + record = { + "$type": "at.margin.annotation", + "createdAt": client.get_current_time_iso(), + "target": { + "source": target_uri, + "sourceHash": source_hash, + }, + "body": { + "value": text + }, + "motivation": act.get("motivation", "commenting") + } + + quote = act.get("quote") + if quote: + record["target"]["selector"] = { + "type": "TextQuoteSelector", + "exact": quote + } + + resp = client.com.atproto.repo.create_record({ + 'repo': client.me.did, + 'collection': 'at.margin.annotation', + 'record': record + }) + print(f" Annotated: {resp.uri}") + except Exception as e: + print(f"Error annotating {target_uri}: {e}") + + else: + print(f"Unknown action type: {action_type}") config = outbox.get("config", {}) if config.get("mark_seen"):