v0.7.49: outlook calendar, logfire tools, shared folders, desktop sec… · simstudioai/sim@2a62673 · GitHub
Skip to content

Commit 2a62673

Browse files
authored
v0.7.49: outlook calendar, logfire tools, shared folders, desktop security hardening, pi improvements
2 parents c3ed1e9 + 1ce2aef commit 2a62673

340 files changed

Lines changed: 69455 additions & 4819 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.
Lines changed: 39 additions & 0 deletions

‎.github/workflows/test-build.yml‎

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ jobs:
177177
- name: Install ripgrep
178178
run: command -v rg || (sudo apt-get update && sudo apt-get install -y ripgrep)
179179

180-
- name: Run tests with coverage
180+
# Named for what it does: `bun run test` is `vitest run`, with no
181+
# `--coverage`. See the Codecov note below.
182+
- name: Run tests
181183
env:
182184
NODE_OPTIONS: '--no-warnings --max-old-space-size=8192'
183185
NEXT_PUBLIC_APP_URL: 'https://www.sim.ai'
@@ -199,6 +201,14 @@ jobs:
199201
fi
200202
echo "✅ Schema and migrations are in sync"
201203
204+
# DEAD PATH: nothing generates `apps/sim/coverage`. The test step runs
205+
# `vitest run` without `--coverage`, and vitest.config.ts declares no
206+
# coverage provider, so this uploads nothing and still reports success in
207+
# ~1s (`fail_ci_if_error: false` hides it). `@vitest/coverage-v8` IS
208+
# installed, so wiring it up is possible — but coverage instrumentation
209+
# costs test time and nothing gates on the result today. Left in place
210+
# pending a decision to either enable coverage or drop this step; do not
211+
# read its green tick as "coverage was published".
202212
- name: Upload coverage to Codecov
203213
uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5
204214
with:
@@ -222,7 +232,11 @@ jobs:
222232
build:
223233
name: Build App
224234
runs-on: ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-16vcpu-ubuntu-2404' || 'linux-x64-8-core' }}
225-
timeout-minutes: 15
235+
# Build durations crossed 15 minutes as the app grew (10m02 on Jul 29 AM,
236+
# 14m44 after the folders/desktop/library merges, then two straight
237+
# timeouts) — GitHub reports a job timeout as "cancelled". 25 keeps
238+
# headroom without masking a genuine hang.
239+
timeout-minutes: 25
226240

227241
steps:
228242
- name: Checkout code
@@ -259,17 +273,12 @@ jobs:
259273
key: ${{ github.repository }}-turbo-cache-build-${{ github.event_name }}${{ github.event.pull_request.head.repo.fork && '-fork' || '' }}
260274
path: ./.turbo
261275

262-
# Turbopack's persistent build cache (NEXT_TURBOPACK_BUILD_CACHE below)
263-
# writes ~5 GB into .next/cache — a sticky disk mounts it in ~1s where an
264-
# actions/cache round-trip would eat the warm-build win. Same event/fork
265-
# namespacing as the other mounts; the GitHub fallback inside cache-mount
266-
# still uses actions/cache with a run_id-suffixed key.
267-
- name: Mount Next.js build cache
268-
uses: ./.github/actions/cache-mount
269-
with:
270-
provider: ${{ vars.CI_PROVIDER }}
271-
key: ${{ github.repository }}-nextjs-cache-${{ github.event_name }}${{ github.event.pull_request.head.repo.fork && '-fork' || '' }}
272-
path: ./apps/sim/.next/cache
276+
# No `.next/cache` mount: the Turbopack persistent build cache is off. A
277+
# controlled A/B on one branch (PR #6078) with a byte-identical module graph
278+
# measured compile at 113s with the cache off, 162s cold with it on, and
279+
# 360s warm — the cache made the same build 3.2x slower, and it grew
280+
# 5.1 GB -> 12 GB across two runs of an unchanged tree, so a disk degrades
281+
# the more it is used. Mounting a disk nothing reads would only cost storage.
273282

274283
# Running out of RAM kills the whole VM and surfaces only as "the runner
275284
# has received a shutdown signal" — no mention of memory, ~12 min in. Warn
@@ -300,7 +309,4 @@ jobs:
300309
AWS_REGION: 'us-west-2'
301310
ENCRYPTION_KEY: '7cf672e460e430c1fba707575c2b0e2ad5a99dddf9b7b7e3b5646e630861db1c' # dummy key for CI only
302311
TURBO_CACHE_DIR: .turbo
303-
# Opt into Turbopack's persistent build cache (beta) for this CI
304-
# check build only — measured 105s cold vs 22s warm locally.
305-
NEXT_TURBOPACK_BUILD_CACHE: '1'
306312
run: bunx turbo run build --filter=sim

