@helipod/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/load-config.ts","../src/functions-dir.ts","../src/dev-options.ts","../src/load-modules.ts","../src/push-pipeline.ts","../src/boot.ts","../src/blobstore-select.ts","../src/objectstore-select.ts","../src/replica-forward.ts","../src/server.ts","../src/watch.ts","../src/cli.ts","../src/serve.ts","../src/deploy-apply.ts","../src/schema-diff.ts","../src/wake-host.ts","../src/deploy.ts","../src/build.ts","../src/build-entry.ts","../src/migrate.ts","../src/migrate/source.ts","../src/migrate/convex-source.ts","../src/migrate/rewrite-imports.ts","../src/migrate/scan-divergences.ts","../src/migrate/data.ts","../src/fleet.ts","../src/objectstore.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { HelipodConfig } from \"@helipod/component\";\n\nconst CACHE_BUST = () => `?t=${Date.now()}`;\n\nexport async function loadConfig(projectDir: string): Promise<HelipodConfig> {\n const path = ([\"helipod.config.ts\", \"helipod.config.js\"] as const)\n .map((f) => join(projectDir, f))\n .find((p) => existsSync(p));\n\n if (!path) return { components: [] };\n\n const mod = (await import(pathToFileURL(path).href + CACHE_BUST())) as {\n default?: HelipodConfig;\n } & HelipodConfig;\n const cfg = (mod.default ?? mod) as HelipodConfig;\n return { components: cfg.components ?? [], deploy: cfg.deploy, functionsDir: cfg.functionsDir };\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { loadConfig } from \"./load-config\";\n\n/** The default backend functions directory name. */\nexport const DEFAULT_FUNCTIONS_DIR = \"helipod\";\n\nexport interface ResolvedFunctionsDir {\n /** Absolute path to the functions directory. */\n functionsDir: string;\n /** Absolute path to the project root (where helipod.config.ts lives). */\n projectRoot: string;\n}\n\n/**\n * Resolve the functions directory. Precedence, highest first:\n * 1. an explicit `--dir` value\n * 2. `functionsDir` in helipod.config.ts\n * 3. DEFAULT_FUNCTIONS_DIR\n *\n * There is deliberately NO implicit fallback to `convex/`: a Convex layout is\n * converted by `helipod migrate`, never adopted silently. See\n * docs_old/superpowers/specs/2026-06-06-functions-dir-rename-design.md.\n *\n * With an explicit flag the project root is that path's parent, so a caller can point at a\n * functions directory anywhere. Without one the root is the cwd, which is what makes it safe\n * to read the config before the directory name is known: helipod.config.ts always sits at\n * the root and never inside the functions directory.\n */\nexport async function resolveFunctionsDir(\n flagValue: string | undefined,\n cwd: string,\n): Promise<ResolvedFunctionsDir> {\n if (flagValue !== undefined && flagValue !== \"\") {\n const functionsDir = isAbsolute(flagValue) ? flagValue : resolve(cwd, flagValue);\n return { functionsDir, projectRoot: dirname(functionsDir) };\n }\n const projectRoot = resolve(cwd);\n const config = await loadConfig(projectRoot);\n const name = config.functionsDir ?? DEFAULT_FUNCTIONS_DIR;\n return { functionsDir: isAbsolute(name) ? name : join(projectRoot, name), projectRoot };\n}\n\n/** The failure message when the resolved directory does not exist. The one Convex-aware string in the CLI. */\nexport function functionsDirNotFoundMessage(functionsDir: string): string {\n return (\n `no functions directory found at ${functionsDir}\\n\\n` +\n `If this is a Convex app, run \\`helipod migrate\\` to convert it. It renames\\n` +\n `convex/ to helipod/ and rewrites your imports.\\n\\n` +\n `Otherwise create ${join(functionsDir, \"schema.ts\")}, or point at an existing folder:\\n` +\n ` helipod dev --dir <path>\\n`\n );\n}\n\n/**\n * Checks that the resolved functions directory exists. When it doesn't, writes the friendly\n * `functionsDirNotFoundMessage` to stderr and returns false — callers should return exit code 1\n * in that case, rather than letting a missing directory escape as a raw fs error further down the\n * command. Every command that resolves a functions directory (serve, deploy, build, objectstore,\n * codegen, dev) should route its existence check through this one helper, not hand-roll the\n * `existsSync` + message-write pair at each call site.\n */\nexport function ensureFunctionsDirExists(functionsDir: string): boolean {\n if (existsSync(functionsDir)) return true;\n process.stderr.write(functionsDirNotFoundMessage(functionsDir));\n return false;\n}\n","/**\n * Resolve `helipod dev` options from CLI flags + defaults.\n */\nimport { DEFAULT_FUNCTIONS_DIR } from \"./functions-dir\";\n\nexport type RuntimeKind = \"bun\" | \"node\" | \"auto\";\n\nexport interface DevOptions {\n port?: number;\n ip?: string;\n functionsDir?: string;\n dataPath?: string;\n runtime?: RuntimeKind;\n /** Optional static web UI directory to serve alongside the API/WebSocket. */\n webDir?: string;\n /** Postgres connection string (flag wins over `HELIPOD_DATABASE_URL`); unset → SQLite. */\n databaseUrl?: string;\n /** File-storage backend flag overrides (`--storage-bucket`/`--storage-endpoint`; win over env). */\n storageBucket?: string;\n storageEndpoint?: string;\n}\n\nexport interface ResolvedDevOptions {\n port: number;\n ip: string;\n functionsDir: string;\n dataPath: string;\n runtime: RuntimeKind;\n webDir: string | undefined;\n databaseUrl: string | undefined;\n storageBucket: string | undefined;\n storageEndpoint: string | undefined;\n}\n\nexport function resolveDevOptions(options: DevOptions = {}): ResolvedDevOptions {\n return {\n port: options.port ?? 3000,\n ip: options.ip ?? \"127.0.0.1\",\n functionsDir: options.functionsDir ?? DEFAULT_FUNCTIONS_DIR,\n dataPath: options.dataPath ?? \".helipod/data.db\",\n runtime: options.runtime ?? \"auto\",\n webDir: options.webDir,\n databaseUrl: options.databaseUrl ?? process.env.HELIPOD_DATABASE_URL,\n storageBucket: options.storageBucket,\n storageEndpoint: options.storageEndpoint,\n };\n}\n\n/** Detect the active JS runtime (Bun is primary; Node is supported). */\nexport function detectRuntime(): \"bun\" | \"node\" {\n return typeof (globalThis as { Bun?: unknown }).Bun !== \"undefined\" ? \"bun\" : \"node\";\n}\n","/**\n * Load a functions directory: esbuild-BUNDLE each module (schema + function files) then import the\n * bundle. Bundling resolves relative imports (incl. the conventional extensionless `./_generated/*`\n * value imports every app uses) at bundle time, identically on Bun / Node / any ESM runtime — so\n * loading no longer depends on the runtime's own resolver (plain Node's ESM rejects extensionless\n * specifiers with ERR_MODULE_NOT_FOUND; Bun accepts them). Bare deps (`@helipod/*`, user npm\n * packages) stay EXTERNAL (`packages: \"external\"`) and resolve at import time from `node_modules`,\n * so engine singletons keep their identity. Extension-agnostic: a hand-authored dev project is\n * `.ts`, a `helipod deploy`-pushed tree is `.js` — both bundle+load the same way.\n */\nimport { createHash } from \"node:crypto\";\nimport { readdirSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join, resolve, dirname } from \"node:path\";\nimport { pathToFileURL, fileURLToPath } from \"node:url\";\nimport { build } from \"esbuild\";\nimport type { SchemaDefinition } from \"@helipod/values\";\nimport type { LoadedProject } from \"./project\";\n\nconst CACHE_BUST = () => `?t=${Date.now()}`;\n\n/** The module key `helipod` uses to address a functions-directory function file — strips the extension. */\nexport function moduleKeyForFile(file: string): string {\n return file.replace(/\\.(ts|js)$/, \"\");\n}\n\n/** List a functions directory's function module files (excludes schema.{ts,js}, `_`-prefixed, and .d.ts). */\nexport function listFunctionModuleFiles(absDir: string): string[] {\n const isModule = (f: string) =>\n (f.endsWith(\".ts\") || f.endsWith(\".js\")) &&\n !f.endsWith(\".d.ts\") &&\n !f.startsWith(\"_\") &&\n f !== \"schema.ts\" &&\n f !== \"schema.js\";\n return readdirSync(absDir).filter(isModule);\n}\n\n/** The nearest ancestor of `startDir` (walking up) that contains a `node_modules` dir. A real app's\n * functions directory sits under its project root, whose `node_modules` has `@helipod/*`; that is what we\n * find. Returns `undefined` if there is no `node_modules` ancestor at all (e.g. a throwaway temp-dir\n * project) — the caller then falls back to the CLI's own root. */\nfunction nearestNodeModulesRoot(startDir: string): string | undefined {\n let dir = resolve(startDir);\n for (;;) {\n if (existsSync(join(dir, \"node_modules\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/** The bundled output goes under `<root>/node_modules/.cache/helipod` so the bundle's external\n * bare imports (`@helipod/*`, user npm deps) resolve via Node's ancestor walk. Uses the app's own\n * `node_modules` root when it has one; otherwise falls back to the CLI's own root (which always has\n * `@helipod/*`), so a `node_modules`-less project (e.g. a temp-dir test fixture) still loads. */\nfunction resolveCacheDir(startDir: string): string {\n const dir =\n nearestNodeModulesRoot(startDir) ??\n // Fallback: the dir containing the CLI's own node_modules (found by walking up from this module).\n (nearestNodeModulesRoot(dirname(fileURLToPath(import.meta.url))) ?? resolve(startDir));\n // Namespace per functions-dir so two projects that resolve to the SAME node_modules ancestor never\n // collide on `<key>.mjs` (a shared path would let a parallel load of a different dir overwrite this\n // one's bundle between write and read — a silent wrong-module load).\n const ns = createHash(\"sha256\").update(resolve(startDir)).digest(\"hex\").slice(0, 16);\n const cacheDir = join(dir, \"node_modules\", \".cache\", \"helipod\", ns);\n mkdirSync(cacheDir, { recursive: true });\n return cacheDir;\n}\n\n/** Extra bare specifiers to keep EXTERNAL during bundle-on-load, beyond `@helipod/*` — the\n * escape hatch for a dep that must NOT be bundled/inlined: e.g. a package relied on for singleton\n * identity across function modules (the same reason `@helipod/*` itself is external — an\n * inlined copy would break `instanceof`/module-level state shared across files), or one with\n * native bindings esbuild can't bundle cleanly. `HELIPOD_BUNDLE_EXTERNAL` is a comma-separated\n * list of esbuild `external` patterns (same glob syntax as esbuild's own option, e.g.\n * `\"sharp,@foo/*\"`); unset means no extra externals — today's behavior is the default. */\nfunction extraBundleExternals(): string[] {\n const raw = process.env.HELIPOD_BUNDLE_EXTERNAL;\n if (!raw) return [];\n return raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\n/** Bundle one module and import it. The relative graph (`./_generated/*`, siblings) AND third-party\n * npm deps are INLINED — esbuild does the CJS→ESM interop at bundle time (like the deploy bundler),\n * so a convention like `import { parseExpression } from \"cron-parser\"` (a CJS package) works under\n * native Node ESM too. `@helipod/*` stays EXTERNAL: those are the engine's own packages, and\n * they must resolve to the ONE instance the running engine loaded (inlining them would give each\n * module its own copy and break singleton identity — `query`/`mutation`/the db registry). A caller\n * can widen the external set via `HELIPOD_BUNDLE_EXTERNAL` (see `extraBundleExternals`) for a\n * dep with the same singleton concern. Node builtins are external automatically under\n * `platform: \"node\"`. Resolution happens at bundle time — runtime-agnostic. */\nasync function bundleAndImport(file: string, key: string, cacheDir: string): Promise<Record<string, unknown>> {\n const result = await build({\n entryPoints: [file],\n bundle: true,\n external: [\"@helipod/*\", ...extraBundleExternals()],\n format: \"esm\",\n platform: \"node\",\n write: false,\n sourcemap: \"inline\",\n logLevel: \"silent\",\n });\n const code = result.outputFiles[0]!.text;\n const outFile = join(cacheDir, `${key.replace(/[\\\\/]/g, \"__\")}.mjs`);\n writeFileSync(outFile, code);\n return (await import(pathToFileURL(outFile).href + CACHE_BUST())) as Record<string, unknown>;\n}\n\nexport async function loadFunctionsDir(dir: string): Promise<LoadedProject> {\n const absDir = resolve(dir);\n const entries = listFunctionModuleFiles(absDir);\n const cacheDir = resolveCacheDir(absDir);\n\n const schemaFile = existsSync(join(absDir, \"schema.ts\")) ? \"schema.ts\" : \"schema.js\";\n const schemaModule = (await bundleAndImport(join(absDir, schemaFile), \"schema\", cacheDir)) as {\n default: SchemaDefinition;\n };\n\n const modules: Record<string, Record<string, unknown>> = {};\n for (const file of entries) {\n const key = moduleKeyForFile(file);\n modules[key] = await bundleAndImport(join(absDir, file), key, cacheDir);\n }\n\n return { schema: schemaModule.default, modules };\n}\n","/**\n * The push pipeline: load the project → run codegen → return artifacts. `helipod dev` runs\n * this on startup and on every file change (hot reload re-runs `push` and re-registers the\n * module map with the running engine — no restart).\n */\nimport { generateAll, type GeneratedBundle } from \"@helipod/codegen\";\nimport type { ComponentDefinition } from \"@helipod/component\";\nimport { loadProject, type LoadedProject, type ProjectArtifacts } from \"./project\";\n\nexport interface PushResult {\n project: ProjectArtifacts;\n generated: GeneratedBundle;\n}\n\nexport function push(\n loaded: LoadedProject,\n components: ComponentDefinition[] = [],\n existingTableNumbers?: Record<string, number>,\n): PushResult {\n const project = loadProject(loaded, components, existingTableNumbers);\n const generated = generateAll({\n schema: project.schemaJson,\n manifest: project.manifest,\n tableNumbers: project.tableNumbers,\n components: components.map((c) => ({ name: c.name, contextType: c.contextType, serverExports: c.serverExports })),\n });\n return { project, generated };\n}\n","/**\n * The shared boot core for `helipod dev` and `helipod serve`: load the project, compose\n * app + components, open the SQLite store, build the embedded runtime + admin API. Neither writes\n * codegen nor starts a server — the callers own those (dev writes _generated + watches; serve\n * hardens + serves).\n */\nimport { mkdirSync, readFileSync, accessSync, constants as fsConstants } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { NodeSqliteAdapter, BunSqliteAdapter, SqliteDocStore } from \"@helipod/docstore-sqlite\";\nimport { NodePgClient, BunSqlClient, PostgresDocStore, type PgClient } from \"@helipod/docstore-postgres\";\nimport type { DocStore } from \"@helipod/docstore\";\nimport {\n createEmbeddedRuntime,\n type EmbeddedRuntime,\n type WriteRouter,\n type EmbeddedWriteFanoutAdapter,\n} from \"@helipod/runtime-embedded\";\nimport { InMemoryLogSink } from \"@helipod/executor\";\nimport { AdminApi, browseTableModule, systemModules, verifyAdminKey } from \"@helipod/admin\";\nimport type { GeneratedBundle } from \"@helipod/codegen\";\nimport type { ComponentDefinition, Driver, WakeHost } from \"@helipod/component\";\nimport type { RegisteredFunction } from \"@helipod/executor\";\nimport type { JSONValue } from \"@helipod/values\";\nimport type { BlobStore } from \"@helipod/blobstore\";\nimport type { ObjectStore } from \"@helipod/objectstore\";\nimport { shardIdList, DEFAULT_SHARD } from \"@helipod/id-codec\";\nimport {\n storageContextProvider,\n storageReaper,\n storageModules,\n storageRoutes,\n type StorageRoute,\n type StorageRouteDeps,\n} from \"@helipod/storage\";\nimport { receiptsReaper } from \"@helipod/receipts\";\nimport { makeBlobStore, isS3Config, resolveStorageConfig, type StorageConfig } from \"./blobstore-select\";\nimport { resolveObjectStore } from \"./objectstore-select\";\nimport { ReplicaWriteForwarder } from \"./replica-forward\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { detectRuntime } from \"./dev-options\";\nimport type { ProjectArtifacts, LoadedProject } from \"./project\";\n\n/** True when `s` looks like a `postgres://`/`postgresql://` connection string (pure — no I/O). */\nexport function isPostgresUrl(s: string | undefined): boolean {\n return !!s && /^postgres(ql)?:\\/\\//.test(s);\n}\n\n/**\n * Build the `PgClient` for a postgres `--database-url`/`HELIPOD_DATABASE_URL`. Under the Bun\n * runtime (the single-binary/`serve` production runtime) uses `BunSqlClient` — native `Bun.SQL`,\n * ~10-17% faster than the `pg` driver; under Node (or any non-Bun host) falls back to `NodePgClient`.\n * Both implement the same `PgClient` seam, so `PostgresDocStore` and everything downstream is\n * unaffected by which one gets picked.\n */\nexport function makePgClient(connectionString: string): PgClient {\n return detectRuntime() === \"bun\" ? new BunSqlClient({ connectionString }) : new NodePgClient({ connectionString });\n}\n\nexport function makeStore(opts: { dataPath: string; databaseUrl?: string }): DocStore {\n if (isPostgresUrl(opts.databaseUrl)) {\n return new PostgresDocStore(makePgClient(opts.databaseUrl!));\n }\n mkdirSync(dirname(resolve(opts.dataPath)), { recursive: true });\n const adapter =\n detectRuntime() === \"bun\" ? new BunSqliteAdapter({ path: opts.dataPath }) : new NodeSqliteAdapter({ path: opts.dataPath });\n return new SqliteDocStore(adapter);\n}\n\n// ── Tier 3 Slice 6 (Task 6.3): the object-storage writer node ──────────────────────────────────\n// `helipod serve --object-store <url>` boots a single-shard (shard \"0\") writer node whose store is\n// the Tier 3 object-storage substrate (`@helipod/objectstore-substrate`) instead of the usual\n// SQLite/Postgres store. Mirrors the fleet-store-bypass shape: `bootLoaded`'s `store = opts.fleet?.\n// store ?? objectStoreOverride ?? makeStore(...)`. The substrate is an ENTERPRISE (`ee/`) package —\n// core `packages/cli` keeps ZERO static/type dependency on it (same discipline `serve.ts`'s\n// `FleetModule` applies to `@helipod/fleet`): the shapes below are hand-declared structural\n// mirrors, loaded only via a dynamic, non-literal `import()` so `tsc`/bundlers never resolve it\n// either. A deployment that never sets `--object-store` pays nothing — the import is never reached.\n\n/** The subset of `ObjectStoreDocStore`'s API this module drives directly (`acquire`/`heartbeat`/\n * `release`, plus the full `DocStore` surface every other boot code path already expects). */\nexport interface ObjectStoreWriterStore extends DocStore {\n acquire(opts: {\n writerId: string;\n leaseTtlMs: number;\n now: number;\n }): Promise<{ acquired: true } | { acquired: false; heldBy: string; expiresAt: number }>;\n heartbeat(opts: { now: number; leaseTtlMs: number }): Promise<void>;\n release(): void;\n /** Tier 3 Slice 6, Task 6.5: the graceful-shutdown variant of `release()` — best-effort CAS-clears\n * the lease in the bucket itself so a challenger's `acquire()` takes over immediately instead of\n * waiting out the full TTL. See `ObjectStoreDocStore.relinquish()`'s doc. */\n relinquish(): Promise<void>;\n /** Tier 3 Slice 7, Task 7.1/7.2: best-effort, self-fencing reclamation of superseded segments/\n * snapshots. Driven automatically on a cadence by the gc-driver (Task 7.3) once registered. */\n gc(): Promise<{ deletedSegments: number; deletedSnapshots: number }>;\n}\n\n/** Structural mirror of `@helipod/objectstore-substrate`'s public surface this module needs. */\nexport interface ObjectStoreSubstrateModule {\n ObjectStoreDocStore: {\n open(opts: { objectStore: ObjectStore; shard: string; local: SqliteDocStore }): Promise<ObjectStoreWriterStore>;\n };\n /** Tier 3 multi-shard single-node serve: the N-lane composite DocStore — routes writes by\n * `shardId` to the owning lane, fans reads out + merges across lanes (k-way merge for ordered\n * index scans). Constructed over a `Map<shardId, ObjectStoreDocStore>` when `--shards N` (N>1). */\n ShardedObjectStoreDocStore: new (\n lanes: ReadonlyMap<string, DocStore>,\n opts?: { defaultShard?: string },\n ) => DocStore;\n ensureGlobals(\n objectStore: ObjectStore,\n globals: { deploymentId: string; numShards: number },\n ): Promise<{ deploymentId: string; numShards: number }>;\n leaseHeartbeatDriver(\n store: { heartbeat(opts: { now: number; leaseTtlMs: number }): Promise<void> },\n opts: { leaseTtlMs: number; heartbeatMs: number; onFenced?: (e: Error) => void },\n ): Driver;\n gcDriver(\n store: { gc(): Promise<{ deletedSegments: number; deletedSnapshots: number }> },\n opts: { sweepMs: number },\n ): Driver;\n /** Tier 3 Slice 8, Task 8.2: the replica reactive-tailer wiring helper (Task 8.1). `runtime` is\n * typed as the real `EmbeddedRuntime` here (already a core, non-enterprise import in this\n * module) rather than the ee package's own narrower structural mirror — `EmbeddedRuntime`\n * satisfies it, and the real substrate module accepts anything shaped like it at runtime. */\n startReplicaReactiveTailer(opts: {\n runtime: EmbeddedRuntime;\n objectStore: ObjectStore;\n shard: string;\n local: SqliteDocStore;\n consumerId: string;\n pollMs?: number;\n }): { stop(): Promise<void> };\n /** Tier 3 Slice 8, Task 8.2: deregister a departed consumer's watermark (shutdown). */\n removeConsumer(objectStore: ObjectStore, shard: string, consumerId: string): Promise<void>;\n /** Object-storage reshard (offline): change a STOPPED deployment's shard count N→M by physically\n * re-partitioning each doc's current state to `shardIdForKeyValue(doc[shardKey], M)`'s lane. */\n reshardObjectStore(opts: {\n objectStore: ObjectStore;\n toShards: number;\n now: number;\n shardKeyFor: (tableNumber: number) => string | null;\n makeLocal: () => SqliteDocStore;\n }): Promise<{ fromShards: number; toShards: number; movedDocs: number; perLaneCounts: Record<string, number> }>;\n}\n\nexport const OBJECTSTORE_SUBSTRATE_ERR_NO_PACKAGE =\n \"helipod: --object-store requires @helipod/objectstore-substrate — install it (bun add @helipod/objectstore-substrate).\";\n\n/**\n * True when `e` is one of this module's object-store fail-fast BOOT errors — the ee-package-missing\n * gate (`OBJECTSTORE_SUBSTRATE_ERR_NO_PACKAGE`), `acquireWithRetry`'s \"held by '<writer>' until …\"\n * timeout, and every `resolveObjectStore` parse/validation throw (bad scheme, missing bucket,\n * missing credentials, unparseable URL) — all of which share the `\"helipod: --object-store\"` /\n * `\"helipod: invalid --object-store\"` message prefix. `serveCommand` uses this to print a clean\n * `✗ <message>` instead of a raw stack trace for these KNOWN, actionable misconfigurations.\n *\n * Deliberately narrow: it does NOT match `assertCasSupported()`'s runtime bucket-connectivity\n * errors (a live AWS SDK network/permissions failure, unprefixed) — those are left to surface with\n * their full stack, since misclassifying a genuine crash as a tidy one-liner would hide the real\n * cause.\n */\nexport function isObjectStoreBootFailFast(e: unknown): e is Error {\n return e instanceof Error && /^helipod: (--object-store|invalid --object-store)\\b/.test(e.message);\n}\n\n/** Dynamic-import gate for the ee substrate package (mirrors `serve.ts`'s `@helipod/fleet` gate:\n * an indirect (non-literal) specifier so `tsc` never statically resolves the enterprise package). */\nexport async function loadObjectStoreSubstrateModule(): Promise<ObjectStoreSubstrateModule> {\n try {\n const specifier: string = \"@helipod/objectstore-substrate\";\n return (await import(specifier)) as unknown as ObjectStoreSubstrateModule;\n } catch {\n throw new Error(OBJECTSTORE_SUBSTRATE_ERR_NO_PACKAGE);\n }\n}\n\n/** Bounded retry over `store.acquire(...)` (Task 6.3): `acquire()` is a single attempt that returns\n * `{acquired:false, heldBy, expiresAt}` when a DIFFERENT live writer currently holds the shard —\n * this polls until acquired or `timeoutMs` elapses, then fails fast with a clear \"held by\" message.\n * A crashed predecessor's lease simply expires on its own (no CAS involved in expiry), so a fresh\n * boot's retry loop takes over automatically once `timeoutMs` covers the remaining TTL — no manual\n * intervention needed for the common failover case. Exported for direct unit testing (no bucket\n * needed — a fake `{acquire}` is enough). */\nexport async function acquireWithRetry(\n store: Pick<ObjectStoreWriterStore, \"acquire\">,\n opts: { writerId: string; leaseTtlMs: number; timeoutMs: number; pollIntervalMs?: number; now?: () => number },\n): Promise<void> {\n const now = opts.now ?? Date.now;\n const pollIntervalMs = opts.pollIntervalMs ?? 1000;\n const deadline = now() + opts.timeoutMs;\n let last: { heldBy: string; expiresAt: number } | undefined;\n for (;;) {\n const result = await store.acquire({ writerId: opts.writerId, leaseTtlMs: opts.leaseTtlMs, now: now() });\n if (result.acquired) return;\n last = { heldBy: result.heldBy, expiresAt: result.expiresAt };\n if (now() >= deadline) {\n throw new Error(\n `helipod: --object-store shard \"0\" held by '${last.heldBy}' until ${new Date(last.expiresAt).toISOString()} — ` +\n `timed out after ${opts.timeoutMs}ms waiting for the lease to free up. If '${last.heldBy}' crashed, its lease ` +\n `will expire on its own and a retry will take over; otherwise stop that writer before starting this one.`,\n );\n }\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n }\n}\n\n/** Construct the concrete `SqliteDocStore` the substrate's `ObjectStoreDocStore.open()` needs as its\n * local materialize target — the same adapter-selection logic as `makeStore`'s SQLite branch, but\n * narrowly typed to `SqliteDocStore` (not the widened `DocStore`) since `open()` calls SQLite-\n * specific methods (`dumpCurrentState`) the generic `DocStore` interface doesn't declare. Always\n * SQLite regardless of `--database-url` — the object-store path's local cache is never Postgres. */\nfunction makeLocalSqliteStore(dataPath: string): SqliteDocStore {\n mkdirSync(dirname(resolve(dataPath)), { recursive: true });\n const adapter =\n detectRuntime() === \"bun\" ? new BunSqliteAdapter({ path: dataPath }) : new NodeSqliteAdapter({ path: dataPath });\n return new SqliteDocStore(adapter);\n}\n\n/** A throwaway in-memory `SqliteDocStore` (runtime-appropriate adapter) — the `objectstore reshard`\n * tool's per-lane materialization/commit target (`reshardObjectStore`'s `makeLocal`). Exported so the\n * reshard command can hand it in without re-deriving the Bun-vs-Node adapter pick. */\nexport function makeInMemorySqliteStore(): SqliteDocStore {\n const adapter =\n detectRuntime() === \"bun\" ? new BunSqliteAdapter({ path: \":memory:\" }) : new NodeSqliteAdapter({ path: \":memory:\" });\n return new SqliteDocStore(adapter);\n}\n\n/** Mirrors `@helipod/runtime-embedded`'s own private `DEPLOYMENT_ID_GLOBAL_KEY` (and\n * `@helipod/fleet`'s exported `FLEET_DEPLOYMENT_ID_KEY`) — the same well-known magic string, not\n * otherwise exported for cross-package reuse (fleet re-declares its own copy too). `createEmbeddedRuntime`\n * reads-or-mints this global on `options.store` right after boot; pre-seeding it here (carried note\n * I1) makes a fresh local materialization ADOPT the bucket's `FleetGlobals.deploymentId` instead of\n * the runtime minting a brand-new one — which would otherwise flip every outbox client to\n * `known:false` on a from-scratch node. `writeGlobalIfAbsent` no-ops if this dataPath already carries\n * a value (a same-node restart) — never overwrite an existing stamp. */\nconst RUNTIME_DEPLOYMENT_ID_GLOBAL_KEY = \"fleet:deploymentId\";\n\n/** Default lease TTL (ms) — mirrors `@helipod/fleet`'s own default (`HELIPOD_FLEET_LEASE_TTL_MS`\n * unset case). Overridable via `bootLoaded`'s `objectStoreLeaseTtlMs` (tests only; not a CLI flag). */\nexport const DEFAULT_OBJECTSTORE_LEASE_TTL_MS = 15000;\n/** Default heartbeat cadence (ms) — comfortably under the lease TTL (see `leaseHeartbeatDriver`'s own\n * `heartbeatMs < leaseTtlMs` assertion). */\nexport const DEFAULT_OBJECTSTORE_HEARTBEAT_MS = 5000;\n/** Default gc-driver sweep cadence (ms) — Tier 3 Slice 7, Task 7.3. gc() is best-effort/idempotent/\n * self-fencing (Task 7.1), so there's no correctness ratio to enforce against the lease TTL the way\n * the heartbeat has — this is purely a reclamation-latency-vs-sweep-cost tradeoff, mirroring\n * `storageReaper`'s own 60s default. Overridable via `HELIPOD_OBJECTSTORE_GC_MS` (env, production\n * tuning) or `bootLoaded`'s `objectStoreGcMs` option (tests). */\nexport const DEFAULT_OBJECTSTORE_GC_MS = 60000;\n\n/**\n * Build (ee-gate → resolve → adopt globals → materialize → acquire) a Tier 3 object-storage writer\n * node's store (Task 6.3). Returns the store to use at the `opts.fleet?.store ?? …` seam, any extra\n * drivers to register (the lease-heartbeat), and a `release` handle for graceful shutdown — which\n * calls `store.relinquish()` (Task 6.5), NOT the in-process-only `store.release()`, so a challenger\n * can take over the shard immediately instead of waiting out the full lease TTL. Throws (fail-fast)\n * on: a CAS-unsupported object store, `@helipod/objectstore-substrate` not installed, or a\n * bounded-retry acquire timeout (another live writer holds the shard).\n */\nasync function buildObjectStoreWriterNode(opts: {\n objectStoreUrl: string;\n dataPath: string;\n onFenced?: (e: Error) => void;\n leaseTtlMs?: number;\n heartbeatMs?: number;\n acquireTimeoutMs?: number;\n /** Test-only: shorten `acquireWithRetry`'s poll cadence (default 1000ms) so a short-`leaseTtlMs`\n * takeover test doesn't wait a full second per retry. Not surfaced as a CLI flag. */\n acquirePollIntervalMs?: number;\n writerId?: string;\n /** Tier 3 Slice 7, Task 7.3: the gc-driver's sweep cadence — unset → `DEFAULT_OBJECTSTORE_GC_MS`. */\n gcMs?: number;\n /** Tier 3 multi-shard single-node serve: the number of object-storage lanes this ONE node owns.\n * Unset / `<= 1` → the shipped single-shard path (one `ObjectStoreDocStore` over shard \"0\",\n * byte-identical to before). `> 1` → this node opens+acquires+heartbeats+gcs EVERY lane in\n * `shardIdList(shards)` (`[\"default\",\"s1\",…]`) and composes them behind a\n * `ShardedObjectStoreDocStore`; the engine's `numShards`-sized `ShardedTransactor` then routes\n * each write to its owning lane and reads fan out + merge across all lanes. */\n shards?: number;\n}): Promise<{ store: DocStore; drivers: Driver[]; release: () => Promise<void>; numShards: number }> {\n const resolved = resolveObjectStore(opts.objectStoreUrl);\n if (resolved === null) {\n throw new Error(`helipod: --object-store \"${opts.objectStoreUrl}\" did not resolve to a store (empty/unset value?).`);\n }\n await resolved.objectStore.assertCasSupported();\n\n const substrate = await loadObjectStoreSubstrateModule();\n const writerId = opts.writerId ?? randomUUID();\n const leaseTtlMs = opts.leaseTtlMs ?? DEFAULT_OBJECTSTORE_LEASE_TTL_MS;\n const heartbeatMs = opts.heartbeatMs ?? DEFAULT_OBJECTSTORE_HEARTBEAT_MS;\n // A crashed predecessor's lease is only reclaimable once it expires — give the retry window enough\n // room to actually observe that (leaseTtlMs) plus a margin for polling/clock skew, unless overridden.\n const acquireTimeoutMs = opts.acquireTimeoutMs ?? leaseTtlMs + 5000;\n const gcMs = opts.gcMs ?? DEFAULT_OBJECTSTORE_GC_MS;\n\n // Slice-4 carried note I1: adopt the bucket's existing deployment identity (never overwrite it) —\n // a fresh deployment mints one here (non-determinism is fine at this CLI-adjacent layer). The\n // `numShards` passed is the DESIRED count for a FRESH bucket (from `--shards`); `ensureGlobals`\n // ADOPTS an existing bucket's count, so the RETURN value is authoritative below.\n const desiredShards = opts.shards && opts.shards > 1 ? opts.shards : 1;\n const globals = await substrate.ensureGlobals(resolved.objectStore, {\n deploymentId: randomUUID(),\n numShards: desiredShards,\n });\n\n // The bucket's PERSISTED shard count is authoritative — a resharded bucket (its globals set by\n // `objectstore reshard`) boots the right lanes without the operator re-specifying `--shards`. A\n // `--shards` that disagrees fails fast (reshard the bucket to change the count, never silently\n // mis-open lanes against the existing layout). The lane bucket prefixes: `numShards === 1` → the\n // single \"0\" lane (born-single-shard OR resharded-to-1 — one unambiguous layout per count);\n // `> 1` → the canonical `shardIdList` ids (identity with the engine's routing shardIds).\n const numShards = globals.numShards;\n if (opts.shards !== undefined && opts.shards !== numShards) {\n throw new Error(\n `helipod: --shards ${opts.shards} disagrees with the bucket's persisted shard count ${numShards} — ` +\n `reshard the bucket (\\`helipod objectstore reshard --object-store <url> --dir <dir> --shards ${opts.shards}\\`) ` +\n `to change it, or drop --shards.`,\n );\n }\n const shardIds: string[] = numShards > 1 ? [...shardIdList(numShards)] : [\"0\"];\n\n // Build ONE lane: open (materialize its own local SQLite) → seed the runtime's deployment-id\n // global so `createEmbeddedRuntime` adopts the bucket's identity → acquire its lease → arm its\n // heartbeat + gc drivers. Each lane is an independent `s{shardId}/…` prefix + local file.\n const buildLane = async (\n shardId: string,\n laneDataPath: string,\n ): Promise<{ lane: ObjectStoreWriterStore; heartbeat: Driver; gc: Driver }> => {\n const local = makeLocalSqliteStore(laneDataPath);\n const lane = await substrate.ObjectStoreDocStore.open({ objectStore: resolved.objectStore, shard: shardId, local });\n await lane.writeGlobalIfAbsent(RUNTIME_DEPLOYMENT_ID_GLOBAL_KEY, globals.deploymentId);\n await acquireWithRetry(lane, {\n writerId,\n leaseTtlMs,\n timeoutMs: acquireTimeoutMs,\n ...(opts.acquirePollIntervalMs !== undefined ? { pollIntervalMs: opts.acquirePollIntervalMs } : {}),\n });\n const heartbeat = substrate.leaseHeartbeatDriver(lane, {\n leaseTtlMs,\n heartbeatMs,\n onFenced: (e) => opts.onFenced?.(e),\n });\n // Tier 3 Slice 7, Task 7.3: the periodic reclamation driver — self-fencing/best-effort (Task 7.1),\n // so it needs no `onFenced`-style shutdown wiring the way the heartbeat does.\n const gc = substrate.gcDriver(lane, { sweepMs: gcMs });\n return { lane, heartbeat, gc };\n };\n\n // Lanes are built SEQUENTIALLY (each acquire may retry against a crashed predecessor's TTL, and a\n // fresh multi-shard node acquiring all lanes serially is fine at boot). Single-shard keeps the\n // exact `opts.dataPath`; multi-shard gives each lane its own `<dataPath>.<shardId>` local file.\n const built: Array<{ shardId: string; lane: ObjectStoreWriterStore; heartbeat: Driver; gc: Driver }> = [];\n for (const shardId of shardIds) {\n const laneDataPath = numShards > 1 ? `${opts.dataPath}.${shardId}` : opts.dataPath;\n built.push({ shardId, ...(await buildLane(shardId, laneDataPath)) });\n }\n\n const drivers = built.flatMap((b) => [b.heartbeat, b.gc]);\n // Graceful shutdown relinquishes EVERY owned lane's bucket lease (best-effort, in parallel) so a\n // successor takes each over immediately rather than waiting out the TTL — see `relinquish()`'s doc.\n const release = async (): Promise<void> => {\n await Promise.all(built.map((b) => b.lane.relinquish()));\n };\n\n if (numShards === 1) return { store: built[0]!.lane, drivers, release, numShards };\n\n // Multi-shard: compose the lanes behind the routing/merging `ShardedObjectStoreDocStore`. Its\n // default lane (\"default\") is `shardIdList(N)[0]` — always present — and is where deployment-level\n // globals/receipts resolve (a single source of truth), matching `ensureGlobals`' own default.\n const lanes = new Map<string, DocStore>(built.map((b) => [b.shardId, b.lane]));\n const store = new substrate.ShardedObjectStoreDocStore(lanes, { defaultShard: DEFAULT_SHARD });\n return { store, drivers, release, numShards };\n}\n\n// ── Tier 3 Slice 8 (Task 8.2): the object-storage REPLICA node ─────────────────────────────────\n// `helipod serve --object-store <url> --replica` boots a read-scaled REPLICA instead of a writer:\n// it MATERIALIZES the shard from the bucket (`ObjectStoreDocStore.open`, same as the writer) but\n// NEVER `acquire()`s the write lease, and runs no heartbeat/gc drivers — only the Task 8.1 reactive-\n// tailer wiring helper (`startReplicaReactiveTailer`), started AFTER the runtime is built (its sink\n// needs the runtime; see `replica-wiring.ts`'s module doc for the chicken-and-egg). Mutation\n// rejection is then FREE: `commitWriteBatch` already throws \"not the lease owner\" for an\n// unacquired store — `wrapReplicaWriteRejection` below only improves that message's wording.\n\n/** Tier 3 Slice 8, Task 8.2: the DX-clear message a mutation sees when routed to a `--replica`\n * node, in place of the substrate's internal \"not the lease owner\" wording (accurate, but not\n * meaningful to an app developer who doesn't know the substrate's lease vocabulary). See\n * `wrapReplicaWriteRejection`'s doc. */\nexport const REPLICA_WRITE_REJECTED_MESSAGE =\n \"helipod: this node is a read replica (--replica) — it holds no write lease and cannot commit \" +\n \"mutations. Send writes to the primary/writer node.\";\n\nconst LEASE_OWNER_REJECTION_RE = /not the lease owner/;\n\n/**\n * Decorate `store` so `commitWrite`/`commitWriteBatch` re-throw `REPLICA_WRITE_REJECTED_MESSAGE` in\n * place of `ObjectStoreDocStore`'s internal \"not the lease owner\" error — every other error (a\n * genuine bug, a validation failure) and every other `DocStore` method (reads, globals, close, …)\n * pass through UNCHANGED.\n *\n * Implemented as a `Proxy` whose `get` trap `.bind(target)`s every forwarded function to the REAL\n * underlying instance rather than the proxy itself — required because `ObjectStoreDocStore` uses a\n * genuine JS private method internally (`#maybeSnapshotBestEffort`, called from inside its own\n * `commitWriteBatch`); invoking a method with `this` bound to a Proxy instead of the real instance\n * would throw (\"cannot read private member from an object whose class did not declare it\") the\n * moment that private access executes. `.bind(target)` sidesteps the hazard without needing to\n * enumerate `DocStore`'s ~20 methods by hand (mirroring `ObjectStoreDocStore`'s own \"everything\n * else: forward\" section, but generically, over whatever `DocStore` happens to declare).\n */\nexport function wrapReplicaWriteRejection(store: DocStore): DocStore {\n return new Proxy(store, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver) as unknown;\n if (typeof value !== \"function\") return value;\n const bound = (value as (...args: unknown[]) => unknown).bind(target);\n if (prop !== \"commitWrite\" && prop !== \"commitWriteBatch\") return bound;\n return async (...args: unknown[]): Promise<unknown> => {\n try {\n return await bound(...args);\n } catch (e) {\n if (e instanceof Error && LEASE_OWNER_REJECTION_RE.test(e.message)) {\n throw new Error(REPLICA_WRITE_REJECTED_MESSAGE);\n }\n throw e;\n }\n };\n },\n });\n}\n\n/** Test-only default when `bootLoaded`'s `objectStoreReplicaConsumerId` is unset — a per-process\n * random id so N replicas over one bucket never collide on the same `s{shard}/consumers/{id}` key. */\nfunction defaultReplicaConsumerId(): string {\n return `replica-${randomUUID()}`;\n}\n\n/** Default poll interval (ms) for a replica's reactive tailer (Task 8.2) — mirrors\n * `ObjectStoreReplicaTailer`'s own shipped default. Overridable via `bootLoaded`'s\n * `objectStoreReplicaPollMs` (tests only; not a CLI flag). */\nexport const DEFAULT_OBJECTSTORE_REPLICA_POLL_MS = 1000;\n\n/**\n * Build (ee-gate → resolve → adopt globals → materialize, NO acquire) a Tier 3 object-storage\n * REPLICA node's store (Task 8.2, design record §7/§8; multi-shard generalization\n * `docs/superpowers/plans/2026-02-20-multi-shard-replicas.md`). Unlike `buildObjectStoreWriterNode`,\n * this never calls `acquire()` — the returned store rejects every mutation for free (the class doc's\n * \"the neat part\"), surfaced via `wrapReplicaWriteRejection`'s clear DX message.\n *\n * The lane count is read from the bucket's `globals.numShards` (authoritative — a replica has no\n * `--shards` flag): `numShards === 1` opens the single \"0\" lane (byte-identical to the shipped path);\n * `> 1` opens one materialize-only lane per `shardIdList(numShards)` id and composes them behind the\n * shipped `ShardedObjectStoreDocStore` read composite. Every mutation is single-lane, so the N lanes\n * are tailed INDEPENDENTLY (no cross-lane ordering); `observeTimestamp` is monotonic-max so the N\n * per-lane tailers advancing the same runtime's oracle is safe.\n *\n * Returns the store to use at `bootLoaded`'s store seam, its `numShards` (so `bootLoaded` sizes the\n * runtime's `ShardedTransactor`/composite to match, exactly like the writer path), plus\n * `attachTailer(runtime)` — call this AFTER `createEmbeddedRuntime` builds the replica's own runtime\n * (the tailer's sink needs it; see `replica-wiring.ts`'s module doc for why this can't be a driver\n * passed INTO the runtime itself). `attachTailer` starts one `startReplicaReactiveTailer` PER LANE and\n * returns a `release()` handle that stops every tailer AND `removeConsumer`s every lane's watermark\n * (so a departed replica stops pinning ANY lane's writer gc) — the shutdown handle `bootLoaded` threads\n * out as `BootResult.objectStoreRelease`, same field the writer path uses (mutually exclusive by\n * construction — `serve.ts` calls whichever one boot actually built, identically either way).\n */\nasync function buildObjectStoreReplicaNode(opts: {\n objectStoreUrl: string;\n dataPath: string;\n /** Test-only: force a deterministic consumer-watermark id. Unset → `defaultReplicaConsumerId()`. */\n consumerId?: string;\n /** Test-only: shorten the tailer's poll cadence. Unset → `DEFAULT_OBJECTSTORE_REPLICA_POLL_MS`. */\n pollMs?: number;\n}): Promise<{\n store: DocStore;\n numShards: number;\n attachTailer: (runtime: EmbeddedRuntime) => () => Promise<void>;\n}> {\n const resolved = resolveObjectStore(opts.objectStoreUrl);\n if (resolved === null) {\n throw new Error(`helipod: --object-store \"${opts.objectStoreUrl}\" did not resolve to a store (empty/unset value?).`);\n }\n await resolved.objectStore.assertCasSupported();\n\n const substrate = await loadObjectStoreSubstrateModule();\n const objectStore = resolved.objectStore;\n\n // Same adopt-not-mint identity discipline as the writer path (see `RUNTIME_DEPLOYMENT_ID_GLOBAL_KEY`'s\n // doc comment) — a replica must NEVER mint a fresh deploymentId; it always adopts whatever the bucket\n // (established by the writer, or an earlier node) already carries. The RETURNED count is authoritative:\n // a multi-shard bucket (writer `--shards N`, or `objectstore reshard`) boots the right lanes here.\n const globals = await substrate.ensureGlobals(objectStore, { deploymentId: randomUUID(), numShards: 1 });\n const numShards = globals.numShards;\n const shardIds: string[] = numShards > 1 ? [...shardIdList(numShards)] : [\"0\"];\n\n // Open + MATERIALIZE each lane (NO acquire — Tier 3 Slice 4's `open()` claims no ownership). Each lane\n // gets its own local SQLite file: `<dataPath>.<shardId>` for multi-shard; the bare `dataPath` for the\n // byte-identical single \"0\" lane.\n const lanes: Array<{ shardId: string; store: DocStore; local: SqliteDocStore }> = [];\n for (const shardId of shardIds) {\n const laneDataPath = numShards > 1 ? `${opts.dataPath}.${shardId}` : opts.dataPath;\n const local = makeLocalSqliteStore(laneDataPath);\n const laneStore = await substrate.ObjectStoreDocStore.open({ objectStore, shard: shardId, local });\n await laneStore.writeGlobalIfAbsent(RUNTIME_DEPLOYMENT_ID_GLOBAL_KEY, globals.deploymentId);\n lanes.push({ shardId, store: laneStore, local });\n }\n\n // Single lane → the store directly (byte-identical). Multi-shard → the shipped fan-out+merge composite,\n // whose default lane is `shardIdList(N)[0] === \"default\"` (where deployment-level globals resolve).\n const composite: DocStore =\n numShards === 1\n ? lanes[0]!.store\n : new substrate.ShardedObjectStoreDocStore(new Map(lanes.map((l) => [l.shardId, l.store])), {\n defaultShard: DEFAULT_SHARD,\n });\n const store = wrapReplicaWriteRejection(composite);\n\n const baseConsumerId = opts.consumerId ?? defaultReplicaConsumerId();\n const pollMs = opts.pollMs ?? DEFAULT_OBJECTSTORE_REPLICA_POLL_MS;\n // Per-lane watermark id: the BARE `baseConsumerId` for the single \"0\" lane (byte-compat — the shipped\n // replica E2E asserts `s0/consumers/<id>`); `${baseConsumerId}:${shardId}` per lane for multi-shard,\n // so each lane's watermark lives under its own `s{shard}/consumers/` and floors only THAT lane's gc.\n const laneConsumerId = (shardId: string): string => (numShards === 1 ? baseConsumerId : `${baseConsumerId}:${shardId}`);\n\n return {\n store,\n numShards,\n attachTailer: (runtime: EmbeddedRuntime) => {\n // One tailer per lane, all driving the SAME runtime's reactive fan-out.\n const handles = lanes.map((l) =>\n substrate.startReplicaReactiveTailer({\n runtime,\n objectStore,\n shard: l.shardId,\n local: l.local,\n consumerId: laneConsumerId(l.shardId),\n pollMs,\n }),\n );\n return async () => {\n await Promise.all(handles.map((h) => h.stop()));\n await Promise.all(lanes.map((l) => substrate.removeConsumer(objectStore, l.shardId, laneConsumerId(l.shardId))));\n };\n },\n };\n}\n\n// ── Shards B2a (T5): NUM_SHARDS first-boot config ──────────────────────────────────────────────\n// Decided ONCE, at first boot, and immutable after: `HELIPOD_FLEET_SHARDS` (or the fleet\n// default of 8) is persisted via `writeGlobalIfAbsent` the first time the store is writable; every\n// later boot reads the persisted value back and fails fast if an explicitly-set env value now\n// disagrees with it (resharding online isn't supported — that's B5's offline tool).\n\n/** Default shard count when neither `HELIPOD_FLEET_SHARDS` nor a persisted value is present.\n * Mirrors `@helipod/fleet`'s own `DEFAULT_NUM_SHARDS` (kept as an independent literal here —\n * core `packages/cli` has zero static dependency on the enterprise `@helipod/fleet` package). */\nexport const DEFAULT_NUM_SHARDS = 8;\n\n/** The `persistence_globals` key the resolved shard count is stamped under (same store contract —\n * SQLite/Postgres, fleet/non-fleet — `getGlobal`/`writeGlobalIfAbsent` all implement it). */\nexport const NUM_SHARDS_GLOBAL_KEY = \"fleet:numShards\";\n\n/** Parse `HELIPOD_FLEET_SHARDS` — a positive integer, else undefined (falls through to the\n * persisted value, or the default on a fresh deployment). Mirrors `serve.ts`'s\n * `parseLeaseTtlMs` shape for the other fleet-adjacent env knob. */\nexport function parseNumShards(raw: string | undefined): number | undefined {\n if (raw === undefined || raw.trim() === \"\") return undefined;\n const n = Number(raw);\n return Number.isFinite(n) && Number.isInteger(n) && n >= 1 ? n : undefined;\n}\n\n/**\n * Parse `HELIPOD_GROUP_COMMIT` (Fleet B4) — a boolean env flag, same `1`/`true`/`yes`\n * (case-insensitive) shape `@helipod/fleet`'s `fleetMultiWriterEnabled` uses for\n * `HELIPOD_FLEET_MULTI_WRITER`. This is just the token PARSER (truthy = `1`/`true`/`yes`); the\n * single-node DEFAULT when the var is unset is store-conditional — see `resolveGroupCommit`. Unlike `HELIPOD_FLEET_\n * SHARDS`, group commit needs no persist-once story: it's a per-boot transactor construction choice,\n * not a durable invariant the log depends on, so a plain env read (no `resolveNumShards`-style\n * mismatch-fail-fast) is the right shape.\n */\nexport function groupCommitEnabled(raw: string | undefined): boolean {\n return /^(1|true|yes)$/i.test(raw ?? \"\");\n}\n\n/**\n * Resolve the single-node (non-fleet) group-commit default. An explicit `HELIPOD_GROUP_COMMIT`\n * always wins (either direction). When it is unset, the default is STORE-CONDITIONAL: ON for\n * Postgres, OFF for SQLite. Rationale (benchmark, `docs/dev/research/writes-benchmark.md`): group\n * commit batches concurrent commits into one fsync — a strict win on fsync-bound Postgres (+39% at\n * 8 clients, +58% at 64, and byte-identical latency at 1 client thanks to the opportunistic \"batch\n * of 1 when idle\" design, so no low-traffic regression) but a ~8% loss on CPU-bound in-memory\n * SQLite (nothing to amortize, pure pipeline overhead). Fleet B4 gated auto-enable on a single\n * GLOBAL 2× threshold and missed (1.63×), shipping dark-off; the per-store data shows the win is\n * store-dependent, so a store-conditional default is the correct refinement (scoped to the\n * single-node path — the fleet path still threads its own `HELIPOD_GROUP_COMMIT` read).\n */\nexport function resolveGroupCommit(opts: { envRaw: string | undefined; databaseUrl: string | undefined }): boolean {\n const raw = opts.envRaw;\n if (raw !== undefined && raw !== \"\") return groupCommitEnabled(raw); // explicit override, either way\n return isPostgresUrl(opts.databaseUrl); // default: ON for Postgres, OFF for SQLite\n}\n\n/** Build the fail-fast message for a `HELIPOD_FLEET_SHARDS` value that disagrees with what's\n * already persisted — named verbatim so tests can assert on it without re-deriving the string. */\nexport function numShardsMismatchError(envValue: number, persisted: number): Error {\n return new Error(\n `helipod: HELIPOD_FLEET_SHARDS=${envValue} conflicts with the shard count already persisted ` +\n `for this deployment (${persisted}, set at first boot). The shard count is immutable after ` +\n `first boot — changing it live isn't supported; resharding is a planned offline tool (B5). ` +\n `Unset HELIPOD_FLEET_SHARDS, or set it to ${persisted} to match the existing deployment.`,\n );\n}\n\n/**\n * Resolve NUM_SHARDS against `store`'s persisted `fleet:numShards` global: a persisted value wins\n * (immutable after first boot) — an explicitly-set `envValue` that disagrees fails fast, naming\n * both. No persisted value → `envValue ?? DEFAULT_NUM_SHARDS`, persisted now via\n * `writeGlobalIfAbsent` so every later boot (fleet or not) sees the same count. `store` must\n * already have run `setupSchema()` (the `persistence_globals` table must exist) — `getGlobal`/\n * `writeGlobalIfAbsent` are plain KV ops, not gated by a `DocStore`'s writer/read-only mode (a\n * fleet sync node's read-only Postgres client can call this too; see `serve.ts`'s fleet wiring,\n * which resolves before any node's writer-vs-sync election).\n *\n * Guards a concurrent-first-boot race (two nodes racing `writeGlobalIfAbsent` on a fresh\n * deployment with disagreeing envs): if this call loses the race (`writeGlobalIfAbsent` returns\n * false — a peer's row landed first), it re-reads the now-persisted value and re-applies the same\n * mismatch check against it, so a genuine env disagreement still fails fast instead of silently\n * running with whichever value happened to land in Postgres.\n */\nexport async function resolveNumShards(\n store: Pick<DocStore, \"getGlobal\" | \"writeGlobalIfAbsent\">,\n envValue: number | undefined,\n): Promise<number> {\n const persistedRaw = await store.getGlobal(NUM_SHARDS_GLOBAL_KEY);\n if (persistedRaw !== null) {\n const persisted = Number(persistedRaw);\n if (envValue !== undefined && envValue !== persisted) throw numShardsMismatchError(envValue, persisted);\n return persisted;\n }\n const resolved = envValue ?? DEFAULT_NUM_SHARDS;\n const wrote = await store.writeGlobalIfAbsent(NUM_SHARDS_GLOBAL_KEY, String(resolved));\n if (wrote) return resolved;\n // Lost a concurrent first-boot race — adopt whichever value actually landed, and still enforce\n // the mismatch check against OUR env (agreeing with our own losing guess no longer matters).\n const raced = Number(await store.getGlobal(NUM_SHARDS_GLOBAL_KEY));\n if (envValue !== undefined && envValue !== raced) throw numShardsMismatchError(envValue, raced);\n return raced;\n}\n\nexport interface BootResult {\n runtime: EmbeddedRuntime;\n adminApi: AdminApi;\n project: ProjectArtifacts;\n generated: GeneratedBundle;\n store: DocStore;\n logSink: InMemoryLogSink;\n /** The boot-time component set (from helipod.config.ts) — `applyDeploy` re-composes against it. */\n components: ComponentDefinition[];\n /** The always-on file-storage byte backend (FS or S3), shared by the provider/reaper/routes. */\n blobStore: BlobStore;\n /**\n * The engine-owned `/api/storage/*` handlers (upload/confirm/serve). Reserved-path routes the\n * server splices into its dispatch (NOT user `http.ts` routes) — see `server.ts`.\n */\n storageRoutes: StorageRoute[];\n /**\n * Reserved engine routes contributed by composed components (e.g. `@helipod/auth`'s\n * `/api/auth/oauth/*`), each bound to `runtime.runHttpAction` and shaped as an engine-owned\n * `StorageRoute` `{method,pathPrefix,handler}` so `server.ts` dispatches them exactly like the\n * always-on storage routes. Fixed at boot (the component set is fixed at boot — only functions/\n * schema hot-swap), so no `setRoutes` live-swap is needed. Empty when no component declares routes.\n */\n componentRoutes: StorageRoute[];\n /**\n * Set only when `objectStoreUrl` was given — the object-store node's graceful-shutdown handle.\n * `serve.ts`'s shutdown calls this AFTER `server.close()` and BEFORE `store.close()`. Two shapes,\n * mutually exclusive by construction (at most one of `replica`/writer ever built this boot):\n * - Writer (Tier 3 Slice 6, Task 6.5): `store.relinquish()`, which best-effort CAS-clears the\n * lease IN THE BUCKET, not just in-process — see `ObjectStoreDocStore.relinquish()`'s doc —\n * so a challenger takes over immediately instead of waiting out the full TTL.\n * - Replica (Tier 3 Slice 8, Task 8.2): stops the reactive-tailer wiring helper (Task 8.1) and\n * `removeConsumer`s this replica's watermark, so a departed replica stops pinning the\n * writer's gc — see `buildObjectStoreReplicaNode`'s doc.\n */\n objectStoreRelease?: () => Promise<void>;\n /**\n * Tier 3 Slice 8 follow-on (replica write-forwarding): set only when this boot is a\n * `--replica` configured with `--writer-url` (i.e. a `ReplicaWriteForwarder` was wired in as\n * the runtime's `writeRouter`). `serve.ts` threads this straight through to\n * `startDevServer`'s `replicaWriterUrl` option, which arms `/api/run`'s single-hop defensive\n * guard (`http-handler.ts`). Absent whenever `--writer-url` is unset (the pre-existing\n * reject-with-message replica behavior, unchanged) or this isn't a replica boot at all.\n */\n replicaWriterUrl?: string;\n}\n\n/**\n * Merge the always-on `_storage:*` privileged built-ins into a function map. The `_storage` modules\n * must live in the runtime's `modules` map (not just `systemModules`) because the action-mode\n * `ctx.storage.store` reaches them through the trusted `invoke`, and the reaper driver through\n * `runFunction` — both resolve `modules`. Since `setModules` (dev reload / `helipod deploy`)\n * REPLACES `modules` wholesale, every such swap must re-apply this so storage survives a hot-swap.\n */\nexport function withStorageModules(map: Record<string, RegisteredFunction>): Record<string, RegisteredFunction> {\n return { ...map, ...storageModules };\n}\n\n/**\n * Fail fast when S3-shaped settings (`HELIPOD_STORAGE_ENDPOINT`/`REGION`/`PUBLIC_URL`, or their\n * `--storage-endpoint`/etc. flag equivalents) are present but no bucket was configured. Those\n * settings only make sense for the S3 backend, which is selected SOLELY by `HELIPOD_STORAGE_BUCKET`\n * (`isS3Config`) — so their presence without a bucket is an unambiguous misconfiguration by an\n * operator who intended S3 but forgot the bucket. Silently falling back to local FS in that case is\n * a data-durability footgun: uploads land on ephemeral local disk (gone on the next container\n * recreate) instead of the object store the operator configured. Refuse to boot with an actionable\n * error rather than start in a silently-wrong state. The AWS credential vars (`AWS_ACCESS_KEY_ID`/\n * `AWS_SECRET_ACCESS_KEY`) are intentionally NOT treated as S3 intent — they're commonly present for\n * unrelated reasons, so keying off them would false-positive on plain FS deployments.\n */\nexport function assertStorageConfigCoherent(storage: StorageConfig | undefined): void {\n if (isS3Config(storage)) return;\n const s3Shaped = storage?.endpoint !== undefined || storage?.region !== undefined || storage?.publicBaseUrl !== undefined;\n if (!s3Shaped) return;\n throw new Error(\n \"helipod: S3 storage settings (HELIPOD_STORAGE_ENDPOINT/REGION/PUBLIC_URL or --storage-endpoint/etc.) \" +\n \"are set, but no bucket was provided — the S3 backend is selected only by HELIPOD_STORAGE_BUCKET \" +\n \"(or --storage-bucket). Set the bucket to use S3, or unset the other storage settings to use local FS. \" +\n \"Refusing to boot rather than silently store uploads on local disk.\",\n );\n}\n\n/**\n * Fail fast if the FS file-storage dir can't be created/written — an operator misconfiguration\n * (read-only mount, wrong owner) must surface as a clear boot error, never a silent-later failure\n * on the first upload. Skipped for the S3 backend (no local dir).\n */\nfunction ensureStorageDirWritable(dir: string): void {\n try {\n mkdirSync(dir, { recursive: true });\n accessSync(dir, fsConstants.W_OK);\n } catch (e) {\n throw new Error(\n `helipod: file-storage directory \"${dir}\" is not creatable/writable — ${e instanceof Error ? e.message : String(e)}. ` +\n `Point --data at a writable location, or configure S3 storage (set HELIPOD_STORAGE_BUCKET).`,\n );\n }\n}\n\n/**\n * Every input the boot core takes. `bootProject` DERIVES its own options from this type (rather than\n * re-declaring them) and forwards them with a spread — see `BootProjectOptions`'s doc for why that\n * matters. Adding an option here therefore reaches `bootProject`'s public surface automatically; the\n * only keys that don't are the two `bootProject` produces itself (`loaded`/`components`).\n */\nexport interface BootLoadedOptions {\n loaded: LoadedProject;\n components: ComponentDefinition[];\n dataPath: string;\n adminKey: string;\n /** Postgres connection string; when unset, falls back to the zero-config SQLite file store. */\n databaseUrl?: string;\n /** File-storage backend overrides (CLI flags win over env, resolved via `resolveStorageConfig`). */\n storage?: StorageConfig;\n /**\n * Override the pending-upload TTL (ms) the `ctx.storage` provider stamps on `expiresAt`. Unset →\n * the provider default (1h). Exists so tests can force a short reap deadline; production leaves\n * it at the default.\n */\n storageUploadTtlMs?: number;\n /**\n * Override the orphan-reaper's sweep interval (ms). Unset → the reaper default (60s). Same\n * test-only motivation as `storageUploadTtlMs`.\n */\n storageReaperSweepMs?: number;\n /**\n * Tier 2 fleet wiring (from `@helipod/fleet`'s `prepareFleetNode`). When set, `store` is the\n * pre-constructed (read-only-until-promoted) Postgres store — used INSTEAD of `makeStore` — and\n * the runtime is built as a fleet node: writes route through `writeRouter` when this node isn't\n * the writer, drivers are deferred until promotion (`deferDrivers`), and a promoted writer's\n * commits fan out via `fanoutAdapter` (pg_notify). Absent for dev / non-fleet serve.\n */\n fleet?: {\n store: DocStore;\n writeRouter?: WriteRouter;\n deferDrivers?: boolean;\n fanoutAdapter?: EmbeddedWriteFanoutAdapter;\n /** Shards B2a: shard count — >1 builds a ShardedTransactor (per-shard parallel commits). */\n numShards?: number;\n /** Fleet B3 hybrid (multi-writer): the replica-backed query store (queries route here; mutations\n * commit to `store`). Threaded straight into `createEmbeddedRuntime`. */\n queryStore?: DocStore;\n /** Receipted Outbox (verdict §(c) placement): the authoritative receipts store the Connect handshake\n * classifies/prunes against — the PRIMARY on a sync node (whose `store` is the receipt-less replica),\n * so the handshake never spuriously resets. Threaded straight into `createEmbeddedRuntime`. */\n receiptsStore?: DocStore;\n /** Fleet B3 hybrid RYOW: awaited in the runtime fan-out drain before a local commit's re-runs. */\n beforeNotify?: (commitTs: bigint) => Promise<void>;\n /** Fleet B4: group commit — resolved by `@helipod/fleet`'s `node.ts` from its OWN\n * `HELIPOD_GROUP_COMMIT` read (mirrors how `numShards` is resolved fleet-side, before\n * `bootLoaded` runs) and threaded straight into `createEmbeddedRuntime`. Unset → `false`. */\n groupCommit?: boolean;\n /** Triggers D1: the stable-prefix accessor for `DriverContext.readLog` (`min(shard_leases.frontier_ts)`\n * in a fleet). Threaded straight into `createEmbeddedRuntime`; absent outside a fleet. */\n stablePrefix?: () => Promise<bigint | null>;\n /** Receipted Outbox: fleet owns the `clientReceiptsGuard()` registration on the concrete Postgres\n * store (in `armWriter`, before the fence) — so `createEmbeddedRuntime` must SKIP its own, which\n * would land on a sync node's `SwitchableDocStore` and vanish on the promotion swapTo. Threaded\n * straight into `createEmbeddedRuntime`; absent outside a fleet (the runtime owns it there). */\n externalReceiptsGuard?: boolean;\n };\n /**\n * Tier 3 Slice 6: object-storage substrate writer node. When set, `store` (at the `opts.fleet?.\n * store ?? … ?? makeStore(...)` seam below) becomes an `ObjectStoreDocStore` over this URL's\n * bucket (shard \"0\") instead of the usual SQLite/Postgres store — see `buildObjectStoreWriterNode`'s\n * doc comment. Mutually exclusive with `fleet` (Tier 2 and Tier 3 are alternative write-scaling\n * stories); combining both throws.\n */\n objectStoreUrl?: string;\n /** Called once, synchronously, the moment the lease-heartbeat driver detects this node has been\n * fenced (lost the shard-0 lease to a challenger). `serve.ts` wires this to trigger graceful\n * shutdown. Ignored when `objectStoreUrl` is unset. */\n objectStoreOnFenced?: (e: Error) => void;\n /** Test-only overrides (mirrors `storageUploadTtlMs`'s pattern) — unset → the production defaults\n * (`DEFAULT_OBJECTSTORE_LEASE_TTL_MS`/`DEFAULT_OBJECTSTORE_HEARTBEAT_MS`/`leaseTtlMs + 5000`). */\n objectStoreLeaseTtlMs?: number;\n objectStoreHeartbeatMs?: number;\n objectStoreAcquireTimeoutMs?: number;\n objectStoreAcquirePollIntervalMs?: number;\n /** Test-only: force a deterministic writer id instead of a fresh `randomUUID()` per boot. */\n objectStoreWriterId?: string;\n /** Tier 3 Slice 7, Task 7.3: the gc-driver's sweep cadence (ms). Unset → `DEFAULT_OBJECTSTORE_GC_MS`\n * (~60s). `serve.ts` threads `HELIPOD_OBJECTSTORE_GC_MS` in here; tests can also set it directly\n * to force an observable reclamation on a short timescale. Ignored when `objectStoreUrl` is unset. */\n objectStoreGcMs?: number;\n /** Tier 3 multi-shard single-node serve: the number of object-storage lanes a `--object-store`\n * WRITER node owns (`serve.ts` threads `--shards`/`HELIPOD_FLEET_SHARDS` in here). Unset / `1`\n * → the shipped single-shard path (shard \"0\"), byte-identical. `> 1` → this node opens+acquires\n * all `shardIdList(N)` lanes and composes a `ShardedObjectStoreDocStore`; the runtime's\n * `numShards` is sized to N so the `ShardedTransactor` routes writes to the owning lane. Ignored\n * for a `--replica` boot (a replica reads its lane count from the bucket's `globals.numShards`, not\n * this flag — it has no `--shards` of its own) and when `objectStoreUrl` is unset. */\n objectStoreShards?: number;\n /** Tier 3 Slice 8, Task 8.2: boot this node as a READ-ONLY REPLICA of `objectStoreUrl`'s shard\n * instead of a writer — materializes + tails, NEVER acquires the write lease (every mutation is\n * rejected with `REPLICA_WRITE_REJECTED_MESSAGE`), and runs no heartbeat/gc drivers. Requires\n * `objectStoreUrl` (throws if set without it — `serve.ts` also validates this at the CLI-flag\n * level, before ever reaching here). Ignored (no-op) when `objectStoreUrl` is unset. */\n replica?: boolean;\n /** Test-only: force a deterministic consumer-watermark id for the replica's tailer. Ignored\n * unless `replica` is set. See `buildObjectStoreReplicaNode`'s `consumerId`. */\n objectStoreReplicaConsumerId?: string;\n /** Test-only: shorten the replica's reactive-tailer poll cadence so a materialize-and-fan-out\n * round is observable within a test's timescale. Unset → `DEFAULT_OBJECTSTORE_REPLICA_POLL_MS`\n * (1000ms). Ignored unless `replica` is set. */\n objectStoreReplicaPollMs?: number;\n /**\n * Tier 3 Slice 8 follow-on: the writer node's URL, from `--writer-url`/`HELIPOD_WRITER_URL`.\n * When set on a `replica` boot, every mutation/action is FORWARDED here (`ReplicaWriteForwarder`,\n * wired in as `createEmbeddedRuntime`'s `writeRouter`) instead of being rejected locally.\n * Ignored unless `replica` is also set. Unset (the default) → today's unchanged reject-with-\n * `REPLICA_WRITE_REJECTED_MESSAGE` behavior.\n */\n writerUrl?: string;\n /**\n * The wake seam: the host's single alarm, for a host that STOPS THE PROCESS between requests (so\n * `setTimeout` never fires and every driver silently goes dead). `serve.ts` builds this from\n * `--wake-url`/`HELIPOD_WAKE_URL` (`httpWakeHost`); the runtime then multiplexes every driver\n * timer down to one arm. Threaded straight into `createEmbeddedRuntime`. Unset (every existing\n * deployment) → plain `setTimeout`, byte-for-byte unchanged.\n */\n wakeHost?: WakeHost;\n /**\n * The wake seam's other half: answers `DriverContext.backstopMs`, the floor/stretch applied to a\n * driver's BACKSTOP poll cadence only (never a next-work wake). `serve.ts` builds this from\n * `--backstop-min-ms`/`HELIPOD_BACKSTOP_MIN_MS`. Threaded straight into `createEmbeddedRuntime`.\n * Unset → identity (the drivers' own 30s/60s), byte-for-byte unchanged.\n */\n backstopMs?: (defaultMs: number) => number;\n}\n\nexport async function bootLoaded(opts: BootLoadedOptions): Promise<BootResult> {\n const { project, generated } = push(opts.loaded, opts.components);\n const logSink = new InMemoryLogSink();\n\n if (opts.objectStoreUrl !== undefined && opts.fleet) {\n throw new Error(\"helipod: --object-store cannot be combined with --fleet (Tier 2) — pick one write-scaling story.\");\n }\n if (opts.replica && opts.objectStoreUrl === undefined) {\n // Defense in depth: `serve.ts` already validates this synchronously at the CLI-flag level,\n // before ever calling `bootProject`/`bootLoaded` — this only guards a direct `bootLoaded` caller\n // (e.g. a test) that sets `replica` without `objectStoreUrl`.\n throw new Error(\n \"helipod: --replica requires --object-store — a replica materializes from an object-storage bucket; pass --object-store <url>.\",\n );\n }\n // Tier 3 Slice 6/8: ee-gate → resolve → adopt globals → materialize → (writer only) acquire the\n // shard-0 lease BEFORE anything else boots — a failed acquire (another live writer holds it) must\n // fail the whole boot fast, not leave a runtime half-constructed over a store this process doesn't\n // own. A `--replica` node (Task 8.2) never acquires — see `buildObjectStoreReplicaNode`.\n const objectStoreWriterNode =\n opts.objectStoreUrl !== undefined && !opts.replica\n ? await buildObjectStoreWriterNode({\n objectStoreUrl: opts.objectStoreUrl,\n dataPath: opts.dataPath,\n onFenced: opts.objectStoreOnFenced,\n leaseTtlMs: opts.objectStoreLeaseTtlMs,\n heartbeatMs: opts.objectStoreHeartbeatMs,\n acquireTimeoutMs: opts.objectStoreAcquireTimeoutMs,\n acquirePollIntervalMs: opts.objectStoreAcquirePollIntervalMs,\n writerId: opts.objectStoreWriterId,\n gcMs: opts.objectStoreGcMs,\n ...(opts.objectStoreShards !== undefined ? { shards: opts.objectStoreShards } : {}),\n })\n : undefined;\n const objectStoreReplicaNode =\n opts.objectStoreUrl !== undefined && opts.replica\n ? await buildObjectStoreReplicaNode({\n objectStoreUrl: opts.objectStoreUrl,\n dataPath: opts.dataPath,\n consumerId: opts.objectStoreReplicaConsumerId,\n pollMs: opts.objectStoreReplicaPollMs,\n })\n : undefined;\n const store =\n opts.fleet?.store ??\n objectStoreWriterNode?.store ??\n objectStoreReplicaNode?.store ??\n makeStore({ dataPath: opts.dataPath, databaseUrl: opts.databaseUrl });\n\n // Multi-shard replicas + write-forwarding is NOT yet supported, and fails fast rather than shipping\n // a latent disappearing-write bug. Write-forwarding relies on the G4 origin-frontier fallback\n // (`SyncProtocolHandler.pendingFrontiers`/`sweepPendingFrontiers`): a forwarded mutation commits on\n // the writer, and the replica advances the origin session's observed frontier once its tailer drains\n // past that commit ts. But a multi-shard replica runs ONE tailer PER LANE, each sweeping pending\n // frontiers with ITS OWN lane's ts — and per-lane object-store timestamps are independent counters,\n // not a shared clock. So a fast lane's sweep could satisfy a forwarded frontier owned by a lane that\n // hasn't applied the write yet → the client drops its optimistic layer while the authoritative row is\n // still absent from the replica (a transient RYOW/no-flicker violation). The tested + shipped\n // multi-shard replica config is REJECT-mode (no `--writer-url`); forwarding on a multi-shard bucket\n // needs a per-lane pending-frontier design (a future slice). Reject-mode single-shard forwarding and\n // reject-mode multi-shard are both unaffected.\n if (objectStoreReplicaNode && opts.writerUrl !== undefined && objectStoreReplicaNode.numShards > 1) {\n throw new Error(\n `helipod: --writer-url (replica write-forwarding) is not yet supported on a multi-shard bucket ` +\n `(this bucket has ${objectStoreReplicaNode.numShards} shards) — run the replica in reject mode (drop --writer-url) ` +\n `and send writes directly to the writer, or use a single-shard deployment.`,\n );\n }\n // Tier 3 Slice 8 follow-on (replica write-forwarding): a replica boot with `--writer-url` set\n // gets a `ReplicaWriteForwarder` wired in as the runtime's `writeRouter` below — every\n // mutation/action forwards to the writer instead of attempting (and failing) a local commit.\n // Unset `writerUrl` (the default) → no writeRouter, unchanged reject-with-message behavior.\n const replicaWriteForwarder =\n objectStoreReplicaNode && opts.writerUrl !== undefined ? new ReplicaWriteForwarder(opts.writerUrl) : undefined;\n\n // Shards B2a (T5): resolve NUM_SHARDS. A fleet caller (`serve.ts --fleet`) has ALREADY resolved\n // + persisted its count against the durable Postgres store BEFORE `prepareFleetNode` (which needs\n // the number up front, to size the per-shard commit-connection pool) and threads it in as\n // `opts.fleet.numShards` — a sync node's `opts.fleet.store` here is its LOCAL replica, not the\n // durable store, so resolving/persisting generically against `store` below would be wrong for\n // that role. Non-fleet (dev, `serve` without `--fleet`, the single binary): resolve right here,\n // against the one store there is — `setupSchema()` is idempotent (`createEmbeddedRuntime` below\n // calls it again), so calling it early just to make `persistence_globals` queryable is safe.\n let numShards: number;\n if (opts.fleet) {\n numShards = opts.fleet.numShards ?? 1;\n } else if (objectStoreWriterNode || objectStoreReplicaNode) {\n // Tier 3 multi-shard serve: a `--object-store` WRITER owns N lanes (each its own bucket prefix +\n // local + lease/heartbeat/gc, composed behind `ShardedObjectStoreDocStore`); a `--replica` now\n // MATERIALIZES + tails the same N lanes behind the same read composite (one tailer per lane). The\n // engine's `numShards`-sized `ShardedTransactor` routes/reads over exactly the lanes each built.\n await store.setupSchema();\n // Authoritative count comes from the bucket's persisted globals (resolved inside the writer/replica\n // build, which for the writer fails fast on a `--shards` mismatch) — NOT `opts.objectStoreShards`\n // directly, so a resharded bucket boots the right `numShards` on both roles even if `--shards` is\n // omitted. Whichever role this boot built reports its lane count here.\n numShards = objectStoreWriterNode?.numShards ?? objectStoreReplicaNode?.numShards ?? 1;\n } else {\n await store.setupSchema();\n numShards = await resolveNumShards(store, parseNumShards(process.env.HELIPOD_FLEET_SHARDS));\n }\n\n // Fleet B4 (T4): resolve GROUP_COMMIT the same shape as `numShards` above — a fleet caller has\n // already resolved its own `HELIPOD_GROUP_COMMIT` read (mirrors `fleetMultiWriterEnabled`'s\n // pattern in `@helipod/fleet`'s `node.ts`) and threads it in as `opts.fleet.groupCommit`; the\n // non-fleet path (dev, `serve` without `--fleet`, the single binary) reads the env var directly.\n // No persist-once story needed (see `groupCommitEnabled`'s doc comment) — a plain per-boot read.\n const groupCommit = opts.fleet\n ? (opts.fleet.groupCommit ?? false)\n : resolveGroupCommit({ envRaw: process.env.HELIPOD_GROUP_COMMIT, databaseUrl: opts.databaseUrl });\n\n // File storage is always on. Blobs sit beside the SQLite file (`<dataDir>/storage`); the signing\n // key is the deployment admin key (already fail-fasted-if-unset by `serve`). The `_storage` table\n // itself was injected into the composed schema/catalog/tableNumbers in `loadProject`.\n const dataDir = dirname(resolve(opts.dataPath));\n const storageConfig = resolveStorageConfig(process.env, opts.storage);\n assertStorageConfigCoherent(storageConfig);\n const blobStore = makeBlobStore({ dataPath: dataDir, storage: storageConfig });\n if (!isS3Config(storageConfig)) ensureStorageDirWritable(join(dataDir, \"storage\"));\n\n const runtime = await createEmbeddedRuntime({\n store,\n catalog: project.catalog,\n logSink,\n // `_storage:*` built-ins go in BOTH maps: `modules` (reached by the action facade's `invoke`\n // and the reaper's `runFunction`) and `systemModules` (reached by the HTTP routes' `runSystem`,\n // the same trusted path `_admin` uses). `systemModules` isn't swapped by `setModules`, so it\n // persists across reload/deploy on its own; `modules` is re-applied via `withStorageModules`.\n modules: withStorageModules(project.moduleMap),\n systemModules: { ...systemModules(), ...storageModules },\n adminModules: { \"_admin:browseTable\": browseTableModule },\n verifyAdmin: (key: string) => verifyAdminKey(opts.adminKey, key),\n componentNames: project.componentNames,\n // Prepend the `ctx.storage` provider and the orphan-reaper driver to whatever components composed.\n contextProviders: [\n storageContextProvider(blobStore, {\n signingKey: opts.adminKey,\n ...(opts.storageUploadTtlMs !== undefined ? { uploadTtlMs: opts.storageUploadTtlMs } : {}),\n }),\n ...project.contextProviders,\n ],\n tableNumbers: project.tableNumbers,\n bootSteps: project.bootSteps,\n drivers: [\n storageReaper(blobStore, opts.storageReaperSweepMs !== undefined ? { sweepMs: opts.storageReaperSweepMs } : undefined),\n // Receipted Outbox TTL reaper (verdict §(c) Retention): a timer-only bulk sweep of expired\n // `client_mutations` rows. Always on (every deployment has the receipts tables); no-op work when\n // no client ever wrote a receipt. Reads the SAME `store` the runtime commits to.\n receiptsReaper(store),\n // Tier 3 Slice 6: the lease-heartbeat + gc drivers (renews shard-0's lease on cadence; stops +\n // signals via `objectStoreOnFenced` on a fence). Writer-only — empty outside the object-store\n // writer path (absent entirely for a `--replica` node, Task 8.2: no heartbeat, no gc — a\n // replica holds no lease and reclaims nothing; its OWN reactive-tailer wiring is started\n // separately, below, once the runtime exists).\n ...(objectStoreWriterNode?.drivers ?? []),\n ...project.drivers,\n ],\n // Fleet (Tier 2): route writes to the lease-holder when not the writer, defer drivers until\n // promotion, and (writer boot) fan out commits cross-process via pg_notify.\n ...(opts.fleet?.writeRouter ? { writeRouter: opts.fleet.writeRouter } : {}),\n // Tier 3 Slice 8 follow-on (replica write-forwarding): mutually exclusive with `opts.fleet`\n // (guarded at the top of this function — `--object-store` + `--fleet` throws), so at most one\n // of these two `writeRouter` spreads ever contributes a key.\n ...(replicaWriteForwarder ? { writeRouter: replicaWriteForwarder } : {}),\n ...(opts.fleet?.deferDrivers ? { deferDrivers: true } : {}),\n ...(opts.fleet?.fanoutAdapter ? { fanoutAdapter: opts.fleet.fanoutAdapter } : {}),\n // Fleet B3 hybrid (multi-writer): the replica-backed query path + the own-commit RYOW drain gate.\n ...(opts.fleet?.queryStore ? { queryStore: opts.fleet.queryStore } : {}),\n // Receipted Outbox (verdict §(c) placement): route the Connect handshake's classification/ack-prune\n // to the authoritative PRIMARY receipts store on a sync node (whose `store` is the receipt-less\n // replica) — without this the handshake spuriously resets a client. Absent → the runtime uses `store`.\n ...(opts.fleet?.receiptsStore ? { receiptsStore: opts.fleet.receiptsStore } : {}),\n ...(opts.fleet?.beforeNotify ? { beforeNotify: opts.fleet.beforeNotify } : {}),\n // Triggers D1: the fleet stable-prefix bound for `readLog` (`min(shard_leases.frontier_ts)`).\n ...(opts.fleet?.stablePrefix ? { stablePrefix: opts.fleet.stablePrefix } : {}),\n // Receipted Outbox: fleet owns the receipts guard on the concrete Postgres store (armWriter,\n // before the fence) — the runtime skips its own registration so it never lands on a sync node's\n // SwitchableDocStore only to vanish on the promotion swapTo. Non-fleet → the runtime owns it.\n ...(opts.fleet?.externalReceiptsGuard ? { externalReceiptsGuard: true } : {}),\n // Shards B2a: >1 → a ShardedTransactor (per-shard parallel commits) over the store — resolved\n // above (fleet: threaded in already-resolved; non-fleet: resolved+persisted just now).\n numShards,\n // Fleet B4 (T4): route every shard's commits through the group-commit committer loop — resolved\n // above (fleet: threaded in already-resolved; non-fleet: read from HELIPOD_GROUP_COMMIT).\n groupCommit,\n // The wake seam (`serve --wake-url` / `--backstop-min-ms`): a host that stops the process between\n // requests fires driver timers via `runtime.fireDueTimers()` instead of `setTimeout`, and can\n // stretch the pure-backstop cadences so an idle app isn't cold-started every 30s. Both absent →\n // today's `setTimeout` + 30s/60s behavior, unchanged.\n ...(opts.wakeHost ? { wakeHost: opts.wakeHost } : {}),\n ...(opts.backstopMs ? { backstopMs: opts.backstopMs } : {}),\n });\n\n // Tier 3 Slice 8, Task 8.2: NOW that the replica's own runtime exists, start the reactive-tailer\n // wiring helper (Task 8.1) — it can't be a driver passed INTO `createEmbeddedRuntime` above\n // because its sink needs the runtime itself (chicken-and-egg; see `replica-wiring.ts`'s module\n // doc). `attachTailer` returns the shutdown handle (stop the tailer + `removeConsumer`).\n const objectStoreReplicaRelease = objectStoreReplicaNode ? objectStoreReplicaNode.attachTailer(runtime) : undefined;\n\n const storageRouteDeps: StorageRouteDeps = {\n // The routes reach the privileged `_storage:_finalize`/`_get` built-ins via `runSystem` (trusted,\n // like `_admin`), which reads `systemModules` — unaffected by any later `setModules` swap.\n runMutation: async (path, args) => (await runtime.runSystem(path, args as JSONValue)).value,\n runQuery: async (path, args) => (await runtime.runSystem(path, args as JSONValue)).value,\n signingKey: opts.adminKey,\n // When authz isn't composed (the default), leave `checkRead` undefined so `handleServe` falls\n // back to the capability-token check (a private file's `getUrl` embeds a valid token). See the\n // task-10 report for the authz effective-permissions bridge status.\n checkRead: makeStorageCheckRead(opts.components),\n };\n const routes = storageRoutes(blobStore, storageRouteDeps);\n\n // Component-contributed reserved routes (Task A3-1): bind each declared httpAction to the runtime\n // and shape it as an engine-owned `StorageRoute`. The raw `Authorization: Bearer <token>` is passed\n // straight through as `identity` (no resolution — same convention `httpAction`/storage use).\n const bearerOf = (request: Request): string | null => {\n const h = request.headers.get(\"authorization\");\n const m = h ? /^Bearer\\s+(.+)$/.exec(h) : null;\n return m ? (m[1] ?? null) : null;\n };\n const componentRoutes: StorageRoute[] = project.componentRoutes.map((r) => ({\n method: r.method,\n pathPrefix: r.pathPrefix,\n handler: (request: Request) => runtime.runHttpAction(r.handlerPath, request, { identity: bearerOf(request) }),\n }));\n\n const adminApi = new AdminApi({\n runtime,\n schemaJson: project.schemaJson,\n tableNumbers: project.tableNumbers,\n manifest: project.manifest,\n logSink,\n catalog: project.catalog,\n });\n return {\n runtime,\n adminApi,\n project,\n generated,\n store,\n logSink,\n components: opts.components,\n blobStore,\n storageRoutes: routes,\n componentRoutes,\n // Mutually exclusive by construction (Task 8.2 guards `objectStoreUrl !== undefined && !replica`\n // vs. `&& replica`) — at most one of these two spreads ever contributes a key, so `serve.ts`'s\n // shutdown can call `objectStoreRelease()` generically without knowing which node type booted.\n ...(objectStoreWriterNode ? { objectStoreRelease: objectStoreWriterNode.release } : {}),\n ...(objectStoreReplicaRelease ? { objectStoreRelease: objectStoreReplicaRelease } : {}),\n // Tier 3 Slice 8 follow-on (replica write-forwarding): threaded through so `serve.ts` can arm\n // `/api/run`'s single-hop defensive guard on THIS node (`startDevServer`'s `replicaWriterUrl`).\n ...(replicaWriteForwarder ? { replicaWriterUrl: opts.writerUrl } : {}),\n };\n}\n\n/**\n * The serve-endpoint read-authorization bridge for a PRIVATE `_storage` file. When the `authz`\n * component is composed, this would resolve the caller's effective-permissions read grant for the\n * `_storage` doc; when it isn't (the default), returns `undefined` so `handleServe` uses the\n * capability-token fallback instead of failing open.\n *\n * NOTE (task 10): the authz side is intentionally not wired yet — `components/authz` exposes only a\n * `resource:action`/scope `can()` check reachable inside a function context, with no per-`(table,id,\n * identity)` read primitive, and this boot layer holds only opaque `ComponentDefinition[]` (not the\n * authz config/context needed to evaluate it). Fabricating a permission convention here would be a\n * guess. The seam is threaded end-to-end so a real authz read-primitive can slot in without touching\n * the routes. Until then a composed-authz deployment still gates private files correctly via tokens.\n */\nfunction makeStorageCheckRead(\n _components: ComponentDefinition[],\n): StorageRouteDeps[\"checkRead\"] {\n return undefined;\n}\n\n/**\n * `bootProject`'s options: everything `bootLoaded` takes, MINUS the two things `bootProject` exists\n * to produce itself, PLUS the `functionsDir` it produces them from. Derived deliberately — never\n * re-declared.\n *\n * WHY (a trap this has already cost a full debug cycle — do not re-introduce it): `bootProject` used to\n * re-declare its own option type and forward every key BY HAND into a fresh object literal. That\n * shape drops options SILENTLY. TypeScript's excess-property check does not apply through a spread,\n * and every caller passes optional options via conditional spread\n * (`...(x !== undefined ? { k: v } : {})`, see `serve.ts`) — so a caller could hand `bootProject` a\n * key its type never declared, get ZERO diagnostics, and have the value vanish before it ever\n * reached `createEmbeddedRuntime`. That is exactly how the wake seam shipped dead: `serve.ts` built\n * a valid `httpWakeHost(--wake-url)`, `bootProject` dropped it, the runtime silently took the\n * `setTimeout` branch, and scheduled work never fired on a host that stops the process between\n * requests — with the whole suite green, because nothing type-checked or tested the seam BETWEEN\n * the two functions.\n *\n * Deriving from `BootLoadedOptions` + forwarding with a spread makes the drop structurally\n * impossible rather than merely caught: a new `bootLoaded` option is part of this type, and is\n * forwarded, the moment it is declared. The `Omit` is the ONLY exclusion list, and it is deliberate:\n * `loaded`/`components` are `bootProject`'s own outputs (`loadFunctionsDir`/`loadConfig`), so\n * accepting them from a caller would be meaningless. Anything else belongs here automatically.\n */\nexport type BootProjectOptions = Omit<BootLoadedOptions, \"loaded\" | \"components\"> & { functionsDir: string };\n\nexport async function bootProject(opts: BootProjectOptions): Promise<BootResult> {\n // Destructure off ONLY what `bootProject` itself consumes/produces; `forwarded` is by construction\n // every remaining `BootLoadedOptions` key, so no option can be left behind. Keep this a spread —\n // re-introducing a hand-enumerated forward re-opens the silent-drop trap documented above (and\n // `boot-options-forwarding.test.ts` is what fails if you do).\n const { functionsDir, ...forwarded } = opts;\n const loaded = await loadFunctionsDir(functionsDir);\n const config = await loadConfig(dirname(functionsDir));\n return bootLoaded({ ...forwarded, loaded, components: config.components });\n}\n\n/**\n * Load the built dashboard SPA and inject the admin key (same-origin, local-only) so it can call\n * `/_admin` without a login prompt. Returns undefined if the dashboard isn't built (→ stub).\n * Shared by `dev` (ephemeral loopback key) and `serve` (no key — the SPA prompts the operator).\n */\nexport function loadDashboard(adminKey: string | undefined): { distDir: string; html: string } | undefined {\n try {\n const indexPath = createRequire(import.meta.url).resolve(\"@helipod/dashboard/dist\");\n const distDir = dirname(indexPath);\n const raw = readFileSync(indexPath, \"utf8\");\n if (adminKey === undefined) return { distDir, html: raw }; // no key embedded → SPA prompts\n // Escape `<` so a key value can never break out of the inline <script> (e.g. `</script>`).\n const inject = `<script>window.__ADMIN_KEY__=${JSON.stringify(adminKey).replace(/</g, \"\\\\u003c\")}</script>`;\n return { distDir, html: raw.replace(\"</head>\", `${inject}</head>`) };\n } catch {\n return undefined;\n }\n}\n","/**\n * Byte-backend selection for the always-on file-storage feature — the `BlobStore` analog to\n * `boot.ts`'s `makeStore` (which picks SQLite vs Postgres). Pure and side-effect-free so it is\n * unit-testable: given a resolved config it returns a `FsBlobStore` (zero-config local default)\n * or an `S3BlobStore` (any S3-compatible bucket: AWS S3, MinIO, R2, …). The actual writable-dir\n * fail-fast and env/flag resolution live in `boot.ts`, not here.\n */\nimport { join } from \"node:path\";\nimport type { BlobStore } from \"@helipod/blobstore\";\nimport { FsBlobStore } from \"@helipod/blobstore-fs\";\nimport { S3BlobStore, type S3Config } from \"@helipod/blobstore-s3\";\n\n/** Resolved storage config. A `bucket` selects the S3 backend; everything else is FS. */\nexport type StorageConfig = Partial<S3Config> & { bucket?: string };\n\nexport interface BlobStoreOptions {\n /**\n * The engine data DIRECTORY (the dir the SQLite file lives in, not the file itself); FS blobs\n * go in `<dataPath>/storage`. `boot.ts` passes `dirname(dbFilePath)` here.\n */\n dataPath: string;\n storage?: StorageConfig;\n}\n\n/** True iff an S3 bucket is configured — the single switch between the S3 and FS backends. */\nexport function isS3Config(storage: StorageConfig | undefined): boolean {\n return Boolean(storage?.bucket);\n}\n\n/**\n * Resolve the storage config from env + optional CLI-flag overrides (flags win, mirroring\n * `--database-url` over `HELIPOD_DATABASE_URL`). Unset bucket → the FS backend. Reads the S3\n * settings from `HELIPOD_STORAGE_*` plus the standard AWS credential vars.\n */\nexport function resolveStorageConfig(\n env: Record<string, string | undefined>,\n flags?: StorageConfig,\n): StorageConfig {\n return {\n bucket: flags?.bucket ?? env.HELIPOD_STORAGE_BUCKET,\n endpoint: flags?.endpoint ?? env.HELIPOD_STORAGE_ENDPOINT,\n region: flags?.region ?? env.HELIPOD_STORAGE_REGION,\n publicBaseUrl: flags?.publicBaseUrl ?? env.HELIPOD_STORAGE_PUBLIC_URL,\n accessKeyId: flags?.accessKeyId ?? env.AWS_ACCESS_KEY_ID,\n secretAccessKey: flags?.secretAccessKey ?? env.AWS_SECRET_ACCESS_KEY,\n ...(flags?.forcePathStyle !== undefined ? { forcePathStyle: flags.forcePathStyle } : {}),\n };\n}\n\n/**\n * Pick the byte backend: `S3BlobStore` when a bucket is configured (`isS3Config`), else the\n * zero-config `FsBlobStore` rooted at `<dataPath>/storage`.\n */\nexport function makeBlobStore(opts: BlobStoreOptions): BlobStore {\n const s = opts.storage;\n if (isS3Config(s)) {\n return new S3BlobStore({\n bucket: s!.bucket!,\n region: s!.region,\n endpoint: s!.endpoint,\n accessKeyId: s!.accessKeyId,\n secretAccessKey: s!.secretAccessKey,\n forcePathStyle: s!.forcePathStyle,\n publicBaseUrl: s!.publicBaseUrl,\n });\n }\n return new FsBlobStore({ root: join(opts.dataPath, \"storage\") });\n}\n","/**\n * Object-store backend selection for the Tier-3 object-storage substrate — the `ObjectStore`\n * analog to `blobstore-select.ts` (which picks the fs-vs-s3 byte backend for file storage).\n * Pure and side-effect-free: parse + construct only, NO live I/O (no bucket probe — the boot\n * path calls the adapter's own `assertCasSupported()` separately once it decides to actually\n * boot the object-store writer node). That purity is what makes this unit-testable without a\n * real bucket or filesystem.\n *\n * URL grammar (one clear shape, chosen to mirror `blobstore-select`'s existing S3 conventions —\n * `endpoint`/`region`/`forcePathStyle`/AWS-env credential fallback — while folding everything\n * into a single `--object-store <url>` flag instead of a family of `--storage-*` flags):\n *\n * - unset / empty string -> `null` (object-store mode not requested)\n * - `file://<path>` -> `FsObjectStore` rooted at `<path>`\n * (e.g. `file:///var/lib/helipod/objects` -> dir `/var/lib/helipod/objects`)\n * - a bare filesystem path (no URL-scheme prefix) -> same, `FsObjectStore` rooted at that path\n * (e.g. `--object-store ./objects`)\n * - `s3://[accessKeyId:secretAccessKey@]host[:port]/bucket[?region=…&endpoint=…&forcePathStyle=…]`\n * -> `S3ObjectStore`. The bucket is the URL's path (first segment); it is REQUIRED.\n * `host[:port]`, when non-empty, becomes the endpoint (`http://host[:port]`) UNLESS an\n * explicit `?endpoint=` query param is given, which always wins. A bare host under `s3://`\n * is assumed `http://` — true for MinIO/R2/etc. run locally or in-cluster. An EMPTY host\n * (`s3:///bucket`, three slashes) means \"no custom endpoint\" — real AWS S3 via the SDK's\n * own region-routed default endpoint. This is why a bucket can't be given as `s3://bucket`\n * (two slashes): the WHATWG URL parser reads that as `hostname=\"bucket\"`, not a path — use\n * `s3:///bucket` instead. Credentials come from the URL userinfo (`key:secret@`) if\n * present, else `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` (checked independently, so e.g.\n * a URL-supplied key with an env-supplied secret works). Missing bucket or missing\n * credentials -> throw a clear `Error` (fail fast at parse time, before any network/lease\n * work).\n * - `s3+http://…` / `s3+https://…` — same grammar and `S3ObjectStore` config as `s3://`, but\n * the scheme itself pins the host-derived endpoint's protocol instead of assuming `http://`\n * — `s3+http://` forces `http://host[:port]`, `s3+https://` forces `https://host[:port]`.\n * This is the way to reach an `https://` endpoint WITHOUT the `?endpoint=` query-param\n * workaround (an explicit `?endpoint=` still wins over either). Any scheme outside this set\n * — including a same-name-different-case typo like `S3://`, or an unrelated one like\n * `gs://`/`azure://`/`http://` — is REJECTED with a clear error rather than silently\n * falling through to `FsObjectStore` (a silent fallback would boot a local-disk store in\n * place of the intended shared bucket).\n *\n * Examples:\n * `s3://minioadmin:minioadmin@localhost:9000/helipod-objects?region=us-east-1`\n * `s3+https://minioadmin:minioadmin@objects.example.com/helipod-objects`\n * `s3:///my-prod-bucket?region=us-west-2` (real AWS S3, creds from env)\n * `file:///data/objects`\n * `./objects`\n */\nimport type { ObjectStore } from \"@helipod/objectstore\";\nimport { FsObjectStore } from \"@helipod/objectstore-fs\";\nimport { S3ObjectStore } from \"@helipod/objectstore-s3\";\n\nexport type ObjectStoreKind = \"s3\" | \"fs\";\n\nexport interface ResolvedObjectStore {\n objectStore: ObjectStore;\n kind: ObjectStoreKind;\n}\n\n/** Slice-6 single-shard-node config: one shard, \"0\", behind the whole store. Multi-shard-node\n * (N lanes behind a routing DocStore) is explicitly out of scope for this slice — see the plan. */\nexport interface ObjectStoreNodeConfig {\n shard: string;\n numShards: number;\n}\n\nexport function defaultObjectStoreNodeConfig(): ObjectStoreNodeConfig {\n return { shard: \"0\", numShards: 1 };\n}\n\n/** Parsed S3 config, exposed for assertion in tests without performing any live S3 I/O\n * (constructing `S3Client` does not itself touch the network). Mirrors `S3ObjectStoreOpts`. */\nexport interface ParsedS3Config {\n bucket: string;\n endpoint?: string;\n region?: string;\n accessKeyId: string;\n secretAccessKey: string;\n forcePathStyle?: boolean;\n}\n\nfunction parseBoolParam(v: string | null): boolean | undefined {\n if (v === null) return undefined;\n if (v === \"true\") return true;\n if (v === \"false\") return false;\n throw new Error(`helipod: invalid --object-store URL — forcePathStyle must be \"true\" or \"false\", got \"${v}\"`);\n}\n\n/** Parse an `s3://…` URL per the grammar documented above. Pure — no I/O. Throws a clear `Error`\n * on a missing bucket or missing credentials (URL userinfo + `env` fallback both absent). */\nexport function parseS3ObjectStoreUrl(\n url: string,\n env: Record<string, string | undefined> = process.env,\n): ParsedS3Config {\n let u: URL;\n try {\n u = new URL(url);\n } catch (e) {\n throw new Error(`helipod: invalid --object-store URL \"${url}\": ${(e as Error).message}`);\n }\n\n const bucket = decodeURIComponent(u.pathname.replace(/^\\//, \"\").split(\"/\")[0] ?? \"\");\n if (!bucket) {\n throw new Error(\n `helipod: --object-store S3 URL \"${url}\" has no bucket — use s3://host/<bucket> ` +\n `(or s3:///<bucket> for real AWS S3 with no custom endpoint).`,\n );\n }\n\n // `s3+https://` pins the host-derived endpoint to https; `s3://`/`s3+http://` (and anything\n // else — this function is only ever reached for a scheme `resolveObjectStore` already vetted)\n // default to http, matching the historical `s3://` behavior.\n const endpointProtocol = u.protocol === \"s3+https:\" ? \"https\" : \"http\";\n const explicitEndpoint = u.searchParams.get(\"endpoint\") ?? undefined;\n const endpoint =\n explicitEndpoint ?? (u.hostname ? `${endpointProtocol}://${u.hostname}${u.port ? `:${u.port}` : \"\"}` : undefined);\n\n const region = u.searchParams.get(\"region\") ?? undefined;\n const forcePathStyle = parseBoolParam(u.searchParams.get(\"forcePathStyle\"));\n\n const accessKeyId = (u.username ? decodeURIComponent(u.username) : undefined) ?? env.AWS_ACCESS_KEY_ID;\n const secretAccessKey = (u.password ? decodeURIComponent(u.password) : undefined) ?? env.AWS_SECRET_ACCESS_KEY;\n if (!accessKeyId || !secretAccessKey) {\n throw new Error(\n `helipod: --object-store S3 URL \"${url}\" is missing credentials — supply them in the URL ` +\n `(s3://accessKeyId:secretAccessKey@…) or set AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY.`,\n );\n }\n\n return { bucket, endpoint, region, accessKeyId, secretAccessKey, forcePathStyle };\n}\n\n/** `file://<path>` or a bare filesystem path -> the dir an `FsObjectStore` should root at.\n * Exported so the fs-branch's directory derivation is directly assertable in tests, mirroring\n * how `parseS3ObjectStoreUrl` is exported for the s3 branch. */\nexport function parseFsObjectStorePath(url: string): string {\n return url.startsWith(\"file://\") ? url.slice(\"file://\".length) : url;\n}\n\n/** Recognizes a leading `<scheme>://` (RFC 3986 scheme-char set). Capture group 1 is the raw,\n * case-preserved scheme — dispatch below matches it verbatim (no case-folding), so a typo like\n * `S3://` is treated as an unrecognized scheme rather than silently accepted. */\nconst SCHEME_RE = /^([a-zA-Z][a-zA-Z0-9+.\\-]*):\\/\\//;\n\nconst SUPPORTED_SCHEMES = \"s3://, s3+http://, s3+https://, file:// (or a bare filesystem path with no scheme)\";\n\n/**\n * Resolve `--object-store <url>` / `HELIPOD_OBJECT_STORE` to a constructed `ObjectStore`\n * adapter. `undefined`/empty -> `null` (object-store mode not requested — the CLI falls through\n * to its normal `makeStore` SQLite/Postgres selection). Pure: parses and constructs only, no\n * live I/O (the caller runs `assertCasSupported()`/`ensureGlobals`/lease-acquire separately).\n *\n * Dispatches on the URL's scheme rather than only special-casing `s3://` — any string shaped\n * like `<scheme>://…` that ISN'T one of the recognized schemes throws instead of silently\n * falling through to `FsObjectStore` (a silent fallback there would boot a local-disk store in\n * place of the intended shared bucket — data would land on private disk with no error). A bare\n * path with no `<scheme>://` prefix still means `fs`, unchanged.\n */\nexport function resolveObjectStore(\n url: string | undefined,\n env: Record<string, string | undefined> = process.env,\n): ResolvedObjectStore | null {\n const trimmed = url?.trim();\n if (!trimmed) return null;\n\n const schemeMatch = trimmed.match(SCHEME_RE);\n if (!schemeMatch) {\n // No `<scheme>://` prefix at all — a bare filesystem path.\n return { objectStore: new FsObjectStore({ dir: parseFsObjectStorePath(trimmed) }), kind: \"fs\" };\n }\n\n switch (schemeMatch[1]) {\n case \"s3\":\n case \"s3+http\":\n case \"s3+https\": {\n const config = parseS3ObjectStoreUrl(trimmed, env);\n return { objectStore: new S3ObjectStore(config), kind: \"s3\" };\n }\n case \"file\":\n return { objectStore: new FsObjectStore({ dir: parseFsObjectStorePath(trimmed) }), kind: \"fs\" };\n default:\n throw new Error(\n `helipod: --object-store URL \"${trimmed}\" uses an unsupported scheme \"${schemeMatch[1]}://\" — ` +\n `supported schemes are ${SUPPORTED_SCHEMES}.`,\n );\n }\n}\n","/**\n * Tier 3 Slice 8 follow-on: replica write-forwarding. `helipod serve --object-store <url>\n * --replica --writer-url <url>` FORWARDS every mutation/action a caller sends to this replica\n * over to the writer node, instead of rejecting it (`boot.ts`'s `wrapReplicaWriteRejection` —\n * still the behavior when `--writer-url` is unset, unchanged/non-breaking).\n *\n * Implements the engine's CORE `WriteRouter` seam (`@helipod/executor`, re-exported by\n * `@helipod/runtime-embedded`) — the SAME seam `@helipod/fleet`'s `WriteForwarder` (ee)\n * implements for Tier 2 (see `ee/packages/fleet/src/forwarder.ts`), but deliberately simpler:\n * ONE fixed writer URL (no shard-lease discovery — the object-store substrate is single-shard-\n * node by construction, see `boot.ts`'s Tier 3 Slice 6/8 scope-boundary note), no idempotency\n * store. `isLocalWriter` always answers `false` — a replica is never the writer for ANY shard,\n * so `EmbeddedRuntime`'s ONE chokepoint (`executor.run()`'s per-shard mutation branch, plus\n * `EmbeddedRuntime.run`/`runAction`'s wholesale action-forward branch) forwards every mutation\n * and action it sees, regardless of origin (WS `Mutation`/`Action` messages, `POST /api/run`, or\n * an action's inner `ctx.runMutation`). Queries never touch this seam — reads stay local on the\n * replica, which is the whole point of a read replica; see `runtime.ts`'s own doc comment on\n * `WriteRouter` (\"queries are never routed\").\n *\n * Forwards to `${writerUrl}/api/run` — the writer's own public mutation/action entrypoint, not a\n * dedicated internal endpoint — carrying:\n * - `identity` as `Authorization: Bearer <identity>` (mirrors how a public httpAction's raw\n * bearer is passed straight through as `opts.identity`, per `docs/enduser/http-actions.md`'s\n * convention; `http-handler.ts`'s `/api/run` handler derives `identity` the same way).\n * - `forwarded: true` in the body — the single-hop guard. The WRITER never re-forwards: it\n * boots with no `writeRouter` at all, so `runtime.run`/`runAction` execute locally\n * unconditionally. A REPLICA that receives a `forwarded: true` request on its OWN\n * `/api/run` (a misconfiguration — some caller's `--writer-url` points at this replica\n * instead of the real writer) rejects it up front instead of silently forwarding again —\n * see `http-handler.ts`'s `/api/run` guard (`replicaWriterUrl` param).\n * - `dedup` (Receipted Outbox `clientId`/`seq`), when present — forwarded so the OWNER (the\n * writer) classifies it, per the \"classification runs where the commit runs\" placement rule\n * `runtime.ts`'s `syncExecutor.runMutation` already documents for the fleet case.\n */\nimport type { WriteRouter, ClientReplay } from \"@helipod/runtime-embedded\";\nimport type { ShardId } from \"@helipod/id-codec\";\nimport type { JSONValue } from \"@helipod/values\";\n\n/** Strip a single trailing slash so `${writerUrl}/api/run` never doubles up (`//api/run`). */\nfunction trimTrailingSlash(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\n/** The writer's `/api/run` JSON response shape this forwarder parses. Additive fields only —\n * `commitTs` and `clientReplay` are new/optional so an older writer (pre this feature) still\n * parses fine (missing `commitTs` -> `undefined`, exactly `forwardedResult()`'s pre-existing\n * hardcoded-0 fallback). */\ninterface WriterRunResponse {\n value?: JSONValue;\n error?: string;\n commitTs?: string;\n clientReplay?: ClientReplay;\n}\n\nexport class ReplicaWriteForwarder implements WriteRouter {\n constructor(private readonly writerUrl: string) {}\n\n /** A replica is never the writer for any shard — every mutation/action forwards. Consulted\n * fresh on every call (mirrors the fleet forwarder's own \"never cached\" contract) — cheap\n * here since it's a constant, not a live lease read. */\n isLocalWriter(_shardId: ShardId): boolean {\n return false;\n }\n\n async forward(\n kind: \"mutation\" | \"action\",\n path: string,\n args: JSONValue,\n identity: string | null,\n _shardId: ShardId,\n dedup?: { clientId: string; seq: number },\n ): Promise<{ value: JSONValue; commitTs?: number; shardId?: string; replay?: ClientReplay }> {\n const body = {\n path,\n args,\n kind,\n forwarded: true,\n ...(dedup ? { clientId: dedup.clientId, seq: dedup.seq } : {}),\n };\n let res: Response;\n try {\n res = await fetch(`${trimTrailingSlash(this.writerUrl)}/api/run`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(identity !== null ? { authorization: `Bearer ${identity}` } : {}),\n },\n body: JSON.stringify(body),\n });\n } catch (e) {\n // A network-level failure (writer unreachable, DNS, connection refused, …) — surface a\n // clear, actionable error rather than an opaque fetch rejection or a silent success.\n throw new Error(\n `helipod: replica write-forward to writer \"${this.writerUrl}\" failed (unreachable) for ${kind} \"${path}\" — ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n const text = await res.text();\n let parsed: WriterRunResponse = {};\n try {\n parsed = text ? (JSON.parse(text) as WriterRunResponse) : {};\n } catch {\n parsed = {};\n }\n if (!res.ok || parsed.error !== undefined) {\n throw new Error(\n parsed.error ??\n `helipod: replica write-forward to writer \"${this.writerUrl}\" returned HTTP ${res.status} for ${kind} \"${path}\"`,\n );\n }\n if (parsed.clientReplay) return { value: parsed.clientReplay.value ?? null, replay: parsed.clientReplay };\n return {\n value: parsed.value ?? null,\n commitTs: parsed.commitTs !== undefined ? Number(parsed.commitTs) : undefined,\n };\n }\n}\n","/**\n * The dev HTTP + WebSocket server. Two backends behind one interface:\n * - **Bun** (primary): `Bun.serve` with native (Zig/uWebSockets-class) WebSockets — far higher\n * connection density; the production path. See docs/dev/architecture/scaling-reality.md.\n * - **Node** (supported): `node:http` + the `ws` package.\n * The HTTP routing ({@link handleHttpRequest}) and static-file resolution are shared and pure.\n */\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { extname, join, resolve, sep } from \"node:path\";\nimport type { EmbeddedRuntime, RuntimeHost, ServeOptions, ServerHandle } from \"@helipod/runtime-embedded\";\nimport type { SyncWebSocket } from \"@helipod/sync\";\nimport type { AdminApi } from \"@helipod/admin\";\nimport type { StorageRoute } from \"@helipod/storage\";\nimport { handleHttpRequest, type ServerInfo, type FleetHandles } from \"./http-handler\";\nimport type { ResolvedRoute } from \"./project\";\nimport type { DeployWireResult } from \"./deploy-apply\";\nimport { detectRuntime } from \"./dev-options\";\n\nconst SYNC_PATH = \"/api/sync\";\nconst STORAGE_PREFIX = \"/api/storage/\";\nconst MAX_BODY_BYTES = 5 * 1024 * 1024;\n\n/**\n * Match an engine-owned `/api/storage/*` request (upload/confirm/serve). These are RESERVED paths\n * spliced into dispatch ahead of user `http.ts` routes and the 404 — the upload/confirm handlers\n * key off method (POST) so a GET `/api/storage/<id>` falls through to the serve handler.\n */\nfunction matchStorageRoute(routes: StorageRoute[] | undefined, method: string, path: string): StorageRoute | undefined {\n if (!routes || !path.startsWith(STORAGE_PREFIX)) return undefined;\n return routes.find((r) => r.method === method && path.startsWith(r.pathPrefix));\n}\n\n/** Match an engine-owned component-contributed route (e.g. auth's `/api/auth/oauth/*`) — same\n * `{method,pathPrefix}` shape as a storage route but not gated to the storage prefix. Dispatched\n * ahead of user `http.ts` routes and the 404, after the storage routes. */\nfunction matchComponentRoute(routes: StorageRoute[] | undefined, method: string, path: string): StorageRoute | undefined {\n if (!routes) return undefined;\n return routes.find((r) => r.method === method && path.startsWith(r.pathPrefix));\n}\n\n/** Methods that carry a request body the server must read (PATCH is used by the admin API). */\nexport function hasBody(method: string | undefined): boolean {\n return method === \"POST\" || method === \"PUT\" || method === \"PATCH\";\n}\n\nconst CONTENT_TYPES: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"text/javascript; charset=utf-8\",\n \".mjs\": \"text/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n};\n\n// `DevServer`/`DevServerOptions` are the process host's concrete instantiations of the neutral\n// `ServerHandle`/`ServeOptions` seam (in `@helipod/runtime-embedded`), pinning its generic\n// parameters to the CLI's own types. The seam carries the per-field docs (lifted verbatim from\n// here); the names are kept so every existing importer (tests, benches, `binary-main`) is unchanged.\n// NOTE: `componentRoutes` (reserved routes contributed by composed components, e.g. auth's OAuth\n// callbacks) lives on the seam's `ServeOptions` alongside `storageRoutes` — see `host.ts`.\nexport type DevServer = ServerHandle<ResolvedRoute>;\nexport type DevServerOptions = ServeOptions<ResolvedRoute, AdminApi, StorageRoute, DeployWireResult, FleetHandles>;\n\n/** Content-type for an embedded dashboard asset, derived from its extension. */\nconst EMBEDDED_CONTENT_TYPES: Record<string, string> = {\n \".js\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".svg\": \"image/svg+xml\",\n \".woff2\": \"font/woff2\",\n \".woff\": \"font/woff\",\n \".png\": \"image/png\",\n \".ico\": \"image/x-icon\",\n \".json\": \"application/json\",\n \".map\": \"application/json\",\n};\n\n/** Minimal structural surface of `Bun.file(path)`, reached only inside a compiled binary. */\ninterface BunFileLike {\n arrayBuffer(): Promise<ArrayBuffer>;\n}\ninterface BunFileRuntime {\n file(path: string): BunFileLike;\n}\n\n/**\n * Serve the dashboard SPA, or null (falls through to a 404).\n * - `distDir` variant (`dev`/`serve`): unchanged — served under `/_dashboard*`, assets from dist.\n * - `assets` variant (compiled binary): served at the site root — `/` and `/index.html` return the\n * embedded `html`; any other path is looked up in the urlPath→embedded-path map and read via\n * `Bun.file` (only reachable here, inside a compiled Bun binary — dev/serve never pass this variant).\n */\nasync function serveDashboard(\n path: string,\n d: { distDir: string; html: string } | { assets: Record<string, string>; html: string },\n): Promise<{ contentType: string; body: string | Buffer | Uint8Array } | null> {\n if (\"distDir\" in d) {\n if (path === \"/_dashboard\" || path === \"/_dashboard/\" || path === \"/_dashboard/index.html\")\n return { contentType: \"text/html; charset=utf-8\", body: d.html };\n if (path.startsWith(\"/_dashboard/\")) {\n return resolveStatic(d.distDir, path.slice(\"/_dashboard\".length));\n }\n return null;\n }\n if (path === \"/\" || path === \"/index.html\") return { contentType: \"text/html\", body: d.html };\n // The dashboard's `index.html` is built with vite `base: \"/_dashboard/\"` (the dev/serve mount\n // point), so its <script>/<link> tags reference `/_dashboard/assets/...` even though the embedded\n // asset map's keys are root-relative (`/assets/...`). Fall back to the un-prefixed key so those\n // requests still resolve when the dashboard is served at the site root.\n const embeddedPath = d.assets[path] ?? (path.startsWith(\"/_dashboard/\") ? d.assets[path.slice(\"/_dashboard\".length)] : undefined);\n if (!embeddedPath) return null;\n const bun = (globalThis as { Bun?: BunFileRuntime }).Bun;\n if (!bun) return null; // unreachable outside a compiled Bun binary\n const body = new Uint8Array(await bun.file(embeddedPath).arrayBuffer());\n return { contentType: EMBEDDED_CONTENT_TYPES[extname(embeddedPath)] ?? \"application/octet-stream\", body };\n}\n\n/** Resolve a static file from `webDir` (with `/` → index.html), guarding against traversal. Pure. */\nfunction resolveStatic(webDir: string, urlPath: string): { contentType: string; body: Buffer } | null {\n const rel = urlPath === \"/\" ? \"/index.html\" : urlPath;\n let root: string;\n let resolved: string;\n try {\n // realpath resolves symlinks too, so neither `..` nor a symlink can escape the web root.\n root = realpathSync(resolve(webDir));\n resolved = realpathSync(resolve(join(webDir, rel)));\n } catch {\n return null;\n }\n // Require the resolved path to be the root itself or strictly underneath it (`root + sep`).\n if (resolved !== root && !resolved.startsWith(root + sep)) return null;\n if (!statSync(resolved).isFile()) return null;\n return { contentType: CONTENT_TYPES[extname(resolved)] ?? \"application/octet-stream\", body: readFileSync(resolved) };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Node backend (node:http + ws) */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Read the raw request body as bytes (a `Buffer`), with no text decoding. This is the ONLY\n * body-reading path that is safe for the engine-owned `/api/storage/*` uploads: an upload body may\n * be arbitrary binary (PNG, PDF, ...), and `handleUpload` reconstructs the exact bytes via\n * `new Uint8Array(await request.arrayBuffer())`. Round-tripping through a decoded/re-encoded utf8\n * string (as {@link readBody} does) would mangle any non-UTF8 byte sequence — see the Task 10\n * fixes report.\n */\nfunction readBodyBytes(req: IncomingMessage): Promise<Buffer> {\n return new Promise((resolvePromise, reject) => {\n const chunks: Buffer[] = [];\n let total = 0;\n req.on(\"data\", (c: Buffer) => {\n total += c.length;\n if (total > MAX_BODY_BYTES) {\n req.destroy();\n reject(new Error(\"request body too large\"));\n return;\n }\n chunks.push(c);\n });\n req.on(\"end\", () => resolvePromise(Buffer.concat(chunks)));\n req.on(\"error\", reject);\n });\n}\n\n/**\n * Text variant of {@link readBodyBytes} for routes that treat the body as utf8 text/JSON (`/api/run`,\n * the admin doc-edit `PATCH`, `httpAction`s, ...). Do NOT use this for the storage upload routes —\n * decoding-then-re-encoding a binary body as utf8 is lossy for non-UTF8 byte sequences.\n */\nfunction readBody(req: IncomingMessage): Promise<string> {\n return readBodyBytes(req).then((b) => b.toString(\"utf8\"));\n}\n\nasync function startNodeServer(runtime: EmbeddedRuntime, options: DevServerOptions): Promise<DevServer> {\n const { WebSocketServer } = (await import(\"ws\")) as typeof import(\"ws\");\n let currentRoutes = options.routes ?? [];\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n void (async () => {\n try {\n const rawUrl = req.url ?? \"/\";\n const url = new URL(rawUrl, \"http://x\");\n const path = url.pathname;\n const needsBody = hasBody(req.method);\n // Storage routes get the raw bytes (binary-safe); every other route keeps the existing\n // utf8-decoded string body. The two are mutually exclusive reads of the same stream.\n const isStorageRequest = path.startsWith(STORAGE_PREFIX);\n const bodyBytes = needsBody && isStorageRequest ? await readBodyBytes(req) : undefined;\n const body = needsBody && !isStorageRequest ? await readBody(req) : undefined;\n const query: Record<string, string> = {};\n url.searchParams.forEach((val, key) => { query[key] = val; });\n const authorization = req.headers.authorization ?? undefined;\n const headers = Object.fromEntries(\n Object.entries(req.headers).filter((e): e is [string, string] => typeof e[1] === \"string\"),\n );\n if ((req.method ?? \"GET\") === \"GET\" && options.dashboard) {\n const dash = await serveDashboard(path, options.dashboard);\n if (dash) {\n res.writeHead(200, { \"content-type\": dash.contentType });\n res.end(dash.body);\n return;\n }\n }\n // Engine-owned `/api/storage/*` — dispatch to the native Web handler and stream its Response\n // (bytes, 302 redirects, 206 partials) back through node:http verbatim.\n const storageRoute = matchStorageRoute(options.storageRoutes, req.method ?? \"GET\", path);\n if (storageRoute) {\n const storageHeaders = new Headers(headers);\n if (authorization && !storageHeaders.has(\"authorization\")) storageHeaders.set(\"authorization\", authorization);\n const request = new Request(`http://${storageHeaders.get(\"host\") ?? \"localhost\"}${rawUrl}`, {\n method: req.method ?? \"GET\",\n headers: storageHeaders,\n // Raw bytes, NOT the utf8-decoded `body` string — see `readBodyBytes`'s doc comment.\n // (Copied into a plain `Uint8Array<ArrayBuffer>` — `Buffer`'s `.buffer` is typed\n // `ArrayBufferLike`, which doesn't structurally satisfy DOM lib's `BodyInit`.)\n ...(needsBody && bodyBytes !== undefined ? { body: new Uint8Array(bodyBytes) } : {}),\n });\n const response = await storageRoute.handler(request);\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((v, k) => { outHeaders[k] = v; });\n res.writeHead(response.status, outHeaders);\n res.end(Buffer.from(await response.arrayBuffer()));\n return;\n }\n const componentRoute = matchComponentRoute(options.componentRoutes, req.method ?? \"GET\", path);\n if (componentRoute) {\n const compHeaders = new Headers(headers);\n if (authorization && !compHeaders.has(\"authorization\")) compHeaders.set(\"authorization\", authorization);\n const request = new Request(`http://${compHeaders.get(\"host\") ?? \"localhost\"}${rawUrl}`, {\n method: req.method ?? \"GET\",\n headers: compHeaders,\n ...(needsBody && !isStorageRequest && body !== undefined ? { body } : {}),\n });\n const response = await componentRoute.handler(request);\n const outHeaders: Record<string, string> = {};\n response.headers.forEach((v, k) => { outHeaders[k] = v; });\n res.writeHead(response.status, outHeaders);\n res.end(Buffer.from(await response.arrayBuffer()));\n return;\n }\n // Derive server info live per request from the runtime — a boot-time snapshot goes stale\n // after the first setModules hot-swap (dev reload / deploy).\n const info: ServerInfo = { functions: runtime.functionPaths(), tables: runtime.tableNames() };\n const response = await handleHttpRequest(\n runtime,\n { method: req.method ?? \"GET\", path, body, query, authorization, headers },\n info,\n options.admin,\n currentRoutes,\n options.deploy,\n options.fleet,\n options.replicaWriterUrl,\n );\n if (response.status === 404 && (req.method ?? \"GET\") === \"GET\" && options.webDir) {\n const file = resolveStatic(options.webDir, path);\n if (file) {\n res.writeHead(200, { \"content-type\": file.contentType });\n res.end(file.body);\n return;\n }\n }\n res.writeHead(response.status, response.headers);\n res.end(response.body);\n } catch (e) {\n res.writeHead(500, { \"content-type\": \"application/json\" });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }));\n }\n })();\n });\n\n const wss = new WebSocketServer({ noServer: true });\n let sessionCounter = 0;\n server.on(\"upgrade\", (req, socket, head) => {\n if ((req.url ?? \"\").split(\"?\")[0] !== SYNC_PATH) {\n socket.destroy();\n return;\n }\n wss.handleUpgrade(req, socket, head, (ws) => {\n const sessionId = `ws-${++sessionCounter}`;\n const syncSocket: SyncWebSocket = {\n send: (data) => ws.send(data),\n get bufferedAmount() {\n return ws.bufferedAmount;\n },\n close: () => ws.close(),\n ping: (onPong) => {\n ws.once(\"pong\", onPong);\n ws.ping();\n },\n };\n runtime.handler.connect(sessionId, syncSocket);\n ws.on(\"message\", (data: Buffer) => void runtime.handler.handleMessage(sessionId, data.toString(\"utf8\")));\n ws.on(\"close\", () => runtime.handler.disconnect(sessionId));\n ws.on(\"error\", () => runtime.handler.disconnect(sessionId));\n });\n });\n\n await new Promise<void>((res) => server.listen(options.port, options.ip, res));\n const address = server.address();\n const port = typeof address === \"object\" && address ? address.port : options.port;\n return {\n url: `http://${options.ip}:${port}`,\n port,\n setRoutes: (r) => { currentRoutes = r; },\n close: async () => {\n // Stop component drivers (scheduler event loop, storage orphan-reaper, …) BEFORE tearing the\n // store down, so a driver's wall-clock timer can't fire a sweep against an already-closed\n // store (which surfaces as a \"statement has been finalized\" error out of the reaper). Reload\n // (dev watch / `deploy`) never calls close() — it uses setModules/setRoutes — so this only\n // runs on a genuine shutdown.\n await runtime.stopDrivers();\n await new Promise<void>((res) => {\n for (const c of wss.clients) c.terminate();\n wss.close();\n server.close(() => res());\n });\n },\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Bun backend (Bun.serve native WebSockets) — primary */\n/* -------------------------------------------------------------------------- */\n\ninterface BunWebSocket {\n send(data: string): number;\n close(): void;\n getBufferedAmount(): number;\n ping(): void;\n readonly data: { sessionId: string };\n}\ninterface BunUpgradeServer {\n upgrade(req: Request, options?: { data?: { sessionId: string } }): boolean;\n}\ninterface BunServeHandle {\n port: number;\n stop(closeActiveConnections?: boolean): void;\n}\ninterface BunServeOptions {\n port: number;\n hostname: string;\n maxRequestBodySize: number;\n fetch(req: Request, server: BunUpgradeServer): Response | undefined | Promise<Response | undefined>;\n websocket: {\n open(ws: BunWebSocket): void;\n message(ws: BunWebSocket, message: string | Uint8Array): void;\n close(ws: BunWebSocket): void;\n pong(ws: BunWebSocket): void;\n };\n}\ninterface BunRuntime {\n serve(options: BunServeOptions): BunServeHandle;\n}\n\n/**\n * Per-session pong callbacks for the Bun transport. Bun delivers pongs to ONE config-level\n * `websocket.pong(ws)` handler (not a per-socket listener like node-ws), so the heartbeat\n * controller's `onPong` is stashed here keyed by session id and invoked when the pong lands.\n */\nconst bunPongCallbacks = new Map<string, () => void>();\n\nasync function startBunServer(runtime: EmbeddedRuntime, options: DevServerOptions): Promise<DevServer> {\n const bun = (globalThis as { Bun?: BunRuntime }).Bun;\n if (!bun) throw new Error(\"Bun runtime not available\");\n let sessionCounter = 0;\n let currentRoutes = options.routes ?? [];\n\n const handle = bun.serve({\n port: options.port,\n hostname: options.ip,\n maxRequestBodySize: MAX_BODY_BYTES,\n async fetch(req, server) {\n const url = new URL(req.url);\n const path = url.pathname;\n if (path === SYNC_PATH) {\n const sessionId = `ws-${++sessionCounter}`;\n return server.upgrade(req, { data: { sessionId } }) ? undefined : new Response(\"upgrade failed\", { status: 400 });\n }\n if (req.method === \"GET\" && options.dashboard) {\n const dash = await serveDashboard(path, options.dashboard);\n if (dash) {\n const body = typeof dash.body === \"string\" ? dash.body : new Uint8Array(dash.body);\n return new Response(body, { headers: { \"content-type\": dash.contentType } });\n }\n }\n // Engine-owned `/api/storage/*` — the native `Request` passes straight to the handler, whose\n // `Response` (streamed bytes / 302 / 206) is returned unchanged by Bun.serve.\n const storageRoute = matchStorageRoute(options.storageRoutes, req.method, path);\n if (storageRoute) return await storageRoute.handler(req);\n const componentRoute = matchComponentRoute(options.componentRoutes, req.method, path);\n if (componentRoute) return await componentRoute.handler(req);\n const body = hasBody(req.method) ? await req.text() : undefined;\n const query: Record<string, string> = {};\n url.searchParams.forEach((val, key) => { query[key] = val; });\n const authorization = req.headers.get(\"authorization\") ?? undefined;\n const headers: Record<string, string> = {};\n req.headers.forEach((v, k) => { headers[k] = v; });\n // Derive server info live per request from the runtime — a boot-time snapshot goes stale\n // after the first setModules hot-swap (dev reload / deploy).\n const info: ServerInfo = { functions: runtime.functionPaths(), tables: runtime.tableNames() };\n const response = await handleHttpRequest(\n runtime,\n { method: req.method, path, body, query, authorization, headers },\n info,\n options.admin,\n currentRoutes,\n options.deploy,\n options.fleet,\n options.replicaWriterUrl,\n );\n if (response.status === 404 && req.method === \"GET\" && options.webDir) {\n const file = resolveStatic(options.webDir, path);\n if (file) return new Response(new Uint8Array(file.body), { headers: { \"content-type\": file.contentType } });\n }\n return new Response(response.body, { status: response.status, headers: response.headers });\n },\n websocket: {\n open(ws) {\n const syncSocket: SyncWebSocket = {\n send: (data) => void ws.send(data),\n get bufferedAmount() {\n return ws.getBufferedAmount();\n },\n close: () => ws.close(),\n ping: (onPong) => {\n bunPongCallbacks.set(ws.data.sessionId, onPong);\n ws.ping();\n },\n };\n runtime.handler.connect(ws.data.sessionId, syncSocket);\n },\n message(ws, message) {\n void runtime.handler.handleMessage(ws.data.sessionId, typeof message === \"string\" ? message : new TextDecoder().decode(message));\n },\n close(ws) {\n bunPongCallbacks.delete(ws.data.sessionId);\n runtime.handler.disconnect(ws.data.sessionId);\n },\n pong(ws) {\n // Bun fires the config-level pong handler; route it to the session's stashed onPong.\n const cb = bunPongCallbacks.get(ws.data.sessionId);\n bunPongCallbacks.delete(ws.data.sessionId);\n cb?.();\n },\n },\n });\n\n return {\n url: `http://${options.ip}:${handle.port}`,\n port: handle.port,\n setRoutes: (r) => { currentRoutes = r; },\n close: async () => {\n // See the Node backend's close(): stop drivers before the store goes away.\n await runtime.stopDrivers();\n handle.stop(true);\n },\n };\n}\n\n/** Start the dev server using the best backend for the current runtime. */\nexport function startDevServer(runtime: EmbeddedRuntime, options: DevServerOptions): Promise<DevServer> {\n return detectRuntime() === \"bun\" ? startBunServer(runtime, options) : startNodeServer(runtime, options);\n}\n\n/**\n * The process {@link RuntimeHost}: binds a runtime to a real TCP port via `Bun.serve` (primary) or\n * `node:http` + `ws`. This class is the ONLY place in the CLI that owns those host primitives — the\n * `detectRuntime()` bun/node split is its private internal (in {@link startDevServer}). Production\n * entrypoints (`dev`/`serve`/`binary`) reach serving exclusively through `host.serve(...)`; a\n * Durable Object host (Slice 3) will implement the same seam without touching any of the above.\n * `serve` is a thin delegation to {@link startDevServer}, which stays exported for tests/benches.\n */\nexport class ProcessRuntimeHost\n implements RuntimeHost<ResolvedRoute, AdminApi, StorageRoute, DeployWireResult, FleetHandles>\n{\n serve(runtime: EmbeddedRuntime, options: DevServerOptions): Promise<DevServer> {\n return startDevServer(runtime, options);\n }\n}\n","/**\n * A small debounced watch loop. The fs-watch wiring is injected so the debounce/dispatch\n * logic is testable without touching the filesystem.\n */\nexport type WatchTriggerReason = \"initial\" | \"change\";\n\nexport interface WatchLoopOptions {\n /** Subscribe to raw change events; return an unsubscribe. */\n subscribe: (onChange: () => void) => () => void;\n /** Called (debounced) to rebuild; reason \"initial\" fires once up front. */\n onTrigger: (reason: WatchTriggerReason) => void | Promise<void>;\n debounceMs?: number;\n /** Injectable timer for tests. */\n setTimer?: (fn: () => void, ms: number) => unknown;\n clearTimer?: (handle: unknown) => void;\n}\n\nexport interface WatchLoop {\n start(): void;\n stop(): void;\n}\n\nexport function createWatchLoop(options: WatchLoopOptions): WatchLoop {\n const debounceMs = options.debounceMs ?? 50;\n const setTimer = options.setTimer ?? ((fn, ms) => setTimeout(fn, ms));\n const clearTimer = options.clearTimer ?? ((h) => clearTimeout(h as ReturnType<typeof setTimeout>));\n let timer: unknown = null;\n let unsubscribe: (() => void) | null = null;\n\n const fire = () => {\n timer = null;\n void options.onTrigger(\"change\");\n };\n\n return {\n start(): void {\n void options.onTrigger(\"initial\");\n unsubscribe = options.subscribe(() => {\n if (timer !== null) clearTimer(timer);\n timer = setTimer(fire, debounceMs);\n });\n },\n stop(): void {\n if (timer !== null) clearTimer(timer);\n unsubscribe?.();\n unsubscribe = null;\n },\n };\n}\n","/**\n * `helipod` CLI. `dev` loads the project, generates `_generated/`, boots the embedded\n * engine, serves HTTP, and hot-reloads on change. `codegen` just regenerates types.\n */\nimport { watch as fsWatch } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { writeGenerated } from \"@helipod/codegen\";\nimport { generateAdminKey } from \"@helipod/admin\";\nimport { resolveDevOptions, type DevOptions } from \"./dev-options\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { resolveFunctionsDir, ensureFunctionsDirExists } from \"./functions-dir\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { bootProject, loadDashboard, withStorageModules } from \"./boot\";\nimport { ProcessRuntimeHost } from \"./server\";\nimport { createWatchLoop } from \"./watch\";\nimport { serveCommand } from \"./serve\";\nimport { deployCommand } from \"./deploy\";\nimport { buildCommand } from \"./build\";\nimport { migrateCommand } from \"./migrate\";\nimport { fleetCommand } from \"./fleet\";\nimport { objectstoreCommand } from \"./objectstore\";\n\nfunction parseFlags(args: string[]): DevOptions {\n const out: DevOptions = {};\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--port\" && args[i + 1]) out.port = Number(args[++i]);\n else if (a === \"--ip\" && args[i + 1]) out.ip = args[++i];\n else if (a === \"--dir\" && args[i + 1]) out.functionsDir = args[++i];\n else if (a === \"--data\" && args[i + 1]) out.dataPath = args[++i];\n else if (a === \"--web\" && args[i + 1]) out.webDir = args[++i];\n else if (a === \"--database-url\" && args[i + 1]) out.databaseUrl = args[++i];\n else if (a === \"--storage-bucket\" && args[i + 1]) out.storageBucket = args[++i];\n else if (a === \"--storage-endpoint\" && args[i + 1]) out.storageEndpoint = args[++i];\n }\n return out;\n}\n\nexport async function devCommand(args: string[]): Promise<number> {\n const flags = parseFlags(args);\n const { functionsDir, projectRoot } = await resolveFunctionsDir(flags.functionsDir, process.cwd());\n if (!ensureFunctionsDirExists(functionsDir)) {\n return 1;\n }\n const opts = resolveDevOptions({ ...flags, functionsDir });\n const generatedDir = join(opts.functionsDir, \"_generated\");\n\n const config = await loadConfig(projectRoot);\n\n // Treat an empty/whitespace HELIPOD_ADMIN_KEY as unset (a blank key would 401 everything).\n const envKey = process.env.HELIPOD_ADMIN_KEY?.trim();\n if (process.env.HELIPOD_ADMIN_KEY !== undefined && !envKey) {\n process.stderr.write(\"⚠ HELIPOD_ADMIN_KEY is set but empty — generating an ephemeral key instead.\\n\");\n }\n const adminKey = envKey || generateAdminKey();\n const ephemeralKey = !envKey; // a generated per-run key, not the operator's persistent secret\n const loopback = [\"127.0.0.1\", \"::1\", \"localhost\"].includes(opts.ip);\n\n const { runtime, adminApi, project, generated, store, logSink, storageRoutes } = await bootProject({\n functionsDir: opts.functionsDir,\n dataPath: opts.dataPath,\n adminKey,\n databaseUrl: opts.databaseUrl,\n storage: { bucket: opts.storageBucket, endpoint: opts.storageEndpoint },\n });\n writeGenerated(generated.files, generatedDir);\n\n // Only inject the key into the (unauthenticated) dashboard HTML when it's an ephemeral key on a\n // loopback bind — never embed a persistent HELIPOD_ADMIN_KEY where any network client can read\n // it. Otherwise serve the SPA without a key so it prompts the operator (stored client-side).\n const dashboard = loadDashboard(ephemeralKey && loopback ? adminKey : undefined);\n // Reach serving through the RuntimeHost seam (Slice 1) — the CLI never touches Bun.serve/node:http.\n const host = new ProcessRuntimeHost();\n const server = await host.serve(\n runtime,\n { port: opts.port, ip: opts.ip, webDir: opts.webDir, admin: { api: adminApi, key: adminKey }, dashboard, routes: project.routes, storageRoutes },\n );\n process.stdout.write(`helipod dev → ${server.url} (dashboard: ${server.url}/_dashboard)\\n`);\n if (!dashboard) process.stdout.write(` (dashboard SPA not built — run \\`bun run --filter @helipod/dashboard build\\`)\\n`);\n process.stdout.write(`admin key → ${adminKey}\\n`);\n if (opts.webDir) process.stdout.write(`web UI → ${server.url}/\\n`);\n\n const watcher = createWatchLoop({\n subscribe: (onChange) => {\n const w = fsWatch(resolve(opts.functionsDir), { recursive: true }, (_e, file) => {\n if (file && !String(file).includes(\"_generated\")) onChange();\n });\n return () => w.close();\n },\n onTrigger: async (reason) => {\n if (reason === \"initial\") return; // already pushed above\n try {\n const next = push(await loadFunctionsDir(opts.functionsDir), config.components);\n writeGenerated(next.generated.files, generatedDir);\n // Re-apply the always-on `_storage:*` built-ins: `setModules` replaces `modules` wholesale.\n runtime.setModules(withStorageModules(next.project.moduleMap));\n server.setRoutes(next.project.routes);\n process.stdout.write(`↻ pushed (${Object.keys(next.project.moduleMap).length} functions)\\n`);\n } catch (e) {\n process.stderr.write(`✗ reload failed: ${e instanceof Error ? e.message : String(e)}\\n`);\n }\n },\n });\n watcher.start();\n\n return new Promise<number>(() => {\n // Run until the process is killed.\n });\n}\n\nexport async function codegenCommand(args: string[]): Promise<number> {\n const flags = parseFlags(args);\n // Same two-step resolve as `devCommand`: consult `functionsDir` in helipod.config.ts when\n // `--dir` isn't given, instead of `resolveDevOptions`'s own bare `?? DEFAULT_FUNCTIONS_DIR`\n // fallback (which never reads the config file) — otherwise `codegen` and `dev` could disagree\n // about where the functions live on a project that sets the config key.\n const { functionsDir } = await resolveFunctionsDir(flags.functionsDir, process.cwd());\n if (!ensureFunctionsDirExists(functionsDir)) return 1;\n const opts = resolveDevOptions({ ...flags, functionsDir });\n const loaded = await loadFunctionsDir(opts.functionsDir);\n const config = await loadConfig(dirname(opts.functionsDir));\n const { generated } = push(loaded, config.components);\n writeGenerated(generated.files, join(opts.functionsDir, \"_generated\"));\n process.stdout.write(`generated ${opts.functionsDir}/_generated\\n`);\n return 0;\n}\n\nfunction printHelp(): void {\n process.stdout.write(\n [\n \"helipod - the reactive backend you self-host\",\n \"\",\n \"Usage: helipod <command> [options]\",\n \"\",\n \"Commands:\",\n \" dev Run the engine with hot reload + dashboard\",\n \" serve Run the production server (requires HELIPOD_ADMIN_KEY)\",\n \" deploy Deploy the app: --target <serve|cloudflare|docker|railway|fly|aws> --env <name> [--dry-run] [--check]\",\n \" build Compile the app to a self-contained executable (bun build --compile)\",\n \" migrate Migrate a Convex project into Helipod (imports + report)\",\n \" migrate export --url <src> --out dump.json Export app data to a portable dump\",\n \" migrate import --url <dst> --in dump.json Import a dump into a deployment\",\n \" codegen Regenerate <functionsDir>/_generated types\",\n \" fleet reshard --shards M --database-url <url> Change a STOPPED fleet's shard count\",\n \" objectstore reshard --shards M --object-store <url> --dir <functionsDir> Change a STOPPED object-storage deployment's shard count\",\n \" help Show this help\",\n \"\",\n \"Options: --port <n> --ip <addr> --dir <functionsDir> --data <dbPath> --database-url <url>\",\n \"Deploy: --target <name> --env <name> --dry-run --check (default target: serve; default env: production)\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n\nexport async function runCli(argv: string[]): Promise<number> {\n const [cmd, ...rest] = argv;\n switch (cmd) {\n case \"dev\":\n return devCommand(rest);\n case \"serve\":\n return serveCommand(rest);\n case \"deploy\":\n return deployCommand(rest);\n case \"build\":\n return buildCommand(rest);\n case \"migrate\":\n return migrateCommand(rest);\n case \"codegen\":\n return codegenCommand(rest);\n case \"fleet\":\n return fleetCommand(rest);\n case \"objectstore\":\n return objectstoreCommand(rest);\n case \"help\":\n case \"--help\":\n case \"-h\":\n case undefined:\n printHelp();\n return 0;\n default:\n process.stderr.write(`unknown command: ${cmd}\\n`);\n printHelp();\n return 1;\n }\n}\n","/**\n * `helipod serve` — the production server. Unlike `dev`: requires a persistent admin key,\n * binds 0.0.0.0, never writes codegen (the mounted functions directory must already contain\n * _generated/), and shuts down gracefully on SIGTERM/SIGINT. Shares the boot core with dev via\n * bootProject().\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { PostgresDocStore } from \"@helipod/docstore-postgres\";\nimport type { DevServer } from \"./server\";\nimport { ProcessRuntimeHost } from \"./server\";\nimport {\n bootProject,\n isPostgresUrl,\n isObjectStoreBootFailFast,\n loadDashboard,\n resolveNumShards,\n parseNumShards,\n makePgClient,\n} from \"./boot\";\nimport { applyDeploy } from \"./deploy-apply\";\nimport { httpWakeHost } from \"./wake-host\";\nimport { resolveFunctionsDir, ensureFunctionsDirExists } from \"./functions-dir\";\nimport type { DeploySchema } from \"./schema-diff\";\nimport type { SchemaJsonLike } from \"@helipod/admin\";\nimport type { DocStore } from \"@helipod/docstore\";\nimport type { EmbeddedRuntime, WriteRouter, EmbeddedWriteFanoutAdapter } from \"@helipod/runtime-embedded\";\nimport type { FleetHandles } from \"./http-handler\";\n\n/**\n * Structural mirrors of `@helipod/fleet`'s public surface. Declared locally (not imported) so\n * core `packages/cli` keeps ZERO static dependency on the enterprise `@helipod/fleet` package —\n * it's loaded only via dynamic `import()` in fleet mode. Keep these in sync with `ee/packages/fleet`.\n * The engine seam types (`WriteRouter`/`EmbeddedWriteFanoutAdapter`) ARE core, so they're imported;\n * `FleetHandles` lives in `./http-handler` (where the proxy consumes it).\n */\n/** The `createEmbeddedRuntime` option deltas `prepareFleetNode` computes (threaded via `bootProject`). */\nexport interface FleetRuntimeOptions {\n store: DocStore;\n writeRouter: WriteRouter;\n deferDrivers: boolean;\n fanoutAdapter?: EmbeddedWriteFanoutAdapter;\n /** Shards B2a: number of shards this node runs — threaded into `createEmbeddedRuntime` (>1 builds a\n * `ShardedTransactor` over the pooled store for per-shard parallel commits). */\n numShards: number;\n /** Fleet B3 hybrid (multi-writer): the replica-backed query store — queries route here while\n * mutations commit to `store` (the primary). Threaded straight into `createEmbeddedRuntime`. */\n queryStore?: DocStore;\n /** Receipted Outbox (verdict §(c) placement): the authoritative receipts store the Connect handshake\n * classifies/prunes against — the PRIMARY on a sync node (whose `store` is the receipt-less replica).\n * Threaded straight into `createEmbeddedRuntime`; absent outside a fleet / on a writer boot. */\n receiptsStore?: DocStore;\n /** Fleet B3 hybrid RYOW: awaited in the runtime's fan-out drain before a local commit's\n * subscription re-runs (wired to the fleet forwarder's replica-catch-up wait). */\n beforeNotify?: (commitTs: bigint) => Promise<void>;\n /** Fleet B4 (T4): group commit — resolved fleet-side from `HELIPOD_GROUP_COMMIT` (mirrors how\n * `@helipod/fleet`'s `node.ts` resolves `HELIPOD_FLEET_MULTI_WRITER`), threaded straight\n * into `createEmbeddedRuntime` via `bootProject`'s `fleet.groupCommit`. Unset → `false`. */\n groupCommit?: boolean;\n /** Triggers D1: the stable-prefix accessor for `DriverContext.readLog` — `min(shard_leases.frontier_ts)`\n * in a fleet (the log tail is gap-free only below the fenced frontier). Threaded straight into\n * `createEmbeddedRuntime`; unset outside a fleet → `readLog` falls back to `store.maxTimestamp()`. */\n stablePrefix?: () => Promise<bigint | null>;\n}\n\n/** `prepareFleetNode`'s result. `client`/`lease`/`forwarder`/`replica`/`switchable` are opaque here\n * — only handed back into `startFleetNode`; the runtime option deltas are what `bootProject`\n * consumes. `pgStore` is the Postgres store (writer runtime store, or a sync node's tail source). */\nexport interface FleetPrep {\n client: unknown;\n pgStore: DocStore;\n replica?: unknown;\n switchable?: unknown;\n /** Sync only: `replica`'s on-disk path — threaded through to `startFleetNode`, which now runs the\n * C7 deployment-id reconcile (deferred there from `prepareFleetNode` so it reads Postgres only\n * after THIS node's own boot has run — see `@helipod/fleet`'s `node.ts`). */\n replicaPath?: string;\n lease: unknown;\n forwarder: unknown;\n role: \"sync\" | \"writer\";\n /** Shards B2a: shard count decided at boot — threaded to `startFleetNode` (acquire-all, seed-all,\n * per-shard guard, idle closer, tailer count gate). */\n numShards: number;\n runtimeOptions: FleetRuntimeOptions;\n}\n\n/** The slice of `@helipod/fleet` serve consumes (via dynamic import). */\nexport interface FleetModule {\n prepareFleetNode(deps: {\n databaseUrl: string;\n advertiseUrl: string;\n adminKey: string;\n dataDir: string;\n /** Lease TTL in ms — the failover-clock knob (see `@helipod/fleet`'s `node.ts`). Threaded from\n * `HELIPOD_FLEET_LEASE_TTL_MS`; undefined → the fleet default (15000). Ops/test tuning. */\n leaseTtlMs?: number;\n /** Shards B2a: shard count (default 8 in the fleet package). T5 owns the persist-once/env story;\n * serve threads a plain number (undefined → fleet default). */\n numShards?: number;\n }): Promise<FleetPrep>;\n startFleetNode(deps: {\n client: unknown;\n pgStore: DocStore;\n runtime: EmbeddedRuntime;\n lease: unknown;\n forwarder: unknown;\n replica?: unknown;\n switchable?: unknown;\n replicaPath?: string;\n /** Shards B2a: from `FleetPrep.numShards` — drives the acquire-all/seed-all/idle-closer. */\n numShards?: number;\n }): Promise<FleetHandles>;\n}\n\nexport interface ServeOptions {\n functionsDir: string;\n dataPath: string;\n ip: string;\n port: number;\n dashboard: boolean;\n /** A static web UI directory to serve at the site root (`index.html` + assets), exactly as `dev`'s\n * `--web` does. Unset → no web UI (today's behavior). Lets a self-hosted `serve` host an app's own\n * frontend on the SAME origin as its sync WebSocket, so a `location.host`-relative client needs no\n * backend-URL config and never makes a cross-origin `/api/sync` connection. */\n webDir?: string;\n /** Enable `POST /_admin/deploy` (`helipod deploy`'s hot-swap target). Off by default — a running\n * `serve` only accepts live code changes when explicitly opted in. */\n allowDeploy: boolean;\n /** Postgres connection string (flag wins over `HELIPOD_DATABASE_URL`); unset → SQLite. */\n databaseUrl?: string;\n /** File-storage backend flag overrides (`--storage-bucket`/`--storage-endpoint`; win over env). */\n storageBucket?: string;\n storageEndpoint?: string;\n /** Test-only: shorten the pending-upload TTL / orphan-reaper sweep so a reap is observable in a\n * test's timescale. Unset → the storage defaults (1h TTL, 60s sweep). Not surfaced as CLI flags. */\n storageUploadTtlMs?: number;\n storageReaperSweepMs?: number;\n /** Tier 2: run this node as part of a symmetric fleet (writer-or-sync, decided at boot by the\n * Postgres write lease). Requires a Postgres `databaseUrl` and an `advertiseUrl`. Optional so\n * existing (non-fleet) `ServeOptions` literals need no change; `resolveServeOptions` always sets it. */\n fleet?: boolean;\n /** The URL other fleet nodes reach THIS node at (recorded on the lease when it's the writer, and\n * the target sync nodes forward writes / proxy httpActions to). Flag wins over env. */\n advertiseUrl?: string;\n /** Tier 3: run this node's store as the object-storage substrate (single-shard writer over the\n * given bucket/dir) instead of SQLite/Postgres — `s3://…`/`s3+http(s)://…`/`file://…`/a bare path,\n * see `objectstore-select.ts`'s grammar doc. Mutually exclusive with `fleet`. Flag wins over env. */\n objectStoreUrl?: string;\n /** Tier 3 Slice 7, Task 7.3: the object-store writer's gc-driver sweep cadence (ms), from\n * `HELIPOD_OBJECTSTORE_GC_MS`. Unset → `boot.ts`'s `DEFAULT_OBJECTSTORE_GC_MS` (~60s). Ignored\n * unless `objectStoreUrl` is set. */\n objectStoreGcMs?: number;\n /** Tier 3 multi-shard single-node serve: the number of object-storage lanes a `--object-store`\n * WRITER owns (`--shards N`, or `HELIPOD_FLEET_SHARDS`). Unset / `1` → single-shard (shard \"0\"),\n * unchanged. `> 1` → this node owns all `shardIdList(N)` lanes. Requires `--object-store`; invalid\n * with `--replica` (replicas are single-shard) or `--fleet` (its own shard resolution). Validated\n * in `serveCommand`. Flag (`--shards`) wins over `HELIPOD_FLEET_SHARDS` env. */\n objectStoreShards?: number;\n /** Tier 3 Slice 8, Task 8.2: boot this node as a READ-ONLY REPLICA of `objectStoreUrl`'s shard\n * (materialize + tail, no write lease — every mutation is rejected) instead of a writer. REQUIRES\n * `objectStoreUrl` (validated in `serveCommand`, before `startServe` is ever called). Optional so\n * existing (non-replica) `ServeOptions` literals need no change; `resolveServeOptions` always\n * sets it. Flag (`--replica`) wins over `HELIPOD_REPLICA` env. */\n replica?: boolean;\n /** Tier 3 Slice 8 follow-on (replica write-forwarding): the writer node's URL — when set on a\n * `--replica` boot, every mutation/action FORWARDS here instead of being rejected. Ignored\n * unless `replica` is also set. Flag (`--writer-url`) wins over `HELIPOD_WRITER_URL` env. */\n writerUrl?: string;\n /** The wake seam's host endpoint (`--wake-url`, wins over `HELIPOD_WAKE_URL`) — for a host that\n * STOPS THE PROCESS between requests, so `setTimeout` never fires and every driver goes dead.\n * Set → `serve` builds an HTTP `WakeHost` that POSTs the next wake's absolute `atMs` here (on\n * Cloudflare, the container's Outbound-Worker hostname, which the Worker turns into a Durable\n * Object alarm). Unset (every existing deployment) → no wake host, plain `setTimeout`. */\n wakeUrl?: string;\n /** Floor for every driver's BACKSTOP poll cadence, ms (`--backstop-min-ms`, wins over\n * `HELIPOD_BACKSTOP_MIN_MS`) — `backstopMs = (d) => Math.max(d, n)`. Unset → identity (the\n * drivers' own 30s/60s). Set where each wake costs a cold start: on Cloudflare a 30s backstop is\n * a container boot every 30s forever. */\n backstopMinMs?: number;\n}\n\n/**\n * Race `promise` against a `ms`-millisecond timeout, resolving to `undefined` (never rejecting)\n * if the timeout wins OR if `promise` itself rejects — used only for genuinely best-effort work\n * (Task 6.6 F1: `objectStoreRelease()`'s bucket CAS at shutdown) where an unbounded hang or a\n * swallowed failure are both acceptable outcomes, so the caller never needs a `try`/`catch`. The\n * loser keeps running in the background (unobserved) — fine here since `objectStoreRelease()`\n * itself never throws (its underlying `relinquish()` swallows CAS errors by design) and the\n * process exits shortly after either way.\n */\nexport function raceWithTimeout(promise: Promise<unknown>, ms: number): Promise<void> {\n return new Promise<void>((resolveOuter) => {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolveOuter();\n }\n }, ms);\n promise.then(\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolveOuter();\n }\n },\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolveOuter();\n }\n },\n );\n });\n}\n\n/** Bound on `objectStoreRelease()` at shutdown (Task 6.6 F1) — `relinquish()` is a live bucket CAS\n * call with no timeout of its own; an unreachable bucket at shutdown could otherwise hang on the\n * AWS SDK's socket timeout, delaying `process.exit(0)` past a container's grace period (→ SIGKILL,\n * skipping the rest of graceful shutdown too). Timing out here is SAFE: the release is best-effort\n * — the lease TTL-expires on its own regardless — so an abandoned relinquish just means the next\n * writer's takeover waits out the full TTL instead of being immediate, not any data-safety loss. */\nexport const OBJECTSTORE_RELINQUISH_TIMEOUT_MS = 2000;\n\n/** Fail-fast messages for `--fleet` misconfiguration (asserted verbatim by `fleet-flags.test.ts`). */\nexport const FLEET_ERR_NO_DB =\n \"fleet mode requires --database-url (Postgres) — set --database-url postgres://… or HELIPOD_DATABASE_URL.\";\nexport const FLEET_ERR_NO_ADVERTISE =\n \"fleet mode requires --advertise-url (or HELIPOD_ADVERTISE_URL) — the URL other fleet nodes reach this node at, e.g. --advertise-url http://10.0.0.2:3000\";\nexport const FLEET_ERR_NO_PACKAGE =\n \"fleet mode requires @helipod/fleet — install it (bun add @helipod/fleet).\";\n\n/**\n * Validate `--fleet` prerequisites. Pure — no I/O; the dynamic-import check (FLEET_ERR_NO_PACKAGE)\n * happens later in `serveCommand`. Only call this when `fleet` is set.\n */\nexport function validateFleetOptions(opts: {\n fleet?: boolean;\n databaseUrl?: string;\n advertiseUrl?: string;\n}): { ok: true; databaseUrl: string; advertiseUrl: string } | { ok: false; error: string } {\n if (!isPostgresUrl(opts.databaseUrl)) return { ok: false, error: FLEET_ERR_NO_DB };\n const advertiseUrl = opts.advertiseUrl?.trim();\n if (!advertiseUrl) return { ok: false, error: FLEET_ERR_NO_ADVERTISE };\n return { ok: true, databaseUrl: opts.databaseUrl!, advertiseUrl };\n}\n\n/** Parse `HELIPOD_FLEET_LEASE_TTL_MS` — a positive finite integer of ms, else undefined (the fleet\n * default applies). Kept here (not in `@helipod/fleet`) so the env read stays at serve's config\n * boundary, alongside the other fleet flags; the fleet package receives a validated number. */\nfunction parseLeaseTtlMs(raw: string | undefined): number | undefined {\n if (raw === undefined || raw.trim() === \"\") return undefined;\n const n = Number(raw);\n return Number.isFinite(n) && n > 0 ? n : undefined;\n}\n\n/**\n * Shards B2a (T5): resolve (and, on a fresh deployment, persist) NUM_SHARDS BEFORE\n * `prepareFleetNode` runs — it needs the final count up front to size the per-shard\n * commit-connection pool, well before `bootProject`'s `createEmbeddedRuntime` ever calls\n * `setupSchema()` on the real runtime store. Opens its own short-lived PgClient (via `makePgClient` —\n * `BunSqlClient` under Bun, `NodePgClient` elsewhere; no commit pool — this is a one-shot KV\n * read/maybe-write, not a shard writer) against the SAME database\n * `--database-url`/`HELIPOD_DATABASE_URL` names, runs `setupSchema()` (idempotent DDL only —\n * `readOnly: true` skips just the writer-lock/ts-seq seeding, not the DDL, so `persistence_globals`\n * is guaranteed to exist afterward even on a brand-new database) and delegates to the shared\n * `resolveNumShards` (same persist-once/mismatch-fail-fast contract non-fleet boot uses in\n * `boot.ts`). Any fleet node — writer or sync — can safely do this: `getGlobal`/\n * `writeGlobalIfAbsent` are plain KV ops, not gated by the store's read-only flag.\n */\nasync function resolveFleetNumShards(databaseUrl: string, envValue: number | undefined): Promise<number> {\n const client = makePgClient(databaseUrl);\n try {\n const probe = new PostgresDocStore(client, { readOnly: true });\n await probe.setupSchema();\n return await resolveNumShards(probe, envValue);\n } finally {\n await client.close();\n }\n}\n\nexport function resolveServeOptions(args: string[]): ServeOptions {\n // The raw `--dir` flag value, captured but NOT defaulted here — \"\" means \"not given\", handled\n // identically to `undefined` by `resolveFunctionsDir` (called later, in `serveCommand`, which also\n // consults `functionsDir` in helipod.config.ts). Resolving eagerly here would bake a literal\n // default in before the config file is ever consulted, silently winning over it — see T3 controller\n // note on the `codegenCommand` gap this whole task exists to close.\n let functionsDir = \"\";\n let dataPath = process.env.HELIPOD_DATA_DIR ? join(process.env.HELIPOD_DATA_DIR, \"db.sqlite\") : \"./data/db.sqlite\";\n let ip = \"0.0.0.0\";\n let port = process.env.PORT ? Number(process.env.PORT) : 3000;\n let dashboard = process.env.HELIPOD_DASHBOARD?.trim().toLowerCase() !== \"off\";\n let allowDeploy = process.env.HELIPOD_ALLOW_DEPLOY === \"1\";\n let webDir = process.env.HELIPOD_WEB_DIR;\n let databaseUrl = process.env.HELIPOD_DATABASE_URL;\n let storageBucket: string | undefined;\n let storageEndpoint: string | undefined;\n let fleet = process.env.HELIPOD_FLEET === \"1\" || process.env.HELIPOD_FLEET?.trim().toLowerCase() === \"true\";\n let advertiseUrl = process.env.HELIPOD_ADVERTISE_URL;\n let objectStoreUrl = process.env.HELIPOD_OBJECT_STORE;\n let replica = /^(1|true|yes)$/i.test(process.env.HELIPOD_REPLICA ?? \"\");\n let writerUrl = process.env.HELIPOD_WRITER_URL;\n // The wake seam (both env-or-flag, flag wins — `objectStoreUrl`'s exact shape above). Unset →\n // no wake host + identity backstops, i.e. byte-for-byte today's behavior.\n let wakeUrl = process.env.HELIPOD_WAKE_URL;\n let backstopMinMs = parseLeaseTtlMs(process.env.HELIPOD_BACKSTOP_MIN_MS);\n // Tier 3 multi-shard single-node serve: object-storage writer lane count. Set ONLY by the\n // `--shards` flag here; the `HELIPOD_FLEET_SHARDS` env fallback is applied AFTER the flag loop\n // and ONLY when `--object-store` is present — otherwise a plain `--fleet` boot (which legitimately\n // reads `HELIPOD_FLEET_SHARDS` for its OWN shard count via `resolveFleetNumShards`) would trip\n // the object-store-only `--shards` validation below.\n let objectStoreShards: number | undefined;\n // Tier 3 Slice 7, Task 7.3: gc-driver cadence — env-only (no CLI flag), mirroring how\n // HELIPOD_FLEET_LEASE_TTL_MS is a pure ops/test tuning knob with no flag equivalent.\n // `parseLeaseTtlMs`'s \"positive finite number, else undefined\" parse is generic, not lease-specific.\n const objectStoreGcMs = parseLeaseTtlMs(process.env.HELIPOD_OBJECTSTORE_GC_MS);\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--dir\" && args[i + 1]) functionsDir = args[++i] as string;\n else if (a === \"--data\" && args[i + 1]) dataPath = args[++i] as string;\n else if (a === \"--ip\" && args[i + 1]) ip = args[++i] as string;\n else if (a === \"--port\" && args[i + 1]) port = Number(args[++i]);\n else if (a === \"--no-dashboard\") dashboard = false;\n else if (a === \"--allow-deploy\") allowDeploy = true;\n else if (a === \"--database-url\" && args[i + 1]) databaseUrl = args[++i] as string;\n else if (a === \"--storage-bucket\" && args[i + 1]) storageBucket = args[++i] as string;\n else if (a === \"--storage-endpoint\" && args[i + 1]) storageEndpoint = args[++i] as string;\n else if (a === \"--fleet\") fleet = true;\n else if (a === \"--advertise-url\" && args[i + 1]) advertiseUrl = args[++i] as string;\n else if (a === \"--object-store\" && args[i + 1]) objectStoreUrl = args[++i] as string;\n else if (a === \"--replica\") replica = true;\n else if (a === \"--writer-url\" && args[i + 1]) writerUrl = args[++i] as string;\n else if (a === \"--shards\" && args[i + 1]) objectStoreShards = Number(args[++i]);\n else if (a === \"--wake-url\" && args[i + 1]) wakeUrl = args[++i] as string;\n else if (a === \"--backstop-min-ms\" && args[i + 1]) backstopMinMs = parseLeaseTtlMs(args[++i]);\n else if (a === \"--web\" && args[i + 1]) webDir = args[++i] as string;\n }\n // `HELIPOD_FLEET_SHARDS` env fallback — ONLY for an object-store boot (never a fleet boot; see\n // the `objectStoreShards` declaration above). The `--shards` flag, if given, always wins.\n if (objectStoreShards === undefined && objectStoreUrl !== undefined) {\n objectStoreShards = parseNumShards(process.env.HELIPOD_FLEET_SHARDS);\n }\n return {\n functionsDir,\n dataPath,\n ip,\n port,\n dashboard,\n ...(webDir !== undefined ? { webDir } : {}),\n allowDeploy,\n databaseUrl,\n storageBucket,\n storageEndpoint,\n fleet,\n advertiseUrl,\n ...(objectStoreUrl !== undefined ? { objectStoreUrl } : {}),\n ...(objectStoreGcMs !== undefined ? { objectStoreGcMs } : {}),\n ...(objectStoreShards !== undefined ? { objectStoreShards } : {}),\n replica,\n ...(writerUrl !== undefined ? { writerUrl } : {}),\n ...(wakeUrl !== undefined ? { wakeUrl } : {}),\n ...(backstopMinMs !== undefined ? { backstopMinMs } : {}),\n };\n}\n\n/**\n * Adapt `AdminApi.getSchema()`'s `SchemaJsonLike` (the data-browser's schema shape) into\n * `DeploySchema[\"schemaJson\"]` (the schema-diff's narrower, required-`documentType` shape) —\n * `AdminApi`'s live schema always carries a real `documentType` for app tables, this just narrows\n * the type safely instead of asserting it.\n */\nfunction toDeploySchema(schemaJson: SchemaJsonLike): DeploySchema[\"schemaJson\"] {\n const tables: DeploySchema[\"schemaJson\"][\"tables\"] = {};\n for (const [name, t] of Object.entries(schemaJson.tables)) {\n const dt = t.documentType;\n tables[name] = { documentType: dt && dt.type === \"object\" ? dt : { type: \"object\", value: {} } };\n }\n return { tables };\n}\n\n/** Testable core: boot + start the server. No signals, no exit, does not block. In fleet mode the\n * caller injects the dynamically-imported `@helipod/fleet` module + resolved config so this core\n * stays free of the enterprise dependency. */\nexport async function startServe(\n opts: ServeOptions & {\n adminKey: string;\n fleetModule?: FleetModule;\n fleetConfig?: { databaseUrl: string; advertiseUrl: string; leaseTtlMs?: number; numShards?: number };\n /** Tier 3 Slice 6: called once, synchronously, the moment the object-store lease-heartbeat driver\n * detects this node has been fenced. `serveCommand` wires this to trigger graceful shutdown; a\n * direct `startServe` test caller may omit it (the driver just logs and stops on its own). */\n onObjectStoreFenced?: (e: Error) => void;\n },\n): Promise<{\n server: DevServer;\n store: DocStore;\n runtime: EmbeddedRuntime;\n fleet?: FleetHandles;\n role?: \"sync\" | \"writer\";\n /** Tier 3 Slice 6: set only when `--object-store` was given — relinquish this node's shard-0\n * lease (Task 6.5: bucket-clearing `store.relinquish()`, for immediate takeover, not just the\n * in-process `release()`). Caller must call this AFTER `server.close()` (stops the heartbeat\n * driver) and BEFORE `store.close()` — see `serveCommand`'s shutdown. */\n objectStoreRelease?: () => Promise<void>;\n}> {\n // The wake seam's backstop policy, resolved once here so the closure captures a plain number\n // rather than re-reading (and re-narrowing) `opts` on every driver call.\n const backstopFloorMs = opts.backstopMinMs;\n\n // Fleet: decide writer-vs-sync via ONE lease tryAcquire BEFORE the runtime is built — its result\n // (writable store, fan-out adapter, deferred drivers, forwarder role) are createEmbeddedRuntime inputs.\n const prep =\n opts.fleet && opts.fleetModule && opts.fleetConfig\n ? await opts.fleetModule.prepareFleetNode({\n ...opts.fleetConfig,\n adminKey: opts.adminKey,\n // A sync node's local replica lives beside the data file (same dir the SQLite store uses).\n dataDir: dirname(resolve(opts.dataPath)),\n })\n : undefined;\n\n const { runtime, adminApi, project, store, components, storageRoutes, componentRoutes, objectStoreRelease, replicaWriterUrl } =\n await bootProject({\n functionsDir: opts.functionsDir,\n dataPath: opts.dataPath,\n adminKey: opts.adminKey,\n databaseUrl: opts.databaseUrl,\n storage: { bucket: opts.storageBucket, endpoint: opts.storageEndpoint },\n ...(opts.storageUploadTtlMs !== undefined ? { storageUploadTtlMs: opts.storageUploadTtlMs } : {}),\n ...(opts.storageReaperSweepMs !== undefined ? { storageReaperSweepMs: opts.storageReaperSweepMs } : {}),\n ...(prep ? { fleet: prep.runtimeOptions } : {}),\n ...(opts.objectStoreUrl !== undefined ? { objectStoreUrl: opts.objectStoreUrl } : {}),\n ...(opts.onObjectStoreFenced ? { objectStoreOnFenced: opts.onObjectStoreFenced } : {}),\n ...(opts.objectStoreGcMs !== undefined ? { objectStoreGcMs: opts.objectStoreGcMs } : {}),\n ...(opts.replica ? { replica: opts.replica } : {}),\n ...(opts.writerUrl !== undefined ? { writerUrl: opts.writerUrl } : {}),\n ...(opts.objectStoreShards !== undefined ? { objectStoreShards: opts.objectStoreShards } : {}),\n // The wake seam (`--wake-url`/`--backstop-min-ms`): a host that stops the process between\n // requests. Both unset (every existing deployment) → no keys, plain `setTimeout` + the drivers'\n // own 30s/60s backstops.\n ...(opts.wakeUrl !== undefined ? { wakeHost: httpWakeHost(opts.wakeUrl) } : {}),\n ...(backstopFloorMs !== undefined ? { backstopMs: (d: number) => Math.max(d, backstopFloorMs) } : {}),\n });\n // No embedded key (0.0.0.0 bind): the dashboard SPA prompts the operator for the admin key.\n const dashboard = opts.dashboard ? loadDashboard(undefined) : undefined;\n\n // Start the fleet node (sync: replica tailer + acquire loop; writer: already live) BEFORE the HTTP\n // server, so its handles exist to pass in. The http layer reads `role()` live per request, so\n // there's no ordering hazard with promotion.\n const fleet =\n prep && opts.fleetModule\n ? await opts.fleetModule.startFleetNode({\n client: prep.client,\n pgStore: prep.pgStore,\n runtime,\n lease: prep.lease,\n forwarder: prep.forwarder,\n replica: prep.replica,\n switchable: prep.switchable,\n replicaPath: prep.replicaPath,\n numShards: prep.numShards,\n })\n : undefined;\n\n // `server` is assigned below by `host.serve`; `setRoutes` only runs on a LATER deploy\n // request, by which time it is set. `current` reads AdminApi's live schema — no serve-side\n // bookkeeping to keep in sync.\n let server: DevServer;\n // The modules from the last successful push this server lifetime — starts empty, so the first\n // deploy after (re)start is a full push and every later one is a true delta. Holds code (for\n // reconstructing `unchanged` entries) — NEVER serialized to the wire.\n let currentPushedModules = new Map<string, { code: string; sha: string }>();\n const deploy = opts.allowDeploy\n ? {\n apply: async (\n payload:\n | { files: Array<{ path: string; code: string }> }\n | { changed: Array<{ path: string; code: string }>; unchanged: Array<{ path: string; sha256: string }> },\n ) => {\n const result = await applyDeploy(\n {\n runtime,\n adminApi,\n setRoutes: (r) => server.setRoutes(r),\n components,\n current: () => {\n const live = adminApi.getSchema();\n return { schemaJson: toDeploySchema(live.schemaJson), tableNumbers: live.tableNumbers };\n },\n deployRoot: join(process.cwd(), \".helipod-deploy\"),\n currentModules: currentPushedModules,\n },\n payload,\n );\n if (!result.ok) return result; // { ok:false, kind, error } — wire-safe (no Map)\n currentPushedModules = result.modules; // update state; strip the Map from the wire result\n return { ok: true as const, rev: result.rev, functions: result.functions };\n },\n modules: (): Record<string, string> =>\n Object.fromEntries([...currentPushedModules].map(([p, v]) => [p, v.sha])),\n }\n : undefined;\n // Reach serving through the RuntimeHost seam (Slice 1) — serve() never touches Bun.serve/node:http.\n server = await new ProcessRuntimeHost().serve(\n runtime,\n {\n port: opts.port,\n ip: opts.ip,\n ...(opts.webDir !== undefined ? { webDir: opts.webDir } : {}),\n admin: { api: adminApi, key: opts.adminKey },\n dashboard,\n routes: project.routes,\n storageRoutes,\n componentRoutes,\n deploy,\n fleet,\n ...(replicaWriterUrl !== undefined ? { replicaWriterUrl } : {}),\n },\n );\n return { server, store, runtime, fleet, role: prep?.role, ...(objectStoreRelease ? { objectStoreRelease } : {}) };\n}\n\n/** CLI wrapper: flags → fail-fast → startServe → signal handlers → run forever. */\nexport async function serveCommand(args: string[]): Promise<number> {\n const opts = resolveServeOptions(args);\n const adminKey = process.env.HELIPOD_ADMIN_KEY?.trim();\n // Admin key first: an operator missing BOTH the key and the functions directory should see the\n // key error, not have it masked by a directory error — this is the more fundamental misconfiguration\n // and was already serve's first fail-fast check before this task.\n if (!adminKey) {\n process.stderr.write(\"✗ HELIPOD_ADMIN_KEY is required for `serve` — set it to a strong secret.\\n\");\n return 1;\n }\n // Resolve the functions directory (flag > helipod.config.ts `functionsDir` > DEFAULT_FUNCTIONS_DIR)\n // and fail loudly — with the migrate hint — if it doesn't exist at all, before falling through to\n // the narrower \"_generated/ missing\" check below (which assumes the directory itself is real).\n const { functionsDir } = await resolveFunctionsDir(opts.functionsDir || undefined, process.cwd());\n if (!ensureFunctionsDirExists(functionsDir)) return 1;\n opts.functionsDir = functionsDir;\n if (!existsSync(join(opts.functionsDir, \"_generated\", \"server.ts\"))) {\n process.stderr.write(\n `✗ ${opts.functionsDir}/_generated not found — run \\`helipod codegen --dir ${opts.functionsDir}\\` and commit _generated/ before deploying.\\n`,\n );\n return 1;\n }\n\n if (opts.fleet && opts.objectStoreUrl !== undefined) {\n process.stderr.write(\n \"✗ --object-store cannot be combined with --fleet (Tier 2) — pick one write-scaling story.\\n\",\n );\n return 1;\n }\n\n // Tier 3 Slice 8, Task 8.2: `--replica` only makes sense over an object-storage bucket — fail\n // fast, synchronously, before any boot work starts (mirrors the fleet+object-store mutual-\n // exclusion check just above).\n if (opts.replica && opts.objectStoreUrl === undefined) {\n process.stderr.write(\n \"✗ --replica requires --object-store — a replica materializes from an object-storage bucket; \" +\n \"set --object-store <url> (or HELIPOD_OBJECT_STORE).\\n\",\n );\n return 1;\n }\n\n // Tier 3 multi-shard single-node serve: `--shards N` (N>1) is an object-storage WRITER concept —\n // reject the combinations that can't mean it, rather than silently ignoring it.\n if (opts.objectStoreShards !== undefined && opts.objectStoreShards > 1) {\n if (opts.objectStoreUrl === undefined) {\n process.stderr.write(\n \"✗ --shards N (N>1) requires --object-store — it sizes the object-storage writer's lane count; \" +\n \"set --object-store <url>, or drop --shards.\\n\",\n );\n return 1;\n }\n if (opts.replica) {\n process.stderr.write(\n \"✗ --shards cannot be combined with --replica — a replica is single-shard (it tails shard 0); \" +\n \"run the multi-shard WRITER with --shards and point replicas at it.\\n\",\n );\n return 1;\n }\n if (!Number.isInteger(opts.objectStoreShards)) {\n process.stderr.write(`✗ --shards must be a positive integer, got \"${opts.objectStoreShards}\".\\n`);\n return 1;\n }\n }\n\n // Tier 3 Slice 8 follow-on (replica write-forwarding): `--writer-url` only means something on a\n // replica — fail fast rather than silently ignore it (which would look like forwarding is\n // configured when it isn't).\n if (opts.writerUrl !== undefined && !opts.replica) {\n process.stderr.write(\n \"✗ --writer-url only applies to --replica (it's the writer this replica forwards mutations/\" +\n \"actions to) — pass --replica too, or drop --writer-url (or HELIPOD_WRITER_URL).\\n\",\n );\n return 1;\n }\n\n // Fleet mode: validate prerequisites and load the enterprise package (dynamic import only —\n // never a static dependency of core cli), failing fast with actionable messages.\n let fleetModule: FleetModule | undefined;\n let fleetConfig: { databaseUrl: string; advertiseUrl: string; leaseTtlMs?: number; numShards?: number } | undefined;\n if (opts.fleet) {\n const v = validateFleetOptions(opts);\n if (!v.ok) {\n process.stderr.write(`✗ ${v.error}\\n`);\n return 1;\n }\n try {\n // Indirect specifier (typed `string`, not a literal) so tsc does NOT statically resolve\n // `@helipod/fleet` — core cli has no static/type dependency on the enterprise package; it's\n // resolved at runtime via the workspace link. See package.json (fleet is deliberately absent).\n const fleetSpecifier: string = \"@helipod/fleet\";\n fleetModule = (await import(fleetSpecifier)) as unknown as FleetModule;\n } catch {\n process.stderr.write(`✗ ${FLEET_ERR_NO_PACKAGE}\\n`);\n return 1;\n }\n // `HELIPOD_FLEET_SHARDS` (Shards B2a, T5): NUM_SHARDS, persisted once at first boot and\n // immutable after — resolved BEFORE `prepareFleetNode` (which needs the final count up front\n // to size the per-shard commit pool). A mismatch against the persisted count fails boot fast.\n let numShards: number;\n try {\n numShards = await resolveFleetNumShards(v.databaseUrl, parseNumShards(process.env.HELIPOD_FLEET_SHARDS));\n } catch (e) {\n process.stderr.write(`✗ ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n // `HELIPOD_FLEET_LEASE_TTL_MS` (ops/test tuning): the lease TTL in ms, the single knob the\n // whole failover clock scales from inside `@helipod/fleet` (heartbeat + acquire cadences are\n // derived from it). Unset → the fleet default (15000ms, behavior-identical to the historical\n // constants). Only a positive finite number is honored; anything else falls through to the\n // default. The wedged-writer E2E sets this to 4000 so failover completes in a test's timescale.\n fleetConfig = {\n databaseUrl: v.databaseUrl,\n advertiseUrl: v.advertiseUrl,\n leaseTtlMs: parseLeaseTtlMs(process.env.HELIPOD_FLEET_LEASE_TTL_MS),\n numShards,\n };\n }\n\n // Tier 3 Slice 6: a forward-reference trampoline — `startServe` needs `onObjectStoreFenced` BEFORE\n // it resolves (so it can thread it into the lease-heartbeat driver at boot), but `shutdown` (which\n // the fence should trigger) can only be defined AFTER `startServe` resolves (it closes over\n // `server`/`store`/`objectStoreRelease`, all part of `startServe`'s result). The indirection lets a\n // fence detected mid-boot-window-adjacent still trigger a real graceful shutdown once one exists.\n let triggerObjectStoreFencedShutdown: (() => void) | undefined;\n let booted: Awaited<ReturnType<typeof startServe>>;\n try {\n booted = await startServe({\n ...opts,\n adminKey,\n fleetModule,\n fleetConfig,\n onObjectStoreFenced: (e) => {\n process.stderr.write(`✗ object-store lease lost — shutting down: ${e.message}\\n`);\n triggerObjectStoreFencedShutdown?.();\n },\n });\n } catch (e) {\n // Task 6.6 F2: mirror the fleet path's clean-message UX for the object-store boot fail-fasts\n // (ee-package missing, acquire-timeout \"held by\", bad --object-store URL/creds) — these are\n // KNOWN, actionable misconfigurations, not crashes. Anything else (a genuine bug) is NOT\n // swallowed here — rethrow so it surfaces with its full stack via `bin.ts`'s catch-all, same as\n // before this fix, rather than being misreported as a tidy one-liner.\n if (isObjectStoreBootFailFast(e)) {\n process.stderr.write(`✗ ${e.message}\\n`);\n return 1;\n }\n throw e;\n }\n const { server, store, role, fleet, objectStoreRelease } = booted;\n process.stdout.write(\n JSON.stringify({\n level: \"info\",\n msg: \"helipod serve\",\n url: server.url,\n dir: opts.functionsDir,\n data: opts.dataPath,\n dashboard: opts.dashboard,\n allowDeploy: opts.allowDeploy,\n // Additive: present only in fleet mode. Task 7's 2-process E2E asserts each node's role here.\n ...(role ? { fleet: true, role } : {}),\n // Additive: present only in object-store mode (Tier 3 Slice 6).\n ...(opts.objectStoreUrl !== undefined ? { objectStore: true } : {}),\n // Additive: present only for a read-only replica node (Tier 3 Slice 8, Task 8.2).\n ...(opts.replica ? { replica: true } : {}),\n // Additive: present only when this replica forwards writes (Tier 3 Slice 8 follow-on).\n ...(opts.writerUrl !== undefined ? { writerUrl: opts.writerUrl } : {}),\n }) + \"\\n\",\n );\n\n let closing = false;\n const shutdown = async (): Promise<void> => {\n if (closing) return;\n closing = true;\n process.stdout.write(JSON.stringify({ level: \"info\", msg: \"shutting down\" }) + \"\\n\");\n // Stop the fleet node (lease acquire loop / replica tailer) before the store closes.\n if (fleet) await fleet.stop();\n // `server.close()` stops every registered driver first (including the object-store\n // lease-heartbeat driver, if any) — release the lease only AFTER that, so a heartbeat tick can\n // never race a voluntary release into a spurious \"fenced\" log during normal shutdown.\n await server.close();\n // Task 6.5: this calls `store.relinquish()`, which best-effort CAS-clears the lease in the\n // bucket itself — awaited so a challenger's takeover on the next poll is genuinely immediate,\n // not merely started-and-abandoned by an unhandled shutdown-time rejection.\n // Task 6.6 F1: bounded — see `raceWithTimeout`'s doc comment. An unreachable bucket must not be\n // able to hang shutdown past the container's grace period; timing out here is safe because the\n // release is best-effort (the lease TTL-expires on its own either way).\n if (objectStoreRelease) await raceWithTimeout(objectStoreRelease(), OBJECTSTORE_RELINQUISH_TIMEOUT_MS);\n await store.close();\n process.exit(0);\n };\n triggerObjectStoreFencedShutdown = () => void shutdown();\n process.on(\"SIGTERM\", () => void shutdown());\n process.on(\"SIGINT\", () => void shutdown());\n\n return new Promise<number>(() => {\n // Run until a signal exits the process.\n });\n}\n","/**\n * Server-side apply for `helipod deploy`: write the pushed tree under a writable dir a sibling\n * chain from the engine's node_modules (so `@helipod/*` resolves), reuse loadFunctionsDir → push,\n * gate on an additive-schema diff, then ATOMICALLY swap modules/routes/schema. All validation\n * happens before the first swap, so a rejected deploy leaves the running version fully live.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport type { EmbeddedRuntime } from \"@helipod/runtime-embedded\";\nimport type { AdminApi } from \"@helipod/admin\";\nimport type { ComponentDefinition } from \"@helipod/component\";\nimport { sha256Hex } from \"@helipod/deploy\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { push } from \"./push-pipeline\";\nimport { withStorageModules } from \"./boot\";\nimport { diffSchema, type DeploySchema } from \"./schema-diff\";\nimport type { ResolvedRoute } from \"./project\";\n\nexport interface DeployDeps {\n runtime: EmbeddedRuntime;\n adminApi: AdminApi;\n setRoutes: (routes: ResolvedRoute[]) => void;\n components: ComponentDefinition[];\n current: () => { schemaJson: DeploySchema[\"schemaJson\"]; tableNumbers: Record<string, number> };\n deployRoot: string;\n /** The modules from the last successful push this server lifetime — used to resolve `unchanged`\n * entries in a delta payload. Empty at boot (first deploy is a full push). */\n currentModules: Map<string, { code: string; sha: string }>;\n}\nexport type DeployResult =\n | { ok: true; rev: string; functions: number; modules: Map<string, { code: string; sha: string }> }\n | { ok: false; kind: \"load-error\" | \"schema-incompatible\" | \"stale-base\"; error: string };\n\n/** The wire-safe subset of `DeployResult` — identical shape minus `modules` (a `Map`, which must\n * never cross HTTP). `serve.ts`'s `deploy.apply` closure strips it before returning; this is the\n * type that actually travels over `/_admin/deploy`. */\nexport type DeployWireResult =\n | { ok: true; rev: string; functions: number }\n | { ok: false; kind: \"load-error\" | \"schema-incompatible\" | \"stale-base\"; error: string };\n\nexport type DeployPayload =\n | { files: Array<{ path: string; code: string }> }\n | { changed: Array<{ path: string; code: string }>; unchanged: Array<{ path: string; sha256: string }> };\n\nexport type ReconstructResult =\n | { ok: true; files: Array<{ path: string; code: string }> }\n | { ok: false; error: string };\n\n/** Rebuild the full file tree from a legacy `{files}` OR a delta `{changed, unchanged}` payload.\n * Each `unchanged` module is resolved from `currentModules` and its sha verified; a missing path or\n * a sha disagreement is a `stale-base` (the client retries as a full push). The union of changed +\n * unchanged is the complete tree, so an unreferenced current module is dropped (deletion by omission). */\nexport function reconstructFiles(\n payload: DeployPayload,\n currentModules: Map<string, { code: string; sha: string }>,\n): ReconstructResult {\n if (\"changed\" in payload) {\n const files = [...(payload.changed ?? [])];\n for (const u of payload.unchanged ?? []) {\n const cur = currentModules.get(u.path);\n if (!cur) return { ok: false, error: `stale-base: server has no module \"${u.path}\"` };\n if (cur.sha !== u.sha256) return { ok: false, error: `stale-base: module \"${u.path}\" hash mismatch` };\n files.push({ path: u.path, code: cur.code });\n }\n return { ok: true, files };\n }\n return { ok: true, files: payload.files ?? [] };\n}\n\nexport async function applyDeploy(\n deps: DeployDeps,\n payload: DeployPayload,\n): Promise<DeployResult> {\n const rec = reconstructFiles(payload, deps.currentModules);\n if (!rec.ok) return { ok: false, kind: \"stale-base\", error: rec.error };\n const files = rec.files;\n const rev = createHash(\"sha256\").update(JSON.stringify(files)).digest(\"hex\").slice(0, 12);\n const dir = join(deps.deployRoot, rev, \"functions\");\n\n let project;\n try {\n for (const f of files) {\n if (typeof f.path !== \"string\" || typeof f.code !== \"string\") {\n throw new Error(`invalid deploy payload: file entry must have a string \"path\" and \"code\"`);\n }\n // Reject any path that could escape the per-rev deploy dir — absolute paths, or a `..`\n // segment (checked on `/`-split segments since packageApp always emits `/`-joined paths).\n if (isAbsolute(f.path) || f.path.split(\"/\").includes(\"..\")) {\n throw new Error(`invalid deploy payload: unsafe path \"${f.path}\"`);\n }\n const abs = join(dir, f.path);\n mkdirSync(dirname(abs), { recursive: true });\n writeFileSync(abs, f.code);\n }\n const loaded = await loadFunctionsDir(dir);\n project = push(loaded, deps.components, deps.current().tableNumbers).project;\n } catch (e) {\n return { ok: false, kind: \"load-error\", error: e instanceof Error ? e.message : String(e) };\n }\n\n const diff = diffSchema(deps.current(), {\n schemaJson: project.schemaJson as DeploySchema[\"schemaJson\"],\n tableNumbers: project.tableNumbers,\n });\n if (!diff.ok) return { ok: false, kind: \"schema-incompatible\", error: diff.reason };\n\n // Atomic swap — only reached after load + diff succeed. Re-apply the always-on `_storage:*`\n // built-ins (they're not in the pushed moduleMap) so file storage survives a live deploy.\n deps.runtime.setModules(withStorageModules(project.moduleMap));\n deps.runtime.setTableNumbers(project.tableNumbers);\n deps.setRoutes(project.routes);\n deps.adminApi.setSchema(project.schemaJson, project.tableNumbers, project.manifest);\n const modules = new Map(files.map((f) => [f.path, { code: f.code, sha: sha256Hex(f.code) }]));\n return { ok: true, rev, functions: Object.keys(project.moduleMap).length, modules };\n}\n","/**\n * The additive-schema gate for `helipod deploy`. A deploy may add tables and add OPTIONAL fields\n * (tableNumbers must stay stable); anything destructive — a dropped/renamed table, a changed\n * tableNumber, a removed field, an incompatible field-type change, or a new REQUIRED field on an\n * existing table — is rejected so the running deployment is never left with a schema its data\n * violates. No data migrations (deferred): destructive means \"reject\", not \"migrate\".\n */\nexport interface ObjectFieldJSON {\n fieldType: { type: string };\n optional: boolean;\n}\nexport interface DeploySchema {\n schemaJson: { tables: Record<string, { documentType: { type: string; value?: Record<string, ObjectFieldJSON> } }> };\n tableNumbers: Record<string, number>;\n}\nexport type SchemaDiff = { ok: true } | { ok: false; reason: string };\n\nfunction fieldsOf(s: DeploySchema, table: string): Record<string, ObjectFieldJSON> {\n return s.schemaJson.tables[table]?.documentType?.value ?? {};\n}\n\n// v1 rejects ANY field-type change — including apparent \"widenings\" like string→union or any→string.\n// The simplified field shape here doesn't carry union members, so we can't safely verify a widening\n// is actually sound (e.g. any→string would invalidate existing non-string rows; string→union isn't\n// safe unless the old type is provably a member of the new union, which we can't check). Strict\n// equality is over-rejection-safe: it only fails a deploy, never corrupts data.\nfunction compatibleType(cur: { type: string }, next: { type: string }): boolean {\n return cur.type === next.type;\n}\n\nexport function diffSchema(current: DeploySchema, next: DeploySchema): SchemaDiff {\n for (const name of Object.keys(current.tableNumbers)) {\n if (!(name in next.tableNumbers)) return { ok: false, reason: `table \"${name}\" was removed (destructive — rename/drop not supported)` };\n if (current.tableNumbers[name] !== next.tableNumbers[name])\n return { ok: false, reason: `table \"${name}\" tableNumber changed ${current.tableNumbers[name]}→${next.tableNumbers[name]} (destructive)` };\n\n const cur = fieldsOf(current, name);\n const nxt = fieldsOf(next, name);\n for (const [field, curV] of Object.entries(cur)) {\n const nxtV = nxt[field];\n if (nxtV === undefined) return { ok: false, reason: `field \"${name}.${field}\" was removed (destructive)` };\n if (!compatibleType(curV.fieldType, nxtV.fieldType))\n return { ok: false, reason: `field \"${name}.${field}\" changed type ${curV.fieldType.type}→${nxtV.fieldType.type} (destructive)` };\n if (curV.optional && !nxtV.optional)\n return { ok: false, reason: `field \"${name}.${field}\" became required (destructive — existing rows may omit it)` };\n }\n for (const [field, nxtV] of Object.entries(nxt)) {\n if (cur[field] === undefined && !nxtV.optional)\n return { ok: false, reason: `field \"${name}.${field}\" is a new required field on an existing table (destructive — existing rows lack it; make it optional)` };\n }\n }\n return { ok: true };\n}\n","/**\n * The configuration-constructible `WakeHost` — `serve --wake-url <url>`'s implementation.\n *\n * A `WakeHost` is a JS closure, but the deployment rig can't inject one: what runs is the SHIPPED\n * `helipod serve` inside a built image. So the host is built from configuration instead, exactly\n * like `--object-store`/`--database-url` already are, and the engine's whole knowledge of the host\n * is \"POST an integer to a URL\" — no host primitive anywhere in `packages/`/`components/`. On\n * Cloudflare the URL is an Outbound-Workers magic hostname (`http://wake.do/arm`): the request never\n * leaves the Workers runtime, and the Worker turns it into a Durable Object alarm. Any other host\n * can implement the same two lines.\n */\nimport type { WakeHost } from \"@helipod/component\";\n\n/**\n * POSTs the next wake's ABSOLUTE `atMs` (the body is the bare integer; `null` — nothing pending —\n * is an empty body) to `url`.\n *\n * FIRE-AND-FORGET, by contract: `armWake` returns `void` and is called from a driver's synchronous\n * timer bookkeeping, which must never block on — or fail because of — a network hop. A failed POST\n * is logged, never thrown, and degrades to a missed wake, which self-heals: the durable table state\n * is the truth and the alarm only decides WHEN TO LOOK, so any later request (or the next successful\n * arm) boots the process and dispatches whatever is overdue.\n */\nexport function httpWakeHost(url: string): WakeHost {\n return {\n armWake(atMs: number | null): void {\n void fetch(url, { method: \"POST\", body: atMs === null ? \"\" : String(atMs) })\n .then((res) => {\n if (!res.ok) console.error(`[wake] arm at ${atMs} rejected by ${url}: ${res.status}`);\n })\n .catch((e: unknown) => {\n console.error(`[wake] arm at ${atMs} failed to reach ${url}:`, e);\n });\n },\n };\n}\n","/**\n * `helipod deploy` — package the local functions directory and push it to a target via the\n * `@helipod/deploy` seam. Targets: `serve` (slice-6b live hot-swap, back-compat default),\n * `cloudflare` (Workers via wrangler), `docker` (build + push an image). This module: resolve\n * flags → build a DeployContext (packageApp/codegen closures over the existing CLI machinery,\n * a real NodeSpawner) → lazy-load the target adapter → preflight → package → push (skipped on\n * --dry-run). `--check` gates on codegen drift (does the committed _generated/ match a fresh run).\n */\nimport { readdirSync, statSync, readFileSync, mkdtempSync, rmSync, existsSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport { transform } from \"esbuild\";\nimport { writeGenerated } from \"@helipod/codegen\";\nimport { resolveDeploy, loadTarget, NodeSpawner, type Spawner, type DeployContext, DeployError } from \"@helipod/deploy\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { resolveFunctionsDir, ensureFunctionsDirExists } from \"./functions-dir\";\n\n/** @deprecated slice-6b's own flag parser, superseded by parseDeployFlags/resolveDeploy. Kept for its existing test coverage. */\nexport interface DeployOptions {\n url: string;\n functionsDir: string;\n adminKey: string;\n}\n\n/** @deprecated see DeployOptions. */\nexport async function resolveDeployOptions(args: string[], env: NodeJS.ProcessEnv): Promise<DeployOptions | { error: string }> {\n let url = env.HELIPOD_DEPLOY_URL?.trim() ?? \"\";\n let dirFlag: string | undefined;\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--url\" && args[i + 1]) url = args[++i]!;\n else if (args[i] === \"--dir\" && args[i + 1]) dirFlag = args[++i]!;\n }\n const adminKey = env.HELIPOD_ADMIN_KEY?.trim() ?? \"\";\n if (!url) return { error: \"missing target URL — pass --url <url> or set HELIPOD_DEPLOY_URL\" };\n if (!adminKey) return { error: \"HELIPOD_ADMIN_KEY is required to deploy\" };\n const { functionsDir } = await resolveFunctionsDir(dirFlag, process.cwd());\n return { url, functionsDir, adminKey };\n}\n\nfunction walkTs(root: string, dir: string, out: string[]): void {\n for (const entry of readdirSync(dir)) {\n const abs = join(dir, entry);\n if (statSync(abs).isDirectory()) walkTs(root, abs, out);\n else if (entry.endsWith(\".ts\") && !entry.endsWith(\".d.ts\")) out.push(abs);\n }\n}\n\nexport async function packageApp(functionsDir: string): Promise<Array<{ path: string; code: string }>> {\n const absFiles: string[] = [];\n walkTs(functionsDir, functionsDir, absFiles);\n const out: Array<{ path: string; code: string }> = [];\n for (const abs of absFiles) {\n const source = readFileSync(abs, \"utf8\");\n // `transform` strips TS types and leaves import specifiers untouched — bare `@helipod/*`\n // resolve from the remote's node_modules; relative imports resolve within the pushed tree.\n const { code } = await transform(source, { loader: \"ts\", format: \"esm\", target: \"esnext\" });\n const rel = relative(functionsDir, abs).split(sep).join(\"/\").replace(/\\.ts$/, \".js\");\n out.push({ path: rel, code });\n }\n return out.sort((a, b) => a.path.localeCompare(b.path));\n}\n\nexport interface DeployDeps {\n spawn?: Spawner;\n cwd?: string;\n interactive?: boolean;\n}\n\nfunction parseDeployFlags(args: string[]): { target?: string; env?: string; url?: string; dirFlag?: string; dryRun: boolean; check: boolean } {\n let target: string | undefined;\n let env: string | undefined;\n let url: string | undefined = process.env.HELIPOD_DEPLOY_URL?.trim() || undefined;\n let dirFlag: string | undefined;\n let dryRun = false;\n let check = false;\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--target\" && args[i + 1]) target = args[++i];\n else if (args[i] === \"--env\" && args[i + 1]) env = args[++i];\n else if (args[i] === \"--url\" && args[i + 1]) url = args[++i];\n else if (args[i] === \"--dir\" && args[i + 1]) dirFlag = args[++i];\n else if (args[i] === \"--dry-run\") dryRun = true;\n else if (args[i] === \"--check\") check = true;\n }\n return { target, env, url, dirFlag, dryRun, check };\n}\n\n/** True if running codegen would change the committed `_generated/` (drift). */\nasync function checkDrift(functionsDir: string, components: Awaited<ReturnType<typeof loadConfig>>[\"components\"]): Promise<boolean> {\n const tmp = mkdtempSync(join(tmpdir(), \"sb-codegen-\"));\n try {\n const { generated } = push(await loadFunctionsDir(functionsDir), components);\n writeGenerated(generated.files, tmp);\n const genDir = join(functionsDir, \"_generated\");\n return !dirsEqual(tmp, genDir);\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n}\n\nfunction dirsEqual(a: string, b: string): boolean {\n const walk = (root: string): Map<string, string> => {\n const out = new Map<string, string>();\n const rec = (dir: string, rel: string) => {\n if (!existsSync(dir)) return;\n for (const e of readdirSync(dir)) {\n const abs = join(dir, e);\n const r = rel ? `${rel}/${e}` : e;\n if (statSync(abs).isDirectory()) rec(abs, r);\n else out.set(r, readFileSync(abs, \"utf8\"));\n }\n };\n rec(root, \"\");\n return out;\n };\n const ma = walk(a);\n const mb = walk(b);\n if (ma.size !== mb.size) return false;\n for (const [k, v] of ma) if (mb.get(k) !== v) return false;\n return true;\n}\n\n/** CLI wrapper: resolve flags → build a DeployContext → dispatch through the DeployTarget seam. */\nexport async function deployCommand(args: string[], deps: DeployDeps = {}): Promise<number> {\n const flags = parseDeployFlags(args);\n const cwd = deps.cwd ?? process.cwd();\n // `resolveFunctionsDir` handles the precedence (--dir > `functionsDir` in helipod.config.ts >\n // DEFAULT_FUNCTIONS_DIR) and always returns an absolute path, so no separate `resolve()` of\n // `flags.dirFlag` is needed here the way a bare flag default would have required.\n const { functionsDir } = await resolveFunctionsDir(flags.dirFlag, cwd);\n // Fail loudly — with the migrate hint — before anything below (the `--check` drift scan or the\n // main package/push flow) can hit `loadFunctionsDir` and throw a raw ENOENT.\n if (!ensureFunctionsDirExists(functionsDir)) return 1;\n const config = await loadConfig(cwd);\n\n if (flags.check) {\n const drift = await checkDrift(functionsDir, config.components);\n if (drift) {\n process.stderr.write(`✗ ${functionsDir}/_generated is out of date — run \\`helipod codegen\\` and commit the result\\n`);\n return 1;\n }\n process.stdout.write(`✓ ${functionsDir}/_generated is up to date\\n`);\n // `--check` never pushes: it's a verification gate. Return after the drift verdict unless the\n // caller ALSO passed --dry-run (the dry-run flow below runs but always skips push), so --check\n // can never reach `push`.\n if (!flags.dryRun) return 0;\n }\n\n const resolved = resolveDeploy({ deploy: config.deploy, target: flags.target, env: flags.env, inlineUrl: flags.url });\n if (\"error\" in resolved) {\n process.stderr.write(`✗ ${resolved.error}\\n`);\n return 1;\n }\n\n let target;\n try {\n target = await loadTarget(resolved.provider);\n } catch (e) {\n process.stderr.write(`✗ ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n\n const interactive = deps.interactive ?? (Boolean(process.stdin.isTTY) && !process.env.CI);\n const ctx: DeployContext = {\n cwd,\n functionsDir,\n env: resolved.env,\n target: resolved,\n interactive,\n spawn: deps.spawn ?? new NodeSpawner(),\n log: (m) => process.stdout.write(` ${m}\\n`),\n packageApp: async () => ({ files: await packageApp(functionsDir) }),\n codegen: async () => {\n const { generated } = push(await loadFunctionsDir(functionsDir), config.components);\n writeGenerated(generated.files, join(functionsDir, \"_generated\"));\n },\n };\n\n try {\n await target.preflight(ctx);\n await target.package(ctx);\n if (flags.dryRun) {\n process.stdout.write(`✓ dry-run OK (${resolved.provider} / ${resolved.env}) — push skipped\\n`);\n return 0;\n }\n const result = await target.push(ctx);\n if (!result.ok) {\n process.stderr.write(`✗ deploy failed: ${result.error}\\n`);\n return 1;\n }\n process.stdout.write(`✓ deployed via ${resolved.provider} (${resolved.env})${result.detail ? ` — ${result.detail}` : \"\"}\\n`);\n if (result.url) process.stdout.write(` ${result.url}\\n`);\n return 0;\n } catch (e) {\n if (e instanceof DeployError) { process.stderr.write(`✗ ${e.message}\\n`); return 1; }\n throw e;\n }\n}\n","/**\n * `helipod build` — compile the app to a self-contained executable via `bun build --compile`.\n * Refresh codegen (so the app's `import \"./_generated/server\"` resolves at compile time), codegen a\n * static-import entrypoint, shell out to `bun build --compile`, then clean up.\n */\nimport { existsSync, mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from \"node:fs\";\nimport { spawnSync } from \"node:child_process\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { writeGenerated } from \"@helipod/codegen\";\nimport { loadFunctionsDir, listFunctionModuleFiles, moduleKeyForFile } from \"./load-modules\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { generateEntrySource } from \"./build-entry\";\nimport { resolveFunctionsDir, ensureFunctionsDirExists } from \"./functions-dir\";\n\nexport interface BuildOptions { functionsDir: string; outfile: string; target: string | null; dashboard: boolean; verbose: boolean }\n\nexport async function resolveBuildOptions(args: string[]): Promise<BuildOptions> {\n let dirFlag: string | undefined, outfile = \"./helipod-server\", target: string | null = null, dashboard = true, verbose = false;\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--dir\" && args[i + 1]) dirFlag = args[++i] as string;\n else if (a === \"--outfile\" && args[i + 1]) outfile = args[++i] as string;\n else if (a === \"--target\" && args[i + 1]) target = args[++i] as string;\n else if (a === \"--no-dashboard\") dashboard = false;\n else if (a === \"--verbose\") verbose = true;\n }\n const { functionsDir } = await resolveFunctionsDir(dirFlag, process.cwd());\n return { functionsDir, outfile, target, dashboard, verbose };\n}\n\nconst TARGETS: Record<string, string> = {\n \"linux-x64\": \"bun-linux-x64\", \"linux-arm64\": \"bun-linux-arm64\",\n \"darwin-x64\": \"bun-darwin-x64\", \"darwin-arm64\": \"bun-darwin-arm64\",\n \"windows-x64\": \"bun-windows-x64\",\n};\nexport function bunTargetFor(friendly: string): string {\n const t = TARGETS[friendly];\n if (!t) throw new Error(`unknown target \"${friendly}\" (expected one of: ${Object.keys(TARGETS).join(\", \")})`);\n return t;\n}\n\n/** Enumerate the built dashboard dist as {urlPath, absPath}. \"/\" maps to index.html. */\nfunction dashboardFiles(): Array<{ urlPath: string; absPath: string }> | null {\n try {\n const indexPath = createRequire(import.meta.url).resolve(\"@helipod/dashboard/dist\");\n const dist = dirname(indexPath);\n const out: Array<{ urlPath: string; absPath: string }> = [];\n const walk = (rel: string) => {\n for (const e of readdirSync(join(dist, rel), { withFileTypes: true })) {\n const r = rel ? `${rel}/${e.name}` : e.name;\n if (e.isDirectory()) walk(r);\n else out.push({ urlPath: r === \"index.html\" ? \"/\" : `/${r}`, absPath: join(dist, r) });\n }\n };\n walk(\"\");\n return out;\n } catch { return null; }\n}\n\nexport async function buildCommand(args: string[]): Promise<number> {\n const opts = await resolveBuildOptions(args);\n // `resolveFunctionsDir` already returns an absolute path, so no extra `resolve()` is needed here.\n const functionsDirAbs = opts.functionsDir;\n // Fail loudly — with the migrate hint — before `loadFunctionsDir` below can throw a raw ENOENT.\n if (!ensureFunctionsDirExists(functionsDirAbs)) return 1;\n // 1. Load + refresh codegen so `import \"./_generated/server\"` resolves when bun bundles the modules.\n const loaded = await loadFunctionsDir(functionsDirAbs);\n const config = await loadConfig(dirname(functionsDirAbs));\n const { generated } = push(loaded, config.components);\n writeGenerated(generated.files, join(functionsDirAbs, \"_generated\"));\n // 2. Codegen the entrypoint.\n const moduleImports = listFunctionModuleFiles(functionsDirAbs).map((f) => ({ key: moduleKeyForFile(f), absPath: join(functionsDirAbs, f) }));\n const schemaAbsPath = join(functionsDirAbs, existsSync(join(functionsDirAbs, \"schema.ts\")) ? \"schema.ts\" : \"schema.js\");\n const cfgTs = join(dirname(functionsDirAbs), \"helipod.config.ts\"), cfgJs = join(dirname(functionsDirAbs), \"helipod.config.js\");\n const configAbsPath = existsSync(cfgTs) ? cfgTs : existsSync(cfgJs) ? cfgJs : null;\n const entrySrc = generateEntrySource({ moduleImports, schemaAbsPath, configAbsPath, dashboardFiles: opts.dashboard ? dashboardFiles() : null });\n const buildDir = resolve(\".helipod-build\");\n mkdirSync(buildDir, { recursive: true });\n const entryPath = join(buildDir, \"entry.ts\");\n writeFileSync(entryPath, entrySrc);\n // 3. Compile.\n // NOTE: no --bytecode — `bun build --compile --bytecode` rejects the entry's top-level await. Cold-start\n // speed is negligible for a long-running self-hosted server binary; revisit if the entry drops TLA.\n const bunArgs = [\"build\", \"--compile\", \"--minify\"];\n if (opts.target) bunArgs.push(`--target=${bunTargetFor(opts.target)}`);\n const outfile = opts.target === \"windows-x64\" && !opts.outfile.endsWith(\".exe\") ? `${opts.outfile}.exe` : opts.outfile;\n bunArgs.push(`--outfile=${resolve(outfile)}`, entryPath);\n // Shell the external `bun` binary via node:child_process so this works whether the CLI itself is\n // invoked under Bun or Node (the compile step needs Bun, but the caller need not be Bun).\n const proc = spawnSync(\"bun\", bunArgs, { stdio: opts.verbose ? \"inherit\" : [\"ignore\", \"ignore\", \"inherit\"] });\n rmSync(buildDir, { recursive: true, force: true });\n if (proc.error) {\n process.stderr.write(`✗ could not run 'bun build --compile' — is Bun installed and on PATH? (${(proc.error as Error).message})\\n`);\n return 1;\n }\n if (proc.status !== 0) { process.stderr.write(\"✗ bun build --compile failed\\n\"); return 1; }\n const size = (statSync(resolve(outfile)).size / (1024 * 1024)).toFixed(0);\n process.stdout.write(`✓ built ${outfile} (${size}MB)\\n`);\n return 0;\n}\n","/**\n * Pure generator for the `helipod build` entrypoint. `bun build --compile` only bundles STATIC\n * imports, so we emit static imports of the app's modules/schema/config (+ embedded dashboard files)\n * and reconstruct the `{schema, modules}` shape `loadFunctionsDir` returns at runtime. `JSON.stringify`\n * on every path/key guards against quotes/backslashes breaking the generated source.\n */\nexport interface EntryInputs {\n moduleImports: Array<{ key: string; absPath: string }>;\n schemaAbsPath: string;\n configAbsPath: string | null;\n dashboardFiles: Array<{ urlPath: string; absPath: string }> | null;\n}\n\nexport function generateEntrySource(inp: EntryInputs): string {\n const L: string[] = [\"// AUTO-GENERATED by `helipod build` — do not edit.\"];\n inp.moduleImports.forEach((m, i) => L.push(`import * as m${i} from ${JSON.stringify(m.absPath)};`));\n L.push(`import schema from ${JSON.stringify(inp.schemaAbsPath)};`);\n if (inp.configAbsPath) L.push(`import * as __config from ${JSON.stringify(inp.configAbsPath)};`);\n (inp.dashboardFiles ?? []).forEach((d, i) => L.push(`import d${i} from ${JSON.stringify(d.absPath)} with { type: \"file\" };`));\n L.push(`import { runBinaryServer } from \"@helipod/cli\";`);\n L.push(\"\");\n const modEntries = inp.moduleImports.map((m, i) => `${JSON.stringify(m.key)}: m${i}`).join(\", \");\n L.push(`const loaded = { schema, modules: { ${modEntries} } };`);\n L.push(inp.configAbsPath ? `const components = (__config.default ?? __config).components ?? [];` : `const components = [];`);\n if (inp.dashboardFiles) {\n const dEntries = inp.dashboardFiles.map((d, i) => `${JSON.stringify(d.urlPath)}: d${i}`).join(\", \");\n L.push(`const dashboard = { ${dEntries} };`);\n L.push(`await runBinaryServer(loaded, components, dashboard);`);\n } else {\n L.push(`await runBinaryServer(loaded, components, undefined);`);\n }\n return L.join(\"\\n\") + \"\\n\";\n}\n","/**\n * `helipod migrate` — turn an existing Convex project into a Helipod project: rewrite\n * imports, scaffold config, write a divergence report, and regenerate `_generated/`. v1 supports\n * only `--from convex`; other origin backends register into `SOURCES` the same way.\n */\nimport { writeFileSync, existsSync, mkdirSync, rmSync, renameSync } from \"node:fs\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { writeGenerated, generateServer } from \"@helipod/codegen\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { resolveSource, type MigrationSource, type ReportEntry } from \"./migrate/source\";\nimport { convexSource } from \"./migrate/convex-source\";\nimport { migrateExportCommand, migrateImportCommand } from \"./migrate/data\";\nimport { resolveFunctionsDir } from \"./functions-dir\";\n\nconst SOURCES: Record<string, MigrationSource> = { convex: convexSource };\n\ninterface MigrateOptions {\n from: string;\n functionsDir: string;\n dryRun: boolean;\n force: boolean;\n}\nfunction parse(args: string[]): MigrateOptions {\n const out: MigrateOptions = { from: \"convex\", functionsDir: \"convex\", dryRun: false, force: false };\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--from\" && args[i + 1]) out.from = args[++i]!;\n else if (a === \"--dir\" && args[i + 1]) out.functionsDir = args[++i]!;\n else if (a === \"--dry-run\") out.dryRun = true;\n else if (a === \"--force\") out.force = true;\n }\n return out;\n}\n\nexport function renderReport(entries: ReportEntry[]): string {\n const by = (s: string) => entries.filter((e) => e.severity === s);\n const section = (title: string, items: ReportEntry[]) =>\n items.length === 0\n ? \"\"\n : `\\n## ${title} (${items.length})\\n\\n` +\n items.map((e) => `- \\`${e.file}${e.line ? `:${e.line}` : \"\"}\\` — ${e.what}. **Fix:** ${e.fix}`).join(\"\\n\") +\n \"\\n\";\n return (\n `# Helipod migration report\\n\\n` +\n `${by(\"auto-fixed\").length} auto-fixed, ${by(\"action-needed\").length} action-needed, ${by(\"unsupported\").length} unsupported.\\n` +\n section(\"Auto-fixed\", by(\"auto-fixed\")) +\n section(\"Action needed\", by(\"action-needed\")) +\n section(\"Unsupported\", by(\"unsupported\"))\n );\n}\n\n/** Is `dir` inside a git repo with uncommitted changes? Returns null if not a git repo. */\nfunction gitDirty(dir: string): boolean | null {\n const r = spawnSync(\"git\", [\"status\", \"--porcelain\"], { cwd: dir, encoding: \"utf8\" });\n if (r.status !== 0) return null;\n return r.stdout.trim().length > 0;\n}\n\nexport async function migrateCommand(args: string[]): Promise<number> {\n // Data-migration verbs (Slice 5) — `migrate export`/`migrate import` move an app's DATA between the\n // portable and DO-native topologies. Kept under `migrate` (a sibling of the bare-`migrate` Convex\n // codemod, which is unchanged) so `helipod migrate` stays one coherent command.\n if (args[0] === \"export\") return migrateExportCommand(args.slice(1));\n if (args[0] === \"import\") return migrateImportCommand(args.slice(1));\n\n const opts = parse(args);\n const functionsDir = resolve(opts.functionsDir);\n const projectRoot = dirname(functionsDir);\n\n const dirty = gitDirty(projectRoot);\n if (dirty === true && !opts.force) {\n process.stderr.write(\n `refusing to migrate: ${projectRoot} has uncommitted changes (commit/stash first, or pass --force)\\n`,\n );\n return 1;\n }\n if (dirty === null) {\n process.stderr.write(`warning: ${projectRoot} is not a git repo — changes will be made in place with no easy revert\\n`);\n }\n\n let source: MigrationSource;\n try {\n source = resolveSource(SOURCES, opts.from);\n } catch (e) {\n process.stderr.write(`${String(e)}\\n`);\n return 1;\n }\n if (!(await source.detect(projectRoot))) {\n process.stderr.write(`no ${opts.from} project detected at ${projectRoot}\\n`);\n return 1;\n }\n\n // Rename the functions directory to Helipod's own convention. Runs AFTER detect (which looks\n // for convex/schema.ts on the untouched tree) and BEFORE analyze, so every path in the plan\n // already refers to the new location. A project that declares its own `functionsDir` wins, so\n // migrate can never produce a layout the CLI would then fail to find.\n //\n // `resolveFunctionsDir(undefined, projectRoot)` replicates its own no-flag branch: `projectRoot`\n // is already an absolute dir (computed above from `--dir`, defaulting to cwd/convex), so passing\n // it as `cwd` makes `resolve(cwd)` idempotent, and it loads `helipod.config.ts` from that same\n // root — the exact `cfg.functionsDir ?? DEFAULT_FUNCTIONS_DIR` resolution this used to hand-roll.\n const { functionsDir: targetDir } = await resolveFunctionsDir(undefined, projectRoot);\n let migratedDir = functionsDir;\n let renamed = false;\n let pendingRename = false;\n if (resolve(functionsDir) !== resolve(targetDir)) {\n if (existsSync(targetDir)) {\n process.stderr.write(\n `refusing to migrate: ${targetDir} already exists (remove or rename it, then re-run)\\n`,\n );\n return 1;\n }\n if (opts.dryRun) {\n // A dry run must not touch the working tree. Leave `migratedDir` as the untouched\n // `functionsDir` so `analyze()` below reads real files at a real, existing path — its file\n // counts stay accurate — and just remember that a rename would happen, for the preview.\n pendingRename = true;\n } else {\n try {\n // `dirty` (computed above) already tells us whether projectRoot is a git repo at all —\n // reuse that signal instead of shelling out to git again. Inside a repo, prefer `git mv`\n // so the rename shows up as a rename in history rather than a delete+add; fall back to a\n // plain filesystem rename if git mv fails for any reason (e.g. the dir isn't tracked yet).\n let didGitMv = false;\n if (dirty !== null) {\n const r = spawnSync(\"git\", [\"mv\", functionsDir, targetDir], { cwd: projectRoot });\n didGitMv = r.status === 0;\n }\n if (!didGitMv) renameSync(functionsDir, targetDir);\n } catch (e) {\n process.stderr.write(\n `refusing to migrate: could not rename ${functionsDir} to ${targetDir}: ` +\n `${e instanceof Error ? e.message : String(e)}\\n`,\n );\n return 1;\n }\n migratedDir = targetDir;\n renamed = true;\n process.stdout.write(`renamed ${functionsDir} → ${targetDir}\\n`);\n }\n }\n\n const plan = await source.analyze(projectRoot, migratedDir);\n if (renamed || pendingRename) {\n plan.report.unshift({\n severity: \"auto-fixed\",\n file: `${basename(functionsDir)}/`,\n what: pendingRename ? `would be renamed to ${basename(targetDir)}/` : `renamed to ${basename(targetDir)}/`,\n fix: pendingRename\n ? `Your backend functions will move to ${basename(targetDir)}/ when you run this migration without --dry-run. Imports inside that folder are relative and will not change.`\n : `Your backend functions now live in ${basename(targetDir)}/. Imports inside that folder are relative and did not change.`,\n });\n }\n\n // Always write the report first (so a later regen failure still leaves it).\n writeFileSync(join(projectRoot, \"MIGRATION-REPORT.md\"), renderReport(plan.report));\n\n if (opts.dryRun) {\n const renameNote = pendingRename ? ` ${basename(functionsDir)}/ would be renamed to ${basename(targetDir)}/.` : \"\";\n process.stdout.write(\n `[dry-run] ${plan.edits.length} files would change, ${plan.scaffold.length} scaffolded.${renameNote} See MIGRATION-REPORT.md\\n`,\n );\n return 0;\n }\n\n for (const edit of plan.edits) writeFileSync(edit.path, edit.newContent);\n for (const file of plan.scaffold) if (!existsSync(file.path)) writeFileSync(file.path, file.content);\n\n // Regenerate _generated/ via the standard pipeline.\n try {\n const generatedDir = join(migratedDir, \"_generated\");\n\n // Delete the app's existing `_generated/` before regenerating (spec §88). A real Convex app\n // ships `_generated/{server.js, server.d.ts, api.js, api.d.ts, dataModel.d.ts}` — the pre-write\n // guard below only checks for `server.ts` (Helipod's own extension), so those stale Convex\n // artifacts would otherwise survive untouched and can shadow the regenerated Helipod files\n // (a JS-first resolver picks the stale `server.js`, which imports the now-uninstalled\n // \"convex/server\"). `force: true` makes this a no-op when the dir is absent (the from-scratch\n // migration case), preserving existing behavior there.\n rmSync(generatedDir, { recursive: true, force: true });\n\n const config = await loadConfig(projectRoot);\n\n // A project migrated straight from Convex source has NEVER had `_generated/` written — its\n // hand-authored function files (e.g. `notes.ts`) already `import ... from \"./_generated/\n // server\"`, so `loadFunctionsDir`'s dynamic import of them needs that file to exist on disk\n // *before* the real codegen below ever runs. `generateServer`'s output doesn't depend on the\n // schema (only on composed components), so pre-writing it here is safe — the accurate,\n // final version (from the fully-loaded project) overwrites this stub a few lines down.\n if (!existsSync(join(generatedDir, \"server.ts\"))) {\n const stub = generateServer(\n { tables: {}, schemaValidation: false },\n { components: config.components.map((c) => ({ name: c.name, contextType: c.contextType, serverExports: c.serverExports })) },\n );\n mkdirSync(generatedDir, { recursive: true });\n writeFileSync(join(generatedDir, \"server.ts\"), stub.content);\n }\n\n const loaded = await loadFunctionsDir(migratedDir);\n const { generated } = push(loaded, config.components);\n writeGenerated(generated.files, generatedDir);\n } catch (e) {\n process.stderr.write(\n `imports migrated, but codegen failed: ${String(e)}\\nSee MIGRATION-REPORT.md; fix the flagged items, then run \\`helipod codegen\\`.\\n`,\n );\n return 1;\n }\n\n const n = plan.report.filter((r) => r.severity !== \"auto-fixed\").length;\n process.stdout.write(`migrated ${plan.edits.length} files. ${n} item(s) need manual attention — see MIGRATION-REPORT.md\\n`);\n return 0;\n}\n","/**\n * The migration source-adapter seam. A `MigrationSource` inspects a project of some origin\n * backend and produces a `MigrationPlan` — the file edits, scaffold, and divergence report that\n * turn it into a Helipod project. v1 ships only a Convex source; Supabase/Firebase are future\n * sources registered the same way.\n */\nexport interface FileEdit {\n /** Absolute path of an existing file to overwrite in place. */\n path: string;\n newContent: string;\n}\nexport interface FileWrite {\n /** Absolute path of a new file to create. */\n path: string;\n content: string;\n}\nexport type ReportSeverity = \"auto-fixed\" | \"action-needed\" | \"unsupported\";\nexport interface ReportEntry {\n severity: ReportSeverity;\n file: string;\n line?: number;\n /** What was found, e.g. `.withIndex(...) query`. */\n what: string;\n /** The concrete Helipod equivalent or next step. */\n fix: string;\n}\nexport interface MigrationPlan {\n edits: FileEdit[];\n scaffold: FileWrite[];\n report: ReportEntry[];\n}\nexport interface MigrationSource {\n id: string;\n detect(projectRoot: string): Promise<boolean>;\n analyze(projectRoot: string, appDir: string): Promise<MigrationPlan>;\n}\n\nexport function resolveSource(sources: Record<string, MigrationSource>, id: string): MigrationSource {\n const source = sources[id];\n if (!source) {\n throw new Error(`unknown migration source \"${id}\" (available: ${Object.keys(sources).join(\", \")})`);\n }\n return source;\n}\n","import { readFileSync, readdirSync, existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport type { FileEdit, FileWrite, MigrationPlan, MigrationSource, ReportEntry } from \"./source\";\nimport { rewriteImports } from \"./rewrite-imports\";\nimport { scanDivergences } from \"./scan-divergences\";\n\n/** Recursively list *.ts/*.tsx files under `dir`, skipping `_generated` and `node_modules`. */\nfunction walk(dir: string): string[] {\n const out: string[] = [];\n for (const ent of readdirSync(dir, { withFileTypes: true })) {\n if (ent.name === \"_generated\" || ent.name === \"node_modules\") continue;\n const full = join(dir, ent.name);\n if (ent.isDirectory()) out.push(...walk(full));\n else if (/\\.tsx?$/.test(ent.name)) out.push(full);\n }\n return out;\n}\n\n/** Which @helipod/* package a rewritten specifier introduces (for the package.json edit). */\nconst INTRODUCED_PKG: Record<string, string> = {\n \"@helipod/values\": \"@helipod/values\",\n \"@helipod/client/react\": \"@helipod/client\",\n \"@helipod/client\": \"@helipod/client\",\n};\n\nexport const convexSource: MigrationSource = {\n id: \"convex\",\n\n async detect(projectRoot: string): Promise<boolean> {\n if (existsSync(join(projectRoot, \"convex\", \"schema.ts\"))) return true;\n const pkgPath = join(projectRoot, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as { dependencies?: Record<string, string> };\n if (pkg.dependencies?.convex) return true;\n }\n return false;\n },\n\n async analyze(projectRoot: string, appDir: string): Promise<MigrationPlan> {\n const edits: FileEdit[] = [];\n const report: ReportEntry[] = [];\n const scaffold: FileWrite[] = [];\n const introduced = new Set<string>();\n let hasCrons = false;\n\n for (const file of walk(appDir)) {\n const src = readFileSync(file, \"utf8\");\n const rel = relative(projectRoot, file);\n const { output, entries } = rewriteImports(src, rel);\n report.push(...entries, ...scanDivergences(src, rel));\n for (const [spec, pkg] of Object.entries(INTRODUCED_PKG)) {\n if (output.includes(`\"${spec}\"`) && !src.includes(`\"${spec}\"`)) introduced.add(pkg);\n }\n if (output !== src) edits.push({ path: file, newContent: output });\n if (file.endsWith(\"crons.ts\") || /\\bcronJobs\\s*\\(/.test(src)) hasCrons = true;\n }\n\n // package.json edit: drop convex deps, add the introduced @helipod/* packages.\n const pkgPath = join(projectRoot, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = JSON.parse(readFileSync(pkgPath, \"utf8\")) as Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n const deps: Record<string, string> = { ...(pkg.dependencies ?? {}) };\n for (const name of Object.keys(deps)) {\n if (name === \"convex\" || name.startsWith(\"@convex-dev/\")) delete deps[name];\n }\n for (const pkgName of introduced) deps[pkgName] = \"latest\";\n const next = { ...pkg, dependencies: deps };\n edits.push({ path: pkgPath, newContent: JSON.stringify(next, null, 2) + \"\\n\" });\n }\n\n // Scaffold a scheduler config only when crons were detected.\n if (hasCrons) {\n scaffold.push({\n path: join(projectRoot, \"helipod.config.ts\"),\n content:\n `import { defineConfig } from \"@helipod/component\";\\n` +\n `import { defineScheduler } from \"@helipod/scheduler\";\\n\\n` +\n `// Convex crons map to Helipod's scheduler component. Move your cron definitions into\\n` +\n `// a helipod/crons.ts using cronJobs() from \"@helipod/scheduler\".\\n` +\n `export default defineConfig({ components: [defineScheduler()] });\\n`,\n });\n }\n\n return { edits, scaffold, report };\n },\n};\n","import type { ReportEntry } from \"./source\";\n\n/** Unambiguous specifier → target rewrites (applied wherever the quoted specifier appears). */\nconst SIMPLE: Record<string, string> = {\n \"convex/values\": \"@helipod/values\",\n \"convex/react\": \"@helipod/client/react\",\n \"convex/browser\": \"@helipod/client\",\n};\n\nconst SCHEMA_SYMBOLS = new Set([\"defineSchema\", \"defineTable\"]);\nconst SERVER_SYMBOLS = new Set([\"httpRouter\", \"httpAction\"]);\nconst CRON_SYMBOLS = new Set([\"cronJobs\"]);\n\nfunction lineOf(source: string, index: number): number {\n let line = 1;\n for (let i = 0; i < index && i < source.length; i++) if (source[i] === \"\\n\") line++;\n return line;\n}\n\n/**\n * Rewrite Convex import specifiers to their Helipod equivalents. Operates on the quoted module\n * specifier so `import`, `export … from`, `require()`, and dynamic `import()` are all handled.\n * `convex/server` is symbol-aware; `./_generated/server` is left alone.\n */\nexport function rewriteImports(source: string, file: string): { output: string; entries: ReportEntry[] } {\n const entries: ReportEntry[] = [];\n let output = source;\n\n // 1. Unambiguous specifiers — replace every quoted occurrence.\n for (const [from, to] of Object.entries(SIMPLE)) {\n const re = new RegExp(`([\"'])${from.replace(\"/\", \"\\\\/\")}\\\\1`, \"g\");\n const input = output; // the string this pass's match offsets index into\n output = output.replace(re, (_m, q, offset: number) => {\n entries.push({ severity: \"auto-fixed\", file, line: lineOf(input, offset), what: `import \"${from}\"`, fix: `rewritten to \"${to}\"` });\n return `${q}${to}${q}`;\n });\n }\n\n // 2. convex/server — symbol-aware (brace clause; multi-line brace clauses are handled since\n // `[^}]*` matches across newlines).\n const serverRe = /import\\s+(?:type\\s+)?\\{([^}]*)\\}\\s*from\\s*([\"'])convex\\/server\\2/g;\n const serverInput = output; // the string this pass's match offsets index into\n output = output.replace(serverRe, (full, names: string, q: string, offset: number) => {\n const line = lineOf(serverInput, offset);\n const syms = names.split(\",\").map((s) => s.trim().split(/\\s+as\\s+/)[0]!.trim()).filter(Boolean);\n const allSchema = syms.length > 0 && syms.every((s) => SCHEMA_SYMBOLS.has(s));\n const allServer = syms.length > 0 && syms.every((s) => SERVER_SYMBOLS.has(s));\n if (allSchema) {\n entries.push({ severity: \"auto-fixed\", file, line, what: `import \"convex/server\" (schema)`, fix: `rewritten to \"@helipod/values\"` });\n return full.replace(/[\"']convex\\/server[\"']/, `${q}@helipod/values${q}`);\n }\n if (allServer) {\n entries.push({ severity: \"auto-fixed\", file, line, what: `import \"convex/server\" (http)`, fix: `rewritten to \"./_generated/server\"` });\n return full.replace(/[\"']convex\\/server[\"']/, `${q}./_generated/server${q}`);\n }\n const hasCron = syms.some((s) => CRON_SYMBOLS.has(s));\n const hasOther = syms.some((s) => !CRON_SYMBOLS.has(s));\n const cronFix = `cronJobs → import from \"@helipod/scheduler\" and compose defineScheduler() in helipod.config.ts`;\n const genericFix = `defineSchema/defineTable → \"@helipod/values\"; httpRouter/httpAction → \"./_generated/server\"`;\n const fix =\n hasCron && hasOther\n ? `${cronFix}; other symbols: map manually: ${genericFix}`\n : hasCron\n ? cronFix\n : `map each symbol manually: ${genericFix}`;\n entries.push({ severity: \"action-needed\", file, line, what: `import { ${syms.join(\", \")} } from \"convex/server\"`, fix });\n return full; // leave unchanged\n });\n\n // 3. Any convex/server occurrence NOT matched above (default import, export-from, require,\n // dynamic import). Re-derive step 2's brace-clause match ranges against the FINAL output (not\n // the offsets recorded during step 2, which may no longer line up after earlier rewrites shift\n // string length) so occurrences step 2 already flagged — or rewrote — aren't re-flagged here.\n const handledRanges: Array<[number, number]> = [];\n serverRe.lastIndex = 0;\n let hm: RegExpExecArray | null;\n while ((hm = serverRe.exec(output)) !== null) {\n handledRanges.push([hm.index, hm.index + hm[0].length]);\n }\n\n const residualRe = /([\"'])convex\\/server\\1/g;\n let m: RegExpExecArray | null;\n while ((m = residualRe.exec(output)) !== null) {\n if (handledRanges.some(([start, end]) => m!.index >= start && m!.index < end)) continue;\n entries.push({ severity: \"action-needed\", file, line: lineOf(output, m.index), what: `import \"convex/server\"`, fix: `map manually: defineSchema/defineTable → \"@helipod/values\"; httpRouter/httpAction → \"./_generated/server\"` });\n }\n\n return { output, entries };\n}\n","import { basename } from \"node:path\";\nimport type { ReportEntry, ReportSeverity } from \"./source\";\n\ninterface Rule {\n test: RegExp;\n severity: ReportSeverity;\n what: string;\n fix: string;\n}\n\nconst RULES: Rule[] = [\n { test: /\\.withIndex\\s*\\(/, severity: \"action-needed\", what: \".withIndex(...) query\",\n fix: `Helipod has no .withIndex — use ctx.db.query(table, \"index\").eq(f, v).gte(f, v).order(\"asc\"|\"desc\").collect()` },\n { test: /ctx\\.db\\.patch\\s*\\(/, severity: \"action-needed\", what: \"ctx.db.patch(...)\",\n fix: `Helipod has no patch — read the doc, spread-merge, ctx.db.replace(id, { ...doc, ...changes })` },\n { test: /\\.paginate\\s*\\(/, severity: \"action-needed\", what: \".paginate(...)\",\n fix: `Helipod paginate({ cursor, pageSize, maxScan? }) returns { page, nextCursor, hasMore, scanCapped }` },\n { test: /ctx\\.auth\\b|getUserIdentity\\s*\\(/, severity: \"action-needed\", what: \"ctx.auth / getUserIdentity()\",\n fix: `Identity is a string token via a context provider (e.g. @helipod/auth's ctx.auth), not a JWT-claims object` },\n { test: /@convex-dev\\/auth|[\"']convex\\/auth[\"']/, severity: \"unsupported\", what: \"Convex Auth\",\n fix: `Auth is not auto-translated — use @helipod/auth or external JWT` },\n { test: /\\bapp\\.use\\s*\\(/, severity: \"unsupported\", what: \"Convex Component (app.use)\",\n fix: `Convex Components don't map 1:1 — recompose via helipod.config.ts` },\n { test: /\\.vectorIndex\\s*\\(|\\.searchIndex\\s*\\(/, severity: \"unsupported\", what: \"vector/search index\",\n fix: `search/vector is not yet supported in Helipod (see roadmap)` },\n];\n\n/** Line-based scan for Convex runtime-API divergences Helipod does NOT auto-transform. */\nexport function scanDivergences(source: string, file: string): ReportEntry[] {\n const entries: ReportEntry[] = [];\n const lines = source.split(\"\\n\");\n\n // Whole-file signals keyed on filename.\n const base = basename(file);\n if (base === \"crons.ts\" || /\\bcronJobs\\s*\\(/.test(source)) {\n const idx = lines.findIndex((l) => /\\bcronJobs\\s*\\(/.test(l));\n entries.push({ severity: \"action-needed\", file, line: idx >= 0 ? idx + 1 : 1, what: \"Convex crons (cronJobs)\",\n fix: `Compose defineScheduler() in helipod.config.ts and use cronJobs() from \"@helipod/scheduler\"` });\n }\n if (base === \"convex.config.ts\") {\n entries.push({ severity: \"unsupported\", file, line: 1, what: \"Convex app config (convex.config.ts)\",\n fix: `Recompose components via helipod.config.ts` });\n }\n\n for (let i = 0; i < lines.length; i++) {\n for (const rule of RULES) {\n if (rule.test.test(lines[i]!)) {\n entries.push({ severity: rule.severity, file, line: i + 1, what: rule.what, fix: rule.fix });\n }\n }\n }\n return entries;\n}\n","/**\n * `helipod migrate export` / `helipod migrate import` — move an app's DATA between the two\n * storage topologies (portable container+R2 / SQLite / Postgres ⇄ Cloudflare DO-native DO-SQLite).\n * Slice 5 of the DO-native host program.\n *\n * These are HTTP clients (modelled on `deploy.ts`) that hit a RUNNING source/target deployment's\n * admin endpoints — `GET /_admin/export` and `POST /_admin/import`, bearer-gated by\n * `HELIPOD_ADMIN_KEY`. Both the container `serve` path and the Cloudflare DO host expose those\n * routes (both funnel `/_admin/*` through the same handler), so one client migrates in either\n * direction; the DO can ONLY be reached over HTTP, which is why an HTTP-first client is the coherent\n * shape. A stopped plain-SQLite source is exported by pointing a throwaway `serve`/`dev` at it first.\n */\nimport { readFileSync, writeFileSync } from \"node:fs\";\n\ninterface DataMigrateOptions {\n url: string;\n file: string; // --out for export, --in for import\n adminKey: string;\n}\n\nfunction resolveOptions(\n args: string[],\n env: NodeJS.ProcessEnv,\n fileFlag: \"--out\" | \"--in\",\n): DataMigrateOptions | { error: string } {\n let url = \"\";\n let file = \"\";\n let adminKey = env.HELIPOD_ADMIN_KEY?.trim() ?? \"\";\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--url\" && args[i + 1]) url = args[++i]!;\n else if (a === fileFlag && args[i + 1]) file = args[++i]!;\n else if (a === \"--admin-key\" && args[i + 1]) adminKey = args[++i]!;\n }\n if (!url) return { error: \"missing target URL — pass --url <url>\" };\n if (!file) return { error: `missing ${fileFlag} <file>` };\n if (!adminKey) return { error: \"HELIPOD_ADMIN_KEY is required (or pass --admin-key)\" };\n return { url, file, adminKey };\n}\n\n/** `helipod migrate export --url <src> --out dump.json` — pull the source's full state to a file. */\nexport async function migrateExportCommand(args: string[]): Promise<number> {\n const opts = resolveOptions(args, process.env, \"--out\");\n if (\"error\" in opts) {\n process.stderr.write(`✗ ${opts.error}\\n`);\n return 1;\n }\n let res: Response;\n try {\n res = await fetch(`${opts.url.replace(/\\/$/, \"\")}/_admin/export`, {\n method: \"GET\",\n headers: { authorization: `Bearer ${opts.adminKey}` },\n });\n } catch (e) {\n process.stderr.write(`✗ could not reach ${opts.url}: ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n if (res.status === 401) {\n process.stderr.write(\"✗ unauthorized — check HELIPOD_ADMIN_KEY / --admin-key\\n\");\n return 1;\n }\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as { error?: string };\n process.stderr.write(`✗ export failed: ${body.error ?? res.statusText}\\n`);\n return 1;\n }\n const dumpText = await res.text();\n writeFileSync(opts.file, dumpText);\n const dump = JSON.parse(dumpText) as { documents?: unknown[]; indexUpdates?: unknown[] };\n process.stdout.write(\n `✓ exported ${dump.documents?.length ?? 0} documents, ${dump.indexUpdates?.length ?? 0} index rows → ${opts.file}\\n`,\n );\n return 0;\n}\n\n/** `helipod migrate import --url <dst> --in dump.json` — push a dump into the target (fresh). */\nexport async function migrateImportCommand(args: string[]): Promise<number> {\n const opts = resolveOptions(args, process.env, \"--in\");\n if (\"error\" in opts) {\n process.stderr.write(`✗ ${opts.error}\\n`);\n return 1;\n }\n let dumpText: string;\n try {\n dumpText = readFileSync(opts.file, \"utf8\");\n } catch (e) {\n process.stderr.write(`✗ could not read ${opts.file}: ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n let res: Response;\n try {\n res = await fetch(`${opts.url.replace(/\\/$/, \"\")}/_admin/import`, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", authorization: `Bearer ${opts.adminKey}` },\n body: dumpText,\n });\n } catch (e) {\n process.stderr.write(`✗ could not reach ${opts.url}: ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n if (res.status === 401) {\n process.stderr.write(\"✗ unauthorized — check HELIPOD_ADMIN_KEY / --admin-key\\n\");\n return 1;\n }\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n imported?: { documents: number; indexUpdates: number };\n error?: string;\n };\n if (!res.ok || !body.ok) {\n // A table-number collision guard rejection (or a malformed dump) lands here with a clear message.\n process.stderr.write(`✗ import failed: ${body.error ?? res.statusText}\\n`);\n return 1;\n }\n process.stdout.write(\n `✓ imported ${body.imported?.documents ?? 0} documents, ${body.imported?.indexUpdates ?? 0} index rows\\n`,\n );\n return 0;\n}\n","/**\n * `helipod fleet` — the CLI entrypoint for offline fleet maintenance operations that live in the\n * enterprise `@helipod/fleet` package. Today: `fleet reshard` (B5 Part 1, Task 9.2), which changes\n * a STOPPED Postgres fleet's shard count. Core `packages/cli` keeps ZERO static dependency on\n * `@helipod/fleet` — it's loaded only via dynamic `import()`, mirroring `serve --fleet`'s gate\n * (`serve.ts`'s `fleetSpecifier`/`FLEET_ERR_NO_PACKAGE`).\n */\nimport { isPostgresUrl, makePgClient } from \"./boot\";\n\n/** The slice of `@helipod/fleet`'s reshard surface `fleetCommand` consumes (via dynamic import).\n * Declared locally (structural, not imported) for the same reason `serve.ts`'s `FleetModule` is —\n * keep core `packages/cli` free of a static/type dependency on the enterprise package. Keep in sync\n * with `ee/packages/fleet/src/reshard.ts`. */\nexport interface ReshardResult {\n previousShards: number;\n newShards: number;\n created: string[];\n deleted: string[];\n frontierFloor: string;\n}\n\nexport interface FleetModule {\n reshardFleet(client: unknown, opts: { targetShards: number }): Promise<ReshardResult>;\n ReshardFleetLiveError: new (...args: unknown[]) => Error;\n ReshardVerificationError: new (...args: unknown[]) => Error;\n}\n\n/** Same message shape as `serve.ts`'s `FLEET_ERR_NO_PACKAGE` — kept as an independent literal (no\n * cross-file import) since the two commands' failure paths are otherwise unrelated. */\nexport const FLEET_ERR_NO_PACKAGE = \"fleet mode requires @helipod/fleet — install it (bun add @helipod/fleet).\";\n\ninterface ReshardArgs {\n targetShards: number;\n databaseUrl: string;\n}\n\n/** Parse `fleet reshard`'s flags. Pure — no I/O. Returns a clear `✗`-prefixed error string on any\n * missing/invalid flag, or the validated args on success. */\nexport function parseReshardArgs(args: string[]): { ok: true; args: ReshardArgs } | { ok: false; error: string } {\n let shardsRaw: string | undefined;\n let databaseUrl: string | undefined = process.env.HELIPOD_DATABASE_URL;\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--shards\" && args[i + 1]) shardsRaw = args[++i];\n else if (a === \"--database-url\" && args[i + 1]) databaseUrl = args[++i];\n }\n\n if (shardsRaw === undefined) {\n return { ok: false, error: \"✗ --shards <M> is required — e.g. --shards 4\" };\n }\n const targetShards = Number(shardsRaw);\n if (!Number.isInteger(targetShards) || targetShards < 1) {\n return { ok: false, error: `✗ --shards must be an integer >= 1, got ${JSON.stringify(shardsRaw)}` };\n }\n\n if (!isPostgresUrl(databaseUrl)) {\n return {\n ok: false,\n error: \"✗ --database-url postgres://… is required (or HELIPOD_DATABASE_URL) — fleet reshard is Postgres-only\",\n };\n }\n\n return { ok: true, args: { targetShards, databaseUrl: databaseUrl! } };\n}\n\n/** `fleet reshard --shards M --database-url <pg>`: dynamically import `@helipod/fleet`, open a\n * short-lived PgClient (via `makePgClient` — `BunSqlClient` under Bun, `NodePgClient` elsewhere),\n * run `reshardFleet`, and print a clear result. Returns the process exit\n * code (0 on success, 1 on any validation/refusal/error). */\nasync function reshardCommand(args: string[]): Promise<number> {\n const parsed = parseReshardArgs(args);\n if (!parsed.ok) {\n process.stderr.write(parsed.error + \"\\n\");\n return 1;\n }\n const { targetShards, databaseUrl } = parsed.args;\n\n let fleetModule: FleetModule;\n try {\n // Indirect specifier (typed `string`, not a literal) so tsc does NOT statically resolve\n // `@helipod/fleet` — mirrors `serve.ts`'s `fleetSpecifier` gate.\n const fleetSpecifier: string = \"@helipod/fleet\";\n fleetModule = (await import(fleetSpecifier)) as unknown as FleetModule;\n } catch {\n process.stderr.write(`✗ ${FLEET_ERR_NO_PACKAGE}\\n`);\n return 1;\n }\n\n const client = makePgClient(databaseUrl);\n try {\n const result = await fleetModule.reshardFleet(client, { targetShards });\n process.stdout.write(\n `✓ resharded ${result.previousShards} → ${result.newShards} shards ` +\n `(created: ${result.created.length ? result.created.join(\", \") : \"none\"}, ` +\n `deleted: ${result.deleted.length ? result.deleted.join(\", \") : \"none\"}, ` +\n `frontier floor: ${result.frontierFloor}); ` +\n `update HELIPOD_FLEET_SHARDS to ${result.newShards} (or unset) before restarting the fleet\\n`,\n );\n return 0;\n } catch (e) {\n process.stderr.write(`✗ ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n } finally {\n await client.close();\n }\n}\n\n/** `helipod fleet <sub> [...]` — sub-dispatches on `args[0]`. Unknown/absent sub → usage error. */\nexport async function fleetCommand(args: string[]): Promise<number> {\n const [sub, ...rest] = args;\n switch (sub) {\n case \"reshard\":\n return reshardCommand(rest);\n default:\n process.stderr.write(\n `✗ unknown fleet subcommand: ${sub ?? \"(none)\"}\\n` +\n `Usage: helipod fleet reshard --shards M --database-url <url>\\n`,\n );\n return 1;\n }\n}\n","/**\n * `helipod objectstore <subcommand>` — object-storage maintenance tools.\n *\n * `objectstore reshard --object-store <url> --dir <functionsDir> --shards M` changes a STOPPED\n * object-storage deployment's shard count N→M: it loads the schema (for each table's shard key),\n * dynamic-imports + gates `@helipod/objectstore-substrate`, and runs `reshardObjectStore` — which\n * physically re-partitions every doc's current state to `shardIdForKeyValue(doc[shardKey], M)`'s lane\n * (see that function's doc for the offline, non-atomic, back-up-first contract). Errors — a live\n * deployment, a bad URL, missing args — surface as a clean `✗ <message>` + exit 1.\n */\nimport { dirname } from \"node:path\";\nimport { resolveObjectStore } from \"./objectstore-select\";\nimport { loadObjectStoreSubstrateModule, makeInMemorySqliteStore } from \"./boot\";\nimport { loadFunctionsDir } from \"./load-modules\";\nimport { loadConfig } from \"./load-config\";\nimport { push } from \"./push-pipeline\";\nimport { resolveFunctionsDir, ensureFunctionsDirExists } from \"./functions-dir\";\n\nexport async function objectstoreCommand(args: string[]): Promise<number> {\n const sub = args[0];\n if (sub !== \"reshard\") {\n process.stderr.write(\n `✗ unknown \\`objectstore\\` subcommand '${sub ?? \"\"}' — usage: ` +\n `helipod objectstore reshard --object-store <url> --dir <functionsDir> --shards M\\n`,\n );\n return 1;\n }\n return reshardCommand(args.slice(1));\n}\n\nasync function reshardCommand(args: string[]): Promise<number> {\n let objectStoreUrl = process.env.HELIPOD_OBJECT_STORE;\n let dirFlag: string | undefined;\n let shards: number | undefined;\n const VALUE_FLAGS = new Set([\"--object-store\", \"--dir\", \"--shards\"]);\n for (let i = 0; i < args.length; i++) {\n const a = args[i] as string;\n if (!VALUE_FLAGS.has(a)) continue;\n // A recognized flag must be followed by a value — a trailing `--dir` with no value is an error,\n // not a silent fall-through to the default (which would misroute an operator who fat-fingered it).\n const val = args[i + 1];\n if (val === undefined) {\n process.stderr.write(`✗ ${a} requires a value.\\n`);\n return 1;\n }\n i++;\n if (a === \"--object-store\") objectStoreUrl = val;\n else if (a === \"--dir\") dirFlag = val;\n else shards = Number(val);\n }\n if (!objectStoreUrl) {\n process.stderr.write(\"✗ objectstore reshard requires --object-store <url> (or HELIPOD_OBJECT_STORE).\\n\");\n return 1;\n }\n if (shards === undefined || !Number.isInteger(shards) || shards < 1) {\n process.stderr.write(\"✗ objectstore reshard requires --shards <M> (a positive integer).\\n\");\n return 1;\n }\n try {\n const resolved = resolveObjectStore(objectStoreUrl); // may throw on an unsupported scheme → clean ✗ below\n if (resolved === null) {\n process.stderr.write(`✗ --object-store \"${objectStoreUrl}\" did not resolve to a store (empty/unset value?).\\n`);\n return 1;\n }\n\n // The reshard's ONLY schema dependency: the per-table shard key. Load the app's functions dir the\n // same way `bootProject` does, and read `.shardKey` off the composed catalog.\n const { functionsDir } = await resolveFunctionsDir(dirFlag, process.cwd());\n // Fail loudly — with the migrate hint, not a raw ENOENT surfaced through the catch-all below —\n // before `loadFunctionsDir` can throw.\n if (!ensureFunctionsDirExists(functionsDir)) return 1;\n const loaded = await loadFunctionsDir(functionsDir);\n const config = await loadConfig(dirname(functionsDir));\n const { project } = push(loaded, config.components);\n const shardKeyFor = (tableNumber: number): string | null =>\n project.catalog.getTableByNumber(tableNumber)?.shardKey ?? null;\n\n const substrate = await loadObjectStoreSubstrateModule();\n await resolved.objectStore.assertCasSupported();\n\n const result = await substrate.reshardObjectStore({\n objectStore: resolved.objectStore,\n toShards: shards,\n now: Date.now(),\n shardKeyFor,\n makeLocal: makeInMemorySqliteStore,\n });\n\n if (result.fromShards === result.toShards) {\n process.stdout.write(`✓ bucket is already at ${result.toShards} shard(s) — nothing to do.\\n`);\n return 0;\n }\n const perLane = Object.entries(result.perLaneCounts)\n .map(([lane, n]) => `${lane}=${n}`)\n .join(\", \");\n process.stdout.write(\n `✓ resharded ${result.fromShards} → ${result.toShards} shard(s) ` +\n `(moved ${result.movedDocs} doc(s); per-lane: ${perLane}). ` +\n `A node booting this bucket now uses ${result.toShards} shard(s) — set --shards ${result.toShards} ` +\n `(or HELIPOD_FLEET_SHARDS), or drop it (the bucket's persisted count is authoritative).\\n`,\n );\n return 0;\n } catch (e) {\n process.stderr.write(`✗ ${e instanceof Error ? e.message : String(e)}\\n`);\n return 1;\n }\n}\n"],"mappings":"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","names":["existsSync","join","join","existsSync","existsSync","join","resolve","dirname","pathToFileURL","CACHE_BUST","mkdirSync","dirname","join","resolve","join","mkdirSync","dirname","resolve","join","readFileSync","join","resolve","resolve","join","readFileSync","response","body","dirname","join","resolve","writeGenerated","existsSync","dirname","join","resolve","PostgresDocStore","createHash","mkdirSync","writeFileSync","dirname","isAbsolute","join","createHash","join","isAbsolute","mkdirSync","dirname","writeFileSync","PostgresDocStore","join","dirname","resolve","storageRoutes","existsSync","readdirSync","statSync","readFileSync","existsSync","join","sep","readdirSync","join","statSync","readFileSync","sep","walk","existsSync","existsSync","mkdirSync","readdirSync","rmSync","statSync","writeFileSync","createRequire","dirname","join","resolve","writeGenerated","createRequire","dirname","walk","readdirSync","join","writeGenerated","existsSync","resolve","mkdirSync","writeFileSync","rmSync","statSync","writeFileSync","existsSync","mkdirSync","rmSync","basename","dirname","join","resolve","spawnSync","writeGenerated","readFileSync","readdirSync","existsSync","join","relative","readdirSync","join","existsSync","readFileSync","relative","readFileSync","writeFileSync","spawnSync","resolve","dirname","existsSync","basename","writeFileSync","join","rmSync","mkdirSync","writeGenerated","FLEET_ERR_NO_PACKAGE","dirname","reshardCommand","dirname","join","storageRoutes","writeGenerated","resolve","dirname"]}