Skip to content

Commit 1e0b3a6

Browse files
committed
Merge remote-tracking branch 'origin/staging' into staging-v64
2 parents c6c5f56 + cbf3aad commit 1e0b3a6

6,041 files changed

Lines changed: 1028863 additions & 136384 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/add-block/SKILL.md

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ export const {ServiceName}Block: BlockConfig = {
5252
// Auth mode
5353
authMode: AuthMode.OAuth, // or AuthMode.ApiKey
5454

55+
// Card summary sentences — see "Canvas Sentences" below
56+
canvasPresentation: {
57+
defaultTitle: '{Default Operation}',
58+
sentences: { byOperation: { /* one per operation dropdown option id */ } },
59+
},
60+
5561
subBlocks: [
5662
// Define all UI fields here
5763
],
@@ -166,8 +172,8 @@ Optional companions: `credentialLabels` (override the picker's section/connect-r
166172
### OAuth deployment availability (required for integration blocks)
167173

168174
A visible tools-category block with OAuth is deployment-gated. Its `oauth-input.serviceId` is
169-
projected into `apps/sim/lib/integrations/integrations.json`, then resolved through
170-
`resolveOAuthClientCapabilityId()` in `apps/sim/lib/core/config/env-capabilities.ts`.
175+
projected into `packages/deployment-config/src/integrations.json`, then resolved through
176+
`resolveOAuthClientCapabilityId()` in `packages/deployment-config/src/env-capabilities.ts`.
171177

172178
When adding or changing an OAuth integration block:
173179

@@ -178,13 +184,14 @@ When adding or changing an OAuth integration block:
178184
3. For a new capability, add its required client fields to `OAUTH_CLIENT_CAPABILITIES` and ensure
179185
every referenced field exists in the env schema in `apps/sim/lib/core/config/env.ts`. Then add
180186
the matching `text` or `secret` input modes to `OAUTH_CLIENT_SETUP_FIELDS` in
181-
`scripts/setup/capability-config.ts`. The CLI catalog is exhaustively typed and checked against
182-
the runtime field list; do not infer secrecy from the field name.
183-
4. If the canonical OAuth service declares `serviceAccountProviderId`, keep
184-
`SERVICE_ACCOUNT_METADATA_BY_OAUTH_SERVICE_ID` in
185-
`apps/sim/lib/integrations/service-account-metadata.ts` aligned. Set
186-
`deploymentRequirement` only when the service-account path is preview-gated or depends on the
187-
OAuth client fields; otherwise omit it.
187+
`packages/sim-setup/src/capability-config.ts`. The CLI catalog is exhaustively typed and checked
188+
against the runtime field list; do not infer secrecy from the field name.
189+
4. If the canonical OAuth service declares `serviceAccountProviderId`, run
190+
`bun run deployment-config:generate`; this regenerates the provider-ID facts in
191+
`packages/deployment-config/src/service-account-providers.generated.ts`. Never hand-edit that
192+
generated map. Add `deploymentRequirement` policy in
193+
`packages/deployment-config/src/service-account-metadata.ts` only when the service-account path
194+
is preview-gated or depends on the OAuth client fields; otherwise omit it.
188195

189196
Missing capability metadata is a runtime configuration error, not a reason to make the integration
190197
silently available.
@@ -945,6 +952,35 @@ Derive templates from the service's real use cases. Each prompt should name a co
945952
- **Ground every skill in operations the block actually exposes** — cross-check each skill's steps against `tools.access`. Never describe an action the integration cannot perform.
946953
- **Derive skills from real, popular use cases found online — never invent them.** Web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles) and only add a skill you can source as something people genuinely do with the service. Do not hallucinate skills.
947954

955+
## Canvas Sentences
956+
957+
Every block declares a one-line prose summary that replaces its card's field rows:
958+
959+
```
960+
Slack ← header (already names the block)
961+
Posts ⟨Ship it 🚀⟩ to ⟨#eng⟩ ← the sentence; ⟨…⟩ are live value chips
962+
```
963+
964+
Write one `byOperation` entry per operation dropdown option (or a single `default`
965+
when the block has no operation dropdown).
966+
967+
**The full authoring contract — voice, structure, and the two mistakes that break
968+
cards silently — is `apps/sim/blocks/AGENTS.md` → "Canvas sentences". Read it
969+
before writing any.** The two failures worth repeating here, because both are
970+
invisible at runtime:
971+
972+
1. A clause naming only one member of a `canonicalParamId` pair drops the sentence
973+
for every advanced-mode user. List all members:
974+
`field: ['channelSelector', 'manualChannel']`.
975+
2. A clause referencing a subblock whose `condition` excludes that operation can
976+
never render.
977+
978+
Validate before finishing:
979+
980+
```bash
981+
bun run apps/sim/scripts/check-canvas-sentences.ts --block={service}
982+
```
983+
948984
## Generated artifacts
949985

950986
Adding a block on its own needs no **tool metadata** regeneration — a block references existing
@@ -957,12 +993,20 @@ After adding or changing one, run:
957993

958994
```bash
959995
bun run scripts/generate-docs.ts
996+
bun run deployment-config:generate
960997
bun run integration-catalog:check
998+
bun run deployment-config:check
999+
bun run docs:check
9611000
```
9621001

9631002
The catalog check independently derives deployment metadata from the executable block registry and
964-
compares it with the committed `apps/sim/lib/integrations/integrations.json`. Review the generated
965-
diff and keep only intentional changes.
1003+
compares it with the committed `packages/deployment-config/src/integrations.json`. The deployment
1004+
config check verifies the generated service-account facts against the canonical OAuth registry and
1005+
catalog. `docs:check` re-renders every generated docs artifact in memory and fails on any committed
1006+
file that differs — it runs in CI via `check:audits`, so commit the full generator output. If the
1007+
generator also trues up pages an earlier PR left stale, commit that catch-up too; reverting it as
1008+
"unrelated drift" makes `docs:check` fail. Review the generated diff and keep only intentional
1009+
changes.
9661010

9671011
## Checklist Before Finishing
9681012

@@ -984,13 +1028,15 @@ diff and keep only intentional changes.
9841028
- [ ] If any tool was added, changed or removed alongside the block: ran `bun run tool-metadata:generate` and committed the artifacts
9851029
- [ ] Ran `bun run scripts/generate-docs.ts`, reviewed the generated diff, and committed the integration catalog changes
9861030
- [ ] `bun run integration-catalog:check` passes
1031+
- [ ] `bun run docs:check` passes (CI gate — fails on any stale generated docs page)
9871032
- [ ] If icon missing: asked user to provide SVG
9881033
- [ ] If triggers exist: `triggers` config set, trigger subBlocks spread
9891034
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`
9901035
- [ ] Timestamps and complex inputs have `wandConfig` enabled
9911036
- [ ] Exported `{Service}BlockMeta` with at least 7 templates
9921037
- [ ] `url` set on `{Service}BlockMeta` to the external service's verified homepage (omit only for first-party blocks with no external service)
9931038
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in `tools.access` and sourced from a real online use case (not invented)
1039+
- [ ] `canvasPresentation.sentences` covers every operation, and `bun run apps/sim/scripts/check-canvas-sentences.ts --block={service}` passes with 100% coverage
9941040

9951041
## Final Validation (Required)
9961042

@@ -1006,3 +1052,34 @@ After creating the block, you MUST validate it against every tool it references:
10061052
4. **Verify conditions** — each subBlock should only show for the operations that actually use it
10071053
5. **Verify `{Service}BlockMeta` is exported** with at least 7 templates, each having `icon`, `title`, `prompt`, `modules`, `category`, and `tags`
10081054
6. **If any tool outputs are still unknown**, explicitly tell the user instead of guessing block outputs
1055+
1056+
## Option Lists: `selectorKey` or `options`, never a per-block fetcher
1057+
1058+
A sub-block gets its choices from exactly one of two places. There is no third.
1059+
1060+
**`selectorKey` — every remote list.** Register the list in `hooks/selectors/providers/<service>/selectors.ts`, add its key to `SelectorKey`, and point the sub-block at it. A selector is parameterized by an explicit `SelectorContext`, so the same definition serves the canvas, the workspace-fork sync modal, and anything added later.
1061+
1062+
```ts
1063+
{ id: 'triggerCredentials', type: 'oauth-input', canonicalParamId: 'oauthCredential', mode: 'trigger' },
1064+
{ id: 'labelIds', type: 'dropdown', multiSelect: true,
1065+
selectorKey: 'gmail.labels', dependsOn: ['triggerCredentials'], mode: 'trigger' },
1066+
{ id: 'manualLabelIds', type: 'short-input', mode: 'trigger-advanced' },
1067+
```
1068+
1069+
`canonicalParamId: 'oauthCredential'` on the credential sub-block is the line people forget. `buildSelectorContextFromBlock` keys the context on a sub-block's CANONICAL id, so without it `context.oauthCredential` is never set and the picker looks unfixable without reading the store. (A credential field is also recognised by its `oauth-input` TYPE as a fallback, so a block whose shipped param is already named something else does not have to rename it.)
1070+
1071+
**`options` — everything else.** A static array, or a pure function of the block's own values for a list that narrows to a sibling's selection. No I/O.
1072+
1073+
```ts
1074+
options: (params) => {
1075+
const model = params?.values.model
1076+
return typeof model === 'string' ? effortsFor(model) : DEFAULT_EFFORTS
1077+
}
1078+
```
1079+
1080+
**Never fetch inside `options`, and never reach into the stores from a block definition.** A fetcher that resolves its credential with `readSubBlockValue(blockId, ...)` only works on the canvas — every surface that is not the editor gets an empty list. `fetchOptions`/`fetchOptionById` were removed for exactly this reason.
1081+
1082+
Two rules the checks enforce:
1083+
1084+
- **A secret never enters a selector's `getQueryKey`.** A query key identifies a resource; a credential authorizes access to it. A credential *id* is fine; a typed password is not (see `imap.mailboxes`).
1085+
- **A sub-block that `dependsOn` a credential / knowledge-base / table selector must be reconfigurable at fork-sync time** — a `selectorKey`, a canonical pair whose basic member is a selector, or a `short-input`/`long-input`. `bun run check:fork-dependent-coverage` fails otherwise, because a fork sync clears those fields on every push and an unofferable one can never be set anywhere that sticks.

.agents/skills/add-integration/SKILL.md

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -538,16 +538,18 @@ the OAuth service configuration, deployment availability, and the setup CLI.
538538
1. Ensure the block has exactly one distinct OAuth `serviceId` and that it matches the canonical
539539
service entry in `apps/sim/lib/oauth/oauth.ts`.
540540
2. Confirm `resolveOAuthClientCapabilityId(serviceId)` resolves to the intended provider entry in
541-
`OAUTH_CLIENT_CAPABILITIES` in `apps/sim/lib/core/config/env-capabilities.ts`. Google and
541+
`OAUTH_CLIENT_CAPABILITIES` in `packages/deployment-config/src/env-capabilities.ts`. Google and
542542
Microsoft service IDs deliberately share provider-level capabilities.
543543
3. For a new OAuth provider, add the required client fields to `OAUTH_CLIENT_CAPABILITIES`, add
544544
every referenced field to the env schema in `apps/sim/lib/core/config/env.ts`, and add the
545545
matching `text` or `secret` entries to `OAUTH_CLIENT_SETUP_FIELDS` in
546-
`scripts/setup/capability-config.ts`. Do not create integration-specific setup logic or infer
547-
secret fields from naming; the CLI mapping is exhaustively checked against the runtime fields.
548-
4. If the canonical OAuth service has `serviceAccountProviderId`, add the matching projection to
549-
`SERVICE_ACCOUNT_METADATA_BY_OAUTH_SERVICE_ID` in
550-
`apps/sim/lib/integrations/service-account-metadata.ts`. Use:
546+
`packages/sim-setup/src/capability-config.ts`. Do not create integration-specific setup logic or
547+
infer secret fields from naming; the CLI mapping is exhaustively checked against the runtime
548+
fields.
549+
4. If the canonical OAuth service has `serviceAccountProviderId`, run
550+
`bun run deployment-config:generate` to refresh
551+
`packages/deployment-config/src/service-account-providers.generated.ts`; never hand-edit the
552+
generated provider-ID map. In `packages/deployment-config/src/service-account-metadata.ts`, use:
551553
- no `deploymentRequirement` when the service-account path works independently of OAuth client fields;
552554
- `'oauth-client'` when it requires the same deployment OAuth client fields;
553555
- `'preview-gated'` when availability is controlled by the service-account preview block.
@@ -560,14 +562,18 @@ a resolvable capability must fail validation.
560562
Run the documentation generator:
561563
```bash
562564
bun run scripts/generate-docs.ts
565+
bun run deployment-config:generate
563566
bun run integration-catalog:check
567+
bun run deployment-config:check
568+
bun run docs:check
564569
```
565570

566571
This creates `apps/docs/content/docs/en/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`).
567572

568-
The same generator refreshes `apps/sim/lib/integrations/integrations.json`. The catalog check then
569-
derives the deployment-relevant fields from the executable block registry and compares them with the
570-
committed projection. Review the generated diff and keep only intentional changes.
573+
The docs generator refreshes `packages/deployment-config/src/integrations.json`, and the deployment
574+
config generator projects service-account provider IDs from that catalog plus the canonical OAuth
575+
registry. The checks compare both committed projections with their sources. Review the generated
576+
diff and keep only intentional changes.
571577

572578
## V2 Integration Pattern
573579

@@ -646,11 +652,16 @@ If creating V2 versions (API-aligned outputs):
646652
- [ ] Created `index.ts` barrel export
647653
- [ ] Registered all triggers in `triggers/registry.ts`
648654

649-
### Docs
655+
### Docs and deployment metadata
650656
- [ ] Ran `bun run scripts/generate-docs.ts`
657+
- [ ] Ran `bun run deployment-config:generate` for OAuth or service-account changes
651658
- [ ] Verified docs file created
652-
- [ ] Reviewed and committed the generated `apps/sim/lib/integrations/integrations.json` change
659+
- [ ] Reviewed and committed the generated `packages/deployment-config/src/integrations.json` change
653660
- [ ] `bun run integration-catalog:check` passes
661+
- [ ] `bun run docs:check` passes — CI fails on stale generated docs, so commit the full generator
662+
output, including catch-up regeneration for pages another PR left stale (never revert it as
663+
"unrelated drift")
664+
- [ ] `bun run deployment-config:check` passes
654665

655666
### Final Validation (Required)
656667
- [ ] Read every tool file and cross-referenced inputs/outputs against the API docs
@@ -768,9 +779,11 @@ tools: {
768779
}
769780
```
770781

771-
#### 3. Create Internal API Route
782+
#### 3. Create Special Internal Tool Execution Route
772783

773-
Create `apps/sim/app/api/tools/{service}/{action}/route.ts`. Internal tool routes are HTTP boundaries and follow the same contract policy as public routes — define the request/response shape in `apps/sim/lib/api/contracts/tools/{service}.ts` (or an existing aggregate) and validate with canonical helpers from `@/lib/api/server`. Never write a route-local Zod schema.
784+
Create `apps/sim/app/api/tools/{service}/{action}/route.ts`. This raw route pattern is only for an integration's provider-execution boundary when it needs special file normalization, large-body handling, or protocol behavior. It is not the pattern for CRUD or other operations on protected Sim resources. For those, use the `migrate-application-operation` skill and an authorized application use case with the ordinary internal/v2 route builders.
785+
786+
Internal tool routes are HTTP boundaries and follow the same contract policy as public routes — define the request/response shape in `apps/sim/lib/api/contracts/tools/{service}.ts` (or an existing aggregate) and validate with canonical helpers from `@/lib/api/server`. Never write a route-local Zod schema. Authenticate and perform cheap admission before parsing or downloading files.
774787

775788
```typescript
776789
// apps/sim/lib/api/contracts/tools/{service}.ts
@@ -996,4 +1009,4 @@ requiredScopes: getScopesForService('{service}'),
9961009
11. **Never hardcode scopes** - Use `getScopesForService()` in blocks and `getCanonicalScopesForProvider()` in auth.ts
9971010
12. **Always add scope descriptions** - New scopes must have entries in `SCOPE_DESCRIPTIONS` within `lib/oauth/utils.ts`
9981011
13. **OAuth service IDs need deployment capabilities** - Every visible OAuth integration must resolve through `OAUTH_CLIENT_CAPABILITIES`; shared Google/Microsoft aliases map to their provider capability
999-
14. **Keep runtime and presentation separate** - Runtime OAuth fields live in `env-capabilities.ts`; CLI input modes live in the exhaustively checked `scripts/setup/capability-config.ts` mapping
1012+
14. **Keep runtime and presentation separate** - Runtime OAuth fields live in `packages/deployment-config/src/env-capabilities.ts`; CLI input modes live in the exhaustively checked `packages/sim-setup/src/capability-config.ts` mapping

.agents/skills/add-tools/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,9 @@ All tool IDs MUST use `snake_case`: `{service}_{action}` (e.g., `x_create_tweet`
475475
- [ ] Index.ts exports all tools and re-exports types (`export * from './types'`)
476476
- [ ] Tools registered in `tools/registry.ts`
477477
- [ ] `bun run tool-metadata:generate` run and the regenerated artifacts committed
478+
- [ ] `bun run scripts/generate-docs.ts` run and the refreshed docs committed — the integration's
479+
docs page is rendered from each tool's description, params, and outputs, and CI's
480+
`bun run docs:check` fails on stale pages
478481
- [ ] Block wired: `tools.access`, dropdown options, subBlocks, `tools.config`, outputs, inputs
479482
- [ ] Model, durable-storage, and internal-execution boundaries use the shared provenance mechanisms
480483
only where a concrete Sim `{{...}}` resolution path requires them

0 commit comments

Comments
 (0)