open-agents-ai 0.187.430 → 0.187.432

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.
package/dist/index.js CHANGED
@@ -355,105 +355,6 @@ var init_typed_node_events = __esm({
355
355
  }
356
356
  });
357
357
 
358
- // packages/cli/src/ui/spinner.ts
359
- var FRAMES, INTERVAL_MS, Spinner;
360
- var init_spinner = __esm({
361
- "packages/cli/src/ui/spinner.ts"() {
362
- "use strict";
363
- FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
364
- INTERVAL_MS = 80;
365
- Spinner = class {
366
- _text;
367
- _frameIndex = 0;
368
- _timer = null;
369
- _isSpinning = false;
370
- constructor(text) {
371
- this._text = text;
372
- }
373
- // --------------------------------------------------------------------------
374
- // Public API
375
- // --------------------------------------------------------------------------
376
- get text() {
377
- return this._text;
378
- }
379
- set text(value2) {
380
- this._text = value2;
381
- if (this._isSpinning && process.stdout.isTTY) {
382
- this._render();
383
- }
384
- }
385
- get isSpinning() {
386
- return this._isSpinning;
387
- }
388
- start() {
389
- if (this._isSpinning) return this;
390
- this._isSpinning = true;
391
- this._frameIndex = 0;
392
- if (process.stdout.isTTY) {
393
- process.stdout.write("\x1B[?25l");
394
- this._render();
395
- this._timer = setInterval(() => {
396
- this._frameIndex = (this._frameIndex + 1) % FRAMES.length;
397
- this._render();
398
- }, INTERVAL_MS);
399
- } else {
400
- process.stdout.write(`${this._text}
401
- `);
402
- }
403
- return this;
404
- }
405
- stop() {
406
- if (!this._isSpinning) return this;
407
- this._isSpinning = false;
408
- if (this._timer !== null) {
409
- clearInterval(this._timer);
410
- this._timer = null;
411
- }
412
- if (process.stdout.isTTY) {
413
- process.stdout.write("\r\x1B[K");
414
- process.stdout.write("\x1B[?25h");
415
- }
416
- return this;
417
- }
418
- succeed(message2) {
419
- this.stop();
420
- const msg = message2 ?? this._text;
421
- process.stdout.write(`\x1B[32m✔\x1B[0m ${msg}
422
- `);
423
- return this;
424
- }
425
- fail(message2) {
426
- this.stop();
427
- const msg = message2 ?? this._text;
428
- process.stdout.write(`\x1B[31m✖\x1B[0m ${msg}
429
- `);
430
- return this;
431
- }
432
- warn(message2) {
433
- this.stop();
434
- const msg = message2 ?? this._text;
435
- process.stdout.write(`\x1B[33m⚠\x1B[0m ${msg}
436
- `);
437
- return this;
438
- }
439
- info(message2) {
440
- this.stop();
441
- const msg = message2 ?? this._text;
442
- process.stdout.write(`\x1B[36mℹ\x1B[0m ${msg}
443
- `);
444
- return this;
445
- }
446
- // --------------------------------------------------------------------------
447
- // Private
448
- // --------------------------------------------------------------------------
449
- _render() {
450
- const frame = FRAMES[this._frameIndex] ?? FRAMES[0];
451
- process.stdout.write(`\r\x1B[36m${frame}\x1B[0m ${this._text}`);
452
- }
453
- };
454
- }
455
- });
456
-
457
358
  // packages/backend-vllm/dist/sleep.js
458
359
  var SleepManager;
