Mods

Live cards for your own objects, in every agent reply.

Codecast already draws its own objects as live references: a task, a pull request, a decision. A mod adds yours, like incidents, customers, deploys or rows in your own product. An agent writes a short id, and you see the object with its current state, a card on hover and a page one click away.

16
kinds built in
9
field types for yours
0
deploys to change a mod
Checkout failing for some customersclaude · working
Checkout is failing for some customers. What happened?

The errors start with #3263Batch webhook retries per endpoint, which went out in the 2:10 deploy. I opened ct-4102Revert the retry storm in the webhook worker to revert it and put the previous build on a canary:

```rollout
{ "service": "payments-api", "build": "v412", "canary": 25 }
```
Releases·rollout
payments-apiv412 canaryholding
25%
traffic on v412
0.2%
errors · v412
6.1%
errors · v413
error rate, last 40mcanary at 2:31
Promote to 50%Roll backOpen deploy

Hit hardest: cus-3f9a21bcAcme Logistics and cus-77d0e412Northwind Bakery. Promote the canary once errors hold under 0.5%. Tracking it as inc-7Checkout 502s after the 2:10 deploy

Checkout 502s after the 2:10 deploy
mitigating
severity
sev-2
service
payments-api
commander
Dana
started
Oct 16, 2:14pm

Error rate jumped from 0.1% to 6% when v413 went out. Canary on v412 is holding.

inc-7 · Incident · Incident deskOpen
.

What the agent wrote, next to what you see

Everything in that reply came from a few hundred characters of plain markdown: five ids and a three-field block. Codecast resolves each id from your workspace and draws it with its title and state; the block goes to the mod that claims it, which draws it from live data.
Point at anything on either side to find its other half. The agent never formats a status, a price or a chart; it writes the id and codecast fills in the rest.
what the agent wrote321 characters

The errors start with #3263, which went out in the 2:10 deploy. I opened ct-4102 to revert it and put the previous build on a canary:

```rollout { "service": "payments-api", "build": "v412", "canary": 25 } ```

Hit hardest: cus-3f9a21bc and cus-77d0e412. Promote the canary once errors hold under 0.5%. Tracking it as inc-7.

what you read

The errors start with Batch webhook retries per endpoint, which went out in the 2:10 deploy. I opened Revert the retry storm in the webhook worker to revert it and put the previous build on a canary:

Releases·rollout
payments-apiv412 canaryholding
25%
traffic on v412
0.2%
errors · v412
6.1%
errors · v413
error rate, last 40mcanary at 2:31
Promote to 50%Roll backOpen deploy

Hit hardest: Acme Logistics and Northwind Bakery. Promote the canary once errors hold under 0.5%. Tracking it as Checkout 502s after the 2:10 deploy.

References keep updating after the message is sent

A pill reads its object every time it draws, so the thread you scroll back to tomorrow shows where things stand now: the revert done, the incident resolved, the customer recovered. Nobody has to edit the old reply.
A mod object that reaches its kind's last status dims in place, so finished items stand apart from open ones.
Checkout failing for some customersnext morning
The errors start with Batch webhook retries per endpoint, which went out in the 2:10 deploy. I opened Revert the retry storm in the webhook worker to revert it. Hit hardest: Acme Logistics and Northwind Bakery. Tracking it as Checkout 502s after the 2:10 deploy.
Checkout 502s after the 2:10 deploy
resolved
severity
sev-2
service
payments-api
commander
Dana
started
Oct 16, 2:14pm

Error rate jumped from 0.1% to 6% when v413 went out. Canary on v412 is holding.

inc-7 · Incident · Incident deskOpen
Northwind Bakery
active
plan
Team · 8 seats
MRR
$640
failed charges
5 since 2:14pm
cus-77d0e412 · Customer · BillingOpen

Sixteen kinds built in

Out of the box, codecast resolves its own objects wherever markdown renders: in replies, docs, task comments, chat and published pages. Each kind has its color, its mark and a card that shows what you would open it to learn. A task shows its status and owner, a pull request its checks and threads, a decision its options and which one you picked.
Write @[Title id] to keep the title in full on every mention. A bare id shows its title the first time and stays short after that, so a paragraph that names one task five times still reads cleanly.
in a sentence

