@llm-dev-ops/agentics-cli 1.3.8 → 1.3.9

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.
Files changed (69) hide show
  1. package/dist/adapters/base-adapter.d.ts +58 -1
  2. package/dist/adapters/base-adapter.d.ts.map +1 -1
  3. package/dist/adapters/base-adapter.js +110 -0
  4. package/dist/adapters/base-adapter.js.map +1 -1
  5. package/dist/cli/index.js +992 -16
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/commands/deploy.d.ts +95 -13
  8. package/dist/commands/deploy.d.ts.map +1 -1
  9. package/dist/commands/deploy.js +420 -14
  10. package/dist/commands/deploy.js.map +1 -1
  11. package/dist/commands/erp.d.ts +302 -0
  12. package/dist/commands/erp.d.ts.map +1 -0
  13. package/dist/commands/erp.js +1064 -0
  14. package/dist/commands/erp.js.map +1 -0
  15. package/dist/commands/export.d.ts +40 -13
  16. package/dist/commands/export.d.ts.map +1 -1
  17. package/dist/commands/export.js +434 -14
  18. package/dist/commands/export.js.map +1 -1
  19. package/dist/commands/index.d.ts +20 -12
  20. package/dist/commands/index.d.ts.map +1 -1
  21. package/dist/commands/index.js +10 -6
  22. package/dist/commands/index.js.map +1 -1
  23. package/dist/commands/inspect.d.ts +84 -18
  24. package/dist/commands/inspect.d.ts.map +1 -1
  25. package/dist/commands/inspect.js +585 -131
  26. package/dist/commands/inspect.js.map +1 -1
  27. package/dist/commands/logout.d.ts +34 -0
  28. package/dist/commands/logout.d.ts.map +1 -0
  29. package/dist/commands/logout.js +73 -0
  30. package/dist/commands/logout.js.map +1 -0
  31. package/dist/commands/plan.d.ts +147 -14
  32. package/dist/commands/plan.d.ts.map +1 -1
  33. package/dist/commands/plan.js +555 -16
  34. package/dist/commands/plan.js.map +1 -1
  35. package/dist/commands/policy.d.ts +136 -0
  36. package/dist/commands/policy.d.ts.map +1 -0
  37. package/dist/commands/policy.js +460 -0
  38. package/dist/commands/policy.js.map +1 -0
  39. package/dist/commands/quantify.d.ts +131 -13
  40. package/dist/commands/quantify.d.ts.map +1 -1
  41. package/dist/commands/quantify.js +425 -14
  42. package/dist/commands/quantify.js.map +1 -1
  43. package/dist/commands/simulate.d.ts +119 -13
  44. package/dist/commands/simulate.d.ts.map +1 -1
  45. package/dist/commands/simulate.js +363 -14
  46. package/dist/commands/simulate.js.map +1 -1
  47. package/dist/commands/usage.d.ts +110 -0
  48. package/dist/commands/usage.d.ts.map +1 -0
  49. package/dist/commands/usage.js +507 -0
  50. package/dist/commands/usage.js.map +1 -0
  51. package/dist/commands/whoami.d.ts +33 -0
  52. package/dist/commands/whoami.d.ts.map +1 -0
  53. package/dist/commands/whoami.js +93 -0
  54. package/dist/commands/whoami.js.map +1 -0
  55. package/dist/config/endpoints.d.ts.map +1 -1
  56. package/dist/config/endpoints.js +15 -0
  57. package/dist/config/endpoints.js.map +1 -1
  58. package/dist/modules/command-parser.d.ts +1 -1
  59. package/dist/modules/command-parser.d.ts.map +1 -1
  60. package/dist/modules/command-parser.js +6 -1
  61. package/dist/modules/command-parser.js.map +1 -1
  62. package/dist/modules/output-renderer.d.ts +1 -0
  63. package/dist/modules/output-renderer.d.ts.map +1 -1
  64. package/dist/modules/output-renderer.js +25 -1
  65. package/dist/modules/output-renderer.js.map +1 -1
  66. package/dist/types/index.d.ts +3 -0
  67. package/dist/types/index.d.ts.map +1 -1
  68. package/dist/types/index.js.map +1 -1
  69. package/package.json +4 -4
