GitHub Copilot App workflows (Experimental)
See the Targets matrix for where copilot-app fits alongside the other deploy targets.
What it does
Section titled “What it does”When copilot-app is enabled and a package ships a prompt with workflow frontmatter (any of interval, schedule_hour, schedule_day at the top level), apm install --target copilot-app inserts the prompt as a row in the GitHub Copilot desktop App’s SQLite store at ~/.copilot/data.db. Add --global to install from a user-scope ~/.apm/apm.yml, or omit it to install from a project’s apm.yml (typical for team-shared scheduled prompts). The App reads new rows on next launch (or refresh) and lists them under Workflows.
Prompts that do not carry workflow frontmatter are plain slash commands: they deploy to file-based targets (copilot, vscode, claude, …) and APM hard-errors with an actionable diagnostic if you point them at copilot-app directly. A single .prompt.md belongs to exactly ONE surface — whichever its frontmatter shape selects.
Why a new target
Section titled “Why a new target”The copilot target writes prompts as files (.github/prompts/<name>.prompt.md) for Copilot in IDEs. The desktop App stores workflows in a SQLite database, not on disk. They are different surfaces; copilot-app exists so that one APM install can serve both without leakage.
Authoring a workflow prompt
Section titled “Authoring a workflow prompt”Add workflow frontmatter (flat top-level keys) to any .prompt.md file in your package’s .apm/prompts/ folder:
---name: Daily Digestinterval: daily # one of: manual, hourly, daily, weeklyschedule_hour: 9 # 0-23, UTC; ignored for manual / hourlyschedule_day: 1 # 0-6 (weekly only)mode: interactive # one of: interactive, planmodel: claude-opus-4.7 # optionalreasoning_effort: high # optional---
Summarise yesterday's commits across all open PRs ...Manual-only workflows omit schedule_hour / schedule_day and set
interval: manual (the default when any other execution-shape key is
present). The Copilot App provides a “run now” affordance for every
workflow, so manual-only is a useful shape — no schedule, just a
named, parameterised prompt the user can fire from the App UI.
The Copilot App also defines an autopilot mode, but APM intentionally
does NOT accept it via this target. Until package signing ships, a
third-party package could declare mode: autopilot and have the App
auto-run the prompt the moment you flip the in-App enable toggle.
Refusing autopilot at the writer is the secure-by-default behaviour;
you can still set autopilot yourself on a per-row basis from the App
UI after install.
Lifecycle
Section titled “Lifecycle”apm action | Effect on ~/.copilot/data.db |
|---|---|
apm install | INSERT row with enabled = 0 (always disabled on install — you opt in). |
apm install (already installed, content unchanged) | UPDATE display fields only. enabled, last_run_at, next_run_at are preserved. |
apm install (already installed, any execution-affecting field changed) | UPDATE row; reset enabled = 0; clear next_run_at. |
apm uninstall | DELETE only APM-namespaced rows (apm--<owner>--<pkg>--<prompt>). User-authored rows are never touched. |
Execution-affecting fields are the prompt body, schedule (interval / schedule_hour / schedule_day), mode, model, and reasoning_effort. The reset is by design: you opted in to a specific prompt, so any change to what runs or when is a new consent surface.
Removing the source .prompt.md from a package and re-syncing drops the lockfile entry but does NOT delete the corresponding row from ~/.copilot/data.db — it merely orphans it. Run apm uninstall <pkg> to remove the row.
Project scoping
Section titled “Project scoping”Workflows are scoped to a real Copilot App project so “Run now” in the Workflows tab CWDs into the right repository and the row groups under the correct sidebar entry. APM resolves the project once per install, then stamps every workflow row’s project_id.
Two resolution paths run in this order:
| Order | When it fires | What it does |
|---|---|---|
| 1 | The Copilot App is running and is reachable on its loopback WebSocket (~/.copilot/run/ws.{port,token}, 0o600). | APM calls the App’s own create_project_from_path over IPC. The App runs full discovery (GitHub owner/repo detection, default branch, account binding) and the resulting project is immediately known to the webview, so opening the Workflows tab cannot hit the white-screen-on-unknown-project failure mode. |
| 2 | The Copilot App is closed, OR the WebSocket surface is unreachable for any reason (stale token after restart, etc). | APM falls back to a direct-SQLite BEGIN IMMEDIATE resolver: SELECT by main_repo_path (UNIQUE), INSERT if missing. |
In both paths the workflow rows are written via direct SQLite — the WS surface is currently project-registration only — so lockfile ids stay namespaced and stable (apm--<owner>--<pkg>--<prompt>) across runs and across the WS-vs-SQLite branch.
If APM cannot derive a repo context at all (no .git/, no origin, etc) the workflows install with project_id = NULL. You can attach them to any project after the fact from the App’s Workflows tab.
One-time restart hint
Section titled “One-time restart hint”The first time APM registers a brand-new project for a given repository, install prints:
[i] Registered a new Copilot App project for this repo. Restart the Copilot App once so the new project appears in the UI (see github/github-app#5483).Subsequent installs into the same repo are silent. The hint is upstream-bug guidance: the App’s webview does not currently refresh its projects sidebar when a new projects row appears mid-session, so one restart wires the new project into the UI. Once the App learns about the project, neither the install nor the App needs to be restarted again.
--global and workflow-shape prompts
Section titled “--global and workflow-shape prompts”Workflows installed with apm install --global run with CWD=~/.copilot, not a repository — which is almost never what the user wants. APM still deploys global workflows (so global skills and commands keep working), but emits a one-time warn-and-proceed diagnostic whenever a --global install carries any workflow-shape prompt:
[!] Copilot App workflows installed with --global run with CWD=~/.copilot, not a project. Attach the workflow to a project from the App's Workflows tab to fix this, or re-run `apm install` from a repo without --global.The remediation is per-row: attach the workflow to any project from the Workflows tab in the App. Or re-run apm install from inside a repo without --global.
Enable and check
Section titled “Enable and check”Use apm experimental enable copilot-app to turn the target on, apm experimental list to see all flags, and apm experimental disable copilot-app to turn it off again. See the Experimental flags reference for the complete subcommand surface.
Database resolution
Section titled “Database resolution”| Order | Source |
|---|---|
| 1 | APM_COPILOT_APP_DB environment variable (absolute path; used as-is). |
| 2 | ~/.copilot/data.db if it exists. |
If neither resolves, the install fails with [x] GitHub Copilot desktop App not detected. Expected ~/.copilot/data.db ... and the command exits 1.
”Auth” model
Section titled “”Auth” model”There is none. The DB file is local; access is governed by your filesystem permissions. APM never sends credentials or syncs the DB anywhere. Treat the DB as user-scope state.
Schema compatibility
Section titled “Schema compatibility”APM guards writes with PRAGMA user_version and accepts the closed range [13, 13] today. If the App ships a newer schema, APM refuses to write and asks you to update APM rather than risk corruption.
Concurrency
Section titled “Concurrency”The Copilot App owns the DB and keeps it in WAL mode while running. APM coexists with the App’s writer connection by issuing BEGIN IMMEDIATE with a bounded retry; if a lock cannot be acquired after the retry window, the install fails with a [!] warning noting that the Copilot App DB stayed locked and asking you to close the GitHub Copilot app momentarily and retry.
Lockfile entries
Section titled “Lockfile entries”Deployed rows are tracked in the project / user lockfile under the copilot-app-db://workflows/<namespaced-id> URI scheme. Standard sync semantics apply: lockfile drift triggers redeploy; removal from lockfile triggers row delete on next install.
Out of scope (today)
Section titled “Out of scope (today)”- Package signing (would unlock additional trust-gated capabilities such as
mode: autopilot). - Scheduled-execution-on-install (deliberately not implemented — first-run is always manual).
gh-awouter-loop target (separate roadmap).