@lazehq/cli 0.1.43 → 0.1.44

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 +640 -106
  2. package/package.json +1 -1
package/dist/laze.mjs CHANGED
@@ -96,9 +96,9 @@ var require_node_gyp_build = __commonJS({
96
96
  var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
97
97
  if (debug) return debug;
98
98
  }
99
- var prebuild = resolve18(dir);
99
+ var prebuild = resolve19(dir);
100
100
  if (prebuild) return prebuild;
101
- var nearby = resolve18(path.dirname(process.execPath));
101
+ var nearby = resolve19(path.dirname(process.execPath));
102
102
  if (nearby) return nearby;
103
103
  var target = [
104
104
  "platform=" + platform,
@@ -114,7 +114,7 @@ var require_node_gyp_build = __commonJS({
114
114
  // eslint-disable-line
115
115
  ].filter(Boolean).join(" ");
116
116
  throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
117
- function resolve18(dir2) {
117
+ function resolve19(dir2) {
118
118
  var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
119
119
  var tuple2 = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
120
120
  if (!tuple2) return;
@@ -6561,9 +6561,9 @@ var require_dispatcher_base = __commonJS({
6561
6561
  }
6562
6562
  close(callback) {
6563
6563
  if (callback === void 0) {
6564
- return new Promise((resolve18, reject) => {
6564
+ return new Promise((resolve19, reject) => {
6565
6565
  this.close((err, data) => {
6566
- return err ? reject(err) : resolve18(data);
6566
+ return err ? reject(err) : resolve19(data);
6567
6567
  });
6568
6568
  });
6569
6569
  }
@@ -6601,9 +6601,9 @@ var require_dispatcher_base = __commonJS({
6601
6601
  err = null;
6602
6602
  }
6603
6603
  if (callback === void 0) {
6604
- return new Promise((resolve18, reject) => {
6604
+ return new Promise((resolve19, reject) => {
6605
6605
  this.destroy(err, (err2, data) => {
6606
- return err2 ? reject(err2) : resolve18(data);
6606
+ return err2 ? reject(err2) : resolve19(data);
6607
6607
  });
6608
6608
  });
6609
6609
  }
@@ -11558,12 +11558,12 @@ upgrade: ${upgrade2}\r
11558
11558
  cb();
11559
11559
  }
11560
11560
  }
11561
- const waitForDrain = () => new Promise((resolve18, reject) => {
11561
+ const waitForDrain = () => new Promise((resolve19, reject) => {
11562
11562
  assert2(callback === null);
11563
11563
  if (socket[kError]) {
11564
11564
  reject(socket[kError]);
11565
11565
  } else {
11566
- callback = resolve18;
11566
+ callback = resolve19;
11567
11567
  }
11568
11568
  });
11569
11569
  socket.on("close", onDrain).on("drain", onDrain);
@@ -12921,12 +12921,12 @@ var require_client_h2 = __commonJS({
12921
12921
  cb();
12922
12922
  }
12923
12923
  }
12924
- const waitForDrain = () => new Promise((resolve18, reject) => {
12924
+ const waitForDrain = () => new Promise((resolve19, reject) => {
12925
12925
  assert2(callback === null);
12926
12926
  if (socket[kError]) {
12927
12927
  reject(socket[kError]);
12928
12928
  } else {
12929
- callback = resolve18;
12929
+ callback = resolve19;
12930
12930
  }
12931
12931
  });
12932
12932
  h2stream.on("close", onDrain).on("drain", onDrain);
@@ -13294,16 +13294,16 @@ var require_client = __commonJS({
13294
13294
  return this[kNeedDrain] < 2;
13295
13295
  }
13296
13296
  [kClose]() {
13297
- return new Promise((resolve18) => {
13297
+ return new Promise((resolve19) => {
13298
13298
  if (this[kSize]) {
13299
- this[kClosedResolve] = resolve18;
13299
+ this[kClosedResolve] = resolve19;
13300
13300
  } else {
13301
- resolve18(null);
13301
+ resolve19(null);
13302
13302
  }
13303
13303
  });
13304
13304
  }
13305
13305
  [kDestroy](err) {
13306
- return new Promise((resolve18) => {
13306
+ return new Promise((resolve19) => {
13307
13307
  const requests2 = this[kQueue].splice(this[kPendingIdx]);
13308
13308
  for (let i = 0; i < requests2.length; i++) {
13309
13309
  const request2 = requests2[i];
@@ -13316,7 +13316,7 @@ var require_client = __commonJS({
13316
13316
  this[kClosedResolve]();
13317
13317
  this[kClosedResolve] = null;
13318
13318
  }
13319
- resolve18(null);
13319
+ resolve19(null);
13320
13320
  };
13321
13321
  if (this[kHTTPContext]) {
13322
13322
  this[kHTTPContext].destroy(err, callback);
@@ -13729,8 +13729,8 @@ var require_pool_base = __commonJS({
13729
13729
  }
13730
13730
  return Promise.all(closeAll);
13731
13731
  } else {
13732
- return new Promise((resolve18) => {
13733
- this[kClosedResolve] = resolve18;
13732
+ return new Promise((resolve19) => {
13733
+ this[kClosedResolve] = resolve19;
13734
13734
  });
13735
13735
  }
13736
13736
  }
@@ -16241,7 +16241,7 @@ var require_readable = __commonJS({
16241
16241
  if (this._readableState.closeEmitted) {
16242
16242
  return Promise.resolve(null);
16243
16243
  }
16244
- return new Promise((resolve18, reject) => {
16244
+ return new Promise((resolve19, reject) => {
16245
16245
  if (this[kContentLength] && this[kContentLength] > limit || this[kBytesRead] > limit) {
16246
16246
  this.destroy(new AbortError());
16247
16247
  }
@@ -16255,11 +16255,11 @@ var require_readable = __commonJS({
16255
16255
  if (signal.aborted) {
16256
16256
  reject(signal.reason ?? new AbortError());
16257
16257
  } else {
16258
- resolve18(null);
16258
+ resolve19(null);
16259
16259
  }
16260
16260
  });
16261
16261
  } else {
16262
- this.on("close", resolve18);
16262
+ this.on("close", resolve19);
16263
16263
  }
16264
16264
  this.on("error", noop2).on("data", () => {
16265
16265
  if (this[kBytesRead] > limit) {
@@ -16287,7 +16287,7 @@ var require_readable = __commonJS({
16287
16287
  }
16288
16288
  function consume(stream, type) {
16289
16289
  assert2(!stream[kConsume]);
16290
- return new Promise((resolve18, reject) => {
16290
+ return new Promise((resolve19, reject) => {
16291
16291
  if (isUnusable(stream)) {
16292
16292
  const rState = stream._readableState;
16293
16293
  if (rState.destroyed && rState.closeEmitted === false) {
@@ -16302,7 +16302,7 @@ var require_readable = __commonJS({
16302
16302
  stream[kConsume] = {
16303
16303
  type,
16304
16304
  stream,
16305
- resolve: resolve18,
16305
+ resolve: resolve19,
16306
16306
  reject,
16307
16307
  length: 0,
16308
16308
  body: []
@@ -16380,18 +16380,18 @@ var require_readable = __commonJS({
16380
16380
  return buffer;
16381
16381
  }
16382
16382
  function consumeEnd(consume2, encoding) {
16383
- const { type, body, resolve: resolve18, stream, length } = consume2;
16383
+ const { type, body, resolve: resolve19, stream, length } = consume2;
16384
16384
  try {
16385
16385
  if (type === "text") {
16386
- resolve18(chunksDecode(body, length, encoding));
16386
+ resolve19(chunksDecode(body, length, encoding));
16387
16387
  } else if (type === "json") {
16388
- resolve18(JSON.parse(chunksDecode(body, length, encoding)));
16388
+ resolve19(JSON.parse(chunksDecode(body, length, encoding)));
16389
16389
  } else if (type === "arrayBuffer") {
16390
- resolve18(chunksConcat(body, length).buffer);
16390
+ resolve19(chunksConcat(body, length).buffer);
16391
16391
  } else if (type === "blob") {
16392
- resolve18(new Blob(body, { type: stream[kContentType] }));
16392
+ resolve19(new Blob(body, { type: stream[kContentType] }));
16393
16393
  } else if (type === "bytes") {
16394
- resolve18(chunksConcat(body, length));
16394
+ resolve19(chunksConcat(body, length));
16395
16395
  }
16396
16396
  consumeFinish(consume2);
16397
16397
  } catch (err) {
@@ -16610,9 +16610,9 @@ var require_api_request = __commonJS({
16610
16610
  };
16611
16611
  function request2(opts, callback) {
16612
16612
  if (callback === void 0) {
16613
- return new Promise((resolve18, reject) => {
16613
+ return new Promise((resolve19, reject) => {
16614
16614
  request2.call(this, opts, (err, data) => {
16615
- return err ? reject(err) : resolve18(data);
16615
+ return err ? reject(err) : resolve19(data);
16616
16616
  });
16617
16617
  });
16618
16618
  }
@@ -16873,9 +16873,9 @@ var require_api_stream = __commonJS({
16873
16873
  };
16874
16874
  function stream(opts, factory, callback) {
16875
16875
  if (callback === void 0) {
16876
- return new Promise((resolve18, reject) => {
16876
+ return new Promise((resolve19, reject) => {
16877
16877
  stream.call(this, opts, factory, (err, data) => {
16878
- return err ? reject(err) : resolve18(data);
16878
+ return err ? reject(err) : resolve19(data);
16879
16879
  });
16880
16880
  });
16881
16881
  }
@@ -17175,9 +17175,9 @@ var require_api_upgrade = __commonJS({
17175
17175
  };
17176
17176
  function upgrade2(opts, callback) {
17177
17177
  if (callback === void 0) {
17178
- return new Promise((resolve18, reject) => {
17178
+ return new Promise((resolve19, reject) => {
17179
17179
  upgrade2.call(this, opts, (err, data) => {
17180
- return err ? reject(err) : resolve18(data);
17180
+ return err ? reject(err) : resolve19(data);
17181
17181
  });
17182
17182
  });
17183
17183
  }
@@ -17271,9 +17271,9 @@ var require_api_connect = __commonJS({
17271
17271
  };
17272
17272
  function connect6(opts, callback) {
17273
17273
  if (callback === void 0) {
17274
- return new Promise((resolve18, reject) => {
17274
+ return new Promise((resolve19, reject) => {
17275
17275
  connect6.call(this, opts, (err, data) => {
17276
- return err ? reject(err) : resolve18(data);
17276
+ return err ? reject(err) : resolve19(data);
17277
17277
  });
17278
17278
  });
17279
17279
  }
@@ -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: mkdir22 } = __require("node:fs/promises");
18737
- var { dirname: dirname23, resolve: resolve18 } = __require("node:path");
18736
+ var { writeFile: writeFile23, readFile: readFile40, mkdir: mkdir22 } = __require("node:fs/promises");
18737
+ var { dirname: dirname24, resolve: resolve19 } = __require("node:path");
18738
18738
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
18739
18739
  var { InvalidArgumentError, UndiciError } = require_errors();
18740
18740
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -18950,7 +18950,7 @@ var require_snapshot_recorder = __commonJS({
18950
18950
  throw new InvalidArgumentError("Snapshot path is required");
18951
18951
  }
18952
18952
  try {
18953
- const data = await readFile39(resolve18(path), "utf8");
18953
+ const data = await readFile40(resolve19(path), "utf8");
18954
18954
  const parsed = JSON.parse(data);
18955
18955
  if (Array.isArray(parsed)) {
18956
18956
  this.#snapshots.clear();
@@ -18979,8 +18979,8 @@ var require_snapshot_recorder = __commonJS({
18979
18979
  if (!path) {
18980
18980
  throw new InvalidArgumentError("Snapshot path is required");
18981
18981
  }
18982
- const resolvedPath = resolve18(path);
18983
- await mkdir22(dirname23(resolvedPath), { recursive: true });
18982
+ const resolvedPath = resolve19(path);
18983
+ await mkdir22(dirname24(resolvedPath), { recursive: true });
18984
18984
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
18985
18985
  hash: hash2,
18986
18986
  snapshot
@@ -26477,7 +26477,7 @@ var require_fetch = __commonJS({
26477
26477
  const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
26478
26478
  return dispatchWithProtocolPreference(body);
26479
26479
  function dispatchWithProtocolPreference(body2, allowH2) {
26480
- return new Promise((resolve18, reject) => agent2.dispatch(
26480
+ return new Promise((resolve19, reject) => agent2.dispatch(
26481
26481
  {
26482
26482
  path: hasTrailingQuestionMark ? `${path}?` : path,
26483
26483
  origin: url2.origin,
@@ -26560,7 +26560,7 @@ var require_fetch = __commonJS({
26560
26560
  }
26561
26561
  }
26562
26562
  const onError = (err) => this.onResponseError(controller, err);
26563
- resolve18({
26563
+ resolve19({
26564
26564
  status: status9,
26565
26565
  statusText,
26566
26566
  headersList,
@@ -26593,7 +26593,7 @@ var require_fetch = __commonJS({
26593
26593
  fetchParams.controller.off("terminated", this.abort);
26594
26594
  }
26595
26595
  if (request2.mode === "websocket" && allowH2 !== false && error62?.code === "UND_ERR_INFO" && error62?.message === "HTTP/2: Extended CONNECT protocol not supported by server") {
26596
- resolve18(dispatchWithProtocolPreference(body2, false));
26596
+ resolve19(dispatchWithProtocolPreference(body2, false));
26597
26597
  return;
26598
26598
  }
26599
26599
  this.body?.destroy(error62);
@@ -26607,7 +26607,7 @@ var require_fetch = __commonJS({
26607
26607
  const rawHeaders = controller?.rawHeaders ?? [];
26608
26608
  const headersList = new HeadersList();
26609
26609
  appendHeadersListFromResponseHeaders(headersList, headers, rawHeaders);
26610
- resolve18({
26610
+ resolve19({
26611
26611
  status: status9,
26612
26612
  statusText: STATUS_CODES[status9],
26613
26613
  headersList,
@@ -31581,7 +31581,7 @@ function runRedacted({
31581
31581
  signal
31582
31582
  }) {
31583
31583
  const values = Object.values(env);
31584
- return new Promise((resolve18, reject) => {
31584
+ return new Promise((resolve19, reject) => {
31585
31585
  const [file3, ...args] = command;
31586
31586
  const child = spawn(file3, args, {
31587
31587
  env: { ...baseEnv, ...env },
@@ -31607,7 +31607,7 @@ function runRedacted({
31607
31607
  child.on("error", reject);
31608
31608
  child.on("close", (code, ended) => {
31609
31609
  signal?.removeEventListener("abort", killGroup);
31610
- void drained.then(() => resolve18(code ?? (ended ? 128 + signalNumber(ended) : 1)));
31610
+ void drained.then(() => resolve19(code ?? (ended ? 128 + signalNumber(ended) : 1)));
31611
31611
  });
31612
31612
  });
31613
31613
  }
@@ -35671,7 +35671,9 @@ var SWITCHES = /* @__PURE__ */ new Set([
35671
35671
  "wait-reply",
35672
35672
  "no-publish",
35673
35673
  "local",
35674
- "done"
35674
+ "done",
35675
+ "names",
35676
+ "shell"
35675
35677
  ]);
35676
35678
  function parseArgs({ argv }) {
35677
35679
  const words = [];
@@ -35709,7 +35711,7 @@ function flagText({
35709
35711
  }
35710
35712
 
35711
35713
  // src/rules/cli-version.rules.ts
35712
- var STAMPED = "0.1.43";
35714
+ var STAMPED = "0.1.44";
35713
35715
  function cliVersionOf({ stamped = STAMPED } = {}) {
35714
35716
  return stamped.startsWith("__") ? "dev" : stamped;
35715
35717
  }
@@ -40748,7 +40750,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
40748
40750
  var NONE = 0;
40749
40751
  var ASSUMED = 1;
40750
40752
  var PROVEN = 2;
40751
- function isRecursive(inst, stack, resolve18) {
40753
+ function isRecursive(inst, stack, resolve19) {
40752
40754
  const cached2 = recursive.get(inst);
40753
40755
  if (cached2 !== void 0)
40754
40756
  return cached2 ? PROVEN : NONE;
@@ -40758,7 +40760,7 @@ function isRecursive(inst, stack, resolve18) {
40758
40760
  let result = NONE;
40759
40761
  const check3 = (child) => {
40760
40762
  if (result !== PROVEN && child?._zod) {
40761
- const answer4 = isRecursive(child, stack, resolve18);
40763
+ const answer4 = isRecursive(child, stack, resolve19);
40762
40764
  if (answer4 > result)
40763
40765
  result = answer4;
40764
40766
  }
@@ -40769,7 +40771,7 @@ function isRecursive(inst, stack, resolve18) {
40769
40771
  const desc = Object.getOwnPropertyDescriptor(sh, key);
40770
40772
  if (spread && !desc.enumerable)
40771
40773
  continue;
40772
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve18) : NONE;
40774
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve19) : NONE;
40773
40775
  if (child > answer4)
40774
40776
  answer4 = child;
40775
40777
  }
@@ -40833,7 +40835,7 @@ function isRecursive(inst, stack, resolve18) {
40833
40835
  break;
40834
40836
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
40835
40837
  case "lazy": {
40836
- const inner = def._cachedInner ?? (resolve18 ? inst._zod.innerType : void 0);
40838
+ const inner = def._cachedInner ?? (resolve19 ? inst._zod.innerType : void 0);
40837
40839
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
40838
40840
  break;
40839
40841
  }
@@ -59661,6 +59663,7 @@ var noticeKindSchema = external_exports.enum([
59661
59663
  "channel",
59662
59664
  "reaction"
59663
59665
  ]);
59666
+ var quietKindSchema = external_exports.enum([...noticeKindSchema.options, "broadcast"]);
59664
59667
  var noticeSenderSchemaDefinition = external_exports.object({
59665
59668
  kind: external_exports.enum(["person", "agent"]),
59666
59669
  id: external_exports.string().min(1).max(64),
@@ -59687,7 +59690,9 @@ var messageNoticeSchema = external_exports.object({
59687
59690
  /** The sender picked "Notify anyway": it breaks through Do Not Disturb, once. */
59688
59691
  urgent: external_exports.boolean().optional(),
59689
59692
  /** It came in through a mirror such as Slack, whose own app already rings: Laze stays silent. */
59690
- mirrored: external_exports.boolean().optional()
59693
+ mirrored: external_exports.boolean().optional(),
59694
+ /** An @channel or @here raised it, not the conversation's every-message level. */
59695
+ broadcast: external_exports.boolean().optional()
59691
59696
  });
59692
59697
  var approvalNoticeSchema = external_exports.object({
59693
59698
  workspaceId: workspaceIdSchema2,
@@ -60111,6 +60116,8 @@ var heldPhonePushShape = {
60111
60116
  channelId: external_exports.string().min(1).optional(),
60112
60117
  messageId: external_exports.string().min(1).optional(),
60113
60118
  kind: noticeKindSchema.optional(),
60119
+ /** A `channel` notice an @channel or @here raised. */
60120
+ broadcast: external_exports.boolean().optional(),
60114
60121
  silent: external_exports.boolean().optional(),
60115
60122
  feed: heldFeedPushSchema.optional(),
60116
60123
  burst: heldBurstPushSchema.optional()
@@ -60143,8 +60150,8 @@ var conversationQuietedPayloadSchemaDefinition = external_exports.object({
60143
60150
  userId: external_exports.string().min(1),
60144
60151
  channelId: external_exports.string().min(1),
60145
60152
  changeId: external_exports.string().min(1),
60146
- levelQuiets: external_exports.array(noticeKindSchema),
60147
- muteQuiets: external_exports.array(noticeKindSchema),
60153
+ levelQuiets: external_exports.array(quietKindSchema),
60154
+ muteQuiets: external_exports.array(quietKindSchema),
60148
60155
  mutedUntil: external_exports.iso.datetime().nullable(),
60149
60156
  at: external_exports.iso.datetime()
60150
60157
  });
@@ -60196,8 +60203,8 @@ var memberNotifySetPayloadSchemaDefinition = external_exports.object({
60196
60203
  channelId: external_exports.string().min(1),
60197
60204
  userId: external_exports.string().min(1),
60198
60205
  changeId: external_exports.string().min(1),
60199
- levelQuiets: external_exports.array(noticeKindSchema),
60200
- muteQuiets: external_exports.array(noticeKindSchema),
60206
+ levelQuiets: external_exports.array(quietKindSchema),
60207
+ muteQuiets: external_exports.array(quietKindSchema),
60201
60208
  mutedUntil: external_exports.iso.datetime().nullable(),
60202
60209
  at: external_exports.iso.datetime()
60203
60210
  });
@@ -60707,6 +60714,8 @@ function connectionNameForField(field) {
60707
60714
  var VaultSecretOfferSlot = uiTokens("vault").component("secretOffer");
60708
60715
 
60709
60716
  // ../../modules/vault/contract/src/vault-reason.ts
60717
+ var VAULT_EXIT_BAD_REASON = 2;
60718
+ var VAULT_REASON_GUIDANCE = 'Write --reason as one short plain sentence a person understands on a phone: what you want to do and why. Good: --reason "Read the query plan to find why the events dashboard is slow".';
60710
60719
  var COMMAND_STARTS = new Set(
60711
60720
  "sudo laze kv aws curl wget npm pnpm yarn npx git gh kubectl helm docker terraform python python3 node bash sh zsh export cd make cargo go ssh scp psql uv pip echo cat env clickhouse-client".split(
60712
60721
  " "
@@ -60787,7 +60796,7 @@ var vaultOwnedKeychainSchemaDefinition = external_exports.discriminatedUnion("ki
60787
60796
  agentKeychain
60788
60797
  ]);
60789
60798
  var vaultOwnedKeychainSchema = vaultOwnedKeychainSchemaDefinition;
60790
- var vaultConnectionKindSchema = external_exports.enum(["api_key_set", "oauth", "mcp"]);
60799
+ var vaultConnectionKindSchema = external_exports.enum(["api_key_set", "oauth", "mcp", "aws"]);
60791
60800
  var vaultConnectionStatusSchema = external_exports.enum(["active", "needs_reconnect"]);
60792
60801
  var vaultFieldNameSchema = external_exports.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).max(64);
60793
60802
  var vaultConnectionNameSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{0,62}$/);
@@ -60832,6 +60841,15 @@ var vaultSecretBundleSchemaDefinition = external_exports.discriminatedUnion("kin
60832
60841
  serverUrl: external_exports.url(),
60833
60842
  headers: external_exports.record(external_exports.string().regex(/^[A-Za-z0-9-]{1,64}$/), external_exports.string().min(1)).default({}),
60834
60843
  tokens: vaultOAuthTokensSchema.nullable().default(null)
60844
+ }),
60845
+ /** An AWS access key: vaultd signs STS calls with it, releases carry only the session. */
60846
+ external_exports.object({
60847
+ kind: external_exports.literal("aws"),
60848
+ accessKeyId: external_exports.string().regex(/^[A-Z0-9]{16,128}$/),
60849
+ secretAccessKey: external_exports.string().min(16).max(256),
60850
+ roleArn: external_exports.string().regex(/^arn:aws[a-z-]*:iam::\d{12}:role\/[\w+=,.@/-]{1,512}$/).nullable().default(null),
60851
+ region: external_exports.string().regex(/^[a-z]{2}(-[a-z]+)+-\d$/),
60852
+ externalId: external_exports.string().min(2).max(1224).nullable().default(null)
60835
60853
  })
60836
60854
  ]);
60837
60855
  var vaultSecretBundleSchema = vaultSecretBundleSchemaDefinition;
@@ -61088,6 +61106,7 @@ var vaultRunReleaseSchemaDefinition = external_exports.discriminatedUnion("outco
61088
61106
  }),
61089
61107
  external_exports.object({ outcome: external_exports.literal("deny"), exitCode: external_exports.number().int(), message: external_exports.string() })
61090
61108
  ]);
61109
+ var vaultRunReleaseSchema = vaultRunReleaseSchemaDefinition;
61091
61110
  var vaultEgressResolveInputSchemaDefinition = external_exports.object({
61092
61111
  agentId: external_exports.string().min(1),
61093
61112
  connectionId: external_exports.string().min(1),
@@ -61414,6 +61433,8 @@ var vaultConfig = Config.define((c) => ({
61414
61433
  auditHeadFile: c.env("VAULT_AUDIT_HEAD_FILE", external_exports.string().min(1).optional()),
61415
61434
  /** vaultd's socket; set, the master key and data keys stay in vaultd, unset keeps them here. */
61416
61435
  vaultdSocket: c.env("LAZE_VAULTD_SOCKET", external_exports.string().min(1).optional()),
61436
+ /** Where the in-process key sends AWS STS calls instead of AWS; vaultd has its own flag. */
61437
+ awsStsEndpoint: c.env("LAZE_VAULT_AWS_STS_ENDPOINT", external_exports.url().optional()),
61417
61438
  /** The workspace whose admins get vault alert cards; unset only logs the alerts. */
61418
61439
  alertWorkspaceId: c.env("VAULT_ALERT_WORKSPACE_ID", external_exports.string().min(1).optional())
61419
61440
  }));
@@ -62042,6 +62063,56 @@ var vaultAlertClearedPayloadSchemaDefinition = external_exports.object({
62042
62063
  at: external_exports.iso.datetime()
62043
62064
  });
62044
62065
 
62066
+ // ../../modules/vault/contract/src/vault-env.ts
62067
+ var VAULT_BATCH_MAX_REFS = 100;
62068
+ var vaultBatchRefSchema = external_exports.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/, "A connection name or a variable name");
62069
+ var batchFieldsDefinition = {
62070
+ refs: external_exports.array(vaultBatchRefSchema).min(1).max(VAULT_BATCH_MAX_REFS),
62071
+ reason: external_exports.string(),
62072
+ command: external_exports.array(external_exports.string()).default([]),
62073
+ /** The run's P-256 public key, base64url; a sealed connection is released only to it. */
62074
+ recipient: external_exports.string().max(200).optional(),
62075
+ /** Resolve the names only: no decision, no card, no audit line and no value. */
62076
+ resolveOnly: external_exports.boolean().default(false)
62077
+ };
62078
+ var vaultBatchReleaseInputSchemaDefinition = external_exports.object({
62079
+ agentId: external_exports.string().min(1),
62080
+ ...batchFieldsDefinition
62081
+ });
62082
+ var vaultBatchReleaseInputSchema = vaultBatchReleaseInputSchemaDefinition;
62083
+ var vaultBatchConnectionSchemaDefinition = external_exports.object({
62084
+ name: vaultConnectionNameSchema,
62085
+ label: external_exports.string(),
62086
+ kind: vaultConnectionKindSchema,
62087
+ sensitivity: vaultSensitivitySchema,
62088
+ fieldNames: external_exports.array(external_exports.string())
62089
+ });
62090
+ var vaultBatchConnectionSchema = vaultBatchConnectionSchemaDefinition;
62091
+ var vaultBatchEntrySchemaDefinition = external_exports.object({
62092
+ ref: external_exports.string(),
62093
+ connection: vaultBatchConnectionSchema.nullable(),
62094
+ release: vaultRunReleaseSchema.nullable()
62095
+ });
62096
+ var vaultBatchEntrySchema = vaultBatchEntrySchemaDefinition;
62097
+ var vaultBatchReleaseSchemaDefinition = external_exports.object({
62098
+ entries: external_exports.array(vaultBatchEntrySchema)
62099
+ });
62100
+ var VAULT_AWS_SESSION_FIELDS = [
62101
+ "AWS_ACCESS_KEY_ID",
62102
+ "AWS_SECRET_ACCESS_KEY",
62103
+ "AWS_SESSION_TOKEN",
62104
+ "AWS_REGION",
62105
+ "AWS_DEFAULT_REGION",
62106
+ "AWS_CREDENTIAL_EXPIRATION"
62107
+ ];
62108
+ var vaultAwsSessionSchemaDefinition = external_exports.object({
62109
+ accessKeyId: external_exports.string().min(1),
62110
+ secretAccessKey: external_exports.string().min(1),
62111
+ sessionToken: external_exports.string().min(1),
62112
+ /** ISO 8601, as STS gives it. */
62113
+ expiration: external_exports.iso.datetime({ offset: true })
62114
+ });
62115
+
62045
62116
  // ../../modules/agent/contract/src/agent-access.ts
62046
62117
  var idSchema5 = external_exports.string().min(1).max(80);
62047
62118
  var agentGranteeSchemaDefinition = external_exports.discriminatedUnion("kind", [
@@ -62780,7 +62851,9 @@ var supervisorFrameSchemaDefinition = external_exports.discriminatedUnion("type"
62780
62851
  method: external_exports.enum(["GET", "POST"]),
62781
62852
  releaseId: external_exports.string().regex(/^[A-Za-z0-9_-]+$/).max(200).optional(),
62782
62853
  body: external_exports.string().max(64 * 1024).optional(),
62783
- turnToken: external_exports.string().min(1).max(8192)
62854
+ turnToken: external_exports.string().min(1).max(8192),
62855
+ /** `laze vault env`: the body is a batch of names, posted to the batch release. */
62856
+ batch: external_exports.boolean().optional()
62784
62857
  })
62785
62858
  ]);
62786
62859
  var computerLaunchSchemaDefinition = external_exports.object({
@@ -65226,6 +65299,11 @@ var agentVaultReleaseInputSchemaDefinition = external_exports.object({
65226
65299
  ...releaseShape,
65227
65300
  channelId: external_exports.string().min(1).max(80).nullable().default(null)
65228
65301
  });
65302
+ var { agentId: _batchAgentId, ...batchShape } = vaultBatchReleaseInputSchema.shape;
65303
+ var agentVaultBatchReleaseInputSchemaDefinition = external_exports.object({
65304
+ ...batchShape,
65305
+ channelId: external_exports.string().min(1).max(80).nullable().default(null)
65306
+ });
65229
65307
  var { id, name: name2, label, kind, keychain, sensitivity, fieldNames, status } = vaultConnectionSchema.shape;
65230
65308
  var agentOwnerKeySchemaDefinition = external_exports.object({
65231
65309
  id,
@@ -70182,8 +70260,8 @@ var CodexAppServer = class _CodexAppServer {
70182
70260
  }
70183
70261
  async call(method, params) {
70184
70262
  const id2 = ++this.#nextId;
70185
- const reply2 = await new Promise((resolve18) => {
70186
- this.#pending.set(id2, resolve18);
70263
+ const reply2 = await new Promise((resolve19) => {
70264
+ this.#pending.set(id2, resolve19);
70187
70265
  this.write({ id: id2, method, params });
70188
70266
  });
70189
70267
  if (reply2.error !== void 0) throw new Error(`${method}: ${JSON.stringify(reply2.error)}`);
@@ -70195,12 +70273,12 @@ var CodexAppServer = class _CodexAppServer {
70195
70273
  /** Starts one turn; `done` settles when it completes, keeping its last agent message. */
70196
70274
  async startTurn({ threadId, text: text2 }) {
70197
70275
  const result = { answer: "" };
70198
- const done = new Promise((resolve18) => {
70276
+ const done = new Promise((resolve19) => {
70199
70277
  const listen = (message2) => {
70200
70278
  absorbTurnEvent({ result, message: message2 });
70201
70279
  if (message2.method !== "turn/completed") return;
70202
70280
  this.#listeners.delete(listen);
70203
- resolve18(result);
70281
+ resolve19(result);
70204
70282
  };
70205
70283
  this.#listeners.add(listen);
70206
70284
  });
@@ -76326,7 +76404,7 @@ function tunnel({
76326
76404
  host: host2,
76327
76405
  port
76328
76406
  }) {
76329
- return new Promise((resolve18, reject) => {
76407
+ return new Promise((resolve19, reject) => {
76330
76408
  const socket = connectTcp(proxy.port, proxy.host);
76331
76409
  let answer4 = "";
76332
76410
  const auth = proxy.authorization ? `Proxy-Authorization: ${proxy.authorization}\r
@@ -76343,7 +76421,7 @@ ${auth}\r
76343
76421
  answer4 += chunk.toString("latin1");
76344
76422
  if (!answer4.includes(HEADER_END)) return;
76345
76423
  socket.off("data", onData);
76346
- if (/^HTTP\/1\.[01] 200/.test(answer4)) return resolve18(socket);
76424
+ if (/^HTTP\/1\.[01] 200/.test(answer4)) return resolve19(socket);
76347
76425
  socket.destroy();
76348
76426
  reject(new Error(`proxy refused the tunnel: ${answer4.split("\r\n")[0] ?? ""}`));
76349
76427
  };
@@ -76356,8 +76434,8 @@ async function upstreamOf({ target, proxy }) {
76356
76434
  const raw = proxy ? await tunnel({ proxy, host: target.hostname, port }) : connectTcp(port, target.hostname);
76357
76435
  if (!secure) return raw;
76358
76436
  const tls = connectTls({ socket: raw, servername: target.hostname });
76359
- await new Promise((resolve18, reject) => {
76360
- tls.once("secureConnect", () => resolve18());
76437
+ await new Promise((resolve19, reject) => {
76438
+ tls.once("secureConnect", () => resolve19());
76361
76439
  tls.once("error", reject);
76362
76440
  });
76363
76441
  return tls;
@@ -76399,8 +76477,8 @@ async function browserSocket({
76399
76477
  createConnection: () => upstream,
76400
76478
  perMessageDeflate: false
76401
76479
  });
76402
- await new Promise((resolve18, reject) => {
76403
- socket.once("open", () => resolve18());
76480
+ await new Promise((resolve19, reject) => {
76481
+ socket.once("open", () => resolve19());
76404
76482
  socket.once("error", reject);
76405
76483
  });
76406
76484
  return socket;
@@ -76413,12 +76491,12 @@ async function browserCall({
76413
76491
  }) {
76414
76492
  const socket = await browserSocket({ target, proxy });
76415
76493
  try {
76416
- return await new Promise((resolve18, reject) => {
76494
+ return await new Promise((resolve19, reject) => {
76417
76495
  socket.on("message", (data) => {
76418
76496
  const reply2 = JSON.parse(textOf2(data));
76419
76497
  if (reply2.id !== 1) return;
76420
76498
  if (reply2.error) reject(new Error(`${method}: ${JSON.stringify(reply2.error)}`));
76421
- else resolve18(reply2.result ?? {});
76499
+ else resolve19(reply2.result ?? {});
76422
76500
  });
76423
76501
  socket.once(
76424
76502
  "close",
@@ -76582,18 +76660,18 @@ function retargetCdpBridge({
76582
76660
  target,
76583
76661
  expiresAt
76584
76662
  }) {
76585
- return new Promise((resolve18) => {
76663
+ return new Promise((resolve19) => {
76586
76664
  const call = httpRequest(
76587
76665
  { host: "127.0.0.1", port, path: TARGET_PATH, method: "PUT", timeout: 2e3 },
76588
76666
  (response) => {
76589
76667
  response.resume();
76590
- resolve18(response.statusCode === 204);
76668
+ resolve19(response.statusCode === 204);
76591
76669
  }
76592
76670
  );
76593
76671
  call.setHeader(KEY_HEADER, key);
76594
76672
  call.setHeader("content-type", "application/json");
76595
76673
  call.once("timeout", () => call.destroy());
76596
- call.once("error", () => resolve18(false));
76674
+ call.once("error", () => resolve19(false));
76597
76675
  call.end(JSON.stringify({ target, expiresAt }));
76598
76676
  });
76599
76677
  }
@@ -76642,15 +76720,15 @@ async function startCdpBridge({
76642
76720
  (socket) => relayPage({ client: socket, targetId, target: url2, proxy })
76643
76721
  );
76644
76722
  });
76645
- await new Promise((resolve18) => server.listen(0, "127.0.0.1", resolve18));
76723
+ await new Promise((resolve19) => server.listen(0, "127.0.0.1", resolve19));
76646
76724
  const port = server.address().port;
76647
76725
  return {
76648
76726
  port,
76649
- close: () => new Promise((resolve18) => {
76727
+ close: () => new Promise((resolve19) => {
76650
76728
  for (const client of relayed) client.destroy();
76651
76729
  pages.close();
76652
76730
  server.closeAllConnections();
76653
- server.close(() => resolve18());
76731
+ server.close(() => resolve19());
76654
76732
  })
76655
76733
  };
76656
76734
  }
@@ -76667,7 +76745,7 @@ function launchCdpBridge({
76667
76745
  stdio: ["ignore", "pipe", "ignore"],
76668
76746
  env: { ...env, LAZE_CDP_TARGET: target, LAZE_CDP_EXPIRES_AT: expiresAt, LAZE_CDP_KEY: key }
76669
76747
  });
76670
- return new Promise((resolve18, reject) => {
76748
+ return new Promise((resolve19, reject) => {
76671
76749
  let printed = "";
76672
76750
  child.once("error", reject);
76673
76751
  child.once("exit", (code) => reject(new Error(`the CDP bridge stopped (${code})`)));
@@ -76678,7 +76756,7 @@ function launchCdpBridge({
76678
76756
  child.stdout.destroy();
76679
76757
  child.removeAllListeners("exit");
76680
76758
  child.unref();
76681
- if (Number.isInteger(port) && port > 0) resolve18(port);
76759
+ if (Number.isInteger(port) && port > 0) resolve19(port);
76682
76760
  else reject(new Error("the CDP bridge printed no port"));
76683
76761
  });
76684
76762
  });
@@ -81274,8 +81352,8 @@ var DOMAINS_USAGE = `Usage:
81274
81352
  var printJson5 = (context, data) => context.out(`${JSON.stringify(data, null, 2)}
81275
81353
  `);
81276
81354
  function printDomain(context, row) {
81277
- const join24 = row.autoJoin ? "auto-join on" : "auto-join off";
81278
- context.out(`${row.domain} ${join24}${row.enforced ? " single sign-on enforced" : ""}
81355
+ const join25 = row.autoJoin ? "auto-join on" : "auto-join off";
81356
+ context.out(`${row.domain} ${join25}${row.enforced ? " single sign-on enforced" : ""}
81279
81357
  `);
81280
81358
  }
81281
81359
  async function list4({ context, args }) {
@@ -82447,14 +82525,14 @@ async function signedGhArgs({
82447
82525
  const arg = args[index] ?? "";
82448
82526
  const [flag2 = "", inline] = arg.startsWith("--") ? arg.split(/=(.*)/s, 2) : [arg];
82449
82527
  const isBody = BODY_FLAGS.has(flag2);
82450
- const isFile = BODY_FILE_FLAGS.has(flag2);
82451
- if (!isBody && !isFile) {
82528
+ const isFile2 = BODY_FILE_FLAGS.has(flag2);
82529
+ if (!isBody && !isFile2) {
82452
82530
  out.push(arg);
82453
82531
  continue;
82454
82532
  }
82455
82533
  const value = inline ?? args[index + 1] ?? "";
82456
82534
  if (inline === void 0) index += 1;
82457
- const body = isFile ? await readBodyFile(value) : value;
82535
+ const body = isFile2 ? await readBodyFile(value) : value;
82458
82536
  out.push("--body", signed({ body, signature }));
82459
82537
  bodied = true;
82460
82538
  }
@@ -85766,6 +85844,456 @@ async function update2({
85766
85844
  return 1;
85767
85845
  }
85768
85846
 
85847
+ // src/services/vault-env-commands.service.ts
85848
+ import { readFile as readFile36, stat as stat5 } from "node:fs/promises";
85849
+ import { dirname as dirname22, join as join24, resolve as resolve15 } from "node:path";
85850
+
85851
+ // src/rules/vault-manifest.rules.ts
85852
+ var VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;
85853
+ var CONNECTION = /^[a-z0-9][a-z0-9-]{0,62}$/;
85854
+ var REFERENCE = /^\{\{vault:([A-Za-z0-9][A-Za-z0-9_/-]{0,127})\}\}$/;
85855
+ function refOf(name3) {
85856
+ return name3.split("/").at(-1) ?? name3;
85857
+ }
85858
+ function unquoted(value) {
85859
+ const trimmed = value.trim();
85860
+ const quote4 = trimmed[0];
85861
+ if ((quote4 === '"' || quote4 === "'") && trimmed.length >= 2 && trimmed.endsWith(quote4)) {
85862
+ return trimmed.slice(1, -1);
85863
+ }
85864
+ return trimmed;
85865
+ }
85866
+ function bareLineOf({ line, where }) {
85867
+ if (CONNECTION.test(line)) return { kind: "connection", ref: line };
85868
+ if (VARIABLE.test(line)) return { kind: "field", variable: line, ref: line };
85869
+ throw new CliUsageError(`${where}: not a name: ${line}`);
85870
+ }
85871
+ function lineOf4({ line, where }) {
85872
+ const at = line.indexOf("=");
85873
+ if (at === -1) return bareLineOf({ line, where });
85874
+ const variable = line.slice(0, at).trim();
85875
+ const value = line.slice(at + 1).trim();
85876
+ if (!VARIABLE.test(variable)) {
85877
+ throw new CliUsageError(`${where}: not a variable name: ${variable}`);
85878
+ }
85879
+ const reference = REFERENCE.exec(value);
85880
+ if (reference?.[1]) return { kind: "reference", variable, ref: refOf(reference[1]) };
85881
+ return { kind: "plain", variable, value: unquoted(value) };
85882
+ }
85883
+ function parseManifest({ text: text2, file: file3 }) {
85884
+ const lines2 = [];
85885
+ for (const [index, raw] of text2.split(/\r?\n/).entries()) {
85886
+ const line = raw.trim().replace(/^export\s+/, "");
85887
+ if (!line || line.startsWith("#")) continue;
85888
+ lines2.push(lineOf4({ line, where: `${file3}:${index + 1}` }));
85889
+ }
85890
+ return lines2;
85891
+ }
85892
+ function refsOf(lines2) {
85893
+ return [...new Set(lines2.flatMap((line) => line.kind === "plain" ? [] : [line.ref]))];
85894
+ }
85895
+ var isAwsSession = (fields) => VAULT_AWS_SESSION_FIELDS.every((name3) => fields[name3] !== void 0);
85896
+ function environmentOf({
85897
+ lines: lines2,
85898
+ released
85899
+ }) {
85900
+ const env = {};
85901
+ for (const line of lines2) {
85902
+ if (line.kind === "plain") {
85903
+ env[line.variable] = line.value;
85904
+ continue;
85905
+ }
85906
+ const fields = released.get(line.ref)?.fields;
85907
+ if (!fields) throw new CliUsageError(`laze vault: nothing was released for ${line.ref}`);
85908
+ if (line.kind === "connection" || isAwsSession(fields)) {
85909
+ Object.assign(env, fields);
85910
+ continue;
85911
+ }
85912
+ const names = Object.keys(fields);
85913
+ const value = fields[line.variable] ?? (names.length === 1 ? fields[names[0] ?? ""] : void 0);
85914
+ if (value === void 0) {
85915
+ throw new CliUsageError(
85916
+ `laze vault: ${line.ref} has no field ${line.variable} (it has ${names.join(", ")}); write ${line.variable}={{vault:<connection>}} for a one-field key, or name the connection on its own line`
85917
+ );
85918
+ }
85919
+ env[line.variable] = value;
85920
+ }
85921
+ return env;
85922
+ }
85923
+ function shellExports(env) {
85924
+ return Object.entries(env).map(([name3, value]) => `export ${name3}='${value.replaceAll("'", `'\\''`)}'`).join("\n");
85925
+ }
85926
+ function credentialProcessJson(fields) {
85927
+ return JSON.stringify({
85928
+ Version: 1,
85929
+ AccessKeyId: fields.AWS_ACCESS_KEY_ID,
85930
+ SecretAccessKey: fields.AWS_SECRET_ACCESS_KEY,
85931
+ SessionToken: fields.AWS_SESSION_TOKEN,
85932
+ Expiration: fields.AWS_CREDENTIAL_EXPIRATION
85933
+ });
85934
+ }
85935
+
85936
+ // src/services/vault-batch.service.ts
85937
+ import { rm as rm14 } from "node:fs/promises";
85938
+ var WHERE = "laze vault env works only on a Laze agent's computer, on a machine it runs on, or signed in as a connected agent";
85939
+ async function batchOf({ response }) {
85940
+ const text2 = await response.text();
85941
+ if (!response.ok) {
85942
+ const code = /"code"\s*:\s*"([^"]+)"/.exec(text2)?.[1] ?? `status ${response.status}`;
85943
+ throw new CliUsageError(`laze vault: the batch was refused (${code})`);
85944
+ }
85945
+ return JSON.parse(text2);
85946
+ }
85947
+ async function doorOf({
85948
+ context,
85949
+ args,
85950
+ keyName
85951
+ }) {
85952
+ const env = context.environment.inherited;
85953
+ const proxy = proxyOf({ env });
85954
+ if (proxy) {
85955
+ const turnFile = turnFileOf({ env });
85956
+ const headers = {
85957
+ "proxy-authorization": proxy.authorization,
85958
+ "x-laze-turn": await turnTokenOf3({ env, turnFile, command: "laze vault env" })
85959
+ };
85960
+ return {
85961
+ keyPath: runKeyPathOf({ turnFile, connection: keyName }),
85962
+ ask: async (body) => batchOf({
85963
+ response: await reach({
85964
+ context,
85965
+ url: `${proxy.origin}/vault/release-batch`,
85966
+ init: {
85967
+ method: "POST",
85968
+ headers: { ...headers, "content-type": "application/json" },
85969
+ body: JSON.stringify(body)
85970
+ }
85971
+ })
85972
+ }),
85973
+ status: async (requestId) => releaseOf({
85974
+ response: await reach({
85975
+ context,
85976
+ url: `${proxy.origin}/vault/release/${encodeURIComponent(requestId)}`,
85977
+ init: { method: "GET", headers }
85978
+ })
85979
+ })
85980
+ };
85981
+ }
85982
+ const signed2 = await signedIn({ context, args }).catch(() => null);
85983
+ if (signed2?.profile.kind !== "agent") throw new CliUsageError(WHERE);
85984
+ const { client, name: name3 } = signed2;
85985
+ const channelId = flagText({ args, name: "channel" }) || null;
85986
+ return {
85987
+ keyPath: runKeyPathOf({ turnFile: void 0, connection: keyName, profile: name3 }),
85988
+ ask: async (body) => {
85989
+ try {
85990
+ return await client.post("/api/agents/me/vault/release-batch", {
85991
+ ...body,
85992
+ channelId
85993
+ });
85994
+ } catch (error62) {
85995
+ if (!(error62 instanceof LazeApiError)) throw error62;
85996
+ throw new CliUsageError(
85997
+ `laze vault: the batch was refused: ${error62.message} (${error62.code})`
85998
+ );
85999
+ }
86000
+ },
86001
+ status: (requestId) => client.post("/api/agents/me/vault/release-status", { requestId, channelId }).catch(refusedRelease)
86002
+ };
86003
+ }
86004
+ async function resolveBatch({
86005
+ context,
86006
+ args,
86007
+ refs
86008
+ }) {
86009
+ const door = await doorOf({ context, args, keyName: "env-names" });
86010
+ const answer4 = await door.ask({ refs, reason: "", command: [], resolveOnly: true });
86011
+ return answer4.entries;
86012
+ }
86013
+ var keyOf = (entry) => entry.connection?.name ?? entry.ref;
86014
+ async function untilAllAnswered({
86015
+ context,
86016
+ door,
86017
+ waiting,
86018
+ deadline
86019
+ }) {
86020
+ const answered = /* @__PURE__ */ new Map();
86021
+ if (waiting.size === 0) return answered;
86022
+ const [first] = waiting.values();
86023
+ context.err(
86024
+ `laze vault: ${[...waiting.keys()].join(", ")} wait for an answer (${first?.message ?? "a card"}); cards expire after 12 hours...
86025
+ `
86026
+ );
86027
+ while (waiting.size > 0) {
86028
+ if (context.nowMs() + POLL_MS2 > deadline) {
86029
+ context.err(
86030
+ `laze vault: ${[...waiting.keys()].join(", ")} not approved yet; ask again later.
86031
+ `
86032
+ );
86033
+ return "capped";
86034
+ }
86035
+ await context.sleep(POLL_MS2);
86036
+ for (const [key, pending] of waiting) {
86037
+ const next = await door.status(pending.requestId);
86038
+ if (next.outcome === "ask") waiting.set(key, next);
86039
+ else {
86040
+ waiting.delete(key);
86041
+ answered.set(key, next);
86042
+ }
86043
+ }
86044
+ }
86045
+ return answered;
86046
+ }
86047
+ async function releaseBatch({
86048
+ context,
86049
+ args,
86050
+ refs,
86051
+ reason,
86052
+ command
86053
+ }) {
86054
+ const deadline = deadlineOf({ args, nowMs: context.nowMs() });
86055
+ const door = await doorOf({ context, args, keyName: `env:${[...refs].toSorted().join(",")}` });
86056
+ const run4 = await runKeyAt({ path: door.keyPath });
86057
+ let answer4;
86058
+ let settled2;
86059
+ try {
86060
+ answer4 = await door.ask({ refs, reason, command, recipient: run4.publicKey });
86061
+ const missing = answer4.entries.filter((entry) => !entry.connection);
86062
+ if (missing.length > 0) {
86063
+ context.err(
86064
+ `laze vault: no key named ${missing.map((entry) => entry.ref).join(", ")} in your vault or reachable by this agent
86065
+ `
86066
+ );
86067
+ return { exitCode: 1 };
86068
+ }
86069
+ settled2 = /* @__PURE__ */ new Map();
86070
+ const waiting = /* @__PURE__ */ new Map();
86071
+ for (const entry of answer4.entries) {
86072
+ const release2 = entry.release;
86073
+ if (!release2) continue;
86074
+ if (release2.outcome === "ask") waiting.set(keyOf(entry), release2);
86075
+ else settled2.set(keyOf(entry), release2);
86076
+ }
86077
+ const later = await untilAllAnswered({ context, door, waiting, deadline });
86078
+ if (later === "capped") return { exitCode: 75 };
86079
+ for (const [key, release2] of later) settled2.set(key, release2);
86080
+ } catch (error62) {
86081
+ if (!(error62 instanceof ServerGoneError)) throw error62;
86082
+ context.err(`${error62.message}. Run the command again to keep waiting.
86083
+ `);
86084
+ return { exitCode: 75 };
86085
+ }
86086
+ return valuesOf({ context, entries: answer4.entries, settled: settled2, run: run4, keyPath: door.keyPath });
86087
+ }
86088
+ function refusalOf({
86089
+ context,
86090
+ settled: settled2
86091
+ }) {
86092
+ const codes = [];
86093
+ for (const [key, release2] of settled2) {
86094
+ if (release2.outcome !== "deny") continue;
86095
+ context.err(`laze vault: ${key}: ${release2.message}
86096
+ `);
86097
+ codes.push(release2.exitCode || 1);
86098
+ }
86099
+ if (codes.length === 0) return 0;
86100
+ return codes.includes(77) ? 77 : codes[0] ?? 1;
86101
+ }
86102
+ async function valuesOf({
86103
+ context,
86104
+ entries,
86105
+ settled: settled2,
86106
+ run: run4,
86107
+ keyPath
86108
+ }) {
86109
+ const refused = refusalOf({ context, settled: settled2 });
86110
+ if (refused !== 0) {
86111
+ await rm14(keyPath, { force: true });
86112
+ return { exitCode: refused };
86113
+ }
86114
+ const opened = /* @__PURE__ */ new Map();
86115
+ let keep = false;
86116
+ for (const [key, release2] of settled2) {
86117
+ if (release2.outcome !== "allow") continue;
86118
+ opened.set(key, await envOf({ release: release2, run: run4 }));
86119
+ if (leaseHolds({ release: release2, nowMs: context.nowMs() })) keep = true;
86120
+ if (release2.message) context.err(`${release2.message}
86121
+ `);
86122
+ }
86123
+ if (!keep) await rm14(keyPath, { force: true });
86124
+ const released = /* @__PURE__ */ new Map();
86125
+ for (const entry of entries) {
86126
+ const fields = opened.get(keyOf(entry));
86127
+ if (fields) released.set(entry.ref, { fields });
86128
+ }
86129
+ return { released, entries };
86130
+ }
86131
+
86132
+ // src/services/vault-env-commands.service.ts
86133
+ var ENV_USAGE = `Usage: laze vault env [<file>] [--env <name>] --reason "<one plain sentence>" [--wait <s>] -- <command> [args...]
86134
+ laze vault env [<file>] [--env <name>] --names
86135
+ laze vault env [<file>] --shell [--command-b64 <base64>] --reason "<one plain sentence>"
86136
+ Runs the command with every key the manifest names in its environment, asked in one go.
86137
+ The manifest is .env.vault (.env.<name>.vault with --env), here or in the nearest parent folder.
86138
+ Lines: KEY (the field KEY of the key that holds it), KEY={{vault:<name>}}, a key's name (all its
86139
+ fields) or KEY=value (plain text); # starts a comment.
86140
+ --names what each line resolves to, never a value
86141
+ --shell export lines to eval instead of running a command; refused on a terminal
86142
+ --reason or KV_REASON / LAZE_VAULT_REASON in the environment
86143
+ Exit codes: the command's own; 2 the reason was refused; 77 the vault denied a key, do not retry;
86144
+ 75 the wait ran out, run it again to keep waiting; 1 a usage error or a name nothing resolves.`;
86145
+ var AWS_USAGE = `Usage: laze vault aws <connection> [--reason "<one plain sentence>"] [-- <command> [args...]]
86146
+ Prints AWS credential_process JSON with a short-lived STS session minted from the key, for
86147
+ ~/.aws/config: credential_process = laze vault aws <connection>
86148
+ With -- <command>, runs it with AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN set.
86149
+ The reason comes from --reason, else KV_REASON or LAZE_VAULT_REASON: set it on each aws, kubectl,
86150
+ helm or terraform command, which reach this through credential_process.`;
86151
+ function reasonOf({ context, args }) {
86152
+ const env = context.environment.inherited;
86153
+ return flagText({ args, name: "reason" }) || env.KV_REASON?.trim() || env.LAZE_VAULT_REASON?.trim() || "";
86154
+ }
86155
+ function refusedReason({
86156
+ context,
86157
+ reason
86158
+ }) {
86159
+ const problem = checkVaultReason(reason);
86160
+ if (problem === "ok") return null;
86161
+ context.err(`laze vault: the reason is refused (${problem}). ${VAULT_REASON_GUIDANCE}
86162
+ `);
86163
+ return VAULT_EXIT_BAD_REASON;
86164
+ }
86165
+ async function isFile(path) {
86166
+ return stat5(path).then(
86167
+ (found) => found.isFile(),
86168
+ () => false
86169
+ );
86170
+ }
86171
+ async function manifestPathOf({
86172
+ context,
86173
+ args
86174
+ }) {
86175
+ const named = args.words[2];
86176
+ if (named) return resolve15(context.cwd, named);
86177
+ const environment = flagText({ args, name: "env" });
86178
+ const file3 = environment ? `.env.${environment}.vault` : ".env.vault";
86179
+ for (let dir = resolve15(context.cwd); ; dir = dirname22(dir)) {
86180
+ if (await isFile(join24(dir, file3))) return join24(dir, file3);
86181
+ if (dirname22(dir) === dir) break;
86182
+ }
86183
+ throw new CliUsageError(`laze vault: no ${file3} here or in a parent folder
86184
+ ${ENV_USAGE}`);
86185
+ }
86186
+ async function manifestOf({
86187
+ context,
86188
+ args
86189
+ }) {
86190
+ const file3 = await manifestPathOf({ context, args });
86191
+ const text2 = await readFile36(file3, "utf8").catch(() => {
86192
+ throw new CliUsageError(`laze vault: cannot read ${file3}`);
86193
+ });
86194
+ return { file: file3, lines: parseManifest({ text: text2, file: file3 }) };
86195
+ }
86196
+ async function printNames({
86197
+ context,
86198
+ args,
86199
+ lines: lines2
86200
+ }) {
86201
+ const refs = refsOf(lines2);
86202
+ const entries = refs.length > 0 ? await resolveBatch({ context, args, refs }) : [];
86203
+ const byRef = new Map(entries.map((entry) => [entry.ref, entry.connection]));
86204
+ let missing = false;
86205
+ for (const line of lines2) {
86206
+ const label3 = line.kind === "connection" ? line.ref : line.variable;
86207
+ if (line.kind === "plain") {
86208
+ context.out(`${label3} plain
86209
+ `);
86210
+ continue;
86211
+ }
86212
+ const connection = byRef.get(line.ref);
86213
+ if (!connection) missing = true;
86214
+ context.out(
86215
+ connection ? `${label3} ${connection.name} ${vaultLevelLabel(connection.sensitivity)}
86216
+ ` : `${label3} not found
86217
+ `
86218
+ );
86219
+ }
86220
+ return missing ? 1 : 0;
86221
+ }
86222
+ function wrappedCommandOf(args) {
86223
+ const encoded = flagText({ args, name: "command-b64" });
86224
+ if (!encoded) return ["(shell)"];
86225
+ return [Buffer.from(encoded, "base64").toString("utf8").slice(0, 2e3)];
86226
+ }
86227
+ async function vaultEnv2({
86228
+ context,
86229
+ args
86230
+ }) {
86231
+ if (args.flags.help) {
86232
+ context.out(`${ENV_USAGE}
86233
+ `);
86234
+ return 0;
86235
+ }
86236
+ const { lines: lines2 } = await manifestOf({ context, args });
86237
+ if (args.flags.names) return printNames({ context, args, lines: lines2 });
86238
+ const shell = args.flags.shell === true;
86239
+ if (shell && context.stdoutIsTerminal) {
86240
+ throw new CliUsageError(
86241
+ "laze vault env --shell prints values: it runs only with its output to a pipe, such as the Bash hook's eval"
86242
+ );
86243
+ }
86244
+ if (!shell && args.rest.length === 0) throw new CliUsageError(ENV_USAGE);
86245
+ const reason = reasonOf({ context, args });
86246
+ if (!reason)
86247
+ throw new CliUsageError(`Say why with --reason "<one plain sentence>"
86248
+ ${ENV_USAGE}`);
86249
+ const badReason = refusedReason({ context, reason });
86250
+ if (badReason !== null) return badReason;
86251
+ const refs = refsOf(lines2);
86252
+ let released = /* @__PURE__ */ new Map();
86253
+ if (refs.length > 0) {
86254
+ const command = shell ? wrappedCommandOf(args) : args.rest;
86255
+ const outcome = await releaseBatch({ context, args, refs, reason, command });
86256
+ if ("exitCode" in outcome) return outcome.exitCode;
86257
+ released = outcome.released;
86258
+ }
86259
+ const env = environmentOf({ lines: lines2, released });
86260
+ if (shell) {
86261
+ context.out(`${shellExports(env)}
86262
+ `);
86263
+ return 0;
86264
+ }
86265
+ return context.runCommand({ command: args.rest, env });
86266
+ }
86267
+ async function vaultAws({
86268
+ context,
86269
+ args
86270
+ }) {
86271
+ const connection = args.words[2];
86272
+ if (!connection || args.flags.help) throw new CliUsageError(AWS_USAGE);
86273
+ const reason = reasonOf({ context, args });
86274
+ if (!reason) {
86275
+ throw new CliUsageError(
86276
+ `Say why with --reason "<one plain sentence>" or KV_REASON
86277
+ ${AWS_USAGE}`
86278
+ );
86279
+ }
86280
+ const badReason = refusedReason({ context, reason });
86281
+ if (badReason !== null) return badReason;
86282
+ const command = args.rest.length > 0 ? args.rest : ["credential_process"];
86283
+ const outcome = await releaseBatch({ context, args, refs: [connection], reason, command });
86284
+ if ("exitCode" in outcome) return outcome.exitCode;
86285
+ const fields = outcome.released.get(connection)?.fields ?? {};
86286
+ if (!fields.AWS_SESSION_TOKEN) {
86287
+ context.err(`laze vault: ${connection} is not an AWS key; use laze vault run for it
86288
+ `);
86289
+ return 1;
86290
+ }
86291
+ if (args.rest.length > 0) return context.runCommand({ command: args.rest, env: fields });
86292
+ context.out(`${credentialProcessJson(fields)}
86293
+ `);
86294
+ return 0;
86295
+ }
86296
+
85769
86297
  // src/services/vault-save-message-commands.service.ts
85770
86298
  var SAVE_USAGE = `Usage: laze vault save <pending> --name <name> --description "<what it is for>"
85771
86299
  Names a key Laze held from a message you received, in the sender's vault.
@@ -85839,7 +86367,7 @@ async function vaultSave({ context, args }) {
85839
86367
  }
85840
86368
 
85841
86369
  // src/services/vault-scrub-commands.service.ts
85842
- function lineOf4(channel) {
86370
+ function lineOf5(channel) {
85843
86371
  const where = channel.name ? `#${channel.name}` : channel.channelId;
85844
86372
  const found = Object.entries(channel.found).map(([vendor, count5]) => `${vendor} ${count5}`).join(", ");
85845
86373
  const kinds = [`held ${channel.held}`, ...found ? [`found: ${found}`] : []].join("; ");
@@ -85853,7 +86381,7 @@ async function vaultScrub({ context, args }) {
85853
86381
  if (args.flags.json) return context.out(`${JSON.stringify(report3, null, 2)}
85854
86382
  `);
85855
86383
  const changed = report3.channels.filter((channel) => channel.messages > 0);
85856
- for (const channel of changed) context.out(lineOf4(channel));
86384
+ for (const channel of changed) context.out(lineOf5(channel));
85857
86385
  const total = changed.reduce((sum, channel) => sum + channel.messages, 0);
85858
86386
  context.out(
85859
86387
  report3.dryRun ? `Dry run: ${total} message(s) would change. Nothing was changed.
@@ -85863,8 +86391,8 @@ async function vaultScrub({ context, args }) {
85863
86391
  }
85864
86392
 
85865
86393
  // src/services/whatsapp-business-commands.service.ts
85866
- import { readFile as readFile36 } from "node:fs/promises";
85867
- import { resolve as resolve15 } from "node:path";
86394
+ import { readFile as readFile37 } from "node:fs/promises";
86395
+ import { resolve as resolve16 } from "node:path";
85868
86396
 
85869
86397
  // ../../modules/whatsapp-business/contract/src/whatsapp-business.prices.ts
85870
86398
  var whatsappBusinessCategorySchema = external_exports.enum([
@@ -86283,7 +86811,7 @@ async function secretsOf2({ context, args }) {
86283
86811
  const fromConnection = flagText({ args, name: "from-vault" });
86284
86812
  if (fromConnection) return { fromConnection };
86285
86813
  const file3 = flagText({ args, name: "from-file" });
86286
- const text2 = file3 ? await readFile36(resolve15(context.cwd, file3), "utf8") : await context.readStdin();
86814
+ const text2 = file3 ? await readFile37(resolve16(context.cwd, file3), "utf8") : await context.readStdin();
86287
86815
  const lines2 = text2.split("\n").map((line) => line.trim()).filter(Boolean);
86288
86816
  if (lines2.length !== 2) {
86289
86817
  throw new CliUsageError(
@@ -86485,7 +87013,7 @@ async function whatsappBusiness({
86485
87013
 
86486
87014
  // src/services/whatsapp-pairing-commands.service.ts
86487
87015
  import { writeFile as writeFile22 } from "node:fs/promises";
86488
- import { resolve as resolve16 } from "node:path";
87016
+ import { resolve as resolve17 } from "node:path";
86489
87017
  var WHATSAPP_PAIRING_USAGE = [
86490
87018
  " laze whatsapp pair <machine> [--qr <file.svg>] link WhatsApp on your machine; scan the code (owner)",
86491
87019
  " laze whatsapp pairing <pairing-id> [--qr <file.svg>] where the linking stands, with a fresh code",
@@ -86504,7 +87032,7 @@ function svgOf(dataUrl) {
86504
87032
  return decodeURIComponent(body);
86505
87033
  }
86506
87034
  async function report({ context, args, pairing: pairing2 }) {
86507
- const qrFile = pairing2.qrSvg ? resolve16(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
87035
+ const qrFile = pairing2.qrSvg ? resolve17(context.cwd, flagText({ args, name: "qr", fallback: "whatsapp-qr.svg" })) : null;
86508
87036
  if (qrFile && pairing2.qrSvg) await writeFile22(qrFile, svgOf(pairing2.qrSvg), "utf8");
86509
87037
  if (args.flags.json) return context.out(`${JSON.stringify({ ...pairing2, qrFile }, null, 2)}
86510
87038
  `);
@@ -86864,8 +87392,8 @@ async function flags({ context, args }) {
86864
87392
  }
86865
87393
 
86866
87394
  // src/services/workspace-commands.service.ts
86867
- import { readFile as readFile37 } from "node:fs/promises";
86868
- import { resolve as resolve17 } from "node:path";
87395
+ import { readFile as readFile38 } from "node:fs/promises";
87396
+ import { resolve as resolve18 } from "node:path";
86869
87397
  var ROLE_NAMES2 = {
86870
87398
  OWNER: "Owner",
86871
87399
  ADMIN: "Admin",
@@ -87047,7 +87575,7 @@ var LOGO_USAGE = "Usage: laze workspace logo set <file.png|jpg|webp> | laze work
87047
87575
  async function readLogo({ context, file: file3 }) {
87048
87576
  let bytes;
87049
87577
  try {
87050
- bytes = new Uint8Array(await readFile37(resolve17(context.cwd, file3)));
87578
+ bytes = new Uint8Array(await readFile38(resolve18(context.cwd, file3)));
87051
87579
  } catch {
87052
87580
  throw new CliUsageError(`No file to read at ${file3}.`);
87053
87581
  }
@@ -87411,6 +87939,9 @@ var HELP = `laze: work in a Laze workspace from your terminal or your agent.
87411
87939
  laze adopt codex [--thread <id>] answer Laze messages in a Codex thread
87412
87940
  laze adopt codex --status | --stop the background adopt that laze agent link started
87413
87941
  laze vault run <name> --reason "<why>" -- <cmd> run a command with a vault connection (agents)
87942
+ laze vault env [<file>] --reason "<why>" -- <cmd> run a command with every key .env.vault names (agents)
87943
+ laze vault env --names | --shell what .env.vault resolves to; export lines for a shell hook
87944
+ laze vault aws <connection> [--reason "<why>"] AWS credential_process JSON from a short-lived STS session
87414
87945
  laze vault save <pending> --name <name> --description "<text>" name a key Laze held from a message (agents)
87415
87946
  laze vault save --from-message <id> --name <name> --description "<text>" save a key a person sent,
87416
87947
  read from stdin, to their own vault; the message keeps {{vault:<name>}} (agents, no vault access)
@@ -87571,6 +88102,8 @@ var COMMANDS3 = {
87571
88102
  skill,
87572
88103
  app,
87573
88104
  "vault run": vaultRun,
88105
+ "vault env": vaultEnv2,
88106
+ "vault aws": vaultAws,
87574
88107
  "vault save": vaultSave,
87575
88108
  "vault save-from-message": vaultSaveFromMessage,
87576
88109
  connect,
@@ -87716,8 +88249,8 @@ async function runCli({
87716
88249
  // src/services/processes.service.ts
87717
88250
  import { execFile as execFile2, spawn as spawn4 } from "node:child_process";
87718
88251
  import { mkdirSync, openSync } from "node:fs";
87719
- import { readFile as readFile38, readlink } from "node:fs/promises";
87720
- import { dirname as dirname22 } from "node:path";
88252
+ import { readFile as readFile39, readlink } from "node:fs/promises";
88253
+ import { dirname as dirname23 } from "node:path";
87721
88254
  import { promisify as promisify2 } from "node:util";
87722
88255
  var run3 = promisify2(execFile2);
87723
88256
  function alive(pid) {
@@ -87730,15 +88263,15 @@ function alive(pid) {
87730
88263
  }
87731
88264
  }
87732
88265
  async function argsOf(pid) {
87733
- const raw = await readFile38(`/proc/${pid}/cmdline`, "utf8").catch(() => void 0);
88266
+ const raw = await readFile39(`/proc/${pid}/cmdline`, "utf8").catch(() => void 0);
87734
88267
  if (raw) return raw.split("\0").filter(Boolean);
87735
88268
  const listed = await run3("ps", ["-o", "args=", "-p", String(pid)]).catch(() => void 0);
87736
88269
  const line = listed?.stdout.trim();
87737
88270
  return line ? line.split(/\s+/) : void 0;
87738
88271
  }
87739
88272
  async function parentOf(pid) {
87740
- const stat5 = await readFile38(`/proc/${pid}/stat`, "utf8").catch(() => void 0);
87741
- const fromStat = stat5 ? Number(stat5.slice(stat5.lastIndexOf(")") + 2).split(" ")[1]) : NaN;
88273
+ const stat6 = await readFile39(`/proc/${pid}/stat`, "utf8").catch(() => void 0);
88274
+ const fromStat = stat6 ? Number(stat6.slice(stat6.lastIndexOf(")") + 2).split(" ")[1]) : NaN;
87742
88275
  if (fromStat > 0) return fromStat;
87743
88276
  const listed = await run3("ps", ["-o", "ppid=", "-p", String(pid)]).catch(() => void 0);
87744
88277
  const parent = Number(listed?.stdout.trim());
@@ -87754,7 +88287,7 @@ async function cwdOf(pid) {
87754
88287
  return line ? line.slice(1) : void 0;
87755
88288
  }
87756
88289
  function spawnDetached({ argv, logPath }) {
87757
- mkdirSync(dirname22(logPath), { recursive: true, mode: 448 });
88290
+ mkdirSync(dirname23(logPath), { recursive: true, mode: 448 });
87758
88291
  const log = openSync(logPath, "a", 384);
87759
88292
  const [program = "", ...rest] = argv;
87760
88293
  const child = spawn4(program, rest, { detached: true, stdio: ["ignore", log, log] });
@@ -87848,15 +88381,15 @@ function terminalAsk() {
87848
88381
  };
87849
88382
  }
87850
88383
  function sleep(ms, signal) {
87851
- return new Promise((resolve18) => {
87852
- if (signal?.aborted) return resolve18();
88384
+ return new Promise((resolve19) => {
88385
+ if (signal?.aborted) return resolve19();
87853
88386
  const stop3 = () => {
87854
88387
  clearTimeout(timer);
87855
- resolve18();
88388
+ resolve19();
87856
88389
  };
87857
88390
  const timer = setTimeout(() => {
87858
88391
  signal?.removeEventListener("abort", stop3);
87859
- resolve18();
88392
+ resolve19();
87860
88393
  }, ms);
87861
88394
  signal?.addEventListener("abort", stop3, { once: true });
87862
88395
  });
@@ -87880,6 +88413,7 @@ if (true) {
87880
88413
  out: (text2) => void process.stdout.write(text2),
87881
88414
  err: (text2) => void process.stderr.write(text2),
87882
88415
  readStdin,
88416
+ stdoutIsTerminal: process.stdout.isTTY === true,
87883
88417
  ...ask ? { ask } : {},
87884
88418
  sleep,
87885
88419
  nowMs: () => nowInstant().epochMilliseconds,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazehq/cli",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
4
4
  "description": "The Laze command line: sign in, read and post in chat, and connect your own Claude Code or Codex session as an agent.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",