Skip to content

Commit 5b4b904

Browse files
committed
Merge remote-tracking branch 'origin/staging' into codex/shared-resource-lifecycle
2 parents fb298fb + 824b5d3 commit 5b4b904

120 files changed

Lines changed: 38822 additions & 5213 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.

‎.claude/rules/sim-testing.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ contracts, and demonstrated regressions.
4848
those checks. Isolate with a unique schema or generated IDs, and clean up in `afterAll`.
4949
- Integration files run one at a time against one shared database. A new `*.integration.ts` is
5050
picked up by CI with no workflow change, and the run writes the JSON report configured in
51-
`vitest.shared.ts`, which CI uploads. Never add a passing suite to the quarantine list in
52-
`apps/sim/vitest.config.ts`.
51+
`vitest.shared.ts`, which CI uploads. Never exclude a failing suite from the run in
52+
`apps/sim/vitest.config.ts`: fix it or delete it.
5353
- `bun run test:integration` starts disposable Postgres and Redis containers, provisions the schema,
5454
and runs both workspaces; pass filenames to narrow the `apps/sim` run.
5555

@@ -169,6 +169,7 @@ The suite's wall time is bound by the single Vite server thread that serves ever
169169
3. Mock heavy graphs a test does not need and the setup does not already mock: `@/blocks`,
170170
`@/triggers/registry`, `@/tools/generated/*`.
171171
4. No real timers: `vi.useFakeTimers()`, `flushMicrotasks()`, or `flushMacrotask()`.
172+
`check:test-patterns` (`real-wait`) fails on a new wall-clock wait in a unit test.
172173
5. Absolute imports only.
173174

174175
### Running

‎.cursor/rules/sim-testing.mdc‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ contracts, and demonstrated regressions.
4646
those checks. Isolate with a unique schema or generated IDs, and clean up in `afterAll`.
4747
- Integration files run one at a time against one shared database. A new `*.integration.ts` is
4848
picked up by CI with no workflow change, and the run writes the JSON report configured in
49-
`vitest.shared.ts`, which CI uploads. Never add a passing suite to the quarantine list in
50-
`apps/sim/vitest.config.ts`.
49+
`vitest.shared.ts`, which CI uploads. Never exclude a failing suite from the run in
50+
`apps/sim/vitest.config.ts`: fix it or delete it.
5151
- `bun run test:integration` starts disposable Postgres and Redis containers, provisions the schema,
5252
and runs both workspaces; pass filenames to narrow the `apps/sim` run.
5353

@@ -167,6 +167,7 @@ The suite's wall time is bound by the single Vite server thread that serves ever
167167
3. Mock heavy graphs a test does not need and the setup does not already mock: `@/blocks`,
168168
`@/triggers/registry`, `@/tools/generated/*`.
169169
4. No real timers: `vi.useFakeTimers()`, `flushMicrotasks()`, or `flushMacrotask()`.
170+
`check:test-patterns` (`real-wait`) fails on a new wall-clock wait in a unit test.
170171
5. Absolute imports only.
171172

172173
### Running

‎.github/scripts/check-project-rollout.py‎

Lines changed: 0 additions & 100 deletions
This file was deleted.

‎.github/scripts/ci-changes.sh‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
# diff sets all of them.
77
#
88
# full integration, e2e, e2e-build, e2e-mobile: any file not allowlisted below
9-
# test the Vitest shards: content, docs app, and desktop changes, plus `full`
9+
# test the Vitest shards and test-types: content, docs app, and desktop changes,
10+
# plus `full`
1011
# build the app's `next build`: content changes, plus `full`
1112
# desktop_live the live Electron suite: any file outside its own skip list
1213
#

‎.github/scripts/ci-gate.sh‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# A skip passes only for a gated job whose `changes` flag is exactly `false`:
77
#
88
# integration, e2e, e2e-build, e2e-mobile full
9-
# test test
9+
# test, test-types test
1010
# build build
1111
# desktop-live desktop_live
1212
#
@@ -25,7 +25,7 @@ fi
2525

