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