@vm0/cli 9.253.0 → 9.254.1

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 (110) hide show
  1. package/{agent-X6O3YR4M.js → agent-CDMQ3BO4.js} +7 -7
  2. package/{banking-NGZXYSVB.js → banking-M5CIVLRH.js} +5 -5
  3. package/chat-TRK5KDSP.js +622 -0
  4. package/chat-TRK5KDSP.js.map +1 -0
  5. package/{chunk-7YTIE7KU.js → chunk-5QLT6M5N.js} +165 -46
  6. package/{chunk-7YTIE7KU.js.map → chunk-5QLT6M5N.js.map} +1 -1
  7. package/{chunk-RMLNBK2X.js → chunk-7NYMO54N.js} +2 -2
  8. package/chunk-B6ELBBRJ.js +83 -0
  9. package/chunk-B6ELBBRJ.js.map +1 -0
  10. package/{chunk-RANJI5FZ.js → chunk-BL37FBZF.js} +2 -2
  11. package/{chunk-XM3WOXFE.js → chunk-BXVXXD3E.js} +4 -4
  12. package/{chunk-KMRZUQHC.js → chunk-D4OTAABD.js} +3 -2
  13. package/{chunk-KMRZUQHC.js.map → chunk-D4OTAABD.js.map} +1 -1
  14. package/{chunk-7JNLGFRW.js → chunk-JLEBJUMI.js} +11 -76
  15. package/chunk-JLEBJUMI.js.map +1 -0
  16. package/{chunk-LIT3JQQR.js → chunk-JXYKIW37.js} +2 -2
  17. package/{chunk-2YJV4T5H.js → chunk-R23NULE7.js} +43 -42
  18. package/chunk-R23NULE7.js.map +1 -0
  19. package/{chunk-2E37DQSD.js → chunk-TBBXBBFT.js} +2 -2
  20. package/{chunk-FJFJLQQW.js → chunk-UUKFGXX5.js} +2 -2
  21. package/{chunk-LO2JYFNP.js → chunk-XBX4JTXR.js} +2 -2
  22. package/{computer-use-C3HZXTKZ.js → computer-use-K7ULCJNC.js} +5 -5
  23. package/{connector-DPZKQG4U.js → connector-JFE4GTW4.js} +8 -8
  24. package/{credit-WY6P3D6B.js → credit-QVY2XIPE.js} +7 -7
  25. package/{developer-support-RYY76Y65.js → developer-support-EJOQWXKB.js} +5 -5
  26. package/{doctor-XZH52P7J.js → doctor-7YEA3BYV.js} +7 -7
  27. package/{esm-GOCEMHJO.js → esm-IFLVLSSI.js} +102 -74
  28. package/esm-IFLVLSSI.js.map +1 -0
  29. package/{feishu-HLSIBEHH.js → feishu-KCN4UME3.js} +5 -5
  30. package/{finance-IWVIYPXL.js → finance-TOKK5DCK.js} +5 -5
  31. package/{generate-IAA656VE.js → generate-6E23MDCE.js} +7 -7
  32. package/{github-MJZJ2VLC.js → github-LJMT5D7D.js} +5 -5
  33. package/{goal-7OCVIFTQ.js → goal-OJ4J7OCD.js} +5 -5
  34. package/{host-KX7NPRZM.js → host-KX5G666N.js} +5 -5
  35. package/{logs-AHOU7TJL.js → logs-IDABHTFA.js} +12 -10
  36. package/{logs-AHOU7TJL.js.map → logs-IDABHTFA.js.map} +1 -1
  37. package/{mail-D3YBSKA6.js → mail-U6JQDKN3.js} +7 -7
  38. package/{maps-AT7I4KK6.js → maps-Y7PIXKLP.js} +5 -5
  39. package/{model-7AEJV5QI.js → model-PXWGKXUA.js} +6 -6
  40. package/{model-provider-CNTRAXGR.js → model-provider-LNVO4LHA.js} +6 -6
  41. package/{org-4EOIMAMU.js → org-G46VCLIF.js} +5 -5
  42. package/package.json +1 -1
  43. package/{people-search-YIPV2HRX.js → people-search-TZBJNLYY.js} +5 -5
  44. package/{phone-RGFGHH4G.js → phone-KEHX5BEJ.js} +5 -5
  45. package/{preference-UIFDOWCE.js → preference-5KLKA6DR.js} +5 -5
  46. package/{resource-UCO5W2EM.js → resource-W2PYM3GG.js} +123 -122
  47. package/resource-W2PYM3GG.js.map +1 -0
  48. package/{scrape-V6KXL77N.js → scrape-27OBJPNR.js} +5 -5
  49. package/{search-FKCTV4PA.js → search-23XNHEE5.js} +11 -9
  50. package/{search-FKCTV4PA.js.map → search-23XNHEE5.js.map} +1 -1
  51. package/{secret-ZOUQEPTX.js → secret-IRLST7ZX.js} +5 -5
  52. package/{slack-4WKWNC54.js → slack-U3YX4HK7.js} +5 -5
  53. package/{teams-MRN5OZEA.js → teams-2BPJ3VT4.js} +5 -5
  54. package/{telegram-DJ6DOWYM.js → telegram-B7JBB6M2.js} +5 -5
  55. package/{upgrade-2VYHUARI.js → upgrade-SFFQF2QF.js} +4 -4
  56. package/{variable-6SNXAUY7.js → variable-ZZ7OX5PU.js} +5 -5
  57. package/{video-DF4MZ6J2.js → video-PEACIVNU.js} +4 -4
  58. package/{weather-PATAREUP.js → weather-4SC7E3OZ.js} +5 -5
  59. package/{web-GMBMMBHY.js → web-2O6V5RRP.js} +5 -5
  60. package/{web-search-SYJ7DI6M.js → web-search-KOU476ZM.js} +5 -5
  61. package/{whoami-KD3QSC6J.js → whoami-VGNKLROW.js} +7 -7
  62. package/{workflow-DATIF2MF.js → workflow-3GXAC4BP.js} +5 -5
  63. package/zero.js +43 -43
  64. package/chat-CRY62LOA.js +0 -246
  65. package/chat-CRY62LOA.js.map +0 -1
  66. package/chunk-2YJV4T5H.js.map +0 -1
  67. package/chunk-7JNLGFRW.js.map +0 -1
  68. package/esm-GOCEMHJO.js.map +0 -1
  69. package/resource-UCO5W2EM.js.map +0 -1
  70. /package/{agent-X6O3YR4M.js.map → agent-CDMQ3BO4.js.map} +0 -0
  71. /package/{banking-NGZXYSVB.js.map → banking-M5CIVLRH.js.map} +0 -0
  72. /package/{chunk-RMLNBK2X.js.map → chunk-7NYMO54N.js.map} +0 -0
  73. /package/{chunk-RANJI5FZ.js.map → chunk-BL37FBZF.js.map} +0 -0
  74. /package/{chunk-XM3WOXFE.js.map → chunk-BXVXXD3E.js.map} +0 -0
  75. /package/{chunk-LIT3JQQR.js.map → chunk-JXYKIW37.js.map} +0 -0
  76. /package/{chunk-2E37DQSD.js.map → chunk-TBBXBBFT.js.map} +0 -0
  77. /package/{chunk-FJFJLQQW.js.map → chunk-UUKFGXX5.js.map} +0 -0
  78. /package/{chunk-LO2JYFNP.js.map → chunk-XBX4JTXR.js.map} +0 -0
  79. /package/{computer-use-C3HZXTKZ.js.map → computer-use-K7ULCJNC.js.map} +0 -0
  80. /package/{connector-DPZKQG4U.js.map → connector-JFE4GTW4.js.map} +0 -0
  81. /package/{credit-WY6P3D6B.js.map → credit-QVY2XIPE.js.map} +0 -0
  82. /package/{developer-support-RYY76Y65.js.map → developer-support-EJOQWXKB.js.map} +0 -0
  83. /package/{doctor-XZH52P7J.js.map → doctor-7YEA3BYV.js.map} +0 -0
  84. /package/{feishu-HLSIBEHH.js.map → feishu-KCN4UME3.js.map} +0 -0
  85. /package/{finance-IWVIYPXL.js.map → finance-TOKK5DCK.js.map} +0 -0
  86. /package/{generate-IAA656VE.js.map → generate-6E23MDCE.js.map} +0 -0
  87. /package/{github-MJZJ2VLC.js.map → github-LJMT5D7D.js.map} +0 -0
  88. /package/{goal-7OCVIFTQ.js.map → goal-OJ4J7OCD.js.map} +0 -0
  89. /package/{host-KX7NPRZM.js.map → host-KX5G666N.js.map} +0 -0
  90. /package/{mail-D3YBSKA6.js.map → mail-U6JQDKN3.js.map} +0 -0
  91. /package/{maps-AT7I4KK6.js.map → maps-Y7PIXKLP.js.map} +0 -0
  92. /package/{model-7AEJV5QI.js.map → model-PXWGKXUA.js.map} +0 -0
  93. /package/{model-provider-CNTRAXGR.js.map → model-provider-LNVO4LHA.js.map} +0 -0
  94. /package/{org-4EOIMAMU.js.map → org-G46VCLIF.js.map} +0 -0
  95. /package/{people-search-YIPV2HRX.js.map → people-search-TZBJNLYY.js.map} +0 -0
  96. /package/{phone-RGFGHH4G.js.map → phone-KEHX5BEJ.js.map} +0 -0
  97. /package/{preference-UIFDOWCE.js.map → preference-5KLKA6DR.js.map} +0 -0
  98. /package/{scrape-V6KXL77N.js.map → scrape-27OBJPNR.js.map} +0 -0
  99. /package/{secret-ZOUQEPTX.js.map → secret-IRLST7ZX.js.map} +0 -0
  100. /package/{slack-4WKWNC54.js.map → slack-U3YX4HK7.js.map} +0 -0
  101. /package/{teams-MRN5OZEA.js.map → teams-2BPJ3VT4.js.map} +0 -0
  102. /package/{telegram-DJ6DOWYM.js.map → telegram-B7JBB6M2.js.map} +0 -0
  103. /package/{upgrade-2VYHUARI.js.map → upgrade-SFFQF2QF.js.map} +0 -0
  104. /package/{variable-6SNXAUY7.js.map → variable-ZZ7OX5PU.js.map} +0 -0
  105. /package/{video-DF4MZ6J2.js.map → video-PEACIVNU.js.map} +0 -0
  106. /package/{weather-PATAREUP.js.map → weather-4SC7E3OZ.js.map} +0 -0
  107. /package/{web-GMBMMBHY.js.map → web-2O6V5RRP.js.map} +0 -0
  108. /package/{web-search-SYJ7DI6M.js.map → web-search-KOU476ZM.js.map} +0 -0
  109. /package/{whoami-KD3QSC6J.js.map → whoami-VGNKLROW.js.map} +0 -0
  110. /package/{workflow-DATIF2MF.js.map → workflow-3GXAC4BP.js.map} +0 -0
