struere 0.16.3 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/struere.js +224 -111
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/workflows.d.ts.map +1 -1
- package/dist/cli/index.js +271 -148
- package/dist/cli/utils/convex.d.ts +6 -1
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/env-file.d.ts +2 -0
- package/dist/cli/utils/env-file.d.ts.map +1 -0
- package/dist/cli/utils/extractor.d.ts +5 -1
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/threads.d.ts +2 -0
- package/dist/cli/utils/threads.d.ts.map +1 -1
- package/dist/cli/utils/validator.d.ts.map +1 -1
- package/dist/cli/utils/workflows.d.ts +7 -2
- package/dist/cli/utils/workflows.d.ts.map +1 -1
- package/dist/define/agent.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -237,7 +237,8 @@ async function syncViaHttp(apiKey, payload) {
|
|
|
237
237
|
triggers: payload.triggers,
|
|
238
238
|
routers: payload.routers,
|
|
239
239
|
workflows: payload.workflows,
|
|
240
|
-
fixtures: payload.fixtures
|
|
240
|
+
fixtures: payload.fixtures,
|
|
241
|
+
secrets: payload.secrets
|
|
241
242
|
}),
|
|
242
243
|
signal: AbortSignal.timeout(30000)
|
|
243
244
|
});
|
|
@@ -65921,8 +65922,8 @@ import { Command as Command6 } from "commander";
|
|
|
65921
65922
|
import chalk7 from "chalk";
|
|
65922
65923
|
import ora6 from "ora";
|
|
65923
65924
|
import chokidar from "chokidar";
|
|
65924
|
-
import { join as
|
|
65925
|
-
import { existsSync as
|
|
65925
|
+
import { join as join9 } from "path";
|
|
65926
|
+
import { existsSync as existsSync9 } from "fs";
|
|
65926
65927
|
|
|
65927
65928
|
// src/cli/commands/sync.ts
|
|
65928
65929
|
init_credentials();
|
|
@@ -66753,7 +66754,9 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
66753
66754
|
} else {
|
|
66754
66755
|
systemPrompt = agent.systemPrompt;
|
|
66755
66756
|
}
|
|
66756
|
-
const tools = (agent.tools || []).map((
|
|
66757
|
+
const tools = (agent.tools || []).map((entry) => {
|
|
66758
|
+
const spec = typeof entry === "string" ? null : entry;
|
|
66759
|
+
const toolName = typeof entry === "string" ? entry : entry.name;
|
|
66757
66760
|
const isBuiltin = BUILTIN_TOOLS.includes(toolName);
|
|
66758
66761
|
if (!isBuiltin && !customToolsMap.has(toolName)) {
|
|
66759
66762
|
const builtinPrefixes = ["entity.", "calendar.", "whatsapp.", "agent.", "airtable.", "email.", "payment.", "web.", "voice.", "router."];
|
|
@@ -66764,7 +66767,13 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
66764
66767
|
const available = customToolsMap.size > 0 ? `Available custom tools: ${Array.from(customToolsMap.keys()).join(", ")}` : "No custom tools were loaded from tools/index.ts";
|
|
66765
66768
|
throw new Error(`Agent "${agent.name}" references tool "${toolName}" but it was not found. ${available}`);
|
|
66766
66769
|
}
|
|
66767
|
-
|
|
66770
|
+
if (!spec)
|
|
66771
|
+
return toolName;
|
|
66772
|
+
return {
|
|
66773
|
+
name: spec.name,
|
|
66774
|
+
identityMode: spec.identityMode,
|
|
66775
|
+
configuredRole: spec.configuredRole
|
|
66776
|
+
};
|
|
66768
66777
|
});
|
|
66769
66778
|
return {
|
|
66770
66779
|
name: agent.name,
|
|
@@ -66802,6 +66811,39 @@ function extractHandlerCode(handler) {
|
|
|
66802
66811
|
return code;
|
|
66803
66812
|
}
|
|
66804
66813
|
|
|
66814
|
+
// src/cli/utils/env-file.ts
|
|
66815
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6 } from "fs";
|
|
66816
|
+
import { join as join8 } from "path";
|
|
66817
|
+
function readEnvSecrets(cwd, environment) {
|
|
66818
|
+
const filePath = join8(cwd, `.env.${environment}`);
|
|
66819
|
+
if (!existsSync8(filePath)) {
|
|
66820
|
+
return {};
|
|
66821
|
+
}
|
|
66822
|
+
const content = readFileSync6(filePath, "utf-8");
|
|
66823
|
+
const secrets = {};
|
|
66824
|
+
for (const rawLine of content.split(/\r?\n/)) {
|
|
66825
|
+
const line = rawLine.trim();
|
|
66826
|
+
if (!line || line.startsWith("#")) {
|
|
66827
|
+
continue;
|
|
66828
|
+
}
|
|
66829
|
+
const withoutExport = line.startsWith("export ") ? line.slice(7).trim() : line;
|
|
66830
|
+
const eqIndex = withoutExport.indexOf("=");
|
|
66831
|
+
if (eqIndex === -1) {
|
|
66832
|
+
continue;
|
|
66833
|
+
}
|
|
66834
|
+
const key = withoutExport.slice(0, eqIndex).trim();
|
|
66835
|
+
if (!key) {
|
|
66836
|
+
continue;
|
|
66837
|
+
}
|
|
66838
|
+
let value = withoutExport.slice(eqIndex + 1).trim();
|
|
66839
|
+
if (value.startsWith('"') && value.endsWith('"') && value.length >= 2 || value.startsWith("'") && value.endsWith("'") && value.length >= 2) {
|
|
66840
|
+
value = value.slice(1, -1);
|
|
66841
|
+
}
|
|
66842
|
+
secrets[key] = value;
|
|
66843
|
+
}
|
|
66844
|
+
return secrets;
|
|
66845
|
+
}
|
|
66846
|
+
|
|
66805
66847
|
// src/cli/utils/validator.ts
|
|
66806
66848
|
var INTEGRATION_PREFIXES = {
|
|
66807
66849
|
"whatsapp.": "WhatsApp (Kapso)",
|
|
@@ -66894,7 +66936,8 @@ function validateResources(payload, resources) {
|
|
|
66894
66936
|
}
|
|
66895
66937
|
const seenIntegrations = new Set;
|
|
66896
66938
|
for (const agent of payload.agents) {
|
|
66897
|
-
for (const
|
|
66939
|
+
for (const tool of agent.tools) {
|
|
66940
|
+
const toolName = typeof tool === "string" ? tool : tool.name;
|
|
66898
66941
|
for (const [prefix, integration] of Object.entries(INTEGRATION_PREFIXES)) {
|
|
66899
66942
|
if (toolName.startsWith(prefix) && !seenIntegrations.has(integration)) {
|
|
66900
66943
|
seenIntegrations.add(integration);
|
|
@@ -66973,6 +67016,7 @@ ${resources.errors.join(`
|
|
|
66973
67016
|
triggers: payload.triggers,
|
|
66974
67017
|
routers: payload.routers,
|
|
66975
67018
|
workflows: payload.workflows,
|
|
67019
|
+
secrets: readEnvSecrets(cwd, "development"),
|
|
66976
67020
|
organizationId,
|
|
66977
67021
|
environment: "development"
|
|
66978
67022
|
});
|
|
@@ -67090,6 +67134,7 @@ ${resources.errors.join(`
|
|
|
67090
67134
|
if (environment === "production") {
|
|
67091
67135
|
const result = await syncOrganization({
|
|
67092
67136
|
...payload,
|
|
67137
|
+
secrets: readEnvSecrets(cwd, "production"),
|
|
67093
67138
|
organizationId,
|
|
67094
67139
|
environment: "production"
|
|
67095
67140
|
});
|
|
@@ -67102,7 +67147,7 @@ ${resources.errors.join(`
|
|
|
67102
67147
|
}
|
|
67103
67148
|
return performDevSync(cwd, organizationId);
|
|
67104
67149
|
}
|
|
67105
|
-
var syncCommand = new Command5("sync").description("Sync resources to Convex and exit").option("--force", "Skip destructive sync confirmation").option("--json", "Output results as JSON").option("--dry-run", "Show what would be synced without syncing").option("--env <environment>", "Target environment (development|production|eval)").action(async (options) => {
|
|
67150
|
+
var syncCommand = new Command5("sync").description("Sync resources to Convex and exit. Syncs .env.development (development) or .env.production (production) from the project root as secrets; development secrets are mirrored to eval.").option("--force", "Skip destructive sync confirmation").option("--json", "Output results as JSON").option("--dry-run", "Show what would be synced without syncing").option("--env <environment>", "Target environment (development|production|eval)").action(async (options) => {
|
|
67106
67151
|
const cwd = process.cwd();
|
|
67107
67152
|
const jsonMode = !!options.json;
|
|
67108
67153
|
const output = createOutput();
|
|
@@ -67174,9 +67219,9 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
67174
67219
|
const payload = await extractSyncPayload(resources);
|
|
67175
67220
|
if (!jsonMode)
|
|
67176
67221
|
output.stop();
|
|
67177
|
-
let
|
|
67222
|
+
let deletions2 = [];
|
|
67178
67223
|
try {
|
|
67179
|
-
|
|
67224
|
+
deletions2 = await checkForDeletions(resources, project.organization.id, environment);
|
|
67180
67225
|
} catch {}
|
|
67181
67226
|
if (jsonMode) {
|
|
67182
67227
|
console.log(JSON.stringify({
|
|
@@ -67189,7 +67234,7 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
67189
67234
|
triggers: (payload.triggers || []).map((t2) => t2.slug),
|
|
67190
67235
|
routers: (payload.routers || []).map((r) => r.slug),
|
|
67191
67236
|
workflows: (payload.workflows || []).map((w) => w.slug),
|
|
67192
|
-
deletions:
|
|
67237
|
+
deletions: deletions2.map((d) => ({ type: d.type, names: d.deleted }))
|
|
67193
67238
|
}));
|
|
67194
67239
|
} else {
|
|
67195
67240
|
console.log(chalk6.bold("Dry run — nothing will be synced"));
|
|
@@ -67201,10 +67246,10 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
67201
67246
|
console.log(chalk6.gray(" Triggers:"), (payload.triggers || []).map((t2) => t2.slug).join(", ") || "none");
|
|
67202
67247
|
console.log(chalk6.gray(" Routers:"), (payload.routers || []).map((r) => r.slug).join(", ") || "none");
|
|
67203
67248
|
console.log(chalk6.gray(" Workflows:"), (payload.workflows || []).map((w) => w.slug).join(", ") || "none");
|
|
67204
|
-
if (
|
|
67249
|
+
if (deletions2.length > 0) {
|
|
67205
67250
|
console.log();
|
|
67206
67251
|
console.log(chalk6.yellow.bold(" Would delete:"));
|
|
67207
|
-
for (const d of
|
|
67252
|
+
for (const d of deletions2) {
|
|
67208
67253
|
for (const name of d.deleted) {
|
|
67209
67254
|
console.log(chalk6.red(` - ${d.type}: ${name}`));
|
|
67210
67255
|
}
|
|
@@ -67214,35 +67259,43 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
67214
67259
|
}
|
|
67215
67260
|
return;
|
|
67216
67261
|
}
|
|
67217
|
-
if (!
|
|
67262
|
+
if (!jsonMode)
|
|
67263
|
+
output.start("Checking remote state");
|
|
67264
|
+
let deletions = [];
|
|
67265
|
+
try {
|
|
67266
|
+
deletions = await checkForDeletions(resources, project.organization.id, environment);
|
|
67218
67267
|
if (!jsonMode)
|
|
67219
|
-
output.
|
|
67220
|
-
|
|
67221
|
-
|
|
67222
|
-
|
|
67223
|
-
|
|
67224
|
-
|
|
67225
|
-
|
|
67226
|
-
|
|
67227
|
-
|
|
67228
|
-
|
|
67229
|
-
|
|
67230
|
-
|
|
67231
|
-
|
|
67232
|
-
|
|
67233
|
-
|
|
67234
|
-
console.log(chalk6.
|
|
67235
|
-
console.log();
|
|
67236
|
-
const shouldContinue = await confirm2({ message: "Continue anyway?", default: false });
|
|
67237
|
-
if (!shouldContinue) {
|
|
67238
|
-
console.log(chalk6.gray("Aborted."));
|
|
67239
|
-
process.exit(0);
|
|
67240
|
-
}
|
|
67241
|
-
console.log();
|
|
67268
|
+
output.stop();
|
|
67269
|
+
} catch (err) {
|
|
67270
|
+
if (!jsonMode) {
|
|
67271
|
+
output.stop();
|
|
67272
|
+
console.log(chalk6.yellow.bold(" ⚠ Could not verify which remote resources would be deleted:"), err instanceof Error ? err.message : String(err));
|
|
67273
|
+
console.log(chalk6.yellow(" Proceeding — a destructive sync cannot be ruled out."));
|
|
67274
|
+
console.log();
|
|
67275
|
+
}
|
|
67276
|
+
}
|
|
67277
|
+
if (deletions.length > 0 && !jsonMode) {
|
|
67278
|
+
console.log(chalk6.red.bold(" ⚠ WARNING: this sync will DELETE remote resources:"));
|
|
67279
|
+
console.log();
|
|
67280
|
+
for (const d of deletions) {
|
|
67281
|
+
console.log(chalk6.yellow(` ${d.type}:`.padEnd(20)), `${d.remote} remote → ${d.local} local`, chalk6.red(`(${d.deleted.length} will be deleted)`));
|
|
67282
|
+
for (const name of d.deleted) {
|
|
67283
|
+
console.log(chalk6.red(` - ${name}`));
|
|
67242
67284
|
}
|
|
67243
|
-
}
|
|
67244
|
-
|
|
67245
|
-
|
|
67285
|
+
}
|
|
67286
|
+
console.log();
|
|
67287
|
+
console.log(chalk6.gray(" Run"), chalk6.cyan("struere pull"), chalk6.gray("first to download remote resources."));
|
|
67288
|
+
console.log();
|
|
67289
|
+
if (!shouldForce) {
|
|
67290
|
+
const shouldContinue = await confirm2({ message: "Continue anyway?", default: false });
|
|
67291
|
+
if (!shouldContinue) {
|
|
67292
|
+
console.log(chalk6.gray("Aborted."));
|
|
67293
|
+
process.exit(0);
|
|
67294
|
+
}
|
|
67295
|
+
console.log();
|
|
67296
|
+
} else {
|
|
67297
|
+
console.log(chalk6.yellow(" Proceeding without confirmation (non-interactive or --force)."));
|
|
67298
|
+
console.log();
|
|
67246
67299
|
}
|
|
67247
67300
|
}
|
|
67248
67301
|
if (!jsonMode)
|
|
@@ -67335,7 +67388,7 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
67335
67388
|
|
|
67336
67389
|
// src/cli/commands/dev.ts
|
|
67337
67390
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
67338
|
-
var devCommand = new Command6("dev").description("Watch files and sync to development on change (long-running)").option("--force", "Skip destructive sync confirmation").action(async (options) => {
|
|
67391
|
+
var devCommand = new Command6("dev").description("Watch files and sync to development on change (long-running). Syncs .env.development from the project root as secrets; development secrets are mirrored to eval.").option("--force", "Skip destructive sync confirmation").action(async (options) => {
|
|
67339
67392
|
const spinner = ora6();
|
|
67340
67393
|
const cwd = process.cwd();
|
|
67341
67394
|
const apiKey = getApiKey();
|
|
@@ -67383,8 +67436,8 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
67383
67436
|
}
|
|
67384
67437
|
console.log();
|
|
67385
67438
|
}
|
|
67386
|
-
const claudeMdPath =
|
|
67387
|
-
if (!
|
|
67439
|
+
const claudeMdPath = join9(cwd, "CLAUDE.md");
|
|
67440
|
+
if (!existsSync9(claudeMdPath)) {
|
|
67388
67441
|
try {
|
|
67389
67442
|
const { generated } = await generateDocs(cwd, ["claude"]);
|
|
67390
67443
|
if (generated.length > 0) {
|
|
@@ -67411,23 +67464,31 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
67411
67464
|
console.log(chalk7.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
67412
67465
|
}
|
|
67413
67466
|
const shouldSkipConfirmation = options.force || nonInteractive;
|
|
67414
|
-
if (initialSyncOk &&
|
|
67467
|
+
if (initialSyncOk && loadedResources) {
|
|
67415
67468
|
spinner.start("Checking remote state");
|
|
67469
|
+
let deletions = [];
|
|
67416
67470
|
try {
|
|
67417
|
-
|
|
67471
|
+
deletions = await checkForDeletions(loadedResources, project.organization.id, "development");
|
|
67418
67472
|
spinner.stop();
|
|
67419
|
-
|
|
67420
|
-
|
|
67421
|
-
|
|
67422
|
-
|
|
67423
|
-
|
|
67424
|
-
|
|
67425
|
-
|
|
67426
|
-
|
|
67473
|
+
} catch (err) {
|
|
67474
|
+
spinner.stop();
|
|
67475
|
+
console.log(chalk7.yellow.bold(" ⚠ Could not verify which remote resources would be deleted:"), err instanceof Error ? err.message : String(err));
|
|
67476
|
+
console.log(chalk7.yellow(" Proceeding — a destructive sync cannot be ruled out."));
|
|
67477
|
+
console.log();
|
|
67478
|
+
}
|
|
67479
|
+
if (deletions.length > 0) {
|
|
67480
|
+
console.log(chalk7.red.bold(" ⚠ WARNING: this sync will DELETE remote resources:"));
|
|
67481
|
+
console.log();
|
|
67482
|
+
for (const d of deletions) {
|
|
67483
|
+
console.log(chalk7.yellow(` ${d.type}:`.padEnd(20)), `${d.remote} remote → ${d.local} local`, chalk7.red(`(${d.deleted.length} will be deleted)`));
|
|
67484
|
+
for (const name of d.deleted) {
|
|
67485
|
+
console.log(chalk7.red(` - ${name}`));
|
|
67427
67486
|
}
|
|
67428
|
-
|
|
67429
|
-
|
|
67430
|
-
|
|
67487
|
+
}
|
|
67488
|
+
console.log();
|
|
67489
|
+
console.log(chalk7.gray(" Run"), chalk7.cyan("struere pull"), chalk7.gray("first to download remote resources."));
|
|
67490
|
+
console.log();
|
|
67491
|
+
if (!shouldSkipConfirmation) {
|
|
67431
67492
|
const shouldContinue = await confirm3({ message: "Continue anyway?", default: false });
|
|
67432
67493
|
if (!shouldContinue) {
|
|
67433
67494
|
console.log();
|
|
@@ -67435,9 +67496,10 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
67435
67496
|
process.exit(0);
|
|
67436
67497
|
}
|
|
67437
67498
|
console.log();
|
|
67499
|
+
} else {
|
|
67500
|
+
console.log(chalk7.yellow(" Proceeding without confirmation (non-interactive or --force)."));
|
|
67501
|
+
console.log();
|
|
67438
67502
|
}
|
|
67439
|
-
} catch {
|
|
67440
|
-
spinner.stop();
|
|
67441
67503
|
}
|
|
67442
67504
|
}
|
|
67443
67505
|
if (initialSyncOk) {
|
|
@@ -67480,7 +67542,7 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
67480
67542
|
dirs.routers,
|
|
67481
67543
|
dirs.workflows,
|
|
67482
67544
|
dirs.fixtures
|
|
67483
|
-
].filter((p) =>
|
|
67545
|
+
].filter((p) => existsSync9(p));
|
|
67484
67546
|
const watcher = chokidar.watch(watchPaths, {
|
|
67485
67547
|
ignoreInitial: true,
|
|
67486
67548
|
ignored: [/node_modules/, /\.struere-tmp-/, /evals\/runs\//],
|
|
@@ -67498,6 +67560,23 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
67498
67560
|
}
|
|
67499
67561
|
const syncSpinner = ora6("Syncing...").start();
|
|
67500
67562
|
try {
|
|
67563
|
+
try {
|
|
67564
|
+
const watchResources = await loadAllResources(cwd);
|
|
67565
|
+
if (watchResources.errors.length === 0) {
|
|
67566
|
+
const deletions = await checkForDeletions(watchResources, project.organization.id, "development");
|
|
67567
|
+
if (deletions.length > 0) {
|
|
67568
|
+
syncSpinner.stop();
|
|
67569
|
+
console.log(chalk7.red.bold(" ⚠ WARNING: this sync will DELETE remote resources:"));
|
|
67570
|
+
for (const d of deletions) {
|
|
67571
|
+
for (const name of d.deleted) {
|
|
67572
|
+
console.log(chalk7.red(` - ${d.type}: ${name}`));
|
|
67573
|
+
}
|
|
67574
|
+
}
|
|
67575
|
+
console.log(chalk7.gray(" Run"), chalk7.cyan("struere pull"), chalk7.gray("to restore them locally."));
|
|
67576
|
+
syncSpinner.start("Syncing...");
|
|
67577
|
+
}
|
|
67578
|
+
}
|
|
67579
|
+
} catch {}
|
|
67501
67580
|
await performDevSync(cwd, project.organization.id);
|
|
67502
67581
|
syncSpinner.succeed("Synced");
|
|
67503
67582
|
} catch (error) {
|
|
@@ -67537,7 +67616,7 @@ import chalk8 from "chalk";
|
|
|
67537
67616
|
import ora7 from "ora";
|
|
67538
67617
|
import { confirm as confirm4 } from "@inquirer/prompts";
|
|
67539
67618
|
init_convex();
|
|
67540
|
-
var deployCommand = new Command7("deploy").description("Deploy all resources to production").option("--dry-run", "Show what would be deployed without deploying").option("--force", "Skip destructive sync confirmation").option("--json", "Output results as JSON").option("-v, --verbose", "Show detailed resource information").action(async (options) => {
|
|
67619
|
+
var deployCommand = new Command7("deploy").description("Deploy all resources to production. Syncs .env.production from the project root as secrets.").option("--dry-run", "Show what would be deployed without deploying").option("--force", "Skip destructive sync confirmation").option("--json", "Output results as JSON").option("-v, --verbose", "Show detailed resource information").action(async (options) => {
|
|
67541
67620
|
const spinner = ora7();
|
|
67542
67621
|
const cwd = process.cwd();
|
|
67543
67622
|
const nonInteractive = !isInteractive();
|
|
@@ -67781,6 +67860,7 @@ var deployCommand = new Command7("deploy").description("Deploy all resources to
|
|
|
67781
67860
|
roles: payload.roles,
|
|
67782
67861
|
triggers: payload.triggers,
|
|
67783
67862
|
routers: payload.routers,
|
|
67863
|
+
secrets: readEnvSecrets(cwd, "production"),
|
|
67784
67864
|
organizationId: project.organization.id,
|
|
67785
67865
|
environment: "production"
|
|
67786
67866
|
});
|
|
@@ -68529,8 +68609,8 @@ init_credentials();
|
|
|
68529
68609
|
import { Command as Command12 } from "commander";
|
|
68530
68610
|
import chalk13 from "chalk";
|
|
68531
68611
|
import ora10 from "ora";
|
|
68532
|
-
import { existsSync as
|
|
68533
|
-
import { join as
|
|
68612
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
|
|
68613
|
+
import { join as join10 } from "path";
|
|
68534
68614
|
init_convex();
|
|
68535
68615
|
|
|
68536
68616
|
// src/cli/utils/generator.ts
|
|
@@ -68950,13 +69030,13 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
|
|
|
68950
69030
|
const created = [];
|
|
68951
69031
|
const skipped = [];
|
|
68952
69032
|
const ensureDir2 = (dir) => {
|
|
68953
|
-
if (!
|
|
69033
|
+
if (!existsSync10(dir)) {
|
|
68954
69034
|
mkdirSync6(dir, { recursive: true });
|
|
68955
69035
|
}
|
|
68956
69036
|
};
|
|
68957
69037
|
const writeOrSkip = (relativePath, content) => {
|
|
68958
|
-
const fullPath =
|
|
68959
|
-
if (
|
|
69038
|
+
const fullPath = join10(cwd, relativePath);
|
|
69039
|
+
if (existsSync10(fullPath) && !options.force) {
|
|
68960
69040
|
skipped.push(relativePath);
|
|
68961
69041
|
return false;
|
|
68962
69042
|
}
|
|
@@ -68964,19 +69044,19 @@ var pullCommand = new Command12("pull").description("Pull remote resources to lo
|
|
|
68964
69044
|
created.push(relativePath);
|
|
68965
69045
|
return true;
|
|
68966
69046
|
}
|
|
68967
|
-
ensureDir2(
|
|
69047
|
+
ensureDir2(join10(cwd, relativePath.split("/").slice(0, -1).join("/")));
|
|
68968
69048
|
writeFileSync7(fullPath, content);
|
|
68969
69049
|
created.push(relativePath);
|
|
68970
69050
|
return true;
|
|
68971
69051
|
};
|
|
68972
|
-
ensureDir2(
|
|
68973
|
-
ensureDir2(
|
|
68974
|
-
ensureDir2(
|
|
68975
|
-
ensureDir2(
|
|
68976
|
-
ensureDir2(
|
|
68977
|
-
ensureDir2(
|
|
68978
|
-
ensureDir2(
|
|
68979
|
-
ensureDir2(
|
|
69052
|
+
ensureDir2(join10(cwd, "agents"));
|
|
69053
|
+
ensureDir2(join10(cwd, "entity-types"));
|
|
69054
|
+
ensureDir2(join10(cwd, "views"));
|
|
69055
|
+
ensureDir2(join10(cwd, "roles"));
|
|
69056
|
+
ensureDir2(join10(cwd, "triggers"));
|
|
69057
|
+
ensureDir2(join10(cwd, "routers"));
|
|
69058
|
+
ensureDir2(join10(cwd, "workflows"));
|
|
69059
|
+
ensureDir2(join10(cwd, "tools"));
|
|
68980
69060
|
const agentSlugs = [];
|
|
68981
69061
|
for (const agent of state.agents) {
|
|
68982
69062
|
if (!agent.systemPrompt && agent.tools.length === 0)
|
|
@@ -70018,7 +70098,8 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
|
|
|
70018
70098
|
const duration = closestExec.durationMs;
|
|
70019
70099
|
const inputTokens = closestExec.inputTokens;
|
|
70020
70100
|
const outputTokens = closestExec.outputTokens;
|
|
70021
|
-
|
|
70101
|
+
const agent = closestExec.agentSlug ?? closestExec.agentId ?? "";
|
|
70102
|
+
console.log(` ${chalk16.dim(` exec: ${statusColor(status)} ${chalk16.cyan(agent)} ${model ?? ""} ${inputTokens ?? 0}in/${outputTokens ?? 0}out ${duration ?? 0}ms`)}`);
|
|
70022
70103
|
if (closestExec.errorMessage) {
|
|
70023
70104
|
console.log(` ${chalk16.red(` error: ${closestExec.errorMessage}`)}`);
|
|
70024
70105
|
}
|
|
@@ -70033,7 +70114,7 @@ init_credentials();
|
|
|
70033
70114
|
import { Command as Command15 } from "commander";
|
|
70034
70115
|
import chalk17 from "chalk";
|
|
70035
70116
|
import ora13 from "ora";
|
|
70036
|
-
import { join as
|
|
70117
|
+
import { join as join11 } from "path";
|
|
70037
70118
|
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync8 } from "fs";
|
|
70038
70119
|
init_convex();
|
|
70039
70120
|
|
|
@@ -70471,15 +70552,15 @@ var runCommand = new Command15("run").description("Run an eval suite").argument(
|
|
|
70471
70552
|
const agentSlug = suiteSlug;
|
|
70472
70553
|
const timestamp = new Date().toISOString().replace(/:/g, "-").replace(/\.\d+Z$/, "");
|
|
70473
70554
|
const folderName = `${timestamp}_${suiteSlug}`;
|
|
70474
|
-
const outDir =
|
|
70555
|
+
const outDir = join11(cwd, "evals", "runs", folderName);
|
|
70475
70556
|
mkdirSync7(outDir, { recursive: true });
|
|
70476
70557
|
const summaryMd = generateSummaryMd(suite.name, suite.slug, agentSlug, run, results);
|
|
70477
|
-
writeFileSync8(
|
|
70558
|
+
writeFileSync8(join11(outDir, "_summary.md"), summaryMd);
|
|
70478
70559
|
for (const r of results) {
|
|
70479
70560
|
const label = statusLabel(r);
|
|
70480
70561
|
const fileName = `${label}_${slugify3(r.caseName)}.md`;
|
|
70481
70562
|
const caseMd = generateCaseMd(r);
|
|
70482
|
-
writeFileSync8(
|
|
70563
|
+
writeFileSync8(join11(outDir, fileName), caseMd);
|
|
70483
70564
|
}
|
|
70484
70565
|
const relativePath = `evals/runs/${folderName}/`;
|
|
70485
70566
|
console.log();
|
|
@@ -70494,7 +70575,7 @@ evalCommand.addCommand(runCommand);
|
|
|
70494
70575
|
init_credentials();
|
|
70495
70576
|
import { Command as Command16 } from "commander";
|
|
70496
70577
|
import chalk18 from "chalk";
|
|
70497
|
-
import { readFileSync as
|
|
70578
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
70498
70579
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
70499
70580
|
|
|
70500
70581
|
// src/cli/utils/whatsapp.ts
|
|
@@ -70843,7 +70924,7 @@ templatesCommand.command("create <name>").description("Create a new message temp
|
|
|
70843
70924
|
let components;
|
|
70844
70925
|
if (opts.file) {
|
|
70845
70926
|
try {
|
|
70846
|
-
const fileContent =
|
|
70927
|
+
const fileContent = readFileSync7(opts.file, "utf-8");
|
|
70847
70928
|
const parsed = JSON.parse(fileContent);
|
|
70848
70929
|
components = Array.isArray(parsed) ? parsed : parsed.components ?? [parsed];
|
|
70849
70930
|
} catch (err) {
|
|
@@ -70974,7 +71055,7 @@ templatesCommand.command("edit <name>").description("Edit a message template").o
|
|
|
70974
71055
|
let components;
|
|
70975
71056
|
if (opts.file) {
|
|
70976
71057
|
try {
|
|
70977
|
-
const fileContent =
|
|
71058
|
+
const fileContent = readFileSync7(opts.file, "utf-8");
|
|
70978
71059
|
const parsed = JSON.parse(fileContent);
|
|
70979
71060
|
components = Array.isArray(parsed) ? parsed : parsed.components ?? [parsed];
|
|
70980
71061
|
} catch (err) {
|
|
@@ -72476,8 +72557,8 @@ init_credentials();
|
|
|
72476
72557
|
import { Command as Command19 } from "commander";
|
|
72477
72558
|
import chalk21 from "chalk";
|
|
72478
72559
|
import ora15 from "ora";
|
|
72479
|
-
import { existsSync as
|
|
72480
|
-
import { join as
|
|
72560
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9 } from "fs";
|
|
72561
|
+
import { join as join12 } from "path";
|
|
72481
72562
|
init_convex();
|
|
72482
72563
|
|
|
72483
72564
|
// src/cli/utils/workflows.ts
|
|
@@ -72576,6 +72657,9 @@ async function cancelWorkflowRun(runId, environment, organizationId) {
|
|
|
72576
72657
|
async function retryWorkflowRun(runId, environment, organizationId) {
|
|
72577
72658
|
return convexMutation6("workflows:retryRun", { runId, environment, ...organizationId && { organizationId } });
|
|
72578
72659
|
}
|
|
72660
|
+
async function retriggerWorkflowRun(runId, environment, organizationId) {
|
|
72661
|
+
return convexMutation6("workflows:retriggerRun", { runId, environment, ...organizationId && { organizationId } });
|
|
72662
|
+
}
|
|
72579
72663
|
async function toggleWorkflow(slug, enabled, environment, organizationId) {
|
|
72580
72664
|
const path = enabled ? "workflows:enable" : "workflows:disable";
|
|
72581
72665
|
return convexMutation6(path, { slug, environment, ...organizationId && { organizationId } });
|
|
@@ -72816,8 +72900,8 @@ function renderNodeRuns(nodeRuns, verbose) {
|
|
|
72816
72900
|
console.log();
|
|
72817
72901
|
});
|
|
72818
72902
|
}
|
|
72819
|
-
var workflowsCommand = new Command19("workflows").description("Manage workflows and
|
|
72820
|
-
workflowsCommand.command("list", { isDefault: true }).description("List all workflows").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--failed", "Show only workflows with recent failures").action(async (opts) => {
|
|
72903
|
+
var workflowsCommand = new Command19("workflows").description("Manage graph-based workflows and inspect, fire, and recover their runs");
|
|
72904
|
+
workflowsCommand.command("list", { isDefault: true }).description("List all workflows with trigger, node count, enabled state, and last-run status").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--failed", "Show only workflows with recent failures").action(async (opts) => {
|
|
72821
72905
|
await ensureAuth6();
|
|
72822
72906
|
const spinner = opts.json ? null : ora15();
|
|
72823
72907
|
try {
|
|
@@ -72869,7 +72953,7 @@ workflowsCommand.command("list", { isDefault: true }).description("List all work
|
|
|
72869
72953
|
process.exit(1);
|
|
72870
72954
|
}
|
|
72871
72955
|
});
|
|
72872
|
-
workflowsCommand.command("get <slug>").description("View workflow
|
|
72956
|
+
workflowsCommand.command("get <slug>").description("View a workflow definition: metadata and the node graph with per-port edges").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
72873
72957
|
await ensureAuth6();
|
|
72874
72958
|
const spinner = opts.json ? null : ora15();
|
|
72875
72959
|
try {
|
|
@@ -72922,7 +73006,7 @@ workflowsCommand.command("get <slug>").description("View workflow details").opti
|
|
|
72922
73006
|
process.exit(1);
|
|
72923
73007
|
}
|
|
72924
73008
|
});
|
|
72925
|
-
workflowsCommand.command("runs [slug]").description("List workflow runs").option("--env <environment>", "Environment", "development").option("--status <status>", "Filter by status (pending|running|completed|completed_with_errors|failed|dead)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
73009
|
+
workflowsCommand.command("runs [slug]").description("List workflow runs (optionally for one workflow), filterable by status").option("--env <environment>", "Environment", "development").option("--status <status>", "Filter by status (pending|running|completed|completed_with_errors|failed|dead)").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
72926
73010
|
await ensureAuth6();
|
|
72927
73011
|
const spinner = opts.json ? null : ora15();
|
|
72928
73012
|
try {
|
|
@@ -72967,7 +73051,7 @@ workflowsCommand.command("runs [slug]").description("List workflow runs").option
|
|
|
72967
73051
|
process.exit(1);
|
|
72968
73052
|
}
|
|
72969
73053
|
});
|
|
72970
|
-
workflowsCommand.command("run <run-id>").description("View
|
|
73054
|
+
workflowsCommand.command("run <run-id>").description("View a run in detail: status, timing, and the per-node execution timeline").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("-v, --verbose", "Show full error messages").action(async (runId, opts) => {
|
|
72971
73055
|
await ensureAuth6();
|
|
72972
73056
|
const spinner = opts.json ? null : ora15();
|
|
72973
73057
|
try {
|
|
@@ -73010,7 +73094,7 @@ workflowsCommand.command("run <run-id>").description("View workflow run details"
|
|
|
73010
73094
|
process.exit(1);
|
|
73011
73095
|
}
|
|
73012
73096
|
});
|
|
73013
|
-
workflowsCommand.command("stats").description("Show
|
|
73097
|
+
workflowsCommand.command("stats").description("Show run counts grouped by status for an environment").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (opts) => {
|
|
73014
73098
|
await ensureAuth6();
|
|
73015
73099
|
const spinner = opts.json ? null : ora15();
|
|
73016
73100
|
try {
|
|
@@ -73053,7 +73137,7 @@ workflowsCommand.command("stats").description("Show workflow run statistics").op
|
|
|
73053
73137
|
process.exit(1);
|
|
73054
73138
|
}
|
|
73055
73139
|
});
|
|
73056
|
-
workflowsCommand.command("logs [slug]").description("
|
|
73140
|
+
workflowsCommand.command("logs [slug]").description("List recent execution history (optionally for one workflow)").option("--env <environment>", "Environment", "development").option("--limit <n>", "Maximum results", "10").option("--json", "Output raw JSON").option("-v, --verbose", "Show full error messages").action(async (slug, opts) => {
|
|
73057
73141
|
await ensureAuth6();
|
|
73058
73142
|
const spinner = opts.json ? null : ora15();
|
|
73059
73143
|
try {
|
|
@@ -73169,7 +73253,7 @@ workflowsCommand.command("log <identifier>").description("View detailed workflow
|
|
|
73169
73253
|
process.exit(1);
|
|
73170
73254
|
}
|
|
73171
73255
|
});
|
|
73172
|
-
workflowsCommand.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) => {
|
|
73256
|
+
workflowsCommand.command("retry <run-id>").description("Retry a failed or dead run, resuming at the dead node (completed branches are not re-run)").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (runId, opts) => {
|
|
73173
73257
|
await ensureAuth6();
|
|
73174
73258
|
const spinner = opts.json ? null : ora15();
|
|
73175
73259
|
const environment = opts.env;
|
|
@@ -73184,10 +73268,44 @@ workflowsCommand.command("retry <run-id>").description("Retry a failed or dead r
|
|
|
73184
73268
|
}
|
|
73185
73269
|
try {
|
|
73186
73270
|
spinner?.start("Retrying run...");
|
|
73187
|
-
await retryWorkflowRun(runId, environment, getOrgId4());
|
|
73271
|
+
const res = await retryWorkflowRun(runId, environment, getOrgId4());
|
|
73272
|
+
if (res.outcome === "definition_changed") {
|
|
73273
|
+
spinner?.stop();
|
|
73274
|
+
if (opts.json) {
|
|
73275
|
+
console.log(JSON.stringify({ success: false, outcome: "definition_changed", runId }));
|
|
73276
|
+
return;
|
|
73277
|
+
}
|
|
73278
|
+
console.log(chalk21.yellow("This run was created on an earlier version of the workflow, so it can't be resumed."));
|
|
73279
|
+
if (isInteractive()) {
|
|
73280
|
+
const readline = await import("readline");
|
|
73281
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
73282
|
+
const answer = await new Promise((resolve) => {
|
|
73283
|
+
rl.question(" Run it again from the start with the original input? This re-executes every step (y/N): ", resolve);
|
|
73284
|
+
});
|
|
73285
|
+
rl.close();
|
|
73286
|
+
if (answer.trim().toLowerCase() === "y") {
|
|
73287
|
+
const fresh = await retriggerWorkflowRun(runId, environment, getOrgId4());
|
|
73288
|
+
console.log(chalk21.green(`Started a fresh run: ${fresh.runId}`));
|
|
73289
|
+
} else {
|
|
73290
|
+
console.log(chalk21.dim("Skipped — re-run anytime with: struere workflows fire <slug>"));
|
|
73291
|
+
}
|
|
73292
|
+
} else {
|
|
73293
|
+
console.log(chalk21.dim("Re-run it with: struere workflows fire <slug>"));
|
|
73294
|
+
}
|
|
73295
|
+
return;
|
|
73296
|
+
}
|
|
73297
|
+
if (res.outcome === "nothing_to_retry") {
|
|
73298
|
+
spinner?.stop();
|
|
73299
|
+
if (opts.json) {
|
|
73300
|
+
console.log(JSON.stringify({ success: false, outcome: "nothing_to_retry", runId }));
|
|
73301
|
+
return;
|
|
73302
|
+
}
|
|
73303
|
+
console.log(chalk21.dim("Nothing to retry on this run."));
|
|
73304
|
+
return;
|
|
73305
|
+
}
|
|
73188
73306
|
spinner?.succeed(chalk21.green(`Run ${runId} queued for retry`));
|
|
73189
73307
|
if (opts.json) {
|
|
73190
|
-
console.log(JSON.stringify({ success: true, runId }));
|
|
73308
|
+
console.log(JSON.stringify({ success: true, outcome: "resumed", runId }));
|
|
73191
73309
|
}
|
|
73192
73310
|
} catch (err) {
|
|
73193
73311
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -73200,7 +73318,7 @@ workflowsCommand.command("retry <run-id>").description("Retry a failed or dead r
|
|
|
73200
73318
|
process.exit(1);
|
|
73201
73319
|
}
|
|
73202
73320
|
});
|
|
73203
|
-
workflowsCommand.command("cancel <run-id>").description("Cancel a pending or running run").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (runId, opts) => {
|
|
73321
|
+
workflowsCommand.command("cancel <run-id>").description("Cancel a pending or running run (marks it dead)").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (runId, opts) => {
|
|
73204
73322
|
await ensureAuth6();
|
|
73205
73323
|
const spinner = opts.json ? null : ora15();
|
|
73206
73324
|
const environment = opts.env;
|
|
@@ -73231,7 +73349,7 @@ workflowsCommand.command("cancel <run-id>").description("Cancel a pending or run
|
|
|
73231
73349
|
process.exit(1);
|
|
73232
73350
|
}
|
|
73233
73351
|
});
|
|
73234
|
-
workflowsCommand.command("enable <slug>").description("Enable a workflow").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
|
|
73352
|
+
workflowsCommand.command("enable <slug>").description("Enable a workflow so it fires on its trigger (schedules next run for cron workflows)").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
|
|
73235
73353
|
await ensureAuth6();
|
|
73236
73354
|
const spinner = opts.json ? null : ora15();
|
|
73237
73355
|
const environment = opts.env;
|
|
@@ -73262,7 +73380,7 @@ workflowsCommand.command("enable <slug>").description("Enable a workflow").optio
|
|
|
73262
73380
|
process.exit(1);
|
|
73263
73381
|
}
|
|
73264
73382
|
});
|
|
73265
|
-
workflowsCommand.command("disable <slug>").description("Disable a workflow").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
|
|
73383
|
+
workflowsCommand.command("disable <slug>").description("Disable a workflow so it stops firing (clears next scheduled run for cron workflows)").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
|
|
73266
73384
|
await ensureAuth6();
|
|
73267
73385
|
const spinner = opts.json ? null : ora15();
|
|
73268
73386
|
const environment = opts.env;
|
|
@@ -73293,7 +73411,7 @@ workflowsCommand.command("disable <slug>").description("Disable a workflow").opt
|
|
|
73293
73411
|
process.exit(1);
|
|
73294
73412
|
}
|
|
73295
73413
|
});
|
|
73296
|
-
workflowsCommand.command("fire <slug>").description("Manually fire a workflow
|
|
73414
|
+
workflowsCommand.command("fire <slug>").description("Manually fire a workflow — starts a real run (no dry-run); test safely in dev/eval").option("--env <environment>", "Environment (development|production|eval)", "development").option("--data <json>", "JSON data for the trigger item").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (slug, opts) => {
|
|
73297
73415
|
await ensureAuth6();
|
|
73298
73416
|
const spinner = opts.json ? null : ora15();
|
|
73299
73417
|
const environment = opts.env;
|
|
@@ -73373,7 +73491,7 @@ workflowsCommand.command("fire <slug>").description("Manually fire a workflow (s
|
|
|
73373
73491
|
process.exit(1);
|
|
73374
73492
|
}
|
|
73375
73493
|
});
|
|
73376
|
-
workflowsCommand.command("import-trigger <slug>").description("Generate a workflow file from a legacy trigger").option("--env <environment>", "Environment to read the trigger from", "development").option("--force", "Overwrite an existing workflow file").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
73494
|
+
workflowsCommand.command("import-trigger <slug>").description("Generate a workflow file (workflows/<slug>.ts) from a legacy linear trigger; leaves the source intact").option("--env <environment>", "Environment to read the trigger from", "development").option("--force", "Overwrite an existing workflow file").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
73377
73495
|
await ensureAuth6();
|
|
73378
73496
|
const spinner = opts.json ? null : ora15();
|
|
73379
73497
|
const cwd = process.cwd();
|
|
@@ -73388,13 +73506,13 @@ workflowsCommand.command("import-trigger <slug>").description("Generate a workfl
|
|
|
73388
73506
|
process.exit(1);
|
|
73389
73507
|
}
|
|
73390
73508
|
const source = convertTriggerToWorkflowSource(trigger);
|
|
73391
|
-
const workflowsDir =
|
|
73392
|
-
if (!
|
|
73509
|
+
const workflowsDir = join12(cwd, "workflows");
|
|
73510
|
+
if (!existsSync11(workflowsDir)) {
|
|
73393
73511
|
mkdirSync8(workflowsDir, { recursive: true });
|
|
73394
73512
|
}
|
|
73395
73513
|
const relativePath = `workflows/${trigger.slug}.ts`;
|
|
73396
|
-
const filePath =
|
|
73397
|
-
if (
|
|
73514
|
+
const filePath = join12(cwd, relativePath);
|
|
73515
|
+
if (existsSync11(filePath) && !opts.force) {
|
|
73398
73516
|
spinner?.fail("Workflow file already exists");
|
|
73399
73517
|
if (opts.json) {
|
|
73400
73518
|
console.log(JSON.stringify({ success: false, error: `${relativePath} already exists (use --force to overwrite)` }));
|
|
@@ -73895,10 +74013,7 @@ threadsCommand.command("view <id>").description("View thread details and message
|
|
|
73895
74013
|
if (thread.externalId) {
|
|
73896
74014
|
console.log(` ${chalk22.gray("External:")} ${chalk22.cyan(thread.externalId)}`);
|
|
73897
74015
|
}
|
|
73898
|
-
console.log(` ${chalk22.gray("Agent:")} ${chalk22.cyan(thread.
|
|
73899
|
-
if (thread.currentAgentId) {
|
|
73900
|
-
console.log(` ${chalk22.gray("Current:")} ${chalk22.cyan(thread.currentAgentId)}`);
|
|
73901
|
-
}
|
|
74016
|
+
console.log(` ${chalk22.gray("Agent:")} ${chalk22.cyan(thread.agentName)}${thread.currentAgentName ? ` ${chalk22.yellow("(routed)")}` : ""}`);
|
|
73902
74017
|
console.log(` ${chalk22.gray("Created:")} ${chalk22.cyan(new Date(thread.createdAt).toISOString())}`);
|
|
73903
74018
|
console.log(` ${chalk22.gray("Updated:")} ${chalk22.cyan(new Date(thread.updatedAt).toISOString())}`);
|
|
73904
74019
|
if (thread.messages?.length) {
|
|
@@ -74008,11 +74123,9 @@ threadsCommand.command("reset").description("Archive a thread by phone number").
|
|
|
74008
74123
|
}
|
|
74009
74124
|
});
|
|
74010
74125
|
async function resolveOrExit(target, environment, json, spinner) {
|
|
74011
|
-
const project = loadProject(process.cwd());
|
|
74012
74126
|
const resolution = await resolveActiveWhatsAppThread({
|
|
74013
74127
|
target,
|
|
74014
|
-
environment
|
|
74015
|
-
organizationId: project?.organization.id
|
|
74128
|
+
environment
|
|
74016
74129
|
});
|
|
74017
74130
|
if (resolution.kind === "none") {
|
|
74018
74131
|
const error = `No active WhatsApp thread found for "${target}" in ${environment}. Did you mean --env production?`;
|
|
@@ -75522,7 +75635,7 @@ function checkWhatsAppConnection(resources) {
|
|
|
75522
75635
|
"whatsapp.getConversation",
|
|
75523
75636
|
"whatsapp.getStatus"
|
|
75524
75637
|
]);
|
|
75525
|
-
const agentsUsingWhatsapp = resources.agents.filter((a) => a.tools?.some((t2) => whatsappTools.has(t2)));
|
|
75638
|
+
const agentsUsingWhatsapp = resources.agents.filter((a) => a.tools?.some((t2) => whatsappTools.has(typeof t2 === "string" ? t2 : t2.name)));
|
|
75526
75639
|
if (agentsUsingWhatsapp.length === 0) {
|
|
75527
75640
|
return {
|
|
75528
75641
|
id: "whatsapp",
|
|
@@ -76194,7 +76307,7 @@ keysCommand.command("revoke <id-or-prefix>").description("Revoke an API key (del
|
|
|
76194
76307
|
// package.json
|
|
76195
76308
|
var package_default = {
|
|
76196
76309
|
name: "struere",
|
|
76197
|
-
version: "0.16.
|
|
76310
|
+
version: "0.16.5",
|
|
76198
76311
|
description: "Build, test, and deploy AI agents",
|
|
76199
76312
|
keywords: [
|
|
76200
76313
|
"ai",
|