See Retry webhook deliveries for the details.

on hover
Retry webhook deliveries
working
agent
claude · opus
project
api
files
6 changed

Swapped the fixed 30s retry for exponential backoff with jitter; replaying the outage fixture now.

+142 −38
jx7c6zkOpen

Open a reference as a pill, a card or a page

The same reference opens three ways without leaving the conversation. Inside a sentence it is a pill. On a line of its own it becomes a card you can expand to full width. A click opens its page. The arrow on a pill opens that page right under the line, so you read it in place and fold it away.
1In a sentence

Its title and state, inline with the text.

Rolled back after Checkout 502s after the 2:10 deploy and paused the deploy train.
2On its own line

A card with a real snippet, which expands to the full width of the reply.

mitigatingsev-2 · payments-api

Error rate jumped from 0.1% to 6% when v413 went out. Canary on v412 is holding.

3Its own page

Every field, editable. The mod can draw its own view above them.

Incidents inc-7
Checkout 502s after the 2:10 deploy
triagemitigatingmonitoringresolved
severitysev-2
servicepayments-api
commanderDana
startedOct 16, 2:14pm

Error rate jumped from 0.1% to 6% when v413 went out. Canary on v412 is holding.

Add your own object kinds

A kind is a few lines in a mod's manifest: a prefix, its statuses in order, and typed fields. From that, codecast gives your kind what its own objects have: numbered ids, a pill in every conversation, a card on hover, a board and a table, a page for each object, and commands your agents use to file and update them.
Ids only become pills when a mod declares the prefix, so covid-19 in a sentence stays prose. A kind stays recognised while its mod is switched off.
incident-desk / codecast-mod.json
"objects": [{
"prefix": "inc",
"title": "Incident",
"plural": "Incidents",
"icon": "flame",
"statuses": ["triage", "mitigating", "monitoring", "resolved"],
"fields": {
"severity": { "type": "enum", "options": ["sev-1", "sev-2", "sev-3"] },
"service": { "type": "text" },
"commander": { "type": "person" },
"started": { "type": "date" },
"session": { "type": "ref" }
}
}]
A pill everywhere markdown renders

Messages, docs, comments, chat, published pages. inc-6 is resolved, so it dims.

Refund webhooks retry with no cap Checkout 502s after the 2:10 deploy Search index lagging behind writes
A board and a table

One column per status, drag to move. A New incident field on top.

triage
inc-8
Refund webhooks retry with no cap
mitigating
inc-7
Checkout 502s after the 2:10 deploy
monitoring
resolved
inc-6
Search index lagging behind writes
A page per object, with typed fields

A severity picker, a person picker, a date, a link to the session it came from. All editable.

severitysev-2
servicepayments-api
commanderDana
startedOct 16, 2:14pm
sessionCheckout failing
Verbs for every agent
$ cast obj create inc "Refund webhooks retry with no cap" --set severity=sev-3
  created inc-8
$ cast obj set inc-7 status=monitoring

Show objects that live in another system

Most of what your team talks about already lives somewhere: customers in your database, orders in your store, tickets in a support tool. An external kind stores nothing. Its ids carry the other system's id, and a small hook answers what each one is called and where it stands, live, every time it draws.
One of our own mods maps nineteen kinds from a product we run (contacts, requests, matches, calls) through a connector. Agents working on that product write those ids in every reply.
billing / ui.tsx
// "external": true in the manifest: nothing is stored in codecast.
on("object.resolve", { object: "cus" }, async ($, e) => {
const r = await $.http.fetch(`https://api.acme.dev/customers/${e.id}`,
{ secret: "acme_admin" });
if (!r.ok) return null;
const c = r.json;
return {
title: c.name,
status: c.health,
fields: { plan: c.plan, mrr: c.mrr, owner: c.owner },
};
});

The API key stays on codecast's server. A request that names a secret is sent from there, only to the origins that secret allows, and no browser ever holds the key. A connected product can be read through $.connector.read instead, as the person who is looking.

