@lazehq/cli 0.1.37 → 0.1.39

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 +895 -327
  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.37";
35711
+ var STAMPED = "0.1.39";
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) {
@@ -67501,6 +67695,27 @@ function notBoundText({
67501
67695
  const who = `${agent2 ? `"${agent2}"` : "this agent"} (config ${configPath})`;
67502
67696
  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
67697
  }
67698
+ function boundMetaOf({ error: error62 }) {
67699
+ if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
67700
+ return error62.meta ?? {};
67701
+ }
67702
+ async function takeOverHere({
67703
+ context,
67704
+ client,
67705
+ session,
67706
+ meta: meta3,
67707
+ profile
67708
+ }) {
67709
+ if (!session || !meta3.session || meta3.host !== session.host) return false;
67710
+ const sessions = (await context.store.read()).sessions ?? {};
67711
+ const theirs = sessions[meta3.session];
67712
+ const mine4 = sessions[sessionKeyOf({ session })] === profile;
67713
+ const stale = mine4 && theirs !== void 0 && theirs !== profile;
67714
+ const claudePid = (await nearestHarnessOf({ context }))?.pid;
67715
+ if (!stale && await liveElsewhere({ context, key: meta3.session, claudePid })) return false;
67716
+ await forSession({ client, session }).post("/api/agents/me/bind", {});
67717
+ return true;
67718
+ }
67504
67719
  async function notBoundNotice({
67505
67720
  context,
67506
67721
  client,
@@ -67510,12 +67725,8 @@ async function notBoundNotice({
67510
67725
  }) {
67511
67726
  if (!(error62 instanceof LazeApiError) || error62.code !== "session_not_bound") return void 0;
67512
67727
  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
- }
67728
+ if (client && await takeOverHere({ context, client, session, meta: meta3, profile })) {
67729
+ return { notice: void 0, rebound: true };
67519
67730
  }
67520
67731
  const key = session ? sessionKeyOf({ session }) : "unknown";
67521
67732
  const path = statePathOf({ context, kind: "told", profile: key });
@@ -68220,13 +68431,13 @@ function channelLabelIn(channel) {
68220
68431
  }
68221
68432
 
68222
68433
  // 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";
68434
+ import { readFile as readFile10, rm as rm4, writeFile as writeFile9, mkdir as mkdir10 } from "node:fs/promises";
68435
+ import { dirname as dirname11 } from "node:path";
68225
68436
 
68226
68437
  // src/services/connect-service.service.ts
68227
68438
  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";
68439
+ import { mkdir as mkdir9, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
68440
+ import { dirname as dirname10, join as join12 } from "node:path";
68230
68441
 
68231
68442
  // src/rules/connect-service.rules.ts
68232
68443
  function systemdWordOf(word3) {
@@ -68348,9 +68559,9 @@ function rolloutEventOf({
68348
68559
  }
68349
68560
 
68350
68561
  // 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";
68562
+ import { mkdir as mkdir8, readFile as readFile9, rename as rename3, rm as rm2, stat as stat2, writeFile as writeFile7 } from "node:fs/promises";
68352
68563
  import { homedir as homedir2, hostname as hostname4 } from "node:os";
68353
- import { dirname as dirname8, join as join10 } from "node:path";
68564
+ import { dirname as dirname9, join as join11 } from "node:path";
68354
68565
 
68355
68566
  // src/services/codex-turn-watch.service.ts
68356
68567
  import { open as open2, readdir as readdir2 } from "node:fs/promises";
@@ -68943,12 +69154,14 @@ async function notesOf({ context }) {
68943
69154
  const notes = await Promise.all(
68944
69155
  files2.map(async (file3) => {
68945
69156
  const pid = Number(file3.replace(/\.json$/, ""));
68946
- const session = await jsonOf(join9(folder, file3));
69157
+ const note = await jsonOf(join9(folder, file3));
68947
69158
  const at = await stat(join9(folder, file3)).then(
68948
69159
  (info) => info.mtimeMs,
68949
69160
  () => 0
68950
69161
  );
68951
- return pid && session ? [{ pid, key: sessionKeyOf({ session }), at }] : [];
69162
+ if (!pid || !note) return [];
69163
+ const { launch = {}, ...session } = note;
69164
+ return [{ pid, key: sessionKeyOf({ session }), at, session, launch }];
68952
69165
  })
68953
69166
  );
68954
69167
  return notes.flat().toSorted((a, b) => b.at - a.at);
@@ -68968,15 +69181,21 @@ async function rushListenersOf({
68968
69181
  for (const [key, profile] of bound) {
68969
69182
  const one = sessions.find((each) => `claude-code:${each.sessionId}` === key);
68970
69183
  if (!one?.id) continue;
68971
- const pids = notes.filter((note) => note.key === key).map((note) => note.pid);
69184
+ const own2 = notes.filter((note) => note.key === key);
69185
+ const pids = own2.map((note) => note.pid);
68972
69186
  const listenerPid = await listenerOf({ context, key, profile, pids });
69187
+ const waiterPid = await waiterOf({ context, key, profile });
68973
69188
  const lastClaudePid = pids.find((pid) => !context.processes.alive(pid));
69189
+ const newest = own2[0];
68974
69190
  rows.push({
68975
69191
  profile,
68976
69192
  rushId: one.id,
69193
+ key,
68977
69194
  standing: rushStandingOf({ one }),
68978
69195
  ...listenerPid ? { listenerPid } : {},
68979
- ...lastClaudePid ? { lastClaudePid } : {}
69196
+ ...waiterPid ? { waiterPid } : {},
69197
+ ...lastClaudePid ? { lastClaudePid } : {},
69198
+ ...newest ? { noted: { session: newest.session, launch: newest.launch } } : {}
68980
69199
  });
68981
69200
  }
68982
69201
  return rows;
@@ -68991,6 +69210,13 @@ async function listenerOf({
68991
69210
  const guard = await jsonOf(guardPathOf({ context, claudePid }));
68992
69211
  if (guard && context.processes.alive(guard.pid)) return guard.pid;
68993
69212
  }
69213
+ return waiterOf({ context, key, profile });
69214
+ }
69215
+ async function waiterOf({
69216
+ context,
69217
+ key,
69218
+ profile
69219
+ }) {
68994
69220
  const lock = statePathOf({ context, kind: "waiters", profile });
68995
69221
  const waiter = await jsonOf(lock);
68996
69222
  const mine4 = waiter?.sessionId === key.slice(key.indexOf(":") + 1);
@@ -69007,12 +69233,122 @@ async function rearmRushGuards({ context }) {
69007
69233
  return started;
69008
69234
  }
69009
69235
 
69236
+ // src/services/rush-watchdog.service.ts
69237
+ import { appendFile, mkdir as mkdir7 } from "node:fs/promises";
69238
+ import { dirname as dirname8, join as join10 } from "node:path";
69239
+ var UNDELIVERED_AFTER_MS = 6e4;
69240
+ var CHECK_TIMEOUT_MS = 5e3;
69241
+ function clientOf({ context, profile }) {
69242
+ return context.store.read().then((config2) => {
69243
+ const entry = config2.profiles[profile];
69244
+ if (!entry) return void 0;
69245
+ return LazeClient.create({
69246
+ baseUrl: entry.url,
69247
+ token: entry.token,
69248
+ fetcher: (input2, init) => context.fetcher(input2, { ...init, signal: AbortSignal.timeout(CHECK_TIMEOUT_MS) })
69249
+ });
69250
+ });
69251
+ }
69252
+ async function waitingOf({ context, profile }) {
69253
+ const client = await clientOf({ context, profile });
69254
+ return client?.get("/api/agents/me/inbox/waiting").catch(() => void 0);
69255
+ }
69256
+ function waitedMsOf({ waiting, nowMs }) {
69257
+ if (waiting.count === 0 || !waiting.oldestPostedAt) return 0;
69258
+ return Math.max(0, nowMs - Temporal3.Instant.from(waiting.oldestPostedAt).epochMilliseconds);
69259
+ }
69260
+ function boundAwayOf({ waiting, key }) {
69261
+ const bound = waiting.session;
69262
+ if (!bound || `${bound.harness}:${bound.sessionId}` === key) return void 0;
69263
+ return `${sessionLabelOf(bound)} (${bound.harness}:${bound.sessionId})`;
69264
+ }
69265
+ async function logDelivery({ context, line }) {
69266
+ const folder = join10(dirname8(context.environment.configPath), "connect");
69267
+ const at = Temporal3.Instant.fromEpochMilliseconds(context.nowMs());
69268
+ const stamped = `${at.toString({ smallestUnit: "second" })} ${line}
69269
+ `;
69270
+ context.out(stamped);
69271
+ await mkdir7(folder, { recursive: true, mode: 448 });
69272
+ await appendFile(join10(folder, "delivery.log"), stamped, { mode: 384 });
69273
+ }
69274
+ async function claimFor({
69275
+ context,
69276
+ client,
69277
+ row
69278
+ }) {
69279
+ const session = row.noted.session;
69280
+ const claim3 = () => forSession({ client, session }).post("/api/agents/me/inbox", {
69281
+ waitSeconds: 0
69282
+ });
69283
+ try {
69284
+ return await claim3();
69285
+ } catch (error62) {
69286
+ const meta3 = boundMetaOf({ error: error62 });
69287
+ if (!meta3) throw error62;
69288
+ const profile = row.profile;
69289
+ if (!await takeOverHere({ context, client, session, meta: meta3, profile })) {
69290
+ 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`;
69291
+ }
69292
+ await logDelivery({
69293
+ context,
69294
+ line: `${profile}: moved the agent from ${meta3.session} to ${row.key}, which this machine binds it to`
69295
+ });
69296
+ return claim3();
69297
+ }
69298
+ }
69299
+ async function checkSession({ context, row }) {
69300
+ if (row.standing === "stopped" || !row.noted) return void 0;
69301
+ const client = await clientOf({ context, profile: row.profile });
69302
+ if (!client) return void 0;
69303
+ const waiting = await client.get("/api/agents/me/inbox/waiting");
69304
+ const waited = waitedMsOf({ waiting, nowMs: context.nowMs() });
69305
+ if (waited <= UNDELIVERED_AFTER_MS) return void 0;
69306
+ const taken = await claimFor({ context, client, row: { ...row, noted: row.noted } });
69307
+ if (typeof taken === "string") return `${row.profile}: ${waiting.count} undelivered; ${taken}`;
69308
+ if (taken.length === 0) return void 0;
69309
+ await keepTaken({ context, profile: row.profile, messages: taken });
69310
+ const self2 = await currentNameOf({ context, client, profile: row.profile });
69311
+ const env = { ...row.noted.launch, LAZE_WAKE_TEXT: hookContextOf({ messages: taken, self: self2 }) };
69312
+ const command = rushSendCommand({ id: row.rushId, program: "rush" });
69313
+ const ids = taken.map((message2) => message2.messageId);
69314
+ if (await context.runCommand({ command, env }) !== 0) {
69315
+ return `${row.profile}: rush session send ${row.rushId} failed; ${ids.join(", ")} stay for its next hook`;
69316
+ }
69317
+ await turnStarted({ context, client, agent: row.profile, messages: taken }).catch(
69318
+ () => void 0
69319
+ );
69320
+ await dropFromSpool({ context, profile: row.profile, messageIds: ids });
69321
+ const seconds = Math.round(waited / 1e3);
69322
+ await logDelivery({
69323
+ context,
69324
+ line: `${row.profile}: its hooks left ${ids.join(", ")} waiting ${seconds}s; handed over through rush ${row.rushId} (${row.standing})`
69325
+ });
69326
+ return void 0;
69327
+ }
69328
+ async function watchRushDelivery({
69329
+ context,
69330
+ said
69331
+ }) {
69332
+ for (const row of await rushListenersOf({ context })) {
69333
+ const problem = await checkSession({ context, row }).catch(
69334
+ (error62) => `${row.profile}: the delivery check failed: ${String(error62)}`
69335
+ );
69336
+ if (!problem) {
69337
+ said.delete(row.profile);
69338
+ continue;
69339
+ }
69340
+ if (said.get(row.profile) === problem) continue;
69341
+ said.set(row.profile, problem);
69342
+ await logDelivery({ context, line: problem });
69343
+ }
69344
+ }
69345
+
69010
69346
  // src/services/connect-delivery.service.ts
69011
69347
  function connectFolderOf({ context }) {
69012
- return join10(dirname8(context.environment.configPath), "connect");
69348
+ return join11(dirname9(context.environment.configPath), "connect");
69013
69349
  }
69014
69350
  function runStatePathOf({ context }) {
69015
- return join10(connectFolderOf({ context }), "run.json");
69351
+ return join11(connectFolderOf({ context }), "run.json");
69016
69352
  }
69017
69353
  async function readJson({ path }) {
69018
69354
  try {
@@ -69176,7 +69512,7 @@ async function serveRounds({
69176
69512
  }
69177
69513
  var saves = 0;
69178
69514
  async function save(run4) {
69179
- await mkdir7(dirname8(run4.path), { recursive: true, mode: 448 });
69515
+ await mkdir8(dirname9(run4.path), { recursive: true, mode: 448 });
69180
69516
  const temporary = `${run4.path}.${run4.self}.${saves += 1}.tmp`;
69181
69517
  await writeFile7(temporary, JSON.stringify(run4.state));
69182
69518
  await rename3(temporary, run4.path);
@@ -69234,6 +69570,7 @@ async function runConnectLoop({ context }) {
69234
69570
  context.out(`laze connect run: pid ${self2}
69235
69571
  `);
69236
69572
  const startedFrom = await cliStampOf({ context });
69573
+ const said = /* @__PURE__ */ new Map();
69237
69574
  const relays = RelayLoops.create({
69238
69575
  context,
69239
69576
  report: async (connectionId, relay2) => {
@@ -69248,6 +69585,10 @@ async function runConnectLoop({ context }) {
69248
69585
  await relays.sync();
69249
69586
  await rearmRushGuards({ context }).catch((error62) => {
69250
69587
  context.err(`laze connect: no rush guard check this round: ${String(error62)}
69588
+ `);
69589
+ });
69590
+ await watchRushDelivery({ context, said }).catch((error62) => {
69591
+ context.err(`laze connect: no rush delivery check this round: ${String(error62)}
69251
69592
  `);
69252
69593
  });
69253
69594
  await save(run4);
@@ -69279,17 +69620,17 @@ var CONNECT_SERVICE_USAGE = `laze connect install|status|stop|uninstall|run: the
69279
69620
  \`laze openclaw connect --local\`, whose OpenClaw relay it also runs.
69280
69621
  `;
69281
69622
  function installedPathOf({ context }) {
69282
- return join11(connectFolderOf({ context }), "service.json");
69623
+ return join12(connectFolderOf({ context }), "service.json");
69283
69624
  }
69284
69625
  function logPathOf({ context }) {
69285
- return join11(connectFolderOf({ context }), "connect.log");
69626
+ return join12(connectFolderOf({ context }), "connect.log");
69286
69627
  }
69287
69628
  function homeOf({ context }) {
69288
- return context.environment.inherited.HOME ?? dirname9(dirname9(context.environment.configPath));
69629
+ return context.environment.inherited.HOME ?? dirname10(dirname10(context.environment.configPath));
69289
69630
  }
69290
69631
  function serviceNameOf({ context }) {
69291
69632
  const { configPath } = context.environment;
69292
- if (configPath === join11(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
69633
+ if (configPath === join12(homeOf({ context }), ".laze", "config.json")) return "laze-connect";
69293
69634
  return `laze-connect-${createHash("sha256").update(configPath).digest("hex").slice(0, 8)}`;
69294
69635
  }
69295
69636
  function serviceEnvOf({ context }) {
@@ -69312,9 +69653,9 @@ async function run({ context, command }) {
69312
69653
  async function installSystemd({ context }) {
69313
69654
  const name3 = serviceNameOf({ context });
69314
69655
  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 });
69656
+ const base = env.XDG_CONFIG_HOME || join12(homeOf({ context }), ".config");
69657
+ const file3 = join12(base, "systemd", "user", `${name3}.service`);
69658
+ await mkdir9(dirname10(file3), { recursive: true });
69318
69659
  await writeFile8(
69319
69660
  file3,
69320
69661
  systemdUnitOf({ argv: runArgvOf({ context }), env: serviceEnvOf({ context }) })
@@ -69328,9 +69669,9 @@ async function installSystemd({ context }) {
69328
69669
  async function installLaunchd({ context }) {
69329
69670
  const name3 = serviceNameOf({ context });
69330
69671
  const label3 = `ai.laze.${name3}`;
69331
- const file3 = join11(homeOf({ context }), "Library", "LaunchAgents", `${label3}.plist`);
69672
+ const file3 = join12(homeOf({ context }), "Library", "LaunchAgents", `${label3}.plist`);
69332
69673
  const log = logPathOf({ context });
69333
- await mkdir8(dirname9(file3), { recursive: true });
69674
+ await mkdir9(dirname10(file3), { recursive: true });
69334
69675
  await writeFile8(
69335
69676
  file3,
69336
69677
  launchAgentOf({
@@ -69383,7 +69724,7 @@ async function installConnectService({ context }) {
69383
69724
  const manager = await managerOf({ context });
69384
69725
  const install = { systemd: installSystemd, launchd: installLaunchd, detached: installDetached };
69385
69726
  const installed = await install[manager]({ context });
69386
- await mkdir8(dirname9(path), { recursive: true, mode: 448 });
69727
+ await mkdir9(dirname10(path), { recursive: true, mode: 448 });
69387
69728
  await writeFile8(path, JSON.stringify(installed));
69388
69729
  return describeInstalled({ installed });
69389
69730
  }
@@ -69420,8 +69761,11 @@ async function status2({ context }) {
69420
69761
  `
69421
69762
  );
69422
69763
  }
69423
- for (const row of await rushListenersOf({ context })) context.out(`${rushLineOf({ row })}
69764
+ for (const row of await rushListenersOf({ context })) {
69765
+ const waiting = await waitingOf({ context, profile: row.profile });
69766
+ context.out(`${rushLineOf({ row })}${inLazeOf({ row, waiting, nowMs: context.nowMs() })}
69424
69767
  `);
69768
+ }
69425
69769
  const config2 = await context.store.read();
69426
69770
  const linked = Object.entries(config2.profiles).filter(([, profile]) => profile.delivery);
69427
69771
  if (linked.length === 0) {
@@ -69436,11 +69780,31 @@ async function status2({ context }) {
69436
69780
  }
69437
69781
  function rushLineOf({ row }) {
69438
69782
  const head = `${row.profile} Claude Code in rush ${row.rushId} ${row.standing}`;
69439
- if (row.standing === "awake") return `${head}, its Claude Code delivers`;
69783
+ if (row.standing === "awake" && row.waiterPid) {
69784
+ return `${head}, its Claude Code delivers (waiter pid ${row.waiterPid})`;
69785
+ }
69786
+ if (row.standing === "awake") {
69787
+ return `${head}, no hook waiter right now: the connect service hands over what waits over ${UNDELIVERED_AFTER_MS / 1e3}s`;
69788
+ }
69440
69789
  if (row.standing === "stopped") return `${head}, gets messages when rush starts it again`;
69441
69790
  if (row.listenerPid) return `${head}, guard pid ${row.listenerPid}`;
69442
69791
  return `${head}, NO LISTENER: messages wait in Laze; \`laze connect install\` brings a guard back`;
69443
69792
  }
69793
+ function inLazeOf({
69794
+ row,
69795
+ waiting,
69796
+ nowMs
69797
+ }) {
69798
+ if (!waiting) return "; Laze could not say what waits";
69799
+ const away = boundAwayOf({ waiting, key: row.key });
69800
+ const bound = away ? `; Laze binds the agent to ${away}, not this session` : "";
69801
+ const waited = waitedMsOf({ waiting, nowMs });
69802
+ if (waiting.count === 0) return bound;
69803
+ const age = `the oldest for ${Math.round(waited / 1e3)}s`;
69804
+ if (waited > UNDELIVERED_AFTER_MS)
69805
+ return `${bound}; UNDELIVERED: ${waiting.count} waiting, ${age}`;
69806
+ return `${bound}; ${waiting.count} waiting, ${age}`;
69807
+ }
69444
69808
  async function stop({ context }) {
69445
69809
  const installed = await readJson({ path: installedPathOf({ context }) });
69446
69810
  if (!installed) {
@@ -69523,7 +69887,7 @@ async function takeLock({
69523
69887
  if (served && context.processes.alive(served) && !mine4) return false;
69524
69888
  context.processes.stop(holder.pid);
69525
69889
  }
69526
- await mkdir9(dirname10(path), { recursive: true, mode: 448 });
69890
+ await mkdir10(dirname11(path), { recursive: true, mode: 448 });
69527
69891
  await writeFile9(
69528
69892
  path,
69529
69893
  JSON.stringify({
@@ -69681,13 +70045,13 @@ async function monitorServes({
69681
70045
  // src/services/codex-link.service.ts
69682
70046
  import { createReadStream } from "node:fs";
69683
70047
  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";
70048
+ import { join as join14, resolve as resolve3 } from "node:path";
69685
70049
  import { createInterface as createInterface2 } from "node:readline";
69686
70050
 
69687
70051
  // src/services/codex-adopt.service.ts
69688
70052
  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";
70053
+ import { mkdir as mkdir11, readdir as readdir4, readFile as readFile11, rm as rm5, stat as stat3, writeFile as writeFile10 } from "node:fs/promises";
70054
+ import { dirname as dirname12, join as join13 } from "node:path";
69691
70055
  import { createInterface } from "node:readline";
69692
70056
 
69693
70057
  // src/rules/codex-requests.rules.ts
@@ -69807,11 +70171,11 @@ var CodexAppServer = class _CodexAppServer {
69807
70171
  }
69808
70172
  };
69809
70173
  async function newestThreadId({ codexHome }) {
69810
- const root = join12(codexHome, "sessions");
70174
+ const root = join13(codexHome, "sessions");
69811
70175
  const files2 = await readdir4(root, { recursive: true }).catch(() => []);
69812
70176
  const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
69813
70177
  const dated = await Promise.all(
69814
- rollouts.map(async (file3) => ({ file: file3, at: (await stat3(join12(root, file3))).mtimeMs }))
70178
+ rollouts.map(async (file3) => ({ file: file3, at: (await stat3(join13(root, file3))).mtimeMs }))
69815
70179
  );
69816
70180
  const newest = dated.toSorted((a, b) => b.at - a.at)[0]?.file ?? "";
69817
70181
  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 +70272,7 @@ async function startAdoptInBackground({
69908
70272
  const adopt = ["adopt", "codex", "--profile", profile, ...threadFlag({ thread: thread2 })];
69909
70273
  const argv = [...context.program, ...adopt, "--supervise"];
69910
70274
  const pid = context.processes.spawnDetached({ argv, logPath: log });
69911
- await mkdir10(dirname11(path), { recursive: true, mode: 448 });
70275
+ await mkdir11(dirname12(path), { recursive: true, mode: 448 });
69912
70276
  await writeFile10(path, JSON.stringify({ pid, thread: thread2, log, startedAt: context.nowMs() }));
69913
70277
  return [
69914
70278
  `Started \`${laze} adopt codex\` in the background (pid ${pid}). It answers each Laze message`,
@@ -70004,7 +70368,7 @@ async function adoptedThreadOf({
70004
70368
  }
70005
70369
  const forked = record3((await codex.call("thread/fork", { threadId })).thread).id;
70006
70370
  if (typeof forked !== "string") throw new Error("thread/fork answered no thread id");
70007
- await mkdir10(dirname11(path), { recursive: true, mode: 448 });
70371
+ await mkdir11(dirname12(path), { recursive: true, mode: 448 });
70008
70372
  await writeFile10(path, JSON.stringify({ ...forks, [threadId]: forked }));
70009
70373
  context.out(
70010
70374
  `Codex holds thread ${threadId} open elsewhere; answering in its new fork ${forked}.
@@ -70076,13 +70440,13 @@ async function newestThreadIn({
70076
70440
  codexHome,
70077
70441
  directory
70078
70442
  }) {
70079
- const root = join13(codexHome, "sessions");
70443
+ const root = join14(codexHome, "sessions");
70080
70444
  const files2 = await readdir5(root, { recursive: true }).catch(() => []);
70081
70445
  const rollouts = files2.filter((file3) => /rollout-.*\.jsonl$/.test(file3));
70082
70446
  const dated = await Promise.all(
70083
70447
  rollouts.map(async (file3) => ({
70084
- path: join13(root, file3),
70085
- at: await stat4(join13(root, file3)).then(
70448
+ path: join14(root, file3),
70449
+ at: await stat4(join14(root, file3)).then(
70086
70450
  (info) => info.mtimeMs,
70087
70451
  () => 0
70088
70452
  )
@@ -70152,9 +70516,9 @@ async function linkCodexSession({
70152
70516
  }
70153
70517
 
70154
70518
  // src/services/laze-plugin.service.ts
70155
- import { mkdir as mkdir11, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
70519
+ import { mkdir as mkdir12, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
70156
70520
  import { homedir as homedir3 } from "node:os";
70157
- import { dirname as dirname12, join as join14 } from "node:path";
70521
+ import { dirname as dirname13, join as join15 } from "node:path";
70158
70522
 
70159
70523
  // src/rules/laze-plugin.rules.ts
70160
70524
  var LAZE_PLUGIN = "laze";
@@ -70273,10 +70637,10 @@ function lazePluginFiles({
70273
70637
  var REGISTER_LIMIT_MS = 6e4;
70274
70638
  var quote2 = (value) => `'${value.replaceAll("'", "'\\''")}'`;
70275
70639
  function pluginFolderOf({ context }) {
70276
- return join14(dirname12(context.environment.configPath), "plugins");
70640
+ return join15(dirname13(context.environment.configPath), "plugins");
70277
70641
  }
70278
70642
  async function pluginIsCurrent({ context }) {
70279
- const manifest = join14(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
70643
+ const manifest = join15(pluginFolderOf({ context }), LAZE_PLUGIN, ".claude-plugin", "plugin.json");
70280
70644
  const written = await readFile12(manifest, "utf8").then(
70281
70645
  (text2) => JSON.parse(text2).version,
70282
70646
  () => void 0
@@ -70291,8 +70655,8 @@ async function writeLazePlugin({ context }) {
70291
70655
  configPath: context.environment.configPath
70292
70656
  });
70293
70657
  for (const [path, text2] of Object.entries(files2)) {
70294
- const target = join14(folder, path);
70295
- await mkdir11(dirname12(target), { recursive: true });
70658
+ const target = join15(folder, path);
70659
+ await mkdir12(dirname13(target), { recursive: true });
70296
70660
  await writeFile11(target, text2);
70297
70661
  }
70298
70662
  return folder;
@@ -70323,8 +70687,8 @@ var RUN_FILES = ["hooks/hooks.json", "monitors/monitors.json"];
70323
70687
  async function cachedPluginOf({ context }) {
70324
70688
  const inherited = context.environment.inherited;
70325
70689
  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(
70690
+ const claude = inherited.CLAUDE_CONFIG_DIR || join15(home, ".claude");
70691
+ const listed = await readFile12(join15(claude, "plugins", "installed_plugins.json"), "utf8").then(
70328
70692
  (text2) => JSON.parse(text2),
70329
70693
  () => void 0
70330
70694
  );
@@ -70335,8 +70699,8 @@ async function refreshStaleCache({ context, folder }) {
70335
70699
  if (!cached2) return true;
70336
70700
  const read3 = (path) => readFile12(path, "utf8").catch(() => "");
70337
70701
  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;
70702
+ const ours = await read3(join15(folder, LAZE_PLUGIN, file3));
70703
+ if (ours === await read3(join15(cached2, file3))) continue;
70340
70704
  const plugin2 = `${LAZE_PLUGIN}@${LAZE_PLUGIN}`;
70341
70705
  const script = [
70342
70706
  `claude plugin uninstall ${plugin2} --scope user ${QUIET}`,
@@ -70347,7 +70711,7 @@ async function refreshStaleCache({ context, folder }) {
70347
70711
  return true;
70348
70712
  }
70349
70713
  function registeredMarkOf({ context }) {
70350
- return join14(pluginFolderOf({ context }), "registered");
70714
+ return join15(pluginFolderOf({ context }), "registered");
70351
70715
  }
70352
70716
  async function pluginRegistered({ context }) {
70353
70717
  return readFile12(registeredMarkOf({ context }), "utf8").then(
@@ -70364,7 +70728,7 @@ async function installLazePlugin({ context }) {
70364
70728
  async function plugin({ context, args }) {
70365
70729
  const action = args.words[1] ?? "install";
70366
70730
  if (action === "path") {
70367
- context.out(`${join14(pluginFolderOf({ context }), LAZE_PLUGIN)}
70731
+ context.out(`${join15(pluginFolderOf({ context }), LAZE_PLUGIN)}
70368
70732
  `);
70369
70733
  return 0;
70370
70734
  }
@@ -70382,8 +70746,8 @@ async function plugin({ context, args }) {
70382
70746
  }
70383
70747
 
70384
70748
  // 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";
70749
+ import { mkdir as mkdir13, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
70750
+ import { dirname as dirname14 } from "node:path";
70387
70751
  var LAZE_MCP_SERVER = "laze";
70388
70752
  var DEV_CHANNELS_FLAG = "--dangerously-load-development-channels";
70389
70753
  var ROUND_SECONDS3 = 50;
@@ -70473,7 +70837,7 @@ async function pushInbox({
70473
70837
  signal
70474
70838
  }) {
70475
70839
  const marker = statePathOf({ context, kind: "channels", profile });
70476
- await mkdir12(dirname13(marker), { recursive: true, mode: 448 });
70840
+ await mkdir13(dirname14(marker), { recursive: true, mode: 448 });
70477
70841
  await writeFile12(marker, JSON.stringify({ pid: context.processes.pid }));
70478
70842
  try {
70479
70843
  while (!signal.aborted) {
@@ -70501,8 +70865,8 @@ async function pushInbox({
70501
70865
  }
70502
70866
 
70503
70867
  // 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";
70868
+ import { mkdir as mkdir14, readFile as readFile13, writeFile as writeFile13 } from "node:fs/promises";
70869
+ import { dirname as dirname15 } from "node:path";
70506
70870
  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
70871
  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
70872
  function monitorsRunHere({ context }) {
@@ -70536,7 +70900,7 @@ async function markReloadTipTold({
70536
70900
  }) {
70537
70901
  if (!session) return;
70538
70902
  const path = toldPathOf({ context, session });
70539
- await mkdir13(dirname14(path), { recursive: true, mode: 448 });
70903
+ await mkdir14(dirname15(path), { recursive: true, mode: 448 });
70540
70904
  await writeFile13(path, String(context.nowMs()), { mode: 384 });
70541
70905
  }
70542
70906
  async function reloadTipOnce({
@@ -70611,8 +70975,8 @@ async function installHooks({
70611
70975
  directory,
70612
70976
  profile
70613
70977
  }) {
70614
- const folder = join15(directory, ".claude");
70615
- const path = join15(folder, "settings.local.json");
70978
+ const folder = join16(directory, ".claude");
70979
+ const path = join16(folder, "settings.local.json");
70616
70980
  const current2 = await readFile14(path, "utf8").then(
70617
70981
  (text2) => JSON.parse(text2),
70618
70982
  () => ({})
@@ -70624,7 +70988,7 @@ async function installHooks({
70624
70988
  waitCommand: command("wait"),
70625
70989
  preToolCommand: command("pre-tool")
70626
70990
  });
70627
- await mkdir14(folder, { recursive: true });
70991
+ await mkdir15(folder, { recursive: true });
70628
70992
  await writeFile14(path, `${JSON.stringify(settings2, null, 2)}
70629
70993
  `);
70630
70994
  return path;
@@ -70888,7 +71252,7 @@ async function addSessionStartWaiter({ context, args }) {
70888
71252
  const directory = context.environment.inherited.CLAUDE_PROJECT_DIR;
70889
71253
  const profile = flagText({ args, name: "profile" });
70890
71254
  if (!directory || !profile) return;
70891
- const path = join15(directory, ".claude", "settings.local.json");
71255
+ const path = join16(directory, ".claude", "settings.local.json");
70892
71256
  const settings2 = await readFile14(path, "utf8").then(
70893
71257
  (text2) => JSON.parse(text2),
70894
71258
  () => void 0
@@ -70898,7 +71262,7 @@ async function addSessionStartWaiter({ context, args }) {
70898
71262
  }
70899
71263
  async function refreshPlugin({ context }) {
70900
71264
  if (await pluginIsCurrent({ context })) return;
70901
- const logPath = join15(pluginFolderOf({ context }), "install.log");
71265
+ const logPath = join16(pluginFolderOf({ context }), "install.log");
70902
71266
  context.processes.spawnDetached({ argv: [...context.program, "plugin", "install"], logPath });
70903
71267
  }
70904
71268
  async function stopHook({ context, args }) {
@@ -71775,8 +72139,8 @@ async function requestAgent({ context, args }) {
71775
72139
  }
71776
72140
 
71777
72141
  // 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";
72142
+ import { mkdir as mkdir16, readdir as readdir6, readFile as readFile16, writeFile as writeFile16 } from "node:fs/promises";
72143
+ import { dirname as dirname16, join as join18, relative as relative3, resolve as resolve6, sep as sep2 } from "node:path";
71780
72144
 
71781
72145
  // ../../modules/app/contract/src/app.connections.ts
71782
72146
  var appFunctionNameSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/);
@@ -72032,7 +72396,8 @@ var createAppInputSchemaDefinition = external_exports.object({
72032
72396
  /** Defaults to the name in lower case words. */
72033
72397
  slug: appSlugSchema.optional(),
72034
72398
  channelId: external_exports.string().min(1).optional(),
72035
- visibility: appVisibilitySchema.default("internal")
72399
+ /** Restricted unless chosen: owner, admins, shares and the conversations it is pinned to. */
72400
+ visibility: appVisibilitySchema.default("restricted")
72036
72401
  });
72037
72402
  var createAppInputSchema = createAppInputSchemaDefinition;
72038
72403
  var listAppsInputSchemaDefinition = external_exports.object({
@@ -72211,7 +72576,8 @@ var appKeyCallerViewSchemaDefinition = external_exports.object({
72211
72576
  });
72212
72577
  var signInHandoffInputSchemaDefinition = external_exports.object({
72213
72578
  ...appRefSchemaDefinition.shape,
72214
- site: appSiteSchema,
72579
+ /** Left out, the published site when there is one, else the draft. */
72580
+ site: appSiteSchema.optional(),
72215
72581
  /** Where the app sends the person after sign-in; kept on the app's own origin. */
72216
72582
  returnPath: external_exports.string().max(2e3).default("/")
72217
72583
  });
@@ -72219,6 +72585,8 @@ var signInHandoffInputSchema = signInHandoffInputSchemaDefinition;
72219
72585
  var signInHandoffSchemaDefinition = external_exports.object({
72220
72586
  /** The app origin's callback, carrying a one-use token valid only for this app and site. */
72221
72587
  redirectUrl: external_exports.string(),
72588
+ /** The site the token opens. */
72589
+ site: appSiteSchema,
72222
72590
  expiresAt: external_exports.iso.datetime()
72223
72591
  });
72224
72592
  var signInHandoffSchema = signInHandoffSchemaDefinition;
@@ -72357,7 +72725,9 @@ var listFunctionLogsInputSchema = listFunctionLogsInputSchemaDefinition;
72357
72725
  var appFunctionSettingsSchemaDefinition = external_exports.object({
72358
72726
  workspaceId: external_exports.string().min(1),
72359
72727
  /** Off: pushes with functions are refused and every function answers app_functions_disabled. */
72360
- functionsEnabled: external_exports.boolean()
72728
+ functionsEnabled: external_exports.boolean(),
72729
+ /** On: a Builder makes an app public at once. Off: a public publish asks an admin. */
72730
+ publicAppsAllowed: external_exports.boolean()
72361
72731
  });
72362
72732
  var appFunctionSettingsSchema = appFunctionSettingsSchemaDefinition;
72363
72733
  var workspaceRefSchemaDefinition = external_exports.object({ workspaceId: external_exports.string().min(1) });
@@ -72367,6 +72737,11 @@ var setFunctionsEnabledInputSchemaDefinition = external_exports.object({
72367
72737
  enabled: external_exports.boolean()
72368
72738
  });
72369
72739
  var setFunctionsEnabledInputSchema = setFunctionsEnabledInputSchemaDefinition;
72740
+ var setPublicAppsAllowedInputSchemaDefinition = external_exports.object({
72741
+ workspaceId: external_exports.string().min(1),
72742
+ allowed: external_exports.boolean()
72743
+ });
72744
+ var setPublicAppsAllowedInputSchema = setPublicAppsAllowedInputSchemaDefinition;
72370
72745
  var appRestoreSchemaDefinition = external_exports.object({
72371
72746
  id: external_exports.string(),
72372
72747
  /** The time the data went back to; absent when the restore undid an earlier one. */
@@ -72467,7 +72842,11 @@ var appAccessSchemaDefinition = external_exports.object({
72467
72842
  /** Pending requests, to the app's Builders; empty for anyone else. */
72468
72843
  requests: external_exports.array(appAccessRequestSchemaDefinition),
72469
72844
  /** The reader's own role. */
72470
- role: appRoleSchema
72845
+ role: appRoleSchema,
72846
+ /** The workspace's name, for "Everyone in <workspace>". */
72847
+ workspaceName: external_exports.string(),
72848
+ /** Whether a Builder makes it public without asking an admin. */
72849
+ publicAppsAllowed: external_exports.boolean()
72471
72850
  });
72472
72851
  var appAccessSchema = appAccessSchemaDefinition;
72473
72852
  var grantAppAccessInputSchemaDefinition = external_exports.object({
@@ -72859,7 +73238,9 @@ var pinAppInputSchemaDefinition = external_exports.object({
72859
73238
  workspaceId: external_exports.string().min(1),
72860
73239
  appId: external_exports.string().min(1),
72861
73240
  /** The conversation, by id or by channel name with or without `#`. */
72862
- channel: external_exports.string().trim().min(1).max(120)
73241
+ channel: external_exports.string().trim().min(1).max(120),
73242
+ /** What the conversation's members may do: editor unless the pinner picked view-only. */
73243
+ role: external_exports.enum(["viewer", "editor"]).optional()
72863
73244
  });
72864
73245
  var pinAppInputSchema = pinAppInputSchemaDefinition;
72865
73246
  var channelPinsInputSchemaDefinition = external_exports.object({
@@ -72885,7 +73266,9 @@ var reorderPinsInputSchema = reorderPinsInputSchemaDefinition;
72885
73266
  var pinAppByKeyInputSchemaDefinition = external_exports.object({
72886
73267
  appId: external_exports.string().min(1),
72887
73268
  /** Absent in an agent's turn means the conversation the turn runs in. */
72888
- channel: external_exports.string().trim().min(1).max(120).optional()
73269
+ channel: external_exports.string().trim().min(1).max(120).optional(),
73270
+ /** On a pin: what the conversation's members may do, editor unless view-only. */
73271
+ role: external_exports.enum(["viewer", "editor"]).optional()
72889
73272
  });
72890
73273
  var channelPinsByKeyInputSchemaDefinition = channelPinsInputSchemaDefinition.omit({
72891
73274
  workspaceId: true
@@ -72935,7 +73318,7 @@ var appBackupCheckAlertsSchemaDefinition = external_exports.object({
72935
73318
  });
72936
73319
 
72937
73320
  // ../../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();
73321
+ 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
73322
  var appConnectionsTrpc = defineTrpcContract("app").query("connections").withInput(appRefSchema).withOutput(appConnectionsSchema).mutation("allowConnection").withInput(appConnectionRefSchema).withOutput(appConnectionsSchema).mutation("revokeConnection").withInput(appConnectionRefSchema).withOutput(appConnectionsSchema).build();
72940
73323
  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
73324
  var appTrpc = joinTrpcContracts("app", appMainTrpc, appConnectionsTrpc, appPinsTrpc);
@@ -72978,6 +73361,7 @@ var renameAppByKeyInputSchemaDefinition = renameAppInputSchema.omit(byKey);
72978
73361
  var deleteAppByKeyInputSchemaDefinition = deleteAppInputSchema.omit(byKey);
72979
73362
  var functionSettingsByKeyInputSchemaDefinition = external_exports.object({});
72980
73363
  var setFunctionsEnabledByKeyInputSchemaDefinition = setFunctionsEnabledInputSchema.omit(byKey);
73364
+ var setPublicAppsAllowedByKeyInputSchemaDefinition = setPublicAppsAllowedInputSchema.omit(byKey);
72981
73365
  var restoreDataByKeyInputSchemaDefinition = external_exports.object({
72982
73366
  ...appByKeySchemaDefinition.shape,
72983
73367
  /** The time to go back to, ISO 8601. */
@@ -73058,8 +73442,8 @@ var appCliCommands = [
73058
73442
  {
73059
73443
  command: "laze app publish",
73060
73444
  operation: "requestPublish",
73061
- arguments: ["[version]", "--visibility internal|public"],
73062
- summary: "Publish for the workspace now; a public publish waits for an approval"
73445
+ arguments: ["[version]", "--visibility restricted|channel|internal|public"],
73446
+ summary: "Publish now for the people who can open the app; opening it to more people waits for an approval"
73063
73447
  },
73064
73448
  {
73065
73449
  command: "laze app make-internal",
@@ -73172,8 +73556,8 @@ var appCliCommands = [
73172
73556
  {
73173
73557
  command: "laze app pin",
73174
73558
  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"
73559
+ arguments: ["[app]", "--channel <c>", "--view-only"],
73560
+ 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
73561
  },
73178
73562
  {
73179
73563
  command: "laze app unpin",
@@ -73223,6 +73607,12 @@ var appCliCommands = [
73223
73607
  arguments: ["[on|off]"],
73224
73608
  summary: "Whether the workspace's apps run server functions; on and off need an admin"
73225
73609
  },
73610
+ {
73611
+ command: "laze app public-apps",
73612
+ operation: "setPublicAppsAllowed",
73613
+ arguments: ["[on|off]"],
73614
+ summary: "Whether Builders make apps public without asking an admin (on by default); on and off need an admin"
73615
+ },
73226
73616
  {
73227
73617
  command: "laze app backups",
73228
73618
  operation: "getBackups",
@@ -74057,6 +74447,18 @@ var functions = async ({ context, args, signed: signed2 }) => {
74057
74447
  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
74448
  print2({ context, args, value: settings2, text: text2 });
74059
74449
  };
74450
+ var publicApps = async ({ context, args, signed: signed2 }) => {
74451
+ const word3 = args.words[2];
74452
+ if (word3 !== void 0 && word3 !== "on" && word3 !== "off") {
74453
+ throw new CliUsageError("Usage: laze app public-apps [on|off]");
74454
+ }
74455
+ const client = await signed2();
74456
+ const settings2 = word3 === void 0 ? await client.post("/api/apps/functions", {}) : await client.post("/api/apps/public-apps", {
74457
+ allowed: word3 === "on"
74458
+ });
74459
+ 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";
74460
+ print2({ context, args, value: settings2, text: text2 });
74461
+ };
74060
74462
  function backupsText({ name: name3, status: status9 }) {
74061
74463
  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
74464
  const replicating = status9.replicating ? "The published data replicates to object storage." : "The published data does not replicate on this host.";
@@ -74137,6 +74539,7 @@ var appManageCommands = {
74137
74539
  delete: remove,
74138
74540
  "revoke-lease": revokeLease,
74139
74541
  functions,
74542
+ "public-apps": publicApps,
74140
74543
  backups,
74141
74544
  restore,
74142
74545
  users,
@@ -74189,16 +74592,19 @@ async function appPinCommand({
74189
74592
  }) {
74190
74593
  const channel = flagText({ args, name: "channel" });
74191
74594
  const { client, appId, name: name3 } = await open3();
74595
+ const viewOnly = verb === "pin" && Boolean(args.flags["view-only"]);
74192
74596
  const listed = await client.post(`/api/apps/${verb}`, {
74193
74597
  appId,
74194
- ...channel ? { channel } : {}
74598
+ ...channel ? { channel } : {},
74599
+ ...viewOnly ? { role: "viewer" } : {}
74195
74600
  });
74196
74601
  const where = channel || "this conversation";
74602
+ const may = viewOnly ? "may open and read the app" : "may open and edit the app";
74197
74603
  print3({
74198
74604
  context,
74199
74605
  args,
74200
74606
  value: listed,
74201
- text: verb === "pin" ? `Pinned ${name3} to ${where}: everyone in it sees the tab and may open the app.
74607
+ text: verb === "pin" ? `Pinned ${name3} to ${where}: everyone in it and their agents see the tab and ${may}.
74202
74608
  ` : `Unpinned ${name3} from ${where}. The app and its data stay.
74203
74609
  `
74204
74610
  });
@@ -74221,7 +74627,7 @@ async function appPinsCommand({
74221
74627
  import { execFile } from "node:child_process";
74222
74628
  import { mkdtemp, rm as rm8, writeFile as writeFile15 } from "node:fs/promises";
74223
74629
  import { tmpdir } from "node:os";
74224
- import { join as join16 } from "node:path";
74630
+ import { join as join17 } from "node:path";
74225
74631
  import { promisify } from "node:util";
74226
74632
  var run2 = promisify(execFile);
74227
74633
  var MODULE_SYNTAX = /^\s*(import|export)\s/m;
@@ -74250,11 +74656,11 @@ async function scriptErrorsOf({
74250
74656
  const unknown2 = unknownCollectionsOf({ files: files2, collections });
74251
74657
  const scripts = files2.flatMap(scriptsOf);
74252
74658
  if (scripts.length === 0) return unknown2;
74253
- const dir = await mkdtemp(join16(tmpdir(), "laze-app-check-"));
74659
+ const dir = await mkdtemp(join17(tmpdir(), "laze-app-check-"));
74254
74660
  try {
74255
74661
  const errors = await Promise.all(
74256
74662
  scripts.map(async (script, index) => {
74257
- const file3 = join16(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
74663
+ const file3 = join17(dir, `${index}.${script.module ? "mjs" : "cjs"}`);
74258
74664
  await writeFile15(file3, script.code);
74259
74665
  try {
74260
74666
  await run2(process.execPath, ["--check", file3]);
@@ -74430,7 +74836,7 @@ function folderOf({ context, word: word3 }) {
74430
74836
  return resolve6(context.cwd, word3 ?? ".");
74431
74837
  }
74432
74838
  async function readManifest(folder) {
74433
- const text2 = await readFile16(join17(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
74839
+ const text2 = await readFile16(join18(folder, APP_MANIFEST_FILE), "utf8").catch(() => void 0);
74434
74840
  if (text2 === void 0) return void 0;
74435
74841
  const parsed = appManifestSchema.safeParse(JSON.parse(text2));
74436
74842
  if (!parsed.success) {
@@ -74478,7 +74884,7 @@ async function listFiles(folder) {
74478
74884
  while (pending.length > 0 && found.length <= MAX_FILES) {
74479
74885
  const current2 = pending.pop() ?? folder;
74480
74886
  for (const entry of await readdir6(current2, { withFileTypes: true })) {
74481
- const path = join17(current2, entry.name);
74887
+ const path = join18(current2, entry.name);
74482
74888
  const rel = relative3(folder, path).split(sep2).join("/");
74483
74889
  if (isSkippedPath({ path: rel })) continue;
74484
74890
  if (entry.isDirectory()) pending.push(path);
@@ -74519,11 +74925,11 @@ var appCreate = async ({ context, args }) => {
74519
74925
  ...visibility ? { visibility } : {}
74520
74926
  });
74521
74927
  const folder = resolve6(context.cwd, flagText({ args, name: "dir", fallback: app2.slug }));
74522
- await mkdir15(folder, { recursive: true });
74928
+ await mkdir16(folder, { recursive: true });
74523
74929
  const files2 = template ? templateFiles({ template, name: name3 }) : {};
74524
74930
  for (const [path, content] of Object.entries(files2)) {
74525
- await mkdir15(dirname15(join17(folder, path)), { recursive: true });
74526
- await writeFile16(join17(folder, path), content);
74931
+ await mkdir16(dirname16(join18(folder, path)), { recursive: true });
74932
+ await writeFile16(join18(folder, path), content);
74527
74933
  }
74528
74934
  const manifest = {
74529
74935
  app: { id: app2.id, name: app2.name, slug: app2.slug },
@@ -74531,7 +74937,7 @@ var appCreate = async ({ context, args }) => {
74531
74937
  views: template?.views ? [...template.views] : [],
74532
74938
  seed: template ? { ...template.seed } : {}
74533
74939
  };
74534
- await writeFile16(join17(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74940
+ await writeFile16(join18(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74535
74941
  `);
74536
74942
  print5({
74537
74943
  context,
@@ -74700,8 +75106,8 @@ var appPull = async ({ context, args }) => {
74700
75106
  );
74701
75107
  }
74702
75108
  for (const file3 of pulled.files) {
74703
- const target = join17(folder, ...file3.path.split("/"));
74704
- await mkdir15(dirname15(target), { recursive: true });
75109
+ const target = join18(folder, ...file3.path.split("/"));
75110
+ await mkdir16(dirname16(target), { recursive: true });
74705
75111
  await writeFile16(
74706
75112
  target,
74707
75113
  file3.encoding === "base64" ? Buffer.from(file3.content, "base64") : file3.content
@@ -74719,7 +75125,7 @@ var appPull = async ({ context, args }) => {
74719
75125
  ])
74720
75126
  )
74721
75127
  };
74722
- await writeFile16(join17(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
75128
+ await writeFile16(join18(folder, APP_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
74723
75129
  `);
74724
75130
  const names = pulled.collections.map((collection) => collection.name);
74725
75131
  const where = relative3(context.cwd, folder) || ".";
@@ -74749,16 +75155,22 @@ var appPublish = async ({ context, args }) => {
74749
75155
  });
74750
75156
  print5({ context, args, value: outcome, text: publishLine(outcome) });
74751
75157
  };
75158
+ var PUBLISH_AUDIENCE = {
75159
+ restricted: "the people it is shared with and its pinned channels",
75160
+ channel: "its channel",
75161
+ internal: "the workspace",
75162
+ public: "everyone"
75163
+ };
74752
75164
  function publishLine(outcome) {
74753
75165
  const { request: request2 } = outcome;
74754
75166
  if (request2.status === "pending") {
74755
- return `Waiting for approval (${request2.id}): a public publish needs a workspace admin's yes.
75167
+ return `Waiting for approval (${request2.id}): opening the app to more people needs a workspace admin's yes.
74756
75168
  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
75169
  Nothing changes for visitors until then; the request expires after 72 hours.
74758
75170
  `;
74759
75171
  }
74760
75172
  if (request2.status === "denied") return "The publish was denied.\n";
74761
- const audience = request2.visibility === "public" ? "everyone" : "the workspace";
75173
+ const audience = PUBLISH_AUDIENCE[request2.visibility];
74762
75174
  return `Published ${request2.version.slice(0, 7)} for ${audience}: ${outcome.app.publishedUrl}
74763
75175
  `;
74764
75176
  }
@@ -75356,6 +75768,7 @@ var APP_COMMANDS = {
75356
75768
  delete: managed(appManageCommands.delete),
75357
75769
  "revoke-lease": managed(appManageCommands["revoke-lease"]),
75358
75770
  functions: managed(appManageCommands.functions),
75771
+ "public-apps": managed(appManageCommands["public-apps"]),
75359
75772
  backups: managed(appManageCommands.backups),
75360
75773
  restore: managed(appManageCommands.restore),
75361
75774
  users: managed(appManageCommands.users),
@@ -75513,6 +75926,15 @@ ${BILLING_USAGE}`);
75513
75926
  }
75514
75927
  return value;
75515
75928
  }
75929
+ function prepaidNoteOf(account, of) {
75930
+ const { prepaid, overdraft = 0, welcome = 0 } = account.credits;
75931
+ const notes = [
75932
+ prepaid < 0 ? `${of(-prepaid)} owed, paid first by the next top-up` : null,
75933
+ overdraft > 0 ? `may go down to -${of(overdraft)}` : null,
75934
+ welcome > 0 ? `welcome credit, ${of(welcome)}` : null
75935
+ ].filter((note) => note !== null);
75936
+ return notes.length > 0 ? ` (${notes.join(", ")})` : "";
75937
+ }
75516
75938
  function printAccount({ context, args }, account) {
75517
75939
  if (args.flags.json) return printJson(context, account);
75518
75940
  const of = (amount) => money(amount, account.currency);
@@ -75521,7 +75943,7 @@ function printAccount({ context, args }, account) {
75521
75943
  context.out(`Plan: ${plan2}${pending}
75522
75944
  `);
75523
75945
  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)" : ""}
75946
+ `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
75947
  `
75526
75948
  );
75527
75949
  const recharge = account.autoRecharge;
@@ -75632,8 +76054,8 @@ async function billing({ context, args }) {
75632
76054
 
75633
76055
  // src/services/browser-commands.service.ts
75634
76056
  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";
76057
+ import { mkdir as mkdir17, readFile as readFile17, writeFile as writeFile17 } from "node:fs/promises";
76058
+ import { dirname as dirname17, join as join19 } from "node:path";
75637
76059
 
75638
76060
  // src/services/browser-tab-commands.service.ts
75639
76061
  var BROWSER_TAB_PATHS = {
@@ -76174,22 +76596,30 @@ var USAGE6 = [
76174
76596
  "",
76175
76597
  BROWSER_TAB_USAGE
76176
76598
  ].join("\n");
76177
- async function turnTokenOf2({ context }) {
76599
+ async function turnTokenOf2({
76600
+ context,
76601
+ args,
76602
+ client,
76603
+ agent: agent2
76604
+ }) {
76178
76605
  const env = context.environment.inherited;
76179
76606
  const pinned = env.LAZE_TURN_TOKEN?.trim();
76180
76607
  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
- );
76608
+ if (env.LAZE_TURN_FILE) {
76609
+ return readFile17(env.LAZE_TURN_FILE, "utf8").then(
76610
+ (text2) => text2.trim(),
76611
+ () => ""
76612
+ );
76613
+ }
76614
+ if (!agent2) return "";
76615
+ return connectedTurnTokenOf({ client, channelId: flagText({ args, name: "channel" }) || null });
76186
76616
  }
76187
76617
  async function computeClient({
76188
76618
  context,
76189
76619
  args
76190
76620
  }) {
76191
- const { client } = await signedIn({ context, args });
76192
- const turn = await turnTokenOf2({ context });
76621
+ const { client, profile } = await signedIn({ context, args });
76622
+ const turn = await turnTokenOf2({ context, args, client, agent: profile.kind === "agent" });
76193
76623
  return turn ? client.withHeaders({ "x-laze-turn": turn }) : client;
76194
76624
  }
76195
76625
  function siteLine(machine2) {
@@ -76253,7 +76683,7 @@ async function cdp({ context, args }) {
76253
76683
  }
76254
76684
  function bridgeStatePath({ context, machine: machine2 }) {
76255
76685
  const safe = machine2.replace(/[^a-zA-Z0-9_-]/g, "_");
76256
- return join18(dirname16(context.environment.configPath), "bridges", `${safe}.json`);
76686
+ return join19(dirname17(context.environment.configPath), "bridges", `${safe}.json`);
76257
76687
  }
76258
76688
  async function bridgePort({
76259
76689
  context,
@@ -76274,7 +76704,7 @@ async function bridgePort({
76274
76704
  key,
76275
76705
  ...target
76276
76706
  });
76277
- await mkdir16(dirname16(path), { recursive: true, mode: 448 });
76707
+ await mkdir17(dirname17(path), { recursive: true, mode: 448 });
76278
76708
  await writeFile17(path, JSON.stringify({ port, key }), { mode: 384 });
76279
76709
  return port;
76280
76710
  }
@@ -77871,9 +78301,11 @@ var billingAccountViewDefinition = external_exports.object({
77871
78301
  /** Included this period by the plan. */
77872
78302
  included: external_exports.number(),
77873
78303
  includedLeft: external_exports.number(),
77874
- /** The prepaid balance; a little below zero when the last call overshot it. */
78304
+ /** The prepaid balance; below zero while the workspace owes usage the next top-up pays. */
77875
78305
  prepaid: external_exports.number(),
77876
- /** The one-off welcome credit this workspace got; 0 when it got none. */
78306
+ /** How far below zero the prepaid balance may go before usage pauses; 0 when not at all. */
78307
+ overdraft: external_exports.number().default(0),
78308
+ /** The one-off welcome credit given before 2026-10-21; 0 when it got none. */
77877
78309
  welcome: external_exports.number().default(0),
77878
78310
  paused: external_exports.boolean(),
77879
78311
  pauseReason: pauseReasonSchema.nullable()
@@ -79656,7 +80088,7 @@ var judgeStatus = async ({ context, args }) => {
79656
80088
  const status9 = await client.get("/api/vault/judge");
79657
80089
  if (args.flags.json) return printJson4({ context, data: status9 });
79658
80090
  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"
80091
+ 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
80092
  );
79661
80093
  };
79662
80094
  var listDevices = async ({ context, args }) => {
@@ -79675,9 +80107,9 @@ var listDevices = async ({ context, args }) => {
79675
80107
 
79676
80108
  // src/services/vault-commands.service.ts
79677
80109
  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";
80110
+ import { mkdir as mkdir18, readFile as readFile22, rm as rm10, writeFile as writeFile18 } from "node:fs/promises";
79679
80111
  import { tmpdir as tmpdir2 } from "node:os";
79680
- import { dirname as dirname17, join as join19 } from "node:path";
80112
+ import { dirname as dirname18, join as join20 } from "node:path";
79681
80113
  var USAGE8 = `Usage: laze vault run <connection> --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
79682
80114
  Runs the command with the connection's values in its environment, on a Laze agent's computer,
79683
80115
  on a machine it runs on, or where a connected agent runs, with its own key.
@@ -79724,8 +80156,8 @@ function runKeyPathOf({
79724
80156
  profile = ""
79725
80157
  }) {
79726
80158
  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`);
80159
+ const base = turnFile ? dirname18(turnFile) : join20(tmpdir2(), "laze-vault", profile);
80160
+ return join20(base, "vault-run-keys", `${name3}.json`);
79729
80161
  }
79730
80162
  async function runKeyAt({ path }) {
79731
80163
  const saved3 = await readFile22(path, "utf8").then(
@@ -79738,7 +80170,7 @@ async function runKeyAt({ path }) {
79738
80170
  }
79739
80171
  const fresh = await generateEcdhKeys();
79740
80172
  const jwk = await globalThis.crypto.subtle.exportKey("jwk", fresh.privateKey);
79741
- await mkdir17(dirname17(path), { recursive: true, mode: 448 });
80173
+ await mkdir18(dirname18(path), { recursive: true, mode: 448 });
79742
80174
  await writeFile18(path, JSON.stringify({ publicKey: fresh.publicKey, privateKey: jwk }), {
79743
80175
  mode: 384
79744
80176
  });
@@ -80694,8 +81126,8 @@ var DOMAINS_USAGE = `Usage:
80694
81126
  var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
80695
81127
  `);
80696
81128
  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" : ""}
81129
+ const join24 = row.autoJoin ? "auto-join on" : "auto-join off";
81130
+ context.out(`${row.domain} ${join24}${row.enforced ? " single sign-on enforced" : ""}
80699
81131
  `);
80700
81132
  }
80701
81133
  async function list4({ context, args }) {
@@ -80730,131 +81162,6 @@ async function domains({ context, args }) {
80730
81162
  import { readFile as readFile26 } from "node:fs/promises";
80731
81163
  import { resolve as resolve10 } from "node:path";
80732
81164
 
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
81165
  // ../../modules/feed/contract/src/feed.ts
80859
81166
  var feedAuthorSchemaDefinition = external_exports.object({
80860
81167
  kind: external_exports.enum(["agent", "person", "system"]),
@@ -81029,7 +81336,8 @@ var feedApprovalSchemaDefinition = external_exports.object({
81029
81336
  "connector_connect",
81030
81337
  "app_access",
81031
81338
  "computer",
81032
- "agent_join"
81339
+ "agent_join",
81340
+ "vault_share"
81033
81341
  ]),
81034
81342
  requestId: external_exports.string(),
81035
81343
  /** The app, for an `app_publish` or `app_access` card. */
@@ -81117,6 +81425,13 @@ var feedGroupSummarySchemaDefinition = external_exports.object({
81117
81425
  counts: external_exports.array(external_exports.object({ label: external_exports.string(), count: external_exports.number().int().positive() }))
81118
81426
  });
81119
81427
  var feedGroupSummarySchema = feedGroupSummarySchemaDefinition;
81428
+ var feedDecisionsSchemaDefinition = external_exports.object({
81429
+ /** How many decisions wait; the banner shows only above zero. */
81430
+ count: external_exports.number().int().nonnegative(),
81431
+ /** The decision cards in feed order, each answered as on the feed. */
81432
+ items: external_exports.array(feedItemSchema)
81433
+ });
81434
+ var feedDecisionsSchema = feedDecisionsSchemaDefinition;
81120
81435
  var feedViewSchemaDefinition = external_exports.object({
81121
81436
  open: external_exports.array(feedItemSchema),
81122
81437
  comingUp: external_exports.array(feedItemSchema),
@@ -81195,7 +81510,9 @@ var answerFeedApprovalInputSchemaDefinition = external_exports.object({
81195
81510
  var answerFeedApprovalInputSchema = answerFeedApprovalInputSchemaDefinition;
81196
81511
  var decideFeedRequestInputSchemaDefinition = external_exports.object({
81197
81512
  ...itemRef.shape,
81198
- decision: external_exports.enum(["approved", "denied"])
81513
+ decision: external_exports.enum(["approved", "denied"]),
81514
+ /** With a Deny: why, for the agent that asked. It goes on the card as the person's reply. */
81515
+ resolutionNote: external_exports.string().max(4e3).optional()
81199
81516
  });
81200
81517
  var decideFeedRequestInputSchema = decideFeedRequestInputSchemaDefinition;
81201
81518
  var feedPublishDurationSchema = external_exports.enum(["once", "day", "always"]);
@@ -81316,9 +81633,10 @@ var feedFileLinkInputSchemaDefinition = external_exports.object({
81316
81633
  var feedFileLinkInputSchema = feedFileLinkInputSchemaDefinition;
81317
81634
  var feedFileLinkSchemaDefinition = external_exports.object({ url: external_exports.string(), expiresAt: external_exports.iso.datetime() });
81318
81635
  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();
81636
+ 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
81637
  var feedUi = uiTokens("feed");
81321
81638
  var FeedNavSlot = feedUi.component("nav");
81639
+ var FeedDecisionsSlot = feedUi.component("decisions");
81322
81640
  var FeedCountHooksToken = feedUi.hooks("count");
81323
81641
  var FeedChannelCardSlot = feedUi.component("channel-card");
81324
81642
  var FeedSearchSlot = feedUi.component("search");
@@ -81397,7 +81715,135 @@ var feedWakeIntentSchemaDefinition = external_exports.object({
81397
81715
  // ../../modules/feed/contract/src/feed.config.ts
81398
81716
  var feedConfig = Config.define(() => ({ publicBaseUrl }));
81399
81717
 
81718
+ // ../../modules/feed/contract/src/feed.decisions.ts
81719
+ function decisionsLineOf(count5) {
81720
+ return `${count5} ${count5 === 1 ? "decision" : "decisions"} waiting on you`;
81721
+ }
81722
+
81723
+ // src/rules/feed-input.rules.ts
81724
+ function csvCellsOf(line) {
81725
+ const cells = [];
81726
+ let cell = "";
81727
+ let quoted = false;
81728
+ for (let at = 0; at < line.length; at += 1) {
81729
+ const char = line[at];
81730
+ if (quoted && char === '"' && line[at + 1] === '"') {
81731
+ cell += '"';
81732
+ at += 1;
81733
+ } else if (char === '"') {
81734
+ quoted = !quoted;
81735
+ } else if (char === "," && !quoted) {
81736
+ cells.push(cell);
81737
+ cell = "";
81738
+ } else {
81739
+ cell += char;
81740
+ }
81741
+ }
81742
+ return [...cells, cell];
81743
+ }
81744
+ function richBodyOf({ kind: kind2, text: text2 }) {
81745
+ if (kind2 === "metric") {
81746
+ try {
81747
+ return { kind: kind2, ...JSON.parse(text2) };
81748
+ } catch {
81749
+ throw new Error("--metric takes JSON: {label, unit, value, delta, bars: [{label, value}]}");
81750
+ }
81751
+ }
81752
+ const [columns = [], ...rows] = text2.split(/\r?\n/).filter((line) => line.trim() !== "").map(csvCellsOf);
81753
+ return { kind: kind2, columns, rows };
81754
+ }
81755
+ function richOf(args) {
81756
+ const metric = flagText({ args, name: "metric" });
81757
+ const table = flagText({ args, name: "table" });
81758
+ if (metric && table) throw new Error("an item carries one rich body: pass --metric or --table");
81759
+ if (metric) return { kind: "metric", source: sourceOf(metric) };
81760
+ if (table) return { kind: "table", source: sourceOf(table) };
81761
+ return void 0;
81762
+ }
81763
+ var TEXT_FLAGS = { draft: "draft", summary: "summary" };
81764
+ var FEED_WRITING = `Write for a person deciding on a phone in a few seconds:
81765
+ - Title: the ask first, short enough to read in one glance.
81766
+ - --summary: one plain sentence of why.
81767
+ - No body: text to send goes in --draft, sources in --link, numbers in --metric or --table.
81768
+ - Plain words. No ids (email, thread, card, channel), no UTC times, no PR or ticket lists,
81769
+ no "Day 9." counters. Numbers only when they change the decision.
81770
+ - Not too terse either: whole sentences a person understands without context.
81771
+ - Replies and comments: same rules, short when you can.
81772
+ The server pushes back with feed_hard_to_read when the text reads like a log;
81773
+ rewrite it, or pass --force to post it as written.`;
81774
+ 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";
81775
+ function pairOf({ value, flag: flag2 }) {
81776
+ const at = value.indexOf("=");
81777
+ if (at <= 0 || at === value.length - 1) {
81778
+ throw new Error(`--${flag2} takes <label>=<value>, got "${value}"`);
81779
+ }
81780
+ return [value.slice(0, at), value.slice(at + 1)];
81781
+ }
81782
+ function sourceOf(value) {
81783
+ return value.startsWith("@") && value.length > 1 ? { file: value.slice(1) } : { text: value };
81784
+ }
81785
+ function dateOf(value) {
81786
+ return value === "none" ? null : value;
81787
+ }
81788
+ function snoozeOf(args) {
81789
+ const people2 = args.lists["snooze-for"] ?? [];
81790
+ if (people2.length === 0) return {};
81791
+ const until = flagText({ args, name: "until" });
81792
+ if (!until) throw new Error("--snooze-for needs --until <ISO time> or --until none");
81793
+ return { snoozeFor: { userIds: [...people2], until: dateOf(until) } };
81794
+ }
81795
+ function textsOf(args) {
81796
+ const texts = {};
81797
+ for (const [flag2, field] of Object.entries(TEXT_FLAGS)) {
81798
+ const value = flagText({ args, name: flag2 });
81799
+ if (value) texts[field] = sourceOf(value);
81800
+ }
81801
+ return texts;
81802
+ }
81803
+ function pairsOf(args) {
81804
+ const fields = {};
81805
+ const links = args.lists.link ?? [];
81806
+ if (links.length > 0) {
81807
+ fields.links = links.map((value) => {
81808
+ const [label3, url2] = pairOf({ value, flag: "link" });
81809
+ return { label: label3, url: url2 };
81810
+ });
81811
+ }
81812
+ const actions = args.lists.action ?? [];
81813
+ if (actions.length > 0) {
81814
+ fields.actions = actions.map((value) => {
81815
+ const [label3, message2] = pairOf({ value, flag: "action" });
81816
+ return { label: label3, message: message2 };
81817
+ });
81818
+ }
81819
+ return fields;
81820
+ }
81821
+ function feedFlagsOf({ args }) {
81822
+ if (args.flags.body !== void 0) throw new Error(FEED_NO_BODY);
81823
+ const fields = pairsOf(args);
81824
+ const tag = flagText({ args, name: "tag" });
81825
+ if (tag) fields.tag = tag;
81826
+ const header = flagText({ args, name: "draft-header" });
81827
+ if (header) fields.draftHeader = header.replaceAll("\\n", "\n");
81828
+ const doneLabel = flagText({ args, name: "done-label" });
81829
+ if (doneLabel) fields.doneLabel = doneLabel;
81830
+ for (const flag2 of ["urgent", "force"]) if (args.flags[flag2]) fields[flag2] = true;
81831
+ const showAt = flagText({ args, name: "show-at" });
81832
+ if (showAt) fields.showAt = dateOf(showAt);
81833
+ const group = flagText({ args, name: "group" });
81834
+ if (group) fields.group = group;
81835
+ const labels = args.lists.label ?? [];
81836
+ if (labels.length > 0) fields.labels = [...labels];
81837
+ const autoSendOn = flagText({ args, name: "auto-send-on" });
81838
+ if (autoSendOn) fields.autoSendOn = dateOf(autoSendOn);
81839
+ const rich = richOf(args);
81840
+ const texts = textsOf(args);
81841
+ return { fields: { ...fields, ...snoozeOf(args) }, texts, ...rich ? { rich } : {} };
81842
+ }
81843
+
81400
81844
  // src/services/feed-files.service.ts
81845
+ import { readFile as readFile25 } from "node:fs/promises";
81846
+ import { basename as basename4, resolve as resolve9 } from "node:path";
81401
81847
  async function bytesOf2({
81402
81848
  context,
81403
81849
  source
@@ -81486,6 +81932,7 @@ var USAGE10 = `Usage:
81486
81932
  laze feed group-summary <group>
81487
81933
  laze feed list [--json]
81488
81934
  laze feed count
81935
+ laze feed decisions [--json]
81489
81936
  laze feed act <id> <actionId> [--draft <text|@file>]
81490
81937
  laze feed comment <id> <text> [--draft <text|@file>] [--force]
81491
81938
  laze feed done|put-back|unsnooze <id>
@@ -81697,6 +82144,16 @@ async function feedCount({ context, args }) {
81697
82144
  context.out(`${answer4.count}
81698
82145
  `);
81699
82146
  }
82147
+ async function feedDecisions({ context, args }) {
82148
+ const { client } = await signedIn({ context, args });
82149
+ const answer4 = await client.get("/api/feed/mine/decisions");
82150
+ if (args.flags.json) return context.out(`${JSON.stringify(answer4, null, 2)}
82151
+ `);
82152
+ if (answer4.count === 0) return context.out("No decisions waiting on you.\n");
82153
+ context.out(`${decisionsLineOf(answer4.count)}
82154
+ `);
82155
+ for (const item of answer4.items) printCard2({ context, item });
82156
+ }
81700
82157
  async function feedAct({ context, args }) {
81701
82158
  const [itemId, actionId] = [args.words[2], args.words[3]];
81702
82159
  if (!itemId || !actionId) throw new CliUsageError(USAGE10);
@@ -81761,6 +82218,7 @@ var FEED_COMMANDS = {
81761
82218
  loops: feedLoops,
81762
82219
  list: feedList,
81763
82220
  count: feedCount,
82221
+ decisions: feedDecisions,
81764
82222
  act: feedAct,
81765
82223
  comment: feedComment,
81766
82224
  done: moveItem("done"),
@@ -82268,12 +82726,12 @@ async function ip({ context, args }) {
82268
82726
  }
82269
82727
 
82270
82728
  // 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";
82729
+ import { mkdir as mkdir19, readFile as readFile29, rename as rename5, rm as rm11, writeFile as writeFile19 } from "node:fs/promises";
82730
+ import { dirname as dirname19, join as join21 } from "node:path";
82273
82731
  var DEFAULT_WAIT_SECONDS2 = 100;
82274
82732
  var JOIN_USAGE = "Usage: laze join [--workspace <name|id|invite link>] [--for <email>] [--name <name>] [--note <text>] [--timeout <seconds>] [--project <folder>]";
82275
82733
  function pendingPathOf({ context }) {
82276
- return join20(dirname18(context.environment.configPath), "join", "pending.json");
82734
+ return join21(dirname19(context.environment.configPath), "join", "pending.json");
82277
82735
  }
82278
82736
  async function readPending({
82279
82737
  context,
@@ -82290,7 +82748,7 @@ async function readPending({
82290
82748
  }
82291
82749
  async function keepPending({ context, pending }) {
82292
82750
  const path = pendingPathOf({ context });
82293
- await mkdir18(dirname18(path), { recursive: true, mode: 448 });
82751
+ await mkdir19(dirname19(path), { recursive: true, mode: 448 });
82294
82752
  const temporary = `${path}.${process.pid}.tmp`;
82295
82753
  await writeFile19(temporary, JSON.stringify(pending), { mode: 384 });
82296
82754
  await rename5(temporary, path);
@@ -83110,8 +83568,8 @@ async function serveMcp({
83110
83568
  }
83111
83569
 
83112
83570
  // 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";
83571
+ import { mkdir as mkdir20, readFile as readFile30, rm as rm12, writeFile as writeFile20 } from "node:fs/promises";
83572
+ import { dirname as dirname20, relative as relative5, resolve as resolve11 } from "node:path";
83115
83573
  async function textArgument({
83116
83574
  context,
83117
83575
  value
@@ -83131,13 +83589,13 @@ async function writeMount({
83131
83589
  }) {
83132
83590
  const root = resolve11(context.cwd, flagText({ args, name: "dir", fallback: ".laze" }), folder);
83133
83591
  await rm12(root, { recursive: true, force: true });
83134
- await mkdir19(root, { recursive: true });
83592
+ await mkdir20(root, { recursive: true });
83135
83593
  for (const file3 of files2) {
83136
83594
  const target = resolve11(root, file3.path);
83137
83595
  const inside = relative5(root, target);
83138
83596
  if (!inside || inside.startsWith(".."))
83139
83597
  throw new Error(`Refusing to write outside ${root}: ${file3.path}`);
83140
- await mkdir19(dirname19(target), { recursive: true });
83598
+ await mkdir20(dirname20(target), { recursive: true });
83141
83599
  await writeFile20(target, file3.content);
83142
83600
  }
83143
83601
  return root;
@@ -83779,11 +84237,12 @@ ${OPS_USAGE}`);
83779
84237
  }
83780
84238
 
83781
84239
  // 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";
84240
+ import { mkdir as mkdir21, readFile as readFile31, realpath, writeFile as writeFile21 } from "node:fs/promises";
84241
+ import { dirname as dirname21, join as join22 } from "node:path";
83784
84242
 
83785
84243
  // src/rules/cli-update.rules.ts
83786
- var CLI_PACKAGE_LATEST = "@lazehq/cli@latest";
84244
+ var CLI_PACKAGE = "@lazehq/cli";
84245
+ var CLI_PACKAGE_LATEST = `${CLI_PACKAGE}@latest`;
83787
84246
  var MANAGERS = [
83788
84247
  { manager: "bun", pattern: /[\\/]\.?bun[\\/]/, command: ["bun", "add", "-g"] },
83789
84248
  { manager: "pnpm", pattern: /[\\/]\.?pnpm[\\/]/, command: ["pnpm", "add", "-g"] },
@@ -83796,7 +84255,17 @@ var MANAGERS = [
83796
84255
  ];
83797
84256
  var NPM_PREFIX = /^(.+)[\\/]lib[\\/]node_modules[\\/]@lazehq[\\/]cli[\\/]/;
83798
84257
  var NPX_CACHE2 = /[\\/]_npx[\\/]/;
83799
- function updatePlanOf({ script }) {
84258
+ function releaseAgeOverrideOf({
84259
+ manager,
84260
+ nowMs
84261
+ }) {
84262
+ if (manager === "npm")
84263
+ return [`--before=${Temporal3.Instant.fromEpochMilliseconds(nowMs).toString()}`];
84264
+ if (manager === "pnpm") return [`--config.minimum-release-age-exclude=${CLI_PACKAGE}`];
84265
+ if (manager === "bun") return ["--minimum-release-age=0"];
84266
+ return [];
84267
+ }
84268
+ function updatePlanOf({ script, nowMs }) {
83800
84269
  if (script === SANDBOX_CLI_PATH) return { kind: "sandbox" };
83801
84270
  const found = MANAGERS.find(({ pattern }) => pattern.test(script));
83802
84271
  if (!found) return { kind: "unmanaged", script };
@@ -83804,17 +84273,59 @@ function updatePlanOf({ script }) {
83804
84273
  return {
83805
84274
  kind: "install",
83806
84275
  manager: found.manager,
83807
- command: [...found.command, ...prefix ? ["--prefix", prefix] : [], CLI_PACKAGE_LATEST]
84276
+ command: [
84277
+ ...found.command,
84278
+ ...prefix ? ["--prefix", prefix] : [],
84279
+ ...releaseAgeOverrideOf({ manager: found.manager, nowMs }),
84280
+ CLI_PACKAGE_LATEST
84281
+ ]
83808
84282
  };
83809
84283
  }
83810
- var RELEASE_AGE_REFUSAL = /\b(ENOVERSIONS|ETARGET)\b/;
83811
- function releaseAgeRetryOf({
84284
+ function pinnedCommandOf({
83812
84285
  plan: plan2,
83813
- stderr: stderr2
84286
+ version: version2
83814
84287
  }) {
83815
- if (plan2.manager !== "npm" || !RELEASE_AGE_REFUSAL.test(stderr2)) return null;
83816
- const at = plan2.command.indexOf(CLI_PACKAGE_LATEST);
83817
- return [...plan2.command.slice(0, at), "--min-release-age=0", ...plan2.command.slice(at)];
84288
+ return plan2.command.map(
84289
+ (part) => part === CLI_PACKAGE_LATEST ? `${CLI_PACKAGE}@${version2}` : part
84290
+ );
84291
+ }
84292
+ var RELEASE_AGE_SETTINGS = {
84293
+ npm: [
84294
+ { setting: "min-release-age", read: ["npm", "config", "get", "min-release-age"] },
84295
+ { setting: "before", read: ["npm", "config", "get", "before"] }
84296
+ ],
84297
+ pnpm: [
84298
+ { setting: "minimum-release-age", read: ["pnpm", "config", "get", "minimum-release-age"] }
84299
+ ]
84300
+ };
84301
+ function settingValueOf({ printed }) {
84302
+ const value = printed.trim();
84303
+ return value === "" || value === "null" || value === "undefined" || value === "0" ? null : value;
84304
+ }
84305
+ var VERSION_LINE = /^laze (\S+)\s*$/m;
84306
+ function printedVersionOf({ printed }) {
84307
+ return VERSION_LINE.exec(printed)?.[1] ?? null;
84308
+ }
84309
+ function heldBackLineOf({
84310
+ manager,
84311
+ installed,
84312
+ latest,
84313
+ settings: settings2,
84314
+ command,
84315
+ script
84316
+ }) {
84317
+ const head = latest ? `laze is ${installed} after the install, but the latest release is ${latest}.` : `laze is still ${installed} after the install, and the npm registry did not say which release is the latest.`;
84318
+ const line = command.join(" ");
84319
+ if (settings2.length > 0) {
84320
+ return `${head} ${manager}'s ${settings2.join(" and ")} setting holds back releases younger than it allows, so ${manager} kept or picked an older one. Install the latest with: ${line}
84321
+ `;
84322
+ }
84323
+ if (manager === "bun") {
84324
+ return `${head} A minimumReleaseAge in bunfig.toml may hold it back, or another laze comes first on PATH (this one is ${script}). Install the latest with: ${line}
84325
+ `;
84326
+ }
84327
+ return `${head} No release-age setting is set, so another laze may come first on PATH (this one is ${script}). Install the latest with: ${line}
84328
+ `;
83818
84329
  }
83819
84330
 
83820
84331
  // src/rules/cli-release.rules.ts
@@ -83879,18 +84390,18 @@ async function startedUpdate({
83879
84390
  server
83880
84391
  }) {
83881
84392
  if (context.environment.inherited.LAZE_AUTO_UPDATE === "0") return null;
83882
- const plan2 = updatePlanOf({ script: await scriptOf(context) });
84393
+ const plan2 = updatePlanOf({ script: await scriptOf(context), nowMs: context.nowMs() });
83883
84394
  if (plan2.kind !== "install") return null;
83884
- const folder = dirname20(context.environment.configPath);
83885
- const stamp = join21(folder, "auto-update.json");
84395
+ const folder = dirname21(context.environment.configPath);
84396
+ const stamp = join22(folder, "auto-update.json");
83886
84397
  const last = await readFile31(stamp, "utf8").then((text2) => JSON.parse(text2)).catch(() => null);
83887
84398
  const now = context.nowMs();
83888
84399
  if (last?.server === server && now - last.atMs < RETRY_AFTER_MS) return null;
83889
- await mkdir20(folder, { recursive: true, mode: 448 });
84400
+ await mkdir21(folder, { recursive: true, mode: 448 });
83890
84401
  await writeFile21(stamp, JSON.stringify({ server, atMs: now }), { mode: 384 });
83891
84402
  context.processes.spawnDetached({
83892
84403
  argv: [...context.program, "update"],
83893
- logPath: join21(folder, "auto-update.log")
84404
+ logPath: join22(folder, "auto-update.log")
83894
84405
  });
83895
84406
  return { manager: plan2.manager };
83896
84407
  }
@@ -84127,7 +84638,7 @@ async function schedule({ context, args }) {
84127
84638
 
84128
84639
  // src/services/skill-commands.service.ts
84129
84640
  import { readdir as readdir7, readFile as readFile33 } from "node:fs/promises";
84130
- import { join as join22, relative as relative6, resolve as resolve12 } from "node:path";
84641
+ import { join as join23, relative as relative6, resolve as resolve12 } from "node:path";
84131
84642
  var USAGE16 = `Usage:
84132
84643
  laze skill list [--agent <agentId>]
84133
84644
  laze skill install <catalogue-id> [--as <name>] [--agent <agentId>]
@@ -84148,7 +84659,7 @@ async function folderFiles({ root }) {
84148
84659
  const files2 = [];
84149
84660
  for (const entry of entries) {
84150
84661
  if (!entry.isFile()) continue;
84151
- const full = join22(entry.parentPath, entry.name);
84662
+ const full = join23(entry.parentPath, entry.name);
84152
84663
  files2.push({ path: relative6(root, full), content: await readFile33(full, "utf8") });
84153
84664
  }
84154
84665
  return files2.toSorted((a, b) => a.path.localeCompare(b.path));
@@ -84947,6 +85458,8 @@ async function statusUsage() {
84947
85458
  // src/services/update-commands.service.ts
84948
85459
  import { realpath as realpath2 } from "node:fs/promises";
84949
85460
  var BY_HAND = `npm install -g ${CLI_PACKAGE_LATEST}`;
85461
+ var REGISTRY_LATEST_URL = `https://registry.npmjs.org/${CLI_PACKAGE}/latest`;
85462
+ var REGISTRY_TIMEOUT_MS = 1e4;
84950
85463
  async function realScriptOf({ program }) {
84951
85464
  const script = program.at(-1) ?? "";
84952
85465
  try {
@@ -84955,11 +85468,55 @@ async function realScriptOf({ program }) {
84955
85468
  return script;
84956
85469
  }
84957
85470
  }
85471
+ async function latestReleaseOf({ context }) {
85472
+ try {
85473
+ const response = await context.fetcher(REGISTRY_LATEST_URL, {
85474
+ signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS)
85475
+ });
85476
+ if (!response.ok) return null;
85477
+ const body = await response.json();
85478
+ return typeof body.version === "string" ? body.version : null;
85479
+ } catch {
85480
+ return null;
85481
+ }
85482
+ }
85483
+ async function printedBy({
85484
+ context,
85485
+ command
85486
+ }) {
85487
+ let printed = "";
85488
+ const sink = {
85489
+ write: (chunk) => {
85490
+ printed += chunk;
85491
+ }
85492
+ };
85493
+ try {
85494
+ const code = await context.runCommand({ command, env: {}, stdout: sink, stderr: sink });
85495
+ return code === 0 ? printed : null;
85496
+ } catch {
85497
+ return null;
85498
+ }
85499
+ }
85500
+ async function releaseAgeSettingsOf({
85501
+ context,
85502
+ manager
85503
+ }) {
85504
+ const settings2 = [];
85505
+ for (const { setting, read: read3 } of RELEASE_AGE_SETTINGS[manager] ?? []) {
85506
+ const value = settingValueOf({ printed: await printedBy({ context, command: read3 }) ?? "" });
85507
+ if (value) settings2.push(`${setting}=${value}`);
85508
+ }
85509
+ return settings2;
85510
+ }
84958
85511
  async function update2({
84959
85512
  context,
84960
- args
85513
+ args,
85514
+ mine: mine4 = cliVersionOf()
84961
85515
  }) {
84962
- const plan2 = updatePlanOf({ script: await realScriptOf({ program: context.program }) });
85516
+ const plan2 = updatePlanOf({
85517
+ script: await realScriptOf({ program: context.program }),
85518
+ nowMs: context.nowMs()
85519
+ });
84963
85520
  if (plan2.kind === "sandbox") {
84964
85521
  context.out("This laze comes with your computer and updates with every Laze release.\n");
84965
85522
  return 0;
@@ -84973,40 +85530,51 @@ async function update2({
84973
85530
  }
84974
85531
  const line = plan2.command.join(" ");
84975
85532
  if (args.flags["dry-run"]) {
84976
- context.out(`laze ${cliVersionOf()}, installed with ${plan2.manager}. Would run: ${line}
85533
+ context.out(`laze ${mine4}, installed with ${plan2.manager}. Would run: ${line}
84977
85534
  `);
84978
85535
  return 0;
84979
85536
  }
84980
- context.out(`Updating laze ${cliVersionOf()} with ${plan2.manager}: ${line}
85537
+ const latest = await latestReleaseOf({ context });
85538
+ if (latest && latest === mine4) {
85539
+ context.out(`laze ${mine4} is the latest release.
84981
85540
  `);
84982
- let stderr2 = "";
84983
- const tee = {
84984
- write: (chunk) => {
84985
- stderr2 += chunk;
84986
- context.err(chunk);
84987
- }
84988
- };
84989
- let code = await context.runCommand({ command: plan2.command, env: {}, stderr: tee });
84990
- const retry = code === 0 ? null : releaseAgeRetryOf({ plan: plan2, stderr: stderr2 });
84991
- if (retry) {
84992
- const retryLine = retry.join(" ");
84993
- context.out(
84994
- `npm's min-release-age setting held back the latest release. Trying once more with the guard off for @lazehq/cli only: ${retryLine}
84995
- `
84996
- );
84997
- code = await context.runCommand({ command: retry, env: {} });
84998
- if (code !== 0) {
84999
- context.err(`npm exited ${code}. Update by hand with: ${retryLine}
85541
+ return 0;
85542
+ }
85543
+ context.out(`Updating laze ${mine4} with ${plan2.manager}: ${line}
85000
85544
  `);
85001
- return code;
85002
- }
85003
- } else if (code !== 0) {
85545
+ const code = await context.runCommand({ command: plan2.command, env: {} });
85546
+ if (code !== 0) {
85004
85547
  context.err(`${plan2.manager} exited ${code}. Update by hand with: ${line}
85005
85548
  `);
85006
85549
  return code;
85007
85550
  }
85008
- context.out("Updated. `laze --version` names the new version.\n");
85009
- return 0;
85551
+ const printed = await printedBy({ context, command: [...context.program, "--version"] });
85552
+ const installed = printed === null ? null : printedVersionOf({ printed });
85553
+ if (!installed) {
85554
+ context.out("Installed. `laze --version` names the new version.\n");
85555
+ return 0;
85556
+ }
85557
+ const held = latest ? releaseSkewOf({ mine: installed, server: latest }) === "older" : installed === mine4;
85558
+ if (!held) {
85559
+ context.out(
85560
+ installed === mine4 ? `laze ${mine4} is the latest release.
85561
+ ` : `Updated laze ${mine4} to ${installed}.
85562
+ `
85563
+ );
85564
+ return 0;
85565
+ }
85566
+ const settings2 = await releaseAgeSettingsOf({ context, manager: plan2.manager });
85567
+ context.err(
85568
+ heldBackLineOf({
85569
+ manager: plan2.manager,
85570
+ installed,
85571
+ latest,
85572
+ settings: settings2,
85573
+ command: latest ? pinnedCommandOf({ plan: plan2, version: latest }) : plan2.command,
85574
+ script: context.program.at(-1) ?? ""
85575
+ })
85576
+ );
85577
+ return 1;
85010
85578
  }
85011
85579
 
85012
85580
  // src/services/vault-save-message-commands.service.ts
@@ -86612,7 +87180,7 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
86612
87180
  laze star add|remove|list [channel] starred conversations in your sidebar (people)
86613
87181
  laze feed post <title> [--channel <c>] ... put an item in people's feed as your agent
86614
87182
  laze feed update|reply|read <id>, laze feed inbox change, answer and read your items
86615
- laze feed list|count your own feed as a person: cards and their actions
87183
+ laze feed list|count|decisions your own feed as a person: cards and their actions
86616
87184
  laze feed act <id> <actionId>, comment <id> <text> answer a card in your feed
86617
87185
  laze feed done|put-back|unsnooze <id>, snooze <id> --until <time> move a card
86618
87186
  laze feed channel <channelId> the feed cards a channel shows
@@ -86959,7 +87527,7 @@ async function runCli({
86959
87527
  import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
86960
87528
  import { mkdirSync, openSync } from "node:fs";
86961
87529
  import { readFile as readFile38, readlink } from "node:fs/promises";
86962
- import { dirname as dirname21 } from "node:path";
87530
+ import { dirname as dirname22 } from "node:path";
86963
87531
  import { promisify as promisify2 } from "node:util";
86964
87532
  var run3 = promisify2(execFile2);
86965
87533
  function alive(pid) {
@@ -86996,7 +87564,7 @@ async function cwdOf(pid) {
86996
87564
  return line ? line.slice(1) : void 0;
86997
87565
  }
86998
87566
  function spawnDetached({ argv, logPath }) {
86999
- mkdirSync(dirname21(logPath), { recursive: true, mode: 448 });
87567
+ mkdirSync(dirname22(logPath), { recursive: true, mode: 448 });
87000
87568
  const log = openSync(logPath, "a", 384);
87001
87569
  const [program = "", ...rest] = argv;
87002
87570
  const child = spawn4(program, rest, { detached: true, stdio: ["ignore", log, log] });