A task running in a workspace shows "Working on a task in <name>
workspace", so the bot's own chat and the main rail say where the work
is. Outside a workspace it stays "Working on a task".
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A workspace's task now carries the bot that has it there (bot_id with
workspace_id), or none while it's shared. A bot reaches its own list and,
in its workspaces, its own tasks plus the shared ones; a workspace admin
every task there. Bots create workspace tasks for themselves by default,
take a shared one by starting it, and hand-overs record the new bot.
Removing or deleting a bot makes its workspace tasks shared again. The
conversation's Tasks modal shows that bot's tasks in the workspace.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A ref quoted alone in a code span now links like any ref, and refs
inside longer code stay literal instead of turning into broken link
text. A file chip opens a file from another bot's folder for a user
who reaches that folder, by the same rule as its bytes, so the
asked bot's files open from the asking bot's conversation. Bots are
told to keep refs out of backticks, and the coordinator to pass them
on as given.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A worker asks for another bot's help with ask_crew. The coordinator
reads the request, asks the right bot (in a workspace, only its
members), and sends the answer back into the asking bot's
conversation, waking it. Each exchange is kept as a read-only
chatroom: listed in the main rail after the workspaces, or in the
workspace's rail for requests made there, with live status rows for
each bot while it's open and a Stop button.
Room sessions are hidden from every conversation list, other bots'
words reach the model fenced as data, and turns, nesting and open
rooms are capped. Closed rooms are pruned after a retention period
and past a cap per place (Settings > General).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A workspace run saves to the bot's own folder unless it picks the
workspace's, but a file chip in a workspace conversation only looked in
the workspace's folder, so those refs rendered as dead text. The chip
now sends both ids and the single-file lookup also searches the bot's
own folder for a user who reaches that bot.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A managed Chrome policy, written as root into each running computer's
container on provision and every sync-computers run, installs the
default extensions (normal_installed: can be turned off, not removed).
Existing computers get it without being recreated.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The update popup showed on installed PWAs after an update had already
landed: the new worker sat waiting behind the open window. Nothing in the
worker is per-version, so it now skips the wait on install, and the
popup is gone.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Bots can now show a concept as a visual: create_graphic (with
update_graphic, read_graphic and list_graphics, on every run, no computer
needed) stores one HTML document in bot_graphics, per user like the
conversation, and the chat renders its [graphic:ID] ref as an inline card
sized to fit, with a large view and a page of its own (no rail).
Graphic HTML is treated as hostile: it is only served at /graphics/<id>
with a CSP sandbox allowing scripts under an origin of its own and no
network, loading only the vendored Chart.js and Mermaid from
/graphics-lib/. The document carries the app's theme vars and scrollbars,
reports its height to the thread, and a frame that navigates away is
closed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Two prompts sent close together (as while a bot is still answering)
shared one row under their group: every copy button bunched beside the
last message's time. Each user message now has its own row, with its
copy button, a new Reply button (once it is saved) and its own time.
copyableMessages is gone with the shared row.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Knowledgebases give bots RAG over documents, scoped like extensions: to
particular bots, to a workspace, or to every bot, with their own button
beside Tools in the composer. Documents are chunked and embedded by the
file-ingest worker with the install's embedding model, which is now an
install-wide setting rather than a per-bot one.
- Word search runs on an FTS5 index ranked by BM25, with a scored LIKE
fallback for scripts written without spaces.
- Changing the embedding model re-indexes documents automatically.
- Ingest jobs wait without spending attempts while every embedding model
rests, fail at once on errors retrying can't fix, and keep passages
searchable by words when the model refuses.
- Settings > Knowledgebases shows each knowledgebase's and document's
index state: spinner, warning, grey check (words only) or green check.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
MCP, skill and tool rows in Settings say "Updated 5m ago" beside how
they're reached and who gets them. updated_at now means a change to an
extension's settings (an edit, or any Access save): runs, connections and
MCP syncs keep their own last_checked_at / last_synced_at and no longer
touch it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sessions from v0.2.8 and earlier were linked to the one before them by
every rollover and New session, so production threads offered "Show the
previous session" (and prompts read summaries) for sessions nothing was
carried from. A link is kept only when the session opens with a message
carried from that session.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Coordinator and worker come from bots.kind; bot_types now only holds
workspace_admin (was admin), each row naming its workspace, with no scope
field. Rows from v0.2.8 and earlier are fixed at boot by migrateBotTypes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- The conversation page tells the rail and the sessions modal which
session it shows (announceShownSession, useShownSession); they reload,
so a session reopened by ?session_id= shows at once.
- Only that session is Current and greyed out (the active one without
?session_id=); the active row then leads back to it.
- The rail lists the session on screen even when it's older than its
latest sessions.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Bots get continue_in_new_session: the bot writes a title and summary,
the session closes for good (read-only) and the new one opens with the
summary as a "Carried over from the last session" message that links
back to the old session.
- Continue in new session (conversation menu, sessions modal) and the
automatic rollover at the session length do the same; New session now
starts a fresh, unlinked session.
- Session length is an app setting in Settings > General.
- ?session_id= opens a session; a carried-over one shows a bar linking to
where the conversation went on instead of the composer.
- The thread can open the previous session above the current one (shown
only, never in the prompt), and replies get search_past_sessions and
read_past_session.
- Sessions are named from their opening messages, not their latest, and
a carried summary is labelled as the earlier session's.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A hook run follows its brief over the bot's memory. When the two disagree,
the run now reports the conflict and says the brief needs changing, rather
than offering to fix its memory. In chat, a change to how a hook's calls are
handled is proposed as a new brief, not saved to memory or promised.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A hook call used to record only how it was taken; its run's answer went
to the chat alone and was lost to the call once the job was pruned. Now
`bot_hook_events` keeps `response`, `response_message_id` and
`responded_at`, written on every call a run took in when that run ends
(completed, failed, lost, stopped or cancelled) by
`recordHookCallResponse` in the job helpers, and calls turn done or
failed. The Calls view searches what calls sent and what runs answered,
filters by status and pages; Show all loads one call whole. Bots get
`search_hook_calls` and `read_hook_call` for their own hooks (never in a
hook call's own run), with payloads always marked as outside data.
Calls are kept for the app setting `hook_events_keep_days` (Settings >
General, default now 30 days). The caller still only gets 202 Queued.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A hook's calls used to run in whatever session was active at the time.
Now `bot_hooks.session_id` pins them to one session, open or closed
(null still follows the active one). The hook form picks where it runs
(the bot's own chat or one of its workspaces) and a session there, or a
new one of its own started beside the active one so the chat on screen
stays. A bot's proposed hook gets the session it was proposed in, and a
missing session is replaced on the next call. Changing place or session
is refused while a run is open; the computer stays only if reachable.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A new personal env scope (paradigm user: one user's secret for one bot)
beats every other scope, reaches only that user's runs of that bot, and
is redacted like any secret. Bots take secrets in with request_secret,
which puts a [secret-request:ID] card in the chat: the user types the
value into a masked input there, never into a message, and the bot is
told only the key. Bots show secrets with capture_secret (a task's
computer tool that saves a file or a command's output straight to a
personal env, then redacts it from the rest of the run) and show_secret
(an env by key): both give a [secret:ID] chip whose Reveal and Copy fetch
the value on click, for its own user (personal) or a super admin
(anything else), logged by key. Values never go into messages, page
props, history, Copy chat or logs. Users manage their own secrets on
Settings > Secrets; the Environment page lists everyone's, remove only.
Deleting a bot or user removes its personal secrets, and SecretsNote
tells bots never to ask for or print secrets in chat.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
propose_skill took no strict schema, so a runbook sent under another key
was dropped and the saved one proposed again; the confirm still said
"Saved". Now an unknown key is an error, a change that changes nothing is
refused, and both the bot and the confirm outcome are told which fields
change and whether the runbook is among them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Each computer's Chrome profile now lives on the data volume
(DATA_DIR/computer-browsers/<id>, mounted at ~/.cobble-browser) and
Chrome is pointed at it with --user-data-dir. The sandbox image resets
its own profile's preferences to session-only cookies on every boot,
which signed every site out whenever Chrome exited. New profiles are
seeded with the image's preferences minus that rule, stale Singleton
links are removed before each provision, and existing computers are
recreated once (skipped while a job runs on them).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Bots get list_hooks, pause_hook and delete_hook, which act directly since
they only take away. A new hook, or a new name, brief or filter, or
switching a paused one back on, goes through propose_hook: it stores a
hook_proposals row and puts a [hook-proposal:ID] card in the reply, which
the user it was proposed to confirms or rejects. The card is read from
what Confirm saves, with the bot's reason labelled as its own; confirming
checks everything again and saves through the Hooks modal's helpers. A
new hook's URL is shown on the card once, to the user only, never in the
outcome the bot is told. What calls a hook, its computers and its signing
are never proposed. Only chat replies propose, and a hook call's own run
gets no hook tools, so a caller's payload can't reach them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A bot hook (bot_hooks) is a secret URL, POST /api/hooks/<token>, whose
calls queue the hook's brief plus the raw body as a task, per user and
bot like a routine. Only the token's hash is kept (shown once, rotatable);
an optional HMAC-SHA256 signing secret is stored encrypted. Calls are
rate limited per address and per hook, recorded in bot_hook_events
(pruned daily), deduplicated by delivery id, and a call while the last
run still waits joins its brief instead of queueing another. The payload
is fenced data and HookRunNote tells the bot never to take instructions
from it; failed runs retry like routines.
A hook can instead watch a computer's browser notifications: the app
installs a small watcher that owns org.freedesktop.Notifications on the
sandbox's session bus, so Chrome hands it every notification (it only
looks for that service at start-up, so Chrome is restarted once, never
mid-task), and it posts each one to its hooks, optionally filtered.
Computers reach the app at COMPUTER_APP_URL or the app container's name.
Users make hooks in the conversation's Hooks modal and manage them all
on /admin/routines; bots never create or change hooks.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A bot's instructions and memory for one workspace were only reachable
from the workspace's settings. The editor is now shared and also opens
from the conversation menu in that workspace ("Instructions here",
loaded on open through api/admin/workspaces/workspace-bot) and from the
workspace rows on the bot's settings page.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The conversation header menu gets a Copy chat row that puts the active
session on the clipboard as one markdown document: a summary, then each
message under its author and time, with quotes, attachments and
reactions. Bot and workspace refs read as names, message headings drop
below the message headings and code blocks stay untouched. The clipboard
write starts on the click with a pending ClipboardItem so Safari allows
it after the fetch.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The wrap-up turn now gets the run's actual tool calls, each bot message
keeps them as bot_messages.tool_log, and history follows recorded bot
messages with an [App record] line. The coordinator also gets update_bot
in workspaces, so it can fill a bot's core prompt from there.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
delegate_task takes a task_id to hand over a task already on a list: it
moves to the worker (a workspace's task stays on its list), goes to
doing, and the job is linked back so its end is noted on the task.
hand_over_schedule moves a bot's own routine to another bot, keeping its
workspace. Users get Hand over in the Tasks UI and both routine lists.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Settings > General gets an App icon (super admin): one of the seven
stones, or an uploaded image with the picked stone as a top-left corner
mark (inside a round launcher's crop, clear of the browser's badge),
previewed in both launcher crops before saving.
Uploads are decoded and cropped to a stored square (no SVG); the set is
drawn into DATA_DIR/install-icon/<version>/ and served publicly and
immutable. The manifest, head icon links and push notifications point at
it; the ember stone keeps the stock icons. The generator shares the icon
renderer.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Settings > General: an App name (super admin) for the installed app.
The manifest's name/short_name, the iOS head tags and the loading
page's title use it, so two installs on one phone can be told apart.
- Notifications get a real badge (white stone silhouette): Android masks
the badge by alpha, so the opaque app icon showed as a square.
- The loading and offline pages load the app's font.
- The font is now Archivo (variable, one request for every weight),
matching the marketing site.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The longest runbook a skill may save and how much of it load_skill hands
back are now set on Settings > General (skill_body_max_chars,
skill_body_shown_chars), defaulting to AppData.SkillBodyMaxChars and
SkillBodyShownChars. Saving, confirming and proposing a skill check the
install's limit; a skill saved before it was lowered can still be toggled.
Co-Authored-By: Claude Opus 5.5 <[email protected]>