Skip to content

Commit 75d5a50

Browse files
committed
Merge remote-tracking branch 'origin/staging' into chore/sync-dev-with-staging-2026-10-23
2 parents de585d0 + 5b85be3 commit 75d5a50

309 files changed

Lines changed: 15159 additions & 3922 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-sandbox.md‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
description: Isolated-vm sandbox worker security policy. Hard rules for anything that lives in the worker child process that runs user code.
33
paths:
44
- "apps/sim/lib/execution/isolated-vm-worker.cjs"
5+
- "apps/sim/lib/execution/isolated-vm-host.cjs"
6+
- "apps/sim/lib/execution/isolated-vm-remote.ts"
57
- "apps/sim/lib/execution/isolated-vm.ts"
68
- "apps/sim/lib/execution/sandbox/**"
79
- "apps/sim/sandboxes/**"
@@ -75,7 +77,31 @@ payload or `ivm.Reference` wrapper in the worker:
7577
- [ ] Does the worker read a new env var? Add it to the `buildWorkerEnv()`
7678
allowlist in `isolated-vm.ts` **and** to the allowlist regression test in
7779
`isolated-vm.test.ts` — the worker does not inherit the app environment,
78-
so an un-allowlisted var is simply absent in the child.
80+
so an un-allowlisted var is simply absent in the child. If the app owns
81+
its value, put it in `appWorkerEnv()` and add it with its accepted shape
82+
to `CLIENT_WORKER_ENV` in `isolated-vm-host.cjs`, so a remote worker
83+
gets the same value.
84+
- [ ] Does the host send the worker a new message type? Add it to
85+
`ALLOWED_INBOUND_TYPES` in `isolated-vm-host.cjs`, or remote workers
86+
never receive it.
87+
88+
## Where the worker runs
89+
90+
The pool in `isolated-vm.ts` opens each worker either as a local child process
91+
or, when `IVM_REMOTE_WORKER_URL` is set (with `IVM_REMOTE_WORKER_TOKEN`; a URL
92+
without a valid token fails executions rather than falling back) and the
93+
`isolated-vm-local-workers` kill switch is off, as a WebSocket connection to
94+
`isolated-vm-host.cjs`, which runs the
95+
same worker in a dedicated service that holds no platform credentials. Every
96+
rule in this file applies in both modes.
97+
98+
- `fetch()` and brokers always run in the app. The host only relays the
99+
worker's messages, so it needs no network access of its own and never gets
100+
a broker implementation.
101+
- A remote target never falls back to a local child process. An unreachable
102+
host fails executions with a system error; keep it that way.
103+
- Changes to the worker message protocol must stay compatible with the
104+
previous release: the host and its clients roll out independently.
79105

80106
## What the worker *may* hold
81107

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
description: "Isolated-vm sandbox worker security policy. Hard rules for anything that lives in the worker child process that runs user code."
3-
globs: ["apps/sim/lib/execution/isolated-vm-worker.cjs","apps/sim/lib/execution/isolated-vm.ts","apps/sim/lib/execution/sandbox/**","apps/sim/sandboxes/**"]
3+
globs: ["apps/sim/lib/execution/isolated-vm-worker.cjs","apps/sim/lib/execution/isolated-vm-host.cjs","apps/sim/lib/execution/isolated-vm-remote.ts","apps/sim/lib/execution/isolated-vm.ts","apps/sim/lib/execution/sandbox/**","apps/sim/sandboxes/**"]
44
---
55

66
<!-- Generated from .claude/rules/sim-sandbox.md by `bun run skills:sync`. Edit the source, not this file. -->
@@ -73,7 +73,31 @@ payload or `ivm.Reference` wrapper in the worker:
7373
- [ ] Does the worker read a new env var? Add it to the `buildWorkerEnv()`
7474
allowlist in `isolated-vm.ts` **and** to the allowlist regression test in
7575
`isolated-vm.test.ts` — the worker does not inherit the app environment,
76-
so an un-allowlisted var is simply absent in the child.
76+
so an un-allowlisted var is simply absent in the child. If the app owns
77+
its value, put it in `appWorkerEnv()` and add it with its accepted shape
78+
to `CLIENT_WORKER_ENV` in `isolated-vm-host.cjs`, so a remote worker
79+
gets the same value.
80+
- [ ] Does the host send the worker a new message type? Add it to
81+
`ALLOWED_INBOUND_TYPES` in `isolated-vm-host.cjs`, or remote workers
82+
never receive it.
83+
84+
## Where the worker runs
85+
86+
The pool in `isolated-vm.ts` opens each worker either as a local child process
87+
or, when `IVM_REMOTE_WORKER_URL` is set (with `IVM_REMOTE_WORKER_TOKEN`; a URL
88+
without a valid token fails executions rather than falling back) and the
89+
`isolated-vm-local-workers` kill switch is off, as a WebSocket connection to
90+
`isolated-vm-host.cjs`, which runs the
91+
same worker in a dedicated service that holds no platform credentials. Every
92+
rule in this file applies in both modes.
93+
94+
- `fetch()` and brokers always run in the app. The host only relays the
95+
worker's messages, so it needs no network access of its own and never gets
96+
a broker implementation.
97+
- A remote target never falls back to a local child process. An unreachable
98+
host fails executions with a system error; keep it that way.
99+
- Changes to the worker message protocol must stay compatible with the
100+
previous release: the host and its clients roll out independently.
77101

