From 601eff22efaad54ed39b28a3192582ed2a86576f Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Tue, 29 Sep 2026 20:15:55 -0700 Subject: [PATCH] improvement(planetscale): add placeholders to every input and fill missing docs intros --- .agents/skills/add-integration/SKILL.md | 32 ++++++++++++++++++- .agents/skills/validate-integration/SKILL.md | 9 ++++++ .../content/docs/integrations/bitbucket.mdx | 17 ++++++++++ apps/docs/content/docs/integrations/modal.mdx | 15 +++++++++ apps/docs/content/docs/integrations/otter.mdx | 15 +++++++++ .../content/docs/integrations/planetscale.mdx | 16 ++++++++++ apps/sim/blocks/blocks/planetscale.ts | 27 +++++++++++++++- 7 files changed, 129 insertions(+), 2 deletions(-) diff --git a/.agents/skills/add-integration/SKILL.md b/.agents/skills/add-integration/SKILL.md index 850571a9cef..865681fa09b 100644 --- a/.agents/skills/add-integration/SKILL.md +++ b/.agents/skills/add-integration/SKILL.md @@ -123,7 +123,7 @@ Follow `.agents/skills/add-block/SKILL.md` for the block structure, subBlock typ `canvasPresentation`; `bun run apps/sim/scripts/check-canvas-sentences.ts --block={service}` must pass (CI runs `check:canvas-sentences --require-coverage`). -Two rules that are easy to get wrong when copying from existing blocks: +Three rules that are easy to get wrong when copying from existing blocks: - Every remote `selectorKey` must use the unified server selector path. Apply the `add-selector` skill: add browser-safe metadata to `apps/sim/lib/selectors/manifest.ts`, reuse or extract a server-only @@ -135,6 +135,12 @@ Two rules that are easy to get wrong when copying from existing blocks: (e.g. `channelSelector` + `channelId` → `canonicalParamId: 'channel'`). It is the only key that survives serialization, so `inputs` and `tools.config.params` reference the canonical id, never the subblock ids. It is unique block-wide, and every member of a group shares the same `required` value. +- Every text-entry subBlock (`short-input`, `long-input`, `code`) and every selector declares a + `placeholder`; an empty box tells the user nothing. Secrets read `Enter your {thing}` (e.g. + `Enter your API key`), free text names what to type (`Enter branch name`), and formatted values + show the shape (`2023-01-01T00:00:00Z`, `1 to 1000`). An optional field with a server-side default + names that default (`Defaults to the database region`). Dropdowns, switches, and `oauth-input` do + not need one. ## Step 4: Add Icon @@ -309,6 +315,28 @@ bun run docs:check This creates `apps/docs/content/docs/integrations/{service}.mdx` — one page per service carrying the block's Actions and, if it has one, its Triggers section. Never hand-edit generated pages; the only editable region is the `{/* MANUAL-CONTENT */}` block (see `scripts/README.md`). +Every generated integration page carries a hand-written intro directly under ``. The +generator preserves it across regenerations, so write it once after the first generate: + +```mdx +{/* MANUAL-CONTENT-START:intro */} +[{Service}](https://service.com/) is {one sentence on what the service is}. + +With the {Service} block, you can: + +- **{Capability}**: {what the operations in this group do} +- **{Capability}**: {...} + +{How to connect: which credential to create and where, if it is not OAuth.} + +In Sim, the {Service} block lets your agents {concrete workflow uses}. +{/* MANUAL-CONTENT-END */} +``` + +Group the bullets by what the user gets done, not one bullet per tool. Only describe operations the +block actually ships. Follow `.claude/rules/constitution.md` for voice. Re-run +`bun run scripts/generate-docs.ts` afterwards and confirm the section survived unchanged. + The docs generator refreshes `packages/deployment-config/src/integrations.json`, and the deployment config generator projects service-account provider IDs from that catalog plus the canonical OAuth registry. The checks compare both committed projections with their sources. Review the generated @@ -368,6 +396,7 @@ If creating V2 versions (API-aligned outputs): - [ ] Defined operation dropdown with all operations - [ ] Added credential field with `requiredScopes: getScopesForService('{service}')` - [ ] Added conditional fields per operation +- [ ] Every `short-input`, `long-input`, `code`, and selector subBlock has a `placeholder` - [ ] Set up dependsOn for cascading selectors - [ ] Every remote `selectorKey` exists in the shared manifest and has one server attachment with trusted credential provider binding and a fixed, credential-bound, or explicitly reviewed @@ -415,6 +444,7 @@ If creating V2 versions (API-aligned outputs): - [ ] Ran `bun run scripts/generate-docs.ts` - [ ] Ran `bun run deployment-config:generate` for OAuth or service-account changes - [ ] Verified docs file created +- [ ] Wrote the `{/* MANUAL-CONTENT-START:intro */}` section under `` and confirmed it survives a regenerate - [ ] Reviewed and committed the generated `packages/deployment-config/src/integrations.json` change - [ ] `bun run integration-catalog:check` passes - [ ] `bun run docs:check` passes — CI fails on stale generated docs, so commit the full generator diff --git a/.agents/skills/validate-integration/SKILL.md b/.agents/skills/validate-integration/SKILL.md index a32df2b8bb3..1bcde985b53 100644 --- a/.agents/skills/validate-integration/SKILL.md +++ b/.agents/skills/validate-integration/SKILL.md @@ -218,6 +218,9 @@ For **each tool** in `tools.access`: - True/false → `switch` (a Yes/No `dropdown` only when the tool needs a third "unset" state) - Credentials → `oauth-input` with correct `serviceId` - [ ] Dropdown `value: () => 'default'` is set for dropdowns with a sensible default +- [ ] Every `short-input`, `long-input`, `code`, and selector subBlock has a `placeholder` — including + password fields (`Enter your API key`). Formatted values show the shape + (`2023-01-01T00:00:00Z`); optional fields with a server default name it. See add-integration → Step 3 ### Advanced Mode - [ ] Optional, rarely-used fields are set to `mode: 'advanced'`: @@ -450,6 +453,10 @@ upstream PR that skipped regeneration), and investigate anything that looks like page losing a section usually means its source block moved or a generator input broke, not that the hunk should be reverted. +The integration's page must carry a `{/* MANUAL-CONTENT-START:intro */}` section directly under +``. If it is missing, write one using the template in add-integration → Step 8, and +check an existing intro against what the block actually ships (no removed or unshipped operations). + If an icon changed, `apps/sim/components/icons.tsx` is the source of truth and `apps/docs/components/icons.tsx` is its generated mirror — they must end up byte-identical for that component. ### Validation Output @@ -473,6 +480,7 @@ After fixing, confirm: - [ ] Validated every tool's ID, params, request, response, outputs, and types against API docs - [ ] Validated block ↔ tool alignment (every tool param has a subBlock, every condition is correct) - [ ] Validated advanced mode on optional/rarely-used fields +- [ ] Validated every text-entry and selector subBlock has a `placeholder` - [ ] Validated wandConfig on timestamps and complex inputs - [ ] Validated tools.config mapping, tool selector, and type coercions - [ ] Validated block outputs match what tools return, with typed JSON where possible @@ -496,6 +504,7 @@ After fixing, confirm: - [ ] Fixed all critical and warning issues - [ ] Ran `bun run tool-metadata:generate` if any tool outputs/params changed, and confirmed `bun run tool-metadata:check` passes - [ ] Ran `bun run scripts/generate-docs.ts` if any block metadata changed, and committed the full generated diff — including stale-page catch-up for other integrations (`bun run docs:check` fails CI on reverted generator output) +- [ ] Validated the docs page has an accurate `MANUAL-CONTENT-START:intro` section - [ ] Ran `bun run lint` after fixes - [ ] Verified TypeScript compiles clean - [ ] Verified added tests fail without their fix diff --git a/apps/docs/content/docs/integrations/bitbucket.mdx b/apps/docs/content/docs/integrations/bitbucket.mdx index 8da2d740a3a..e89819972b9 100644 --- a/apps/docs/content/docs/integrations/bitbucket.mdx +++ b/apps/docs/content/docs/integrations/bitbucket.mdx @@ -10,6 +10,23 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" color="#FFFFFF" /> +{/* MANUAL-CONTENT-START:intro */} +[Bitbucket](https://bitbucket.org/) is Atlassian's Git hosting service for code, pull requests, and CI/CD with Bitbucket Pipelines. + +With the Bitbucket block, you can: + +- **Browse workspaces and repositories**: List workspaces and repositories, and read repository details +- **Read source code**: List branches, commits, and directory contents, and read files and file metadata +- **Manage branches**: Create and delete branches +- **Work on pull requests**: List, read, create, approve, merge, and decline pull requests, read their diffs, and list or add comments +- **Run pipelines**: List pipelines and their steps, trigger or stop a pipeline, and read step logs + +Connect your Bitbucket account with OAuth. The Bitbucket triggers can also start a workflow on pushes, repository changes, build status updates, and pull request events, with the webhook managed for you. + +In Sim, the Bitbucket block lets your agents take part in your development process: review a pull request when it opens, summarize a failed pipeline from its step logs, or cut a release branch and open the pull request for it. +{/* MANUAL-CONTENT-END */} + + ## Usage Instructions Connect Bitbucket Cloud to inspect repositories and source, collaborate on pull requests, diagnose or control pipelines, and start workflows from repository and pull request events. OAuth is used for actions and automatic webhook management. diff --git a/apps/docs/content/docs/integrations/modal.mdx b/apps/docs/content/docs/integrations/modal.mdx index 9986a47d34b..48e8899afcd 100644 --- a/apps/docs/content/docs/integrations/modal.mdx +++ b/apps/docs/content/docs/integrations/modal.mdx @@ -10,6 +10,21 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" color="#000000" /> +{/* MANUAL-CONTENT-START:intro */} +[Modal](https://modal.com/) is a serverless platform for running Python code, AI models, and batch jobs on cloud CPUs and GPUs. + +With the Modal block, you can: + +- **Call your functions**: Send an HTTPS request to a deployed Modal Web Function or Server and get back its response +- **Generate completions**: Get chat completions from a model you serve on a Modal Endpoint +- **List models**: See which models a token can reach + +To connect, create a proxy auth token in your Modal workspace settings and enter its token ID and secret in the block. + +In Sim, the Modal block lets your agents use compute you already run on Modal: call a custom inference function, run a GPU job on data from an earlier block, or use your own hosted model inside a workflow. +{/* MANUAL-CONTENT-END */} + + ## Usage Instructions Integrate Modal into your workflow to reach the serverless compute you already run there. Invoke a deployed Web Function or Server over HTTPS with proxy-token auth, generate completions from a model served by a Modal Endpoint, and list the models a token can reach. diff --git a/apps/docs/content/docs/integrations/otter.mdx b/apps/docs/content/docs/integrations/otter.mdx index 879091512a4..c049a657f41 100644 --- a/apps/docs/content/docs/integrations/otter.mdx +++ b/apps/docs/content/docs/integrations/otter.mdx @@ -10,6 +10,21 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" color="#FFFFFF" /> +{/* MANUAL-CONTENT-START:intro */} +[Otter.ai](https://otter.ai/) is an AI meeting assistant that records, transcribes, and summarizes conversations. + +With the Otter block, you can: + +- **Read conversations**: List conversations and read each one's summary, action items, insights, outline, and transcript +- **Get recordings**: Get audio download links and import recordings for transcription +- **Browse your workspace**: List channels and their members, read workspace details, and list conversations across the workspace + +To connect, enter an API key from an Otter Enterprise workspace. The Otter triggers can also start a workflow when a conversation finishes processing or is shared. + +In Sim, the Otter block lets your agents act on your meetings: send action items to your task tracker, post summaries to Slack, or save transcripts to a knowledge base. +{/* MANUAL-CONTENT-END */} + + ## Usage Instructions Integrate Otter.ai into your workflow to list and read meeting conversations with their summaries, action items, insights, outlines, and transcripts, get audio download links, import recordings, and browse channels and workspace details. Otter can also trigger workflows when a conversation finishes processing or is shared. Requires an Otter Enterprise workspace. diff --git a/apps/docs/content/docs/integrations/planetscale.mdx b/apps/docs/content/docs/integrations/planetscale.mdx index 0b172b85c06..098d48e02ec 100644 --- a/apps/docs/content/docs/integrations/planetscale.mdx +++ b/apps/docs/content/docs/integrations/planetscale.mdx @@ -10,6 +10,22 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" color="#111111" /> +{/* MANUAL-CONTENT-START:intro */} +[PlanetScale](https://planetscale.com/) is a managed database platform for MySQL (built on Vitess) and PostgreSQL. It uses Git-style branches for schema changes and deploy requests to review and ship those changes safely. + +With the PlanetScale block, you can: + +- **Inspect databases and branches**: List the databases in an organization, read database details, and list or read branches +- **Manage branches**: Create development branches from a parent, restore a backup into a new branch, or delete branches you no longer need +- **Work with backups**: Create on-demand backups, list backups for a branch, and check a backup's state, size, and expiration +- **Ship schema changes (Vitess)**: Create deploy requests, review or approve them, queue them for deployment, and close them + +To connect, create a service token in your PlanetScale organization settings and grant it access to the databases and actions your workflow needs. Enter the service token ID, the service token, and your organization slug in the block. + +In Sim, the PlanetScale block lets your agents manage database operations as part of a workflow: spin up a branch when a pull request opens, take a backup before a release, report on backup health every day, or open and track a deploy request for a schema change. To run SQL queries against a database, use the MySQL or PostgreSQL block. +{/* MANUAL-CONTENT-END */} + + ## Usage Instructions Manage PlanetScale databases and branches, create and inspect backups, and create, review, queue, and close Vitess deploy requests. Authenticate with an organization service token. Deploy-request actions require a Vitess database; SQL queries are available through the MySQL and PostgreSQL integrations. diff --git a/apps/sim/blocks/blocks/planetscale.ts b/apps/sim/blocks/blocks/planetscale.ts index 0107dd5f813..aa6013ae855 100644 --- a/apps/sim/blocks/blocks/planetscale.ts +++ b/apps/sim/blocks/blocks/planetscale.ts @@ -124,6 +124,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'serviceTokenId', title: 'Service Token ID', type: 'short-input', + placeholder: 'Enter your service token ID', password: true, required: true, paramVisibility: 'user-only', @@ -132,6 +133,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'serviceToken', title: 'Service Token', type: 'short-input', + placeholder: 'Enter your service token', password: true, required: true, paramVisibility: 'user-only', @@ -140,13 +142,14 @@ export const PlanetScaleBlock: BlockConfig = { id: 'organization', title: 'Organization', type: 'short-input', - placeholder: 'Organization slug', + placeholder: 'Enter your organization slug', required: true, }, { id: 'q', title: 'Search', type: 'short-input', + placeholder: 'Filter by name', condition: { field: 'operation', value: ['list_databases', 'list_branches'] }, required: false, mode: 'advanced', @@ -155,6 +158,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'page', title: 'Page', type: 'short-input', + placeholder: '1', condition: { field: 'operation', value: ['list_databases', 'list_branches', 'list_backups', 'list_deploy_requests'], @@ -166,6 +170,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'perPage', title: 'Per Page', type: 'short-input', + placeholder: '25', condition: { field: 'operation', value: ['list_databases', 'list_branches', 'list_backups', 'list_deploy_requests'], @@ -225,6 +230,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualDatabase', title: 'Database', type: 'short-input', + placeholder: 'Enter database name', canonicalParamId: 'database', mode: 'advanced', required: { @@ -309,6 +315,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'name', title: 'Name', type: 'short-input', + placeholder: 'Enter a name', condition: { field: 'operation', value: ['create_branch', 'create_backup'] }, required: { field: 'operation', value: ['create_branch'] }, }, @@ -341,6 +348,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualParentBranch', title: 'Parent Branch Name', type: 'short-input', + placeholder: 'Defaults to the default branch', canonicalParamId: 'parentBranch', mode: 'advanced', required: false, @@ -366,6 +374,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualBackupId', title: 'Backup ID', type: 'short-input', + placeholder: 'Enter backup ID', canonicalParamId: 'backupId', mode: 'advanced', required: { field: 'operation', value: ['get_backup'] }, @@ -375,6 +384,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'region', title: 'Region', type: 'short-input', + placeholder: 'Defaults to the database region', condition: { field: 'operation', value: ['create_branch'] }, required: false, mode: 'advanced', @@ -383,6 +393,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'restorePoint', title: 'Restore Point', type: 'short-input', + placeholder: '2023-01-01T00:00:00Z', condition: { field: 'operation', value: ['create_branch'] }, required: false, mode: 'advanced', @@ -398,6 +409,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'replicas', title: 'Replicas', type: 'short-input', + placeholder: '0 to 8', condition: { field: 'operation', value: ['create_branch'] }, required: false, mode: 'advanced', @@ -426,6 +438,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'majorVersion', title: 'Major Version', type: 'short-input', + placeholder: 'Defaults to the parent branch version', condition: { field: 'operation', value: ['create_branch'] }, required: false, mode: 'advanced', @@ -467,6 +480,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualBranch', title: 'Branch Name', type: 'short-input', + placeholder: 'Enter branch name', canonicalParamId: 'branch', mode: 'advanced', required: { @@ -540,6 +554,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'policy', title: 'Policy', type: 'short-input', + placeholder: 'Enter backup policy ID', condition: { field: 'operation', value: ['list_backups'] }, required: false, mode: 'advanced', @@ -548,6 +563,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'from', title: 'From', type: 'short-input', + placeholder: '2023-01-01T00:00:00Z', condition: { field: 'operation', value: ['list_backups'] }, required: false, mode: 'advanced', @@ -563,6 +579,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'to', title: 'To', type: 'short-input', + placeholder: '2023-01-31T23:59:59Z', condition: { field: 'operation', value: ['list_backups'] }, required: false, mode: 'advanced', @@ -578,6 +595,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'runningAt', title: 'Running At', type: 'short-input', + placeholder: '2023-01-01T00:00:00Z..2023-01-31T23:59:59Z', condition: { field: 'operation', value: ['list_backups', 'list_deploy_requests'] }, required: false, mode: 'advanced', @@ -609,6 +627,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'retentionValue', title: 'Retention Value', type: 'short-input', + placeholder: '1 to 1000', condition: { field: 'operation', value: ['create_backup'] }, required: false, mode: 'advanced', @@ -630,6 +649,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'deployRequestState', title: 'Deploy Request State', type: 'short-input', + placeholder: 'open, closed, or deployed', condition: { field: 'operation', value: ['list_deploy_requests'] }, required: false, mode: 'advanced', @@ -650,6 +670,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualIntoBranch', title: 'Target Branch Name', type: 'short-input', + placeholder: 'Enter target branch name', canonicalParamId: 'intoBranch', mode: 'advanced', required: { field: 'operation', value: ['create_deploy_request'] }, @@ -659,6 +680,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'deployedAt', title: 'Deployed At', type: 'short-input', + placeholder: '2023-01-01T00:00:00Z..2023-01-31T23:59:59Z', condition: { field: 'operation', value: ['list_deploy_requests'] }, required: false, mode: 'advanced', @@ -674,6 +696,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'notes', title: 'Notes', type: 'long-input', + placeholder: 'Describe the schema change', condition: { field: 'operation', value: ['create_deploy_request'] }, required: false, }, @@ -735,6 +758,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'manualDeployRequestNumber', title: 'Deploy Request Number', type: 'short-input', + placeholder: 'Enter deploy request number', canonicalParamId: 'deployRequestNumber', mode: 'advanced', required: { @@ -786,6 +810,7 @@ export const PlanetScaleBlock: BlockConfig = { id: 'body', title: 'Body', type: 'long-input', + placeholder: 'Add review comments', condition: { field: 'operation', value: ['review_deploy_request'] }, required: false, },