grok-bot-cli 0.4.2 → 0.5.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/dist/install.mjs CHANGED
@@ -7,7 +7,7 @@ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'nod
7
7
  import { fileURLToPath } from 'node:url';
8
8
 
9
9
  const pluginName = "gbot";
10
- const pluginVersion = "0.4.2";
10
+ const pluginVersion = "0.5.0";
11
11
  const receiptFile = ".agent-bundle-install.json";
12
12
  const receiptFormat = "agent-bundle-install-receipt/2";
13
13
  const legacyReceiptFormat = "agent-bundle-install-receipt/1";
@@ -13424,7 +13424,7 @@ if (process.env.NODE_ENV === 'production') {
13424
13424
 
13425
13425
  // Hosts and the CLI print thrown error text (and stack), and a fetch or proxy failure can echo
13426
13426
  // a credential. Rewrap with a redacted message; keep `name` and own fields such as `reason`,
13427
- // `delivery`, `mode`, and `envelope` so outcome documents still classify the failure.
13427
+ // `delivery`, `mode`, and correlation ids so outcome documents still classify the failure.
13428
13428
  const withRedactedErrors = async (run)=>{
13429
13429
  try {
13430
13430
  return await run();
@@ -13673,7 +13673,9 @@ const inputSchema = zod__rspack_import_3/* .object */.Ikc({
13673
13673
  after,
13674
13674
  limit
13675
13675
  });
13676
- const entries = (0,_gbot_js__rspack_import_2/* .transcriptEntries */.xw)(delta.entries);
13676
+ const entries = (0,_gbot_js__rspack_import_2/* .transcriptEntries */.xw)({
13677
+ entries: delta.entries
13678
+ });
13677
13679
  const summary = delta.gapReset ? `${delta.entryCount} entries; gap reset` : after === undefined ? `${delta.entryCount} entries` : `${delta.entryCount} new`;
13678
13680
  const receipt = {
13679
13681
  cursor: delta.cursor,
@@ -25083,19 +25085,17 @@ class GatewayError extends Error {
25083
25085
  const GATEWAY_TIMEOUT_MS = 30000;
25084
25086
  const GATEWAY_MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
25085
25087
  function backendBase() {
25086
- return (process.env.SAND_BACKEND_URL || process.env.CURSOR_API_BASE_URL || "https://api2.cursor.sh").replace(/\/$/, "");
25088
+ return (process.env.CURSOR_API_BASE_URL || "https://api2.cursor.sh").replace(/\/$/, "");
25087
25089
  }
25088
25090
  function accessTokenFromEnv() {
25089
- return (process.env.CURSOR_ACCESS_TOKEN || process.env.GROK_BOT_ACCESS_TOKEN || process.env.SAND_ACCESS_TOKEN || "").trim();
25091
+ return (process.env.CURSOR_ACCESS_TOKEN || "").trim();
25090
25092
  }
25091
25093
  function gatewayTokenFromEnv() {
25092
- return (process.env.GROK_BOT_GATEWAY_TOKEN || process.env.SAND_HOST_GATEWAY_TOKEN || process.env.SAND_GATEWAY_TOKEN || "").trim();
25094
+ return (process.env.GROK_BOT_GATEWAY_TOKEN || "").trim();
25093
25095
  }
25094
25096
  function gatewayOverride() {
25095
25097
  const token = gatewayTokenFromEnv();
25096
- const explicitUrl = (process.env.GROK_BOT_GATEWAY_URL || process.env.SAND_HOST_GATEWAY_URL || "").trim();
25097
- const localUrl = token ? "http://127.0.0.1:" + (process.env.SAND_HOST_PORT || "1340") : "";
25098
- const url = explicitUrl || localUrl;
25098
+ const url = (process.env.GROK_BOT_GATEWAY_URL || "").trim();
25099
25099
  if (url && token) {
25100
25100
  return {
25101
25101
  gatewayUrl: (0,_url_policy_js__rspack_import_3/* .assertAllowedCredentialUrl */.Re)(url.replace(/\/$/, ""), {
@@ -25415,14 +25415,13 @@ async function removeGroupMember(session, groupRef, memberRef) {
25415
25415
  const next = group.memberIds.filter((id)=>id !== member.id);
25416
25416
  return setGroupMembers(session, group.id, next);
25417
25417
  }
25418
- async function sendPrompt(session, ref, prompt, extra = {}) {
25418
+ async function sendPrompt(session, ref, prompt) {
25419
25419
  const rec = await resolveRef(session, ref);
25420
25420
  const body = {
25421
25421
  agentId: rec.id,
25422
25422
  prompt,
25423
- clientNonce: extra.clientNonce || (0,node_crypto__rspack_import_0.randomUUID)()
25423
+ clientNonce: (0,node_crypto__rspack_import_0.randomUUID)()
25424
25424
  };
25425
- if (extra.replyToId) body.replyToId = extra.replyToId;
25426
25425
  let data;
25427
25426
  try {
25428
25427
  data = await gatewayCall(session, "sendPrompt", body);
@@ -25613,10 +25612,7 @@ function isUuid(value) {
25613
25612
  function defaultCandidateRoots() {
25614
25613
  const home = homedir();
25615
25614
  const env = [
25616
- process.env.GROK_BOT_AGENTS_DIR,
25617
- process.env.SAND_AGENTS_DIR,
25618
- process.env.SAND_DATA_ROOT && join(process.env.SAND_DATA_ROOT, "agents"),
25619
- process.env.SAND_DATA_ROOT && join(process.env.SAND_DATA_ROOT, "agent-data", "agents")
25615
+ process.env.GROK_BOT_AGENTS_DIR
25620
25616
  ].filter(Boolean);
25621
25617
  return [
25622
25618
  ...env,
@@ -25876,7 +25872,6 @@ function removeGroupMember(root, groupRef, memberRef) {
25876
25872
 
25877
25873
  },
25878
25874
  "./src/core/transcript.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
25879
- // Shared by `gbot thread` and the grok-bot plugin's gbot_thread tool.
25880
25875
  /** Coerce anything to a string without throwing (numbers, BigInt, unserializable objects). */ function toSafeText(value) {
25881
25876
  if (typeof value === "string") return value;
25882
25877
  if (value == null) return "";
@@ -25914,15 +25909,12 @@ function entryTextRaw(e) {
25914
25909
  return typeof e.preview === "string" ? e.preview : "";
25915
25910
  }
25916
25911
  function transcriptEntries(payload) {
25917
- if (Array.isArray(payload)) return payload;
25918
25912
  if (!payload || typeof payload !== "object") return [];
25919
- const entries = payload.entries || payload.messages || payload.items;
25920
- return Array.isArray(entries) ? entries : [];
25913
+ return Array.isArray(payload.entries) ? payload.entries : [];
25921
25914
  }
25922
25915
  function sourceEntryId(entry) {
25923
25916
  if (!entry || typeof entry !== "object") return "";
25924
- if (typeof entry.id === "string" && entry.id) return entry.id;
25925
- return typeof entry.messageId === "string" ? entry.messageId : "";
25917
+ return typeof entry.id === "string" ? entry.id : "";
25926
25918
  }
25927
25919
  function lastSourceId(entries, fallback = "") {
25928
25920
  for(let index = entries.length - 1; index >= 0; index -= 1){
@@ -25987,6 +25979,8 @@ __webpack_require__.d(__webpack_exports__, {
25987
25979
  * never *.cursorvm.com, so a CURSOR_ACCESS_TOKEN cannot be pointed at a box host.
25988
25980
  * Local/dev gateways: http(s)://127.0.0.1|localhost|::1 when GROK_BOT_ALLOW_LOCAL_GATEWAY=1.
25989
25981
  * Escape hatch: GROK_BOT_ALLOW_ANY_GATEWAY=1 (unsafe; disables host checks; warns once).
25982
+ * Test mode (GROK_BOT_TEST=1 or NODE_ENV=test): loopback only, for gateway and backend
25983
+ * alike, and the escape hatches are ignored — a test can never reach a live thread.
25990
25984
  */ function truthyEnv(name) {
25991
25985
  const v = (process.env[name] || "").trim().toLowerCase();
25992
25986
  return v === "1" || v === "true" || v === "yes";
@@ -25997,6 +25991,9 @@ function allowAnyGateway() {
25997
25991
  function allowLocalGateway() {
25998
25992
  return truthyEnv("GROK_BOT_ALLOW_LOCAL_GATEWAY");
25999
25993
  }
25994
+ function testMode() {
25995
+ return truthyEnv("GROK_BOT_TEST") || process.env.NODE_ENV === "test";
25996
+ }
26000
25997
  const warned = new Set();
26001
25998
  function warnOnce(key, message) {
26002
25999
  if (warned.has(key)) return;
@@ -26036,6 +26033,12 @@ function isCursorGatewayHostname(hostname) {
26036
26033
  if (parsed.username || parsed.password) {
26037
26034
  throw new Error("Rejected " + label + ": userinfo is not allowed.");
26038
26035
  }
26036
+ if (testMode()) {
26037
+ if (!isLocalHostname(parsed.hostname) || parsed.protocol !== "http:" && parsed.protocol !== "https:") {
26038
+ throw new Error("Rejected " + label + " host \"" + parsed.hostname + "\": test mode (GROK_BOT_TEST / NODE_ENV=test) only allows http(s) loopback gateways.");
26039
+ }
26040
+ return String(rawUrl).replace(/\/$/, "");
26041
+ }
26039
26042
  if (allowAnyGateway()) {
26040
26043
  warnOnce("ALLOW_ANY", "warning: GROK_BOT_ALLOW_ANY_GATEWAY is set; credential host checks are disabled.");
26041
26044
  return String(rawUrl).replace(/\/$/, "");
@@ -26173,7 +26176,7 @@ globalThis.__rspack_rsc_manifest__ ??= Object.freeze({
26173
26176
  });
26174
26177
  if (node_worker_threads__rspack_import_0.parentPort === null) throw new Error('Generated Flight worker requires a parent port.');
26175
26178
  process.stdout.write = process.stderr.write.bind(process.stderr);
26176
- const ARTIFACT_EPOCH = "gbot@0.4.2";
26179
+ const ARTIFACT_EPOCH = "gbot@0.5.0";
26177
26180
  const processLifetime = {
26178
26181
  hits: 0,
26179
26182
  instanceId: crypto.randomUUID(),
@@ -10996,7 +10996,7 @@ if (process.env.NODE_ENV === 'production') {
10996
10996
 
10997
10997
  // Hosts and the CLI print thrown error text (and stack), and a fetch or proxy failure can echo
10998
10998
  // a credential. Rewrap with a redacted message; keep `name` and own fields such as `reason`,
10999
- // `delivery`, `mode`, and `envelope` so outcome documents still classify the failure.
10999
+ // `delivery`, `mode`, and correlation ids so outcome documents still classify the failure.
11000
11000
  const withRedactedErrors = async (run)=>{
11001
11001
  try {
11002
11002
  return await run();
@@ -11245,7 +11245,9 @@ const inputSchema = zod__rspack_import_3/* .object */.Ikc({
11245
11245
  after,
11246
11246
  limit
11247
11247
  });
11248
- const entries = (0,_gbot_js__rspack_import_2/* .transcriptEntries */.xw)(delta.entries);
11248
+ const entries = (0,_gbot_js__rspack_import_2/* .transcriptEntries */.xw)({
11249
+ entries: delta.entries
11250
+ });
11249
11251
  const summary = delta.gapReset ? `${delta.entryCount} entries; gap reset` : after === undefined ? `${delta.entryCount} entries` : `${delta.entryCount} new`;
11250
11252
  const receipt = {
11251
11253
  cursor: delta.cursor,
@@ -106202,7 +106204,7 @@ __webpack_require__.r(__webpack_exports__);
106202
106204
  const route0 = Object.assign({}, Reflect.get(_home_runner_work_grok_bot_cli_grok_bot_cli_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_3, 'default'), _home_runner_work_grok_bot_cli_grok_bot_cli_src_mcp_grok_bot_tools_gbot_send_tsx__rspack_import_3);
106203
106205
 
106204
106206
  const route1 = Object.assign({}, Reflect.get(_home_runner_work_grok_bot_cli_grok_bot_cli_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_4, 'default'), _home_runner_work_grok_bot_cli_grok_bot_cli_src_mcp_grok_bot_tools_gbot_thread_tsx__rspack_import_4);
106205
- const ARTIFACT_EPOCH = "gbot@0.4.2";
106207
+ const ARTIFACT_EPOCH = "gbot@0.5.0";
106206
106208
  const pluginRoot = (0,_agent_bundle_runtime__rspack_import_5/* .resolvePluginRoot */.E7)({
106207
106209
  fallback: (0,node_url__rspack_import_0.fileURLToPath)(new URL('..', import.meta.url)),
106208
106210
  stateAnchor: 'user-data'
@@ -106291,7 +106293,7 @@ const routes = Object.freeze({
106291
106293
  lineage: lineage.registry,
106292
106294
  plugin: {
106293
106295
  "name": "gbot",
106294
- "version": "0.4.2"
106296
+ "version": "0.5.0"
106295
106297
  },
106296
106298
  pluginRoot: pluginRoot.identity,
106297
106299
  routes
@@ -106572,19 +106574,17 @@ class GatewayError extends Error {
106572
106574
  const GATEWAY_TIMEOUT_MS = 30000;
106573
106575
  const GATEWAY_MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
106574
106576
  function backendBase() {
106575
- return (process.env.SAND_BACKEND_URL || process.env.CURSOR_API_BASE_URL || "https://api2.cursor.sh").replace(/\/$/, "");
106577
+ return (process.env.CURSOR_API_BASE_URL || "https://api2.cursor.sh").replace(/\/$/, "");
106576
106578
  }
106577
106579
  function accessTokenFromEnv() {
106578
- return (process.env.CURSOR_ACCESS_TOKEN || process.env.GROK_BOT_ACCESS_TOKEN || process.env.SAND_ACCESS_TOKEN || "").trim();
106580
+ return (process.env.CURSOR_ACCESS_TOKEN || "").trim();
106579
106581
  }
106580
106582
  function gatewayTokenFromEnv() {
106581
- return (process.env.GROK_BOT_GATEWAY_TOKEN || process.env.SAND_HOST_GATEWAY_TOKEN || process.env.SAND_GATEWAY_TOKEN || "").trim();
106583
+ return (process.env.GROK_BOT_GATEWAY_TOKEN || "").trim();
106582
106584
  }
106583
106585
  function gatewayOverride() {
106584
106586
  const token = gatewayTokenFromEnv();
106585
- const explicitUrl = (process.env.GROK_BOT_GATEWAY_URL || process.env.SAND_HOST_GATEWAY_URL || "").trim();
106586
- const localUrl = token ? "http://127.0.0.1:" + (process.env.SAND_HOST_PORT || "1340") : "";
106587
- const url = explicitUrl || localUrl;
106587
+ const url = (process.env.GROK_BOT_GATEWAY_URL || "").trim();
106588
106588
  if (url && token) {
106589
106589
  return {
106590
106590
  gatewayUrl: (0,_url_policy_js__rspack_import_3/* .assertAllowedCredentialUrl */.Re)(url.replace(/\/$/, ""), {
@@ -106904,14 +106904,13 @@ async function removeGroupMember(session, groupRef, memberRef) {
106904
106904
  const next = group.memberIds.filter((id)=>id !== member.id);
106905
106905
  return setGroupMembers(session, group.id, next);
106906
106906
  }
106907
- async function sendPrompt(session, ref, prompt, extra = {}) {
106907
+ async function sendPrompt(session, ref, prompt) {
106908
106908
  const rec = await resolveRef(session, ref);
106909
106909
  const body = {
106910
106910
  agentId: rec.id,
106911
106911
  prompt,
106912
- clientNonce: extra.clientNonce || (0,node_crypto__rspack_import_0.randomUUID)()
106912
+ clientNonce: (0,node_crypto__rspack_import_0.randomUUID)()
106913
106913
  };
106914
- if (extra.replyToId) body.replyToId = extra.replyToId;
106915
106914
  let data;
106916
106915
  try {
106917
106916
  data = await gatewayCall(session, "sendPrompt", body);
@@ -107102,10 +107101,7 @@ function isUuid(value) {
107102
107101
  function defaultCandidateRoots() {
107103
107102
  const home = homedir();
107104
107103
  const env = [
107105
- process.env.GROK_BOT_AGENTS_DIR,
107106
- process.env.SAND_AGENTS_DIR,
107107
- process.env.SAND_DATA_ROOT && join(process.env.SAND_DATA_ROOT, "agents"),
107108
- process.env.SAND_DATA_ROOT && join(process.env.SAND_DATA_ROOT, "agent-data", "agents")
107104
+ process.env.GROK_BOT_AGENTS_DIR
107109
107105
  ].filter(Boolean);
107110
107106
  return [
107111
107107
  ...env,
@@ -107365,7 +107361,6 @@ function removeGroupMember(root, groupRef, memberRef) {
107365
107361
 
107366
107362
  },
107367
107363
  "./src/core/transcript.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
107368
- // Shared by `gbot thread` and the grok-bot plugin's gbot_thread tool.
107369
107364
  /** Coerce anything to a string without throwing (numbers, BigInt, unserializable objects). */ function toSafeText(value) {
107370
107365
  if (typeof value === "string") return value;
107371
107366
  if (value == null) return "";
@@ -107403,15 +107398,12 @@ function entryTextRaw(e) {
107403
107398
  return typeof e.preview === "string" ? e.preview : "";
107404
107399
  }
107405
107400
  function transcriptEntries(payload) {
107406
- if (Array.isArray(payload)) return payload;
107407
107401
  if (!payload || typeof payload !== "object") return [];
107408
- const entries = payload.entries || payload.messages || payload.items;
107409
- return Array.isArray(entries) ? entries : [];
107402
+ return Array.isArray(payload.entries) ? payload.entries : [];
107410
107403
  }
107411
107404
  function sourceEntryId(entry) {
107412
107405
  if (!entry || typeof entry !== "object") return "";
107413
- if (typeof entry.id === "string" && entry.id) return entry.id;
107414
- return typeof entry.messageId === "string" ? entry.messageId : "";
107406
+ return typeof entry.id === "string" ? entry.id : "";
107415
107407
  }
107416
107408
  function lastSourceId(entries, fallback = "") {
107417
107409
  for(let index = entries.length - 1; index >= 0; index -= 1){
@@ -107476,6 +107468,8 @@ __webpack_require__.d(__webpack_exports__, {
107476
107468
  * never *.cursorvm.com, so a CURSOR_ACCESS_TOKEN cannot be pointed at a box host.
107477
107469
  * Local/dev gateways: http(s)://127.0.0.1|localhost|::1 when GROK_BOT_ALLOW_LOCAL_GATEWAY=1.
107478
107470
  * Escape hatch: GROK_BOT_ALLOW_ANY_GATEWAY=1 (unsafe; disables host checks; warns once).
107471
+ * Test mode (GROK_BOT_TEST=1 or NODE_ENV=test): loopback only, for gateway and backend
107472
+ * alike, and the escape hatches are ignored — a test can never reach a live thread.
107479
107473
  */ function truthyEnv(name) {
107480
107474
  const v = (process.env[name] || "").trim().toLowerCase();
107481
107475
  return v === "1" || v === "true" || v === "yes";
@@ -107486,6 +107480,9 @@ function allowAnyGateway() {
107486
107480
  function allowLocalGateway() {
107487
107481
  return truthyEnv("GROK_BOT_ALLOW_LOCAL_GATEWAY");
107488
107482
  }
107483
+ function testMode() {
107484
+ return truthyEnv("GROK_BOT_TEST") || process.env.NODE_ENV === "test";
107485
+ }
107489
107486
  const warned = new Set();
107490
107487
  function warnOnce(key, message) {
107491
107488
  if (warned.has(key)) return;
@@ -107525,6 +107522,12 @@ function isCursorGatewayHostname(hostname) {
107525
107522
  if (parsed.username || parsed.password) {
107526
107523
  throw new Error("Rejected " + label + ": userinfo is not allowed.");
107527
107524
  }
107525
+ if (testMode()) {
107526
+ if (!isLocalHostname(parsed.hostname) || parsed.protocol !== "http:" && parsed.protocol !== "https:") {
107527
+ throw new Error("Rejected " + label + " host \"" + parsed.hostname + "\": test mode (GROK_BOT_TEST / NODE_ENV=test) only allows http(s) loopback gateways.");
107528
+ }
107529
+ return String(rawUrl).replace(/\/$/, "");
107530
+ }
107528
107531
  if (allowAnyGateway()) {
107529
107532
  warnOnce("ALLOW_ANY", "warning: GROK_BOT_ALLOW_ANY_GATEWAY is set; credential host checks are disabled.");
107530
107533
  return String(rawUrl).replace(/\/$/, "");
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grok-bot-cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "CLI and Agent Bundle plugin for Grok Bot agents and groups: create, update, message, inspect threads, and automate cleanup",
5
5
  "type": "module",
6
6
  "engines": {
@@ -14,7 +14,7 @@
14
14
  "release": "changeset publish",
15
15
  "test": "npm run test:unit && npm run test:routes",
16
16
  "test:routes": "rstest --config rstest.route-unit.config.ts",
17
- "test:unit": "node scripts/run-unit-tests.mjs",
17
+ "test:unit": "node --env-file=test.env --test \"test/*.test.js\"",
18
18
  "typecheck": "tsc -p tsconfig.json --noEmit",
19
19
  "validate": "agent-bundle validate",
20
20
  "validate:artifact": "agent-bundle validate --artifact artifact"
package/dist/plugin.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://agent-plugins.org/schemas/1.0.0/plugin.schema.json","author":{"name":"Zack Jackson","url":"https://github.com/ScriptedAlchemy"},"description":"Message Grok Bot bots and groups and read their threads from Codex, Claude Code, and Cursor.","homepage":"https://github.com/ScriptedAlchemy/grok-bot-cli#readme","keywords":["grok","grok-bot","grokbot","gbot","cursor","ai-agents","automation","terminal","cli","agent-bundle"],"license":"MIT","name":"gbot","repository":"https://github.com/ScriptedAlchemy/grok-bot-cli","version":"0.4.2"}
1
+ {"$schema":"https://agent-plugins.org/schemas/1.0.0/plugin.schema.json","author":{"name":"Zack Jackson","url":"https://github.com/ScriptedAlchemy"},"description":"Message Grok Bot bots and groups and read their threads from Codex, Claude Code, and Cursor.","homepage":"https://github.com/ScriptedAlchemy/grok-bot-cli#readme","keywords":["grok","grok-bot","grokbot","gbot","cursor","ai-agents","automation","terminal","cli","agent-bundle"],"license":"MIT","name":"gbot","repository":"https://github.com/ScriptedAlchemy/grok-bot-cli","version":"0.5.0"}
@@ -34,4 +34,6 @@ Framework argument/schema errors use stderr and exit 2. `--json` is reserved bef
34
34
 
35
35
  ## Auth
36
36
 
37
- Same order as `gbot`: explicit `GROK_BOT_GATEWAY_*`, else Grok Bot app session, else `CURSOR_ACCESS_TOKEN`. `gbot doctor` shows which source is present.
37
+ Same order as `gbot`: `GROK_BOT_GATEWAY_URL` plus `GROK_BOT_GATEWAY_TOKEN`,
38
+ else the Grok Bot app session, else `CURSOR_ACCESS_TOKEN`. `gbot doctor` shows
39
+ which source is present.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grok-bot-cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "CLI and Agent Bundle plugin for Grok Bot agents and groups: create, update, message, inspect threads, and automate cleanup",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  "release": "changeset publish",
21
21
  "test": "npm run test:unit && npm run test:routes",
22
22
  "test:routes": "rstest --config rstest.route-unit.config.ts",
23
- "test:unit": "node scripts/run-unit-tests.mjs",
23
+ "test:unit": "node --env-file=test.env --test \"test/*.test.js\"",
24
24
  "typecheck": "tsc -p tsconfig.json --noEmit",
25
25
  "validate": "agent-bundle validate",
26
26
  "validate:artifact": "agent-bundle validate --artifact artifact"