|
| 1 | +# Process workflow fleet canvas |
| 2 | + |
| 3 | +This project-scoped Copilot canvas lets maintainers refresh the authenticated |
| 4 | +Process-PSModule caller inventory, inspect each repository against the v8 caller |
| 5 | +contract, and send a confirmed migration request to the active agent. The |
| 6 | +loopback server never edits another repository or opens a pull request. |
| 7 | + |
| 8 | +## Structure |
| 9 | + |
| 10 | +| File | Responsibility | |
| 11 | +| --- | --- | |
| 12 | +| `extension.mjs` | Declares the canvas, strict open/action schemas, lifecycle, and SDK wiring. | |
| 13 | +| `fleet-service.mjs` | Resolves the repository, stores workspace-scoped state, runs inventory refreshes, serves loopback HTTP, and calls `session.send()`. | |
| 14 | +| `fleet-model.mjs` | Normalizes inventory records, encodes the v8 target, computes deltas, and builds structured migration prompts. | |
| 15 | +| `renderer.mjs` | Returns the dependency-free dashboard HTML, CSS, and browser interactions. | |
| 16 | +| `fleet-model.test.mjs` | Tests normalization, comparison, fail-closed behavior, and prompt generation with built-in Node modules. | |
| 17 | + |
| 18 | +`extension.mjs` must remain an ES module with that exact name. Copilot resolves |
| 19 | +`@github/copilot-sdk` for the extension process, so this directory does not need |
| 20 | +a `package.json` or `node_modules`. |
| 21 | + |
| 22 | +## Load and open |
| 23 | + |
| 24 | +Copilot discovers immediate children of `.github/extensions/`. After changing |
| 25 | +the extension, reload project extensions and confirm |
| 26 | +`project:process-workflow-fleet` is running: |
| 27 | + |
| 28 | +```text |
| 29 | +extensions_reload({}) |
| 30 | +extensions_manage({ operation: "list" }) |
| 31 | +extensions_manage({ operation: "inspect", name: "process-workflow-fleet" }) |
| 32 | +``` |
| 33 | + |
| 34 | +Inspect the declaration, then open a stable panel instance: |
| 35 | + |
| 36 | +```text |
| 37 | +list_canvas_capabilities({ canvasId: "process-workflow-fleet" }) |
| 38 | +open_canvas({ |
| 39 | + canvasId: "process-workflow-fleet", |
| 40 | + instanceId: "process-workflow-fleet-main", |
| 41 | + input: { organization: "PSModule" } |
| 42 | +}) |
| 43 | +``` |
| 44 | + |
| 45 | +Reopening the same `instanceId` focuses the panel. Durable inventory and |
| 46 | +selection state is keyed by the repository workspace under the Copilot session |
| 47 | +`files/process-workflow-fleet/` artifact directory, not by the panel ID. |
| 48 | +Refreshed evidence is disposable user-specific state and is never committed |
| 49 | +automatically. |
| 50 | + |
| 51 | +## Use and test |
| 52 | + |
| 53 | +The dashboard refresh button runs |
| 54 | +`.github/scripts/Get-ProcessPSModuleWorkflowInventory.ps1` in authenticated |
| 55 | +GitHub mode with target `v8`. A failed refresh clears prior success state and |
| 56 | +shows the command context and sanitized diagnostic. |
| 57 | + |
| 58 | +Agent-facing actions are: |
| 59 | + |
| 60 | +- `refresh_inventory` |
| 61 | +- `get_summary` |
| 62 | +- `get_repository` |
| 63 | +- `set_selection` |
| 64 | +- `request_migration` |
| 65 | + |
| 66 | +`request_migration` returns a preview by default. It calls `session.send()` only |
| 67 | +when `dryRun` is `false`, `confirmed` is `true`, the selection is nonempty, and |
| 68 | +the current inventory is complete. |
| 69 | + |
| 70 | +Run deterministic helper tests with: |
| 71 | + |
| 72 | +```powershell |
| 73 | +node --test .github/extensions/process-workflow-fleet/fleet-model.test.mjs |
| 74 | +``` |
| 75 | + |
| 76 | +## Debug |
| 77 | + |
| 78 | +Start with `extensions_manage({ operation: "inspect", name: |
| 79 | +"process-workflow-fleet" })`. The reported log captures provider startup and |
| 80 | +runtime failures; do not add `console.log`, because standard output carries the |
| 81 | +JSON-RPC protocol. Use `session.log()` for deliberate diagnostics. |
| 82 | + |
| 83 | +For lifecycle and schema checks, reload before testing and verify: |
| 84 | + |
| 85 | +1. discovery and capabilities; |
| 86 | +2. valid and invalid open input; |
| 87 | +3. each declared action and invalid action input; |
| 88 | +4. reserved `canvas.*` action rejection; |
| 89 | +5. loopback rendering and panel cleanup. |
| 90 | + |
| 91 | +## Extend safely |
| 92 | + |
| 93 | +Keep the SDK declaration in `extension.mjs`, domain logic in |
| 94 | +`fleet-model.mjs`, privileged boundaries in `fleet-service.mjs`, and rendering |
| 95 | +in `renderer.mjs`. Add a strict JSON schema for every new agent action and a |
| 96 | +deterministic test for every comparison or prompt change. |
| 97 | + |
| 98 | +Bind HTTP only to `127.0.0.1`, require the per-panel request token for writes, |
| 99 | +and close the server in `onClose`. HTTP handlers may prepare evidence or |
| 100 | +requests, but repository mutations must stay in normal Copilot sessions where |
| 101 | +the user can see tool calls and permission prompts. Never include credentials |
| 102 | +in state, HTML, diagnostics, or migration requests. |
0 commit comments