@wraps.dev/cli 3.9.1 → 3.10.0

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/cli.js CHANGED
@@ -30451,17 +30451,31 @@ async function attachConsoleRoleInvoke(config2) {
30451
30451
  }
30452
30452
  new aws22.iam.RolePolicy(target.logicalName, {
30453
30453
  role: target.roleName,
30454
- policy: config2.enforcerArn.apply(
30455
- (arn) => JSON.stringify({
30456
- Version: "2012-10-17",
30457
- Statement: [
30458
- {
30459
- Effect: "Allow",
30460
- Action: "lambda:InvokeFunction",
30461
- Resource: arn
30462
- }
30463
- ]
30464
- })
30454
+ policy: config2.policyTableArn.apply(
30455
+ (tableArn) => config2.enforcerArn.apply(
30456
+ (enforcerArn) => JSON.stringify({
30457
+ Version: "2012-10-17",
30458
+ Statement: [
30459
+ {
30460
+ Effect: "Allow",
30461
+ Action: "lambda:InvokeFunction",
30462
+ Resource: enforcerArn
30463
+ },
30464
+ {
30465
+ // syncAgentPolicy() assumes this role and writes the
30466
+ // CONFIG#<agentId> item the enforcer reads to identify an
30467
+ // agent. Without it every send returns "unknown agent" — the
30468
+ // agent is created but permanently unusable.
30469
+ // PutItem is the ONLY DynamoDB action the API performs against
30470
+ // the customer account; policy edits and kills are full-item
30471
+ // Puts through the same path.
30472
+ Effect: "Allow",
30473
+ Action: "dynamodb:PutItem",
30474
+ Resource: tableArn
30475
+ }
30476
+ ]
30477
+ })
30478
+ )
30465
30479
  )
30466
30480
  });
30467
30481
  granted += 1;
@@ -39677,7 +39691,8 @@ async function deployEmailStack(config2) {
39677
39691
  });
39678
39692
  const { createAgentUser: createAgentUser2, attachConsoleRoleInvoke: attachConsoleRoleInvoke2 } = await Promise.resolve().then(() => (init_iam_agent_user(), iam_agent_user_exports));
39679
39693
  await attachConsoleRoleInvoke2({
39680
- enforcerArn: enforcer.lambdaFunction.arn
39694
+ enforcerArn: enforcer.lambdaFunction.arn,
39695
+ policyTableArn: policyTable.arn
39681
39696
  });
39682
39697
  agentCredentials = {};
39683
39698
  agentAliasArns = {};
@@ -40202,7 +40217,7 @@ ${suggestion}
40202
40217
  metadata.timestamp = (/* @__PURE__ */ new Date()).toISOString();
40203
40218
  await saveConnectionMetadata(metadata);
40204
40219
  });
40205
- await progress.execute("Syncing agent policy", async () => {
40220
+ const sync = await progress.execute("Syncing agent policy", async () => {
40206
40221
  const resp = await api.post(`/v1/agents/${created.id}/policy-sync`, {
40207
40222
  credentialUserArn: creds.userArn,
40208
40223
  enforcerFunctionArn,
@@ -40211,7 +40226,9 @@ ${suggestion}
40211
40226
  if (!resp.ok) {
40212
40227
  throw new Error(await parseAgentApiError(resp));
40213
40228
  }
40229
+ return await resp.json();
40214
40230
  });
40231
+ const syncFailed = sync.syncStatus === "failed";
40215
40232
  if (isJsonMode()) {
40216
40233
  jsonSuccess("email.agent.create", {
40217
40234
  id: created.id,
@@ -40226,13 +40243,23 @@ ${suggestion}
40226
40243
  policyTableName: outputs.agentPolicyTableName ?? null,
40227
40244
  accessKeyId: creds.accessKeyId,
40228
40245
  secretAccessKey: creds.secretAccessKey,
40229
- userArn: creds.userArn
40246
+ userArn: creds.userArn,
40247
+ // The command DID create the agent and mint a real credential even when
40248
+ // the sync failed — jsonSuccess (not jsonError) is deliberate here so
40249
+ // the credential doesn't have to be smuggled through an error payload a
40250
+ // scripted caller isn't looking at. syncStatus is the field to branch on.
40251
+ syncStatus: sync.syncStatus ?? "unknown",
40252
+ warning: sync.warning ?? null
40230
40253
  });
40231
40254
  return;
40232
40255
  }
40233
40256
  progress.stop();
40234
40257
  console.log();
40235
- clack18.log.success(pc20.bold(`Agent "${name}" is ready.`));
40258
+ if (syncFailed) {
40259
+ clack18.log.warn(pc20.bold(`Agent "${name}" was created but CANNOT send yet.`));
40260
+ } else {
40261
+ clack18.log.success(pc20.bold(`Agent "${name}" is ready.`));
40262
+ }
40236
40263
  console.log();
40237
40264
  console.log(` ${pc20.dim("Address:")} ${pc20.cyan(emailAddress)}`);
40238
40265
  console.log(` ${pc20.dim("Agent ID:")} ${pc20.cyan(created.id)}`);
@@ -40247,14 +40274,25 @@ ${suggestion}
40247
40274
  ].join("\n");
40248
40275
  clack18.note(mcpEnv, "MCP env \u2014 save now, the secret is shown only once");
40249
40276
  console.log();
40250
- console.log(pc20.bold("Next steps:"));
40251
- console.log(
40252
- ` 1. Add the env above to your agent's ${pc20.cyan("@wraps.dev/mcp")} config`
40253
- );
40254
- console.log(
40255
- ` 2. Review pending sends: ${pc20.cyan("wraps email agent list")}`
40256
- );
40257
- console.log();
40277
+ if (syncFailed) {
40278
+ console.log(pc20.bold("This agent cannot send until the sync succeeds:"));
40279
+ if (sync.warning) {
40280
+ console.log(` ${pc20.yellow(sync.warning)}`);
40281
+ }
40282
+ console.log(
40283
+ ` Still failing after that? Reach us: ${pc20.cyan("wraps support")}`
40284
+ );
40285
+ console.log();
40286
+ } else {
40287
+ console.log(pc20.bold("Next steps:"));
40288
+ console.log(
40289
+ ` 1. Add the env above to your agent's ${pc20.cyan("@wraps.dev/mcp")} config`
40290
+ );
40291
+ console.log(
40292
+ ` 2. Review pending sends: ${pc20.cyan("wraps email agent list")}`
40293
+ );
40294
+ console.log();
40295
+ }
40258
40296
  }
40259
40297
  async function agentList(options) {
40260
40298
  const api = await createAgentApiClient(options.token);