2626
failed="$(jq -r '
2727
{"integration": "full", "e2e": "full", "e2e-build": "full", "e2e-mobile": "full", "test": "test",
28-
"build": "build", "desktop-live": "desktop_live"} as $gate
28+
"test-types": "test", "build": "build", "desktop-live": "desktop_live"} as $gate
2929
| (.changes.outputs // {}) as $flags
3030
| to_entries[]
3131
| select(.value.result != "success")

‎.github/workflows/checks.yml‎

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,9 +653,9 @@ jobs:
653653
# Every workspace, not just realtime. packages/emcn, packages/utils,
654654
# apps/desktop and apps/docs had no type check in CI at all; apps/sim's
655655
# source was covered only as a side effect of `next build` in the separate
656-
# `build` job. Note this does NOT cover apps/sim's tests — its tsconfig
657-
# excludes *.test.ts(x), and including them today surfaces ~2.2k errors,
658-
# so that is its own cleanup rather than a gate to switch on here.
656+
# `build` job. This does NOT cover apps/sim's tests — its tsconfig
657+
# excludes *.test.ts(x), which carry ~2.2k errors; the `test-types` job
658+
# ratchets those per file instead.
659659
- name: Type-check all workspaces
660660
run: bunx turbo run type-check
661661

@@ -672,6 +672,41 @@ jobs:
672672
fi
673673
echo "✅ Schema and migrations are in sync"
674674
675+
# Type errors in apps/sim's unit tests, ratcheted per file and TS code against a committed
676+
# baseline (scripts/check-test-types.ts). It type-checks the whole app with its ~3.4k test files:
677+
# lint's uncached apps/sim type-check alone takes ~35 s on this runner, so it gets its own job
678+
# beside lint rather than a place in check:audits, which also runs on laptops. Gated like `test`.
679+
# On failure the compiler output and its exit status are uploaded, so a fix can shrink the
680+
# existing baseline from them (`--diagnostics <file> --update`) without a local compile; nothing
681+
# ever raises the baseline.
682+
test-types:
683+
name: test-types
684+
needs: changes
685+
if: needs.changes.outputs.test == 'true'
686+
runs-on: *runner-4vcpu
687+
timeout-minutes: 10
688+
689+
steps:
690+
- *checkout-mirror
691+
- *checkout-plain
692+
693+
- name: Setup workspace
694+
uses: ./.github/actions/setup
695+
with:
696+
provider: ${{ vars.CI_PROVIDER }}
697+
698+
- name: Ratchet type errors in apps/sim tests
699+
run: bun run scripts/check-test-types.ts --report "$RUNNER_TEMP/test-types"
700+
701+
- name: Upload compiler output and counts
702+
if: failure()
703+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
704+
with:
705+
name: test-types
706+
path: ${{ runner.temp }}/test-types/
707+
if-no-files-found: ignore
708+
retention-days: 14
709+
675710
# The root scripts and every workspace's Vitest suite (`bun run test`), split in two. apps/sim is
676711
# about 98% of the time, so only its files are sharded; shard 1 also runs the root scripts and
677712
# the other workspaces. Each shard keeps its own Turbo cache: pass-through args are part of the
@@ -876,7 +911,8 @@ jobs:
876911
# on a cancelled run would report a cancelled head commit as passing.
877912
ci:
878913
name: ci
879-
needs: [changes, integration, e2e, e2e-mobile, desktop-live, lint, test, build, e2e-build]
914+
needs:
915+
[changes, integration, e2e, e2e-mobile, desktop-live, lint, test-types, test, build, e2e-build]
880916
if: ${{ always() }}
881917
runs-on: *runner-2vcpu
882918
timeout-minutes: 5

‎.github/workflows/ci.yml‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ jobs:
114114
migrate:
115115
permissions:
116116
contents: read
117-
id-token: write
118117
name: migrate
119118
needs: [checks]
120119
# Explicit need results instead of the implicit success(): a skipped job
@@ -134,10 +133,6 @@ jobs:
134133
STAGING_DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
135134
MIGRATION_DATABASE_URL: ${{ secrets.MIGRATION_DATABASE_URL }}
136135
STAGING_MIGRATION_DATABASE_URL: ${{ secrets.STAGING_MIGRATION_DATABASE_URL }}
137-
AWS_ROLE_TO_ASSUME: ${{ secrets.AWS_ROLE_TO_ASSUME }}
138-
STAGING_AWS_ROLE_TO_ASSUME: ${{ secrets.STAGING_AWS_ROLE_TO_ASSUME }}
139-
AWS_REGION: ${{ secrets.AWS_REGION }}
140-
STAGING_AWS_REGION: ${{ secrets.STAGING_AWS_REGION }}
141136

142137
# Same ordering for dev (schema push before the dev image lands in ECR)
143138
migrate-dev:

‎.github/workflows/migrate.yml‎

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ on:
1818
required: false
1919
STAGING_MIGRATION_DATABASE_URL:
2020
required: false
21-
AWS_ROLE_TO_ASSUME:
22-
required: false
23-
STAGING_AWS_ROLE_TO_ASSUME:
24-
required: false
25-
AWS_REGION:
26-
required: false
27-
STAGING_AWS_REGION:
28-
required: false
2921
workflow_dispatch:
3022
inputs:
3123
environment:
@@ -39,7 +31,6 @@ on:
3931

4032
permissions:
4133
contents: read
42-
id-token: write
4334

4435
jobs:
4536
migrate:
@@ -60,32 +51,13 @@ jobs:
6051
provider: ${{ vars.CI_PROVIDER }}
6152
node-version: ''
6253

63-
- name: Check Project column expansion and whether enforcement needs rollout evidence
64-
id: project-contract
54+
- name: Validate Project migration database prerequisites
6555
if: inputs.environment != 'dev'
6656
working-directory: ./packages/db
6757
env:
6858
DATABASE_URL: ${{ inputs.environment == 'production' && secrets.DATABASE_URL || inputs.environment == 'staging' && secrets.STAGING_DATABASE_URL || '' }}
6959
MIGRATION_DATABASE_URL: ${{ inputs.environment == 'production' && secrets.MIGRATION_DATABASE_URL || inputs.environment == 'staging' && secrets.STAGING_MIGRATION_DATABASE_URL || '' }}
70-
run: bun --no-env-file scripts/project-contract-required.ts >> "$GITHUB_OUTPUT"
71-
72-
- name: Configure AWS for Project connector retirement verification
73-
if: steps.project-contract.outputs.required == 'true'
74-
uses: aws-actions/configure-aws-credentials@e7f100cf4c008499ea8adda475de1042d6975c7b
75-
with:
76-
role-to-assume: ${{ inputs.environment == 'production' && secrets.AWS_ROLE_TO_ASSUME || secrets.STAGING_AWS_ROLE_TO_ASSUME }}
77-
aws-region: ${{ inputs.environment == 'production' && secrets.AWS_REGION || secrets.STAGING_AWS_REGION }}
78-
79-
# Acknowledge #8830 only after authority-aware readers/writers deploy and all incompatible
80-
# servers and relevant old Trigger.dev runs drain. The runner commits the column-authority
81-
# switch before backfill, validation, and connector retirement; retries never revert it.
82-
# The preflight independently checks ECS retirement; it does not inspect worker runs.
83-
- name: Require completed authority-aware rollout before Project cutover
84-
if: steps.project-contract.outputs.required == 'true'
85-
env:
86-
ENVIRONMENT: ${{ inputs.environment }}
87-
EXPECTED_IMAGE_DIGEST: ${{ inputs.environment == 'production' && vars.PROJECT_COLUMN_ENFORCEMENT_READY_IMAGE_DIGEST_PRODUCTION || inputs.environment == 'staging' && vars.PROJECT_COLUMN_ENFORCEMENT_READY_IMAGE_DIGEST_STAGING || '' }}
88-
run: python3 .github/scripts/check-project-rollout.py --environment "$ENVIRONMENT" --region "$AWS_REGION" --expected-image-digest "$EXPECTED_IMAGE_DIGEST"
60+
run: bun --no-env-file scripts/project-contract-required.ts
8961

9062
# The expression maps the explicit environment input to exactly one repo
9163
# secret, so the job never holds another environment's database URL. An

‎CLAUDE.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ This file (also `AGENTS.md`) holds the repo-wide rules. Area detail lives in `.c
2222
- `compareStrings(left, right)` from `@sim/utils/string` — code-unit ordering for hashes, fingerprints, and cross-process comparisons; never `localeCompare` there
2323
- `backoffWithJitter(attempt, retryAfterMs, options?)` / `parseRetryAfter(header)` from `@sim/utils/retry` — never reimplement exponential backoff inline
2424
- **Deployment flags in the browser**: client code inside a workspace, organization, or standalone settings surface reads `hosted`, `billingEnabled`, `chatEnabled`, and the enterprise feature set through `useDeploymentShape()` (components) or `getDeploymentShape()` (block conditions, stores, helpers) from `@/lib/core/config/deployment-shape`, never `isHosted`/`isBillingEnabled`/... from `env-flags`. Those constants freeze at module init from the root layout's `NEXT_PUBLIC_*` transport, which Next's bare 404 shell and `global-error` never emit, so a recovered tab would render Sim Cloud as self-hosted; the reader is seeded from the server-resolved workspace host context, organization layout, or standalone settings layout instead. Server code keeps reading `env-flags`.
25-
- **Type-checking**: `bun run type-check` at the root checks every workspace (`bun run type-check` inside a workspace checks just that one). `apps/sim`'s tsconfig excludes `*.test.ts(x)`, so its tests are not type-checked. Never remove the `@typescript/native` alias from the root `devDependencies`: nothing imports it, but without it a bare `tsc` resolves to the ~10x slower TypeScript 6 compiler. `bun run check:native-typecheck` enforces this; its header explains the bin-resolution trap.
25+
- **Type-checking**: `bun run type-check` at the root checks every workspace (`bun run type-check` inside a workspace checks just that one). `apps/sim`'s tsconfig excludes `*.test.ts(x)`, so `type-check` skips its tests; CI's `test-types` job ratchets their errors per file and TS code instead (`check:test-types`, whose header says how to fix a finding): a test file may not gain one. Never remove the `@typescript/native` alias from the root `devDependencies`: nothing imports it, but without it a bare `tsc` resolves to the ~10x slower TypeScript 6 compiler. `bun run check:native-typecheck` enforces this; its header explains the bin-resolution trap.
2626

2727
## Architecture
2828

‎apps/desktop/e2e/chat-panel.spec.ts‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,22 +289,20 @@ test('chat panel sizes survive navigation, chat switches, collapse, and layout c
289289
}
290290

291291
await check('a viewport change during a drag clamps the committed display width', async () => {
292-
await page.getByRole('button', { name: 'Resize container' }).click()
293-
await expectWidth(520)
292+
await expectWidth(698)
294293
const rect = await beginDrag()
295294
await page.mouse.move(rect.x + 20, rect.y + 100, { steps: 12 })
296-
await expectWidth(500)
295+
await expectWidth(678)
297296
await shell.evaluate(({ BrowserWindow }) =>
298-
BrowserWindow.getAllWindows()[0].setContentSize(300, 400)
297+
BrowserWindow.getAllWindows()[0].setContentSize(500, 400)
299298
)
300-
await expect.poll(() => page.evaluate(() => window.innerWidth)).toBe(600)
299+
await expect.poll(() => page.evaluate(() => window.innerWidth)).toBe(1000)
301300
await page.mouse.up()
302-
await expectWidth(480)
301+
await expectWidth(520)
303302
await shell.evaluate(({ BrowserWindow }) =>
304303
BrowserWindow.getAllWindows()[0].setContentSize(720, 400)
305304
)
306-
await expectWidth(500)
307-
await page.getByRole('button', { name: 'Resize container' }).click()
305+
await expectWidth(678)
308306
await dragTo(698)
309307
})
310308

0 commit comments

Comments
 (0)