struere 0.10.6 → 0.11.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.
@@ -945,7 +945,7 @@ slug: "basic-agent-tests"
945
945
  agent: "${agentSlug}"
946
946
  description: "Verify agent responds correctly and uses tools appropriately"
947
947
  tags: ["smoke-test"]
948
- judgeModel: "xai/grok-4-1-fast"
948
+ judgeModel: "openai/gpt-5-mini"
949
949
  judgePrompt: "Evaluate whether the agent responds correctly and uses appropriate tools. Be lenient on phrasing but strict on factual accuracy."
950
950
 
951
951
  cases:
@@ -1002,7 +1002,7 @@ slug: "${slug}"
1002
1002
  agent: "${agentSlug}"
1003
1003
  description: "TODO: Describe what this eval suite tests"
1004
1004
  tags: []
1005
- judgeModel: "xai/grok-4-1-fast"
1005
+ judgeModel: "openai/gpt-5-mini"
1006
1006
  judgePrompt: "TODO: Custom instructions for the judge (e.g. strictness level, focus areas)"
1007
1007
 
1008
1008
  cases:
@@ -1102,7 +1102,7 @@ export default defineAgent({
1102
1102
  version: "0.1.0",
1103
1103
  description: "${displayName} Agent",
1104
1104
  model: {
1105
- model: "xai/grok-4-1-fast",
1105
+ model: "openai/gpt-5-mini",
1106
1106
  temperature: 0.7,
1107
1107
  maxTokens: 4096,
1108
1108
  },
@@ -1435,7 +1435,7 @@ function defineAgent(config) {
1435
1435
  if (!config.systemPrompt) throw new Error('System prompt is required')
1436
1436
  return {
1437
1437
  model: {
1438
- model: 'xai/grok-4-1-fast',
1438
+ model: 'openai/gpt-5-mini',
1439
1439
  temperature: 0.7,
1440
1440
  maxTokens: 4096,
1441
1441
  },
@@ -1795,8 +1795,8 @@ function generateTypeDeclarations(cwd) {
1795
1795
  import { Command as Command2 } from "commander";
1796
1796
  import chalk2 from "chalk";
1797
1797
  import ora2 from "ora";
1798
- import { join as join6, dirname as dirname2 } from "path";
1799
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
1798
+ import { join as join7, dirname as dirname3 } from "path";
1799
+ import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
1800
1800
 
1801
1801
  // src/cli/utils/loader.ts
1802
1802
  import { existsSync as existsSync5, readdirSync, readFileSync as readFileSync4 } from "fs";
@@ -1924,6 +1924,43 @@ function getResourceDirectories(cwd) {
1924
1924
  };
1925
1925
  }
1926
1926
 
1927
+ // src/cli/utils/skill.ts
1928
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
1929
+ import { dirname as dirname2, join as join6 } from "path";
1930
+ var SKILL_URL = "https://docs.struere.dev/skill";
1931
+ var SKILL_PATH = ".claude/skills/struere-developer/SKILL.md";
1932
+ var FALLBACK_SKILL = `---
1933
+ name: struere-developer
1934
+ description: "Build, configure, and deploy AI agents on the Struere platform. Use when working with Struere projects (struere.json present), defining agents/data-types/roles/triggers, using the Struere SDK (defineAgent, defineData, defineRole, defineTrigger, defineTools), running struere CLI commands, calling the Struere Chat API, or debugging agent behavior."
1935
+ metadata:
1936
+ author: struere
1937
+ version: 1.0.0
1938
+ category: developer-tools
1939
+ ---
1940
+
1941
+ # Struere Developer Guide
1942
+
1943
+ Fetch the full skill from: ${SKILL_URL}
1944
+ `;
1945
+ async function installSkill(cwd) {
1946
+ const filePath = join6(cwd, SKILL_PATH);
1947
+ const dir = dirname2(filePath);
1948
+ if (!existsSync6(dir)) {
1949
+ mkdirSync4(dir, { recursive: true });
1950
+ }
1951
+ let content;
1952
+ try {
1953
+ const controller = new AbortController;
1954
+ const timeout = setTimeout(() => controller.abort(), 5000);
1955
+ const response = await fetch(SKILL_URL, { signal: controller.signal });
1956
+ clearTimeout(timeout);
1957
+ content = await response.text();
1958
+ } catch {
1959
+ content = FALLBACK_SKILL;
1960
+ }
1961
+ writeFileSync4(filePath, content);
1962
+ }
1963
+
1927
1964
  // src/cli/commands/docs.ts
1928
1965
  var TEMPLATE_URL = "https://docs.struere.dev/llms-workspace.txt";
1929
1966
  var FALLBACK_TEMPLATE = `# Struere Workspace
@@ -1998,12 +2035,12 @@ async function fetchTemplate() {
1998
2035
  }
1999
2036
  }
2000
2037
  function writeTarget(cwd, target, content) {
2001
- const filePath = join6(cwd, TARGET_FILES[target]);
2002
- const dir = dirname2(filePath);
2003
- if (!existsSync6(dir)) {
2004
- mkdirSync4(dir, { recursive: true });
2038
+ const filePath = join7(cwd, TARGET_FILES[target]);
2039
+ const dir = dirname3(filePath);
2040
+ if (!existsSync7(dir)) {
2041
+ mkdirSync5(dir, { recursive: true });
2005
2042
  }
2006
- writeFileSync4(filePath, content);
2043
+ writeFileSync5(filePath, content);
2007
2044
  }
2008
2045
  async function generateDocs(cwd, targets) {
2009
2046
  const generated = [];
@@ -2032,6 +2069,7 @@ async function generateDocs(cwd, targets) {
2032
2069
  writeTarget(cwd, target, content);
2033
2070
  generated.push(TARGET_FILES[target]);
2034
2071
  }
2072
+ await installSkill(cwd);
2035
2073
  return { generated };
2036
2074
  }
2037
2075
  var docsCommand = new Command2("docs").description("Generate AI context files (CLAUDE.md, .cursorrules, copilot-instructions) from live docs").option("--claude", "Generate CLAUDE.md only").option("--cursor", "Generate .cursorrules only").option("--copilot", "Generate .github/copilot-instructions.md only").action(async (options) => {
@@ -2314,6 +2352,7 @@ async function runInit(cwd, selectedOrg) {
2314
2352
  } catch {
2315
2353
  console.log(chalk5.yellow("\u26A0"), "Could not fetch docs for CLAUDE.md");
2316
2354
  }
2355
+ await installSkill(cwd);
2317
2356
  console.log();
2318
2357
  console.log(chalk5.green("\u2713"), "Project initialized");
2319
2358
  return true;
@@ -2417,6 +2456,7 @@ var initCommand = new Command4("init").description("Initialize a new Struere org
2417
2456
  } catch {
2418
2457
  console.log(chalk5.yellow("\u26A0"), "Could not fetch docs for CLAUDE.md");
2419
2458
  }
2459
+ await installSkill(cwd);
2420
2460
  console.log();
2421
2461
  console.log(chalk5.green("Success!"), "Project initialized");
2422
2462
  console.log();
@@ -2440,8 +2480,8 @@ import { Command as Command6 } from "commander";
2440
2480
  import chalk7 from "chalk";
2441
2481
  import ora6 from "ora";
2442
2482
  import chokidar from "chokidar";
2443
- import { join as join7 } from "path";
2444
- import { existsSync as existsSync7 } from "fs";
2483
+ import { join as join8 } from "path";
2484
+ import { existsSync as existsSync8 } from "fs";
2445
2485
 
2446
2486
  // src/cli/commands/sync.ts
2447
2487
  import { Command as Command5 } from "commander";
@@ -2615,7 +2655,7 @@ function extractAgentPayload(agent, customToolsMap) {
2615
2655
  threadContextParams: agent.threadContextParams,
2616
2656
  systemPrompt,
2617
2657
  model: {
2618
- model: agent.model?.model || "xai/grok-4-1-fast",
2658
+ model: agent.model?.model || "openai/gpt-5-mini",
2619
2659
  temperature: agent.model?.temperature,
2620
2660
  maxTokens: agent.model?.maxTokens
2621
2661
  },
@@ -3329,8 +3369,8 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
3329
3369
  }
3330
3370
  console.log();
3331
3371
  }
3332
- const claudeMdPath = join7(cwd, "CLAUDE.md");
3333
- if (!existsSync7(claudeMdPath)) {
3372
+ const claudeMdPath = join8(cwd, "CLAUDE.md");
3373
+ if (!existsSync8(claudeMdPath)) {
3334
3374
  try {
3335
3375
  const { generated } = await generateDocs(cwd, ["claude"]);
3336
3376
  if (generated.length > 0) {
@@ -3441,7 +3481,7 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
3441
3481
  dirs.evals,
3442
3482
  dirs.triggers,
3443
3483
  dirs.fixtures
3444
- ].filter((p) => existsSync7(p));
3484
+ ].filter((p) => existsSync8(p));
3445
3485
  const watcher = chokidar.watch(watchPaths, {
3446
3486
  ignoreInitial: true,
3447
3487
  ignored: [/node_modules/, /\.struere-tmp-/, /evals\/runs\//],
@@ -4254,8 +4294,8 @@ var statusCommand = new Command11("status").description("Compare local vs remote
4254
4294
  import { Command as Command12 } from "commander";
4255
4295
  import chalk13 from "chalk";
4256
4296
  import ora10 from "ora";
4257
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
4258
- import { join as join8 } from "path";
4297
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
4298
+ import { join as join9 } from "path";
4259
4299
 
4260
4300
  // src/cli/utils/generator.ts
4261
4301
  var BUILTIN_TOOLS2 = [
@@ -4625,13 +4665,13 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
4625
4665
  const created = [];
4626
4666
  const skipped = [];
4627
4667
  const ensureDir2 = (dir) => {
4628
- if (!existsSync8(dir)) {
4629
- mkdirSync5(dir, { recursive: true });
4668
+ if (!existsSync9(dir)) {
4669
+ mkdirSync6(dir, { recursive: true });
4630
4670
  }
4631
4671
  };
4632
4672
  const writeOrSkip = (relativePath, content) => {
4633
- const fullPath = join8(cwd, relativePath);
4634
- if (existsSync8(fullPath) && !options.force) {
4673
+ const fullPath = join9(cwd, relativePath);
4674
+ if (existsSync9(fullPath) && !options.force) {
4635
4675
  skipped.push(relativePath);
4636
4676
  return false;
4637
4677
  }
@@ -4639,16 +4679,16 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
4639
4679
  created.push(relativePath);
4640
4680
  return true;
4641
4681
  }
4642
- ensureDir2(join8(cwd, relativePath.split("/").slice(0, -1).join("/")));
4643
- writeFileSync5(fullPath, content);
4682
+ ensureDir2(join9(cwd, relativePath.split("/").slice(0, -1).join("/")));
4683
+ writeFileSync6(fullPath, content);
4644
4684
  created.push(relativePath);
4645
4685
  return true;
4646
4686
  };
4647
- ensureDir2(join8(cwd, "agents"));
4648
- ensureDir2(join8(cwd, "entity-types"));
4649
- ensureDir2(join8(cwd, "roles"));
4650
- ensureDir2(join8(cwd, "triggers"));
4651
- ensureDir2(join8(cwd, "tools"));
4687
+ ensureDir2(join9(cwd, "agents"));
4688
+ ensureDir2(join9(cwd, "entity-types"));
4689
+ ensureDir2(join9(cwd, "roles"));
4690
+ ensureDir2(join9(cwd, "triggers"));
4691
+ ensureDir2(join9(cwd, "tools"));
4652
4692
  const agentSlugs = [];
4653
4693
  for (const agent of state.agents) {
4654
4694
  if (!agent.systemPrompt && agent.tools.length === 0)
@@ -4700,6 +4740,7 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
4700
4740
  if (content)
4701
4741
  writeOrSkip("triggers/index.ts", content);
4702
4742
  }
4743
+ await installSkill(cwd);
4703
4744
  if (options.json) {
4704
4745
  console.log(JSON.stringify({
4705
4746
  created,
@@ -5582,8 +5623,8 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
5582
5623
  import { Command as Command15 } from "commander";
5583
5624
  import chalk17 from "chalk";
5584
5625
  import ora13 from "ora";
5585
- import { join as join9 } from "path";
5586
- import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "fs";
5626
+ import { join as join10 } from "path";
5627
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "fs";
5587
5628
 
5588
5629
  // src/cli/utils/evals.ts
5589
5630
  function getToken3() {
@@ -6016,15 +6057,15 @@ var runCommand = new Command15("run").description("Run an eval suite").argument(
6016
6057
  const agentSlug = suiteSlug;
6017
6058
  const timestamp = new Date().toISOString().replace(/:/g, "-").replace(/\.\d+Z$/, "");
6018
6059
  const folderName = `${timestamp}_${suiteSlug}`;
6019
- const outDir = join9(cwd, "evals", "runs", folderName);
6020
- mkdirSync6(outDir, { recursive: true });
6060
+ const outDir = join10(cwd, "evals", "runs", folderName);
6061
+ mkdirSync7(outDir, { recursive: true });
6021
6062
  const summaryMd = generateSummaryMd(suite.name, suite.slug, agentSlug, run, results);
6022
- writeFileSync6(join9(outDir, "_summary.md"), summaryMd);
6063
+ writeFileSync7(join10(outDir, "_summary.md"), summaryMd);
6023
6064
  for (const r of results) {
6024
6065
  const label = statusLabel(r);
6025
6066
  const fileName = `${label}_${slugify3(r.caseName)}.md`;
6026
6067
  const caseMd = generateCaseMd(r);
6027
- writeFileSync6(join9(outDir, fileName), caseMd);
6068
+ writeFileSync7(join10(outDir, fileName), caseMd);
6028
6069
  }
6029
6070
  const relativePath = `evals/runs/${folderName}/`;
6030
6071
  console.log();
@@ -6823,15 +6864,771 @@ var integrationCommand = new Command17("integration").description("Manage integr
6823
6864
  console.log();
6824
6865
  });
6825
6866
 
6826
- // src/cli/commands/compile-prompt.ts
6867
+ // src/cli/commands/triggers.ts
6827
6868
  import { Command as Command18 } from "commander";
6828
6869
  import chalk20 from "chalk";
6829
6870
  import ora14 from "ora";
6830
- var compilePromptCommand = new Command18("compile-prompt").description("Compile and preview an agent's system prompt after template processing").argument("<agent-slug>", "Agent slug to compile prompt for").option("--env <env>", "Environment: development | production", "development").option("--message <msg>", "Sample message for template context").option("--channel <channel>", "Sample channel (whatsapp, widget, api, dashboard)").option("--param <key=value...>", "Custom thread param (repeatable)", (val, acc) => {
6871
+
6872
+ // src/cli/utils/triggers.ts
6873
+ function getToken6() {
6874
+ const credentials = loadCredentials();
6875
+ const apiKey = getApiKey();
6876
+ const token = apiKey || credentials?.token;
6877
+ if (!token)
6878
+ throw new Error("Not authenticated");
6879
+ return token;
6880
+ }
6881
+ async function convexQuery6(path, args) {
6882
+ const token = getToken6();
6883
+ const response = await fetch(`${CONVEX_URL}/api/query`, {
6884
+ method: "POST",
6885
+ headers: {
6886
+ "Content-Type": "application/json",
6887
+ Authorization: `Bearer ${token}`
6888
+ },
6889
+ body: JSON.stringify({ path, args })
6890
+ });
6891
+ const text = await response.text();
6892
+ let json;
6893
+ try {
6894
+ json = JSON.parse(text);
6895
+ } catch {
6896
+ throw new Error(text || `HTTP ${response.status}`);
6897
+ }
6898
+ if (!response.ok) {
6899
+ throw new Error(json.errorData?.message || json.errorMessage || text);
6900
+ }
6901
+ if (json.status === "error") {
6902
+ throw new Error(json.errorMessage || "Unknown error from Convex");
6903
+ }
6904
+ return json.value;
6905
+ }
6906
+ async function convexMutation4(path, args) {
6907
+ const token = getToken6();
6908
+ const response = await fetch(`${CONVEX_URL}/api/mutation`, {
6909
+ method: "POST",
6910
+ headers: {
6911
+ "Content-Type": "application/json",
6912
+ Authorization: `Bearer ${token}`
6913
+ },
6914
+ body: JSON.stringify({ path, args })
6915
+ });
6916
+ const text = await response.text();
6917
+ let json;
6918
+ try {
6919
+ json = JSON.parse(text);
6920
+ } catch {
6921
+ throw new Error(text || `HTTP ${response.status}`);
6922
+ }
6923
+ if (!response.ok) {
6924
+ throw new Error(json.errorData?.message || json.errorMessage || text);
6925
+ }
6926
+ if (json.status === "error") {
6927
+ throw new Error(json.errorMessage || "Unknown error from Convex");
6928
+ }
6929
+ return json.value;
6930
+ }
6931
+ async function listTriggers(environment) {
6932
+ return convexQuery6("triggers:list", { environment });
6933
+ }
6934
+ async function getTrigger(slug, environment) {
6935
+ return convexQuery6("triggers:getBySlug", { slug, environment });
6936
+ }
6937
+ async function listTriggerRuns(options) {
6938
+ return convexQuery6("triggers:listRuns", {
6939
+ environment: options.environment,
6940
+ ...options.status && { status: options.status },
6941
+ ...options.triggerSlug && { triggerSlug: options.triggerSlug },
6942
+ ...options.limit && { limit: options.limit }
6943
+ });
6944
+ }
6945
+ async function getTriggerRunDetail(runId, environment) {
6946
+ return convexQuery6("triggers:getRunDetail", {
6947
+ runId,
6948
+ ...environment && { environment }
6949
+ });
6950
+ }
6951
+ async function getTriggerRunStats(environment) {
6952
+ return convexQuery6("triggers:getRunStats", { environment });
6953
+ }
6954
+ async function getLastRunStatuses(environment) {
6955
+ return convexQuery6("triggers:getLastRunStatuses", { environment });
6956
+ }
6957
+ async function cancelTriggerRun(runId, environment) {
6958
+ return convexMutation4("triggers:cancelRun", { runId, environment });
6959
+ }
6960
+ async function retryTriggerRun(runId, environment) {
6961
+ return convexMutation4("triggers:retryRun", { runId, environment });
6962
+ }
6963
+ async function toggleTrigger(slug, enabled, environment) {
6964
+ const path = enabled ? "triggers:enable" : "triggers:disable";
6965
+ return convexMutation4(path, { slug, environment });
6966
+ }
6967
+ async function listTriggerExecutions(options) {
6968
+ return convexQuery6("triggers:listExecutions", {
6969
+ environment: options.environment,
6970
+ ...options.triggerSlug && { triggerSlug: options.triggerSlug },
6971
+ ...options.limit && { limit: options.limit }
6972
+ });
6973
+ }
6974
+ async function getTriggerExecutionDetail(eventId) {
6975
+ return convexQuery6("triggers:getExecutionDetail", { eventId });
6976
+ }
6977
+
6978
+ // src/cli/commands/triggers.ts
6979
+ async function ensureAuth5() {
6980
+ const cwd = process.cwd();
6981
+ const nonInteractive = !isInteractive();
6982
+ if (!hasProject(cwd)) {
6983
+ if (nonInteractive) {
6984
+ console.error(chalk20.red("No struere.json found. Run struere init first."));
6985
+ process.exit(1);
6986
+ }
6987
+ console.log(chalk20.yellow("No struere.json found - initializing project..."));
6988
+ console.log();
6989
+ const success = await runInit(cwd);
6990
+ if (!success) {
6991
+ process.exit(1);
6992
+ }
6993
+ console.log();
6994
+ }
6995
+ let credentials = loadCredentials();
6996
+ const apiKey = getApiKey();
6997
+ if (!credentials && !apiKey) {
6998
+ if (nonInteractive) {
6999
+ console.error(chalk20.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7000
+ process.exit(1);
7001
+ }
7002
+ console.log(chalk20.yellow("Not logged in - authenticating..."));
7003
+ console.log();
7004
+ credentials = await performLogin();
7005
+ if (!credentials) {
7006
+ console.log(chalk20.red("Authentication failed"));
7007
+ process.exit(1);
7008
+ }
7009
+ console.log();
7010
+ }
7011
+ return true;
7012
+ }
7013
+ function relativeTime2(ts) {
7014
+ const diff = Date.now() - ts;
7015
+ const seconds = Math.floor(diff / 1000);
7016
+ if (seconds < 60)
7017
+ return `${seconds}s ago`;
7018
+ const minutes = Math.floor(seconds / 60);
7019
+ if (minutes < 60)
7020
+ return `${minutes}m ago`;
7021
+ const hours = Math.floor(minutes / 60);
7022
+ if (hours < 24)
7023
+ return `${hours}h ago`;
7024
+ const days = Math.floor(hours / 24);
7025
+ return `${days}d ago`;
7026
+ }
7027
+ function statusColor4(status) {
7028
+ switch (status) {
7029
+ case "completed":
7030
+ case "success":
7031
+ return chalk20.green(status);
7032
+ case "pending":
7033
+ return chalk20.yellow(status);
7034
+ case "running":
7035
+ return chalk20.cyan(status);
7036
+ case "failed":
7037
+ case "dead":
7038
+ return chalk20.red(status);
7039
+ default:
7040
+ return chalk20.gray(status);
7041
+ }
7042
+ }
7043
+ function renderAgentChatStep(entry, stepNum, verbose) {
7044
+ const stepStatus = entry.status === "success" ? chalk20.green("success") : chalk20.red("failed");
7045
+ const result = entry.result;
7046
+ const meta = result?._executionMeta;
7047
+ const agentSlug = result?.agentSlug;
7048
+ const threadId = result?.threadId;
7049
+ const response = result?.response;
7050
+ const toolCallSummary = meta?.toolCallSummary;
7051
+ const iterationCount = meta?.iterationCount;
7052
+ const errorCount = meta?.errorCount;
7053
+ const model = meta?.model;
7054
+ console.log(` Step ${stepNum}: ${chalk20.cyan("agent.chat")} \u2192 ${stepStatus} (${entry.durationMs}ms)`);
7055
+ if (entry.as)
7056
+ console.log(` ${chalk20.gray("as:")} ${entry.as}`);
7057
+ const parts = [];
7058
+ if (agentSlug)
7059
+ parts.push(`Agent: ${chalk20.cyan(agentSlug)}`);
7060
+ if (threadId)
7061
+ parts.push(`Thread: ${chalk20.dim(String(threadId).slice(-12))}`);
7062
+ if (iterationCount)
7063
+ parts.push(`${iterationCount} iteration${iterationCount > 1 ? "s" : ""}`);
7064
+ if (parts.length)
7065
+ console.log(` ${parts.join(" | ")}`);
7066
+ if (toolCallSummary?.length) {
7067
+ const ok = toolCallSummary.filter((t) => t.status === "success").length;
7068
+ const errors = toolCallSummary.filter((t) => t.status !== "success").length;
7069
+ const tokenInfo = meta ? `Tokens: ${result?.usage?.inputTokens ?? 0} in / ${result?.usage?.outputTokens ?? 0} out` : "";
7070
+ console.log(` Tools: ${toolCallSummary.length} calls (${chalk20.green(`${ok} ok`)}${errors > 0 ? `, ${chalk20.red(`${errors} errors`)}` : ""})${tokenInfo ? ` | ${tokenInfo}` : ""}`);
7071
+ }
7072
+ if (iterationCount && iterationCount >= 10) {
7073
+ console.log(` ${chalk20.red("!!")} ${chalk20.yellow("Agent hit maximum iteration limit (10) - response may be incomplete")}`);
7074
+ }
7075
+ if (errorCount && errorCount > 0 && entry.status === "success") {
7076
+ console.log(` ${chalk20.yellow("!")} ${chalk20.yellow(`${errorCount} tool error${errorCount > 1 ? "s" : ""} occurred (agent self-corrected)`)}`);
7077
+ }
7078
+ if (verbose && toolCallSummary?.length) {
7079
+ console.log();
7080
+ console.log(` ${chalk20.bold("Agent Tool Calls")}`);
7081
+ console.log(` ${chalk20.gray("\xB7".repeat(50))}`);
7082
+ for (const tc of toolCallSummary) {
7083
+ const tcStatus = tc.status === "success" ? chalk20.green("ok") : chalk20.red(String(tc.status));
7084
+ console.log(` ${chalk20.dim(String(tc.name).padEnd(20))} ${tcStatus} (${tc.durationMs}ms)`);
7085
+ if (tc.errorMessage) {
7086
+ console.log(` ${chalk20.red(String(tc.errorMessage).slice(0, 120))}`);
7087
+ }
7088
+ }
7089
+ console.log(` ${chalk20.gray("\xB7".repeat(50))}`);
7090
+ }
7091
+ if (response) {
7092
+ const truncated = response.length > 200 ? response.slice(0, 200) + "..." : response;
7093
+ console.log(` ${chalk20.gray("Response:")} ${truncated}`);
7094
+ }
7095
+ if (entry.status === "success" && threadId && (errorCount ?? 0) > 0) {
7096
+ console.log(` ${chalk20.dim(`Hint: Run \`struere logs view ${threadId} --exec\` for full agent transcript`)}`);
7097
+ }
7098
+ if (entry.error)
7099
+ console.log(` ${chalk20.red("Error:")} ${entry.error}`);
7100
+ console.log();
7101
+ }
7102
+ function renderExecutionLog(executionLog, verbose) {
7103
+ console.log();
7104
+ console.log(chalk20.bold("Execution Log"));
7105
+ console.log(chalk20.gray("\u2500".repeat(60)));
7106
+ executionLog.forEach((entry, i) => {
7107
+ if (entry.tool === "agent.chat") {
7108
+ renderAgentChatStep(entry, i + 1, verbose ?? false);
7109
+ return;
7110
+ }
7111
+ const stepStatus = entry.status === "success" ? chalk20.green("success") : chalk20.red("failed");
7112
+ console.log(` Step ${i + 1}: ${chalk20.cyan(String(entry.tool))} \u2192 ${stepStatus} (${entry.durationMs}ms)`);
7113
+ if (entry.as)
7114
+ console.log(` ${chalk20.gray("as:")} ${entry.as}`);
7115
+ console.log(` ${chalk20.gray("Args:")} ${JSON.stringify(entry.args, null, 2).split(`
7116
+ `).join(`
7117
+ `)}`);
7118
+ if (entry.result)
7119
+ console.log(` ${chalk20.gray("Result:")} ${JSON.stringify(entry.result, null, 2).split(`
7120
+ `).join(`
7121
+ `)}`);
7122
+ if (entry.error)
7123
+ console.log(` ${chalk20.red("Error:")} ${entry.error}`);
7124
+ console.log();
7125
+ });
7126
+ }
7127
+ var triggersCommand = new Command18("triggers").description("Manage triggers and automation runs");
7128
+ triggersCommand.command("list", { isDefault: true }).description("List all triggers").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--failed", "Show only triggers with recent failures").action(async (opts) => {
7129
+ await ensureAuth5();
7130
+ const spinner = ora14();
7131
+ try {
7132
+ spinner.start("Fetching triggers");
7133
+ const [triggers, statuses] = await Promise.all([
7134
+ listTriggers(opts.env),
7135
+ getLastRunStatuses(opts.env)
7136
+ ]);
7137
+ let filtered = triggers;
7138
+ if (opts.failed) {
7139
+ filtered = triggers.filter((t) => statuses[t.slug]?.status === "failed");
7140
+ }
7141
+ spinner.succeed(`Found ${filtered.length} triggers${opts.failed ? " (failed only)" : ""}`);
7142
+ if (opts.json) {
7143
+ console.log(JSON.stringify(filtered, null, 2));
7144
+ return;
7145
+ }
7146
+ console.log();
7147
+ renderTable([
7148
+ { key: "name", label: "Name", width: 20 },
7149
+ { key: "slug", label: "Slug", width: 18 },
7150
+ { key: "entityType", label: "Entity", width: 14 },
7151
+ { key: "action", label: "Action", width: 10 },
7152
+ { key: "enabled", label: "Enabled", width: 8 },
7153
+ { key: "lastRun", label: "Last Run", width: 12 },
7154
+ { key: "lastError", label: "Last Error", width: 25 },
7155
+ { key: "updated", label: "Updated", width: 10 }
7156
+ ], filtered.map((t) => ({
7157
+ name: t.name ?? "",
7158
+ slug: t.slug ?? "",
7159
+ entityType: t.entityType ?? "",
7160
+ action: t.action ?? "",
7161
+ enabled: t.enabled ? chalk20.green("\u2713") : chalk20.red("\u2717"),
7162
+ lastRun: statuses[t.slug] ? statusColor4(statuses[t.slug].status) : chalk20.gray("-"),
7163
+ lastError: statuses[t.slug]?.status === "failed" ? chalk20.red((statuses[t.slug].error ?? "").slice(0, 23)) : "",
7164
+ updated: relativeTime2(t.updatedAt ?? Date.now())
7165
+ })));
7166
+ console.log();
7167
+ } catch (err) {
7168
+ const message = err instanceof Error ? err.message : String(err);
7169
+ spinner.fail("Failed to fetch triggers");
7170
+ if (opts.json) {
7171
+ console.log(JSON.stringify({ success: false, error: message }));
7172
+ } else {
7173
+ console.log(chalk20.red("Error:"), message);
7174
+ }
7175
+ process.exit(1);
7176
+ }
7177
+ });
7178
+ triggersCommand.command("get <slug>").description("View trigger details").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (slug, opts) => {
7179
+ await ensureAuth5();
7180
+ const spinner = ora14();
7181
+ try {
7182
+ spinner.start("Fetching trigger");
7183
+ const trigger = await getTrigger(slug, opts.env);
7184
+ if (!trigger) {
7185
+ spinner.fail("Trigger not found");
7186
+ if (opts.json) {
7187
+ console.log(JSON.stringify({ success: false, error: "Trigger not found" }));
7188
+ }
7189
+ process.exit(1);
7190
+ }
7191
+ spinner.succeed("Trigger loaded");
7192
+ if (opts.json) {
7193
+ console.log(JSON.stringify(trigger, null, 2));
7194
+ return;
7195
+ }
7196
+ console.log();
7197
+ console.log(` ${chalk20.gray("Name:")} ${chalk20.cyan(trigger.name)}`);
7198
+ console.log(` ${chalk20.gray("Slug:")} ${chalk20.cyan(trigger.slug)}`);
7199
+ console.log(` ${chalk20.gray("Description:")} ${chalk20.cyan(trigger.description || "-")}`);
7200
+ console.log(` ${chalk20.gray("Entity Type:")} ${chalk20.cyan(trigger.entityType)}`);
7201
+ console.log(` ${chalk20.gray("Action:")} ${chalk20.cyan(trigger.action)}`);
7202
+ console.log(` ${chalk20.gray("Enabled:")} ${trigger.enabled ? chalk20.green("\u2713") : chalk20.red("\u2717")}`);
7203
+ console.log(` ${chalk20.gray("Created:")} ${chalk20.cyan(relativeTime2(trigger.createdAt ?? Date.now()))}`);
7204
+ console.log(` ${chalk20.gray("Updated:")} ${chalk20.cyan(relativeTime2(trigger.updatedAt ?? Date.now()))}`);
7205
+ if (trigger.condition) {
7206
+ console.log();
7207
+ console.log(` ${chalk20.gray("Condition:")}`);
7208
+ console.log(` ${JSON.stringify(trigger.condition, null, 2).split(`
7209
+ `).join(`
7210
+ `)}`);
7211
+ }
7212
+ if (trigger.schedule) {
7213
+ console.log();
7214
+ console.log(` ${chalk20.gray("Schedule:")}`);
7215
+ for (const [key, value] of Object.entries(trigger.schedule)) {
7216
+ console.log(` ${chalk20.gray(key + ":")} ${chalk20.cyan(String(value))}`);
7217
+ }
7218
+ }
7219
+ if (trigger.retry) {
7220
+ console.log();
7221
+ console.log(` ${chalk20.gray("Retry:")}`);
7222
+ for (const [key, value] of Object.entries(trigger.retry)) {
7223
+ console.log(` ${chalk20.gray(key + ":")} ${chalk20.cyan(String(value))}`);
7224
+ }
7225
+ }
7226
+ if (trigger.actions?.length) {
7227
+ console.log();
7228
+ console.log(` ${chalk20.gray("Actions:")}`);
7229
+ trigger.actions.forEach((action, i) => {
7230
+ console.log(` ${chalk20.dim("Step " + (i + 1) + ":")} ${chalk20.cyan(action.tool)}${action.as ? ` (as: ${action.as})` : ""}`);
7231
+ if (action.args) {
7232
+ console.log(` ${JSON.stringify(action.args, null, 2).split(`
7233
+ `).join(`
7234
+ `)}`);
7235
+ }
7236
+ });
7237
+ }
7238
+ console.log();
7239
+ } catch (err) {
7240
+ const message = err instanceof Error ? err.message : String(err);
7241
+ spinner.fail("Failed to fetch trigger");
7242
+ if (opts.json) {
7243
+ console.log(JSON.stringify({ success: false, error: message }));
7244
+ } else {
7245
+ console.log(chalk20.red("Error:"), message);
7246
+ }
7247
+ process.exit(1);
7248
+ }
7249
+ });
7250
+ triggersCommand.command("runs [slug]").description("List trigger runs").option("--env <environment>", "Environment", "development").option("--status <status>", "Filter by status (pending|running|completed|failed|dead)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (slug, opts) => {
7251
+ await ensureAuth5();
7252
+ const spinner = ora14();
7253
+ try {
7254
+ spinner.start("Fetching runs");
7255
+ const runs = await listTriggerRuns({
7256
+ environment: opts.env,
7257
+ status: opts.status,
7258
+ triggerSlug: slug,
7259
+ limit: parseInt(opts.limit, 10)
7260
+ });
7261
+ spinner.succeed(`Found ${runs.length} runs`);
7262
+ if (opts.json) {
7263
+ console.log(JSON.stringify(runs, null, 2));
7264
+ return;
7265
+ }
7266
+ console.log();
7267
+ renderTable([
7268
+ { key: "id", label: "ID", width: 24 },
7269
+ { key: "trigger", label: "Trigger", width: 16 },
7270
+ { key: "status", label: "Status", width: 10 },
7271
+ { key: "attempts", label: "Attempts", width: 8 },
7272
+ { key: "entity", label: "Entity", width: 14 },
7273
+ { key: "error", label: "Error", width: 30 },
7274
+ { key: "time", label: "Time", width: 10 }
7275
+ ], runs.map((r) => ({
7276
+ id: r._id ?? "",
7277
+ trigger: r.triggerSlug ?? "",
7278
+ status: statusColor4(r.status),
7279
+ attempts: r.attempts ?? "",
7280
+ entity: r.entityId ? r.entityId.slice(-12) : "",
7281
+ error: r.errorMessage ?? "",
7282
+ time: relativeTime2(r.createdAt ?? Date.now())
7283
+ })));
7284
+ console.log();
7285
+ } catch (err) {
7286
+ const message = err instanceof Error ? err.message : String(err);
7287
+ spinner.fail("Failed to fetch runs");
7288
+ if (opts.json) {
7289
+ console.log(JSON.stringify({ success: false, error: message }));
7290
+ } else {
7291
+ console.log(chalk20.red("Error:"), message);
7292
+ }
7293
+ process.exit(1);
7294
+ }
7295
+ });
7296
+ triggersCommand.command("run <run-id>").description("View trigger run details").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("-v, --verbose", "Show detailed agent tool calls").action(async (runId, opts) => {
7297
+ await ensureAuth5();
7298
+ const spinner = ora14();
7299
+ try {
7300
+ spinner.start("Fetching run");
7301
+ const run = await getTriggerRunDetail(runId, opts.env);
7302
+ if (!run) {
7303
+ spinner.fail("Run not found");
7304
+ if (opts.json) {
7305
+ console.log(JSON.stringify({ success: false, error: "Run not found" }));
7306
+ }
7307
+ process.exit(1);
7308
+ }
7309
+ spinner.succeed("Run loaded");
7310
+ if (opts.json) {
7311
+ console.log(JSON.stringify(run, null, 2));
7312
+ return;
7313
+ }
7314
+ console.log();
7315
+ console.log(` ${chalk20.gray("Trigger:")} ${chalk20.cyan(run.triggerSlug)}`);
7316
+ console.log(` ${chalk20.gray("Status:")} ${statusColor4(run.status)}`);
7317
+ console.log(` ${chalk20.gray("Entity:")} ${chalk20.cyan(run.entityId)}`);
7318
+ console.log(` ${chalk20.gray("Attempts:")} ${chalk20.cyan(`${run.attempts} / ${run.maxAttempts}`)}`);
7319
+ console.log(` ${chalk20.gray("Scheduled:")} ${chalk20.cyan(new Date(run.scheduledFor).toISOString())}`);
7320
+ console.log(` ${chalk20.gray("Started:")} ${chalk20.cyan(run.startedAt ? new Date(run.startedAt).toISOString() : "-")}`);
7321
+ console.log(` ${chalk20.gray("Completed:")} ${chalk20.cyan(run.completedAt ? new Date(run.completedAt).toISOString() : "-")}`);
7322
+ if (run.errorMessage) {
7323
+ console.log(` ${chalk20.gray("Error:")} ${chalk20.red(run.errorMessage)}`);
7324
+ }
7325
+ const executionLog = run.result?.executionLog;
7326
+ if (executionLog?.length) {
7327
+ renderExecutionLog(executionLog, opts.verbose);
7328
+ }
7329
+ console.log();
7330
+ } catch (err) {
7331
+ const message = err instanceof Error ? err.message : String(err);
7332
+ spinner.fail("Failed to fetch run");
7333
+ if (opts.json) {
7334
+ console.log(JSON.stringify({ success: false, error: message }));
7335
+ } else {
7336
+ console.log(chalk20.red("Error:"), message);
7337
+ }
7338
+ process.exit(1);
7339
+ }
7340
+ });
7341
+ triggersCommand.command("stats").description("Show trigger run statistics").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (opts) => {
7342
+ await ensureAuth5();
7343
+ const spinner = ora14();
7344
+ try {
7345
+ spinner.start("Fetching statistics");
7346
+ const stats = await getTriggerRunStats(opts.env);
7347
+ spinner.succeed("Run statistics");
7348
+ if (opts.json) {
7349
+ console.log(JSON.stringify(stats, null, 2));
7350
+ return;
7351
+ }
7352
+ console.log();
7353
+ console.log(chalk20.bold(` Run Statistics (${opts.env})`));
7354
+ console.log();
7355
+ const statuses = [
7356
+ { key: "pending", color: chalk20.yellow },
7357
+ { key: "running", color: chalk20.cyan },
7358
+ { key: "completed", color: chalk20.green },
7359
+ { key: "failed", color: chalk20.red },
7360
+ { key: "dead", color: chalk20.gray }
7361
+ ];
7362
+ let total = 0;
7363
+ for (const { key, color } of statuses) {
7364
+ const count = stats[key] ?? 0;
7365
+ total += count;
7366
+ console.log(` ${color(key.padEnd(12))} ${String(count).padStart(6)}`);
7367
+ }
7368
+ console.log(` ${chalk20.gray("\u2500".repeat(18))}`);
7369
+ console.log(` ${chalk20.bold("Total".padEnd(12))} ${chalk20.bold(String(total).padStart(6))}`);
7370
+ console.log();
7371
+ const executions = await listTriggerExecutions({ environment: opts.env, limit: 50 });
7372
+ const recentFailures = executions.filter((e) => e.eventType === "trigger.failed");
7373
+ const recentSuccesses = executions.length - recentFailures.length;
7374
+ console.log(chalk20.bold(` Recent Executions`));
7375
+ console.log();
7376
+ console.log(` ${chalk20.green("Succeeded".padEnd(12))} ${String(recentSuccesses).padStart(6)}`);
7377
+ console.log(` ${chalk20.red("Failed".padEnd(12))} ${String(recentFailures.length).padStart(6)}`);
7378
+ if (recentFailures.length > 0) {
7379
+ const last = recentFailures[0];
7380
+ console.log();
7381
+ console.log(` ${chalk20.gray("Last failure:")} ${last.payload?.triggerSlug ?? "unknown"} (${relativeTime2(last.timestamp)})`);
7382
+ }
7383
+ console.log();
7384
+ } catch (err) {
7385
+ const message = err instanceof Error ? err.message : String(err);
7386
+ spinner.fail("Failed to fetch statistics");
7387
+ if (opts.json) {
7388
+ console.log(JSON.stringify({ success: false, error: message }));
7389
+ } else {
7390
+ console.log(chalk20.red("Error:"), message);
7391
+ }
7392
+ process.exit(1);
7393
+ }
7394
+ });
7395
+ triggersCommand.command("logs [slug]").description("View trigger execution history").option("--env <environment>", "Environment", "development").option("--limit <n>", "Maximum results", "10").option("--json", "Output raw JSON").action(async (slug, opts) => {
7396
+ await ensureAuth5();
7397
+ const spinner = ora14();
7398
+ try {
7399
+ spinner.start("Fetching execution logs");
7400
+ const executions = await listTriggerExecutions({
7401
+ environment: opts.env,
7402
+ triggerSlug: slug,
7403
+ limit: parseInt(opts.limit, 10)
7404
+ });
7405
+ spinner.succeed(`Found ${executions.length} executions`);
7406
+ if (opts.json) {
7407
+ console.log(JSON.stringify(executions, null, 2));
7408
+ return;
7409
+ }
7410
+ console.log();
7411
+ renderTable([
7412
+ { key: "id", label: "ID", width: 24 },
7413
+ { key: "trigger", label: "Trigger", width: 16 },
7414
+ { key: "status", label: "Status", width: 8 },
7415
+ { key: "steps", label: "Steps", width: 7 },
7416
+ { key: "duration", label: "Duration", width: 10 },
7417
+ { key: "error", label: "Error", width: 30 },
7418
+ { key: "time", label: "Time", width: 10 }
7419
+ ], executions.map((e) => {
7420
+ const status = e.eventType === "trigger.executed" ? "success" : "failed";
7421
+ const log = e.payload?.executionLog ?? [];
7422
+ const totalMs = log.reduce((sum, s) => sum + (s.durationMs || 0), 0);
7423
+ const passed = log.filter((s) => s.status === "success").length;
7424
+ return {
7425
+ id: e._id ?? "",
7426
+ trigger: e.payload?.triggerSlug ?? "",
7427
+ status: statusColor4(status),
7428
+ steps: `${passed}/${log.length}`,
7429
+ duration: `${totalMs}ms`,
7430
+ error: status === "failed" ? (e.payload?.error ?? "").slice(0, 28) : "",
7431
+ time: relativeTime2(e.timestamp ?? Date.now())
7432
+ };
7433
+ }));
7434
+ console.log();
7435
+ } catch (err) {
7436
+ const message = err instanceof Error ? err.message : String(err);
7437
+ spinner.fail("Failed to fetch execution logs");
7438
+ if (opts.json) {
7439
+ console.log(JSON.stringify({ success: false, error: message }));
7440
+ } else {
7441
+ console.log(chalk20.red("Error:"), message);
7442
+ }
7443
+ process.exit(1);
7444
+ }
7445
+ });
7446
+ triggersCommand.command("log <event-id>").description("View detailed trigger execution log").option("--json", "Output raw JSON").option("-v, --verbose", "Show detailed agent tool calls").action(async (eventId, opts) => {
7447
+ await ensureAuth5();
7448
+ const spinner = ora14();
7449
+ try {
7450
+ spinner.start("Fetching execution detail");
7451
+ const event = await getTriggerExecutionDetail(eventId);
7452
+ if (!event) {
7453
+ spinner.fail("Execution not found");
7454
+ if (opts.json) {
7455
+ console.log(JSON.stringify({ success: false, error: "Execution not found" }));
7456
+ }
7457
+ process.exit(1);
7458
+ }
7459
+ spinner.succeed("Execution loaded");
7460
+ if (opts.json) {
7461
+ console.log(JSON.stringify(event, null, 2));
7462
+ return;
7463
+ }
7464
+ const status = event.eventType === "trigger.executed" ? "success" : "failed";
7465
+ console.log();
7466
+ console.log(` ${chalk20.gray("Trigger:")} ${chalk20.cyan(event.payload?.triggerSlug ?? "")}`);
7467
+ console.log(` ${chalk20.gray("Status:")} ${statusColor4(status)}`);
7468
+ console.log(` ${chalk20.gray("Timestamp:")} ${chalk20.cyan(new Date(event.timestamp).toISOString())}`);
7469
+ if (event.entityId) {
7470
+ console.log(` ${chalk20.gray("Entity:")} ${chalk20.cyan(event.entityId)}`);
7471
+ }
7472
+ if (status === "failed" && event.payload?.error) {
7473
+ console.log(` ${chalk20.gray("Error:")} ${chalk20.red(event.payload.error)}`);
7474
+ }
7475
+ const executionLog = event.payload?.executionLog;
7476
+ if (executionLog?.length) {
7477
+ renderExecutionLog(executionLog, opts.verbose);
7478
+ }
7479
+ if (status === "failed" && event.payload?.triggerData) {
7480
+ console.log(chalk20.bold("Trigger Data"));
7481
+ console.log(chalk20.gray("\u2500".repeat(60)));
7482
+ console.log(` ${JSON.stringify(event.payload.triggerData, null, 2).split(`
7483
+ `).join(`
7484
+ `)}`);
7485
+ console.log();
7486
+ }
7487
+ } catch (err) {
7488
+ const message = err instanceof Error ? err.message : String(err);
7489
+ spinner.fail("Failed to fetch execution detail");
7490
+ if (opts.json) {
7491
+ console.log(JSON.stringify({ success: false, error: message }));
7492
+ } else {
7493
+ console.log(chalk20.red("Error:"), message);
7494
+ }
7495
+ process.exit(1);
7496
+ }
7497
+ });
7498
+ triggersCommand.command("retry <run-id>").description("Retry a failed or dead run").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (runId, opts) => {
7499
+ await ensureAuth5();
7500
+ const spinner = ora14();
7501
+ const environment = opts.env;
7502
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7503
+ const readline = await import("readline");
7504
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7505
+ await new Promise((resolve) => {
7506
+ rl.question(chalk20.yellow(`WARNING: Retrying run in PRODUCTION environment.
7507
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7508
+ });
7509
+ rl.close();
7510
+ }
7511
+ try {
7512
+ spinner.start("Retrying run...");
7513
+ await retryTriggerRun(runId, environment);
7514
+ spinner.succeed(chalk20.green(`Run ${runId} queued for retry`));
7515
+ if (opts.json) {
7516
+ console.log(JSON.stringify({ success: true, runId }));
7517
+ }
7518
+ } catch (err) {
7519
+ const message = err instanceof Error ? err.message : String(err);
7520
+ spinner.fail("Failed to retry run");
7521
+ if (opts.json) {
7522
+ console.log(JSON.stringify({ success: false, error: message }));
7523
+ } else {
7524
+ console.log(chalk20.red("Error:"), message);
7525
+ }
7526
+ process.exit(1);
7527
+ }
7528
+ });
7529
+ triggersCommand.command("cancel <run-id>").description("Cancel a pending run").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (runId, opts) => {
7530
+ await ensureAuth5();
7531
+ const spinner = ora14();
7532
+ const environment = opts.env;
7533
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7534
+ const readline = await import("readline");
7535
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7536
+ await new Promise((resolve) => {
7537
+ rl.question(chalk20.yellow(`WARNING: Cancelling run in PRODUCTION environment.
7538
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7539
+ });
7540
+ rl.close();
7541
+ }
7542
+ try {
7543
+ spinner.start("Cancelling run...");
7544
+ await cancelTriggerRun(runId, environment);
7545
+ spinner.succeed(chalk20.green(`Run ${runId} cancelled`));
7546
+ if (opts.json) {
7547
+ console.log(JSON.stringify({ success: true, runId }));
7548
+ }
7549
+ } catch (err) {
7550
+ const message = err instanceof Error ? err.message : String(err);
7551
+ spinner.fail("Failed to cancel run");
7552
+ if (opts.json) {
7553
+ console.log(JSON.stringify({ success: false, error: message }));
7554
+ } else {
7555
+ console.log(chalk20.red("Error:"), message);
7556
+ }
7557
+ process.exit(1);
7558
+ }
7559
+ });
7560
+ triggersCommand.command("enable <slug>").description("Enable a trigger").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
7561
+ await ensureAuth5();
7562
+ const spinner = ora14();
7563
+ const environment = opts.env;
7564
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7565
+ const readline = await import("readline");
7566
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7567
+ await new Promise((resolve) => {
7568
+ rl.question(chalk20.yellow(`WARNING: Enabling trigger in PRODUCTION environment.
7569
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7570
+ });
7571
+ rl.close();
7572
+ }
7573
+ try {
7574
+ spinner.start("Enabling trigger...");
7575
+ await toggleTrigger(slug, true, environment);
7576
+ spinner.succeed(chalk20.green(`Trigger ${slug} enabled`));
7577
+ if (opts.json) {
7578
+ console.log(JSON.stringify({ success: true, slug }));
7579
+ }
7580
+ } catch (err) {
7581
+ const message = err instanceof Error ? err.message : String(err);
7582
+ spinner.fail("Failed to enable trigger");
7583
+ if (opts.json) {
7584
+ console.log(JSON.stringify({ success: false, error: message }));
7585
+ } else {
7586
+ console.log(chalk20.red("Error:"), message);
7587
+ }
7588
+ process.exit(1);
7589
+ }
7590
+ });
7591
+ triggersCommand.command("disable <slug>").description("Disable a trigger").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
7592
+ await ensureAuth5();
7593
+ const spinner = ora14();
7594
+ const environment = opts.env;
7595
+ if (environment === "production" && !opts.confirm && isInteractive()) {
7596
+ const readline = await import("readline");
7597
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7598
+ await new Promise((resolve) => {
7599
+ rl.question(chalk20.yellow(`WARNING: Disabling trigger in PRODUCTION environment.
7600
+ Press Enter to continue or Ctrl+C to cancel: `), resolve);
7601
+ });
7602
+ rl.close();
7603
+ }
7604
+ try {
7605
+ spinner.start("Disabling trigger...");
7606
+ await toggleTrigger(slug, false, environment);
7607
+ spinner.succeed(chalk20.green(`Trigger ${slug} disabled`));
7608
+ if (opts.json) {
7609
+ console.log(JSON.stringify({ success: true, slug }));
7610
+ }
7611
+ } catch (err) {
7612
+ const message = err instanceof Error ? err.message : String(err);
7613
+ spinner.fail("Failed to disable trigger");
7614
+ if (opts.json) {
7615
+ console.log(JSON.stringify({ success: false, error: message }));
7616
+ } else {
7617
+ console.log(chalk20.red("Error:"), message);
7618
+ }
7619
+ process.exit(1);
7620
+ }
7621
+ });
7622
+
7623
+ // src/cli/commands/compile-prompt.ts
7624
+ import { Command as Command19 } from "commander";
7625
+ import chalk21 from "chalk";
7626
+ import ora15 from "ora";
7627
+ var compilePromptCommand = new Command19("compile-prompt").description("Compile and preview an agent's system prompt after template processing").argument("<agent-slug>", "Agent slug to compile prompt for").option("--env <env>", "Environment: development | production", "development").option("--message <msg>", "Sample message for template context").option("--channel <channel>", "Sample channel (whatsapp, widget, api, dashboard)").option("--param <key=value...>", "Custom thread param (repeatable)", (val, acc) => {
6831
7628
  acc.push(val);
6832
7629
  return acc;
6833
7630
  }, []).option("--json", "Output full JSON (raw + compiled + context)").option("--raw", "Show raw uncompiled template instead of compiled").action(async (agentSlug, options) => {
6834
- const spinner = ora14();
7631
+ const spinner = ora15();
6835
7632
  const cwd = process.cwd();
6836
7633
  const nonInteractive = !isInteractive();
6837
7634
  const jsonMode = !!options.json;
@@ -6840,11 +7637,11 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6840
7637
  if (jsonMode) {
6841
7638
  console.log(JSON.stringify({ success: false, error: "No struere.json found" }));
6842
7639
  } else {
6843
- console.log(chalk20.red("No struere.json found. Run struere init first."));
7640
+ console.log(chalk21.red("No struere.json found. Run struere init first."));
6844
7641
  }
6845
7642
  process.exit(1);
6846
7643
  }
6847
- console.log(chalk20.yellow("No struere.json found - initializing project..."));
7644
+ console.log(chalk21.yellow("No struere.json found - initializing project..."));
6848
7645
  console.log();
6849
7646
  const success = await runInit(cwd);
6850
7647
  if (!success) {
@@ -6857,7 +7654,7 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6857
7654
  if (jsonMode) {
6858
7655
  console.log(JSON.stringify({ success: false, error: "Failed to load struere.json" }));
6859
7656
  } else {
6860
- console.log(chalk20.red("Failed to load struere.json"));
7657
+ console.log(chalk21.red("Failed to load struere.json"));
6861
7658
  }
6862
7659
  process.exit(1);
6863
7660
  }
@@ -6868,15 +7665,15 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6868
7665
  if (jsonMode) {
6869
7666
  console.log(JSON.stringify({ success: false, error: "Not authenticated. Set STRUERE_API_KEY or run struere login." }));
6870
7667
  } else {
6871
- console.log(chalk20.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7668
+ console.log(chalk21.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
6872
7669
  }
6873
7670
  process.exit(1);
6874
7671
  }
6875
- console.log(chalk20.yellow("Not logged in - authenticating..."));
7672
+ console.log(chalk21.yellow("Not logged in - authenticating..."));
6876
7673
  console.log();
6877
7674
  credentials = await performLogin();
6878
7675
  if (!credentials) {
6879
- console.log(chalk20.red("Authentication failed"));
7676
+ console.log(chalk21.red("Authentication failed"));
6880
7677
  process.exit(1);
6881
7678
  }
6882
7679
  console.log();
@@ -6888,7 +7685,7 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6888
7685
  if (jsonMode) {
6889
7686
  console.log(JSON.stringify({ success: false, error: `Invalid param format: ${param}. Use key=value.` }));
6890
7687
  } else {
6891
- console.log(chalk20.red(`Invalid param format: ${param}. Use key=value.`));
7688
+ console.log(chalk21.red(`Invalid param format: ${param}. Use key=value.`));
6892
7689
  }
6893
7690
  process.exit(1);
6894
7691
  }
@@ -6898,7 +7695,7 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6898
7695
  }
