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