struere 0.14.2 → 0.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/struere.js +418 -65
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/keys.d.ts +3 -0
- package/dist/cli/commands/keys.d.ts.map +1 -0
- package/dist/cli/commands/triggers.d.ts.map +1 -1
- package/dist/cli/index.js +418 -65
- package/dist/cli/utils/apiKeys.d.ts +31 -0
- package/dist/cli/utils/apiKeys.d.ts.map +1 -0
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/logs.d.ts +4 -3
- package/dist/cli/utils/logs.d.ts.map +1 -1
- package/dist/cli/utils/threads.d.ts +1 -0
- package/dist/cli/utils/threads.d.ts.map +1 -1
- package/dist/cli/utils/triggers.d.ts +12 -10
- package/dist/cli/utils/triggers.d.ts.map +1 -1
- package/dist/client/chatClient.d.ts +8 -0
- package/dist/client/chatClient.d.ts.map +1 -0
- package/dist/client/dataClient.d.ts +21 -0
- package/dist/client/dataClient.d.ts.map +1 -0
- package/dist/client/index.d.ts +13 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +245 -0
- package/dist/client/transport.d.ts +35 -0
- package/dist/client/transport.d.ts.map +1 -0
- package/dist/client/types.d.ts +130 -0
- package/dist/client/types.d.ts.map +1 -0
- package/package.json +6 -2
package/dist/bin/struere.js
CHANGED
|
@@ -680,7 +680,8 @@ async function _fireTrigger(options) {
|
|
|
680
680
|
slug: options.slug,
|
|
681
681
|
environment: options.environment,
|
|
682
682
|
entityId: options.entityId,
|
|
683
|
-
data: options.data
|
|
683
|
+
data: options.data,
|
|
684
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
684
685
|
}
|
|
685
686
|
}),
|
|
686
687
|
signal: AbortSignal.timeout(60000)
|
|
@@ -3633,7 +3634,10 @@ var devCommand = new Command6("dev").description("Watch files and sync to develo
|
|
|
3633
3634
|
const apiKey = getApiKey();
|
|
3634
3635
|
const nonInteractive = !isInteractive();
|
|
3635
3636
|
if (nonInteractive) {
|
|
3636
|
-
console.error("Error: struere dev
|
|
3637
|
+
console.error(chalk7.red("Error:"), "`struere dev` requires an interactive terminal (TTY) to render its watch UI.");
|
|
3638
|
+
console.error(chalk7.gray(" - For a one-shot sync, use:"), chalk7.cyan("struere sync [--env development]"));
|
|
3639
|
+
console.error(chalk7.gray(" - For continuous deployment in CI/CD, use:"), chalk7.cyan("struere deploy"));
|
|
3640
|
+
console.error(chalk7.gray(" - To run dev in the foreground, attach a TTY (avoid backgrounding with `&` or piping output)."));
|
|
3637
3641
|
process.exit(1);
|
|
3638
3642
|
}
|
|
3639
3643
|
console.log();
|
|
@@ -5849,7 +5853,8 @@ async function queryThreads(options) {
|
|
|
5849
5853
|
environment: options.environment,
|
|
5850
5854
|
...options.agentId && { agentId: options.agentId },
|
|
5851
5855
|
...options.channel && { channel: options.channel },
|
|
5852
|
-
...options.limit && { limit: options.limit }
|
|
5856
|
+
...options.limit && { limit: options.limit },
|
|
5857
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
5853
5858
|
});
|
|
5854
5859
|
if (result.error || !result.data)
|
|
5855
5860
|
return result;
|
|
@@ -5865,20 +5870,21 @@ async function queryThreads(options) {
|
|
|
5865
5870
|
}
|
|
5866
5871
|
return result;
|
|
5867
5872
|
}
|
|
5868
|
-
async function queryThreadDetail(threadId, messageLimit) {
|
|
5873
|
+
async function queryThreadDetail(threadId, messageLimit, organizationId) {
|
|
5869
5874
|
return convexQuery2("threads:getWithMessages", {
|
|
5870
5875
|
id: threadId,
|
|
5871
|
-
...messageLimit && { messageLimit }
|
|
5876
|
+
...messageLimit && { messageLimit },
|
|
5877
|
+
...organizationId && { organizationId }
|
|
5872
5878
|
});
|
|
5873
5879
|
}
|
|
5874
|
-
async function queryThreadExecutions(threadId) {
|
|
5875
|
-
return convexQuery2("executions:getByThread", { threadId });
|
|
5880
|
+
async function queryThreadExecutions(threadId, organizationId) {
|
|
5881
|
+
return convexQuery2("executions:getByThread", { threadId, ...organizationId && { organizationId } });
|
|
5876
5882
|
}
|
|
5877
|
-
async function resolveThreadId(shortId, environment) {
|
|
5883
|
+
async function resolveThreadId(shortId, environment, organizationId) {
|
|
5878
5884
|
if (shortId.includes("|") || shortId.length > 20) {
|
|
5879
5885
|
return { data: shortId };
|
|
5880
5886
|
}
|
|
5881
|
-
const result = await queryThreads({ environment: environment ?? "development", limit: 100 });
|
|
5887
|
+
const result = await queryThreads({ environment: environment ?? "development", limit: 100, organizationId });
|
|
5882
5888
|
if (result.error || !result.data)
|
|
5883
5889
|
return { error: result.error ?? "Could not fetch threads" };
|
|
5884
5890
|
const threads = result.data;
|
|
@@ -5887,7 +5893,7 @@ async function resolveThreadId(shortId, environment) {
|
|
|
5887
5893
|
for (const env of ["production", "development", "eval"]) {
|
|
5888
5894
|
if (env === (environment ?? "development"))
|
|
5889
5895
|
continue;
|
|
5890
|
-
const envResult = await queryThreads({ environment: env, limit: 100 });
|
|
5896
|
+
const envResult = await queryThreads({ environment: env, limit: 100, organizationId });
|
|
5891
5897
|
if (envResult.data) {
|
|
5892
5898
|
const envThreads = envResult.data;
|
|
5893
5899
|
const envMatch = envThreads.find((t) => t._id.endsWith(shortId));
|
|
@@ -5989,7 +5995,8 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
5989
5995
|
agentId,
|
|
5990
5996
|
channel: opts.channel,
|
|
5991
5997
|
phone: opts.phone,
|
|
5992
|
-
limit: parseInt(opts.limit, 10)
|
|
5998
|
+
limit: parseInt(opts.limit, 10),
|
|
5999
|
+
organizationId: orgId
|
|
5993
6000
|
});
|
|
5994
6001
|
if (error || !data) {
|
|
5995
6002
|
spinner?.fail("Failed to fetch conversations");
|
|
@@ -6026,8 +6033,9 @@ logsCommand.command("list", { isDefault: true }).description("List recent conver
|
|
|
6026
6033
|
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) => {
|
|
6027
6034
|
await ensureAuth2();
|
|
6028
6035
|
const spinner = opts.json ? null : ora12();
|
|
6036
|
+
const orgId = getOrgId2();
|
|
6029
6037
|
spinner?.start("Resolving thread");
|
|
6030
|
-
const resolved = await resolveThreadId(rawThreadId, opts.env);
|
|
6038
|
+
const resolved = await resolveThreadId(rawThreadId, opts.env, orgId);
|
|
6031
6039
|
if (resolved.error || !resolved.data) {
|
|
6032
6040
|
spinner?.fail("Thread not found");
|
|
6033
6041
|
console.log(chalk16.red("Error:"), resolved.error || `No thread matched "${rawThreadId}"`);
|
|
@@ -6037,7 +6045,7 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
|
|
|
6037
6045
|
spinner?.stop();
|
|
6038
6046
|
spinner?.start("Fetching conversation");
|
|
6039
6047
|
const fetchLimit = opts.tail ? 1000 : parseInt(opts.limit, 10);
|
|
6040
|
-
const { data, error } = await queryThreadDetail(threadId, fetchLimit);
|
|
6048
|
+
const { data, error } = await queryThreadDetail(threadId, fetchLimit, orgId);
|
|
6041
6049
|
if (error || !data) {
|
|
6042
6050
|
spinner?.fail("Failed to fetch conversation");
|
|
6043
6051
|
console.log(chalk16.red("Error:"), error || "Thread not found");
|
|
@@ -6047,7 +6055,7 @@ logsCommand.command("view <thread-id>").description("View conversation messages"
|
|
|
6047
6055
|
const result = data;
|
|
6048
6056
|
let executions = [];
|
|
6049
6057
|
if (opts.exec) {
|
|
6050
|
-
const execResult = await queryThreadExecutions(threadId);
|
|
6058
|
+
const execResult = await queryThreadExecutions(threadId, orgId);
|
|
6051
6059
|
if (execResult.data) {
|
|
6052
6060
|
executions = execResult.data;
|
|
6053
6061
|
}
|
|
@@ -7666,51 +7674,54 @@ async function convexMutation5(path, args) {
|
|
|
7666
7674
|
}
|
|
7667
7675
|
return json.value;
|
|
7668
7676
|
}
|
|
7669
|
-
async function listTriggers(environment) {
|
|
7670
|
-
return convexQuery6("triggers:list", { environment });
|
|
7677
|
+
async function listTriggers(environment, organizationId) {
|
|
7678
|
+
return convexQuery6("triggers:list", { environment, ...organizationId && { organizationId } });
|
|
7671
7679
|
}
|
|
7672
|
-
async function getTrigger(slug, environment) {
|
|
7673
|
-
return convexQuery6("triggers:getBySlug", { slug, environment });
|
|
7680
|
+
async function getTrigger(slug, environment, organizationId) {
|
|
7681
|
+
return convexQuery6("triggers:getBySlug", { slug, environment, ...organizationId && { organizationId } });
|
|
7674
7682
|
}
|
|
7675
7683
|
async function listTriggerRuns(options) {
|
|
7676
7684
|
return convexQuery6("triggers:listRuns", {
|
|
7677
7685
|
environment: options.environment,
|
|
7678
7686
|
...options.status && { status: options.status },
|
|
7679
7687
|
...options.triggerSlug && { triggerSlug: options.triggerSlug },
|
|
7680
|
-
...options.limit && { limit: options.limit }
|
|
7688
|
+
...options.limit && { limit: options.limit },
|
|
7689
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
7681
7690
|
});
|
|
7682
7691
|
}
|
|
7683
|
-
async function getTriggerRunDetail(runId, environment) {
|
|
7692
|
+
async function getTriggerRunDetail(runId, environment, organizationId) {
|
|
7684
7693
|
return convexQuery6("triggers:getRunDetail", {
|
|
7685
7694
|
runId,
|
|
7686
|
-
...environment && { environment }
|
|
7695
|
+
...environment && { environment },
|
|
7696
|
+
...organizationId && { organizationId }
|
|
7687
7697
|
});
|
|
7688
7698
|
}
|
|
7689
|
-
async function getTriggerRunStats(environment) {
|
|
7690
|
-
return convexQuery6("triggers:getRunStats", { environment });
|
|
7699
|
+
async function getTriggerRunStats(environment, organizationId) {
|
|
7700
|
+
return convexQuery6("triggers:getRunStats", { environment, ...organizationId && { organizationId } });
|
|
7691
7701
|
}
|
|
7692
|
-
async function getLastRunStatuses(environment) {
|
|
7693
|
-
return convexQuery6("triggers:getLastRunStatuses", { environment });
|
|
7702
|
+
async function getLastRunStatuses(environment, organizationId) {
|
|
7703
|
+
return convexQuery6("triggers:getLastRunStatuses", { environment, ...organizationId && { organizationId } });
|
|
7694
7704
|
}
|
|
7695
|
-
async function cancelTriggerRun(runId, environment) {
|
|
7696
|
-
return convexMutation5("triggers:cancelRun", { runId, environment });
|
|
7705
|
+
async function cancelTriggerRun(runId, environment, organizationId) {
|
|
7706
|
+
return convexMutation5("triggers:cancelRun", { runId, environment, ...organizationId && { organizationId } });
|
|
7697
7707
|
}
|
|
7698
|
-
async function retryTriggerRun(runId, environment) {
|
|
7699
|
-
return convexMutation5("triggers:retryRun", { runId, environment });
|
|
7708
|
+
async function retryTriggerRun(runId, environment, organizationId) {
|
|
7709
|
+
return convexMutation5("triggers:retryRun", { runId, environment, ...organizationId && { organizationId } });
|
|
7700
7710
|
}
|
|
7701
|
-
async function toggleTrigger(slug, enabled, environment) {
|
|
7711
|
+
async function toggleTrigger(slug, enabled, environment, organizationId) {
|
|
7702
7712
|
const path = enabled ? "triggers:enable" : "triggers:disable";
|
|
7703
|
-
return convexMutation5(path, { slug, environment });
|
|
7713
|
+
return convexMutation5(path, { slug, environment, ...organizationId && { organizationId } });
|
|
7704
7714
|
}
|
|
7705
7715
|
async function listTriggerExecutions(options) {
|
|
7706
7716
|
return convexQuery6("triggers:listExecutions", {
|
|
7707
7717
|
environment: options.environment,
|
|
7708
7718
|
...options.triggerSlug && { triggerSlug: options.triggerSlug },
|
|
7709
|
-
...options.limit && { limit: options.limit }
|
|
7719
|
+
...options.limit && { limit: options.limit },
|
|
7720
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
7710
7721
|
});
|
|
7711
7722
|
}
|
|
7712
|
-
async function getTriggerExecutionDetail(eventId, environment) {
|
|
7713
|
-
return convexQuery6("triggers:getExecutionDetail", { eventId, ...environment && { environment } });
|
|
7723
|
+
async function getTriggerExecutionDetail(eventId, environment, organizationId) {
|
|
7724
|
+
return convexQuery6("triggers:getExecutionDetail", { eventId, ...environment && { environment }, ...organizationId && { organizationId } });
|
|
7714
7725
|
}
|
|
7715
7726
|
async function convexAction3(path, args) {
|
|
7716
7727
|
const token = getToken3();
|
|
@@ -7737,11 +7748,15 @@ async function convexAction3(path, args) {
|
|
|
7737
7748
|
}
|
|
7738
7749
|
return json.value;
|
|
7739
7750
|
}
|
|
7740
|
-
async function retryImmediateExecution(eventId, environment) {
|
|
7741
|
-
return convexAction3("triggers:retryImmediateExecution", { eventId, environment });
|
|
7751
|
+
async function retryImmediateExecution(eventId, environment, organizationId) {
|
|
7752
|
+
return convexAction3("triggers:retryImmediateExecution", { eventId, environment, ...organizationId && { organizationId } });
|
|
7742
7753
|
}
|
|
7743
7754
|
|
|
7744
7755
|
// src/cli/commands/triggers.ts
|
|
7756
|
+
function getOrgId3() {
|
|
7757
|
+
const project = loadProject(process.cwd());
|
|
7758
|
+
return project?.organization.id;
|
|
7759
|
+
}
|
|
7745
7760
|
async function withTriggerAuthRetry(fn) {
|
|
7746
7761
|
try {
|
|
7747
7762
|
return await fn();
|
|
@@ -7909,10 +7924,11 @@ triggersCommand.command("list", { isDefault: true }).description("List all trigg
|
|
|
7909
7924
|
await ensureAuth5();
|
|
7910
7925
|
const spinner = opts.json ? null : ora14();
|
|
7911
7926
|
try {
|
|
7927
|
+
const orgId = getOrgId3();
|
|
7912
7928
|
spinner?.start("Fetching triggers");
|
|
7913
7929
|
const [triggers, statuses] = await Promise.all([
|
|
7914
|
-
listTriggers(opts.env),
|
|
7915
|
-
getLastRunStatuses(opts.env)
|
|
7930
|
+
listTriggers(opts.env, orgId),
|
|
7931
|
+
getLastRunStatuses(opts.env, orgId)
|
|
7916
7932
|
]);
|
|
7917
7933
|
let filtered = triggers;
|
|
7918
7934
|
if (opts.failed) {
|
|
@@ -7958,7 +7974,7 @@ triggersCommand.command("get <slug>").description("View trigger details").option
|
|
|
7958
7974
|
const spinner = opts.json ? null : ora14();
|
|
7959
7975
|
try {
|
|
7960
7976
|
spinner?.start("Fetching trigger");
|
|
7961
|
-
const trigger = await getTrigger(slug, opts.env);
|
|
7977
|
+
const trigger = await getTrigger(slug, opts.env, getOrgId3());
|
|
7962
7978
|
if (!trigger) {
|
|
7963
7979
|
spinner?.fail("Trigger not found");
|
|
7964
7980
|
if (opts.json) {
|
|
@@ -8041,7 +8057,8 @@ triggersCommand.command("runs [slug]").description("List trigger runs").option("
|
|
|
8041
8057
|
environment: opts.env,
|
|
8042
8058
|
status: opts.status,
|
|
8043
8059
|
triggerSlug: slug,
|
|
8044
|
-
limit: parseInt(opts.limit, 10)
|
|
8060
|
+
limit: parseInt(opts.limit, 10),
|
|
8061
|
+
organizationId: getOrgId3()
|
|
8045
8062
|
});
|
|
8046
8063
|
spinner?.succeed(`Found ${runs.length} runs`);
|
|
8047
8064
|
if (opts.json) {
|
|
@@ -8083,7 +8100,7 @@ triggersCommand.command("run <run-id>").description("View trigger run details").
|
|
|
8083
8100
|
const spinner = opts.json ? null : ora14();
|
|
8084
8101
|
try {
|
|
8085
8102
|
spinner?.start("Fetching run");
|
|
8086
|
-
const run = await getTriggerRunDetail(runId, opts.env);
|
|
8103
|
+
const run = await getTriggerRunDetail(runId, opts.env, getOrgId3());
|
|
8087
8104
|
if (!run) {
|
|
8088
8105
|
spinner?.fail("Run not found");
|
|
8089
8106
|
if (opts.json) {
|
|
@@ -8127,8 +8144,9 @@ triggersCommand.command("stats").description("Show trigger run statistics").opti
|
|
|
8127
8144
|
await ensureAuth5();
|
|
8128
8145
|
const spinner = opts.json ? null : ora14();
|
|
8129
8146
|
try {
|
|
8147
|
+
const orgId = getOrgId3();
|
|
8130
8148
|
spinner?.start("Fetching statistics");
|
|
8131
|
-
const stats = await getTriggerRunStats(opts.env);
|
|
8149
|
+
const stats = await getTriggerRunStats(opts.env, orgId);
|
|
8132
8150
|
spinner?.succeed("Run statistics");
|
|
8133
8151
|
if (opts.json) {
|
|
8134
8152
|
console.log(JSON.stringify(stats, null, 2));
|
|
@@ -8153,7 +8171,7 @@ triggersCommand.command("stats").description("Show trigger run statistics").opti
|
|
|
8153
8171
|
console.log(` ${chalk20.gray("\u2500".repeat(18))}`);
|
|
8154
8172
|
console.log(` ${chalk20.bold("Total".padEnd(12))} ${chalk20.bold(String(total).padStart(6))}`);
|
|
8155
8173
|
console.log();
|
|
8156
|
-
const executions = await listTriggerExecutions({ environment: opts.env, limit: 50 });
|
|
8174
|
+
const executions = await listTriggerExecutions({ environment: opts.env, limit: 50, organizationId: orgId });
|
|
8157
8175
|
const recentFailures = executions.filter((e) => e.eventType === "trigger.failed");
|
|
8158
8176
|
const recentSuccesses = executions.length - recentFailures.length;
|
|
8159
8177
|
console.log(chalk20.bold(` Recent Executions`));
|
|
@@ -8185,7 +8203,8 @@ triggersCommand.command("logs [slug]").description("View trigger execution histo
|
|
|
8185
8203
|
const executions = await withTriggerAuthRetry(() => listTriggerExecutions({
|
|
8186
8204
|
environment: opts.env,
|
|
8187
8205
|
triggerSlug: slug,
|
|
8188
|
-
limit: parseInt(opts.limit, 10)
|
|
8206
|
+
limit: parseInt(opts.limit, 10),
|
|
8207
|
+
organizationId: getOrgId3()
|
|
8189
8208
|
}));
|
|
8190
8209
|
spinner?.succeed(`Found ${executions.length} executions`);
|
|
8191
8210
|
if (opts.json) {
|
|
@@ -8245,6 +8264,7 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8245
8264
|
await ensureAuth5();
|
|
8246
8265
|
const spinner = opts.json ? null : ora14();
|
|
8247
8266
|
try {
|
|
8267
|
+
const orgId = getOrgId3();
|
|
8248
8268
|
const nth = parseInt(opts.nth, 10);
|
|
8249
8269
|
if (isNaN(nth) || nth < 1) {
|
|
8250
8270
|
console.error(chalk20.red("Error:"), "--nth must be a positive integer (e.g., --nth 1 for most recent)");
|
|
@@ -8257,7 +8277,8 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8257
8277
|
const executions = await withTriggerAuthRetry(() => listTriggerExecutions({
|
|
8258
8278
|
environment: opts.env,
|
|
8259
8279
|
triggerSlug: identifier,
|
|
8260
|
-
limit: nth
|
|
8280
|
+
limit: nth,
|
|
8281
|
+
organizationId: orgId
|
|
8261
8282
|
}));
|
|
8262
8283
|
if (!executions.length) {
|
|
8263
8284
|
spinner?.fail(`No executions found for trigger "${identifier}" in ${opts.env}`);
|
|
@@ -8275,7 +8296,7 @@ triggersCommand.command("log <identifier>").description("View detailed trigger e
|
|
|
8275
8296
|
spinner?.succeed(`Found execution for "${identifier}"`);
|
|
8276
8297
|
}
|
|
8277
8298
|
spinner?.start("Fetching execution detail");
|
|
8278
|
-
const event = await withTriggerAuthRetry(() => getTriggerExecutionDetail(eventId, opts.env));
|
|
8299
|
+
const event = await withTriggerAuthRetry(() => getTriggerExecutionDetail(eventId, opts.env, orgId));
|
|
8279
8300
|
if (!event) {
|
|
8280
8301
|
spinner?.fail("Execution not found");
|
|
8281
8302
|
if (opts.json) {
|
|
@@ -8337,7 +8358,7 @@ triggersCommand.command("retry <run-id>").description("Retry a failed or dead ru
|
|
|
8337
8358
|
}
|
|
8338
8359
|
try {
|
|
8339
8360
|
spinner?.start("Retrying run...");
|
|
8340
|
-
await retryTriggerRun(runId, environment);
|
|
8361
|
+
await retryTriggerRun(runId, environment, getOrgId3());
|
|
8341
8362
|
spinner?.succeed(chalk20.green(`Run ${runId} queued for retry`));
|
|
8342
8363
|
if (opts.json) {
|
|
8343
8364
|
console.log(JSON.stringify({ success: true, runId }));
|
|
@@ -8368,7 +8389,7 @@ triggersCommand.command("cancel <run-id>").description("Cancel a pending run").o
|
|
|
8368
8389
|
}
|
|
8369
8390
|
try {
|
|
8370
8391
|
spinner?.start("Cancelling run...");
|
|
8371
|
-
await cancelTriggerRun(runId, environment);
|
|
8392
|
+
await cancelTriggerRun(runId, environment, getOrgId3());
|
|
8372
8393
|
spinner?.succeed(chalk20.green(`Run ${runId} cancelled`));
|
|
8373
8394
|
if (opts.json) {
|
|
8374
8395
|
console.log(JSON.stringify({ success: true, runId }));
|
|
@@ -8399,7 +8420,7 @@ triggersCommand.command("enable <slug>").description("Enable a trigger").option(
|
|
|
8399
8420
|
}
|
|
8400
8421
|
try {
|
|
8401
8422
|
spinner?.start("Enabling trigger...");
|
|
8402
|
-
await toggleTrigger(slug, true, environment);
|
|
8423
|
+
await toggleTrigger(slug, true, environment, getOrgId3());
|
|
8403
8424
|
spinner?.succeed(chalk20.green(`Trigger ${slug} enabled`));
|
|
8404
8425
|
if (opts.json) {
|
|
8405
8426
|
console.log(JSON.stringify({ success: true, slug }));
|
|
@@ -8430,7 +8451,7 @@ triggersCommand.command("disable <slug>").description("Disable a trigger").optio
|
|
|
8430
8451
|
}
|
|
8431
8452
|
try {
|
|
8432
8453
|
spinner?.start("Disabling trigger...");
|
|
8433
|
-
await toggleTrigger(slug, false, environment);
|
|
8454
|
+
await toggleTrigger(slug, false, environment, getOrgId3());
|
|
8434
8455
|
spinner?.succeed(chalk20.green(`Trigger ${slug} disabled`));
|
|
8435
8456
|
if (opts.json) {
|
|
8436
8457
|
console.log(JSON.stringify({ success: true, slug }));
|
|
@@ -8461,7 +8482,7 @@ triggersCommand.command("retry-event <event-id>").description("Retry a failed im
|
|
|
8461
8482
|
}
|
|
8462
8483
|
try {
|
|
8463
8484
|
spinner?.start("Retrying failed execution...");
|
|
8464
|
-
const result = await retryImmediateExecution(eventId, environment);
|
|
8485
|
+
const result = await retryImmediateExecution(eventId, environment, getOrgId3());
|
|
8465
8486
|
if (result.success) {
|
|
8466
8487
|
spinner?.succeed(chalk20.green(`Execution retried successfully`));
|
|
8467
8488
|
} else {
|
|
@@ -8509,7 +8530,8 @@ triggersCommand.command("fire <slug>").description("Manually fire a trigger").op
|
|
|
8509
8530
|
slug,
|
|
8510
8531
|
environment,
|
|
8511
8532
|
entityId: opts.entity,
|
|
8512
|
-
data
|
|
8533
|
+
data,
|
|
8534
|
+
organizationId: getOrgId3()
|
|
8513
8535
|
});
|
|
8514
8536
|
if (error) {
|
|
8515
8537
|
spinner?.fail("Trigger execution failed");
|
|
@@ -8667,12 +8689,14 @@ async function listThreads(options) {
|
|
|
8667
8689
|
return convexQuery7("threads:listWithPreviews", {
|
|
8668
8690
|
environment: options.environment,
|
|
8669
8691
|
channel: options.channel,
|
|
8670
|
-
limit: options.limit
|
|
8692
|
+
limit: options.limit,
|
|
8693
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
8671
8694
|
});
|
|
8672
8695
|
}
|
|
8673
8696
|
async function getThreadWithMessages(options) {
|
|
8674
8697
|
return convexQuery7("threads:getWithMessages", {
|
|
8675
|
-
id: options.threadId
|
|
8698
|
+
id: options.threadId,
|
|
8699
|
+
...options.organizationId && { organizationId: options.organizationId }
|
|
8676
8700
|
});
|
|
8677
8701
|
}
|
|
8678
8702
|
async function archiveThread(options) {
|
|
@@ -10450,8 +10474,8 @@ function checkModelConfig(resources) {
|
|
|
10450
10474
|
hint: "Check agent model config - temperature should be 0-2"
|
|
10451
10475
|
};
|
|
10452
10476
|
}
|
|
10453
|
-
async function checkStuckThreads(environment) {
|
|
10454
|
-
const threads = await withAuthRetry2(() => listThreads({ environment, limit: 100 }));
|
|
10477
|
+
async function checkStuckThreads(environment, organizationId) {
|
|
10478
|
+
const threads = await withAuthRetry2(() => listThreads({ environment, limit: 100, organizationId }));
|
|
10455
10479
|
const issues = [];
|
|
10456
10480
|
const now = Date.now();
|
|
10457
10481
|
const fiveMinutes = 5 * 60 * 1000;
|
|
@@ -10480,8 +10504,8 @@ async function checkStuckThreads(environment) {
|
|
|
10480
10504
|
hint: "Run `struere threads archive <id>` to archive stuck threads"
|
|
10481
10505
|
};
|
|
10482
10506
|
}
|
|
10483
|
-
async function checkTriggerHealth(environment) {
|
|
10484
|
-
const executions = await withAuthRetry2(() => listTriggerExecutions({ environment, limit: 100 }));
|
|
10507
|
+
async function checkTriggerHealth(environment, organizationId) {
|
|
10508
|
+
const executions = await withAuthRetry2(() => listTriggerExecutions({ environment, limit: 100, organizationId }));
|
|
10485
10509
|
if (executions.length === 0) {
|
|
10486
10510
|
return {
|
|
10487
10511
|
id: "trigger-health",
|
|
@@ -10528,8 +10552,8 @@ async function checkTriggerHealth(environment) {
|
|
|
10528
10552
|
hint: "Run `struere triggers logs <slug>` to investigate failures"
|
|
10529
10553
|
};
|
|
10530
10554
|
}
|
|
10531
|
-
async function checkSyncDrift(resources, environment) {
|
|
10532
|
-
const { state, error } = await withAuthRetry2(() => getSyncState(
|
|
10555
|
+
async function checkSyncDrift(resources, environment, organizationId) {
|
|
10556
|
+
const { state, error } = await withAuthRetry2(() => getSyncState(organizationId, environment));
|
|
10533
10557
|
if (error || !state) {
|
|
10534
10558
|
return {
|
|
10535
10559
|
id: "sync-drift",
|
|
@@ -10638,6 +10662,8 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10638
10662
|
const spinner = opts.json ? null : ora20();
|
|
10639
10663
|
const cwd = process.cwd();
|
|
10640
10664
|
const environment = opts.env;
|
|
10665
|
+
const project = loadProject(cwd);
|
|
10666
|
+
const organizationId = project?.organization.id;
|
|
10641
10667
|
try {
|
|
10642
10668
|
spinner?.start("Loading resources...");
|
|
10643
10669
|
const resources = await loadAllResources(cwd);
|
|
@@ -10648,9 +10674,9 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10648
10674
|
runCheck(() => checkTemplateApprovals(resources)),
|
|
10649
10675
|
runCheck(() => checkEntityTypeReferences(resources)),
|
|
10650
10676
|
runCheck(() => checkModelConfig(resources)),
|
|
10651
|
-
runCheck(() => checkStuckThreads(environment)),
|
|
10652
|
-
runCheck(() => checkTriggerHealth(environment)),
|
|
10653
|
-
runCheck(() => checkSyncDrift(resources, environment))
|
|
10677
|
+
runCheck(() => checkStuckThreads(environment, organizationId)),
|
|
10678
|
+
runCheck(() => checkTriggerHealth(environment, organizationId)),
|
|
10679
|
+
runCheck(() => checkSyncDrift(resources, environment, organizationId))
|
|
10654
10680
|
]);
|
|
10655
10681
|
spinner?.stop();
|
|
10656
10682
|
const checks = results.map((r) => r.status === "fulfilled" ? r.value : { id: "unknown", label: "Unknown", status: "warn", message: `Check failed: ${r.reason}` });
|
|
@@ -10704,10 +10730,332 @@ var doctorCommand = new Command25("doctor").description("Run diagnostic checks o
|
|
|
10704
10730
|
process.exit(1);
|
|
10705
10731
|
}
|
|
10706
10732
|
});
|
|
10733
|
+
|
|
10734
|
+
// src/cli/commands/keys.ts
|
|
10735
|
+
init_credentials();
|
|
10736
|
+
import { Command as Command26 } from "commander";
|
|
10737
|
+
import chalk29 from "chalk";
|
|
10738
|
+
import ora21 from "ora";
|
|
10739
|
+
import { input as input3, confirm as confirm8 } from "@inquirer/prompts";
|
|
10740
|
+
init_convex();
|
|
10741
|
+
|
|
10742
|
+
// src/cli/utils/apiKeys.ts
|
|
10743
|
+
init_credentials();
|
|
10744
|
+
init_config();
|
|
10745
|
+
function getToken5() {
|
|
10746
|
+
const credentials = loadCredentials();
|
|
10747
|
+
const apiKey = getApiKey();
|
|
10748
|
+
const token = apiKey || credentials?.token;
|
|
10749
|
+
if (!token)
|
|
10750
|
+
throw new Error("Not authenticated");
|
|
10751
|
+
return token;
|
|
10752
|
+
}
|
|
10753
|
+
async function convexQuery8(path, args) {
|
|
10754
|
+
const token = getToken5();
|
|
10755
|
+
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
10756
|
+
method: "POST",
|
|
10757
|
+
headers: {
|
|
10758
|
+
"Content-Type": "application/json",
|
|
10759
|
+
Authorization: `Bearer ${token}`
|
|
10760
|
+
},
|
|
10761
|
+
body: JSON.stringify({ path, args })
|
|
10762
|
+
});
|
|
10763
|
+
const text = await response.text();
|
|
10764
|
+
let json;
|
|
10765
|
+
try {
|
|
10766
|
+
json = JSON.parse(text);
|
|
10767
|
+
} catch {
|
|
10768
|
+
throw new Error(text || `HTTP ${response.status}`);
|
|
10769
|
+
}
|
|
10770
|
+
if (!response.ok) {
|
|
10771
|
+
throw new Error(json.errorData?.message || json.errorMessage || text);
|
|
10772
|
+
}
|
|
10773
|
+
if (json.status === "error") {
|
|
10774
|
+
throw new Error(json.errorMessage || "Unknown error from Convex");
|
|
10775
|
+
}
|
|
10776
|
+
return json.value;
|
|
10777
|
+
}
|
|
10778
|
+
async function convexMutation6(path, args) {
|
|
10779
|
+
const token = getToken5();
|
|
10780
|
+
const response = await fetch(`${CONVEX_URL}/api/mutation`, {
|
|
10781
|
+
method: "POST",
|
|
10782
|
+
headers: {
|
|
10783
|
+
"Content-Type": "application/json",
|
|
10784
|
+
Authorization: `Bearer ${token}`
|
|
10785
|
+
},
|
|
10786
|
+
body: JSON.stringify({ path, args })
|
|
10787
|
+
});
|
|
10788
|
+
const text = await response.text();
|
|
10789
|
+
let json;
|
|
10790
|
+
try {
|
|
10791
|
+
json = JSON.parse(text);
|
|
10792
|
+
} catch {
|
|
10793
|
+
throw new Error(text || `HTTP ${response.status}`);
|
|
10794
|
+
}
|
|
10795
|
+
if (!response.ok) {
|
|
10796
|
+
throw new Error(json.errorData?.message || json.errorMessage || text);
|
|
10797
|
+
}
|
|
10798
|
+
if (json.status === "error") {
|
|
10799
|
+
throw new Error(json.errorMessage || "Unknown error from Convex");
|
|
10800
|
+
}
|
|
10801
|
+
return json.value;
|
|
10802
|
+
}
|
|
10803
|
+
async function listApiKeys() {
|
|
10804
|
+
return convexQuery8("apiKeys:list", {});
|
|
10805
|
+
}
|
|
10806
|
+
async function createApiKey(args) {
|
|
10807
|
+
return convexMutation6("apiKeys:create", {
|
|
10808
|
+
name: args.name,
|
|
10809
|
+
environment: args.environment,
|
|
10810
|
+
permissions: args.permissions ?? ["*"]
|
|
10811
|
+
});
|
|
10812
|
+
}
|
|
10813
|
+
async function removeApiKey(id) {
|
|
10814
|
+
return convexMutation6("apiKeys:remove", { id });
|
|
10815
|
+
}
|
|
10816
|
+
|
|
10817
|
+
// src/cli/commands/keys.ts
|
|
10818
|
+
async function withKeyAuthRetry(fn) {
|
|
10819
|
+
try {
|
|
10820
|
+
return await fn();
|
|
10821
|
+
} catch (err) {
|
|
10822
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10823
|
+
if (msg.includes("Unauthenticated") || msg.includes("OIDC") || msg.includes("token") || msg.includes("expired")) {
|
|
10824
|
+
const refreshed = await refreshToken();
|
|
10825
|
+
if (!refreshed)
|
|
10826
|
+
throw err;
|
|
10827
|
+
return fn();
|
|
10828
|
+
}
|
|
10829
|
+
throw err;
|
|
10830
|
+
}
|
|
10831
|
+
}
|
|
10832
|
+
async function ensureAuth9() {
|
|
10833
|
+
const cwd = process.cwd();
|
|
10834
|
+
const nonInteractive = !isInteractive();
|
|
10835
|
+
if (!hasProject(cwd)) {
|
|
10836
|
+
if (nonInteractive) {
|
|
10837
|
+
console.error(chalk29.red("No struere.json found. Run struere init first."));
|
|
10838
|
+
process.exit(1);
|
|
10839
|
+
}
|
|
10840
|
+
console.log(chalk29.yellow("No struere.json found - initializing project..."));
|
|
10841
|
+
console.log();
|
|
10842
|
+
const success = await runInit(cwd);
|
|
10843
|
+
if (!success) {
|
|
10844
|
+
process.exit(1);
|
|
10845
|
+
}
|
|
10846
|
+
console.log();
|
|
10847
|
+
}
|
|
10848
|
+
let credentials = loadCredentials();
|
|
10849
|
+
const apiKey = getApiKey();
|
|
10850
|
+
if (!credentials && !apiKey) {
|
|
10851
|
+
if (nonInteractive) {
|
|
10852
|
+
console.error(chalk29.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
|
|
10853
|
+
process.exit(1);
|
|
10854
|
+
}
|
|
10855
|
+
console.log(chalk29.yellow("Not logged in - authenticating..."));
|
|
10856
|
+
console.log();
|
|
10857
|
+
credentials = await performLogin();
|
|
10858
|
+
if (!credentials) {
|
|
10859
|
+
console.log(chalk29.red("Authentication failed"));
|
|
10860
|
+
process.exit(1);
|
|
10861
|
+
}
|
|
10862
|
+
console.log();
|
|
10863
|
+
}
|
|
10864
|
+
return true;
|
|
10865
|
+
}
|
|
10866
|
+
function relativeTime4(ts) {
|
|
10867
|
+
const diff = Date.now() - ts;
|
|
10868
|
+
const seconds = Math.floor(diff / 1000);
|
|
10869
|
+
if (seconds < 60)
|
|
10870
|
+
return `${seconds}s ago`;
|
|
10871
|
+
const minutes = Math.floor(seconds / 60);
|
|
10872
|
+
if (minutes < 60)
|
|
10873
|
+
return `${minutes}m ago`;
|
|
10874
|
+
const hours = Math.floor(minutes / 60);
|
|
10875
|
+
if (hours < 24)
|
|
10876
|
+
return `${hours}h ago`;
|
|
10877
|
+
const days = Math.floor(hours / 24);
|
|
10878
|
+
return `${days}d ago`;
|
|
10879
|
+
}
|
|
10880
|
+
function maskedPrefix(prefix) {
|
|
10881
|
+
return `${prefix}****`;
|
|
10882
|
+
}
|
|
10883
|
+
function isValidEnvironment(value) {
|
|
10884
|
+
return value === "development" || value === "production" || value === "eval";
|
|
10885
|
+
}
|
|
10886
|
+
var keysCommand = new Command26("keys").description("Manage API keys");
|
|
10887
|
+
keysCommand.command("list", { isDefault: true }).description("List API keys").option("--env <environment>", "Filter by environment (development|production|eval)").option("--json", "Output raw JSON").action(async (opts) => {
|
|
10888
|
+
await ensureAuth9();
|
|
10889
|
+
const spinner = opts.json ? null : ora21();
|
|
10890
|
+
try {
|
|
10891
|
+
spinner?.start("Fetching API keys");
|
|
10892
|
+
let keys = await withKeyAuthRetry(() => listApiKeys());
|
|
10893
|
+
if (opts.env) {
|
|
10894
|
+
if (!isValidEnvironment(opts.env)) {
|
|
10895
|
+
spinner?.fail(`Invalid environment: ${opts.env}`);
|
|
10896
|
+
process.exit(1);
|
|
10897
|
+
}
|
|
10898
|
+
keys = keys.filter((k) => k.environment === opts.env);
|
|
10899
|
+
}
|
|
10900
|
+
spinner?.succeed(`Found ${keys.length} API key${keys.length === 1 ? "" : "s"}${opts.env ? ` (${opts.env})` : ""}`);
|
|
10901
|
+
if (opts.json) {
|
|
10902
|
+
console.log(JSON.stringify(keys, null, 2));
|
|
10903
|
+
return;
|
|
10904
|
+
}
|
|
10905
|
+
console.log();
|
|
10906
|
+
renderTable([
|
|
10907
|
+
{ key: "id", label: "ID", width: 14 },
|
|
10908
|
+
{ key: "name", label: "Name", width: 24 },
|
|
10909
|
+
{ key: "prefix", label: "Prefix", width: 22 },
|
|
10910
|
+
{ key: "environment", label: "Env", width: 12 },
|
|
10911
|
+
{ key: "created", label: "Created", width: 12 },
|
|
10912
|
+
{ key: "lastUsed", label: "Last Used", width: 12 }
|
|
10913
|
+
], keys.map((k) => ({
|
|
10914
|
+
id: k.id.slice(-12),
|
|
10915
|
+
name: k.name,
|
|
10916
|
+
prefix: maskedPrefix(k.keyPrefix),
|
|
10917
|
+
environment: k.environment,
|
|
10918
|
+
created: relativeTime4(k.createdAt),
|
|
10919
|
+
lastUsed: k.lastUsedAt ? relativeTime4(k.lastUsedAt) : chalk29.gray("-")
|
|
10920
|
+
})));
|
|
10921
|
+
console.log();
|
|
10922
|
+
} catch (err) {
|
|
10923
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10924
|
+
spinner?.fail("Failed to fetch API keys");
|
|
10925
|
+
if (opts.json) {
|
|
10926
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
10927
|
+
} else {
|
|
10928
|
+
console.log(chalk29.red("Error:"), message);
|
|
10929
|
+
}
|
|
10930
|
+
process.exit(1);
|
|
10931
|
+
}
|
|
10932
|
+
});
|
|
10933
|
+
keysCommand.command("create").description("Create a new API key").option("--name <name>", "Key name").option("--env <environment>", "Environment (development|production|eval)", "development").option("--json", "Output raw JSON").option("--confirm", "Skip production confirmation").action(async (opts) => {
|
|
10934
|
+
await ensureAuth9();
|
|
10935
|
+
if (!isValidEnvironment(opts.env)) {
|
|
10936
|
+
const message = `Invalid environment: ${opts.env}`;
|
|
10937
|
+
if (opts.json) {
|
|
10938
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
10939
|
+
} else {
|
|
10940
|
+
console.log(chalk29.red("Error:"), message);
|
|
10941
|
+
}
|
|
10942
|
+
process.exit(1);
|
|
10943
|
+
}
|
|
10944
|
+
const environment = opts.env;
|
|
10945
|
+
let name = opts.name;
|
|
10946
|
+
if (!name || !name.trim()) {
|
|
10947
|
+
if (!isInteractive()) {
|
|
10948
|
+
const message = "--name is required in non-interactive mode";
|
|
10949
|
+
if (opts.json) {
|
|
10950
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
10951
|
+
} else {
|
|
10952
|
+
console.log(chalk29.red("Error:"), message);
|
|
10953
|
+
}
|
|
10954
|
+
process.exit(1);
|
|
10955
|
+
}
|
|
10956
|
+
name = await input3({
|
|
10957
|
+
message: "API key name:",
|
|
10958
|
+
validate: (v) => v.trim().length > 0 || "Name is required"
|
|
10959
|
+
});
|
|
10960
|
+
}
|
|
10961
|
+
name = name.trim();
|
|
10962
|
+
if (environment === "production" && !opts.confirm && !opts.json && isInteractive()) {
|
|
10963
|
+
const ok = await confirm8({
|
|
10964
|
+
message: chalk29.yellow("Create API key in PRODUCTION environment?"),
|
|
10965
|
+
default: false
|
|
10966
|
+
});
|
|
10967
|
+
if (!ok) {
|
|
10968
|
+
console.log(chalk29.gray("Cancelled"));
|
|
10969
|
+
process.exit(0);
|
|
10970
|
+
}
|
|
10971
|
+
}
|
|
10972
|
+
const spinner = opts.json ? null : ora21();
|
|
10973
|
+
try {
|
|
10974
|
+
spinner?.start("Creating API key");
|
|
10975
|
+
const result = await withKeyAuthRetry(() => createApiKey({ name, environment }));
|
|
10976
|
+
spinner?.succeed(chalk29.green(`Created API key ${chalk29.cyan(result.name)}`));
|
|
10977
|
+
if (opts.json) {
|
|
10978
|
+
console.log(JSON.stringify({
|
|
10979
|
+
id: result.id,
|
|
10980
|
+
name: result.name,
|
|
10981
|
+
prefix: result.keyPrefix,
|
|
10982
|
+
key: result.key,
|
|
10983
|
+
environment,
|
|
10984
|
+
createdAt: result.createdAt
|
|
10985
|
+
}, null, 2));
|
|
10986
|
+
return;
|
|
10987
|
+
}
|
|
10988
|
+
console.log();
|
|
10989
|
+
console.log(chalk29.bold(" " + chalk29.yellow("Save this key now \u2014 it will not be shown again.")));
|
|
10990
|
+
console.log();
|
|
10991
|
+
console.log(` ${chalk29.gray("Key:")} ${chalk29.cyan(result.key)}`);
|
|
10992
|
+
console.log(` ${chalk29.gray("Name:")} ${result.name}`);
|
|
10993
|
+
console.log(` ${chalk29.gray("Prefix:")} ${result.keyPrefix}`);
|
|
10994
|
+
console.log(` ${chalk29.gray("Environment:")} ${environment}`);
|
|
10995
|
+
console.log(` ${chalk29.gray("ID:")} ${result.id}`);
|
|
10996
|
+
console.log();
|
|
10997
|
+
} catch (err) {
|
|
10998
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10999
|
+
spinner?.fail("Failed to create API key");
|
|
11000
|
+
if (opts.json) {
|
|
11001
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
11002
|
+
} else {
|
|
11003
|
+
console.log(chalk29.red("Error:"), message);
|
|
11004
|
+
}
|
|
11005
|
+
process.exit(1);
|
|
11006
|
+
}
|
|
11007
|
+
});
|
|
11008
|
+
keysCommand.command("revoke <id-or-prefix>").description("Revoke an API key (delete)").option("--confirm", "Skip confirmation prompt").option("--json", "Output raw JSON").action(async (idOrPrefix, opts) => {
|
|
11009
|
+
await ensureAuth9();
|
|
11010
|
+
const spinner = opts.json ? null : ora21();
|
|
11011
|
+
try {
|
|
11012
|
+
spinner?.start("Looking up API key");
|
|
11013
|
+
const keys = await withKeyAuthRetry(() => listApiKeys());
|
|
11014
|
+
const target = keys.find((k) => k.id === idOrPrefix) ?? keys.find((k) => k.id.endsWith(idOrPrefix)) ?? keys.find((k) => k.keyPrefix === idOrPrefix) ?? keys.find((k) => k.keyPrefix.startsWith(idOrPrefix));
|
|
11015
|
+
if (!target) {
|
|
11016
|
+
spinner?.fail(`API key not found: ${idOrPrefix}`);
|
|
11017
|
+
if (opts.json) {
|
|
11018
|
+
console.log(JSON.stringify({ success: false, error: "API key not found" }));
|
|
11019
|
+
}
|
|
11020
|
+
process.exit(1);
|
|
11021
|
+
}
|
|
11022
|
+
spinner?.succeed(`Found ${chalk29.cyan(target.name)} (${maskedPrefix(target.keyPrefix)}, ${target.environment})`);
|
|
11023
|
+
if (!opts.confirm && !opts.json) {
|
|
11024
|
+
if (!isInteractive()) {
|
|
11025
|
+
console.log(chalk29.red("Error:"), "Use --confirm to revoke in non-interactive mode");
|
|
11026
|
+
process.exit(1);
|
|
11027
|
+
}
|
|
11028
|
+
const ok = await confirm8({
|
|
11029
|
+
message: `Revoke this key? This cannot be undone.`,
|
|
11030
|
+
default: false
|
|
11031
|
+
});
|
|
11032
|
+
if (!ok) {
|
|
11033
|
+
console.log(chalk29.gray("Cancelled"));
|
|
11034
|
+
process.exit(0);
|
|
11035
|
+
}
|
|
11036
|
+
}
|
|
11037
|
+
const revokeSpinner = opts.json ? null : ora21();
|
|
11038
|
+
revokeSpinner?.start("Revoking API key");
|
|
11039
|
+
await withKeyAuthRetry(() => removeApiKey(target.id));
|
|
11040
|
+
revokeSpinner?.succeed(chalk29.green(`Revoked ${chalk29.cyan(target.name)}`));
|
|
11041
|
+
if (opts.json) {
|
|
11042
|
+
console.log(JSON.stringify({ success: true, id: target.id, name: target.name }));
|
|
11043
|
+
}
|
|
11044
|
+
} catch (err) {
|
|
11045
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
11046
|
+
spinner?.fail("Failed to revoke API key");
|
|
11047
|
+
if (opts.json) {
|
|
11048
|
+
console.log(JSON.stringify({ success: false, error: message }));
|
|
11049
|
+
} else {
|
|
11050
|
+
console.log(chalk29.red("Error:"), message);
|
|
11051
|
+
}
|
|
11052
|
+
process.exit(1);
|
|
11053
|
+
}
|
|
11054
|
+
});
|
|
10707
11055
|
// package.json
|
|
10708
11056
|
var package_default = {
|
|
10709
11057
|
name: "struere",
|
|
10710
|
-
version: "0.14.
|
|
11058
|
+
version: "0.14.3",
|
|
10711
11059
|
description: "Build, test, and deploy AI agents",
|
|
10712
11060
|
keywords: [
|
|
10713
11061
|
"ai",
|
|
@@ -10742,13 +11090,17 @@ var package_default = {
|
|
|
10742
11090
|
".": {
|
|
10743
11091
|
import: "./dist/index.js",
|
|
10744
11092
|
types: "./dist/index.d.ts"
|
|
11093
|
+
},
|
|
11094
|
+
"./client": {
|
|
11095
|
+
import: "./dist/client/index.js",
|
|
11096
|
+
types: "./dist/client/index.d.ts"
|
|
10745
11097
|
}
|
|
10746
11098
|
},
|
|
10747
11099
|
files: [
|
|
10748
11100
|
"dist"
|
|
10749
11101
|
],
|
|
10750
11102
|
scripts: {
|
|
10751
|
-
build: "bun build ./src/cli/index.ts --outdir ./dist/cli --target bun --external commander --external chalk --external ora --external chokidar --external yaml --external @inquirer/prompts && bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/bin/struere.ts --outdir ./dist/bin --target bun --external commander --external chalk --external ora --external chokidar --external yaml --external @inquirer/prompts && tsc --emitDeclarationOnly && chmod +x ./dist/bin/struere.js",
|
|
11103
|
+
build: "bun build ./src/cli/index.ts --outdir ./dist/cli --target bun --external commander --external chalk --external ora --external chokidar --external yaml --external @inquirer/prompts && bun build ./src/index.ts --outdir ./dist --target node && bun build ./src/client/index.ts --outdir ./dist/client --target browser && bun build ./src/bin/struere.ts --outdir ./dist/bin --target bun --external commander --external chalk --external ora --external chokidar --external yaml --external @inquirer/prompts && tsc --emitDeclarationOnly && chmod +x ./dist/bin/struere.js",
|
|
10752
11104
|
dev: "tsc --watch",
|
|
10753
11105
|
test: "bun test",
|
|
10754
11106
|
prepublishOnly: "bun run build"
|
|
@@ -10832,4 +11184,5 @@ program.addCommand(chatCommand);
|
|
|
10832
11184
|
program.addCommand(whatsappCommand);
|
|
10833
11185
|
program.addCommand(diffCommand);
|
|
10834
11186
|
program.addCommand(doctorCommand);
|
|
11187
|
+
program.addCommand(keysCommand);
|
|
10835
11188
|
program.parse();
|