@artemiskit/cli 0.1.8 → 0.2.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/CHANGELOG.md +83 -0
- package/bin/artemis.ts +0 -0
- package/dist/index.js +70637 -33387
- package/dist/src/commands/compare.d.ts.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/redteam.d.ts.map +1 -1
- package/dist/src/commands/run.d.ts.map +1 -1
- package/dist/src/commands/stress.d.ts.map +1 -1
- package/dist/src/config/loader.d.ts +3 -1
- package/dist/src/config/loader.d.ts.map +1 -1
- package/dist/src/config/schema.d.ts +8 -0
- package/dist/src/config/schema.d.ts.map +1 -1
- package/dist/src/ui/index.d.ts +3 -1
- package/dist/src/ui/index.d.ts.map +1 -1
- package/dist/src/ui/panels.d.ts +21 -0
- package/dist/src/ui/panels.d.ts.map +1 -1
- package/dist/src/ui/prompts.d.ts +92 -0
- package/dist/src/ui/prompts.d.ts.map +1 -0
- package/dist/src/utils/adapter.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/commands/compare.ts +25 -0
- package/src/commands/init.ts +173 -69
- package/src/commands/redteam.ts +63 -10
- package/src/commands/run.ts +542 -137
- package/src/commands/stress.ts +76 -3
- package/src/config/loader.ts +5 -2
- package/src/config/schema.ts +1 -0
- package/src/ui/index.ts +19 -0
- package/src/ui/panels.ts +153 -5
- package/src/ui/prompts.ts +749 -0
- package/src/utils/adapter.ts +8 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/compare.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../../src/commands/compare.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6HpC,wBAAgB,cAAc,IAAI,OAAO,CAsGxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4RpC,wBAAgB,WAAW,IAAI,OAAO,CA0HrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redteam.d.ts","sourceRoot":"","sources":["../../../src/commands/redteam.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"redteam.d.ts","sourceRoot":"","sources":["../../../src/commands/redteam.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkCH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkCpC,wBAAgB,cAAc,IAAI,OAAO,CA6bxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgVpC,wBAAgB,UAAU,IAAI,OAAO,CAmTpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stress.d.ts","sourceRoot":"","sources":["../../../src/commands/stress.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"stress.d.ts","sourceRoot":"","sources":["../../../src/commands/stress.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCpC,wBAAgB,aAAa,IAAI,OAAO,CAuRvC"}
|
|
@@ -5,7 +5,9 @@ import { type ArtemisConfig } from './schema';
|
|
|
5
5
|
/**
|
|
6
6
|
* Find and load the configuration file
|
|
7
7
|
*/
|
|
8
|
-
export declare function loadConfig(configPath?: string): Promise<ArtemisConfig
|
|
8
|
+
export declare function loadConfig(configPath?: string): Promise<(ArtemisConfig & {
|
|
9
|
+
_path: string;
|
|
10
|
+
}) | null>;
|
|
9
11
|
/**
|
|
10
12
|
* Get a merged config with CLI options taking precedence
|
|
11
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/config/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,UAAU,CAAC;AAInE;;GAEG;AACH,wBAAsB,UAAU,
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/config/loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,UAAU,CAAC;AAInE;;GAEG;AACH,wBAAsB,UAAU,CAC9B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC,CA+BrD;AAiDD;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,GAAG,IAAI,EAChC,UAAU,EAAE,OAAO,CAAC,aAAa,CAAC,GACjC,aAAa,CAWf"}
|
|
@@ -12,6 +12,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
|
|
|
12
12
|
resourceName: z.ZodOptional<z.ZodString>;
|
|
13
13
|
deploymentName: z.ZodOptional<z.ZodString>;
|
|
14
14
|
apiVersion: z.ZodOptional<z.ZodString>;
|
|
15
|
+
embeddingDeploymentName: z.ZodOptional<z.ZodString>;
|
|
15
16
|
underlyingProvider: z.ZodOptional<z.ZodEnum<["openai", "azure", "anthropic", "google", "mistral"]>>;
|
|
16
17
|
}, "strip", z.ZodTypeAny, {
|
|
17
18
|
apiKey?: string | undefined;
|
|
@@ -23,6 +24,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
|
|
|
23
24
|
resourceName?: string | undefined;
|
|
24
25
|
deploymentName?: string | undefined;
|
|
25
26
|
apiVersion?: string | undefined;
|
|
27
|
+
embeddingDeploymentName?: string | undefined;
|
|
26
28
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
27
29
|
}, {
|
|
28
30
|
apiKey?: string | undefined;
|
|
@@ -34,6 +36,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
|
|
|
34
36
|
resourceName?: string | undefined;
|
|
35
37
|
deploymentName?: string | undefined;
|
|
36
38
|
apiVersion?: string | undefined;
|
|
39
|
+
embeddingDeploymentName?: string | undefined;
|
|
37
40
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
38
41
|
}>;
|
|
39
42
|
declare const StorageConfigSchema: z.ZodObject<{
|
|
@@ -69,6 +72,7 @@ export declare const ArtemisConfigSchema: z.ZodObject<{
|
|
|
69
72
|
resourceName: z.ZodOptional<z.ZodString>;
|
|
70
73
|
deploymentName: z.ZodOptional<z.ZodString>;
|
|
71
74
|
apiVersion: z.ZodOptional<z.ZodString>;
|
|
75
|
+
embeddingDeploymentName: z.ZodOptional<z.ZodString>;
|
|
72
76
|
underlyingProvider: z.ZodOptional<z.ZodEnum<["openai", "azure", "anthropic", "google", "mistral"]>>;
|
|
73
77
|
}, "strip", z.ZodTypeAny, {
|
|
74
78
|
apiKey?: string | undefined;
|
|
@@ -80,6 +84,7 @@ export declare const ArtemisConfigSchema: z.ZodObject<{
|
|
|
80
84
|
resourceName?: string | undefined;
|
|
81
85
|
deploymentName?: string | undefined;
|
|
82
86
|
apiVersion?: string | undefined;
|
|
87
|
+
embeddingDeploymentName?: string | undefined;
|
|
83
88
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
84
89
|
}, {
|
|
85
90
|
apiKey?: string | undefined;
|
|
@@ -91,6 +96,7 @@ export declare const ArtemisConfigSchema: z.ZodObject<{
|
|
|
91
96
|
resourceName?: string | undefined;
|
|
92
97
|
deploymentName?: string | undefined;
|
|
93
98
|
apiVersion?: string | undefined;
|
|
99
|
+
embeddingDeploymentName?: string | undefined;
|
|
94
100
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
95
101
|
}>>>;
|
|
96
102
|
storage: z.ZodOptional<z.ZodObject<{
|
|
@@ -154,6 +160,7 @@ export declare const ArtemisConfigSchema: z.ZodObject<{
|
|
|
154
160
|
resourceName?: string | undefined;
|
|
155
161
|
deploymentName?: string | undefined;
|
|
156
162
|
apiVersion?: string | undefined;
|
|
163
|
+
embeddingDeploymentName?: string | undefined;
|
|
157
164
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
158
165
|
}> | undefined;
|
|
159
166
|
storage?: {
|
|
@@ -187,6 +194,7 @@ export declare const ArtemisConfigSchema: z.ZodObject<{
|
|
|
187
194
|
resourceName?: string | undefined;
|
|
188
195
|
deploymentName?: string | undefined;
|
|
189
196
|
apiVersion?: string | undefined;
|
|
197
|
+
embeddingDeploymentName?: string | undefined;
|
|
190
198
|
underlyingProvider?: "openai" | "anthropic" | "google" | "mistral" | "azure" | undefined;
|
|
191
199
|
}> | undefined;
|
|
192
200
|
storage?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,CAAC;AAEH,QAAA,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAMvB,CAAC;AAcH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
package/dist/src/ui/index.d.ts
CHANGED
|
@@ -7,10 +7,12 @@ export { colors, icons, colorByPercentage, formatPercentage } from './colors.js'
|
|
|
7
7
|
export { isTTY, getTerminalWidth, renderConditional, centerText, padText, stripAnsi, truncate, formatDuration, formatNumber, } from './utils.js';
|
|
8
8
|
export { renderProgressBar, ProgressBar, renderInlineProgress } from './progress.js';
|
|
9
9
|
export type { ProgressBarOptions } from './progress.js';
|
|
10
|
-
export { renderSummaryPanel, renderStressSummaryPanel, renderRedteamSummaryPanel, renderInfoBox, } from './panels.js';
|
|
10
|
+
export { renderSummaryPanel, renderStressSummaryPanel, renderRedteamSummaryPanel, renderInfoBox, renderFailureReason, } from './panels.js';
|
|
11
11
|
export type { SummaryData, StressSummaryData, RedteamSummaryData } from './panels.js';
|
|
12
12
|
export { renderError, renderWarning, getProviderErrorContext } from './errors.js';
|
|
13
13
|
export type { ErrorContext } from './errors.js';
|
|
14
14
|
export { LiveTestStatus, Spinner, createSpinner } from './live-status.js';
|
|
15
15
|
export type { TestStatus } from './live-status.js';
|
|
16
|
+
export { isInteractive, promptProvider, promptModel, promptScenarios, promptConfirm, promptInput, promptPassword, promptSelect, promptApiKeyIfNeeded, getApiKeyEnvVar, runInitWizard, PROVIDER_CHOICES, MODEL_CHOICES, } from './prompts.js';
|
|
17
|
+
export type { InitWizardResult } from './prompts.js';
|
|
16
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjF,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,SAAS,EACT,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrF,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjF,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,SAAS,EACT,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrF,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,EACzB,aAAa,EACb,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAClF,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,eAAe,EACf,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/src/ui/panels.d.ts
CHANGED
|
@@ -17,9 +17,22 @@ export interface StressSummaryData {
|
|
|
17
17
|
duration: number;
|
|
18
18
|
avgLatency: number;
|
|
19
19
|
p50Latency: number;
|
|
20
|
+
p90Latency: number;
|
|
20
21
|
p95Latency: number;
|
|
21
22
|
p99Latency: number;
|
|
22
23
|
throughput: number;
|
|
24
|
+
/** Token usage (optional) */
|
|
25
|
+
tokens?: {
|
|
26
|
+
total: number;
|
|
27
|
+
prompt: number;
|
|
28
|
+
completion: number;
|
|
29
|
+
avgPerRequest: number;
|
|
30
|
+
};
|
|
31
|
+
/** Cost estimation (optional) */
|
|
32
|
+
cost?: {
|
|
33
|
+
totalUsd: number;
|
|
34
|
+
model: string;
|
|
35
|
+
};
|
|
23
36
|
}
|
|
24
37
|
export interface RedteamSummaryData {
|
|
25
38
|
totalCases: number;
|
|
@@ -46,4 +59,12 @@ export declare function renderRedteamSummaryPanel(data: RedteamSummaryData): str
|
|
|
46
59
|
* Render a simple info box
|
|
47
60
|
*/
|
|
48
61
|
export declare function renderInfoBox(title: string, lines: string[]): string;
|
|
62
|
+
/**
|
|
63
|
+
* Render a styled failure reason for test cases
|
|
64
|
+
* Provides consistent formatting for verbose error output
|
|
65
|
+
*/
|
|
66
|
+
export declare function renderFailureReason(reason: string, options?: {
|
|
67
|
+
matcherType?: string;
|
|
68
|
+
indent?: number;
|
|
69
|
+
}): string;
|
|
49
70
|
//# sourceMappingURL=panels.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../../../src/ui/panels.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../../../src/ui/panels.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,iCAAiC;IACjC,IAAI,CAAC,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAiC5D;AA4BD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAiHxE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CA4C1E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAsBpE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IACR,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,MAAM,CA0CR"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive prompts module
|
|
3
|
+
* Provides Inquirer-based user prompts for CLI interactivity
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if interactive mode is available
|
|
7
|
+
*/
|
|
8
|
+
export declare function isInteractive(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Provider options for selection
|
|
11
|
+
* Note: Only providers with implemented adapters are included
|
|
12
|
+
*/
|
|
13
|
+
export declare const PROVIDER_CHOICES: {
|
|
14
|
+
name: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* Known models by provider - used for validation
|
|
19
|
+
* Updated January 2026
|
|
20
|
+
*/
|
|
21
|
+
export declare const KNOWN_MODELS: Record<string, string[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Model choices displayed in the prompt
|
|
24
|
+
* Updated January 2026
|
|
25
|
+
*/
|
|
26
|
+
export declare const MODEL_CHOICES: Record<string, {
|
|
27
|
+
name: string;
|
|
28
|
+
value: string;
|
|
29
|
+
}[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Prompt user to select a provider
|
|
32
|
+
*/
|
|
33
|
+
export declare function promptProvider(message?: string): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Prompt user to select a model for a given provider
|
|
36
|
+
* Includes hybrid validation for custom models
|
|
37
|
+
*/
|
|
38
|
+
export declare function promptModel(provider: string, message?: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Prompt user to select scenarios from a list
|
|
41
|
+
*/
|
|
42
|
+
export declare function promptScenarios(scenarios: {
|
|
43
|
+
path: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}[], message?: string): Promise<string[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Prompt for confirmation
|
|
48
|
+
*/
|
|
49
|
+
export declare function promptConfirm(message: string, defaultValue?: boolean): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Prompt for text input
|
|
52
|
+
*/
|
|
53
|
+
export declare function promptInput(message: string, options?: {
|
|
54
|
+
default?: string;
|
|
55
|
+
validate?: (input: string) => boolean | string;
|
|
56
|
+
}): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Prompt for a password/secret (hidden input)
|
|
59
|
+
*/
|
|
60
|
+
export declare function promptPassword(message: string, options?: {
|
|
61
|
+
validate?: (input: string) => boolean | string;
|
|
62
|
+
}): Promise<string>;
|
|
63
|
+
/**
|
|
64
|
+
* Prompt for selection from a list
|
|
65
|
+
*/
|
|
66
|
+
export declare function promptSelect<T extends string>(message: string, choices: {
|
|
67
|
+
name: string;
|
|
68
|
+
value: T;
|
|
69
|
+
}[]): Promise<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Interactive init wizard configuration
|
|
72
|
+
*/
|
|
73
|
+
export interface InitWizardResult {
|
|
74
|
+
projectName: string;
|
|
75
|
+
provider: string;
|
|
76
|
+
model: string;
|
|
77
|
+
storageType: 'local' | 'supabase';
|
|
78
|
+
createExample: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Run the interactive init wizard
|
|
82
|
+
*/
|
|
83
|
+
export declare function runInitWizard(): Promise<InitWizardResult>;
|
|
84
|
+
/**
|
|
85
|
+
* Prompt for API key if not set
|
|
86
|
+
*/
|
|
87
|
+
export declare function promptApiKeyIfNeeded(provider: string, envVarName: string): Promise<string | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Get the environment variable name for a provider's API key
|
|
90
|
+
*/
|
|
91
|
+
export declare function getApiKeyEnvVar(provider: string): string;
|
|
92
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/ui/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;GAQ5B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAgHjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAwD3E,CAAC;AAEF;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,SAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AA8QD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkChG;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC3C,OAAO,SAA6B,GACnC,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBnB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,UAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAU1F;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;CAC3C,GACL,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAAC;CAC3C,GACL,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,CAAC,SAAS,MAAM,EACjD,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,EAAE,GACpC,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,GAAG,UAAU,CAAC;IAClC,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CA4C/D;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6BxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/utils/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sCAAsC;IACtC,UAAU,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAClC,wCAAwC;IACxC,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,qCAAqC;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B;AAOD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,aAAa,EAAE,aAAa,CAAC;IAC7B,+DAA+D;IAC/D,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CA8ErF;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/utils/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,sCAAsC;IACtC,UAAU,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAClC,wCAAwC;IACxC,cAAc,CAAC,EAAE,YAAY,CAAC;IAC9B,qCAAqC;IACrC,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B;AAOD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oDAAoD;IACpD,aAAa,EAAE,aAAa,CAAC;IAC7B,+DAA+D;IAC/D,cAAc,EAAE,cAAc,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CA8ErF;AA+WD;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,EACzB,cAAc,CAAC,EAAE,MAAM,GACtB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAK5C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,CAAC,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAA;CAAE,CAKjE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,EACzB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,CAAC,EAAE,MAAM,EACjB,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,GAAG,SAAS,CAEpB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artemiskit/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Command-line interface for ArtemisKit LLM evaluation toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
"test": "bun test"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@artemiskit/adapter-openai": "0.1.
|
|
49
|
-
"@artemiskit/adapter-vercel-ai": "0.1.
|
|
50
|
-
"@artemiskit/core": "0.
|
|
51
|
-
"@artemiskit/redteam": "0.
|
|
52
|
-
"@artemiskit/reports": "0.
|
|
48
|
+
"@artemiskit/adapter-openai": "0.1.7",
|
|
49
|
+
"@artemiskit/adapter-vercel-ai": "0.1.7",
|
|
50
|
+
"@artemiskit/core": "0.2.0",
|
|
51
|
+
"@artemiskit/redteam": "0.2.0",
|
|
52
|
+
"@artemiskit/reports": "0.2.0",
|
|
53
53
|
"chalk": "^5.3.0",
|
|
54
54
|
"cli-table3": "^0.6.3",
|
|
55
55
|
"commander": "^12.0.0",
|
package/src/commands/compare.ts
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Compare command - Compare two test runs
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { writeFileSync } from 'node:fs';
|
|
6
|
+
import { resolve } from 'node:path';
|
|
7
|
+
import { buildComparisonData, generateCompareHTMLReport } from '@artemiskit/reports';
|
|
5
8
|
import chalk from 'chalk';
|
|
6
9
|
import { Command } from 'commander';
|
|
7
10
|
import { loadConfig } from '../config/loader.js';
|
|
@@ -11,6 +14,8 @@ import { createStorage } from '../utils/storage.js';
|
|
|
11
14
|
interface CompareOptions {
|
|
12
15
|
threshold?: number;
|
|
13
16
|
config?: string;
|
|
17
|
+
html?: string;
|
|
18
|
+
json?: string;
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
function renderComparisonPanel(
|
|
@@ -135,6 +140,8 @@ export function compareCommand(): Command {
|
|
|
135
140
|
.argument('<current>', 'Current run ID')
|
|
136
141
|
.option('--threshold <number>', 'Regression threshold (0-1)', '0.05')
|
|
137
142
|
.option('--config <path>', 'Path to config file')
|
|
143
|
+
.option('--html <path>', 'Generate HTML comparison report')
|
|
144
|
+
.option('--json <path>', 'Generate JSON comparison report')
|
|
138
145
|
.action(async (baselineId: string, currentId: string, options: CompareOptions) => {
|
|
139
146
|
const spinner = createSpinner('Loading runs...');
|
|
140
147
|
spinner.start();
|
|
@@ -165,6 +172,24 @@ export function compareCommand(): Command {
|
|
|
165
172
|
const comparison = await storage.compare(baselineId, currentId);
|
|
166
173
|
const { baseline, current, delta } = comparison;
|
|
167
174
|
|
|
175
|
+
// Generate HTML report if requested
|
|
176
|
+
if (options.html) {
|
|
177
|
+
const htmlPath = resolve(options.html);
|
|
178
|
+
const html = generateCompareHTMLReport(baseline, current);
|
|
179
|
+
writeFileSync(htmlPath, html, 'utf-8');
|
|
180
|
+
console.log(`${icons.passed} HTML comparison report saved to: ${chalk.cyan(htmlPath)}`);
|
|
181
|
+
console.log();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Generate JSON report if requested
|
|
185
|
+
if (options.json) {
|
|
186
|
+
const jsonPath = resolve(options.json);
|
|
187
|
+
const comparisonData = buildComparisonData(baseline, current);
|
|
188
|
+
writeFileSync(jsonPath, JSON.stringify(comparisonData, null, 2), 'utf-8');
|
|
189
|
+
console.log(`${icons.passed} JSON comparison report saved to: ${chalk.cyan(jsonPath)}`);
|
|
190
|
+
console.log();
|
|
191
|
+
}
|
|
192
|
+
|
|
168
193
|
// Show comparison panel
|
|
169
194
|
if (isTTY) {
|
|
170
195
|
console.log(renderComparisonPanel(baseline, current, delta));
|
package/src/commands/init.ts
CHANGED
|
@@ -7,7 +7,13 @@ import { appendFile, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import { Command } from 'commander';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type InitWizardResult,
|
|
12
|
+
createSpinner,
|
|
13
|
+
icons,
|
|
14
|
+
isInteractive,
|
|
15
|
+
runInitWizard,
|
|
16
|
+
} from '../ui/index.js';
|
|
11
17
|
import { checkForUpdateAndNotify, getCurrentVersion } from '../utils/update-checker.js';
|
|
12
18
|
|
|
13
19
|
const DEFAULT_CONFIG = `# ArtemisKit Configuration
|
|
@@ -86,6 +92,67 @@ const ENV_KEYS = [
|
|
|
86
92
|
'ANTHROPIC_API_KEY=',
|
|
87
93
|
];
|
|
88
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Generate config content from wizard results
|
|
97
|
+
*/
|
|
98
|
+
function generateConfigFromWizard(wizard: InitWizardResult): string {
|
|
99
|
+
const providerConfigs: Record<string, string> = {
|
|
100
|
+
openai: ` openai:
|
|
101
|
+
apiKey: \${OPENAI_API_KEY}
|
|
102
|
+
defaultModel: ${wizard.model}`,
|
|
103
|
+
'azure-openai': ` azure-openai:
|
|
104
|
+
apiKey: \${AZURE_OPENAI_API_KEY}
|
|
105
|
+
resourceName: \${AZURE_OPENAI_RESOURCE}
|
|
106
|
+
deploymentName: \${AZURE_OPENAI_DEPLOYMENT}
|
|
107
|
+
apiVersion: "2024-02-15-preview"`,
|
|
108
|
+
anthropic: ` anthropic:
|
|
109
|
+
apiKey: \${ANTHROPIC_API_KEY}
|
|
110
|
+
defaultModel: ${wizard.model}`,
|
|
111
|
+
google: ` google:
|
|
112
|
+
apiKey: \${GOOGLE_AI_API_KEY}
|
|
113
|
+
defaultModel: ${wizard.model}`,
|
|
114
|
+
mistral: ` mistral:
|
|
115
|
+
apiKey: \${MISTRAL_API_KEY}
|
|
116
|
+
defaultModel: ${wizard.model}`,
|
|
117
|
+
ollama: ` ollama:
|
|
118
|
+
baseUrl: http://localhost:11434
|
|
119
|
+
defaultModel: ${wizard.model}`,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const storageConfig =
|
|
123
|
+
wizard.storageType === 'supabase'
|
|
124
|
+
? `storage:
|
|
125
|
+
type: supabase
|
|
126
|
+
supabaseUrl: \${SUPABASE_URL}
|
|
127
|
+
supabaseKey: \${SUPABASE_ANON_KEY}`
|
|
128
|
+
: `storage:
|
|
129
|
+
type: local
|
|
130
|
+
basePath: ./artemis-runs`;
|
|
131
|
+
|
|
132
|
+
return `# ArtemisKit Configuration
|
|
133
|
+
project: ${wizard.projectName}
|
|
134
|
+
|
|
135
|
+
# Default provider settings
|
|
136
|
+
provider: ${wizard.provider}
|
|
137
|
+
model: ${wizard.model}
|
|
138
|
+
|
|
139
|
+
# Provider configurations
|
|
140
|
+
providers:
|
|
141
|
+
${providerConfigs[wizard.provider] || providerConfigs.openai}
|
|
142
|
+
|
|
143
|
+
# Storage configuration
|
|
144
|
+
${storageConfig}
|
|
145
|
+
|
|
146
|
+
# Scenarios directory
|
|
147
|
+
scenariosDir: ./scenarios
|
|
148
|
+
|
|
149
|
+
# Output settings
|
|
150
|
+
output:
|
|
151
|
+
format: json
|
|
152
|
+
dir: ./artemis-output
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
|
|
89
156
|
function renderWelcomeBanner(): string {
|
|
90
157
|
// Brand color for "KIT" portion: #fb923c (orange)
|
|
91
158
|
const brandColor = chalk.hex('#fb923c');
|
|
@@ -230,82 +297,119 @@ export function initCommand(): Command {
|
|
|
230
297
|
.description('Initialize ArtemisKit in the current directory')
|
|
231
298
|
.option('-f, --force', 'Overwrite existing configuration')
|
|
232
299
|
.option('--skip-env', 'Skip adding environment variables to .env')
|
|
233
|
-
.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
300
|
+
.option('-i, --interactive', 'Run interactive setup wizard')
|
|
301
|
+
.option('-y, --yes', 'Use defaults without prompts (non-interactive)')
|
|
302
|
+
.action(
|
|
303
|
+
async (options: {
|
|
304
|
+
force?: boolean;
|
|
305
|
+
skipEnv?: boolean;
|
|
306
|
+
interactive?: boolean;
|
|
307
|
+
yes?: boolean;
|
|
308
|
+
}) => {
|
|
309
|
+
const spinner = createSpinner();
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
const cwd = process.cwd();
|
|
313
|
+
|
|
314
|
+
// Show welcome banner
|
|
315
|
+
console.log(renderWelcomeBanner());
|
|
316
|
+
|
|
317
|
+
// Determine if we should run interactive wizard
|
|
318
|
+
const shouldRunWizard =
|
|
319
|
+
options.interactive || (isInteractive() && !options.yes && !options.force);
|
|
320
|
+
|
|
321
|
+
let configContent = DEFAULT_CONFIG;
|
|
322
|
+
let createExample = true;
|
|
323
|
+
|
|
324
|
+
// Run interactive wizard if applicable
|
|
325
|
+
if (shouldRunWizard) {
|
|
326
|
+
try {
|
|
327
|
+
const wizardResult = await runInitWizard();
|
|
328
|
+
configContent = generateConfigFromWizard(wizardResult);
|
|
329
|
+
createExample = wizardResult.createExample;
|
|
330
|
+
console.log(''); // Add spacing after wizard
|
|
331
|
+
} catch (wizardError) {
|
|
332
|
+
// If wizard fails (e.g., user cancels), fall back to defaults
|
|
333
|
+
if ((wizardError as Error).message?.includes('closed')) {
|
|
334
|
+
console.log(chalk.yellow('\n Setup cancelled. Using defaults.\n'));
|
|
335
|
+
} else {
|
|
336
|
+
throw wizardError;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
262
340
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
spinner.
|
|
269
|
-
} else {
|
|
270
|
-
spinner.start('Creating example scenario...');
|
|
271
|
-
await writeFile(scenarioPath, DEFAULT_SCENARIO);
|
|
272
|
-
spinner.succeed(
|
|
273
|
-
scenarioExists ? 'Overwrote scenarios/example.yaml' : 'Created scenarios/example.yaml'
|
|
274
|
-
);
|
|
275
|
-
}
|
|
341
|
+
// Step 1: Create directories
|
|
342
|
+
spinner.start('Creating project structure...');
|
|
343
|
+
await mkdir(join(cwd, 'scenarios'), { recursive: true });
|
|
344
|
+
await mkdir(join(cwd, 'artemis-runs'), { recursive: true });
|
|
345
|
+
await mkdir(join(cwd, 'artemis-output'), { recursive: true });
|
|
346
|
+
spinner.succeed('Created project structure');
|
|
276
347
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
348
|
+
// Step 2: Write config file
|
|
349
|
+
const configPath = join(cwd, 'artemis.config.yaml');
|
|
350
|
+
const configExists = existsSync(configPath);
|
|
351
|
+
|
|
352
|
+
if (configExists && !options.force) {
|
|
353
|
+
spinner.info('Config file already exists (use --force to overwrite)');
|
|
354
|
+
} else {
|
|
355
|
+
spinner.start('Writing configuration...');
|
|
356
|
+
await writeFile(configPath, configContent);
|
|
357
|
+
spinner.succeed(
|
|
358
|
+
configExists ? 'Overwrote artemis.config.yaml' : 'Created artemis.config.yaml'
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Step 3: Write example scenario (if requested)
|
|
363
|
+
if (createExample) {
|
|
364
|
+
const scenarioPath = join(cwd, 'scenarios', 'example.yaml');
|
|
365
|
+
const scenarioExists = existsSync(scenarioPath);
|
|
366
|
+
|
|
367
|
+
if (scenarioExists && !options.force) {
|
|
368
|
+
spinner.info('Example scenario already exists (use --force to overwrite)');
|
|
369
|
+
} else {
|
|
370
|
+
spinner.start('Creating example scenario...');
|
|
371
|
+
await writeFile(scenarioPath, DEFAULT_SCENARIO);
|
|
372
|
+
spinner.succeed(
|
|
373
|
+
scenarioExists
|
|
374
|
+
? 'Overwrote scenarios/example.yaml'
|
|
375
|
+
: 'Created scenarios/example.yaml'
|
|
289
376
|
);
|
|
290
377
|
}
|
|
291
|
-
} else if (skipped.length > 0) {
|
|
292
|
-
spinner.info('All environment variables already exist in .env');
|
|
293
|
-
} else {
|
|
294
|
-
spinner.succeed('Created .env with environment variables');
|
|
295
378
|
}
|
|
296
|
-
}
|
|
297
379
|
|
|
298
|
-
|
|
299
|
-
|
|
380
|
+
// Step 4: Update .env file
|
|
381
|
+
if (!options.skipEnv) {
|
|
382
|
+
spinner.start('Updating .env file...');
|
|
383
|
+
const { added, skipped } = await appendEnvKeys(cwd);
|
|
384
|
+
|
|
385
|
+
if (added.length > 0) {
|
|
386
|
+
spinner.succeed(`Added ${added.length} environment variable(s) to .env`);
|
|
387
|
+
if (skipped.length > 0) {
|
|
388
|
+
console.log(
|
|
389
|
+
chalk.dim(
|
|
390
|
+
` ${icons.info} Skipped ${skipped.length} existing key(s): ${skipped.join(', ')}`
|
|
391
|
+
)
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
} else if (skipped.length > 0) {
|
|
395
|
+
spinner.info('All environment variables already exist in .env');
|
|
396
|
+
} else {
|
|
397
|
+
spinner.succeed('Created .env with environment variables');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
300
400
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
401
|
+
// Show success panel
|
|
402
|
+
console.log(renderSuccessPanel());
|
|
403
|
+
|
|
404
|
+
// Non-blocking update check (fire and forget)
|
|
405
|
+
checkForUpdateAndNotify();
|
|
406
|
+
} catch (error) {
|
|
407
|
+
spinner.fail('Error');
|
|
408
|
+
console.error(chalk.red(`\n${icons.failed} ${(error as Error).message}`));
|
|
409
|
+
process.exit(1);
|
|
410
|
+
}
|
|
307
411
|
}
|
|
308
|
-
|
|
412
|
+
);
|
|
309
413
|
|
|
310
414
|
return cmd;
|
|
311
415
|
}
|