Skip to main content

Custom Apps

Custom apps are full Vite/React/TypeScript projects hosted by Autessa. The CLI can pull an app's draft source to your machine, push edits back, and run a production deploy — which makes an Autessa app editable with whatever editor, diff tool, or coding agent you already use.

Key concepts​

Draft and published​

An app has a draft — the private working copy — and a published version, which is what end users actually reach. push writes to the draft. Nothing you push is live.

Publishing is a production deploy, not a save. It snapshots the draft, builds it, and once the build succeeds serves it to everyone with access — its public URL and any custom domains — replacing whatever was live before. Treat it as a deliberate step, not a reflex after every edit.

If you are driving the CLI from a coding agent, this is the rule to encode: stay in the draft unless the user explicitly asked to launch, ship, deploy or go live. See Coding agents.

What the file API covers​

pull and push handle text source files only. The read-only src/autessa/ library — the generated bindings an app uses to reach agents, tools and tables — is never returned by pull and cannot be pushed.

index.html is Vite's entry shell: a <div id="root"> and a module script tag. Page content belongs in the React files under src/. Overwriting index.html with static markup breaks the app.

autessa.config.json​

Every app carries a config file binding it to the platform resources it uses:

{
"version": "1.0.0",
"agents": { "TODO_MANAGER": "Lo59cuYy9d8T" },
"tools": {},
"tables": {
"TODO_LIST": "U49RQBUdAaRq",
"TODO_COMMENTS": "mcjl7XmDfKCI"
},
"managers": {},
"scheduledJobs": {}
}

This is the seam between an app and everything else you build headless. A script that creates a table and an agent can write their ids straight into this file and push it, and the app picks them up.

How to find an app​

autessa app all --output table
appId appName sharingLevel userAccessLevel hostingMode latestVersion publishedVersion
------------ ----------- ------------ --------------- ----------- ------------- ----------------
GTBhswTJ6a9r BasicTodo PRIVATE ADMIN DEFAULT 1 1
lCHdKACw4tpE BasicTodo PRIVATE ADMIN DEFAULT

An app with no publishedVersion has never been deployed — it exists only as a draft.

Get the URLs a human needs:

autessa app visible-urls --appId GTBhswTJ6a9r
{
"editorUrl": "https://builder.autessa.com/app-builder/editor/GTBhswTJ6a9r",
"publishedUrl": "https://builder.autessa.com/customappsv2/view/GTBhswTJ6a9r"
}

autessa app get returns full details plus the draft file listing; get-app-info is a lighter read that skips the file listing.

How to pull the source​

autessa app pull --appId GTBhswTJ6a9r

Returns a path→content map of the draft's editable files:

{
"files": {
"autessa.config.json": "{\n \"version\": \"1.0.0\", ... }",
"index.html": "<!DOCTYPE html>\n<html lang=\"en\"> ... ",
"package.json": "{\"private\":true,\"devDependencies\":{ ... }}",
"src/App.tsx": "...",
"src/components/ui/Button.tsx": "...",
"src/pages/Todos.tsx": "..."
}
}

Paging​

Large apps come back in pages. When nextPageToken is present, call pull again with it until it is absent:

autessa app pull --appId GTBhswTJ6a9r --pageToken <token>

A file larger than the transfer budget is reported in skipped rather than dropped silently — check that array, don't assume an empty response means an empty app.

Writing the files to disk​

pull returns JSON, so unpacking it is one jq step:

mkdir -p ./myapp && cd ./myapp

autessa app pull --appId GTBhswTJ6a9r \
| jq -r '.files | to_entries[] | @base64' \
| while read -r row; do
entry=$(echo "$row" | base64 --decode)
path=$(echo "$entry" | jq -r '.key')
mkdir -p "$(dirname "$path")"
echo "$entry" | jq -r '.value' > "$path"
done

Now edit with anything — your editor, a formatter, a coding agent, a codemod.

How to push edits back​

push takes the same path→content map:

autessa app push --appId GTBhswTJ6a9r --files '{
"src/pages/Todos.tsx": "import React from \"react\";\n\nexport default function Todos() {\n return <div>…</div>;\n}\n"
}'
{
"savedPaths": ["src/pages/Todos.tsx"],
"deletedPaths": []
}

Rebuild the map from a local directory:

FILES=$(find . -type f \
! -path './node_modules/*' ! -path './.git/*' ! -path './dist/*' ! -path './src/autessa/*' \
-print0 | xargs -0 jq -Rs 'input_filename as $f | {($f | ltrimstr("./")): .}' | jq -s 'add')

autessa app push --appId GTBhswTJ6a9r --files "$FILES"

Skip node_modules, .git, dist/build, lockfiles, src/autessa/, and any binary files — the file API is text-only.

Mirroring vs. adding​

By default push mirrors: draft files absent from your payload are deleted, so a partial push removes everything you left out. That is what you want when pushing a complete local tree.

--addOnly changes it to add-and-update, never delete:

autessa app push --appId GTBhswTJ6a9r --files '{"src/pages/Todos.tsx":"..."}' --addOnly

Use --addOnly for a targeted single-file edit. Use the default mirror when your local directory is the authoritative copy.

The response tells you exactly what happened — savedPaths, deletedPaths, and binaryContentPaths for anything containing NUL bytes (still saved, but worth a look).