@@ -1,22 +1,120 @@
1
1
  /**
2
- * Quantify Command
2
+ * Quantify Command - CRUD Command for ROI Report Management
3
3
  *
4
- * SPARC Pseudocode Reference: §2.7
4
+ * ARCHITECTURE:
5
+ * - This module supports both orchestration commands AND local CRUD operations
6
+ * - Local CRUD uses file-based persistence in .agentics/quantify/
7
+ * - Has its own error handling and exit codes
5
8
  *
6
- * FLOW:
7
- * 1. Parse arguments CommandObject
8
- * 2. VALIDATE request against contract (MUST pass before network call)
9
- * 3. Generate ROI report via enterprise-roi-engine
10
- * 4. VALIDATE response has execution_metadata (reject if missing)
11
- * 5. Record audit entry
12
- * 6. Return RoiReportReference
9
+ * SUBCOMMANDS (Local CRUD):
10
+ * - list List all ROI reports
11
+ * - inspect Inspect a specific report by ID
12
+ * - create Create a new ROI report record
13
+ * - delete Delete a report
14
+ * - compare Compare two reports (stubbed math)
13
15
  *
14
- * CONTRACT ENFORCEMENT:
15
- * - Request validation happens BEFORE any network call
16
- * - Response validation requires execution_metadata
17
- * - No bypass flags or soft-fail behavior
16
+ * ORCHESTRATION (External):
17
+ * - Default command executes via enterprise-roi-engine
18
18
  */
19
19
  import type { CommandOptions, RoiReportReference, SimulationReference, RoiReportType, FlexibleInput } from '../types/index.js';
