Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/brains/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "brains",
"description": "Your memory layer: Gmail, Calendar, Drive, and prior Claude conversations as queryable pages, with reflexive recall, hook-driven turn-by-turn capture and inbox delivery, and boards/automations/workflows on top.",
"version": "2.7.1",
"version": "2.8.0",
"author": {
"name": "brains (ssvlabs)"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/brains/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "brains",
"version": "2.7.1",
"version": "2.8.0",
"description": "Your personal memory layer for Codex: query Gmail, Calendar, Drive, and prior conversations, then build boards, automations, and workflows.",
"author": {
"name": "brains (ssvlabs)",
Expand Down
28 changes: 23 additions & 5 deletions plugins/brains/generated/capability-catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,34 @@
"artifacts": [
{
"capability_id": "integration-actions",
"catalog_sha256": "c46b9cf2f88ed3cefe0f5766665c12f06dafaa0e56dba1f5586ab9cd56c39ac2",
"catalog_sha256": "29f58ddc5dab294814934fe7af0d808f4b7dc441e3c3d29bb0e67fa705d7add4",
"artifact_path": "plugins/brains/skills/brains-write/SKILL.md",
"artifact_sha256": "f14839e4ed852771fc8dd91b0196f9caeeb63ce56dead747a53d83fd83dd9475"
"artifact_sha256": "b27acd2ffc1ba4914890a88dba00e71f7052bd738369f28f9d86a1566bd2f548"
},
{
"capability_id": "brains-features",
"catalog_sha256": "03c153311f597a651c9719dc17229e6677b4c2b2823458b0b50c12617146a5bd",
"catalog_sha256": "6086cbe9877b2005b3cea06611ba74ab7b527eaed04af39e5a815c94c8806b37",
"artifact_path": "plugins/brains/skills/brains-build/SKILL.md",
"artifact_sha256": "8e377f866efdbf6653cda64fcc44cef6a8038e1d74dfd2311af4a0ded434c237"
"artifact_sha256": "753afa4d8b4833b91622fa8c55d2bc76304e9a9170faed3365c7febd53836ae0"
},
{
"capability_id": "procedure:board",
"catalog_sha256": "d9242158554683b1b18ac2f26ebfecf6c0d42c00e480524be2e6ee35df1fb879",
"artifact_path": "plugins/brains/skills/brains-board/SKILL.md",
"artifact_sha256": "bfc28da5ef20ec559fe10bd9b21d2d7ca673de5533f012bd9cfaa3947241cf6f"
},
{
"capability_id": "procedure:automation",
"catalog_sha256": "ea1e883788e138e39b80627e5a14d6ac35dc7f658b4628e7e32084bb6620fe8b",
"artifact_path": "plugins/brains/skills/brains-automation/SKILL.md",
"artifact_sha256": "e71b5648d93e611de49fd81549217db8232427262e282af6d1c1d70c9c2e17c9"
},
{
"capability_id": "procedure:workflow",
"catalog_sha256": "ec1f5989adae2630f16879299f05cc79c6aabfd9897c968c69618882b35f1278",
"artifact_path": "plugins/brains/skills/brains-workflow/SKILL.md",
"artifact_sha256": "b22814fd630ed78964d54440ec327e3aebcde8c812aaa9985fff9c4d345d3f09"
}
],
"source_commit": "9888bc944d0a3e5d2c178eaaf8b23811364457d9"
"source_commit": "864c45fa7e1c4b4d60116b6697abc596a272fbff"
}
623 changes: 623 additions & 0 deletions plugins/brains/skills/brains-automation/SKILL.md

Large diffs are not rendered by default.

172 changes: 172 additions & 0 deletions plugins/brains/skills/brains-board/SKILL.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions plugins/brains/skills/brains-build/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: brains-build
description: The catalog of what brains can do beyond search — board, board skill, bulk upload, dashboard, page, automation, recurring brief / digest, workflow, mini-site, board source link, dataset recipe, integrations, telegram bot. Use when the user asks "what can brains do", asks how to do X in brains, or describes a shape one of these fits. They might say "track a list of…", "every morning do…", "build me a deck…". Routes to the tool, flow or skill that owns it.
name: "brains-build"
description: "The inventory of what brains can do beyond search. Use when the user asks \"what can brains do\", \"can brains do\", \"what else can brains do\" — a capability question, not a request to build one. Yields to brains-board / brains-automation / brains-workflow the moment they want one made. Answers name the feature and route to whatever owns it."
---

<!-- Generated by ssvlabs/brains apps/mcp/scripts/generate-capability-catalog.ts.
Expand All @@ -18,7 +18,7 @@ Don't restate that artifact here — open it.
| **Bulk upload** | Load a large or arbitrary-format file into a board without reading it into context. | `create_import_grant` → `bulk_append_rows` |
| **Dashboard** | A live, interactive view of a board that you author as a full HTML app. | `get_dashboard` → `set_dashboard` |
| **Page** | A first-class note in a brain. | `create_page` |
| **Automation** | A sandboxed TS program on a cron schedule with a scoped token. | `create_automation_flow` if your client exposes it (follow the playbook it returns), otherwise the Automations page (`/automations`) |
| **Automation** | A sandboxed TS program on a cron schedule with a scoped token. | `create_automation_flow` if your client exposes it (follow the playbook it returns), otherwise the Agents page (`/agents`) |
| **Recurring brief / digest** | Install a prebuilt automation that sends a recurring summary instead of scaffolding one. | `list_recipes` → `install_recipe` |
| **Workflow** | A goal container: charter, KPIs, deadlines, roster, an owned board and template automations. | `create_workflow_flow` if your client exposes it (follow the playbook it returns), otherwise `create_workflow` |
| **Mini-site** | Static sandboxed HTML on a brain — a deck, a one-pager, a shareable link. | `create_mini_site` |
Expand Down
178 changes: 178 additions & 0 deletions plugins/brains/skills/brains-workflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
---
name: "brains-workflow"
description: "Set up a workflow — a goal container with KPIs, deadlines, a roster of brains users, its own board and template agents that track progress. Use when the user is organising a project rather than a list: \"ship X by Q3\", \"coordinate this initiative\", \"set up a project with KPIs and a team\". A plain board is the simpler answer for tracking alone."
---

<!-- Generated by ssvlabs/brains apps/mcp/scripts/generate-capability-catalog.ts.
Source: the authoring procedure catalog. Do not hand-edit. -->

# Create-workflow flow — run this with the user

You're guiding the user through scaffolding a **workflow**: a goal-shaped container with KPIs, deadlines, a roster of brains users, an owned board, and a set of template agents that track progress, nudge people, and review milestones. The workflow is created **active** by default — attached agents start firing on their crons immediately.

A workflow is more than a board — it's the whole project around it. When the user deletes the workflow, its board and agents go with it.

Walk the user through these steps. **One question per turn.** Do not skip ahead. Do not call `create_workflow` until Step 7 confirms structure.

---

## Flow state — one line, every turn

End EVERY message in this flow with a checkpoint (last line, above any chips), so a later turn
can pick up where you left off:

`FLOW workflow · step 1/10 purpose · done: (none) · facts: (none) · next: the user's answer to the question above`

Steps in order: `purpose`, `kpis`, `deadlines`, `roster`, `inputs`, `templates`, `confirm`, `provision`, `smoke_test`, `handoff`. Write `(none)` in a segment that has nothing yet.
When the flow is finished emit `FLOW workflow · done` instead, or
`FLOW workflow · cancelled` if the user drops it — without that,
the flow looks live forever.

`done:` records what you have already CREATED, with the id the call returned — `workflow_id=…`. Write it there the moment the call comes back. It is the only record that survives: a confirmation means the user said yes, not that the write happened.

`facts:` carries the decisions you cannot re-read from the conversation — `templates`. Keep each one short.

**Picking up a flow already in progress:**

1. **Before creating anything, check whether you already did.** If the last checkpoint names an
effect for the step you are about to run, that artifact exists — look it up by its id, tell the
user, and continue from the next step. Never create a second one.
2. Checkpoint present and readable → carry on from the step it names.
3. Checkpoint garbled → re-emit a corrected one from what you can see, then carry on.
4. No checkpoint but you still have this procedure → work out where you are from the
conversation, say in one line where you are resuming, and confirm before any write.
5. No checkpoint and no procedure → do not improvise the steps; the gates in here are not
optional. The one exception: if the user asks to pick a flow back up and you no longer have its procedure in front of you, reload it once — then continue from the last checkpoint rather than starting over. Never re-fetch one you can still see.
6. Nothing recoverable → start over, but collect everything in ONE question instead of walking
the whole interview again.

## Step 1 — Purpose & success

If a `purpose_hint` came in, echo it back as your understanding ("So you want a workflow for X — is that right?") and skip cold-asking.

Otherwise: ask what the workflow is trying to achieve. One sentence.

## Step 2 — KPIs

Ask: what measurable signals tell the user this workflow is succeeding? 1–4 KPIs. For each: a name, a target value, optional unit, optional deadline.

Examples:
- `{ name: "signed customers", target: 5, deadline: "2026-08-01" }`
- `{ name: "NPS", target: 50, unit: "score" }`

Don't accept fuzzy goals as KPIs — push back if the user says "engagement" without a number.

## Step 3 — Deadlines & milestones

Ask: hard end-date + any intermediate beats (milestones). At least the end-date.

Format: `[{ label, date: "YYYY-MM-DD" }]`.

## Step 4 — Roster

Ask: who's involved, by role. Roles: `owner` (you), `contributor` (does work), `observer` (gets digests, no nudges).

Every roster member must be a **brains user** — look them up with `whoami` for the caller, and ask the user for emails/handles of the others. If a named person isn't yet a brains user, say so plainly ("X isn't on brains — invite them first, or skip them for now") and continue without them.

Resolve each member to a `user_id` (UUID) before moving on. Look up via the explicit user roster (whoami / brains user search) if you have it.

## Step 5 — Inputs (auto-detect, then confirm)

**Do not ask cold.** First, infer the workflow's domain from the purpose + KPIs (product? sales? hiring? research?). Then:

1. Call `list_integrations` and pick 0–3 that fit the domain. Examples:
- product / engineering workflows → `github`
- sales / CRM workflows → `gmail`, `calendar`
- research / planning → `drive`
2. Call `list_boards` and pick 0–3 by name match against the purpose.

Then say: *"Based on what you're shipping, I think these are relevant: <integrations + boards>. Want me to add anything else, or remove any?"* Skip the question entirely if nothing turned up.

Collected names + ids go on the charter as context, not as wiring.

## Step 6 — Recommend templates (assertive)

**Do not enumerate-and-ask.** Recommend all three by default. Say something like:

> *"I'll attach all three templates: **progress_scorer** (daily % to KPI), **task_nudger** (daily due-soon digest pushed to your Telegram bot), and **milestone_reviewer** (Friday LLM recap). Speak up if you want to drop any or tweak crons — otherwise defaults."*

The three v1 templates + defaults:

1. **progress_scorer** — `0 9 * * *`, slip_threshold_pct=50.
2. **task_nudger** — `0 8 * * *`, window_hours=24.
3. **milestone_reviewer** — `0 18 * * 5`.

Each template gets saved as an **active** agent owned by this workflow — its cron starts firing as soon as the workflow is created. Only ask granular questions if the user pushes back. Otherwise move on.

## Step 7 — Confirm proposed structure

Show the user a tight summary:

```
Workflow: <title>
Charter: <one line>
KPIs: <count> — <names>
Deadlines: <end-date> (+ N milestones)
Roster: <count> people — <owner>, <names>
Owned board: "<title> — tasks"
Owned dashboard: progress + tasks (auto-provisioned)
Agents to attach: <selected templates>
```

Ask: "Look good? I'll create it active — attached agents start firing on their crons immediately. You can flip it to paused from /workflows/<id> if you want to halt them." Wait for explicit yes.

## Step 8 — Provision (single call)

When the user says yes, call `create_workflow` ONCE with:

```
title, charter, kpis, deadlines, roster,
automation_templates: [{ template_id: "...", params: { ... } }, ...]
```

The tool creates, in one transaction: the workflow row (status=active), the owned board (with a "tasks" dataset), a **default progress dashboard** attached to that board, and one agent row per selected template (state=active, workflow_id set, source rendered from the template + params). Returns `workflow_id` + `board_id` + `automation_ids` (array, one per attached template) + `workflow_url` + `dashboard_url`.

Do NOT hand off to the user yet — Step 8.5 must run first.

## Step 8.5 — Smoke test every attached agent (mandatory)

A template that renders cleanly is not the same as a template that runs cleanly. Render-time substitution can still produce source that fails on a missing tool grant, a board row shape the template assumed, an empty roster the cron summary crashes on, or a typo in a field name. **Never tell the user the workflow is ready until each attached agent has actually executed once.** Templates are not exempt — they're more likely to silently break than hand-written source, because the user never read them.

For each `automation_id` returned by `create_workflow`, call `run_automation_once` with:

- `automation_id` — the id from the array
- `dry_run: true` — execute the source against a real trigger payload but suppress outbound writes; same hook as the admin Dry-Run button

The tool enqueues a `trigger_kind='manual'` run and polls `automation_runs` until it terminates or `wait_seconds` elapses (default `max_wall_seconds + 90`). Run them sequentially so failures are easy to attribute; do NOT fan out in parallel.

Read each result:

| `status` | What to do |
|---|---|
| `succeeded` | Note one line of `stdout` to confirm intent (e.g. *"progress_scorer: scored 0/4 KPIs, no slip"*). Continue. |
| `partial` | Exit 0 but stderr non-empty — the template caught errors and kept going. Treat as a failure for smoke-test purposes: show the user the `stderr` tail, patch via `update_automation` (usually a retry/backoff around the failing call), and re-run. Don't continue until it goes fully green. |
| `failed` / `killed` | Show the user the `error` field + tail of `stderr`. Common shapes: tool-grant mismatch (`tool 'X' not in grants`), empty roster (`Cannot read properties of undefined`), missing field on the freshly-created board. Patch via `update_automation` and re-run `run_automation_once`. Two failures on the same agent → stop and ask the user how to proceed, don't guess a third fix. |
| `skipped` | Source bailed early (e.g. *"no tasks due in window"* for task_nudger on a brand-new workflow with zero tasks). Expected for an empty workflow; confirm with the user that the skip reason matches the trigger payload that fired, then continue. |
| `queued` / `running` (timed out — `timed_out: true`) | Run didn't reach a terminal status before `wait_seconds`. The response carries `timeout_reason` + a `next_step` line — **surface `next_step` verbatim** for this template (don't roll your own triage table) and continue. Don't claim success. |