6899
7696
  const environment = options.env;
6900
7697
  if (!jsonMode) {
6901
- spinner.start(`Compiling prompt for ${chalk20.cyan(agentSlug)} (${environment})`);
7698
+ spinner.start(`Compiling prompt for ${chalk21.cyan(agentSlug)} (${environment})`);
6902
7699
  }
6903
7700
  const doCompile = async () => {
6904
7701
  return compilePrompt({
@@ -6920,7 +7717,7 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6920
7717
  if (jsonMode) {
6921
7718
  console.log(JSON.stringify({ success: false, error: "Authentication failed" }));
6922
7719
  } else {
6923
- console.log(chalk20.red("Authentication failed"));
7720
+ console.log(chalk21.red("Authentication failed"));
6924
7721
  }
6925
7722
  process.exit(1);
6926
7723
  }
@@ -6935,7 +7732,7 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6935
7732
  console.log(JSON.stringify({ success: false, error }));
6936
7733
  } else {
6937
7734
  spinner.fail("Failed to compile prompt");
6938
- console.log(chalk20.red("Error:"), error);
7735
+ console.log(chalk21.red("Error:"), error);
6939
7736
  }
6940
7737
  process.exit(1);
6941
7738
  }
@@ -6958,25 +7755,25 @@ var compilePromptCommand = new Command18("compile-prompt").description("Compile
6958
7755
  }, null, 2));
