openpencil/packages/core/src/tools/registry.ts
Danila Poyarkov f2ef9c976d
XPath query for node selection (#82)
* Add XPath query for node selection

- packages/core/src/xpath.ts: XPath engine using fontoxpath with custom
  DOM facade over SceneGraph nodes
- RPC command: 'query' with selector, page, limit params
- CLI command: 'open-pencil query <file> <xpath>' with --json, --page, --limit
- AI/MCP tool: 'query_nodes' with XPath examples in description
- Queryable attributes: name, width, height, x, y, visible, opacity,
  cornerRadius, fontSize, fontFamily, fontWeight, layoutMode, itemSpacing,
  padding*, strokeWeight, rotation, locked, blendMode, text, lineHeight,
  letterSpacing

* Add tests and docs for XPath query

- 9 unit tests for queryByXPath/matchByXPath core functions
- 6 tool tests for query_nodes AI/MCP tool
- README: query examples in CLI section
- VitePress docs: patterns, queryable attributes, example output
- CHANGELOG: feature entry

* Lazy-load fontoxpath to avoid bundling in desktop app

- Dynamic import() instead of static import for fontoxpath
- queryByXPath/matchByXPath now async (they were sync before)
- RpcCommand.execute allows R | Promise<R> for async commands
- Fix 2 lint errors (unnecessary optional chain, always-truthy)
- Update all tests and CLI to await results
2026-03-09 15:32:27 +03:00

136 lines
2.9 KiB
TypeScript

import type { ToolDef } from './schema'
import {
getSelection, getPageTree, getNode, findNodes, queryNodes, getComponents,
listPages, switchPage, getCurrentPage, pageBounds, selectNodes, listFonts
} from './read'
import {
createShape, render, createComponent, createInstance,
createPage, createVector, createSlice
} from './create'
import {
setFill, setStroke, setEffects, updateNode, setLayout, setConstraints,
setRotation, setOpacity, setRadius, setMinMax, setText, setFont, setFontRange,
setTextResize, setVisible, setBlend, setLocked, setStrokeAlign,
setTextProperties, setLayoutChild
} from './modify'
import {
deleteNode, cloneNode, renameNode, reparentNode, groupNodes, ungroupNode,
flattenNodes, nodeToComponent, nodeBounds, nodeMove, nodeResize,
nodeAncestors, nodeChildren, nodeTree, nodeBindings, nodeReplaceWith, arrangeNodes
} from './structure'
import {
listVariables, listCollections, getVariable, findVariables,
createVariable, setVariable, deleteVariable, bindVariable,
getCollection, createCollection, deleteCollection
} from './variables'
import {
booleanUnion, booleanSubtract, booleanIntersect, booleanExclude,
pathGet, pathSet, pathScale, pathFlip, pathMove,
viewportGet, viewportSet, viewportZoomToFit,
exportSvg, exportImage
} from './vector'
import {
analyzeColors, analyzeTypography, analyzeSpacing, analyzeClusters,
diffCreate, diffShow, evalCode
} from './analyze'
export const ALL_TOOLS: ToolDef[] = [
// Read
getSelection,
getPageTree,
getNode,
findNodes,
queryNodes,
getComponents,
listPages,
switchPage,
getCurrentPage,
pageBounds,
selectNodes,
listFonts,
// Create
createShape,
render,
createComponent,
createInstance,
createPage,
createVector,
createSlice,
// Modify
setFill,
setStroke,
setEffects,
updateNode,
setLayout,
setConstraints,
setRotation,
setOpacity,
setRadius,
setMinMax,
setText,
setFont,
setFontRange,
setTextResize,
setVisible,
setBlend,
setLocked,
setStrokeAlign,
setTextProperties,
setLayoutChild,
// Structure
deleteNode,
cloneNode,
renameNode,
reparentNode,
groupNodes,
ungroupNode,
flattenNodes,
nodeToComponent,
nodeBounds,
nodeMove,
nodeResize,
nodeAncestors,
nodeChildren,
nodeTree,
nodeBindings,
nodeReplaceWith,
arrangeNodes,
// Variables
listVariables,
listCollections,
getVariable,
findVariables,
createVariable,
setVariable,
deleteVariable,
bindVariable,
getCollection,
createCollection,
deleteCollection,
// Vector & export
booleanUnion,
booleanSubtract,
booleanIntersect,
booleanExclude,
pathGet,
pathSet,
pathScale,
pathFlip,
pathMove,
viewportGet,
viewportSet,
viewportZoomToFit,
exportSvg,
exportImage,
// Analyze & diff
analyzeColors,
analyzeTypography,
analyzeSpacing,
analyzeClusters,
diffCreate,
diffShow,
// Eval
evalCode
]