nolo-cli 0.38.0-alpha.3 → 0.47.0-alpha.2

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 (134) hide show
  1. package/{_executeModel-SWONBJ7Z.js → _executeModel-5PG6CUWD.js} +41 -42
  2. package/{action-KMBZ3LCZ.js → action-FLLC2SIX.js} +7 -7
  3. package/{addContentAction-KQ44UT2U.js → addContentAction-SVSPUUK4.js} +6 -6
  4. package/{addDialogAgentAction-ILSDCMYL.js → addDialogAgentAction-W3JGU4F7.js} +5 -5
  5. package/{agentDeleteCommand-SMUJYI6N.js → agentDeleteCommand-SHSPQZHI.js} +25 -26
  6. package/{agentEmailCommands-YWCGZ4RO.js → agentEmailCommands-LQKO5GRW.js} +54 -55
  7. package/{agentListCommands-ULFV2XJQ.js → agentListCommands-5QTNEYMQ.js} +31 -29
  8. package/{agentMachineCommands-7YZ2TIYZ.js → agentMachineCommands-P5K454CN.js} +24 -25
  9. package/{agentPullCommand-TSWAJPS2.js → agentPullCommand-M552CYSI.js} +2 -2
  10. package/{agentRecordCommands-EVOSSHJR.js → agentRecordCommands-Z4QYCNP4.js} +50 -51
  11. package/{agentRunCommand-PO55WUIY.js → agentRunCommand-HV3Y34B5.js} +52 -53
  12. package/{agentRunControl-7MUPSYDQ.js → agentRunControl-LHXOP4IU.js} +43 -1
  13. package/{agentRuntimeLocal-Q6D3G6G7.js → agentRuntimeLocal-ZKXYFLXI.js} +20 -21
  14. package/{agentSlice-6TRUUOSX.js → agentSlice-NKFLP3RI.js} +6 -6
  15. package/{agentSuperviseCommands-MKWW3ICX.js → agentSuperviseCommands-IMRZ56RC.js} +2 -2
  16. package/{appDeleteCommands-JDBSRLTX.js → appDeleteCommands-XYGAZIJX.js} +24 -25
  17. package/{appDeployCommands-Q5H2NBKQ.js → appDeployCommands-7T5CABRB.js} +24 -25
  18. package/{appDeployStatusCommands-PSYBUIZT.js → appDeployStatusCommands-KTFQMRPZ.js} +24 -25
  19. package/{appGetCommands-IX64IUW6.js → appGetCommands-HOX2ULSV.js} +24 -25
  20. package/{appListCommands-BJZFX65H.js → appListCommands-3SLCEHND.js} +24 -25
  21. package/{authCommand-B2XRHNJH.js → authCommand-OY2E2VQK.js} +12 -12
  22. package/{authCommands-GWABTFMR.js → authCommands-SBQVTD6V.js} +5 -5
  23. package/{chatQueueReduxAdapter-N7Z5MUPU.js → chatQueueReduxAdapter-WMMBQK3Y.js} +20 -20
  24. package/chunk-25J3BB35.js +6041 -0
  25. package/{chunk-U6QQLXWI.js → chunk-2X5S4IBZ.js} +1 -1
  26. package/{chunk-MJWX4JQO.js → chunk-3EEK7T3D.js} +1 -1
  27. package/{chunk-UNHKVD2N.js → chunk-43CXXVJD.js} +1 -1
  28. package/{chunk-WRP5TTM6.js → chunk-4MXGXSYN.js} +83 -3
  29. package/{chunk-7N7XKGEQ.js → chunk-4ZNDBDWG.js} +6 -6
  30. package/{chunk-XVVNNJAA.js → chunk-5BPZLBFB.js} +20 -51
  31. package/{chunk-MWGCZ4CS.js → chunk-5PPFYHU2.js} +3 -3
  32. package/{chunk-W445DPVT.js → chunk-5QRCPERU.js} +1 -1
  33. package/{chunk-GKHV4UH5.js → chunk-5UOBIU5G.js} +31 -3
  34. package/{chunk-BMB563Y6.js → chunk-6BYAXNH5.js} +3 -3
  35. package/{chunk-SMPAUSX5.js → chunk-6FGXGFAH.js} +2 -2
  36. package/{chunk-46VPXYIV.js → chunk-6LYUN76O.js} +5 -5
  37. package/{chunk-FTM4KUOZ.js → chunk-7XTC3KRG.js} +1 -1
  38. package/{chunk-IMHO5LC6.js → chunk-7XZ5GXSN.js} +1 -1
  39. package/{chunk-E2OQ5N2F.js → chunk-AEXP2UZT.js} +341 -16
  40. package/{chunk-MZZZYUZS.js → chunk-AV2CELZZ.js} +37 -12
  41. package/{chunk-JI2TIPLP.js → chunk-AYXSUBVC.js} +1 -1
  42. package/{chunk-J6WH4PYZ.js → chunk-CIF4X6ZM.js} +1 -1
  43. package/{chunk-GZRMWK5R.js → chunk-DQLYEGP7.js} +2 -2
  44. package/{chunk-GUYMR3JL.js → chunk-E2QH2AYX.js} +69 -3
  45. package/{chunk-B6H5XCT2.js → chunk-EMEUU5IY.js} +3 -3
  46. package/{chunk-X6EN3KJX.js → chunk-ENYDQKOB.js} +319 -71
  47. package/{chunk-RCFIB45Q.js → chunk-EVBFYPDC.js} +2 -2
  48. package/{chunk-PV734VZX.js → chunk-EXLOROHG.js} +1 -1
  49. package/{chunk-WRN7L5CS.js → chunk-FA4SY4F5.js} +1 -1
  50. package/{chunk-4WVNHL3V.js → chunk-FAWK6DBF.js} +157 -51
  51. package/{chunk-IFS5CUEH.js → chunk-FJHLA6SX.js} +1 -1
  52. package/{chunk-T2BZICLK.js → chunk-G46DB6KG.js} +49 -6
  53. package/{chunk-FGLKRJDI.js → chunk-GK74OOFT.js} +2 -2
  54. package/{chunk-LM6IYQ3F.js → chunk-GLKOYSRU.js} +8 -1
  55. package/{chunk-JIADXJYU.js → chunk-H2G6JXTR.js} +1 -1
  56. package/{chunk-IKGHZMK2.js → chunk-H2JQB6B6.js} +12 -12
  57. package/{chunk-MGIHZ5CJ.js → chunk-HAPCUPEO.js} +2 -2
  58. package/{chunk-LD6Y6RJY.js → chunk-HGDOIDQ4.js} +2 -2
  59. package/{chunk-NZLQ7B5P.js → chunk-HOM6NILS.js} +3 -3
  60. package/{chunk-IZNJDUJ4.js → chunk-I4JISVWK.js} +1 -1
  61. package/{chunk-N4XRDM26.js → chunk-IA3A5373.js} +2 -2
  62. package/{chunk-Y5MMUI3L.js → chunk-IWUPQUWA.js} +2 -2
  63. package/{chunk-L7SMDIL6.js → chunk-JEGPB5H2.js} +3 -3
  64. package/{chunk-GEPHJJW4.js → chunk-L7NG2M6H.js} +1 -1
  65. package/{chunk-XQES6LXQ.js → chunk-LFLWZX76.js} +2 -2
  66. package/{chunk-IIOHYLIG.js → chunk-LGUQHYAL.js} +1 -1
  67. package/{chunk-4AWH4LQA.js → chunk-LYGNQHUW.js} +3 -1
  68. package/{db-3H3JECGY.js → chunk-M5PVFLD4.js} +11 -158
  69. package/{chunk-WN5AJG5I.js → chunk-MKZRKDQM.js} +1 -1
  70. package/{chunk-VOXNBPLB.js → chunk-MUIJYGYW.js} +649 -41
  71. package/{chunk-CYAC5WXX.js → chunk-MWT2BBCH.js} +213 -45
  72. package/{chunk-V5GA74HI.js → chunk-MZXZJVVD.js} +20 -39
  73. package/{chunk-ZBB3MZR3.js → chunk-OLNC7AWK.js} +7 -4
  74. package/{chunk-J5NMOM35.js → chunk-OYNDYVSE.js} +1 -1
  75. package/{chunk-C6ELZQ7H.js → chunk-OZVGA4SY.js} +1 -1
  76. package/{chunk-K4KIFRIN.js → chunk-Q24S4NDF.js} +1 -1
  77. package/{chunk-NRROOY22.js → chunk-Q6DMA2OM.js} +271 -130
  78. package/{chunk-2WKUUY2E.js → chunk-SVEUG45B.js} +5 -3
  79. package/{chunk-IZCHPD7T.js → chunk-TNPCQNGQ.js} +11 -6
  80. package/{chunk-4DMPISV6.js → chunk-URBGEE42.js} +2 -2
  81. package/{chunk-2KO5QQFV.js → chunk-V2IPBG5U.js} +1 -1
  82. package/{chunk-B6YYACBT.js → chunk-WPFNAEIW.js} +1 -1
  83. package/{chunk-23KKIMD5.js → chunk-WVGEBWA6.js} +4 -4
  84. package/{chunk-KU6CDTZ5.js → chunk-XMI3APSU.js} +61 -49
  85. package/{chunk-64KIQZA2.js → chunk-XO3G35OV.js} +1 -1
  86. package/{chunk-UWGWUOVN.js → chunk-YNOGNUBC.js} +108 -47
  87. package/{chunk-XT73C4VH.js → chunk-Z5NW3O7V.js} +1 -1
  88. package/{codingSkills-H6N5EKSX.js → codingSkills-BYQI6EPT.js} +2 -2
  89. package/{createAgentAutomationAction-U57ZMPMS.js → createAgentAutomationAction-ENDNA3Q4.js} +21 -21
  90. package/{createDialogAction-MAJLBNK4.js → createDialogAction-2KNX6S2D.js} +23 -23
  91. package/{createPageAction-4EX7HU6G.js → createPageAction-SNBCYPK6.js} +21 -21
  92. package/db-VQSAOWAO.js +162 -0
  93. package/{dbSlice-PIQGICNM.js → dbSlice-XWUM4QOF.js} +5 -5
  94. package/deleteFile-NPZ64DFN.js +1 -1
  95. package/{dialogCommands-4MHZXEIS.js → dialogCommands-6E5P35DG.js} +28 -26
  96. package/{dialogSlice-AL3UJLOJ.js → dialogSlice-RTPOD6EW.js} +20 -20
  97. package/{docCreateCommands-GDYFEK67.js → docCreateCommands-JWY25UFB.js} +23 -24
  98. package/{docDeleteCommands-WIE5CXED.js → docDeleteCommands-BPJOCSX4.js} +24 -25
  99. package/{docReadCommands-LTOOPJVC.js → docReadCommands-BSEZCYTQ.js} +23 -24
  100. package/{docStore-35B5VAFF.js → docStore-TYHVLU7G.js} +22 -22
  101. package/{docUpdateCommands-TZGAGXSG.js → docUpdateCommands-S2IE2VV4.js} +23 -24
  102. package/{fetchMessages-CUEFN4GQ.js → fetchMessages-KZQVBXKY.js} +3 -3
  103. package/{getPricing-P3E2WRIH.js → getPricing-X3HXP6VQ.js} +3 -3
  104. package/{handleSendMessageAction-PXX2R5JS.js → handleSendMessageAction-QYXDQXGH.js} +21 -21
  105. package/index.js +69 -69
  106. package/levelLazyShim-GZBKODGI.js +7 -0
  107. package/{localDialogRead-P7CHFMIC.js → localDialogRead-NQ33HBSI.js} +2 -2
  108. package/{localRuntimeAuthority-S77B5QVB.js → localRuntimeAuthority-KQDAE64E.js} +4 -4
  109. package/{localRuntimeDb-N3H3HQ7G.js → localRuntimeDb-PF7CFKDL.js} +2 -2
  110. package/{machineCommands-VCPPY23X.js → machineCommands-QCE4KLGR.js} +48 -49
  111. package/{machineWsRunDispatch-A4C727GL.js → machineWsRunDispatch-FBRMGU5D.js} +48 -49
  112. package/{models-L7S2EKPM.js → models-7LWATQFH.js} +2 -2
  113. package/package.json +1 -1
  114. package/{read-6C2XD3YZ.js → read-DQQ75VI3.js} +2 -2
  115. package/{readDocTool-Y7AB365O.js → readDocTool-HCQQFAZD.js} +1 -1
  116. package/{readlineWorkspace-BIBIM6DG.js → readlineWorkspace-2TACWKMN.js} +164 -78
  117. package/{removeDialogAgentAction-KG5WMJRZ.js → removeDialogAgentAction-DNONRKST.js} +7 -7
  118. package/{runAgentClientLoop-RKDXMIZW.js → runAgentClientLoop-GBLDVBT5.js} +39 -39
  119. package/{runtimeDoctorCommands-HT4O2PXL.js → runtimeDoctorCommands-JKTTN723.js} +4 -4
  120. package/serverStoreFactory-YMXDF4NI.js +20 -0
  121. package/{setDialogExtraReferencesAction-O2NLXMSM.js → setDialogExtraReferencesAction-ERHUPT3F.js} +6 -6
  122. package/{setPrimaryDialogAgentAction-FYYUY7PB.js → setPrimaryDialogAgentAction-6C2HYNEC.js} +7 -7
  123. package/{settingSlice-GPLI6E3M.js → settingSlice-YVRJFKQX.js} +6 -6
  124. package/{spaceCommands-4FMO3SNP.js → spaceCommands-XOLPJMRK.js} +23 -24
  125. package/{spaceSlice-2W4GJ2OE.js → spaceSlice-OQPAGQDP.js} +21 -21
  126. package/{streamAgentChatTurn-FS52LDQP.js → streamAgentChatTurn-SN5XJJ7U.js} +91 -49
  127. package/{switchDialogAgentAction-GH5P6Q3Z.js → switchDialogAgentAction-HP57XYFP.js} +5 -5
  128. package/{tools-3J5CKEE7.js → tools-Y65Y3CI4.js} +32 -32
  129. package/{tuiSummaryLlmCaller-SHRB4RWM.js → tuiSummaryLlmCaller-NBTWT57U.js} +25 -14
  130. package/{updateDialogTitleAction-5MGPA3OO.js → updateDialogTitleAction-OAOP7CCE.js} +24 -23
  131. package/chunk-4APLX2RT.js +0 -1514
  132. package/chunk-P66M7LSQ.js +0 -58
  133. package/{chunk-6WD3OOJS.js → chunk-UV6VISQJ.js} +0 -0
  134. package/{tableCommands-PQUJ55AS.js → tableCommands-P2TXJ3CF.js} +1 -1
