Core development
Work on the core package (types, validation, normalization, diff). Use when modifying DSL processing logic, adding new node/edge properties, changing validation rules, or updating the diff algorithm.From its SKILL.md
npx -y skills add 7nohe/figram --skill core-developmentAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.9 KB, 950 tokens by cl100k_base, as published. Nobody here has run it
Core Package Development
The core package (packages/core/) is dependency-free and handles all DSL processing.
Data Flow
DSL (YAML input) → validate() → normalize() → IR → diff() → Patch
Key Files
| File | Purpose | Exports |
|---|---|---|
types.ts | Type definitions | DSL*, IR*, Patch, WebSocket protocol |
validate.ts | YAML validation | validate(dsl): ValidationResult |
normalize.ts | DSL → IR conversion | normalize(dsl): IRDocument |
diff.ts | IR diff calculation | diff(prev, next): Patch |
Type Hierarchy
DSL Types (user input) IR Types (normalized)
───────────────────── ────────────────────
DSLDocument IRDocument
├─ version: number ├─ version: number
├─ docId: string ├─ docId: string
├─ title?: string ├─ title: string
├─ nodes: DSLNode[] ├─ nodes: Record<string, IRNode>
└─ edges?: DSLEdge[] └─ edges: Record<string, IREdge>
DSLNode IRNode
├─ id: string ├─ id: string
├─ provider: string ├─ provider: string
├─ kind: string ├─ kind: string
├─ label?: string ├─ label: string (default: id)
├─ parent?: string ├─ parent: string | null
└─ layout: DSLLayout └─ layout: { x, y, w, h }
DSLEdge IREdge
├─ id: string ├─ id: string
├─ from: string ├─ from: string
├─ to: string ├─ to: string
└─ label?: string └─ label: string (default: "")
Patch Operations
type PatchOp =
| { op: "upsertNode"; node: IRNode }
| { op: "removeNode"; id: string }
| { op: "upsertEdge"; edge: IREdge }
| { op: "removeEdge"; id: string };
interface Patch {
baseRev: number;
nextRev: number;
ops: PatchOp[];
}
WebSocket Protocol Types
// Plugin → CLI
interface HelloMessage {
type: "hello";
docId: string;
secret?: string;
}
interface RequestFullMessage {
type: "requestFull";
docId: string;
}
// CLI → Plugin
interface FullMessage {
type: "full";
rev: number;
ir: IRDocument;
}
interface PatchMessage {
type: "patch";
baseRev: number;
nextRev: number;
ops: PatchOp[];
}
interface ErrorMessage {
type: "error";
message: string;
}
Development Workflow
- Modify types → Update
types.ts - Update validation → Ensure
validate.tscatches invalid input - Update normalization → Handle new fields/defaults in
normalize.ts - Update diff → Handle new patch scenarios in
diff.ts - Add tests → Co-located
*.test.tsfiles - Run tests →
bun test packages/core/
Testing
# All core tests
bun test packages/core/
# Specific test file
bun test packages/core/src/diff.test.ts
bun test packages/core/src/validate.test.ts
bun test packages/core/src/normalize.test.ts
# Watch mode
bun test --watch packages/core/
Common Patterns
Adding a new node property
- Add to
DSLNodeandIRNodeintypes.ts - Add validation in
validate.ts - Add default value handling in
normalize.ts - Update diff logic if property affects equality
- Add test cases for validation, normalization, and diff
Adding a new edge property
- Add to
DSLEdgeandIREdgeintypes.ts - Add validation in
validate.ts - Add default value handling in
normalize.ts - Update diff logic for edge equality check
- Add test cases