clayton-forge 0.1.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.
@@ -0,0 +1,2 @@
1
+ export declare function commandNew(targetDir?: string): Promise<void>;
2
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.commandNew = commandNew;
40
+ const inquirer_1 = __importDefault(require("inquirer"));
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ const ora_1 = __importDefault(require("ora"));
45
+ // ─────────────────────────────────────────────
46
+ // Helpers de display
47
+ // ─────────────────────────────────────────────
48
+ function header() {
49
+ console.log("");
50
+ console.log(chalk_1.default.bold.white(" ╔═══════════════════════════════════╗"));
51
+ console.log(chalk_1.default.bold.white(" ║") + chalk_1.default.bold.cyan(" CLAYTON FORGE — new ") + chalk_1.default.bold.white("║"));
52
+ console.log(chalk_1.default.bold.white(" ╚═══════════════════════════════════╝"));
53
+ console.log("");
54
+ console.log(chalk_1.default.gray(" Let's create your agent. Answer a few questions."));
55
+ console.log(chalk_1.default.gray(" Press Ctrl+C at any time to cancel.\n"));
56
+ }
57
+ // ─────────────────────────────────────────────
58
+ // Wizard
59
+ // ─────────────────────────────────────────────
60
+ async function commandNew(targetDir) {
61
+ header();
62
+ const answers = await inquirer_1.default.prompt([
63
+ {
64
+ type: "input",
65
+ name: "name",
66
+ message: chalk_1.default.white("Agent name") + chalk_1.default.gray(" (kebab-case, e.g. invoice-classifier):"),
67
+ validate: (v) => /^[a-z][a-z0-9-]*$/.test(v) || "Use lowercase letters, numbers, and hyphens only",
68
+ },
69
+ {
70
+ type: "input",
71
+ name: "description",
72
+ message: chalk_1.default.white("What does this agent do?"),
73
+ validate: (v) => v.trim().length > 5 || "Please write a short description",
74
+ },
75
+ {
76
+ type: "list",
77
+ name: "type",
78
+ message: chalk_1.default.white("Agent type:"),
79
+ choices: [
80
+ { name: "reactive — receives input → processes → responds", value: "reactive" },
81
+ { name: "proactive — acts on triggers without waiting for input", value: "proactive" },
82
+ { name: "pipeline — sequential steps, each feeding the next", value: "pipeline" },
83
+ { name: "orchestrator— coordinates other agents", value: "orchestrator" },
84
+ { name: "worker — executed by an orchestrator", value: "worker" },
85
+ ],
86
+ },
87
+ {
88
+ type: "list",
89
+ name: "llm_provider",
90
+ message: chalk_1.default.white("LLM provider:"),
91
+ choices: [
92
+ { name: "anthropic (Claude — requires ANTHROPIC_API_KEY)", value: "anthropic" },
93
+ { name: "openai (GPT — requires OPENAI_API_KEY)", value: "openai" },
94
+ { name: "ollama (local — requires Ollama running)", value: "ollama" },
95
+ { name: "lmstudio (local — requires LM Studio running)", value: "lmstudio" },
96
+ { name: "openai-compatible (any OpenAI-compatible API)", value: "openai-compatible" },
97
+ { name: "none (rule-based, no LLM)", value: "none" },
98
+ ],
99
+ },
100
+ {
101
+ type: "input",
102
+ name: "llm_model",
103
+ message: chalk_1.default.white("Model name:"),
104
+ when: (a) => a.llm_provider !== "none",
105
+ default: (a) => {
106
+ const defaults = {
107
+ anthropic: "claude-sonnet-4-6",
108
+ openai: "gpt-4o-mini",
109
+ ollama: "llama3",
110
+ lmstudio: "local-model",
111
+ "openai-compatible": "default",
112
+ };
113
+ return defaults[a.llm_provider] ?? "";
114
+ },
115
+ },
116
+ {
117
+ type: "list",
118
+ name: "output_format",
119
+ message: chalk_1.default.white("Output format:"),
120
+ choices: [
121
+ { name: "text — plain text response", value: "text" },
122
+ { name: "json — structured JSON (add output schema)", value: "json" },
123
+ { name: "markdown — formatted markdown", value: "markdown" },
124
+ ],
125
+ },
126
+ {
127
+ type: "list",
128
+ name: "trust_level",
129
+ message: chalk_1.default.white("Trust level:"),
130
+ choices: [
131
+ { name: "0 — sandboxed (no external access)", value: 0 },
132
+ { name: "1 — read-only (reads data, no writes)", value: 1 },
133
+ { name: "2 — write (reads and writes)", value: 2 },
134
+ { name: "3 — admin (full control)", value: 3 },
135
+ ],
136
+ },
137
+ ]);
138
+ // Destino
139
+ const projectName = answers.name;
140
+ const dest = targetDir ? path.resolve(targetDir, projectName) : path.resolve(process.cwd(), projectName);
141
+ // Verificar se pasta já existe
142
+ if (fs.existsSync(dest)) {
143
+ console.log(chalk_1.default.red(`\n✗ Directory already exists: ${dest}`));
144
+ process.exit(1);
145
+ }
146
+ const spinner = (0, ora_1.default)("Creating your agent...").start();
147
+ try {
148
+ // Criar pasta
149
+ fs.mkdirSync(dest, { recursive: true });
150
+ // Gerar agent.yaml
151
+ const apiKeyVar = getApiKeyVar(answers.llm_provider);
152
+ const agentYaml = buildAgentYaml(answers, apiKeyVar);
153
+ fs.writeFileSync(path.join(dest, "agent.yaml"), agentYaml);
154
+ // Gerar agent.test.yaml
155
+ const testYaml = buildTestYaml(answers.name);
156
+ fs.writeFileSync(path.join(dest, "agent.test.yaml"), testYaml);
157
+ // Gerar README.md
158
+ const readme = buildReadme(answers);
159
+ fs.writeFileSync(path.join(dest, "README.md"), readme);
160
+ // Gerar .env.example
161
+ if (apiKeyVar) {
162
+ fs.writeFileSync(path.join(dest, ".env.example"), `${apiKeyVar}=your-api-key-here\n`);
163
+ }
164
+ spinner.succeed(chalk_1.default.green("Agent created!"));
165
+ // Summary
166
+ console.log("");
167
+ console.log(chalk_1.default.bold(" 📁 " + dest));
168
+ console.log(chalk_1.default.gray(" ├── agent.yaml"));
169
+ console.log(chalk_1.default.gray(" ├── agent.test.yaml"));
170
+ console.log(chalk_1.default.gray(" ├── README.md"));
171
+ if (apiKeyVar)
172
+ console.log(chalk_1.default.gray(" └── .env.example"));
173
+ console.log("");
174
+ console.log(chalk_1.default.bold.cyan(" Next steps:"));
175
+ console.log(chalk_1.default.white(` $ cd ${projectName}`));
176
+ if (apiKeyVar)
177
+ console.log(chalk_1.default.white(` $ cp .env.example .env # add your API key`));
178
+ console.log(chalk_1.default.white(` $ cforge run # execute the agent`));
179
+ console.log(chalk_1.default.white(` $ cforge test # run tests`));
180
+ console.log("");
181
+ }
182
+ catch (err) {
183
+ spinner.fail("Failed to create agent");
184
+ console.error(err);
185
+ process.exit(1);
186
+ }
187
+ }
188
+ // ─────────────────────────────────────────────
189
+ // Builders
190
+ // ─────────────────────────────────────────────
191
+ function getApiKeyVar(provider) {
192
+ const map = {
193
+ anthropic: "ANTHROPIC_API_KEY",
194
+ openai: "OPENAI_API_KEY",
195
+ };
196
+ return map[provider] ?? null;
197
+ }
198
+ function buildAgentYaml(answers, apiKeyVar) {
199
+ const lines = [
200
+ `name: "${answers.name}"`,
201
+ `version: "1.0.0"`,
202
+ `description: "${answers.description}"`,
203
+ `type: ${answers.type}`,
204
+ `trust_level: ${answers.trust_level}`,
205
+ ``,
206
+ `llm:`,
207
+ ` provider: ${answers.llm_provider}`,
208
+ ];
209
+ if (answers.llm_provider !== "none") {
210
+ lines.push(` model: ${answers.llm_model}`);
211
+ if (apiKeyVar) {
212
+ lines.push(` api_key: "\${${apiKeyVar}}"`);
213
+ }
214
+ lines.push(` temperature: 0.1`);
215
+ lines.push(` max_tokens: 1000`);
216
+ }
217
+ lines.push(``);
218
+ lines.push(`prompt:`);
219
+ lines.push(` system: |`);
220
+ lines.push(` You are ${answers.description}.`);
221
+ lines.push(` Be concise, accurate, and helpful.`);
222
+ lines.push(` user_template: "{{input}}"`);
223
+ lines.push(` variables:`);
224
+ lines.push(` - name: input`);
225
+ lines.push(` required: true`);
226
+ lines.push(` description: "The user's input"`);
227
+ lines.push(``);
228
+ lines.push(`output:`);
229
+ lines.push(` format: ${answers.output_format}`);
230
+ lines.push(``);
231
+ lines.push(`tests:`);
232
+ lines.push(` - file: agent.test.yaml`);
233
+ lines.push(``);
234
+ return lines.join("\n");
235
+ }
236
+ function buildTestYaml(agentName) {
237
+ return [
238
+ `agent: "${agentName}"`,
239
+ ``,
240
+ `cases:`,
241
+ ` - name: "basic test"`,
242
+ ` input:`,
243
+ ` input: "Hello, world!"`,
244
+ ` expected_contains:`,
245
+ ` - "Hello" # adjust to match your agent's expected output`,
246
+ ` timeout_ms: 30000`,
247
+ ``,
248
+ ].join("\n");
249
+ }
250
+ function buildReadme(answers) {
251
+ return [
252
+ `# ${answers.name}`,
253
+ ``,
254
+ `> ${answers.description}`,
255
+ ``,
256
+ `## Overview`,
257
+ ``,
258
+ `| Field | Value |`,
259
+ `|-------|-------|`,
260
+ `| **Type** | ${answers.type} |`,
261
+ `| **LLM** | ${answers.llm_provider}${answers.llm_model ? ` / ${answers.llm_model}` : ""} |`,
262
+ `| **Output** | ${answers.output_format} |`,
263
+ `| **Trust Level** | ${answers.trust_level} |`,
264
+ ``,
265
+ `## Usage`,
266
+ ``,
267
+ `\`\`\`bash`,
268
+ `cforge run # execute the agent`,
269
+ `cforge test # run test suite`,
270
+ `\`\`\``,
271
+ ``,
272
+ `## Configuration`,
273
+ ``,
274
+ `Edit \`agent.yaml\` to customize the agent's behavior.`,
275
+ ``,
276
+ `## Tests`,
277
+ ``,
278
+ `Edit \`agent.test.yaml\` to add test cases.`,
279
+ ``,
280
+ `---`,
281
+ ``,
282
+ `Built with [Clayton Forge](https://github.com/devclaytonn10/clayton-forge)`,
283
+ ``,
284
+ ].join("\n");
285
+ }
286
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1,2 @@
1
+ export declare function commandRun(agentDir?: string, inputArg?: string): Promise<void>;
2
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.commandRun = commandRun;
40
+ const readline = __importStar(require("readline"));
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const ora_1 = __importDefault(require("ora"));
43
+ // ─────────────────────────────────────────────
44
+ // cforge run [agent-dir]
45
+ // ─────────────────────────────────────────────
46
+ async function commandRun(agentDir, inputArg) {
47
+ const { parseAgentFile, findAgentFile, executeAgent } = await Promise.resolve().then(() => __importStar(require("@clayton-forge/core")));
48
+ // 1. Find agent.yaml
49
+ const searchDir = agentDir ? require("path").resolve(agentDir) : process.cwd();
50
+ const agentPath = require("fs").existsSync(require("path").join(searchDir, "agent.yaml"))
51
+ ? require("path").join(searchDir, "agent.yaml")
52
+ : findAgentFile(searchDir);
53
+ if (!agentPath) {
54
+ console.error(chalk_1.default.red("✗ No agent.yaml found. Run this command inside an agent directory."));
55
+ process.exit(1);
56
+ }
57
+ // 2. Parse
58
+ let agent;
59
+ try {
60
+ agent = parseAgentFile(agentPath);
61
+ }
62
+ catch (err) {
63
+ console.error(chalk_1.default.red("✗ Invalid agent.yaml:"), err instanceof Error ? err.message : err);
64
+ process.exit(1);
65
+ }
66
+ console.log("");
67
+ console.log(chalk_1.default.bold.cyan(` ▶ ${agent.name}`) + chalk_1.default.gray(` v${agent.version}`));
68
+ console.log(chalk_1.default.gray(` ${agent.description ?? ""}`));
69
+ console.log(chalk_1.default.gray(` Provider: ${agent.llm.provider}${agent.llm.model ? ` / ${agent.llm.model}` : ""}`));
70
+ console.log("");
71
+ // 3. Collect input
72
+ const requiredVars = agent.prompt.variables.filter((v) => v.required);
73
+ const variables = {};
74
+ if (inputArg && requiredVars.length <= 1) {
75
+ // Se só tem uma variável obrigatória, usa o argumento direto
76
+ const varName = requiredVars[0]?.name ?? "input";
77
+ variables[varName] = inputArg;
78
+ }
79
+ else {
80
+ // Interactive input
81
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
82
+ const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
83
+ for (const variable of agent.prompt.variables) {
84
+ if (variable.required || !variable.default) {
85
+ const defaultHint = variable.default ? chalk_1.default.gray(` (default: ${variable.default})`) : "";
86
+ const descHint = variable.description ? chalk_1.default.gray(` — ${variable.description}`) : "";
87
+ const value = await question(` ${chalk_1.default.white(variable.name)}${descHint}${defaultHint}: `);
88
+ variables[variable.name] = value || variable.default || "";
89
+ }
90
+ }
91
+ rl.close();
92
+ }
93
+ console.log("");
94
+ // 4. Execute
95
+ const spinner = (0, ora_1.default)("Running agent...").start();
96
+ const result = await executeAgent(agent, { variables });
97
+ if (result.success) {
98
+ spinner.succeed(chalk_1.default.green(`Done`) + chalk_1.default.gray(` (${result.duration_ms}ms)`));
99
+ console.log("");
100
+ console.log(chalk_1.default.bold(" Output:"));
101
+ console.log("");
102
+ // Format output based on type
103
+ const lines = result.output.split("\n");
104
+ for (const line of lines) {
105
+ console.log(" " + line);
106
+ }
107
+ if (result.llm_response?.usage) {
108
+ const { input_tokens, output_tokens } = result.llm_response.usage;
109
+ console.log("");
110
+ console.log(chalk_1.default.gray(` Tokens: ${input_tokens ?? "?"} in / ${output_tokens ?? "?"} out`));
111
+ }
112
+ }
113
+ else {
114
+ spinner.fail(chalk_1.default.red("Execution failed"));
115
+ console.log("");
116
+ console.error(chalk_1.default.red(" Error:"), result.error);
117
+ process.exit(1);
118
+ }
119
+ console.log("");
120
+ }
121
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1,2 @@
1
+ export declare function commandTest(agentDir?: string): Promise<void>;
2
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.commandTest = commandTest;
40
+ const path = __importStar(require("path"));
41
+ const fs = __importStar(require("fs"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const ora_1 = __importDefault(require("ora"));
44
+ // ─────────────────────────────────────────────
45
+ // cforge test [agent-dir]
46
+ // ─────────────────────────────────────────────
47
+ async function commandTest(agentDir) {
48
+ const { parseAgentFile, parseTestFile, runTestSuite, findAgentFile } = await Promise.resolve().then(() => __importStar(require("@clayton-forge/core")));
49
+ // 1. Find agent.yaml
50
+ const searchDir = agentDir ? path.resolve(agentDir) : process.cwd();
51
+ const agentYamlPath = fs.existsSync(path.join(searchDir, "agent.yaml"))
52
+ ? path.join(searchDir, "agent.yaml")
53
+ : findAgentFile(searchDir);
54
+ if (!agentYamlPath) {
55
+ console.error(chalk_1.default.red("✗ No agent.yaml found."));
56
+ process.exit(1);
57
+ }
58
+ // 2. Parse agent
59
+ let agent;
60
+ try {
61
+ agent = parseAgentFile(agentYamlPath);
62
+ }
63
+ catch (err) {
64
+ console.error(chalk_1.default.red("✗ Invalid agent.yaml:"), err instanceof Error ? err.message : err);
65
+ process.exit(1);
66
+ }
67
+ // 3. Find test files
68
+ const agentDir2 = path.dirname(agentYamlPath);
69
+ const testFiles = (agent.tests ?? []).map((t) => path.resolve(agentDir2, t.file));
70
+ // Fallback: tenta agent.test.yaml se não há tests declarados
71
+ if (testFiles.length === 0) {
72
+ const fallback = path.join(agentDir2, "agent.test.yaml");
73
+ if (fs.existsSync(fallback))
74
+ testFiles.push(fallback);
75
+ }
76
+ if (testFiles.length === 0) {
77
+ console.error(chalk_1.default.red("✗ No test files found. Create agent.test.yaml first."));
78
+ process.exit(1);
79
+ }
80
+ console.log("");
81
+ console.log(chalk_1.default.bold.cyan(` ⚗ Testing: ${agent.name}`) + chalk_1.default.gray(` v${agent.version}`));
82
+ console.log(chalk_1.default.gray(` Provider: ${agent.llm.provider}${agent.llm.model ? ` / ${agent.llm.model}` : ""}`));
83
+ console.log("");
84
+ let totalPassed = 0;
85
+ let totalFailed = 0;
86
+ for (const testFile of testFiles) {
87
+ // 4. Parse test suite
88
+ let suite;
89
+ try {
90
+ suite = parseTestFile(testFile);
91
+ }
92
+ catch (err) {
93
+ console.error(chalk_1.default.red(`✗ Invalid test file ${testFile}:`), err instanceof Error ? err.message : err);
94
+ continue;
95
+ }
96
+ console.log(chalk_1.default.gray(` File: ${path.basename(testFile)}`));
97
+ console.log(chalk_1.default.gray(` Cases: ${suite.cases.length}`));
98
+ console.log("");
99
+ // 5. Run
100
+ const spinner = (0, ora_1.default)("Running tests...").start();
101
+ const summary = await runTestSuite(agent, suite);
102
+ spinner.stop();
103
+ // 6. Display results
104
+ for (const result of summary.results) {
105
+ if (result.passed) {
106
+ console.log(chalk_1.default.green(" ✓ PASS") +
107
+ chalk_1.default.white(` ${result.name}`) +
108
+ chalk_1.default.gray(` (${result.duration_ms}ms)`));
109
+ }
110
+ else {
111
+ console.log(chalk_1.default.red(" ✗ FAIL") +
112
+ chalk_1.default.white(` ${result.name}`) +
113
+ chalk_1.default.gray(` (${result.duration_ms}ms)`));
114
+ for (const failure of result.failures) {
115
+ console.log(chalk_1.default.red(" ↳ " + failure));
116
+ }
117
+ if (result.error) {
118
+ console.log(chalk_1.default.red(" Error: " + result.error));
119
+ }
120
+ }
121
+ }
122
+ totalPassed += summary.passed;
123
+ totalFailed += summary.failed;
124
+ console.log("");
125
+ console.log(chalk_1.default.gray(" ─────────────────────────────────────"));
126
+ const statusColor = summary.failed === 0 ? chalk_1.default.green : chalk_1.default.red;
127
+ console.log(statusColor(` ${summary.passed}/${summary.total} passed`) +
128
+ chalk_1.default.gray(` · ${summary.duration_ms}ms`));
129
+ }
130
+ console.log("");
131
+ // Final exit code
132
+ if (totalFailed > 0) {
133
+ process.exit(1);
134
+ }
135
+ }
136
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map