aui-agent-builder 0.3.68 → 0.3.69
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/README.md +40 -1
- package/dist/api-client/index.d.ts +36 -0
- package/dist/api-client/index.d.ts.map +1 -1
- package/dist/api-client/index.js +90 -0
- package/dist/api-client/index.js.map +1 -1
- package/dist/commands/agents.d.ts +13 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +784 -1
- package/dist/commands/agents.js.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/ui/views/AgentsView.d.ts +19 -0
- package/dist/ui/views/AgentsView.d.ts.map +1 -1
- package/dist/ui/views/AgentsView.js +38 -0
- package/dist/ui/views/AgentsView.js.map +1 -1
- package/dist/web/assets/{index-DSg2xrPw.js → index-C_ca_RjQ.js} +2 -2
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
package/dist/commands/agents.js
CHANGED
|
@@ -3,7 +3,7 @@ import { render, Box, Text } from "ink";
|
|
|
3
3
|
import inquirer from "inquirer";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import { getAuthenticatedSession, listAgents as listAgentsSvc, listVersions as listVersionsSvc, switchToAgent, } from "../services/agents.service.js";
|
|
6
|
-
import { AgentsMenuView, AgentsListView, AgentSwitchView, VersionsListView, } from "../ui/views/AgentsView.js";
|
|
6
|
+
import { AgentsMenuView, AgentsListView, AgentSwitchView, VersionsListView, AgentDeletePreviewView, AgentDeleteResultView, } from "../ui/views/AgentsView.js";
|
|
7
7
|
import { Spinner, ErrorDisplay, StatusLine } from "../ui/components/index.js";
|
|
8
8
|
import { AUIClient } from "../api-client/index.js";
|
|
9
9
|
import { isJsonMode, outputJson, stderrLog } from "../utils/json-output.js";
|
|
@@ -12,6 +12,73 @@ function renderView(element) {
|
|
|
12
12
|
const instance = render(element);
|
|
13
13
|
instance.unmount();
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Best-effort follow-up DELETE on the legacy network record after the
|
|
17
|
+
* agent-settings DELETE succeeds.
|
|
18
|
+
*
|
|
19
|
+
* Agent creation is a 3-step process (network → settings → agent-management).
|
|
20
|
+
* The agent-settings DELETE is the primary record removal; this safety-net
|
|
21
|
+
* also removes the network shell so the agent disappears from the legacy
|
|
22
|
+
* `networks.list` immediately. If it fails (e.g. already cascaded) we
|
|
23
|
+
* surface a warning but never let it fail the overall operation.
|
|
24
|
+
*/
|
|
25
|
+
async function deleteNetworkBestEffort(client, networkId) {
|
|
26
|
+
try {
|
|
27
|
+
const resp = await client.networks.delete(networkId);
|
|
28
|
+
if (resp && resp.status === false) {
|
|
29
|
+
return {
|
|
30
|
+
deleted: false,
|
|
31
|
+
errorMessage: resp.message || "backend returned status=false",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return { deleted: true };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return { deleted: false, errorMessage: formatApiErrorBody(err) };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build a human-readable summary from an API error.
|
|
42
|
+
*
|
|
43
|
+
* Surfaces FastAPI-style validation errors so the user sees
|
|
44
|
+
* "Field required: query.deleted_by" instead of the generic
|
|
45
|
+
* "API request failed (422 Unprocessable Entity)".
|
|
46
|
+
*/
|
|
47
|
+
function formatApiErrorBody(error) {
|
|
48
|
+
if (!error || typeof error !== "object")
|
|
49
|
+
return String(error);
|
|
50
|
+
const e = error;
|
|
51
|
+
const status = e.status;
|
|
52
|
+
const body = e.body;
|
|
53
|
+
if (body && typeof body === "object") {
|
|
54
|
+
const detail = body.detail;
|
|
55
|
+
if (Array.isArray(detail) && detail.length > 0) {
|
|
56
|
+
const items = detail.slice(0, 3).map((d) => {
|
|
57
|
+
if (!d || typeof d !== "object")
|
|
58
|
+
return String(d);
|
|
59
|
+
const dd = d;
|
|
60
|
+
const where = Array.isArray(dd.loc) ? dd.loc.filter(Boolean).join(".") : "";
|
|
61
|
+
const msg = dd.msg ?? dd.type ?? "invalid";
|
|
62
|
+
return where ? `${msg} (${where})` : String(msg);
|
|
63
|
+
});
|
|
64
|
+
const more = detail.length > items.length ? ` (+${detail.length - items.length} more)` : "";
|
|
65
|
+
return `${status ?? "?"} — ${items.join("; ")}${more}`;
|
|
66
|
+
}
|
|
67
|
+
if (typeof detail === "string")
|
|
68
|
+
return `${status ?? "?"} — ${detail}`;
|
|
69
|
+
const msg = body.msg ??
|
|
70
|
+
body.message ??
|
|
71
|
+
body.error;
|
|
72
|
+
if (typeof msg === "string")
|
|
73
|
+
return `${status ?? "?"} — ${msg}`;
|
|
74
|
+
}
|
|
75
|
+
if (typeof body === "string" && body.length > 0) {
|
|
76
|
+
return `${status ?? "?"} — ${body.slice(0, 300)}`;
|
|
77
|
+
}
|
|
78
|
+
if (e.message)
|
|
79
|
+
return e.message;
|
|
80
|
+
return String(error);
|
|
81
|
+
}
|
|
15
82
|
export async function agents(options = {}) {
|
|
16
83
|
const session = await getAuthenticatedSession();
|
|
17
84
|
if (options.list) {
|
|
@@ -35,6 +102,10 @@ export async function agents(options = {}) {
|
|
|
35
102
|
await handleCreateAgent(options);
|
|
36
103
|
return;
|
|
37
104
|
}
|
|
105
|
+
if (options.delete) {
|
|
106
|
+
await handleDeleteAgent(options);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
38
109
|
if (options.import) {
|
|
39
110
|
const { importAgent } = await import("./import-agent.js");
|
|
40
111
|
await importAgent();
|
|
@@ -61,6 +132,11 @@ export async function agents(options = {}) {
|
|
|
61
132
|
{ name: "Import from another account", value: "import-other-account" },
|
|
62
133
|
{ name: "Import from another organization", value: "import-other-org" },
|
|
63
134
|
new inquirer.Separator(),
|
|
135
|
+
{
|
|
136
|
+
name: chalk.red("Delete agent or version") + chalk.gray(" (irreversible)"),
|
|
137
|
+
value: "delete",
|
|
138
|
+
},
|
|
139
|
+
new inquirer.Separator(),
|
|
64
140
|
{ name: "Back", value: "back" },
|
|
65
141
|
],
|
|
66
142
|
},
|
|
@@ -79,6 +155,9 @@ export async function agents(options = {}) {
|
|
|
79
155
|
else if (action === "create") {
|
|
80
156
|
await handleCreateAgent({});
|
|
81
157
|
}
|
|
158
|
+
else if (action === "delete") {
|
|
159
|
+
await handleDeleteAgent({});
|
|
160
|
+
}
|
|
82
161
|
else if (action === "import") {
|
|
83
162
|
const { importAgent } = await import("./import-agent.js");
|
|
84
163
|
await importAgent();
|
|
@@ -289,6 +368,710 @@ export async function agents(options = {}) {
|
|
|
289
368
|
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to switch agent." }));
|
|
290
369
|
}
|
|
291
370
|
}
|
|
371
|
+
async function handleDeleteAgent(opts = {}) {
|
|
372
|
+
const config = getConfig();
|
|
373
|
+
const client = new AUIClient({
|
|
374
|
+
baseUrl: config.apiUrl,
|
|
375
|
+
authToken: config.authToken,
|
|
376
|
+
accountId: config.accountId,
|
|
377
|
+
organizationId: config.organizationId,
|
|
378
|
+
environment: config.environment,
|
|
379
|
+
});
|
|
380
|
+
const apiKey = loadAgentSettingsApiKey();
|
|
381
|
+
if (apiKey)
|
|
382
|
+
client.setAgentSettingsApiKey(apiKey);
|
|
383
|
+
// ─── Non-interactive: --network-id given → delete entire agent ───
|
|
384
|
+
// (also covers --network-id + --all-versions explicitly)
|
|
385
|
+
if (opts.networkId && !opts.version) {
|
|
386
|
+
await runDeleteEntireAgent(client, {
|
|
387
|
+
networkId: opts.networkId,
|
|
388
|
+
skipConfirm: !!opts.yes,
|
|
389
|
+
});
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
// ─── Non-interactive: --version given → delete specific version ───
|
|
393
|
+
if (opts.version) {
|
|
394
|
+
const agentMgmtId = opts.agentId || opts.use;
|
|
395
|
+
await runDeleteVersion(client, {
|
|
396
|
+
agentManagementId: agentMgmtId,
|
|
397
|
+
networkId: opts.networkId,
|
|
398
|
+
versionId: opts.version,
|
|
399
|
+
skipConfirm: !!opts.yes,
|
|
400
|
+
});
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
// ─── Non-interactive: --agent-id + --all-versions → loop per-version DELETEs ───
|
|
404
|
+
// (kept distinct from --network-id which does a single full-agent DELETE)
|
|
405
|
+
if (opts.agentId && opts.allVersions) {
|
|
406
|
+
const agent = await client.agentManagement.getAgent(opts.agentId).catch(() => null);
|
|
407
|
+
if (!agent) {
|
|
408
|
+
renderView(_jsx(ErrorDisplay, { message: `Agent not found: ${opts.agentId}`, suggestion: "Run `aui agent --list` to see available agents." }));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
await runDeleteAllVersions(client, {
|
|
412
|
+
agentManagementId: agent.id,
|
|
413
|
+
networkId: agent.scope.network_id || undefined,
|
|
414
|
+
agentName: agent.name,
|
|
415
|
+
activeVersionId: agent.active_version_id,
|
|
416
|
+
skipConfirm: !!opts.yes,
|
|
417
|
+
});
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
// ─── Interactive flow: org → account → agent → scope ───
|
|
421
|
+
logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "red", bold: true, children: "⚠ " }), _jsx(Text, { bold: true, children: "Delete an agent or a specific version" })] }), _jsx(Box, { children: _jsx(Text, { color: "gray", children: " This is permanent and cannot be undone." }) })] }));
|
|
422
|
+
// Step 1: Select organization
|
|
423
|
+
logView(_jsx(Text, { color: "gray", children: " \u250C Step 1 \u2192 Select Organization" }));
|
|
424
|
+
const org = await pickOrganization(client);
|
|
425
|
+
if (!org)
|
|
426
|
+
return;
|
|
427
|
+
client.setScope({ organizationId: org.id });
|
|
428
|
+
logView(_jsx(StatusLine, { kind: "success", label: `Organization: ${org.name}` }));
|
|
429
|
+
// Step 2: Select account
|
|
430
|
+
logView(_jsx(Text, { color: "gray", children: " \u251C Step 2 \u2192 Select Account" }));
|
|
431
|
+
const account = await pickAccount(client);
|
|
432
|
+
if (!account)
|
|
433
|
+
return;
|
|
434
|
+
client.setScope({ accountId: account.id });
|
|
435
|
+
logView(_jsx(StatusLine, { kind: "success", label: `Account: ${account.name}` }));
|
|
436
|
+
// Step 3: Select agent
|
|
437
|
+
logView(_jsx(Text, { color: "gray", children: " \u251C Step 3 \u2192 Select Agent" }));
|
|
438
|
+
const picked = await pickAgentInAccount(client);
|
|
439
|
+
if (!picked)
|
|
440
|
+
return;
|
|
441
|
+
const { network } = picked;
|
|
442
|
+
const networkId = network._id || network.id;
|
|
443
|
+
const agentName = network.name;
|
|
444
|
+
logView(_jsx(StatusLine, { kind: "success", label: `Agent: ${agentName}` }));
|
|
445
|
+
// Step 4: Choose what to delete
|
|
446
|
+
logView(_jsx(Text, { color: "gray", children: " \u2514 Step 4 \u2192 Choose what to delete" }));
|
|
447
|
+
const { scope } = await inquirer.prompt([
|
|
448
|
+
{
|
|
449
|
+
type: "list",
|
|
450
|
+
name: "scope",
|
|
451
|
+
message: "What do you want to delete?",
|
|
452
|
+
choices: [
|
|
453
|
+
{
|
|
454
|
+
name: `${chalk.red("Delete entire agent")} ${chalk.gray("(single API call — removes ALL versions)")}`,
|
|
455
|
+
value: "agent",
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
name: `${chalk.yellow("Delete a specific version")} ${chalk.gray("(keeps the agent)")}`,
|
|
459
|
+
value: "version",
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
name: `${chalk.magenta("Delete all versions")} ${chalk.gray("(loops per-version DELETE — keeps the agent shell)")}`,
|
|
463
|
+
value: "all-versions",
|
|
464
|
+
},
|
|
465
|
+
new inquirer.Separator(),
|
|
466
|
+
{ name: "Cancel", value: "cancel" },
|
|
467
|
+
],
|
|
468
|
+
},
|
|
469
|
+
]);
|
|
470
|
+
if (scope === "cancel") {
|
|
471
|
+
logView(_jsx(StatusLine, { kind: "muted", label: "Cancelled." }));
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (scope === "agent") {
|
|
475
|
+
// Entire-agent delete only needs the network_id; the cascade + the
|
|
476
|
+
// safety-net network DELETE handle everything else. Skip the lookup.
|
|
477
|
+
await runDeleteEntireAgent(client, {
|
|
478
|
+
networkId,
|
|
479
|
+
agentName,
|
|
480
|
+
skipConfirm: false,
|
|
481
|
+
});
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
// For version-related scopes we need the agent-management ID (and the
|
|
485
|
+
// active_version_id). Resolve it once via a targeted lookup by network_id.
|
|
486
|
+
const lookupSpinner = render(_jsx(Spinner, { label: "Resolving agent record..." }));
|
|
487
|
+
let agentManagementId;
|
|
488
|
+
let activeVersionId = null;
|
|
489
|
+
try {
|
|
490
|
+
const resp = await client.agentManagement.listAgents(client.getOrganizationId(), 1, 50, { network_id: networkId });
|
|
491
|
+
const match = resp.items.find((a) => a.scope.network_id === networkId || a.id === networkId);
|
|
492
|
+
if (match) {
|
|
493
|
+
agentManagementId = match.id;
|
|
494
|
+
activeVersionId = match.active_version_id;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
// best-effort; handled below
|
|
499
|
+
}
|
|
500
|
+
finally {
|
|
501
|
+
lookupSpinner.unmount();
|
|
502
|
+
}
|
|
503
|
+
if (!agentManagementId) {
|
|
504
|
+
renderView(_jsx(ErrorDisplay, { message: "This agent has no agent-management record, so per-version operations aren't available.", suggestion: "Use 'Delete entire agent' instead, or pass --agent-id explicitly." }));
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (scope === "all-versions") {
|
|
508
|
+
await runDeleteAllVersions(client, {
|
|
509
|
+
agentManagementId,
|
|
510
|
+
networkId,
|
|
511
|
+
agentName,
|
|
512
|
+
activeVersionId,
|
|
513
|
+
skipConfirm: false,
|
|
514
|
+
});
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
// scope === "version"
|
|
518
|
+
const versionsSpinner = render(_jsx(Spinner, { label: `Fetching versions for "${agentName}"...` }));
|
|
519
|
+
try {
|
|
520
|
+
const versions = await fetchAllVersionsForAgent(client, agentManagementId);
|
|
521
|
+
versionsSpinner.unmount();
|
|
522
|
+
if (versions.length === 0) {
|
|
523
|
+
renderView(_jsx(ErrorDisplay, { message: "No versions found for this agent.", suggestion: "Nothing to delete. Use the entire-agent option instead." }));
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const { selectedVersion } = await inquirer.prompt([
|
|
527
|
+
{
|
|
528
|
+
type: "list",
|
|
529
|
+
name: "selectedVersion",
|
|
530
|
+
message: "Select version to delete:",
|
|
531
|
+
choices: versions.map((v) => {
|
|
532
|
+
const isActive = v.id === activeVersionId;
|
|
533
|
+
const vLabel = `v${v.version_number}.${v.version_revision_number}`;
|
|
534
|
+
const statusBadge = v.status === "published"
|
|
535
|
+
? chalk.green(v.status)
|
|
536
|
+
: v.status === "archived"
|
|
537
|
+
? chalk.gray(v.status)
|
|
538
|
+
: chalk.yellow(v.status);
|
|
539
|
+
const activeBadge = isActive ? chalk.green(" ← live") : "";
|
|
540
|
+
return {
|
|
541
|
+
name: `${vLabel} [${statusBadge}]${activeBadge}`,
|
|
542
|
+
value: v,
|
|
543
|
+
};
|
|
544
|
+
}),
|
|
545
|
+
pageSize: 15,
|
|
546
|
+
},
|
|
547
|
+
]);
|
|
548
|
+
await runDeleteVersion(client, {
|
|
549
|
+
agentManagementId,
|
|
550
|
+
networkId,
|
|
551
|
+
versionId: selectedVersion.id,
|
|
552
|
+
agentName,
|
|
553
|
+
versionLabel: `v${selectedVersion.version_number}.${selectedVersion.version_revision_number}`,
|
|
554
|
+
versionStatus: selectedVersion.status,
|
|
555
|
+
isActiveVersion: selectedVersion.id === activeVersionId,
|
|
556
|
+
skipConfirm: false,
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
catch (error) {
|
|
560
|
+
versionsSpinner.unmount();
|
|
561
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to fetch versions." }));
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
async function pickOrganization(client) {
|
|
565
|
+
const spinner = render(_jsx(Spinner, { label: "Fetching organizations..." }));
|
|
566
|
+
try {
|
|
567
|
+
// Fetch page 1 to learn totalPages, then fetch the rest in parallel.
|
|
568
|
+
const first = await client.organizations.listMy(1, 50);
|
|
569
|
+
const allOrgs = [...first.data.docs];
|
|
570
|
+
const totalPages = first.data.totalPages ?? 1;
|
|
571
|
+
if (totalPages > 1) {
|
|
572
|
+
const restPages = Array.from({ length: totalPages - 1 }, (_, i) => i + 2);
|
|
573
|
+
const rest = await Promise.all(restPages.map((p) => client.organizations.listMy(p, 50)));
|
|
574
|
+
for (const r of rest)
|
|
575
|
+
allOrgs.push(...r.data.docs);
|
|
576
|
+
}
|
|
577
|
+
spinner.unmount();
|
|
578
|
+
if (allOrgs.length === 0) {
|
|
579
|
+
const fallbackId = session.organization_id || client.getOrganizationId();
|
|
580
|
+
if (!fallbackId) {
|
|
581
|
+
renderView(_jsx(ErrorDisplay, { message: "No organizations available.", suggestion: "Run `aui login` to refresh your session." }));
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
return { id: fallbackId, name: session.organization_name || fallbackId };
|
|
585
|
+
}
|
|
586
|
+
if (allOrgs.length === 1) {
|
|
587
|
+
const o = allOrgs[0];
|
|
588
|
+
return { id: o._id || o.id, name: o.name };
|
|
589
|
+
}
|
|
590
|
+
const currentOrgId = session.organization_id;
|
|
591
|
+
const { chosen } = await inquirer.prompt([
|
|
592
|
+
{
|
|
593
|
+
type: "list",
|
|
594
|
+
name: "chosen",
|
|
595
|
+
message: "Select organization:",
|
|
596
|
+
choices: allOrgs.map((o) => {
|
|
597
|
+
const isCurrent = o._id === currentOrgId || o.id === currentOrgId;
|
|
598
|
+
const meta = chalk.gray(`(${o.niceName || o._id})`);
|
|
599
|
+
const label = isCurrent
|
|
600
|
+
? `${o.name} ${meta} ${chalk.green("← current")}`
|
|
601
|
+
: `${o.name} ${meta}`;
|
|
602
|
+
return { name: label, value: o };
|
|
603
|
+
}),
|
|
604
|
+
pageSize: 15,
|
|
605
|
+
},
|
|
606
|
+
]);
|
|
607
|
+
const o = chosen;
|
|
608
|
+
return { id: o._id || o.id, name: o.name };
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
spinner.unmount();
|
|
612
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to fetch organizations." }));
|
|
613
|
+
return null;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
async function pickAccount(client) {
|
|
617
|
+
const spinner = render(_jsx(Spinner, { label: "Fetching accounts..." }));
|
|
618
|
+
try {
|
|
619
|
+
// Fetch page 1 to learn totalPages, then fetch the rest in parallel.
|
|
620
|
+
const first = await client.accounts.list(1, 50);
|
|
621
|
+
const allAccounts = [...first.data.docs];
|
|
622
|
+
const totalPages = first.data.totalPages ?? 1;
|
|
623
|
+
if (totalPages > 1) {
|
|
624
|
+
const restPages = Array.from({ length: totalPages - 1 }, (_, i) => i + 2);
|
|
625
|
+
const rest = await Promise.all(restPages.map((p) => client.accounts.list(p, 50)));
|
|
626
|
+
for (const r of rest)
|
|
627
|
+
allAccounts.push(...r.data.docs);
|
|
628
|
+
}
|
|
629
|
+
spinner.unmount();
|
|
630
|
+
if (allAccounts.length === 0) {
|
|
631
|
+
renderView(_jsx(ErrorDisplay, { message: "No accounts found in this organization.", suggestion: "Nothing to delete here." }));
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
if (allAccounts.length === 1) {
|
|
635
|
+
const a = allAccounts[0];
|
|
636
|
+
return { id: a._id || a.id, name: a.name };
|
|
637
|
+
}
|
|
638
|
+
const currentAccountId = session.account_id;
|
|
639
|
+
const { chosen } = await inquirer.prompt([
|
|
640
|
+
{
|
|
641
|
+
type: "list",
|
|
642
|
+
name: "chosen",
|
|
643
|
+
message: "Select account:",
|
|
644
|
+
choices: allAccounts.map((a) => {
|
|
645
|
+
const isCurrent = a._id === currentAccountId || a.id === currentAccountId;
|
|
646
|
+
const meta = chalk.gray(`(${a.niceName})`);
|
|
647
|
+
const label = isCurrent
|
|
648
|
+
? `${a.name} ${meta} ${chalk.green("← current")}`
|
|
649
|
+
: `${a.name} ${meta}`;
|
|
650
|
+
return { name: label, value: a };
|
|
651
|
+
}),
|
|
652
|
+
pageSize: 15,
|
|
653
|
+
},
|
|
654
|
+
]);
|
|
655
|
+
const a = chosen;
|
|
656
|
+
return { id: a._id || a.id, name: a.name };
|
|
657
|
+
}
|
|
658
|
+
catch (error) {
|
|
659
|
+
spinner.unmount();
|
|
660
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to fetch accounts." }));
|
|
661
|
+
return null;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
async function pickAgentInAccount(client) {
|
|
665
|
+
const spinner = render(_jsx(Spinner, { label: "Fetching agents..." }));
|
|
666
|
+
try {
|
|
667
|
+
// Use the legacy networks endpoint — it's already filtered server-side
|
|
668
|
+
// by org+account, which is what we want for an account-scoped picker.
|
|
669
|
+
// The agent-management lookup is deferred to AFTER selection (single
|
|
670
|
+
// targeted call by network_id) and only when the chosen scope needs it.
|
|
671
|
+
const netResp = await client.networks.list();
|
|
672
|
+
const networks = netResp.data;
|
|
673
|
+
spinner.unmount();
|
|
674
|
+
if (networks.length === 0) {
|
|
675
|
+
renderView(_jsx(ErrorDisplay, { message: "No agents found in this account.", suggestion: "Nothing to delete here." }));
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
const currentNetworkId = session.network_id;
|
|
679
|
+
const { chosen } = await inquirer.prompt([
|
|
680
|
+
{
|
|
681
|
+
type: "list",
|
|
682
|
+
name: "chosen",
|
|
683
|
+
message: "Select agent to delete from:",
|
|
684
|
+
choices: networks.map((n) => {
|
|
685
|
+
const id = n._id || n.id;
|
|
686
|
+
const isCurrent = id === currentNetworkId;
|
|
687
|
+
const label = isCurrent
|
|
688
|
+
? `${n.name} ${chalk.green("← current")}`
|
|
689
|
+
: n.name;
|
|
690
|
+
return { name: label, value: { network: n } };
|
|
691
|
+
}),
|
|
692
|
+
pageSize: 15,
|
|
693
|
+
},
|
|
694
|
+
]);
|
|
695
|
+
return chosen;
|
|
696
|
+
}
|
|
697
|
+
catch (error) {
|
|
698
|
+
spinner.unmount();
|
|
699
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to fetch agents." }));
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
async function fetchAllVersionsForAgent(client, agentManagementId) {
|
|
704
|
+
const all = [];
|
|
705
|
+
let page = 1;
|
|
706
|
+
let hasMore = true;
|
|
707
|
+
while (hasMore) {
|
|
708
|
+
const resp = await client.agentManagement.listVersions(agentManagementId, page, 50);
|
|
709
|
+
all.push(...resp.items);
|
|
710
|
+
hasMore = page < resp.pages;
|
|
711
|
+
page++;
|
|
712
|
+
}
|
|
713
|
+
return all;
|
|
714
|
+
}
|
|
715
|
+
async function runDeleteAllVersions(client, args) {
|
|
716
|
+
const { agentManagementId, networkId, agentName, activeVersionId } = args;
|
|
717
|
+
const fetchSpinner = render(_jsx(Spinner, { label: "Fetching versions..." }));
|
|
718
|
+
let versions;
|
|
719
|
+
try {
|
|
720
|
+
versions = await fetchAllVersionsForAgent(client, agentManagementId);
|
|
721
|
+
fetchSpinner.unmount();
|
|
722
|
+
}
|
|
723
|
+
catch (error) {
|
|
724
|
+
fetchSpinner.unmount();
|
|
725
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: "Failed to fetch versions." }));
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
if (versions.length === 0) {
|
|
729
|
+
renderView(_jsx(Box, { flexDirection: "column", paddingX: 1, children: _jsx(StatusLine, { kind: "muted", label: "No versions to delete." }) }));
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const activeCount = versions.filter((v) => v.id === activeVersionId).length;
|
|
733
|
+
const deletableCount = versions.length - activeCount;
|
|
734
|
+
if (isJsonMode()) {
|
|
735
|
+
if (!args.skipConfirm) {
|
|
736
|
+
outputJson({
|
|
737
|
+
requires_confirmation: true,
|
|
738
|
+
message: "Refusing to delete in JSON mode without --yes. Re-run with --yes to confirm.",
|
|
739
|
+
agent: { name: agentName, agent_management_id: agentManagementId, network_id: networkId },
|
|
740
|
+
versions_total: versions.length,
|
|
741
|
+
versions_deletable: deletableCount,
|
|
742
|
+
versions_active_blocked: activeCount,
|
|
743
|
+
});
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
stderrLog(`Deleting ${versions.length} version(s) of "${agentName}" one-by-one...`);
|
|
747
|
+
const results = await loopDeleteVersions(client, agentManagementId, versions, activeVersionId);
|
|
748
|
+
const cleared = clearSessionIfMatchesAgentVersionsAfterAll(versions, results);
|
|
749
|
+
outputJson({
|
|
750
|
+
scope: "all-versions",
|
|
751
|
+
agent: { name: agentName, agent_management_id: agentManagementId, network_id: networkId },
|
|
752
|
+
attempted: versions.length,
|
|
753
|
+
deleted: results.filter((r) => r.success).length,
|
|
754
|
+
failed: results.filter((r) => !r.success).map((r) => ({
|
|
755
|
+
version_id: r.version.id,
|
|
756
|
+
version: `v${r.version.version_number}.${r.version.version_revision_number}`,
|
|
757
|
+
error: r.errorMessage,
|
|
758
|
+
})),
|
|
759
|
+
session_cleared: cleared,
|
|
760
|
+
});
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "red", bold: true, children: "⚠ " }), _jsxs(Text, { bold: true, children: ["You are about to delete every version of \"", agentName, "\""] })] }), _jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ", versions.length, " version(s) total \u00B7 ", deletableCount, " deletable", activeCount > 0 ? ` · ${activeCount} active (will be blocked by backend)` : ""] }) }), _jsx(Box, { children: _jsxs(Text, { color: "gray", children: [" ", "This keeps the agent shell. Use 'Delete entire agent' for a full wipe."] }) })] }));
|
|
764
|
+
if (!args.skipConfirm) {
|
|
765
|
+
const { typed } = await inquirer.prompt([
|
|
766
|
+
{
|
|
767
|
+
type: "input",
|
|
768
|
+
name: "typed",
|
|
769
|
+
message: `Type the agent name (${agentName}) to confirm:`,
|
|
770
|
+
validate: (v) => v.trim() === agentName ? true : `Type exactly: ${agentName}`,
|
|
771
|
+
},
|
|
772
|
+
]);
|
|
773
|
+
if (typed.trim() !== agentName) {
|
|
774
|
+
logView(_jsx(StatusLine, { kind: "muted", label: "Cancelled." }));
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const loopSpinner = render(_jsx(Spinner, { label: `Deleting ${versions.length} version(s)...` }));
|
|
779
|
+
let results;
|
|
780
|
+
try {
|
|
781
|
+
results = await loopDeleteVersions(client, agentManagementId, versions, activeVersionId);
|
|
782
|
+
}
|
|
783
|
+
finally {
|
|
784
|
+
loopSpinner.unmount();
|
|
785
|
+
}
|
|
786
|
+
const succeeded = results.filter((r) => r.success);
|
|
787
|
+
const failed = results.filter((r) => !r.success);
|
|
788
|
+
logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: [_jsx(StatusLine, { kind: failed.length === 0 ? "success" : "warning", label: `Deleted ${succeeded.length}/${versions.length} version(s) of "${agentName}".` }), failed.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "gray", children: " Failed:" }), failed.slice(0, 10).map((r) => (_jsxs(Box, { children: [_jsx(Text, { color: "gray", children: " " }), _jsxs(Text, { color: "red", children: ["v", r.version.version_number, ".", r.version.version_revision_number] }), _jsxs(Text, { color: "gray", children: [" — ", r.errorMessage] })] }, r.version.id))), failed.length > 10 && (_jsxs(Text, { color: "gray", children: [" ", "... and ", failed.length - 10, " more"] }))] }))] }));
|
|
789
|
+
const cleared = clearSessionIfMatchesAgentVersionsAfterAll(versions, results);
|
|
790
|
+
if (cleared) {
|
|
791
|
+
logView(_jsx(StatusLine, { kind: "muted", label: "Session version pointer cleared." }));
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
async function loopDeleteVersions(client, agentManagementId, versions, activeVersionId) {
|
|
795
|
+
const results = [];
|
|
796
|
+
// Delete non-active versions first; the active one (if any) attempts last.
|
|
797
|
+
const ordered = [
|
|
798
|
+
...versions.filter((v) => v.id !== activeVersionId),
|
|
799
|
+
...versions.filter((v) => v.id === activeVersionId),
|
|
800
|
+
];
|
|
801
|
+
for (const v of ordered) {
|
|
802
|
+
try {
|
|
803
|
+
await client.agentManagement.deleteVersion(agentManagementId, v.id, session.user_id);
|
|
804
|
+
results.push({ version: v, success: true });
|
|
805
|
+
}
|
|
806
|
+
catch (err) {
|
|
807
|
+
results.push({ version: v, success: false, errorMessage: formatApiErrorBody(err) });
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return results;
|
|
811
|
+
}
|
|
812
|
+
function clearSessionIfMatchesAgentVersionsAfterAll(versions, results) {
|
|
813
|
+
const current = loadSession();
|
|
814
|
+
if (!current?.version_id)
|
|
815
|
+
return false;
|
|
816
|
+
const currentDeleted = results.find((r) => r.success && r.version.id === current.version_id);
|
|
817
|
+
if (!currentDeleted)
|
|
818
|
+
return false;
|
|
819
|
+
delete current.version_id;
|
|
820
|
+
delete current.version_number;
|
|
821
|
+
delete current.version_revision_number;
|
|
822
|
+
saveSession(current);
|
|
823
|
+
return true;
|
|
824
|
+
}
|
|
825
|
+
async function runDeleteEntireAgent(client, args) {
|
|
826
|
+
let { networkId, agentName, agentManagementId } = args;
|
|
827
|
+
// Resolve a friendly name + version count for the preview
|
|
828
|
+
let totalVersions;
|
|
829
|
+
try {
|
|
830
|
+
if (!agentManagementId) {
|
|
831
|
+
const resp = await client.agentManagement.listAgents(client.getOrganizationId(), 1, 50, { network_id: networkId });
|
|
832
|
+
const match = resp.items.find((a) => a.scope.network_id === networkId || a.id === networkId);
|
|
833
|
+
if (match) {
|
|
834
|
+
agentManagementId = match.id;
|
|
835
|
+
if (!agentName)
|
|
836
|
+
agentName = match.name;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (agentManagementId) {
|
|
840
|
+
const versionsResp = await client.agentManagement.listVersions(agentManagementId, 1, 1);
|
|
841
|
+
totalVersions = versionsResp.total;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
catch {
|
|
845
|
+
// best-effort enrichment
|
|
846
|
+
}
|
|
847
|
+
if (!agentName)
|
|
848
|
+
agentName = networkId;
|
|
849
|
+
if (isJsonMode()) {
|
|
850
|
+
if (!args.skipConfirm) {
|
|
851
|
+
outputJson({
|
|
852
|
+
requires_confirmation: true,
|
|
853
|
+
message: "Refusing to delete in JSON mode without --yes. Re-run with --yes to confirm.",
|
|
854
|
+
agent: { name: agentName, network_id: networkId, agent_management_id: agentManagementId },
|
|
855
|
+
total_versions: totalVersions,
|
|
856
|
+
});
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
stderrLog(`Deleting agent "${agentName}" (network ${networkId})...`);
|
|
860
|
+
try {
|
|
861
|
+
const result = await client.agentManagement.deleteAgentByNetwork(networkId, session.user_id);
|
|
862
|
+
const networkResult = await deleteNetworkBestEffort(client, networkId);
|
|
863
|
+
const cleared = clearSessionIfMatchesAgent(networkId, agentManagementId);
|
|
864
|
+
outputJson({
|
|
865
|
+
deleted: true,
|
|
866
|
+
scope: "agent",
|
|
867
|
+
agent: { name: agentName, network_id: networkId, agent_management_id: agentManagementId },
|
|
868
|
+
versions_deleted: result.versions_deleted ?? totalVersions,
|
|
869
|
+
network_deleted: networkResult.deleted,
|
|
870
|
+
...(networkResult.deleted ? {} : { network_delete_error: networkResult.errorMessage }),
|
|
871
|
+
session_cleared: cleared,
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
catch (error) {
|
|
875
|
+
const code = error instanceof Error && "status" in error
|
|
876
|
+
? `HTTP_${error.status}`
|
|
877
|
+
: "DELETE_AGENT_FAILED";
|
|
878
|
+
outputJson({
|
|
879
|
+
deleted: false,
|
|
880
|
+
error: {
|
|
881
|
+
code,
|
|
882
|
+
message: error instanceof Error ? error.message : String(error),
|
|
883
|
+
},
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
renderView(_jsx(AgentDeletePreviewView, { scope: "agent", agentName: agentName, agentId: agentManagementId || networkId, networkId: networkId, totalVersions: totalVersions }));
|
|
889
|
+
if (!args.skipConfirm) {
|
|
890
|
+
const { typed } = await inquirer.prompt([
|
|
891
|
+
{
|
|
892
|
+
type: "input",
|
|
893
|
+
name: "typed",
|
|
894
|
+
message: `Type the agent name (${agentName}) to confirm:`,
|
|
895
|
+
validate: (v) => v.trim() === agentName
|
|
896
|
+
? true
|
|
897
|
+
: `Type exactly: ${agentName}`,
|
|
898
|
+
},
|
|
899
|
+
]);
|
|
900
|
+
if (typed.trim() !== agentName) {
|
|
901
|
+
logView(_jsx(StatusLine, { kind: "muted", label: "Cancelled." }));
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
// Two-call deletion (safer):
|
|
906
|
+
// 1. agent-settings DELETE → removes versions, settings, agent record
|
|
907
|
+
// 2. networks DELETE → safety net so the agent disappears from
|
|
908
|
+
// the legacy networks listing immediately
|
|
909
|
+
const deleteSpinner = render(_jsx(Spinner, { label: "Deleting agent..." }));
|
|
910
|
+
try {
|
|
911
|
+
await client.agentManagement.deleteAgentByNetwork(networkId, session.user_id);
|
|
912
|
+
deleteSpinner.unmount();
|
|
913
|
+
logView(_jsx(StatusLine, { kind: "success", label: "Agent-management record deleted (versions, settings)." }));
|
|
914
|
+
const networkSpinner = render(_jsx(Spinner, { label: "Removing network shell..." }));
|
|
915
|
+
const networkResult = await deleteNetworkBestEffort(client, networkId);
|
|
916
|
+
networkSpinner.unmount();
|
|
917
|
+
if (networkResult.deleted) {
|
|
918
|
+
logView(_jsx(StatusLine, { kind: "success", label: "Network record removed." }));
|
|
919
|
+
}
|
|
920
|
+
else {
|
|
921
|
+
logView(_jsx(StatusLine, { kind: "warning", label: `Network shell could not be removed automatically: ${networkResult.errorMessage}. The agent may still appear in some legacy listings.` }));
|
|
922
|
+
}
|
|
923
|
+
const cleared = clearSessionIfMatchesAgent(networkId, agentManagementId);
|
|
924
|
+
renderView(_jsx(AgentDeleteResultView, { scope: "agent", agentName: agentName, cleared: cleared }));
|
|
925
|
+
}
|
|
926
|
+
catch (error) {
|
|
927
|
+
deleteSpinner.unmount();
|
|
928
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: `Failed to delete agent: ${formatApiErrorBody(error)}` }));
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
async function runDeleteVersion(client, args) {
|
|
932
|
+
let { agentManagementId, networkId, versionId, agentName, versionLabel, versionStatus, isActiveVersion, } = args;
|
|
933
|
+
// Resolve agent_id from session/network if not provided
|
|
934
|
+
if (!agentManagementId) {
|
|
935
|
+
const networkLookup = networkId || session.network_id;
|
|
936
|
+
if (!networkLookup) {
|
|
937
|
+
renderView(_jsx(ErrorDisplay, { message: "Could not resolve which agent the version belongs to.", suggestion: "Pass --agent-id <id> (or --network-id <id>), or switch to an agent first with: aui agent --switch" }));
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
try {
|
|
941
|
+
const resp = await client.agentManagement.listAgents(client.getOrganizationId(), 1, 50, { network_id: networkLookup });
|
|
942
|
+
const match = resp.items.find((a) => a.scope.network_id === networkLookup || a.id === networkLookup);
|
|
943
|
+
if (match) {
|
|
944
|
+
agentManagementId = match.id;
|
|
945
|
+
if (!agentName)
|
|
946
|
+
agentName = match.name;
|
|
947
|
+
if (!networkId)
|
|
948
|
+
networkId = match.scope.network_id || undefined;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
catch {
|
|
952
|
+
// ignore
|
|
953
|
+
}
|
|
954
|
+
if (!agentManagementId) {
|
|
955
|
+
renderView(_jsx(ErrorDisplay, { message: "Agent not found for the given identifiers.", suggestion: "Run `aui agent --list` to see available agents." }));
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
// Enrich version info from backend if missing
|
|
960
|
+
if (!versionLabel || !versionStatus || isActiveVersion === undefined) {
|
|
961
|
+
try {
|
|
962
|
+
const v = await client.agentManagement.getVersion(agentManagementId, versionId);
|
|
963
|
+
if (!versionLabel)
|
|
964
|
+
versionLabel = `v${v.version_number}.${v.version_revision_number}`;
|
|
965
|
+
if (!versionStatus)
|
|
966
|
+
versionStatus = v.status;
|
|
967
|
+
const agent = await client.agentManagement.getAgent(agentManagementId).catch(() => null);
|
|
968
|
+
if (agent && isActiveVersion === undefined) {
|
|
969
|
+
isActiveVersion = agent.active_version_id === versionId;
|
|
970
|
+
}
|
|
971
|
+
if (agent && !agentName)
|
|
972
|
+
agentName = agent.name;
|
|
973
|
+
}
|
|
974
|
+
catch {
|
|
975
|
+
// best-effort enrichment
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
if (!agentName)
|
|
979
|
+
agentName = agentManagementId;
|
|
980
|
+
if (isJsonMode()) {
|
|
981
|
+
if (!args.skipConfirm) {
|
|
982
|
+
outputJson({
|
|
983
|
+
requires_confirmation: true,
|
|
984
|
+
message: "Refusing to delete in JSON mode without --yes. Re-run with --yes to confirm.",
|
|
985
|
+
agent: { name: agentName, agent_management_id: agentManagementId },
|
|
986
|
+
version: { id: versionId, label: versionLabel, status: versionStatus, is_active: isActiveVersion },
|
|
987
|
+
});
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
stderrLog(`Deleting version ${versionLabel ?? versionId} of "${agentName}"...`);
|
|
991
|
+
try {
|
|
992
|
+
await client.agentManagement.deleteVersion(agentManagementId, versionId, session.user_id);
|
|
993
|
+
const cleared = clearSessionIfMatchesVersion(versionId);
|
|
994
|
+
outputJson({
|
|
995
|
+
deleted: true,
|
|
996
|
+
scope: "version",
|
|
997
|
+
agent: { name: agentName, agent_management_id: agentManagementId },
|
|
998
|
+
version: { id: versionId, label: versionLabel },
|
|
999
|
+
session_cleared: cleared,
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
catch (error) {
|
|
1003
|
+
const code = error instanceof Error && "status" in error
|
|
1004
|
+
? `HTTP_${error.status}`
|
|
1005
|
+
: "DELETE_VERSION_FAILED";
|
|
1006
|
+
outputJson({
|
|
1007
|
+
deleted: false,
|
|
1008
|
+
error: {
|
|
1009
|
+
code,
|
|
1010
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1011
|
+
},
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
renderView(_jsx(AgentDeletePreviewView, { scope: "version", agentName: agentName, agentId: agentManagementId, networkId: networkId, versionLabel: versionLabel, versionId: versionId, versionStatus: versionStatus, isActiveVersion: isActiveVersion }));
|
|
1017
|
+
if (!args.skipConfirm) {
|
|
1018
|
+
const { confirm } = await inquirer.prompt([
|
|
1019
|
+
{
|
|
1020
|
+
type: "confirm",
|
|
1021
|
+
name: "confirm",
|
|
1022
|
+
message: isActiveVersion
|
|
1023
|
+
? `${chalk.red("WARNING:")} this version is currently live. Continue?`
|
|
1024
|
+
: `Delete ${versionLabel ?? versionId} permanently?`,
|
|
1025
|
+
default: false,
|
|
1026
|
+
},
|
|
1027
|
+
]);
|
|
1028
|
+
if (!confirm) {
|
|
1029
|
+
logView(_jsx(StatusLine, { kind: "muted", label: "Cancelled." }));
|
|
1030
|
+
return;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
const deleteSpinner = render(_jsx(Spinner, { label: "Deleting version..." }));
|
|
1034
|
+
try {
|
|
1035
|
+
await client.agentManagement.deleteVersion(agentManagementId, versionId, session.user_id);
|
|
1036
|
+
deleteSpinner.unmount();
|
|
1037
|
+
const cleared = clearSessionIfMatchesVersion(versionId);
|
|
1038
|
+
renderView(_jsx(AgentDeleteResultView, { scope: "version", agentName: agentName, versionLabel: versionLabel, cleared: cleared }));
|
|
1039
|
+
}
|
|
1040
|
+
catch (error) {
|
|
1041
|
+
deleteSpinner.unmount();
|
|
1042
|
+
renderView(_jsx(ErrorDisplay, { error: error, message: `Failed to delete version: ${formatApiErrorBody(error)}` }));
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
function clearSessionIfMatchesAgent(deletedNetworkId, deletedAgentManagementId) {
|
|
1046
|
+
const current = loadSession();
|
|
1047
|
+
if (!current)
|
|
1048
|
+
return false;
|
|
1049
|
+
const matchesNetwork = current.network_id === deletedNetworkId;
|
|
1050
|
+
const matchesAgentMgmt = !!deletedAgentManagementId &&
|
|
1051
|
+
current.agent_management_id === deletedAgentManagementId;
|
|
1052
|
+
if (!matchesNetwork && !matchesAgentMgmt)
|
|
1053
|
+
return false;
|
|
1054
|
+
delete current.network_id;
|
|
1055
|
+
delete current.network_name;
|
|
1056
|
+
delete current.agent_management_id;
|
|
1057
|
+
delete current.version_id;
|
|
1058
|
+
delete current.version_number;
|
|
1059
|
+
delete current.version_revision_number;
|
|
1060
|
+
saveSession(current);
|
|
1061
|
+
return true;
|
|
1062
|
+
}
|
|
1063
|
+
function clearSessionIfMatchesVersion(deletedVersionId) {
|
|
1064
|
+
const current = loadSession();
|
|
1065
|
+
if (!current)
|
|
1066
|
+
return false;
|
|
1067
|
+
if (current.version_id !== deletedVersionId)
|
|
1068
|
+
return false;
|
|
1069
|
+
delete current.version_id;
|
|
1070
|
+
delete current.version_number;
|
|
1071
|
+
delete current.version_revision_number;
|
|
1072
|
+
saveSession(current);
|
|
1073
|
+
return true;
|
|
1074
|
+
}
|
|
292
1075
|
async function handleCreateAgent(opts = {}) {
|
|
293
1076
|
const config = getConfig();
|
|
294
1077
|
const client = new AUIClient({
|