@rajat-rastogi/maestro 0.1.6 → 0.1.7

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.
@@ -442,6 +442,8 @@ body {
442
442
  let sessionStart = 0;
443
443
  let elapsedInterval = null;
444
444
  const sectionTimers = new Map(); // section-content element → { start, frozen, elEl }
445
+ let replayTimings = null; // null = live mode; array in replay mode
446
+ let replaySectionIdx = 0;
445
447
 
446
448
  // ── DOM refs ──
447
449
  const logEl = document.getElementById('log');
@@ -459,6 +461,58 @@ body {
459
461
  const logWrap = document.getElementById('log-wrap');
460
462
 
461
463
  // ── Helpers ──
464
+ function parseTs(ts) {
465
+ if (!ts) return null;
466
+ const m = ts.match(/\[(\d{2})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\]/);
467
+ if (!m) return null;
468
+ return new Date(2000 + +m[1], +m[2] - 1, +m[3], +m[4], +m[5], +m[6]).getTime();
469
+ }
470
+
471
+ function computeReplayTimings(events) {
472
+ // Find header indices and first/last timestamps
473
+ const headerIdxs = [];
474
+ let firstTs = null;
475
+ let lastTs = null;
476
+
477
+ for (let i = 0; i < events.length; i++) {
478
+ const ev = events[i];
479
+ if (ev.level === 'header' && ev.text.startsWith('---')) {
480
+ headerIdxs.push(i);
481
+ }
482
+ const t = parseTs(ev.ts);
483
+ if (t !== null) {
484
+ if (firstTs === null) firstTs = t;
485
+ lastTs = t;
486
+ }
487
+ }
488
+
489
+ const totalMs = (firstTs !== null && lastTs !== null) ? lastTs - firstTs : null;
490
+
491
+ // Compute per-section durations
492
+ const sectionDurations = headerIdxs.map((hi, si) => {
493
+ const nextHi = headerIdxs[si + 1] ?? events.length;
494
+
495
+ // start = first timestamped ev after the header
496
+ let start = null;
497
+ for (let i = hi + 1; i < nextHi; i++) {
498
+ const t = parseTs(events[i].ts);
499
+ if (t !== null) { start = t; break; }
500
+ }
501
+
502
+ // end = first timestamped ev in the next section, or lastTs
503
+ let end = null;
504
+ for (let i = nextHi; i < events.length; i++) {
505
+ const t = parseTs(events[i].ts);
506
+ if (t !== null) { end = t; break; }
507
+ }
508
+ if (end === null) end = lastTs;
509
+
510
+ return (start !== null && end !== null) ? end - start : null;
511
+ });
512
+
513
+ return { totalMs, sectionDurations };
514
+ }
515
+
462
516
  function formatElapsed(ms) {
463
517
  const s = Math.floor(ms / 1000);
464
518
  const m = Math.floor(s / 60);
@@ -534,7 +588,6 @@ body {
534
588
 
535
589
  const elapsedEl = document.createElement('span');
536
590
  elapsedEl.className = 'section-elapsed';
537
- elapsedEl.textContent = '0s';
538
591
 
539
592
  hdr.appendChild(toggle);
540
593
  hdr.appendChild(badge);
@@ -554,7 +607,16 @@ body {
554
607
  });
555
608
 
556
609
  currentSectionEl = content;
557
- sectionTimers.set(content, { start: sectionStart, frozen: false, elEl: elapsedEl });
610
+
611
+ if (replayTimings !== null) {
612
+ // Replay: use pre-computed duration, no live timer
613
+ const ms = replayTimings[replaySectionIdx++];
614
+ elapsedEl.textContent = ms !== null ? formatElapsed(ms) : '';
615
+ } else {
616
+ // Live: start timer as before
617
+ elapsedEl.textContent = '0s';
618
+ sectionTimers.set(content, { start: sectionStart, frozen: false, elEl: elapsedEl });
619
+ }
558
620
 
559
621
  sectionDiv.classList.toggle('hidden', !matchesPhase(phase, activePhase));
560
622
  }
@@ -804,13 +866,16 @@ body {
804
866
  })
805
867
  .then(data => {
806
868
  if (data.planContent) renderPlan(data.planContent);
807
- sessionStart = Date.now();
808
- startElapsedTimer();
869
+ const timings = computeReplayTimings(data.events);
870
+ replayTimings = timings.sectionDurations;
871
+ replaySectionIdx = 0;
872
+ if (timings.totalMs !== null) elapsedTotal.textContent = formatElapsed(timings.totalMs);
809
873
  for (const ev of data.events) appendEvent(ev);
810
- stopTimers();
874
+ replayTimings = null;
811
875
  if (autoScroll) window.scrollTo(0, document.body.scrollHeight);
812
876
  })
813
877
  .catch(err => {
878
+ replayTimings = null;
814
879
  logWrap.innerHTML = '<div style="color:var(--error);padding:20px">Failed to load replay data.'
815
880
  + (err.message ? '<br><small style="color:var(--ts)">' + err.message + '</small>' : '')
816
881
  + '</div>';
@@ -1 +1 @@
1
- {"version":3,"file":"replay-parser.d.ts","sourceRoot":"","sources":["../../src/dashboard/replay-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAsD/F"}
1
+ {"version":3,"file":"replay-parser.d.ts","sourceRoot":"","sources":["../../src/dashboard/replay-parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI1C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAmE/F"}
@@ -10,15 +10,29 @@ export function parseProgressFile(filePath) {
10
10
  const planFileMatch = content.match(/^starting maestro loop: (.+?\.md) \(/m);
11
11
  if (planFileMatch) {
12
12
  const cwd = path.dirname(path.dirname(path.dirname(path.resolve(filePath))));
13
- const fullPath = path.join(cwd, planFileMatch[1]);
13
+ const planPath = planFileMatch[1];
14
+ const fullPath = path.isAbsolute(planPath) ? planPath : path.join(cwd, planPath);
14
15
  try {
15
16
  planContent = fs.readFileSync(fullPath, 'utf8');
16
17
  }
17
18
  catch {
19
+ // Fallback 1: exact name in completed/ (plan not yet timestamped)
18
20
  try {
19
21
  planContent = fs.readFileSync(path.join(path.dirname(fullPath), 'completed', path.basename(fullPath)), 'utf8');
20
22
  }
21
- catch { /* not found */ }
23
+ catch {
24
+ // Fallback 2: timestamped name in completed/, e.g. my-plan-20260307-175011.md
25
+ try {
26
+ const completedDir = path.join(path.dirname(fullPath), 'completed');
27
+ const baseName = path.basename(fullPath, '.md');
28
+ const entries = fs.readdirSync(completedDir);
29
+ const match = entries.find(e => e.startsWith(baseName + '-') && e.endsWith('.md'));
30
+ if (match) {
31
+ planContent = fs.readFileSync(path.join(completedDir, match), 'utf8');
32
+ }
33
+ }
34
+ catch { /* not found */ }
35
+ }
22
36
  }
23
37
  }
24
38
  let currentPhase = 'info';
@@ -1 +1 @@
1
- {"version":3,"file":"replay-parser.js","sourceRoot":"","sources":["../../src/dashboard/replay-parser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replay-parser.js","sourceRoot":"","sources":["../../src/dashboard/replay-parser.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rajat-rastogi/maestro",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Conduct your codebase — autonomous AI coding orchestrator",
5
5
  "type": "module",
6
6
  "main": "dist/main.js",