murmur8 4.3.4 → 4.5.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "murmur8",
3
- "version": "4.3.4",
3
+ "version": "4.5.0",
4
4
  "description": "Multi-agent workflow framework for automated feature development",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/murm.js CHANGED
@@ -5,6 +5,7 @@ const { execSync, spawn } = require('child_process');
5
5
  const fs = require('fs');
6
6
  const readline = require('readline');
7
7
  const theme = require('./theme');
8
+ const { recordHistory, readHistoryFile, writeHistoryFile } = require('./history');
8
9
 
9
10
  const CONFIG_FILE = '.claude/murm-config.json';
10
11
  const LOCK_FILE = '.claude/murm.lock';
@@ -19,6 +20,27 @@ const LEGACY_QUEUE_FILE = '.claude/parallel-queue.json';
19
20
  let runningProcesses = new Map();
20
21
  let isAborting = false;
21
22
 
23
+ const HISTORY_FILE = '.claude/pipeline-history.json';
24
+
25
+ function mergeWorktreeHistory(worktreePath) {
26
+ const worktreeHistoryPath = path.join(worktreePath, HISTORY_FILE);
27
+ if (!fs.existsSync(worktreeHistoryPath)) return [];
28
+
29
+ try {
30
+ const worktreeEntries = JSON.parse(fs.readFileSync(worktreeHistoryPath, 'utf8'));
31
+ if (!Array.isArray(worktreeEntries) || worktreeEntries.length === 0) return [];
32
+
33
+ const mainHistory = readHistoryFile();
34
+ if (mainHistory.error) return worktreeEntries;
35
+
36
+ mainHistory.push(...worktreeEntries);
37
+ writeHistoryFile(mainHistory);
38
+ return worktreeEntries;
39
+ } catch {
40
+ return [];
41
+ }
42
+ }
43
+
22
44
  /**
23
45
  * Migrate a legacy file path to the new path.
24
46
  * If the old file exists and the new one doesn't, rename it.
@@ -1284,6 +1306,11 @@ async function runMurm(slugs, options = {}) {
1284
1306
  if (mergeResult.success) {
1285
1307
  feature.status = 'murm_complete';
1286
1308
  console.log(`[${timestamp}] ${result.slug}: ${theme.MESSAGES.mergedAndLanded} \u2713`);
1309
+ // Merge per-stage history from worktree before cleanup
1310
+ const merged = mergeWorktreeHistory(feature.worktreePath);
1311
+ if (merged.length > 0) {
1312
+ feature.historyMerged = true;
1313
+ }
1287
1314
  removeWorktree(result.slug);
1288
1315
  } else if (mergeResult.conflict) {
1289
1316
  feature.status = 'merge_conflict';
@@ -1342,6 +1369,29 @@ async function runMurm(slugs, options = {}) {
1342
1369
  });
1343
1370
  }
1344
1371
 
1372
+ // Record batch-level history
1373
+ recordHistory({
1374
+ slug: slugs.join('+'),
1375
+ mode: 'murmuration',
1376
+ status: summary.failed === 0 && summary.conflicts === 0 ? 'success' : 'partial',
1377
+ startedAt: queue.startedAt,
1378
+ completedAt: new Date().toISOString(),
1379
+ totalDurationMs: Date.now() - new Date(queue.startedAt).getTime(),
1380
+ baseBranch,
1381
+ features: queue.features.map(f => ({
1382
+ slug: f.slug,
1383
+ status: f.status,
1384
+ startedAt: f.startedAt,
1385
+ completedAt: f.completedAt
1386
+ })),
1387
+ summary: {
1388
+ total: slugs.length,
1389
+ completed: summary.completed,
1390
+ failed: summary.failed,
1391
+ conflicts: summary.conflicts
1392
+ }
1393
+ });
1394
+
1345
1395
  return { success: summary.failed === 0 && summary.conflicts === 0, summary };
1346
1396
  } finally {
1347
1397
  // Always release lock when done