‎.gitignore‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,14 @@ i18n.cache
102102
# Python (apps/pii tests/tooling)
103103
__pycache__/
104104
.pytest_cache/
105+
106+
# Local file-upload spill directory. `UPLOAD_DIR_SERVER` is
107+
# `join(process.cwd(), 'uploads')`, so it follows the cwd rather than a fixed
108+
# root: under `turbo run test` the cwd is apps/sim and `apps/sim/.gitignore`'s
109+
# `/uploads` catches it, but running vitest from the repo root drops ~40
110+
# `uploads/execution/**/large-value-*.json` files here instead.
111+
#
112+
# Anchored deliberately. An unanchored `uploads/` would also match
113+
# `apps/sim/lib/uploads/` — 61 files of tracked source — and silently ignore
114+
# anything added there later.
115+
/uploads

‎apps/desktop/README.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Sim Desktop (macOS)
22

3-
A thin Electron shell around the hosted Sim web app. The renderer loads the configured origin (default `https://sim.ai`) as a normal top-level page in a bundled, pinned Chromium — rendering is identical to Chrome of that version on every machine. No UI is re-implemented and no server stack is bundled.
3+
A thin Electron shell around the hosted Sim web app. The renderer loads the configured origin (default `https://www.sim.ai` — the origin the server actually serves; the apex 301s there) as a normal top-level page in a bundled, pinned Chromium — rendering is identical to Chrome of that version on every machine. No UI is re-implemented and no server stack is bundled.
44

55
## Layout
66

@@ -44,7 +44,7 @@ e2e/ # Playwright _electron smoke suite
4444
```bash
4545
bun install # workspace root
4646
cd apps/desktop
47-
bun run dev # bundle + launch against https://sim.ai
47+
bun run dev # bundle + launch against https://www.sim.ai
4848
SIM_DESKTOP_ORIGIN=http://localhost:3000 bun run dev # against local sim
4949
```
5050

@@ -74,7 +74,7 @@ Deviations from the original plan doc (deliberate):
7474

7575
## Provider matrix (U5 spike — keep current)
7676

