diff --git a/.claude/skills/writing-provider-guides/SKILL.md b/.claude/skills/writing-provider-guides/SKILL.md new file mode 100644 index 00000000..6fa824d7 --- /dev/null +++ b/.claude/skills/writing-provider-guides/SKILL.md @@ -0,0 +1,77 @@ +--- +name: writing-provider-guides +description: Use when creating or updating an Ampersand provider (connector) guide in src/provider-guides/ — adding a new connector doc, extending an existing guide with deep connector support (Read/Write/Subscribe), or fixing a guide's structure, headings, or wording. +--- + +# Writing Provider Guides + +## Overview + +Every provider guide in `src/provider-guides/*.mdx` follows one canonical structure with exact, fixed wording. Older guides drifted (title-case headings, unlinked object names, paraphrased sentences) — never imitate an arbitrary existing guide. Copy sentences from [templates.md](templates.md) **verbatim** and fill only the `` slots. + +**Core principle: the guide is assembled from fixed templates, not written.** Your judgment goes into gathering accurate provider facts, not into phrasing. + +## Workflow + +1. **Gather required inputs.** Ask the user for any of these you cannot derive: + - Provider display name + slug (slug = folder/file name in the [amp-labs/connectors](https://github.com/amp-labs/connectors) repo, and the mdx filename) + - Connector type: proxy-only or deep + - Auth type: `oauth2_authorization_code` | `oauth2_client_credentials` | `api_key` | `basic_auth` | custom + - Capabilities: subset of read / write / subscribe / proxy + - Base URL (preserve placeholders like `{{.workspace}}`) + + Optional (proceed with `` comments if missing): object lists + upstream API reference URLs, dynamic-token explanations, credential-creation steps, screenshots. + +2. **Inspect the connectors repo** to confirm/derive the inputs — see "Data gathering" in templates.md. Never fabricate objects, scopes, endpoints, or URLs; prefer a TODO comment over a guess. + +3. **Classify the incremental-read pattern** (A: none, B: ≤5 objects, C: all, D: >5 objects) — this selects the exact Read Actions sentence. Only claim incremental support with evidence from code; otherwise use Pattern A plus a TODO. + +4. **Assemble the MDX** in the canonical section order from templates.md, choosing the auth-type variants. For **updates to an existing guide**: bring headings/wording of the sections you touch up to the canonical templates; keep factual content (credential steps, screenshots) as-is; move any non-template sections (e.g. "API documentation", "Rate limits") to the end of the file unchanged. + +5. **Register navigation** (new guides only): add `"provider-guides/"` to the "Provider guides" group in `src/generate-docs.ts`, keeping the list alphabetically sorted case-insensitively. Then run `pnpm run gen` (or tell the user to). + +6. **Run the verification checklist** below before declaring the guide done. + +## Non-negotiable rules + +- **Every object bullet is a markdown link**: `- []()`. If no URL is found after searching the provider's API docs, write `- `. A bare object name with no link and no TODO is a defect. +- **Headings are exact strings** from templates.md — sentence case (`## What's supported`, `### Supported actions`, `## Before you get started`), never title case. +- **Action bullet order**: Read → Subscribe → Write → Proxy. Only supported actions appear. Each bullet ends with a period. The Proxy bullet always carries the base URL in backticks. +- **Fixed URLs**: Ampersand OAuth redirect `https://api.withampersand.com/callbacks/v1/oauth`; dashboard `https://dashboard.withampersand.com`; samples `https://github.com/amp-labs/samples/blob/main//amp.yaml`. +- **Example integration is conditional on an observable fact**: if the samples-repo `amp.yaml` for the slug exists (check with `curl -s -o /dev/null -w "%{http_code}" https://raw.githubusercontent.com/amp-labs/samples/main//amp.yaml` → 200), use the one-line samples-link template; otherwise use the inline-manifest template. Never emit a samples link you haven't verified. +- **Each dynamic token** (`{{.workspace}}`, `{{.region}}`, …) is explained once under "Before you get started": what it is and where the customer finds it. +- Inline code (backticks) for object names, field names, tokens, and URLs-as-values; `[text](url)` for every navigable link — no raw URLs in prose. +- Imperative voice ("Create…", "Click…"); no future tense; "GitHub" spelled with capital H. +- For deep connectors, treat Read and Write as enabled when implementation files exist in `providers//`, even if `Support` flags in the catalog say otherwise. + +## Verification checklist (run every time) + +```bash +F=src/provider-guides/.mdx +grep -n "^#" $F # headings match templates.md exactly (sentence case) +sed -n '/### Supported objects/,/### Example integration/p' $F | grep "^- " | grep -v "\[.*\](" | grep -v "TODO" # unlinked object bullets — must output nothing +grep -n "Proxy Actions" $F # base URL present in backticks +grep -c "{{\." $F # every token also explained in Before you get started +``` + +Then confirm by eye: +- [ ] Section order matches the skeleton in templates.md +- [ ] Read Actions sentence is byte-identical to pattern A/B/C/D +- [ ] amp.yaml example (if inline) contains only supported capabilities +- [ ] "a"/"an" correct before provider name in Example integration line +- [ ] Auth intro + prompt lines match the auth-type table +- [ ] Samples link verified with curl (200) if used +- [ ] New guide registered alphabetically in `src/generate-docs.ts` +- [ ] No fabricated objects, scopes, or URLs; TODOs mark every unknown + +## Common mistakes + +| Mistake | Fix | +|---|---| +| Copying heading case from an old guide (`## What's Supported`) | Use templates.md headings, not existing guides | +| Object bullets without links | Every bullet: `[name](url)` or name + `` | +| Paraphrasing the Read Actions sentence | Copy pattern A/B/C/D byte-for-byte, fill slots only | +| Linking samples repo without checking it exists | curl the raw amp.yaml URL first; 404 → inline manifest | +| `## Add App Details in Ampersand` as H2 / rephrased | `### Add your app info to Ampersand`, nested under "Before you get started" | +| Provider-app instructions for non-OAuth-auth-code providers | Only OAuth2 Authorization Code needs a Provider App; others get the "no Provider App" intro line | +| Forgetting navigation registration | New slug goes into `src/generate-docs.ts`, alphabetical, then `pnpm run gen` | diff --git a/.claude/skills/writing-provider-guides/templates.md b/.claude/skills/writing-provider-guides/templates.md new file mode 100644 index 00000000..dcccbe9e --- /dev/null +++ b/.claude/skills/writing-provider-guides/templates.md @@ -0,0 +1,305 @@ +# Provider Guide Templates + +**Copy fixed text verbatim. Fill only `` slots. Do not rephrase, reorder, or "improve" fixed sentences.** + +## Page skeleton (canonical section order) + +```markdown +--- +title: "" +--- + + + +## What's supported + +### Supported actions + +### Notes ← optional; only when real caveats exist + +### Supported objects ← deep connectors only + +### Example integration + +## Before you get started + +### + +## Using the connector + + +``` + +--- + +## Supported actions + +```markdown +### Supported actions + +This connector supports: + +- +- [Subscribe Actions](/subscribe-actions). +- [Write Actions](/write-actions). +- [Proxy Actions](/proxy-actions), using the base URL ``. +``` + +Rules: order is Read → Subscribe → Write → Proxy; include only supported actions; every bullet ends with a period; Proxy bullet always carries the base URL in backticks (placeholders preserved, e.g. `` `https://rest.{{.restInstanceId}}.braze.com` ``). + +### Read bullet — Pattern A: no incremental read + +```markdown +- [Read Actions](/read-actions), including full historic backfill. Please note that incremental read is not supported, a full read of the instance will be done for each scheduled read. +``` + +### Read bullet — Pattern B: incremental for ≤5 objects (list inline) + +```markdown +- [Read Actions](/read-actions), including full historic backfill. Please note that incremental read is supported only for ``, `` and `` currently. For all other objects, a full read of the instance will be done per scheduled read. +``` + +### Read bullet — Pattern C: incremental for all objects + +```markdown +- [Read Actions](/read-actions), including full historic backfill and incremental read for all supported objects. +``` + +### Read bullet — Pattern D: incremental for >5 objects (annotate object list) + +```markdown +- [Read Actions](/read-actions), including full historic backfill. Incremental reading is supported for the objects listed below. For all other objects, a full read of the instance will be done per scheduled read. +``` + +With Pattern D, append ` (supports incremental read)` to each supporting bullet in the read-objects list. + +If a Subscribe action needs provider-specific setup, extend its bullet: +```markdown +- [Subscribe Actions](/subscribe-actions). Please note that [special set up](#set-up-subscribe-actions) is needed for . +``` + +--- + +## Supported objects (deep connectors) + +```markdown +### Supported objects + +The connector supports reading from the following objects: + +- []() +- []() + +The connector supports writing to the following objects: + +- []() +``` + +Rules: +- **REQUIRED:** every bullet is `[name](url)` linking to the provider's API reference for that object. Unknown URL → `- `. Never a bare name. +- Alphabetical order within each list. +- Object names exactly as used in `amp.yaml` (e.g. `email/hard_bounces`, `user/keys`). +- Pattern D: append ` (supports incremental read)` to supporting read bullets. +- If read + write lists are long, `#### Read objects` / `#### Write objects` subheadings may replace the intro sentences (see procore.mdx). +- If the object list is known to be incomplete: + ```markdown + > Note: The list below may be incomplete. + ``` +- Proxy-only connectors: omit this section, or use short prose pointing at the provider's API docs: + ```markdown + ### Supported objects + + is supported through Proxy Actions only. Use the proxy to call any [ API]() endpoint, for example `GET /v1/projects`. + ``` + +--- + +## Example integration + +**First check** (observable predicate — do not skip): +```bash +curl -s -o /dev/null -w "%{http_code}" https://raw.githubusercontent.com/amp-labs/samples/main//amp.yaml +``` + +**HTTP 200 → samples-link form:** +```markdown +### Example integration + +For an example manifest file of a integration, visit our [samples repo on GitHub](https://github.com/amp-labs/samples/blob/main//amp.yaml). +``` +Use "an" instead of "a" when the provider name starts with a vowel sound ("an Outplay integration", "an Asana integration"). + +**Otherwise → inline-manifest form** (action blocks only for supported capabilities): +```markdown +### Example integration + +To define an integration for , create a manifest file that looks like this: + +```YAML +# amp.yaml +specVersion: 1.0.0 +integrations: + - name: Integration + displayName: My Integration + provider: + read: + objects: + - objectName: + destination: + write: + objects: + - objectName: + proxy: + enabled: true +``` +``` +Proxy-only connectors: keep only the `proxy` block. + +--- + +## Before you get started — auth-type variants + +### OAuth2 Authorization Code (Provider App required) + +```markdown +## Before you get started + +To integrate with Ampersand, you will need a [ account](). + +Once your account is created, you'll need to create a app and obtain the following credentials from it: + +- Client ID +- Client Secret + +You will then use these credentials to connect your application to Ampersand. + +### Creating a app + +1. Log in to the [ developer portal](). +2. +3. Set the redirect/callback URL to: `https://api.withampersand.com/callbacks/v1/oauth` +4. + +### Add your app info to Ampersand + +1. Log in to your [Ampersand Dashboard](https://dashboard.withampersand.com). + +2. Select the project where you want to create a integration. + + ![Ampersand Project Selection](/images/provider-guides/) + +3. Select **Provider Apps**. + +4. Select **** from the **Provider** list. + +5. Enter the **Client ID** and **Client Secret** obtained from your app. + +6. Click **Save Changes**. +``` + +Notes: scopes bullet list goes under "Creating a app" if the provider requires selecting scopes. Only reference images that actually exist in `src/images/provider-guides/`; otherwise omit the image line (no fabricated paths). + +### API Key / Basic Auth / OAuth2 Client Credentials (no Provider App) + +```markdown +## Before you get started + +To connect with Ampersand, you will need a [ account](). + +### Creating credentials + +1. +2. +``` + +- Section title options: `### Creating an API key for `, `### Creating credentials` — pick what fits the credential. +- **Each dynamic token gets explained here.** Example (from outplay.mdx): "Note your workspace identifier - this is the subdomain in your URL (e.g., if your URL is `https://mycompany-api.outplayhq.com`, your workspace is `mycompany`)." +- Nonstandard Basic Auth mapping (e.g. API key as username, blank password) gets stated explicitly and linked to the provider's auth docs, plus this sentence: "The UI components will display this link, so that your users can successfully provide their credentials." For extensive quirks, add a `## Credential format for ` section at the end of the file (see connectWise.mdx). + +--- + +## Using the connector + +```markdown +## Using the connector + + + +To start integrating with : + +- Create a manifest file like the [example above](#example-integration). +- Deploy it using the [amp CLI](/cli/overview). +- If you are using Read Actions, create a [destination](/destinations). +- Embed the [InstallIntegration](/embeddable-ui-components#install-integration) UI component. +- Start using the connector! + - If your integration has [Read Actions](/read-actions), you'll start getting webhook messages. + - If your integration has [Write Actions](/write-actions), you can start making API calls to our Write API. + - If your integration has [Proxy Actions](/proxy-actions), you can start making Proxy API calls. +``` + +Rules: +- Include the destination bullet only if Read is supported. +- Include only the "Start using" sub-bullets for supported actions. +- If Subscribe is supported, the first sub-bullet becomes: `If your integration has [Read Actions](/read-actions) or [Subscribe Actions](/subscribe-actions), you'll start getting webhook messages.` + +### Auth intro / prompt lines + +| Auth type | `` | `` | +|---|---|---| +| OAuth2 Authorization Code | *(omit)* | The UI component will prompt the customer for OAuth authorization. | +| OAuth2 Client Credentials | This connector uses OAuth2 Client Credentials grant type, which means that you do not need to set up a Provider App before getting started. (Provider apps are only required for providers that use OAuth2 Authorization Code grant type.) | The UI component will prompt the customer for their credentials. | +| API Key | This connector uses API Key auth, which means that you do not need to set up a Provider App before getting started. (Provider apps are only required for providers that use OAuth2 Authorization Code grant type.) | The UI component will prompt the customer for their API key. | +| Basic Auth | This connector uses Basic Auth, which means that you do not need to set up a Provider App before getting started. (Provider apps are only required for providers that use OAuth2 Authorization Code grant type.) | The UI component will prompt the customer for their username and password. | + +If the customer must also supply dynamic tokens, extend the prompt line, e.g. "…for their API credentials and workspace location." + +### Proxy-only ending variant + +For proxy-only connectors, replace the last two bullets ("Embed…", "Start using…") with: + +```markdown +- Embed the [InstallIntegration](/embeddable-ui-components#install-integration) UI component. +- Start making [Proxy Calls](/proxy-actions), and Ampersand will automatically attach the correct header required by . Please note that this connector's base URL is ``. +``` + +For OAuth (either grant type) proxy-only connectors, the last bullet is instead: +```markdown +- Start making [Proxy Calls](/proxy-actions), and Ampersand will automatically handle the authentication with . +``` + +--- + +## Data gathering — amp-labs/connectors repo + +### Catalog entry (all connectors) + +Fetch `https://raw.githubusercontent.com/amp-labs/connectors/main/providers/.go` and read the `SetInfo(, ProviderInfo{...})` block: +- `DisplayName` → guide title +- `AuthType` (+ `Oauth2Opts.GrantType`) → auth-type variant +- `BaseURL` → Proxy bullet (preserve `{{.placeholders}}`) +- `Support` flags → proxy-only capabilities +- `Metadata` / `PostAuthentication` fields → dynamic tokens to document + +If the file is missing on `main`, ask the user for the feature branch and note at the top of the draft: `` + +### Deep connectors (folder pattern) + +Explore `https://github.com/amp-labs/connectors/tree/main/providers/`: +- `support.go` / `supports.go`, `schemas.json` → object lists +- read/write handler files → capabilities. **Presence of implementation files wins over `Support` flags** — flags lag behind. +- Incremental cues: `SupportsIncremental` / `IncrementalObjects` maps, or handlers filtering on timestamps (`since`, `updated_at`, `modifiedDate`). Mention the cursor field only if explicitly named in code. +- Objects in code override `schemas.json`; note conflicts with a TODO. + +### Upstream API reference links + +For each object, find the provider's API reference page for that resource (try `developers.`, `docs.`, `developer.`). Link the closest resource-level page. Nothing found → ``. Never invent URL paths. + +--- + +## Navigation registration (new guides) + +1. In `src/generate-docs.ts`, find the `group: "Provider guides"` block. +2. Insert `"provider-guides/",` keeping case-insensitive alphabetical order; one entry per line, double quotes, trailing comma. +3. Run `pnpm run gen`. If the user asked for no build, remind them to run it later. diff --git a/src/docs.json b/src/docs.json index 0c3b2cf1..72d858cc 100644 --- a/src/docs.json +++ b/src/docs.json @@ -241,6 +241,7 @@ "provider-guides/snapchatAds", "provider-guides/snowflake", "provider-guides/solarwindsServiceDesk", + "provider-guides/square", "provider-guides/stripe", "provider-guides/superSend", "provider-guides/surveyMonkey", diff --git a/src/generate-docs.ts b/src/generate-docs.ts index 2b83c791..9fe65aeb 100644 --- a/src/generate-docs.ts +++ b/src/generate-docs.ts @@ -473,6 +473,7 @@ const baseConfig = { "provider-guides/snapchatAds", "provider-guides/snowflake", "provider-guides/solarwindsServiceDesk", + "provider-guides/square", "provider-guides/stripe", "provider-guides/superSend", "provider-guides/surveyMonkey", diff --git a/src/images/customer-guides/square_oauth.gif b/src/images/customer-guides/square_oauth.gif new file mode 100644 index 00000000..2b1084c3 Binary files /dev/null and b/src/images/customer-guides/square_oauth.gif differ diff --git a/src/images/provider-guides/square_amp.png b/src/images/provider-guides/square_amp.png new file mode 100644 index 00000000..b00e862a Binary files /dev/null and b/src/images/provider-guides/square_amp.png differ diff --git a/src/provider-guides/square.mdx b/src/provider-guides/square.mdx new file mode 100644 index 00000000..47cd018d --- /dev/null +++ b/src/provider-guides/square.mdx @@ -0,0 +1,81 @@ +--- +title: "Square" +--- + +## What's supported + +### Supported actions + +This connector supports: + +- [Proxy Actions](/proxy-actions), using the base URL `https://connect.squareup.com`. + +### Notes + +For testing against Square's [sandbox environment](https://developer.squareup.com/docs/devtools/sandbox/overview), set `provider: squareSandbox` in your manifest file. This is identical to `square` except that it uses the base URL `https://connect.squareupsandbox.com`. + +### Example integration + +To define an integration for Square, create a manifest file that looks like this: + +```YAML +# amp.yaml +specVersion: 1.0.0 +integrations: + - name: squareIntegration + displayName: My Square Integration + provider: square + proxy: + enabled: true +``` + +## Before you get started + +To integrate Square with Ampersand, you will need a [Square account](https://squareup.com/signup). + +Once your account is created, you'll need to create a Square app and obtain the following credentials from it: + +- Client ID +- Client Secret + +You will then use these credentials to connect your application to Ampersand. + +### Creating a Square app + +1. Log in to the [Square developer portal](https://developer.squareup.com/apps). +2. Click **+** to create a new application and give it a name. +3. Open the application and select the **OAuth** tab. +4. Set the redirect/callback URL to: `https://api.withampersand.com/callbacks/v1/oauth` +5. Copy the **Application ID** (Client ID) and **Application Secret** (Client Secret) from the **OAuth** page. +6. Note the [OAuth permissions (scopes)](https://developer.squareup.com/docs/oauth-api/square-permissions) your integration requires. + + ![Square OAuth](/images/customer-guides/square_oauth.gif) + +### Add your Square app info to Ampersand + +1. Log in to your [Ampersand Dashboard](https://dashboard.withampersand.com). + +2. Select the project where you want to create a Square integration. + + ![Ampersand Project Selection](/images/provider-guides/dd47b7a-Ampersand.png) + +3. Select **Provider Apps**. + +4. Select **Square** from the **Provider** list. + +5. Enter the **Client ID** and **Client Secret** obtained from your Square app. + +6. Enter the scopes your integration requires. + +7. Click **Save Changes**. + + ![Ampersand Project Selection](/images/provider-guides/square_amp.png) + +## Using the connector + +To start integrating with Square: + +- Create a manifest file like the [example above](#example-integration). +- Deploy it using the [amp CLI](/cli/overview). +- Embed the [InstallIntegration](/embeddable-ui-components#install-integration) UI component. The UI component will prompt the customer for OAuth authorization. +- Start making [Proxy Calls](/proxy-actions), and Ampersand will automatically handle the authentication with Square.