@lazehq/cli 0.1.49 → 0.1.50

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.
Files changed (2) hide show
  1. package/dist/laze.mjs +858 -491
  2. package/package.json +1 -1
package/dist/laze.mjs CHANGED
@@ -18733,7 +18733,7 @@ var require_snapshot_utils = __commonJS({
18733
18733
  var require_snapshot_recorder = __commonJS({
18734
18734
  "../../node_modules/.pnpm/undici@8.10.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
18735
18735
  "use strict";
18736
- var { writeFile: writeFile23, readFile: readFile40, mkdir: mkdir22 } = __require("node:fs/promises");
18736
+ var { writeFile: writeFile24, readFile: readFile40, mkdir: mkdir23 } = __require("node:fs/promises");
18737
18737
  var { dirname: dirname24, resolve: resolve19 } = __require("node:path");
18738
18738
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
18739
18739
  var { InvalidArgumentError, UndiciError } = require_errors();
@@ -18980,12 +18980,12 @@ var require_snapshot_recorder = __commonJS({
18980
18980
  throw new InvalidArgumentError("Snapshot path is required");
18981
18981
  }
18982
18982
  const resolvedPath = resolve19(path);
18983
- await mkdir22(dirname24(resolvedPath), { recursive: true });
18983
+ await mkdir23(dirname24(resolvedPath), { recursive: true });
18984
18984
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
18985
18985
  hash: hash2,
18986
18986
  snapshot
18987
18987
  }));
18988
- await writeFile23(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
18988
+ await writeFile24(resolvedPath, JSON.stringify(data, null, 2), { flush: true });
18989
18989
  }
18990
18990
  /**
18991
18991
  * Clears all recorded snapshots
@@ -30914,6 +30914,14 @@ function isLazeIdText(text2) {
30914
30914
  var REDACTION_MARKER = "[SECRET]";
30915
30915
  var MAX_SCAN_LENGTH = 25e4;
30916
30916
  var NAME_LOOKBACK = 200;
30917
+ var VENDOR_FORMAT_RULE_IDS = /* @__PURE__ */ new Set([
30918
+ "github_token",
30919
+ "provider_api_key",
30920
+ "stripe_secret_key",
30921
+ "slack_token",
30922
+ "google_api_key",
30923
+ "vendor_api_key"
30924
+ ]);
30917
30925
  function charClasses(value) {
30918
30926
  let lower = 0;
30919
30927
  let upper = 0;
@@ -31482,13 +31490,49 @@ function findSecrets({
31482
31490
  );
31483
31491
  }
31484
31492
 
31493
+ // ../../packages/secret-guard/src/detector/one-time-links.ts
31494
+ var URL_PATTERN = /https?:\/\/[^\s<>"'`)\]]+/g;
31495
+ var ONE_TIME_WORDS = /(?:^|[^a-z])(?:magic|verify|verification|confirm|login|log-in|signin|sign-in|sign_in|auth|2fa|mfa|otp|token|code|reset|invite|passwordless|one-time|onetime|callback)(?:$|[^a-z])/i;
31496
+ var KEPT_IN_LINKS = /* @__PURE__ */ new Set([
31497
+ ...VENDOR_FORMAT_RULE_IDS,
31498
+ "aws_access_key_id",
31499
+ "url_credentials",
31500
+ "pem_private_key"
31501
+ ]);
31502
+ function isOneTime(url2) {
31503
+ try {
31504
+ const parsed = new URL(url2);
31505
+ const names = [...parsed.searchParams.keys()].join(" ");
31506
+ return ONE_TIME_WORDS.test(`${parsed.pathname} ${names} ${parsed.hash}`);
31507
+ } catch {
31508
+ return false;
31509
+ }
31510
+ }
31511
+ function oneTimeLinksIn({ text: text2 }) {
31512
+ return [...text2.matchAll(URL_PATTERN)].flatMap((match) => {
31513
+ const url2 = match[0].replace(/[.,;:!?]+$/, "");
31514
+ return isOneTime(url2) ? [{ url: url2, start: match.index, end: match.index + url2.length }] : [];
31515
+ });
31516
+ }
31517
+ function withoutOneTimeLinkTokens({
31518
+ text: text2,
31519
+ secrets
31520
+ }) {
31521
+ const links = oneTimeLinksIn({ text: text2 });
31522
+ if (links.length === 0) return [...secrets];
31523
+ return secrets.filter(
31524
+ (secret) => KEPT_IN_LINKS.has(secret.kind) || !links.some((link) => secret.start >= link.start && secret.end <= link.end)
31525
+ );
31526
+ }
31527
+
31485
31528
  // ../../packages/secret-guard/src/detector/draft-secrets.ts
31486
31529
  var MESSAGE_TOKEN = /<@(?:person|agent):[A-Za-z0-9_-]{1,64}>|<!(?:channel|here)>|<file:[A-Za-z0-9_-]{1,64}>/g;
31487
31530
  function withoutMessageTokens(text2) {
31488
31531
  return text2.replace(MESSAGE_TOKEN, (token2) => " ".repeat(token2.length));
31489
31532
  }
31490
31533
  function draftSecretsIn({ text: text2 }) {
31491
- return findSecrets({ text: withoutMessageTokens(text2) });
31534
+ const scanned = withoutMessageTokens(text2);
31535
+ return withoutOneTimeLinkTokens({ text: scanned, secrets: findSecrets({ text: scanned }) });
31492
31536
  }
31493
31537
 
31494
31538
  // ../../packages/secret-guard/src/detector/vault-reference.ts
@@ -31523,6 +31567,19 @@ function applySavedProposals({
31523
31567
  );
31524
31568
  }
31525
31569
 
31570
+ // ../../packages/secret-guard/src/fields/identifier-fields.ts
31571
+ var IDENTIFIER_WORDS = /(?:^|[^A-Z])(?:USER|USERNAME|USER_NAME|EMAIL|E_MAIL|MAIL|LOGIN|ACCOUNT)(?:$|[^A-Z])/;
31572
+ var SECRET_WORDS = /PASS|SECRET|TOKEN|KEY|PIN|OTP|CREDENTIAL|PRIVATE/;
31573
+ function isIdentifierField({ name: name3 }) {
31574
+ const upper = name3.toUpperCase();
31575
+ return IDENTIFIER_WORDS.test(upper) && !SECRET_WORDS.test(upper);
31576
+ }
31577
+ function secretValuesOf({
31578
+ fields
31579
+ }) {
31580
+ return Object.entries(fields).filter(([name3]) => !isIdentifierField({ name: name3 })).map(([, value]) => value);
31581
+ }
31582
+
31526
31583
  // ../../packages/secret-guard/src/redaction/redactor.ts
31527
31584
  var REDACTED = "****";
31528
31585
  var MIN_REDACTED_LENGTH = 4;
@@ -35718,7 +35775,7 @@ function flagText({
35718
35775
  }
35719
35776
 
35720
35777
  // src/rules/cli-version.rules.ts
35721
- var STAMPED = "0.1.49";
35778
+ var STAMPED = "0.1.50";
35722
35779
  function cliVersionOf({ stamped = STAMPED } = {}) {
35723
35780
  return stamped.startsWith("__") ? "dev" : stamped;
35724
35781
  }
@@ -57814,6 +57871,29 @@ var deviceGrantSummarySchema = deviceGrantSummarySchemaDefinition;
57814
57871
  var ApiKeyApi = moduleApi()("api-key");
57815
57872
  var apiKeyTrpc = defineTrpcContract("apiKey").mutation("create").withInput(createApiKeyInputSchema).withOutput(createdApiKeySchema).query("list").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(external_exports.array(apiKeySummarySchema)).mutation("revoke").withInput(revokeApiKeyInputSchema).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("listMine").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(external_exports.array(personalApiKeySchema)).mutation("revokeMine").withInput(revokeApiKeyInputSchema).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("deviceGrant").withInput(external_exports.object({ workspaceId: external_exports.string().min(1), userCode: external_exports.string().min(1).max(20) })).withOutput(deviceGrantSummarySchema).mutation("approveDevice").withInput(decideDeviceGrantInputSchema).withOutput(external_exports.object({ approved: external_exports.literal(true) })).mutation("denyDevice").withInput(decideDeviceGrantInputSchema).withOutput(external_exports.object({ denied: external_exports.literal(true) })).build();
57816
57873
 
57874
+ // ../../modules/chat/contract/src/chat.gifs.ts
57875
+ var GIF_QUERY_MAX = 100;
57876
+ var searchGifsInputSchemaDefinition = external_exports.object({
57877
+ workspaceId: external_exports.string().min(1),
57878
+ query: external_exports.string().trim().min(1).max(GIF_QUERY_MAX),
57879
+ page: external_exports.number().int().min(1).max(50).default(1)
57880
+ });
57881
+ var searchGifsInputSchema = searchGifsInputSchemaDefinition;
57882
+ var gifSchemaDefinition = external_exports.object({
57883
+ id: external_exports.string(),
57884
+ title: external_exports.string(),
57885
+ /** The animated GIF a sent message shows. */
57886
+ url: external_exports.string().url(),
57887
+ width: external_exports.number().int().nonnegative(),
57888
+ height: external_exports.number().int().nonnegative()
57889
+ });
57890
+ var gifSchema = gifSchemaDefinition;
57891
+ var gifResultsSchemaDefinition = external_exports.object({
57892
+ gifs: external_exports.array(gifSchema),
57893
+ hasNext: external_exports.boolean()
57894
+ });
57895
+ var gifResultsSchema = gifResultsSchemaDefinition;
57896
+
57817
57897
  // ../../modules/chat/contract/src/chat.layout.ts
57818
57898
  var LAYOUT_BLOCKS_MAX = 50;
57819
57899
  var LAYOUT_TEXT_MAX = 3e3;
@@ -58229,6 +58309,8 @@ var attentionCardSchemaDefinition = external_exports.object({
58229
58309
  canAlwaysAllow: external_exports.boolean(),
58230
58310
  /** How long "Allow for this agent" lasts, shown on the button; null when not known. */
58231
58311
  alwaysLeaseSeconds: external_exports.number().int().positive().nullable().default(null),
58312
+ /** A vault card whose Allow covers the rest of the agent's turn: "Allow for this task". */
58313
+ allowCoversTask: external_exports.boolean().optional(),
58232
58314
  /** The vault's request id when the card is a vault approval; null for a harness question. */
58233
58315
  vaultRequestId: external_exports.string().nullable().default(null),
58234
58316
  /** A vault approval whose Allow goes through the owner's device passkey. */
@@ -58582,7 +58664,9 @@ var directoryEntrySchemaDefinition = external_exports.object({
58582
58664
  removedAt: external_exports.iso.datetime().nullable().default(null),
58583
58665
  removedByName: external_exports.string().nullable().default(null),
58584
58666
  /** An agent that runs outside Laze: what it reads leaves Laze. False for people. */
58585
- runsOutside: external_exports.boolean().default(false)
58667
+ runsOutside: external_exports.boolean().default(false),
58668
+ /** Other names a person goes by, such as "Drew" or their Slack name; mentions match them. */
58669
+ aliases: external_exports.array(external_exports.string()).optional()
58586
58670
  });
58587
58671
  var chatOverviewSchemaDefinition = external_exports.object({
58588
58672
  viewer: chatActorSchemaDefinition,
@@ -59448,7 +59532,7 @@ var ChatApi = moduleApi()("chat");
59448
59532
  var chatConversationsTrpc = defineTrpcContract("chat").query("overview").withInput(workspaceInputSchema).withOutput(chatOverviewSchema).query("unreadSummary").withInput(external_exports.object({})).withOutput(external_exports.array(workspaceUnreadSchema)).query("browse").withInput(workspaceInputSchema).withOutput(external_exports.array(browsableChannelSchema)).mutation("createChannel").withInput(createChannelInputSchema).withOutput(conversationSchema).mutation("join").withInput(channelInputSchema).withOutput(conversationSchema).mutation("leave").withInput(channelInputSchema).withOutput(external_exports.object({ left: external_exports.literal(true) })).mutation("updateChannel").withInput(updateChannelInputSchema).withOutput(conversationSchema).mutation("setDefaultAgent").withInput(setDefaultAgentInputSchema).withOutput(conversationSchema).query("logChannelHint").withInput(channelInputSchema).withOutput(logChannelHintSchema).mutation("dismissLogChannelHint").withInput(channelInputSchema).withOutput(external_exports.object({ dismissed: external_exports.literal(true) })).mutation("archiveChannel").withInput(channelInputSchema).withOutput(conversationSchema).mutation("unarchiveChannel").withInput(channelInputSchema).withOutput(conversationSchema).mutation("addMembers").withInput(addMembersInputSchema).withOutput(conversationSchema).mutation("removeMember").withInput(removeMemberInputSchema).withOutput(conversationSchema).mutation("openDirect").withInput(openDirectInputSchema).withOutput(conversationSchema).query("conversation").withInput(channelInputSchema).withOutput(conversationSchema).build();
59449
59533
  var chatChannelRolesTrpc = defineTrpcContract("chat").mutation("setChannelRole").withInput(setChannelRoleInputSchema).withOutput(conversationSchema).mutation("extendChannel").withInput(extendChannelInputSchema).withOutput(conversationSchema).build();
59450
59534
  var chatMessagesTrpc = defineTrpcContract("chat").query("history").withInput(historyInputSchema).withOutput(historyPageSchema).query("thread").withInput(messageInputSchema).withOutput(threadSchema).mutation("post").withInput(postMessageInputSchema).withOutput(messageSchema).mutation("forward").withInput(forwardMessageInputSchema).withOutput(messageSchema).mutation("addMentioned").withInput(addMentionedInputSchema).withOutput(messageSchema).mutation("edit").withInput(editMessageInputSchema).withOutput(messageSchema).mutation("delete").withInput(messageInputSchema).withOutput(messageSchema).mutation("remove").withInput(messageInputSchema).withOutput(messageSchema).mutation("react").withInput(reactInputSchema).withOutput(messageSchema).mutation("signalTyping").withInput(signalTypingInputSchema).withOutput(external_exports.object({ sent: external_exports.literal(true) })).mutation("markRead").withInput(markReadInputSchema).withOutput(external_exports.object({ lastReadSeq: external_exports.number().int().nonnegative() })).mutation("markUnread").withInput(markUnreadInputSchema).withOutput(external_exports.object({ lastReadSeq: external_exports.number().int().nonnegative() })).query("search").withInput(searchInputSchema).withOutput(searchResultSchema).build();
59451
- var chatFilesTrpc = defineTrpcContract("chat").mutation("startUpload").withInput(startUploadInputSchema).withOutput(uploadTicketSchema).mutation("completeUpload").withInput(completeUploadInputSchema).withOutput(attachmentSchema).mutation("abortUpload").withInput(fileInputSchema).withOutput(external_exports.object({ aborted: external_exports.literal(true) })).query("fileLink").withInput(fileLinkInputSchema).withOutput(fileLinkSchema).query("channelFiles").withInput(channelFilesInputSchema).withOutput(channelFilesSchema).mutation("renameAttachment").withInput(renameAttachmentInputSchema).withOutput(attachmentSchema).mutation("hideUnfurl").withInput(hideUnfurlInputSchema).withOutput(messageSchema).query("unfurlImage").withInput(hideUnfurlInputSchema).withOutput(fileLinkSchema).build();
59535
+ var chatFilesTrpc = defineTrpcContract("chat").mutation("startUpload").withInput(startUploadInputSchema).withOutput(uploadTicketSchema).mutation("completeUpload").withInput(completeUploadInputSchema).withOutput(attachmentSchema).mutation("abortUpload").withInput(fileInputSchema).withOutput(external_exports.object({ aborted: external_exports.literal(true) })).query("fileLink").withInput(fileLinkInputSchema).withOutput(fileLinkSchema).query("channelFiles").withInput(channelFilesInputSchema).withOutput(channelFilesSchema).mutation("renameAttachment").withInput(renameAttachmentInputSchema).withOutput(attachmentSchema).mutation("hideUnfurl").withInput(hideUnfurlInputSchema).withOutput(messageSchema).query("unfurlImage").withInput(hideUnfurlInputSchema).withOutput(fileLinkSchema).query("searchGifs").withInput(searchGifsInputSchema).withOutput(gifResultsSchema).build();
59452
59536
  var chatFollowingTrpc = defineTrpcContract("chat").mutation("setNotify").withInput(setNotifyInputSchema).withOutput(conversationSummarySchema).mutation("hideConversation").withInput(channelInputSchema).withOutput(external_exports.object({ hidden: external_exports.literal(true) })).mutation("followThread").withInput(followThreadInputSchema).withOutput(threadFollowSchema).query("threadFollow").withInput(messageInputSchema).withOutput(threadFollowSchema).query("threads").withInput(threadsInputSchema).withOutput(threadsPageSchema).query("threadsUnread").withInput(workspaceInputSchema).withOutput(threadsUnreadSchema).query("notificationCount").withInput(workspaceInputSchema).withOutput(external_exports.object({ count: external_exports.number().int().nonnegative() })).mutation("markThreadRead").withInput(messageInputSchema).withOutput(external_exports.object({ read: external_exports.literal(true) })).mutation("pin").withInput(pinMessageInputSchema).withOutput(messageSchema).query("pins").withInput(channelInputSchema).withOutput(pinsPageSchema).query("saved").withInput(savedInputSchema).withOutput(savedPageSchema).query("savedMarks").withInput(workspaceInputSchema).withOutput(savedMarksSchema).mutation("saveMessage").withInput(saveMessageInputSchema).withOutput(savedStatusSchema).mutation("markSavedDone").withInput(markSavedDoneInputSchema).withOutput(savedStatusSchema).mutation("setReminder").withInput(setReminderInputSchema).withOutput(savedStatusSchema).query("activity").withInput(activityInputSchema).withOutput(activityPageSchema).mutation("markActivityRead").withInput(markActivityReadInputSchema).withOutput(external_exports.object({ read: external_exports.literal(true) })).build();
59453
59537
  var chatSessionTrpc = defineTrpcContract("chat").mutation("realtimeToken").withInput(workspaceInputSchema).withOutput(realtimeTokenSchema).query("drafts").withInput(workspaceInputSchema).withOutput(draftListSchema).mutation("saveDraft").withInput(saveDraftInputSchema).withOutput(draftSavedSchema).mutation("deleteDraft").withInput(deleteDraftInputSchema).withOutput(draftSavedSchema).query("sent").withInput(listSentInputSchema).withOutput(sentPageSchema).query("sidebarLayout").withInput(workspaceInputSchema).withOutput(sidebarLayoutSchema).mutation("editSidebar").withInput(editSidebarInputSchema).withOutput(sidebarLayoutSchema).mutation("star").withInput(starInputSchema).withOutput(starStatusSchema).query("starred").withInput(workspaceInputSchema).withOutput(starredListSchema).mutation("scrubSecrets").withInput(scrubChatInputSchema).withOutput(chatScrubReportSchema).mutation("restoreScrubbed").withInput(messageInputSchema).withOutput(messageSchema).build();
59454
59538
  var chatScheduledTrpc = defineTrpcContract("chat").mutation("scheduleMessage").withInput(scheduleMessageInputSchema).withOutput(scheduledMessageSchema).query("scheduled").withInput(listScheduledInputSchema).withOutput(scheduledListSchema).mutation("editScheduled").withInput(editScheduledInputSchema).withOutput(scheduledMessageSchema).mutation("sendScheduledNow").withInput(scheduledInputSchema).withOutput(scheduledMessageSchema).mutation("cancelScheduled").withInput(scheduledInputSchema).withOutput(scheduledMessageSchema).build();
@@ -60582,8 +60666,21 @@ var finishVaultDeviceEnrolmentInputSchemaDefinition = external_exports.object({
60582
60666
  /** P-256 SPKI DER; signs approvals of later devices. */
60583
60667
  signingPublicKey: base64Url,
60584
60668
  /** DER ECDSA over nativeSignedMessage({ purpose: "enrol", challenge }). */
60585
- signature: base64Url
60586
- }).optional()
60669
+ signature: base64Url,
60670
+ /** The same for one install of the app, through Face ID changes; named on a re-enrol. */
60671
+ installId: external_exports.string().min(8).max(128).optional(),
60672
+ /** Required for ios_secure_enclave: DCAppAttestService over appAttestClientData(...). */
60673
+ appAttest: external_exports.object({
60674
+ /** The App Attest key id as iOS returns it (standard base64 of the key's SHA-256). */
60675
+ keyId: external_exports.string().min(1).max(64),
60676
+ /** The CBOR attestation object, base64url. */
60677
+ attestation: base64Url
60678
+ }).optional()
60679
+ }).optional(),
60680
+ /** A re-enrol from the same install: the device it replaces, retired when this one is stored. */
60681
+ replacesDeviceId: external_exports.string().min(1).optional(),
60682
+ /** A fresh reauth proof; required with replacesDeviceId and spent by it. */
60683
+ reauthToken: external_exports.string().min(1).optional()
60587
60684
  });
60588
60685
  var finishVaultDeviceEnrolmentInputSchema = finishVaultDeviceEnrolmentInputSchemaDefinition;
60589
60686
  var sealedRecipientSchema = external_exports.object({
@@ -60673,7 +60770,9 @@ var answerSealedApprovalInputSchemaDefinition = external_exports.object({
60673
60770
  release: external_exports.object({ epk: base64Url, ciphertext: base64Url }),
60674
60771
  via: external_exports.enum(["feed", "channel", "ios", "desktop", "web"]).default("web"),
60675
60772
  /** Allow for this agent for this long: runs with the same key reuse the release until then. */
60676
- durationSeconds: external_exports.number().int().positive().optional()
60773
+ durationSeconds: external_exports.number().int().positive().optional(),
60774
+ /** The active device that opened the secret; removing it ends this release and its lease. */
60775
+ approverDeviceId: external_exports.string().min(1).optional()
60677
60776
  });
60678
60777
  var answerSealedApprovalInputSchema = answerSealedApprovalInputSchemaDefinition;
60679
60778
  var vaultRunSealedReleaseSchemaDefinition = external_exports.object({
@@ -61199,6 +61298,8 @@ var vaultApprovalStateSchema = external_exports.enum([
61199
61298
  "denied",
61200
61299
  "expired"
61201
61300
  ]);
61301
+ var vaultApprovalListStateSchemaDefinition = external_exports.union([vaultApprovalStateSchema, external_exports.literal("withdrawn")]).transform((state) => state === "withdrawn" ? "expired" : state);
61302
+ var vaultApprovalListStateSchema = vaultApprovalListStateSchemaDefinition;
61202
61303
  var vaultAnswerViaSchema = external_exports.enum(["feed", "channel", "ios", "desktop", "web"]);
61203
61304
  var vaultApprovalRequestSchemaDefinition = external_exports.object({
61204
61305
  id: external_exports.string(),
@@ -61228,7 +61329,9 @@ var vaultApprovalRequestSchemaDefinition = external_exports.object({
61228
61329
  /** The connection's title, so an approver who cannot list it still knows what is asked. */
61229
61330
  connectionTitle: external_exports.string().nullable().default(null),
61230
61331
  /** The longest lease Allow for this agent offers; null offers only once and deny. */
61231
- maxLeaseSeconds: external_exports.number().int().positive().nullable().default(null)
61332
+ maxLeaseSeconds: external_exports.number().int().positive().nullable().default(null),
61333
+ /** Allow covers the rest of the agent's turn ("Allow for this task"), not one command. */
61334
+ coversTask: external_exports.boolean().optional()
61232
61335
  });
61233
61336
  var vaultApprovalRequestSchema = vaultApprovalRequestSchemaDefinition;
61234
61337
  var answerVaultApprovalInputSchemaDefinition = external_exports.object({
@@ -61446,7 +61549,7 @@ var vaultTrpc = defineTrpcContract("vault").mutation("createConnection").withInp
61446
61549
  reason: external_exports.string().trim().min(1).max(200),
61447
61550
  reauthToken: external_exports.string().min(1).max(200).optional()
61448
61551
  })
61449
- ).withOutput(external_exports.object({ fields: external_exports.record(external_exports.string(), external_exports.string()) })).mutation("beginReauth").withInput(workspaceInput).withOutput(vaultReauthChallengeSchema).mutation("confirmReauth").withInput(confirmVaultReauthInputSchema).withOutput(vaultReauthProofSchema).mutation("grantConnection").withInput(grantVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("lendToChannel").withInput(lendVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("revokeGrant").withInput(revokeVaultGrantInputSchema).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("listGrants").withInput(connectionInput).withOutput(external_exports.array(vaultGrantSchema)).mutation("shareConnection").withInput(shareVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("approveShare").withInput(approveVaultShareInputSchema).withOutput(vaultGrantSchema).mutation("sealConnection").withInput(sealVaultConnectionInputSchema).withOutput(vaultConnectionSchema).query("listApprovals").withInput(external_exports.object({ ...workspaceInput.shape, state: vaultApprovalStateSchema.optional() })).withOutput(external_exports.array(vaultApprovalRequestSchema)).mutation("answerApproval").withInput(answerVaultApprovalInputSchema).withOutput(vaultApprovalRequestSchema).query("listAudit").withInput(vaultAuditReadInputSchema).withOutput(vaultAuditPageSchema).query("listActivity").withInput(vaultAuditReadInputSchema).withOutput(external_exports.array(vaultAuditEntrySchema)).query("listLeases").withInput(workspaceInput).withOutput(external_exports.array(vaultLeaseSchema)).mutation("endLease").withInput(endVaultLeaseInputSchema).withOutput(external_exports.object({ ended: external_exports.literal(true) })).query("mostAsked").withInput(vaultMostAskedInputSchema).withOutput(vaultMostAskedSchema).query("judgeStatus").withInput(workspaceInput).withOutput(vaultJudgeStatusSchema).query("listLevelLimits").withInput(workspaceInput).withOutput(external_exports.array(vaultLevelLimitSchema)).mutation("setLevelLimit").withInput(setVaultLevelLimitInputSchema).withOutput(external_exports.array(vaultLevelLimitSchema)).query("listDevices").withInput(workspaceInput).withOutput(external_exports.array(vaultDeviceSchema)).mutation("beginDeviceEnrolment").withInput(workspaceInput).withOutput(vaultDeviceEnrolmentSchema).mutation("finishDeviceEnrolment").withInput(finishVaultDeviceEnrolmentInputSchema).withOutput(vaultDeviceSchema).mutation("beginDeviceApproval").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ challenge: external_exports.string(), sealed: external_exports.array(vaultSealedMaterialSchema) })).mutation("approveDevice").withInput(approveVaultDeviceInputSchema).withOutput(vaultDeviceSchema).mutation("removeDevice").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ removed: external_exports.literal(true) })).mutation("createSealedConnection").withInput(createSealedConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("resealConnection").withInput(resealConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("openSealedConnection").withInput(
61552
+ ).withOutput(external_exports.object({ fields: external_exports.record(external_exports.string(), external_exports.string()) })).mutation("beginReauth").withInput(workspaceInput).withOutput(vaultReauthChallengeSchema).mutation("confirmReauth").withInput(confirmVaultReauthInputSchema).withOutput(vaultReauthProofSchema).mutation("grantConnection").withInput(grantVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("lendToChannel").withInput(lendVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("revokeGrant").withInput(revokeVaultGrantInputSchema).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("listGrants").withInput(connectionInput).withOutput(external_exports.array(vaultGrantSchema)).mutation("shareConnection").withInput(shareVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("approveShare").withInput(approveVaultShareInputSchema).withOutput(vaultGrantSchema).mutation("sealConnection").withInput(sealVaultConnectionInputSchema).withOutput(vaultConnectionSchema).query("listApprovals").withInput(external_exports.object({ ...workspaceInput.shape, state: vaultApprovalListStateSchema.optional() })).withOutput(external_exports.array(vaultApprovalRequestSchema)).mutation("answerApproval").withInput(answerVaultApprovalInputSchema).withOutput(vaultApprovalRequestSchema).query("listAudit").withInput(vaultAuditReadInputSchema).withOutput(vaultAuditPageSchema).query("listActivity").withInput(vaultAuditReadInputSchema).withOutput(external_exports.array(vaultAuditEntrySchema)).query("listLeases").withInput(workspaceInput).withOutput(external_exports.array(vaultLeaseSchema)).mutation("endLease").withInput(endVaultLeaseInputSchema).withOutput(external_exports.object({ ended: external_exports.literal(true) })).query("mostAsked").withInput(vaultMostAskedInputSchema).withOutput(vaultMostAskedSchema).query("judgeStatus").withInput(workspaceInput).withOutput(vaultJudgeStatusSchema).query("listLevelLimits").withInput(workspaceInput).withOutput(external_exports.array(vaultLevelLimitSchema)).mutation("setLevelLimit").withInput(setVaultLevelLimitInputSchema).withOutput(external_exports.array(vaultLevelLimitSchema)).query("listDevices").withInput(workspaceInput).withOutput(external_exports.array(vaultDeviceSchema)).mutation("beginDeviceEnrolment").withInput(workspaceInput).withOutput(vaultDeviceEnrolmentSchema).mutation("finishDeviceEnrolment").withInput(finishVaultDeviceEnrolmentInputSchema).withOutput(vaultDeviceSchema).mutation("beginDeviceApproval").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ challenge: external_exports.string(), sealed: external_exports.array(vaultSealedMaterialSchema) })).mutation("approveDevice").withInput(approveVaultDeviceInputSchema).withOutput(vaultDeviceSchema).mutation("removeDevice").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ removed: external_exports.literal(true) })).mutation("createSealedConnection").withInput(createSealedConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("resealConnection").withInput(resealConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("openSealedConnection").withInput(
61450
61553
  external_exports.object({
61451
61554
  ...connectionInput.shape,
61452
61555
  reason: external_exports.string().trim().min(1).max(200),
@@ -61478,6 +61581,8 @@ var vaultConfig = Config.define((c) => ({
61478
61581
  "VAULT_PREVIOUS_KEY_GRACE_MINUTES",
61479
61582
  external_exports.coerce.number().int().min(0).default(30)
61480
61583
  ),
61584
+ /** iPhone enrolment without App Attest (simulator); applies only off a public origin. */
61585
+ appAttestDev: c.env("VAULT_APP_ATTEST_DEV", environmentBooleanSchema.default(false)),
61481
61586
  /** The origin passkeys are made on; unset accepts any localhost origin, for development. */
61482
61587
  publicBaseUrl,
61483
61588
  /** A file each audit chain head is appended to as a JSON line; unset only logs the heads. */
@@ -61561,7 +61666,9 @@ var vaultApprovalRequestedPayloadSchemaDefinition = external_exports.object({
61561
61666
  /** Sealed to the owner's devices: Allow goes through the device's passkey, deny does not. */
61562
61667
  sealed: external_exports.boolean().default(false),
61563
61668
  /** For a send, the message it would send, read from the provider. */
61564
- draft: vaultDraftPreviewSchema.nullable().default(null)
61669
+ draft: vaultDraftPreviewSchema.nullable().default(null),
61670
+ /** Allow covers the rest of the agent's turn ("Allow for this task"), not one command. */
61671
+ coversTask: external_exports.boolean().optional()
61565
61672
  });
61566
61673
  var vaultApprovalResolvedPayloadSchemaDefinition = external_exports.object({
61567
61674
  workspaceId: external_exports.string().min(1),
@@ -61580,6 +61687,10 @@ var vaultApprovalResolvedPayloadSchemaDefinition = external_exports.object({
61580
61687
  answeredByName: external_exports.string().default(""),
61581
61688
  /** A deny or a timeout: until when the same action is refused without a new card. */
61582
61689
  blockedUntil: external_exports.iso.datetime().nullable().default(null),
61690
+ /** An expired card closed because the agent's turn that asked ended; nothing is blocked. */
61691
+ endedWithTurn: external_exports.boolean().optional(),
61692
+ /** A task card: its Allow covered the rest of the agent's turn. */
61693
+ coversTask: external_exports.boolean().optional(),
61583
61694
  /** Who decides the card, so their open approvals lists refresh. */
61584
61695
  approverUserIds: external_exports.array(external_exports.string()).readonly().default([])
61585
61696
  });
@@ -66131,7 +66242,9 @@ var callerWorkspaceMemberSchemaDefinition = external_exports.object({
66131
66242
  email: external_exports.string(),
66132
66243
  name: external_exports.string(),
66133
66244
  role: roleSchema,
66134
- joinedAt: external_exports.iso.datetime()
66245
+ joinedAt: external_exports.iso.datetime(),
66246
+ /** Other names they go by in the workspace; absent or empty without any. */
66247
+ aliases: external_exports.array(external_exports.string()).optional()
66135
66248
  });
66136
66249
  var callerWorkspaceInviteSchemaDefinition = external_exports.object({
66137
66250
  id: external_exports.string().min(1),
@@ -66173,6 +66286,9 @@ var decideRequestAsCallerInputSchemaDefinition = external_exports.object({
66173
66286
  requestId: external_exports.string().trim().min(1).max(80),
66174
66287
  decision: external_exports.enum(["approved", "denied"])
66175
66288
  });
66289
+ var setAliasesAsCallerInputSchemaDefinition = external_exports.object({
66290
+ aliases: external_exports.array(external_exports.string().trim().max(40)).max(5)
66291
+ });
66176
66292
  var renameWorkspaceAsCallerInputSchemaDefinition = external_exports.object({
66177
66293
  name: external_exports.string().trim().min(1).max(80)
66178
66294
  });
@@ -67240,6 +67356,10 @@ var slackProfilesSchemaDefinition = external_exports.object({
67240
67356
  profiles: external_exports.array(slackProfileSchemaDefinition)
67241
67357
  });
67242
67358
  var slackProfilesSchema = slackProfilesSchemaDefinition;
67359
+ var slackLinkedNamesSchemaDefinition = external_exports.object({
67360
+ people: external_exports.array(external_exports.object({ personId: external_exports.string().min(1), names: external_exports.array(external_exports.string()) }))
67361
+ });
67362
+ var slackLinkedNamesSchema = slackLinkedNamesSchemaDefinition;
67243
67363
 
67244
67364
  // ../../modules/slack/contract/src/slack-setup.ts
67245
67365
  var workspaceIdSchema13 = external_exports.string().min(1);
@@ -67608,7 +67728,7 @@ var slackSearchAnswerSchemaDefinition = external_exports.object({
67608
67728
  var slackSearchAnswerSchema = slackSearchAnswerSchemaDefinition;
67609
67729
  var SlackApi = moduleApi()("slack");
67610
67730
  var workspaceInput3 = external_exports.object({ workspaceId: workspaceIdSchema14 });
67611
- var slackTrpc = defineTrpcContract("slack").query("overview").withInput(workspaceInput3).withOutput(slackOverviewSchema).mutation("startSetup").withInput(startSlackSetupInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("beginSetup").withInput(beginSlackSetupInputSchema).withOutput(slackSetupSchema).mutation("saveAppCredentials").withInput(saveSlackAppCredentialsInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("installApp").withInput(installSlackAppInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startInstall").withInput(startSlackInstallInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startLink").withInput(startSlackLinkInputSchema).withOutput(startedSlackAuthorizeSchema).query("channels").withInput(slackTeamInputSchema).withOutput(external_exports.array(slackChannelViewSchema)).mutation("setMirror").withInput(setSlackMirrorInputSchema).withOutput(slackConnectionViewSchema).mutation("updateConnection").withInput(updateSlackConnectionInputSchema).withOutput(slackConnectionViewSchema).mutation("disconnect").withInput(slackTeamInputSchema).withOutput(external_exports.object({ disconnected: external_exports.literal(true) })).mutation("unlink").withInput(slackTeamInputSchema).withOutput(slackConnectionViewSchema).query("linkPrompts").withInput(workspaceInput3).withOutput(slackLinkPromptsSchema).mutation("dismissLinkPrompt").withInput(dismissSlackLinkPromptInputSchema).withOutput(slackLinkPromptsSchema).query("people").withInput(slackPeopleInputSchema).withOutput(slackPeopleSchema).query("bookmarks").withInput(slackBookmarksInputSchema).withOutput(slackBookmarksSchema).query("profiles").withInput(slackProfilesInputSchema).withOutput(slackProfilesSchema).mutation("openDirect").withInput(openSlackDirectInputSchema).withOutput(openedSlackDirectSchema).mutation("updateApp").withInput(updateSlackAppInputSchema).withOutput(external_exports.object({ updated: external_exports.literal(true) })).query("history").withInput(slackHistoryInputSchema).withOutput(slackHistoryPageSchema).query("search").withInput(slackSearchInputSchema).withOutput(slackSearchAnswerSchema).query("movePreview").withInput(slackMoveChannelInputSchema).withOutput(slackMovePreviewSchema).mutation("startMoves").withInput(startSlackMovesInputSchema).withOutput(startedSlackMovesSchema).mutation("cancelMove").withInput(slackMoveInputSchema).withOutput(slackMoveViewSchema).query("moves").withInput(workspaceInput3).withOutput(slackMovesSchema).build();
67731
+ var slackTrpc = defineTrpcContract("slack").query("overview").withInput(workspaceInput3).withOutput(slackOverviewSchema).mutation("startSetup").withInput(startSlackSetupInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("beginSetup").withInput(beginSlackSetupInputSchema).withOutput(slackSetupSchema).mutation("saveAppCredentials").withInput(saveSlackAppCredentialsInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("installApp").withInput(installSlackAppInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startInstall").withInput(startSlackInstallInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startLink").withInput(startSlackLinkInputSchema).withOutput(startedSlackAuthorizeSchema).query("channels").withInput(slackTeamInputSchema).withOutput(external_exports.array(slackChannelViewSchema)).mutation("setMirror").withInput(setSlackMirrorInputSchema).withOutput(slackConnectionViewSchema).mutation("updateConnection").withInput(updateSlackConnectionInputSchema).withOutput(slackConnectionViewSchema).mutation("disconnect").withInput(slackTeamInputSchema).withOutput(external_exports.object({ disconnected: external_exports.literal(true) })).mutation("unlink").withInput(slackTeamInputSchema).withOutput(slackConnectionViewSchema).query("linkPrompts").withInput(workspaceInput3).withOutput(slackLinkPromptsSchema).mutation("dismissLinkPrompt").withInput(dismissSlackLinkPromptInputSchema).withOutput(slackLinkPromptsSchema).query("people").withInput(slackPeopleInputSchema).withOutput(slackPeopleSchema).query("bookmarks").withInput(slackBookmarksInputSchema).withOutput(slackBookmarksSchema).query("profiles").withInput(slackProfilesInputSchema).withOutput(slackProfilesSchema).query("linkedNames").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(slackLinkedNamesSchema).mutation("openDirect").withInput(openSlackDirectInputSchema).withOutput(openedSlackDirectSchema).mutation("updateApp").withInput(updateSlackAppInputSchema).withOutput(external_exports.object({ updated: external_exports.literal(true) })).query("history").withInput(slackHistoryInputSchema).withOutput(slackHistoryPageSchema).query("search").withInput(slackSearchInputSchema).withOutput(slackSearchAnswerSchema).query("movePreview").withInput(slackMoveChannelInputSchema).withOutput(slackMovePreviewSchema).mutation("startMoves").withInput(startSlackMovesInputSchema).withOutput(startedSlackMovesSchema).mutation("cancelMove").withInput(slackMoveInputSchema).withOutput(slackMoveViewSchema).query("moves").withInput(workspaceInput3).withOutput(slackMovesSchema).build();
67612
67732
 
67613
67733
  // ../../modules/slack/contract/src/slack-keys.ts
67614
67734
  var SLACK_KEY_PATHS = {
@@ -71069,6 +71189,16 @@ someone an action cannot be done because Laze refused it earlier, run \`laze cha
71069
71189
  again. When a change lifts a refusal you hit in a conversation, tell the people there once that
71070
71190
  it works now.
71071
71191
 
71192
+ ## Browser tabs and sign-ins
71193
+
71194
+ - \`laze browser tabs\` lists the live browser tabs of your conversations. You drive every tab
71195
+ your owner owns from this session (\`laze browser goto|read|cdp <tab>\`); you need no Laze
71196
+ computer and no helper agent. Reuse an open tab by its title instead of opening another.
71197
+ - A site needs a sign-in: \`laze browser ask <tab> "Sign in to <site>"\`. The person signs in on
71198
+ the tab's screen and presses Done, which reaches you as a message (\`--wait\` waits for it).
71199
+ - Only when the person says to use a saved key: \`laze browser login <tab> --vault <connection>\`.
71200
+ Never ask for a password and never write scripts that type one.
71201
+
71072
71202
  If \`laze\` is not on the PATH, run the same commands through \`npx -y @lazehq/cli@latest\`.
71073
71203
  Never print or repeat your Laze key.
71074
71204
  `;
@@ -76620,8 +76750,370 @@ async function billing({ context, args }) {
76620
76750
 
76621
76751
  // src/services/browser-commands.service.ts
76622
76752
  import { randomBytes } from "node:crypto";
76623
- import { mkdir as mkdir17, readFile as readFile17, writeFile as writeFile17 } from "node:fs/promises";
76753
+ import { mkdir as mkdir19, readFile as readFile18, writeFile as writeFile19 } from "node:fs/promises";
76754
+ import { dirname as dirname18, join as join21 } from "node:path";
76755
+
76756
+ // src/services/browser-tab-commands.service.ts
76757
+ import { mkdir as mkdir18, writeFile as writeFile18 } from "node:fs/promises";
76758
+ import { tmpdir as tmpdir3 } from "node:os";
76759
+ import { join as join20 } from "node:path";
76760
+
76761
+ // src/rules/browser-login.rules.ts
76762
+ var PASSWORD_NAME = /pass|pwd/i;
76763
+ var USER_NAME = /user|email|e-mail|login|account|name|^id$|_id$/i;
76764
+ function loginValuesOf({
76765
+ connection,
76766
+ values,
76767
+ userField,
76768
+ passField
76769
+ }) {
76770
+ const names = Object.keys(values).toSorted();
76771
+ const listed = names.join(", ") || "no fields";
76772
+ const refusal = (why) => ({
76773
+ refusal: `laze browser login: ${why}; ${connection} holds ${listed}. Pass --user-field <field> and --pass-field <field>.`
76774
+ });
76775
+ if (userField && values[userField] === void 0)
76776
+ return refusal(`${connection} has no field ${userField}`);
76777
+ if (passField && values[passField] === void 0)
76778
+ return refusal(`${connection} has no field ${passField}`);
76779
+ const passName = passField ?? names.find((name3) => PASSWORD_NAME.test(name3)) ?? (names.length === 1 ? names[0] : void 0);
76780
+ if (passName === void 0) return refusal("no field reads as the password");
76781
+ const userName = userField ?? names.find((name3) => name3 !== passName && USER_NAME.test(name3)) ?? void 0;
76782
+ const password = values[passName] ?? "";
76783
+ if (!password) return refusal(`${passName} is empty`);
76784
+ const username = userName === void 0 ? void 0 : values[userName];
76785
+ return username ? { username, password } : { password };
76786
+ }
76787
+
76788
+ // src/services/vault-commands.service.ts
76789
+ import { createHash as createHash2 } from "node:crypto";
76790
+ import { mkdir as mkdir17, readFile as readFile17, rm as rm9, writeFile as writeFile17 } from "node:fs/promises";
76791
+ import { tmpdir as tmpdir2 } from "node:os";
76624
76792
  import { dirname as dirname17, join as join19 } from "node:path";
76793
+ var USAGE6 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
76794
+ Runs the command with the connection's values in its environment, on a Laze agent's computer,
76795
+ on a machine it runs on, or where a connected agent runs, with its own key.
76796
+ --channel <id> the conversation whose turn it runs in, when the agent answers in several`;
76797
+ var POLL_MS = 3e3;
76798
+ var RESTART_WAIT_MS = 12e4;
76799
+ var RESTART_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 1e4];
76800
+ var P2562 = { name: "ECDH", namedCurve: "P-256" };
76801
+ var ServerGoneError = class extends Error {
76802
+ };
76803
+ function proxyOf({ env }) {
76804
+ const raw = env.LAZE_VAULT_PROXY || env.HTTP_PROXY || env.http_proxy;
76805
+ if (!raw) return null;
76806
+ const url2 = new URL(raw);
76807
+ const user = decodeURIComponent(url2.username);
76808
+ const password = decodeURIComponent(url2.password);
76809
+ return {
76810
+ origin: url2.origin,
76811
+ authorization: `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`
76812
+ };
76813
+ }
76814
+ function turnFileOf({
76815
+ env
76816
+ }) {
76817
+ return env.LAZE_TURN_FILE || void 0;
76818
+ }
76819
+ async function turnTokenOf2({
76820
+ env,
76821
+ turnFile,
76822
+ command = "laze vault run"
76823
+ }) {
76824
+ const pinned = env.LAZE_TURN_TOKEN?.trim();
76825
+ if (pinned) return pinned;
76826
+ if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
76827
+ try {
76828
+ return (await readFile17(turnFile, "utf8")).trim();
76829
+ } catch {
76830
+ throw new CliUsageError(`${command} works only during an agent's turn`);
76831
+ }
76832
+ }
76833
+ function runKeyPathOf({
76834
+ turnFile,
76835
+ connection,
76836
+ profile = ""
76837
+ }) {
76838
+ const name3 = createHash2("sha256").update(connection).digest("hex");
76839
+ const base = turnFile ? dirname17(turnFile) : join19(tmpdir2(), "laze-vault", profile);
76840
+ return join19(base, "vault-run-keys", `${name3}.json`);
76841
+ }
76842
+ async function runKeyAt({ path }) {
76843
+ const saved3 = await readFile17(path, "utf8").then(
76844
+ (text2) => JSON.parse(text2),
76845
+ () => void 0
76846
+ );
76847
+ if (saved3 && typeof saved3.publicKey === "string" && saved3.privateKey) {
76848
+ const privateKey = await globalThis.crypto.subtle.importKey("jwk", saved3.privateKey, P2562, false, ["deriveBits"]).catch(() => void 0);
76849
+ if (privateKey) return { privateKey, publicKey: saved3.publicKey };
76850
+ }
76851
+ const fresh = await generateEcdhKeys();
76852
+ const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
76853
+ await mkdir17(dirname17(path), { recursive: true, mode: 448 });
76854
+ await writeFile17(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
76855
+ mode: 384
76856
+ });
76857
+ return fresh;
76858
+ }
76859
+ function connectionRefused(error62) {
76860
+ const cause = error62.cause;
76861
+ if (cause?.code === "ECONNREFUSED") return true;
76862
+ return cause?.errors?.some((inner) => inner.code === "ECONNREFUSED") ?? false;
76863
+ }
76864
+ async function sendOnce({
76865
+ context,
76866
+ url: url2,
76867
+ init
76868
+ }) {
76869
+ let response;
76870
+ try {
76871
+ response = await context.fetcher(url2, init);
76872
+ } catch (error62) {
76873
+ const wasRefused = connectionRefused(error62);
76874
+ if (init.method === "POST" && !wasRefused) throw error62;
76875
+ return { restarting: wasRefused ? "connection refused" : String(error62) };
76876
+ }
76877
+ if (response.status !== 502 && response.status !== 503) return { response };
76878
+ const code = codeOf(await response.clone().text());
76879
+ const neverReached = response.status === 503 && code === "vault_not_answering";
76880
+ if (init.method === "POST" && !neverReached) return { response };
76881
+ return { restarting: `status ${response.status}${code ? ` ${code}` : ""}` };
76882
+ }
76883
+ async function reach(input2) {
76884
+ const { context } = input2;
76885
+ const started = context.nowMs();
76886
+ for (let attempt = 0; ; attempt += 1) {
76887
+ const sent = await sendOnce(input2);
76888
+ if ("response" in sent) return sent.response;
76889
+ if (context.nowMs() - started >= RESTART_WAIT_MS) {
76890
+ throw new ServerGoneError(
76891
+ `laze vault: the Laze server did not come back (${sent.restarting})`
76892
+ );
76893
+ }
76894
+ if (attempt === 0) {
76895
+ context.err(
76896
+ `laze vault: the Laze server is not answering (${sent.restarting}), probably restarting; waiting up to 2 min...
76897
+ `
76898
+ );
76899
+ }
76900
+ await context.sleep(RESTART_BACKOFF_MS[Math.min(attempt, RESTART_BACKOFF_MS.length - 1)] ?? 0);
76901
+ }
76902
+ }
76903
+ function codeOf(text2) {
76904
+ return /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1];
76905
+ }
76906
+ async function releaseOf({ response }) {
76907
+ const text2 = await response.text();
76908
+ if (!response.ok) {
76909
+ return {
76910
+ outcome: "deny",
76911
+ exitCode: 1,
76912
+ message: `laze vault: the release was refused (${codeOf(text2) ?? `status ${response.status}`})`
76913
+ };
76914
+ }
76915
+ return JSON.parse(text2);
76916
+ }
76917
+ async function envOf({
76918
+ release: release2,
76919
+ run: run4
76920
+ }) {
76921
+ if (!release2.sealed) return release2.env;
76922
+ const sealed = await openRunRelease({
76923
+ release: release2.sealed,
76924
+ runPrivateKey: run4.privateKey,
76925
+ runPublicKey: run4.publicKey,
76926
+ requestId: release2.sealed.requestId
76927
+ });
76928
+ return { ...release2.env, ...sealed };
76929
+ }
76930
+ function deadlineOf({ args, nowMs }) {
76931
+ const wait = flagText({ args, name: "wait" }) || (args.flags.wait === true ? args.words[3] : "");
76932
+ if (!wait) return Infinity;
76933
+ if (!(Number(wait) >= 0)) throw new CliUsageError(`--wait takes a number of seconds
76934
+ ${USAGE6}`);
76935
+ return nowMs + Number(wait) * 1e3;
76936
+ }
76937
+ async function untilAnswered({
76938
+ context,
76939
+ first,
76940
+ next,
76941
+ deadline
76942
+ }) {
76943
+ let release2 = first;
76944
+ while (release2.outcome === "ask") {
76945
+ if (context.nowMs() + POLL_MS > deadline) {
76946
+ context.err(`${release2.message}. Not approved yet; ask again later.
76947
+ `);
76948
+ return "capped";
76949
+ }
76950
+ if (release2 === first) {
76951
+ context.err(`${release2.message}. Waiting for an answer (cards expire after 12 hours)...
76952
+ `);
76953
+ }
76954
+ await context.sleep(POLL_MS);
76955
+ release2 = await next(release2.requestId);
76956
+ }
76957
+ return release2;
76958
+ }
76959
+ function leaseHolds({
76960
+ release: release2,
76961
+ nowMs
76962
+ }) {
76963
+ const ends = release2.sealed?.leaseEndsAt;
76964
+ return ends !== void 0 && Temporal3.Instant.from(ends).epochMilliseconds > nowMs;
76965
+ }
76966
+ async function vaultRelease({
76967
+ context,
76968
+ args,
76969
+ connection,
76970
+ reason,
76971
+ command
76972
+ }) {
76973
+ const deadline = deadlineOf({ args, nowMs: context.nowMs() });
76974
+ const env = context.environment.inherited;
76975
+ const proxy = proxyOf({ env });
76976
+ if (!proxy) return keyRelease({ context, args, connection, reason, command, deadline });
76977
+ const turnFile = turnFileOf({ env });
76978
+ const headers = {
76979
+ "proxy-authorization": proxy.authorization,
76980
+ "x-laze-turn": await turnTokenOf2({ env, turnFile })
76981
+ };
76982
+ const keyPath = runKeyPathOf({ turnFile, connection });
76983
+ const run4 = await runKeyAt({ path: keyPath });
76984
+ const body = JSON.stringify({ connection, reason, command, recipient: run4.publicKey });
76985
+ let release2;
76986
+ try {
76987
+ const first = await releaseOf({
76988
+ response: await reach({
76989
+ context,
76990
+ url: `${proxy.origin}/vault/release`,
76991
+ init: { method: "POST", headers: { ...headers, "content-type": "application/json" }, body }
76992
+ })
76993
+ });
76994
+ const next = async (requestId) => releaseOf({
76995
+ response: await reach({
76996
+ context,
76997
+ url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
76998
+ init: { method: "GET", headers }
76999
+ })
77000
+ });
77001
+ release2 = await untilAnswered({ context, first, next, deadline });
77002
+ } catch (error62) {
77003
+ if (!(error62 instanceof ServerGoneError)) throw error62;
77004
+ context.err(`${error62.message}. Run the command again to keep waiting.
77005
+ `);
77006
+ return { exitCode: 75 };
77007
+ }
77008
+ return settled({ context, release: release2, run: run4, keyPath });
77009
+ }
77010
+ async function settled({
77011
+ context,
77012
+ release: release2,
77013
+ run: run4,
77014
+ keyPath
77015
+ }) {
77016
+ if (release2 === "capped") return { exitCode: 75 };
77017
+ if (release2.outcome === "deny") {
77018
+ await rm9(keyPath, { force: true });
77019
+ context.err(`${release2.message}
77020
+ `);
77021
+ return { exitCode: release2.exitCode || 1 };
77022
+ }
77023
+ const values = await envOf({ release: release2, run: run4 });
77024
+ if (!leaseHolds({ release: release2, nowMs: context.nowMs() })) await rm9(keyPath, { force: true });
77025
+ if (release2.message) context.err(`${release2.message}
77026
+ `);
77027
+ return { env: values };
77028
+ }
77029
+ function refusedRelease(error62) {
77030
+ if (!(error62 instanceof LazeApiError)) throw error62;
77031
+ return {
77032
+ outcome: "deny",
77033
+ exitCode: 1,
77034
+ message: `laze vault: the release was refused: ${error62.message} (${error62.code})`
77035
+ };
77036
+ }
77037
+ async function keyRelease({
77038
+ context,
77039
+ args,
77040
+ connection,
77041
+ reason,
77042
+ command,
77043
+ deadline
77044
+ }) {
77045
+ const where = new CliUsageError(
77046
+ "laze vault run works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent"
77047
+ );
77048
+ const signed2 = await signedIn({ context, args }).catch(() => null);
77049
+ if (signed2?.profile.kind !== "agent") throw where;
77050
+ const { client, name: name3 } = signed2;
77051
+ const channelId = flagText({ args, name: "channel" }) || null;
77052
+ const keyPath = runKeyPathOf({ turnFile: void 0, connection, profile: name3 });
77053
+ const run4 = await runKeyAt({ path: keyPath });
77054
+ const first = await client.post("/api/agents/me/vault/release", {
77055
+ connection,
77056
+ reason,
77057
+ command,
77058
+ recipient: run4.publicKey,
77059
+ channelId
77060
+ }).catch(refusedRelease);
77061
+ const next = (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease);
77062
+ const release2 = await untilAnswered({ context, first, next, deadline });
77063
+ return settled({ context, release: release2, run: run4, keyPath });
77064
+ }
77065
+ async function vaultRun({
77066
+ context,
77067
+ args
77068
+ }) {
77069
+ const connection = args.words[2];
77070
+ const reason = flagText({ args, name: "reason" });
77071
+ if (!connection || args.rest.length === 0) throw new CliUsageError(USAGE6);
77072
+ if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
77073
+ ${USAGE6}`);
77074
+ const foreign = commandReferenceNames({ command: args.rest }).find(
77075
+ (name3) => vaultReferenceConnectionName({ name: name3 }) !== connection
77076
+ );
77077
+ if (foreign !== void 0) {
77078
+ const named = vaultReferenceConnectionName({ name: foreign });
77079
+ context.err(
77080
+ `laze vault: the command names {{vault:${foreign}}}, but this run releases only ${connection}, not ${named}. Nothing was asked and the command did not run.
77081
+ `
77082
+ );
77083
+ return 1;
77084
+ }
77085
+ const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
77086
+ if ("exitCode" in released) return released.exitCode;
77087
+ const prepared = preparedCommand({
77088
+ command: args.rest,
77089
+ released: /* @__PURE__ */ new Map([[connection, released.env]])
77090
+ });
77091
+ if ("refusal" in prepared) {
77092
+ context.err(`${prepared.refusal}
77093
+ `);
77094
+ return 1;
77095
+ }
77096
+ const redact = secretValuesOf({ fields: released.env });
77097
+ return context.runCommand({ command: prepared.command, env: released.env, redact });
77098
+ }
77099
+ function preparedCommand({
77100
+ command,
77101
+ released
77102
+ }) {
77103
+ for (const [name3, fields] of released) {
77104
+ const [problem] = unusableFieldProblems({ fields });
77105
+ if (problem !== void 0) {
77106
+ return {
77107
+ refusal: `laze vault: ${name3}: ${problem}, so the command did not run. Ask its owner to save the real value on the vault page.`
77108
+ };
77109
+ }
77110
+ }
77111
+ const filled = fillCommandReferences({ command, released });
77112
+ if ("refusal" in filled) {
77113
+ return { refusal: `laze vault: ${filled.refusal}. The command did not run.` };
77114
+ }
77115
+ return filled;
77116
+ }
76625
77117
 
76626
77118
  // src/services/browser-tab-commands.service.ts
76627
77119
  var BROWSER_TAB_PATHS = {
@@ -76633,19 +77125,30 @@ var BROWSER_TAB_PATHS = {
76633
77125
  ask: "/api/compute/browser-tabs/ask",
76634
77126
  share: "/api/compute/browser-tabs/share",
76635
77127
  close: "/api/compute/browser-tabs/close",
76636
- cdp: "/api/compute/browser-tabs/cdp"
77128
+ cdp: "/api/compute/browser-tabs/cdp",
77129
+ login: "/api/compute/browser-tabs/login"
76637
77130
  };
77131
+ var ASK_WAIT_SECONDS = 15 * 60;
77132
+ var ASK_POLL_MS = 3e3;
76638
77133
  var BROWSER_TAB_USAGE = [
76639
77134
  "Usage: laze browser open <url> [--title <title>] [--channel <channel>] a live browser tab in the conversation",
76640
77135
  " laze browser tabs [--channel <channel>] the conversation's browser tabs",
76641
77136
  " laze browser tab <tab> one tab: its owner, sharing and page",
76642
77137
  " laze browser goto <tab> <url> send the tab to another page",
76643
77138
  " laze browser read <tab> the page's address, title and text",
76644
- " laze browser ask <tab> <what> ask the person you work for to sign in or click something there",
77139
+ " laze browser ask <tab> <what> [--wait[=<seconds>]] ask the person you work for to sign in or click something there",
77140
+ " laze browser login <tab> --vault <connection> [--reason <why>] [--user-field <field> --pass-field <field>]",
77141
+ " [--user-input <css> --pass-input <css>] type a saved sign-in into the page and submit it",
76645
77142
  " laze browser cdp <tab> a CDP address on the tab's browser",
76646
77143
  " laze browser share <tab> private|watch|use who sees the screen and who types into it",
76647
77144
  " laze browser close <tab> unpin the tab and close its browser",
76648
- "A tab is named by its id or its title."
77145
+ "A tab is named by its id or its title. Opening a title that is already open reuses that tab.",
77146
+ "Any agent working for the tab's owner drives it, connected agents (Claude Code, Codex) from",
77147
+ "their own session included; no Laze computer is needed. Another person's agent cannot.",
77148
+ "Sign-ins: ask the person in the tab first (`laze browser ask`); they sign in on the screen and",
77149
+ "press Done, which reaches you at once. Use `laze browser login --vault` only when the person",
77150
+ "says to use a saved key; a code or emailed link it meets becomes a request to them in the tab.",
77151
+ "Never write scripts that type passwords."
76649
77152
  ].join("\n");
76650
77153
  var SHARING = /* @__PURE__ */ new Set(["private", "watch", "use"]);
76651
77154
  function channelOf({ context, args }) {
@@ -76677,6 +77180,12 @@ async function openTab({ args, client, channel, print: print9 }) {
76677
77180
  ...title ? { title } : {},
76678
77181
  ...channel
76679
77182
  });
77183
+ if (tab.reused)
77184
+ return print9(
77185
+ tab,
77186
+ `Reused ${tab.title} (${tab.id}), ${tab.ownerName}'s browser tab already open, and sent it to ${tab.url}
77187
+ `
77188
+ );
76680
77189
  print9(
76681
77190
  tab,
76682
77191
  `Opened ${tab.title} (${tab.id}) in ${tab.ownerName}'s browser, pinned as a tab of the conversation.
@@ -76714,17 +77223,134 @@ async function readTab({ args, client, channel, print: print9 }) {
76714
77223
  });
76715
77224
  print9(page, pageText({ page }));
76716
77225
  }
76717
- async function askOnTab({ args, client, channel, print: print9 }) {
77226
+ async function askOnTab(run4) {
77227
+ const { args, client, channel, print: print9 } = run4;
76718
77228
  const tab = word({ args, at: 2 });
76719
77229
  const text2 = args.words.slice(3).join(" ").trim();
76720
77230
  if (!text2) throw new CliUsageError(BROWSER_TAB_USAGE);
76721
77231
  const asked = await client.post(BROWSER_TAB_PATHS.ask, { tab, text: text2, ...channel });
76722
- print9(
76723
- asked,
76724
- `Asked ${asked.ask?.userName ?? asked.ownerName} in the conversation; the tab shows them your request with Done.
77232
+ const who = asked.ask?.userName ?? asked.ownerName;
77233
+ if (args.flags.wait === void 0)
77234
+ return print9(
77235
+ asked,
77236
+ `Asked ${who} in the conversation; the tab shows them your request full screen with "Done, hand back".
76725
77237
  Wait for their "Done" message before you go on in ${asked.title}.
77238
+ `
77239
+ );
77240
+ run4.context.err(`Asked ${who} in the conversation; waiting for their Done...
77241
+ `);
77242
+ return waitForDone({ run: run4, tab: asked, who });
77243
+ }
77244
+ async function waitForDone({
77245
+ run: run4,
77246
+ tab,
77247
+ who
77248
+ }) {
77249
+ const { context, args, client, channel, print: print9 } = run4;
77250
+ const seconds = Number(flagText({ args, name: "wait" }) || ASK_WAIT_SECONDS);
77251
+ if (!(seconds > 0)) throw new CliUsageError(BROWSER_TAB_USAGE);
77252
+ const deadline = context.nowMs() + seconds * 1e3;
77253
+ while (context.nowMs() < deadline) {
77254
+ await context.sleep(Math.min(ASK_POLL_MS, Math.max(0, deadline - context.nowMs())));
77255
+ const now = await client.post(BROWSER_TAB_PATHS.get, { tab: tab.id, ...channel });
77256
+ if (!now.ask) return print9(now, `${who} pressed Done. ${now.title} shows ${now.url}
77257
+ `);
77258
+ }
77259
+ print9(
77260
+ tab,
77261
+ `${who} has not pressed Done yet; the request stays open. Wait for their "Done" message.
76726
77262
  `
76727
77263
  );
77264
+ return 75;
77265
+ }
77266
+ async function loginOnTab(run4) {
77267
+ const { context, args, client, channel, json: json5 } = run4;
77268
+ const tab = word({ args, at: 2 });
77269
+ const connection = flagText({ args, name: "vault" });
77270
+ if (!connection)
77271
+ throw new CliUsageError(
77272
+ `Name the saved sign-in with --vault <connection>
77273
+ ${BROWSER_TAB_USAGE}`
77274
+ );
77275
+ const reason = flagText({ args, name: "reason" }) || `Sign in on the ${tab} browser tab of the conversation`;
77276
+ const released = await vaultRelease({
77277
+ context,
77278
+ args,
77279
+ connection,
77280
+ reason,
77281
+ command: ["laze", "browser", "login", tab]
77282
+ });
77283
+ if ("exitCode" in released) return released.exitCode;
77284
+ const [problem] = unusableFieldProblems({ fields: released.env });
77285
+ if (problem !== void 0) {
77286
+ context.err(`laze browser login: ${connection}: ${problem}. Nothing was typed.
77287
+ `);
77288
+ return 1;
77289
+ }
77290
+ const values = loginValuesOf({
77291
+ connection,
77292
+ values: released.env,
77293
+ userField: flagText({ args, name: "user-field" }) || void 0,
77294
+ passField: flagText({ args, name: "pass-field" }) || void 0
77295
+ });
77296
+ if ("refusal" in values) {
77297
+ context.err(`${values.refusal}
77298
+ `);
77299
+ return 1;
77300
+ }
77301
+ const userInput = flagText({ args, name: "user-input" });
77302
+ const passInput = flagText({ args, name: "pass-input" });
77303
+ const answer4 = await client.post(BROWSER_TAB_PATHS.login, {
77304
+ tab,
77305
+ ...values,
77306
+ ...userInput ? { userInput } : {},
77307
+ ...passInput ? { passInput } : {},
77308
+ ...channel
77309
+ });
77310
+ const screenshotPath = answer4.screenshot ? await savedScreenshot({
77311
+ tabId: answer4.tabId,
77312
+ data: answer4.screenshot,
77313
+ nowMs: context.nowMs()
77314
+ }) : null;
77315
+ const { screenshot: _shown, ...rest } = answer4;
77316
+ if (json5) context.out(`${JSON.stringify({ ...rest, screenshotPath }, null, 2)}
77317
+ `);
77318
+ else context.out(loginText({ answer: answer4, tab, screenshotPath }));
77319
+ return answer4.state === "refused" || answer4.state === "still_on_form" ? 1 : 0;
77320
+ }
77321
+ function loginText({
77322
+ answer: answer4,
77323
+ tab,
77324
+ screenshotPath
77325
+ }) {
77326
+ const page = `${answer4.title || "(no title)"}
77327
+ ${answer4.url}
77328
+ `;
77329
+ const shot = screenshotPath ? `Screenshot: ${screenshotPath}
77330
+ ` : "";
77331
+ if (answer4.state === "signed_in") return `Signed in.
77332
+ ${page}${shot}`;
77333
+ if (answer4.state === "second_step")
77334
+ return `The site asks for a second step (a code or an emailed link). Asked ${answer4.askedUserName ?? "the person"} in the conversation to finish it in the tab;
77335
+ wait for their "Done" message before you go on.
77336
+ ${page}${shot}`;
77337
+ if (answer4.state === "refused")
77338
+ return `The site refused the sign-in: ${answer4.error ?? "no reason shown"}
77339
+ ${page}${shot}`;
77340
+ return `Still on the sign-in page after submitting. Look at the screenshot, then ask the person in the tab:
77341
+ laze browser ask ${tab} "Finish signing in"
77342
+ ${page}${shot}`;
77343
+ }
77344
+ async function savedScreenshot({
77345
+ tabId,
77346
+ data,
77347
+ nowMs
77348
+ }) {
77349
+ const folder = join20(tmpdir3(), "laze-browser");
77350
+ await mkdir18(folder, { recursive: true, mode: 448 });
77351
+ const path = join20(folder, `${tabId.replace(/[^a-zA-Z0-9_-]/g, "_")}-login-${nowMs}.jpg`);
77352
+ await writeFile18(path, Buffer.from(data, "base64"), { mode: 384 });
77353
+ return path;
76728
77354
  }
76729
77355
  async function shareTab({ args, client, channel, print: print9 }) {
76730
77356
  const tab = word({ args, at: 2 });
@@ -76750,6 +77376,7 @@ var TAB_RUNS = {
76750
77376
  goto: gotoTab,
76751
77377
  read: readTab,
76752
77378
  ask: askOnTab,
77379
+ login: loginOnTab,
76753
77380
  share: shareTab,
76754
77381
  close: closeTab
76755
77382
  };
@@ -76763,7 +77390,7 @@ async function browserTab({
76763
77390
  const json5 = Boolean(args.flags.json);
76764
77391
  const print9 = (value, text2) => context.out(json5 ? `${JSON.stringify(value, null, 2)}
76765
77392
  ` : text2);
76766
- await handler({ context, args, client, channel: channelOf({ context, args }), json: json5, print: print9 });
77393
+ return handler({ context, args, client, channel: channelOf({ context, args }), json: json5, print: print9 });
76767
77394
  }
76768
77395
  async function browserTabCdp({
76769
77396
  context,
@@ -77178,7 +77805,7 @@ var PATHS2 = {
77178
77805
  wake: "/api/compute/machines/wake",
77179
77806
  delete: "/api/compute/machines/delete"
77180
77807
  };
77181
- var USAGE6 = [
77808
+ var BROWSER_USAGE = [
77182
77809
  "Usage: laze browser setup <site> [--name <machine>] a machine with Chrome a person signs in on",
77183
77810
  " laze browser setup <site> --on <machine> the same on a person's own machine (laze machine list)",
77184
77811
  " laze browser cdp <machine> a CDP address for this turn (Playwright connectOverCDP)",
@@ -77188,7 +77815,7 @@ var USAGE6 = [
77188
77815
  "",
77189
77816
  BROWSER_TAB_USAGE
77190
77817
  ].join("\n");
77191
- async function turnTokenOf2({
77818
+ async function turnTokenOf3({
77192
77819
  context,
77193
77820
  args,
77194
77821
  client,
@@ -77198,7 +77825,7 @@ async function turnTokenOf2({
77198
77825
  const pinned = env.LAZE_TURN_TOKEN?.trim();
77199
77826
  if (pinned) return pinned;
77200
77827
  if (env.LAZE_TURN_FILE) {
77201
- return readFile17(env.LAZE_TURN_FILE, "utf8").then(
77828
+ return readFile18(env.LAZE_TURN_FILE, "utf8").then(
77202
77829
  (text2) => text2.trim(),
77203
77830
  () => ""
77204
77831
  );
@@ -77211,7 +77838,7 @@ async function computeClient({
77211
77838
  args
77212
77839
  }) {
77213
77840
  const { client, profile } = await signedIn({ context, args });
77214
- const turn = await turnTokenOf2({ context, args, client, agent: profile.kind === "agent" });
77841
+ const turn = await turnTokenOf3({ context, args, client, agent: profile.kind === "agent" });
77215
77842
  return turn ? client.withHeaders({ "x-laze-turn": turn }) : client;
77216
77843
  }
77217
77844
  function siteLine(machine2) {
@@ -77225,12 +77852,12 @@ function statusLine(machine2) {
77225
77852
  }
77226
77853
  function machineArg({ args }) {
77227
77854
  const machine2 = args.words[2];
77228
- if (!machine2) throw new CliUsageError(USAGE6);
77855
+ if (!machine2) throw new CliUsageError(BROWSER_USAGE);
77229
77856
  return machine2;
77230
77857
  }
77231
77858
  async function setup({ context, args }) {
77232
77859
  const site = args.words[2];
77233
- if (!site) throw new CliUsageError(USAGE6);
77860
+ if (!site) throw new CliUsageError(BROWSER_USAGE);
77234
77861
  const name3 = flagText({ args, name: "name" }) || void 0;
77235
77862
  const on = flagText({ args, name: "on" }) || void 0;
77236
77863
  const client = await computeClient({ context, args });
@@ -77288,7 +77915,7 @@ async function answering({
77288
77915
  }
77289
77916
  function bridgeStatePath({ context, machine: machine2 }) {
77290
77917
  const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
77291
- return join19(dirname17(context.environment.configPath), "bridges", `${safe}.json`);
77918
+ return join21(dirname18(context.environment.configPath), "bridges", `${safe}.json`);
77292
77919
  }
77293
77920
  async function bridgePort({
77294
77921
  context,
@@ -77296,7 +77923,7 @@ async function bridgePort({
77296
77923
  access
77297
77924
  }) {
77298
77925
  const path = bridgeStatePath({ context, machine: machine2 });
77299
- const live = await readFile17(path, "utf8").then(
77926
+ const live = await readFile18(path, "utf8").then(
77300
77927
  (text2) => JSON.parse(text2),
77301
77928
  () => void 0
77302
77929
  );
@@ -77309,15 +77936,15 @@ async function bridgePort({
77309
77936
  key,
77310
77937
  ...target
77311
77938
  });
77312
- await mkdir17(dirname17(path), { recursive: true, mode: 448 });
77313
- await writeFile17(path, JSON.stringify({ port, key }), { mode: 384 });
77939
+ await mkdir19(dirname18(path), { recursive: true, mode: 448 });
77940
+ await writeFile19(path, JSON.stringify({ port, key }), { mode: 384 });
77314
77941
  return port;
77315
77942
  }
77316
77943
  async function bridge({ context }) {
77317
77944
  const env = context.environment.inherited;
77318
77945
  const target = env.LAZE_CDP_TARGET;
77319
77946
  const expiresAt = env.LAZE_CDP_EXPIRES_AT;
77320
- if (!target || !expiresAt) throw new CliUsageError(USAGE6);
77947
+ if (!target || !expiresAt) throw new CliUsageError(BROWSER_USAGE);
77321
77948
  let until = Temporal3.Instant.from(expiresAt).epochMilliseconds;
77322
77949
  const running = await startCdpBridge({
77323
77950
  target,
@@ -77374,8 +78001,21 @@ async function change({
77374
78001
  `);
77375
78002
  context.out(statusLine(machine2));
77376
78003
  }
77377
- var TAB_COMMANDS = /* @__PURE__ */ new Set(["open", "tabs", "tab", "goto", "read", "ask", "share", "close"]);
77378
- async function browser({ context, args }) {
78004
+ var TAB_COMMANDS = /* @__PURE__ */ new Set([
78005
+ "open",
78006
+ "tabs",
78007
+ "tab",
78008
+ "goto",
78009
+ "read",
78010
+ "ask",
78011
+ "login",
78012
+ "share",
78013
+ "close"
78014
+ ]);
78015
+ async function browser({
78016
+ context,
78017
+ args
78018
+ }) {
77379
78019
  const command = args.words[1];
77380
78020
  if (command && TAB_COMMANDS.has(command))
77381
78021
  return browserTab({ context, args, client: await computeClient({ context, args }) });
@@ -77386,7 +78026,7 @@ async function browser({ context, args }) {
77386
78026
  if (command === "status") return status3({ context, args });
77387
78027
  if (command === "sleep" || command === "wake" || command === "delete")
77388
78028
  return change({ context, args, path: PATHS2[command] });
77389
- throw new CliUsageError(USAGE6);
78029
+ throw new CliUsageError(BROWSER_USAGE);
77390
78030
  }
77391
78031
 
77392
78032
  // src/rules/channel-format.rules.ts
@@ -77958,7 +78598,7 @@ async function channelSettings({ context, args }) {
77958
78598
  }
77959
78599
 
77960
78600
  // src/services/chat-actions-commands.service.ts
77961
- import { readFile as readFile18 } from "node:fs/promises";
78601
+ import { readFile as readFile19 } from "node:fs/promises";
77962
78602
  import { basename as basename3, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve7 } from "node:path";
77963
78603
 
77964
78604
  // src/rules/file-types.rules.ts
@@ -78040,7 +78680,7 @@ async function uploadFile({
78040
78680
 
78041
78681
  // src/services/thread-wait-commands.service.ts
78042
78682
  var USAGE7 = "Usage: laze thread <message-id> --wait-reply [--timeout <1-3600 seconds>]";
78043
- var POLL_MS = 3e3;
78683
+ var POLL_MS2 = 3e3;
78044
78684
  function timeoutOf({ args }) {
78045
78685
  const seconds = Number(flagText({ args, name: "timeout", fallback: "600" }));
78046
78686
  if (!Number.isInteger(seconds) || seconds < 1 || seconds > 3600) throw new CliUsageError(USAGE7);
@@ -78057,8 +78697,8 @@ async function threadWaitReply({
78057
78697
  const read3 = () => client.post(CHAT_KEY_PATHS.thread, { messageId });
78058
78698
  const seen = new Set((await read3()).replies.map((reply2) => reply2.id));
78059
78699
  const isNew = (reply2) => reply2.author.kind === "person" && !seen.has(reply2.id);
78060
- for (let waited = 0; waited < seconds * 1e3; waited += POLL_MS) {
78061
- await context.sleep(POLL_MS);
78700
+ for (let waited = 0; waited < seconds * 1e3; waited += POLL_MS2) {
78701
+ await context.sleep(POLL_MS2);
78062
78702
  const reply2 = (await read3()).replies.find(isNew);
78063
78703
  if (!reply2) continue;
78064
78704
  const line = `${reply2.seq} ${reply2.id} person ${reply2.author.id} ${reply2.body}
@@ -78296,7 +78936,7 @@ function uploadNameOf({ cwd, path }) {
78296
78936
  }
78297
78937
  var fileUpload = async ({ context, args, client }) => {
78298
78938
  const path = resolve7(context.cwd, wordAt(args, 3));
78299
- const bytes = new Uint8Array(await readFile18(path));
78939
+ const bytes = new Uint8Array(await readFile19(path));
78300
78940
  const answer4 = await uploadFile({
78301
78941
  context,
78302
78942
  client,
@@ -78469,7 +79109,7 @@ async function chatActions({
78469
79109
  }
78470
79110
 
78471
79111
  // src/services/claude-monitor.service.ts
78472
- import { readFile as readFile19, rm as rm9 } from "node:fs/promises";
79112
+ import { readFile as readFile20, rm as rm10 } from "node:fs/promises";
78473
79113
  var MONITOR_IDLE_MS = 3e4;
78474
79114
  var MONITOR_OUTRANKED_MS = 3e3;
78475
79115
  async function deliverOnce({
@@ -78531,7 +79171,7 @@ async function monitorRound(turn) {
78531
79171
  async function release({ context, profile }) {
78532
79172
  const lock = statePathOf({ context, kind: "waiters", profile });
78533
79173
  if ((await holderOf({ path: lock }))?.pid === context.processes.pid)
78534
- await rm9(lock, { force: true });
79174
+ await rm10(lock, { force: true });
78535
79175
  }
78536
79176
  async function monitorHook({ context, args }) {
78537
79177
  const claudePid = await claudePidOf({ context });
@@ -78570,7 +79210,7 @@ async function monitorSessionOf({
78570
79210
  const fromEnv = sessionOf({ context, harness: "claude-code", sessionId });
78571
79211
  if (fromEnv || !claudePid) return fromEnv;
78572
79212
  const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
78573
- return readFile19(path, "utf8").then(
79213
+ return readFile20(path, "utf8").then(
78574
79214
  (text2) => JSON.parse(text2),
78575
79215
  () => void 0
78576
79216
  );
@@ -78607,6 +79247,8 @@ var browserTabDefinition = external_exports.object({
78607
79247
  /** What an agent asked a person to do in the tab, until someone who may answer presses Done. */
78608
79248
  ask: browserTabAskDefinition.nullable(),
78609
79249
  createdAt: external_exports.iso.datetime(),
79250
+ /** Only on an open: an open tab of that title was reused instead of making a second one. */
79251
+ reused: external_exports.boolean().optional(),
78610
79252
  /** What the reader may do: see the screen, type into it, change the tab; asked: the open
78611
79253
  * request names them. */
78612
79254
  you: external_exports.object({
@@ -78654,6 +79296,31 @@ var shareDefinition = external_exports.object({
78654
79296
  sharing: browserTabSharingSchema
78655
79297
  });
78656
79298
  var browserTabShareInputSchema = shareDefinition;
79299
+ var loginDefinition = external_exports.object({
79300
+ ...browserTabRefDefinition.shape,
79301
+ username: external_exports.string().min(1).max(1e3).optional(),
79302
+ password: external_exports.string().min(1).max(1e3),
79303
+ userInput: external_exports.string().trim().min(1).max(300).optional(),
79304
+ passInput: external_exports.string().trim().min(1).max(300).optional()
79305
+ });
79306
+ var browserLoginStateSchema = external_exports.enum([
79307
+ "signed_in",
79308
+ "second_step",
79309
+ "refused",
79310
+ "still_on_form"
79311
+ ]);
79312
+ var loginAnswerDefinition = external_exports.object({
79313
+ tabId: external_exports.string().min(1),
79314
+ url: external_exports.string(),
79315
+ title: external_exports.string(),
79316
+ state: browserLoginStateSchema,
79317
+ /** The page's error line when it refused the sign-in. */
79318
+ error: external_exports.string().nullable(),
79319
+ /** The screen after submitting, a JPEG in base64; null when the browser gave none. */
79320
+ screenshot: external_exports.string().nullable(),
79321
+ /** On a second step: the person the tab now asks to finish it. */
79322
+ askedUserName: external_exports.string().nullable()
79323
+ });
78657
79324
  var browserTabPageDefinition = external_exports.object({
78658
79325
  tabId: external_exports.string().min(1),
78659
79326
  url: external_exports.string(),
@@ -78693,6 +79360,7 @@ var restBrowserTabInputDefinition = browserTabRefDefinition.omit({ workspaceId:
78693
79360
  var restBrowserTabGotoInputDefinition = gotoDefinition.omit({ workspaceId: true });
78694
79361
  var restBrowserTabAskInputDefinition = askDefinition.omit({ workspaceId: true });
78695
79362
  var restBrowserTabShareInputDefinition = shareDefinition.omit({ workspaceId: true });
79363
+ var restBrowserTabLoginInputDefinition = loginDefinition.omit({ workspaceId: true });
78696
79364
 
78697
79365
  // ../../modules/compute/contract/src/compute.config.ts
78698
79366
  var computeConfig = Config.define((c) => ({
@@ -80005,6 +80673,7 @@ var machineWatchStateDefinition = external_exports.object({
80005
80673
  var computeUi = uiTokens("compute");
80006
80674
  var ComputeBrowserTabSlot = computeUi.component("browser-tab");
80007
80675
  var ComputeOpenBrowserSlot = computeUi.component("open-browser");
80676
+ var ComputeBrowserLinkOfferSlot = computeUi.component("browser-link-offer");
80008
80677
 
80009
80678
  // src/services/computer-fleet-commands.service.ts
80010
80679
  var COMPUTER_FLEET_USAGE = ` laze computer mine [--json] every Laze computer your agents may run on, your default one first
@@ -80278,10 +80947,10 @@ async function computer({ context, args }) {
80278
80947
  }
80279
80948
 
80280
80949
  // src/services/connect-commands.service.ts
80281
- import { readFile as readFile21 } from "node:fs/promises";
80950
+ import { readFile as readFile22 } from "node:fs/promises";
80282
80951
 
80283
80952
  // src/services/mcp-gateway.service.ts
80284
- import { readFile as readFile20 } from "node:fs/promises";
80953
+ import { readFile as readFile21 } from "node:fs/promises";
80285
80954
  import { createInterface as createInterface3 } from "node:readline";
80286
80955
  var TURN_HEADER = "x-laze-turn";
80287
80956
  function serveMcpGateway({
@@ -80324,7 +80993,7 @@ async function relayMcpLines({
80324
80993
  const github3 = env.LAZE_GITHUB_CONNECTION;
80325
80994
  const url2 = `${profile.url.replace(/\/+$/, "")}/api/connectors/mcp/${encodeURIComponent(profile.agentId)}${github3 ? `?github=${encodeURIComponent(github3)}` : ""}`;
80326
80995
  const turnFile = env.LAZE_TURN_FILE;
80327
- const readTurn = () => readFile20(turnFile, "utf8").then(
80996
+ const readTurn = () => readFile21(turnFile, "utf8").then(
80328
80997
  (text2) => text2.trim(),
80329
80998
  () => ""
80330
80999
  );
@@ -80414,7 +81083,7 @@ async function turnOf({ context }) {
80414
81083
  const pinned = env.LAZE_TURN_TOKEN?.trim();
80415
81084
  if (pinned) return pinned;
80416
81085
  const file3 = env.LAZE_TURN_FILE;
80417
- const turn = file3 ? await readFile21(file3, "utf8").then(
81086
+ const turn = file3 ? await readFile22(file3, "utf8").then(
80418
81087
  (text2) => text2.trim(),
80419
81088
  () => ""
80420
81089
  ) : "";
@@ -80747,335 +81416,6 @@ var listDevices = async ({ context, args }) => {
80747
81416
  }
80748
81417
  };
80749
81418
 
80750
- // src/services/vault-commands.service.ts
80751
- import { createHash as createHash2 } from "node:crypto";
80752
- import { mkdir as mkdir18, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
80753
- import { tmpdir as tmpdir2 } from "node:os";
80754
- import { dirname as dirname18, join as join20 } from "node:path";
80755
- var USAGE8 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
80756
- Runs the command with the connection's values in its environment, on a Laze agent's computer,
80757
- on a machine it runs on, or where a connected agent runs, with its own key.
80758
- --channel <id> the conversation whose turn it runs in, when the agent answers in several`;
80759
- var POLL_MS2 = 3e3;
80760
- var RESTART_WAIT_MS = 12e4;
80761
- var RESTART_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 1e4];
80762
- var P2562 = { name: "ECDH", namedCurve: "P-256" };
80763
- var ServerGoneError = class extends Error {
80764
- };
80765
- function proxyOf({ env }) {
80766
- const raw = env.LAZE_VAULT_PROXY || env.HTTP_PROXY || env.http_proxy;
80767
- if (!raw) return null;
80768
- const url2 = new URL(raw);
80769
- const user = decodeURIComponent(url2.username);
80770
- const password = decodeURIComponent(url2.password);
80771
- return {
80772
- origin: url2.origin,
80773
- authorization: `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`
80774
- };
80775
- }
80776
- function turnFileOf({
80777
- env
80778
- }) {
80779
- return env.LAZE_TURN_FILE || void 0;
80780
- }
80781
- async function turnTokenOf3({
80782
- env,
80783
- turnFile,
80784
- command = "laze vault run"
80785
- }) {
80786
- const pinned = env.LAZE_TURN_TOKEN?.trim();
80787
- if (pinned) return pinned;
80788
- if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
80789
- try {
80790
- return (await readFile22(turnFile, "utf8")).trim();
80791
- } catch {
80792
- throw new CliUsageError(`${command} works only during an agent's turn`);
80793
- }
80794
- }
80795
- function runKeyPathOf({
80796
- turnFile,
80797
- connection,
80798
- profile = ""
80799
- }) {
80800
- const name3 = createHash2("sha256").update(connection).digest("hex");
80801
- const base = turnFile ? dirname18(turnFile) : join20(tmpdir2(), "laze-vault", profile);
80802
- return join20(base, "vault-run-keys", `${name3}.json`);
80803
- }
80804
- async function runKeyAt({ path }) {
80805
- const saved3 = await readFile22(path, "utf8").then(
80806
- (text2) => JSON.parse(text2),
80807
- () => void 0
80808
- );
80809
- if (saved3 && typeof saved3.publicKey === "string" && saved3.privateKey) {
80810
- const privateKey = await globalThis.crypto.subtle.importKey("jwk", saved3.privateKey, P2562, false, ["deriveBits"]).catch(() => void 0);
80811
- if (privateKey) return { privateKey, publicKey: saved3.publicKey };
80812
- }
80813
- const fresh = await generateEcdhKeys();
80814
- const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
80815
- await mkdir18(dirname18(path), { recursive: true, mode: 448 });
80816
- await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
80817
- mode: 384
80818
- });
80819
- return fresh;
80820
- }
80821
- function connectionRefused(error62) {
80822
- const cause = error62.cause;
80823
- if (cause?.code === "ECONNREFUSED") return true;
80824
- return cause?.errors?.some((inner) => inner.code === "ECONNREFUSED") ?? false;
80825
- }
80826
- async function sendOnce({
80827
- context,
80828
- url: url2,
80829
- init
80830
- }) {
80831
- let response;
80832
- try {
80833
- response = await context.fetcher(url2, init);
80834
- } catch (error62) {
80835
- const wasRefused = connectionRefused(error62);
80836
- if (init.method === "POST" && !wasRefused) throw error62;
80837
- return { restarting: wasRefused ? "connection refused" : String(error62) };
80838
- }
80839
- if (response.status !== 502 && response.status !== 503) return { response };
80840
- const code = codeOf(await response.clone().text());
80841
- const neverReached = response.status === 503 && code === "vault_not_answering";
80842
- if (init.method === "POST" && !neverReached) return { response };
80843
- return { restarting: `status ${response.status}${code ? ` ${code}` : ""}` };
80844
- }
80845
- async function reach(input2) {
80846
- const { context } = input2;
80847
- const started = context.nowMs();
80848
- for (let attempt = 0; ; attempt += 1) {
80849
- const sent = await sendOnce(input2);
80850
- if ("response" in sent) return sent.response;
80851
- if (context.nowMs() - started >= RESTART_WAIT_MS) {
80852
- throw new ServerGoneError(
80853
- `laze vault: the Laze server did not come back (${sent.restarting})`
80854
- );
80855
- }
80856
- if (attempt === 0) {
80857
- context.err(
80858
- `laze vault: the Laze server is not answering (${sent.restarting}), probably restarting; waiting up to 2 min...
80859
- `
80860
- );
80861
- }
80862
- await context.sleep(RESTART_BACKOFF_MS[Math.min(attempt, RESTART_BACKOFF_MS.length - 1)] ?? 0);
80863
- }
80864
- }
80865
- function codeOf(text2) {
80866
- return /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1];
80867
- }
80868
- async function releaseOf({ response }) {
80869
- const text2 = await response.text();
80870
- if (!response.ok) {
80871
- return {
80872
- outcome: "deny",
80873
- exitCode: 1,
80874
- message: `laze vault: the release was refused (${codeOf(text2) ?? `status ${response.status}`})`
80875
- };
80876
- }
80877
- return JSON.parse(text2);
80878
- }
80879
- async function envOf({
80880
- release: release2,
80881
- run: run4
80882
- }) {
80883
- if (!release2.sealed) return release2.env;
80884
- const sealed = await openRunRelease({
80885
- release: release2.sealed,
80886
- runPrivateKey: run4.privateKey,
80887
- runPublicKey: run4.publicKey,
80888
- requestId: release2.sealed.requestId
80889
- });
80890
- return { ...release2.env, ...sealed };
80891
- }
80892
- function deadlineOf({ args, nowMs }) {
80893
- const wait = flagText({ args, name: "wait" }) || (args.flags.wait === true ? args.words[3] : "");
80894
- if (!wait) return Infinity;
80895
- if (!(Number(wait) >= 0)) throw new CliUsageError(`--wait takes a number of seconds
80896
- ${USAGE8}`);
80897
- return nowMs + Number(wait) * 1e3;
80898
- }
80899
- async function untilAnswered({
80900
- context,
80901
- first,
80902
- next,
80903
- deadline
80904
- }) {
80905
- let release2 = first;
80906
- while (release2.outcome === "ask") {
80907
- if (context.nowMs() + POLL_MS2 > deadline) {
80908
- context.err(`${release2.message}. Not approved yet; ask again later.
80909
- `);
80910
- return "capped";
80911
- }
80912
- if (release2 === first) {
80913
- context.err(`${release2.message}. Waiting for an answer (cards expire after 12 hours)...
80914
- `);
80915
- }
80916
- await context.sleep(POLL_MS2);
80917
- release2 = await next(release2.requestId);
80918
- }
80919
- return release2;
80920
- }
80921
- function leaseHolds({
80922
- release: release2,
80923
- nowMs
80924
- }) {
80925
- const ends = release2.sealed?.leaseEndsAt;
80926
- return ends !== void 0 && Temporal3.Instant.from(ends).epochMilliseconds > nowMs;
80927
- }
80928
- async function vaultRelease({
80929
- context,
80930
- args,
80931
- connection,
80932
- reason,
80933
- command
80934
- }) {
80935
- const deadline = deadlineOf({ args, nowMs: context.nowMs() });
80936
- const env = context.environment.inherited;
80937
- const proxy = proxyOf({ env });
80938
- if (!proxy) return keyRelease({ context, args, connection, reason, command, deadline });
80939
- const turnFile = turnFileOf({ env });
80940
- const headers = {
80941
- "proxy-authorization": proxy.authorization,
80942
- "x-laze-turn": await turnTokenOf3({ env, turnFile })
80943
- };
80944
- const keyPath = runKeyPathOf({ turnFile, connection });
80945
- const run4 = await runKeyAt({ path: keyPath });
80946
- const body = JSON.stringify({ connection, reason, command, recipient: run4.publicKey });
80947
- let release2;
80948
- try {
80949
- const first = await releaseOf({
80950
- response: await reach({
80951
- context,
80952
- url: `${proxy.origin}/vault/release`,
80953
- init: { method: "POST", headers: { ...headers, "content-type": "application/json" }, body }
80954
- })
80955
- });
80956
- const next = async (requestId) => releaseOf({
80957
- response: await reach({
80958
- context,
80959
- url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
80960
- init: { method: "GET", headers }
80961
- })
80962
- });
80963
- release2 = await untilAnswered({ context, first, next, deadline });
80964
- } catch (error62) {
80965
- if (!(error62 instanceof ServerGoneError)) throw error62;
80966
- context.err(`${error62.message}. Run the command again to keep waiting.
80967
- `);
80968
- return { exitCode: 75 };
80969
- }
80970
- return settled({ context, release: release2, run: run4, keyPath });
80971
- }
80972
- async function settled({
80973
- context,
80974
- release: release2,
80975
- run: run4,
80976
- keyPath
80977
- }) {
80978
- if (release2 === "capped") return { exitCode: 75 };
80979
- if (release2.outcome === "deny") {
80980
- await rm10(keyPath, { force: true });
80981
- context.err(`${release2.message}
80982
- `);
80983
- return { exitCode: release2.exitCode || 1 };
80984
- }
80985
- const values = await envOf({ release: release2, run: run4 });
80986
- if (!leaseHolds({ release: release2, nowMs: context.nowMs() })) await rm10(keyPath, { force: true });
80987
- if (release2.message) context.err(`${release2.message}
80988
- `);
80989
- return { env: values };
80990
- }
80991
- function refusedRelease(error62) {
80992
- if (!(error62 instanceof LazeApiError)) throw error62;
80993
- return {
80994
- outcome: "deny",
80995
- exitCode: 1,
80996
- message: `laze vault: the release was refused: ${error62.message} (${error62.code})`
80997
- };
80998
- }
80999
- async function keyRelease({
81000
- context,
81001
- args,
81002
- connection,
81003
- reason,
81004
- command,
81005
- deadline
81006
- }) {
81007
- const where = new CliUsageError(
81008
- "laze vault run works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent"
81009
- );
81010
- const signed2 = await signedIn({ context, args }).catch(() => null);
81011
- if (signed2?.profile.kind !== "agent") throw where;
81012
- const { client, name: name3 } = signed2;
81013
- const channelId = flagText({ args, name: "channel" }) || null;
81014
- const keyPath = runKeyPathOf({ turnFile: void 0, connection, profile: name3 });
81015
- const run4 = await runKeyAt({ path: keyPath });
81016
- const first = await client.post("/api/agents/me/vault/release", {
81017
- connection,
81018
- reason,
81019
- command,
81020
- recipient: run4.publicKey,
81021
- channelId
81022
- }).catch(refusedRelease);
81023
- const next = (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease);
81024
- const release2 = await untilAnswered({ context, first, next, deadline });
81025
- return settled({ context, release: release2, run: run4, keyPath });
81026
- }
81027
- async function vaultRun({
81028
- context,
81029
- args
81030
- }) {
81031
- const connection = args.words[2];
81032
- const reason = flagText({ args, name: "reason" });
81033
- if (!connection || args.rest.length === 0) throw new CliUsageError(USAGE8);
81034
- if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
81035
- ${USAGE8}`);
81036
- const foreign = commandReferenceNames({ command: args.rest }).find(
81037
- (name3) => vaultReferenceConnectionName({ name: name3 }) !== connection
81038
- );
81039
- if (foreign !== void 0) {
81040
- const named = vaultReferenceConnectionName({ name: foreign });
81041
- context.err(
81042
- `laze vault: the command names {{vault:${foreign}}}, but this run releases only ${connection}, not ${named}. Nothing was asked and the command did not run.
81043
- `
81044
- );
81045
- return 1;
81046
- }
81047
- const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
81048
- if ("exitCode" in released) return released.exitCode;
81049
- const prepared = preparedCommand({
81050
- command: args.rest,
81051
- released: /* @__PURE__ */ new Map([[connection, released.env]])
81052
- });
81053
- if ("refusal" in prepared) {
81054
- context.err(`${prepared.refusal}
81055
- `);
81056
- return 1;
81057
- }
81058
- return context.runCommand({ command: prepared.command, env: released.env });
81059
- }
81060
- function preparedCommand({
81061
- command,
81062
- released
81063
- }) {
81064
- for (const [name3, fields] of released) {
81065
- const [problem] = unusableFieldProblems({ fields });
81066
- if (problem !== void 0) {
81067
- return {
81068
- refusal: `laze vault: ${name3}: ${problem}, so the command did not run. Ask its owner to save the real value on the vault page.`
81069
- };
81070
- }
81071
- }
81072
- const filled = fillCommandReferences({ command, released });
81073
- if ("refusal" in filled) {
81074
- return { refusal: `laze vault: ${filled.refusal}. The command did not run.` };
81075
- }
81076
- return filled;
81077
- }
81078
-
81079
81419
  // src/services/vault-share-commands.service.ts
81080
81420
  var SHARE_USAGE2 = "Usage: laze vault share <connection> --with <email|userId> [--for 1h]";
81081
81421
  var WAITING_LINE = "It waits for the owner's approval with a passkey or Face ID, in Settings > Vault.";
@@ -81094,7 +81434,7 @@ async function inTurn({
81094
81434
  command
81095
81435
  }) {
81096
81436
  const env = context.environment.inherited;
81097
- const turn = await turnTokenOf3({ env, turnFile: turnFileOf({ env }), command });
81437
+ const turn = await turnTokenOf2({ env, turnFile: turnFileOf({ env }), command });
81098
81438
  return client.withHeaders({ "x-laze-turn": turn });
81099
81439
  }
81100
81440
  function printShare({ context, grant }) {
@@ -81778,16 +82118,16 @@ function dndLine({ pausedUntil }) {
81778
82118
  }
81779
82119
 
81780
82120
  // src/services/dnd-commands.service.ts
81781
- var USAGE9 = "Usage: laze dnd 30m|1h|2h|until <HH:mm|ISO time> [--tz <zone>], laze dnd off";
82121
+ var USAGE8 = "Usage: laze dnd 30m|1h|2h|until <HH:mm|ISO time> [--tz <zone>], laze dnd off";
81782
82122
  async function dnd({ context, args }) {
81783
82123
  const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
81784
82124
  let input2;
81785
82125
  try {
81786
82126
  input2 = dndInputOf({ words: args.words.slice(1), now: nowInstant(), timeZone });
81787
82127
  } catch {
81788
- throw new CliUsageError(USAGE9);
82128
+ throw new CliUsageError(USAGE8);
81789
82129
  }
81790
- if (!input2) throw new CliUsageError(USAGE9);
82130
+ if (!input2) throw new CliUsageError(USAGE8);
81791
82131
  const { client } = await signedIn({ context, args });
81792
82132
  const settings2 = await client.post(
81793
82133
  "/api/agents/me/notifications/snooze",
@@ -81806,8 +82146,8 @@ var DOMAINS_USAGE = `Usage:
81806
82146
  var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
81807
82147
  `);
81808
82148
  function printDomain(context, row) {
81809
- const join25 = row.autoJoin ? "auto-join on" : "auto-join off";
81810
- context.out(`${row.domain} ${join25}${row.enforced ? " single sign-on enforced" : ""}
82149
+ const join26 = row.autoJoin ? "auto-join on" : "auto-join off";
82150
+ context.out(`${row.domain} ${join26}${row.enforced ? " single sign-on enforced" : ""}
81811
82151
  `);
81812
82152
  }
81813
82153
  async function list4({ context, args }) {
@@ -82036,6 +82376,8 @@ var feedApprovalSchemaDefinition = external_exports.object({
82036
82376
  why: external_exports.string(),
82037
82377
  /** The longest lease Allow for this agent may give; null offers only once and deny. */
82038
82378
  maxLeaseSeconds: external_exports.number().int().positive().nullable(),
82379
+ /** A vault card whose Allow covers the rest of the agent's turn: "Allow for this task". */
82380
+ coversTask: external_exports.boolean().optional(),
82039
82381
  /** The card's timeout; a publish waits without one. */
82040
82382
  expiresAt: external_exports.iso.datetime().nullable(),
82041
82383
  state: feedApprovalStateSchema,
@@ -82612,7 +82954,7 @@ async function feedAttachmentIdsOf({
82612
82954
  }
82613
82955
 
82614
82956
  // src/services/feed-commands.service.ts
82615
- var USAGE10 = `Usage:
82957
+ var USAGE9 = `Usage:
82616
82958
  laze feed post <title> [--channel <channel>] [--tag <tag>] [--summary <line>]
82617
82959
  [--draft <text|@file>] [--draft-header "To: ...\\nRe: ..."]
82618
82960
  [--metric <json|@file.json> | --table <csv|@file.csv>]
@@ -82683,7 +83025,7 @@ function printItem({
82683
83025
  }
82684
83026
  async function feedPost({ context, args }) {
82685
83027
  const title = args.words.slice(2).join(" ").trim();
82686
- if (!title) throw new CliUsageError(USAGE10);
83028
+ if (!title) throw new CliUsageError(USAGE9);
82687
83029
  const flags2 = flagsOf(args);
82688
83030
  const { client } = await signedIn({ context, args });
82689
83031
  const channel = flagText({ args, name: "channel" });
@@ -82705,7 +83047,7 @@ async function feedPost({ context, args }) {
82705
83047
  }
82706
83048
  async function feedUpdate({ context, args }) {
82707
83049
  const itemId = args.words[2];
82708
- if (!itemId) throw new CliUsageError(USAGE10);
83050
+ if (!itemId) throw new CliUsageError(USAGE9);
82709
83051
  const flags2 = flagsOf(args);
82710
83052
  const { client } = await signedIn({ context, args });
82711
83053
  const body = await bodyOf2({ context, flags: flags2 });
@@ -82721,7 +83063,7 @@ async function feedUpdate({ context, args }) {
82721
83063
  async function feedReply({ context, args }) {
82722
83064
  const itemId = args.words[2];
82723
83065
  const text2 = args.words.slice(3).join(" ").trim();
82724
- if (!itemId || !text2) throw new CliUsageError(USAGE10);
83066
+ if (!itemId || !text2) throw new CliUsageError(USAGE9);
82725
83067
  const { client } = await signedIn({ context, args });
82726
83068
  const replied = await client.post("/api/feed/items/reply", {
82727
83069
  itemId,
@@ -82734,7 +83076,7 @@ async function feedReply({ context, args }) {
82734
83076
  }
82735
83077
  async function feedRead({ context, args }) {
82736
83078
  const itemId = args.words[2];
82737
- if (!itemId) throw new CliUsageError(USAGE10);
83079
+ if (!itemId) throw new CliUsageError(USAGE9);
82738
83080
  const { client } = await signedIn({ context, args });
82739
83081
  const read3 = await client.post("/api/feed/items/read", { itemId });
82740
83082
  printItem({ context, args, item: read3 });
@@ -82753,7 +83095,7 @@ async function feedClose({ context, args }) {
82753
83095
  const itemId = args.words[2];
82754
83096
  const loop = flagText({ args, name: "loop" });
82755
83097
  const note = flagText({ args, name: "note" });
82756
- if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(USAGE10);
83098
+ if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(USAGE9);
82757
83099
  const { client } = await signedIn({ context, args });
82758
83100
  const closed = await client.post("/api/feed/items/close", {
82759
83101
  ...itemId ? { itemId } : { loop },
@@ -82779,7 +83121,7 @@ async function feedLoops({ context, args }) {
82779
83121
  }
82780
83122
  async function feedGroupSummary({ context, args }) {
82781
83123
  const group = args.words.slice(2).join(" ").trim();
82782
- if (!group) throw new CliUsageError(USAGE10);
83124
+ if (!group) throw new CliUsageError(USAGE9);
82783
83125
  const { client } = await signedIn({ context, args });
82784
83126
  const pointer = await client.post("/api/feed/group-summary", { group });
82785
83127
  if (args.flags.json) return context.out(`${JSON.stringify(pointer, null, 2)}
@@ -82859,7 +83201,7 @@ async function feedDecisions({ context, args }) {
82859
83201
  }
82860
83202
  async function feedAct({ context, args }) {
82861
83203
  const [itemId, actionId] = [args.words[2], args.words[3]];
82862
- if (!itemId || !actionId) throw new CliUsageError(USAGE10);
83204
+ if (!itemId || !actionId) throw new CliUsageError(USAGE9);
82863
83205
  const draft = await textFlag({ context, args, name: "draft" });
82864
83206
  const { client } = await signedIn({ context, args });
82865
83207
  const item = await client.post("/api/feed/mine/act", {
@@ -82872,7 +83214,7 @@ async function feedAct({ context, args }) {
82872
83214
  async function feedComment({ context, args }) {
82873
83215
  const itemId = args.words[2];
82874
83216
  const text2 = args.words.slice(3).join(" ").trim();
82875
- if (!itemId || !text2) throw new CliUsageError(USAGE10);
83217
+ if (!itemId || !text2) throw new CliUsageError(USAGE9);
82876
83218
  const draft = await textFlag({ context, args, name: "draft" });
82877
83219
  const { client } = await signedIn({ context, args });
82878
83220
  const item = await client.post("/api/feed/mine/comment", {
@@ -82886,7 +83228,7 @@ async function feedComment({ context, args }) {
82886
83228
  function moveItem(path) {
82887
83229
  return async ({ context, args }) => {
82888
83230
  const itemId = args.words[2];
82889
- if (!itemId) throw new CliUsageError(USAGE10);
83231
+ if (!itemId) throw new CliUsageError(USAGE9);
82890
83232
  const { client } = await signedIn({ context, args });
82891
83233
  const item = await client.post(`/api/feed/mine/${path}`, { itemId });
82892
83234
  printMoved({ context, args, item });
@@ -82895,14 +83237,14 @@ function moveItem(path) {
82895
83237
  async function feedSnooze({ context, args }) {
82896
83238
  const itemId = args.words[2];
82897
83239
  const until = flagText({ args, name: "until" });
82898
- if (!itemId || !until) throw new CliUsageError(USAGE10);
83240
+ if (!itemId || !until) throw new CliUsageError(USAGE9);
82899
83241
  const { client } = await signedIn({ context, args });
82900
83242
  const item = await client.post("/api/feed/mine/snooze", { itemId, until });
82901
83243
  printMoved({ context, args, item });
82902
83244
  }
82903
83245
  async function feedChannel({ context, args }) {
82904
83246
  const channelId = args.words[2];
82905
- if (!channelId) throw new CliUsageError(USAGE10);
83247
+ if (!channelId) throw new CliUsageError(USAGE9);
82906
83248
  const { client } = await signedIn({ context, args });
82907
83249
  const items = await client.post("/api/feed/channel", { channelId });
82908
83250
  if (args.flags.json) return context.out(`${JSON.stringify(items, null, 2)}
@@ -82933,7 +83275,7 @@ var FEED_COMMANDS = {
82933
83275
  async function feed({ context, args }) {
82934
83276
  const name3 = args.words[1] ?? "";
82935
83277
  const command = Object.hasOwn(FEED_COMMANDS, name3) ? FEED_COMMANDS[name3] : void 0;
82936
- if (!command) throw new CliUsageError(USAGE10);
83278
+ if (!command) throw new CliUsageError(USAGE9);
82937
83279
  await command({ context, args });
82938
83280
  }
82939
83281
 
@@ -83429,12 +83771,12 @@ async function ip({ context, args }) {
83429
83771
  }
83430
83772
 
83431
83773
  // src/services/join-commands.service.ts
83432
- import { mkdir as mkdir19, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile19 } from "node:fs/promises";
83433
- import { dirname as dirname19, join as join21 } from "node:path";
83774
+ import { mkdir as mkdir20, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile20 } from "node:fs/promises";
83775
+ import { dirname as dirname19, join as join22 } from "node:path";
83434
83776
  var DEFAULT_WAIT_SECONDS2 = 100;
83435
83777
  var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
83436
83778
  function pendingPathOf({ context }) {
83437
- return join21(dirname19(context.environment.configPath), "join", "pending.json");
83779
+ return join22(dirname19(context.environment.configPath), "join", "pending.json");
83438
83780
  }
83439
83781
  async function readPending({
83440
83782
  context,
@@ -83451,9 +83793,9 @@ async function readPending({
83451
83793
  }
83452
83794
  async function keepPending({ context, pending }) {
83453
83795
  const path = pendingPathOf({ context });
83454
- await mkdir19(dirname19(path), { recursive: true, mode: 448 });
83796
+ await mkdir20(dirname19(path), { recursive: true, mode: 448 });
83455
83797
  const temporary = `${path}.${process.pid}.tmp`;
83456
- await writeFile19(temporary, JSON.stringify(pending), { mode: 384 });
83798
+ await writeFile20(temporary, JSON.stringify(pending), { mode: 384 });
83457
83799
  await rename5(temporary, path);
83458
83800
  }
83459
83801
  async function dropPending({ context }) {
@@ -83770,7 +84112,7 @@ function machineAccessCommand(name3) {
83770
84112
  }
83771
84113
 
83772
84114
  // src/services/machine-commands.service.ts
83773
- var USAGE11 = [
84115
+ var USAGE10 = [
83774
84116
  "Usage: laze machine connect <name> the command to run on your own machine (people)",
83775
84117
  " laze machine connect <name> --again a new command for a machine you connected; the old code stops working",
83776
84118
  " laze machine connect <name> --ssh <user>@<host>[:port] a machine that cannot run the connector, over SSH (people)",
@@ -83816,7 +84158,7 @@ function listLine(machine2) {
83816
84158
  var EXEC_ENV_MAX = 32;
83817
84159
  function machineArg2({ args }) {
83818
84160
  const machine2 = args.words[2];
83819
- if (!machine2) throw new CliUsageError(USAGE11);
84161
+ if (!machine2) throw new CliUsageError(USAGE10);
83820
84162
  return machine2;
83821
84163
  }
83822
84164
  async function connect2({ context, args }) {
@@ -83842,7 +84184,7 @@ async function connectSsh({
83842
84184
  }) {
83843
84185
  const ssh = flagText({ args, name: "ssh" });
83844
84186
  if (!ssh) throw new CliUsageError(`--ssh takes <user>@<host>[:port]
83845
- ${USAGE11}`);
84187
+ ${USAGE10}`);
83846
84188
  const client = await computeClient({ context, args });
83847
84189
  const made = await client.post(COMPUTE_REST_PATHS.connectSsh, {
83848
84190
  name: name3,
@@ -83918,11 +84260,11 @@ async function exec({
83918
84260
  }) {
83919
84261
  const machine2 = machineArg2({ args });
83920
84262
  const command = commandText({ rest: args.rest });
83921
- if (!command.trim()) throw new CliUsageError(USAGE11);
84263
+ if (!command.trim()) throw new CliUsageError(USAGE10);
83922
84264
  const timeout = flagText({ args, name: "timeout" });
83923
84265
  if (timeout && !(Number(timeout) >= 1))
83924
84266
  throw new CliUsageError(`--timeout takes a number of seconds
83925
- ${USAGE11}`);
84267
+ ${USAGE10}`);
83926
84268
  const released = await vaultEnv({ context, args });
83927
84269
  if ("exitCode" in released) return released.exitCode;
83928
84270
  const client = await computeClient({ context, args });
@@ -83950,11 +84292,11 @@ async function vaultEnv({
83950
84292
  const connections = args.lists.vault ?? [];
83951
84293
  if (args.flags.vault === true)
83952
84294
  throw new CliUsageError(`--vault takes a connection name
83953
- ${USAGE11}`);
84295
+ ${USAGE10}`);
83954
84296
  if (connections.length === 0) return {};
83955
84297
  const reason = flagText({ args, name: "reason" });
83956
84298
  if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
83957
- ${USAGE11}`);
84299
+ ${USAGE10}`);
83958
84300
  const env = {};
83959
84301
  for (const connection of new Set(connections)) {
83960
84302
  const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
@@ -83974,11 +84316,11 @@ ${USAGE11}`);
83974
84316
  async function host({ context, args }) {
83975
84317
  const machineName = args.words[2];
83976
84318
  const agent2 = args.words[3];
83977
- if (!machineName || !agent2) throw new CliUsageError(USAGE11);
84319
+ if (!machineName || !agent2) throw new CliUsageError(USAGE10);
83978
84320
  const whenOffline = flagText({ args, name: "when-offline", fallback: "wait" });
83979
84321
  if (whenOffline !== "wait" && whenOffline !== "computer" && whenOffline !== "sandbox")
83980
84322
  throw new CliUsageError(`--when-offline takes wait or computer
83981
- ${USAGE11}`);
84323
+ ${USAGE10}`);
83982
84324
  const client = await computeClient({ context, args });
83983
84325
  const machine2 = await client.post(COMPUTE_REST_PATHS.host, {
83984
84326
  machine: machineName,
@@ -83995,7 +84337,7 @@ ${USAGE11}`);
83995
84337
  }
83996
84338
  async function unhost({ context, args }) {
83997
84339
  const agent2 = args.words[2];
83998
- if (!agent2) throw new CliUsageError(USAGE11);
84340
+ if (!agent2) throw new CliUsageError(USAGE10);
83999
84341
  const client = await computeClient({ context, args });
84000
84342
  const done = await client.post(COMPUTE_REST_PATHS.unhost, { agent: agent2 });
84001
84343
  if (args.flags.json) return context.out(`${JSON.stringify(done, null, 2)}
@@ -84032,7 +84374,7 @@ async function machine({ context, args }) {
84032
84374
  if (command === "unhost") return unhost({ context, args });
84033
84375
  const access = machineAccessCommand(command);
84034
84376
  if (access) return access({ context, args });
84035
- throw new CliUsageError(USAGE11);
84377
+ throw new CliUsageError(USAGE10);
84036
84378
  }
84037
84379
 
84038
84380
  // src/services/mcp-server.service.ts
@@ -84271,7 +84613,7 @@ async function serveMcp({
84271
84613
  }
84272
84614
 
84273
84615
  // src/services/mount-files.service.ts
84274
- import { mkdir as mkdir20, readFile as readFile30, rm as rm12, writeFile as writeFile20 } from "node:fs/promises";
84616
+ import { mkdir as mkdir21, readFile as readFile30, rm as rm12, writeFile as writeFile21 } from "node:fs/promises";
84275
84617
  import { dirname as dirname20, relative as relative5, resolve as resolve11 } from "node:path";
84276
84618
  async function textArgument({
84277
84619
  context,
@@ -84292,20 +84634,20 @@ async function writeMount({
84292
84634
  }) {
84293
84635
  const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
84294
84636
  await rm12(root, { recursive: true, force: true });
84295
- await mkdir20(root, { recursive: true });
84637
+ await mkdir21(root, { recursive: true });
84296
84638
  for (const file3 of files2) {
84297
84639
  const target = resolve11(root, file3.path);
84298
84640
  const inside = relative5(root, target);
84299
84641
  if (!inside || inside.startsWith(".."))
84300
84642
  throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
84301
- await mkdir20(dirname20(target), { recursive: true });
84302
- await writeFile20(target, file3.content);
84643
+ await mkdir21(dirname20(target), { recursive: true });
84644
+ await writeFile21(target, file3.content);
84303
84645
  }
84304
84646
  return root;
84305
84647
  }
84306
84648
 
84307
84649
  // src/services/memory-commands.service.ts
84308
- var USAGE12 = `Usage:
84650
+ var USAGE11 = `Usage:
84309
84651
  laze memory get SOUL.md|AGENTS.md|MEMORY.md [--channel <channel>]
84310
84652
  laze memory set <file> <text|@file|-> [--channel <channel>] [--base <version>]
84311
84653
  laze memory append MEMORY.md <text|@file|-> [--channel <channel>]
@@ -84317,7 +84659,7 @@ MEMORY.md is the file of the turn's channel (LAZE_CHANNEL), or of --channel when
84317
84659
  var FILES = /* @__PURE__ */ new Set(["SOUL.md", "AGENTS.md", "MEMORY.md"]);
84318
84660
  function fileRef({ context, args }) {
84319
84661
  const file3 = args.words[2] ?? "";
84320
- if (!FILES.has(file3)) throw new CliUsageError(USAGE12);
84662
+ if (!FILES.has(file3)) throw new CliUsageError(USAGE11);
84321
84663
  const channel = turnChannel({ context, args });
84322
84664
  return { file: file3, ...channel ? { channel } : {} };
84323
84665
  }
@@ -84356,7 +84698,7 @@ async function memoryHistory({ context, args }) {
84356
84698
  async function memorySet({ context, args }) {
84357
84699
  const ref = fileRef({ context, args });
84358
84700
  const value = args.words.slice(3).join(" ");
84359
- if (!value) throw new CliUsageError(USAGE12);
84701
+ if (!value) throw new CliUsageError(USAGE11);
84360
84702
  const content = await textArgument({ context, value });
84361
84703
  const base = args.flags.base;
84362
84704
  const { client } = await signedIn({ context, args });
@@ -84372,7 +84714,7 @@ async function memorySet({ context, args }) {
84372
84714
  async function memoryAppend({ context, args }) {
84373
84715
  const ref = fileRef({ context, args });
84374
84716
  const value = args.words.slice(3).join(" ");
84375
- if (!value) throw new CliUsageError(USAGE12);
84717
+ if (!value) throw new CliUsageError(USAGE11);
84376
84718
  const text2 = await textArgument({ context, value });
84377
84719
  const { client } = await signedIn({ context, args });
84378
84720
  const saved3 = await client.post("/api/memory/append", { ...ref, text: text2 });
@@ -84382,7 +84724,7 @@ async function memoryAppend({ context, args }) {
84382
84724
  }
84383
84725
  async function memorySearch({ context, args }) {
84384
84726
  const query = args.words.slice(2).join(" ").trim();
84385
- if (!query) throw new CliUsageError(USAGE12);
84727
+ if (!query) throw new CliUsageError(USAGE11);
84386
84728
  const { client } = await signedIn({ context, args });
84387
84729
  const hits = await client.post("/api/memory/search", { query });
84388
84730
  if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
@@ -84416,13 +84758,13 @@ var MEMORY_COMMANDS = {
84416
84758
  async function memory({ context, args }) {
84417
84759
  const name3 = args.words[1] ?? "";
84418
84760
  const command = Object.hasOwn(MEMORY_COMMANDS, name3) ? MEMORY_COMMANDS[name3] : void 0;
84419
- if (!command) throw new CliUsageError(USAGE12);
84761
+ if (!command) throw new CliUsageError(USAGE11);
84420
84762
  await command({ context, args });
84421
84763
  }
84422
84764
 
84423
84765
  // src/services/models-commands.service.ts
84424
84766
  var WINDOWS = ["day", "week", "month"];
84425
- var USAGE13 = `Usage:
84767
+ var USAGE12 = `Usage:
84426
84768
  laze models policy whether Laze models are on, the default budget and the cap
84427
84769
  laze models set-policy [on|off] [--default-day <usd|none>] [--cap-day <usd|none>] ... (admins)
84428
84770
  --default-week, --default-month, --cap-week and --cap-month set the other windows
@@ -84447,7 +84789,7 @@ function limitsFrom({
84447
84789
  const value = text2 === "none" ? null : Number(text2);
84448
84790
  if (value !== null && (!Number.isFinite(value) || value < 0))
84449
84791
  throw new CliUsageError(`--${prefix}${window2} takes an amount in USD or none.
84450
- ${USAGE13}`);
84792
+ ${USAGE12}`);
84451
84793
  next[window2] = value;
84452
84794
  changed = true;
84453
84795
  }
@@ -84472,12 +84814,12 @@ async function showPolicy({ context, args }) {
84472
84814
  }
84473
84815
  async function setPolicy({ context, args }) {
84474
84816
  const state = args.words[2];
84475
- if (state !== void 0 && state !== "on" && state !== "off") throw new CliUsageError(USAGE13);
84817
+ if (state !== void 0 && state !== "on" && state !== "off") throw new CliUsageError(USAGE12);
84476
84818
  const { client } = await signedIn({ context, args });
84477
84819
  const current2 = await client.get("/api/models/policy");
84478
84820
  const defaultBudget = limitsFrom({ args, prefix: "default-", current: current2.defaultBudget });
84479
84821
  const cap = limitsFrom({ args, prefix: "cap-", current: current2.cap });
84480
- if (!state && !defaultBudget && !cap) throw new CliUsageError(USAGE13);
84822
+ if (!state && !defaultBudget && !cap) throw new CliUsageError(USAGE12);
84481
84823
  const updated = await client.post("/api/models/policy", {
84482
84824
  ...state ? { lazeModels: state === "on" } : {},
84483
84825
  ...defaultBudget ? { defaultBudget } : {},
@@ -84518,11 +84860,11 @@ async function agentNamed({ client, name: name3 }) {
84518
84860
  }
84519
84861
  async function setBudget({ context, args }) {
84520
84862
  const name3 = args.words[2];
84521
- if (!name3) throw new CliUsageError(USAGE13);
84863
+ if (!name3) throw new CliUsageError(USAGE12);
84522
84864
  const { client } = await signedIn({ context, args });
84523
84865
  const agent2 = await agentNamed({ client, name: name3 });
84524
84866
  const next = limitsFrom({ args, prefix: "", current: agent2.budget });
84525
- if (!next) throw new CliUsageError(USAGE13);
84867
+ if (!next) throw new CliUsageError(USAGE12);
84526
84868
  const updated = await client.post("/api/models/agents/budget", {
84527
84869
  agentId: agent2.agentId,
84528
84870
  budget: next
@@ -84555,7 +84897,7 @@ var MODEL_COMMANDS = {
84555
84897
  async function models({ context, args }) {
84556
84898
  const name3 = args.words[1] ?? "policy";
84557
84899
  const command = Object.hasOwn(MODEL_COMMANDS, name3) ? MODEL_COMMANDS[name3] : void 0;
84558
- if (!command) throw new CliUsageError(USAGE13);
84900
+ if (!command) throw new CliUsageError(USAGE12);
84559
84901
  await command({ context, args });
84560
84902
  }
84561
84903
 
@@ -84633,7 +84975,7 @@ var monitorResume = stateRun("/api/agents/monitors/resume", "resume");
84633
84975
  var monitorRemove = stateRun("/api/agents/monitors/remove", "rm");
84634
84976
 
84635
84977
  // src/services/notification-commands.service.ts
84636
- var USAGE14 = `Usage:
84978
+ var USAGE13 = `Usage:
84637
84979
  laze notifications [show] your notification settings (people)
84638
84980
  laze notifications set [--channels all|mentions|nothing] [--keywords a,b] [--dnd on|off]
84639
84981
  [--dnd-from 22:00] [--dnd-to 08:00] [--tz <IANA zone>] [--push on|off] [--email on|off]
@@ -84662,14 +85004,14 @@ function switchOf({ args, name: name3 }) {
84662
85004
  if (!text2) return void 0;
84663
85005
  if (text2 !== "on" && text2 !== "off")
84664
85006
  throw new CliUsageError(`--${name3} takes on or off.
84665
- ${USAGE14}`);
85007
+ ${USAGE13}`);
84666
85008
  return text2 === "on";
84667
85009
  }
84668
85010
  function changesOf(args) {
84669
85011
  const channels2 = flagText({ args, name: "channels" });
84670
85012
  if (channels2 && !["all", "mentions", "nothing"].includes(channels2))
84671
85013
  throw new CliUsageError(`--channels takes all, mentions or nothing.
84672
- ${USAGE14}`);
85014
+ ${USAGE13}`);
84673
85015
  const keywords = typeof args.flags.keywords === "string" ? args.flags.keywords : void 0;
84674
85016
  const emailAfter = flagText({ args, name: "email-after" });
84675
85017
  const changes2 = {
@@ -84691,7 +85033,7 @@ async function showSettings({ context, args }) {
84691
85033
  }
84692
85034
  async function setSettings({ context, args }) {
84693
85035
  const changes2 = changesOf(args);
84694
- if (Object.keys(changes2).length === 0) throw new CliUsageError(USAGE14);
85036
+ if (Object.keys(changes2).length === 0) throw new CliUsageError(USAGE13);
84695
85037
  const { client } = await signedIn({ context, args });
84696
85038
  print7({
84697
85039
  context,
@@ -84702,7 +85044,7 @@ async function setSettings({ context, args }) {
84702
85044
  async function snoozeFor({ context, args }) {
84703
85045
  const word3 = args.words[2];
84704
85046
  const minutes = word3 === "off" ? 0 : Number(word3);
84705
- if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(USAGE14);
85047
+ if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(USAGE13);
84706
85048
  const { client } = await signedIn({ context, args });
84707
85049
  print7({
84708
85050
  context,
@@ -84720,7 +85062,7 @@ var NOTIFICATION_COMMANDS = {
84720
85062
  async function notifications({ context, args }) {
84721
85063
  const name3 = args.words[1] ?? "show";
84722
85064
  const command = Object.hasOwn(NOTIFICATION_COMMANDS, name3) ? NOTIFICATION_COMMANDS[name3] : void 0;
84723
- if (!command) throw new CliUsageError(USAGE14);
85065
+ if (!command) throw new CliUsageError(USAGE13);
84724
85066
  await command({ context, args });
84725
85067
  }
84726
85068
 
@@ -84957,8 +85299,8 @@ ${OPS_USAGE}`);
84957
85299
  }
84958
85300
 
84959
85301
  // src/services/release-watch.service.ts
84960
- import { mkdir as mkdir21, readFile as readFile31, realpath, writeFile as writeFile21 } from "node:fs/promises";
84961
- import { dirname as dirname21, join as join22 } from "node:path";
85302
+ import { mkdir as mkdir22, readFile as readFile31, realpath, writeFile as writeFile22 } from "node:fs/promises";
85303
+ import { dirname as dirname21, join as join23 } from "node:path";
84962
85304
 
84963
85305
  // src/rules/cli-update.rules.ts
84964
85306
  var CLI_PACKAGE = "@lazehq/cli";
@@ -85105,15 +85447,15 @@ async function startedUpdate({
85105
85447
  const plan2 = updatePlanOf({ script: await scriptOf(context) });
85106
85448
  if (plan2.kind !== "install") return null;
85107
85449
  const folder = dirname21(context.environment.configPath);
85108
- const stamp = join22(folder, "auto-update.json");
85450
+ const stamp = join23(folder, "auto-update.json");
85109
85451
  const last = await readFile31(stamp, "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
85110
85452
  const now = context.nowMs();
85111
85453
  if (last?.server === server && now - last.atMs < RETRY_AFTER_MS) return null;
85112
- await mkdir21(folder, { recursive: true, mode: 448 });
85113
- await writeFile21(stamp, JSON.stringify({ server, atMs: now }), { mode: 384 });
85454
+ await mkdir22(folder, { recursive: true, mode: 448 });
85455
+ await writeFile22(stamp, JSON.stringify({ server, atMs: now }), { mode: 384 });
85114
85456
  context.processes.spawnDetached({
85115
85457
  argv: [...context.program, "update"],
85116
- logPath: join22(folder, "auto-update.log")
85458
+ logPath: join23(folder, "auto-update.log")
85117
85459
  });
85118
85460
  return { manager: plan2.manager };
85119
85461
  }
@@ -85224,7 +85566,7 @@ async function rushWakeHook({ context, args }) {
85224
85566
  }
85225
85567
 
85226
85568
  // src/services/schedule-commands.service.ts
85227
- var USAGE15 = `Usage:
85569
+ var USAGE14 = `Usage:
85228
85570
  laze schedule add <name> --prompt <text> (--cron "<m h dom mon dow>" | --rrule "<RRULE>" | --at <local time>)
85229
85571
  [--tz <IANA zone>] [--channel <channelId>] [--agent <agentId>]
85230
85572
  laze schedule list
@@ -85239,7 +85581,7 @@ function timingOf(args) {
85239
85581
  const given = [cron, rrule, at].filter(Boolean);
85240
85582
  if (given.length !== 1)
85241
85583
  throw new CliUsageError(`Give exactly one of --cron, --rrule or --at.
85242
- ${USAGE15}`);
85584
+ ${USAGE14}`);
85243
85585
  if (cron) return { kind: "cron", cron };
85244
85586
  if (rrule) return { kind: "rrule", rrule };
85245
85587
  return { kind: "once", at };
@@ -85254,7 +85596,7 @@ function printSchedule({ context, schedule: schedule2 }) {
85254
85596
  async function scheduleAdd({ context, args }) {
85255
85597
  const name3 = args.words.slice(2).join(" ").trim();
85256
85598
  const prompt = flagText({ args, name: "prompt" });
85257
- if (!name3 || !prompt) throw new CliUsageError(USAGE15);
85599
+ if (!name3 || !prompt) throw new CliUsageError(USAGE14);
85258
85600
  const timing = timingOf(args);
85259
85601
  const { client } = await signedIn({ context, args });
85260
85602
  const channelId = flagText({ args, name: "channel" });
@@ -85291,7 +85633,7 @@ function changesOf2(args) {
85291
85633
  async function scheduleUpdate({ context, args }) {
85292
85634
  const scheduleId = args.words[2];
85293
85635
  const changes2 = changesOf2(args);
85294
- if (!scheduleId || Object.keys(changes2).length === 0) throw new CliUsageError(USAGE15);
85636
+ if (!scheduleId || Object.keys(changes2).length === 0) throw new CliUsageError(USAGE14);
85295
85637
  const { client } = await signedIn({ context, args });
85296
85638
  const schedule2 = await client.post("/api/schedules/update", { scheduleId, ...changes2 });
85297
85639
  if (args.flags.json) return context.out(`${JSON.stringify(schedule2, null, 2)}
@@ -85308,7 +85650,7 @@ async function scheduleList({ context, args }) {
85308
85650
  function byId(path) {
85309
85651
  return async ({ context, args }) => {
85310
85652
  const scheduleId = args.words[2];
85311
- if (!scheduleId) throw new CliUsageError(USAGE15);
85653
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85312
85654
  const { client } = await signedIn({ context, args });
85313
85655
  const answer4 = await client.post(`/api/schedules/${path}`, {
85314
85656
  scheduleId
@@ -85322,7 +85664,7 @@ function byId(path) {
85322
85664
  }
85323
85665
  async function scheduleRuns({ context, args }) {
85324
85666
  const scheduleId = args.words[2];
85325
- if (!scheduleId) throw new CliUsageError(USAGE15);
85667
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85326
85668
  const { client } = await signedIn({ context, args });
85327
85669
  const runs = await client.post("/api/schedules/runs", { scheduleId });
85328
85670
  if (args.flags.json) return context.out(`${JSON.stringify(runs, null, 2)}
@@ -85336,7 +85678,7 @@ async function scheduleRuns({ context, args }) {
85336
85678
  }
85337
85679
  async function scheduleRun({ context, args }) {
85338
85680
  const scheduleId = args.words[2];
85339
- if (!scheduleId) throw new CliUsageError(USAGE15);
85681
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85340
85682
  const { client } = await signedIn({ context, args });
85341
85683
  const run4 = await client.post("/api/schedules/run", { scheduleId });
85342
85684
  if (args.flags.json) return context.out(`${JSON.stringify(run4, null, 2)}
@@ -85357,14 +85699,14 @@ var SCHEDULE_COMMANDS = {
85357
85699
  async function schedule({ context, args }) {
85358
85700
  const name3 = args.words[1] ?? "";
85359
85701
  const command = Object.hasOwn(SCHEDULE_COMMANDS, name3) ? SCHEDULE_COMMANDS[name3] : void 0;
85360
- if (!command) throw new CliUsageError(USAGE15);
85702
+ if (!command) throw new CliUsageError(USAGE14);
85361
85703
  await command({ context, args });
85362
85704
  }
85363
85705
 
85364
85706
  // src/services/skill-commands.service.ts
85365
85707
  import { readdir as readdir7, readFile as readFile33 } from "node:fs/promises";
85366
- import { join as join23, relative as relative6, resolve as resolve13 } from "node:path";
85367
- var USAGE16 = `Usage:
85708
+ import { join as join24, relative as relative6, resolve as resolve13 } from "node:path";
85709
+ var USAGE15 = `Usage:
85368
85710
  laze skill list [--agent <agentId>]
85369
85711
  laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
85370
85712
  laze skill install --from <folder> [--as <name>] [--agent <agentId>] a folder with a SKILL.md
@@ -85384,7 +85726,7 @@ async function folderFiles({ root }) {
85384
85726
  const files2 = [];
85385
85727
  for (const entry of entries) {
85386
85728
  if (!entry.isFile()) continue;
85387
- const full = join23(entry.parentPath, entry.name);
85729
+ const full = join24(entry.parentPath, entry.name);
85388
85730
  files2.push({ path: relative6(root, full), content: await readFile33(full, "utf8") });
85389
85731
  }
85390
85732
  return files2.toSorted((a, b) => a.path.localeCompare(b.path));
@@ -85413,7 +85755,7 @@ async function skillList({ context, args }) {
85413
85755
  async function skillInstall({ context, args }) {
85414
85756
  const catalogueId = args.words[2];
85415
85757
  const from = flagText({ args, name: "from" });
85416
- if (!catalogueId === !from) throw new CliUsageError(USAGE16);
85758
+ if (!catalogueId === !from) throw new CliUsageError(USAGE15);
85417
85759
  const name3 = flagText({ args, name: "as" });
85418
85760
  const agent2 = flagText({ args, name: "agent" });
85419
85761
  const files2 = from ? await folderFiles({ root: resolve13(context.cwd, from) }) : void 0;
@@ -85431,7 +85773,7 @@ async function skillInstall({ context, args }) {
85431
85773
  }
85432
85774
  async function skillShow({ context, args }) {
85433
85775
  const name3 = args.words[2];
85434
- if (!name3) throw new CliUsageError(USAGE16);
85776
+ if (!name3) throw new CliUsageError(USAGE15);
85435
85777
  const agent2 = flagText({ args, name: "agent" });
85436
85778
  const { client } = await signedIn({ context, args });
85437
85779
  const skill2 = await client.post("/api/skills/show", {
@@ -85464,7 +85806,7 @@ function agentFlag(args) {
85464
85806
  }
85465
85807
  async function skillRemove({ context, args }) {
85466
85808
  const name3 = args.words[2];
85467
- if (!name3) throw new CliUsageError(USAGE16);
85809
+ if (!name3) throw new CliUsageError(USAGE15);
85468
85810
  const { client } = await signedIn({ context, args });
85469
85811
  const removed = await client.post("/api/skills/remove", {
85470
85812
  name: name3,
@@ -85481,7 +85823,7 @@ async function skillUpdate({ context, args }) {
85481
85823
  const description = typeof args.flags.description === "string" ? args.flags.description : void 0;
85482
85824
  const skillMdFile = flagText({ args, name: "skill-md" });
85483
85825
  if (!name3 || !newName && description === void 0 && !skillMdFile) {
85484
- throw new CliUsageError(USAGE16);
85826
+ throw new CliUsageError(USAGE15);
85485
85827
  }
85486
85828
  const skillMd = skillMdFile ? await readFile33(resolve13(context.cwd, skillMdFile), "utf8") : void 0;
85487
85829
  const { client } = await signedIn({ context, args });
@@ -85500,7 +85842,7 @@ async function skillUpdate({ context, args }) {
85500
85842
  function pinning({ unpin }) {
85501
85843
  return async ({ context, args }) => {
85502
85844
  const name3 = args.words[2];
85503
- if (!name3) throw new CliUsageError(USAGE16);
85845
+ if (!name3) throw new CliUsageError(USAGE15);
85504
85846
  const { client } = await signedIn({ context, args });
85505
85847
  const path = unpin ? "/api/skills/unpin" : "/api/skills/pin";
85506
85848
  const skill2 = await client.post(path, { name: name3, ...agentFlag(args) });
@@ -85524,7 +85866,7 @@ var SKILL_COMMANDS = {
85524
85866
  async function skill({ context, args }) {
85525
85867
  const name3 = args.words[1] ?? "";
85526
85868
  const command = Object.hasOwn(SKILL_COMMANDS, name3) ? SKILL_COMMANDS[name3] : void 0;
85527
- if (!command) throw new CliUsageError(USAGE16);
85869
+ if (!command) throw new CliUsageError(USAGE15);
85528
85870
  await command({ context, args });
85529
85871
  }
85530
85872
 
@@ -86135,11 +86477,11 @@ function statusLine2({ presence: presence2 }) {
86135
86477
  }
86136
86478
 
86137
86479
  // src/services/status-commands.service.ts
86138
- var USAGE17 = "Usage: laze status set <emoji> [text] [--for 30m|1h|4h|today|week|never] [--tz <zone>], laze status clear|away|active";
86480
+ var USAGE16 = "Usage: laze status set <emoji> [text] [--for 30m|1h|4h|today|week|never] [--tz <zone>], laze status clear|away|active";
86139
86481
  function clearAfterOf({ args }) {
86140
86482
  const wanted = flagText({ args, name: "for", fallback: "never" });
86141
86483
  const known = STATUS_CLEAR_AFTER.find((candidate) => candidate === wanted);
86142
- if (!known) throw new CliUsageError(USAGE17);
86484
+ if (!known) throw new CliUsageError(USAGE16);
86143
86485
  return known;
86144
86486
  }
86145
86487
  function answer3({
@@ -86153,7 +86495,7 @@ function answer3({
86153
86495
  }
86154
86496
  async function statusSet({ context, args }) {
86155
86497
  const [, , emoji3, ...words] = args.words;
86156
- if (!emoji3) throw new CliUsageError(USAGE17);
86498
+ if (!emoji3) throw new CliUsageError(USAGE16);
86157
86499
  const clearAfter = clearAfterOf({ args });
86158
86500
  const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
86159
86501
  const { client } = await signedIn({ context, args });
@@ -86177,7 +86519,7 @@ async function statusAway({ context, args }) {
86177
86519
  answer3({ context, args, presence: presence2 });
86178
86520
  }
86179
86521
  async function statusUsage() {
86180
- throw new CliUsageError(USAGE17);
86522
+ throw new CliUsageError(USAGE16);
86181
86523
  }
86182
86524
 
86183
86525
  // src/services/update-commands.service.ts
@@ -86301,7 +86643,7 @@ async function update2({
86301
86643
 
86302
86644
  // src/services/vault-env-commands.service.ts
86303
86645
  import { readFile as readFile36, stat as stat5 } from "node:fs/promises";
86304
- import { dirname as dirname22, join as join24, resolve as resolve15 } from "node:path";
86646
+ import { dirname as dirname22, join as join25, resolve as resolve15 } from "node:path";
86305
86647
 
86306
86648
  // src/rules/vault-manifest.rules.ts
86307
86649
  var VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -86410,7 +86752,7 @@ async function doorOf({
86410
86752
  const turnFile = turnFileOf({ env });
86411
86753
  const headers = {
86412
86754
  "proxy-authorization": proxy.authorization,
86413
- "x-laze-turn": await turnTokenOf3({ env, turnFile, command: "laze vault env" })
86755
+ "x-laze-turn": await turnTokenOf2({ env, turnFile, command: "laze vault env" })
86414
86756
  };
86415
86757
  return {
86416
86758
  keyPath: runKeyPathOf({ turnFile, connection: keyName }),
@@ -86480,14 +86822,14 @@ async function untilAllAnswered({
86480
86822
  `
86481
86823
  );
86482
86824
  while (waiting.size > 0) {
86483
- if (context.nowMs() + POLL_MS2 > deadline) {
86825
+ if (context.nowMs() + POLL_MS > deadline) {
86484
86826
  context.err(
86485
86827
  `laze vault: ${[...waiting.keys()].join(", ")} not approved yet; ask again later.
86486
86828
  `
86487
86829
  );
86488
86830
  return "capped";
86489
86831
  }
86490
- await context.sleep(POLL_MS2);
86832
+ await context.sleep(POLL_MS);
86491
86833
  for (const [key, pending] of waiting) {
86492
86834
  const next = await door.status(pending.requestId);
86493
86835
  if (next.outcome === "ask") waiting.set(key, next);
@@ -86642,7 +86984,7 @@ async function manifestPathOf({
86642
86984
  const environment = flagText({ args, name: "env" });
86643
86985
  const file3 = environment ? `.env.${environment}.vault` : ".env.vault";
86644
86986
  for (let dir = resolve15(context.cwd); ; dir = dirname22(dir)) {
86645
- if (await isFile(join24(dir, file3))) return join24(dir, file3);
86987
+ if (await isFile(join25(dir, file3))) return join25(dir, file3);
86646
86988
  if (dirname22(dir) === dir) break;
86647
86989
  }
86648
86990
  throw new CliUsageError(`laze vault: no ${file3} here or in a parent folder
@@ -86753,7 +87095,7 @@ ${ENV_USAGE}`);
86753
87095
  `);
86754
87096
  return 0;
86755
87097
  }
86756
- const redact = [...released.values()].flatMap(({ fields }) => Object.values(fields));
87098
+ const redact = [...released.values()].flatMap(({ fields }) => secretValuesOf({ fields }));
86757
87099
  return context.runCommand({ command: prepared.command, env, redact });
86758
87100
  }
86759
87101
  async function vaultAws({
@@ -86802,7 +87144,7 @@ async function postInTurn({
86802
87144
  body
86803
87145
  }) {
86804
87146
  const env = context.environment.inherited;
86805
- const turn = await turnTokenOf3({
87147
+ const turn = await turnTokenOf2({
86806
87148
  env,
86807
87149
  turnFile: turnFileOf({ env }),
86808
87150
  command: "laze vault save"
@@ -87505,7 +87847,7 @@ async function whatsappBusiness({
87505
87847
  }
87506
87848
 
87507
87849
  // src/services/whatsapp-pairing-commands.service.ts
87508
- import { writeFile as writeFile22 } from "node:fs/promises";
87850
+ import { writeFile as writeFile23 } from "node:fs/promises";
87509
87851
  import { resolve as resolve17 } from "node:path";
87510
87852
  var WHATSAPP_PAIRING_USAGE = [
87511
87853
  " laze whatsapp pair <machine> [--qr <file.svg>] link WhatsApp on your machine; scan the code (owner)",
@@ -87526,7 +87868,7 @@ function svgOf(dataUrl) {
87526
87868
  }
87527
87869
  async function report({ context, args, pairing: pairing2 }) {
87528
87870
  const qrFile = pairing2.qrSvg ? resolve17(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
87529
- if (qrFile && pairing2.qrSvg) await writeFile22(qrFile, svgOf(pairing2.qrSvg), "utf8");
87871
+ if (qrFile && pairing2.qrSvg) await writeFile23(qrFile, svgOf(pairing2.qrSvg), "utf8");
87530
87872
  if (args.flags.json) return context.out(`${JSON.stringify({ ...pairing2, qrFile }, null, 2)}
87531
87873
  `);
87532
87874
  context.out(`${pairing2.pairingId} ${pairing2.state}
@@ -87591,7 +87933,7 @@ var PATHS3 = {
87591
87933
  var STATUS_WAIT_SECONDS2 = 50;
87592
87934
  var STATUS_CALLS2 = 2;
87593
87935
  var SETTLED = /* @__PURE__ */ new Set(["sent", "denied", "expired", "failed"]);
87594
- var USAGE18 = [
87936
+ var USAGE17 = [
87595
87937
  "Usage: laze whatsapp chats <machine> [--limit <n>] the chats on the machine, newest first",
87596
87938
  " laze whatsapp read <machine> <chat> [--limit <n>] a chat's last messages, oldest first",
87597
87939
  ' laze whatsapp send <machine> <chat> "<text>" send as the owner; an agent waits for their approval',
@@ -87601,14 +87943,14 @@ var USAGE18 = [
87601
87943
  ].join("\n");
87602
87944
  function word2({ args, at }) {
87603
87945
  const value = args.words[at];
87604
- if (!value) throw new CliUsageError(USAGE18);
87946
+ if (!value) throw new CliUsageError(USAGE17);
87605
87947
  return value;
87606
87948
  }
87607
87949
  function limitOf5({ args }) {
87608
87950
  const text2 = flagText({ args, name: "limit" });
87609
87951
  if (!text2) return {};
87610
87952
  const limit = Number(text2);
87611
- if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(USAGE18);
87953
+ if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(USAGE17);
87612
87954
  return { limit };
87613
87955
  }
87614
87956
  async function chats({ context, args }) {
@@ -87670,7 +88012,7 @@ Still waiting. Run \`laze whatsapp status ${send4.id}\` later to see the answer.
87670
88012
  }
87671
88013
  async function send3({ context, args }) {
87672
88014
  const text2 = args.words.slice(4).join(" ") || args.rest.join(" ");
87673
- if (!text2) throw new CliUsageError(USAGE18);
88015
+ if (!text2) throw new CliUsageError(USAGE17);
87674
88016
  const client = await computeClient({ context, args });
87675
88017
  const asked = await client.post(PATHS3.send, {
87676
88018
  machine: word2({ args, at: 2 }),
@@ -87700,11 +88042,11 @@ async function whatsapp({
87700
88042
  if (command === "status") return status8({ context, args });
87701
88043
  const linking = whatsappPairingCommand(command);
87702
88044
  if (linking) return linking({ context, args });
87703
- throw new CliUsageError(USAGE18);
88045
+ throw new CliUsageError(USAGE17);
87704
88046
  }
87705
88047
 
87706
88048
  // src/services/wiki-commands.service.ts
87707
- var USAGE19 = `Usage:
88049
+ var USAGE18 = `Usage:
87708
88050
  laze wiki list
87709
88051
  laze wiki get <path>
87710
88052
  laze wiki put <path> <markdown|@file|-> [--title <title>] [--channel <channel>] [--base <version>]
@@ -87724,7 +88066,7 @@ async function wikiList({ context, args }) {
87724
88066
  }
87725
88067
  async function wikiGet({ context, args }) {
87726
88068
  const path = args.words[2];
87727
- if (!path) throw new CliUsageError(USAGE19);
88069
+ if (!path) throw new CliUsageError(USAGE18);
87728
88070
  const { client } = await signedIn({ context, args });
87729
88071
  const page = await client.post("/api/wiki/get", { path });
87730
88072
  if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
@@ -87741,7 +88083,7 @@ Linked from: ${page.backlinks.map((link) => link.path).join(", ")}
87741
88083
  async function wikiPut({ context, args }) {
87742
88084
  const path = args.words[2];
87743
88085
  const value = args.words.slice(3).join(" ");
87744
- if (!path || !value) throw new CliUsageError(USAGE19);
88086
+ if (!path || !value) throw new CliUsageError(USAGE18);
87745
88087
  const body = await textArgument({ context, value });
87746
88088
  const title = flagText({ args, name: "title" });
87747
88089
  const channel = flagText({ args, name: "channel" });
@@ -87761,7 +88103,7 @@ async function wikiPut({ context, args }) {
87761
88103
  }
87762
88104
  async function wikiSearch({ context, args }) {
87763
88105
  const query = args.words.slice(2).join(" ").trim();
87764
- if (!query) throw new CliUsageError(USAGE19);
88106
+ if (!query) throw new CliUsageError(USAGE18);
87765
88107
  const { client } = await signedIn({ context, args });
87766
88108
  const hits = await client.post("/api/wiki/search", { query });
87767
88109
  if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
@@ -87771,7 +88113,7 @@ async function wikiSearch({ context, args }) {
87771
88113
  }
87772
88114
  async function wikiHistory({ context, args }) {
87773
88115
  const path = args.words[2];
87774
- if (!path) throw new CliUsageError(USAGE19);
88116
+ if (!path) throw new CliUsageError(USAGE18);
87775
88117
  const { client } = await signedIn({ context, args });
87776
88118
  const revisions = await client.post("/api/wiki/history", { path });
87777
88119
  if (args.flags.json) return context.out(`${JSON.stringify(revisions, null, 2)}
@@ -87785,7 +88127,7 @@ async function wikiHistory({ context, args }) {
87785
88127
  }
87786
88128
  async function wikiMove({ context, args }) {
87787
88129
  const [, , path, to] = args.words;
87788
- if (!path || !to) throw new CliUsageError(USAGE19);
88130
+ if (!path || !to) throw new CliUsageError(USAGE18);
87789
88131
  const { client } = await signedIn({ context, args });
87790
88132
  const page = await client.post("/api/wiki/move", { path, to });
87791
88133
  if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
@@ -87795,7 +88137,7 @@ async function wikiMove({ context, args }) {
87795
88137
  }
87796
88138
  async function wikiRemove({ context, args }) {
87797
88139
  const path = args.words[2];
87798
- if (!path) throw new CliUsageError(USAGE19);
88140
+ if (!path) throw new CliUsageError(USAGE18);
87799
88141
  const { client } = await signedIn({ context, args });
87800
88142
  const removed = await client.post("/api/wiki/remove", { path });
87801
88143
  if (args.flags.json) return context.out(`${JSON.stringify(removed)}
@@ -87815,7 +88157,7 @@ var WIKI_COMMANDS = {
87815
88157
  async function wiki({ context, args }) {
87816
88158
  const name3 = args.words[1] ?? "";
87817
88159
  const command = Object.hasOwn(WIKI_COMMANDS, name3) ? WIKI_COMMANDS[name3] : void 0;
87818
- if (!command) throw new CliUsageError(USAGE19);
88160
+ if (!command) throw new CliUsageError(USAGE18);
87819
88161
  await command({ context, args });
87820
88162
  }
87821
88163
 
@@ -88131,8 +88473,27 @@ async function list9({ context, args }) {
88131
88473
  context,
88132
88474
  args,
88133
88475
  answer: answer4,
88134
- text: (members3) => members3.map((it) => `${ROLE_NAMES2[it.role]} ${it.name} ${it.email} ${it.userId}
88135
- `).join("")
88476
+ text: (members3) => members3.map((it) => {
88477
+ const aka2 = it.aliases?.length ? ` aka ${it.aliases.join(", ")}` : "";
88478
+ return `${ROLE_NAMES2[it.role]} ${it.name} ${it.email} ${it.userId}${aka2}
88479
+ `;
88480
+ }).join("")
88481
+ });
88482
+ }
88483
+ async function aka({ context, args }) {
88484
+ const { client } = await signedIn({ context, args });
88485
+ const names = args.words.slice(2);
88486
+ const clear = Boolean(args.flags.clear);
88487
+ const answer4 = names.length > 0 || clear ? await client.post("/api/agents/me/workspace/aka/set", {
88488
+ aliases: clear ? [] : names
88489
+ }) : await client.post("/api/agents/me/workspace/aka", {});
88490
+ print8({
88491
+ context,
88492
+ args,
88493
+ answer: answer4,
88494
+ text: (it) => it.aliases?.length ? `${it.name}, also known as ${it.aliases.join(", ")}
88495
+ ` : `${it.name} goes by no other name. Add some with laze members aka <name>...
88496
+ `
88136
88497
  });
88137
88498
  }
88138
88499
  async function invite({ context, args }) {
@@ -88264,6 +88625,7 @@ var MEMBERS_COMMANDS = {
88264
88625
  "revoke-invite": revokeInvite,
88265
88626
  "invite-link": inviteLink,
88266
88627
  role,
88628
+ aka,
88267
88629
  remove: remove5,
88268
88630
  requests,
88269
88631
  approve: deciding("approved"),
@@ -88275,7 +88637,7 @@ async function members2({ context, args }) {
88275
88637
  const command = MEMBERS_COMMANDS[sub];
88276
88638
  if (!command) {
88277
88639
  throw new CliUsageError(
88278
- "Usage: laze members [invite | invites | revoke-invite | invite-link | role | remove | requests | approve | deny]"
88640
+ "Usage: laze members [invite | invites | revoke-invite | invite-link | role | aka | remove | requests | approve | deny]"
88279
88641
  );
88280
88642
  }
88281
88643
  return command({ context, args });
@@ -88327,6 +88689,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
88327
88689
  laze members invite <email> [--role owner|admin|member|guest] invite someone (admins)
88328
88690
  laze members invites | revoke-invite <email|id> invitations waiting, or take one back (admins)
88329
88691
  laze members invite-link <email|id> a fresh link for an invitation, shown once (admins)
88692
+ laze members aka [<name>...] [--clear] the other names you go by, such as a nickname
88330
88693
  laze members role <member> owner|admin|member|guest change a member's role (admins)
88331
88694
  laze members remove <member> take someone out of the workspace (admins)
88332
88695
  laze members requests | approve <id> | deny <id> access requests waiting for an admin
@@ -88458,8 +88821,10 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
88458
88821
  laze connect providers|start|search|mcp|mcp-key|github|card|card-key connect services as yourself
88459
88822
  laze connect install|status|stop|uninstall the service that hands linked Codex sessions their messages
88460
88823
  laze openclaw list|connect|agent|agent-key|feed|disconnect your OpenClaw gateways and their agents
88461
- laze browser open|tabs|goto|read|ask|cdp|share|close a live browser tab pinned to the conversation
88824
+ laze browser open|tabs|goto|read|ask|login|cdp|share|close a live browser tab pinned to the conversation
88462
88825
  Show your work: open pages in a browser tab of the conversation; ask the person you work for to sign in there, never ask for a password
88826
+ Any agent working for the tab's owner drives it, connected agents (Claude Code, Codex) from their own session included
88827
+ laze browser login <tab> --vault <connection> types a saved sign-in only when the person says to use it; laze browser --help for all
88463
88828
  laze browser setup|cdp|screen|status <machine> a machine with Chrome a person signs in on, for agents
88464
88829
  Sites without an API need a person's login: open a browser tab and ask there, never ask for a password; a browser machine only when the person asks for one
88465
88830
  laze browser setup <site> --on <machine> the browser on a person's own machine instead, at no Laze compute cost
@@ -88723,7 +89088,9 @@ async function runCli({
88723
89088
  [openclaw, OPENCLAW_USAGE],
88724
89089
  [chatActions, CHAT_ACTIONS_USAGE],
88725
89090
  [agentLogins, LOGINS_HELP],
88726
- [agentPools, POOLS_HELP]
89091
+ [agentPools, POOLS_HELP],
89092
+ [browser, `${BROWSER_USAGE}
89093
+ `]
88727
89094
  ]);
88728
89095
  if (command && args.flags.help && ownHelp.has(command)) {
88729
89096
  context.out(ownHelp.get(command) ?? HELP);