Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
bec4639
feat(mothership): run scheduled jobs as durable unattended chat turns…
waleedlatif1 Oct 23, 2026
f9d3c62
docs(library): update best-ai-agents-support-ticket-triage (#9337)
waleedlatif1 Oct 23, 2026
5b69c9a
docs(library): update dify-alternatives (#9336)
waleedlatif1 Oct 23, 2026
9482fb3
docs(library): update how-to-create-an-ai-agent (#9335)
waleedlatif1 Oct 23, 2026
9ac12a2
fix(workflow-tests): keep the error of a mock that throws (#9333)
waleedlatif1 Oct 23, 2026
0b1155f
docs(library): update ai-agent-examples-by-department-and-industry (#…
waleedlatif1 Oct 23, 2026
75e7a8a
chore(deps): upgrade Bun to 1.4.4 (#9338)
waleedlatif1 Oct 23, 2026
0f755fe
fix(models): mark OpenAI gpt-4.1-nano deprecated (#9340)
waleedlatif1 Oct 23, 2026
4d26987
fix(mcp): classify unresolvable and egress-refused server URLs in dis…
waleedlatif1 Oct 23, 2026
63ca24f
fix(gmail): drop an expired history cursor instead of re-saving it ev…
waleedlatif1 Oct 23, 2026
e5ad3ae
fix(logs): keep provenance sidecars intact through log PII redaction …
waleedlatif1 Oct 23, 2026
7d1b047
fix(workflows): accept json input type and return 400 for unsupported…
waleedlatif1 Oct 23, 2026
2fc2008
fix(mothership): close the scheduled-job review gaps (#9345)
waleedlatif1 Oct 23, 2026
42f3409
fix(db): isolate billing and auth connection pools, release the redep…
waleedlatif1 Oct 23, 2026
60f7996
fix(logs): stop loading execution data and snapshots that reads do no…
waleedlatif1 Oct 23, 2026
1a69d2a
fix(workflows): accept legacy input field types instead of rejecting …
waleedlatif1 Oct 23, 2026
d76f2cd
improvement(execution): run sandbox workers on a dedicated worker hos…
waleedlatif1 Oct 23, 2026
772fcf7
fix(egress): retry a gateway CONNECT once on connection failure and l…
waleedlatif1 Oct 23, 2026
b9e6ffb
improvement(auth): encrypt stored integration tokens (#9346)
waleedlatif1 Oct 23, 2026
fe743ef
docs(library): update what-is-an-mcp-server (#9352)
waleedlatif1 Oct 23, 2026
0a6f8f9
docs(library): update best-ai-automation-tools-2026 (#9353)
waleedlatif1 Oct 23, 2026
546a378
docs(library): update top-ai-assistants-2026 (#9356)
waleedlatif1 Oct 23, 2026
7f3a075
docs(library): update langgraph-alternatives (#9357)
waleedlatif1 Oct 23, 2026
4df5d85
improvement(library): rank related posts by tag rarity, add backlinks…
waleedlatif1 Oct 23, 2026
0753608
improvement(library): single JSON-LD source, Markdown articles, and I…
waleedlatif1 Oct 24, 2026
511a064
fix(execution): close retired remote sandbox workers with a normal cl…
waleedlatif1 Oct 24, 2026
60b02de
fix(ci): pick the CodeDeploy action when the app Deploy stage has sid…
waleedlatif1 Oct 24, 2026
14e3315
fix(library): correct vendor facts and remove self-ranking in compari…
waleedlatif1 Oct 24, 2026
7b02221
docs(library): update best-ai-agents-for-lead-enrichment-2026 (#9361)
waleedlatif1 Oct 24, 2026
d4dfd17
docs(library): update best-conversational-ai-platforms-crm-helpdesk (…
waleedlatif1 Oct 24, 2026
dfb3535
fix(db): count the billing and auth pools in the scaling guide and re…
waleedlatif1 Oct 24, 2026
3fc79a2
fix(gmail): clear the history cursor only from a poll that held one (…
waleedlatif1 Oct 24, 2026
06fee1b
fix(billing): register the Stripe plugin only when the webhook secret…
waleedlatif1 Oct 24, 2026
4d33981
improvement(docs): build feature-branch docs previews only when docs …
waleedlatif1 Oct 24, 2026
420dc7a
fix(mothership): retry a job dispatch whose usage read failed instead…
waleedlatif1 Oct 24, 2026
92ce843
fix(mcp): answer an unpublishable workflow input on tool updates as v…
waleedlatif1 Oct 24, 2026
6c8ad7f
docs(library): update agentic-ai-coding-tools-what-they-are-and-how-t…
waleedlatif1 Oct 24, 2026
4b8f3e4
docs(library): update openai-vs-n8n-vs-sim (#9369)
waleedlatif1 Oct 24, 2026
27f0a83
fix(mothership): hold callerless runs' sim_cli to read API scopes (#9…
waleedlatif1 Oct 24, 2026
b7ee16f
docs(library): update best-conversational-ai-platforms-crm-helpdesk (…
waleedlatif1 Oct 25, 2026
f54acff
docs(library): update agentic-ai-coding-tools-what-they-are-and-how-t…
waleedlatif1 Oct 25, 2026
96cf934
docs(library): update ai-agent-examples-by-department-and-industry (#…
waleedlatif1 Oct 25, 2026
09d3bef
feat(library): AI Coding Agents vs Code Completion Tools: Which Shoul…
waleedlatif1 Oct 25, 2026
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
28 changes: 27 additions & 1 deletion .claude/rules/sim-sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
description: Isolated-vm sandbox worker security policy. Hard rules for anything that lives in the worker child process that runs user code.
paths:
- "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/**"
Expand Down Expand Up @@ -75,7 +77,31 @@ payload or `ivm.Reference` wrapper in the worker:
- [ ] Does the worker read a new env var? Add it to the `buildWorkerEnv()`
allowlist in `isolated-vm.ts` **and** to the allowlist regression test in
`isolated-vm.test.ts` — the worker does not inherit the app environment,
so an un-allowlisted var is simply absent in the child.
so an un-allowlisted var is simply absent in the child. If the app owns
its value, put it in `appWorkerEnv()` and add it with its accepted shape
to `CLIENT_WORKER_ENV` in `isolated-vm-host.cjs`, so a remote worker
gets the same value.
- [ ] Does the host send the worker a new message type? Add it to
`ALLOWED_INBOUND_TYPES` in `isolated-vm-host.cjs`, or remote workers
never receive it.

## Where the worker runs

The pool in `isolated-vm.ts` opens each worker either as a local child process
or, when `IVM_REMOTE_WORKER_URL` is set (with `IVM_REMOTE_WORKER_TOKEN`; a URL
without a valid token fails executions rather than falling back) and the
`isolated-vm-local-workers` kill switch is off, as a WebSocket connection to
`isolated-vm-host.cjs`, which runs the
same worker in a dedicated service that holds no platform credentials. Every
rule in this file applies in both modes.

- `fetch()` and brokers always run in the app. The host only relays the
worker's messages, so it needs no network access of its own and never gets
a broker implementation.
- A remote target never falls back to a local child process. An unreachable
host fails executions with a system error; keep it that way.
- Changes to the worker message protocol must stay compatible with the
previous release: the host and its clients roll out independently.

## What the worker *may* hold

Expand Down
28 changes: 26 additions & 2 deletions .cursor/rules/sim-sandbox.mdc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
description: "Isolated-vm sandbox worker security policy. Hard rules for anything that lives in the worker child process that runs user code."
globs: ["apps/sim/lib/execution/isolated-vm-worker.cjs","apps/sim/lib/execution/isolated-vm.ts","apps/sim/lib/execution/sandbox/**","apps/sim/sandboxes/**"]
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/**"]
---

<!-- Generated from .claude/rules/sim-sandbox.md by `bun run skills:sync`. Edit the source, not this file. -->
Expand Down Expand Up @@ -73,7 +73,31 @@ payload or `ivm.Reference` wrapper in the worker:
- [ ] Does the worker read a new env var? Add it to the `buildWorkerEnv()`
allowlist in `isolated-vm.ts` **and** to the allowlist regression test in
`isolated-vm.test.ts` — the worker does not inherit the app environment,
so an un-allowlisted var is simply absent in the child.
so an un-allowlisted var is simply absent in the child. If the app owns
its value, put it in `appWorkerEnv()` and add it with its accepted shape
to `CLIENT_WORKER_ENV` in `isolated-vm-host.cjs`, so a remote worker
gets the same value.
- [ ] Does the host send the worker a new message type? Add it to
`ALLOWED_INBOUND_TYPES` in `isolated-vm-host.cjs`, or remote workers
never receive it.

## Where the worker runs

The pool in `isolated-vm.ts` opens each worker either as a local child process
or, when `IVM_REMOTE_WORKER_URL` is set (with `IVM_REMOTE_WORKER_TOKEN`; a URL
without a valid token fails executions rather than falling back) and the
`isolated-vm-local-workers` kill switch is off, as a WebSocket connection to
`isolated-vm-host.cjs`, which runs the
same worker in a dedicated service that holds no platform credentials. Every
rule in this file applies in both modes.

- `fetch()` and brokers always run in the app. The host only relays the
worker's messages, so it needs no network access of its own and never gets
a broker implementation.
- A remote target never falls back to a local child process. An unreachable
host fails executions with a system error; keep it that way.
- Changes to the worker message protocol must stay compatible with the
previous release: the host and its clients roll out independently.

## What the worker *may* hold

Expand Down
2 changes: 1 addition & 1 deletion .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ runs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
bun-version: 1.4.4

- name: Setup Node
if: inputs.node-version != ''
Expand Down
7 changes: 5 additions & 2 deletions .github/scripts/wait-for-ecs-cutover.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,15 @@ while [ -z "$DEPLOYMENT_ID" ] || [ "$DEPLOYMENT_ID" = 'None' ]; do
DEPLOYMENT_ID=$(printf '%s\n' "$deploy_actions" | DEPLOY_STATE="$deploy_state" EXECUTION_ID="$EXECUTION_ID" python3 -c '
import json, os, re, sys
state = json.loads(os.environ["DEPLOY_STATE"])
actions = json.load(sys.stdin)
# The Deploy stage can also run sidecar actions (e.g. a CodeBuild image deploy); only the
# CodeDeploy blue/green action carries the ECS cutover.
actions = [a for a in json.load(sys.stdin)
if a.get("input", {}).get("actionTypeId", {}).get("provider") == "CodeDeployToECS"]
if not state or state.get("latestExecution", {}).get("pipelineExecutionId") != os.environ["EXECUTION_ID"] or not actions:
print("")
sys.exit(0)
if len({a["actionName"] for a in actions}) != 1:
raise SystemExit("ERROR: expected one Deploy action in the app pipeline")
raise SystemExit("ERROR: expected one CodeDeploy ECS action in the app pipeline Deploy stage")
latest = max(actions, key=lambda a: a["startTime"])
matches = [a["latestExecution"] for a in state.get("actionStates", [])
if a["actionName"] == latest["actionName"]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
bun-version: 1.4.4
- name: Install only the pinned task planner
continue-on-error: true
run: bun install --global "turbo@$(jq -r .devDependencies.turbo package.json)"
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ jobs:
needs.promote.result == 'success' &&
needs.trigger-upload.result == 'success' &&
needs.promote.outputs.promoted == 'true'
outputs:
# The new app serves traffic; indexnow keys off this, not the later Trigger.dev promotion.
cutover: ${{ steps.cutover.outcome }}
# Mostly waiting on the ECS cutover after a dependency install: the smallest runner is enough.
runs-on: *runner-2vcpu
# Leave setup/promotion headroom above the 70-minute cutover poll.
Expand Down Expand Up @@ -596,6 +599,7 @@ jobs:
# An unchanged tag may belong to a failed or still-running earlier deploy.
# Verify its latest cutover rather than treating tag equality as success.
- name: Wait for ECS traffic cutover
id: cutover
env:
OVERALL_TIMEOUT: 4200
APP_IMAGE_CHANGED: ${{ needs.promote.outputs.app_image_changed }}
Expand Down Expand Up @@ -636,6 +640,59 @@ jobs:
fi
bunx trigger.dev@4.5.16 promote "$VERSION" "${TARGET_ARGS[@]}"
# Production only, once the new app serves traffic: submit the library and comparison URLs this
# push changed to IndexNow. Best effort: nothing depends on it, and a failure never fails the run.
indexnow:
name: indexnow
needs: [promote, trigger-promote]
if: >-
!cancelled() &&
github.event_name == 'push' &&
github.ref == 'refs/heads/main' &&
needs.promote.outputs.promoted == 'true' &&
needs.trigger-promote.outputs.cutover == 'success'
runs-on: *runner-2vcpu
timeout-minutes: 5
continue-on-error: true
permissions:
contents: read
actions: read
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v6

- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.4

# Diff from the head of the last earlier run whose submission succeeded, not the previous
# push: a push that never deployed, or whose submission failed, would otherwise drop its
# changed URLs for good. Falls back to the previous push when no such run is in view. The
# diff needs only the two trees, so that one commit is fetched alone; an all-zero `before`
# (the branch's first push) has no base, which the script skips.
- name: Submit changed URLs to IndexNow
env:
GH_TOKEN: ${{ github.token }}
PUSH_BEFORE: ${{ github.event.before }}
run: |
BASE_SHA=""
while read -r run_id head_sha; do
conclusion="$(gh api --paginate "repos/$GITHUB_REPOSITORY/actions/runs/$run_id/jobs?per_page=100" \
--jq '.jobs[] | select(.name == "indexnow") | .conclusion')"
Comment thread
waleedlatif1 marked this conversation as resolved.
if [[ "$conclusion" == "success" ]]; then
BASE_SHA="$head_sha"
break
fi
done < <(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/ci.yml/runs?branch=main&event=push&per_page=30" \
--jq ".workflow_runs[] | select(.id < $GITHUB_RUN_ID) | \"\\(.id) \\(.head_sha)\"")
BASE_SHA="${BASE_SHA:-$PUSH_BEFORE}"
echo "Submitting URLs changed in $BASE_SHA..$GITHUB_SHA"
if [[ ! "$BASE_SHA" =~ ^0+$ ]]; then
git fetch --no-tags --depth=1 origin "$BASE_SHA"
fi
bun scripts/ping-indexnow.ts "$BASE_SHA" "$GITHUB_SHA"
# Build ARM64 images for GHCR (main branch only, runs in parallel with
# tests). Pushes only the immutable sha tag — latest-arm64/version-arm64
# are applied by ghcr after the gate, so a failing run
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/desktop-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
bun-version: 1.4.4

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

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

- name: Setup Node
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/desktop-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
bun-version: 1.4.4

- name: Setup Node
uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v6
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/helm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
- name: Setup Bun
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: 1.4.2
bun-version: 1.4.4

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

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

# Derives appVersion rather than checking it, so the published chart cannot
# be pinned to an older Sim than the release it ships with. The committed
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"type": "module",
"main": "dist/main.cjs",
"engines": {
"bun": ">=1.4.2",
"bun": ">=1.4.4",
"node": ">=20.0.0"
},
"scripts": {
Expand Down
Loading
Loading