@wraps.dev/cli 2.26.0 → 2.26.1
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/api-lambda.zip +0 -0
- package/dist/cli.js +105 -37
- package/dist/cli.js.map +1 -1
- package/dist/lambda/agent-enforcer/.bundled +1 -1
- package/dist/lambda/event-processor/.bundled +1 -1
- package/dist/lambda/inbound-processor/.bundled +1 -1
- package/dist/lambda/sms-event-processor/.bundled +1 -1
- package/package.json +1 -1
package/dist/api-lambda.zip
CHANGED
|
Binary file
|
package/dist/cli.js
CHANGED
|
@@ -16120,9 +16120,38 @@ async function deployEmailStack(config2) {
|
|
|
16120
16120
|
};
|
|
16121
16121
|
}
|
|
16122
16122
|
|
|
16123
|
+
// src/utils/shared/agent-api.ts
|
|
16124
|
+
init_esm_shims();
|
|
16125
|
+
init_config();
|
|
16126
|
+
async function createAgentApiClient(tokenFlag) {
|
|
16127
|
+
const token = await resolveTokenAsync({ token: tokenFlag });
|
|
16128
|
+
if (!token) {
|
|
16129
|
+
return { ok: false, reason: "not-authenticated" };
|
|
16130
|
+
}
|
|
16131
|
+
const apiBase = getApiBaseUrl();
|
|
16132
|
+
const orgHeader = {};
|
|
16133
|
+
const orgs = (await readAuthConfig())?.auth?.organizations;
|
|
16134
|
+
if (orgs && orgs.length === 1) {
|
|
16135
|
+
orgHeader["X-Organization-Id"] = orgs[0].id;
|
|
16136
|
+
}
|
|
16137
|
+
const call = (method) => (path3, body) => fetch(`${apiBase}${path3}`, {
|
|
16138
|
+
method,
|
|
16139
|
+
headers: {
|
|
16140
|
+
Authorization: `Bearer ${token}`,
|
|
16141
|
+
...body ? { "Content-Type": "application/json" } : {},
|
|
16142
|
+
...orgHeader
|
|
16143
|
+
},
|
|
16144
|
+
...body ? { body: JSON.stringify(body) } : {}
|
|
16145
|
+
});
|
|
16146
|
+
return { ok: true, get: call("GET"), post: call("POST") };
|
|
16147
|
+
}
|
|
16148
|
+
async function parseAgentApiError(resp) {
|
|
16149
|
+
const data = await resp.json().catch(() => ({}));
|
|
16150
|
+
return data.error ?? `HTTP ${resp.status}`;
|
|
16151
|
+
}
|
|
16152
|
+
|
|
16123
16153
|
// src/commands/email/agent.ts
|
|
16124
16154
|
init_aws();
|
|
16125
|
-
init_config();
|
|
16126
16155
|
init_fs();
|
|
16127
16156
|
init_json_output();
|
|
16128
16157
|
init_metadata();
|
|
@@ -16169,32 +16198,6 @@ var DEFAULT_AGENT_POLICY = {
|
|
|
16169
16198
|
allowedRecipientDomains: []
|
|
16170
16199
|
};
|
|
16171
16200
|
var AGENT_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,51}$/;
|
|
16172
|
-
async function createAgentApiClient(tokenFlag) {
|
|
16173
|
-
const token = await resolveTokenAsync({ token: tokenFlag });
|
|
16174
|
-
if (!token) {
|
|
16175
|
-
return { ok: false, reason: "not-authenticated" };
|
|
16176
|
-
}
|
|
16177
|
-
const apiBase = getApiBaseUrl();
|
|
16178
|
-
const orgHeader = {};
|
|
16179
|
-
const orgs = (await readAuthConfig())?.auth?.organizations;
|
|
16180
|
-
if (orgs && orgs.length === 1) {
|
|
16181
|
-
orgHeader["X-Organization-Id"] = orgs[0].id;
|
|
16182
|
-
}
|
|
16183
|
-
const call = (method) => (path3, body) => fetch(`${apiBase}${path3}`, {
|
|
16184
|
-
method,
|
|
16185
|
-
headers: {
|
|
16186
|
-
Authorization: `Bearer ${token}`,
|
|
16187
|
-
...body ? { "Content-Type": "application/json" } : {},
|
|
16188
|
-
...orgHeader
|
|
16189
|
-
},
|
|
16190
|
-
...body ? { body: JSON.stringify(body) } : {}
|
|
16191
|
-
});
|
|
16192
|
-
return { ok: true, get: call("GET"), post: call("POST") };
|
|
16193
|
-
}
|
|
16194
|
-
async function parseError(resp) {
|
|
16195
|
-
const data = await resp.json().catch(() => ({}));
|
|
16196
|
-
return data.error ?? `HTTP ${resp.status}`;
|
|
16197
|
-
}
|
|
16198
16201
|
async function agentCreate(options) {
|
|
16199
16202
|
if (!isJsonMode()) {
|
|
16200
16203
|
clack15.intro(pc17.bold("Create Agent Mailbox"));
|
|
@@ -16250,7 +16253,7 @@ Sign in first: ${pc17.cyan("wraps auth login")}
|
|
|
16250
16253
|
async () => {
|
|
16251
16254
|
const resp = await api.get("/v1/connections");
|
|
16252
16255
|
if (!resp.ok) {
|
|
16253
|
-
throw new Error(await
|
|
16256
|
+
throw new Error(await parseAgentApiError(resp));
|
|
16254
16257
|
}
|
|
16255
16258
|
const data = await resp.json();
|
|
16256
16259
|
return data.connections.some((c) => c.accountId === identity.accountId);
|
|
@@ -16396,7 +16399,7 @@ Connect (or reconnect) first so it is stored locally:
|
|
|
16396
16399
|
return { kind: "created", agent: await resp.json() };
|
|
16397
16400
|
}
|
|
16398
16401
|
if (resp.status !== 409) {
|
|
16399
|
-
throw new Error(await
|
|
16402
|
+
throw new Error(await parseAgentApiError(resp));
|
|
16400
16403
|
}
|
|
16401
16404
|
const listResp = await api.get("/v1/agents");
|
|
16402
16405
|
const existing = listResp.ok ? (await listResp.json()).agents.find(
|
|
@@ -16567,7 +16570,7 @@ ${suggestion}
|
|
|
16567
16570
|
awsAccountId: identity.accountId
|
|
16568
16571
|
});
|
|
16569
16572
|
if (!resp.ok) {
|
|
16570
|
-
throw new Error(await
|
|
16573
|
+
throw new Error(await parseAgentApiError(resp));
|
|
16571
16574
|
}
|
|
16572
16575
|
});
|
|
16573
16576
|
if (isJsonMode()) {
|
|
@@ -16630,7 +16633,7 @@ async function agentList(options) {
|
|
|
16630
16633
|
}
|
|
16631
16634
|
const resp = await api.get("/v1/agents");
|
|
16632
16635
|
if (!resp.ok) {
|
|
16633
|
-
const message = await
|
|
16636
|
+
const message = await parseAgentApiError(resp);
|
|
16634
16637
|
if (isJsonMode()) {
|
|
16635
16638
|
jsonError("email.agent.list", { code: "API_ERROR", message });
|
|
16636
16639
|
} else {
|
|
@@ -16670,7 +16673,7 @@ async function agentKill(options) {
|
|
|
16670
16673
|
}
|
|
16671
16674
|
const listResp = await api.get("/v1/agents");
|
|
16672
16675
|
if (!listResp.ok) {
|
|
16673
|
-
const message = await
|
|
16676
|
+
const message = await parseAgentApiError(listResp);
|
|
16674
16677
|
if (isJsonMode()) {
|
|
16675
16678
|
jsonError("email.agent.kill", { code: "API_ERROR", message });
|
|
16676
16679
|
} else {
|
|
@@ -16729,7 +16732,7 @@ async function agentKill(options) {
|
|
|
16729
16732
|
}
|
|
16730
16733
|
const resp = await api.post(`/v1/agents/${target.id}/kill`);
|
|
16731
16734
|
if (!resp.ok) {
|
|
16732
|
-
const message = await
|
|
16735
|
+
const message = await parseAgentApiError(resp);
|
|
16733
16736
|
if (isJsonMode()) {
|
|
16734
16737
|
jsonError("email.agent.kill", { code: "API_ERROR", message });
|
|
16735
16738
|
} else {
|
|
@@ -20535,6 +20538,9 @@ ${pc20.dim("Example:")}`);
|
|
|
20535
20538
|
init_esm_shims();
|
|
20536
20539
|
init_events();
|
|
20537
20540
|
init_route53();
|
|
20541
|
+
import * as clack19 from "@clack/prompts";
|
|
20542
|
+
import * as pulumi18 from "@pulumi/pulumi";
|
|
20543
|
+
import pc21 from "picocolors";
|
|
20538
20544
|
init_aws();
|
|
20539
20545
|
init_errors();
|
|
20540
20546
|
init_fs();
|
|
@@ -20542,9 +20548,6 @@ init_json_output();
|
|
|
20542
20548
|
init_metadata();
|
|
20543
20549
|
init_output();
|
|
20544
20550
|
init_pulumi();
|
|
20545
|
-
import * as clack19 from "@clack/prompts";
|
|
20546
|
-
import * as pulumi18 from "@pulumi/pulumi";
|
|
20547
|
-
import pc21 from "picocolors";
|
|
20548
20551
|
async function getEmailIdentityInfo(domain, region) {
|
|
20549
20552
|
try {
|
|
20550
20553
|
const { SESv2Client: SESv2Client10, GetEmailIdentityCommand: GetEmailIdentityCommand7 } = await import("@aws-sdk/client-sesv2");
|
|
@@ -20563,6 +20566,30 @@ async function getEmailIdentityInfo(domain, region) {
|
|
|
20563
20566
|
throw error;
|
|
20564
20567
|
}
|
|
20565
20568
|
}
|
|
20569
|
+
function selectAgentsToDestroy(emailConfig) {
|
|
20570
|
+
const agentsConfig = emailConfig?.agents;
|
|
20571
|
+
if (!agentsConfig?.enabled) {
|
|
20572
|
+
return [];
|
|
20573
|
+
}
|
|
20574
|
+
return (agentsConfig.agents ?? []).map((a) => ({
|
|
20575
|
+
id: a.id,
|
|
20576
|
+
name: a.name,
|
|
20577
|
+
emailAddress: a.emailAddress
|
|
20578
|
+
}));
|
|
20579
|
+
}
|
|
20580
|
+
function buildAgentDestroySummaryLines(agents) {
|
|
20581
|
+
if (agents.length === 0) {
|
|
20582
|
+
return [];
|
|
20583
|
+
}
|
|
20584
|
+
const addresses = agents.map((a) => a.emailAddress).join(", ");
|
|
20585
|
+
return [
|
|
20586
|
+
"",
|
|
20587
|
+
`Agent mailboxes (${agents.length}): ${addresses}`,
|
|
20588
|
+
pc21.yellow(
|
|
20589
|
+
"Agent scoped credentials are revoked (IAM users wraps-agent-* deleted), the wraps-agent-enforcer Lambda and wraps-email-agent-policy table are destroyed, and any pending approvals become undeliverable."
|
|
20590
|
+
)
|
|
20591
|
+
];
|
|
20592
|
+
}
|
|
20566
20593
|
async function emailDestroy(options) {
|
|
20567
20594
|
const startTime = Date.now();
|
|
20568
20595
|
if (isJsonMode() && !options.force) {
|
|
@@ -20623,6 +20650,7 @@ async function emailDestroy(options) {
|
|
|
20623
20650
|
const emailConfig = emailService?.config;
|
|
20624
20651
|
const domain = emailConfig?.domain;
|
|
20625
20652
|
const storedStackName = emailService?.pulumiStackName;
|
|
20653
|
+
const agentsToDestroy = selectAgentsToDestroy(emailConfig);
|
|
20626
20654
|
if (!(options.force || options.preview)) {
|
|
20627
20655
|
const additionalDomainNames = (emailConfig?.additionalDomains ?? []).map((d) => d.domain).filter(Boolean);
|
|
20628
20656
|
const domainList = [domain, ...additionalDomainNames].filter(Boolean);
|
|
@@ -20635,6 +20663,7 @@ async function emailDestroy(options) {
|
|
|
20635
20663
|
"Event streaming stops: the Wraps dashboard email timeline and event history for THIS ENTIRE AWS ACCOUNT stop receiving events. Historical events in DynamoDB are destroyed with the table. This cannot be undone."
|
|
20636
20664
|
)
|
|
20637
20665
|
];
|
|
20666
|
+
summaryLines.push(...buildAgentDestroySummaryLines(agentsToDestroy));
|
|
20638
20667
|
if (emailService?.webhookSecret) {
|
|
20639
20668
|
summaryLines.push(
|
|
20640
20669
|
"",
|
|
@@ -20731,6 +20760,13 @@ async function emailDestroy(options) {
|
|
|
20731
20760
|
);
|
|
20732
20761
|
}
|
|
20733
20762
|
}
|
|
20763
|
+
const agentSummaryLines = buildAgentDestroySummaryLines(agentsToDestroy);
|
|
20764
|
+
if (agentSummaryLines.length > 0) {
|
|
20765
|
+
clack19.note(
|
|
20766
|
+
agentSummaryLines.filter(Boolean).join("\n"),
|
|
20767
|
+
"Agent mailboxes"
|
|
20768
|
+
);
|
|
20769
|
+
}
|
|
20734
20770
|
clack19.outro(
|
|
20735
20771
|
pc21.green("Preview complete. Run without --preview to destroy.")
|
|
20736
20772
|
);
|
|
@@ -20850,6 +20886,33 @@ async function emailDestroy(options) {
|
|
|
20850
20886
|
}
|
|
20851
20887
|
} catch {
|
|
20852
20888
|
}
|
|
20889
|
+
if (agentsToDestroy.length > 0) {
|
|
20890
|
+
try {
|
|
20891
|
+
const agentApi = await createAgentApiClient();
|
|
20892
|
+
if (agentApi.ok) {
|
|
20893
|
+
let killed = 0;
|
|
20894
|
+
for (const agent of agentsToDestroy) {
|
|
20895
|
+
try {
|
|
20896
|
+
const resp = await agentApi.post(`/v1/agents/${agent.id}/kill`);
|
|
20897
|
+
if (resp.ok) {
|
|
20898
|
+
killed++;
|
|
20899
|
+
}
|
|
20900
|
+
} catch {
|
|
20901
|
+
}
|
|
20902
|
+
}
|
|
20903
|
+
if (!isJsonMode()) {
|
|
20904
|
+
clack19.log.info(
|
|
20905
|
+
`Marked ${killed}/${agentsToDestroy.length} agent(s) as killed in the Wraps dashboard.`
|
|
20906
|
+
);
|
|
20907
|
+
}
|
|
20908
|
+
} else if (!isJsonMode()) {
|
|
20909
|
+
clack19.log.warn(
|
|
20910
|
+
"Could not reach the Wraps Platform to update agent status \u2014 your agents will still show as active in the dashboard. Kill them there: wraps email agent kill (or the dashboard)."
|
|
20911
|
+
);
|
|
20912
|
+
}
|
|
20913
|
+
} catch {
|
|
20914
|
+
}
|
|
20915
|
+
}
|
|
20853
20916
|
await deleteConnectionMetadata(identity.accountId, region);
|
|
20854
20917
|
progress.stop();
|
|
20855
20918
|
if (isJsonMode()) {
|
|
@@ -20857,7 +20920,12 @@ async function emailDestroy(options) {
|
|
|
20857
20920
|
destroyed: !destroyFailed,
|
|
20858
20921
|
region,
|
|
20859
20922
|
dns_cleaned: shouldCleanDNS,
|
|
20860
|
-
partial_failure: destroyFailed
|
|
20923
|
+
partial_failure: destroyFailed,
|
|
20924
|
+
agents: agentsToDestroy.map((a) => ({
|
|
20925
|
+
id: a.id,
|
|
20926
|
+
name: a.name,
|
|
20927
|
+
emailAddress: a.emailAddress
|
|
20928
|
+
}))
|
|
20861
20929
|
});
|
|
20862
20930
|
trackServiceRemoved("email", {
|
|
20863
20931
|
reason: "user_initiated",
|