Skip to content

Commit d5190c4

Browse files
Merge origin/staging into feat/sim-cli
Staging is authoritative for the app: all 538 conflicts (344 add/add, 193 content, 1 modify/delete) resolved to staging's side. The CLI is adapted to staging's v2 shapes rather than the reverse. CLI refactor for the new v2 surface: - describeFile -> getFile (/files/[fileId]/metadata, json) - getFileContent -> downloadFile (/files/[fileId], binary) - shareFile/unshareFile -> getFileShare + upsertFileShare, exposed as `files share get` / `files share set`; v2 folds unshare into the same PATCH via --is-active false, so there is no separate operation Generator fixes (scripts/generate-v2-cli-api.ts): - resolve $ref against $defs when classifying a request field. Staging's `.meta({ id })` schemas are lifted into $defs, so every folder-path field read as `unknown` and the CLI demanded JSON for a plain string flag - treat an annotation-only schema as `unknown` instead of throwing Merge artifacts repaired (auto-merged clean, semantically wrong): - primitives.ts: duplicate workspaceFileNameSchema - blob/client.ts: duplicate getBlobPresignedUploadUrl. The two copies differed -- ours signed with SAS permission 'w' (authorizes overwriting an existing blob), staging with 'c' (create-only). Kept staging's - lifecycle.ts, workflow-utils.ts, persisted-message.test.ts, edit-workflow/index.ts: our call sites left against staging's signatures - dropped credential-extractor.secretless.test.ts and the preserveWorkspaceReferences option it covers; staging's sanitizer has no such option, so the secretless copilot projection now follows staging and no longer preserves workspace resource ids turn-persistence.ts removed: staging carries that logic inline in post.ts, so nothing imported it after the merge. Verified: apps/sim and packages/sim-cli type-check; 212 CLI tests pass; check:api-validation passes at staging's 1107-route baseline (the stripped chat routes never existed on staging); lint:check green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JNFjchn6dcM7xevh34PKHE
2 parents ebfa60f + a7115e8 commit d5190c4

3,487 files changed

Lines changed: 384026 additions & 62876 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: 36 additions & 1 deletion
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
],
@@ -945,6 +951,35 @@ Derive templates from the service's real use cases. Each prompt should name a co
945951
- **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.
946952
- **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.
947953

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

950985
Adding a block on its own needs no **tool metadata** regeneration — a block references existing
@@ -963,7 +998,6 @@ bun run integration-catalog:check
963998
The catalog check independently derives deployment metadata from the executable block registry and
964999
compares it with the committed `apps/sim/lib/integrations/integrations.json`. Review the generated
9651000
diff and keep only intentional changes.
966-
9671001
## Checklist Before Finishing
9681002

9691003
- [ ] `integrationType` is set to the correct `IntegrationType` enum value
@@ -991,6 +1025,7 @@ diff and keep only intentional changes.
9911025
- [ ] Exported `{Service}BlockMeta` with at least 7 templates
9921026
- [ ] `url` set on `{Service}BlockMeta` to the external service's verified homepage (omit only for first-party blocks with no external service)
9931027
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in `tools.access` and sourced from a real online use case (not invented)
1028+
- [ ] `canvasPresentation.sentences` covers every operation, and `bun run apps/sim/scripts/check-canvas-sentences.ts --block={service}` passes with 100% coverage
9941029

9951030
## Final Validation (Required)
9961031

.agents/skills/add-column-type/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ This was not always true: adding `currency` originally took ~40 edits across 32
1515
Do **not** hunt for places to edit. Add your type to the `ColumnType` union first and let `tsc` produce the list:
1616

1717
```bash
18-
cd apps/sim && bunx tsc --noEmit -p tsconfig.json
18+
cd apps/sim && bun run type-check
1919
```
2020

2121
You will get two errors, naming `column-types/registry.ts` and `column-types/registry.server.ts`. Register in both.
@@ -153,7 +153,7 @@ Registering the *type* is compiler-enforced. Registering its *metadata* is not,
153153

154154
## Final Validation (Required)
155155

