Skip to content
Open
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
151 changes: 151 additions & 0 deletions .agents/skills/create-squad/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
name: create-squad
description: Author a new Agent Squad bundle — scaffold it from the template, interview the author, fill every file, and validate. Use when the user wants to create, build, or add a new squad (a deployable bundle of proactive Pancake sub-agents).
---

# Create a squad

Author a complete, valid Agent Squad bundle with the user. Work through the steps in order
— later steps depend on earlier ones.

## Step 1 — Load the contract

Before writing anything, read, in this order:

1. [`docs/bundle-reference.md`](../../../docs/bundle-reference.md) — the exact file contract.
2. [`docs/creating-a-squad.md`](../../../docs/creating-a-squad.md) — the public-grade
authoring guide and principles.
3. The skeleton bundle [`template/`](../../../template/) — every file. Your output mirrors
its structure.

Do not invent the contract from memory — read these files.

## Step 2 — Interview the author

Ask the user what they want, and don't scaffold until you have answers for all of it:

- **The squad** — its purpose, and a kebab-case `name` (globally unique, ≤ 64 chars).
- **Each agent** — `id` (kebab-case), role / `description`, `model` (`haiku`/`sonnet`/`opus`,
string enum), `heartbeat` — a curated subset of [OpenClaw's
`agents.list[].heartbeat`](https://docs.openclaw.ai/gateway/config-agents#agents-defaults-heartbeat).
Only six sub-fields are accepted: `every`, `model`, `lightContext`,
`isolatedSession`, `skipWhenBusy`, `timeoutSeconds`. `every` is an OpenClaw duration
string in units `ms`/`s`/`m`/`h` (e.g. `"30m"`, `"2h"`, `"24h"`, `"0m"` to disable);
named values like `"daily"` are invalid. `heartbeat.model` is the same `haiku`/`sonnet`/`opus`
enum. Keep each agent single-lane and focused.
- **Skills** — which are squad-wide (every agent gets them) vs agent-specific.
- **Required identities** — external sites the squad needs connected, each with a reason.
- **Required vault secrets** — each `{ key, label, type }`.
- **Required tool permissions** — must be drawn from the canonical Pancake tool list
([`docs/bundle-reference.md#tool-permissions`](../../../docs/bundle-reference.md#tool-permissions)).
Accepted keys today: `browser`, `exa` / `web_search` / `web_fetch`, `github`,
`google-workspace` / `google_workspace`, `notion`, `agentmail`, `vault`,
`preview-host` / `publish_preview`, `mcp-installer`,
`image-generation` / `image_generate` / `image`, `cron`. Anything else is rejected by
the validator. Slack and voice/TTS are intentionally excluded — those are user-facing
channels owned by the co-founder, not by a sub-agent.
- **Crons** — any scheduled jobs, and what each one does.
- **Catalog metadata** — `tags` for the marketplace card (no `token_intensity` — it is
deprecated and Pancake Cloud computes token usage automatically).

## Step 3 — Scaffold

Copy [`template/`](../../../template/) to `squads/<name>/`, then fill every file:

- **`manifest.json`** — package descriptor only. `agents` is a string array of kebab ids.
No per-agent runtime config in this file. Delete optional sections the squad doesn't use.
- **`agents/<id>/agent.json`** for every agent — the per-agent runtime config (curated
subset of OpenClaw's `agents.list[]`). Required: `id`, `description`. `model` is a
string from `haiku`/`sonnet`/`opus`. `heartbeat` is an object with up to six allowed
sub-fields: `every`, `model`, `lightContext`, `isolatedSession`, `skipWhenBusy`,
`timeoutSeconds`. `every` is an OpenClaw duration in `ms`/`s`/`m`/`h` (e.g. `"30m"`,
`"2h"`, `"24h"`); plain strings (`"daily"`) and named values are rejected. Pod-level
fields like `prompt`, `target`, `directPolicy`, `session`, `to`, `ackMaxChars` are
rejected. Top-level optional fields: `skills`, `contextInjection`, `bootstrapMaxChars`,
`params`. Unknown fields anywhere are rejected.
- **`agents/<id>/IDENTITY.md`, `SOUL.md`, and `HEARTBEAT.md`** for every agent; add
`agents/<id>/MEMORY.md` if useful. `HEARTBEAT.md` is **required** when `agent.json`
declares a heartbeat — keep it out of `SOUL.md` (behaviour) and `MEMORY.md` (pointer
index).
- **Every skill file** referenced by `manifest.skills` or `agent.json#/skills`, in
SKILL.md format (frontmatter `name` + `description`, then a procedure written as steps).
- **`SQUAD.md`** — frontmatter is minimal: `tags` (recommended) and optional
`preview_image`. The body is the marketplace catalog's source of truth for per-agent
prose, so describe every agent here in user-facing language.
- **`ONBOARD.md`** — the runnable onboarding script the co-founder executes after deploy.
- Add or delete the optional `crons/jobs.json` and squad-wide `MEMORY.md` depending on
Step 2.
- **Strip every `<!-- TODO -->` comment and placeholder** the template ships with. The
validator errors on any unresolved TODO marker outside `template/`.

> If this repo has no `squads/` directory — i.e. it is a third-party self-host repo — scaffold
> at the **repo root** instead of under `squads/<name>/`. See
> [`docs/publishing.md`](../../../docs/publishing.md).

## Step 4 — Bake in the conventions

- Each agent is a **focused, single-lane specialist** that reports to the co-founder — not a
generalist.
- **Bounded tool output is a hard default.** Any agent that runs queries (SQL / HogQL / API)
or calls tools that can return large payloads must enforce result-size discipline in its
skills **and** `SOUL.md`: aggregate over enumerate, put a small explicit `LIMIT` on every
row-returning query, project named scalar fields (never `SELECT *` or a raw JSON blob), and
send wide or row-level extracts to a file rather than into the conversation. State the
rationale in the skill so it sticks: a single tool result over ~25k tokens overflows the
model context, **cannot be compacted away** (it exceeds the summarizer's per-message limit),
and wedges the agent in a fail→retry loop that burns the model fallback ladder until the
session is manually reset. This is a real production failure mode, not a hypothetical — see
`squads/posthog-squad/agents/posthog-agent/skills/posthog-mcp-toolkit.md → Result-size
discipline` for the reference implementation.
- `ONBOARD.md` is a **runnable script** the co-founder executes: collect secrets via
`vault_request`, connect identities via `browser_identity_add`, save answers to the agent's
`MEMORY.md`, and create + dispatch a first task. It must fit `estimated_setup_minutes`.
- `MEMORY.md` is a **thin index of pointers**, never a notebook.
- `HEARTBEAT.md` is the **imperative wake procedure** OpenClaw loads on every pulse —
not behaviour (that's `SOUL.md`), not pointers (that's `MEMORY.md`). It must require
the agent to **execute at least one task before closing the session** (no
orient-and-bail), and to write a **digest** to `memory/YYYY-MM-DD.md` before ending
the turn — what was done, what changed, what's still open, the next wake's first
move. `NO_REPLY` is only acceptable when nothing is actionable, with the reason
logged first.
- The **`SQUAD.md` body** is the catalog's per-agent prose surface — describe each
agent in user-facing language there (not in `manifest.json`).
- **Forbidden files**: do not create `AGENTS.md`, `USER.md`, `BOOTSTRAP.md`, or `BOOT.md`
inside the bundle — those are pod-managed by Pancake Cloud. `TOOLS.md` is allowed (it
is bundle-authored documentation).
- Crons target **only this squad's own agents**.
- **Squad crons run in the agent's *persistent* session — they cannot be isolated.** OpenClaw
has an ephemeral `sessionTarget: "isolated"` cron mode, but it requires the target *not* be a
named agent and `payload.kind: "agentTurn"` — and the squad installer rejects any cron whose
`sessionTarget` isn't one of the bundle's own agents (which it must be). So every squad cron
runs as `payload.kind: "systemEvent"` in that agent's main session, which **persists and
accumulates across runs**. Design for two consequences: (1) a cron run that emits an oversized
tool result wedges that main session with no sandbox to fall back on — bounded tool output
(above) is the only guard; (2) each cron run must **self-clean** — do the work, file results
to the wiki, write the daily digest, and close — so the persistent session does not grow
unbounded. `heartbeat.isolatedSession` gives *heartbeat wakes* a fresh session, but there is
**no equivalent for crons** — never assume a cron is sandboxed.
- A cron run with nothing to report must reply with the single literal token `NO_REPLY`.

## Step 5 — Validate (mandatory gate)

Validation is a **blocking gate**, not advisory. The bundle is not finished until the
validator exits 0 with no errors.

```sh
node scripts/validate.mjs squads/<name>
```

- Run the validator **after every batch of edits**, not just at the end. The validator
is your test loop — it catches forbidden files, unresolved TODOs, schema drift, and
broken file references that compound if left until the end.
- Fix every error and re-run. Treat warnings the same way unless the user explicitly
accepts them (e.g. a deliberately tag-less private bundle).
- **Do not declare the bundle finished** until you have run the validator at least once
and seen it exit 0 on this specific bundle.

## Step 6 — Hand off

Tell the user the bundle is ready, summarize what was built, state the validator
outcome (the last exit-0 run on this bundle), and point them to
[`docs/publishing.md`](../../../docs/publishing.md) for getting it into the marketplace.
84 changes: 84 additions & 0 deletions .agents/skills/validate-squad/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
name: validate-squad
description: Validate an Agent Squad bundle and fix what's broken — runs the repo validator, explains each error in plain language, and corrects the offending files. Use when the user wants to check, validate, or debug a squad bundle.
---

# Validate a squad

Run the validator, explain what it found, and fix it.

## Step 1 — Run the validator

```sh
node scripts/validate.mjs # every squads/* bundle and template/
node scripts/validate.mjs squads/<name> # one specific bundle
```

Scope it to a single bundle if the user named one. The validator exits non-zero if any
bundle has an error; warnings never fail the run.

## Step 2 — Explain each error

For every error, tell the user in plain language **what** is wrong and **why** it matters,
referencing [`docs/bundle-reference.md`](../../../docs/bundle-reference.md) for the rule.
The validator's checks fall into the following categories:

- **Manifest schema** (e.g. `agents[0] "Geo Agent" must be kebab-case`) — a field in
`manifest.json` breaks a rule: bad kebab-case or semver, a missing required field, a
value outside an enum, a duplicate agent id, or `agents` is no longer an object array
(it must now be a string array of agent ids).
- **`agent.json` missing** (`agents/<id>/agent.json not found`) — every id in
`manifest.agents` must have a matching `agents/<id>/agent.json` file.
- **`agent.json` schema** (e.g. `agents/<id>/agent.json#/model must be one of: haiku,
sonnet, opus`) — the per-agent config is invalid. Common causes:
- Wrong `model` value (string enum `haiku`/`sonnet`/`opus`) — applies to both
top-level `model` and `heartbeat.model`.
- `heartbeat` written as a plain string instead of the object shape (e.g.
`"heartbeat": "daily"` instead of `"heartbeat": { "every": "24h" }`).
- `heartbeat.every` written as a named value (`"daily"`) instead of an OpenClaw duration
in `ms`/`s`/`m`/`h` (`"30m"`, `"2h"`, `"24h"`, `"0m"`).
- Unknown field on the agent or inside `heartbeat`. Only six heartbeat sub-fields are
accepted (`every`, `model`, `lightContext`, `isolatedSession`, `skipWhenBusy`,
`timeoutSeconds`); pod-level fields like `prompt`, `target`, `directPolicy`,
`session`, `to`, `ackMaxChars` are rejected because they're not authorable from a
bundle.
- `id` not matching the directory name.
- **Referenced-file errors** — a file the manifest or agent.json points to (`SQUAD.md`,
`ONBOARD.md`, a skill, `IDENTITY.md`, `SOUL.md`, `HEARTBEAT.md` when the agent has a
heartbeat) is missing, is a symlink, is not a regular file, or resolves outside the
bundle root.
- **Unknown tool permission** (e.g. `required_tool_permissions[2] "message" is not an
accepted tool key`) — an entry in `manifest.required_tool_permissions` is not in the
canonical Pancake tool list (see [`bundle-reference.md#tool-permissions`](../../../docs/bundle-reference.md#tool-permissions)).
Common migrations: `browser_task`/`browser_open`/`browser_action` → `browser`;
`message`, `slack-block-kit`, `voice`, `tts` → **delete** (Slack and voice are
user-facing channels owned by the co-founder, not a squad agent). If the bundle still
carries `slack-block-kit` from an earlier draft, that's why — drop it.
- **Targeting errors** (`crons/jobs.json`) — a cron's `sessionTarget` names an agent the
squad does not declare. Squad crons may target only the squad's own agents.
- **Forbidden file** (e.g. `agents/<id>/USER.md forbidden filename`) — the bundle
contains a file named `AGENTS.md`, `USER.md`, `BOOTSTRAP.md`, or `BOOT.md`. Those are
pod-managed by Pancake Cloud and must not appear inside a bundle. Delete the file.
`TOOLS.md` is *allowed* and is not flagged.
- **Deprecated field** (e.g. `SQUAD.md frontmatter has a deprecated 'token_intensity:'
line`) — `token_intensity` has been removed from the contract. Pancake Cloud computes
token usage automatically; delete the line.
- **Unresolved TODO** (e.g. `SQUAD.md unresolved TODO marker on line 12`) — the bundle
still contains `<!-- TODO`, `TODO:`, or a bare `TODO` line left over from the template.
Strip the placeholder.
- **Frontmatter warnings** — `SQUAD.md` missing `tags`, or `ONBOARD.md` missing its
frontmatter block. These do not fail the run but advise the user to fix them so the
catalog card renders correctly.

## Step 3 — Fix the offending files

Correct each error in the relevant file. Make the smallest change that satisfies the
contract — don't rewrite content that isn't broken. For a missing referenced file, either
create the file or remove the manifest reference, depending on the user's intent (ask if
unclear). For a forbidden filename, delete the file (or rename it if the content is
worth keeping — e.g. `USER.md` content can move into `MEMORY.md` as a pointer).

## Step 4 — Re-run until clean

Run the validator again. Repeat Steps 2–3 until it exits 0 with no errors. Then report the
result: confirm the bundle is valid, and list any warnings the user chose to leave.
43 changes: 43 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# AGENTS.md

Orientation for a Codex session opened in this repo.

## What this repo is

`squads` is a documentation-and-content repo for **Agent Squads** — installable bundles
that deploy proactive sub-agents into a Pancake pod. It holds Pancake's official squads,
the source the Pancake marketplace seeds from, and the public contract for squad authors.

There is **no application code** here — no `package.json`, no build. Just two
zero-dependency Node scripts: `scripts/validate.mjs` (mirrors marketplace ingestion) and
`scripts/test-validator.mjs` (self-tests for the validator, run by CI to catch
regressions in the validator itself).

## How the repo is organized

- `squads/<name>/` directories are **squad bundles** — the unit the marketplace ingests.
- `template/` is a complete, valid skeleton bundle authors copy from.
- `docs/` is the full contract and authoring guides.
- `scripts/validate.mjs` validates every bundle; `manifest.schema.json` is the editor schema.

## The bundle contract, in one paragraph

A bundle is a directory with a `manifest.json` (the package descriptor: `name`, `version`,
`description`, `author`, `agents` as a string array of ids, plus optional squad-wide
skills, required identities, and vault secrets), a `SQUAD.md` catalog card, an
`ONBOARD.md` onboarding script, and per agent: an `agents/<id>/agent.json` (the per-agent
runtime config — model, heartbeat, agent-specific skills, mirroring OpenClaw's
`agents.list[]`), `agents/<id>/IDENTITY.md`, and `agents/<id>/SOUL.md`. Optionally it
carries `MEMORY.md` seed memory, `skills/` files, `crons/jobs.json`, and a per-agent
`HEARTBEAT.md` (required when `agent.json` declares a heartbeat). Full detail is in
[`docs/bundle-reference.md`](./docs/bundle-reference.md).

## Working in this repo

- To **author** a new squad, use the `create-squad` skill.
- To **check or fix** a squad, use the `validate-squad` skill.
- To validate directly: `node scripts/validate.mjs` (add a bundle path to scope it).
- Model new squads on [`template/`](./template/) (the skeleton) and the contract in
[`docs/bundle-reference.md`](./docs/bundle-reference.md).

Any change to a squad bundle must keep `node scripts/validate.mjs` green — CI enforces it.
2 changes: 1 addition & 1 deletion squads/meta-ads-squad/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "meta-ads-squad",
"version": "0.1.0",
"version": "0.1.1",
"description": "Single-agent Meta Ads squad: daily diagnostic + action sweep, daily digest, weekly review. Holds spend flat autonomously; escalates only budget increases.",
"author": "pancake-official",
"license": "MIT",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ description: Profile a Meta ad account — identity, capabilities, KPI targets,

Every recommendation in the rest of these files assumes you know what kind of account you are working on. This file is how you answer that question.

## Marketing API access tiers

Before profiling the account, know what your app's API access actually permits — this is widely misunderstood.

**Development Access fully works for managing your own ad accounts** — accounts owned by the same Business that owns the app. You do **not** need App Review to operate against an ad account that belongs to you. The calls work; campaigns, ad sets, ads, and insights are all readable and writable on day one.

What Development tier limits is **scale and rate**, not capability:

- **Rate:** roughly 60 quota points per 300-second window (1 point per read, 3 per write).
- **Accounts:** a small handful of ad accounts.

**Standard Access (via App Review)** raises the ceiling to roughly 9,000 points per window. You need it for managing many client accounts or sustaining a heavy cron rhythm — but **not to make the calls work at all**. For a single self-owned account on a light cadence, Development tier is enough; the App Review step (3–10 business days) is a scale upgrade you can defer until rate limits actually bite.

When an account hits rate-limit errors (HTTP 429 / code 17), that's the Development-tier point budget being exhausted — the fix is either thinning the cron rhythm or moving to Standard Access, not re-checking permissions.

## Account identity sheet

For each Meta ad account under management, capture the following before doing any analysis. Treat this as the configuration that every other workflow reads.
Expand Down
Loading