Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/add-column-type/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ This was not always true: adding `currency` originally took ~40 edits across 32
Do **not** hunt for places to edit. Add your type to the `ColumnType` union first and let `tsc` produce the list:

```bash
cd apps/sim && bunx tsc --noEmit -p tsconfig.json
cd apps/sim && bun run type-check
```

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

## Final Validation (Required)

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.
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.
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.
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.
4. **`bun run lint:check`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.
Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/add-enrichment/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,7 +128,7 @@ export const ENRICHMENT_REGISTRY: EnrichmentRegistry = {

## Step 5: Verify

1. `bunx tsc --noEmit` (from `apps/sim`, `NODE_OPTIONS=--max-old-space-size=8192`) and `bunx biome check` on the changed files.
1. `bun run type-check` (from `apps/sim`) and `bunx biome check` on the changed files.
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.
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.

Expand Down
4 changes: 2 additions & 2 deletions .claude/commands/add-column-type.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,7 +14,7 @@ This was not always true: adding `currency` originally took ~40 edits across 32
Do **not** hunt for places to edit. Add your type to the `ColumnType` union first and let `tsc` produce the list:

```bash
cd apps/sim && bunx tsc --noEmit -p tsconfig.json
cd apps/sim && bun run type-check
```

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

## Final Validation (Required)

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.
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.
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.
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.
4. **`bun run lint:check`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.
Expand Down
2 changes: 1 addition & 1 deletion .claude/commands/add-enrichment.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -127,7 +127,7 @@ export const ENRICHMENT_REGISTRY: EnrichmentRegistry = {

## Step 5: Verify

1. `bunx tsc --noEmit` (from `apps/sim`, `NODE_OPTIONS=--max-old-space-size=8192`) and `bunx biome check` on the changed files.
1. `bun run type-check` (from `apps/sim`) and `bunx biome check` on the changed files.
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.
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.

Expand Down
7 changes: 7 additions & 0 deletions .claude/rules/global.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -65,3 +65,10 @@ const filtered = filterUndefined(obj)

## Package Manager
Use `bun` and `bunx`, not `npm` and `npx`.

## Type-checking
`tsc` must resolve to the native (Go) TypeScript 7 compiler. Do not remove the `@typescript/native` alias from the root `devDependencies` — nothing imports it, and deleting it looks harmless.

`apps/sim` needs `@typescript/typescript6` for its runtime TypeScript API, and that package depends on `@typescript/old` — an alias of `typescript@6` — which declares its own `tsc` bin. Package managers pick bin winners by lexical sort rather than dependency depth, so `@typescript/old` beats `typescript` and `node_modules/.bin/tsc` silently becomes the JavaScript TypeScript 6 compiler: identical diagnostics, ~10x slower (83s vs 8s on `apps/sim`). The `@typescript/native` alias exists only to sort ahead of `@typescript/old`.

`bun run check:native-typecheck` fails the build if a bare `tsc` stops reporting 7.x — which is also what a newly added package that sorts ahead of `@typescript/native` and ships a `tsc` bin would look like. See [microsoft/typescript-go#4567](https://github.com/microsoft/typescript-go/issues/4567).
6 changes: 3 additions & 3 deletions .claude/skills/add-settings-page/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ Key paths:
hand-roll a Save button, a `beforeunload`, or an "Unsaved changes" modal —
they're centralized. See the "Save / Discard + unsaved-changes guard" section
in `.claude/rules/sim-settings-pages.md`.
5. **Verify:** `cd apps/sim && bunx tsc --noEmit`; `bunx biome check --write <file>`.
5. **Verify:** `cd apps/sim && bun run type-check`; `bunx biome check --write <file>`.

## Mode B — Audit existing settings pages

Expand DownExpand Up@@ -76,7 +76,7 @@ For each page component, confirm the checklist in `.claude/rules/sim-settings-pa
unless they're also being changed for an unrelated, deliberate reason.
7. Remove now-unused imports (`ChipInput`/`Search`) ONLY after grepping that
they are not still used elsewhere in the file (e.g. by a detail view).
8. **Verify the whole sweep:** `tsc --noEmit`, `biome check` on every touched
8. **Verify the whole sweep:** `bun run type-check`, `biome check` on every touched
file, and run the affected pages' tests. Diff each file against the base and
confirm the change is purely structural before shipping.

Expand DownExpand Up@@ -105,5 +105,5 @@ contract. Then, per page:
7. Check what the old row rendered *beside* the title (a badge, a timestamp, a
transport label). The row's title truncates as one unit, so anything folded
into it can be ellipsised away — move it to `description` or `badge`.
8. Verify: `tsc --noEmit`, `biome check`, the page's tests, and a diff read of
8. Verify: `bun run type-check`, `biome check`, the page's tests, and a diff read of
every converted block for lost props, conditions, and `key` placement.
4 changes: 2 additions & 2 deletions .cursor/commands/add-column-type.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@ This was not always true: adding `currency` originally took ~40 edits across 32
Do **not** hunt for places to edit. Add your type to the `ColumnType` union first and let `tsc` produce the list:

```bash
cd apps/sim && bunx tsc --noEmit -p tsconfig.json
cd apps/sim && bun run type-check
```

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

## Final Validation (Required)

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.
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.
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.
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.
4. **`bun run lint:check`, `bun run check:api-validation`, `bun run check:client-boundary`** from the repo root.
Expand Down
2 changes: 1 addition & 1 deletion .cursor/commands/add-enrichment.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -122,7 +122,7 @@ export const ENRICHMENT_REGISTRY: EnrichmentRegistry = {

## Step 5: Verify

1. `bunx tsc --noEmit` (from `apps/sim`, `NODE_OPTIONS=--max-old-space-size=8192`) and `bunx biome check` on the changed files.
1. `bun run type-check` (from `apps/sim`) and `bunx biome check` on the changed files.
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.
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.

Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/test-build.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -192,6 +192,12 @@ jobs:
fi
bun run check:migrations "$BASE_REF"

# Runs before the type-check itself: if a bare `tsc` has fallen back to the
# JavaScript TypeScript 6 compiler that `@typescript/typescript6` drags in
# transitively, the type-check below still passes — it just takes ~10x longer.
- name: Native type-check audit
run: bun run check:native-typecheck

# Every workspace, not just realtime. packages/emcn, packages/utils,
# apps/desktop and apps/docs had no type check in CI at all; apps/sim's
# source was covered only as a side effect of `next build` in the separate
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,7 @@ You are a professional software engineer. All code must follow best practices: a
- `truncate(str, maxLength, suffix?)` from `@sim/utils/string` — never inline slice + ellipsis
- `backoffWithJitter(attempt, retryAfterMs, options?)` / `parseRetryAfter(header)` from `@sim/utils/retry` — shared retry pacing; never reimplement exponential backoff inline
- **Package Manager**: Use `bun` and `bunx`, not `npm` and `npx`
- **Type-checking**: Run `bun run type-check` (per workspace) or `bunx turbo run type-check` (all of them). Do not remove the `@typescript/native` alias from the root `devDependencies` — nothing imports it, but it is what makes a bare `tsc` resolve to the native TypeScript 7 compiler instead of the ~10x slower JavaScript TypeScript 6 one that `@typescript/typescript6` pulls in transitively. `bun run check:native-typecheck` enforces this

## Architecture

Expand Down
2 changes: 1 addition & 1 deletion apps/sim/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,7 +25,7 @@
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"email:dev": "email dev --dir components/emails",
"type-check": "NODE_OPTIONS='--max-old-space-size=8192' tsc --noEmit",
"type-check": "tsc --noEmit",
"lint": "biome check --write --unsafe .",
"lint:check": "biome check .",
"format": "biome format --write .",
Expand Down
3 changes: 3 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -43,6 +43,7 @@
"check:bare-icons": "bun run scripts/check-bare-icons.ts",
"check:icon-paths": "bun run scripts/check-icon-paths.ts",
"check:migrations": "bun run scripts/check-migrations-safety.ts",
"check:native-typecheck": "bun run scripts/check-native-typecheck.ts",
"check:desktop-bridge": "bun run scripts/check-desktop-bridge-contract.ts --check",
"check:desktop-ipc": "bun run scripts/check-desktop-ipc-contract.ts",
"desktop-bridge-contract:update": "bun run scripts/check-desktop-bridge-contract.ts --update",
Expand DownExpand Up@@ -106,6 +107,7 @@
"@clack/prompts": "1.7.0",
"@octokit/rest": "^21.0.0",
"@types/opentype.js": "1.3.10",
"@typescript/native": "npm:typescript@^7.0.2",
"@vercel/og": "0.6.8",
"chalk": "5.6.2",
"glob": "13.0.0",
Expand Down
39 changes: 39 additions & 0 deletions scripts/check-native-typecheck.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bun
/**
* Asserts that a bare `tsc` runs the native (Go) TypeScript 7 compiler.
*
* `apps/sim` needs `@typescript/typescript6` for its runtime TypeScript API, and that
* package depends on `@typescript/old` — an alias of `typescript@6` — which declares its
* own `tsc` bin. Package managers pick bin winners by lexical sort rather than dependency
* depth, so `@typescript/old` beats `typescript` and `node_modules/.bin/tsc` silently
* becomes the JavaScript TypeScript 6 compiler: identical diagnostics, ~10x slower.
*
* The root `@typescript/native` alias exists purely to win that sort. Nothing imports it —
* deleting it costs every `tsc` invocation in the repo an order of magnitude, with no
* visible failure. This audit is what makes that regression loud.
*
* @see https://github.com/microsoft/typescript-go/issues/4567
*/
import { spawnSync } from 'node:child_process'
import path from 'node:path'

const ROOT = path.resolve(import.meta.dir, '..')
const BIN_TSC = path.join(ROOT, 'node_modules', '.bin', 'tsc')

const result = spawnSync(BIN_TSC, ['--version'], { encoding: 'utf8' })
const reported = result.stdout?.trim() ?? ''

if (!/^Version 7\./.test(reported)) {
const detail = reported || result.stderr?.trim() || `exit ${result.status}`
console.error('Native type-check audit failed:\n')
console.error(` node_modules/.bin/tsc reports "${detail}", expected TypeScript 7.x (native).`)
console.error(
'\n A bare `tsc` has fallen back to the JavaScript TypeScript 6 compiler that\n' +
' `@typescript/typescript6` pulls in transitively — same diagnostics, ~10x slower.\n' +
' Check that the `@typescript/native` alias is still in the root devDependencies,\n' +
' and that no newly added package sorts ahead of it while declaring a `tsc` bin.'
)
process.exit(1)
}

console.log(`Native type-check audit passed (bare \`tsc\` is ${reported}).`)
Loading