@yemi33/minions 0.1.1036 → 0.1.1038

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/CHANGELOG.md CHANGED
@@ -1,5 +1,90 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1038 (2026-04-16)
4
+
5
+ ### Features
6
+ - Doc-chat performance — debounced persistence, session TTL, smart disk reads (#1164)
7
+ - split getStatus() into fast/slow state tiers with separate TTLs (#1170)
8
+ - Cache _countWorktrees() with 30s TTL (#1166)
9
+ - Pre-cache gzipped status buffer alongside JSON cache (#1171)
10
+ - parallelize ADO and GitHub PR polling with Promise.allSettled (#1172)
11
+ - route implement items to dedicated implement playbook (#1115)
12
+
13
+ ### Fixes
14
+ - allow test tasks to create PRs when files are modified
15
+ - sidecar oversized dispatch prompts to prevent dashboard OOM (closes #1167) (#1183)
16
+ - use locked write for failed-with-PR reconciliation in cleanup.js (#1169)
17
+ - prevent test from corrupting live meeting state
18
+ - scheduler enabled field falsy check treats undefined as disabled (#1160)
19
+ - update branch-dedup tests to use canonical PR IDs after merge with master (#1146)
20
+ - auto-review not firing for manually-linked PRs with autoObserve=true
21
+ - mark PR abandoned on 404 instead of silently retrying each tick
22
+ - replace undefined PROJECTS with config.projects in checkWatches (#1108)
23
+ - write permission for publish workflow
24
+ - run tests inline and post check runs for publish PRs
25
+ - add maxBuffer to all GitHub CLI spawns + paginate PR list (#1130)
26
+ - add required CI checks for PRs + update publish for auto-merge
27
+ - revert to PR merge now that stale status check is removed
28
+ - guard live review check against undefined vote/state values (#1132)
29
+ - push version bump directly to master instead of via PR
30
+ - add push-triggered CI for chore/publish branches
31
+ - publish workflow chore PRs failing to merge
32
+ - harden KB ordering
33
+ - harden audited state transitions
34
+
35
+ ### Other
36
+ - Fix audit cleanup and test isolation
37
+ - docs(sched-weekly-docs-cleanup-1776355200664): weekly documentation cleanup (#1181)
38
+ - [E2E] Dashboard & engine perf: gzip cache, tiered status, lock backoff, polling parallelization (#1174)
39
+ - Fix doc chat session isolation
40
+ - test(pipeline): add unit tests for CRUD, stage execution, run lifecycle (#1162)
41
+ - chore: test publish after removing stale status check
42
+ - chore: trigger publish test
43
+ - chore: test publish workflow fix
44
+ - chore: trigger publish workflow test
45
+
46
+ ## 0.1.1037 (2026-04-16)
47
+
48
+ ### Features
49
+ - Doc-chat performance — debounced persistence, session TTL, smart disk reads (#1164)
50
+ - split getStatus() into fast/slow state tiers with separate TTLs (#1170)
51
+ - Cache _countWorktrees() with 30s TTL (#1166)
52
+ - Pre-cache gzipped status buffer alongside JSON cache (#1171)
53
+ - parallelize ADO and GitHub PR polling with Promise.allSettled (#1172)
54
+ - route implement items to dedicated implement playbook (#1115)
55
+
56
+ ### Fixes
57
+ - allow test tasks to create PRs when files are modified
58
+ - sidecar oversized dispatch prompts to prevent dashboard OOM (closes #1167) (#1183)
59
+ - use locked write for failed-with-PR reconciliation in cleanup.js (#1169)
60
+ - prevent test from corrupting live meeting state
61
+ - scheduler enabled field falsy check treats undefined as disabled (#1160)
62
+ - update branch-dedup tests to use canonical PR IDs after merge with master (#1146)
63
+ - auto-review not firing for manually-linked PRs with autoObserve=true
64
+ - mark PR abandoned on 404 instead of silently retrying each tick
65
+ - replace undefined PROJECTS with config.projects in checkWatches (#1108)
66
+ - write permission for publish workflow
67
+ - run tests inline and post check runs for publish PRs
68
+ - add maxBuffer to all GitHub CLI spawns + paginate PR list (#1130)
69
+ - add required CI checks for PRs + update publish for auto-merge
70
+ - revert to PR merge now that stale status check is removed
71
+ - guard live review check against undefined vote/state values (#1132)
72
+ - push version bump directly to master instead of via PR
73
+ - add push-triggered CI for chore/publish branches
74
+ - publish workflow chore PRs failing to merge
75
+ - harden KB ordering
76
+ - harden audited state transitions
77
+
78
+ ### Other
79
+ - docs(sched-weekly-docs-cleanup-1776355200664): weekly documentation cleanup (#1181)
80
+ - [E2E] Dashboard & engine perf: gzip cache, tiered status, lock backoff, polling parallelization (#1174)
81
+ - Fix doc chat session isolation
82
+ - test(pipeline): add unit tests for CRUD, stage execution, run lifecycle (#1162)
83
+ - chore: test publish after removing stale status check
84
+ - chore: trigger publish test
85
+ - chore: test publish workflow fix
86
+ - chore: trigger publish workflow test
87
+
3
88
  ## 0.1.1036 (2026-04-16)
4
89
 
5
90
  ### Features
@@ -14,7 +14,7 @@
14
14
  - Creating the structured PRD in JSON format
15
15
  - Gap analysis: what was built vs. what the codebase instructions describe vs. what's missing
16
16
  - Feature inventory: cataloguing existing agent capabilities, then identifying what's absent
17
- - Producing `docs/prd-gaps.json` with structured feature records
17
+ - Producing PRD JSON files in `{{team_root}}/prd/` with structured feature records (one file per plan; filename matches the source plan slug)
18
18
  - Flagging unknowns and ambiguities in the requirements
19
19
 
20
20
  ## PRD JSON Output Format
@@ -43,7 +43,7 @@
43
43
  - Read Dallas's build summary from `{{team_root}}/notes/inbox/dallas-build-*.md`
44
44
  - Cross-reference against all `docs/`, agent `CLAUDE.md` files, and prototype instructions
45
45
  - Be exhaustive on missing features — better to over-document than under-document
46
- - Output the JSON to `docs/prd-gaps.json`
46
+ - Output the JSON to `{{team_root}}/prd/<plan-slug>.json` (the engine's `materializePlansAsWorkItems()` reads from that directory)
47
47
 
48
48
  ## Boundaries
49
49
 
@@ -37,13 +37,13 @@ Skips PRs where `status !== "active"`.
37
37
 
38
38
  ### Source 2: PRD Gap Analysis (via `materializePlansAsWorkItems`)
39
39
 
40
- PRD items flow through `materializePlansAsWorkItems()`, which scans `~/.minions/prd/*.json` for PRD files with `missing`/`planned` items and creates work items in the target project's queue.
40
+ PRD items flow through `materializePlansAsWorkItems()`, which scans `~/.minions/prd/*.json` for PRD files with `missing` / `updated` / `planned` items and creates work items in the target project's queue.
41
41
 
42
- **Reads:** `<project>/docs/prd-gaps.json` (or custom path from `workSources.prd.path`)
42
+ **Reads:** `~/.minions/prd/*.json` — the central PRD directory. (Legacy `<project>/docs/prd-gaps.json` paths are no longer scanned.)
43
43
 
44
44
  | Item State | Action | Dispatch Type |
45
45
  |------------|--------|---------------|
46
- | `status: "missing"` or `"planned"` | Queue implementation | `implement` |
46
+ | `status: "missing"` or `"updated"` | Queue implementation (re-opens any existing done WI) | `implement` |
47
47
  | `estimated_complexity: "large"` | Routes to `implement:large` (prefers Rebecca) | `implement:large` |
48
48
 
49
49
  ### Source 3: Per-Project Work Items (`discoverFromWorkItems`)
@@ -165,14 +165,19 @@ Item found
165
165
  `resolveAgent()` parses `routing.md` to pick the right agent:
166
166
 
167
167
  ```
168
- routing.md table:
168
+ routing.md table (see the file for the authoritative list):
169
169
  implement → dallas (fallback: ralph)
170
170
  implement:large → rebecca (fallback: dallas)
171
171
  review → ripley (fallback: lambert)
172
- fix → _author_ (fallback: dallas) ← routes to PR author
173
- analyze lambert (fallback: rebecca)
172
+ fix → _author_ (fallback: _any_) ← routes to PR author, any idle as fallback
173
+ plan ripley (fallback: rebecca)
174
+ plan-to-prd → lambert (fallback: rebecca)
174
175
  explore → ripley (fallback: rebecca)
175
176
  test → dallas (fallback: ralph)
177
+ ask → ripley (fallback: rebecca)
178
+ verify → dallas (fallback: ralph)
179
+ decompose → ripley (fallback: rebecca)
180
+ meeting → ripley (fallback: lambert)
176
181
  ```
177
182
 
178
183
  Resolution order:
@@ -216,7 +221,7 @@ git worktree add <rootDir>/../worktrees/<branch> -b <branch> <mainBranch>
216
221
  ```
217
222
  - Branch names are sanitized (alphanumeric, dots, hyphens, slashes only, max 200 chars)
218
223
  - If worktree fails for implement/fix → item marked as error, moved to completed
219
- - If worktree fails for review/analyze → falls back to rootDir (read-only tasks)
224
+ - If worktree fails for review/explore/ask → falls back to rootDir (read-only tasks)
220
225
 
221
226
  ### 3. Render Playbook
222
227
  ```
@@ -291,8 +296,8 @@ The dashboard exposes a unified input box at `http://localhost:7331` that parses
291
296
  | `@agent` | Assigns to a specific agent (sets `item.agent`) |
292
297
  | `@everyone` | Fan-out to all agents (sets `scope: 'fan-out'`) |
293
298
  | `!high` / `!low` | Sets priority (default: medium) |
294
- | `/decide` | Creates a decision (appended to `notes.md`) |
295
- | `/prd` | Creates a PRD item (appended to `prd-gaps.json`) |
299
+ | `/note` | Writes a note to `notes/inbox/` for consolidation into `notes.md` |
300
+ | `/plan` | Creates a plan draft (appended to `plans/`) |
296
301
  | `#project` | Targets a specific project queue |
297
302
 
298
303
  Work type is auto-detected from keywords (fix, explore, test, review → implement as fallback). The `@agent` assignment flows through to the engine: `item.agent || resolveAgent(workType, config)`.
@@ -305,20 +310,20 @@ Work type is auto-detected from keywords (fix, explore, test, review → impleme
305
310
 
306
311
  ┌──────────┼──────────┐
307
312
  ▼ ▼ ▼
308
- work-items decisions prd-gaps
309
- .json .md .json
313
+ work-items notes/ plans/
314
+ .json inbox/*.md *.md
310
315
 
311
316
  Per-project sources: Central engine: Agents:
312
317
 
313
318
  work-items.json ──┐
314
- prd-gaps.json ────┤
315
319
  pull-requests.json┤ discoverWork() dispatch.json
316
320
  docs/**/*.md (specs)┤ (each tick) ┌──────────┐
317
321
  │ │ │ pending │
318
322
  ~/.minions/ │ │ │ active │
319
323
  work-items.json ┤ │ │ completed │
320
- plans/*.md ─────┘ └─────┬────┘
321
- addToDispatch()─────────┘
324
+ prd/*.json ─────┤ └─────┬────┘
325
+ plans/*.md ─────┘ ▼ │
326
+ addToDispatch()────────┘
322
327
 
323
328
  ADO REST API ─── pollPrBuildStatus() ──► pull-requests.json
324
329
  (every 6min) (buildStatus field) │
@@ -390,20 +395,12 @@ All discovery behavior is controlled via `config.json`:
390
395
  "name": "MyProject",
391
396
  "localPath": "C:/Users/you/MyProject",
392
397
  "workSources": {
393
- "prd": {
394
- "enabled": true,
395
- "path": "docs/prd-gaps.json",
396
- "itemFilter": { "status": ["missing", "planned"] },
397
- "cooldownMinutes": 30
398
- },
399
398
  "pullRequests": {
400
399
  "enabled": true,
401
- "path": "projects/<name>/pull-requests.json",
402
400
  "cooldownMinutes": 30
403
401
  },
404
402
  "workItems": {
405
403
  "enabled": true,
406
- "path": "projects/<name>/work-items.json",
407
404
  "cooldownMinutes": 0
408
405
  }
409
406
  }
@@ -11,9 +11,9 @@ Click the **CC** button in the top-right header of the dashboard. A slide-out ch
11
11
  CC maintains a true multi-turn session using Claude CLI's `--resume` flag. Unlike a typical stateless API call, each message resumes the same conversation — Claude retains full history including tool calls, intermediate reasoning, and file contents from prior turns.
12
12
 
13
13
  **Session lifecycle:**
14
- - **Created** on first message (or after expiry/new-session)
14
+ - **Created** on first message (or after the system prompt changes, or when you click **New Session**)
15
15
  - **Resumed** on subsequent messages via `--resume <sessionId>`
16
- - **Expires** after 2 hours of inactivity
16
+ - **Invalidated** only when the CC system prompt changes — detected by hashing `CC_STATIC_SYSTEM_PROMPT` into `_ccPromptHash` and comparing on each call. There is no time-based expiry and no turn cap (`CC_SESSION_MAX_TURNS = Infinity`).
17
17
  - **Persisted** to `engine/cc-session.json` — survives dashboard restarts
18
18
  - **Frontend messages** saved to `localStorage` — survive page refresh
19
19
 
@@ -108,7 +108,7 @@ User message (CC panel, doc modal, or steer)
108
108
 
109
109
  POST /api/command-center (or /api/doc-chat, /api/steer-document)
110
110
 
111
- ├── Validate session (expiry check)
111
+ ├── Validate session (prompt-hash check — invalidate if `_ccPromptHash` drifted)
112
112
  ├── Build dynamic state preamble (buildCCStatePreamble)
113
113
  ├── callLLM() with sessionId (resume) or without (new)
114
114
  │ model: sonnet
package/engine/cleanup.js CHANGED
@@ -448,17 +448,19 @@ function runCleanup(config, verbose = false) {
448
448
  try {
449
449
  const wiPath = projectWorkItemsPath(project);
450
450
  let reconciled = 0;
451
- mutateWorkItems(wiPath, items => {
452
- for (const item of items) {
453
- if (item.status === shared.WI_STATUS.FAILED && item._pr) {
454
- item.status = shared.WI_STATUS.DONE;
455
- if (item.failReason) delete item.failReason;
456
- if (item.failedAt) delete item.failedAt;
457
- if (!item.completedAt) item.completedAt = shared.ts();
458
- reconciled++;
451
+ mutateWorkItems(wiPath, items => {
452
+ for (const item of items) {
453
+ if (item.status === shared.WI_STATUS.FAILED && item._pr) {
454
+ item.status = shared.WI_STATUS.DONE;
455
+ if (item.failReason) delete item.failReason;
456
+ if (item.failedAt) delete item.failedAt;
457
+ delete item._retryCount;
458
+ delete item._pendingReason;
459
+ if (!item.completedAt) item.completedAt = shared.ts();
460
+ reconciled++;
461
+ }
459
462
  }
460
- }
461
- });
463
+ });
462
464
  if (reconciled > 0) {
463
465
  log('info', `Reconciled ${reconciled} failed-with-PR item(s) → done in ${project.name}`);
464
466
  }
@@ -472,15 +474,17 @@ function runCleanup(config, verbose = false) {
472
474
  try {
473
475
  const wiPath = projectWorkItemsPath(project);
474
476
  let migrated = 0;
475
- mutateWorkItems(wiPath, items => {
476
- for (const item of items) {
477
- if (LEGACY_DONE_ALIASES.has(item.status)) {
478
- item.status = shared.WI_STATUS.DONE;
479
- delete item._pendingReason;
480
- migrated++;
477
+ mutateWorkItems(wiPath, items => {
478
+ for (const item of items) {
479
+ if (LEGACY_DONE_ALIASES.has(item.status)) {
480
+ item.status = shared.WI_STATUS.DONE;
481
+ delete item._retryCount;
482
+ delete item._pendingReason;
483
+ if (!item.completedAt) item.completedAt = shared.ts();
484
+ migrated++;
485
+ }
481
486
  }
482
- }
483
- });
487
+ });
484
488
  if (migrated > 0) {
485
489
  log('info', `Migrated ${migrated} legacy status(es) → done in ${project.name} work items`);
486
490
  }
@@ -494,7 +498,9 @@ function runCleanup(config, verbose = false) {
494
498
  for (const item of items) {
495
499
  if (LEGACY_DONE_ALIASES.has(item.status)) {
496
500
  item.status = shared.WI_STATUS.DONE;
501
+ delete item._retryCount;
497
502
  delete item._pendingReason;
503
+ if (!item.completedAt) item.completedAt = shared.ts();
498
504
  migrated++;
499
505
  }
500
506
  }
@@ -503,6 +509,36 @@ function runCleanup(config, verbose = false) {
503
509
  log('info', `Migrated ${migrated} legacy status(es) → done in central work items`);
504
510
  }
505
511
  } catch (e) { log('warn', 'migrate central legacy statuses: ' + e.message); }
512
+
513
+ // 6c. Strip stale retry metadata from completed work items
514
+ cleaned.doneRetryCounts = 0;
515
+ for (const project of projects) {
516
+ try {
517
+ const wiPath = projectWorkItemsPath(project);
518
+ mutateWorkItems(wiPath, items => {
519
+ for (const item of items) {
520
+ if (item.status === shared.WI_STATUS.DONE && item._retryCount !== undefined) {
521
+ delete item._retryCount;
522
+ cleaned.doneRetryCounts++;
523
+ }
524
+ }
525
+ });
526
+ } catch (e) { log('warn', 'cleanup done retry metadata: ' + e.message); }
527
+ }
528
+ try {
529
+ const centralPath = path.join(MINIONS_DIR, 'work-items.json');
530
+ mutateWorkItems(centralPath, items => {
531
+ for (const item of items) {
532
+ if (item.status === shared.WI_STATUS.DONE && item._retryCount !== undefined) {
533
+ delete item._retryCount;
534
+ cleaned.doneRetryCounts++;
535
+ }
536
+ }
537
+ });
538
+ } catch (e) { log('warn', 'cleanup central done retry metadata: ' + e.message); }
539
+ if (cleaned.doneRetryCounts > 0) {
540
+ log('info', `Cleanup: cleared ${cleaned.doneRetryCounts} stale retry count(s) from done work items`);
541
+ }
506
542
  // PRD items (missing_features[].status)
507
543
  try {
508
544
  let prdDirEntries;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1036",
3
+ "version": "0.1.1038",
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"
@@ -1,32 +0,0 @@
1
- # Verification: Fix silent state-loss bugs in dispatch persistence, lifecycle races, and checkpoint handling
2
-
3
- **Plan:** minions-2026-04-01-5.json
4
- **Date:** 2026-04-11
5
- **Verified by:** Ripley
6
-
7
- ## Results Summary
8
-
9
- | Item | PR | Verdict |
10
- |------|-----|---------|
11
- | P-b3c9e4f6: needs-human-review skip filter | PR-55 (merged) | PASS |
12
- | P-f7a2d8e1: dispatch persistence gate | PR-57 (merged) | PASS |
13
- | P-d5e1a7b3: TOCTOU races in lifecycle | PR-56 (merged) | PASS |
14
- | P-a8f4c2d9: fan-out checkpoint handling | PR-58 (merged) | REGRESSION |
15
- | P-e6b0d3a5: checkpoint cleanup + _pendingReason | PR-60 (merged) | REGRESSION |
16
- | P-c1d7f9e8: resolveWiPath export | PR-59 (closed) | NOT MERGED |
17
-
18
- **Tests:** 1463 passed, 0 failed, 2 skipped
19
-
20
- ## Regressions
21
-
22
- Two items (P-a8f4c2d9, P-e6b0d3a5) were correctly merged but their changes were
23
- subsequently lost during engine.js refactors that rewrote `discoverCentralWorkItems`
24
- to use a mutations Map pattern. The original direct-item-mutation code was not carried
25
- forward.
26
-
27
- Affected features:
28
- 1. Fan-out checkpoint.json reading (engine.js:2484-2487 missing `worktreePath`)
29
- 2. Checkpoint file deletion after consumption (no `unlinkSync` calls remain)
30
- 3. `_pendingReason` clearing on fan-out/single-agent dispatch
31
-
32
- See full report in `prd/guides/verify-minions-2026-04-01-5.md` (runtime, gitignored).