Billing retries · payments
Twelve charges failed for Acme Logistics since the deploy and five for Northwind Bakery. Both retried cleanly once the canary took over.
Northwind Bakery
churn risk
plan
Team · 8 seats
MRR
$640
failed charges
5 since 2:14pm
cus-77d0e412 · Customer · BillingOpen
cus-3f9a21bc
what the agent wrote
1 call
your API, per draw
0 rows
copied into codecast

Blocks that draw live data and buttons

A mod can claim a fenced block type. The agent writes a few fields; the mod draws them with live data, as stats, charts, tables and buttons, in every place markdown renders. With the mod off, the block shows as plain code.
Mods draw with codecast's own elements: cards, tables, stats, sparklines, charts, tabs, pills. A block looks native in light and dark, in every theme, because a mod may only use the theme's colors.

Canary is out on the previous build:

Releases·rollout
payments-apiv412 canaryholding
25%
traffic on v412
0.2%
errors · v412
6.1%
errors · v413
error rate, last 40mcanary at 2:31
Promote to 50%Roll backOpen deploy
cast-canvas

Built in. A one-off drawing the agent writes as HTML for one reply. Static once sent.

a mod's block

Code that draws from live data, for everyone with the mod, every time the block appears.

releases / ui.tsx
on("ui.render", { fence: "rollout" }, async ($, e) => {
const { service, build } = JSON.parse(e.props.code);
const url = `https://deploy.acme.dev/${service}/${build}`;
const r = await $.http.fetch(url, { secret: "deploy" });
const d = r.json;
return (
<Card title={service}>
<Grid columns={3}>
<Stat label="traffic" value={`${d.canary}%`} />
<Stat label="errors" value={d.errors.canary} tone="green" />
<Stat label="errors" value={d.errors.current} tone="red" />
</Grid>
<Sparkline values={d.errors.series} tone="red" />
<Row gap={2}>
<Button variant="primary" onPress={() => promote($, d, 50)}>
Promote to 50%
</Button>
<Button onPress={() => rollback($, d)}>Roll back</Button>
</Row>
</Card>
);
});

Agents learn your kinds when the mod is installed

A mod carries a short note for agents: what its objects are, which blocks it draws, when to reach for them. Every session the mod applies to starts with that note. So the incident an agent notices at the end of a long task gets filed as inc-8 instead of being mentioned once and forgotten.
incident-desk / AGENTS.md
Incidents (inc-N): mention one by its short id and it
reads as a live reference. When you find a problem you
are not fixing in this session, file it with
cast obj create inc "<title>", or write a finding block
and let the person file it with one click.
Every session the mod applies to starts with this note.
Retry webhook deliveries · api

The payments worker now backs off with jitter and caps at five tries. While tracing it I found the same pattern somewhere I am not touching:

Incident desk·finding
Refund webhooks retry with no cap

Same pattern as the payments worker: a provider outage multiplies into a retry storm. Not fixing it in this session.

sev-3refunds-worker

Panes, commands, sidebar sections and themes

The same mod can give your team a screen of its own. A pane is a full page drawn with codecast's own cards, tables, stats and charts. It reads your sessions, tasks, plans and pull requests from the app's local store, so it fills instantly and updates as sessions move, with no server of your own behind it.
codecast
Incident deskv3 · r122
3
open
2
sev-2 or worse
38m
median to resolve
inc-7Checkout 502s after the 2:10 deploymitigating
inc-5Image CDN 404s in eu-westmonitoring
inc-9Login emails delayedtriage
inc-6Search index lagging behind writesresolved
incident3
Mods
Incident deskOpen board
Incident deskDeclare an incident
ReleasesPromote canary on payments-api
  • 1
    Sidebar sections under the app's nav

    A titled section the mod draws, like the open incidents with their live state.

  • 2
    Panes a tab, or one cell of a split

    A whole screen, drawn from your store, filled the instant it opens.

  • 3
    Palette commands a Mods group in the command palette

    Open a pane, or run in place. A failure shows as a toast.

  • 4
    Themes Settings, Appearance

    A palette for light and dark that recolors the whole app.