20
+ export declare const QUANTIFY_EXIT_CODES: {
21
+ readonly SUCCESS: 0;
22
+ readonly INPUT_ERROR: 100;
23
+ readonly NOT_FOUND: 100;
24
+ readonly IO_ERROR: 74;
25
+ readonly UNEXPECTED_ERROR: 1;
26
+ };
27
+ export interface QuantifyRecord {
28
+ id: string;
29
+ name: string;
30
+ description: string;
31
+ report_type: RoiReportType;
32
+ simulation_id?: string;
33
+ status: QuantifyStatus;
34
+ metrics: RoiMetrics;
35
+ created_at: string;
36
+ updated_at: string;
37
+ version: number;
38
+ metadata?: Record<string, unknown>;
39
+ }
40
+ export type QuantifyStatus = 'draft' | 'pending' | 'completed' | 'archived';
41
+ export interface RoiMetrics {
42
+ total_cost_savings?: number;
43
+ total_revenue_impact?: number;
44
+ roi_percentage?: number;
45
+ payback_period_months?: number;
46
+ net_present_value?: number;
47
+ internal_rate_of_return?: number;
48
+ currency: string;
49
+ time_horizon: string;
50
+ }
51
+ export interface QuantifyCreateInput {
52
+ name: string;
53
+ description?: string;
54
+ report_type?: RoiReportType;
55
+ simulation_id?: string;
56
+ metrics?: Partial<RoiMetrics>;
57
+ metadata?: Record<string, unknown>;
58
+ }
59
+ export interface QuantifyCreateResult {
60
+ report: QuantifyRecord;
61
+ timing: number;
62
+ }
63
+ export interface QuantifyListInput {
64
+ status?: QuantifyStatus;
65
+ report_type?: RoiReportType;
66
+ limit?: number;
67
+ }
68
+ export interface QuantifyListResult {
69
+ reports: QuantifySummary[];
70
+ count: number;
71
+ timing: number;
72
+ }
73
+ export interface QuantifySummary {
74
+ id: string;
75
+ name: string;
76
+ report_type: RoiReportType;
77
+ status: string;
78
+ created_at: string;
79
+ roi_percentage?: number;
80
+ }
81
+ export interface QuantifyInspectInput {
82
+ id: string;
83
+ }
84
+ export interface QuantifyInspectResult {
85
+ report: QuantifyRecord | null;
86
+ found: boolean;
87
+ timing: number;
88
+ }
89
+ export interface QuantifyDeleteInput {
90
+ id: string;
91
+ }
92
+ export interface QuantifyDeleteResult {
93
+ deleted: boolean;
94
+ id: string;
95
+ timing: number;
96
+ }
97
+ export interface QuantifyCompareInput {
98
+ idA: string;
99
+ idB: string;
100
+ }
101
+ export interface QuantifyCompareResult {
102
+ reportA: QuantifyRecord | null;
103
+ reportB: QuantifyRecord | null;
104
+ comparison: ComparisonSummary | null;
105
+ timing: number;
106
+ }
107
+ export interface ComparisonSummary {
108
+ delta_roi: number | null;
109
+ delta_cost_savings: number | null;
110
+ delta_revenue_impact: number | null;
111
+ percentage_difference: number | null;
112
+ better_report: string | null;
113
+ summary: string;
114
+ }
115
+ export declare function formatQuantifyForDisplay(record: QuantifyRecord): string;
116
+ export declare function formatQuantifyListForDisplay(reports: QuantifySummary[]): string;
117
+ export declare function formatCompareForDisplay(result: QuantifyCompareResult): string;
20
118
  export interface QuantifyCommandInput {
21
119
  simRef: FlexibleInput<SimulationReference>;
22
120
  reportType?: RoiReportType;
@@ -29,4 +127,24 @@ export interface QuantifyCommandResult {
29
127
  timing: number;
30
128
  }
31
129
  export declare function executeQuantifyCommand(input: QuantifyCommandInput, options: CommandOptions): Promise<QuantifyCommandResult>;
130
+ /**
131
+ * Create a new ROI report record
132
+ */
133
+ export declare function executeQuantifyCreateCommand(input: QuantifyCreateInput, options: CommandOptions): Promise<QuantifyCreateResult>;
134
+ /**
135
+ * List ROI reports from local storage
136
+ */
137
+ export declare function executeQuantifyListCommand(input: QuantifyListInput, _options: CommandOptions): Promise<QuantifyListResult>;
138
+ /**
139
+ * Inspect a specific ROI report by ID
140
+ */
141
+ export declare function executeQuantifyInspectCommand(input: QuantifyInspectInput, options: CommandOptions): Promise<QuantifyInspectResult>;
142
+ /**
143
+ * Delete an ROI report
144
+ */
145
+ export declare function executeQuantifyDeleteCommand(input: QuantifyDeleteInput, options: CommandOptions): Promise<QuantifyDeleteResult>;
146
+ /**
147
+ * Compare two ROI reports (stubbed math)
148
+ */
149
+ export declare function executeQuantifyCompareCommand(input: QuantifyCompareInput, options: CommandOptions): Promise<QuantifyCompareResult>;
32
150
  //# sourceMappingURL=quantify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quantify.d.ts","sourceRoot":"","sources":["../../src/commands/quantify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,aAAa,EAEd,MAAM,mBAAmB,CAAC;AAuB3B,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,WAAW,CAAC,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CA6IhC"}
1
+ {"version":3,"file":"quantify.d.ts","sourceRoot":"","sources":["../../src/commands/quantify.ts"],"names":[],"mappings":"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"}
@@ -1,30 +1,255 @@
1
1
  /**
2
- * Quantify Command
2
+ * Quantify Command - CRUD Command for ROI Report Management
3
3
  *
4
- * SPARC Pseudocode Reference: §2.7
4
+ * ARCHITECTURE:
5
+ * - This module supports both orchestration commands AND local CRUD operations
6
+ * - Local CRUD uses file-based persistence in .agentics/quantify/
7
+ * - Has its own error handling and exit codes
5
8
  *
6
- * FLOW:
7
- * 1. Parse arguments CommandObject
8
- * 2. VALIDATE request against contract (MUST pass before network call)
9
- * 3. Generate ROI report via enterprise-roi-engine
10
- * 4. VALIDATE response has execution_metadata (reject if missing)
11
- * 5. Record audit entry
12
- * 6. Return RoiReportReference
9
+ * SUBCOMMANDS (Local CRUD):
10
+ * - list List all ROI reports
11
+ * - inspect Inspect a specific report by ID
12
+ * - create Create a new ROI report record
13
+ * - delete Delete a report
14
+ * - compare Compare two reports (stubbed math)
13
15
  *
14
- * CONTRACT ENFORCEMENT:
15
- * - Request validation happens BEFORE any network call
16
- * - Response validation requires execution_metadata
17
- * - No bypass flags or soft-fail behavior
16
+ * ORCHESTRATION (External):
17
+ * - Default command executes via enterprise-roi-engine
18
18
  */
19
+ import * as fs from 'node:fs';
20
+ import * as path from 'node:path';
19
21
  import { isNaturalLanguage } from '../types/index.js';
20
22
  import { RoiEngineAdapter } from '../adapters/base-adapter.js';
21
23
  import { createOrchestrationEngine, } from '../modules/orchestration-engine.js';
22
24
  import { createArtifactHandoff } from '../modules/artifact-handoff.js';
23
25
  import { createAuditTrail } from '../audit/audit-trail.js';
24
- import { failFast, toError } from '../errors/index.js';
26
+ import { failFast, toError, CLIError } from '../errors/index.js';
25
27
  import { loadEndpointConfig } from '../config/endpoints.js';
26
28
  import { validateRequest, validateResponse, RequestSchemas, ResponseSchemas, } from '../contracts/validator.js';
27
29
  // ============================================================================
30
+ // Quantify-Specific Exit Codes
31
+ // ============================================================================
32
+ export const QUANTIFY_EXIT_CODES = {
33
+ SUCCESS: 0,
34
+ INPUT_ERROR: 100,
35
+ NOT_FOUND: 100,
36
+ IO_ERROR: 74,
37
+ UNEXPECTED_ERROR: 1,
38
+ };
39
+ // ============================================================================
40
+ // Storage Configuration
41
+ // ============================================================================
42
+ function getQuantifyDir() {
43
+ const baseDir = process.env['AGENTICS_DATA_DIR'] ?? process.cwd();
44
+ return path.join(baseDir, '.agentics', 'quantify');
45
+ }
46
+ function ensureQuantifyDir() {
47
+ const dir = getQuantifyDir();
48
+ if (!fs.existsSync(dir)) {
49
+ fs.mkdirSync(dir, { recursive: true });
50
+ }
51
+ }
52
+ function getQuantifyPath(id) {
53
+ return path.join(getQuantifyDir(), `${id}.json`);
54
+ }
55
+ // ============================================================================
56
+ // Storage Operations
57
+ // ============================================================================
58
+ function loadQuantifyRecord(id) {
59
+ const filePath = getQuantifyPath(id);
60
+ if (!fs.existsSync(filePath)) {
61
+ return null;
62
+ }
63
+ try {
64
+ const content = fs.readFileSync(filePath, 'utf-8');
65
+ return JSON.parse(content);
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ function saveQuantifyRecord(record) {
72
+ ensureQuantifyDir();
73
+ const filePath = getQuantifyPath(record.id);
74
+ fs.writeFileSync(filePath, JSON.stringify(record, null, 2), 'utf-8');
75
+ }
76
+ function deleteQuantifyFile(id) {
77
+ const filePath = getQuantifyPath(id);
78
+ if (!fs.existsSync(filePath)) {
79
+ return false;
80
+ }
81
+ fs.unlinkSync(filePath);
82
+ return true;
83
+ }
84
+ function listAllQuantifyRecords() {
85
+ const dir = getQuantifyDir();
86
+ if (!fs.existsSync(dir)) {
87
+ return [];
88
+ }
89
+ const files = fs.readdirSync(dir).filter(f => f.endsWith('.json'));
90
+ const records = [];
91
+ for (const file of files) {
92
+ try {
93
+ const content = fs.readFileSync(path.join(dir, file), 'utf-8');
94
+ records.push(JSON.parse(content));
95
+ }
96
+ catch {
97
+ // Skip invalid files
98
+ }
99
+ }
100
+ return records;
101
+ }
102
+ // ============================================================================
103
+ // ID Generation
104
+ // ============================================================================
105
+ function generateQuantifyId() {
106
+ const timestamp = Date.now().toString(36);
107
+ const random = Math.random().toString(36).substring(2, 8);
108
+ return `roi-${timestamp}-${random}`;
109
+ }
110
+ // ============================================================================
111
+ // Validation
112
+ // ============================================================================
113
+ function validateQuantifyId(id, correlationId) {
114
+ if (!id || typeof id !== 'string' || id.trim() === '') {
115
+ throw new CLIError({
116
+ code: 'ECLI-QUANTIFY-001',
117
+ category: 'INPUT_ERROR',
118
+ message: 'Report ID is required',
119
+ details: { provided: id },
120
+ module: 'quantify',
121
+ correlationId,
122
+ recoverable: false,
123
+ exitCode: QUANTIFY_EXIT_CODES.INPUT_ERROR,
124
+ });
125
+ }
126
+ }
127
+ function validateQuantifyName(name, correlationId) {
128
+ if (!name || typeof name !== 'string' || name.trim() === '') {
129
+ throw new CLIError({
130
+ code: 'ECLI-QUANTIFY-002',
131
+ category: 'INPUT_ERROR',
132
+ message: 'Report name is required',
133
+ details: { provided: name },
134
+ module: 'quantify',
135
+ correlationId,
136
+ recoverable: false,
137
+ exitCode: QUANTIFY_EXIT_CODES.INPUT_ERROR,
138
+ });
139
+ }
140
+ if (name.length > 256) {
141
+ throw new CLIError({
142
+ code: 'ECLI-QUANTIFY-003',
143
+ category: 'INPUT_ERROR',
144
+ message: 'Report name cannot exceed 256 characters',
145
+ details: { provided_length: name.length, max_length: 256 },
146
+ module: 'quantify',
147
+ correlationId,
148
+ recoverable: false,
149
+ exitCode: QUANTIFY_EXIT_CODES.INPUT_ERROR,
150
+ });
151
+ }
152
+ }
153
+ // ============================================================================
154
+ // Display Formatting
155
+ // ============================================================================
156
+ export function formatQuantifyForDisplay(record) {
157
+ const lines = [];
158
+ const statusIcon = record.status === 'completed' ? '[OK]'
159
+ : record.status === 'pending' ? '[PEND]'
160
+ : record.status === 'archived' ? '[ARCH]'
161
+ : '[DRAFT]';
162
+ lines.push(`${statusIcon} ${record.id}`);
163
+ lines.push(` Name: ${record.name}`);
164
+ lines.push(` Report Type: ${record.report_type}`);
165
+ lines.push(` Status: ${record.status}`);
166
+ lines.push(` Description: ${record.description || '(none)'}`);
167
+ if (record.simulation_id) {
168
+ lines.push(` Simulation: ${record.simulation_id}`);
169
+ }
170
+ lines.push(` Version: ${record.version}`);
171
+ lines.push(` Created: ${new Date(record.created_at).toLocaleString()}`);
172
+ lines.push(` Updated: ${new Date(record.updated_at).toLocaleString()}`);
173
+ // Metrics
174
+ const m = record.metrics;
175
+ lines.push(` Currency: ${m.currency}`);
176
+ lines.push(` Time Horizon: ${m.time_horizon}`);
177
+ if (m.roi_percentage !== undefined) {
178
+ lines.push(` ROI: ${m.roi_percentage.toFixed(2)}%`);
179
+ }
180
+ if (m.total_cost_savings !== undefined) {
181
+ lines.push(` Cost Savings: ${m.total_cost_savings.toLocaleString()} ${m.currency}`);
182
+ }
183
+ if (m.total_revenue_impact !== undefined) {
184
+ lines.push(` Revenue Impact: ${m.total_revenue_impact.toLocaleString()} ${m.currency}`);
185
+ }
186
+ if (m.payback_period_months !== undefined) {
187
+ lines.push(` Payback: ${m.payback_period_months} months`);
188
+ }
189
+ if (m.net_present_value !== undefined) {
190
+ lines.push(` NPV: ${m.net_present_value.toLocaleString()} ${m.currency}`);
191
+ }
192
+ if (m.internal_rate_of_return !== undefined) {
193
+ lines.push(` IRR: ${m.internal_rate_of_return.toFixed(2)}%`);
194
+ }
195
+ return lines.join('\n');
196
+ }
197
+ export function formatQuantifyListForDisplay(reports) {
198
+ if (reports.length === 0) {
199
+ return 'No ROI reports found.';
200
+ }
201
+ const lines = [];
202
+ lines.push(`Found ${reports.length} report${reports.length === 1 ? '' : 's'}:`);
203
+ lines.push('');
204
+ for (const report of reports) {
205
+ const roiStr = report.roi_percentage !== undefined ? ` (${report.roi_percentage.toFixed(1)}% ROI)` : '';
206
+ lines.push(` ${report.id} - ${report.name} [${report.status}]${roiStr}`);
207
+ lines.push(` Type: ${report.report_type}`);
208
+ lines.push(` Created: ${new Date(report.created_at).toLocaleString()}`);
209
+ lines.push('');
210
+ }
211
+ return lines.join('\n');
212
+ }
213
+ export function formatCompareForDisplay(result) {
214
+ const lines = [];
215
+ if (!result.reportA || !result.reportB) {
216
+ if (!result.reportA) {
217
+ lines.push('Report A not found.');
218
+ }
219
+ if (!result.reportB) {
220
+ lines.push('Report B not found.');
221
+ }
222
+ return lines.join('\n');
223
+ }
224
+ lines.push('ROI Report Comparison');
225
+ lines.push('=====================');
226
+ lines.push('');
227
+ lines.push(`Report A: ${result.reportA.id} - ${result.reportA.name}`);
228
+ lines.push(`Report B: ${result.reportB.id} - ${result.reportB.name}`);
229
+ lines.push('');
230
+ if (result.comparison) {
231
+ const c = result.comparison;
232
+ if (c.delta_roi !== null) {
233
+ lines.push(`ROI Difference: ${c.delta_roi >= 0 ? '+' : ''}${c.delta_roi.toFixed(2)}%`);
234
+ }
235
+ if (c.delta_cost_savings !== null) {
236
+ lines.push(`Cost Savings Difference: ${c.delta_cost_savings >= 0 ? '+' : ''}${c.delta_cost_savings.toLocaleString()}`);
237
+ }
238
+ if (c.delta_revenue_impact !== null) {
239
+ lines.push(`Revenue Impact Difference: ${c.delta_revenue_impact >= 0 ? '+' : ''}${c.delta_revenue_impact.toLocaleString()}`);
240
+ }
241
+ if (c.percentage_difference !== null) {
242
+ lines.push(`Overall Difference: ${c.percentage_difference >= 0 ? '+' : ''}${c.percentage_difference.toFixed(2)}%`);
243
+ }
244
+ lines.push('');
245
+ lines.push(`Summary: ${c.summary}`);
246
+ if (c.better_report) {
247
+ lines.push(`Better Report: ${c.better_report}`);
248
+ }
249
+ }
250
+ return lines.join('\n');
251
+ }
252
+ // ============================================================================
28
253
  // Quantify Command Implementation
29
254
  // ============================================================================
30
255
  export async function executeQuantifyCommand(input, options) {
@@ -148,4 +373,190 @@ export async function executeQuantifyCommand(input, options) {
148
373
  });
149
374
  }
150
375
  }
376
+ // ============================================================================
377
+ // CRUD Command Implementations
378
+ // ============================================================================
379
+ /**
380
+ * Create a new ROI report record
381
+ */
382
+ export async function executeQuantifyCreateCommand(input, options) {
383
+ const startTime = Date.now();
384
+ const correlationId = options.trace_id ?? crypto.randomUUID();
385
+ validateQuantifyName(input.name, correlationId);
386
+ const now = new Date().toISOString();
387
+ const report = {
388
+ id: generateQuantifyId(),
389
+ name: input.name.trim(),
390
+ description: input.description?.trim() ?? '',
391
+ report_type: input.report_type ?? 'cfo-grade',
392
+ simulation_id: input.simulation_id,
393
+ status: 'draft',
394
+ metrics: {
395
+ currency: input.metrics?.currency ?? 'USD',
396
+ time_horizon: input.metrics?.time_horizon ?? 'annual',
397
+ total_cost_savings: input.metrics?.total_cost_savings,
398
+ total_revenue_impact: input.metrics?.total_revenue_impact,
399
+ roi_percentage: input.metrics?.roi_percentage,
400
+ payback_period_months: input.metrics?.payback_period_months,
401
+ net_present_value: input.metrics?.net_present_value,
402
+ internal_rate_of_return: input.metrics?.internal_rate_of_return,
403
+ },
404
+ created_at: now,
405
+ updated_at: now,
406
+ version: 1,
407
+ metadata: input.metadata,
408
+ };
409
+ try {
410
+ saveQuantifyRecord(report);
411
+ }
412
+ catch (error) {
413
+ throw new CLIError({
414
+ code: 'ECLI-QUANTIFY-IO-001',
415
+ category: 'INTERNAL_ERROR',
416
+ message: 'Failed to save ROI report',
417
+ details: { error: error instanceof Error ? error.message : String(error) },
418
+ module: 'quantify',
419
+ correlationId,
420
+ recoverable: false,
421
+ exitCode: QUANTIFY_EXIT_CODES.IO_ERROR,
422
+ });
423
+ }
424
+ return {
425
+ report,
426
+ timing: Date.now() - startTime,
427
+ };
428
+ }
429
+ /**
430
+ * List ROI reports from local storage
431
+ */
432
+ export async function executeQuantifyListCommand(input, _options) {
433
+ const startTime = Date.now();
434
+ let records = listAllQuantifyRecords();
435
+ // Apply filters
436
+ if (input.status) {
437
+ records = records.filter(r => r.status === input.status);
438
+ }
439
+ if (input.report_type) {
440
+ records = records.filter(r => r.report_type === input.report_type);
441
+ }
442
+ // Sort by updated_at descending
443
+ records.sort((a, b) => new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime());
444
+ // Apply limit
445
+ if (input.limit && input.limit > 0) {
446
+ records = records.slice(0, input.limit);
447
+ }
448
+ // Map to summary
449
+ const summaries = records.map(r => ({
450
+ id: r.id,
451
+ name: r.name,
452
+ report_type: r.report_type,
453
+ status: r.status,
454
+ created_at: r.created_at,
455
+ roi_percentage: r.metrics.roi_percentage,
456
+ }));
457
+ return {
458
+ reports: summaries,
459
+ count: summaries.length,
460
+ timing: Date.now() - startTime,
461
+ };
462
+ }
463
+ /**
464
+ * Inspect a specific ROI report by ID
465
+ */
466
+ export async function executeQuantifyInspectCommand(input, options) {
467
+ const startTime = Date.now();
468
+ const correlationId = options.trace_id ?? crypto.randomUUID();
469
+ validateQuantifyId(input.id, correlationId);
470
+ const report = loadQuantifyRecord(input.id);
471
+ return {
472
+ report,
473
+ found: report !== null,
474
+ timing: Date.now() - startTime,
475
+ };
476
+ }
477
+ /**
478
+ * Delete an ROI report
479
+ */
480
+ export async function executeQuantifyDeleteCommand(input, options) {
481
+ const startTime = Date.now();
482
+ const correlationId = options.trace_id ?? crypto.randomUUID();
483
+ validateQuantifyId(input.id, correlationId);
484
+ const deleted = deleteQuantifyFile(input.id);
485
+ if (!deleted) {
486
+ throw new CLIError({
487
+ code: 'ECLI-QUANTIFY-NOT-FOUND',
488
+ category: 'INPUT_ERROR',
489
+ message: `ROI report not found: ${input.id}`,
490
+ details: { id: input.id },
491
+ module: 'quantify',
492
+ correlationId,
493
+ recoverable: false,
494
+ exitCode: QUANTIFY_EXIT_CODES.NOT_FOUND,
495
+ });
496
+ }
497
+ return {
498
+ deleted: true,
499
+ id: input.id,
500
+ timing: Date.now() - startTime,
501
+ };
502
+ }
503
+ /**
504
+ * Compare two ROI reports (stubbed math)
505
+ */
506
+ export async function executeQuantifyCompareCommand(input, options) {
507
+ const startTime = Date.now();
508
+ const correlationId = options.trace_id ?? crypto.randomUUID();
509
+ validateQuantifyId(input.idA, correlationId);
510
+ validateQuantifyId(input.idB, correlationId);
511
+ const reportA = loadQuantifyRecord(input.idA);
512
+ const reportB = loadQuantifyRecord(input.idB);
513
+ let comparison = null;
514
+ if (reportA && reportB) {
515
+ const mA = reportA.metrics;
516
+ const mB = reportB.metrics;
517
+ const deltaRoi = (mA.roi_percentage !== undefined && mB.roi_percentage !== undefined)
518
+ ? mA.roi_percentage - mB.roi_percentage
519
+ : null;
520
+ const deltaCostSavings = (mA.total_cost_savings !== undefined && mB.total_cost_savings !== undefined)
521
+ ? mA.total_cost_savings - mB.total_cost_savings
522
+ : null;
523
+ const deltaRevenueImpact = (mA.total_revenue_impact !== undefined && mB.total_revenue_impact !== undefined)
524
+ ? mA.total_revenue_impact - mB.total_revenue_impact
525
+ : null;
526
+ // Simple percentage difference based on ROI
527
+ const percentageDifference = deltaRoi;
528
+ let betterReport = null;
529
+ let summary;
530
+ if (deltaRoi !== null) {
531
+ if (deltaRoi > 0) {
532
+ betterReport = reportA.id;
533
+ summary = `Report A shows ${deltaRoi.toFixed(2)}% higher ROI than Report B.`;
534
+ }
535
+ else if (deltaRoi < 0) {
536
+ betterReport = reportB.id;
537
+ summary = `Report B shows ${Math.abs(deltaRoi).toFixed(2)}% higher ROI than Report A.`;
538
+ }
539
+ else {
540
+ summary = 'Both reports show equivalent ROI.';
541
+ }
542
+ }
543
+ else {
544
+ summary = 'Unable to compare ROI - metrics not available in one or both reports.';
545
+ }
546
+ comparison = {
547
+ delta_roi: deltaRoi,
548
+ delta_cost_savings: deltaCostSavings,
549
+ delta_revenue_impact: deltaRevenueImpact,
550
+ percentage_difference: percentageDifference,
551
+ better_report: betterReport,
552
+ summary,
553
+ };
554
+ }
555
+ return {
556
+ reportA,
557
+ reportB,
558
+ comparison,
559
+ timing: Date.now() - startTime,
560
+ };
561
+ }
151
562
  //# sourceMappingURL=quantify.js.map