Appearance
Joiner CLI Reference
Use this skill as the concise command reference for poe-tiles. Prefer exact command examples over prose. If a command needs authentication, assume the user has run poe-tiles login; it does not require a Poe API key. API keys via --api-key, POE_API_KEY, or ~/.poe-tiles/poe-tiles-api-key are legacy alternatives.
Install and Upgrade
bash
poe-tiles --version
poe-tiles upgrade
poe-tiles upgrade --printOptions:
poe-tiles upgrade --print: print the equivalent install command without running it.
Global Options
bash
poe-tiles --help
poe-tiles --version
poe-tiles --json tiles list
poe-tiles --server http://localhost:8787 tiles list
poe-tiles --server http://localhost:8787 login
poe-tiles --api-key "$POE_API_KEY" tiles listOptions:
--json: output machine-readable JSON.--server <url>: override the server URL.POE_SERVER_URLis the environment-variable equivalent.--api-key <key>: legacy Poe API key override for API-backed commands.-V, --version: output the CLI version.-h, --help: display help.
Environment:
POE_TILES_SESSION_TOKEN: Joiner session token. Usually created bypoe-tiles loginin~/.poe-tiles/poe-tiles-session-token.~/.poe-tiles/poe-tiles-session-token: home-directory file containing exactly one Joiner session token.POE_API_KEY: legacy Poe API key. Explicit API keys still work via--api-key, this env var, or the local API key file.~/.poe-tiles/poe-tiles-api-key: legacy home-directory file containing exactly one raw Poe API key.POE_SERVER_URL: optional server URL override.
Local-only commands that do not need authentication to start: tiles init, doctor, skills install, upgrade.
Setup Doctor
bash
poe-tiles doctor
poe-tiles doctor --cwd ./my-app
poe-tiles --json doctor --cwd ./my-appUse doctor before build/publish in a generated activity workspace. It checks Bun, dependencies, .poe-tile.json, package scripts, and local publish auth. If auth is missing, run poe-tiles login; do not ask first-time creators to paste API keys into chat.
Auth Commands
bash
poe-tiles login
poe-tiles auth whoami
poe-tiles auth usage
poe-tiles auth points-history
poe-tiles auth logout
poe-tiles --json auth whoamiCommands:
login: open or print a browser approval URL and save a local CLI session.auth whoami: show the current authenticated user.auth usage: show point balance.auth points-history: show usage history.auth logout: end the current session.
Options:
poe-tiles login --remote: print a browser approval URL/code for opening in any browser, useful on SSH or remote machines.poe-tiles login --no-open: compatibility alias for printing the browser approval URL without opening a browser.poe-tiles login --open: force opening the browser approval URL in this machine's browser.poe-tiles login --device-label <label>: label the device shown in the approval UI.- Global
--jsonis useful for scripting.
Remix Command
remix
bash
poe-tiles remix app_123
poe-tiles remix myuser my-app
poe-tiles remix myuser/my-app --dir ./my-local-copyArguments:
<typeIdOrCreatorName>: app ID,userHandle/appHandle, or creator name when paired with[handle].[handle]: app handle when the first argument is a creator name.
After unpacking, remix makes the copy usable on its own:
- Rewrites the
poe-tiles-sdkdependency inpackage.jsonfrom a workspace reference to the published SDK tarball URL, sobun installresolves the SDK. - Installs the SDK skills (tile-creator, synced-store) into
.claude/skills/.
If the source carries other internal workspace dependencies (apps published from a monorepo sometimes do), remix leaves them intact and warns — they have no published package and bun install will fail until you remove or replace them.
Options:
--dir <path>: output directory for the unpacked source bundle. Defaults to the app handle. The directory must not already exist.--no-skills: skip installing the SDK skills into.claude/skills/.
Apps Commands
tiles init
bash
poe-tiles tiles init
poe-tiles tiles init my-app --template solidjs
poe-tiles tiles init my-game --template phaserjs --output-dir ./poe-tiles
poe-tiles tiles init my-app --template react --no-skills
poe-tiles tiles init my-app --template vanilla-js --no-blank
poe-tiles tiles init my-proto --template react --no-storeArguments:
[app-name]: app name, lowercase alphanumeric plus hyphens.
Options:
-t, --template <template>: one ofreact,vanilla-js,solidjs,preact,phaserjs.--workspace-sdk: resolvepoe-tiles-sdkthroughworkspace:*instead of the published tarball.--internal-mono-repo: configure an internal ai-app monorepo scaffold. Implies--workspace-sdk.--output-dir <path>: parent directory for the new app. Defaults to the current directory.--no-skills: skip copying SDK skills into.claude/skills/.--no-blank: keep the todo-list example instead of blanking generated app code.--no-store(experimental): scaffold without synced-store. Nosynced-store/,client.ts, backend entry, mutator test, or e2e tests; state is in memory only and the generated.poe-tile.jsonhas nosourceBundle. For throwaway prototypes.
tiles list
bash
poe-tiles tiles list
poe-tiles --json tiles list
poe-tiles --json tiles list | jq '.[].handle'Options:
- No command-specific options. Use global
--jsonfor scripting.
tiles get
bash
poe-tiles tiles get myuser/my-app
poe-tiles tiles get app_123
poe-tiles --json tiles get myuser/my-app | jq '.bundleUrl'Arguments:
<tileHandleOrId>: app ID oruserHandle/appHandle.
Options:
- No command-specific options.
tiles download-source
bash
poe-tiles tiles download-source myuser/my-app
poe-tiles tiles download-source app_123 --out ./source-bundle.tar.gzArguments:
<tileHandleOrId>: app ID oruserHandle/appHandle.
Options:
--out <path>: output path for the downloaded source bundle. Default:source-bundle.tar.gz.
tiles rename
bash
poe-tiles tiles rename myuser/old-handle new-handle
poe-tiles tiles rename app_123 new-handleArguments:
<tileHandleOrId>: app ID oruserHandle/appHandle.<newHandle>: new lowercase alphanumeric-plus-hyphens handle, unique per creator.
Options:
--use-poe-account: rename an app owned by the@poesystem account. Requires an allowlisted API key.
tiles channels
Show an activity's release channels — which version is live (what players run) vs staging (your latest publish), plus each channel's schema version. Owner only. Note: schema versions are not populated by the publish path yet, so the schema column currently shows as unknown/null for every channel.
bash
poe-tiles tiles channels myuser/my-app
poe-tiles --json tiles channels app_123Arguments:
<tileHandleOrId>: app ID oruserHandle/appHandle.
tiles set-channel / tiles delete-channel
Point a channel at a specific published version, or delete a custom channel. Owner only. Use these to pin staging (which otherwise auto-advances to your latest publish) to an older build, or to keep your own named test channels.
bash
poe-tiles tiles set-channel myuser/my-app staging 3 --no-auto-advance # pin staging to v3 (stops auto-advancing)
poe-tiles tiles set-channel myuser/my-app beta 5 # create/point a custom "beta" channel (manual)
poe-tiles tiles set-channel myuser/my-app beta 6 --auto-advance # make it follow the newest publish
poe-tiles tiles delete-channel myuser/my-app beta # remove a custom channelArguments:
<tileHandleOrId>: app ID oruserHandle/appHandle.<channel>: channel name — lowercase letters, digits, and hyphens.<versionNumber>(set-channel): the published version to point at.
Notes:
set-channelrefuseslive; the live channel moves only throughpublish --promote(which carries the schema-downgrade guard).liveandstagingare reserved and cannot be deleted.--auto-advancemakes the channel jump to the newest version on every publish (the built-instagingbehavior).--no-auto-advancepins it manually — needed to holdstagingon an old build, since omitting both flags preserves the channel's current setting (andstagingstarts auto-advancing). A brand-new custom channel starts manual.
tiles publish
A publish updates the staging channel, not live. Players keep running the live version until you promote — either with --promote on the publish, or a later --promote re-publish. Use tiles channels to see the current state. (An in-app promote UI on the activity's page is coming soon; the CLI is the way to promote today.)
bash
poe-tiles tiles publish # updates staging only (test before going live)
poe-tiles tiles publish --promote # publish AND make it live for everyone
poe-tiles tiles publish --handle my-app --dir ./dist
poe-tiles tiles publish
poe-tiles tiles publish --change-summary "Added touch controls and improved scoring."
# Inside a platform Edit session: preview normally, then finalize the original tile.
poe-tiles tiles publish --finalize-edit
poe-tiles tiles publish --finalize-edit --edit-handle renamed-tile
poe-tiles tiles publish --handle my-app --dir ./dist --display-name "My App" --short-description "A fast party game."
poe-tiles tiles publish --handle my-app --dir ./dist --source-bundle . --source-bundle-visibility owner_only
poe-tiles tiles publish --handle my-app --profile-picture ./assets/icon.png --long-description ./README.md
poe-tiles tiles publish --handle my-app --profile-picture="" --short-description="" --long-description=""Options:
--handle <handle>: app handle. Required unless.poe-tile.jsonprovides one.--dir <path>: directory containing app files andindex.html. Defaults to.poe-tile.jsonruntimeBundle.dir, ordist.--publish-as-poe: publish under the@poesystem account. Requires an allowlisted API key.--no-publish-as-poe: publish under the calling user (the default).--source-bundle <path>: source-code directory to upload alongside the runtime bundle. Requires--source-bundle-visibility.--source-bundle-visibility <vis>:owner_onlyorpublic.--source-bundle-ignore <path>: ignore file with extra source-bundle exclusion patterns.--profile-picture <pathOrUrl>: app icon. Local PNG/JPG/WEBP <=512 KB, or anhttps://URL. Empty string clears.--short-description <text>: one-line tagline <=140 chars. Empty string clears.--long-description <path>: markdown file <=16 KB. Empty string clears.--display-name <name>: human-friendly name <=80 chars. Empty string clears.--change-summary <text>: per-publish user-facing summary <=500 chars, included in Creator chat receipts.--promote: after publishing, immediately promote the new version tolivefor all players. The server promotes in-band under the same request identity that published, so--promotecomposes with--publish-as-poe(and the other publish-as identities) and the publish receipt is never lost. Without it, a publish only updatesstagingand you promote later with a--promotere-publish. Once publishes declare a schema version, rolling back across a schema-version bump will be refused (SCHEMA_DOWNGRADE_BLOCKED); that guard is inert today because schema versions are not emitted yet.--finalize-edit: inside a platform Edit session, publish the current project to the original activity instead of its unlisted preview. The server rejects this outside the matching Edit session.--edit-handle <handle>: with--finalize-edit, explicitly rename the original activity; otherwise its current handle is preserved.
Use the current schema v10 to set the config-only instancing field (there is no CLI flag for it):
json
{
"$schema": "https://poe-tiles-docs.pages.dev/schemas/poe-tile/v10.json",
"handle": "word-duel",
"instancing": "per-context"
}per-launch is the default. Omitting instancing on re-publish preserves the existing value; set "per-launch" explicitly to reset it.
Categories are assigned automatically by the platform. Do not submit a categories field. If a legacy .poe-tile.json contains it, delete the top-level field (including a null or empty value) and retry; keep other metadata intact.
Store Commands
Store commands use the authenticated user-router WebSocket. Each command accepts --timeout-ms <ms> where listed; default is 15000.
stores access
bash
poe-tiles stores access todo-store room-1
poe-tiles stores access todo-store room-1 --timeout-ms 30000Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.
Options:
--timeout-ms <ms>: WebSocket open and response timeout in milliseconds.
stores pull
bash
poe-tiles stores pull todo-store room-1 --after-version 0
poe-tiles stores pull todo-store room-1 --after-version 42 --target-local-bytes 2000000
poe-tiles --json stores pull todo-store room-1 --after-version 0 | jq '.patches'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.
Options:
--after-version <version>: only return patches after this store version. Default:0.--target-local-bytes <bytes>: target local data budget for the pull. Default:1000000.--timeout-ms <ms>: WebSocket open and response timeout in milliseconds.
stores schema
bash
poe-tiles stores schema todo-store room-1
poe-tiles --json stores schema todo-store room-1 | jq '.commands.mutators'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.
Options:
--timeout-ms <ms>: WebSocket open and response timeout in milliseconds.
stores get
bash
poe-tiles stores get todo-store room-1 todos todo-1
poe-tiles --json stores get todo-store room-1 todos todo-1 | jq '.value'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.<tableName>: table name visible to the authenticated user.<itemKey>: item key.
Options:
- No command-specific options. Global
--jsonis useful for scripting.
stores scan
bash
poe-tiles stores scan todo-store room-1 todos --limit 50
poe-tiles stores scan todo-store room-1 todos --sort-key-prefix active --limit 20
poe-tiles stores scan todo-store room-1 todos --cursor '{"itemKey":"todo-1","sortKey":"active"}' --limit 20
poe-tiles stores scan todo-store room-1 todos --cursor '$last' --reverse --limit 20
poe-tiles --json stores scan todo-store room-1 todos --limit 50 | jq '.items'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.<tableName>: table name visible to the authenticated user.
Options:
--sort-key-prefix <prefix>: only include sort keys with this prefix.--item-key-prefix <prefix>: only include item keys with this prefix.--cursor <cursor>: entry-key JSON cursor,$first, or$last.--limit <count>: maximum number of items to return.--reverse: scan in descending order.
stores action
bash
poe-tiles stores action todo-store room-1 countTodos
poe-tiles stores action todo-store room-1 summarize --input '{"status":"open"}'
poe-tiles stores action todo-store room-1 importPreview --input-file ./input.json
poe-tiles --json stores action todo-store room-1 countTodos | jq '.result'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.<actionName>: action name.
Options:
--input <json>: inline JSON input.--input-file <path>: read action input JSON from a file.
Omit both input options to pass {}. Pass at most one of --input or --input-file.
stores mutate
bash
poe-tiles stores mutate todo-store room-1 setTodo --input '{"id":"todo-1","text":"Buy milk"}'
poe-tiles stores mutate todo-store room-1 clearDone --input null
poe-tiles stores mutate todo-store room-1 importTodos --input-file ./input.json
poe-tiles --json stores mutate todo-store room-1 setTodo --input '{"id":"todo-1","text":"Buy milk"}' | jq '.version'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.<mutationName>: mutator name.
Options:
--input <json>: inline JSON input.--input-file <path>: read mutator input JSON from a file.--timeout-ms <ms>: WebSocket open and response timeout in milliseconds.
Pass exactly one of --input or --input-file.
store files upload
bash
poe-tiles store files upload touch-grass room-1 ./photo.jpg --content-type image/jpeg
poe-tiles --json store files upload touch-grass room-1 ./photo.jpg | jq '.fileId'Arguments:
<typeId>: store type ID.<instanceId>: store instance ID.<file>: local path to a non-empty file of at most 10 MiB.
Options:
--name <name>: display name; defaults to the local file's basename.--content-type <type>: receiver hint; the platform inspects the bytes authoritatively.
The authenticated user must be an active instance member, and the app must opt in with _requestUploadUrl. Claim the returned fileId in a fileRefs-declared field using store mutate; unclaimed uploads expire.
Model Commands
bash
poe-tiles models list
poe-tiles --json models list | jq '.[].id'Options:
- No command-specific options.
Account Commands
bash
poe-tiles accounts list
poe-tiles accounts unlink github
poe-tiles --json accounts listCommands:
accounts list: list linked OAuth accounts.accounts unlink <providerId>: unlink one connected account.
Arguments:
<providerId>: provider ID to unlink.
Options:
- No command-specific options.
Skills Commands
bash
poe-tiles skills install
poe-tiles skills install --dir .codex/skills
poe-tiles skills install --dir path/to/skillsOptions:
--dir <path>: target directory. Each skill is written as<dir>/<skill-name>/. Default:.claude/skills.
Install merges with existing skill directories: matching files are overwritten, and user-added files outside the bundle are preserved.
Scripting Patterns
bash
poe-tiles --json tiles list | jq '.[].handle'
poe-tiles --json auth points-history | jq '[.[] | .cost_points] | add'
poe-tiles --json stores schema todo-store room-1 | jq '.commands'
poe-tiles --server http://localhost:8787 --json tiles listWhen a user asks for a command's options, prefer poe-tiles <command> --help as the final source of truth if the installed CLI may differ from this skill.