@lazehq/cli 0.1.48 → 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 +907 -502
  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.48";
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
  });
@@ -65445,6 +65556,11 @@ var callerSchemaDefinition = external_exports.object({
65445
65556
  /** The person's time zone, or the agent owner's (IANA; UTC while Laze does not know it). */
65446
65557
  timeZone: external_exports.string().optional()
65447
65558
  });
65559
+ var agentGuideFilesSchemaDefinition = external_exports.object({
65560
+ "work/SOUL.md": external_exports.string(),
65561
+ "work/AGENTS.md": external_exports.string(),
65562
+ "work/CLAUDE.md": external_exports.string()
65563
+ });
65448
65564
  var agentChannelLevelSchema = external_exports.enum(["everything", "mentions"]);
65449
65565
  var callerChannelSchemaDefinition = external_exports.object({
65450
65566
  id: idSchema15,
@@ -65668,6 +65784,15 @@ var AgentHopLimitNoticeSlot = agentUi.component("hopLimitNotice");
65668
65784
  var AgentRetryTurnSlot = agentUi.component("retryTurn");
65669
65785
  var AgentHeldNoticeSlot = agentUi.component("heldNotice");
65670
65786
 
65787
+ // ../../modules/agent/contract/src/laze-changes.ts
65788
+ var lazeChangeSchemaDefinition = external_exports.object({
65789
+ /** The day it reached prod, YYYY-MM-DD. */
65790
+ date: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/),
65791
+ /** The refusal codes it lifted; empty when the refusal had no code of its own. */
65792
+ codes: external_exports.array(external_exports.string()),
65793
+ text: external_exports.string().min(1)
65794
+ });
65795
+
65671
65796
  // ../../modules/agent/contract/src/agent.config.ts
65672
65797
  var positiveInt3 = external_exports.coerce.number().int().positive();
65673
65798
  var agentConfig = Config.define((c) => ({
@@ -66117,7 +66242,9 @@ var callerWorkspaceMemberSchemaDefinition = external_exports.object({
66117
66242
  email: external_exports.string(),
66118
66243
  name: external_exports.string(),
66119
66244
  role: roleSchema,
66120
- 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()
66121
66248
  });
66122
66249
  var callerWorkspaceInviteSchemaDefinition = external_exports.object({
66123
66250
  id: external_exports.string().min(1),
@@ -66159,6 +66286,9 @@ var decideRequestAsCallerInputSchemaDefinition = external_exports.object({
66159
66286
  requestId: external_exports.string().trim().min(1).max(80),
66160
66287
  decision: external_exports.enum(["approved", "denied"])
66161
66288
  });
66289
+ var setAliasesAsCallerInputSchemaDefinition = external_exports.object({
66290
+ aliases: external_exports.array(external_exports.string().trim().max(40)).max(5)
66291
+ });
66162
66292
  var renameWorkspaceAsCallerInputSchemaDefinition = external_exports.object({
66163
66293
  name: external_exports.string().trim().min(1).max(80)
66164
66294
  });
@@ -67226,6 +67356,10 @@ var slackProfilesSchemaDefinition = external_exports.object({
67226
67356
  profiles: external_exports.array(slackProfileSchemaDefinition)
67227
67357
  });
67228
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;
67229
67363
 
67230
67364
  // ../../modules/slack/contract/src/slack-setup.ts
67231
67365
  var workspaceIdSchema13 = external_exports.string().min(1);
@@ -67594,7 +67728,7 @@ var slackSearchAnswerSchemaDefinition = external_exports.object({
67594
67728
  var slackSearchAnswerSchema = slackSearchAnswerSchemaDefinition;
67595
67729
  var SlackApi = moduleApi()("slack");
67596
67730
  var workspaceInput3 = external_exports.object({ workspaceId: workspaceIdSchema14 });
67597
- 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();
67598
67732
 
67599
67733
  // ../../modules/slack/contract/src/slack-keys.ts
67600
67734
  var SLACK_KEY_PATHS = {
@@ -71048,6 +71182,23 @@ are waiting, if you think one was missed.
71048
71182
  with \`laze app pull --app <app>\` (its files: page, plan, code) and
71049
71183
  \`laze app records list <collection> --app <app>\` (its data).
71050
71184
 
71185
+ ## When Laze refused something
71186
+
71187
+ A refusal is about Laze as it was then; Laze ships fixes several times a day. Before telling
71188
+ someone an action cannot be done because Laze refused it earlier, run \`laze changes\` and try it
71189
+ again. When a change lifts a refusal you hit in a conversation, tell the people there once that
71190
+ it works now.
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
+
71051
71202
  If \`laze\` is not on the PATH, run the same commands through \`npx -y @lazehq/cli@latest\`.
71052
71203
  Never print or repeat your Laze key.
71053
71204
  `;
@@ -72806,6 +72957,9 @@ var appSchemaDefinition = external_exports.object({
72806
72957
  publishedUrl: external_exports.string(),
72807
72958
  /** The live version; null before the first push or while the app is taken offline. */
72808
72959
  publishedVersion: appVersionIdSchema.nullable(),
72960
+ /** Pages loaded before apps were trunk-based still require these: the origin and live version. */
72961
+ draftUrl: external_exports.string().optional(),
72962
+ draftVersion: appVersionIdSchema.nullable().optional(),
72809
72963
  pendingPublish: publishRequestSchema.nullable(),
72810
72964
  /** The standing approval for public publishes; absent or null when every one asks. */
72811
72965
  publishLease: publishLeaseSchema.nullable().optional(),
@@ -76423,6 +76577,18 @@ async function workspaces({ context, args }) {
76423
76577
  );
76424
76578
  }
76425
76579
  }
76580
+ async function changes({ context, args }) {
76581
+ const { client } = await signedIn({ context, args });
76582
+ const list10 = await client.get("/api/agents/me/changes");
76583
+ if (args.flags.json) return context.out(`${JSON.stringify(list10, null, 2)}
76584
+ `);
76585
+ if (list10.length === 0) return context.out("No recent changes.\n");
76586
+ for (const change2 of list10) {
76587
+ const lifted = change2.codes.length > 0 ? ` (lifts ${change2.codes.join(", ")})` : "";
76588
+ context.out(`${change2.date}${lifted}: ${change2.text}
76589
+ `);
76590
+ }
76591
+ }
76426
76592
 
76427
76593
  // src/services/billing-commands.service.ts
76428
76594
  var BILLING_USAGE = `Usage:
@@ -76584,8 +76750,370 @@ async function billing({ context, args }) {
76584
76750
 
76585
76751
  // src/services/browser-commands.service.ts
76586
76752
  import { randomBytes } from "node:crypto";
76587
- 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";
76588
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
+ }
76589
77117
 
76590
77118
  // src/services/browser-tab-commands.service.ts
76591
77119
  var BROWSER_TAB_PATHS = {
@@ -76597,19 +77125,30 @@ var BROWSER_TAB_PATHS = {
76597
77125
  ask: "/api/compute/browser-tabs/ask",
76598
77126
  share: "/api/compute/browser-tabs/share",
76599
77127
  close: "/api/compute/browser-tabs/close",
76600
- cdp: "/api/compute/browser-tabs/cdp"
77128
+ cdp: "/api/compute/browser-tabs/cdp",
77129
+ login: "/api/compute/browser-tabs/login"
76601
77130
  };
77131
+ var ASK_WAIT_SECONDS = 15 * 60;
77132
+ var ASK_POLL_MS = 3e3;
76602
77133
  var BROWSER_TAB_USAGE = [
76603
77134
  "Usage: laze browser open <url> [--title <title>] [--channel <channel>] a live browser tab in the conversation",
76604
77135
  " laze browser tabs [--channel <channel>] the conversation's browser tabs",
76605
77136
  " laze browser tab <tab> one tab: its owner, sharing and page",
76606
77137
  " laze browser goto <tab> <url> send the tab to another page",
76607
77138
  " laze browser read <tab> the page's address, title and text",
76608
- " 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",
76609
77142
  " laze browser cdp <tab> a CDP address on the tab's browser",
76610
77143
  " laze browser share <tab> private|watch|use who sees the screen and who types into it",
76611
77144
  " laze browser close <tab> unpin the tab and close its browser",
76612
- "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."
76613
77152
  ].join("\n");
76614
77153
  var SHARING = /* @__PURE__ */ new Set(["private", "watch", "use"]);
76615
77154
  function channelOf({ context, args }) {
@@ -76641,6 +77180,12 @@ async function openTab({ args, client, channel, print: print9 }) {
76641
77180
  ...title ? { title } : {},
76642
77181
  ...channel
76643
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
+ );
76644
77189
  print9(
76645
77190
  tab,
76646
77191
  `Opened ${tab.title} (${tab.id}) in ${tab.ownerName}'s browser, pinned as a tab of the conversation.
@@ -76678,17 +77223,134 @@ async function readTab({ args, client, channel, print: print9 }) {
76678
77223
  });
76679
77224
  print9(page, pageText({ page }));
76680
77225
  }
76681
- async function askOnTab({ args, client, channel, print: print9 }) {
77226
+ async function askOnTab(run4) {
77227
+ const { args, client, channel, print: print9 } = run4;
76682
77228
  const tab = word({ args, at: 2 });
76683
77229
  const text2 = args.words.slice(3).join(" ").trim();
76684
77230
  if (!text2) throw new CliUsageError(BROWSER_TAB_USAGE);
76685
77231
  const asked = await client.post(BROWSER_TAB_PATHS.ask, { tab, text: text2, ...channel });
76686
- print9(
76687
- asked,
76688
- `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".
76689
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.
76690
77262
  `
76691
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;
76692
77354
  }
76693
77355
  async function shareTab({ args, client, channel, print: print9 }) {
76694
77356
  const tab = word({ args, at: 2 });
@@ -76714,6 +77376,7 @@ var TAB_RUNS = {
76714
77376
  goto: gotoTab,
76715
77377
  read: readTab,
76716
77378
  ask: askOnTab,
77379
+ login: loginOnTab,
76717
77380
  share: shareTab,
76718
77381
  close: closeTab
76719
77382
  };
@@ -76727,7 +77390,7 @@ async function browserTab({
76727
77390
  const json5 = Boolean(args.flags.json);
76728
77391
  const print9 = (value, text2) => context.out(json5 ? `${JSON.stringify(value, null, 2)}
76729
77392
  ` : text2);
76730
- 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 });
76731
77394
  }
76732
77395
  async function browserTabCdp({
76733
77396
  context,
@@ -77142,7 +77805,7 @@ var PATHS2 = {
77142
77805
  wake: "/api/compute/machines/wake",
77143
77806
  delete: "/api/compute/machines/delete"
77144
77807
  };
77145
- var USAGE6 = [
77808
+ var BROWSER_USAGE = [
77146
77809
  "Usage: laze browser setup <site> [--name <machine>] a machine with Chrome a person signs in on",
77147
77810
  " laze browser setup <site> --on <machine> the same on a person's own machine (laze machine list)",
77148
77811
  " laze browser cdp <machine> a CDP address for this turn (Playwright connectOverCDP)",
@@ -77152,7 +77815,7 @@ var USAGE6 = [
77152
77815
  "",
77153
77816
  BROWSER_TAB_USAGE
77154
77817
  ].join("\n");
77155
- async function turnTokenOf2({
77818
+ async function turnTokenOf3({
77156
77819
  context,
77157
77820
  args,
77158
77821
  client,
@@ -77162,7 +77825,7 @@ async function turnTokenOf2({
77162
77825
  const pinned = env.LAZE_TURN_TOKEN?.trim();
77163
77826
  if (pinned) return pinned;
77164
77827
  if (env.LAZE_TURN_FILE) {
77165
- return readFile17(env.LAZE_TURN_FILE, "utf8").then(
77828
+ return readFile18(env.LAZE_TURN_FILE, "utf8").then(
77166
77829
  (text2) => text2.trim(),
77167
77830
  () => ""
77168
77831
  );
@@ -77175,7 +77838,7 @@ async function computeClient({
77175
77838
  args
77176
77839
  }) {
77177
77840
  const { client, profile } = await signedIn({ context, args });
77178
- const turn = await turnTokenOf2({ context, args, client, agent: profile.kind === "agent" });
77841
+ const turn = await turnTokenOf3({ context, args, client, agent: profile.kind === "agent" });
77179
77842
  return turn ? client.withHeaders({ "x-laze-turn": turn }) : client;
77180
77843
  }
77181
77844
  function siteLine(machine2) {
@@ -77189,12 +77852,12 @@ function statusLine(machine2) {
77189
77852
  }
77190
77853
  function machineArg({ args }) {
77191
77854
  const machine2 = args.words[2];
77192
- if (!machine2) throw new CliUsageError(USAGE6);
77855
+ if (!machine2) throw new CliUsageError(BROWSER_USAGE);
77193
77856
  return machine2;
77194
77857
  }
77195
77858
  async function setup({ context, args }) {
77196
77859
  const site = args.words[2];
77197
- if (!site) throw new CliUsageError(USAGE6);
77860
+ if (!site) throw new CliUsageError(BROWSER_USAGE);
77198
77861
  const name3 = flagText({ args, name: "name" }) || void 0;
77199
77862
  const on = flagText({ args, name: "on" }) || void 0;
77200
77863
  const client = await computeClient({ context, args });
@@ -77252,7 +77915,7 @@ async function answering({
77252
77915
  }
77253
77916
  function bridgeStatePath({ context, machine: machine2 }) {
77254
77917
  const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
77255
- return join19(dirname17(context.environment.configPath), "bridges", `${safe}.json`);
77918
+ return join21(dirname18(context.environment.configPath), "bridges", `${safe}.json`);
77256
77919
  }
77257
77920
  async function bridgePort({
77258
77921
  context,
@@ -77260,7 +77923,7 @@ async function bridgePort({
77260
77923
  access
77261
77924
  }) {
77262
77925
  const path = bridgeStatePath({ context, machine: machine2 });
77263
- const live = await readFile17(path, "utf8").then(
77926
+ const live = await readFile18(path, "utf8").then(
77264
77927
  (text2) => JSON.parse(text2),
77265
77928
  () => void 0
77266
77929
  );
@@ -77273,15 +77936,15 @@ async function bridgePort({
77273
77936
  key,
77274
77937
  ...target
77275
77938
  });
77276
- await mkdir17(dirname17(path), { recursive: true, mode: 448 });
77277
- 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 });
77278
77941
  return port;
77279
77942
  }
77280
77943
  async function bridge({ context }) {
77281
77944
  const env = context.environment.inherited;
77282
77945
  const target = env.LAZE_CDP_TARGET;
77283
77946
  const expiresAt = env.LAZE_CDP_EXPIRES_AT;
77284
- if (!target || !expiresAt) throw new CliUsageError(USAGE6);
77947
+ if (!target || !expiresAt) throw new CliUsageError(BROWSER_USAGE);
77285
77948
  let until = Temporal3.Instant.from(expiresAt).epochMilliseconds;
77286
77949
  const running = await startCdpBridge({
77287
77950
  target,
@@ -77338,8 +78001,21 @@ async function change({
77338
78001
  `);
77339
78002
  context.out(statusLine(machine2));
77340
78003
  }
77341
- var TAB_COMMANDS = /* @__PURE__ */ new Set(["open", "tabs", "tab", "goto", "read", "ask", "share", "close"]);
77342
- 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
+ }) {
77343
78019
  const command = args.words[1];
77344
78020
  if (command && TAB_COMMANDS.has(command))
77345
78021
  return browserTab({ context, args, client: await computeClient({ context, args }) });
@@ -77350,7 +78026,7 @@ async function browser({ context, args }) {
77350
78026
  if (command === "status") return status3({ context, args });
77351
78027
  if (command === "sleep" || command === "wake" || command === "delete")
77352
78028
  return change({ context, args, path: PATHS2[command] });
77353
- throw new CliUsageError(USAGE6);
78029
+ throw new CliUsageError(BROWSER_USAGE);
77354
78030
  }
77355
78031
 
77356
78032
  // src/rules/channel-format.rules.ts
@@ -77922,7 +78598,7 @@ async function channelSettings({ context, args }) {
77922
78598
  }
77923
78599
 
77924
78600
  // src/services/chat-actions-commands.service.ts
77925
- import { readFile as readFile18 } from "node:fs/promises";
78601
+ import { readFile as readFile19 } from "node:fs/promises";
77926
78602
  import { basename as basename3, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve7 } from "node:path";
77927
78603
 
77928
78604
  // src/rules/file-types.rules.ts
@@ -78004,7 +78680,7 @@ async function uploadFile({
78004
78680
 
78005
78681
  // src/services/thread-wait-commands.service.ts
78006
78682
  var USAGE7 = "Usage: laze thread <message-id> --wait-reply [--timeout <1-3600 seconds>]";
78007
- var POLL_MS = 3e3;
78683
+ var POLL_MS2 = 3e3;
78008
78684
  function timeoutOf({ args }) {
78009
78685
  const seconds = Number(flagText({ args, name: "timeout", fallback: "600" }));
78010
78686
  if (!Number.isInteger(seconds) || seconds < 1 || seconds > 3600) throw new CliUsageError(USAGE7);
@@ -78021,8 +78697,8 @@ async function threadWaitReply({
78021
78697
  const read3 = () => client.post(CHAT_KEY_PATHS.thread, { messageId });
78022
78698
  const seen = new Set((await read3()).replies.map((reply2) => reply2.id));
78023
78699
  const isNew = (reply2) => reply2.author.kind === "person" && !seen.has(reply2.id);
78024
- for (let waited = 0; waited < seconds * 1e3; waited += POLL_MS) {
78025
- await context.sleep(POLL_MS);
78700
+ for (let waited = 0; waited < seconds * 1e3; waited += POLL_MS2) {
78701
+ await context.sleep(POLL_MS2);
78026
78702
  const reply2 = (await read3()).replies.find(isNew);
78027
78703
  if (!reply2) continue;
78028
78704
  const line = `${reply2.seq} ${reply2.id} person ${reply2.author.id} ${reply2.body}
@@ -78260,7 +78936,7 @@ function uploadNameOf({ cwd, path }) {
78260
78936
  }
78261
78937
  var fileUpload = async ({ context, args, client }) => {
78262
78938
  const path = resolve7(context.cwd, wordAt(args, 3));
78263
- const bytes = new Uint8Array(await readFile18(path));
78939
+ const bytes = new Uint8Array(await readFile19(path));
78264
78940
  const answer4 = await uploadFile({
78265
78941
  context,
78266
78942
  client,
@@ -78433,7 +79109,7 @@ async function chatActions({
78433
79109
  }
78434
79110
 
78435
79111
  // src/services/claude-monitor.service.ts
78436
- import { readFile as readFile19, rm as rm9 } from "node:fs/promises";
79112
+ import { readFile as readFile20, rm as rm10 } from "node:fs/promises";
78437
79113
  var MONITOR_IDLE_MS = 3e4;
78438
79114
  var MONITOR_OUTRANKED_MS = 3e3;
78439
79115
  async function deliverOnce({
@@ -78495,7 +79171,7 @@ async function monitorRound(turn) {
78495
79171
  async function release({ context, profile }) {
78496
79172
  const lock = statePathOf({ context, kind: "waiters", profile });
78497
79173
  if ((await holderOf({ path: lock }))?.pid === context.processes.pid)
78498
- await rm9(lock, { force: true });
79174
+ await rm10(lock, { force: true });
78499
79175
  }
78500
79176
  async function monitorHook({ context, args }) {
78501
79177
  const claudePid = await claudePidOf({ context });
@@ -78534,7 +79210,7 @@ async function monitorSessionOf({
78534
79210
  const fromEnv = sessionOf({ context, harness: "claude-code", sessionId });
78535
79211
  if (fromEnv || !claudePid) return fromEnv;
78536
79212
  const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
78537
- return readFile19(path, "utf8").then(
79213
+ return readFile20(path, "utf8").then(
78538
79214
  (text2) => JSON.parse(text2),
78539
79215
  () => void 0
78540
79216
  );
@@ -78571,6 +79247,8 @@ var browserTabDefinition = external_exports.object({
78571
79247
  /** What an agent asked a person to do in the tab, until someone who may answer presses Done. */
78572
79248
  ask: browserTabAskDefinition.nullable(),
78573
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(),
78574
79252
  /** What the reader may do: see the screen, type into it, change the tab; asked: the open
78575
79253
  * request names them. */
78576
79254
  you: external_exports.object({
@@ -78618,6 +79296,31 @@ var shareDefinition = external_exports.object({
78618
79296
  sharing: browserTabSharingSchema
78619
79297
  });
78620
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
+ });
78621
79324
  var browserTabPageDefinition = external_exports.object({
78622
79325
  tabId: external_exports.string().min(1),
78623
79326
  url: external_exports.string(),
@@ -78657,6 +79360,7 @@ var restBrowserTabInputDefinition = browserTabRefDefinition.omit({ workspaceId:
78657
79360
  var restBrowserTabGotoInputDefinition = gotoDefinition.omit({ workspaceId: true });
78658
79361
  var restBrowserTabAskInputDefinition = askDefinition.omit({ workspaceId: true });
78659
79362
  var restBrowserTabShareInputDefinition = shareDefinition.omit({ workspaceId: true });
79363
+ var restBrowserTabLoginInputDefinition = loginDefinition.omit({ workspaceId: true });
78660
79364
 
78661
79365
  // ../../modules/compute/contract/src/compute.config.ts
78662
79366
  var computeConfig = Config.define((c) => ({
@@ -79969,6 +80673,7 @@ var machineWatchStateDefinition = external_exports.object({
79969
80673
  var computeUi = uiTokens("compute");
79970
80674
  var ComputeBrowserTabSlot = computeUi.component("browser-tab");
79971
80675
  var ComputeOpenBrowserSlot = computeUi.component("open-browser");
80676
+ var ComputeBrowserLinkOfferSlot = computeUi.component("browser-link-offer");
79972
80677
 
79973
80678
  // src/services/computer-fleet-commands.service.ts
79974
80679
  var COMPUTER_FLEET_USAGE = ` laze computer mine [--json] every Laze computer your agents may run on, your default one first
@@ -80242,10 +80947,10 @@ async function computer({ context, args }) {
80242
80947
  }
80243
80948
 
80244
80949
  // src/services/connect-commands.service.ts
80245
- import { readFile as readFile21 } from "node:fs/promises";
80950
+ import { readFile as readFile22 } from "node:fs/promises";
80246
80951
 
80247
80952
  // src/services/mcp-gateway.service.ts
80248
- import { readFile as readFile20 } from "node:fs/promises";
80953
+ import { readFile as readFile21 } from "node:fs/promises";
80249
80954
  import { createInterface as createInterface3 } from "node:readline";
80250
80955
  var TURN_HEADER = "x-laze-turn";
80251
80956
  function serveMcpGateway({
@@ -80288,7 +80993,7 @@ async function relayMcpLines({
80288
80993
  const github3 = env.LAZE_GITHUB_CONNECTION;
80289
80994
  const url2 = `${profile.url.replace(/\/+$/, "")}/api/connectors/mcp/${encodeURIComponent(profile.agentId)}${github3 ? `?github=${encodeURIComponent(github3)}` : ""}`;
80290
80995
  const turnFile = env.LAZE_TURN_FILE;
80291
- const readTurn = () => readFile20(turnFile, "utf8").then(
80996
+ const readTurn = () => readFile21(turnFile, "utf8").then(
80292
80997
  (text2) => text2.trim(),
80293
80998
  () => ""
80294
80999
  );
@@ -80378,7 +81083,7 @@ async function turnOf({ context }) {
80378
81083
  const pinned = env.LAZE_TURN_TOKEN?.trim();
80379
81084
  if (pinned) return pinned;
80380
81085
  const file3 = env.LAZE_TURN_FILE;
80381
- const turn = file3 ? await readFile21(file3, "utf8").then(
81086
+ const turn = file3 ? await readFile22(file3, "utf8").then(
80382
81087
  (text2) => text2.trim(),
80383
81088
  () => ""
80384
81089
  ) : "";
@@ -80711,335 +81416,6 @@ var listDevices = async ({ context, args }) => {
80711
81416
  }
80712
81417
  };
80713
81418
 
80714
- // src/services/vault-commands.service.ts
80715
- import { createHash as createHash2 } from "node:crypto";
80716
- import { mkdir as mkdir18, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
80717
- import { tmpdir as tmpdir2 } from "node:os";
80718
- import { dirname as dirname18, join as join20 } from "node:path";
80719
- var USAGE8 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
80720
- Runs the command with the connection's values in its environment, on a Laze agent's computer,
80721
- on a machine it runs on, or where a connected agent runs, with its own key.
80722
- --channel <id> the conversation whose turn it runs in, when the agent answers in several`;
80723
- var POLL_MS2 = 3e3;
80724
- var RESTART_WAIT_MS = 12e4;
80725
- var RESTART_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 1e4];
80726
- var P2562 = { name: "ECDH", namedCurve: "P-256" };
80727
- var ServerGoneError = class extends Error {
80728
- };
80729
- function proxyOf({ env }) {
80730
- const raw = env.LAZE_VAULT_PROXY || env.HTTP_PROXY || env.http_proxy;
80731
- if (!raw) return null;
80732
- const url2 = new URL(raw);
80733
- const user = decodeURIComponent(url2.username);
80734
- const password = decodeURIComponent(url2.password);
80735
- return {
80736
- origin: url2.origin,
80737
- authorization: `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`
80738
- };
80739
- }
80740
- function turnFileOf({
80741
- env
80742
- }) {
80743
- return env.LAZE_TURN_FILE || void 0;
80744
- }
80745
- async function turnTokenOf3({
80746
- env,
80747
- turnFile,
80748
- command = "laze vault run"
80749
- }) {
80750
- const pinned = env.LAZE_TURN_TOKEN?.trim();
80751
- if (pinned) return pinned;
80752
- if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
80753
- try {
80754
- return (await readFile22(turnFile, "utf8")).trim();
80755
- } catch {
80756
- throw new CliUsageError(`${command} works only during an agent's turn`);
80757
- }
80758
- }
80759
- function runKeyPathOf({
80760
- turnFile,
80761
- connection,
80762
- profile = ""
80763
- }) {
80764
- const name3 = createHash2("sha256").update(connection).digest("hex");
80765
- const base = turnFile ? dirname18(turnFile) : join20(tmpdir2(), "laze-vault", profile);
80766
- return join20(base, "vault-run-keys", `${name3}.json`);
80767
- }
80768
- async function runKeyAt({ path }) {
80769
- const saved3 = await readFile22(path, "utf8").then(
80770
- (text2) => JSON.parse(text2),
80771
- () => void 0
80772
- );
80773
- if (saved3 && typeof saved3.publicKey === "string" && saved3.privateKey) {
80774
- const privateKey = await globalThis.crypto.subtle.importKey("jwk", saved3.privateKey, P2562, false, ["deriveBits"]).catch(() => void 0);
80775
- if (privateKey) return { privateKey, publicKey: saved3.publicKey };
80776
- }
80777
- const fresh = await generateEcdhKeys();
80778
- const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
80779
- await mkdir18(dirname18(path), { recursive: true, mode: 448 });
80780
- await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
80781
- mode: 384
80782
- });
80783
- return fresh;
80784
- }
80785
- function connectionRefused(error62) {
80786
- const cause = error62.cause;
80787
- if (cause?.code === "ECONNREFUSED") return true;
80788
- return cause?.errors?.some((inner) => inner.code === "ECONNREFUSED") ?? false;
80789
- }
80790
- async function sendOnce({
80791
- context,
80792
- url: url2,
80793
- init
80794
- }) {
80795
- let response;
80796
- try {
80797
- response = await context.fetcher(url2, init);
80798
- } catch (error62) {
80799
- const wasRefused = connectionRefused(error62);
80800
- if (init.method === "POST" && !wasRefused) throw error62;
80801
- return { restarting: wasRefused ? "connection refused" : String(error62) };
80802
- }
80803
- if (response.status !== 502 && response.status !== 503) return { response };
80804
- const code = codeOf(await response.clone().text());
80805
- const neverReached = response.status === 503 && code === "vault_not_answering";
80806
- if (init.method === "POST" && !neverReached) return { response };
80807
- return { restarting: `status ${response.status}${code ? ` ${code}` : ""}` };
80808
- }
80809
- async function reach(input2) {
80810
- const { context } = input2;
80811
- const started = context.nowMs();
80812
- for (let attempt = 0; ; attempt += 1) {
80813
- const sent = await sendOnce(input2);
80814
- if ("response" in sent) return sent.response;
80815
- if (context.nowMs() - started >= RESTART_WAIT_MS) {
80816
- throw new ServerGoneError(
80817
- `laze vault: the Laze server did not come back (${sent.restarting})`
80818
- );
80819
- }
80820
- if (attempt === 0) {
80821
- context.err(
80822
- `laze vault: the Laze server is not answering (${sent.restarting}), probably restarting; waiting up to 2 min...
80823
- `
80824
- );
80825
- }
80826
- await context.sleep(RESTART_BACKOFF_MS[Math.min(attempt, RESTART_BACKOFF_MS.length - 1)] ?? 0);
80827
- }
80828
- }
80829
- function codeOf(text2) {
80830
- return /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1];
80831
- }
80832
- async function releaseOf({ response }) {
80833
- const text2 = await response.text();
80834
- if (!response.ok) {
80835
- return {
80836
- outcome: "deny",
80837
- exitCode: 1,
80838
- message: `laze vault: the release was refused (${codeOf(text2) ?? `status ${response.status}`})`
80839
- };
80840
- }
80841
- return JSON.parse(text2);
80842
- }
80843
- async function envOf({
80844
- release: release2,
80845
- run: run4
80846
- }) {
80847
- if (!release2.sealed) return release2.env;
80848
- const sealed = await openRunRelease({
80849
- release: release2.sealed,
80850
- runPrivateKey: run4.privateKey,
80851
- runPublicKey: run4.publicKey,
80852
- requestId: release2.sealed.requestId
80853
- });
80854
- return { ...release2.env, ...sealed };
80855
- }
80856
- function deadlineOf({ args, nowMs }) {
80857
- const wait = flagText({ args, name: "wait" }) || (args.flags.wait === true ? args.words[3] : "");
80858
- if (!wait) return Infinity;
80859
- if (!(Number(wait) >= 0)) throw new CliUsageError(`--wait takes a number of seconds
80860
- ${USAGE8}`);
80861
- return nowMs + Number(wait) * 1e3;
80862
- }
80863
- async function untilAnswered({
80864
- context,
80865
- first,
80866
- next,
80867
- deadline
80868
- }) {
80869
- let release2 = first;
80870
- while (release2.outcome === "ask") {
80871
- if (context.nowMs() + POLL_MS2 > deadline) {
80872
- context.err(`${release2.message}. Not approved yet; ask again later.
80873
- `);
80874
- return "capped";
80875
- }
80876
- if (release2 === first) {
80877
- context.err(`${release2.message}. Waiting for an answer (cards expire after 12 hours)...
80878
- `);
80879
- }
80880
- await context.sleep(POLL_MS2);
80881
- release2 = await next(release2.requestId);
80882
- }
80883
- return release2;
80884
- }
80885
- function leaseHolds({
80886
- release: release2,
80887
- nowMs
80888
- }) {
80889
- const ends = release2.sealed?.leaseEndsAt;
80890
- return ends !== void 0 && Temporal3.Instant.from(ends).epochMilliseconds > nowMs;
80891
- }
80892
- async function vaultRelease({
80893
- context,
80894
- args,
80895
- connection,
80896
- reason,
80897
- command
80898
- }) {
80899
- const deadline = deadlineOf({ args, nowMs: context.nowMs() });
80900
- const env = context.environment.inherited;
80901
- const proxy = proxyOf({ env });
80902
- if (!proxy) return keyRelease({ context, args, connection, reason, command, deadline });
80903
- const turnFile = turnFileOf({ env });
80904
- const headers = {
80905
- "proxy-authorization": proxy.authorization,
80906
- "x-laze-turn": await turnTokenOf3({ env, turnFile })
80907
- };
80908
- const keyPath = runKeyPathOf({ turnFile, connection });
80909
- const run4 = await runKeyAt({ path: keyPath });
80910
- const body = JSON.stringify({ connection, reason, command, recipient: run4.publicKey });
80911
- let release2;
80912
- try {
80913
- const first = await releaseOf({
80914
- response: await reach({
80915
- context,
80916
- url: `${proxy.origin}/vault/release`,
80917
- init: { method: "POST", headers: { ...headers, "content-type": "application/json" }, body }
80918
- })
80919
- });
80920
- const next = async (requestId) => releaseOf({
80921
- response: await reach({
80922
- context,
80923
- url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
80924
- init: { method: "GET", headers }
80925
- })
80926
- });
80927
- release2 = await untilAnswered({ context, first, next, deadline });
80928
- } catch (error62) {
80929
- if (!(error62 instanceof ServerGoneError)) throw error62;
80930
- context.err(`${error62.message}. Run the command again to keep waiting.
80931
- `);
80932
- return { exitCode: 75 };
80933
- }
80934
- return settled({ context, release: release2, run: run4, keyPath });
80935
- }
80936
- async function settled({
80937
- context,
80938
- release: release2,
80939
- run: run4,
80940
- keyPath
80941
- }) {
80942
- if (release2 === "capped") return { exitCode: 75 };
80943
- if (release2.outcome === "deny") {
80944
- await rm10(keyPath, { force: true });
80945
- context.err(`${release2.message}
80946
- `);
80947
- return { exitCode: release2.exitCode || 1 };
80948
- }
80949
- const values = await envOf({ release: release2, run: run4 });
80950
- if (!leaseHolds({ release: release2, nowMs: context.nowMs() })) await rm10(keyPath, { force: true });
80951
- if (release2.message) context.err(`${release2.message}
80952
- `);
80953
- return { env: values };
80954
- }
80955
- function refusedRelease(error62) {
80956
- if (!(error62 instanceof LazeApiError)) throw error62;
80957
- return {
80958
- outcome: "deny",
80959
- exitCode: 1,
80960
- message: `laze vault: the release was refused: ${error62.message} (${error62.code})`
80961
- };
80962
- }
80963
- async function keyRelease({
80964
- context,
80965
- args,
80966
- connection,
80967
- reason,
80968
- command,
80969
- deadline
80970
- }) {
80971
- const where = new CliUsageError(
80972
- "laze vault run works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent"
80973
- );
80974
- const signed2 = await signedIn({ context, args }).catch(() => null);
80975
- if (signed2?.profile.kind !== "agent") throw where;
80976
- const { client, name: name3 } = signed2;
80977
- const channelId = flagText({ args, name: "channel" }) || null;
80978
- const keyPath = runKeyPathOf({ turnFile: void 0, connection, profile: name3 });
80979
- const run4 = await runKeyAt({ path: keyPath });
80980
- const first = await client.post("/api/agents/me/vault/release", {
80981
- connection,
80982
- reason,
80983
- command,
80984
- recipient: run4.publicKey,
80985
- channelId
80986
- }).catch(refusedRelease);
80987
- const next = (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease);
80988
- const release2 = await untilAnswered({ context, first, next, deadline });
80989
- return settled({ context, release: release2, run: run4, keyPath });
80990
- }
80991
- async function vaultRun({
80992
- context,
80993
- args
80994
- }) {
80995
- const connection = args.words[2];
80996
- const reason = flagText({ args, name: "reason" });
80997
- if (!connection || args.rest.length === 0) throw new CliUsageError(USAGE8);
80998
- if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
80999
- ${USAGE8}`);
81000
- const foreign = commandReferenceNames({ command: args.rest }).find(
81001
- (name3) => vaultReferenceConnectionName({ name: name3 }) !== connection
81002
- );
81003
- if (foreign !== void 0) {
81004
- const named = vaultReferenceConnectionName({ name: foreign });
81005
- context.err(
81006
- `laze vault: the command names {{vault:${foreign}}}, but this run releases only ${connection}, not ${named}. Nothing was asked and the command did not run.
81007
- `
81008
- );
81009
- return 1;
81010
- }
81011
- const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
81012
- if ("exitCode" in released) return released.exitCode;
81013
- const prepared = preparedCommand({
81014
- command: args.rest,
81015
- released: /* @__PURE__ */ new Map([[connection, released.env]])
81016
- });
81017
- if ("refusal" in prepared) {
81018
- context.err(`${prepared.refusal}
81019
- `);
81020
- return 1;
81021
- }
81022
- return context.runCommand({ command: prepared.command, env: released.env });
81023
- }
81024
- function preparedCommand({
81025
- command,
81026
- released
81027
- }) {
81028
- for (const [name3, fields] of released) {
81029
- const [problem] = unusableFieldProblems({ fields });
81030
- if (problem !== void 0) {
81031
- return {
81032
- refusal: `laze vault: ${name3}: ${problem}, so the command did not run. Ask its owner to save the real value on the vault page.`
81033
- };
81034
- }
81035
- }
81036
- const filled = fillCommandReferences({ command, released });
81037
- if ("refusal" in filled) {
81038
- return { refusal: `laze vault: ${filled.refusal}. The command did not run.` };
81039
- }
81040
- return filled;
81041
- }
81042
-
81043
81419
  // src/services/vault-share-commands.service.ts
81044
81420
  var SHARE_USAGE2 = "Usage: laze vault share <connection> --with <email|userId> [--for 1h]";
81045
81421
  var WAITING_LINE = "It waits for the owner's approval with a passkey or Face ID, in Settings > Vault.";
@@ -81058,7 +81434,7 @@ async function inTurn({
81058
81434
  command
81059
81435
  }) {
81060
81436
  const env = context.environment.inherited;
81061
- const turn = await turnTokenOf3({ env, turnFile: turnFileOf({ env }), command });
81437
+ const turn = await turnTokenOf2({ env, turnFile: turnFileOf({ env }), command });
81062
81438
  return client.withHeaders({ "x-laze-turn": turn });
81063
81439
  }
81064
81440
  function printShare({ context, grant }) {
@@ -81742,16 +82118,16 @@ function dndLine({ pausedUntil }) {
81742
82118
  }
81743
82119
 
81744
82120
  // src/services/dnd-commands.service.ts
81745
- 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";
81746
82122
  async function dnd({ context, args }) {
81747
82123
  const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
81748
82124
  let input2;
81749
82125
  try {
81750
82126
  input2 = dndInputOf({ words: args.words.slice(1), now: nowInstant(), timeZone });
81751
82127
  } catch {
81752
- throw new CliUsageError(USAGE9);
82128
+ throw new CliUsageError(USAGE8);
81753
82129
  }
81754
- if (!input2) throw new CliUsageError(USAGE9);
82130
+ if (!input2) throw new CliUsageError(USAGE8);
81755
82131
  const { client } = await signedIn({ context, args });
81756
82132
  const settings2 = await client.post(
81757
82133
  "/api/agents/me/notifications/snooze",
@@ -81770,8 +82146,8 @@ var DOMAINS_USAGE = `Usage:
81770
82146
  var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
81771
82147
  `);
81772
82148
  function printDomain(context, row) {
81773
- const join25 = row.autoJoin ? "auto-join on" : "auto-join off";
81774
- 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" : ""}
81775
82151
  `);
81776
82152
  }
81777
82153
  async function list4({ context, args }) {
@@ -82000,6 +82376,8 @@ var feedApprovalSchemaDefinition = external_exports.object({
82000
82376
  why: external_exports.string(),
82001
82377
  /** The longest lease Allow for this agent may give; null offers only once and deny. */
82002
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(),
82003
82381
  /** The card's timeout; a publish waits without one. */
82004
82382
  expiresAt: external_exports.iso.datetime().nullable(),
82005
82383
  state: feedApprovalStateSchema,
@@ -82576,7 +82954,7 @@ async function feedAttachmentIdsOf({
82576
82954
  }
82577
82955
 
82578
82956
  // src/services/feed-commands.service.ts
82579
- var USAGE10 = `Usage:
82957
+ var USAGE9 = `Usage:
82580
82958
  laze feed post <title> [--channel <channel>] [--tag <tag>] [--summary <line>]
82581
82959
  [--draft <text|@file>] [--draft-header "To: ...\\nRe: ..."]
82582
82960
  [--metric <json|@file.json> | --table <csv|@file.csv>]
@@ -82647,7 +83025,7 @@ function printItem({
82647
83025
  }
82648
83026
  async function feedPost({ context, args }) {
82649
83027
  const title = args.words.slice(2).join(" ").trim();
82650
- if (!title) throw new CliUsageError(USAGE10);
83028
+ if (!title) throw new CliUsageError(USAGE9);
82651
83029
  const flags2 = flagsOf(args);
82652
83030
  const { client } = await signedIn({ context, args });
82653
83031
  const channel = flagText({ args, name: "channel" });
@@ -82669,7 +83047,7 @@ async function feedPost({ context, args }) {
82669
83047
  }
82670
83048
  async function feedUpdate({ context, args }) {
82671
83049
  const itemId = args.words[2];
82672
- if (!itemId) throw new CliUsageError(USAGE10);
83050
+ if (!itemId) throw new CliUsageError(USAGE9);
82673
83051
  const flags2 = flagsOf(args);
82674
83052
  const { client } = await signedIn({ context, args });
82675
83053
  const body = await bodyOf2({ context, flags: flags2 });
@@ -82685,7 +83063,7 @@ async function feedUpdate({ context, args }) {
82685
83063
  async function feedReply({ context, args }) {
82686
83064
  const itemId = args.words[2];
82687
83065
  const text2 = args.words.slice(3).join(" ").trim();
82688
- if (!itemId || !text2) throw new CliUsageError(USAGE10);
83066
+ if (!itemId || !text2) throw new CliUsageError(USAGE9);
82689
83067
  const { client } = await signedIn({ context, args });
82690
83068
  const replied = await client.post("/api/feed/items/reply", {
82691
83069
  itemId,
@@ -82698,7 +83076,7 @@ async function feedReply({ context, args }) {
82698
83076
  }
82699
83077
  async function feedRead({ context, args }) {
82700
83078
  const itemId = args.words[2];
82701
- if (!itemId) throw new CliUsageError(USAGE10);
83079
+ if (!itemId) throw new CliUsageError(USAGE9);
82702
83080
  const { client } = await signedIn({ context, args });
82703
83081
  const read3 = await client.post("/api/feed/items/read", { itemId });
82704
83082
  printItem({ context, args, item: read3 });
@@ -82717,7 +83095,7 @@ async function feedClose({ context, args }) {
82717
83095
  const itemId = args.words[2];
82718
83096
  const loop = flagText({ args, name: "loop" });
82719
83097
  const note = flagText({ args, name: "note" });
82720
- if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(USAGE10);
83098
+ if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(USAGE9);
82721
83099
  const { client } = await signedIn({ context, args });
82722
83100
  const closed = await client.post("/api/feed/items/close", {
82723
83101
  ...itemId ? { itemId } : { loop },
@@ -82743,7 +83121,7 @@ async function feedLoops({ context, args }) {
82743
83121
  }
82744
83122
  async function feedGroupSummary({ context, args }) {
82745
83123
  const group = args.words.slice(2).join(" ").trim();
82746
- if (!group) throw new CliUsageError(USAGE10);
83124
+ if (!group) throw new CliUsageError(USAGE9);
82747
83125
  const { client } = await signedIn({ context, args });
82748
83126
  const pointer = await client.post("/api/feed/group-summary", { group });
82749
83127
  if (args.flags.json) return context.out(`${JSON.stringify(pointer, null, 2)}
@@ -82823,7 +83201,7 @@ async function feedDecisions({ context, args }) {
82823
83201
  }
82824
83202
  async function feedAct({ context, args }) {
82825
83203
  const [itemId, actionId] = [args.words[2], args.words[3]];
82826
- if (!itemId || !actionId) throw new CliUsageError(USAGE10);
83204
+ if (!itemId || !actionId) throw new CliUsageError(USAGE9);
82827
83205
  const draft = await textFlag({ context, args, name: "draft" });
82828
83206
  const { client } = await signedIn({ context, args });
82829
83207
  const item = await client.post("/api/feed/mine/act", {
@@ -82836,7 +83214,7 @@ async function feedAct({ context, args }) {
82836
83214
  async function feedComment({ context, args }) {
82837
83215
  const itemId = args.words[2];
82838
83216
  const text2 = args.words.slice(3).join(" ").trim();
82839
- if (!itemId || !text2) throw new CliUsageError(USAGE10);
83217
+ if (!itemId || !text2) throw new CliUsageError(USAGE9);
82840
83218
  const draft = await textFlag({ context, args, name: "draft" });
82841
83219
  const { client } = await signedIn({ context, args });
82842
83220
  const item = await client.post("/api/feed/mine/comment", {
@@ -82850,7 +83228,7 @@ async function feedComment({ context, args }) {
82850
83228
  function moveItem(path) {
82851
83229
  return async ({ context, args }) => {
82852
83230
  const itemId = args.words[2];
82853
- if (!itemId) throw new CliUsageError(USAGE10);
83231
+ if (!itemId) throw new CliUsageError(USAGE9);
82854
83232
  const { client } = await signedIn({ context, args });
82855
83233
  const item = await client.post(`/api/feed/mine/${path}`, { itemId });
82856
83234
  printMoved({ context, args, item });
@@ -82859,14 +83237,14 @@ function moveItem(path) {
82859
83237
  async function feedSnooze({ context, args }) {
82860
83238
  const itemId = args.words[2];
82861
83239
  const until = flagText({ args, name: "until" });
82862
- if (!itemId || !until) throw new CliUsageError(USAGE10);
83240
+ if (!itemId || !until) throw new CliUsageError(USAGE9);
82863
83241
  const { client } = await signedIn({ context, args });
82864
83242
  const item = await client.post("/api/feed/mine/snooze", { itemId, until });
82865
83243
  printMoved({ context, args, item });
82866
83244
  }
82867
83245
  async function feedChannel({ context, args }) {
82868
83246
  const channelId = args.words[2];
82869
- if (!channelId) throw new CliUsageError(USAGE10);
83247
+ if (!channelId) throw new CliUsageError(USAGE9);
82870
83248
  const { client } = await signedIn({ context, args });
82871
83249
  const items = await client.post("/api/feed/channel", { channelId });
82872
83250
  if (args.flags.json) return context.out(`${JSON.stringify(items, null, 2)}
@@ -82897,7 +83275,7 @@ var FEED_COMMANDS = {
82897
83275
  async function feed({ context, args }) {
82898
83276
  const name3 = args.words[1] ?? "";
82899
83277
  const command = Object.hasOwn(FEED_COMMANDS, name3) ? FEED_COMMANDS[name3] : void 0;
82900
- if (!command) throw new CliUsageError(USAGE10);
83278
+ if (!command) throw new CliUsageError(USAGE9);
82901
83279
  await command({ context, args });
82902
83280
  }
82903
83281
 
@@ -83393,12 +83771,12 @@ async function ip({ context, args }) {
83393
83771
  }
83394
83772
 
83395
83773
  // src/services/join-commands.service.ts
83396
- import { mkdir as mkdir19, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile19 } from "node:fs/promises";
83397
- 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";
83398
83776
  var DEFAULT_WAIT_SECONDS2 = 100;
83399
83777
  var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
83400
83778
  function pendingPathOf({ context }) {
83401
- return join21(dirname19(context.environment.configPath), "join", "pending.json");
83779
+ return join22(dirname19(context.environment.configPath), "join", "pending.json");
83402
83780
  }
83403
83781
  async function readPending({
83404
83782
  context,
@@ -83415,9 +83793,9 @@ async function readPending({
83415
83793
  }
83416
83794
  async function keepPending({ context, pending }) {
83417
83795
  const path = pendingPathOf({ context });
83418
- await mkdir19(dirname19(path), { recursive: true, mode: 448 });
83796
+ await mkdir20(dirname19(path), { recursive: true, mode: 448 });
83419
83797
  const temporary = `${path}.${process.pid}.tmp`;
83420
- await writeFile19(temporary, JSON.stringify(pending), { mode: 384 });
83798
+ await writeFile20(temporary, JSON.stringify(pending), { mode: 384 });
83421
83799
  await rename5(temporary, path);
83422
83800
  }
83423
83801
  async function dropPending({ context }) {
@@ -83734,7 +84112,7 @@ function machineAccessCommand(name3) {
83734
84112
  }
83735
84113
 
83736
84114
  // src/services/machine-commands.service.ts
83737
- var USAGE11 = [
84115
+ var USAGE10 = [
83738
84116
  "Usage: laze machine connect <name> the command to run on your own machine (people)",
83739
84117
  " laze machine connect <name> --again a new command for a machine you connected; the old code stops working",
83740
84118
  " laze machine connect <name> --ssh <user>@<host>[:port] a machine that cannot run the connector, over SSH (people)",
@@ -83780,7 +84158,7 @@ function listLine(machine2) {
83780
84158
  var EXEC_ENV_MAX = 32;
83781
84159
  function machineArg2({ args }) {
83782
84160
  const machine2 = args.words[2];
83783
- if (!machine2) throw new CliUsageError(USAGE11);
84161
+ if (!machine2) throw new CliUsageError(USAGE10);
83784
84162
  return machine2;
83785
84163
  }
83786
84164
  async function connect2({ context, args }) {
@@ -83806,7 +84184,7 @@ async function connectSsh({
83806
84184
  }) {
83807
84185
  const ssh = flagText({ args, name: "ssh" });
83808
84186
  if (!ssh) throw new CliUsageError(`--ssh takes <user>@<host>[:port]
83809
- ${USAGE11}`);
84187
+ ${USAGE10}`);
83810
84188
  const client = await computeClient({ context, args });
83811
84189
  const made = await client.post(COMPUTE_REST_PATHS.connectSsh, {
83812
84190
  name: name3,
@@ -83882,11 +84260,11 @@ async function exec({
83882
84260
  }) {
83883
84261
  const machine2 = machineArg2({ args });
83884
84262
  const command = commandText({ rest: args.rest });
83885
- if (!command.trim()) throw new CliUsageError(USAGE11);
84263
+ if (!command.trim()) throw new CliUsageError(USAGE10);
83886
84264
  const timeout = flagText({ args, name: "timeout" });
83887
84265
  if (timeout && !(Number(timeout) >= 1))
83888
84266
  throw new CliUsageError(`--timeout takes a number of seconds
83889
- ${USAGE11}`);
84267
+ ${USAGE10}`);
83890
84268
  const released = await vaultEnv({ context, args });
83891
84269
  if ("exitCode" in released) return released.exitCode;
83892
84270
  const client = await computeClient({ context, args });
@@ -83914,11 +84292,11 @@ async function vaultEnv({
83914
84292
  const connections = args.lists.vault ?? [];
83915
84293
  if (args.flags.vault === true)
83916
84294
  throw new CliUsageError(`--vault takes a connection name
83917
- ${USAGE11}`);
84295
+ ${USAGE10}`);
83918
84296
  if (connections.length === 0) return {};
83919
84297
  const reason = flagText({ args, name: "reason" });
83920
84298
  if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
83921
- ${USAGE11}`);
84299
+ ${USAGE10}`);
83922
84300
  const env = {};
83923
84301
  for (const connection of new Set(connections)) {
83924
84302
  const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
@@ -83938,11 +84316,11 @@ ${USAGE11}`);
83938
84316
  async function host({ context, args }) {
83939
84317
  const machineName = args.words[2];
83940
84318
  const agent2 = args.words[3];
83941
- if (!machineName || !agent2) throw new CliUsageError(USAGE11);
84319
+ if (!machineName || !agent2) throw new CliUsageError(USAGE10);
83942
84320
  const whenOffline = flagText({ args, name: "when-offline", fallback: "wait" });
83943
84321
  if (whenOffline !== "wait" && whenOffline !== "computer" && whenOffline !== "sandbox")
83944
84322
  throw new CliUsageError(`--when-offline takes wait or computer
83945
- ${USAGE11}`);
84323
+ ${USAGE10}`);
83946
84324
  const client = await computeClient({ context, args });
83947
84325
  const machine2 = await client.post(COMPUTE_REST_PATHS.host, {
83948
84326
  machine: machineName,
@@ -83959,7 +84337,7 @@ ${USAGE11}`);
83959
84337
  }
83960
84338
  async function unhost({ context, args }) {
83961
84339
  const agent2 = args.words[2];
83962
- if (!agent2) throw new CliUsageError(USAGE11);
84340
+ if (!agent2) throw new CliUsageError(USAGE10);
83963
84341
  const client = await computeClient({ context, args });
83964
84342
  const done = await client.post(COMPUTE_REST_PATHS.unhost, { agent: agent2 });
83965
84343
  if (args.flags.json) return context.out(`${JSON.stringify(done, null, 2)}
@@ -83996,7 +84374,7 @@ async function machine({ context, args }) {
83996
84374
  if (command === "unhost") return unhost({ context, args });
83997
84375
  const access = machineAccessCommand(command);
83998
84376
  if (access) return access({ context, args });
83999
- throw new CliUsageError(USAGE11);
84377
+ throw new CliUsageError(USAGE10);
84000
84378
  }
84001
84379
 
84002
84380
  // src/services/mcp-server.service.ts
@@ -84235,7 +84613,7 @@ async function serveMcp({
84235
84613
  }
84236
84614
 
84237
84615
  // src/services/mount-files.service.ts
84238
- 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";
84239
84617
  import { dirname as dirname20, relative as relative5, resolve as resolve11 } from "node:path";
84240
84618
  async function textArgument({
84241
84619
  context,
@@ -84256,20 +84634,20 @@ async function writeMount({
84256
84634
  }) {
84257
84635
  const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
84258
84636
  await rm12(root, { recursive: true, force: true });
84259
- await mkdir20(root, { recursive: true });
84637
+ await mkdir21(root, { recursive: true });
84260
84638
  for (const file3 of files2) {
84261
84639
  const target = resolve11(root, file3.path);
84262
84640
  const inside = relative5(root, target);
84263
84641
  if (!inside || inside.startsWith(".."))
84264
84642
  throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
84265
- await mkdir20(dirname20(target), { recursive: true });
84266
- await writeFile20(target, file3.content);
84643
+ await mkdir21(dirname20(target), { recursive: true });
84644
+ await writeFile21(target, file3.content);
84267
84645
  }
84268
84646
  return root;
84269
84647
  }
84270
84648
 
84271
84649
  // src/services/memory-commands.service.ts
84272
- var USAGE12 = `Usage:
84650
+ var USAGE11 = `Usage:
84273
84651
  laze memory get SOUL.md|AGENTS.md|MEMORY.md [--channel <channel>]
84274
84652
  laze memory set <file> <text|@file|-> [--channel <channel>] [--base <version>]
84275
84653
  laze memory append MEMORY.md <text|@file|-> [--channel <channel>]
@@ -84281,7 +84659,7 @@ MEMORY.md is the file of the turn's channel (LAZE_CHANNEL), or of --channel when
84281
84659
  var FILES = /* @__PURE__ */ new Set(["SOUL.md", "AGENTS.md", "MEMORY.md"]);
84282
84660
  function fileRef({ context, args }) {
84283
84661
  const file3 = args.words[2] ?? "";
84284
- if (!FILES.has(file3)) throw new CliUsageError(USAGE12);
84662
+ if (!FILES.has(file3)) throw new CliUsageError(USAGE11);
84285
84663
  const channel = turnChannel({ context, args });
84286
84664
  return { file: file3, ...channel ? { channel } : {} };
84287
84665
  }
@@ -84320,7 +84698,7 @@ async function memoryHistory({ context, args }) {
84320
84698
  async function memorySet({ context, args }) {
84321
84699
  const ref = fileRef({ context, args });
84322
84700
  const value = args.words.slice(3).join(" ");
84323
- if (!value) throw new CliUsageError(USAGE12);
84701
+ if (!value) throw new CliUsageError(USAGE11);
84324
84702
  const content = await textArgument({ context, value });
84325
84703
  const base = args.flags.base;
84326
84704
  const { client } = await signedIn({ context, args });
@@ -84336,7 +84714,7 @@ async function memorySet({ context, args }) {
84336
84714
  async function memoryAppend({ context, args }) {
84337
84715
  const ref = fileRef({ context, args });
84338
84716
  const value = args.words.slice(3).join(" ");
84339
- if (!value) throw new CliUsageError(USAGE12);
84717
+ if (!value) throw new CliUsageError(USAGE11);
84340
84718
  const text2 = await textArgument({ context, value });
84341
84719
  const { client } = await signedIn({ context, args });
84342
84720
  const saved3 = await client.post("/api/memory/append", { ...ref, text: text2 });
@@ -84346,7 +84724,7 @@ async function memoryAppend({ context, args }) {
84346
84724
  }
84347
84725
  async function memorySearch({ context, args }) {
84348
84726
  const query = args.words.slice(2).join(" ").trim();
84349
- if (!query) throw new CliUsageError(USAGE12);
84727
+ if (!query) throw new CliUsageError(USAGE11);
84350
84728
  const { client } = await signedIn({ context, args });
84351
84729
  const hits = await client.post("/api/memory/search", { query });
84352
84730
  if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
@@ -84380,13 +84758,13 @@ var MEMORY_COMMANDS = {
84380
84758
  async function memory({ context, args }) {
84381
84759
  const name3 = args.words[1] ?? "";
84382
84760
  const command = Object.hasOwn(MEMORY_COMMANDS, name3) ? MEMORY_COMMANDS[name3] : void 0;
84383
- if (!command) throw new CliUsageError(USAGE12);
84761
+ if (!command) throw new CliUsageError(USAGE11);
84384
84762
  await command({ context, args });
84385
84763
  }
84386
84764
 
84387
84765
  // src/services/models-commands.service.ts
84388
84766
  var WINDOWS = ["day", "week", "month"];
84389
- var USAGE13 = `Usage:
84767
+ var USAGE12 = `Usage:
84390
84768
  laze models policy whether Laze models are on, the default budget and the cap
84391
84769
  laze models set-policy [on|off] [--default-day <usd|none>] [--cap-day <usd|none>] ... (admins)
84392
84770
  --default-week, --default-month, --cap-week and --cap-month set the other windows
@@ -84411,7 +84789,7 @@ function limitsFrom({
84411
84789
  const value = text2 === "none" ? null : Number(text2);
84412
84790
  if (value !== null && (!Number.isFinite(value) || value < 0))
84413
84791
  throw new CliUsageError(`--${prefix}${window2} takes an amount in USD or none.
84414
- ${USAGE13}`);
84792
+ ${USAGE12}`);
84415
84793
  next[window2] = value;
84416
84794
  changed = true;
84417
84795
  }
@@ -84436,12 +84814,12 @@ async function showPolicy({ context, args }) {
84436
84814
  }
84437
84815
  async function setPolicy({ context, args }) {
84438
84816
  const state = args.words[2];
84439
- 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);
84440
84818
  const { client } = await signedIn({ context, args });
84441
84819
  const current2 = await client.get("/api/models/policy");
84442
84820
  const defaultBudget = limitsFrom({ args, prefix: "default-", current: current2.defaultBudget });
84443
84821
  const cap = limitsFrom({ args, prefix: "cap-", current: current2.cap });
84444
- if (!state && !defaultBudget && !cap) throw new CliUsageError(USAGE13);
84822
+ if (!state && !defaultBudget && !cap) throw new CliUsageError(USAGE12);
84445
84823
  const updated = await client.post("/api/models/policy", {
84446
84824
  ...state ? { lazeModels: state === "on" } : {},
84447
84825
  ...defaultBudget ? { defaultBudget } : {},
@@ -84482,11 +84860,11 @@ async function agentNamed({ client, name: name3 }) {
84482
84860
  }
84483
84861
  async function setBudget({ context, args }) {
84484
84862
  const name3 = args.words[2];
84485
- if (!name3) throw new CliUsageError(USAGE13);
84863
+ if (!name3) throw new CliUsageError(USAGE12);
84486
84864
  const { client } = await signedIn({ context, args });
84487
84865
  const agent2 = await agentNamed({ client, name: name3 });
84488
84866
  const next = limitsFrom({ args, prefix: "", current: agent2.budget });
84489
- if (!next) throw new CliUsageError(USAGE13);
84867
+ if (!next) throw new CliUsageError(USAGE12);
84490
84868
  const updated = await client.post("/api/models/agents/budget", {
84491
84869
  agentId: agent2.agentId,
84492
84870
  budget: next
@@ -84519,7 +84897,7 @@ var MODEL_COMMANDS = {
84519
84897
  async function models({ context, args }) {
84520
84898
  const name3 = args.words[1] ?? "policy";
84521
84899
  const command = Object.hasOwn(MODEL_COMMANDS, name3) ? MODEL_COMMANDS[name3] : void 0;
84522
- if (!command) throw new CliUsageError(USAGE13);
84900
+ if (!command) throw new CliUsageError(USAGE12);
84523
84901
  await command({ context, args });
84524
84902
  }
84525
84903
 
@@ -84597,7 +84975,7 @@ var monitorResume = stateRun("/api/agents/monitors/resume", "resume");
84597
84975
  var monitorRemove = stateRun("/api/agents/monitors/remove", "rm");
84598
84976
 
84599
84977
  // src/services/notification-commands.service.ts
84600
- var USAGE14 = `Usage:
84978
+ var USAGE13 = `Usage:
84601
84979
  laze notifications [show] your notification settings (people)
84602
84980
  laze notifications set [--channels all|mentions|nothing] [--keywords a,b] [--dnd on|off]
84603
84981
  [--dnd-from 22:00] [--dnd-to 08:00] [--tz <IANA zone>] [--push on|off] [--email on|off]
@@ -84626,17 +85004,17 @@ function switchOf({ args, name: name3 }) {
84626
85004
  if (!text2) return void 0;
84627
85005
  if (text2 !== "on" && text2 !== "off")
84628
85006
  throw new CliUsageError(`--${name3} takes on or off.
84629
- ${USAGE14}`);
85007
+ ${USAGE13}`);
84630
85008
  return text2 === "on";
84631
85009
  }
84632
85010
  function changesOf(args) {
84633
85011
  const channels2 = flagText({ args, name: "channels" });
84634
85012
  if (channels2 && !["all", "mentions", "nothing"].includes(channels2))
84635
85013
  throw new CliUsageError(`--channels takes all, mentions or nothing.
84636
- ${USAGE14}`);
85014
+ ${USAGE13}`);
84637
85015
  const keywords = typeof args.flags.keywords === "string" ? args.flags.keywords : void 0;
84638
85016
  const emailAfter = flagText({ args, name: "email-after" });
84639
- const changes = {
85017
+ const changes2 = {
84640
85018
  channelDefault: channels2 || void 0,
84641
85019
  keywords: keywords?.split(",").map((word3) => word3.trim()).filter(Boolean),
84642
85020
  dndEnabled: switchOf({ args, name: "dnd" }),
@@ -84647,26 +85025,26 @@ ${USAGE14}`);
84647
85025
  emailEnabled: switchOf({ args, name: "email" }),
84648
85026
  emailDelayMinutes: emailAfter ? Number(emailAfter) : void 0
84649
85027
  };
84650
- return Object.fromEntries(Object.entries(changes).filter(([, value]) => value !== void 0));
85028
+ return Object.fromEntries(Object.entries(changes2).filter(([, value]) => value !== void 0));
84651
85029
  }
84652
85030
  async function showSettings({ context, args }) {
84653
85031
  const { client } = await signedIn({ context, args });
84654
85032
  print7({ context, args, settings: await client.get("/api/agents/me/notifications") });
84655
85033
  }
84656
85034
  async function setSettings({ context, args }) {
84657
- const changes = changesOf(args);
84658
- if (Object.keys(changes).length === 0) throw new CliUsageError(USAGE14);
85035
+ const changes2 = changesOf(args);
85036
+ if (Object.keys(changes2).length === 0) throw new CliUsageError(USAGE13);
84659
85037
  const { client } = await signedIn({ context, args });
84660
85038
  print7({
84661
85039
  context,
84662
85040
  args,
84663
- settings: await client.post("/api/agents/me/notifications", changes)
85041
+ settings: await client.post("/api/agents/me/notifications", changes2)
84664
85042
  });
84665
85043
  }
84666
85044
  async function snoozeFor({ context, args }) {
84667
85045
  const word3 = args.words[2];
84668
85046
  const minutes = word3 === "off" ? 0 : Number(word3);
84669
- if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(USAGE14);
85047
+ if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(USAGE13);
84670
85048
  const { client } = await signedIn({ context, args });
84671
85049
  print7({
84672
85050
  context,
@@ -84684,7 +85062,7 @@ var NOTIFICATION_COMMANDS = {
84684
85062
  async function notifications({ context, args }) {
84685
85063
  const name3 = args.words[1] ?? "show";
84686
85064
  const command = Object.hasOwn(NOTIFICATION_COMMANDS, name3) ? NOTIFICATION_COMMANDS[name3] : void 0;
84687
- if (!command) throw new CliUsageError(USAGE14);
85065
+ if (!command) throw new CliUsageError(USAGE13);
84688
85066
  await command({ context, args });
84689
85067
  }
84690
85068
 
@@ -84921,8 +85299,8 @@ ${OPS_USAGE}`);
84921
85299
  }
84922
85300
 
84923
85301
  // src/services/release-watch.service.ts
84924
- import { mkdir as mkdir21, readFile as readFile31, realpath, writeFile as writeFile21 } from "node:fs/promises";
84925
- 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";
84926
85304
 
84927
85305
  // src/rules/cli-update.rules.ts
84928
85306
  var CLI_PACKAGE = "@lazehq/cli";
@@ -85069,15 +85447,15 @@ async function startedUpdate({
85069
85447
  const plan2 = updatePlanOf({ script: await scriptOf(context) });
85070
85448
  if (plan2.kind !== "install") return null;
85071
85449
  const folder = dirname21(context.environment.configPath);
85072
- const stamp = join22(folder, "auto-update.json");
85450
+ const stamp = join23(folder, "auto-update.json");
85073
85451
  const last = await readFile31(stamp, "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
85074
85452
  const now = context.nowMs();
85075
85453
  if (last?.server === server && now - last.atMs < RETRY_AFTER_MS) return null;
85076
- await mkdir21(folder, { recursive: true, mode: 448 });
85077
- 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 });
85078
85456
  context.processes.spawnDetached({
85079
85457
  argv: [...context.program, "update"],
85080
- logPath: join22(folder, "auto-update.log")
85458
+ logPath: join23(folder, "auto-update.log")
85081
85459
  });
85082
85460
  return { manager: plan2.manager };
85083
85461
  }
@@ -85188,7 +85566,7 @@ async function rushWakeHook({ context, args }) {
85188
85566
  }
85189
85567
 
85190
85568
  // src/services/schedule-commands.service.ts
85191
- var USAGE15 = `Usage:
85569
+ var USAGE14 = `Usage:
85192
85570
  laze schedule add <name> --prompt <text> (--cron "<m h dom mon dow>" | --rrule "<RRULE>" | --at <local time>)
85193
85571
  [--tz <IANA zone>] [--channel <channelId>] [--agent <agentId>]
85194
85572
  laze schedule list
@@ -85203,7 +85581,7 @@ function timingOf(args) {
85203
85581
  const given = [cron, rrule, at].filter(Boolean);
85204
85582
  if (given.length !== 1)
85205
85583
  throw new CliUsageError(`Give exactly one of --cron, --rrule or --at.
85206
- ${USAGE15}`);
85584
+ ${USAGE14}`);
85207
85585
  if (cron) return { kind: "cron", cron };
85208
85586
  if (rrule) return { kind: "rrule", rrule };
85209
85587
  return { kind: "once", at };
@@ -85218,7 +85596,7 @@ function printSchedule({ context, schedule: schedule2 }) {
85218
85596
  async function scheduleAdd({ context, args }) {
85219
85597
  const name3 = args.words.slice(2).join(" ").trim();
85220
85598
  const prompt = flagText({ args, name: "prompt" });
85221
- if (!name3 || !prompt) throw new CliUsageError(USAGE15);
85599
+ if (!name3 || !prompt) throw new CliUsageError(USAGE14);
85222
85600
  const timing = timingOf(args);
85223
85601
  const { client } = await signedIn({ context, args });
85224
85602
  const channelId = flagText({ args, name: "channel" });
@@ -85236,9 +85614,9 @@ async function scheduleAdd({ context, args }) {
85236
85614
  printSchedule({ context, schedule: schedule2 });
85237
85615
  }
85238
85616
  function changesOf2(args) {
85239
- const changes = {};
85617
+ const changes2 = {};
85240
85618
  const timed = ["cron", "rrule", "at"].some((name3) => flagText({ args, name: name3 }));
85241
- if (timed) changes.timing = timingOf(args);
85619
+ if (timed) changes2.timing = timingOf(args);
85242
85620
  for (const [flag2, field] of [
85243
85621
  ["name", "name"],
85244
85622
  ["prompt", "prompt"],
@@ -85246,18 +85624,18 @@ function changesOf2(args) {
85246
85624
  ["agent", "agentId"]
85247
85625
  ]) {
85248
85626
  const value = flagText({ args, name: flag2 });
85249
- if (value) changes[field] = value;
85627
+ if (value) changes2[field] = value;
85250
85628
  }
85251
85629
  const channel = flagText({ args, name: "channel" });
85252
- if (channel) changes.channelId = channel === "none" ? null : channel;
85253
- return changes;
85630
+ if (channel) changes2.channelId = channel === "none" ? null : channel;
85631
+ return changes2;
85254
85632
  }
85255
85633
  async function scheduleUpdate({ context, args }) {
85256
85634
  const scheduleId = args.words[2];
85257
- const changes = changesOf2(args);
85258
- if (!scheduleId || Object.keys(changes).length === 0) throw new CliUsageError(USAGE15);
85635
+ const changes2 = changesOf2(args);
85636
+ if (!scheduleId || Object.keys(changes2).length === 0) throw new CliUsageError(USAGE14);
85259
85637
  const { client } = await signedIn({ context, args });
85260
- const schedule2 = await client.post("/api/schedules/update", { scheduleId, ...changes });
85638
+ const schedule2 = await client.post("/api/schedules/update", { scheduleId, ...changes2 });
85261
85639
  if (args.flags.json) return context.out(`${JSON.stringify(schedule2, null, 2)}
85262
85640
  `);
85263
85641
  printSchedule({ context, schedule: schedule2 });
@@ -85272,7 +85650,7 @@ async function scheduleList({ context, args }) {
85272
85650
  function byId(path) {
85273
85651
  return async ({ context, args }) => {
85274
85652
  const scheduleId = args.words[2];
85275
- if (!scheduleId) throw new CliUsageError(USAGE15);
85653
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85276
85654
  const { client } = await signedIn({ context, args });
85277
85655
  const answer4 = await client.post(`/api/schedules/${path}`, {
85278
85656
  scheduleId
@@ -85286,7 +85664,7 @@ function byId(path) {
85286
85664
  }
85287
85665
  async function scheduleRuns({ context, args }) {
85288
85666
  const scheduleId = args.words[2];
85289
- if (!scheduleId) throw new CliUsageError(USAGE15);
85667
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85290
85668
  const { client } = await signedIn({ context, args });
85291
85669
  const runs = await client.post("/api/schedules/runs", { scheduleId });
85292
85670
  if (args.flags.json) return context.out(`${JSON.stringify(runs, null, 2)}
@@ -85300,7 +85678,7 @@ async function scheduleRuns({ context, args }) {
85300
85678
  }
85301
85679
  async function scheduleRun({ context, args }) {
85302
85680
  const scheduleId = args.words[2];
85303
- if (!scheduleId) throw new CliUsageError(USAGE15);
85681
+ if (!scheduleId) throw new CliUsageError(USAGE14);
85304
85682
  const { client } = await signedIn({ context, args });
85305
85683
  const run4 = await client.post("/api/schedules/run", { scheduleId });
85306
85684
  if (args.flags.json) return context.out(`${JSON.stringify(run4, null, 2)}
@@ -85321,14 +85699,14 @@ var SCHEDULE_COMMANDS = {
85321
85699
  async function schedule({ context, args }) {
85322
85700
  const name3 = args.words[1] ?? "";
85323
85701
  const command = Object.hasOwn(SCHEDULE_COMMANDS, name3) ? SCHEDULE_COMMANDS[name3] : void 0;
85324
- if (!command) throw new CliUsageError(USAGE15);
85702
+ if (!command) throw new CliUsageError(USAGE14);
85325
85703
  await command({ context, args });
85326
85704
  }
85327
85705
 
85328
85706
  // src/services/skill-commands.service.ts
85329
85707
  import { readdir as readdir7, readFile as readFile33 } from "node:fs/promises";
85330
- import { join as join23, relative as relative6, resolve as resolve13 } from "node:path";
85331
- var USAGE16 = `Usage:
85708
+ import { join as join24, relative as relative6, resolve as resolve13 } from "node:path";
85709
+ var USAGE15 = `Usage:
85332
85710
  laze skill list [--agent <agentId>]
85333
85711
  laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
85334
85712
  laze skill install --from <folder> [--as <name>] [--agent <agentId>] a folder with a SKILL.md
@@ -85348,7 +85726,7 @@ async function folderFiles({ root }) {
85348
85726
  const files2 = [];
85349
85727
  for (const entry of entries) {
85350
85728
  if (!entry.isFile()) continue;
85351
- const full = join23(entry.parentPath, entry.name);
85729
+ const full = join24(entry.parentPath, entry.name);
85352
85730
  files2.push({ path: relative6(root, full), content: await readFile33(full, "utf8") });
85353
85731
  }
85354
85732
  return files2.toSorted((a, b) => a.path.localeCompare(b.path));
@@ -85377,7 +85755,7 @@ async function skillList({ context, args }) {
85377
85755
  async function skillInstall({ context, args }) {
85378
85756
  const catalogueId = args.words[2];
85379
85757
  const from = flagText({ args, name: "from" });
85380
- if (!catalogueId === !from) throw new CliUsageError(USAGE16);
85758
+ if (!catalogueId === !from) throw new CliUsageError(USAGE15);
85381
85759
  const name3 = flagText({ args, name: "as" });
85382
85760
  const agent2 = flagText({ args, name: "agent" });
85383
85761
  const files2 = from ? await folderFiles({ root: resolve13(context.cwd, from) }) : void 0;
@@ -85395,7 +85773,7 @@ async function skillInstall({ context, args }) {
85395
85773
  }
85396
85774
  async function skillShow({ context, args }) {
85397
85775
  const name3 = args.words[2];
85398
- if (!name3) throw new CliUsageError(USAGE16);
85776
+ if (!name3) throw new CliUsageError(USAGE15);
85399
85777
  const agent2 = flagText({ args, name: "agent" });
85400
85778
  const { client } = await signedIn({ context, args });
85401
85779
  const skill2 = await client.post("/api/skills/show", {
@@ -85428,7 +85806,7 @@ function agentFlag(args) {
85428
85806
  }
85429
85807
  async function skillRemove({ context, args }) {
85430
85808
  const name3 = args.words[2];
85431
- if (!name3) throw new CliUsageError(USAGE16);
85809
+ if (!name3) throw new CliUsageError(USAGE15);
85432
85810
  const { client } = await signedIn({ context, args });
85433
85811
  const removed = await client.post("/api/skills/remove", {
85434
85812
  name: name3,
@@ -85445,7 +85823,7 @@ async function skillUpdate({ context, args }) {
85445
85823
  const description = typeof args.flags.description === "string" ? args.flags.description : void 0;
85446
85824
  const skillMdFile = flagText({ args, name: "skill-md" });
85447
85825
  if (!name3 || !newName && description === void 0 && !skillMdFile) {
85448
- throw new CliUsageError(USAGE16);
85826
+ throw new CliUsageError(USAGE15);
85449
85827
  }
85450
85828
  const skillMd = skillMdFile ? await readFile33(resolve13(context.cwd, skillMdFile), "utf8") : void 0;
85451
85829
  const { client } = await signedIn({ context, args });
@@ -85464,7 +85842,7 @@ async function skillUpdate({ context, args }) {
85464
85842
  function pinning({ unpin }) {
85465
85843
  return async ({ context, args }) => {
85466
85844
  const name3 = args.words[2];
85467
- if (!name3) throw new CliUsageError(USAGE16);
85845
+ if (!name3) throw new CliUsageError(USAGE15);
85468
85846
  const { client } = await signedIn({ context, args });
85469
85847
  const path = unpin ? "/api/skills/unpin" : "/api/skills/pin";
85470
85848
  const skill2 = await client.post(path, { name: name3, ...agentFlag(args) });
@@ -85488,7 +85866,7 @@ var SKILL_COMMANDS = {
85488
85866
  async function skill({ context, args }) {
85489
85867
  const name3 = args.words[1] ?? "";
85490
85868
  const command = Object.hasOwn(SKILL_COMMANDS, name3) ? SKILL_COMMANDS[name3] : void 0;
85491
- if (!command) throw new CliUsageError(USAGE16);
85869
+ if (!command) throw new CliUsageError(USAGE15);
85492
85870
  await command({ context, args });
85493
85871
  }
85494
85872
 
@@ -86099,11 +86477,11 @@ function statusLine2({ presence: presence2 }) {
86099
86477
  }
86100
86478
 
86101
86479
  // src/services/status-commands.service.ts
86102
- 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";
86103
86481
  function clearAfterOf({ args }) {
86104
86482
  const wanted = flagText({ args, name: "for", fallback: "never" });
86105
86483
  const known = STATUS_CLEAR_AFTER.find((candidate) => candidate === wanted);
86106
- if (!known) throw new CliUsageError(USAGE17);
86484
+ if (!known) throw new CliUsageError(USAGE16);
86107
86485
  return known;
86108
86486
  }
86109
86487
  function answer3({
@@ -86117,7 +86495,7 @@ function answer3({
86117
86495
  }
86118
86496
  async function statusSet({ context, args }) {
86119
86497
  const [, , emoji3, ...words] = args.words;
86120
- if (!emoji3) throw new CliUsageError(USAGE17);
86498
+ if (!emoji3) throw new CliUsageError(USAGE16);
86121
86499
  const clearAfter = clearAfterOf({ args });
86122
86500
  const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
86123
86501
  const { client } = await signedIn({ context, args });
@@ -86141,7 +86519,7 @@ async function statusAway({ context, args }) {
86141
86519
  answer3({ context, args, presence: presence2 });
86142
86520
  }
86143
86521
  async function statusUsage() {
86144
- throw new CliUsageError(USAGE17);
86522
+ throw new CliUsageError(USAGE16);
86145
86523
  }
86146
86524
 
86147
86525
  // src/services/update-commands.service.ts
@@ -86265,7 +86643,7 @@ async function update2({
86265
86643
 
86266
86644
  // src/services/vault-env-commands.service.ts
86267
86645
  import { readFile as readFile36, stat as stat5 } from "node:fs/promises";
86268
- 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";
86269
86647
 
86270
86648
  // src/rules/vault-manifest.rules.ts
86271
86649
  var VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -86374,7 +86752,7 @@ async function doorOf({
86374
86752
  const turnFile = turnFileOf({ env });
86375
86753
  const headers = {
86376
86754
  "proxy-authorization": proxy.authorization,
86377
- "x-laze-turn": await turnTokenOf3({ env, turnFile, command: "laze vault env" })
86755
+ "x-laze-turn": await turnTokenOf2({ env, turnFile, command: "laze vault env" })
86378
86756
  };
86379
86757
  return {
86380
86758
  keyPath: runKeyPathOf({ turnFile, connection: keyName }),
@@ -86444,14 +86822,14 @@ async function untilAllAnswered({
86444
86822
  `
86445
86823
  );
86446
86824
  while (waiting.size > 0) {
86447
- if (context.nowMs() + POLL_MS2 > deadline) {
86825
+ if (context.nowMs() + POLL_MS > deadline) {
86448
86826
  context.err(
86449
86827
  `laze vault: ${[...waiting.keys()].join(", ")} not approved yet; ask again later.
86450
86828
  `
86451
86829
  );
86452
86830
  return "capped";
86453
86831
  }
86454
- await context.sleep(POLL_MS2);
86832
+ await context.sleep(POLL_MS);
86455
86833
  for (const [key, pending] of waiting) {
86456
86834
  const next = await door.status(pending.requestId);
86457
86835
  if (next.outcome === "ask") waiting.set(key, next);
@@ -86606,7 +86984,7 @@ async function manifestPathOf({
86606
86984
  const environment = flagText({ args, name: "env" });
86607
86985
  const file3 = environment ? `.env.${environment}.vault` : ".env.vault";
86608
86986
  for (let dir = resolve15(context.cwd); ; dir = dirname22(dir)) {
86609
- if (await isFile(join24(dir, file3))) return join24(dir, file3);
86987
+ if (await isFile(join25(dir, file3))) return join25(dir, file3);
86610
86988
  if (dirname22(dir) === dir) break;
86611
86989
  }
86612
86990
  throw new CliUsageError(`laze vault: no ${file3} here or in a parent folder
@@ -86717,7 +87095,7 @@ ${ENV_USAGE}`);
86717
87095
  `);
86718
87096
  return 0;
86719
87097
  }
86720
- const redact = [...released.values()].flatMap(({ fields }) => Object.values(fields));
87098
+ const redact = [...released.values()].flatMap(({ fields }) => secretValuesOf({ fields }));
86721
87099
  return context.runCommand({ command: prepared.command, env, redact });
86722
87100
  }
86723
87101
  async function vaultAws({
@@ -86766,7 +87144,7 @@ async function postInTurn({
86766
87144
  body
86767
87145
  }) {
86768
87146
  const env = context.environment.inherited;
86769
- const turn = await turnTokenOf3({
87147
+ const turn = await turnTokenOf2({
86770
87148
  env,
86771
87149
  turnFile: turnFileOf({ env }),
86772
87150
  command: "laze vault save"
@@ -87469,7 +87847,7 @@ async function whatsappBusiness({
87469
87847
  }
87470
87848
 
87471
87849
  // src/services/whatsapp-pairing-commands.service.ts
87472
- import { writeFile as writeFile22 } from "node:fs/promises";
87850
+ import { writeFile as writeFile23 } from "node:fs/promises";
87473
87851
  import { resolve as resolve17 } from "node:path";
87474
87852
  var WHATSAPP_PAIRING_USAGE = [
87475
87853
  " laze whatsapp pair <machine> [--qr <file.svg>] link WhatsApp on your machine; scan the code (owner)",
@@ -87490,7 +87868,7 @@ function svgOf(dataUrl) {
87490
87868
  }
87491
87869
  async function report({ context, args, pairing: pairing2 }) {
87492
87870
  const qrFile = pairing2.qrSvg ? resolve17(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
87493
- if (qrFile && pairing2.qrSvg) await writeFile22(qrFile, svgOf(pairing2.qrSvg), "utf8");
87871
+ if (qrFile && pairing2.qrSvg) await writeFile23(qrFile, svgOf(pairing2.qrSvg), "utf8");
87494
87872
  if (args.flags.json) return context.out(`${JSON.stringify({ ...pairing2, qrFile }, null, 2)}
87495
87873
  `);
87496
87874
  context.out(`${pairing2.pairingId} ${pairing2.state}
@@ -87555,7 +87933,7 @@ var PATHS3 = {
87555
87933
  var STATUS_WAIT_SECONDS2 = 50;
87556
87934
  var STATUS_CALLS2 = 2;
87557
87935
  var SETTLED = /* @__PURE__ */ new Set(["sent", "denied", "expired", "failed"]);
87558
- var USAGE18 = [
87936
+ var USAGE17 = [
87559
87937
  "Usage: laze whatsapp chats <machine> [--limit <n>] the chats on the machine, newest first",
87560
87938
  " laze whatsapp read <machine> <chat> [--limit <n>] a chat's last messages, oldest first",
87561
87939
  ' laze whatsapp send <machine> <chat> "<text>" send as the owner; an agent waits for their approval',
@@ -87565,14 +87943,14 @@ var USAGE18 = [
87565
87943
  ].join("\n");
87566
87944
  function word2({ args, at }) {
87567
87945
  const value = args.words[at];
87568
- if (!value) throw new CliUsageError(USAGE18);
87946
+ if (!value) throw new CliUsageError(USAGE17);
87569
87947
  return value;
87570
87948
  }
87571
87949
  function limitOf5({ args }) {
87572
87950
  const text2 = flagText({ args, name: "limit" });
87573
87951
  if (!text2) return {};
87574
87952
  const limit = Number(text2);
87575
- if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(USAGE18);
87953
+ if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(USAGE17);
87576
87954
  return { limit };
87577
87955
  }
87578
87956
  async function chats({ context, args }) {
@@ -87634,7 +88012,7 @@ Still waiting. Run \`laze whatsapp status ${send4.id}\` later to see the answer.
87634
88012
  }
87635
88013
  async function send3({ context, args }) {
87636
88014
  const text2 = args.words.slice(4).join(" ") || args.rest.join(" ");
87637
- if (!text2) throw new CliUsageError(USAGE18);
88015
+ if (!text2) throw new CliUsageError(USAGE17);
87638
88016
  const client = await computeClient({ context, args });
87639
88017
  const asked = await client.post(PATHS3.send, {
87640
88018
  machine: word2({ args, at: 2 }),
@@ -87664,11 +88042,11 @@ async function whatsapp({
87664
88042
  if (command === "status") return status8({ context, args });
87665
88043
  const linking = whatsappPairingCommand(command);
87666
88044
  if (linking) return linking({ context, args });
87667
- throw new CliUsageError(USAGE18);
88045
+ throw new CliUsageError(USAGE17);
87668
88046
  }
87669
88047
 
87670
88048
  // src/services/wiki-commands.service.ts
87671
- var USAGE19 = `Usage:
88049
+ var USAGE18 = `Usage:
87672
88050
  laze wiki list
87673
88051
  laze wiki get <path>
87674
88052
  laze wiki put <path> <markdown|@file|-> [--title <title>] [--channel <channel>] [--base <version>]
@@ -87688,7 +88066,7 @@ async function wikiList({ context, args }) {
87688
88066
  }
87689
88067
  async function wikiGet({ context, args }) {
87690
88068
  const path = args.words[2];
87691
- if (!path) throw new CliUsageError(USAGE19);
88069
+ if (!path) throw new CliUsageError(USAGE18);
87692
88070
  const { client } = await signedIn({ context, args });
87693
88071
  const page = await client.post("/api/wiki/get", { path });
87694
88072
  if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
@@ -87705,7 +88083,7 @@ Linked from: ${page.backlinks.map((link) => link.path).join(", ")}
87705
88083
  async function wikiPut({ context, args }) {
87706
88084
  const path = args.words[2];
87707
88085
  const value = args.words.slice(3).join(" ");
87708
- if (!path || !value) throw new CliUsageError(USAGE19);
88086
+ if (!path || !value) throw new CliUsageError(USAGE18);
87709
88087
  const body = await textArgument({ context, value });
87710
88088
  const title = flagText({ args, name: "title" });
87711
88089
  const channel = flagText({ args, name: "channel" });
@@ -87725,7 +88103,7 @@ async function wikiPut({ context, args }) {
87725
88103
  }
87726
88104
  async function wikiSearch({ context, args }) {
87727
88105
  const query = args.words.slice(2).join(" ").trim();
87728
- if (!query) throw new CliUsageError(USAGE19);
88106
+ if (!query) throw new CliUsageError(USAGE18);
87729
88107
  const { client } = await signedIn({ context, args });
87730
88108
  const hits = await client.post("/api/wiki/search", { query });
87731
88109
  if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
@@ -87735,7 +88113,7 @@ async function wikiSearch({ context, args }) {
87735
88113
  }
87736
88114
  async function wikiHistory({ context, args }) {
87737
88115
  const path = args.words[2];
87738
- if (!path) throw new CliUsageError(USAGE19);
88116
+ if (!path) throw new CliUsageError(USAGE18);
87739
88117
  const { client } = await signedIn({ context, args });
87740
88118
  const revisions = await client.post("/api/wiki/history", { path });
87741
88119
  if (args.flags.json) return context.out(`${JSON.stringify(revisions, null, 2)}
@@ -87749,7 +88127,7 @@ async function wikiHistory({ context, args }) {
87749
88127
  }
87750
88128
  async function wikiMove({ context, args }) {
87751
88129
  const [, , path, to] = args.words;
87752
- if (!path || !to) throw new CliUsageError(USAGE19);
88130
+ if (!path || !to) throw new CliUsageError(USAGE18);
87753
88131
  const { client } = await signedIn({ context, args });
87754
88132
  const page = await client.post("/api/wiki/move", { path, to });
87755
88133
  if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
@@ -87759,7 +88137,7 @@ async function wikiMove({ context, args }) {
87759
88137
  }
87760
88138
  async function wikiRemove({ context, args }) {
87761
88139
  const path = args.words[2];
87762
- if (!path) throw new CliUsageError(USAGE19);
88140
+ if (!path) throw new CliUsageError(USAGE18);
87763
88141
  const { client } = await signedIn({ context, args });
87764
88142
  const removed = await client.post("/api/wiki/remove", { path });
87765
88143
  if (args.flags.json) return context.out(`${JSON.stringify(removed)}
@@ -87779,7 +88157,7 @@ var WIKI_COMMANDS = {
87779
88157
  async function wiki({ context, args }) {
87780
88158
  const name3 = args.words[1] ?? "";
87781
88159
  const command = Object.hasOwn(WIKI_COMMANDS, name3) ? WIKI_COMMANDS[name3] : void 0;
87782
- if (!command) throw new CliUsageError(USAGE19);
88160
+ if (!command) throw new CliUsageError(USAGE18);
87783
88161
  await command({ context, args });
87784
88162
  }
87785
88163
 
@@ -88095,8 +88473,27 @@ async function list9({ context, args }) {
88095
88473
  context,
88096
88474
  args,
88097
88475
  answer: answer4,
88098
- text: (members3) => members3.map((it) => `${ROLE_NAMES2[it.role]} ${it.name} ${it.email} ${it.userId}
88099
- `).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
+ `
88100
88497
  });
88101
88498
  }
88102
88499
  async function invite({ context, args }) {
@@ -88228,6 +88625,7 @@ var MEMBERS_COMMANDS = {
88228
88625
  "revoke-invite": revokeInvite,
88229
88626
  "invite-link": inviteLink,
88230
88627
  role,
88628
+ aka,
88231
88629
  remove: remove5,
88232
88630
  requests,
88233
88631
  approve: deciding("approved"),
@@ -88239,7 +88637,7 @@ async function members2({ context, args }) {
88239
88637
  const command = MEMBERS_COMMANDS[sub];
88240
88638
  if (!command) {
88241
88639
  throw new CliUsageError(
88242
- "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]"
88243
88641
  );
88244
88642
  }
88245
88643
  return command({ context, args });
@@ -88276,6 +88674,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
88276
88674
  laze update [--dry-run] install the latest release (npm, pnpm, bun or yarn)
88277
88675
  laze logout revoke this profile's key and forget it
88278
88676
  laze whoami who this key speaks for
88677
+ laze changes what changed in Laze lately; retry an action it refused before
88279
88678
  laze workspaces your signed-in profiles
88280
88679
  laze workspace the workspace this key belongs to
88281
88680
  laze workspace mine every workspace you belong to, with your role
@@ -88290,6 +88689,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
88290
88689
  laze members invite <email> [--role owner|admin|member|guest] invite someone (admins)
88291
88690
  laze members invites | revoke-invite <email|id> invitations waiting, or take one back (admins)
88292
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
88293
88693
  laze members role <member> owner|admin|member|guest change a member's role (admins)
88294
88694
  laze members remove <member> take someone out of the workspace (admins)
88295
88695
  laze members requests | approve <id> | deny <id> access requests waiting for an admin
@@ -88421,8 +88821,10 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
88421
88821
  laze connect providers|start|search|mcp|mcp-key|github|card|card-key connect services as yourself
88422
88822
  laze connect install|status|stop|uninstall the service that hands linked Codex sessions their messages
88423
88823
  laze openclaw list|connect|agent|agent-key|feed|disconnect your OpenClaw gateways and their agents
88424
- 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
88425
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
88426
88828
  laze browser setup|cdp|screen|status <machine> a machine with Chrome a person signs in on, for agents
88427
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
88428
88830
  laze browser setup <site> --on <machine> the browser on a person's own machine instead, at no Laze compute cost
@@ -88487,6 +88889,7 @@ var COMMANDS3 = {
88487
88889
  join: joinAsAgent,
88488
88890
  logout,
88489
88891
  whoami,
88892
+ changes,
88490
88893
  workspaces,
88491
88894
  workspace,
88492
88895
  members: members2,
@@ -88685,7 +89088,9 @@ async function runCli({
88685
89088
  [openclaw, OPENCLAW_USAGE],
88686
89089
  [chatActions, CHAT_ACTIONS_USAGE],
88687
89090
  [agentLogins, LOGINS_HELP],
88688
- [agentPools, POOLS_HELP]
89091
+ [agentPools, POOLS_HELP],
89092
+ [browser, `${BROWSER_USAGE}
89093
+ `]
88689
89094
  ]);
88690
89095
  if (command && args.flags.help && ownHelp.has(command)) {
88691
89096
  context.out(ownHelp.get(command) ?? HELP);