struere 0.14.0 → 0.14.2
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 +287 -155
- 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 +6 -1
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/threads.d.ts.map +1 -1
- package/dist/cli/index.js +287 -155
- package/dist/cli/utils/convex.d.ts +7 -0
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/extractor.d.ts +11 -1
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/runtime.d.ts +1 -0
- package/dist/cli/utils/runtime.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -2549,6 +2549,22 @@ import chalk3 from "chalk";
|
|
|
2549
2549
|
function isInteractive() {
|
|
2550
2550
|
return process.stdout.isTTY === true && !process.env.CI && !getApiKey();
|
|
2551
2551
|
}
|
|
2552
|
+
function createSilentOutput() {
|
|
2553
|
+
return {
|
|
2554
|
+
start() {},
|
|
2555
|
+
succeed() {},
|
|
2556
|
+
fail() {},
|
|
2557
|
+
stop() {},
|
|
2558
|
+
info() {},
|
|
2559
|
+
warn() {},
|
|
2560
|
+
error(msg) {
|
|
2561
|
+
console.error(msg);
|
|
2562
|
+
},
|
|
2563
|
+
json(data) {
|
|
2564
|
+
console.log(JSON.stringify(data, null, 2));
|
|
2565
|
+
}
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2552
2568
|
function createOutput() {
|
|
2553
2569
|
if (isInteractive()) {
|
|
2554
2570
|
const spinner = ora3();
|
|
@@ -2658,15 +2674,15 @@ orgCommand.command("list").description("List your organizations").option("--json
|
|
|
2658
2674
|
await refreshToken();
|
|
2659
2675
|
const fresh = loadCredentials();
|
|
2660
2676
|
const token = fresh?.token || credentials.token;
|
|
2661
|
-
const spinner = ora4();
|
|
2662
|
-
spinner
|
|
2677
|
+
const spinner = options.json ? null : ora4();
|
|
2678
|
+
spinner?.start("Fetching organizations");
|
|
2663
2679
|
const { organizations, error } = await listMyOrganizations(token);
|
|
2664
2680
|
if (error) {
|
|
2665
|
-
spinner
|
|
2681
|
+
spinner?.fail("Failed to fetch organizations");
|
|
2666
2682
|
console.log(chalk4.red(error));
|
|
2667
2683
|
process.exit(1);
|
|
2668
2684
|
}
|
|
2669
|
-
spinner
|
|
2685
|
+
spinner?.stop();
|
|
2670
2686
|
if (options.json) {
|
|
2671
2687
|
console.log(JSON.stringify(organizations, null, 2));
|
|
2672
2688
|
return;
|
|
@@ -2706,15 +2722,15 @@ orgCommand.command("create").argument("[name]", "Organization name").description
|
|
|
2706
2722
|
}
|
|
2707
2723
|
name = name.trim();
|
|
2708
2724
|
const slug = options.slug || slugify(name);
|
|
2709
|
-
const spinner = ora4();
|
|
2710
|
-
spinner
|
|
2725
|
+
const spinner = options.json ? null : ora4();
|
|
2726
|
+
spinner?.start("Creating organization");
|
|
2711
2727
|
const { organization, error } = await createOrganization(token, name, slug);
|
|
2712
2728
|
if (error || !organization) {
|
|
2713
|
-
spinner
|
|
2729
|
+
spinner?.fail("Failed to create organization");
|
|
2714
2730
|
console.log(chalk4.red(error || "Unknown error"));
|
|
2715
2731
|
process.exit(1);
|
|
2716
2732
|
}
|
|
2717
|
-
spinner
|
|
2733
|
+
spinner?.stop();
|
|
2718
2734
|
if (options.json) {
|
|
2719
2735
|
console.log(JSON.stringify(organization, null, 2));
|
|
2720
2736
|
return;
|
|
@@ -3110,6 +3126,11 @@ function extractAgentPayload(agent, customToolsMap) {
|
|
|
3110
3126
|
const tools = (agent.tools || []).map((toolName) => {
|
|
3111
3127
|
const isBuiltin = BUILTIN_TOOLS.includes(toolName);
|
|
3112
3128
|
if (!isBuiltin && !customToolsMap.has(toolName)) {
|
|
3129
|
+
const builtinPrefixes = ["entity.", "calendar.", "whatsapp.", "agent.", "airtable.", "email.", "payment.", "web.", "voice.", "router."];
|
|
3130
|
+
const looksBuiltin = builtinPrefixes.some((prefix) => toolName.startsWith(prefix));
|
|
3131
|
+
if (looksBuiltin) {
|
|
3132
|
+
throw new Error(`Agent "${agent.name}" references tool "${toolName}" which looks like a built-in tool but is not recognized. Try updating the CLI: npm install -g struere@latest`);
|
|
3133
|
+
}
|
|
3113
3134
|
const available = customToolsMap.size > 0 ? `Available custom tools: ${Array.from(customToolsMap.keys()).join(", ")}` : "No custom tools were loaded from tools/index.ts";
|
|
3114
3135
|
throw new Error(`Agent "${agent.name}" references tool "${toolName}" but it was not found. ${available}`);
|
|
3115
3136
|
}
|
|
@@ -3205,6 +3226,42 @@ function validateResources(payload, resources) {
|
|
|
3205
3226
|
}
|
|
3206
3227
|
|
|
3207
3228
|
// src/cli/commands/sync.ts
|
|
3229
|
+
class SyncValidationFailureError extends Error {
|
|
3230
|
+
validationErrors;
|
|
3231
|
+
constructor(validationErrors) {
|
|
3232
|
+
super("Server-side validation failed for one or more resources");
|
|
3233
|
+
this.name = "SyncValidationFailureError";
|
|
3234
|
+
this.validationErrors = validationErrors;
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
function renderValidationErrors(errors) {
|
|
3238
|
+
console.log();
|
|
3239
|
+
console.log(chalk6.red.bold("Validation failed \u2014 no changes were applied."));
|
|
3240
|
+
console.log();
|
|
3241
|
+
const labels = {
|
|
3242
|
+
agents: "agent",
|
|
3243
|
+
entityTypes: "entity type",
|
|
3244
|
+
roles: "role",
|
|
3245
|
+
evalSuites: "eval suite",
|
|
3246
|
+
triggers: "trigger",
|
|
3247
|
+
fixtures: "fixture",
|
|
3248
|
+
routers: "router",
|
|
3249
|
+
tools: "tool"
|
|
3250
|
+
};
|
|
3251
|
+
const order = ["agents", "entityTypes", "roles", "evalSuites", "triggers", "fixtures", "routers", "tools"];
|
|
3252
|
+
for (const key of order) {
|
|
3253
|
+
const items = errors[key];
|
|
3254
|
+
if (!items || items.length === 0)
|
|
3255
|
+
continue;
|
|
3256
|
+
const label = labels[key] || key;
|
|
3257
|
+
console.log(chalk6.red.bold(` ${key}:`), chalk6.red(`${items.length} invalid ${label}${items.length === 1 ? "" : "s"}`));
|
|
3258
|
+
for (const item of items) {
|
|
3259
|
+
const id = item.slug || item.name || "(unidentified)";
|
|
3260
|
+
console.log(chalk6.red(` - ${id}: ${item.error}`));
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
console.log();
|
|
3264
|
+
}
|
|
3208
3265
|
async function performDevSync(cwd, organizationId) {
|
|
3209
3266
|
generateTypeDeclarations(cwd);
|
|
3210
3267
|
const resources = await loadAllResources(cwd);
|
|
@@ -3235,6 +3292,8 @@ ${resources.errors.join(`
|
|
|
3235
3292
|
environment: "development"
|
|
3236
3293
|
});
|
|
3237
3294
|
if (!devResult.success) {
|
|
3295
|
+
if (devResult.validationErrors)
|
|
3296
|
+
throw new SyncValidationFailureError(devResult.validationErrors);
|
|
3238
3297
|
throw new Error(devResult.error || "Dev sync failed");
|
|
3239
3298
|
}
|
|
3240
3299
|
const hasEvalContent = payload.evalSuites && payload.evalSuites.length > 0 || payload.fixtures && payload.fixtures.length > 0;
|
|
@@ -3250,6 +3309,8 @@ ${resources.errors.join(`
|
|
|
3250
3309
|
environment: "eval"
|
|
3251
3310
|
});
|
|
3252
3311
|
if (!evalResult.success) {
|
|
3312
|
+
if (evalResult.validationErrors)
|
|
3313
|
+
throw new SyncValidationFailureError(evalResult.validationErrors);
|
|
3253
3314
|
throw new Error(evalResult.error || "Eval sync failed");
|
|
3254
3315
|
}
|
|
3255
3316
|
}
|
|
@@ -3322,8 +3383,11 @@ ${resources.errors.join(`
|
|
|
3322
3383
|
organizationId,
|
|
3323
3384
|
environment: "eval"
|
|
3324
3385
|
});
|
|
3325
|
-
if (!result.success)
|
|
3386
|
+
if (!result.success) {
|
|
3387
|
+
if (result.validationErrors)
|
|
3388
|
+
throw new SyncValidationFailureError(result.validationErrors);
|
|
3326
3389
|
throw new Error(result.error || "Eval sync failed");
|
|
3390
|
+
}
|
|
3327
3391
|
return result;
|
|
3328
3392
|
}
|
|
3329
3393
|
if (environment === "production") {
|
|
@@ -3332,8 +3396,11 @@ ${resources.errors.join(`
|
|
|
3332
3396
|
organizationId,
|
|
3333
3397
|
environment: "production"
|
|
3334
3398
|
});
|
|
3335
|
-
if (!result.success)
|
|
3399
|
+
if (!result.success) {
|
|
3400
|
+
if (result.validationErrors)
|
|
3401
|
+
throw new SyncValidationFailureError(result.validationErrors);
|
|
3336
3402
|
throw new Error(result.error || "Production sync failed");
|
|
3403
|
+
}
|
|
3337
3404
|
return result;
|
|
3338
3405
|
}
|
|
3339
3406
|
return performDevSync(cwd, organizationId);
|
|
@@ -3481,8 +3548,42 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
3481
3548
|
output.start("Syncing to Convex");
|
|
3482
3549
|
try {
|
|
3483
3550
|
const result = await syncToEnvironment(cwd, project.organization.id, environment);
|
|
3484
|
-
if (!jsonMode)
|
|
3551
|
+
if (!jsonMode) {
|
|
3485
3552
|
output.succeed(`Synced to ${environment}`);
|
|
3553
|
+
console.log();
|
|
3554
|
+
const types = [
|
|
3555
|
+
{ label: "agent", data: result.agents },
|
|
3556
|
+
{ label: "entity type", data: result.entityTypes },
|
|
3557
|
+
{ label: "role", data: result.roles },
|
|
3558
|
+
{ label: "trigger", data: result.triggers },
|
|
3559
|
+
{ label: "router", data: result.routers },
|
|
3560
|
+
{ label: "eval suite", data: result.evalSuites }
|
|
3561
|
+
];
|
|
3562
|
+
let hasChanges = false;
|
|
3563
|
+
for (const { label, data } of types) {
|
|
3564
|
+
if (!data)
|
|
3565
|
+
continue;
|
|
3566
|
+
for (const name of data.created) {
|
|
3567
|
+
console.log(chalk6.green(` + Created ${label}: ${name}`));
|
|
3568
|
+
hasChanges = true;
|
|
3569
|
+
}
|
|
3570
|
+
for (const name of data.updated) {
|
|
3571
|
+
console.log(chalk6.blue(` ~ Updated ${label}: ${name}`));
|
|
3572
|
+
hasChanges = true;
|
|
3573
|
+
}
|
|
3574
|
+
for (const name of data.deleted) {
|
|
3575
|
+
console.log(chalk6.red(` - Deleted ${label}: ${name}`));
|
|
3576
|
+
hasChanges = true;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
if (!hasChanges) {
|
|
3580
|
+
console.log(chalk6.gray(" No changes detected"));
|
|
3581
|
+
}
|
|
3582
|
+
if (result.evalSuites?.skipped && result.evalSuites.skipped.length > 0) {
|
|
3583
|
+
console.log(chalk6.yellow(` Skipped eval suites (agent not found): ${result.evalSuites.skipped.join(", ")}`));
|
|
3584
|
+
}
|
|
3585
|
+
console.log();
|
|
3586
|
+
}
|
|
3486
3587
|
if (jsonMode) {
|
|
3487
3588
|
console.log(JSON.stringify({
|
|
3488
3589
|
success: true,
|
|
@@ -3505,6 +3606,15 @@ var syncCommand = new Command5("sync").description("Sync resources to Convex and
|
|
|
3505
3606
|
}));
|
|
3506
3607
|
}
|
|
3507
3608
|
} catch (error) {
|
|
3609
|
+
if (error instanceof SyncValidationFailureError) {
|
|
3610
|
+
if (jsonMode) {
|
|
3611
|
+
console.log(JSON.stringify({ success: false, validationErrors: error.validationErrors }));
|
|
3612
|
+
} else {
|
|
3613
|
+
output.fail("Sync failed");
|
|
3614
|
+
renderValidationErrors(error.validationErrors);
|
|
3615
|
+
}
|
|
3616
|
+
process.exit(1);
|
|
3617
|
+
}
|
|
3508
3618
|
if (jsonMode) {
|
|
3509
3619
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }));
|
|
3510
3620
|
} else {
|
|
@@ -3635,6 +3745,9 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
3635
3745
|
console.log(chalk7.gray(" 2."), "Or run", chalk7.cyan("struere init"), "to select a different organization");
|
|
3636
3746
|
console.log();
|
|
3637
3747
|
process.exit(1);
|
|
3748
|
+
} else if (error instanceof SyncValidationFailureError) {
|
|
3749
|
+
spinner.fail("Sync failed");
|
|
3750
|
+
renderValidationErrors(error.validationErrors);
|
|
3638
3751
|
} else {
|
|
3639
3752
|
spinner.fail("Sync failed");
|
|
3640
3753
|
console.log(chalk7.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
@@ -3675,8 +3788,13 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
3675
3788
|
await performDevSync(cwd, project.organization.id);
|
|
3676
3789
|
syncSpinner.succeed("Synced");
|
|
3677
3790
|
} catch (error) {
|
|
3678
|
-
|
|
3679
|
-
|
|
3791
|
+
if (error instanceof SyncValidationFailureError) {
|
|
3792
|
+
syncSpinner.fail("Sync failed");
|
|
3793
|
+
renderValidationErrors(error.validationErrors);
|
|
3794
|
+
} else {
|
|
3795
|
+
syncSpinner.fail("Sync failed");
|
|
3796
|
+
console.log(chalk7.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
3797
|
+
}
|
|
3680
3798
|
}
|
|
3681
3799
|
};
|
|
3682
3800
|
const handleFileChange = (path, action) => {
|
|
@@ -3943,6 +4061,8 @@ var deployCommand = new Command7("deploy").description("Deploy all resources to
|
|
|
3943
4061
|
environment: "production"
|
|
3944
4062
|
});
|
|
3945
4063
|
if (!syncResult.success) {
|
|
4064
|
+
if (syncResult.validationErrors)
|
|
4065
|
+
throw new SyncValidationFailureError(syncResult.validationErrors);
|
|
3946
4066
|
throw new Error(syncResult.error || "Deploy failed");
|
|
3947
4067
|
}
|
|
3948
4068
|
const elapsed = Date.now() - startTime;
|
|
@@ -4052,6 +4172,14 @@ var deployCommand = new Command7("deploy").description("Deploy all resources to
|
|
|
4052
4172
|
console.log();
|
|
4053
4173
|
}
|
|
4054
4174
|
process.exit(1);
|
|
4175
|
+
} else if (error instanceof SyncValidationFailureError) {
|
|
4176
|
+
if (jsonMode) {
|
|
4177
|
+
console.log(JSON.stringify({ success: false, validationErrors: error.validationErrors }));
|
|
4178
|
+
} else {
|
|
4179
|
+
spinner.fail("Deployment failed");
|
|
4180
|
+
renderValidationErrors(error.validationErrors);
|
|
4181
|
+
}
|
|
4182
|
+
process.exit(1);
|
|
4055
4183
|
} else {
|
|
4056
4184
|
if (jsonMode) {
|
|
4057
4185
|
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }));
|
|
@@ -5338,17 +5466,17 @@ function flattenEntityForTable(entity) {
|
|
|
5338
5466
|
var entitiesCommand = new Command13("data").description("Manage data records");
|
|
5339
5467
|
entitiesCommand.command("types").description("List available data types").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5340
5468
|
await ensureAuth();
|
|
5341
|
-
const spinner = ora11();
|
|
5469
|
+
const spinner = opts.json ? null : ora11();
|
|
5342
5470
|
const env = opts.env;
|
|
5343
5471
|
const orgId = getOrgId();
|
|
5344
|
-
spinner
|
|
5472
|
+
spinner?.start("Fetching data types");
|
|
5345
5473
|
const { data, error } = await queryEntityTypes(env, orgId);
|
|
5346
5474
|
if (error || !data) {
|
|
5347
|
-
spinner
|
|
5475
|
+
spinner?.fail("Failed to fetch data types");
|
|
5348
5476
|
console.log(chalk15.red("Error:"), error);
|
|
5349
5477
|
process.exit(1);
|
|
5350
5478
|
}
|
|
5351
|
-
spinner
|
|
5479
|
+
spinner?.succeed("Data types loaded");
|
|
5352
5480
|
const types = data;
|
|
5353
5481
|
if (opts.json) {
|
|
5354
5482
|
console.log(JSON.stringify(types, null, 2));
|
|
@@ -5373,10 +5501,10 @@ entitiesCommand.command("types").description("List available data types").option
|
|
|
5373
5501
|
});
|
|
5374
5502
|
entitiesCommand.command("list <type>").description("List records of a type").option("--env <environment>", "Environment (development|production)", "development").option("--status <status>", "Filter by status").option("--limit <n>", "Maximum results", "50").option("--json", "Output raw JSON").action(async (type, opts) => {
|
|
5375
5503
|
await ensureAuth();
|
|
5376
|
-
const spinner = ora11();
|
|
5504
|
+
const spinner = opts.json ? null : ora11();
|
|
5377
5505
|
const env = opts.env;
|
|
5378
5506
|
const orgId = getOrgId();
|
|
5379
|
-
spinner
|
|
5507
|
+
spinner?.start(`Fetching ${type} records`);
|
|
5380
5508
|
const [entitiesResult, typeResult] = await Promise.all([
|
|
5381
5509
|
queryEntities(type, env, {
|
|
5382
5510
|
status: opts.status,
|
|
@@ -5385,12 +5513,12 @@ entitiesCommand.command("list <type>").description("List records of a type").opt
|
|
|
5385
5513
|
queryEntityTypeBySlug(type, env, orgId)
|
|
5386
5514
|
]);
|
|
5387
5515
|
if (entitiesResult.error || !entitiesResult.data) {
|
|
5388
|
-
spinner
|
|
5516
|
+
spinner?.fail(`Failed to fetch ${type} records`);
|
|
5389
5517
|
console.log(chalk15.red("Error:"), entitiesResult.error);
|
|
5390
5518
|
process.exit(1);
|
|
5391
5519
|
}
|
|
5392
5520
|
const entities = entitiesResult.data;
|
|
5393
|
-
spinner
|
|
5521
|
+
spinner?.succeed(`Found ${entities.length} ${type} records`);
|
|
5394
5522
|
if (opts.json) {
|
|
5395
5523
|
console.log(JSON.stringify(entities, null, 2));
|
|
5396
5524
|
return;
|
|
@@ -5405,25 +5533,26 @@ entitiesCommand.command("list <type>").description("List records of a type").opt
|
|
|
5405
5533
|
});
|
|
5406
5534
|
entitiesCommand.command("get <id>").description("Get record details").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
5407
5535
|
await ensureAuth();
|
|
5408
|
-
const spinner = ora11();
|
|
5536
|
+
const spinner = opts.json ? null : ora11();
|
|
5409
5537
|
const env = opts.env;
|
|
5410
5538
|
const orgId = getOrgId();
|
|
5411
|
-
spinner
|
|
5539
|
+
spinner?.start("Resolving record ID");
|
|
5412
5540
|
const resolved = await resolveEntityId(rawId, env, orgId);
|
|
5413
5541
|
if (resolved.error || !resolved.data) {
|
|
5414
|
-
spinner
|
|
5542
|
+
spinner?.fail("Record not found");
|
|
5415
5543
|
console.log(chalk15.red("Error:"), resolved.error || `No record matched "${rawId}"`);
|
|
5416
5544
|
process.exit(1);
|
|
5417
5545
|
}
|
|
5418
5546
|
const id = resolved.data;
|
|
5419
|
-
spinner
|
|
5547
|
+
if (spinner)
|
|
5548
|
+
spinner.text = "Fetching record";
|
|
5420
5549
|
const { data, error } = await queryEntity(id, env, orgId);
|
|
5421
5550
|
if (error || !data) {
|
|
5422
|
-
spinner
|
|
5551
|
+
spinner?.fail("Failed to fetch record");
|
|
5423
5552
|
console.log(chalk15.red("Error:"), error || "Record not found");
|
|
5424
5553
|
process.exit(1);
|
|
5425
5554
|
}
|
|
5426
|
-
spinner
|
|
5555
|
+
spinner?.succeed("Record loaded");
|
|
5427
5556
|
const result = data;
|
|
5428
5557
|
if (opts.json) {
|
|
5429
5558
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -5453,7 +5582,7 @@ entitiesCommand.command("get <id>").description("Get record details").option("--
|
|
|
5453
5582
|
});
|
|
5454
5583
|
entitiesCommand.command("create <type>").description("Create a new record").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Record data as JSON").option("--status <status>", "Initial status").option("--json", "Output raw JSON").action(async (type, opts) => {
|
|
5455
5584
|
await ensureAuth();
|
|
5456
|
-
const spinner = ora11();
|
|
5585
|
+
const spinner = opts.json ? null : ora11();
|
|
5457
5586
|
const env = opts.env;
|
|
5458
5587
|
const orgId = getOrgId();
|
|
5459
5588
|
let data;
|
|
@@ -5468,14 +5597,14 @@ entitiesCommand.command("create <type>").description("Create a new record").opti
|
|
|
5468
5597
|
console.log(chalk15.red("--data <json> is required in non-interactive mode"));
|
|
5469
5598
|
process.exit(1);
|
|
5470
5599
|
} else {
|
|
5471
|
-
spinner
|
|
5600
|
+
spinner?.start(`Fetching ${type} schema`);
|
|
5472
5601
|
const { data: typeData, error: error2 } = await queryEntityTypeBySlug(type, env, orgId);
|
|
5473
5602
|
if (error2 || !typeData) {
|
|
5474
|
-
spinner
|
|
5603
|
+
spinner?.fail(`Data type not found: ${type}`);
|
|
5475
5604
|
console.log(chalk15.red("Error:"), error2 || "Not found");
|
|
5476
5605
|
process.exit(1);
|
|
5477
5606
|
}
|
|
5478
|
-
spinner
|
|
5607
|
+
spinner?.succeed(`Schema loaded for ${type}`);
|
|
5479
5608
|
console.log();
|
|
5480
5609
|
const entityType = typeData;
|
|
5481
5610
|
const schema = entityType.schema;
|
|
@@ -5509,14 +5638,14 @@ entitiesCommand.command("create <type>").description("Create a new record").opti
|
|
|
5509
5638
|
}
|
|
5510
5639
|
console.log();
|
|
5511
5640
|
}
|
|
5512
|
-
spinner
|
|
5641
|
+
spinner?.start(`Creating ${type} record`);
|
|
5513
5642
|
const { data: result, error } = await createEntity(type, data, env, opts.status, orgId);
|
|
5514
5643
|
if (error) {
|
|
5515
|
-
spinner
|
|
5644
|
+
spinner?.fail("Failed to create record");
|
|
5516
5645
|
console.log(chalk15.red("Error:"), error);
|
|
5517
5646
|
process.exit(1);
|
|
5518
5647
|
}
|
|
5519
|
-
spinner
|
|
5648
|
+
spinner?.succeed(`Record created`);
|
|
5520
5649
|
if (opts.json) {
|
|
5521
5650
|
console.log(JSON.stringify({ id: result }, null, 2));
|
|
5522
5651
|
} else {
|
|
@@ -5527,7 +5656,7 @@ entitiesCommand.command("create <type>").description("Create a new record").opti
|
|
|
5527
5656
|
});
|
|
5528
5657
|
entitiesCommand.command("update <id>").description("Update a record").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Update data as JSON").option("--status <status>", "New status").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
5529
5658
|
await ensureAuth();
|
|
5530
|
-
const spinner = ora11();
|
|
5659
|
+
const spinner = opts.json ? null : ora11();
|
|
5531
5660
|
const env = opts.env;
|
|
5532
5661
|
const orgId = getOrgId();
|
|
5533
5662
|
if (!opts.data && !opts.status) {
|
|
@@ -5543,22 +5672,23 @@ entitiesCommand.command("update <id>").description("Update a record").option("--
|
|
|
5543
5672
|
process.exit(1);
|
|
5544
5673
|
}
|
|
5545
5674
|
}
|
|
5546
|
-
spinner
|
|
5675
|
+
spinner?.start("Resolving record ID");
|
|
5547
5676
|
const resolved = await resolveEntityId(rawId, env, orgId);
|
|
5548
5677
|
if (resolved.error || !resolved.data) {
|
|
5549
|
-
spinner
|
|
5678
|
+
spinner?.fail("Record not found");
|
|
5550
5679
|
console.log(chalk15.red("Error:"), resolved.error || `No record matched "${rawId}"`);
|
|
5551
5680
|
process.exit(1);
|
|
5552
5681
|
}
|
|
5553
5682
|
const id = resolved.data;
|
|
5554
|
-
spinner
|
|
5683
|
+
if (spinner)
|
|
5684
|
+
spinner.text = "Updating record";
|
|
5555
5685
|
const { data: result, error } = await updateEntity(id, data, env, opts.status, orgId);
|
|
5556
5686
|
if (error) {
|
|
5557
|
-
spinner
|
|
5687
|
+
spinner?.fail("Failed to update record");
|
|
5558
5688
|
console.log(chalk15.red("Error:"), error);
|
|
5559
5689
|
process.exit(1);
|
|
5560
5690
|
}
|
|
5561
|
-
spinner
|
|
5691
|
+
spinner?.succeed("Record updated");
|
|
5562
5692
|
if (opts.json) {
|
|
5563
5693
|
console.log(JSON.stringify(result, null, 2));
|
|
5564
5694
|
} else {
|
|
@@ -5646,21 +5776,21 @@ entitiesCommand.command("delete <id>").description("Delete a record").option("--
|
|
|
5646
5776
|
});
|
|
5647
5777
|
entitiesCommand.command("search <type> <query>").description("Search records").option("--env <environment>", "Environment (development|production)", "development").option("--limit <n>", "Maximum results", "25").option("--json", "Output raw JSON").action(async (type, query, opts) => {
|
|
5648
5778
|
await ensureAuth();
|
|
5649
|
-
const spinner = ora11();
|
|
5779
|
+
const spinner = opts.json ? null : ora11();
|
|
5650
5780
|
const env = opts.env;
|
|
5651
5781
|
const orgId = getOrgId();
|
|
5652
|
-
spinner
|
|
5782
|
+
spinner?.start(`Searching ${type} for "${query}"`);
|
|
5653
5783
|
const [searchResult, typeResult] = await Promise.all([
|
|
5654
5784
|
searchEntities(type, query, env, parseInt(opts.limit, 10), orgId),
|
|
5655
5785
|
queryEntityTypeBySlug(type, env, orgId)
|
|
5656
5786
|
]);
|
|
5657
5787
|
if (searchResult.error || !searchResult.data) {
|
|
5658
|
-
spinner
|
|
5788
|
+
spinner?.fail("Search failed");
|
|
5659
5789
|
console.log(chalk15.red("Error:"), searchResult.error);
|
|
5660
5790
|
process.exit(1);
|
|
5661
5791
|
}
|
|
5662
5792
|
const entities = searchResult.data;
|
|
5663
|
-
spinner
|
|
5793
|
+
spinner?.succeed(`Found ${entities.length} results`);
|
|
5664
5794
|
if (opts.json) {
|
|
5665
5795
|
console.log(JSON.stringify(entities, null, 2));
|
|
5666
5796
|
return;
|
|
@@ -5839,21 +5969,21 @@ function formatTimestamp(ts) {
|
|
|
5839
5969
|
var logsCommand = new Command14("logs").description("View and debug agent conversations");
|
|
5840
5970
|
logsCommand.command("list", { isDefault: true }).description("List recent conversations").option("--env <environment>", "Environment (development|production|eval)", "development").option("--agent <slug>", "Filter by agent slug").option("--channel <channel>", "Filter by channel (api|whatsapp|widget|dashboard)").option("--phone <number>", "Filter by phone number").option("--limit <n>", "Maximum results", "20").option("--json", "Output raw JSON").action(async (opts) => {
|
|
5841
5971
|
await ensureAuth2();
|
|
5842
|
-
const spinner = ora12();
|
|
5972
|
+
const spinner = opts.json ? null : ora12();
|
|
5843
5973
|
const orgId = getOrgId2();
|
|
5844
5974
|
let agentId;
|
|
5845
5975
|
if (opts.agent) {
|
|
5846
|
-
spinner
|
|
5976
|
+
spinner?.start(`Resolving agent "${opts.agent}"`);
|
|
5847
5977
|
const resolved = await resolveAgentSlug(opts.agent, orgId);
|
|
5848
5978
|
if (resolved.error || !resolved.data) {
|
|
5849
|
-
spinner
|
|
5979
|
+
spinner?.fail("Agent not found");
|
|
5850
5980
|
console.log(chalk16.red("Error:"), resolved.error || `No agent matched "${opts.agent}"`);
|
|
5851
5981
|
process.exit(1);
|
|
5852
5982
|
}
|
|
5853
5983
|
agentId = resolved.data;
|
|
5854
|
-
spinner
|
|
5984
|
+
spinner?.succeed(`Agent resolved: ${opts.agent}`);
|
|
5855
5985
|
}
|
|
5856
|
-
spinner
|
|
5986
|
+
spinner?.start("Fetching conversations");
|
|
5857
5987
|
const { data, error } = await queryThreads({
|
|
5858
5988
|
environment: opts.env,
|
|
5859
5989
|
agentId,
|
|
@@ -5862,17 +5992,16 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5862
5992
|
limit: parseInt(opts.limit, 10)
|
|
5863
5993
|
});
|
|
5864
5994
|
if (error || !data) {
|
|
5865
|
-
spinner
|
|
5995
|
+
spinner?.fail("Failed to fetch conversations");
|
|
5866
5996
|
console.log(chalk16.red("Error:"), error);
|
|
5867
5997
|
process.exit(1);
|
|
5868
5998
|
}
|
|
5869
5999
|
const threads = data;
|
|
5870
6000
|
if (opts.json) {
|
|
5871
|
-
spinner.stop();
|
|
5872
6001
|
console.log(JSON.stringify(threads, null, 2));
|
|
5873
6002
|
return;
|
|
5874
6003
|
}
|
|
5875
|
-
spinner
|
|
6004
|
+
spinner?.succeed(`Found ${threads.length} conversations`);
|
|
5876
6005
|
console.log();
|
|
5877
6006
|
renderTable([
|
|
5878
6007
|
{ key: "id", label: "ID", width: 14 },
|
|
@@ -5896,25 +6025,25 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5896
6025
|
});
|
|
5897
6026
|
logsCommand.command("view <thread-id>").description("View conversation messages").option("--env <environment>", "Environment hint for resolving short IDs").option("--exec", "Include execution details").option("--verbose", "Show full tool call arguments and results").option("--tail", "Show most recent messages (use with --limit)").option("--json", "Output raw JSON").option("--limit <n>", "Message limit", "100").action(async (rawThreadId, opts) => {
|
|
5898
6027
|
await ensureAuth2();
|
|
5899
|
-
const spinner = ora12();
|
|
5900
|
-
spinner
|
|
6028
|
+
const spinner = opts.json ? null : ora12();
|
|
6029
|
+
spinner?.start("Resolving thread");
|
|
5901
6030
|
const resolved = await resolveThreadId(rawThreadId, opts.env);
|
|
5902
6031
|
if (resolved.error || !resolved.data) {
|
|
5903
|
-
spinner
|
|
6032
|
+
spinner?.fail("Thread not found");
|
|
5904
6033
|
console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
|
|
5905
6034
|
process.exit(1);
|
|
5906
6035
|
}
|
|
5907
6036
|
const threadId = resolved.data;
|
|
5908
|
-
spinner
|
|
5909
|
-
spinner
|
|
6037
|
+
spinner?.stop();
|
|
6038
|
+
spinner?.start("Fetching conversation");
|
|
5910
6039
|
const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
|
|
5911
6040
|
const { data, error } = await queryThreadDetail(threadId, fetchLimit);
|
|
5912
6041
|
if (error || !data) {
|
|
5913
|
-
spinner
|
|
6042
|
+
spinner?.fail("Failed to fetch conversation");
|
|
5914
6043
|
console.log(chalk16.red("Error:"), error || "Thread not found");
|
|
5915
6044
|
process.exit(1);
|
|
5916
6045
|
}
|
|
5917
|
-
spinner
|
|
6046
|
+
spinner?.stop();
|
|
5918
6047
|
const result = data;
|
|
5919
6048
|
let executions = [];
|
|
5920
6049
|
if (opts.exec) {
|
|
@@ -6795,7 +6924,7 @@ var templatesCommand = new Command16("templates").description("Manage WhatsApp m
|
|
|
6795
6924
|
templatesCommand.command("list").description("List all message templates").option("--env <environment>", "Environment to find connection (development|production|eval)").option("--json", "Output raw JSON").action(async (opts) => {
|
|
6796
6925
|
await ensureAuth3();
|
|
6797
6926
|
const connectionId = await resolveConnectionId(opts.env ?? "production");
|
|
6798
|
-
const out = createOutput();
|
|
6927
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
6799
6928
|
out.start("Fetching templates");
|
|
6800
6929
|
const { data, error } = await listTemplates(connectionId);
|
|
6801
6930
|
if (error) {
|
|
@@ -6857,7 +6986,7 @@ templatesCommand.command("create <name>").description("Create a new message temp
|
|
|
6857
6986
|
console.log(chalk18.red("Components must be a JSON array"));
|
|
6858
6987
|
process.exit(1);
|
|
6859
6988
|
}
|
|
6860
|
-
const out = createOutput();
|
|
6989
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
6861
6990
|
out.start(`Creating template "${name}"`);
|
|
6862
6991
|
const { data, error } = await createTemplate(connectionId, name, opts.language, opts.category.toUpperCase(), components, opts.allowCategoryChange);
|
|
6863
6992
|
const result = data;
|
|
@@ -6904,7 +7033,7 @@ templatesCommand.command("delete <name>").description("Delete a message template
|
|
|
6904
7033
|
templatesCommand.command("status <name>").description("Check template approval status").option("--env <environment>", "Environment to find connection").option("--connection <id>", "WhatsApp connection ID").option("--json", "Output raw JSON").action(async (name, opts) => {
|
|
6905
7034
|
await ensureAuth3();
|
|
6906
7035
|
const connectionId = await resolveConnectionId(opts.env ?? "production", opts.connection);
|
|
6907
|
-
const out = createOutput();
|
|
7036
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
6908
7037
|
out.start(`Checking status for "${name}"`);
|
|
6909
7038
|
const { data, error } = await getTemplateStatus(connectionId, name);
|
|
6910
7039
|
if (error) {
|
|
@@ -6942,7 +7071,7 @@ templatesCommand.command("status <name>").description("Check template approval s
|
|
|
6942
7071
|
templatesCommand.command("edit <name>").description("Edit a message template").option("--env <environment>", "Environment to find connection").option("--connection <id>", "WhatsApp connection ID").option("--components <json>", "New components as JSON string").option("--file <path>", "Read components from a JSON file").option("--category <cat>", "New category (UTILITY|MARKETING|AUTHENTICATION)").option("--language <code>", "Language code").option("--json", "Output raw JSON").action(async (name, opts) => {
|
|
6943
7072
|
await ensureAuth3();
|
|
6944
7073
|
const connectionId = await resolveConnectionId(opts.env ?? "production", opts.connection);
|
|
6945
|
-
const out = createOutput();
|
|
7074
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
6946
7075
|
out.start(`Fetching template "${name}"`);
|
|
6947
7076
|
const { data: statusData, error: statusError } = await getTemplateStatus(connectionId, name);
|
|
6948
7077
|
if (statusError) {
|
|
@@ -7262,7 +7391,7 @@ function buildConfigFromOpts(provider, opts) {
|
|
|
7262
7391
|
var integrationCommand = new Command17("integration").description("Manage integrations").argument("[provider]", "Integration provider (airtable, resend, flow)").option("--env <environment>", "Environment (development|production)", "development").option("--token <pat>", "Personal access token (airtable)").option("--base-id <id>", "Default base ID (airtable)").option("--from-email <email>", "From email address (resend)").option("--from-name <name>", "From display name (resend)").option("--reply-to <email>", "Reply-to address (resend)").option("--api-url <url>", "API URL (flow)").option("--api-key <key>", "API key (flow)").option("--secret-key <secret>", "Secret key (flow)").option("--return-url <url>", "Return URL after payment (flow)").option("--account-sid <sid>", "Twilio Account SID (twilio)").option("--auth-token <token>", "Twilio Auth Token (twilio)").option("--phone-number <number>", "Twilio phone number in E.164 format (twilio)").option("--router <slug>", "Router slug to assign to phone number (twilio)").option("--agent <slug>", "Agent slug to assign to phone number (twilio)").option("--test", "Test the connection after saving").option("--remove", "Remove integration config").option("--enable", "Enable integration").option("--disable", "Disable integration").option("--status", "Show current config status").option("--yes", "Skip confirmation prompts").option("--json", "Output raw JSON").action(async (provider, opts) => {
|
|
7263
7392
|
await ensureAuth4();
|
|
7264
7393
|
const env = opts.env;
|
|
7265
|
-
const out = createOutput();
|
|
7394
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
7266
7395
|
if (!provider || provider === "list") {
|
|
7267
7396
|
out.start("Fetching integrations");
|
|
7268
7397
|
const { data, error } = await listIntegrationConfigs(env);
|
|
@@ -7778,9 +7907,9 @@ function renderExecutionLog(executionLog, verbose) {
|
|
|
7778
7907
|
var triggersCommand = new Command18("triggers").description("Manage triggers and automation runs");
|
|
7779
7908
|
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) => {
|
|
7780
7909
|
await ensureAuth5();
|
|
7781
|
-
const spinner = ora14();
|
|
7910
|
+
const spinner = opts.json ? null : ora14();
|
|
7782
7911
|
try {
|
|
7783
|
-
spinner
|
|
7912
|
+
spinner?.start("Fetching triggers");
|
|
7784
7913
|
const [triggers, statuses] = await Promise.all([
|
|
7785
7914
|
listTriggers(opts.env),
|
|
7786
7915
|
getLastRunStatuses(opts.env)
|
|
@@ -7789,7 +7918,7 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7789
7918
|
if (opts.failed) {
|
|
7790
7919
|
filtered = triggers.filter((t) => statuses[t.slug]?.status === "failed");
|
|
7791
7920
|
}
|
|
7792
|
-
spinner
|
|
7921
|
+
spinner?.succeed(`Found ${filtered.length} triggers${opts.failed ? " (failed only)" : ""}`);
|
|
7793
7922
|
if (opts.json) {
|
|
7794
7923
|
console.log(JSON.stringify(filtered, null, 2));
|
|
7795
7924
|
return;
|
|
@@ -7815,7 +7944,7 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7815
7944
|
console.log();
|
|
7816
7945
|
} catch (err) {
|
|
7817
7946
|
const message = err instanceof Error ? err.message : String(err);
|
|
7818
|
-
spinner
|
|
7947
|
+
spinner?.fail("Failed to fetch triggers");
|
|
7819
7948
|
if (opts.json) {
|
|
7820
7949
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
7821
7950
|
} else {
|
|
@@ -7826,18 +7955,18 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7826
7955
|
});
|
|
7827
7956
|
triggersCommand.command("get <slug>").description("View trigger details").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (slug, opts) => {
|
|
7828
7957
|
await ensureAuth5();
|
|
7829
|
-
const spinner = ora14();
|
|
7958
|
+
const spinner = opts.json ? null : ora14();
|
|
7830
7959
|
try {
|
|
7831
|
-
spinner
|
|
7960
|
+
spinner?.start("Fetching trigger");
|
|
7832
7961
|
const trigger = await getTrigger(slug, opts.env);
|
|
7833
7962
|
if (!trigger) {
|
|
7834
|
-
spinner
|
|
7963
|
+
spinner?.fail("Trigger not found");
|
|
7835
7964
|
if (opts.json) {
|
|
7836
7965
|
console.log(JSON.stringify({ success: false, error: "Trigger not found" }));
|
|
7837
7966
|
}
|
|
7838
7967
|
process.exit(1);
|
|
7839
7968
|
}
|
|
7840
|
-
spinner
|
|
7969
|
+
spinner?.succeed("Trigger loaded");
|
|
7841
7970
|
if (opts.json) {
|
|
7842
7971
|
console.log(JSON.stringify(trigger, null, 2));
|
|
7843
7972
|
return;
|
|
@@ -7894,7 +8023,7 @@ triggersCommand.command("get <slug>").description("View trigger details").option
|
|
|
7894
8023
|
console.log();
|
|
7895
8024
|
} catch (err) {
|
|
7896
8025
|
const message = err instanceof Error ? err.message : String(err);
|
|
7897
|
-
spinner
|
|
8026
|
+
spinner?.fail("Failed to fetch trigger");
|
|
7898
8027
|
if (opts.json) {
|
|
7899
8028
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
7900
8029
|
} else {
|
|
@@ -7905,16 +8034,16 @@ triggersCommand.command("get <slug>").description("View trigger details").option
|
|
|
7905
8034
|
});
|
|
7906
8035
|
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) => {
|
|
7907
8036
|
await ensureAuth5();
|
|
7908
|
-
const spinner = ora14();
|
|
8037
|
+
const spinner = opts.json ? null : ora14();
|
|
7909
8038
|
try {
|
|
7910
|
-
spinner
|
|
8039
|
+
spinner?.start("Fetching runs");
|
|
7911
8040
|
const runs = await listTriggerRuns({
|
|
7912
8041
|
environment: opts.env,
|
|
7913
8042
|
status: opts.status,
|
|
7914
8043
|
triggerSlug: slug,
|
|
7915
8044
|
limit: parseInt(opts.limit, 10)
|
|
7916
8045
|
});
|
|
7917
|
-
spinner
|
|
8046
|
+
spinner?.succeed(`Found ${runs.length} runs`);
|
|
7918
8047
|
if (opts.json) {
|
|
7919
8048
|
console.log(JSON.stringify(runs, null, 2));
|
|
7920
8049
|
return;
|
|
@@ -7940,7 +8069,7 @@ triggersCommand.command("runs [slug]").description("List trigger runs").option("
|
|
|
7940
8069
|
console.log();
|
|
7941
8070
|
} catch (err) {
|
|
7942
8071
|
const message = err instanceof Error ? err.message : String(err);
|
|
7943
|
-
spinner
|
|
8072
|
+
spinner?.fail("Failed to fetch runs");
|
|
7944
8073
|
if (opts.json) {
|
|
7945
8074
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
7946
8075
|
} else {
|
|
@@ -7951,18 +8080,18 @@ triggersCommand.command("runs [slug]").description("List trigger runs").option("
|
|
|
7951
8080
|
});
|
|
7952
8081
|
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) => {
|
|
7953
8082
|
await ensureAuth5();
|
|
7954
|
-
const spinner = ora14();
|
|
8083
|
+
const spinner = opts.json ? null : ora14();
|
|
7955
8084
|
try {
|
|
7956
|
-
spinner
|
|
8085
|
+
spinner?.start("Fetching run");
|
|
7957
8086
|
const run = await getTriggerRunDetail(runId, opts.env);
|
|
7958
8087
|
if (!run) {
|
|
7959
|
-
spinner
|
|
8088
|
+
spinner?.fail("Run not found");
|
|
7960
8089
|
if (opts.json) {
|
|
7961
8090
|
console.log(JSON.stringify({ success: false, error: "Run not found" }));
|
|
7962
8091
|
}
|
|
7963
8092
|
process.exit(1);
|
|
7964
8093
|
}
|
|
7965
|
-
spinner
|
|
8094
|
+
spinner?.succeed("Run loaded");
|
|
7966
8095
|
if (opts.json) {
|
|
7967
8096
|
console.log(JSON.stringify(run, null, 2));
|
|
7968
8097
|
return;
|
|
@@ -7985,7 +8114,7 @@ triggersCommand.command("run <run-id>").description("View trigger run details").
|
|
|
7985
8114
|
console.log();
|
|
7986
8115
|
} catch (err) {
|
|
7987
8116
|
const message = err instanceof Error ? err.message : String(err);
|
|
7988
|
-
spinner
|
|
8117
|
+
spinner?.fail("Failed to fetch run");
|
|
7989
8118
|
if (opts.json) {
|
|
7990
8119
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
7991
8120
|
} else {
|
|
@@ -7996,11 +8125,11 @@ triggersCommand.command("run <run-id>").description("View trigger run details").
|
|
|
7996
8125
|
});
|
|
7997
8126
|
triggersCommand.command("stats").description("Show trigger run statistics").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (opts) => {
|
|
7998
8127
|
await ensureAuth5();
|
|
7999
|
-
const spinner = ora14();
|
|
8128
|
+
const spinner = opts.json ? null : ora14();
|
|
8000
8129
|
try {
|
|
8001
|
-
spinner
|
|
8130
|
+
spinner?.start("Fetching statistics");
|
|
8002
8131
|
const stats = await getTriggerRunStats(opts.env);
|
|
8003
|
-
spinner
|
|
8132
|
+
spinner?.succeed("Run statistics");
|
|
8004
8133
|
if (opts.json) {
|
|
8005
8134
|
console.log(JSON.stringify(stats, null, 2));
|
|
8006
8135
|
return;
|
|
@@ -8039,7 +8168,7 @@ triggersCommand.command("stats").description("Show trigger run statistics").opti
|
|
|
8039
8168
|
console.log();
|
|
8040
8169
|
} catch (err) {
|
|
8041
8170
|
const message = err instanceof Error ? err.message : String(err);
|
|
8042
|
-
spinner
|
|
8171
|
+
spinner?.fail("Failed to fetch statistics");
|
|
8043
8172
|
if (opts.json) {
|
|
8044
8173
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8045
8174
|
} else {
|
|
@@ -8050,15 +8179,15 @@ triggersCommand.command("stats").description("Show trigger run statistics").opti
|
|
|
8050
8179
|
});
|
|
8051
8180
|
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").option("-v, --verbose", "Show full error messages").action(async (slug, opts) => {
|
|
8052
8181
|
await ensureAuth5();
|
|
8053
|
-
const spinner = ora14();
|
|
8182
|
+
const spinner = opts.json ? null : ora14();
|
|
8054
8183
|
try {
|
|
8055
|
-
spinner
|
|
8184
|
+
spinner?.start("Fetching execution logs");
|
|
8056
8185
|
const executions = await withTriggerAuthRetry(() => listTriggerExecutions({
|
|
8057
8186
|
environment: opts.env,
|
|
8058
8187
|
triggerSlug: slug,
|
|
8059
8188
|
limit: parseInt(opts.limit, 10)
|
|
8060
8189
|
}));
|
|
8061
|
-
spinner
|
|
8190
|
+
spinner?.succeed(`Found ${executions.length} executions`);
|
|
8062
8191
|
if (opts.json) {
|
|
8063
8192
|
console.log(JSON.stringify(executions, null, 2));
|
|
8064
8193
|
return;
|
|
@@ -8103,7 +8232,7 @@ triggersCommand.command("logs [slug]").description("View trigger execution histo
|
|
|
8103
8232
|
console.log();
|
|
8104
8233
|
} catch (err) {
|
|
8105
8234
|
const message = err instanceof Error ? err.message : String(err);
|
|
8106
|
-
spinner
|
|
8235
|
+
spinner?.fail("Failed to fetch execution logs");
|
|
8107
8236
|
if (opts.json) {
|
|
8108
8237
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8109
8238
|
} else {
|
|
@@ -8114,7 +8243,7 @@ triggersCommand.command("logs [slug]").description("View trigger execution histo
|
|
|
8114
8243
|
});
|
|
8115
8244
|
triggersCommand.command("log <identifier>").description("View detailed trigger execution log (by event ID or trigger slug)").option("--env <environment>", "Environment", "development").option("--nth <n>", "Show nth most recent execution (when using slug)", "1").option("--json", "Output raw JSON").option("-v, --verbose", "Show detailed agent tool calls").action(async (identifier, opts) => {
|
|
8116
8245
|
await ensureAuth5();
|
|
8117
|
-
const spinner = ora14();
|
|
8246
|
+
const spinner = opts.json ? null : ora14();
|
|
8118
8247
|
try {
|
|
8119
8248
|
const nth = parseInt(opts.nth, 10);
|
|
8120
8249
|
if (isNaN(nth) || nth < 1) {
|
|
@@ -8124,14 +8253,14 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8124
8253
|
let eventId = identifier;
|
|
8125
8254
|
const isConvexId = /^[0-9a-zA-Z]{20,}$/.test(identifier);
|
|
8126
8255
|
if (!isConvexId) {
|
|
8127
|
-
spinner
|
|
8256
|
+
spinner?.start("Resolving trigger slug to latest execution");
|
|
8128
8257
|
const executions = await withTriggerAuthRetry(() => listTriggerExecutions({
|
|
8129
8258
|
environment: opts.env,
|
|
8130
8259
|
triggerSlug: identifier,
|
|
8131
8260
|
limit: nth
|
|
8132
8261
|
}));
|
|
8133
8262
|
if (!executions.length) {
|
|
8134
|
-
spinner
|
|
8263
|
+
spinner?.fail(`No executions found for trigger "${identifier}" in ${opts.env}`);
|
|
8135
8264
|
if (opts.json) {
|
|
8136
8265
|
console.log(JSON.stringify({ success: false, error: `No executions found for trigger "${identifier}"` }));
|
|
8137
8266
|
}
|
|
@@ -8139,22 +8268,22 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8139
8268
|
}
|
|
8140
8269
|
const idx = nth - 1;
|
|
8141
8270
|
if (idx >= executions.length) {
|
|
8142
|
-
spinner
|
|
8271
|
+
spinner?.fail(`Only ${executions.length} executions found, cannot get #${nth}`);
|
|
8143
8272
|
process.exit(1);
|
|
8144
8273
|
}
|
|
8145
8274
|
eventId = executions[idx]._id;
|
|
8146
|
-
spinner
|
|
8275
|
+
spinner?.succeed(`Found execution for "${identifier}"`);
|
|
8147
8276
|
}
|
|
8148
|
-
spinner
|
|
8277
|
+
spinner?.start("Fetching execution detail");
|
|
8149
8278
|
const event = await withTriggerAuthRetry(() => getTriggerExecutionDetail(eventId, opts.env));
|
|
8150
8279
|
if (!event) {
|
|
8151
|
-
spinner
|
|
8280
|
+
spinner?.fail("Execution not found");
|
|
8152
8281
|
if (opts.json) {
|
|
8153
8282
|
console.log(JSON.stringify({ success: false, error: "Execution not found" }));
|
|
8154
8283
|
}
|
|
8155
8284
|
process.exit(1);
|
|
8156
8285
|
}
|
|
8157
|
-
spinner
|
|
8286
|
+
spinner?.succeed("Execution loaded");
|
|
8158
8287
|
if (opts.json) {
|
|
8159
8288
|
console.log(JSON.stringify(event, null, 2));
|
|
8160
8289
|
return;
|
|
@@ -8184,7 +8313,7 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8184
8313
|
}
|
|
8185
8314
|
} catch (err) {
|
|
8186
8315
|
const message = err instanceof Error ? err.message : String(err);
|
|
8187
|
-
spinner
|
|
8316
|
+
spinner?.fail("Failed to fetch execution detail");
|
|
8188
8317
|
if (opts.json) {
|
|
8189
8318
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8190
8319
|
} else {
|
|
@@ -8195,7 +8324,7 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8195
8324
|
});
|
|
8196
8325
|
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) => {
|
|
8197
8326
|
await ensureAuth5();
|
|
8198
|
-
const spinner = ora14();
|
|
8327
|
+
const spinner = opts.json ? null : ora14();
|
|
8199
8328
|
const environment = opts.env;
|
|
8200
8329
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8201
8330
|
const readline = await import("readline");
|
|
@@ -8207,15 +8336,15 @@ triggersCommand.command("retry <run-id>").description("Retry a failed or dead ru
|
|
|
8207
8336
|
rl.close();
|
|
8208
8337
|
}
|
|
8209
8338
|
try {
|
|
8210
|
-
spinner
|
|
8339
|
+
spinner?.start("Retrying run...");
|
|
8211
8340
|
await retryTriggerRun(runId, environment);
|
|
8212
|
-
spinner
|
|
8341
|
+
spinner?.succeed(chalk20.green(`Run ${runId} queued for retry`));
|
|
8213
8342
|
if (opts.json) {
|
|
8214
8343
|
console.log(JSON.stringify({ success: true, runId }));
|
|
8215
8344
|
}
|
|
8216
8345
|
} catch (err) {
|
|
8217
8346
|
const message = err instanceof Error ? err.message : String(err);
|
|
8218
|
-
spinner
|
|
8347
|
+
spinner?.fail("Failed to retry run");
|
|
8219
8348
|
if (opts.json) {
|
|
8220
8349
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8221
8350
|
} else {
|
|
@@ -8226,7 +8355,7 @@ triggersCommand.command("retry <run-id>").description("Retry a failed or dead ru
|
|
|
8226
8355
|
});
|
|
8227
8356
|
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) => {
|
|
8228
8357
|
await ensureAuth5();
|
|
8229
|
-
const spinner = ora14();
|
|
8358
|
+
const spinner = opts.json ? null : ora14();
|
|
8230
8359
|
const environment = opts.env;
|
|
8231
8360
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8232
8361
|
const readline = await import("readline");
|
|
@@ -8238,15 +8367,15 @@ triggersCommand.command("cancel <run-id>").description("Cancel a pending run").o
|
|
|
8238
8367
|
rl.close();
|
|
8239
8368
|
}
|
|
8240
8369
|
try {
|
|
8241
|
-
spinner
|
|
8370
|
+
spinner?.start("Cancelling run...");
|
|
8242
8371
|
await cancelTriggerRun(runId, environment);
|
|
8243
|
-
spinner
|
|
8372
|
+
spinner?.succeed(chalk20.green(`Run ${runId} cancelled`));
|
|
8244
8373
|
if (opts.json) {
|
|
8245
8374
|
console.log(JSON.stringify({ success: true, runId }));
|
|
8246
8375
|
}
|
|
8247
8376
|
} catch (err) {
|
|
8248
8377
|
const message = err instanceof Error ? err.message : String(err);
|
|
8249
|
-
spinner
|
|
8378
|
+
spinner?.fail("Failed to cancel run");
|
|
8250
8379
|
if (opts.json) {
|
|
8251
8380
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8252
8381
|
} else {
|
|
@@ -8257,7 +8386,7 @@ triggersCommand.command("cancel <run-id>").description("Cancel a pending run").o
|
|
|
8257
8386
|
});
|
|
8258
8387
|
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) => {
|
|
8259
8388
|
await ensureAuth5();
|
|
8260
|
-
const spinner = ora14();
|
|
8389
|
+
const spinner = opts.json ? null : ora14();
|
|
8261
8390
|
const environment = opts.env;
|
|
8262
8391
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8263
8392
|
const readline = await import("readline");
|
|
@@ -8269,15 +8398,15 @@ triggersCommand.command("enable <slug>").description("Enable a trigger").option(
|
|
|
8269
8398
|
rl.close();
|
|
8270
8399
|
}
|
|
8271
8400
|
try {
|
|
8272
|
-
spinner
|
|
8401
|
+
spinner?.start("Enabling trigger...");
|
|
8273
8402
|
await toggleTrigger(slug, true, environment);
|
|
8274
|
-
spinner
|
|
8403
|
+
spinner?.succeed(chalk20.green(`Trigger ${slug} enabled`));
|
|
8275
8404
|
if (opts.json) {
|
|
8276
8405
|
console.log(JSON.stringify({ success: true, slug }));
|
|
8277
8406
|
}
|
|
8278
8407
|
} catch (err) {
|
|
8279
8408
|
const message = err instanceof Error ? err.message : String(err);
|
|
8280
|
-
spinner
|
|
8409
|
+
spinner?.fail("Failed to enable trigger");
|
|
8281
8410
|
if (opts.json) {
|
|
8282
8411
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8283
8412
|
} else {
|
|
@@ -8288,7 +8417,7 @@ triggersCommand.command("enable <slug>").description("Enable a trigger").option(
|
|
|
8288
8417
|
});
|
|
8289
8418
|
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) => {
|
|
8290
8419
|
await ensureAuth5();
|
|
8291
|
-
const spinner = ora14();
|
|
8420
|
+
const spinner = opts.json ? null : ora14();
|
|
8292
8421
|
const environment = opts.env;
|
|
8293
8422
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8294
8423
|
const readline = await import("readline");
|
|
@@ -8300,15 +8429,15 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
|
|
|
8300
8429
|
rl.close();
|
|
8301
8430
|
}
|
|
8302
8431
|
try {
|
|
8303
|
-
spinner
|
|
8432
|
+
spinner?.start("Disabling trigger...");
|
|
8304
8433
|
await toggleTrigger(slug, false, environment);
|
|
8305
|
-
spinner
|
|
8434
|
+
spinner?.succeed(chalk20.green(`Trigger ${slug} disabled`));
|
|
8306
8435
|
if (opts.json) {
|
|
8307
8436
|
console.log(JSON.stringify({ success: true, slug }));
|
|
8308
8437
|
}
|
|
8309
8438
|
} catch (err) {
|
|
8310
8439
|
const message = err instanceof Error ? err.message : String(err);
|
|
8311
|
-
spinner
|
|
8440
|
+
spinner?.fail("Failed to disable trigger");
|
|
8312
8441
|
if (opts.json) {
|
|
8313
8442
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8314
8443
|
} else {
|
|
@@ -8319,7 +8448,7 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
|
|
|
8319
8448
|
});
|
|
8320
8449
|
triggersCommand.command("retry-event <event-id>").description("Retry a failed immediate trigger execution").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (eventId, opts) => {
|
|
8321
8450
|
await ensureAuth5();
|
|
8322
|
-
const spinner = ora14();
|
|
8451
|
+
const spinner = opts.json ? null : ora14();
|
|
8323
8452
|
const environment = opts.env;
|
|
8324
8453
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8325
8454
|
const readline = await import("readline");
|
|
@@ -8331,19 +8460,19 @@ triggersCommand.command("retry-event <event-id>").description("Retry a failed im
|
|
|
8331
8460
|
rl.close();
|
|
8332
8461
|
}
|
|
8333
8462
|
try {
|
|
8334
|
-
spinner
|
|
8463
|
+
spinner?.start("Retrying failed execution...");
|
|
8335
8464
|
const result = await retryImmediateExecution(eventId, environment);
|
|
8336
8465
|
if (result.success) {
|
|
8337
|
-
spinner
|
|
8466
|
+
spinner?.succeed(chalk20.green(`Execution retried successfully`));
|
|
8338
8467
|
} else {
|
|
8339
|
-
spinner
|
|
8468
|
+
spinner?.fail(chalk20.red(`Execution retry failed again`));
|
|
8340
8469
|
}
|
|
8341
8470
|
if (opts.json) {
|
|
8342
8471
|
console.log(JSON.stringify(result));
|
|
8343
8472
|
}
|
|
8344
8473
|
} catch (err) {
|
|
8345
8474
|
const message = err instanceof Error ? err.message : String(err);
|
|
8346
|
-
spinner
|
|
8475
|
+
spinner?.fail("Failed to retry execution");
|
|
8347
8476
|
if (opts.json) {
|
|
8348
8477
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8349
8478
|
} else {
|
|
@@ -8354,7 +8483,7 @@ triggersCommand.command("retry-event <event-id>").description("Retry a failed im
|
|
|
8354
8483
|
});
|
|
8355
8484
|
triggersCommand.command("fire <slug>").description("Manually fire a trigger").option("--env <environment>", "Environment (development|production|eval)", "development").option("--entity <entityId>", "Entity ID to provide as context").option("--data <json>", "JSON data for template context").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").option("-v, --verbose", "Show detailed agent tool calls").action(async (slug, opts) => {
|
|
8356
8485
|
await ensureAuth5();
|
|
8357
|
-
const spinner = ora14();
|
|
8486
|
+
const spinner = opts.json ? null : ora14();
|
|
8358
8487
|
const environment = opts.env;
|
|
8359
8488
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8360
8489
|
const readline = await import("readline");
|
|
@@ -8375,7 +8504,7 @@ triggersCommand.command("fire <slug>").description("Manually fire a trigger").op
|
|
|
8375
8504
|
}
|
|
8376
8505
|
}
|
|
8377
8506
|
try {
|
|
8378
|
-
spinner
|
|
8507
|
+
spinner?.start(`Firing trigger ${chalk20.cyan(slug)}...`);
|
|
8379
8508
|
const { result, error } = await fireTrigger({
|
|
8380
8509
|
slug,
|
|
8381
8510
|
environment,
|
|
@@ -8383,7 +8512,7 @@ triggersCommand.command("fire <slug>").description("Manually fire a trigger").op
|
|
|
8383
8512
|
data
|
|
8384
8513
|
});
|
|
8385
8514
|
if (error) {
|
|
8386
|
-
spinner
|
|
8515
|
+
spinner?.fail("Trigger execution failed");
|
|
8387
8516
|
if (opts.json) {
|
|
8388
8517
|
console.log(JSON.stringify({ success: false, error }));
|
|
8389
8518
|
} else {
|
|
@@ -8392,13 +8521,13 @@ triggersCommand.command("fire <slug>").description("Manually fire a trigger").op
|
|
|
8392
8521
|
process.exit(1);
|
|
8393
8522
|
}
|
|
8394
8523
|
if (!result) {
|
|
8395
|
-
spinner
|
|
8524
|
+
spinner?.fail("No result returned");
|
|
8396
8525
|
process.exit(1);
|
|
8397
8526
|
}
|
|
8398
8527
|
if (result.success) {
|
|
8399
|
-
spinner
|
|
8528
|
+
spinner?.succeed(chalk20.green(`Trigger ${chalk20.cyan(slug)} fired successfully`));
|
|
8400
8529
|
} else {
|
|
8401
|
-
spinner
|
|
8530
|
+
spinner?.fail(chalk20.red(`Trigger ${chalk20.cyan(slug)} execution failed`));
|
|
8402
8531
|
}
|
|
8403
8532
|
if (opts.json) {
|
|
8404
8533
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -8416,7 +8545,7 @@ triggersCommand.command("fire <slug>").description("Manually fire a trigger").op
|
|
|
8416
8545
|
}
|
|
8417
8546
|
} catch (err) {
|
|
8418
8547
|
const message = err instanceof Error ? err.message : String(err);
|
|
8419
|
-
spinner
|
|
8548
|
+
spinner?.fail("Failed to fire trigger");
|
|
8420
8549
|
if (opts.json) {
|
|
8421
8550
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8422
8551
|
} else {
|
|
@@ -8654,6 +8783,8 @@ function channelColor(channel) {
|
|
|
8654
8783
|
return chalk21.magenta(channel);
|
|
8655
8784
|
case "dashboard":
|
|
8656
8785
|
return chalk21.cyan(channel);
|
|
8786
|
+
case "voice":
|
|
8787
|
+
return chalk21.yellow(channel);
|
|
8657
8788
|
default:
|
|
8658
8789
|
return chalk21.gray(channel ?? "-");
|
|
8659
8790
|
}
|
|
@@ -8673,17 +8804,17 @@ function roleColor(role) {
|
|
|
8673
8804
|
}
|
|
8674
8805
|
}
|
|
8675
8806
|
var threadsCommand = new Command19("threads").description("Manage conversation threads");
|
|
8676
|
-
threadsCommand.command("list", { isDefault: true }).description("List conversation threads").option("--env <environment>", "Environment (development|production|eval)", "development").option("--channel <channel>", "Filter by channel (whatsapp|api|widget|dashboard)").option("--limit <n>", "Maximum results", "25").option("--json", "Output raw JSON").action(async (opts) => {
|
|
8807
|
+
threadsCommand.command("list", { isDefault: true }).description("List conversation threads").option("--env <environment>", "Environment (development|production|eval)", "development").option("--channel <channel>", "Filter by channel (whatsapp|api|widget|dashboard|voice)").option("--limit <n>", "Maximum results", "25").option("--json", "Output raw JSON").action(async (opts) => {
|
|
8677
8808
|
await ensureAuth6();
|
|
8678
|
-
const spinner = ora15();
|
|
8809
|
+
const spinner = opts.json ? null : ora15();
|
|
8679
8810
|
try {
|
|
8680
|
-
spinner
|
|
8811
|
+
spinner?.start("Fetching threads");
|
|
8681
8812
|
const threads = await listThreads({
|
|
8682
8813
|
environment: opts.env,
|
|
8683
8814
|
channel: opts.channel,
|
|
8684
8815
|
limit: parseInt(opts.limit, 10)
|
|
8685
8816
|
});
|
|
8686
|
-
spinner
|
|
8817
|
+
spinner?.succeed(`Found ${threads.length} threads`);
|
|
8687
8818
|
if (opts.json) {
|
|
8688
8819
|
console.log(JSON.stringify(threads, null, 2));
|
|
8689
8820
|
return;
|
|
@@ -8707,7 +8838,7 @@ threadsCommand.command("list", { isDefault: true }).description("List conversati
|
|
|
8707
8838
|
console.log();
|
|
8708
8839
|
} catch (err) {
|
|
8709
8840
|
const message = err instanceof Error ? err.message : String(err);
|
|
8710
|
-
spinner
|
|
8841
|
+
spinner?.fail("Failed to fetch threads");
|
|
8711
8842
|
if (opts.json) {
|
|
8712
8843
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8713
8844
|
} else {
|
|
@@ -8718,21 +8849,21 @@ threadsCommand.command("list", { isDefault: true }).description("List conversati
|
|
|
8718
8849
|
});
|
|
8719
8850
|
threadsCommand.command("view <id>").description("View thread details and messages").option("--env <environment>", "Environment", "development").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
8720
8851
|
await ensureAuth6();
|
|
8721
|
-
const spinner = ora15();
|
|
8852
|
+
const spinner = opts.json ? null : ora15();
|
|
8722
8853
|
try {
|
|
8723
|
-
spinner
|
|
8854
|
+
spinner?.start("Fetching thread");
|
|
8724
8855
|
const thread = await getThreadWithMessages({
|
|
8725
8856
|
threadId: id,
|
|
8726
8857
|
environment: opts.env
|
|
8727
8858
|
});
|
|
8728
8859
|
if (!thread) {
|
|
8729
|
-
spinner
|
|
8860
|
+
spinner?.fail("Thread not found");
|
|
8730
8861
|
if (opts.json) {
|
|
8731
8862
|
console.log(JSON.stringify({ success: false, error: "Thread not found" }));
|
|
8732
8863
|
}
|
|
8733
8864
|
process.exit(1);
|
|
8734
8865
|
}
|
|
8735
|
-
spinner
|
|
8866
|
+
spinner?.succeed("Thread loaded");
|
|
8736
8867
|
if (opts.json) {
|
|
8737
8868
|
console.log(JSON.stringify(thread, null, 2));
|
|
8738
8869
|
return;
|
|
@@ -8765,7 +8896,7 @@ threadsCommand.command("view <id>").description("View thread details and message
|
|
|
8765
8896
|
console.log();
|
|
8766
8897
|
} catch (err) {
|
|
8767
8898
|
const message = err instanceof Error ? err.message : String(err);
|
|
8768
|
-
spinner
|
|
8899
|
+
spinner?.fail("Failed to fetch thread");
|
|
8769
8900
|
if (opts.json) {
|
|
8770
8901
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8771
8902
|
} else {
|
|
@@ -8776,7 +8907,7 @@ threadsCommand.command("view <id>").description("View thread details and message
|
|
|
8776
8907
|
});
|
|
8777
8908
|
threadsCommand.command("archive <id>").description("Archive a thread (frees its externalId)").option("--env <environment>", "Environment", "development").option("--confirm", "Skip production confirmation").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
8778
8909
|
await ensureAuth6();
|
|
8779
|
-
const spinner = ora15();
|
|
8910
|
+
const spinner = opts.json ? null : ora15();
|
|
8780
8911
|
const environment = opts.env;
|
|
8781
8912
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8782
8913
|
const readline = await import("readline");
|
|
@@ -8788,18 +8919,18 @@ threadsCommand.command("archive <id>").description("Archive a thread (frees its
|
|
|
8788
8919
|
rl.close();
|
|
8789
8920
|
}
|
|
8790
8921
|
try {
|
|
8791
|
-
spinner
|
|
8922
|
+
spinner?.start("Archiving thread...");
|
|
8792
8923
|
const result = await archiveThread({
|
|
8793
8924
|
threadId: id,
|
|
8794
8925
|
environment
|
|
8795
8926
|
});
|
|
8796
|
-
spinner
|
|
8927
|
+
spinner?.succeed(chalk21.green(`Thread ${id} archived`));
|
|
8797
8928
|
if (opts.json) {
|
|
8798
8929
|
console.log(JSON.stringify({ success: true, threadId: id }));
|
|
8799
8930
|
}
|
|
8800
8931
|
} catch (err) {
|
|
8801
8932
|
const message = err instanceof Error ? err.message : String(err);
|
|
8802
|
-
spinner
|
|
8933
|
+
spinner?.fail("Failed to archive thread");
|
|
8803
8934
|
if (opts.json) {
|
|
8804
8935
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8805
8936
|
} else {
|
|
@@ -8810,7 +8941,7 @@ threadsCommand.command("archive <id>").description("Archive a thread (frees its
|
|
|
8810
8941
|
});
|
|
8811
8942
|
threadsCommand.command("reset").description("Archive a thread by phone number").requiredOption("--phone <number>", "Phone number to find and archive").option("--env <environment>", "Environment", "production").option("--confirm", "Skip production confirmation").option("--json", "Output raw JSON").action(async (opts) => {
|
|
8812
8943
|
await ensureAuth6();
|
|
8813
|
-
const spinner = ora15();
|
|
8944
|
+
const spinner = opts.json ? null : ora15();
|
|
8814
8945
|
const environment = opts.env;
|
|
8815
8946
|
if (environment === "production" && !opts.confirm && isInteractive()) {
|
|
8816
8947
|
const readline = await import("readline");
|
|
@@ -8822,30 +8953,31 @@ threadsCommand.command("reset").description("Archive a thread by phone number").
|
|
|
8822
8953
|
rl.close();
|
|
8823
8954
|
}
|
|
8824
8955
|
try {
|
|
8825
|
-
spinner
|
|
8956
|
+
spinner?.start(`Finding thread for phone ${opts.phone}...`);
|
|
8826
8957
|
const thread = await findThreadByPhone({
|
|
8827
8958
|
phone: opts.phone,
|
|
8828
8959
|
environment
|
|
8829
8960
|
});
|
|
8830
8961
|
if (!thread) {
|
|
8831
|
-
spinner
|
|
8962
|
+
spinner?.fail(`No thread found for phone number ${opts.phone}`);
|
|
8832
8963
|
if (opts.json) {
|
|
8833
8964
|
console.log(JSON.stringify({ success: false, error: "Thread not found for phone number" }));
|
|
8834
8965
|
}
|
|
8835
8966
|
process.exit(1);
|
|
8836
8967
|
}
|
|
8837
|
-
spinner
|
|
8968
|
+
if (spinner)
|
|
8969
|
+
spinner.text = `Archiving thread ${thread._id}...`;
|
|
8838
8970
|
await archiveThread({
|
|
8839
8971
|
threadId: thread._id,
|
|
8840
8972
|
environment
|
|
8841
8973
|
});
|
|
8842
|
-
spinner
|
|
8974
|
+
spinner?.succeed(chalk21.green(`Thread ${thread._id} archived (phone: ${opts.phone})`));
|
|
8843
8975
|
if (opts.json) {
|
|
8844
8976
|
console.log(JSON.stringify({ success: true, threadId: thread._id, phone: opts.phone }));
|
|
8845
8977
|
}
|
|
8846
8978
|
} catch (err) {
|
|
8847
8979
|
const message = err instanceof Error ? err.message : String(err);
|
|
8848
|
-
spinner
|
|
8980
|
+
spinner?.fail("Failed to reset thread");
|
|
8849
8981
|
if (opts.json) {
|
|
8850
8982
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
8851
8983
|
} else {
|
|
@@ -9557,7 +9689,7 @@ var whatsappCommand = new Command23("whatsapp").description("Manage WhatsApp con
|
|
|
9557
9689
|
whatsappCommand.command("list").description("List WhatsApp connections with routing assignments").option("--env <environment>", "Environment (development|production)", "production").option("--json", "Output raw JSON").action(async (opts) => {
|
|
9558
9690
|
await ensureAuth7();
|
|
9559
9691
|
const env = opts.env;
|
|
9560
|
-
const out = createOutput();
|
|
9692
|
+
const out = opts.json ? createSilentOutput() : createOutput();
|
|
9561
9693
|
out.start("Fetching WhatsApp connections");
|
|
9562
9694
|
const { data, error } = await listWhatsAppConnections(env);
|
|
9563
9695
|
if (error || !data) {
|
|
@@ -10503,14 +10635,14 @@ async function runCheck(fn) {
|
|
|
10503
10635
|
}
|
|
10504
10636
|
var doctorCommand = new Command25("doctor").description("Run diagnostic checks on your Struere project").option("--env <environment>", "Environment to check", "development").option("--json", "Output raw JSON").action(async (opts) => {
|
|
10505
10637
|
await ensureAuth8();
|
|
10506
|
-
const spinner = ora20();
|
|
10638
|
+
const spinner = opts.json ? null : ora20();
|
|
10507
10639
|
const cwd = process.cwd();
|
|
10508
10640
|
const environment = opts.env;
|
|
10509
10641
|
try {
|
|
10510
|
-
spinner
|
|
10642
|
+
spinner?.start("Loading resources...");
|
|
10511
10643
|
const resources = await loadAllResources(cwd);
|
|
10512
|
-
spinner
|
|
10513
|
-
spinner
|
|
10644
|
+
spinner?.succeed("Resources loaded");
|
|
10645
|
+
spinner?.start("Running diagnostics...");
|
|
10514
10646
|
const results = await Promise.allSettled([
|
|
10515
10647
|
runCheck(() => checkWhatsAppConnection(resources)),
|
|
10516
10648
|
runCheck(() => checkTemplateApprovals(resources)),
|
|
@@ -10520,7 +10652,7 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10520
10652
|
runCheck(() => checkTriggerHealth(environment)),
|
|
10521
10653
|
runCheck(() => checkSyncDrift(resources, environment))
|
|
10522
10654
|
]);
|
|
10523
|
-
spinner
|
|
10655
|
+
spinner?.stop();
|
|
10524
10656
|
const checks = results.map((r) => r.status === "fulfilled" ? r.value : { id: "unknown", label: "Unknown", status: "warn", message: `Check failed: ${r.reason}` });
|
|
10525
10657
|
const summary = {
|
|
10526
10658
|
ok: checks.filter((c) => c.status === "ok").length,
|
|
@@ -10563,7 +10695,7 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10563
10695
|
}
|
|
10564
10696
|
} catch (err) {
|
|
10565
10697
|
const message = err instanceof Error ? err.message : String(err);
|
|
10566
|
-
spinner
|
|
10698
|
+
spinner?.fail("Diagnostics failed");
|
|
10567
10699
|
if (opts.json) {
|
|
10568
10700
|
console.log(JSON.stringify({ success: false, error: message }));
|
|
10569
10701
|
} else {
|
|
@@ -10575,7 +10707,7 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10575
10707
|
// package.json
|
|
10576
10708
|
var package_default = {
|
|
10577
10709
|
name: "struere",
|
|
10578
|
-
version: "0.14.
|
|
10710
|
+
version: "0.14.2",
|
|
10579
10711
|
description: "Build, test, and deploy AI agents",
|
|
10580
10712
|
keywords: [
|
|
10581
10713
|
"ai",
|