@yemi33/minions 0.1.651 → 0.1.652
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 +5 -0
- package/engine/shared.js +26 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/engine/shared.js
CHANGED
|
@@ -303,9 +303,9 @@ function writeToInbox(agentId, slug, content, _inboxDir) {
|
|
|
303
303
|
if (existing) return false;
|
|
304
304
|
const noteId = `NOTE-${uid()}`;
|
|
305
305
|
// Inject structured ID as YAML frontmatter if content doesn't already have it
|
|
306
|
-
const hasFrontmatter = content
|
|
306
|
+
const hasFrontmatter = /^\s*---[\r\n]/.test(content);
|
|
307
307
|
const tagged = hasFrontmatter
|
|
308
|
-
? content.replace(
|
|
308
|
+
? content.replace(/^\s*---[\r\n]+/, `---\nid: ${noteId}\n`)
|
|
309
309
|
: `---\nid: ${noteId}\nagent: ${agentId}\ndate: ${dateStamp()}\n---\n\n${content}`;
|
|
310
310
|
const filePath = path.join(inboxDir, `${prefix}.md`);
|
|
311
311
|
safeWrite(filePath, tagged);
|
|
@@ -825,7 +825,9 @@ function mutatePullRequests(filePath, mutator) {
|
|
|
825
825
|
/**
|
|
826
826
|
* Remove a git worktree, falling back to fs.rmSync if git fails (e.g., locked on Windows).
|
|
827
827
|
* Only removes directories under worktreeRoot to prevent accidental deletion.
|
|
828
|
+
* Tracks persistent failures to avoid retrying locked paths every cleanup cycle.
|
|
828
829
|
*/
|
|
830
|
+
const _removeWorktreeFailures = new Map(); // path → { count, lastAttempt }
|
|
829
831
|
function removeWorktree(wtPath, gitRoot, worktreeRoot) {
|
|
830
832
|
const resolved = path.resolve(wtPath);
|
|
831
833
|
const resolvedRoot = path.resolve(worktreeRoot) + path.sep;
|
|
@@ -833,13 +835,19 @@ function removeWorktree(wtPath, gitRoot, worktreeRoot) {
|
|
|
833
835
|
log('warn', `removeWorktree: refusing to remove ${wtPath} — not under ${worktreeRoot}`);
|
|
834
836
|
return false;
|
|
835
837
|
}
|
|
838
|
+
// Skip paths that failed 3+ times — retry after 1 hour cooldown
|
|
839
|
+
const prior = _removeWorktreeFailures.get(resolved);
|
|
840
|
+
if (prior && prior.count >= 3 && Date.now() - prior.lastAttempt < 3600000) return false;
|
|
841
|
+
|
|
836
842
|
try {
|
|
837
843
|
exec(`git worktree remove "${wtPath}" --force`, { cwd: gitRoot, stdio: 'pipe', timeout: 15000, windowsHide: true });
|
|
844
|
+
_removeWorktreeFailures.delete(resolved);
|
|
838
845
|
return true;
|
|
839
846
|
} catch (gitErr) {
|
|
840
847
|
try {
|
|
841
848
|
fs.rmSync(resolved, { recursive: true, force: true });
|
|
842
849
|
try { exec('git worktree prune', { cwd: gitRoot, stdio: 'pipe', timeout: 10000, windowsHide: true }); } catch {}
|
|
850
|
+
_removeWorktreeFailures.delete(resolved);
|
|
843
851
|
return true;
|
|
844
852
|
} catch (rmErr) {
|
|
845
853
|
// Windows EPERM: a process may hold file handles — try rd /s /q as fallback
|
|
@@ -847,15 +855,28 @@ function removeWorktree(wtPath, gitRoot, worktreeRoot) {
|
|
|
847
855
|
try {
|
|
848
856
|
exec(`rd /s /q "${resolved}"`, { stdio: 'pipe', timeout: 15000, windowsHide: true });
|
|
849
857
|
try { exec('git worktree prune', { cwd: gitRoot, stdio: 'pipe', timeout: 10000, windowsHide: true }); } catch {}
|
|
858
|
+
_removeWorktreeFailures.delete(resolved);
|
|
850
859
|
return true;
|
|
851
860
|
} catch {}
|
|
852
861
|
}
|
|
853
|
-
|
|
862
|
+
const fail = _removeWorktreeFailures.get(resolved) || { count: 0, lastAttempt: 0 };
|
|
863
|
+
fail.count++;
|
|
864
|
+
fail.lastAttempt = Date.now();
|
|
865
|
+
_removeWorktreeFailures.set(resolved, fail);
|
|
866
|
+
if (fail.count <= 3) log('warn', `removeWorktree: failed for ${wtPath} (attempt ${fail.count}/3): ${rmErr.message}`);
|
|
854
867
|
return false;
|
|
855
868
|
}
|
|
856
869
|
}
|
|
857
870
|
}
|
|
858
871
|
|
|
872
|
+
function slugify(text, maxLen = 50) {
|
|
873
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, maxLen);
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
function formatTranscriptEntry(t) {
|
|
877
|
+
return '### ' + (t.agent || 'agent') + ' (' + (t.type || '') + ', Round ' + (t.round || '?') + ')\n\n' + (t.content || '');
|
|
878
|
+
}
|
|
879
|
+
|
|
859
880
|
module.exports = {
|
|
860
881
|
MINIONS_DIR,
|
|
861
882
|
PR_LINKS_PATH,
|
|
@@ -912,6 +933,8 @@ module.exports = {
|
|
|
912
933
|
removeWorktree,
|
|
913
934
|
LOCK_STALE_MS,
|
|
914
935
|
flushLogs,
|
|
936
|
+
slugify,
|
|
937
|
+
formatTranscriptEntry,
|
|
915
938
|
_logBuffer, // exported for testing
|
|
916
939
|
};
|
|
917
940
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.652",
|
|
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"
|