459
360
  var init_sleep = __esm({
@@ -88633,7 +88534,7 @@ var require_auto = __commonJS({
88633
88534
  // ../../../node_modules/acme-client/src/client.js
88634
88535
  var require_client = __commonJS({
88635
88536
  "../../../node_modules/acme-client/src/client.js"(exports, module) {
88636
- var { createHash: createHash13 } = __require("crypto");
88537
+ var { createHash: createHash14 } = __require("crypto");
88637
88538
  var { getPemBodyAsB64u } = require_crypto();
88638
88539
  var { log: log22 } = require_logger();
88639
88540
  var HttpClient = require_http();
@@ -88944,14 +88845,14 @@ var require_client = __commonJS({
88944
88845
  */
88945
88846
  async getChallengeKeyAuthorization(challenge) {
88946
88847
  const jwk = this.http.getJwk();
88947
- const keysum = createHash13("sha256").update(JSON.stringify(jwk));
88848
+ const keysum = createHash14("sha256").update(JSON.stringify(jwk));
88948
88849
  const thumbprint = keysum.digest("base64url");
88949
88850
  const result = `${challenge.token}.${thumbprint}`;
88950
88851
  if (challenge.type === "http-01") {
88951
88852
  return result;
88952
88853
  }
88953
88854
  if (challenge.type === "dns-01") {
88954
- return createHash13("sha256").update(result).digest("base64url");
88855
+ return createHash14("sha256").update(result).digest("base64url");
88955
88856
  }
88956
88857
  if (challenge.type === "tls-alpn-01") {
88957
88858
  return result;
@@ -231549,7 +231450,7 @@ var require_websocket2 = __commonJS({
231549
231450
  var http6 = __require("http");
231550
231451
  var net5 = __require("net");
231551
231452
  var tls2 = __require("tls");
231552
- var { randomBytes: randomBytes23, createHash: createHash13 } = __require("crypto");
231453
+ var { randomBytes: randomBytes23, createHash: createHash14 } = __require("crypto");
231553
231454
  var { Duplex: Duplex3, Readable } = __require("stream");
231554
231455
  var { URL: URL3 } = __require("url");
231555
231456
  var PerMessageDeflate2 = require_permessage_deflate2();
@@ -232209,7 +232110,7 @@ var require_websocket2 = __commonJS({
232209
232110
  abortHandshake(websocket, socket, "Invalid Upgrade header");
232210
232111
  return;
232211
232112
  }
232212
- const digest3 = createHash13("sha1").update(key + GUID).digest("base64");
232113
+ const digest3 = createHash14("sha1").update(key + GUID).digest("base64");
232213
232114
  if (res.headers["sec-websocket-accept"] !== digest3) {
232214
232115
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
232215
232116
  return;
@@ -232576,7 +232477,7 @@ var require_websocket_server = __commonJS({
232576
232477
  var EventEmitter12 = __require("events");
232577
232478
  var http6 = __require("http");
232578
232479
  var { Duplex: Duplex3 } = __require("stream");
232579
- var { createHash: createHash13 } = __require("crypto");
232480
+ var { createHash: createHash14 } = __require("crypto");
232580
232481
  var extension2 = require_extension2();
232581
232482
  var PerMessageDeflate2 = require_permessage_deflate2();
232582
232483
  var subprotocol2 = require_subprotocol();
@@ -232877,7 +232778,7 @@ var require_websocket_server = __commonJS({
232877
232778
  );
232878
232779
  }
232879
232780
  if (this._state > RUNNING) return abortHandshake(socket, 503);
232880
- const digest3 = createHash13("sha1").update(key + GUID).digest("base64");
232781
+ const digest3 = createHash14("sha1").update(key + GUID).digest("base64");
232881
232782
  const headers = [
232882
232783
  "HTTP/1.1 101 Switching Protocols",
232883
232784
  "Upgrade: websocket",
@@ -245684,13 +245585,13 @@ Justification: ${justification || "(none provided)"}`,
245684
245585
  }
245685
245586
  const snapshot = JSON.stringify(this.selfState, null, 2);
245686
245587
  try {
245687
- const { createHash: createHash13 } = await import("node:crypto");
245588
+ const { createHash: createHash14 } = await import("node:crypto");
245688
245589
  const snapshotDir = join24(this.cwd, ".oa", "identity", "snapshots");
245689
245590
  await mkdir6(snapshotDir, { recursive: true });
245690
245591
  const version4 = this.selfState.version;
245691
245592
  const snapshotPath = join24(snapshotDir, `v${version4}.json`);
245692
245593
  await writeFile11(snapshotPath, snapshot, "utf8");
245693
- const hash = createHash13("sha256").update(snapshot).digest("hex");
245594
+ const hash = createHash14("sha256").update(snapshot).digest("hex");
245694
245595
  await writeFile11(join24(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
245695
245596
  let ipfsCid = "";
245696
245597
  try {
@@ -245823,8 +245724,8 @@ New: ${newNarrative.slice(0, 200)}...`,
245823
245724
  }
245824
245725
  // ── Helpers ──────────────────────────────────────────────────────────────
245825
245726
  createDefaultState() {
245826
- const { createHash: createHash13 } = __require("node:crypto");
245827
- const machineId = createHash13("sha256").update(this.cwd).digest("hex").slice(0, 12);
245727
+ const { createHash: createHash14 } = __require("node:crypto");
245728
+ const machineId = createHash14("sha256").update(this.cwd).digest("hex").slice(0, 12);
245828
245729
  return {
245829
245730
  self_id: `oa-${machineId}`,
245830
245731
  version: 1,
@@ -245906,9 +245807,9 @@ New: ${newNarrative.slice(0, 200)}...`,
245906
245807
  let cid;
245907
245808
  if (this.selfState.version > prevVersion) {
245908
245809
  try {
245909
- const { createHash: createHash13 } = await import("node:crypto");
245810
+ const { createHash: createHash14 } = await import("node:crypto");
245910
245811
  const stateJson = JSON.stringify(this.selfState);
245911
- const hash = createHash13("sha256").update(stateJson).digest("hex").slice(0, 32);
245812
+ const hash = createHash14("sha256").update(stateJson).digest("hex").slice(0, 32);
245912
245813
  const cidsPath = join24(this.cwd, ".oa", "identity", "cids.json");
245913
245814
  const cidsData = { latest: "", hash, version: this.selfState.version };
245914
245815
  try {
@@ -524187,6 +524088,105 @@ var init_dist8 = __esm({
524187
524088
  }
524188
524089
  });
524189
524090
 
524091
+ // packages/cli/src/ui/spinner.ts
524092
+ var FRAMES, INTERVAL_MS, Spinner;
524093
+ var init_spinner = __esm({
524094
+ "packages/cli/src/ui/spinner.ts"() {
524095
+ "use strict";
524096
+ FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
524097
+ INTERVAL_MS = 80;
524098
+ Spinner = class {
524099
+ _text;
524100
+ _frameIndex = 0;
524101
+ _timer = null;
524102
+ _isSpinning = false;
524103
+ constructor(text) {
524104
+ this._text = text;
524105
+ }
524106
+ // --------------------------------------------------------------------------
524107
+ // Public API
524108
+ // --------------------------------------------------------------------------
524109
+ get text() {
524110
+ return this._text;
524111
+ }
524112
+ set text(value2) {
524113
+ this._text = value2;
524114
+ if (this._isSpinning && process.stdout.isTTY) {
524115
+ this._render();
524116
+ }
524117
+ }
524118
+ get isSpinning() {
524119
+ return this._isSpinning;
524120
+ }
524121
+ start() {
524122
+ if (this._isSpinning) return this;
524123
+ this._isSpinning = true;
524124
+ this._frameIndex = 0;
524125
+ if (process.stdout.isTTY) {
524126
+ process.stdout.write("\x1B[?25l");
524127
+ this._render();
524128
+ this._timer = setInterval(() => {
524129
+ this._frameIndex = (this._frameIndex + 1) % FRAMES.length;
524130
+ this._render();
524131
+ }, INTERVAL_MS);
524132
+ } else {
524133
+ process.stdout.write(`${this._text}
524134
+ `);
524135
+ }
524136
+ return this;
524137
+ }
524138
+ stop() {
524139
+ if (!this._isSpinning) return this;
524140
+ this._isSpinning = false;
524141
+ if (this._timer !== null) {
524142
+ clearInterval(this._timer);
524143
+ this._timer = null;
524144
+ }
524145
+ if (process.stdout.isTTY) {
524146
+ process.stdout.write("\r\x1B[K");
524147
+ process.stdout.write("\x1B[?25h");
524148
+ }
524149
+ return this;
524150
+ }
524151
+ succeed(message2) {
524152
+ this.stop();
524153
+ const msg = message2 ?? this._text;
524154
+ process.stdout.write(`\x1B[32m✔\x1B[0m ${msg}
524155
+ `);
524156
+ return this;
524157
+ }
524158
+ fail(message2) {
524159
+ this.stop();
524160
+ const msg = message2 ?? this._text;
524161
+ process.stdout.write(`\x1B[31m✖\x1B[0m ${msg}
524162
+ `);
524163
+ return this;
524164
+ }
524165
+ warn(message2) {
524166
+ this.stop();
524167
+ const msg = message2 ?? this._text;
524168
+ process.stdout.write(`\x1B[33m⚠\x1B[0m ${msg}
524169
+ `);
524170
+ return this;
524171
+ }
524172
+ info(message2) {
524173
+ this.stop();
524174
+ const msg = message2 ?? this._text;
524175
+ process.stdout.write(`\x1B[36mℹ\x1B[0m ${msg}
524176
+ `);
524177
+ return this;
524178
+ }
524179
+ // --------------------------------------------------------------------------
524180
+ // Private
524181
+ // --------------------------------------------------------------------------
524182
+ _render() {
524183
+ const frame = FRAMES[this._frameIndex] ?? FRAMES[0];
524184
+ process.stdout.write(`\r\x1B[36m${frame}\x1B[0m ${this._text}`);
524185
+ }
524186
+ };
524187
+ }
524188
+ });
524189
+
524190
524190
  // packages/cli/src/api/py-embed.ts
524191
524191
  var py_embed_exports = {};
524192
524192
  __export(py_embed_exports, {
@@ -527292,7 +527292,7 @@ var require_websocket3 = __commonJS({
527292
527292
  var http6 = __require("http");
527293
527293
  var net5 = __require("net");
527294
527294
  var tls2 = __require("tls");
527295
- var { randomBytes: randomBytes23, createHash: createHash13 } = __require("crypto");
527295
+ var { randomBytes: randomBytes23, createHash: createHash14 } = __require("crypto");
527296
527296
  var { Duplex: Duplex3, Readable } = __require("stream");
527297
527297
  var { URL: URL3 } = __require("url");
527298
527298
  var PerMessageDeflate2 = require_permessage_deflate3();
@@ -527952,7 +527952,7 @@ var require_websocket3 = __commonJS({
527952
527952
  abortHandshake(websocket, socket, "Invalid Upgrade header");
527953
527953
  return;
527954
527954
  }
527955
- const digest3 = createHash13("sha1").update(key + GUID).digest("base64");
527955
+ const digest3 = createHash14("sha1").update(key + GUID).digest("base64");
527956
527956
  if (res.headers["sec-websocket-accept"] !== digest3) {
527957
527957
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
527958
527958
  return;
@@ -528319,7 +528319,7 @@ var require_websocket_server2 = __commonJS({
528319
528319
  var EventEmitter12 = __require("events");
528320
528320
  var http6 = __require("http");
528321
528321
  var { Duplex: Duplex3 } = __require("stream");
528322
- var { createHash: createHash13 } = __require("crypto");
528322
+ var { createHash: createHash14 } = __require("crypto");
528323
528323
  var extension2 = require_extension3();
528324
528324
  var PerMessageDeflate2 = require_permessage_deflate3();
528325
528325
  var subprotocol2 = require_subprotocol2();
@@ -528620,7 +528620,7 @@ var require_websocket_server2 = __commonJS({
528620
528620
  );
528621
528621
  }
528622
528622
  if (this._state > RUNNING) return abortHandshake(socket, 503);
528623
- const digest3 = createHash13("sha1").update(key + GUID).digest("base64");
528623
+ const digest3 = createHash14("sha1").update(key + GUID).digest("base64");
528624
528624
  const headers = [
528625
528625
  "HTTP/1.1 101 Switching Protocols",
528626
528626
  "Upgrade: websocket",
@@ -529663,9 +529663,10 @@ __export(oa_directory_exports, {
529663
529663
  writeIndexData: () => writeIndexData,
529664
529664
  writeIndexMeta: () => writeIndexMeta
529665
529665
  });
529666
- import { existsSync as existsSync57, mkdirSync as mkdirSync32, readFileSync as readFileSync44, writeFileSync as writeFileSync29, readdirSync as readdirSync14, statSync as statSync17, unlinkSync as unlinkSync14, openSync as openSync2, closeSync as closeSync2 } from "node:fs";
529666
+ import { existsSync as existsSync57, mkdirSync as mkdirSync32, readFileSync as readFileSync44, writeFileSync as writeFileSync29, readdirSync as readdirSync14, statSync as statSync17, unlinkSync as unlinkSync14, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync3 } from "node:fs";
529667
529667
  import { join as join75, relative as relative6, basename as basename13, dirname as dirname22 } from "node:path";
529668
529668
  import { homedir as homedir25 } from "node:os";
529669
+ import { createHash as createHash8 } from "node:crypto";
529669
529670
  function findGitRoot(startDir) {
529670
529671
  let dir = startDir;
529671
529672
  const visited = /* @__PURE__ */ new Set();
@@ -529944,6 +529945,14 @@ function loadPendingTask(repoRoot) {
529944
529945
  return null;
529945
529946
  }
529946
529947
  }
529948
+ function computeDedupeHash(task, savedAt) {
529949
+ return createHash8("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
529950
+ }
529951
+ function generateSessionId() {
529952
+ const timestamp = Date.now().toString(36);
529953
+ const random = Math.random().toString(36).slice(2, 8);
529954
+ return `${timestamp}-${random}`;
529955
+ }
529947
529956
  function acquireLock(lockPath) {
529948
529957
  const startTime = Date.now();
529949
529958
  const pid = process.pid;
@@ -530027,16 +530036,11 @@ function normalizeSessionContextEntry(entry) {
530027
530036
  const assistantResponse = normalizeSessionText(entry.assistantResponse, 1200);
530028
530037
  if (assistantResponse) normalized.assistantResponse = assistantResponse;
530029
530038
  if (entry.source) normalized.source = entry.source;
530030
- return normalized;
530031
- }
530032
- function sameStringArray(a2, b) {
530033
- const left = a2 ?? [];
530034
- const right = b ?? [];
530035
- if (left.length !== right.length) return false;
530036
- for (let i2 = 0; i2 < left.length; i2++) {
530037
- if (left[i2] !== right[i2]) return false;
530039
+ normalized._dedupeHash = computeDedupeHash(normalized.task, normalized.savedAt);
530040
+ if (!normalized.sessionId) {
530041
+ normalized.sessionId = generateSessionId();
530038
530042
  }
530039
- return true;
530043
+ return normalized;
530040
530044
  }
530041
530045
  function lastMatchingIndex(items, predicate) {
530042
530046
  for (let i2 = items.length - 1; i2 >= 0; i2--) {
@@ -530058,9 +530062,6 @@ function isWithinReplaceWindow(a2, b) {
530058
530062
  if (left == null || right == null) return true;
530059
530063
  return Math.abs(right - left) <= SAME_TASK_REPLACE_WINDOW_MS;
530060
530064
  }
530061
- function isExactSessionDuplicate(a2, b) {
530062
- return sameTask(a2, b) && a2.summary === b.summary && (a2.assistantResponse ?? "") === (b.assistantResponse ?? "") && sameStringArray(a2.filesModified, b.filesModified) && sameStringArray(a2.toolsUsed, b.toolsUsed) && (a2.provenance ?? "") === (b.provenance ?? "") && a2.toolCalls === b.toolCalls && a2.completed === b.completed && a2.model === b.model;
530063
- }
530064
530065
  function mergeSessionContextEntry(previous, incoming) {
530065
530066
  return {
530066
530067
  ...previous,
@@ -530099,12 +530100,19 @@ function saveSessionContext(repoRoot, entry) {
530099
530100
  ctx3 = { entries: [], maxEntries: MAX_CONTEXT_ENTRIES, updatedAt: "" };
530100
530101
  }
530101
530102
  const normalizedEntry = normalizeSessionContextEntry(entry);
530102
- const exactIndex = lastMatchingIndex(
530103
- ctx3.entries,
530104
- (existing) => isExactSessionDuplicate(normalizeSessionContextEntry(existing), normalizedEntry)
530105
- );
530106
- if (exactIndex >= 0) {
530107
- ctx3.entries[exactIndex] = mergeSessionContextEntry(ctx3.entries[exactIndex], normalizedEntry);
530103
+ const hashToIndex = /* @__PURE__ */ new Map();
530104
+ for (let i2 = 0; i2 < ctx3.entries.length; i2++) {
530105
+ const existing = ctx3.entries[i2];
530106
+ const hash = existing._dedupeHash || computeDedupeHash(
530107
+ cleanPromptForDiary(existing.task),
530108
+ existing.savedAt
530109
+ );
530110
+ hashToIndex.set(hash, i2);
530111
+ }
530112
+ const incomingHash = normalizedEntry._dedupeHash;
530113
+ const hashMatchIndex = hashToIndex.get(incomingHash);
530114
+ if (hashMatchIndex !== void 0) {
530115
+ ctx3.entries[hashMatchIndex] = mergeSessionContextEntry(ctx3.entries[hashMatchIndex], normalizedEntry);
530108
530116
  } else {
530109
530117
  const relatedIndex = lastMatchingIndex(ctx3.entries, (existing) => {
530110
530118
  const normalizedExisting = normalizeSessionContextEntry(existing);
@@ -530129,7 +530137,17 @@ function saveSessionContext(repoRoot, entry) {
530129
530137
  ctx3.entries = ctx3.entries.slice(-ctx3.maxEntries);
530130
530138
  }
530131
530139
  ctx3.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
530132
- writeFileSync29(filePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
530140
+ const tempFilePath = filePath + ".tmp";
530141
+ writeFileSync29(tempFilePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
530142
+ try {
530143
+ renameSync3(tempFilePath, filePath);
530144
+ } catch {
530145
+ writeFileSync29(filePath, JSON.stringify(ctx3, null, 2) + "\n", "utf-8");
530146
+ try {
530147
+ unlinkSync14(tempFilePath);
530148
+ } catch {
530149
+ }
530150
+ }
530133
530151
  try {
530134
530152
  writeFileSync29(
530135
530153
  join75(contextDir, "session-diary.md"),
@@ -534227,6 +534245,7 @@ ${CONTENT_BG_SEQ}`);
534227
534245
  process.stdout.write(RESET2);
534228
534246
  this._brailleSpinner.setMetrics({ isStreaming: false });
534229
534247
  this.renderFooterAndPositionInput();
534248
+ this.parkCursorInInput();
534230
534249
  this.scheduleMouseIdle();
534231
534250
  }
534232
534251
  }
@@ -534905,6 +534924,27 @@ ${CONTENT_BG_SEQ}`);
534905
534924
  this.termWrite(
534906
534925
  `\x1B[${this.scrollRegionTop};${pos.scrollEnd}r\x1B[${pos.scrollEnd};1H` + (clearScrollback ? "\x1B[3J" : "")
534907
534926
  );
534927
+ if (this.writeDepth === 0) {
534928
+ this.parkCursorInInput();
534929
+ }
534930
+ }
534931
+ /**
534932
+ * Park cursor in the input row — ensures cursor is always in the input area
534933
+ * after scroll region changes or other operations that may leave it elsewhere.
534934
+ * Called after applyScrollRegion() and in endContentWrite() for safety.
534935
+ */
534936
+ parkCursorInInput() {
534937
+ if (!this.active) return;
534938
+ const rows = termRows();
534939
+ const w = getTermWidth();
534940
+ const pos = this.rowPositions(rows);
534941
+ const inputWrap = this.wrapInput(w);
534942
+ const cursorRow = pos.inputStartRow + inputWrap.cursorRow;
534943
+ const cursorCol = inputWrap.cursorCol;
534944
+ if (process.env.OA_DEBUG_CURSOR === "1") {
534945
+ console.error(`[CURSOR DEBUG] parkCursorInInput: row=${cursorRow}, col=${cursorCol}, inputStartRow=${pos.inputStartRow}, cursorRow=${inputWrap.cursorRow}, writeDepth=${this.writeDepth}`);
534946
+ }
534947
+ this.termWrite(`\x1B[${cursorRow};${cursorCol}H\x1B[?25h`);
534908
534948
  }
534909
534949
  /**
534910
534950
  * WO-TASK-02 — Public hook for the TUI tasks renderer. When the tasks
@@ -541244,10 +541284,11 @@ async function showNodeDetail(options2, nodeId) {
541244
541284
  renderError2(`Failed to load node: ${e2}`);
541245
541285
  }
541246
541286
  console.log();
541247
- renderInfo2("Press Enter to go back...");
541248
- await new Promise((resolve41) => {
541249
- rl.resume();
541250
- rl.once("line", () => resolve41());
541287
+ const backItem = [{ key: "back", label: import_chalk.default.cyan(" Back to Episodes") }];
541288
+ await tuiSelect({
541289
+ items: backItem,
541290
+ rl,
541291
+ availableRows: 3
541251
541292
  });
541252
541293
  }
541253
541294
  async function showEpisodesMenu(options2) {
@@ -541332,10 +541373,11 @@ async function showEpisodeDetail(options2, episodeId) {
541332
541373
  renderError2(`Failed to load episode: ${e2}`);
541333
541374
  }
541334
541375
  console.log();
541335
- renderInfo2("Press Enter to go back...");
541336
- await new Promise((resolve41) => {
541337
- rl.resume();
541338
- rl.once("line", () => resolve41());
541376
+ const backItem = [{ key: "back", label: import_chalk.default.cyan(" Back to Episodes") }];
541377
+ await tuiSelect({
541378
+ items: backItem,
541379
+ rl,
541380
+ availableRows: 3
541339
541381
  });
541340
541382
  }
541341
541383
  var import_chalk;
@@ -557971,7 +558013,7 @@ var init_types = __esm({
557971
558013
  });
557972
558014
 
557973
558015
  // packages/cli/src/tui/p2p/secret-vault.ts
557974
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync2, createHash as createHash8 } from "node:crypto";
558016
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync2, createHash as createHash9 } from "node:crypto";
557975
558017
  import { readFileSync as readFileSync54, writeFileSync as writeFileSync37, existsSync as existsSync69, mkdirSync as mkdirSync40 } from "node:fs";
557976
558018
  import { dirname as dirname26 } from "node:path";
557977
558019
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
@@ -558216,7 +558258,7 @@ var init_secret_vault = __esm({
558216
558258
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
558217
558259
  fingerprint() {
558218
558260
  const names = Array.from(this.secrets.keys()).sort();
558219
- const hash = createHash8("sha256");
558261
+ const hash = createHash9("sha256");
558220
558262
  for (const name10 of names) {
558221
558263
  hash.update(name10 + ":");
558222
558264
  hash.update(this.secrets.get(name10).value);
@@ -558231,7 +558273,7 @@ var init_secret_vault = __esm({
558231
558273
  // packages/cli/src/tui/p2p/peer-mesh.ts
558232
558274
  import { EventEmitter as EventEmitter7 } from "node:events";
558233
558275
  import { createServer as createServer5 } from "node:http";
558234
- import { randomBytes as randomBytes19, createHash as createHash9, generateKeyPairSync } from "node:crypto";
558276
+ import { randomBytes as randomBytes19, createHash as createHash10, generateKeyPairSync } from "node:crypto";
558235
558277
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
558236
558278
  var init_peer_mesh = __esm({
558237
558279
  "packages/cli/src/tui/p2p/peer-mesh.ts"() {
@@ -558248,7 +558290,7 @@ var init_peer_mesh = __esm({
558248
558290
  const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
558249
558291
  this.publicKey = publicKey2.export({ type: "spki", format: "der" });
558250
558292
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
558251
- this.peerId = createHash9("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
558293
+ this.peerId = createHash10("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
558252
558294
  this.capabilities = options2.capabilities;
558253
558295
  this.displayName = options2.displayName;
558254
558296
  this._authKey = options2.authKey ?? randomBytes19(24).toString("base64url");
@@ -566112,7 +566154,7 @@ import {
566112
566154
  readFileSync as readFileSync62,
566113
566155
  readdirSync as readdirSync25,
566114
566156
  writeFileSync as writeFileSync42,
566115
- renameSync as renameSync4,
566157
+ renameSync as renameSync5,
566116
566158
  mkdirSync as mkdirSync47,
566117
566159
  unlinkSync as unlinkSync21
566118
566160
  } from "node:fs";
@@ -566135,7 +566177,7 @@ function persistSession(s2) {
566135
566177
  const final2 = sessionPath(s2.id);
566136
566178
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
566137
566179
  writeFileSync42(tmp, JSON.stringify(s2, null, 2), "utf-8");
566138
- renameSync4(tmp, final2);
566180
+ renameSync5(tmp, final2);
566139
566181
  } catch {
566140
566182
  }
566141
566183
  }
@@ -566145,7 +566187,7 @@ function persistInFlight(j) {
566145
566187
  const final2 = inFlightPath(j.sessionId);
566146
566188
  const tmp = `${final2}.tmp.${process.pid}.${Date.now()}`;
566147
566189
  writeFileSync42(tmp, JSON.stringify(j, null, 2), "utf-8");
566148
- renameSync4(tmp, final2);
566190
+ renameSync5(tmp, final2);
566149
566191
  } catch {
566150
566192
  }
566151
566193
  }
@@ -566527,7 +566569,7 @@ __export(projects_exports, {
566527
566569
  setCurrentProject: () => setCurrentProject,
566528
566570
  unregisterProject: () => unregisterProject
566529
566571
  });
566530
- import { readFileSync as readFileSync63, writeFileSync as writeFileSync43, mkdirSync as mkdirSync48, existsSync as existsSync79, statSync as statSync23, renameSync as renameSync5 } from "node:fs";
566572
+ import { readFileSync as readFileSync63, writeFileSync as writeFileSync43, mkdirSync as mkdirSync48, existsSync as existsSync79, statSync as statSync23, renameSync as renameSync6 } from "node:fs";
566531
566573
  import { homedir as homedir34 } from "node:os";
566532
566574
  import { basename as basename19, join as join97, resolve as resolve34 } from "node:path";
566533
566575
  import { randomUUID as randomUUID12 } from "node:crypto";
@@ -566546,7 +566588,7 @@ function writeAll(file) {
566546
566588
  mkdirSync48(OA_DIR3, { recursive: true });
566547
566589
  const tmp = `${PROJECTS_FILE}.${randomUUID12().slice(0, 8)}.tmp`;
566548
566590
  writeFileSync43(tmp, JSON.stringify(file, null, 2), "utf8");
566549
- renameSync5(tmp, PROJECTS_FILE);
566591
+ renameSync6(tmp, PROJECTS_FILE);
566550
566592
  }
566551
566593
  function listProjects() {
566552
566594
  const { projects } = readAll();
@@ -567540,7 +567582,7 @@ var init_disk_task_output = __esm({
567540
567582
  });
567541
567583
 
567542
567584
  // packages/cli/src/api/http.ts
567543
- import { createHash as createHash10 } from "node:crypto";
567585
+ import { createHash as createHash11 } from "node:crypto";
567544
567586
  function problemDetails(opts) {
567545
567587
  const p2 = {
567546
567588
  type: opts.type ?? "about:blank",
@@ -567603,7 +567645,7 @@ function paginated(items, page2, total) {
567603
567645
  }
567604
567646
  function computeEtag(payload) {
567605
567647
  const json = typeof payload === "string" ? payload : JSON.stringify(payload);
567606
- const hash = createHash10("sha1").update(json).digest("hex").slice(0, 16);
567648
+ const hash = createHash11("sha1").update(json).digest("hex").slice(0, 16);
567607
567649
  return `W/"${hash}"`;
567608
567650
  }
567609
567651
  function checkNotModified(req2, res, etag) {
@@ -575382,7 +575424,7 @@ import { homedir as homedir39 } from "node:os";
575382
575424
  import { spawn as spawn25, execSync as execSync55 } from "node:child_process";
575383
575425
  import { mkdirSync as mkdirSync54, writeFileSync as writeFileSync47, readFileSync as readFileSync69, readdirSync as readdirSync29, existsSync as existsSync87, watch as fsWatch3 } from "node:fs";
575384
575426
  import { randomBytes as randomBytes21, randomUUID as randomUUID13 } from "node:crypto";
575385
- import { createHash as createHash12 } from "node:crypto";
575427
+ import { createHash as createHash13 } from "node:crypto";
575386
575428
  function getVersion3() {
575387
575429
  try {
575388
575430
  const require3 = createRequire4(import.meta.url);
@@ -576129,8 +576171,9 @@ function checkAuth(req2, res, requiredScope = "read") {
576129
576171
  });
576130
576172
  return false;
576131
576173
  }
576132
- req2._authUser = auth.user;
576133
- req2._authScope = auth.scope;
576174
+ const reqWithAuth = req2;
576175
+ reqWithAuth._authUser = auth.user;
576176
+ reqWithAuth._authScope = auth.scope;
576134
576177
  return true;
576135
576178
  }
576136
576179
  function handleHealth(res) {
@@ -579408,7 +579451,7 @@ function listScheduledTasks() {
579408
579451
  const schedule = String(t2?.schedule || t2?.cron || t2?.when || "");
579409
579452
  const enabled2 = typeof t2?.enabled === "boolean" ? t2.enabled : true;
579410
579453
  const realId = typeof t2?.id === "string" && t2.id ? t2.id : null;
579411
- const fallbackId = createHash12("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
579454
+ const fallbackId = createHash13("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
579412
579455
  const uid = realId || fallbackId;
579413
579456
  const key = `${uid}`;
579414
579457
  if (seen.has(key)) return;
@@ -579525,8 +579568,8 @@ function deleteScheduledById(id) {
579525
579568
  if (id) candidates.push(id);
579526
579569
  if (typeof entry?.id === "string" && entry.id && !candidates.includes(entry.id)) candidates.push(entry.id);
579527
579570
  try {
579528
- const { createHash: createHash13 } = __require("node:crypto");
579529
- const fallback = createHash13("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
579571
+ const { createHash: createHash14 } = __require("node:crypto");
579572
+ const fallback = createHash14("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
579530
579573
  if (!candidates.includes(fallback)) candidates.push(fallback);
579531
579574
  } catch {
579532
579575
  }
@@ -587105,13 +587148,13 @@ ${fullInput}`;
587105
587148
  writeContent(() => renderError2(errMsg));
587106
587149
  if (failureStore) {
587107
587150
  try {
587108
- const { createHash: createHash13 } = await import("node:crypto");
587151
+ const { createHash: createHash14 } = await import("node:crypto");
587109
587152
  failureStore.insert({
587110
587153
  taskId: "",
587111
587154
  sessionId: `${Date.now()}`,
587112
587155
  repoRoot,
587113
587156
  failureType: "runtime-error",
587114
- fingerprint: createHash13("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
587157
+ fingerprint: createHash14("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
587115
587158
  filePath: null,
587116
587159
  errorMessage: errMsg.slice(0, 500),
587117
587160
  context: null,
@@ -588714,6 +588757,7 @@ import { dirname as dirname33, join as join109 } from "node:path";
588714
588757
 
588715
588758
  // packages/cli/src/cli.ts
588716
588759
  init_typed_node_events();
588760
+ init_dist8();
588717
588761
  import { createInterface } from "node:readline";
588718
588762
  function createCli(options2) {
588719
588763
  return {
@@ -588723,6 +588767,29 @@ function createCli(options2) {
588723
588767
  console.log(`Backend: ${options2.backendUrl}`);
588724
588768
  console.log(`Project: ${options2.projectRoot}`);
588725
588769
  console.log("");
588770
+ const backend = new OllamaAgenticBackend(options2.backendUrl, options2.model);
588771
+ const runner = new AgenticRunner(backend, {
588772
+ maxTurns: 50
588773
+ });
588774
+ runner.onEvent((event) => {
588775
+ switch (event.type) {
588776
+ case "tool_call":
588777
+ if (event.toolName) console.log(`[tool] ${event.toolName}`);
588778
+ break;
588779
+ case "tool_result":
588780
+ if (event.toolName) console.log(`[tool] ${event.toolName} ${event.success ? "✓" : "✗"}`);
588781
+ break;
588782
+ case "status":
588783
+ if (event.content) console.log(`[status] ${event.content.slice(0, 100)}`);
588784
+ break;
588785
+ case "assistant_text":
588786
+ if (event.content) process.stdout.write(event.content);
588787
+ break;
588788
+ case "error":
588789
+ if (event.content) console.error(`[error] ${event.content}`);
588790
+ break;
588791
+ }
588792
+ });
588726
588793
  const rl = createInterface({
588727
588794
  input: process.stdin,
588728
588795
  output: process.stdout,
@@ -588740,8 +588807,16 @@ function createCli(options2) {
588740
588807
  rl.close();
588741
588808
  return;
588742
588809
  }
588743
- console.log(`[agent] Processing: "${input}"`);
588744
- console.log("[agent] Agent loop not yet connected.");
588810
+ try {
588811
+ const result = await runner.run(input);
588812
+ console.log("");
588813
+ console.log(`[agent] Task completed: ${result.completed ? "success" : "incomplete"}`);
588814
+ if (result.summary) {
588815
+ console.log(`[agent] Summary: ${result.summary.slice(0, 200)}`);
588816
+ }
588817
+ } catch (err) {
588818
+ console.error("[agent] Error:", err instanceof Error ? err.message : String(err));
588819
+ }
588745
588820
  console.log("");
588746
588821
  rl.prompt();
588747
588822
  });
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.430",
3
+ "version": "0.187.432",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "open-agents-ai",
9
- "version": "0.187.430",
9
+ "version": "0.187.432",
10
10
  "hasInstallScript": true,
11
11
  "license": "CC-BY-NC-4.0",
12
12
  "dependencies": {
@@ -3229,9 +3229,9 @@
3229
3229
  }
3230
3230
  },
3231
3231
  "node_modules/caniuse-lite": {
3232
- "version": "1.0.30001788",
3233
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001788.tgz",
3234
- "integrity": "sha512-6q8HFp+lOQtcf7wBK+uEenxymVWkGKkjFpCvw5W25cmMwEDU45p1xQFBQv8JDlMMry7eNxyBaR+qxgmTUZkIRQ==",
3232
+ "version": "1.0.30001790",
3233
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001790.tgz",
3234
+ "integrity": "sha512-bOoxfJPyYo+ds6W0YfptaCWbFnJYjh2Y1Eow5lRv+vI2u8ganPZqNm1JwNh0t2ELQCqIWg4B3dWEusgAmsoyOw==",
3235
3235
  "funding": [
3236
3236
  {
3237
3237
  "type": "opencollective",
@@ -3944,9 +3944,9 @@
3944
3944
  "license": "MIT"
3945
3945
  },
3946
3946
  "node_modules/electron-to-chromium": {
3947
- "version": "1.5.342",
3948
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.342.tgz",
3949
- "integrity": "sha512-GTuy59SdGxYgz+HN8KwOjFAVF2gfoKEmv0PFholcvVtbI9GPDND0m6ynGX3gAKOavcHRLrcfNy0QMbHbAemYdw==",
3947
+ "version": "1.5.343",
3948
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.343.tgz",
3949
+ "integrity": "sha512-YHnQ3MXI08icvL9ZKnEBy05F2EQ8ob01UaMOuMbM8l+4UcAq6MPPbBTJBbsBUg3H8JeZNt+O4fjsoWth3p6IFg==",
3950
3950
  "license": "ISC",
3951
3951
  "peer": true
3952
3952
  },
@@ -6822,9 +6822,9 @@
6822
6822
  }
6823
6823
  },
6824
6824
  "node_modules/node-releases": {
6825
- "version": "2.0.37",
6826
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz",
6827
- "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==",
6825
+ "version": "2.0.38",
6826
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz",
6827
+ "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==",
6828
6828
  "license": "MIT",
6829
6829
  "peer": true
6830
6830
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.187.430",
3
+ "version": "0.187.432",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",