How to publish​

Only when the app is genuinely meant to go live:

autessa app publish --appId GTBhswTJ6a9r

Publishing is asynchronous. It returns a publishJobId and a version and starts a build; the app is live only once that build reaches SUCCESS:

autessa app publish-status --publishJobId <id>

Poll while terminal is false, and watch phase. A FAILED build carries the error tail — fix the draft and publish again.

You can also publish as part of a push:

autessa app push --appId GTBhswTJ6a9r --files "$FILES" --publish

which returns version, buildId, publishJobId and buildStatus: BUILDING — still asynchronous, still needing publish-status.

Do not report an app as live until the build has actually succeeded. publish returning cleanly means the build started.

How to create, clone and roll back​

# start from a template
autessa app create --appName "My Site" --templateType SAAS_APP

# copy an existing app's draft into a new private app you own
autessa app clone --appId GTBhswTJ6a9r --appName "My Site (fork)"

# roll the DRAFT back to a previously published version's source
autessa app rollback --appId GTBhswTJ6a9r --version 1

# list versions with build status
autessa app versions --appId GTBhswTJ6a9r

Templates are BOOTSTRAP, SAAS_APP, LANDING_PAGE and DASHBOARD. Note what rollback does: it restores the draft from an old version's source. It does not itself change what is live — publish afterwards for that.

How to control access and domains​

autessa app get-sharing-details --appId GTBhswTJ6a9r

autessa app share --appId GTBhswTJ6a9r \
--sharingLevel COMPANY \
--companyPermissionLevel WRITE \
--hostingMode AUTH_CODE \
--publicSlug my-site \
--authCode s3cr3t

share configures two independent things in one ADMIN-only call: who can edit the source (code sharing), and how end users reach the deployed app (hosting mode). get-sharing-details is the read-only view of exactly what it would modify.

Custom domains:

autessa app check-slug --appId GTBhswTJ6a9r --publicSlug my-site
autessa app domains add --appId GTBhswTJ6a9r --domainName app.example.com
autessa app domains status --appId GTBhswTJ6a9r
autessa app domains verify --appId GTBhswTJ6a9r --domainId <domainId>
autessa app domains remove --appId GTBhswTJ6a9r --domainId <domainId>

domains add returns the CNAME — and, when required, the TXT verification record — the domain owner must create. domains status lists each domain's state, its CNAME target, the live URL once ACTIVE, and the TXT record while PENDING_TXT. domains verify runs one provisioning step synchronously instead of waiting for the next scheduled poll, and also resets a FAILED domain for retry.

What stays in the web builder​

The visual app builder — the workspace, the file tree UI, and the vibecode assistant — is a browser experience. The CLI covers the file round-trip and the lifecycle; it does not replace the editor. See App Builder and Vibecode.

Full command reference​

22 commands21 runnable1 in the web app
CommandWhat it does
autessa app allList every custom app you can access in the current company, each with its latest/published version numbers, hosting mode, slug, and your access level.
autessa app check-slugCheck whether a public URL slug is available and validly formatted, returning available and a reason.
autessa app cloneCreate a new private app you own by copying another app's draft source files.
autessa app createCreate a new custom web app from a starter template, scaffolding its draft files.
autessa app deletePermanently delete an app — its custom domains, all draft/version/build files, and database rows.
autessa app domains addAttach a customer-owned custom domain to an app and get back the CNAME (and possibly TXT verification) records the domain owner must create.
autessa app domains removeDetach a custom domain from an app and tear down its CDN tenant.
autessa app domains statusList an app's custom domains with status, CNAME target, live URL when ACTIVE, and the TXT verification record when PENDING_TXT.
autessa app domains verifySynchronously run one step of domain provisioning (DNS check, tenant creation, certificate attach) instead of waiting for the next scheduled poll; also resets a FAILED domain for retry.
autessa app getFetch one app's full details (versions, hosting mode, slug, public URL, your access level) plus its draft file listing.
autessa app get-app-infoFetch just an app's details (name, versions, hosting mode, slug, public URL, your access level) — a lighter read than get that does not return the draft file listing or refresh the library files.
autessa app get-sharing-detailsGet an app's sharing level, company permission, hosting mode, per-user grants, and your own access level — a read-only view of exactly what share would modify.
autessa app preview-urlWeb appApp preview URLs are opened from the app builder in the web app.
autessa app publishPublish the app — a PRODUCTION DEPLOY of all your draft changes, not a save.
autessa app publish-statusPoll the live progress of a publish job (from publish) until it finishes.
autessa app pullDownload an app's editable draft source files to sync a draft to a local folder, one page at a time.
autessa app pushSave files into an app's draft — the private working copy, one step below deploying to production.
autessa app rollbackRoll the app's editable DRAFT back to a previously published version's source.
autessa app shareConfigure two independent things about an app in one ADMIN-only call: who can EDIT its source (code sharing) and how END-USERS reach the deployed app (hosting).
autessa app updateUpdate an app's metadata — appName, description, and the public SEO fields.
autessa app versionsList all versions of an app, newest first, with each version's state, buildId, and live build status.
autessa app visible-urlsThe two URLs that matter for an app, composed in one call: editorUrl, where the owner opens it in the builder, and publishedUrl, the single live URL its end-users reach.