skill / adom-api
!

Not installable via adompkg

This skill has no published release. adompkg install kyle/adom-api will not work until a maintainer publishes a tarball with install.sh and uninstall.sh.

See the publishing docs for the package.json schema and tarball layout required to ship this skill.


name: adom-api
user-invokable: true
description: Adom Docker Container API reference. Use when the user wants to control workcell hardware, cameras, messaging, repo sync, or other platform features from code running in the Docker container.

Adom Docker Container API

Status: Not yet available. This API is on the Adom roadmap and is actively being developed. The endpoints, WebSocket events, and CLI wrapper described below represent the planned design. This document will be updated with final URLs, ports, and details as the API becomes available.

The Docker container in every Adom project will have access to the Adom API — a set of HTTP REST endpoints and a WebSocket channel for controlling workcell hardware, communicating with the front-end web app, and managing project state. All API calls originate from inside the Docker container.

Adom Platform URLs

Understanding how Adom URLs work is important for generating correct links in READMEs, documentation, and scripts.

URL Scheme

What URL pattern
Hydrogen web app https://hydrogen.adom.inc/
Project directory browser https://hydrogen.adom.inc/{username}/{project}/tree/latest/{path}
Project file viewer https://hydrogen.adom.inc/{username}/{project}/blob/latest/{path}
Adom REST API (external) https://carbon.adom.inc/ (requires browser session auth)
Adom WebSocket (external) wss://iron.adom.inc/ (requires auth token)
Container VS Code https://coder.{username}-{project}-{hash}.containers.adom.inc/
Container proxy (ports) https://coder.{username}-{project}-{hash}.containers.adom.inc/proxy/{port}/

/tree/ vs /blob/: Use /tree/latest/{path} for directories, /blob/latest/{path} for individual files — same convention as GitHub.

Deriving username and project name

Both can be read from the VSCODE_PROXY_URI environment variable inside the container:

# Full URI: https://coder.{username}-{project}-{hash}.containers.adom.inc/proxy/{{port}}/
echo $VSCODE_PROXY_URI
# Example: https://coder.john-adom-conduit-d4d7f7f287915e49.containers.adom.inc/proxy/{{port}}/

The hostname format is coder.{username}-{project}-{hash}.containers.adom.inc. Extract username and project by splitting on - up to the 32-char hex hash at the end.

Linking to project files from READMEs

Always use absolute Hydrogen URLs when linking to project files in a README — relative paths resolve incorrectly in the Hydrogen file browser:

# WRONG — relative path resolves incorrectly on Hydrogen:
\[ICM-42688-P\](project-content/schematics/symbols/ICM-42688-P/)

