@yemi33/minions 0.1.2360 → 0.1.2361

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.
@@ -1163,18 +1163,33 @@ async function discoverPipelineWork(config) {
1163
1163
  }).join('\n\n');
1164
1164
  }
1165
1165
 
1166
- // Scan for inbox/archive notes created by this stage's agents
1166
+ // Scan for inbox/archive notes created by this stage's agents.
1167
+ // stageWiIds are scoped to this run (work-item ids embed the unique
1168
+ // run id), so matching on them alone is safe. stage.id/pipeline.id
1169
+ // are STATIC across every run of a recurring pipeline, so a bare
1170
+ // substring match on them would match every historical note ever
1171
+ // written for that stage/pipeline name (W-mrcr6do0001404e6). Keep
1172
+ // that fallback only as a safety net for notes that don't embed a
1173
+ // WI id, and gate it on mtime >= this run's startedAt so it can
1174
+ // never pick up notes older than the current run.
1167
1175
  try {
1168
1176
  const notesDirs = [
1169
1177
  NOTES_INBOX_DIR,
1170
1178
  NOTES_ARCHIVE_DIR,
1171
1179
  ];
1172
1180
  const stageWiIds = stageState.artifacts?.workItems || [];
1181
+ const runStartedAt = activeRun.startedAt ? new Date(activeRun.startedAt).getTime() : 0;
1173
1182
  const notes = [];
1174
1183
  for (const dir of notesDirs) {
1175
1184
  for (const f of safeReadDir(dir).filter(n => n.endsWith('.md'))) {
1176
- if (stageWiIds.some(id => f.includes(id)) || f.includes(stage.id) || f.includes(pipeline.id)) {
1185
+ if (stageWiIds.some(id => f.includes(id))) {
1177
1186
  notes.push(f);
1187
+ continue;
1188
+ }
1189
+ if (f.includes(stage.id) || f.includes(pipeline.id)) {
1190
+ let mtime = 0;
1191
+ try { mtime = fs.statSync(path.join(dir, f)).mtimeMs; } catch { /* file may have vanished */ }
1192
+ if (mtime >= runStartedAt) notes.push(f);
1178
1193
  }
1179
1194
  }
1180
1195
  }
package/engine.js CHANGED
@@ -6569,23 +6569,33 @@ function restoreHijackedOperatorCheckouts(config) {
6569
6569
  if (!localPath || !fs.existsSync(localPath)) continue;
6570
6570
  if (shared.resolveCheckoutMode(project) === shared.CHECKOUT_MODES.LIVE) continue; // live-mode: feature branch is intentional
6571
6571
  const main = project.mainBranch || 'main';
6572
- if (String(execSilent('git rev-parse --is-inside-work-tree', { cwd: localPath }) || '').trim() !== 'true') continue;
6573
- const cur = String(execSilent('git rev-parse --abbrev-ref HEAD', { cwd: localPath }) || '').trim();
6572
+ const opts = { cwd: localPath };
6573
+ // W-mrcvh5hw000o6cf1: use the argv-form (shell: false) git helper instead of
6574
+ // execSilent(). execSilent() shells out via cmd.exe, which cannot chdir into
6575
+ // a UNC path (`//wsl.localhost/...`, `\\server\share\...`) — it silently
6576
+ // falls back to the Windows directory and every git call then fails with
6577
+ // "fatal: not a git repository", every tick, forever, for WSL/UNC-hosted
6578
+ // projects. shellSafeGitSync spawns git.exe directly (execFileSync,
6579
+ // shell:false) so `cwd` is honored even for UNC paths.
6580
+ let isRepo;
6581
+ try { isRepo = String(shared.shellSafeGitSync(['rev-parse', '--is-inside-work-tree'], opts) || '').trim(); }
6582
+ catch { continue; } // not a git repo (or transiently unreachable) — nothing to restore, skip quietly
6583
+ if (isRepo !== 'true') continue;
6584
+ const cur = String(shared.shellSafeGitSync(['rev-parse', '--abbrev-ref', 'HEAD'], opts) || '').trim();
6574
6585
  if (!cur || cur === 'HEAD' || cur === main) continue; // on main or detached — fine
6575
- const gitDir = String(execSilent('git rev-parse --git-dir', { cwd: localPath }) || '').trim();
6586
+ const gitDir = String(shared.shellSafeGitSync(['rev-parse', '--git-dir'], opts) || '').trim();
6576
6587
  const absGitDir = gitDir ? (path.isAbsolute(gitDir) ? gitDir : path.join(localPath, gitDir)) : path.join(localPath, '.git');
6577
6588
  const mergeStuck = fs.existsSync(path.join(absGitDir, 'MERGE_HEAD'));
6578
6589
  const rebaseStuck = fs.existsSync(path.join(absGitDir, 'rebase-merge')) || fs.existsSync(path.join(absGitDir, 'rebase-apply'));
6579
6590
  if (!mergeStuck && !rebaseStuck && !_FLEET_BRANCH_RE.test(cur)) continue; // likely a human's deliberate checkout — leave it
6580
6591
  const why = mergeStuck ? ' (stuck merge)' : rebaseStuck ? ' (stuck rebase)' : ' (fleet branch in live checkout)';
6581
6592
  log('warn', `Operator checkout for ${project.name} is on '${cur}'${why}; worktree-mode requires ${main} — restoring`);
6582
- const opts = { cwd: localPath };
6583
- if (mergeStuck) execSilent('git merge --abort', opts);
6584
- if (rebaseStuck) execSilent('git rebase --abort', opts);
6585
- execSilent('git reset --hard HEAD', opts); // drop uncommitted hijack state; branch commits stay on the ref
6593
+ if (mergeStuck) shared.shellSafeGitSync(['merge', '--abort'], opts);
6594
+ if (rebaseStuck) shared.shellSafeGitSync(['rebase', '--abort'], opts);
6595
+ shared.shellSafeGitSync(['reset', '--hard', 'HEAD'], opts); // drop uncommitted hijack state; branch commits stay on the ref
6586
6596
  try { shared.validateGitRef(main); } catch (ve) { throw new Error(`restoreHijackedOperatorCheckouts: invalid mainBranch ${JSON.stringify(main)}: ${ve.message}`); }
6587
6597
  shared.shellSafeGitSync(['checkout', main], opts);
6588
- const now = String(execSilent('git rev-parse --abbrev-ref HEAD', { cwd: localPath }) || '').trim();
6598
+ const now = String(shared.shellSafeGitSync(['rev-parse', '--abbrev-ref', 'HEAD'], opts) || '').trim();
6589
6599
  if (now === main) {
6590
6600
  try {
6591
6601
  writeInboxAlert(`operator-checkout-restored-${project.name}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2360",
3
+ "version": "0.1.2361",
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"