After every agent has been smoke-tested, write a one-line summary per template before moving on, e.g.:

> *"Smoke test results — progress_scorer ✅ succeeded, task_nudger ⏭ skipped (no tasks yet, expected), milestone_reviewer ✅ succeeded."*

If any smoke test failed and could not be patched, the workflow is NOT ready. Tell the user which template is broken and that the workflow's status flip will fire a broken agent on its cron. Do not paper over it.

## Step 9 — Hand off

Only after Step 8.5 is complete: hand the user the `workflow_url` and `dashboard_url`. Tell them the workflow is **active** — attached agents are already firing on their crons. They can flip it to paused from /workflows/<id> if they need to halt them. Surface the smoke-test summary one more time so they know which templates were validated and which were skipped.

## Hard rules

- **One question per turn.** No bundling.
- **Roster is brains-users-only.** Do not invent a fallback to gmail.
- **KPIs need numbers.** Don't accept vibe-goals.
- **Auto-detect Step 5.** Do not ask "any integrations or boards?" cold — call `list_integrations` + `list_boards` first, then confirm a curated list.
- **Be assertive on templates.** Recommend all three; do not enumerate-and-ask unless the user pushes back.
- **Every workflow has a dashboard.** It's mandatory — `create_workflow` always provisions one.
- **Always end in a single `create_workflow` call.** Do not try to wire agents, boards, or dashboards manually — the tool handles provisioning.
- **Templates only.** No hand-rolled agent source in this flow — that's what create_automation_flow is for.
- **Smoke-test every attached agent before hand-off.** Step 8.5 is mandatory; a "template" agent can fail at runtime exactly like a hand-rolled one, and the user has not read the rendered source. Don't claim a workflow is ready until every attached agent has executed once.
4 changes: 2 additions & 2 deletions plugins/brains/skills/brains-write/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: brains-write
description: How to take ACTIONS on the user's integrations through brains — send an email, create a calendar event, make a Drive doc, comment on a Monday item, run a live Gmail search, post a message. Use whenever the user wants to send/create/reply/forward/mark/schedule something, or "message/ping/DM" someone. Covers the codex action flow and the draft→confirm gate.
name: "brains-write"
description: "How to take ACTIONS on the user's integrations through brains — send an email, create a calendar event, make a Drive doc, comment on a Monday item, run a live Gmail search, post a message. Use whenever the user wants to send/create/reply/forward/mark/schedule something, or \"message/ping/DM\" someone. Covers the codex action flow and the draft→confirm gate."
---

<!-- Generated by ssvlabs/brains apps/mcp/scripts/generate-capability-catalog.ts.
Expand Down
Loading
Loading