# 12 — Service README Generation

Rules for creating and maintaining the `README.md` of an individual FlowRunner service, generated from the
service's `src/index.js` (the single source of truth).

## Structure — exact sections, in order

1. **Title**: `{Service Name} FlowRunner Extension` — the `name` passed to `Flowrunner.createExtension`.
2. **Description** — brief overview of the service's purpose and main capabilities. Do NOT use the phrase "Service Description"; focus on what the service does.
3. **Ideal Use Cases** — bullet points of scenarios where the service is helpful (use this exact heading).
4. **List of Actions** — logically sorted list of action names only (no descriptions); alphabetical or logical grouping.
5. **List of Triggers** — logically sorted list of trigger names only (no descriptions).
6. **Agent Ideas** — cross-service synergies (see below), always the last section.

## Content Rules

- **Maximum 2000 characters total.** Brevity is the point — no per-action/trigger descriptions.
- Standard Markdown; bullet points for lists; clear, concise language; consistent structure across all services.
- Extraction from `src/index.js`:

  | README needs | Read from |
  |---|---|
  | Service name | the `name` prop of `Flowrunner.createExtension({ ... })` |
  | Actions | every `ext.addAction({ ... })` — list its **`label`** |
  | Triggers | every `ext.addPollingTrigger({ ... })` and `ext.addRealtimeTrigger({ ... })` — list its **`label`** |

- **List `label`, never `id`.** `id` is the persisted execution key and is frozen once a service ships, so it
  may read nothing like the current behaviour. `label` is the human text the console shows, so it is what
  belongs in a README.
- **Exclude** everything that is not a user-facing action or trigger: `ext.dictionary(...)` registrations,
  `dynamicParams`, `result` loader functions, `initContext`, `apiRequest`, `helpers`, and
  `ext.setupOauth2` / `ext.setupRealtimeTriggers` setup calls. These are internal support declarations, and
  the SYSTEM methods generated from them are never documented.
- If a `GENERATED_README.md` exists in the service directory it may be used as a source, but never modify it —
  it is auto-generated and excluded from version control.

## Agent Ideas Section

Every README ends with an `## Agent Ideas` section highlighting multi-service workflows an AI Agent could orchestrate:

1. Scan the other service directories under `services/` and read their READMEs to understand capabilities.
2. Select 2–3 services that pair well with the current one.
3. Write 2–3 bullets; each must name the specific operations by their exact `label` (from this service AND the
   companions), describe a realistic end-to-end workflow, and be a single concise sentence.

Example:

```markdown
## Agent Ideas

- When a **ShipBob** "On Order Shipped" trigger fires, use **Gmail** "Send Email" to notify the customer with tracking details and estimated delivery date
- Use **Airtable** "Get Records" to fetch new product listings, then call **ShipBob** "Create Product" to sync each product into ShipBob's fulfillment catalog
- When a **ShipBob** "On Return Completed" trigger fires, use **Google Sheets** "Append Row" to log the return details into a returns tracking spreadsheet
```

(If the project contains only one service, base the Agent Ideas on well-known FlowRunner integrations instead.)

The README of the service you are writing follows this document; what you quote from a companion service
follows whatever that companion declares.

## Process & Verification

- Process one service at a time; the README must reflect `src/index.js` exactly.
- When updating, preserve manually-added sections (extra notes, troubleshooting) that don't conflict with the required structure.
- After generating/updating, cross-reference against `src/index.js`: every registered action and trigger is
  listed, nothing removed is still documented, names match the `label` values, and the character limit is
  respected.
- **Refactoring a service should not change its README** unless a `label` changed. A diff there when you only
  meant to change internals is a signal that something user-facing moved — check before accepting it.