@@ -4,14 +4,14 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  loadConnectorPermissionInfos,
6
6
  policyIcon
7
- } from "./chunk-XM3WOXFE.js";
7
+ } from "./chunk-BXVXXD3E.js";
8
8
  import {
9
9
  isInteractive,
10
10
  promptConfirm
11
11
  } from "./chunk-X2545RBX.js";
12
12
  import {
13
13
  permissionGrantsToFirewallPolicies
14
- } from "./chunk-RMLNBK2X.js";
14
+ } from "./chunk-7NYMO54N.js";
15
15
  import {
16
16
  createZeroAgent,
17
17
  deleteZeroAgent,
@@ -23,14 +23,14 @@ import {
23
23
  listZeroUserPermissionGrants,
24
24
  updateZeroAgent,
25
25
  updateZeroAgentInstructions
26
- } from "./chunk-2YJV4T5H.js";
27
- import "./chunk-2E37DQSD.js";
26
+ } from "./chunk-R23NULE7.js";
27
+ import "./chunk-TBBXBBFT.js";
28
28
  import "./chunk-SB7EZ2ZO.js";
29
29
  import {
30
30
  source_default,
31
31
  withErrorHandler
32
- } from "./chunk-7YTIE7KU.js";
33
- import "./chunk-KMRZUQHC.js";
32
+ } from "./chunk-5QLT6M5N.js";
33
+ import "./chunk-D4OTAABD.js";
34
34
  import {
35
35
  Command
36
36
  } from "./chunk-LD4ZVU4O.js";
