import type { ClientPlatform } from "./types.js"; /** The bare-metal runner fleets the algorithm can execute tests on. */ export type RunnerPlatform = "android" | "ios"; /** * The remote-execution vocabulary — the building blocks the algorithm * composes into ONE emulator/simulator-bound test run (see * runRemoteJob in shared.ts): * * acquireLock → checkRunner → syncTree → ensureDevice → install → * build* → runJob → fetchResults → releaseLock * * WHICH command fails is what classifies the failure: environment * steps (checkRunner, syncTree, ensureDevice) fail as INFRASTRUCTURE — * they say nothing about the code; code-bound steps (install, build*, * runJob) are judged for interference from other agents' in-flight * work vs. a genuine result. * * These are farketari's OWN command names: the catalog defines the * vocabulary, and what actually runs behind each name is configured * per project at implementation time (the boilerplate's runner * directories carry a task vocabulary of the same shape, but nothing * here references it). */ export interface RemoteRunnerCommands { /** Pre-flight probe — runner reachable, virtualization available, disk not full. */ checkRunner: string; /** Take the runner-wide semaphore so a direct run and a real CI job never fight for the device. Held per attempt. */ acquireLock: string; /** Release the semaphore taken by acquireLock. Always runs, even after a failed attempt. */ releaseLock: string; /** Push the CURRENT working tree (uncommitted work included, no git) to the runner's workspace. */ syncTree: string; /** Install dependencies in the runner workspace after a sync — a no-op when lockfiles are unchanged. */ install: string; /** Reset the runner workspace — the recovery move when sync drift is suspected. Not part of the fixed composition. */ cleanWorkspace: string; /** Boot the device (emulator/simulator) if absent, reuse it warm if running. */ ensureDevice: string; /** Healthcheck — device absent / booting / ready / wedged. Diagnostic; not part of the fixed composition. */ deviceStatus: string; /** Kill the device — the recovery move before retrying ensureDevice. */ killDevice: string; /** Build the release binary the device jobs (acceptance, smoke) drive — a no-op when inputs are unchanged. */ buildReleaseBinary: string; /** Run the named CI job's own image + script against the synced tree (parity with the pipeline). */ runJob: string; /** Same as runJob, restricted to given spec files — cheaper repair rounds; not used by the fixed composition yet. */ runJobFiltered: string; /** Pull the last run's structured test output (per-spec verdicts) from the runner. */ fetchResults: string; /** Pull the last run's artifacts (screenshots, videos, device logs) — defect-repair evidence. Best-effort. */ fetchArtifacts: string; } /** * The commands the tool is allowed to run, as configuration — the * counterpart of RepoLayout for executables. The algorithm never invents * shell commands; it runs entries from this catalog (through the * CommandRunner role), so porting the tool to another project means * editing this catalog, not the algorithm. * * All commands run from the repository root. `<...>` marks a placeholder * the caller fills in (a migration name, a spec file, a flow file). */ export interface CommandCatalog { toolchain: { /** Install every package's dependencies — the first move in a fresh * checkout or a freshly bootstrapped project. */ install: string; }; db: { /** Start the database container. */ startDatabase: string; /** Diff the schema against the migrations and generate a new migration. */ generateMigration: string; /** Apply pending migrations. */ applyMigrations: string; /** Read-only: pending migrations / clean-apply check, between ripple steps 5 and 6. */ migrationStatus: string; /** Regenerate the typed query code from the SQL queries. */ generateQueryCode: string; /** Interactive SQL REPL — inspecting real rows during B2 divergence repair. */ psql: string; /** Wipe data without dropping the schema — clean state between repair iterations. */ resetData: string; }; contract: { /** Regenerate API clients and server types from the OpenAPI specs. */ generateClientsAndServer: string; }; stack: { /** The full local stack with real externals. */ up: string; /** The full local stack with faked externals (LLM, email, ...). */ upWithFakes: string; /** The stack flavor the client backend-integration tests expect. */ upForClientIntegrationTests: string; /** Teardown — the clean-slate move after a wedged stack or infra failure. */ down: string; }; quality: { /** Typecheck every package at once — the cheapest pre-flight before a remote run. */ typecheckAll: string; /** Per-package typechecks. */ typecheck: Partial>; /** Lint gate (needs a green baseline before it can gate anything). */ lint: string; /** Format pass — keeps multi-agent diffs reviewable. */ format: string; /** * Verifies every co-located localization catalog against the global * configuration (languages present, key parity, no empty values). * Runs as a pre-commit gate on every slice: any slice that adds a * presenter or component adds catalogs, and this proves them complete. */ localizationVerify: string; /** * Non-interactive slice-end version bumps: patch-bump every * deployable the slice changed (since the slice base, checkpoint * commits included) whose Version.ts has not moved yet. Runs before * the slice's FINAL commit so the version-bump guard — which judges * the whole slice — passes with the bump the change earns. Idempotent; * a human's deliberate minor/major bump is left alone. */ bumpChangedVersions: string; }; build: { /** Every production build — local drift insurance before the slice pipeline runs. */ all: string; webAppForAcceptance: string; flagsAdminForAcceptance: string; }; backendTests: { unit: string; /** One unit spec file — per-item TDD cycles. */ unitSingle: string; /** * One unit spec file narrowed to ONE test — and * placeholders. Used whenever the item carries the * title its write-test session reported, so an absent test reads as * "no tests found", never as the file's other tests passing. */ unitSingleTitled?: string; dbIntegration: string; /** One db-integration spec file — per-item B2 cycles. */ dbIntegrationSingle: string; redisIntegration: string; }; clientTests: Record and * placeholders (see backendTests.unitSingleTitled). */ e2eSingleTitled?: string; /** * The client's localization suite: catalog-selection tests, apart * from e2e (which asserts behavior in the default language only). * Passes empty until the client has localized screens. */ localization?: string; /** Fake-vs-real contract tests (needs the stack up). */ backendIntegration: string; /** One contract spec — per-item C2 cycles. */ backendIntegrationSingle?: string; /** The client's acceptance suite. */ acceptance: string; /** Additional acceptance lane, where one exists (mobile iOS). */ acceptanceIos?: string; }>; smoke: { /** Run all smoke journey flows (release build, real backend). */ runFlows: string; /** Run one journey flow — cheap smoke-repair iterations. */ runSingleFlow: string; }; devices: { /** Boot the local Android emulator — local mobile iteration, and the * building block a warm-emulator RemoteTestExecutor uses on the runner. */ bootAndroidEmulator: string; }; /** The remote-execution vocabulary, per runner fleet. */ remote: Record; } export interface CommandResult { succeeded: boolean; output: string; } /** Executes catalog commands and returns their outcome with full output. */ export interface CommandRunner { run(command: string, description: string): Promise; } /** * The catalog of the nextjs-fastify stack. Every entry exists in the * repo: the task-level suites forward extra args ({{.CLI_ARGS}}), which is * what the `-- ` single-test forms rely on. * * Suite output is read by models, so every entry is tuned for * FAILURE-ONLY output — a green run must cost near-zero tokens, a red * run must carry full failure detail. Vitest's default reporter already * behaves this way when piped (--silent=passed-only additionally mutes * passing tests' console noise); Playwright needs --reporter=dot or it * lists every passing test. The device lanes (mobile acceptance, smoke) * are deliberately untouched: their runs are batched on the runner and * per-spec verdicts are read from their output (remote.fetchResults), which * silencing would break. */ export declare const NEXTJS_FASTIFY_BOILERPLATE_COMMANDS: CommandCatalog;