156-
1. **`cd apps/sim && bunx tsc --noEmit -p tsconfig.json`** — must be clean. If any file *outside* `column-types/` errors, that file has a hardcoded type list; fix it to read the registry.
156+
1. **`cd apps/sim && bun run type-check`** — must be clean. If any file *outside* `column-types/` errors, that file has a hardcoded type list; fix it to read the registry.
157157
2. **Grep for leaks**`grep -rnE "(===|!==) '{id}'|case '{id}':" apps/sim --include='*.ts' --include='*.tsx' | grep -v column-types/`. (All three forms: a plain `!==` and a `case` are how half of `currency`'s real branches are written.) Hits are expected; judge each. A hit is fine when it mounts a specific React component or encodes a genuinely one-off behavior (`json`'s mono textarea, `date`'s timezone-aware parsing). A hit is a **leak** when it restates something the registry could answer — an icon, a label, a colour, an operator set, a cast, a coercion. Leaks get a registry field, not a new branch.
158158
3. **Run the suite**`bunx vitest run lib/table 'app/workspace/[workspaceId]/tables' lib/api app/api/table app/api/v1 lib/copilot/tools/server/table`. Existing tests must pass **unchanged**; needing to edit one means you changed behavior for the other types.
159159
4. **`bun run lint:check`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export const ENRICHMENT_REGISTRY: EnrichmentRegistry = {
128128

129129
## Step 5: Verify
130130

131-
1. `bunx tsc --noEmit` (from `apps/sim`, `NODE_OPTIONS=--max-old-space-size=8192`) and `bunx biome check` on the changed files.
131+
1. `bun run type-check` (from `apps/sim`) and `bunx biome check` on the changed files.
132132
2. In a table → **+ New column → Enrichments** → pick the new enrichment, map its inputs to columns, name the output column(s), Save. Confirm it appears in the catalog with its icon/description.
133133
3. With hosted keys (or a workspace BYOK key) configured for each provider's service, run a row and confirm the cell fills; the dev-server log shows `Enrichment hit { provider }`. A row whose providers all miss completes blank; a row where every provider errored shows an error cell.
134134

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

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,24 @@ service's official documentation or an unambiguous local execution path proves t
131131
field is consumed by an AI model. If that cannot be established, preserve existing tool behavior
132132
and leave the field unannotated.
133133

134-
- **Ordinary provider/API input:** leave it unchanged. Do not add blanket result sanitization.
134+
- **Ordinary provider/API input:** leave it unchanged. Explicit `{{...}}` references resolve and are
135+
sent with their normal request semantics. A URL, domain, resource ID, control field, or opaque
136+
payload is not model-visible merely because the provider is AI-backed or may process the
137+
referenced resource later.
135138
- **Text or structured content consumed by an AI model:** declare `request.modelInput` with
136139
`mode: 'project'` and select only the exact model-visible fields. The shared executor replaces
137140
activated Sim secrets with canonical `{{NAME}}` labels before request formatting. For nested or
138141
JSON-string fields, use a small shared selector plus `applyProjected`; verify that selecting the
139142
rebuilt params reproduces the projected selection.
140-
- **Opaque model input sent directly to an external provider** such as a model-read URL or image
141-
payload: declare `request.opaqueModelInput` with `mode: 'reject-resolved-secrets'` and select only
142-
the exact effective value. The shared `executeTool` preflight rejects incomplete or secret-bearing
143-
committed provenance before URL/body formatting or network I/O, preserves safe request bytes,
144-
and sends no provenance metadata to the provider.
145-
- **Opaque model input owned by an authenticated internal route** such as uploaded audio, image,
146-
video, file bytes, or signed URLs: add `privateProvenance` to a projected request, or use
147-
`mode: 'private-provenance'` when there is no textual projection. The route must call
143+
- **Serialized model content sent directly to an external provider:** include the serialized
144+
top-level param in `request.modelInput`. Project the private copy before the existing request
145+
formatter parses it; keep formatter behavior deterministic when a whole-value placeholder is not
146+
valid in the serialized grammar. Do not introduce a second hard-rejection path.
147+
- **Opaque model input owned by an authenticated internal route** such as inline audio, image,
148+
video, or document bytes: add `privateProvenance` to a projected request, or use
149+
`mode: 'private-provenance'` when there is no textual projection. Do not select storage keys,
150+
paths, signed URLs, or ordinary remote URLs as byte provenance; the owning route must authorize
151+
stored bytes independently at model egress. The route must call
148152
`validateOpaqueModelInputProvenance` before downloading or sending content to the model and must
149153
apply the workspace-file provenance guard before reading a persisted workspace file.
150154
- **Sim-owned durable storage or internal execution handoff** that can later enter a workflow/model
@@ -160,9 +164,9 @@ Hard rules:
160164
- Never substitute secret plaintext into source or serialize plaintext provenance.
161165
- Never hand-roll private provenance headers/envelopes; the shared `executeTool` boundary owns
162166
transport and strips private metadata from functional results.
163-
- Never attach private provenance to an external URL or to `directExecution`. Use the centralized
164-
`opaqueModelInput` rejection mode for external/direct opaque model inputs, or an authenticated
165-
internal route when encrypted provenance must cross the boundary.
167+
- Never attach private provenance to an external URL or to `directExecution`. Project proven
168+
model-visible external fields with `request.modelInput`; otherwise preserve ordinary request
169+
semantics. Use an authenticated internal route when encrypted provenance must cross the boundary.
166170
- Never sanitize arbitrary third-party tool results. Projection applies only to secrets activated
167171
by Sim's resolved-secret provenance for that execution/tool call.
168172
- Do not add provenance merely because a value is persisted, returned by a tool, or appears in a
@@ -173,12 +177,11 @@ Hard rules:
173177
provider responses, filenames, URLs, and errors remain unchanged when Sim did not resolve a
174178
secret into them.
175179

176-
Add focused tests covering named projection, ordinary identical text without provenance, nested
177-
shape preservation, malformed/incomplete private metadata failing closed, centralized external
178-
opaque rejection before formatting/I/O without byte changes or metadata transport, headerless
179-
legacy requests, and absence of private metadata in the public tool result. For durable sinks, also
180-
cover legacy `NULL` markers, exact-empty new writes, tracked secret writes, stale/missing sidecars,
181-
and scope isolation.
180+
Add focused tests covering named projection, ordinary identical text without provenance, nested and
181+
serialized shape handling, unchanged ordinary external inputs, malformed/incomplete private metadata
182+
failing closed, headerless legacy requests, and absence of private metadata in the public tool result.
183+
For durable sinks, also cover legacy `NULL` markers, exact-empty new writes, tracked secret writes,
184+
stale/missing sidecars, and scope isolation.
182185

183186
## Step 3: Create Block
184187

@@ -594,8 +597,8 @@ If creating V2 versions (API-aligned outputs):
594597
- [ ] Registered all tools in `tools/registry.ts`
595598
- [ ] Ran `bun run tool-metadata:generate` and committed the regenerated artifacts
596599
- [ ] Classified every model-visible, opaque, Sim-durable, and internal-execution request field
597-
- [ ] Added shared model-input projection, centralized opaque rejection, or private provenance only
598-
where required
600+
- [ ] Added shared model-input projection or private provenance only where required; ordinary
601+
external resource locators and control inputs retain their request semantics
599602
- [ ] Confirmed ordinary third-party tool results are not generically sanitized
600603
- [ ] Added provenance compatibility and fail-closed boundary tests where applicable
601604

@@ -765,9 +768,11 @@ tools: {
765768
}
766769
```
767770

768-
#### 3. Create Internal API Route
771+
#### 3. Create Special Internal Tool Execution Route
769772

770-
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.
773+
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.
774+
775+
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.
771776

772777
```typescript
773778
// apps/sim/lib/api/contracts/tools/{service}.ts

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,16 @@ export const {serviceName}{Action}Tool: ToolConfig<
150150
- Leave ordinary external API inputs and third-party results unchanged. Add provenance handling only
151151
when an exact field is proven to cross a Sim model, durable-storage, or internal-execution boundary.
152152
- Project AI-consumed text/structured fields with the smallest exact `request.modelInput` selector.
153-
- Reject resolved secrets in opaque model input sent directly to an external provider with
154-
`request.opaqueModelInput`; never attach private metadata to an external URL or `directExecution`.
155-
- For authenticated internal routes, use `privateProvenance` for opaque model input or
156-
`request.secretProvenance` for durable writes and execution handoffs. Authenticate first, validate
157-
the exact selection and scope, strip the private envelope, then import or propagate provenance at
158-
the receiving boundary. Preserve documented headerless legacy behavior.
153+
- Treat URLs, domains, resource IDs, and control fields as ordinary request values unless the exact
154+
field is proven model-visible. For serialized external model content, project the serialized
155+
top-level param through `request.modelInput` before the existing formatter parses it; do not add a
156+
separate hard-rejection mechanism.
157+
- For authenticated internal routes, use `privateProvenance` for actual inline/raw model bytes or
158+
`request.secretProvenance` for durable writes and execution handoffs. Do not treat a storage key,
159+
path, signed URL, or remote URL as provenance for fetched bytes; authorize tracked stored bytes at
160+
the owning model-egress boundary. Authenticate first, validate the exact selection and scope,
161+
strip the private envelope, then import or propagate provenance at the receiving boundary.
162+
Preserve documented headerless legacy behavior.
159163
- Never substitute secret plaintext into source, serialize plaintext provenance, hand-roll private
160164
headers, or blanket-sanitize tool results.
161165
- Add focused tests for named projection, identical unproven public text, malformed/incomplete

.agents/skills/design-taste-frontend/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
name: design-taste-frontend
3+
source: https://github.com/leonxlnx/taste-skill — skills/taste-skill/SKILL.md
34
description: Anti-slop frontend skill for landing pages, portfolios, and redesigns. The agent reads the brief, infers the right design direction, and ships interfaces that do not look templated. Real design systems when applicable, audit-first on redesigns, strict pre-flight check.
45
---
56

.agents/skills/emil-design-eng/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
name: emil-design-eng
3+
source: https://github.com/emilkowalski/skill — skills/emil-design-eng/SKILL.md
34
description: This skill encodes Emil Kowalski's philosophy on UI polish, component design, animation decisions, and the invisible details that make software feel great.
45
---
56

.agents/skills/make-interfaces-feel-better/SKILL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
name: make-interfaces-feel-better
3+
source: https://github.com/jakubkrehel/make-interfaces-feel-better — skills/make-interfaces-feel-better/SKILL.md
34
description: Design engineering principles for making interfaces feel polished. Use when building UI components, reviewing frontend code, implementing animations, hover states, shadows, borders, typography, micro-interactions, enter/exit animations, or any visual detail work. Triggers on UI polish, design details, "make it feel better", "feels off", stagger animations, border radius, optical alignment, font smoothing, tabular numbers, image outlines, box shadows.
45
---
56

0 commit comments

Comments
 (0)