@@ -594,4 +594,4 @@ Notes:
594
594
  export {
595
595
  zeroAgentCommand
596
596
  };
597
- //# sourceMappingURL=agent-X6O3YR4M.js.map
597
+ //# sourceMappingURL=agent-CDMQ3BO4.js.map
@@ -3,14 +3,14 @@ import { createRequire as __createRequire } from "node:module";
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  callZeroBanking
6
- } from "./chunk-2YJV4T5H.js";
7
- import "./chunk-2E37DQSD.js";
6
+ } from "./chunk-R23NULE7.js";
7
+ import "./chunk-TBBXBBFT.js";
8
8
  import "./chunk-SB7EZ2ZO.js";
9
9
  import {
10
10
  source_default,
11
11
  withErrorHandler
12
- } from "./chunk-7YTIE7KU.js";
13
- import "./chunk-KMRZUQHC.js";
12
+ } from "./chunk-5QLT6M5N.js";
13
+ import "./chunk-D4OTAABD.js";
14
14
  import {
15
15
  Command,
16
16
  InvalidArgumentError
@@ -114,4 +114,4 @@ Notes:
114
114
  export {
115
115
  zeroBankingCommand
116
116
  };
117
- //# sourceMappingURL=banking-NGZXYSVB.js.map
117
+ //# sourceMappingURL=banking-M5CIVLRH.js.map
@@ -0,0 +1,622 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __createRequire } from "node:module";
3
+ const require = __createRequire(import.meta.url);
4
+ import {
5
+ formatIsoTimestamp,
6
+ isUuid,
7
+ parseBoundedLogCount
8
+ } from "./chunk-B6ELBBRJ.js";
9
+ import {
10
+ formatModelProviderRoute
11
+ } from "./chunk-JXYKIW37.js";
12
+ import {
13
+ chatThreadEventSchema,
14
+ chatThreadSnapshotProjectionSchema,
15
+ getZeroChatThread,
16
+ getZeroChatThreadSnapshot,
17
+ listZeroChatThreadEvents,
18
+ listZeroModelPolicies,
19
+ renameZeroChatThread,
20
+ updateZeroChatThreadModelSelection
21
+ } from "./chunk-R23NULE7.js";
22
+ import "./chunk-TBBXBBFT.js";
23
+ import "./chunk-SB7EZ2ZO.js";
24
+ import {
25
+ getApiUrl,
26
+ source_default,
27
+ withErrorHandler
28
+ } from "./chunk-5QLT6M5N.js";
29
+ import {
30
+ decodeZeroTokenPayload
31
+ } from "./chunk-D4OTAABD.js";
32
+ import {
33
+ Command
34
+ } from "./chunk-LD4ZVU4O.js";
35
+ import {
36
+ init_esm_shims
37
+ } from "./chunk-3VVCUQPB.js";
38
+
39
+ // src/commands/zero/chat/index.ts
40
+ init_esm_shims();
41
+
42
+ // src/commands/zero/chat/get.ts
43
+ init_esm_shims();
44
+ function getCurrentChatThreadId() {
45
+ return process.env.ZERO_CHAT_THREAD_ID?.trim() || void 0;
46
+ }
47
+ function printUsageError(message, hint) {
48
+ console.error(source_default.red(`\u2717 ${message}`));
49
+ console.error(source_default.dim(` ${hint}`));
50
+ process.exit(1);
51
+ }
52
+ var getCommand = new Command().name("get").description("Show the current web chat thread").option("--json", "Print machine-readable JSON").addHelpText(
53
+ "after",
54
+ `
55
+ Examples:
56
+ Show this chat: zero chat get
57
+ Print JSON: zero chat get --json
58
+
59
+ Notes:
60
+ - Uses ZERO_CHAT_THREAD_ID from the current web chat thread
61
+ - Authenticates via ZERO_TOKEN (requires chat-thread:read capability)`
62
+ ).action(
63
+ withErrorHandler(async (options) => {
64
+ const threadId = getCurrentChatThreadId();
65
+ if (!threadId) {
66
+ printUsageError(
67
+ "ZERO_CHAT_THREAD_ID is not set",
68
+ "Run this command from a Zero web chat thread."
69
+ );
70
+ }
71
+ const thread = await getZeroChatThread({ threadId });
72
+ if (options.json) {
73
+ console.log(JSON.stringify(thread));
74
+ return;
75
+ }
76
+ console.log(source_default.green("\u2713 Chat thread loaded"));
77
+ console.log(source_default.dim(` Thread: ${thread.id}`));
78
+ console.log(source_default.dim(` Title: ${thread.title ?? "(untitled)"}`));
79
+ console.log(
80
+ source_default.dim(` Model: ${thread.selectedModel ?? "(default)"}`)
81
+ );
82
+ })
83
+ );
84
+
85
+ // src/commands/zero/chat/list.ts
86
+ init_esm_shims();
87
+
88
+ // src/commands/zero/chat/chat-thread-cache.ts
89
+ init_esm_shims();
90
+ import { createHash, randomUUID } from "crypto";
91
+ import { mkdir, readFile, rename, rm, writeFile } from "fs/promises";
92
+ import { homedir } from "os";
93
+ import { dirname, join } from "path";
94
+
95
+ // ../../packages/core/src/chat-thread-event-replay.ts
96
+ init_esm_shims();
97
+ function compareThreadOrder(left, right) {
98
+ const leftPinned = left.pinnedAt !== null;
99
+ const rightPinned = right.pinnedAt !== null;
100
+ if (leftPinned !== rightPinned) {
101
+ return leftPinned ? -1 : 1;
102
+ }
103
+ const sortCompare = right.sortAt.localeCompare(left.sortAt);
104
+ if (sortCompare !== 0) {
105
+ return sortCompare;
106
+ }
107
+ return right.id.localeCompare(left.id);
108
+ }
109
+ function applyEvent(threads, event, pendingThreadUpdates) {
110
+ if (event.kind === "created") {
111
+ threads.set(event.chatThreadId, {
112
+ id: event.chatThreadId,
113
+ agentId: event.agentId,
114
+ title: event.title,
115
+ sortAt: event.createdAt,
116
+ createdAt: event.createdAt,
117
+ updatedAt: event.createdAt,
118
+ pinnedAt: null,
119
+ renamedAt: null,
120
+ selectedModel: event.selectedModel,
121
+ serviceTier: event.serviceTier,
122
+ computerUseHostId: event.computerUseHostId
123
+ });
124
+ const pendingUpdates = pendingThreadUpdates.get(event.chatThreadId) ?? [];
125
+ pendingThreadUpdates.delete(event.chatThreadId);
126
+ for (const pendingUpdate of pendingUpdates) {
127
+ if (pendingUpdate.createdAt.localeCompare(event.createdAt) >= 0) {
128
+ applyEvent(threads, pendingUpdate, pendingThreadUpdates);
129
+ }
130
+ }
131
+ return;
132
+ }
133
+ if (event.kind === "deleted") {
134
+ threads.delete(event.chatThreadId);
135
+ return;
136
+ }
137
+ const thread = threads.get(event.chatThreadId);
138
+ if (!thread) {
139
+ if (event.kind === "model_selection_updated" || event.kind === "service_tier_updated" || event.kind === "computer_use_host_updated") {
140
+ const pendingUpdates = pendingThreadUpdates.get(event.chatThreadId) ?? [];
141
+ pendingThreadUpdates.set(event.chatThreadId, [...pendingUpdates, event]);
142
+ }
143
+ return;
144
+ }
145
+ if (event.kind === "renamed") {
146
+ threads.set(event.chatThreadId, {
147
+ ...thread,
148
+ title: event.title,
149
+ renamedAt: event.createdAt,
150
+ updatedAt: event.createdAt
151
+ });
152
+ return;
153
+ }
154
+ if (event.kind === "pinned") {
155
+ threads.set(event.chatThreadId, {
156
+ ...thread,
157
+ pinnedAt: event.createdAt,
158
+ updatedAt: event.createdAt
159
+ });
160
+ return;
161
+ }
162
+ if (event.kind === "unpinned") {
163
+ threads.set(event.chatThreadId, {
164
+ ...thread,
165
+ pinnedAt: null,
166
+ updatedAt: event.createdAt
167
+ });
168
+ return;
169
+ }
170
+ if (event.kind === "model_selection_updated") {
171
+ threads.set(event.chatThreadId, {
172
+ ...thread,
173
+ selectedModel: event.selectedModel,
174
+ updatedAt: event.createdAt
175
+ });
176
+ return;
177
+ }
178
+ if (event.kind === "service_tier_updated") {
179
+ threads.set(event.chatThreadId, {
180
+ ...thread,
181
+ serviceTier: event.serviceTier,
182
+ updatedAt: event.createdAt
183
+ });
184
+ return;
185
+ }
186
+ if (event.kind === "computer_use_host_updated") {
187
+ threads.set(event.chatThreadId, {
188
+ ...thread,
189
+ computerUseHostId: event.computerUseHostId,
190
+ updatedAt: event.createdAt
191
+ });
192
+ return;
193
+ }
194
+ threads.set(event.chatThreadId, {
195
+ ...thread,
196
+ sortAt: event.createdAt
197
+ });
198
+ }
199
+ function replayChatThreadEvents(snapshot, events) {
200
+ const threads = /* @__PURE__ */ new Map();
201
+ for (const thread of snapshot) {
202
+ threads.set(thread.id, {
203
+ ...thread,
204
+ selectedModel: thread.selectedModel ?? null,
205
+ serviceTier: thread.serviceTier ?? null,
206
+ computerUseHostId: thread.computerUseHostId ?? null
207
+ });
208
+ }
209
+ const pendingThreadUpdates = /* @__PURE__ */ new Map();
210
+ for (const event of events) {
211
+ applyEvent(threads, event, pendingThreadUpdates);
212
+ }
213
+ return [...threads.values()].sort(compareThreadOrder);
214
+ }
215
+
216
+ // src/commands/zero/chat/chat-thread-cache.ts
217
+ var CACHE_VERSION = 1;
218
+ var MAX_EVENT_PAGES_PER_SYNC = 20;
219
+ function isRecord(value) {
220
+ return typeof value === "object" && value !== null;
221
+ }
222
+ function parseCache(raw) {
223
+ let value;
224
+ try {
225
+ value = JSON.parse(raw);
226
+ } catch (error) {
227
+ if (error instanceof SyntaxError) {
228
+ return null;
229
+ }
230
+ throw error;
231
+ }
232
+ if (!isRecord(value) || value.version !== CACHE_VERSION || !isRecord(value.snapshot)) {
233
+ return null;
234
+ }
235
+ const chatThreads = chatThreadSnapshotProjectionSchema.array().safeParse(value.snapshot.chatThreads);
236
+ const events = chatThreadEventSchema.array().safeParse(value.events);
237
+ const latestEventId2 = value.snapshot.latestEventId;
238
+ if (!chatThreads.success || !events.success || latestEventId2 !== null && typeof latestEventId2 !== "string") {
239
+ return null;
240
+ }
241
+ return {
242
+ version: CACHE_VERSION,
243
+ snapshot: {
244
+ chatThreads: chatThreads.data,
245
+ latestEventId: latestEventId2
246
+ },
247
+ events: events.data
248
+ };
249
+ }
250
+ function cacheRoot() {
251
+ return process.env.XDG_CACHE_HOME?.trim() || join(homedir(), ".cache");
252
+ }
253
+ async function cachePath() {
254
+ const token = decodeZeroTokenPayload();
255
+ if (!token) {
256
+ throw new Error("ZERO_TOKEN does not contain a valid Zero cache scope");
257
+ }
258
+ const apiUrl = await getApiUrl();
259
+ const scope = createHash("sha256").update(`${apiUrl}\0${token.orgId}\0${token.userId}`).digest("hex");
260
+ return join(cacheRoot(), "vm0", "zero", "chat-threads", `${scope}.json`);
261
+ }
262
+ function isNodeError(error) {
263
+ return error instanceof Error && "code" in error;
264
+ }
265
+ async function readCache(path) {
266
+ let raw;
267
+ try {
268
+ raw = await readFile(path, "utf8");
269
+ } catch (error) {
270
+ if (isNodeError(error) && error.code === "ENOENT") {
271
+ return null;
272
+ }
273
+ throw error;
274
+ }
275
+ return parseCache(raw);
276
+ }
277
+ async function writeCache(path, cache) {
278
+ await mkdir(dirname(path), { recursive: true, mode: 448 });
279
+ const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
280
+ try {
281
+ await writeFile(temporaryPath, `${JSON.stringify(cache)}
282
+ `, {
283
+ encoding: "utf8",
284
+ flag: "wx",
285
+ mode: 384
286
+ });
287
+ await rename(temporaryPath, path);
288
+ } finally {
289
+ await rm(temporaryPath, { force: true });
290
+ }
291
+ }
292
+ function mergeEvents(existing, incoming) {
293
+ const byId = /* @__PURE__ */ new Map();
294
+ for (const event of existing) {
295
+ byId.set(event.id, event);
296
+ }
297
+ for (const event of incoming) {
298
+ byId.set(event.id, event);
299
+ }
300
+ return [...byId.values()].sort((left, right) => {
301
+ const timeCompare = left.createdAt.localeCompare(right.createdAt);
302
+ return timeCompare !== 0 ? timeCompare : left.id.localeCompare(right.id);
303
+ });
304
+ }
305
+ async function freshCache() {
306
+ return {
307
+ version: CACHE_VERSION,
308
+ snapshot: await getZeroChatThreadSnapshot(),
309
+ events: []
310
+ };
311
+ }
312
+ function latestEventId(cache) {
313
+ return cache.events.at(-1)?.id ?? cache.snapshot.latestEventId ?? void 0;
314
+ }
315
+ async function syncCachedChatThreads() {
316
+ const path = await cachePath();
317
+ let cache = await readCache(path) ?? await freshCache();
318
+ let cursor = latestEventId(cache);
319
+ for (let page = 0; page < MAX_EVENT_PAGES_PER_SYNC; page++) {
320
+ const result = await listZeroChatThreadEvents({
321
+ sinceEventId: cursor
322
+ });
323
+ if (result.kind === "expired") {
324
+ cache = await freshCache();
325
+ cursor = latestEventId(cache);
326
+ continue;
327
+ }
328
+ if (result.events.length > 0) {
329
+ cache = {
330
+ ...cache,
331
+ events: mergeEvents(cache.events, result.events)
332
+ };
333
+ const lastEvent = result.events.at(-1);
334
+ if (lastEvent) {
335
+ cursor = lastEvent.id;
336
+ }
337
+ }
338
+ if (!result.hasMore || result.events.length === 0) {
339
+ break;
340
+ }
341
+ }
342
+ await writeCache(path, cache);
343
+ return replayChatThreadEvents(cache.snapshot.chatThreads, cache.events);
344
+ }
345
+
346
+ // src/commands/zero/chat/list.ts
347
+ var DEFAULT_LIMIT = 20;
348
+ var MAX_LIMIT = 100;
349
+ function printUsageError2(message, hint) {
350
+ console.error(source_default.red(`\u2717 ${message}`));
351
+ console.error(source_default.dim(` ${hint}`));
352
+ process.exit(1);
353
+ }
354
+ function resolveAgentId(flagAgentId) {
355
+ const agentId = flagAgentId?.trim() || process.env.ZERO_AGENT_ID?.trim();
356
+ if (!agentId) {
357
+ printUsageError2(
358
+ "ZERO_AGENT_ID is not set",
359
+ "Pass --agent <agent-id> or run inside an agent sandbox."
360
+ );
361
+ }
362
+ if (!isUuid(agentId)) {
363
+ printUsageError2(
364
+ `Invalid agent ID "${agentId}" \u2014 expected a UUID`,
365
+ "Pass a valid UUID with --agent <agent-id>."
366
+ );
367
+ }
368
+ return agentId;
369
+ }
370
+ function titleForDisplay(title) {
371
+ return (title ?? "(untitled)").replace(/\s+/g, " ");
372
+ }
373
+ var listCommand = new Command().name("list").alias("ls").description("List web chat threads for an agent").option("--agent <id>", "Filter by Zero agent ID (defaults to ZERO_AGENT_ID)").option(
374
+ "--limit <n>",
375
+ `Maximum number of threads to print (default: ${DEFAULT_LIMIT}, max: ${MAX_LIMIT})`
376
+ ).option("--json", "Print machine-readable JSON").addHelpText(
377
+ "after",
378
+ `
379
+ Examples:
380
+ List this agent's chats: zero chat list
381
+ List another agent: zero chat list --agent <agent-id>
382
+ Limit the output: zero chat list --limit 10
383
+ Print JSON: zero chat list --json
384
+
385
+ Notes:
386
+ - Defaults --agent to ZERO_AGENT_ID
387
+ - Authenticates via ZERO_TOKEN (requires chat-thread:read capability)
388
+ - Replays cached snapshot and incremental chat thread events`
389
+ ).action(
390
+ withErrorHandler(async (options) => {
391
+ const agentId = resolveAgentId(options.agent);
392
+ const limit = options.limit === void 0 ? DEFAULT_LIMIT : parseBoundedLogCount(options.limit, "--limit", 1, MAX_LIMIT);
393
+ const allThreads = await syncCachedChatThreads();
394
+ const matchingThreads = allThreads.filter((thread) => {
395
+ return thread.agentId === agentId;
396
+ });
397
+ const threads = matchingThreads.slice(0, limit);
398
+ if (options.json) {
399
+ console.log(
400
+ JSON.stringify({
401
+ agentId,
402
+ total: matchingThreads.length,
403
+ threads
404
+ })
405
+ );
406
+ return;
407
+ }
408
+ if (threads.length === 0) {
409
+ console.log(source_default.dim("No chat threads found"));
410
+ return;
411
+ }
412
+ const header = [
413
+ "THREAD ID".padEnd(38),
414
+ "SORTED".padEnd(20),
415
+ "PINNED".padEnd(6),
416
+ "TITLE"
417
+ ].join(" ");
418
+ console.log(source_default.dim(header));
419
+ for (const thread of threads) {
420
+ console.log(
421
+ [
422
+ thread.id.padEnd(38),
423
+ formatIsoTimestamp(thread.sortAt).padEnd(20),
424
+ (thread.pinnedAt === null ? "-" : "yes").padEnd(6),
425
+ titleForDisplay(thread.title)
426
+ ].join(" ")
427
+ );
428
+ }
429
+ if (threads.length < matchingThreads.length) {
430
+ console.log();
431
+ console.log(
432
+ source_default.dim(
433
+ ` Showing ${threads.length} of ${matchingThreads.length} threads. Use --limit to adjust.`
434
+ )
435
+ );
436
+ }
437
+ })
438
+ );
439
+
440
+ // src/commands/zero/chat/model.ts
441
+ init_esm_shims();
442
+ function getCurrentChatThreadId2() {
443
+ return process.env.ZERO_CHAT_THREAD_ID?.trim() || void 0;
444
+ }
445
+ function printUsageError3(message, hint) {
446
+ console.error(source_default.red(`\u2717 ${message}`));
447
+ console.error(source_default.dim(` ${hint}`));
448
+ process.exit(1);
449
+ }
450
+ function switchablePolicies(policies) {
451
+ return policies.filter((policy) => {
452
+ return policy.routeStatus === "valid";
453
+ });
454
+ }
455
+ function formatModelName(policy) {
456
+ return `${policy.modelLabel} ${source_default.dim(`(${policy.model})`)}`;
457
+ }
458
+ function printSwitchableModels(policies) {
459
+ const switchable = switchablePolicies(policies);
460
+ if (switchable.length === 0) {
461
+ console.log(source_default.dim("No switchable models are available for this user"));
462
+ return;
463
+ }
464
+ for (const policy of switchable) {
465
+ const defaultMarker = policy.isDefault ? source_default.dim(" (default)") : "";
466
+ console.log(` - ${formatModelName(policy)}${defaultMarker}`);
467
+ console.log(` provider: ${formatModelProviderRoute(policy)}`);
468
+ }
469
+ }
470
+ function printCurrentModel(thread) {
471
+ console.log(source_default.green("\u2713 Chat thread loaded"));
472
+ console.log(source_default.dim(` Thread: ${thread.id}`));
473
+ console.log(source_default.dim(` Title: ${thread.title ?? "(untitled)"}`));
474
+ console.log(source_default.dim(` Model: ${thread.selectedModel ?? "(default)"}`));
475
+ }
476
+ async function printModelHelp(command) {
477
+ const result = await listZeroModelPolicies();
478
+ console.log(command.helpInformation().trimEnd());
479
+ console.log();
480
+ console.log(source_default.bold("Switchable models:"));
481
+ printSwitchableModels(result.policies);
482
+ console.log();
483
+ console.log("Use the model id in parentheses:");
484
+ console.log(source_default.cyan(" zero chat model <model>"));
485
+ }
486
+ async function printCurrentModelAndChoices(threadId) {
487
+ const [thread, result] = await Promise.all([
488
+ getZeroChatThread({ threadId }),
489
+ listZeroModelPolicies()
490
+ ]);
491
+ printCurrentModel(thread);
492
+ console.log();
493
+ console.log(source_default.bold("Switchable models:"));
494
+ printSwitchableModels(result.policies);
495
+ console.log();
496
+ console.log("Switch models:");
497
+ console.log(source_default.cyan(" zero chat model <model>"));
498
+ }
499
+ async function switchModel(threadId, model) {
500
+ const result = await listZeroModelPolicies();
501
+ const policy = result.policies.find((candidate) => {
502
+ return candidate.model === model;
503
+ });
504
+ if (!policy) {
505
+ printUsageError3(`Unknown model: ${model}`, "Run: zero chat model --help");
506
+ }
507
+ if (policy.routeStatus !== "valid") {
508
+ const reason = policy.routeStatusReason ? ` (${policy.routeStatusReason})` : "";
509
+ printUsageError3(
510
+ `Model is not switchable: ${model}${reason}`,
511
+ "Run: zero chat model --help"
512
+ );
513
+ }
514
+ const updated = await updateZeroChatThreadModelSelection({
515
+ threadId,
516
+ model
517
+ });
518
+ console.log(source_default.green("\u2713 Chat model updated"));
519
+ console.log(source_default.dim(` Thread: ${updated.threadId}`));
520
+ console.log(source_default.dim(` Model: ${policy.modelLabel} (${model})`));
521
+ }
522
+ var modelCommand = new Command().name("model").description("Show or switch the current web chat thread model").argument("[model]", "Model id to use for this chat thread").helpOption(false).option("-h, --help", "Show help with switchable models").addHelpText(
523
+ "after",
524
+ `
525
+ Examples:
526
+ Show this chat model: zero chat model
527
+ Switch this model: zero chat model claude-sonnet-5
528
+
529
+ Notes:
530
+ - Uses ZERO_CHAT_THREAD_ID from the current web chat thread
531
+ - Authenticates via ZERO_TOKEN (requires chat-thread:write capability to switch)`
532
+ ).action(
533
+ withErrorHandler(
534
+ async (model, options) => {
535
+ if (options.help) {
536
+ await printModelHelp(modelCommand);
537
+ return;
538
+ }
539
+ const threadId = getCurrentChatThreadId2();
540
+ if (!threadId) {
541
+ printUsageError3(
542
+ "ZERO_CHAT_THREAD_ID is not set",
543
+ "Run this command from a Zero web chat thread."
544
+ );
545
+ }
546
+ if (!model) {
547
+ await printCurrentModelAndChoices(threadId);
548
+ return;
549
+ }
550
+ await switchModel(threadId, model);
551
+ }
552
+ )
553
+ );
554
+
555
+ // src/commands/zero/chat/rename.ts
556
+ init_esm_shims();
557
+ function getCurrentChatThreadId3() {
558
+ return process.env.ZERO_CHAT_THREAD_ID?.trim() || void 0;
559
+ }
560
+ function printUsageError4(message, hint) {
561
+ console.error(source_default.red(`\u2717 ${message}`));
562
+ console.error(source_default.dim(` ${hint}`));
563
+ process.exit(1);
564
+ }
565
+ var renameCommand = new Command().name("rename").description("Rename a web chat thread").argument("<title...>", "New chat title").option("--thread <id>", "Chat thread ID (defaults to ZERO_CHAT_THREAD_ID)").option("--json", "Print machine-readable JSON").addHelpText(
566
+ "after",
567
+ `
568
+ Examples:
569
+ Rename this chat: zero chat rename "Launch plan"
570
+ Rename another: zero chat rename --thread <thread-id> "Launch plan"
571
+
572
+ Notes:
573
+ - Defaults --thread to ZERO_CHAT_THREAD_ID
574
+ - Authenticates via ZERO_TOKEN (requires chat-thread:write capability)`
575
+ ).action(
576
+ withErrorHandler(async (titleParts, options) => {
577
+ const title = titleParts.join(" ").trim();
578
+ if (!title) {
579
+ printUsageError4(
580
+ "Title is required",
581
+ 'Run: zero chat rename "New title"'
582
+ );
583
+ }
584
+ const threadId = options.thread?.trim() || getCurrentChatThreadId3();
585
+ if (!threadId) {
586
+ printUsageError4(
587
+ "ZERO_CHAT_THREAD_ID is not set",
588
+ "Pass --thread <thread-id> or run inside a Zero web chat thread."
589
+ );
590
+ }
591
+ if (!isUuid(threadId)) {
592
+ printUsageError4(
593
+ `Invalid thread ID "${threadId}" \u2014 expected a UUID`,
594
+ "Pass a valid UUID with --thread <thread-id>."
595
+ );
596
+ }
597
+ const result = await renameZeroChatThread({ threadId, title });
598
+ if (options.json) {
599
+ console.log(JSON.stringify(result));
600
+ return;
601
+ }
602
+ console.log(source_default.green("\u2713 Chat title updated"));
603
+ console.log(source_default.dim(` Thread: ${result.threadId}`));
604
+ console.log(source_default.dim(` Title: ${result.title}`));
605
+ })
606
+ );
607
+
608
+ // src/commands/zero/chat/index.ts
609
+ var zeroChatCommand = new Command().name("chat").description("Manage web chat threads").addCommand(getCommand).addCommand(listCommand).addCommand(modelCommand).addCommand(renameCommand).addHelpText(
610
+ "after",
611
+ `
612
+ Examples:
613
+ List agent chats: zero chat list
614
+ Show this chat: zero chat get
615
+ Switch model: zero chat model claude-sonnet-5
616
+ Rename this chat: zero chat rename "Launch plan"
617
+ Rename another: zero chat rename --thread <thread-id> "Launch plan"`
618
+ );
619
+ export {
620
+ zeroChatCommand
621
+ };
622
+ //# sourceMappingURL=chat-TRK5KDSP.js.map