vent-hq 0.7.5 → 0.7.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stephan Gazarov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.mjs CHANGED
@@ -453,7 +453,15 @@ function printEvent(event, jsonMode) {
453
453
  return;
454
454
  }
455
455
  if (!isTTY) {
456
- process.stdout.write(JSON.stringify(event) + "\n");
456
+ const meta2 = event.metadata_json ?? {};
457
+ if (event.event_type === "test_completed") {
458
+ const name = meta2.test_name ?? "test";
459
+ const status = meta2.status ?? "unknown";
460
+ const durationMs = meta2.duration_ms;
461
+ const duration = durationMs != null ? (durationMs / 1e3).toFixed(1) + "s" : "";
462
+ process.stderr.write(` ${status === "completed" || status === "pass" ? "\u2714" : "\u2718"} ${name} ${duration}
463
+ `);
464
+ }
457
465
  return;
458
466
  }
459
467
  const meta = event.metadata_json ?? {};
@@ -512,58 +520,41 @@ function printRunComplete(meta) {
512
520
  }
513
521
  }
514
522
  function printSummary(testResults, runComplete, runId, jsonMode) {
515
- if (jsonMode) {
516
- const failedTests = testResults.filter((e) => {
517
- const meta = e.metadata_json ?? {};
518
- const r = meta.result;
519
- const status = r?.status ?? meta.status;
520
- return status && status !== "completed" && status !== "pass";
521
- }).map((e) => {
522
- const meta = e.metadata_json ?? {};
523
- const r = meta.result;
524
- return {
525
- name: r?.name ?? meta.test_name ?? "test",
526
- status: r?.status ?? meta.status,
527
- duration_ms: r?.duration_ms ?? meta.duration_ms,
528
- intent_accuracy: r?.behavior?.intent_accuracy?.score,
529
- p50_ttfw_ms: r?.latency?.p50_ttfw_ms
530
- };
531
- });
532
- const agg = runComplete.aggregate;
533
- const counts = agg?.red_team_tests ?? agg?.conversation_tests;
534
- process.stdout.write(
535
- JSON.stringify({
536
- event_type: "summary",
537
- data: {
538
- run_id: runId,
539
- status: runComplete.status,
540
- total: runComplete.total_tests ?? counts?.total,
541
- passed: runComplete.passed_tests ?? counts?.passed,
542
- failed: runComplete.failed_tests ?? counts?.failed,
543
- failed_tests: failedTests,
544
- check: `npx vent-hq status ${runId} --json`
545
- }
546
- }) + "\n"
547
- );
548
- return;
549
- }
550
- const failures = testResults.filter((e) => {
523
+ const allTests = testResults.map((e) => {
551
524
  const meta = e.metadata_json ?? {};
552
525
  const r = meta.result;
553
- const status = r?.status ?? meta.status;
554
- return status && status !== "completed" && status !== "pass";
526
+ return {
527
+ name: r?.name ?? meta.test_name ?? "test",
528
+ status: r?.status ?? meta.status,
529
+ duration_ms: r?.duration_ms ?? meta.duration_ms,
530
+ intent_accuracy: r?.behavior?.intent_accuracy?.score,
531
+ p50_ttfw_ms: r?.latency?.p50_ttfw_ms,
532
+ error: r?.error ?? void 0
533
+ };
555
534
  });
535
+ const agg = runComplete.aggregate;
536
+ const counts = agg?.red_team_tests ?? agg?.conversation_tests;
537
+ const summaryData = {
538
+ run_id: runId,
539
+ status: runComplete.status,
540
+ total: runComplete.total_tests ?? counts?.total,
541
+ passed: runComplete.passed_tests ?? counts?.passed,
542
+ failed: runComplete.failed_tests ?? counts?.failed,
543
+ tests: allTests,
544
+ check: `npx vent-hq status ${runId} --json`
545
+ };
546
+ if (jsonMode || !isTTY) {
547
+ process.stdout.write(JSON.stringify(summaryData) + "\n");
548
+ return;
549
+ }
550
+ const failures = allTests.filter((t2) => t2.status && t2.status !== "completed" && t2.status !== "pass");
556
551
  if (failures.length > 0) {
557
552
  process.stdout.write("\n" + bold("Failed tests:") + "\n");
558
- for (const event of failures) {
559
- const meta = event.metadata_json ?? {};
560
- const r = meta.result;
561
- const name = r?.name ?? meta.test_name ?? "test";
562
- const durationMs = r?.duration_ms ?? meta.duration_ms;
563
- const duration = durationMs != null ? (durationMs / 1e3).toFixed(1) + "s" : "\u2014";
564
- const parts = [red("\u2718"), bold(name), dim(duration)];
565
- if (r?.behavior?.intent_accuracy) {
566
- parts.push(`intent: ${r.behavior.intent_accuracy.score}`);
553
+ for (const t2 of failures) {
554
+ const duration = t2.duration_ms != null ? (t2.duration_ms / 1e3).toFixed(1) + "s" : "\u2014";
555
+ const parts = [red("\u2718"), bold(t2.name), dim(duration)];
556
+ if (t2.intent_accuracy != null) {
557
+ parts.push(`intent: ${t2.intent_accuracy}`);
567
558
  }
568
559
  process.stdout.write(" " + parts.join(" ") + "\n");
569
560
  }
@@ -588,6 +579,7 @@ function printSuccess(message) {
588
579
  }
589
580
 
590
581
  // src/commands/run.ts
582
+ var isTTY2 = process.stdout.isTTY;
591
583
  function log2(msg) {
592
584
  const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
593
585
  process.stderr.write(`[vent ${ts}] ${msg}
@@ -760,8 +752,15 @@ async function runCommand(args) {
760
752
  }
761
753
  }
762
754
  log2(`summary: testResults=${testResults.length} runComplete=${!!runCompleteData} exitCode=${exitCode}`);
763
- if (runCompleteData && testResults.length > 0) {
755
+ if (runCompleteData) {
764
756
  printSummary(testResults, runCompleteData, run_id, args.json);
757
+ } else if (!isTTY2) {
758
+ process.stdout.write(JSON.stringify({
759
+ run_id,
760
+ status: exitCode === 0 ? "pass" : "error",
761
+ error: "Stream ended without run_complete event",
762
+ check: `npx vent-hq status ${run_id} --json`
763
+ }) + "\n");
765
764
  }
766
765
  log2(`exiting with code ${exitCode}`);
767
766
  return exitCode;
@@ -5371,11 +5370,11 @@ async function statusCommand(args) {
5371
5370
  if (status2 === "running" || status2 === "queued") {
5372
5371
  printInfo(`Run ${args.runId}: ${status2} (${testCount} tests completed so far)`);
5373
5372
  } else {
5374
- const isTTY2 = process.stdout.isTTY;
5375
- const bold2 = (s) => isTTY2 ? `\x1B[1m${s}\x1B[0m` : s;
5376
- const dim2 = (s) => isTTY2 ? `\x1B[2m${s}\x1B[0m` : s;
5377
- const green2 = (s) => isTTY2 ? `\x1B[32m${s}\x1B[0m` : s;
5378
- const red2 = (s) => isTTY2 ? `\x1B[31m${s}\x1B[0m` : s;
5373
+ const isTTY3 = process.stdout.isTTY;
5374
+ const bold2 = (s) => isTTY3 ? `\x1B[1m${s}\x1B[0m` : s;
5375
+ const dim2 = (s) => isTTY3 ? `\x1B[2m${s}\x1B[0m` : s;
5376
+ const green2 = (s) => isTTY3 ? `\x1B[32m${s}\x1B[0m` : s;
5377
+ const red2 = (s) => isTTY3 ? `\x1B[31m${s}\x1B[0m` : s;
5379
5378
  if (status2 === "pass") {
5380
5379
  process.stdout.write(green2(bold2("Run passed")) + "\n");
5381
5380
  } else {
@@ -6814,7 +6813,7 @@ async function main() {
6814
6813
  return 0;
6815
6814
  }
6816
6815
  if (command === "--version" || command === "-v") {
6817
- const pkg = await import("./package-HCBRPLMU.mjs");
6816
+ const pkg = await import("./package-GMLASC6S.mjs");
6818
6817
  console.log(`vent-hq ${pkg.default.version}`);
6819
6818
  return 0;
6820
6819
  }
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-U4M3XDTH.mjs";
3
+
4
+ // package.json
5
+ var package_default = {
6
+ name: "vent-hq",
7
+ version: "0.7.6",
8
+ type: "module",
9
+ description: "Vent CLI \u2014 CI/CD for voice AI agents",
10
+ bin: {
11
+ "vent-hq": "dist/index.mjs"
12
+ },
13
+ files: [
14
+ "dist"
15
+ ],
16
+ scripts: {
17
+ build: "node scripts/bundle.mjs",
18
+ clean: "rm -rf dist"
19
+ },
20
+ keywords: [
21
+ "vent",
22
+ "cli",
23
+ "voice",
24
+ "agent",
25
+ "testing",
26
+ "ci-cd"
27
+ ],
28
+ license: "MIT",
29
+ publishConfig: {
30
+ access: "public"
31
+ },
32
+ repository: {
33
+ type: "git",
34
+ url: "https://github.com/vent-hq/vent",
35
+ directory: "packages/cli"
36
+ },
37
+ homepage: "https://ventmcp.dev",
38
+ dependencies: {
39
+ "@clack/prompts": "^1.1.0",
40
+ ws: "^8.18.0"
41
+ },
42
+ devDependencies: {
43
+ "@types/ws": "^8.5.0",
44
+ "@vent/relay-client": "workspace:*",
45
+ "@vent/shared": "workspace:*",
46
+ esbuild: "^0.24.0"
47
+ }
48
+ };
49
+ export {
50
+ package_default as default
51
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vent-hq",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "type": "module",
5
5
  "description": "Vent CLI — CI/CD for voice AI agents",
6
6
  "bin": {
@@ -9,10 +9,6 @@
9
9
  "files": [
10
10
  "dist"
11
11
  ],
12
- "scripts": {
13
- "build": "node scripts/bundle.mjs",
14
- "clean": "rm -rf dist"
15
- },
16
12
  "keywords": [
17
13
  "vent",
18
14
  "cli",
@@ -37,8 +33,12 @@
37
33
  },
38
34
  "devDependencies": {
39
35
  "@types/ws": "^8.5.0",
40
- "@vent/relay-client": "workspace:*",
41
- "@vent/shared": "workspace:*",
42
- "esbuild": "^0.24.0"
36
+ "esbuild": "^0.24.0",
37
+ "@vent/relay-client": "0.1.0",
38
+ "@vent/shared": "0.0.1"
39
+ },
40
+ "scripts": {
41
+ "build": "node scripts/bundle.mjs",
42
+ "clean": "rm -rf dist"
43
43
  }
44
- }
44
+ }