Skip to content
Registry

onboarding

v0.1.1

Guided console tour — step content, per-operator progress in state, and an injected page that spotlights the console element each step talks about.

license: Apache-2.0consoledocsonboardingtourui

Install

bash
iii trigger compose::add worker=onboarding@0.1.1

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

Agent-ready brief for v0.1.1
Install, config, dependencies, readme, skills and API reference, all in one place. Fetch as agent-context.md for an LLM to consume.
The same content rendered as discrete blocks below is exposed as a single markdown document at /workers/onboarding.md?version=0.1.1. Paste it into an LLM prompt or pipe it through curl from a worker.

Install

iii trigger compose::add worker=onboarding@0.1.1

Dependencies

Dependency · 2Version

Readme

README.md

onboarding

The guided console tour. The page and its tab are called onboarding; a "tour" is one unit of content inside it, so a second tour can be added without renaming anything.

Three parts:

Part Lives in Owns
Content src/tours.mjs which tours exist, their steps, and the console element each step points at
Progress the state worker, scope onboarding how far each operator got, so a reload resumes mid-tour
Rendering ui/page.tsx (injected into the console) the step list and the spotlight box

Functions

  • onboarding::tours::list — every tour in curriculum order.
  • onboarding::tours::get — one tour with all of its steps.
  • onboarding::progress::get — the status of every step per tour, with the trigger evidence that closed it, plus the next tour to offer.
  • onboarding::steps::complete — mark one step complete. Pass fired when a trigger closed it; its type and payload are kept as evidence.
  • onboarding::steps::reset — forget one tour and start it again.
  • onboarding::subscribe — add an email address to the iii product-update list (the last step's signup box; the POST happens here, never in the browser).

Progress is written with state::update and its ordered atomic ops, never state::get then state::set: two invocations can interleave around an await, and a read-then-replace write would drop the earlier one. merge walks and creates the path it names, so one step lands under its own tour. A reset nulls its tour (the op set reaches top-level keys only for remove) and the read drops nulls on the way out.

Conditions

A step can wait on a real engine trigger instead of a button. The page binds it the way the console's own live pages do — a per-tab function id, then registerTrigger pointed at it — so what the operator sees is the payload the engine delivered, not a simulation.

The condition is its own row under its step, and stays there once it fires: the trigger type, its state, and the time it fired. Expanding it shows the binding config and the payload, the way the harness shows a function call. The row opens when the operator opens it: a trigger that fires does not throw its payload over whatever is being read.

The tour ships two kinds. The first step waits on harness::turn-completed, so it closes when the agent answers. The four steps whose work the AGENT does — Composability, Discoverability, Extensibility, Reactivity — each wait on a state trigger bound to one key, step__completed, in the onboarding scope; their prompts end by telling the agent to write it as it ends its turn. The end of the turn is the boundary, not the agent's own sense of being finished — asked for the latter it reports while it is still working. The trigger matches the key, not the value: whatever the agent writes there, the write is the report.

That is what keeps the open step and the step being worked on the same step. A long build used to read as finished the moment its prompt was sent, because the button closed the step. The page binds every reachable condition when the step is displayed, before any button is clicked, so the wait is already running when the prompt goes out.

Anchors

A step's anchors are selectors for the console element it talks about, best first. The first is always a class the console carries for this tour: onboarding-menu-bar, onboarding-tabs, onboarding-palette, onboarding-conversations, onboarding-composer, onboarding-traces. Each one sits in ade/web/src beside a short comment that says it is a tour anchor. pnpm test fails if a step points at a class the console no longer has. The selectors after the first are the console's own stable hooks, so the box still lands on a console build older than the anchor classes.

The spotlight is one fixed box in document.body that follows the anchor's rectangle, animated with CSS transitions on the console's motion tokens (see ui/src/spotlight.ts). No animation library: it is one moving rectangle.

Styling

The page is styled with the console's OWN CSS — its utility classes and the uiClasses recipes (card, listItem, chip) — so it inherits the house spacing, edges and hover states, and follows the theme. ui/styles.css holds only what those cannot express: the spotlight box, the status dot, the progress bar, the caret, and the payload block. The markup stays hand-rolled rather than built from shared components, so the page renders on a console build older than a component it would otherwise import.

The steps

The tour says that this is an engine with workers, not a chat app with plugins, and the steps together cover CODER: Composable (the harness is a worker calling functions other workers register), Observable (the traces step, anchored on the console's traces screen), Discoverable (one engine, one palette), Extensible (this page is a worker's page; install more from the package repo), Reactive (the trigger step). The last step, "Stay in touch", takes an email address for the roadmap and product updates, with icon links to Discord, GitHub, X and LinkedIn, and a link to the docs. After it, "Clean up" asks the agent to remove this worker and close the pane — the same composition move as adding one, run backwards. It carries no condition: the worker that would report the step done is the worker being removed.

The Observability step takes two clicks. The first places the traces panel beside the tour; the button then becomes a green, briefly pulsing Continue, which is what closes the step. Opening a panel and having read it are different things, and one click could only say the first.

Build

pnpm install          # worker deps (iii-sdk)
pnpm --dir ui install # UI deps, from the shared console-UI workspace
pnpm build            # ui/dist assets, then dist/bundle
pnpm test

pnpm build:assets writes ui/dist/{page.js,styles.css} with esbuild alone — no pnpm workspace and no tsc — which is what scripts.install runs inside the worker's VM. pnpm build:bundle writes the publishable shape: dist/bundle/index.mjs with the worker and its dependencies inlined, and the two page assets beside it. onboarding::ui-content reads whichever layout has the page — beside the bundle, or ui/dist in a checkout.

III_ONBOARDING_UI_WATCH=1 re-registers a changed asset, which hot-swaps the page in every open console tab. III_ONBOARDING_UI_DIR overrides where the assets are read from.

API reference (JSON)

agent-api-reference.json
{
  "functions": [
    {
      "description": "Read an operator’s tour progress: per tour, the status of every step and the trigger evidence that closed it, plus which tour to offer next.",
      "metadata": {},
      "name": "onboarding::progress::get",
      "request_schema": {
        "properties": {
          "subject": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "next_tour_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "tours": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "tours",
          "next_tour_id"
        ],
        "type": "object"
      }
    },
    {
      "description": "Mark one tour step complete. Pass `fired` when a trigger closed it — its type and payload are kept as the evidence the tour shows back.",
      "metadata": {},
      "name": "onboarding::steps::complete",
      "request_schema": {
        "properties": {
          "fired": {
            "properties": {
              "function_id": {
                "type": "string"
              },
              "payload": {},
              "trigger_type": {
                "type": "string"
              }
            },
            "type": "object"
          },
          "step_id": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "tour_id": {
            "type": "string"
          }
        },
        "required": [
          "tour_id",
          "step_id"
        ],
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "step": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "step"
        ],
        "type": "object"
      }
    },
    {
      "description": "Forget every step of one tour, so it starts from the beginning again.",
      "metadata": {},
      "name": "onboarding::steps::reset",
      "request_schema": {
        "properties": {
          "subject": {
            "type": "string"
          },
          "tour_id": {
            "type": "string"
          }
        },
        "required": [
          "tour_id"
        ],
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "reset": {
            "type": "boolean"
          }
        },
        "required": [
          "reset"
        ],
        "type": "object"
      }
    },
    {
      "description": "Add an email address to the iii product-update list.",
      "metadata": {},
      "name": "onboarding::subscribe",
      "request_schema": {
        "properties": {
          "email": {
            "type": "string"
          },
          "source": {
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "subscribed": {
            "type": "boolean"
          }
        },
        "required": [
          "subscribed"
        ],
        "type": "object"
      }
    },
    {
      "description": "Fetch one tour by id with every step: id, title, body, and the CSS anchor the console page spotlights for that step.",
      "metadata": {},
      "name": "onboarding::tours::get",
      "request_schema": {
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "tour": {
            "properties": {},
            "type": "object"
          }
        },
        "required": [
          "tour"
        ],
        "type": "object"
      }
    },
    {
      "description": "List every available tour in curriculum order with its id, title, description, and step count. Call this to find out what onboarding content exists.",
      "metadata": {},
      "name": "onboarding::tours::list",
      "request_schema": {
        "properties": {},
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "tours": {
            "type": "array"
          }
        },
        "required": [
          "tours"
        ],
        "type": "object"
      }
    },
    {
      "description": "Serve the injectable onboarding console page assets.",
      "metadata": {
        "internal": true
      },
      "name": "onboarding::ui-content",
      "request_schema": {
        "properties": {
          "path": {
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "type": "object"
      },
      "response_schema": {
        "properties": {
          "content": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          }
        },
        "required": [
          "content",
          "content_type"
        ],
        "type": "object"
      }
    }
  ],
  "triggers": []
}

Search the registry

Find workers, kits and executables, or jump to a page.