agentleFS
dylanroscoverdylanroscover/Embody/.claude/skills/manage-annotations/SKILL.md

manage-annotations

Skill213 starsChanged 2 months agoMITView on GitHub

MUST READ before creating, modifying, or querying annotations. Contains parameter names, coordinate model, and API quirks.

The file

Files
SKILL.md
<!-- Generated by Embody/Envoy - Do not remove this comment - sha:ba9799e3ea1e5758 -->

Manage Annotations Workflow

Creating Annotations

create_annotation(
    parent_path='/path/to/network',
    mode='annotate',     # 'annotate' (title bar), 'comment', or 'networkbox'
    title='My Group',
    text='Description of this group',
    x=..., y=..., width=..., height=...,
    color=[r, g, b],     # Optional, floats 0-1
    opacity=0.5           # Optional
)

Always favor annotations over OP comments for documenting operators or groups.

Enclosing Operators

To create an annotation that encloses a group of operators:

  1. Get positions: get_network_layout on the parent COMP (includes all operator positions and bounding box)
  2. Calculate bounding box: Find min_x, max_x, min_y, max_y (max includes operator width/height: max_x = max(op_x + op_w), max_y = max(op_y + op_h))
  3. Add padding: 70 units on left/right/bottom, 170 units on top (title bar + body text)
  4. Set coordinates:
    • nodeX = min_x - 70
    • nodeY = min_y - 70 (BELOW operators, not above!)
    • nodeWidth = max_x - min_x + 140
    • nodeHeight = max_y - min_y + 240 (70 bottom + 170 top)

Coordinate Model

  • nodeX/nodeY = bottom-left corner, width/height extend rightward and upward
  • Title bar renders at the top of the rectangle
  • Common mistake: Setting nodeY above the operators. nodeY must be BELOW (less than) the lowest operator's Y.

Querying

  • get_annotations - list all annotations in a COMP with properties and enclosed operators
  • get_enclosed_ops - get operators enclosed by an annotation, or annotations enclosing an operator
  • set_annotation - modify text, title, color, opacity, position, or size

Deleting Annotations

Delete via delete_op, never via raw .destroy() in execute_python. delete_op resolves utility annotations, purges any tracking, and arms an auto-save checkpoint that re-exports the parent TDXN COMP's .tdxn without the annotation -- the deletion is durable. A raw .destroy() leaves the stale annotations: entry in the parent's .tdxn on disk, and the next reimport of that COMP (import_network, manager Reload, or cold open) resurrects the annotation with its pre-delete text.

annotateCOMP Quirks

  • utility is True for every annotation -- TD UI-drawn ones are born that way, create_annotation sets it, and TDXN import applies it on every annotation it recreates. (A bare Python parent.create('annotateCOMP') is utility=False -- set ann.utility = True immediately to match; a non-utility annotation is an ordinary COMP subtree that enumeration sweeps will walk into.)
  • utility=True hides the op from op(), parent.op(), AND .children -- only findChildren(includeUtility=True) sees it, and a deep findChildren does not even DESCEND into a utility annotate's subtree unless includeUtility=True is passed (verified live, TD 2025.33070). Paths THROUGH a utility annotate to its interior ops still resolve via op().
  • Every Envoy op-path tool resolves utility annotations (delete_op, set_parameter, set_op_position, get_op, ... -- they share one utility-aware resolver). For DISCOVERY, use get_annotations (always sees them) or pass include_utility=True to query_network/find_children -- with the default False, annotations are invisible in those listings.
  • Annotations are never externalized per-op -- they round-trip through the parent TDXN COMP's semantic annotations: section. externalize_op refuses them, and tagging sweeps skip them and their internals (the widget internals are TD-managed stock content cloned from TDAnnotate).
  • envoy_bot_* is reserved for Embot, the mascot Envoy stands on the operator it is working on (the Embot parameter). The read tools hide those parts and report how many as embot_hidden; Embody strips them from every saved file and deletes loose ones on save. Never create, move, edit or delete an annotation with that prefix -- and never name one of yours that way, or it will be deleted as an artifact.
  • .type returns 'annotate' (not 'annotateCOMP')
  • findChildren(type=annotateCOMP) requires the class object, not the string
  • Cannot be reliably renamed after creation (TD also ignores a name passed at create time -- rename right after creating instead)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.