@llm-dev-ops/agentics-cli 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/erp.d.ts +8 -1
- package/dist/commands/erp.d.ts.map +1 -1
- package/dist/commands/erp.js +150 -37
- package/dist/commands/erp.js.map +1 -1
- package/dist/pipeline/auto-chain.d.ts.map +1 -1
- package/dist/pipeline/auto-chain.js +223 -9
- package/dist/pipeline/auto-chain.js.map +1 -1
- package/dist/pipeline/phase2/phases/adr-generator.d.ts.map +1 -1
- package/dist/pipeline/phase2/phases/adr-generator.js +214 -9
- package/dist/pipeline/phase2/phases/adr-generator.js.map +1 -1
- package/dist/pipeline/phase2/phases/ddd-generator.d.ts.map +1 -1
- package/dist/pipeline/phase2/phases/ddd-generator.js +117 -1
- package/dist/pipeline/phase2/phases/ddd-generator.js.map +1 -1
- package/dist/pipeline/phase2/phases/prompt-generator.js +76 -4
- package/dist/pipeline/phase2/phases/prompt-generator.js.map +1 -1
- package/dist/pipeline/phase2/phases/research-dossier.d.ts.map +1 -1
- package/dist/pipeline/phase2/phases/research-dossier.js +58 -10
- package/dist/pipeline/phase2/phases/research-dossier.js.map +1 -1
- package/dist/synthesis/ask-artifact-writer.d.ts.map +1 -1
- package/dist/synthesis/ask-artifact-writer.js +37 -2
- package/dist/synthesis/ask-artifact-writer.js.map +1 -1
- package/dist/synthesis/simulation-renderers.d.ts.map +1 -1
- package/dist/synthesis/simulation-renderers.js +494 -50
- package/dist/synthesis/simulation-renderers.js.map +1 -1
- package/package.json +1 -1
|
@@ -234,13 +234,15 @@ export async function executeAutoChain(traceId, options = {}) {
|
|
|
234
234
|
let scenarioBranch;
|
|
235
235
|
let originalBranch;
|
|
236
236
|
let scenarioQuery = '';
|
|
237
|
-
// Read scenario query from Phase 1 manifest
|
|
237
|
+
// Read scenario query and simulation ID from Phase 1 manifest
|
|
238
|
+
let simulationId = '';
|
|
238
239
|
try {
|
|
239
240
|
const manifestPath = path.join(runDir, 'manifest.json');
|
|
240
241
|
if (fs.existsSync(manifestPath)) {
|
|
241
242
|
const raw = fs.readFileSync(manifestPath, 'utf-8');
|
|
242
243
|
const manifest = JSON.parse(raw);
|
|
243
244
|
scenarioQuery = manifest.query ?? '';
|
|
245
|
+
simulationId = manifest.simulation_id ?? manifest.execution_id ?? '';
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
catch {
|
|
@@ -869,23 +871,34 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
869
871
|
derivedPhases.push({ title: heading, slug, content: section, folder, adrIds: matchedAdrIds });
|
|
870
872
|
}
|
|
871
873
|
}
|
|
872
|
-
//
|
|
873
|
-
|
|
874
|
-
|
|
874
|
+
// ADR-PIPELINE-031: Enrich with ADR-derived phases when SPARC sections alone are insufficient.
|
|
875
|
+
// Each ADR that isn't already covered by a SPARC-derived phase becomes its own build step.
|
|
876
|
+
if (derivedPhases.length < 8 && adrs.length > 0) {
|
|
877
|
+
const existingSlugs = new Set(derivedPhases.map(p => p.slug));
|
|
878
|
+
const existingTitleWords = new Set(derivedPhases.flatMap(p => p.title.toLowerCase().split(/\W+/).filter(w => w.length > 3)));
|
|
875
879
|
for (const adr of adrs) {
|
|
876
880
|
const slug = adr.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 50);
|
|
881
|
+
// Skip if a phase with similar slug or overlapping title already exists
|
|
882
|
+
if (existingSlugs.has(slug))
|
|
883
|
+
continue;
|
|
884
|
+
const adrKeywords = adr.title.toLowerCase().split(/\W+/).filter(w => w.length > 3);
|
|
885
|
+
const overlap = adrKeywords.filter(w => existingTitleWords.has(w)).length;
|
|
886
|
+
if (overlap >= 2)
|
|
887
|
+
continue; // sufficiently covered by an existing phase
|
|
877
888
|
const adrLower = `${adr.title} ${adr.context} ${adr.decision}`.toLowerCase();
|
|
878
889
|
let folder = 'backend';
|
|
879
890
|
if (/frontend|ui|dashboard/.test(adrLower))
|
|
880
891
|
folder = 'frontend';
|
|
881
|
-
else if (/erp|netsuite|sap|dynamics/.test(adrLower))
|
|
892
|
+
else if (/erp|netsuite|sap|dynamics|coupa|workday|maximo|oracle/.test(adrLower))
|
|
882
893
|
folder = 'erp';
|
|
883
|
-
else if (/integration|connector/.test(adrLower))
|
|
894
|
+
else if (/integration|connector|webhook/.test(adrLower))
|
|
884
895
|
folder = 'integrations';
|
|
885
896
|
else if (/deploy|infra|docker/.test(adrLower))
|
|
886
897
|
folder = 'src';
|
|
887
898
|
else if (/test|quality/.test(adrLower))
|
|
888
899
|
folder = 'tests';
|
|
900
|
+
else if (/audit|governance|approval/.test(adrLower))
|
|
901
|
+
folder = 'backend';
|
|
889
902
|
derivedPhases.push({
|
|
890
903
|
title: adr.title,
|
|
891
904
|
slug,
|
|
@@ -893,6 +906,9 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
893
906
|
folder,
|
|
894
907
|
adrIds: [adr.id],
|
|
895
908
|
});
|
|
909
|
+
existingSlugs.add(slug);
|
|
910
|
+
for (const w of adrKeywords)
|
|
911
|
+
existingTitleWords.add(w);
|
|
896
912
|
}
|
|
897
913
|
}
|
|
898
914
|
// Always add foundation (first) and testing/deployment (last) if not present
|
|
@@ -934,6 +950,186 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
934
950
|
adrIds: [],
|
|
935
951
|
});
|
|
936
952
|
}
|
|
953
|
+
// ADR-PIPELINE-031: Guarantee ≥10 prompts by adding standard cross-cutting phases
|
|
954
|
+
// when domain-specific + ADR-derived phases don't reach the minimum.
|
|
955
|
+
const crossCutting = [
|
|
956
|
+
{ title: 'Observability & Structured Logging', slug: 'observability', folder: 'backend',
|
|
957
|
+
content: `ADR-PIPELINE-034: Implement complete observability infrastructure.
|
|
958
|
+
|
|
959
|
+
## 1. Structured Logger (src/logger.ts)
|
|
960
|
+
|
|
961
|
+
Create a logger factory that outputs JSON to stderr:
|
|
962
|
+
|
|
963
|
+
\`\`\`typescript
|
|
964
|
+
export interface Logger {
|
|
965
|
+
info(event: string, data?: Record<string, unknown>): void;
|
|
966
|
+
warn(event: string, data?: Record<string, unknown>): void;
|
|
967
|
+
error(event: string, error: Error, data?: Record<string, unknown>): void;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export function createLogger(service: string): Logger {
|
|
971
|
+
// Each log entry: { timestamp, level, service, event, correlationId?, ...data }
|
|
972
|
+
// Output to stderr as single-line JSON
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
// Correlation ID context — thread through entire request lifecycle
|
|
976
|
+
export function withCorrelationId<T>(correlationId: string, fn: () => T): T;
|
|
977
|
+
export function getCorrelationId(): string | undefined;
|
|
978
|
+
\`\`\`
|
|
979
|
+
|
|
980
|
+
## 2. Correlation ID Threading
|
|
981
|
+
|
|
982
|
+
Every analysis run generates a correlationId (UUID). This ID flows through:
|
|
983
|
+
- analysis.started → analysis.excess_detected → analysis.completed
|
|
984
|
+
- decision.created → erp.sync.attempted → erp.sync.succeeded/failed
|
|
985
|
+
|
|
986
|
+
Pass correlationId as a parameter through service functions or use AsyncLocalStorage.
|
|
987
|
+
|
|
988
|
+
## 3. Instrumentation Points (minimum)
|
|
989
|
+
|
|
990
|
+
| Event | When | Data |
|
|
991
|
+
|-------|------|------|
|
|
992
|
+
| analysis.started | Analysis begins | { correlationId, supplierCount, recordCount } |
|
|
993
|
+
| analysis.completed | Analysis finishes | { correlationId, durationMs, flagCount, opportunityCount } |
|
|
994
|
+
| decision.created | Decision recorded | { correlationId, decisionId, opportunityId, status } |
|
|
995
|
+
| erp.sync.attempted | ERP write starts | { correlationId, transactionId, supplierId, action } |
|
|
996
|
+
| erp.sync.succeeded | ERP write succeeds | { correlationId, transactionId, responseTime } |
|
|
997
|
+
| erp.sync.failed | ERP write fails | { correlationId, transactionId, error, retryCount } |
|
|
998
|
+
|
|
999
|
+
## 4. ERP Error Handling
|
|
1000
|
+
|
|
1001
|
+
The ERP connector must handle:
|
|
1002
|
+
- Network timeout: configurable (default 30s), log erp.sync.failed with timeout error
|
|
1003
|
+
- Rate limiting (429): exponential backoff (1s, 2s, 4s, max 3 retries), log each retry
|
|
1004
|
+
- Schema validation: log and quarantine invalid records, don't crash the pipeline
|
|
1005
|
+
- Idempotency: generate idempotency key per transaction to prevent duplicate writes on retry
|
|
1006
|
+
|
|
1007
|
+
## 5. Health Check
|
|
1008
|
+
|
|
1009
|
+
If the project includes an API layer, add GET /health returning:
|
|
1010
|
+
\`\`\`json
|
|
1011
|
+
{ "status": "ok", "service": "packaging-waste-optimizer", "version": "0.1.0", "uptime": 12345, "lastAnalysisRun": "2026-04-09T..." }
|
|
1012
|
+
\`\`\`
|
|
1013
|
+
|
|
1014
|
+
## 6. Tests
|
|
1015
|
+
|
|
1016
|
+
- Test that logger outputs valid JSON to stderr
|
|
1017
|
+
- Test that correlationId flows through analysis → decision → ERP sync
|
|
1018
|
+
- Test that ERP error handling retries on 429 and logs failures` },
|
|
1019
|
+
{ title: 'Configuration & Environment Management', slug: 'configuration', folder: 'src',
|
|
1020
|
+
content: `ADR-PIPELINE-034: Configuration module for environment-based settings.
|
|
1021
|
+
|
|
1022
|
+
Create src/config.ts with a typed configuration object:
|
|
1023
|
+
|
|
1024
|
+
\`\`\`typescript
|
|
1025
|
+
export interface AppConfig {
|
|
1026
|
+
env: 'development' | 'staging' | 'production';
|
|
1027
|
+
logLevel: 'debug' | 'info' | 'warn' | 'error';
|
|
1028
|
+
erp: {
|
|
1029
|
+
baseUrl: string;
|
|
1030
|
+
apiVersion: string;
|
|
1031
|
+
clientId: string;
|
|
1032
|
+
timeoutMs: number; // default 30000
|
|
1033
|
+
maxRetries: number; // default 3
|
|
1034
|
+
};
|
|
1035
|
+
analysis: {
|
|
1036
|
+
// Domain-specific thresholds — externalized, not hardcoded
|
|
1037
|
+
[key: string]: number | string | boolean;
|
|
1038
|
+
};
|
|
1039
|
+
}
|
|
1040
|
+
\`\`\`
|
|
1041
|
+
|
|
1042
|
+
Requirements:
|
|
1043
|
+
- Read all values from environment variables (never hardcode secrets)
|
|
1044
|
+
- Validate at startup — fail fast with clear error messages for missing required vars
|
|
1045
|
+
- Provide sensible defaults for optional values (timeoutMs, maxRetries, logLevel)
|
|
1046
|
+
- Export a singleton config object used by all services
|
|
1047
|
+
- Include tests that verify validation catches missing required vars` },
|
|
1048
|
+
{ title: 'API Layer & Request Handling', slug: 'api-layer', folder: 'backend',
|
|
1049
|
+
content: 'Build REST API endpoints exposing core domain operations. Input validation at API boundary (Zod or equivalent). Authentication and authorization middleware. Structured error responses with correlation IDs. Rate limiting.' },
|
|
1050
|
+
{ title: 'Persistence & Data Access Layer', slug: 'persistence', folder: 'backend',
|
|
1051
|
+
content: 'Implement repository interfaces per aggregate (ports pattern). Database adapter implementations. Audit trail persistence (append-only, tamper-evident). Transaction management for multi-aggregate operations.' },
|
|
1052
|
+
{ title: 'Demo Script & CLI Entry Point', slug: 'demo', folder: 'src',
|
|
1053
|
+
content: `ADR-PIPELINE-037: User-facing entry points for the prototype.
|
|
1054
|
+
|
|
1055
|
+
## 1. Demo Script (src/demo.ts) — REQUIRED
|
|
1056
|
+
|
|
1057
|
+
Create a runnable demo (\`npx tsx src/demo.ts\`) that:
|
|
1058
|
+
1. Loads all seed data
|
|
1059
|
+
2. Runs the complete analysis pipeline end-to-end
|
|
1060
|
+
3. Prints formatted results to stdout using tables (not raw JSON):
|
|
1061
|
+
- Summary table: key metrics, top findings
|
|
1062
|
+
- Per-entity breakdown (e.g., per-supplier, per-zone, per-employee)
|
|
1063
|
+
- Scenario comparison table with tradeoff columns
|
|
1064
|
+
4. Demonstrates the decision/approval workflow:
|
|
1065
|
+
- Create a draft decision for the top opportunity
|
|
1066
|
+
- Approve it with a test approver
|
|
1067
|
+
5. Shows the ERP sync payload:
|
|
1068
|
+
- Print the structured payload that would be sent to the ERP
|
|
1069
|
+
- Mark as "dry run" — do not actually sync
|
|
1070
|
+
|
|
1071
|
+
The demo must run without any external dependencies (no database, no API keys, no network).
|
|
1072
|
+
|
|
1073
|
+
## 2. CLI Interface (src/cli.ts) — OPTIONAL
|
|
1074
|
+
|
|
1075
|
+
If time permits, create a minimal CLI:
|
|
1076
|
+
\`\`\`
|
|
1077
|
+
npx tsx src/cli.ts --analyze # Run analysis, print results
|
|
1078
|
+
npx tsx src/cli.ts --scenarios # Show scenario comparison
|
|
1079
|
+
npx tsx src/cli.ts --decide <id> # Create decision for opportunity
|
|
1080
|
+
npx tsx src/cli.ts --sync <id> # Dry-run ERP sync for decision
|
|
1081
|
+
npx tsx src/cli.ts --help # Usage examples
|
|
1082
|
+
\`\`\`
|
|
1083
|
+
|
|
1084
|
+
## 3. Architecture Divergence ADR — REQUIRED
|
|
1085
|
+
|
|
1086
|
+
Create \`docs/ADR-001-monolithic-prototype.md\` in the generated project:
|
|
1087
|
+
|
|
1088
|
+
\`\`\`markdown
|
|
1089
|
+
# ADR-001: Monolithic Library for Prototype Phase
|
|
1090
|
+
|
|
1091
|
+
## Status
|
|
1092
|
+
Accepted
|
|
1093
|
+
|
|
1094
|
+
## Context
|
|
1095
|
+
The SPARC architecture specification describes multiple microservices with event-driven
|
|
1096
|
+
communication. For the prototype evaluation period (3-7 days), deploying and operating
|
|
1097
|
+
microservices adds unnecessary complexity without delivering proportional value.
|
|
1098
|
+
|
|
1099
|
+
## Decision
|
|
1100
|
+
Build as a single TypeScript library with clean module boundaries:
|
|
1101
|
+
- analysis/ — Pure computation, no side effects
|
|
1102
|
+
- decisions/ — State management with audit trail
|
|
1103
|
+
- erp/ — External system integration (adapter pattern)
|
|
1104
|
+
- data/ — Seed data and data access
|
|
1105
|
+
|
|
1106
|
+
Each module exports a barrel (index.ts) and communicates via typed interfaces,
|
|
1107
|
+
not shared mutable state. This structure enables decomposition into independent
|
|
1108
|
+
services when the pilot validates the approach.
|
|
1109
|
+
|
|
1110
|
+
## Consequences
|
|
1111
|
+
- Prototype can be built, tested, and demonstrated in days, not weeks
|
|
1112
|
+
- Module boundaries enforce separation of concerns without deployment overhead
|
|
1113
|
+
- Migration to microservices requires extracting modules into packages — not rewriting
|
|
1114
|
+
\`\`\`
|
|
1115
|
+
|
|
1116
|
+
## Tests
|
|
1117
|
+
- Test that demo.ts runs without errors (import and execute main function)
|
|
1118
|
+
- Test that it produces non-empty stdout output` },
|
|
1119
|
+
];
|
|
1120
|
+
const existingSlugSet = new Set(derivedPhases.map(p => p.slug));
|
|
1121
|
+
for (const cc of crossCutting) {
|
|
1122
|
+
if (derivedPhases.length >= 12)
|
|
1123
|
+
break;
|
|
1124
|
+
if (existingSlugSet.has(cc.slug))
|
|
1125
|
+
continue;
|
|
1126
|
+
// Don't add if a phase already covers this topic
|
|
1127
|
+
if (derivedPhases.some(p => p.title.toLowerCase().includes(cc.slug.split('-')[0])))
|
|
1128
|
+
continue;
|
|
1129
|
+
derivedPhases.push({ ...cc, adrIds: [] });
|
|
1130
|
+
existingSlugSet.add(cc.slug);
|
|
1131
|
+
}
|
|
1132
|
+
console.error(` [PROMPTS] ${derivedPhases.length} phases derived (SPARC + ADRs + cross-cutting, minimum 10 per ADR-PIPELINE-031)`);
|
|
937
1133
|
// ── Helper: extract DDD context names and summaries relevant to a phase ──
|
|
938
1134
|
function getDddSummaryForPhase(phaseTitle, phaseContent) {
|
|
939
1135
|
if (!dddContent)
|
|
@@ -1024,6 +1220,14 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
1024
1220
|
`**Target folder:** \`${phase.folder}/\``,
|
|
1025
1221
|
'',
|
|
1026
1222
|
];
|
|
1223
|
+
// ADR-PIPELINE-033: Simulation lineage in every prompt
|
|
1224
|
+
if (simulationId || traceId) {
|
|
1225
|
+
lines.push('## Simulation Lineage', '');
|
|
1226
|
+
if (simulationId)
|
|
1227
|
+
lines.push(`Originating simulation: \`${simulationId}\``);
|
|
1228
|
+
lines.push(`Trace ID: \`${traceId}\``);
|
|
1229
|
+
lines.push('');
|
|
1230
|
+
}
|
|
1027
1231
|
// ── Narrative description — the core of each prompt ──
|
|
1028
1232
|
lines.push('## Overview', '', narrative, '');
|
|
1029
1233
|
// Previously completed phases (brief list)
|
|
@@ -1075,8 +1279,8 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
1075
1279
|
if (dddSummary) {
|
|
1076
1280
|
lines.push('## Domain Model Reference', '', dddSummary, '');
|
|
1077
1281
|
}
|
|
1078
|
-
// Implementation instructions
|
|
1079
|
-
lines.push('## Implementation Requirements', '', '- All code must be CUSTOM to this project — implement the specific business logic described above', '- Follow the technology decisions from the ADRs referenced in the overview', '- Write production-quality code with proper error handling', '- Include unit tests (London School TDD — mock at module boundaries)', '- Export public interfaces so later build phases can import them', `- Place all files in the \`${phase.folder}/\` directory`, '');
|
|
1282
|
+
// Implementation instructions — ADR-PIPELINE-033: include traceability requirements
|
|
1283
|
+
lines.push('## Implementation Requirements', '', '- All code must be CUSTOM to this project — implement the specific business logic described above', '- Follow the technology decisions from the ADRs referenced in the overview', '- Write production-quality code with proper error handling', '- Include unit tests (London School TDD — mock at module boundaries)', '- Export public interfaces so later build phases can import them', `- Place all files in the \`${phase.folder}/\` directory`, '', '## Traceability Requirements (ADR-PIPELINE-033)', '', '- All domain types that represent decisions, recommendations, or ERP actions must include optional `simulationId?: string` and `traceId?: string` fields', '- Audit trail entries must include these IDs when available', '- ERP transaction payloads must carry `simulationId` and `traceId` for end-to-end lineage', `${simulationId ? `- Use simulation ID \`${simulationId}\` as the default value when creating records in this build step` : '- Simulation ID will be injected at runtime from the pipeline context'}`, '');
|
|
1080
1284
|
fs.writeFileSync(path.join(promptsDir, filename), lines.join('\n'), { mode: 0o600, encoding: 'utf-8' });
|
|
1081
1285
|
completedPhases.push(`${order}. ${phase.title}`);
|
|
1082
1286
|
}
|
|
@@ -1087,7 +1291,17 @@ The prompts must be production-grade — they will be given directly to a coding
|
|
|
1087
1291
|
folder: phase.folder,
|
|
1088
1292
|
adrs: phase.adrIds,
|
|
1089
1293
|
}));
|
|
1090
|
-
|
|
1294
|
+
// ADR-PIPELINE-033: Include simulation lineage in execution plan
|
|
1295
|
+
const plan = {
|
|
1296
|
+
totalSteps,
|
|
1297
|
+
prompts: planItems,
|
|
1298
|
+
lineage: {
|
|
1299
|
+
simulationId: simulationId || undefined,
|
|
1300
|
+
traceId: traceId || undefined,
|
|
1301
|
+
pipelineVersion: '1.7.3',
|
|
1302
|
+
},
|
|
1303
|
+
};
|
|
1304
|
+
fs.writeFileSync(path.join(promptsDir, 'execution-plan.json'), JSON.stringify(plan, null, 2), { mode: 0o600, encoding: 'utf-8' });
|
|
1091
1305
|
console.error(` [PROMPTS] Wrote ${totalSteps} implementation prompts derived from SPARC architecture + ADRs`);
|
|
1092
1306
|
}
|
|
1093
1307
|
copyPlanningArtifacts(runDir, projectRoot);
|