open-agents-ai 0.104.31 → 0.105.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 (2) hide show
  1. package/dist/index.js +928 -588
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5639,8 +5639,8 @@ function deleteCustomToolDefinition(name, scope, repoRoot) {
5639
5639
  const dir = scope === "project" && repoRoot ? projectToolsDir(repoRoot) : globalToolsDir();
5640
5640
  const filePath = join13(dir, `${name}.json`);
5641
5641
  if (existsSync10(filePath)) {
5642
- const { unlinkSync: unlinkSync9 } = __require("node:fs");
5643
- unlinkSync9(filePath);
5642
+ const { unlinkSync: unlinkSync10 } = __require("node:fs");
5643
+ unlinkSync10(filePath);
5644
5644
  return true;
5645
5645
  }
5646
5646
  return false;
@@ -12555,15 +12555,16 @@ async function handleCmd(cmd) {
12555
12555
  riData.auth_key = riAuthKey;
12556
12556
  }
12557
12557
 
12558
+ // Streaming mode: if stream_file is provided, use stream:true and write tokens to file
12559
+ var riStreamFile = args.stream_file || '';
12560
+ var riUseStream = !!riStreamFile;
12561
+
12558
12562
  // If target_peer specified, invoke directly. Otherwise auto-discover.
12559
12563
  if (riTargetPeer) {
12560
- // Race libp2p direct dial and NATS relay IN PARALLEL.
12561
- // For cross-NAT peers, libp2p dial can take 10-60s to fail while NATS
12562
- // succeeds in <1s. Racing them eliminates the wait.
12563
- dlog('remote_infer: invoking ' + riCapName + ' on peer ' + riTargetPeer.slice(0, 20) + ' (libp2p' + (_natsConn ? ' + NATS parallel' : '') + ')');
12564
+ dlog('remote_infer: invoking ' + riCapName + ' on peer ' + riTargetPeer.slice(0, 20) + ' stream=' + riUseStream + ' (libp2p' + (_natsConn ? ' + NATS parallel' : '') + ')');
12564
12565
  try {
12565
- var RI_TIMEOUT = 60000; // 60s outer timeout \u2014 fail fast for interactive use
12566
- var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: false, maxDurationMs: 45000 });
12566
+ var RI_TIMEOUT = 120000;
12567
+ var riInvokeP = nexus.invokeCapability(riTargetPeer, riCapName, riData, { stream: riUseStream, maxDurationMs: 90000 });
12567
12568
  var riTimeoutP = new Promise(function(_, reject) { setTimeout(function() { reject(new Error('remote_infer timed out after ' + (RI_TIMEOUT / 1000) + 's')); }, RI_TIMEOUT); });
12568
12569
 
12569
12570
  // Build race candidates \u2014 libp2p + timeout always present
@@ -12667,22 +12668,67 @@ async function handleCmd(cmd) {
12667
12668
  }
12668
12669
 
12669
12670
  // riResult and riTargetPeer are available from either path above
12670
- // Check if the invoke returned an error message instead of real data.
12671
- // IMPORTANT: Only flag short non-JSON strings as errors. Valid inference
12672
- // responses are JSON with model/response/choices \u2014 the model's natural
12673
- // language output often contains words like "error" or "not found" which
12674
- // would cause false positives if we checked the entire JSON string.
12671
+ // \u2500\u2500 Streaming mode: iterate AsyncGenerator, write tokens to file \u2500\u2500
12672
+ if (riUseStream && riResult && typeof riResult[Symbol.asyncIterator] === 'function') {
12673
+ // Signal OA process that streaming has started
12674
+ writeResp(id, { ok: true, output: JSON.stringify({ streaming: true, stream_file: riStreamFile }) });
12675
+
12676
+ var riTokenContent = '';
12677
+ var riToolCalls = [];
12678
+ var riInputTokens = 0;
12679
+ var riOutputTokens = 0;
12680
+ try {
12681
+ for await (var riEvt of riResult) {
12682
+ if (riEvt.event === 'token' && riEvt.data) {
12683
+ var tkn = typeof riEvt.data === 'string' ? riEvt.data : String(riEvt.data);
12684
+ riTokenContent += tkn;
12685
+ appendFileSync(riStreamFile, JSON.stringify({ type: 'token', content: tkn }) + '
12686
+ ');
12687
+ } else if (riEvt.event === 'result' && riEvt.data) {
12688
+ // Final metadata event \u2014 parse for usage/tool_calls
12689
+ try {
12690
+ var riMeta = typeof riEvt.data === 'string' ? JSON.parse(riEvt.data) : riEvt.data;
12691
+ if (riMeta.usage) {
12692
+ riInputTokens = riMeta.usage.input_tokens || riMeta.usage.prompt_tokens || 0;
12693
+ riOutputTokens = riMeta.usage.output_tokens || riMeta.usage.completion_tokens || 0;
12694
+ }
12695
+ if (riMeta.choices && riMeta.choices[0] && riMeta.choices[0].message && riMeta.choices[0].message.tool_calls) {
12696
+ riToolCalls = riMeta.choices[0].message.tool_calls;
12697
+ }
12698
+ } catch {}
12699
+ }
12700
+ }
12701
+ } catch (riStreamErr) {
12702
+ dlog('remote_infer: stream error: ' + (riStreamErr.message || riStreamErr));
12703
+ }
12704
+
12705
+ // Write done sentinel with final response
12706
+ var riFinalPayload = {
12707
+ model: riModel,
12708
+ response: riTokenContent,
12709
+ choices: [{
12710
+ message: {
12711
+ content: riTokenContent,
12712
+ tool_calls: riToolCalls.length > 0 ? riToolCalls : undefined,
12713
+ },
12714
+ }],
12715
+ usage: { input_tokens: riInputTokens, output_tokens: riOutputTokens },
12716
+ };
12717
+ appendFileSync(riStreamFile, JSON.stringify({ type: 'done', result: JSON.stringify(riFinalPayload) }) + '
12718
+ ');
12719
+ dlog('remote_infer: stream complete, tokens=' + riTokenContent.length + ' in=' + riInputTokens + ' out=' + riOutputTokens);
12720
+ break;
12721
+ }
12722
+
12723
+ // \u2500\u2500 Unary mode: check for errors and write response \u2500\u2500
12675
12724
  var riIsError = false;
12676
12725
  if (typeof riResult === 'string') {
12677
- // Try to parse as JSON \u2014 if it has model+response or choices, it's valid
12678
12726
  var riParsedCheck = null;
12679
12727
  try { riParsedCheck = JSON.parse(riResult); } catch {}
12680
12728
  if (riParsedCheck && typeof riParsedCheck === 'object' &&
12681
12729
  (riParsedCheck.model || riParsedCheck.choices || riParsedCheck.response !== undefined)) {
12682
- // Valid inference response \u2014 NOT an error
12683
12730
  riIsError = false;
12684
12731
  } else {
12685
- // Non-JSON or unstructured response \u2014 check for error keywords
12686
12732
  var riLower = riResult.toLowerCase();
12687
12733
  if (riLower.includes('unauthorized') || riLower.includes('forbidden') ||
12688
12734
  riLower.includes('not found') || riLower.includes('error') ||
@@ -13118,12 +13164,15 @@ async function handleCmd(cmd) {
13118
13164
 
13119
13165
  var genResp, genData, output, inputTokens, outputTokens, responsePayload;
13120
13166
 
13167
+ // Detect if requester wants streaming (outputMode from invoke.open)
13168
+ var wantsStream = request.outputMode === 'stream';
13169
+
13121
13170
  if (parsedReq && parsedReq.messages && Array.isArray(parsedReq.messages)) {
13122
13171
  // Structured request \u2014 use /v1/chat/completions (supports tools + multi-turn)
13123
13172
  var chatBody = {
13124
13173
  model: model.name,
13125
13174
  messages: parsedReq.messages,
13126
- stream: false,
13175
+ stream: wantsStream,
13127
13176
  };
13128
13177
  if (parsedReq.tools && parsedReq.tools.length > 0) {
13129
13178
  chatBody.tools = parsedReq.tools;
@@ -13134,41 +13183,117 @@ async function handleCmd(cmd) {
13134
13183
 
13135
13184
  var chatHeaders = { 'Content-Type': 'application/json' };
13136
13185
  if (isPassthrough && endpointAuth) chatHeaders['Authorization'] = 'Bearer ' + endpointAuth;
13137
- dlog('expose: calling /v1/chat/completions with ' + chatBody.messages.length + ' messages, tools=' + (chatBody.tools ? chatBody.tools.length : 0) + (isPassthrough ? ' (passthrough)' : ''));
13186
+ dlog('expose: calling /v1/chat/completions with ' + chatBody.messages.length + ' messages, tools=' + (chatBody.tools ? chatBody.tools.length : 0) + ' stream=' + wantsStream + (isPassthrough ? ' (passthrough)' : ''));
13138
13187
  genResp = await fetch(ollamaUrl + '/v1/chat/completions', {
13139
13188
  method: 'POST',
13140
13189
  headers: chatHeaders,
13141
13190
  body: JSON.stringify(chatBody),
13142
- signal: AbortSignal.timeout(210000), // 3.5 min \u2014 upstream API may be slow
13191
+ signal: AbortSignal.timeout(210000),
13143
13192
  });
13144
- genData = await genResp.json();
13145
- dlog('expose: ollama response keys=' + Object.keys(genData).join(',') + ' choices=' + (genData.choices ? genData.choices.length : 0));
13146
-
13147
- var chatChoices = genData.choices || [];
13148
- var firstMsg = (chatChoices[0] || {}).message || {};
13149
- // Strip <think>...</think> tags from content (thinking models)
13150
- var rawContent = firstMsg.content || '';
13151
- output = rawContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
13152
- // Fallback: if content is empty but reasoning exists, use reasoning
13153
- // (happens when max_tokens is too small for thinking models at temp=0)
13154
- if (!output && firstMsg.reasoning) {
13155
- output = firstMsg.reasoning;
13156
- }
13157
- // Update the choices to reflect final content
13158
- if (chatChoices[0] && chatChoices[0].message) {
13159
- chatChoices[0].message.content = output;
13160
- }
13161
- dlog('expose: rawContent_len=' + rawContent.length + ' output_len=' + output.length + ' reasoning=' + (firstMsg.reasoning ? firstMsg.reasoning.length : 0) + ' tool_calls=' + (firstMsg.tool_calls ? firstMsg.tool_calls.length : 0));
13162
- inputTokens = (genData.usage || {}).prompt_tokens || 0;
13163
- outputTokens = (genData.usage || {}).completion_tokens || 0;
13164
13193
 
13165
- responsePayload = {
13166
- model: model.name,
13167
- response: output,
13168
- choices: chatChoices,
13169
- usage: { input_tokens: inputTokens, output_tokens: outputTokens },
13170
- pricing: entry.pricing,
13171
- };
13194
+ if (wantsStream && genResp.ok && genResp.body) {
13195
+ // \u2500\u2500 SSE streaming path \u2014 read tokens and send as invoke.event \u2500\u2500
13196
+ var sseReader = genResp.body.getReader();
13197
+ var sseDecoder = new TextDecoder();
13198
+ var sseBuf = '';
13199
+ var sseSeq = 0;
13200
+ var sseContent = '';
13201
+ var sseToolCalls = [];
13202
+ inputTokens = 0;
13203
+ outputTokens = 0;
13204
+
13205
+ while (true) {
13206
+ var sseChunk = await sseReader.read();
13207
+ if (sseChunk.done) break;
13208
+ sseBuf += sseDecoder.decode(sseChunk.value, { stream: true });
13209
+ var sseLines = sseBuf.split('
13210
+ ');
13211
+ sseBuf = sseLines.pop();
13212
+
13213
+ for (var sli = 0; sli < sseLines.length; sli++) {
13214
+ var sseLine = sseLines[sli];
13215
+ if (!sseLine.startsWith('data: ')) continue;
13216
+ var sseData = sseLine.slice(6).trim();
13217
+ if (sseData === '[DONE]') continue;
13218
+
13219
+ try {
13220
+ var sseObj = JSON.parse(sseData);
13221
+ var sseDelta = (sseObj.choices && sseObj.choices[0] && sseObj.choices[0].delta) || {};
13222
+ var sseToken = sseDelta.content || '';
13223
+ if (sseToken) {
13224
+ sseContent += sseToken;
13225
+ await swrite({
13226
+ type: 'invoke.event', version: 1,
13227
+ requestId: request.requestId, seq: sseSeq++,
13228
+ event: 'token', data: sseToken,
13229
+ });
13230
+ }
13231
+ // Collect tool calls from streaming deltas
13232
+ if (sseDelta.tool_calls) {
13233
+ for (var stci = 0; stci < sseDelta.tool_calls.length; stci++) {
13234
+ var stc = sseDelta.tool_calls[stci];
13235
+ if (stc.index !== undefined) {
13236
+ while (sseToolCalls.length <= stc.index) sseToolCalls.push({ id: '', function: { name: '', arguments: '' } });
13237
+ if (stc.id) sseToolCalls[stc.index].id = stc.id;
13238
+ if (stc.function) {
13239
+ if (stc.function.name) sseToolCalls[stc.index].function.name = stc.function.name;
13240
+ if (stc.function.arguments) sseToolCalls[stc.index].function.arguments += stc.function.arguments;
13241
+ }
13242
+ }
13243
+ }
13244
+ }
13245
+ // Capture usage from final chunk
13246
+ if (sseObj.usage) {
13247
+ inputTokens = sseObj.usage.prompt_tokens || 0;
13248
+ outputTokens = sseObj.usage.completion_tokens || 0;
13249
+ }
13250
+ } catch (sseParseErr) { /* skip bad SSE lines */ }
13251
+ }
13252
+ }
13253
+
13254
+ // Strip thinking tags from accumulated content
13255
+ output = sseContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
13256
+ // Build final response payload for the result event
13257
+ var sseChoices = [{
13258
+ message: {
13259
+ content: output,
13260
+ tool_calls: sseToolCalls.length > 0 ? sseToolCalls : undefined,
13261
+ },
13262
+ }];
13263
+ responsePayload = {
13264
+ model: model.name,
13265
+ response: output,
13266
+ choices: sseChoices,
13267
+ usage: { input_tokens: inputTokens, output_tokens: outputTokens },
13268
+ pricing: entry.pricing,
13269
+ };
13270
+ } else {
13271
+ // \u2500\u2500 Unary path (stream: false or streaming not available) \u2500\u2500
13272
+ genData = await genResp.json();
13273
+ dlog('expose: ollama response keys=' + Object.keys(genData).join(',') + ' choices=' + (genData.choices ? genData.choices.length : 0));
13274
+
13275
+ var chatChoices = genData.choices || [];
13276
+ var firstMsg = (chatChoices[0] || {}).message || {};
13277
+ var rawContent = firstMsg.content || '';
13278
+ output = rawContent.replace(/<think>[\\s\\S]*?<\\/think>/g, '').trim();
13279
+ if (!output && firstMsg.reasoning) {
13280
+ output = firstMsg.reasoning;
13281
+ }
13282
+ if (chatChoices[0] && chatChoices[0].message) {
13283
+ chatChoices[0].message.content = output;
13284
+ }
13285
+ dlog('expose: rawContent_len=' + rawContent.length + ' output_len=' + output.length);
13286
+ inputTokens = (genData.usage || {}).prompt_tokens || 0;
13287
+ outputTokens = (genData.usage || {}).completion_tokens || 0;
13288
+
13289
+ responsePayload = {
13290
+ model: model.name,
13291
+ response: output,
13292
+ choices: chatChoices,
13293
+ usage: { input_tokens: inputTokens, output_tokens: outputTokens },
13294
+ pricing: entry.pricing,
13295
+ };
13296
+ }
13172
13297
  } else if (isPassthrough) {
13173
13298
  // Passthrough flat prompt \u2014 convert to /v1/chat/completions (upstream has no /api/generate)
13174
13299
  var flatPrompt = parsedReq && parsedReq.prompt ? parsedReq.prompt : (prompt || 'Hello');
@@ -14321,11 +14446,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14321
14446
  nodePaths.push(globalDir);
14322
14447
  } catch {
14323
14448
  }
14324
- const { openSync, closeSync } = await import("node:fs");
14449
+ const { openSync: openSync2, closeSync: closeSync2 } = await import("node:fs");
14325
14450
  const daemonLogPath = join30(this.nexusDir, "daemon.log");
14326
14451
  const daemonErrPath = join30(this.nexusDir, "daemon.err");
14327
- const outFd = openSync(daemonLogPath, "w");
14328
- const errFd = openSync(daemonErrPath, "w");
14452
+ const outFd = openSync2(daemonLogPath, "w");
14453
+ const errFd = openSync2(daemonErrPath, "w");
14329
14454
  const child = spawn11("node", [daemonPath, this.nexusDir, agentName, agentType], {
14330
14455
  detached: true,
14331
14456
  stdio: ["ignore", outFd, errFd],
@@ -14334,11 +14459,11 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
14334
14459
  });
14335
14460
  child.unref();
14336
14461
  try {
14337
- closeSync(outFd);
14462
+ closeSync2(outFd);
14338
14463
  } catch {
14339
14464
  }
14340
14465
  try {
14341
- closeSync(errFd);
14466
+ closeSync2(errFd);
14342
14467
  } catch {
14343
14468
  }
14344
14469
  const statusFile = join30(this.nexusDir, "status.json");
@@ -20059,9 +20184,9 @@ ${marker}` : marker);
20059
20184
  if (!this._workingDirectory)
20060
20185
  return;
20061
20186
  try {
20062
- const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync19 } = __require("node:fs");
20063
- const { join: join56 } = __require("node:path");
20064
- const sessionDir = join56(this._workingDirectory, ".oa", "session", this._sessionId);
20187
+ const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync20 } = __require("node:fs");
20188
+ const { join: join57 } = __require("node:path");
20189
+ const sessionDir = join57(this._workingDirectory, ".oa", "session", this._sessionId);
20065
20190
  mkdirSync21(sessionDir, { recursive: true });
20066
20191
  const checkpoint = {
20067
20192
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -20074,7 +20199,7 @@ ${marker}` : marker);
20074
20199
  memexEntryCount: this._memexArchive.size,
20075
20200
  fileRegistrySize: this._fileRegistry.size
20076
20201
  };
20077
- writeFileSync19(join56(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20202
+ writeFileSync20(join57(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
20078
20203
  } catch {
20079
20204
  }
20080
20205
  }
@@ -21340,6 +21465,11 @@ ${transcript}`
21340
21465
  });
21341
21466
 
21342
21467
  // packages/orchestrator/dist/nexusBackend.js
21468
+ import { existsSync as existsSync26, statSync as statSync9, openSync, readSync, closeSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
21469
+ import { watch as fsWatch } from "node:fs";
21470
+ import { join as join34 } from "node:path";
21471
+ import { tmpdir as tmpdir6 } from "node:os";
21472
+ import { randomBytes as randomBytes7 } from "node:crypto";
21343
21473
  var NexusAgenticBackend;
21344
21474
  var init_nexusBackend = __esm({
21345
21475
  "packages/orchestrator/dist/nexusBackend.js"() {
@@ -21475,47 +21605,199 @@ var init_nexusBackend = __esm({
21475
21605
  };
21476
21606
  }
21477
21607
  /**
21478
- * Simulated streaming: calls chatCompletion() for the full response,
21479
- * then yields it as word-level StreamChunk objects.
21480
- * Gives API compatibility with the streaming path in AgenticRunner.
21608
+ * Real streaming: sends remote_infer with a stream_file, then tails
21609
+ * the file for token-by-token delivery from the remote peer.
21610
+ * Falls back to unary + word-split if streaming setup fails.
21481
21611
  */
21482
21612
  async *chatCompletionStream(request) {
21483
- const response = await this.chatCompletion(request);
21484
- const choice = response.choices[0];
21485
- if (!choice)
21486
- return;
21487
- const msg = choice.message;
21488
- if (msg.content) {
21489
- const words = msg.content.split(/(\s+)/);
21490
- for (const word of words) {
21491
- if (word) {
21492
- yield { type: "content", content: word };
21493
- }
21613
+ const streamFile = join34(tmpdir6(), `nexus-stream-${randomBytes7(6).toString("hex")}.jsonl`);
21614
+ writeFileSync8(streamFile, "", "utf8");
21615
+ const daemonArgs = {
21616
+ model: this.model,
21617
+ messages: JSON.stringify(request.messages),
21618
+ tools: JSON.stringify(request.tools),
21619
+ temperature: String(request.temperature),
21620
+ max_tokens: String(request.maxTokens),
21621
+ stream_file: streamFile
21622
+ };
21623
+ if (this.targetPeer)
21624
+ daemonArgs.target_peer = this.targetPeer;
21625
+ if (this.authKey)
21626
+ daemonArgs.auth_key = this.authKey;
21627
+ daemonArgs.think = String(this.thinking);
21628
+ let rawResult;
21629
+ try {
21630
+ rawResult = await this.sendFn("remote_infer", daemonArgs, request.timeoutMs || 12e4);
21631
+ } catch (sendErr) {
21632
+ this.consecutiveFailures++;
21633
+ try {
21634
+ unlinkSync3(streamFile);
21635
+ } catch {
21494
21636
  }
21637
+ throw sendErr;
21495
21638
  }
21496
- if (msg.toolCalls) {
21497
- for (let i = 0; i < msg.toolCalls.length; i++) {
21498
- const tc = msg.toolCalls[i];
21499
- yield {
21500
- type: "tool_call_delta",
21501
- toolCallIndex: i,
21502
- toolCallId: tc.id,
21503
- toolCallName: tc.name,
21504
- toolCallArgs: JSON.stringify(tc.arguments)
21505
- };
21639
+ let isStreaming = false;
21640
+ try {
21641
+ const parsed = JSON.parse(rawResult);
21642
+ if (parsed.streaming === true) {
21643
+ isStreaming = true;
21506
21644
  }
21645
+ } catch {
21507
21646
  }
21508
- if (response.usage) {
21509
- yield {
21510
- type: "usage",
21511
- usage: {
21512
- promptTokens: response.usage.promptTokens ?? 0,
21513
- completionTokens: response.usage.completionTokens ?? 0,
21514
- totalTokens: response.usage.totalTokens
21647
+ if (!isStreaming) {
21648
+ try {
21649
+ unlinkSync3(streamFile);
21650
+ } catch {
21651
+ }
21652
+ let parsed;
21653
+ try {
21654
+ parsed = JSON.parse(rawResult);
21655
+ } catch {
21656
+ this.consecutiveFailures++;
21657
+ throw new Error(rawResult.slice(0, 500));
21658
+ }
21659
+ if (parsed.success === false) {
21660
+ this.consecutiveFailures++;
21661
+ throw new Error(`Remote inference failed: ${String(parsed.output || rawResult)}`);
21662
+ }
21663
+ this.consecutiveFailures = 0;
21664
+ const invokeResult = parsed.result;
21665
+ let responseData = null;
21666
+ if (typeof invokeResult === "string") {
21667
+ try {
21668
+ responseData = JSON.parse(invokeResult);
21669
+ } catch {
21670
+ responseData = { response: invokeResult };
21515
21671
  }
21516
- };
21672
+ } else if (invokeResult) {
21673
+ const events = Array.isArray(invokeResult) ? invokeResult : [invokeResult];
21674
+ for (const evt of events) {
21675
+ if (evt.event === "result" && evt.data) {
21676
+ const evtData = evt.data;
21677
+ try {
21678
+ responseData = typeof evtData === "string" ? JSON.parse(evtData) : evtData;
21679
+ } catch {
21680
+ responseData = { response: String(evtData) };
21681
+ }
21682
+ }
21683
+ }
21684
+ }
21685
+ const content = responseData ? responseData.response || "" : "";
21686
+ if (content) {
21687
+ const words = content.split(/(\s+)/);
21688
+ for (const word of words) {
21689
+ if (word)
21690
+ yield { type: "content", content: word };
21691
+ }
21692
+ }
21693
+ yield { type: "finish", finishReason: "stop" };
21694
+ return;
21695
+ }
21696
+ this.consecutiveFailures = 0;
21697
+ let position = 0;
21698
+ let done = false;
21699
+ const deadline = Date.now() + (request.timeoutMs ?? 12e4);
21700
+ try {
21701
+ while (!done && Date.now() < deadline) {
21702
+ await new Promise((resolve32) => {
21703
+ let resolved = false;
21704
+ const finish = () => {
21705
+ if (!resolved) {
21706
+ resolved = true;
21707
+ resolve32();
21708
+ }
21709
+ };
21710
+ let watcher = null;
21711
+ try {
21712
+ watcher = fsWatch(streamFile, { persistent: false }, () => {
21713
+ try {
21714
+ watcher?.close();
21715
+ } catch {
21716
+ }
21717
+ finish();
21718
+ });
21719
+ } catch {
21720
+ }
21721
+ setTimeout(() => {
21722
+ try {
21723
+ watcher?.close();
21724
+ } catch {
21725
+ }
21726
+ finish();
21727
+ }, 50);
21728
+ });
21729
+ const stat5 = statSync9(streamFile, { throwIfNoEntry: false });
21730
+ if (!stat5 || stat5.size <= position)
21731
+ continue;
21732
+ const fd = openSync(streamFile, "r");
21733
+ const buf = Buffer.allocUnsafe(stat5.size - position);
21734
+ readSync(fd, buf, 0, buf.length, position);
21735
+ closeSync(fd);
21736
+ position = stat5.size;
21737
+ for (const line of buf.toString("utf8").split("\n")) {
21738
+ if (!line.trim())
21739
+ continue;
21740
+ let event;
21741
+ try {
21742
+ event = JSON.parse(line);
21743
+ } catch {
21744
+ continue;
21745
+ }
21746
+ if (event.type === "token" && event.content) {
21747
+ yield { type: "content", content: event.content };
21748
+ } else if (event.type === "done") {
21749
+ done = true;
21750
+ if (event.result) {
21751
+ try {
21752
+ const r = JSON.parse(event.result);
21753
+ const choices = r.choices;
21754
+ if (choices?.[0]) {
21755
+ const msg = choices[0].message || {};
21756
+ const toolCalls = msg.tool_calls || [];
21757
+ if (toolCalls.length > 0) {
21758
+ for (let i = 0; i < toolCalls.length; i++) {
21759
+ const tc = toolCalls[i];
21760
+ const fn = tc.function || {};
21761
+ let args;
21762
+ try {
21763
+ args = typeof fn.arguments === "string" ? JSON.parse(fn.arguments) : fn.arguments ?? {};
21764
+ } catch {
21765
+ args = { _raw: fn.arguments };
21766
+ }
21767
+ yield {
21768
+ type: "tool_call_delta",
21769
+ toolCallIndex: i,
21770
+ toolCallId: tc.id || crypto.randomUUID(),
21771
+ toolCallName: fn.name,
21772
+ toolCallArgs: JSON.stringify(args)
21773
+ };
21774
+ }
21775
+ }
21776
+ }
21777
+ if (r.usage) {
21778
+ yield {
21779
+ type: "usage",
21780
+ usage: {
21781
+ promptTokens: r.usage.input_tokens ?? r.usage.prompt_tokens ?? 0,
21782
+ completionTokens: r.usage.output_tokens ?? r.usage.completion_tokens ?? 0,
21783
+ totalTokens: (r.usage.input_tokens ?? 0) + (r.usage.output_tokens ?? 0)
21784
+ }
21785
+ };
21786
+ }
21787
+ } catch {
21788
+ }
21789
+ }
21790
+ yield { type: "finish", finishReason: "stop" };
21791
+ break;
21792
+ }
21793
+ }
21794
+ }
21795
+ } finally {
21796
+ try {
21797
+ unlinkSync3(streamFile);
21798
+ } catch {
21799
+ }
21517
21800
  }
21518
- yield { type: "finish", finishReason: "stop" };
21519
21801
  }
21520
21802
  extractUsage(data) {
21521
21803
  const usage = data.usage;
@@ -22356,8 +22638,8 @@ __export(listen_exports, {
22356
22638
  waitForTranscribeCli: () => waitForTranscribeCli
22357
22639
  });
22358
22640
  import { spawn as spawn14, execSync as execSync23 } from "node:child_process";
22359
- import { existsSync as existsSync26, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, readdirSync as readdirSync6 } from "node:fs";
22360
- import { join as join34, dirname as dirname13 } from "node:path";
22641
+ import { existsSync as existsSync27, mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, readdirSync as readdirSync6 } from "node:fs";
22642
+ import { join as join35, dirname as dirname13 } from "node:path";
22361
22643
  import { homedir as homedir8 } from "node:os";
22362
22644
  import { fileURLToPath as fileURLToPath8 } from "node:url";
22363
22645
  import { EventEmitter } from "node:events";
@@ -22443,15 +22725,15 @@ function findMicCaptureCommand() {
22443
22725
  function findLiveWhisperScript() {
22444
22726
  const thisDir = dirname13(fileURLToPath8(import.meta.url));
22445
22727
  const candidates = [
22446
- join34(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
22447
- join34(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
22448
- join34(thisDir, "../../execution/scripts/live-whisper.py"),
22728
+ join35(thisDir, "../../../../packages/execution/scripts/live-whisper.py"),
22729
+ join35(thisDir, "../../../packages/execution/scripts/live-whisper.py"),
22730
+ join35(thisDir, "../../execution/scripts/live-whisper.py"),
22449
22731
  // npm install layout — scripts bundled alongside dist
22450
- join34(thisDir, "../scripts/live-whisper.py"),
22451
- join34(thisDir, "../../scripts/live-whisper.py")
22732
+ join35(thisDir, "../scripts/live-whisper.py"),
22733
+ join35(thisDir, "../../scripts/live-whisper.py")
22452
22734
  ];
22453
22735
  for (const p of candidates) {
22454
- if (existsSync26(p))
22736
+ if (existsSync27(p))
22455
22737
  return p;
22456
22738
  }
22457
22739
  try {
@@ -22461,21 +22743,21 @@ function findLiveWhisperScript() {
22461
22743
  stdio: ["pipe", "pipe", "pipe"]
22462
22744
  }).trim();
22463
22745
  const candidates2 = [
22464
- join34(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
22465
- join34(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
22746
+ join35(globalRoot, "open-agents-ai", "dist", "scripts", "live-whisper.py"),
22747
+ join35(globalRoot, "open-agents-ai", "scripts", "live-whisper.py")
22466
22748
  ];
22467
22749
  for (const p of candidates2) {
22468
- if (existsSync26(p))
22750
+ if (existsSync27(p))
22469
22751
  return p;
22470
22752
  }
22471
22753
  } catch {
22472
22754
  }
22473
- const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
22474
- if (existsSync26(nvmBase)) {
22755
+ const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
22756
+ if (existsSync27(nvmBase)) {
22475
22757
  try {
22476
22758
  for (const ver of readdirSync6(nvmBase)) {
22477
- const p = join34(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
22478
- if (existsSync26(p))
22759
+ const p = join35(nvmBase, ver, "lib", "node_modules", "open-agents-ai", "dist", "scripts", "live-whisper.py");
22760
+ if (existsSync27(p))
22479
22761
  return p;
22480
22762
  }
22481
22763
  } catch {
@@ -22493,7 +22775,7 @@ function ensureTranscribeCliBackground() {
22493
22775
  timeout: 5e3,
22494
22776
  stdio: ["pipe", "pipe", "pipe"]
22495
22777
  }).trim();
22496
- if (existsSync26(join34(globalRoot, "transcribe-cli", "dist", "index.js"))) {
22778
+ if (existsSync27(join35(globalRoot, "transcribe-cli", "dist", "index.js"))) {
22497
22779
  return true;
22498
22780
  }
22499
22781
  } catch {
@@ -22716,24 +22998,24 @@ var init_listen = __esm({
22716
22998
  timeout: 5e3,
22717
22999
  stdio: ["pipe", "pipe", "pipe"]
22718
23000
  }).trim();
22719
- const tcPath = join34(globalRoot, "transcribe-cli");
22720
- if (existsSync26(join34(tcPath, "dist", "index.js"))) {
23001
+ const tcPath = join35(globalRoot, "transcribe-cli");
23002
+ if (existsSync27(join35(tcPath, "dist", "index.js"))) {
22721
23003
  const { createRequire: createRequire4 } = await import("node:module");
22722
23004
  const req = createRequire4(import.meta.url);
22723
- return req(join34(tcPath, "dist", "index.js"));
23005
+ return req(join35(tcPath, "dist", "index.js"));
22724
23006
  }
22725
23007
  } catch {
22726
23008
  }
22727
- const nvmBase = join34(homedir8(), ".nvm", "versions", "node");
22728
- if (existsSync26(nvmBase)) {
23009
+ const nvmBase = join35(homedir8(), ".nvm", "versions", "node");
23010
+ if (existsSync27(nvmBase)) {
22729
23011
  try {
22730
23012
  const { readdirSync: readdirSync17 } = await import("node:fs");
22731
23013
  for (const ver of readdirSync17(nvmBase)) {
22732
- const tcPath = join34(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
22733
- if (existsSync26(join34(tcPath, "dist", "index.js"))) {
23014
+ const tcPath = join35(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
23015
+ if (existsSync27(join35(tcPath, "dist", "index.js"))) {
22734
23016
  const { createRequire: createRequire4 } = await import("node:module");
22735
23017
  const req = createRequire4(import.meta.url);
22736
- return req(join34(tcPath, "dist", "index.js"));
23018
+ return req(join35(tcPath, "dist", "index.js"));
22737
23019
  }
22738
23020
  }
22739
23021
  } catch {
@@ -23015,10 +23297,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
23015
23297
  });
23016
23298
  if (outputDir) {
23017
23299
  const { basename: basename16 } = await import("node:path");
23018
- const transcriptDir = join34(outputDir, ".oa", "transcripts");
23300
+ const transcriptDir = join35(outputDir, ".oa", "transcripts");
23019
23301
  mkdirSync8(transcriptDir, { recursive: true });
23020
- const outFile = join34(transcriptDir, `${basename16(filePath)}.txt`);
23021
- writeFileSync8(outFile, result.text, "utf-8");
23302
+ const outFile = join35(transcriptDir, `${basename16(filePath)}.txt`);
23303
+ writeFileSync9(outFile, result.text, "utf-8");
23022
23304
  }
23023
23305
  return {
23024
23306
  text: result.text,
@@ -25266,7 +25548,7 @@ var require_websocket = __commonJS({
25266
25548
  var http = __require("http");
25267
25549
  var net = __require("net");
25268
25550
  var tls = __require("tls");
25269
- var { randomBytes: randomBytes10, createHash: createHash5 } = __require("crypto");
25551
+ var { randomBytes: randomBytes11, createHash: createHash5 } = __require("crypto");
25270
25552
  var { Duplex, Readable } = __require("stream");
25271
25553
  var { URL: URL3 } = __require("url");
25272
25554
  var PerMessageDeflate = require_permessage_deflate();
@@ -25796,7 +26078,7 @@ var require_websocket = __commonJS({
25796
26078
  }
25797
26079
  }
25798
26080
  const defaultPort = isSecure ? 443 : 80;
25799
- const key = randomBytes10(16).toString("base64");
26081
+ const key = randomBytes11(16).toString("base64");
25800
26082
  const request = isSecure ? https.request : http.request;
25801
26083
  const protocolSet = /* @__PURE__ */ new Set();
25802
26084
  let perMessageDeflate;
@@ -28371,11 +28653,11 @@ var init_voice_session = __esm({
28371
28653
  import { createServer as createServer2, request as httpRequest } from "node:http";
28372
28654
  import { spawn as spawn16, exec } from "node:child_process";
28373
28655
  import { EventEmitter as EventEmitter3 } from "node:events";
28374
- import { randomBytes as randomBytes7 } from "node:crypto";
28656
+ import { randomBytes as randomBytes8 } from "node:crypto";
28375
28657
  import { URL as URL2 } from "node:url";
28376
28658
  import { loadavg, cpus, totalmem, freemem } from "node:os";
28377
- import { existsSync as existsSync27, readFileSync as readFileSync19, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
28378
- import { join as join35 } from "node:path";
28659
+ import { existsSync as existsSync28, readFileSync as readFileSync19, writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, mkdirSync as mkdirSync9, readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
28660
+ import { join as join36 } from "node:path";
28379
28661
  function cleanForwardHeaders(raw, targetHost) {
28380
28662
  const out = {};
28381
28663
  for (const [key, value] of Object.entries(raw)) {
@@ -28403,8 +28685,8 @@ function fmtTokens(n) {
28403
28685
  }
28404
28686
  function readExposeState(stateDir) {
28405
28687
  try {
28406
- const path = join35(stateDir, STATE_FILE_NAME);
28407
- if (!existsSync27(path))
28688
+ const path = join36(stateDir, STATE_FILE_NAME);
28689
+ if (!existsSync28(path))
28408
28690
  return null;
28409
28691
  const raw = readFileSync19(path, "utf8");
28410
28692
  const data = JSON.parse(raw);
@@ -28418,13 +28700,13 @@ function readExposeState(stateDir) {
28418
28700
  function writeExposeState(stateDir, state) {
28419
28701
  try {
28420
28702
  mkdirSync9(stateDir, { recursive: true });
28421
- writeFileSync9(join35(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
28703
+ writeFileSync10(join36(stateDir, STATE_FILE_NAME), JSON.stringify(state, null, 2));
28422
28704
  } catch {
28423
28705
  }
28424
28706
  }
28425
28707
  function removeExposeState(stateDir) {
28426
28708
  try {
28427
- unlinkSync3(join35(stateDir, STATE_FILE_NAME));
28709
+ unlinkSync4(join36(stateDir, STATE_FILE_NAME));
28428
28710
  } catch {
28429
28711
  }
28430
28712
  }
@@ -28513,8 +28795,8 @@ async function collectSystemMetricsAsync() {
28513
28795
  }
28514
28796
  function readP2PExposeState(stateDir) {
28515
28797
  try {
28516
- const path = join35(stateDir, P2P_STATE_FILE_NAME);
28517
- if (!existsSync27(path))
28798
+ const path = join36(stateDir, P2P_STATE_FILE_NAME);
28799
+ if (!existsSync28(path))
28518
28800
  return null;
28519
28801
  const raw = readFileSync19(path, "utf8");
28520
28802
  const data = JSON.parse(raw);
@@ -28528,13 +28810,13 @@ function readP2PExposeState(stateDir) {
28528
28810
  function writeP2PExposeState(stateDir, state) {
28529
28811
  try {
28530
28812
  mkdirSync9(stateDir, { recursive: true });
28531
- writeFileSync9(join35(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
28813
+ writeFileSync10(join36(stateDir, P2P_STATE_FILE_NAME), JSON.stringify(state, null, 2));
28532
28814
  } catch {
28533
28815
  }
28534
28816
  }
28535
28817
  function removeP2PExposeState(stateDir) {
28536
28818
  try {
28537
- unlinkSync3(join35(stateDir, P2P_STATE_FILE_NAME));
28819
+ unlinkSync4(join36(stateDir, P2P_STATE_FILE_NAME));
28538
28820
  } catch {
28539
28821
  }
28540
28822
  }
@@ -28616,7 +28898,7 @@ var init_expose = __esm({
28616
28898
  this._stateDir = options.stateDir ?? null;
28617
28899
  this._fullAccess = options.fullAccess ?? false;
28618
28900
  if (options.authKey === void 0 || options.authKey === "") {
28619
- this._authKey = randomBytes7(24).toString("base64url");
28901
+ this._authKey = randomBytes8(24).toString("base64url");
28620
28902
  } else {
28621
28903
  this._authKey = options.authKey;
28622
28904
  }
@@ -29324,7 +29606,7 @@ ${this.formatConnectionInfo()}`);
29324
29606
  this._onInfo = options.onInfo;
29325
29607
  this._onError = options.onError;
29326
29608
  if (options.authKey === void 0 || options.authKey === "") {
29327
- this._authKey = randomBytes7(24).toString("base64url");
29609
+ this._authKey = randomBytes8(24).toString("base64url");
29328
29610
  } else {
29329
29611
  this._authKey = options.authKey;
29330
29612
  }
@@ -29362,7 +29644,7 @@ ${this.formatConnectionInfo()}`);
29362
29644
  throw new Error(`Expose failed: ${exposeResult.error}`);
29363
29645
  }
29364
29646
  const nexusDir = this._nexusTool.getNexusDir();
29365
- const statusPath = join35(nexusDir, "status.json");
29647
+ const statusPath = join36(nexusDir, "status.json");
29366
29648
  for (let i = 0; i < 80; i++) {
29367
29649
  try {
29368
29650
  const raw = readFileSync19(statusPath, "utf8");
@@ -29396,8 +29678,8 @@ ${this.formatConnectionInfo()}`);
29396
29678
  });
29397
29679
  }
29398
29680
  try {
29399
- const invocDir = join35(nexusDir, "invocations");
29400
- if (existsSync27(invocDir)) {
29681
+ const invocDir = join36(nexusDir, "invocations");
29682
+ if (existsSync28(invocDir)) {
29401
29683
  this._prevInvocCount = readdirSync7(invocDir).filter((f) => f.endsWith(".json")).length;
29402
29684
  this._stats.totalRequests = this._prevInvocCount;
29403
29685
  }
@@ -29426,9 +29708,9 @@ ${this.formatConnectionInfo()}`);
29426
29708
  if (!state)
29427
29709
  return null;
29428
29710
  const nexusDir = nexusTool.getNexusDir();
29429
- const statusPath = join35(nexusDir, "status.json");
29711
+ const statusPath = join36(nexusDir, "status.json");
29430
29712
  try {
29431
- if (!existsSync27(statusPath)) {
29713
+ if (!existsSync28(statusPath)) {
29432
29714
  removeP2PExposeState(stateDir);
29433
29715
  return null;
29434
29716
  }
@@ -29485,8 +29767,8 @@ ${this.formatConnectionInfo()}`);
29485
29767
  let lastMeteringLineCount = 0;
29486
29768
  this._activityPollTimer = setInterval(() => {
29487
29769
  try {
29488
- const invocDir = join35(nexusDir, "invocations");
29489
- if (!existsSync27(invocDir))
29770
+ const invocDir = join36(nexusDir, "invocations");
29771
+ if (!existsSync28(invocDir))
29490
29772
  return;
29491
29773
  const files = readdirSync7(invocDir).filter((f) => f.endsWith(".json"));
29492
29774
  const invocCount = files.length;
@@ -29501,16 +29783,16 @@ ${this.formatConnectionInfo()}`);
29501
29783
  let recentActive = 0;
29502
29784
  for (const f of files.slice(-10)) {
29503
29785
  try {
29504
- const st = statSync9(join35(invocDir, f));
29786
+ const st = statSync10(join36(invocDir, f));
29505
29787
  if (now - st.mtimeMs < 1e4)
29506
29788
  recentActive++;
29507
29789
  } catch {
29508
29790
  }
29509
29791
  }
29510
- const meteringFile = join35(nexusDir, "metering.jsonl");
29792
+ const meteringFile = join36(nexusDir, "metering.jsonl");
29511
29793
  let meteringLines = lastMeteringLineCount;
29512
29794
  try {
29513
- if (existsSync27(meteringFile)) {
29795
+ if (existsSync28(meteringFile)) {
29514
29796
  const content = readFileSync19(meteringFile, "utf8");
29515
29797
  meteringLines = content.split("\n").filter((l) => l.trim()).length;
29516
29798
  }
@@ -29537,8 +29819,8 @@ ${this.formatConnectionInfo()}`);
29537
29819
  this._activityPollTimer.unref();
29538
29820
  this._pollTimer = setInterval(() => {
29539
29821
  try {
29540
- const statusPath = join35(nexusDir, "status.json");
29541
- if (existsSync27(statusPath)) {
29822
+ const statusPath = join36(nexusDir, "status.json");
29823
+ if (existsSync28(statusPath)) {
29542
29824
  const status = JSON.parse(readFileSync19(statusPath, "utf8"));
29543
29825
  if (status.peerId && !this._peerId) {
29544
29826
  this._peerId = status.peerId;
@@ -29548,8 +29830,8 @@ ${this.formatConnectionInfo()}`);
29548
29830
  } catch {
29549
29831
  }
29550
29832
  try {
29551
- const invocDir = join35(nexusDir, "invocations");
29552
- if (existsSync27(invocDir)) {
29833
+ const invocDir = join36(nexusDir, "invocations");
29834
+ if (existsSync28(invocDir)) {
29553
29835
  const files = readdirSync7(invocDir);
29554
29836
  const invocCount = files.filter((f) => f.endsWith(".json")).length;
29555
29837
  if (invocCount > this._stats.totalRequests) {
@@ -29560,8 +29842,8 @@ ${this.formatConnectionInfo()}`);
29560
29842
  } catch {
29561
29843
  }
29562
29844
  try {
29563
- const meteringFile = join35(nexusDir, "metering.jsonl");
29564
- if (existsSync27(meteringFile)) {
29845
+ const meteringFile = join36(nexusDir, "metering.jsonl");
29846
+ if (existsSync28(meteringFile)) {
29565
29847
  const content = readFileSync19(meteringFile, "utf8");
29566
29848
  if (content.length > lastMeteringSize) {
29567
29849
  const newContent = content.slice(lastMeteringSize);
@@ -29778,9 +30060,9 @@ var init_types = __esm({
29778
30060
  });
29779
30061
 
29780
30062
  // packages/cli/dist/tui/p2p/secret-vault.js
29781
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes8, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
29782
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync10, existsSync as existsSync28, mkdirSync as mkdirSync10 } from "node:fs";
29783
- import { join as join36, dirname as dirname14 } from "node:path";
30063
+ import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes9, scryptSync as scryptSync2, createHash as createHash2 } from "node:crypto";
30064
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync11, existsSync as existsSync29, mkdirSync as mkdirSync10 } from "node:fs";
30065
+ import { join as join37, dirname as dirname14 } from "node:path";
29784
30066
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
29785
30067
  var init_secret_vault = __esm({
29786
30068
  "packages/cli/dist/tui/p2p/secret-vault.js"() {
@@ -29984,24 +30266,24 @@ var init_secret_vault = __esm({
29984
30266
  minTrust: s.minTrust,
29985
30267
  createdAt: s.createdAt
29986
30268
  })));
29987
- const salt = randomBytes8(SALT_LEN);
30269
+ const salt = randomBytes9(SALT_LEN);
29988
30270
  const key = scryptSync2(passphrase, salt, KEY_LEN);
29989
- const iv = randomBytes8(IV_LEN);
30271
+ const iv = randomBytes9(IV_LEN);
29990
30272
  const cipher = createCipheriv2(CIPHER_ALGO, key, iv);
29991
30273
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
29992
30274
  const tag = cipher.getAuthTag();
29993
30275
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
29994
30276
  const dir = dirname14(this.storePath);
29995
- if (!existsSync28(dir))
30277
+ if (!existsSync29(dir))
29996
30278
  mkdirSync10(dir, { recursive: true });
29997
- writeFileSync10(this.storePath, blob, { mode: 384 });
30279
+ writeFileSync11(this.storePath, blob, { mode: 384 });
29998
30280
  }
29999
30281
  /**
30000
30282
  * Load vault from disk, decrypting with the given passphrase.
30001
30283
  * Returns the number of secrets loaded.
30002
30284
  */
30003
30285
  load(passphrase) {
30004
- if (!this.storePath || !existsSync28(this.storePath))
30286
+ if (!this.storePath || !existsSync29(this.storePath))
30005
30287
  return 0;
30006
30288
  const blob = readFileSync20(this.storePath);
30007
30289
  if (blob.length < SALT_LEN + IV_LEN + 16) {
@@ -30044,7 +30326,7 @@ var init_secret_vault = __esm({
30044
30326
  // packages/cli/dist/tui/p2p/peer-mesh.js
30045
30327
  import { EventEmitter as EventEmitter4 } from "node:events";
30046
30328
  import { createServer as createServer3 } from "node:http";
30047
- import { randomBytes as randomBytes9, createHash as createHash3, generateKeyPairSync } from "node:crypto";
30329
+ import { randomBytes as randomBytes10, createHash as createHash3, generateKeyPairSync } from "node:crypto";
30048
30330
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
30049
30331
  var init_peer_mesh = __esm({
30050
30332
  "packages/cli/dist/tui/p2p/peer-mesh.js"() {
@@ -30096,7 +30378,7 @@ var init_peer_mesh = __esm({
30096
30378
  this.peerId = createHash3("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
30097
30379
  this.capabilities = options.capabilities;
30098
30380
  this.displayName = options.displayName;
30099
- this._authKey = options.authKey ?? randomBytes9(24).toString("base64url");
30381
+ this._authKey = options.authKey ?? randomBytes10(24).toString("base64url");
30100
30382
  }
30101
30383
  // ── Lifecycle ───────────────────────────────────────────────────────────
30102
30384
  /** Start the mesh node — creates WS server and connects to bootstrap peers */
@@ -30260,7 +30542,7 @@ var init_peer_mesh = __esm({
30260
30542
  if (!ws || ws.readyState !== import_websocket.default.OPEN) {
30261
30543
  throw new Error(`Peer ${peerId} not connected`);
30262
30544
  }
30263
- const msgId = randomBytes9(8).toString("hex");
30545
+ const msgId = randomBytes10(8).toString("hex");
30264
30546
  return new Promise((resolve32, reject) => {
30265
30547
  const timeout = setTimeout(() => {
30266
30548
  this.pendingRequests.delete(msgId);
@@ -30481,7 +30763,7 @@ var init_peer_mesh = __esm({
30481
30763
  const msg = {
30482
30764
  type,
30483
30765
  from: this.peerId,
30484
- msgId: msgId ?? randomBytes9(8).toString("hex"),
30766
+ msgId: msgId ?? randomBytes10(8).toString("hex"),
30485
30767
  ts: (/* @__PURE__ */ new Date()).toISOString(),
30486
30768
  payload
30487
30769
  };
@@ -31116,15 +31398,15 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
31116
31398
  async function fetchPeerModels(peerId, authKey) {
31117
31399
  try {
31118
31400
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
31119
- const { existsSync: existsSync44, readFileSync: readFileSync32 } = await import("node:fs");
31120
- const { join: join56 } = await import("node:path");
31401
+ const { existsSync: existsSync45, readFileSync: readFileSync32 } = await import("node:fs");
31402
+ const { join: join57 } = await import("node:path");
31121
31403
  const cwd4 = process.cwd();
31122
31404
  const nexusTool = new NexusTool2(cwd4);
31123
31405
  const nexusDir = nexusTool.getNexusDir();
31124
31406
  let isLocalPeer = false;
31125
31407
  try {
31126
- const statusPath = join56(nexusDir, "status.json");
31127
- if (existsSync44(statusPath)) {
31408
+ const statusPath = join57(nexusDir, "status.json");
31409
+ if (existsSync45(statusPath)) {
31128
31410
  const status = JSON.parse(readFileSync32(statusPath, "utf8"));
31129
31411
  if (status.peerId === peerId)
31130
31412
  isLocalPeer = true;
@@ -31132,8 +31414,8 @@ async function fetchPeerModels(peerId, authKey) {
31132
31414
  } catch {
31133
31415
  }
31134
31416
  if (isLocalPeer) {
31135
- const pricingPath = join56(nexusDir, "pricing.json");
31136
- if (existsSync44(pricingPath)) {
31417
+ const pricingPath = join57(nexusDir, "pricing.json");
31418
+ if (existsSync45(pricingPath)) {
31137
31419
  try {
31138
31420
  const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
31139
31421
  const localModels = (pricing.models || []).map((m) => ({
@@ -31149,8 +31431,8 @@ async function fetchPeerModels(peerId, authKey) {
31149
31431
  }
31150
31432
  }
31151
31433
  }
31152
- const cachePath = join56(nexusDir, "peer-models-cache.json");
31153
- if (existsSync44(cachePath)) {
31434
+ const cachePath = join57(nexusDir, "peer-models-cache.json");
31435
+ if (existsSync45(cachePath)) {
31154
31436
  try {
31155
31437
  const cache4 = JSON.parse(readFileSync32(cachePath, "utf8"));
31156
31438
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
@@ -31267,8 +31549,8 @@ async function fetchPeerModels(peerId, authKey) {
31267
31549
  } catch {
31268
31550
  }
31269
31551
  if (isLocalPeer) {
31270
- const pricingPath = join56(nexusDir, "pricing.json");
31271
- if (existsSync44(pricingPath)) {
31552
+ const pricingPath = join57(nexusDir, "pricing.json");
31553
+ if (existsSync45(pricingPath)) {
31272
31554
  try {
31273
31555
  const pricing = JSON.parse(readFileSync32(pricingPath, "utf8"));
31274
31556
  return (pricing.models || []).map((m) => ({
@@ -31539,14 +31821,14 @@ var init_render2 = __esm({
31539
31821
  });
31540
31822
 
31541
31823
  // packages/prompts/dist/promptLoader.js
31542
- import { readFileSync as readFileSync21, existsSync as existsSync29 } from "node:fs";
31543
- import { join as join37, dirname as dirname15 } from "node:path";
31824
+ import { readFileSync as readFileSync21, existsSync as existsSync30 } from "node:fs";
31825
+ import { join as join38, dirname as dirname15 } from "node:path";
31544
31826
  import { fileURLToPath as fileURLToPath9 } from "node:url";
31545
31827
  function loadPrompt2(promptPath, vars) {
31546
31828
  let content = cache2.get(promptPath);
31547
31829
  if (content === void 0) {
31548
- const fullPath = join37(PROMPTS_DIR2, promptPath);
31549
- if (!existsSync29(fullPath)) {
31830
+ const fullPath = join38(PROMPTS_DIR2, promptPath);
31831
+ if (!existsSync30(fullPath)) {
31550
31832
  throw new Error(`Prompt file not found: ${fullPath}`);
31551
31833
  }
31552
31834
  content = readFileSync21(fullPath, "utf-8");
@@ -31562,9 +31844,9 @@ var init_promptLoader2 = __esm({
31562
31844
  "use strict";
31563
31845
  __filename2 = fileURLToPath9(import.meta.url);
31564
31846
  __dirname5 = dirname15(__filename2);
31565
- devPath = join37(__dirname5, "..", "templates");
31566
- publishedPath = join37(__dirname5, "..", "prompts", "templates");
31567
- PROMPTS_DIR2 = existsSync29(devPath) ? devPath : publishedPath;
31847
+ devPath = join38(__dirname5, "..", "templates");
31848
+ publishedPath = join38(__dirname5, "..", "prompts", "templates");
31849
+ PROMPTS_DIR2 = existsSync30(devPath) ? devPath : publishedPath;
31568
31850
  cache2 = /* @__PURE__ */ new Map();
31569
31851
  }
31570
31852
  });
@@ -31675,7 +31957,7 @@ var init_task_templates = __esm({
31675
31957
  });
31676
31958
 
31677
31959
  // packages/prompts/dist/index.js
31678
- import { join as join38, dirname as dirname16 } from "node:path";
31960
+ import { join as join39, dirname as dirname16 } from "node:path";
31679
31961
  import { fileURLToPath as fileURLToPath10 } from "node:url";
31680
31962
  var _dir, _packageRoot;
31681
31963
  var init_dist6 = __esm({
@@ -31686,26 +31968,26 @@ var init_dist6 = __esm({
31686
31968
  init_task_templates();
31687
31969
  init_render2();
31688
31970
  _dir = dirname16(fileURLToPath10(import.meta.url));
31689
- _packageRoot = join38(_dir, "..");
31971
+ _packageRoot = join39(_dir, "..");
31690
31972
  }
31691
31973
  });
31692
31974
 
31693
31975
  // packages/cli/dist/tui/oa-directory.js
31694
- import { existsSync as existsSync30, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync11, readdirSync as readdirSync8, statSync as statSync10, unlinkSync as unlinkSync4 } from "node:fs";
31695
- import { join as join39, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
31976
+ import { existsSync as existsSync31, mkdirSync as mkdirSync11, readFileSync as readFileSync22, writeFileSync as writeFileSync12, readdirSync as readdirSync8, statSync as statSync11, unlinkSync as unlinkSync5 } from "node:fs";
31977
+ import { join as join40, relative as relative2, basename as basename9, extname as extname8 } from "node:path";
31696
31978
  import { homedir as homedir9 } from "node:os";
31697
31979
  function initOaDirectory(repoRoot) {
31698
- const oaPath = join39(repoRoot, OA_DIR);
31980
+ const oaPath = join40(repoRoot, OA_DIR);
31699
31981
  for (const sub of SUBDIRS) {
31700
- mkdirSync11(join39(oaPath, sub), { recursive: true });
31982
+ mkdirSync11(join40(oaPath, sub), { recursive: true });
31701
31983
  }
31702
31984
  try {
31703
- const gitignorePath = join39(repoRoot, ".gitignore");
31985
+ const gitignorePath = join40(repoRoot, ".gitignore");
31704
31986
  const settingsPattern = ".oa/settings.json";
31705
- if (existsSync30(gitignorePath)) {
31987
+ if (existsSync31(gitignorePath)) {
31706
31988
  const content = readFileSync22(gitignorePath, "utf-8");
31707
31989
  if (!content.includes(settingsPattern)) {
31708
- writeFileSync11(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
31990
+ writeFileSync12(gitignorePath, content.trimEnd() + "\n" + settingsPattern + "\n", "utf-8");
31709
31991
  }
31710
31992
  }
31711
31993
  } catch {
@@ -31713,12 +31995,12 @@ function initOaDirectory(repoRoot) {
31713
31995
  return oaPath;
31714
31996
  }
31715
31997
  function hasOaDirectory(repoRoot) {
31716
- return existsSync30(join39(repoRoot, OA_DIR, "index"));
31998
+ return existsSync31(join40(repoRoot, OA_DIR, "index"));
31717
31999
  }
31718
32000
  function loadProjectSettings(repoRoot) {
31719
- const settingsPath = join39(repoRoot, OA_DIR, "settings.json");
32001
+ const settingsPath = join40(repoRoot, OA_DIR, "settings.json");
31720
32002
  try {
31721
- if (existsSync30(settingsPath)) {
32003
+ if (existsSync31(settingsPath)) {
31722
32004
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
31723
32005
  }
31724
32006
  } catch {
@@ -31726,16 +32008,16 @@ function loadProjectSettings(repoRoot) {
31726
32008
  return {};
31727
32009
  }
31728
32010
  function saveProjectSettings(repoRoot, settings) {
31729
- const oaPath = join39(repoRoot, OA_DIR);
32011
+ const oaPath = join40(repoRoot, OA_DIR);
31730
32012
  mkdirSync11(oaPath, { recursive: true });
31731
32013
  const existing = loadProjectSettings(repoRoot);
31732
32014
  const merged = { ...existing, ...settings };
31733
- writeFileSync11(join39(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32015
+ writeFileSync12(join40(oaPath, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
31734
32016
  }
31735
32017
  function loadGlobalSettings() {
31736
- const settingsPath = join39(homedir9(), ".open-agents", "settings.json");
32018
+ const settingsPath = join40(homedir9(), ".open-agents", "settings.json");
31737
32019
  try {
31738
- if (existsSync30(settingsPath)) {
32020
+ if (existsSync31(settingsPath)) {
31739
32021
  return JSON.parse(readFileSync22(settingsPath, "utf-8"));
31740
32022
  }
31741
32023
  } catch {
@@ -31743,11 +32025,11 @@ function loadGlobalSettings() {
31743
32025
  return {};
31744
32026
  }
31745
32027
  function saveGlobalSettings(settings) {
31746
- const dir = join39(homedir9(), ".open-agents");
32028
+ const dir = join40(homedir9(), ".open-agents");
31747
32029
  mkdirSync11(dir, { recursive: true });
31748
32030
  const existing = loadGlobalSettings();
31749
32031
  const merged = { ...existing, ...settings };
31750
- writeFileSync11(join39(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32032
+ writeFileSync12(join40(dir, "settings.json"), JSON.stringify(merged, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
31751
32033
  }
31752
32034
  function resolveSettings(repoRoot) {
31753
32035
  const global = loadGlobalSettings();
@@ -31762,9 +32044,9 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
31762
32044
  while (dir && !visited.has(dir)) {
31763
32045
  visited.add(dir);
31764
32046
  for (const name of CONTEXT_FILES) {
31765
- const filePath = join39(dir, name);
32047
+ const filePath = join40(dir, name);
31766
32048
  const normalizedName = name.toLowerCase();
31767
- if (existsSync30(filePath) && !seen.has(filePath)) {
32049
+ if (existsSync31(filePath) && !seen.has(filePath)) {
31768
32050
  seen.add(filePath);
31769
32051
  try {
31770
32052
  let content = readFileSync22(filePath, "utf-8");
@@ -31781,8 +32063,8 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
31781
32063
  }
31782
32064
  }
31783
32065
  }
31784
- const projectMap = join39(dir, OA_DIR, "context", "project-map.md");
31785
- if (existsSync30(projectMap) && !seen.has(projectMap)) {
32066
+ const projectMap = join40(dir, OA_DIR, "context", "project-map.md");
32067
+ if (existsSync31(projectMap) && !seen.has(projectMap)) {
31786
32068
  seen.add(projectMap);
31787
32069
  try {
31788
32070
  let content = readFileSync22(projectMap, "utf-8");
@@ -31797,7 +32079,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
31797
32079
  } catch {
31798
32080
  }
31799
32081
  }
31800
- const parent = join39(dir, "..");
32082
+ const parent = join40(dir, "..");
31801
32083
  if (parent === dir)
31802
32084
  break;
31803
32085
  dir = parent;
@@ -31815,7 +32097,7 @@ function discoverContextFiles(repoRoot, maxContentLen = 8e3) {
31815
32097
  return found;
31816
32098
  }
31817
32099
  function readIndexMeta(repoRoot) {
31818
- const metaPath = join39(repoRoot, OA_DIR, "index", "meta.json");
32100
+ const metaPath = join40(repoRoot, OA_DIR, "index", "meta.json");
31819
32101
  try {
31820
32102
  return JSON.parse(readFileSync22(metaPath, "utf-8"));
31821
32103
  } catch {
@@ -31868,28 +32150,28 @@ ${tree}\`\`\`
31868
32150
  sections.push("");
31869
32151
  }
31870
32152
  const content = sections.join("\n");
31871
- const contextDir = join39(repoRoot, OA_DIR, "context");
32153
+ const contextDir = join40(repoRoot, OA_DIR, "context");
31872
32154
  mkdirSync11(contextDir, { recursive: true });
31873
- writeFileSync11(join39(contextDir, "project-map.md"), content, "utf-8");
32155
+ writeFileSync12(join40(contextDir, "project-map.md"), content, "utf-8");
31874
32156
  return content;
31875
32157
  }
31876
32158
  function saveSession(repoRoot, session) {
31877
- const historyDir = join39(repoRoot, OA_DIR, "history");
32159
+ const historyDir = join40(repoRoot, OA_DIR, "history");
31878
32160
  mkdirSync11(historyDir, { recursive: true });
31879
- writeFileSync11(join39(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
32161
+ writeFileSync12(join40(historyDir, `${session.id}.json`), JSON.stringify(session, null, 2), "utf-8");
31880
32162
  }
31881
32163
  function loadRecentSessions(repoRoot, limit = 5) {
31882
- const historyDir = join39(repoRoot, OA_DIR, "history");
31883
- if (!existsSync30(historyDir))
32164
+ const historyDir = join40(repoRoot, OA_DIR, "history");
32165
+ if (!existsSync31(historyDir))
31884
32166
  return [];
31885
32167
  try {
31886
32168
  const files = readdirSync8(historyDir).filter((f) => f.endsWith(".json") && f !== "pending-task.json").map((f) => {
31887
- const stat5 = statSync10(join39(historyDir, f));
32169
+ const stat5 = statSync11(join40(historyDir, f));
31888
32170
  return { file: f, mtime: stat5.mtimeMs };
31889
32171
  }).sort((a, b) => b.mtime - a.mtime).slice(0, limit);
31890
32172
  return files.map((f) => {
31891
32173
  try {
31892
- return JSON.parse(readFileSync22(join39(historyDir, f.file), "utf-8"));
32174
+ return JSON.parse(readFileSync22(join40(historyDir, f.file), "utf-8"));
31893
32175
  } catch {
31894
32176
  return null;
31895
32177
  }
@@ -31899,18 +32181,18 @@ function loadRecentSessions(repoRoot, limit = 5) {
31899
32181
  }
31900
32182
  }
31901
32183
  function savePendingTask(repoRoot, task) {
31902
- const historyDir = join39(repoRoot, OA_DIR, "history");
32184
+ const historyDir = join40(repoRoot, OA_DIR, "history");
31903
32185
  mkdirSync11(historyDir, { recursive: true });
31904
- writeFileSync11(join39(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
32186
+ writeFileSync12(join40(historyDir, PENDING_TASK_FILE), JSON.stringify(task, null, 2) + "\n", "utf-8");
31905
32187
  }
31906
32188
  function loadPendingTask(repoRoot) {
31907
- const filePath = join39(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
32189
+ const filePath = join40(repoRoot, OA_DIR, "history", PENDING_TASK_FILE);
31908
32190
  try {
31909
- if (!existsSync30(filePath))
32191
+ if (!existsSync31(filePath))
31910
32192
  return null;
31911
32193
  const data = JSON.parse(readFileSync22(filePath, "utf-8"));
31912
32194
  try {
31913
- unlinkSync4(filePath);
32195
+ unlinkSync5(filePath);
31914
32196
  } catch {
31915
32197
  }
31916
32198
  return data;
@@ -31919,12 +32201,12 @@ function loadPendingTask(repoRoot) {
31919
32201
  }
31920
32202
  }
31921
32203
  function saveSessionContext(repoRoot, entry) {
31922
- const contextDir = join39(repoRoot, OA_DIR, "context");
32204
+ const contextDir = join40(repoRoot, OA_DIR, "context");
31923
32205
  mkdirSync11(contextDir, { recursive: true });
31924
- const filePath = join39(contextDir, CONTEXT_SAVE_FILE);
32206
+ const filePath = join40(contextDir, CONTEXT_SAVE_FILE);
31925
32207
  let ctx;
31926
32208
  try {
31927
- if (existsSync30(filePath)) {
32209
+ if (existsSync31(filePath)) {
31928
32210
  ctx = JSON.parse(readFileSync22(filePath, "utf-8"));
31929
32211
  } else {
31930
32212
  ctx = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
@@ -31937,12 +32219,12 @@ function saveSessionContext(repoRoot, entry) {
31937
32219
  ctx.entries = ctx.entries.slice(-ctx.maxEntries);
31938
32220
  }
31939
32221
  ctx.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
31940
- writeFileSync11(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
32222
+ writeFileSync12(filePath, JSON.stringify(ctx, null, 2) + "\n", "utf-8");
31941
32223
  }
31942
32224
  function loadSessionContext(repoRoot) {
31943
- const filePath = join39(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
32225
+ const filePath = join40(repoRoot, OA_DIR, "context", CONTEXT_SAVE_FILE);
31944
32226
  try {
31945
- if (!existsSync30(filePath))
32227
+ if (!existsSync31(filePath))
31946
32228
  return null;
31947
32229
  return JSON.parse(readFileSync22(filePath, "utf-8"));
31948
32230
  } catch {
@@ -31991,8 +32273,8 @@ function detectManifests(repoRoot) {
31991
32273
  { file: "docker-compose.yaml", type: "Docker Compose" }
31992
32274
  ];
31993
32275
  for (const check of checks) {
31994
- const filePath = join39(repoRoot, check.file);
31995
- if (existsSync30(filePath)) {
32276
+ const filePath = join40(repoRoot, check.file);
32277
+ if (existsSync31(filePath)) {
31996
32278
  let name;
31997
32279
  if (check.nameField) {
31998
32280
  try {
@@ -32025,7 +32307,7 @@ function findKeyFiles(repoRoot) {
32025
32307
  { pattern: "CLAUDE.md", description: "Claude Code context" }
32026
32308
  ];
32027
32309
  for (const check of checks) {
32028
- if (existsSync30(join39(repoRoot, check.pattern))) {
32310
+ if (existsSync31(join40(repoRoot, check.pattern))) {
32029
32311
  keyFiles.push({ path: check.pattern, description: check.description });
32030
32312
  }
32031
32313
  }
@@ -32051,12 +32333,12 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
32051
32333
  if (entry.isDirectory()) {
32052
32334
  let fileCount = 0;
32053
32335
  try {
32054
- fileCount = readdirSync8(join39(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32336
+ fileCount = readdirSync8(join40(root, entry.name)).filter((f) => !f.startsWith(".")).length;
32055
32337
  } catch {
32056
32338
  }
32057
32339
  result += `${prefix}${connector}${entry.name}/ (${fileCount})
32058
32340
  `;
32059
- result += buildDirTree(join39(root, entry.name), maxDepth, childPrefix, depth + 1);
32341
+ result += buildDirTree(join40(root, entry.name), maxDepth, childPrefix, depth + 1);
32060
32342
  } else if (depth < maxDepth) {
32061
32343
  result += `${prefix}${connector}${entry.name}
32062
32344
  `;
@@ -32068,7 +32350,7 @@ function buildDirTree(root, maxDepth, prefix = "", depth = 0) {
32068
32350
  }
32069
32351
  function loadUsageFile(filePath) {
32070
32352
  try {
32071
- if (existsSync30(filePath)) {
32353
+ if (existsSync31(filePath)) {
32072
32354
  return JSON.parse(readFileSync22(filePath, "utf-8"));
32073
32355
  }
32074
32356
  } catch {
@@ -32076,9 +32358,9 @@ function loadUsageFile(filePath) {
32076
32358
  return { records: [] };
32077
32359
  }
32078
32360
  function saveUsageFile(filePath, data) {
32079
- const dir = join39(filePath, "..");
32361
+ const dir = join40(filePath, "..");
32080
32362
  mkdirSync11(dir, { recursive: true });
32081
- writeFileSync11(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32363
+ writeFileSync12(filePath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
32082
32364
  }
32083
32365
  function recordUsage(kind, value, opts) {
32084
32366
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -32106,15 +32388,15 @@ function recordUsage(kind, value, opts) {
32106
32388
  }
32107
32389
  saveUsageFile(filePath, data);
32108
32390
  };
32109
- update(join39(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32391
+ update(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32110
32392
  if (opts?.repoRoot) {
32111
- update(join39(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32393
+ update(join40(opts.repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32112
32394
  }
32113
32395
  }
32114
32396
  function loadUsageHistory(kind, repoRoot) {
32115
- const globalPath = join39(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32397
+ const globalPath = join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE);
32116
32398
  const globalData = loadUsageFile(globalPath);
32117
- const localData = repoRoot ? loadUsageFile(join39(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32399
+ const localData = repoRoot ? loadUsageFile(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE)) : { records: [] };
32118
32400
  const map = /* @__PURE__ */ new Map();
32119
32401
  for (const r of globalData.records) {
32120
32402
  if (r.kind !== kind)
@@ -32145,9 +32427,9 @@ function deleteUsageRecord(kind, value, repoRoot) {
32145
32427
  saveUsageFile(filePath, data);
32146
32428
  }
32147
32429
  };
32148
- remove(join39(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32430
+ remove(join40(homedir9(), ".open-agents", USAGE_HISTORY_FILE));
32149
32431
  if (repoRoot) {
32150
- remove(join39(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32432
+ remove(join40(repoRoot, OA_DIR, USAGE_HISTORY_FILE));
32151
32433
  }
32152
32434
  }
32153
32435
  var OA_DIR, SUBDIRS, CONTEXT_FILES, PENDING_TASK_FILE, CONTEXT_SAVE_FILE, MAX_CONTEXT_ENTRIES, SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
@@ -32197,8 +32479,8 @@ var init_oa_directory = __esm({
32197
32479
  import * as readline from "node:readline";
32198
32480
  import { execSync as execSync25, spawn as spawn17, exec as exec2 } from "node:child_process";
32199
32481
  import { promisify as promisify5 } from "node:util";
32200
- import { existsSync as existsSync31, writeFileSync as writeFileSync12, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
32201
- import { join as join40 } from "node:path";
32482
+ import { existsSync as existsSync32, writeFileSync as writeFileSync13, readFileSync as readFileSync23, appendFileSync as appendFileSync2, mkdirSync as mkdirSync12 } from "node:fs";
32483
+ import { join as join41 } from "node:path";
32202
32484
  import { homedir as homedir10, platform } from "node:os";
32203
32485
  function detectSystemSpecs() {
32204
32486
  let totalRamGB = 0;
@@ -32485,7 +32767,7 @@ async function installOllamaMac(_rl) {
32485
32767
  execSync25('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { stdio: "inherit", timeout: 6e5 });
32486
32768
  if (!hasCmd("brew")) {
32487
32769
  try {
32488
- const brewPrefix = existsSync31("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
32770
+ const brewPrefix = existsSync32("/opt/homebrew/bin/brew") ? "/opt/homebrew" : "/usr/local";
32489
32771
  process.env["PATH"] = `${brewPrefix}/bin:${process.env["PATH"]}`;
32490
32772
  } catch {
32491
32773
  }
@@ -33239,10 +33521,10 @@ async function doSetup(config, rl) {
33239
33521
  `PARAMETER num_predict ${numPredict}`,
33240
33522
  `PARAMETER stop "<|endoftext|>"`
33241
33523
  ].join("\n");
33242
- const modelDir2 = join40(homedir10(), ".open-agents", "models");
33524
+ const modelDir2 = join41(homedir10(), ".open-agents", "models");
33243
33525
  mkdirSync12(modelDir2, { recursive: true });
33244
- const modelfilePath = join40(modelDir2, `Modelfile.${customName}`);
33245
- writeFileSync12(modelfilePath, modelfileContent + "\n", "utf8");
33526
+ const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
33527
+ writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
33246
33528
  process.stdout.write(` ${c2.dim("Creating model...")} `);
33247
33529
  execSync25(`ollama create ${customName} -f ${modelfilePath}`, {
33248
33530
  stdio: "pipe",
@@ -33287,7 +33569,7 @@ async function isModelAvailable(config) {
33287
33569
  }
33288
33570
  function isFirstRun() {
33289
33571
  try {
33290
- return !existsSync31(join40(homedir10(), ".open-agents", "config.json"));
33572
+ return !existsSync32(join41(homedir10(), ".open-agents", "config.json"));
33291
33573
  } catch {
33292
33574
  return true;
33293
33575
  }
@@ -33324,7 +33606,7 @@ function detectPkgManager() {
33324
33606
  return null;
33325
33607
  }
33326
33608
  function getVenvDir() {
33327
- return join40(homedir10(), ".open-agents", "venv");
33609
+ return join41(homedir10(), ".open-agents", "venv");
33328
33610
  }
33329
33611
  function hasVenvModule() {
33330
33612
  try {
@@ -33336,8 +33618,8 @@ function hasVenvModule() {
33336
33618
  }
33337
33619
  function ensureVenv(log) {
33338
33620
  const venvDir = getVenvDir();
33339
- const venvPip = join40(venvDir, "bin", "pip");
33340
- if (existsSync31(venvPip))
33621
+ const venvPip = join41(venvDir, "bin", "pip");
33622
+ if (existsSync32(venvPip))
33341
33623
  return venvDir;
33342
33624
  log("Creating Python venv for vision deps...");
33343
33625
  if (!hasCmd("python3")) {
@@ -33349,9 +33631,9 @@ function ensureVenv(log) {
33349
33631
  return null;
33350
33632
  }
33351
33633
  try {
33352
- mkdirSync12(join40(homedir10(), ".open-agents"), { recursive: true });
33634
+ mkdirSync12(join41(homedir10(), ".open-agents"), { recursive: true });
33353
33635
  execSync25(`python3 -m venv "${venvDir}"`, { stdio: "pipe", timeout: 3e4 });
33354
- execSync25(`"${join40(venvDir, "bin", "pip")}" install --upgrade pip`, {
33636
+ execSync25(`"${join41(venvDir, "bin", "pip")}" install --upgrade pip`, {
33355
33637
  stdio: "pipe",
33356
33638
  timeout: 6e4
33357
33639
  });
@@ -33542,15 +33824,15 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
33542
33824
  }
33543
33825
  }
33544
33826
  const venvDir = getVenvDir();
33545
- const venvBin = join40(venvDir, "bin");
33546
- const venvMoondream = join40(venvBin, "moondream-station");
33827
+ const venvBin = join41(venvDir, "bin");
33828
+ const venvMoondream = join41(venvBin, "moondream-station");
33547
33829
  const venv = ensureVenv(log);
33548
- if (venv && !hasCmd("moondream-station") && !existsSync31(venvMoondream)) {
33549
- const venvPip = join40(venvBin, "pip");
33830
+ if (venv && !hasCmd("moondream-station") && !existsSync32(venvMoondream)) {
33831
+ const venvPip = join41(venvBin, "pip");
33550
33832
  log("Installing moondream-station in ~/.open-agents/venv...");
33551
33833
  try {
33552
33834
  execSync25(`"${venvPip}" install moondream-station`, { stdio: "pipe", timeout: 3e5 });
33553
- if (existsSync31(venvMoondream)) {
33835
+ if (existsSync32(venvMoondream)) {
33554
33836
  log("moondream-station installed successfully.");
33555
33837
  } else {
33556
33838
  try {
@@ -33567,8 +33849,8 @@ async function ensureVisionDeps(onInfo, getSudoPassword) {
33567
33849
  }
33568
33850
  }
33569
33851
  if (venv) {
33570
- const venvPython = join40(venvBin, "python");
33571
- const venvPip2 = join40(venvBin, "pip");
33852
+ const venvPython = join41(venvBin, "python");
33853
+ const venvPip2 = join41(venvBin, "pip");
33572
33854
  let ocrStackInstalled = false;
33573
33855
  try {
33574
33856
  execSync25(`"${venvPython}" -c "import cv2, pytesseract, numpy, PIL"`, { stdio: "pipe", timeout: 1e4 });
@@ -33712,10 +33994,10 @@ async function createExpandedVariantAsync(baseModel, specs, sizeGB, kvBytesPerTo
33712
33994
  `PARAMETER num_predict ${numPredict}`,
33713
33995
  `PARAMETER stop "<|endoftext|>"`
33714
33996
  ].join("\n");
33715
- const modelDir2 = join40(homedir10(), ".open-agents", "models");
33997
+ const modelDir2 = join41(homedir10(), ".open-agents", "models");
33716
33998
  mkdirSync12(modelDir2, { recursive: true });
33717
- const modelfilePath = join40(modelDir2, `Modelfile.${customName}`);
33718
- writeFileSync12(modelfilePath, modelfileContent + "\n", "utf8");
33999
+ const modelfilePath = join41(modelDir2, `Modelfile.${customName}`);
34000
+ writeFileSync13(modelfilePath, modelfileContent + "\n", "utf8");
33719
34001
  await execAsync(`ollama create ${customName} -f ${modelfilePath}`, {
33720
34002
  timeout: 12e4
33721
34003
  });
@@ -33789,8 +34071,8 @@ async function ensureNeovim() {
33789
34071
  const platform5 = process.platform;
33790
34072
  const arch = process.arch;
33791
34073
  if (platform5 === "linux") {
33792
- const binDir = join40(homedir10(), ".local", "bin");
33793
- const nvimDest = join40(binDir, "nvim");
34074
+ const binDir = join41(homedir10(), ".local", "bin");
34075
+ const nvimDest = join41(binDir, "nvim");
33794
34076
  try {
33795
34077
  mkdirSync12(binDir, { recursive: true });
33796
34078
  } catch {
@@ -33861,9 +34143,9 @@ async function ensureNeovim() {
33861
34143
  }
33862
34144
  function ensurePathInShellRc(binDir) {
33863
34145
  const shell = process.env.SHELL ?? "";
33864
- const rcFile = shell.includes("zsh") ? join40(homedir10(), ".zshrc") : join40(homedir10(), ".bashrc");
34146
+ const rcFile = shell.includes("zsh") ? join41(homedir10(), ".zshrc") : join41(homedir10(), ".bashrc");
33865
34147
  try {
33866
- const rcContent = existsSync31(rcFile) ? readFileSync23(rcFile, "utf8") : "";
34148
+ const rcContent = existsSync32(rcFile) ? readFileSync23(rcFile, "utf8") : "";
33867
34149
  if (rcContent.includes(binDir))
33868
34150
  return;
33869
34151
  const exportLine = `
@@ -34445,7 +34727,7 @@ var init_tui_select = __esm({
34445
34727
  });
34446
34728
 
34447
34729
  // packages/cli/dist/tui/drop-panel.js
34448
- import { existsSync as existsSync32 } from "node:fs";
34730
+ import { existsSync as existsSync33 } from "node:fs";
34449
34731
  import { extname as extname9, resolve as resolve27 } from "node:path";
34450
34732
  function ansi4(code, text) {
34451
34733
  return isTTY4 ? `\x1B[${code}m${text}\x1B[0m` : text;
@@ -34560,7 +34842,7 @@ function showDropPanel(opts) {
34560
34842
  filePath = decodeURIComponent(filePath.slice(7));
34561
34843
  }
34562
34844
  filePath = resolve27(filePath);
34563
- if (!existsSync32(filePath)) {
34845
+ if (!existsSync33(filePath)) {
34564
34846
  errorMsg = `File not found: ${filePath}`;
34565
34847
  render();
34566
34848
  return;
@@ -34631,9 +34913,9 @@ var init_drop_panel = __esm({
34631
34913
  });
34632
34914
 
34633
34915
  // packages/cli/dist/tui/neovim-mode.js
34634
- import { existsSync as existsSync33, unlinkSync as unlinkSync5 } from "node:fs";
34635
- import { tmpdir as tmpdir6 } from "node:os";
34636
- import { join as join41 } from "node:path";
34916
+ import { existsSync as existsSync34, unlinkSync as unlinkSync6 } from "node:fs";
34917
+ import { tmpdir as tmpdir7 } from "node:os";
34918
+ import { join as join42 } from "node:path";
34637
34919
  import { execSync as execSync26 } from "node:child_process";
34638
34920
  function isNeovimActive() {
34639
34921
  return _state !== null && !_state.cleanedUp;
@@ -34681,10 +34963,10 @@ async function startNeovimMode(opts) {
34681
34963
  );
34682
34964
  } catch {
34683
34965
  }
34684
- const socketPath = join41(tmpdir6(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
34966
+ const socketPath = join42(tmpdir7(), `oa-nvim-${process.pid}-${Date.now()}.sock`);
34685
34967
  try {
34686
- if (existsSync33(socketPath))
34687
- unlinkSync5(socketPath);
34968
+ if (existsSync34(socketPath))
34969
+ unlinkSync6(socketPath);
34688
34970
  } catch {
34689
34971
  }
34690
34972
  const ptyCols = opts.cols;
@@ -34834,13 +35116,13 @@ function resizeNeovim(cols, contentRows) {
34834
35116
  }
34835
35117
  async function connectRPC(state, neovimPkg, cols) {
34836
35118
  let attempts = 0;
34837
- while (!existsSync33(state.socketPath) && attempts < 30) {
35119
+ while (!existsSync34(state.socketPath) && attempts < 30) {
34838
35120
  await new Promise((r) => setTimeout(r, 200));
34839
35121
  attempts++;
34840
35122
  if (state.cleanedUp)
34841
35123
  return;
34842
35124
  }
34843
- if (!existsSync33(state.socketPath))
35125
+ if (!existsSync34(state.socketPath))
34844
35126
  return;
34845
35127
  const nvim = neovimPkg.attach({ socket: state.socketPath });
34846
35128
  state.nvim = nvim;
@@ -34976,8 +35258,8 @@ function doCleanup(state) {
34976
35258
  state.pty = null;
34977
35259
  }
34978
35260
  try {
34979
- if (existsSync33(state.socketPath))
34980
- unlinkSync5(state.socketPath);
35261
+ if (existsSync34(state.socketPath))
35262
+ unlinkSync6(state.socketPath);
34981
35263
  } catch {
34982
35264
  }
34983
35265
  if (state.stdinHandler) {
@@ -35032,9 +35314,9 @@ __export(voice_exports, {
35032
35314
  registerCustomOnnxModel: () => registerCustomOnnxModel,
35033
35315
  resetNarrationContext: () => resetNarrationContext
35034
35316
  });
35035
- import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13, readFileSync as readFileSync24, unlinkSync as unlinkSync6, readdirSync as readdirSync9, renameSync, statSync as statSync11 } from "node:fs";
35036
- import { join as join42 } from "node:path";
35037
- import { homedir as homedir11, tmpdir as tmpdir7, platform as platform2 } from "node:os";
35317
+ import { existsSync as existsSync35, mkdirSync as mkdirSync13, writeFileSync as writeFileSync14, readFileSync as readFileSync24, unlinkSync as unlinkSync7, readdirSync as readdirSync9, renameSync, statSync as statSync12 } from "node:fs";
35318
+ import { join as join43 } from "node:path";
35319
+ import { homedir as homedir11, tmpdir as tmpdir8, platform as platform2 } from "node:os";
35038
35320
  import { execSync as execSync27, spawn as nodeSpawn } from "node:child_process";
35039
35321
  import { createRequire } from "node:module";
35040
35322
  function registerCustomOnnxModel(id, label) {
@@ -35055,34 +35337,34 @@ function listVoiceModels() {
35055
35337
  }));
35056
35338
  }
35057
35339
  function voiceDir() {
35058
- return join42(homedir11(), ".open-agents", "voice");
35340
+ return join43(homedir11(), ".open-agents", "voice");
35059
35341
  }
35060
35342
  function modelsDir() {
35061
- return join42(voiceDir(), "models");
35343
+ return join43(voiceDir(), "models");
35062
35344
  }
35063
35345
  function modelDir(id) {
35064
- return join42(modelsDir(), id);
35346
+ return join43(modelsDir(), id);
35065
35347
  }
35066
35348
  function modelOnnxPath(id) {
35067
- return join42(modelDir(id), "model.onnx");
35349
+ return join43(modelDir(id), "model.onnx");
35068
35350
  }
35069
35351
  function modelConfigPath(id) {
35070
- return join42(modelDir(id), "config.json");
35352
+ return join43(modelDir(id), "config.json");
35071
35353
  }
35072
35354
  function luxttsVenvDir() {
35073
- return join42(voiceDir(), "luxtts-venv");
35355
+ return join43(voiceDir(), "luxtts-venv");
35074
35356
  }
35075
35357
  function luxttsVenvPy() {
35076
- return platform2() === "win32" ? join42(luxttsVenvDir(), "Scripts", "python.exe") : join42(luxttsVenvDir(), "bin", "python3");
35358
+ return platform2() === "win32" ? join43(luxttsVenvDir(), "Scripts", "python.exe") : join43(luxttsVenvDir(), "bin", "python3");
35077
35359
  }
35078
35360
  function luxttsRepoDir() {
35079
- return join42(voiceDir(), "LuxTTS");
35361
+ return join43(voiceDir(), "LuxTTS");
35080
35362
  }
35081
35363
  function luxttsCloneRefsDir() {
35082
- return join42(voiceDir(), "clone-refs");
35364
+ return join43(voiceDir(), "clone-refs");
35083
35365
  }
35084
35366
  function luxttsInferScript() {
35085
- return join42(voiceDir(), "luxtts-infer.py");
35367
+ return join43(voiceDir(), "luxtts-infer.py");
35086
35368
  }
35087
35369
  function emotionToPitchBias(emotion, stark = false, autist = false) {
35088
35370
  if (autist)
@@ -35890,8 +36172,8 @@ var init_voice = __esm({
35890
36172
  const refsDir = luxttsCloneRefsDir();
35891
36173
  const targets = ["glados", "overwatch"];
35892
36174
  for (const modelId of targets) {
35893
- const refFile = join42(refsDir, `${modelId}-ref.wav`);
35894
- if (existsSync34(refFile))
36175
+ const refFile = join43(refsDir, `${modelId}-ref.wav`);
36176
+ if (existsSync35(refFile))
35895
36177
  continue;
35896
36178
  try {
35897
36179
  await this.generateCloneRef(modelId);
@@ -35970,24 +36252,24 @@ var init_voice = __esm({
35970
36252
  }
35971
36253
  p = p.replace(/\\ /g, " ");
35972
36254
  if (p.startsWith("~/") || p === "~") {
35973
- p = join42(homedir11(), p.slice(1));
36255
+ p = join43(homedir11(), p.slice(1));
35974
36256
  }
35975
- if (!existsSync34(p)) {
36257
+ if (!existsSync35(p)) {
35976
36258
  return `File not found: ${p}
35977
36259
  (original input: ${audioPath})`;
35978
36260
  }
35979
36261
  audioPath = p;
35980
36262
  const refsDir = luxttsCloneRefsDir();
35981
- if (!existsSync34(refsDir))
36263
+ if (!existsSync35(refsDir))
35982
36264
  mkdirSync13(refsDir, { recursive: true });
35983
36265
  const ext = audioPath.split(".").pop() || "wav";
35984
36266
  const srcName = (audioPath.split("/").pop() ?? "clone").replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]/g, "-");
35985
36267
  const ts = Date.now().toString(36);
35986
36268
  const destFilename = `clone-${srcName}-${ts}.${ext}`;
35987
- const destPath = join42(refsDir, destFilename);
36269
+ const destPath = join43(refsDir, destFilename);
35988
36270
  try {
35989
36271
  const data = readFileSync24(audioPath);
35990
- writeFileSync13(destPath, data);
36272
+ writeFileSync14(destPath, data);
35991
36273
  } catch (err) {
35992
36274
  return `Failed to copy audio file: ${err instanceof Error ? err.message : String(err)}`;
35993
36275
  }
@@ -36027,9 +36309,9 @@ var init_voice = __esm({
36027
36309
  return `Failed to synthesize reference audio from ${source.label}.`;
36028
36310
  }
36029
36311
  const refsDir = luxttsCloneRefsDir();
36030
- if (!existsSync34(refsDir))
36312
+ if (!existsSync35(refsDir))
36031
36313
  mkdirSync13(refsDir, { recursive: true });
36032
- const destPath = join42(refsDir, `${sourceModelId}-ref.wav`);
36314
+ const destPath = join43(refsDir, `${sourceModelId}-ref.wav`);
36033
36315
  const sampleRate = this.config?.audio?.sample_rate ?? 22050;
36034
36316
  this.writeWav(audioData, sampleRate, destPath);
36035
36317
  this.luxttsCloneRef = destPath;
@@ -36045,11 +36327,11 @@ var init_voice = __esm({
36045
36327
  // -------------------------------------------------------------------------
36046
36328
  /** Metadata file for friendly names of clone refs */
36047
36329
  static cloneMetaFile() {
36048
- return join42(luxttsCloneRefsDir(), "meta.json");
36330
+ return join43(luxttsCloneRefsDir(), "meta.json");
36049
36331
  }
36050
36332
  loadCloneMeta() {
36051
36333
  const p = _VoiceEngine.cloneMetaFile();
36052
- if (!existsSync34(p))
36334
+ if (!existsSync35(p))
36053
36335
  return {};
36054
36336
  try {
36055
36337
  return JSON.parse(readFileSync24(p, "utf8"));
@@ -36059,9 +36341,9 @@ var init_voice = __esm({
36059
36341
  }
36060
36342
  saveCloneMeta(meta) {
36061
36343
  const dir = luxttsCloneRefsDir();
36062
- if (!existsSync34(dir))
36344
+ if (!existsSync35(dir))
36063
36345
  mkdirSync13(dir, { recursive: true });
36064
- writeFileSync13(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
36346
+ writeFileSync14(_VoiceEngine.cloneMetaFile(), JSON.stringify(meta, null, 2));
36065
36347
  }
36066
36348
  /** Audio file extensions recognized as clone references */
36067
36349
  static AUDIO_EXTS = /* @__PURE__ */ new Set(["wav", "mp3", "ogg", "flac", "m4a", "opus", "aac"]);
@@ -36071,7 +36353,7 @@ var init_voice = __esm({
36071
36353
  */
36072
36354
  listCloneRefs() {
36073
36355
  const dir = luxttsCloneRefsDir();
36074
- if (!existsSync34(dir))
36356
+ if (!existsSync35(dir))
36075
36357
  return [];
36076
36358
  const meta = this.loadCloneMeta();
36077
36359
  const files = readdirSync9(dir).filter((f) => {
@@ -36079,10 +36361,10 @@ var init_voice = __esm({
36079
36361
  return _VoiceEngine.AUDIO_EXTS.has(ext);
36080
36362
  });
36081
36363
  return files.map((f) => {
36082
- const p = join42(dir, f);
36364
+ const p = join43(dir, f);
36083
36365
  let size = 0;
36084
36366
  try {
36085
- size = statSync11(p).size;
36367
+ size = statSync12(p).size;
36086
36368
  } catch {
36087
36369
  }
36088
36370
  return {
@@ -36096,11 +36378,11 @@ var init_voice = __esm({
36096
36378
  }
36097
36379
  /** Delete a clone reference file by filename. Returns true if deleted. */
36098
36380
  deleteCloneRef(filename) {
36099
- const p = join42(luxttsCloneRefsDir(), filename);
36100
- if (!existsSync34(p))
36381
+ const p = join43(luxttsCloneRefsDir(), filename);
36382
+ if (!existsSync35(p))
36101
36383
  return false;
36102
36384
  try {
36103
- unlinkSync6(p);
36385
+ unlinkSync7(p);
36104
36386
  const meta = this.loadCloneMeta();
36105
36387
  delete meta[filename];
36106
36388
  this.saveCloneMeta(meta);
@@ -36121,8 +36403,8 @@ var init_voice = __esm({
36121
36403
  }
36122
36404
  /** Set the active clone reference by filename. */
36123
36405
  setActiveCloneRef(filename) {
36124
- const p = join42(luxttsCloneRefsDir(), filename);
36125
- if (!existsSync34(p))
36406
+ const p = join43(luxttsCloneRefsDir(), filename);
36407
+ if (!existsSync35(p))
36126
36408
  return `File not found: ${filename}`;
36127
36409
  this.luxttsCloneRef = p;
36128
36410
  return `Active clone voice set to: ${filename}`;
@@ -36407,11 +36689,11 @@ var init_voice = __esm({
36407
36689
  }
36408
36690
  this.onPCMOutput(Buffer.from(int16.buffer), sampleRate);
36409
36691
  }
36410
- const wavPath = join42(tmpdir7(), `oa-voice-${Date.now()}.wav`);
36692
+ const wavPath = join43(tmpdir8(), `oa-voice-${Date.now()}.wav`);
36411
36693
  this.writeWav(audioData, sampleRate, wavPath);
36412
36694
  await this.playWav(wavPath);
36413
36695
  try {
36414
- unlinkSync6(wavPath);
36696
+ unlinkSync7(wavPath);
36415
36697
  } catch {
36416
36698
  }
36417
36699
  }
@@ -36545,7 +36827,7 @@ var init_voice = __esm({
36545
36827
  return buffer;
36546
36828
  }
36547
36829
  writeWav(samples, sampleRate, path) {
36548
- writeFileSync13(path, this.buildWavBuffer(samples, sampleRate));
36830
+ writeFileSync14(path, this.buildWavBuffer(samples, sampleRate));
36549
36831
  }
36550
36832
  // -------------------------------------------------------------------------
36551
36833
  // Audio playback (system default speakers)
@@ -36656,7 +36938,7 @@ var init_voice = __esm({
36656
36938
  return new Promise((resolve32, reject) => {
36657
36939
  const proc = nodeSpawn("sh", ["-c", command], {
36658
36940
  stdio: ["ignore", "pipe", "pipe"],
36659
- cwd: tmpdir7()
36941
+ cwd: tmpdir8()
36660
36942
  });
36661
36943
  let stdout = "";
36662
36944
  let stderr = "";
@@ -36750,7 +37032,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36750
37032
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
36751
37033
  const mlxVoice = model.mlxVoice ?? "af_heart";
36752
37034
  const mlxLangCode = model.mlxLangCode ?? "a";
36753
- const wavPath = join42(tmpdir7(), `oa-mlx-${Date.now()}.wav`);
37035
+ const wavPath = join43(tmpdir8(), `oa-mlx-${Date.now()}.wav`);
36754
37036
  const pyScript = [
36755
37037
  "import sys, json",
36756
37038
  "from mlx_audio.tts import generate as tts_gen",
@@ -36758,16 +37040,16 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36758
37040
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
36759
37041
  ].join("; ");
36760
37042
  try {
36761
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir7() });
37043
+ execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
36762
37044
  } catch (err) {
36763
37045
  try {
36764
37046
  const safeText = cleaned.replace(/'/g, "'\\''");
36765
- execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir7() });
37047
+ execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
36766
37048
  } catch (err2) {
36767
37049
  return;
36768
37050
  }
36769
37051
  }
36770
- if (!existsSync34(wavPath))
37052
+ if (!existsSync35(wavPath))
36771
37053
  return;
36772
37054
  if (volume !== 1) {
36773
37055
  try {
@@ -36779,7 +37061,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36779
37061
  samples[i] = Math.round(samples[i] * volume);
36780
37062
  }
36781
37063
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
36782
- writeFileSync13(wavPath, scaled);
37064
+ writeFileSync14(wavPath, scaled);
36783
37065
  }
36784
37066
  } catch {
36785
37067
  }
@@ -36797,7 +37079,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36797
37079
  }
36798
37080
  await this.playWav(wavPath);
36799
37081
  try {
36800
- unlinkSync6(wavPath);
37082
+ unlinkSync7(wavPath);
36801
37083
  } catch {
36802
37084
  }
36803
37085
  }
@@ -36818,7 +37100,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36818
37100
  const mlxModelId = model.mlxModelId ?? "mlx-community/Kokoro-82M-bf16";
36819
37101
  const mlxVoice = model.mlxVoice ?? "af_heart";
36820
37102
  const mlxLangCode = model.mlxLangCode ?? "a";
36821
- const wavPath = join42(tmpdir7(), `oa-mlx-buf-${Date.now()}.wav`);
37103
+ const wavPath = join43(tmpdir8(), `oa-mlx-buf-${Date.now()}.wav`);
36822
37104
  const pyScript = [
36823
37105
  "import sys, json",
36824
37106
  "from mlx_audio.tts import generate as tts_gen",
@@ -36826,20 +37108,20 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36826
37108
  `tts_gen.main(["--model", ${JSON.stringify(mlxModelId)}, "--text", text, "--voice", ${JSON.stringify(mlxVoice)}, "--lang_code", ${JSON.stringify(mlxLangCode)}, "--audio_path", ${JSON.stringify(wavPath)}])`
36827
37109
  ].join("; ");
36828
37110
  try {
36829
- execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir7() });
37111
+ execSync27(`${py} -c ${JSON.stringify(pyScript)} ${JSON.stringify(JSON.stringify(cleaned))}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
36830
37112
  } catch {
36831
37113
  try {
36832
37114
  const safeText = cleaned.replace(/'/g, "'\\''");
36833
- execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir7() });
37115
+ execSync27(`${py} -m mlx_audio.tts.generate --model ${mlxModelId} --text '${safeText}' --voice ${mlxVoice} --lang_code ${mlxLangCode} --audio_path ${JSON.stringify(wavPath)}`, { stdio: "pipe", timeout: 6e4, cwd: tmpdir8() });
36834
37116
  } catch {
36835
37117
  return null;
36836
37118
  }
36837
37119
  }
36838
- if (!existsSync34(wavPath))
37120
+ if (!existsSync35(wavPath))
36839
37121
  return null;
36840
37122
  try {
36841
37123
  const data = readFileSync24(wavPath);
36842
- unlinkSync6(wavPath);
37124
+ unlinkSync7(wavPath);
36843
37125
  return data;
36844
37126
  } catch {
36845
37127
  return null;
@@ -36861,7 +37143,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36861
37143
  }
36862
37144
  const venvDir = luxttsVenvDir();
36863
37145
  const venvPy = luxttsVenvPy();
36864
- if (existsSync34(venvPy)) {
37146
+ if (existsSync35(venvPy)) {
36865
37147
  try {
36866
37148
  await this.asyncShell(`${venvPy} -c "import sys; sys.path.insert(0, '${luxttsRepoDir()}'); from zipvoice.luxvoice import LuxTTS; print('ok')"`, 3e4);
36867
37149
  let hasCudaSys = false;
@@ -36891,7 +37173,7 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36891
37173
  }
36892
37174
  }
36893
37175
  renderInfo("Setting up LuxTTS voice cloning (first-time setup, this takes several minutes)...");
36894
- if (!existsSync34(venvDir)) {
37176
+ if (!existsSync35(venvDir)) {
36895
37177
  renderInfo(" Creating Python virtual environment...");
36896
37178
  try {
36897
37179
  await this.asyncShell(`${py} -m venv ${JSON.stringify(venvDir)}`, 6e4);
@@ -36929,10 +37211,10 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36929
37211
  }
36930
37212
  }
36931
37213
  const repoDir = luxttsRepoDir();
36932
- if (!existsSync34(join42(repoDir, "zipvoice", "luxvoice.py"))) {
37214
+ if (!existsSync35(join43(repoDir, "zipvoice", "luxvoice.py"))) {
36933
37215
  renderInfo(" Cloning LuxTTS repository...");
36934
37216
  try {
36935
- if (existsSync34(repoDir)) {
37217
+ if (existsSync35(repoDir)) {
36936
37218
  await this.asyncShell(`rm -rf ${JSON.stringify(repoDir)}`, 3e4);
36937
37219
  }
36938
37220
  await this.asyncShell(`git clone --depth 1 https://github.com/ysharma3501/LuxTTS.git ${JSON.stringify(repoDir)}`, 12e4);
@@ -36972,14 +37254,14 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
36972
37254
  }
36973
37255
  /** Auto-detect an existing clone reference in the refs directory */
36974
37256
  autoDetectCloneRef() {
36975
- if (this.luxttsCloneRef && existsSync34(this.luxttsCloneRef))
37257
+ if (this.luxttsCloneRef && existsSync35(this.luxttsCloneRef))
36976
37258
  return;
36977
37259
  const refsDir = luxttsCloneRefsDir();
36978
- if (!existsSync34(refsDir))
37260
+ if (!existsSync35(refsDir))
36979
37261
  return;
36980
37262
  for (const name of ["custom-clone.wav", "custom-clone.mp3", "glados-ref.wav", "overwatch-ref.wav"]) {
36981
- const p = join42(refsDir, name);
36982
- if (existsSync34(p)) {
37263
+ const p = join43(refsDir, name);
37264
+ if (existsSync35(p)) {
36983
37265
  this.luxttsCloneRef = p;
36984
37266
  return;
36985
37267
  }
@@ -37080,20 +37362,20 @@ if __name__ == '__main__':
37080
37362
  `;
37081
37363
  const scriptPath2 = luxttsInferScript();
37082
37364
  mkdirSync13(voiceDir(), { recursive: true });
37083
- writeFileSync13(scriptPath2, script);
37365
+ writeFileSync14(scriptPath2, script);
37084
37366
  }
37085
37367
  /** Ensure the LuxTTS daemon is running, spawn if needed */
37086
37368
  async ensureLuxttsDaemon() {
37087
37369
  if (this._luxttsDaemon && !this._luxttsDaemon.killed)
37088
37370
  return true;
37089
37371
  const venvPy = luxttsVenvPy();
37090
- if (!existsSync34(venvPy))
37372
+ if (!existsSync35(venvPy))
37091
37373
  return false;
37092
37374
  return new Promise((resolve32) => {
37093
37375
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
37094
37376
  const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
37095
37377
  stdio: ["pipe", "pipe", "pipe"],
37096
- cwd: tmpdir7(),
37378
+ cwd: tmpdir8(),
37097
37379
  env
37098
37380
  });
37099
37381
  this._luxttsDaemon = daemon;
@@ -37166,7 +37448,7 @@ if __name__ == '__main__':
37166
37448
  * Volume is applied via WAV sample scaling.
37167
37449
  */
37168
37450
  async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1) {
37169
- if (!this.luxttsCloneRef || !existsSync34(this.luxttsCloneRef)) {
37451
+ if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef)) {
37170
37452
  return;
37171
37453
  }
37172
37454
  const cleaned = text.replace(/\*/g, "").trim();
@@ -37175,7 +37457,7 @@ if __name__ == '__main__':
37175
37457
  const ready = await this.ensureLuxttsDaemon();
37176
37458
  if (!ready)
37177
37459
  return;
37178
- const wavPath = join42(tmpdir7(), `oa-luxtts-${Date.now()}.wav`);
37460
+ const wavPath = join43(tmpdir8(), `oa-luxtts-${Date.now()}.wav`);
37179
37461
  try {
37180
37462
  await this.luxttsRequest({
37181
37463
  action: "synthesize",
@@ -37187,7 +37469,7 @@ if __name__ == '__main__':
37187
37469
  } catch {
37188
37470
  return;
37189
37471
  }
37190
- if (!existsSync34(wavPath))
37472
+ if (!existsSync35(wavPath))
37191
37473
  return;
37192
37474
  if (volume !== 1) {
37193
37475
  try {
@@ -37199,7 +37481,7 @@ if __name__ == '__main__':
37199
37481
  }
37200
37482
  const header = wavData.subarray(0, 44);
37201
37483
  const scaled = Buffer.concat([header, Buffer.from(samples.buffer, samples.byteOffset, samples.byteLength)]);
37202
- writeFileSync13(wavPath, scaled);
37484
+ writeFileSync14(wavPath, scaled);
37203
37485
  }
37204
37486
  } catch {
37205
37487
  }
@@ -37232,7 +37514,7 @@ if __name__ == '__main__':
37232
37514
  }
37233
37515
  await this.playWav(wavPath);
37234
37516
  try {
37235
- unlinkSync6(wavPath);
37517
+ unlinkSync7(wavPath);
37236
37518
  } catch {
37237
37519
  }
37238
37520
  }
@@ -37241,7 +37523,7 @@ if __name__ == '__main__':
37241
37523
  * Used for Telegram voice messages and WebSocket streaming.
37242
37524
  */
37243
37525
  async synthesizeLuxttsToBuffer(text) {
37244
- if (!this.luxttsCloneRef || !existsSync34(this.luxttsCloneRef))
37526
+ if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef))
37245
37527
  return null;
37246
37528
  const cleaned = text.replace(/\*/g, "").trim();
37247
37529
  if (!cleaned)
@@ -37249,7 +37531,7 @@ if __name__ == '__main__':
37249
37531
  const ready = await this.ensureLuxttsDaemon();
37250
37532
  if (!ready)
37251
37533
  return null;
37252
- const wavPath = join42(tmpdir7(), `oa-luxtts-buf-${Date.now()}.wav`);
37534
+ const wavPath = join43(tmpdir8(), `oa-luxtts-buf-${Date.now()}.wav`);
37253
37535
  try {
37254
37536
  await this.luxttsRequest({
37255
37537
  action: "synthesize",
@@ -37261,11 +37543,11 @@ if __name__ == '__main__':
37261
37543
  } catch {
37262
37544
  return null;
37263
37545
  }
37264
- if (!existsSync34(wavPath))
37546
+ if (!existsSync35(wavPath))
37265
37547
  return null;
37266
37548
  try {
37267
37549
  const data = readFileSync24(wavPath);
37268
- unlinkSync6(wavPath);
37550
+ unlinkSync7(wavPath);
37269
37551
  return data;
37270
37552
  } catch {
37271
37553
  return null;
@@ -37279,40 +37561,40 @@ if __name__ == '__main__':
37279
37561
  return;
37280
37562
  const arch = process.arch;
37281
37563
  mkdirSync13(voiceDir(), { recursive: true });
37282
- const pkgPath = join42(voiceDir(), "package.json");
37564
+ const pkgPath = join43(voiceDir(), "package.json");
37283
37565
  const expectedDeps = {
37284
37566
  "onnxruntime-node": "^1.21.0",
37285
37567
  "phonemizer": "^1.2.1"
37286
37568
  };
37287
- if (existsSync34(pkgPath)) {
37569
+ if (existsSync35(pkgPath)) {
37288
37570
  try {
37289
37571
  const existing = JSON.parse(readFileSync24(pkgPath, "utf8"));
37290
37572
  if (!existing.dependencies?.["phonemizer"]) {
37291
37573
  existing.dependencies = { ...existing.dependencies, ...expectedDeps };
37292
- writeFileSync13(pkgPath, JSON.stringify(existing, null, 2));
37574
+ writeFileSync14(pkgPath, JSON.stringify(existing, null, 2));
37293
37575
  }
37294
37576
  } catch {
37295
37577
  }
37296
37578
  }
37297
- if (!existsSync34(pkgPath)) {
37298
- writeFileSync13(pkgPath, JSON.stringify({
37579
+ if (!existsSync35(pkgPath)) {
37580
+ writeFileSync14(pkgPath, JSON.stringify({
37299
37581
  name: "open-agents-voice",
37300
37582
  private: true,
37301
37583
  dependencies: expectedDeps
37302
37584
  }, null, 2));
37303
37585
  }
37304
- const voiceRequire = createRequire(join42(voiceDir(), "index.js"));
37586
+ const voiceRequire = createRequire(join43(voiceDir(), "index.js"));
37305
37587
  const probeOnnx = () => {
37306
37588
  try {
37307
- const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join42(voiceDir(), "node_modules") } });
37589
+ const result = execSync27(`node -e "try { require('onnxruntime-node'); console.log('OK'); } catch(e) { console.log('FAIL:' + e.message); }"`, { cwd: voiceDir(), stdio: "pipe", timeout: 15e3, env: { ...process.env, NODE_PATH: join43(voiceDir(), "node_modules") } });
37308
37590
  const output = result.toString().trim();
37309
37591
  return output === "OK";
37310
37592
  } catch {
37311
37593
  return false;
37312
37594
  }
37313
37595
  };
37314
- const onnxNodeModules = join42(voiceDir(), "node_modules", "onnxruntime-node");
37315
- const onnxInstalled = existsSync34(onnxNodeModules);
37596
+ const onnxNodeModules = join43(voiceDir(), "node_modules", "onnxruntime-node");
37597
+ const onnxInstalled = existsSync35(onnxNodeModules);
37316
37598
  if (onnxInstalled && !probeOnnx()) {
37317
37599
  throw new Error(`Voice synthesis unavailable: ONNX runtime crashes on this CPU (${process.platform}-${arch}). This is a known issue with some ARM SoCs where the CPU vendor is not recognized. Voice feedback will be disabled but all other features work normally.`);
37318
37600
  }
@@ -37370,18 +37652,18 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
37370
37652
  const dir = modelDir(id);
37371
37653
  const onnxPath = modelOnnxPath(id);
37372
37654
  const configPath = modelConfigPath(id);
37373
- if (existsSync34(onnxPath) && existsSync34(configPath))
37655
+ if (existsSync35(onnxPath) && existsSync35(configPath))
37374
37656
  return;
37375
37657
  mkdirSync13(dir, { recursive: true });
37376
- if (!existsSync34(configPath)) {
37658
+ if (!existsSync35(configPath)) {
37377
37659
  renderInfo(`Downloading ${model.label} voice config...`);
37378
37660
  const configResp = await fetch(model.configUrl);
37379
37661
  if (!configResp.ok)
37380
37662
  throw new Error(`Failed to download config: HTTP ${configResp.status}`);
37381
37663
  const configText = await configResp.text();
37382
- writeFileSync13(configPath, configText);
37664
+ writeFileSync14(configPath, configText);
37383
37665
  }
37384
- if (!existsSync34(onnxPath)) {
37666
+ if (!existsSync35(onnxPath)) {
37385
37667
  renderInfo(`Downloading ${model.label} voice model (this may take a minute)...`);
37386
37668
  const onnxResp = await fetch(model.onnxUrl);
37387
37669
  if (!onnxResp.ok)
@@ -37406,7 +37688,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
37406
37688
  }
37407
37689
  }
37408
37690
  const fullBuffer = Buffer.concat(chunks);
37409
- writeFileSync13(onnxPath, fullBuffer);
37691
+ writeFileSync14(onnxPath, fullBuffer);
37410
37692
  renderInfo(`${model.label} model downloaded (${formatBytes2(fullBuffer.length)}).`);
37411
37693
  }
37412
37694
  }
@@ -37418,7 +37700,7 @@ Error: ${err instanceof Error ? err.message : String(err)}`);
37418
37700
  throw new Error("ONNX runtime not loaded");
37419
37701
  const onnxPath = modelOnnxPath(this.modelId);
37420
37702
  const configPath = modelConfigPath(this.modelId);
37421
- if (!existsSync34(onnxPath) || !existsSync34(configPath)) {
37703
+ if (!existsSync35(onnxPath) || !existsSync35(configPath)) {
37422
37704
  throw new Error(`Model files not found for ${this.modelId}`);
37423
37705
  }
37424
37706
  this.config = JSON.parse(readFileSync24(configPath, "utf8"));
@@ -39654,11 +39936,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
39654
39936
  const models = await fetchModels(peerUrl, authKey);
39655
39937
  if (models.length > 0) {
39656
39938
  try {
39657
- const { writeFileSync: writeFileSync19, mkdirSync: mkdirSync21 } = await import("node:fs");
39658
- const { join: join56, dirname: dirname20 } = await import("node:path");
39659
- const cachePath = join56(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
39939
+ const { writeFileSync: writeFileSync20, mkdirSync: mkdirSync21 } = await import("node:fs");
39940
+ const { join: join57, dirname: dirname20 } = await import("node:path");
39941
+ const cachePath = join57(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
39660
39942
  mkdirSync21(dirname20(cachePath), { recursive: true });
39661
- writeFileSync19(cachePath, JSON.stringify({
39943
+ writeFileSync20(cachePath, JSON.stringify({
39662
39944
  peerId,
39663
39945
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
39664
39946
  models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
@@ -39857,17 +40139,17 @@ async function handleUpdate(subcommand, ctx) {
39857
40139
  try {
39858
40140
  const { createRequire: createRequire4 } = await import("node:module");
39859
40141
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
39860
- const { dirname: dirname20, join: join56 } = await import("node:path");
39861
- const { existsSync: existsSync44 } = await import("node:fs");
40142
+ const { dirname: dirname20, join: join57 } = await import("node:path");
40143
+ const { existsSync: existsSync45 } = await import("node:fs");
39862
40144
  const req = createRequire4(import.meta.url);
39863
40145
  const thisDir = dirname20(fileURLToPath14(import.meta.url));
39864
40146
  const candidates = [
39865
- join56(thisDir, "..", "package.json"),
39866
- join56(thisDir, "..", "..", "package.json"),
39867
- join56(thisDir, "..", "..", "..", "package.json")
40147
+ join57(thisDir, "..", "package.json"),
40148
+ join57(thisDir, "..", "..", "package.json"),
40149
+ join57(thisDir, "..", "..", "..", "package.json")
39868
40150
  ];
39869
40151
  for (const pkgPath of candidates) {
39870
- if (existsSync44(pkgPath)) {
40152
+ if (existsSync45(pkgPath)) {
39871
40153
  const pkg = req(pkgPath);
39872
40154
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
39873
40155
  currentVersion = pkg.version ?? "0.0.0";
@@ -39905,13 +40187,6 @@ async function handleUpdate(subcommand, ctx) {
39905
40187
  }
39906
40188
  };
39907
40189
  }
39908
- process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
39909
- process.stdout.write(`
39910
- ${c2.bold("Open Agents Update")}
39911
- ${c2.dim("\u2500".repeat(40))}
39912
-
39913
- `);
39914
- const checkSpinner = startInlineSpinner(`Checking for updates ${c2.dim(`(current: v${currentVersion})`)}`);
39915
40190
  const info = await checkForUpdate(currentVersion, true);
39916
40191
  const { exec: exec4, execSync: es2 } = await import("node:child_process");
39917
40192
  let needsSudo = false;
@@ -39925,6 +40200,65 @@ async function handleUpdate(subcommand, ctx) {
39925
40200
  }
39926
40201
  } catch {
39927
40202
  }
40203
+ const items = [];
40204
+ const skipKeys = [];
40205
+ items.push({ key: "hdr_status", label: selectColors.dim(`\u2500\u2500\u2500 v${currentVersion} \u2500\u2500\u2500`), kind: "header" });
40206
+ skipKeys.push("hdr_status");
40207
+ if (info) {
40208
+ items.push({ key: "info_avail", label: `Update available: v${currentVersion} \u2192 ${c2.bold(c2.green("v" + info.latestVersion))}`, kind: "info" });
40209
+ } else {
40210
+ items.push({ key: "info_avail", label: c2.dim("Primary package is up to date"), kind: "info" });
40211
+ }
40212
+ skipKeys.push("info_avail");
40213
+ items.push({ key: "hdr_options", label: selectColors.dim("\u2500\u2500\u2500 Update Options \u2500\u2500\u2500"), kind: "header" });
40214
+ skipKeys.push("hdr_options");
40215
+ if (info) {
40216
+ items.push({ key: "quick", label: "Quick Update", detail: "Install latest package only (fast)", kind: "action" });
40217
+ }
40218
+ items.push({ key: "full", label: "Full Update", detail: "Package + dependencies + native modules + Python + cloudflared", kind: "action" });
40219
+ items.push({ key: "deps_only", label: "Dependencies Only", detail: "Update subordinate deps (nexus, viem, moondream, etc.)", kind: "action" });
40220
+ items.push({ key: "rebuild", label: "Rebuild Native Modules", detail: "Rebuild better-sqlite3, node-pty, etc.", kind: "action" });
40221
+ items.push({ key: "python", label: "Python Packages Only", detail: "Upgrade venv packages (moondream, tesseract, etc.)", kind: "action" });
40222
+ items.push({ key: "hdr_policy", label: selectColors.dim("\u2500\u2500\u2500 Policy \u2500\u2500\u2500"), kind: "header" });
40223
+ skipKeys.push("hdr_policy");
40224
+ items.push({ key: "policy_auto", label: "Auto-update mode", detail: "Install updates automatically after tasks", kind: "action" });
40225
+ items.push({ key: "policy_manual", label: "Manual-update mode", detail: "Only update when you run /update", kind: "action" });
40226
+ const menuResult = await tuiSelect({
40227
+ items,
40228
+ title: "Update Manager",
40229
+ rl: ctx.rl,
40230
+ skipKeys,
40231
+ availableRows: ctx.availableContentRows?.()
40232
+ });
40233
+ if (!menuResult.confirmed || !menuResult.key) {
40234
+ renderInfo("Update cancelled.");
40235
+ return;
40236
+ }
40237
+ if (menuResult.key === "policy_auto") {
40238
+ const settings = { updateMode: "auto" };
40239
+ saveProjectSettings(repoRoot, settings);
40240
+ saveGlobalSettings(settings);
40241
+ renderInfo("Update mode: auto \u2014 updates install automatically after task completion.");
40242
+ return;
40243
+ }
40244
+ if (menuResult.key === "policy_manual") {
40245
+ const settings = { updateMode: "manual" };
40246
+ saveProjectSettings(repoRoot, settings);
40247
+ saveGlobalSettings(settings);
40248
+ renderInfo("Update mode: manual \u2014 only installs when you run /update.");
40249
+ return;
40250
+ }
40251
+ const doPackage = menuResult.key === "quick" || menuResult.key === "full";
40252
+ const doDeps = menuResult.key === "deps_only" || menuResult.key === "full";
40253
+ const doRebuild = menuResult.key === "rebuild" || menuResult.key === "full";
40254
+ const doPython = menuResult.key === "python" || menuResult.key === "full";
40255
+ const doCloudflared = menuResult.key === "full";
40256
+ process.stdout.write("\x1B[?1049h\x1B[H\x1B[2J");
40257
+ process.stdout.write(`
40258
+ ${c2.bold("Open Agents Update")}
40259
+ ${c2.dim("\u2500".repeat(40))}
40260
+
40261
+ `);
39928
40262
  let installError = "";
39929
40263
  const runInstall2 = (cmd) => new Promise((resolve32) => {
39930
40264
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
@@ -39937,7 +40271,6 @@ async function handleUpdate(subcommand, ctx) {
39937
40271
  if (needsSudo) {
39938
40272
  process.stdout.write("\x1B[?1049l");
39939
40273
  renderInfo("Global npm directory requires elevated permissions.");
39940
- renderInfo("You'll be asked for your password once \u2014 it covers all update steps.");
39941
40274
  safeWrite("\n");
39942
40275
  try {
39943
40276
  es2("sudo -v", { stdio: "inherit", timeout: 6e4 });
@@ -39954,14 +40287,11 @@ async function handleUpdate(subcommand, ctx) {
39954
40287
  }
39955
40288
  const sudoPrefix = needsSudo ? "sudo " : "";
39956
40289
  let primaryUpdated = false;
39957
- if (!info) {
39958
- checkSpinner.stop(`Primary package up to date (v${currentVersion}).`);
39959
- } else {
39960
- checkSpinner.stop(`Update available: v${info.currentVersion} \u2192 v${c2.bold(c2.green(info.latestVersion))}`);
40290
+ let depsUpdated = false;
40291
+ if (doPackage && info) {
39961
40292
  const installSpinner = startInlineSpinner("Installing update");
39962
40293
  const installCmd = `${sudoPrefix}npm install -g open-agents-ai@latest --prefer-online`;
39963
- let installOk = false;
39964
- installOk = await runInstall2(installCmd);
40294
+ let installOk = await runInstall2(installCmd);
39965
40295
  if (!installOk && /ENOTEMPTY|errno -39/i.test(installError)) {
39966
40296
  installSpinner.stop("Cleaning stale npm temp files...");
39967
40297
  try {
@@ -39982,10 +40312,6 @@ async function handleUpdate(subcommand, ctx) {
39982
40312
  }
39983
40313
  if (!installOk) {
39984
40314
  installSpinner.stop("Update install failed.");
39985
- const errPreview = installError.split("\n").filter((l) => l.trim()).slice(-3).join("\n ");
39986
- if (errPreview)
39987
- renderWarning(`Error:
39988
- ${errPreview}`);
39989
40315
  renderWarning(`Try manually: ${sudoPrefix}npm i -g open-agents-ai`);
39990
40316
  process.stdout.write("\x1B[?1049l");
39991
40317
  return;
@@ -39993,99 +40319,113 @@ async function handleUpdate(subcommand, ctx) {
39993
40319
  installSpinner.stop(`Update installed (v${info.latestVersion}).`);
39994
40320
  primaryUpdated = true;
39995
40321
  }
39996
- const depsSpinner = startInlineSpinner("Checking subordinate dependencies");
39997
- let depsUpdated = false;
39998
- try {
39999
- const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
40000
- const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
40001
- const { existsSync: fe, readFileSync: rf } = await import("node:fs");
40002
- const { join: pj } = await import("node:path");
40003
- const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
40004
- if (fe(pkgPath)) {
40005
- const pkg = JSON.parse(rf(pkgPath, "utf8"));
40006
- const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
40007
- const depNames = Object.keys(allDeps);
40008
- if (depNames.length > 0) {
40009
- const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
40010
- const updateOk = await runInstall2(updateCmd);
40011
- if (updateOk)
40012
- depsUpdated = true;
40322
+ if (doDeps) {
40323
+ const depsSpinner = startInlineSpinner("Updating subordinate dependencies");
40324
+ try {
40325
+ const prefix = es2("npm prefix -g", { encoding: "utf8", timeout: 5e3 }).trim();
40326
+ const globalModules = prefix.endsWith("/lib") ? prefix + "/node_modules" : prefix + "/lib/node_modules";
40327
+ const { existsSync: fe, readFileSync: rf } = await import("node:fs");
40328
+ const { join: pj } = await import("node:path");
40329
+ const pkgPath = pj(globalModules, "open-agents-ai", "package.json");
40330
+ if (fe(pkgPath)) {
40331
+ const pkg = JSON.parse(rf(pkgPath, "utf8"));
40332
+ const allDeps = { ...pkg.dependencies || {}, ...pkg.optionalDependencies || {} };
40333
+ if (Object.keys(allDeps).length > 0) {
40334
+ const updateCmd = `${sudoPrefix}npm update --prefer-online --prefix "${pj(globalModules, "open-agents-ai")}" 2>/dev/null || true`;
40335
+ const updateOk = await runInstall2(updateCmd);
40336
+ if (updateOk)
40337
+ depsUpdated = true;
40338
+ }
40013
40339
  }
40340
+ } catch {
40014
40341
  }
40015
- } catch {
40342
+ depsSpinner.stop(depsUpdated ? "Dependencies updated." : "Dependencies checked.");
40016
40343
  }
40017
- depsSpinner.stop(depsUpdated ? "Dependencies updated to latest." : "Dependencies checked.");
40018
- if (!primaryUpdated && !depsUpdated) {
40019
- renderInfo("Everything is up to date \u2014 no changes needed.");
40344
+ if (!primaryUpdated && !depsUpdated && !doRebuild && !doPython && !doCloudflared) {
40345
+ renderInfo("No changes needed.");
40020
40346
  safeWrite("\n");
40021
40347
  await new Promise((r) => setTimeout(r, 1e3));
40022
40348
  process.stdout.write("\x1B[?1049l");
40023
40349
  return;
40024
40350
  }
40025
- const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
40026
- const rebuildOk = await new Promise((resolve32) => {
40027
- const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
40028
- child.stdout?.resume();
40029
- child.stderr?.resume();
40030
- });
40031
- rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
40351
+ if (doRebuild) {
40352
+ const rebuildSpinner = startInlineSpinner("Rebuilding native modules");
40353
+ const rebuildOk = await new Promise((resolve32) => {
40354
+ const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve32(true));
40355
+ child.stdout?.resume();
40356
+ child.stderr?.resume();
40357
+ });
40358
+ rebuildSpinner.stop(rebuildOk ? "Native modules rebuilt." : "Native rebuild skipped.");
40359
+ }
40032
40360
  const { existsSync: fsExists } = await import("node:fs");
40033
40361
  const { join: pathJoin } = await import("node:path");
40034
40362
  const { homedir: getHome } = await import("node:os");
40035
- let hasPython = hasCmd("python3") || hasCmd("python");
40036
- if (!hasPython) {
40037
- const pyInstallSpinner = startInlineSpinner("Installing Python3");
40038
- try {
40039
- ensurePython3();
40040
- hasPython = hasCmd("python3") || hasCmd("python");
40041
- pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
40042
- } catch {
40043
- pyInstallSpinner.stop("Python3 install failed.");
40363
+ if (doPython) {
40364
+ let hasPython = hasCmd("python3") || hasCmd("python");
40365
+ if (!hasPython) {
40366
+ const pyInstallSpinner = startInlineSpinner("Installing Python3");
40367
+ try {
40368
+ ensurePython3();
40369
+ hasPython = hasCmd("python3") || hasCmd("python");
40370
+ pyInstallSpinner.stop(hasPython ? "Python3 installed." : "Python3 install failed.");
40371
+ } catch {
40372
+ pyInstallSpinner.stop("Python3 install failed.");
40373
+ }
40374
+ }
40375
+ if (hasPython && !checkPythonVenv()) {
40376
+ const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
40377
+ try {
40378
+ ensurePythonVenv();
40379
+ venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
40380
+ } catch {
40381
+ venvInstallSpinner.stop("python3-venv install failed.");
40382
+ }
40383
+ }
40384
+ const venvDir = pathJoin(getHome(), ".open-agents", "venv");
40385
+ const venvPip = pathJoin(venvDir, "bin", "pip");
40386
+ if (fsExists(venvPip)) {
40387
+ const pySpinner = startInlineSpinner("Upgrading Python venv packages");
40388
+ const pyOk = await new Promise((resolve32) => {
40389
+ const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
40390
+ child.stdout?.resume();
40391
+ child.stderr?.resume();
40392
+ });
40393
+ pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
40394
+ } else {
40395
+ const pySpinner = startInlineSpinner("Setting up Python venv & deps");
40396
+ await ensureVisionDeps((msg) => {
40397
+ pySpinner.stop(msg);
40398
+ }).catch(() => {
40399
+ });
40400
+ pySpinner.stop("Python deps bootstrapped.");
40044
40401
  }
40045
40402
  }
40046
- if (hasPython && !checkPythonVenv()) {
40047
- const venvInstallSpinner = startInlineSpinner("Installing python3-venv");
40403
+ let hasCf = false;
40404
+ if (doCloudflared) {
40405
+ const cfSpinner = startInlineSpinner("Checking cloudflared");
40048
40406
  try {
40049
- ensurePythonVenv();
40050
- venvInstallSpinner.stop(checkPythonVenv() ? "python3-venv installed." : "python3-venv install failed.");
40407
+ const { execSync: es } = await import("node:child_process");
40408
+ es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
40409
+ hasCf = true;
40051
40410
  } catch {
40052
- venvInstallSpinner.stop("python3-venv install failed.");
40053
40411
  }
40412
+ if (!hasCf) {
40413
+ cfSpinner.stop("Installing cloudflared...");
40414
+ ensureCloudflaredBackground((msg) => renderInfo(msg));
40415
+ await new Promise((r) => setTimeout(r, 1e3));
40416
+ } else {
40417
+ cfSpinner.stop("cloudflared ready.");
40418
+ }
40419
+ ensureTranscribeCliBackground();
40054
40420
  }
40055
- const venvDir = pathJoin(getHome(), ".open-agents", "venv");
40056
- const venvPip = pathJoin(venvDir, "bin", "pip");
40057
- if (fsExists(venvPip)) {
40058
- const pySpinner = startInlineSpinner("Upgrading Python venv packages");
40059
- const pyOk = await new Promise((resolve32) => {
40060
- const child = exec4(`"${venvPip}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve32(!err));
40061
- child.stdout?.resume();
40062
- child.stderr?.resume();
40063
- });
40064
- pySpinner.stop(pyOk ? "Python packages upgraded." : "Python upgrade skipped.");
40065
- } else {
40066
- const pySpinner = startInlineSpinner("Setting up Python venv & deps");
40067
- await ensureVisionDeps((msg) => {
40068
- pySpinner.stop(msg);
40069
- }).catch(() => {
40070
- });
40071
- pySpinner.stop("Python deps bootstrapped.");
40072
- }
40073
- const cfSpinner = startInlineSpinner("Checking cloudflared");
40074
- let hasCf = false;
40075
- try {
40076
- const { execSync: es } = await import("node:child_process");
40077
- es("which cloudflared", { stdio: "pipe", timeout: 3e3 });
40078
- hasCf = true;
40079
- } catch {
40080
- }
40081
- if (!hasCf) {
40082
- cfSpinner.stop("Installing cloudflared...");
40083
- ensureCloudflaredBackground((msg) => renderInfo(msg));
40421
+ if (!primaryUpdated) {
40422
+ safeWrite(`
40423
+ ${c2.green("\u2714")} Done.
40424
+ `);
40084
40425
  await new Promise((r) => setTimeout(r, 1e3));
40085
- } else {
40086
- cfSpinner.stop("cloudflared ready.");
40426
+ process.stdout.write("\x1B[?1049l");
40427
+ return;
40087
40428
  }
40088
- ensureTranscribeCliBackground();
40089
40429
  const reloadSpinner = startInlineSpinner("Loading");
40090
40430
  await new Promise((r) => setTimeout(r, 400));
40091
40431
  ctx.contextSave?.();
@@ -40433,8 +40773,8 @@ var init_commands = __esm({
40433
40773
  });
40434
40774
 
40435
40775
  // packages/cli/dist/tui/project-context.js
40436
- import { existsSync as existsSync35, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
40437
- import { join as join43, basename as basename10 } from "node:path";
40776
+ import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
40777
+ import { join as join44, basename as basename10 } from "node:path";
40438
40778
  import { execSync as execSync28 } from "node:child_process";
40439
40779
  import { homedir as homedir12, platform as platform3, release } from "node:os";
40440
40780
  function getModelTier(modelName) {
@@ -40469,8 +40809,8 @@ function loadProjectMap(repoRoot) {
40469
40809
  if (!hasOaDirectory(repoRoot)) {
40470
40810
  initOaDirectory(repoRoot);
40471
40811
  }
40472
- const mapPath = join43(repoRoot, OA_DIR, "context", "project-map.md");
40473
- if (existsSync35(mapPath)) {
40812
+ const mapPath = join44(repoRoot, OA_DIR, "context", "project-map.md");
40813
+ if (existsSync36(mapPath)) {
40474
40814
  try {
40475
40815
  const content = readFileSync25(mapPath, "utf-8");
40476
40816
  return content;
@@ -40513,31 +40853,31 @@ ${log}`);
40513
40853
  }
40514
40854
  function loadMemoryContext(repoRoot) {
40515
40855
  const sections = [];
40516
- const oaMemDir = join43(repoRoot, OA_DIR, "memory");
40856
+ const oaMemDir = join44(repoRoot, OA_DIR, "memory");
40517
40857
  const oaEntries = loadMemoryDir(oaMemDir, "project");
40518
40858
  if (oaEntries)
40519
40859
  sections.push(oaEntries);
40520
- const legacyMemDir = join43(repoRoot, ".open-agents", "memory");
40521
- if (legacyMemDir !== oaMemDir && existsSync35(legacyMemDir)) {
40860
+ const legacyMemDir = join44(repoRoot, ".open-agents", "memory");
40861
+ if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
40522
40862
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
40523
40863
  if (legacyEntries)
40524
40864
  sections.push(legacyEntries);
40525
40865
  }
40526
- const globalMemDir = join43(homedir12(), ".open-agents", "memory");
40866
+ const globalMemDir = join44(homedir12(), ".open-agents", "memory");
40527
40867
  const globalEntries = loadMemoryDir(globalMemDir, "global");
40528
40868
  if (globalEntries)
40529
40869
  sections.push(globalEntries);
40530
40870
  return sections.join("\n\n");
40531
40871
  }
40532
40872
  function loadMemoryDir(memDir, scope) {
40533
- if (!existsSync35(memDir))
40873
+ if (!existsSync36(memDir))
40534
40874
  return "";
40535
40875
  const lines = [];
40536
40876
  try {
40537
40877
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
40538
40878
  for (const file of files.slice(0, 10)) {
40539
40879
  try {
40540
- const raw = readFileSync25(join43(memDir, file), "utf-8");
40880
+ const raw = readFileSync25(join44(memDir, file), "utf-8");
40541
40881
  const entries = JSON.parse(raw);
40542
40882
  const topic = basename10(file, ".json");
40543
40883
  const keys = Object.keys(entries);
@@ -41560,12 +41900,12 @@ var init_carousel = __esm({
41560
41900
  });
41561
41901
 
41562
41902
  // packages/cli/dist/tui/carousel-descriptors.js
41563
- import { existsSync as existsSync36, readFileSync as readFileSync26, writeFileSync as writeFileSync14, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
41564
- import { join as join44, basename as basename11 } from "node:path";
41903
+ import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
41904
+ import { join as join45, basename as basename11 } from "node:path";
41565
41905
  function loadToolProfile(repoRoot) {
41566
- const filePath = join44(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
41906
+ const filePath = join45(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
41567
41907
  try {
41568
- if (!existsSync36(filePath))
41908
+ if (!existsSync37(filePath))
41569
41909
  return null;
41570
41910
  return JSON.parse(readFileSync26(filePath, "utf-8"));
41571
41911
  } catch {
@@ -41573,9 +41913,9 @@ function loadToolProfile(repoRoot) {
41573
41913
  }
41574
41914
  }
41575
41915
  function saveToolProfile(repoRoot, profile) {
41576
- const contextDir = join44(repoRoot, OA_DIR, "context");
41916
+ const contextDir = join45(repoRoot, OA_DIR, "context");
41577
41917
  mkdirSync14(contextDir, { recursive: true });
41578
- writeFileSync14(join44(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
41918
+ writeFileSync15(join45(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
41579
41919
  }
41580
41920
  function categorizeToolCall(toolName) {
41581
41921
  for (const cat of TOOL_CATEGORIES) {
@@ -41633,9 +41973,9 @@ function weightedColor(profile) {
41633
41973
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
41634
41974
  }
41635
41975
  function loadCachedDescriptors(repoRoot) {
41636
- const filePath = join44(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
41976
+ const filePath = join45(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
41637
41977
  try {
41638
- if (!existsSync36(filePath))
41978
+ if (!existsSync37(filePath))
41639
41979
  return null;
41640
41980
  const cached = JSON.parse(readFileSync26(filePath, "utf-8"));
41641
41981
  return cached.phrases.length > 0 ? cached.phrases : null;
@@ -41644,14 +41984,14 @@ function loadCachedDescriptors(repoRoot) {
41644
41984
  }
41645
41985
  }
41646
41986
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
41647
- const contextDir = join44(repoRoot, OA_DIR, "context");
41987
+ const contextDir = join45(repoRoot, OA_DIR, "context");
41648
41988
  mkdirSync14(contextDir, { recursive: true });
41649
41989
  const cached = {
41650
41990
  phrases,
41651
41991
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
41652
41992
  sourceHash
41653
41993
  };
41654
- writeFileSync14(join44(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
41994
+ writeFileSync15(join45(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
41655
41995
  }
41656
41996
  function generateDescriptors(repoRoot) {
41657
41997
  const profile = loadToolProfile(repoRoot);
@@ -41699,9 +42039,9 @@ function generateDescriptors(repoRoot) {
41699
42039
  return phrases;
41700
42040
  }
41701
42041
  function extractFromPackageJson(repoRoot, tags) {
41702
- const pkgPath = join44(repoRoot, "package.json");
42042
+ const pkgPath = join45(repoRoot, "package.json");
41703
42043
  try {
41704
- if (!existsSync36(pkgPath))
42044
+ if (!existsSync37(pkgPath))
41705
42045
  return;
41706
42046
  const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
41707
42047
  if (pkg.name && typeof pkg.name === "string") {
@@ -41747,7 +42087,7 @@ function extractFromManifests(repoRoot, tags) {
41747
42087
  { file: ".github/workflows", tag: "ci/cd" }
41748
42088
  ];
41749
42089
  for (const check of manifestChecks) {
41750
- if (existsSync36(join44(repoRoot, check.file))) {
42090
+ if (existsSync37(join45(repoRoot, check.file))) {
41751
42091
  tags.push(check.tag);
41752
42092
  }
41753
42093
  }
@@ -41769,16 +42109,16 @@ function extractFromSessions(repoRoot, tags) {
41769
42109
  }
41770
42110
  }
41771
42111
  function extractFromMemory(repoRoot, tags) {
41772
- const memoryDir = join44(repoRoot, OA_DIR, "memory");
42112
+ const memoryDir = join45(repoRoot, OA_DIR, "memory");
41773
42113
  try {
41774
- if (!existsSync36(memoryDir))
42114
+ if (!existsSync37(memoryDir))
41775
42115
  return;
41776
42116
  const files = readdirSync11(memoryDir).filter((f) => f.endsWith(".json"));
41777
42117
  for (const file of files) {
41778
42118
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
41779
42119
  tags.push(topic);
41780
42120
  try {
41781
- const data = JSON.parse(readFileSync26(join44(memoryDir, file), "utf-8"));
42121
+ const data = JSON.parse(readFileSync26(join45(memoryDir, file), "utf-8"));
41782
42122
  if (data && typeof data === "object") {
41783
42123
  const keys = Object.keys(data).slice(0, 3);
41784
42124
  for (const key of keys) {
@@ -42401,10 +42741,10 @@ var init_stream_renderer = __esm({
42401
42741
 
42402
42742
  // packages/cli/dist/tui/edit-history.js
42403
42743
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
42404
- import { join as join45 } from "node:path";
42744
+ import { join as join46 } from "node:path";
42405
42745
  function createEditHistoryLogger(repoRoot, sessionId) {
42406
- const historyDir = join45(repoRoot, ".oa", "history");
42407
- const logPath = join45(historyDir, "edits.jsonl");
42746
+ const historyDir = join46(repoRoot, ".oa", "history");
42747
+ const logPath = join46(historyDir, "edits.jsonl");
42408
42748
  try {
42409
42749
  mkdirSync15(historyDir, { recursive: true });
42410
42750
  } catch {
@@ -42515,14 +42855,14 @@ var init_edit_history = __esm({
42515
42855
  });
42516
42856
 
42517
42857
  // packages/cli/dist/tui/promptLoader.js
42518
- import { readFileSync as readFileSync27, existsSync as existsSync37 } from "node:fs";
42519
- import { join as join46, dirname as dirname17 } from "node:path";
42858
+ import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
42859
+ import { join as join47, dirname as dirname17 } from "node:path";
42520
42860
  import { fileURLToPath as fileURLToPath11 } from "node:url";
42521
42861
  function loadPrompt3(promptPath, vars) {
42522
42862
  let content = cache3.get(promptPath);
42523
42863
  if (content === void 0) {
42524
- const fullPath = join46(PROMPTS_DIR3, promptPath);
42525
- if (!existsSync37(fullPath)) {
42864
+ const fullPath = join47(PROMPTS_DIR3, promptPath);
42865
+ if (!existsSync38(fullPath)) {
42526
42866
  throw new Error(`Prompt file not found: ${fullPath}`);
42527
42867
  }
42528
42868
  content = readFileSync27(fullPath, "utf-8");
@@ -42538,20 +42878,20 @@ var init_promptLoader3 = __esm({
42538
42878
  "use strict";
42539
42879
  __filename3 = fileURLToPath11(import.meta.url);
42540
42880
  __dirname6 = dirname17(__filename3);
42541
- devPath2 = join46(__dirname6, "..", "..", "prompts");
42542
- publishedPath2 = join46(__dirname6, "..", "prompts");
42543
- PROMPTS_DIR3 = existsSync37(devPath2) ? devPath2 : publishedPath2;
42881
+ devPath2 = join47(__dirname6, "..", "..", "prompts");
42882
+ publishedPath2 = join47(__dirname6, "..", "prompts");
42883
+ PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
42544
42884
  cache3 = /* @__PURE__ */ new Map();
42545
42885
  }
42546
42886
  });
42547
42887
 
42548
42888
  // packages/cli/dist/tui/dream-engine.js
42549
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync15, readFileSync as readFileSync28, existsSync as existsSync38, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
42550
- import { join as join47, basename as basename12 } from "node:path";
42889
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
42890
+ import { join as join48, basename as basename12 } from "node:path";
42551
42891
  import { execSync as execSync29 } from "node:child_process";
42552
42892
  function loadAutoresearchMemory(repoRoot) {
42553
- const memoryPath = join47(repoRoot, ".oa", "memory", "autoresearch.json");
42554
- if (!existsSync38(memoryPath))
42893
+ const memoryPath = join48(repoRoot, ".oa", "memory", "autoresearch.json");
42894
+ if (!existsSync39(memoryPath))
42555
42895
  return "";
42556
42896
  try {
42557
42897
  const raw = readFileSync28(memoryPath, "utf-8");
@@ -42744,14 +43084,14 @@ var init_dream_engine = __esm({
42744
43084
  const content = String(args["content"] ?? "");
42745
43085
  if (!rawPath)
42746
43086
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
42747
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join47(this.autoresearchDir, basename12(rawPath)) : join47(this.autoresearchDir, rawPath);
43087
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
42748
43088
  if (!targetPath.startsWith(this.autoresearchDir)) {
42749
43089
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
42750
43090
  }
42751
43091
  try {
42752
- const dir = join47(targetPath, "..");
43092
+ const dir = join48(targetPath, "..");
42753
43093
  mkdirSync16(dir, { recursive: true });
42754
- writeFileSync15(targetPath, content, "utf-8");
43094
+ writeFileSync16(targetPath, content, "utf-8");
42755
43095
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
42756
43096
  } catch (err) {
42757
43097
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42779,12 +43119,12 @@ var init_dream_engine = __esm({
42779
43119
  const rawPath = String(args["path"] ?? "");
42780
43120
  const oldStr = String(args["old_string"] ?? "");
42781
43121
  const newStr = String(args["new_string"] ?? "");
42782
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join47(this.autoresearchDir, basename12(rawPath)) : join47(this.autoresearchDir, rawPath);
43122
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
42783
43123
  if (!targetPath.startsWith(this.autoresearchDir)) {
42784
43124
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
42785
43125
  }
42786
43126
  try {
42787
- if (!existsSync38(targetPath)) {
43127
+ if (!existsSync39(targetPath)) {
42788
43128
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
42789
43129
  }
42790
43130
  let content = readFileSync28(targetPath, "utf-8");
@@ -42792,7 +43132,7 @@ var init_dream_engine = __esm({
42792
43132
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
42793
43133
  }
42794
43134
  content = content.replace(oldStr, newStr);
42795
- writeFileSync15(targetPath, content, "utf-8");
43135
+ writeFileSync16(targetPath, content, "utf-8");
42796
43136
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
42797
43137
  } catch (err) {
42798
43138
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42833,14 +43173,14 @@ var init_dream_engine = __esm({
42833
43173
  const content = String(args["content"] ?? "");
42834
43174
  if (!rawPath)
42835
43175
  return { success: false, output: "", error: "path is required", durationMs: Date.now() - start };
42836
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join47(this.dreamsDir, basename12(rawPath)) : join47(this.dreamsDir, rawPath);
43176
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
42837
43177
  if (!targetPath.startsWith(this.dreamsDir)) {
42838
43178
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
42839
43179
  }
42840
43180
  try {
42841
- const dir = join47(targetPath, "..");
43181
+ const dir = join48(targetPath, "..");
42842
43182
  mkdirSync16(dir, { recursive: true });
42843
- writeFileSync15(targetPath, content, "utf-8");
43183
+ writeFileSync16(targetPath, content, "utf-8");
42844
43184
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
42845
43185
  } catch (err) {
42846
43186
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42868,12 +43208,12 @@ var init_dream_engine = __esm({
42868
43208
  const rawPath = String(args["path"] ?? "");
42869
43209
  const oldStr = String(args["old_string"] ?? "");
42870
43210
  const newStr = String(args["new_string"] ?? "");
42871
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join47(this.dreamsDir, basename12(rawPath)) : join47(this.dreamsDir, rawPath);
43211
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
42872
43212
  if (!targetPath.startsWith(this.dreamsDir)) {
42873
43213
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
42874
43214
  }
42875
43215
  try {
42876
- if (!existsSync38(targetPath)) {
43216
+ if (!existsSync39(targetPath)) {
42877
43217
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
42878
43218
  }
42879
43219
  let content = readFileSync28(targetPath, "utf-8");
@@ -42881,7 +43221,7 @@ var init_dream_engine = __esm({
42881
43221
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
42882
43222
  }
42883
43223
  content = content.replace(oldStr, newStr);
42884
- writeFileSync15(targetPath, content, "utf-8");
43224
+ writeFileSync16(targetPath, content, "utf-8");
42885
43225
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
42886
43226
  } catch (err) {
42887
43227
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42935,7 +43275,7 @@ var init_dream_engine = __esm({
42935
43275
  constructor(config, repoRoot) {
42936
43276
  this.config = config;
42937
43277
  this.repoRoot = repoRoot;
42938
- this.dreamsDir = join47(repoRoot, ".oa", "dreams");
43278
+ this.dreamsDir = join48(repoRoot, ".oa", "dreams");
42939
43279
  this.state = {
42940
43280
  mode: "default",
42941
43281
  active: false,
@@ -43019,8 +43359,8 @@ ${result.summary}`;
43019
43359
  if (mode !== "default" || cycle === totalCycles) {
43020
43360
  renderDreamContraction(cycle);
43021
43361
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
43022
- const summaryPath = join47(this.dreamsDir, `cycle-${cycle}-summary.md`);
43023
- writeFileSync15(summaryPath, cycleSummary, "utf-8");
43362
+ const summaryPath = join48(this.dreamsDir, `cycle-${cycle}-summary.md`);
43363
+ writeFileSync16(summaryPath, cycleSummary, "utf-8");
43024
43364
  }
43025
43365
  if (mode === "lucid" && !this.abortController.signal.aborted) {
43026
43366
  this.saveVersionCheckpoint(cycle);
@@ -43232,7 +43572,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
43232
43572
  }
43233
43573
  /** Build role-specific tool sets for swarm agents */
43234
43574
  buildSwarmTools(role, _workspace) {
43235
- const autoresearchDir = join47(this.repoRoot, ".oa", "autoresearch");
43575
+ const autoresearchDir = join48(this.repoRoot, ".oa", "autoresearch");
43236
43576
  const taskComplete = this.createSwarmTaskCompleteTool(role);
43237
43577
  switch (role) {
43238
43578
  case "researcher": {
@@ -43596,7 +43936,7 @@ INSTRUCTIONS:
43596
43936
  2. Summarize the key learnings and next steps
43597
43937
 
43598
43938
  Call task_complete with a human-readable summary of the autoresearch session.`, workspace, onEvent);
43599
- const reportPath = join47(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
43939
+ const reportPath = join48(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
43600
43940
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
43601
43941
 
43602
43942
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -43619,7 +43959,7 @@ ${summaryResult}
43619
43959
  `;
43620
43960
  try {
43621
43961
  mkdirSync16(this.dreamsDir, { recursive: true });
43622
- writeFileSync15(reportPath, report, "utf-8");
43962
+ writeFileSync16(reportPath, report, "utf-8");
43623
43963
  } catch {
43624
43964
  }
43625
43965
  renderSwarmComplete(workspace);
@@ -43685,7 +44025,7 @@ ${summaryResult}
43685
44025
  }
43686
44026
  /** Save workspace backup for lucid mode */
43687
44027
  saveVersionCheckpoint(cycle) {
43688
- const checkpointDir = join47(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
44028
+ const checkpointDir = join48(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
43689
44029
  try {
43690
44030
  mkdirSync16(checkpointDir, { recursive: true });
43691
44031
  try {
@@ -43704,10 +44044,10 @@ ${summaryResult}
43704
44044
  encoding: "utf-8",
43705
44045
  timeout: 5e3
43706
44046
  }).trim();
43707
- writeFileSync15(join47(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
43708
- writeFileSync15(join47(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
43709
- writeFileSync15(join47(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
43710
- writeFileSync15(join47(checkpointDir, "checkpoint.json"), JSON.stringify({
44047
+ writeFileSync16(join48(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
44048
+ writeFileSync16(join48(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
44049
+ writeFileSync16(join48(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
44050
+ writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({
43711
44051
  cycle,
43712
44052
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
43713
44053
  gitHash,
@@ -43715,7 +44055,7 @@ ${summaryResult}
43715
44055
  }, null, 2), "utf-8");
43716
44056
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
43717
44057
  } catch {
43718
- writeFileSync15(join47(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44058
+ writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
43719
44059
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
43720
44060
  }
43721
44061
  } catch (err) {
@@ -43773,14 +44113,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
43773
44113
  ---
43774
44114
  *Auto-generated by open-agents dream engine*
43775
44115
  `;
43776
- writeFileSync15(join47(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44116
+ writeFileSync16(join48(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
43777
44117
  } catch {
43778
44118
  }
43779
44119
  }
43780
44120
  /** Save dream state for resume/inspection */
43781
44121
  saveDreamState() {
43782
44122
  try {
43783
- writeFileSync15(join47(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44123
+ writeFileSync16(join48(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
43784
44124
  } catch {
43785
44125
  }
43786
44126
  }
@@ -44154,8 +44494,8 @@ var init_bless_engine = __esm({
44154
44494
  });
44155
44495
 
44156
44496
  // packages/cli/dist/tui/dmn-engine.js
44157
- import { existsSync as existsSync39, readFileSync as readFileSync29, writeFileSync as writeFileSync16, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync7 } from "node:fs";
44158
- import { join as join48, basename as basename13 } from "node:path";
44497
+ import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync8 } from "node:fs";
44498
+ import { join as join49, basename as basename13 } from "node:path";
44159
44499
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
44160
44500
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
44161
44501
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -44268,8 +44608,8 @@ var init_dmn_engine = __esm({
44268
44608
  constructor(config, repoRoot) {
44269
44609
  this.config = config;
44270
44610
  this.repoRoot = repoRoot;
44271
- this.stateDir = join48(repoRoot, ".oa", "dmn");
44272
- this.historyDir = join48(repoRoot, ".oa", "dmn", "cycles");
44611
+ this.stateDir = join49(repoRoot, ".oa", "dmn");
44612
+ this.historyDir = join49(repoRoot, ".oa", "dmn", "cycles");
44273
44613
  mkdirSync17(this.historyDir, { recursive: true });
44274
44614
  this.loadState();
44275
44615
  }
@@ -44859,11 +45199,11 @@ OUTPUT: Call task_complete with JSON:
44859
45199
  async gatherMemoryTopics() {
44860
45200
  const topics = [];
44861
45201
  const dirs = [
44862
- join48(this.repoRoot, ".oa", "memory"),
44863
- join48(this.repoRoot, ".open-agents", "memory")
45202
+ join49(this.repoRoot, ".oa", "memory"),
45203
+ join49(this.repoRoot, ".open-agents", "memory")
44864
45204
  ];
44865
45205
  for (const dir of dirs) {
44866
- if (!existsSync39(dir))
45206
+ if (!existsSync40(dir))
44867
45207
  continue;
44868
45208
  try {
44869
45209
  const files = readdirSync13(dir).filter((f) => f.endsWith(".json"));
@@ -44879,8 +45219,8 @@ OUTPUT: Call task_complete with JSON:
44879
45219
  }
44880
45220
  // ── State persistence ─────────────────────────────────────────────────
44881
45221
  loadState() {
44882
- const path = join48(this.stateDir, "state.json");
44883
- if (existsSync39(path)) {
45222
+ const path = join49(this.stateDir, "state.json");
45223
+ if (existsSync40(path)) {
44884
45224
  try {
44885
45225
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
44886
45226
  } catch {
@@ -44889,19 +45229,19 @@ OUTPUT: Call task_complete with JSON:
44889
45229
  }
44890
45230
  saveState() {
44891
45231
  try {
44892
- writeFileSync16(join48(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45232
+ writeFileSync17(join49(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44893
45233
  } catch {
44894
45234
  }
44895
45235
  }
44896
45236
  saveCycleResult(result) {
44897
45237
  try {
44898
45238
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
44899
- writeFileSync16(join48(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45239
+ writeFileSync17(join49(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
44900
45240
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
44901
45241
  if (files.length > 50) {
44902
45242
  for (const old of files.slice(0, files.length - 50)) {
44903
45243
  try {
44904
- unlinkSync7(join48(this.historyDir, old));
45244
+ unlinkSync8(join49(this.historyDir, old));
44905
45245
  } catch {
44906
45246
  }
44907
45247
  }
@@ -44914,8 +45254,8 @@ OUTPUT: Call task_complete with JSON:
44914
45254
  });
44915
45255
 
44916
45256
  // packages/cli/dist/tui/snr-engine.js
44917
- import { existsSync as existsSync40, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
44918
- import { join as join49, basename as basename14 } from "node:path";
45257
+ import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
45258
+ import { join as join50, basename as basename14 } from "node:path";
44919
45259
  function computeDPrime(signalScores, noiseScores) {
44920
45260
  if (signalScores.length === 0 || noiseScores.length === 0)
44921
45261
  return 0;
@@ -45155,11 +45495,11 @@ Call task_complete with the JSON array when done.`, onEvent)
45155
45495
  loadMemoryEntries(topics) {
45156
45496
  const entries = [];
45157
45497
  const dirs = [
45158
- join49(this.repoRoot, ".oa", "memory"),
45159
- join49(this.repoRoot, ".open-agents", "memory")
45498
+ join50(this.repoRoot, ".oa", "memory"),
45499
+ join50(this.repoRoot, ".open-agents", "memory")
45160
45500
  ];
45161
45501
  for (const dir of dirs) {
45162
- if (!existsSync40(dir))
45502
+ if (!existsSync41(dir))
45163
45503
  continue;
45164
45504
  try {
45165
45505
  const files = readdirSync14(dir).filter((f) => f.endsWith(".json"));
@@ -45168,7 +45508,7 @@ Call task_complete with the JSON array when done.`, onEvent)
45168
45508
  if (topics.length > 0 && !topics.includes(topic))
45169
45509
  continue;
45170
45510
  try {
45171
- const data = JSON.parse(readFileSync30(join49(dir, f), "utf-8"));
45511
+ const data = JSON.parse(readFileSync30(join50(dir, f), "utf-8"));
45172
45512
  for (const [key, val] of Object.entries(data)) {
45173
45513
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
45174
45514
  entries.push({ topic, key, value });
@@ -45735,8 +46075,8 @@ var init_tool_policy = __esm({
45735
46075
  });
45736
46076
 
45737
46077
  // packages/cli/dist/tui/telegram-bridge.js
45738
- import { mkdirSync as mkdirSync18, existsSync as existsSync41, unlinkSync as unlinkSync8, readdirSync as readdirSync15, statSync as statSync12 } from "node:fs";
45739
- import { join as join50, resolve as resolve28 } from "node:path";
46078
+ import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync9, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46079
+ import { join as join51, resolve as resolve28 } from "node:path";
45740
46080
  import { writeFile as writeFileAsync } from "node:fs/promises";
45741
46081
  function convertMarkdownToTelegramHTML(md) {
45742
46082
  let html = md;
@@ -46501,7 +46841,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46501
46841
  return null;
46502
46842
  const buffer = Buffer.from(await res.arrayBuffer());
46503
46843
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
46504
- const localPath = join50(this.mediaCacheDir, fileName);
46844
+ const localPath = join51(this.mediaCacheDir, fileName);
46505
46845
  await writeFileAsync(localPath, buffer);
46506
46846
  return localPath;
46507
46847
  } catch {
@@ -46589,7 +46929,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46589
46929
  for (const [key, entry] of this.mediaCache) {
46590
46930
  if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
46591
46931
  try {
46592
- unlinkSync8(entry.localPath);
46932
+ unlinkSync9(entry.localPath);
46593
46933
  } catch {
46594
46934
  }
46595
46935
  this.mediaCache.delete(key);
@@ -46665,11 +47005,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46665
47005
  let mimeType = "audio/wav";
46666
47006
  try {
46667
47007
  const { execSync: execSyncLocal } = await import("node:child_process");
46668
- const { tmpdir: tmpdir9 } = await import("node:os");
47008
+ const { tmpdir: tmpdir10 } = await import("node:os");
46669
47009
  const { join: joinPath } = await import("node:path");
46670
47010
  const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
46671
- const tmpWav = joinPath(tmpdir9(), `oa-tg-voice-${Date.now()}.wav`);
46672
- const tmpOgg = joinPath(tmpdir9(), `oa-tg-voice-${Date.now()}.ogg`);
47011
+ const tmpWav = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.wav`);
47012
+ const tmpOgg = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.ogg`);
46673
47013
  writeFs(tmpWav, wavBuffer);
46674
47014
  execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
46675
47015
  timeout: 15e3,
@@ -48940,11 +49280,11 @@ var init_status_bar = __esm({
48940
49280
  import * as readline2 from "node:readline";
48941
49281
  import { Writable } from "node:stream";
48942
49282
  import { cwd } from "node:process";
48943
- import { resolve as resolve29, join as join51, dirname as dirname18, extname as extname10 } from "node:path";
49283
+ import { resolve as resolve29, join as join52, dirname as dirname18, extname as extname10 } from "node:path";
48944
49284
  import { createRequire as createRequire2 } from "node:module";
48945
49285
  import { fileURLToPath as fileURLToPath12 } from "node:url";
48946
- import { readFileSync as readFileSync31, writeFileSync as writeFileSync17, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
48947
- import { existsSync as existsSync42 } from "node:fs";
49286
+ import { readFileSync as readFileSync31, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
49287
+ import { existsSync as existsSync43 } from "node:fs";
48948
49288
  import { homedir as homedir13 } from "node:os";
48949
49289
  function formatTimeAgo(date) {
48950
49290
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -48964,12 +49304,12 @@ function getVersion3() {
48964
49304
  const require2 = createRequire2(import.meta.url);
48965
49305
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
48966
49306
  const candidates = [
48967
- join51(thisDir, "..", "package.json"),
48968
- join51(thisDir, "..", "..", "package.json"),
48969
- join51(thisDir, "..", "..", "..", "package.json")
49307
+ join52(thisDir, "..", "package.json"),
49308
+ join52(thisDir, "..", "..", "package.json"),
49309
+ join52(thisDir, "..", "..", "..", "package.json")
48970
49310
  ];
48971
49311
  for (const pkgPath of candidates) {
48972
- if (existsSync42(pkgPath)) {
49312
+ if (existsSync43(pkgPath)) {
48973
49313
  const pkg = require2(pkgPath);
48974
49314
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
48975
49315
  return pkg.version ?? "0.0.0";
@@ -49176,15 +49516,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
49176
49516
  function gatherMemorySnippets(root) {
49177
49517
  const snippets = [];
49178
49518
  const dirs = [
49179
- join51(root, ".oa", "memory"),
49180
- join51(root, ".open-agents", "memory")
49519
+ join52(root, ".oa", "memory"),
49520
+ join52(root, ".open-agents", "memory")
49181
49521
  ];
49182
49522
  for (const dir of dirs) {
49183
- if (!existsSync42(dir))
49523
+ if (!existsSync43(dir))
49184
49524
  continue;
49185
49525
  try {
49186
49526
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
49187
- const data = JSON.parse(readFileSync31(join51(dir, f), "utf-8"));
49527
+ const data = JSON.parse(readFileSync31(join52(dir, f), "utf-8"));
49188
49528
  for (const val of Object.values(data)) {
49189
49529
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
49190
49530
  if (v.length > 10)
@@ -50148,7 +50488,7 @@ async function startInteractive(config, repoPath) {
50148
50488
  let p2pGateway = null;
50149
50489
  let peerMesh = null;
50150
50490
  let inferenceRouter = null;
50151
- const secretVault = new SecretVault(join51(repoRoot, ".oa", "vault.enc"));
50491
+ const secretVault = new SecretVault(join52(repoRoot, ".oa", "vault.enc"));
50152
50492
  let adminSessionKey = null;
50153
50493
  const callSubAgents = /* @__PURE__ */ new Map();
50154
50494
  const streamRenderer = new StreamRenderer();
@@ -50357,12 +50697,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50357
50697
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
50358
50698
  return [hits, line];
50359
50699
  }
50360
- const HISTORY_DIR = join51(homedir13(), ".open-agents");
50361
- const HISTORY_FILE = join51(HISTORY_DIR, "repl-history");
50700
+ const HISTORY_DIR = join52(homedir13(), ".open-agents");
50701
+ const HISTORY_FILE = join52(HISTORY_DIR, "repl-history");
50362
50702
  const MAX_HISTORY_LINES = 500;
50363
50703
  let savedHistory = [];
50364
50704
  try {
50365
- if (existsSync42(HISTORY_FILE)) {
50705
+ if (existsSync43(HISTORY_FILE)) {
50366
50706
  const raw = readFileSync31(HISTORY_FILE, "utf8").trim();
50367
50707
  if (raw)
50368
50708
  savedHistory = raw.split("\n").reverse();
@@ -50387,7 +50727,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50387
50727
  if (Math.random() < 0.02) {
50388
50728
  const all = readFileSync31(HISTORY_FILE, "utf8").trim().split("\n");
50389
50729
  if (all.length > MAX_HISTORY_LINES) {
50390
- writeFileSync17(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
50730
+ writeFileSync18(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
50391
50731
  }
50392
50732
  }
50393
50733
  } catch {
@@ -50568,7 +50908,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50568
50908
  } catch {
50569
50909
  }
50570
50910
  try {
50571
- const oaDir = join51(repoRoot, ".oa");
50911
+ const oaDir = join52(repoRoot, ".oa");
50572
50912
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
50573
50913
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
50574
50914
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -50591,7 +50931,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50591
50931
  } catch {
50592
50932
  }
50593
50933
  try {
50594
- const oaDir = join51(repoRoot, ".oa");
50934
+ const oaDir = join52(repoRoot, ".oa");
50595
50935
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
50596
50936
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
50597
50937
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51410,7 +51750,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51410
51750
  kind,
51411
51751
  targetUrl,
51412
51752
  authKey,
51413
- stateDir: join51(repoRoot, ".oa"),
51753
+ stateDir: join52(repoRoot, ".oa"),
51414
51754
  passthrough: passthrough ?? false,
51415
51755
  loadbalance: loadbalance ?? false,
51416
51756
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -51458,7 +51798,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51458
51798
  await tunnelGateway.stop();
51459
51799
  tunnelGateway = null;
51460
51800
  }
51461
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join51(repoRoot, ".oa") });
51801
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join52(repoRoot, ".oa") });
51462
51802
  newTunnel.on("stats", (stats) => {
51463
51803
  statusBar.setExposeStatus({
51464
51804
  status: stats.status,
@@ -51720,8 +52060,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51720
52060
  }
51721
52061
  },
51722
52062
  destroyProject() {
51723
- const oaPath = join51(repoRoot, OA_DIR);
51724
- if (existsSync42(oaPath)) {
52063
+ const oaPath = join52(repoRoot, OA_DIR);
52064
+ if (existsSync43(oaPath)) {
51725
52065
  try {
51726
52066
  rmSync2(oaPath, { recursive: true, force: true });
51727
52067
  writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
@@ -52066,8 +52406,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
52066
52406
  }
52067
52407
  }
52068
52408
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
52069
- const isImage = isImagePath(cleanPath) && existsSync42(resolve29(repoRoot, cleanPath));
52070
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync42(resolve29(repoRoot, cleanPath));
52409
+ const isImage = isImagePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
52410
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
52071
52411
  if (activeTask) {
52072
52412
  if (activeTask.runner.isPaused) {
52073
52413
  activeTask.runner.resume();
@@ -52655,7 +52995,7 @@ import { glob } from "glob";
52655
52995
  import ignore from "ignore";
52656
52996
  import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
52657
52997
  import { createHash as createHash4 } from "node:crypto";
52658
- import { join as join52, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
52998
+ import { join as join53, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
52659
52999
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
52660
53000
  var init_codebase_indexer = __esm({
52661
53001
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -52699,7 +53039,7 @@ var init_codebase_indexer = __esm({
52699
53039
  const ig = ignore.default();
52700
53040
  if (this.config.respectGitignore) {
52701
53041
  try {
52702
- const gitignoreContent = await readFile17(join52(this.config.rootDir, ".gitignore"), "utf-8");
53042
+ const gitignoreContent = await readFile17(join53(this.config.rootDir, ".gitignore"), "utf-8");
52703
53043
  ig.add(gitignoreContent);
52704
53044
  } catch {
52705
53045
  }
@@ -52714,7 +53054,7 @@ var init_codebase_indexer = __esm({
52714
53054
  for (const relativePath of files) {
52715
53055
  if (ig.ignores(relativePath))
52716
53056
  continue;
52717
- const fullPath = join52(this.config.rootDir, relativePath);
53057
+ const fullPath = join53(this.config.rootDir, relativePath);
52718
53058
  try {
52719
53059
  const fileStat = await stat4(fullPath);
52720
53060
  if (fileStat.size > this.config.maxFileSize)
@@ -52760,7 +53100,7 @@ var init_codebase_indexer = __esm({
52760
53100
  if (!child) {
52761
53101
  child = {
52762
53102
  name: part,
52763
- path: join52(current.path, part),
53103
+ path: join53(current.path, part),
52764
53104
  type: "directory",
52765
53105
  children: []
52766
53106
  };
@@ -52843,17 +53183,17 @@ __export(index_repo_exports, {
52843
53183
  indexRepoCommand: () => indexRepoCommand
52844
53184
  });
52845
53185
  import { resolve as resolve30 } from "node:path";
52846
- import { existsSync as existsSync43, statSync as statSync13 } from "node:fs";
53186
+ import { existsSync as existsSync44, statSync as statSync14 } from "node:fs";
52847
53187
  import { cwd as cwd2 } from "node:process";
52848
53188
  async function indexRepoCommand(opts, _config) {
52849
53189
  const repoRoot = resolve30(opts.repoPath ?? cwd2());
52850
53190
  printHeader("Index Repository");
52851
53191
  printInfo(`Indexing: ${repoRoot}`);
52852
- if (!existsSync43(repoRoot)) {
53192
+ if (!existsSync44(repoRoot)) {
52853
53193
  printError(`Path does not exist: ${repoRoot}`);
52854
53194
  process.exit(1);
52855
53195
  }
52856
- const stat5 = statSync13(repoRoot);
53196
+ const stat5 = statSync14(repoRoot);
52857
53197
  if (!stat5.isDirectory()) {
52858
53198
  printError(`Path is not a directory: ${repoRoot}`);
52859
53199
  process.exit(1);
@@ -53101,7 +53441,7 @@ var config_exports = {};
53101
53441
  __export(config_exports, {
53102
53442
  configCommand: () => configCommand
53103
53443
  });
53104
- import { join as join53, resolve as resolve31 } from "node:path";
53444
+ import { join as join54, resolve as resolve31 } from "node:path";
53105
53445
  import { homedir as homedir14 } from "node:os";
53106
53446
  import { cwd as cwd3 } from "node:process";
53107
53447
  function redactIfSensitive(key, value) {
@@ -53184,7 +53524,7 @@ function handleShow(opts, config) {
53184
53524
  }
53185
53525
  }
53186
53526
  printSection("Config File");
53187
- printInfo(`~/.open-agents/config.json (${join53(homedir14(), ".open-agents", "config.json")})`);
53527
+ printInfo(`~/.open-agents/config.json (${join54(homedir14(), ".open-agents", "config.json")})`);
53188
53528
  printSection("Priority Chain");
53189
53529
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
53190
53530
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -53223,7 +53563,7 @@ function handleSet(opts, _config) {
53223
53563
  const coerced = coerceForSettings(key, value);
53224
53564
  saveProjectSettings(repoRoot, { [key]: coerced });
53225
53565
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
53226
- printInfo(`Saved to ${join53(repoRoot, ".oa", "settings.json")}`);
53566
+ printInfo(`Saved to ${join54(repoRoot, ".oa", "settings.json")}`);
53227
53567
  printInfo("This override applies only when running in this workspace.");
53228
53568
  } catch (err) {
53229
53569
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -53480,9 +53820,9 @@ var eval_exports = {};
53480
53820
  __export(eval_exports, {
53481
53821
  evalCommand: () => evalCommand
53482
53822
  });
53483
- import { tmpdir as tmpdir8 } from "node:os";
53484
- import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync18 } from "node:fs";
53485
- import { join as join54 } from "node:path";
53823
+ import { tmpdir as tmpdir9 } from "node:os";
53824
+ import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
53825
+ import { join as join55 } from "node:path";
53486
53826
  async function evalCommand(opts, config) {
53487
53827
  const suiteName = opts.suite ?? "basic";
53488
53828
  const suite = SUITES[suiteName];
@@ -53607,9 +53947,9 @@ async function evalCommand(opts, config) {
53607
53947
  process.exit(failed > 0 ? 1 : 0);
53608
53948
  }
53609
53949
  function createTempEvalRepo() {
53610
- const dir = join54(tmpdir8(), `open-agents-eval-${Date.now()}`);
53950
+ const dir = join55(tmpdir9(), `open-agents-eval-${Date.now()}`);
53611
53951
  mkdirSync20(dir, { recursive: true });
53612
- writeFileSync18(join54(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
53952
+ writeFileSync19(join55(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
53613
53953
  return dir;
53614
53954
  }
53615
53955
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -53669,7 +54009,7 @@ init_updater();
53669
54009
  import { parseArgs as nodeParseArgs2 } from "node:util";
53670
54010
  import { createRequire as createRequire3 } from "node:module";
53671
54011
  import { fileURLToPath as fileURLToPath13 } from "node:url";
53672
- import { dirname as dirname19, join as join55 } from "node:path";
54012
+ import { dirname as dirname19, join as join56 } from "node:path";
53673
54013
 
53674
54014
  // packages/cli/dist/cli.js
53675
54015
  import { createInterface } from "node:readline";
@@ -53776,7 +54116,7 @@ init_output();
53776
54116
  function getVersion4() {
53777
54117
  try {
53778
54118
  const require2 = createRequire3(import.meta.url);
53779
- const pkgPath = join55(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54119
+ const pkgPath = join56(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
53780
54120
  const pkg = require2(pkgPath);
53781
54121
  return pkg.version;
53782
54122
  } catch {