The Fleet Pulse mod open as a pane in codecast: four stat tiles over a table of sessions waiting on the viewer
A real one: Fleet Pulse, a small mod running as a tab. Its tiles and the Waiting on you table read straight from the local store.

Build a mod by asking for it

Describe the mod in the conversation; your agent builds it and pushes, and the running pane appears in the thread. Each change you ask for lands in place: the header flashes and the revision ticks up. It is live in your app seconds after each push, with no deploy.
A pane that fails to draw shows Try again in its own spot, a failed redraw keeps the last good drawing, and the agent reads the same Logs you do.
Incident desk mod · ops
Make me an incident desk: open incidents, who is commander, how long each has run.
pushed r1
Group it by service and show each severity.
pushed r2
Add the error rate for each service over the last hour.
pushed r3
Incident deskr1r2r3LogsOpen
3
open
2
sev-2 or worse
2h 10m
longest running
payments-apisev-2Checkout 502s after the 2:10 deploy
cdnsev-2Image CDN 404s in eu-west
authsev-3Login emails delayed
1Describe
what you want, in the thread
2Push
live in your app in seconds
3Steer
each change redraws in place
4Publish
a numbered version with its source

Read data from your own machines

Some facts live on a laptop or a server: a log file, a running process, a GPU, a local database. A mod's local half runs in the codecast daemon on your own machines, reads what they can read, and publishes values its panes and blocks draw from. It can file objects too, so a spike in a log becomes an incident on the board.
A local half runs only where a person approved that exact version, by typing the mod's name in a terminal on that machine. Agents are told they cannot approve their own, and a new version waits for a new approval.
incident-desk / local.ts
on("local.start", ($) => {
$.every(10_000, async () => {
const { stdout } = await $.sh("tail -n 2000 /var/log/payments/api.log");
const lines = stdout.split("\n");
const errors = lines.filter((l) => l.includes(" 502 ")).length;
$.publish("payments.errors", errors);
if (errors > 50) await $.objects.create({
prefix: "inc", title: "payments-api 502s on " + $.device,
fields: { severity: "sev-2", service: "payments-api" },
});
});
});
build-box
Linux · approved v3
3
502s in 10s
dana-mbp
macOS · approved v3
0
502s in 10s
sam-mbp
macOS · not approved
$ cast mod approve incident-desk

Each mod reaches only what it was granted

Each mod runs in a locked-down frame of its own, with no access to the page around it. Its manifest says what it reads, what it writes and which sites it may call, and every read and write is checked against that. Building a mod fails on code that reaches past its grants, and names the grant it would need.
Incident desk
Shared by Dana · v3 · panes, a block, the inc kind
Install
reads
sessions, tasks, pull requests
writes
incidents (its own kind), tasks
fetches
deploy.acme.dev
secrets
deploy, kept on the server
Grants changed: reviewwhat you see if v4 asks to read more
  • A teammate's mod runs for you only after you press Install, at the grants on its card.
  • Keys never reach a browser. Requests that need one are sent from codecast's server.
  • It writes only the kinds it owns, and sees your name, never your email.
  • Every version keeps its source: readable, diffable, one step to roll back.
For scripts and agents

Mods are built by agents, so the build loop is a handful of commands. You can run them yourself too.

cast mod new <name>a working scaffold: a pane, a command and a block
cast mod buildbundle, typecheck, and check the code against its grants
cast mod pushlive in the app within seconds; prints the pane's link
cast mod logs <name>what it printed and threw while drawing
cast mod publish -m <note>a numbered version with its source
cast mod rollback <name>back to an earlier version
cast mod guidewhat every running mod asks of agents
cast obj kindsevery object kind in this workspace
cast obj create <prefix> <title>file an object, with --set field=value
cast obj set <id> status=<s>move it along

Get started with mods

Install codecast, open Agent features from your account menu and switch on Mods. Then ask an agent for the first one: the incident desk, the customer lookup, the deploy panel your team keeps asking about.

Script
curl -fsSL codecast.sh/install | sh
Also via brew install codecast-sh/tap/codecast or npm install -g @codecast-sh/cli