@yemi33/minions 0.1.2047 → 0.1.2049
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/dashboard/js/command-center.js +72 -0
- package/dashboard/js/command-history.js +2 -1
- package/dashboard/js/command-input.js +7 -3
- package/dashboard/js/command-parser.js +1 -0
- package/dashboard/js/detail-panel.js +7 -0
- package/dashboard/js/fre.js +1 -0
- package/dashboard/js/live-stream.js +2 -0
- package/dashboard/js/modal-qa.js +9 -0
- package/dashboard/js/modal.js +1 -0
- package/dashboard/js/qa.js +6 -0
- package/dashboard/js/refresh.js +3 -1
- package/dashboard/js/render-agents.js +30 -3
- package/dashboard/js/render-dispatch.js +12 -0
- package/dashboard/js/render-inbox.js +6 -0
- package/dashboard/js/render-kb.js +4 -0
- package/dashboard/js/render-managed.js +1 -0
- package/dashboard/js/render-meetings.js +6 -0
- package/dashboard/js/render-other.js +11 -0
- package/dashboard/js/render-pinned.js +2 -0
- package/dashboard/js/render-pipelines.js +5 -0
- package/dashboard/js/render-plans.js +9 -0
- package/dashboard/js/render-prd.js +8 -0
- package/dashboard/js/render-prs.js +4 -0
- package/dashboard/js/render-schedules.js +5 -0
- package/dashboard/js/render-skills.js +2 -0
- package/dashboard/js/render-watches.js +10 -0
- package/dashboard/js/render-work-items.js +9 -0
- package/dashboard/js/settings.js +10 -0
- package/dashboard/slim.html +8 -8
- package/docs/deprecated.json +7 -3
- package/engine/cleanup.js +24 -1
- package/engine/lifecycle.js +0 -1
- package/engine/queries.js +37 -5
- package/package.json +6 -3
- package/playbooks/fix.md +15 -5
- package/playbooks/shared-rules.md +29 -0
package/engine/queries.js
CHANGED
|
@@ -531,6 +531,11 @@ function getAgents(config) {
|
|
|
531
531
|
// → engine.defaultCli → 'copilot'. Surfaced so the dashboard can show a
|
|
532
532
|
// runtime tag next to the agent name.
|
|
533
533
|
const runtime = shared.resolveAgentCli(a, config.engine || {});
|
|
534
|
+
// Resolve the model alongside the runtime so the dashboard can render a
|
|
535
|
+
// sibling chip (W-mpmwxk4y00053271). `resolveAgentModel` returns
|
|
536
|
+
// `undefined` when neither the per-agent override nor `engine.defaultModel`
|
|
537
|
+
// is set, which the renderer treats as "runtime default" and omits.
|
|
538
|
+
const model = shared.resolveAgentModel(a, config.engine || {}) || null;
|
|
534
539
|
const inboxFiles = allInboxFiles.filter(f => f.includes(a.id));
|
|
535
540
|
let steeringInboxFiles = [];
|
|
536
541
|
try { steeringInboxFiles = steering.listUnreadSteeringMessages(a.id); } catch { steeringInboxFiles = []; }
|
|
@@ -552,7 +557,7 @@ function getAgents(config) {
|
|
|
552
557
|
const chartered = fs.existsSync(path.join(AGENTS_DIR, a.id, 'charter.md'));
|
|
553
558
|
if (lastAction.length > 120) lastAction = lastAction.slice(0, 120) + '...';
|
|
554
559
|
return {
|
|
555
|
-
...a, runtime, status: s.status, lastAction,
|
|
560
|
+
...a, runtime, model, status: s.status, lastAction,
|
|
556
561
|
currentTask: (s.task || '').slice(0, 200),
|
|
557
562
|
// P-w2c8d1e7 — Phase 1.2: surface the active dispatch id so watch
|
|
558
563
|
// captureState can snapshot it for currentDispatchId-aware predicates.
|
|
@@ -1236,8 +1241,16 @@ function getWorkItems(config) {
|
|
|
1236
1241
|
}
|
|
1237
1242
|
}
|
|
1238
1243
|
if (!item._pr) {
|
|
1239
|
-
// Derive from PR.prdItems (single source of truth)
|
|
1240
|
-
|
|
1244
|
+
// Derive from PR.prdItems (single source of truth), then fall back to
|
|
1245
|
+
// branch identity. The branch fallback heals decomposed-child WIs whose
|
|
1246
|
+
// PR-opening agent only stamped the parent id into prdItems — branch
|
|
1247
|
+
// names (`work/<wi-id>`) are unique per WI within a project, so a
|
|
1248
|
+
// branch hit is as authoritative as a prdItems hit. Scoped to the same
|
|
1249
|
+
// project so cross-repo branch collisions don't false-link.
|
|
1250
|
+
// (W-mpn0b76200044eed)
|
|
1251
|
+
const itemProject = item.project || item._source;
|
|
1252
|
+
const linkedPr = allPrs.find(p => (p.prdItems || []).includes(item.id))
|
|
1253
|
+
|| (item.branch && allPrs.find(p => p.branch === item.branch && p._project === itemProject));
|
|
1241
1254
|
if (linkedPr) {
|
|
1242
1255
|
item._pr = linkedPr.id;
|
|
1243
1256
|
item._prUrl = linkedPr.url;
|
|
@@ -1925,6 +1938,10 @@ function getProjectGitStatus(localPath, configuredMainBranch = null) {
|
|
|
1925
1938
|
const key = _projectGitStatusCacheKey(localPath, configuredMainBranch);
|
|
1926
1939
|
const now = Date.now();
|
|
1927
1940
|
const cached = _projectGitStatusCache.get(key);
|
|
1941
|
+
// Compute ref-mtime freshness once. Used twice below: to gate the TTL
|
|
1942
|
+
// fast-path AND to decide whether the stale-while-revalidate return
|
|
1943
|
+
// should null out the known-stale ahead/behind counters (#2848).
|
|
1944
|
+
const refsAdvanced = !!(cached && _projectGitRefsAdvancedSince(localPath, configuredMainBranch, cached.refMtimes));
|
|
1928
1945
|
// Within TTL: short-circuit ONLY when no tracked git ref has advanced
|
|
1929
1946
|
// past cached.ts. Without the mtime gate, a freshly-pulled repo serves
|
|
1930
1947
|
// the pre-pull ahead/behind counts for up to 15s + one SPA poll (~19s
|
|
@@ -1939,7 +1956,7 @@ function getProjectGitStatus(localPath, configuredMainBranch = null) {
|
|
|
1939
1956
|
if (cachedIsMissing && fs.existsSync(localPath)) {
|
|
1940
1957
|
// Path came back — fall through to schedule a fresh probe.
|
|
1941
1958
|
} else if (cached && cached.ts && (now - cached.ts) < PROJECT_GIT_STATUS_TTL
|
|
1942
|
-
&& !
|
|
1959
|
+
&& !refsAdvanced) {
|
|
1943
1960
|
return cached.value;
|
|
1944
1961
|
}
|
|
1945
1962
|
// Cheap synchronous existsSync — short-circuits a path that just disappeared
|
|
@@ -1955,7 +1972,22 @@ function getProjectGitStatus(localPath, configuredMainBranch = null) {
|
|
|
1955
1972
|
// previous value (or pending placeholder on the very first call). The next
|
|
1956
1973
|
// /api/status response after the refresh settles will have fresh data.
|
|
1957
1974
|
_scheduleProjectGitStatusRefresh(localPath, key, configuredMainBranch);
|
|
1958
|
-
|
|
1975
|
+
if (!cached) return PROJECT_GIT_STATUS_PENDING;
|
|
1976
|
+
// When tracked git refs have advanced past the cached snapshot, the
|
|
1977
|
+
// cached ahead/behind counts are known to be stale (e.g. user just ran
|
|
1978
|
+
// `git pull` / `git fetch` and the local checkout is now current).
|
|
1979
|
+
// Returning the cached value as-is would briefly display a misleading
|
|
1980
|
+
// "behind: 8" after the user has already pulled to current — see
|
|
1981
|
+
// yemi33/minions#2848. Null those specific counters so the dashboard
|
|
1982
|
+
// shows a pending state for ahead/behind until the background probe
|
|
1983
|
+
// settles; branch and dirty flags stay valid enough on the cached
|
|
1984
|
+
// value (and update on the next poll once the probe lands). TTL-expiry
|
|
1985
|
+
// fall-throughs (refsAdvanced=false) still return the prior counters
|
|
1986
|
+
// because nothing local has actually changed there.
|
|
1987
|
+
if (refsAdvanced) {
|
|
1988
|
+
return { ...cached.value, ahead: null, behind: null };
|
|
1989
|
+
}
|
|
1990
|
+
return cached.value;
|
|
1959
1991
|
}
|
|
1960
1992
|
|
|
1961
1993
|
// Force a refresh now and wait for completion. Called from dashboard boot
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2049",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"test:perf": "node test/perf/managed-spawn-load.test.js",
|
|
24
24
|
"test:e2e:accept": "node test/playwright/accept-baseline.js",
|
|
25
25
|
"test:e2e:accept-force": "node test/playwright/accept-baseline.js --force",
|
|
26
|
-
"test:setup": "npx playwright install chromium"
|
|
26
|
+
"test:setup": "npx playwright install chromium",
|
|
27
|
+
"lint": "eslint dashboard/"
|
|
27
28
|
},
|
|
28
29
|
"keywords": [
|
|
29
30
|
"ai",
|
|
@@ -65,7 +66,9 @@
|
|
|
65
66
|
"@azure-devops/mcp": "2.7.0"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
|
68
|
-
"@playwright/test": "^1.58.2"
|
|
69
|
+
"@playwright/test": "^1.58.2",
|
|
70
|
+
"eslint": "^9.39.4",
|
|
71
|
+
"eslint-plugin-no-unsanitized": "^4.1.5"
|
|
69
72
|
},
|
|
70
73
|
"publishConfig": {
|
|
71
74
|
"access": "public"
|
package/playbooks/fix.md
CHANGED
|
@@ -93,11 +93,21 @@ Do NOT remove the worktree — the engine handles cleanup automatically.
|
|
|
93
93
|
|
|
94
94
|
## Resolve Review Comments
|
|
95
95
|
|
|
96
|
-
After pushing, respond to each review comment/thread
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- **
|
|
96
|
+
After pushing, respond to each review comment/thread. **Every disposition requires a reply before you resolve, close, or mark-fixed the thread — no exceptions.** Resolving a thread silently is a process violation (see "Resolving Review Threads — No Silent Closures" in `shared-rules.md`).
|
|
97
|
+
|
|
98
|
+
Pick the disposition that matches the finding and post the matching reply, then act on the thread:
|
|
99
|
+
|
|
100
|
+
- **Fixed** → Reply confirming the fix with commit SHA or `file:line` of the change, then resolve the thread.
|
|
101
|
+
- **Satisfied elsewhere** (addressed by another chunk / sibling PR / existing wiring the reviewer missed) → Reply citing the exact PR number, commit SHA, or `file:line` that satisfies it, then resolve. Example: `Satisfied by chunk 6 (PR 5216079) — ArtifactsMainScreen.kt:305 re-fires start() via LaunchedEffect on every screen enter.`
|
|
102
|
+
- **Deferred** (non-blocking nit you accept but choose not to act on now) → Reply starting with `Deferred:` and a one-line reason, then resolve. Example: `Deferred: default-off rollout switch makes this acceptable for v1; revisit if telemetry shows otherwise.`
|
|
103
|
+
- **Tracked as follow-up** → Reply with `Tracked as follow-up: W-…` and the WI link, then resolve (see `## Follow-up Dispatch` below).
|
|
104
|
+
- **Won't fix / disagree** (comment is invalid, stale, already addressed, out of scope, or harmful) → Reply with the evidence-backed rationale explaining why no code change was made. Leave the thread **active** for the reviewer to decide; do NOT resolve unilaterally.
|
|
105
|
+
|
|
106
|
+
Host-specific mechanics:
|
|
107
|
+
- **GitHub**: Reply to each review comment, then resolve the conversation for the four resolve-eligible dispositions above. Leave Won't-fix threads unresolved.
|
|
108
|
+
- **ADO**: Use `az` CLI first to reply to each thread and update status when supported; use ADO MCP only as a fallback when `az` is unavailable or insufficient. Set status to `fixed` for Fixed/Satisfied-elsewhere/Tracked-as-follow-up and `closed` for Deferred; leave `active` for Won't-fix rationale replies.
|
|
109
|
+
|
|
110
|
+
Hard rule: never resolve, close, or mark-fixed a thread without first posting a reply that explains the disposition. The chunk-5 / Caleb-Tseng / MaiLibraryViewModel thread (ADO 5215549 thread 65692221) is the canonical bad example — closed silently with no audit trail.
|
|
101
111
|
|
|
102
112
|
## Follow-up Dispatch
|
|
103
113
|
|
|
@@ -140,6 +140,35 @@ Concretely:
|
|
|
140
140
|
- If you skipped local validation, say so in the completion JSON (e.g. `tests: skipped — relying on PR pipeline`) and still exit.
|
|
141
141
|
- Holding a slot to watch a pipeline is wasted capacity; the engine has its own pipeline-monitoring path.
|
|
142
142
|
|
|
143
|
+
## Resolving Review Threads — No Silent Closures
|
|
144
|
+
|
|
145
|
+
Whenever you resolve, close, or mark-fixed any PR review thread (GitHub
|
|
146
|
+
conversation or ADO thread), you MUST first post a reply on that thread
|
|
147
|
+
explaining the disposition. This is non-negotiable across every playbook
|
|
148
|
+
(`fix`, `review`, `implement`, follow-up dispatch, anything that touches
|
|
149
|
+
a review thread).
|
|
150
|
+
|
|
151
|
+
Allowed dispositions and what the reply MUST contain:
|
|
152
|
+
- **Fixed** → reply with commit SHA or file:line of the change, then resolve.
|
|
153
|
+
- **Satisfied elsewhere** (addressed by another chunk / sibling PR / existing
|
|
154
|
+
wiring the reviewer missed) → reply citing the exact PR number, commit
|
|
155
|
+
SHA, or `file:line` that satisfies it, then resolve. Example:
|
|
156
|
+
`Satisfied by chunk 6 (PR 5216079) — ArtifactsMainScreen.kt:305
|
|
157
|
+
re-fires start() via LaunchedEffect on every screen enter.`
|
|
158
|
+
- **Deferred** (non-blocking nit you accept but choose not to act on now)
|
|
159
|
+
→ reply starting with `Deferred:` and a one-line reason, then resolve.
|
|
160
|
+
Example: `Deferred: default-off rollout switch makes this acceptable
|
|
161
|
+
for v1; revisit if telemetry shows otherwise.`
|
|
162
|
+
- **Tracked as follow-up** → reply with `Tracked as follow-up: W-…` and
|
|
163
|
+
the WI link, then resolve (see follow-up dispatch template).
|
|
164
|
+
- **Won't fix / disagree** → reply with the evidence-backed rationale;
|
|
165
|
+
leave the thread **active** for the reviewer to decide. Do NOT resolve
|
|
166
|
+
unilaterally.
|
|
167
|
+
|
|
168
|
+
Hard rule: resolving a thread with no reply comment is a process violation.
|
|
169
|
+
The chunk-5 / Caleb-Tseng / MaiLibraryViewModel thread (ADO 5215549 thread
|
|
170
|
+
65692221) is the canonical bad example — closed silently with no audit trail.
|
|
171
|
+
|
|
143
172
|
{{#github_shared_rules}}
|
|
144
173
|
## Checking PR and Build Status
|
|
145
174
|
|