myscript/iinkts/symbol-system

Claude Code and agent skill by myscript/iinkts

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Deep guide to the iinkTS symbol system: TSymbol union, type guards, the Ops/Util two-layer pattern, SymbolFactory, symbolRegistry. Use when writing type-safe symbol code, adding symbol behavior, or debugging type confusion between variants.

Install

npx vskill@latest install myscript/iinkts/symbol-system

SKILL.md

Symbol System

Hierarchy

TSymbol (union, src/symbol/Symbol.ts)
├── TStroke — raw ink stroke
├── TText — recognized text
├── TMath — math formula
├── TDecorator — edge/arrow decorator
├── TEdge (union) — TEdgeLine, TEdgeArc, TEdgePolyLine, TAnchor (smart connectors)
└── TShape (union) — TShapeCircle, TShapeEllipse, TShapePolygon

Not in `TSymbol`: TEraser (separate), legacy Stroke/CanvasSymbol (deprecated v1, src/symbol/legacy/), TPoint/TBox/OBB (primitives).

Two layers of per-type logic

  1. `*Ops` — pure functions/objects co-located with the type definition in src/symbol/{type}/{Type}.ts: StrokeOps, TextOps, MathOps, DecoratorOps, EraserOps, BoxOps, ShapeOps, EdgeOps. This is where create/update/overlap logic actually lives — usable standalone, no registry dependency.
  2. `*Util` — adapter classes in src/symbol-utils/{type}/{Type}Util.ts (StrokeUtil, TextUtil, MathUtil, ShapeUtil, EdgeUtil, DecoratorUtil), extending abstract SymbolUtil. Mostly delegate to the matching *Ops, plus implement getSVGElement() for rendering. All 6 register into symbolRegistry via registerBuiltinSymbolUtils().

SVGRenderer dispatches rendering with symbolRegistry.getUtil(symbol.type).getSVGElement(symbol) — no switch on SymbolType in the renderer.

Type Guards

Co-located with each type, not centralized:

typescript
import { isStroke, isRecognizedMath, isRecognizedText } from "@/symbol/stroke/Stroke"
import { isText } from "@/symbol/text/Text"
import { isMath } from "@/symbol/math/Math"
import { isDecorator } from "@/symbol/decorator/Decorator"
// Narrow before accessing type-specific properties
if (isStroke(symbol)) {
symbol.pointers // now typed as TStroke
}

If a type guard you need doesn't exist, add it next to the type definition — never inline symbol.type === "..." checks.

Note: src/symbol/SymbolHelpers.ts is NOT a dispatcher — it only exports cloneSymbol() (via structuredClone). The real per-type dispatch is symbolRegistry in src/symbol-utils/.

IIModel Interactions

IIModel stores symbols in a Map<string, TSymbol> (keyed by symbol.id):

typescript
model.addSymbol(symbol) // adds to map + updates bounding box cache
model.getSymbol(id) // returns TSymbol | undefined
model.symbols // returns TSymbol[] (from map values)
model.removeSymbol(id)
model.updateSymbol(symbol) // replace by id

Cache invalidation: IIModel caches bounding boxes. After bulk mutations, call model.resetBoundingBox().

SymbolFactory

Use SymbolFactory (src/symbol-utils/SymbolFactory.ts) to create symbols — never construct a type literal directly:

typescript
import { SymbolFactory } from "@/symbol-utils"

Creating symbols by hand bypasses ID generation and default style merging.

Common Mistakes

MistakeFix
symbol.type === "stroke" inline checkUse isStroke(symbol) from @/symbol/stroke/Stroke
Assuming SymbolHelpers dispatches by typeIt only has cloneSymbol() — use symbolRegistry
Branching on SymbolType in a manager/rendererAdd/extend the type's *Ops/*Util pair instead
Mutating model.symbols array directlyUse model.addSymbol() / model.removeSymbol()
Looking for per-type logic in src/symbol/ onlyRendering + capability flags live in src/symbol-utils/

Adding a New Symbol Type

See the add-symbol-type skill for the full step-by-step (enum → type+Ops → Util adapter → registry → renderer → tests).

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/myscript/iinkts/symbol-system/badge)](https://verified-skill.com/skills/myscript/iinkts/symbol-system)

Something wrong with this skill or its page? Tell us.