6959
7756
  } else if (options.raw) {
6960
7757
  console.log();
6961
- console.log(chalk20.bold("Raw System Prompt"));
6962
- console.log(chalk20.gray("\u2500".repeat(60)));
7758
+ console.log(chalk21.bold("Raw System Prompt"));
7759
+ console.log(chalk21.gray("\u2500".repeat(60)));
6963
7760
  console.log(result.raw);
6964
- console.log(chalk20.gray("\u2500".repeat(60)));
7761
+ console.log(chalk21.gray("\u2500".repeat(60)));
6965
7762
  } else {
6966
7763
  console.log();
6967
- console.log(chalk20.bold("Compiled System Prompt"));
6968
- console.log(chalk20.gray("\u2500".repeat(60)));
7764
+ console.log(chalk21.bold("Compiled System Prompt"));
7765
+ console.log(chalk21.gray("\u2500".repeat(60)));
6969
7766
  console.log(result.compiled);
6970
- console.log(chalk20.gray("\u2500".repeat(60)));
7767
+ console.log(chalk21.gray("\u2500".repeat(60)));
6971
7768
  }
6972
7769
  });
6973
7770
 
6974
7771
  // src/cli/commands/run-tool.ts
6975
- import { Command as Command19 } from "commander";
6976
- import chalk21 from "chalk";
6977
- import ora15 from "ora";
6978
- var runToolCommand = new Command19("run-tool").description("Run a tool as it would execute during a real agent conversation").argument("<agent-slug>", "Agent slug").argument("<tool-name>", "Tool name (e.g., entity.query)").option("--env <environment>", "Environment: development | production | eval", "development").option("--args <json>", "Tool arguments as JSON string", "{}").option("--args-file <path>", "Read tool arguments from a JSON file").option("--json", "Output full JSON result").option("--confirm", "Skip production confirmation prompt").action(async (agentSlug, toolName, options) => {
6979
- const spinner = ora15();
7772
+ import { Command as Command20 } from "commander";
7773
+ import chalk22 from "chalk";
7774
+ import ora16 from "ora";
7775
+ var runToolCommand = new Command20("run-tool").description("Run a tool as it would execute during a real agent conversation").argument("<agent-slug>", "Agent slug").argument("<tool-name>", "Tool name (e.g., entity.query)").option("--env <environment>", "Environment: development | production | eval", "development").option("--args <json>", "Tool arguments as JSON string", "{}").option("--args-file <path>", "Read tool arguments from a JSON file").option("--json", "Output full JSON result").option("--confirm", "Skip production confirmation prompt").action(async (agentSlug, toolName, options) => {
7776
+ const spinner = ora16();
6980
7777
  const cwd = process.cwd();
6981
7778
  const nonInteractive = !isInteractive();
6982
7779
  const jsonMode = !!options.json;
@@ -6985,11 +7782,11 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
6985
7782
  if (jsonMode) {
6986
7783
  console.log(JSON.stringify({ success: false, error: "No struere.json found" }));
6987
7784
  } else {
6988
- console.log(chalk21.red("No struere.json found. Run struere init first."));
7785
+ console.log(chalk22.red("No struere.json found. Run struere init first."));
6989
7786
  }
6990
7787
  process.exit(1);
6991
7788
  }
6992
- console.log(chalk21.yellow("No struere.json found - initializing project..."));
7789
+ console.log(chalk22.yellow("No struere.json found - initializing project..."));
6993
7790
  console.log();
6994
7791
  const success = await runInit(cwd);
6995
7792
  if (!success) {
@@ -7002,7 +7799,7 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7002
7799
  if (jsonMode) {
7003
7800
  console.log(JSON.stringify({ success: false, error: "Failed to load struere.json" }));
7004
7801
  } else {
7005
- console.log(chalk21.red("Failed to load struere.json"));
7802
+ console.log(chalk22.red("Failed to load struere.json"));
7006
7803
  }
7007
7804
  process.exit(1);
7008
7805
  }
@@ -7013,15 +7810,15 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7013
7810
  if (jsonMode) {
7014
7811
  console.log(JSON.stringify({ success: false, error: "Not authenticated. Set STRUERE_API_KEY or run struere login." }));
7015
7812
  } else {
7016
- console.log(chalk21.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7813
+ console.log(chalk22.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7017
7814
  }
7018
7815
  process.exit(1);
7019
7816
  }
7020
- console.log(chalk21.yellow("Not logged in - authenticating..."));
7817
+ console.log(chalk22.yellow("Not logged in - authenticating..."));
7021
7818
  console.log();
7022
7819
  credentials = await performLogin();
7023
7820
  if (!credentials) {
7024
- console.log(chalk21.red("Authentication failed"));
7821
+ console.log(chalk22.red("Authentication failed"));
7025
7822
  process.exit(1);
7026
7823
  }
7027
7824
  console.log();
@@ -7039,7 +7836,7 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7039
7836
  if (jsonMode) {
7040
7837
  console.log(JSON.stringify({ success: false, error: `Invalid JSON: ${err instanceof Error ? err.message : String(err)}` }));
7041
7838
  } else {
7042
- console.log(chalk21.red(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`));
7839
+ console.log(chalk22.red(`Invalid JSON: ${err instanceof Error ? err.message : String(err)}`));
7043
7840
  }
7044
7841
  process.exit(1);
7045
7842
  }
@@ -7048,14 +7845,14 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7048
7845
  const readline = await import("readline");
7049
7846
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7050
7847
  await new Promise((resolve) => {
7051
- rl.question(chalk21.yellow(`WARNING: Running tool against PRODUCTION environment.
7848
+ rl.question(chalk22.yellow(`WARNING: Running tool against PRODUCTION environment.
7052
7849
  This will execute real operations with real data.
7053
7850
  Press Enter to continue or Ctrl+C to cancel: `), resolve);
7054
7851
  });
7055
7852
  rl.close();
7056
7853
  }
7057
7854
  if (!jsonMode) {
7058
- spinner.start(`Running ${chalk21.cyan(toolName)} on ${chalk21.cyan(agentSlug)} (${environment})`);
7855
+ spinner.start(`Running ${chalk22.cyan(toolName)} on ${chalk22.cyan(agentSlug)} (${environment})`);
7059
7856
  }
7060
7857
  const doRunTool = async () => {
7061
7858
  return runTool({
@@ -7076,7 +7873,7 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7076
7873
  if (jsonMode) {
7077
7874
  console.log(JSON.stringify({ success: false, error: "Authentication failed" }));
7078
7875
  } else {
7079
- console.log(chalk21.red("Authentication failed"));
7876
+ console.log(chalk22.red("Authentication failed"));
7080
7877
  }
7081
7878
  process.exit(1);
7082
7879
  }
@@ -7084,14 +7881,14 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7084
7881
  result = retry.result;
7085
7882
  error = retry.error;
7086
7883
  if (!jsonMode && !error)
7087
- spinner.succeed(`Ran ${chalk21.cyan(toolName)}`);
7884
+ spinner.succeed(`Ran ${chalk22.cyan(toolName)}`);
7088
7885
  }
7089
7886
  if (error) {
7090
7887
  if (jsonMode) {
7091
7888
  console.log(JSON.stringify({ success: false, error }));
7092
7889
  } else {
7093
7890
  spinner.fail("Failed to run tool");
7094
- console.log(chalk21.red("Error:"), error);
7891
+ console.log(chalk22.red("Error:"), error);
7095
7892
  }
7096
7893
  process.exit(1);
7097
7894
  }
@@ -7107,32 +7904,32 @@ var runToolCommand = new Command19("run-tool").description("Run a tool as it wou
7107
7904
  if (jsonMode) {
7108
7905
  console.log(JSON.stringify({ success: false, error: `${result.errorType}: ${result.message}`, result }));
7109
7906
  } else {
7110
- spinner.fail(chalk21.red(`${result.errorType}: ${result.message}`));
7907
+ spinner.fail(chalk22.red(`${result.errorType}: ${result.message}`));
7111
7908
  }
7112
7909
  process.exit(1);
7113
7910
  }
7114
7911
  if (!jsonMode) {
7115
- spinner.succeed(`Ran ${chalk21.cyan(toolName)} on ${chalk21.cyan(result.agent.slug)} (${result.environment}) in ${result.durationMs}ms`);
7912
+ spinner.succeed(`Ran ${chalk22.cyan(toolName)} on ${chalk22.cyan(result.agent.slug)} (${result.environment}) in ${result.durationMs}ms`);
7116
7913
  }
7117
7914
  if (jsonMode) {
7118
7915
  console.log(JSON.stringify(result, null, 2));
7119
7916
  } else {
7120
7917
  console.log();
7121
- console.log(chalk21.dim("\u2500".repeat(50)));
7918
+ console.log(chalk22.dim("\u2500".repeat(50)));
7122
7919
  console.log(JSON.stringify(result.result, null, 2));
7123
- console.log(chalk21.dim("\u2500".repeat(50)));
7920
+ console.log(chalk22.dim("\u2500".repeat(50)));
7124
7921
  console.log();
7125
- console.log(chalk21.dim(`Identity: ${result.identity.actorType} (${result.identity.identityMode} mode)`));
7922
+ console.log(chalk22.dim(`Identity: ${result.identity.actorType} (${result.identity.identityMode} mode)`));
7126
7923
  }
7127
7924
  });
7128
7925
 
7129
7926
  // src/cli/commands/chat.ts
7130
- import { Command as Command20 } from "commander";
7131
- import chalk22 from "chalk";
7132
- import ora16 from "ora";
7927
+ import { Command as Command21 } from "commander";
7928
+ import chalk23 from "chalk";
7929
+ import ora17 from "ora";
7133
7930
  import readline from "readline";
7134
- var chatCommand = new Command20("chat").description("Chat with an agent").argument("<agent-slug>", "Agent slug").option("--env <environment>", "Environment: development | production | eval", "development").option("--thread <id>", "Continue an existing thread").option("--message <msg>", "Single message mode (send and exit)").option("--json", "Output JSON").option("--channel <channel>", "Channel identifier", "api").option("-v, --verbose", "Show detailed response info").option("--confirm", "Skip production warning prompt").action(async (agentSlug, options) => {
7135
- const spinner = ora16();
7931
+ var chatCommand = new Command21("chat").description("Chat with an agent").argument("<agent-slug>", "Agent slug").option("--env <environment>", "Environment: development | production | eval", "development").option("--thread <id>", "Continue an existing thread").option("--message <msg>", "Single message mode (send and exit)").option("--json", "Output JSON").option("--channel <channel>", "Channel identifier", "api").option("-v, --verbose", "Show detailed response info").option("--confirm", "Skip production warning prompt").action(async (agentSlug, options) => {
7932
+ const spinner = ora17();
7136
7933
  const cwd = process.cwd();
7137
7934
  const nonInteractive = !isInteractive();
7138
7935
  const jsonMode = !!options.json;
@@ -7141,11 +7938,11 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7141
7938
  if (jsonMode) {
7142
7939
  console.log(JSON.stringify({ success: false, error: "No struere.json found" }));
7143
7940
  } else {
7144
- console.log(chalk22.red("No struere.json found. Run struere init first."));
7941
+ console.log(chalk23.red("No struere.json found. Run struere init first."));
7145
7942
  }
7146
7943
  process.exit(1);
7147
7944
  }
7148
- console.log(chalk22.yellow("No struere.json found - initializing project..."));
7945
+ console.log(chalk23.yellow("No struere.json found - initializing project..."));
7149
7946
  console.log();
7150
7947
  const success = await runInit(cwd);
7151
7948
  if (!success) {
@@ -7158,7 +7955,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7158
7955
  if (jsonMode) {
7159
7956
  console.log(JSON.stringify({ success: false, error: "Failed to load struere.json" }));
7160
7957
  } else {
7161
- console.log(chalk22.red("Failed to load struere.json"));
7958
+ console.log(chalk23.red("Failed to load struere.json"));
7162
7959
  }
7163
7960
  process.exit(1);
7164
7961
  }
@@ -7169,15 +7966,15 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7169
7966
  if (jsonMode) {
7170
7967
  console.log(JSON.stringify({ success: false, error: "Not authenticated. Set STRUERE_API_KEY or run struere login." }));
7171
7968
  } else {
7172
- console.log(chalk22.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7969
+ console.log(chalk23.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
7173
7970
  }
7174
7971
  process.exit(1);
7175
7972
  }
7176
- console.log(chalk22.yellow("Not logged in - authenticating..."));
7973
+ console.log(chalk23.yellow("Not logged in - authenticating..."));
7177
7974
  console.log();
7178
7975
  credentials = await performLogin();
7179
7976
  if (!credentials) {
7180
- console.log(chalk22.red("Authentication failed"));
7977
+ console.log(chalk23.red("Authentication failed"));
7181
7978
  process.exit(1);
7182
7979
  }
7183
7980
  console.log();
@@ -7186,7 +7983,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7186
7983
  if (environment === "production" && !nonInteractive && !options.confirm) {
7187
7984
  const confirmRl = readline.createInterface({ input: process.stdin, output: process.stdout });
7188
7985
  await new Promise((resolve) => {
7189
- confirmRl.question(chalk22.yellow(`WARNING: Chatting with agent in PRODUCTION environment.
7986
+ confirmRl.question(chalk23.yellow(`WARNING: Chatting with agent in PRODUCTION environment.
7190
7987
  Press Enter to continue or Ctrl+C to cancel: `), resolve);
7191
7988
  });
7192
7989
  confirmRl.close();
@@ -7216,7 +8013,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7216
8013
  if (jsonMode) {
7217
8014
  console.log(JSON.stringify({ success: false, error: "Authentication failed" }));
7218
8015
  } else {
7219
- console.log(chalk22.red("Authentication failed"));
8016
+ console.log(chalk23.red("Authentication failed"));
7220
8017
  }
7221
8018
  process.exit(1);
7222
8019
  }
@@ -7231,7 +8028,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7231
8028
  console.log(JSON.stringify({ success: false, error }));
7232
8029
  } else {
7233
8030
  spinner.fail("Failed to send message");
7234
- console.log(chalk22.red("Error:"), error);
8031
+ console.log(chalk23.red("Error:"), error);
7235
8032
  }
7236
8033
  process.exit(1);
7237
8034
  }
@@ -7251,30 +8048,30 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7251
8048
  console.log();
7252
8049
  console.log("\u2500".repeat(60));
7253
8050
  console.log();
7254
- console.log(chalk22.green("Agent:"));
8051
+ console.log(chalk23.green("Agent:"));
7255
8052
  console.log(result.message);
7256
8053
  console.log();
7257
8054
  if (options.verbose) {
7258
- console.log(chalk22.dim(`Thread: ${result.threadId}`));
7259
- console.log(chalk22.dim(`Tokens: ${result.usage.inputTokens} in / ${result.usage.outputTokens} out (${result.usage.totalTokens} total)`));
7260
- console.log(chalk22.dim("Tool call details available in dashboard"));
8055
+ console.log(chalk23.dim(`Thread: ${result.threadId}`));
8056
+ console.log(chalk23.dim(`Tokens: ${result.usage.inputTokens} in / ${result.usage.outputTokens} out (${result.usage.totalTokens} total)`));
8057
+ console.log(chalk23.dim("Tool call details available in dashboard"));
7261
8058
  } else {
7262
- console.log(chalk22.dim(`Thread: ${result.threadId} | Tokens: ${result.usage.totalTokens}`));
8059
+ console.log(chalk23.dim(`Thread: ${result.threadId} | Tokens: ${result.usage.totalTokens}`));
7263
8060
  }
7264
8061
  console.log();
7265
8062
  console.log("\u2500".repeat(60));
7266
8063
  }
7267
8064
  return;
7268
8065
  }
7269
- console.log(chalk22.bold(`Chat with ${chalk22.cyan(agentSlug)} (${environment})`));
7270
- console.log(chalk22.dim("Type 'exit' to quit"));
8066
+ console.log(chalk23.bold(`Chat with ${chalk23.cyan(agentSlug)} (${environment})`));
8067
+ console.log(chalk23.dim("Type 'exit' to quit"));
7271
8068
  console.log();
7272
8069
  let threadId = options.thread;
7273
8070
  let processing = false;
7274
8071
  let generation = 0;
7275
8072
  let currentAbort = null;
7276
8073
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
7277
- rl.setPrompt(chalk22.cyan("You: "));
8074
+ rl.setPrompt(chalk23.cyan("You: "));
7278
8075
  rl.prompt();
7279
8076
  rl.on("SIGINT", () => {
7280
8077
  if (processing) {
@@ -7286,7 +8083,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7286
8083
  spinner.stop();
7287
8084
  processing = false;
7288
8085
  console.log();
7289
- console.log(chalk22.yellow("Cancelled"));
8086
+ console.log(chalk23.yellow("Cancelled"));
7290
8087
  console.log();
7291
8088
  rl.resume();
7292
8089
  rl.prompt();
@@ -7324,7 +8121,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7324
8121
  if (thisGeneration !== generation)
7325
8122
  return;
7326
8123
  if (!credentials) {
7327
- console.log(chalk22.red("Authentication failed"));
8124
+ console.log(chalk23.red("Authentication failed"));
7328
8125
  rl.close();
7329
8126
  return;
7330
8127
  }
@@ -7338,7 +8135,7 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7338
8135
  }
7339
8136
  if (error) {
7340
8137
  spinner.fail("");
7341
- console.log(chalk22.red("Error:"), error);
8138
+ console.log(chalk23.red("Error:"), error);
7342
8139
  processing = false;
7343
8140
  currentAbort = null;
7344
8141
  rl.resume();
@@ -7356,15 +8153,15 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7356
8153
  spinner.stop();
7357
8154
  threadId = result.threadId;
7358
8155
  console.log();
7359
- console.log(chalk22.green("Agent:"));
8156
+ console.log(chalk23.green("Agent:"));
7360
8157
  console.log(result.message);
7361
8158
  console.log();
7362
8159
  if (options.verbose) {
7363
- console.log(chalk22.dim(`Thread: ${result.threadId}`));
7364
- console.log(chalk22.dim(`Tokens: ${result.usage.inputTokens} in / ${result.usage.outputTokens} out (${result.usage.totalTokens} total)`));
7365
- console.log(chalk22.dim("Tool call details available in dashboard"));
8160
+ console.log(chalk23.dim(`Thread: ${result.threadId}`));
8161
+ console.log(chalk23.dim(`Tokens: ${result.usage.inputTokens} in / ${result.usage.outputTokens} out (${result.usage.totalTokens} total)`));
8162
+ console.log(chalk23.dim("Tool call details available in dashboard"));
7366
8163
  } else {
7367
- console.log(chalk22.dim(`Tokens: ${result.usage.totalTokens}`));
8164
+ console.log(chalk23.dim(`Tokens: ${result.usage.totalTokens}`));
7368
8165
  }
7369
8166
  console.log();
7370
8167
  processing = false;
@@ -7374,14 +8171,14 @@ var chatCommand = new Command20("chat").description("Chat with an agent").argume
7374
8171
  });
7375
8172
  rl.on("close", () => {
7376
8173
  console.log();
7377
- console.log(chalk22.dim("Goodbye!"));
8174
+ console.log(chalk23.dim("Goodbye!"));
7378
8175
  process.exit(0);
7379
8176
  });
7380
8177
  });
7381
8178
  // package.json
7382
8179
  var package_default = {
7383
8180
  name: "struere",
7384
- version: "0.10.6",
8181
+ version: "0.11.0",
7385
8182
  description: "Build, test, and deploy AI agents",
7386
8183
  keywords: [
7387
8184
  "ai",
@@ -7498,6 +8295,7 @@ program.addCommand(docsCommand);
7498
8295
  program.addCommand(evalCommand);
7499
8296
  program.addCommand(templatesCommand);
7500
8297
  program.addCommand(integrationCommand);
8298
+ program.addCommand(triggersCommand);
7501
8299
  program.addCommand(compilePromptCommand);
7502
8300
  program.addCommand(runToolCommand);
7503
8301
  program.addCommand(chatCommand);