- name
- edit-app
- description
- Use when the user wants to iterate on an existing generated Power Apps mobile app after /create-mobile-app: update Application Insights configuration, the plan, data model, native capabilities, design, screens, generated app code, and preview without restarting the full project flow. Natural-language triggers include 'the app already exists', 'edit my app', 'change this screen', and 'add a feature to this app'.
- user-invocable
- true
- allowed-tools
- Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion, Task, Skill
- model
- opus
> **Plugin check**: Run `node "${PLUGIN_ROOT}/scripts/check-version.js"` - if it outputs a message, show it to the user before proceeding.
**Shared instructions: [shared-instructions.md](../../shared/shared-instructions.md)** — read first.
# Edit App (`/edit-app`)
Post-generation editor for an existing mobile app. `native-app-plan.md` remains the source of truth, but the default outcome is a fixed generated app, not a plan-only diff. After the user approves the plan delta, continue into Dataverse/native/design/screen mutations, run verification, update `memory-bank.md`, and regenerate the static preview when UI changed.
Use `--plan-only` only when the user explicitly asks to update planning docs without changing app code. Normal follow-up prompts in Copilot Chat Agent mode should apply the app change end to end.
## Edit documentation protocol
Keep two HTML files current during every edit:
- `<edit-temp-dir>/edit-app-progress.html` shows the live operation checklist.
- `docs/create-app-plan.html` remains the living description of the app.
Both are best-effort documentation. A rendering failure does not authorize a mutation, cancel an
approval gate, or turn a failed verification into success.
### Progress page
As soon as Step 0 resolves `working_dir`, before inferred-plan sync or the first progress write, ask
`app-docs.js` for a namespaced directory inside the user's OS temp directory:
```bash
node "${PLUGIN_ROOT}/scripts/app-docs.js" --working-dir '<working_dir>' temp
```
Use the returned `directory`, `progress`, `progressHtml`, and `sync` paths for the rest of the
run. Do not create progress files inside the project. Create `<edit-temp-dir>/edit-app-progress.json`
with one row per operation this edit will run.
Use stable IDs such as `inspect`, `impact`, `plan`, `approve`, `save-plan`, `data`, `native`,
`design`, `screens`, `verify`, `preview`, and `sync-plan`. Omit operations that do not apply.
Each row has `id`, `label`, `status` (`pending`, `active`, `waiting`, `done`, `skipped`, or
`failed`), and an optional `note`.
Add a top-level `changes` array for the Changes tab.
Keep it empty during initial inspection.
After Step 2, every entry requires `kind`, `title`, `rationale`, and optional `detail`.
Use `kind: general` for text-only changes.
Use structured diagram data for data-model and screen changes:
```json
{
"changes": [
{
"kind": "data-model",
"title": "Add inspection evidence",
"detail": "Create a child table for photos and signatures.",
"rationale": "One inspection can have several evidence records with independent metadata.",
"dataModel": {
"tables": [
{
"name": "Inspection",
"columns": [{ "name": "inspectionid", "type": "guid", "primaryKey": true }]
},
{
"name": "Evidence",
"columns": [
{ "name": "evidenceid", "type": "guid", "primaryKey": true },
{ "name": "inspectionid", "type": "guid", "foreignKey": true }
]
}
],
"relationships": [
{
"from": "Inspection",
"to": "Evidence",
"cardinality": "one-to-many",
"label": "contains"
}
]
}
},
{
"kind": "screen",
"title": "Add inspection detail",
"detail": "Add a route that shows findings and evidence.",
"rationale": "Inspectors need a focused review surface before updating a record.",
"screenGraph": {
"screens": [
{ "id": "list", "name": "Inspections", "route": "/inspections" },
{ "id": "detail", "name": "Inspection detail", "route": "/inspections/[id]" }
],
"edges": [
{ "from": "list", "to": "detail", "label": "Select inspection" }
]
}
}
]
}
```
Derive data-model tables, columns, and relationships from the validated schema proposal.
Derive screen nodes and edges from the updated Screen Map and Navigation Contracts.
When multiple screens are shown, include every navigation edge needed to explain how the user moves
between them.
Do not hand-author Mermaid source in the payload.
`app-docs.js` derives and renders the ER diagram or screen graph from the structured data.
Retain the approved wording, rationale, and graph data through implementation and verification.
Rewrite that JSON at every numbered step boundary and run:
```bash
node "${PLUGIN_ROOT}/scripts/app-docs.js" --working-dir '<working_dir>' progress \
--json-file '<edit-temp-dir>/edit-app-progress.json'
```
Every progress payload is a complete snapshot, not a patch.
Carry every operation row forward and update all rows whose state changed before publishing.
When the top-level phase advances, no row from an earlier phase may remain `active` or `waiting`.
In particular, an approval wait must show inspection and planning as complete and the approval row
as `waiting`.
The top-level object also carries `phase`, `status`, `note`, `waiting`, and
`devicePreviewReady`. Set the current row to `waiting` and `waiting: true` before every user
question. Set completed rows to `done`; do not leave the first row active for the whole run. On
failure, mark the failed row and top-level status `failed`. The page keeps a phone preview on the
right while work is active. Keep `devicePreviewReady: false` until this edit's Step 8 phone command
succeeds. Then set it to `true` in the final progress write, mark every applicable row settled, and
set top-level status `done`. A QR left by an earlier run is never current-run preview evidence.
Every branch that ends the workflow must publish a terminal progress write. Preserve the operation's
actual result, mark completed rows `done` or `failed`, mark rows that will not run `skipped`, clear
`waiting`, and set the top-level status to `done` or `failed`.
Open `<edit-temp-dir>/edit-app-progress.html` once after the first write using the host's file
opener. If no opener is available, print the absolute path. The page refreshes itself while work
is active.
### Living app plan
`app-docs.js sync` accepts a structured snapshot, not a prose summary:
```json
{
"appName": "Field inspections",
"dataPlatform": "dataverse",
"inferred": false,
"summary": "Added inspection detail and evidence capture.",
"sections": {
"requirements": {},
"architecture": { "dataPlatform": "dataverse", "nativeCapabilities": [], "connectors": [] },
"dataModel": { "tables": [] },
"screens": { "navigation": "", "list": [] },
"design": {},
"offline": {},
"trust": {}
},
"sectionStates": { "screens": "approved" }
}
```
For an existing plan, include every section this edit changed and omit unchanged sections. Serialize
the complete current section after implementation; the sync command replaces that section so
removed screens, connectors, capabilities, and tables do not survive as stale rows. Build values
from the verified app and its durable plan, not from the pre-approval proposal.
Write the payload to `<edit-temp-dir>/app-plan-sync.json`, then run:
```bash
node "${PLUGIN_ROOT}/scripts/app-docs.js" --working-dir '<working_dir>' sync \
--json-file '<edit-temp-dir>/app-plan-sync.json'
```
If `docs/.run-plan.json` is missing, the payload must cover every section that can be derived from
the app: routes and layouts for `screens`, generated models/services and the manifest for
`dataModel`, `power.config.json` plus generated registrations for connectors, `src/native/` and
template dependencies for native capabilities, and brand/token files for `design`. Mark this first
snapshot `inferred: true` and use the note `Plan inferred from existing app state because no prior
create-run plan was present.` Unknown facts stay explicitly unknown; do not guess.
Update `docs/create-app-plan.html` in the background. Do not open or focus it during `/edit-app`.
Run the sync command after an inferred baseline is created, after approved plan sections are saved,
and again after Step 8 verification so the page ends on the app's actual current state. Tell the
user when the living app plan has been updated to reflect the latest verified changes.
## When to use
- "Improve the search screen to make it easier to use on mobile"
- "Add loading, empty, and error states to the list screen"
- "Add a detail screen for the selected record"
- "Update the design to better match the company branding"
- "Add a form to create a new record in Dataverse"
- "Add barcode scanning and use the scanned value to search records"
- "Generate a new static preview of the updated app"
- "Add a `case` table to the data model"
- "Replace the Drawer navigation with Tabs"
- "Add `expo-camera` to the native capabilities"
- "Add signature capture to approvals and store it in Dataverse"
- "Generate an evidence PDF and retain it on the inspection record"
- "Add a View PDF action for an HTTPS report URL"
- "Reorder screens — move profile out of tabs, into a modal from the home header"
- "Enable Application Insights for this app"
- "Change the Application Insights resource used by this app"
- "Disable Application Insights for this app"
## When NOT to use
- Brand-new project → `/create-mobile-app`
- Explicit implementation-only request → the matching leaf skill under
[app-edit-routing.md](../../shared/references/app-edit-routing.md); do not infer
this from a short request or the absence of screen details.
- No recognizable generated app root (`package.json` plus `app/`) → stop and ask for the app
directory. A missing plan by itself is handled by the inferred-baseline path below.
## Workflow
This skill owns direct feature requests forwarded by native, connector,
data-model, and design entry points. Reuse the forwarded original request,
arguments, and answers; do not ask the user to repeat them.
Those entry points ask permission before invoking this full workflow. Reuse
`entry_choice: full-integration` for the current request without repeating the
mode question. A direct `/edit-app` invocation also needs no entry-choice menu.
Neither authorizes mutations: keep the impact/plan gates below. Approved child
calls skip the entry question and return here; do not create a recursive menu.
For each child skill invocation, explicitly pass the
[app-edit-routing.md](../../shared/references/app-edit-routing.md) context:
`MOBILE_APP_ORCHESTRATING=1`, `orchestrator: edit-app`, `working_dir`, `phase`,
and `approved_scope`. Planning uses read-only proposals; Step 5 implementation
uses the scope approved in Step 3 and saved in Step 4. The marker is not approval
and must not be persisted or relied on via a previous shell export.
0. Locate app + health/drift probe → 0.5 Application Insights fast path when applicable → 1. Discover intent + inspect existing app → 1.5 Impact preview → 2. Re-plan affected sections → 3. Gate intent, plan + mutation preview → 4. Write plan diff → 5. Apply additions/refreshes → 6. Rebuild affected screens → 6.5 Unregister approved retired sources → 7. Verify + quality sweep → 8. Preview + memory-bank update + optional debug handoff
---
## Edit Quality Gate Policy — no quality compromise
This is a focused edit workflow, not a lighter quality bar. Reuse `/create-mobile-app` gates at edit scale.
**Required gates by edit type:**
| Edit touches | Required gates |
|---|---|
| Any source file | Existing-app health gate, final `npx --no-install tsc --noEmit` |
| Dataverse/schema/connector | Environment drift gate, data-source/schema gate, Generated Services snapshot refresh, final `tsc` |
| Navigation/routes | Navigation/layout gate, route contract check, final `tsc` |
| New screen | Shared scaffold gate, skeleton gate, screen-builder wave gate, style-quality sweep, route check, final `tsc` |
| Existing screen TSX | Screen edit gate, style-quality sweep, route check when navigation changed, final `tsc` |
| Native capability | Native allowlist gate, wrapper existence gate, final `tsc` |
| Pure-JavaScript dependency | Approved exact-version dependency table, package-content gate, package validation, final `tsc` |
| Design/component/density | Design-system gate, affected-screen style sweep, final `tsc`, preview |
| Application Insights configuration only | Valid `app.json`, provider `appConfig` wiring, final `tsc` only if `app/_layout.tsx` changed |
**When a gate fails:** capture full output once, classify by root cause, repair in a batch, rerun the same gate once. Do not make line-by-line fixes with `tsc` after every tiny edit. Continue only when the gate is clean or record a `BLOCKED:` / `DONE_WITH_CONCERNS:` entry in `memory-bank.md`.
**Hard stops:**
- Do not run data-source mutations if the app root/environment cannot be identified.
- Do not launch screen-builders from broken generated services, route layouts, shared code, or skeletons.
- Do not import native wrappers in screens before `/add-native` has generated them.
- Do not hide unsupported native capabilities behind mocks or TODOs just to satisfy TypeScript.
- Do not mark an edit successful if changed screens fail TypeScript, route contracts, or required validators.
### Step 0 — Locate app + health/drift probe
**Telemetry checkpoint: `assess_app_health_and_drift`**
Before any project read or command, execute
[app-working-directory.md](${PLUGIN_ROOT}/shared/references/app-working-directory.md).
Resolve the absolute `working_dir` once, bind every shell call to it with the
fail-closed guard, and use absolute paths for file tools. Forward that same root
to every data child; a previous `cd` or inherited launch cwd is not a handoff.
Immediately run the edit documentation protocol's `temp` command and bind its returned
`directory`, `progress`, `progressHtml`, and `sync` paths as `<edit-temp-dir>` values before any
inferred-plan sync or progress write below.
```bash
cd -- '<working_dir>' || { echo "BLOCKED: cannot enter working_dir" >&2; exit 1; }
test -f native-app-plan.md && echo "OK: plan found" || echo "INFO: plan will be inferred"
test -f package.json && echo "OK: package found" || echo "ERROR: no package"
test -d app && echo "OK: app routes found" || echo "ERROR: no app routes"
test -f memory-bank.md && echo "OK: memory bank found" || echo "WARN: no memory bank"
git status --short
```
If `package.json` or `app/` is missing, STOP because this is not a recognizable generated app.
If `native-app-plan.md` is missing, inspect the current app before asking edit questions. Build an
inferred current-state baseline from routes/layouts, `power.config.json`, generated
models/services, `.datamodel-manifest.json`, `src/native/`, package dependencies, brand/token
files, and `memory-bank.md` when present. Write `native-app-plan.md` with every evidenced section,
label it `Inferred current-state baseline`, and mark unresolved facts as unknown. Do not run
`/create-mobile-app`, invent missing business intent, or treat inference as mutation approval.
Create `<edit-temp-dir>/app-plan-sync.json` from the same evidence and run the `sync` command so imported apps
receive `docs/create-app-plan.html` before planning begins.
Create the edit progress payload now with `inspect: active`, run the `progress` command, and open
`<edit-temp-dir>/edit-app-progress.html`.
Read if present:
- `memory-bank.md` — project facts, target environment, visual companion flag, prior blocks
- `.datamodel-manifest.json` — existing Dataverse tables/columns
- `brand/design-system.md` and `brand/tokens.ts` — design constraints and token availability
- `src/generated/services/*.ts` and `src/generated/models/*.ts` — generated data surface
Run these existing-app health checks before any mutation:
This is an inspection-only gate. Include required scaffold/provider/service
repairs in the proposed mutation scope; do not apply them before Step 3 approval.
`--plan-only` never authorizes these repairs or any other app/cloud mutation.
| Check | Action if unhealthy |
|---|---|
| `memory-bank.md` exists and has expected headings | If missing/corrupt, ask whether to proceed with reduced resume safety; create/update only after approval |
| `power.config.json`, `.resolved-environment.json`, and memory bank env agree | For data-source/schema edits, STOP until the user confirms the intended environment |
Ver en GitHub