unfazed 0.9.0 → 0.10.1
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.
- package/CHANGELOG.md +46 -0
- package/README.md +59 -2
- package/REFERENCE.md +2 -2
- package/dist/cli/eve-sandbox.d.ts +3 -0
- package/dist/cli/eve-sandbox.js +268 -0
- package/dist/cli/eve-sandbox.js.map +1 -0
- package/dist/cli/login.d.ts +1 -1
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/eve-sandbox/daemon.d.ts +65 -0
- package/dist/eve-sandbox/daemon.js +687 -0
- package/dist/eve-sandbox/daemon.js.map +1 -0
- package/dist/eve-sandbox/index.d.ts +82 -0
- package/dist/eve-sandbox/index.js +368 -0
- package/dist/eve-sandbox/index.js.map +1 -0
- package/dist/eve-sandbox/protocol.d.ts +68 -0
- package/dist/eve-sandbox/protocol.js +22 -0
- package/dist/eve-sandbox/protocol.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/oidc.d.ts +3 -3
- package/dist/oidc.js +3 -3
- package/dist/oidc.js.map +1 -1
- package/dist/reference.generated.js +1 -1
- package/dist/reference.generated.js.map +1 -1
- package/package.json +14 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference.generated.js","sourceRoot":"","sources":["../src/reference.generated.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yDAAyD;AAEzD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAW,ymiBAAymiB,CAAC","sourcesContent":["// GENERATED by scripts/embed-reference.ts from REFERENCE.md. Do not edit:\n// change REFERENCE.md and run `bun run embed-reference`.\n\n/** The SDK's reference: every method with its signature (REFERENCE.md). */\nexport const REFERENCE: string = \"# unfazed SDK reference\\n\\nEvery method of `Unfazed`, with its signature, in one page. In a script:\\n`import { Unfazed, help } from \\\"unfazed\\\"; const unfazed = new Unfazed();`\\n(run_script injects the credential; elsewhere `UNFZ_API_TOKEN` or\\n`npx unfazed login`; `oidc` needs neither). `help()` returns this page;\\n`help(\\\"writeFiles\\\")` one entry. Methods are async and throw an\\n`UnfazedError` subclass on failure.\\nEvery method takes an optional last `options` with `signal` (and, for single\\nrequests, `timeoutMs`). The names follow the MCP tools: `listCommits` is\\n`list_commits`, `waitForEvents` is `wait_for_events`.\\n\\n```ts\\nimport { Unfazed } from \\\"unfazed\\\";\\n\\nexport default async () => {\\n const unfazed = new Unfazed();\\n const ws = await unfazed.ensureWorkspace(\\\"hello\\\");\\n const wrote = await unfazed.writeFiles(ws.id, {\\n \\\"server.ts\\\": `export default { fetch: () => new Response(\\\"hi\\\") }`,\\n \\\"package.json\\\": JSON.stringify({ name: \\\"hello\\\" }),\\n }, { commitMessage: \\\"First version\\\" }); // ONE request, ONE commit\\n const app = await unfazed.deployService({ workspaceId: ws.id, alias: \\\"hello\\\", wait: true });\\n return { url: app.url, commit: wrote.commit?.sha, timings: app.timings };\\n};\\n```\\n\\n## Saved, committed, deployed\\n\\nA file write has three states. **Saved**: the call returned; the app's\\nfiles have it and the next deploy uses it. **Committed**: on an app with\\nplatform git, `commit.committed && !commit.waiting`; it is in `listCommits`.\\n**Deployed**: a deploy of those files went READY (`deployService({ wait:\\ntrue })`). A write never deploys by itself, except when `commit.deploys` is\\ntrue (the branch head is imported like a push).\\n\\n`commit.waiting: true` means saved, with the commit queued for the git\\nserver: it lands in order, `sha` is null until then, nothing to retry.\\n`waitForCommit` (or `writeFiles(…, { waitForCommit: true })`) resolves once\\nit landed.\\n\\n## Workspaces\\n\\n### `createWorkspace(name: string): Promise<Workspace>`\\nA new workspace: files, env, deployments. Names are unique per owner,\\ncase-insensitively; prefer `ensureWorkspace` in re-runnable scripts.\\n\\n### `ensureWorkspace(name: string): Promise<Workspace>`\\nThe workspace named `name`, created only when missing. Safe to re-run.\\n\\n### `listWorkspaces(): Promise<Workspace[]>`\\n\\n### `liveApps(workspaceId: string): Promise<LiveApp[]>`\\nThe apps the workspace serves now: `{ alias, deploymentID, domains }`.\\n\\n### `deleteWorkspace(workspaceId: string, options?: { withDeployments?: true, confirmAliases: string[], ignoreNotFound?: boolean }): Promise<boolean>`\\nDeletes it; with `withDeployments`, every app it serves, which\\n`confirmAliases` must name exactly (`liveApps`). Kept 30 days for support.\\n\\n### `deleteApp(app: { workspaceId, alias }, options?: { ignoreNotFound?: boolean }): Promise<DeleteAppResult>`\\nDeletes one app (every deployment of the alias, its App State, env and\\nbindings); the workspace and its other apps stay.\\n\\n### `whoami(): Promise<Whoami>`\\nWho the token is, its scopes, usage and limits.\\n\\n## Files\\n\\n### `writeFiles(workspaceId: string, files: Record<string, string | { text } | { base64 } | { bytes }>, options?: { commitMessage?: string, waitForCommit?: boolean | WaitOptions, allowPartial?: boolean }): Promise<WriteFilesResult>`\\nWrites every file in ONE request, which is ONE commit on an app with\\nplatform git (MCP `write_workspace_files`). Result: `{ files: [{ path, ok,\\nerror, file }], written, failed, totalBytes, commit, commits, landed? }`;\\n`commit` is `{ sha, branch, message, committed, waiting, waitingCount,\\ndeploys, conflicts, writeSHA, paused }` or null without platform git. Not\\ntransactional: when a file fails it throws `UnfazedWriteError` (`.result`,\\n`.failed`) unless `allowPartial`. Up to 100 files and 32 MiB per request; a\\nbigger map is several requests, each a commit.\\n\\n```ts\\nconst out = await unfazed.writeFiles(ws.id, { \\\"a.ts\\\": a, \\\"logo.png\\\": { bytes } }, { commitMessage: \\\"Logo\\\" });\\nif (out.commit?.conflicts.length) console.log(\\\"a push changed\\\", out.commit.conflicts, \\\"mine:\\\", out.commit.writeSHA);\\n```\\n\\n### `writeFile(workspaceId: string, path: string, text: string, options?: { commitMessage?, waitForCommit? }): Promise<WorkspaceFile & { commit }>`\\nOne text file: `writeFiles` with one entry.\\n\\n### `writeBinaryFile(workspaceId: string, path: string, content: Uint8Array | ArrayBuffer | { base64: string }, options?): Promise<WorkspaceFile & { commit }>`\\n\\n### `waitForCommit(workspaceId: string, waitOptions?: WaitOptions): Promise<{ branch, head, waitedMs }>`\\nResolves once no write of the app waits for its commit; `head` then has\\nevery earlier write. Immediate (`head: null`) without platform git. Default\\ntimeout 2 minutes (`UnfazedTimeoutError`; the writes stay saved).\\n\\n### `readFile(workspaceId: string, path: string, input?: { offset?, limit? }): Promise<{ text, totalBytes, truncated, nextOffset, file } | null>`\\n\\n### `listFiles(workspaceId: string, input?: { limit?, offset?, order? }): Promise<WorkspaceFilePage>`\\n\\n### `deleteFile(workspaceId: string, path: string): Promise<boolean>`\\n`false` when there was nothing to delete.\\n\\n## Deploys\\n\\n### `deployService(options: { workspaceId, alias?, wait?, waitOptions?, timings?, runtime?, serviceMode?, healthPath?, cronSchedule?, cronPath? }): Promise<DeployResult>`\\nBuilds and deploys the workspace as an HTTP service (`server.ts` default\\nexport, or `unfazed.json`). Returns BUILDING at once; with `wait: true`,\\nresolves READY or throws `UnfazedDeployError` (`reason` FAILED with the\\nbuild error, or TIMEOUT; default 10 minutes). Every call is a new release;\\nthe same `alias` redeploys that app.\\n\\nWith `wait: true` the result has `timings`:\\n`{ client: { createMs, waitMs, totalMs, waitRequests, waitMode },\\nplatform: { totalMs, buildMs, promoteMs, phases, buildMode,\\nartifactTransport, buildMemoryMiB } }`, both in milliseconds. `platform` is\\nwhat the platform measured (created to READY); `client` is what you waited.\\nThe wait is server-side, so the two differ by about one round trip.\\n\\n```ts\\nconst app = await unfazed.deployService({ workspaceId: ws.id, alias: \\\"api\\\", wait: true });\\napp.timings?.platform?.phases; // { vm_install: 900, vm_build: 2600, admission: 40, … }\\n```\\n\\n### `deployStatic(options: { workspaceId, alias?, wait?, spaMode? }): Promise<DeployResult>`\\n\\n### `deployBox(options: { workspaceId, alias, wait?, resources?: { memMiB?, vcpus?, diskGiB? } }): Promise<DeployResult>`\\nA persistent Linux VM over SSH (`sshCommand`). Always pass `alias`.\\n\\n### `deploy(input: CreateDeploymentInput, options?: { wait?, waitOptions?, timings? }): Promise<DeployResult>`\\nAny `createDeployment` input.\\n\\n### `waitForDeployment(target: string | { workspaceId, gitCommit, alias?, after? }, waitOptions?: WaitOptions): Promise<Deployment>`\\nWaits server-side (MCP `wait_for_deployment`: one request per 45 s at most,\\nanswered when the status changes) until READY; throws `UnfazedDeployError`\\non FAILED or timeout. A new app's landing on its server is waited for too.\\n`waitOptions: { timeoutMs?, signal?, mode?: \\\"server\\\" | \\\"poll\\\" }`. The\\nplatform holds at most 16 waits of one account at once; past that a wait\\nby id polls instead.\\n\\nInstead of an id, name the deploy a git import makes of a commit (a\\nrestore, a push or a sync deploys before any id exists): `{ workspaceId,\\ngitCommit, alias?, after? }`. The wait covers the import too, and a failed\\nimport throws `UnfazedDeployError` with its error. `alias` is required when\\nseveral apps (`apps[]`) deployed the commit; `after` (a restore's\\n`waitAfter`) counts only deployments begun after it.\\n\\n### `getDeployment(deploymentId: string): Promise<Deployment | null>`\\n\\n### `getDeploymentByAlias(alias: string): Promise<Deployment | null>`\\n\\n### `listDeployments(input?: { workspaceID?, alias?, kind?, limit?, offset? }): Promise<DeploymentPage>`\\nNewest first.\\n\\n### `listReleases(alias: string): Promise<Deployment[]>`\\nThe alias's history; `aliasHeld` marks the live one.\\n\\n### `rollback(options: { alias, to?, expectedCurrentId?, retries? }): Promise<Deployment>`\\nPoints the alias back at a prior READY release (default: the one before\\nthe live one). A bare `rollback({ alias })` toggles; pin `to` in anything\\nre-runnable.\\n\\n### `deleteDeployment(deploymentId: string, options?: { ignoreNotFound? }): Promise<boolean>`\\n\\n## Runtime, logs, events, timings\\n\\n### `getStatus(deploymentId: string): Promise<ServiceStatus>`\\n`{ running, health, inFlight, restartCount, memSizeMiB, lastError, … }`.\\n\\n### `getLogs(deploymentId: string, input?: { tailBytes? }): Promise<{ stdout, stderr, truncated, … }>`\\nFilter in the script: `logs.stderr.split(\\\"\\\\n\\\").filter((l) => l.includes(\\\"ERROR\\\"))`.\\n\\n### `getEvents(deploymentId: string, limit?: number): Promise<DeploymentEvent[]>`\\nThe latest `limit` (default 20) lifecycle events, oldest first: `{ type,\\ntypeEnum, severity, message, vmID, metadata, timings, createdAt }`. `type`\\nis the event's own name, as MCP reports it: `\\\"deployment.build_finished\\\"`,\\n`\\\"deployment.phases\\\"`, `\\\"service.vm_started\\\"`. `typeEnum` is the GraphQL\\nenum (`UNKNOWN` for names it lacks); match on `type`. A timing event's\\n`timings` is what it measured, parsed by the platform; null otherwise.\\n\\n### `getDeploymentTimings(deploymentId: string): Promise<PlatformTimings | null>`\\nA deploy's measured phases (ms), as the platform reads them from all its\\ntiming events: `{ totalMs, buildMs, promoteMs, phases, buildMode,\\nartifactTransport, buildMemoryMiB }`. `parseDeploymentTimings(events)` does\\nthe same for events you already read, preferring each event's `timings`;\\ndurations are whole, non-negative milliseconds (anything else is dropped).\\n\\n### `restartService(deploymentId: string)` / `stopService(deploymentId: string)`\\n\\n## Env and secrets\\n\\nSnapshotted into a release at deploy time: redeploy the alias to apply.\\n\\n### `setEnv(workspaceId, name, value)` / `setSecret(workspaceId, name, value)`: `Promise<EnvVar>`\\nWorkspace defaults. A name is plain or secret, never both.\\n\\n### `setEnvMany(workspaceId: string, vars: Record<string, string>, options?: { secret?: boolean }): Promise<EnvVar[]>`\\n\\n### `deleteEnv(workspaceId, name): Promise<boolean>` / `listEnv(workspaceId): Promise<EnvVar[]>`\\n\\n### `setAppEnv(workspaceId, alias, name, value)` / `setAppSecret(workspaceId, alias, name, value)`: `Promise<EnvVar>`\\nOne app's override.\\n\\n### `removeAppEnv(workspaceId, alias, name): Promise<boolean>`\\nBlocks the name for the app (a mask). `inheritAppEnv` clears it.\\n\\n### `inheritAppEnv(workspaceId, alias, name): Promise<boolean>` / `listAppEnv(workspaceId, alias): Promise<EnvVar[]>`\\n\\n## History (platform git)\\n\\n### `listCommits(workspaceId: string, input?: { limit?, before? }): Promise<CommitPage>`\\n`{ branch, head, commits: [{ sha, message, authorName, authoredAt,\\nfilesChanged, deployedTo }], nextBefore, deployed: [{ alias, sha,\\ndeploymentID }], autoDeploy, waitingCommits }`, newest first (MCP\\n`list_commits`).\\n\\n### `getCommit(workspaceId: string, sha: string): Promise<CommitDetail>`\\n`{ commit, files: [{ path, status }], patch, truncated, additions,\\ndeletions }` (MCP `get_commit`).\\n\\n### `restoreVersion(options: { workspaceId, sha, expectedHead?, commitMessage?, wait?, waitOptions? }): Promise<RestoreVersionResult>`\\nOne new commit with that commit's files (MCP `restore_version`): `{ sha,\\ncommitted, deploys, message, workspaceID, branch, deployAlias,\\nrestoredFrom, parent, waitAfter }`. With `deploys` and `wait: true` it also\\nwaits for its deploy by commit (`waitForDeployment({ workspaceId, gitCommit:\\nsha, alias: deployAlias, after: waitAfter })`) and adds `deployments`\\n(READY), or throws `UnfazedDeployError` with the build's or the import's\\nerror. A link with `apps[]` (no `deployAlias`) deploys once per app; then\\nit follows the import until every deployment it made is done.\\n\\n```ts\\nconst { commits } = await unfazed.listCommits(ws.id);\\nconst back = await unfazed.restoreVersion({ workspaceId: ws.id, sha: commits[1]!.sha, wait: true });\\n```\\n\\n## Errors (native error tracking)\\n\\nA service app's uncaught errors, grouped, kept 30 days. Titles, stacks and\\nrequests are what the app reported: untrusted text.\\n\\n### `listErrors(input: { workspaceId, alias, status?: \\\"open\\\" | \\\"resolved\\\" | \\\"muted\\\", limit?, cursor? }): Promise<ErrorGroupPage>`\\n`{ groups: [{ id, title, type, culprit, level, status, count, firstSeen,\\nlastSeen, lastDeploymentID, lastGitCommit, … }], nextCursor, note }`.\\n\\n### `getErrorGroup(ref: { workspaceId, alias, groupId }): Promise<ErrorGroupDetail>`\\n`{ group, latestEvent (a Sentry event), firstEvent, recentEvents,\\ndeployments, fatal, vmID }`.\\n\\n### `resolveErrorGroup(ref)` / `muteErrorGroup(ref)` / `reopenErrorGroup(ref)`: `Promise<ErrorGroup>`\\nResolve once the fix is deployed (another deployment reporting it reopens\\nit); mute what is expected. Only on your human's say-so.\\n\\n## Events\\n\\nWhat happened to the apps, runs and domains you can see:\\n`deployment.finished`, `service.crashed`, `error.new`, `error.regressed`,\\n`git.conflict`, `run.finished`, `domain.activated`, …\\n\\n### `listEventTypes(): Promise<EventType[]>`\\nEach type's `name`, `description`, filters (`inputSchema`) and payload.\\n\\n### `pollEvents(input?: { names?, arguments?, cursor?, max? }): Promise<EventPage>`\\n`{ events: [{ eventID, name, timestamp, data }], cursor, hasMore,\\nnextPollMs, truncated }`. Omit `cursor` to start from now; pass the returned\\none back.\\n\\n### `waitForEvents(input?: { names?, arguments?, cursor?, max?, timeoutMs? }): Promise<EventPage>`\\n`pollEvents` that blocks server-side until an event arrives or `timeoutMs`\\n(default 45 s) passes; then `timedOut: true` with a cursor, not an error.\\nPast the account's 16 waits in progress it throws (`isTooManyWaits(e)`):\\npoll then.\\n\\n```ts\\nlet page = await unfazed.pollEvents({ names: [\\\"deployment.finished\\\"], arguments: { \\\"deployment.finished\\\": { alias: \\\"api\\\" } } });\\n// … deploy …\\npage = await unfazed.waitForEvents({ names: [\\\"deployment.finished\\\"], cursor: page.cursor, timeoutMs: 120_000 });\\n```\\n\\n## Agent runs\\n\\n### `createRun(options: { workspaceId, prompt?, harness?, command?, setup?, verify?, access?, alias?, maxSeconds?, wait? }): Promise<Run>`\\nA one-shot agent run in a fresh VM. `wait: true` polls to SUCCEEDED,\\nFAILED or CANCELLED (all returned, never thrown).\\n\\n### `waitForRun(runId: string, waitOptions?: WaitOptions): Promise<Run>`\\n\\n### `getRun(runId)` / `listRuns(filter?: { workspaceId?, status?, limit?, offset? })` / `cancelRun(runId)`\\n\\n### `followUpRun(runId: string, options: { prompt, mode?, wait? }): Promise<Run>`\\n\\n### `answerRun(runId: string, answer: string): Promise<Run>`\\nAnswers a BLOCKED run's question.\\n\\n### `runEvents(runId)` / `runConsole(runId, { tailBytes? })` / `runTranscript(runId, { tailBytes? })`\\n\\n### `listRunHarnesses(): Promise<RunHarness[]>`\\n\\n## Workload identity\\n\\nOIDC tokens the platform issues to the app the code runs in (a service or a\\ncron job): short-lived JWTs for one audience, from the issuer\\n`https://unfazed.dev/oidc`, which a service that trusts it takes instead of\\nan API key. Claims include `sub`, `aud`, `owner_id`, `project_id`, `app_id`,\\n`alias`, `environment` and `deployment_id`. The only credential is the app's\\n`UNFZ_STATE_TOKEN`, set in each of its VMs: no API token, so a bare\\n`new Unfazed()` works in an app for this. Without an instance:\\n`import { oidc, oidcToken } from \\\"unfazed\\\"` (`oidcToken(audience)` is\\n`oidc.token(audience)`).\\n\\n### `oidc.token(audience: string, options?: { ttlSeconds?, signal? }): Promise<string>`\\nA JWT for `audience` (1 to 256 printable ASCII characters, no whitespace);\\n`ttlSeconds` from 60 to 3600, else the platform's default. Cached per\\n(audience, ttl) until 80% of its lifetime; concurrent calls share one\\nrequest. 503s, network failures and 429s (after their `Retry-After`) are\\nretried up to 3 times; if a refresh still fails that way, the previous token\\ncomes back while it is valid. Throws `UnfazedOIDCError` (`code`, `status`,\\n`description`, `retryable`, `retryAfterMs`): `not_in_app` (no\\n`UNFZ_STATE_TOKEN`), `invalid_audience`, `invalid_request`, `invalid_token`,\\n`rate_limited`, `oidc_disabled`, `temporarily_unavailable`, `unreachable`.\\n\\n```ts\\nconst jwt = await unfazed.oidc.token(\\\"https://api.example.com\\\", { ttlSeconds: 300 });\\nawait fetch(\\\"https://api.example.com/v1/things\\\", { headers: { Authorization: `Bearer ${jwt}` } });\\n```\\n\\n### `oidc.tokenResponse(audience: string, options?: { ttlSeconds?, signal? }): Promise<{ token, expiresAt: Date }>`\\n`oidc.token` with the token's expiry.\\n\\n### `oidc.fetchWithToken(audience: string, options?: { ttlSeconds?, fetch? }): fetch`\\nA `fetch` that sends each request with `Authorization: Bearer <token>`\\n(replacing one already there), everything else as given: for a client that\\ntakes a `fetch`. An invalid audience (an unset variable) throws at once.\\n\\n```ts\\nconst openai = new OpenAI({\\n baseURL: process.env.PRIVATEINFERENCE_BASE_URL,\\n apiKey: \\\"unused\\\",\\n fetch: unfazed.oidc.fetchWithToken(process.env.PRIVATEINFERENCE_AUDIENCE),\\n});\\n```\\n\\n## Anything else\\n\\n`unfazed.client` is the typed GraphQL transport over the same credential:\\n`await unfazed.client.query(document, variables)`. `operations` exports\\nevery document the SDK uses.\\n\";\n"]}
|
|
1
|
+
{"version":3,"file":"reference.generated.js","sourceRoot":"","sources":["../src/reference.generated.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yDAAyD;AAEzD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,SAAS,GAAW,+kiBAA+kiB,CAAC","sourcesContent":["// GENERATED by scripts/embed-reference.ts from REFERENCE.md. Do not edit:\n// change REFERENCE.md and run `bun run embed-reference`.\n\n/** The SDK's reference: every method with its signature (REFERENCE.md). */\nexport const REFERENCE: string = \"# unfazed SDK reference\\n\\nEvery method of `Unfazed`, with its signature, in one page. In a script:\\n`import { Unfazed, help } from \\\"unfazed\\\"; const unfazed = new Unfazed();`\\n(run_script injects the credential; elsewhere `UNFZ_API_TOKEN` or\\n`npx unfazed login`; `oidc` needs neither). `help()` returns this page;\\n`help(\\\"writeFiles\\\")` one entry. Methods are async and throw an\\n`UnfazedError` subclass on failure.\\nEvery method takes an optional last `options` with `signal` (and, for single\\nrequests, `timeoutMs`). The names follow the MCP tools: `listCommits` is\\n`list_commits`, `waitForEvents` is `wait_for_events`.\\n\\n```ts\\nimport { Unfazed } from \\\"unfazed\\\";\\n\\nexport default async () => {\\n const unfazed = new Unfazed();\\n const ws = await unfazed.ensureWorkspace(\\\"hello\\\");\\n const wrote = await unfazed.writeFiles(ws.id, {\\n \\\"server.ts\\\": `export default { fetch: () => new Response(\\\"hi\\\") }`,\\n \\\"package.json\\\": JSON.stringify({ name: \\\"hello\\\" }),\\n }, { commitMessage: \\\"First version\\\" }); // ONE request, ONE commit\\n const app = await unfazed.deployService({ workspaceId: ws.id, alias: \\\"hello\\\", wait: true });\\n return { url: app.url, commit: wrote.commit?.sha, timings: app.timings };\\n};\\n```\\n\\n## Saved, committed, deployed\\n\\nA file write has three states. **Saved**: the call returned; the app's\\nfiles have it and the next deploy uses it. **Committed**: on an app with\\nplatform git, `commit.committed && !commit.waiting`; it is in `listCommits`.\\n**Deployed**: a deploy of those files went READY (`deployService({ wait:\\ntrue })`). A write never deploys by itself, except when `commit.deploys` is\\ntrue (the branch head is imported like a push).\\n\\n`commit.waiting: true` means saved, with the commit queued for the git\\nserver: it lands in order, `sha` is null until then, nothing to retry.\\n`waitForCommit` (or `writeFiles(…, { waitForCommit: true })`) resolves once\\nit landed.\\n\\n## Workspaces\\n\\n### `createWorkspace(name: string): Promise<Workspace>`\\nA new workspace: files, env, deployments. Names are unique per owner,\\ncase-insensitively; prefer `ensureWorkspace` in re-runnable scripts.\\n\\n### `ensureWorkspace(name: string): Promise<Workspace>`\\nThe workspace named `name`, created only when missing. Safe to re-run.\\n\\n### `listWorkspaces(): Promise<Workspace[]>`\\n\\n### `liveApps(workspaceId: string): Promise<LiveApp[]>`\\nThe apps the workspace serves now: `{ alias, deploymentID, domains }`.\\n\\n### `deleteWorkspace(workspaceId: string, options?: { withDeployments?: true, confirmAliases: string[], ignoreNotFound?: boolean }): Promise<boolean>`\\nDeletes it; with `withDeployments`, every app it serves, which\\n`confirmAliases` must name exactly (`liveApps`). Kept 30 days for support.\\n\\n### `deleteApp(app: { workspaceId, alias }, options?: { ignoreNotFound?: boolean }): Promise<DeleteAppResult>`\\nDeletes one app (every deployment of the alias, its App State, env and\\nbindings); the workspace and its other apps stay.\\n\\n### `whoami(): Promise<Whoami>`\\nWho the token is, its scopes, usage and limits.\\n\\n## Files\\n\\n### `writeFiles(workspaceId: string, files: Record<string, string | { text } | { base64 } | { bytes }>, options?: { commitMessage?: string, waitForCommit?: boolean | WaitOptions, allowPartial?: boolean }): Promise<WriteFilesResult>`\\nWrites every file in ONE request, which is ONE commit on an app with\\nplatform git (MCP `write_workspace_files`). Result: `{ files: [{ path, ok,\\nerror, file }], written, failed, totalBytes, commit, commits, landed? }`;\\n`commit` is `{ sha, branch, message, committed, waiting, waitingCount,\\ndeploys, conflicts, writeSHA, paused }` or null without platform git. Not\\ntransactional: when a file fails it throws `UnfazedWriteError` (`.result`,\\n`.failed`) unless `allowPartial`. Up to 100 files and 32 MiB per request; a\\nbigger map is several requests, each a commit.\\n\\n```ts\\nconst out = await unfazed.writeFiles(ws.id, { \\\"a.ts\\\": a, \\\"logo.png\\\": { bytes } }, { commitMessage: \\\"Logo\\\" });\\nif (out.commit?.conflicts.length) console.log(\\\"a push changed\\\", out.commit.conflicts, \\\"mine:\\\", out.commit.writeSHA);\\n```\\n\\n### `writeFile(workspaceId: string, path: string, text: string, options?: { commitMessage?, waitForCommit? }): Promise<WorkspaceFile & { commit }>`\\nOne text file: `writeFiles` with one entry.\\n\\n### `writeBinaryFile(workspaceId: string, path: string, content: Uint8Array | ArrayBuffer | { base64: string }, options?): Promise<WorkspaceFile & { commit }>`\\n\\n### `waitForCommit(workspaceId: string, waitOptions?: WaitOptions): Promise<{ branch, head, waitedMs }>`\\nResolves once no write of the app waits for its commit; `head` then has\\nevery earlier write. Immediate (`head: null`) without platform git. Default\\ntimeout 2 minutes (`UnfazedTimeoutError`; the writes stay saved).\\n\\n### `readFile(workspaceId: string, path: string, input?: { offset?, limit? }): Promise<{ text, totalBytes, truncated, nextOffset, file } | null>`\\n\\n### `listFiles(workspaceId: string, input?: { limit?, offset?, order? }): Promise<WorkspaceFilePage>`\\n\\n### `deleteFile(workspaceId: string, path: string): Promise<boolean>`\\n`false` when there was nothing to delete.\\n\\n## Deploys\\n\\n### `deployService(options: { workspaceId, alias?, wait?, waitOptions?, timings?, runtime?, serviceMode?, healthPath?, cronSchedule?, cronPath? }): Promise<DeployResult>`\\nBuilds and deploys the workspace as an HTTP service (`server.ts` default\\nexport, or `unfazed.json`). Returns BUILDING at once; with `wait: true`,\\nresolves READY or throws `UnfazedDeployError` (`reason` FAILED with the\\nbuild error, or TIMEOUT; default 10 minutes). Every call is a new release;\\nthe same `alias` redeploys that app.\\n\\nWith `wait: true` the result has `timings`:\\n`{ client: { createMs, waitMs, totalMs, waitRequests, waitMode },\\nplatform: { totalMs, buildMs, promoteMs, phases, buildMode,\\nartifactTransport, buildMemoryMiB } }`, both in milliseconds. `platform` is\\nwhat the platform measured (created to READY); `client` is what you waited.\\nThe wait is server-side, so the two differ by about one round trip.\\n\\n```ts\\nconst app = await unfazed.deployService({ workspaceId: ws.id, alias: \\\"api\\\", wait: true });\\napp.timings?.platform?.phases; // { vm_install: 900, vm_build: 2600, admission: 40, … }\\n```\\n\\n### `deployStatic(options: { workspaceId, alias?, wait?, spaMode? }): Promise<DeployResult>`\\n\\n### `deployBox(options: { workspaceId, alias, wait?, resources?: { memMiB?, vcpus?, diskGiB? } }): Promise<DeployResult>`\\nA persistent Linux VM over SSH (`sshCommand`). Always pass `alias`.\\n\\n### `deploy(input: CreateDeploymentInput, options?: { wait?, waitOptions?, timings? }): Promise<DeployResult>`\\nAny `createDeployment` input.\\n\\n### `waitForDeployment(target: string | { workspaceId, gitCommit, alias?, after? }, waitOptions?: WaitOptions): Promise<Deployment>`\\nWaits server-side (MCP `wait_for_deployment`: one request per 45 s at most,\\nanswered when the status changes) until READY; throws `UnfazedDeployError`\\non FAILED or timeout. A new app's landing on its server is waited for too.\\n`waitOptions: { timeoutMs?, signal?, mode?: \\\"server\\\" | \\\"poll\\\" }`. The\\nplatform holds at most 16 waits of one account at once; past that a wait\\nby id polls instead.\\n\\nInstead of an id, name the deploy a git import makes of a commit (a\\nrestore, a push or a sync deploys before any id exists): `{ workspaceId,\\ngitCommit, alias?, after? }`. The wait covers the import too, and a failed\\nimport throws `UnfazedDeployError` with its error. `alias` is required when\\nseveral apps (`apps[]`) deployed the commit; `after` (a restore's\\n`waitAfter`) counts only deployments begun after it.\\n\\n### `getDeployment(deploymentId: string): Promise<Deployment | null>`\\n\\n### `getDeploymentByAlias(alias: string): Promise<Deployment | null>`\\n\\n### `listDeployments(input?: { workspaceID?, alias?, kind?, limit?, offset? }): Promise<DeploymentPage>`\\nNewest first.\\n\\n### `listReleases(alias: string): Promise<Deployment[]>`\\nThe alias's history; `aliasHeld` marks the live one.\\n\\n### `rollback(options: { alias, to?, expectedCurrentId?, retries? }): Promise<Deployment>`\\nPoints the alias back at a prior READY release (default: the one before\\nthe live one). A bare `rollback({ alias })` toggles; pin `to` in anything\\nre-runnable.\\n\\n### `deleteDeployment(deploymentId: string, options?: { ignoreNotFound? }): Promise<boolean>`\\n\\n## Runtime, logs, events, timings\\n\\n### `getStatus(deploymentId: string): Promise<ServiceStatus>`\\n`{ running, health, inFlight, restartCount, memSizeMiB, lastError, … }`.\\n\\n### `getLogs(deploymentId: string, input?: { tailBytes? }): Promise<{ stdout, stderr, truncated, … }>`\\nFilter in the script: `logs.stderr.split(\\\"\\\\n\\\").filter((l) => l.includes(\\\"ERROR\\\"))`.\\n\\n### `getEvents(deploymentId: string, limit?: number): Promise<DeploymentEvent[]>`\\nThe latest `limit` (default 20) lifecycle events, oldest first: `{ type,\\ntypeEnum, severity, message, vmID, metadata, timings, createdAt }`. `type`\\nis the event's own name, as MCP reports it: `\\\"deployment.build_finished\\\"`,\\n`\\\"deployment.phases\\\"`, `\\\"service.vm_started\\\"`. `typeEnum` is the GraphQL\\nenum (`UNKNOWN` for names it lacks); match on `type`. A timing event's\\n`timings` is what it measured, parsed by the platform; null otherwise.\\n\\n### `getDeploymentTimings(deploymentId: string): Promise<PlatformTimings | null>`\\nA deploy's measured phases (ms), as the platform reads them from all its\\ntiming events: `{ totalMs, buildMs, promoteMs, phases, buildMode,\\nartifactTransport, buildMemoryMiB }`. `parseDeploymentTimings(events)` does\\nthe same for events you already read, preferring each event's `timings`;\\ndurations are whole, non-negative milliseconds (anything else is dropped).\\n\\n### `restartService(deploymentId: string)` / `stopService(deploymentId: string)`\\n\\n## Env and secrets\\n\\nSnapshotted into a release at deploy time: redeploy the alias to apply.\\n\\n### `setEnv(workspaceId, name, value)` / `setSecret(workspaceId, name, value)`: `Promise<EnvVar>`\\nWorkspace defaults. A name is plain or secret, never both.\\n\\n### `setEnvMany(workspaceId: string, vars: Record<string, string>, options?: { secret?: boolean }): Promise<EnvVar[]>`\\n\\n### `deleteEnv(workspaceId, name): Promise<boolean>` / `listEnv(workspaceId): Promise<EnvVar[]>`\\n\\n### `setAppEnv(workspaceId, alias, name, value)` / `setAppSecret(workspaceId, alias, name, value)`: `Promise<EnvVar>`\\nOne app's override.\\n\\n### `removeAppEnv(workspaceId, alias, name): Promise<boolean>`\\nBlocks the name for the app (a mask). `inheritAppEnv` clears it.\\n\\n### `inheritAppEnv(workspaceId, alias, name): Promise<boolean>` / `listAppEnv(workspaceId, alias): Promise<EnvVar[]>`\\n\\n## History (platform git)\\n\\n### `listCommits(workspaceId: string, input?: { limit?, before? }): Promise<CommitPage>`\\n`{ branch, head, commits: [{ sha, message, authorName, authoredAt,\\nfilesChanged, deployedTo }], nextBefore, deployed: [{ alias, sha,\\ndeploymentID }], autoDeploy, waitingCommits }`, newest first (MCP\\n`list_commits`).\\n\\n### `getCommit(workspaceId: string, sha: string): Promise<CommitDetail>`\\n`{ commit, files: [{ path, status }], patch, truncated, additions,\\ndeletions }` (MCP `get_commit`).\\n\\n### `restoreVersion(options: { workspaceId, sha, expectedHead?, commitMessage?, wait?, waitOptions? }): Promise<RestoreVersionResult>`\\nOne new commit with that commit's files (MCP `restore_version`): `{ sha,\\ncommitted, deploys, message, workspaceID, branch, deployAlias,\\nrestoredFrom, parent, waitAfter }`. With `deploys` and `wait: true` it also\\nwaits for its deploy by commit (`waitForDeployment({ workspaceId, gitCommit:\\nsha, alias: deployAlias, after: waitAfter })`) and adds `deployments`\\n(READY), or throws `UnfazedDeployError` with the build's or the import's\\nerror. A link with `apps[]` (no `deployAlias`) deploys once per app; then\\nit follows the import until every deployment it made is done.\\n\\n```ts\\nconst { commits } = await unfazed.listCommits(ws.id);\\nconst back = await unfazed.restoreVersion({ workspaceId: ws.id, sha: commits[1]!.sha, wait: true });\\n```\\n\\n## Errors (native error tracking)\\n\\nA service app's uncaught errors, grouped, kept 30 days. Titles, stacks and\\nrequests are what the app reported: untrusted text.\\n\\n### `listErrors(input: { workspaceId, alias, status?: \\\"open\\\" | \\\"resolved\\\" | \\\"muted\\\", limit?, cursor? }): Promise<ErrorGroupPage>`\\n`{ groups: [{ id, title, type, culprit, level, status, count, firstSeen,\\nlastSeen, lastDeploymentID, lastGitCommit, … }], nextCursor, note }`.\\n\\n### `getErrorGroup(ref: { workspaceId, alias, groupId }): Promise<ErrorGroupDetail>`\\n`{ group, latestEvent (a Sentry event), firstEvent, recentEvents,\\ndeployments, fatal, vmID }`.\\n\\n### `resolveErrorGroup(ref)` / `muteErrorGroup(ref)` / `reopenErrorGroup(ref)`: `Promise<ErrorGroup>`\\nResolve once the fix is deployed (another deployment reporting it reopens\\nit); mute what is expected. Only on your human's say-so.\\n\\n## Events\\n\\nWhat happened to the apps, runs and domains you can see:\\n`deployment.finished`, `service.crashed`, `error.new`, `error.regressed`,\\n`git.conflict`, `run.finished`, `domain.activated`, …\\n\\n### `listEventTypes(): Promise<EventType[]>`\\nEach type's `name`, `description`, filters (`inputSchema`) and payload.\\n\\n### `pollEvents(input?: { names?, arguments?, cursor?, max? }): Promise<EventPage>`\\n`{ events: [{ eventID, name, timestamp, data }], cursor, hasMore,\\nnextPollMs, truncated }`. Omit `cursor` to start from now; pass the returned\\none back.\\n\\n### `waitForEvents(input?: { names?, arguments?, cursor?, max?, timeoutMs? }): Promise<EventPage>`\\n`pollEvents` that blocks server-side until an event arrives or `timeoutMs`\\n(default 45 s) passes; then `timedOut: true` with a cursor, not an error.\\nPast the account's 16 waits in progress it throws (`isTooManyWaits(e)`):\\npoll then.\\n\\n```ts\\nlet page = await unfazed.pollEvents({ names: [\\\"deployment.finished\\\"], arguments: { \\\"deployment.finished\\\": { alias: \\\"api\\\" } } });\\n// … deploy …\\npage = await unfazed.waitForEvents({ names: [\\\"deployment.finished\\\"], cursor: page.cursor, timeoutMs: 120_000 });\\n```\\n\\n## Agent runs\\n\\n### `createRun(options: { workspaceId, prompt?, harness?, command?, setup?, verify?, access?, alias?, maxSeconds?, wait? }): Promise<Run>`\\nA one-shot agent run in a fresh VM. `wait: true` polls to SUCCEEDED,\\nFAILED or CANCELLED (all returned, never thrown).\\n\\n### `waitForRun(runId: string, waitOptions?: WaitOptions): Promise<Run>`\\n\\n### `getRun(runId)` / `listRuns(filter?: { workspaceId?, status?, limit?, offset? })` / `cancelRun(runId)`\\n\\n### `followUpRun(runId: string, options: { prompt, mode?, wait? }): Promise<Run>`\\n\\n### `answerRun(runId: string, answer: string): Promise<Run>`\\nAnswers a BLOCKED run's question.\\n\\n### `runEvents(runId)` / `runConsole(runId, { tailBytes? })` / `runTranscript(runId, { tailBytes? })`\\n\\n### `listRunHarnesses(): Promise<RunHarness[]>`\\n\\n## Workload identity\\n\\nOIDC tokens the platform issues to the app the code runs in (a service or a\\ncron job): short-lived JWTs for one audience, from the issuer\\n`https://unfazed.dev/oidc`, which a service that trusts it takes instead of\\nan API key. Claims include `sub`, `aud`, `owner_id`, `project_id`, `app_id`,\\n`alias`, `environment` and `deployment_id`. The only credential is the app's\\n`UNFZ_STATE_TOKEN`, set in each of its VMs: no API token, so a bare\\n`new Unfazed()` works in an app for this. Without an instance:\\n`import { oidc, oidcToken } from \\\"unfazed\\\"` (`oidcToken(audience)` is\\n`oidc.token(audience)`).\\n\\n### `oidc.token(audience: string, options?: { ttlSeconds?, signal? }): Promise<string>`\\nA JWT for `audience` (1 to 256 printable ASCII characters, no whitespace);\\n`ttlSeconds` from 60 to 3600, else the platform's default. Cached per\\n(audience, ttl) until 80% of its lifetime; concurrent calls share one\\nrequest. 503s, network failures and 429s (after their `Retry-After`) are\\nretried up to 3 times; if a refresh still fails that way, the previous token\\ncomes back while it is valid. Throws `UnfazedOIDCError` (`code`, `status`,\\n`description`, `retryable`, `retryAfterMs`): `not_in_app` (no\\n`UNFZ_STATE_TOKEN`), `invalid_audience`, `invalid_request`, `invalid_token`,\\n`rate_limited`, `oidc_disabled`, `temporarily_unavailable`, `unreachable`.\\n\\n```ts\\nconst jwt = await unfazed.oidc.token(\\\"https://api.example.com\\\", { ttlSeconds: 300 });\\nawait fetch(\\\"https://api.example.com/v1/things\\\", { headers: { Authorization: `Bearer ${jwt}` } });\\n```\\n\\n### `oidc.tokenResponse(audience: string, options?: { ttlSeconds?, signal? }): Promise<{ token, expiresAt: Date }>`\\n`oidc.token` with the token's expiry.\\n\\n### `oidc.fetchWithToken(audience: string, options?: { ttlSeconds?, fetch? }): fetch`\\nA `fetch` that sends each request with `Authorization: Bearer <token>`\\n(replacing one already there), everything else as given: for a client that\\ntakes a `fetch`. An invalid audience (an unset variable) throws at once.\\n\\n```ts\\nconst openai = new OpenAI({\\n baseURL: process.env.API_BASE_URL,\\n apiKey: \\\"unused\\\",\\n fetch: unfazed.oidc.fetchWithToken(process.env.API_AUDIENCE),\\n});\\n```\\n\\n## Anything else\\n\\n`unfazed.client` is the typed GraphQL transport over the same credential:\\n`await unfazed.client.query(document, variables)`. `operations` exports\\nevery document the SDK uses.\\n\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unfazed",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Official TypeScript SDK for unfazed. The code-mode companion to the unfazed MCP server: deploy, wait, tail logs and roll back from one script. `npx unfazed login` signs you in. Also ships the unfazed World for Workflow SDK (unfazed/workflow).",
|
|
3
|
+
"version": "0.10.1",
|
|
4
|
+
"description": "Official TypeScript SDK for unfazed. The code-mode companion to the unfazed MCP server: deploy, wait, tail logs and roll back from one script. `npx unfazed login` signs you in. Also ships the unfazed World for Workflow SDK (unfazed/workflow) and eve sandboxes on unfazed boxes (unfazed/eve-sandbox).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
"import": "./dist/workflow/nitro.js",
|
|
32
32
|
"default": "./dist/workflow/nitro.js"
|
|
33
33
|
},
|
|
34
|
+
"./eve-sandbox": {
|
|
35
|
+
"types": "./dist/eve-sandbox/index.d.ts",
|
|
36
|
+
"import": "./dist/eve-sandbox/index.js",
|
|
37
|
+
"default": "./dist/eve-sandbox/index.js"
|
|
38
|
+
},
|
|
34
39
|
"./package.json": "./package.json"
|
|
35
40
|
},
|
|
36
41
|
"files": [
|
|
@@ -99,7 +104,8 @@
|
|
|
99
104
|
"drizzle-orm": ">=0.45.2",
|
|
100
105
|
"nitro": ">=3.0.260610-beta",
|
|
101
106
|
"pg": "^8.20.0",
|
|
102
|
-
"workflow": "^5.2.0"
|
|
107
|
+
"workflow": "^5.2.0",
|
|
108
|
+
"eve": ">=0.90.0"
|
|
103
109
|
},
|
|
104
110
|
"peerDependenciesMeta": {
|
|
105
111
|
"@workflow/core": {
|
|
@@ -122,6 +128,9 @@
|
|
|
122
128
|
},
|
|
123
129
|
"workflow": {
|
|
124
130
|
"optional": true
|
|
131
|
+
},
|
|
132
|
+
"eve": {
|
|
133
|
+
"optional": true
|
|
125
134
|
}
|
|
126
135
|
},
|
|
127
136
|
"devDependencies": {
|
|
@@ -141,6 +150,7 @@
|
|
|
141
150
|
"pg": "8.20.0",
|
|
142
151
|
"typescript": "^6.0.3",
|
|
143
152
|
"vitest": "4.1.10",
|
|
144
|
-
"workflow": "5.2.2"
|
|
153
|
+
"workflow": "5.2.2",
|
|
154
|
+
"eve": "0.90.0"
|
|
145
155
|
}
|
|
146
156
|
}
|