Skip to content

Commit 90f4238

Browse files
committed
Merge branch 'staging' into codex/schedule-recovery-reconciliation
2 parents c7a839a + f5728fa commit 90f4238

1,249 files changed

Lines changed: 167346 additions & 16295 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: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ Optional companions: `credentialLabels` (override the picker's section/connect-r
172172
### OAuth deployment availability (required for integration blocks)
173173

174174
A visible tools-category block with OAuth is deployment-gated. Its `oauth-input.serviceId` is
175-
projected into `apps/sim/lib/integrations/integrations.json`, then resolved through
176-
`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`.
177177

178178
When adding or changing an OAuth integration block:
179179

@@ -184,13 +184,14 @@ When adding or changing an OAuth integration block:
184184
3. For a new capability, add its required client fields to `OAUTH_CLIENT_CAPABILITIES` and ensure
185185
every referenced field exists in the env schema in `apps/sim/lib/core/config/env.ts`. Then add
186186
the matching `text` or `secret` input modes to `OAUTH_CLIENT_SETUP_FIELDS` in
187-
`scripts/setup/capability-config.ts`. The CLI catalog is exhaustively typed and checked against
188-
the runtime field list; do not infer secrecy from the field name.
189-
4. If the canonical OAuth service declares `serviceAccountProviderId`, keep
190-
`SERVICE_ACCOUNT_METADATA_BY_OAUTH_SERVICE_ID` in
191-
`apps/sim/lib/integrations/service-account-metadata.ts` aligned. Set
192-
`deploymentRequirement` only when the service-account path is preview-gated or depends on the
193-
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.
194195

195196
Missing capability metadata is a runtime configuration error, not a reason to make the integration
196197
silently available.
@@ -992,16 +993,21 @@ After adding or changing one, run:
992993

993994
```bash
994995
bun run scripts/generate-docs.ts
996+
bun run deployment-config:generate
995997
bun run integration-catalog:check
998+
bun run deployment-config:check
996999
bun run docs:check
9971000
```
9981001

9991002
The catalog check independently derives deployment metadata from the executable block registry and
1000-
compares it with the committed `apps/sim/lib/integrations/integrations.json`. `docs:check` re-renders
1001-
every generated docs artifact in memory and fails on any committed file that differs — it runs in CI
1002-
via `check:audits`, so commit the full generator output. If the generator also trues up pages an
1003-
earlier PR left stale, commit that catch-up too; reverting it as "unrelated drift" makes `docs:check`
1004-
fail.
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.
1010+
10051011
## Checklist Before Finishing
10061012

10071013
- [ ] `integrationType` is set to the correct `IntegrationType` enum value
@@ -1046,3 +1052,34 @@ After creating the block, you MUST validate it against every tool it references:
10461052
4. **Verify conditions** — each subBlock should only show for the operations that actually use it
10471053
5. **Verify `{Service}BlockMeta` is exported** with at least 7 templates, each having `icon`, `title`, `prompt`, `modules`, `category`, and `tags`
10481054
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: 19 additions & 12 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,15 +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
564568
bun run docs:check
565569
```
566570

567571
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`).
568572

569-
The same generator refreshes `apps/sim/lib/integrations/integrations.json`. The catalog check then
570-
derives the deployment-relevant fields from the executable block registry and compares them with the
571-
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.
572577

573578
## V2 Integration Pattern
574579

@@ -647,14 +652,16 @@ If creating V2 versions (API-aligned outputs):
647652
- [ ] Created `index.ts` barrel export
648653
- [ ] Registered all triggers in `triggers/registry.ts`
649654

650-
### Docs
655+
### Docs and deployment metadata
651656
- [ ] Ran `bun run scripts/generate-docs.ts`
657+
- [ ] Ran `bun run deployment-config:generate` for OAuth or service-account changes
652658
- [ ] Verified docs file created
653-
- [ ] 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
654660
- [ ] `bun run integration-catalog:check` passes
655661
- [ ] `bun run docs:check` passes — CI fails on stale generated docs, so commit the full generator
656662
output, including catch-up regeneration for pages another PR left stale (never revert it as
657663
"unrelated drift")
664+
- [ ] `bun run deployment-config:check` passes
658665

659666
### Final Validation (Required)
660667
- [ ] Read every tool file and cross-referenced inputs/outputs against the API docs
@@ -1002,4 +1009,4 @@ requiredScopes: getScopesForService('{service}'),
10021009
11. **Never hardcode scopes** - Use `getScopesForService()` in blocks and `getCanonicalScopesForProvider()` in auth.ts
10031010
12. **Always add scope descriptions** - New scopes must have entries in `SCOPE_DESCRIPTIONS` within `lib/oauth/utils.ts`
10041011
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
1005-
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-trigger/SKILL.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,37 @@ Add to `helm/sim/values.yaml` under the existing polling cron jobs:
472472
- Cursor-based (changes API): `apps/sim/lib/webhooks/polling/google-drive.ts`
473473
- Timestamp-based: `apps/sim/lib/webhooks/polling/google-calendar.ts`
474474