@@ -35,6 +35,306 @@ function resolveRunRecordPath(runId, env, homedir = nodeHomedir) {
35
35
  function resolveRunLogPath(runId, env, homedir = nodeHomedir) {
36
36
  return join(resolveRunsDir(env, homedir), `${runId}.log`);
37
37
  }
38
+ function resolveRunQueuePath(runId, env, homedir = nodeHomedir) {
39
+ return join(resolveRunsDir(env, homedir), `${runId}.queue.jsonl`);
40
+ }
41
+ function defaultGenerateQueueEntryId() {
42
+ const ts = Date.now().toString(36);
43
+ const rand = Math.random().toString(36).slice(2, 10);
44
+ return `qmsg-${ts}-${rand}`;
45
+ }
46
+ function _parseQueueLines(content) {
47
+ if (!content.trim()) return [];
48
+ const lines = content.split("\n").map((l) => l.trim()).filter(Boolean);
49
+ const entries = [];
50
+ for (const line of lines) {
51
+ try {
52
+ const item = JSON.parse(line);
53
+ if (typeof item?.text === "string" && item.text.trim()) {
54
+ entries.push({
55
+ id: typeof item.id === "string" && item.id.trim() ? item.id.trim() : defaultGenerateQueueEntryId(),
56
+ ts: typeof item.ts === "number" ? item.ts : Date.now(),
57
+ text: item.text.trim()
58
+ });
59
+ }
60
+ } catch {
61
+ if (line.length > 0) {
62
+ entries.push({
63
+ id: defaultGenerateQueueEntryId(),
64
+ ts: Date.now(),
65
+ text: line
66
+ });
67
+ }
68
+ }
69
+ }
70
+ return entries;
71
+ }
72
+ var parseQueueLines = _parseQueueLines;
73
+ function _serializeQueueEntries(entries) {
74
+ if (entries.length === 0) return "";
75
+ return entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
76
+ }
77
+ var serializeQueueEntries = _serializeQueueEntries;
78
+ function _countQueueMessagesLocked(queuePath, fs = nodeFs) {
79
+ if (!fs.existsSync(queuePath)) return 0;
80
+ try {
81
+ const content = fs.readFileSync(queuePath, "utf8");
82
+ return _parseQueueLines(content).length;
83
+ } catch {
84
+ return 0;
85
+ }
86
+ }
87
+ function _readQueueMessagesLocked(queuePath, fs = nodeFs) {
88
+ if (!fs.existsSync(queuePath)) return [];
89
+ try {
90
+ const content = fs.readFileSync(queuePath, "utf8");
91
+ return _parseQueueLines(content).map((e) => e.text);
92
+ } catch {
93
+ return [];
94
+ }
95
+ }
96
+ function _readQueueEntriesLocked(queuePath, fs = nodeFs) {
97
+ if (!fs.existsSync(queuePath)) return [];
98
+ try {
99
+ const content = fs.readFileSync(queuePath, "utf8");
100
+ return _parseQueueLines(content);
101
+ } catch {
102
+ return [];
103
+ }
104
+ }
105
+ function tryUnlinkFile(fs, path) {
106
+ if (typeof path !== "string" || path.length === 0) return true;
107
+ try {
108
+ if (fs.existsSync(path)) {
109
+ fs.unlinkSync(path);
110
+ }
111
+ return true;
112
+ } catch (error) {
113
+ const code = error.code;
114
+ return code === "ENOENT";
115
+ }
116
+ }
117
+ function tryRmdir(fs, path) {
118
+ if (typeof path !== "string" || path.length === 0) return true;
119
+ try {
120
+ if (typeof fs.rmdirSync === "function") {
121
+ fs.rmdirSync(path);
122
+ } else {
123
+ fs.unlinkSync(path);
124
+ }
125
+ return true;
126
+ } catch (error) {
127
+ if (error?.code === "ENOENT") return true;
128
+ return false;
129
+ }
130
+ }
131
+ var QUEUE_LOCK_STALE_MS = 6e4;
132
+ var QUEUE_LOCK_RETRIES = 20;
133
+ var QUEUE_LOCK_RETRY_INTERVAL_MS = 10;
134
+ function defaultGenerateOwnerTokenId() {
135
+ const ts = Date.now().toString(36);
136
+ const rand = Math.random().toString(36).slice(2, 10);
137
+ return `own-${ts}-${rand}`;
138
+ }
139
+ function normalizeQueueDeps(depsOrFs) {
140
+ if (!depsOrFs) return {};
141
+ if ("mkdirSync" in depsOrFs) {
142
+ return { fs: depsOrFs };
143
+ }
144
+ return depsOrFs;
145
+ }
146
+ async function withQueueLock(queuePath, fnOrDeps, depsOrFnOrOpts, maybeOpts) {
147
+ let fn;
148
+ let rawDeps;
149
+ let opts = maybeOpts ?? {};
150
+ if (typeof fnOrDeps === "function") {
151
+ fn = fnOrDeps;
152
+ if (depsOrFnOrOpts && typeof depsOrFnOrOpts === "object" && !("mkdirSync" in depsOrFnOrOpts) && !("fs" in depsOrFnOrOpts) && !("env" in depsOrFnOrOpts)) {
153
+ opts = { ...depsOrFnOrOpts, ...maybeOpts };
154
+ rawDeps = void 0;
155
+ } else {
156
+ rawDeps = depsOrFnOrOpts;
157
+ }
158
+ } else {
159
+ rawDeps = fnOrDeps;
160
+ fn = depsOrFnOrOpts;
161
+ }
162
+ const deps = normalizeQueueDeps(rawDeps);
163
+ const fs = deps.fs ?? nodeFs;
164
+ const now = deps.now ?? (() => /* @__PURE__ */ new Date());
165
+ const staleLockMs = opts.staleLockMs ?? QUEUE_LOCK_STALE_MS;
166
+ const retries = opts.retries ?? QUEUE_LOCK_RETRIES;
167
+ const retryIntervalMs = opts.retryIntervalMs ?? QUEUE_LOCK_RETRY_INTERVAL_MS;
168
+ const lockPath = `${queuePath}.lock`;
169
+ const tokenPath = join(lockPath, "owner.json");
170
+ try {
171
+ fs.mkdirSync(dirname(lockPath), { recursive: true });
172
+ } catch {
173
+ }
174
+ const myOwnerId = defaultGenerateOwnerTokenId();
175
+ let held = false;
176
+ const tryAcquire = () => {
177
+ let created = false;
178
+ try {
179
+ fs.mkdirSync(lockPath);
180
+ created = true;
181
+ } catch {
182
+ try {
183
+ if (typeof fs.statSync === "function") {
184
+ const stat = fs.statSync(lockPath);
185
+ const ageMs = stat ? now().getTime() - stat.mtimeMs : 0;
186
+ if (ageMs > staleLockMs) {
187
+ try {
188
+ tryUnlinkFile(fs, tokenPath);
189
+ tryRmdir(fs, lockPath);
190
+ } catch {
191
+ }
192
+ try {
193
+ fs.mkdirSync(lockPath);
194
+ created = true;
195
+ } catch {
196
+ }
197
+ }
198
+ }
199
+ } catch {
200
+ }
201
+ }
202
+ if (created) {
203
+ try {
204
+ const token = {
205
+ ownerId: myOwnerId,
206
+ pid: process.pid,
207
+ createdAt: now().toISOString(),
208
+ createdAtMs: now().getTime()
209
+ };
210
+ fs.writeFileSync(tokenPath, JSON.stringify(token), "utf8");
211
+ return true;
212
+ } catch (writeTokenErr) {
213
+ tryRmdir(fs, lockPath);
214
+ throw writeTokenErr;
215
+ }
216
+ }
217
+ return false;
218
+ };
219
+ for (let attempt = 0; attempt <= retries; attempt++) {
220
+ if (tryAcquire()) {
221
+ held = true;
222
+ break;
223
+ }
224
+ if (attempt < retries && retryIntervalMs > 0) {
225
+ await new Promise((resolve2) => setTimeout(resolve2, retryIntervalMs));
226
+ }
227
+ }
228
+ if (!held) {
229
+ throw new Error(`queue busy: ${queuePath}`);
230
+ }
231
+ try {
232
+ return await fn();
233
+ } finally {
234
+ if (held) {
235
+ try {
236
+ let currentOwnerId;
237
+ if (fs.existsSync(tokenPath)) {
238
+ try {
239
+ const raw = fs.readFileSync(tokenPath, "utf8");
240
+ const parsed = JSON.parse(raw);
241
+ currentOwnerId = parsed?.ownerId;
242
+ } catch {
243
+ currentOwnerId = void 0;
244
+ }
245
+ }
246
+ if (currentOwnerId === myOwnerId) {
247
+ tryUnlinkFile(fs, tokenPath);
248
+ tryRmdir(fs, lockPath);
249
+ } else {
250
+ console.error(
251
+ `[nolo] Warning: queue lock for ${queuePath} was taken over by another process (owner mismatch: expected ${myOwnerId}, found ${currentOwnerId ?? "none"}). Will not release.`
252
+ );
253
+ }
254
+ } catch (releaseErr) {
255
+ console.error(`[nolo] Warning: failed to release queue lock for ${queuePath}:`, releaseErr);
256
+ }
257
+ }
258
+ }
259
+ }
260
+ async function appendRunQueue(queuePath, input, depsOrFs = {}) {
261
+ const deps = normalizeQueueDeps(depsOrFs);
262
+ const fs = deps.fs ?? nodeFs;
263
+ const now = deps.now ?? (() => /* @__PURE__ */ new Date());
264
+ const text = typeof input === "string" ? input : input.text;
265
+ const entryId = typeof input === "object" && typeof input.id === "string" && input.id.trim() ? input.id.trim() : defaultGenerateQueueEntryId();
266
+ const entry = { id: entryId, ts: now().getTime(), text };
267
+ const line = JSON.stringify(entry) + "\n";
268
+ return await withQueueLock(queuePath, deps, async () => {
269
+ if (typeof fs.appendFileSync === "function") {
270
+ fs.appendFileSync(queuePath, line, "utf8");
271
+ } else {
272
+ const existing = fs.existsSync(queuePath) ? fs.readFileSync(queuePath, "utf8") : "";
273
+ fs.writeFileSync(queuePath, existing + line, "utf8");
274
+ }
275
+ const currentContent = fs.existsSync(queuePath) ? fs.readFileSync(queuePath, "utf8") : line;
276
+ return { queuedCount: _parseQueueLines(currentContent).length, entryId };
277
+ });
278
+ }
279
+ async function countQueueMessages(queuePath, depsOrFs = {}) {
280
+ const deps = normalizeQueueDeps(depsOrFs);
281
+ const fs = deps.fs ?? nodeFs;
282
+ if (!fs.existsSync(queuePath)) return 0;
283
+ return await withQueueLock(queuePath, deps, async () => {
284
+ return _countQueueMessagesLocked(queuePath, fs);
285
+ });
286
+ }
287
+ async function readQueueMessages(queuePath, depsOrFs = {}) {
288
+ const deps = normalizeQueueDeps(depsOrFs);
289
+ const fs = deps.fs ?? nodeFs;
290
+ if (!fs.existsSync(queuePath)) return [];
291
+ return await withQueueLock(queuePath, deps, async () => {
292
+ return _readQueueMessagesLocked(queuePath, fs);
293
+ });
294
+ }
295
+ async function readQueueEntries(queuePath, depsOrFs = {}) {
296
+ const deps = normalizeQueueDeps(depsOrFs);
297
+ const fs = deps.fs ?? nodeFs;
298
+ if (!fs.existsSync(queuePath)) return [];
299
+ return await withQueueLock(queuePath, deps, async () => {
300
+ return _readQueueEntriesLocked(queuePath, fs);
301
+ });
302
+ }
303
+ async function popAllQueueEntries(queuePath, depsOrFs = {}) {
304
+ const deps = normalizeQueueDeps(depsOrFs);
305
+ const fs = deps.fs ?? nodeFs;
306
+ return await withQueueLock(queuePath, deps, async () => {
307
+ if (!fs.existsSync(queuePath)) return [];
308
+ const content = fs.readFileSync(queuePath, "utf8");
309
+ const entries = _parseQueueLines(content);
310
+ tryUnlinkFile(fs, queuePath);
311
+ return entries;
312
+ });
313
+ }
314
+ async function popSingleQueueMessage(queuePath, depsOrFs = {}) {
315
+ const deps = normalizeQueueDeps(depsOrFs);
316
+ const fs = deps.fs ?? nodeFs;
317
+ return await withQueueLock(queuePath, deps, async () => {
318
+ if (!fs.existsSync(queuePath)) return null;
319
+ const content = fs.readFileSync(queuePath, "utf8");
320
+ const entries = _parseQueueLines(content);
321
+ if (entries.length === 0) {
322
+ tryUnlinkFile(fs, queuePath);
323
+ return null;
324
+ }
325
+ const [first, ...rest] = entries;
326
+ if (rest.length === 0) {
327
+ tryUnlinkFile(fs, queuePath);
328
+ } else {
329
+ fs.writeFileSync(queuePath, _serializeQueueEntries(rest), "utf8");
330
+ }
331
+ return first;
332
+ });
333
+ }
334
+ async function popQueueMessages(queuePath, depsOrFs = {}) {
335
+ const entries = await popAllQueueEntries(queuePath, depsOrFs);
336
+ return entries.map((e) => e.text);
337
+ }
38
338
  function resolveRunReportPath(runId, env, homedir = nodeHomedir) {
39
339
  return join(resolveRunsDir(env, homedir), `${runId}.report.md`);
40
340
  }
@@ -269,19 +569,7 @@ function queryRunRecords(query, deps = {}) {
269
569
  return { runs: sliced, total, hasMore };
270
570
  }
271
571
  var DEFAULT_GC_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
272
- function tryUnlinkFile(fs, path) {
273
- if (typeof path !== "string" || path.length === 0) return true;
274
- try {
275
- if (fs.existsSync(path)) {
276
- fs.unlinkSync(path);
277
- }
278
- return true;
279
- } catch (error) {
280
- const code = error.code;
281
- return code === "ENOENT";
282
- }
283
- }
284
- function gcRunRecords(deps = {}, options = {}) {
572
+ async function gcRunRecords(deps = {}, options = {}) {
285
573
  const fs = deps.fs ?? nodeFs;
286
574
  const now = (deps.now ?? (() => /* @__PURE__ */ new Date()))();
287
575
  const nowMs = now instanceof Date ? now.getTime() : Date.parse(String(now));
@@ -296,14 +584,25 @@ function gcRunRecords(deps = {}, options = {}) {
296
584
  if (!Number.isFinite(ageMs) || ageMs < retentionMs) continue;
297
585
  const jsonPath = resolveRunRecordPath(record.runId, deps.env, deps.homedir);
298
586
  const logPath = resolveRunLogPath(record.runId, deps.env, deps.homedir);
587
+ const queuePath = record.queuePath ?? resolveRunQueuePath(record.runId, deps.env, deps.homedir);
299
588
  const reportPath = resolveRunReportPath(record.runId, deps.env, deps.homedir);
300
589
  const reportJsonPath = resolveRunReportJsonPath(record.runId, deps.env, deps.homedir);
301
590
  const msgPath = record.msgFile ?? join(resolveRunsDir(deps.env, deps.homedir), `${record.runId}.msg.md`);
302
591
  const logOk = tryUnlinkFile(fs, logPath);
303
592
  const msgOk = tryUnlinkFile(fs, msgPath);
593
+ let queueOk = true;
594
+ if (fs.existsSync(queuePath)) {
595
+ try {
596
+ await withQueueLock(queuePath, deps, () => {
597
+ tryUnlinkFile(fs, queuePath);
598
+ });
599
+ } catch {
600
+ queueOk = false;
601
+ }
602
+ }
304
603
  tryUnlinkFile(fs, reportPath);
305
604
  tryUnlinkFile(fs, reportJsonPath);
306
- if (!logOk || !msgOk) {
605
+ if (!logOk || !msgOk || !queueOk) {
307
606
  failedIds.push(record.runId);
308
607
  continue;
309
608
  }
@@ -430,6 +729,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
430
729
  const runId = generateRunId();
431
730
  const batchId = input.batchId ?? (deps.generateBatchId ?? defaultGenerateBatchId)();
432
731
  const logPath = resolveRunLogPath(runId, env, homedir);
732
+ const queuePath = resolveRunQueuePath(runId, env, homedir);
433
733
  const recordPath = resolveRunRecordPath(runId, env, homedir);
434
734
  const runsDir = resolveRunsDir(env, homedir);
435
735
  fs.mkdirSync(runsDir, { recursive: true });
@@ -473,15 +773,19 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
473
773
  ...typeof input.timeoutMs === "number" ? { timeoutMs: input.timeoutMs } : {},
474
774
  status: "running",
475
775
  logPath,
776
+ queuePath,
476
777
  batchId,
477
778
  ...typeof input.parentDialogId === "string" && input.parentDialogId.trim() ? { parentDialogId: input.parentDialogId.trim() } : {},
478
779
  ...dodCommands && dodCommands.length > 0 ? { dodCommands } : {},
479
780
  ...spawnHead ? { spawnHead } : {}
480
781
  };
481
782
  fs.writeFileSync(recordPath, JSON.stringify(record, null, 2));
783
+ const rawArgsWithQueue = (input.rawArgs ?? []).some(
784
+ (arg) => arg === "--queue-file" || arg.startsWith("--queue-file=")
785
+ ) ? input.rawArgs : [...input.rawArgs ?? [], "--queue-file", queuePath];
482
786
  const { execPath, childArgs } = buildAgentRunChildCommand(
483
787
  {
484
- rawArgs: input.rawArgs,
788
+ rawArgs: rawArgsWithQueue,
485
789
  commandPath: input.commandPath,
486
790
  cliEntrypointPath: input.cliEntrypointPath,
487
791
  messagePath
@@ -507,7 +811,7 @@ async function spawnLocalBackgroundRun(input, deps = {}) {
507
811
  if (processStartedAt) record.processStartedAt = processStartedAt.toISOString();
508
812
  writeRunRecord(record, deps);
509
813
  }
510
- return { runId, pid: proc.pid, logPath, batchId };
814
+ return { runId, pid: proc.pid, logPath, queuePath, batchId };
511
815
  }
512
816
  function ackRunRecord(runId, deps = {}) {
513
817
  withRunRecordLock(runId, deps, () => {
@@ -1053,6 +1357,27 @@ export {
1053
1357
  resolveRunsDir,
1054
1358
  resolveRunRecordPath,
1055
1359
  resolveRunLogPath,
1360
+ resolveRunQueuePath,
1361
+ defaultGenerateQueueEntryId,
1362
+ _parseQueueLines,
1363
+ parseQueueLines,
1364
+ _serializeQueueEntries,
1365
+ serializeQueueEntries,
1366
+ _countQueueMessagesLocked,
1367
+ _readQueueMessagesLocked,
1368
+ _readQueueEntriesLocked,
1369
+ QUEUE_LOCK_STALE_MS,
1370
+ QUEUE_LOCK_RETRIES,
1371
+ QUEUE_LOCK_RETRY_INTERVAL_MS,
1372
+ defaultGenerateOwnerTokenId,
1373
+ withQueueLock,
1374
+ appendRunQueue,
1375
+ countQueueMessages,
1376
+ readQueueMessages,
1377
+ readQueueEntries,
1378
+ popAllQueueEntries,
1379
+ popSingleQueueMessage,
1380
+ popQueueMessages,
1056
1381
  resolveRunReportPath,
1057
1382
  resolveRunReportJsonPath,
1058
1383
  defaultGenerateRunId,
@@ -23,19 +23,23 @@ import {
23
23
  shouldStripReasoningContentForOutbound,
24
24
  toOpenAiCompatibleMessages,
25
25
  toResponsesTools
26
- } from "./chunk-BMB563Y6.js";
26
+ } from "./chunk-6BYAXNH5.js";
27
27
  import {
28
28
  buildProviderExecutionPlan,
29
29
  canUsePlatformChatProvider,
30
30
  hasDirectOpenAiCompatibleProvider,
31
31
  resolveAgentRuntimeLocation,
32
+ resolveClientVersion,
32
33
  resolvePlatformAuthToken,
33
34
  resolvePlatformServerUrl,
34
35
  resolveProviderTransportDecision
35
- } from "./chunk-GKHV4UH5.js";
36
+ } from "./chunk-5UOBIU5G.js";
36
37
  import {
37
38
  clipCompactText
38
- } from "./chunk-FGLKRJDI.js";
39
+ } from "./chunk-GK74OOFT.js";
40
+ import {
41
+ NOLO_CLIENT_VERSION_HEADER
42
+ } from "./chunk-ENYDQKOB.js";
39
43
  import {
40
44
  isRecord
41
45
  } from "./chunk-KUG52IAP.js";
@@ -62,7 +66,7 @@ function extractUsageFromSsePayload(parsed) {
62
66
  if (topLevel && typeof topLevel === "object" && hasUsageTokens(topLevel)) {
63
67
  return topLevel;
64
68
  }
65
- if (payload.type === "response.completed") {
69
+ if (typeof payload.type === "string" && payload.type.startsWith("response.")) {
66
70
  const response = payload.response;
67
71
  if (response && typeof response === "object") {
68
72
  const nested = response.usage;
@@ -434,7 +438,9 @@ async function resolvePlatformChatProviderConfig(args) {
434
438
  requestOptions: plan.requestOptions,
435
439
  ...plan.apiKey ? { apiKey: plan.apiKey } : {},
436
440
  ...plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {},
437
- ...args.agentConfig.apiSource ? { apiSource: args.agentConfig.apiSource } : {}
441
+ ...args.agentConfig.apiSource ? { apiSource: args.agentConfig.apiSource } : {},
442
+ ...plan.usageProvider ? { usageProvider: plan.usageProvider } : {},
443
+ ...resolveClientVersion(args.env) ? { clientVersion: resolveClientVersion(args.env) } : {}
438
444
  };
439
445
  }
440
446
  return {
@@ -447,7 +453,9 @@ async function resolvePlatformChatProviderConfig(args) {
447
453
  requestOptions: plan.requestOptions,
448
454
  ...plan.apiKey ? { apiKey: plan.apiKey } : {},
449
455
  ...plan.apiKeyHeader ? { apiKeyHeader: plan.apiKeyHeader } : {},
450
- ...plan.apiSource ? { apiSource: plan.apiSource } : {}
456
+ ...plan.apiSource ? { apiSource: plan.apiSource } : {},
457
+ ...plan.usageProvider ? { usageProvider: plan.usageProvider } : {},
458
+ ...plan.clientVersion ? { clientVersion: plan.clientVersion } : {}
451
459
  };
452
460
  }
453
461
  function buildPlatformChatCompletionRequest(args) {
@@ -468,7 +476,9 @@ function buildPlatformChatCompletionRequest(args) {
468
476
  })
469
477
  },
470
478
  stream: args.stream ?? false,
471
- ...args.stream ? getUsageRequestOptions(args.providerConfig.provider, { api: "chat-completions" }) : {},
479
+ ...args.stream ? getUsageRequestOptions(args.providerConfig.usageProvider ?? args.providerConfig.provider, {
480
+ api: usesResponsesApi ? "responses" : "chat-completions"
481
+ }) : {},
472
482
  ...requestOptions,
473
483
  ...args.tools && args.tools.length > 0 ? {
474
484
  tools: usesResponsesApi ? toResponsesTools(args.tools) : args.tools,
@@ -489,7 +499,13 @@ function buildPlatformChatCompletionRequest(args) {
489
499
  method: "POST",
490
500
  headers: {
491
501
  "Content-Type": "application/json",
492
- Authorization: `Bearer ${args.providerConfig.authToken}`
502
+ Authorization: `Bearer ${args.providerConfig.authToken}`,
503
+ // 客户端版本闸门第 2 层:与鉴权头同处一处统一注入,避免某条命令路径
504
+ // 漏发。server 据此拒绝「该客户端认不了 wire 的托管模型」;不发这个头
505
+ // 的旧客户端在 server 侧 fail-open(已知局限)。
506
+ ...args.providerConfig.clientVersion ? {
507
+ [NOLO_CLIENT_VERSION_HEADER]: args.providerConfig.clientVersion
508
+ } : {}
493
509
  },
494
510
  body: JSON.stringify(body)
495
511
  }
@@ -588,7 +604,11 @@ function processPlatformChatSseEvent(event, state) {
588
604
  const trimmed = line.trim();
589
605
  if (!trimmed.startsWith("data:")) continue;
590
606
  const payload = trimmed.slice(5).trim();
591
- if (!payload || payload === "[DONE]") continue;
607
+ if (!payload) continue;
608
+ if (payload === "[DONE]") {
609
+ state.sawDone = true;
610
+ continue;
611
+ }
592
612
  let parsed;
593
613
  try {
594
614
  parsed = JSON.parse(payload);
@@ -666,7 +686,8 @@ async function readPlatformChatSseCompletion(args) {
666
686
  accumulatedToolCalls: createToolCallAccumulator(),
667
687
  thinkState: createThinkParserState(),
668
688
  toolCallTextState: createToolCallTextParserState(),
669
- finishReason: void 0
689
+ finishReason: void 0,
690
+ sawDone: false
670
691
  };
671
692
  for await (const frame of readSseFrames(args.response)) {
672
693
  processPlatformChatSseEvent(frame, state);
@@ -700,11 +721,13 @@ async function readPlatformChatSseCompletion(args) {
700
721
  );
701
722
  const tool_calls2 = completedToolCalls.length > 0 ? completedToolCalls : normalizedDsmlCalls.length > 0 ? normalizedDsmlCalls : completionsToolCalls.length > 0 ? completionsToolCalls : finalizeResponsesToolCalls(state.responsesToolCalls);
702
723
  const finalUsage2 = mergeBillingIntoUsage(state.usage, state.billing);
724
+ const streamComplete2 = state.sawDone || !!state.usage || !!state.finishReason;
703
725
  return {
704
726
  content: normalizedFinal.content || state.content,
705
727
  ...state.reasoning ? { reasoning_content: state.reasoning } : {},
706
728
  ...tool_calls2.length > 0 ? { tool_calls: tool_calls2 } : {},
707
- ...finalUsage2 ? { usage: finalUsage2, stream_complete: true } : {},
729
+ ...finalUsage2 ? { usage: finalUsage2 } : {},
730
+ ...streamComplete2 ? { stream_complete: true } : {},
708
731
  // finish_reason 供 executePlatformChatCompletion 穿透给 localLoop 的
709
732
  // 空轮/截断判定;此前 reader 从不回传,流式路径恒缺。
710
733
  ...state.finishReason ? { finish_reason: state.finishReason } : {}
@@ -712,11 +735,13 @@ async function readPlatformChatSseCompletion(args) {
712
735
  }
713
736
  const tool_calls = finalizeAccumulatedToolCalls(state.accumulatedToolCalls);
714
737
  const finalUsage = mergeBillingIntoUsage(state.usage, state.billing);
738
+ const streamComplete = state.sawDone || !!state.usage || !!state.finishReason;
715
739
  return {
716
740
  content: state.content,
717
741
  ...state.reasoning ? { reasoning_content: state.reasoning } : {},
718
742
  ...tool_calls.length > 0 ? { tool_calls } : {},
719
- ...finalUsage ? { usage: finalUsage, stream_complete: true } : {},
743
+ ...finalUsage ? { usage: finalUsage } : {},
744
+ ...streamComplete ? { stream_complete: true } : {},
720
745
  ...state.finishReason ? { finish_reason: state.finishReason } : {}
721
746
  };
722
747
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DEFAULT_AGENT_BASE_POLICY,
3
3
  DEFAULT_USER_PREFERENCE_PROFILE
4
- } from "./chunk-B6H5XCT2.js";
4
+ } from "./chunk-EMEUU5IY.js";
5
5
 
6
6
  // packages/ai/policy/runtimePolicy.ts
7
7
  var clampLevel = (value, fallback) => {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Level
3
- } from "./chunk-6WD3OOJS.js";
3
+ } from "./chunk-UV6VISQJ.js";
4
4
 
5
5
  // packages/database-engine/levelAuthorityStore.ts
6
6
  var safeJsonEncoding = {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  buildLocalAgentLookupKeys,
3
3
  shouldReadAgentKeyRemotely
4
- } from "./chunk-J5NMOM35.js";
4
+ } from "./chunk-OYNDYVSE.js";
5
5
  import {
6
6
  resolveCliAgentKeyInput
7
7
  } from "./chunk-EKLRRZIN.js";
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-A7GB5UGH.js";
22
22
  import {
23
23
  createAgentKey
24
- } from "./chunk-2WKUUY2E.js";
24
+ } from "./chunk-SVEUG45B.js";
25
25
 
26
26
  // packages/cli/agentRecordHelpers.ts
27
27
  import { readFileSync } from "node:fs";
@@ -3,10 +3,10 @@ import {
3
3
  } from "./chunk-YYLHWIW6.js";
4
4
  import {
5
5
  compareAgentSelection
6
- } from "./chunk-IZCHPD7T.js";
6
+ } from "./chunk-TNPCQNGQ.js";
7
7
  import {
8
8
  getModelAbility
9
- } from "./chunk-FTM4KUOZ.js";
9
+ } from "./chunk-7XTC3KRG.js";
10
10
  import {
11
11
  isOwnedAgentKey,
12
12
  ownedAgentKey,
@@ -157,8 +157,74 @@ function toSafeAgentSummary(record, options) {
157
157
  function sortSafeAgentSummaries(agents) {
158
158
  return [...agents].sort(compareAgentSelection);
159
159
  }
160
+ var COMPACT_AGENT_SUMMARY_FIELDS = [
161
+ "agentKey",
162
+ "name",
163
+ "model",
164
+ "provider",
165
+ "apiSource",
166
+ "isFavorite",
167
+ "isOAuth",
168
+ "isOwned",
169
+ "isPublic",
170
+ "tools",
171
+ // 仅限流中的 agent 才会带(可用 agent 上不存在)。对"现在能不能选它"是
172
+ // 决策信息(CLI --show-unavailable 场景);默认列表已把这类 agent 过滤掉,
173
+ // 所以通常根本不占字节。
174
+ "nextAvailableAt"
175
+ ];
176
+ function omitNullishAgentSummaryFields(summary) {
177
+ const result = {};
178
+ for (const [key, value] of Object.entries(summary)) {
179
+ if (value !== null && value !== void 0) {
180
+ result[key] = value;
181
+ }
182
+ }
183
+ return result;
184
+ }
185
+ function toCompactAgentSummary(summary) {
186
+ const compact = {};
187
+ for (const field of COMPACT_AGENT_SUMMARY_FIELDS) {
188
+ const value = summary[field];
189
+ if (value !== null && value !== void 0) {
190
+ compact[field] = value;
191
+ }
192
+ }
193
+ return compact;
194
+ }
195
+ var UNAVAILABLE_AGENT_SUMMARY_FIELDS = [
196
+ "agentKey",
197
+ "name",
198
+ "model",
199
+ "provider",
200
+ "apiSource",
201
+ "isFavorite",
202
+ "isOAuth",
203
+ "isOwned",
204
+ "nextAvailableAt",
205
+ "favoritedAt",
206
+ "updatedAt"
207
+ ];
208
+ function toUnavailableAgentSummary(summary) {
209
+ const item = {
210
+ name: summary.name,
211
+ isFavorite: summary.isFavorite,
212
+ isOAuth: summary.isOAuth,
213
+ isOwned: summary.isOwned
214
+ };
215
+ for (const field of UNAVAILABLE_AGENT_SUMMARY_FIELDS) {
216
+ const value = summary[field];
217
+ if (value !== null && value !== void 0) {
218
+ item[field] = value;
219
+ }
220
+ }
221
+ return item;
222
+ }
160
223
 
161
224
  export {
162
225
  toSafeAgentSummary,
163
- sortSafeAgentSummaries
226
+ sortSafeAgentSummaries,
227
+ omitNullishAgentSummaryFields,
228
+ toCompactAgentSummary,
229
+ toUnavailableAgentSummary
164
230
  };
@@ -13,18 +13,18 @@ import {
13
13
  toTimestampMs,
14
14
  upsert,
15
15
  write
16
- } from "./chunk-23KKIMD5.js";
16
+ } from "./chunk-WVGEBWA6.js";
17
17
  import {
18
18
  createUserKey,
19
19
  createUserPreferenceKey,
20
20
  ulid
21
- } from "./chunk-2WKUUY2E.js";
21
+ } from "./chunk-SVEUG45B.js";
22
22
  import {
23
23
  asTrimmedLowercaseString
24
24
  } from "./chunk-QSJ3HFEF.js";
25
25
  import {
26
26
  BUILTIN_NOLO_AGENT_KEY
27
- } from "./chunk-XT73C4VH.js";
27
+ } from "./chunk-Z5NW3O7V.js";
28
28
  import {
29
29
  asyncThunkCreator,
30
30
  buildCreateSlice,