struere 0.12.2 → 0.12.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.
@@ -6647,6 +6647,53 @@ async function getTemplateStatus(connectionId, name) {
6647
6647
  name
6648
6648
  });
6649
6649
  }
6650
+ async function convexMutation3(path, args) {
6651
+ const token = getToken2();
6652
+ if (!token)
6653
+ return { error: "Not authenticated" };
6654
+ const response = await fetch(`${CONVEX_URL}/api/mutation`, {
6655
+ method: "POST",
6656
+ headers: {
6657
+ "Content-Type": "application/json",
6658
+ Authorization: `Bearer ${token}`
6659
+ },
6660
+ body: JSON.stringify({ path, args })
6661
+ });
6662
+ const text = await response.text();
6663
+ let json;
6664
+ try {
6665
+ json = JSON.parse(text);
6666
+ } catch {
6667
+ return { error: text || `HTTP ${response.status}` };
6668
+ }
6669
+ if (!response.ok) {
6670
+ const msg = json.errorData?.message || json.message || json.errorMessage || text;
6671
+ return { error: String(msg) };
6672
+ }
6673
+ if (json.status === "success")
6674
+ return { data: json.value };
6675
+ if (json.status === "error")
6676
+ return { error: String(json.errorMessage || "Unknown error") };
6677
+ return { error: `Unexpected response: ${text}` };
6678
+ }
6679
+ async function listRouters(env) {
6680
+ return convexQuery4("routers:list", { environment: env });
6681
+ }
6682
+ async function setConnectionRouter(connectionId, routerId) {
6683
+ return convexMutation3("whatsapp:setPhoneAgent", {
6684
+ connectionId,
6685
+ routerId
6686
+ });
6687
+ }
6688
+ async function setConnectionAgent(connectionId, agentId) {
6689
+ return convexMutation3("whatsapp:setPhoneAgent", {
6690
+ connectionId,
6691
+ agentId
6692
+ });
6693
+ }
6694
+ async function resolveAgentBySlug(slug) {
6695
+ return convexQuery4("agents:getBySlug", { slug });
6696
+ }
6650
6697
  async function updateTemplate(connectionId, templateId, updates) {
6651
6698
  if (getApiKey()) {
6652
6699
  return httpPost("/v1/templates/update", { connectionId, templateId, ...updates });
@@ -7020,7 +7067,7 @@ async function convexQuery5(path, args) {
7020
7067
  return { error: String(json.errorMessage || "Unknown error") };
7021
7068
  return { error: `Unexpected response: ${text}` };
7022
7069
  }
7023
- async function convexMutation3(path, args) {
7070
+ async function convexMutation4(path, args) {
7024
7071
  const result = await getValidToken();
7025
7072
  if ("error" in result)
7026
7073
  return { error: result.error };
@@ -7084,19 +7131,19 @@ async function getIntegrationConfig(provider, env) {
7084
7131
  return convexQuery5("integrations:getConfig", { provider, environment: env });
7085
7132
  }
7086
7133
  async function updateIntegrationConfig(provider, env, config) {
7087
- return convexMutation3("integrations:updateConfig", { provider, environment: env, config });
7134
+ return convexMutation4("integrations:updateConfig", { provider, environment: env, config });
7088
7135
  }
7089
7136
  async function testIntegrationConnection(provider, env) {
7090
7137
  return convexAction2("integrations:testConnection", { provider, environment: env });
7091
7138
  }
7092
7139
  async function deleteIntegrationConfig(provider, env) {
7093
- return convexMutation3("integrations:deleteConfig", { provider, environment: env });
7140
+ return convexMutation4("integrations:deleteConfig", { provider, environment: env });
7094
7141
  }
7095
7142
  async function listIntegrationConfigs(env) {
7096
7143
  return convexQuery5("integrations:listConfigs", { environment: env });
7097
7144
  }
7098
7145
  async function setIntegrationStatus(provider, env, status) {
7099
- return convexMutation3("integrations:setConfigStatus", { provider, environment: env, status });
7146
+ return convexMutation4("integrations:setConfigStatus", { provider, environment: env, status });
7100
7147
  }
7101
7148
 
7102
7149
  // src/cli/commands/integration.ts
@@ -7416,7 +7463,7 @@ async function convexQuery6(path, args) {
7416
7463
  }
7417
7464
  return json.value;
7418
7465
  }
7419
- async function convexMutation4(path, args) {
7466
+ async function convexMutation5(path, args) {
7420
7467
  const token = getToken3();
7421
7468
  const response = await fetch(`${CONVEX_URL}/api/mutation`, {
7422
7469
  method: "POST",
@@ -7468,14 +7515,14 @@ async function getLastRunStatuses(environment) {
7468
7515
  return convexQuery6("triggers:getLastRunStatuses", { environment });
7469
7516
  }
7470
7517
  async function cancelTriggerRun(runId, environment) {
7471
- return convexMutation4("triggers:cancelRun", { runId, environment });
7518
+ return convexMutation5("triggers:cancelRun", { runId, environment });
7472
7519
  }
7473
7520
  async function retryTriggerRun(runId, environment) {
7474
- return convexMutation4("triggers:retryRun", { runId, environment });
7521
+ return convexMutation5("triggers:retryRun", { runId, environment });
7475
7522
  }
7476
7523
  async function toggleTrigger(slug, enabled, environment) {
7477
7524
  const path = enabled ? "triggers:enable" : "triggers:disable";
7478
- return convexMutation4(path, { slug, environment });
7525
+ return convexMutation5(path, { slug, environment });
7479
7526
  }
7480
7527
  async function listTriggerExecutions(options) {
7481
7528
  return convexQuery6("triggers:listExecutions", {
@@ -8794,10 +8841,207 @@ var chatCommand = new Command21("chat").description("Chat with an agent or via a
8794
8841
  process.exit(0);
8795
8842
  });
8796
8843
  });
8844
+
8845
+ // src/cli/commands/whatsapp.ts
8846
+ init_credentials();
8847
+ import { Command as Command22 } from "commander";
8848
+ import chalk24 from "chalk";
8849
+ async function ensureAuth6() {
8850
+ const cwd = process.cwd();
8851
+ const nonInteractive = !isInteractive();
8852
+ if (!hasProject(cwd)) {
8853
+ if (nonInteractive) {
8854
+ console.error(chalk24.red("No struere.json found. Run struere init first."));
8855
+ process.exit(1);
8856
+ }
8857
+ console.log(chalk24.yellow("No struere.json found - initializing project..."));
8858
+ console.log();
8859
+ const success = await runInit(cwd);
8860
+ if (!success) {
8861
+ process.exit(1);
8862
+ }
8863
+ console.log();
8864
+ }
8865
+ let credentials = loadCredentials();
8866
+ const apiKey = getApiKey();
8867
+ if (!credentials && !apiKey) {
8868
+ if (nonInteractive) {
8869
+ console.error(chalk24.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
8870
+ process.exit(1);
8871
+ }
8872
+ console.log(chalk24.yellow("Not logged in - authenticating..."));
8873
+ console.log();
8874
+ credentials = await performLogin();
8875
+ if (!credentials) {
8876
+ console.log(chalk24.red("Authentication failed"));
8877
+ process.exit(1);
8878
+ }
8879
+ console.log();
8880
+ }
8881
+ return true;
8882
+ }
8883
+ async function resolveConnection(env, identifier, out) {
8884
+ out.start("Fetching WhatsApp connections");
8885
+ const { data, error } = await listWhatsAppConnections(env);
8886
+ if (error || !data) {
8887
+ out.fail("Failed to fetch connections");
8888
+ out.error(error ?? "Unknown error");
8889
+ return null;
8890
+ }
8891
+ const connections = data;
8892
+ const match = connections.find((c) => {
8893
+ if (c._id === identifier)
8894
+ return true;
8895
+ if (c._id.endsWith(identifier))
8896
+ return true;
8897
+ if (c.label && c.label.toLowerCase() === identifier.toLowerCase())
8898
+ return true;
8899
+ if (c.phoneNumber && c.phoneNumber === identifier.replace(/^\+/, ""))
8900
+ return true;
8901
+ if (c.phoneNumber && `+${c.phoneNumber}` === identifier)
8902
+ return true;
8903
+ return false;
8904
+ });
8905
+ if (!match) {
8906
+ out.fail(`Connection not found: ${identifier}`);
8907
+ out.info('Run "struere whatsapp list" to see available connections');
8908
+ return null;
8909
+ }
8910
+ out.succeed(`Found connection: ${match.label || (match.phoneNumber ? `+${match.phoneNumber}` : match._id)}`);
8911
+ return match;
8912
+ }
8913
+ function connectionLabel(conn) {
8914
+ return conn.label || (conn.phoneNumber ? `+${conn.phoneNumber}` : conn._id.slice(-12));
8915
+ }
8916
+ function statusColor5(status) {
8917
+ switch (status) {
8918
+ case "connected":
8919
+ return chalk24.green(status);
8920
+ case "pending_setup":
8921
+ return chalk24.yellow("pending");
8922
+ case "disconnected":
8923
+ return chalk24.red(status);
8924
+ default:
8925
+ return chalk24.gray(status);
8926
+ }
8927
+ }
8928
+ function assignmentLabel(conn) {
8929
+ if (conn.routerName)
8930
+ return `Router: ${conn.routerName}`;
8931
+ if (conn.agentName)
8932
+ return `Agent: ${conn.agentName}`;
8933
+ if (conn.routerId)
8934
+ return `Router: ${conn.routerId.slice(-8)}`;
8935
+ if (conn.agentId)
8936
+ return `Agent: ${conn.agentId.slice(-8)}`;
8937
+ return chalk24.gray("none");
8938
+ }
8939
+ var whatsappCommand = new Command22("whatsapp").description("Manage WhatsApp connections and routing");
8940
+ whatsappCommand.command("list").description("List WhatsApp connections with routing assignments").option("--env <environment>", "Environment (development|production)", "production").option("--json", "Output raw JSON").action(async (opts) => {
8941
+ await ensureAuth6();
8942
+ const env = opts.env;
8943
+ const out = createOutput();
8944
+ out.start("Fetching WhatsApp connections");
8945
+ const { data, error } = await listWhatsAppConnections(env);
8946
+ if (error || !data) {
8947
+ out.fail("Failed to fetch connections");
8948
+ out.error(error ?? "Unknown error");
8949
+ process.exit(1);
8950
+ }
8951
+ const connections = data;
8952
+ out.succeed(`Found ${connections.length} connections`);
8953
+ if (opts.json) {
8954
+ console.log(JSON.stringify(connections, null, 2));
8955
+ return;
8956
+ }
8957
+ console.log();
8958
+ if (connections.length === 0) {
8959
+ console.log(chalk24.gray(" No WhatsApp connections found"));
8960
+ console.log();
8961
+ return;
8962
+ }
8963
+ renderTable([
8964
+ { key: "label", label: "Label", width: 20 },
8965
+ { key: "phone", label: "Phone", width: 18 },
8966
+ { key: "status", label: "Status", width: 14 },
8967
+ { key: "assignment", label: "Assignment", width: 30 },
8968
+ { key: "id", label: "ID", width: 16 }
8969
+ ], connections.map((c) => ({
8970
+ label: c.label || chalk24.gray("-"),
8971
+ phone: c.phoneNumber ? `+${c.phoneNumber}` : chalk24.gray("-"),
8972
+ status: statusColor5(c.status),
8973
+ assignment: assignmentLabel(c),
8974
+ id: c._id.slice(-12)
8975
+ })));
8976
+ console.log();
8977
+ });
8978
+ whatsappCommand.command("set-router <connection> <router-slug>").description("Assign a router to a WhatsApp connection").option("--env <environment>", "Environment (development|production)", "production").action(async (connection, routerSlug, opts) => {
8979
+ await ensureAuth6();
8980
+ const env = opts.env;
8981
+ const out = createOutput();
8982
+ const conn = await resolveConnection(env, connection, out);
8983
+ if (!conn)
8984
+ process.exit(1);
8985
+ out.start(`Looking up router "${routerSlug}"`);
8986
+ const { data: routersData, error: routersError } = await listRouters(env);
8987
+ if (routersError || !routersData) {
8988
+ out.fail("Failed to fetch routers");
8989
+ out.error(routersError ?? "Unknown error");
8990
+ process.exit(1);
8991
+ }
8992
+ const routers = routersData;
8993
+ const router = routers.find((r) => r.slug === routerSlug);
8994
+ if (!router) {
8995
+ out.fail(`Router not found: ${routerSlug}`);
8996
+ if (routers.length > 0) {
8997
+ out.info(`Available routers: ${routers.map((r) => r.slug).join(", ")}`);
8998
+ } else {
8999
+ out.info("No routers found in this environment");
9000
+ }
9001
+ process.exit(1);
9002
+ }
9003
+ out.succeed(`Found router: ${router.name}`);
9004
+ out.start("Assigning router to connection");
9005
+ const { error: setError } = await setConnectionRouter(conn._id, router._id);
9006
+ if (setError) {
9007
+ out.fail("Failed to assign router");
9008
+ out.error(setError);
9009
+ process.exit(1);
9010
+ }
9011
+ out.succeed(`Connection ${connectionLabel(conn)} now routes via ${router.name} (${routerSlug})`);
9012
+ console.log();
9013
+ });
9014
+ whatsappCommand.command("set-agent <connection> <agent-slug>").description("Assign an agent directly to a WhatsApp connection").option("--env <environment>", "Environment (development|production)", "production").action(async (connection, agentSlug, opts) => {
9015
+ await ensureAuth6();
9016
+ const env = opts.env;
9017
+ const out = createOutput();
9018
+ const conn = await resolveConnection(env, connection, out);
9019
+ if (!conn)
9020
+ process.exit(1);
9021
+ out.start(`Looking up agent "${agentSlug}"`);
9022
+ const { data: agentData, error: agentError } = await resolveAgentBySlug(agentSlug);
9023
+ if (agentError || !agentData) {
9024
+ out.fail(`Agent not found: ${agentSlug}`);
9025
+ if (agentError)
9026
+ out.error(agentError);
9027
+ process.exit(1);
9028
+ }
9029
+ const agent = agentData;
9030
+ out.succeed(`Found agent: ${agent.name}`);
9031
+ out.start("Assigning agent to connection");
9032
+ const { error: setError } = await setConnectionAgent(conn._id, agent._id);
9033
+ if (setError) {
9034
+ out.fail("Failed to assign agent");
9035
+ out.error(setError);
9036
+ process.exit(1);
9037
+ }
9038
+ out.succeed(`Connection ${connectionLabel(conn)} now assigned to agent ${agent.name} (${agentSlug})`);
9039
+ console.log();
9040
+ });
8797
9041
  // package.json
8798
9042
  var package_default = {
8799
9043
  name: "struere",
8800
- version: "0.12.2",
9044
+ version: "0.12.3",
8801
9045
  description: "Build, test, and deploy AI agents",
8802
9046
  keywords: [
8803
9047
  "ai",
@@ -8918,4 +9162,5 @@ program.addCommand(triggersCommand);
8918
9162
  program.addCommand(compilePromptCommand);
8919
9163
  program.addCommand(runToolCommand);
8920
9164
  program.addCommand(chatCommand);
9165
+ program.addCommand(whatsappCommand);
8921
9166
  program.parse();
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const whatsappCommand: Command;
3
+ //# sourceMappingURL=whatsapp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/whatsapp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA4HnC,eAAO,MAAM,eAAe,SAC6B,CAAA"}
package/dist/cli/index.js CHANGED
@@ -6647,6 +6647,53 @@ async function getTemplateStatus(connectionId, name) {
6647
6647
  name
6648
6648
  });
6649
6649
  }
6650
+ async function convexMutation3(path, args) {
6651
+ const token = getToken2();
6652
+ if (!token)
6653
+ return { error: "Not authenticated" };
6654
+ const response = await fetch(`${CONVEX_URL}/api/mutation`, {
6655
+ method: "POST",
6656
+ headers: {
6657
+ "Content-Type": "application/json",
6658
+ Authorization: `Bearer ${token}`
6659
+ },
6660
+ body: JSON.stringify({ path, args })
6661
+ });
6662
+ const text = await response.text();
6663
+ let json;
6664
+ try {
6665
+ json = JSON.parse(text);
6666
+ } catch {
6667
+ return { error: text || `HTTP ${response.status}` };
6668
+ }
6669
+ if (!response.ok) {
6670
+ const msg = json.errorData?.message || json.message || json.errorMessage || text;
6671
+ return { error: String(msg) };
6672
+ }
6673
+ if (json.status === "success")
6674
+ return { data: json.value };
6675
+ if (json.status === "error")
6676
+ return { error: String(json.errorMessage || "Unknown error") };
6677
+ return { error: `Unexpected response: ${text}` };
6678
+ }
6679
+ async function listRouters(env) {
6680
+ return convexQuery4("routers:list", { environment: env });
6681
+ }
6682
+ async function setConnectionRouter(connectionId, routerId) {
6683
+ return convexMutation3("whatsapp:setPhoneAgent", {
6684
+ connectionId,
6685
+ routerId
6686
+ });
6687
+ }
6688
+ async function setConnectionAgent(connectionId, agentId) {
6689
+ return convexMutation3("whatsapp:setPhoneAgent", {
6690
+ connectionId,
6691
+ agentId
6692
+ });
6693
+ }
6694
+ async function resolveAgentBySlug(slug) {
6695
+ return convexQuery4("agents:getBySlug", { slug });
6696
+ }
6650
6697
  async function updateTemplate(connectionId, templateId, updates) {
6651
6698
  if (getApiKey()) {
6652
6699
  return httpPost("/v1/templates/update", { connectionId, templateId, ...updates });
@@ -7020,7 +7067,7 @@ async function convexQuery5(path, args) {
7020
7067
  return { error: String(json.errorMessage || "Unknown error") };
7021
7068
  return { error: `Unexpected response: ${text}` };
7022
7069
  }
7023
- async function convexMutation3(path, args) {
7070
+ async function convexMutation4(path, args) {
7024
7071
  const result = await getValidToken();
7025
7072
  if ("error" in result)
7026
7073
  return { error: result.error };
@@ -7084,19 +7131,19 @@ async function getIntegrationConfig(provider, env) {
7084
7131
  return convexQuery5("integrations:getConfig", { provider, environment: env });
7085
7132
  }
7086
7133
  async function updateIntegrationConfig(provider, env, config) {
7087
- return convexMutation3("integrations:updateConfig", { provider, environment: env, config });
7134
+ return convexMutation4("integrations:updateConfig", { provider, environment: env, config });
7088
7135
  }
7089
7136
  async function testIntegrationConnection(provider, env) {
7090
7137
  return convexAction2("integrations:testConnection", { provider, environment: env });
7091
7138
  }
7092
7139
  async function deleteIntegrationConfig(provider, env) {
7093
- return convexMutation3("integrations:deleteConfig", { provider, environment: env });
7140
+ return convexMutation4("integrations:deleteConfig", { provider, environment: env });
7094
7141
  }
7095
7142
  async function listIntegrationConfigs(env) {
7096
7143
  return convexQuery5("integrations:listConfigs", { environment: env });
7097
7144
  }
7098
7145
  async function setIntegrationStatus(provider, env, status) {
7099
- return convexMutation3("integrations:setConfigStatus", { provider, environment: env, status });
7146
+ return convexMutation4("integrations:setConfigStatus", { provider, environment: env, status });
7100
7147
  }
7101
7148
 
7102
7149
  // src/cli/commands/integration.ts
@@ -7416,7 +7463,7 @@ async function convexQuery6(path, args) {
7416
7463
  }
7417
7464
  return json.value;
7418
7465
  }
7419
- async function convexMutation4(path, args) {
7466
+ async function convexMutation5(path, args) {
7420
7467
  const token = getToken3();
7421
7468
  const response = await fetch(`${CONVEX_URL}/api/mutation`, {
7422
7469
  method: "POST",
@@ -7468,14 +7515,14 @@ async function getLastRunStatuses(environment) {
7468
7515
  return convexQuery6("triggers:getLastRunStatuses", { environment });
7469
7516
  }
7470
7517
  async function cancelTriggerRun(runId, environment) {
7471
- return convexMutation4("triggers:cancelRun", { runId, environment });
7518
+ return convexMutation5("triggers:cancelRun", { runId, environment });
7472
7519
  }
7473
7520
  async function retryTriggerRun(runId, environment) {
7474
- return convexMutation4("triggers:retryRun", { runId, environment });
7521
+ return convexMutation5("triggers:retryRun", { runId, environment });
7475
7522
  }
7476
7523
  async function toggleTrigger(slug, enabled, environment) {
7477
7524
  const path = enabled ? "triggers:enable" : "triggers:disable";
7478
- return convexMutation4(path, { slug, environment });
7525
+ return convexMutation5(path, { slug, environment });
7479
7526
  }
7480
7527
  async function listTriggerExecutions(options) {
7481
7528
  return convexQuery6("triggers:listExecutions", {
@@ -8794,10 +8841,207 @@ var chatCommand = new Command21("chat").description("Chat with an agent or via a
8794
8841
  process.exit(0);
8795
8842
  });
8796
8843
  });
8844
+
8845
+ // src/cli/commands/whatsapp.ts
8846
+ init_credentials();
8847
+ import { Command as Command22 } from "commander";
8848
+ import chalk24 from "chalk";
8849
+ async function ensureAuth6() {
8850
+ const cwd = process.cwd();
8851
+ const nonInteractive = !isInteractive();
8852
+ if (!hasProject(cwd)) {
8853
+ if (nonInteractive) {
8854
+ console.error(chalk24.red("No struere.json found. Run struere init first."));
8855
+ process.exit(1);
8856
+ }
8857
+ console.log(chalk24.yellow("No struere.json found - initializing project..."));
8858
+ console.log();
8859
+ const success = await runInit(cwd);
8860
+ if (!success) {
8861
+ process.exit(1);
8862
+ }
8863
+ console.log();
8864
+ }
8865
+ let credentials = loadCredentials();
8866
+ const apiKey = getApiKey();
8867
+ if (!credentials && !apiKey) {
8868
+ if (nonInteractive) {
8869
+ console.error(chalk24.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
8870
+ process.exit(1);
8871
+ }
8872
+ console.log(chalk24.yellow("Not logged in - authenticating..."));
8873
+ console.log();
8874
+ credentials = await performLogin();
8875
+ if (!credentials) {
8876
+ console.log(chalk24.red("Authentication failed"));
8877
+ process.exit(1);
8878
+ }
8879
+ console.log();
8880
+ }
8881
+ return true;
8882
+ }
8883
+ async function resolveConnection(env, identifier, out) {
8884
+ out.start("Fetching WhatsApp connections");
8885
+ const { data, error } = await listWhatsAppConnections(env);
8886
+ if (error || !data) {
8887
+ out.fail("Failed to fetch connections");
8888
+ out.error(error ?? "Unknown error");
8889
+ return null;
8890
+ }
8891
+ const connections = data;
8892
+ const match = connections.find((c) => {
8893
+ if (c._id === identifier)
8894
+ return true;
8895
+ if (c._id.endsWith(identifier))
8896
+ return true;
8897
+ if (c.label && c.label.toLowerCase() === identifier.toLowerCase())
8898
+ return true;
8899
+ if (c.phoneNumber && c.phoneNumber === identifier.replace(/^\+/, ""))
8900
+ return true;
8901
+ if (c.phoneNumber && `+${c.phoneNumber}` === identifier)
8902
+ return true;
8903
+ return false;
8904
+ });
8905
+ if (!match) {
8906
+ out.fail(`Connection not found: ${identifier}`);
8907
+ out.info('Run "struere whatsapp list" to see available connections');
8908
+ return null;
8909
+ }
8910
+ out.succeed(`Found connection: ${match.label || (match.phoneNumber ? `+${match.phoneNumber}` : match._id)}`);
8911
+ return match;
8912
+ }
8913
+ function connectionLabel(conn) {
8914
+ return conn.label || (conn.phoneNumber ? `+${conn.phoneNumber}` : conn._id.slice(-12));
8915
+ }
8916
+ function statusColor5(status) {
8917
+ switch (status) {
8918
+ case "connected":
8919
+ return chalk24.green(status);
8920
+ case "pending_setup":
8921
+ return chalk24.yellow("pending");
8922
+ case "disconnected":
8923
+ return chalk24.red(status);
8924
+ default:
8925
+ return chalk24.gray(status);
8926
+ }
8927
+ }
8928
+ function assignmentLabel(conn) {
8929
+ if (conn.routerName)
8930
+ return `Router: ${conn.routerName}`;
8931
+ if (conn.agentName)
8932
+ return `Agent: ${conn.agentName}`;
8933
+ if (conn.routerId)
8934
+ return `Router: ${conn.routerId.slice(-8)}`;
8935
+ if (conn.agentId)
8936
+ return `Agent: ${conn.agentId.slice(-8)}`;
8937
+ return chalk24.gray("none");
8938
+ }
8939
+ var whatsappCommand = new Command22("whatsapp").description("Manage WhatsApp connections and routing");
8940
+ whatsappCommand.command("list").description("List WhatsApp connections with routing assignments").option("--env <environment>", "Environment (development|production)", "production").option("--json", "Output raw JSON").action(async (opts) => {
8941
+ await ensureAuth6();
8942
+ const env = opts.env;
8943
+ const out = createOutput();
8944
+ out.start("Fetching WhatsApp connections");
8945
+ const { data, error } = await listWhatsAppConnections(env);
8946
+ if (error || !data) {
8947
+ out.fail("Failed to fetch connections");
8948
+ out.error(error ?? "Unknown error");
8949
+ process.exit(1);
8950
+ }
8951
+ const connections = data;
8952
+ out.succeed(`Found ${connections.length} connections`);
8953
+ if (opts.json) {
8954
+ console.log(JSON.stringify(connections, null, 2));
8955
+ return;
8956
+ }
8957
+ console.log();
8958
+ if (connections.length === 0) {
8959
+ console.log(chalk24.gray(" No WhatsApp connections found"));
8960
+ console.log();
8961
+ return;
8962
+ }
8963
+ renderTable([
8964
+ { key: "label", label: "Label", width: 20 },
8965
+ { key: "phone", label: "Phone", width: 18 },
8966
+ { key: "status", label: "Status", width: 14 },
8967
+ { key: "assignment", label: "Assignment", width: 30 },
8968
+ { key: "id", label: "ID", width: 16 }
8969
+ ], connections.map((c) => ({
8970
+ label: c.label || chalk24.gray("-"),
8971
+ phone: c.phoneNumber ? `+${c.phoneNumber}` : chalk24.gray("-"),
8972
+ status: statusColor5(c.status),
8973
+ assignment: assignmentLabel(c),
8974
+ id: c._id.slice(-12)
8975
+ })));
8976
+ console.log();
8977
+ });
8978
+ whatsappCommand.command("set-router <connection> <router-slug>").description("Assign a router to a WhatsApp connection").option("--env <environment>", "Environment (development|production)", "production").action(async (connection, routerSlug, opts) => {
8979
+ await ensureAuth6();
8980
+ const env = opts.env;
8981
+ const out = createOutput();
8982
+ const conn = await resolveConnection(env, connection, out);
8983
+ if (!conn)
8984
+ process.exit(1);
8985
+ out.start(`Looking up router "${routerSlug}"`);
8986
+ const { data: routersData, error: routersError } = await listRouters(env);
8987
+ if (routersError || !routersData) {
8988
+ out.fail("Failed to fetch routers");
8989
+ out.error(routersError ?? "Unknown error");
8990
+ process.exit(1);
8991
+ }
8992
+ const routers = routersData;
8993
+ const router = routers.find((r) => r.slug === routerSlug);
8994
+ if (!router) {
8995
+ out.fail(`Router not found: ${routerSlug}`);
8996
+ if (routers.length > 0) {
8997
+ out.info(`Available routers: ${routers.map((r) => r.slug).join(", ")}`);
8998
+ } else {
8999
+ out.info("No routers found in this environment");
9000
+ }
9001
+ process.exit(1);
9002
+ }
9003
+ out.succeed(`Found router: ${router.name}`);
9004
+ out.start("Assigning router to connection");
9005
+ const { error: setError } = await setConnectionRouter(conn._id, router._id);
9006
+ if (setError) {
9007
+ out.fail("Failed to assign router");
9008
+ out.error(setError);
9009
+ process.exit(1);
9010
+ }
9011
+ out.succeed(`Connection ${connectionLabel(conn)} now routes via ${router.name} (${routerSlug})`);
9012
+ console.log();
9013
+ });
9014
+ whatsappCommand.command("set-agent <connection> <agent-slug>").description("Assign an agent directly to a WhatsApp connection").option("--env <environment>", "Environment (development|production)", "production").action(async (connection, agentSlug, opts) => {
9015
+ await ensureAuth6();
9016
+ const env = opts.env;
9017
+ const out = createOutput();
9018
+ const conn = await resolveConnection(env, connection, out);
9019
+ if (!conn)
9020
+ process.exit(1);
9021
+ out.start(`Looking up agent "${agentSlug}"`);
9022
+ const { data: agentData, error: agentError } = await resolveAgentBySlug(agentSlug);
9023
+ if (agentError || !agentData) {
9024
+ out.fail(`Agent not found: ${agentSlug}`);
9025
+ if (agentError)
9026
+ out.error(agentError);
9027
+ process.exit(1);
9028
+ }
9029
+ const agent = agentData;
9030
+ out.succeed(`Found agent: ${agent.name}`);
9031
+ out.start("Assigning agent to connection");
9032
+ const { error: setError } = await setConnectionAgent(conn._id, agent._id);
9033
+ if (setError) {
9034
+ out.fail("Failed to assign agent");
9035
+ out.error(setError);
9036
+ process.exit(1);
9037
+ }
9038
+ out.succeed(`Connection ${connectionLabel(conn)} now assigned to agent ${agent.name} (${agentSlug})`);
9039
+ console.log();
9040
+ });
8797
9041
  // package.json
8798
9042
  var package_default = {
8799
9043
  name: "struere",
8800
- version: "0.12.2",
9044
+ version: "0.12.3",
8801
9045
  description: "Build, test, and deploy AI agents",
8802
9046
  keywords: [
8803
9047
  "ai",
@@ -8918,4 +9162,5 @@ program.addCommand(triggersCommand);
8918
9162
  program.addCommand(compilePromptCommand);
8919
9163
  program.addCommand(runToolCommand);
8920
9164
  program.addCommand(chatCommand);
9165
+ program.addCommand(whatsappCommand);
8921
9166
  program.parse();
@@ -19,6 +19,26 @@ export declare function getTemplateStatus(connectionId: string, name: string): P
19
19
  data?: unknown;
20
20
  error?: string;
21
21
  }>;
22
+ export declare function listRouters(env: string): Promise<{
23
+ data?: unknown;
24
+ error?: string;
25
+ }>;
26
+ export declare function setConnectionRouter(connectionId: string, routerId: string): Promise<{
27
+ data?: unknown;
28
+ error?: string;
29
+ }>;
30
+ export declare function setConnectionAgent(connectionId: string, agentId: string): Promise<{
31
+ data?: unknown;
32
+ error?: string;
33
+ }>;
34
+ export declare function resolveAgentBySlug(slug: string): Promise<{
35
+ data?: {
36
+ _id: string;
37
+ name: string;
38
+ slug: string;
39
+ };
40
+ error?: string;
41
+ }>;
22
42
  export declare function updateTemplate(connectionId: string, templateId: string, updates: {
23
43
  name?: string;
24
44
  language?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/whatsapp.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG,aAAa,GAAG,YAAY,CAAA;AA2G/C,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,WAAW;WAnGyB,OAAO;YAAU,MAAM;GA0G7G;AAED,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM;WA5G+B,OAAO;YAAU,MAAM;GAmH7G;AAED,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC1C,mBAAmB,CAAC,EAAE,OAAO;WA3HwD,OAAO;YAAU,MAAM;GA+I7G;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;WAjJgB,OAAO;YAAU,MAAM;GAyJ7G;AAED,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;WA3Ja,OAAO;YAAU,MAAM;GAmK7G;AAED,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE;WAxKxB,OAAO;YAAU,MAAM;GAkL7G"}
1
+ {"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/whatsapp.ts"],"names":[],"mappings":"AAGA,KAAK,WAAW,GAAG,aAAa,GAAG,YAAY,CAAA;AA2G/C,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,WAAW;WAnGyB,OAAO;YAAU,MAAM;GA0G7G;AAED,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM;WA5G+B,OAAO;YAAU,MAAM;GAmH7G;AAED,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC1C,mBAAmB,CAAC,EAAE,OAAO;WA3HwD,OAAO;YAAU,MAAM;GA+I7G;AAED,wBAAsB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;WAjJgB,OAAO;YAAU,MAAM;GAyJ7G;AAED,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;WA3Ja,OAAO;YAAU,MAAM;GAmK7G;AAiCD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM;WAhI6C,OAAO;YAAU,MAAM;GAkIhH;AAED,wBAAsB,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;WAnCa,OAAO;YAAU,MAAM;GAwCnH;AAED,wBAAsB,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;WA1Ce,OAAO;YAAU,MAAM;GA+CnH;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAEtI;AAED,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CAAE;WA7NxB,OAAO;YAAU,MAAM;GAuO7G"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "struere",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "Build, test, and deploy AI agents",
5
5
  "keywords": [
6
6
  "ai",