struere 0.11.2 → 0.12.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.
@@ -33,12 +33,7 @@ function loadCredentials() {
33
33
  }
34
34
  try {
35
35
  const data = readFileSync(CREDENTIALS_FILE, "utf-8");
36
- const credentials = JSON.parse(data);
37
- if (new Date(credentials.expiresAt) < new Date) {
38
- clearCredentials();
39
- return null;
40
- }
41
- return credentials;
36
+ return JSON.parse(data);
42
37
  } catch {
43
38
  return null;
44
39
  }
@@ -936,7 +931,7 @@ function getTsConfig() {
936
931
  rootDir: ".",
937
932
  types: ["bun-types"],
938
933
  paths: {
939
- struere: ["./.struere/index.d.ts"]
934
+ struere: ["./.struere"]
940
935
  }
941
936
  },
942
937
  include: ["**/*.ts"],
@@ -5364,10 +5359,13 @@ function getToken2() {
5364
5359
  return apiKey || credentials?.token || null;
5365
5360
  }
5366
5361
  async function convexQuery2(path, args) {
5367
- const token = getToken2();
5368
- if (!token)
5369
- return { error: "Not authenticated" };
5370
- const response = await fetch(`${CONVEX_URL}/api/query`, {
5362
+ let token = getToken2();
5363
+ if (!token) {
5364
+ token = await refreshToken();
5365
+ if (!token)
5366
+ return { error: "Not authenticated. Run `struere login`." };
5367
+ }
5368
+ let response = await fetch(`${CONVEX_URL}/api/query`, {
5371
5369
  method: "POST",
5372
5370
  headers: {
5373
5371
  "Content-Type": "application/json",
@@ -5375,6 +5373,19 @@ async function convexQuery2(path, args) {
5375
5373
  },
5376
5374
  body: JSON.stringify({ path, args })
5377
5375
  });
5376
+ if (response.status === 401 || response.status === 403) {
5377
+ const refreshed = await refreshToken();
5378
+ if (refreshed) {
5379
+ response = await fetch(`${CONVEX_URL}/api/query`, {
5380
+ method: "POST",
5381
+ headers: {
5382
+ "Content-Type": "application/json",
5383
+ Authorization: `Bearer ${refreshed}`
5384
+ },
5385
+ body: JSON.stringify({ path, args })
5386
+ });
5387
+ }
5388
+ }
5378
5389
  const text = await response.text();
5379
5390
  let json;
5380
5391
  try {
@@ -5383,22 +5394,45 @@ async function convexQuery2(path, args) {
5383
5394
  return { error: text || `HTTP ${response.status}` };
5384
5395
  }
5385
5396
  if (!response.ok) {
5386
- const msg = json.errorData?.message || json.message || json.errorMessage || text;
5387
- return { error: String(msg) };
5397
+ const errorData = json.errorData;
5398
+ const msg = errorData?.message || json.message || json.errorMessage || text;
5399
+ const msgStr = String(msg);
5400
+ if (msgStr.includes("OIDC") || msgStr.includes("token")) {
5401
+ return { error: "Session expired. Run `struere logout && struere login`." };
5402
+ }
5403
+ return { error: msgStr };
5388
5404
  }
5389
5405
  if (json.status === "success")
5390
5406
  return { data: json.value };
5391
- if (json.status === "error")
5392
- return { error: String(json.errorMessage || "Unknown error") };
5407
+ if (json.status === "error") {
5408
+ const errMsg = String(json.errorMessage || "Unknown error");
5409
+ if (errMsg.includes("OIDC") || errMsg.includes("token")) {
5410
+ return { error: "Session expired. Run `struere logout && struere login`." };
5411
+ }
5412
+ return { error: errMsg };
5413
+ }
5393
5414
  return { error: `Unexpected response: ${text}` };
5394
5415
  }
5395
5416
  async function queryThreads(options) {
5396
- return convexQuery2("threads:listWithPreviews", {
5417
+ const result = await convexQuery2("threads:listWithPreviews", {
5397
5418
  environment: options.environment,
5398
5419
  ...options.agentId && { agentId: options.agentId },
5399
5420
  ...options.channel && { channel: options.channel },
5400
5421
  ...options.limit && { limit: options.limit }
5401
5422
  });
5423
+ if (result.error || !result.data)
5424
+ return result;
5425
+ if (options.phone) {
5426
+ const threads = result.data;
5427
+ const filtered = threads.filter((t) => {
5428
+ const externalId = t.externalId ?? "";
5429
+ const params = t.channelParams;
5430
+ const phone = params?.phoneNumber ?? "";
5431
+ return externalId.includes(options.phone) || phone.includes(options.phone);
5432
+ });
5433
+ return { data: filtered };
5434
+ }
5435
+ return result;
5402
5436
  }
5403
5437
  async function queryThreadDetail(threadId, messageLimit) {
5404
5438
  return convexQuery2("threads:getWithMessages", {
@@ -5409,6 +5443,31 @@ async function queryThreadDetail(threadId, messageLimit) {
5409
5443
  async function queryThreadExecutions(threadId) {
5410
5444
  return convexQuery2("executions:getByThread", { threadId });
5411
5445
  }
5446
+ async function resolveThreadId(shortId, environment) {
5447
+ if (shortId.includes("|") || shortId.length > 20) {
5448
+ return { data: shortId };
5449
+ }
5450
+ const result = await queryThreads({ environment: environment ?? "development", limit: 100 });
5451
+ if (result.error || !result.data)
5452
+ return { error: result.error ?? "Could not fetch threads" };
5453
+ const threads = result.data;
5454
+ const match = threads.find((t) => t._id.endsWith(shortId));
5455
+ if (!match) {
5456
+ for (const env of ["production", "development", "eval"]) {
5457
+ if (env === (environment ?? "development"))
5458
+ continue;
5459
+ const envResult = await queryThreads({ environment: env, limit: 100 });
5460
+ if (envResult.data) {
5461
+ const envThreads = envResult.data;
5462
+ const envMatch = envThreads.find((t) => t._id.endsWith(shortId));
5463
+ if (envMatch)
5464
+ return { data: envMatch._id };
5465
+ }
5466
+ }
5467
+ return { error: `No thread found matching "${shortId}"` };
5468
+ }
5469
+ return { data: match._id };
5470
+ }
5412
5471
  async function resolveAgentSlug(slug, organizationId) {
5413
5472
  const result = await convexQuery2("agents:getBySlug", { slug, ...organizationId && { organizationId } });
5414
5473
  if (result.error)
@@ -5477,7 +5536,7 @@ function formatTimestamp(ts) {
5477
5536
  return d.toTimeString().slice(0, 8);
5478
5537
  }
5479
5538
  var logsCommand = new Command14("logs").description("View and debug agent conversations");
5480
- logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
5539
+ logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--phone <number>", "Filter by phone number").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
5481
5540
  await ensureAuth2();
5482
5541
  const spinner = ora12();
5483
5542
  const orgId = getOrgId2();
@@ -5498,6 +5557,7 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5498
5557
  environment: opts.env,
5499
5558
  agentId,
5500
5559
  channel: opts.channel,
5560
+ phone: opts.phone,
5501
5561
  limit: parseInt(opts.limit, 10)
5502
5562
  });
5503
5563
  if (error || !data) {
@@ -5506,11 +5566,12 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5506
5566
  process.exit(1);
5507
5567
  }
5508
5568
  const threads = data;
5509
- spinner.succeed(`Found ${threads.length} conversations`);
5510
5569
  if (opts.json) {
5570
+ spinner.stop();
5511
5571
  console.log(JSON.stringify(threads, null, 2));
5512
5572
  return;
5513
5573
  }
5574
+ spinner.succeed(`Found ${threads.length} conversations`);
5514
5575
  console.log();
5515
5576
  renderTable([
5516
5577
  { key: "id", label: "ID", width: 14 },
@@ -5532,37 +5593,86 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5532
5593
  }));
5533
5594
  console.log();
5534
5595
  });
5535
- logsCommand.command("view <thread-id>").description("View conversation messages").option("--exec", "Include execution details").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (threadId, opts) => {
5596
+ logsCommand.command("view <thread-id>").description("View conversation messages").option("--env <environment>", "Environment hint for resolving short IDs").option("--exec", "Include execution details").option("--verbose", "Show full tool call arguments and results").option("--tail", "Show most recent messages (use with --limit)").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (rawThreadId, opts) => {
5536
5597
  await ensureAuth2();
5537
5598
  const spinner = ora12();
5599
+ spinner.start("Resolving thread");
5600
+ const resolved = await resolveThreadId(rawThreadId, opts.env);
5601
+ if (resolved.error || !resolved.data) {
5602
+ spinner.fail("Thread not found");
5603
+ console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
5604
+ process.exit(1);
5605
+ }
5606
+ const threadId = resolved.data;
5607
+ spinner.stop();
5538
5608
  spinner.start("Fetching conversation");
5539
- const { data, error } = await queryThreadDetail(threadId, parseInt(opts.limit, 10));
5609
+ const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
5610
+ const { data, error } = await queryThreadDetail(threadId, fetchLimit);
5540
5611
  if (error || !data) {
5541
5612
  spinner.fail("Failed to fetch conversation");
5542
5613
  console.log(chalk16.red("Error:"), error || "Thread not found");
5543
5614
  process.exit(1);
5544
5615
  }
5545
- spinner.succeed("Conversation loaded");
5616
+ spinner.stop();
5546
5617
  const result = data;
5618
+ let executions = [];
5619
+ if (opts.exec) {
5620
+ const execResult = await queryThreadExecutions(threadId);
5621
+ if (execResult.data) {
5622
+ executions = execResult.data;
5623
+ }
5624
+ }
5547
5625
  if (opts.json) {
5548
- console.log(JSON.stringify(result, null, 2));
5626
+ console.log(JSON.stringify(opts.exec ? { ...result, executions } : result, null, 2));
5549
5627
  return;
5550
5628
  }
5629
+ const truncLen = opts.verbose ? 1e4 : 500;
5551
5630
  console.log();
5552
5631
  console.log(chalk16.bold(`Thread: ${result._id}`));
5553
5632
  console.log(chalk16.gray(` Environment: ${result.environment ?? "unknown"} Channel: ${result.channel ?? "api"}`));
5554
- console.log(chalk16.gray("\u2500".repeat(60)));
5555
- const messages = result.messages ?? [];
5633
+ console.log(chalk16.gray("\u2500".repeat(80)));
5634
+ let messages = result.messages ?? [];
5635
+ if (opts.tail) {
5636
+ const limit = parseInt(opts.limit, 10);
5637
+ if (messages.length > limit) {
5638
+ messages = messages.slice(-limit);
5639
+ console.log(chalk16.dim(` ... ${messages.length} earlier messages hidden (showing last ${limit})`));
5640
+ }
5641
+ }
5642
+ const execByTime = new Map;
5643
+ for (const exec of executions) {
5644
+ const ts = exec.createdAt ?? exec._creationTime ?? 0;
5645
+ execByTime.set(ts, exec);
5646
+ }
5556
5647
  for (let i = 0;i < messages.length; i++) {
5557
5648
  const msg = messages[i];
5558
5649
  const ts = formatTimestamp(msg.createdAt ?? msg._creationTime ?? Date.now());
5650
+ const msgTs = msg.createdAt ?? msg._creationTime ?? 0;
5559
5651
  const role = msg.role;
5560
5652
  const content = msg.content ?? "";
5561
5653
  const toolCalls = msg.toolCalls;
5654
+ const attachments = msg.attachments;
5655
+ const channelData = msg.channelData;
5562
5656
  if (role === "user") {
5563
5657
  console.log();
5564
5658
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.cyan("User")}`);
5565
5659
  console.log(` ${content}`);
5660
+ if (attachments?.length) {
5661
+ for (const att of attachments) {
5662
+ console.log(` ${chalk16.magenta(`\uD83D\uDCCE ${att.type}`)} ${att.fileName ?? ""} ${chalk16.dim(att.mimeType ?? "")}`);
5663
+ console.log(` ${chalk16.dim(` url: ${att.url?.slice(0, 120)}`)}`);
5664
+ if (att.attachmentId)
5665
+ console.log(` ${chalk16.dim(` attachmentId: ${att.attachmentId}`)}`);
5666
+ }
5667
+ }
5668
+ if (channelData && typeof channelData === "object") {
5669
+ const cdType = channelData.type;
5670
+ const mediaStorageId = channelData.mediaStorageId;
5671
+ const mediaDirectUrl = channelData.mediaDirectUrl;
5672
+ if (cdType && cdType !== "text") {
5673
+ console.log(` ${chalk16.dim(` channel: ${cdType}${mediaStorageId ? ` storageId:${mediaStorageId}` : ""}${mediaDirectUrl ? ` directUrl:${String(mediaDirectUrl).slice(0, 80)}` : ""}`)}`);
5674
+ }
5675
+ }
5566
5676
  } else if (role === "assistant" && toolCalls?.length) {
5567
5677
  console.log();
5568
5678
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
@@ -5570,57 +5680,44 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
5570
5680
  console.log(` ${content}`);
5571
5681
  for (const call of toolCalls) {
5572
5682
  console.log(` ${chalk16.yellow("Tool: " + call.name)}`);
5573
- console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, 200))}`);
5683
+ console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, truncLen))}`);
5574
5684
  }
5575
5685
  } else if (role === "assistant") {
5576
5686
  console.log();
5577
5687
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
5578
5688
  console.log(` ${content}`);
5579
5689
  } else if (role === "tool") {
5580
- console.log(` ${chalk16.dim("\u2190 " + content.slice(0, 200))}`);
5690
+ console.log(` ${chalk16.dim("\u2190 " + content.slice(0, truncLen))}`);
5581
5691
  } else if (role === "system") {
5582
5692
  console.log();
5583
5693
  console.log(` ${chalk16.dim("[System] " + content.slice(0, 100))}`);
5584
5694
  }
5585
- }
5586
- console.log();
5587
- if (opts.exec) {
5588
- spinner.start("Fetching executions");
5589
- const execResult = await queryThreadExecutions(threadId);
5590
- if (execResult.error || !execResult.data) {
5591
- spinner.fail("Failed to fetch executions");
5592
- console.log(chalk16.red("Error:"), execResult.error);
5593
- return;
5594
- }
5595
- spinner.succeed("Executions loaded");
5596
- const executions = execResult.data;
5597
- console.log();
5598
- console.log(chalk16.bold("Executions"));
5599
- console.log(chalk16.gray("\u2500".repeat(60)));
5600
- for (const exec of executions) {
5601
- const status = exec.status;
5602
- const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
5603
- const toolCallDetails = exec.toolCallDetails;
5604
- console.log();
5605
- console.log(` ${chalk16.gray("Status:")} ${statusColor(status)}`);
5606
- if (exec.model)
5607
- console.log(` ${chalk16.gray("Model:")} ${exec.model}`);
5608
- if (exec.inputTokens || exec.outputTokens)
5609
- console.log(` ${chalk16.gray("Tokens:")} ${exec.inputTokens ?? 0} in / ${exec.outputTokens ?? 0} out`);
5610
- if (exec.durationMs)
5611
- console.log(` ${chalk16.gray("Duration:")} ${exec.durationMs}ms`);
5612
- if (toolCallDetails?.length) {
5613
- console.log(` ${chalk16.gray("Tools:")} ${toolCallDetails.length} calls`);
5614
- for (const tc of toolCallDetails) {
5615
- console.log(` ${tc.name} (${tc.durationMs}ms) -> ${tc.status}`);
5695
+ if (opts.exec && role === "assistant" && toolCalls?.length) {
5696
+ let closestExec;
5697
+ let closestDiff = Infinity;
5698
+ for (const exec of executions) {
5699
+ const execTs = exec.createdAt ?? exec._creationTime ?? 0;
5700
+ const diff = Math.abs(execTs - msgTs);
5701
+ if (diff < closestDiff) {
5702
+ closestDiff = diff;
5703
+ closestExec = exec;
5616
5704
  }
5617
5705
  }
5618
- if (exec.errorMessage) {
5619
- console.log(` ${chalk16.red("Error:")} ${exec.errorMessage}`);
5706
+ if (closestExec && closestDiff < 30000) {
5707
+ const status = closestExec.status;
5708
+ const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
5709
+ const model = closestExec.model;
5710
+ const duration = closestExec.durationMs;
5711
+ const inputTokens = closestExec.inputTokens;
5712
+ const outputTokens = closestExec.outputTokens;
5713
+ console.log(` ${chalk16.dim(` exec: ${statusColor(status)} ${model ?? ""} ${inputTokens ?? 0}in/${outputTokens ?? 0}out ${duration ?? 0}ms`)}`);
5714
+ if (closestExec.errorMessage) {
5715
+ console.log(` ${chalk16.red(` error: ${closestExec.errorMessage}`)}`);
5716
+ }
5620
5717
  }
5621
5718
  }
5622
- console.log();
5623
5719
  }
5720
+ console.log();
5624
5721
  });
5625
5722
 
5626
5723
  // src/cli/commands/eval.ts
@@ -6978,6 +7075,34 @@ async function listTriggerExecutions(options) {
6978
7075
  async function getTriggerExecutionDetail(eventId) {
6979
7076
  return convexQuery6("triggers:getExecutionDetail", { eventId });
6980
7077
  }
7078
+ async function convexAction3(path, args) {
7079
+ const token = getToken6();
7080
+ const response = await fetch(`${CONVEX_URL}/api/action`, {
7081
+ method: "POST",
7082
+ headers: {
7083
+ "Content-Type": "application/json",
7084
+ Authorization: `Bearer ${token}`
7085
+ },
7086
+ body: JSON.stringify({ path, args })
7087
+ });
7088
+ const text = await response.text();
7089
+ let json;
7090
+ try {
7091
+ json = JSON.parse(text);
7092
+ } catch {
7093
+ throw new Error(text || `HTTP ${response.status}`);
7094
+ }
7095
+ if (!response.ok) {
7096
+ throw new Error(json.errorData?.message || json.errorMessage || text);
7097
+ }
7098
+ if (json.status === "error") {
7099
+ throw new Error(json.errorMessage || "Unknown error from Convex");
7100
+ }
7101
+ return json.value;
7102
+ }
7103
+ async function retryImmediateExecution(eventId, environment) {
7104
+ return convexAction3("triggers:retryImmediateExecution", { eventId, environment });
7105
+ }
6981
7106
 
6982
7107
  // src/cli/commands/triggers.ts
6983
7108
  async function ensureAuth5() {
@@ -7623,6 +7748,41 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
7623
7748
  process.exit(1);
7624
7749
  }
7625
7750
  });
7751
+ triggersCommand.command("retry-event <event-id>").description("Retry a failed immediate trigger execution").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (eventId, opts) => {
7752
+ await ensureAuth5();
7753
+ const spinner = ora14();
7754
+ const environment = opts.env;
7755
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7756
+ const readline = await import("readline");
7757
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7758
+ await new Promise((resolve) => {
7759
+ rl.question(chalk20.yellow(`WARNING: Retrying execution in PRODUCTION environment.
7760
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7761
+ });
7762
+ rl.close();
7763
+ }
7764
+ try {
7765
+ spinner.start("Retrying failed execution...");
7766
+ const result = await retryImmediateExecution(eventId, environment);
7767
+ if (result.success) {
7768
+ spinner.succeed(chalk20.green(`Execution retried successfully`));
7769
+ } else {
7770
+ spinner.fail(chalk20.red(`Execution retry failed again`));
7771
+ }
7772
+ if (opts.json) {
7773
+ console.log(JSON.stringify(result));
7774
+ }
7775
+ } catch (err) {
7776
+ const message = err instanceof Error ? err.message : String(err);
7777
+ spinner.fail("Failed to retry execution");
7778
+ if (opts.json) {
7779
+ console.log(JSON.stringify({ success: false, error: message }));
7780
+ } else {
7781
+ console.log(chalk20.red("Error:"), message);
7782
+ }
7783
+ process.exit(1);
7784
+ }
7785
+ });
7626
7786
 
