@yemi33/minions 0.1.1861 → 0.1.1863
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 +10 -0
- package/engine/spawn-agent.js +34 -4
- package/package.json +1 -1
- package/playbooks/implement.md +10 -8
- package/playbooks/shared-rules.md +43 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.1863 (2026-05-11)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- push early + targeted-only verify, fully avoid runtime CLI crash trigger
|
|
7
|
+
|
|
8
|
+
## 0.1.1862 (2026-05-11)
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
- use 'exit' event for OS exit code + dedup sentinel; warn agents off .cmd shims
|
|
12
|
+
|
|
3
13
|
## 0.1.1861 (2026-05-10)
|
|
4
14
|
|
|
5
15
|
### Fixes
|
package/engine/spawn-agent.js
CHANGED
|
@@ -409,11 +409,38 @@ function main() {
|
|
|
409
409
|
}, MCP_STARTUP_TIMEOUT);
|
|
410
410
|
proc.stdout.once('data', () => { gotFirstOutput = true; clearTimeout(startupTimer); });
|
|
411
411
|
|
|
412
|
+
// Track the real OS exit code via the 'exit' event. Node's 'close' event
|
|
413
|
+
// can report code=0 on Windows when the OS-level exit was non-zero
|
|
414
|
+
// (observed empirically with both Claude Code CLI and Copilot CLI exiting
|
|
415
|
+
// with OS exit code 1 silently during long PowerShell tool calls — procdump
|
|
416
|
+
// captured the 1, but the engine's onAgentClose saw the spawn-agent's parent
|
|
417
|
+
// pipe report code=0). The 'exit' event fires earlier and carries the OS code
|
|
418
|
+
// more reliably; 'close' waits for stdio teardown which can race.
|
|
419
|
+
let realExitFromEvent = null;
|
|
420
|
+
let realSignalFromEvent = null;
|
|
421
|
+
let sentinelWritten = false;
|
|
422
|
+
proc.on('exit', (code, signal) => {
|
|
423
|
+
if (Number.isInteger(code)) realExitFromEvent = code;
|
|
424
|
+
if (signal) realSignalFromEvent = signal;
|
|
425
|
+
});
|
|
412
426
|
proc.on('close', (code, signal) => {
|
|
413
427
|
clearTimeout(startupTimer);
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
|
|
428
|
+
// Prefer the 'exit' event's code/signal when present — see note above.
|
|
429
|
+
const effectiveCode = (realExitFromEvent != null) ? realExitFromEvent : code;
|
|
430
|
+
const effectiveSignal = realSignalFromEvent || signal;
|
|
431
|
+
const exitCode = normalizeRuntimeExit(effectiveCode, effectiveSignal);
|
|
432
|
+
if (sentinelWritten) {
|
|
433
|
+
// Defense-in-depth: never write a duplicate sentinel. We observed pairs
|
|
434
|
+
// of [process-exit] code=0 lines in live-output.log across many failed
|
|
435
|
+
// runs, which suggests close has fired twice in some edge cases (e.g.,
|
|
436
|
+
// shim re-launch on Windows). One sentinel per spawn is the contract.
|
|
437
|
+
fs.appendFileSync(debugPath, `EXIT (duplicate close, skipping sentinel): code=${exitCode}${effectiveSignal ? ` signal=${effectiveSignal}` : ''}\n`);
|
|
438
|
+
process.exit(exitCode);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
sentinelWritten = true;
|
|
442
|
+
const sentinelResult = writeProcessExitSentinel({ exitCode, signal: effectiveSignal });
|
|
443
|
+
fs.appendFileSync(debugPath, `EXIT: code=${exitCode}${effectiveSignal ? ` signal=${effectiveSignal}` : ''} (close=${code} exit=${realExitFromEvent})\nSTDERR: ${stderrBuf.slice(0, 500)}\n`);
|
|
417
444
|
if (!sentinelResult.fileWritten) {
|
|
418
445
|
fs.appendFileSync(debugPath, `EXIT SENTINEL: file write failed for ${process.env.MINIONS_LIVE_OUTPUT_PATH}\n`);
|
|
419
446
|
}
|
|
@@ -421,7 +448,10 @@ function main() {
|
|
|
421
448
|
});
|
|
422
449
|
proc.on('error', (err) => {
|
|
423
450
|
fs.appendFileSync(debugPath, `ERROR: ${err.message}\n`);
|
|
424
|
-
|
|
451
|
+
if (!sentinelWritten) {
|
|
452
|
+
sentinelWritten = true;
|
|
453
|
+
writeProcessExitSentinel({ exitCode: 1 });
|
|
454
|
+
}
|
|
425
455
|
process.exit(1);
|
|
426
456
|
});
|
|
427
457
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1863",
|
|
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"
|
package/playbooks/implement.md
CHANGED
|
@@ -59,21 +59,23 @@ Deliver this as if the user asked you directly in a CLI:
|
|
|
59
59
|
You are already running in a git worktree on branch `{{branch_name}}`. Do NOT create additional worktrees — the engine pre-created one for you.
|
|
60
60
|
Do NOT remove the worktree — the engine handles cleanup automatically.
|
|
61
61
|
|
|
62
|
-
## Validation
|
|
62
|
+
## Validation — TARGETED ONLY, before publish
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Prove the change with the repo's own documented checks, BUT keep the
|
|
65
|
+
verification surface narrow:
|
|
65
66
|
|
|
66
67
|
- Use the project's source of truth for commands: `CLAUDE.md`, README, package scripts, Makefile, or equivalent build config.
|
|
67
|
-
- Run the
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
68
|
+
- **Run only TARGETED tests covering the code you changed.** A single test file or a single test name is enough. Examples: `node test/unit/<my-file>.test.js`, `python -m pytest tests/test_my_module.py::test_my_case`, `cargo test --test my_test`.
|
|
69
|
+
- **Do NOT run the full project test suite (`node test/unit.test.js`, `npm test`, `yarn test`, etc.) as a verification step.** The full-suite run in a long agent session is the primary trigger for the runtime CLI crash documented in shared-rules.md. The engine and PR CI handle full-suite regression detection — your job is to verify the code you wrote works, not to re-prove the entire suite.
|
|
70
|
+
- Use a quick `node --check <file>` (or equivalent) for syntax validation — cheap and never crashes.
|
|
71
|
+
- Capture the exact targeted commands run and the meaningful result in the PR description or completion report.
|
|
72
|
+
- Do not publish changes with a broken build or failing tests that you introduced; if your targeted check fails, fix it before pushing.
|
|
71
73
|
|
|
72
74
|
Long builds, dependency installs, and tests may be quiet for several minutes. Let the normal CLI command run naturally; do not add artificial heartbeat output or split commands just to show progress.
|
|
73
75
|
|
|
74
|
-
## Publish
|
|
76
|
+
## Publish — push EARLY, before any expansion of verification scope
|
|
75
77
|
|
|
76
|
-
After
|
|
78
|
+
After targeted validation passes, commit only the relevant files and push this branch IMMEDIATELY. This protects the work product: a runtime CLI crash on any later command cannot lose code that's already on the remote.
|
|
77
79
|
|
|
78
80
|
```bash
|
|
79
81
|
git add <specific files>
|
|
@@ -74,6 +74,49 @@ Use `status: "failed"` plus an accurate `failure_class`, `retryable`, and `needs
|
|
|
74
74
|
|
|
75
75
|
**No-op completions:** when you correctly decline to do the work — the change was already shipped on master, the dispatch premise is wrong, the flagged review comment is your own author-notes, etc. — write `status: "success"`, `pr: "N/A"`, AND add `"noop": true`. The engine treats `noop: true` as the canonical signal that no PR was expected, marks the work item done with the rationale surfaced in `_noopReason` for the dashboard, and skips the missing-PR-attachment failure. Without `noop: true`, an empty PR will still be flagged as a silent failure and auto-retried up to `maxRetries` times.
|
|
76
76
|
|
|
77
|
+
## CRITICAL RULE: Never run `npm`/`yarn`/`pnpm` test scripts via the shell tool
|
|
78
|
+
|
|
79
|
+
**You will crash silently if you run `npm test`, `npm run <anything>`, `yarn test`,
|
|
80
|
+
`pnpm test`, `npx mocha`, `npx jest`, `npx vitest`, or any package-manager
|
|
81
|
+
script wrapper from your shell/PowerShell tool.** The runtime CLI (whether
|
|
82
|
+
Copilot CLI or Claude Code CLI) deterministically exits with OS code 1 mid-
|
|
83
|
+
conversation when invoking a `.cmd` shim that spawns a child node process
|
|
84
|
+
producing substantial stdout. This is confirmed by controlled reproductions
|
|
85
|
+
on both runtimes (2026-05-11) — including with full memory dumps. You will
|
|
86
|
+
NOT see an error message; the engine will mark your work as "phantom
|
|
87
|
+
completion" and the WI will fail with no PR.
|
|
88
|
+
|
|
89
|
+
This rule overrides any contradictory guidance you might find elsewhere
|
|
90
|
+
(including playbook instructions to "run the full suite"). The playbook
|
|
91
|
+
wants the test signal; it does NOT want you to crash trying to get it.
|
|
92
|
+
Use direct binary invocations every time:
|
|
93
|
+
|
|
94
|
+
| ❌ never | ✅ instead |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `npm test` | `node test/unit.test.js` (or whatever the project's `test` script wraps) |
|
|
97
|
+
| `npm run <script>` | The underlying command — check `package.json` `scripts.<script>` |
|
|
98
|
+
| `yarn test`, `pnpm test` | Same — find the underlying `node ...` invocation |
|
|
99
|
+
| `npx mocha tests/` | `node node_modules/mocha/bin/mocha.js tests/` |
|
|
100
|
+
| `npx jest <file>` | `node node_modules/jest/bin/jest.js <file>` |
|
|
101
|
+
| `npx vitest run` | `node node_modules/vitest/vitest.mjs run` |
|
|
102
|
+
|
|
103
|
+
Non-`.cmd` test runners are safe (no shim chain):
|
|
104
|
+
|
|
105
|
+
- `python -m pytest tests/test_foo.py` ← Python uses `.exe`, not `.cmd`
|
|
106
|
+
- `cargo test --test foo` ← Rust cargo is `.exe`
|
|
107
|
+
- `dotnet test path/to/Project.Tests.csproj` ← .NET dotnet is `.exe`
|
|
108
|
+
- `go test ./...` ← Go is `.exe`
|
|
109
|
+
|
|
110
|
+
**Targeted single-file tests are STRONGLY preferred over full-suite runs**
|
|
111
|
+
regardless of how you invoke them. They're faster, smaller in output, and
|
|
112
|
+
produce the same regression signal for the code you actually changed.
|
|
113
|
+
|
|
114
|
+
If the project's test setup truly requires `npm test` (e.g., it sets env
|
|
115
|
+
vars in a hook), report this in your completion block and use the closest
|
|
116
|
+
direct equivalent anyway. Do not invoke the wrapper — verification you
|
|
117
|
+
don't get because you crashed is worse than verification you skipped
|
|
118
|
+
deliberately.
|
|
119
|
+
|
|
77
120
|
## Long-Running Commands
|
|
78
121
|
|
|
79
122
|
Builds, dependency installs, tests, and local servers can be quiet for long periods. Run the repo's normal CLI commands and let them finish; do not add artificial progress output, heartbeat loops, or command-specific workarounds just to keep Minions active.
|