475+
## Option Lists: `selectorKey` or `options`, never a per-block fetcher
476+
477+
A sub-block gets its choices from exactly one of two places. There is no third.
478+
479+
**`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.
480+
481+
```ts
482+
{ id: 'triggerCredentials', type: 'oauth-input', canonicalParamId: 'oauthCredential', mode: 'trigger' },
483+
{ id: 'labelIds', type: 'dropdown', multiSelect: true,
484+
selectorKey: 'gmail.labels', dependsOn: ['triggerCredentials'], mode: 'trigger' },
485+
{ id: 'manualLabelIds', type: 'short-input', mode: 'trigger-advanced' },
486+
```
487+
488+
`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.)
489+
490+
**`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.
491+
492+
```ts
493+
options: (params) => {
494+
const model = params?.values.model
495+
return typeof model === 'string' ? effortsFor(model) : DEFAULT_EFFORTS
496+
}
497+
```
498+
499+
**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.
500+
501+
Two rules the checks enforce:
502+
503+
- **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`).
504+
- **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.
505+
475506
## Checklist
476507

477508
### Trigger Definition

.agents/skills/babysit/SKILL.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,21 @@ round. Always check both conditions freshly after every push.
134134
When the loop ends, summarize: how many rounds it took, what was actually fixed (one line each),
135135
what was pushed back on as a false positive and why, and the final Greptile score / thread count.
136136

137+
## Public-repo hygiene
138+
139+
Every reply, comment and commit you post here is public and permanent, and review bots quote
140+
your replies back so a leak propagates. Before each post, strip anything that ties the change to
141+
a tenant: customer/company names, workspace/user/org/KB/connector IDs, emails, tenant hostnames,
142+
verbatim document/sheet/folder names, log lines, and per-tenant DB output. Cite the mechanism and
143+
aggregate numbers instead — see `/ship`'s "What to Omit" for the full list and the pre-publish
144+
grep. Triaging a finding often means pasting evidence you gathered from prod; that is exactly the
145+
moment this gets violated. Check before posting, not after: editing a comment does not unsend its
146+
notification email.
147+
137148
## Hard rules
138149

139150
- Never post the two re-review mentions as a single combined comment.
151+
- Never paste prod evidence into a reply without scrubbing it first (see above).
140152
- Never resolve a thread without replying to it first.
141153
- Never fix a finding with a hacky workaround — if the clean fix isn't obvious, find the sibling
142154
pattern elsewhere in the codebase solving the same class of problem and match it.

.agents/skills/emcn-design-review/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Use CSS variable pattern (`text-[var(--text-primary)]`), never Tailwind semantic
3939
**Surfaces**: `--bg`, `--surface-1` through `--surface-7`, `--surface-hover`, `--surface-active`
4040
**Borders**: `--border`, `--border-1`, `--border-muted`
4141
**Brand/accent**: `--brand-secondary`, `--brand-accent`
42-
**Z-Index**: `--z-dropdown` (100), `--z-modal` (200), `--z-popover` (300), `--z-tooltip` (400), `--z-toast` (500)
42+
**Z-Index**: `--z-dropdown` (100), `--z-toast` (150), `--z-modal` (200), `--z-popover` (300), `--z-tooltip` (400), `--z-takeover` (500), `--z-shell-gate` (600)
4343
**Shadows**: `shadow-subtle`, `shadow-medium`, `shadow-overlay`, `shadow-card`
4444
**Badges**: `--badge-*` semantic families (success/error/gray/blue/purple/orange/amber/teal/cyan/pink, each with `-bg`/`-text`)
4545

.agents/skills/migrate-application-operation/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Run at minimum:
317317
```bash
318318
bunx vitest run <focused test files>
319319
bunx biome check <changed source and test files>
320-
bunx turbo run type-check --filter=sim --filter=@sim/auth
320+
bunx turbo run type-check --filter=@sim/app --filter=@sim/auth
321321
bun run check:api-validation:strict
322322
git diff --check
323323
```

.agents/skills/ship/SKILL.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,20 @@ chore(scope): description for maintenance
102102

103103
## What to Omit
104104

105-
The repo is public. Keep the title and description to the code change and its reasoning — never:
105+
The repo is public. **Everything you publish — title, description, commit messages, and every later comment — must stand on its own without the incident that produced it.** Never include:
106106

107-
- Customer, company, or user names; workspace/user/org IDs; email addresses
107+
- Customer, company, or user names; workspace/user/org/KB/connector IDs; email addresses
108108
- Prod or staging operational data: log lines, DB rows, metrics, timestamps, incident details, canary/alert output
109-
- Infrastructure specifics: hostnames, ARNs, internal URLs, env var values, secret names
109+
- Infrastructure specifics: hostnames (incl. tenant subdomains), ARNs, internal URLs, env var values, secret names
110+
- Verbatim customer content: file names, document titles, sheet/column names, folder paths
110111

111-
Describe the bug by its mechanism, not by how you found it. "Expired OAuth credentials fail to refresh in the worker" — not "the Sheets canary failed at 16:31Z for workspace abc-123".
112+
Describe the bug by its mechanism, not by how you found it. "Expired OAuth credentials fail to refresh in the worker" — not "the Sheets canary failed at 16:31Z for workspace abc-123". Aggregate counts are fine once detached from the tenant ("1,379 PDFs failed"); the same number attributed to a named customer is not. Replace real examples with placeholders (`<real sheet name>`) rather than cutting them — the illustration is usually the useful part.
113+
114+
**Scrub before publishing, not after** — a leak is public the instant it posts, and editing later does not unsend the notification email. This applies to every PR you open, including ones created directly with `gh pr create` rather than through this skill. Grep the title, body, and `git log origin/staging..HEAD` before publishing:
115+
116+
```bash
117+
grep -niE 'customer-or-company-name|@[a-z0-9.-]+\.(com|io|ai)|[0-9a-f]{8}-[0-9a-f]{4}-|\.sharepoint\.com|arn:aws|https?://[a-z0-9.-]*\.internal'
118+
```
112119

113120
## PR Description Format
114121

0 commit comments

Comments
 (0)