@codexhost/cli-darwin-x64 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,529 +5,9 @@ var __export = (target, all) => {
5
5
  __defProp(target, name, { get: all[name], enumerable: true });
6
6
  };
7
7
 
8
- // ../../../node_modules/diff/libesm/diff/base.js
9
- var Diff = class {
10
- diff(oldStr, newStr, options = {}) {
11
- let callback;
12
- if (typeof options === "function") {
13
- callback = options;
14
- options = {};
15
- } else if ("callback" in options) {
16
- callback = options.callback;
17
- }
18
- const oldString = this.castInput(oldStr, options);
19
- const newString = this.castInput(newStr, options);
20
- const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
21
- const newTokens = this.removeEmpty(this.tokenize(newString, options));
22
- return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
23
- }
24
- diffWithOptionsObj(oldTokens, newTokens, options, callback) {
25
- var _a3;
26
- const done = (value) => {
27
- value = this.postProcess(value, options);
28
- if (callback) {
29
- setTimeout(function() {
30
- callback(value);
31
- }, 0);
32
- return void 0;
33
- } else {
34
- return value;
35
- }
36
- };
37
- const newLen = newTokens.length, oldLen = oldTokens.length;
38
- let editLength = 1;
39
- let maxEditLength = newLen + oldLen;
40
- if (options.maxEditLength != null) {
41
- maxEditLength = Math.min(maxEditLength, options.maxEditLength);
42
- }
43
- const maxExecutionTime = (_a3 = options.timeout) !== null && _a3 !== void 0 ? _a3 : Infinity;
44
- const abortAfterTimestamp = Date.now() + maxExecutionTime;
45
- const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
46
- let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
47
- if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
48
- return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
49
- }
50
- let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
51
- const execEditLength = () => {
52
- for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
53
- let basePath;
54
- const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
55
- if (removePath) {
56
- bestPath[diagonalPath - 1] = void 0;
57
- }
58
- let canAdd = false;
59
- if (addPath) {
60
- const addPathNewPos = addPath.oldPos - diagonalPath;
61
- canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
62
- }
63
- const canRemove = removePath && removePath.oldPos + 1 < oldLen;
64
- if (!canAdd && !canRemove) {
65
- bestPath[diagonalPath] = void 0;
66
- continue;
67
- }
68
- if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
69
- basePath = this.addToPath(addPath, true, false, 0, options);
70
- } else {
71
- basePath = this.addToPath(removePath, false, true, 1, options);
72
- }
73
- newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
74
- if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
75
- return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
76
- } else {
77
- bestPath[diagonalPath] = basePath;
78
- if (basePath.oldPos + 1 >= oldLen) {
79
- maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
80
- }
81
- if (newPos + 1 >= newLen) {
82
- minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
83
- }
84
- }
85
- }
86
- editLength++;
87
- };
88
- if (callback) {
89
- (function exec() {
90
- setTimeout(function() {
91
- if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
92
- return callback(void 0);
93
- }
94
- if (!execEditLength()) {
95
- exec();
96
- }
97
- }, 0);
98
- })();
99
- } else {
100
- while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
101
- const ret = execEditLength();
102
- if (ret) {
103
- return ret;
104
- }
105
- }
106
- }
107
- }
108
- addToPath(path6, added, removed, oldPosInc, options) {
109
- const last = path6.lastComponent;
110
- if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
111
- return {
112
- oldPos: path6.oldPos + oldPosInc,
113
- lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
114
- };
115
- } else {
116
- return {
117
- oldPos: path6.oldPos + oldPosInc,
118
- lastComponent: { count: 1, added, removed, previousComponent: last }
119
- };
120
- }
121
- }
122
- extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
123
- const newLen = newTokens.length, oldLen = oldTokens.length;
124
- let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
125
- while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
126
- newPos++;
127
- oldPos++;
128
- commonCount++;
129
- if (options.oneChangePerToken) {
130
- basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
131
- }
132
- }
133
- if (commonCount && !options.oneChangePerToken) {
134
- basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
135
- }
136
- basePath.oldPos = oldPos;
137
- return newPos;
138
- }
139
- equals(left, right, options) {
140
- if (options.comparator) {
141
- return options.comparator(left, right);
142
- } else {
143
- return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
144
- }
145
- }
146
- removeEmpty(array2) {
147
- const ret = [];
148
- for (let i = 0; i < array2.length; i++) {
149
- if (array2[i]) {
150
- ret.push(array2[i]);
151
- }
152
- }
153
- return ret;
154
- }
155
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
156
- castInput(value, options) {
157
- return value;
158
- }
159
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
160
- tokenize(value, options) {
161
- return Array.from(value);
162
- }
163
- join(chars) {
164
- return chars.join("");
165
- }
166
- postProcess(changeObjects, options) {
167
- return changeObjects;
168
- }
169
- get useLongestToken() {
170
- return false;
171
- }
172
- buildValues(lastComponent, newTokens, oldTokens) {
173
- const components = [];
174
- let nextComponent;
175
- while (lastComponent) {
176
- components.push(lastComponent);
177
- nextComponent = lastComponent.previousComponent;
178
- delete lastComponent.previousComponent;
179
- lastComponent = nextComponent;
180
- }
181
- components.reverse();
182
- const componentLen = components.length;
183
- let componentPos = 0, newPos = 0, oldPos = 0;
184
- for (; componentPos < componentLen; componentPos++) {
185
- const component = components[componentPos];
186
- if (!component.removed) {
187
- if (!component.added && this.useLongestToken) {
188
- let value = newTokens.slice(newPos, newPos + component.count);
189
- value = value.map(function(value2, i) {
190
- const oldValue = oldTokens[oldPos + i];
191
- return oldValue.length > value2.length ? oldValue : value2;
192
- });
193
- component.value = this.join(value);
194
- } else {
195
- component.value = this.join(newTokens.slice(newPos, newPos + component.count));
196
- }
197
- newPos += component.count;
198
- if (!component.added) {
199
- oldPos += component.count;
200
- }
201
- } else {
202
- component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
203
- oldPos += component.count;
204
- }
205
- }
206
- return components;
207
- }
208
- };
209
-
210
- // ../../../node_modules/diff/libesm/diff/line.js
211
- var LineDiff = class extends Diff {
212
- constructor() {
213
- super(...arguments);
214
- this.tokenize = tokenize;
215
- }
216
- equals(left, right, options) {
217
- if (options.ignoreWhitespace) {
218
- if (!options.newlineIsToken || !left.includes("\n")) {
219
- left = left.trim();
220
- }
221
- if (!options.newlineIsToken || !right.includes("\n")) {
222
- right = right.trim();
223
- }
224
- } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
225
- if (left.endsWith("\n")) {
226
- left = left.slice(0, -1);
227
- }
228
- if (right.endsWith("\n")) {
229
- right = right.slice(0, -1);
230
- }
231
- }
232
- return super.equals(left, right, options);
233
- }
234
- };
235
- var lineDiff = new LineDiff();
236
- function diffLines(oldStr, newStr, options) {
237
- return lineDiff.diff(oldStr, newStr, options);
238
- }
239
- function tokenize(value, options) {
240
- if (options.stripTrailingCr) {
241
- value = value.replace(/\r\n/g, "\n");
242
- }
243
- const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
244
- if (!linesAndNewlines[linesAndNewlines.length - 1]) {
245
- linesAndNewlines.pop();
246
- }
247
- for (let i = 0; i < linesAndNewlines.length; i++) {
248
- const line = linesAndNewlines[i];
249
- if (i % 2 && !options.newlineIsToken) {
250
- retLines[retLines.length - 1] += line;
251
- } else {
252
- retLines.push(line);
253
- }
254
- }
255
- return retLines;
256
- }
257
-
258
- // ../../../node_modules/diff/libesm/patch/parse.js
259
- function parsePatch(uniDiff) {
260
- const diffstr = uniDiff.split(/\n/), list = [];
261
- let i = 0;
262
- function parseIndex() {
263
- const index = {};
264
- list.push(index);
265
- while (i < diffstr.length) {
266
- const line = diffstr[i];
267
- if (/^(---|\+\+\+|@@)\s/.test(line)) {
268
- break;
269
- }
270
- const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
271
- if (header) {
272
- index.index = header[1];
273
- }
274
- i++;
275
- }
276
- parseFileHeader(index);
277
- parseFileHeader(index);
278
- index.hunks = [];
279
- while (i < diffstr.length) {
280
- const line = diffstr[i];
281
- if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
282
- break;
283
- } else if (/^@@/.test(line)) {
284
- index.hunks.push(parseHunk());
285
- } else if (line) {
286
- throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
287
- } else {
288
- i++;
289
- }
290
- }
291
- }
292
- function parseFileHeader(index) {
293
- const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
294
- if (fileHeader) {
295
- const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
296
- let fileName = data[0].replace(/\\\\/g, "\\");
297
- if (/^".*"$/.test(fileName)) {
298
- fileName = fileName.substr(1, fileName.length - 2);
299
- }
300
- if (fileHeader[1] === "---") {
301
- index.oldFileName = fileName;
302
- index.oldHeader = header;
303
- } else {
304
- index.newFileName = fileName;
305
- index.newHeader = header;
306
- }
307
- i++;
308
- }
309
- }
310
- function parseHunk() {
311
- var _a3;
312
- const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
313
- const hunk = {
314
- oldStart: +chunkHeader[1],
315
- oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
316
- newStart: +chunkHeader[3],
317
- newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
318
- lines: []
319
- };
320
- if (hunk.oldLines === 0) {
321
- hunk.oldStart += 1;
322
- }
323
- if (hunk.newLines === 0) {
324
- hunk.newStart += 1;
325
- }
326
- let addCount = 0, removeCount = 0;
327
- for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
328
- const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
329
- if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
330
- hunk.lines.push(diffstr[i]);
331
- if (operation === "+") {
332
- addCount++;
333
- } else if (operation === "-") {
334
- removeCount++;
335
- } else if (operation === " ") {
336
- addCount++;
337
- removeCount++;
338
- }
339
- } else {
340
- throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
341
- }
342
- }
343
- if (!addCount && hunk.newLines === 1) {
344
- hunk.newLines = 0;
345
- }
346
- if (!removeCount && hunk.oldLines === 1) {
347
- hunk.oldLines = 0;
348
- }
349
- if (addCount !== hunk.newLines) {
350
- throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
351
- }
352
- if (removeCount !== hunk.oldLines) {
353
- throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
354
- }
355
- return hunk;
356
- }
357
- while (i < diffstr.length) {
358
- parseIndex();
359
- }
360
- return list;
361
- }
362
-
363
- // ../../../node_modules/diff/libesm/patch/create.js
364
- function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
365
- let optionsObj;
366
- if (!options) {
367
- optionsObj = {};
368
- } else if (typeof options === "function") {
369
- optionsObj = { callback: options };
370
- } else {
371
- optionsObj = options;
372
- }
373
- if (typeof optionsObj.context === "undefined") {
374
- optionsObj.context = 4;
375
- }
376
- const context = optionsObj.context;
377
- if (optionsObj.newlineIsToken) {
378
- throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
379
- }
380
- if (!optionsObj.callback) {
381
- return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
382
- } else {
383
- const { callback } = optionsObj;
384
- diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
385
- const patch = diffLinesResultToPatch(diff);
386
- callback(patch);
387
- } }));
388
- }
389
- function diffLinesResultToPatch(diff) {
390
- if (!diff) {
391
- return;
392
- }
393
- diff.push({ value: "", lines: [] });
394
- function contextLines(lines) {
395
- return lines.map(function(entry) {
396
- return " " + entry;
397
- });
398
- }
399
- const hunks = [];
400
- let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
401
- for (let i = 0; i < diff.length; i++) {
402
- const current = diff[i], lines = current.lines || splitLines(current.value);
403
- current.lines = lines;
404
- if (current.added || current.removed) {
405
- if (!oldRangeStart) {
406
- const prev = diff[i - 1];
407
- oldRangeStart = oldLine;
408
- newRangeStart = newLine;
409
- if (prev) {
410
- curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
411
- oldRangeStart -= curRange.length;
412
- newRangeStart -= curRange.length;
413
- }
414
- }
415
- for (const line of lines) {
416
- curRange.push((current.added ? "+" : "-") + line);
417
- }
418
- if (current.added) {
419
- newLine += lines.length;
420
- } else {
421
- oldLine += lines.length;
422
- }
423
- } else {
424
- if (oldRangeStart) {
425
- if (lines.length <= context * 2 && i < diff.length - 2) {
426
- for (const line of contextLines(lines)) {
427
- curRange.push(line);
428
- }
429
- } else {
430
- const contextSize = Math.min(lines.length, context);
431
- for (const line of contextLines(lines.slice(0, contextSize))) {
432
- curRange.push(line);
433
- }
434
- const hunk = {
435
- oldStart: oldRangeStart,
436
- oldLines: oldLine - oldRangeStart + contextSize,
437
- newStart: newRangeStart,
438
- newLines: newLine - newRangeStart + contextSize,
439
- lines: curRange
440
- };
441
- hunks.push(hunk);
442
- oldRangeStart = 0;
443
- newRangeStart = 0;
444
- curRange = [];
445
- }
446
- }
447
- oldLine += lines.length;
448
- newLine += lines.length;
449
- }
450
- }
451
- for (const hunk of hunks) {
452
- for (let i = 0; i < hunk.lines.length; i++) {
453
- if (hunk.lines[i].endsWith("\n")) {
454
- hunk.lines[i] = hunk.lines[i].slice(0, -1);
455
- } else {
456
- hunk.lines.splice(i + 1, 0, "\");
457
- i++;
458
- }
459
- }
460
- }
461
- return {
462
- oldFileName,
463
- newFileName,
464
- oldHeader,
465
- newHeader,
466
- hunks
467
- };
468
- }
469
- }
470
- function formatPatch(patch) {
471
- if (Array.isArray(patch)) {
472
- return patch.map(formatPatch).join("\n");
473
- }
474
- const ret = [];
475
- if (patch.oldFileName == patch.newFileName) {
476
- ret.push("Index: " + patch.oldFileName);
477
- }
478
- ret.push("===================================================================");
479
- ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
480
- ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
481
- for (let i = 0; i < patch.hunks.length; i++) {
482
- const hunk = patch.hunks[i];
483
- if (hunk.oldLines === 0) {
484
- hunk.oldStart -= 1;
485
- }
486
- if (hunk.newLines === 0) {
487
- hunk.newStart -= 1;
488
- }
489
- ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
490
- for (const line of hunk.lines) {
491
- ret.push(line);
492
- }
493
- }
494
- return ret.join("\n") + "\n";
495
- }
496
- function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
497
- if (typeof options === "function") {
498
- options = { callback: options };
499
- }
500
- if (!(options === null || options === void 0 ? void 0 : options.callback)) {
501
- const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
502
- if (!patchObj) {
503
- return;
504
- }
505
- return formatPatch(patchObj);
506
- } else {
507
- const { callback } = options;
508
- structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
509
- if (!patchObj) {
510
- callback(void 0);
511
- } else {
512
- callback(formatPatch(patchObj));
513
- }
514
- } }));
515
- }
516
- }
517
- function splitLines(text) {
518
- const hasTrailingNl = text.endsWith("\n");
519
- const result = text.split("\n").map((line) => line + "\n");
520
- if (hasTrailingNl) {
521
- result.pop();
522
- } else {
523
- result.push(result.pop().slice(0, -1));
524
- }
525
- return result;
526
- }
527
-
528
- // dist/pi-adapter.js
529
- import { randomUUID as randomUUID2 } from "node:crypto";
530
- import path5 from "node:path";
8
+ // dist/pi-empty-session.js
9
+ import { createReadStream } from "node:fs";
10
+ import { createInterface } from "node:readline";
531
11
 
532
12
  // ../../../node_modules/zod/v4/classic/external.js
533
13
  var external_exports = {};