78102
## What the worker *may* hold
79103

‎.github/actions/setup/action.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ runs:
3535
- name: Setup Bun
3636
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
3737
with:
38-
bun-version: 1.4.2
38+
bun-version: 1.4.4
3939

4040
- name: Setup Node
4141
if: inputs.node-version != ''

‎.github/scripts/wait-for-ecs-cutover.sh‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,15 @@ while [ -z "$DEPLOYMENT_ID" ] || [ "$DEPLOYMENT_ID" = 'None' ]; do
9292
DEPLOYMENT_ID=$(printf '%s\n' "$deploy_actions" | DEPLOY_STATE="$deploy_state" EXECUTION_ID="$EXECUTION_ID" python3 -c '
9393
import json, os, re, sys
9494
state = json.loads(os.environ["DEPLOY_STATE"])
95-
actions = json.load(sys.stdin)
95+
# The Deploy stage can also run sidecar actions (e.g. a CodeBuild image deploy); only the
96+
# CodeDeploy blue/green action carries the ECS cutover.
97+
actions = [a for a in json.load(sys.stdin)
98+
if a.get("input", {}).get("actionTypeId", {}).get("provider") == "CodeDeployToECS"]
9699
if not state or state.get("latestExecution", {}).get("pipelineExecutionId") != os.environ["EXECUTION_ID"] or not actions:
97100
print("")
98101
sys.exit(0)
99102
if len({a["actionName"] for a in actions}) != 1:
100-
raise SystemExit("ERROR: expected one Deploy action in the app pipeline")
103+
raise SystemExit("ERROR: expected one CodeDeploy ECS action in the app pipeline Deploy stage")
101104
latest = max(actions, key=lambda a: a["startTime"])
102105
matches = [a["latestExecution"] for a in state.get("actionStates", [])
103106
if a["actionName"] == latest["actionName"]

‎.github/workflows/checks.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ jobs:
4545
- name: Setup Bun
4646
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
4747
with:
48-
bun-version: 1.4.2
48+
bun-version: 1.4.4
4949
- name: Install only the pinned task planner
5050
continue-on-error: true
5151
run: bun install --global "turbo@$(jq -r .devDependencies.turbo package.json)"

‎.github/workflows/ci.yml‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,9 @@ jobs:
569569
needs.promote.result == 'success' &&
570570
needs.trigger-upload.result == 'success' &&
571571
needs.promote.outputs.promoted == 'true'
572+
outputs:
573+
# The new app serves traffic; indexnow keys off this, not the later Trigger.dev promotion.
574+
cutover: ${{ steps.cutover.outcome }}
572575
# Mostly waiting on the ECS cutover after a dependency install: the smallest runner is enough.
573576
runs-on: *runner-2vcpu
574577
# Leave setup/promotion headroom above the 70-minute cutover poll.
@@ -596,6 +599,7 @@ jobs:
596599
# An unchanged tag may belong to a failed or still-running earlier deploy.
597600
# Verify its latest cutover rather than treating tag equality as success.
598601
- name: Wait for ECS traffic cutover
602+
id: cutover
599603
env:
600604
OVERALL_TIMEOUT: 4200
601605
APP_IMAGE_CHANGED: ${{ needs.promote.outputs.app_image_changed }}
@@ -636,6 +640,64 @@ jobs:
636640
fi
637641
bunx trigger.dev@4.5.16 promote "$VERSION" "${TARGET_ARGS[@]}"
638642
643+
# Production only, once the new app serves traffic: submit the library and comparison URLs this
644+
# push changed to IndexNow. Best effort: nothing depends on it, and a failure never fails the run.
645+
indexnow:
646+
name: indexnow
647+
needs: [promote, trigger-promote]
648+
if: >-
649+
!cancelled() &&
650+
github.event_name == 'push' &&
651+
github.ref == 'refs/heads/main' &&
652+
needs.promote.outputs.promoted == 'true' &&
653+
needs.trigger-promote.outputs.cutover == 'success'
654+
runs-on: *runner-2vcpu
655+
timeout-minutes: 5
656+
continue-on-error: true
657+
permissions:
658+
contents: read
659+
actions: read
660+
checks: read
661+
steps:
662+
- name: Checkout code
663+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6
664+
665+
- name: Setup Bun
666+
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
667+
with:
668+
bun-version: 1.4.4
669+
670+
# Diff from the last earlier main commit whose `indexnow` check succeeded, not the previous
671+
# push: a push that never deployed, or whose submission failed, would otherwise drop its
672+
# changed URLs for good. The check-runs lookup asks for this one check per commit, so it
673+
# stays small and counts every attempt of a re-run; a lookup that errors counts as no
674+
# success. With no success in view, the base is the oldest run in view, so URLs that no
675+
# submission ever covered are sent now. The diff needs only the two trees, so that one
676+
# commit is fetched alone; an all-zero `before` (the branch's first push) has no base,
677+
# which the script skips.
678+
- name: Submit changed URLs to IndexNow
679+
env:
680+
GH_TOKEN: ${{ github.token }}
681+
PUSH_BEFORE: ${{ github.event.before }}
682+
run: |
683+
BASE_SHA=""
684+
OLDEST_SHA=""
685+
while read -r head_sha; do
686+
OLDEST_SHA="$head_sha"
687+
if succeeded="$(gh api "repos/$GITHUB_REPOSITORY/commits/$head_sha/check-runs?check_name=indexnow&filter=all" \
688+
--jq '[.check_runs[] | select(.conclusion == "success")] | length')" && [[ "$succeeded" -gt 0 ]]; then
689+
BASE_SHA="$head_sha"
690+
break
691+
fi
692+
done < <(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/ci.yml/runs?branch=main&event=push&per_page=30" \
693+
--jq ".workflow_runs[] | select(.id < $GITHUB_RUN_ID) | .head_sha")
694+
BASE_SHA="${BASE_SHA:-${OLDEST_SHA:-$PUSH_BEFORE}}"
695+
echo "Submitting URLs changed in $BASE_SHA..$GITHUB_SHA"
696+
if [[ ! "$BASE_SHA" =~ ^0+$ ]]; then
697+
git fetch --no-tags --depth=1 origin "$BASE_SHA"
698+
fi
699+
bun scripts/ping-indexnow.ts "$BASE_SHA" "$GITHUB_SHA"
700+
639701
# Build ARM64 images for GHCR (main branch only, runs in parallel with
640702
# tests). Pushes only the immutable sha tag — latest-arm64/version-arm64
641703
# are applied by ghcr after the gate, so a failing run

‎.github/workflows/desktop-e2e.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ jobs:
7979
- name: Setup Bun
8080
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
8181
with:
82-
bun-version: 1.4.2
82+
bun-version: 1.4.4
8383

8484
# Electron, electron-builder and Playwright download their binaries on every cold install. All
8585
# three caches are keyed by version inside, so an older entry restored by prefix is harmless.
@@ -151,7 +151,7 @@ jobs:
151151
- name: Setup Bun
152152
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
153153
with:
154-
bun-version: 1.4.2
154+
bun-version: 1.4.4
155155

156156
# Electron, electron-builder and Playwright download their binaries on every cold install. All
157157
# three caches are keyed by version inside, so an older entry restored by prefix is harmless.
@@ -213,7 +213,7 @@ jobs:
213213
- name: Setup Bun
214214
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
215215
with:
216-
bun-version: 1.4.2
216+
bun-version: 1.4.4
217217

218218
- name: Setup Node
219219
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6

‎.github/workflows/desktop-release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ jobs:
143143
- name: Setup Bun
144144
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
145145
with:
146-
bun-version: 1.4.2
146+
bun-version: 1.4.4
147147

148148
- name: Setup Node
149149
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6

‎.github/workflows/helm.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ jobs:
6262
- name: Setup Bun
6363
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
6464
with:
65-
bun-version: 1.4.2
65+
bun-version: 1.4.4
6666

6767
# Docker Compose and Kubernetes must run the same background jobs on the
6868
# same schedules; this fails the build if the two drift apart. The script
@@ -286,7 +286,7 @@ jobs:
286286
- name: Setup Bun
287287
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
288288
with:
289-
bun-version: 1.4.2
289+
bun-version: 1.4.4
290290

291291
# Derives appVersion rather than checking it, so the published chart cannot
292292
# be pinned to an older Sim than the release it ships with. The committed
@@ -481,7 +481,7 @@ jobs:
481481
- name: Setup Bun
482482
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
483483
with:
484-
bun-version: 1.4.2
484+
bun-version: 1.4.4
485485

486486
# Derives appVersion rather than checking it, so the published chart cannot
487487
# be pinned to an older Sim than the release it ships with. The committed

‎apps/desktop/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"type": "module",
1010
"main": "dist/main.cjs",
1111
"engines": {
12-
"bun": ">=1.4.2",
12+
"bun": ">=1.4.4",
1313
"node": ">=20.0.0"
1414
},
1515
"scripts": {

0 commit comments

Comments
 (0)