@lazehq/cli 0.1.38 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/laze.mjs +779 -297
  2. package/package.json +1 -1
package/dist/laze.mjs CHANGED
@@ -18733,8 +18733,8 @@ var require_snapshot_utils = __commonJS({
18733
18733
  var require_snapshot_recorder = __commonJS({
18734
18734
  "../../node_modules/.pnpm/undici@8.10.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
18735
18735
  "use strict";
18736
- var { writeFile: writeFile23, readFile: readFile39, mkdir: mkdir21 } = __require("node:fs/promises");
18737
- var { dirname: dirname22, resolve: resolve17 } = __require("node:path");
18736
+ var { writeFile: writeFile23, readFile: readFile39, mkdir: mkdir22 } = __require("node:fs/promises");
18737
+ var { dirname: dirname23, resolve: resolve17 } = __require("node:path");
18738
18738
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
18739
18739
  var { InvalidArgumentError, UndiciError } = require_errors();
18740
18740
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -18980,7 +18980,7 @@ var require_snapshot_recorder = __commonJS({
18980
18980
  throw new InvalidArgumentError("Snapshot path is required");
18981
18981
  }
18982
18982
  const resolvedPath = resolve17(path);
18983
- await mkdir21(dirname22(resolvedPath), { recursive: true });
18983
+ await mkdir22(dirname23(resolvedPath), { recursive: true });
18984
18984
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
18985
18985
  hash: hash2,
18986
18986
  snapshot
@@ -35708,7 +35708,7 @@ function flagText({
35708
35708
  }
35709
35709
 
35710
35710
  // src/rules/cli-version.rules.ts
35711
- var STAMPED = "0.1.38";
35711
+ var STAMPED = "0.1.40";
35712
35712
  function cliVersionOf({ stamped = STAMPED } = {}) {
35713
35713
  return stamped.startsWith("__") ? "dev" : stamped;
35714
35714
  }
@@ -57796,6 +57796,96 @@ var deviceGrantSummarySchema = deviceGrantSummarySchemaDefinition;
57796
57796
  var ApiKeyApi = moduleApi()("api-key");
57797
57797
  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();
57798
57798
 
57799
+ // ../../modules/chat/contract/src/chat.layout.ts
57800
+ var LAYOUT_BLOCKS_MAX = 50;
57801
+ var LAYOUT_TEXT_MAX = 3e3;
57802
+ var LAYOUT_ITEMS_MAX = 25;
57803
+ var markdown = external_exports.string().max(LAYOUT_TEXT_MAX);
57804
+ var plain = external_exports.string().max(LAYOUT_TEXT_MAX);
57805
+ var imageUrl = external_exports.url({ protocol: /^https?$/ }).max(2e3);
57806
+ var linkUrl = external_exports.string().max(3e3);
57807
+ var layoutImageSchemaDefinition = external_exports.object({ url: imageUrl, alt: plain });
57808
+ var layoutButtonSchemaDefinition = external_exports.object({
57809
+ text: plain,
57810
+ url: linkUrl.nullable(),
57811
+ style: external_exports.enum(["default", "primary", "danger"])
57812
+ });
57813
+ var layoutAccessorySchemaDefinition = external_exports.discriminatedUnion("type", [
57814
+ external_exports.object({ type: external_exports.literal("image"), image: layoutImageSchemaDefinition }),
57815
+ external_exports.object({ type: external_exports.literal("button"), button: layoutButtonSchemaDefinition })
57816
+ ]);
57817
+ var contextItemSchemaDefinition = external_exports.discriminatedUnion("type", [
57818
+ external_exports.object({ type: external_exports.literal("text"), text: markdown }),
57819
+ external_exports.object({ type: external_exports.literal("image"), image: layoutImageSchemaDefinition })
57820
+ ]);
57821
+ var buttons = external_exports.array(layoutButtonSchemaDefinition).max(LAYOUT_ITEMS_MAX);
57822
+ var cardSchemaDefinition = external_exports.object({
57823
+ type: external_exports.literal("card"),
57824
+ icon: layoutImageSchemaDefinition.nullable(),
57825
+ heroImage: layoutImageSchemaDefinition.nullable(),
57826
+ title: markdown,
57827
+ subtitle: markdown,
57828
+ body: markdown,
57829
+ actions: buttons
57830
+ });
57831
+ var layoutBlockSchemaDefinition = external_exports.discriminatedUnion("type", [
57832
+ external_exports.object({ type: external_exports.literal("header"), text: plain }),
57833
+ external_exports.object({
57834
+ type: external_exports.literal("section"),
57835
+ text: markdown,
57836
+ fields: external_exports.array(markdown).max(LAYOUT_ITEMS_MAX),
57837
+ accessory: layoutAccessorySchemaDefinition.nullable()
57838
+ }),
57839
+ external_exports.object({
57840
+ type: external_exports.literal("context"),
57841
+ items: external_exports.array(contextItemSchemaDefinition).max(LAYOUT_ITEMS_MAX)
57842
+ }),
57843
+ external_exports.object({ type: external_exports.literal("actions"), buttons }),
57844
+ external_exports.object({ type: external_exports.literal("divider") }),
57845
+ external_exports.object({
57846
+ type: external_exports.literal("image"),
57847
+ image: layoutImageSchemaDefinition,
57848
+ title: plain
57849
+ }),
57850
+ /** Rich text, a markdown block or the source's own text: drawn like a message body. */
57851
+ external_exports.object({ type: external_exports.literal("text"), text: markdown }),
57852
+ cardSchemaDefinition,
57853
+ external_exports.object({ type: external_exports.literal("carousel"), cards: external_exports.array(cardSchemaDefinition).max(10) })
57854
+ ]);
57855
+ var attachmentFieldSchemaDefinition = external_exports.object({
57856
+ title: plain,
57857
+ value: markdown,
57858
+ short: external_exports.boolean()
57859
+ });
57860
+ var layoutAttachmentSchemaDefinition = external_exports.object({
57861
+ type: external_exports.literal("attachment"),
57862
+ /** `#RRGGBB`, or null for the default grey bar. */
57863
+ color: external_exports.string().regex(/^#[0-9A-F]{6}$/).nullable(),
57864
+ pretext: markdown,
57865
+ author: external_exports.object({ name: plain, url: linkUrl.nullable(), icon: imageUrl.nullable() }).nullable(),
57866
+ title: plain,
57867
+ titleUrl: linkUrl.nullable(),
57868
+ text: markdown,
57869
+ fields: external_exports.array(attachmentFieldSchemaDefinition).max(LAYOUT_ITEMS_MAX),
57870
+ blocks: external_exports.array(layoutBlockSchemaDefinition).max(LAYOUT_BLOCKS_MAX),
57871
+ image: layoutImageSchemaDefinition.nullable(),
57872
+ thumb: layoutImageSchemaDefinition.nullable(),
57873
+ actions: buttons,
57874
+ footer: markdown,
57875
+ footerIcon: imageUrl.nullable(),
57876
+ /** The attachment's time, a `<!date^...>` token the reader formats; "" for none. */
57877
+ ts: markdown
57878
+ });
57879
+ var layoutPartSchemaDefinition = external_exports.union([
57880
+ layoutBlockSchemaDefinition,
57881
+ layoutAttachmentSchemaDefinition
57882
+ ]);
57883
+ var messageLayoutSchemaDefinition = external_exports.object({
57884
+ /** No parts means the source drew only its text: no layout is kept. */
57885
+ parts: external_exports.array(layoutPartSchemaDefinition).max(LAYOUT_BLOCKS_MAX)
57886
+ });
57887
+ var messageLayoutSchema = messageLayoutSchemaDefinition;
57888
+
57799
57889
  // ../../modules/chat/contract/src/chat.presence.ts
57800
57890
  var STATUS_TEXT_MAX = 100;
57801
57891
  var idSchema = external_exports.string().min(1).max(64);
@@ -58384,6 +58474,8 @@ var messageSchemaDefinition = external_exports.object({
58384
58474
  pin: messagePinSchemaDefinition.nullable().default(null),
58385
58475
  /** A forward's quote of the original message, taken when it was forwarded. */
58386
58476
  forward: messageForwardSchemaDefinition.nullable().optional(),
58477
+ /** The blocks and attachments a mirrored message's source drew; clients draw it for the body. */
58478
+ layout: messageLayoutSchema.nullable().optional(),
58387
58479
  /** A message written in Laze that its mirror is still waiting to send, or could not send. */
58388
58480
  mirrorDelivery: mirrorDeliverySchema.nullable().optional(),
58389
58481
  /** A thread reply also sent to its conversation: it shows in the thread and the channel. */
@@ -58548,7 +58640,9 @@ var updateChannelInputSchemaDefinition = external_exports.object({
58548
58640
  /** Makes a public channel private; the creator's or a workspace Admin's change, one way only. */
58549
58641
  visibility: external_exports.literal("private").optional(),
58550
58642
  /** No agent answers unless named; a channel Admin's or a workspace Admin's change. */
58551
- mentionedOnly: external_exports.boolean().optional()
58643
+ mentionedOnly: external_exports.boolean().optional(),
58644
+ /** The sender's key: each notice the change posts carries it, as `<key>-name` or `-topic`. */
58645
+ clientKey: external_exports.string().regex(/^[A-Za-z0-9_-]{8,48}$/).optional()
58552
58646
  });
58553
58647
  var updateChannelInputSchema = updateChannelInputSchemaDefinition;
58554
58648
  var logChannelHintSchemaDefinition = external_exports.object({ suggested: external_exports.boolean() });
@@ -58572,7 +58666,9 @@ var newMemberSchemaDefinition = external_exports.object({
58572
58666
  var addMembersInputSchemaDefinition = external_exports.object({
58573
58667
  workspaceId: workspaceIdSchema,
58574
58668
  channelId: idSchema4,
58575
- members: external_exports.array(newMemberSchemaDefinition).min(1).max(100)
58669
+ members: external_exports.array(newMemberSchemaDefinition).min(1).max(100),
58670
+ /** The sender's key: the notice for `members[i]` carries `<key>-<i>`. */
58671
+ clientKey: external_exports.string().regex(/^[A-Za-z0-9_-]{8,48}$/).optional()
58576
58672
  });
58577
58673
  var addMembersInputSchema = addMembersInputSchemaDefinition;
58578
58674
  var removeMemberInputSchemaDefinition = external_exports.object({
@@ -58738,6 +58834,8 @@ var postMirroredInputSchemaDefinition = external_exports.object({
58738
58834
  keyOwnerUserId: idSchema4,
58739
58835
  origin: messageOriginSchemaDefinition,
58740
58836
  body: external_exports.string().max(MESSAGE_BODY_MAX),
58837
+ /** The source's blocks and attachments, drawn in place of the body; null when it has none. */
58838
+ layout: messageLayoutSchema.nullable().default(null),
58741
58839
  threadRootId: idSchema4.nullable().default(null),
58742
58840
  createdAt: external_exports.iso.datetime().optional(),
58743
58841
  /** A notice is a one-line change at the source, such as a new topic; it mentions no one. */
@@ -58749,6 +58847,8 @@ var updateMirroredInputSchemaDefinition = external_exports.object({
58749
58847
  /** Whose vault holds a key in the new text: the linked author, else whoever mirrored it. */
58750
58848
  keyOwnerUserId: idSchema4,
58751
58849
  body: external_exports.string().max(MESSAGE_BODY_MAX).optional(),
58850
+ /** The source's blocks and attachments now; null drops them; left out keeps them. */
58851
+ layout: messageLayoutSchema.nullable().optional(),
58752
58852
  deleted: external_exports.boolean().default(false),
58753
58853
  /** Laze read the source's message again, which is not an edit: no edited mark. */
58754
58854
  rerendered: external_exports.boolean().default(false)
@@ -59293,6 +59393,11 @@ var readableTextInputSchemaDefinition = external_exports.object({
59293
59393
  workspaceId: workspaceIdSchema,
59294
59394
  bodies: external_exports.array(external_exports.string()).max(HISTORY_PAGE_MAX)
59295
59395
  });
59396
+ var joinedChannelSchemaDefinition = external_exports.object({
59397
+ id: external_exports.string(),
59398
+ name: external_exports.string(),
59399
+ kind: external_exports.enum(["public", "private"])
59400
+ });
59296
59401
  var ChatApi = moduleApi()("chat");
59297
59402
  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();
59298
59403
  var chatChannelRolesTrpc = defineTrpcContract("chat").mutation("setChannelRole").withInput(setChannelRoleInputSchema).withOutput(conversationSchema).mutation("extendChannel").withInput(extendChannelInputSchema).withOutput(conversationSchema).build();
@@ -59348,6 +59453,7 @@ var apnsPayloadSchemaDefinition = external_exports.object({
59348
59453
  aps: external_exports.object({
59349
59454
  alert: external_exports.object({ title: external_exports.string().min(1).max(120), body: external_exports.string().max(400) }).optional(),
59350
59455
  badge: external_exports.number().int().nonnegative().optional(),
59456
+ /** The system's default sound; absent plays nothing. */
59351
59457
  sound: external_exports.literal("default").optional(),
59352
59458
  "thread-id": external_exports.string().min(1).max(200).optional(),
59353
59459
  category: external_exports.literal(APNS_APPROVAL_CATEGORY).optional(),
@@ -59397,7 +59503,9 @@ var webPushPayloadSchemaDefinition = external_exports.object({
59397
59503
  title: external_exports.string().min(1).max(WEB_PUSH_TITLE_MAX),
59398
59504
  body: external_exports.string().max(WEB_PUSH_BODY_MAX),
59399
59505
  url: external_exports.string().min(1).max(2048),
59400
- tag: external_exports.string().min(1).max(200)
59506
+ tag: external_exports.string().min(1).max(200),
59507
+ /** Shown without the system sound, such as for a message a Slack mirror brought in. */
59508
+ silent: external_exports.boolean().optional()
59401
59509
  }).strict();
59402
59510
  var webPushPayloadSchema = webPushPayloadSchemaDefinition;
59403
59511
  var requestWebPushDeliveryCommandSchemaDefinition = external_exports.object({
@@ -59486,6 +59594,8 @@ var clockSchema = external_exports.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "
59486
59594
  var channelDefaultSchema = external_exports.enum(["all", "mentions", "nothing"]);
59487
59595
  var FEED_PUSH_KINDS = ["approvals", "urgent", "replies", "wakeups", "groups"];
59488
59596
  var feedPushKindSchema = external_exports.enum(FEED_PUSH_KINDS);
59597
+ var PHONE_PUSH_DELAYS = [0, 1, 2, 5, 10, 15, 30];
59598
+ var phonePushDelaySchema = external_exports.literal(PHONE_PUSH_DELAYS);
59489
59599
  var notificationSettingsSchemaDefinition = external_exports.object({
59490
59600
  channelDefault: channelDefaultSchema,
59491
59601
  /** Words that notify like a mention, matched whole and case-blind. */
@@ -59511,7 +59621,9 @@ var notificationSettingsSchemaDefinition = external_exports.object({
59511
59621
  /** Weekly sends on Mondays only. */
59512
59622
  digestFrequency: external_exports.enum(["daily", "weekly"]),
59513
59623
  /** Skips Saturday and Sunday. */
59514
- digestWeekdaysOnly: external_exports.boolean()
59624
+ digestWeekdaysOnly: external_exports.boolean(),
59625
+ /** Minutes without input on the web or the desktop app before notices reach the phone. */
59626
+ phonePushAfterMinutes: phonePushDelaySchema
59515
59627
  });
59516
59628
  var notificationSettingsSchema = notificationSettingsSchemaDefinition;
59517
59629
  var updateSettingsInputSchemaDefinition = external_exports.object({
@@ -59572,7 +59684,9 @@ var messageNoticeSchema = external_exports.object({
59572
59684
  /** Who it comes from, anyone outside Laze included: a burst from one sender is pushed once. */
59573
59685
  from: external_exports.object({ key: external_exports.string().min(1).max(200), name: external_exports.string().max(120) }).optional(),
59574
59686
  /** The sender picked "Notify anyway": it breaks through Do Not Disturb, once. */
59575
- urgent: external_exports.boolean().optional()
59687
+ urgent: external_exports.boolean().optional(),
59688
+ /** It came in through a mirror such as Slack, whose own app already rings: Laze stays silent. */
59689
+ mirrored: external_exports.boolean().optional()
59576
59690
  });
59577
59691
  var approvalNoticeSchema = external_exports.object({
59578
59692
  workspaceId: workspaceIdSchema2,
@@ -59626,7 +59740,9 @@ var desktopPublicationSchemaDefinition = external_exports.object({
59626
59740
  tag: external_exports.string(),
59627
59741
  sender: noticeSenderSchema.optional(),
59628
59742
  /** The message's place in its conversation, so reading past it closes the notification. */
59629
- seq: external_exports.number().int().nonnegative().optional()
59743
+ seq: external_exports.number().int().nonnegative().optional(),
59744
+ /** Shown without any sound, such as for a message a Slack mirror brought in. */
59745
+ silent: external_exports.boolean().optional()
59630
59746
  }).nullable(),
59631
59747
  badge: external_exports.number().int().nonnegative(),
59632
59748
  /** The tag of a notification to take back, such as one for a message since deleted. */
@@ -60417,6 +60533,7 @@ var vaultSealedApprovalSchemaDefinition = external_exports.object({
60417
60533
  var vaultSealedApprovalSchema = vaultSealedApprovalSchemaDefinition;
60418
60534
  var vaultUi = uiTokens("vault");
60419
60535
  var VaultSealedApprovalSlot = vaultUi.component("sealedApproval");
60536
+ var VaultShareApprovalSlot = vaultUi.component("shareApproval");
60420
60537
  var VaultPasskeyStepSlot = vaultUi.component("passkeyStep");
60421
60538
  var VaultNavSlot = vaultUi.component("nav");
60422
60539
  var answerSealedApprovalInputSchemaDefinition = external_exports.object({
@@ -60789,6 +60906,24 @@ var approveVaultShareInputSchemaDefinition = external_exports.object({
60789
60906
  reauthToken: external_exports.string().min(1)
60790
60907
  });
60791
60908
  var approveVaultShareInputSchema = approveVaultShareInputSchemaDefinition;
60909
+ var revokeVaultGrantInputSchemaDefinition = external_exports.object({
60910
+ workspaceId: external_exports.string().min(1),
60911
+ grantId: external_exports.string().min(1),
60912
+ resolutionNote: external_exports.string().trim().max(500).optional()
60913
+ });
60914
+ var revokeVaultGrantInputSchema = revokeVaultGrantInputSchemaDefinition;
60915
+ var vaultWaitingShareSchemaDefinition = external_exports.object({
60916
+ grantId: external_exports.string().min(1),
60917
+ connectionId: external_exports.string().min(1),
60918
+ /** The key's name as its owner reads it. */
60919
+ keyLabel: external_exports.string(),
60920
+ /** The teammate the share is for. */
60921
+ recipientUserId: external_exports.string().min(1),
60922
+ /** The agent that asked the share; null when it was asked from the CLI. */
60923
+ agentId: external_exports.string().nullable().default(null),
60924
+ expiresAt: external_exports.iso.datetime().nullable(),
60925
+ askedAt: external_exports.iso.datetime()
60926
+ });
60792
60927
  var sealVaultConnectionInputSchemaDefinition = external_exports.object({
60793
60928
  workspaceId: external_exports.string().min(1),
60794
60929
  connectionId: external_exports.string().min(1),
@@ -61168,7 +61303,7 @@ var vaultTrpc = defineTrpcContract("vault").mutation("createConnection").withInp
61168
61303
  reason: external_exports.string().trim().min(1).max(200),
61169
61304
  reauthToken: external_exports.string().min(1).max(200).optional()
61170
61305
  })
61171
- ).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(external_exports.object({ workspaceId: external_exports.string().min(1), grantId: external_exports.string().min(1) })).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("listGrants").withInput(connectionInput).withOutput(external_exports.array(vaultGrantSchema)).mutation("shareConnection").withInput(shareVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("approveShare").withInput(approveVaultShareInputSchema).withOutput(vaultGrantSchema).mutation("sealConnection").withInput(sealVaultConnectionInputSchema).withOutput(vaultConnectionSchema).query("listApprovals").withInput(external_exports.object({ ...workspaceInput.shape, state: vaultApprovalStateSchema.optional() })).withOutput(external_exports.array(vaultApprovalRequestSchema)).mutation("answerApproval").withInput(answerVaultApprovalInputSchema).withOutput(vaultApprovalRequestSchema).query("listAudit").withInput(vaultAuditReadInputSchema).withOutput(vaultAuditPageSchema).query("listActivity").withInput(vaultAuditReadInputSchema).withOutput(external_exports.array(vaultAuditEntrySchema)).query("listLeases").withInput(workspaceInput).withOutput(external_exports.array(vaultLeaseSchema)).mutation("endLease").withInput(endVaultLeaseInputSchema).withOutput(external_exports.object({ ended: external_exports.literal(true) })).query("mostAsked").withInput(vaultMostAskedInputSchema).withOutput(vaultMostAskedSchema).query("judgeStatus").withInput(workspaceInput).withOutput(vaultJudgeStatusSchema).query("listLevelLimits").withInput(workspaceInput).withOutput(external_exports.array(vaultLevelLimitSchema)).mutation("setLevelLimit").withInput(setVaultLevelLimitInputSchema).withOutput(external_exports.array(vaultLevelLimitSchema)).query("listDevices").withInput(workspaceInput).withOutput(external_exports.array(vaultDeviceSchema)).mutation("beginDeviceEnrolment").withInput(workspaceInput).withOutput(vaultDeviceEnrolmentSchema).mutation("finishDeviceEnrolment").withInput(finishVaultDeviceEnrolmentInputSchema).withOutput(vaultDeviceSchema).mutation("beginDeviceApproval").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ challenge: external_exports.string(), sealed: external_exports.array(vaultSealedMaterialSchema) })).mutation("approveDevice").withInput(approveVaultDeviceInputSchema).withOutput(vaultDeviceSchema).mutation("removeDevice").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ removed: external_exports.literal(true) })).mutation("createSealedConnection").withInput(createSealedConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("resealConnection").withInput(resealConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("openSealedConnection").withInput(
61306
+ ).withOutput(external_exports.object({ fields: external_exports.record(external_exports.string(), external_exports.string()) })).mutation("beginReauth").withInput(workspaceInput).withOutput(vaultReauthChallengeSchema).mutation("confirmReauth").withInput(confirmVaultReauthInputSchema).withOutput(vaultReauthProofSchema).mutation("grantConnection").withInput(grantVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("lendToChannel").withInput(lendVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("revokeGrant").withInput(revokeVaultGrantInputSchema).withOutput(external_exports.object({ revoked: external_exports.literal(true) })).query("listGrants").withInput(connectionInput).withOutput(external_exports.array(vaultGrantSchema)).mutation("shareConnection").withInput(shareVaultConnectionInputSchema).withOutput(vaultGrantSchema).mutation("approveShare").withInput(approveVaultShareInputSchema).withOutput(vaultGrantSchema).mutation("sealConnection").withInput(sealVaultConnectionInputSchema).withOutput(vaultConnectionSchema).query("listApprovals").withInput(external_exports.object({ ...workspaceInput.shape, state: vaultApprovalStateSchema.optional() })).withOutput(external_exports.array(vaultApprovalRequestSchema)).mutation("answerApproval").withInput(answerVaultApprovalInputSchema).withOutput(vaultApprovalRequestSchema).query("listAudit").withInput(vaultAuditReadInputSchema).withOutput(vaultAuditPageSchema).query("listActivity").withInput(vaultAuditReadInputSchema).withOutput(external_exports.array(vaultAuditEntrySchema)).query("listLeases").withInput(workspaceInput).withOutput(external_exports.array(vaultLeaseSchema)).mutation("endLease").withInput(endVaultLeaseInputSchema).withOutput(external_exports.object({ ended: external_exports.literal(true) })).query("mostAsked").withInput(vaultMostAskedInputSchema).withOutput(vaultMostAskedSchema).query("judgeStatus").withInput(workspaceInput).withOutput(vaultJudgeStatusSchema).query("listLevelLimits").withInput(workspaceInput).withOutput(external_exports.array(vaultLevelLimitSchema)).mutation("setLevelLimit").withInput(setVaultLevelLimitInputSchema).withOutput(external_exports.array(vaultLevelLimitSchema)).query("listDevices").withInput(workspaceInput).withOutput(external_exports.array(vaultDeviceSchema)).mutation("beginDeviceEnrolment").withInput(workspaceInput).withOutput(vaultDeviceEnrolmentSchema).mutation("finishDeviceEnrolment").withInput(finishVaultDeviceEnrolmentInputSchema).withOutput(vaultDeviceSchema).mutation("beginDeviceApproval").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ challenge: external_exports.string(), sealed: external_exports.array(vaultSealedMaterialSchema) })).mutation("approveDevice").withInput(approveVaultDeviceInputSchema).withOutput(vaultDeviceSchema).mutation("removeDevice").withInput(external_exports.object({ ...workspaceInput.shape, deviceId: external_exports.string().min(1) })).withOutput(external_exports.object({ removed: external_exports.literal(true) })).mutation("createSealedConnection").withInput(createSealedConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("resealConnection").withInput(resealConnectionInputSchema).withOutput(vaultConnectionSchema).mutation("openSealedConnection").withInput(
61172
61307
  external_exports.object({
61173
61308
  ...connectionInput.shape,
61174
61309
  reason: external_exports.string().trim().min(1).max(200),
@@ -61303,6 +61438,18 @@ var vaultApprovalResolvedPayloadSchemaDefinition = external_exports.object({
61303
61438
  /** Who decides the card, so their open approvals lists refresh. */
61304
61439
  approverUserIds: external_exports.array(external_exports.string()).readonly().default([])
61305
61440
  });
61441
+ var vaultShareSettledPayloadSchemaDefinition = external_exports.object({
61442
+ workspaceId: external_exports.string().min(1),
61443
+ grantId: external_exports.string().min(1),
61444
+ ownerUserId: external_exports.string().min(1),
61445
+ state: external_exports.enum(["approved", "denied"]),
61446
+ answeredByUserId: external_exports.string().min(1),
61447
+ /** The agent that asked the share; null when it was asked from the CLI. */
61448
+ agentId: external_exports.string().nullable().default(null),
61449
+ /** Why the owner said no, for the agent that asked; empty when nothing. */
61450
+ resolutionNote: external_exports.string().default(""),
61451
+ at: external_exports.iso.datetime()
61452
+ });
61306
61453
 
61307
61454
  // ../../modules/vault/contract/src/vault-oauth.ts
61308
61455
  var tokenFieldsSchema = external_exports.object({
@@ -61357,7 +61504,7 @@ async function hkdfKey(input2) {
61357
61504
  }
61358
61505
  async function gcmOpen(input2) {
61359
61506
  try {
61360
- const plain2 = await subtle().decrypt(
61507
+ const plain3 = await subtle().decrypt(
61361
61508
  {
61362
61509
  name: "AES-GCM",
61363
61510
  iv: input2.sealed.subarray(0, IV_BYTES),
@@ -61366,7 +61513,7 @@ async function gcmOpen(input2) {
61366
61513
  input2.key,
61367
61514
  input2.sealed.subarray(IV_BYTES)
61368
61515
  );
61369
- return new Uint8Array(plain2);
61516
+ return new Uint8Array(plain3);
61370
61517
  } catch {
61371
61518
  throw new VaultSealMismatchError();
61372
61519
  }
@@ -61402,7 +61549,7 @@ function fieldsOf(value) {
61402
61549
  }
61403
61550
  var releaseLabel = (requestId) => `laze-vault/release/v1/${requestId}`;
61404
61551
  async function openRunRelease(input2) {
61405
- const plain2 = await decryptFrom({
61552
+ const plain3 = await decryptFrom({
61406
61553
  agree: agreementOf(input2.runPrivateKey),
61407
61554
  publicKey: fromBase64Url(input2.runPublicKey),
61408
61555
  epk: input2.release.epk,
@@ -61410,7 +61557,7 @@ async function openRunRelease(input2) {
61410
61557
  info: releaseLabel(input2.requestId),
61411
61558
  aad: releaseLabel(input2.requestId)
61412
61559
  });
61413
- return fieldsOf(JSON.parse(new TextDecoder().decode(plain2)).fields);
61560
+ return fieldsOf(JSON.parse(new TextDecoder().decode(plain3)).fields);
61414
61561
  }
61415
61562
 
61416
61563
  // ../../modules/vault/contract/src/vault-scrub.ts
@@ -61558,6 +61705,8 @@ var vaultAlertRaisedPayloadSchemaDefinition = external_exports.object({
61558
61705
  workspaceId: external_exports.string().min(1),
61559
61706
  /** One per alert: `vaultd:<seq>:<at>` from vaultd, `audit:<workspace>:<seq>` from the chain. */
61560
61707
  alertId: external_exports.string().min(1),
61708
+ /** The card it lands on: repeats of one incident share it. Absent, the alert has its own. */
61709
+ incidentId: external_exports.string().min(1).optional(),
61561
61710
  /** vaultd's sequence number, the worker's cursor; null for an alert the vault raised itself. */
61562
61711
  seq: external_exports.number().int().nonnegative().nullable(),
61563
61712
  /** `unexpected_caller`, `decrypt_burst`, `audit_chain_broken`, `test`, or a newer kind. */
@@ -61743,7 +61892,9 @@ var vaultWatchReportSchemaDefinition = external_exports.object({
61743
61892
  });
61744
61893
  var vaultWatchReportReceiptSchemaDefinition = external_exports.object({
61745
61894
  stored: external_exports.boolean(),
61746
- alerted: external_exports.boolean()
61895
+ alerted: external_exports.boolean(),
61896
+ /** This report made VAULT_WATCH_FAILED_CHECKS failed checks in a row, or ended such a run. */
61897
+ checkFailing: external_exports.enum(["started", "ended"]).nullable()
61747
61898
  });
61748
61899
  var b64url = external_exports.string().min(1).max(8192).regex(/^[A-Za-z0-9_-]+$/, "base64url without padding");
61749
61900
  var vaultPasskeyAssertionSchemaDefinition = external_exports.object({
@@ -61773,7 +61924,9 @@ var vaultdStateSchemaDefinition = external_exports.union([
61773
61924
  currentKeyId: external_exports.string(),
61774
61925
  readableKeyIds: external_exports.array(external_exports.string()),
61775
61926
  breaker: external_exports.enum(["closed", "open"]),
61776
- dryRun: external_exports.boolean()
61927
+ dryRun: external_exports.boolean(),
61928
+ /** The pinned operator passkey's credential id; empty when none is pinned. */
61929
+ operatorCredentialId: external_exports.string()
61777
61930
  }),
61778
61931
  external_exports.object({ holder: external_exports.literal("vaultd"), reachable: external_exports.literal(false), problem: external_exports.string() }),
61779
61932
  /** Development and tests: the key lives in this process, which has no breaker. */
@@ -61802,12 +61955,16 @@ var vaultWatchReportReceivedPayloadSchemaDefinition = external_exports.object({
61802
61955
  /** The alert workspace (VAULT_ALERT_WORKSPACE_ID), where a stopped watchdog's card lands. */
61803
61956
  workspaceId: external_exports.string().min(1),
61804
61957
  reportAt: external_exports.iso.datetime({ offset: true }),
61805
- at: external_exports.iso.datetime()
61958
+ at: external_exports.iso.datetime(),
61959
+ /** False when the run could not count unwraps: it does not hold the stopped card back. */
61960
+ checked: external_exports.boolean().default(true)
61806
61961
  });
61807
61962
  var vaultAlertClearedPayloadSchemaDefinition = external_exports.object({
61808
61963
  workspaceId: external_exports.string().min(1),
61809
61964
  /** The `alertId` of the vault_alert_raised it clears. */
61810
61965
  alertId: external_exports.string().min(1),
61966
+ /** The incident it clears, when the alert named one: its card goes to Handled. */
61967
+ incidentId: external_exports.string().min(1).optional(),
61811
61968
  label: external_exports.string().min(1).max(80),
61812
61969
  at: external_exports.iso.datetime()
61813
61970
  });
@@ -62064,6 +62221,14 @@ var lazeAgentEventSchemaDefinition = external_exports.discriminatedUnion("type",
62064
62221
  external_exports.object({ type: external_exports.literal("stalled"), silentMs: external_exports.number().int().nonnegative() }),
62065
62222
  /** A supervisor process came up with empty queues: Laze sends it what is still unanswered. */
62066
62223
  external_exports.object({ type: external_exports.literal("supervisor_started"), bootId: external_exports.string().min(1) }),
62224
+ /** A message the computer took no turn for: the laze CLI the agent answers with is gone. */
62225
+ external_exports.object({
62226
+ type: external_exports.literal("computer_trouble"),
62227
+ reason: external_exports.literal("cli_missing"),
62228
+ detail: external_exports.string().max(1e3),
62229
+ channelId: external_exports.string().min(1),
62230
+ threadRootId: external_exports.string().min(1).optional()
62231
+ }),
62067
62232
  /** The harness stopped to ask a person questions; it waits for an `attention_answer` frame. */
62068
62233
  external_exports.object({
62069
62234
  type: external_exports.literal("attention_opened"),
@@ -63931,8 +64096,10 @@ var liveStepsSchemaDefinition = external_exports.object({
63931
64096
  turn: liveTurnSchemaDefinition.nullable(),
63932
64097
  steps: external_exports.array(sequencedStepSchemaDefinition),
63933
64098
  lastSeq: external_exports.number().int().nonnegative(),
63934
- /** Null where the realtime edge is not configured: the panel says live steps are unavailable. */
63935
- stream: realtimeTokenSchema.nullable()
64099
+ /** Null where the realtime edge is not configured: the panel shows what it read. */
64100
+ stream: realtimeTokenSchema.nullable(),
64101
+ /** False for a person who may not talk to the agent: they see none of its steps. */
64102
+ visible: external_exports.boolean()
63936
64103
  });
63937
64104
  var liveStepsSchema = liveStepsSchemaDefinition;
63938
64105
  var replyStepsInputSchemaDefinition = external_exports.object({
@@ -64546,6 +64713,15 @@ var agentHarnessSchema = external_exports.enum([
64546
64713
  "mcp",
64547
64714
  "other"
64548
64715
  ]);
64716
+ var AGENT_HARNESS_NAMES = {
64717
+ "claude-code": "Claude Code",
64718
+ codex: "Codex",
64719
+ chatgpt: "ChatGPT",
64720
+ claude: "Claude",
64721
+ cowork: "Cowork",
64722
+ cursor: "Cursor",
64723
+ openclaw: "OpenClaw"
64724
+ };
64549
64725
  var agentSessionSchemaDefinition = external_exports.object({
64550
64726
  harness: agentHarnessSchema,
64551
64727
  sessionId: external_exports.string().min(1).max(200),
@@ -64818,6 +64994,12 @@ var receiveInboxInputSchemaDefinition = external_exports.object({
64818
64994
  waitSeconds: external_exports.coerce.number().int().min(0).max(INBOX_WAIT_MAX_SECONDS).default(0),
64819
64995
  limit: external_exports.coerce.number().int().min(1).max(50).default(20)
64820
64996
  });
64997
+ var inboxWaitingSchemaDefinition = external_exports.object({
64998
+ count: external_exports.number().int().min(0),
64999
+ /** When the oldest waiting message was posted; null when nothing waits. */
65000
+ oldestPostedAt: external_exports.iso.datetime().nullable(),
65001
+ session: agentSessionSchemaDefinition.nullable()
65002
+ });
64821
65003
  var callerSchemaDefinition = external_exports.object({
64822
65004
  kind: external_exports.enum(["person", "agent"]),
64823
65005
  id: idSchema14,
@@ -65032,7 +65214,6 @@ var AgentLoginCardSlot = agentUi.component("loginCard");
65032
65214
  var AgentBudgetCardSlot = agentUi.component("budgetCard");
65033
65215
  var AgentStopTurnSlot = agentUi.component("stopTurn");
65034
65216
  var AgentLiveStepsSlot = agentUi.component("liveSteps");
65035
- var AgentReplyStepsSlot = agentUi.component("replySteps");
65036
65217
  var AgentSessionHooksToken = agentUi.hooks("session");
65037
65218
  var AgentCreateDialogSlot = agentUi.component("createDialog");
65038
65219
  var AgentEditDialogSlot = agentUi.component("editDialog");
@@ -65699,6 +65880,14 @@ var sessionClaimSchemaDefinition = external_exports.object({
65699
65880
  folder: external_exports.string().max(500),
65700
65881
  host: external_exports.string().max(200)
65701
65882
  });
65883
+ function sessionLabelOf({
65884
+ harness,
65885
+ folder,
65886
+ host: host2
65887
+ }) {
65888
+ const name3 = AGENT_HARNESS_NAMES[harness] ?? "A session";
65889
+ return [name3, folder ? `in ${folder}` : "", host2 ? `on ${host2}` : ""].filter(Boolean).join(" ");
65890
+ }
65702
65891
  var boundSessionSchemaDefinition = external_exports.object({ bound: external_exports.literal(true) });
65703
65892
  var requestConnectionInputSchemaDefinition = external_exports.object({
65704
65893
  harness: agentHarnessSchema.default("other"),
@@ -66028,8 +66217,8 @@ async function copyAgent({
66028
66217
  }
66029
66218
 
66030
66219
  // src/services/agent-commands.service.ts
66031
- import { mkdir as mkdir14, readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
66032
- import { join as join15, resolve as resolve4 } from "node:path";
66220
+ import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
66221
+ import { join as join16, resolve as resolve4 } from "node:path";
66033
66222
 
66034
66223
  // src/rules/agent-profile.rules.ts
66035
66224
  var LEVELS = { fast: "Laze Fast", frontier: "Laze Frontier" };
@@ -66647,6 +66836,11 @@ var slackMessageEventSchemaDefinition = external_exports.object({
66647
66836
  latestReply: external_exports.string().nullable().default(null),
66648
66837
  /** When the message was last edited, Slack's `edited.ts`; null when it never was. */
66649
66838
  editedTs: external_exports.string().nullable().default(null),
66839
+ /** The message's Block Kit blocks and legacy attachments as Slack sent them, until handled. */
66840
+ blocks: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
66841
+ /** The message's own `text` beside its blocks; `text` above is what Slack shows, flattened. */
66842
+ sourceText: external_exports.string().optional(),
66843
+ attachments: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
66650
66844
  /** For `tokens_revoked`: the Slack users whose tokens were revoked, and whether the bot's was. */
66651
66845
  revoked: external_exports.object({ userIds: external_exports.array(external_exports.string()), bot: external_exports.boolean() }).optional()
66652
66846
  });
@@ -67050,7 +67244,7 @@ var TOKEN = /<@(person|agent):([A-Za-z0-9_-]+)>|<!(channel|here)>|<#([A-Za-z0-9_
67050
67244
  var LINK = /!?\[([^\]]*)\]\([^)\s]*(?:\s+"[^"]*")?\)/g;
67051
67245
  var AUTOLINK = /<((?:https?|mailto):[^>\s]+)>/g;
67052
67246
  var FILE_MARKER = /<file:[A-Za-z0-9_-]+>/g;
67053
- function plain(text2) {
67247
+ function plain2(text2) {
67054
67248
  return withoutMarkdownMarks(
67055
67249
  text2.replace(/```[\w+-]*/g, " ").replace(LINK, "$1").replace(AUTOLINK, "$1").replace(FILE_MARKER, " ")
67056
67250
  );
@@ -67065,14 +67259,14 @@ function bodyAsText({
67065
67259
  let from = 0;
67066
67260
  for (const token2 of written.matchAll(TOKEN)) {
67067
67261
  const [whole, kind2, id2, broadcast, channelId] = token2;
67068
- text2 += plain(written.slice(from, token2.index));
67262
+ text2 += plain2(written.slice(from, token2.index));
67069
67263
  from = token2.index + whole.length;
67070
67264
  if (channelId) {
67071
67265
  text2 += `#${mentions.channels.find((channel) => channel.id === channelId)?.name ?? "channel"}`;
67072
67266
  } else if (kind2 && id2) text2 += `@${actorName(kind2, id2)}`;
67073
67267
  else text2 += `@${broadcast ?? "channel"}`;
67074
67268
  }
67075
- text2 += plain(written.slice(from));
67269
+ text2 += plain2(written.slice(from));
67076
67270
  return text2.replace(/\s+/g, " ").trim();
67077
67271
  }
67078
67272
  function escaped(term) {
@@ -67296,6 +67490,7 @@ async function claudeProjectOf({
67296
67490
  import { mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
67297
67491
  import { dirname as dirname2, join as join2 } from "node:path";
67298
67492
  var PUSH_GRACE_MS = 3 * 6e4;
67493
+ var IN_FLIGHT_MS = 35e3;
67299
67494
  function fileNameOf({ profile }) {
67300
67495
  return profile.replace(/[^a-zA-Z0-9_-]/g, "_");
67301
67496
  }
@@ -67354,7 +67549,8 @@ async function dueFromSpool({
67354
67549
  context,
67355
67550
  profile,
67356
67551
  seen,
67357
- pushedToo
67552
+ pushedToo,
67553
+ settledOnly = false
67358
67554
  }) {
67359
67555
  const path = statePathOf({ context, kind: "spool", profile });
67360
67556
  const entries = await readSpool({ path });
@@ -67369,7 +67565,8 @@ async function dueFromSpool({
67369
67565
  messageIds: shown.map((entry) => entry.message.messageId)
67370
67566
  });
67371
67567
  const late = context.nowMs() - PUSH_GRACE_MS;
67372
- return entries.filter((entry) => !shown.includes(entry)).filter((entry) => entry.pushedAt === void 0 || pushedToo && entry.pushedAt <= late).map((entry) => entry.message);
67568
+ const settled2 = context.nowMs() - IN_FLIGHT_MS;
67569
+ return entries.filter((entry) => !shown.includes(entry)).filter((entry) => !settledOnly || entry.takenAt <= settled2).filter((entry) => entry.pushedAt === void 0 || pushedToo && entry.pushedAt <= late).map((entry) => entry.message);
67373
67570
  }
67374
67571
 
67375
67572
  // src/services/harness-session.service.ts
@@ -67501,6 +67698,27 @@ function notBoundText({
67501
67698
  const who = `${agent2 ? `"${agent2}"` : "this agent"} (config ${configPath})`;
67502
67699
  return `Laze: ${who} listens in another session${meta3.bound ? `: ${meta3.bound}` : ""}. Create a new Laze agent with this session: laze agent request. Or move this agent here: laze agent bind.`;
67503
67700
  }
67701
+ function boundMetaOf({ error: error62 }) {
67702
+ if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
67703
+ return error62.meta ?? {};
67704
+ }
67705
+ async function takeOverHere({
67706
+ context,
67707
+ client,
67708
+ session,
67709
+ meta: meta3,
67710
+ profile
67711
+ }) {
67712
+ if (!session || !meta3.session || meta3.host !== session.host) return false;
67713
+ const sessions = (await context.store.read()).sessions ?? {};
67714
+ const theirs = sessions[meta3.session];
67715
+ const mine4 = sessions[sessionKeyOf({ session })] === profile;
67716
+ const stale = mine4 && theirs !== void 0 && theirs !== profile;
67717
+ const claudePid = (await nearestHarnessOf({ context }))?.pid;
67718
+ if (!stale && await liveElsewhere({ context, key: meta3.session, claudePid })) return false;
67719
+ await forSession({ client, session }).post("/api/agents/me/bind", {});
67720
+ return true;
67721
+ }
67504
67722
  async function notBoundNotice({
67505
67723
  context,
67506
67724
  client,
@@ -67510,12 +67728,8 @@ async function notBoundNotice({
67510
67728
  }) {
67511
67729
  if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
67512
67730
  const meta3 = error62.meta ?? {};
67513
- if (client && session && meta3.session && meta3.host === session.host) {
67514
- const claudePid = (await nearestHarnessOf({ context }))?.pid;
67515
- if (!await liveElsewhere({ context, key: meta3.session, claudePid })) {
67516
- await client.post("/api/agents/me/bind", {});
67517
- return { notice: void 0, rebound: true };
67518
- }
67731
+ if (client && await takeOverHere({ context, client, session, meta: meta3, profile })) {
67732
+ return { notice: void 0, rebound: true };
67519
67733
  }
67520
67734
  const key = session ? sessionKeyOf({ session }) : "unknown";
67521
67735
  const path = statePathOf({ context, kind: "told", profile: key });
@@ -68220,13 +68434,13 @@ function channelLabelIn(channel) {
68220
68434
  }
68221
68435
 
68222
68436
  // src/services/claude-wait.service.ts
68223
- import { readFile as readFile10, rm as rm4, writeFile as writeFile9, mkdir as mkdir9 } from "node:fs/promises";
68224
- import { dirname as dirname10 } from "node:path";
68437
+ import { readFile as readFile10, rm as rm4, writeFile as writeFile9, mkdir as mkdir10 } from "node:fs/promises";
68438
+ import { dirname as dirname11 } from "node:path";
68225
68439
 
68226
68440
  // src/services/connect-service.service.ts
68227
68441
  import { createHash } from "node:crypto";
68228
- import { mkdir as mkdir8, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
68229
- import { dirname as dirname9, join as join11 } from "node:path";
68442
+ import { mkdir as mkdir9, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
68443
+ import { dirname as dirname10, join as join12 } from "node:path";
68230
68444
 
68231
68445
  // src/rules/connect-service.rules.ts
68232
68446
  function systemdWordOf(word3) {
@@ -68348,9 +68562,9 @@ function rolloutEventOf({
68348
68562
  }
68349
68563
 
68350
68564
  // src/services/connect-delivery.service.ts
68351
- import { mkdir as mkdir7, readFile as readFile9, rename as rename3, rm as rm2, stat as stat2, writeFile as writeFile7 } from "node:fs/promises";
68565
+ import { mkdir as mkdir8, readFile as readFile9, rename as rename3, rm as rm2, stat as stat2, writeFile as writeFile7 } from "node:fs/promises";
68352
68566
  import { homedir as homedir2, hostname as hostname4 } from "node:os";
68353
- import { dirname as dirname8, join as join10 } from "node:path";
68567
+ import { dirname as dirname9, join as join11 } from "node:path";
68354
68568
 
68355
68569
  // src/services/codex-turn-watch.service.ts
68356
68570
  import { open as open2, readdir as readdir2 } from "node:fs/promises";
@@ -68943,12 +69157,14 @@ async function notesOf({ context }) {
68943
69157
  const notes = await Promise.all(
68944
69158
  files2.map(async (file3) => {
68945
69159
  const pid = Number(file3.replace(/\.json$/, ""));
68946
- const session = await jsonOf(join9(folder, file3));
69160
+ const note = await jsonOf(join9(folder, file3));
68947
69161
  const at = await stat(join9(folder, file3)).then(
68948
69162
  (info) => info.mtimeMs,
68949
69163
  () => 0
68950
69164
  );
68951
- return pid && session ? [{ pid, key: sessionKeyOf({ session }), at }] : [];
69165
+ if (!pid || !note) return [];
69166
+ const { launch = {}, ...session } = note;
69167
+ return [{ pid, key: sessionKeyOf({ session }), at, session, launch }];
68952
69168
  })
68953
69169
  );
68954
69170
  return notes.flat().toSorted((a, b) => b.at - a.at);
@@ -68968,15 +69184,21 @@ async function rushListenersOf({
68968
69184
  for (const [key, profile] of bound) {
68969
69185
  const one = sessions.find((each) => `claude-code:${each.sessionId}` === key);
68970
69186
  if (!one?.id) continue;
68971
- const pids = notes.filter((note) => note.key === key).map((note) => note.pid);
69187
+ const own2 = notes.filter((note) => note.key === key);
69188
+ const pids = own2.map((note) => note.pid);
68972
69189
  const listenerPid = await listenerOf({ context, key, profile, pids });
69190
+ const waiterPid = await waiterOf({ context, key, profile });
68973
69191
  const lastClaudePid = pids.find((pid) => !context.processes.alive(pid));
69192
+ const newest = own2[0];
68974
69193
  rows.push({
68975
69194
  profile,
68976
69195
  rushId: one.id,
69196
+ key,
68977
69197
  standing: rushStandingOf({ one }),
68978
69198
  ...listenerPid ? { listenerPid } : {},
68979
- ...lastClaudePid ? { lastClaudePid } : {}
69199
+ ...waiterPid ? { waiterPid } : {},
69200
+ ...lastClaudePid ? { lastClaudePid } : {},
69201
+ ...newest ? { noted: { session: newest.session, launch: newest.launch } } : {}
68980
69202
  });
68981
69203
  }
68982
69204
  return rows;
@@ -68991,6 +69213,13 @@ async function listenerOf({
68991
69213
  const guard = await jsonOf(guardPathOf({ context, claudePid }));
68992
69214
  if (guard && context.processes.alive(guard.pid)) return guard.pid;
68993
69215
  }
69216
+ return waiterOf({ context, key, profile });
69217
+ }
69218
+ async function waiterOf({
69219
+ context,
69220
+ key,
69221
+ profile
69222
+ }) {
68994
69223
  const lock = statePathOf({ context, kind: "waiters", profile });
68995
69224
  const waiter = await jsonOf(lock);
68996
69225
  const mine4 = waiter?.sessionId === key.slice(key.indexOf(":") + 1);
@@ -69007,12 +69236,122 @@ async function rearmRushGuards({ context }) {
69007
69236
  return started;
69008
69237
  }
69009
69238
 
69239
+ // src/services/rush-watchdog.service.ts
69240
+ import { appendFile, mkdir as mkdir7 } from "node:fs/promises";
69241
+ import { dirname as dirname8, join as join10 } from "node:path";
69242
+ var UNDELIVERED_AFTER_MS = 6e4;
69243
+ var CHECK_TIMEOUT_MS = 5e3;
69244
+ function clientOf({ context, profile }) {
69245
+ return context.store.read().then((config2) => {
69246
+ const entry = config2.profiles[profile];
69247
+ if (!entry) return void 0;
69248
+ return LazeClient.create({
69249
+ baseUrl: entry.url,
69250
+ token: entry.token,
69251
+ fetcher: (input2, init) => context.fetcher(input2, { ...init, signal: AbortSignal.timeout(CHECK_TIMEOUT_MS) })
69252
+ });
69253
+ });
69254
+ }
69255
+ async function waitingOf({ context, profile }) {
69256
+ const client = await clientOf({ context, profile });
69257
+ return client?.get("/api/agents/me/inbox/waiting").catch(() => void 0);
69258
+ }
69259
+ function waitedMsOf({ waiting, nowMs }) {
69260
+ if (waiting.count === 0 || !waiting.oldestPostedAt) return 0;
69261
+ return Math.max(0, nowMs - Temporal3.Instant.from(waiting.oldestPostedAt).epochMilliseconds);
69262
+ }
69263
+ function boundAwayOf({ waiting, key }) {
69264
+ const bound = waiting.session;
69265
+ if (!bound || `${bound.harness}:${bound.sessionId}` === key) return void 0;
69266
+ return `${sessionLabelOf(bound)} (${bound.harness}:${bound.sessionId})`;
69267
+ }
69268
+ async function logDelivery({ context, line }) {
69269
+ const folder = join10(dirname8(context.environment.configPath), "connect");
69270
+ const at = Temporal3.Instant.fromEpochMilliseconds(context.nowMs());
69271
+ const stamped = `${at.toString({ smallestUnit: "second" })} ${line}
69272
+ `;
69273
+ context.out(stamped);
69274
+ await mkdir7(folder, { recursive: true, mode: 448 });
69275
+ await appendFile(join10(folder, "delivery.log"), stamped, { mode: 384 });
69276
+ }
69277
+ async function claimFor({
69278
+ context,
69279
+ client,
69280
+ row
69281
+ }) {
69282
+ const session = row.noted.session;
69283
+ const claim3 = () => forSession({ client, session }).post("/api/agents/me/inbox", {
69284
+ waitSeconds: 0
69285
+ });
69286
+ try {
69287
+ return await claim3();
69288
+ } catch (error62) {
69289
+ const meta3 = boundMetaOf({ error: error62 });
69290
+ if (!meta3) throw error62;
69291
+ const profile = row.profile;
69292
+ if (!await takeOverHere({ context, client, session, meta: meta3, profile })) {
69293
+ return `Laze binds it to ${meta3.bound ?? meta3.session ?? "another session"}, which this machine still runs; \`laze agent bind\` in rush ${row.rushId} moves it here`;
69294
+ }
69295
+ await logDelivery({
69296
+ context,
69297
+ line: `${profile}: moved the agent from ${meta3.session} to ${row.key}, which this machine binds it to`
69298
+ });
69299
+ return claim3();
69300
+ }
69301
+ }
69302
+ async function checkSession({ context, row }) {
69303
+ if (row.standing === "stopped" || !row.noted) return void 0;
69304
+ const client = await clientOf({ context, profile: row.profile });
69305
+ if (!client) return void 0;
69306
+ const waiting = await client.get("/api/agents/me/inbox/waiting");
69307
+ const waited = waitedMsOf({ waiting, nowMs: context.nowMs() });
69308
+ if (waited <= UNDELIVERED_AFTER_MS) return void 0;
69309
+ const taken = await claimFor({ context, client, row: { ...row, noted: row.noted } });
69310
+ if (typeof taken === "string") return `${row.profile}: ${waiting.count} undelivered; ${taken}`;
69311
+ if (taken.length === 0) return void 0;
69312
+ await keepTaken({ context, profile: row.profile, messages: taken });
69313
+ const self2 = await currentNameOf({ context, client, profile: row.profile });
69314
+ const env = { ...row.noted.launch, LAZE_WAKE_TEXT: hookContextOf({ messages: taken, self: self2 }) };
69315
+ const command = rushSendCommand({ id: row.rushId, program: "rush" });
69316
+ const ids = taken.map((message2) => message2.messageId);
69317
+ if (await context.runCommand({ command, env }) !== 0) {
69318
+ return `${row.profile}: rush session send ${row.rushId} failed; ${ids.join(", ")} stay for its next hook`;
69319
+ }
69320
+ await turnStarted({ context, client, agent: row.profile, messages: taken }).catch(
69321
+ () => void 0
69322
+ );
69323
+ await dropFromSpool({ context, profile: row.profile, messageIds: ids });
69324
+ const seconds = Math.round(waited / 1e3);
69325
+ await logDelivery({
69326
+ context,
69327
+ line: `${row.profile}: its hooks left ${ids.join(", ")} waiting ${seconds}s; handed over through rush ${row.rushId} (${row.standing})`
69328
+ });
69329
+ return void 0;
69330
+ }
69331
+ async function watchRushDelivery({
69332
+ context,
69333
+ said
69334
+ }) {
69335
+ for (const row of await rushListenersOf({ context })) {
69336
+ const problem = await checkSession({ context, row }).catch(
69337
+ (error62) => `${row.profile}: the delivery check failed: ${String(error62)}`
69338
+ );
69339
+ if (!problem) {
69340
+ said.delete(row.profile);
69341
+ continue;
69342
+ }
69343
+ if (said.get(row.profile) === problem) continue;
69344
+ said.set(row.profile, problem);
69345
+ await logDelivery({ context, line: problem });
69346
+ }
69347
+ }
69348
+
69010
69349
  // src/services/connect-delivery.service.ts
69011
69350
  function connectFolderOf({ context }) {
69012
- return join10(dirname8(context.environment.configPath), "connect");
69351
+ return join11(dirname9(context.environment.configPath), "connect");
69013
69352
  }
69014
69353
  function runStatePathOf({ context }) {
69015
- return join10(connectFolderOf({ context }), "run.json");
69354
+ return join11(connectFolderOf({ context }), "run.json");
69016
69355
  }
69017
69356
  async function readJson({ path }) {
69018
69357
  try {
@@ -69176,7 +69515,7 @@ async function serveRounds({
69176
69515
  }
69177
69516
  var saves = 0;
69178
69517
  async function save(run4) {
69179
- await mkdir7(dirname8(run4.path), { recursive: true, mode: 448 });
69518
+ await mkdir8(dirname9(run4.path), { recursive: true, mode: 448 });
69180
69519
  const temporary = `${run4.path}.${run4.self}.${saves += 1}.tmp`;
69181
69520
  await writeFile7(temporary, JSON.stringify(run4.state));
69182
69521
  await rename3(temporary, run4.path);
@@ -69234,6 +69573,7 @@ async function runConnectLoop({ context }) {
69234
69573
  context.out(`laze connect run: pid ${self2}
69235
69574
  `);
69236
69575
  const startedFrom = await cliStampOf({ context });
69576
+ const said = /* @__PURE__ */ new Map();
69237
69577
  const relays = RelayLoops.create({
69238
69578
  context,
69239
69579
  report: async (connectionId, relay2) => {
@@ -69248,6 +69588,10 @@ async function runConnectLoop({ context }) {
69248
69588
  await relays.sync();
69249
69589
  await rearmRushGuards({ context }).catch((error62) => {
69250
69590
  context.err(`laze connect: no rush guard check this round: ${String(error62)}
69591
+ `);
69592
+ });
69593
+ await watchRushDelivery({ context, said }).catch((error62) => {
69594
+ context.err(`laze connect: no rush delivery check this round: ${String(error62)}
69251
69595
  `);
69252
69596
  });
69253
69597
  await save(run4);
@@ -69279,17 +69623,17 @@ var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the
69279
69623
  \`laze openclaw connect --local\`, whose OpenClaw relay it also runs.
69280
69624
  `;
69281
69625
  function installedPathOf({ context }) {
69282
- return join11(connectFolderOf({ context }), "service.json");
69626
+ return join12(connectFolderOf({ context }), "service.json");
69283
69627
  }
69284
69628
  function logPathOf({ context }) {
69285
- return join11(connectFolderOf({ context }), "connect.log");
69629
+ return join12(connectFolderOf({ context }), "connect.log");
69286
69630
  }
69287
69631
  function homeOf({ context }) {
69288
- return context.environment.inherited.HOME ?? dirname9(dirname9(context.environment.configPath));
69632
+ return context.environment.inherited.HOME ?? dirname10(dirname10(context.environment.configPath));
69289
69633
  }
69290
69634
  function serviceNameOf({ context }) {
69291
69635
  const { configPath } = context.environment;
69292
- if (configPath === join11(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
69636
+ if (configPath === join12(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
69293
69637
  return `laze-connect-${createHash("sha256").update(configPath).digest("hex").slice(0, 8)}`;
69294
69638
  }
69295
69639
  function serviceEnvOf({ context }) {
@@ -69312,9 +69656,9 @@ async function run({ context, command }) {
69312
69656
  async function installSystemd({ context }) {
69313
69657
  const name3 = serviceNameOf({ context });
69314
69658
  const env = context.environment.inherited;
69315
- const base = env.XDG_CONFIG_HOME || join11(homeOf({ context }), ".config");
69316
- const file3 = join11(base, "systemd", "user", `${name3}.service`);
69317
- await mkdir8(dirname9(file3), { recursive: true });
69659
+ const base = env.XDG_CONFIG_HOME || join12(homeOf({ context }), ".config");
69660
+ const file3 = join12(base, "systemd", "user", `${name3}.service`);
69661
+ await mkdir9(dirname10(file3), { recursive: true });
69318
69662
  await writeFile8(
69319
69663
  file3,
69320
69664
  systemdUnitOf({ argv: runArgvOf({ context }), env: serviceEnvOf({ context }) })
@@ -69328,9 +69672,9 @@ async function installSystemd({ context }) {
69328
69672
  async function installLaunchd({ context }) {
69329
69673
  const name3 = serviceNameOf({ context });
69330
69674
  const label3 = `ai.laze.${name3}`;
69331
- const file3 = join11(homeOf({ context }), "Library", "LaunchAgents", `${label3}.plist`);
69675
+ const file3 = join12(homeOf({ context }), "Library", "LaunchAgents", `${label3}.plist`);
69332
69676
  const log = logPathOf({ context });
69333
- await mkdir8(dirname9(file3), { recursive: true });
69677
+ await mkdir9(dirname10(file3), { recursive: true });
69334
69678
  await writeFile8(
69335
69679
  file3,
69336
69680
  launchAgentOf({
@@ -69365,7 +69709,7 @@ async function stopInstalled({
69365
69709
  installed
69366
69710
  }) {
69367
69711
  if (installed.manager === "systemd") {
69368
- await run({ context, command: ["systemctl", "--user", "stop", `${installed.name}.service`] });
69712
+ await quietly({ context, script: `systemctl --user stop '${installed.name}.service'` });
69369
69713
  } else if (installed.manager === "launchd") {
69370
69714
  await quietly({ context, script: `launchctl bootout gui/$(id -u)/${installed.name}` });
69371
69715
  } else if (installed.pid) {
@@ -69383,13 +69727,15 @@ async function installConnectService({ context }) {
69383
69727
  const manager = await managerOf({ context });
69384
69728
  const install = { systemd: installSystemd, launchd: installLaunchd, detached: installDetached };
69385
69729
  const installed = await install[manager]({ context });
69386
- await mkdir8(dirname9(path), { recursive: true, mode: 448 });
69730
+ await mkdir9(dirname10(path), { recursive: true, mode: 448 });
69387
69731
  await writeFile8(path, JSON.stringify(installed));
69388
69732
  return describeInstalled({ installed });
69389
69733
  }
69390
69734
  async function ensureConnectService({ context }) {
69391
69735
  const running = await runStateOf({ context });
69392
69736
  if (running && context.processes.alive(running.pid)) return false;
69737
+ const installed = await readJson({ path: installedPathOf({ context }) });
69738
+ if (installed && installed.manager !== "detached") return false;
69393
69739
  await installConnectService({ context });
69394
69740
  return true;
69395
69741
  }
@@ -69420,8 +69766,11 @@ async function status2({ context }) {
69420
69766
  `
69421
69767
  );
69422
69768
  }
69423
- for (const row of await rushListenersOf({ context })) context.out(`${rushLineOf({ row })}
69769
+ for (const row of await rushListenersOf({ context })) {
69770
+ const waiting = await waitingOf({ context, profile: row.profile });
69771
+ context.out(`${rushLineOf({ row })}${inLazeOf({ row, waiting, nowMs: context.nowMs() })}
69424
69772
  `);
69773
+ }
69425
69774
  const config2 = await context.store.read();
69426
69775
  const linked = Object.entries(config2.profiles).filter(([, profile]) => profile.delivery);
69427
69776
  if (linked.length === 0) {
@@ -69436,11 +69785,31 @@ async function status2({ context }) {
69436
69785
  }
69437
69786
  function rushLineOf({ row }) {
69438
69787
  const head = `${row.profile} Claude Code in rush ${row.rushId} ${row.standing}`;
69439
- if (row.standing === "awake") return `${head}, its Claude Code delivers`;
69788
+ if (row.standing === "awake" && row.waiterPid) {
69789
+ return `${head}, its Claude Code delivers (waiter pid ${row.waiterPid})`;
69790
+ }
69791
+ if (row.standing === "awake") {
69792
+ return `${head}, no hook waiter right now: the connect service hands over what waits over ${UNDELIVERED_AFTER_MS / 1e3}s`;
69793
+ }
69440
69794
  if (row.standing === "stopped") return `${head}, gets messages when rush starts it again`;
69441
69795
  if (row.listenerPid) return `${head}, guard pid ${row.listenerPid}`;
69442
69796
  return `${head}, NO LISTENER: messages wait in Laze; \`laze connect install\` brings a guard back`;
69443
69797
  }
69798
+ function inLazeOf({
69799
+ row,
69800
+ waiting,
69801
+ nowMs
69802
+ }) {
69803
+ if (!waiting) return "; Laze could not say what waits";
69804
+ const away = boundAwayOf({ waiting, key: row.key });
69805
+ const bound = away ? `; Laze binds the agent to ${away}, not this session` : "";
69806
+ const waited = waitedMsOf({ waiting, nowMs });
69807
+ if (waiting.count === 0) return bound;
69808
+ const age = `the oldest for ${Math.round(waited / 1e3)}s`;
69809
+ if (waited > UNDELIVERED_AFTER_MS)
69810
+ return `${bound}; UNDELIVERED: ${waiting.count} waiting, ${age}`;
69811
+ return `${bound}; ${waiting.count} waiting, ${age}`;
69812
+ }
69444
69813
  async function stop({ context }) {
69445
69814
  const installed = await readJson({ path: installedPathOf({ context }) });
69446
69815
  if (!installed) {
@@ -69523,7 +69892,7 @@ async function takeLock({
69523
69892
  if (served && context.processes.alive(served) && !mine4) return false;
69524
69893
  context.processes.stop(holder.pid);
69525
69894
  }
69526
- await mkdir9(dirname10(path), { recursive: true, mode: 448 });
69895
+ await mkdir10(dirname11(path), { recursive: true, mode: 448 });
69527
69896
  await writeFile9(
69528
69897
  path,
69529
69898
  JSON.stringify({
@@ -69570,7 +69939,13 @@ async function takeRound2({
69570
69939
  async function roundOf({ context, client, name: name3, lock, claudePid, session, seen }) {
69571
69940
  if ((await holderOf({ path: lock }))?.pid !== context.processes.pid) return void 0;
69572
69941
  if (claudePid && !context.processes.alive(claudePid)) return void 0;
69573
- const due = await dueFromSpool({ context, profile: name3, seen, pushedToo: true });
69942
+ const due = await dueFromSpool({
69943
+ context,
69944
+ profile: name3,
69945
+ seen,
69946
+ pushedToo: true,
69947
+ settledOnly: true
69948
+ });
69574
69949
  if (due.length > 0) return due;
69575
69950
  if (await channelLive({ context, profile: name3 })) {
69576
69951
  await context.sleep(CHANNEL_CHECK_MS);
@@ -69681,13 +70056,13 @@ async function monitorServes({
69681
70056
  // src/services/codex-link.service.ts
69682
70057
  import { createReadStream } from "node:fs";
69683
70058
  import { readdir as readdir5, rm as rm6, stat as stat4 } from "node:fs/promises";
69684
- import { join as join13, resolve as resolve3 } from "node:path";
70059
+ import { join as join14, resolve as resolve3 } from "node:path";
69685
70060
  import { createInterface as createInterface2 } from "node:readline";
69686
70061
 
69687
70062
  // src/services/codex-adopt.service.ts
69688
70063
  import { spawn as spawn2 } from "node:child_process";
69689
- import { mkdir as mkdir10, readdir as readdir4, readFile as readFile11, rm as rm5, stat as stat3, writeFile as writeFile10 } from "node:fs/promises";
69690
- import { dirname as dirname11, join as join12 } from "node:path";
70064
+ import { mkdir as mkdir11, readdir as readdir4, readFile as readFile11, rm as rm5, stat as stat3, writeFile as writeFile10 } from "node:fs/promises";
70065
+ import { dirname as dirname12, join as join13 } from "node:path";
69691
70066
  import { createInterface } from "node:readline";
69692
70067
 
69693
70068
  // src/rules/codex-requests.rules.ts
@@ -69807,11 +70182,11 @@ var CodexAppServer = class _CodexAppServer {
69807
70182
  }
69808
70183
  };
69809
70184
  async function newestThreadId({ codexHome }) {
69810
- const root = join12(codexHome, "sessions");
70185
+ const root = join13(codexHome, "sessions");
69811
70186
  const files2 = await readdir4(root, { recursive: true }).catch(() => []);
69812
70187
  const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
69813
70188
  const dated = await Promise.all(
69814
- rollouts.map(async (file3) => ({ file: file3, at: (await stat3(join12(root, file3))).mtimeMs }))
70189
+ rollouts.map(async (file3) => ({ file: file3, at: (await stat3(join13(root, file3))).mtimeMs }))
69815
70190
  );
69816
70191
  const newest = dated.toSorted((a, b) => b.at - a.at)[0]?.file ?? "";
69817
70192
  const id2 = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/.exec(newest);
@@ -69908,7 +70283,7 @@ async function startAdoptInBackground({
69908
70283
  const adopt = ["adopt", "codex", "--profile", profile, ...threadFlag({ thread: thread2 })];
69909
70284
  const argv = [...context.program, ...adopt, "--supervise"];
69910
70285
  const pid = context.processes.spawnDetached({ argv, logPath: log });
69911
- await mkdir10(dirname11(path), { recursive: true, mode: 448 });
70286
+ await mkdir11(dirname12(path), { recursive: true, mode: 448 });
69912
70287
  await writeFile10(path, JSON.stringify({ pid, thread: thread2, log, startedAt: context.nowMs() }));
69913
70288
  return [
69914
70289
  `Started \`${laze} adopt codex\` in the background (pid ${pid}). It answers each Laze message`,
@@ -70004,7 +70379,7 @@ async function adoptedThreadOf({
70004
70379
  }
70005
70380
  const forked = record3((await codex.call("thread/fork", { threadId })).thread).id;
70006
70381
  if (typeof forked !== "string") throw new Error("thread/fork answered no thread id");
70007
- await mkdir10(dirname11(path), { recursive: true, mode: 448 });
70382
+ await mkdir11(dirname12(path), { recursive: true, mode: 448 });
70008
70383
  await writeFile10(path, JSON.stringify({ ...forks, [threadId]: forked }));
70009
70384
  context.out(
70010
70385
  `Codex holds thread ${threadId} open elsewhere; answering in its new fork ${forked}.
@@ -70076,13 +70451,13 @@ async function newestThreadIn({
70076
70451
  codexHome,
70077
70452
  directory
70078
70453
  }) {
70079
- const root = join13(codexHome, "sessions");
70454
+ const root = join14(codexHome, "sessions");
70080
70455
  const files2 = await readdir5(root, { recursive: true }).catch(() => []);
70081
70456
  const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
70082
70457
  const dated = await Promise.all(
70083
70458
  rollouts.map(async (file3) => ({
70084
- path: join13(root, file3),
70085
- at: await stat4(join13(root, file3)).then(
70459
+ path: join14(root, file3),
70460
+ at: await stat4(join14(root, file3)).then(
70086
70461
  (info) => info.mtimeMs,
70087
70462
  () => 0
70088
70463
  )
@@ -70152,9 +70527,9 @@ async function linkCodexSession({
70152
70527
  }
70153
70528
 
70154
70529
  // src/services/laze-plugin.service.ts
70155
- import { mkdir as mkdir11, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
70530
+ import { mkdir as mkdir12, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
70156
70531
  import { homedir as homedir3 } from "node:os";
70157
- import { dirname as dirname12, join as join14 } from "node:path";
70532
+ import { dirname as dirname13, join as join15 } from "node:path";
70158
70533
 
70159
70534
  // src/rules/laze-plugin.rules.ts
70160
70535
  var LAZE_PLUGIN = "laze";
@@ -70273,10 +70648,10 @@ function lazePluginFiles({
70273
70648
  var REGISTER_LIMIT_MS = 6e4;
70274
70649
  var quote2 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
70275
70650
  function pluginFolderOf({ context }) {
70276
- return join14(dirname12(context.environment.configPath), "plugins");
70651
+ return join15(dirname13(context.environment.configPath), "plugins");
70277
70652
  }
70278
70653
  async function pluginIsCurrent({ context }) {
70279
- const manifest = join14(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
70654
+ const manifest = join15(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
70280
70655
  const written = await readFile12(manifest, "utf8").then(
70281
70656
  (text2) => JSON.parse(text2).version,
70282
70657
  () => void 0
@@ -70291,8 +70666,8 @@ async function writeLazePlugin({ context }) {
70291
70666
  configPath: context.environment.configPath
70292
70667
  });
70293
70668
  for (const [path, text2] of Object.entries(files2)) {
70294
- const target = join14(folder, path);
70295
- await mkdir11(dirname12(target), { recursive: true });
70669
+ const target = join15(folder, path);
70670
+ await mkdir12(dirname13(target), { recursive: true });
70296
70671
  await writeFile11(target, text2);
70297
70672
  }
70298
70673
  return folder;
@@ -70323,8 +70698,8 @@ var RUN_FILES = ["hooks/hooks.json", "monitors/monitors.json"];
70323
70698
  async function cachedPluginOf({ context }) {
70324
70699
  const inherited = context.environment.inherited;
70325
70700
  const home = inherited.HOME || homedir3();
70326
- const claude = inherited.CLAUDE_CONFIG_DIR || join14(home, ".claude");
70327
- const listed = await readFile12(join14(claude, "plugins", "installed_plugins.json"), "utf8").then(
70701
+ const claude = inherited.CLAUDE_CONFIG_DIR || join15(home, ".claude");
70702
+ const listed = await readFile12(join15(claude, "plugins", "installed_plugins.json"), "utf8").then(
70328
70703
  (text2) => JSON.parse(text2),
70329
70704
  () => void 0
70330
70705
  );
@@ -70335,8 +70710,8 @@ async function refreshStaleCache({ context, folder }) {
70335
70710
  if (!cached2) return true;
70336
70711
  const read3 = (path) => readFile12(path, "utf8").catch(() => "");
70337
70712
  for (const file3 of RUN_FILES) {
70338
- const ours = await read3(join14(folder, LAZE_PLUGIN, file3));
70339
- if (ours === await read3(join14(cached2, file3))) continue;
70713
+ const ours = await read3(join15(folder, LAZE_PLUGIN, file3));
70714
+ if (ours === await read3(join15(cached2, file3))) continue;
70340
70715
  const plugin2 = `${LAZE_PLUGIN}@${LAZE_PLUGIN}`;
70341
70716
  const script = [
70342
70717
  `claude plugin uninstall ${plugin2} --scope user ${QUIET}`,
@@ -70347,7 +70722,7 @@ async function refreshStaleCache({ context, folder }) {
70347
70722
  return true;
70348
70723
  }
70349
70724
  function registeredMarkOf({ context }) {
70350
- return join14(pluginFolderOf({ context }), "registered");
70725
+ return join15(pluginFolderOf({ context }), "registered");
70351
70726
  }
70352
70727
  async function pluginRegistered({ context }) {
70353
70728
  return readFile12(registeredMarkOf({ context }), "utf8").then(
@@ -70364,7 +70739,7 @@ async function installLazePlugin({ context }) {
70364
70739
  async function plugin({ context, args }) {
70365
70740
  const action = args.words[1] ?? "install";
70366
70741
  if (action === "path") {
70367
- context.out(`${join14(pluginFolderOf({ context }), LAZE_PLUGIN)}
70742
+ context.out(`${join15(pluginFolderOf({ context }), LAZE_PLUGIN)}
70368
70743
  `);
70369
70744
  return 0;
70370
70745
  }
@@ -70382,8 +70757,8 @@ async function plugin({ context, args }) {
70382
70757
  }
70383
70758
 
70384
70759
  // src/services/mcp-channel.service.ts
70385
- import { mkdir as mkdir12, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
70386
- import { dirname as dirname13 } from "node:path";
70760
+ import { mkdir as mkdir13, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
70761
+ import { dirname as dirname14 } from "node:path";
70387
70762
  var LAZE_MCP_SERVER = "laze";
70388
70763
  var DEV_CHANNELS_FLAG = "--dangerously-load-development-channels";
70389
70764
  var ROUND_SECONDS3 = 50;
@@ -70473,7 +70848,7 @@ async function pushInbox({
70473
70848
  signal
70474
70849
  }) {
70475
70850
  const marker = statePathOf({ context, kind: "channels", profile });
70476
- await mkdir12(dirname13(marker), { recursive: true, mode: 448 });
70851
+ await mkdir13(dirname14(marker), { recursive: true, mode: 448 });
70477
70852
  await writeFile12(marker, JSON.stringify({ pid: context.processes.pid }));
70478
70853
  try {
70479
70854
  while (!signal.aborted) {
@@ -70501,8 +70876,8 @@ async function pushInbox({
70501
70876
  }
70502
70877
 
70503
70878
  // src/services/plugin-tip.service.ts
70504
- import { mkdir as mkdir13, readFile as readFile13, writeFile as writeFile13 } from "node:fs/promises";
70505
- import { dirname as dirname14 } from "node:path";
70879
+ import { mkdir as mkdir14, readFile as readFile13, writeFile as writeFile13 } from "node:fs/promises";
70880
+ import { dirname as dirname15 } from "node:path";
70506
70881
  var RELOAD_TIP = "Laze: the Laze plugin is installed in Claude Code, and this session has not loaded it yet. Tell the user once, in one plain line, that it is optional: typing /reload-plugins makes Laze messages arrive right away; until then they still arrive through the hooks.";
70507
70882
  var LINK_RELOAD_TIP = "Tell the user once, in one plain line, that it is optional: typing /reload-plugins makes Laze messages arrive right away; until then they still arrive through the hooks.";
70508
70883
  function monitorsRunHere({ context }) {
@@ -70536,7 +70911,7 @@ async function markReloadTipTold({
70536
70911
  }) {
70537
70912
  if (!session) return;
70538
70913
  const path = toldPathOf({ context, session });
70539
- await mkdir13(dirname14(path), { recursive: true, mode: 448 });
70914
+ await mkdir14(dirname15(path), { recursive: true, mode: 448 });
70540
70915
  await writeFile13(path, String(context.nowMs()), { mode: 384 });
70541
70916
  }
70542
70917
  async function reloadTipOnce({
@@ -70611,8 +70986,8 @@ async function installHooks({
70611
70986
  directory,
70612
70987
  profile
70613
70988
  }) {
70614
- const folder = join15(directory, ".claude");
70615
- const path = join15(folder, "settings.local.json");
70989
+ const folder = join16(directory, ".claude");
70990
+ const path = join16(folder, "settings.local.json");
70616
70991
  const current2 = await readFile14(path, "utf8").then(
70617
70992
  (text2) => JSON.parse(text2),
70618
70993
  () => ({})
@@ -70624,7 +70999,7 @@ async function installHooks({
70624
70999
  waitCommand: command("wait"),
70625
71000
  preToolCommand: command("pre-tool")
70626
71001
  });
70627
- await mkdir14(folder, { recursive: true });
71002
+ await mkdir15(folder, { recursive: true });
70628
71003
  await writeFile14(path, `${JSON.stringify(settings2, null, 2)}
70629
71004
  `);
70630
71005
  return path;
@@ -70849,7 +71224,8 @@ async function handOver({ context, args }) {
70849
71224
  context,
70850
71225
  profile: agent2,
70851
71226
  seen: () => input2.transcript_path ? readFile14(input2.transcript_path, "utf8") : Promise.resolve(""),
70852
- pushedToo: false
71227
+ pushedToo: false,
71228
+ settledOnly: true
70853
71229
  });
70854
71230
  const claim3 = forSession({ client, session });
70855
71231
  let fresh;
@@ -70888,7 +71264,7 @@ async function addSessionStartWaiter({ context, args }) {
70888
71264
  const directory = context.environment.inherited.CLAUDE_PROJECT_DIR;
70889
71265
  const profile = flagText({ args, name: "profile" });
70890
71266
  if (!directory || !profile) return;
70891
- const path = join15(directory, ".claude", "settings.local.json");
71267
+ const path = join16(directory, ".claude", "settings.local.json");
70892
71268
  const settings2 = await readFile14(path, "utf8").then(
70893
71269
  (text2) => JSON.parse(text2),
70894
71270
  () => void 0
@@ -70898,7 +71274,7 @@ async function addSessionStartWaiter({ context, args }) {
70898
71274
  }
70899
71275
  async function refreshPlugin({ context }) {
70900
71276
  if (await pluginIsCurrent({ context })) return;
70901
- const logPath = join15(pluginFolderOf({ context }), "install.log");
71277
+ const logPath = join16(pluginFolderOf({ context }), "install.log");
70902
71278
  context.processes.spawnDetached({ argv: [...context.program, "plugin", "install"], logPath });
70903
71279
  }
70904
71280
  async function stopHook({ context, args }) {
@@ -71775,8 +72151,8 @@ async function requestAgent({ context, args }) {
71775
72151
  }
71776
72152
 
71777
72153
  // src/services/app-commands.service.ts
71778
- import { mkdir as mkdir15, readdir as readdir6, readFile as readFile16, writeFile as writeFile16 } from "node:fs/promises";
71779
- import { dirname as dirname15, join as join17, relative as relative3, resolve as resolve6, sep as sep2 } from "node:path";
72154
+ import { mkdir as mkdir16, readdir as readdir6, readFile as readFile16, writeFile as writeFile16 } from "node:fs/promises";
72155
+ import { dirname as dirname16, join as join18, relative as relative3, resolve as resolve6, sep as sep2 } from "node:path";
71780
72156
 
71781
72157
  // ../../modules/app/contract/src/app.connections.ts
71782
72158
  var appFunctionNameSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/);
@@ -72032,7 +72408,8 @@ var createAppInputSchemaDefinition = external_exports.object({
72032
72408
  /** Defaults to the name in lower case words. */
72033
72409
  slug: appSlugSchema.optional(),
72034
72410
  channelId: external_exports.string().min(1).optional(),
72035
- visibility: appVisibilitySchema.default("internal")
72411
+ /** Restricted unless chosen: owner, admins, shares and the conversations it is pinned to. */
72412
+ visibility: appVisibilitySchema.default("restricted")
72036
72413
  });
72037
72414
  var createAppInputSchema = createAppInputSchemaDefinition;
72038
72415
  var listAppsInputSchemaDefinition = external_exports.object({
@@ -72211,7 +72588,8 @@ var appKeyCallerViewSchemaDefinition = external_exports.object({
72211
72588
  });
72212
72589
  var signInHandoffInputSchemaDefinition = external_exports.object({
72213
72590
  ...appRefSchemaDefinition.shape,
72214
- site: appSiteSchema,
72591
+ /** Left out, the published site when there is one, else the draft. */
72592
+ site: appSiteSchema.optional(),
72215
72593
  /** Where the app sends the person after sign-in; kept on the app's own origin. */
72216
72594
  returnPath: external_exports.string().max(2e3).default("/")
72217
72595
  });
@@ -72219,6 +72597,8 @@ var signInHandoffInputSchema = signInHandoffInputSchemaDefinition;
72219
72597
  var signInHandoffSchemaDefinition = external_exports.object({
72220
72598
  /** The app origin's callback, carrying a one-use token valid only for this app and site. */
72221
72599
  redirectUrl: external_exports.string(),
72600
+ /** The site the token opens. */
72601
+ site: appSiteSchema,
72222
72602
  expiresAt: external_exports.iso.datetime()
72223
72603
  });
72224
72604
  var signInHandoffSchema = signInHandoffSchemaDefinition;
@@ -72357,7 +72737,9 @@ var listFunctionLogsInputSchema = listFunctionLogsInputSchemaDefinition;
72357
72737
  var appFunctionSettingsSchemaDefinition = external_exports.object({
72358
72738
  workspaceId: external_exports.string().min(1),
72359
72739
  /** Off: pushes with functions are refused and every function answers app_functions_disabled. */
72360
- functionsEnabled: external_exports.boolean()
72740
+ functionsEnabled: external_exports.boolean(),
72741
+ /** On: a Builder makes an app public at once. Off: a public publish asks an admin. */
72742
+ publicAppsAllowed: external_exports.boolean()
72361
72743
  });
72362
72744
  var appFunctionSettingsSchema = appFunctionSettingsSchemaDefinition;
72363
72745
  var workspaceRefSchemaDefinition = external_exports.object({ workspaceId: external_exports.string().min(1) });
@@ -72367,6 +72749,11 @@ var setFunctionsEnabledInputSchemaDefinition = external_exports.object({
72367
72749
  enabled: external_exports.boolean()
72368
72750
  });
72369
72751
  var setFunctionsEnabledInputSchema = setFunctionsEnabledInputSchemaDefinition;
72752
+ var setPublicAppsAllowedInputSchemaDefinition = external_exports.object({
72753
+ workspaceId: external_exports.string().min(1),
72754
+ allowed: external_exports.boolean()
72755
+ });
72756
+ var setPublicAppsAllowedInputSchema = setPublicAppsAllowedInputSchemaDefinition;
72370
72757
  var appRestoreSchemaDefinition = external_exports.object({
72371
72758
  id: external_exports.string(),
72372
72759
  /** The time the data went back to; absent when the restore undid an earlier one. */
@@ -72467,7 +72854,11 @@ var appAccessSchemaDefinition = external_exports.object({
72467
72854
  /** Pending requests, to the app's Builders; empty for anyone else. */
72468
72855
  requests: external_exports.array(appAccessRequestSchemaDefinition),
72469
72856
  /** The reader's own role. */
72470
- role: appRoleSchema
72857
+ role: appRoleSchema,
72858
+ /** The workspace's name, for "Everyone in <workspace>". */
72859
+ workspaceName: external_exports.string(),
72860
+ /** Whether a Builder makes it public without asking an admin. */
72861
+ publicAppsAllowed: external_exports.boolean()
72471
72862
  });
72472
72863
  var appAccessSchema = appAccessSchemaDefinition;
72473
72864
  var grantAppAccessInputSchemaDefinition = external_exports.object({
@@ -72859,7 +73250,9 @@ var pinAppInputSchemaDefinition = external_exports.object({
72859
73250
  workspaceId: external_exports.string().min(1),
72860
73251
  appId: external_exports.string().min(1),
72861
73252
  /** The conversation, by id or by channel name with or without `#`. */
72862
- channel: external_exports.string().trim().min(1).max(120)
73253
+ channel: external_exports.string().trim().min(1).max(120),
73254
+ /** What the conversation's members may do: editor unless the pinner picked view-only. */
73255
+ role: external_exports.enum(["viewer", "editor"]).optional()
72863
73256
  });
72864
73257
  var pinAppInputSchema = pinAppInputSchemaDefinition;
72865
73258
  var channelPinsInputSchemaDefinition = external_exports.object({
@@ -72885,7 +73278,9 @@ var reorderPinsInputSchema = reorderPinsInputSchemaDefinition;
72885
73278
  var pinAppByKeyInputSchemaDefinition = external_exports.object({
72886
73279
  appId: external_exports.string().min(1),
72887
73280
  /** Absent in an agent's turn means the conversation the turn runs in. */
72888
- channel: external_exports.string().trim().min(1).max(120).optional()
73281
+ channel: external_exports.string().trim().min(1).max(120).optional(),
73282
+ /** On a pin: what the conversation's members may do, editor unless view-only. */
73283
+ role: external_exports.enum(["viewer", "editor"]).optional()
72889
73284
  });
72890
73285
  var channelPinsByKeyInputSchemaDefinition = channelPinsInputSchemaDefinition.omit({
72891
73286
  workspaceId: true
@@ -72935,7 +73330,7 @@ var appBackupCheckAlertsSchemaDefinition = external_exports.object({
72935
73330
  });
72936
73331
 
72937
73332
  // ../../modules/app/contract/src/app.trpc.ts
72938
- var appMainTrpc = defineTrpcContract("app").query("list").withInput(listAppsInputSchema).withOutput(external_exports.array(appSchema)).query("get").withInput(appRefSchema).withOutput(appSchema).mutation("create").withInput(createAppInputSchema).withOutput(appSchema).mutation("rename").withInput(renameAppInputSchema).withOutput(appSchema).mutation("archive").withInput(appRefSchema).withOutput(appSchema).mutation("unarchive").withInput(appRefSchema).withOutput(appSchema).mutation("delete").withInput(deleteAppInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).query("versions").withInput(appRefSchema).withOutput(external_exports.array(appVersionSchema)).mutation("revert").withInput(revertInputSchema).withOutput(appVersionSchema).mutation("publish").withInput(publishInputSchema).withOutput(publishOutcomeSchema).query("collections").withInput(siteRefSchema).withOutput(external_exports.array(collectionSchema)).query("records").withInput(listRecordsInputSchema).withOutput(recordPageSchema).mutation("writeRecord").withInput(writeRecordInputSchema).withOutput(appRecordSchema).mutation("deleteRecord").withInput(deleteRecordInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).query("views").withInput(siteRefSchema).withOutput(external_exports.array(appViewSchema)).mutation("saveView").withInput(saveViewInputSchema).withOutput(appViewSchema).mutation("deleteView").withInput(deleteViewInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).mutation("chooseCardRows").withInput(chooseCardRowsInputSchema).withOutput(appCardChoiceSchema).query("exportRecords").withInput(exportRecordsInputSchema).withOutput(recordExportSchema).mutation("importRecords").withInput(importRecordsInputSchema).withOutput(recordImportSchema).mutation("decidePublish").withInput(decidePublishInputSchema).withOutput(publishOutcomeSchema).mutation("nameVersion").withInput(nameVersionInputSchema).withOutput(appVersionSchema).mutation("makeInternal").withInput(appRefSchema).withOutput(appSchema).mutation("revokePublishLease").withInput(appRefSchema).withOutput(appSchema).mutation("signInHandoff").withInput(signInHandoffInputSchema).withOutput(signInHandoffSchema).query("functionLogs").withInput(listFunctionLogsInputSchema).withOutput(external_exports.array(appFunctionLogEntrySchema)).query("functionSettings").withInput(appWorkspaceRefSchema).withOutput(appFunctionSettingsSchema).query("access").withInput(appRefSchema).withOutput(appAccessSchema).query("members").withInput(appRefSchema).withOutput(appMembersSchema).mutation("grantAccess").withInput(grantAppAccessInputSchema).withOutput(appAccessSchema).mutation("revokeAccess").withInput(revokeAppAccessInputSchema).withOutput(appAccessSchema).mutation("setVisibility").withInput(setAppVisibilityInputSchema).withOutput(visibilityOutcomeSchema).mutation("setMemberRole").withInput(setMemberRoleInputSchema).withOutput(appAccessSchema).mutation("unpublish").withInput(appRefSchema).withOutput(appSchema).query("door").withInput(appRefSchema).withOutput(appDoorSchema).mutation("requestAccess").withInput(appRefSchema).withOutput(appDoorSchema).mutation("decideAccess").withInput(decideAppAccessInputSchema).withOutput(appAccessRequestSchema).query("users").withInput(appRefSchema).withOutput(appUsersSchema).mutation("blockUser").withInput(blockAppUserInputSchema).withOutput(appUsersSchema).mutation("deleteUser").withInput(deleteAppUserInputSchema).withOutput(deletedAppUserSchema).mutation("setFunctionsEnabled").withInput(setFunctionsEnabledInputSchema).withOutput(appFunctionSettingsSchema).query("backups").withInput(appRefSchema).withOutput(appBackupStatusSchema).mutation("restoreData").withInput(restoreAppDataInputSchema).withOutput(appRestoreSchema).query("cost").withInput(appRefSchema).withOutput(appCostSchema).mutation("setBudget").withInput(setAppBudgetInputSchema).withOutput(appCostSchema).query("triggers").withInput(appRefSchema).withOutput(appTriggersSchema).mutation("setTriggerPaused").withInput(setAppTriggerPausedInputSchema).withOutput(appTriggerSchema).mutation("removeTrigger").withInput(appTriggerRefSchema).withOutput(external_exports.object({ removed: external_exports.literal(true) })).build();
73333
+ var appMainTrpc = defineTrpcContract("app").query("list").withInput(listAppsInputSchema).withOutput(external_exports.array(appSchema)).query("get").withInput(appRefSchema).withOutput(appSchema).mutation("create").withInput(createAppInputSchema).withOutput(appSchema).mutation("rename").withInput(renameAppInputSchema).withOutput(appSchema).mutation("archive").withInput(appRefSchema).withOutput(appSchema).mutation("unarchive").withInput(appRefSchema).withOutput(appSchema).mutation("delete").withInput(deleteAppInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).query("versions").withInput(appRefSchema).withOutput(external_exports.array(appVersionSchema)).mutation("revert").withInput(revertInputSchema).withOutput(appVersionSchema).mutation("publish").withInput(publishInputSchema).withOutput(publishOutcomeSchema).query("collections").withInput(siteRefSchema).withOutput(external_exports.array(collectionSchema)).query("records").withInput(listRecordsInputSchema).withOutput(recordPageSchema).mutation("writeRecord").withInput(writeRecordInputSchema).withOutput(appRecordSchema).mutation("deleteRecord").withInput(deleteRecordInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).query("views").withInput(siteRefSchema).withOutput(external_exports.array(appViewSchema)).mutation("saveView").withInput(saveViewInputSchema).withOutput(appViewSchema).mutation("deleteView").withInput(deleteViewInputSchema).withOutput(external_exports.object({ deleted: external_exports.literal(true) })).mutation("chooseCardRows").withInput(chooseCardRowsInputSchema).withOutput(appCardChoiceSchema).query("exportRecords").withInput(exportRecordsInputSchema).withOutput(recordExportSchema).mutation("importRecords").withInput(importRecordsInputSchema).withOutput(recordImportSchema).mutation("decidePublish").withInput(decidePublishInputSchema).withOutput(publishOutcomeSchema).mutation("nameVersion").withInput(nameVersionInputSchema).withOutput(appVersionSchema).mutation("makeInternal").withInput(appRefSchema).withOutput(appSchema).mutation("revokePublishLease").withInput(appRefSchema).withOutput(appSchema).mutation("signInHandoff").withInput(signInHandoffInputSchema).withOutput(signInHandoffSchema).query("functionLogs").withInput(listFunctionLogsInputSchema).withOutput(external_exports.array(appFunctionLogEntrySchema)).query("functionSettings").withInput(appWorkspaceRefSchema).withOutput(appFunctionSettingsSchema).query("access").withInput(appRefSchema).withOutput(appAccessSchema).query("members").withInput(appRefSchema).withOutput(appMembersSchema).mutation("grantAccess").withInput(grantAppAccessInputSchema).withOutput(appAccessSchema).mutation("revokeAccess").withInput(revokeAppAccessInputSchema).withOutput(appAccessSchema).mutation("setVisibility").withInput(setAppVisibilityInputSchema).withOutput(visibilityOutcomeSchema).mutation("setMemberRole").withInput(setMemberRoleInputSchema).withOutput(appAccessSchema).mutation("unpublish").withInput(appRefSchema).withOutput(appSchema).query("door").withInput(appRefSchema).withOutput(appDoorSchema).mutation("requestAccess").withInput(appRefSchema).withOutput(appDoorSchema).mutation("decideAccess").withInput(decideAppAccessInputSchema).withOutput(appAccessRequestSchema).query("users").withInput(appRefSchema).withOutput(appUsersSchema).mutation("blockUser").withInput(blockAppUserInputSchema).withOutput(appUsersSchema).mutation("deleteUser").withInput(deleteAppUserInputSchema).withOutput(deletedAppUserSchema).mutation("setFunctionsEnabled").withInput(setFunctionsEnabledInputSchema).withOutput(appFunctionSettingsSchema).mutation("setPublicAppsAllowed").withInput(setPublicAppsAllowedInputSchema).withOutput(appFunctionSettingsSchema).query("backups").withInput(appRefSchema).withOutput(appBackupStatusSchema).mutation("restoreData").withInput(restoreAppDataInputSchema).withOutput(appRestoreSchema).query("cost").withInput(appRefSchema).withOutput(appCostSchema).mutation("setBudget").withInput(setAppBudgetInputSchema).withOutput(appCostSchema).query("triggers").withInput(appRefSchema).withOutput(appTriggersSchema).mutation("setTriggerPaused").withInput(setAppTriggerPausedInputSchema).withOutput(appTriggerSchema).mutation("removeTrigger").withInput(appTriggerRefSchema).withOutput(external_exports.object({ removed: external_exports.literal(true) })).build();
72939
73334
  var appConnectionsTrpc = defineTrpcContract("app").query("connections").withInput(appRefSchema).withOutput(appConnectionsSchema).mutation("allowConnection").withInput(appConnectionRefSchema).withOutput(appConnectionsSchema).mutation("revokeConnection").withInput(appConnectionRefSchema).withOutput(appConnectionsSchema).build();
72940
73335
  var appPinsTrpc = defineTrpcContract("app").query("pins").withInput(channelPinsInputSchema).withOutput(channelAppPinsSchema).mutation("pin").withInput(pinAppInputSchema).withOutput(channelAppPinsSchema).mutation("unpin").withInput(pinAppInputSchema).withOutput(channelAppPinsSchema).mutation("setPinView").withInput(setPinViewInputSchema).withOutput(channelAppPinsSchema).mutation("reorderPins").withInput(reorderPinsInputSchema).withOutput(channelAppPinsSchema).build();
72941
73336
  var appTrpc = joinTrpcContracts("app", appMainTrpc, appConnectionsTrpc, appPinsTrpc);
@@ -72978,6 +73373,7 @@ var renameAppByKeyInputSchemaDefinition = renameAppInputSchema.omit(byKey);
72978
73373
  var deleteAppByKeyInputSchemaDefinition = deleteAppInputSchema.omit(byKey);
72979
73374
  var functionSettingsByKeyInputSchemaDefinition = external_exports.object({});
72980
73375
  var setFunctionsEnabledByKeyInputSchemaDefinition = setFunctionsEnabledInputSchema.omit(byKey);
73376
+ var setPublicAppsAllowedByKeyInputSchemaDefinition = setPublicAppsAllowedInputSchema.omit(byKey);
72981
73377
  var restoreDataByKeyInputSchemaDefinition = external_exports.object({
72982
73378
  ...appByKeySchemaDefinition.shape,
72983
73379
  /** The time to go back to, ISO 8601. */
@@ -73058,8 +73454,8 @@ var appCliCommands = [
73058
73454
  {
73059
73455
  command: "laze app publish",
73060
73456
  operation: "requestPublish",
73061
- arguments: ["[version]", "--visibility internal|public"],
73062
- summary: "Publish for the workspace now; a public publish waits for an approval"
73457
+ arguments: ["[version]", "--visibility restricted|channel|internal|public"],
73458
+ summary: "Publish now for the people who can open the app; opening it to more people waits for an approval"
73063
73459
  },
73064
73460
  {
73065
73461
  command: "laze app make-internal",
@@ -73172,8 +73568,8 @@ var appCliCommands = [
73172
73568
  {
73173
73569
  command: "laze app pin",
73174
73570
  operation: "pinApp",
73175
- arguments: ["[app]", "--channel <c>"],
73176
- summary: "Pin the app as a tab of a channel or chat for everyone in it, who may then open it; an app an agent creates or publishes from a conversation is pinned there on its own"
73571
+ arguments: ["[app]", "--channel <c>", "--view-only"],
73572
+ summary: "Pin the app as a tab of a channel or chat; everyone in it and their agents may then edit it, or only view it with --view-only. An app an agent creates or publishes from a conversation is pinned there on its own"
73177
73573
  },
73178
73574
  {
73179
73575
  command: "laze app unpin",
@@ -73223,6 +73619,12 @@ var appCliCommands = [
73223
73619
  arguments: ["[on|off]"],
73224
73620
  summary: "Whether the workspace's apps run server functions; on and off need an admin"
73225
73621
  },
73622
+ {
73623
+ command: "laze app public-apps",
73624
+ operation: "setPublicAppsAllowed",
73625
+ arguments: ["[on|off]"],
73626
+ summary: "Whether Builders make apps public without asking an admin (on by default); on and off need an admin"
73627
+ },
73226
73628
  {
73227
73629
  command: "laze app backups",
73228
73630
  operation: "getBackups",
@@ -74057,6 +74459,18 @@ var functions = async ({ context, args, signed: signed2 }) => {
74057
74459
  const text2 = settings2.functionsEnabled ? "Server functions are on for this workspace's apps.\n" : "Server functions are off: pushes with functions are refused and every function answers app_functions_disabled.\n";
74058
74460
  print2({ context, args, value: settings2, text: text2 });
74059
74461
  };
74462
+ var publicApps = async ({ context, args, signed: signed2 }) => {
74463
+ const word3 = args.words[2];
74464
+ if (word3 !== void 0 && word3 !== "on" && word3 !== "off") {
74465
+ throw new CliUsageError("Usage: laze app public-apps [on|off]");
74466
+ }
74467
+ const client = await signed2();
74468
+ const settings2 = word3 === void 0 ? await client.post("/api/apps/functions", {}) : await client.post("/api/apps/public-apps", {
74469
+ allowed: word3 === "on"
74470
+ });
74471
+ const text2 = settings2.publicAppsAllowed ? "Public apps are allowed: a Builder makes an app public without asking an admin.\n" : "Public apps ask an admin first: making an app public waits for an Owner or Admin to approve.\n";
74472
+ print2({ context, args, value: settings2, text: text2 });
74473
+ };
74060
74474
  function backupsText({ name: name3, status: status9 }) {
74061
74475
  const window2 = status9.from && status9.to ? `A restore can go back to any time from ${status9.from} to ${status9.to}.` : "Nothing to restore to yet.";
74062
74476
  const replicating = status9.replicating ? "The published data replicates to object storage." : "The published data does not replicate on this host.";
@@ -74137,6 +74551,7 @@ var appManageCommands = {
74137
74551
  delete: remove,
74138
74552
  "revoke-lease": revokeLease,
74139
74553
  functions,
74554
+ "public-apps": publicApps,
74140
74555
  backups,
74141
74556
  restore,
74142
74557
  users,
@@ -74189,16 +74604,19 @@ async function appPinCommand({
74189
74604
  }) {
74190
74605
  const channel = flagText({ args, name: "channel" });
74191
74606
  const { client, appId, name: name3 } = await open3();
74607
+ const viewOnly = verb === "pin" && Boolean(args.flags["view-only"]);
74192
74608
  const listed = await client.post(`/api/apps/${verb}`, {
74193
74609
  appId,
74194
- ...channel ? { channel } : {}
74610
+ ...channel ? { channel } : {},
74611
+ ...viewOnly ? { role: "viewer" } : {}
74195
74612
  });
74196
74613
  const where = channel || "this conversation";
74614
+ const may = viewOnly ? "may open and read the app" : "may open and edit the app";
74197
74615
  print3({
74198
74616
  context,
74199
74617
  args,
74200
74618
  value: listed,
74201
- text: verb === "pin" ? `Pinned ${name3} to ${where}: everyone in it sees the tab and may open the app.
74619
+ text: verb === "pin" ? `Pinned ${name3} to ${where}: everyone in it and their agents see the tab and ${may}.
74202
74620
  ` : `Unpinned ${name3} from ${where}. The app and its data stay.
74203
74621
  `
74204
74622
  });
@@ -74221,7 +74639,7 @@ async function appPinsCommand({
74221
74639
  import { execFile } from "node:child_process";
74222
74640
  import { mkdtemp, rm as rm8, writeFile as writeFile15 } from "node:fs/promises";
74223
74641
  import { tmpdir } from "node:os";
74224
- import { join as join16 } from "node:path";
74642
+ import { join as join17 } from "node:path";
74225
74643
  import { promisify } from "node:util";
74226
74644
  var run2 = promisify(execFile);
74227
74645
  var MODULE_SYNTAX = /^\s*(import|export)\s/m;
@@ -74250,11 +74668,11 @@ async function scriptErrorsOf({
74250
74668
  const unknown2 = unknownCollectionsOf({ files: files2, collections });
74251
74669
  const scripts = files2.flatMap(scriptsOf);
74252
74670
  if (scripts.length === 0) return unknown2;
74253
- const dir = await mkdtemp(join16(tmpdir(), "laze-app-check-"));
74671
+ const dir = await mkdtemp(join17(tmpdir(), "laze-app-check-"));
74254
74672
  try {
74255
74673
  const errors = await Promise.all(
74256
74674
  scripts.map(async (script, index) => {
74257
- const file3 = join16(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
74675
+ const file3 = join17(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
74258
74676
  await writeFile15(file3, script.code);
74259
74677
  try {
74260
74678
  await run2(process.execPath, ["--check", file3]);
@@ -74430,7 +74848,7 @@ function folderOf({ context, word: word3 }) {
74430
74848
  return resolve6(context.cwd, word3 ?? ".");
74431
74849
  }
74432
74850
  async function readManifest(folder) {
74433
- const text2 = await readFile16(join17(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
74851
+ const text2 = await readFile16(join18(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
74434
74852
  if (text2 === void 0) return void 0;
74435
74853
  const parsed = appManifestSchema.safeParse(JSON.parse(text2));
74436
74854
  if (!parsed.success) {
@@ -74478,7 +74896,7 @@ async function listFiles(folder) {
74478
74896
  while (pending.length > 0 && found.length <= MAX_FILES) {
74479
74897
  const current2 = pending.pop() ?? folder;
74480
74898
  for (const entry of await readdir6(current2, { withFileTypes: true })) {
74481
- const path = join17(current2, entry.name);
74899
+ const path = join18(current2, entry.name);
74482
74900
  const rel = relative3(folder, path).split(sep2).join("/");
74483
74901
  if (isSkippedPath({ path: rel })) continue;
74484
74902
  if (entry.isDirectory()) pending.push(path);
@@ -74519,11 +74937,11 @@ var appCreate = async ({ context, args }) => {
74519
74937
  ...visibility ? { visibility } : {}
74520
74938
  });
74521
74939
  const folder = resolve6(context.cwd, flagText({ args, name: "dir", fallback: app2.slug }));
74522
- await mkdir15(folder, { recursive: true });
74940
+ await mkdir16(folder, { recursive: true });
74523
74941
  const files2 = template ? templateFiles({ template, name: name3 }) : {};
74524
74942
  for (const [path, content] of Object.entries(files2)) {
74525
- await mkdir15(dirname15(join17(folder, path)), { recursive: true });
74526
- await writeFile16(join17(folder, path), content);
74943
+ await mkdir16(dirname16(join18(folder, path)), { recursive: true });
74944
+ await writeFile16(join18(folder, path), content);
74527
74945
  }
74528
74946
  const manifest = {
74529
74947
  app: { id: app2.id, name: app2.name, slug: app2.slug },
@@ -74531,7 +74949,7 @@ var appCreate = async ({ context, args }) => {
74531
74949
  views: template?.views ? [...template.views] : [],
74532
74950
  seed: template ? { ...template.seed } : {}
74533
74951
  };
74534
- await writeFile16(join17(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74952
+ await writeFile16(join18(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74535
74953
  `);
74536
74954
  print5({
74537
74955
  context,
@@ -74700,8 +75118,8 @@ var appPull = async ({ context, args }) => {
74700
75118
  );
74701
75119
  }
74702
75120
  for (const file3 of pulled.files) {
74703
- const target = join17(folder, ...file3.path.split("/"));
74704
- await mkdir15(dirname15(target), { recursive: true });
75121
+ const target = join18(folder, ...file3.path.split("/"));
75122
+ await mkdir16(dirname16(target), { recursive: true });
74705
75123
  await writeFile16(
74706
75124
  target,
74707
75125
  file3.encoding === "base64" ? Buffer.from(file3.content, "base64") : file3.content
@@ -74719,7 +75137,7 @@ var appPull = async ({ context, args }) => {
74719
75137
  ])
74720
75138
  )
74721
75139
  };
74722
- await writeFile16(join17(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
75140
+ await writeFile16(join18(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74723
75141
  `);
74724
75142
  const names = pulled.collections.map((collection) => collection.name);
74725
75143
  const where = relative3(context.cwd, folder) || ".";
@@ -74749,16 +75167,22 @@ var appPublish = async ({ context, args }) => {
74749
75167
  });
74750
75168
  print5({ context, args, value: outcome, text: publishLine(outcome) });
74751
75169
  };
75170
+ var PUBLISH_AUDIENCE = {
75171
+ restricted: "the people it is shared with and its pinned channels",
75172
+ channel: "its channel",
75173
+ internal: "the workspace",
75174
+ public: "everyone"
75175
+ };
74752
75176
  function publishLine(outcome) {
74753
75177
  const { request: request2 } = outcome;
74754
75178
  if (request2.status === "pending") {
74755
- return `Waiting for approval (${request2.id}): a public publish needs a workspace admin's yes.
75179
+ return `Waiting for approval (${request2.id}): opening the app to more people needs a workspace admin's yes.
74756
75180
  They see a publish card in their Laze feed and on the app's page, and can approve once, for 24 hours or always for this app.
74757
75181
  Nothing changes for visitors until then; the request expires after 72 hours.
74758
75182
  `;
74759
75183
  }
74760
75184
  if (request2.status === "denied") return "The publish was denied.\n";
74761
- const audience = request2.visibility === "public" ? "everyone" : "the workspace";
75185
+ const audience = PUBLISH_AUDIENCE[request2.visibility];
74762
75186
  return `Published ${request2.version.slice(0, 7)} for ${audience}: ${outcome.app.publishedUrl}
74763
75187
  `;
74764
75188
  }
@@ -75356,6 +75780,7 @@ var APP_COMMANDS = {
75356
75780
  delete: managed(appManageCommands.delete),
75357
75781
  "revoke-lease": managed(appManageCommands["revoke-lease"]),
75358
75782
  functions: managed(appManageCommands.functions),
75783
+ "public-apps": managed(appManageCommands["public-apps"]),
75359
75784
  backups: managed(appManageCommands.backups),
75360
75785
  restore: managed(appManageCommands.restore),
75361
75786
  users: managed(appManageCommands.users),
@@ -75513,6 +75938,15 @@ ${BILLING_USAGE}`);
75513
75938
  }
75514
75939
  return value;
75515
75940
  }
75941
+ function prepaidNoteOf(account, of) {
75942
+ const { prepaid, overdraft = 0, welcome = 0 } = account.credits;
75943
+ const notes = [
75944
+ prepaid < 0 ? `${of(-prepaid)} owed, paid first by the next top-up` : null,
75945
+ overdraft > 0 ? `may go down to -${of(overdraft)}` : null,
75946
+ welcome > 0 ? `welcome credit, ${of(welcome)}` : null
75947
+ ].filter((note) => note !== null);
75948
+ return notes.length > 0 ? ` (${notes.join(", ")})` : "";
75949
+ }
75516
75950
  function printAccount({ context, args }, account) {
75517
75951
  if (args.flags.json) return printJson(context, account);
75518
75952
  const of = (amount) => money(amount, account.currency);
@@ -75521,7 +75955,7 @@ function printAccount({ context, args }, account) {
75521
75955
  context.out(`Plan: ${plan2}${pending}
75522
75956
  `);
75523
75957
  context.out(
75524
- `Credits: ${of(account.credits.includedLeft)} of ${of(account.credits.included)} included left, ${of(account.credits.prepaid)} prepaid${account.credits.welcome ? ` (welcome credit, ${of(account.credits.welcome)})` : ""}${account.credits.paused ? " (paused: top up to resume)" : ""}
75958
+ `Credits: ${of(account.credits.includedLeft)} of ${of(account.credits.included)} included left, ${of(account.credits.prepaid)} prepaid${prepaidNoteOf(account, of)}${account.credits.paused ? " (paused: top up to resume)" : ""}
75525
75959
  `
75526
75960
  );
75527
75961
  const recharge = account.autoRecharge;
@@ -75632,8 +76066,8 @@ async function billing({ context, args }) {
75632
76066
 
75633
76067
  // src/services/browser-commands.service.ts
75634
76068
  import { randomBytes } from "node:crypto";
75635
- import { mkdir as mkdir16, readFile as readFile17, writeFile as writeFile17 } from "node:fs/promises";
75636
- import { dirname as dirname16, join as join18 } from "node:path";
76069
+ import { mkdir as mkdir17, readFile as readFile17, writeFile as writeFile17 } from "node:fs/promises";
76070
+ import { dirname as dirname17, join as join19 } from "node:path";
75637
76071
 
75638
76072
  // src/services/browser-tab-commands.service.ts
75639
76073
  var BROWSER_TAB_PATHS = {
@@ -76174,22 +76608,30 @@ var USAGE6 = [
76174
76608
  "",
76175
76609
  BROWSER_TAB_USAGE
76176
76610
  ].join("\n");
76177
- async function turnTokenOf2({ context }) {
76611
+ async function turnTokenOf2({
76612
+ context,
76613
+ args,
76614
+ client,
76615
+ agent: agent2
76616
+ }) {
76178
76617
  const env = context.environment.inherited;
76179
76618
  const pinned = env.LAZE_TURN_TOKEN?.trim();
76180
76619
  if (pinned) return pinned;
76181
- if (!env.LAZE_TURN_FILE) return "";
76182
- return readFile17(env.LAZE_TURN_FILE, "utf8").then(
76183
- (text2) => text2.trim(),
76184
- () => ""
76185
- );
76620
+ if (env.LAZE_TURN_FILE) {
76621
+ return readFile17(env.LAZE_TURN_FILE, "utf8").then(
76622
+ (text2) => text2.trim(),
76623
+ () => ""
76624
+ );
76625
+ }
76626
+ if (!agent2) return "";
76627
+ return connectedTurnTokenOf({ client, channelId: flagText({ args, name: "channel" }) || null });
76186
76628
  }
76187
76629
  async function computeClient({
76188
76630
  context,
76189
76631
  args
76190
76632
  }) {
76191
- const { client } = await signedIn({ context, args });
76192
- const turn = await turnTokenOf2({ context });
76633
+ const { client, profile } = await signedIn({ context, args });
76634
+ const turn = await turnTokenOf2({ context, args, client, agent: profile.kind === "agent" });
76193
76635
  return turn ? client.withHeaders({ "x-laze-turn": turn }) : client;
76194
76636
  }
76195
76637
  function siteLine(machine2) {
@@ -76253,7 +76695,7 @@ async function cdp({ context, args }) {
76253
76695
  }
76254
76696
  function bridgeStatePath({ context, machine: machine2 }) {
76255
76697
  const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
76256
- return join18(dirname16(context.environment.configPath), "bridges", `${safe}.json`);
76698
+ return join19(dirname17(context.environment.configPath), "bridges", `${safe}.json`);
76257
76699
  }
76258
76700
  async function bridgePort({
76259
76701
  context,
@@ -76274,7 +76716,7 @@ async function bridgePort({
76274
76716
  key,
76275
76717
  ...target
76276
76718
  });
76277
- await mkdir16(dirname16(path), { recursive: true, mode: 448 });
76719
+ await mkdir17(dirname17(path), { recursive: true, mode: 448 });
76278
76720
  await writeFile17(path, JSON.stringify({ port, key }), { mode: 384 });
76279
76721
  return port;
76280
76722
  }
@@ -77451,7 +77893,13 @@ async function deliverOnce({
77451
77893
  }
77452
77894
  const named = { ...args, flags: { ...args.flags, profile } };
77453
77895
  const { client } = await signedIn({ context, args: named });
77454
- const due = await dueFromSpool({ context, profile, seen: async () => "", pushedToo: true });
77896
+ const due = await dueFromSpool({
77897
+ context,
77898
+ profile,
77899
+ seen: async () => "",
77900
+ pushedToo: true,
77901
+ settledOnly: true
77902
+ });
77455
77903
  const taken = due.length > 0 ? [] : await takeRound2({ context, client, claudePid, session });
77456
77904
  const messages = [...due, ...taken];
77457
77905
  if (messages.length === 0) {
@@ -77871,9 +78319,11 @@ var billingAccountViewDefinition = external_exports.object({
77871
78319
  /** Included this period by the plan. */
77872
78320
  included: external_exports.number(),
77873
78321
  includedLeft: external_exports.number(),
77874
- /** The prepaid balance; a little below zero when the last call overshot it. */
78322
+ /** The prepaid balance; below zero while the workspace owes usage the next top-up pays. */
77875
78323
  prepaid: external_exports.number(),
77876
- /** The one-off welcome credit this workspace got; 0 when it got none. */
78324
+ /** How far below zero the prepaid balance may go before usage pauses; 0 when not at all. */
78325
+ overdraft: external_exports.number().default(0),
78326
+ /** The one-off welcome credit given before 2026-10-21; 0 when it got none. */
77877
78327
  welcome: external_exports.number().default(0),
77878
78328
  paused: external_exports.boolean(),
77879
78329
  pauseReason: pauseReasonSchema.nullable()
@@ -79656,7 +80106,7 @@ var judgeStatus = async ({ context, args }) => {
79656
80106
  const status9 = await client.get("/api/vault/judge");
79657
80107
  if (args.flags.json) return printJson4({ context, data: status9 });
79658
80108
  context.out(
79659
- status9.configured ? "The judge is set up: Checked uses are decided by it.\n" : "No judge is set up: every Checked use asks a person.\n"
80109
+ status9.configured ? "Automatic approval is on: Laze checks each Auto use against the key's rules.\n" : "Automatic approval is switched off: every Auto use waits for your OK.\n"
79660
80110
  );
79661
80111
  };
79662
80112
  var listDevices = async ({ context, args }) => {
@@ -79675,9 +80125,9 @@ var listDevices = async ({ context, args }) => {
79675
80125
 
79676
80126
  // src/services/vault-commands.service.ts
79677
80127
  import { createHash as createHash2 } from "node:crypto";
79678
- import { mkdir as mkdir17, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
80128
+ import { mkdir as mkdir18, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
79679
80129
  import { tmpdir as tmpdir2 } from "node:os";
79680
- import { dirname as dirname17, join as join19 } from "node:path";
80130
+ import { dirname as dirname18, join as join20 } from "node:path";
79681
80131
  var USAGE8 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
79682
80132
  Runs the command with the connection's values in its environment, on a Laze agent's computer,
79683
80133
  on a machine it runs on, or where a connected agent runs, with its own key.
@@ -79724,8 +80174,8 @@ function runKeyPathOf({
79724
80174
  profile = ""
79725
80175
  }) {
79726
80176
  const name3 = createHash2("sha256").update(connection).digest("hex");
79727
- const base = turnFile ? dirname17(turnFile) : join19(tmpdir2(), "laze-vault", profile);
79728
- return join19(base, "vault-run-keys", `${name3}.json`);
80177
+ const base = turnFile ? dirname18(turnFile) : join20(tmpdir2(), "laze-vault", profile);
80178
+ return join20(base, "vault-run-keys", `${name3}.json`);
79729
80179
  }
79730
80180
  async function runKeyAt({ path }) {
79731
80181
  const saved3 = await readFile22(path, "utf8").then(
@@ -79738,7 +80188,7 @@ async function runKeyAt({ path }) {
79738
80188
  }
79739
80189
  const fresh = await generateEcdhKeys();
79740
80190
  const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
79741
- await mkdir17(dirname17(path), { recursive: true, mode: 448 });
80191
+ await mkdir18(dirname18(path), { recursive: true, mode: 448 });
79742
80192
  await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
79743
80193
  mode: 384
79744
80194
  });
@@ -80694,8 +81144,8 @@ var DOMAINS_USAGE = `Usage:
80694
81144
  var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
80695
81145
  `);
80696
81146
  function printDomain(context, row) {
80697
- const join23 = row.autoJoin ? "auto-join on" : "auto-join off";
80698
- context.out(`${row.domain} ${join23}${row.enforced ? " single sign-on enforced" : ""}
81147
+ const join24 = row.autoJoin ? "auto-join on" : "auto-join off";
81148
+ context.out(`${row.domain} ${join24}${row.enforced ? " single sign-on enforced" : ""}
80699
81149
  `);
80700
81150
  }
80701
81151
  async function list4({ context, args }) {
@@ -80730,131 +81180,6 @@ async function domains({ context, args }) {
80730
81180
  import { readFile as readFile26 } from "node:fs/promises";
80731
81181
  import { resolve as resolve10 } from "node:path";
80732
81182
 
80733
- // src/rules/feed-input.rules.ts
80734
- function csvCellsOf(line) {
80735
- const cells = [];
80736
- let cell = "";
80737
- let quoted = false;
80738
- for (let at = 0; at < line.length; at += 1) {
80739
- const char = line[at];
80740
- if (quoted && char === '"' && line[at + 1] === '"') {
80741
- cell += '"';
80742
- at += 1;
80743
- } else if (char === '"') {
80744
- quoted = !quoted;
80745
- } else if (char === "," && !quoted) {
80746
- cells.push(cell);
80747
- cell = "";
80748
- } else {
80749
- cell += char;
80750
- }
80751
- }
80752
- return [...cells, cell];
80753
- }
80754
- function richBodyOf({ kind: kind2, text: text2 }) {
80755
- if (kind2 === "metric") {
80756
- try {
80757
- return { kind: kind2, ...JSON.parse(text2) };
80758
- } catch {
80759
- throw new Error("--metric takes JSON: {label, unit, value, delta, bars: [{label, value}]}");
80760
- }
80761
- }
80762
- const [columns = [], ...rows] = text2.split(/\r?\n/).filter((line) => line.trim() !== "").map(csvCellsOf);
80763
- return { kind: kind2, columns, rows };
80764
- }
80765
- function richOf(args) {
80766
- const metric = flagText({ args, name: "metric" });
80767
- const table = flagText({ args, name: "table" });
80768
- if (metric && table) throw new Error("an item carries one rich body: pass --metric or --table");
80769
- if (metric) return { kind: "metric", source: sourceOf(metric) };
80770
- if (table) return { kind: "table", source: sourceOf(table) };
80771
- return void 0;
80772
- }
80773
- var TEXT_FLAGS = { draft: "draft", summary: "summary" };
80774
- var FEED_WRITING = `Write for a person deciding on a phone in a few seconds:
80775
- - Title: the ask first, short enough to read in one glance.
80776
- - --summary: one plain sentence of why.
80777
- - No body: text to send goes in --draft, sources in --link, numbers in --metric or --table.
80778
- - Plain words. No ids (email, thread, card, channel), no UTC times, no PR or ticket lists,
80779
- no "Day 9." counters. Numbers only when they change the decision.
80780
- - Not too terse either: whole sentences a person understands without context.
80781
- - Replies and comments: same rules, short when you can.
80782
- The server pushes back with feed_hard_to_read when the text reads like a log;
80783
- rewrite it, or pass --force to post it as written.`;
80784
- var FEED_NO_BODY = "feed cards have no body: put the point in the title and one --summary line, text to send in --draft, sources in --link";
80785
- function pairOf({ value, flag: flag2 }) {
80786
- const at = value.indexOf("=");
80787
- if (at <= 0 || at === value.length - 1) {
80788
- throw new Error(`--${flag2} takes <label>=<value>, got "${value}"`);
80789
- }
80790
- return [value.slice(0, at), value.slice(at + 1)];
80791
- }
80792
- function sourceOf(value) {
80793
- return value.startsWith("@") && value.length > 1 ? { file: value.slice(1) } : { text: value };
80794
- }
80795
- function dateOf(value) {
80796
- return value === "none" ? null : value;
80797
- }
80798
- function snoozeOf(args) {
80799
- const people2 = args.lists["snooze-for"] ?? [];
80800
- if (people2.length === 0) return {};
80801
- const until = flagText({ args, name: "until" });
80802
- if (!until) throw new Error("--snooze-for needs --until <ISO time> or --until none");
80803
- return { snoozeFor: { userIds: [...people2], until: dateOf(until) } };
80804
- }
80805
- function textsOf(args) {
80806
- const texts = {};
80807
- for (const [flag2, field] of Object.entries(TEXT_FLAGS)) {
80808
- const value = flagText({ args, name: flag2 });
80809
- if (value) texts[field] = sourceOf(value);
80810
- }
80811
- return texts;
80812
- }
80813
- function pairsOf(args) {
80814
- const fields = {};
80815
- const links = args.lists.link ?? [];
80816
- if (links.length > 0) {
80817
- fields.links = links.map((value) => {
80818
- const [label3, url2] = pairOf({ value, flag: "link" });
80819
- return { label: label3, url: url2 };
80820
- });
80821
- }
80822
- const actions = args.lists.action ?? [];
80823
- if (actions.length > 0) {
80824
- fields.actions = actions.map((value) => {
80825
- const [label3, message2] = pairOf({ value, flag: "action" });
80826
- return { label: label3, message: message2 };
80827
- });
80828
- }
80829
- return fields;
80830
- }
80831
- function feedFlagsOf({ args }) {
80832
- if (args.flags.body !== void 0) throw new Error(FEED_NO_BODY);
80833
- const fields = pairsOf(args);
80834
- const tag = flagText({ args, name: "tag" });
80835
- if (tag) fields.tag = tag;
80836
- const header = flagText({ args, name: "draft-header" });
80837
- if (header) fields.draftHeader = header.replaceAll("\\n", "\n");
80838
- const doneLabel = flagText({ args, name: "done-label" });
80839
- if (doneLabel) fields.doneLabel = doneLabel;
80840
- for (const flag2 of ["urgent", "force"]) if (args.flags[flag2]) fields[flag2] = true;
80841
- const showAt = flagText({ args, name: "show-at" });
80842
- if (showAt) fields.showAt = dateOf(showAt);
80843
- const group = flagText({ args, name: "group" });
80844
- if (group) fields.group = group;
80845
- const labels = args.lists.label ?? [];
80846
- if (labels.length > 0) fields.labels = [...labels];
80847
- const autoSendOn = flagText({ args, name: "auto-send-on" });
80848
- if (autoSendOn) fields.autoSendOn = dateOf(autoSendOn);
80849
- const rich = richOf(args);
80850
- const texts = textsOf(args);
80851
- return { fields: { ...fields, ...snoozeOf(args) }, texts, ...rich ? { rich } : {} };
80852
- }
80853
-
80854
- // src/services/feed-files.service.ts
80855
- import { readFile as readFile25 } from "node:fs/promises";
80856
- import { basename as basename4, resolve as resolve9 } from "node:path";
80857
-
80858
81183
  // ../../modules/feed/contract/src/feed.ts
80859
81184
  var feedAuthorSchemaDefinition = external_exports.object({
80860
81185
  kind: external_exports.enum(["agent", "person", "system"]),
@@ -81029,7 +81354,8 @@ var feedApprovalSchemaDefinition = external_exports.object({
81029
81354
  "connector_connect",
81030
81355
  "app_access",
81031
81356
  "computer",
81032
- "agent_join"
81357
+ "agent_join",
81358
+ "vault_share"
81033
81359
  ]),
81034
81360
  requestId: external_exports.string(),
81035
81361
  /** The app, for an `app_publish` or `app_access` card. */
@@ -81117,6 +81443,13 @@ var feedGroupSummarySchemaDefinition = external_exports.object({
81117
81443
  counts: external_exports.array(external_exports.object({ label: external_exports.string(), count: external_exports.number().int().positive() }))
81118
81444
  });
81119
81445
  var feedGroupSummarySchema = feedGroupSummarySchemaDefinition;
81446
+ var feedDecisionsSchemaDefinition = external_exports.object({
81447
+ /** How many decisions wait; the banner shows only above zero. */
81448
+ count: external_exports.number().int().nonnegative(),
81449
+ /** The decision cards in feed order, each answered as on the feed. */
81450
+ items: external_exports.array(feedItemSchema)
81451
+ });
81452
+ var feedDecisionsSchema = feedDecisionsSchemaDefinition;
81120
81453
  var feedViewSchemaDefinition = external_exports.object({
81121
81454
  open: external_exports.array(feedItemSchema),
81122
81455
  comingUp: external_exports.array(feedItemSchema),
@@ -81195,7 +81528,9 @@ var answerFeedApprovalInputSchemaDefinition = external_exports.object({
81195
81528
  var answerFeedApprovalInputSchema = answerFeedApprovalInputSchemaDefinition;
81196
81529
  var decideFeedRequestInputSchemaDefinition = external_exports.object({
81197
81530
  ...itemRef.shape,
81198
- decision: external_exports.enum(["approved", "denied"])
81531
+ decision: external_exports.enum(["approved", "denied"]),
81532
+ /** With a Deny: why, for the agent that asked. It goes on the card as the person's reply. */
81533
+ resolutionNote: external_exports.string().max(4e3).optional()
81199
81534
  });
81200
81535
  var decideFeedRequestInputSchema = decideFeedRequestInputSchemaDefinition;
81201
81536
  var feedPublishDurationSchema = external_exports.enum(["once", "day", "always"]);
@@ -81316,9 +81651,10 @@ var feedFileLinkInputSchemaDefinition = external_exports.object({
81316
81651
  var feedFileLinkInputSchema = feedFileLinkInputSchemaDefinition;
81317
81652
  var feedFileLinkSchemaDefinition = external_exports.object({ url: external_exports.string(), expiresAt: external_exports.iso.datetime() });
81318
81653
  var feedFileLinkSchema = feedFileLinkSchemaDefinition;
81319
- var feedTrpc = defineTrpcContract("feed").query("channelItems").withInput(external_exports.object({ workspaceId: external_exports.string().min(1), channelId: external_exports.string().min(1) })).withOutput(external_exports.array(feedAgentItemSchema)).query("list").withInput(listFeedInputSchema).withOutput(feedViewSchema).query("card").withInput(itemRef).withOutput(feedCardViewSchema).query("fileLink").withInput(feedFileLinkInputSchema).withOutput(feedFileLinkSchema).query("count").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(external_exports.object({ count: external_exports.number().int().nonnegative() })).mutation("act").withInput(actFeedItemInputSchema).withOutput(feedItemSchema).mutation("comment").withInput(commentFeedItemInputSchema).withOutput(feedItemSchema).mutation("done").withInput(itemRef).withOutput(feedItemSchema).mutation("stopAutoSend").withInput(itemRef).withOutput(feedItemSchema).mutation("putBack").withInput(putBackFeedItemInputSchema).withOutput(feedItemSchema).mutation("snooze").withInput(snoozeFeedItemInputSchema).withOutput(feedItemSchema).mutation("unsnooze").withInput(itemRef).withOutput(feedItemSchema).mutation("saveDraft").withInput(saveFeedDraftInputSchema).withOutput(feedItemSchema).mutation("editItem").withInput(editFeedItemInputSchema).withOutput(feedItemSchema).mutation("saveMessage").withInput(saveFeedMessageInputSchema).withOutput(feedItemSchema).mutation("answerApproval").withInput(answerFeedApprovalInputSchema).withOutput(feedItemSchema).mutation("decidePublish").withInput(decideFeedPublishInputSchema).withOutput(feedItemSchema).mutation("decideAccess").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideServer").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideAppAccess").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideComputer").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideAgentJoin").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).build();
81654
+ var feedTrpc = defineTrpcContract("feed").query("channelItems").withInput(external_exports.object({ workspaceId: external_exports.string().min(1), channelId: external_exports.string().min(1) })).withOutput(external_exports.array(feedAgentItemSchema)).query("list").withInput(listFeedInputSchema).withOutput(feedViewSchema).query("card").withInput(itemRef).withOutput(feedCardViewSchema).query("fileLink").withInput(feedFileLinkInputSchema).withOutput(feedFileLinkSchema).query("count").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(external_exports.object({ count: external_exports.number().int().nonnegative() })).query("decisions").withInput(external_exports.object({ workspaceId: external_exports.string().min(1) })).withOutput(feedDecisionsSchema).mutation("act").withInput(actFeedItemInputSchema).withOutput(feedItemSchema).mutation("comment").withInput(commentFeedItemInputSchema).withOutput(feedItemSchema).mutation("done").withInput(itemRef).withOutput(feedItemSchema).mutation("stopAutoSend").withInput(itemRef).withOutput(feedItemSchema).mutation("putBack").withInput(putBackFeedItemInputSchema).withOutput(feedItemSchema).mutation("snooze").withInput(snoozeFeedItemInputSchema).withOutput(feedItemSchema).mutation("unsnooze").withInput(itemRef).withOutput(feedItemSchema).mutation("saveDraft").withInput(saveFeedDraftInputSchema).withOutput(feedItemSchema).mutation("editItem").withInput(editFeedItemInputSchema).withOutput(feedItemSchema).mutation("saveMessage").withInput(saveFeedMessageInputSchema).withOutput(feedItemSchema).mutation("answerApproval").withInput(answerFeedApprovalInputSchema).withOutput(feedItemSchema).mutation("decidePublish").withInput(decideFeedPublishInputSchema).withOutput(feedItemSchema).mutation("decideAccess").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideServer").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideAppAccess").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideComputer").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).mutation("decideAgentJoin").withInput(decideFeedRequestInputSchema).withOutput(feedItemSchema).build();
81320
81655
  var feedUi = uiTokens("feed");
81321
81656
  var FeedNavSlot = feedUi.component("nav");
81657
+ var FeedDecisionsSlot = feedUi.component("decisions");
81322
81658
  var FeedCountHooksToken = feedUi.hooks("count");
81323
81659
  var FeedChannelCardSlot = feedUi.component("channel-card");
81324
81660
  var FeedSearchSlot = feedUi.component("search");
@@ -81397,7 +81733,135 @@ var feedWakeIntentSchemaDefinition = external_exports.object({
81397
81733
  // ../../modules/feed/contract/src/feed.config.ts
81398
81734
  var feedConfig = Config.define(() => ({ publicBaseUrl }));
81399
81735
 
81736
+ // ../../modules/feed/contract/src/feed.decisions.ts
81737
+ function decisionsLineOf(count5) {
81738
+ return `${count5} ${count5 === 1 ? "decision" : "decisions"} waiting on you`;
81739
+ }
81740
+
81741
+ // src/rules/feed-input.rules.ts
81742
+ function csvCellsOf(line) {
81743
+ const cells = [];
81744
+ let cell = "";
81745
+ let quoted = false;
81746
+ for (let at = 0; at < line.length; at += 1) {
81747
+ const char = line[at];
81748
+ if (quoted && char === '"' && line[at + 1] === '"') {
81749
+ cell += '"';
81750
+ at += 1;
81751
+ } else if (char === '"') {
81752
+ quoted = !quoted;
81753
+ } else if (char === "," && !quoted) {
81754
+ cells.push(cell);
81755
+ cell = "";
81756
+ } else {
81757
+ cell += char;
81758
+ }
81759
+ }
81760
+ return [...cells, cell];
81761
+ }
81762
+ function richBodyOf({ kind: kind2, text: text2 }) {
81763
+ if (kind2 === "metric") {
81764
+ try {
81765
+ return { kind: kind2, ...JSON.parse(text2) };
81766
+ } catch {
81767
+ throw new Error("--metric takes JSON: {label, unit, value, delta, bars: [{label, value}]}");
81768
+ }
81769
+ }
81770
+ const [columns = [], ...rows] = text2.split(/\r?\n/).filter((line) => line.trim() !== "").map(csvCellsOf);
81771
+ return { kind: kind2, columns, rows };
81772
+ }
81773
+ function richOf(args) {
81774
+ const metric = flagText({ args, name: "metric" });
81775
+ const table = flagText({ args, name: "table" });
81776
+ if (metric && table) throw new Error("an item carries one rich body: pass --metric or --table");
81777
+ if (metric) return { kind: "metric", source: sourceOf(metric) };
81778
+ if (table) return { kind: "table", source: sourceOf(table) };
81779
+ return void 0;
81780
+ }
81781
+ var TEXT_FLAGS = { draft: "draft", summary: "summary" };
81782
+ var FEED_WRITING = `Write for a person deciding on a phone in a few seconds:
81783
+ - Title: the ask first, short enough to read in one glance.
81784
+ - --summary: one plain sentence of why.
81785
+ - No body: text to send goes in --draft, sources in --link, numbers in --metric or --table.
81786
+ - Plain words. No ids (email, thread, card, channel), no UTC times, no PR or ticket lists,
81787
+ no "Day 9." counters. Numbers only when they change the decision.
81788
+ - Not too terse either: whole sentences a person understands without context.
81789
+ - Replies and comments: same rules, short when you can.
81790
+ The server pushes back with feed_hard_to_read when the text reads like a log;
81791
+ rewrite it, or pass --force to post it as written.`;
81792
+ var FEED_NO_BODY = "feed cards have no body: put the point in the title and one --summary line, text to send in --draft, sources in --link";
81793
+ function pairOf({ value, flag: flag2 }) {
81794
+ const at = value.indexOf("=");
81795
+ if (at <= 0 || at === value.length - 1) {
81796
+ throw new Error(`--${flag2} takes <label>=<value>, got "${value}"`);
81797
+ }
81798
+ return [value.slice(0, at), value.slice(at + 1)];
81799
+ }
81800
+ function sourceOf(value) {
81801
+ return value.startsWith("@") && value.length > 1 ? { file: value.slice(1) } : { text: value };
81802
+ }
81803
+ function dateOf(value) {
81804
+ return value === "none" ? null : value;
81805
+ }
81806
+ function snoozeOf(args) {
81807
+ const people2 = args.lists["snooze-for"] ?? [];
81808
+ if (people2.length === 0) return {};
81809
+ const until = flagText({ args, name: "until" });
81810
+ if (!until) throw new Error("--snooze-for needs --until <ISO time> or --until none");
81811
+ return { snoozeFor: { userIds: [...people2], until: dateOf(until) } };
81812
+ }
81813
+ function textsOf(args) {
81814
+ const texts = {};
81815
+ for (const [flag2, field] of Object.entries(TEXT_FLAGS)) {
81816
+ const value = flagText({ args, name: flag2 });
81817
+ if (value) texts[field] = sourceOf(value);
81818
+ }
81819
+ return texts;
81820
+ }
81821
+ function pairsOf(args) {
81822
+ const fields = {};
81823
+ const links = args.lists.link ?? [];
81824
+ if (links.length > 0) {
81825
+ fields.links = links.map((value) => {
81826
+ const [label3, url2] = pairOf({ value, flag: "link" });
81827
+ return { label: label3, url: url2 };
81828
+ });
81829
+ }
81830
+ const actions = args.lists.action ?? [];
81831
+ if (actions.length > 0) {
81832
+ fields.actions = actions.map((value) => {
81833
+ const [label3, message2] = pairOf({ value, flag: "action" });
81834
+ return { label: label3, message: message2 };
81835
+ });
81836
+ }
81837
+ return fields;
81838
+ }
81839
+ function feedFlagsOf({ args }) {
81840
+ if (args.flags.body !== void 0) throw new Error(FEED_NO_BODY);
81841
+ const fields = pairsOf(args);
81842
+ const tag = flagText({ args, name: "tag" });
81843
+ if (tag) fields.tag = tag;
81844
+ const header = flagText({ args, name: "draft-header" });
81845
+ if (header) fields.draftHeader = header.replaceAll("\\n", "\n");
81846
+ const doneLabel = flagText({ args, name: "done-label" });
81847
+ if (doneLabel) fields.doneLabel = doneLabel;
81848
+ for (const flag2 of ["urgent", "force"]) if (args.flags[flag2]) fields[flag2] = true;
81849
+ const showAt = flagText({ args, name: "show-at" });
81850
+ if (showAt) fields.showAt = dateOf(showAt);
81851
+ const group = flagText({ args, name: "group" });
81852
+ if (group) fields.group = group;
81853
+ const labels = args.lists.label ?? [];
81854
+ if (labels.length > 0) fields.labels = [...labels];
81855
+ const autoSendOn = flagText({ args, name: "auto-send-on" });
81856
+ if (autoSendOn) fields.autoSendOn = dateOf(autoSendOn);
81857
+ const rich = richOf(args);
81858
+ const texts = textsOf(args);
81859
+ return { fields: { ...fields, ...snoozeOf(args) }, texts, ...rich ? { rich } : {} };
81860
+ }
81861
+
81400
81862
  // src/services/feed-files.service.ts
81863
+ import { readFile as readFile25 } from "node:fs/promises";
81864
+ import { basename as basename4, resolve as resolve9 } from "node:path";
81401
81865
  async function bytesOf2({
81402
81866
  context,
81403
81867
  source
@@ -81486,6 +81950,7 @@ var USAGE10 = `Usage:
81486
81950
  laze feed group-summary <group>
81487
81951
  laze feed list [--json]
81488
81952
  laze feed count
81953
+ laze feed decisions [--json]
81489
81954
  laze feed act <id> <actionId> [--draft <text|@file>]
81490
81955
  laze feed comment <id> <text> [--draft <text|@file>] [--force]
81491
81956
  laze feed done|put-back|unsnooze <id>
@@ -81697,6 +82162,16 @@ async function feedCount({ context, args }) {
81697
82162
  context.out(`${answer4.count}
81698
82163
  `);
81699
82164
  }
82165
+ async function feedDecisions({ context, args }) {
82166
+ const { client } = await signedIn({ context, args });
82167
+ const answer4 = await client.get("/api/feed/mine/decisions");
82168
+ if (args.flags.json) return context.out(`${JSON.stringify(answer4, null, 2)}
82169
+ `);
82170
+ if (answer4.count === 0) return context.out("No decisions waiting on you.\n");
82171
+ context.out(`${decisionsLineOf(answer4.count)}
82172
+ `);
82173
+ for (const item of answer4.items) printCard2({ context, item });
82174
+ }
81700
82175
  async function feedAct({ context, args }) {
81701
82176
  const [itemId, actionId] = [args.words[2], args.words[3]];
81702
82177
  if (!itemId || !actionId) throw new CliUsageError(USAGE10);
@@ -81761,6 +82236,7 @@ var FEED_COMMANDS = {
81761
82236
  loops: feedLoops,
81762
82237
  list: feedList,
81763
82238
  count: feedCount,
82239
+ decisions: feedDecisions,
81764
82240
  act: feedAct,
81765
82241
  comment: feedComment,
81766
82242
  done: moveItem("done"),
@@ -82268,12 +82744,12 @@ async function ip({ context, args }) {
82268
82744
  }
82269
82745
 
82270
82746
  // src/services/join-commands.service.ts
82271
- import { mkdir as mkdir18, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile19 } from "node:fs/promises";
82272
- import { dirname as dirname18, join as join20 } from "node:path";
82747
+ import { mkdir as mkdir19, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile19 } from "node:fs/promises";
82748
+ import { dirname as dirname19, join as join21 } from "node:path";
82273
82749
  var DEFAULT_WAIT_SECONDS2 = 100;
82274
82750
  var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
82275
82751
  function pendingPathOf({ context }) {
82276
- return join20(dirname18(context.environment.configPath), "join", "pending.json");
82752
+ return join21(dirname19(context.environment.configPath), "join", "pending.json");
82277
82753
  }
82278
82754
  async function readPending({
82279
82755
  context,
@@ -82290,7 +82766,7 @@ async function readPending({
82290
82766
  }
82291
82767
  async function keepPending({ context, pending }) {
82292
82768
  const path = pendingPathOf({ context });
82293
- await mkdir18(dirname18(path), { recursive: true, mode: 448 });
82769
+ await mkdir19(dirname19(path), { recursive: true, mode: 448 });
82294
82770
  const temporary = `${path}.${process.pid}.tmp`;
82295
82771
  await writeFile19(temporary, JSON.stringify(pending), { mode: 384 });
82296
82772
  await rename5(temporary, path);
@@ -83110,8 +83586,8 @@ async function serveMcp({
83110
83586
  }
83111
83587
 
83112
83588
  // src/services/mount-files.service.ts
83113
- import { mkdir as mkdir19, readFile as readFile30, rm as rm12, writeFile as writeFile20 } from "node:fs/promises";
83114
- import { dirname as dirname19, relative as relative5, resolve as resolve11 } from "node:path";
83589
+ import { mkdir as mkdir20, readFile as readFile30, rm as rm12, writeFile as writeFile20 } from "node:fs/promises";
83590
+ import { dirname as dirname20, relative as relative5, resolve as resolve11 } from "node:path";
83115
83591
  async function textArgument({
83116
83592
  context,
83117
83593
  value
@@ -83131,13 +83607,13 @@ async function writeMount({
83131
83607
  }) {
83132
83608
  const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
83133
83609
  await rm12(root, { recursive: true, force: true });
83134
- await mkdir19(root, { recursive: true });
83610
+ await mkdir20(root, { recursive: true });
83135
83611
  for (const file3 of files2) {
83136
83612
  const target = resolve11(root, file3.path);
83137
83613
  const inside = relative5(root, target);
83138
83614
  if (!inside || inside.startsWith(".."))
83139
83615
  throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
83140
- await mkdir19(dirname19(target), { recursive: true });
83616
+ await mkdir20(dirname20(target), { recursive: true });
83141
83617
  await writeFile20(target, file3.content);
83142
83618
  }
83143
83619
  return root;
@@ -83779,8 +84255,8 @@ ${OPS_USAGE}`);
83779
84255
  }
83780
84256
 
83781
84257
  // src/services/release-watch.service.ts
83782
- import { mkdir as mkdir20, readFile as readFile31, realpath, writeFile as writeFile21 } from "node:fs/promises";
83783
- import { dirname as dirname20, join as join21 } from "node:path";
84258
+ import { mkdir as mkdir21, readFile as readFile31, realpath, writeFile as writeFile21 } from "node:fs/promises";
84259
+ import { dirname as dirname21, join as join22 } from "node:path";
83784
84260
 
83785
84261
  // src/rules/cli-update.rules.ts
83786
84262
  var CLI_PACKAGE = "@lazehq/cli";
@@ -83934,16 +84410,16 @@ async function startedUpdate({
83934
84410
  if (context.environment.inherited.LAZE_AUTO_UPDATE === "0") return null;
83935
84411
  const plan2 = updatePlanOf({ script: await scriptOf(context), nowMs: context.nowMs() });
83936
84412
  if (plan2.kind !== "install") return null;
83937
- const folder = dirname20(context.environment.configPath);
83938
- const stamp = join21(folder, "auto-update.json");
84413
+ const folder = dirname21(context.environment.configPath);
84414
+ const stamp = join22(folder, "auto-update.json");
83939
84415
  const last = await readFile31(stamp, "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
83940
84416
  const now = context.nowMs();
83941
84417
  if (last?.server === server && now - last.atMs < RETRY_AFTER_MS) return null;
83942
- await mkdir20(folder, { recursive: true, mode: 448 });
84418
+ await mkdir21(folder, { recursive: true, mode: 448 });
83943
84419
  await writeFile21(stamp, JSON.stringify({ server, atMs: now }), { mode: 384 });
83944
84420
  context.processes.spawnDetached({
83945
84421
  argv: [...context.program, "update"],
83946
- logPath: join21(folder, "auto-update.log")
84422
+ logPath: join22(folder, "auto-update.log")
83947
84423
  });
83948
84424
  return { manager: plan2.manager };
83949
84425
  }
@@ -83985,7 +84461,13 @@ async function guardRound(guard) {
83985
84461
  if (!await takeLock({ context, path: lock, claudePid, ...sessionIdOf({ session }) }))
83986
84462
  return true;
83987
84463
  }
83988
- const due = await dueFromSpool({ context, profile: name3, seen: async () => "", pushedToo: true });
84464
+ const due = await dueFromSpool({
84465
+ context,
84466
+ profile: name3,
84467
+ seen: async () => "",
84468
+ pushedToo: true,
84469
+ settledOnly: true
84470
+ });
83989
84471
  const messages = due.length > 0 ? due : await takeRound2({ context, client, claudePid: 0, session });
83990
84472
  if (messages.length === 0) return false;
83991
84473
  await keepTaken({ context, profile: name3, messages });
@@ -84180,7 +84662,7 @@ async function schedule({ context, args }) {
84180
84662
 
84181
84663
  // src/services/skill-commands.service.ts
84182
84664
  import { readdir as readdir7, readFile as readFile33 } from "node:fs/promises";
84183
- import { join as join22, relative as relative6, resolve as resolve12 } from "node:path";
84665
+ import { join as join23, relative as relative6, resolve as resolve12 } from "node:path";
84184
84666
  var USAGE16 = `Usage:
84185
84667
  laze skill list [--agent <agentId>]
84186
84668
  laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
@@ -84201,7 +84683,7 @@ async function folderFiles({ root }) {
84201
84683
  const files2 = [];
84202
84684
  for (const entry of entries) {
84203
84685
  if (!entry.isFile()) continue;
84204
- const full = join22(entry.parentPath, entry.name);
84686
+ const full = join23(entry.parentPath, entry.name);
84205
84687
  files2.push({ path: relative6(root, full), content: await readFile33(full, "utf8") });
84206
84688
  }
84207
84689
  return files2.toSorted((a, b) => a.path.localeCompare(b.path));
@@ -86722,7 +87204,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
86722
87204
  laze star add|remove|list [channel] starred conversations in your sidebar (people)
86723
87205
  laze feed post <title> [--channel <c>] ... put an item in people's feed as your agent
86724
87206
  laze feed update|reply|read <id>, laze feed inbox change, answer and read your items
86725
- laze feed list|count your own feed as a person: cards and their actions
87207
+ laze feed list|count|decisions your own feed as a person: cards and their actions
86726
87208
  laze feed act <id> <actionId>, comment <id> <text> answer a card in your feed
86727
87209
  laze feed done|put-back|unsnooze <id>, snooze <id> --until <time> move a card
86728
87210
  laze feed channel <channelId> the feed cards a channel shows
@@ -87069,7 +87551,7 @@ async function runCli({
87069
87551
  import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
87070
87552
  import { mkdirSync, openSync } from "node:fs";
87071
87553
  import { readFile as readFile38, readlink } from "node:fs/promises";
87072
- import { dirname as dirname21 } from "node:path";
87554
+ import { dirname as dirname22 } from "node:path";
87073
87555
  import { promisify as promisify2 } from "node:util";
87074
87556
  var run3 = promisify2(execFile2);
87075
87557
  function alive(pid) {
@@ -87106,7 +87588,7 @@ async function cwdOf(pid) {
87106
87588
  return line ? line.slice(1) : void 0;
87107
87589
  }
87108
87590
  function spawnDetached({ argv, logPath }) {
87109
- mkdirSync(dirname21(logPath), { recursive: true, mode: 448 });
87591
+ mkdirSync(dirname22(logPath), { recursive: true, mode: 448 });
87110
87592
  const log = openSync(logPath, "a", 384);
87111
87593
  const [program = "", ...rest] = argv;
87112
87594
  const child = spawn4(program, rest, { detached: true, stdio: ["ignore", log, log] });