window.oniyanma
アプリを開くと、window.oniyanma が生えます。ブラウザの開発者コンソールから、 UI とまったく同じコマンド層を叩けます。
[oniyanma] window.oniyanma ready — oniyanma.tools() / oniyanma.execute(name,args) / oniyanma.getState() / oniyanma.connectRelay(url,room)ここから出した編集の発行者は api(name: 'window.oniyanma')として記録され、 破壊的コマンドは確認ゲートを通ります。
コマンド
tools()
Anthropic tool-use 互換のツール定義一覧(ToolDef[])を返します。 外部エージェントはこれを読んで execute() を呼ぶだけで oniyanma を操作できます。
oniyanma.tools()
// → [{ name: 'setColorMode', description: '…', input_schema: { … } }, …]commands()
コマンド名だけの配列。tools().map(t => t.name) の省略形です。
oniyanma.commands()
// → ['setColorMode', 'setPointSize', …]execute(name, args?)
コマンドを実行します。Promise を返します。
await oniyanma.execute('setColorMode', { mode: 'elevation' }) // → { ok: true }
await oniyanma.execute('queryElevation', { bins: 8 })
await oniyanma.execute('deleteSelection', { confirm: true })未知のコマンド名、引数の型違反、サーフェス違反は例外になります。 → 返り値とエラーの約束
getState()
現在状態のスナップショット。→ 状態スナップショット
oniyanma.getState()
// → { backend: 'webgpu', colorMode: 'elevation', sources: [...], alignedBounds: [...], … }協働
joinRoom(url, room?, name?)
協働ルームへ参加します。room の既定は自分のルーム(推測されない UUID)、 name の既定は 'guest'。
oniyanma.joinRoom('wss://oniyanma-demo.pages.dev/collab', undefined, '山田')inviteLink(server?)
現在のルームの招待 URL を返します。このリンクを開いた人は同じルームへ自動参加します。
oniyanma.inviteLink()
// → 'https://…/?collab=wss://…&room=<uuid>&name=…'server を省略しても同期サーバが載ります。?collab= が無いと受け取った側が自動参加せず、 「リンクを渡したのに相手が来ない」という分かりにくい失敗になるためです。
leaveRoom()
退出します。
showPeerMarkers(visible)
他の参加者の視点・選択マーカーの表示を切り替えます。
oniyanma.showPeerMarkers(false)MCP 中継
connectRelay(url, room?)
コマンド中継コーディネータへ viewer として接続します。 これで MCP クライアント側からこのブラウザを操作できるようになります。 room の既定は 'oniyanma'。
oniyanma.connectRelay('ws://localhost:8787', 'bridge1')
// → 'connecting to ws://localhost:8787 room=bridge1'disconnectRelay()
中継を切断します。
デバッグ
debugInput()
入力状態のスナップショットを返します。 「描画は動くのに操作だけ効かない」を切り分けるためのものです。
oniyanma.debugInput()使い方の例
上端 20% のスラブを選んで、点数を確認してから消す:
const { alignedBounds: b } = oniyanma.getState()
const zTop = b[5] - (b[5] - b[2]) * 0.2
await oniyanma.execute('selectBox', { min: [b[0], b[1], zTop], max: [b[3], b[4], b[5]] })
await oniyanma.execute('deleteSelection') // → preview: 件数だけ返る
await oniyanma.execute('deleteSelection', { confirm: true })分類ごとの点数を数える:
await oniyanma.execute('queryClasses')
// → { total: 1234567, counts: { '0': 1200000, '2': 34567 } }所見を起票して公開する:
const { id } = await oniyanma.execute('createFinding', {
typeId: 'damage',
fields: { kind: 'ひび割れ', grade: 'c' },
pin: [x, y, z],
})
await oniyanma.execute('publishFinding', { id })