diff --git a/README.md b/README.md index 3c3b730ee2..f9828ea46c 100644 --- a/README.md +++ b/README.md @@ -112,7 +112,8 @@ bun run reset ``` `bun run reset` drops the platform database schema and removes the hub's -and the dev sidecar's on-disk asset directories — everything boot-time +on-disk asset directory (which also holds provisioned sidecar state) — +everything boot-time seeding and onboarding created. Nothing is re-seeded until the next `bun run dev` — that recreates the schema and, once the hub is serving again, reprovisions and re-seeds the root tenant from scratch, landing you at a diff --git a/docs/local-rip.md b/docs/local-rip.md index 4e93f30670..432105edbe 100644 --- a/docs/local-rip.md +++ b/docs/local-rip.md @@ -39,8 +39,8 @@ bun run dev `bun run dev` and its boot-time seeding created — skip it on a genuinely fresh checkout. `bun run dev` validates `.env`, confirms `DATABASE_URL` is reachable, applies pending migrations, builds the web -UI, seeds the administrator account, and starts the hub, one sidecar, and -the web dev server together — the hub then provisions and seeds the root +UI, seeds the administrator account, and starts the hub and the web +build — the hub then provisions and seeds the root tenant itself once it is serving (see [README.md](../README.md#running-locally) for exactly what it checks). Leave `ANTHROPIC_API_KEY` unset in `.env` for diff --git a/packages/chat-ui/test/use-typing-indicator.test.tsx b/packages/chat-ui/test/use-typing-indicator.test.tsx index 680ce1b1c2..3d618b0901 100644 --- a/packages/chat-ui/test/use-typing-indicator.test.tsx +++ b/packages/chat-ui/test/use-typing-indicator.test.tsx @@ -13,9 +13,11 @@ import type { TypingState } from "../src/typing-indicator"; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); // Long enough that real event-loop jitter can't flip a "before expiry" / -// "after expiry" assertion; short enough to keep the suite well under a -// second even so. -const TEST_TIMEOUT_MS = 120; +// "after expiry" assertion — CI runners under load have been observed to +// stretch a single await by well over 100ms, so every "before expiry" +// margin below is a quarter of the expiry or better. Short enough to keep +// the suite around two seconds even so. +const TEST_TIMEOUT_MS = 500; function mount( selfPrincipalId: string | undefined, @@ -77,19 +79,20 @@ describe("useTypingIndicator (real timer wiring)", () => { test("a second ping re-arms the expiry rather than doubling timers", async () => { const harness = mount("prn_self1", "chan_a"); - harness.ping("prn_other1"); // t=0, would expire at t=120 unless re-armed + harness.ping("prn_other1"); // t=0, would expire at t=500 unless re-armed - await harness.settle(50); // t=50 - harness.ping("prn_other1"); // re-armed: now expires at t=170 + await harness.settle(150); // t=150 + harness.ping("prn_other1"); // re-armed: now expires at t=650 - // t=140 — past the original (unarmed) expiry at 120 with a 20ms - // margin, but well before the re-armed one at 170. Still showing here - // only makes sense if the re-arm actually took effect. - await harness.settle(90); + // t=400 — past the original (unarmed) expiry at 500 would be a + // failure of the re-arm, and it is still 250ms before the re-armed + // expiry at 650. Still showing here only makes sense if the re-arm + // actually took effect. + await harness.settle(250); expect(harness.get()?.principalId).toBe("prn_other1"); - // t=210 — past the re-armed expiry at 170 with a 40ms margin. - await harness.settle(70); + // t=800 — past the re-armed expiry at 650 with a 150ms margin. + await harness.settle(400); expect(harness.get()).toBeNull(); harness.unmount(); }); diff --git a/scripts/reset.test.ts b/scripts/reset.test.ts index a8db0170d0..e86c7fe371 100644 --- a/scripts/reset.test.ts +++ b/scripts/reset.test.ts @@ -41,10 +41,9 @@ describe("requireLocalDatabase", () => { }); describe("resolveLocalStateDirs", () => { - test("resolves the hub dir against apps/hub and the sidecar dir at the repo root", () => { + test("resolves the hub dir against apps/hub", () => { const dirs = resolveLocalStateDirs("/repo", ".data/hub"); expect(dirs.hubDataDir).toBe(path.resolve("/repo/apps/hub/.data/hub")); - expect(dirs.sidecarDataDir).toBe(path.resolve("/repo/.data/sidecar")); }); test("honors an absolute HUB_DATA_DIR", () => { @@ -98,7 +97,7 @@ describe("resetLocalState", () => { ]); }); - test("reports no removed directories when neither is present", async () => { + test("reports no removed directories when it is not present", async () => { const deps: ResetDeps = { root: "/repo", resetSchema: async () => undefined, diff --git a/scripts/reset.ts b/scripts/reset.ts index 2e4361f70f..315e7ec39c 100644 --- a/scripts/reset.ts +++ b/scripts/reset.ts @@ -2,8 +2,9 @@ // onboarding flow: drops the platform schema (database, auth tables, // every installed package's tables, and the db-setup ledger all live // in the same schema, so one drop clears them all) and removes the -// on-disk directories the hub and the dev sidecar keep durable repo -// and asset state in. +// on-disk directory the hub keeps durable repo and asset state in. +// Provisioned sidecar state lives under the hub data dir, so the hub +// reset covers it. // // Refuses outright against a non-local DATABASE_URL — there is no // override. A schema drop is unrecoverable, and this script exists for @@ -46,19 +47,16 @@ export function requireLocalDatabase(databaseUrl: string): void { } /** - * The on-disk directories a local `bun run dev` checkout keeps durable + * The on-disk directory a local `bun run dev` checkout keeps durable * state in: the hub's `HUB_DATA_DIR` (resolved the same way the hub - * itself resolves it — against `apps/hub`'s working directory) and the - * dev sidecar's data directory, which `scripts/dev.ts` always pins to - * `.data/sidecar` at the repo root regardless of `SIDECAR_DATA_DIR`. + * itself resolves it — against `apps/hub`'s working directory). */ export function resolveLocalStateDirs( root: string, hubDataDir: string, -): { hubDataDir: string; sidecarDataDir: string } { +): { hubDataDir: string } { return { hubDataDir: path.resolve(path.join(root, "apps", "hub"), hubDataDir), - sidecarDataDir: path.join(root, ".data", "sidecar"), }; } @@ -82,10 +80,10 @@ const defaultDeps: ResetDeps = { }; /** - * Drop the platform schema and remove the on-disk asset directories, + * Drop the platform schema and remove the on-disk asset directory, * leaving a checkout in the same state as a fresh clone with `.env` * already filled in. `bun run dev` recreates the schema and the - * directories on its next start. + * directory on its next start. */ export async function resetLocalState( env: Record, @@ -98,7 +96,7 @@ export async function resetLocalState( const dirs = resolveLocalStateDirs(deps.root, config.hubDataDir); const removedDirs: string[] = []; - for (const dir of [dirs.hubDataDir, dirs.sidecarDataDir]) { + for (const dir of [dirs.hubDataDir]) { if (!deps.exists(dir)) continue; await deps.rm(dir, { recursive: true, force: true }); removedDirs.push(dir); @@ -128,7 +126,7 @@ if (import.meta.main) { `reset: dropped the platform schema in database ${JSON.stringify(report.database)}`, ); if (report.removedDirs.length === 0) { - console.log("reset: no on-disk asset directories were present"); + console.log("reset: no on-disk asset directory was present"); } else { for (const dir of report.removedDirs) { console.log(`reset: removed ${dir}`);