@llm-dev-ops/agentics-cli 1.3.7 → 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.
- package/dist/adapters/base-adapter.d.ts +58 -1
- package/dist/adapters/base-adapter.d.ts.map +1 -1
- package/dist/adapters/base-adapter.js +110 -0
- package/dist/adapters/base-adapter.js.map +1 -1
- package/dist/cli/index.js +992 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/deploy.d.ts +95 -13
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +420 -14
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/erp.d.ts +302 -0
- package/dist/commands/erp.d.ts.map +1 -0
- package/dist/commands/erp.js +1064 -0
- package/dist/commands/erp.js.map +1 -0
- package/dist/commands/export.d.ts +40 -13
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +434 -14
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/index.d.ts +20 -12
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +10 -6
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/inspect.d.ts +84 -18
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +585 -131
- package/dist/commands/inspect.js.map +1 -1
- package/dist/commands/logout.d.ts +34 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +73 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/plan.d.ts +147 -14
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +557 -16
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/policy.d.ts +136 -0
- package/dist/commands/policy.d.ts.map +1 -0
- package/dist/commands/policy.js +460 -0
- package/dist/commands/policy.js.map +1 -0
- package/dist/commands/quantify.d.ts +131 -13
- package/dist/commands/quantify.d.ts.map +1 -1
- package/dist/commands/quantify.js +425 -14
- package/dist/commands/quantify.js.map +1 -1
- package/dist/commands/simulate.d.ts +119 -13
- package/dist/commands/simulate.d.ts.map +1 -1
- package/dist/commands/simulate.js +363 -14
- package/dist/commands/simulate.js.map +1 -1
- package/dist/commands/usage.d.ts +110 -0
- package/dist/commands/usage.d.ts.map +1 -0
- package/dist/commands/usage.js +507 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/whoami.d.ts +33 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +93 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config/endpoints.d.ts.map +1 -1
- package/dist/config/endpoints.js +16 -1
- package/dist/config/endpoints.js.map +1 -1
- package/dist/contracts/schemas/index.d.ts +4 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -1
- package/dist/contracts/schemas/index.js +2 -0
- package/dist/contracts/schemas/index.js.map +1 -1
- package/dist/contracts/validator.d.ts.map +1 -1
- package/dist/contracts/validator.js +55 -148
- package/dist/contracts/validator.js.map +1 -1
- package/dist/modules/artifact-handoff.d.ts +5 -0
- package/dist/modules/artifact-handoff.d.ts.map +1 -1
- package/dist/modules/artifact-handoff.js +47 -11
- package/dist/modules/artifact-handoff.js.map +1 -1
- package/dist/modules/command-parser.d.ts +1 -1
- package/dist/modules/command-parser.d.ts.map +1 -1
- package/dist/modules/command-parser.js +6 -1
- package/dist/modules/command-parser.js.map +1 -1
- package/dist/modules/output-renderer.d.ts +1 -0
- package/dist/modules/output-renderer.d.ts.map +1 -1
- package/dist/modules/output-renderer.js +25 -1
- package/dist/modules/output-renderer.js.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- 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
|
-
*
|
|
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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
*
|
|
15
|
-
* -
|
|
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;
|
|
1
|
+
{"version":3,"file":"quantify.d.ts","sourceRoot":"","sources":["../../src/commands/quantify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACb,aAAa,EAEd,MAAM,mBAAmB,CAAC;AAuB3B,eAAO,MAAM,mBAAmB;;;;;;CAMtB,CAAC;AAMX,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,aAAa,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAE5E,MAAM,WAAW,UAAU;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,aAAa,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAoID,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CA2CvE;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAkB/E;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA0C7E;AAMD,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;AAMD;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,oBAAoB,CAAC,CAiD/B;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAoC7B;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAahC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,oBAAoB,CAAC,CA0B/B;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,qBAAqB,CAAC,CAgEhC"}
|
|
@@ -1,30 +1,255 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Quantify Command
|
|
2
|
+
* Quantify Command - CRUD Command for ROI Report Management
|
|
3
3
|
*
|
|
4
|
-
*
|
|
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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
*
|
|
15
|
-
* -
|
|
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
|