open-agents-ai 0.104.31 → 0.105.0

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 +778 -496
  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";
@@ -40433,8 +40715,8 @@ var init_commands = __esm({
40433
40715
  });
40434
40716
 
40435
40717
  // 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";
40718
+ import { existsSync as existsSync36, readFileSync as readFileSync25, readdirSync as readdirSync10 } from "node:fs";
40719
+ import { join as join44, basename as basename10 } from "node:path";
40438
40720
  import { execSync as execSync28 } from "node:child_process";
40439
40721
  import { homedir as homedir12, platform as platform3, release } from "node:os";
40440
40722
  function getModelTier(modelName) {
@@ -40469,8 +40751,8 @@ function loadProjectMap(repoRoot) {
40469
40751
  if (!hasOaDirectory(repoRoot)) {
40470
40752
  initOaDirectory(repoRoot);
40471
40753
  }
40472
- const mapPath = join43(repoRoot, OA_DIR, "context", "project-map.md");
40473
- if (existsSync35(mapPath)) {
40754
+ const mapPath = join44(repoRoot, OA_DIR, "context", "project-map.md");
40755
+ if (existsSync36(mapPath)) {
40474
40756
  try {
40475
40757
  const content = readFileSync25(mapPath, "utf-8");
40476
40758
  return content;
@@ -40513,31 +40795,31 @@ ${log}`);
40513
40795
  }
40514
40796
  function loadMemoryContext(repoRoot) {
40515
40797
  const sections = [];
40516
- const oaMemDir = join43(repoRoot, OA_DIR, "memory");
40798
+ const oaMemDir = join44(repoRoot, OA_DIR, "memory");
40517
40799
  const oaEntries = loadMemoryDir(oaMemDir, "project");
40518
40800
  if (oaEntries)
40519
40801
  sections.push(oaEntries);
40520
- const legacyMemDir = join43(repoRoot, ".open-agents", "memory");
40521
- if (legacyMemDir !== oaMemDir && existsSync35(legacyMemDir)) {
40802
+ const legacyMemDir = join44(repoRoot, ".open-agents", "memory");
40803
+ if (legacyMemDir !== oaMemDir && existsSync36(legacyMemDir)) {
40522
40804
  const legacyEntries = loadMemoryDir(legacyMemDir, "project/legacy");
40523
40805
  if (legacyEntries)
40524
40806
  sections.push(legacyEntries);
40525
40807
  }
40526
- const globalMemDir = join43(homedir12(), ".open-agents", "memory");
40808
+ const globalMemDir = join44(homedir12(), ".open-agents", "memory");
40527
40809
  const globalEntries = loadMemoryDir(globalMemDir, "global");
40528
40810
  if (globalEntries)
40529
40811
  sections.push(globalEntries);
40530
40812
  return sections.join("\n\n");
40531
40813
  }
40532
40814
  function loadMemoryDir(memDir, scope) {
40533
- if (!existsSync35(memDir))
40815
+ if (!existsSync36(memDir))
40534
40816
  return "";
40535
40817
  const lines = [];
40536
40818
  try {
40537
40819
  const files = readdirSync10(memDir).filter((f) => f.endsWith(".json"));
40538
40820
  for (const file of files.slice(0, 10)) {
40539
40821
  try {
40540
- const raw = readFileSync25(join43(memDir, file), "utf-8");
40822
+ const raw = readFileSync25(join44(memDir, file), "utf-8");
40541
40823
  const entries = JSON.parse(raw);
40542
40824
  const topic = basename10(file, ".json");
40543
40825
  const keys = Object.keys(entries);
@@ -41560,12 +41842,12 @@ var init_carousel = __esm({
41560
41842
  });
41561
41843
 
41562
41844
  // 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";
41845
+ import { existsSync as existsSync37, readFileSync as readFileSync26, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, readdirSync as readdirSync11 } from "node:fs";
41846
+ import { join as join45, basename as basename11 } from "node:path";
41565
41847
  function loadToolProfile(repoRoot) {
41566
- const filePath = join44(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
41848
+ const filePath = join45(repoRoot, OA_DIR, "context", TOOL_PROFILE_FILE);
41567
41849
  try {
41568
- if (!existsSync36(filePath))
41850
+ if (!existsSync37(filePath))
41569
41851
  return null;
41570
41852
  return JSON.parse(readFileSync26(filePath, "utf-8"));
41571
41853
  } catch {
@@ -41573,9 +41855,9 @@ function loadToolProfile(repoRoot) {
41573
41855
  }
41574
41856
  }
41575
41857
  function saveToolProfile(repoRoot, profile) {
41576
- const contextDir = join44(repoRoot, OA_DIR, "context");
41858
+ const contextDir = join45(repoRoot, OA_DIR, "context");
41577
41859
  mkdirSync14(contextDir, { recursive: true });
41578
- writeFileSync14(join44(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
41860
+ writeFileSync15(join45(contextDir, TOOL_PROFILE_FILE), JSON.stringify(profile, null, 2), "utf-8");
41579
41861
  }
41580
41862
  function categorizeToolCall(toolName) {
41581
41863
  for (const cat of TOOL_CATEGORIES) {
@@ -41633,9 +41915,9 @@ function weightedColor(profile) {
41633
41915
  return selectedCat.colors[Math.floor(Math.random() * selectedCat.colors.length)];
41634
41916
  }
41635
41917
  function loadCachedDescriptors(repoRoot) {
41636
- const filePath = join44(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
41918
+ const filePath = join45(repoRoot, OA_DIR, "context", DESCRIPTOR_FILE);
41637
41919
  try {
41638
- if (!existsSync36(filePath))
41920
+ if (!existsSync37(filePath))
41639
41921
  return null;
41640
41922
  const cached = JSON.parse(readFileSync26(filePath, "utf-8"));
41641
41923
  return cached.phrases.length > 0 ? cached.phrases : null;
@@ -41644,14 +41926,14 @@ function loadCachedDescriptors(repoRoot) {
41644
41926
  }
41645
41927
  }
41646
41928
  function saveCachedDescriptors(repoRoot, phrases, sourceHash) {
41647
- const contextDir = join44(repoRoot, OA_DIR, "context");
41929
+ const contextDir = join45(repoRoot, OA_DIR, "context");
41648
41930
  mkdirSync14(contextDir, { recursive: true });
41649
41931
  const cached = {
41650
41932
  phrases,
41651
41933
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
41652
41934
  sourceHash
41653
41935
  };
41654
- writeFileSync14(join44(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
41936
+ writeFileSync15(join45(contextDir, DESCRIPTOR_FILE), JSON.stringify(cached, null, 2), "utf-8");
41655
41937
  }
41656
41938
  function generateDescriptors(repoRoot) {
41657
41939
  const profile = loadToolProfile(repoRoot);
@@ -41699,9 +41981,9 @@ function generateDescriptors(repoRoot) {
41699
41981
  return phrases;
41700
41982
  }
41701
41983
  function extractFromPackageJson(repoRoot, tags) {
41702
- const pkgPath = join44(repoRoot, "package.json");
41984
+ const pkgPath = join45(repoRoot, "package.json");
41703
41985
  try {
41704
- if (!existsSync36(pkgPath))
41986
+ if (!existsSync37(pkgPath))
41705
41987
  return;
41706
41988
  const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
41707
41989
  if (pkg.name && typeof pkg.name === "string") {
@@ -41747,7 +42029,7 @@ function extractFromManifests(repoRoot, tags) {
41747
42029
  { file: ".github/workflows", tag: "ci/cd" }
41748
42030
  ];
41749
42031
  for (const check of manifestChecks) {
41750
- if (existsSync36(join44(repoRoot, check.file))) {
42032
+ if (existsSync37(join45(repoRoot, check.file))) {
41751
42033
  tags.push(check.tag);
41752
42034
  }
41753
42035
  }
@@ -41769,16 +42051,16 @@ function extractFromSessions(repoRoot, tags) {
41769
42051
  }
41770
42052
  }
41771
42053
  function extractFromMemory(repoRoot, tags) {
41772
- const memoryDir = join44(repoRoot, OA_DIR, "memory");
42054
+ const memoryDir = join45(repoRoot, OA_DIR, "memory");
41773
42055
  try {
41774
- if (!existsSync36(memoryDir))
42056
+ if (!existsSync37(memoryDir))
41775
42057
  return;
41776
42058
  const files = readdirSync11(memoryDir).filter((f) => f.endsWith(".json"));
41777
42059
  for (const file of files) {
41778
42060
  const topic = file.replace(/\.json$/, "").replace(/[-_]/g, " ");
41779
42061
  tags.push(topic);
41780
42062
  try {
41781
- const data = JSON.parse(readFileSync26(join44(memoryDir, file), "utf-8"));
42063
+ const data = JSON.parse(readFileSync26(join45(memoryDir, file), "utf-8"));
41782
42064
  if (data && typeof data === "object") {
41783
42065
  const keys = Object.keys(data).slice(0, 3);
41784
42066
  for (const key of keys) {
@@ -42401,10 +42683,10 @@ var init_stream_renderer = __esm({
42401
42683
 
42402
42684
  // packages/cli/dist/tui/edit-history.js
42403
42685
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15 } from "node:fs";
42404
- import { join as join45 } from "node:path";
42686
+ import { join as join46 } from "node:path";
42405
42687
  function createEditHistoryLogger(repoRoot, sessionId) {
42406
- const historyDir = join45(repoRoot, ".oa", "history");
42407
- const logPath = join45(historyDir, "edits.jsonl");
42688
+ const historyDir = join46(repoRoot, ".oa", "history");
42689
+ const logPath = join46(historyDir, "edits.jsonl");
42408
42690
  try {
42409
42691
  mkdirSync15(historyDir, { recursive: true });
42410
42692
  } catch {
@@ -42515,14 +42797,14 @@ var init_edit_history = __esm({
42515
42797
  });
42516
42798
 
42517
42799
  // 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";
42800
+ import { readFileSync as readFileSync27, existsSync as existsSync38 } from "node:fs";
42801
+ import { join as join47, dirname as dirname17 } from "node:path";
42520
42802
  import { fileURLToPath as fileURLToPath11 } from "node:url";
42521
42803
  function loadPrompt3(promptPath, vars) {
42522
42804
  let content = cache3.get(promptPath);
42523
42805
  if (content === void 0) {
42524
- const fullPath = join46(PROMPTS_DIR3, promptPath);
42525
- if (!existsSync37(fullPath)) {
42806
+ const fullPath = join47(PROMPTS_DIR3, promptPath);
42807
+ if (!existsSync38(fullPath)) {
42526
42808
  throw new Error(`Prompt file not found: ${fullPath}`);
42527
42809
  }
42528
42810
  content = readFileSync27(fullPath, "utf-8");
@@ -42538,20 +42820,20 @@ var init_promptLoader3 = __esm({
42538
42820
  "use strict";
42539
42821
  __filename3 = fileURLToPath11(import.meta.url);
42540
42822
  __dirname6 = dirname17(__filename3);
42541
- devPath2 = join46(__dirname6, "..", "..", "prompts");
42542
- publishedPath2 = join46(__dirname6, "..", "prompts");
42543
- PROMPTS_DIR3 = existsSync37(devPath2) ? devPath2 : publishedPath2;
42823
+ devPath2 = join47(__dirname6, "..", "..", "prompts");
42824
+ publishedPath2 = join47(__dirname6, "..", "prompts");
42825
+ PROMPTS_DIR3 = existsSync38(devPath2) ? devPath2 : publishedPath2;
42544
42826
  cache3 = /* @__PURE__ */ new Map();
42545
42827
  }
42546
42828
  });
42547
42829
 
42548
42830
  // 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";
42831
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16, readFileSync as readFileSync28, existsSync as existsSync39, cpSync, rmSync, readdirSync as readdirSync12 } from "node:fs";
42832
+ import { join as join48, basename as basename12 } from "node:path";
42551
42833
  import { execSync as execSync29 } from "node:child_process";
42552
42834
  function loadAutoresearchMemory(repoRoot) {
42553
- const memoryPath = join47(repoRoot, ".oa", "memory", "autoresearch.json");
42554
- if (!existsSync38(memoryPath))
42835
+ const memoryPath = join48(repoRoot, ".oa", "memory", "autoresearch.json");
42836
+ if (!existsSync39(memoryPath))
42555
42837
  return "";
42556
42838
  try {
42557
42839
  const raw = readFileSync28(memoryPath, "utf-8");
@@ -42744,14 +43026,14 @@ var init_dream_engine = __esm({
42744
43026
  const content = String(args["content"] ?? "");
42745
43027
  if (!rawPath)
42746
43028
  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);
43029
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
42748
43030
  if (!targetPath.startsWith(this.autoresearchDir)) {
42749
43031
  return { success: false, output: "", error: "Autoresearch mode: writes are confined to .oa/autoresearch/", durationMs: Date.now() - start };
42750
43032
  }
42751
43033
  try {
42752
- const dir = join47(targetPath, "..");
43034
+ const dir = join48(targetPath, "..");
42753
43035
  mkdirSync16(dir, { recursive: true });
42754
- writeFileSync15(targetPath, content, "utf-8");
43036
+ writeFileSync16(targetPath, content, "utf-8");
42755
43037
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
42756
43038
  } catch (err) {
42757
43039
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42779,12 +43061,12 @@ var init_dream_engine = __esm({
42779
43061
  const rawPath = String(args["path"] ?? "");
42780
43062
  const oldStr = String(args["old_string"] ?? "");
42781
43063
  const newStr = String(args["new_string"] ?? "");
42782
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join47(this.autoresearchDir, basename12(rawPath)) : join47(this.autoresearchDir, rawPath);
43064
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/autoresearch") ? join48(this.autoresearchDir, basename12(rawPath)) : join48(this.autoresearchDir, rawPath);
42783
43065
  if (!targetPath.startsWith(this.autoresearchDir)) {
42784
43066
  return { success: false, output: "", error: "Autoresearch mode: edits are confined to .oa/autoresearch/", durationMs: Date.now() - start };
42785
43067
  }
42786
43068
  try {
42787
- if (!existsSync38(targetPath)) {
43069
+ if (!existsSync39(targetPath)) {
42788
43070
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
42789
43071
  }
42790
43072
  let content = readFileSync28(targetPath, "utf-8");
@@ -42792,7 +43074,7 @@ var init_dream_engine = __esm({
42792
43074
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
42793
43075
  }
42794
43076
  content = content.replace(oldStr, newStr);
42795
- writeFileSync15(targetPath, content, "utf-8");
43077
+ writeFileSync16(targetPath, content, "utf-8");
42796
43078
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
42797
43079
  } catch (err) {
42798
43080
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42833,14 +43115,14 @@ var init_dream_engine = __esm({
42833
43115
  const content = String(args["content"] ?? "");
42834
43116
  if (!rawPath)
42835
43117
  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);
43118
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
42837
43119
  if (!targetPath.startsWith(this.dreamsDir)) {
42838
43120
  return { success: false, output: "", error: "Dream mode: writes are confined to .oa/dreams/", durationMs: Date.now() - start };
42839
43121
  }
42840
43122
  try {
42841
- const dir = join47(targetPath, "..");
43123
+ const dir = join48(targetPath, "..");
42842
43124
  mkdirSync16(dir, { recursive: true });
42843
- writeFileSync15(targetPath, content, "utf-8");
43125
+ writeFileSync16(targetPath, content, "utf-8");
42844
43126
  return { success: true, output: `Wrote ${content.length} bytes to ${rawPath}`, durationMs: Date.now() - start };
42845
43127
  } catch (err) {
42846
43128
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42868,12 +43150,12 @@ var init_dream_engine = __esm({
42868
43150
  const rawPath = String(args["path"] ?? "");
42869
43151
  const oldStr = String(args["old_string"] ?? "");
42870
43152
  const newStr = String(args["new_string"] ?? "");
42871
- const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join47(this.dreamsDir, basename12(rawPath)) : join47(this.dreamsDir, rawPath);
43153
+ const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".oa/dreams") ? join48(this.dreamsDir, basename12(rawPath)) : join48(this.dreamsDir, rawPath);
42872
43154
  if (!targetPath.startsWith(this.dreamsDir)) {
42873
43155
  return { success: false, output: "", error: "Dream mode: edits are confined to .oa/dreams/", durationMs: Date.now() - start };
42874
43156
  }
42875
43157
  try {
42876
- if (!existsSync38(targetPath)) {
43158
+ if (!existsSync39(targetPath)) {
42877
43159
  return { success: false, output: "", error: `File not found: ${rawPath}`, durationMs: Date.now() - start };
42878
43160
  }
42879
43161
  let content = readFileSync28(targetPath, "utf-8");
@@ -42881,7 +43163,7 @@ var init_dream_engine = __esm({
42881
43163
  return { success: false, output: "", error: "old_string not found in file", durationMs: Date.now() - start };
42882
43164
  }
42883
43165
  content = content.replace(oldStr, newStr);
42884
- writeFileSync15(targetPath, content, "utf-8");
43166
+ writeFileSync16(targetPath, content, "utf-8");
42885
43167
  return { success: true, output: `Edited ${rawPath}`, durationMs: Date.now() - start };
42886
43168
  } catch (err) {
42887
43169
  return { success: false, output: "", error: String(err), durationMs: Date.now() - start };
@@ -42935,7 +43217,7 @@ var init_dream_engine = __esm({
42935
43217
  constructor(config, repoRoot) {
42936
43218
  this.config = config;
42937
43219
  this.repoRoot = repoRoot;
42938
- this.dreamsDir = join47(repoRoot, ".oa", "dreams");
43220
+ this.dreamsDir = join48(repoRoot, ".oa", "dreams");
42939
43221
  this.state = {
42940
43222
  mode: "default",
42941
43223
  active: false,
@@ -43019,8 +43301,8 @@ ${result.summary}`;
43019
43301
  if (mode !== "default" || cycle === totalCycles) {
43020
43302
  renderDreamContraction(cycle);
43021
43303
  const cycleSummary = this.buildCycleSummary(cycle, previousFindings);
43022
- const summaryPath = join47(this.dreamsDir, `cycle-${cycle}-summary.md`);
43023
- writeFileSync15(summaryPath, cycleSummary, "utf-8");
43304
+ const summaryPath = join48(this.dreamsDir, `cycle-${cycle}-summary.md`);
43305
+ writeFileSync16(summaryPath, cycleSummary, "utf-8");
43024
43306
  }
43025
43307
  if (mode === "lucid" && !this.abortController.signal.aborted) {
43026
43308
  this.saveVersionCheckpoint(cycle);
@@ -43232,7 +43514,7 @@ After synthesis, call task_complete with the final prioritized summary.`, toolMo
43232
43514
  }
43233
43515
  /** Build role-specific tool sets for swarm agents */
43234
43516
  buildSwarmTools(role, _workspace) {
43235
- const autoresearchDir = join47(this.repoRoot, ".oa", "autoresearch");
43517
+ const autoresearchDir = join48(this.repoRoot, ".oa", "autoresearch");
43236
43518
  const taskComplete = this.createSwarmTaskCompleteTool(role);
43237
43519
  switch (role) {
43238
43520
  case "researcher": {
@@ -43596,7 +43878,7 @@ INSTRUCTIONS:
43596
43878
  2. Summarize the key learnings and next steps
43597
43879
 
43598
43880
  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`);
43881
+ const reportPath = join48(this.dreamsDir, `cycle-${cycleNum}-autoresearch-report.md`);
43600
43882
  const report = `# Autoresearch Swarm Report \u2014 Cycle ${cycleNum}
43601
43883
 
43602
43884
  **Date**: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}
@@ -43619,7 +43901,7 @@ ${summaryResult}
43619
43901
  `;
43620
43902
  try {
43621
43903
  mkdirSync16(this.dreamsDir, { recursive: true });
43622
- writeFileSync15(reportPath, report, "utf-8");
43904
+ writeFileSync16(reportPath, report, "utf-8");
43623
43905
  } catch {
43624
43906
  }
43625
43907
  renderSwarmComplete(workspace);
@@ -43685,7 +43967,7 @@ ${summaryResult}
43685
43967
  }
43686
43968
  /** Save workspace backup for lucid mode */
43687
43969
  saveVersionCheckpoint(cycle) {
43688
- const checkpointDir = join47(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
43970
+ const checkpointDir = join48(this.dreamsDir, "checkpoints", `cycle-${cycle}`);
43689
43971
  try {
43690
43972
  mkdirSync16(checkpointDir, { recursive: true });
43691
43973
  try {
@@ -43704,10 +43986,10 @@ ${summaryResult}
43704
43986
  encoding: "utf-8",
43705
43987
  timeout: 5e3
43706
43988
  }).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({
43989
+ writeFileSync16(join48(checkpointDir, "git-status.txt"), gitStatus, "utf-8");
43990
+ writeFileSync16(join48(checkpointDir, "git-diff.patch"), gitDiff, "utf-8");
43991
+ writeFileSync16(join48(checkpointDir, "git-hash.txt"), gitHash, "utf-8");
43992
+ writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({
43711
43993
  cycle,
43712
43994
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
43713
43995
  gitHash,
@@ -43715,7 +43997,7 @@ ${summaryResult}
43715
43997
  }, null, 2), "utf-8");
43716
43998
  renderInfo(`Checkpoint saved: cycle ${cycle} (${gitHash.slice(0, 8)})`);
43717
43999
  } catch {
43718
- writeFileSync15(join47(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
44000
+ writeFileSync16(join48(checkpointDir, "checkpoint.json"), JSON.stringify({ cycle, timestamp: (/* @__PURE__ */ new Date()).toISOString(), mode: this.state.mode }, null, 2), "utf-8");
43719
44001
  renderInfo(`Checkpoint saved: cycle ${cycle} (no git)`);
43720
44002
  }
43721
44003
  } catch (err) {
@@ -43773,14 +44055,14 @@ ${files.map((f) => `- [\`${f}\`](./${f})`).join("\n")}
43773
44055
  ---
43774
44056
  *Auto-generated by open-agents dream engine*
43775
44057
  `;
43776
- writeFileSync15(join47(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
44058
+ writeFileSync16(join48(this.dreamsDir, "PROPOSAL-INDEX.md"), index, "utf-8");
43777
44059
  } catch {
43778
44060
  }
43779
44061
  }
43780
44062
  /** Save dream state for resume/inspection */
43781
44063
  saveDreamState() {
43782
44064
  try {
43783
- writeFileSync15(join47(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44065
+ writeFileSync16(join48(this.dreamsDir, "dream-state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
43784
44066
  } catch {
43785
44067
  }
43786
44068
  }
@@ -44154,8 +44436,8 @@ var init_bless_engine = __esm({
44154
44436
  });
44155
44437
 
44156
44438
  // 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";
44439
+ import { existsSync as existsSync40, readFileSync as readFileSync29, writeFileSync as writeFileSync17, mkdirSync as mkdirSync17, readdirSync as readdirSync13, unlinkSync as unlinkSync8 } from "node:fs";
44440
+ import { join as join49, basename as basename13 } from "node:path";
44159
44441
  function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
44160
44442
  const competenceReport = competence.length > 0 ? competence.map((c3) => {
44161
44443
  const rate = c3.attempts > 0 ? Math.round(c3.successes / c3.attempts * 100) : 0;
@@ -44268,8 +44550,8 @@ var init_dmn_engine = __esm({
44268
44550
  constructor(config, repoRoot) {
44269
44551
  this.config = config;
44270
44552
  this.repoRoot = repoRoot;
44271
- this.stateDir = join48(repoRoot, ".oa", "dmn");
44272
- this.historyDir = join48(repoRoot, ".oa", "dmn", "cycles");
44553
+ this.stateDir = join49(repoRoot, ".oa", "dmn");
44554
+ this.historyDir = join49(repoRoot, ".oa", "dmn", "cycles");
44273
44555
  mkdirSync17(this.historyDir, { recursive: true });
44274
44556
  this.loadState();
44275
44557
  }
@@ -44859,11 +45141,11 @@ OUTPUT: Call task_complete with JSON:
44859
45141
  async gatherMemoryTopics() {
44860
45142
  const topics = [];
44861
45143
  const dirs = [
44862
- join48(this.repoRoot, ".oa", "memory"),
44863
- join48(this.repoRoot, ".open-agents", "memory")
45144
+ join49(this.repoRoot, ".oa", "memory"),
45145
+ join49(this.repoRoot, ".open-agents", "memory")
44864
45146
  ];
44865
45147
  for (const dir of dirs) {
44866
- if (!existsSync39(dir))
45148
+ if (!existsSync40(dir))
44867
45149
  continue;
44868
45150
  try {
44869
45151
  const files = readdirSync13(dir).filter((f) => f.endsWith(".json"));
@@ -44879,8 +45161,8 @@ OUTPUT: Call task_complete with JSON:
44879
45161
  }
44880
45162
  // ── State persistence ─────────────────────────────────────────────────
44881
45163
  loadState() {
44882
- const path = join48(this.stateDir, "state.json");
44883
- if (existsSync39(path)) {
45164
+ const path = join49(this.stateDir, "state.json");
45165
+ if (existsSync40(path)) {
44884
45166
  try {
44885
45167
  this.state = JSON.parse(readFileSync29(path, "utf-8"));
44886
45168
  } catch {
@@ -44889,19 +45171,19 @@ OUTPUT: Call task_complete with JSON:
44889
45171
  }
44890
45172
  saveState() {
44891
45173
  try {
44892
- writeFileSync16(join48(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
45174
+ writeFileSync17(join49(this.stateDir, "state.json"), JSON.stringify(this.state, null, 2) + "\n", "utf-8");
44893
45175
  } catch {
44894
45176
  }
44895
45177
  }
44896
45178
  saveCycleResult(result) {
44897
45179
  try {
44898
45180
  const filename = `cycle-${result.cycleNumber}-${Date.now()}.json`;
44899
- writeFileSync16(join48(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
45181
+ writeFileSync17(join49(this.historyDir, filename), JSON.stringify(result, null, 2) + "\n", "utf-8");
44900
45182
  const files = readdirSync13(this.historyDir).filter((f) => f.startsWith("cycle-") && f.endsWith(".json")).sort();
44901
45183
  if (files.length > 50) {
44902
45184
  for (const old of files.slice(0, files.length - 50)) {
44903
45185
  try {
44904
- unlinkSync7(join48(this.historyDir, old));
45186
+ unlinkSync8(join49(this.historyDir, old));
44905
45187
  } catch {
44906
45188
  }
44907
45189
  }
@@ -44914,8 +45196,8 @@ OUTPUT: Call task_complete with JSON:
44914
45196
  });
44915
45197
 
44916
45198
  // 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";
45199
+ import { existsSync as existsSync41, readdirSync as readdirSync14, readFileSync as readFileSync30 } from "node:fs";
45200
+ import { join as join50, basename as basename14 } from "node:path";
44919
45201
  function computeDPrime(signalScores, noiseScores) {
44920
45202
  if (signalScores.length === 0 || noiseScores.length === 0)
44921
45203
  return 0;
@@ -45155,11 +45437,11 @@ Call task_complete with the JSON array when done.`, onEvent)
45155
45437
  loadMemoryEntries(topics) {
45156
45438
  const entries = [];
45157
45439
  const dirs = [
45158
- join49(this.repoRoot, ".oa", "memory"),
45159
- join49(this.repoRoot, ".open-agents", "memory")
45440
+ join50(this.repoRoot, ".oa", "memory"),
45441
+ join50(this.repoRoot, ".open-agents", "memory")
45160
45442
  ];
45161
45443
  for (const dir of dirs) {
45162
- if (!existsSync40(dir))
45444
+ if (!existsSync41(dir))
45163
45445
  continue;
45164
45446
  try {
45165
45447
  const files = readdirSync14(dir).filter((f) => f.endsWith(".json"));
@@ -45168,7 +45450,7 @@ Call task_complete with the JSON array when done.`, onEvent)
45168
45450
  if (topics.length > 0 && !topics.includes(topic))
45169
45451
  continue;
45170
45452
  try {
45171
- const data = JSON.parse(readFileSync30(join49(dir, f), "utf-8"));
45453
+ const data = JSON.parse(readFileSync30(join50(dir, f), "utf-8"));
45172
45454
  for (const [key, val] of Object.entries(data)) {
45173
45455
  const value = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
45174
45456
  entries.push({ topic, key, value });
@@ -45735,8 +46017,8 @@ var init_tool_policy = __esm({
45735
46017
  });
45736
46018
 
45737
46019
  // 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";
46020
+ import { mkdirSync as mkdirSync18, existsSync as existsSync42, unlinkSync as unlinkSync9, readdirSync as readdirSync15, statSync as statSync13 } from "node:fs";
46021
+ import { join as join51, resolve as resolve28 } from "node:path";
45740
46022
  import { writeFile as writeFileAsync } from "node:fs/promises";
45741
46023
  function convertMarkdownToTelegramHTML(md) {
45742
46024
  let html = md;
@@ -46501,7 +46783,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46501
46783
  return null;
46502
46784
  const buffer = Buffer.from(await res.arrayBuffer());
46503
46785
  const fileName = `${Date.now()}-${fileId.slice(0, 8)}${extension}`;
46504
- const localPath = join50(this.mediaCacheDir, fileName);
46786
+ const localPath = join51(this.mediaCacheDir, fileName);
46505
46787
  await writeFileAsync(localPath, buffer);
46506
46788
  return localPath;
46507
46789
  } catch {
@@ -46589,7 +46871,7 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46589
46871
  for (const [key, entry] of this.mediaCache) {
46590
46872
  if (now - entry.cachedAt > MEDIA_CACHE_TTL_MS) {
46591
46873
  try {
46592
- unlinkSync8(entry.localPath);
46874
+ unlinkSync9(entry.localPath);
46593
46875
  } catch {
46594
46876
  }
46595
46877
  this.mediaCache.delete(key);
@@ -46665,11 +46947,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
46665
46947
  let mimeType = "audio/wav";
46666
46948
  try {
46667
46949
  const { execSync: execSyncLocal } = await import("node:child_process");
46668
- const { tmpdir: tmpdir9 } = await import("node:os");
46950
+ const { tmpdir: tmpdir10 } = await import("node:os");
46669
46951
  const { join: joinPath } = await import("node:path");
46670
46952
  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`);
46953
+ const tmpWav = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.wav`);
46954
+ const tmpOgg = joinPath(tmpdir10(), `oa-tg-voice-${Date.now()}.ogg`);
46673
46955
  writeFs(tmpWav, wavBuffer);
46674
46956
  execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
46675
46957
  timeout: 15e3,
@@ -48940,11 +49222,11 @@ var init_status_bar = __esm({
48940
49222
  import * as readline2 from "node:readline";
48941
49223
  import { Writable } from "node:stream";
48942
49224
  import { cwd } from "node:process";
48943
- import { resolve as resolve29, join as join51, dirname as dirname18, extname as extname10 } from "node:path";
49225
+ import { resolve as resolve29, join as join52, dirname as dirname18, extname as extname10 } from "node:path";
48944
49226
  import { createRequire as createRequire2 } from "node:module";
48945
49227
  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";
49228
+ import { readFileSync as readFileSync31, writeFileSync as writeFileSync18, appendFileSync as appendFileSync4, rmSync as rmSync2, readdirSync as readdirSync16, mkdirSync as mkdirSync19 } from "node:fs";
49229
+ import { existsSync as existsSync43 } from "node:fs";
48948
49230
  import { homedir as homedir13 } from "node:os";
48949
49231
  function formatTimeAgo(date) {
48950
49232
  const seconds = Math.floor((Date.now() - date.getTime()) / 1e3);
@@ -48964,12 +49246,12 @@ function getVersion3() {
48964
49246
  const require2 = createRequire2(import.meta.url);
48965
49247
  const thisDir = dirname18(fileURLToPath12(import.meta.url));
48966
49248
  const candidates = [
48967
- join51(thisDir, "..", "package.json"),
48968
- join51(thisDir, "..", "..", "package.json"),
48969
- join51(thisDir, "..", "..", "..", "package.json")
49249
+ join52(thisDir, "..", "package.json"),
49250
+ join52(thisDir, "..", "..", "package.json"),
49251
+ join52(thisDir, "..", "..", "..", "package.json")
48970
49252
  ];
48971
49253
  for (const pkgPath of candidates) {
48972
- if (existsSync42(pkgPath)) {
49254
+ if (existsSync43(pkgPath)) {
48973
49255
  const pkg = require2(pkgPath);
48974
49256
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
48975
49257
  return pkg.version ?? "0.0.0";
@@ -49176,15 +49458,15 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
49176
49458
  function gatherMemorySnippets(root) {
49177
49459
  const snippets = [];
49178
49460
  const dirs = [
49179
- join51(root, ".oa", "memory"),
49180
- join51(root, ".open-agents", "memory")
49461
+ join52(root, ".oa", "memory"),
49462
+ join52(root, ".open-agents", "memory")
49181
49463
  ];
49182
49464
  for (const dir of dirs) {
49183
- if (!existsSync42(dir))
49465
+ if (!existsSync43(dir))
49184
49466
  continue;
49185
49467
  try {
49186
49468
  for (const f of readdirSync16(dir).filter((f2) => f2.endsWith(".json"))) {
49187
- const data = JSON.parse(readFileSync31(join51(dir, f), "utf-8"));
49469
+ const data = JSON.parse(readFileSync31(join52(dir, f), "utf-8"));
49188
49470
  for (const val of Object.values(data)) {
49189
49471
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
49190
49472
  if (v.length > 10)
@@ -50148,7 +50430,7 @@ async function startInteractive(config, repoPath) {
50148
50430
  let p2pGateway = null;
50149
50431
  let peerMesh = null;
50150
50432
  let inferenceRouter = null;
50151
- const secretVault = new SecretVault(join51(repoRoot, ".oa", "vault.enc"));
50433
+ const secretVault = new SecretVault(join52(repoRoot, ".oa", "vault.enc"));
50152
50434
  let adminSessionKey = null;
50153
50435
  const callSubAgents = /* @__PURE__ */ new Map();
50154
50436
  const streamRenderer = new StreamRenderer();
@@ -50357,12 +50639,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50357
50639
  const hits = allCompletions.filter((c3) => c3.toLowerCase().startsWith(lower));
50358
50640
  return [hits, line];
50359
50641
  }
50360
- const HISTORY_DIR = join51(homedir13(), ".open-agents");
50361
- const HISTORY_FILE = join51(HISTORY_DIR, "repl-history");
50642
+ const HISTORY_DIR = join52(homedir13(), ".open-agents");
50643
+ const HISTORY_FILE = join52(HISTORY_DIR, "repl-history");
50362
50644
  const MAX_HISTORY_LINES = 500;
50363
50645
  let savedHistory = [];
50364
50646
  try {
50365
- if (existsSync42(HISTORY_FILE)) {
50647
+ if (existsSync43(HISTORY_FILE)) {
50366
50648
  const raw = readFileSync31(HISTORY_FILE, "utf8").trim();
50367
50649
  if (raw)
50368
50650
  savedHistory = raw.split("\n").reverse();
@@ -50387,7 +50669,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50387
50669
  if (Math.random() < 0.02) {
50388
50670
  const all = readFileSync31(HISTORY_FILE, "utf8").trim().split("\n");
50389
50671
  if (all.length > MAX_HISTORY_LINES) {
50390
- writeFileSync17(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
50672
+ writeFileSync18(HISTORY_FILE, all.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
50391
50673
  }
50392
50674
  }
50393
50675
  } catch {
@@ -50568,7 +50850,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50568
50850
  } catch {
50569
50851
  }
50570
50852
  try {
50571
- const oaDir = join51(repoRoot, ".oa");
50853
+ const oaDir = join52(repoRoot, ".oa");
50572
50854
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
50573
50855
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
50574
50856
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -50591,7 +50873,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
50591
50873
  } catch {
50592
50874
  }
50593
50875
  try {
50594
- const oaDir = join51(repoRoot, ".oa");
50876
+ const oaDir = join52(repoRoot, ".oa");
50595
50877
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
50596
50878
  onInfo: (msg) => writeContent(() => renderInfo(msg)),
50597
50879
  onError: (msg) => writeContent(() => renderWarning(msg))
@@ -51410,7 +51692,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51410
51692
  kind,
51411
51693
  targetUrl,
51412
51694
  authKey,
51413
- stateDir: join51(repoRoot, ".oa"),
51695
+ stateDir: join52(repoRoot, ".oa"),
51414
51696
  passthrough: passthrough ?? false,
51415
51697
  loadbalance: loadbalance ?? false,
51416
51698
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -51458,7 +51740,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51458
51740
  await tunnelGateway.stop();
51459
51741
  tunnelGateway = null;
51460
51742
  }
51461
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join51(repoRoot, ".oa") });
51743
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join52(repoRoot, ".oa") });
51462
51744
  newTunnel.on("stats", (stats) => {
51463
51745
  statusBar.setExposeStatus({
51464
51746
  status: stats.status,
@@ -51720,8 +52002,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
51720
52002
  }
51721
52003
  },
51722
52004
  destroyProject() {
51723
- const oaPath = join51(repoRoot, OA_DIR);
51724
- if (existsSync42(oaPath)) {
52005
+ const oaPath = join52(repoRoot, OA_DIR);
52006
+ if (existsSync43(oaPath)) {
51725
52007
  try {
51726
52008
  rmSync2(oaPath, { recursive: true, force: true });
51727
52009
  writeContent(() => renderInfo(`Removed ${OA_DIR}/ directory.`));
@@ -52066,8 +52348,8 @@ Execute this skill now. Follow the behavioral guidance above.`;
52066
52348
  }
52067
52349
  }
52068
52350
  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));
52351
+ const isImage = isImagePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
52352
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync43(resolve29(repoRoot, cleanPath));
52071
52353
  if (activeTask) {
52072
52354
  if (activeTask.runner.isPaused) {
52073
52355
  activeTask.runner.resume();
@@ -52655,7 +52937,7 @@ import { glob } from "glob";
52655
52937
  import ignore from "ignore";
52656
52938
  import { readFile as readFile17, stat as stat4 } from "node:fs/promises";
52657
52939
  import { createHash as createHash4 } from "node:crypto";
52658
- import { join as join52, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
52940
+ import { join as join53, relative as relative3, extname as extname11, basename as basename15 } from "node:path";
52659
52941
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
52660
52942
  var init_codebase_indexer = __esm({
52661
52943
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -52699,7 +52981,7 @@ var init_codebase_indexer = __esm({
52699
52981
  const ig = ignore.default();
52700
52982
  if (this.config.respectGitignore) {
52701
52983
  try {
52702
- const gitignoreContent = await readFile17(join52(this.config.rootDir, ".gitignore"), "utf-8");
52984
+ const gitignoreContent = await readFile17(join53(this.config.rootDir, ".gitignore"), "utf-8");
52703
52985
  ig.add(gitignoreContent);
52704
52986
  } catch {
52705
52987
  }
@@ -52714,7 +52996,7 @@ var init_codebase_indexer = __esm({
52714
52996
  for (const relativePath of files) {
52715
52997
  if (ig.ignores(relativePath))
52716
52998
  continue;
52717
- const fullPath = join52(this.config.rootDir, relativePath);
52999
+ const fullPath = join53(this.config.rootDir, relativePath);
52718
53000
  try {
52719
53001
  const fileStat = await stat4(fullPath);
52720
53002
  if (fileStat.size > this.config.maxFileSize)
@@ -52760,7 +53042,7 @@ var init_codebase_indexer = __esm({
52760
53042
  if (!child) {
52761
53043
  child = {
52762
53044
  name: part,
52763
- path: join52(current.path, part),
53045
+ path: join53(current.path, part),
52764
53046
  type: "directory",
52765
53047
  children: []
52766
53048
  };
@@ -52843,17 +53125,17 @@ __export(index_repo_exports, {
52843
53125
  indexRepoCommand: () => indexRepoCommand
52844
53126
  });
52845
53127
  import { resolve as resolve30 } from "node:path";
52846
- import { existsSync as existsSync43, statSync as statSync13 } from "node:fs";
53128
+ import { existsSync as existsSync44, statSync as statSync14 } from "node:fs";
52847
53129
  import { cwd as cwd2 } from "node:process";
52848
53130
  async function indexRepoCommand(opts, _config) {
52849
53131
  const repoRoot = resolve30(opts.repoPath ?? cwd2());
52850
53132
  printHeader("Index Repository");
52851
53133
  printInfo(`Indexing: ${repoRoot}`);
52852
- if (!existsSync43(repoRoot)) {
53134
+ if (!existsSync44(repoRoot)) {
52853
53135
  printError(`Path does not exist: ${repoRoot}`);
52854
53136
  process.exit(1);
52855
53137
  }
52856
- const stat5 = statSync13(repoRoot);
53138
+ const stat5 = statSync14(repoRoot);
52857
53139
  if (!stat5.isDirectory()) {
52858
53140
  printError(`Path is not a directory: ${repoRoot}`);
52859
53141
  process.exit(1);
@@ -53101,7 +53383,7 @@ var config_exports = {};
53101
53383
  __export(config_exports, {
53102
53384
  configCommand: () => configCommand
53103
53385
  });
53104
- import { join as join53, resolve as resolve31 } from "node:path";
53386
+ import { join as join54, resolve as resolve31 } from "node:path";
53105
53387
  import { homedir as homedir14 } from "node:os";
53106
53388
  import { cwd as cwd3 } from "node:process";
53107
53389
  function redactIfSensitive(key, value) {
@@ -53184,7 +53466,7 @@ function handleShow(opts, config) {
53184
53466
  }
53185
53467
  }
53186
53468
  printSection("Config File");
53187
- printInfo(`~/.open-agents/config.json (${join53(homedir14(), ".open-agents", "config.json")})`);
53469
+ printInfo(`~/.open-agents/config.json (${join54(homedir14(), ".open-agents", "config.json")})`);
53188
53470
  printSection("Priority Chain");
53189
53471
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
53190
53472
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -53223,7 +53505,7 @@ function handleSet(opts, _config) {
53223
53505
  const coerced = coerceForSettings(key, value);
53224
53506
  saveProjectSettings(repoRoot, { [key]: coerced });
53225
53507
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
53226
- printInfo(`Saved to ${join53(repoRoot, ".oa", "settings.json")}`);
53508
+ printInfo(`Saved to ${join54(repoRoot, ".oa", "settings.json")}`);
53227
53509
  printInfo("This override applies only when running in this workspace.");
53228
53510
  } catch (err) {
53229
53511
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -53480,9 +53762,9 @@ var eval_exports = {};
53480
53762
  __export(eval_exports, {
53481
53763
  evalCommand: () => evalCommand
53482
53764
  });
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";
53765
+ import { tmpdir as tmpdir9 } from "node:os";
53766
+ import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync19 } from "node:fs";
53767
+ import { join as join55 } from "node:path";
53486
53768
  async function evalCommand(opts, config) {
53487
53769
  const suiteName = opts.suite ?? "basic";
53488
53770
  const suite = SUITES[suiteName];
@@ -53607,9 +53889,9 @@ async function evalCommand(opts, config) {
53607
53889
  process.exit(failed > 0 ? 1 : 0);
53608
53890
  }
53609
53891
  function createTempEvalRepo() {
53610
- const dir = join54(tmpdir8(), `open-agents-eval-${Date.now()}`);
53892
+ const dir = join55(tmpdir9(), `open-agents-eval-${Date.now()}`);
53611
53893
  mkdirSync20(dir, { recursive: true });
53612
- writeFileSync18(join54(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
53894
+ writeFileSync19(join55(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
53613
53895
  return dir;
53614
53896
  }
53615
53897
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -53669,7 +53951,7 @@ init_updater();
53669
53951
  import { parseArgs as nodeParseArgs2 } from "node:util";
53670
53952
  import { createRequire as createRequire3 } from "node:module";
53671
53953
  import { fileURLToPath as fileURLToPath13 } from "node:url";
53672
- import { dirname as dirname19, join as join55 } from "node:path";
53954
+ import { dirname as dirname19, join as join56 } from "node:path";
53673
53955
 
53674
53956
  // packages/cli/dist/cli.js
53675
53957
  import { createInterface } from "node:readline";
@@ -53776,7 +54058,7 @@ init_output();
53776
54058
  function getVersion4() {
53777
54059
  try {
53778
54060
  const require2 = createRequire3(import.meta.url);
53779
- const pkgPath = join55(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
54061
+ const pkgPath = join56(dirname19(fileURLToPath13(import.meta.url)), "..", "package.json");
53780
54062
  const pkg = require2(pkgPath);
53781
54063
  return pkg.version;
53782
54064
  } catch {