snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
119
templates/agent/client/tools/TargetAreaTool.tsx
Normal file
119
templates/agent/client/tools/TargetAreaTool.tsx
Normal file
@@ -0,0 +1,119 @@
|
||||
import { BoxModel, StateNode, VecModel } from 'tldraw'
|
||||
import { AgentAppAgentsManager } from '../agent/managers/AgentAppAgentsManager'
|
||||
|
||||
export class TargetAreaTool extends StateNode {
|
||||
static override id = 'target-area'
|
||||
static override initial = 'idle'
|
||||
static override children() {
|
||||
return [TargetAreaIdle, TargetAreaPointing, TargetAreaDragging]
|
||||
}
|
||||
|
||||
override isLockable = false
|
||||
|
||||
override onEnter() {
|
||||
this.editor.setCursor({ type: 'cross', rotation: 0 })
|
||||
}
|
||||
|
||||
override onExit() {
|
||||
this.editor.setCursor({ type: 'default', rotation: 0 })
|
||||
}
|
||||
|
||||
override onInterrupt() {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
override onCancel() {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
private complete() {
|
||||
this.parent.transition('select', {})
|
||||
}
|
||||
}
|
||||
|
||||
class TargetAreaIdle extends StateNode {
|
||||
static override id = 'idle'
|
||||
|
||||
override onPointerDown() {
|
||||
this.parent.transition('pointing')
|
||||
}
|
||||
}
|
||||
|
||||
class TargetAreaPointing extends StateNode {
|
||||
static override id = 'pointing'
|
||||
|
||||
private initialScreenPoint: VecModel | undefined = undefined
|
||||
private initialPagePoint: VecModel | undefined = undefined
|
||||
|
||||
override onEnter() {
|
||||
this.initialScreenPoint = this.editor.inputs.getCurrentScreenPoint().clone()
|
||||
this.initialPagePoint = this.editor.inputs.getCurrentPagePoint().clone()
|
||||
}
|
||||
|
||||
override onPointerMove() {
|
||||
if (!this.initialScreenPoint) return
|
||||
if (this.editor.inputs.getIsDragging()) {
|
||||
this.parent.transition('dragging', { initialPagePoint: this.initialPagePoint })
|
||||
}
|
||||
}
|
||||
|
||||
override onPointerUp() {
|
||||
const agents = AgentAppAgentsManager.getAgents(this.editor)
|
||||
for (const agent of agents) {
|
||||
agent.context.add({
|
||||
type: 'point',
|
||||
point: this.editor.inputs.getCurrentPagePoint().clone(),
|
||||
source: 'user',
|
||||
})
|
||||
}
|
||||
this.editor.setCurrentTool('select')
|
||||
}
|
||||
}
|
||||
|
||||
class TargetAreaDragging extends StateNode {
|
||||
static override id = 'dragging'
|
||||
|
||||
private initialPagePoint: VecModel | undefined = undefined
|
||||
private bounds: BoxModel | undefined = undefined
|
||||
|
||||
override onEnter(props: { initialPagePoint: VecModel }) {
|
||||
this.initialPagePoint = props.initialPagePoint
|
||||
this.updateBounds()
|
||||
}
|
||||
|
||||
override onPointerMove() {
|
||||
this.updateBounds()
|
||||
}
|
||||
|
||||
override onPointerUp() {
|
||||
this.editor.updateInstanceState({
|
||||
brush: null,
|
||||
})
|
||||
|
||||
if (!this.bounds) throw new Error('Bounds not set')
|
||||
const agents = AgentAppAgentsManager.getAgents(this.editor)
|
||||
for (const agent of agents) {
|
||||
agent.context.add({
|
||||
type: 'area',
|
||||
bounds: this.bounds,
|
||||
source: 'user',
|
||||
})
|
||||
}
|
||||
this.editor.setCurrentTool('select')
|
||||
}
|
||||
|
||||
updateBounds() {
|
||||
if (!this.initialPagePoint) return
|
||||
const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
|
||||
const x = Math.min(this.initialPagePoint.x, currentPagePoint.x)
|
||||
const y = Math.min(this.initialPagePoint.y, currentPagePoint.y)
|
||||
const w = Math.abs(currentPagePoint.x - this.initialPagePoint.x)
|
||||
const h = Math.abs(currentPagePoint.y - this.initialPagePoint.y)
|
||||
|
||||
this.editor.updateInstanceState({
|
||||
brush: { x, y, w, h },
|
||||
})
|
||||
|
||||
this.bounds = { x, y, w, h }
|
||||
}
|
||||
}
|
||||
165
templates/agent/client/tools/TargetShapeTool.tsx
Normal file
165
templates/agent/client/tools/TargetShapeTool.tsx
Normal file
@@ -0,0 +1,165 @@
|
||||
import { Box, BoxModel, StateNode, TLShape, VecModel } from 'tldraw'
|
||||
import { convertTldrawShapeToFocusedShape } from '../../shared/format/convertTldrawShapeToFocusedShape'
|
||||
import { AgentAppAgentsManager } from '../agent/managers/AgentAppAgentsManager'
|
||||
|
||||
export class TargetShapeTool extends StateNode {
|
||||
static override id = 'target-shape'
|
||||
static override initial = 'idle'
|
||||
static override children() {
|
||||
return [TargetShapeIdle, TargetShapePointing, TargetShapeDragging]
|
||||
}
|
||||
|
||||
override isLockable = false
|
||||
|
||||
override onEnter() {
|
||||
this.editor.setCursor({ type: 'cross', rotation: 0 })
|
||||
}
|
||||
|
||||
override onExit() {
|
||||
this.editor.setCursor({ type: 'default', rotation: 0 })
|
||||
}
|
||||
|
||||
override onInterrupt() {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
override onCancel() {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
private complete() {
|
||||
this.parent.transition('select', {})
|
||||
}
|
||||
}
|
||||
|
||||
class TargetShapeIdle extends StateNode {
|
||||
static override id = 'idle'
|
||||
|
||||
override onPointerMove() {
|
||||
const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
|
||||
const shape = this.editor.getShapeAtPoint(currentPagePoint, { hitInside: true })
|
||||
if (shape) {
|
||||
this.editor.setHintingShapes([shape])
|
||||
} else {
|
||||
this.editor.setHintingShapes([])
|
||||
}
|
||||
}
|
||||
|
||||
override onPointerDown() {
|
||||
const shape = this.editor.getShapeAtPoint(this.editor.inputs.getCurrentPagePoint(), {
|
||||
hitInside: true,
|
||||
})
|
||||
this.parent.transition('pointing', { shape })
|
||||
}
|
||||
}
|
||||
|
||||
class TargetShapePointing extends StateNode {
|
||||
static override id = 'pointing'
|
||||
|
||||
private shape: TLShape | undefined = undefined
|
||||
private initialScreenPoint: VecModel | undefined = undefined
|
||||
private initialPagePoint: VecModel | undefined = undefined
|
||||
|
||||
override onEnter({ shape }: { shape: TLShape }) {
|
||||
this.initialScreenPoint = this.editor.inputs.getCurrentScreenPoint().clone()
|
||||
this.initialPagePoint = this.editor.inputs.getCurrentPagePoint().clone()
|
||||
this.shape = shape
|
||||
}
|
||||
|
||||
override onPointerMove() {
|
||||
if (!this.initialScreenPoint) return
|
||||
if (this.editor.inputs.getIsDragging()) {
|
||||
this.parent.transition('dragging', { initialPagePoint: this.initialPagePoint })
|
||||
}
|
||||
}
|
||||
|
||||
override onPointerUp() {
|
||||
this.editor.setHintingShapes([])
|
||||
if (this.shape) {
|
||||
const agents = AgentAppAgentsManager.getAgents(this.editor)
|
||||
for (const agent of agents) {
|
||||
agent.context.add({
|
||||
type: 'shape',
|
||||
shape: convertTldrawShapeToFocusedShape(this.editor, this.shape),
|
||||
source: 'user',
|
||||
})
|
||||
}
|
||||
}
|
||||
this.editor.setCurrentTool('select')
|
||||
}
|
||||
}
|
||||
|
||||
class TargetShapeDragging extends StateNode {
|
||||
static override id = 'dragging'
|
||||
|
||||
private shapes: TLShape[] = []
|
||||
private initialPagePoint: VecModel | undefined = undefined
|
||||
private bounds: BoxModel | undefined = undefined
|
||||
|
||||
override onEnter(props: { initialPagePoint: VecModel }) {
|
||||
this.initialPagePoint = props.initialPagePoint
|
||||
this.editor.setHintingShapes([])
|
||||
this.updateBounds()
|
||||
}
|
||||
|
||||
override onPointerMove() {
|
||||
this.updateBounds()
|
||||
}
|
||||
|
||||
override onPointerUp() {
|
||||
this.editor.setHintingShapes([])
|
||||
this.editor.updateInstanceState({
|
||||
brush: null,
|
||||
})
|
||||
|
||||
if (!this.bounds) throw new Error('Bounds not set')
|
||||
const agents = AgentAppAgentsManager.getAgents(this.editor)
|
||||
if (this.shapes.length <= 3) {
|
||||
for (const shape of this.shapes) {
|
||||
for (const agent of agents) {
|
||||
agent.context.add({
|
||||
type: 'shape',
|
||||
shape: convertTldrawShapeToFocusedShape(this.editor, shape),
|
||||
source: 'user',
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const agent of agents) {
|
||||
agent.context.add({
|
||||
type: 'shapes',
|
||||
shapes: this.shapes.map((shape) => convertTldrawShapeToFocusedShape(this.editor, shape)),
|
||||
source: 'user',
|
||||
})
|
||||
}
|
||||
}
|
||||
this.editor.setCurrentTool('select')
|
||||
}
|
||||
|
||||
updateBounds() {
|
||||
if (!this.initialPagePoint) return
|
||||
const currentPagePoint = this.editor.inputs.getCurrentPagePoint()
|
||||
const x = Math.min(this.initialPagePoint.x, currentPagePoint.x)
|
||||
const y = Math.min(this.initialPagePoint.y, currentPagePoint.y)
|
||||
const w = Math.abs(currentPagePoint.x - this.initialPagePoint.x)
|
||||
const h = Math.abs(currentPagePoint.y - this.initialPagePoint.y)
|
||||
|
||||
this.editor.updateInstanceState({
|
||||
brush: { x, y, w, h },
|
||||
})
|
||||
|
||||
this.bounds = { x, y, w, h }
|
||||
|
||||
const bounds = new Box(x, y, w, h)
|
||||
const shapesInBounds = this.editor.getCurrentPageShapesSorted().filter((shape) => {
|
||||
const geometry = this.editor.getShapeGeometry(shape)
|
||||
const pageTransform = this.editor.getShapePageTransform(shape)
|
||||
const shapeTransform = pageTransform.clone().invert()
|
||||
const boundsInShapeSpace = shapeTransform.applyToPoints(bounds.corners)
|
||||
return geometry.overlapsPolygon(boundsInShapeSpace)
|
||||
})
|
||||
|
||||
this.shapes = shapesInBounds
|
||||
this.editor.setHintingShapes(shapesInBounds)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user