7627
7787
  // src/cli/commands/compile-prompt.ts
7628
7788
  import { Command as Command19 } from "commander";
@@ -8182,7 +8342,7 @@ var chatCommand = new Command21("chat").description("Chat with an agent").argume
8182
8342
  // package.json
8183
8343
  var package_default = {
8184
8344
  name: "struere",
8185
- version: "0.11.2",
8345
+ version: "0.12.0",
8186
8346
  description: "Build, test, and deploy AI agents",
8187
8347
  keywords: [
8188
8348
  "ai",
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA6EnC,eAAO,MAAM,WAAW,SAC4B,CAAA"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8EnC,eAAO,MAAM,WAAW,SAC4B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA0KnC,eAAO,MAAM,eAAe,SACyB,CAAA"}
1
+ {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA2KnC,eAAO,MAAM,eAAe,SACyB,CAAA"}
package/dist/cli/index.js CHANGED
@@ -33,12 +33,7 @@ function loadCredentials() {
33
33
  }
34
34
  try {
35
35
  const data = readFileSync(CREDENTIALS_FILE, "utf-8");
36
- const credentials = JSON.parse(data);
37
- if (new Date(credentials.expiresAt) < new Date) {
38
- clearCredentials();
39
- return null;
40
- }
41
- return credentials;
36
+ return JSON.parse(data);
42
37
  } catch {
43
38
  return null;
44
39
  }
@@ -936,7 +931,7 @@ function getTsConfig() {
936
931
  rootDir: ".",
937
932
  types: ["bun-types"],
938
933
  paths: {
939
- struere: ["./.struere/index.d.ts"]
934
+ struere: ["./.struere"]
940
935
  }
941
936
  },
942
937
  include: ["**/*.ts"],
@@ -5364,10 +5359,13 @@ function getToken2() {
5364
5359
  return apiKey || credentials?.token || null;
5365
5360
  }
5366
5361
  async function convexQuery2(path, args) {
5367
- const token = getToken2();
5368
- if (!token)
5369
- return { error: "Not authenticated" };
5370
- const response = await fetch(`${CONVEX_URL}/api/query`, {
5362
+ let token = getToken2();
5363
+ if (!token) {
5364
+ token = await refreshToken();
5365
+ if (!token)
5366
+ return { error: "Not authenticated. Run `struere login`." };
5367
+ }
5368
+ let response = await fetch(`${CONVEX_URL}/api/query`, {
5371
5369
  method: "POST",
5372
5370
  headers: {
5373
5371
  "Content-Type": "application/json",
@@ -5375,6 +5373,19 @@ async function convexQuery2(path, args) {
5375
5373
  },
5376
5374
  body: JSON.stringify({ path, args })
5377
5375
  });
5376
+ if (response.status === 401 || response.status === 403) {
5377
+ const refreshed = await refreshToken();
5378
+ if (refreshed) {
5379
+ response = await fetch(`${CONVEX_URL}/api/query`, {
5380
+ method: "POST",
5381
+ headers: {
5382
+ "Content-Type": "application/json",
5383
+ Authorization: `Bearer ${refreshed}`
5384
+ },
5385
+ body: JSON.stringify({ path, args })
5386
+ });
5387
+ }
5388
+ }
5378
5389
  const text = await response.text();
5379
5390
  let json;
5380
5391
  try {
@@ -5383,22 +5394,45 @@ async function convexQuery2(path, args) {
5383
5394
  return { error: text || `HTTP ${response.status}` };
5384
5395
  }
5385
5396
  if (!response.ok) {
5386
- const msg = json.errorData?.message || json.message || json.errorMessage || text;
5387
- return { error: String(msg) };
5397
+ const errorData = json.errorData;
5398
+ const msg = errorData?.message || json.message || json.errorMessage || text;
5399
+ const msgStr = String(msg);
5400
+ if (msgStr.includes("OIDC") || msgStr.includes("token")) {
5401
+ return { error: "Session expired. Run `struere logout && struere login`." };
5402
+ }
5403
+ return { error: msgStr };
5388
5404
  }
5389
5405
  if (json.status === "success")
5390
5406
  return { data: json.value };
5391
- if (json.status === "error")
5392
- return { error: String(json.errorMessage || "Unknown error") };
5407
+ if (json.status === "error") {
5408
+ const errMsg = String(json.errorMessage || "Unknown error");
5409
+ if (errMsg.includes("OIDC") || errMsg.includes("token")) {
5410
+ return { error: "Session expired. Run `struere logout && struere login`." };
5411
+ }
5412
+ return { error: errMsg };
5413
+ }
5393
5414
  return { error: `Unexpected response: ${text}` };
5394
5415
  }
5395
5416
  async function queryThreads(options) {
5396
- return convexQuery2("threads:listWithPreviews", {
5417
+ const result = await convexQuery2("threads:listWithPreviews", {
5397
5418
  environment: options.environment,
5398
5419
  ...options.agentId && { agentId: options.agentId },
5399
5420
  ...options.channel && { channel: options.channel },
5400
5421
  ...options.limit && { limit: options.limit }
5401
5422
  });
5423
+ if (result.error || !result.data)
5424
+ return result;
5425
+ if (options.phone) {
5426
+ const threads = result.data;
5427
+ const filtered = threads.filter((t) => {
5428
+ const externalId = t.externalId ?? "";
5429
+ const params = t.channelParams;
5430
+ const phone = params?.phoneNumber ?? "";
5431
+ return externalId.includes(options.phone) || phone.includes(options.phone);
5432
+ });
5433
+ return { data: filtered };
5434
+ }
5435
+ return result;
5402
5436
  }
5403
5437
  async function queryThreadDetail(threadId, messageLimit) {
5404
5438
  return convexQuery2("threads:getWithMessages", {
@@ -5409,6 +5443,31 @@ async function queryThreadDetail(threadId, messageLimit) {
5409
5443
  async function queryThreadExecutions(threadId) {
5410
5444
  return convexQuery2("executions:getByThread", { threadId });
5411
5445
  }
5446
+ async function resolveThreadId(shortId, environment) {
5447
+ if (shortId.includes("|") || shortId.length > 20) {
5448
+ return { data: shortId };
5449
+ }
5450
+ const result = await queryThreads({ environment: environment ?? "development", limit: 100 });
5451
+ if (result.error || !result.data)
5452
+ return { error: result.error ?? "Could not fetch threads" };
5453
+ const threads = result.data;
5454
+ const match = threads.find((t) => t._id.endsWith(shortId));
5455
+ if (!match) {
5456
+ for (const env of ["production", "development", "eval"]) {
5457
+ if (env === (environment ?? "development"))
5458
+ continue;
5459
+ const envResult = await queryThreads({ environment: env, limit: 100 });
5460
+ if (envResult.data) {
5461
+ const envThreads = envResult.data;
5462
+ const envMatch = envThreads.find((t) => t._id.endsWith(shortId));
5463
+ if (envMatch)
5464
+ return { data: envMatch._id };
5465
+ }
5466
+ }
5467
+ return { error: `No thread found matching "${shortId}"` };
5468
+ }
5469
+ return { data: match._id };
5470
+ }
5412
5471
  async function resolveAgentSlug(slug, organizationId) {
5413
5472
  const result = await convexQuery2("agents:getBySlug", { slug, ...organizationId && { organizationId } });
5414
5473
  if (result.error)
@@ -5477,7 +5536,7 @@ function formatTimestamp(ts) {
5477
5536
  return d.toTimeString().slice(0, 8);
5478
5537
  }
5479
5538
  var logsCommand = new Command14("logs").description("View and debug agent conversations");
5480
- logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
5539
+ logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--phone <number>", "Filter by phone number").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
5481
5540
  await ensureAuth2();
5482
5541
  const spinner = ora12();
5483
5542
  const orgId = getOrgId2();
@@ -5498,6 +5557,7 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5498
5557
  environment: opts.env,
5499
5558
  agentId,
5500
5559
  channel: opts.channel,
5560
+ phone: opts.phone,
5501
5561
  limit: parseInt(opts.limit, 10)
5502
5562
  });
5503
5563
  if (error || !data) {
@@ -5506,11 +5566,12 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5506
5566
  process.exit(1);
5507
5567
  }
5508
5568
  const threads = data;
5509
- spinner.succeed(`Found ${threads.length} conversations`);
5510
5569
  if (opts.json) {
5570
+ spinner.stop();
5511
5571
  console.log(JSON.stringify(threads, null, 2));
5512
5572
  return;
5513
5573
  }
5574
+ spinner.succeed(`Found ${threads.length} conversations`);
5514
5575
  console.log();
5515
5576
  renderTable([
5516
5577
  { key: "id", label: "ID", width: 14 },
@@ -5532,37 +5593,86 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
5532
5593
  }));
5533
5594
  console.log();
5534
5595
  });
5535
- logsCommand.command("view <thread-id>").description("View conversation messages").option("--exec", "Include execution details").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (threadId, opts) => {
5596
+ logsCommand.command("view <thread-id>").description("View conversation messages").option("--env <environment>", "Environment hint for resolving short IDs").option("--exec", "Include execution details").option("--verbose", "Show full tool call arguments and results").option("--tail", "Show most recent messages (use with --limit)").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (rawThreadId, opts) => {
5536
5597
  await ensureAuth2();
5537
5598
  const spinner = ora12();
5599
+ spinner.start("Resolving thread");
5600
+ const resolved = await resolveThreadId(rawThreadId, opts.env);
5601
+ if (resolved.error || !resolved.data) {
5602
+ spinner.fail("Thread not found");
5603
+ console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
5604
+ process.exit(1);
5605
+ }
5606
+ const threadId = resolved.data;
5607
+ spinner.stop();
5538
5608
  spinner.start("Fetching conversation");
5539
- const { data, error } = await queryThreadDetail(threadId, parseInt(opts.limit, 10));
5609
+ const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
5610
+ const { data, error } = await queryThreadDetail(threadId, fetchLimit);
5540
5611
  if (error || !data) {
5541
5612
  spinner.fail("Failed to fetch conversation");
5542
5613
  console.log(chalk16.red("Error:"), error || "Thread not found");
5543
5614
  process.exit(1);
5544
5615
  }
5545
- spinner.succeed("Conversation loaded");
5616
+ spinner.stop();
5546
5617
  const result = data;
5618
+ let executions = [];
5619
+ if (opts.exec) {
5620
+ const execResult = await queryThreadExecutions(threadId);
5621
+ if (execResult.data) {
5622
+ executions = execResult.data;
5623
+ }
5624
+ }
5547
5625
  if (opts.json) {
5548
- console.log(JSON.stringify(result, null, 2));
5626
+ console.log(JSON.stringify(opts.exec ? { ...result, executions } : result, null, 2));
5549
5627
  return;
5550
5628
  }
5629
+ const truncLen = opts.verbose ? 1e4 : 500;
5551
5630
  console.log();
5552
5631
  console.log(chalk16.bold(`Thread: ${result._id}`));
5553
5632
  console.log(chalk16.gray(` Environment: ${result.environment ?? "unknown"} Channel: ${result.channel ?? "api"}`));
5554
- console.log(chalk16.gray("\u2500".repeat(60)));
5555
- const messages = result.messages ?? [];
5633
+ console.log(chalk16.gray("\u2500".repeat(80)));
5634
+ let messages = result.messages ?? [];
5635
+ if (opts.tail) {
5636
+ const limit = parseInt(opts.limit, 10);
5637
+ if (messages.length > limit) {
5638
+ messages = messages.slice(-limit);
5639
+ console.log(chalk16.dim(` ... ${messages.length} earlier messages hidden (showing last ${limit})`));
5640
+ }
5641
+ }
5642
+ const execByTime = new Map;
5643
+ for (const exec of executions) {
5644
+ const ts = exec.createdAt ?? exec._creationTime ?? 0;
5645
+ execByTime.set(ts, exec);
5646
+ }
5556
5647
  for (let i = 0;i < messages.length; i++) {
5557
5648
  const msg = messages[i];
5558
5649
  const ts = formatTimestamp(msg.createdAt ?? msg._creationTime ?? Date.now());
5650
+ const msgTs = msg.createdAt ?? msg._creationTime ?? 0;
5559
5651
  const role = msg.role;
5560
5652
  const content = msg.content ?? "";
5561
5653
  const toolCalls = msg.toolCalls;
5654
+ const attachments = msg.attachments;
5655
+ const channelData = msg.channelData;
5562
5656
  if (role === "user") {
5563
5657
  console.log();
5564
5658
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.cyan("User")}`);
5565
5659
  console.log(` ${content}`);
5660
+ if (attachments?.length) {
5661
+ for (const att of attachments) {
5662
+ console.log(` ${chalk16.magenta(`\uD83D\uDCCE ${att.type}`)} ${att.fileName ?? ""} ${chalk16.dim(att.mimeType ?? "")}`);
5663
+ console.log(` ${chalk16.dim(` url: ${att.url?.slice(0, 120)}`)}`);
5664
+ if (att.attachmentId)
5665
+ console.log(` ${chalk16.dim(` attachmentId: ${att.attachmentId}`)}`);
5666
+ }
5667
+ }
5668
+ if (channelData && typeof channelData === "object") {
5669
+ const cdType = channelData.type;
5670
+ const mediaStorageId = channelData.mediaStorageId;
5671
+ const mediaDirectUrl = channelData.mediaDirectUrl;
5672
+ if (cdType && cdType !== "text") {
5673
+ console.log(` ${chalk16.dim(` channel: ${cdType}${mediaStorageId ? ` storageId:${mediaStorageId}` : ""}${mediaDirectUrl ? ` directUrl:${String(mediaDirectUrl).slice(0, 80)}` : ""}`)}`);
5674
+ }
5675
+ }
5566
5676
  } else if (role === "assistant" && toolCalls?.length) {
5567
5677
  console.log();
5568
5678
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
@@ -5570,57 +5680,44 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
5570
5680
  console.log(` ${content}`);
5571
5681
  for (const call of toolCalls) {
5572
5682
  console.log(` ${chalk16.yellow("Tool: " + call.name)}`);
5573
- console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, 200))}`);
5683
+ console.log(` ${chalk16.dim("\u2192 " + JSON.stringify(call.arguments).slice(0, truncLen))}`);
5574
5684
  }
5575
5685
  } else if (role === "assistant") {
5576
5686
  console.log();
5577
5687
  console.log(` ${chalk16.gray(`[${ts}]`)} ${chalk16.green("Agent")}`);
5578
5688
  console.log(` ${content}`);
5579
5689
  } else if (role === "tool") {
5580
- console.log(` ${chalk16.dim("\u2190 " + content.slice(0, 200))}`);
5690
+ console.log(` ${chalk16.dim("\u2190 " + content.slice(0, truncLen))}`);
5581
5691
  } else if (role === "system") {
5582
5692
  console.log();
5583
5693
  console.log(` ${chalk16.dim("[System] " + content.slice(0, 100))}`);
5584
5694
  }
5585
- }
5586
- console.log();
5587
- if (opts.exec) {
5588
- spinner.start("Fetching executions");
5589
- const execResult = await queryThreadExecutions(threadId);
5590
- if (execResult.error || !execResult.data) {
5591
- spinner.fail("Failed to fetch executions");
5592
- console.log(chalk16.red("Error:"), execResult.error);
5593
- return;
5594
- }
5595
- spinner.succeed("Executions loaded");
5596
- const executions = execResult.data;
5597
- console.log();
5598
- console.log(chalk16.bold("Executions"));
5599
- console.log(chalk16.gray("\u2500".repeat(60)));
5600
- for (const exec of executions) {
5601
- const status = exec.status;
5602
- const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
5603
- const toolCallDetails = exec.toolCallDetails;
5604
- console.log();
5605
- console.log(` ${chalk16.gray("Status:")} ${statusColor(status)}`);
5606
- if (exec.model)
5607
- console.log(` ${chalk16.gray("Model:")} ${exec.model}`);
5608
- if (exec.inputTokens || exec.outputTokens)
5609
- console.log(` ${chalk16.gray("Tokens:")} ${exec.inputTokens ?? 0} in / ${exec.outputTokens ?? 0} out`);
5610
- if (exec.durationMs)
5611
- console.log(` ${chalk16.gray("Duration:")} ${exec.durationMs}ms`);
5612
- if (toolCallDetails?.length) {
5613
- console.log(` ${chalk16.gray("Tools:")} ${toolCallDetails.length} calls`);
5614
- for (const tc of toolCallDetails) {
5615
- console.log(` ${tc.name} (${tc.durationMs}ms) -> ${tc.status}`);
5695
+ if (opts.exec && role === "assistant" && toolCalls?.length) {
5696
+ let closestExec;
5697
+ let closestDiff = Infinity;
5698
+ for (const exec of executions) {
5699
+ const execTs = exec.createdAt ?? exec._creationTime ?? 0;
5700
+ const diff = Math.abs(execTs - msgTs);
5701
+ if (diff < closestDiff) {
5702
+ closestDiff = diff;
5703
+ closestExec = exec;
5616
5704
  }
5617
5705
  }
5618
- if (exec.errorMessage) {
5619
- console.log(` ${chalk16.red("Error:")} ${exec.errorMessage}`);
5706
+ if (closestExec && closestDiff < 30000) {
5707
+ const status = closestExec.status;
5708
+ const statusColor = status === "success" ? chalk16.green : status === "error" ? chalk16.red : chalk16.yellow;
5709
+ const model = closestExec.model;
5710
+ const duration = closestExec.durationMs;
5711
+ const inputTokens = closestExec.inputTokens;
5712
+ const outputTokens = closestExec.outputTokens;
5713
+ console.log(` ${chalk16.dim(` exec: ${statusColor(status)} ${model ?? ""} ${inputTokens ?? 0}in/${outputTokens ?? 0}out ${duration ?? 0}ms`)}`);
5714
+ if (closestExec.errorMessage) {
5715
+ console.log(` ${chalk16.red(` error: ${closestExec.errorMessage}`)}`);
5716
+ }
5620
5717
  }
5621
5718
  }
5622
- console.log();
5623
5719
  }
5720
+ console.log();
5624
5721
  });
5625
5722
 
5626
5723
  // src/cli/commands/eval.ts
@@ -6978,6 +7075,34 @@ async function listTriggerExecutions(options) {
6978
7075
  async function getTriggerExecutionDetail(eventId) {
6979
7076
  return convexQuery6("triggers:getExecutionDetail", { eventId });
6980
7077
  }
7078
+ async function convexAction3(path, args) {
7079
+ const token = getToken6();
7080
+ const response = await fetch(`${CONVEX_URL}/api/action`, {
7081
+ method: "POST",
7082
+ headers: {
7083
+ "Content-Type": "application/json",
7084
+ Authorization: `Bearer ${token}`
7085
+ },
7086
+ body: JSON.stringify({ path, args })
7087
+ });
7088
+ const text = await response.text();
7089
+ let json;
7090
+ try {
7091
+ json = JSON.parse(text);
7092
+ } catch {
7093
+ throw new Error(text || `HTTP ${response.status}`);
7094
+ }
7095
+ if (!response.ok) {
7096
+ throw new Error(json.errorData?.message || json.errorMessage || text);
7097
+ }
7098
+ if (json.status === "error") {
7099
+ throw new Error(json.errorMessage || "Unknown error from Convex");
7100
+ }
7101
+ return json.value;
7102
+ }
7103
+ async function retryImmediateExecution(eventId, environment) {
7104
+ return convexAction3("triggers:retryImmediateExecution", { eventId, environment });
7105
+ }
6981
7106
 
6982
7107
  // src/cli/commands/triggers.ts
6983
7108
  async function ensureAuth5() {
@@ -7623,6 +7748,41 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
7623
7748
  process.exit(1);
7624
7749
  }
7625
7750
  });
7751
+ triggersCommand.command("retry-event <event-id>").description("Retry a failed immediate trigger execution").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (eventId, opts) => {
7752
+ await ensureAuth5();
7753
+ const spinner = ora14();
7754
+ const environment = opts.env;
7755
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7756
+ const readline = await import("readline");
7757
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7758
+ await new Promise((resolve) => {
7759
+ rl.question(chalk20.yellow(`WARNING: Retrying execution in PRODUCTION environment.
7760
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7761
+ });
7762
+ rl.close();
7763
+ }
7764
+ try {
7765
+ spinner.start("Retrying failed execution...");
7766
+ const result = await retryImmediateExecution(eventId, environment);
7767
+ if (result.success) {
7768
+ spinner.succeed(chalk20.green(`Execution retried successfully`));
7769
+ } else {
7770
+ spinner.fail(chalk20.red(`Execution retry failed again`));
7771
+ }
7772
+ if (opts.json) {
7773
+ console.log(JSON.stringify(result));
7774
+ }
7775
+ } catch (err) {
7776
+ const message = err instanceof Error ? err.message : String(err);
7777
+ spinner.fail("Failed to retry execution");
7778
+ if (opts.json) {
7779
+ console.log(JSON.stringify({ success: false, error: message }));
7780
+ } else {
7781
+ console.log(chalk20.red("Error:"), message);
7782
+ }
7783
+ process.exit(1);
7784
+ }
7785
+ });
7626
7786
 
7627
7787
  // src/cli/commands/compile-prompt.ts
7628
7788
  import { Command as Command19 } from "commander";
@@ -8182,7 +8342,7 @@ var chatCommand = new Command21("chat").description("Chat with an agent").argume
8182
8342
  // package.json
8183
8343
  var package_default = {
8184
8344
  name: "struere",
8185
- version: "0.11.2",
8345
+ version: "0.12.0",
8186
8346
  description: "Build, test, and deploy AI agents",
8187
8347
  keywords: [
8188
8348
  "ai",
@@ -17,6 +17,7 @@ export interface Credentials {
17
17
  }
18
18
  export declare function saveCredentials(credentials: Credentials): void;
19
19
  export declare function loadCredentials(): Credentials | null;
20
+ export declare function isTokenExpired(): boolean;
20
21
  export declare function clearCredentials(): void;
21
22
  export declare function getApiKey(): string | null;
22
23
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,CAAC,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAG9D;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAkBpD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAMzC"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/credentials.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAA;QACV,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,cAAc,CAAC,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,YAAY,CAAC,EAAE;QACb,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAG9D;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAWpD;AAED,wBAAgB,cAAc,IAAI,OAAO,CAIxC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAMzC"}
@@ -2,6 +2,7 @@ export declare function queryThreads(options: {
2
2
  environment: string;
3
3
  agentId?: string;
4
4
  channel?: string;
5
+ phone?: string;
5
6
  limit?: number;
6
7
  }): Promise<{
7
8
  data?: unknown;
@@ -15,6 +16,10 @@ export declare function queryThreadExecutions(threadId: string): Promise<{
15
16
  data?: unknown;
16
17
  error?: string;
17
18
  }>;
19
+ export declare function resolveThreadId(shortId: string, environment?: string): Promise<{
20
+ data?: string;
21
+ error?: string;
22
+ }>;
18
23
  export declare function resolveAgentSlug(slug: string, organizationId?: string): Promise<{
19
24
  data?: string;
20
25
  error?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/logs.ts"],"names":[],"mappings":"AAwCA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAO9C;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAK5H;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAEzG;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxH"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/logs.ts"],"names":[],"mappings":"AAqEA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB9C;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAK5H;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAEzG;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqBvH;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxH"}
@@ -104,5 +104,8 @@ export declare function listTriggerExecutions(options: {
104
104
  limit?: number;
105
105
  }): Promise<TriggerExecution[]>;
106
106
  export declare function getTriggerExecutionDetail(eventId: string): Promise<TriggerExecution | null>;
107
+ export declare function retryImmediateExecution(eventId: string, environment: Environment): Promise<{
108
+ success: boolean;
109
+ }>;
107
110
  export {};
108
111
  //# sourceMappingURL=triggers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/triggers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"triggers.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/triggers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "struere",
3
- "version": "0.11.2",
3
+ "version": "0.12.0",
4
4
  "description": "Build, test, and deploy AI agents",
5
5
  "keywords": [
6
6
  "ai",