@voicethere/agent 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -23,30 +23,25 @@ npm install
23
23
  npm run build
24
24
  ```
25
25
 
26
- **Voice E2E:** deploy to the VoiceThere platform or run against your organization's internal agent runner. With a local runner checkout, point it at your bundle:
27
-
28
- ```bash
29
- AGENT_BUNDLE_PATH=/path/to/dist/agent.js npm run start
30
- ```
31
-
32
- Open the runner URL in a browser, connect, and speak.
33
-
34
26
  ## Verify locally (sandbox, no WebRTC)
35
27
 
36
- Before deploying to VoiceThere, confirm your bundle loads and responds under the **same Node sandbox** the runner uses:
28
+ Before deploying to VoiceThere, build your bundle and run sandbox checks (same Node `--permission` flags as production):
37
29
 
38
30
  ```bash
39
- npm run verify:local
31
+ npx @voicethere/agent verify
40
32
  ```
41
33
 
42
- | Script | When to use |
43
- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
44
- | `npm run verify:local` | **Default** — `npm run build`, then fork `dist/agent.js` in the sandbox and assert a `speak` reply to `user_speech_final` |
45
- | `npm run verify:local:only` | Re-run smoke after build; optional `AGENT_BUNDLE_PATH=./dist/agent.js` or `--bundle <path>` |
34
+ This runs a short checklist: Node version, bundle build, sandbox load, IPC `session_start`, `user_speech_final` → `speak`, and no `agent_error`. Failures print which check failed and why.
35
+
36
+ | Command | When to use |
37
+ | ------- | ----------- |
38
+ | `npx @voicethere/agent verify` | **Default** — build `agent.ts` → `dist/agent.js`, then run all checks |
39
+ | `npx @voicethere/agent verify --no-build` | Re-run checks on an existing bundle |
40
+ | `npx @voicethere/agent verify --no-build --bundle ./dist/agent.js` | Verify a specific bundle path |
46
41
 
47
- This checks bundle load, IPC, and Node permission flags. It does **not** replace a voice roundtrip — use the VoiceThere agent runner (platform or internal deployment) for mic/WebRTC E2E.
42
+ Optional flags: `--entry` / `-e`, `--outfile` / `-o` (same as `build`).
48
43
 
49
- Harness: [`scripts/sandbox/`](./scripts/sandbox/) (aligned with the agent runner child launcher).
44
+ This does **not** replace a voice roundtrip with mic/WebRTC — deploy to the VoiceThere platform for full E2E.
50
45
 
51
46
  ## API
52
47
 
@@ -214,9 +209,10 @@ Prefer **one esbuild bundle** so production behavior matches `npm run verify:loc
214
209
 
215
210
  **Pre-publish checklist**
216
211
 
217
- 1. `npm run build` — produce `dist/agent.js`
218
- 2. `npm run verify:local` sandbox + IPC smoke (same flags as production child)
219
- 3. Optional: voice E2E with the VoiceThere agent runner (platform or internal deployment)
212
+ 1. `npx @voicethere/agent verify` — build your bundle and run sandbox checks
213
+ 2. Deploy the bundle to VoiceThere (platform upload or CLI when available)
214
+
215
+ For iterative work: `npx @voicethere/agent build` then `npx @voicethere/agent verify --no-build`.
220
216
 
221
217
  ## Build outputs
222
218
 
@@ -230,11 +226,17 @@ Prefer **one esbuild bundle** so production behavior matches `npm run verify:loc
230
226
  ```bash
231
227
  npm run build # compile SDK + example bundle (repo dev)
232
228
  npm run build:lib # compile SDK only (tsc → dist/)
233
- npx @voicethere/agent build # customer project: bundle agent.ts dist/agent.js
234
- npm run verify:local # sandbox smoke (build + fork bundle)
229
+ npm run verify:local # repo dev: build example + sandbox verify
235
230
  npm run test:ci # typecheck + vitest
