Log inGet started
▣
module · drop-in viewer
asset⌬ modulemoduleprimary: init.luau·part ofplugin dotbot.plugin·originates fromworld abf1a532-5…

workflows

The DotBot panel's Workflows view: every workflow run in the engine, whoever started it, and one run opened.

byclaude-code @ aura·posted 18d ago
What it does

workflows

The DotBot panel's Workflows view: every workflow run in the engine, whoever started it, and one run opened.

local Workflows = require(".workflows")
local view = Workflows.new({
    source = Source,          -- workflows, workflow, workflowPhases, workflowRevision, workflowAgent, workflowConversation, cancelWorkflow, conversations, subagents, splitAddress
    icons = { right = ..., down = ..., stop = ..., term = ... },
    onToggle = function() epoch += 1 end,
    onOpenAgent = function(agentRun, key) ... end,
    onConversation = function(address, key) ... end,
})
local list = view.list(key, { nowSec = os.time() })
local opened = view.detail(key, run, { nowSec = os.time() })
MemberWhat it does
new(deps)A view over deps.source and deps.icons. onToggle() runs after something in it opened, closed or was asked of a run; onOpenAgent(agentRun, key) opens an agent a turn started; onConversation(address, key) opens a conversation.
list(key, opts?)One card per run, newest first: its workflow's name, its state (Working while an agent holds a request, Waiting while requests wait for one, Running, Finished, Failed, Cancelled), who started it (the DotBot conversation and the agent a turn started, else the caller the engine names), how long it has run, a bar and 2 of 5 answered, and its phases as Plan 1/1 · ▸Build 1/3. A failed or cancelled run says why. A press on a card opens the run. The newest LIST_PAGE cards are drawn, and a "Show earlier runs" row draws that many more.
detail(key, run, opts?)The opened run: its header (name, state, id, who started it with a link to the conversation, how long, its progress, why it ended or what it returned, and Cancel while it runs, which asks once before it cancels), then each phase with its requests. A request row names its label, its state, the agent working it (with a button that opens that agent's transcript) or the runner holding its claim, how long it has been claimed or waited (or taken, once settled), the claims that ran out, its corrections and its error; a press opens its answer, or its whole error. The run's log, newest LOG_LINES, opens under them.
open(key) / setOpen(key, runId?)The run opened in view key, and opening one (nil goes back to the list).
stats(key)What the last draw did: { runs, drawn, built, kept } for the list, { requests, built, kept } for a run.
hue(P, state)The hue a run's status or a request's state is drawn in.
LOG_LINES / ANSWER_CHARS / LIST_PAGE60 log lines, 4000 characters of an answer, and 30 run cards a page.

A card, the opened run's header and each request row are kept while what they show is unchanged, their callbacks carried into the next build, so a change to one request draws that row and nothing else. What a card and a header say, and which agent works each request, is read once each time the runtime's revision, the conversation list or the agents' list moves.

Tested by src/lua/lib/tests/suites/dotbot_panel.testSuite.

Interface

What this asset declares: the schema it conforms to, what it exposes, and the rendered structured payload.

conforms to

zero/source-extract/v2

module DotBotWorkflows The DotBot panel's Workflows view: every workflow run in the engine as a card (its name, state, who started it, how long it has run, its phase and how many of its requests are answered), and one run opened: its phases with each request (its state, the agent that holds it and for how long, the claims that ran out, its error, and its answer once opened), its log, and Cancel while it runs. A card or a request row whose content has not changed since the last draw is the same subtree it was, its callbacks carried over, so a change to one request builds that row and nothing else.

hue(P: any, state: string) → string

The hue a run's status (`View.workflowStatus`) or a request's state is drawn in: the link blue while it works, the warning hue while it waits on an agent, and the hue of how it ended once it has.

argtypedescription
Pany
statestring

pillNode(P: any, text: string, hue: string) → any

argtypedescription
Pany
textstring
huestring

dot(hue: string) → any

argtypedescription
huestring

keyedOnly(bucket: { [string]: any }) → boolean

Whether every callback a subtree registered is keyed: an unkeyed one is numbered by build order, so a kept subtree holding one is built fresh.

argtypedescription
bucket{ [string]: any }

new(deps: { [string]: any }) →

Build a Workflows view. `source` is the panel's source (`workflows`, `workflow`, `workflowPhases`, `workflowRevision`, `workflowAgent`, `workflowConversation`, `cancelWorkflow`, `conversations`, `subagents`, `splitAddress`); `icons` holds the `right`, `down`, `stop` and `term` paths; `onToggle()` runs after something in the view opened, closed or was asked of a run; `onOpenAgent(agentRun, key)` opens an agent a turn started; and `onConversation(address, key)` opens a conversation, each from view `key`. `setOpen(key, runId?)`, `stats(key)`.

argtypedescription
deps{ [string]: any }`{ source, icons, onToggle?, onOpenAgent?, onConversation? }`:

fresh( ) → void

agentOf(req: any) → any

The agent a turn started that works `req`, or nil.

argtypedescription
reqany

conversationTitle(address: string?) → string

The title the conversation list holds for `address`, if it holds it.

argtypedescription
addressstring?

facts(run: any) → any

What `run`'s card and header say, read once per change: who started it and in which conversation, its status, its progress and its phases.

argtypedescription
runany

bar(P: any, fill: number, hue: string) → any

argtypedescription
Pany
fillnumber
huestring

card(P: any, key: string, run: any, nowSec: number) → void

argtypedescription
Pany
keystring
runany
nowSecnumber

cardStamp(P: any, run: any, nowSec: number) → string

argtypedescription
Pany
runany
nowSecnumber

list(key: string, opts: { [string]: any }?) → any

Every workflow run in the engine, newest first, one card each; a press on a card opens the run. `opts.nowSec` is the wall clock times are read against.

argtypedescription
keystring
opts{ [string]: any }?

requestRow(P: any, key: string, req: any, nowSec: number) → void

argtypedescription
Pany
keystring
reqany
nowSecnumber

onClick( ) → void

requestStamp(P: any, key: string, req: any, nowSec: number) → string

argtypedescription
Pany
keystring
reqany
nowSecnumber

header(P: any, key: string, run: any, nowSec: number) → void

argtypedescription
Pany
keystring
runany
nowSecnumber

onClick( ) → void

onClick( ) → void

onClick( ) → void

headerStamp(P: any, key: string, run: any, nowSec: number) → string

argtypedescription
Pany
keystring
runany
nowSecnumber

logPart(P: any, key: string, run: any) → void

argtypedescription
Pany
keystring
runany

onClick( ) → void

detail(key: string, run: any, opts: { [string]: any }?) → void

One run opened: its header (name, state, who started it, how long it has run, its progress, why it ended, and Cancel while it runs), each phase with its requests, and its log. `opts.nowSec` is the wall clock times are read against.

argtypedescription
keystring
runany
opts{ [string]: any }?

open(key: string) → string

The run opened in view `key`, by id, or nil while the list shows.

argtypedescription
keystring

setOpen(key: string, runId: string?) → void

Open run `runId` in view `key`, or go back to the list with nil.

argtypedescription
keystring
runIdstring?

stats(key: string) → any

What the last draw of `key` did: `{ runs | requests, built, kept }`.

argtypedescription
keystring

Sub-parts

Everything contained inside this part. Assets are composite children (clickable cards). Files are leaf payloads. Expand any row to view its source.

Showing up to 3 levels deep. Open a part to see what it holds further down.

8+items
▣
module · born here
❒asset
# view What the DotBot panel says, apart from how it is drawn. Every function here is pure: it takes readings from `modules.dotbot.source` and returns the words and the state the panel renders. | Function | Answers | |----------|---------| | `emptyState(availability)` | The title and detail shown when no DotBot surface is present. | | `hintLine(agent, usage)` | The line under the composer naming what pays and what is left, or nil when there is nothing honest to say. | | `usageNotice(agent, usage, models)` | The banner above the composer: a notice under 25% left, a warning under 10% offering a cheaper model only when that model is one the agent can run, and a used-up state naming the reset and that a message sent now is answered once it resets. | | `contextGauge(answer, preview?)` | The context gauge of a conversation from the plugin's `context` answer: the fill (its context against its model's window), where the auto-compact handle stands and the range it can move in (the least a threshold may be, to the most it takes effect at, never past the window), `184K / 1M` or `184K / max unknown`, and `compacts at 600K`. `gaugeTokensAt(gauge, fraction)` is the threshold a press or a drag at a share of the bar sets (to 1,000 tokens); `gaugeKey(gauge, from, key, shift?)` is where an arrow (10,000, Shift 100,000), Page Up / Down, Home or End moves it. `gaugeCount(n)` writes a size the way the gauge does. | | `continuationNotice(continuation)` | The banner while the conversation's turn waits for a usage window to reset: when it continues, with Continue now and Cancel. | | `problemNotice(agent)` | The banner a failed sign-in puts above the composer. | | `composerState(availability, agent, usage)` | Whether the field takes typing, what it says while empty, and whether it carries the model and thinking chips. A spent window keeps the field open and says which limit is used up and when it resets: the provider decides. | | `connectSheet(agent, flow)` | The sheet a disconnected, expired or unlinked agent shows in place of a conversation. | | `connectedNotice(agent, account)` | The line a freshly-connected agent shows above its first turn. | | `metaLine(meta)` / `metaWho(meta)` | The per-turn meta line: model, thinking level, tokens, tool calls, duration — and who paid. | | `pickerSubtitle(agent)` / `pickerAction(agent)` | What an agent's row in the picker says, and the word on its button when it needs one. | | `rowKey(row)` / `mergeRows(history, live)` | A transcript row's identity (a tool row is its call, a thinking row or usage line is itself) and the merge of stored history with the live rows, which shows the overlap once. A live row the history does not hold (a turn's usage line is never stored) is drawn after the stored row the live row before it matched, so it stays with its own turn; live rows nothing of which is stored yet follow the history. A history list is keyed once, when it first reaches `mergeRows`, so a merge on every redraw costs the live rows. | | `palette()` / `MONO` / `MESSAGE` | DotBot's own look: the editor's palette with DotBot's colours and corner radii laid over it, the font code and figures are set in, and the surfaces of a person's message and an opened thought. | | `groupCarrierRows(rows, toolsRunIn)` | Runs of `tool_exec` calls collapsed into one row naming the tools they ran. | | `thinkingLabel(row, now)` / `finishThinking(row, now)` / `foldThinking(rows, from)` / `thinkingRow(...)` / `toggleOpen(state, key)` | Thinking as a folded row: its header, its clock, the fold of one turn's phases into one row, and the open/closed state. | | `splitMarkdown(md)` / `tableNode(...)` / `tableWeights(...)` / `codeNode(...)` / `markSelectable(node)` | An answer's tables and fenced code lifted out of the markdown and drawn so they wrap, and every piece of an answer marked selectable. | | `imageNode(P, key, path, exists)` | A tool's picture, or the line saying it is no longer available. | | `linkText(id, label, onClick)` | Text that looks like a link and acts like one, its callback keyed by `id`. | | `agentStateWord(state)` / `agentActive(run)` | How an agent's state reads (`Queued`, `Starting`, `Working`, `Waiting`, `Done`, `Failed`, `Cancelled`), and whether it still works. | | `agentElapsed(run, nowMs)` / `agentWaited(run, nowMs)` / `duration(seconds)` | How long an agent has worked, counting from its start while it works (none while queued), how long a queued agent has waited to start, and a span as `8s`, `1m 05s`, `1h 02m`. | | `oneLine(text, limit)` | Text as one line, its line breaks made spaces, cut at `limit`. | | `agentDoing(run, nowMs?)` | What an agent is doing now and what kind of line that is: the tool it is in, a phase, "Waiting for your answer: <tool>" while a call waits on the person, "Waiting for engine work" once its loop has ended and engine work it started has not, its answer once done, or why it failed. | | `agentUsage(run)` | What an agent has used: tool calls, input, output and cache hit rate. | | `agentsHeading(runs)` / `agentsHeadingParts(runs)` | The line over a conversation's agents, naming how many are in each state, e.g. `Agents · 1 queued · 2 working · 1 done`, and its pieces, each with the state it counts. | | `agentsUsageLine(totals)` | The line under the composer naming what the agents used, from `subagentUsage`: how many, their input, output and cache hit rate, and the credits they were charged. | | `USAGE_PENDING` | What `usageLine` says before a provider has reported a window. | | `workflowStatus(run)` | How a workflow run's state reads and the state its hue comes from: `Working` while an agent holds one of its requests, `Waiting` while requests wait for one, `Running`, `Finished`, `Failed`, `Cancelled`. | | `requestStateWord(state)` | How a workflow request's state reads (`Waiting`, `Claimed`, `Answered`, `Failed`, `Cancelled`). | | `workflowElapsed(run, nowSec)` / `workflowProgress(run)` | How long a run has taken, and `{ answered, asked, failed, text }` with `text` such as `2 of 5 answered · 1 failed`. | | `phaseName(name)` / `workflowPhaseLine(run, phases)` | A phase's name (`Start` for the unnamed one), and the phases as `Plan 1/1 · ▸Build 1/3`, the one the run is in marked. | | `workflowStarter(run, title?, agentName?, address?)` | Who started a run: `in “<conversation>”` (or `in DotBot conversation <first 8 of its id>` when the list names it by its id alone), `by agent <name> in ...`, or `by <caller>` from what the engine recorded. | | `requestTiming(req, nowSec, agent?)` | A request's line: the agent working it or the runner holding its claim, how long it has been claimed or waited or took, the claims that ran out and its corrections. | | `answerText(answer, limit?)` | An answer as text: a string as it is, a table of named string, number or boolean fields as one `name: value` line each, anything else as indented JSON, cut at `limit`. | | `workflowsRunningText(count)` | `1 workflow running`, `3 workflows running`. | | `waitingOn(runs, args)` | The Working row while `wait_for_agents` runs: the agents it waits on, by name, newest first as the cards stand, and whether it waits for the first of them; once they have all ended, that they have. | The thresholds the usage ladder turns on are `noticeThreshold` (25) and `warnThreshold` (10).
▲ 0↑ born
·
plugin · born here
❒asset
# dotbot DotBot, the agent in Zero's editor: the component that runs a person's own Claude or ChatGPT plan (or OrigoZero credits) from inside Zero, and the DotBot panel in the editor's right dock that talks to it. This world is where the plugin's published copy lives; the engine's built-in library pins a version of it. ## What is here | Part | What it is | |------|------------| | `plugin.wasm` | The DotBot component (`wasm32-wasip2`), built in the DotBot repo from `crates/dbot-zero-plugin`. | | `plugin.yaml` | The plugin's grants: its scope, the hosts it may reach, its private storage. | | `surface.module` | The plugin's Luau surface, what `require("@builtin::plugins.dotbot")` resolves to. | | `source.module` | What the panel reads: agents, accounts, conversations, history, turns, agents a turn started. | | `service.module` | The trusted service between the panel and the component: calls, the event ring, jobs. | | `panel.editorPanel` | The DotBot panel itself: toolbar, transcript, agents, composer, settings. | | `view.module` | What the panel says and how it looks (`palette()`), apart from how it is drawn. | | `transcript.module` | The transcript and the agents section, drawn as virtual rows. | | `workflows.module` | The Workflows view. | Each module's own README says what it does in detail. ## Seeing a panel change The editor draws its DotBot tab from the built-in library, not from this world, so an edit to the panel here does not show in the real tab. Open the world's own panel code over a fake plugin with example data instead: ```bash luau --lang luau 'require("/source/dotbotPanelPreview.module").open()' ``` It opens a **DotBot preview** tab beside the real one. Run it again after each edit. `dotbotPanelPreview.module/README.md` says what it shows. ## Shipping a change Work on a branch of this world and open a pull request into `main`. How a merged change reaches the engine (publishing `plugin.wasm`, and the engine's pin of this world) is written down in the DotBot repo, in `docs/zero-plugin.md`.
▲ 0↑ born
backing path · dotbot.plugin/workflows.module

Problems

Everything affecting this asset right now: its own problems, anything wrong inside it, and problems on its direct dependencies.

0problems
No problems reported on this asset or on the parts this page shows. Parts it leaves out are not counted here.
⌬ZeroMind agent review · awaiting first pass
Findings
Reviewer findings (handle · model · tag · quoted note) appear here once the per-pass review log lands. Today only the rolled-up agent_score is exposed.
usability—
did it work as advertised
quality—
authoring polish + cohesion
performance—
frame & memory budget held
agent review score
—
/ 100
awaiting first pass
usability × 0.40
+ quality × 0.35
+ performance × 0.25
± compat factor

Usability ratings

Did the part work as advertised when consumers tried to drop it in. Separate from upvotes: those are taste; this is "did it function".

—%no reports yet
Sign in to report whether this part worked for you.
Discussion

Scoped to this part · feeds back into the world's score.

0comments
Sign in to post.sign in
No comments yet. Be the first.