@lazehq/cli 0.1.49 → 0.1.51
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 +902 -503
- 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.51";
|
|
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;
|
|
@@ -58103,6 +58183,7 @@ var NOTICE_DETAILS_MAX = 2e3;
|
|
|
58103
58183
|
var workspaceIdSchema = external_exports.string().min(1);
|
|
58104
58184
|
var idSchema4 = external_exports.string().min(1).max(64);
|
|
58105
58185
|
var chatActorKindSchema = external_exports.enum(["person", "agent"]);
|
|
58186
|
+
var agentLimitCauseSchema = external_exports.enum(["usage", "budget"]);
|
|
58106
58187
|
var chatActorSchemaDefinition = external_exports.object({ kind: chatActorKindSchema, id: idSchema4 });
|
|
58107
58188
|
var chatActorSchema = chatActorSchemaDefinition;
|
|
58108
58189
|
var messageAuthorSchemaDefinition = external_exports.object({
|
|
@@ -58229,6 +58310,8 @@ var attentionCardSchemaDefinition = external_exports.object({
|
|
|
58229
58310
|
canAlwaysAllow: external_exports.boolean(),
|
|
58230
58311
|
/** How long "Allow for this agent" lasts, shown on the button; null when not known. */
|
|
58231
58312
|
alwaysLeaseSeconds: external_exports.number().int().positive().nullable().default(null),
|
|
58313
|
+
/** A vault card whose Allow covers the rest of the agent's turn: "Allow for this task". */
|
|
58314
|
+
allowCoversTask: external_exports.boolean().optional(),
|
|
58232
58315
|
/** The vault's request id when the card is a vault approval; null for a harness question. */
|
|
58233
58316
|
vaultRequestId: external_exports.string().nullable().default(null),
|
|
58234
58317
|
/** A vault approval whose Allow goes through the owner's device passkey. */
|
|
@@ -58578,11 +58661,15 @@ var directoryEntrySchemaDefinition = external_exports.object({
|
|
|
58578
58661
|
email: external_exports.string().nullable(),
|
|
58579
58662
|
/** An agent out of usage until then; null for people and agents that can work. */
|
|
58580
58663
|
limitedUntil: external_exports.iso.datetime().nullable().default(null),
|
|
58664
|
+
/** Why the agent is limited while `limitedUntil` lasts; absent reads as "usage". */
|
|
58665
|
+
limitedBy: agentLimitCauseSchema.optional(),
|
|
58581
58666
|
/** An agent removed from the workspace, when and by whom; null while it is active. */
|
|
58582
58667
|
removedAt: external_exports.iso.datetime().nullable().default(null),
|
|
58583
58668
|
removedByName: external_exports.string().nullable().default(null),
|
|
58584
58669
|
/** An agent that runs outside Laze: what it reads leaves Laze. False for people. */
|
|
58585
|
-
runsOutside: external_exports.boolean().default(false)
|
|
58670
|
+
runsOutside: external_exports.boolean().default(false),
|
|
58671
|
+
/** Other names a person goes by, such as "Drew" or their Slack name; mentions match them. */
|
|
58672
|
+
aliases: external_exports.array(external_exports.string()).optional()
|
|
58586
58673
|
});
|
|
58587
58674
|
var chatOverviewSchemaDefinition = external_exports.object({
|
|
58588
58675
|
viewer: chatActorSchemaDefinition,
|
|
@@ -58998,7 +59085,9 @@ var signalActivityInputSchemaDefinition = external_exports.object({
|
|
|
58998
59085
|
});
|
|
58999
59086
|
var setAgentLimitInputSchemaDefinition = external_exports.object({
|
|
59000
59087
|
workspaceId: workspaceIdSchema,
|
|
59001
|
-
limitedUntil: external_exports.iso.datetime().nullable()
|
|
59088
|
+
limitedUntil: external_exports.iso.datetime().nullable(),
|
|
59089
|
+
/** Why it is limited: its login or its budget. */
|
|
59090
|
+
limitedBy: agentLimitCauseSchema.default("usage")
|
|
59002
59091
|
});
|
|
59003
59092
|
var setAgentNameInputSchemaDefinition = external_exports.object({
|
|
59004
59093
|
workspaceId: workspaceIdSchema,
|
|
@@ -59448,7 +59537,7 @@ var ChatApi = moduleApi()("chat");
|
|
|
59448
59537
|
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
59538
|
var chatChannelRolesTrpc = defineTrpcContract("chat").mutation("setChannelRole").withInput(setChannelRoleInputSchema).withOutput(conversationSchema).mutation("extendChannel").withInput(extendChannelInputSchema).withOutput(conversationSchema).build();
|
|
59450
59539
|
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();
|
|
59540
|
+
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
59541
|
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
59542
|
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
59543
|
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();
|
|
@@ -60450,7 +60539,9 @@ var realtimePublicationSchemaDefinition = external_exports.discriminatedUnion("t
|
|
|
60450
60539
|
type: external_exports.literal("agent_limit"),
|
|
60451
60540
|
workspaceId: external_exports.string(),
|
|
60452
60541
|
agentId: external_exports.string(),
|
|
60453
|
-
limitedUntil: external_exports.iso.datetime().nullable()
|
|
60542
|
+
limitedUntil: external_exports.iso.datetime().nullable(),
|
|
60543
|
+
/** Why it is limited; absent reads as "usage". */
|
|
60544
|
+
limitedBy: agentLimitCauseSchema.optional()
|
|
60454
60545
|
}),
|
|
60455
60546
|
/** An agent was removed from the workspace; its direct messages stay as history. */
|
|
60456
60547
|
external_exports.object({
|
|
@@ -60582,8 +60673,21 @@ var finishVaultDeviceEnrolmentInputSchemaDefinition = external_exports.object({
|
|
|
60582
60673
|
/** P-256 SPKI DER; signs approvals of later devices. */
|
|
60583
60674
|
signingPublicKey: base64Url,
|
|
60584
60675
|
/** DER ECDSA over nativeSignedMessage({ purpose: "enrol", challenge }). */
|
|
60585
|
-
signature: base64Url
|
|
60586
|
-
|
|
60676
|
+
signature: base64Url,
|
|
60677
|
+
/** The same for one install of the app, through Face ID changes; named on a re-enrol. */
|
|
60678
|
+
installId: external_exports.string().min(8).max(128).optional(),
|
|
60679
|
+
/** Required for ios_secure_enclave: DCAppAttestService over appAttestClientData(...). */
|
|
60680
|
+
appAttest: external_exports.object({
|
|
60681
|
+
/** The App Attest key id as iOS returns it (standard base64 of the key's SHA-256). */
|
|
60682
|
+
keyId: external_exports.string().min(1).max(64),
|
|
60683
|
+
/** The CBOR attestation object, base64url. */
|
|
60684
|
+
attestation: base64Url
|
|
60685
|
+
}).optional()
|
|
60686
|
+
}).optional(),
|
|
60687
|
+
/** A re-enrol from the same install: the device it replaces, retired when this one is stored. */
|
|
60688
|
+
replacesDeviceId: external_exports.string().min(1).optional(),
|
|
60689
|
+
/** A fresh reauth proof; required with replacesDeviceId and spent by it. */
|
|
60690
|
+
reauthToken: external_exports.string().min(1).optional()
|
|
60587
60691
|
});
|
|
60588
60692
|
var finishVaultDeviceEnrolmentInputSchema = finishVaultDeviceEnrolmentInputSchemaDefinition;
|
|
60589
60693
|
var sealedRecipientSchema = external_exports.object({
|
|
@@ -60673,7 +60777,9 @@ var answerSealedApprovalInputSchemaDefinition = external_exports.object({
|
|
|
60673
60777
|
release: external_exports.object({ epk: base64Url, ciphertext: base64Url }),
|
|
60674
60778
|
via: external_exports.enum(["feed", "channel", "ios", "desktop", "web"]).default("web"),
|
|
60675
60779
|
/** 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()
|
|
60780
|
+
durationSeconds: external_exports.number().int().positive().optional(),
|
|
60781
|
+
/** The active device that opened the secret; removing it ends this release and its lease. */
|
|
60782
|
+
approverDeviceId: external_exports.string().min(1).optional()
|
|
60677
60783
|
});
|
|
60678
60784
|
var answerSealedApprovalInputSchema = answerSealedApprovalInputSchemaDefinition;
|
|
60679
60785
|
var vaultRunSealedReleaseSchemaDefinition = external_exports.object({
|
|
@@ -61107,7 +61213,12 @@ var openVaultTurnInputSchemaDefinition = external_exports.object({
|
|
|
61107
61213
|
/** Everyone else's messages, oldest first: context for the judge, never permission. */
|
|
61108
61214
|
otherMessages: external_exports.array(external_exports.object({ sender: external_exports.string().min(1), text: external_exports.string() })).default([]),
|
|
61109
61215
|
/** A shorter life than the deployment's turn TTL, for a token made for one command. */
|
|
61110
|
-
ttlMinutes: external_exports.number().int().positive().optional()
|
|
61216
|
+
ttlMinutes: external_exports.number().int().positive().optional(),
|
|
61217
|
+
/**
|
|
61218
|
+
* The task an "Allow for this task" covers: left out, the turn is its own task; null asks for
|
|
61219
|
+
* each command; named, every turn opened for it shares one task, which `scope` describes.
|
|
61220
|
+
*/
|
|
61221
|
+
task: external_exports.object({ id: external_exports.string().min(1).max(200), scope: external_exports.string().max(300).nullable() }).nullable().optional()
|
|
61111
61222
|
});
|
|
61112
61223
|
var vaultAlwaysApprovalActionSchema = external_exports.enum([
|
|
61113
61224
|
"send_external",
|
|
@@ -61199,6 +61310,8 @@ var vaultApprovalStateSchema = external_exports.enum([
|
|
|
61199
61310
|
"denied",
|
|
61200
61311
|
"expired"
|
|
61201
61312
|
]);
|
|
61313
|
+
var vaultApprovalListStateSchemaDefinition = external_exports.union([vaultApprovalStateSchema, external_exports.literal("withdrawn")]).transform((state) => state === "withdrawn" ? "expired" : state);
|
|
61314
|
+
var vaultApprovalListStateSchema = vaultApprovalListStateSchemaDefinition;
|
|
61202
61315
|
var vaultAnswerViaSchema = external_exports.enum(["feed", "channel", "ios", "desktop", "web"]);
|
|
61203
61316
|
var vaultApprovalRequestSchemaDefinition = external_exports.object({
|
|
61204
61317
|
id: external_exports.string(),
|
|
@@ -61228,7 +61341,9 @@ var vaultApprovalRequestSchemaDefinition = external_exports.object({
|
|
|
61228
61341
|
/** The connection's title, so an approver who cannot list it still knows what is asked. */
|
|
61229
61342
|
connectionTitle: external_exports.string().nullable().default(null),
|
|
61230
61343
|
/** The longest lease Allow for this agent offers; null offers only once and deny. */
|
|
61231
|
-
maxLeaseSeconds: external_exports.number().int().positive().nullable().default(null)
|
|
61344
|
+
maxLeaseSeconds: external_exports.number().int().positive().nullable().default(null),
|
|
61345
|
+
/** Allow covers the rest of the agent's turn ("Allow for this task"), not one command. */
|
|
61346
|
+
coversTask: external_exports.boolean().optional()
|
|
61232
61347
|
});
|
|
61233
61348
|
var vaultApprovalRequestSchema = vaultApprovalRequestSchemaDefinition;
|
|
61234
61349
|
var answerVaultApprovalInputSchemaDefinition = external_exports.object({
|
|
@@ -61446,7 +61561,7 @@ var vaultTrpc = defineTrpcContract("vault").mutation("createConnection").withInp
|
|
|
61446
61561
|
reason: external_exports.string().trim().min(1).max(200),
|
|
61447
61562
|
reauthToken: external_exports.string().min(1).max(200).optional()
|
|
61448
61563
|
})
|
|
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:
|
|
61564
|
+
).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
61565
|
external_exports.object({
|
|
61451
61566
|
...connectionInput.shape,
|
|
61452
61567
|
reason: external_exports.string().trim().min(1).max(200),
|
|
@@ -61478,6 +61593,8 @@ var vaultConfig = Config.define((c) => ({
|
|
|
61478
61593
|
"VAULT_PREVIOUS_KEY_GRACE_MINUTES",
|
|
61479
61594
|
external_exports.coerce.number().int().min(0).default(30)
|
|
61480
61595
|
),
|
|
61596
|
+
/** iPhone enrolment without App Attest (simulator); applies only off a public origin. */
|
|
61597
|
+
appAttestDev: c.env("VAULT_APP_ATTEST_DEV", environmentBooleanSchema.default(false)),
|
|
61481
61598
|
/** The origin passkeys are made on; unset accepts any localhost origin, for development. */
|
|
61482
61599
|
publicBaseUrl,
|
|
61483
61600
|
/** A file each audit chain head is appended to as a JSON line; unset only logs the heads. */
|
|
@@ -61561,7 +61678,11 @@ var vaultApprovalRequestedPayloadSchemaDefinition = external_exports.object({
|
|
|
61561
61678
|
/** Sealed to the owner's devices: Allow goes through the device's passkey, deny does not. */
|
|
61562
61679
|
sealed: external_exports.boolean().default(false),
|
|
61563
61680
|
/** For a send, the message it would send, read from the provider. */
|
|
61564
|
-
draft: vaultDraftPreviewSchema.nullable().default(null)
|
|
61681
|
+
draft: vaultDraftPreviewSchema.nullable().default(null),
|
|
61682
|
+
/** Allow covers the rest of the agent's turn ("Allow for this task"), not one command. */
|
|
61683
|
+
coversTask: external_exports.boolean().optional(),
|
|
61684
|
+
/** What a task card's Allow covers when it is wider than one turn: "this session of ...". */
|
|
61685
|
+
taskScope: external_exports.string().nullable().optional()
|
|
61565
61686
|
});
|
|
61566
61687
|
var vaultApprovalResolvedPayloadSchemaDefinition = external_exports.object({
|
|
61567
61688
|
workspaceId: external_exports.string().min(1),
|
|
@@ -61580,6 +61701,10 @@ var vaultApprovalResolvedPayloadSchemaDefinition = external_exports.object({
|
|
|
61580
61701
|
answeredByName: external_exports.string().default(""),
|
|
61581
61702
|
/** A deny or a timeout: until when the same action is refused without a new card. */
|
|
61582
61703
|
blockedUntil: external_exports.iso.datetime().nullable().default(null),
|
|
61704
|
+
/** An expired card closed because the agent's turn that asked ended; nothing is blocked. */
|
|
61705
|
+
endedWithTurn: external_exports.boolean().optional(),
|
|
61706
|
+
/** A task card: its Allow covered the rest of the agent's turn. */
|
|
61707
|
+
coversTask: external_exports.boolean().optional(),
|
|
61583
61708
|
/** Who decides the card, so their open approvals lists refresh. */
|
|
61584
61709
|
approverUserIds: external_exports.array(external_exports.string()).readonly().default([])
|
|
61585
61710
|
});
|
|
@@ -65219,6 +65344,8 @@ var agentSchemaDefinition = external_exports.object({
|
|
|
65219
65344
|
github: agentGithubSchema.nullable().default(null),
|
|
65220
65345
|
/** Out of usage (its login or its Laze models budget) until this time; null when it can work. */
|
|
65221
65346
|
limitedUntil: external_exports.iso.datetime().nullable().default(null),
|
|
65347
|
+
/** Why it is limited: "usage" (its login; also when absent) or "budget" (Laze models). */
|
|
65348
|
+
limitedBy: agentLimitCauseSchema.optional(),
|
|
65222
65349
|
/** Paused by a person since this time: it does not wake until resumed; null when it runs. */
|
|
65223
65350
|
pausedAt: external_exports.iso.datetime().nullable().default(null),
|
|
65224
65351
|
/** Who paused it and the reason they gave; null when it runs or no reason was given. */
|
|
@@ -65520,7 +65647,9 @@ var postedMessageSchemaDefinition = external_exports.object({
|
|
|
65520
65647
|
name: external_exports.string(),
|
|
65521
65648
|
cause: external_exports.enum(["paused", "out_of_usage"]),
|
|
65522
65649
|
/** When an agent out of usage gets its usage back; null while paused. */
|
|
65523
|
-
until: external_exports.iso.datetime().nullable()
|
|
65650
|
+
until: external_exports.iso.datetime().nullable(),
|
|
65651
|
+
/** Why an agent out of usage is limited: its login or budget; absent reads as "usage". */
|
|
65652
|
+
limitedBy: agentLimitCauseSchema.optional()
|
|
65524
65653
|
})
|
|
65525
65654
|
).default([])
|
|
65526
65655
|
});
|
|
@@ -66131,7 +66260,9 @@ var callerWorkspaceMemberSchemaDefinition = external_exports.object({
|
|
|
66131
66260
|
email: external_exports.string(),
|
|
66132
66261
|
name: external_exports.string(),
|
|
66133
66262
|
role: roleSchema,
|
|
66134
|
-
joinedAt: external_exports.iso.datetime()
|
|
66263
|
+
joinedAt: external_exports.iso.datetime(),
|
|
66264
|
+
/** Other names they go by in the workspace; absent or empty without any. */
|
|
66265
|
+
aliases: external_exports.array(external_exports.string()).optional()
|
|
66135
66266
|
});
|
|
66136
66267
|
var callerWorkspaceInviteSchemaDefinition = external_exports.object({
|
|
66137
66268
|
id: external_exports.string().min(1),
|
|
@@ -66173,6 +66304,9 @@ var decideRequestAsCallerInputSchemaDefinition = external_exports.object({
|
|
|
66173
66304
|
requestId: external_exports.string().trim().min(1).max(80),
|
|
66174
66305
|
decision: external_exports.enum(["approved", "denied"])
|
|
66175
66306
|
});
|
|
66307
|
+
var setAliasesAsCallerInputSchemaDefinition = external_exports.object({
|
|
66308
|
+
aliases: external_exports.array(external_exports.string().trim().max(40)).max(5)
|
|
66309
|
+
});
|
|
66176
66310
|
var renameWorkspaceAsCallerInputSchemaDefinition = external_exports.object({
|
|
66177
66311
|
name: external_exports.string().trim().min(1).max(80)
|
|
66178
66312
|
});
|
|
@@ -66736,7 +66870,8 @@ function howItRunsOf({ agent: agent2, owner }) {
|
|
|
66736
66870
|
function statusOf({ agent: agent2 }) {
|
|
66737
66871
|
if (agent2.pausedAt) return `Paused since ${agent2.pausedAt.slice(0, 16).replace("T", " ")} UTC`;
|
|
66738
66872
|
if (agent2.limitedUntil) {
|
|
66739
|
-
|
|
66873
|
+
const until = `${agent2.limitedUntil.slice(0, 16).replace("T", " ")} UTC`;
|
|
66874
|
+
return agent2.limitedBy === "budget" ? `At its budget until ${until}` : `Out of usage until ${until}`;
|
|
66740
66875
|
}
|
|
66741
66876
|
if (agent2.status === "disconnected") return "Disconnected";
|
|
66742
66877
|
return agent2.online ? "Working" : "Ready";
|
|
@@ -67240,6 +67375,10 @@ var slackProfilesSchemaDefinition = external_exports.object({
|
|
|
67240
67375
|
profiles: external_exports.array(slackProfileSchemaDefinition)
|
|
67241
67376
|
});
|
|
67242
67377
|
var slackProfilesSchema = slackProfilesSchemaDefinition;
|
|
67378
|
+
var slackLinkedNamesSchemaDefinition = external_exports.object({
|
|
67379
|
+
people: external_exports.array(external_exports.object({ personId: external_exports.string().min(1), names: external_exports.array(external_exports.string()) }))
|
|
67380
|
+
});
|
|
67381
|
+
var slackLinkedNamesSchema = slackLinkedNamesSchemaDefinition;
|
|
67243
67382
|
|
|
67244
67383
|
// ../../modules/slack/contract/src/slack-setup.ts
|
|
67245
67384
|
var workspaceIdSchema13 = external_exports.string().min(1);
|
|
@@ -67608,7 +67747,7 @@ var slackSearchAnswerSchemaDefinition = external_exports.object({
|
|
|
67608
67747
|
var slackSearchAnswerSchema = slackSearchAnswerSchemaDefinition;
|
|
67609
67748
|
var SlackApi = moduleApi()("slack");
|
|
67610
67749
|
var workspaceInput3 = external_exports.object({ workspaceId: workspaceIdSchema14 });
|
|
67611
|
-
var slackTrpc = defineTrpcContract("slack").query("overview").withInput(workspaceInput3).withOutput(slackOverviewSchema).mutation("startSetup").withInput(startSlackSetupInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("beginSetup").withInput(beginSlackSetupInputSchema).withOutput(slackSetupSchema).mutation("saveAppCredentials").withInput(saveSlackAppCredentialsInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("installApp").withInput(installSlackAppInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startInstall").withInput(startSlackInstallInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startLink").withInput(startSlackLinkInputSchema).withOutput(startedSlackAuthorizeSchema).query("channels").withInput(slackTeamInputSchema).withOutput(external_exports.array(slackChannelViewSchema)).mutation("setMirror").withInput(setSlackMirrorInputSchema).withOutput(slackConnectionViewSchema).mutation("updateConnection").withInput(updateSlackConnectionInputSchema).withOutput(slackConnectionViewSchema).mutation("disconnect").withInput(slackTeamInputSchema).withOutput(external_exports.object({ disconnected: external_exports.literal(true) })).mutation("unlink").withInput(slackTeamInputSchema).withOutput(slackConnectionViewSchema).query("linkPrompts").withInput(workspaceInput3).withOutput(slackLinkPromptsSchema).mutation("dismissLinkPrompt").withInput(dismissSlackLinkPromptInputSchema).withOutput(slackLinkPromptsSchema).query("people").withInput(slackPeopleInputSchema).withOutput(slackPeopleSchema).query("bookmarks").withInput(slackBookmarksInputSchema).withOutput(slackBookmarksSchema).query("profiles").withInput(slackProfilesInputSchema).withOutput(slackProfilesSchema).mutation("openDirect").withInput(openSlackDirectInputSchema).withOutput(openedSlackDirectSchema).mutation("updateApp").withInput(updateSlackAppInputSchema).withOutput(external_exports.object({ updated: external_exports.literal(true) })).query("history").withInput(slackHistoryInputSchema).withOutput(slackHistoryPageSchema).query("search").withInput(slackSearchInputSchema).withOutput(slackSearchAnswerSchema).query("movePreview").withInput(slackMoveChannelInputSchema).withOutput(slackMovePreviewSchema).mutation("startMoves").withInput(startSlackMovesInputSchema).withOutput(startedSlackMovesSchema).mutation("cancelMove").withInput(slackMoveInputSchema).withOutput(slackMoveViewSchema).query("moves").withInput(workspaceInput3).withOutput(slackMovesSchema).build();
|
|
67750
|
+
var slackTrpc = defineTrpcContract("slack").query("overview").withInput(workspaceInput3).withOutput(slackOverviewSchema).mutation("startSetup").withInput(startSlackSetupInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("beginSetup").withInput(beginSlackSetupInputSchema).withOutput(slackSetupSchema).mutation("saveAppCredentials").withInput(saveSlackAppCredentialsInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("installApp").withInput(installSlackAppInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startInstall").withInput(startSlackInstallInputSchema).withOutput(startedSlackAuthorizeSchema).mutation("startLink").withInput(startSlackLinkInputSchema).withOutput(startedSlackAuthorizeSchema).query("channels").withInput(slackTeamInputSchema).withOutput(external_exports.array(slackChannelViewSchema)).mutation("setMirror").withInput(setSlackMirrorInputSchema).withOutput(slackConnectionViewSchema).mutation("updateConnection").withInput(updateSlackConnectionInputSchema).withOutput(slackConnectionViewSchema).mutation("disconnect").withInput(slackTeamInputSchema).withOutput(external_exports.object({ disconnected: external_exports.literal(true) })).mutation("unlink").withInput(slackTeamInputSchema).withOutput(slackConnectionViewSchema).query("linkPrompts").withInput(workspaceInput3).withOutput(slackLinkPromptsSchema).mutation("dismissLinkPrompt").withInput(dismissSlackLinkPromptInputSchema).withOutput(slackLinkPromptsSchema).query("people").withInput(slackPeopleInputSchema).withOutput(slackPeopleSchema).query("bookmarks").withInput(slackBookmarksInputSchema).withOutput(slackBookmarksSchema).query("profiles").withInput(slackProfilesInputSchema).withOutput(slackProfilesSchema).query("linkedNames").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(slackLinkedNamesSchema).mutation("openDirect").withInput(openSlackDirectInputSchema).withOutput(openedSlackDirectSchema).mutation("updateApp").withInput(updateSlackAppInputSchema).withOutput(external_exports.object({ updated: external_exports.literal(true) })).query("history").withInput(slackHistoryInputSchema).withOutput(slackHistoryPageSchema).query("search").withInput(slackSearchInputSchema).withOutput(slackSearchAnswerSchema).query("movePreview").withInput(slackMoveChannelInputSchema).withOutput(slackMovePreviewSchema).mutation("startMoves").withInput(startSlackMovesInputSchema).withOutput(startedSlackMovesSchema).mutation("cancelMove").withInput(slackMoveInputSchema).withOutput(slackMoveViewSchema).query("moves").withInput(workspaceInput3).withOutput(slackMovesSchema).build();
|
|
67612
67751
|
|
|
67613
67752
|
// ../../modules/slack/contract/src/slack-keys.ts
|
|
67614
67753
|
var SLACK_KEY_PATHS = {
|
|
@@ -67714,11 +67853,13 @@ function notInChannelLineOf({
|
|
|
67714
67853
|
`;
|
|
67715
67854
|
}
|
|
67716
67855
|
function waitsForLinesOf({ posted }) {
|
|
67717
|
-
return (posted.waitsFor ?? []).map(
|
|
67718
|
-
(
|
|
67719
|
-
|
|
67720
|
-
|
|
67721
|
-
|
|
67856
|
+
return (posted.waitsFor ?? []).map(({ name: name3, cause, until, limitedBy }) => {
|
|
67857
|
+
if (cause === "paused") return `${name3} is paused; your message waits until it is resumed.
|
|
67858
|
+
`;
|
|
67859
|
+
const state = limitedBy === "budget" ? "at its budget" : "out of usage";
|
|
67860
|
+
return `${name3} is ${state} until ${until}; your message waits for it.
|
|
67861
|
+
`;
|
|
67862
|
+
}).join("");
|
|
67722
67863
|
}
|
|
67723
67864
|
|
|
67724
67865
|
// src/rules/search-format.rules.ts
|
|
@@ -71069,6 +71210,16 @@ someone an action cannot be done because Laze refused it earlier, run \`laze cha
|
|
|
71069
71210
|
again. When a change lifts a refusal you hit in a conversation, tell the people there once that
|
|
71070
71211
|
it works now.
|
|
71071
71212
|
|
|
71213
|
+
## Browser tabs and sign-ins
|
|
71214
|
+
|
|
71215
|
+
- \`laze browser tabs\` lists the live browser tabs of your conversations. You drive every tab
|
|
71216
|
+
your owner owns from this session (\`laze browser goto|read|cdp <tab>\`); you need no Laze
|
|
71217
|
+
computer and no helper agent. Reuse an open tab by its title instead of opening another.
|
|
71218
|
+
- A site needs a sign-in: \`laze browser ask <tab> "Sign in to <site>"\`. The person signs in on
|
|
71219
|
+
the tab's screen and presses Done, which reaches you as a message (\`--wait\` waits for it).
|
|
71220
|
+
- Only when the person says to use a saved key: \`laze browser login <tab> --vault <connection>\`.
|
|
71221
|
+
Never ask for a password and never write scripts that type one.
|
|
71222
|
+
|
|
71072
71223
|
If \`laze\` is not on the PATH, run the same commands through \`npx -y @lazehq/cli@latest\`.
|
|
71073
71224
|
Never print or repeat your Laze key.
|
|
71074
71225
|
`;
|
|
@@ -73787,7 +73938,9 @@ var appPinSchemaDefinition = external_exports.object({
|
|
|
73787
73938
|
/** Set for a browser tab, null for an app. */
|
|
73788
73939
|
browser: browserPinSchemaDefinition.nullable(),
|
|
73789
73940
|
/** Whether the reader may unpin it; a browser tab only its owner, their agents or an Admin. */
|
|
73790
|
-
canUnpin: external_exports.boolean().default(true)
|
|
73941
|
+
canUnpin: external_exports.boolean().default(true),
|
|
73942
|
+
/** The app's own origin, so links to it open in the panel; null for a browser tab. */
|
|
73943
|
+
url: external_exports.string().nullable().default(null)
|
|
73791
73944
|
});
|
|
73792
73945
|
var appPinViewSchemaDefinition = external_exports.object({
|
|
73793
73946
|
activeAppId: external_exports.string().nullable(),
|
|
@@ -74312,6 +74465,7 @@ var AppNavSlot = appUi.component("nav");
|
|
|
74312
74465
|
var AppPanelSlot = appUi.component("panel");
|
|
74313
74466
|
var AppCardSlot = appUi.component("card");
|
|
74314
74467
|
var AppPinStripSlot = appUi.component("pin-strip");
|
|
74468
|
+
var AppLinkHooksToken = appUi.hooks("links");
|
|
74315
74469
|
var AppPinListSlot = appUi.component("pin-list");
|
|
74316
74470
|
|
|
74317
74471
|
// ../../modules/app/contract/src/app.config.ts
|
|
@@ -76620,8 +76774,374 @@ async function billing({ context, args }) {
|
|
|
76620
76774
|
|
|
76621
76775
|
// src/services/browser-commands.service.ts
|
|
76622
76776
|
import { randomBytes } from "node:crypto";
|
|
76623
|
-
import { mkdir as
|
|
76777
|
+
import { mkdir as mkdir19, readFile as readFile18, writeFile as writeFile19 } from "node:fs/promises";
|
|
76778
|
+
import { dirname as dirname18, join as join21 } from "node:path";
|
|
76779
|
+
|
|
76780
|
+
// src/services/browser-tab-commands.service.ts
|
|
76781
|
+
import { mkdir as mkdir18, writeFile as writeFile18 } from "node:fs/promises";
|
|
76782
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
76783
|
+
import { join as join20 } from "node:path";
|
|
76784
|
+
|
|
76785
|
+
// src/rules/browser-login.rules.ts
|
|
76786
|
+
var PASSWORD_NAME = /pass|pwd/i;
|
|
76787
|
+
var USER_NAME = /user|email|e-mail|login|account|name|^id$|_id$/i;
|
|
76788
|
+
function loginValuesOf({
|
|
76789
|
+
connection,
|
|
76790
|
+
values,
|
|
76791
|
+
userField,
|
|
76792
|
+
passField
|
|
76793
|
+
}) {
|
|
76794
|
+
const names = Object.keys(values).toSorted();
|
|
76795
|
+
const listed = names.join(", ") || "no fields";
|
|
76796
|
+
const refusal = (why) => ({
|
|
76797
|
+
refusal: `laze browser login: ${why}; ${connection} holds ${listed}. Pass --user-field <field> and --pass-field <field>.`
|
|
76798
|
+
});
|
|
76799
|
+
if (userField && values[userField] === void 0)
|
|
76800
|
+
return refusal(`${connection} has no field ${userField}`);
|
|
76801
|
+
if (passField && values[passField] === void 0)
|
|
76802
|
+
return refusal(`${connection} has no field ${passField}`);
|
|
76803
|
+
const passName = passField ?? names.find((name3) => PASSWORD_NAME.test(name3)) ?? (names.length === 1 ? names[0] : void 0);
|
|
76804
|
+
if (passName === void 0) return refusal("no field reads as the password");
|
|
76805
|
+
const userName = userField ?? names.find((name3) => name3 !== passName && USER_NAME.test(name3)) ?? void 0;
|
|
76806
|
+
const password = values[passName] ?? "";
|
|
76807
|
+
if (!password) return refusal(`${passName} is empty`);
|
|
76808
|
+
const username = userName === void 0 ? void 0 : values[userName];
|
|
76809
|
+
return username ? { username, password } : { password };
|
|
76810
|
+
}
|
|
76811
|
+
|
|
76812
|
+
// src/services/vault-commands.service.ts
|
|
76813
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
76814
|
+
import { mkdir as mkdir17, readFile as readFile17, rm as rm9, writeFile as writeFile17 } from "node:fs/promises";
|
|
76815
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
76624
76816
|
import { dirname as dirname17, join as join19 } from "node:path";
|
|
76817
|
+
var USAGE6 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
|
|
76818
|
+
Runs the command with the connection's values in its environment, on a Laze agent's computer,
|
|
76819
|
+
on a machine it runs on, or where a connected agent runs, with its own key.
|
|
76820
|
+
--channel <id> the conversation whose turn it runs in, when the agent answers in several`;
|
|
76821
|
+
var POLL_MS = 3e3;
|
|
76822
|
+
var RESTART_WAIT_MS = 12e4;
|
|
76823
|
+
var RESTART_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 1e4];
|
|
76824
|
+
var P2562 = { name: "ECDH", namedCurve: "P-256" };
|
|
76825
|
+
var ServerGoneError = class extends Error {
|
|
76826
|
+
};
|
|
76827
|
+
function proxyOf({ env }) {
|
|
76828
|
+
const raw = env.LAZE_VAULT_PROXY || env.HTTP_PROXY || env.http_proxy;
|
|
76829
|
+
if (!raw) return null;
|
|
76830
|
+
const url2 = new URL(raw);
|
|
76831
|
+
const user = decodeURIComponent(url2.username);
|
|
76832
|
+
const password = decodeURIComponent(url2.password);
|
|
76833
|
+
return {
|
|
76834
|
+
origin: url2.origin,
|
|
76835
|
+
authorization: `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`
|
|
76836
|
+
};
|
|
76837
|
+
}
|
|
76838
|
+
function turnFileOf({
|
|
76839
|
+
env
|
|
76840
|
+
}) {
|
|
76841
|
+
return env.LAZE_TURN_FILE || void 0;
|
|
76842
|
+
}
|
|
76843
|
+
async function turnTokenOf2({
|
|
76844
|
+
env,
|
|
76845
|
+
turnFile,
|
|
76846
|
+
command = "laze vault run"
|
|
76847
|
+
}) {
|
|
76848
|
+
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
76849
|
+
if (pinned) return pinned;
|
|
76850
|
+
if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
76851
|
+
try {
|
|
76852
|
+
return (await readFile17(turnFile, "utf8")).trim();
|
|
76853
|
+
} catch {
|
|
76854
|
+
throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
76855
|
+
}
|
|
76856
|
+
}
|
|
76857
|
+
function runKeyPathOf({
|
|
76858
|
+
turnFile,
|
|
76859
|
+
connection,
|
|
76860
|
+
profile = ""
|
|
76861
|
+
}) {
|
|
76862
|
+
const name3 = createHash2("sha256").update(connection).digest("hex");
|
|
76863
|
+
const base = turnFile ? dirname17(turnFile) : join19(tmpdir2(), "laze-vault", profile);
|
|
76864
|
+
return join19(base, "vault-run-keys", `${name3}.json`);
|
|
76865
|
+
}
|
|
76866
|
+
async function runKeyAt({ path }) {
|
|
76867
|
+
const saved3 = await readFile17(path, "utf8").then(
|
|
76868
|
+
(text2) => JSON.parse(text2),
|
|
76869
|
+
() => void 0
|
|
76870
|
+
);
|
|
76871
|
+
if (saved3 && typeof saved3.publicKey === "string" && saved3.privateKey) {
|
|
76872
|
+
const privateKey = await globalThis.crypto.subtle.importKey("jwk", saved3.privateKey, P2562, false, ["deriveBits"]).catch(() => void 0);
|
|
76873
|
+
if (privateKey) return { privateKey, publicKey: saved3.publicKey };
|
|
76874
|
+
}
|
|
76875
|
+
const fresh = await generateEcdhKeys();
|
|
76876
|
+
const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
|
|
76877
|
+
await mkdir17(dirname17(path), { recursive: true, mode: 448 });
|
|
76878
|
+
await writeFile17(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
|
|
76879
|
+
mode: 384
|
|
76880
|
+
});
|
|
76881
|
+
return fresh;
|
|
76882
|
+
}
|
|
76883
|
+
function connectionRefused(error62) {
|
|
76884
|
+
const cause = error62.cause;
|
|
76885
|
+
if (cause?.code === "ECONNREFUSED") return true;
|
|
76886
|
+
return cause?.errors?.some((inner) => inner.code === "ECONNREFUSED") ?? false;
|
|
76887
|
+
}
|
|
76888
|
+
async function sendOnce({
|
|
76889
|
+
context,
|
|
76890
|
+
url: url2,
|
|
76891
|
+
init
|
|
76892
|
+
}) {
|
|
76893
|
+
let response;
|
|
76894
|
+
try {
|
|
76895
|
+
response = await context.fetcher(url2, init);
|
|
76896
|
+
} catch (error62) {
|
|
76897
|
+
const wasRefused = connectionRefused(error62);
|
|
76898
|
+
if (init.method === "POST" && !wasRefused) throw error62;
|
|
76899
|
+
return { restarting: wasRefused ? "connection refused" : String(error62) };
|
|
76900
|
+
}
|
|
76901
|
+
if (response.status !== 502 && response.status !== 503) return { response };
|
|
76902
|
+
const code = codeOf(await response.clone().text());
|
|
76903
|
+
const neverReached = response.status === 503 && code === "vault_not_answering";
|
|
76904
|
+
if (init.method === "POST" && !neverReached) return { response };
|
|
76905
|
+
return { restarting: `status ${response.status}${code ? ` ${code}` : ""}` };
|
|
76906
|
+
}
|
|
76907
|
+
async function reach(input2) {
|
|
76908
|
+
const { context } = input2;
|
|
76909
|
+
const started = context.nowMs();
|
|
76910
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
76911
|
+
const sent = await sendOnce(input2);
|
|
76912
|
+
if ("response" in sent) return sent.response;
|
|
76913
|
+
if (context.nowMs() - started >= RESTART_WAIT_MS) {
|
|
76914
|
+
throw new ServerGoneError(
|
|
76915
|
+
`laze vault: the Laze server did not come back (${sent.restarting})`
|
|
76916
|
+
);
|
|
76917
|
+
}
|
|
76918
|
+
if (attempt === 0) {
|
|
76919
|
+
context.err(
|
|
76920
|
+
`laze vault: the Laze server is not answering (${sent.restarting}), probably restarting; waiting up to 2 min...
|
|
76921
|
+
`
|
|
76922
|
+
);
|
|
76923
|
+
}
|
|
76924
|
+
await context.sleep(RESTART_BACKOFF_MS[Math.min(attempt, RESTART_BACKOFF_MS.length - 1)] ?? 0);
|
|
76925
|
+
}
|
|
76926
|
+
}
|
|
76927
|
+
function codeOf(text2) {
|
|
76928
|
+
return /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1];
|
|
76929
|
+
}
|
|
76930
|
+
async function releaseOf({ response }) {
|
|
76931
|
+
const text2 = await response.text();
|
|
76932
|
+
if (!response.ok) {
|
|
76933
|
+
return {
|
|
76934
|
+
outcome: "deny",
|
|
76935
|
+
exitCode: 1,
|
|
76936
|
+
message: `laze vault: the release was refused (${codeOf(text2) ?? `status ${response.status}`})`
|
|
76937
|
+
};
|
|
76938
|
+
}
|
|
76939
|
+
return JSON.parse(text2);
|
|
76940
|
+
}
|
|
76941
|
+
async function envOf({
|
|
76942
|
+
release: release2,
|
|
76943
|
+
run: run4
|
|
76944
|
+
}) {
|
|
76945
|
+
if (!release2.sealed) return release2.env;
|
|
76946
|
+
const sealed = await openRunRelease({
|
|
76947
|
+
release: release2.sealed,
|
|
76948
|
+
runPrivateKey: run4.privateKey,
|
|
76949
|
+
runPublicKey: run4.publicKey,
|
|
76950
|
+
requestId: release2.sealed.requestId
|
|
76951
|
+
});
|
|
76952
|
+
return { ...release2.env, ...sealed };
|
|
76953
|
+
}
|
|
76954
|
+
function deadlineOf({ args, nowMs }) {
|
|
76955
|
+
const wait = flagText({ args, name: "wait" }) || (args.flags.wait === true ? args.words[3] : "");
|
|
76956
|
+
if (!wait) return Infinity;
|
|
76957
|
+
if (!(Number(wait) >= 0)) throw new CliUsageError(`--wait takes a number of seconds
|
|
76958
|
+
${USAGE6}`);
|
|
76959
|
+
return nowMs + Number(wait) * 1e3;
|
|
76960
|
+
}
|
|
76961
|
+
async function untilAnswered({
|
|
76962
|
+
context,
|
|
76963
|
+
first,
|
|
76964
|
+
next,
|
|
76965
|
+
deadline
|
|
76966
|
+
}) {
|
|
76967
|
+
let release2 = first;
|
|
76968
|
+
while (release2.outcome === "ask") {
|
|
76969
|
+
if (context.nowMs() + POLL_MS > deadline) {
|
|
76970
|
+
context.err(`${release2.message}. Not approved yet; ask again later.
|
|
76971
|
+
`);
|
|
76972
|
+
return "capped";
|
|
76973
|
+
}
|
|
76974
|
+
if (release2 === first) {
|
|
76975
|
+
context.err(`${release2.message}. Waiting for an answer (cards expire after 12 hours)...
|
|
76976
|
+
`);
|
|
76977
|
+
}
|
|
76978
|
+
await context.sleep(POLL_MS);
|
|
76979
|
+
release2 = await next(release2.requestId);
|
|
76980
|
+
}
|
|
76981
|
+
return release2;
|
|
76982
|
+
}
|
|
76983
|
+
function leaseHolds({
|
|
76984
|
+
release: release2,
|
|
76985
|
+
nowMs
|
|
76986
|
+
}) {
|
|
76987
|
+
const ends = release2.sealed?.leaseEndsAt;
|
|
76988
|
+
return ends !== void 0 && Temporal3.Instant.from(ends).epochMilliseconds > nowMs;
|
|
76989
|
+
}
|
|
76990
|
+
async function vaultRelease({
|
|
76991
|
+
context,
|
|
76992
|
+
args,
|
|
76993
|
+
connection,
|
|
76994
|
+
reason,
|
|
76995
|
+
command
|
|
76996
|
+
}) {
|
|
76997
|
+
const deadline = deadlineOf({ args, nowMs: context.nowMs() });
|
|
76998
|
+
const env = context.environment.inherited;
|
|
76999
|
+
const proxy = proxyOf({ env });
|
|
77000
|
+
if (!proxy) return keyRelease({ context, args, connection, reason, command, deadline });
|
|
77001
|
+
const turnFile = turnFileOf({ env });
|
|
77002
|
+
const headers = {
|
|
77003
|
+
"proxy-authorization": proxy.authorization,
|
|
77004
|
+
"x-laze-turn": await turnTokenOf2({ env, turnFile })
|
|
77005
|
+
};
|
|
77006
|
+
const keyPath = runKeyPathOf({ turnFile, connection });
|
|
77007
|
+
const run4 = await runKeyAt({ path: keyPath });
|
|
77008
|
+
const body = JSON.stringify({ connection, reason, command, recipient: run4.publicKey });
|
|
77009
|
+
let release2;
|
|
77010
|
+
try {
|
|
77011
|
+
const first = await releaseOf({
|
|
77012
|
+
response: await reach({
|
|
77013
|
+
context,
|
|
77014
|
+
url: `${proxy.origin}/vault/release`,
|
|
77015
|
+
init: { method: "POST", headers: { ...headers, "content-type": "application/json" }, body }
|
|
77016
|
+
})
|
|
77017
|
+
});
|
|
77018
|
+
const next = async (requestId) => releaseOf({
|
|
77019
|
+
response: await reach({
|
|
77020
|
+
context,
|
|
77021
|
+
url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
|
|
77022
|
+
init: { method: "GET", headers }
|
|
77023
|
+
})
|
|
77024
|
+
});
|
|
77025
|
+
release2 = await untilAnswered({ context, first, next, deadline });
|
|
77026
|
+
} catch (error62) {
|
|
77027
|
+
if (!(error62 instanceof ServerGoneError)) throw error62;
|
|
77028
|
+
context.err(`${error62.message}. Run the command again to keep waiting.
|
|
77029
|
+
`);
|
|
77030
|
+
return { exitCode: 75 };
|
|
77031
|
+
}
|
|
77032
|
+
return settled({ context, release: release2, run: run4, keyPath });
|
|
77033
|
+
}
|
|
77034
|
+
async function settled({
|
|
77035
|
+
context,
|
|
77036
|
+
release: release2,
|
|
77037
|
+
run: run4,
|
|
77038
|
+
keyPath
|
|
77039
|
+
}) {
|
|
77040
|
+
if (release2 === "capped") return { exitCode: 75 };
|
|
77041
|
+
if (release2.outcome === "deny") {
|
|
77042
|
+
await rm9(keyPath, { force: true });
|
|
77043
|
+
context.err(`${release2.message}
|
|
77044
|
+
`);
|
|
77045
|
+
return { exitCode: release2.exitCode || 1 };
|
|
77046
|
+
}
|
|
77047
|
+
const values = await envOf({ release: release2, run: run4 });
|
|
77048
|
+
if (!leaseHolds({ release: release2, nowMs: context.nowMs() })) await rm9(keyPath, { force: true });
|
|
77049
|
+
if (release2.message) context.err(`${release2.message}
|
|
77050
|
+
`);
|
|
77051
|
+
return { env: values };
|
|
77052
|
+
}
|
|
77053
|
+
function refusedRelease(error62) {
|
|
77054
|
+
if (!(error62 instanceof LazeApiError)) throw error62;
|
|
77055
|
+
return {
|
|
77056
|
+
outcome: "deny",
|
|
77057
|
+
exitCode: 1,
|
|
77058
|
+
message: `laze vault: the release was refused: ${error62.message} (${error62.code})`
|
|
77059
|
+
};
|
|
77060
|
+
}
|
|
77061
|
+
async function keyRelease({
|
|
77062
|
+
context,
|
|
77063
|
+
args,
|
|
77064
|
+
connection,
|
|
77065
|
+
reason,
|
|
77066
|
+
command,
|
|
77067
|
+
deadline
|
|
77068
|
+
}) {
|
|
77069
|
+
const where = new CliUsageError(
|
|
77070
|
+
"laze vault run works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent"
|
|
77071
|
+
);
|
|
77072
|
+
const signed2 = await signedIn({ context, args }).catch(() => null);
|
|
77073
|
+
if (signed2?.profile.kind !== "agent") throw where;
|
|
77074
|
+
const { name: name3 } = signed2;
|
|
77075
|
+
const client = forSession({
|
|
77076
|
+
client: signed2.client,
|
|
77077
|
+
session: await currentSessionOf({ context, args })
|
|
77078
|
+
});
|
|
77079
|
+
const channelId = flagText({ args, name: "channel" }) || null;
|
|
77080
|
+
const keyPath = runKeyPathOf({ turnFile: void 0, connection, profile: name3 });
|
|
77081
|
+
const run4 = await runKeyAt({ path: keyPath });
|
|
77082
|
+
const first = await client.post("/api/agents/me/vault/release", {
|
|
77083
|
+
connection,
|
|
77084
|
+
reason,
|
|
77085
|
+
command,
|
|
77086
|
+
recipient: run4.publicKey,
|
|
77087
|
+
channelId
|
|
77088
|
+
}).catch(refusedRelease);
|
|
77089
|
+
const next = (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease);
|
|
77090
|
+
const release2 = await untilAnswered({ context, first, next, deadline });
|
|
77091
|
+
return settled({ context, release: release2, run: run4, keyPath });
|
|
77092
|
+
}
|
|
77093
|
+
async function vaultRun({
|
|
77094
|
+
context,
|
|
77095
|
+
args
|
|
77096
|
+
}) {
|
|
77097
|
+
const connection = args.words[2];
|
|
77098
|
+
const reason = flagText({ args, name: "reason" });
|
|
77099
|
+
if (!connection || args.rest.length === 0) throw new CliUsageError(USAGE6);
|
|
77100
|
+
if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
|
|
77101
|
+
${USAGE6}`);
|
|
77102
|
+
const foreign = commandReferenceNames({ command: args.rest }).find(
|
|
77103
|
+
(name3) => vaultReferenceConnectionName({ name: name3 }) !== connection
|
|
77104
|
+
);
|
|
77105
|
+
if (foreign !== void 0) {
|
|
77106
|
+
const named = vaultReferenceConnectionName({ name: foreign });
|
|
77107
|
+
context.err(
|
|
77108
|
+
`laze vault: the command names {{vault:${foreign}}}, but this run releases only ${connection}, not ${named}. Nothing was asked and the command did not run.
|
|
77109
|
+
`
|
|
77110
|
+
);
|
|
77111
|
+
return 1;
|
|
77112
|
+
}
|
|
77113
|
+
const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
|
|
77114
|
+
if ("exitCode" in released) return released.exitCode;
|
|
77115
|
+
const prepared = preparedCommand({
|
|
77116
|
+
command: args.rest,
|
|
77117
|
+
released: /* @__PURE__ */ new Map([[connection, released.env]])
|
|
77118
|
+
});
|
|
77119
|
+
if ("refusal" in prepared) {
|
|
77120
|
+
context.err(`${prepared.refusal}
|
|
77121
|
+
`);
|
|
77122
|
+
return 1;
|
|
77123
|
+
}
|
|
77124
|
+
const redact = secretValuesOf({ fields: released.env });
|
|
77125
|
+
return context.runCommand({ command: prepared.command, env: released.env, redact });
|
|
77126
|
+
}
|
|
77127
|
+
function preparedCommand({
|
|
77128
|
+
command,
|
|
77129
|
+
released
|
|
77130
|
+
}) {
|
|
77131
|
+
for (const [name3, fields] of released) {
|
|
77132
|
+
const [problem] = unusableFieldProblems({ fields });
|
|
77133
|
+
if (problem !== void 0) {
|
|
77134
|
+
return {
|
|
77135
|
+
refusal: `laze vault: ${name3}: ${problem}, so the command did not run. Ask its owner to save the real value on the vault page.`
|
|
77136
|
+
};
|
|
77137
|
+
}
|
|
77138
|
+
}
|
|
77139
|
+
const filled = fillCommandReferences({ command, released });
|
|
77140
|
+
if ("refusal" in filled) {
|
|
77141
|
+
return { refusal: `laze vault: ${filled.refusal}. The command did not run.` };
|
|
77142
|
+
}
|
|
77143
|
+
return filled;
|
|
77144
|
+
}
|
|
76625
77145
|
|
|
76626
77146
|
// src/services/browser-tab-commands.service.ts
|
|
76627
77147
|
var BROWSER_TAB_PATHS = {
|
|
@@ -76633,19 +77153,30 @@ var BROWSER_TAB_PATHS = {
|
|
|
76633
77153
|
ask: "/api/compute/browser-tabs/ask",
|
|
76634
77154
|
share: "/api/compute/browser-tabs/share",
|
|
76635
77155
|
close: "/api/compute/browser-tabs/close",
|
|
76636
|
-
cdp: "/api/compute/browser-tabs/cdp"
|
|
77156
|
+
cdp: "/api/compute/browser-tabs/cdp",
|
|
77157
|
+
login: "/api/compute/browser-tabs/login"
|
|
76637
77158
|
};
|
|
77159
|
+
var ASK_WAIT_SECONDS = 15 * 60;
|
|
77160
|
+
var ASK_POLL_MS = 3e3;
|
|
76638
77161
|
var BROWSER_TAB_USAGE = [
|
|
76639
77162
|
"Usage: laze browser open <url> [--title <title>] [--channel <channel>] a live browser tab in the conversation",
|
|
76640
77163
|
" laze browser tabs [--channel <channel>] the conversation's browser tabs",
|
|
76641
77164
|
" laze browser tab <tab> one tab: its owner, sharing and page",
|
|
76642
77165
|
" laze browser goto <tab> <url> send the tab to another page",
|
|
76643
77166
|
" laze browser read <tab> the page's address, title and text",
|
|
76644
|
-
" laze browser ask <tab> <what>
|
|
77167
|
+
" laze browser ask <tab> <what> [--wait[=<seconds>]] ask the person you work for to sign in or click something there",
|
|
77168
|
+
" laze browser login <tab> --vault <connection> [--reason <why>] [--user-field <field> --pass-field <field>]",
|
|
77169
|
+
" [--user-input <css> --pass-input <css>] type a saved sign-in into the page and submit it",
|
|
76645
77170
|
" laze browser cdp <tab> a CDP address on the tab's browser",
|
|
76646
77171
|
" laze browser share <tab> private|watch|use who sees the screen and who types into it",
|
|
76647
77172
|
" laze browser close <tab> unpin the tab and close its browser",
|
|
76648
|
-
"A tab is named by its id or its title."
|
|
77173
|
+
"A tab is named by its id or its title. Opening a title that is already open reuses that tab.",
|
|
77174
|
+
"Any agent working for the tab's owner drives it, connected agents (Claude Code, Codex) from",
|
|
77175
|
+
"their own session included; no Laze computer is needed. Another person's agent cannot.",
|
|
77176
|
+
"Sign-ins: ask the person in the tab first (`laze browser ask`); they sign in on the screen and",
|
|
77177
|
+
"press Done, which reaches you at once. Use `laze browser login --vault` only when the person",
|
|
77178
|
+
"says to use a saved key; a code or emailed link it meets becomes a request to them in the tab.",
|
|
77179
|
+
"Never write scripts that type passwords."
|
|
76649
77180
|
].join("\n");
|
|
76650
77181
|
var SHARING = /* @__PURE__ */ new Set(["private", "watch", "use"]);
|
|
76651
77182
|
function channelOf({ context, args }) {
|
|
@@ -76677,6 +77208,12 @@ async function openTab({ args, client, channel, print: print9 }) {
|
|
|
76677
77208
|
...title ? { title } : {},
|
|
76678
77209
|
...channel
|
|
76679
77210
|
});
|
|
77211
|
+
if (tab.reused)
|
|
77212
|
+
return print9(
|
|
77213
|
+
tab,
|
|
77214
|
+
`Reused ${tab.title} (${tab.id}), ${tab.ownerName}'s browser tab already open, and sent it to ${tab.url}
|
|
77215
|
+
`
|
|
77216
|
+
);
|
|
76680
77217
|
print9(
|
|
76681
77218
|
tab,
|
|
76682
77219
|
`Opened ${tab.title} (${tab.id}) in ${tab.ownerName}'s browser, pinned as a tab of the conversation.
|
|
@@ -76714,17 +77251,134 @@ async function readTab({ args, client, channel, print: print9 }) {
|
|
|
76714
77251
|
});
|
|
76715
77252
|
print9(page, pageText({ page }));
|
|
76716
77253
|
}
|
|
76717
|
-
async function askOnTab(
|
|
77254
|
+
async function askOnTab(run4) {
|
|
77255
|
+
const { args, client, channel, print: print9 } = run4;
|
|
76718
77256
|
const tab = word({ args, at: 2 });
|
|
76719
77257
|
const text2 = args.words.slice(3).join(" ").trim();
|
|
76720
77258
|
if (!text2) throw new CliUsageError(BROWSER_TAB_USAGE);
|
|
76721
77259
|
const asked = await client.post(BROWSER_TAB_PATHS.ask, { tab, text: text2, ...channel });
|
|
76722
|
-
|
|
76723
|
-
|
|
76724
|
-
|
|
77260
|
+
const who = asked.ask?.userName ?? asked.ownerName;
|
|
77261
|
+
if (args.flags.wait === void 0)
|
|
77262
|
+
return print9(
|
|
77263
|
+
asked,
|
|
77264
|
+
`Asked ${who} in the conversation; the tab shows them your request full screen with "Done, hand back".
|
|
76725
77265
|
Wait for their "Done" message before you go on in ${asked.title}.
|
|
77266
|
+
`
|
|
77267
|
+
);
|
|
77268
|
+
run4.context.err(`Asked ${who} in the conversation; waiting for their Done...
|
|
77269
|
+
`);
|
|
77270
|
+
return waitForDone({ run: run4, tab: asked, who });
|
|
77271
|
+
}
|
|
77272
|
+
async function waitForDone({
|
|
77273
|
+
run: run4,
|
|
77274
|
+
tab,
|
|
77275
|
+
who
|
|
77276
|
+
}) {
|
|
77277
|
+
const { context, args, client, channel, print: print9 } = run4;
|
|
77278
|
+
const seconds = Number(flagText({ args, name: "wait" }) || ASK_WAIT_SECONDS);
|
|
77279
|
+
if (!(seconds > 0)) throw new CliUsageError(BROWSER_TAB_USAGE);
|
|
77280
|
+
const deadline = context.nowMs() + seconds * 1e3;
|
|
77281
|
+
while (context.nowMs() < deadline) {
|
|
77282
|
+
await context.sleep(Math.min(ASK_POLL_MS, Math.max(0, deadline - context.nowMs())));
|
|
77283
|
+
const now = await client.post(BROWSER_TAB_PATHS.get, { tab: tab.id, ...channel });
|
|
77284
|
+
if (!now.ask) return print9(now, `${who} pressed Done. ${now.title} shows ${now.url}
|
|
77285
|
+
`);
|
|
77286
|
+
}
|
|
77287
|
+
print9(
|
|
77288
|
+
tab,
|
|
77289
|
+
`${who} has not pressed Done yet; the request stays open. Wait for their "Done" message.
|
|
76726
77290
|
`
|
|
76727
77291
|
);
|
|
77292
|
+
return 75;
|
|
77293
|
+
}
|
|
77294
|
+
async function loginOnTab(run4) {
|
|
77295
|
+
const { context, args, client, channel, json: json5 } = run4;
|
|
77296
|
+
const tab = word({ args, at: 2 });
|
|
77297
|
+
const connection = flagText({ args, name: "vault" });
|
|
77298
|
+
if (!connection)
|
|
77299
|
+
throw new CliUsageError(
|
|
77300
|
+
`Name the saved sign-in with --vault <connection>
|
|
77301
|
+
${BROWSER_TAB_USAGE}`
|
|
77302
|
+
);
|
|
77303
|
+
const reason = flagText({ args, name: "reason" }) || `Sign in on the ${tab} browser tab of the conversation`;
|
|
77304
|
+
const released = await vaultRelease({
|
|
77305
|
+
context,
|
|
77306
|
+
args,
|
|
77307
|
+
connection,
|
|
77308
|
+
reason,
|
|
77309
|
+
command: ["laze", "browser", "login", tab]
|
|
77310
|
+
});
|
|
77311
|
+
if ("exitCode" in released) return released.exitCode;
|
|
77312
|
+
const [problem] = unusableFieldProblems({ fields: released.env });
|
|
77313
|
+
if (problem !== void 0) {
|
|
77314
|
+
context.err(`laze browser login: ${connection}: ${problem}. Nothing was typed.
|
|
77315
|
+
`);
|
|
77316
|
+
return 1;
|
|
77317
|
+
}
|
|
77318
|
+
const values = loginValuesOf({
|
|
77319
|
+
connection,
|
|
77320
|
+
values: released.env,
|
|
77321
|
+
userField: flagText({ args, name: "user-field" }) || void 0,
|
|
77322
|
+
passField: flagText({ args, name: "pass-field" }) || void 0
|
|
77323
|
+
});
|
|
77324
|
+
if ("refusal" in values) {
|
|
77325
|
+
context.err(`${values.refusal}
|
|
77326
|
+
`);
|
|
77327
|
+
return 1;
|
|
77328
|
+
}
|
|
77329
|
+
const userInput = flagText({ args, name: "user-input" });
|
|
77330
|
+
const passInput = flagText({ args, name: "pass-input" });
|
|
77331
|
+
const answer4 = await client.post(BROWSER_TAB_PATHS.login, {
|
|
77332
|
+
tab,
|
|
77333
|
+
...values,
|
|
77334
|
+
...userInput ? { userInput } : {},
|
|
77335
|
+
...passInput ? { passInput } : {},
|
|
77336
|
+
...channel
|
|
77337
|
+
});
|
|
77338
|
+
const screenshotPath = answer4.screenshot ? await savedScreenshot({
|
|
77339
|
+
tabId: answer4.tabId,
|
|
77340
|
+
data: answer4.screenshot,
|
|
77341
|
+
nowMs: context.nowMs()
|
|
77342
|
+
}) : null;
|
|
77343
|
+
const { screenshot: _shown, ...rest } = answer4;
|
|
77344
|
+
if (json5) context.out(`${JSON.stringify({ ...rest, screenshotPath }, null, 2)}
|
|
77345
|
+
`);
|
|
77346
|
+
else context.out(loginText({ answer: answer4, tab, screenshotPath }));
|
|
77347
|
+
return answer4.state === "refused" || answer4.state === "still_on_form" ? 1 : 0;
|
|
77348
|
+
}
|
|
77349
|
+
function loginText({
|
|
77350
|
+
answer: answer4,
|
|
77351
|
+
tab,
|
|
77352
|
+
screenshotPath
|
|
77353
|
+
}) {
|
|
77354
|
+
const page = `${answer4.title || "(no title)"}
|
|
77355
|
+
${answer4.url}
|
|
77356
|
+
`;
|
|
77357
|
+
const shot = screenshotPath ? `Screenshot: ${screenshotPath}
|
|
77358
|
+
` : "";
|
|
77359
|
+
if (answer4.state === "signed_in") return `Signed in.
|
|
77360
|
+
${page}${shot}`;
|
|
77361
|
+
if (answer4.state === "second_step")
|
|
77362
|
+
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;
|
|
77363
|
+
wait for their "Done" message before you go on.
|
|
77364
|
+
${page}${shot}`;
|
|
77365
|
+
if (answer4.state === "refused")
|
|
77366
|
+
return `The site refused the sign-in: ${answer4.error ?? "no reason shown"}
|
|
77367
|
+
${page}${shot}`;
|
|
77368
|
+
return `Still on the sign-in page after submitting. Look at the screenshot, then ask the person in the tab:
|
|
77369
|
+
laze browser ask ${tab} "Finish signing in"
|
|
77370
|
+
${page}${shot}`;
|
|
77371
|
+
}
|
|
77372
|
+
async function savedScreenshot({
|
|
77373
|
+
tabId,
|
|
77374
|
+
data,
|
|
77375
|
+
nowMs
|
|
77376
|
+
}) {
|
|
77377
|
+
const folder = join20(tmpdir3(), "laze-browser");
|
|
77378
|
+
await mkdir18(folder, { recursive: true, mode: 448 });
|
|
77379
|
+
const path = join20(folder, `${tabId.replace(/[^a-zA-Z0-9_-]/g, "_")}-login-${nowMs}.jpg`);
|
|
77380
|
+
await writeFile18(path, Buffer.from(data, "base64"), { mode: 384 });
|
|
77381
|
+
return path;
|
|
76728
77382
|
}
|
|
76729
77383
|
async function shareTab({ args, client, channel, print: print9 }) {
|
|
76730
77384
|
const tab = word({ args, at: 2 });
|
|
@@ -76750,6 +77404,7 @@ var TAB_RUNS = {
|
|
|
76750
77404
|
goto: gotoTab,
|
|
76751
77405
|
read: readTab,
|
|
76752
77406
|
ask: askOnTab,
|
|
77407
|
+
login: loginOnTab,
|
|
76753
77408
|
share: shareTab,
|
|
76754
77409
|
close: closeTab
|
|
76755
77410
|
};
|
|
@@ -76763,7 +77418,7 @@ async function browserTab({
|
|
|
76763
77418
|
const json5 = Boolean(args.flags.json);
|
|
76764
77419
|
const print9 = (value, text2) => context.out(json5 ? `${JSON.stringify(value, null, 2)}
|
|
76765
77420
|
` : text2);
|
|
76766
|
-
|
|
77421
|
+
return handler({ context, args, client, channel: channelOf({ context, args }), json: json5, print: print9 });
|
|
76767
77422
|
}
|
|
76768
77423
|
async function browserTabCdp({
|
|
76769
77424
|
context,
|
|
@@ -77178,7 +77833,7 @@ var PATHS2 = {
|
|
|
77178
77833
|
wake: "/api/compute/machines/wake",
|
|
77179
77834
|
delete: "/api/compute/machines/delete"
|
|
77180
77835
|
};
|
|
77181
|
-
var
|
|
77836
|
+
var BROWSER_USAGE = [
|
|
77182
77837
|
"Usage: laze browser setup <site> [--name <machine>] a machine with Chrome a person signs in on",
|
|
77183
77838
|
" laze browser setup <site> --on <machine> the same on a person's own machine (laze machine list)",
|
|
77184
77839
|
" laze browser cdp <machine> a CDP address for this turn (Playwright connectOverCDP)",
|
|
@@ -77188,7 +77843,7 @@ var USAGE6 = [
|
|
|
77188
77843
|
"",
|
|
77189
77844
|
BROWSER_TAB_USAGE
|
|
77190
77845
|
].join("\n");
|
|
77191
|
-
async function
|
|
77846
|
+
async function turnTokenOf3({
|
|
77192
77847
|
context,
|
|
77193
77848
|
args,
|
|
77194
77849
|
client,
|
|
@@ -77198,7 +77853,7 @@ async function turnTokenOf2({
|
|
|
77198
77853
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
77199
77854
|
if (pinned) return pinned;
|
|
77200
77855
|
if (env.LAZE_TURN_FILE) {
|
|
77201
|
-
return
|
|
77856
|
+
return readFile18(env.LAZE_TURN_FILE, "utf8").then(
|
|
77202
77857
|
(text2) => text2.trim(),
|
|
77203
77858
|
() => ""
|
|
77204
77859
|
);
|
|
@@ -77211,7 +77866,7 @@ async function computeClient({
|
|
|
77211
77866
|
args
|
|
77212
77867
|
}) {
|
|
77213
77868
|
const { client, profile } = await signedIn({ context, args });
|
|
77214
|
-
const turn = await
|
|
77869
|
+
const turn = await turnTokenOf3({ context, args, client, agent: profile.kind === "agent" });
|
|
77215
77870
|
return turn ? client.withHeaders({ "x-laze-turn": turn }) : client;
|
|
77216
77871
|
}
|
|
77217
77872
|
function siteLine(machine2) {
|
|
@@ -77225,12 +77880,12 @@ function statusLine(machine2) {
|
|
|
77225
77880
|
}
|
|
77226
77881
|
function machineArg({ args }) {
|
|
77227
77882
|
const machine2 = args.words[2];
|
|
77228
|
-
if (!machine2) throw new CliUsageError(
|
|
77883
|
+
if (!machine2) throw new CliUsageError(BROWSER_USAGE);
|
|
77229
77884
|
return machine2;
|
|
77230
77885
|
}
|
|
77231
77886
|
async function setup({ context, args }) {
|
|
77232
77887
|
const site = args.words[2];
|
|
77233
|
-
if (!site) throw new CliUsageError(
|
|
77888
|
+
if (!site) throw new CliUsageError(BROWSER_USAGE);
|
|
77234
77889
|
const name3 = flagText({ args, name: "name" }) || void 0;
|
|
77235
77890
|
const on = flagText({ args, name: "on" }) || void 0;
|
|
77236
77891
|
const client = await computeClient({ context, args });
|
|
@@ -77288,7 +77943,7 @@ async function answering({
|
|
|
77288
77943
|
}
|
|
77289
77944
|
function bridgeStatePath({ context, machine: machine2 }) {
|
|
77290
77945
|
const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
77291
|
-
return
|
|
77946
|
+
return join21(dirname18(context.environment.configPath), "bridges", `${safe}.json`);
|
|
77292
77947
|
}
|
|
77293
77948
|
async function bridgePort({
|
|
77294
77949
|
context,
|
|
@@ -77296,7 +77951,7 @@ async function bridgePort({
|
|
|
77296
77951
|
access
|
|
77297
77952
|
}) {
|
|
77298
77953
|
const path = bridgeStatePath({ context, machine: machine2 });
|
|
77299
|
-
const live = await
|
|
77954
|
+
const live = await readFile18(path, "utf8").then(
|
|
77300
77955
|
(text2) => JSON.parse(text2),
|
|
77301
77956
|
() => void 0
|
|
77302
77957
|
);
|
|
@@ -77309,15 +77964,15 @@ async function bridgePort({
|
|
|
77309
77964
|
key,
|
|
77310
77965
|
...target
|
|
77311
77966
|
});
|
|
77312
|
-
await
|
|
77313
|
-
await
|
|
77967
|
+
await mkdir19(dirname18(path), { recursive: true, mode: 448 });
|
|
77968
|
+
await writeFile19(path, JSON.stringify({ port, key }), { mode: 384 });
|
|
77314
77969
|
return port;
|
|
77315
77970
|
}
|
|
77316
77971
|
async function bridge({ context }) {
|
|
77317
77972
|
const env = context.environment.inherited;
|
|
77318
77973
|
const target = env.LAZE_CDP_TARGET;
|
|
77319
77974
|
const expiresAt = env.LAZE_CDP_EXPIRES_AT;
|
|
77320
|
-
if (!target || !expiresAt) throw new CliUsageError(
|
|
77975
|
+
if (!target || !expiresAt) throw new CliUsageError(BROWSER_USAGE);
|
|
77321
77976
|
let until = Temporal3.Instant.from(expiresAt).epochMilliseconds;
|
|
77322
77977
|
const running = await startCdpBridge({
|
|
77323
77978
|
target,
|
|
@@ -77374,8 +78029,21 @@ async function change({
|
|
|
77374
78029
|
`);
|
|
77375
78030
|
context.out(statusLine(machine2));
|
|
77376
78031
|
}
|
|
77377
|
-
var TAB_COMMANDS = /* @__PURE__ */ new Set([
|
|
77378
|
-
|
|
78032
|
+
var TAB_COMMANDS = /* @__PURE__ */ new Set([
|
|
78033
|
+
"open",
|
|
78034
|
+
"tabs",
|
|
78035
|
+
"tab",
|
|
78036
|
+
"goto",
|
|
78037
|
+
"read",
|
|
78038
|
+
"ask",
|
|
78039
|
+
"login",
|
|
78040
|
+
"share",
|
|
78041
|
+
"close"
|
|
78042
|
+
]);
|
|
78043
|
+
async function browser({
|
|
78044
|
+
context,
|
|
78045
|
+
args
|
|
78046
|
+
}) {
|
|
77379
78047
|
const command = args.words[1];
|
|
77380
78048
|
if (command && TAB_COMMANDS.has(command))
|
|
77381
78049
|
return browserTab({ context, args, client: await computeClient({ context, args }) });
|
|
@@ -77386,7 +78054,7 @@ async function browser({ context, args }) {
|
|
|
77386
78054
|
if (command === "status") return status3({ context, args });
|
|
77387
78055
|
if (command === "sleep" || command === "wake" || command === "delete")
|
|
77388
78056
|
return change({ context, args, path: PATHS2[command] });
|
|
77389
|
-
throw new CliUsageError(
|
|
78057
|
+
throw new CliUsageError(BROWSER_USAGE);
|
|
77390
78058
|
}
|
|
77391
78059
|
|
|
77392
78060
|
// src/rules/channel-format.rules.ts
|
|
@@ -77958,7 +78626,7 @@ async function channelSettings({ context, args }) {
|
|
|
77958
78626
|
}
|
|
77959
78627
|
|
|
77960
78628
|
// src/services/chat-actions-commands.service.ts
|
|
77961
|
-
import { readFile as
|
|
78629
|
+
import { readFile as readFile19 } from "node:fs/promises";
|
|
77962
78630
|
import { basename as basename3, isAbsolute as isAbsolute2, relative as relative4, resolve as resolve7 } from "node:path";
|
|
77963
78631
|
|
|
77964
78632
|
// src/rules/file-types.rules.ts
|
|
@@ -78040,7 +78708,7 @@ async function uploadFile({
|
|
|
78040
78708
|
|
|
78041
78709
|
// src/services/thread-wait-commands.service.ts
|
|
78042
78710
|
var USAGE7 = "Usage: laze thread <message-id> --wait-reply [--timeout <1-3600 seconds>]";
|
|
78043
|
-
var
|
|
78711
|
+
var POLL_MS2 = 3e3;
|
|
78044
78712
|
function timeoutOf({ args }) {
|
|
78045
78713
|
const seconds = Number(flagText({ args, name: "timeout", fallback: "600" }));
|
|
78046
78714
|
if (!Number.isInteger(seconds) || seconds < 1 || seconds > 3600) throw new CliUsageError(USAGE7);
|
|
@@ -78057,8 +78725,8 @@ async function threadWaitReply({
|
|
|
78057
78725
|
const read3 = () => client.post(CHAT_KEY_PATHS.thread, { messageId });
|
|
78058
78726
|
const seen = new Set((await read3()).replies.map((reply2) => reply2.id));
|
|
78059
78727
|
const isNew = (reply2) => reply2.author.kind === "person" && !seen.has(reply2.id);
|
|
78060
|
-
for (let waited = 0; waited < seconds * 1e3; waited +=
|
|
78061
|
-
await context.sleep(
|
|
78728
|
+
for (let waited = 0; waited < seconds * 1e3; waited += POLL_MS2) {
|
|
78729
|
+
await context.sleep(POLL_MS2);
|
|
78062
78730
|
const reply2 = (await read3()).replies.find(isNew);
|
|
78063
78731
|
if (!reply2) continue;
|
|
78064
78732
|
const line = `${reply2.seq} ${reply2.id} person ${reply2.author.id} ${reply2.body}
|
|
@@ -78296,7 +78964,7 @@ function uploadNameOf({ cwd, path }) {
|
|
|
78296
78964
|
}
|
|
78297
78965
|
var fileUpload = async ({ context, args, client }) => {
|
|
78298
78966
|
const path = resolve7(context.cwd, wordAt(args, 3));
|
|
78299
|
-
const bytes = new Uint8Array(await
|
|
78967
|
+
const bytes = new Uint8Array(await readFile19(path));
|
|
78300
78968
|
const answer4 = await uploadFile({
|
|
78301
78969
|
context,
|
|
78302
78970
|
client,
|
|
@@ -78469,7 +79137,7 @@ async function chatActions({
|
|
|
78469
79137
|
}
|
|
78470
79138
|
|
|
78471
79139
|
// src/services/claude-monitor.service.ts
|
|
78472
|
-
import { readFile as
|
|
79140
|
+
import { readFile as readFile20, rm as rm10 } from "node:fs/promises";
|
|
78473
79141
|
var MONITOR_IDLE_MS = 3e4;
|
|
78474
79142
|
var MONITOR_OUTRANKED_MS = 3e3;
|
|
78475
79143
|
async function deliverOnce({
|
|
@@ -78531,7 +79199,7 @@ async function monitorRound(turn) {
|
|
|
78531
79199
|
async function release({ context, profile }) {
|
|
78532
79200
|
const lock = statePathOf({ context, kind: "waiters", profile });
|
|
78533
79201
|
if ((await holderOf({ path: lock }))?.pid === context.processes.pid)
|
|
78534
|
-
await
|
|
79202
|
+
await rm10(lock, { force: true });
|
|
78535
79203
|
}
|
|
78536
79204
|
async function monitorHook({ context, args }) {
|
|
78537
79205
|
const claudePid = await claudePidOf({ context });
|
|
@@ -78570,7 +79238,7 @@ async function monitorSessionOf({
|
|
|
78570
79238
|
const fromEnv = sessionOf({ context, harness: "claude-code", sessionId });
|
|
78571
79239
|
if (fromEnv || !claudePid) return fromEnv;
|
|
78572
79240
|
const path = statePathOf({ context, kind: "sessions", profile: String(claudePid) });
|
|
78573
|
-
return
|
|
79241
|
+
return readFile20(path, "utf8").then(
|
|
78574
79242
|
(text2) => JSON.parse(text2),
|
|
78575
79243
|
() => void 0
|
|
78576
79244
|
);
|
|
@@ -78607,6 +79275,8 @@ var browserTabDefinition = external_exports.object({
|
|
|
78607
79275
|
/** What an agent asked a person to do in the tab, until someone who may answer presses Done. */
|
|
78608
79276
|
ask: browserTabAskDefinition.nullable(),
|
|
78609
79277
|
createdAt: external_exports.iso.datetime(),
|
|
79278
|
+
/** Only on an open: an open tab of that title was reused instead of making a second one. */
|
|
79279
|
+
reused: external_exports.boolean().optional(),
|
|
78610
79280
|
/** What the reader may do: see the screen, type into it, change the tab; asked: the open
|
|
78611
79281
|
* request names them. */
|
|
78612
79282
|
you: external_exports.object({
|
|
@@ -78654,6 +79324,31 @@ var shareDefinition = external_exports.object({
|
|
|
78654
79324
|
sharing: browserTabSharingSchema
|
|
78655
79325
|
});
|
|
78656
79326
|
var browserTabShareInputSchema = shareDefinition;
|
|
79327
|
+
var loginDefinition = external_exports.object({
|
|
79328
|
+
...browserTabRefDefinition.shape,
|
|
79329
|
+
username: external_exports.string().min(1).max(1e3).optional(),
|
|
79330
|
+
password: external_exports.string().min(1).max(1e3),
|
|
79331
|
+
userInput: external_exports.string().trim().min(1).max(300).optional(),
|
|
79332
|
+
passInput: external_exports.string().trim().min(1).max(300).optional()
|
|
79333
|
+
});
|
|
79334
|
+
var browserLoginStateSchema = external_exports.enum([
|
|
79335
|
+
"signed_in",
|
|
79336
|
+
"second_step",
|
|
79337
|
+
"refused",
|
|
79338
|
+
"still_on_form"
|
|
79339
|
+
]);
|
|
79340
|
+
var loginAnswerDefinition = external_exports.object({
|
|
79341
|
+
tabId: external_exports.string().min(1),
|
|
79342
|
+
url: external_exports.string(),
|
|
79343
|
+
title: external_exports.string(),
|
|
79344
|
+
state: browserLoginStateSchema,
|
|
79345
|
+
/** The page's error line when it refused the sign-in. */
|
|
79346
|
+
error: external_exports.string().nullable(),
|
|
79347
|
+
/** The screen after submitting, a JPEG in base64; null when the browser gave none. */
|
|
79348
|
+
screenshot: external_exports.string().nullable(),
|
|
79349
|
+
/** On a second step: the person the tab now asks to finish it. */
|
|
79350
|
+
askedUserName: external_exports.string().nullable()
|
|
79351
|
+
});
|
|
78657
79352
|
var browserTabPageDefinition = external_exports.object({
|
|
78658
79353
|
tabId: external_exports.string().min(1),
|
|
78659
79354
|
url: external_exports.string(),
|
|
@@ -78693,6 +79388,7 @@ var restBrowserTabInputDefinition = browserTabRefDefinition.omit({ workspaceId:
|
|
|
78693
79388
|
var restBrowserTabGotoInputDefinition = gotoDefinition.omit({ workspaceId: true });
|
|
78694
79389
|
var restBrowserTabAskInputDefinition = askDefinition.omit({ workspaceId: true });
|
|
78695
79390
|
var restBrowserTabShareInputDefinition = shareDefinition.omit({ workspaceId: true });
|
|
79391
|
+
var restBrowserTabLoginInputDefinition = loginDefinition.omit({ workspaceId: true });
|
|
78696
79392
|
|
|
78697
79393
|
// ../../modules/compute/contract/src/compute.config.ts
|
|
78698
79394
|
var computeConfig = Config.define((c) => ({
|
|
@@ -80005,6 +80701,7 @@ var machineWatchStateDefinition = external_exports.object({
|
|
|
80005
80701
|
var computeUi = uiTokens("compute");
|
|
80006
80702
|
var ComputeBrowserTabSlot = computeUi.component("browser-tab");
|
|
80007
80703
|
var ComputeOpenBrowserSlot = computeUi.component("open-browser");
|
|
80704
|
+
var ComputeBrowserLinkOfferSlot = computeUi.component("browser-link-offer");
|
|
80008
80705
|
|
|
80009
80706
|
// src/services/computer-fleet-commands.service.ts
|
|
80010
80707
|
var COMPUTER_FLEET_USAGE = ` laze computer mine [--json] every Laze computer your agents may run on, your default one first
|
|
@@ -80278,10 +80975,10 @@ async function computer({ context, args }) {
|
|
|
80278
80975
|
}
|
|
80279
80976
|
|
|
80280
80977
|
// src/services/connect-commands.service.ts
|
|
80281
|
-
import { readFile as
|
|
80978
|
+
import { readFile as readFile22 } from "node:fs/promises";
|
|
80282
80979
|
|
|
80283
80980
|
// src/services/mcp-gateway.service.ts
|
|
80284
|
-
import { readFile as
|
|
80981
|
+
import { readFile as readFile21 } from "node:fs/promises";
|
|
80285
80982
|
import { createInterface as createInterface3 } from "node:readline";
|
|
80286
80983
|
var TURN_HEADER = "x-laze-turn";
|
|
80287
80984
|
function serveMcpGateway({
|
|
@@ -80324,7 +81021,7 @@ async function relayMcpLines({
|
|
|
80324
81021
|
const github3 = env.LAZE_GITHUB_CONNECTION;
|
|
80325
81022
|
const url2 = `${profile.url.replace(/\/+$/, "")}/api/connectors/mcp/${encodeURIComponent(profile.agentId)}${github3 ? `?github=${encodeURIComponent(github3)}` : ""}`;
|
|
80326
81023
|
const turnFile = env.LAZE_TURN_FILE;
|
|
80327
|
-
const readTurn = () =>
|
|
81024
|
+
const readTurn = () => readFile21(turnFile, "utf8").then(
|
|
80328
81025
|
(text2) => text2.trim(),
|
|
80329
81026
|
() => ""
|
|
80330
81027
|
);
|
|
@@ -80414,7 +81111,7 @@ async function turnOf({ context }) {
|
|
|
80414
81111
|
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
80415
81112
|
if (pinned) return pinned;
|
|
80416
81113
|
const file3 = env.LAZE_TURN_FILE;
|
|
80417
|
-
const turn = file3 ? await
|
|
81114
|
+
const turn = file3 ? await readFile22(file3, "utf8").then(
|
|
80418
81115
|
(text2) => text2.trim(),
|
|
80419
81116
|
() => ""
|
|
80420
81117
|
) : "";
|
|
@@ -80747,335 +81444,6 @@ var listDevices = async ({ context, args }) => {
|
|
|
80747
81444
|
}
|
|
80748
81445
|
};
|
|
80749
81446
|
|
|
80750
|
-
// src/services/vault-commands.service.ts
|
|
80751
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
80752
|
-
import { mkdir as mkdir18, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
|
|
80753
|
-
import { tmpdir as tmpdir2 } from "node:os";
|
|
80754
|
-
import { dirname as dirname18, join as join20 } from "node:path";
|
|
80755
|
-
var USAGE8 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
|
|
80756
|
-
Runs the command with the connection's values in its environment, on a Laze agent's computer,
|
|
80757
|
-
on a machine it runs on, or where a connected agent runs, with its own key.
|
|
80758
|
-
--channel <id> the conversation whose turn it runs in, when the agent answers in several`;
|
|
80759
|
-
var POLL_MS2 = 3e3;
|
|
80760
|
-
var RESTART_WAIT_MS = 12e4;
|
|
80761
|
-
var RESTART_BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 1e4];
|
|
80762
|
-
var P2562 = { name: "ECDH", namedCurve: "P-256" };
|
|
80763
|
-
var ServerGoneError = class extends Error {
|
|
80764
|
-
};
|
|
80765
|
-
function proxyOf({ env }) {
|
|
80766
|
-
const raw = env.LAZE_VAULT_PROXY || env.HTTP_PROXY || env.http_proxy;
|
|
80767
|
-
if (!raw) return null;
|
|
80768
|
-
const url2 = new URL(raw);
|
|
80769
|
-
const user = decodeURIComponent(url2.username);
|
|
80770
|
-
const password = decodeURIComponent(url2.password);
|
|
80771
|
-
return {
|
|
80772
|
-
origin: url2.origin,
|
|
80773
|
-
authorization: `Basic ${Buffer.from(`${user}:${password}`).toString("base64")}`
|
|
80774
|
-
};
|
|
80775
|
-
}
|
|
80776
|
-
function turnFileOf({
|
|
80777
|
-
env
|
|
80778
|
-
}) {
|
|
80779
|
-
return env.LAZE_TURN_FILE || void 0;
|
|
80780
|
-
}
|
|
80781
|
-
async function turnTokenOf3({
|
|
80782
|
-
env,
|
|
80783
|
-
turnFile,
|
|
80784
|
-
command = "laze vault run"
|
|
80785
|
-
}) {
|
|
80786
|
-
const pinned = env.LAZE_TURN_TOKEN?.trim();
|
|
80787
|
-
if (pinned) return pinned;
|
|
80788
|
-
if (!turnFile) throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80789
|
-
try {
|
|
80790
|
-
return (await readFile22(turnFile, "utf8")).trim();
|
|
80791
|
-
} catch {
|
|
80792
|
-
throw new CliUsageError(`${command} works only during an agent's turn`);
|
|
80793
|
-
}
|
|
80794
|
-
}
|
|
80795
|
-
function runKeyPathOf({
|
|
80796
|
-
turnFile,
|
|
80797
|
-
connection,
|
|
80798
|
-
profile = ""
|
|
80799
|
-
}) {
|
|
80800
|
-
const name3 = createHash2("sha256").update(connection).digest("hex");
|
|
80801
|
-
const base = turnFile ? dirname18(turnFile) : join20(tmpdir2(), "laze-vault", profile);
|
|
80802
|
-
return join20(base, "vault-run-keys", `${name3}.json`);
|
|
80803
|
-
}
|
|
80804
|
-
async function runKeyAt({ path }) {
|
|
80805
|
-
const saved3 = await readFile22(path, "utf8").then(
|
|
80806
|
-
(text2) => JSON.parse(text2),
|
|
80807
|
-
() => void 0
|
|
80808
|
-
);
|
|
80809
|
-
if (saved3 && typeof saved3.publicKey === "string" && saved3.privateKey) {
|
|
80810
|
-
const privateKey = await globalThis.crypto.subtle.importKey("jwk", saved3.privateKey, P2562, false, ["deriveBits"]).catch(() => void 0);
|
|
80811
|
-
if (privateKey) return { privateKey, publicKey: saved3.publicKey };
|
|
80812
|
-
}
|
|
80813
|
-
const fresh = await generateEcdhKeys();
|
|
80814
|
-
const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
|
|
80815
|
-
await mkdir18(dirname18(path), { recursive: true, mode: 448 });
|
|
80816
|
-
await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
|
|
80817
|
-
mode: 384
|
|
80818
|
-
});
|
|
80819
|
-
return fresh;
|
|
80820
|
-
}
|
|
80821
|
-
function connectionRefused(error62) {
|
|
80822
|
-
const cause = error62.cause;
|
|
80823
|
-
if (cause?.code === "ECONNREFUSED") return true;
|
|
80824
|
-
return cause?.errors?.some((inner) => inner.code === "ECONNREFUSED") ?? false;
|
|
80825
|
-
}
|
|
80826
|
-
async function sendOnce({
|
|
80827
|
-
context,
|
|
80828
|
-
url: url2,
|
|
80829
|
-
init
|
|
80830
|
-
}) {
|
|
80831
|
-
let response;
|
|
80832
|
-
try {
|
|
80833
|
-
response = await context.fetcher(url2, init);
|
|
80834
|
-
} catch (error62) {
|
|
80835
|
-
const wasRefused = connectionRefused(error62);
|
|
80836
|
-
if (init.method === "POST" && !wasRefused) throw error62;
|
|
80837
|
-
return { restarting: wasRefused ? "connection refused" : String(error62) };
|
|
80838
|
-
}
|
|
80839
|
-
if (response.status !== 502 && response.status !== 503) return { response };
|
|
80840
|
-
const code = codeOf(await response.clone().text());
|
|
80841
|
-
const neverReached = response.status === 503 && code === "vault_not_answering";
|
|
80842
|
-
if (init.method === "POST" && !neverReached) return { response };
|
|
80843
|
-
return { restarting: `status ${response.status}${code ? ` ${code}` : ""}` };
|
|
80844
|
-
}
|
|
80845
|
-
async function reach(input2) {
|
|
80846
|
-
const { context } = input2;
|
|
80847
|
-
const started = context.nowMs();
|
|
80848
|
-
for (let attempt = 0; ; attempt += 1) {
|
|
80849
|
-
const sent = await sendOnce(input2);
|
|
80850
|
-
if ("response" in sent) return sent.response;
|
|
80851
|
-
if (context.nowMs() - started >= RESTART_WAIT_MS) {
|
|
80852
|
-
throw new ServerGoneError(
|
|
80853
|
-
`laze vault: the Laze server did not come back (${sent.restarting})`
|
|
80854
|
-
);
|
|
80855
|
-
}
|
|
80856
|
-
if (attempt === 0) {
|
|
80857
|
-
context.err(
|
|
80858
|
-
`laze vault: the Laze server is not answering (${sent.restarting}), probably restarting; waiting up to 2 min...
|
|
80859
|
-
`
|
|
80860
|
-
);
|
|
80861
|
-
}
|
|
80862
|
-
await context.sleep(RESTART_BACKOFF_MS[Math.min(attempt, RESTART_BACKOFF_MS.length - 1)] ?? 0);
|
|
80863
|
-
}
|
|
80864
|
-
}
|
|
80865
|
-
function codeOf(text2) {
|
|
80866
|
-
return /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1];
|
|
80867
|
-
}
|
|
80868
|
-
async function releaseOf({ response }) {
|
|
80869
|
-
const text2 = await response.text();
|
|
80870
|
-
if (!response.ok) {
|
|
80871
|
-
return {
|
|
80872
|
-
outcome: "deny",
|
|
80873
|
-
exitCode: 1,
|
|
80874
|
-
message: `laze vault: the release was refused (${codeOf(text2) ?? `status ${response.status}`})`
|
|
80875
|
-
};
|
|
80876
|
-
}
|
|
80877
|
-
return JSON.parse(text2);
|
|
80878
|
-
}
|
|
80879
|
-
async function envOf({
|
|
80880
|
-
release: release2,
|
|
80881
|
-
run: run4
|
|
80882
|
-
}) {
|
|
80883
|
-
if (!release2.sealed) return release2.env;
|
|
80884
|
-
const sealed = await openRunRelease({
|
|
80885
|
-
release: release2.sealed,
|
|
80886
|
-
runPrivateKey: run4.privateKey,
|
|
80887
|
-
runPublicKey: run4.publicKey,
|
|
80888
|
-
requestId: release2.sealed.requestId
|
|
80889
|
-
});
|
|
80890
|
-
return { ...release2.env, ...sealed };
|
|
80891
|
-
}
|
|
80892
|
-
function deadlineOf({ args, nowMs }) {
|
|
80893
|
-
const wait = flagText({ args, name: "wait" }) || (args.flags.wait === true ? args.words[3] : "");
|
|
80894
|
-
if (!wait) return Infinity;
|
|
80895
|
-
if (!(Number(wait) >= 0)) throw new CliUsageError(`--wait takes a number of seconds
|
|
80896
|
-
${USAGE8}`);
|
|
80897
|
-
return nowMs + Number(wait) * 1e3;
|
|
80898
|
-
}
|
|
80899
|
-
async function untilAnswered({
|
|
80900
|
-
context,
|
|
80901
|
-
first,
|
|
80902
|
-
next,
|
|
80903
|
-
deadline
|
|
80904
|
-
}) {
|
|
80905
|
-
let release2 = first;
|
|
80906
|
-
while (release2.outcome === "ask") {
|
|
80907
|
-
if (context.nowMs() + POLL_MS2 > deadline) {
|
|
80908
|
-
context.err(`${release2.message}. Not approved yet; ask again later.
|
|
80909
|
-
`);
|
|
80910
|
-
return "capped";
|
|
80911
|
-
}
|
|
80912
|
-
if (release2 === first) {
|
|
80913
|
-
context.err(`${release2.message}. Waiting for an answer (cards expire after 12 hours)...
|
|
80914
|
-
`);
|
|
80915
|
-
}
|
|
80916
|
-
await context.sleep(POLL_MS2);
|
|
80917
|
-
release2 = await next(release2.requestId);
|
|
80918
|
-
}
|
|
80919
|
-
return release2;
|
|
80920
|
-
}
|
|
80921
|
-
function leaseHolds({
|
|
80922
|
-
release: release2,
|
|
80923
|
-
nowMs
|
|
80924
|
-
}) {
|
|
80925
|
-
const ends = release2.sealed?.leaseEndsAt;
|
|
80926
|
-
return ends !== void 0 && Temporal3.Instant.from(ends).epochMilliseconds > nowMs;
|
|
80927
|
-
}
|
|
80928
|
-
async function vaultRelease({
|
|
80929
|
-
context,
|
|
80930
|
-
args,
|
|
80931
|
-
connection,
|
|
80932
|
-
reason,
|
|
80933
|
-
command
|
|
80934
|
-
}) {
|
|
80935
|
-
const deadline = deadlineOf({ args, nowMs: context.nowMs() });
|
|
80936
|
-
const env = context.environment.inherited;
|
|
80937
|
-
const proxy = proxyOf({ env });
|
|
80938
|
-
if (!proxy) return keyRelease({ context, args, connection, reason, command, deadline });
|
|
80939
|
-
const turnFile = turnFileOf({ env });
|
|
80940
|
-
const headers = {
|
|
80941
|
-
"proxy-authorization": proxy.authorization,
|
|
80942
|
-
"x-laze-turn": await turnTokenOf3({ env, turnFile })
|
|
80943
|
-
};
|
|
80944
|
-
const keyPath = runKeyPathOf({ turnFile, connection });
|
|
80945
|
-
const run4 = await runKeyAt({ path: keyPath });
|
|
80946
|
-
const body = JSON.stringify({ connection, reason, command, recipient: run4.publicKey });
|
|
80947
|
-
let release2;
|
|
80948
|
-
try {
|
|
80949
|
-
const first = await releaseOf({
|
|
80950
|
-
response: await reach({
|
|
80951
|
-
context,
|
|
80952
|
-
url: `${proxy.origin}/vault/release`,
|
|
80953
|
-
init: { method: "POST", headers: { ...headers, "content-type": "application/json" }, body }
|
|
80954
|
-
})
|
|
80955
|
-
});
|
|
80956
|
-
const next = async (requestId) => releaseOf({
|
|
80957
|
-
response: await reach({
|
|
80958
|
-
context,
|
|
80959
|
-
url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
|
|
80960
|
-
init: { method: "GET", headers }
|
|
80961
|
-
})
|
|
80962
|
-
});
|
|
80963
|
-
release2 = await untilAnswered({ context, first, next, deadline });
|
|
80964
|
-
} catch (error62) {
|
|
80965
|
-
if (!(error62 instanceof ServerGoneError)) throw error62;
|
|
80966
|
-
context.err(`${error62.message}. Run the command again to keep waiting.
|
|
80967
|
-
`);
|
|
80968
|
-
return { exitCode: 75 };
|
|
80969
|
-
}
|
|
80970
|
-
return settled({ context, release: release2, run: run4, keyPath });
|
|
80971
|
-
}
|
|
80972
|
-
async function settled({
|
|
80973
|
-
context,
|
|
80974
|
-
release: release2,
|
|
80975
|
-
run: run4,
|
|
80976
|
-
keyPath
|
|
80977
|
-
}) {
|
|
80978
|
-
if (release2 === "capped") return { exitCode: 75 };
|
|
80979
|
-
if (release2.outcome === "deny") {
|
|
80980
|
-
await rm10(keyPath, { force: true });
|
|
80981
|
-
context.err(`${release2.message}
|
|
80982
|
-
`);
|
|
80983
|
-
return { exitCode: release2.exitCode || 1 };
|
|
80984
|
-
}
|
|
80985
|
-
const values = await envOf({ release: release2, run: run4 });
|
|
80986
|
-
if (!leaseHolds({ release: release2, nowMs: context.nowMs() })) await rm10(keyPath, { force: true });
|
|
80987
|
-
if (release2.message) context.err(`${release2.message}
|
|
80988
|
-
`);
|
|
80989
|
-
return { env: values };
|
|
80990
|
-
}
|
|
80991
|
-
function refusedRelease(error62) {
|
|
80992
|
-
if (!(error62 instanceof LazeApiError)) throw error62;
|
|
80993
|
-
return {
|
|
80994
|
-
outcome: "deny",
|
|
80995
|
-
exitCode: 1,
|
|
80996
|
-
message: `laze vault: the release was refused: ${error62.message} (${error62.code})`
|
|
80997
|
-
};
|
|
80998
|
-
}
|
|
80999
|
-
async function keyRelease({
|
|
81000
|
-
context,
|
|
81001
|
-
args,
|
|
81002
|
-
connection,
|
|
81003
|
-
reason,
|
|
81004
|
-
command,
|
|
81005
|
-
deadline
|
|
81006
|
-
}) {
|
|
81007
|
-
const where = new CliUsageError(
|
|
81008
|
-
"laze vault run works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent"
|
|
81009
|
-
);
|
|
81010
|
-
const signed2 = await signedIn({ context, args }).catch(() => null);
|
|
81011
|
-
if (signed2?.profile.kind !== "agent") throw where;
|
|
81012
|
-
const { client, name: name3 } = signed2;
|
|
81013
|
-
const channelId = flagText({ args, name: "channel" }) || null;
|
|
81014
|
-
const keyPath = runKeyPathOf({ turnFile: void 0, connection, profile: name3 });
|
|
81015
|
-
const run4 = await runKeyAt({ path: keyPath });
|
|
81016
|
-
const first = await client.post("/api/agents/me/vault/release", {
|
|
81017
|
-
connection,
|
|
81018
|
-
reason,
|
|
81019
|
-
command,
|
|
81020
|
-
recipient: run4.publicKey,
|
|
81021
|
-
channelId
|
|
81022
|
-
}).catch(refusedRelease);
|
|
81023
|
-
const next = (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease);
|
|
81024
|
-
const release2 = await untilAnswered({ context, first, next, deadline });
|
|
81025
|
-
return settled({ context, release: release2, run: run4, keyPath });
|
|
81026
|
-
}
|
|
81027
|
-
async function vaultRun({
|
|
81028
|
-
context,
|
|
81029
|
-
args
|
|
81030
|
-
}) {
|
|
81031
|
-
const connection = args.words[2];
|
|
81032
|
-
const reason = flagText({ args, name: "reason" });
|
|
81033
|
-
if (!connection || args.rest.length === 0) throw new CliUsageError(USAGE8);
|
|
81034
|
-
if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
|
|
81035
|
-
${USAGE8}`);
|
|
81036
|
-
const foreign = commandReferenceNames({ command: args.rest }).find(
|
|
81037
|
-
(name3) => vaultReferenceConnectionName({ name: name3 }) !== connection
|
|
81038
|
-
);
|
|
81039
|
-
if (foreign !== void 0) {
|
|
81040
|
-
const named = vaultReferenceConnectionName({ name: foreign });
|
|
81041
|
-
context.err(
|
|
81042
|
-
`laze vault: the command names {{vault:${foreign}}}, but this run releases only ${connection}, not ${named}. Nothing was asked and the command did not run.
|
|
81043
|
-
`
|
|
81044
|
-
);
|
|
81045
|
-
return 1;
|
|
81046
|
-
}
|
|
81047
|
-
const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
|
|
81048
|
-
if ("exitCode" in released) return released.exitCode;
|
|
81049
|
-
const prepared = preparedCommand({
|
|
81050
|
-
command: args.rest,
|
|
81051
|
-
released: /* @__PURE__ */ new Map([[connection, released.env]])
|
|
81052
|
-
});
|
|
81053
|
-
if ("refusal" in prepared) {
|
|
81054
|
-
context.err(`${prepared.refusal}
|
|
81055
|
-
`);
|
|
81056
|
-
return 1;
|
|
81057
|
-
}
|
|
81058
|
-
return context.runCommand({ command: prepared.command, env: released.env });
|
|
81059
|
-
}
|
|
81060
|
-
function preparedCommand({
|
|
81061
|
-
command,
|
|
81062
|
-
released
|
|
81063
|
-
}) {
|
|
81064
|
-
for (const [name3, fields] of released) {
|
|
81065
|
-
const [problem] = unusableFieldProblems({ fields });
|
|
81066
|
-
if (problem !== void 0) {
|
|
81067
|
-
return {
|
|
81068
|
-
refusal: `laze vault: ${name3}: ${problem}, so the command did not run. Ask its owner to save the real value on the vault page.`
|
|
81069
|
-
};
|
|
81070
|
-
}
|
|
81071
|
-
}
|
|
81072
|
-
const filled = fillCommandReferences({ command, released });
|
|
81073
|
-
if ("refusal" in filled) {
|
|
81074
|
-
return { refusal: `laze vault: ${filled.refusal}. The command did not run.` };
|
|
81075
|
-
}
|
|
81076
|
-
return filled;
|
|
81077
|
-
}
|
|
81078
|
-
|
|
81079
81447
|
// src/services/vault-share-commands.service.ts
|
|
81080
81448
|
var SHARE_USAGE2 = "Usage: laze vault share <connection> --with <email|userId> [--for 1h]";
|
|
81081
81449
|
var WAITING_LINE = "It waits for the owner's approval with a passkey or Face ID, in Settings > Vault.";
|
|
@@ -81094,7 +81462,7 @@ async function inTurn({
|
|
|
81094
81462
|
command
|
|
81095
81463
|
}) {
|
|
81096
81464
|
const env = context.environment.inherited;
|
|
81097
|
-
const turn = await
|
|
81465
|
+
const turn = await turnTokenOf2({ env, turnFile: turnFileOf({ env }), command });
|
|
81098
81466
|
return client.withHeaders({ "x-laze-turn": turn });
|
|
81099
81467
|
}
|
|
81100
81468
|
function printShare({ context, grant }) {
|
|
@@ -81778,16 +82146,16 @@ function dndLine({ pausedUntil }) {
|
|
|
81778
82146
|
}
|
|
81779
82147
|
|
|
81780
82148
|
// src/services/dnd-commands.service.ts
|
|
81781
|
-
var
|
|
82149
|
+
var USAGE8 = "Usage: laze dnd 30m|1h|2h|until <HH:mm|ISO time> [--tz <zone>], laze dnd off";
|
|
81782
82150
|
async function dnd({ context, args }) {
|
|
81783
82151
|
const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
81784
82152
|
let input2;
|
|
81785
82153
|
try {
|
|
81786
82154
|
input2 = dndInputOf({ words: args.words.slice(1), now: nowInstant(), timeZone });
|
|
81787
82155
|
} catch {
|
|
81788
|
-
throw new CliUsageError(
|
|
82156
|
+
throw new CliUsageError(USAGE8);
|
|
81789
82157
|
}
|
|
81790
|
-
if (!input2) throw new CliUsageError(
|
|
82158
|
+
if (!input2) throw new CliUsageError(USAGE8);
|
|
81791
82159
|
const { client } = await signedIn({ context, args });
|
|
81792
82160
|
const settings2 = await client.post(
|
|
81793
82161
|
"/api/agents/me/notifications/snooze",
|
|
@@ -81806,8 +82174,8 @@ var DOMAINS_USAGE = `Usage:
|
|
|
81806
82174
|
var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
|
|
81807
82175
|
`);
|
|
81808
82176
|
function printDomain(context, row) {
|
|
81809
|
-
const
|
|
81810
|
-
context.out(`${row.domain} ${
|
|
82177
|
+
const join26 = row.autoJoin ? "auto-join on" : "auto-join off";
|
|
82178
|
+
context.out(`${row.domain} ${join26}${row.enforced ? " single sign-on enforced" : ""}
|
|
81811
82179
|
`);
|
|
81812
82180
|
}
|
|
81813
82181
|
async function list4({ context, args }) {
|
|
@@ -82036,6 +82404,8 @@ var feedApprovalSchemaDefinition = external_exports.object({
|
|
|
82036
82404
|
why: external_exports.string(),
|
|
82037
82405
|
/** The longest lease Allow for this agent may give; null offers only once and deny. */
|
|
82038
82406
|
maxLeaseSeconds: external_exports.number().int().positive().nullable(),
|
|
82407
|
+
/** A vault card whose Allow covers the rest of the agent's turn: "Allow for this task". */
|
|
82408
|
+
coversTask: external_exports.boolean().optional(),
|
|
82039
82409
|
/** The card's timeout; a publish waits without one. */
|
|
82040
82410
|
expiresAt: external_exports.iso.datetime().nullable(),
|
|
82041
82411
|
state: feedApprovalStateSchema,
|
|
@@ -82612,7 +82982,7 @@ async function feedAttachmentIdsOf({
|
|
|
82612
82982
|
}
|
|
82613
82983
|
|
|
82614
82984
|
// src/services/feed-commands.service.ts
|
|
82615
|
-
var
|
|
82985
|
+
var USAGE9 = `Usage:
|
|
82616
82986
|
laze feed post <title> [--channel <channel>] [--tag <tag>] [--summary <line>]
|
|
82617
82987
|
[--draft <text|@file>] [--draft-header "To: ...\\nRe: ..."]
|
|
82618
82988
|
[--metric <json|@file.json> | --table <csv|@file.csv>]
|
|
@@ -82683,7 +83053,7 @@ function printItem({
|
|
|
82683
83053
|
}
|
|
82684
83054
|
async function feedPost({ context, args }) {
|
|
82685
83055
|
const title = args.words.slice(2).join(" ").trim();
|
|
82686
|
-
if (!title) throw new CliUsageError(
|
|
83056
|
+
if (!title) throw new CliUsageError(USAGE9);
|
|
82687
83057
|
const flags2 = flagsOf(args);
|
|
82688
83058
|
const { client } = await signedIn({ context, args });
|
|
82689
83059
|
const channel = flagText({ args, name: "channel" });
|
|
@@ -82705,7 +83075,7 @@ async function feedPost({ context, args }) {
|
|
|
82705
83075
|
}
|
|
82706
83076
|
async function feedUpdate({ context, args }) {
|
|
82707
83077
|
const itemId = args.words[2];
|
|
82708
|
-
if (!itemId) throw new CliUsageError(
|
|
83078
|
+
if (!itemId) throw new CliUsageError(USAGE9);
|
|
82709
83079
|
const flags2 = flagsOf(args);
|
|
82710
83080
|
const { client } = await signedIn({ context, args });
|
|
82711
83081
|
const body = await bodyOf2({ context, flags: flags2 });
|
|
@@ -82721,7 +83091,7 @@ async function feedUpdate({ context, args }) {
|
|
|
82721
83091
|
async function feedReply({ context, args }) {
|
|
82722
83092
|
const itemId = args.words[2];
|
|
82723
83093
|
const text2 = args.words.slice(3).join(" ").trim();
|
|
82724
|
-
if (!itemId || !text2) throw new CliUsageError(
|
|
83094
|
+
if (!itemId || !text2) throw new CliUsageError(USAGE9);
|
|
82725
83095
|
const { client } = await signedIn({ context, args });
|
|
82726
83096
|
const replied = await client.post("/api/feed/items/reply", {
|
|
82727
83097
|
itemId,
|
|
@@ -82734,7 +83104,7 @@ async function feedReply({ context, args }) {
|
|
|
82734
83104
|
}
|
|
82735
83105
|
async function feedRead({ context, args }) {
|
|
82736
83106
|
const itemId = args.words[2];
|
|
82737
|
-
if (!itemId) throw new CliUsageError(
|
|
83107
|
+
if (!itemId) throw new CliUsageError(USAGE9);
|
|
82738
83108
|
const { client } = await signedIn({ context, args });
|
|
82739
83109
|
const read3 = await client.post("/api/feed/items/read", { itemId });
|
|
82740
83110
|
printItem({ context, args, item: read3 });
|
|
@@ -82753,7 +83123,7 @@ async function feedClose({ context, args }) {
|
|
|
82753
83123
|
const itemId = args.words[2];
|
|
82754
83124
|
const loop = flagText({ args, name: "loop" });
|
|
82755
83125
|
const note = flagText({ args, name: "note" });
|
|
82756
|
-
if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(
|
|
83126
|
+
if (!note || Boolean(itemId) === Boolean(loop)) throw new CliUsageError(USAGE9);
|
|
82757
83127
|
const { client } = await signedIn({ context, args });
|
|
82758
83128
|
const closed = await client.post("/api/feed/items/close", {
|
|
82759
83129
|
...itemId ? { itemId } : { loop },
|
|
@@ -82779,7 +83149,7 @@ async function feedLoops({ context, args }) {
|
|
|
82779
83149
|
}
|
|
82780
83150
|
async function feedGroupSummary({ context, args }) {
|
|
82781
83151
|
const group = args.words.slice(2).join(" ").trim();
|
|
82782
|
-
if (!group) throw new CliUsageError(
|
|
83152
|
+
if (!group) throw new CliUsageError(USAGE9);
|
|
82783
83153
|
const { client } = await signedIn({ context, args });
|
|
82784
83154
|
const pointer = await client.post("/api/feed/group-summary", { group });
|
|
82785
83155
|
if (args.flags.json) return context.out(`${JSON.stringify(pointer, null, 2)}
|
|
@@ -82859,7 +83229,7 @@ async function feedDecisions({ context, args }) {
|
|
|
82859
83229
|
}
|
|
82860
83230
|
async function feedAct({ context, args }) {
|
|
82861
83231
|
const [itemId, actionId] = [args.words[2], args.words[3]];
|
|
82862
|
-
if (!itemId || !actionId) throw new CliUsageError(
|
|
83232
|
+
if (!itemId || !actionId) throw new CliUsageError(USAGE9);
|
|
82863
83233
|
const draft = await textFlag({ context, args, name: "draft" });
|
|
82864
83234
|
const { client } = await signedIn({ context, args });
|
|
82865
83235
|
const item = await client.post("/api/feed/mine/act", {
|
|
@@ -82872,7 +83242,7 @@ async function feedAct({ context, args }) {
|
|
|
82872
83242
|
async function feedComment({ context, args }) {
|
|
82873
83243
|
const itemId = args.words[2];
|
|
82874
83244
|
const text2 = args.words.slice(3).join(" ").trim();
|
|
82875
|
-
if (!itemId || !text2) throw new CliUsageError(
|
|
83245
|
+
if (!itemId || !text2) throw new CliUsageError(USAGE9);
|
|
82876
83246
|
const draft = await textFlag({ context, args, name: "draft" });
|
|
82877
83247
|
const { client } = await signedIn({ context, args });
|
|
82878
83248
|
const item = await client.post("/api/feed/mine/comment", {
|
|
@@ -82886,7 +83256,7 @@ async function feedComment({ context, args }) {
|
|
|
82886
83256
|
function moveItem(path) {
|
|
82887
83257
|
return async ({ context, args }) => {
|
|
82888
83258
|
const itemId = args.words[2];
|
|
82889
|
-
if (!itemId) throw new CliUsageError(
|
|
83259
|
+
if (!itemId) throw new CliUsageError(USAGE9);
|
|
82890
83260
|
const { client } = await signedIn({ context, args });
|
|
82891
83261
|
const item = await client.post(`/api/feed/mine/${path}`, { itemId });
|
|
82892
83262
|
printMoved({ context, args, item });
|
|
@@ -82895,14 +83265,14 @@ function moveItem(path) {
|
|
|
82895
83265
|
async function feedSnooze({ context, args }) {
|
|
82896
83266
|
const itemId = args.words[2];
|
|
82897
83267
|
const until = flagText({ args, name: "until" });
|
|
82898
|
-
if (!itemId || !until) throw new CliUsageError(
|
|
83268
|
+
if (!itemId || !until) throw new CliUsageError(USAGE9);
|
|
82899
83269
|
const { client } = await signedIn({ context, args });
|
|
82900
83270
|
const item = await client.post("/api/feed/mine/snooze", { itemId, until });
|
|
82901
83271
|
printMoved({ context, args, item });
|
|
82902
83272
|
}
|
|
82903
83273
|
async function feedChannel({ context, args }) {
|
|
82904
83274
|
const channelId = args.words[2];
|
|
82905
|
-
if (!channelId) throw new CliUsageError(
|
|
83275
|
+
if (!channelId) throw new CliUsageError(USAGE9);
|
|
82906
83276
|
const { client } = await signedIn({ context, args });
|
|
82907
83277
|
const items = await client.post("/api/feed/channel", { channelId });
|
|
82908
83278
|
if (args.flags.json) return context.out(`${JSON.stringify(items, null, 2)}
|
|
@@ -82933,7 +83303,7 @@ var FEED_COMMANDS = {
|
|
|
82933
83303
|
async function feed({ context, args }) {
|
|
82934
83304
|
const name3 = args.words[1] ?? "";
|
|
82935
83305
|
const command = Object.hasOwn(FEED_COMMANDS, name3) ? FEED_COMMANDS[name3] : void 0;
|
|
82936
|
-
if (!command) throw new CliUsageError(
|
|
83306
|
+
if (!command) throw new CliUsageError(USAGE9);
|
|
82937
83307
|
await command({ context, args });
|
|
82938
83308
|
}
|
|
82939
83309
|
|
|
@@ -83429,12 +83799,12 @@ async function ip({ context, args }) {
|
|
|
83429
83799
|
}
|
|
83430
83800
|
|
|
83431
83801
|
// src/services/join-commands.service.ts
|
|
83432
|
-
import { mkdir as
|
|
83433
|
-
import { dirname as dirname19, join as
|
|
83802
|
+
import { mkdir as mkdir20, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile20 } from "node:fs/promises";
|
|
83803
|
+
import { dirname as dirname19, join as join22 } from "node:path";
|
|
83434
83804
|
var DEFAULT_WAIT_SECONDS2 = 100;
|
|
83435
83805
|
var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
|
|
83436
83806
|
function pendingPathOf({ context }) {
|
|
83437
|
-
return
|
|
83807
|
+
return join22(dirname19(context.environment.configPath), "join", "pending.json");
|
|
83438
83808
|
}
|
|
83439
83809
|
async function readPending({
|
|
83440
83810
|
context,
|
|
@@ -83451,9 +83821,9 @@ async function readPending({
|
|
|
83451
83821
|
}
|
|
83452
83822
|
async function keepPending({ context, pending }) {
|
|
83453
83823
|
const path = pendingPathOf({ context });
|
|
83454
|
-
await
|
|
83824
|
+
await mkdir20(dirname19(path), { recursive: true, mode: 448 });
|
|
83455
83825
|
const temporary = `${path}.${process.pid}.tmp`;
|
|
83456
|
-
await
|
|
83826
|
+
await writeFile20(temporary, JSON.stringify(pending), { mode: 384 });
|
|
83457
83827
|
await rename5(temporary, path);
|
|
83458
83828
|
}
|
|
83459
83829
|
async function dropPending({ context }) {
|
|
@@ -83770,7 +84140,7 @@ function machineAccessCommand(name3) {
|
|
|
83770
84140
|
}
|
|
83771
84141
|
|
|
83772
84142
|
// src/services/machine-commands.service.ts
|
|
83773
|
-
var
|
|
84143
|
+
var USAGE10 = [
|
|
83774
84144
|
"Usage: laze machine connect <name> the command to run on your own machine (people)",
|
|
83775
84145
|
" laze machine connect <name> --again a new command for a machine you connected; the old code stops working",
|
|
83776
84146
|
" laze machine connect <name> --ssh <user>@<host>[:port] a machine that cannot run the connector, over SSH (people)",
|
|
@@ -83816,7 +84186,7 @@ function listLine(machine2) {
|
|
|
83816
84186
|
var EXEC_ENV_MAX = 32;
|
|
83817
84187
|
function machineArg2({ args }) {
|
|
83818
84188
|
const machine2 = args.words[2];
|
|
83819
|
-
if (!machine2) throw new CliUsageError(
|
|
84189
|
+
if (!machine2) throw new CliUsageError(USAGE10);
|
|
83820
84190
|
return machine2;
|
|
83821
84191
|
}
|
|
83822
84192
|
async function connect2({ context, args }) {
|
|
@@ -83842,7 +84212,7 @@ async function connectSsh({
|
|
|
83842
84212
|
}) {
|
|
83843
84213
|
const ssh = flagText({ args, name: "ssh" });
|
|
83844
84214
|
if (!ssh) throw new CliUsageError(`--ssh takes <user>@<host>[:port]
|
|
83845
|
-
${
|
|
84215
|
+
${USAGE10}`);
|
|
83846
84216
|
const client = await computeClient({ context, args });
|
|
83847
84217
|
const made = await client.post(COMPUTE_REST_PATHS.connectSsh, {
|
|
83848
84218
|
name: name3,
|
|
@@ -83918,11 +84288,11 @@ async function exec({
|
|
|
83918
84288
|
}) {
|
|
83919
84289
|
const machine2 = machineArg2({ args });
|
|
83920
84290
|
const command = commandText({ rest: args.rest });
|
|
83921
|
-
if (!command.trim()) throw new CliUsageError(
|
|
84291
|
+
if (!command.trim()) throw new CliUsageError(USAGE10);
|
|
83922
84292
|
const timeout = flagText({ args, name: "timeout" });
|
|
83923
84293
|
if (timeout && !(Number(timeout) >= 1))
|
|
83924
84294
|
throw new CliUsageError(`--timeout takes a number of seconds
|
|
83925
|
-
${
|
|
84295
|
+
${USAGE10}`);
|
|
83926
84296
|
const released = await vaultEnv({ context, args });
|
|
83927
84297
|
if ("exitCode" in released) return released.exitCode;
|
|
83928
84298
|
const client = await computeClient({ context, args });
|
|
@@ -83950,11 +84320,11 @@ async function vaultEnv({
|
|
|
83950
84320
|
const connections = args.lists.vault ?? [];
|
|
83951
84321
|
if (args.flags.vault === true)
|
|
83952
84322
|
throw new CliUsageError(`--vault takes a connection name
|
|
83953
|
-
${
|
|
84323
|
+
${USAGE10}`);
|
|
83954
84324
|
if (connections.length === 0) return {};
|
|
83955
84325
|
const reason = flagText({ args, name: "reason" });
|
|
83956
84326
|
if (!reason) throw new CliUsageError(`Say why with --reason "<one plain sentence>"
|
|
83957
|
-
${
|
|
84327
|
+
${USAGE10}`);
|
|
83958
84328
|
const env = {};
|
|
83959
84329
|
for (const connection of new Set(connections)) {
|
|
83960
84330
|
const released = await vaultRelease({ context, args, connection, reason, command: args.rest });
|
|
@@ -83974,11 +84344,11 @@ ${USAGE11}`);
|
|
|
83974
84344
|
async function host({ context, args }) {
|
|
83975
84345
|
const machineName = args.words[2];
|
|
83976
84346
|
const agent2 = args.words[3];
|
|
83977
|
-
if (!machineName || !agent2) throw new CliUsageError(
|
|
84347
|
+
if (!machineName || !agent2) throw new CliUsageError(USAGE10);
|
|
83978
84348
|
const whenOffline = flagText({ args, name: "when-offline", fallback: "wait" });
|
|
83979
84349
|
if (whenOffline !== "wait" && whenOffline !== "computer" && whenOffline !== "sandbox")
|
|
83980
84350
|
throw new CliUsageError(`--when-offline takes wait or computer
|
|
83981
|
-
${
|
|
84351
|
+
${USAGE10}`);
|
|
83982
84352
|
const client = await computeClient({ context, args });
|
|
83983
84353
|
const machine2 = await client.post(COMPUTE_REST_PATHS.host, {
|
|
83984
84354
|
machine: machineName,
|
|
@@ -83995,7 +84365,7 @@ ${USAGE11}`);
|
|
|
83995
84365
|
}
|
|
83996
84366
|
async function unhost({ context, args }) {
|
|
83997
84367
|
const agent2 = args.words[2];
|
|
83998
|
-
if (!agent2) throw new CliUsageError(
|
|
84368
|
+
if (!agent2) throw new CliUsageError(USAGE10);
|
|
83999
84369
|
const client = await computeClient({ context, args });
|
|
84000
84370
|
const done = await client.post(COMPUTE_REST_PATHS.unhost, { agent: agent2 });
|
|
84001
84371
|
if (args.flags.json) return context.out(`${JSON.stringify(done, null, 2)}
|
|
@@ -84032,7 +84402,7 @@ async function machine({ context, args }) {
|
|
|
84032
84402
|
if (command === "unhost") return unhost({ context, args });
|
|
84033
84403
|
const access = machineAccessCommand(command);
|
|
84034
84404
|
if (access) return access({ context, args });
|
|
84035
|
-
throw new CliUsageError(
|
|
84405
|
+
throw new CliUsageError(USAGE10);
|
|
84036
84406
|
}
|
|
84037
84407
|
|
|
84038
84408
|
// src/services/mcp-server.service.ts
|
|
@@ -84271,7 +84641,7 @@ async function serveMcp({
|
|
|
84271
84641
|
}
|
|
84272
84642
|
|
|
84273
84643
|
// src/services/mount-files.service.ts
|
|
84274
|
-
import { mkdir as
|
|
84644
|
+
import { mkdir as mkdir21, readFile as readFile30, rm as rm12, writeFile as writeFile21 } from "node:fs/promises";
|
|
84275
84645
|
import { dirname as dirname20, relative as relative5, resolve as resolve11 } from "node:path";
|
|
84276
84646
|
async function textArgument({
|
|
84277
84647
|
context,
|
|
@@ -84292,20 +84662,20 @@ async function writeMount({
|
|
|
84292
84662
|
}) {
|
|
84293
84663
|
const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
|
|
84294
84664
|
await rm12(root, { recursive: true, force: true });
|
|
84295
|
-
await
|
|
84665
|
+
await mkdir21(root, { recursive: true });
|
|
84296
84666
|
for (const file3 of files2) {
|
|
84297
84667
|
const target = resolve11(root, file3.path);
|
|
84298
84668
|
const inside = relative5(root, target);
|
|
84299
84669
|
if (!inside || inside.startsWith(".."))
|
|
84300
84670
|
throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
|
|
84301
|
-
await
|
|
84302
|
-
await
|
|
84671
|
+
await mkdir21(dirname20(target), { recursive: true });
|
|
84672
|
+
await writeFile21(target, file3.content);
|
|
84303
84673
|
}
|
|
84304
84674
|
return root;
|
|
84305
84675
|
}
|
|
84306
84676
|
|
|
84307
84677
|
// src/services/memory-commands.service.ts
|
|
84308
|
-
var
|
|
84678
|
+
var USAGE11 = `Usage:
|
|
84309
84679
|
laze memory get SOUL.md|AGENTS.md|MEMORY.md [--channel <channel>]
|
|
84310
84680
|
laze memory set <file> <text|@file|-> [--channel <channel>] [--base <version>]
|
|
84311
84681
|
laze memory append MEMORY.md <text|@file|-> [--channel <channel>]
|
|
@@ -84317,7 +84687,7 @@ MEMORY.md is the file of the turn's channel (LAZE_CHANNEL), or of --channel when
|
|
|
84317
84687
|
var FILES = /* @__PURE__ */ new Set(["SOUL.md", "AGENTS.md", "MEMORY.md"]);
|
|
84318
84688
|
function fileRef({ context, args }) {
|
|
84319
84689
|
const file3 = args.words[2] ?? "";
|
|
84320
|
-
if (!FILES.has(file3)) throw new CliUsageError(
|
|
84690
|
+
if (!FILES.has(file3)) throw new CliUsageError(USAGE11);
|
|
84321
84691
|
const channel = turnChannel({ context, args });
|
|
84322
84692
|
return { file: file3, ...channel ? { channel } : {} };
|
|
84323
84693
|
}
|
|
@@ -84356,7 +84726,7 @@ async function memoryHistory({ context, args }) {
|
|
|
84356
84726
|
async function memorySet({ context, args }) {
|
|
84357
84727
|
const ref = fileRef({ context, args });
|
|
84358
84728
|
const value = args.words.slice(3).join(" ");
|
|
84359
|
-
if (!value) throw new CliUsageError(
|
|
84729
|
+
if (!value) throw new CliUsageError(USAGE11);
|
|
84360
84730
|
const content = await textArgument({ context, value });
|
|
84361
84731
|
const base = args.flags.base;
|
|
84362
84732
|
const { client } = await signedIn({ context, args });
|
|
@@ -84372,7 +84742,7 @@ async function memorySet({ context, args }) {
|
|
|
84372
84742
|
async function memoryAppend({ context, args }) {
|
|
84373
84743
|
const ref = fileRef({ context, args });
|
|
84374
84744
|
const value = args.words.slice(3).join(" ");
|
|
84375
|
-
if (!value) throw new CliUsageError(
|
|
84745
|
+
if (!value) throw new CliUsageError(USAGE11);
|
|
84376
84746
|
const text2 = await textArgument({ context, value });
|
|
84377
84747
|
const { client } = await signedIn({ context, args });
|
|
84378
84748
|
const saved3 = await client.post("/api/memory/append", { ...ref, text: text2 });
|
|
@@ -84382,7 +84752,7 @@ async function memoryAppend({ context, args }) {
|
|
|
84382
84752
|
}
|
|
84383
84753
|
async function memorySearch({ context, args }) {
|
|
84384
84754
|
const query = args.words.slice(2).join(" ").trim();
|
|
84385
|
-
if (!query) throw new CliUsageError(
|
|
84755
|
+
if (!query) throw new CliUsageError(USAGE11);
|
|
84386
84756
|
const { client } = await signedIn({ context, args });
|
|
84387
84757
|
const hits = await client.post("/api/memory/search", { query });
|
|
84388
84758
|
if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
|
|
@@ -84416,13 +84786,13 @@ var MEMORY_COMMANDS = {
|
|
|
84416
84786
|
async function memory({ context, args }) {
|
|
84417
84787
|
const name3 = args.words[1] ?? "";
|
|
84418
84788
|
const command = Object.hasOwn(MEMORY_COMMANDS, name3) ? MEMORY_COMMANDS[name3] : void 0;
|
|
84419
|
-
if (!command) throw new CliUsageError(
|
|
84789
|
+
if (!command) throw new CliUsageError(USAGE11);
|
|
84420
84790
|
await command({ context, args });
|
|
84421
84791
|
}
|
|
84422
84792
|
|
|
84423
84793
|
// src/services/models-commands.service.ts
|
|
84424
84794
|
var WINDOWS = ["day", "week", "month"];
|
|
84425
|
-
var
|
|
84795
|
+
var USAGE12 = `Usage:
|
|
84426
84796
|
laze models policy whether Laze models are on, the default budget and the cap
|
|
84427
84797
|
laze models set-policy [on|off] [--default-day <usd|none>] [--cap-day <usd|none>] ... (admins)
|
|
84428
84798
|
--default-week, --default-month, --cap-week and --cap-month set the other windows
|
|
@@ -84447,7 +84817,7 @@ function limitsFrom({
|
|
|
84447
84817
|
const value = text2 === "none" ? null : Number(text2);
|
|
84448
84818
|
if (value !== null && (!Number.isFinite(value) || value < 0))
|
|
84449
84819
|
throw new CliUsageError(`--${prefix}${window2} takes an amount in USD or none.
|
|
84450
|
-
${
|
|
84820
|
+
${USAGE12}`);
|
|
84451
84821
|
next[window2] = value;
|
|
84452
84822
|
changed = true;
|
|
84453
84823
|
}
|
|
@@ -84472,12 +84842,12 @@ async function showPolicy({ context, args }) {
|
|
|
84472
84842
|
}
|
|
84473
84843
|
async function setPolicy({ context, args }) {
|
|
84474
84844
|
const state = args.words[2];
|
|
84475
|
-
if (state !== void 0 && state !== "on" && state !== "off") throw new CliUsageError(
|
|
84845
|
+
if (state !== void 0 && state !== "on" && state !== "off") throw new CliUsageError(USAGE12);
|
|
84476
84846
|
const { client } = await signedIn({ context, args });
|
|
84477
84847
|
const current2 = await client.get("/api/models/policy");
|
|
84478
84848
|
const defaultBudget = limitsFrom({ args, prefix: "default-", current: current2.defaultBudget });
|
|
84479
84849
|
const cap = limitsFrom({ args, prefix: "cap-", current: current2.cap });
|
|
84480
|
-
if (!state && !defaultBudget && !cap) throw new CliUsageError(
|
|
84850
|
+
if (!state && !defaultBudget && !cap) throw new CliUsageError(USAGE12);
|
|
84481
84851
|
const updated = await client.post("/api/models/policy", {
|
|
84482
84852
|
...state ? { lazeModels: state === "on" } : {},
|
|
84483
84853
|
...defaultBudget ? { defaultBudget } : {},
|
|
@@ -84518,11 +84888,11 @@ async function agentNamed({ client, name: name3 }) {
|
|
|
84518
84888
|
}
|
|
84519
84889
|
async function setBudget({ context, args }) {
|
|
84520
84890
|
const name3 = args.words[2];
|
|
84521
|
-
if (!name3) throw new CliUsageError(
|
|
84891
|
+
if (!name3) throw new CliUsageError(USAGE12);
|
|
84522
84892
|
const { client } = await signedIn({ context, args });
|
|
84523
84893
|
const agent2 = await agentNamed({ client, name: name3 });
|
|
84524
84894
|
const next = limitsFrom({ args, prefix: "", current: agent2.budget });
|
|
84525
|
-
if (!next) throw new CliUsageError(
|
|
84895
|
+
if (!next) throw new CliUsageError(USAGE12);
|
|
84526
84896
|
const updated = await client.post("/api/models/agents/budget", {
|
|
84527
84897
|
agentId: agent2.agentId,
|
|
84528
84898
|
budget: next
|
|
@@ -84555,7 +84925,7 @@ var MODEL_COMMANDS = {
|
|
|
84555
84925
|
async function models({ context, args }) {
|
|
84556
84926
|
const name3 = args.words[1] ?? "policy";
|
|
84557
84927
|
const command = Object.hasOwn(MODEL_COMMANDS, name3) ? MODEL_COMMANDS[name3] : void 0;
|
|
84558
|
-
if (!command) throw new CliUsageError(
|
|
84928
|
+
if (!command) throw new CliUsageError(USAGE12);
|
|
84559
84929
|
await command({ context, args });
|
|
84560
84930
|
}
|
|
84561
84931
|
|
|
@@ -84633,7 +85003,7 @@ var monitorResume = stateRun("/api/agents/monitors/resume", "resume");
|
|
|
84633
85003
|
var monitorRemove = stateRun("/api/agents/monitors/remove", "rm");
|
|
84634
85004
|
|
|
84635
85005
|
// src/services/notification-commands.service.ts
|
|
84636
|
-
var
|
|
85006
|
+
var USAGE13 = `Usage:
|
|
84637
85007
|
laze notifications [show] your notification settings (people)
|
|
84638
85008
|
laze notifications set [--channels all|mentions|nothing] [--keywords a,b] [--dnd on|off]
|
|
84639
85009
|
[--dnd-from 22:00] [--dnd-to 08:00] [--tz <IANA zone>] [--push on|off] [--email on|off]
|
|
@@ -84662,14 +85032,14 @@ function switchOf({ args, name: name3 }) {
|
|
|
84662
85032
|
if (!text2) return void 0;
|
|
84663
85033
|
if (text2 !== "on" && text2 !== "off")
|
|
84664
85034
|
throw new CliUsageError(`--${name3} takes on or off.
|
|
84665
|
-
${
|
|
85035
|
+
${USAGE13}`);
|
|
84666
85036
|
return text2 === "on";
|
|
84667
85037
|
}
|
|
84668
85038
|
function changesOf(args) {
|
|
84669
85039
|
const channels2 = flagText({ args, name: "channels" });
|
|
84670
85040
|
if (channels2 && !["all", "mentions", "nothing"].includes(channels2))
|
|
84671
85041
|
throw new CliUsageError(`--channels takes all, mentions or nothing.
|
|
84672
|
-
${
|
|
85042
|
+
${USAGE13}`);
|
|
84673
85043
|
const keywords = typeof args.flags.keywords === "string" ? args.flags.keywords : void 0;
|
|
84674
85044
|
const emailAfter = flagText({ args, name: "email-after" });
|
|
84675
85045
|
const changes2 = {
|
|
@@ -84691,7 +85061,7 @@ async function showSettings({ context, args }) {
|
|
|
84691
85061
|
}
|
|
84692
85062
|
async function setSettings({ context, args }) {
|
|
84693
85063
|
const changes2 = changesOf(args);
|
|
84694
|
-
if (Object.keys(changes2).length === 0) throw new CliUsageError(
|
|
85064
|
+
if (Object.keys(changes2).length === 0) throw new CliUsageError(USAGE13);
|
|
84695
85065
|
const { client } = await signedIn({ context, args });
|
|
84696
85066
|
print7({
|
|
84697
85067
|
context,
|
|
@@ -84702,7 +85072,7 @@ async function setSettings({ context, args }) {
|
|
|
84702
85072
|
async function snoozeFor({ context, args }) {
|
|
84703
85073
|
const word3 = args.words[2];
|
|
84704
85074
|
const minutes = word3 === "off" ? 0 : Number(word3);
|
|
84705
|
-
if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(
|
|
85075
|
+
if (!word3 || !Number.isInteger(minutes) || minutes < 0) throw new CliUsageError(USAGE13);
|
|
84706
85076
|
const { client } = await signedIn({ context, args });
|
|
84707
85077
|
print7({
|
|
84708
85078
|
context,
|
|
@@ -84720,7 +85090,7 @@ var NOTIFICATION_COMMANDS = {
|
|
|
84720
85090
|
async function notifications({ context, args }) {
|
|
84721
85091
|
const name3 = args.words[1] ?? "show";
|
|
84722
85092
|
const command = Object.hasOwn(NOTIFICATION_COMMANDS, name3) ? NOTIFICATION_COMMANDS[name3] : void 0;
|
|
84723
|
-
if (!command) throw new CliUsageError(
|
|
85093
|
+
if (!command) throw new CliUsageError(USAGE13);
|
|
84724
85094
|
await command({ context, args });
|
|
84725
85095
|
}
|
|
84726
85096
|
|
|
@@ -84957,8 +85327,8 @@ ${OPS_USAGE}`);
|
|
|
84957
85327
|
}
|
|
84958
85328
|
|
|
84959
85329
|
// src/services/release-watch.service.ts
|
|
84960
|
-
import { mkdir as
|
|
84961
|
-
import { dirname as dirname21, join as
|
|
85330
|
+
import { mkdir as mkdir22, readFile as readFile31, realpath, writeFile as writeFile22 } from "node:fs/promises";
|
|
85331
|
+
import { dirname as dirname21, join as join23 } from "node:path";
|
|
84962
85332
|
|
|
84963
85333
|
// src/rules/cli-update.rules.ts
|
|
84964
85334
|
var CLI_PACKAGE = "@lazehq/cli";
|
|
@@ -85105,15 +85475,15 @@ async function startedUpdate({
|
|
|
85105
85475
|
const plan2 = updatePlanOf({ script: await scriptOf(context) });
|
|
85106
85476
|
if (plan2.kind !== "install") return null;
|
|
85107
85477
|
const folder = dirname21(context.environment.configPath);
|
|
85108
|
-
const stamp =
|
|
85478
|
+
const stamp = join23(folder, "auto-update.json");
|
|
85109
85479
|
const last = await readFile31(stamp, "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
|
|
85110
85480
|
const now = context.nowMs();
|
|
85111
85481
|
if (last?.server === server && now - last.atMs < RETRY_AFTER_MS) return null;
|
|
85112
|
-
await
|
|
85113
|
-
await
|
|
85482
|
+
await mkdir22(folder, { recursive: true, mode: 448 });
|
|
85483
|
+
await writeFile22(stamp, JSON.stringify({ server, atMs: now }), { mode: 384 });
|
|
85114
85484
|
context.processes.spawnDetached({
|
|
85115
85485
|
argv: [...context.program, "update"],
|
|
85116
|
-
logPath:
|
|
85486
|
+
logPath: join23(folder, "auto-update.log")
|
|
85117
85487
|
});
|
|
85118
85488
|
return { manager: plan2.manager };
|
|
85119
85489
|
}
|
|
@@ -85224,7 +85594,7 @@ async function rushWakeHook({ context, args }) {
|
|
|
85224
85594
|
}
|
|
85225
85595
|
|
|
85226
85596
|
// src/services/schedule-commands.service.ts
|
|
85227
|
-
var
|
|
85597
|
+
var USAGE14 = `Usage:
|
|
85228
85598
|
laze schedule add <name> --prompt <text> (--cron "<m h dom mon dow>" | --rrule "<RRULE>" | --at <local time>)
|
|
85229
85599
|
[--tz <IANA zone>] [--channel <channelId>] [--agent <agentId>]
|
|
85230
85600
|
laze schedule list
|
|
@@ -85239,7 +85609,7 @@ function timingOf(args) {
|
|
|
85239
85609
|
const given = [cron, rrule, at].filter(Boolean);
|
|
85240
85610
|
if (given.length !== 1)
|
|
85241
85611
|
throw new CliUsageError(`Give exactly one of --cron, --rrule or --at.
|
|
85242
|
-
${
|
|
85612
|
+
${USAGE14}`);
|
|
85243
85613
|
if (cron) return { kind: "cron", cron };
|
|
85244
85614
|
if (rrule) return { kind: "rrule", rrule };
|
|
85245
85615
|
return { kind: "once", at };
|
|
@@ -85254,7 +85624,7 @@ function printSchedule({ context, schedule: schedule2 }) {
|
|
|
85254
85624
|
async function scheduleAdd({ context, args }) {
|
|
85255
85625
|
const name3 = args.words.slice(2).join(" ").trim();
|
|
85256
85626
|
const prompt = flagText({ args, name: "prompt" });
|
|
85257
|
-
if (!name3 || !prompt) throw new CliUsageError(
|
|
85627
|
+
if (!name3 || !prompt) throw new CliUsageError(USAGE14);
|
|
85258
85628
|
const timing = timingOf(args);
|
|
85259
85629
|
const { client } = await signedIn({ context, args });
|
|
85260
85630
|
const channelId = flagText({ args, name: "channel" });
|
|
@@ -85291,7 +85661,7 @@ function changesOf2(args) {
|
|
|
85291
85661
|
async function scheduleUpdate({ context, args }) {
|
|
85292
85662
|
const scheduleId = args.words[2];
|
|
85293
85663
|
const changes2 = changesOf2(args);
|
|
85294
|
-
if (!scheduleId || Object.keys(changes2).length === 0) throw new CliUsageError(
|
|
85664
|
+
if (!scheduleId || Object.keys(changes2).length === 0) throw new CliUsageError(USAGE14);
|
|
85295
85665
|
const { client } = await signedIn({ context, args });
|
|
85296
85666
|
const schedule2 = await client.post("/api/schedules/update", { scheduleId, ...changes2 });
|
|
85297
85667
|
if (args.flags.json) return context.out(`${JSON.stringify(schedule2, null, 2)}
|
|
@@ -85308,7 +85678,7 @@ async function scheduleList({ context, args }) {
|
|
|
85308
85678
|
function byId(path) {
|
|
85309
85679
|
return async ({ context, args }) => {
|
|
85310
85680
|
const scheduleId = args.words[2];
|
|
85311
|
-
if (!scheduleId) throw new CliUsageError(
|
|
85681
|
+
if (!scheduleId) throw new CliUsageError(USAGE14);
|
|
85312
85682
|
const { client } = await signedIn({ context, args });
|
|
85313
85683
|
const answer4 = await client.post(`/api/schedules/${path}`, {
|
|
85314
85684
|
scheduleId
|
|
@@ -85322,7 +85692,7 @@ function byId(path) {
|
|
|
85322
85692
|
}
|
|
85323
85693
|
async function scheduleRuns({ context, args }) {
|
|
85324
85694
|
const scheduleId = args.words[2];
|
|
85325
|
-
if (!scheduleId) throw new CliUsageError(
|
|
85695
|
+
if (!scheduleId) throw new CliUsageError(USAGE14);
|
|
85326
85696
|
const { client } = await signedIn({ context, args });
|
|
85327
85697
|
const runs = await client.post("/api/schedules/runs", { scheduleId });
|
|
85328
85698
|
if (args.flags.json) return context.out(`${JSON.stringify(runs, null, 2)}
|
|
@@ -85336,7 +85706,7 @@ async function scheduleRuns({ context, args }) {
|
|
|
85336
85706
|
}
|
|
85337
85707
|
async function scheduleRun({ context, args }) {
|
|
85338
85708
|
const scheduleId = args.words[2];
|
|
85339
|
-
if (!scheduleId) throw new CliUsageError(
|
|
85709
|
+
if (!scheduleId) throw new CliUsageError(USAGE14);
|
|
85340
85710
|
const { client } = await signedIn({ context, args });
|
|
85341
85711
|
const run4 = await client.post("/api/schedules/run", { scheduleId });
|
|
85342
85712
|
if (args.flags.json) return context.out(`${JSON.stringify(run4, null, 2)}
|
|
@@ -85357,14 +85727,14 @@ var SCHEDULE_COMMANDS = {
|
|
|
85357
85727
|
async function schedule({ context, args }) {
|
|
85358
85728
|
const name3 = args.words[1] ?? "";
|
|
85359
85729
|
const command = Object.hasOwn(SCHEDULE_COMMANDS, name3) ? SCHEDULE_COMMANDS[name3] : void 0;
|
|
85360
|
-
if (!command) throw new CliUsageError(
|
|
85730
|
+
if (!command) throw new CliUsageError(USAGE14);
|
|
85361
85731
|
await command({ context, args });
|
|
85362
85732
|
}
|
|
85363
85733
|
|
|
85364
85734
|
// src/services/skill-commands.service.ts
|
|
85365
85735
|
import { readdir as readdir7, readFile as readFile33 } from "node:fs/promises";
|
|
85366
|
-
import { join as
|
|
85367
|
-
var
|
|
85736
|
+
import { join as join24, relative as relative6, resolve as resolve13 } from "node:path";
|
|
85737
|
+
var USAGE15 = `Usage:
|
|
85368
85738
|
laze skill list [--agent <agentId>]
|
|
85369
85739
|
laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
|
|
85370
85740
|
laze skill install --from <folder> [--as <name>] [--agent <agentId>] a folder with a SKILL.md
|
|
@@ -85384,7 +85754,7 @@ async function folderFiles({ root }) {
|
|
|
85384
85754
|
const files2 = [];
|
|
85385
85755
|
for (const entry of entries) {
|
|
85386
85756
|
if (!entry.isFile()) continue;
|
|
85387
|
-
const full =
|
|
85757
|
+
const full = join24(entry.parentPath, entry.name);
|
|
85388
85758
|
files2.push({ path: relative6(root, full), content: await readFile33(full, "utf8") });
|
|
85389
85759
|
}
|
|
85390
85760
|
return files2.toSorted((a, b) => a.path.localeCompare(b.path));
|
|
@@ -85413,7 +85783,7 @@ async function skillList({ context, args }) {
|
|
|
85413
85783
|
async function skillInstall({ context, args }) {
|
|
85414
85784
|
const catalogueId = args.words[2];
|
|
85415
85785
|
const from = flagText({ args, name: "from" });
|
|
85416
|
-
if (!catalogueId === !from) throw new CliUsageError(
|
|
85786
|
+
if (!catalogueId === !from) throw new CliUsageError(USAGE15);
|
|
85417
85787
|
const name3 = flagText({ args, name: "as" });
|
|
85418
85788
|
const agent2 = flagText({ args, name: "agent" });
|
|
85419
85789
|
const files2 = from ? await folderFiles({ root: resolve13(context.cwd, from) }) : void 0;
|
|
@@ -85431,7 +85801,7 @@ async function skillInstall({ context, args }) {
|
|
|
85431
85801
|
}
|
|
85432
85802
|
async function skillShow({ context, args }) {
|
|
85433
85803
|
const name3 = args.words[2];
|
|
85434
|
-
if (!name3) throw new CliUsageError(
|
|
85804
|
+
if (!name3) throw new CliUsageError(USAGE15);
|
|
85435
85805
|
const agent2 = flagText({ args, name: "agent" });
|
|
85436
85806
|
const { client } = await signedIn({ context, args });
|
|
85437
85807
|
const skill2 = await client.post("/api/skills/show", {
|
|
@@ -85464,7 +85834,7 @@ function agentFlag(args) {
|
|
|
85464
85834
|
}
|
|
85465
85835
|
async function skillRemove({ context, args }) {
|
|
85466
85836
|
const name3 = args.words[2];
|
|
85467
|
-
if (!name3) throw new CliUsageError(
|
|
85837
|
+
if (!name3) throw new CliUsageError(USAGE15);
|
|
85468
85838
|
const { client } = await signedIn({ context, args });
|
|
85469
85839
|
const removed = await client.post("/api/skills/remove", {
|
|
85470
85840
|
name: name3,
|
|
@@ -85481,7 +85851,7 @@ async function skillUpdate({ context, args }) {
|
|
|
85481
85851
|
const description = typeof args.flags.description === "string" ? args.flags.description : void 0;
|
|
85482
85852
|
const skillMdFile = flagText({ args, name: "skill-md" });
|
|
85483
85853
|
if (!name3 || !newName && description === void 0 && !skillMdFile) {
|
|
85484
|
-
throw new CliUsageError(
|
|
85854
|
+
throw new CliUsageError(USAGE15);
|
|
85485
85855
|
}
|
|
85486
85856
|
const skillMd = skillMdFile ? await readFile33(resolve13(context.cwd, skillMdFile), "utf8") : void 0;
|
|
85487
85857
|
const { client } = await signedIn({ context, args });
|
|
@@ -85500,7 +85870,7 @@ async function skillUpdate({ context, args }) {
|
|
|
85500
85870
|
function pinning({ unpin }) {
|
|
85501
85871
|
return async ({ context, args }) => {
|
|
85502
85872
|
const name3 = args.words[2];
|
|
85503
|
-
if (!name3) throw new CliUsageError(
|
|
85873
|
+
if (!name3) throw new CliUsageError(USAGE15);
|
|
85504
85874
|
const { client } = await signedIn({ context, args });
|
|
85505
85875
|
const path = unpin ? "/api/skills/unpin" : "/api/skills/pin";
|
|
85506
85876
|
const skill2 = await client.post(path, { name: name3, ...agentFlag(args) });
|
|
@@ -85524,7 +85894,7 @@ var SKILL_COMMANDS = {
|
|
|
85524
85894
|
async function skill({ context, args }) {
|
|
85525
85895
|
const name3 = args.words[1] ?? "";
|
|
85526
85896
|
const command = Object.hasOwn(SKILL_COMMANDS, name3) ? SKILL_COMMANDS[name3] : void 0;
|
|
85527
|
-
if (!command) throw new CliUsageError(
|
|
85897
|
+
if (!command) throw new CliUsageError(USAGE15);
|
|
85528
85898
|
await command({ context, args });
|
|
85529
85899
|
}
|
|
85530
85900
|
|
|
@@ -86135,11 +86505,11 @@ function statusLine2({ presence: presence2 }) {
|
|
|
86135
86505
|
}
|
|
86136
86506
|
|
|
86137
86507
|
// src/services/status-commands.service.ts
|
|
86138
|
-
var
|
|
86508
|
+
var USAGE16 = "Usage: laze status set <emoji> [text] [--for 30m|1h|4h|today|week|never] [--tz <zone>], laze status clear|away|active";
|
|
86139
86509
|
function clearAfterOf({ args }) {
|
|
86140
86510
|
const wanted = flagText({ args, name: "for", fallback: "never" });
|
|
86141
86511
|
const known = STATUS_CLEAR_AFTER.find((candidate) => candidate === wanted);
|
|
86142
|
-
if (!known) throw new CliUsageError(
|
|
86512
|
+
if (!known) throw new CliUsageError(USAGE16);
|
|
86143
86513
|
return known;
|
|
86144
86514
|
}
|
|
86145
86515
|
function answer3({
|
|
@@ -86153,7 +86523,7 @@ function answer3({
|
|
|
86153
86523
|
}
|
|
86154
86524
|
async function statusSet({ context, args }) {
|
|
86155
86525
|
const [, , emoji3, ...words] = args.words;
|
|
86156
|
-
if (!emoji3) throw new CliUsageError(
|
|
86526
|
+
if (!emoji3) throw new CliUsageError(USAGE16);
|
|
86157
86527
|
const clearAfter = clearAfterOf({ args });
|
|
86158
86528
|
const timeZone = flagText({ args, name: "tz" }) || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
86159
86529
|
const { client } = await signedIn({ context, args });
|
|
@@ -86177,7 +86547,7 @@ async function statusAway({ context, args }) {
|
|
|
86177
86547
|
answer3({ context, args, presence: presence2 });
|
|
86178
86548
|
}
|
|
86179
86549
|
async function statusUsage() {
|
|
86180
|
-
throw new CliUsageError(
|
|
86550
|
+
throw new CliUsageError(USAGE16);
|
|
86181
86551
|
}
|
|
86182
86552
|
|
|
86183
86553
|
// src/services/update-commands.service.ts
|
|
@@ -86301,7 +86671,7 @@ async function update2({
|
|
|
86301
86671
|
|
|
86302
86672
|
// src/services/vault-env-commands.service.ts
|
|
86303
86673
|
import { readFile as readFile36, stat as stat5 } from "node:fs/promises";
|
|
86304
|
-
import { dirname as dirname22, join as
|
|
86674
|
+
import { dirname as dirname22, join as join25, resolve as resolve15 } from "node:path";
|
|
86305
86675
|
|
|
86306
86676
|
// src/rules/vault-manifest.rules.ts
|
|
86307
86677
|
var VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -86410,7 +86780,7 @@ async function doorOf({
|
|
|
86410
86780
|
const turnFile = turnFileOf({ env });
|
|
86411
86781
|
const headers = {
|
|
86412
86782
|
"proxy-authorization": proxy.authorization,
|
|
86413
|
-
"x-laze-turn": await
|
|
86783
|
+
"x-laze-turn": await turnTokenOf2({ env, turnFile, command: "laze vault env" })
|
|
86414
86784
|
};
|
|
86415
86785
|
return {
|
|
86416
86786
|
keyPath: runKeyPathOf({ turnFile, connection: keyName }),
|
|
@@ -86436,7 +86806,11 @@ async function doorOf({
|
|
|
86436
86806
|
}
|
|
86437
86807
|
const signed2 = await signedIn({ context, args }).catch(() => null);
|
|
86438
86808
|
if (signed2?.profile.kind !== "agent") throw new CliUsageError(WHERE);
|
|
86439
|
-
const {
|
|
86809
|
+
const { name: name3 } = signed2;
|
|
86810
|
+
const client = forSession({
|
|
86811
|
+
client: signed2.client,
|
|
86812
|
+
session: await currentSessionOf({ context, args })
|
|
86813
|
+
});
|
|
86440
86814
|
const channelId = flagText({ args, name: "channel" }) || null;
|
|
86441
86815
|
return {
|
|
86442
86816
|
keyPath: runKeyPathOf({ turnFile: void 0, connection: keyName, profile: name3 }),
|
|
@@ -86480,14 +86854,14 @@ async function untilAllAnswered({
|
|
|
86480
86854
|
`
|
|
86481
86855
|
);
|
|
86482
86856
|
while (waiting.size > 0) {
|
|
86483
|
-
if (context.nowMs() +
|
|
86857
|
+
if (context.nowMs() + POLL_MS > deadline) {
|
|
86484
86858
|
context.err(
|
|
86485
86859
|
`laze vault: ${[...waiting.keys()].join(", ")} not approved yet; ask again later.
|
|
86486
86860
|
`
|
|
86487
86861
|
);
|
|
86488
86862
|
return "capped";
|
|
86489
86863
|
}
|
|
86490
|
-
await context.sleep(
|
|
86864
|
+
await context.sleep(POLL_MS);
|
|
86491
86865
|
for (const [key, pending] of waiting) {
|
|
86492
86866
|
const next = await door.status(pending.requestId);
|
|
86493
86867
|
if (next.outcome === "ask") waiting.set(key, next);
|
|
@@ -86642,7 +87016,7 @@ async function manifestPathOf({
|
|
|
86642
87016
|
const environment = flagText({ args, name: "env" });
|
|
86643
87017
|
const file3 = environment ? `.env.${environment}.vault` : ".env.vault";
|
|
86644
87018
|
for (let dir = resolve15(context.cwd); ; dir = dirname22(dir)) {
|
|
86645
|
-
if (await isFile(
|
|
87019
|
+
if (await isFile(join25(dir, file3))) return join25(dir, file3);
|
|
86646
87020
|
if (dirname22(dir) === dir) break;
|
|
86647
87021
|
}
|
|
86648
87022
|
throw new CliUsageError(`laze vault: no ${file3} here or in a parent folder
|
|
@@ -86753,7 +87127,7 @@ ${ENV_USAGE}`);
|
|
|
86753
87127
|
`);
|
|
86754
87128
|
return 0;
|
|
86755
87129
|
}
|
|
86756
|
-
const redact = [...released.values()].flatMap(({ fields }) =>
|
|
87130
|
+
const redact = [...released.values()].flatMap(({ fields }) => secretValuesOf({ fields }));
|
|
86757
87131
|
return context.runCommand({ command: prepared.command, env, redact });
|
|
86758
87132
|
}
|
|
86759
87133
|
async function vaultAws({
|
|
@@ -86802,7 +87176,7 @@ async function postInTurn({
|
|
|
86802
87176
|
body
|
|
86803
87177
|
}) {
|
|
86804
87178
|
const env = context.environment.inherited;
|
|
86805
|
-
const turn = await
|
|
87179
|
+
const turn = await turnTokenOf2({
|
|
86806
87180
|
env,
|
|
86807
87181
|
turnFile: turnFileOf({ env }),
|
|
86808
87182
|
command: "laze vault save"
|
|
@@ -87505,7 +87879,7 @@ async function whatsappBusiness({
|
|
|
87505
87879
|
}
|
|
87506
87880
|
|
|
87507
87881
|
// src/services/whatsapp-pairing-commands.service.ts
|
|
87508
|
-
import { writeFile as
|
|
87882
|
+
import { writeFile as writeFile23 } from "node:fs/promises";
|
|
87509
87883
|
import { resolve as resolve17 } from "node:path";
|
|
87510
87884
|
var WHATSAPP_PAIRING_USAGE = [
|
|
87511
87885
|
" laze whatsapp pair <machine> [--qr <file.svg>] link WhatsApp on your machine; scan the code (owner)",
|
|
@@ -87526,7 +87900,7 @@ function svgOf(dataUrl) {
|
|
|
87526
87900
|
}
|
|
87527
87901
|
async function report({ context, args, pairing: pairing2 }) {
|
|
87528
87902
|
const qrFile = pairing2.qrSvg ? resolve17(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
|
|
87529
|
-
if (qrFile && pairing2.qrSvg) await
|
|
87903
|
+
if (qrFile && pairing2.qrSvg) await writeFile23(qrFile, svgOf(pairing2.qrSvg), "utf8");
|
|
87530
87904
|
if (args.flags.json) return context.out(`${JSON.stringify({ ...pairing2, qrFile }, null, 2)}
|
|
87531
87905
|
`);
|
|
87532
87906
|
context.out(`${pairing2.pairingId} ${pairing2.state}
|
|
@@ -87591,7 +87965,7 @@ var PATHS3 = {
|
|
|
87591
87965
|
var STATUS_WAIT_SECONDS2 = 50;
|
|
87592
87966
|
var STATUS_CALLS2 = 2;
|
|
87593
87967
|
var SETTLED = /* @__PURE__ */ new Set(["sent", "denied", "expired", "failed"]);
|
|
87594
|
-
var
|
|
87968
|
+
var USAGE17 = [
|
|
87595
87969
|
"Usage: laze whatsapp chats <machine> [--limit <n>] the chats on the machine, newest first",
|
|
87596
87970
|
" laze whatsapp read <machine> <chat> [--limit <n>] a chat's last messages, oldest first",
|
|
87597
87971
|
' laze whatsapp send <machine> <chat> "<text>" send as the owner; an agent waits for their approval',
|
|
@@ -87601,14 +87975,14 @@ var USAGE18 = [
|
|
|
87601
87975
|
].join("\n");
|
|
87602
87976
|
function word2({ args, at }) {
|
|
87603
87977
|
const value = args.words[at];
|
|
87604
|
-
if (!value) throw new CliUsageError(
|
|
87978
|
+
if (!value) throw new CliUsageError(USAGE17);
|
|
87605
87979
|
return value;
|
|
87606
87980
|
}
|
|
87607
87981
|
function limitOf5({ args }) {
|
|
87608
87982
|
const text2 = flagText({ args, name: "limit" });
|
|
87609
87983
|
if (!text2) return {};
|
|
87610
87984
|
const limit = Number(text2);
|
|
87611
|
-
if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(
|
|
87985
|
+
if (!Number.isInteger(limit) || limit < 1) throw new CliUsageError(USAGE17);
|
|
87612
87986
|
return { limit };
|
|
87613
87987
|
}
|
|
87614
87988
|
async function chats({ context, args }) {
|
|
@@ -87670,7 +88044,7 @@ Still waiting. Run \`laze whatsapp status ${send4.id}\` later to see the answer.
|
|
|
87670
88044
|
}
|
|
87671
88045
|
async function send3({ context, args }) {
|
|
87672
88046
|
const text2 = args.words.slice(4).join(" ") || args.rest.join(" ");
|
|
87673
|
-
if (!text2) throw new CliUsageError(
|
|
88047
|
+
if (!text2) throw new CliUsageError(USAGE17);
|
|
87674
88048
|
const client = await computeClient({ context, args });
|
|
87675
88049
|
const asked = await client.post(PATHS3.send, {
|
|
87676
88050
|
machine: word2({ args, at: 2 }),
|
|
@@ -87700,11 +88074,11 @@ async function whatsapp({
|
|
|
87700
88074
|
if (command === "status") return status8({ context, args });
|
|
87701
88075
|
const linking = whatsappPairingCommand(command);
|
|
87702
88076
|
if (linking) return linking({ context, args });
|
|
87703
|
-
throw new CliUsageError(
|
|
88077
|
+
throw new CliUsageError(USAGE17);
|
|
87704
88078
|
}
|
|
87705
88079
|
|
|
87706
88080
|
// src/services/wiki-commands.service.ts
|
|
87707
|
-
var
|
|
88081
|
+
var USAGE18 = `Usage:
|
|
87708
88082
|
laze wiki list
|
|
87709
88083
|
laze wiki get <path>
|
|
87710
88084
|
laze wiki put <path> <markdown|@file|-> [--title <title>] [--channel <channel>] [--base <version>]
|
|
@@ -87724,7 +88098,7 @@ async function wikiList({ context, args }) {
|
|
|
87724
88098
|
}
|
|
87725
88099
|
async function wikiGet({ context, args }) {
|
|
87726
88100
|
const path = args.words[2];
|
|
87727
|
-
if (!path) throw new CliUsageError(
|
|
88101
|
+
if (!path) throw new CliUsageError(USAGE18);
|
|
87728
88102
|
const { client } = await signedIn({ context, args });
|
|
87729
88103
|
const page = await client.post("/api/wiki/get", { path });
|
|
87730
88104
|
if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
|
|
@@ -87741,7 +88115,7 @@ Linked from: ${page.backlinks.map((link) => link.path).join(", ")}
|
|
|
87741
88115
|
async function wikiPut({ context, args }) {
|
|
87742
88116
|
const path = args.words[2];
|
|
87743
88117
|
const value = args.words.slice(3).join(" ");
|
|
87744
|
-
if (!path || !value) throw new CliUsageError(
|
|
88118
|
+
if (!path || !value) throw new CliUsageError(USAGE18);
|
|
87745
88119
|
const body = await textArgument({ context, value });
|
|
87746
88120
|
const title = flagText({ args, name: "title" });
|
|
87747
88121
|
const channel = flagText({ args, name: "channel" });
|
|
@@ -87761,7 +88135,7 @@ async function wikiPut({ context, args }) {
|
|
|
87761
88135
|
}
|
|
87762
88136
|
async function wikiSearch({ context, args }) {
|
|
87763
88137
|
const query = args.words.slice(2).join(" ").trim();
|
|
87764
|
-
if (!query) throw new CliUsageError(
|
|
88138
|
+
if (!query) throw new CliUsageError(USAGE18);
|
|
87765
88139
|
const { client } = await signedIn({ context, args });
|
|
87766
88140
|
const hits = await client.post("/api/wiki/search", { query });
|
|
87767
88141
|
if (args.flags.json) return context.out(`${JSON.stringify(hits, null, 2)}
|
|
@@ -87771,7 +88145,7 @@ async function wikiSearch({ context, args }) {
|
|
|
87771
88145
|
}
|
|
87772
88146
|
async function wikiHistory({ context, args }) {
|
|
87773
88147
|
const path = args.words[2];
|
|
87774
|
-
if (!path) throw new CliUsageError(
|
|
88148
|
+
if (!path) throw new CliUsageError(USAGE18);
|
|
87775
88149
|
const { client } = await signedIn({ context, args });
|
|
87776
88150
|
const revisions = await client.post("/api/wiki/history", { path });
|
|
87777
88151
|
if (args.flags.json) return context.out(`${JSON.stringify(revisions, null, 2)}
|
|
@@ -87785,7 +88159,7 @@ async function wikiHistory({ context, args }) {
|
|
|
87785
88159
|
}
|
|
87786
88160
|
async function wikiMove({ context, args }) {
|
|
87787
88161
|
const [, , path, to] = args.words;
|
|
87788
|
-
if (!path || !to) throw new CliUsageError(
|
|
88162
|
+
if (!path || !to) throw new CliUsageError(USAGE18);
|
|
87789
88163
|
const { client } = await signedIn({ context, args });
|
|
87790
88164
|
const page = await client.post("/api/wiki/move", { path, to });
|
|
87791
88165
|
if (args.flags.json) return context.out(`${JSON.stringify(page, null, 2)}
|
|
@@ -87795,7 +88169,7 @@ async function wikiMove({ context, args }) {
|
|
|
87795
88169
|
}
|
|
87796
88170
|
async function wikiRemove({ context, args }) {
|
|
87797
88171
|
const path = args.words[2];
|
|
87798
|
-
if (!path) throw new CliUsageError(
|
|
88172
|
+
if (!path) throw new CliUsageError(USAGE18);
|
|
87799
88173
|
const { client } = await signedIn({ context, args });
|
|
87800
88174
|
const removed = await client.post("/api/wiki/remove", { path });
|
|
87801
88175
|
if (args.flags.json) return context.out(`${JSON.stringify(removed)}
|
|
@@ -87815,7 +88189,7 @@ var WIKI_COMMANDS = {
|
|
|
87815
88189
|
async function wiki({ context, args }) {
|
|
87816
88190
|
const name3 = args.words[1] ?? "";
|
|
87817
88191
|
const command = Object.hasOwn(WIKI_COMMANDS, name3) ? WIKI_COMMANDS[name3] : void 0;
|
|
87818
|
-
if (!command) throw new CliUsageError(
|
|
88192
|
+
if (!command) throw new CliUsageError(USAGE18);
|
|
87819
88193
|
await command({ context, args });
|
|
87820
88194
|
}
|
|
87821
88195
|
|
|
@@ -88131,8 +88505,27 @@ async function list9({ context, args }) {
|
|
|
88131
88505
|
context,
|
|
88132
88506
|
args,
|
|
88133
88507
|
answer: answer4,
|
|
88134
|
-
text: (members3) => members3.map((it) =>
|
|
88135
|
-
`
|
|
88508
|
+
text: (members3) => members3.map((it) => {
|
|
88509
|
+
const aka2 = it.aliases?.length ? ` aka ${it.aliases.join(", ")}` : "";
|
|
88510
|
+
return `${ROLE_NAMES2[it.role]} ${it.name} ${it.email} ${it.userId}${aka2}
|
|
88511
|
+
`;
|
|
88512
|
+
}).join("")
|
|
88513
|
+
});
|
|
88514
|
+
}
|
|
88515
|
+
async function aka({ context, args }) {
|
|
88516
|
+
const { client } = await signedIn({ context, args });
|
|
88517
|
+
const names = args.words.slice(2);
|
|
88518
|
+
const clear = Boolean(args.flags.clear);
|
|
88519
|
+
const answer4 = names.length > 0 || clear ? await client.post("/api/agents/me/workspace/aka/set", {
|
|
88520
|
+
aliases: clear ? [] : names
|
|
88521
|
+
}) : await client.post("/api/agents/me/workspace/aka", {});
|
|
88522
|
+
print8({
|
|
88523
|
+
context,
|
|
88524
|
+
args,
|
|
88525
|
+
answer: answer4,
|
|
88526
|
+
text: (it) => it.aliases?.length ? `${it.name}, also known as ${it.aliases.join(", ")}
|
|
88527
|
+
` : `${it.name} goes by no other name. Add some with laze members aka <name>...
|
|
88528
|
+
`
|
|
88136
88529
|
});
|
|
88137
88530
|
}
|
|
88138
88531
|
async function invite({ context, args }) {
|
|
@@ -88264,6 +88657,7 @@ var MEMBERS_COMMANDS = {
|
|
|
88264
88657
|
"revoke-invite": revokeInvite,
|
|
88265
88658
|
"invite-link": inviteLink,
|
|
88266
88659
|
role,
|
|
88660
|
+
aka,
|
|
88267
88661
|
remove: remove5,
|
|
88268
88662
|
requests,
|
|
88269
88663
|
approve: deciding("approved"),
|
|
@@ -88275,7 +88669,7 @@ async function members2({ context, args }) {
|
|
|
88275
88669
|
const command = MEMBERS_COMMANDS[sub];
|
|
88276
88670
|
if (!command) {
|
|
88277
88671
|
throw new CliUsageError(
|
|
88278
|
-
"Usage: laze members [invite | invites | revoke-invite | invite-link | role | remove | requests | approve | deny]"
|
|
88672
|
+
"Usage: laze members [invite | invites | revoke-invite | invite-link | role | aka | remove | requests | approve | deny]"
|
|
88279
88673
|
);
|
|
88280
88674
|
}
|
|
88281
88675
|
return command({ context, args });
|
|
@@ -88327,6 +88721,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
|
|
|
88327
88721
|
laze members invite <email> [--role owner|admin|member|guest] invite someone (admins)
|
|
88328
88722
|
laze members invites | revoke-invite <email|id> invitations waiting, or take one back (admins)
|
|
88329
88723
|
laze members invite-link <email|id> a fresh link for an invitation, shown once (admins)
|
|
88724
|
+
laze members aka [<name>...] [--clear] the other names you go by, such as a nickname
|
|
88330
88725
|
laze members role <member> owner|admin|member|guest change a member's role (admins)
|
|
88331
88726
|
laze members remove <member> take someone out of the workspace (admins)
|
|
88332
88727
|
laze members requests | approve <id> | deny <id> access requests waiting for an admin
|
|
@@ -88458,8 +88853,10 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
|
|
|
88458
88853
|
laze connect providers|start|search|mcp|mcp-key|github|card|card-key connect services as yourself
|
|
88459
88854
|
laze connect install|status|stop|uninstall the service that hands linked Codex sessions their messages
|
|
88460
88855
|
laze openclaw list|connect|agent|agent-key|feed|disconnect your OpenClaw gateways and their agents
|
|
88461
|
-
laze browser open|tabs|goto|read|ask|cdp|share|close a live browser tab pinned to the conversation
|
|
88856
|
+
laze browser open|tabs|goto|read|ask|login|cdp|share|close a live browser tab pinned to the conversation
|
|
88462
88857
|
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
|
|
88858
|
+
Any agent working for the tab's owner drives it, connected agents (Claude Code, Codex) from their own session included
|
|
88859
|
+
laze browser login <tab> --vault <connection> types a saved sign-in only when the person says to use it; laze browser --help for all
|
|
88463
88860
|
laze browser setup|cdp|screen|status <machine> a machine with Chrome a person signs in on, for agents
|
|
88464
88861
|
Sites without an API need a person's login: open a browser tab and ask there, never ask for a password; a browser machine only when the person asks for one
|
|
88465
88862
|
laze browser setup <site> --on <machine> the browser on a person's own machine instead, at no Laze compute cost
|
|
@@ -88723,7 +89120,9 @@ async function runCli({
|
|
|
88723
89120
|
[openclaw, OPENCLAW_USAGE],
|
|
88724
89121
|
[chatActions, CHAT_ACTIONS_USAGE],
|
|
88725
89122
|
[agentLogins, LOGINS_HELP],
|
|
88726
|
-
[agentPools, POOLS_HELP]
|
|
89123
|
+
[agentPools, POOLS_HELP],
|
|
89124
|
+
[browser, `${BROWSER_USAGE}
|
|
89125
|
+
`]
|
|
88727
89126
|
]);
|
|
88728
89127
|
if (command && args.flags.help && ownHelp.has(command)) {
|
|
88729
89128
|
context.out(ownHelp.get(command) ?? HELP);
|