agentblueprint 0.7.10 → 0.7.12

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/dist/renderers.js CHANGED
@@ -2463,69 +2463,139 @@ function buildClaudeCodeHooksConfig(input) {
2463
2463
  return JSON.stringify(config, null, 2) + '\n';
2464
2464
  }
2465
2465
  // =============================================================================
2466
- // STRATEGIC RECOMMENDATIONS (Phase 5 — Living Blueprint)
2466
+ // NEXT ACTIONS (deterministic — Living Blueprint)
2467
2467
  // =============================================================================
2468
+ /**
2469
+ * Deterministic recommendations derived from implementation state + progress data.
2470
+ * Facts and priorities only: which agents to implement next, which metrics deviate,
2471
+ * which deviations to review. No LLM, no how-to instructions.
2472
+ *
2473
+ * LLM-generated strategic advice lives in the Reality Dashboard (web UI) and the
2474
+ * get_recommendations MCP tool, not here.
2475
+ */
2468
2476
  function buildRecommendations(input) {
2469
- const recs = input.recommendations.recommendations;
2470
2477
  const lines = [];
2471
- lines.push('# Strategic Recommendations');
2472
- lines.push('');
2473
- lines.push(`> Generated: ${recs.generatedAt}`);
2474
- lines.push('');
2475
- lines.push(recs.summary);
2476
- lines.push('');
2477
- // Group by priority
2478
- const priorityOrder = ['critical', 'high', 'medium', 'low'];
2479
- const priorityLabels = {
2480
- critical: 'Critical',
2481
- high: 'High Priority',
2482
- medium: 'Medium Priority',
2483
- low: 'Lower Priority',
2484
- };
2485
- for (const priority of priorityOrder) {
2486
- const group = recs.recommendations.filter(r => r.priority === priority);
2487
- if (group.length === 0)
2478
+ const state = input.implementationState;
2479
+ const sd = rec(state.stateData);
2480
+ const stateAgents = arr(sd.agents);
2481
+ const bp = rec(input.blueprintData);
2482
+ const team = arr(bp.enhancedDigitalTeam);
2483
+ const phases = arr(bp.phases);
2484
+ const syncDate = state.syncedAt ? state.syncedAt.split('T')[0] : 'unknown';
2485
+ // Build status lookup from implementation state
2486
+ const statusByName = new Map();
2487
+ for (const sa of stateAgents) {
2488
+ const a = rec(sa);
2489
+ statusByName.set(str(a.name).toLowerCase().trim(), str(a.status) || 'not_started');
2490
+ }
2491
+ // Count implemented
2492
+ let implementedCount = 0;
2493
+ let inProgressCount = 0;
2494
+ for (const status of statusByName.values()) {
2495
+ if (status === 'implemented' || status === 'modified')
2496
+ implementedCount++;
2497
+ if (status === 'in_progress')
2498
+ inProgressCount++;
2499
+ }
2500
+ const totalAgents = stateAgents.length || team.length;
2501
+ lines.push('# Next Actions');
2502
+ lines.push('');
2503
+ lines.push(`${implementedCount} of ${totalAgents} agents implemented. Last synced: ${syncDate}.`);
2504
+ lines.push('');
2505
+ // --- Agents to implement (ordered by phase, then team position) ---
2506
+ // Build phase ordering: which agents belong to which phase
2507
+ const agentPhaseMap = new Map();
2508
+ const phaseOrder = [];
2509
+ for (const phase of phases) {
2510
+ const p = rec(phase);
2511
+ const phaseName = str(p.name);
2512
+ if (phaseName)
2513
+ phaseOrder.push(phaseName);
2514
+ const introduced = arr(p.agentsIntroduced);
2515
+ for (const ai of introduced) {
2516
+ const a = rec(ai);
2517
+ const refId = str(a.agentRefId);
2518
+ if (refId)
2519
+ agentPhaseMap.set(refId, phaseName);
2520
+ }
2521
+ }
2522
+ // Find agents not yet implemented, preserving team order
2523
+ const remaining = [];
2524
+ for (const member of team) {
2525
+ const agent = rec(member);
2526
+ const name = str(agent.name);
2527
+ const id = str(agent.id);
2528
+ const status = statusByName.get(name.toLowerCase().trim()) || 'not_started';
2529
+ if (status === 'implemented' || status === 'modified' || status === 'skipped')
2488
2530
  continue;
2489
- lines.push(`## ${priorityLabels[priority]}`);
2531
+ const role = str(agent.role) || str(agent.agentRole) || '';
2532
+ const phase = agentPhaseMap.get(id) || '';
2533
+ const deps = arr(agent.dependencies).map((d) => str(d)).filter(Boolean);
2534
+ remaining.push({ name, role, phase, status, deps });
2535
+ }
2536
+ // Sort: in_progress first, then by phase order, then team position (already in order)
2537
+ remaining.sort((a, b) => {
2538
+ if (a.status === 'in_progress' && b.status !== 'in_progress')
2539
+ return -1;
2540
+ if (b.status === 'in_progress' && a.status !== 'in_progress')
2541
+ return 1;
2542
+ const aIdx = a.phase ? phaseOrder.indexOf(a.phase) : 999;
2543
+ const bIdx = b.phase ? phaseOrder.indexOf(b.phase) : 999;
2544
+ return aIdx - bIdx;
2545
+ });
2546
+ if (remaining.length > 0) {
2547
+ lines.push('## Agents to Implement');
2490
2548
  lines.push('');
2491
- for (const rec of group) {
2492
- lines.push(`### ${rec.id}: ${rec.title}`);
2493
- lines.push('');
2494
- lines.push(`**Category:** ${rec.category.replace(/_/g, ' ')}`);
2495
- lines.push(`**Confidence:** ${rec.confidence}`);
2496
- lines.push('');
2497
- lines.push(`**What:** ${rec.what}`);
2498
- lines.push('');
2499
- lines.push(`**Why:** ${rec.why}`);
2549
+ lines.push('| # | Agent | Role | Phase | Status | Dependencies |');
2550
+ lines.push('|---|-------|------|-------|--------|--------------|');
2551
+ for (let i = 0; i < remaining.length; i++) {
2552
+ const r = remaining[i];
2553
+ const depsStr = r.deps.length > 0 ? r.deps.join(', ') : '-';
2554
+ lines.push(`| ${i + 1} | ${r.name} | ${r.role} | ${r.phase || '-'} | ${r.status} | ${depsStr} |`);
2555
+ }
2556
+ lines.push('');
2557
+ }
2558
+ // --- Metric deviations ---
2559
+ if (hasProgressData(input)) {
2560
+ const progress = input.progress;
2561
+ const deviating = progress.actuals.filter(a => a.status !== 'on_track');
2562
+ if (deviating.length > 0) {
2563
+ lines.push('## Metric Deviations');
2500
2564
  lines.push('');
2501
- lines.push(`**Expected Impact:** ${rec.expectedImpact}`);
2502
- if (rec.financialImpact) {
2503
- const fi = rec.financialImpact;
2504
- const value = fi.estimatedValue ? ` (${fi.estimatedValue})` : '';
2505
- lines.push('');
2506
- lines.push(`**Financial Impact:** ${fi.type.replace(/_/g, ' ')}${value} -- ${fi.basis}`);
2507
- }
2508
- if (rec.relatedAgents?.length) {
2509
- lines.push('');
2510
- lines.push(`**Related Agents:** ${rec.relatedAgents.join(', ')}`);
2511
- }
2512
- if (rec.relatedMetrics?.length) {
2513
- lines.push('');
2514
- lines.push(`**Related Metrics:** ${rec.relatedMetrics.join(', ')}`);
2565
+ lines.push('| Metric | Target | Actual | Status | Deviation |');
2566
+ lines.push('|--------|--------|--------|--------|-----------|');
2567
+ for (const m of deviating) {
2568
+ const devPct = m.deviationPercent != null ? `${m.deviationPercent > 0 ? '+' : ''}${m.deviationPercent}%` : '-';
2569
+ lines.push(`| ${m.metricName} | ${m.predictedValue} | ${m.actualValue} | ${m.status} | ${devPct} |`);
2515
2570
  }
2516
2571
  lines.push('');
2517
2572
  }
2573
+ const s = progress.summary;
2574
+ lines.push(`Metrics: ${s.onTrack} on track, ${s.minorDeviation} minor deviation, ${s.majorDeviation} major deviation.`);
2575
+ lines.push('');
2518
2576
  }
2519
- // Context snapshot footer
2520
- const ctx = recs.contextSnapshot;
2521
- lines.push('---');
2522
- lines.push('');
2523
- lines.push(`Implementation: ${ctx.implementationProgress}`);
2524
- lines.push(`Performance: ${ctx.performanceStatus}`);
2525
- if (ctx.daysInImplementation > 0) {
2526
- lines.push(`Days in implementation: ${ctx.daysInImplementation}`);
2577
+ // --- Deviations from plan ---
2578
+ const archDevs = arr(rec(sd.architecture).deviations).filter((d) => str(d));
2579
+ const agentsWithDevs = stateAgents
2580
+ .map((a) => rec(a))
2581
+ .filter(a => arr(a.deviations).length > 0);
2582
+ if (archDevs.length > 0 || agentsWithDevs.length > 0) {
2583
+ lines.push('## Deviations from Plan');
2584
+ lines.push('');
2585
+ if (archDevs.length > 0) {
2586
+ lines.push('**Architecture:**');
2587
+ for (const d of archDevs)
2588
+ lines.push(`- ${str(d)}`);
2589
+ lines.push('');
2590
+ }
2591
+ for (const a of agentsWithDevs) {
2592
+ const devs = arr(a.deviations);
2593
+ lines.push(`**${str(a.name)}:**`);
2594
+ for (const d of devs)
2595
+ lines.push(`- ${str(d)}`);
2596
+ lines.push('');
2597
+ }
2527
2598
  }
2528
- lines.push('');
2529
2599
  return lines.join('\n');
2530
2600
  }
2531
2601
  // =============================================================================
@@ -2588,8 +2658,8 @@ export function renderSkillDirectory(input) {
2588
2658
  if (hasImplementationData(input)) {
2589
2659
  files.set('CURRENT-STATE.md', buildCurrentState(input));
2590
2660
  }
2591
- // Strategic recommendations (return visits -- Living Blueprint Phase 5)
2592
- if (hasImplementationData(input) && input.recommendations?.recommendations) {
2661
+ // Next actions (return visits -- deterministic from implementation state + progress)
2662
+ if (hasImplementationData(input)) {
2593
2663
  files.set('RECOMMENDATIONS.md', buildRecommendations(input));
2594
2664
  }
2595
2665
  return files;