diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7eeda0af..d9552168 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "agent-orchestrator-frontend", "version": "0.0.0", + "dependencies": { + "openapi-fetch": "^0.17.0" + }, "devDependencies": { "electron": "^33.0.0", "typescript": "^5.6.0" @@ -673,6 +676,21 @@ "wrappy": "1" } }, + "node_modules/openapi-fetch": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.17.0.tgz", + "integrity": "sha512-PsbZR1wAPcG91eEthKhN+Zn92FMHxv+/faECIwjXdxfTODGSGegYv0sc1Olz+HYPvKOuoXfp+0pA2XVt2cI0Ig==", + "license": "MIT", + "dependencies": { + "openapi-typescript-helpers": "^0.1.0" + } + }, + "node_modules/openapi-typescript-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.1.0.tgz", + "integrity": "sha512-OKTGPthhivLw/fHz6c3OPtg72vi86qaMlqbJuVJ23qOvQ+53uw1n7HdmkJFibloF7QEjDrDkzJiOJuockM/ljw==", + "license": "MIT" + }, "node_modules/p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index b58407e8..ec5b2ce9 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,9 @@ "typecheck": "tsc --noEmit", "start": "npm run build && electron ." }, + "dependencies": { + "openapi-fetch": "^0.17.0" + }, "devDependencies": { "electron": "^33.0.0", "typescript": "^5.6.0" diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts new file mode 100644 index 00000000..557c8665 --- /dev/null +++ b/frontend/src/api/client.ts @@ -0,0 +1,26 @@ +import createClient from "openapi-fetch"; +import type { paths } from "./schema"; + +// The daemon binds DEFAULT_PORT unless AO_PORT overrides it (see config.go), +// and writes the port it actually bound to running.json (runfile.File.Port). +// DEFAULT_PORT only mirrors config.DefaultPort as a last-resort fallback for +// when the runfile hasn't been read yet — clients must NOT assume it. +export const DEFAULT_PORT = 3001; + +// baseURLForPort builds the loopback base URL for a known daemon port. Pass the +// port read from running.json; default only as a fallback. +export const baseURLForPort = (port: number = DEFAULT_PORT): string => + `http://127.0.0.1:${port}`; + +// createApiClient builds a typed openapi-fetch client for the daemon's +// /api/v1 surface. The renderer cannot read running.json directly, so the +// wiring layer must read it (via IPC to the main process) and pass the resolved +// base URL here — hardcoding DEFAULT_PORT would silently break any user who +// overrides AO_PORT. Request/response types come from ./schema.ts, generated +// from the backend OpenAPI document (`npm run api` at the repo root). +export const createApiClient = (baseUrl: string) => + createClient({ baseUrl }); + +// Re-export the generated component schemas for convenient use in the renderer, +// e.g. components["schemas"]["Project"], "Session", "APIError". +export type { components, paths } from "./schema";