77-
Host lists live in `src/main/navigation.ts` (`SYSTEM_BROWSER_IDP_HOSTS`, `IN_WINDOW_IDP_HOSTS`). Verified so far: Google + Microsoft blocked (by policy, not spike); GitHub assumed lenient. **Before GA, run the spike**: GitHub sign-in, consumer-Microsoft, a sample of integration connects (Notion, Slack, Linear, Atlassian, Box, Dropbox), SSO, and Turnstile-on-signup in a packaged build, then update the lists and this section.
77+
The host list lives in `src/main/navigation.ts` (`SYSTEM_BROWSER_IDP_HOSTS`) and now applies to **integration connects only** — sign-in always goes through the system-browser handoff whatever the IdP, so no provider needs to be classified as embed-tolerant for login. (The old `IN_WINDOW_IDP_HOSTS` list existed to keep GitHub sign-in in-window; embedding a login is a one-way door in a chrome-less shell and splits better-auth's OAuth state across two cookie jars, so it was removed.) Verified so far: Google + Microsoft block embedding by policy. **Before GA, run the spike** for connects: a sample of integration connects (Notion, Slack, Linear, Atlassian, Box, Dropbox) plus SSO and Turnstile-on-signup in a packaged build, then update the list and this section.
7878

7979
## Web-app coupling contract (audit on web-app changes)
8080

‎apps/desktop/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"start": "electron .",
1919
"package:dir": "bun run build && electron-builder --mac dir --publish never",
2020
"package:mac": "bun run build && electron-builder --mac --publish never",
21-
"package:share": "bun run build && electron-builder --mac --publish never -c.mac.timestamp=none",
21+
"package:share": "bun run scripts/package-share.ts",
2222
"install:local": "bun run scripts/install-local.ts",
2323
"type-check": "tsc --noEmit",
2424
"lint": "biome check --write --unsafe .",

‎apps/desktop/scripts/build.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const watch = process.argv.includes('--watch')
77
// non-prod environment): SIM_DESKTOP_DEFAULT_ORIGIN=https://www.dev.sim.ai.
88
// Baked into the bundle so it applies to fresh installs with no settings —
99
// unlike the SIM_DESKTOP_ORIGIN env var, which only affects terminal-launched
10-
// processes. Official builds leave it unset (default https://sim.ai).
10+
// processes. Official builds leave it unset (default https://www.sim.ai).
1111
const bakedDefaultOrigin = process.env.SIM_DESKTOP_DEFAULT_ORIGIN ?? ''
1212
if (
1313
bakedDefaultOrigin &&

‎apps/desktop/scripts/channels.ts‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Build-time channel identity, derived from the origin a build is baked to.
3+
*
4+
* Must stay in sync with APP_NAME_FOR_CHANNEL / channelForOrigin in
5+
* src/main/config.ts. That pair is the RUNTIME source of truth — the app calls
6+
* app.setName() from its baked origin at startup, which decides the userData
7+
* directory and single-instance lock — and this is what the packager stamps
8+
* into the bundle. When the two disagree, the bundle on disk and the running
9+
* app disagree about which app they are: a dev-pointed build packaged as
10+
* "Sim.app" with the production bundle id installs over a real production
11+
* install while naming itself "Sim Dev" at runtime.
12+
*/
13+
14+
/** Canonical no-redirect origins per environment. */
15+
export const PROD_ORIGIN = 'https://www.sim.ai'
16+
export const STAGING_ORIGIN = 'https://www.staging.sim.ai'
17+
export const DEV_ORIGIN = 'https://www.dev.sim.ai'
18+
export const LOCAL_ORIGIN = 'http://localhost:3000'
19+
20+
export interface ChannelIdentity {
21+
/** Display + bundle name; also the userData directory name. */
22+
name: string
23+
appId: string
24+
/** Baked default origin + persisted settings origin. */
25+
origin: string
26+
/**
27+
* Artifact filename stem, and the per-channel scratch directory name.
28+
* Space-free for the same reason electron-builder.yml's artifactName is:
29+
* GitHub rewrites asset names containing spaces, which desyncs the
30+
* electron-updater manifest from the uploaded files.
31+
*/
32+
slug: string
33+
}
34+
35+
export const PROD: ChannelIdentity = {
36+
name: 'Sim',
37+
appId: 'ai.sim.desktop',
38+
origin: PROD_ORIGIN,
39+
slug: 'sim',
40+
}
41+
export const STAGING: ChannelIdentity = {
42+
name: 'Sim Staging',
43+
appId: 'ai.sim.desktop.staging',
44+
origin: STAGING_ORIGIN,
45+
slug: 'sim-staging',
46+
}
47+
export const DEV: ChannelIdentity = {
48+
name: 'Sim Dev',
49+
appId: 'ai.sim.desktop.dev',
50+
origin: DEV_ORIGIN,
51+
slug: 'sim-dev',
52+
}
53+
export const LOCAL: ChannelIdentity = {
54+
name: 'Sim Local',
55+
appId: 'ai.sim.desktop.local',
56+
origin: LOCAL_ORIGIN,
57+
slug: 'sim-local',
58+
}
59+
60+
/** Every channel, in the order a full run builds them. */
61+
export const ALL_CHANNELS: readonly ChannelIdentity[] = [PROD, STAGING, DEV, LOCAL]
62+
63+
/**
64+
* Resolves the identity a build baked to `origin` must carry. Mirrors
65+
* channelForOrigin in src/main/config.ts, including its fall-through to
66+
* production for unrecognized hosts (self-hosted origins are production
67+
* builds pointed elsewhere). An empty origin means "unset", which the app
68+
* resolves to DEFAULT_ORIGIN — production.
69+
*/
70+
export function identityForOrigin(origin: string): ChannelIdentity {
71+
if (!origin) return PROD
72+
let host: string
73+
try {
74+
host = new URL(origin).hostname.toLowerCase()
75+
} catch {
76+
return PROD
77+
}
78+
if (host === 'localhost' || host === '127.0.0.1') return LOCAL
79+
if (host === 'dev.sim.ai' || host.endsWith('.dev.sim.ai')) return DEV
80+
if (host === 'staging.sim.ai' || host.endsWith('.staging.sim.ai')) return STAGING
81+
return PROD
82+
}

‎apps/desktop/scripts/install-local.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ const CHANNEL_FLAGS: Record<string, ChannelIdentity> = {
4040
appId: 'ai.sim.desktop.staging',
4141
origin: 'https://www.staging.sim.ai',
4242
},
43-
// Bare sim.ai, matching official prod builds (config.ts) — www.sim.ai
44-
// would land in a different cookie partition than a real install.
45-
'--prod': { name: 'Sim', appId: 'ai.sim.desktop', origin: 'https://sim.ai' },
43+
// Origin left unset, exactly as official prod builds do, so this install
44+
// resolves the same DEFAULT_ORIGIN (config.ts) and therefore the same cookie
45+
// partition as a real one. Naming an origin here re-creates the drift that
46+
// pinned prod to the apex while the server serves www.
47+
'--prod': { name: 'Sim', appId: 'ai.sim.desktop' },
4648
}
4749

4850
const DEFAULT_IDENTITY: ChannelIdentity = { name: 'Sim', appId: 'ai.sim.desktop' }
Lines changed: 124 additions & 0 deletions

0 commit comments

Comments
 (0)