236
231
  ```
237
232
 
233
+ Customer project:
234
+
235
+ ```bash
236
+ npx @voicethere/agent build # bundle agent.ts → dist/agent.js
237
+ npx @voicethere/agent verify # build + sandbox checks
238
+ ```
239
+
238
240
  ## Release
239
241
 
240
242
  See [`scripts/RELEASE.md`](./scripts/RELEASE.md) — tag `release/X.Y.Z` triggers npm publish (same workflow pattern as [`node-webrtc-rust`](https://github.com/akirilyuk/node-webrtc-rust)).
package/dist/cli.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Customer-facing CLI — bundle agent source for the VoiceThere sandbox.
3
+ * Customer-facing CLI — bundle and verify voice agents for VoiceThere.
4
4
  *
5
5
  * npx @voicethere/agent build
6
- * npx @voicethere/agent build --entry agent.ts --outfile dist/agent.js
6
+ * npx @voicethere/agent verify
7
7
  */
8
8
  export {};
9
9
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js CHANGED
@@ -1,28 +1,43 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Customer-facing CLI — bundle agent source for the VoiceThere sandbox.
3
+ * Customer-facing CLI — bundle and verify voice agents for VoiceThere.
4
4
  *
5
5
  * npx @voicethere/agent build
6
- * npx @voicethere/agent build --entry agent.ts --outfile dist/agent.js
6
+ * npx @voicethere/agent verify
7
7
  */
8
8
  import { buildAgentBundle } from "./build-bundle.js";
9
- const DEFAULT_ENTRY = "agent.ts";
10
- const DEFAULT_OUTFILE = "dist/agent.js";
9
+ import { DEFAULT_VERIFY_BUNDLE, DEFAULT_VERIFY_ENTRY, } from "./verify/lib.js";
10
+ import { formatVerifyFailure, runAgentVerify, } from "./verify/run-verify.js";
11
+ const DEFAULT_ENTRY = DEFAULT_VERIFY_ENTRY;
12
+ const DEFAULT_OUTFILE = DEFAULT_VERIFY_BUNDLE;
11
13
  function printHelp() {
12
- process.stdout.write(`@voicethere/agent — bundle your voice agent for VoiceThere
14
+ process.stdout.write(`@voicethere/agent — bundle and verify your voice agent
13
15
 
14
16
  Usage:
17
+ npx @voicethere/agent
15
18
  npx @voicethere/agent build [options]
16
- npx @voicethere/agent [options] (build is the default command)
19
+ npx @voicethere/agent verify [options]
17
20
 
18
- Options:
21
+ Commands:
22
+ build Bundle agent source to a single ESM file
23
+ verify Build (optional) and run sandbox checks on the bundle
24
+
25
+ Build options:
19
26
  --entry, -e <path> Agent entry file (default: ${DEFAULT_ENTRY})
20
27
  --outfile, -o <path> Output bundle (default: ${DEFAULT_OUTFILE})
28
+
29
+ Verify options:
30
+ --entry, -e <path> Entry for build step (default: ${DEFAULT_ENTRY})
31
+ --outfile, -o <path> Bundle output path (default: ${DEFAULT_OUTFILE})
32
+ --bundle, -b <path> Bundle to verify (default: ${DEFAULT_OUTFILE})
33
+ --no-build Skip build; verify an existing bundle only
21
34
  --help, -h Show this help
22
35
 
23
- Example:
36
+ Examples:
24
37
  npm install @voicethere/agent
25
38
  npx @voicethere/agent build --entry src/agent.ts --outfile dist/agent.js
39
+ npx @voicethere/agent verify
40
+ npx @voicethere/agent verify --no-build --bundle dist/agent.js
26
41
  `);
27
42
  }
28
43
  function parseBuildArgs(argv) {
@@ -56,15 +71,79 @@ function parseBuildArgs(argv) {
56
71
  }
57
72
  return { entry, outfile };
58
73
  }
74
+ function parseVerifyArgs(argv) {
75
+ let entry = DEFAULT_ENTRY;
76
+ let outfile = DEFAULT_OUTFILE;
77
+ let noBuild = false;
78
+ let bundleArg;
79
+ for (let i = 0; i < argv.length; i += 1) {
80
+ const arg = argv[i];
81
+ if (arg === "--help" || arg === "-h") {
82
+ printHelp();
83
+ process.exit(0);
84
+ }
85
+ if (arg === "--no-build") {
86
+ noBuild = true;
87
+ continue;
88
+ }
89
+ if (arg === "--entry" || arg === "-e") {
90
+ const value = argv[i + 1];
91
+ if (!value) {
92
+ throw new Error(`${arg} requires a path`);
93
+ }
94
+ entry = value;
95
+ i += 1;
96
+ continue;
97
+ }
98
+ if (arg === "--outfile" || arg === "-o") {
99
+ const value = argv[i + 1];
100
+ if (!value) {
101
+ throw new Error(`${arg} requires a path`);
102
+ }
103
+ outfile = value;
104
+ i += 1;
105
+ continue;
106
+ }
107
+ if (arg === "--bundle" || arg === "-b") {
108
+ const value = argv[i + 1];
109
+ if (!value) {
110
+ throw new Error(`${arg} requires a path`);
111
+ }
112
+ bundleArg = value;
113
+ i += 1;
114
+ continue;
115
+ }
116
+ throw new Error(`Unknown option: ${arg}`);
117
+ }
118
+ return {
119
+ entry,
120
+ outfile,
121
+ bundlePath: bundleArg ?? outfile,
122
+ noBuild,
123
+ };
124
+ }
59
125
  async function runBuild(argv) {
60
126
  const { entry, outfile } = parseBuildArgs(argv);
61
127
  await buildAgentBundle({ entry, outfile });
62
128
  process.stdout.write(`Built ${outfile} from ${entry}\n`);
63
129
  }
