agentblueprint 0.6.19 → 0.6.22
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/__tests__/renderers.test.js +520 -2
- package/dist/__tests__/renderers.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +200 -2
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/client.d.ts +75 -0
- package/dist/client.js +6 -0
- package/dist/client.js.map +1 -1
- package/dist/download.js +17 -1
- package/dist/download.js.map +1 -1
- package/dist/renderers.d.ts +4 -0
- package/dist/renderers.js +724 -28
- package/dist/renderers.js.map +1 -1
- package/dist/server.js +26 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/download-blueprint.js +17 -3
- package/dist/tools/download-blueprint.js.map +1 -1
- package/dist/tools/get-progress.d.ts +17 -0
- package/dist/tools/get-progress.js +73 -0
- package/dist/tools/get-progress.js.map +1 -0
- package/dist/tools/report-metric.d.ts +26 -0
- package/dist/tools/report-metric.js +45 -0
- package/dist/tools/report-metric.js.map +1 -0
- package/package.json +1 -1
package/dist/renderers.js
CHANGED
|
@@ -1291,10 +1291,318 @@ function buildGuardrailsAndGovernance(input) {
|
|
|
1291
1291
|
function normalizeMetricName(name) {
|
|
1292
1292
|
return name.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim();
|
|
1293
1293
|
}
|
|
1294
|
+
// =============================================================================
|
|
1295
|
+
// REALITY LAYER HELPERS (Living Blueprint Phase 3A)
|
|
1296
|
+
// =============================================================================
|
|
1297
|
+
function hasImplementationData(input) {
|
|
1298
|
+
if (!input.implementationState)
|
|
1299
|
+
return false;
|
|
1300
|
+
const sd = rec(input.implementationState.stateData);
|
|
1301
|
+
const agents = arr(sd.agents);
|
|
1302
|
+
return agents.some((a) => str(rec(a).status) !== 'not_started');
|
|
1303
|
+
}
|
|
1304
|
+
export function hasProgressData(input) {
|
|
1305
|
+
if (!input.progress)
|
|
1306
|
+
return false;
|
|
1307
|
+
return input.progress.actuals.length > 0;
|
|
1308
|
+
}
|
|
1309
|
+
function buildProgressByName(input) {
|
|
1310
|
+
const map = new Map();
|
|
1311
|
+
if (!input.progress)
|
|
1312
|
+
return map;
|
|
1313
|
+
for (const actual of input.progress.actuals) {
|
|
1314
|
+
map.set(normalizeMetricName(actual.metricName), {
|
|
1315
|
+
actualValue: actual.actualValue,
|
|
1316
|
+
status: actual.status,
|
|
1317
|
+
recordedAt: actual.recordedAt,
|
|
1318
|
+
deviationPercent: actual.deviationPercent,
|
|
1319
|
+
predictedValue: actual.predictedValue,
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
return map;
|
|
1323
|
+
}
|
|
1324
|
+
// =============================================================================
|
|
1325
|
+
// CURRENT-STATE.md (new file on return visits)
|
|
1326
|
+
// =============================================================================
|
|
1327
|
+
function buildCurrentState(input) {
|
|
1328
|
+
const lines = [];
|
|
1329
|
+
const state = input.implementationState;
|
|
1330
|
+
const sd = rec(state.stateData);
|
|
1331
|
+
const stateAgents = arr(sd.agents);
|
|
1332
|
+
const bp = rec(input.blueprintData);
|
|
1333
|
+
const team = arr(bp.enhancedDigitalTeam);
|
|
1334
|
+
const syncDate = state.syncedAt ? state.syncedAt.split('T')[0] : 'unknown';
|
|
1335
|
+
const overallStatus = str(sd.overall_status) || 'unknown';
|
|
1336
|
+
lines.push('# Current State', '');
|
|
1337
|
+
lines.push(`> Last synced: ${syncDate} | Overall: ${overallStatus}`, '');
|
|
1338
|
+
// Agent status table
|
|
1339
|
+
const bpAgentsByName = new Map();
|
|
1340
|
+
for (const a of team) {
|
|
1341
|
+
const agent = rec(a);
|
|
1342
|
+
bpAgentsByName.set(str(agent.name).toLowerCase().trim(), agent);
|
|
1343
|
+
}
|
|
1344
|
+
lines.push('## Agent Implementation Status', '');
|
|
1345
|
+
lines.push('| # | Agent | Planned Role | Status | Platform Artifact | Deviations |');
|
|
1346
|
+
lines.push('|---|-------|-------------|--------|-------------------|------------|');
|
|
1347
|
+
let implementedCount = 0;
|
|
1348
|
+
const totalAgents = stateAgents.length || team.length;
|
|
1349
|
+
for (let i = 0; i < stateAgents.length; i++) {
|
|
1350
|
+
const sa = rec(stateAgents[i]);
|
|
1351
|
+
const name = str(sa.name);
|
|
1352
|
+
const status = str(sa.status) || 'not_started';
|
|
1353
|
+
const artifact = str(sa.platform_artifact) || '-';
|
|
1354
|
+
const deviations = arr(sa.deviations);
|
|
1355
|
+
const devStr = deviations.length > 0 ? deviations.map((d) => str(d)).join('; ') : '-';
|
|
1356
|
+
const bpAgent = bpAgentsByName.get(name.toLowerCase().trim());
|
|
1357
|
+
const plannedRole = bpAgent ? str(bpAgent.role) || str(bpAgent.agentRole) || '-' : '-';
|
|
1358
|
+
if (status === 'implemented' || status === 'modified')
|
|
1359
|
+
implementedCount++;
|
|
1360
|
+
lines.push(`| ${i + 1} | ${name} | ${plannedRole} | ${status} | ${artifact} | ${devStr} |`);
|
|
1361
|
+
}
|
|
1362
|
+
lines.push('');
|
|
1363
|
+
lines.push(`${implementedCount} of ${totalAgents} agents implemented.`, '');
|
|
1364
|
+
// Platform comparison
|
|
1365
|
+
const stPlatform = rec(sd.platform);
|
|
1366
|
+
const stArch = rec(sd.architecture);
|
|
1367
|
+
const plannedPlatform = getPlatformName(bp);
|
|
1368
|
+
const plannedPattern = getAgenticPattern(bp);
|
|
1369
|
+
const actualPlatform = str(stPlatform.name) || 'Not reported';
|
|
1370
|
+
const actualPattern = str(stArch.pattern) || 'Not reported';
|
|
1371
|
+
if (actualPlatform !== 'Not reported' || actualPattern !== 'Not reported') {
|
|
1372
|
+
lines.push('## Platform', '');
|
|
1373
|
+
lines.push('| | Planned | Actual |');
|
|
1374
|
+
lines.push('|---|---------|--------|');
|
|
1375
|
+
lines.push(`| Platform | ${plannedPlatform} | ${actualPlatform} |`);
|
|
1376
|
+
lines.push(`| Pattern | ${plannedPattern} | ${actualPattern} |`);
|
|
1377
|
+
if (str(stPlatform.version))
|
|
1378
|
+
lines.push(`| Version | - | ${str(stPlatform.version)} |`);
|
|
1379
|
+
if (str(stPlatform.environment))
|
|
1380
|
+
lines.push(`| Environment | - | ${str(stPlatform.environment)} |`);
|
|
1381
|
+
lines.push('');
|
|
1382
|
+
}
|
|
1383
|
+
// Architecture deviations
|
|
1384
|
+
const archDevs = arr(stArch.deviations).filter((d) => str(d));
|
|
1385
|
+
if (archDevs.length > 0) {
|
|
1386
|
+
lines.push('## Architecture Deviations', '');
|
|
1387
|
+
for (const d of archDevs)
|
|
1388
|
+
lines.push(`- ${str(d)}`);
|
|
1389
|
+
lines.push('');
|
|
1390
|
+
}
|
|
1391
|
+
// Additional components
|
|
1392
|
+
const addlComponents = arr(stArch.additional_components).filter((c) => str(c));
|
|
1393
|
+
if (addlComponents.length > 0) {
|
|
1394
|
+
lines.push('## Additional Components', '');
|
|
1395
|
+
for (const c of addlComponents)
|
|
1396
|
+
lines.push(`- ${str(c)}`);
|
|
1397
|
+
lines.push('');
|
|
1398
|
+
}
|
|
1399
|
+
// Integrations connected (per agent)
|
|
1400
|
+
const agentsWithIntegrations = stateAgents
|
|
1401
|
+
.map((a) => rec(a))
|
|
1402
|
+
.filter(a => arr(a.integrations_connected).length > 0);
|
|
1403
|
+
if (agentsWithIntegrations.length > 0) {
|
|
1404
|
+
lines.push('## Integrations Connected', '');
|
|
1405
|
+
for (const a of agentsWithIntegrations) {
|
|
1406
|
+
const integrations = arr(a.integrations_connected).map((i) => str(i)).join(', ');
|
|
1407
|
+
lines.push(`- **${str(a.name)}**: ${integrations}`);
|
|
1408
|
+
}
|
|
1409
|
+
lines.push('');
|
|
1410
|
+
}
|
|
1411
|
+
// Performance against targets (if progress data exists)
|
|
1412
|
+
if (hasProgressData(input)) {
|
|
1413
|
+
const progress = input.progress;
|
|
1414
|
+
lines.push('## Performance Against Targets', '');
|
|
1415
|
+
lines.push('| Metric | Target | Actual | Status | Measured |');
|
|
1416
|
+
lines.push('|--------|--------|--------|--------|----------|');
|
|
1417
|
+
for (const actual of progress.actuals) {
|
|
1418
|
+
const measured = actual.recordedAt ? actual.recordedAt.split('T')[0] : '-';
|
|
1419
|
+
lines.push(`| ${actual.metricName} | ${actual.predictedValue} | ${actual.actualValue} | ${actual.status} | ${measured} |`);
|
|
1420
|
+
}
|
|
1421
|
+
lines.push('');
|
|
1422
|
+
const s = progress.summary;
|
|
1423
|
+
lines.push(`${s.onTrack} on track, ${s.minorDeviation} minor deviation, ${s.majorDeviation} major deviation.`, '');
|
|
1424
|
+
}
|
|
1425
|
+
return lines.join('\n');
|
|
1426
|
+
}
|
|
1427
|
+
// =============================================================================
|
|
1428
|
+
// RECOMMENDATIONS.md (new file on return visits)
|
|
1429
|
+
// =============================================================================
|
|
1430
|
+
function buildRecommendations(input) {
|
|
1431
|
+
const lines = [];
|
|
1432
|
+
lines.push('# Recommendations', '');
|
|
1433
|
+
lines.push('> Prioritized next actions based on implementation state and performance data.', '');
|
|
1434
|
+
let recNum = 0;
|
|
1435
|
+
const bp = rec(input.blueprintData);
|
|
1436
|
+
const team = arr(bp.enhancedDigitalTeam);
|
|
1437
|
+
const bc = rec(input.businessCaseData);
|
|
1438
|
+
// Build epic lookup for priority ordering
|
|
1439
|
+
const epics = arr(rec(input.implementationPlanData).epics);
|
|
1440
|
+
const epicByNormalizedName = new Map();
|
|
1441
|
+
for (const e of epics) {
|
|
1442
|
+
const epic = rec(e);
|
|
1443
|
+
const name = str(epic.name).toLowerCase().trim();
|
|
1444
|
+
epicByNormalizedName.set(name, {
|
|
1445
|
+
phase: str(epic.phase),
|
|
1446
|
+
priority: str(epic.priority) || 'P2',
|
|
1447
|
+
dependencies: arr(epic.dependencies).map((d) => typeof d === 'string' ? d : str(rec(d).description) || str(d)),
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
// Helper to find the best-matching epic for an agent
|
|
1451
|
+
function findEpicForAgent(agentName) {
|
|
1452
|
+
const norm = agentName.toLowerCase().trim();
|
|
1453
|
+
// Direct match
|
|
1454
|
+
for (const [epicName, epic] of epicByNormalizedName) {
|
|
1455
|
+
if (epicName.includes(norm) || norm.includes(epicName))
|
|
1456
|
+
return epic;
|
|
1457
|
+
}
|
|
1458
|
+
// Word overlap
|
|
1459
|
+
const agentWords = norm.split(/\s+/).filter(w => w.length > 2);
|
|
1460
|
+
for (const [epicName, epic] of epicByNormalizedName) {
|
|
1461
|
+
for (const word of agentWords) {
|
|
1462
|
+
if (epicName.includes(word))
|
|
1463
|
+
return epic;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
return undefined;
|
|
1467
|
+
}
|
|
1468
|
+
// Priority sort key: P0=0, P1=1, P2=2, unknown=3
|
|
1469
|
+
function priorityKey(p) {
|
|
1470
|
+
if (p === 'P0')
|
|
1471
|
+
return 0;
|
|
1472
|
+
if (p === 'P1')
|
|
1473
|
+
return 1;
|
|
1474
|
+
if (p === 'P2')
|
|
1475
|
+
return 2;
|
|
1476
|
+
return 3;
|
|
1477
|
+
}
|
|
1478
|
+
// --- Section 1: Unimplemented agents ---
|
|
1479
|
+
if (hasImplementationData(input)) {
|
|
1480
|
+
const sd = rec(input.implementationState.stateData);
|
|
1481
|
+
const stateAgents = arr(sd.agents);
|
|
1482
|
+
const implementedNames = new Set(stateAgents
|
|
1483
|
+
.map((a) => rec(a))
|
|
1484
|
+
.filter(a => str(a.status) === 'implemented' || str(a.status) === 'modified')
|
|
1485
|
+
.map(a => str(a.name).toLowerCase().trim()));
|
|
1486
|
+
const unimplemented = [];
|
|
1487
|
+
for (const sa of stateAgents) {
|
|
1488
|
+
const a = rec(sa);
|
|
1489
|
+
const status = str(a.status);
|
|
1490
|
+
if (status === 'implemented' || status === 'modified' || status === 'skipped')
|
|
1491
|
+
continue;
|
|
1492
|
+
const name = str(a.name);
|
|
1493
|
+
const bpAgent = team.find((t) => str(rec(t).name).toLowerCase().trim() === name.toLowerCase().trim());
|
|
1494
|
+
const role = bpAgent ? str(rec(bpAgent).role) || str(rec(bpAgent).agentRole) : '-';
|
|
1495
|
+
const epic = findEpicForAgent(name);
|
|
1496
|
+
const phase = epic?.phase || '-';
|
|
1497
|
+
const priority = epic?.priority || '-';
|
|
1498
|
+
unimplemented.push({
|
|
1499
|
+
name,
|
|
1500
|
+
role,
|
|
1501
|
+
status,
|
|
1502
|
+
phase,
|
|
1503
|
+
priority,
|
|
1504
|
+
priorityNum: priorityKey(priority),
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
// Sort by roadmap priority
|
|
1508
|
+
unimplemented.sort((a, b) => a.priorityNum - b.priorityNum);
|
|
1509
|
+
if (unimplemented.length > 0) {
|
|
1510
|
+
lines.push('## Next Agents to Implement', '');
|
|
1511
|
+
for (const agent of unimplemented) {
|
|
1512
|
+
recNum++;
|
|
1513
|
+
const statusLabel = agent.status === 'in_progress' ? ' (in progress)' : '';
|
|
1514
|
+
lines.push(`### ${recNum}. ${agent.status === 'in_progress' ? 'Continue' : 'Implement'} ${agent.name}${statusLabel}`, '');
|
|
1515
|
+
lines.push(`Role: ${agent.role}`);
|
|
1516
|
+
if (agent.phase !== '-')
|
|
1517
|
+
lines.push(`Roadmap phase: ${agent.phase} | Priority: ${agent.priority}`);
|
|
1518
|
+
lines.push(`Read agent spec in \`references/agent-specifications.md\`.`, '');
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
// --- Section 2: Metric deviations ---
|
|
1523
|
+
if (hasProgressData(input)) {
|
|
1524
|
+
const progress = input.progress;
|
|
1525
|
+
const deviating = progress.actuals
|
|
1526
|
+
.filter(a => a.status === 'major_deviation' || a.status === 'minor_deviation')
|
|
1527
|
+
.sort((a, b) => {
|
|
1528
|
+
// Major before minor
|
|
1529
|
+
if (a.status !== b.status)
|
|
1530
|
+
return a.status === 'major_deviation' ? -1 : 1;
|
|
1531
|
+
// Then by absolute deviation descending
|
|
1532
|
+
const absA = Math.abs(a.deviationPercent ?? 0);
|
|
1533
|
+
const absB = Math.abs(b.deviationPercent ?? 0);
|
|
1534
|
+
return absB - absA;
|
|
1535
|
+
});
|
|
1536
|
+
if (deviating.length > 0) {
|
|
1537
|
+
lines.push('## Metrics Requiring Attention', '');
|
|
1538
|
+
for (const metric of deviating) {
|
|
1539
|
+
recNum++;
|
|
1540
|
+
const devPct = metric.deviationPercent != null ? `${metric.deviationPercent > 0 ? '+' : ''}${metric.deviationPercent.toFixed(1)}%` : '-';
|
|
1541
|
+
lines.push(`### ${recNum}. Address ${metric.metricName} deviation`, '');
|
|
1542
|
+
lines.push(`Target: ${metric.predictedValue} | Actual: ${metric.actualValue} | Deviation: ${devPct}`);
|
|
1543
|
+
lines.push(`Status: ${metric.status}`);
|
|
1544
|
+
// Financial context
|
|
1545
|
+
const quantifiedROI = rec(rec(bc.benefits).quantifiedROI);
|
|
1546
|
+
if (metric.metricType === 'financial' && str(quantifiedROI.roi)) {
|
|
1547
|
+
lines.push(`Financial impact: This metric is tracked against the projected ${str(quantifiedROI.roi)} ROI in the business case.`);
|
|
1548
|
+
}
|
|
1549
|
+
else if (str(quantifiedROI.roi)) {
|
|
1550
|
+
const annualSavings = str(rec(rec(quantifiedROI.laborCostDetail).projectedSavings).costSavingsAnnual);
|
|
1551
|
+
if (annualSavings) {
|
|
1552
|
+
lines.push(`Financial context: Operational metrics drive the projected ${annualSavings} annual savings in the business case.`);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
lines.push('');
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
// --- Section 3: Spec deviations ---
|
|
1560
|
+
if (hasImplementationData(input)) {
|
|
1561
|
+
const sd = rec(input.implementationState.stateData);
|
|
1562
|
+
const stateAgents = arr(sd.agents);
|
|
1563
|
+
const agentsWithDeviations = stateAgents
|
|
1564
|
+
.map((a) => rec(a))
|
|
1565
|
+
.filter(a => arr(a.deviations).length > 0);
|
|
1566
|
+
if (agentsWithDeviations.length > 0) {
|
|
1567
|
+
lines.push('## Deviations to Review', '');
|
|
1568
|
+
for (const agent of agentsWithDeviations) {
|
|
1569
|
+
recNum++;
|
|
1570
|
+
const name = str(agent.name);
|
|
1571
|
+
const bpAgent = team.find((t) => str(rec(t).name).toLowerCase().trim() === name.toLowerCase().trim());
|
|
1572
|
+
const role = bpAgent ? str(rec(bpAgent).role) || str(rec(bpAgent).agentRole) : '-';
|
|
1573
|
+
lines.push(`### ${recNum}. Review deviations: ${name}`, '');
|
|
1574
|
+
lines.push(`Planned role: ${role}`, '');
|
|
1575
|
+
for (const d of arr(agent.deviations)) {
|
|
1576
|
+
lines.push(`- ${str(d)}`);
|
|
1577
|
+
}
|
|
1578
|
+
lines.push('');
|
|
1579
|
+
lines.push('Check if these deviations affect the agent\'s success metrics in `references/evaluation-criteria.md`.', '');
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
// --- Section 4: Financial impact note ---
|
|
1584
|
+
if (hasProgressData(input)) {
|
|
1585
|
+
const progress = input.progress;
|
|
1586
|
+
const deviationCount = progress.summary.minorDeviation + progress.summary.majorDeviation;
|
|
1587
|
+
const quantifiedROI = rec(rec(bc.benefits).quantifiedROI);
|
|
1588
|
+
if (deviationCount > 0 && str(quantifiedROI.roi)) {
|
|
1589
|
+
lines.push('## Financial Impact Note', '');
|
|
1590
|
+
const payback = str(quantifiedROI.paybackPeriod);
|
|
1591
|
+
lines.push(`${deviationCount} metric${deviationCount > 1 ? 's are' : ' is'} deviating from targets. The business case projected ${str(quantifiedROI.roi)} ROI${payback ? ` and ${payback} payback period` : ''}.`);
|
|
1592
|
+
lines.push('Track whether deviations affect these projections using Agent Blueprint\'s performance monitoring.', '');
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
if (recNum === 0) {
|
|
1596
|
+
lines.push('All agents implemented and metrics on track. No action items at this time.', '');
|
|
1597
|
+
}
|
|
1598
|
+
return lines.join('\n');
|
|
1599
|
+
}
|
|
1294
1600
|
function buildEvaluationCriteria(input) {
|
|
1295
1601
|
const { blueprintData, businessCaseData } = input;
|
|
1296
1602
|
const bp = rec(blueprintData);
|
|
1297
1603
|
const bc = rec(businessCaseData);
|
|
1604
|
+
const progressMap = buildProgressByName(input);
|
|
1605
|
+
const hasActuals = progressMap.size > 0;
|
|
1298
1606
|
const lines = [
|
|
1299
1607
|
'# Evaluation Criteria',
|
|
1300
1608
|
'',
|
|
@@ -1373,37 +1681,67 @@ function buildEvaluationCriteria(input) {
|
|
|
1373
1681
|
group.sort((a, b) => fieldScore(b) - fieldScore(a));
|
|
1374
1682
|
dedupedOps.push(group[0]);
|
|
1375
1683
|
}
|
|
1376
|
-
const operationalRows = dedupedOps.map(r =>
|
|
1684
|
+
const operationalRows = dedupedOps.map(r => {
|
|
1685
|
+
if (hasActuals) {
|
|
1686
|
+
const match = progressMap.get(normalizeMetricName(r.name));
|
|
1687
|
+
const actual = match ? match.actualValue : '-';
|
|
1688
|
+
const status = match ? match.status : '-';
|
|
1689
|
+
const measured = match ? match.recordedAt.split('T')[0] : '-';
|
|
1690
|
+
return `| ${r.name} | ${r.baseline} | ${r.target} | ${actual} | ${status} | ${measured} | ${r.direction} | ${r.unit} | ${r.frequency} | ${r.source} |`;
|
|
1691
|
+
}
|
|
1692
|
+
return `| ${r.name} | ${r.baseline} | ${r.target} | ${r.direction} | ${r.unit} | ${r.frequency} | ${r.source} |`;
|
|
1693
|
+
});
|
|
1377
1694
|
if (operationalRows.length > 0) {
|
|
1378
1695
|
hasContent = true;
|
|
1379
|
-
|
|
1696
|
+
if (hasActuals) {
|
|
1697
|
+
lines.push('## Operational Metrics', '', '| Metric | Baseline | Target | Actual | Status | Measured | Direction | Unit | Frequency | Source |', '|--------|----------|--------|--------|--------|----------|-----------|------|-----------|--------|', ...operationalRows, '');
|
|
1698
|
+
}
|
|
1699
|
+
else {
|
|
1700
|
+
lines.push('## Operational Metrics', '', '| Metric | Baseline | Target | Direction | Unit | Frequency | Source |', '|--------|----------|--------|-----------|------|-----------|--------|', ...operationalRows, '');
|
|
1701
|
+
}
|
|
1380
1702
|
}
|
|
1381
|
-
|
|
1382
|
-
const financialRows = [];
|
|
1703
|
+
const collectedFin = [];
|
|
1383
1704
|
if (roiFin.length > 0) {
|
|
1384
1705
|
for (const item of roiFin) {
|
|
1385
1706
|
const m = rec(item);
|
|
1386
|
-
|
|
1707
|
+
collectedFin.push({
|
|
1708
|
+
name: str(m.name), target: str(m.predictedValue),
|
|
1709
|
+
direction: str(m.direction) || '-', unit: str(m.unit) || '-', source: str(m.source),
|
|
1710
|
+
});
|
|
1387
1711
|
}
|
|
1388
1712
|
}
|
|
1389
1713
|
else {
|
|
1390
1714
|
if (str(quantifiedROI.roi)) {
|
|
1391
|
-
|
|
1715
|
+
collectedFin.push({ name: 'ROI', target: str(quantifiedROI.roi), direction: 'higher_is_better', unit: '%', source: 'quantifiedROI' });
|
|
1392
1716
|
}
|
|
1393
1717
|
if (str(quantifiedROI.paybackPeriod)) {
|
|
1394
|
-
|
|
1718
|
+
collectedFin.push({ name: 'Payback Period', target: str(quantifiedROI.paybackPeriod), direction: 'lower_is_better', unit: 'months', source: 'quantifiedROI' });
|
|
1395
1719
|
}
|
|
1396
1720
|
if (str(quantifiedROI.npv)) {
|
|
1397
|
-
|
|
1721
|
+
collectedFin.push({ name: 'NPV', target: str(quantifiedROI.npv), direction: 'higher_is_better', unit: 'currency', source: 'quantifiedROI' });
|
|
1398
1722
|
}
|
|
1399
1723
|
const annualSavings = str(rec(rec(quantifiedROI.laborCostDetail).projectedSavings).costSavingsAnnual);
|
|
1400
1724
|
if (annualSavings) {
|
|
1401
|
-
|
|
1725
|
+
collectedFin.push({ name: 'Annual Cost Savings', target: annualSavings, direction: 'higher_is_better', unit: 'currency', source: 'quantifiedROI' });
|
|
1402
1726
|
}
|
|
1403
1727
|
}
|
|
1728
|
+
const financialRows = collectedFin.map(r => {
|
|
1729
|
+
if (hasActuals) {
|
|
1730
|
+
const match = progressMap.get(normalizeMetricName(r.name));
|
|
1731
|
+
const actual = match ? match.actualValue : '-';
|
|
1732
|
+
const status = match ? match.status : '-';
|
|
1733
|
+
return `| ${r.name} | ${r.target} | ${actual} | ${status} | ${r.direction} | ${r.unit} | ${r.source} |`;
|
|
1734
|
+
}
|
|
1735
|
+
return `| ${r.name} | ${r.target} | ${r.direction} | ${r.unit} | ${r.source} |`;
|
|
1736
|
+
});
|
|
1404
1737
|
if (financialRows.length > 0) {
|
|
1405
1738
|
hasContent = true;
|
|
1406
|
-
|
|
1739
|
+
if (hasActuals) {
|
|
1740
|
+
lines.push('## Financial Metrics', '', '| Metric | Target | Actual | Status | Direction | Unit | Source |', '|--------|--------|--------|--------|-----------|------|--------|', ...financialRows, '');
|
|
1741
|
+
}
|
|
1742
|
+
else {
|
|
1743
|
+
lines.push('## Financial Metrics', '', '| Metric | Target | Direction | Unit | Source |', '|--------|--------|-----------|------|--------|', ...financialRows, '');
|
|
1744
|
+
}
|
|
1407
1745
|
}
|
|
1408
1746
|
// --- Agent-Level Metrics ---
|
|
1409
1747
|
const agentRows = [];
|
|
@@ -1412,12 +1750,25 @@ function buildEvaluationCriteria(input) {
|
|
|
1412
1750
|
const metrics = arr(a.successMetrics);
|
|
1413
1751
|
for (const item of metrics) {
|
|
1414
1752
|
const m = rec(item);
|
|
1415
|
-
|
|
1753
|
+
if (hasActuals) {
|
|
1754
|
+
const match = progressMap.get(normalizeMetricName(str(m.metric)));
|
|
1755
|
+
const actual = match ? match.actualValue : '-';
|
|
1756
|
+
const status = match ? match.status : '-';
|
|
1757
|
+
agentRows.push(`| ${str(a.name)} | ${str(m.metric)} | ${str(m.target)} | ${actual} | ${status} |`);
|
|
1758
|
+
}
|
|
1759
|
+
else {
|
|
1760
|
+
agentRows.push(`| ${str(a.name)} | ${str(m.metric)} | ${str(m.target)} |`);
|
|
1761
|
+
}
|
|
1416
1762
|
}
|
|
1417
1763
|
}
|
|
1418
1764
|
if (agentRows.length > 0) {
|
|
1419
1765
|
hasContent = true;
|
|
1420
|
-
|
|
1766
|
+
if (hasActuals) {
|
|
1767
|
+
lines.push('## Agent-Level Metrics', '', '| Agent | Metric | Target | Actual | Status |', '|-------|--------|--------|--------|--------|', ...agentRows, '');
|
|
1768
|
+
}
|
|
1769
|
+
else {
|
|
1770
|
+
lines.push('## Agent-Level Metrics', '', '| Agent | Metric | Target |', '|-------|--------|--------|', ...agentRows, '');
|
|
1771
|
+
}
|
|
1421
1772
|
}
|
|
1422
1773
|
if (!hasContent) {
|
|
1423
1774
|
lines.push('> No evaluation criteria available yet. Generate a Business Case to populate', '> operational and financial metrics, or add success metrics to agent specifications.', '');
|
|
@@ -1426,7 +1777,166 @@ function buildEvaluationCriteria(input) {
|
|
|
1426
1777
|
lines.push('## Monitoring Guidance', '', '> If using Agent Blueprint\'s performance monitoring feature, these criteria can inform metric setup:', '> - Operational metrics correspond to `metricType: "operational"`', '> - Financial metrics correspond to `metricType: "financial"`', '> - Use metric names and targets when recording actuals via the Performance tab or webhook integrations', '');
|
|
1427
1778
|
return lines.join('\n');
|
|
1428
1779
|
}
|
|
1780
|
+
function buildGettingStartedReturnVisit(input) {
|
|
1781
|
+
const lines = [];
|
|
1782
|
+
const sd = rec(input.implementationState.stateData);
|
|
1783
|
+
const stateAgents = arr(sd.agents);
|
|
1784
|
+
const team = arr(rec(input.blueprintData).enhancedDigitalTeam);
|
|
1785
|
+
const totalAgents = stateAgents.length || team.length;
|
|
1786
|
+
let implementedCount = 0;
|
|
1787
|
+
const inProgressNames = [];
|
|
1788
|
+
for (const sa of stateAgents) {
|
|
1789
|
+
const a = rec(sa);
|
|
1790
|
+
const status = str(a.status);
|
|
1791
|
+
if (status === 'implemented' || status === 'modified')
|
|
1792
|
+
implementedCount++;
|
|
1793
|
+
if (status === 'in_progress')
|
|
1794
|
+
inProgressNames.push(str(a.name));
|
|
1795
|
+
}
|
|
1796
|
+
lines.push('# Getting Started');
|
|
1797
|
+
lines.push('');
|
|
1798
|
+
lines.push('YOU ARE CONTINUING AN IMPLEMENTATION. Implementation state has been synced');
|
|
1799
|
+
lines.push('back to Agent Blueprint. Read `CURRENT-STATE.md` for where things stand');
|
|
1800
|
+
lines.push('and `RECOMMENDATIONS.md` for what to do next.');
|
|
1801
|
+
lines.push('');
|
|
1802
|
+
lines.push('## Current status');
|
|
1803
|
+
lines.push('');
|
|
1804
|
+
lines.push(`${implementedCount} of ${totalAgents} agents implemented. Overall: ${str(sd.overall_status) || 'in_progress'}.`);
|
|
1805
|
+
if (inProgressNames.length > 0) {
|
|
1806
|
+
lines.push(`In progress: ${inProgressNames.join(', ')}.`);
|
|
1807
|
+
}
|
|
1808
|
+
if (hasProgressData(input)) {
|
|
1809
|
+
const s = input.progress.summary;
|
|
1810
|
+
lines.push(`${s.onTrack} metric${s.onTrack !== 1 ? 's' : ''} on track, ${s.minorDeviation} minor deviation${s.minorDeviation !== 1 ? 's' : ''}, ${s.majorDeviation} major deviation${s.majorDeviation !== 1 ? 's' : ''}.`);
|
|
1811
|
+
}
|
|
1812
|
+
lines.push('');
|
|
1813
|
+
// Ground rules (same as first visit)
|
|
1814
|
+
lines.push('## Ground rules (MUST FOLLOW)');
|
|
1815
|
+
lines.push('');
|
|
1816
|
+
lines.push('- **Do not summarize the blueprint.** The user already knows what they bought.');
|
|
1817
|
+
lines.push(' Do not list agents, describe the architecture, or restate the problem.');
|
|
1818
|
+
lines.push(' Go straight to building.');
|
|
1819
|
+
lines.push('- **Do not ask questions you can answer yourself.** Check your configured MCP');
|
|
1820
|
+
lines.push(' servers, read the spec files, query the platform. Only ask the user when');
|
|
1821
|
+
lines.push(' you genuinely cannot proceed without their input.');
|
|
1822
|
+
lines.push('- **Act, then report.** Do not narrate what you are about to do. Do it, then');
|
|
1823
|
+
lines.push(' tell the user what you did and what comes next. One short status per milestone.');
|
|
1824
|
+
lines.push('- **Be decisive.** When you know the right approach, take it. Do not present');
|
|
1825
|
+
lines.push(' options and ask the user to choose. Recommend and act.');
|
|
1826
|
+
lines.push('- **Recover fast.** When something fails, try the obvious fix immediately.');
|
|
1827
|
+
lines.push(' One fix, one alternative, then ask. Do not spiral.');
|
|
1828
|
+
lines.push('- **Verify before presenting.** Never give the user a URL, path, or command');
|
|
1829
|
+
lines.push(' you have not verified against the actual platform instance.');
|
|
1830
|
+
lines.push('');
|
|
1831
|
+
// Step 1
|
|
1832
|
+
lines.push('## Step 1: Review current state');
|
|
1833
|
+
lines.push('');
|
|
1834
|
+
lines.push('Read `CURRENT-STATE.md` for the full implementation picture:');
|
|
1835
|
+
lines.push('- Which agents are implemented, in progress, or not started');
|
|
1836
|
+
lines.push('- Platform and architecture decisions made so far');
|
|
1837
|
+
lines.push('- Performance against targets (if metrics have been reported)');
|
|
1838
|
+
lines.push('');
|
|
1839
|
+
// Step 2
|
|
1840
|
+
lines.push('## Step 2: Follow recommendations');
|
|
1841
|
+
lines.push('');
|
|
1842
|
+
lines.push('Read `RECOMMENDATIONS.md` for prioritized next actions:');
|
|
1843
|
+
lines.push('- Agents to implement next (ordered by roadmap priority)');
|
|
1844
|
+
lines.push('- Metrics that need attention (deviations from targets)');
|
|
1845
|
+
lines.push('- Deviations from spec that warrant review');
|
|
1846
|
+
lines.push('');
|
|
1847
|
+
// Step 3
|
|
1848
|
+
lines.push('## Step 3: Continue implementation');
|
|
1849
|
+
lines.push('');
|
|
1850
|
+
if (inProgressNames.length > 0) {
|
|
1851
|
+
lines.push(`Agent${inProgressNames.length > 1 ? 's' : ''} in progress: ${inProgressNames.join(', ')}. Pick up where you left off.`);
|
|
1852
|
+
lines.push('');
|
|
1853
|
+
}
|
|
1854
|
+
if (input.vendorSkill) {
|
|
1855
|
+
lines.push(`The \`.claude/skills/${input.vendorSkill.skillName}/\` skill contains platform-specific`);
|
|
1856
|
+
lines.push('deployment guidance. Follow it for all platform-specific work.');
|
|
1857
|
+
lines.push('');
|
|
1858
|
+
}
|
|
1859
|
+
lines.push('For each agent:');
|
|
1860
|
+
lines.push('1. Review the agent spec in `references/agent-specifications.md`');
|
|
1861
|
+
lines.push('2. Build the agent with its tools and instructions');
|
|
1862
|
+
lines.push('3. Test and iterate until behavior matches the spec');
|
|
1863
|
+
lines.push('4. Update `implementation-state.yaml` with status and platform artifact');
|
|
1864
|
+
lines.push('5. Move to the next agent');
|
|
1865
|
+
lines.push('');
|
|
1866
|
+
// Step 4
|
|
1867
|
+
lines.push('## Step 4: Validate and measure');
|
|
1868
|
+
lines.push('');
|
|
1869
|
+
lines.push('Use `references/evaluation-criteria.md` to verify success metrics.');
|
|
1870
|
+
lines.push('Report actuals via MCP tool:');
|
|
1871
|
+
lines.push('');
|
|
1872
|
+
lines.push(' Use the report_metric tool with:');
|
|
1873
|
+
lines.push(` blueprintId: "${input.blueprintId}"`);
|
|
1874
|
+
lines.push(' metrics:');
|
|
1875
|
+
lines.push(' - metricName: "Metric Name"');
|
|
1876
|
+
lines.push(' actualValue: "measured value"');
|
|
1877
|
+
lines.push('');
|
|
1878
|
+
// Step 5
|
|
1879
|
+
lines.push('## Step 5: Sync your progress');
|
|
1880
|
+
lines.push('');
|
|
1881
|
+
lines.push('After implementing each agent or making significant changes, sync immediately:');
|
|
1882
|
+
lines.push('');
|
|
1883
|
+
lines.push('**MCP tool** (preferred):');
|
|
1884
|
+
lines.push('');
|
|
1885
|
+
lines.push(' Use the sync_implementation_state tool with:');
|
|
1886
|
+
lines.push(` blueprintId: "${input.blueprintId}"`);
|
|
1887
|
+
lines.push(' stateData: <contents of implementation-state.yaml as JSON>');
|
|
1888
|
+
lines.push('');
|
|
1889
|
+
lines.push('**CLI**:');
|
|
1890
|
+
lines.push('');
|
|
1891
|
+
lines.push(` agentblueprint sync --blueprint ${input.blueprintId}`);
|
|
1892
|
+
lines.push('');
|
|
1893
|
+
lines.push('When you observe actual metric values, report them via MCP tool:');
|
|
1894
|
+
lines.push('');
|
|
1895
|
+
lines.push(' Use the report_metric tool with:');
|
|
1896
|
+
lines.push(` blueprintId: "${input.blueprintId}"`);
|
|
1897
|
+
lines.push(' metrics:');
|
|
1898
|
+
lines.push(' - metricName: "Metric Name"');
|
|
1899
|
+
lines.push(' actualValue: "measured value"');
|
|
1900
|
+
lines.push('');
|
|
1901
|
+
lines.push('See `AGENTS.md` for trigger points, deviation rules, and full sync guidance.');
|
|
1902
|
+
lines.push('');
|
|
1903
|
+
lines.push('**Claude Code users**: See `hooks/claude-code-sync.json` for a Stop hook that');
|
|
1904
|
+
lines.push('reminds you to sync when implementation-state.yaml has unsynced changes.');
|
|
1905
|
+
lines.push('');
|
|
1906
|
+
// Platform patterns (same as first visit)
|
|
1907
|
+
lines.push('## Platform patterns');
|
|
1908
|
+
lines.push('');
|
|
1909
|
+
lines.push('These patterns help you map the vendor-agnostic spec to your target platform:');
|
|
1910
|
+
lines.push('');
|
|
1911
|
+
lines.push('- **Agent orchestration**: Look for your platform\'s agent/bot framework,');
|
|
1912
|
+
lines.push(' workflow engine, or flow builder. The spec describes a');
|
|
1913
|
+
const pattern = getPatternName(input);
|
|
1914
|
+
if (pattern) {
|
|
1915
|
+
lines.push(` ${pattern} pattern -- find your platform's equivalent orchestration mechanism.`);
|
|
1916
|
+
}
|
|
1917
|
+
else {
|
|
1918
|
+
lines.push(' multi-agent pattern -- find your platform\'s equivalent orchestration mechanism.');
|
|
1919
|
+
}
|
|
1920
|
+
lines.push('- **Data integration**: Check what APIs or connectors exist for the data sources');
|
|
1921
|
+
lines.push(' listed in `references/architecture-decisions.md`. Prefer native connectors');
|
|
1922
|
+
lines.push(' over custom API calls.');
|
|
1923
|
+
lines.push('- **Guardrails**: Map the escalation rules from `references/guardrails-and-governance.md`');
|
|
1924
|
+
lines.push(' to platform-native controls (approval chains, role-based access, audit logs).');
|
|
1925
|
+
lines.push('- **Scoping**: Some platforms have namespace or scope constraints on API-created');
|
|
1926
|
+
lines.push(' records. If records don\'t appear in the expected scope, check your platform\'s');
|
|
1927
|
+
lines.push(' documentation on scoped app deployment.');
|
|
1928
|
+
lines.push('');
|
|
1929
|
+
// Footer
|
|
1930
|
+
lines.push('---');
|
|
1931
|
+
lines.push('');
|
|
1932
|
+
lines.push('Generated by [Agent Blueprint](https://app.agentblueprint.ai)');
|
|
1933
|
+
lines.push('');
|
|
1934
|
+
return lines.join('\n');
|
|
1935
|
+
}
|
|
1429
1936
|
function buildGettingStarted(input) {
|
|
1937
|
+
if (hasImplementationData(input)) {
|
|
1938
|
+
return buildGettingStartedReturnVisit(input);
|
|
1939
|
+
}
|
|
1430
1940
|
const lines = [];
|
|
1431
1941
|
lines.push('# Getting Started');
|
|
1432
1942
|
lines.push('');
|
|
@@ -1497,10 +2007,11 @@ function buildGettingStarted(input) {
|
|
|
1497
2007
|
lines.push('platform that supports AI agents with tool use.');
|
|
1498
2008
|
lines.push('');
|
|
1499
2009
|
// Step 3
|
|
1500
|
-
lines.push('## Step 3:
|
|
2010
|
+
lines.push('## Step 3: Build and validate the pilot');
|
|
1501
2011
|
lines.push('');
|
|
1502
2012
|
lines.push('Check `references/implementation-roadmap.md` for Phase 1 scope.');
|
|
1503
|
-
lines.push('Build the lead agent first.
|
|
2013
|
+
lines.push('Build the lead agent first. **Do not expand to remaining agents until the');
|
|
2014
|
+
lines.push('pilot is fully working with real data.** This is a gate, not a suggestion.');
|
|
1504
2015
|
lines.push('');
|
|
1505
2016
|
if (input.vendorSkill) {
|
|
1506
2017
|
lines.push(`The \`.claude/skills/${input.vendorSkill.skillName}/\` skill contains the deployment`);
|
|
@@ -1511,17 +2022,50 @@ function buildGettingStarted(input) {
|
|
|
1511
2022
|
lines.push('follow its deployment sequence instead of the general pattern below.');
|
|
1512
2023
|
}
|
|
1513
2024
|
lines.push('');
|
|
1514
|
-
lines.push('
|
|
1515
|
-
lines.push('
|
|
1516
|
-
lines.push('
|
|
1517
|
-
lines.push('
|
|
1518
|
-
lines.push('
|
|
1519
|
-
lines.push('
|
|
1520
|
-
lines.push('
|
|
2025
|
+
lines.push('### Pilot progression');
|
|
2026
|
+
lines.push('');
|
|
2027
|
+
lines.push('**Phase A: Scaffold and validate orchestration.**');
|
|
2028
|
+
lines.push('1. Create the application container (scoped app, project, etc.) for the pilot.');
|
|
2029
|
+
lines.push(' State your intent: "I\'ll create a new application called \'[Name]\' to contain all agents."');
|
|
2030
|
+
lines.push('2. Build the first worker agent with its tools and instructions.');
|
|
2031
|
+
lines.push('3. Use simulation scripts to validate the LLM orchestration (tool chaining,');
|
|
2032
|
+
lines.push(' parameter passing, sequencing). This proves the agent can chain tools correctly.');
|
|
2033
|
+
lines.push('4. **Test before proceeding.** Invoke the agent programmatically, read the execution');
|
|
2034
|
+
lines.push(' trace, verify each tool produced output. Do not rely on UI testing alone. Re-test');
|
|
2035
|
+
lines.push(' until the full tool chain completes end-to-end.');
|
|
2036
|
+
lines.push('');
|
|
2037
|
+
lines.push('**Phase B: Make the pilot real.** Simulation scripts are not a finished pilot.');
|
|
2038
|
+
lines.push('5. Replace simulation scripts with real implementations that connect to actual');
|
|
2039
|
+
lines.push(' data sources, APIs, and platform tables.');
|
|
2040
|
+
lines.push('6. Test again with real data. The pilot should deliver measurable business value,');
|
|
2041
|
+
lines.push(' not just prove tool chaining works.');
|
|
2042
|
+
lines.push('');
|
|
2043
|
+
lines.push('**Phase C: Expand.** Only after the pilot works end-to-end with real data:');
|
|
2044
|
+
lines.push('7. Add remaining agents one at a time, testing after each.');
|
|
2045
|
+
lines.push('8. Wire the orchestrator last, once all workers are validated.');
|
|
2046
|
+
lines.push('');
|
|
2047
|
+
lines.push('### Your role through implementation');
|
|
2048
|
+
lines.push('');
|
|
2049
|
+
lines.push('Your job does not end when simulation scripts are deployed. Stay with the user');
|
|
2050
|
+
lines.push('through the full implementation. Operate in three modes:');
|
|
2051
|
+
lines.push('');
|
|
2052
|
+
lines.push('1. **Do it directly.** When you have system access (MCP, API, credentials), do the');
|
|
2053
|
+
lines.push(' work yourself. Create records, write scripts, configure integrations, test.');
|
|
2054
|
+
lines.push('2. **Offer to do it with access.** When you know how but lack credentials or');
|
|
2055
|
+
lines.push(' permissions, tell the user what you need.');
|
|
2056
|
+
lines.push('3. **Walk the user through it.** When only the user can act (UI-only config,');
|
|
2057
|
+
lines.push(' credential vaults, third-party admin consoles), give exact step-by-step');
|
|
2058
|
+
lines.push(' instructions, then verify programmatically that it worked.');
|
|
1521
2059
|
lines.push('');
|
|
1522
2060
|
// Step 4
|
|
1523
2061
|
lines.push('## Step 4: Validate');
|
|
1524
2062
|
lines.push('');
|
|
2063
|
+
lines.push('**Test programmatically, not just in the UI.** Invoke agents via API or');
|
|
2064
|
+
lines.push('server-side scripts. Read execution traces to verify each tool produced');
|
|
2065
|
+
lines.push('output. Do not rely on sleep/wait loops -- poll the execution state tables.');
|
|
2066
|
+
lines.push('If execution trace tables are access-restricted, use server-side scripts');
|
|
2067
|
+
lines.push('(e.g., background scripts with GlideRecord) to read them.');
|
|
2068
|
+
lines.push('');
|
|
1525
2069
|
lines.push('Use `references/evaluation-criteria.md` to verify success metrics');
|
|
1526
2070
|
lines.push('are measurable in the target platform. Run `scripts/validate-spec.sh`');
|
|
1527
2071
|
lines.push('to check structural completeness of the spec files.');
|
|
@@ -1538,15 +2082,40 @@ function buildGettingStarted(input) {
|
|
|
1538
2082
|
lines.push('5. Update `overall_status` as you progress.');
|
|
1539
2083
|
lines.push('6. Fill in the `platform` section with the actual platform, version, and environment.');
|
|
1540
2084
|
lines.push('');
|
|
1541
|
-
lines.push('
|
|
2085
|
+
lines.push('### Sync trigger points');
|
|
2086
|
+
lines.push('');
|
|
2087
|
+
lines.push('Sync after each of these events (do not wait until the end):');
|
|
2088
|
+
lines.push('- After implementing an agent');
|
|
2089
|
+
lines.push('- After connecting an integration');
|
|
2090
|
+
lines.push('- After modifying an agent\'s behavior');
|
|
2091
|
+
lines.push('- At the end of every coding session');
|
|
2092
|
+
lines.push('');
|
|
2093
|
+
lines.push('### How to sync');
|
|
2094
|
+
lines.push('');
|
|
2095
|
+
lines.push('**MCP tool** (preferred when Agent Blueprint MCP server is connected):');
|
|
1542
2096
|
lines.push('');
|
|
1543
|
-
lines.push('
|
|
1544
|
-
lines.push(
|
|
2097
|
+
lines.push(' Use the sync_implementation_state tool with:');
|
|
2098
|
+
lines.push(` blueprintId: "${input.blueprintId}"`);
|
|
2099
|
+
lines.push(' stateData: <contents of implementation-state.yaml as JSON>');
|
|
1545
2100
|
lines.push('');
|
|
1546
|
-
lines.push('
|
|
2101
|
+
lines.push('**CLI**:');
|
|
1547
2102
|
lines.push('');
|
|
1548
|
-
lines.push(
|
|
1549
|
-
lines.push('
|
|
2103
|
+
lines.push(` agentblueprint sync --blueprint ${input.blueprintId}`);
|
|
2104
|
+
lines.push('');
|
|
2105
|
+
lines.push('### Reporting metrics');
|
|
2106
|
+
lines.push('');
|
|
2107
|
+
lines.push('When you observe actual metric values in the running system, report them:');
|
|
2108
|
+
lines.push('');
|
|
2109
|
+
lines.push(' Use the report_metric tool with:');
|
|
2110
|
+
lines.push(` blueprintId: "${input.blueprintId}"`);
|
|
2111
|
+
lines.push(' metrics:');
|
|
2112
|
+
lines.push(' - metricName: "Metric Name"');
|
|
2113
|
+
lines.push(' actualValue: "measured value"');
|
|
2114
|
+
lines.push('');
|
|
2115
|
+
lines.push('See `AGENTS.md` for the full sync rules and all trigger points.');
|
|
2116
|
+
lines.push('');
|
|
2117
|
+
lines.push('**Claude Code users**: See `hooks/claude-code-sync.json` for a Stop hook that');
|
|
2118
|
+
lines.push('reminds you to sync when implementation-state.yaml has unsynced changes.');
|
|
1550
2119
|
lines.push('');
|
|
1551
2120
|
// Platform patterns
|
|
1552
2121
|
lines.push('## Platform patterns');
|
|
@@ -1749,7 +2318,7 @@ function buildImplementationState(input) {
|
|
|
1749
2318
|
// Header
|
|
1750
2319
|
lines.push('# implementation-state.yaml');
|
|
1751
2320
|
lines.push('# Updated by the coding agent as implementation progresses.');
|
|
1752
|
-
lines.push(
|
|
2321
|
+
lines.push(`# Sync back to Agent Blueprint: agentblueprint sync --blueprint ${input.blueprintId}`);
|
|
1753
2322
|
lines.push('');
|
|
1754
2323
|
lines.push('schema_version: "1.0"');
|
|
1755
2324
|
lines.push(`blueprint_id: "${input.blueprintId}"`);
|
|
@@ -1834,6 +2403,122 @@ function buildImplementationState(input) {
|
|
|
1834
2403
|
return lines.join('\n') + '\n';
|
|
1835
2404
|
}
|
|
1836
2405
|
// =============================================================================
|
|
2406
|
+
// AGENTS.MD -- UNIVERSAL SYNC RULES
|
|
2407
|
+
// =============================================================================
|
|
2408
|
+
function buildAgentsMd(input) {
|
|
2409
|
+
const bpId = input.blueprintId;
|
|
2410
|
+
const lines = [];
|
|
2411
|
+
lines.push('# Sync Rules');
|
|
2412
|
+
lines.push('');
|
|
2413
|
+
lines.push('Rules for keeping Agent Blueprint in sync with your implementation.');
|
|
2414
|
+
lines.push('These apply to ALL coding agents regardless of IDE or framework.');
|
|
2415
|
+
lines.push('');
|
|
2416
|
+
lines.push('## Blueprint ID');
|
|
2417
|
+
lines.push('');
|
|
2418
|
+
lines.push(` ${bpId}`);
|
|
2419
|
+
lines.push('');
|
|
2420
|
+
lines.push('## When to sync implementation state');
|
|
2421
|
+
lines.push('');
|
|
2422
|
+
lines.push('Sync after each of these events:');
|
|
2423
|
+
lines.push('- After implementing an agent (status: not_started -> implemented)');
|
|
2424
|
+
lines.push('- After connecting an integration to an agent');
|
|
2425
|
+
lines.push('- After modifying an already-implemented agent (status -> modified)');
|
|
2426
|
+
lines.push('- After changing architecture decisions (e.g., switching orchestration pattern)');
|
|
2427
|
+
lines.push('- At the end of every coding session, if any agents changed');
|
|
2428
|
+
lines.push('');
|
|
2429
|
+
lines.push('## How to sync');
|
|
2430
|
+
lines.push('');
|
|
2431
|
+
lines.push('**MCP tool** (preferred when Agent Blueprint MCP server is connected):');
|
|
2432
|
+
lines.push('');
|
|
2433
|
+
lines.push(' Use the sync_implementation_state tool with:');
|
|
2434
|
+
lines.push(` blueprintId: "${bpId}"`);
|
|
2435
|
+
lines.push(' stateData: <contents of implementation-state.yaml as JSON>');
|
|
2436
|
+
lines.push('');
|
|
2437
|
+
lines.push('**CLI** (alternative):');
|
|
2438
|
+
lines.push('');
|
|
2439
|
+
lines.push(` agentblueprint sync --blueprint ${bpId}`);
|
|
2440
|
+
lines.push('');
|
|
2441
|
+
lines.push('Both methods accept the data from implementation-state.yaml. Keep that file');
|
|
2442
|
+
lines.push('updated as you work.');
|
|
2443
|
+
lines.push('');
|
|
2444
|
+
lines.push('## When to report metrics');
|
|
2445
|
+
lines.push('');
|
|
2446
|
+
lines.push('Report metrics when you observe actual values in the running system:');
|
|
2447
|
+
lines.push('- After deploying an agent and observing its first real outputs');
|
|
2448
|
+
lines.push('- When reviewing dashboards or logs that show metric values');
|
|
2449
|
+
lines.push('- During validation testing against success criteria');
|
|
2450
|
+
lines.push('- Periodically as the system runs in production');
|
|
2451
|
+
lines.push('');
|
|
2452
|
+
lines.push('## How to report metrics');
|
|
2453
|
+
lines.push('');
|
|
2454
|
+
lines.push('**MCP tool**:');
|
|
2455
|
+
lines.push('');
|
|
2456
|
+
lines.push(' Use the report_metric tool with:');
|
|
2457
|
+
lines.push(` blueprintId: "${bpId}"`);
|
|
2458
|
+
lines.push(' metrics:');
|
|
2459
|
+
lines.push(' - metricName: "Metric Name"');
|
|
2460
|
+
lines.push(' actualValue: "measured value"');
|
|
2461
|
+
lines.push(' notes: "how/where you measured this"');
|
|
2462
|
+
lines.push('');
|
|
2463
|
+
lines.push('Metric reporting is MCP-only. There is no CLI equivalent yet.');
|
|
2464
|
+
lines.push('');
|
|
2465
|
+
lines.push('## Documenting deviations');
|
|
2466
|
+
lines.push('');
|
|
2467
|
+
lines.push('When you deviate from the spec (different tool, different approach, skipped an agent):');
|
|
2468
|
+
lines.push('1. Update the agent\'s `deviations` array in implementation-state.yaml');
|
|
2469
|
+
lines.push('2. Include a brief reason (e.g., "Used Flow Designer instead of Workflow -- better parallel support")');
|
|
2470
|
+
lines.push('3. Sync so Agent Blueprint can track spec drift and adjust recommendations');
|
|
2471
|
+
lines.push('');
|
|
2472
|
+
lines.push('## Why this matters');
|
|
2473
|
+
lines.push('');
|
|
2474
|
+
lines.push('Each sync creates a versioned snapshot. Agent Blueprint uses your progress to:');
|
|
2475
|
+
lines.push('- Generate prioritized next-step recommendations');
|
|
2476
|
+
lines.push('- Track spec drift and surface deviations that need attention');
|
|
2477
|
+
lines.push('- Compare actual performance against predicted targets');
|
|
2478
|
+
lines.push('- Improve future blueprints based on real-world outcomes');
|
|
2479
|
+
lines.push('');
|
|
2480
|
+
return lines.join('\n');
|
|
2481
|
+
}
|
|
2482
|
+
// =============================================================================
|
|
2483
|
+
// CLAUDE CODE HOOKS REFERENCE
|
|
2484
|
+
// =============================================================================
|
|
2485
|
+
function buildClaudeCodeHooksConfig(input) {
|
|
2486
|
+
const bpId = input.blueprintId;
|
|
2487
|
+
// Shell command: read stdin, check stop_hook_active, check for implementation-state.yaml changes
|
|
2488
|
+
// Uses jq for JSON parsing (no python3). Uses git status --porcelain to catch both tracked and untracked changes.
|
|
2489
|
+
// Stop hooks: exit 0 with no output = allow stop. Output {"decision":"block","reason":"..."} = block stop.
|
|
2490
|
+
const command = [
|
|
2491
|
+
'INPUT=$(cat);',
|
|
2492
|
+
'ACTIVE=$(echo "$INPUT" | jq -r \'.stop_hook_active // false\');',
|
|
2493
|
+
'if [ "$ACTIVE" = "true" ]; then exit 0; fi;',
|
|
2494
|
+
'if git status --porcelain 2>/dev/null | grep -q "implementation-state.yaml"; then',
|
|
2495
|
+
` echo '{"decision":"block","reason":"implementation-state.yaml has unsynced changes. Run: agentblueprint sync ${bpId}"}';`,
|
|
2496
|
+
'fi',
|
|
2497
|
+
].join(' ');
|
|
2498
|
+
const config = {
|
|
2499
|
+
_comment: [
|
|
2500
|
+
'Claude Code Stop hook reference for automated Agent Blueprint sync.',
|
|
2501
|
+
'Copy the "hooks" section into .claude/settings.json or .claude/settings.local.json.',
|
|
2502
|
+
'Review and adapt for your project before installing.',
|
|
2503
|
+
`Blueprint ID: ${bpId}`,
|
|
2504
|
+
].join(' '),
|
|
2505
|
+
hooks: {
|
|
2506
|
+
Stop: [
|
|
2507
|
+
{
|
|
2508
|
+
hooks: [
|
|
2509
|
+
{
|
|
2510
|
+
type: 'command',
|
|
2511
|
+
command,
|
|
2512
|
+
timeout: 30,
|
|
2513
|
+
},
|
|
2514
|
+
],
|
|
2515
|
+
},
|
|
2516
|
+
],
|
|
2517
|
+
},
|
|
2518
|
+
};
|
|
2519
|
+
return JSON.stringify(config, null, 2) + '\n';
|
|
2520
|
+
}
|
|
2521
|
+
// =============================================================================
|
|
1837
2522
|
// MAIN RENDER FUNCTION
|
|
1838
2523
|
// =============================================================================
|
|
1839
2524
|
/**
|
|
@@ -1858,6 +2543,10 @@ export function renderSkillDirectory(input) {
|
|
|
1858
2543
|
files.set('references/platform-connectivity.md', buildPlatformConnectivity());
|
|
1859
2544
|
// Getting Started guide
|
|
1860
2545
|
files.set('GETTING-STARTED.md', buildGettingStarted(input));
|
|
2546
|
+
// Sync rules (universal -- all coding agents via AGENTS.md standard)
|
|
2547
|
+
files.set('AGENTS.md', buildAgentsMd(input));
|
|
2548
|
+
// Claude Code hooks reference (agent-specific -- Claude Code only)
|
|
2549
|
+
files.set('hooks/claude-code-sync.json', buildClaudeCodeHooksConfig(input));
|
|
1861
2550
|
// Deployment guides (vendor skill replaces vendor deployment guide when present)
|
|
1862
2551
|
if (input.generalGuide) {
|
|
1863
2552
|
files.set('references/deployment-guide-general.md', input.generalGuide);
|
|
@@ -1873,6 +2562,13 @@ export function renderSkillDirectory(input) {
|
|
|
1873
2562
|
files.set('scripts/validate-spec.sh', buildValidateScript());
|
|
1874
2563
|
// Implementation state template
|
|
1875
2564
|
files.set('implementation-state.yaml', buildImplementationState(input));
|
|
2565
|
+
// Reality layer (return visits -- Living Blueprint Phase 3A)
|
|
2566
|
+
if (hasImplementationData(input)) {
|
|
2567
|
+
files.set('CURRENT-STATE.md', buildCurrentState(input));
|
|
2568
|
+
}
|
|
2569
|
+
if (hasImplementationData(input) || hasProgressData(input)) {
|
|
2570
|
+
files.set('RECOMMENDATIONS.md', buildRecommendations(input));
|
|
2571
|
+
}
|
|
1876
2572
|
return files;
|
|
1877
2573
|
}
|
|
1878
2574
|
//# sourceMappingURL=renderers.js.map
|