@@ -1295,10 +775,10 @@ function mergeDefs(...defs) {
1295
775
  function cloneDef(schema) {
1296
776
  return mergeDefs(schema._zod.def);
1297
777
  }
1298
- function getElementAtPath(obj, path6) {
1299
- if (!path6)
778
+ function getElementAtPath(obj, path7) {
779
+ if (!path7)
1300
780
  return obj;
1301
- return path6.reduce((acc, key) => acc?.[key], obj);
781
+ return path7.reduce((acc, key) => acc?.[key], obj);
1302
782
  }
1303
783
  function promiseAllObject(promisesObj) {
1304
784
  const keys = Object.keys(promisesObj);
@@ -1707,11 +1187,11 @@ function explicitlyAborted(x, startIndex = 0) {
1707
1187
  }
1708
1188
  return false;
1709
1189
  }
1710
- function prefixIssues(path6, issues) {
1190
+ function prefixIssues(path7, issues) {
1711
1191
  return issues.map((iss) => {
1712
1192
  var _a3;
1713
1193
  (_a3 = iss).path ?? (_a3.path = []);
1714
- iss.path.unshift(path6);
1194
+ iss.path.unshift(path7);
1715
1195
  return iss;
1716
1196
  });
1717
1197
  }
@@ -1858,16 +1338,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1858
1338
  }
1859
1339
  function formatError(error51, mapper = (issue2) => issue2.message) {
1860
1340
  const fieldErrors = { _errors: [] };
1861
- const processError = (error52, path6 = []) => {
1341
+ const processError = (error52, path7 = []) => {
1862
1342
  for (const issue2 of error52.issues) {
1863
1343
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1864
- issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
1344
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
1865
1345
  } else if (issue2.code === "invalid_key") {
1866
- processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1346
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1867
1347
  } else if (issue2.code === "invalid_element") {
1868
- processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1348
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1869
1349
  } else {
1870
- const fullpath = [...path6, ...issue2.path];
1350
+ const fullpath = [...path7, ...issue2.path];
1871
1351
  if (fullpath.length === 0) {
1872
1352
  fieldErrors._errors.push(mapper(issue2));
1873
1353
  } else {
@@ -1894,17 +1374,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1894
1374
  }
1895
1375
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1896
1376
  const result = { errors: [] };
1897
- const processError = (error52, path6 = []) => {
1377
+ const processError = (error52, path7 = []) => {
1898
1378
  var _a3, _b;
1899
1379
  for (const issue2 of error52.issues) {
1900
1380
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1901
- issue2.errors.map((issues) => processError({ issues }, [...path6, ...issue2.path]));
1381
+ issue2.errors.map((issues) => processError({ issues }, [...path7, ...issue2.path]));
1902
1382
  } else if (issue2.code === "invalid_key") {
1903
- processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1383
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1904
1384
  } else if (issue2.code === "invalid_element") {
1905
- processError({ issues: issue2.issues }, [...path6, ...issue2.path]);
1385
+ processError({ issues: issue2.issues }, [...path7, ...issue2.path]);
1906
1386
  } else {
1907
- const fullpath = [...path6, ...issue2.path];
1387
+ const fullpath = [...path7, ...issue2.path];
1908
1388
  if (fullpath.length === 0) {
1909
1389
  result.errors.push(mapper(issue2));
1910
1390
  continue;
@@ -1936,8 +1416,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1936
1416
  }
1937
1417
  function toDotPath(_path) {
1938
1418
  const segs = [];
1939
- const path6 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1940
- for (const seg of path6) {
1419
+ const path7 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1420
+ for (const seg of path7) {
1941
1421
  if (typeof seg === "number")
1942
1422
  segs.push(`[${seg}]`);
1943
1423
  else if (typeof seg === "symbol")
@@ -14629,13 +14109,13 @@ function resolveRef(ref, ctx) {
14629
14109
  if (!ref.startsWith("#")) {
14630
14110
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14631
14111
  }
14632
- const path6 = ref.slice(1).split("/").filter(Boolean);
14633
- if (path6.length === 0) {
14112
+ const path7 = ref.slice(1).split("/").filter(Boolean);
14113
+ if (path7.length === 0) {
14634
14114
  return ctx.rootSchema;
14635
14115
  }
14636
14116
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14637
- if (path6[0] === defsKey) {
14638
- const key = path6[1];
14117
+ if (path7[0] === defsKey) {
14118
+ const key = path7[1];
14639
14119
  if (!key || !ctx.defs[key]) {
14640
14120
  throw new Error(`Reference not found: ${ref}`);
14641
14121
  }
@@ -15069,6 +14549,8 @@ var threadUsageSnapshotSchema = external_exports.object({
15069
14549
  reasoningOutputTokens: nonNegativeSafeIntegerSchema.optional(),
15070
14550
  totalTokens: nonNegativeSafeIntegerSchema.optional(),
15071
14551
  totalCostUsd: finiteNonNegativeNumberSchema.optional(),
14552
+ totalCredits: finiteNonNegativeNumberSchema.optional(),
14553
+ contextUsagePercent: finiteNonNegativeNumberSchema.optional(),
15072
14554
  cacheHitRatePercent: cacheHitRatePercentSchema.optional(),
15073
14555
  contextWindowTokens: nonNegativeSafeIntegerSchema.optional(),
15074
14556
  contextUsedTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -15699,713 +15181,1405 @@ var externalThreadForkResultSchema = external_exports.object({
15699
15181
  threadId: hostThreadIdSchema
15700
15182
  }).strict();
15701
15183
 
15702
- // ../../shared-contracts/dist/harness-commands.js
15703
- var commandIdSchema = external_exports.string().trim().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u).brand();
15704
- var commandInvocationSchema = external_exports.string().min(1).max(128);
15705
- var commandLabelSchema = external_exports.string().trim().min(1).max(128);
15706
- var commandDescriptionSchema = external_exports.string().trim().min(1).max(512);
15707
- var harnessCommandDescriptorSchema = external_exports.object({
15708
- id: commandIdSchema,
15709
- invocation: commandInvocationSchema,
15710
- label: commandLabelSchema,
15711
- description: commandDescriptionSchema.optional(),
15712
- argumentMode: external_exports.enum(["none", "text"])
15713
- }).strict();
15714
- var harnessCommandCatalogSchema = external_exports.object({
15715
- commands: external_exports.array(harnessCommandDescriptorSchema)
15716
- }).strict().superRefine((catalog, context) => {
15717
- const ids = /* @__PURE__ */ new Set();
15718
- for (const [index, command] of catalog.commands.entries()) {
15719
- if (ids.has(command.id)) {
15720
- context.addIssue({
15721
- code: "custom",
15722
- message: "Harness command IDs must be unique",
15723
- path: ["commands", index, "id"]
15724
- });
15184
+ // ../../shared-contracts/dist/harness-commands.js
15185
+ var commandIdSchema = external_exports.string().trim().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u).brand();
15186
+ var commandInvocationSchema = external_exports.string().min(1).max(128);
15187
+ var commandLabelSchema = external_exports.string().trim().min(1).max(128);
15188
+ var commandDescriptionSchema = external_exports.string().trim().min(1).max(512);
15189
+ var harnessCommandDescriptorSchema = external_exports.object({
15190
+ id: commandIdSchema,
15191
+ invocation: commandInvocationSchema,
15192
+ label: commandLabelSchema,
15193
+ description: commandDescriptionSchema.optional(),
15194
+ argumentMode: external_exports.enum(["none", "text"])
15195
+ }).strict();
15196
+ var harnessCommandCatalogSchema = external_exports.object({
15197
+ commands: external_exports.array(harnessCommandDescriptorSchema)
15198
+ }).strict().superRefine((catalog, context) => {
15199
+ const ids = /* @__PURE__ */ new Set();
15200
+ for (const [index, command] of catalog.commands.entries()) {
15201
+ if (ids.has(command.id)) {
15202
+ context.addIssue({
15203
+ code: "custom",
15204
+ message: "Harness command IDs must be unique",
15205
+ path: ["commands", index, "id"]
15206
+ });
15207
+ }
15208
+ ids.add(command.id);
15209
+ }
15210
+ });
15211
+ var harnessCommandsInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema }).strict();
15212
+ var threadCommandsInspectParamsSchema = external_exports.object({
15213
+ threadId: hostThreadIdSchema
15214
+ }).strict();
15215
+ var threadCommandExecuteParamsSchema = external_exports.object({
15216
+ threadId: hostThreadIdSchema,
15217
+ commandId: commandIdSchema,
15218
+ turnId: hostTurnIdSchema.optional(),
15219
+ arguments: jsonObjectSchema.optional()
15220
+ }).strict();
15221
+ var threadCommandExecuteResultSchema = external_exports.object({
15222
+ accepted: external_exports.literal(true),
15223
+ turnId: hostTurnIdSchema
15224
+ }).strict();
15225
+
15226
+ // ../../shared-contracts/dist/json-rpc.js
15227
+ var jsonRpcVersionSchema = external_exports.literal("2.0").optional();
15228
+ var absentSchema = external_exports.never().optional();
15229
+ var methodSchema = external_exports.string().min(1);
15230
+ var jsonRpcIdSchema = external_exports.union([external_exports.string(), external_exports.number().int()]);
15231
+ var jsonRpcErrorSchema = external_exports.object({
15232
+ code: external_exports.number().int(),
15233
+ message: external_exports.string(),
15234
+ data: jsonValueSchema.optional()
15235
+ }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["data"]));
15236
+ var jsonRpcRequestSchema = external_exports.object({
15237
+ jsonrpc: jsonRpcVersionSchema,
15238
+ id: jsonRpcIdSchema,
15239
+ method: methodSchema,
15240
+ params: jsonValueSchema.optional(),
15241
+ result: absentSchema,
15242
+ error: absentSchema
15243
+ }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "params", "result", "error"]));
15244
+ var jsonRpcNotificationSchema = external_exports.object({
15245
+ jsonrpc: jsonRpcVersionSchema,
15246
+ id: absentSchema,
15247
+ method: methodSchema,
15248
+ params: jsonValueSchema.optional(),
15249
+ result: absentSchema,
15250
+ error: absentSchema
15251
+ }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "id", "params", "result", "error"]));
15252
+ var jsonRpcSuccessResponseSchema = external_exports.object({
15253
+ jsonrpc: jsonRpcVersionSchema,
15254
+ id: jsonRpcIdSchema,
15255
+ method: absentSchema,
15256
+ params: absentSchema,
15257
+ result: jsonValueSchema,
15258
+ error: absentSchema
15259
+ }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "method", "params", "error"]));
15260
+ var jsonRpcErrorResponseSchema = external_exports.object({
15261
+ jsonrpc: jsonRpcVersionSchema,
15262
+ id: jsonRpcIdSchema,
15263
+ method: absentSchema,
15264
+ params: absentSchema,
15265
+ result: absentSchema,
15266
+ error: jsonRpcErrorSchema
15267
+ }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "method", "params", "result"]));
15268
+ var jsonRpcEnvelopeSchema = external_exports.union([
15269
+ jsonRpcRequestSchema,
15270
+ jsonRpcNotificationSchema,
15271
+ jsonRpcSuccessResponseSchema,
15272
+ jsonRpcErrorResponseSchema
15273
+ ]);
15274
+
15275
+ // ../../shared-contracts/dist/native-refs.js
15276
+ var nativeIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15277
+ message: "Native identifier must not be empty or whitespace"
15278
+ });
15279
+ var nativeSessionRefV1RuntimeSchema = external_exports.strictObject({
15280
+ harnessId: harnessIdSchema,
15281
+ nativeSessionId: nativeIdSchema,
15282
+ locator: jsonValueSchema.optional(),
15283
+ formatVersion: external_exports.literal(1)
15284
+ }).superRefine(rejectExplicitUndefined(["locator"]));
15285
+ var nativeSessionRefV1Schema = nativeSessionRefV1RuntimeSchema;
15286
+ var nativeSessionRefSchema = nativeSessionRefV1Schema;
15287
+ var nativeTurnRefV1Schema = external_exports.strictObject({
15288
+ harnessId: harnessIdSchema,
15289
+ nativeSessionId: nativeIdSchema,
15290
+ nativeTurnKey: nativeIdSchema,
15291
+ formatVersion: external_exports.literal(1)
15292
+ });
15293
+ var nativeTurnRefSchema = nativeTurnRefV1Schema;
15294
+ var nativeCheckpointRefV1RuntimeSchema = external_exports.strictObject({
15295
+ harnessId: harnessIdSchema,
15296
+ nativeSessionId: nativeIdSchema,
15297
+ checkpointId: nativeIdSchema,
15298
+ locator: jsonValueSchema.optional(),
15299
+ formatVersion: external_exports.literal(1)
15300
+ }).superRefine(rejectExplicitUndefined(["locator"]));
15301
+ var nativeCheckpointRefV1Schema = nativeCheckpointRefV1RuntimeSchema;
15302
+ var nativeCheckpointRefSchema = nativeCheckpointRefV1Schema;
15303
+
15304
+ // ../../shared-contracts/dist/updates.js
15305
+ var UPDATE_ERROR_MAX_LENGTH = 500;
15306
+ var UPDATE_SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;
15307
+ var updateSemanticVersionSchema = external_exports.string().regex(UPDATE_SEMVER_PATTERN);
15308
+ var updateInstallationSchema = external_exports.enum(["npm", "windows-installer", "macos-dmg"]);
15309
+ var updatePhaseSchema = external_exports.enum([
15310
+ "prepared",
15311
+ "downloading",
15312
+ "waiting-for-exit",
15313
+ "installing",
15314
+ "restarting",
15315
+ "succeeded",
15316
+ "failed"
15317
+ ]);
15318
+ var updateStatusSchema = external_exports.strictObject({
15319
+ version: updateSemanticVersionSchema,
15320
+ installation: updateInstallationSchema,
15321
+ phase: updatePhaseSchema,
15322
+ updatedAt: external_exports.number().int().nonnegative(),
15323
+ downloadedBytes: external_exports.number().int().nonnegative().optional(),
15324
+ totalBytes: external_exports.number().int().positive().optional(),
15325
+ error: external_exports.string().min(1).max(UPDATE_ERROR_MAX_LENGTH).nullable()
15326
+ }).superRefine((status, context) => {
15327
+ if (status.downloadedBytes !== void 0 && status.totalBytes !== void 0 && status.downloadedBytes > status.totalBytes) {
15328
+ context.addIssue({
15329
+ code: "custom",
15330
+ path: ["downloadedBytes"],
15331
+ message: "downloadedBytes must not exceed totalBytes"
15332
+ });
15333
+ }
15334
+ });
15335
+ var updateEmptyParamsSchema = external_exports.strictObject({});
15336
+ var githubReleaseNotesUrlSchema = external_exports.string().max(300).regex(/^https:\/\/github\.com\/BytePioneer-AI\/codex-host\/releases\/tag\/v[0-9A-Za-z.+-]+$/u, "release notes URL must identify a codexhost GitHub Release");
15337
+ var updateCheckResultSchema = external_exports.strictObject({
15338
+ currentVersion: updateSemanticVersionSchema,
15339
+ installation: updateInstallationSchema.nullable(),
15340
+ latestVersion: updateSemanticVersionSchema.nullable(),
15341
+ updateAvailable: external_exports.boolean(),
15342
+ installationAvailable: external_exports.boolean(),
15343
+ releaseNotes: external_exports.string().min(1).max(2e4).nullable(),
15344
+ releaseNotesUrl: githubReleaseNotesUrlSchema.nullable(),
15345
+ status: updateStatusSchema.nullable(),
15346
+ error: external_exports.string().min(1).max(UPDATE_ERROR_MAX_LENGTH).nullable()
15347
+ });
15348
+ var updateStartResultSchema = external_exports.strictObject({
15349
+ status: updateStatusSchema
15350
+ });
15351
+ var updateStatusResultSchema = external_exports.strictObject({
15352
+ status: updateStatusSchema.nullable()
15353
+ });
15354
+
15355
+ // ../../shared-contracts/dist/index.js
15356
+ var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15357
+
15358
+ // dist/pi-empty-session.js
15359
+ import { randomUUID } from "node:crypto";
15360
+ import { link, open as open2, rm } from "node:fs/promises";
15361
+ import path from "node:path";
15362
+
15363
+ // dist/pi-model-catalog.js
15364
+ var PI_MODEL_REF_PREFIX = "pi-model-v1.";
15365
+ var PI_DRAFT_THINKING_OPTION_IDS = [
15366
+ "off",
15367
+ "minimal",
15368
+ "low",
15369
+ "medium",
15370
+ "high",
15371
+ "xhigh",
15372
+ "max"
15373
+ ].map((id) => harnessThinkingOptionIdSchema.parse(id));
15374
+ var PI_THINKING_LABELS = {
15375
+ off: "Off",
15376
+ minimal: "Minimal",
15377
+ low: "Low",
15378
+ medium: "Medium",
15379
+ high: "High",
15380
+ xhigh: "Extra High",
15381
+ max: "Max"
15382
+ };
15383
+ function compareText(left, right) {
15384
+ return left < right ? -1 : left > right ? 1 : 0;
15385
+ }
15386
+ function assertNativePart(value, name) {
15387
+ if (value.trim().length === 0)
15388
+ throw new Error(`Pi ${name} must not be empty`);
15389
+ }
15390
+ function encodePiModelRef(model) {
15391
+ assertNativePart(model.provider, "Model provider");
15392
+ assertNativePart(model.id, "Model id");
15393
+ const encoded = Buffer.from(JSON.stringify([model.provider, model.id]), "utf8").toString("base64url");
15394
+ return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
15395
+ }
15396
+ function decodePiModelRef(ref) {
15397
+ const parsedRef = harnessModelRefSchema.parse(ref);
15398
+ if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
15399
+ throw new Error("Model Ref does not belong to PiAdapter");
15400
+ }
15401
+ const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
15402
+ let decoded;
15403
+ try {
15404
+ decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
15405
+ } catch {
15406
+ throw new Error("Pi Model Ref is malformed");
15407
+ }
15408
+ if (!Array.isArray(decoded) || decoded.length !== 2 || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
15409
+ throw new Error("Pi Model Ref has an invalid native identity");
15410
+ }
15411
+ const native = { provider: decoded[0], id: decoded[1] };
15412
+ assertNativePart(native.provider, "Model provider");
15413
+ assertNativePart(native.id, "Model id");
15414
+ if (encodePiModelRef(native).id !== parsedRef.id) {
15415
+ throw new Error("Pi Model Ref is not canonical");
15416
+ }
15417
+ return native;
15418
+ }
15419
+ function samePiModel(left, right) {
15420
+ return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
15421
+ }
15422
+ function fallbackThinkingLabel(id) {
15423
+ const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
15424
+ return label || id;
15425
+ }
15426
+ function normalizePiThinkingOptions(levels) {
15427
+ return levels.map((id) => harnessThinkingOptionSchema.parse({
15428
+ id,
15429
+ label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
15430
+ }));
15431
+ }
15432
+ function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
15433
+ const byRef = /* @__PURE__ */ new Map();
15434
+ for (const native of nativeModels) {
15435
+ const ref = encodePiModelRef(native);
15436
+ const existing = byRef.get(ref.id);
15437
+ if (existing) {
15438
+ if (existing.reasoning !== native.reasoning) {
15439
+ throw new Error("Pi duplicate Model entries disagree on reasoning capability");
15440
+ }
15441
+ continue;
15442
+ }
15443
+ byRef.set(ref.id, {
15444
+ model: {
15445
+ ref,
15446
+ label: `${native.provider} / ${native.id}`
15447
+ },
15448
+ reasoning: native.reasoning
15449
+ });
15450
+ }
15451
+ const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
15452
+ if (defaultModel && !byRef.has(defaultModel.id)) {
15453
+ throw new Error("Pi effective Model is absent from the available Model catalog");
15454
+ }
15455
+ if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
15456
+ throw new Error("Pi effective Thinking option is absent from the available option catalog");
15457
+ }
15458
+ if (thinkingLevels && !effectiveThinkingOptionId) {
15459
+ throw new Error("Pi did not report an effective Thinking option");
15460
+ }
15461
+ const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
15462
+ const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
15463
+ const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
15464
+ const models = [...byRef.values()].map(({ model, reasoning }) => ({
15465
+ ...model,
15466
+ supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
15467
+ })).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
15468
+ const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
15469
+ return harnessModelCatalogSchema.parse({
15470
+ models,
15471
+ ...defaultModel ? { defaultModel } : {},
15472
+ thinkingOptions,
15473
+ ...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
15474
+ });
15475
+ }
15476
+
15477
+ // dist/pi-history.js
15478
+ var piHarnessId = harnessIdSchema.parse("pi");
15479
+ function isRecord(value) {
15480
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15481
+ }
15482
+ function textContent(value) {
15483
+ if (typeof value === "string")
15484
+ return value;
15485
+ if (!Array.isArray(value))
15486
+ return "";
15487
+ return value.filter((part) => isRecord(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
15488
+ }
15489
+ function thinkingContent(value) {
15490
+ if (!Array.isArray(value))
15491
+ return "";
15492
+ return value.filter((part) => isRecord(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
15493
+ }
15494
+ function validatedEntry(value) {
15495
+ if (typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
15496
+ throw new Error("Pi history contains an invalid Entry identity");
15497
+ }
15498
+ return value;
15499
+ }
15500
+ function activePiEntries(history) {
15501
+ if (history.leafId === null)
15502
+ return [];
15503
+ const byId = new Map(history.entries.map((value) => {
15504
+ const entry = validatedEntry(value);
15505
+ return [entry.id, entry];
15506
+ }));
15507
+ const reversed = [];
15508
+ const visited = /* @__PURE__ */ new Set();
15509
+ let current = history.leafId;
15510
+ while (current !== null) {
15511
+ if (visited.has(current))
15512
+ throw new Error("Pi history active branch contains a cycle");
15513
+ visited.add(current);
15514
+ const entry = byId.get(current);
15515
+ if (!entry)
15516
+ throw new Error("Pi history active branch references a missing Entry");
15517
+ reversed.push(entry);
15518
+ current = entry.parentId;
15519
+ }
15520
+ return reversed.reverse();
15521
+ }
15522
+ function message(entry) {
15523
+ return entry.type === "message" && isRecord(entry.message) ? entry.message : null;
15524
+ }
15525
+ function messageRole(entry) {
15526
+ const value = message(entry)?.role;
15527
+ return typeof value === "string" ? value : null;
15528
+ }
15529
+ function itemId(entryId, kind, ordinal) {
15530
+ return hostItemIdSchema.parse(`pi-item-v1-${entryId}-${kind}-${ordinal}`);
15531
+ }
15532
+ function assistantOutcome(entries) {
15533
+ const assistants = entries.map((entry) => message(entry)).filter((value) => value?.role === "assistant");
15534
+ const final = assistants.at(-1);
15535
+ if (!final)
15536
+ return { status: "unknown", reason: "Pi history has no Assistant terminal" };
15537
+ const stopReason = final.stopReason;
15538
+ if (stopReason === "aborted") {
15539
+ return { status: "cancelled", reason: "Pi Assistant was aborted" };
15540
+ }
15541
+ if (stopReason === "error") {
15542
+ return {
15543
+ status: "failed",
15544
+ error: {
15545
+ code: "nativeFailure",
15546
+ message: typeof final.errorMessage === "string" && final.errorMessage.length > 0 ? final.errorMessage : "Pi Assistant failed",
15547
+ retryable: false
15548
+ }
15549
+ };
15550
+ }
15551
+ if (typeof stopReason === "string" || textContent(final.content).length > 0) {
15552
+ return { status: "succeeded" };
15553
+ }
15554
+ return { status: "unknown", reason: "Pi Assistant terminal is not classifiable" };
15555
+ }
15556
+ function itemOutcome(outcome) {
15557
+ if (outcome.status === "failed")
15558
+ return { status: "failed", error: outcome.error };
15559
+ if (outcome.status === "cancelled") {
15560
+ return {
15561
+ status: "cancelled",
15562
+ ...outcome.reason ? { reason: outcome.reason } : {}
15563
+ };
15564
+ }
15565
+ return { status: "succeeded" };
15566
+ }
15567
+ function toolOutput(value) {
15568
+ const text = textContent(value);
15569
+ return text.length > 0 ? { content: [{ type: "text", text }] } : void 0;
15570
+ }
15571
+ function snapshotItems(entries, outcome) {
15572
+ const snapshots = [];
15573
+ const toolCalls = /* @__PURE__ */ new Map();
15574
+ for (const entry of entries) {
15575
+ const nativeMessage = message(entry);
15576
+ if (!nativeMessage)
15577
+ continue;
15578
+ const content = Array.isArray(nativeMessage.content) ? nativeMessage.content : [];
15579
+ if (nativeMessage.role === "assistant") {
15580
+ const text = textContent(content);
15581
+ const reasoning = thinkingContent(content);
15582
+ let projectedText = false;
15583
+ let projectedReasoning = false;
15584
+ for (const [ordinal, part] of content.entries()) {
15585
+ if (!isRecord(part))
15586
+ continue;
15587
+ if (part.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
15588
+ const item2 = {
15589
+ type: "reasoning",
15590
+ itemId: itemId(entry.id, "reasoning", 0),
15591
+ text: reasoning
15592
+ };
15593
+ snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
15594
+ projectedReasoning = true;
15595
+ continue;
15596
+ }
15597
+ if (part.type === "text" && !projectedText && text.length > 0) {
15598
+ const item2 = {
15599
+ type: "agentMessage",
15600
+ itemId: itemId(entry.id, "assistant", 0),
15601
+ text
15602
+ };
15603
+ snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
15604
+ projectedText = true;
15605
+ continue;
15606
+ }
15607
+ if (part.type !== "toolCall" || typeof part.id !== "string" || typeof part.name !== "string") {
15608
+ continue;
15609
+ }
15610
+ const parsedArguments = jsonValueSchema.safeParse(part.arguments);
15611
+ if (!parsedArguments.success)
15612
+ continue;
15613
+ toolCalls.set(part.id, {
15614
+ entryId: entry.id,
15615
+ ordinal,
15616
+ name: part.name,
15617
+ arguments: parsedArguments.data
15618
+ });
15619
+ }
15620
+ continue;
15725
15621
  }
15726
- ids.add(command.id);
15622
+ if (nativeMessage.role !== "toolResult" || typeof nativeMessage.toolCallId !== "string" || typeof nativeMessage.toolName !== "string") {
15623
+ continue;
15624
+ }
15625
+ const call = toolCalls.get(nativeMessage.toolCallId);
15626
+ if (!call || call.name !== nativeMessage.toolName)
15627
+ continue;
15628
+ const output = toolOutput(nativeMessage.content);
15629
+ const item = {
15630
+ type: "toolExecution",
15631
+ itemId: itemId(call.entryId, "tool", call.ordinal),
15632
+ toolName: call.name,
15633
+ arguments: call.arguments,
15634
+ ...output ? { output } : {}
15635
+ };
15636
+ const toolSucceeded = nativeMessage.isError === false;
15637
+ snapshots.push({
15638
+ item,
15639
+ outcome: toolSucceeded ? { status: "succeeded" } : {
15640
+ status: "failed",
15641
+ error: {
15642
+ code: "nativeFailure",
15643
+ message: `Pi Tool '${call.name}' failed`,
15644
+ retryable: false
15645
+ }
15646
+ }
15647
+ });
15727
15648
  }
15728
- });
15729
- var harnessCommandsInspectParamsSchema = external_exports.object({ harnessId: harnessIdSchema }).strict();
15730
- var threadCommandsInspectParamsSchema = external_exports.object({
15731
- threadId: hostThreadIdSchema
15732
- }).strict();
15733
- var threadCommandExecuteParamsSchema = external_exports.object({
15734
- threadId: hostThreadIdSchema,
15735
- commandId: commandIdSchema,
15736
- turnId: hostTurnIdSchema.optional(),
15737
- arguments: jsonObjectSchema.optional()
15738
- }).strict();
15739
- var threadCommandExecuteResultSchema = external_exports.object({
15740
- accepted: external_exports.literal(true),
15741
- turnId: hostTurnIdSchema
15742
- }).strict();
15743
-
15744
- // ../../shared-contracts/dist/json-rpc.js
15745
- var jsonRpcVersionSchema = external_exports.literal("2.0").optional();
15746
- var absentSchema = external_exports.never().optional();
15747
- var methodSchema = external_exports.string().min(1);
15748
- var jsonRpcIdSchema = external_exports.union([external_exports.string(), external_exports.number().int()]);
15749
- var jsonRpcErrorSchema = external_exports.object({
15750
- code: external_exports.number().int(),
15751
- message: external_exports.string(),
15752
- data: jsonValueSchema.optional()
15753
- }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["data"]));
15754
- var jsonRpcRequestSchema = external_exports.object({
15755
- jsonrpc: jsonRpcVersionSchema,
15756
- id: jsonRpcIdSchema,
15757
- method: methodSchema,
15758
- params: jsonValueSchema.optional(),
15759
- result: absentSchema,
15760
- error: absentSchema
15761
- }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "params", "result", "error"]));
15762
- var jsonRpcNotificationSchema = external_exports.object({
15763
- jsonrpc: jsonRpcVersionSchema,
15764
- id: absentSchema,
15765
- method: methodSchema,
15766
- params: jsonValueSchema.optional(),
15767
- result: absentSchema,
15768
- error: absentSchema
15769
- }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "id", "params", "result", "error"]));
15770
- var jsonRpcSuccessResponseSchema = external_exports.object({
15771
- jsonrpc: jsonRpcVersionSchema,
15772
- id: jsonRpcIdSchema,
15773
- method: absentSchema,
15774
- params: absentSchema,
15775
- result: jsonValueSchema,
15776
- error: absentSchema
15777
- }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "method", "params", "error"]));
15778
- var jsonRpcErrorResponseSchema = external_exports.object({
15779
- jsonrpc: jsonRpcVersionSchema,
15780
- id: jsonRpcIdSchema,
15781
- method: absentSchema,
15782
- params: absentSchema,
15783
- result: absentSchema,
15784
- error: jsonRpcErrorSchema
15785
- }).catchall(jsonValueSchema).superRefine(rejectExplicitUndefined(["jsonrpc", "method", "params", "result"]));
15786
- var jsonRpcEnvelopeSchema = external_exports.union([
15787
- jsonRpcRequestSchema,
15788
- jsonRpcNotificationSchema,
15789
- jsonRpcSuccessResponseSchema,
15790
- jsonRpcErrorResponseSchema
15791
- ]);
15792
-
15793
- // ../../shared-contracts/dist/native-refs.js
15794
- var nativeIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
15795
- message: "Native identifier must not be empty or whitespace"
15796
- });
15797
- var nativeSessionRefV1RuntimeSchema = external_exports.strictObject({
15798
- harnessId: harnessIdSchema,
15799
- nativeSessionId: nativeIdSchema,
15800
- locator: jsonValueSchema.optional(),
15801
- formatVersion: external_exports.literal(1)
15802
- }).superRefine(rejectExplicitUndefined(["locator"]));
15803
- var nativeSessionRefV1Schema = nativeSessionRefV1RuntimeSchema;
15804
- var nativeSessionRefSchema = nativeSessionRefV1Schema;
15805
- var nativeTurnRefV1Schema = external_exports.strictObject({
15806
- harnessId: harnessIdSchema,
15807
- nativeSessionId: nativeIdSchema,
15808
- nativeTurnKey: nativeIdSchema,
15809
- formatVersion: external_exports.literal(1)
15810
- });
15811
- var nativeTurnRefSchema = nativeTurnRefV1Schema;
15812
- var nativeCheckpointRefV1RuntimeSchema = external_exports.strictObject({
15813
- harnessId: harnessIdSchema,
15814
- nativeSessionId: nativeIdSchema,
15815
- checkpointId: nativeIdSchema,
15816
- locator: jsonValueSchema.optional(),
15817
- formatVersion: external_exports.literal(1)
15818
- }).superRefine(rejectExplicitUndefined(["locator"]));
15819
- var nativeCheckpointRefV1Schema = nativeCheckpointRefV1RuntimeSchema;
15820
- var nativeCheckpointRefSchema = nativeCheckpointRefV1Schema;
15821
-
15822
- // ../../shared-contracts/dist/updates.js
15823
- var UPDATE_ERROR_MAX_LENGTH = 500;
15824
- var UPDATE_SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;
15825
- var updateSemanticVersionSchema = external_exports.string().regex(UPDATE_SEMVER_PATTERN);
15826
- var updateInstallationSchema = external_exports.enum(["npm", "windows-installer", "macos-dmg"]);
15827
- var updatePhaseSchema = external_exports.enum([
15828
- "prepared",
15829
- "downloading",
15830
- "waiting-for-exit",
15831
- "installing",
15832
- "restarting",
15833
- "succeeded",
15834
- "failed"
15835
- ]);
15836
- var updateStatusSchema = external_exports.strictObject({
15837
- version: updateSemanticVersionSchema,
15838
- installation: updateInstallationSchema,
15839
- phase: updatePhaseSchema,
15840
- updatedAt: external_exports.number().int().nonnegative(),
15841
- downloadedBytes: external_exports.number().int().nonnegative().optional(),
15842
- totalBytes: external_exports.number().int().positive().optional(),
15843
- error: external_exports.string().min(1).max(UPDATE_ERROR_MAX_LENGTH).nullable()
15844
- }).superRefine((status, context) => {
15845
- if (status.downloadedBytes !== void 0 && status.totalBytes !== void 0 && status.downloadedBytes > status.totalBytes) {
15846
- context.addIssue({
15847
- code: "custom",
15848
- path: ["downloadedBytes"],
15849
- message: "downloadedBytes must not exceed totalBytes"
15649
+ return snapshots;
15650
+ }
15651
+ function modelChange(entry) {
15652
+ return entry.type === "model_change" && typeof entry.provider === "string" && typeof entry.modelId === "string" ? { provider: entry.provider, id: entry.modelId } : null;
15653
+ }
15654
+ function mapPiSnapshot(history, state) {
15655
+ const active = activePiEntries(history);
15656
+ const turns = [];
15657
+ let effectiveModel = state.model;
15658
+ for (let index = 0; index < active.length; ) {
15659
+ const model = modelChange(active[index]);
15660
+ if (model) {
15661
+ effectiveModel = model;
15662
+ index += 1;
15663
+ continue;
15664
+ }
15665
+ const user = active[index];
15666
+ if (messageRole(user) !== "user") {
15667
+ index += 1;
15668
+ continue;
15669
+ }
15670
+ let end = index + 1;
15671
+ while (end < active.length && messageRole(active[end]) !== "user")
15672
+ end += 1;
15673
+ const entries = active.slice(index, end);
15674
+ const outcome = assistantOutcome(entries);
15675
+ const userText = textContent(message(user)?.content);
15676
+ const nativeTurnRef = nativeTurnRefSchema.parse({
15677
+ harnessId: piHarnessId,
15678
+ nativeSessionId: state.sessionId,
15679
+ nativeTurnKey: user.id,
15680
+ formatVersion: 1
15681
+ });
15682
+ const checkpoint = nativeCheckpointRefSchema.parse({
15683
+ harnessId: piHarnessId,
15684
+ nativeSessionId: state.sessionId,
15685
+ checkpointId: user.id,
15686
+ formatVersion: 1
15687
+ });
15688
+ turns.push({
15689
+ nativeTurnRef,
15690
+ checkpoint,
15691
+ input: [{ type: "text", text: userText }],
15692
+ items: snapshotItems(entries, outcome),
15693
+ outcome,
15694
+ ...effectiveModel ? { model: encodePiModelRef(effectiveModel) } : {}
15850
15695
  });
15696
+ for (const entry of entries) {
15697
+ const changed = modelChange(entry);
15698
+ if (changed)
15699
+ effectiveModel = changed;
15700
+ }
15701
+ index = end;
15851
15702
  }
15852
- });
15853
- var updateEmptyParamsSchema = external_exports.strictObject({});
15854
- var githubReleaseNotesUrlSchema = external_exports.string().max(300).regex(/^https:\/\/github\.com\/BytePioneer-AI\/codex-host\/releases\/tag\/v[0-9A-Za-z.+-]+$/u, "release notes URL must identify a codexhost GitHub Release");
15855
- var updateCheckResultSchema = external_exports.strictObject({
15856
- currentVersion: updateSemanticVersionSchema,
15857
- installation: updateInstallationSchema.nullable(),
15858
- latestVersion: updateSemanticVersionSchema.nullable(),
15859
- updateAvailable: external_exports.boolean(),
15860
- installationAvailable: external_exports.boolean(),
15861
- releaseNotes: external_exports.string().min(1).max(2e4).nullable(),
15862
- releaseNotesUrl: githubReleaseNotesUrlSchema.nullable(),
15863
- status: updateStatusSchema.nullable(),
15864
- error: external_exports.string().min(1).max(UPDATE_ERROR_MAX_LENGTH).nullable()
15865
- });
15866
- var updateStartResultSchema = external_exports.strictObject({
15867
- status: updateStatusSchema
15868
- });
15869
- var updateStatusResultSchema = external_exports.strictObject({
15870
- status: updateStatusSchema.nullable()
15871
- });
15703
+ return { turns };
15704
+ }
15705
+ function resolvePiLastTurnBoundary(history) {
15706
+ const users = activePiEntries(history).filter((entry) => messageRole(entry) === "user");
15707
+ const last = users.at(-1);
15708
+ return last ? { lastUserEntryId: last.id, sourceTurnCount: users.length } : null;
15709
+ }
15710
+ function resolvePiForkBoundary(history, checkpointId) {
15711
+ const active = activePiEntries(history);
15712
+ const users = active.filter((entry) => messageRole(entry) === "user");
15713
+ const targetTurnIndex = users.findIndex((entry) => entry.id === checkpointId);
15714
+ if (targetTurnIndex < 0)
15715
+ throw new Error("Pi Checkpoint is not on the active branch");
15716
+ return {
15717
+ targetTurnIndex,
15718
+ nextUserEntryId: users[targetTurnIndex + 1]?.id ?? null
15719
+ };
15720
+ }
15872
15721
 
15873
- // ../../shared-contracts/dist/index.js
15874
- var workspaceContractVersionSchema = external_exports.literal(WORKSPACE_CONTRACT_VERSION);
15722
+ // dist/pi-session-file.js
15723
+ import { open, realpath } from "node:fs/promises";
15724
+ var MAX_SESSION_HEADER_BYTES = 64 * 1024;
15725
+ var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
15726
+ function isRecord2(value) {
15727
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15728
+ }
15729
+ async function readPiSessionHeader(sessionFile) {
15730
+ const handle = await open(sessionFile, "r");
15731
+ try {
15732
+ const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
15733
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
15734
+ const contents = buffer.subarray(0, bytesRead);
15735
+ const newline = contents.indexOf(10);
15736
+ if (newline < 0 && bytesRead === buffer.length) {
15737
+ throw new Error("Pi Session header exceeds the supported size");
15738
+ }
15739
+ const headerText = utf8Decoder.decode(newline < 0 ? contents : contents.subarray(0, newline));
15740
+ let parsed;
15741
+ try {
15742
+ parsed = JSON.parse(headerText);
15743
+ } catch {
15744
+ throw new Error("Pi Session header is not valid JSON");
15745
+ }
15746
+ if (!isRecord2(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
15747
+ throw new Error("Pi Session header is invalid");
15748
+ }
15749
+ return {
15750
+ type: "session",
15751
+ id: parsed.id,
15752
+ cwd: parsed.cwd,
15753
+ ...typeof parsed.version === "number" ? { version: parsed.version } : {}
15754
+ };
15755
+ } finally {
15756
+ await handle.close();
15757
+ }
15758
+ }
15759
+ async function verifyPiSessionCwd(input) {
15760
+ if (!input.sessionFile)
15761
+ throw new Error("Pi Fork Session has no persisted Session file");
15762
+ const header = await readPiSessionHeader(input.sessionFile);
15763
+ if (header.id !== input.sessionId) {
15764
+ throw new Error("Pi Fork Session header identity does not match RPC state");
15765
+ }
15766
+ const [actualCwd, expectedCwd] = await Promise.all([
15767
+ realpath(header.cwd),
15768
+ realpath(input.expectedCwd)
15769
+ ]);
15770
+ if (actualCwd !== expectedCwd) {
15771
+ throw new Error("Pi Fork Session did not bind the requested cwd");
15772
+ }
15773
+ }
15875
15774
 
15876
- // ../../harness-adapter/dist/question.js
15877
- function invalidRequest(message3) {
15878
- return { code: "invalidRequest", message: message3, retryable: false };
15775
+ // dist/pi-empty-session.js
15776
+ async function persistEmptyPiSession(input) {
15777
+ const { state, history, sourceSessionFile, sourceSessionId, cwd } = input;
15778
+ const destination = state.sessionFile;
15779
+ if (!destination || !path.isAbsolute(destination) || path.resolve(destination) === path.resolve(sourceSessionFile) || state.sessionId === sourceSessionId || mapPiSnapshot(history, { sessionId: state.sessionId, model: null }).turns.length !== 0)
15780
+ throw new Error("Pi empty Session is not an independent empty native fork");
15781
+ await verifyPiSessionCwd({
15782
+ sessionFile: sourceSessionFile,
15783
+ sessionId: sourceSessionId,
15784
+ expectedCwd: cwd
15785
+ });
15786
+ const sourceHeader = await readPiSessionHeader(sourceSessionFile);
15787
+ if (sourceHeader.type !== "session" || sourceHeader.version !== 3) {
15788
+ throw new Error("Pi empty Session persistence requires native v3 history");
15789
+ }
15790
+ const entries = history.entries;
15791
+ const active = activePiEntries(history);
15792
+ if (active.length !== entries.length || active.some((entry, index) => entry.id !== entries[index]?.id)) {
15793
+ throw new Error("Pi empty Session must expose its complete active branch");
15794
+ }
15795
+ const header = {
15796
+ type: "session",
15797
+ version: 3,
15798
+ id: state.sessionId,
15799
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15800
+ cwd,
15801
+ parentSession: sourceSessionFile
15802
+ };
15803
+ const temporary = path.join(path.dirname(destination), `.codexhost-${randomUUID()}.tmp`);
15804
+ try {
15805
+ const file2 = await open2(temporary, "wx", 384);
15806
+ try {
15807
+ await file2.writeFile([header, ...entries].map((entry) => JSON.stringify(entry)).join("\n") + "\n");
15808
+ await file2.sync();
15809
+ } finally {
15810
+ await file2.close();
15811
+ }
15812
+ await link(temporary, destination);
15813
+ if (process.platform !== "win32") {
15814
+ const directory = await open2(path.dirname(destination), "r");
15815
+ try {
15816
+ await directory.sync();
15817
+ } finally {
15818
+ await directory.close();
15819
+ }
15820
+ }
15821
+ } finally {
15822
+ await rm(temporary, { force: true });
15823
+ }
15879
15824
  }
15880
- function validateHostQuestionResponse(interaction, response) {
15881
- const questionIds = new Set(interaction.questions.map(({ id }) => id));
15882
- if (response.cancelled) {
15883
- return Object.keys(response.answers).length === 0 ? null : invalidRequest("Cancelled Question Response must not contain answers");
15825
+ async function readPiEmptySessionConfiguration(sessionFile) {
15826
+ let header;
15827
+ try {
15828
+ header = await readPiSessionHeader(sessionFile);
15829
+ } catch (error51) {
15830
+ if (error51.code === "ENOENT")
15831
+ return void 0;
15832
+ throw error51;
15884
15833
  }
15885
- for (const answerId of Object.keys(response.answers)) {
15886
- if (!questionIds.has(answerId)) {
15887
- return invalidRequest("Question Response contains an unknown Question ID");
15834
+ if (header.version !== 3)
15835
+ return void 0;
15836
+ const stream = createReadStream(sessionFile, { encoding: "utf8" });
15837
+ const lines = createInterface({ input: stream, crlfDelay: Infinity });
15838
+ let readFailure;
15839
+ stream.on("error", (error51) => {
15840
+ readFailure = error51;
15841
+ lines.close();
15842
+ });
15843
+ let model;
15844
+ let thinkingLevel;
15845
+ let previous = null;
15846
+ let first = true;
15847
+ try {
15848
+ for await (const line of lines) {
15849
+ if (first) {
15850
+ first = false;
15851
+ continue;
15852
+ }
15853
+ if (!line.trim())
15854
+ continue;
15855
+ const entry = jsonValueSchema.parse(JSON.parse(line));
15856
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
15857
+ return void 0;
15858
+ if (entry.type === "message" || typeof entry.id !== "string" || entry.parentId !== previous)
15859
+ return void 0;
15860
+ previous = entry.id;
15861
+ if (entry.type === "model_change" && typeof entry.provider === "string" && typeof entry.modelId === "string") {
15862
+ model = { provider: entry.provider, id: entry.modelId };
15863
+ }
15864
+ if (entry.type === "thinking_level_change") {
15865
+ thinkingLevel = harnessThinkingOptionIdSchema.parse(entry.thinkingLevel);
15866
+ }
15888
15867
  }
15868
+ } finally {
15869
+ lines.close();
15870
+ stream.destroy();
15889
15871
  }
15890
- for (const question of interaction.questions) {
15891
- const answers = response.answers[question.id] ?? [];
15892
- if (!question.optional && answers.length === 0) {
15893
- return invalidRequest("Question Response omits a required answer");
15872
+ if (readFailure)
15873
+ throw readFailure;
15874
+ return model && thinkingLevel ? { model, thinkingLevel } : void 0;
15875
+ }
15876
+
15877
+ // ../../../node_modules/diff/libesm/diff/base.js
15878
+ var Diff = class {
15879
+ diff(oldStr, newStr, options = {}) {
15880
+ let callback;
15881
+ if (typeof options === "function") {
15882
+ callback = options;
15883
+ options = {};
15884
+ } else if ("callback" in options) {
15885
+ callback = options.callback;
15886
+ }
15887
+ const oldString = this.castInput(oldStr, options);
15888
+ const newString = this.castInput(newStr, options);
15889
+ const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
15890
+ const newTokens = this.removeEmpty(this.tokenize(newString, options));
15891
+ return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
15892
+ }
15893
+ diffWithOptionsObj(oldTokens, newTokens, options, callback) {
15894
+ var _a3;
15895
+ const done = (value) => {
15896
+ value = this.postProcess(value, options);
15897
+ if (callback) {
15898
+ setTimeout(function() {
15899
+ callback(value);
15900
+ }, 0);
15901
+ return void 0;
15902
+ } else {
15903
+ return value;
15904
+ }
15905
+ };
15906
+ const newLen = newTokens.length, oldLen = oldTokens.length;
15907
+ let editLength = 1;
15908
+ let maxEditLength = newLen + oldLen;
15909
+ if (options.maxEditLength != null) {
15910
+ maxEditLength = Math.min(maxEditLength, options.maxEditLength);
15911
+ }
15912
+ const maxExecutionTime = (_a3 = options.timeout) !== null && _a3 !== void 0 ? _a3 : Infinity;
15913
+ const abortAfterTimestamp = Date.now() + maxExecutionTime;
15914
+ const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
15915
+ let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
15916
+ if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
15917
+ return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
15918
+ }
15919
+ let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
15920
+ const execEditLength = () => {
15921
+ for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
15922
+ let basePath;
15923
+ const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
15924
+ if (removePath) {
15925
+ bestPath[diagonalPath - 1] = void 0;
15926
+ }
15927
+ let canAdd = false;
15928
+ if (addPath) {
15929
+ const addPathNewPos = addPath.oldPos - diagonalPath;
15930
+ canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
15931
+ }
15932
+ const canRemove = removePath && removePath.oldPos + 1 < oldLen;
15933
+ if (!canAdd && !canRemove) {
15934
+ bestPath[diagonalPath] = void 0;
15935
+ continue;
15936
+ }
15937
+ if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
15938
+ basePath = this.addToPath(addPath, true, false, 0, options);
15939
+ } else {
15940
+ basePath = this.addToPath(removePath, false, true, 1, options);
15941
+ }
15942
+ newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
15943
+ if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
15944
+ return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
15945
+ } else {
15946
+ bestPath[diagonalPath] = basePath;
15947
+ if (basePath.oldPos + 1 >= oldLen) {
15948
+ maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
15949
+ }
15950
+ if (newPos + 1 >= newLen) {
15951
+ minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
15952
+ }
15953
+ }
15954
+ }
15955
+ editLength++;
15956
+ };
15957
+ if (callback) {
15958
+ (function exec() {
15959
+ setTimeout(function() {
15960
+ if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
15961
+ return callback(void 0);
15962
+ }
15963
+ if (!execEditLength()) {
15964
+ exec();
15965
+ }
15966
+ }, 0);
15967
+ })();
15968
+ } else {
15969
+ while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
15970
+ const ret = execEditLength();
15971
+ if (ret) {
15972
+ return ret;
15973
+ }
15974
+ }
15975
+ }
15976
+ }
15977
+ addToPath(path7, added, removed, oldPosInc, options) {
15978
+ const last = path7.lastComponent;
15979
+ if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
15980
+ return {
15981
+ oldPos: path7.oldPos + oldPosInc,
15982
+ lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
15983
+ };
15984
+ } else {
15985
+ return {
15986
+ oldPos: path7.oldPos + oldPosInc,
15987
+ lastComponent: { count: 1, added, removed, previousComponent: last }
15988
+ };
15989
+ }
15990
+ }
15991
+ extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
15992
+ const newLen = newTokens.length, oldLen = oldTokens.length;
15993
+ let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
15994
+ while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
15995
+ newPos++;
15996
+ oldPos++;
15997
+ commonCount++;
15998
+ if (options.oneChangePerToken) {
15999
+ basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
16000
+ }
16001
+ }
16002
+ if (commonCount && !options.oneChangePerToken) {
16003
+ basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
16004
+ }
16005
+ basePath.oldPos = oldPos;
16006
+ return newPos;
16007
+ }
16008
+ equals(left, right, options) {
16009
+ if (options.comparator) {
16010
+ return options.comparator(left, right);
16011
+ } else {
16012
+ return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
16013
+ }
16014
+ }
16015
+ removeEmpty(array2) {
16016
+ const ret = [];
16017
+ for (let i = 0; i < array2.length; i++) {
16018
+ if (array2[i]) {
16019
+ ret.push(array2[i]);
16020
+ }
16021
+ }
16022
+ return ret;
16023
+ }
16024
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
16025
+ castInput(value, options) {
16026
+ return value;
16027
+ }
16028
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
16029
+ tokenize(value, options) {
16030
+ return Array.from(value);
16031
+ }
16032
+ join(chars) {
16033
+ return chars.join("");
16034
+ }
16035
+ postProcess(changeObjects, options) {
16036
+ return changeObjects;
16037
+ }
16038
+ get useLongestToken() {
16039
+ return false;
16040
+ }
16041
+ buildValues(lastComponent, newTokens, oldTokens) {
16042
+ const components = [];
16043
+ let nextComponent;
16044
+ while (lastComponent) {
16045
+ components.push(lastComponent);
16046
+ nextComponent = lastComponent.previousComponent;
16047
+ delete lastComponent.previousComponent;
16048
+ lastComponent = nextComponent;
15894
16049
  }
15895
- if (question.type === "text") {
15896
- if (answers.length > 1) {
15897
- return invalidRequest("Text Question accepts at most one answer");
16050
+ components.reverse();
16051
+ const componentLen = components.length;
16052
+ let componentPos = 0, newPos = 0, oldPos = 0;
16053
+ for (; componentPos < componentLen; componentPos++) {
16054
+ const component = components[componentPos];
16055
+ if (!component.removed) {
16056
+ if (!component.added && this.useLongestToken) {
16057
+ let value = newTokens.slice(newPos, newPos + component.count);
16058
+ value = value.map(function(value2, i) {
16059
+ const oldValue = oldTokens[oldPos + i];
16060
+ return oldValue.length > value2.length ? oldValue : value2;
16061
+ });
16062
+ component.value = this.join(value);
16063
+ } else {
16064
+ component.value = this.join(newTokens.slice(newPos, newPos + component.count));
16065
+ }
16066
+ newPos += component.count;
16067
+ if (!component.added) {
16068
+ oldPos += component.count;
16069
+ }
16070
+ } else {
16071
+ component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
16072
+ oldPos += component.count;
15898
16073
  }
15899
- continue;
15900
- }
15901
- if (!question.multiple && answers.length > 1) {
15902
- return invalidRequest("Single-choice Question accepts at most one answer");
15903
- }
15904
- const declared = new Set(question.options.map(({ value }) => value));
15905
- if (!question.allowOther && answers.some((answer) => !declared.has(answer))) {
15906
- return invalidRequest("Question Response contains an undeclared choice");
15907
16074
  }
16075
+ return components;
15908
16076
  }
15909
- return null;
15910
- }
16077
+ };
15911
16078
 
15912
- // ../../harness-adapter/dist/output-channel.js
15913
- var HarnessOutputChannel = class {
15914
- outputs;
15915
- #consumerCreated = false;
15916
- #ended = false;
15917
- #pending = [];
15918
- #values = [];
16079
+ // ../../../node_modules/diff/libesm/diff/line.js
16080
+ var LineDiff = class extends Diff {
15919
16081
  constructor() {
15920
- this.outputs = {
15921
- [Symbol.asyncIterator]: () => {
15922
- if (this.#consumerCreated) {
15923
- throw new Error("Harness outputs allow only one consumer");
15924
- }
15925
- this.#consumerCreated = true;
15926
- return {
15927
- next: () => this.#next()
15928
- };
16082
+ super(...arguments);
16083
+ this.tokenize = tokenize;
16084
+ }
16085
+ equals(left, right, options) {
16086
+ if (options.ignoreWhitespace) {
16087
+ if (!options.newlineIsToken || !left.includes("\n")) {
16088
+ left = left.trim();
15929
16089
  }
15930
- };
16090
+ if (!options.newlineIsToken || !right.includes("\n")) {
16091
+ right = right.trim();
16092
+ }
16093
+ } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
16094
+ if (left.endsWith("\n")) {
16095
+ left = left.slice(0, -1);
16096
+ }
16097
+ if (right.endsWith("\n")) {
16098
+ right = right.slice(0, -1);
16099
+ }
16100
+ }
16101
+ return super.equals(left, right, options);
15931
16102
  }
15932
- emit(value) {
15933
- if (this.#ended)
15934
- return false;
15935
- const resolve = this.#pending.shift();
15936
- if (resolve)
15937
- resolve({ done: false, value });
15938
- else
15939
- this.#values.push(value);
15940
- return true;
16103
+ };
16104
+ var lineDiff = new LineDiff();
16105
+ function diffLines(oldStr, newStr, options) {
16106
+ return lineDiff.diff(oldStr, newStr, options);
16107
+ }
16108
+ function tokenize(value, options) {
16109
+ if (options.stripTrailingCr) {
16110
+ value = value.replace(/\r\n/g, "\n");
15941
16111
  }
15942
- end() {
15943
- if (this.#ended)
15944
- return;
15945
- this.#ended = true;
15946
- if (this.#values.length !== 0)
15947
- return;
15948
- for (const resolve of this.#pending.splice(0))
15949
- resolve({ done: true, value: void 0 });
16112
+ const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
16113
+ if (!linesAndNewlines[linesAndNewlines.length - 1]) {
16114
+ linesAndNewlines.pop();
15950
16115
  }
15951
- #next() {
15952
- const value = this.#values.shift();
15953
- if (value !== void 0)
15954
- return Promise.resolve({ done: false, value });
15955
- if (this.#ended)
15956
- return Promise.resolve({ done: true, value: void 0 });
15957
- return new Promise((resolve) => this.#pending.push(resolve));
16116
+ for (let i = 0; i < linesAndNewlines.length; i++) {
16117
+ const line = linesAndNewlines[i];
16118
+ if (i % 2 && !options.newlineIsToken) {
16119
+ retLines[retLines.length - 1] += line;
16120
+ } else {
16121
+ retLines.push(line);
16122
+ }
15958
16123
  }
15959
- };
15960
-
15961
- // ../../harness-adapter/dist/diagnostics.js
15962
- var DIAGNOSTIC_TAIL_MAX_LENGTH = 8e3;
15963
- var SENSITIVE_VALUE_PATTERN = /(api[_-]?key|access[_-]?token|auth(?:orization)?|password|secret)(\s*[:=]\s*)([^\s,;]+)/giu;
15964
- var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/giu;
15965
- function sanitizeDiagnosticTail(value) {
15966
- const redacted = value.replace(BEARER_PATTERN, "Bearer [redacted]").replace(SENSITIVE_VALUE_PATTERN, "$1$2[redacted]");
15967
- return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
16124
+ return retLines;
15968
16125
  }
15969
16126
 
15970
- // ../../harness-adapter/dist/usage.js
15971
- var tokenFields = [
15972
- "inputTokens",
15973
- "cachedInputTokens",
15974
- "cacheWriteInputTokens",
15975
- "outputTokens",
15976
- "outputTokensPerSecond",
15977
- "reasoningOutputTokens",
15978
- "totalTokens",
15979
- "contextWindowTokens",
15980
- "contextUsedTokens"
15981
- ];
15982
- var safeIntegerFields = [
15983
- "planFiveHourResetsAtUnix",
15984
- "planSevenDayResetsAtUnix"
15985
- ];
15986
- var percentFields = [
15987
- "cacheHitRatePercent",
15988
- "planFiveHourUsedPercent",
15989
- "planSevenDayUsedPercent"
15990
- ];
15991
- var usageFields = /* @__PURE__ */ new Set([
15992
- ...tokenFields,
15993
- ...safeIntegerFields,
15994
- ...percentFields,
15995
- "totalCostUsd"
15996
- ]);
15997
- function isRecord(value) {
15998
- return typeof value === "object" && value !== null && !Array.isArray(value);
15999
- }
16000
- function parseHostUsage(value) {
16001
- if (!isRecord(value))
16002
- throw new Error("Harness Usage must be an object");
16003
- const keys = Object.keys(value);
16004
- if (keys.length === 0)
16005
- throw new Error("Harness Usage must contain a reliable field");
16006
- for (const key of keys) {
16007
- if (!usageFields.has(key)) {
16008
- throw new Error(`Harness Usage contains unknown field '${key}'`);
16127
+ // ../../../node_modules/diff/libesm/patch/parse.js
16128
+ function parsePatch(uniDiff) {
16129
+ const diffstr = uniDiff.split(/\n/), list = [];
16130
+ let i = 0;
16131
+ function parseIndex() {
16132
+ const index = {};
16133
+ list.push(index);
16134
+ while (i < diffstr.length) {
16135
+ const line = diffstr[i];
16136
+ if (/^(---|\+\+\+|@@)\s/.test(line)) {
16137
+ break;
16138
+ }
16139
+ const header = /^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/.exec(line);
16140
+ if (header) {
16141
+ index.index = header[1];
16142
+ }
16143
+ i++;
16144
+ }
16145
+ parseFileHeader(index);
16146
+ parseFileHeader(index);
16147
+ index.hunks = [];
16148
+ while (i < diffstr.length) {
16149
+ const line = diffstr[i];
16150
+ if (/^(Index:\s|diff\s|---\s|\+\+\+\s|===================================================================)/.test(line)) {
16151
+ break;
16152
+ } else if (/^@@/.test(line)) {
16153
+ index.hunks.push(parseHunk());
16154
+ } else if (line) {
16155
+ throw new Error("Unknown line " + (i + 1) + " " + JSON.stringify(line));
16156
+ } else {
16157
+ i++;
16158
+ }
16159
+ }
16160
+ }
16161
+ function parseFileHeader(index) {
16162
+ const fileHeader = /^(---|\+\+\+)\s+(.*)\r?$/.exec(diffstr[i]);
16163
+ if (fileHeader) {
16164
+ const data = fileHeader[2].split(" ", 2), header = (data[1] || "").trim();
16165
+ let fileName = data[0].replace(/\\\\/g, "\\");
16166
+ if (/^".*"$/.test(fileName)) {
16167
+ fileName = fileName.substr(1, fileName.length - 2);
16168
+ }
16169
+ if (fileHeader[1] === "---") {
16170
+ index.oldFileName = fileName;
16171
+ index.oldHeader = header;
16172
+ } else {
16173
+ index.newFileName = fileName;
16174
+ index.newHeader = header;
16175
+ }
16176
+ i++;
16177
+ }
16178
+ }
16179
+ function parseHunk() {
16180
+ var _a3;
16181
+ const chunkHeaderIndex = i, chunkHeaderLine = diffstr[i++], chunkHeader = chunkHeaderLine.split(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
16182
+ const hunk = {
16183
+ oldStart: +chunkHeader[1],
16184
+ oldLines: typeof chunkHeader[2] === "undefined" ? 1 : +chunkHeader[2],
16185
+ newStart: +chunkHeader[3],
16186
+ newLines: typeof chunkHeader[4] === "undefined" ? 1 : +chunkHeader[4],
16187
+ lines: []
16188
+ };
16189
+ if (hunk.oldLines === 0) {
16190
+ hunk.oldStart += 1;
16191
+ }
16192
+ if (hunk.newLines === 0) {
16193
+ hunk.newStart += 1;
16194
+ }
16195
+ let addCount = 0, removeCount = 0;
16196
+ for (; i < diffstr.length && (removeCount < hunk.oldLines || addCount < hunk.newLines || ((_a3 = diffstr[i]) === null || _a3 === void 0 ? void 0 : _a3.startsWith("\\"))); i++) {
16197
+ const operation = diffstr[i].length == 0 && i != diffstr.length - 1 ? " " : diffstr[i][0];
16198
+ if (operation === "+" || operation === "-" || operation === " " || operation === "\\") {
16199
+ hunk.lines.push(diffstr[i]);
16200
+ if (operation === "+") {
16201
+ addCount++;
16202
+ } else if (operation === "-") {
16203
+ removeCount++;
16204
+ } else if (operation === " ") {
16205
+ addCount++;
16206
+ removeCount++;
16207
+ }
16208
+ } else {
16209
+ throw new Error(`Hunk at line ${chunkHeaderIndex + 1} contained invalid line ${diffstr[i]}`);
16210
+ }
16009
16211
  }
16010
- }
16011
- for (const field of tokenFields) {
16012
- const candidate = value[field];
16013
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16014
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16212
+ if (!addCount && hunk.newLines === 1) {
16213
+ hunk.newLines = 0;
16015
16214
  }
16016
- }
16017
- for (const field of safeIntegerFields) {
16018
- const candidate = value[field];
16019
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16020
- throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16215
+ if (!removeCount && hunk.oldLines === 1) {
16216
+ hunk.oldLines = 0;
16021
16217
  }
16022
- }
16023
- if (value.outputTokensPerSecond !== void 0 && (typeof value.outputTokensPerSecond !== "number" || !Number.isFinite(value.outputTokensPerSecond) || value.outputTokensPerSecond < 0)) {
16024
- throw new Error("Harness Usage 'outputTokensPerSecond' must be a finite non-negative number");
16025
- }
16026
- if (value.totalCostUsd !== void 0 && (typeof value.totalCostUsd !== "number" || !Number.isFinite(value.totalCostUsd) || value.totalCostUsd < 0)) {
16027
- throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
16028
- }
16029
- for (const field of percentFields) {
16030
- const candidate = value[field];
16031
- if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
16032
- throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
16218
+ if (addCount !== hunk.newLines) {
16219
+ throw new Error("Added line count did not match for hunk at line " + (chunkHeaderIndex + 1));
16033
16220
  }
16221
+ if (removeCount !== hunk.oldLines) {
16222
+ throw new Error("Removed line count did not match for hunk at line " + (chunkHeaderIndex + 1));
16223
+ }
16224
+ return hunk;
16034
16225
  }
16035
- const hasContextUsed = value.contextUsedTokens !== void 0;
16036
- const hasContextWindow = value.contextWindowTokens !== void 0;
16037
- if (hasContextUsed !== hasContextWindow) {
16038
- throw new Error("Harness Usage context fields must be provided together");
16039
- }
16040
- if (hasContextWindow && value.contextWindowTokens === 0) {
16041
- throw new Error("Harness Usage 'contextWindowTokens' must be greater than zero");
16042
- }
16043
- if (value.planFiveHourResetsAtUnix !== void 0 && value.planFiveHourUsedPercent === void 0) {
16044
- throw new Error("Harness Usage 'planFiveHourResetsAtUnix' must be provided with 'planFiveHourUsedPercent'");
16045
- }
16046
- if (value.planSevenDayResetsAtUnix !== void 0 && value.planSevenDayUsedPercent === void 0) {
16047
- throw new Error("Harness Usage 'planSevenDayResetsAtUnix' must be provided with 'planSevenDayUsedPercent'");
16226
+ while (i < diffstr.length) {
16227
+ parseIndex();
16048
16228
  }
16049
- return { ...value };
16229
+ return list;
16050
16230
  }
16051
16231
 
16052
- // dist/pi-model-catalog.js
16053
- var PI_MODEL_REF_PREFIX = "pi-model-v1.";
16054
- var PI_DRAFT_THINKING_OPTION_IDS = [
16055
- "off",
16056
- "minimal",
16057
- "low",
16058
- "medium",
16059
- "high",
16060
- "xhigh",
16061
- "max"
16062
- ].map((id) => harnessThinkingOptionIdSchema.parse(id));
16063
- var PI_THINKING_LABELS = {
16064
- off: "Off",
16065
- minimal: "Minimal",
16066
- low: "Low",
16067
- medium: "Medium",
16068
- high: "High",
16069
- xhigh: "Extra High",
16070
- max: "Max"
16071
- };
16072
- function compareText(left, right) {
16073
- return left < right ? -1 : left > right ? 1 : 0;
16074
- }
16075
- function assertNativePart(value, name) {
16076
- if (value.trim().length === 0)
16077
- throw new Error(`Pi ${name} must not be empty`);
16078
- }
16079
- function encodePiModelRef(model) {
16080
- assertNativePart(model.provider, "Model provider");
16081
- assertNativePart(model.id, "Model id");
16082
- const encoded = Buffer.from(JSON.stringify([model.provider, model.id]), "utf8").toString("base64url");
16083
- return harnessModelRefSchema.parse({ id: `${PI_MODEL_REF_PREFIX}${encoded}` });
16084
- }
16085
- function decodePiModelRef(ref) {
16086
- const parsedRef = harnessModelRefSchema.parse(ref);
16087
- if (!parsedRef.id.startsWith(PI_MODEL_REF_PREFIX)) {
16088
- throw new Error("Model Ref does not belong to PiAdapter");
16232
+ // ../../../node_modules/diff/libesm/patch/create.js
16233
+ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
16234
+ let optionsObj;
16235
+ if (!options) {
16236
+ optionsObj = {};
16237
+ } else if (typeof options === "function") {
16238
+ optionsObj = { callback: options };
16239
+ } else {
16240
+ optionsObj = options;
16089
16241
  }
16090
- const encoded = parsedRef.id.slice(PI_MODEL_REF_PREFIX.length);
16091
- let decoded;
16092
- try {
16093
- decoded = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
16094
- } catch {
16095
- throw new Error("Pi Model Ref is malformed");
16242
+ if (typeof optionsObj.context === "undefined") {
16243
+ optionsObj.context = 4;
16096
16244
  }
16097
- if (!Array.isArray(decoded) || decoded.length !== 2 || typeof decoded[0] !== "string" || typeof decoded[1] !== "string") {
16098
- throw new Error("Pi Model Ref has an invalid native identity");
16245
+ const context = optionsObj.context;
16246
+ if (optionsObj.newlineIsToken) {
16247
+ throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
16099
16248
  }
16100
- const native = { provider: decoded[0], id: decoded[1] };
16101
- assertNativePart(native.provider, "Model provider");
16102
- assertNativePart(native.id, "Model id");
16103
- if (encodePiModelRef(native).id !== parsedRef.id) {
16104
- throw new Error("Pi Model Ref is not canonical");
16249
+ if (!optionsObj.callback) {
16250
+ return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
16251
+ } else {
16252
+ const { callback } = optionsObj;
16253
+ diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
16254
+ const patch = diffLinesResultToPatch(diff);
16255
+ callback(patch);
16256
+ } }));
16105
16257
  }
16106
- return native;
16107
- }
16108
- function samePiModel(left, right) {
16109
- return left === null ? right === null : right !== null && left.provider === right.provider && left.id === right.id;
16110
- }
16111
- function fallbackThinkingLabel(id) {
16112
- const label = id.split(/[._~-]+/u).filter((part) => part.length > 0).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
16113
- return label || id;
16114
- }
16115
- function normalizePiThinkingOptions(levels) {
16116
- return levels.map((id) => harnessThinkingOptionSchema.parse({
16117
- id,
16118
- label: PI_THINKING_LABELS[id] ?? fallbackThinkingLabel(id)
16119
- }));
16120
- }
16121
- function normalizePiModelCatalog(nativeModels, effectiveModel, thinkingLevels, effectiveThinkingOptionId) {
16122
- const byRef = /* @__PURE__ */ new Map();
16123
- for (const native of nativeModels) {
16124
- const ref = encodePiModelRef(native);
16125
- const existing = byRef.get(ref.id);
16126
- if (existing) {
16127
- if (existing.reasoning !== native.reasoning) {
16128
- throw new Error("Pi duplicate Model entries disagree on reasoning capability");
16129
- }
16130
- continue;
16258
+ function diffLinesResultToPatch(diff) {
16259
+ if (!diff) {
16260
+ return;
16131
16261
  }
16132
- byRef.set(ref.id, {
16133
- model: {
16134
- ref,
16135
- label: `${native.provider} / ${native.id}`
16136
- },
16137
- reasoning: native.reasoning
16138
- });
16139
- }
16140
- const defaultModel = effectiveModel ? encodePiModelRef(effectiveModel) : void 0;
16141
- if (defaultModel && !byRef.has(defaultModel.id)) {
16142
- throw new Error("Pi effective Model is absent from the available Model catalog");
16143
- }
16144
- if (thinkingLevels && effectiveThinkingOptionId && !thinkingLevels.includes(effectiveThinkingOptionId)) {
16145
- throw new Error("Pi effective Thinking option is absent from the available option catalog");
16146
- }
16147
- if (thinkingLevels && !effectiveThinkingOptionId) {
16148
- throw new Error("Pi did not report an effective Thinking option");
16149
- }
16150
- const thinkingOptions = thinkingLevels ? normalizePiThinkingOptions(PI_DRAFT_THINKING_OPTION_IDS) : [];
16151
- const allThinkingOptionIds = thinkingOptions.map(({ id }) => id);
16152
- const offThinkingOptionId = thinkingOptions.find(({ id }) => id === "off")?.id;
16153
- const models = [...byRef.values()].map(({ model, reasoning }) => ({
16154
- ...model,
16155
- supportedThinkingOptionIds: reasoning ? allThinkingOptionIds : offThinkingOptionId ? [offThinkingOptionId] : []
16156
- })).sort((left, right) => compareText(left.label, right.label) || compareText(left.ref.id, right.ref.id));
16157
- const defaultThinkingOptionId = thinkingOptions.find(({ id }) => id === effectiveThinkingOptionId)?.id;
16158
- return harnessModelCatalogSchema.parse({
16159
- models,
16160
- ...defaultModel ? { defaultModel } : {},
16161
- thinkingOptions,
16162
- ...defaultThinkingOptionId ? { defaultThinkingOptionId } : {}
16163
- });
16164
- }
16165
-
16166
- // dist/pi-history.js
16167
- var piHarnessId = harnessIdSchema.parse("pi");
16168
- function isRecord2(value) {
16169
- return typeof value === "object" && value !== null && !Array.isArray(value);
16170
- }
16171
- function textContent(value) {
16172
- if (typeof value === "string")
16173
- return value;
16174
- if (!Array.isArray(value))
16175
- return "";
16176
- return value.filter((part) => isRecord2(part) && part.type === "text" && typeof part.text === "string").map((part) => part.text).join("");
16177
- }
16178
- function thinkingContent(value) {
16179
- if (!Array.isArray(value))
16180
- return "";
16181
- return value.filter((part) => isRecord2(part) && part.type === "thinking" && typeof part.thinking === "string").map((part) => part.thinking).join("");
16182
- }
16183
- function validatedEntry(value) {
16184
- if (typeof value.id !== "string" || value.id.length === 0 || value.parentId !== null && typeof value.parentId !== "string" || typeof value.type !== "string") {
16185
- throw new Error("Pi history contains an invalid Entry identity");
16262
+ diff.push({ value: "", lines: [] });
16263
+ function contextLines(lines) {
16264
+ return lines.map(function(entry) {
16265
+ return " " + entry;
16266
+ });
16267
+ }
16268
+ const hunks = [];
16269
+ let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
16270
+ for (let i = 0; i < diff.length; i++) {
16271
+ const current = diff[i], lines = current.lines || splitLines(current.value);
16272
+ current.lines = lines;
16273
+ if (current.added || current.removed) {
16274
+ if (!oldRangeStart) {
16275
+ const prev = diff[i - 1];
16276
+ oldRangeStart = oldLine;
16277
+ newRangeStart = newLine;
16278
+ if (prev) {
16279
+ curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
16280
+ oldRangeStart -= curRange.length;
16281
+ newRangeStart -= curRange.length;
16282
+ }
16283
+ }
16284
+ for (const line of lines) {
16285
+ curRange.push((current.added ? "+" : "-") + line);
16286
+ }
16287
+ if (current.added) {
16288
+ newLine += lines.length;
16289
+ } else {
16290
+ oldLine += lines.length;
16291
+ }
16292
+ } else {
16293
+ if (oldRangeStart) {
16294
+ if (lines.length <= context * 2 && i < diff.length - 2) {
16295
+ for (const line of contextLines(lines)) {
16296
+ curRange.push(line);
16297
+ }
16298
+ } else {
16299
+ const contextSize = Math.min(lines.length, context);
16300
+ for (const line of contextLines(lines.slice(0, contextSize))) {
16301
+ curRange.push(line);
16302
+ }
16303
+ const hunk = {
16304
+ oldStart: oldRangeStart,
16305
+ oldLines: oldLine - oldRangeStart + contextSize,
16306
+ newStart: newRangeStart,
16307
+ newLines: newLine - newRangeStart + contextSize,
16308
+ lines: curRange
16309
+ };
16310
+ hunks.push(hunk);
16311
+ oldRangeStart = 0;
16312
+ newRangeStart = 0;
16313
+ curRange = [];
16314
+ }
16315
+ }
16316
+ oldLine += lines.length;
16317
+ newLine += lines.length;
16318
+ }
16319
+ }
16320
+ for (const hunk of hunks) {
16321
+ for (let i = 0; i < hunk.lines.length; i++) {
16322
+ if (hunk.lines[i].endsWith("\n")) {
16323
+ hunk.lines[i] = hunk.lines[i].slice(0, -1);
16324
+ } else {
16325
+ hunk.lines.splice(i + 1, 0, "\");
16326
+ i++;
16327
+ }
16328
+ }
16329
+ }
16330
+ return {
16331
+ oldFileName,
16332
+ newFileName,
16333
+ oldHeader,
16334
+ newHeader,
16335
+ hunks
16336
+ };
16186
16337
  }
16187
- return value;
16188
16338
  }
16189
- function activePiEntries(history) {
16190
- if (history.leafId === null)
16191
- return [];
16192
- const byId = new Map(history.entries.map((value) => {
16193
- const entry = validatedEntry(value);
16194
- return [entry.id, entry];
16195
- }));
16196
- const reversed = [];
16197
- const visited = /* @__PURE__ */ new Set();
16198
- let current = history.leafId;
16199
- while (current !== null) {
16200
- if (visited.has(current))
16201
- throw new Error("Pi history active branch contains a cycle");
16202
- visited.add(current);
16203
- const entry = byId.get(current);
16204
- if (!entry)
16205
- throw new Error("Pi history active branch references a missing Entry");
16206
- reversed.push(entry);
16207
- current = entry.parentId;
16339
+ function formatPatch(patch) {
16340
+ if (Array.isArray(patch)) {
16341
+ return patch.map(formatPatch).join("\n");
16208
16342
  }
16209
- return reversed.reverse();
16210
- }
16211
- function message(entry) {
16212
- return entry.type === "message" && isRecord2(entry.message) ? entry.message : null;
16213
- }
16214
- function messageRole(entry) {
16215
- const value = message(entry)?.role;
16216
- return typeof value === "string" ? value : null;
16217
- }
16218
- function itemId(entryId, kind, ordinal) {
16219
- return hostItemIdSchema.parse(`pi-item-v1-${entryId}-${kind}-${ordinal}`);
16343
+ const ret = [];
16344
+ if (patch.oldFileName == patch.newFileName) {
16345
+ ret.push("Index: " + patch.oldFileName);
16346
+ }
16347
+ ret.push("===================================================================");
16348
+ ret.push("--- " + patch.oldFileName + (typeof patch.oldHeader === "undefined" ? "" : " " + patch.oldHeader));
16349
+ ret.push("+++ " + patch.newFileName + (typeof patch.newHeader === "undefined" ? "" : " " + patch.newHeader));
16350
+ for (let i = 0; i < patch.hunks.length; i++) {
16351
+ const hunk = patch.hunks[i];
16352
+ if (hunk.oldLines === 0) {
16353
+ hunk.oldStart -= 1;
16354
+ }
16355
+ if (hunk.newLines === 0) {
16356
+ hunk.newStart -= 1;
16357
+ }
16358
+ ret.push("@@ -" + hunk.oldStart + "," + hunk.oldLines + " +" + hunk.newStart + "," + hunk.newLines + " @@");
16359
+ for (const line of hunk.lines) {
16360
+ ret.push(line);
16361
+ }
16362
+ }
16363
+ return ret.join("\n") + "\n";
16220
16364
  }
16221
- function assistantOutcome(entries) {
16222
- const assistants = entries.map((entry) => message(entry)).filter((value) => value?.role === "assistant");
16223
- const final = assistants.at(-1);
16224
- if (!final)
16225
- return { status: "unknown", reason: "Pi history has no Assistant terminal" };
16226
- const stopReason = final.stopReason;
16227
- if (stopReason === "aborted") {
16228
- return { status: "cancelled", reason: "Pi Assistant was aborted" };
16365
+ function createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
16366
+ if (typeof options === "function") {
16367
+ options = { callback: options };
16229
16368
  }
16230
- if (stopReason === "error") {
16231
- return {
16232
- status: "failed",
16233
- error: {
16234
- code: "nativeFailure",
16235
- message: typeof final.errorMessage === "string" && final.errorMessage.length > 0 ? final.errorMessage : "Pi Assistant failed",
16236
- retryable: false
16369
+ if (!(options === null || options === void 0 ? void 0 : options.callback)) {
16370
+ const patchObj = structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options);
16371
+ if (!patchObj) {
16372
+ return;
16373
+ }
16374
+ return formatPatch(patchObj);
16375
+ } else {
16376
+ const { callback } = options;
16377
+ structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, Object.assign(Object.assign({}, options), { callback: (patchObj) => {
16378
+ if (!patchObj) {
16379
+ callback(void 0);
16380
+ } else {
16381
+ callback(formatPatch(patchObj));
16237
16382
  }
16238
- };
16239
- }
16240
- if (typeof stopReason === "string" || textContent(final.content).length > 0) {
16241
- return { status: "succeeded" };
16383
+ } }));
16242
16384
  }
16243
- return { status: "unknown", reason: "Pi Assistant terminal is not classifiable" };
16244
16385
  }
16245
- function itemOutcome(outcome) {
16246
- if (outcome.status === "failed")
16247
- return { status: "failed", error: outcome.error };
16248
- if (outcome.status === "cancelled") {
16249
- return {
16250
- status: "cancelled",
16251
- ...outcome.reason ? { reason: outcome.reason } : {}
16252
- };
16386
+ function splitLines(text) {
16387
+ const hasTrailingNl = text.endsWith("\n");
16388
+ const result = text.split("\n").map((line) => line + "\n");
16389
+ if (hasTrailingNl) {
16390
+ result.pop();
16391
+ } else {
16392
+ result.push(result.pop().slice(0, -1));
16253
16393
  }
16254
- return { status: "succeeded" };
16394
+ return result;
16255
16395
  }
16256
- function toolOutput(value) {
16257
- const text = textContent(value);
16258
- return text.length > 0 ? { content: [{ type: "text", text }] } : void 0;
16396
+
16397
+ // dist/pi-adapter.js
16398
+ import { randomUUID as randomUUID3 } from "node:crypto";
16399
+ import path6 from "node:path";
16400
+
16401
+ // ../../harness-adapter/dist/question.js
16402
+ function invalidRequest(message3) {
16403
+ return { code: "invalidRequest", message: message3, retryable: false };
16259
16404
  }
16260
- function snapshotItems(entries, outcome) {
16261
- const snapshots = [];
16262
- const toolCalls = /* @__PURE__ */ new Map();
16263
- for (const entry of entries) {
16264
- const nativeMessage = message(entry);
16265
- if (!nativeMessage)
16266
- continue;
16267
- const content = Array.isArray(nativeMessage.content) ? nativeMessage.content : [];
16268
- if (nativeMessage.role === "assistant") {
16269
- const text = textContent(content);
16270
- const reasoning = thinkingContent(content);
16271
- let projectedText = false;
16272
- let projectedReasoning = false;
16273
- for (const [ordinal, part] of content.entries()) {
16274
- if (!isRecord2(part))
16275
- continue;
16276
- if (part.type === "thinking" && !projectedReasoning && reasoning.length > 0) {
16277
- const item2 = {
16278
- type: "reasoning",
16279
- itemId: itemId(entry.id, "reasoning", 0),
16280
- text: reasoning
16281
- };
16282
- snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
16283
- projectedReasoning = true;
16284
- continue;
16285
- }
16286
- if (part.type === "text" && !projectedText && text.length > 0) {
16287
- const item2 = {
16288
- type: "agentMessage",
16289
- itemId: itemId(entry.id, "assistant", 0),
16290
- text
16291
- };
16292
- snapshots.push({ item: item2, outcome: itemOutcome(outcome) });
16293
- projectedText = true;
16294
- continue;
16295
- }
16296
- if (part.type !== "toolCall" || typeof part.id !== "string" || typeof part.name !== "string") {
16297
- continue;
16298
- }
16299
- const parsedArguments = jsonValueSchema.safeParse(part.arguments);
16300
- if (!parsedArguments.success)
16301
- continue;
16302
- toolCalls.set(part.id, {
16303
- entryId: entry.id,
16304
- ordinal,
16305
- name: part.name,
16306
- arguments: parsedArguments.data
16307
- });
16405
+ function validateHostQuestionResponse(interaction, response) {
16406
+ const questionIds = new Set(interaction.questions.map(({ id }) => id));
16407
+ if (response.cancelled) {
16408
+ return Object.keys(response.answers).length === 0 ? null : invalidRequest("Cancelled Question Response must not contain answers");
16409
+ }
16410
+ for (const answerId of Object.keys(response.answers)) {
16411
+ if (!questionIds.has(answerId)) {
16412
+ return invalidRequest("Question Response contains an unknown Question ID");
16413
+ }
16414
+ }
16415
+ for (const question of interaction.questions) {
16416
+ const answers = response.answers[question.id] ?? [];
16417
+ if (!question.optional && answers.length === 0) {
16418
+ return invalidRequest("Question Response omits a required answer");
16419
+ }
16420
+ if (question.type === "text") {
16421
+ if (answers.length > 1) {
16422
+ return invalidRequest("Text Question accepts at most one answer");
16308
16423
  }
16309
16424
  continue;
16310
16425
  }
16311
- if (nativeMessage.role !== "toolResult" || typeof nativeMessage.toolCallId !== "string" || typeof nativeMessage.toolName !== "string") {
16312
- continue;
16426
+ if (!question.multiple && answers.length > 1) {
16427
+ return invalidRequest("Single-choice Question accepts at most one answer");
16313
16428
  }
16314
- const call = toolCalls.get(nativeMessage.toolCallId);
16315
- if (!call || call.name !== nativeMessage.toolName)
16316
- continue;
16317
- const output = toolOutput(nativeMessage.content);
16318
- const item = {
16319
- type: "toolExecution",
16320
- itemId: itemId(call.entryId, "tool", call.ordinal),
16321
- toolName: call.name,
16322
- arguments: call.arguments,
16323
- ...output ? { output } : {}
16324
- };
16325
- const toolSucceeded = nativeMessage.isError === false;
16326
- snapshots.push({
16327
- item,
16328
- outcome: toolSucceeded ? { status: "succeeded" } : {
16329
- status: "failed",
16330
- error: {
16331
- code: "nativeFailure",
16332
- message: `Pi Tool '${call.name}' failed`,
16333
- retryable: false
16429
+ const declared = new Set(question.options.map(({ value }) => value));
16430
+ if (!question.allowOther && answers.some((answer) => !declared.has(answer))) {
16431
+ return invalidRequest("Question Response contains an undeclared choice");
16432
+ }
16433
+ }
16434
+ return null;
16435
+ }
16436
+
16437
+ // ../../harness-adapter/dist/output-channel.js
16438
+ var HarnessOutputChannel = class {
16439
+ outputs;
16440
+ #consumerCreated = false;
16441
+ #ended = false;
16442
+ #pending = [];
16443
+ #values = [];
16444
+ constructor() {
16445
+ this.outputs = {
16446
+ [Symbol.asyncIterator]: () => {
16447
+ if (this.#consumerCreated) {
16448
+ throw new Error("Harness outputs allow only one consumer");
16334
16449
  }
16450
+ this.#consumerCreated = true;
16451
+ return {
16452
+ next: () => this.#next()
16453
+ };
16335
16454
  }
16336
- });
16455
+ };
16456
+ }
16457
+ emit(value) {
16458
+ if (this.#ended)
16459
+ return false;
16460
+ const resolve = this.#pending.shift();
16461
+ if (resolve)
16462
+ resolve({ done: false, value });
16463
+ else
16464
+ this.#values.push(value);
16465
+ return true;
16337
16466
  }
16338
- return snapshots;
16467
+ end() {
16468
+ if (this.#ended)
16469
+ return;
16470
+ this.#ended = true;
16471
+ if (this.#values.length !== 0)
16472
+ return;
16473
+ for (const resolve of this.#pending.splice(0))
16474
+ resolve({ done: true, value: void 0 });
16475
+ }
16476
+ #next() {
16477
+ const value = this.#values.shift();
16478
+ if (value !== void 0)
16479
+ return Promise.resolve({ done: false, value });
16480
+ if (this.#ended)
16481
+ return Promise.resolve({ done: true, value: void 0 });
16482
+ return new Promise((resolve) => this.#pending.push(resolve));
16483
+ }
16484
+ };
16485
+
16486
+ // ../../harness-adapter/dist/diagnostics.js
16487
+ var DIAGNOSTIC_TAIL_MAX_LENGTH = 8e3;
16488
+ var SENSITIVE_VALUE_PATTERN = /(api[_-]?key|access[_-]?token|auth(?:orization)?|password|secret)(\s*[:=]\s*)([^\s,;]+)/giu;
16489
+ var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/giu;
16490
+ function sanitizeDiagnosticTail(value) {
16491
+ const redacted = value.replace(BEARER_PATTERN, "Bearer [redacted]").replace(SENSITIVE_VALUE_PATTERN, "$1$2[redacted]");
16492
+ return redacted.length <= DIAGNOSTIC_TAIL_MAX_LENGTH ? redacted : redacted.slice(-DIAGNOSTIC_TAIL_MAX_LENGTH);
16339
16493
  }
16340
- function modelChange(entry) {
16341
- return entry.type === "model_change" && typeof entry.provider === "string" && typeof entry.modelId === "string" ? { provider: entry.provider, id: entry.modelId } : null;
16494
+
16495
+ // ../../harness-adapter/dist/usage.js
16496
+ var tokenFields = [
16497
+ "inputTokens",
16498
+ "cachedInputTokens",
16499
+ "cacheWriteInputTokens",
16500
+ "outputTokens",
16501
+ "outputTokensPerSecond",
16502
+ "reasoningOutputTokens",
16503
+ "totalTokens",
16504
+ "contextWindowTokens",
16505
+ "contextUsedTokens"
16506
+ ];
16507
+ var safeIntegerFields = [
16508
+ "planFiveHourResetsAtUnix",
16509
+ "planSevenDayResetsAtUnix"
16510
+ ];
16511
+ var percentFields = [
16512
+ "cacheHitRatePercent",
16513
+ "planFiveHourUsedPercent",
16514
+ "planSevenDayUsedPercent"
16515
+ ];
16516
+ var usageFields = /* @__PURE__ */ new Set([
16517
+ ...tokenFields,
16518
+ ...safeIntegerFields,
16519
+ ...percentFields,
16520
+ "totalCostUsd",
16521
+ "totalCredits",
16522
+ "contextUsagePercent"
16523
+ ]);
16524
+ function isRecord3(value) {
16525
+ return typeof value === "object" && value !== null && !Array.isArray(value);
16342
16526
  }
16343
- function mapPiSnapshot(history, state) {
16344
- const active = activePiEntries(history);
16345
- const turns = [];
16346
- let effectiveModel = state.model;
16347
- for (let index = 0; index < active.length; ) {
16348
- const model = modelChange(active[index]);
16349
- if (model) {
16350
- effectiveModel = model;
16351
- index += 1;
16352
- continue;
16527
+ function parseHostUsage(value) {
16528
+ if (!isRecord3(value))
16529
+ throw new Error("Harness Usage must be an object");
16530
+ const keys = Object.keys(value);
16531
+ if (keys.length === 0)
16532
+ throw new Error("Harness Usage must contain a reliable field");
16533
+ for (const key of keys) {
16534
+ if (!usageFields.has(key)) {
16535
+ throw new Error(`Harness Usage contains unknown field '${key}'`);
16353
16536
  }
16354
- const user = active[index];
16355
- if (messageRole(user) !== "user") {
16356
- index += 1;
16357
- continue;
16537
+ }
16538
+ for (const field of ["totalCredits", "contextUsagePercent"]) {
16539
+ const candidate = value[field];
16540
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)) {
16541
+ throw new Error(`Harness Usage '${field}' must be a finite non-negative number`);
16358
16542
  }
16359
- let end = index + 1;
16360
- while (end < active.length && messageRole(active[end]) !== "user")
16361
- end += 1;
16362
- const entries = active.slice(index, end);
16363
- const outcome = assistantOutcome(entries);
16364
- const userText = textContent(message(user)?.content);
16365
- const nativeTurnRef = nativeTurnRefSchema.parse({
16366
- harnessId: piHarnessId,
16367
- nativeSessionId: state.sessionId,
16368
- nativeTurnKey: user.id,
16369
- formatVersion: 1
16370
- });
16371
- const checkpoint = nativeCheckpointRefSchema.parse({
16372
- harnessId: piHarnessId,
16373
- nativeSessionId: state.sessionId,
16374
- checkpointId: user.id,
16375
- formatVersion: 1
16376
- });
16377
- turns.push({
16378
- nativeTurnRef,
16379
- checkpoint,
16380
- input: [{ type: "text", text: userText }],
16381
- items: snapshotItems(entries, outcome),
16382
- outcome,
16383
- ...effectiveModel ? { model: encodePiModelRef(effectiveModel) } : {}
16384
- });
16385
- for (const entry of entries) {
16386
- const changed = modelChange(entry);
16387
- if (changed)
16388
- effectiveModel = changed;
16543
+ }
16544
+ for (const field of tokenFields) {
16545
+ const candidate = value[field];
16546
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16547
+ throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16389
16548
  }
16390
- index = end;
16391
16549
  }
16392
- return { turns };
16393
- }
16394
- function resolvePiLastTurnBoundary(history) {
16395
- const users = activePiEntries(history).filter((entry) => messageRole(entry) === "user");
16396
- const last = users.at(-1);
16397
- return last ? { lastUserEntryId: last.id, sourceTurnCount: users.length } : null;
16398
- }
16399
- function resolvePiForkBoundary(history, checkpointId) {
16400
- const active = activePiEntries(history);
16401
- const users = active.filter((entry) => messageRole(entry) === "user");
16402
- const targetTurnIndex = users.findIndex((entry) => entry.id === checkpointId);
16403
- if (targetTurnIndex < 0)
16404
- throw new Error("Pi Checkpoint is not on the active branch");
16405
- return {
16406
- targetTurnIndex,
16407
- nextUserEntryId: users[targetTurnIndex + 1]?.id ?? null
16408
- };
16550
+ for (const field of safeIntegerFields) {
16551
+ const candidate = value[field];
16552
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0)) {
16553
+ throw new Error(`Harness Usage '${field}' must be a non-negative safe integer`);
16554
+ }
16555
+ }
16556
+ if (value.outputTokensPerSecond !== void 0 && (typeof value.outputTokensPerSecond !== "number" || !Number.isFinite(value.outputTokensPerSecond) || value.outputTokensPerSecond < 0)) {
16557
+ throw new Error("Harness Usage 'outputTokensPerSecond' must be a finite non-negative number");
16558
+ }
16559
+ if (value.totalCostUsd !== void 0 && (typeof value.totalCostUsd !== "number" || !Number.isFinite(value.totalCostUsd) || value.totalCostUsd < 0)) {
16560
+ throw new Error("Harness Usage 'totalCostUsd' must be a finite non-negative number");
16561
+ }
16562
+ for (const field of percentFields) {
16563
+ const candidate = value[field];
16564
+ if (candidate !== void 0 && (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0 || candidate > 100)) {
16565
+ throw new Error(`Harness Usage '${field}' must be between 0 and 100`);
16566
+ }
16567
+ }
16568
+ const hasContextUsed = value.contextUsedTokens !== void 0;
16569
+ const hasContextWindow = value.contextWindowTokens !== void 0;
16570
+ if (hasContextUsed !== hasContextWindow) {
16571
+ throw new Error("Harness Usage context fields must be provided together");
16572
+ }
16573
+ if (hasContextWindow && value.contextWindowTokens === 0) {
16574
+ throw new Error("Harness Usage 'contextWindowTokens' must be greater than zero");
16575
+ }
16576
+ if (value.planFiveHourResetsAtUnix !== void 0 && value.planFiveHourUsedPercent === void 0) {
16577
+ throw new Error("Harness Usage 'planFiveHourResetsAtUnix' must be provided with 'planFiveHourUsedPercent'");
16578
+ }
16579
+ if (value.planSevenDayResetsAtUnix !== void 0 && value.planSevenDayUsedPercent === void 0) {
16580
+ throw new Error("Harness Usage 'planSevenDayResetsAtUnix' must be provided with 'planSevenDayUsedPercent'");
16581
+ }
16582
+ return { ...value };
16409
16583
  }
16410
16584
 
16411
16585
  // dist/pi-last-turn-rollback.js
@@ -16456,16 +16630,23 @@ async function rollbackPiLastTurn(transport, sourceSessionId, cwd) {
16456
16630
  if (snapshot.turns.length !== boundary.sourceTurnCount - 1 || actualTurnKeys.some((key, index) => key !== expectedTurnKeys[index])) {
16457
16631
  throw new Error("Pi last-Turn rollback did not produce the exact retained history prefix");
16458
16632
  }
16459
- await transport.verifySessionCwd(cwd);
16460
- return { ok: true };
16633
+ try {
16634
+ await transport.verifySessionCwd(cwd);
16635
+ return { ok: true, unpersisted: false };
16636
+ } catch (error51) {
16637
+ if (snapshot.turns.length === 0 && error51?.code === "ENOENT") {
16638
+ return { ok: true, unpersisted: true };
16639
+ }
16640
+ throw error51;
16641
+ }
16461
16642
  }
16462
16643
 
16463
16644
  // dist/pi-session-import.js
16464
- import { createReadStream } from "node:fs";
16465
- import { opendir, realpath, stat } from "node:fs/promises";
16645
+ import { createReadStream as createReadStream2 } from "node:fs";
16646
+ import { opendir, realpath as realpath2, stat } from "node:fs/promises";
16466
16647
  import os from "node:os";
16467
- import path from "node:path";
16468
- import { createInterface } from "node:readline";
16648
+ import path2 from "node:path";
16649
+ import { createInterface as createInterface2 } from "node:readline";
16469
16650
  var PiSessionChangedError = class extends Error {
16470
16651
  constructor() {
16471
16652
  super("Pi Session changed during discovery; refresh and retry");
@@ -16474,14 +16655,14 @@ var PiSessionChangedError = class extends Error {
16474
16655
  function sameFile(left, right) {
16475
16656
  return left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.ino === right.ino && left.dev === right.dev;
16476
16657
  }
16477
- function isRecord3(value) {
16658
+ function isRecord4(value) {
16478
16659
  return typeof value === "object" && value !== null && !Array.isArray(value);
16479
16660
  }
16480
16661
  function missing(error51) {
16481
- return isRecord3(error51) && error51.code === "ENOENT";
16662
+ return isRecord4(error51) && error51.code === "ENOENT";
16482
16663
  }
16483
16664
  function expandDirectory(value, home) {
16484
- return path.resolve(value === "~" ? home : value.startsWith(`~${path.sep}`) || value.startsWith("~/") ? path.join(home, value.slice(2)) : value);
16665
+ return path2.resolve(value === "~" ? home : value.startsWith(`~${path2.sep}`) || value.startsWith("~/") ? path2.join(home, value.slice(2)) : value);
16485
16666
  }
16486
16667
  function piSessionImportDirectory(environment) {
16487
16668
  const home = (process.platform === "win32" ? environment.USERPROFILE : environment.HOME) || os.homedir();
@@ -16490,7 +16671,7 @@ function piSessionImportDirectory(environment) {
16490
16671
  return { directory: expandDirectory(custom2, home), flat: true };
16491
16672
  const agent = environment.PI_CODING_AGENT_DIR;
16492
16673
  return {
16493
- directory: path.join(agent ? expandDirectory(agent, home) : path.join(home, ".pi", "agent"), "sessions"),
16674
+ directory: path2.join(agent ? expandDirectory(agent, home) : path2.join(home, ".pi", "agent"), "sessions"),
16494
16675
  flat: false
16495
16676
  };
16496
16677
  }
@@ -16508,9 +16689,9 @@ async function sessionFiles(directory, flat, signal) {
16508
16689
  for await (const entry of entries) {
16509
16690
  signal.throwIfAborted();
16510
16691
  if (projectLevel && entry.isDirectory())
16511
- await visit(path.join(dir, entry.name), false);
16692
+ await visit(path2.join(dir, entry.name), false);
16512
16693
  else if (!projectLevel && entry.isFile() && entry.name.endsWith(".jsonl")) {
16513
- files.push(path.join(dir, entry.name));
16694
+ files.push(path2.join(dir, entry.name));
16514
16695
  }
16515
16696
  }
16516
16697
  };
@@ -16521,8 +16702,8 @@ async function readCandidate(file2, signal) {
16521
16702
  const before = await stat(file2);
16522
16703
  if (!before.isFile() || before.size === 0)
16523
16704
  return null;
16524
- const stream = createReadStream(file2, { encoding: "utf8", signal, end: before.size - 1 });
16525
- const lines = createInterface({ input: stream, crlfDelay: Infinity });
16705
+ const stream = createReadStream2(file2, { encoding: "utf8", signal, end: before.size - 1 });
16706
+ const lines = createInterface2({ input: stream, crlfDelay: Infinity });
16526
16707
  let header;
16527
16708
  let name = null;
16528
16709
  let firstMessage = null;
@@ -16540,20 +16721,20 @@ async function readCandidate(file2, signal) {
16540
16721
  } catch {
16541
16722
  return null;
16542
16723
  }
16543
- if (!isRecord3(entry))
16724
+ if (!isRecord4(entry))
16544
16725
  return null;
16545
16726
  if (!header) {
16546
- if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !path.isAbsolute(entry.cwd))
16727
+ if (entry.type !== "session" || entry.version !== 3 || typeof entry.id !== "string" || typeof entry.cwd !== "string" || !path2.isAbsolute(entry.cwd))
16547
16728
  return null;
16548
16729
  header = entry;
16549
16730
  continue;
16550
16731
  }
16551
16732
  if (typeof entry.id !== "string" || entry.id.length === 0 || entries.has(entry.id) || entry.parentId !== null && (typeof entry.parentId !== "string" || !entries.has(entry.parentId)))
16552
16733
  return null;
16553
- const message3 = isRecord3(entry.message) ? entry.message : null;
16734
+ const message3 = isRecord4(entry.message) ? entry.message : null;
16554
16735
  if (!firstMessage && entry.type === "message" && message3?.role === "user") {
16555
16736
  const content = message3.content;
16556
- const text = typeof content === "string" ? content : Array.isArray(content) ? content.filter((block) => isRecord3(block) && block.type === "text" && typeof block.text === "string").map((block) => block.text).join(" ") : "";
16737
+ const text = typeof content === "string" ? content : Array.isArray(content) ? content.filter((block) => isRecord4(block) && block.type === "text" && typeof block.text === "string").map((block) => block.text).join(" ") : "";
16557
16738
  firstMessage = text.replaceAll("\0", "").trim().slice(0, HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH) || null;
16558
16739
  }
16559
16740
  hasUser = entry.type === "message" && message3?.role === "user" || typeof entry.parentId === "string" && entries.get(entry.parentId) === true;
@@ -16577,13 +16758,13 @@ async function readCandidate(file2, signal) {
16577
16758
  const after = await stat(file2);
16578
16759
  if (!sameFile(before, after))
16579
16760
  throw new PiSessionChangedError();
16580
- const cwd = await realpath(String(header.cwd));
16761
+ const cwd = await realpath2(String(header.cwd));
16581
16762
  if (!(await stat(cwd)).isDirectory())
16582
16763
  return null;
16583
16764
  const nativeRef = nativeSessionRefSchema.safeParse({
16584
16765
  harnessId: "pi",
16585
16766
  nativeSessionId: header.id,
16586
- locator: { sessionFile: await realpath(file2) },
16767
+ locator: { sessionFile: await realpath2(file2) },
16587
16768
  formatVersion: 1
16588
16769
  });
16589
16770
  const candidate = harnessSessionImportCandidateSchema.safeParse({
@@ -16596,8 +16777,8 @@ async function readCandidate(file2, signal) {
16596
16777
  return candidate.success && nativeRef.success ? { candidate: candidate.data, nativeRef: nativeRef.data } : null;
16597
16778
  }
16598
16779
  async function readIdentity(file2, signal) {
16599
- const stream = createReadStream(file2, { encoding: "utf8", signal });
16600
- const lines = createInterface({ input: stream, crlfDelay: Infinity });
16780
+ const stream = createReadStream2(file2, { encoding: "utf8", signal });
16781
+ const lines = createInterface2({ input: stream, crlfDelay: Infinity });
16601
16782
  try {
16602
16783
  for await (const line of lines) {
16603
16784
  signal.throwIfAborted();
@@ -16609,7 +16790,7 @@ async function readIdentity(file2, signal) {
16609
16790
  } catch {
16610
16791
  return null;
16611
16792
  }
16612
- return isRecord3(header) && header.type === "session" && header.version === 3 && typeof header.id === "string" ? header.id : null;
16793
+ return isRecord4(header) && header.type === "session" && header.version === 3 && typeof header.id === "string" ? header.id : null;
16613
16794
  }
16614
16795
  return null;
16615
16796
  } finally {
@@ -16693,14 +16874,14 @@ var PiSessionImportIndex = class {
16693
16874
 
16694
16875
  // dist/pi-rpc-session.js
16695
16876
  import { spawn, spawnSync } from "node:child_process";
16696
- import { randomUUID } from "node:crypto";
16697
- import path4 from "node:path";
16877
+ import { randomUUID as randomUUID2 } from "node:crypto";
16878
+ import path5 from "node:path";
16698
16879
 
16699
16880
  // ../../harness-discovery/dist/environment.js
16700
16881
  import fs from "node:fs";
16701
- import path2 from "node:path";
16882
+ import path3 from "node:path";
16702
16883
  function targetPath(platform) {
16703
- return platform === "win32" ? path2.win32 : path2.posix;
16884
+ return platform === "win32" ? path3.win32 : path3.posix;
16704
16885
  }
16705
16886
  function environmentValue(environment, name) {
16706
16887
  const lowered = name.toLowerCase();
@@ -16743,11 +16924,11 @@ function newestFirst(names) {
16743
16924
  }
16744
16925
 
16745
16926
  // ../../harness-discovery/dist/node-runtime.js
16746
- import path3 from "node:path";
16927
+ import path4 from "node:path";
16747
16928
  function withNodeRuntimeOnPath(environment, runtimeExecutable = process.execPath, platform = process.platform) {
16748
16929
  const pathKey = Object.keys(environment).find((name) => name.toLowerCase() === "path") ?? "PATH";
16749
16930
  const delimiter = platform === "win32" ? ";" : ":";
16750
- const runtimeDirectory = path3.dirname(runtimeExecutable);
16931
+ const runtimeDirectory = path4.dirname(runtimeExecutable);
16751
16932
  const directories = (environment[pathKey] ?? "").split(delimiter).filter(Boolean);
16752
16933
  const equal = platform === "win32" ? (value) => value.toLowerCase() : (value) => value;
16753
16934
  if (!directories.some((directory) => equal(directory) === equal(runtimeDirectory))) {
@@ -16946,14 +17127,14 @@ function resolvePiExecutable(input, dependencies = {}) {
16946
17127
  }
16947
17128
 
16948
17129
  // dist/pi-usage.js
16949
- function isRecord4(value) {
17130
+ function isRecord5(value) {
16950
17131
  return typeof value === "object" && value !== null && !Array.isArray(value);
16951
17132
  }
16952
17133
  function nonNegativeSafeInteger(value) {
16953
17134
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
16954
17135
  }
16955
17136
  function optionalPiCacheHitRatePercent(value) {
16956
- if (!isRecord4(value) || value.role !== "assistant" || !isRecord4(value.usage))
17137
+ if (!isRecord5(value) || value.role !== "assistant" || !isRecord5(value.usage))
16957
17138
  return null;
16958
17139
  const input = nonNegativeSafeInteger(value.usage.input);
16959
17140
  const cacheRead = nonNegativeSafeInteger(value.usage.cacheRead);
@@ -16966,20 +17147,20 @@ function optionalPiCacheHitRatePercent(value) {
16966
17147
  function latestPiCacheHitRatePercent(history) {
16967
17148
  let latest = null;
16968
17149
  for (const entry of activePiEntries(history)) {
16969
- if (entry.type === "message" && isRecord4(entry.message) && entry.message.role === "assistant") {
17150
+ if (entry.type === "message" && isRecord5(entry.message) && entry.message.role === "assistant") {
16970
17151
  latest = optionalPiCacheHitRatePercent(entry.message);
16971
17152
  }
16972
17153
  }
16973
17154
  return latest;
16974
17155
  }
16975
17156
  function responseData(response, operation) {
16976
- if (!isRecord4(response.data)) {
17157
+ if (!isRecord5(response.data)) {
16977
17158
  throw new Error(`Pi RPC ${operation} response has no data`);
16978
17159
  }
16979
17160
  return response.data;
16980
17161
  }
16981
17162
  function contextUsage(value) {
16982
- if (!isRecord4(value))
17163
+ if (!isRecord5(value))
16983
17164
  throw new Error("Pi RPC context Usage is invalid");
16984
17165
  return parseHostUsage({
16985
17166
  contextUsedTokens: value.tokens,
@@ -16989,15 +17170,15 @@ function contextUsage(value) {
16989
17170
  function parsePiSessionUsage(response) {
16990
17171
  const data = responseData(response, "Session stats");
16991
17172
  const tokens = data.tokens;
16992
- if (tokens !== void 0 && !isRecord4(tokens)) {
17173
+ if (tokens !== void 0 && !isRecord5(tokens)) {
16993
17174
  throw new Error("Pi RPC Session stats tokens are invalid");
16994
17175
  }
16995
17176
  return parseHostUsage({
16996
- ...isRecord4(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
16997
- ...isRecord4(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
16998
- ...isRecord4(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
16999
- ...isRecord4(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
17000
- ...isRecord4(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
17177
+ ...isRecord5(tokens) && tokens.input !== void 0 ? { inputTokens: tokens.input } : {},
17178
+ ...isRecord5(tokens) && tokens.cacheRead !== void 0 ? { cachedInputTokens: tokens.cacheRead } : {},
17179
+ ...isRecord5(tokens) && tokens.cacheWrite !== void 0 ? { cacheWriteInputTokens: tokens.cacheWrite } : {},
17180
+ ...isRecord5(tokens) && tokens.output !== void 0 ? { outputTokens: tokens.output } : {},
17181
+ ...isRecord5(tokens) && tokens.total !== void 0 ? { totalTokens: tokens.total } : {},
17001
17182
  ...data.cost !== void 0 ? { totalCostUsd: data.cost } : {},
17002
17183
  ...data.contextUsage !== void 0 ? contextUsage(data.contextUsage) : {}
17003
17184
  });
@@ -17016,54 +17197,6 @@ function optionalPiStateContextUsage(value) {
17016
17197
  }
17017
17198
  }
17018
17199
 
17019
- // dist/pi-session-file.js
17020
- import { open, realpath as realpath2 } from "node:fs/promises";
17021
- var MAX_SESSION_HEADER_BYTES = 64 * 1024;
17022
- var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
17023
- function isRecord5(value) {
17024
- return typeof value === "object" && value !== null && !Array.isArray(value);
17025
- }
17026
- async function readPiSessionHeader(sessionFile) {
17027
- const handle = await open(sessionFile, "r");
17028
- try {
17029
- const buffer = Buffer.allocUnsafe(MAX_SESSION_HEADER_BYTES);
17030
- const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
17031
- const contents = buffer.subarray(0, bytesRead);
17032
- const newline = contents.indexOf(10);
17033
- if (newline < 0 && bytesRead === buffer.length) {
17034
- throw new Error("Pi Session header exceeds the supported size");
17035
- }
17036
- const headerText = utf8Decoder.decode(newline < 0 ? contents : contents.subarray(0, newline));
17037
- let parsed;
17038
- try {
17039
- parsed = JSON.parse(headerText);
17040
- } catch {
17041
- throw new Error("Pi Session header is not valid JSON");
17042
- }
17043
- if (!isRecord5(parsed) || parsed.type !== "session" || typeof parsed.id !== "string" || parsed.id.length === 0 || typeof parsed.cwd !== "string" || parsed.cwd.length === 0) {
17044
- throw new Error("Pi Session header is invalid");
17045
- }
17046
- return { type: "session", id: parsed.id, cwd: parsed.cwd };
17047
- } finally {
17048
- await handle.close();
17049
- }
17050
- }
17051
- async function verifyPiSessionCwd(input) {
17052
- if (!input.sessionFile)
17053
- throw new Error("Pi Fork Session has no persisted Session file");
17054
- const header = await readPiSessionHeader(input.sessionFile);
17055
- if (header.id !== input.sessionId) {
17056
- throw new Error("Pi Fork Session header identity does not match RPC state");
17057
- }
17058
- const [actualCwd, expectedCwd] = await Promise.all([
17059
- realpath2(header.cwd),
17060
- realpath2(input.expectedCwd)
17061
- ]);
17062
- if (actualCwd !== expectedCwd) {
17063
- throw new Error("Pi Fork Session did not bind the requested cwd");
17064
- }
17065
- }
17066
-
17067
17200
  // dist/pi-rpc-session.js
17068
17201
  var PiRpcFaultError = class extends Error {
17069
17202
  kind;
@@ -17245,6 +17378,9 @@ function piRpcProcessCommand(options, dependencies = {}) {
17245
17378
  if (options.model && (options.sessionFile || options.forkSessionFile)) {
17246
17379
  throw new Error("Pi RPC cannot combine a startup Model with Session restore or Fork");
17247
17380
  }
17381
+ if (options.emptySessionConfiguration && (!options.sessionFile || options.model || options.forkSessionFile)) {
17382
+ throw new Error("Pi empty Session configuration requires an exclusive Session resume");
17383
+ }
17248
17384
  const platform = dependencies.platform ?? process.platform;
17249
17385
  const command = resolvePiExecutable({
17250
17386
  ...options.command ? { command: options.command } : {},
@@ -17255,9 +17391,17 @@ function piRpcProcessCommand(options, dependencies = {}) {
17255
17391
  ...dependencies.isExecutable ? { isExecutable: dependencies.isExecutable } : {}
17256
17392
  });
17257
17393
  const sessionArguments = options.forkSessionFile ? ["--fork", options.forkSessionFile] : options.sessionFile ? ["--session", options.sessionFile] : [];
17258
- const modelArguments = options.model ? ["--provider", options.model.provider, "--model", options.model.id] : [];
17259
- const arguments_ = ["--mode", "rpc", ...modelArguments, ...sessionArguments];
17260
- const extension = path4.win32.extname(command).toLowerCase();
17394
+ const startupModel = options.emptySessionConfiguration?.model ?? options.model;
17395
+ const modelArguments = startupModel ? ["--provider", startupModel.provider, "--model", startupModel.id] : [];
17396
+ const thinkingArguments = options.emptySessionConfiguration ? ["--thinking", options.emptySessionConfiguration.thinkingLevel] : [];
17397
+ const arguments_ = [
17398
+ "--mode",
17399
+ "rpc",
17400
+ ...modelArguments,
17401
+ ...thinkingArguments,
17402
+ ...sessionArguments
17403
+ ];
17404
+ const extension = path5.win32.extname(command).toLowerCase();
17261
17405
  if (platform !== "win32" || ![".cmd", ".bat"].includes(extension)) {
17262
17406
  return { command, arguments: arguments_, windowsVerbatimArguments: false };
17263
17407
  }
@@ -17290,6 +17434,7 @@ var PiRpcSession = class {
17290
17434
  #buffer = Buffer.alloc(0);
17291
17435
  #child = null;
17292
17436
  #closed = false;
17437
+ #closePromise = null;
17293
17438
  #compactionActive = false;
17294
17439
  #compactionTurn = null;
17295
17440
  #compactionTimeout = null;
@@ -17340,7 +17485,8 @@ var PiRpcSession = class {
17340
17485
  }),
17341
17486
  ...this.#options.sessionFile ? { sessionFile: this.#options.sessionFile } : {},
17342
17487
  ...this.#options.forkSessionFile ? { forkSessionFile: this.#options.forkSessionFile } : {},
17343
- ...this.#options.model ? { model: this.#options.model } : {}
17488
+ ...this.#options.model ? { model: this.#options.model } : {},
17489
+ ...this.#options.emptySessionConfiguration ? { emptySessionConfiguration: this.#options.emptySessionConfiguration } : {}
17344
17490
  });
17345
17491
  this.#child = child;
17346
17492
  child.stdout.on("data", (chunk) => this.#push(chunk));
@@ -17597,12 +17743,13 @@ var PiRpcSession = class {
17597
17743
  this.#fail(fault);
17598
17744
  void this.close().catch(() => void 0);
17599
17745
  }
17600
- async close() {
17601
- if (this.#closed)
17602
- return;
17603
- this.#closed = true;
17604
- this.#rejectAll(new Error("Pi RPC Session closed"));
17605
- await this.#stopProcess();
17746
+ close() {
17747
+ if (!this.#closed) {
17748
+ this.#closed = true;
17749
+ this.#rejectAll(new Error("Pi RPC Session closed"));
17750
+ }
17751
+ this.#closePromise ??= this.#stopProcess();
17752
+ return this.#closePromise;
17606
17753
  }
17607
17754
  async #stopProcess() {
17608
17755
  const child = this.#child;
@@ -17766,7 +17913,7 @@ var PiRpcSession = class {
17766
17913
  const active = {
17767
17914
  origin: "autonomous",
17768
17915
  autonomousEvents: events,
17769
- nativeTurnKey: assistantMessageId(value) ?? randomUUID(),
17916
+ nativeTurnKey: assistantMessageId(value) ?? randomUUID2(),
17770
17917
  nativeCancellationObserved: false,
17771
17918
  text: "",
17772
17919
  assistantMessageId: null,
@@ -18009,7 +18156,7 @@ var PiRpcSession = class {
18009
18156
  if (active.assistantMessageId !== null && active.reasoningMessageOpen) {
18010
18157
  active.onEvent({ type: "reasoning.completed", messageId: active.assistantMessageId });
18011
18158
  }
18012
- const messageId = assistantMessageId(value) ?? randomUUID();
18159
+ const messageId = assistantMessageId(value) ?? randomUUID2();
18013
18160
  active.assistantMessageId = messageId;
18014
18161
  active.sawStreamedMessageText = false;
18015
18162
  active.sawStreamedMessageReasoning = false;
@@ -18070,7 +18217,7 @@ var PiRpcSession = class {
18070
18217
  if (!child?.stdin.writable || this.#closed || this.#failed) {
18071
18218
  return Promise.reject(new Error("Pi RPC stdin is unavailable"));
18072
18219
  }
18073
- const id = `codexhost-${randomUUID()}`;
18220
+ const id = `codexhost-${randomUUID2()}`;
18074
18221
  return new Promise((resolve, reject) => {
18075
18222
  const pending = {
18076
18223
  command: type,
@@ -18122,7 +18269,7 @@ var PiRpcSession = class {
18122
18269
  }
18123
18270
  let finalFault = fault;
18124
18271
  try {
18125
- await this.#stopProcess();
18272
+ await this.close();
18126
18273
  } catch (error51) {
18127
18274
  finalFault = new PiRpcFaultError("processExited", `Pi RPC timed-out Prompt cleanup failed: ${message2(error51)}`);
18128
18275
  }
@@ -18333,10 +18480,10 @@ function stripDiffPrefix(pathString) {
18333
18480
  return pathString.startsWith("a/") || pathString.startsWith("b/") ? pathString.slice(2) : pathString;
18334
18481
  }
18335
18482
  function displayPath(nativePath, cwd) {
18336
- const resolvedCwd = path5.resolve(cwd);
18337
- const resolvedPath = path5.isAbsolute(nativePath) ? path5.resolve(nativePath) : path5.resolve(cwd, nativePath);
18338
- const relative = path5.relative(resolvedCwd, resolvedPath);
18339
- const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path5.sep}`);
18483
+ const resolvedCwd = path6.resolve(cwd);
18484
+ const resolvedPath = path6.isAbsolute(nativePath) ? path6.resolve(nativePath) : path6.resolve(cwd, nativePath);
18485
+ const relative = path6.relative(resolvedCwd, resolvedPath);
18486
+ const inside = relative.length > 0 && relative !== ".." && !relative.startsWith(`..${path6.sep}`);
18340
18487
  const selected = inside ? relative : resolvedPath;
18341
18488
  const normalized = selected.replaceAll("\\", "/");
18342
18489
  if (normalized.length === 0 || normalized === ".")
@@ -19149,7 +19296,7 @@ var PiHarnessSession = class {
19149
19296
  }));
19150
19297
  return;
19151
19298
  }
19152
- const turnId = hostTurnIdSchema.parse(randomUUID2());
19299
+ const turnId = hostTurnIdSchema.parse(randomUUID3());
19153
19300
  let resolveCompletion = () => void 0;
19154
19301
  const completion = new Promise((resolve) => {
19155
19302
  resolveCompletion = resolve;
@@ -19311,7 +19458,7 @@ var PiHarnessSession = class {
19311
19458
  if (active.interactionByNativeId.has(request.requestId)) {
19312
19459
  throw new Error("Pi Interaction started more than once");
19313
19460
  }
19314
- const interactionId = hostInteractionIdSchema.parse(randomUUID2());
19461
+ const interactionId = hostInteractionIdSchema.parse(randomUUID3());
19315
19462
  const question = request.method === "select" ? {
19316
19463
  id: "answer",
19317
19464
  type: "choice",
@@ -19650,7 +19797,7 @@ var PiHarnessSession = class {
19650
19797
  this.#channel.emit({ kind: "event", event });
19651
19798
  }
19652
19799
  #newItemId() {
19653
- return hostItemIdSchema.parse(randomUUID2());
19800
+ return hostItemIdSchema.parse(randomUUID3());
19654
19801
  }
19655
19802
  };
19656
19803
  var PiAdapter = class {
@@ -19865,8 +20012,11 @@ var PiAdapter = class {
19865
20012
  });
19866
20013
  }
19867
20014
  }
20015
+ const emptySessionConfiguration = input.kind === "resume" ? await readPiEmptySessionConfiguration(sourceSessionFile) : void 0;
19868
20016
  transport = this.#createTransport({
19869
20017
  cwd: input.cwd,
20018
+ ...input.environment ? { environment: input.environment } : {},
20019
+ ...emptySessionConfiguration ? { emptySessionConfiguration } : {},
19870
20020
  ...input.kind === "resume" ? { sessionFile: sourceSessionFile } : { forkSessionFile: sourceSessionFile },
19871
20021
  onFault: (error51) => session?.handleTransportFault(error51)
19872
20022
  });
@@ -19918,6 +20068,45 @@ var PiAdapter = class {
19918
20068
  retryable: false
19919
20069
  });
19920
20070
  }
20071
+ if (rolledBack.unpersisted) {
20072
+ const state = transport.state;
20073
+ const history = await transport.getEntries();
20074
+ await transport.close();
20075
+ await persistEmptyPiSession({
20076
+ state,
20077
+ history,
20078
+ sourceSessionFile,
20079
+ sourceSessionId: sourceRef.nativeSessionId,
20080
+ cwd: input.cwd
20081
+ });
20082
+ if (!state.sessionFile)
20083
+ throw new Error("Pi empty fork has no Session file");
20084
+ const configuration = await readPiEmptySessionConfiguration(state.sessionFile);
20085
+ if (!configuration)
20086
+ throw new Error("Pi empty fork has no restorable configuration");
20087
+ transport = this.#createTransport({
20088
+ cwd: input.cwd,
20089
+ ...input.environment ? { environment: input.environment } : {},
20090
+ sessionFile: state.sessionFile,
20091
+ emptySessionConfiguration: configuration,
20092
+ onFault: (error51) => session?.handleTransportFault(error51)
20093
+ });
20094
+ await transport.start();
20095
+ if (transport.state.sessionId !== state.sessionId) {
20096
+ throw new Error("Pi empty fork resumed with a different identity");
20097
+ }
20098
+ const model = nativeModelFromState(state);
20099
+ if (model && !samePiModel(nativeModelFromState(transport.state), model)) {
20100
+ await transport.selectModel(model);
20101
+ }
20102
+ if (state.thinkingLevel && transport.state.thinkingLevel !== state.thinkingLevel) {
20103
+ await transport.selectThinkingOption(state.thinkingLevel);
20104
+ }
20105
+ if (!samePiModel(nativeModelFromState(transport.state), model) || transport.state.thinkingLevel !== state.thinkingLevel) {
20106
+ throw new Error("Pi empty fork could not restore its configuration");
20107
+ }
20108
+ await transport.verifySessionCwd(input.cwd);
20109
+ }
19921
20110
  }
19922
20111
  const startedThinkingLevels = await transport.getAvailableThinkingLevels();
19923
20112
  this.#thinkingSelectionSupported = startedThinkingLevels !== null;