130
+ async function runVerify(argv) {
131
+ const { entry, outfile, bundlePath, noBuild } = parseVerifyArgs(argv);
132
+ const result = await runAgentVerify({
133
+ entry,
134
+ outfile,
135
+ bundlePath,
136
+ noBuild,
137
+ });
138
+ if (!result.ok) {
139
+ process.stderr.write(`[@voicethere/agent verify] FAIL: ${formatVerifyFailure(result)}\n`);
140
+ process.exit(1);
141
+ }
142
+ }
64
143
  async function main() {
65
144
  const args = process.argv.slice(2);
66
145
  if (args.length === 0) {
67
- await runBuild([]);
146
+ printHelp();
68
147
  return;
69
148
  }
70
149
  if (args[0] === "help" || args[0] === "--help" || args[0] === "-h") {
@@ -75,17 +154,22 @@ async function main() {
75
154
  await runBuild(args.slice(1));
76
155
  return;
77
156
  }
78
- if (args[0]?.startsWith("-")) {
79
- await runBuild(args);
157
+ if (args[0] === "verify") {
158
+ await runVerify(args.slice(1));
80
159
  return;
81
160
  }
161
+ if (args[0]?.startsWith("-")) {
162
+ process.stderr.write("Missing command. Use `build` or `verify` before options.\n\n");
163
+ printHelp();
164
+ process.exit(1);
165
+ }
82
166
  process.stderr.write(`Unknown command: ${args[0]}\n\n`);
83
167
  printHelp();
84
168
  process.exit(1);
85
169
  }
86
170
  main().catch((error) => {
87
171
  const message = error instanceof Error ? error.message : String(error);
88
- process.stderr.write(`agent build failed: ${message}\n`);
172
+ process.stderr.write(`[@voicethere/agent] ${message}\n`);
89
173
  process.exit(1);
90
174
  });
91
175
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Sandboxed child bootstrap — loads customer bundle under Node --permission.
3
+ *
4
+ * Keep in sync with the agent runner `src/child/loader-entry.js`.
5
+ */
6
+
7
+ const bundlePath = process.env.__CHILD_BUNDLE_PATH__;
8
+ if (!bundlePath) {
9
+ process.stderr.write("[child] missing __CHILD_BUNDLE_PATH__\n");
10
+ process.exit(1);
11
+ }
12
+
13
+ function formatArgs(args) {
14
+ return args.map((value) => String(value)).join(" ");
15
+ }
16
+
17
+ console.log = (...args) => {
18
+ process.send?.({ type: "log", level: "info", message: formatArgs(args) });
19
+ };
20
+
21
+ console.info = console.log;
22
+
23
+ console.error = (...args) => {
24
+ process.send?.({ type: "log", level: "error", message: formatArgs(args) });
25
+ };
26
+
27
+ console.warn = (...args) => {
28
+ process.send?.({
29
+ type: "log",
30
+ level: "info",
31
+ message: `[warn] ${formatArgs(args)}`,
32
+ });
33
+ };
34
+
35
+ const { pathToFileURL } = await import("node:url");
36
+
37
+ try {
38
+ await import(pathToFileURL(bundlePath).href);
39
+ } catch (error) {
40
+ const message = error instanceof Error ? error.message : String(error);
41
+ process.send?.({
42
+ type: "agent_error",
43
+ sessionId: "",
44
+ message: `Bundle load failed: ${message}`,
45
+ });
46
+ process.exit(1);
47
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Node --permission flags for the customer child process.
3
+ *
4
+ * Keep in sync with the agent runner `src/child/sandbox.ts`.
5
+ */
6
+ /**
7
+ * Node --permission flags for the customer child: no subprocesses, no fs writes.
8
+ * `fs` read is limited to the loader + bundle directories (no `--allow-child-process`).
9
+ */
10
+ export declare function buildChildExecArgv(options: {
11
+ loaderDir: string;
12
+ bundlePath: string;
13
+ }): string[];
14
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,EAAE,CAUX"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Node --permission flags for the customer child process.
3
+ *
4
+ * Keep in sync with the agent runner `src/child/sandbox.ts`.
5
+ */
6
+ import { dirname, resolve } from "node:path";
7
+ /**
8
+ * Node --permission flags for the customer child: no subprocesses, no fs writes.
9
+ * `fs` read is limited to the loader + bundle directories (no `--allow-child-process`).
10
+ */
11
+ export function buildChildExecArgv(options) {
12
+ const readDirs = new Set([
13
+ resolve(options.loaderDir),
14
+ resolve(dirname(options.bundlePath)),
15
+ ]);
16
+ return [
17
+ "--permission",
18
+ ...[...readDirs].map((dir) => `--allow-fs-read=${dir}`),
19
+ ];
20
+ }
21
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/sandbox/sandbox.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAGlC;IACC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS;QAC/B,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1B,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;KACrC,CAAC,CAAC;IAEH,OAAO;QACL,cAAc;QACd,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,mBAAmB,GAAG,EAAE,CAAC;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Fork a customer agent bundle the same way the agent runner does (IPC + sandbox).
3
+ *
4
+ * Keep behavior aligned with runner `src/child/starter.ts`.
5
+ */
6
+ import { type ChildToParentMessage, type ParentToChildMessage } from "../protocol.js";
7
+ export interface StartSandboxedChildOptions {
8
+ sessionId: string;
9
+ bundlePath: string;
10
+ projectId?: string;
11
+ buildId?: string;
12
+ onStderr?: (message: string) => void;
13
+ }
14
+ export interface SandboxedChild {
15
+ pid: number;
16
+ bundlePath: string;
17
+ send(message: ParentToChildMessage): boolean;
18
+ kill(signal?: NodeJS.Signals): void;
19
+ onMessage(handler: (message: ChildToParentMessage) => void): () => void;
20
+ onExit(handler: (code: number | null, signal: NodeJS.Signals | null) => void): () => void;
21
+ }
22
+ export declare function resolveBundlePath(bundlePath: string): string;
23
+ export declare function startSandboxedChild(options: StartSandboxedChildOptions): SandboxedChild;
24
+ //# sourceMappingURL=start-child.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-child.d.ts","sourceRoot":"","sources":["../../src/sandbox/start-child.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AAMxB,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IACpC,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACxE,MAAM,CACJ,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,KAAK,IAAI,GACpE,MAAM,IAAI,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,0BAA0B,GAClC,cAAc,CAiEhB"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Fork a customer agent bundle the same way the agent runner does (IPC + sandbox).
3
+ *
4
+ * Keep behavior aligned with runner `src/child/starter.ts`.
5
+ */
6
+ import { fork } from "node:child_process";
7
+ import { existsSync } from "node:fs";
8
+ import { dirname, join, resolve } from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { ALLOWED_CHILD_ENV_KEYS, } from "../protocol.js";
11
+ import { buildChildExecArgv } from "./sandbox.js";
12
+ const SANDBOX_DIR = dirname(fileURLToPath(import.meta.url));
13
+ const LOADER_ENTRY = join(SANDBOX_DIR, "loader-entry.js");
14
+ export function resolveBundlePath(bundlePath) {
15
+ const resolved = resolve(bundlePath.trim());
16
+ if (!existsSync(resolved)) {
17
+ throw new Error(`Bundle not found: ${resolved}`);
18
+ }
19
+ return resolved;
20
+ }
21
+ export function startSandboxedChild(options) {
22
+ const bundlePath = resolveBundlePath(options.bundlePath);
23
+ const env = {
24
+ NODE_ENV: "production",
25
+ __CHILD_BUNDLE_PATH__: bundlePath,
26
+ };
27
+ for (const key of ALLOWED_CHILD_ENV_KEYS) {
28
+ if (key === "SESSION_ID")
29
+ env[key] = options.sessionId;
30
+ if (key === "PROJECT_ID" && options.projectId)
31
+ env[key] = options.projectId;
32
+ if (key === "BUILD_ID" && options.buildId)
33
+ env[key] = options.buildId;
34
+ }
35
+ const child = fork(LOADER_ENTRY, [], {
36
+ env,
37
+ stdio: ["ignore", "pipe", "pipe", "ipc"],
38
+ execArgv: buildChildExecArgv({
39
+ loaderDir: SANDBOX_DIR,
40
+ bundlePath,
41
+ }),
42
+ });
43
+ child.stderr?.on("data", (chunk) => {
44
+ const message = String(chunk).trim();
45
+ if (message)
46
+ options.onStderr?.(message);
47
+ });
48
+ const messageHandlers = new Set();
49
+ const exitHandlers = new Set();
50
+ child.on("message", (message) => {
51
+ if (!message || typeof message !== "object")
52
+ return;
53
+ const payload = message;
54
+ for (const handler of messageHandlers) {
55
+ handler(payload);
56
+ }
57
+ });
58
+ child.on("exit", (code, signal) => {
59
+ for (const handler of exitHandlers) {
60
+ handler(code, signal);
61
+ }
62
+ });
63
+ return {
64
+ pid: child.pid ?? -1,
65
+ bundlePath,
66
+ send(message) {
67
+ if (!child.connected)
68
+ return false;
69
+ return child.send(message);
70
+ },
71
+ kill(signal = "SIGTERM") {
72
+ child.kill(signal);
73
+ },
74
+ onMessage(handler) {
75
+ messageHandlers.add(handler);
76
+ return () => messageHandlers.delete(handler);
77
+ },
78
+ onExit(handler) {
79
+ exitHandlers.add(handler);
80
+ return () => exitHandlers.delete(handler);
81
+ },
82
+ };
83
+ }
84
+ //# sourceMappingURL=start-child.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-child.js","sourceRoot":"","sources":["../../src/sandbox/start-child.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAqB,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,sBAAsB,GAGvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;AAqB1D,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,OAAmC;IAEnC,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,GAAG,GAAsB;QAC7B,QAAQ,EAAE,YAAY;QACtB,qBAAqB,EAAE,UAAU;KAClC,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,sBAAsB,EAAE,CAAC;QACzC,IAAI,GAAG,KAAK,YAAY;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QACvD,IAAI,GAAG,KAAK,YAAY,IAAI,OAAO,CAAC,SAAS;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;QAC5E,IAAI,GAAG,KAAK,UAAU,IAAI,OAAO,CAAC,OAAO;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IACxE,CAAC;IAED,MAAM,KAAK,GAAiB,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE;QACjD,GAAG;QACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC;QACxC,QAAQ,EAAE,kBAAkB,CAAC;YAC3B,SAAS,EAAE,WAAW;YACtB,UAAU;SACX,CAAC;KACH,CAAC,CAAC;IAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,OAAO;YAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,IAAI,GAAG,EAA2C,CAAC;IAC3E,MAAM,YAAY,GAAG,IAAI,GAAG,EAEzB,CAAC;IAEJ,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAgB,EAAE,EAAE;QACvC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO;QACpD,MAAM,OAAO,GAAG,OAA+B,CAAC;QAChD,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;YACtC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACpB,UAAU;QACV,IAAI,CAAC,OAA6B;YAChC,IAAI,CAAC,KAAK,CAAC,SAAS;gBAAE,OAAO,KAAK,CAAC;YACnC,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,SAAyB,SAAS;YACrC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;QACD,SAAS,CAAC,OAAO;YACf,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,CAAC,OAAO;YACZ,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ChildToParentMessage } from "../protocol.js";
2
+ export declare const VERIFY_SESSION_ID = "local-verify";
3
+ export declare const DEFAULT_VERIFY_BUNDLE = "dist/agent.js";
4
+ export declare const DEFAULT_VERIFY_ENTRY = "agent.ts";
5
+ export declare function parseBundleArg(argv: string[], env?: NodeJS.ProcessEnv, cwd?: string): string;
6
+ export declare function waitForSpeak(messages: ChildToParentMessage[], sessionId: string, timeoutMs: number): Promise<Extract<ChildToParentMessage, {
7
+ type: "speak";
8
+ }>>;
9
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/verify/lib.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AACrD,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAE/C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAWR;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,oBAAoB,EAAE,EAChC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,CAuB3D"}
@@ -0,0 +1,34 @@
1
+ import { resolve } from "node:path";
2
+ export const VERIFY_SESSION_ID = "local-verify";
3
+ export const DEFAULT_VERIFY_BUNDLE = "dist/agent.js";
4
+ export const DEFAULT_VERIFY_ENTRY = "agent.ts";
5
+ export function parseBundleArg(argv, env = process.env, cwd = process.cwd()) {
6
+ for (let i = 0; i < argv.length; i += 1) {
7
+ const arg = argv[i];
8
+ if ((arg === "--bundle" || arg === "-b") && argv[i + 1]) {
9
+ return resolve(cwd, argv[i + 1]);
10
+ }
11
+ }
12
+ if (env.AGENT_BUNDLE_PATH?.trim()) {
13
+ return resolve(cwd, env.AGENT_BUNDLE_PATH.trim());
14
+ }
15
+ return resolve(cwd, DEFAULT_VERIFY_BUNDLE);
16
+ }
17
+ export function waitForSpeak(messages, sessionId, timeoutMs) {
18
+ return new Promise((resolvePromise, reject) => {
19
+ const started = Date.now();
20
+ const timer = setInterval(() => {
21
+ const speak = messages.find((m) => m.type === "speak" && m.sessionId === sessionId);
22
+ if (speak) {
23
+ clearInterval(timer);
24
+ resolvePromise(speak);
25
+ return;
26
+ }
27
+ if (Date.now() - started >= timeoutMs) {
28
+ clearInterval(timer);
29
+ reject(new Error(`Timed out after ${timeoutMs}ms waiting for child speak IPC`));
30
+ }
31
+ }, 50);
32
+ });
33
+ }
34
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/verify/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAChD,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAC;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;AAE/C,MAAM,UAAU,cAAc,CAC5B,IAAc,EACd,MAAyB,OAAO,CAAC,GAAG,EACpC,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxD,OAAO,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,QAAgC,EAChC,SAAiB,EACjB,SAAiB;IAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CACzB,CAAC,CAAC,EAAyD,EAAE,CAC3D,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAClD,CAAC;YACF,IAAI,KAAK,EAAE,CAAC;gBACV,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrB,cAAc,CAAC,KAAK,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC;gBACtC,aAAa,CAAC,KAAK,CAAC,CAAC;gBACrB,MAAM,CACJ,IAAI,KAAK,CACP,mBAAmB,SAAS,gCAAgC,CAC7D,CACF,CAAC;YACJ,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface VerifyAgentOptions {
2
+ cwd?: string;
3
+ entry?: string;
4
+ outfile?: string;
5
+ bundlePath?: string;
6
+ /** When true, skip the build step and verify an existing bundle only. */
7
+ noBuild?: boolean;
8
+ /** When true, suppress per-check log lines (for tests). */
9
+ quiet?: boolean;
10
+ }
11
+ export interface VerifyCheckResult {
12
+ name: string;
13
+ ok: boolean;
14
+ detail?: string;
15
+ }
16
+ export interface VerifyAgentResult {
17
+ ok: boolean;
18
+ checks: VerifyCheckResult[];
19
+ bundlePath: string;
20
+ }
21
+ export declare function runAgentVerify(options?: VerifyAgentOptions): Promise<VerifyAgentResult>;
22
+ export declare function formatVerifyFailure(result: VerifyAgentResult): string;
23
+ //# sourceMappingURL=run-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-verify.d.ts","sourceRoot":"","sources":["../../src/verify/run-verify.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;CACpB;AAqBD,wBAAsB,cAAc,CAClC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAuL5B;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAQrE"}
@@ -0,0 +1,176 @@
1
+ import { existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { buildAgentBundle } from "../build-bundle.js";
4
+ import { startSandboxedChild } from "../sandbox/start-child.js";
5
+ import { VERIFY_SESSION_ID, parseBundleArg, waitForSpeak, } from "./lib.js";
6
+ const READY_MS = 300;
7
+ const SPEAK_TIMEOUT_MS = 5000;
8
+ const MIN_NODE_MAJOR = 22;
9
+ function delay(ms) {
10
+ return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));
11
+ }
12
+ function logLine(quiet, message) {
13
+ if (!quiet) {
14
+ process.stdout.write(`${message}\n`);
15
+ }
16
+ }
17
+ function failCheck(checks, name, detail) {
18
+ checks.push({ name, ok: false, detail });
19
+ return { ok: false, checks, bundlePath: "" };
20
+ }
21
+ export async function runAgentVerify(options = {}) {
22
+ const cwd = options.cwd ?? process.cwd();
23
+ const checks = [];
24
+ const quiet = options.quiet;
25
+ const entry = options.entry ?? "agent.ts";
26
+ const outfile = options.outfile ?? "dist/agent.js";
27
+ const bundlePath = options.bundlePath ??
28
+ parseBundleArg([], process.env, cwd);
29
+ logLine(quiet, "[@voicethere/agent verify]");
30
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
31
+ if (!Number.isFinite(nodeMajor) || nodeMajor < MIN_NODE_MAJOR) {
32
+ return failCheck(checks, "Node.js version", `Node ${MIN_NODE_MAJOR}+ required (--permission sandbox); found ${process.version}`);
33
+ }
34
+ checks.push({
35
+ name: "Node.js version",
36
+ ok: true,
37
+ detail: process.version,
38
+ });
39
+ logLine(quiet, `✓ Node.js ${process.version}`);
40
+ if (!options.noBuild) {
41
+ try {
42
+ await buildAgentBundle({ cwd, entry, outfile });
43
+ checks.push({
44
+ name: "Build bundle",
45
+ ok: true,
46
+ detail: `${outfile} from ${entry}`,
47
+ });
48
+ logLine(quiet, `✓ Built ${outfile} from ${entry}`);
49
+ }
50
+ catch (error) {
51
+ const detail = error instanceof Error ? error.message : String(error);
52
+ return failCheck(checks, "Build bundle", detail);
53
+ }
54
+ }
55
+ else {
56
+ checks.push({
57
+ name: "Build bundle",
58
+ ok: true,
59
+ detail: "skipped (--no-build)",
60
+ });
61
+ logLine(quiet, "○ Build bundle (skipped)");
62
+ }
63
+ const resolvedBundle = resolve(cwd, bundlePath);
64
+ if (!existsSync(resolvedBundle)) {
65
+ return failCheck(checks, "Bundle present", `Bundle not found: ${resolvedBundle}`);
66
+ }
67
+ checks.push({
68
+ name: "Bundle present",
69
+ ok: true,
70
+ detail: resolvedBundle,
71
+ });
72
+ logLine(quiet, `✓ Bundle present (${resolvedBundle})`);
73
+ const childMessages = [];
74
+ let childError;
75
+ let earlyExitCode;
76
+ let child;
77
+ try {
78
+ child = startSandboxedChild({
79
+ sessionId: VERIFY_SESSION_ID,
80
+ bundlePath: resolvedBundle,
81
+ onStderr: (message) => {
82
+ if (!quiet) {
83
+ process.stderr.write(`[child stderr] ${message}\n`);
84
+ }
85
+ },
86
+ });
87
+ }
88
+ catch (error) {
89
+ const detail = error instanceof Error ? error.message : String(error);
90
+ return failCheck(checks, "Sandbox spawn", detail);
91
+ }
92
+ checks.push({
93
+ name: "Sandbox spawn",
94
+ ok: true,
95
+ detail: `pid ${child.pid}`,
96
+ });
97
+ logLine(quiet, `✓ Sandbox spawn (pid ${child.pid})`);
98
+ child.onMessage((message) => {
99
+ childMessages.push(message);
100
+ if (message.type === "log" && !quiet) {
101
+ process.stdout.write(`[child ${message.level}] ${message.message}\n`);
102
+ }
103
+ if (message.type === "agent_error") {
104
+ childError = message.message;
105
+ }
106
+ if (message.type === "speak" && !quiet) {
107
+ process.stdout.write(`[child speak] ${message.text}\n`);
108
+ }
109
+ });
110
+ const exitPromise = new Promise((resolveExit) => {
111
+ child.onExit((code) => {
112
+ earlyExitCode = code;
113
+ resolveExit(code);
114
+ });
115
+ });
116
+ child.send({
117
+ type: "session_start",
118
+ sessionId: VERIFY_SESSION_ID,
119
+ env: {
120
+ SESSION_ID: VERIFY_SESSION_ID,
121
+ PROJECT_ID: "local",
122
+ BUILD_ID: "verify",
123
+ },
124
+ });
125
+ await delay(READY_MS);
126
+ if (earlyExitCode !== undefined) {
127
+ return failCheck(checks, "Bundle load", `Child exited early with code ${earlyExitCode ?? "null"}`);
128
+ }
129
+ checks.push({ name: "Bundle load", ok: true });
130
+ logLine(quiet, "✓ Bundle load");
131
+ child.send({
132
+ type: "speech_event",
133
+ sessionId: VERIFY_SESSION_ID,
134
+ event: { type: "user_speech_final", text: "hello from verify" },
135
+ });
136
+ try {
137
+ const speak = await waitForSpeak(childMessages, VERIFY_SESSION_ID, SPEAK_TIMEOUT_MS);
138
+ if (!speak.text.trim()) {
139
+ return failCheck(checks, "Speech response", "Child returned empty speak text for user_speech_final");
140
+ }
141
+ checks.push({
142
+ name: "Speech response",
143
+ ok: true,
144
+ detail: speak.text.trim(),
145
+ });
146
+ logLine(quiet, `✓ Speech response (${speak.text.trim()})`);
147
+ }
148
+ catch (error) {
149
+ const detail = error instanceof Error ? error.message : String(error);
150
+ child.kill("SIGTERM");
151
+ await exitPromise;
152
+ return failCheck(checks, "Speech response", detail);
153
+ }
154
+ if (childError) {
155
+ child.kill("SIGTERM");
156
+ await exitPromise;
157
+ return failCheck(checks, "No agent errors", childError);
158
+ }
159
+ checks.push({ name: "No agent errors", ok: true });
160
+ logLine(quiet, "✓ No agent errors");
161
+ child.send({ type: "session_end", sessionId: VERIFY_SESSION_ID });
162
+ child.kill("SIGTERM");
163
+ await exitPromise;
164
+ logLine(quiet, "[@voicethere/agent verify] All checks passed.");
165
+ return { ok: true, checks, bundlePath: resolvedBundle };
166
+ }
167
+ export function formatVerifyFailure(result) {
168
+ const failed = result.checks.filter((check) => !check.ok);
169
+ if (failed.length === 0) {
170
+ return "Verify failed";
171
+ }
172
+ return failed
173
+ .map((check) => `${check.name}: ${check.detail ?? "failed"}`)
174
+ .join("; ");
175
+ }
176
+ //# sourceMappingURL=run-verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-verify.js","sourceRoot":"","sources":["../../src/verify/run-verify.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voicethere/agent",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "VoiceThere customer agent SDK — IPC types and runtime helpers for sandboxed child bundles",
5
5
  "type": "module",
6
6
  "exports": {
@@ -16,14 +16,14 @@
16
16
  "README.md"
17
17
  ],
18
18
  "scripts": {
19
- "build:lib": "tsc -p tsconfig.json",
19
+ "build:lib": "tsc -p tsconfig.json && mkdir -p dist/sandbox && cp src/sandbox/loader-entry.js dist/sandbox/",
20
20
  "build:example": "node dist/cli.js build --entry examples/agent.ts --outfile dist/agent.js",
21
21
  "build": "npm run build:lib && npm run build:example",
22
22
  "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
23
23
  "test": "vitest run",
24
24
  "test:ci": "npm run typecheck && npm run build && npm run test",
25
- "verify:local": "npm run build && tsx scripts/verify-local.ts",
26
- "verify:local:only": "tsx scripts/verify-local.ts",
25
+ "verify:local": "npm run build && node dist/cli.js verify --no-build --bundle dist/agent.js",
26
+ "verify:local:only": "node dist/cli.js verify --no-build --bundle dist/agent.js",
27
27
  "prepublishOnly": "npm run build"
28
28
  },
29
29
  "repository": {
@@ -22,6 +22,10 @@ npx @voicethere/agent build
22
22
  # optional: --entry agent.ts --outfile dist/agent.js
23
23
  ```
24
24
 
25
- **Verify sandbox (no WebRTC):** from the agent repo, `npm run verify:local` after building your bundle.
25
+ **Verify sandbox (no WebRTC):**
26
+
27
+ ```bash
28
+ npx @voicethere/agent verify
29
+ ```
26
30
 
27
31
  **Voice E2E:** host with the VoiceThere agent runner (platform or internal deployment) — set `AGENT_BUNDLE_PATH` to your built `dist/agent.js`.
@@ -8,6 +8,9 @@
8
8
  * npm install @voicethere/agent
9
9
  * npx @voicethere/agent build
10
10
  *
11
+ * Verify (sandbox checks, no WebRTC):
12
+ * npx @voicethere/agent verify
13
+ *
11
14
  * Voice E2E (VoiceThere agent runner — platform or internal deployment):
12
15
  * AGENT_BUNDLE_PATH=./dist/agent.js npm run start
13
16
  */