@agentblueprint/mcp-server 0.2.1 → 0.3.1
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 +107 -11
- package/dist/__tests__/renderers.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +2 -2
- package/dist/client.d.ts +1 -0
- package/dist/download.js +3 -1
- package/dist/download.js.map +1 -1
- package/dist/renderers.d.ts +1 -0
- package/dist/renderers.js +464 -104
- package/dist/renderers.js.map +1 -1
- package/dist/tools/download-blueprint.js +3 -1
- package/dist/tools/download-blueprint.js.map +1 -1
- package/package.json +1 -1
package/dist/renderers.js
CHANGED
|
@@ -24,6 +24,26 @@ function arr(val) {
|
|
|
24
24
|
function rec(val) {
|
|
25
25
|
return val && typeof val === 'object' && !Array.isArray(val) ? val : {};
|
|
26
26
|
}
|
|
27
|
+
/** Returns string representation for numbers, passes through strings, '' otherwise */
|
|
28
|
+
function numStr(val) {
|
|
29
|
+
if (typeof val === 'number')
|
|
30
|
+
return String(val);
|
|
31
|
+
if (typeof val === 'string')
|
|
32
|
+
return val;
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
/** Checks if a string value is a placeholder/garbage value that shouldn't be rendered */
|
|
36
|
+
function isPlaceholder(val) {
|
|
37
|
+
return ['—', '–', '-', 'N/A', 'n/a', 'TBD', 'null', 'undefined', 'none'].includes(val.trim());
|
|
38
|
+
}
|
|
39
|
+
/** Strips a trailing unit suffix to prevent double-units (e.g. "3.6 months" + " months") */
|
|
40
|
+
function stripTrailingUnit(val, unit) {
|
|
41
|
+
return val.replace(new RegExp(`\\s*${unit}\\s*$`, 'i'), '');
|
|
42
|
+
}
|
|
43
|
+
/** Joins string arrays with separator; returns '' for non-arrays */
|
|
44
|
+
function arrStr(val, sep = ', ') {
|
|
45
|
+
return Array.isArray(val) ? val.filter((v) => typeof v === 'string').join(sep) : '';
|
|
46
|
+
}
|
|
27
47
|
function getPlatformName(bp) {
|
|
28
48
|
const pr = rec(bp.platformRecommendation);
|
|
29
49
|
const pp = rec(pr.primaryPlatform);
|
|
@@ -43,7 +63,12 @@ function getInvestmentTier(bc) {
|
|
|
43
63
|
const amount = str(ask.investmentAmount);
|
|
44
64
|
if (!amount)
|
|
45
65
|
return 'unknown';
|
|
46
|
-
|
|
66
|
+
// Extract the first number group only (avoid concatenating multiple numbers
|
|
67
|
+
// e.g. "$13,143 one-time + $2,981 annual" → 13143, not 131432981)
|
|
68
|
+
const match = amount.match(/[\d,]+(?:\.\d+)?/);
|
|
69
|
+
if (!match)
|
|
70
|
+
return 'unknown';
|
|
71
|
+
const num = parseFloat(match[0].replace(/,/g, ''));
|
|
47
72
|
if (isNaN(num))
|
|
48
73
|
return 'unknown';
|
|
49
74
|
if (num < 100000)
|
|
@@ -131,89 +156,130 @@ function buildSkillBody(input) {
|
|
|
131
156
|
});
|
|
132
157
|
lines.push('');
|
|
133
158
|
lines.push('> Full agent specifications in `references/agent-specifications.md`', '');
|
|
134
|
-
// Phase
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
lines.push('**Pilot workstreams:**', '');
|
|
150
|
-
for (const ws of workstreams) {
|
|
151
|
-
const w = rec(ws);
|
|
152
|
-
lines.push(`- ${str(w.title)}`);
|
|
159
|
+
// Phase rendering — prefer implementation plan epics when available
|
|
160
|
+
const ipEpics = input.implementationPlanData ? arr(rec(input.implementationPlanData).epics) : [];
|
|
161
|
+
if (ipEpics.length > 0) {
|
|
162
|
+
const pilotEpics = ipEpics.filter((e) => str(rec(e).phase).toLowerCase().includes('pilot'));
|
|
163
|
+
const fullEpics = ipEpics.filter((e) => !str(rec(e).phase).toLowerCase().includes('pilot'));
|
|
164
|
+
lines.push('## Phase 1: Pilot', '');
|
|
165
|
+
if (pilotEpics.length > 0) {
|
|
166
|
+
const seen = new Set();
|
|
167
|
+
for (const epic of pilotEpics) {
|
|
168
|
+
const e = rec(epic);
|
|
169
|
+
const name = str(e.name);
|
|
170
|
+
if (name && !seen.has(name)) {
|
|
171
|
+
seen.add(name);
|
|
172
|
+
lines.push(`- **${name}**${str(e.estimatedDuration) ? ` (${str(e.estimatedDuration)})` : ''}`);
|
|
173
|
+
}
|
|
153
174
|
}
|
|
154
175
|
lines.push('');
|
|
155
176
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
177
|
+
else {
|
|
178
|
+
lines.push('_No pilot epics defined. See `references/implementation-roadmap.md` for phasing._', '');
|
|
179
|
+
}
|
|
180
|
+
lines.push('## Phase 2: Full Implementation', '');
|
|
181
|
+
if (fullEpics.length > 0) {
|
|
182
|
+
const seen = new Set();
|
|
183
|
+
for (const epic of fullEpics) {
|
|
184
|
+
const e = rec(epic);
|
|
185
|
+
const name = str(e.name);
|
|
186
|
+
if (name && !seen.has(name)) {
|
|
187
|
+
seen.add(name);
|
|
188
|
+
lines.push(`- **${name}**${str(e.estimatedDuration) ? ` (${str(e.estimatedDuration)})` : ''}`);
|
|
189
|
+
}
|
|
163
190
|
}
|
|
164
191
|
lines.push('');
|
|
165
192
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
lines.push('**Exit criteria:**', '');
|
|
169
|
-
for (const c of exitCriteria)
|
|
170
|
-
lines.push(`- ${c}`);
|
|
171
|
-
lines.push('');
|
|
193
|
+
else {
|
|
194
|
+
lines.push('_See `references/implementation-roadmap.md` for full rollout plan._', '');
|
|
172
195
|
}
|
|
173
196
|
}
|
|
174
197
|
else {
|
|
175
|
-
lines.push('
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (fullPhases.length > 0) {
|
|
181
|
-
for (const phase of fullPhases) {
|
|
182
|
-
const p = rec(phase);
|
|
183
|
-
lines.push(`### ${str(p.name)}`, '');
|
|
198
|
+
lines.push('## Phase 1: Pilot', '');
|
|
199
|
+
const phases = arr(bp.phases);
|
|
200
|
+
const pilotPhase = phases.find((p) => str(p?.name).toLowerCase().includes('pilot') || str(p?.name).toLowerCase().includes('phase 1'));
|
|
201
|
+
if (pilotPhase) {
|
|
202
|
+
const p = rec(pilotPhase);
|
|
184
203
|
if (str(p.phaseGoal))
|
|
185
|
-
lines.push(str(p.phaseGoal)
|
|
204
|
+
lines.push(`**Goal:** ${str(p.phaseGoal)}`, '');
|
|
186
205
|
if (p.durationWeeks)
|
|
187
206
|
lines.push(`**Duration:** ${p.durationWeeks} weeks`);
|
|
188
207
|
if (str(p.phaseCost))
|
|
189
|
-
lines.push(`**Cost:** ${str(p.phaseCost)}`);
|
|
208
|
+
lines.push(`**Cost target:** ${str(p.phaseCost)}`);
|
|
190
209
|
lines.push('');
|
|
210
|
+
const workstreams = arr(p.workstreams);
|
|
211
|
+
if (workstreams.length > 0) {
|
|
212
|
+
lines.push('**Pilot workstreams:**', '');
|
|
213
|
+
for (const ws of workstreams) {
|
|
214
|
+
const w = rec(ws);
|
|
215
|
+
lines.push(`- ${str(w.title)}`);
|
|
216
|
+
}
|
|
217
|
+
lines.push('');
|
|
218
|
+
}
|
|
219
|
+
const gate = rec(p.decisionGate);
|
|
220
|
+
if (gate.criteria) {
|
|
221
|
+
lines.push('**Decision gate criteria:**', '');
|
|
222
|
+
for (const c of arr(gate.criteria)) {
|
|
223
|
+
const cr = rec(c);
|
|
224
|
+
const label = str(cr.name) || str(cr.criterion) || str(cr.metric) || str(cr.description) || 'Unnamed criterion';
|
|
225
|
+
lines.push(`- ${label}: ${str(cr.target) || str(cr.threshold)}`);
|
|
226
|
+
}
|
|
227
|
+
lines.push('');
|
|
228
|
+
}
|
|
229
|
+
const exitCriteria = arr(p.exitCriteria);
|
|
230
|
+
if (exitCriteria.length > 0) {
|
|
231
|
+
lines.push('**Exit criteria:**', '');
|
|
232
|
+
for (const c of exitCriteria)
|
|
233
|
+
lines.push(`- ${c}`);
|
|
234
|
+
lines.push('');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
lines.push('_No pilot phase defined. See `references/implementation-roadmap.md` for phasing._', '');
|
|
239
|
+
}
|
|
240
|
+
lines.push('## Phase 2: Full Implementation', '');
|
|
241
|
+
const fullPhases = phases.filter((p) => !str(p?.name).toLowerCase().includes('pilot') && !str(p?.name).toLowerCase().includes('phase 1'));
|
|
242
|
+
if (fullPhases.length > 0) {
|
|
243
|
+
for (const phase of fullPhases) {
|
|
244
|
+
const p = rec(phase);
|
|
245
|
+
lines.push(`### ${str(p.name)}`, '');
|
|
246
|
+
if (str(p.phaseGoal))
|
|
247
|
+
lines.push(str(p.phaseGoal), '');
|
|
248
|
+
if (p.durationWeeks)
|
|
249
|
+
lines.push(`**Duration:** ${p.durationWeeks} weeks`);
|
|
250
|
+
if (str(p.phaseCost))
|
|
251
|
+
lines.push(`**Cost:** ${str(p.phaseCost)}`);
|
|
252
|
+
lines.push('');
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
lines.push('_See `references/implementation-roadmap.md` for full rollout plan._', '');
|
|
191
257
|
}
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
lines.push('_See `references/implementation-roadmap.md` for full rollout plan._', '');
|
|
195
258
|
}
|
|
196
259
|
// Financial Summary
|
|
197
260
|
lines.push('## Financial Summary', '');
|
|
198
261
|
if (bc) {
|
|
199
262
|
const benefits = rec(bc.benefits);
|
|
200
263
|
const quantifiedROI = rec(benefits.quantifiedROI);
|
|
201
|
-
if (str(quantifiedROI.roi))
|
|
264
|
+
if (str(quantifiedROI.roi) && !isPlaceholder(str(quantifiedROI.roi)))
|
|
202
265
|
lines.push(`- **ROI:** ${str(quantifiedROI.roi)}`);
|
|
203
|
-
if (str(quantifiedROI.npv))
|
|
266
|
+
if (str(quantifiedROI.npv) && !isPlaceholder(str(quantifiedROI.npv)))
|
|
204
267
|
lines.push(`- **NPV:** ${str(quantifiedROI.npv)}`);
|
|
205
|
-
if (str(quantifiedROI.paybackPeriod))
|
|
268
|
+
if (str(quantifiedROI.paybackPeriod) && !isPlaceholder(str(quantifiedROI.paybackPeriod)))
|
|
206
269
|
lines.push(`- **Payback:** ${str(quantifiedROI.paybackPeriod)}`);
|
|
207
270
|
const pilotROI = rec(quantifiedROI.pilotROI);
|
|
208
|
-
|
|
271
|
+
const skillPilotCapex = str(rec(pilotROI.pilotCapex).value);
|
|
272
|
+
const skillPilotSavings = str(rec(pilotROI.pilotAnnualSavings).value);
|
|
273
|
+
const skillPilotYear1Net = str(rec(pilotROI.pilotYear1Net).value);
|
|
274
|
+
if (skillPilotCapex || skillPilotSavings) {
|
|
209
275
|
lines.push('');
|
|
210
276
|
lines.push('**Pilot economics:**');
|
|
211
|
-
if (
|
|
212
|
-
lines.push(`- Pilot
|
|
213
|
-
if (
|
|
214
|
-
lines.push(`- Pilot
|
|
215
|
-
if (
|
|
216
|
-
lines.push(`- Pilot
|
|
277
|
+
if (skillPilotCapex)
|
|
278
|
+
lines.push(`- Pilot capex: ${skillPilotCapex}`);
|
|
279
|
+
if (skillPilotSavings)
|
|
280
|
+
lines.push(`- Pilot annual savings: ${skillPilotSavings}`);
|
|
281
|
+
if (skillPilotYear1Net)
|
|
282
|
+
lines.push(`- Pilot Year 1 net: ${skillPilotYear1Net}`);
|
|
217
283
|
}
|
|
218
284
|
lines.push('');
|
|
219
285
|
lines.push('> Full financial analysis in `references/financial-case.md`', '');
|
|
@@ -344,6 +410,244 @@ function buildBusinessContext(input) {
|
|
|
344
410
|
}
|
|
345
411
|
return lines.join('\n');
|
|
346
412
|
}
|
|
413
|
+
function buildOrganizationContext(input) {
|
|
414
|
+
const bp = input.businessProfileData;
|
|
415
|
+
const lines = ['# Organization Context', ''];
|
|
416
|
+
if (!bp) {
|
|
417
|
+
lines.push('_No business profile data available. Create a Business Profile to enrich this section._', '');
|
|
418
|
+
return lines.join('\n');
|
|
419
|
+
}
|
|
420
|
+
// Company overview
|
|
421
|
+
const companyName = str(bp.companyName);
|
|
422
|
+
if (companyName) {
|
|
423
|
+
lines.push(`## ${companyName}`, '');
|
|
424
|
+
}
|
|
425
|
+
if (str(bp.description))
|
|
426
|
+
lines.push(str(bp.description), '');
|
|
427
|
+
// Industry & scale
|
|
428
|
+
if (str(bp.industry) || str(bp.size) || str(bp.revenue)) {
|
|
429
|
+
lines.push('## Industry & Scale', '');
|
|
430
|
+
if (str(bp.industry))
|
|
431
|
+
lines.push(`- **Industry:** ${str(bp.industry)}`);
|
|
432
|
+
if (str(bp.size))
|
|
433
|
+
lines.push(`- **Company size:** ${str(bp.size)}`);
|
|
434
|
+
if (str(bp.revenue))
|
|
435
|
+
lines.push(`- **Revenue:** ${str(bp.revenue)}`);
|
|
436
|
+
if (str(bp.currency) && str(bp.currency) !== 'USD')
|
|
437
|
+
lines.push(`- **Currency:** ${str(bp.currency)}`);
|
|
438
|
+
lines.push('');
|
|
439
|
+
}
|
|
440
|
+
// Technology profile
|
|
441
|
+
const tech = rec(bp.technologyProfile);
|
|
442
|
+
const systems = arr(tech.systems);
|
|
443
|
+
const dataInfra = rec(tech.dataInfrastructure);
|
|
444
|
+
const integration = rec(tech.integrationCapabilities);
|
|
445
|
+
const security = rec(tech.securityCompliance);
|
|
446
|
+
if (systems.length > 0 || dataInfra.cloudPlatforms || dataInfra.dataWarehouseExists !== undefined || integration.apiReadiness || integration.apiMaturity) {
|
|
447
|
+
lines.push('## Technology Landscape', '');
|
|
448
|
+
if (systems.length > 0) {
|
|
449
|
+
lines.push('### Current Systems', '');
|
|
450
|
+
lines.push('| System | Category | Criticality |');
|
|
451
|
+
lines.push('|--------|----------|-------------|');
|
|
452
|
+
for (const sys of systems) {
|
|
453
|
+
const s = rec(sys);
|
|
454
|
+
lines.push(`| ${str(s.name)} | ${str(s.category)} | ${str(s.criticality) || str(s.businessCriticality)} |`);
|
|
455
|
+
}
|
|
456
|
+
lines.push('');
|
|
457
|
+
}
|
|
458
|
+
const cloudPlatforms = arrStr(dataInfra.cloudPlatforms);
|
|
459
|
+
if (cloudPlatforms || dataInfra.dataWarehouseExists !== undefined || str(dataInfra.cloudProvider)) {
|
|
460
|
+
lines.push('### Data Infrastructure', '');
|
|
461
|
+
if (cloudPlatforms)
|
|
462
|
+
lines.push(`- **Cloud platforms:** ${cloudPlatforms}`);
|
|
463
|
+
else if (str(dataInfra.cloudProvider))
|
|
464
|
+
lines.push(`- **Cloud provider:** ${str(dataInfra.cloudProvider)}`);
|
|
465
|
+
if (dataInfra.dataWarehouseExists !== undefined)
|
|
466
|
+
lines.push(`- **Data warehouse:** ${dataInfra.dataWarehouseExists ? 'Yes' : 'No'}`);
|
|
467
|
+
if (dataInfra.dataLakeExists !== undefined)
|
|
468
|
+
lines.push(`- **Data lake:** ${dataInfra.dataLakeExists ? 'Yes' : 'No'}`);
|
|
469
|
+
if (str(dataInfra.dataGovernanceMaturity))
|
|
470
|
+
lines.push(`- **Data governance maturity:** ${str(dataInfra.dataGovernanceMaturity)}`);
|
|
471
|
+
else if (str(dataInfra.dataQuality))
|
|
472
|
+
lines.push(`- **Data quality:** ${str(dataInfra.dataQuality)}`);
|
|
473
|
+
lines.push('');
|
|
474
|
+
}
|
|
475
|
+
const apiReadiness = str(integration.apiReadiness) || str(integration.apiMaturity);
|
|
476
|
+
const currentIntegrations = arrStr(integration.currentIntegrations);
|
|
477
|
+
if (apiReadiness || currentIntegrations || str(integration.integrationPatterns)) {
|
|
478
|
+
lines.push('### Integration Capabilities', '');
|
|
479
|
+
if (apiReadiness)
|
|
480
|
+
lines.push(`- **API readiness:** ${apiReadiness}`);
|
|
481
|
+
if (currentIntegrations)
|
|
482
|
+
lines.push(`- **Current integrations:** ${currentIntegrations}`);
|
|
483
|
+
else if (str(integration.integrationPatterns))
|
|
484
|
+
lines.push(`- **Integration patterns:** ${str(integration.integrationPatterns)}`);
|
|
485
|
+
if (str(integration.integrationPlatform) && !isPlaceholder(str(integration.integrationPlatform)))
|
|
486
|
+
lines.push(`- **Integration platform:** ${str(integration.integrationPlatform)}`);
|
|
487
|
+
else if (str(integration.middlewarePlatforms) && !isPlaceholder(str(integration.middlewarePlatforms)))
|
|
488
|
+
lines.push(`- **Middleware:** ${str(integration.middlewarePlatforms)}`);
|
|
489
|
+
lines.push('');
|
|
490
|
+
}
|
|
491
|
+
const complianceCerts = arrStr(security.complianceCertifications);
|
|
492
|
+
const privacyMeasures = arrStr(security.dataPrivacyMeasures);
|
|
493
|
+
if (complianceCerts || privacyMeasures || str(security.complianceFrameworks) || str(security.dataPrivacy)) {
|
|
494
|
+
lines.push('### Security & Compliance', '');
|
|
495
|
+
if (complianceCerts)
|
|
496
|
+
lines.push(`- **Compliance certifications:** ${complianceCerts}`);
|
|
497
|
+
else if (str(security.complianceFrameworks))
|
|
498
|
+
lines.push(`- **Compliance frameworks:** ${str(security.complianceFrameworks)}`);
|
|
499
|
+
if (privacyMeasures)
|
|
500
|
+
lines.push(`- **Data privacy measures:** ${privacyMeasures}`);
|
|
501
|
+
else if (str(security.dataPrivacy))
|
|
502
|
+
lines.push(`- **Data privacy:** ${str(security.dataPrivacy)}`);
|
|
503
|
+
lines.push('');
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
// Business operations
|
|
507
|
+
const ops = rec(bp.businessOperations);
|
|
508
|
+
const keyProcesses = arr(ops.keyProcesses);
|
|
509
|
+
const painPoints = arr(ops.painPoints);
|
|
510
|
+
const stakeholders = arr(ops.stakeholders);
|
|
511
|
+
if (keyProcesses.length > 0 || painPoints.length > 0) {
|
|
512
|
+
lines.push('## Business Operations', '');
|
|
513
|
+
if (keyProcesses.length > 0) {
|
|
514
|
+
lines.push('### Key Processes', '');
|
|
515
|
+
for (const proc of keyProcesses) {
|
|
516
|
+
const p = rec(proc);
|
|
517
|
+
const name = str(p.name) || str(p.processName);
|
|
518
|
+
const volume = str(p.volume) || str(p.transactionVolume);
|
|
519
|
+
if (name) {
|
|
520
|
+
lines.push(`- **${name}**${volume ? ` (${volume})` : ''}`);
|
|
521
|
+
if (str(p.frequency))
|
|
522
|
+
lines.push(` - Frequency: ${str(p.frequency)}`);
|
|
523
|
+
if (str(p.automationLevel))
|
|
524
|
+
lines.push(` - Automation level: ${str(p.automationLevel)}`);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
lines.push('');
|
|
528
|
+
}
|
|
529
|
+
if (painPoints.length > 0) {
|
|
530
|
+
lines.push('### Operational Pain Points', '');
|
|
531
|
+
for (const pp of painPoints) {
|
|
532
|
+
if (typeof pp === 'string') {
|
|
533
|
+
lines.push(`- ${pp}`);
|
|
534
|
+
}
|
|
535
|
+
else {
|
|
536
|
+
const p = rec(pp);
|
|
537
|
+
const desc = str(p.description) || str(p.painPoint);
|
|
538
|
+
if (desc)
|
|
539
|
+
lines.push(`- ${desc}${str(p.severity) ? ` _(${str(p.severity)})_` : ''}`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
lines.push('');
|
|
543
|
+
}
|
|
544
|
+
if (stakeholders.length > 0) {
|
|
545
|
+
lines.push('### Key Stakeholders', '');
|
|
546
|
+
for (const sh of stakeholders) {
|
|
547
|
+
const s = rec(sh);
|
|
548
|
+
const role = str(s.role) || str(s.title);
|
|
549
|
+
const name = str(s.name);
|
|
550
|
+
if (role || name)
|
|
551
|
+
lines.push(`- **${role || name}**${name && role ? ` — ${name}` : ''}`);
|
|
552
|
+
}
|
|
553
|
+
lines.push('');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
// Organizational capabilities
|
|
557
|
+
const caps = rec(bp.organizationalCapabilities);
|
|
558
|
+
const technicalTeam = rec(caps.technicalTeam);
|
|
559
|
+
const currentAutomation = rec(caps.currentAutomation);
|
|
560
|
+
const devCapacity = numStr(technicalTeam.developmentCapacity);
|
|
561
|
+
if (devCapacity || str(technicalTeam.size) || str(currentAutomation.level)) {
|
|
562
|
+
lines.push('## Organizational Capabilities', '');
|
|
563
|
+
if (devCapacity)
|
|
564
|
+
lines.push(`- **Development capacity:** ${devCapacity} FTEs`);
|
|
565
|
+
else if (str(technicalTeam.size))
|
|
566
|
+
lines.push(`- **Technical team size:** ${str(technicalTeam.size)}`);
|
|
567
|
+
if (str(technicalTeam.aiMlExperience))
|
|
568
|
+
lines.push(`- **AI/ML experience:** ${str(technicalTeam.aiMlExperience)}`);
|
|
569
|
+
else if (str(technicalTeam.aiExperience))
|
|
570
|
+
lines.push(`- **AI experience:** ${str(technicalTeam.aiExperience)}`);
|
|
571
|
+
if (str(currentAutomation.level))
|
|
572
|
+
lines.push(`- **Current automation level:** ${str(currentAutomation.level)}`);
|
|
573
|
+
const automatedProcesses = arrStr(currentAutomation.automatedProcesses);
|
|
574
|
+
if (automatedProcesses)
|
|
575
|
+
lines.push(`- **Automated processes:** ${automatedProcesses}`);
|
|
576
|
+
else if (str(currentAutomation.tools))
|
|
577
|
+
lines.push(`- **Automation tools:** ${str(currentAutomation.tools)}`);
|
|
578
|
+
lines.push('');
|
|
579
|
+
}
|
|
580
|
+
// Constraints
|
|
581
|
+
const constraints = rec(bp.constraintsProfile);
|
|
582
|
+
const budget = rec(constraints.budget);
|
|
583
|
+
const timeline = rec(constraints.timeline);
|
|
584
|
+
const technical = rec(constraints.technical);
|
|
585
|
+
const regulatory = rec(constraints.regulatory);
|
|
586
|
+
const totalBudget = str(budget.totalAiBudget) || str(budget.totalBudget);
|
|
587
|
+
const annualBudget = str(budget.annualOpexAvailable) || str(budget.annualBudget);
|
|
588
|
+
const deadlines = arrStr(timeline.criticalDeadlines);
|
|
589
|
+
const rolloutTimeline = str(timeline.fullRolloutTimeline) || str(timeline.preferredTimeline);
|
|
590
|
+
const legacyConstraints = arrStr(technical.legacySystemConstraints);
|
|
591
|
+
const regulations = arrStr(regulatory.industryRegulations);
|
|
592
|
+
if (totalBudget || deadlines || str(timeline.deadline) || regulations || str(regulatory.requirements)) {
|
|
593
|
+
lines.push('## Constraints', '');
|
|
594
|
+
if (totalBudget)
|
|
595
|
+
lines.push(`- **Budget:** ${totalBudget}`);
|
|
596
|
+
if (annualBudget)
|
|
597
|
+
lines.push(`- **Annual budget:** ${annualBudget}`);
|
|
598
|
+
if (deadlines)
|
|
599
|
+
lines.push(`- **Critical deadlines:** ${deadlines}`);
|
|
600
|
+
else if (str(timeline.deadline))
|
|
601
|
+
lines.push(`- **Deadline:** ${str(timeline.deadline)}`);
|
|
602
|
+
if (rolloutTimeline)
|
|
603
|
+
lines.push(`- **Rollout timeline:** ${rolloutTimeline}`);
|
|
604
|
+
if (legacyConstraints)
|
|
605
|
+
lines.push(`- **Legacy system constraints:** ${legacyConstraints}`);
|
|
606
|
+
else if (str(technical.limitations))
|
|
607
|
+
lines.push(`- **Technical limitations:** ${str(technical.limitations)}`);
|
|
608
|
+
if (regulations)
|
|
609
|
+
lines.push(`- **Industry regulations:** ${regulations}`);
|
|
610
|
+
else if (str(regulatory.requirements))
|
|
611
|
+
lines.push(`- **Regulatory:** ${str(regulatory.requirements)}`);
|
|
612
|
+
lines.push('');
|
|
613
|
+
}
|
|
614
|
+
// Strategic initiatives
|
|
615
|
+
const initiatives = arr(bp.strategicInitiatives);
|
|
616
|
+
if (initiatives.length > 0) {
|
|
617
|
+
lines.push('## Strategic Initiatives', '');
|
|
618
|
+
for (const init of initiatives) {
|
|
619
|
+
const i = rec(init);
|
|
620
|
+
const title = str(i.title);
|
|
621
|
+
if (title) {
|
|
622
|
+
lines.push(`### ${title}`, '');
|
|
623
|
+
if (str(i.description))
|
|
624
|
+
lines.push(str(i.description), '');
|
|
625
|
+
if (str(i.priority))
|
|
626
|
+
lines.push(`- **Priority:** ${str(i.priority)}`);
|
|
627
|
+
if (str(i.status))
|
|
628
|
+
lines.push(`- **Status:** ${str(i.status)}`);
|
|
629
|
+
if (str(i.budget))
|
|
630
|
+
lines.push(`- **Budget:** ${str(i.budget)}`);
|
|
631
|
+
if (str(i.timeline))
|
|
632
|
+
lines.push(`- **Timeline:** ${str(i.timeline)}`);
|
|
633
|
+
const outcomes = arr(i.expectedOutcomes);
|
|
634
|
+
if (outcomes.length > 0) {
|
|
635
|
+
lines.push('- **Expected outcomes:**');
|
|
636
|
+
for (const o of outcomes)
|
|
637
|
+
lines.push(` - ${o}`);
|
|
638
|
+
}
|
|
639
|
+
lines.push('');
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
// AI readiness
|
|
644
|
+
if (bp.aiReadinessScore !== null && bp.aiReadinessScore !== undefined) {
|
|
645
|
+
lines.push('## AI Readiness', '');
|
|
646
|
+
lines.push(`- **Score:** ${bp.aiReadinessScore}/100`);
|
|
647
|
+
lines.push('');
|
|
648
|
+
}
|
|
649
|
+
return lines.join('\n');
|
|
650
|
+
}
|
|
347
651
|
function buildAgentSpecifications(input) {
|
|
348
652
|
const bp = input.blueprintData;
|
|
349
653
|
const team = getTeam(bp);
|
|
@@ -351,7 +655,7 @@ function buildAgentSpecifications(input) {
|
|
|
351
655
|
for (const agent of team) {
|
|
352
656
|
const name = str(agent.name);
|
|
353
657
|
lines.push(`## ${name}`, '');
|
|
354
|
-
const role = str(agent.role);
|
|
658
|
+
const role = str(agent.role) || str(rec(agent.instructions).role);
|
|
355
659
|
const type = str(agent.agentRole) || str(agent.orchestrationRole) || str(agent.type) || 'Worker';
|
|
356
660
|
const supervision = str(agent.supervisionLevel) || 'Supervised';
|
|
357
661
|
lines.push(`- **Role:** ${role}`);
|
|
@@ -388,7 +692,7 @@ function buildAgentSpecifications(input) {
|
|
|
388
692
|
const t = rec(tool);
|
|
389
693
|
const tName = str(t.name);
|
|
390
694
|
const tCat = str(t.toolCategory) || str(t.type) || '';
|
|
391
|
-
const tDesc = str(t.description).replace(/\|/g, '\\|')
|
|
695
|
+
const tDesc = str(t.description).replace(/\|/g, '\\|');
|
|
392
696
|
lines.push(`| ${tName} | ${tCat} | ${tDesc} |`);
|
|
393
697
|
}
|
|
394
698
|
lines.push('');
|
|
@@ -410,10 +714,12 @@ function buildAgentSpecifications(input) {
|
|
|
410
714
|
lines.push('');
|
|
411
715
|
}
|
|
412
716
|
const risk = rec(agent.riskAssessment);
|
|
413
|
-
if (str(risk.level)) {
|
|
717
|
+
if (str(risk.level) && !isPlaceholder(str(risk.level))) {
|
|
414
718
|
lines.push('### Risk Assessment', '');
|
|
415
719
|
lines.push(`- **Level:** ${str(risk.level)}`);
|
|
416
|
-
|
|
720
|
+
const riskImpact = str(risk.impact);
|
|
721
|
+
if (riskImpact && !isPlaceholder(riskImpact))
|
|
722
|
+
lines.push(`- **Impact:** ${riskImpact}`);
|
|
417
723
|
const controls = arr(risk.controls);
|
|
418
724
|
if (controls.length > 0) {
|
|
419
725
|
lines.push('- **Controls:**');
|
|
@@ -476,64 +782,90 @@ function buildFinancialCase(input) {
|
|
|
476
782
|
}
|
|
477
783
|
const benefits = rec(bc.benefits);
|
|
478
784
|
const qROI = rec(benefits.quantifiedROI);
|
|
479
|
-
|
|
785
|
+
const roiVal = str(qROI.roi);
|
|
786
|
+
const npvVal = str(qROI.npv);
|
|
787
|
+
const paybackVal = str(qROI.paybackPeriod);
|
|
788
|
+
if ((roiVal && !isPlaceholder(roiVal)) || (npvVal && !isPlaceholder(npvVal)) || (paybackVal && !isPlaceholder(paybackVal))) {
|
|
480
789
|
lines.push('## Return on Investment', '');
|
|
481
|
-
if (
|
|
482
|
-
lines.push(`- **ROI:** ${
|
|
483
|
-
if (
|
|
484
|
-
lines.push(`- **NPV:** ${
|
|
485
|
-
if (
|
|
486
|
-
lines.push(`- **Payback period:** ${
|
|
790
|
+
if (roiVal && !isPlaceholder(roiVal))
|
|
791
|
+
lines.push(`- **ROI:** ${roiVal}`);
|
|
792
|
+
if (npvVal && !isPlaceholder(npvVal))
|
|
793
|
+
lines.push(`- **NPV:** ${npvVal}`);
|
|
794
|
+
if (paybackVal && !isPlaceholder(paybackVal))
|
|
795
|
+
lines.push(`- **Payback period:** ${paybackVal}`);
|
|
487
796
|
lines.push('');
|
|
488
797
|
}
|
|
798
|
+
// Labor cost detail (nested object: currentStateBaseline / projectedSavings)
|
|
489
799
|
const laborDetail = rec(qROI.laborCostDetail);
|
|
490
|
-
|
|
800
|
+
const currentBaseline = rec(laborDetail.currentStateBaseline);
|
|
801
|
+
const projectedSavings = rec(laborDetail.projectedSavings);
|
|
802
|
+
const blendedRate = str(rec(currentBaseline.blendedHourlyRate).value);
|
|
803
|
+
const totalAnnualCost = str(rec(currentBaseline.totalAnnualCost).value);
|
|
804
|
+
const totalAnnualHours = str(rec(currentBaseline.totalAnnualHours).value);
|
|
805
|
+
const costSavingsAnnual = str(rec(projectedSavings.costSavingsAnnual).value);
|
|
806
|
+
if (totalAnnualCost || blendedRate) {
|
|
491
807
|
lines.push('## Labor Cost Analysis', '');
|
|
492
|
-
if (
|
|
493
|
-
lines.push(`- **Avg. fully-loaded rate:** ${
|
|
494
|
-
if (
|
|
495
|
-
lines.push(`- **Annual labor cost:** ${
|
|
496
|
-
if (
|
|
497
|
-
lines.push(`- **Annual hours affected:** ${
|
|
498
|
-
if (
|
|
499
|
-
lines.push(`- **Automation savings:** ${
|
|
808
|
+
if (blendedRate)
|
|
809
|
+
lines.push(`- **Avg. fully-loaded rate:** ${blendedRate}`);
|
|
810
|
+
if (totalAnnualCost)
|
|
811
|
+
lines.push(`- **Annual labor cost:** ${totalAnnualCost}`);
|
|
812
|
+
if (totalAnnualHours)
|
|
813
|
+
lines.push(`- **Annual hours affected:** ${totalAnnualHours}`);
|
|
814
|
+
if (costSavingsAnnual)
|
|
815
|
+
lines.push(`- **Automation savings:** ${costSavingsAnnual}`);
|
|
500
816
|
lines.push('');
|
|
501
817
|
}
|
|
818
|
+
// Cost breakdown (each field is { value, notes?, source? })
|
|
502
819
|
const costBreakdown = rec(qROI.costBreakdown);
|
|
503
|
-
|
|
820
|
+
const cbImpl = str(rec(costBreakdown.implementation).value);
|
|
821
|
+
const cbLic = str(rec(costBreakdown.annualLicensing).value);
|
|
822
|
+
const cbSupport = str(rec(costBreakdown.annualSupportMaintenance).value);
|
|
823
|
+
if (cbImpl || cbLic) {
|
|
504
824
|
lines.push('## Cost Breakdown', '');
|
|
505
|
-
if (
|
|
506
|
-
lines.push(`- **Implementation:** ${
|
|
507
|
-
if (
|
|
508
|
-
lines.push(`- **Annual licensing:** ${
|
|
509
|
-
if (
|
|
510
|
-
lines.push(`- **Annual support/maintenance:** ${
|
|
825
|
+
if (cbImpl)
|
|
826
|
+
lines.push(`- **Implementation:** ${cbImpl}`);
|
|
827
|
+
if (cbLic)
|
|
828
|
+
lines.push(`- **Annual licensing:** ${cbLic}`);
|
|
829
|
+
if (cbSupport)
|
|
830
|
+
lines.push(`- **Annual support/maintenance:** ${cbSupport}`);
|
|
511
831
|
lines.push('');
|
|
512
832
|
}
|
|
833
|
+
// Pilot ROI (nested: pilotCapex/pilotOpex/pilotAnnualSavings/pilotYear1Net are { value, calculation })
|
|
513
834
|
const pilotROI = rec(qROI.pilotROI);
|
|
514
|
-
|
|
835
|
+
const pilotCapex = str(rec(pilotROI.pilotCapex).value);
|
|
836
|
+
const pilotOpex = str(rec(pilotROI.pilotOpex).value);
|
|
837
|
+
const pilotSavings = str(rec(pilotROI.pilotAnnualSavings).value);
|
|
838
|
+
const pilotYear1Net = str(rec(pilotROI.pilotYear1Net).value);
|
|
839
|
+
const pilotPayback = numStr(pilotROI.pilotPaybackMonths);
|
|
840
|
+
if (pilotCapex || pilotSavings) {
|
|
515
841
|
lines.push('## Pilot Economics', '');
|
|
516
|
-
if (
|
|
517
|
-
lines.push(`- **Pilot
|
|
518
|
-
if (
|
|
519
|
-
lines.push(`- **Pilot
|
|
520
|
-
if (
|
|
521
|
-
lines.push(`- **Pilot
|
|
522
|
-
if (
|
|
523
|
-
lines.push(`- **
|
|
842
|
+
if (pilotCapex)
|
|
843
|
+
lines.push(`- **Pilot capex:** ${pilotCapex}`);
|
|
844
|
+
if (pilotOpex)
|
|
845
|
+
lines.push(`- **Pilot opex:** ${pilotOpex}`);
|
|
846
|
+
if (pilotSavings)
|
|
847
|
+
lines.push(`- **Pilot annual savings:** ${pilotSavings}`);
|
|
848
|
+
if (pilotYear1Net)
|
|
849
|
+
lines.push(`- **Pilot Year 1 net:** ${pilotYear1Net}`);
|
|
850
|
+
if (pilotPayback)
|
|
851
|
+
lines.push(`- **Payback:** ${stripTrailingUnit(pilotPayback, 'months')} months`);
|
|
524
852
|
lines.push('');
|
|
525
853
|
}
|
|
854
|
+
// Sensitivity analysis (roiPercentage, paybackMonths, annualSavings — all numbers/strings)
|
|
526
855
|
const sensitivity = rec(qROI.sensitivity);
|
|
527
856
|
if (sensitivity.conservative || sensitivity.realistic || sensitivity.optimistic) {
|
|
528
857
|
lines.push('## Sensitivity Analysis', '');
|
|
529
|
-
lines.push('| Scenario |
|
|
530
|
-
lines.push('
|
|
858
|
+
lines.push('| Scenario | ROI | Payback | Annual Savings |');
|
|
859
|
+
lines.push('|----------|-----|---------|----------------|');
|
|
531
860
|
for (const [label, key] of [['Conservative', 'conservative'], ['Realistic', 'realistic'], ['Optimistic', 'optimistic']]) {
|
|
532
861
|
const s = rec(sensitivity[key]);
|
|
533
|
-
|
|
862
|
+
const roi = numStr(s.roiPercentage);
|
|
863
|
+
const payback = numStr(s.paybackMonths);
|
|
864
|
+
lines.push(`| ${label} | ${roi ? stripTrailingUnit(roi, '%') + '%' : ''} | ${payback ? stripTrailingUnit(payback, 'months') + ' months' : ''} | ${str(s.annualSavings)} |`);
|
|
534
865
|
}
|
|
535
866
|
lines.push('');
|
|
536
867
|
}
|
|
868
|
+
// 5-year projection (calculator uses costsThisYear/valueDelivered/netThisYear/runningTotal)
|
|
537
869
|
const fiveYear = arr(qROI.fiveYearProjection);
|
|
538
870
|
if (fiveYear.length > 0) {
|
|
539
871
|
lines.push('## Five-Year Projection', '');
|
|
@@ -541,7 +873,7 @@ function buildFinancialCase(input) {
|
|
|
541
873
|
lines.push('|------|-----------|-------|---------------|------------|');
|
|
542
874
|
for (const yr of fiveYear) {
|
|
543
875
|
const y = rec(yr);
|
|
544
|
-
lines.push(`| ${
|
|
876
|
+
lines.push(`| ${numStr(y.year)} | ${str(y.costsThisYear) || str(y.investment)} | ${str(y.valueDelivered) || str(y.value)} | ${str(y.netThisYear) || str(y.netCashFlow)} | ${str(y.runningTotal) || str(y.cumulative)} |`);
|
|
545
877
|
}
|
|
546
878
|
lines.push('');
|
|
547
879
|
}
|
|
@@ -558,6 +890,26 @@ function buildFinancialCase(input) {
|
|
|
558
890
|
lines.push(`- **Time to market:** ${str(tangible.timeToMarket)}`);
|
|
559
891
|
lines.push('');
|
|
560
892
|
}
|
|
893
|
+
// Recommendation
|
|
894
|
+
const recommendation = rec(bc.recommendation);
|
|
895
|
+
if (str(recommendation.summary) || str(recommendation.decisionRequest)) {
|
|
896
|
+
lines.push('## Recommendation', '');
|
|
897
|
+
if (str(recommendation.summary))
|
|
898
|
+
lines.push(str(recommendation.summary), '');
|
|
899
|
+
if (str(recommendation.decisionRequest)) {
|
|
900
|
+
lines.push(`**Decision request:** ${str(recommendation.decisionRequest)}`, '');
|
|
901
|
+
}
|
|
902
|
+
const immediateActions = arr(recommendation.immediateActions);
|
|
903
|
+
if (immediateActions.length > 0) {
|
|
904
|
+
lines.push('**Immediate actions upon approval:**', '');
|
|
905
|
+
for (const action of immediateActions)
|
|
906
|
+
lines.push(`1. ${action}`);
|
|
907
|
+
lines.push('');
|
|
908
|
+
}
|
|
909
|
+
if (str(recommendation.blueprintImplementationRef)) {
|
|
910
|
+
lines.push(`> ${str(recommendation.blueprintImplementationRef)}`, '');
|
|
911
|
+
}
|
|
912
|
+
}
|
|
561
913
|
return lines.join('\n');
|
|
562
914
|
}
|
|
563
915
|
function buildImplementationRoadmap(input) {
|
|
@@ -783,12 +1135,14 @@ function buildArchitectureDecisions(input) {
|
|
|
783
1135
|
}
|
|
784
1136
|
}
|
|
785
1137
|
const feasibility = rec(bp.feasibilityIndicators);
|
|
786
|
-
|
|
1138
|
+
const feasConfidence = str(feasibility.feasibilityConfidence) || str(feasibility.overallScore);
|
|
1139
|
+
const feasBasis = str(feasibility.feasibilityBasis) || str(feasibility.recommendation);
|
|
1140
|
+
if (feasConfidence || feasBasis) {
|
|
787
1141
|
lines.push('## Feasibility Assessment', '');
|
|
788
|
-
if (
|
|
789
|
-
lines.push(`**
|
|
790
|
-
if (
|
|
791
|
-
lines.push(`**
|
|
1142
|
+
if (feasConfidence)
|
|
1143
|
+
lines.push(`**Confidence:** ${feasConfidence}`);
|
|
1144
|
+
if (feasBasis)
|
|
1145
|
+
lines.push(`**Basis:** ${feasBasis}`);
|
|
792
1146
|
lines.push('');
|
|
793
1147
|
}
|
|
794
1148
|
return lines.join('\n');
|
|
@@ -849,8 +1203,12 @@ function buildGuardrailsAndGovernance(input) {
|
|
|
849
1203
|
lines.push('');
|
|
850
1204
|
}
|
|
851
1205
|
const risk = rec(agent.riskAssessment);
|
|
852
|
-
if (str(risk.level)) {
|
|
853
|
-
|
|
1206
|
+
if (str(risk.level) && !isPlaceholder(str(risk.level))) {
|
|
1207
|
+
const impactStr = str(risk.impact);
|
|
1208
|
+
const riskLine = impactStr && !isPlaceholder(impactStr)
|
|
1209
|
+
? `**Risk:** ${str(risk.level)} — ${impactStr}`
|
|
1210
|
+
: `**Risk:** ${str(risk.level)}`;
|
|
1211
|
+
lines.push(riskLine);
|
|
854
1212
|
lines.push('');
|
|
855
1213
|
}
|
|
856
1214
|
}
|
|
@@ -944,6 +1302,7 @@ fi
|
|
|
944
1302
|
echo ""
|
|
945
1303
|
echo "--- Optional Files ---"
|
|
946
1304
|
check_optional "references/business-context.md"
|
|
1305
|
+
check_optional "references/organization-context.md"
|
|
947
1306
|
check_optional "references/financial-case.md"
|
|
948
1307
|
check_optional "references/implementation-roadmap.md"
|
|
949
1308
|
check_optional "references/guardrails-and-governance.md"
|
|
@@ -977,6 +1336,7 @@ export function renderSkillDirectory(input) {
|
|
|
977
1336
|
files.set('SKILL.md', `${frontmatter}\n\n${body}`);
|
|
978
1337
|
// Reference files
|
|
979
1338
|
files.set('references/business-context.md', buildBusinessContext(input));
|
|
1339
|
+
files.set('references/organization-context.md', buildOrganizationContext(input));
|
|
980
1340
|
files.set('references/agent-specifications.md', buildAgentSpecifications(input));
|
|
981
1341
|
files.set('references/financial-case.md', buildFinancialCase(input));
|
|
982
1342
|
files.set('references/implementation-roadmap.md', buildImplementationRoadmap(input));
|