@yemi33/minions 0.1.2447 → 0.1.2449
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli-api-client.js +1 -1
- package/bin/install-internal-minions.js +1382 -44
- package/bin/install-layout.js +150 -0
- package/bin/minions.js +460 -167
- package/dashboard/docs/typography.md +65 -12
- package/dashboard/js/command-center.js +66 -7
- package/dashboard/js/detail-panel.js +36 -0
- package/dashboard/js/memory-panel.js +59 -12
- package/dashboard/js/qa.js +186 -45
- package/dashboard/js/refresh.js +148 -12
- package/dashboard/js/render-dispatch.js +3 -4
- package/dashboard/js/render-inbox.js +2 -2
- package/dashboard/js/render-other.js +3 -3
- package/dashboard/js/render-pipelines.js +14 -0
- package/dashboard/js/render-plans.js +57 -9
- package/dashboard/js/render-prd.js +132 -23
- package/dashboard/js/render-prs.js +195 -166
- package/dashboard/js/render-schedules.js +63 -3
- package/dashboard/js/render-utils.js +3 -3
- package/dashboard/js/render-watches.js +19 -3
- package/dashboard/js/render-work-items.js +238 -30
- package/dashboard/js/settings.js +205 -54
- package/dashboard/js/utils.js +51 -1
- package/dashboard/pages/home.html +1 -1
- package/dashboard/pages/qa.html +1 -16
- package/dashboard/pages/work.html +40 -0
- package/dashboard/shared/cc-limits.js +79 -0
- package/dashboard/shared/pr-filters.js +21 -38
- package/dashboard/shared/project-git-summary.js +1 -1
- package/dashboard/shared/record-filters.js +169 -0
- package/dashboard/shared/watches-source.js +1 -1
- package/dashboard/shared/welcome-popup.js +1 -1
- package/dashboard/shared/wi-filters.js +302 -0
- package/dashboard/slim/body.html +1 -0
- package/dashboard/slim/js/command-send.js +26 -0
- package/dashboard/slim/js/modals-tiles.js +380 -39
- package/dashboard/slim/js/status.js +13 -21
- package/dashboard/slim/layout.html +1 -0
- package/dashboard/slim/panel-bootstrap.js +6 -2
- package/dashboard/slim/styles.css +38 -0
- package/dashboard/styles.css +159 -55
- package/dashboard-build.js +52 -6
- package/dashboard.js +956 -423
- package/docs/README.md +11 -6
- package/docs/api-errors.md +2 -2
- package/docs/architecture-review-2026-07-09.md +1 -1
- package/docs/architecture.excalidraw +2 -2
- package/docs/auto-discovery.md +18 -9
- package/docs/branch-derivation.md +4 -4
- package/docs/capture-demos.js +39 -2
- package/docs/ci-runner-canary.md +123 -0
- package/docs/claude-md-propagation.md +2 -2
- package/docs/cloud-agent-dispatch.md +204 -0
- package/docs/command-center.md +7 -7
- package/docs/completion-reports.md +43 -20
- package/docs/constants.md +10 -3
- package/docs/constellation-bridge.md +134 -6
- package/docs/constellation-style-telemetry.md +4 -4
- package/docs/contracts/capability-protocol.v1.json +165 -0
- package/docs/cooldown-merge-semantics.md +12 -12
- package/docs/copilot-cli-schema.md +7 -7
- package/docs/cross-repo-plans.md +10 -10
- package/docs/dead-code-audit-retractions.md +5 -5
- package/docs/default-branch-ci.md +173 -0
- package/docs/deprecated.json +31 -31
- package/docs/design-inbox-entries-schema.md +3 -3
- package/docs/design-language.md +1051 -0
- package/docs/design-state-storage.md +11 -11
- package/docs/diagnostics-crash-reports.md +9 -9
- package/docs/diagnostics-memory.md +5 -5
- package/docs/documentation-audit-2026-07-09.md +7 -7
- package/docs/engine-restart.md +90 -5
- package/docs/harness-mode.md +1 -1
- package/docs/internal-install.md +338 -39
- package/docs/kb-dedup-duplicate-pair-investigation.md +5 -5
- package/docs/kb-pr3223-cascade-archiving.md +1 -1
- package/docs/kb-pr696-merge-conflict-docs.md +6 -6
- package/docs/kb-sweep.md +35 -35
- package/docs/keep-processes.md +1 -1
- package/docs/live-checkout-mode.md +30 -30
- package/docs/managed-spawn.md +18 -14
- package/docs/named-agents.md +7 -7
- package/docs/plan-lifecycle.md +69 -2
- package/docs/pr-author-identity.md +114 -0
- package/docs/pr-auto-fix-dispatch.md +19 -4
- package/docs/pr-comment-followup.md +6 -6
- package/docs/pr-review-fix-loop.md +59 -10
- package/docs/process-termination.md +40 -0
- package/docs/proposals/repo-pool-for-live-checkout.md +13 -13
- package/docs/qa-runbook-lifecycle.md +367 -17
- package/docs/qa-runbooks.md +3 -3
- package/docs/rfc-completion-json.md +18 -18
- package/docs/runtime-adapters.md +26 -21
- package/docs/security.md +6 -6
- package/docs/self-improvement.md +4 -4
- package/docs/shared-lifecycle-module-map.md +473 -472
- package/docs/skills.md +52 -3
- package/docs/slim-ux/concepts.md +121 -116
- package/docs/specs/agent-configurability.md +18 -18
- package/docs/specs/agent-rename.md +18 -18
- package/docs/team-memory.md +38 -21
- package/docs/timeouts-and-liveness.md +118 -10
- package/docs/tutorials/01-install-and-connect.md +1 -1
- package/docs/watches.md +40 -39
- package/docs/workspace-manifests.md +4 -4
- package/docs/worktree-lifecycle.md +293 -14
- package/engine/README.md +46 -0
- package/engine/{ado-comment.js → ado/comment.js} +8 -8
- package/engine/{ado-git-auth.js → ado/git-auth.js} +4 -4
- package/engine/{ado.js → ado/index.js} +417 -63
- package/engine/{ado-status.js → ado/status.js} +6 -8
- package/engine/{ado-token.js → ado/token.js} +1 -1
- package/engine/{acp-transport.js → agents/acp-transport.js} +62 -22
- package/engine/{agent-worker-pool.js → agents/agent-worker-pool.js} +17 -8
- package/engine/{cc-worker-pool.js → agents/cc-worker-pool.js} +16 -6
- package/engine/{claude-md-context.js → agents/claude-md-context.js} +5 -5
- package/engine/{harness-context.js → agents/harness-context.js} +5 -5
- package/engine/{harness.js → agents/harness.js} +3 -3
- package/engine/{llm.js → agents/llm.js} +18 -14
- package/engine/{model-discovery.js → agents/model-discovery.js} +2 -2
- package/engine/{playbook.js → agents/playbook.js} +155 -22
- package/engine/{pooled-agent-process.js → agents/pooled-agent-process.js} +14 -12
- package/engine/{preflight.js → agents/preflight.js} +29 -10
- package/engine/{spawn-agent.js → agents/spawn-agent.js} +25 -14
- package/engine/{spawn-phase-watchdog.js → agents/spawn-phase-watchdog.js} +16 -7
- package/engine/{steering.js → agents/steering.js} +5 -5
- package/engine/{tools-inventory.js → agents/tools-inventory.js} +2 -2
- package/engine/{agent-api-validation.js → api/agent-api-validation.js} +2 -2
- package/engine/{api-validation.js → api/api-validation.js} +1 -1
- package/engine/api/bridge.js +787 -0
- package/engine/{cc-api-validation.js → api/cc-api-validation.js} +1 -1
- package/engine/api/companion.js +560 -0
- package/engine/{content-api-validation.js → api/content-api-validation.js} +2 -2
- package/engine/{pr-issue-validation.js → api/pr-issue-validation.js} +33 -6
- package/engine/{settings-validation.js → api/settings-validation.js} +32 -4
- package/engine/api-contracts/agent-content.js +4 -4
- package/engine/api-contracts/capability-manifest.js +236 -0
- package/engine/api-contracts/capability-protocol.js +333 -0
- package/engine/api-contracts/cc-ops.js +1 -1
- package/engine/api-contracts/config-runtime.js +5 -0
- package/engine/api-contracts/core.js +28 -1
- package/engine/api-contracts/index.js +100 -0
- package/engine/api-contracts/orchestration.js +18 -5
- package/engine/api-contracts/pull-requests.js +37 -6
- package/engine/api-contracts/qa-process.js +29 -6
- package/engine/api-contracts/work-plan-prd.js +21 -1
- package/engine/cloud/contract.js +212 -0
- package/engine/cloud/index.js +159 -0
- package/engine/{execution-model.js → core/execution-model.js} +1 -1
- package/engine/{features.js → core/features.js} +4 -4
- package/engine/{operator-identity.js → core/operator-identity.js} +1 -1
- package/engine/{queries.js → core/queries.js} +201 -36
- package/engine/{safe-expr.js → core/safe-expr.js} +1 -1
- package/engine/{shared.js → core/shared.js} +1637 -175
- package/engine/{stdio-timestamps.js → core/stdio-timestamps.js} +1 -1
- package/engine/{untrusted-fence.js → core/untrusted-fence.js} +3 -3
- package/engine/db/index.js +11 -2
- package/engine/db/migrations/002-dispatches.js +3 -3
- package/engine/db/migrations/003-work-items.js +1 -1
- package/engine/db/migrations/004-pull-requests.js +1 -1
- package/engine/db/migrations/006-metrics.js +1 -1
- package/engine/db/migrations/007-watches.js +2 -2
- package/engine/db/migrations/008-small-state.js +1 -1
- package/engine/db/migrations/009-qa.js +1 -1
- package/engine/db/migrations/010-pr-links.js +1 -1
- package/engine/db/migrations/011-remaining-state.js +1 -1
- package/engine/db/migrations/012-steering-deliveries.js +2 -2
- package/engine/db/migrations/013-backfill-broken-note-links.js +1 -1
- package/engine/db/migrations/014-pr-fix-target-prefs.js +2 -2
- package/engine/db/migrations/015-plans-prds.js +0 -0
- package/engine/db/migrations/018-sql-only-cutover.js +2 -2
- package/engine/db/migrations/021-archived-work-items.js +1 -1
- package/engine/db/migrations/022-global-cc-session.js +1 -1
- package/engine/db/migrations/023-engine-state.js +1 -1
- package/engine/db/migrations/025-malformed-work-item-phantoms.js +1 -1
- package/engine/db/migrations/027-review-learning-lifecycle.js +1 -1
- package/engine/db/migrations/029-repair-reused-versions.js +20 -0
- package/engine/db/migrations/031-pr-author-identity.js +137 -0
- package/engine/{consolidation.js → memory/consolidation.js} +6 -6
- package/engine/{kb-sweep-runner.js → memory/kb-sweep-runner.js} +2 -2
- package/engine/{kb-sweep.js → memory/kb-sweep.js} +9 -7
- package/engine/{memory-retrieval.js → memory/memory-retrieval.js} +46 -4
- package/engine/{memory-store.js → memory/memory-store.js} +3 -3
- package/engine/{promotion.js → memory/promotion.js} +3 -3
- package/engine/{review-learning-backfill.js → memory/review-learning-backfill.js} +6 -6
- package/engine/{review-learning.js → memory/review-learning.js} +10 -5
- package/engine/{diagnostics-memory.js → observability/diagnostics-memory.js} +1 -1
- package/engine/{logs-store.js → observability/logs-store.js} +5 -5
- package/engine/{metrics-store.js → observability/metrics-store.js} +4 -4
- package/engine/{check-status.js → operations/check-status.js} +3 -3
- package/engine/{cli.js → operations/cli.js} +271 -113
- package/engine/{distribution.js → operations/distribution.js} +5 -6
- package/engine/{cleanup.js → orchestration/cleanup.js} +72 -45
- package/engine/{cooldown.js → orchestration/cooldown.js} +5 -5
- package/engine/{dispatch-events.js → orchestration/dispatch-events.js} +2 -2
- package/engine/{dispatch.js → orchestration/dispatch.js} +129 -36
- package/engine/orchestration/failed-scheduled-cleanup.js +274 -0
- package/engine/{lifecycle.js → orchestration/lifecycle.js} +198 -90
- package/engine/{meeting.js → orchestration/meeting.js} +6 -16
- package/engine/{pipeline.js → orchestration/pipeline.js} +12 -12
- package/engine/{pre-dispatch-eval.js → orchestration/pre-dispatch-eval.js} +10 -9
- package/engine/{routing.js → orchestration/routing.js} +3 -3
- package/engine/{schedule-bootstrap.js → orchestration/schedule-bootstrap.js} +4 -4
- package/engine/{scheduler.js → orchestration/scheduler.js} +38 -8
- package/engine/{timeout.js → orchestration/timeout.js} +158 -109
- package/engine/{db-events.js → persistence/db-events.js} +2 -2
- package/engine/{dispatch-store.js → persistence/dispatch-store.js} +7 -7
- package/engine/{inbox-store.js → persistence/inbox-store.js} +2 -2
- package/engine/{note-link-backfill.js → persistence/note-link-backfill.js} +4 -4
- package/engine/{pr-fix-target-store.js → persistence/pr-fix-target-store.js} +8 -8
- package/engine/{pull-requests-store.js → persistence/pull-requests-store.js} +21 -7
- package/engine/{small-state-store.js → persistence/small-state-store.js} +31 -31
- package/engine/persistence/state-operations.js +350 -0
- package/engine/{steering-store.js → persistence/steering-store.js} +6 -6
- package/engine/{issues.js → planning/issues.js} +2 -2
- package/engine/{plan-prd-validation.js → planning/plan-prd-validation.js} +8 -2
- package/engine/planning/prd-result-sidecar.js +190 -0
- package/engine/{prd-store.js → planning/prd-store.js} +17 -17
- package/engine/{project-discovery.js → planning/project-discovery.js} +5 -5
- package/engine/{projects.js → planning/projects.js} +10 -10
- package/engine/{resolve-area.js → planning/resolve-area.js} +1 -1
- package/engine/{work-item-validation.js → planning/work-item-validation.js} +39 -3
- package/engine/{work-items-store.js → planning/work-items-store.js} +29 -21
- package/engine/{keep-process-sweep.js → processes/keep-process-sweep.js} +57 -17
- package/engine/{managed-spawn-launcher.js → processes/managed-spawn-launcher.js} +3 -3
- package/engine/{managed-spawn.js → processes/managed-spawn.js} +97 -46
- package/engine/{process-utils.js → processes/process-utils.js} +599 -55
- package/engine/{abandoned-pr-reconciliation.js → providers/abandoned-pr-reconciliation.js} +17 -7
- package/engine/{comment-classifier.js → providers/comment-classifier.js} +85 -17
- package/engine/{comment-format.js → providers/comment-format.js} +5 -5
- package/engine/{gh-comment.js → providers/gh-comment.js} +15 -15
- package/engine/{gh-token.js → providers/gh-token.js} +4 -4
- package/engine/{github.js → providers/github.js} +131 -54
- package/engine/{pr-action.js → providers/pr-action.js} +13 -12
- package/engine/{pr-clone-keep.js → providers/pr-clone-keep.js} +7 -7
- package/engine/{pr-devbox.js → providers/pr-devbox.js} +6 -6
- package/engine/{pr-fix-target.js → providers/pr-fix-target.js} +13 -13
- package/engine/{pr-remote-patch.js → providers/pr-remote-patch.js} +4 -4
- package/engine/{pr-resolve.js → providers/pr-resolve.js} +7 -7
- package/engine/{pr-temp-clone.js → providers/pr-temp-clone.js} +5 -5
- package/engine/{pr-track.js → providers/pr-track.js} +11 -13
- package/engine/{shared-branch-pr-reconcile.js → providers/shared-branch-pr-reconcile.js} +4 -4
- package/engine/qa/auto-prd-qa.js +313 -0
- package/engine/{qa-from-prd.js → qa/from-prd.js} +42 -12
- package/engine/qa/prd-session.js +240 -0
- package/engine/{qa-process-validation.js → qa/process-validation.js} +14 -9
- package/engine/{qa-runbooks.js → qa/runbooks.js} +1 -1
- package/engine/{qa-runs.js → qa/runs.js} +286 -15
- package/engine/{qa-sessions.js → qa/sessions.js} +595 -49
- package/engine/qa/visual-journey.js +654 -0
- package/engine/{qa-runners.js → qa-runners/index.js} +7 -7
- package/engine/qa-runners/maestro.js +3 -3
- package/engine/qa-runners/playwright.js +2 -2
- package/engine/{restart-health.js → recovery/restart-health.js} +48 -4
- package/engine/recovery/stop-stack.js +607 -0
- package/engine/{supervisor.js → recovery/supervisor.js} +105 -175
- package/engine/{watchdog.js → recovery/watchdog.js} +136 -13
- package/engine/runtimes/claude.js +14 -12
- package/engine/runtimes/codex.js +8 -6
- package/engine/runtimes/copilot.js +17 -16
- package/engine/{watch-actions.js → watches/actions.js} +13 -13
- package/engine/{watches.js → watches/index.js} +43 -32
- package/engine/{watches-store.js → watches/store.js} +4 -4
- package/engine/{create-pr-worktree.js → worktrees/create-pr.js} +1 -1
- package/engine/{worktree-gc.js → worktrees/gc.js} +70 -22
- package/engine/worktrees/inventory.js +671 -0
- package/engine/{live-checkout.js → worktrees/live-checkout.js} +4 -4
- package/engine/{worktree-pool.js → worktrees/pool.js} +2 -2
- package/engine/{worktree-preflight.js → worktrees/preflight.js} +1 -0
- package/engine/worktrees/quarantine-refs.js +173 -0
- package/engine.js +1137 -208
- package/minions.js +147 -77
- package/package.json +10 -6
- package/playbooks/_pr-description-audit.md +110 -78
- package/playbooks/build-fix-complex.md +2 -0
- package/playbooks/fix.md +16 -12
- package/playbooks/implement-shared.md +2 -0
- package/playbooks/implement.md +19 -20
- package/playbooks/plan-to-prd.md +18 -3
- package/playbooks/qa-session-draft.md +136 -1
- package/playbooks/qa-session-execute.md +80 -2
- package/playbooks/qa-session-setup.md +17 -1
- package/playbooks/qa-validate.md +1 -1
- package/playbooks/setup.md +2 -0
- package/playbooks/shared-rules.md +25 -32
- package/playbooks/templates/followup-dispatch.md +4 -3
- package/playbooks/verify.md +1 -1
- package/prompts/cc-system.md +19 -27
- package/watch-plugins/README.md +92 -0
- package/watch-plugins/ado-author-prs.js +336 -0
- package/watch-plugins/gh-author-prs.js +375 -0
- package/watch-plugins/http.js +474 -0
- package/watch-plugins/teams-channel.js +869 -0
- package/docs/dev-composite-workflow.md +0 -101
- package/docs/pr-screenshots/pr-886/after-single-header.png +0 -0
- package/docs/pr-screenshots/pr-886/before-duplicate-header.png +0 -0
- package/docs/pr-screenshots/pr-895/01-cancellation-reason-detail.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-default.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-fmf-selected.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-dropdown-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
- package/docs/visual-evidence-ci.md +0 -103
- package/engine/bridge.js +0 -379
- package/engine/quarantine-refs.js +0 -103
- package/engine/state-operations.js +0 -178
- /package/engine/{steering-constraints.js → agents/steering-constraints.js} +0 -0
|
@@ -41,32 +41,19 @@ Bias toward senior-engineer restraint:
|
|
|
41
41
|
- Clean up only artifacts introduced by your own work, such as now-unused imports, variables, helpers, docs, or tests. Mention unrelated dead code instead of deleting it.
|
|
42
42
|
- Turn the task into verifiable goals before editing. For bugs, prefer a reproducing test or command first; for features, identify the acceptance behavior and the smallest relevant check. Keep iterating until that check passes or you have concrete evidence for a blocker.
|
|
43
43
|
|
|
44
|
-
## Branch
|
|
44
|
+
## Branch ownership
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
1. GitHub repos: `gh api user --jq .login` (e.g. `yemi33`, `yemishin_microsoft`)
|
|
52
|
-
2. Azure DevOps repos: `az account show --query user.name -o tsv` and take the localpart before `@` (e.g. `yemishin`)
|
|
53
|
-
3. Fallback: `git config user.email` localpart, then `$USER` / `$USERNAME`
|
|
54
|
-
- `<wi-id>` is the work-item or PRD-item id verbatim (`W-mp7abc123`, `P-a1b2c3d4`, `PL-…`).
|
|
55
|
-
- `<slug>` is a short lowercase kebab-case summary derived from the title. ASCII only, words separated by `-`, ≤ 40 chars, no leading/trailing hyphens.
|
|
56
|
-
|
|
57
|
-
Examples:
|
|
58
|
-
- `user/yemi33/W-mp7abc123-fix-login-redirect`
|
|
59
|
-
- `user/yemishin/P-a1b2c3d4-shared-schemas`
|
|
60
|
-
- `user/yemishin_microsoft/PL-feature-rollout-stage-1`
|
|
61
|
-
|
|
62
|
-
Application:
|
|
63
|
-
- The engine pre-creates your worktree on a branch matching this convention. Push to that branch as injected via `{{branch_name}}` — do not create or rename branches.
|
|
64
|
-
- When you create a work item programmatically (API, plan-to-prd, scripts), set the WI's `branch` (or PRD `feature_branch`) to the conventional name so the engine creates the worktree on the right branch from the start. `dashboard.js` derives this automatically when callers omit `branch`.
|
|
65
|
-
- The legacy `feat/<id>-<slug>` and bare `work/<id>` formats are deprecated; the engine no longer falls back to them.
|
|
46
|
+
The engine pre-creates the task worktree and injects its branch as
|
|
47
|
+
`{{branch_name}}`. Push that exact branch; do not derive a branch from a user,
|
|
48
|
+
create or rename branches, or infer ownership from the active platform account.
|
|
49
|
+
When a caller omits a branch, the canonical engine fallback is `work/<wi-id>`.
|
|
50
|
+
Shared-branch plans use the PRD's explicit `feature_branch`.
|
|
66
51
|
|
|
67
52
|
### PR-fix exception (DO NOT branch off master)
|
|
68
53
|
|
|
69
|
-
For a `type: "fix"` work item that targets an existing PR, the engine reuses the
|
|
54
|
+
For a `type: "fix"` work item that targets an existing PR, the engine reuses the
|
|
55
|
+
PR's **source branch** instead of deriving a new task branch. PR pointers are
|
|
56
|
+
detected from any of:
|
|
70
57
|
|
|
71
58
|
- Structured fields: `targetPr`, `pr_id`, `prUrl`, `prNumber`, `pullRequest`, `sourcePr`
|
|
72
59
|
- `references[*].url` (manual `/api/work-items` callers usually pass the PR pointer here)
|
|
@@ -167,12 +154,16 @@ For the canonical schema — every field, the `failure_class` enum, `noop:true`
|
|
|
167
154
|
|
|
168
155
|
## Minions API access
|
|
169
156
|
|
|
170
|
-
The Minions dashboard
|
|
157
|
+
The resolved Minions dashboard for this dispatch is
|
|
158
|
+
`http://localhost:{{dashboard_port}}`. Agents may call its HTTP endpoints when
|
|
159
|
+
(and only when) the playbook explicitly authorizes it for a particular task.
|
|
160
|
+
Most dispatches do not need API access, and uninvited writes to engine-managed
|
|
161
|
+
state are prohibited.
|
|
171
162
|
|
|
172
163
|
When a playbook authorizes an API call (e.g. follow-up work-item dispatch from `playbooks/templates/followup-dispatch.md`), use the standard `curl` shape:
|
|
173
164
|
|
|
174
165
|
```bash
|
|
175
|
-
curl -sS -X POST http://localhost:
|
|
166
|
+
curl -sS -X POST http://localhost:{{dashboard_port}}/api/<route> \
|
|
176
167
|
-H 'Content-Type: application/json' \
|
|
177
168
|
-H 'X-Minions-Agent: <your-agent-id>' \
|
|
178
169
|
-H 'X-Minions-Origin-Wi: <current-work-item-id>' \
|
|
@@ -181,7 +172,7 @@ curl -sS -X POST http://localhost:7331/api/<route> \
|
|
|
181
172
|
|
|
182
173
|
Conventions:
|
|
183
174
|
|
|
184
|
-
- The full live route surface is available at `GET http://localhost:
|
|
175
|
+
- The full live route surface is available at `GET http://localhost:{{dashboard_port}}/api/routes` (the route registry includes method, path, and a one-line description for every handler).
|
|
185
176
|
- **Identification headers (for traceability, not auth).** Set `X-Minions-Agent` to your agent id and `X-Minions-Origin-Wi` to the work-item id you were dispatched against. Endpoints that persist these (e.g. `POST /api/work-items`) store them as `_originAgent` / `_originWi` for the dashboard timeline. Agents do **not** have a `X-CC-Turn-Id` — that header is reserved for Command Center turns.
|
|
186
177
|
- The dashboard binds to `127.0.0.1` only; no auth token is required for localhost calls.
|
|
187
178
|
- Treat HTTP 4xx as a contract violation: surface the response body in your completion summary instead of retrying blindly.
|
|
@@ -208,7 +199,7 @@ Concretely:
|
|
|
208
199
|
- Do not sleep or busy-wait for `mergeStatus`, `buildStatus`, or any ADO/GitHub API to flip from `running` to `passing`.
|
|
209
200
|
- If you skipped local validation, say so in the completion JSON (e.g. `tests: skipped — relying on PR pipeline`) and still exit.
|
|
210
201
|
- Holding a slot to watch a pipeline is wasted capacity; the engine has its own pipeline-monitoring path.
|
|
211
|
-
- **
|
|
202
|
+
- **Visual evidence (screenshots + recordings) is a DEFAULT completion behavior for UI changes on ANY project.** By default, when your diff alters a **rendered UI surface in any project** — web front-ends, dashboards, mobile webviews, or any view a user sees — capture and embed visual evidence in the PR description: BEFORE/AFTER screenshots for visual fixes (AFTER-only for new UI), plus a **screen recording/video** for interactive, animated, or multi-step flows. Decide "is this a visual change?" from whether the diff changes a rendered surface, NOT from repo-specific paths. **How to capture — resolution order:** (1) **harness first** — consult the TARGET repo's own instructions for how it runs its UI and captures evidence (`AGENTS.md`, `CLAUDE.md`, `README`/`CONTRIBUTING`, a project-local playbook under `projects/<name>/playbooks/`, or a project-embedded skill under `.claude/skills` / `.github/skills` / `.agents/skills`; the engine surfaces this harness plumbing read-only via `engine/agents/harness-context.js` and `GET /api/harness/diagnostics`); (2) **fall back** to Minions' own project-agnostic Playwright skill `capture-web-evidence` (`.claude/skills/capture-web-evidence/SKILL.md`) when the repo has no visual-evidence instructions. As ONE concrete example, the **minions dashboard gate stays MANDATORY**: any PR whose diff changes a rendered dashboard/UI surface (files under `dashboard/`, `dashboard/slim/`, `dashboard/pages/`, `dashboard/js/`, `dashboard/styles.css`, or anything that alters what a page/route renders) MUST embed AFTER screenshots in the PR description (full recipe: `_pr-description-audit.md`). Skips are allowed only on a recorded hard failure (dev server won't start, Playwright MCP unavailable, route 404s, upload auth fails). Save PNGs/videos ONLY under `agents/<id>/screenshots/` (recordings under a `recordings/` subdir) — NEVER `git add` a screenshot or video. Backend/engine/text/analysis/docs diffs get NO visual evidence.
|
|
212
203
|
|
|
213
204
|
## Resolving Review Threads — No Silent Closures
|
|
214
205
|
|
|
@@ -317,7 +308,9 @@ gh pr view <prNumber> --json number,title,state,mergeable,reviewDecision,headRef
|
|
|
317
308
|
|
|
318
309
|
## Posting PR Comments and Reviews (MANDATORY MARKER)
|
|
319
310
|
|
|
320
|
-
|
|
311
|
+
PR comments and reviews may be sent through a platform credential shared by
|
|
312
|
+
multiple agents. The engine cannot infer Minions agent identity from that
|
|
313
|
+
platform login, so every agent-authored post must include the Minions marker.
|
|
321
314
|
|
|
322
315
|
**Preferred path — `minions pr comment` (auto-prepends the marker):**
|
|
323
316
|
```bash
|
|
@@ -349,7 +342,7 @@ The marker is an HTML comment on its own line — GitHub's renderer strips it be
|
|
|
349
342
|
```
|
|
350
343
|
So write `Fixed by [Minions](https://icy-water-0224cc51e.2.azurestaticapps.net/minions)`, not a bare `Fixed by Minions`. This applies to GitHub and ADO comments alike. Do **not** link occurrences inside the HTML marker line, code blocks, or file paths — only the human-readable prose mention. Link the first occurrence per comment; subsequent repeats in the same comment may stay plain.
|
|
351
344
|
|
|
352
|
-
> **Engine safety net.** When you post via `minions pr comment` (GitHub: `minions pr comment <repo> <number> …`; ADO: `minions pr comment <number> --host ado --ado-org … --ado-project … --repo-id … …`), the engine deterministically hyperlinks the first bare `… by Minions` signature trailer for you (`engine/comment-format.js#linkifyBrandTrailer`, applied in the shared `buildMinionsCommentBody` consumed by both `engine/gh-comment.js` and `engine/ado
|
|
345
|
+
> **Engine safety net.** When you post via `minions pr comment` (GitHub: `minions pr comment <repo> <number> …`; ADO: `minions pr comment <number> --host ado --ado-org … --ado-project … --repo-id … …`), the engine deterministically hyperlinks the first bare `… by Minions` signature trailer for you (`engine/providers/comment-format.js#linkifyBrandTrailer`, applied in the shared `buildMinionsCommentBody` consumed by both `engine/providers/gh-comment.js` and `engine/ado/comment.js`) — a no-op if you already linked the first mention. This is a backstop, not a license to skip the link: the **raw fallbacks** (`gh pr comment`, `az repos pr comment`, ADO REST) do NOT pass through that chokepoint, so you must link the brand mention yourself there. Subject-form mentions like "Minions rebased this branch" are still your responsibility on both hosts.
|
|
353
346
|
|
|
354
347
|
## GitHub Tooling and Auth
|
|
355
348
|
|
|
@@ -379,13 +372,13 @@ Read `GET http://localhost:{{dashboard_port}}/api/pull-requests` and find the pr
|
|
|
379
372
|
|
|
380
373
|
**Live status (when engine isn't running or you need up-to-the-moment results):**
|
|
381
374
|
```bash
|
|
382
|
-
node engine/ado
|
|
383
|
-
node engine/ado
|
|
384
|
-
node engine/ado
|
|
375
|
+
node engine/ado/status.js <prNumber> # reads the cached SQL PR store
|
|
376
|
+
node engine/ado/status.js <prNumber> --live # fresh ADO API call
|
|
377
|
+
node engine/ado/status.js <prNumber> --live --project MyProject
|
|
385
378
|
```
|
|
386
379
|
Output is JSON with the same fields. Exit 0 on success, 1 if not found.
|
|
387
380
|
|
|
388
|
-
**Never make raw `curl` calls to ADO APIs directly.** Use `node engine/ado
|
|
381
|
+
**Never make raw `curl` calls to ADO APIs directly.** Use `node engine/ado/status.js`, which routes through `engine/ado/index.js` — authenticated, retried, circuit-broken. Raw `azureauth` + curl bypasses all of that.
|
|
389
382
|
|
|
390
383
|
**If you must run `azureauth` directly, ALWAYS include `--timeout 1`.** Without this flag, `azureauth ado token` can hang indefinitely waiting for interactive broker UI that never appears in headless agent sessions. This causes the Claude Code process to silently exit and the engine to declare the agent orphaned. Example: `azureauth ado token --mode iwa --mode broker --output token --timeout 1`.
|
|
391
384
|
|
|
@@ -34,11 +34,12 @@ and explain your reasoning — don't manufacture work.
|
|
|
34
34
|
|
|
35
35
|
## The API call
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
Use the dashboard resolved for this dispatch at
|
|
38
|
+
`http://localhost:{{dashboard_port}}`. Create a follow-up work item with
|
|
39
|
+
`POST /api/work-items`:
|
|
39
40
|
|
|
40
41
|
```bash
|
|
41
|
-
curl -sS -X POST http://localhost:
|
|
42
|
+
curl -sS -X POST http://localhost:{{dashboard_port}}/api/work-items \
|
|
42
43
|
-H 'Content-Type: application/json' \
|
|
43
44
|
-H 'X-Minions-Agent: <your-agent-id>' \
|
|
44
45
|
-H 'X-Minions-Origin-Wi: <current-wi-id>' \
|
package/playbooks/verify.md
CHANGED
|
@@ -78,7 +78,7 @@ A green E2E build proves the code compiles and the existing tests still pass. It
|
|
|
78
78
|
2. **Identify the silent failure modes.** A change that adds a guard, demotes a fallback, or removes a field has a *what-used-to-happen-here* shadow. Name it. For removals: which call sites read the removed field, and what do they fall back to now? For added guards: what input previously passed and now gets rejected — is that input ever produced legitimately? For demoted fallbacks: which production path relied on the fallback, and is the new primary path actually populated there?
|
|
79
79
|
3. **Check the test additions cover the new branch, not just the happy path.** A test that only asserts the new behavior on a freshly constructed input is half a test. The other half is: does an *existing* fixture that exercised the old behavior still pass, and does it pass for the right reason (not because the assertion got loosened)? Cite the test by file:line and the fixture it uses.
|
|
80
80
|
4. **Read the comments in the diff with suspicion.** Comments like "this also handles X" or "the gate at Y skips this path" are claims the agent made. Verify each one by opening Y and confirming the gate actually does what the comment says. If the claim is wrong, the change has a hole.
|
|
81
|
-
5. **Schema/contract changes deserve a grep across language boundaries.** A field added to a JSON contract in `engine/shared.js` may also be referenced in `dashboard/js/*.js`, `playbooks/*.md`, `test/**`, and any external consumer. Run a literal grep for the field name across the whole tree, not just the PR's touched files.
|
|
81
|
+
5. **Schema/contract changes deserve a grep across language boundaries.** A field added to a JSON contract in `engine/core/shared.js` may also be referenced in `dashboard/js/*.js`, `playbooks/*.md`, `test/**`, and any external consumer. Run a literal grep for the field name across the whole tree, not just the PR's touched files.
|
|
82
82
|
|
|
83
83
|
Record one verdict per engine-touching PR in the form: `PR-####: <safe | risk: <description with path:line citation> | needs human review: <question>>`. "Looks fine" without per-call-site evidence is not acceptable. If you cannot complete the audit in the time available, say so explicitly and list the unaudited PRs in the Merge Decisions section under "PRs requiring human decision".
|
|
84
84
|
|
package/prompts/cc-system.md
CHANGED
|
@@ -41,14 +41,18 @@ Minions runtime state lives in `{{minions_dir}}/engine/state.db` and is accessed
|
|
|
41
41
|
|
|
42
42
|
## Your skills
|
|
43
43
|
|
|
44
|
-
Your runtime is the **Copilot CLI**, not Claude Code.
|
|
44
|
+
Your runtime is the **Copilot CLI**, not Claude Code. The registry below is the complete list of what is available to you, and it mixes two sources that you use in **different ways**.
|
|
45
|
+
|
|
46
|
+
**1. Runtime-registered skills — invoke them with the `skill` tool.** These have no `<path>` element and live in:
|
|
45
47
|
|
|
46
48
|
- `~/.copilot/skills/<name>/SKILL.md` — user-level skills (yours)
|
|
47
49
|
- `~/.copilot/installed-plugins/<marketplace>/<plugin>/skills/<name>/SKILL.md` — plugin-provided skills (also yours)
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
Call your `skill` tool with the skill name (the directory name); the skill body then guides the next steps. **Both user-level and plugin-level skills are invokable the same way** — the `<location>` tag is metadata, not a permission gate.
|
|
52
|
+
|
|
53
|
+
**2. Project-embedded skills — read the `<path>`, do NOT call the `skill` tool.** Minions discovers these under the configured project checkouts (including nested `.claude/skills`, `.github/skills`, and `.agents/skills` directories) and injects them below with a `project:<name>` `<location>` and an on-disk `<path>`. Your runtime never registered them — your working directory is the Minions root, not that project — so invoking one by name will fail. Instead, read the `SKILL.md` at its `<path>` and follow the steps yourself. When the skill belongs to a project repo, prefer delegating the actual work to an agent on that project (see "Role: Orchestrator" below) and let the agent's own runtime pick the skill up natively.
|
|
50
54
|
|
|
51
|
-
When asked "what skills do you have", answer from the registry below — do NOT grep/glob
|
|
55
|
+
When asked "what skills do you have", answer from the registry below — do NOT grep/glob for skill directories. The registry already enumerates the project-embedded ones (`.claude/skills` included) with their on-disk `<path>`, so a filesystem search adds nothing.
|
|
52
56
|
|
|
53
57
|
{{available_skills}}
|
|
54
58
|
|
|
@@ -228,7 +232,7 @@ If the endpoint returns `matched:"none"`, you may also enumerate first-level are
|
|
|
228
232
|
|
|
229
233
|
## Read-only PR actions on ANY PR — POST /api/pr-action
|
|
230
234
|
|
|
231
|
-
When the user asks you to **review / summarize / comment-on / triage a specific PR by URL or id** — including PRs in repos that are NOT a configured Minions project (e.g. "review this PR https://github.com/
|
|
235
|
+
When the user asks you to **review / summarize / comment-on / triage a specific PR by URL or id** — including PRs in repos that are NOT a configured Minions project (e.g. "review this PR https://github.com/owner/repo/pull/42", "summarize ado:org/project/repo#123", "triage github:owner/repo#42") — route it through `POST /api/pr-action` instead of dispatching a `review`/`explore` work item. This path is **projectless and read-only**: it resolves the PR, fetches its diff + metadata with NO clone/worktree, and reasons over the (untrusted-fenced) content. Use it for one-off, look-don't-touch asks on an arbitrary PR.
|
|
232
236
|
|
|
233
237
|
- `url` — REQUIRED. A PR URL (`https://github.com/owner/repo/pull/N`, ADO PR URL) or canonical id (`github:owner/repo#N`, `ado:org/proj/repo#N`).
|
|
234
238
|
- `action` — REQUIRED. One of `review`, `summarize`, `comment`, `triage` (read-only only; a code-mutating `fix` is intentionally NOT accepted here).
|
|
@@ -269,10 +273,10 @@ When the user describes a UI/E2E flow they want validated against a *live, runni
|
|
|
269
273
|
- The user wants a code change, unit/integration tests in the repo, or an investigation. Keep using `/api/work-items` with `type: "fix"`, `"implement"`, `"test"`, `"explore"`.
|
|
270
274
|
- The user explicitly says "QA …", "smoke test …", "test the … flow", "validate the … journey", or names a concrete UI walkthrough against a live app. Use `/api/qa/session`.
|
|
271
275
|
|
|
272
|
-
**Body shape (mirrors `engine/qa
|
|
276
|
+
**Body shape (mirrors `engine/qa/sessions.js#validateSpec`):**
|
|
273
277
|
|
|
274
278
|
- `target` — REQUIRED object describing what to QA against. `target.kind` is one of:
|
|
275
|
-
- `pr` — needs `target.prId` (e.g. `"github:
|
|
279
|
+
- `pr` — needs `target.prId` (e.g. `"github:owner/repo#42"` or `"ado:org/project/repo#123"`).
|
|
276
280
|
- `branch` — needs `target.branch` (e.g. `"develop"`).
|
|
277
281
|
- `commit` — needs `target.sha` (full 40-char SHA).
|
|
278
282
|
- `current` — uses the user's current worktree. `target.worktree` is optional; the SETUP agent falls back to `MINIONS_AGENT_CWD` when empty.
|
|
@@ -287,7 +291,7 @@ When the user describes a UI/E2E flow they want validated against a *live, runni
|
|
|
287
291
|
curl -s -X POST http://localhost:{{dashboard_port}}/api/qa/session \
|
|
288
292
|
-H 'Content-Type: application/json' \
|
|
289
293
|
-H 'X-CC-Turn-Id: {{cc_turn_id}}' \
|
|
290
|
-
-d '{"target":{"kind":"pr","prId":"github:
|
|
294
|
+
-d '{"target":{"kind":"pr","prId":"github:owner/MyApp#1234"},"flowsRaw":"Open the homepage, click Login, enter test@example.com / hunter2, and verify the dashboard renders with the user'\''s name in the header.","mode":"confirm","capture":{"screenshots":true,"logs":true},"projects":["MyApp"]}'
|
|
291
295
|
```
|
|
292
296
|
|
|
293
297
|
**Worked example — current worktree, auto mode, video capture, single project:**
|
|
@@ -312,7 +316,7 @@ curl -s -X POST http://localhost:{{dashboard_port}}/api/qa/session \
|
|
|
312
316
|
|
|
313
317
|
### PRD-driven QA — "qa this PRD" → POST /api/qa/from-prd
|
|
314
318
|
|
|
315
|
-
When the user points QA at a **completed/approved PRD** rather than describing the flow themselves — "QA this PRD", "qa `minions-opg-2026-06-16-3`", "qa the PRD-driven QA PRD", "smoke test the checkout PRD" — route it through `POST /api/qa/from-prd` instead of building a `flowsRaw` by hand. This is a thin bridge over QA Sessions: `engine/qa
|
|
319
|
+
When the user points QA at a **completed/approved PRD** rather than describing the flow themselves — "QA this PRD", "qa `minions-opg-2026-06-16-3`", "qa the PRD-driven QA PRD", "smoke test the checkout PRD" — route it through `POST /api/qa/from-prd` instead of building a `flowsRaw` by hand. This is a thin bridge over QA Sessions: `engine/qa/from-prd.js` reads the PRD JSON (and its `prd/guides/verify-*.md` when present), derives the QA `target` and the natural-language flows from the PRD's items / acceptance criteria, then reuses the exact same `createSession` + `queueSetup` orchestration as `/api/qa/session`. You don't assemble the spec — name the PRD and the endpoint does the rest.
|
|
316
320
|
|
|
317
321
|
**Body shape:** `{ prd, mode?, runner? }`
|
|
318
322
|
|
|
@@ -340,8 +344,8 @@ The `X-CC-Turn-Id` header is the audit trail — the handler stamps it onto the
|
|
|
340
344
|
- **`fix` vs `implement` — pick deliberately.** `type: "fix"` in the engine means "this work item responds to comments or build failures on a tracked PR" — it requires a PR pointer (in `references[*].url`, `meta.pr_followup.parent_pr_url`, or `targetPr`/`pr_id`/`prNumber`) and is dispatched onto the PR's source branch. **Fresh bugfix work** that will open a NEW PR (engine bugs, default-branch CI failures, repo-level regressions found from logs) is `type: "implement"`, not `type: "fix"`. Emitting `type: "fix"` without a PR pointer trips the `pr_not_found` discovery gate (engine.js#discoverWork) and the WI stays blocked indefinitely. Rule of thumb: if the work could land on master via a brand-new PR, it's `implement`; if it must push commits into an existing PR's source branch, it's `fix`.
|
|
341
345
|
- Exempt from the `project` requirement (these run rootless or via central paths): `ask`, `explore`, `plan`, `plan-to-prd`, `meeting`. (`docs` is intentionally NOT exempt — it's write-capable and lands in `WORKTREE_REQUIRING_TYPES`, so it needs a real project worktree. For minions-repo docs work, pass `project: "minions"` explicitly.) `setup` is also in the project-required set — it operates inside a real project worktree but produces no PR. Every other type needs a project worktree, so the server rejects project-less creates with `400 { error, knownProjects }` when ≠1 project is configured.
|
|
342
346
|
- **`meta.keep_processes: true`** — opt-in flag that lets the agent leave specific descendant PIDs running after it exits (default: engine reaps EVERYTHING the agent spawned). **Set this whenever the user's intent is to leave a process alive after the agent finishes** — e.g. "spin up the dev server and exit", "start the watcher and leave it running", "set up my dev env", "keep the emulator open", "launch the daemon for me", "boot the constellation host and disconnect". Don't set it for normal build/test/run-once tasks (`npm test`, `npm run build`, one-shot scripts) — those should be reaped. Also accepts optional `meta.keep_processes_ttl_minutes` (default 60, hard-cap 1440 = 24h). When you set this flag, also make the WI title/description say something like "leave the dev server running" so the agent knows to write `agents/<id>/keep-pids.json` before exiting (the playbook injects the contract automatically when the flag is on). Example: `-d '{"title":"Spin up Constellation dev env and leave server running","type":"implement","project":"constellation","description":"Run bun install + bun run dev. Leave the dev server (port 5173) and Constellation host (port 3001) running after you exit so the user can iterate.","meta":{"keep_processes":true,"keep_processes_ttl_minutes":240}}'`. Inspect / kill kept PIDs anytime via `GET /api/keep-processes` and `POST /api/keep-processes/kill`.
|
|
343
|
-
- **`skipPr: true`** — opt-in flag that tells the engine NOT to enforce the PR-attachment contract for
|
|
344
|
-
- **`oneShot: true`** — opt-in flag for one-off human-initiated dispatches that should NOT enroll the discovered PR into the engine's automatic review/fix loop. The PR is still tracked (status + comments are polled normally) but `discoverFromPrs` skips it for review/fix dispatch. **Set this when the user's intent is "do this single action against an existing PR, then stop"** — e.g. "review PR #
|
|
347
|
+
- **`skipPr: true`** — opt-in flag that tells the engine NOT to enforce the PR-attachment contract for work that cannot produce a PR because it mutates state outside a tracked repository. This flag changes completion accounting only; it does **not** authorize filesystem cleanup or machine-level changes. Any such mutation still requires an explicit, path-specific user request, must preserve unrelated state, and must avoid broad deletion. **Do NOT set it for any task that touches tracked source.** Prefer `type: "setup"` for project bootstrap tasks and `type: "explore"` for read-only work.
|
|
348
|
+
- **`oneShot: true`** — opt-in flag for one-off human-initiated dispatches that should NOT enroll the discovered PR into the engine's automatic review/fix loop. The PR is still tracked (status + comments are polled normally) but `discoverFromPrs` skips it for review/fix dispatch. **Set this when the user's intent is "do this single action against an existing PR, then stop"** — e.g. "review PR #42 once", "rebase PR #43 once and exit", "post a fix-summary comment on PR #44". Don't set it for normal feature/fix work where the PR should keep cycling through review/fix until merged. Example: `-d '{"title":"One-off review of PR #42","type":"review","project":"MyApp","description":"Single review pass on github:owner/MyApp#42. Do not re-dispatch on subsequent comments.","oneShot":true}'`.
|
|
345
349
|
- `POST /api/notes`: `title`, `what` REQUIRED.
|
|
346
350
|
- `POST /api/knowledge`: `category`, `title`, `content` REQUIRED. Categories: `architecture`, `conventions`, `project-notes`, `build-reports`, `reviews`.
|
|
347
351
|
- `POST /api/plan`: `title` REQUIRED. `description`, `priority`, `project`, `agent`, `branchStrategy` optional.
|
|
@@ -375,25 +379,13 @@ The server validates: `liveValidation` requires `checkoutMode:"live"`, canonical
|
|
|
375
379
|
|
|
376
380
|
## GitHub auth
|
|
377
381
|
|
|
378
|
-
We have multiple authed `gh` accounts (`yemi33`, `yemishin_microsoft`) covering three repo scopes (`yemi33/minions`, `yemishin_microsoft/minions`, `opg-microsoft/minions`).
|
|
379
|
-
|
|
380
382
|
**Never run `gh auth switch`.** It flips the global active account and races with the engine's GH poller — past `gh auth switch` calls left the engine polling the wrong account for hours, with PRs stuck in `abandoned` until reconciliation un-flipped them.
|
|
381
383
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
Account map (mirrors `engine.ghAccounts` in `config.json`):
|
|
389
|
-
|
|
390
|
-
| Owner | gh account |
|
|
391
|
-
|-------|------------|
|
|
392
|
-
| `opg-microsoft` | `yemishin_microsoft` |
|
|
393
|
-
| `yemishin_microsoft` | `yemishin_microsoft` |
|
|
394
|
-
| `yemi33` | `yemi33` |
|
|
395
|
-
|
|
396
|
-
The engine resolves these automatically via `engine/gh-token.js` for its own polling and issue creation; only CC and agents need to be careful in shell commands. If you're unsure which account a slug needs, the table above is the source of truth.
|
|
384
|
+
For shell operations, enumerate configured `gh` accounts and select one by
|
|
385
|
+
probing the exact target slug with a per-command `GH_TOKEN`. Verify repository
|
|
386
|
+
identity and required permissions before any write. Fail closed when no account
|
|
387
|
+
has access; never hardcode an operator login or rely on the globally active
|
|
388
|
+
account. Engine-owned calls resolve this mapping through `engine/gh-token.js`.
|
|
397
389
|
|
|
398
390
|
## Document edits
|
|
399
391
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Watch Plugins
|
|
2
|
+
|
|
3
|
+
This directory contains JavaScript extensions that add target types to Minions
|
|
4
|
+
watches. A watch is a SQLite record that combines a target type, target,
|
|
5
|
+
condition, interval, and optional action. Plugins define how a new kind of
|
|
6
|
+
target is fetched, snapshotted, evaluated, and exposed to action templates.
|
|
7
|
+
|
|
8
|
+
## Loading and trust
|
|
9
|
+
|
|
10
|
+
At engine startup, `engine/watches/index.js` loads every top-level `*.js` file in
|
|
11
|
+
`<MINIONS_DIR>/watch-plugins/`. Changes require an engine restart.
|
|
12
|
+
|
|
13
|
+
Plugins are trusted, unsandboxed Node.js code running inside the engine process.
|
|
14
|
+
They can access the filesystem, environment, network, and engine modules.
|
|
15
|
+
Install only reviewed plugins. A plugin failure is logged and skipped so it
|
|
16
|
+
does not prevent the engine from starting. Plugins cannot replace built-in or
|
|
17
|
+
previously registered target types.
|
|
18
|
+
|
|
19
|
+
The former directory name was `watches.d/`. Legacy custom plugins remain loaded
|
|
20
|
+
with a deprecation warning so upgrades do not disable existing watches. Move
|
|
21
|
+
them into `watch-plugins/`; new plugins belong only here.
|
|
22
|
+
|
|
23
|
+
## Contract
|
|
24
|
+
|
|
25
|
+
A plugin exports one `{ name, spec }` object or an array of them:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
module.exports = {
|
|
29
|
+
name: 'example-target',
|
|
30
|
+
spec: {
|
|
31
|
+
label: 'Example Target',
|
|
32
|
+
description: 'What this target watches',
|
|
33
|
+
conditions: ['status-change'],
|
|
34
|
+
absoluteConditions: [],
|
|
35
|
+
validateTarget(target, context) {
|
|
36
|
+
return null; // return an error string when invalid
|
|
37
|
+
},
|
|
38
|
+
fetchEntity(target, state) {
|
|
39
|
+
return null;
|
|
40
|
+
},
|
|
41
|
+
captureState(entity, previousState) {
|
|
42
|
+
return {};
|
|
43
|
+
},
|
|
44
|
+
evaluate(condition, entity, previousState, target) {
|
|
45
|
+
return { triggered: false, message: '' };
|
|
46
|
+
},
|
|
47
|
+
contextVars(entity, previousState, newState) {
|
|
48
|
+
return {};
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Required fields are `label`, non-empty `conditions`, `fetchEntity`,
|
|
55
|
+
`captureState`, and `evaluate`. `description`, `absoluteConditions`,
|
|
56
|
+
`validateTarget`, `isTerminalForCondition`, and `contextVars` are optional.
|
|
57
|
+
|
|
58
|
+
The engine's watch evaluation path is synchronous. A plugin that performs
|
|
59
|
+
network I/O should refresh a bounded module-level cache in the background and
|
|
60
|
+
return the latest cached entity from `fetchEntity`. Never perform network calls
|
|
61
|
+
while a Minions state lock is held.
|
|
62
|
+
|
|
63
|
+
## Bundled plugins
|
|
64
|
+
|
|
65
|
+
| Plugin | Target type | Purpose |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `http.js` | `http` | Poll an HTTP endpoint and compare status or extracted values |
|
|
68
|
+
| `gh-author-prs.js` | `gh-author-prs` | Detect new non-draft GitHub PRs by author |
|
|
69
|
+
| `ado-author-prs.js` | `ado-author-prs` | Detect new non-draft Azure DevOps PRs by configured author |
|
|
70
|
+
| `teams-channel.js` | `teams-channel` | Detect new Microsoft Teams channel messages and replies |
|
|
71
|
+
|
|
72
|
+
Repository/account/channel identities belong in the watch target or Minions
|
|
73
|
+
configuration, never as plugin defaults. GitHub authentication resolves through
|
|
74
|
+
`config.engine.ghAccounts`; Azure DevOps plugins use the shared ADO token path.
|
|
75
|
+
Secrets must come from environment variables or engine token helpers and must
|
|
76
|
+
never be persisted in watch records or logs.
|
|
77
|
+
|
|
78
|
+
## Creating a watch
|
|
79
|
+
|
|
80
|
+
Use Dashboard **Watches**, the CLI, or the API. Discover the active runtime
|
|
81
|
+
surface first:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
minions watch target-types
|
|
85
|
+
minions watch action-types
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The dashboard API exposes the same registries at
|
|
89
|
+
`GET /api/watches/target-types` and `GET /api/watches/action-types`.
|
|
90
|
+
|
|
91
|
+
Full lifecycle, condition, and action documentation:
|
|
92
|
+
[docs/watches.md](../docs/watches.md).
|