# CORRECT — absolute Hydrogen URL:
[ICM-42688-P](https://hydrogen.adom.inc/john/adom-conduit/tree/latest/project-content/schematics/symbols/ICM-42688-P)

Access

  • REST API base URL: http://localhost:{{ADOM_API_PORT}}/api/v1 (exact port and base URL forthcoming — will be provided as an environment variable in the Docker container)
  • WebSocket endpoint: ws://localhost:{{ADOM_API_PORT}}/ws (for real-time subscriptions and bidirectional updates)
  • CLI wrapper: adom command pre-installed in the Docker container for shell convenience (forthcoming)

All REST endpoints accept and return JSON. The WebSocket channel sends/receives JSON messages with a type field indicating the event or command.

Authentication

API calls from the Docker container are automatically authenticated — no API key or token is needed. The container's identity is tied to the project and user session.


Camera Control

Every workcell includes a camera system. The base tier is xyZoom; the upgrade tier is xyPanTiltZoom.

xyZoom (base camera)

The xyZoom system has two cameras on a single gantry:

  1. Wide camera — Fixed 120° FOV. Always shows a full birds-eye view of the entire workcell, even as the gantry moves. Provides constant spatial awareness.
  2. Zoom camera — Variable zoom that can focus down to a 10 mm x 10 mm area filling the entire live feed. Used for close inspection of components, solder joints, traces, etc.

The gantry moves along X and Y axes to position both cameras over any point in the workcell.

REST endpoints

Method Endpoint Description
POST /camera/move Move the camera gantry to an X/Y position and set zoom level
GET /camera/position Get current gantry position and zoom level
GET /camera/capabilities Returns which camera system is installed (xyZoom or xyPanTiltZoom)

POST /camera/move — request body

{
  "x": 288,
  "y": 288,
  "zoom": 1.0
}
Field Type Description
x number X position in mm on the base scaffold (0–576)
y number Y position in mm on the base scaffold (0–576)
zoom number Zoom level. 1.0 = fully zoomed out, higher values zoom in. Maximum zoom fills the feed with a 10 mm x 10 mm area.

GET /camera/position — response

{
  "x": 288,
  "y": 288,
  "zoom": 1.0,
  "cameraType": "xyZoom"
}

WebSocket events

Subscribe to camera position updates in real time:

{ "type": "camera.position", "x": 288, "y": 288, "zoom": 1.0 }

The front-end web app automatically reflects camera movements made via the API, and vice versa — if a user moves the camera from the web panel, the Docker container receives position updates over the WebSocket.

CLI examples (forthcoming)

adom camera move --x 100 --y 200 --zoom 5
adom camera position

xyPanTiltZoom (upgrade camera)

The xyPanTiltZoom adds pan and tilt axes to the zoom camera, allowing angled views rather than only top-down. It also supports 3D viewer linking — the camera physically matches whatever angle the user navigates to in the web app's 3D layout viewer.

Additional REST endpoints

Method Endpoint Description
POST /camera/move Same endpoint, with additional pan and tilt fields
POST /camera/link-3d Enable or disable 3D viewer linking

POST /camera/move — extended request body (xyPanTiltZoom)

{
  "x": 288,
  "y": 288,
  "zoom": 1.0,
  "pan": 0,
  "tilt": 90
}
Field Type Description
pan number Pan angle in degrees (horizontal rotation)
tilt number Tilt angle in degrees. 90 = straight down (top-down view), lower values angle the camera.

POST /camera/link-3d — request body

{
  "enabled": true
}

When enabled, the physical camera continuously tracks the user's viewpoint in the 3D layout editor. The user navigates in 3D on the web; the real camera follows. Disable linking to return to manual/API control.


Messaging

Send messages from the Docker container to the front-end web app so the user sees them in their browser.

Method Endpoint Description
POST /message/send Send a message to the web app

POST /message/send — request body

{
  "text": "Firmware upload complete. Board is ready for testing.",
  "level": "info"
}
Field Type Description
text string The message content
level string info, warning, or error. Controls how the message is displayed in the web app.

CLI example (forthcoming)

adom message send "Firmware upload complete" --level info

Repository Sync

Sync changes from the Docker container back to the project's main repository on Adom.

The easiest way: click the "Commit & Save Project Files" button on the Adom project page in Hydrogen. This commits and pushes all project directory changes in one click — no git setup required.

Important for AI agents: This button requires the user's authenticated browser session. It cannot be triggered programmatically from inside the Docker container — the container does not hold the user's Hydrogen session token. Do not attempt to call the Adom REST API (carbon.adom.inc) to trigger a sync; it will return 401. Just tell the user to click the button.

The programmatic API (planned, not yet available) will expose the same functionality:

Method Endpoint Description
POST /repo/sync Push Docker container changes upstream to the main repo
GET /repo/status Check sync status (pending changes, last sync time)

POST /repo/sync — request body

{
  "message": "Updated motor control firmware"
}
Field Type Description
message string Optional commit/sync message describing the changes

Viewers

Query how many users are currently viewing this project in their browser.

Method Endpoint Description
GET /viewers/count Number of active browser sessions viewing this project
GET /viewers/list List of active viewers (usernames)

GET /viewers/count — response

{
  "count": 3
}

WebSocket events

Subscribe to viewer count changes in real time:

{ "type": "viewers.update", "count": 3 }

3D Layout Viewer

Control the 3D layout editor panel in the front-end web app from the Docker container.

Method Endpoint Description
POST /layout/reload Reload the layout from its backing file (picks up any changes made on disk)
GET /layout/camera Get the user's current view angle and camera position in the 3D viewer
POST /layout/camera Set the view angle and camera position (animate the 3D viewer)
POST /layout/animate Execute a scripted camera move sequence in the 3D viewer
POST /layout/open Open a new layout panel showing an alternate layout file
POST /layout/save Force the layout editor to save its current state to the backing file

GET /layout/camera — response

{
  "position": { "x": 288, "y": 288, "z": 500 },
  "target": { "x": 288, "y": 288, "z": 0 },
  "zoom": 1.0
}

POST /layout/camera — request body

{
  "position": { "x": 100, "y": 200, "z": 300 },
  "target": { "x": 100, "y": 200, "z": 0 },
  "zoom": 2.0,
  "animate": true,
  "duration": 1000
}
Field Type Description
position { x, y, z } Camera position in 3D space (mm)
target { x, y, z } Point the camera looks at (mm)
zoom number Zoom level
animate boolean Whether to smoothly animate to the new position or jump instantly
duration number Animation duration in milliseconds (only used when animate is true)

POST /layout/animate — request body

{
  "moves": [
    { "position": { "x": 100, "y": 100, "z": 400 }, "target": { "x": 100, "y": 100, "z": 0 }, "duration": 1000 },
    { "position": { "x": 400, "y": 400, "z": 200 }, "target": { "x": 400, "y": 400, "z": 0 }, "duration": 2000 }
  ]
}

Executes a sequence of camera moves in order — useful for creating guided tours or focusing on specific areas of the layout.

POST /layout/open — request body

{
  "file": "project-content/layouts/alternate-layout.json"
}

Opens a new layout panel showing the specified file. The original layout panel remains open.

WebSocket events

{ "type": "layout.camera", "position": { "x": 288, "y": 288, "z": 500 }, "target": { "x": 288, "y": 288, "z": 0 }, "zoom": 1.0 }

Subscribe to layout.camera to track the user's 3D viewer navigation in real time.


Schematic Viewer

Control the schematic editor panel in the front-end web app from the Docker container.

Method Endpoint Description
POST /schematic/reload Reload the schematic from its backing file (picks up any changes made on disk)
GET /schematic/camera Get the user's current view position and zoom in the schematic viewer
POST /schematic/open Open a new schematic panel showing an alternate schematic file
POST /schematic/save Force the schematic editor to save its current state to the backing file

GET /schematic/camera — response

{
  "page": "Main",
  "position": { "x": 500, "y": 300 },
  "zoom": 1.0
}
Field Type Description
page string The name of the schematic page currently visible
position { x, y } Pan position in the 2D schematic view
zoom number Zoom level

POST /schematic/open — request body

{
  "file": "project-content/schematics/alternate-schematic.json"
}

Opens a new schematic panel showing the specified file. The original schematic panel remains open.

WebSocket events

{ "type": "schematic.camera", "page": "Main", "position": { "x": 500, "y": 300 }, "zoom": 1.0 }

Subscribe to schematic.camera to track the user's schematic viewer navigation in real time.


WebSocket Reference

Connect to the WebSocket endpoint to receive real-time events and send commands without polling.

Connection: ws://localhost:{{ADOM_API_PORT}}/ws

Subscribing to events

After connecting, send a subscribe message:

{ "type": "subscribe", "channels": ["camera.position", "viewers.update", "layout.camera", "schematic.camera"] }

Event types

Event type Description
camera.position Camera gantry moved (x, y, zoom, and optionally pan/tilt)
viewers.update Active viewer count changed
message.received A message was sent to the web app (echo for confirmation)
repo.sync.complete Repo sync finished
layout.camera User navigated the 3D layout viewer (position, target, zoom)
schematic.camera User navigated the schematic viewer (page, position, zoom)

Future APIs

The following APIs are planned and will be documented here as they become available:

  • Power control — Programmatic control of control panel power rails (variable DC, 24V DC)
  • GPIO control — Read/write GPIO pins on the control panel
  • Oscilloscope — Trigger measurements and retrieve waveform data
  • Robot shuttle — Request scaffold moves between workcell, powered storage, and warehouse
  • InstaPCB — Submit fabrication jobs and check status programmatically. InstaPCB provides 4-hour PCB turnaround at JLCPCB-like pricing using UV fiber laser fabrication. Runs on ~14 dedicated "tool workcells" on the factory floor (separate from subscriber cloud workcells). Components sourced via Mouser drone delivery. Fabricated boards are delivered directly to the subscriber's cloud workcell for immediate testing. See use-cases.md for full details.

Notes for AI agents

When writing scripts that call the Adom API:

  • Always check /camera/capabilities before sending pan/tilt commands — the workcell may only have xyZoom.
  • Use the WebSocket for anything that needs live updates (camera tracking, viewer monitoring). Use REST for one-shot commands.
  • All coordinates are in millimeters relative to the base scaffold origin (0,0 is one corner, 576,576 is the opposite).
  • The API is only accessible from inside the Docker container. It is not exposed to the public internet.
  • Project directory is root-owned: /home/adom/project is owned by root by default. To write files there, use sudo tee (e.g. echo "content" | sudo tee /home/adom/project/file.txt) or fix ownership with sudo chown -R $USER /home/adom/project.
  • Do not attempt programmatic repo sync: The "Commit & Save Project Files" button in Hydrogen requires the user's browser session. Calling carbon.adom.inc from the container returns 401. Tell the user to click the button in the Hydrogen UI.