@wayai/cli 0.3.92 → 0.3.93
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/index.js +209 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -561,6 +561,15 @@ var init_api_client = __esm({
|
|
|
561
561
|
const qs = new URLSearchParams({ hub_id: hubId });
|
|
562
562
|
return this.request("GET", `/api/setup/connections?${qs.toString()}`);
|
|
563
563
|
}
|
|
564
|
+
/**
|
|
565
|
+
* Active operational alerts (Status & Notices) for a hub — the same runtime
|
|
566
|
+
* connection/credential-health surface the web app shows. Requires `hub:read`.
|
|
567
|
+
* The read surface never carries a provider error body (only provider +
|
|
568
|
+
* status_code + category + counts), so it's safe to print verbatim.
|
|
569
|
+
*/
|
|
570
|
+
async getHubAlerts(hubId) {
|
|
571
|
+
return this.request("GET", `/api/hubs/${encodeURIComponent(hubId)}/alerts`);
|
|
572
|
+
}
|
|
564
573
|
/** Set a credential on a PREVIEW connection (direct secret or org-credential link). */
|
|
565
574
|
async setPreviewConnectionCredential(connectionId, body) {
|
|
566
575
|
return this.request("PATCH", `/api/setup/connections/${connectionId}`, body);
|
|
@@ -8780,7 +8789,8 @@ var init_utils = __esm({
|
|
|
8780
8789
|
"eval",
|
|
8781
8790
|
"admin",
|
|
8782
8791
|
"report",
|
|
8783
|
-
"conversations"
|
|
8792
|
+
"conversations",
|
|
8793
|
+
"alerts"
|
|
8784
8794
|
]);
|
|
8785
8795
|
}
|
|
8786
8796
|
});
|
|
@@ -15998,6 +16008,183 @@ var init_conversations = __esm({
|
|
|
15998
16008
|
}
|
|
15999
16009
|
});
|
|
16000
16010
|
|
|
16011
|
+
// src/lib/hub-alerts.ts
|
|
16012
|
+
function severityGlyph(severity) {
|
|
16013
|
+
switch (severity) {
|
|
16014
|
+
case "critical":
|
|
16015
|
+
return "\u2716";
|
|
16016
|
+
case "warn":
|
|
16017
|
+
return "\u26A0";
|
|
16018
|
+
default:
|
|
16019
|
+
return "\u2139";
|
|
16020
|
+
}
|
|
16021
|
+
}
|
|
16022
|
+
function formatProviderBits(alert) {
|
|
16023
|
+
return [alert.provider, alert.status_code != null ? `${alert.status_code}` : null].filter(Boolean).join(" ");
|
|
16024
|
+
}
|
|
16025
|
+
function formatAlertTarget(alert, resolveLabel) {
|
|
16026
|
+
if (alert.connection_id) {
|
|
16027
|
+
return resolveLabel?.(alert.connection_id) ?? `connection ${alert.connection_id}`;
|
|
16028
|
+
}
|
|
16029
|
+
if (alert.channel_id) return `channel ${alert.channel_id}`;
|
|
16030
|
+
return "\u2014";
|
|
16031
|
+
}
|
|
16032
|
+
function describeCategory(category) {
|
|
16033
|
+
switch (category) {
|
|
16034
|
+
case "connection_auth":
|
|
16035
|
+
return {
|
|
16036
|
+
label: "Credential rejected",
|
|
16037
|
+
hint: "The provider rejected this connection's credential (auth). Update the API key/credential on the connection."
|
|
16038
|
+
};
|
|
16039
|
+
case "connection_quota":
|
|
16040
|
+
return {
|
|
16041
|
+
label: "Quota / rate limit",
|
|
16042
|
+
hint: "The provider returned a quota or rate-limit error. Check the provider account's usage/billing."
|
|
16043
|
+
};
|
|
16044
|
+
case "channel_token":
|
|
16045
|
+
return {
|
|
16046
|
+
label: "Channel token invalid",
|
|
16047
|
+
hint: "The channel token is expired or revoked. Reconnect the channel to refresh it."
|
|
16048
|
+
};
|
|
16049
|
+
case "tool_auth":
|
|
16050
|
+
return {
|
|
16051
|
+
label: "Tool auth failed",
|
|
16052
|
+
hint: "An external tool/MCP server rejected auth. Re-authorize the tool connection."
|
|
16053
|
+
};
|
|
16054
|
+
case "production_credential_missing":
|
|
16055
|
+
return {
|
|
16056
|
+
label: "Production credential missing",
|
|
16057
|
+
hint: "A production connection has no credential. Set it with `wayai set-connection-credential`."
|
|
16058
|
+
};
|
|
16059
|
+
default:
|
|
16060
|
+
if (category.startsWith("provider:")) {
|
|
16061
|
+
return {
|
|
16062
|
+
label: "Provider degraded",
|
|
16063
|
+
hint: "An upstream provider is degraded (platform-level). Usually clears on its own once the provider recovers."
|
|
16064
|
+
};
|
|
16065
|
+
}
|
|
16066
|
+
return { label: category, hint: "Tenant-actionable connection/credential alert \u2014 inspect the connection in the hub UI." };
|
|
16067
|
+
}
|
|
16068
|
+
}
|
|
16069
|
+
function activeAlerts(alerts) {
|
|
16070
|
+
return alerts.filter((a) => a.status === "active");
|
|
16071
|
+
}
|
|
16072
|
+
function summarizeActiveAlertsForReport(alerts) {
|
|
16073
|
+
const active = activeAlerts(alerts);
|
|
16074
|
+
if (active.length === 0) return null;
|
|
16075
|
+
const lines = active.map((a) => {
|
|
16076
|
+
const { label } = describeCategory(a.category);
|
|
16077
|
+
const target = formatAlertTarget(a);
|
|
16078
|
+
const providerBits = formatProviderBits(a);
|
|
16079
|
+
return `- [${a.severity}] ${a.category} (${label}) \xB7 ${target}${providerBits ? ` \xB7 ${providerBits}` : ""} \xB7 seen ${a.count}\xD7`;
|
|
16080
|
+
});
|
|
16081
|
+
return `Active hub alerts at report time (${active.length}):
|
|
16082
|
+
${lines.join("\n")}`;
|
|
16083
|
+
}
|
|
16084
|
+
var init_hub_alerts = __esm({
|
|
16085
|
+
"src/lib/hub-alerts.ts"() {
|
|
16086
|
+
"use strict";
|
|
16087
|
+
}
|
|
16088
|
+
});
|
|
16089
|
+
|
|
16090
|
+
// src/commands/alerts.ts
|
|
16091
|
+
var alerts_exports = {};
|
|
16092
|
+
__export(alerts_exports, {
|
|
16093
|
+
alertsCommand: () => alertsCommand
|
|
16094
|
+
});
|
|
16095
|
+
function printAlertsHelp() {
|
|
16096
|
+
console.error(`
|
|
16097
|
+
wayai alerts \u2014 show a hub's active operational alerts (Status & Notices)
|
|
16098
|
+
|
|
16099
|
+
Usage:
|
|
16100
|
+
wayai alerts Active alerts for the active hub
|
|
16101
|
+
wayai alerts --hub <uuid|name> For a specific hub (accepts a raw uuid without a workspace)
|
|
16102
|
+
wayai alerts --json Raw JSON output
|
|
16103
|
+
|
|
16104
|
+
Alerts are tenant-actionable connection/credential health signals raised at
|
|
16105
|
+
runtime \u2014 e.g. a provider rejecting a bad/expired key (\`connection_auth\`),
|
|
16106
|
+
a rate/quota limit (\`connection_quota\`), an expired channel token
|
|
16107
|
+
(\`channel_token\`), or a missing production credential. Run this FIRST when a
|
|
16108
|
+
hub misbehaves (audio/TTS not delivered, agent not replying, a tool failing)
|
|
16109
|
+
before reading code or filing a report.
|
|
16110
|
+
`.trim());
|
|
16111
|
+
}
|
|
16112
|
+
function fmtTime(iso) {
|
|
16113
|
+
const d = new Date(iso);
|
|
16114
|
+
return Number.isNaN(d.getTime()) ? iso : d.toLocaleString();
|
|
16115
|
+
}
|
|
16116
|
+
async function alertsCommand(args2) {
|
|
16117
|
+
if (wantsHelp(args2)) {
|
|
16118
|
+
printAlertsHelp();
|
|
16119
|
+
return;
|
|
16120
|
+
}
|
|
16121
|
+
const jsonIdx = args2.indexOf("--json");
|
|
16122
|
+
const jsonOutput = jsonIdx !== -1;
|
|
16123
|
+
if (jsonOutput) args2.splice(jsonIdx, 1);
|
|
16124
|
+
const hubId = resolveActiveHubId(args2);
|
|
16125
|
+
const { config, accessToken } = await requireAuth();
|
|
16126
|
+
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
16127
|
+
let alerts;
|
|
16128
|
+
try {
|
|
16129
|
+
({ alerts } = await client.getHubAlerts(hubId));
|
|
16130
|
+
} catch (err) {
|
|
16131
|
+
if (err instanceof ApiError && err.status === 404) {
|
|
16132
|
+
console.error(`Hub ${hubId} not found, or you lack read access to it.`);
|
|
16133
|
+
process.exit(1);
|
|
16134
|
+
}
|
|
16135
|
+
if (err instanceof ApiError && err.status === 403) {
|
|
16136
|
+
console.error(`You don't have read access to hub ${hubId}.`);
|
|
16137
|
+
process.exit(1);
|
|
16138
|
+
}
|
|
16139
|
+
throw err;
|
|
16140
|
+
}
|
|
16141
|
+
const active = activeAlerts(alerts);
|
|
16142
|
+
if (jsonOutput) {
|
|
16143
|
+
console.log(JSON.stringify({ hub_id: hubId, alerts: active }, null, 2));
|
|
16144
|
+
return;
|
|
16145
|
+
}
|
|
16146
|
+
if (active.length === 0) {
|
|
16147
|
+
console.log(`Hub ${hubId} \u2014 no active alerts \u2713`);
|
|
16148
|
+
return;
|
|
16149
|
+
}
|
|
16150
|
+
const connLabels = /* @__PURE__ */ new Map();
|
|
16151
|
+
try {
|
|
16152
|
+
const { connections } = await client.listConnections(hubId);
|
|
16153
|
+
for (const conn of connections) {
|
|
16154
|
+
if (!conn.connection_id) continue;
|
|
16155
|
+
const name = conn.connection_display_name || conn.connector_name;
|
|
16156
|
+
connLabels.set(conn.connection_id, `${name} (${conn.connector_type})`);
|
|
16157
|
+
}
|
|
16158
|
+
} catch {
|
|
16159
|
+
}
|
|
16160
|
+
const noun = active.length === 1 ? "alert" : "alerts";
|
|
16161
|
+
console.log(`Hub ${hubId} \u2014 ${active.length} active ${noun}
|
|
16162
|
+
`);
|
|
16163
|
+
for (const a of active) {
|
|
16164
|
+
const { label, hint } = describeCategory(a.category);
|
|
16165
|
+
const target = formatAlertTarget(a, (id) => connLabels.get(id));
|
|
16166
|
+
const providerBits = formatProviderBits(a);
|
|
16167
|
+
console.log(`${severityGlyph(a.severity)} ${a.severity} ${a.category} \u2014 ${label}`);
|
|
16168
|
+
console.log(` ${target}${providerBits ? ` \xB7 ${providerBits}` : ""}`);
|
|
16169
|
+
console.log(` ${hint}`);
|
|
16170
|
+
if (a.org_credential_id) {
|
|
16171
|
+
console.log(` Shared org credential \u2014 fix it once at the org credential (\`wayai update-credential\`); it fans out to every hub linking it.`);
|
|
16172
|
+
}
|
|
16173
|
+
console.log(` seen ${a.count}\xD7 \xB7 first ${fmtTime(a.first_seen_at)} \xB7 last ${fmtTime(a.last_seen_at)}`);
|
|
16174
|
+
console.log("");
|
|
16175
|
+
}
|
|
16176
|
+
}
|
|
16177
|
+
var init_alerts = __esm({
|
|
16178
|
+
"src/commands/alerts.ts"() {
|
|
16179
|
+
"use strict";
|
|
16180
|
+
init_auth();
|
|
16181
|
+
init_workspace();
|
|
16182
|
+
init_api_client();
|
|
16183
|
+
init_utils();
|
|
16184
|
+
init_hub_alerts();
|
|
16185
|
+
}
|
|
16186
|
+
});
|
|
16187
|
+
|
|
16001
16188
|
// src/commands/delete-history.ts
|
|
16002
16189
|
var delete_history_exports = {};
|
|
16003
16190
|
__export(delete_history_exports, {
|
|
@@ -20445,6 +20632,19 @@ async function reportCreateCommand(args2, cliVersion = null) {
|
|
|
20445
20632
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
20446
20633
|
const repoConfig = readRepoConfig();
|
|
20447
20634
|
const organizationId = repoConfig?.organization_id;
|
|
20635
|
+
let contextWithAlerts = context;
|
|
20636
|
+
if (hubId) {
|
|
20637
|
+
try {
|
|
20638
|
+
const { alerts } = await client.getHubAlerts(hubId);
|
|
20639
|
+
const alertSummary = summarizeActiveAlertsForReport(alerts);
|
|
20640
|
+
if (alertSummary) {
|
|
20641
|
+
contextWithAlerts = context ? `${context}
|
|
20642
|
+
|
|
20643
|
+
${alertSummary}` : alertSummary;
|
|
20644
|
+
}
|
|
20645
|
+
} catch {
|
|
20646
|
+
}
|
|
20647
|
+
}
|
|
20448
20648
|
try {
|
|
20449
20649
|
const result = await client.submitReport({
|
|
20450
20650
|
title,
|
|
@@ -20457,7 +20657,7 @@ async function reportCreateCommand(args2, cliVersion = null) {
|
|
|
20457
20657
|
conversation_id: conversationId,
|
|
20458
20658
|
error_message: errorMessage,
|
|
20459
20659
|
steps_to_reproduce: steps,
|
|
20460
|
-
additional_context:
|
|
20660
|
+
additional_context: contextWithAlerts,
|
|
20461
20661
|
client_version: clientVersion
|
|
20462
20662
|
});
|
|
20463
20663
|
if (result.created) {
|
|
@@ -20488,6 +20688,7 @@ var init_report_create = __esm({
|
|
|
20488
20688
|
init_auth();
|
|
20489
20689
|
init_repo_config();
|
|
20490
20690
|
init_api_client();
|
|
20691
|
+
init_hub_alerts();
|
|
20491
20692
|
init_version_status();
|
|
20492
20693
|
}
|
|
20493
20694
|
});
|
|
@@ -21054,6 +21255,11 @@ async function main() {
|
|
|
21054
21255
|
await conversationsCommand2(args);
|
|
21055
21256
|
break;
|
|
21056
21257
|
}
|
|
21258
|
+
case "alerts": {
|
|
21259
|
+
const { alertsCommand: alertsCommand2 } = await Promise.resolve().then(() => (init_alerts(), alerts_exports));
|
|
21260
|
+
await alertsCommand2(args);
|
|
21261
|
+
break;
|
|
21262
|
+
}
|
|
21057
21263
|
case "delete-history": {
|
|
21058
21264
|
const { deleteHistoryCommand: deleteHistoryCommand2 } = await Promise.resolve().then(() => (init_delete_history(), delete_history_exports));
|
|
21059
21265
|
await deleteHistoryCommand2(args);
|
|
@@ -21187,6 +21393,7 @@ Commands:
|
|
|
21187
21393
|
unbind Clear the worktree hub binding
|
|
21188
21394
|
send-message Send a test message to a hub (preview or production)
|
|
21189
21395
|
conversations List or inspect conversations
|
|
21396
|
+
alerts Show a hub's active connection/credential alerts (run this FIRST when a hub misbehaves)
|
|
21190
21397
|
analytics Show analytics summary and metrics (use \`analytics query\` for structured ClickHouse queries)
|
|
21191
21398
|
delete-history Delete your conversations on a hub (--conversation-id <id> for just one)
|
|
21192
21399
|
evals List evaluation scenarios for the current hub (use \`evals sql\` for read-only SQL on eval results)
|