@corca-org/ceal-host-linux-arm64 1.0.18 → 1.0.20

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.
@@ -1,6 +1,2036 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cealCreateRequire } from "node:module";
3
3
  const require = __cealCreateRequire(import.meta.url);
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12
+ }) : x)(function(x) {
13
+ if (typeof require !== "undefined") return require.apply(this, arguments);
14
+ throw Error('Dynamic require of "' + x + '" is not supported');
15
+ });
16
+ var __commonJS = (cb, mod) => function __require2() {
17
+ try {
18
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
+ } catch (e) {
20
+ throw mod = 0, e;
21
+ }
22
+ };
23
+ var __copyProps = (to, from, except, desc) => {
24
+ if (from && typeof from === "object" || typeof from === "function") {
25
+ for (let key of __getOwnPropNames(from))
26
+ if (!__hasOwnProp.call(to, key) && key !== except)
27
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28
+ }
29
+ return to;
30
+ };
31
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32
+ // If the importer is in node compatibility mode or this is not an ESM
33
+ // file that has been converted to a CommonJS file using a Babel-
34
+ // compatible transform (i.e. "__esModule" has not been set), then set
35
+ // "default" to the CommonJS "module.exports" for node compatibility.
36
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37
+ mod
38
+ ));
39
+
40
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/parser.js
41
+ var require_parser = __commonJS({
42
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/parser.js"(exports2, module2) {
43
+ "use strict";
44
+ var ParserEND = 1114112;
45
+ var ParserError = class _ParserError extends Error {
46
+ /* istanbul ignore next */
47
+ constructor(msg, filename, linenumber) {
48
+ super("[ParserError] " + msg, filename, linenumber);
49
+ this.name = "ParserError";
50
+ this.code = "ParserError";
51
+ if (Error.captureStackTrace) Error.captureStackTrace(this, _ParserError);
52
+ }
53
+ };
54
+ var State = class {
55
+ constructor(parser) {
56
+ this.parser = parser;
57
+ this.buf = "";
58
+ this.returned = null;
59
+ this.result = null;
60
+ this.resultTable = null;
61
+ this.resultArr = null;
62
+ }
63
+ };
64
+ var Parser = class {
65
+ constructor() {
66
+ this.pos = 0;
67
+ this.col = 0;
68
+ this.line = 0;
69
+ this.obj = {};
70
+ this.ctx = this.obj;
71
+ this.stack = [];
72
+ this._buf = "";
73
+ this.char = null;
74
+ this.ii = 0;
75
+ this.state = new State(this.parseStart);
76
+ }
77
+ parse(str) {
78
+ if (str.length === 0 || str.length == null) return;
79
+ this._buf = String(str);
80
+ this.ii = -1;
81
+ this.char = -1;
82
+ let getNext;
83
+ while (getNext === false || this.nextChar()) {
84
+ getNext = this.runOne();
85
+ }
86
+ this._buf = null;
87
+ }
88
+ nextChar() {
89
+ if (this.char === 10) {
90
+ ++this.line;
91
+ this.col = -1;
92
+ }
93
+ ++this.ii;
94
+ this.char = this._buf.codePointAt(this.ii);
95
+ ++this.pos;
96
+ ++this.col;
97
+ return this.haveBuffer();
98
+ }
99
+ haveBuffer() {
100
+ return this.ii < this._buf.length;
101
+ }
102
+ runOne() {
103
+ return this.state.parser.call(this, this.state.returned);
104
+ }
105
+ finish() {
106
+ this.char = ParserEND;
107
+ let last;
108
+ do {
109
+ last = this.state.parser;
110
+ this.runOne();
111
+ } while (this.state.parser !== last);
112
+ this.ctx = null;
113
+ this.state = null;
114
+ this._buf = null;
115
+ return this.obj;
116
+ }
117
+ next(fn) {
118
+ if (typeof fn !== "function") throw new ParserError("Tried to set state to non-existent state: " + JSON.stringify(fn));
119
+ this.state.parser = fn;
120
+ }
121
+ goto(fn) {
122
+ this.next(fn);
123
+ return this.runOne();
124
+ }
125
+ call(fn, returnWith) {
126
+ if (returnWith) this.next(returnWith);
127
+ this.stack.push(this.state);
128
+ this.state = new State(fn);
129
+ }
130
+ callNow(fn, returnWith) {
131
+ this.call(fn, returnWith);
132
+ return this.runOne();
133
+ }
134
+ return(value) {
135
+ if (this.stack.length === 0) throw this.error(new ParserError("Stack underflow"));
136
+ if (value === void 0) value = this.state.buf;
137
+ this.state = this.stack.pop();
138
+ this.state.returned = value;
139
+ }
140
+ returnNow(value) {
141
+ this.return(value);
142
+ return this.runOne();
143
+ }
144
+ consume() {
145
+ if (this.char === ParserEND) throw this.error(new ParserError("Unexpected end-of-buffer"));
146
+ this.state.buf += this._buf[this.ii];
147
+ }
148
+ error(err) {
149
+ err.line = this.line;
150
+ err.col = this.col;
151
+ err.pos = this.pos;
152
+ return err;
153
+ }
154
+ /* istanbul ignore next */
155
+ parseStart() {
156
+ throw new ParserError("Must declare a parseStart method");
157
+ }
158
+ };
159
+ Parser.END = ParserEND;
160
+ Parser.Error = ParserError;
161
+ module2.exports = Parser;
162
+ }
163
+ });
164
+
165
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime.js
166
+ var require_create_datetime = __commonJS({
167
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime.js"(exports2, module2) {
168
+ "use strict";
169
+ module2.exports = (value) => {
170
+ const date = new Date(value);
171
+ if (isNaN(date)) {
172
+ throw new TypeError("Invalid Datetime");
173
+ } else {
174
+ return date;
175
+ }
176
+ };
177
+ }
178
+ });
179
+
180
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/format-num.js
181
+ var require_format_num = __commonJS({
182
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/format-num.js"(exports2, module2) {
183
+ "use strict";
184
+ module2.exports = (d, num) => {
185
+ num = String(num);
186
+ while (num.length < d) num = "0" + num;
187
+ return num;
188
+ };
189
+ }
190
+ });
191
+
192
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime-float.js
193
+ var require_create_datetime_float = __commonJS({
194
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-datetime-float.js"(exports2, module2) {
195
+ "use strict";
196
+ var f = require_format_num();
197
+ var FloatingDateTime = class extends Date {
198
+ constructor(value) {
199
+ super(value + "Z");
200
+ this.isFloating = true;
201
+ }
202
+ toISOString() {
203
+ const date = `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`;
204
+ const time = `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`;
205
+ return `${date}T${time}`;
206
+ }
207
+ };
208
+ module2.exports = (value) => {
209
+ const date = new FloatingDateTime(value);
210
+ if (isNaN(date)) {
211
+ throw new TypeError("Invalid Datetime");
212
+ } else {
213
+ return date;
214
+ }
215
+ };
216
+ }
217
+ });
218
+
219
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-date.js
220
+ var require_create_date = __commonJS({
221
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-date.js"(exports2, module2) {
222
+ "use strict";
223
+ var f = require_format_num();
224
+ var DateTime = global.Date;
225
+ var Date2 = class extends DateTime {
226
+ constructor(value) {
227
+ super(value);
228
+ this.isDate = true;
229
+ }
230
+ toISOString() {
231
+ return `${this.getUTCFullYear()}-${f(2, this.getUTCMonth() + 1)}-${f(2, this.getUTCDate())}`;
232
+ }
233
+ };
234
+ module2.exports = (value) => {
235
+ const date = new Date2(value);
236
+ if (isNaN(date)) {
237
+ throw new TypeError("Invalid Datetime");
238
+ } else {
239
+ return date;
240
+ }
241
+ };
242
+ }
243
+ });
244
+
245
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-time.js
246
+ var require_create_time = __commonJS({
247
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/create-time.js"(exports2, module2) {
248
+ "use strict";
249
+ var f = require_format_num();
250
+ var Time = class extends Date {
251
+ constructor(value) {
252
+ super(`0000-01-01T${value}Z`);
253
+ this.isTime = true;
254
+ }
255
+ toISOString() {
256
+ return `${f(2, this.getUTCHours())}:${f(2, this.getUTCMinutes())}:${f(2, this.getUTCSeconds())}.${f(3, this.getUTCMilliseconds())}`;
257
+ }
258
+ };
259
+ module2.exports = (value) => {
260
+ const date = new Time(value);
261
+ if (isNaN(date)) {
262
+ throw new TypeError("Invalid Datetime");
263
+ } else {
264
+ return date;
265
+ }
266
+ };
267
+ }
268
+ });
269
+
270
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/toml-parser.js
271
+ var require_toml_parser = __commonJS({
272
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/lib/toml-parser.js"(exports, module) {
273
+ "use strict";
274
+ module.exports = makeParserClass(require_parser());
275
+ module.exports.makeParserClass = makeParserClass;
276
+ var TomlError = class _TomlError extends Error {
277
+ constructor(msg) {
278
+ super(msg);
279
+ this.name = "TomlError";
280
+ if (Error.captureStackTrace) Error.captureStackTrace(this, _TomlError);
281
+ this.fromTOML = true;
282
+ this.wrapped = null;
283
+ }
284
+ };
285
+ TomlError.wrap = (err) => {
286
+ const terr = new TomlError(err.message);
287
+ terr.code = err.code;
288
+ terr.wrapped = err;
289
+ return terr;
290
+ };
291
+ module.exports.TomlError = TomlError;
292
+ var createDateTime = require_create_datetime();
293
+ var createDateTimeFloat = require_create_datetime_float();
294
+ var createDate = require_create_date();
295
+ var createTime = require_create_time();
296
+ var CTRL_I = 9;
297
+ var CTRL_J = 10;
298
+ var CTRL_M = 13;
299
+ var CTRL_CHAR_BOUNDARY = 31;
300
+ var CHAR_SP = 32;
301
+ var CHAR_QUOT = 34;
302
+ var CHAR_NUM = 35;
303
+ var CHAR_APOS = 39;
304
+ var CHAR_PLUS = 43;
305
+ var CHAR_COMMA = 44;
306
+ var CHAR_HYPHEN = 45;
307
+ var CHAR_PERIOD = 46;
308
+ var CHAR_0 = 48;
309
+ var CHAR_1 = 49;
310
+ var CHAR_7 = 55;
311
+ var CHAR_9 = 57;
312
+ var CHAR_COLON = 58;
313
+ var CHAR_EQUALS = 61;
314
+ var CHAR_A = 65;
315
+ var CHAR_E = 69;
316
+ var CHAR_F = 70;
317
+ var CHAR_T = 84;
318
+ var CHAR_U = 85;
319
+ var CHAR_Z = 90;
320
+ var CHAR_LOWBAR = 95;
321
+ var CHAR_a = 97;
322
+ var CHAR_b = 98;
323
+ var CHAR_e = 101;
324
+ var CHAR_f = 102;
325
+ var CHAR_i = 105;
326
+ var CHAR_l = 108;
327
+ var CHAR_n = 110;
328
+ var CHAR_o = 111;
329
+ var CHAR_r = 114;
330
+ var CHAR_s = 115;
331
+ var CHAR_t = 116;
332
+ var CHAR_u = 117;
333
+ var CHAR_x = 120;
334
+ var CHAR_z = 122;
335
+ var CHAR_LCUB = 123;
336
+ var CHAR_RCUB = 125;
337
+ var CHAR_LSQB = 91;
338
+ var CHAR_BSOL = 92;
339
+ var CHAR_RSQB = 93;
340
+ var CHAR_DEL = 127;
341
+ var SURROGATE_FIRST = 55296;
342
+ var SURROGATE_LAST = 57343;
343
+ var escapes = {
344
+ [CHAR_b]: "\b",
345
+ [CHAR_t]: " ",
346
+ [CHAR_n]: "\n",
347
+ [CHAR_f]: "\f",
348
+ [CHAR_r]: "\r",
349
+ [CHAR_QUOT]: '"',
350
+ [CHAR_BSOL]: "\\"
351
+ };
352
+ function isDigit(cp) {
353
+ return cp >= CHAR_0 && cp <= CHAR_9;
354
+ }
355
+ function isHexit(cp) {
356
+ return cp >= CHAR_A && cp <= CHAR_F || cp >= CHAR_a && cp <= CHAR_f || cp >= CHAR_0 && cp <= CHAR_9;
357
+ }
358
+ function isBit(cp) {
359
+ return cp === CHAR_1 || cp === CHAR_0;
360
+ }
361
+ function isOctit(cp) {
362
+ return cp >= CHAR_0 && cp <= CHAR_7;
363
+ }
364
+ function isAlphaNumQuoteHyphen(cp) {
365
+ return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_APOS || cp === CHAR_QUOT || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN;
366
+ }
367
+ function isAlphaNumHyphen(cp) {
368
+ return cp >= CHAR_A && cp <= CHAR_Z || cp >= CHAR_a && cp <= CHAR_z || cp >= CHAR_0 && cp <= CHAR_9 || cp === CHAR_LOWBAR || cp === CHAR_HYPHEN;
369
+ }
370
+ var _type = /* @__PURE__ */ Symbol("type");
371
+ var _declared = /* @__PURE__ */ Symbol("declared");
372
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
373
+ var defineProperty = Object.defineProperty;
374
+ var descriptor = { configurable: true, enumerable: true, writable: true, value: void 0 };
375
+ function hasKey(obj, key) {
376
+ if (hasOwnProperty.call(obj, key)) return true;
377
+ if (key === "__proto__") defineProperty(obj, "__proto__", descriptor);
378
+ return false;
379
+ }
380
+ var INLINE_TABLE = /* @__PURE__ */ Symbol("inline-table");
381
+ function InlineTable() {
382
+ return Object.defineProperties({}, {
383
+ [_type]: { value: INLINE_TABLE }
384
+ });
385
+ }
386
+ function isInlineTable(obj) {
387
+ if (obj === null || typeof obj !== "object") return false;
388
+ return obj[_type] === INLINE_TABLE;
389
+ }
390
+ var TABLE = /* @__PURE__ */ Symbol("table");
391
+ function Table() {
392
+ return Object.defineProperties({}, {
393
+ [_type]: { value: TABLE },
394
+ [_declared]: { value: false, writable: true }
395
+ });
396
+ }
397
+ function isTable(obj) {
398
+ if (obj === null || typeof obj !== "object") return false;
399
+ return obj[_type] === TABLE;
400
+ }
401
+ var _contentType = /* @__PURE__ */ Symbol("content-type");
402
+ var INLINE_LIST = /* @__PURE__ */ Symbol("inline-list");
403
+ function InlineList(type) {
404
+ return Object.defineProperties([], {
405
+ [_type]: { value: INLINE_LIST },
406
+ [_contentType]: { value: type }
407
+ });
408
+ }
409
+ function isInlineList(obj) {
410
+ if (obj === null || typeof obj !== "object") return false;
411
+ return obj[_type] === INLINE_LIST;
412
+ }
413
+ var LIST = /* @__PURE__ */ Symbol("list");
414
+ function List() {
415
+ return Object.defineProperties([], {
416
+ [_type]: { value: LIST }
417
+ });
418
+ }
419
+ function isList(obj) {
420
+ if (obj === null || typeof obj !== "object") return false;
421
+ return obj[_type] === LIST;
422
+ }
423
+ var _custom;
424
+ try {
425
+ const utilInspect = eval("require('util').inspect");
426
+ _custom = utilInspect.custom;
427
+ } catch (_) {
428
+ }
429
+ var _inspect = _custom || "inspect";
430
+ var BoxedBigInt = class {
431
+ constructor(value) {
432
+ try {
433
+ this.value = global.BigInt.asIntN(64, value);
434
+ } catch (_) {
435
+ this.value = null;
436
+ }
437
+ Object.defineProperty(this, _type, { value: INTEGER });
438
+ }
439
+ isNaN() {
440
+ return this.value === null;
441
+ }
442
+ /* istanbul ignore next */
443
+ toString() {
444
+ return String(this.value);
445
+ }
446
+ /* istanbul ignore next */
447
+ [_inspect]() {
448
+ return `[BigInt: ${this.toString()}]}`;
449
+ }
450
+ valueOf() {
451
+ return this.value;
452
+ }
453
+ };
454
+ var INTEGER = /* @__PURE__ */ Symbol("integer");
455
+ function Integer(value) {
456
+ let num = Number(value);
457
+ if (Object.is(num, -0)) num = 0;
458
+ if (global.BigInt && !Number.isSafeInteger(num)) {
459
+ return new BoxedBigInt(value);
460
+ } else {
461
+ return Object.defineProperties(new Number(num), {
462
+ isNaN: { value: function() {
463
+ return isNaN(this);
464
+ } },
465
+ [_type]: { value: INTEGER },
466
+ [_inspect]: { value: () => `[Integer: ${value}]` }
467
+ });
468
+ }
469
+ }
470
+ function isInteger(obj) {
471
+ if (obj === null || typeof obj !== "object") return false;
472
+ return obj[_type] === INTEGER;
473
+ }
474
+ var FLOAT = /* @__PURE__ */ Symbol("float");
475
+ function Float(value) {
476
+ return Object.defineProperties(new Number(value), {
477
+ [_type]: { value: FLOAT },
478
+ [_inspect]: { value: () => `[Float: ${value}]` }
479
+ });
480
+ }
481
+ function isFloat(obj) {
482
+ if (obj === null || typeof obj !== "object") return false;
483
+ return obj[_type] === FLOAT;
484
+ }
485
+ function tomlType(value) {
486
+ const type = typeof value;
487
+ if (type === "object") {
488
+ if (value === null) return "null";
489
+ if (value instanceof Date) return "datetime";
490
+ if (_type in value) {
491
+ switch (value[_type]) {
492
+ case INLINE_TABLE:
493
+ return "inline-table";
494
+ case INLINE_LIST:
495
+ return "inline-list";
496
+ /* istanbul ignore next */
497
+ case TABLE:
498
+ return "table";
499
+ /* istanbul ignore next */
500
+ case LIST:
501
+ return "list";
502
+ case FLOAT:
503
+ return "float";
504
+ case INTEGER:
505
+ return "integer";
506
+ }
507
+ }
508
+ }
509
+ return type;
510
+ }
511
+ function makeParserClass(Parser) {
512
+ class TOMLParser extends Parser {
513
+ constructor() {
514
+ super();
515
+ this.ctx = this.obj = Table();
516
+ }
517
+ /* MATCH HELPER */
518
+ atEndOfWord() {
519
+ return this.char === CHAR_NUM || this.char === CTRL_I || this.char === CHAR_SP || this.atEndOfLine();
520
+ }
521
+ atEndOfLine() {
522
+ return this.char === Parser.END || this.char === CTRL_J || this.char === CTRL_M;
523
+ }
524
+ parseStart() {
525
+ if (this.char === Parser.END) {
526
+ return null;
527
+ } else if (this.char === CHAR_LSQB) {
528
+ return this.call(this.parseTableOrList);
529
+ } else if (this.char === CHAR_NUM) {
530
+ return this.call(this.parseComment);
531
+ } else if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
532
+ return null;
533
+ } else if (isAlphaNumQuoteHyphen(this.char)) {
534
+ return this.callNow(this.parseAssignStatement);
535
+ } else {
536
+ throw this.error(new TomlError(`Unknown character "${this.char}"`));
537
+ }
538
+ }
539
+ // HELPER, this strips any whitespace and comments to the end of the line
540
+ // then RETURNS. Last state in a production.
541
+ parseWhitespaceToEOL() {
542
+ if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
543
+ return null;
544
+ } else if (this.char === CHAR_NUM) {
545
+ return this.goto(this.parseComment);
546
+ } else if (this.char === Parser.END || this.char === CTRL_J) {
547
+ return this.return();
548
+ } else {
549
+ throw this.error(new TomlError("Unexpected character, expected only whitespace or comments till end of line"));
550
+ }
551
+ }
552
+ /* ASSIGNMENT: key = value */
553
+ parseAssignStatement() {
554
+ return this.callNow(this.parseAssign, this.recordAssignStatement);
555
+ }
556
+ recordAssignStatement(kv) {
557
+ let target = this.ctx;
558
+ let finalKey = kv.key.pop();
559
+ for (let kw of kv.key) {
560
+ if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) {
561
+ throw this.error(new TomlError("Can't redefine existing key"));
562
+ }
563
+ target = target[kw] = target[kw] || Table();
564
+ }
565
+ if (hasKey(target, finalKey)) {
566
+ throw this.error(new TomlError("Can't redefine existing key"));
567
+ }
568
+ if (isInteger(kv.value) || isFloat(kv.value)) {
569
+ target[finalKey] = kv.value.valueOf();
570
+ } else {
571
+ target[finalKey] = kv.value;
572
+ }
573
+ return this.goto(this.parseWhitespaceToEOL);
574
+ }
575
+ /* ASSSIGNMENT expression, key = value possibly inside an inline table */
576
+ parseAssign() {
577
+ return this.callNow(this.parseKeyword, this.recordAssignKeyword);
578
+ }
579
+ recordAssignKeyword(key) {
580
+ if (this.state.resultTable) {
581
+ this.state.resultTable.push(key);
582
+ } else {
583
+ this.state.resultTable = [key];
584
+ }
585
+ return this.goto(this.parseAssignKeywordPreDot);
586
+ }
587
+ parseAssignKeywordPreDot() {
588
+ if (this.char === CHAR_PERIOD) {
589
+ return this.next(this.parseAssignKeywordPostDot);
590
+ } else if (this.char !== CHAR_SP && this.char !== CTRL_I) {
591
+ return this.goto(this.parseAssignEqual);
592
+ }
593
+ }
594
+ parseAssignKeywordPostDot() {
595
+ if (this.char !== CHAR_SP && this.char !== CTRL_I) {
596
+ return this.callNow(this.parseKeyword, this.recordAssignKeyword);
597
+ }
598
+ }
599
+ parseAssignEqual() {
600
+ if (this.char === CHAR_EQUALS) {
601
+ return this.next(this.parseAssignPreValue);
602
+ } else {
603
+ throw this.error(new TomlError('Invalid character, expected "="'));
604
+ }
605
+ }
606
+ parseAssignPreValue() {
607
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
608
+ return null;
609
+ } else {
610
+ return this.callNow(this.parseValue, this.recordAssignValue);
611
+ }
612
+ }
613
+ recordAssignValue(value) {
614
+ return this.returnNow({ key: this.state.resultTable, value });
615
+ }
616
+ /* COMMENTS: #...eol */
617
+ parseComment() {
618
+ do {
619
+ if (this.char === Parser.END || this.char === CTRL_J) {
620
+ return this.return();
621
+ }
622
+ } while (this.nextChar());
623
+ }
624
+ /* TABLES AND LISTS, [foo] and [[foo]] */
625
+ parseTableOrList() {
626
+ if (this.char === CHAR_LSQB) {
627
+ this.next(this.parseList);
628
+ } else {
629
+ return this.goto(this.parseTable);
630
+ }
631
+ }
632
+ /* TABLE [foo.bar.baz] */
633
+ parseTable() {
634
+ this.ctx = this.obj;
635
+ return this.goto(this.parseTableNext);
636
+ }
637
+ parseTableNext() {
638
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
639
+ return null;
640
+ } else {
641
+ return this.callNow(this.parseKeyword, this.parseTableMore);
642
+ }
643
+ }
644
+ parseTableMore(keyword) {
645
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
646
+ return null;
647
+ } else if (this.char === CHAR_RSQB) {
648
+ if (hasKey(this.ctx, keyword) && (!isTable(this.ctx[keyword]) || this.ctx[keyword][_declared])) {
649
+ throw this.error(new TomlError("Can't redefine existing key"));
650
+ } else {
651
+ this.ctx = this.ctx[keyword] = this.ctx[keyword] || Table();
652
+ this.ctx[_declared] = true;
653
+ }
654
+ return this.next(this.parseWhitespaceToEOL);
655
+ } else if (this.char === CHAR_PERIOD) {
656
+ if (!hasKey(this.ctx, keyword)) {
657
+ this.ctx = this.ctx[keyword] = Table();
658
+ } else if (isTable(this.ctx[keyword])) {
659
+ this.ctx = this.ctx[keyword];
660
+ } else if (isList(this.ctx[keyword])) {
661
+ this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1];
662
+ } else {
663
+ throw this.error(new TomlError("Can't redefine existing key"));
664
+ }
665
+ return this.next(this.parseTableNext);
666
+ } else {
667
+ throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
668
+ }
669
+ }
670
+ /* LIST [[a.b.c]] */
671
+ parseList() {
672
+ this.ctx = this.obj;
673
+ return this.goto(this.parseListNext);
674
+ }
675
+ parseListNext() {
676
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
677
+ return null;
678
+ } else {
679
+ return this.callNow(this.parseKeyword, this.parseListMore);
680
+ }
681
+ }
682
+ parseListMore(keyword) {
683
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
684
+ return null;
685
+ } else if (this.char === CHAR_RSQB) {
686
+ if (!hasKey(this.ctx, keyword)) {
687
+ this.ctx[keyword] = List();
688
+ }
689
+ if (isInlineList(this.ctx[keyword])) {
690
+ throw this.error(new TomlError("Can't extend an inline array"));
691
+ } else if (isList(this.ctx[keyword])) {
692
+ const next = Table();
693
+ this.ctx[keyword].push(next);
694
+ this.ctx = next;
695
+ } else {
696
+ throw this.error(new TomlError("Can't redefine an existing key"));
697
+ }
698
+ return this.next(this.parseListEnd);
699
+ } else if (this.char === CHAR_PERIOD) {
700
+ if (!hasKey(this.ctx, keyword)) {
701
+ this.ctx = this.ctx[keyword] = Table();
702
+ } else if (isInlineList(this.ctx[keyword])) {
703
+ throw this.error(new TomlError("Can't extend an inline array"));
704
+ } else if (isInlineTable(this.ctx[keyword])) {
705
+ throw this.error(new TomlError("Can't extend an inline table"));
706
+ } else if (isList(this.ctx[keyword])) {
707
+ this.ctx = this.ctx[keyword][this.ctx[keyword].length - 1];
708
+ } else if (isTable(this.ctx[keyword])) {
709
+ this.ctx = this.ctx[keyword];
710
+ } else {
711
+ throw this.error(new TomlError("Can't redefine an existing key"));
712
+ }
713
+ return this.next(this.parseListNext);
714
+ } else {
715
+ throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
716
+ }
717
+ }
718
+ parseListEnd(keyword) {
719
+ if (this.char === CHAR_RSQB) {
720
+ return this.next(this.parseWhitespaceToEOL);
721
+ } else {
722
+ throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));
723
+ }
724
+ }
725
+ /* VALUE string, number, boolean, inline list, inline object */
726
+ parseValue() {
727
+ if (this.char === Parser.END) {
728
+ throw this.error(new TomlError("Key without value"));
729
+ } else if (this.char === CHAR_QUOT) {
730
+ return this.next(this.parseDoubleString);
731
+ }
732
+ if (this.char === CHAR_APOS) {
733
+ return this.next(this.parseSingleString);
734
+ } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
735
+ return this.goto(this.parseNumberSign);
736
+ } else if (this.char === CHAR_i) {
737
+ return this.next(this.parseInf);
738
+ } else if (this.char === CHAR_n) {
739
+ return this.next(this.parseNan);
740
+ } else if (isDigit(this.char)) {
741
+ return this.goto(this.parseNumberOrDateTime);
742
+ } else if (this.char === CHAR_t || this.char === CHAR_f) {
743
+ return this.goto(this.parseBoolean);
744
+ } else if (this.char === CHAR_LSQB) {
745
+ return this.call(this.parseInlineList, this.recordValue);
746
+ } else if (this.char === CHAR_LCUB) {
747
+ return this.call(this.parseInlineTable, this.recordValue);
748
+ } else {
749
+ throw this.error(new TomlError("Unexpected character, expecting string, number, datetime, boolean, inline array or inline table"));
750
+ }
751
+ }
752
+ recordValue(value) {
753
+ return this.returnNow(value);
754
+ }
755
+ parseInf() {
756
+ if (this.char === CHAR_n) {
757
+ return this.next(this.parseInf2);
758
+ } else {
759
+ throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'));
760
+ }
761
+ }
762
+ parseInf2() {
763
+ if (this.char === CHAR_f) {
764
+ if (this.state.buf === "-") {
765
+ return this.return(-Infinity);
766
+ } else {
767
+ return this.return(Infinity);
768
+ }
769
+ } else {
770
+ throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'));
771
+ }
772
+ }
773
+ parseNan() {
774
+ if (this.char === CHAR_a) {
775
+ return this.next(this.parseNan2);
776
+ } else {
777
+ throw this.error(new TomlError('Unexpected character, expected "nan"'));
778
+ }
779
+ }
780
+ parseNan2() {
781
+ if (this.char === CHAR_n) {
782
+ return this.return(NaN);
783
+ } else {
784
+ throw this.error(new TomlError('Unexpected character, expected "nan"'));
785
+ }
786
+ }
787
+ /* KEYS, barewords or basic, literal, or dotted */
788
+ parseKeyword() {
789
+ if (this.char === CHAR_QUOT) {
790
+ return this.next(this.parseBasicString);
791
+ } else if (this.char === CHAR_APOS) {
792
+ return this.next(this.parseLiteralString);
793
+ } else {
794
+ return this.goto(this.parseBareKey);
795
+ }
796
+ }
797
+ /* KEYS: barewords */
798
+ parseBareKey() {
799
+ do {
800
+ if (this.char === Parser.END) {
801
+ throw this.error(new TomlError("Key ended without value"));
802
+ } else if (isAlphaNumHyphen(this.char)) {
803
+ this.consume();
804
+ } else if (this.state.buf.length === 0) {
805
+ throw this.error(new TomlError("Empty bare keys are not allowed"));
806
+ } else {
807
+ return this.returnNow();
808
+ }
809
+ } while (this.nextChar());
810
+ }
811
+ /* STRINGS, single quoted (literal) */
812
+ parseSingleString() {
813
+ if (this.char === CHAR_APOS) {
814
+ return this.next(this.parseLiteralMultiStringMaybe);
815
+ } else {
816
+ return this.goto(this.parseLiteralString);
817
+ }
818
+ }
819
+ parseLiteralString() {
820
+ do {
821
+ if (this.char === CHAR_APOS) {
822
+ return this.return();
823
+ } else if (this.atEndOfLine()) {
824
+ throw this.error(new TomlError("Unterminated string"));
825
+ } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) {
826
+ throw this.errorControlCharInString();
827
+ } else {
828
+ this.consume();
829
+ }
830
+ } while (this.nextChar());
831
+ }
832
+ parseLiteralMultiStringMaybe() {
833
+ if (this.char === CHAR_APOS) {
834
+ return this.next(this.parseLiteralMultiString);
835
+ } else {
836
+ return this.returnNow();
837
+ }
838
+ }
839
+ parseLiteralMultiString() {
840
+ if (this.char === CTRL_M) {
841
+ return null;
842
+ } else if (this.char === CTRL_J) {
843
+ return this.next(this.parseLiteralMultiStringContent);
844
+ } else {
845
+ return this.goto(this.parseLiteralMultiStringContent);
846
+ }
847
+ }
848
+ parseLiteralMultiStringContent() {
849
+ do {
850
+ if (this.char === CHAR_APOS) {
851
+ return this.next(this.parseLiteralMultiEnd);
852
+ } else if (this.char === Parser.END) {
853
+ throw this.error(new TomlError("Unterminated multi-line string"));
854
+ } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) {
855
+ throw this.errorControlCharInString();
856
+ } else {
857
+ this.consume();
858
+ }
859
+ } while (this.nextChar());
860
+ }
861
+ parseLiteralMultiEnd() {
862
+ if (this.char === CHAR_APOS) {
863
+ return this.next(this.parseLiteralMultiEnd2);
864
+ } else {
865
+ this.state.buf += "'";
866
+ return this.goto(this.parseLiteralMultiStringContent);
867
+ }
868
+ }
869
+ parseLiteralMultiEnd2() {
870
+ if (this.char === CHAR_APOS) {
871
+ return this.return();
872
+ } else {
873
+ this.state.buf += "''";
874
+ return this.goto(this.parseLiteralMultiStringContent);
875
+ }
876
+ }
877
+ /* STRINGS double quoted */
878
+ parseDoubleString() {
879
+ if (this.char === CHAR_QUOT) {
880
+ return this.next(this.parseMultiStringMaybe);
881
+ } else {
882
+ return this.goto(this.parseBasicString);
883
+ }
884
+ }
885
+ parseBasicString() {
886
+ do {
887
+ if (this.char === CHAR_BSOL) {
888
+ return this.call(this.parseEscape, this.recordEscapeReplacement);
889
+ } else if (this.char === CHAR_QUOT) {
890
+ return this.return();
891
+ } else if (this.atEndOfLine()) {
892
+ throw this.error(new TomlError("Unterminated string"));
893
+ } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I) {
894
+ throw this.errorControlCharInString();
895
+ } else {
896
+ this.consume();
897
+ }
898
+ } while (this.nextChar());
899
+ }
900
+ recordEscapeReplacement(replacement) {
901
+ this.state.buf += replacement;
902
+ return this.goto(this.parseBasicString);
903
+ }
904
+ parseMultiStringMaybe() {
905
+ if (this.char === CHAR_QUOT) {
906
+ return this.next(this.parseMultiString);
907
+ } else {
908
+ return this.returnNow();
909
+ }
910
+ }
911
+ parseMultiString() {
912
+ if (this.char === CTRL_M) {
913
+ return null;
914
+ } else if (this.char === CTRL_J) {
915
+ return this.next(this.parseMultiStringContent);
916
+ } else {
917
+ return this.goto(this.parseMultiStringContent);
918
+ }
919
+ }
920
+ parseMultiStringContent() {
921
+ do {
922
+ if (this.char === CHAR_BSOL) {
923
+ return this.call(this.parseMultiEscape, this.recordMultiEscapeReplacement);
924
+ } else if (this.char === CHAR_QUOT) {
925
+ return this.next(this.parseMultiEnd);
926
+ } else if (this.char === Parser.END) {
927
+ throw this.error(new TomlError("Unterminated multi-line string"));
928
+ } else if (this.char === CHAR_DEL || this.char <= CTRL_CHAR_BOUNDARY && this.char !== CTRL_I && this.char !== CTRL_J && this.char !== CTRL_M) {
929
+ throw this.errorControlCharInString();
930
+ } else {
931
+ this.consume();
932
+ }
933
+ } while (this.nextChar());
934
+ }
935
+ errorControlCharInString() {
936
+ let displayCode = "\\u00";
937
+ if (this.char < 16) {
938
+ displayCode += "0";
939
+ }
940
+ displayCode += this.char.toString(16);
941
+ return this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in strings, use ${displayCode} instead`));
942
+ }
943
+ recordMultiEscapeReplacement(replacement) {
944
+ this.state.buf += replacement;
945
+ return this.goto(this.parseMultiStringContent);
946
+ }
947
+ parseMultiEnd() {
948
+ if (this.char === CHAR_QUOT) {
949
+ return this.next(this.parseMultiEnd2);
950
+ } else {
951
+ this.state.buf += '"';
952
+ return this.goto(this.parseMultiStringContent);
953
+ }
954
+ }
955
+ parseMultiEnd2() {
956
+ if (this.char === CHAR_QUOT) {
957
+ return this.return();
958
+ } else {
959
+ this.state.buf += '""';
960
+ return this.goto(this.parseMultiStringContent);
961
+ }
962
+ }
963
+ parseMultiEscape() {
964
+ if (this.char === CTRL_M || this.char === CTRL_J) {
965
+ return this.next(this.parseMultiTrim);
966
+ } else if (this.char === CHAR_SP || this.char === CTRL_I) {
967
+ return this.next(this.parsePreMultiTrim);
968
+ } else {
969
+ return this.goto(this.parseEscape);
970
+ }
971
+ }
972
+ parsePreMultiTrim() {
973
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
974
+ return null;
975
+ } else if (this.char === CTRL_M || this.char === CTRL_J) {
976
+ return this.next(this.parseMultiTrim);
977
+ } else {
978
+ throw this.error(new TomlError("Can't escape whitespace"));
979
+ }
980
+ }
981
+ parseMultiTrim() {
982
+ if (this.char === CTRL_J || this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M) {
983
+ return null;
984
+ } else {
985
+ return this.returnNow();
986
+ }
987
+ }
988
+ parseEscape() {
989
+ if (this.char in escapes) {
990
+ return this.return(escapes[this.char]);
991
+ } else if (this.char === CHAR_u) {
992
+ return this.call(this.parseSmallUnicode, this.parseUnicodeReturn);
993
+ } else if (this.char === CHAR_U) {
994
+ return this.call(this.parseLargeUnicode, this.parseUnicodeReturn);
995
+ } else {
996
+ throw this.error(new TomlError("Unknown escape character: " + this.char));
997
+ }
998
+ }
999
+ parseUnicodeReturn(char) {
1000
+ try {
1001
+ const codePoint = parseInt(char, 16);
1002
+ if (codePoint >= SURROGATE_FIRST && codePoint <= SURROGATE_LAST) {
1003
+ throw this.error(new TomlError("Invalid unicode, character in range 0xD800 - 0xDFFF is reserved"));
1004
+ }
1005
+ return this.returnNow(String.fromCodePoint(codePoint));
1006
+ } catch (err) {
1007
+ throw this.error(TomlError.wrap(err));
1008
+ }
1009
+ }
1010
+ parseSmallUnicode() {
1011
+ if (!isHexit(this.char)) {
1012
+ throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));
1013
+ } else {
1014
+ this.consume();
1015
+ if (this.state.buf.length >= 4) return this.return();
1016
+ }
1017
+ }
1018
+ parseLargeUnicode() {
1019
+ if (!isHexit(this.char)) {
1020
+ throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));
1021
+ } else {
1022
+ this.consume();
1023
+ if (this.state.buf.length >= 8) return this.return();
1024
+ }
1025
+ }
1026
+ /* NUMBERS */
1027
+ parseNumberSign() {
1028
+ this.consume();
1029
+ return this.next(this.parseMaybeSignedInfOrNan);
1030
+ }
1031
+ parseMaybeSignedInfOrNan() {
1032
+ if (this.char === CHAR_i) {
1033
+ return this.next(this.parseInf);
1034
+ } else if (this.char === CHAR_n) {
1035
+ return this.next(this.parseNan);
1036
+ } else {
1037
+ return this.callNow(this.parseNoUnder, this.parseNumberIntegerStart);
1038
+ }
1039
+ }
1040
+ parseNumberIntegerStart() {
1041
+ if (this.char === CHAR_0) {
1042
+ this.consume();
1043
+ return this.next(this.parseNumberIntegerExponentOrDecimal);
1044
+ } else {
1045
+ return this.goto(this.parseNumberInteger);
1046
+ }
1047
+ }
1048
+ parseNumberIntegerExponentOrDecimal() {
1049
+ if (this.char === CHAR_PERIOD) {
1050
+ this.consume();
1051
+ return this.call(this.parseNoUnder, this.parseNumberFloat);
1052
+ } else if (this.char === CHAR_E || this.char === CHAR_e) {
1053
+ this.consume();
1054
+ return this.next(this.parseNumberExponentSign);
1055
+ } else {
1056
+ return this.returnNow(Integer(this.state.buf));
1057
+ }
1058
+ }
1059
+ parseNumberInteger() {
1060
+ if (isDigit(this.char)) {
1061
+ this.consume();
1062
+ } else if (this.char === CHAR_LOWBAR) {
1063
+ return this.call(this.parseNoUnder);
1064
+ } else if (this.char === CHAR_E || this.char === CHAR_e) {
1065
+ this.consume();
1066
+ return this.next(this.parseNumberExponentSign);
1067
+ } else if (this.char === CHAR_PERIOD) {
1068
+ this.consume();
1069
+ return this.call(this.parseNoUnder, this.parseNumberFloat);
1070
+ } else {
1071
+ const result = Integer(this.state.buf);
1072
+ if (result.isNaN()) {
1073
+ throw this.error(new TomlError("Invalid number"));
1074
+ } else {
1075
+ return this.returnNow(result);
1076
+ }
1077
+ }
1078
+ }
1079
+ parseNoUnder() {
1080
+ if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD || this.char === CHAR_E || this.char === CHAR_e) {
1081
+ throw this.error(new TomlError("Unexpected character, expected digit"));
1082
+ } else if (this.atEndOfWord()) {
1083
+ throw this.error(new TomlError("Incomplete number"));
1084
+ }
1085
+ return this.returnNow();
1086
+ }
1087
+ parseNoUnderHexOctBinLiteral() {
1088
+ if (this.char === CHAR_LOWBAR || this.char === CHAR_PERIOD) {
1089
+ throw this.error(new TomlError("Unexpected character, expected digit"));
1090
+ } else if (this.atEndOfWord()) {
1091
+ throw this.error(new TomlError("Incomplete number"));
1092
+ }
1093
+ return this.returnNow();
1094
+ }
1095
+ parseNumberFloat() {
1096
+ if (this.char === CHAR_LOWBAR) {
1097
+ return this.call(this.parseNoUnder, this.parseNumberFloat);
1098
+ } else if (isDigit(this.char)) {
1099
+ this.consume();
1100
+ } else if (this.char === CHAR_E || this.char === CHAR_e) {
1101
+ this.consume();
1102
+ return this.next(this.parseNumberExponentSign);
1103
+ } else {
1104
+ return this.returnNow(Float(this.state.buf));
1105
+ }
1106
+ }
1107
+ parseNumberExponentSign() {
1108
+ if (isDigit(this.char)) {
1109
+ return this.goto(this.parseNumberExponent);
1110
+ } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
1111
+ this.consume();
1112
+ this.call(this.parseNoUnder, this.parseNumberExponent);
1113
+ } else {
1114
+ throw this.error(new TomlError("Unexpected character, expected -, + or digit"));
1115
+ }
1116
+ }
1117
+ parseNumberExponent() {
1118
+ if (isDigit(this.char)) {
1119
+ this.consume();
1120
+ } else if (this.char === CHAR_LOWBAR) {
1121
+ return this.call(this.parseNoUnder);
1122
+ } else {
1123
+ return this.returnNow(Float(this.state.buf));
1124
+ }
1125
+ }
1126
+ /* NUMBERS or DATETIMES */
1127
+ parseNumberOrDateTime() {
1128
+ if (this.char === CHAR_0) {
1129
+ this.consume();
1130
+ return this.next(this.parseNumberBaseOrDateTime);
1131
+ } else {
1132
+ return this.goto(this.parseNumberOrDateTimeOnly);
1133
+ }
1134
+ }
1135
+ parseNumberOrDateTimeOnly() {
1136
+ if (this.char === CHAR_LOWBAR) {
1137
+ return this.call(this.parseNoUnder, this.parseNumberInteger);
1138
+ } else if (isDigit(this.char)) {
1139
+ this.consume();
1140
+ if (this.state.buf.length > 4) this.next(this.parseNumberInteger);
1141
+ } else if (this.char === CHAR_E || this.char === CHAR_e) {
1142
+ this.consume();
1143
+ return this.next(this.parseNumberExponentSign);
1144
+ } else if (this.char === CHAR_PERIOD) {
1145
+ this.consume();
1146
+ return this.call(this.parseNoUnder, this.parseNumberFloat);
1147
+ } else if (this.char === CHAR_HYPHEN) {
1148
+ return this.goto(this.parseDateTime);
1149
+ } else if (this.char === CHAR_COLON) {
1150
+ return this.goto(this.parseOnlyTimeHour);
1151
+ } else {
1152
+ return this.returnNow(Integer(this.state.buf));
1153
+ }
1154
+ }
1155
+ parseDateTimeOnly() {
1156
+ if (this.state.buf.length < 4) {
1157
+ if (isDigit(this.char)) {
1158
+ return this.consume();
1159
+ } else if (this.char === CHAR_COLON) {
1160
+ return this.goto(this.parseOnlyTimeHour);
1161
+ } else {
1162
+ throw this.error(new TomlError("Expected digit while parsing year part of a date"));
1163
+ }
1164
+ } else {
1165
+ if (this.char === CHAR_HYPHEN) {
1166
+ return this.goto(this.parseDateTime);
1167
+ } else {
1168
+ throw this.error(new TomlError("Expected hyphen (-) while parsing year part of date"));
1169
+ }
1170
+ }
1171
+ }
1172
+ parseNumberBaseOrDateTime() {
1173
+ if (this.char === CHAR_b) {
1174
+ this.consume();
1175
+ return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerBin);
1176
+ } else if (this.char === CHAR_o) {
1177
+ this.consume();
1178
+ return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerOct);
1179
+ } else if (this.char === CHAR_x) {
1180
+ this.consume();
1181
+ return this.call(this.parseNoUnderHexOctBinLiteral, this.parseIntegerHex);
1182
+ } else if (this.char === CHAR_PERIOD) {
1183
+ return this.goto(this.parseNumberInteger);
1184
+ } else if (isDigit(this.char)) {
1185
+ return this.goto(this.parseDateTimeOnly);
1186
+ } else {
1187
+ return this.returnNow(Integer(this.state.buf));
1188
+ }
1189
+ }
1190
+ parseIntegerHex() {
1191
+ if (isHexit(this.char)) {
1192
+ this.consume();
1193
+ } else if (this.char === CHAR_LOWBAR) {
1194
+ return this.call(this.parseNoUnderHexOctBinLiteral);
1195
+ } else {
1196
+ const result = Integer(this.state.buf);
1197
+ if (result.isNaN()) {
1198
+ throw this.error(new TomlError("Invalid number"));
1199
+ } else {
1200
+ return this.returnNow(result);
1201
+ }
1202
+ }
1203
+ }
1204
+ parseIntegerOct() {
1205
+ if (isOctit(this.char)) {
1206
+ this.consume();
1207
+ } else if (this.char === CHAR_LOWBAR) {
1208
+ return this.call(this.parseNoUnderHexOctBinLiteral);
1209
+ } else {
1210
+ const result = Integer(this.state.buf);
1211
+ if (result.isNaN()) {
1212
+ throw this.error(new TomlError("Invalid number"));
1213
+ } else {
1214
+ return this.returnNow(result);
1215
+ }
1216
+ }
1217
+ }
1218
+ parseIntegerBin() {
1219
+ if (isBit(this.char)) {
1220
+ this.consume();
1221
+ } else if (this.char === CHAR_LOWBAR) {
1222
+ return this.call(this.parseNoUnderHexOctBinLiteral);
1223
+ } else {
1224
+ const result = Integer(this.state.buf);
1225
+ if (result.isNaN()) {
1226
+ throw this.error(new TomlError("Invalid number"));
1227
+ } else {
1228
+ return this.returnNow(result);
1229
+ }
1230
+ }
1231
+ }
1232
+ /* DATETIME */
1233
+ parseDateTime() {
1234
+ if (this.state.buf.length < 4) {
1235
+ throw this.error(new TomlError("Years less than 1000 must be zero padded to four characters"));
1236
+ }
1237
+ this.state.result = this.state.buf;
1238
+ this.state.buf = "";
1239
+ return this.next(this.parseDateMonth);
1240
+ }
1241
+ parseDateMonth() {
1242
+ if (this.char === CHAR_HYPHEN) {
1243
+ if (this.state.buf.length < 2) {
1244
+ throw this.error(new TomlError("Months less than 10 must be zero padded to two characters"));
1245
+ }
1246
+ this.state.result += "-" + this.state.buf;
1247
+ this.state.buf = "";
1248
+ return this.next(this.parseDateDay);
1249
+ } else if (isDigit(this.char)) {
1250
+ this.consume();
1251
+ } else {
1252
+ throw this.error(new TomlError("Incomplete datetime"));
1253
+ }
1254
+ }
1255
+ parseDateDay() {
1256
+ if (this.char === CHAR_T || this.char === CHAR_SP) {
1257
+ if (this.state.buf.length < 2) {
1258
+ throw this.error(new TomlError("Days less than 10 must be zero padded to two characters"));
1259
+ }
1260
+ this.state.result += "-" + this.state.buf;
1261
+ this.state.buf = "";
1262
+ return this.next(this.parseStartTimeHour);
1263
+ } else if (this.atEndOfWord()) {
1264
+ return this.returnNow(createDate(this.state.result + "-" + this.state.buf));
1265
+ } else if (isDigit(this.char)) {
1266
+ this.consume();
1267
+ } else {
1268
+ throw this.error(new TomlError("Incomplete datetime"));
1269
+ }
1270
+ }
1271
+ parseStartTimeHour() {
1272
+ if (this.atEndOfWord()) {
1273
+ return this.returnNow(createDate(this.state.result));
1274
+ } else {
1275
+ return this.goto(this.parseTimeHour);
1276
+ }
1277
+ }
1278
+ parseTimeHour() {
1279
+ if (this.char === CHAR_COLON) {
1280
+ if (this.state.buf.length < 2) {
1281
+ throw this.error(new TomlError("Hours less than 10 must be zero padded to two characters"));
1282
+ }
1283
+ this.state.result += "T" + this.state.buf;
1284
+ this.state.buf = "";
1285
+ return this.next(this.parseTimeMin);
1286
+ } else if (isDigit(this.char)) {
1287
+ this.consume();
1288
+ } else {
1289
+ throw this.error(new TomlError("Incomplete datetime"));
1290
+ }
1291
+ }
1292
+ parseTimeMin() {
1293
+ if (this.state.buf.length < 2 && isDigit(this.char)) {
1294
+ this.consume();
1295
+ } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
1296
+ this.state.result += ":" + this.state.buf;
1297
+ this.state.buf = "";
1298
+ return this.next(this.parseTimeSec);
1299
+ } else {
1300
+ throw this.error(new TomlError("Incomplete datetime"));
1301
+ }
1302
+ }
1303
+ parseTimeSec() {
1304
+ if (isDigit(this.char)) {
1305
+ this.consume();
1306
+ if (this.state.buf.length === 2) {
1307
+ this.state.result += ":" + this.state.buf;
1308
+ this.state.buf = "";
1309
+ return this.next(this.parseTimeZoneOrFraction);
1310
+ }
1311
+ } else {
1312
+ throw this.error(new TomlError("Incomplete datetime"));
1313
+ }
1314
+ }
1315
+ parseOnlyTimeHour() {
1316
+ if (this.char === CHAR_COLON) {
1317
+ if (this.state.buf.length < 2) {
1318
+ throw this.error(new TomlError("Hours less than 10 must be zero padded to two characters"));
1319
+ }
1320
+ this.state.result = this.state.buf;
1321
+ this.state.buf = "";
1322
+ return this.next(this.parseOnlyTimeMin);
1323
+ } else {
1324
+ throw this.error(new TomlError("Incomplete time"));
1325
+ }
1326
+ }
1327
+ parseOnlyTimeMin() {
1328
+ if (this.state.buf.length < 2 && isDigit(this.char)) {
1329
+ this.consume();
1330
+ } else if (this.state.buf.length === 2 && this.char === CHAR_COLON) {
1331
+ this.state.result += ":" + this.state.buf;
1332
+ this.state.buf = "";
1333
+ return this.next(this.parseOnlyTimeSec);
1334
+ } else {
1335
+ throw this.error(new TomlError("Incomplete time"));
1336
+ }
1337
+ }
1338
+ parseOnlyTimeSec() {
1339
+ if (isDigit(this.char)) {
1340
+ this.consume();
1341
+ if (this.state.buf.length === 2) {
1342
+ return this.next(this.parseOnlyTimeFractionMaybe);
1343
+ }
1344
+ } else {
1345
+ throw this.error(new TomlError("Incomplete time"));
1346
+ }
1347
+ }
1348
+ parseOnlyTimeFractionMaybe() {
1349
+ this.state.result += ":" + this.state.buf;
1350
+ if (this.char === CHAR_PERIOD) {
1351
+ this.state.buf = "";
1352
+ this.next(this.parseOnlyTimeFraction);
1353
+ } else {
1354
+ return this.return(createTime(this.state.result));
1355
+ }
1356
+ }
1357
+ parseOnlyTimeFraction() {
1358
+ if (isDigit(this.char)) {
1359
+ this.consume();
1360
+ } else if (this.atEndOfWord()) {
1361
+ if (this.state.buf.length === 0) throw this.error(new TomlError("Expected digit in milliseconds"));
1362
+ return this.returnNow(createTime(this.state.result + "." + this.state.buf));
1363
+ } else {
1364
+ throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
1365
+ }
1366
+ }
1367
+ parseTimeZoneOrFraction() {
1368
+ if (this.char === CHAR_PERIOD) {
1369
+ this.consume();
1370
+ this.next(this.parseDateTimeFraction);
1371
+ } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
1372
+ this.consume();
1373
+ this.next(this.parseTimeZoneHour);
1374
+ } else if (this.char === CHAR_Z) {
1375
+ this.consume();
1376
+ return this.return(createDateTime(this.state.result + this.state.buf));
1377
+ } else if (this.atEndOfWord()) {
1378
+ return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf));
1379
+ } else {
1380
+ throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
1381
+ }
1382
+ }
1383
+ parseDateTimeFraction() {
1384
+ if (isDigit(this.char)) {
1385
+ this.consume();
1386
+ } else if (this.state.buf.length === 1) {
1387
+ throw this.error(new TomlError("Expected digit in milliseconds"));
1388
+ } else if (this.char === CHAR_HYPHEN || this.char === CHAR_PLUS) {
1389
+ this.consume();
1390
+ this.next(this.parseTimeZoneHour);
1391
+ } else if (this.char === CHAR_Z) {
1392
+ this.consume();
1393
+ return this.return(createDateTime(this.state.result + this.state.buf));
1394
+ } else if (this.atEndOfWord()) {
1395
+ return this.returnNow(createDateTimeFloat(this.state.result + this.state.buf));
1396
+ } else {
1397
+ throw this.error(new TomlError("Unexpected character in datetime, expected period (.), minus (-), plus (+) or Z"));
1398
+ }
1399
+ }
1400
+ parseTimeZoneHour() {
1401
+ if (isDigit(this.char)) {
1402
+ this.consume();
1403
+ if (/\d\d$/.test(this.state.buf)) return this.next(this.parseTimeZoneSep);
1404
+ } else {
1405
+ throw this.error(new TomlError("Unexpected character in datetime, expected digit"));
1406
+ }
1407
+ }
1408
+ parseTimeZoneSep() {
1409
+ if (this.char === CHAR_COLON) {
1410
+ this.consume();
1411
+ this.next(this.parseTimeZoneMin);
1412
+ } else {
1413
+ throw this.error(new TomlError("Unexpected character in datetime, expected colon"));
1414
+ }
1415
+ }
1416
+ parseTimeZoneMin() {
1417
+ if (isDigit(this.char)) {
1418
+ this.consume();
1419
+ if (/\d\d$/.test(this.state.buf)) return this.return(createDateTime(this.state.result + this.state.buf));
1420
+ } else {
1421
+ throw this.error(new TomlError("Unexpected character in datetime, expected digit"));
1422
+ }
1423
+ }
1424
+ /* BOOLEAN */
1425
+ parseBoolean() {
1426
+ if (this.char === CHAR_t) {
1427
+ this.consume();
1428
+ return this.next(this.parseTrue_r);
1429
+ } else if (this.char === CHAR_f) {
1430
+ this.consume();
1431
+ return this.next(this.parseFalse_a);
1432
+ }
1433
+ }
1434
+ parseTrue_r() {
1435
+ if (this.char === CHAR_r) {
1436
+ this.consume();
1437
+ return this.next(this.parseTrue_u);
1438
+ } else {
1439
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1440
+ }
1441
+ }
1442
+ parseTrue_u() {
1443
+ if (this.char === CHAR_u) {
1444
+ this.consume();
1445
+ return this.next(this.parseTrue_e);
1446
+ } else {
1447
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1448
+ }
1449
+ }
1450
+ parseTrue_e() {
1451
+ if (this.char === CHAR_e) {
1452
+ return this.return(true);
1453
+ } else {
1454
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1455
+ }
1456
+ }
1457
+ parseFalse_a() {
1458
+ if (this.char === CHAR_a) {
1459
+ this.consume();
1460
+ return this.next(this.parseFalse_l);
1461
+ } else {
1462
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1463
+ }
1464
+ }
1465
+ parseFalse_l() {
1466
+ if (this.char === CHAR_l) {
1467
+ this.consume();
1468
+ return this.next(this.parseFalse_s);
1469
+ } else {
1470
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1471
+ }
1472
+ }
1473
+ parseFalse_s() {
1474
+ if (this.char === CHAR_s) {
1475
+ this.consume();
1476
+ return this.next(this.parseFalse_e);
1477
+ } else {
1478
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1479
+ }
1480
+ }
1481
+ parseFalse_e() {
1482
+ if (this.char === CHAR_e) {
1483
+ return this.return(false);
1484
+ } else {
1485
+ throw this.error(new TomlError("Invalid boolean, expected true or false"));
1486
+ }
1487
+ }
1488
+ /* INLINE LISTS */
1489
+ parseInlineList() {
1490
+ if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
1491
+ return null;
1492
+ } else if (this.char === Parser.END) {
1493
+ throw this.error(new TomlError("Unterminated inline array"));
1494
+ } else if (this.char === CHAR_NUM) {
1495
+ return this.call(this.parseComment);
1496
+ } else if (this.char === CHAR_RSQB) {
1497
+ return this.return(this.state.resultArr || InlineList());
1498
+ } else {
1499
+ return this.callNow(this.parseValue, this.recordInlineListValue);
1500
+ }
1501
+ }
1502
+ recordInlineListValue(value) {
1503
+ if (this.state.resultArr) {
1504
+ const listType = this.state.resultArr[_contentType];
1505
+ const valueType = tomlType(value);
1506
+ if (listType !== valueType) {
1507
+ throw this.error(new TomlError(`Inline lists must be a single type, not a mix of ${listType} and ${valueType}`));
1508
+ }
1509
+ } else {
1510
+ this.state.resultArr = InlineList(tomlType(value));
1511
+ }
1512
+ if (isFloat(value) || isInteger(value)) {
1513
+ this.state.resultArr.push(value.valueOf());
1514
+ } else {
1515
+ this.state.resultArr.push(value);
1516
+ }
1517
+ return this.goto(this.parseInlineListNext);
1518
+ }
1519
+ parseInlineListNext() {
1520
+ if (this.char === CHAR_SP || this.char === CTRL_I || this.char === CTRL_M || this.char === CTRL_J) {
1521
+ return null;
1522
+ } else if (this.char === CHAR_NUM) {
1523
+ return this.call(this.parseComment);
1524
+ } else if (this.char === CHAR_COMMA) {
1525
+ return this.next(this.parseInlineList);
1526
+ } else if (this.char === CHAR_RSQB) {
1527
+ return this.goto(this.parseInlineList);
1528
+ } else {
1529
+ throw this.error(new TomlError("Invalid character, expected whitespace, comma (,) or close bracket (])"));
1530
+ }
1531
+ }
1532
+ /* INLINE TABLE */
1533
+ parseInlineTable() {
1534
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
1535
+ return null;
1536
+ } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
1537
+ throw this.error(new TomlError("Unterminated inline array"));
1538
+ } else if (this.char === CHAR_RCUB) {
1539
+ return this.return(this.state.resultTable || InlineTable());
1540
+ } else {
1541
+ if (!this.state.resultTable) this.state.resultTable = InlineTable();
1542
+ return this.callNow(this.parseAssign, this.recordInlineTableValue);
1543
+ }
1544
+ }
1545
+ recordInlineTableValue(kv) {
1546
+ let target = this.state.resultTable;
1547
+ let finalKey = kv.key.pop();
1548
+ for (let kw of kv.key) {
1549
+ if (hasKey(target, kw) && (!isTable(target[kw]) || target[kw][_declared])) {
1550
+ throw this.error(new TomlError("Can't redefine existing key"));
1551
+ }
1552
+ target = target[kw] = target[kw] || Table();
1553
+ }
1554
+ if (hasKey(target, finalKey)) {
1555
+ throw this.error(new TomlError("Can't redefine existing key"));
1556
+ }
1557
+ if (isInteger(kv.value) || isFloat(kv.value)) {
1558
+ target[finalKey] = kv.value.valueOf();
1559
+ } else {
1560
+ target[finalKey] = kv.value;
1561
+ }
1562
+ return this.goto(this.parseInlineTableNext);
1563
+ }
1564
+ parseInlineTableNext() {
1565
+ if (this.char === CHAR_SP || this.char === CTRL_I) {
1566
+ return null;
1567
+ } else if (this.char === Parser.END || this.char === CHAR_NUM || this.char === CTRL_J || this.char === CTRL_M) {
1568
+ throw this.error(new TomlError("Unterminated inline array"));
1569
+ } else if (this.char === CHAR_COMMA) {
1570
+ return this.next(this.parseInlineTable);
1571
+ } else if (this.char === CHAR_RCUB) {
1572
+ return this.goto(this.parseInlineTable);
1573
+ } else {
1574
+ throw this.error(new TomlError("Invalid character, expected whitespace, comma (,) or close bracket (])"));
1575
+ }
1576
+ }
1577
+ }
1578
+ return TOMLParser;
1579
+ }
1580
+ }
1581
+ });
1582
+
1583
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-pretty-error.js
1584
+ var require_parse_pretty_error = __commonJS({
1585
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-pretty-error.js"(exports2, module2) {
1586
+ "use strict";
1587
+ module2.exports = prettyError;
1588
+ function prettyError(err, buf) {
1589
+ if (err.pos == null || err.line == null) return err;
1590
+ let msg = err.message;
1591
+ msg += ` at row ${err.line + 1}, col ${err.col + 1}, pos ${err.pos}:
1592
+ `;
1593
+ if (buf && buf.split) {
1594
+ const lines = buf.split(/\n/);
1595
+ const lineNumWidth = String(Math.min(lines.length, err.line + 3)).length;
1596
+ let linePadding = " ";
1597
+ while (linePadding.length < lineNumWidth) linePadding += " ";
1598
+ for (let ii = Math.max(0, err.line - 1); ii < Math.min(lines.length, err.line + 2); ++ii) {
1599
+ let lineNum = String(ii + 1);
1600
+ if (lineNum.length < lineNumWidth) lineNum = " " + lineNum;
1601
+ if (err.line === ii) {
1602
+ msg += lineNum + "> " + lines[ii] + "\n";
1603
+ msg += linePadding + " ";
1604
+ for (let hh = 0; hh < err.col; ++hh) {
1605
+ msg += " ";
1606
+ }
1607
+ msg += "^\n";
1608
+ } else {
1609
+ msg += lineNum + ": " + lines[ii] + "\n";
1610
+ }
1611
+ }
1612
+ }
1613
+ err.message = msg + "\n";
1614
+ return err;
1615
+ }
1616
+ }
1617
+ });
1618
+
1619
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-string.js
1620
+ var require_parse_string = __commonJS({
1621
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-string.js"(exports2, module2) {
1622
+ "use strict";
1623
+ module2.exports = parseString;
1624
+ var TOMLParser = require_toml_parser();
1625
+ var prettyError = require_parse_pretty_error();
1626
+ function parseString(str) {
1627
+ if (global.Buffer && global.Buffer.isBuffer(str)) {
1628
+ str = str.toString("utf8");
1629
+ }
1630
+ const parser = new TOMLParser();
1631
+ try {
1632
+ parser.parse(str);
1633
+ return parser.finish();
1634
+ } catch (err) {
1635
+ throw prettyError(err, str);
1636
+ }
1637
+ }
1638
+ }
1639
+ });
1640
+
1641
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-async.js
1642
+ var require_parse_async = __commonJS({
1643
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-async.js"(exports2, module2) {
1644
+ "use strict";
1645
+ module2.exports = parseAsync;
1646
+ var TOMLParser = require_toml_parser();
1647
+ var prettyError = require_parse_pretty_error();
1648
+ function parseAsync(str, opts) {
1649
+ if (!opts) opts = {};
1650
+ const index = 0;
1651
+ const blocksize = opts.blocksize || 40960;
1652
+ const parser = new TOMLParser();
1653
+ return new Promise((resolve, reject2) => {
1654
+ setImmediate(parseAsyncNext, index, blocksize, resolve, reject2);
1655
+ });
1656
+ function parseAsyncNext(index2, blocksize2, resolve, reject2) {
1657
+ if (index2 >= str.length) {
1658
+ try {
1659
+ return resolve(parser.finish());
1660
+ } catch (err) {
1661
+ return reject2(prettyError(err, str));
1662
+ }
1663
+ }
1664
+ try {
1665
+ parser.parse(str.slice(index2, index2 + blocksize2));
1666
+ setImmediate(parseAsyncNext, index2 + blocksize2, blocksize2, resolve, reject2);
1667
+ } catch (err) {
1668
+ reject2(prettyError(err, str));
1669
+ }
1670
+ }
1671
+ }
1672
+ }
1673
+ });
1674
+
1675
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-stream.js
1676
+ var require_parse_stream = __commonJS({
1677
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse-stream.js"(exports2, module2) {
1678
+ "use strict";
1679
+ module2.exports = parseStream;
1680
+ var stream = __require("stream");
1681
+ var TOMLParser = require_toml_parser();
1682
+ function parseStream(stm) {
1683
+ if (stm) {
1684
+ return parseReadable(stm);
1685
+ } else {
1686
+ return parseTransform(stm);
1687
+ }
1688
+ }
1689
+ function parseReadable(stm) {
1690
+ const parser = new TOMLParser();
1691
+ stm.setEncoding("utf8");
1692
+ return new Promise((resolve, reject2) => {
1693
+ let readable;
1694
+ let ended = false;
1695
+ let errored = false;
1696
+ function finish() {
1697
+ ended = true;
1698
+ if (readable) return;
1699
+ try {
1700
+ resolve(parser.finish());
1701
+ } catch (err) {
1702
+ reject2(err);
1703
+ }
1704
+ }
1705
+ function error(err) {
1706
+ errored = true;
1707
+ reject2(err);
1708
+ }
1709
+ stm.once("end", finish);
1710
+ stm.once("error", error);
1711
+ readNext();
1712
+ function readNext() {
1713
+ readable = true;
1714
+ let data;
1715
+ while ((data = stm.read()) !== null) {
1716
+ try {
1717
+ parser.parse(data);
1718
+ } catch (err) {
1719
+ return error(err);
1720
+ }
1721
+ }
1722
+ readable = false;
1723
+ if (ended) return finish();
1724
+ if (errored) return;
1725
+ stm.once("readable", readNext);
1726
+ }
1727
+ });
1728
+ }
1729
+ function parseTransform() {
1730
+ const parser = new TOMLParser();
1731
+ return new stream.Transform({
1732
+ objectMode: true,
1733
+ transform(chunk, encoding, cb) {
1734
+ try {
1735
+ parser.parse(chunk.toString(encoding));
1736
+ } catch (err) {
1737
+ this.emit("error", err);
1738
+ }
1739
+ cb();
1740
+ },
1741
+ flush(cb) {
1742
+ try {
1743
+ this.push(parser.finish());
1744
+ } catch (err) {
1745
+ this.emit("error", err);
1746
+ }
1747
+ cb();
1748
+ }
1749
+ });
1750
+ }
1751
+ }
1752
+ });
1753
+
1754
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse.js
1755
+ var require_parse = __commonJS({
1756
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/parse.js"(exports2, module2) {
1757
+ "use strict";
1758
+ module2.exports = require_parse_string();
1759
+ module2.exports.async = require_parse_async();
1760
+ module2.exports.stream = require_parse_stream();
1761
+ module2.exports.prettyError = require_parse_pretty_error();
1762
+ }
1763
+ });
1764
+
1765
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/stringify.js
1766
+ var require_stringify = __commonJS({
1767
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/stringify.js"(exports2, module2) {
1768
+ "use strict";
1769
+ module2.exports = stringify;
1770
+ module2.exports.value = stringifyInline;
1771
+ function stringify(obj) {
1772
+ if (obj === null) throw typeError("null");
1773
+ if (obj === void 0) throw typeError("undefined");
1774
+ if (typeof obj !== "object") throw typeError(typeof obj);
1775
+ if (typeof obj.toJSON === "function") obj = obj.toJSON();
1776
+ if (obj == null) return null;
1777
+ const type = tomlType2(obj);
1778
+ if (type !== "table") throw typeError(type);
1779
+ return stringifyObject("", "", obj);
1780
+ }
1781
+ function typeError(type) {
1782
+ return new Error("Can only stringify objects, not " + type);
1783
+ }
1784
+ function arrayOneTypeError() {
1785
+ return new Error("Array values can't have mixed types");
1786
+ }
1787
+ function getInlineKeys(obj) {
1788
+ return Object.keys(obj).filter((key) => isInline(obj[key]));
1789
+ }
1790
+ function getComplexKeys(obj) {
1791
+ return Object.keys(obj).filter((key) => !isInline(obj[key]));
1792
+ }
1793
+ function toJSON(obj) {
1794
+ let nobj = Array.isArray(obj) ? [] : Object.prototype.hasOwnProperty.call(obj, "__proto__") ? { ["__proto__"]: void 0 } : {};
1795
+ for (let prop of Object.keys(obj)) {
1796
+ if (obj[prop] && typeof obj[prop].toJSON === "function" && !("toISOString" in obj[prop])) {
1797
+ nobj[prop] = obj[prop].toJSON();
1798
+ } else {
1799
+ nobj[prop] = obj[prop];
1800
+ }
1801
+ }
1802
+ return nobj;
1803
+ }
1804
+ function stringifyObject(prefix, indent, obj) {
1805
+ obj = toJSON(obj);
1806
+ var inlineKeys;
1807
+ var complexKeys;
1808
+ inlineKeys = getInlineKeys(obj);
1809
+ complexKeys = getComplexKeys(obj);
1810
+ var result = [];
1811
+ var inlineIndent = indent || "";
1812
+ inlineKeys.forEach((key) => {
1813
+ var type = tomlType2(obj[key]);
1814
+ if (type !== "undefined" && type !== "null") {
1815
+ result.push(inlineIndent + stringifyKey(key) + " = " + stringifyAnyInline(obj[key], true));
1816
+ }
1817
+ });
1818
+ if (result.length > 0) result.push("");
1819
+ var complexIndent = prefix && inlineKeys.length > 0 ? indent + " " : "";
1820
+ complexKeys.forEach((key) => {
1821
+ result.push(stringifyComplex(prefix, complexIndent, key, obj[key]));
1822
+ });
1823
+ return result.join("\n");
1824
+ }
1825
+ function isInline(value) {
1826
+ switch (tomlType2(value)) {
1827
+ case "undefined":
1828
+ case "null":
1829
+ case "integer":
1830
+ case "nan":
1831
+ case "float":
1832
+ case "boolean":
1833
+ case "string":
1834
+ case "datetime":
1835
+ return true;
1836
+ case "array":
1837
+ return value.length === 0 || tomlType2(value[0]) !== "table";
1838
+ case "table":
1839
+ return Object.keys(value).length === 0;
1840
+ /* istanbul ignore next */
1841
+ default:
1842
+ return false;
1843
+ }
1844
+ }
1845
+ function tomlType2(value) {
1846
+ if (value === void 0) {
1847
+ return "undefined";
1848
+ } else if (value === null) {
1849
+ return "null";
1850
+ } else if (typeof value === "bigint" || Number.isInteger(value) && !Object.is(value, -0)) {
1851
+ return "integer";
1852
+ } else if (typeof value === "number") {
1853
+ return "float";
1854
+ } else if (typeof value === "boolean") {
1855
+ return "boolean";
1856
+ } else if (typeof value === "string") {
1857
+ return "string";
1858
+ } else if ("toISOString" in value) {
1859
+ return isNaN(value) ? "undefined" : "datetime";
1860
+ } else if (Array.isArray(value)) {
1861
+ return "array";
1862
+ } else {
1863
+ return "table";
1864
+ }
1865
+ }
1866
+ function stringifyKey(key) {
1867
+ var keyStr = String(key);
1868
+ if (/^[-A-Za-z0-9_]+$/.test(keyStr)) {
1869
+ return keyStr;
1870
+ } else {
1871
+ return stringifyBasicString(keyStr);
1872
+ }
1873
+ }
1874
+ function stringifyBasicString(str) {
1875
+ return '"' + escapeString(str).replace(/"/g, '\\"') + '"';
1876
+ }
1877
+ function stringifyLiteralString(str) {
1878
+ return "'" + str + "'";
1879
+ }
1880
+ function numpad(num, str) {
1881
+ while (str.length < num) str = "0" + str;
1882
+ return str;
1883
+ }
1884
+ function escapeString(str) {
1885
+ return str.replace(/\\/g, "\\\\").replace(/[\b]/g, "\\b").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\f/g, "\\f").replace(/\r/g, "\\r").replace(/([\u0000-\u001f\u007f])/, (c) => "\\u" + numpad(4, c.codePointAt(0).toString(16)));
1886
+ }
1887
+ function stringifyMultilineString(str) {
1888
+ let escaped = str.split(/\n/).map((str2) => {
1889
+ return escapeString(str2).replace(/"(?="")/g, '\\"');
1890
+ }).join("\n");
1891
+ if (escaped.slice(-1) === '"') escaped += "\\\n";
1892
+ return '"""\n' + escaped + '"""';
1893
+ }
1894
+ function stringifyAnyInline(value, multilineOk) {
1895
+ let type = tomlType2(value);
1896
+ if (type === "string") {
1897
+ if (multilineOk && /\n/.test(value)) {
1898
+ type = "string-multiline";
1899
+ } else if (!/[\b\t\n\f\r']/.test(value) && /"/.test(value)) {
1900
+ type = "string-literal";
1901
+ }
1902
+ }
1903
+ return stringifyInline(value, type);
1904
+ }
1905
+ function stringifyInline(value, type) {
1906
+ if (!type) type = tomlType2(value);
1907
+ switch (type) {
1908
+ case "string-multiline":
1909
+ return stringifyMultilineString(value);
1910
+ case "string":
1911
+ return stringifyBasicString(value);
1912
+ case "string-literal":
1913
+ return stringifyLiteralString(value);
1914
+ case "integer":
1915
+ return stringifyInteger(value);
1916
+ case "float":
1917
+ return stringifyFloat(value);
1918
+ case "boolean":
1919
+ return stringifyBoolean(value);
1920
+ case "datetime":
1921
+ return stringifyDatetime(value);
1922
+ case "array":
1923
+ return stringifyInlineArray(value.filter((_) => tomlType2(_) !== "null" && tomlType2(_) !== "undefined" && tomlType2(_) !== "nan"));
1924
+ case "table":
1925
+ return stringifyInlineTable(value);
1926
+ /* istanbul ignore next */
1927
+ default:
1928
+ throw typeError(type);
1929
+ }
1930
+ }
1931
+ function stringifyInteger(value) {
1932
+ return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, "_");
1933
+ }
1934
+ function stringifyFloat(value) {
1935
+ if (value === Infinity) {
1936
+ return "inf";
1937
+ } else if (value === -Infinity) {
1938
+ return "-inf";
1939
+ } else if (Object.is(value, NaN)) {
1940
+ return "nan";
1941
+ } else if (Object.is(value, -0)) {
1942
+ return "-0.0";
1943
+ }
1944
+ var chunks = String(value).split(".");
1945
+ var int = chunks[0];
1946
+ var dec = chunks[1] || 0;
1947
+ return stringifyInteger(int) + "." + dec;
1948
+ }
1949
+ function stringifyBoolean(value) {
1950
+ return String(value);
1951
+ }
1952
+ function stringifyDatetime(value) {
1953
+ return value.toISOString();
1954
+ }
1955
+ function isNumber(type) {
1956
+ return type === "float" || type === "integer";
1957
+ }
1958
+ function arrayType(values) {
1959
+ var contentType = tomlType2(values[0]);
1960
+ if (values.every((_) => tomlType2(_) === contentType)) return contentType;
1961
+ if (values.every((_) => isNumber(tomlType2(_)))) return "float";
1962
+ return "mixed";
1963
+ }
1964
+ function validateArray(values) {
1965
+ const type = arrayType(values);
1966
+ if (type === "mixed") {
1967
+ throw arrayOneTypeError();
1968
+ }
1969
+ return type;
1970
+ }
1971
+ function stringifyInlineArray(values) {
1972
+ values = toJSON(values);
1973
+ const type = validateArray(values);
1974
+ var result = "[";
1975
+ var stringified = values.map((_) => stringifyInline(_, type));
1976
+ if (stringified.join(", ").length > 60 || /\n/.test(stringified)) {
1977
+ result += "\n " + stringified.join(",\n ") + "\n";
1978
+ } else {
1979
+ result += " " + stringified.join(", ") + (stringified.length > 0 ? " " : "");
1980
+ }
1981
+ return result + "]";
1982
+ }
1983
+ function stringifyInlineTable(value) {
1984
+ value = toJSON(value);
1985
+ var result = [];
1986
+ Object.keys(value).forEach((key) => {
1987
+ result.push(stringifyKey(key) + " = " + stringifyAnyInline(value[key], false));
1988
+ });
1989
+ return "{ " + result.join(", ") + (result.length > 0 ? " " : "") + "}";
1990
+ }
1991
+ function stringifyComplex(prefix, indent, key, value) {
1992
+ var valueType = tomlType2(value);
1993
+ if (valueType === "array") {
1994
+ return stringifyArrayOfTables(prefix, indent, key, value);
1995
+ } else if (valueType === "table") {
1996
+ return stringifyComplexTable(prefix, indent, key, value);
1997
+ } else {
1998
+ throw typeError(valueType);
1999
+ }
2000
+ }
2001
+ function stringifyArrayOfTables(prefix, indent, key, values) {
2002
+ values = toJSON(values);
2003
+ validateArray(values);
2004
+ var firstValueType = tomlType2(values[0]);
2005
+ if (firstValueType !== "table") throw typeError(firstValueType);
2006
+ var fullKey = prefix + stringifyKey(key);
2007
+ var result = "";
2008
+ values.forEach((table) => {
2009
+ if (result.length > 0) result += "\n";
2010
+ result += indent + "[[" + fullKey + "]]\n";
2011
+ result += stringifyObject(fullKey + ".", indent, table);
2012
+ });
2013
+ return result;
2014
+ }
2015
+ function stringifyComplexTable(prefix, indent, key, value) {
2016
+ var fullKey = prefix + stringifyKey(key);
2017
+ var result = "";
2018
+ if (getInlineKeys(value).length > 0) {
2019
+ result += indent + "[" + fullKey + "]\n";
2020
+ }
2021
+ return result + stringifyObject(fullKey + ".", indent, value);
2022
+ }
2023
+ }
2024
+ });
2025
+
2026
+ // node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/toml.js
2027
+ var require_toml = __commonJS({
2028
+ "node_modules/.pnpm/@iarna+toml@2.2.5/node_modules/@iarna/toml/toml.js"(exports2) {
2029
+ "use strict";
2030
+ exports2.parse = require_parse();
2031
+ exports2.stringify = require_stringify();
2032
+ }
2033
+ });
4
2034
 
5
2035
  // packages/ceal-client-protocol/src/canonical-json.ts
6
2036
  function cealCanonicalJson(value) {
@@ -109,6 +2139,9 @@ var client_wire_contract_default = {
109
2139
  "document"
110
2140
  ],
111
2141
  optional_fields: [
2142
+ "operation_id",
2143
+ "visible_output_max_bytes",
2144
+ "local_delivery",
112
2145
  "verified_artifact"
113
2146
  ],
114
2147
  bare_document_fields: [
@@ -195,6 +2228,7 @@ var CEAL_COMMAND_RESPONSE_FOCUSED_PROMPT_CONTINUATION_DOCUMENT_FIELDS = Object.f
195
2228
  var CEAL_COMMAND_RESPONSE_DISCOVERY_COMMAND = response.discovery_command;
196
2229
  var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_SCHEMA_VERSION = response.discovery_manifest_schema_version;
197
2230
  var CEAL_COMMAND_RESPONSE_DISCOVERY_MANIFEST_DOCUMENT_FIELDS = Object.freeze([...response.discovery_manifest_document_fields]);
2231
+ var CEAL_COMMAND_RESPONSE_MAX_BYTES = CEAL_ENCODED_JSON_DOCUMENT_MAX_BYTES;
198
2232
 
199
2233
  // packages/ceal-client-protocol/src/vocabulary.ts
200
2234
  function vocabulary(words) {
@@ -225,6 +2259,7 @@ var CEAL_WRITE_RECEIPT_PROVIDER_STATES = vocabulary(["outcome_unknown", "verifie
225
2259
  var CEAL_WRITE_RECEIPT_PROVIDER_READBACKS = vocabulary(["outcome_unknown", "verified", "not_applied"]);
226
2260
  var CEAL_PROTOCOL_VERSION = "1.4.0";
227
2261
  var CEAL_OPERATION_ACCESS_SCHEMA_VERSION = "ceal.operation_access.v1";
2262
+ var CEAL_GATEWAY_CONTINUATION_CURSOR_PHASES = vocabulary(["scan", "delivery", "terminal"]);
228
2263
  var CEAL_GATEWAY_ACTIVE_CALL_PHASES = vocabulary([
229
2264
  "audited_call_pending",
230
2265
  "continuation_read_pending",
@@ -248,6 +2283,7 @@ var CEAL_GATEWAY_ORGANIZATION_ROUTE_FACT_CALL_KEYS = Object.freeze([
248
2283
  // packages/ceal-client-protocol/src/operation-next-actions.ts
249
2284
  var CEAL_REPEAT_REQUEST_NEXT_ACTION = "repeat_request";
250
2285
  var CEAL_INSPECT_RECEIPT_NEXT_ACTION = "inspect_receipt";
2286
+ var CEAL_ANSWER_WITH_GAP_NEXT_ACTION = "answer_with_gap";
251
2287
  var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
252
2288
  "select_did_you_mean",
253
2289
  "choose_new_output_path",
@@ -301,10 +2337,20 @@ var CALLER_RECOVERABLE_NEXT_ACTION_VALUES = [
301
2337
  "retry_after",
302
2338
  // The ref names a container of rows (a Notion database or data source), which
303
2339
  // has no body of its own; the caller searches its rows instead of reading it.
304
- "search_container_rows"
2340
+ "search_container_rows",
2341
+ // A settled unknown write names the exact receipt Operation that can inspect
2342
+ // its outcome without issuing another provider mutation.
2343
+ "write_receipt.get",
2344
+ // Command resolution carries the exact required Operation sequence beside
2345
+ // this action, so the caller can execute each declared input in order.
2346
+ "follow_required_action_sequence",
2347
+ // The command needs caller-owned local materialization (for example an
2348
+ // @path file) before the Gateway can receive the argument.
2349
+ "materialize_local_argument"
305
2350
  ];
306
2351
  var CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS = Object.freeze(CALLER_RECOVERABLE_NEXT_ACTION_VALUES);
307
2352
  var NON_REMEDY_NEXT_ACTION_VALUES = [
2353
+ CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
308
2354
  // Only an administrator can take the named step -- approving a place for an
309
2355
  // Operation, granting a withheld capability -- so a non-administrator asks
310
2356
  // one. The refusal names the administrator step; this word is the ask.
@@ -352,7 +2398,58 @@ var NON_REMEDY_NEXT_ACTION_VALUES = [
352
2398
  "select_exact_approval"
353
2399
  ];
354
2400
  var CEAL_NON_REMEDY_NEXT_ACTIONS = Object.freeze(NON_REMEDY_NEXT_ACTION_VALUES);
355
- var DECLARED = /* @__PURE__ */ new Set([...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS, ...CEAL_NON_REMEDY_NEXT_ACTIONS]);
2401
+ var CEAL_DECLARED_NEXT_ACTIONS = Object.freeze([...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS, ...CEAL_NON_REMEDY_NEXT_ACTIONS]);
2402
+ var DECLARED = new Set(CEAL_DECLARED_NEXT_ACTIONS);
2403
+ function defineCealNonModelNextActions(actions) {
2404
+ return actions;
2405
+ }
2406
+ var NON_MODEL_NEXT_ACTION_VALUES = defineCealNonModelNextActions([
2407
+ CEAL_INSPECT_RECEIPT_NEXT_ACTION,
2408
+ "await_pending_approval",
2409
+ "inspect_gateway",
2410
+ "operator_action",
2411
+ "none",
2412
+ "check_gateway",
2413
+ "inspect_context_store",
2414
+ "inspect_local_cache",
2415
+ "inspect_local_client",
2416
+ "inspect_local_command",
2417
+ "inspect_local_output",
2418
+ "inspect_local_route",
2419
+ "inspect_request",
2420
+ "reconcile",
2421
+ "reconcile_occurrence",
2422
+ "retry_after_owner_recovery",
2423
+ "select_exact_approval"
2424
+ ]);
2425
+ var NON_MODEL_NEXT_ACTIONS = new Set(NON_MODEL_NEXT_ACTION_VALUES);
2426
+ function isCealModelActionableNonRemedyNextAction(action) {
2427
+ return !NON_MODEL_NEXT_ACTIONS.has(action);
2428
+ }
2429
+ var CEAL_MODEL_ACTIONABLE_NEXT_ACTIONS = Object.freeze([
2430
+ ...CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS,
2431
+ ...CEAL_NON_REMEDY_NEXT_ACTIONS.filter(isCealModelActionableNonRemedyNextAction)
2432
+ ]);
2433
+ var MODEL_ACTIONABLE = new Set(CEAL_MODEL_ACTIONABLE_NEXT_ACTIONS);
2434
+ var NON_MODEL_ACTION_TO_MODEL_ACTION = Object.freeze({
2435
+ [CEAL_INSPECT_RECEIPT_NEXT_ACTION]: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2436
+ await_pending_approval: "ask_admin",
2437
+ inspect_gateway: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2438
+ operator_action: "ask_admin",
2439
+ none: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2440
+ check_gateway: "ask_admin",
2441
+ inspect_context_store: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2442
+ inspect_local_cache: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2443
+ inspect_local_client: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2444
+ inspect_local_command: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2445
+ inspect_local_output: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2446
+ inspect_local_route: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2447
+ inspect_request: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2448
+ reconcile: CEAL_ANSWER_WITH_GAP_NEXT_ACTION,
2449
+ reconcile_occurrence: "ask_admin",
2450
+ retry_after_owner_recovery: "ask_admin",
2451
+ select_exact_approval: "ask_admin"
2452
+ });
356
2453
  var RETRY_PROMISE_NEXT_ACTIONS = ["retry", "retry_after"];
357
2454
  var RETRY_PROMISE = new Set(RETRY_PROMISE_NEXT_ACTIONS);
358
2455
  var RECOVERABLE = new Set(CEAL_CALLER_RECOVERABLE_NEXT_ACTIONS);
@@ -622,21 +2719,15 @@ var CEAL_OPERATION_ACCESS_CLASSES = vocabulary(["read", "write"]);
622
2719
  // packages/ceal-client-protocol/src/domain-vocabulary.ts
623
2720
  var CEAL_CONNECTOR_STATUSES = vocabulary(["active", "disabled", "disconnected"]);
624
2721
  var CEAL_CONNECTOR_CUSTODIES = vocabulary(["organization", "personal"]);
625
- var CEAL_PROVIDER_BOUNDARY_KINDS = vocabulary([
626
- "github_account",
627
- "github_organization",
628
- "google_workspace_domain",
629
- "notion_workspace",
630
- "slack_workspace"
631
- ]);
632
- var CEAL_PROVIDER_BOUNDARY_EVIDENCE = vocabulary(["provider_readback", "operator_stated"]);
633
2722
  var CEAL_ACCESS_LEVELS = vocabulary(["none", "read", "read_write"]);
634
2723
  var CEAL_PERSONAL_ACCESS_CEILINGS = vocabulary(["disabled", "read", "read_write"]);
635
2724
  var CEAL_TARGET_REF_PATTERN = "^[^\\p{Cc}]+$";
636
2725
  var TARGET_REF = new RegExp(CEAL_TARGET_REF_PATTERN, "u");
637
2726
  var CEAL_TARGET_VISIBILITIES = vocabulary(["public", "private"]);
638
- var CEAL_PRINCIPAL_KINDS = vocabulary(["human", "service", "runtime"]);
2727
+ var CEAL_PRINCIPAL_KINDS = vocabulary(["human", "runtime"]);
2728
+ var CEAL_PERSISTED_PRINCIPAL_KINDS = vocabulary(["human", "service", "runtime"]);
639
2729
  var CEAL_ORGANIZATION_ROLES = vocabulary(["member", "admin"]);
2730
+ var CEAL_CALENDAR_PERIODS = vocabulary(["day", "week", "month"]);
640
2731
  var LABEL_EXPECTATION = `public-safe display text of at most ${CEAL_PUBLIC_DISPLAY_NAME_MAX_BYTES} bytes`;
641
2732
 
642
2733
  // packages/ceal-client-protocol/src/safe-json-budget.ts
@@ -812,7 +2903,7 @@ var CEAL_SCHEMA_LITERALS = [
812
2903
  "ceal.operation_receipt.v1",
813
2904
  "ceal.operation_result.v1",
814
2905
  "ceal.operation_result.compact.v1",
815
- "ceal.local_result_materialization.v1",
2906
+ "ceal.local_result_file.v1",
816
2907
  "ceal.local_result_root.v1",
817
2908
  "ceal.owner_bootstrap_exchange_request.v1",
818
2909
  "ceal.owner_bootstrap_exchange_result.v1",
@@ -842,6 +2933,9 @@ var CEAL_BOUNDED_SERIES_CATALOG = Object.freeze({
842
2933
  gateway_personal_client_access_audit: (root) => join(root, "access-audit.jsonl")
843
2934
  });
844
2935
 
2936
+ // packages/ceal-client-protocol/src/canonical-http-boundary.ts
2937
+ var CEAL_CANONICAL_HTTP_MAX_RESPONSE_BYTES = CEAL_COMMAND_RESPONSE_MAX_BYTES;
2938
+
845
2939
  // packages/ceal-client-protocol/src/gateway-installation-activation.ts
846
2940
  var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_DATA_CHARACTERS = 32;
847
2941
  var CEAL_GATEWAY_INSTALLATION_ACTIVATION_CODE_CHECK_CHARACTERS = 8;
@@ -906,41 +3000,6 @@ var CEAL_VERIFIED_ARTIFACT_DESCRIPTOR_JSON_SCHEMA = Object.freeze({
906
3000
  }
907
3001
  });
908
3002
 
909
- // packages/ceal-client-protocol/src/provider-operation-vocabulary.ts
910
- var CEAL_FILE_TYPE_FAMILIES = vocabulary(["all", "image", "pdf"]);
911
- var CEAL_GITHUB_ISSUE_STATES = vocabulary(["open", "closed", "all"]);
912
- var CEAL_NOTION_UPDATABLE_BLOCK_TYPES = vocabulary([
913
- "paragraph",
914
- "heading_1",
915
- "heading_2",
916
- "heading_3",
917
- "bulleted_list_item",
918
- "numbered_list_item",
919
- "to_do",
920
- "code"
921
- ]);
922
- var CEAL_NOTION_NEUTRAL_TYPES = vocabulary([
923
- "text",
924
- "number",
925
- "boolean",
926
- "date",
927
- "select",
928
- "multi_select",
929
- "people",
930
- "url",
931
- "email",
932
- "phone",
933
- "unsupported"
934
- ]);
935
- var CEAL_NOTION_IDENTITY_GAP_REASONS = vocabulary([
936
- "identity_unavailable",
937
- "identity_stale",
938
- "identity_ambiguous",
939
- "identity_revoked",
940
- "identity_unlinked"
941
- ]);
942
- var CEAL_NOTION_STRING_VALUE_TYPES = vocabulary(["text", "select", "url", "email", "phone"]);
943
-
944
3003
  // packages/ceal-client-protocol/src/opaque-reference.ts
945
3004
  var CEAL_OPAQUE_HANDLE_KINDS = vocabulary(["target", "message", "thread", "artifact", "document", "block", "object"]);
946
3005
  var CEAL_OPAQUE_REF_KINDS = vocabulary([...CEAL_OPAQUE_HANDLE_KINDS, "result", "operation-receipt", "reply-receipt", "field", "notion-data-source"]);
@@ -950,6 +3009,7 @@ var REQUIRED_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_f
950
3009
  var OPTIONAL_FIELDS = CEAL_CLIENT_WIRE_CONTRACT.command_response.bare_document_optional_fields;
951
3010
 
952
3011
  // packages/ceal-client-protocol/src/resource-row.ts
3012
+ var CEAL_RESOURCE_ROW_TITLE_MATCH_DISPOSITIONS = vocabulary(["exact", "not_exact", "unknown"]);
953
3013
  var CEAL_RESOURCE_SEARCH_ORDERS = vocabulary(["relevance", "modified", "viewed", "created"]);
954
3014
  var CEAL_RESOURCE_SEARCH_DIRECTIONS = vocabulary(["ascending", "descending"]);
955
3015
  var CEAL_RESOURCE_SEARCH_FILTERS = vocabulary(["query", "modified_since", "since", "until", "authored_by_me", "authored_by", "include_replies", "kinds", "container_ref", "container_refs", "container_names", "addressed_to_me", "unread"]);
@@ -973,6 +3033,7 @@ var CEAL_ACTIVITY_TIMESTAMP_BASES = vocabulary([
973
3033
  "resource_modified"
974
3034
  ]);
975
3035
  var CEAL_ACTIVITY_CONNECTOR_KINDS = vocabulary(["slack", "github", "google-calendar", "google-drive", "notion"]);
3036
+ var CEAL_ACTIVITY_UNSUPPORTED_EVENT_KIND_CODE = "unsupported_event_kind";
976
3037
  var CEAL_ACTIVITY_GAP_CODES = vocabulary([
977
3038
  "provider_page_budget",
978
3039
  "call_deadline",
@@ -980,7 +3041,7 @@ var CEAL_ACTIVITY_GAP_CODES = vocabulary([
980
3041
  "provider_cursor_unavailable",
981
3042
  "malformed_provider_page",
982
3043
  "visibility_incomplete",
983
- "unsupported_event_kind",
3044
+ CEAL_ACTIVITY_UNSUPPORTED_EVENT_KIND_CODE,
984
3045
  "direct_messages_excluded"
985
3046
  ]);
986
3047
  var CEAL_ACTIVITY_EVENT_KINDS = vocabulary([
@@ -1032,6 +3093,7 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
1032
3093
  next: { required: true, timestamp: false },
1033
3094
  kind: { required: true, timestamp: false },
1034
3095
  matched_kinds: { required: false, timestamp: false },
3096
+ title_match: { required: false, timestamp: false },
1035
3097
  title: { required: true, timestamp: false },
1036
3098
  container_label: { required: true, timestamp: false },
1037
3099
  container_ref: { required: false, timestamp: false },
@@ -1045,6 +3107,8 @@ var RESOURCE_ROW_KEY_RULES = Object.freeze({
1045
3107
  modified_at: { required: false, timestamp: true },
1046
3108
  modified_at_local: { required: false, timestamp: true },
1047
3109
  viewed_by_me_at: { required: false, timestamp: true },
3110
+ own_ceal_write: { required: false, timestamp: false },
3111
+ owned_by_me: { required: false, timestamp: false },
1048
3112
  visibility: { required: false, timestamp: false },
1049
3113
  start: { required: false, timestamp: false },
1050
3114
  end: { required: false, timestamp: false },
@@ -1078,6 +3142,15 @@ function cealExcludedTargetCoverageJsonSchema() {
1078
3142
  };
1079
3143
  }
1080
3144
 
3145
+ // packages/ceal-client-protocol/src/gateway-write-identity.ts
3146
+ var CEAL_GATEWAY_WRITE_IDENTITY_ROLES = Object.freeze(["replay_identity", "lookup_handle", "collision_evidence"]);
3147
+ var CEAL_GATEWAY_WRITE_REQUEST_REF_PATTERN = /^gateway-write-request:[a-f0-9]{8}-(?:[a-f0-9]{4}-){3}[a-f0-9]{12}$/u;
3148
+ var CEAL_GATEWAY_WRITE_IDENTITY_FIELDS = Object.freeze({
3149
+ replay_identity: "idempotency_claim_sha256",
3150
+ lookup_handle: "write_request_sha256",
3151
+ collision_evidence: "normalized_mutation_sha256"
3152
+ });
3153
+
1081
3154
  // packages/ceal-client-protocol/src/write-safety-finding.ts
1082
3155
  var CEAL_WRITE_SAFETY_FINDING_STATUSES = vocabulary(["warning", "unchecked"]);
1083
3156
  var CEAL_WRITE_SAFETY_AUDIENCES = vocabulary(["workspace", "person", "members", "unknown"]);
@@ -1105,7 +3178,11 @@ var CEAL_REFRESH_FAILURE_CODES = vocabulary([
1105
3178
  "refresh_revoked",
1106
3179
  "authority_replaced",
1107
3180
  "refresh_recovery_unavailable",
1108
- "refresh_recovery_expired"
3181
+ "refresh_recovery_expired",
3182
+ // The serving gate answers this while the Gateway is still starting and the
3183
+ // refresh was never attempted; the same attempt stays retryable. It is never
3184
+ // stored by the session owner, only answered at the serving edge.
3185
+ "gateway_starting"
1109
3186
  ]);
1110
3187
 
1111
3188
  // packages/ceal-client-protocol/src/request-validation-primitives.ts
@@ -1138,7 +3215,7 @@ var CANCELLATION_STATES = vocabulary(["requested", "cancelled"]);
1138
3215
  var CEAL_REQUEST_KEYS = Object.freeze(["schema_version", "ceal_request_ref", "created_at", "authority", "prompt_ref", "host_session_ref", "host_turn_ref", "host_source_ref"]);
1139
3216
  var CEAL_REQUEST_JSON_SCHEMA = {
1140
3217
  type: "object",
1141
- maxProperties: 10,
3218
+ maxProperties: 11,
1142
3219
  additionalProperties: false,
1143
3220
  properties: {
1144
3221
  schema_version: { type: "string", const: CEAL_REQUEST_SCHEMA_VERSION, maxLength: 32 },
@@ -1162,7 +3239,8 @@ var CEAL_REQUEST_JSON_SCHEMA = {
1162
3239
  host_turn_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1163
3240
  host_input_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1164
3241
  host_source_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source },
1165
- requester_timezone: { type: "string", minLength: 1, maxLength: 128, description: "IANA timezone observed for the requester on this Request." }
3242
+ requester_timezone: { type: "string", minLength: 1, maxLength: 128, description: "IANA timezone observed for the requester on this Request." },
3243
+ device_ref: { type: "string", minLength: 1, maxLength: 128, pattern: SAFE_REF.source, description: "Device that submitted this Request through its client session; absent for Host turns and older records." }
1166
3244
  },
1167
3245
  required: CEAL_REQUEST_KEYS
1168
3246
  };
@@ -1221,6 +3299,7 @@ var REQUEST_EXECUTION_PREPARE_REFUSAL_PROPERTIES = {
1221
3299
  retryable: { type: "boolean" },
1222
3300
  source: { type: "string", enum: ["provider", "gateway"] },
1223
3301
  retry_after_ms: { type: "integer", minimum: 0, maximum: CEAL_RETRY_AFTER_MAX_MS },
3302
+ write_request_ref: { type: "string", pattern: CEAL_GATEWAY_WRITE_REQUEST_REF_PATTERN.source, maxLength: 128 },
1224
3303
  excluded_targets: cealExcludedTargetCoverageJsonSchema(),
1225
3304
  repaired_input: {},
1226
3305
  unrepaired_pointers: { type: "array", maxItems: 128, items: { type: "string", minLength: 1, maxLength: 256 } },
@@ -1285,6 +3364,43 @@ function cealHostObservationRef(producer, digest2) {
1285
3364
  if (!HOST_OBSERVATION_PRODUCER.test(producer) || !HOST_OBSERVATION_DIGEST.test(digest2)) invalid("Ceal Host observation reference parts are invalid.");
1286
3365
  return `${CEAL_HOST_OBSERVATION_REF_PREFIX}${producer}-${digest2}`;
1287
3366
  }
3367
+ var HOST_TOKEN_OBSERVATION_BREAKDOWN_KEYS = vocabulary(["cached_input", "cache_write_input", "reasoning_output"]);
3368
+ function createHostTokenObservationValue(counts, source) {
3369
+ const core = validTokenCore(counts);
3370
+ if (typeof source !== "string" || source.length === 0 || source.length > 256) invalid("Ceal Host token observation source is invalid.");
3371
+ const value = { status: "available", unit: "tokens", input: core.input, output: core.output, total: core.total, source };
3372
+ for (const breakdown of validTokenBreakdowns(counts)) value[breakdown.key] = breakdown.tokens;
3373
+ assertHostObservationValue(value, "token");
3374
+ return value;
3375
+ }
3376
+ function validTokenCore(counts) {
3377
+ if (!isOperationRecord(counts) || !safeCount(counts.input) || !safeCount(counts.output) || !safeCount(counts.total)) invalid("Ceal Host token observation counts are invalid.");
3378
+ if (counts.total !== counts.input + counts.output) invalid("Ceal Host token observation counts are invalid.");
3379
+ return { input: counts.input, output: counts.output, total: counts.total };
3380
+ }
3381
+ function validTokenBreakdowns(counts) {
3382
+ const breakdowns = [
3383
+ { key: "cached_input", tokens: counts.cached_input },
3384
+ { key: "cache_write_input", tokens: counts.cache_write_input },
3385
+ { key: "reasoning_output", tokens: counts.reasoning_output }
3386
+ ];
3387
+ const stated = breakdowns.filter((breakdown) => breakdown.tokens !== void 0).map((breakdown) => ({ key: breakdown.key, tokens: Number(breakdown.tokens) }));
3388
+ for (const breakdown of stated) {
3389
+ if (!safeCount(breakdown.tokens)) invalid("Ceal Host token observation counts are invalid.");
3390
+ }
3391
+ const cached = counts.cached_input ?? 0;
3392
+ const created = counts.cache_write_input ?? 0;
3393
+ const reasoning = counts.reasoning_output ?? 0;
3394
+ if (cached + created > counts.input || reasoning > counts.output) invalid("Ceal Host token observation counts are invalid.");
3395
+ return stated;
3396
+ }
3397
+ function hostObservationNotRecorded(reason) {
3398
+ if (typeof reason !== "string" || reason.length === 0 || reason.length > 256) invalid("Ceal Host observation gap reason is invalid.");
3399
+ return { status: "not_recorded", reason };
3400
+ }
3401
+ function safeCount(value) {
3402
+ return Number.isSafeInteger(value) && Number(value) >= 0;
3403
+ }
1288
3404
  function validateCealHostObservationDraft(value) {
1289
3405
  const record3 = operationRecord(value, "Ceal Host observation draft is invalid.");
1290
3406
  requirePrefixedRef(record3.observation_ref, CEAL_HOST_OBSERVATION_REF_PREFIX, "Ceal Host observation reference is invalid.");
@@ -1437,6 +3553,55 @@ var CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS = vocabulary([
1437
3553
  "host_input_mismatch",
1438
3554
  "host_prompt_mismatch"
1439
3555
  ]);
3556
+ var CEAL_HOST_AUTHENTICATION_CAUSES = vocabulary([
3557
+ "invalid_arguments",
3558
+ "options_invalid",
3559
+ "session_unavailable",
3560
+ "context_unavailable",
3561
+ "context_replaced",
3562
+ "no_binding",
3563
+ "context_stale",
3564
+ "context_expired",
3565
+ "host_source_refused",
3566
+ "host_credential_refused",
3567
+ "gateway_unavailable",
3568
+ "gateway_rate_limited",
3569
+ "gateway_refused",
3570
+ "gateway_response_invalid",
3571
+ "producer_frame_invalid",
3572
+ "relay_permission_denied",
3573
+ "relay_unavailable",
3574
+ "transient_retryable",
3575
+ "mint_failed",
3576
+ "relay_failed",
3577
+ "host_refusal_invalid"
3578
+ ]);
3579
+ var CEAL_HOST_AUTHENTICATION_POLICY = Object.freeze({
3580
+ invalid_arguments: Object.freeze({ classification: "host_arguments_invalid", next_action: "answer_with_gap" }),
3581
+ options_invalid: Object.freeze({ classification: "host_configuration_invalid", next_action: "answer_with_gap" }),
3582
+ session_unavailable: Object.freeze({ classification: "host_session_unavailable", next_action: "answer_with_gap" }),
3583
+ context_unavailable: Object.freeze({ classification: "host_context_unavailable", next_action: "refresh_host_invocation_context", remedy: "the Host has no invocation context from the current transcript turn; send a new message to start a fresh Host turn, then retry this command on that turn (run `ceal-host install` only if the Host hook registration is missing or drifted)" }),
3584
+ context_replaced: Object.freeze({ classification: "host_invocation_context_stale", next_action: "refresh_host_invocation_context" }),
3585
+ no_binding: Object.freeze({ classification: "host_binding_unavailable", next_action: "refresh_host_invocation_context" }),
3586
+ context_stale: Object.freeze({ classification: "host_invocation_context_stale", next_action: "refresh_host_invocation_context" }),
3587
+ context_expired: Object.freeze({ classification: "host_invocation_context_expired", next_action: "refresh_host_invocation_context" }),
3588
+ host_source_refused: Object.freeze({ classification: "host_source_refused", next_action: "answer_with_gap" }),
3589
+ host_credential_refused: Object.freeze({ classification: "host_registration_credential_refused", next_action: "ask_admin" }),
3590
+ gateway_unavailable: Object.freeze({ classification: "host_mint_gateway_unavailable", next_action: "ask_admin" }),
3591
+ gateway_rate_limited: Object.freeze({ classification: "host_mint_gateway_rate_limited", next_action: "answer_with_gap" }),
3592
+ gateway_refused: Object.freeze({ classification: "host_mint_gateway_refused", next_action: "answer_with_gap" }),
3593
+ gateway_response_invalid: Object.freeze({ classification: "host_mint_gateway_response_invalid", next_action: "answer_with_gap" }),
3594
+ producer_frame_invalid: Object.freeze({ classification: "host_producer_frame_invalid", next_action: "ask_admin", remedy: "ask an administrator to inspect and repair the producer frame, then start a fresh Host turn" }),
3595
+ relay_permission_denied: Object.freeze({ classification: "host_relay_permission_denied", next_action: "rerun_outside_agent_sandbox", remedy: "an agent sandbox denied the Host Relay socket; run `ceal` as the only command, with no pipe, redirect, or `&&`, so the Host allow rule runs it outside the sandbox" }),
3596
+ relay_unavailable: Object.freeze({ classification: "host_relay_unavailable", next_action: "answer_with_gap" }),
3597
+ transient_retryable: Object.freeze({ classification: "host_mint_transient_retryable", next_action: "retry" }),
3598
+ mint_failed: Object.freeze({ classification: "host_mint_failed", next_action: "answer_with_gap" }),
3599
+ relay_failed: Object.freeze({ classification: "host_relay_failed", next_action: "answer_with_gap" }),
3600
+ host_refusal_invalid: Object.freeze({ classification: "host_refusal_invalid", next_action: "answer_with_gap" })
3601
+ });
3602
+ function isCealHostAuthenticationCause(value) {
3603
+ return isVocabularyWord(CEAL_HOST_AUTHENTICATION_CAUSES, value);
3604
+ }
1440
3605
  function decodeCealHostInvocationAuthenticationRequest(value) {
1441
3606
  if (!isCealJsonRecord(value) || !exactKeys(value, ["schema_version", "client_nonce"]) || value.schema_version !== CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA || typeof value.client_nonce !== "string" || !CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce)) {
1442
3607
  throw new TypeError("The Host invocation authentication request is invalid.");
@@ -1450,19 +3615,46 @@ function decodeCealHostInvocationAuthenticationResult(value, now = /* @__PURE__
1450
3615
  return Object.freeze({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_RESULT_SCHEMA, context_token: value.context_token, expires_at: value.expires_at });
1451
3616
  }
1452
3617
  function validFutureTimestamp(value, now) {
1453
- const timestamp5 = Date.parse(value);
1454
- return Number.isFinite(timestamp5) && new Date(timestamp5).toISOString() === value && timestamp5 > now.getTime();
3618
+ const timestamp4 = Date.parse(value);
3619
+ return Number.isFinite(timestamp4) && new Date(timestamp4).toISOString() === value && timestamp4 > now.getTime();
1455
3620
  }
1456
3621
  function exactKeys(value, expected) {
1457
3622
  const keys = Object.keys(value);
1458
3623
  return keys.length === expected.length && expected.every((key) => Object.hasOwn(value, key));
1459
3624
  }
1460
3625
 
3626
+ // packages/ceal-client-protocol/src/host-service-diagnostic.ts
3627
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_SCHEMA = "ceal.host_service_diagnostic.v1";
3628
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_PRODUCERS = vocabulary(["claude", "codex"]);
3629
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_EVENTS = vocabulary([
3630
+ "hook_invoked",
3631
+ "registration_written",
3632
+ "hook_failed",
3633
+ "watcher_turn_observed",
3634
+ "current_prompt_registered",
3635
+ "current_prompt_registration_failed",
3636
+ "current_prompt_capacity_exhausted",
3637
+ "activation_recorded",
3638
+ "activation_failed",
3639
+ "watcher_scan_failed",
3640
+ "activation_wait_skipped",
3641
+ "activation_wait_engaged",
3642
+ "activation_wait_completed",
3643
+ "activation_wait_exhausted"
3644
+ ]);
3645
+ var CEAL_HOST_SERVICE_DIAGNOSTIC_FAILURE_KINDS = vocabulary([
3646
+ "malformed_line",
3647
+ "other",
3648
+ "payload_rejected",
3649
+ "read_error",
3650
+ "size_budget",
3651
+ "symlink"
3652
+ ]);
3653
+
1461
3654
  // packages/ceal-client-protocol/src/client-result-materialization.ts
1462
3655
  var CEAL_UNREAD_REASONS = vocabulary(["blocked", "unavailable", "too_large", "unsupported", "download_failed", "permission_denied"]);
1463
- var CEAL_MODEL_VISIBLE_COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
1464
- var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "read_argv"]);
1465
- var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS2, "local_result_root", "continue_argv", "model_disclosure"]);
3656
+ var REQUIRED_FIELDS2 = Object.freeze(["schema_version", "operation_id", "path", "sha256"]);
3657
+ var FIELDS = /* @__PURE__ */ new Set([...REQUIRED_FIELDS2, "items_path", "row_count", "result_complete", "coverage", "local_result_root", "model_disclosure", "continue_argv", "how_to_read"]);
1466
3658
 
1467
3659
  // packages/ceal-client-protocol/src/gateway-cache-origin-validation.ts
1468
3660
  var CEAL_MAX_CACHE_ORIGIN_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -1492,14 +3684,6 @@ var CEAL_GATEWAY_ANNOUNCEMENT_POLICY_NON_CLAIMS = vocabulary([
1492
3684
  "target_specific_scope_not_declared"
1493
3685
  ]);
1494
3686
 
1495
- // packages/ceal-client-protocol/src/gateway-write-identity.ts
1496
- var CEAL_GATEWAY_WRITE_IDENTITY_ROLES = Object.freeze(["replay_identity", "lookup_handle", "collision_evidence"]);
1497
- var CEAL_GATEWAY_WRITE_IDENTITY_FIELDS = Object.freeze({
1498
- replay_identity: "idempotency_claim_sha256",
1499
- lookup_handle: "write_request_sha256",
1500
- collision_evidence: "normalized_mutation_sha256"
1501
- });
1502
-
1503
3687
  // packages/ceal-client-protocol/src/gateway-scoped-identity-projection-validation.ts
1504
3688
  var PROJECTION_REVISION_KEYS = Object.freeze(["graph_revision", "subject_key_revision", "projection_revision"]);
1505
3689
 
@@ -1512,6 +3696,18 @@ var CEAL_SUPPORTED_GATEWAY_PROTOCOL_RANGE = Object.freeze({
1512
3696
  // packages/ceal-client-protocol/src/admin-projection-vocabulary.ts
1513
3697
  var ADMIN_PROJECTION_STATES = vocabulary(["ready", "empty", "partial", "unknown"]);
1514
3698
  var ADMIN_VIEW_KINDS = vocabulary(["request_detail", "resource_access_timeline", "weekly_usage"]);
3699
+ var ADMIN_RECORD_PROJECTION_KINDS = vocabulary([
3700
+ "request_list",
3701
+ "usage_series",
3702
+ "connector_health",
3703
+ "person_connections",
3704
+ "client_sessions",
3705
+ "knowledge_base",
3706
+ "change_history",
3707
+ "approval_queue",
3708
+ "access_group_list",
3709
+ "capability_catalogue"
3710
+ ]);
1515
3711
  var ADMIN_GAP_KINDS = vocabulary(["unknown", "unavailable", "partial"]);
1516
3712
  var ADMIN_UNAVAILABLE_REASONS = vocabulary([
1517
3713
  "not_recorded",
@@ -1535,7 +3731,11 @@ var ADMIN_SOURCE_OWNERS = vocabulary([
1535
3731
  "person",
1536
3732
  "resource",
1537
3733
  "prompt",
1538
- "usage"
3734
+ "usage",
3735
+ "connector",
3736
+ "session",
3737
+ "knowledge",
3738
+ "policy"
1539
3739
  ]);
1540
3740
  var ADMIN_COMPLETENESS_STATES = vocabulary(["complete", "partial", "unknown"]);
1541
3741
  var ADMIN_OPERATION_OUTCOMES = vocabulary(["completed", "failed", "denied", "cancelled", "unknown"]);
@@ -1813,6 +4013,9 @@ async function doctorCodexClient(options = {}) {
1813
4013
  return { schema_version: CODEX_CLIENT_DOCTOR_SCHEMA_VERSION, ...await doctorClient(options, "Codex") };
1814
4014
  }
1815
4015
 
4016
+ // host/invocation-authentication-command.ts
4017
+ import { performance } from "node:perf_hooks";
4018
+
1816
4019
  // host/relay/src/producer-frame.ts
1817
4020
  var HOST_PRODUCER_FRAME_SCHEMA = "ceal.host_producer_frame.v1";
1818
4021
  var HOST_PRODUCER_MAX_JSON_BYTES = 262144;
@@ -1824,6 +4027,15 @@ var FRAME_KINDS = new Set(HOST_PRODUCER_FRAME_KINDS);
1824
4027
  function isHostProducerFrameKind(value) {
1825
4028
  return typeof value === "string" && FRAME_KINDS.has(value);
1826
4029
  }
4030
+ var HOST_PRODUCER_FRAME_ERROR_CODES = [
4031
+ "invalid_frame_encoding",
4032
+ "invalid_frame_length",
4033
+ "frame_truncated",
4034
+ "unsupported_frame_schema",
4035
+ "invalid_frame_shape",
4036
+ "invalid_producer_identity",
4037
+ "frame_too_large"
4038
+ ];
1827
4039
  var HostProducerFrameError = class extends Error {
1828
4040
  code;
1829
4041
  constructor(code, message = code) {
@@ -1858,6 +4070,9 @@ function decodeHostProducerFrame(input) {
1858
4070
  validateFrame(value);
1859
4071
  return value;
1860
4072
  }
4073
+ function isHostSafeRef(value) {
4074
+ return safeRef(value);
4075
+ }
1861
4076
  function validateFrame(value) {
1862
4077
  if (!record(value)) throw new HostProducerFrameError("invalid_frame_shape");
1863
4078
  if (value.schema_version !== HOST_PRODUCER_FRAME_SCHEMA) throw new HostProducerFrameError("unsupported_frame_schema", `unsupported_frame_schema: ${refusalFact("schema_version", value.schema_version, HOST_PRODUCER_FRAME_SCHEMA)}`);
@@ -1945,6 +4160,15 @@ function exactOptional(value, required, optional) {
1945
4160
  return required.every((key) => keys.includes(key)) && keys.every((key) => required.includes(key) || optional.includes(key));
1946
4161
  }
1947
4162
 
4163
+ // host/relay/src/host-producer-core.ts
4164
+ import { createHash as createHash3 } from "node:crypto";
4165
+ import { O_NOFOLLOW, O_RDONLY as O_RDONLY2 } from "node:constants";
4166
+ import { mkdir as mkdir2, open as open3, readFile as readFile2, rename as rename2, writeFile } from "node:fs/promises";
4167
+ import { join as join3 } from "node:path";
4168
+
4169
+ // host/relay/src/relay-ipc.ts
4170
+ import { createConnection, createServer } from "node:net";
4171
+
1948
4172
  // host/relay/src/durable-atomic-replacement.ts
1949
4173
  import { O_RDONLY } from "node:constants";
1950
4174
  import { lstat, mkdir, open as open2, rename, unlink } from "node:fs/promises";
@@ -1962,20 +4186,24 @@ var DEFAULT_PORT = {
1962
4186
  // host/relay/src/relay-request-binding-store.ts
1963
4187
  var MAX_STATE_BYTES = 8 * 1024 * 1024;
1964
4188
 
1965
- // host/relay/src/relay-quarantine-store.ts
1966
- var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
1967
-
1968
- // host/relay/src/relay-admission-store.ts
1969
- var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
1970
- var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
1971
- var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
1972
-
1973
- // host/relay/src/relay-ipc.ts
1974
- import { createConnection, createServer } from "node:net";
1975
-
1976
4189
  // host/relay/src/current-prompt-custody.ts
1977
4190
  var HOST_CURRENT_PROMPT_MAX_BYTES = 256 * 1024;
1978
4191
 
4192
+ // host/service-log.ts
4193
+ function writeHostServiceDiagnostic(producer_id, event, failure_kind, cause, sink) {
4194
+ const line = `${JSON.stringify({ schema_version: CEAL_HOST_SERVICE_DIAGNOSTIC_SCHEMA, producer_id, event, ...event === "watcher_scan_failed" && failure_kind !== void 0 ? { failure_kind } : {}, ...event === "watcher_scan_failed" && cause !== void 0 ? { cause } : {} })}
4195
+ `;
4196
+ try {
4197
+ (sink ?? defaultHostServiceDiagnosticSink)(line);
4198
+ } catch {
4199
+ }
4200
+ }
4201
+ function defaultHostServiceDiagnosticSink(line) {
4202
+ process.stderr.write(line);
4203
+ }
4204
+ var HOST_SERVICE_LOG_MAX_BYTES = 1024 * 1024;
4205
+ var HOST_SERVICE_LOG_TAIL_BYTES = 64 * 1024;
4206
+
1979
4207
  // host/relay/src/relay-ipc.ts
1980
4208
  var HOST_RELAY_REQUEST_BINDING_KEYS = Object.freeze([
1981
4209
  "schema_version",
@@ -1996,6 +4224,7 @@ var HOST_RELAY_IPC_RESPONSE_SCHEMA = "ceal.host_relay_admission.v1";
1996
4224
  var HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA = "ceal.host_relay_invocation_context_query.v1";
1997
4225
  var HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA = "ceal.host_relay_invocation_context_result.v1";
1998
4226
  var HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA = "ceal.host_relay_current_prompt_register.v1";
4227
+ var HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA = "ceal.host_relay_current_prompt_release.v1";
1999
4228
  var HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA = "ceal.host_relay_current_prompt_result.v1";
2000
4229
  var HOST_RELAY_IPC_LENGTH_BYTES = Uint32Array.BYTES_PER_ELEMENT;
2001
4230
  var HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES = 4096;
@@ -2008,6 +4237,8 @@ var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
2008
4237
  "gateway_unavailable",
2009
4238
  "gateway_refused",
2010
4239
  "gateway_response_invalid",
4240
+ "gateway_rate_limited",
4241
+ "producer_frame_invalid",
2011
4242
  "deadline",
2012
4243
  "cancelled",
2013
4244
  "mint_failed",
@@ -2021,6 +4252,17 @@ var HOST_RELAY_INVOCATION_MINT_REFUSAL_REASONS = vocabulary([
2021
4252
  "host_input_mismatch",
2022
4253
  "host_prompt_mismatch"
2023
4254
  ]);
4255
+ var HOST_RELAY_DIRECT_WIRE_MINT_REASONS = vocabulary([
4256
+ "context_stale",
4257
+ "context_expired",
4258
+ "host_source_refused",
4259
+ "host_credential_refused",
4260
+ "gateway_unavailable",
4261
+ "gateway_rate_limited",
4262
+ "gateway_refused",
4263
+ "gateway_response_invalid",
4264
+ "producer_frame_invalid"
4265
+ ]);
2024
4266
  var HOST_RELAY_INVOCATION_MINT_OUTCOMES = vocabulary(["completed", "caller_cancelled", "deadline", "failed", "no_binding"]);
2025
4267
  var HOST_RELAY_EXCHANGE_FAILURES = vocabulary([
2026
4268
  "permission_denied",
@@ -2042,6 +4284,12 @@ var HostRelayIpcError = class extends Error {
2042
4284
  this.failure = failure2;
2043
4285
  }
2044
4286
  };
4287
+ var HostRelayCurrentPromptCapacityRefusal = class extends Error {
4288
+ constructor() {
4289
+ super("current_prompt_capacity_exhausted");
4290
+ this.name = "HostRelayCurrentPromptCapacityRefusal";
4291
+ }
4292
+ };
2045
4293
  function hostRelayExchangeFailure(error) {
2046
4294
  return error instanceof HostRelayIpcError ? error.failure : void 0;
2047
4295
  }
@@ -2090,8 +4338,14 @@ var HostRelayCurrentPromptPort = class {
2090
4338
  async register(input) {
2091
4339
  const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_REGISTER_SCHEMA, ...input };
2092
4340
  const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
4341
+ if (response2.status === "capacity_exhausted") throw new HostRelayCurrentPromptCapacityRefusal();
2093
4342
  if (response2.status !== "registered") throw new HostRelayIpcError("relay_unavailable", response2.status);
2094
4343
  }
4344
+ async release(identity) {
4345
+ const request2 = { schema_version: HOST_RELAY_CURRENT_PROMPT_RELEASE_SCHEMA, ...identity };
4346
+ const response2 = await exchange(this.endpoint, encodeLengthPrefixed(request2), this.timeout_ms, decodeCurrentPromptResponseBuffer);
4347
+ if (response2.status !== "released") throw new HostRelayIpcError("relay_unavailable", response2.status, "response_invalid");
4348
+ }
2095
4349
  };
2096
4350
  function submitHostProducerFrame(endpoint, frame, timeoutMs = 5e3) {
2097
4351
  return exchange(endpoint, encodeHostProducerFrame(frame), timeoutMs, decodeResponseBuffer);
@@ -2183,7 +4437,7 @@ function decodeInvocationContextResponseBuffer(buffer) {
2183
4437
  function decodeCurrentPromptResponseBuffer(buffer) {
2184
4438
  const value = decodeLengthPrefixedJson(buffer, HOST_RELAY_ADMISSION_RESPONSE_MAX_BYTES);
2185
4439
  if (value === null) return null;
2186
- if (!record2(value) || !exactKeys3(value, ["schema_version", "status"]) || value.schema_version !== HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA || value.status !== "registered" && value.status !== "current_prompt_unavailable") throw new HostRelayIpcError("relay_unavailable");
4440
+ if (!record2(value) || !exactKeys3(value, ["schema_version", "status"]) || value.schema_version !== HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA || value.status !== "registered" && value.status !== "capacity_exhausted" && value.status !== "current_prompt_unavailable" && value.status !== "released") throw new HostRelayIpcError("relay_unavailable", "Host Relay current-prompt response is invalid.", "response_invalid");
2187
4441
  return { schema_version: HOST_RELAY_CURRENT_PROMPT_RESULT_SCHEMA, status: value.status };
2188
4442
  }
2189
4443
  function encodeInvocationContextQuery(query) {
@@ -2192,11 +4446,14 @@ function encodeInvocationContextQuery(query) {
2192
4446
  return encodeLengthPrefixed(value);
2193
4447
  }
2194
4448
  function validInvocationContextQueryRequest(value) {
2195
- return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "client_nonce"]) && typeof value.client_nonce === "string" && CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce);
4449
+ return validQueryIdentity(value, HOST_RELAY_INVOCATION_CONTEXT_QUERY_SCHEMA) && exactKeys3(value, ["schema_version", "producer_id", "producer_installation_ref", "local_session_ref", "local_turn_ref", "client_nonce"], ["visible_output_max_bytes"]) && typeof value.client_nonce === "string" && CEAL_HOST_CLIENT_NONCE_PATTERN.test(value.client_nonce) && (value.visible_output_max_bytes === void 0 || validVisibleOutputBudget(value.visible_output_max_bytes));
2196
4450
  }
2197
4451
  function validQueryIdentity(value, schema) {
2198
4452
  return record2(value) && value.schema_version === schema && (value.producer_id === "codex" || value.producer_id === "claude") && safeRef2(value.producer_installation_ref) && safeRef2(value.local_session_ref) && safeRef2(value.local_turn_ref);
2199
4453
  }
4454
+ function validVisibleOutputBudget(value) {
4455
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= CEAL_CANONICAL_HTTP_MAX_RESPONSE_BYTES;
4456
+ }
2200
4457
  function validInvocationContextResponse(value) {
2201
4458
  if (!record2(value) || value.schema_version !== HOST_RELAY_INVOCATION_CONTEXT_RESULT_SCHEMA) return false;
2202
4459
  if (value.status === "no_binding") return Object.keys(value).length === 2;
@@ -2228,8 +4485,9 @@ function encodeLengthPrefixed(value) {
2228
4485
  body.copy(output, HOST_RELAY_IPC_LENGTH_BYTES);
2229
4486
  return output;
2230
4487
  }
2231
- function exactKeys3(value, keys) {
2232
- return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
4488
+ function exactKeys3(value, required, optional = []) {
4489
+ const keys = Object.keys(value);
4490
+ return required.every((key) => Object.hasOwn(value, key)) && keys.every((key) => required.includes(key) || optional.includes(key));
2233
4491
  }
2234
4492
  function safeRef2(value) {
2235
4493
  return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
@@ -2238,24 +4496,385 @@ function errorCode2(error) {
2238
4496
  return record2(error) && typeof error.code === "string" ? error.code : null;
2239
4497
  }
2240
4498
 
4499
+ // host/relay/src/host-producer-core.ts
4500
+ var HOST_TRANSCRIPT_CURSOR_REASONS = vocabulary(["transcript_replaced", "transcript_truncated", "transcript_rewritten", "transcript_malformed"]);
4501
+ function isHostTranscriptCursorReason(value) {
4502
+ return typeof value === "string" && HOST_TRANSCRIPT_CURSOR_REASONS.some((reason) => reason === value);
4503
+ }
4504
+ var TRANSCRIPT_MISSING_REASON = "transcript_missing";
4505
+ var TRANSCRIPT_SCAN_READ_ERROR_ERRNOS = ["EBADF", "EACCES", "EIO", "EMFILE", "ENFILE", "ENOENT", "ENOTDIR", "EPERM"];
4506
+ function transcriptScanFailureKind(error, adapterFailureKind) {
4507
+ if (transcriptErrorCode(error) === "ELOOP") return "symlink";
4508
+ const adapter = adapterFailureKind(error);
4509
+ if (adapter !== void 0) return adapter;
4510
+ const code = transcriptErrorCode(error);
4511
+ if (code === "EFBIG") return "size_budget";
4512
+ if (code !== null && TRANSCRIPT_SCAN_READ_ERROR_ERRNOS.includes(code)) return "read_error";
4513
+ return "other";
4514
+ }
4515
+ async function registerHostCurrentPromptDiagnosed(register, diagnostic) {
4516
+ try {
4517
+ await register();
4518
+ diagnostic("current_prompt_registered");
4519
+ return true;
4520
+ } catch (error) {
4521
+ if (!(error instanceof HostRelayCurrentPromptCapacityRefusal)) diagnostic("current_prompt_registration_failed");
4522
+ throw error;
4523
+ }
4524
+ }
4525
+ function transcriptErrorCode(error) {
4526
+ return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : null;
4527
+ }
4528
+ var HOST_TRANSCRIPT_READ_CHUNK_BYTES = 256 * 1024;
4529
+ async function readTranscriptCompleteChunk(handle, offset, size) {
4530
+ const available = Math.max(0, size - offset);
4531
+ if (available === 0) return "empty";
4532
+ const chunks = [];
4533
+ let position = offset;
4534
+ let total = 0;
4535
+ let lastNewline = -1;
4536
+ while (position < size) {
4537
+ const buffer = Buffer.alloc(Math.min(HOST_TRANSCRIPT_READ_CHUNK_BYTES, size - position));
4538
+ const read = await handle.read(buffer, 0, buffer.length, position);
4539
+ if (read.bytesRead === 0) break;
4540
+ const chunk = buffer.subarray(0, read.bytesRead);
4541
+ chunks.push(chunk);
4542
+ const newline = chunk.lastIndexOf(10);
4543
+ if (newline >= 0) lastNewline = total + newline;
4544
+ total += chunk.length;
4545
+ position += chunk.length;
4546
+ if (lastNewline >= 0) break;
4547
+ }
4548
+ if (lastNewline < 0) return "partial";
4549
+ return Buffer.concat(chunks, total).subarray(0, lastNewline + 1);
4550
+ }
4551
+ async function readTranscriptAnchor(handle, offset, anchorBytes) {
4552
+ const start = Math.max(0, offset - anchorBytes);
4553
+ const anchor = Buffer.alloc(offset - start);
4554
+ if (anchor.length > 0) await handle.read(anchor, 0, anchor.length, start);
4555
+ return { start, sha256: transcriptSha256(anchor) };
4556
+ }
4557
+ async function transcriptAnchorMatches(handle, cursor) {
4558
+ const buffer = Buffer.alloc(cursor.offset - cursor.anchor_start);
4559
+ if (buffer.length > 0) await handle.read(buffer, 0, buffer.length, cursor.anchor_start);
4560
+ return transcriptSha256(buffer) === cursor.anchor_sha256;
4561
+ }
4562
+ function transcriptCursorIdentityReason(cursor, transcriptPath, device, inode) {
4563
+ if (cursor.device !== device || cursor.inode !== inode || cursor.transcript_path !== transcriptPath) return "transcript_replaced";
4564
+ return null;
4565
+ }
4566
+ async function transcriptCursorBoundsReason(handle, cursor, size) {
4567
+ if (size < cursor.offset) return "transcript_truncated";
4568
+ if (cursor.offset > 0 && !await transcriptAnchorMatches(handle, cursor)) return "transcript_rewritten";
4569
+ return null;
4570
+ }
4571
+ function transcriptSha256(value) {
4572
+ return createHash3("sha256").update(value).digest("hex");
4573
+ }
4574
+ function transcriptObjectSha256(value) {
4575
+ return createHash3("sha256").update(JSON.stringify(value), "utf8").digest("hex");
4576
+ }
4577
+ function isTranscriptRecord(value) {
4578
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4579
+ }
4580
+ function isMissingTranscriptError(error) {
4581
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
4582
+ }
4583
+ function transcriptTimestamp(now, fail) {
4584
+ const value = now();
4585
+ if (!Number.isFinite(value.getTime())) throw fail();
4586
+ return value.toISOString();
4587
+ }
4588
+ function transcriptExpiration(now, retentionMs, fail) {
4589
+ return new Date(Date.parse(transcriptTimestamp(now, fail)) + retentionMs).toISOString();
4590
+ }
4591
+ function createTranscriptWatcherBase(options, owner) {
4592
+ if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw owner.invalid_outbox();
4593
+ return {
4594
+ outboxRetentionMs: options.retention_ms ?? owner.default_retention_ms,
4595
+ now: options.now ?? (() => /* @__PURE__ */ new Date()),
4596
+ log: options.log ?? ((line) => {
4597
+ process.stderr.write(`${line}
4598
+ `);
4599
+ }),
4600
+ producerInstallationRef: options.producer_installation_ref
4601
+ };
4602
+ }
4603
+ async function scanTranscriptRegistrations(registrations, scanOne) {
4604
+ let records = 0;
4605
+ let enqueued = 0;
4606
+ let quarantined = 0;
4607
+ for (const registration of registrations) {
4608
+ const result = await scanOne(registration);
4609
+ records += result.records;
4610
+ enqueued += result.enqueued;
4611
+ if (result.quarantined) quarantined += 1;
4612
+ }
4613
+ return { registrations: registrations.length, records, enqueued, quarantined };
4614
+ }
4615
+ function formatRetiredTranscriptLog(producerLabel, transcriptPath) {
4616
+ return `${producerLabel} retired a transcript registration: transcript_path=${JSON.stringify(transcriptPath)}, reason=${TRANSCRIPT_MISSING_REASON}.`;
4617
+ }
4618
+ var HostTranscriptWatcher = class {
4619
+ outboxRetentionMs;
4620
+ now;
4621
+ log;
4622
+ producerInstallationRef;
4623
+ clockFailure;
4624
+ constructor(options, owner) {
4625
+ const base = createTranscriptWatcherBase(options, owner);
4626
+ this.outboxRetentionMs = base.outboxRetentionMs;
4627
+ this.now = base.now;
4628
+ this.log = base.log;
4629
+ this.producerInstallationRef = base.producerInstallationRef;
4630
+ this.clockFailure = owner.clock_failure;
4631
+ }
4632
+ async scanOnce() {
4633
+ return scanTranscriptRegistrations(await this.listRegistrations(), (registration) => this.scanRegistration(registration));
4634
+ }
4635
+ async scanRegistration(registration) {
4636
+ try {
4637
+ return await this.openTranscript(registration, (handle) => this.scanOpened(handle, registration), {
4638
+ missing: () => this.retireMissing(registration),
4639
+ failed: (handle, error) => this.scanFailed(handle, registration, error)
4640
+ });
4641
+ } catch (error) {
4642
+ if (error instanceof HostRelayCurrentPromptCapacityRefusal) return { records: 0, enqueued: 0, quarantined: false };
4643
+ throw error;
4644
+ }
4645
+ }
4646
+ async openTranscript(registration, scan, handlers) {
4647
+ let handle;
4648
+ try {
4649
+ handle = await open3(this.transcriptPathOf(registration), O_RDONLY2 | O_NOFOLLOW);
4650
+ return await scan(handle);
4651
+ } catch (error) {
4652
+ if (handle === void 0 && isMissingTranscriptError(error)) return handlers.missing();
4653
+ if (hostRelayExchangeFailure(error) !== void 0 || error instanceof HostRelayCurrentPromptCapacityRefusal) throw error;
4654
+ return handlers.failed(handle, error);
4655
+ } finally {
4656
+ await handle?.close();
4657
+ }
4658
+ }
4659
+ /**
4660
+ * A transcript the Host deleted never comes back, so retrying its
4661
+ * registration once per reconcile interval is a failure with no end.
4662
+ * Retire it at the scan that finds it missing and say so once. Only
4663
+ * ENOENT means gone; a permission or busy failure is about this moment,
4664
+ * not about the file, and keeps the registration for the next scan.
4665
+ */
4666
+ async retireMissingTranscript(transcriptPath, producerLabel, retire) {
4667
+ await retire();
4668
+ this.log(formatRetiredTranscriptLog(producerLabel, transcriptPath));
4669
+ return { records: 0, enqueued: 0, quarantined: false };
4670
+ }
4671
+ stamp() {
4672
+ return transcriptTimestamp(this.now, this.clockFailure);
4673
+ }
4674
+ expire(retentionMs) {
4675
+ return transcriptExpiration(this.now, retentionMs, this.clockFailure);
4676
+ }
4677
+ sha(value) {
4678
+ return transcriptSha256(value);
4679
+ }
4680
+ objectSha(value) {
4681
+ return transcriptObjectSha256(value);
4682
+ }
4683
+ isRecord(value) {
4684
+ return isTranscriptRecord(value);
4685
+ }
4686
+ readChunk(handle, offset, size) {
4687
+ return readTranscriptCompleteChunk(handle, offset, size);
4688
+ }
4689
+ readAnchor(handle, offset, anchorBytes) {
4690
+ return readTranscriptAnchor(handle, offset, anchorBytes);
4691
+ }
4692
+ cursorIdentityReason(cursor, transcriptPath, device, inode) {
4693
+ return transcriptCursorIdentityReason(cursor, transcriptPath, device, inode);
4694
+ }
4695
+ cursorBoundsReason(handle, cursor, size) {
4696
+ return transcriptCursorBoundsReason(handle, cursor, size);
4697
+ }
4698
+ };
4699
+ var HOST_PRODUCER_STATE_IDENTITY = {
4700
+ codex: { file_name: "codex-producer-state.json", schema: "ceal.codex_producer_state.v1" },
4701
+ claude: { file_name: "claude-producer-state.json", schema: "ceal.claude_producer_state.v1" }
4702
+ };
4703
+ var HostProducerDrainCore = class {
4704
+ host;
4705
+ relay;
4706
+ statePath;
4707
+ stateSchema;
4708
+ installationRef;
4709
+ epoch;
4710
+ now;
4711
+ tail = Promise.resolve();
4712
+ constructor(host, runtime) {
4713
+ if (!isHostSafeRef(runtime.producer_installation_ref)) throw host.fail("configuration", `${host.producer_label} producer installation identity is invalid.`);
4714
+ const epoch = runtime.producer_epoch ?? 1;
4715
+ if (!Number.isSafeInteger(epoch) || epoch <= 0) throw host.fail("configuration", `${host.producer_label} producer epoch is invalid.`);
4716
+ this.host = host;
4717
+ this.relay = runtime.relay;
4718
+ this.statePath = join3(host.outbox_directory, HOST_PRODUCER_STATE_IDENTITY[host.producer_id].file_name);
4719
+ this.stateSchema = HOST_PRODUCER_STATE_IDENTITY[host.producer_id].schema;
4720
+ this.installationRef = runtime.producer_installation_ref;
4721
+ this.epoch = epoch;
4722
+ this.now = runtime.now ?? (() => /* @__PURE__ */ new Date());
4723
+ }
4724
+ drainOutbox() {
4725
+ const run = this.tail.then(() => this.drainLocked());
4726
+ this.tail = run.then(() => void 0, () => void 0);
4727
+ return run;
4728
+ }
4729
+ async drainLocked() {
4730
+ const read = await this.host.listEnvelopes();
4731
+ let admitted = 0;
4732
+ let expired = 0;
4733
+ let retained = 0;
4734
+ for (const envelope of read.entries) {
4735
+ const reserved = await this.hasReservation(this.host.submissionRefOf(envelope));
4736
+ if (!reserved && Date.parse(this.host.expiresAtOf(envelope)) <= this.now().getTime()) {
4737
+ await this.host.removeEnvelope(envelope);
4738
+ expired += 1;
4739
+ continue;
4740
+ }
4741
+ const frames = await this.reserve(envelope);
4742
+ let complete = true;
4743
+ for (const frame of frames) {
4744
+ const outcome = await this.relay.admit(frame);
4745
+ if (outcome.code !== "admitted" && outcome.code !== "already_admitted") {
4746
+ complete = false;
4747
+ break;
4748
+ }
4749
+ }
4750
+ if (!complete) {
4751
+ retained += 1;
4752
+ break;
4753
+ }
4754
+ await this.host.removeEnvelope(envelope);
4755
+ await this.release(this.host.submissionRefOf(envelope));
4756
+ admitted += 1;
4757
+ }
4758
+ return { admitted, retained: retained + Math.max(0, read.entries.length - admitted - expired - retained), expired, malformed: read.malformed };
4759
+ }
4760
+ async hasReservation(submissionRef) {
4761
+ return (await this.readState()).pending[submissionRef] !== void 0;
4762
+ }
4763
+ async reserve(envelope) {
4764
+ const state = await this.readState();
4765
+ const submissionRef = this.host.submissionRefOf(envelope);
4766
+ const existing = state.pending[submissionRef];
4767
+ if (existing !== void 0) return existing;
4768
+ const drafts = await this.host.mapEnvelope(envelope);
4769
+ const frames = drafts.map((draft, offset) => ({
4770
+ schema_version: "ceal.host_producer_frame.v1",
4771
+ producer_id: this.host.producer_id,
4772
+ producer_installation_ref: this.installationRef,
4773
+ producer_epoch: this.epoch,
4774
+ sequence: state.next_sequence + offset,
4775
+ frame_kind: draft.frame_kind,
4776
+ occurred_at: this.host.createdAtOf(envelope),
4777
+ payload: draft.payload
4778
+ }));
4779
+ await this.writeState({ ...state, next_sequence: state.next_sequence + frames.length, pending: { ...state.pending, [submissionRef]: frames } });
4780
+ return frames;
4781
+ }
4782
+ async release(submissionRef) {
4783
+ const state = await this.readState();
4784
+ if (state.pending[submissionRef] === void 0) return;
4785
+ const pending = { ...state.pending };
4786
+ delete pending[submissionRef];
4787
+ await this.writeState({ ...state, pending });
4788
+ }
4789
+ async readState() {
4790
+ try {
4791
+ const value = JSON.parse(await readFile2(this.statePath, "utf8"));
4792
+ return this.decodeState(value);
4793
+ } catch (error) {
4794
+ if (errorCode3(error) !== "ENOENT") throw error;
4795
+ return { schema_version: this.stateSchema, producer_installation_ref: this.installationRef, producer_epoch: this.epoch, next_sequence: 1, pending: {} };
4796
+ }
4797
+ }
4798
+ async writeState(state) {
4799
+ await mkdir2(this.host.outbox_directory, { recursive: true, mode: 448 });
4800
+ const temporary = `${this.statePath}.${process.pid}.new`;
4801
+ await writeFile(temporary, JSON.stringify(state), { mode: 384 });
4802
+ await rename2(temporary, this.statePath);
4803
+ }
4804
+ decodeState(value) {
4805
+ const label = this.host.producer_label;
4806
+ const fail = (code, message) => this.host.fail(code, message);
4807
+ if (!isDrainStateHeader(value, this.stateSchema, this.installationRef)) {
4808
+ throw fail("storage", `${label} producer state header is malformed or belongs to another installation (${refusalFacts([
4809
+ { name: "schema_version", value: isTranscriptRecord(value) ? value.schema_version : void 0, expected: this.stateSchema },
4810
+ { name: "producer_installation_ref", value: isTranscriptRecord(value) ? value.producer_installation_ref : void 0, expected: this.installationRef }
4811
+ ])}).`);
4812
+ }
4813
+ if (Number(value.producer_epoch) > this.epoch) throw fail("storage", `${label} producer state epoch is ahead of this installation (${refusalFact("producer_epoch", value.producer_epoch, `at most ${this.epoch}`)}).`);
4814
+ const pending = {};
4815
+ const storedEpoch = Number(value.producer_epoch);
4816
+ for (const [submissionRef, frames] of Object.entries(value.pending)) {
4817
+ if (!isHostSafeRef(submissionRef) || !Array.isArray(frames) || frames.length === 0) throw fail("storage", `${label} producer pending reservation is malformed.`);
4818
+ pending[submissionRef] = frames.map((frame) => this.decodeStoredFrame(frame, storedEpoch));
4819
+ }
4820
+ return { schema_version: this.stateSchema, producer_installation_ref: this.installationRef, producer_epoch: this.epoch, next_sequence: Number(value.next_sequence), pending };
4821
+ }
4822
+ decodeStoredFrame(value, storedEpoch) {
4823
+ const label = this.host.producer_label;
4824
+ const json = Buffer.from(JSON.stringify(value), "utf8");
4825
+ const encoded = Buffer.allocUnsafe(json.length + 4);
4826
+ encoded.writeUInt32BE(json.length, 0);
4827
+ json.copy(encoded, 4);
4828
+ const frame = decodeHostProducerFrame(encoded);
4829
+ if (frame.producer_id !== this.host.producer_id || frame.producer_installation_ref !== this.installationRef || frame.producer_epoch > storedEpoch) throw this.host.fail("storage", `${label} producer pending frame identity is malformed (${refusalFacts([
4830
+ { name: "producer_id", value: frame.producer_id, expected: this.host.producer_id },
4831
+ { name: "producer_installation_ref", value: frame.producer_installation_ref, expected: this.installationRef },
4832
+ { name: "producer_epoch", value: frame.producer_epoch, expected: `at most ${storedEpoch}` }
4833
+ ])}).`);
4834
+ return frame;
4835
+ }
4836
+ };
4837
+ function isDrainStateHeader(value, schema, installationRef) {
4838
+ return isTranscriptRecord(value) && value.schema_version === schema && value.producer_installation_ref === installationRef && Number.isSafeInteger(value.producer_epoch) && Number(value.producer_epoch) > 0 && Number.isSafeInteger(value.next_sequence) && Number(value.next_sequence) > 0 && isTranscriptRecord(value.pending);
4839
+ }
4840
+ function errorCode3(error) {
4841
+ return typeof error === "object" && error !== null && "code" in error ? String(error.code) : null;
4842
+ }
4843
+
4844
+ // host/relay/src/relay-quarantine-store.ts
4845
+ var RELAY_QUARANTINE_MAX_BYTES = 16 * 1024 * 1024;
4846
+ var RELAY_QUARANTINE_FRAME_REASONS = ["frame_identity_conflict", "sequence_gap", "gateway_refused"];
4847
+ var RELAY_QUARANTINE_REASONS = [...RELAY_QUARANTINE_FRAME_REASONS, ...HOST_PRODUCER_FRAME_ERROR_CODES];
4848
+
4849
+ // host/relay/src/relay-admission-store.ts
4850
+ var DEFAULT_LIMITS = { global_count: 8192, global_bytes: 64 * 1024 * 1024, producer_count: 4096, producer_bytes: 32 * 1024 * 1024 };
4851
+ var RETRY_SECONDS = [1, 2, 4, 8, 16, 32, 60];
4852
+ var MAX_RETRYABLE_ATTEMPTS = RETRY_SECONDS.length + 10;
4853
+
2241
4854
  // host/invocation-authentication-command.ts
2242
4855
  var HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX = ["authenticate", "--client-nonce"];
2243
- var REFUSAL_REASON_PATTERN = /^[a-z][a-z0-9_ ]{0,63}$/u;
2244
- function installedHostInvocationAuthenticationCommandOptions(config) {
4856
+ var HOST_AUTHENTICATION_BUDGET_ENVIRONMENT = "CEAL_HOST_AUTHENTICATION_BUDGET_MS";
4857
+ var HOST_CONTEXT_ACTIVATION_WAIT_MAX_MS = 2e4;
4858
+ var CODEX_CONTEXT_ACTIVATION_WAIT_MAX_MS = HOST_CONTEXT_ACTIVATION_WAIT_MAX_MS;
4859
+ var HOST_AUTHENTICATION_COMPLETION_RESERVE_MS = 5e3;
4860
+ var INVOCATION_CONTEXT_POLL_INTERVAL_MS = 250;
4861
+ var REFUSAL_REASON_PATTERN = /^[a-z][a-z0-9_]{0,63}$/u;
4862
+ function installedHostInvocationAuthenticationCommandOptions(config, contextBudgetMs, maxContextWaitMs) {
2245
4863
  const port = new HostRelayInvocationContextPort(config.relay_endpoint);
2246
4864
  return {
2247
4865
  host_source_ref: config.host_source_ref,
2248
4866
  outbox_dir: config.outbox_dir,
2249
4867
  producer_installation_ref: config.producer_installation_ref,
4868
+ context_activation_wait_ms: boundedContextActivationWait(contextBudgetMs, config.ipc_timeout_ms, maxContextWaitMs),
2250
4869
  mint_invocation_context: (input) => port.mintInvocationContext({ ...input, producer_id: input.producer_id })
2251
4870
  };
2252
4871
  }
2253
- async function runHostInvocationAuthenticationCommand(descriptor, args, options) {
4872
+ async function runHostInvocationAuthenticationCommand(descriptor2, args, options) {
2254
4873
  let sink = options?.output_sink;
2255
4874
  try {
2256
- const resolved = await resolveOptions(descriptor, args, options);
4875
+ const resolved = await resolveOptions(descriptor2, args, options);
2257
4876
  sink = resolved.options.output_sink;
2258
- writeResult(await authenticateHostInvocation(descriptor, resolved.input, resolved.options), sink);
4877
+ writeResult(await authenticateHostInvocation(descriptor2, resolved.input, resolved.options), sink);
2259
4878
  return 0;
2260
4879
  } catch (error) {
2261
4880
  writeResult({ ok: false, code: "invocation_authentication_unavailable", reason: authenticationRefusalReason(error) }, sink);
@@ -2264,65 +4883,150 @@ async function runHostInvocationAuthenticationCommand(descriptor, args, options)
2264
4883
  }
2265
4884
  function authenticationRefusalReason(error) {
2266
4885
  const message = error instanceof Error ? error.message : "";
2267
- return REFUSAL_REASON_PATTERN.test(message) ? message : "unclassified";
4886
+ if (!REFUSAL_REASON_PATTERN.test(message)) return "host_refusal_invalid";
4887
+ return isCealHostAuthenticationCause(message) ? message : "host_refusal_invalid";
2268
4888
  }
2269
- async function authenticateHostInvocation(descriptor, input, options) {
2270
- if (input.length !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX.length + 1 || input[0] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[0] || input[1] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[1]) throw new TypeError("invalid arguments");
4889
+ async function authenticateHostInvocation(descriptor2, input, options) {
4890
+ if (input.length !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX.length + 1 || input[0] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[0] || input[1] !== HOST_INVOCATION_AUTHENTICATION_COMMAND_PREFIX[1]) throw new TypeError("invalid_arguments");
2271
4891
  const request2 = decodeCealHostInvocationAuthenticationRequest({ schema_version: CEAL_HOST_INVOCATION_AUTHENTICATION_REQUEST_SCHEMA, client_nonce: input[2] });
2272
4892
  const config = validateOptions(options);
2273
- const now = (config.now ?? (() => /* @__PURE__ */ new Date()))();
2274
- const { store, current } = await currentInvocation(descriptor, config, now);
2275
- if (config.mint_invocation_context === void 0) throw new TypeError("mint unavailable");
4893
+ const now = config.now ?? (() => /* @__PURE__ */ new Date());
4894
+ const { store, current } = await currentInvocation(descriptor2, config, now);
4895
+ if (config.mint_invocation_context === void 0) throw new TypeError("relay_failed");
2276
4896
  const query = {
2277
- producer_id: descriptor.producer_id,
4897
+ producer_id: descriptor2.producer_id,
2278
4898
  producer_installation_ref: config.producer_installation_ref,
2279
4899
  local_session_ref: current.identity.host_session_ref,
2280
4900
  local_turn_ref: current.identity.host_turn_ref,
2281
- client_nonce: request2.client_nonce
4901
+ client_nonce: request2.client_nonce,
4902
+ ...await visibleOutputBudget(descriptor2)
2282
4903
  };
2283
4904
  const response2 = await mintedResult(config.mint_invocation_context, query);
2284
- const rechecked = await store.readInvocationContext(current.identity.host_source_ref, current.identity.host_session_ref, (config.now ?? (() => /* @__PURE__ */ new Date()))());
2285
- if (rechecked === null || !sameTurn(current, rechecked)) throw new TypeError("context replaced");
2286
- return decodeCealHostInvocationAuthenticationResult(response2.result, now);
4905
+ const completedAt = now();
4906
+ const rechecked = await store.readInvocationContext(current.identity.host_source_ref, current.identity.host_session_ref, completedAt);
4907
+ if (rechecked === null || !sameTurn(current, rechecked)) throw new TypeError("context_replaced");
4908
+ return decodeCealHostInvocationAuthenticationResult(response2.result, completedAt);
4909
+ }
4910
+ async function visibleOutputBudget(descriptor2) {
4911
+ const bytes = await descriptor2.resolve_visible_output_max_bytes?.();
4912
+ return bytes === void 0 ? {} : { visible_output_max_bytes: bytes };
2287
4913
  }
2288
4914
  async function mintedResult(mint, query) {
2289
4915
  let response2;
2290
4916
  try {
2291
4917
  response2 = await mint(query);
2292
4918
  } catch (error) {
2293
- throw new TypeError(`relay ${hostRelayExchangeFailure(error) ?? "unavailable"}`);
4919
+ throw new TypeError(exchangeFailureCause(hostRelayExchangeFailure(error) ?? "unavailable"));
2294
4920
  }
2295
- if (response2.status === "refused") throw new TypeError(`mint ${response2.reason}`);
2296
- if (response2.status !== "ready") throw new TypeError(response2.status);
4921
+ if (response2.status === "refused") throw new TypeError(mintRefusalCause(response2.reason));
4922
+ if (response2.status !== "ready") throw new TypeError("no_binding");
2297
4923
  return response2;
2298
4924
  }
2299
- async function currentInvocation(descriptor, config, now) {
2300
- const store = descriptor.create_store(config.outbox_dir);
2301
- const identity = resolveIdentity(descriptor, config);
4925
+ function mintRefusalCause(reason) {
4926
+ if (isDirectMintRefusalCause(reason)) return reason;
4927
+ if (reason === "deadline" || reason === "cancelled") return "transient_retryable";
4928
+ if (reason === "mint_failed" || reason === "relay_failed") return reason;
4929
+ return isVocabularyWord(CEAL_HOST_MINT_REQUEST_CONTEXT_REFUSAL_REASONS, reason) ? "context_stale" : "host_refusal_invalid";
4930
+ }
4931
+ function isDirectMintRefusalCause(reason) {
4932
+ return isVocabularyWord(HOST_RELAY_DIRECT_WIRE_MINT_REASONS, reason);
4933
+ }
4934
+ function exchangeFailureCause(failure2) {
4935
+ if (failure2 === "permission_denied") return "relay_permission_denied";
4936
+ if (failure2 === "timed_out") return "transient_retryable";
4937
+ return "relay_unavailable";
4938
+ }
4939
+ async function currentInvocation(descriptor2, config, now) {
4940
+ const store = descriptor2.create_store(config.outbox_dir);
4941
+ const identity = resolveIdentity(descriptor2, config);
2302
4942
  if (identity.status !== "ready") throw new TypeError(identity.status);
2303
- const current = await store.readInvocationContext(identity.identity.host_source_ref, identity.identity.host_session_ref, now);
2304
- if (current === null || Date.parse(current.expires_at) <= now.getTime()) throw new TypeError("context unavailable");
2305
- return { store, current };
4943
+ const waitBudgetMs = config.context_activation_wait_ms ?? 0;
4944
+ const monotonicNow = config.monotonic_now ?? (() => performance.now());
4945
+ const deadline = monotonicNow() + waitBudgetMs;
4946
+ let firstCheck = true;
4947
+ let waitEngaged = false;
4948
+ while (true) {
4949
+ if (!firstCheck && monotonicNow() >= deadline) {
4950
+ recordActivationWaitExhaustion(descriptor2.producer_id, waitEngaged, waitBudgetMs, config.diagnostic_sink);
4951
+ throw new TypeError("context_unavailable");
4952
+ }
4953
+ firstCheck = false;
4954
+ const observedAt = now();
4955
+ const current = await readLiveSessionContext(store, identity.identity.host_source_ref, identity.identity.host_session_ref, observedAt);
4956
+ if (current !== null) {
4957
+ recordActivationWaitCompletion(descriptor2.producer_id, waitEngaged, config.diagnostic_sink);
4958
+ return { store, current };
4959
+ }
4960
+ const remainingMs = deadline - monotonicNow();
4961
+ if (remainingMs <= 0) {
4962
+ recordActivationWaitExhaustion(descriptor2.producer_id, waitEngaged, waitBudgetMs, config.diagnostic_sink);
4963
+ throw new TypeError("context_unavailable");
4964
+ }
4965
+ recordActivationWaitEngagement(descriptor2.producer_id, waitEngaged, config.diagnostic_sink);
4966
+ waitEngaged = true;
4967
+ const intervalMs = Math.min(INVOCATION_CONTEXT_POLL_INTERVAL_MS, remainingMs);
4968
+ await (config.wait ?? waitForContextActivation)(intervalMs);
4969
+ }
4970
+ }
4971
+ function recordActivationWaitExhaustion(producer, engaged, budgetMs, sink) {
4972
+ if (engaged || budgetMs > 0) writeHostServiceDiagnostic(producer, "activation_wait_exhausted", void 0, void 0, sink);
4973
+ else writeHostServiceDiagnostic(producer, "activation_wait_skipped", void 0, void 0, sink);
4974
+ }
4975
+ function recordActivationWaitCompletion(producer, engaged, sink) {
4976
+ if (engaged) writeHostServiceDiagnostic(producer, "activation_wait_completed", void 0, void 0, sink);
4977
+ }
4978
+ function recordActivationWaitEngagement(producer, engaged, sink) {
4979
+ if (!engaged) writeHostServiceDiagnostic(producer, "activation_wait_engaged", void 0, void 0, sink);
4980
+ }
4981
+ async function readLiveSessionContext(store, hostSourceRef, hostSessionRef, now) {
4982
+ const current = await store.readInvocationContext(hostSourceRef, hostSessionRef, now);
4983
+ if (current !== null) {
4984
+ if (Date.parse(current.expires_at) <= now.getTime()) throw new TypeError("context_expired");
4985
+ return current;
4986
+ }
4987
+ const raw = await store.readRawInvocationContext?.(hostSourceRef, hostSessionRef);
4988
+ if (raw !== null && raw !== void 0 && Date.parse(raw.expires_at) <= now.getTime()) throw new TypeError("context_expired");
4989
+ return null;
2306
4990
  }
2307
- function resolveIdentity(descriptor, options) {
2308
- const sessionId = options.session_id === null ? void 0 : options.session_id ?? process.env[descriptor.session_id_env];
2309
- if (isHostSessionId(sessionId)) return { status: "ready", identity: { host_source_ref: options.host_source_ref, host_session_ref: descriptor.session_ref(options.host_source_ref, sessionId) } };
2310
- return { status: "unavailable" };
4991
+ function resolveIdentity(descriptor2, options) {
4992
+ const sessionId = options.session_id === null ? void 0 : options.session_id ?? process.env[descriptor2.session_id_env];
4993
+ if (isHostSessionId(sessionId)) return { status: "ready", identity: { host_source_ref: options.host_source_ref, host_session_ref: descriptor2.session_ref(options.host_source_ref, sessionId) } };
4994
+ return { status: "session_unavailable" };
2311
4995
  }
2312
- async function resolveOptions(descriptor, args, options) {
4996
+ async function resolveOptions(descriptor2, args, options) {
2313
4997
  if (options !== void 0) return { input: [...args], options };
2314
- const configPath = descriptor.parse_config_flag(args);
4998
+ const configPath = descriptor2.parse_config_flag(args);
4999
+ const config = await descriptor2.read_producer_config(configPath);
2315
5000
  return {
2316
- input: args.filter((argument) => !argument.startsWith(`${descriptor.config_flag}=`)),
2317
- options: installedHostInvocationAuthenticationCommandOptions(await descriptor.read_producer_config(configPath))
5001
+ input: args.filter((argument) => !argument.startsWith(`${descriptor2.config_flag}=`)),
5002
+ options: installedHostInvocationAuthenticationCommandOptions(config, authenticationBudgetMsFromEnvironment(), descriptor2.context_activation_wait_max_ms)
2318
5003
  };
2319
5004
  }
5005
+ function authenticationBudgetMsFromEnvironment() {
5006
+ const value = process.env[HOST_AUTHENTICATION_BUDGET_ENVIRONMENT];
5007
+ if (value === void 0) return 0;
5008
+ if (!/^(?:0|[1-9][0-9]{0,8})$/u.test(value)) throw new TypeError("invalid_arguments");
5009
+ return Number(value);
5010
+ }
5011
+ function boundedContextActivationWait(contextBudgetMs, relayTimeoutMs, maxContextWaitMs) {
5012
+ if (maxContextWaitMs === void 0 || contextBudgetMs <= 0) return 0;
5013
+ const availableWaitMs = contextBudgetMs - relayTimeoutMs - HOST_AUTHENTICATION_COMPLETION_RESERVE_MS;
5014
+ return Math.max(0, Math.min(maxContextWaitMs, availableWaitMs));
5015
+ }
5016
+ function waitForContextActivation(milliseconds) {
5017
+ return new Promise((resolve) => {
5018
+ setTimeout(resolve, milliseconds);
5019
+ });
5020
+ }
2320
5021
  function validateOptions(options) {
2321
- if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0 || typeof options.host_source_ref !== "string" || !SAFE_REF.test(options.host_source_ref) || typeof options.producer_installation_ref !== "string" || !SAFE_REF.test(options.producer_installation_ref) || !validOptionalSession(options.session_id)) {
2322
- throw new TypeError("options invalid");
5022
+ if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0 || typeof options.host_source_ref !== "string" || !SAFE_REF.test(options.host_source_ref) || typeof options.producer_installation_ref !== "string" || !SAFE_REF.test(options.producer_installation_ref) || !validContextActivationWait(options.context_activation_wait_ms) || !validOptionalSession(options.session_id)) {
5023
+ throw new TypeError("options_invalid");
2323
5024
  }
2324
5025
  return options;
2325
5026
  }
5027
+ function validContextActivationWait(value) {
5028
+ return value === void 0 || Number.isSafeInteger(value) && value >= 0 && value <= HOST_CONTEXT_ACTIVATION_WAIT_MAX_MS;
5029
+ }
2326
5030
  function isHostSessionId(value) {
2327
5031
  return typeof value === "string" && value.length > 0 && value.length <= 256 && !value.includes("\0");
2328
5032
  }
@@ -2341,7 +5045,7 @@ function writeResult(value, sink) {
2341
5045
  import { posix as posix3, win32 as win323 } from "node:path";
2342
5046
 
2343
5047
  // host/runtime-source-paths.ts
2344
- import { createHash as createHash3 } from "node:crypto";
5048
+ import { createHash as createHash4 } from "node:crypto";
2345
5049
  import { posix as posix2, win32 as win322 } from "node:path";
2346
5050
 
2347
5051
  // host/absolute-path.ts
@@ -2363,7 +5067,7 @@ function hostRuntimeSourcePaths(stateRoot, sourceRef, platform = process.platfor
2363
5067
  const sourcesRoot = path.join(stateRoot, "sources");
2364
5068
  const sourceRoot = path.join(sourcesRoot, sourceId);
2365
5069
  const runtimeRoot = path.join(stateRoot, "run");
2366
- const endpoint = platform === "win32" ? `\\\\.\\pipe\\ceal-host-${createHash3("sha256").update(`${stateRoot}\0${sourceRef}`).digest("hex").slice(0, 24)}` : path.join(runtimeRoot, `${sourceId}.sock`);
5070
+ const endpoint = platform === "win32" ? `\\\\.\\pipe\\ceal-host-${createHash4("sha256").update(`${stateRoot}\0${sourceRef}`).digest("hex").slice(0, 24)}` : path.join(runtimeRoot, `${sourceId}.sock`);
2367
5071
  assertHostRuntimeIpcLength(endpoint, platform);
2368
5072
  return { sourceId, sourcesRoot, sourceRoot, relayRoot: path.join(sourceRoot, "relay"), codexOutbox: path.join(sourceRoot, "producers", "codex", "outbox"), claudeOutbox: path.join(sourceRoot, "producers", "claude", "outbox"), endpoint, runtimeRoot };
2369
5073
  }
@@ -2379,7 +5083,7 @@ function assertHostProducerSourcePaths(stateRoot, config, producer, platform = p
2379
5083
 
2380
5084
  // host/producer-service.ts
2381
5085
  import { constants } from "node:fs";
2382
- import { lstat as lstat2, open as open3 } from "node:fs/promises";
5086
+ import { lstat as lstat2, open as open4 } from "node:fs/promises";
2383
5087
  var SAFE_REF4 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
2384
5088
  var HOST_PRODUCER_CONFIG_FLAG = "--ceal-host-config";
2385
5089
  var HostProducerServiceError = class extends Error {
@@ -2400,22 +5104,22 @@ function hostProducerExtraPath(extras, key) {
2400
5104
  function parseHostProducerConfigFlag(args, platform = process.platform) {
2401
5105
  return parseProducerHostConfigFlag(args, HOST_PRODUCER_CONFIG_FLAG, platform, hostProducerError);
2402
5106
  }
2403
- async function readHostProducerConfig(descriptor, configPath, platform = process.platform) {
2404
- const config = decodeHostProducerConfigText(descriptor, await readProducerConfigText(configPath, platform, hostProducerError), platform);
5107
+ async function readHostProducerConfig(descriptor2, configPath, platform = process.platform) {
5108
+ const config = decodeHostProducerConfigText(descriptor2, await readProducerConfigText(configPath, platform, hostProducerError), platform);
2405
5109
  const path = platform === "win32" ? win323 : posix3;
2406
5110
  const root = path.resolve(config.outbox_dir, "../../../../..");
2407
5111
  try {
2408
- assertHostProducerSourcePaths(root, config, descriptor.producer_id, platform);
5112
+ assertHostProducerSourcePaths(root, config, descriptor2.producer_id, platform);
2409
5113
  } catch (error) {
2410
5114
  throw hostProducerError("invalid_config", error instanceof Error ? error.message : "Host producer source tuple is invalid.");
2411
5115
  }
2412
5116
  return config;
2413
5117
  }
2414
- function decodeHostProducerConfigText(descriptor, text, platform = process.platform) {
2415
- const extraPaths = descriptor.extra_paths ?? [];
2416
- const decoded = decodeProducerConfigCore(text, { schema: descriptor.schema, keys: [...HOST_PRODUCER_CONFIG_KEYS, ...extraPaths], platform, extraPaths, error: hostProducerError });
5118
+ function decodeHostProducerConfigText(descriptor2, text, platform = process.platform) {
5119
+ const extraPaths = descriptor2.extra_paths ?? [];
5120
+ const decoded = decodeProducerConfigCore(text, { schema: descriptor2.schema, keys: [...HOST_PRODUCER_CONFIG_KEYS, ...extraPaths], platform, extraPaths, error: hostProducerError });
2417
5121
  const { extra_paths: extras, ...core } = decoded;
2418
- return Object.freeze(descriptor.config({ schema_version: descriptor.schema, ...core }, extras));
5122
+ return Object.freeze(descriptor2.config({ schema_version: descriptor2.schema, ...core }, extras));
2419
5123
  }
2420
5124
  function hostProducerError(code, message = code) {
2421
5125
  return new HostProducerServiceError(code, message);
@@ -2490,7 +5194,7 @@ function validateConfigFile(value, platform, error) {
2490
5194
  }
2491
5195
  async function openConfigFile(configPath, flags, error) {
2492
5196
  try {
2493
- return await open3(configPath, flags);
5197
+ return await open4(configPath, flags);
2494
5198
  } catch {
2495
5199
  throw error("config_unavailable");
2496
5200
  }
@@ -2551,7 +5255,7 @@ function boundedMilliseconds(value) {
2551
5255
  }
2552
5256
 
2553
5257
  // host/codex/src/codex-decoder.ts
2554
- import { createHash as createHash4 } from "node:crypto";
5258
+ import { createHash as createHash5 } from "node:crypto";
2555
5259
 
2556
5260
  // host/codex/src/codex-types.ts
2557
5261
  var CODEX_THREAD_ID_ENVIRONMENT = "CODEX_THREAD_ID";
@@ -2562,10 +5266,6 @@ var CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION = "ceal.codex_invocation_context.v1"
2562
5266
  var CODEX_TRANSCRIPT_REGISTRATION_SCHEMA_VERSION = "ceal.codex_transcript_registration.v1";
2563
5267
  var CODEX_TRANSCRIPT_CURSOR_SCHEMA_VERSION = "ceal.codex_transcript_cursor.v1";
2564
5268
  var CODEX_DEFAULT_RETENTION_MS = 24 * 60 * 60 * 1e3;
2565
- var CODEX_TRANSCRIPT_CURSOR_REASONS = ["transcript_replaced", "transcript_truncated", "transcript_rewritten", "transcript_malformed"];
2566
- function isCodexTranscriptCursorReason(value) {
2567
- return typeof value === "string" && CODEX_TRANSCRIPT_CURSOR_REASONS.some((reason) => reason === value);
2568
- }
2569
5269
  var CodexHostAdapterError = class extends Error {
2570
5270
  name = "CodexHostAdapterError";
2571
5271
  code;
@@ -2577,7 +5277,7 @@ var CodexHostAdapterError = class extends Error {
2577
5277
 
2578
5278
  // host/codex/src/codex-decoder.ts
2579
5279
  var SAFE_REF5 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
2580
- var MAX_PAYLOAD_BYTES = 64 * 1024;
5280
+ var MAX_PAYLOAD_BYTES = 512 * 1024;
2581
5281
  function observationRef(event, identity, value) {
2582
5282
  return cealHostObservationRef("codex", shortDigest({ event, identity, value }));
2583
5283
  }
@@ -2601,16 +5301,16 @@ function turnObservationValue(sessionId, turnRef, status) {
2601
5301
  return { status, host_session_id_sha256: sha256(sessionId), host_turn_ref: turnRef };
2602
5302
  }
2603
5303
  function sha256(value) {
2604
- return createHash4("sha256").update(value, "utf8").digest("hex");
5304
+ return createHash5("sha256").update(value, "utf8").digest("hex");
2605
5305
  }
2606
5306
  function shortDigest(value) {
2607
5307
  return cealRequestSha256(value);
2608
5308
  }
2609
5309
 
2610
5310
  // host/codex/src/codex-outbox.ts
2611
- import { O_NOFOLLOW, O_RDONLY as O_RDONLY2 } from "node:constants";
2612
- import { lstat as lstat3, mkdir as mkdir2, open as open4, readdir, rename as rename2, unlink as unlink2 } from "node:fs/promises";
2613
- import { dirname, isAbsolute as isAbsolute2, join as join3 } from "node:path";
5311
+ import { O_NOFOLLOW as O_NOFOLLOW2, O_RDONLY as O_RDONLY3 } from "node:constants";
5312
+ import { lstat as lstat3, mkdir as mkdir3, open as open5, readdir, rename as rename3, unlink as unlink2 } from "node:fs/promises";
5313
+ import { dirname, isAbsolute as isAbsolute2, join as join4 } from "node:path";
2614
5314
 
2615
5315
  // host/invocation-context.ts
2616
5316
  var HOST_INVOCATION_IDENTITY_KEYS = ["host_session_ref", "host_turn_ref", "host_source_ref"];
@@ -2624,17 +5324,32 @@ function hasHostInvocationIdentityKeys(value) {
2624
5324
  function hasHostInvocationContextKeys(value, optional = []) {
2625
5325
  return requiredKeys(value, HOST_INVOCATION_CONTEXT_REQUIRED_KEYS, optional);
2626
5326
  }
2627
- function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor) {
5327
+ async function readLatestSessionProjection(file, hostSourceRef, hostSessionRef, readProjection) {
5328
+ const context = await readProjection(file);
5329
+ if (context === null || context.identity.host_source_ref !== hostSourceRef || context.identity.host_session_ref !== hostSessionRef) return null;
5330
+ return context;
5331
+ }
5332
+ function isLiveSessionProjection(context, now) {
5333
+ return context !== null && Date.parse(context.expires_at) > now.getTime();
5334
+ }
5335
+ function invocationContextFromTurn(identity, promptRef, expiresAt, descriptor2) {
2628
5336
  const context = {
2629
- schema_version: descriptor.schema_version,
5337
+ schema_version: descriptor2.schema_version,
2630
5338
  identity,
2631
5339
  prompt_ref: promptRef,
2632
5340
  expires_at: expiresAt,
2633
- ...descriptor.working_directory === void 0 ? {} : { working_directory: descriptor.working_directory }
5341
+ ...descriptor2.turn_generation_ref === void 0 ? {} : { turn_generation_ref: descriptor2.turn_generation_ref },
5342
+ ...descriptor2.working_directory === void 0 ? {} : { working_directory: descriptor2.working_directory }
2634
5343
  };
2635
- descriptor.validate(context);
5344
+ descriptor2.validate(context);
2636
5345
  return Object.freeze(context);
2637
5346
  }
5347
+ function isHostInvocationTurnSelection(value) {
5348
+ return isRecord3(value) && Object.keys(value).length === 5 && value.schema_version === "ceal.host_invocation_turn_selection.v1" && ["host_source_ref", "host_session_ref", "prompt_ref", "turn_generation_ref"].every((key) => safeRef3(value[key]));
5349
+ }
5350
+ function invocationTurnSelectionMatches(context, selection) {
5351
+ return selection === null || context !== null && selection.host_source_ref === context.identity.host_source_ref && selection.host_session_ref === context.identity.host_session_ref && selection.prompt_ref === context.prompt_ref && selection.turn_generation_ref === context.turn_generation_ref;
5352
+ }
2638
5353
  function exactKeys4(value, keys) {
2639
5354
  const actual = Object.keys(value);
2640
5355
  return actual.length === keys.length && keys.every((key) => Object.hasOwn(value, key)) && actual.every((key) => keys.includes(key));
@@ -2644,10 +5359,16 @@ function requiredKeys(value, required, optional) {
2644
5359
  const allowed = /* @__PURE__ */ new Set([...required, ...optional]);
2645
5360
  return actual.length >= required.length && actual.length <= allowed.size && required.every((key) => Object.hasOwn(value, key)) && actual.every((key) => allowed.has(key));
2646
5361
  }
5362
+ function isRecord3(value) {
5363
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5364
+ }
5365
+ function safeRef3(value) {
5366
+ return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
5367
+ }
2647
5368
 
2648
5369
  // host/codex/src/codex-invocation-context.ts
2649
- function codexInvocationContextFromTurn(identity, promptRef, expiresAt) {
2650
- return invocationContextFromTurn(identity, promptRef, expiresAt, { schema_version: CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION, validate: validateCodexHostInvocationContext });
5370
+ function codexInvocationContextFromTurn(identity, promptRef, expiresAt, turnGenerationRef) {
5371
+ return invocationContextFromTurn(identity, promptRef, expiresAt, { schema_version: CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION, validate: validateCodexHostInvocationContext, turn_generation_ref: turnGenerationRef });
2651
5372
  }
2652
5373
  function validateCodexHostInvocationContext(value) {
2653
5374
  if (!isContextShape(value)) {
@@ -2657,28 +5378,29 @@ function validateCodexHostInvocationContext(value) {
2657
5378
  validateContextReferences(value);
2658
5379
  validateContextTimes(value);
2659
5380
  }
2660
- function invocationContextFromBinding(binding) {
5381
+ function invocationContextFromBinding(binding, turnGenerationRef) {
2661
5382
  const context = {
2662
5383
  schema_version: CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION,
2663
5384
  identity: binding.identity,
2664
5385
  prompt_ref: binding.prompt_ref,
2665
5386
  request_ref: binding.request_ref,
2666
5387
  bound_at: binding.bound_at,
2667
- expires_at: binding.expires_at
5388
+ expires_at: binding.expires_at,
5389
+ ...turnGenerationRef === void 0 ? {} : { turn_generation_ref: turnGenerationRef }
2668
5390
  };
2669
5391
  validateCodexHostInvocationContext(context);
2670
5392
  return Object.freeze(context);
2671
5393
  }
2672
5394
  function validateIdentity2(value) {
2673
- if (!isRecord3(value) || !hasHostInvocationIdentityKeys(value) || ![value.host_session_ref, value.host_turn_ref, value.host_source_ref].every(safeRef3)) {
5395
+ if (!isRecord4(value) || !hasHostInvocationIdentityKeys(value) || ![value.host_session_ref, value.host_turn_ref, value.host_source_ref].every(safeRef4)) {
2674
5396
  throw new CodexHostAdapterError("storage", "Codex Host invocation identity is malformed.");
2675
5397
  }
2676
5398
  }
2677
5399
  function isContextShape(value) {
2678
- return isRecord3(value) && hasHostInvocationContextKeys(value, ["request_ref", "bound_at"]) && value.schema_version === CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION;
5400
+ return isRecord4(value) && hasHostInvocationContextKeys(value, ["request_ref", "bound_at", "turn_generation_ref"]) && value.schema_version === CODEX_INVOCATION_CONTEXT_SCHEMA_VERSION;
2679
5401
  }
2680
5402
  function validateContextReferences(value) {
2681
- if (!safeRef3(value.prompt_ref) || !optionalSafeRef(value.request_ref)) throw new CodexHostAdapterError("storage", "Codex Host invocation context is malformed.");
5403
+ if (!safeRef4(value.prompt_ref) || !optionalSafeRef(value.request_ref) || !optionalSafeRef(value.turn_generation_ref)) throw new CodexHostAdapterError("storage", "Codex Host invocation context is malformed.");
2682
5404
  }
2683
5405
  function validateContextTimes(value) {
2684
5406
  const expiresAt = value.expires_at;
@@ -2687,18 +5409,18 @@ function validateContextTimes(value) {
2687
5409
  if (typeof boundAt === "string" && Date.parse(boundAt) > Date.parse(expiresAt)) throw new CodexHostAdapterError("storage", `Codex Host invocation context has invalid binding time (${refusalFact("bound_at", boundAt, `at or before ${expiresAt}`)}).`);
2688
5410
  }
2689
5411
  function optionalSafeRef(value) {
2690
- return value === void 0 || safeRef3(value);
5412
+ return value === void 0 || safeRef4(value);
2691
5413
  }
2692
5414
  function optionalTimestamp(value) {
2693
5415
  return value === void 0 || timestamp2(value);
2694
5416
  }
2695
- function safeRef3(value) {
5417
+ function safeRef4(value) {
2696
5418
  return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u.test(value);
2697
5419
  }
2698
5420
  function timestamp2(value) {
2699
5421
  return typeof value === "string" && value.length <= 64 && Number.isFinite(Date.parse(value));
2700
5422
  }
2701
- function isRecord3(value) {
5423
+ function isRecord4(value) {
2702
5424
  return value !== null && typeof value === "object" && !Array.isArray(value);
2703
5425
  }
2704
5426
 
@@ -2711,20 +5433,22 @@ var CodexOutboxStore = class {
2711
5433
  bindingsDirectory;
2712
5434
  sessionsDirectory;
2713
5435
  activeContextsDirectory;
5436
+ turnSelectionsDirectory;
2714
5437
  registrationsDirectory;
2715
5438
  cursorsDirectory;
2716
5439
  constructor(directory) {
2717
5440
  if (typeof directory !== "string" || directory.length === 0) throw new CodexHostAdapterError("configuration", "Codex outbox directory is required.");
2718
5441
  this.directory = directory;
2719
- this.entriesDirectory = join3(directory, "entries");
2720
- this.bindingsDirectory = join3(directory, "bindings");
2721
- this.sessionsDirectory = join3(directory, "sessions");
2722
- this.activeContextsDirectory = join3(directory, "active-contexts");
2723
- this.registrationsDirectory = join3(directory, "transcript-registrations");
2724
- this.cursorsDirectory = join3(directory, "transcript-cursors");
5442
+ this.entriesDirectory = join4(directory, "entries");
5443
+ this.bindingsDirectory = join4(directory, "bindings");
5444
+ this.sessionsDirectory = join4(directory, "sessions");
5445
+ this.activeContextsDirectory = join4(directory, "active-contexts");
5446
+ this.turnSelectionsDirectory = join4(directory, "turn-selections");
5447
+ this.registrationsDirectory = join4(directory, "transcript-registrations");
5448
+ this.cursorsDirectory = join4(directory, "transcript-cursors");
2725
5449
  }
2726
5450
  async prepare() {
2727
- for (const path of [this.directory, this.entriesDirectory, this.bindingsDirectory, this.sessionsDirectory, this.activeContextsDirectory, this.registrationsDirectory, this.cursorsDirectory]) {
5451
+ for (const path of [this.directory, this.entriesDirectory, this.bindingsDirectory, this.sessionsDirectory, this.activeContextsDirectory, this.turnSelectionsDirectory, this.registrationsDirectory, this.cursorsDirectory]) {
2728
5452
  await ensurePrivateOwnerDirectory(path);
2729
5453
  }
2730
5454
  }
@@ -2740,7 +5464,7 @@ var CodexOutboxStore = class {
2740
5464
  for (const name of await readdir(this.entriesDirectory)) {
2741
5465
  if (!name.endsWith(".json")) continue;
2742
5466
  try {
2743
- const value = JSON.parse(await readPrivateFile(join3(this.entriesDirectory, name)));
5467
+ const value = JSON.parse(await readPrivateFile(join4(this.entriesDirectory, name)));
2744
5468
  validateEnvelope(value);
2745
5469
  entries.push(value);
2746
5470
  } catch {
@@ -2768,8 +5492,8 @@ var CodexOutboxStore = class {
2768
5492
  * prompt replaces this projection, so it cannot inherit the prior turn's
2769
5493
  * Request by session alone.
2770
5494
  */
2771
- async activateInvocationContext(identity, promptRef, expiresAt) {
2772
- const context = codexInvocationContextFromTurn(identity, promptRef, expiresAt);
5495
+ async activateInvocationContext(identity, promptRef, expiresAt, turnGenerationRef) {
5496
+ const context = codexInvocationContextFromTurn(identity, promptRef, expiresAt, turnGenerationRef);
2773
5497
  await this.prepare();
2774
5498
  const path = this.activeContextPath(identity);
2775
5499
  try {
@@ -2783,6 +5507,25 @@ var CodexOutboxStore = class {
2783
5507
  throw error;
2784
5508
  }
2785
5509
  }
5510
+ async writeInvocationTurnSelection(selection) {
5511
+ if (!isHostInvocationTurnSelection(selection)) throw new CodexHostAdapterError("invalid_input", "Codex Host turn selection is invalid.");
5512
+ await this.prepare();
5513
+ await writeAtomicJson(this.turnSelectionPath(selection.host_source_ref, selection.host_session_ref), selection);
5514
+ }
5515
+ async readInvocationTurnSelection(hostSourceRef, hostSessionRef) {
5516
+ if (!SAFE_REF6.test(hostSourceRef) || !SAFE_REF6.test(hostSessionRef)) throw new CodexHostAdapterError("invalid_input", "Codex Host turn selection identity is invalid.");
5517
+ await this.prepare();
5518
+ return readOptionalJson(this.turnSelectionPath(hostSourceRef, hostSessionRef), validateTurnSelection);
5519
+ }
5520
+ async attachInvocationTurnGeneration(identity, promptRef, turnGenerationRef) {
5521
+ const selection = await this.readInvocationTurnSelection(identity.host_source_ref, identity.host_session_ref);
5522
+ if (selection === null || selection.prompt_ref !== promptRef || selection.turn_generation_ref !== turnGenerationRef) return false;
5523
+ const path = this.activeContextPath(identity);
5524
+ const active = await readOptionalJson(path, validateCodexHostInvocationContext);
5525
+ if (active === null || active.prompt_ref !== promptRef || !sameIdentity(active.identity, identity)) return false;
5526
+ await writeAtomicJson(path, { ...active, turn_generation_ref: turnGenerationRef });
5527
+ return true;
5528
+ }
2786
5529
  /**
2787
5530
  * Publish a Request reference only while the acknowledged binding is still
2788
5531
  * the active turn. A delayed relay response therefore cannot overwrite a
@@ -2792,17 +5535,25 @@ var CodexOutboxStore = class {
2792
5535
  validateBinding(binding);
2793
5536
  const active = await this.readInvocationContext(binding.identity.host_source_ref, binding.identity.host_session_ref, now);
2794
5537
  if (active === null || !sameIdentity(active.identity, binding.identity)) return false;
2795
- await writeAtomicJson(this.activeContextPath(binding.identity), invocationContextFromBinding(binding));
5538
+ await writeAtomicJson(this.activeContextPath(binding.identity), invocationContextFromBinding(binding, active.turn_generation_ref));
2796
5539
  return true;
2797
5540
  }
2798
- /** Return only the active session projection; never fall back to another turn. */
5541
+ /** Return only the live session projection; never fall back to another turn. */
2799
5542
  async readInvocationContext(hostSourceRef, hostSessionRef, now = /* @__PURE__ */ new Date()) {
2800
- if (!SAFE_REF6.test(hostSourceRef) || !SAFE_REF6.test(hostSessionRef)) throw new CodexHostAdapterError("invalid_input", "Codex Host session identity is invalid.");
2801
5543
  if (!(now instanceof Date) || !Number.isFinite(now.getTime())) throw new CodexHostAdapterError("invalid_input", "Codex Host context clock is invalid.");
5544
+ const context = await this.readRawInvocationContext(hostSourceRef, hostSessionRef);
5545
+ return isLiveSessionProjection(context, now) && invocationTurnSelectionMatches(context, await this.readInvocationTurnSelection(hostSourceRef, hostSessionRef)) ? context : null;
5546
+ }
5547
+ /**
5548
+ * The latest Codex session projection even when past expiry, so the
5549
+ * invocation authenticator can report an expired context distinctly from
5550
+ * a missing one. Every other caller keeps the fail-closed read above.
5551
+ */
5552
+ async readRawInvocationContext(hostSourceRef, hostSessionRef) {
5553
+ if (!SAFE_REF6.test(hostSourceRef) || !SAFE_REF6.test(hostSessionRef)) throw new CodexHostAdapterError("invalid_input", "Codex Host session identity is invalid.");
2802
5554
  await this.prepare();
2803
- const context = await readOptionalJson(this.activeContextPath({ host_source_ref: hostSourceRef, host_session_ref: hostSessionRef }), validateCodexHostInvocationContext);
2804
- if (context === null || context.identity.host_source_ref !== hostSourceRef || context.identity.host_session_ref !== hostSessionRef) return null;
2805
- return Date.parse(context.expires_at) > now.getTime() ? context : null;
5555
+ const context = await readLatestSessionProjection(this.activeContextPath({ host_source_ref: hostSourceRef, host_session_ref: hostSessionRef }), hostSourceRef, hostSessionRef, (file) => readOptionalJson(file, validateCodexHostInvocationContext));
5556
+ return invocationTurnSelectionMatches(context, await this.readInvocationTurnSelection(hostSourceRef, hostSessionRef)) ? context : null;
2806
5557
  }
2807
5558
  /** Clear the projection only if the caller still owns its exact active turn. */
2808
5559
  async clearInvocationContext(identity, now = /* @__PURE__ */ new Date()) {
@@ -2861,7 +5612,7 @@ var CodexOutboxStore = class {
2861
5612
  for (const name of await readdir(this.registrationsDirectory)) {
2862
5613
  if (!name.endsWith(".json")) continue;
2863
5614
  try {
2864
- const value = JSON.parse(await readPrivateFile(join3(this.registrationsDirectory, name)));
5615
+ const value = JSON.parse(await readPrivateFile(join4(this.registrationsDirectory, name)));
2865
5616
  validateRegistration(value);
2866
5617
  registrations.push(value);
2867
5618
  } catch {
@@ -2903,22 +5654,25 @@ var CodexOutboxStore = class {
2903
5654
  }
2904
5655
  entryPath(submissionRef) {
2905
5656
  if (!SAFE_REF6.test(submissionRef)) throw storageError("Codex submission identity is malformed.");
2906
- return join3(this.entriesDirectory, `${cealRequestSha256(submissionRef)}.json`);
5657
+ return join4(this.entriesDirectory, `${cealRequestSha256(submissionRef)}.json`);
2907
5658
  }
2908
5659
  bindingPath(identity) {
2909
- return join3(this.bindingsDirectory, `${identityKey(identity)}.json`);
5660
+ return join4(this.bindingsDirectory, `${identityKey(identity)}.json`);
2910
5661
  }
2911
5662
  sessionPath(sourceRef, sessionRef) {
2912
- return join3(this.sessionsDirectory, `${identityKey({ host_source_ref: sourceRef, host_session_ref: sessionRef, host_turn_ref: "session" })}.json`);
5663
+ return join4(this.sessionsDirectory, `${identityKey({ host_source_ref: sourceRef, host_session_ref: sessionRef, host_turn_ref: "session" })}.json`);
2913
5664
  }
2914
5665
  activeContextPath(identity) {
2915
- return join3(this.activeContextsDirectory, `${invocationContextKey(identity)}.json`);
5666
+ return join4(this.activeContextsDirectory, `${invocationContextKey(identity)}.json`);
5667
+ }
5668
+ turnSelectionPath(sourceRef, sessionRef) {
5669
+ return join4(this.turnSelectionsDirectory, `${invocationContextKey({ host_source_ref: sourceRef, host_session_ref: sessionRef })}.json`);
2916
5670
  }
2917
5671
  registrationPath(sourceRef, sessionRef) {
2918
- return join3(this.registrationsDirectory, `${sessionStateKey(sourceRef, sessionRef)}.json`);
5672
+ return join4(this.registrationsDirectory, `${sessionStateKey(sourceRef, sessionRef)}.json`);
2919
5673
  }
2920
5674
  cursorPath(sourceRef, sessionRef) {
2921
- return join3(this.cursorsDirectory, `${sessionStateKey(sourceRef, sessionRef)}.json`);
5675
+ return join4(this.cursorsDirectory, `${sessionStateKey(sourceRef, sessionRef)}.json`);
2922
5676
  }
2923
5677
  };
2924
5678
  async function removeOwnerState(path, what) {
@@ -2956,7 +5710,7 @@ async function findBindingByAlias(directory, sourceRef, sessionRef, alias) {
2956
5710
  }
2957
5711
  async function readBindingCandidate(directory, name) {
2958
5712
  try {
2959
- const value = JSON.parse(await readPrivateFile(join3(directory, name)));
5713
+ const value = JSON.parse(await readPrivateFile(join4(directory, name)));
2960
5714
  validateBinding(value);
2961
5715
  return value;
2962
5716
  } catch {
@@ -2975,14 +5729,14 @@ async function writeAtomicJson(path, value) {
2975
5729
  if (text === void 0) throw storageError("Codex owner state cannot be serialized.");
2976
5730
  const temp = `${path}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
2977
5731
  try {
2978
- const handle = await open4(temp, "wx", 384);
5732
+ const handle = await open5(temp, "wx", 384);
2979
5733
  try {
2980
5734
  await handle.writeFile(text, "utf8");
2981
5735
  await handle.sync();
2982
5736
  } finally {
2983
5737
  await handle.close();
2984
5738
  }
2985
- await rename2(temp, path);
5739
+ await rename3(temp, path);
2986
5740
  await syncDirectory(dirname(path));
2987
5741
  } catch (error) {
2988
5742
  try {
@@ -2995,7 +5749,7 @@ async function writeAtomicJson(path, value) {
2995
5749
  }
2996
5750
  async function syncDirectory(path) {
2997
5751
  try {
2998
- const handle = await open4(path, "r");
5752
+ const handle = await open5(path, "r");
2999
5753
  try {
3000
5754
  await handle.sync();
3001
5755
  } finally {
@@ -3020,7 +5774,7 @@ async function ensurePrivateOwnerDirectory(path) {
3020
5774
  await lstat3(path);
3021
5775
  } catch (error) {
3022
5776
  if (!isNotFound(error)) throw storageError("Codex owner state directory is unavailable.");
3023
- await mkdir2(path, { recursive: true, mode: 448 });
5777
+ await mkdir3(path, { recursive: true, mode: 448 });
3024
5778
  }
3025
5779
  const stats = await lstat3(path);
3026
5780
  const uid = typeof process.geteuid === "function" ? process.geteuid() : stats.uid;
@@ -3031,7 +5785,7 @@ async function ensurePrivateOwnerDirectory(path) {
3031
5785
  async function readPrivateFile(path) {
3032
5786
  let handle;
3033
5787
  try {
3034
- handle = await open4(path, O_RDONLY2 | O_NOFOLLOW);
5788
+ handle = await open5(path, O_RDONLY3 | O_NOFOLLOW2);
3035
5789
  const stats = await handle.stat();
3036
5790
  const uid = typeof process.geteuid === "function" ? process.geteuid() : stats.uid;
3037
5791
  if (!stats.isFile()) throw storageError(`Codex owner state path is not a regular file (${refusalFact("mode", `0o${stats.mode.toString(8)}`, "a regular-file mode (0o100xxx)")}).`);
@@ -3043,7 +5797,7 @@ async function readPrivateFile(path) {
3043
5797
  }
3044
5798
  }
3045
5799
  function validateEnvelope(value) {
3046
- if (!isRecord4(value)) throw storageError("Codex outbox entry is malformed.");
5800
+ if (!isRecord5(value)) throw storageError("Codex outbox entry is malformed.");
3047
5801
  if (!sameKeys(value, ["schema_version", "identity", "host_input_ref", "input_kind", "prompt_ref", "observations", "origin_input", "submission_ref", "created_at", "expires_at"], ["request_ref", "codex_turn_id"])) throw storageError(`Codex outbox entry key set is malformed (${refusalFact("keys", Object.keys(value), "exactly the outbox entry key set")}).`);
3048
5802
  if (value.schema_version !== CODEX_OUTBOX_SCHEMA_VERSION) throw storageError(`Codex outbox entry is malformed (${refusalFact("schema_version", value.schema_version, `expected ${CODEX_OUTBOX_SCHEMA_VERSION}`)}).`);
3049
5803
  validateIdentity3(value.identity);
@@ -3061,7 +5815,7 @@ function validateEnvelopeReferences(value) {
3061
5815
  if (typeof value.origin_input !== "boolean") throw storageError("Codex outbox origin disposition is malformed.");
3062
5816
  }
3063
5817
  function validateRegistration(value) {
3064
- if (!isRecord4(value)) throw storageError("Codex transcript registration is malformed.");
5818
+ if (!isRecord5(value)) throw storageError("Codex transcript registration is malformed.");
3065
5819
  if (!sameKeys(value, ["schema_version", "host_source_ref", "host_session_ref", "codex_session_id", "transcript_path", "registered_at", "expires_at"], ["cwd"])) throw storageError(`Codex transcript registration key set is malformed (${refusalFact("keys", Object.keys(value), "exactly the registration key set")}).`);
3066
5820
  if (value.schema_version !== CODEX_TRANSCRIPT_REGISTRATION_SCHEMA_VERSION) throw storageError(`Codex transcript registration is malformed (${refusalFact("schema_version", value.schema_version, `expected ${CODEX_TRANSCRIPT_REGISTRATION_SCHEMA_VERSION}`)}).`);
3067
5821
  validateRegistrationFields(value);
@@ -3077,12 +5831,12 @@ function validRegistrationCwd(value) {
3077
5831
  return value === void 0 || typeof value === "string" && isAbsolute2(value) && value.length <= CODEX_TRANSCRIPT_PATH_MAX_CHARACTERS && !value.includes("\0");
3078
5832
  }
3079
5833
  function validateCursor(value) {
3080
- if (!isRecord4(value)) throw storageError("Codex transcript cursor is malformed.");
5834
+ if (!isRecord5(value)) throw storageError("Codex transcript cursor is malformed.");
3081
5835
  if (!sameKeys(value, ["schema_version", "host_source_ref", "host_session_ref", "transcript_path", "device", "inode", "offset", "last_ordinal", "anchor_start", "anchor_sha256", "header_validated", "status", "updated_at"], ["active_task", "reason"])) throw storageError(`Codex transcript cursor key set is malformed (${refusalFact("keys", Object.keys(value), "exactly the cursor key set")}).`);
3082
5836
  if (value.schema_version !== CODEX_TRANSCRIPT_CURSOR_SCHEMA_VERSION) throw storageError(`Codex transcript cursor is malformed (${refusalFact("schema_version", value.schema_version, `expected ${CODEX_TRANSCRIPT_CURSOR_SCHEMA_VERSION}`)}).`);
3083
5837
  if (!validCursorSource(value) || !validCursorPosition(value) || !validCursorStatus(value)) throw storageError("Codex transcript cursor fields are malformed.");
3084
5838
  if (value.active_task !== void 0 && !validActiveTask(value.active_task)) throw storageError("Codex transcript task cursor is malformed.");
3085
- if (value.reason !== void 0 && !isCodexTranscriptCursorReason(value.reason)) throw storageError("Codex transcript cursor reason is malformed.");
5839
+ if (value.reason !== void 0 && !isHostTranscriptCursorReason(value.reason)) throw storageError("Codex transcript cursor reason is malformed.");
3086
5840
  }
3087
5841
  function validCursorSource(value) {
3088
5842
  return [value.host_source_ref, value.host_session_ref].every((candidate) => typeof candidate === "string" && SAFE_REF6.test(candidate)) && typeof value.transcript_path === "string" && value.transcript_path.length > 0 && typeof value.device === "string" && typeof value.inode === "string";
@@ -3094,7 +5848,7 @@ function validCursorStatus(value) {
3094
5848
  return (value.status === "active" || value.status === "quarantined") && isTimestamp(value.updated_at);
3095
5849
  }
3096
5850
  function validActiveTask(value) {
3097
- if (!isRecord4(value) || !sameKeys(value, ["codex_turn_id", "host_turn_ref", "started_at"], ["origin_host_input_ref", "prompt_ref", "model", "token_usage", "last_total_usage", "token_usage_gap_reason"])) return false;
5851
+ if (!isRecord5(value) || !sameKeys(value, ["codex_turn_id", "host_turn_ref", "started_at"], ["origin_host_input_ref", "prompt_ref", "model", "token_usage", "last_total_usage", "token_usage_gap_reason"])) return false;
3098
5852
  return validActiveTaskIdentity(value) && validActiveTaskReferences(value) && validActiveTaskUsage(value);
3099
5853
  }
3100
5854
  function validActiveTaskIdentity(value) {
@@ -3110,7 +5864,7 @@ function validActiveTaskUsage(value) {
3110
5864
  return (value.token_usage === void 0 || validTokenUsage(value.token_usage)) && (value.last_total_usage === void 0 || validTokenUsage(value.last_total_usage)) && (value.token_usage_gap_reason === void 0 || value.token_usage_gap_reason === "token_count_shape_not_attributable");
3111
5865
  }
3112
5866
  function validTokenUsage(value) {
3113
- if (!isRecord4(value) || !sameKeys(value, ["input_tokens", "cached_input_tokens", "cache_write_input_tokens", "output_tokens", "reasoning_output_tokens", "total_tokens"])) return false;
5867
+ if (!isRecord5(value) || !sameKeys(value, ["input_tokens", "cached_input_tokens", "cache_write_input_tokens", "output_tokens", "reasoning_output_tokens", "total_tokens"])) return false;
3114
5868
  if (![value.input_tokens, value.cached_input_tokens, value.cache_write_input_tokens, value.output_tokens, value.reasoning_output_tokens, value.total_tokens].every(nonNegativeInteger)) return false;
3115
5869
  return value.total_tokens === Number(value.input_tokens) + Number(value.output_tokens) && Number(value.cached_input_tokens) + Number(value.cache_write_input_tokens) <= Number(value.input_tokens) && Number(value.reasoning_output_tokens) <= Number(value.output_tokens);
3116
5870
  }
@@ -3130,7 +5884,7 @@ function validateEnvelopeTimestamps(value) {
3130
5884
  if (!isTimestamp(value.expires_at)) throw storageError("Codex outbox timestamps are malformed.");
3131
5885
  }
3132
5886
  function validateBinding(value) {
3133
- if (!isRecord4(value)) throw storageError("Codex turn binding is malformed.");
5887
+ if (!isRecord5(value)) throw storageError("Codex turn binding is malformed.");
3134
5888
  if (!sameKeys(value, ["schema_version", "identity", "prompt_ref", "request_ref", "codex_turn_ids", "bound_at", "expires_at"])) throw storageError(`Codex turn binding key set is malformed (${refusalFact("keys", Object.keys(value), "exactly the turn binding key set")}).`);
3135
5889
  if (value.schema_version !== CODEX_TURN_BINDING_SCHEMA_VERSION) throw storageError(`Codex turn binding is malformed (${refusalFact("schema_version", value.schema_version, `expected ${CODEX_TURN_BINDING_SCHEMA_VERSION}`)}).`);
3136
5890
  validateIdentity3(value.identity);
@@ -3138,19 +5892,22 @@ function validateBinding(value) {
3138
5892
  if (!isStringList(value.codex_turn_ids) || !isTimestamp(value.bound_at) || !isTimestamp(value.expires_at)) throw storageError("Codex turn binding fields are malformed.");
3139
5893
  }
3140
5894
  function validateSession(value) {
3141
- if (!isRecord4(value)) throw storageError("Codex session snapshot is malformed.");
5895
+ if (!isRecord5(value)) throw storageError("Codex session snapshot is malformed.");
3142
5896
  if (!sameKeys(value, ["schema_version", "host_session_ref", "host_source_ref", "observed_at", "value", "expires_at"])) throw storageError(`Codex session snapshot key set is malformed (${refusalFact("keys", Object.keys(value), "exactly the session snapshot key set")}).`);
3143
5897
  if (value.schema_version !== CODEX_SESSION_SCHEMA_VERSION) throw storageError(`Codex session snapshot is malformed (${refusalFact("schema_version", value.schema_version, `expected ${CODEX_SESSION_SCHEMA_VERSION}`)}).`);
3144
5898
  if (!SAFE_REF6.test(String(value.host_session_ref)) || !SAFE_REF6.test(String(value.host_source_ref)) || !isTimestamp(value.observed_at) || !isTimestamp(value.expires_at) || !isJsonValue(value.value)) throw storageError("Codex session snapshot fields are malformed.");
3145
5899
  }
5900
+ function validateTurnSelection(value) {
5901
+ if (!isHostInvocationTurnSelection(value)) throw storageError("Codex Host turn selection is malformed.");
5902
+ }
3146
5903
  function validateIdentity3(value) {
3147
- if (!isRecord4(value) || !hasHostInvocationIdentityKeys(value) || ![value.host_session_ref, value.host_turn_ref, value.host_source_ref].every((candidate) => typeof candidate === "string" && SAFE_REF6.test(candidate))) throw storageError("Codex Host identity is malformed.");
5904
+ if (!isRecord5(value) || !hasHostInvocationIdentityKeys(value) || ![value.host_session_ref, value.host_turn_ref, value.host_source_ref].every((candidate) => typeof candidate === "string" && SAFE_REF6.test(candidate))) throw storageError("Codex Host identity is malformed.");
3148
5905
  }
3149
5906
  function isJsonValue(value) {
3150
5907
  if (value === null || typeof value === "string" || typeof value === "boolean") return true;
3151
5908
  if (typeof value === "number") return Number.isFinite(value);
3152
5909
  if (Array.isArray(value)) return value.every(isJsonValue);
3153
- return isRecord4(value) && Object.entries(value).every(([key, child]) => key.length > 0 && key.length <= 128 && isJsonValue(child));
5910
+ return isRecord5(value) && Object.entries(value).every(([key, child]) => key.length > 0 && key.length <= 128 && isJsonValue(child));
3154
5911
  }
3155
5912
  function isStringList(value) {
3156
5913
  return Array.isArray(value) && value.every((candidate) => typeof candidate === "string" && SAFE_REF6.test(candidate));
@@ -3163,104 +5920,50 @@ function sameKeys(value, required, optional = []) {
3163
5920
  const keys = Object.keys(value);
3164
5921
  return keys.length >= required.length && keys.length <= allowed.size && required.every((key) => Object.hasOwn(value, key)) && keys.every((key) => allowed.has(key));
3165
5922
  }
3166
- function isRecord4(value) {
5923
+ function isRecord5(value) {
3167
5924
  return value !== null && typeof value === "object" && !Array.isArray(value);
3168
5925
  }
3169
5926
  function isNotFound(error) {
3170
- return isRecord4(error) && error.code === "ENOENT";
5927
+ return isRecord5(error) && error.code === "ENOENT";
3171
5928
  }
3172
5929
  function storageError(message) {
3173
5930
  return new CodexHostAdapterError("storage", message);
3174
5931
  }
3175
5932
 
3176
5933
  // host/codex/src/codex-producer.ts
3177
- import { createHash as createHash5 } from "node:crypto";
3178
- import { mkdir as mkdir3, readFile as readFile2, rename as rename3, writeFile } from "node:fs/promises";
3179
- import { join as join4 } from "node:path";
3180
- var STATE_SCHEMA = "ceal.codex_producer_state.v1";
5934
+ import { createHash as createHash6 } from "node:crypto";
3181
5935
  var SAFE_REF7 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
3182
5936
  var CodexProducer = class {
5937
+ producer_id = "codex";
5938
+ producer_label = "Codex";
5939
+ outbox_directory;
3183
5940
  store;
3184
- statePath;
3185
- installationRef;
3186
- epoch;
3187
- relay;
3188
- now;
3189
- tail = Promise.resolve();
5941
+ core;
3190
5942
  constructor(options) {
3191
- if (!SAFE_REF7.test(options.producer_installation_ref)) throw new CodexHostAdapterError("configuration", "Codex producer installation identity is invalid.");
3192
- const epoch = options.producer_epoch ?? 1;
3193
- if (!Number.isSafeInteger(epoch) || epoch <= 0) throw new CodexHostAdapterError("configuration", "Codex producer epoch is invalid.");
3194
5943
  this.store = new CodexOutboxStore(options.outbox_dir);
3195
- this.statePath = join4(options.outbox_dir, "codex-producer-state.json");
3196
- this.installationRef = options.producer_installation_ref;
3197
- this.epoch = epoch;
3198
- this.relay = options.relay;
3199
- this.now = options.now ?? (() => /* @__PURE__ */ new Date());
5944
+ this.outbox_directory = this.store.directory;
5945
+ this.core = new HostProducerDrainCore(this, options);
3200
5946
  }
3201
5947
  drainOutbox() {
3202
- const run = this.tail.then(() => this.drainLocked());
3203
- this.tail = run.then(() => void 0, () => void 0);
3204
- return run;
5948
+ return this.core.drainOutbox();
3205
5949
  }
3206
- async drainLocked() {
3207
- const read = await this.store.list();
3208
- let admitted = 0;
3209
- let expired = 0;
3210
- let retained = 0;
3211
- for (const envelope of read.entries) {
3212
- const reserved = await this.hasReservation(envelope.submission_ref);
3213
- if (!reserved && Date.parse(envelope.expires_at) <= this.now().getTime()) {
3214
- await this.store.remove(envelope);
3215
- expired += 1;
3216
- continue;
3217
- }
3218
- const frames = await this.reserve(envelope);
3219
- let complete = true;
3220
- for (const frame of frames) {
3221
- const outcome = await this.relay.admit(frame);
3222
- if (outcome.code !== "admitted" && outcome.code !== "already_admitted") {
3223
- complete = false;
3224
- break;
3225
- }
3226
- }
3227
- if (!complete) {
3228
- retained += 1;
3229
- break;
3230
- }
3231
- await this.store.remove(envelope);
3232
- await this.release(envelope.submission_ref);
3233
- admitted += 1;
3234
- }
3235
- return { admitted, retained: retained + Math.max(0, read.entries.length - admitted - expired - retained), expired, malformed: read.malformed };
5950
+ fail(code, message) {
5951
+ return new CodexHostAdapterError(code, message);
3236
5952
  }
3237
- async hasReservation(submissionRef) {
3238
- return (await this.readState()).pending[submissionRef] !== void 0;
5953
+ listEnvelopes() {
5954
+ return this.store.list();
3239
5955
  }
3240
- async reserve(envelope) {
3241
- const state = await this.readState();
3242
- const existing = state.pending[envelope.submission_ref];
3243
- if (existing !== void 0) return existing;
3244
- const drafts = await this.mapEnvelope(envelope);
3245
- const frames = drafts.map((draft, offset) => ({
3246
- schema_version: "ceal.host_producer_frame.v1",
3247
- producer_id: "codex",
3248
- producer_installation_ref: this.installationRef,
3249
- producer_epoch: this.epoch,
3250
- sequence: state.next_sequence + offset,
3251
- frame_kind: draft.frame_kind,
3252
- occurred_at: envelope.created_at,
3253
- payload: draft.payload
3254
- }));
3255
- await this.writeState({ ...state, next_sequence: state.next_sequence + frames.length, pending: { ...state.pending, [envelope.submission_ref]: frames } });
3256
- return frames;
5956
+ removeEnvelope(envelope) {
5957
+ return this.store.remove(envelope);
3257
5958
  }
3258
- async release(submissionRef) {
3259
- const state = await this.readState();
3260
- if (state.pending[submissionRef] === void 0) return;
3261
- const pending = { ...state.pending };
3262
- delete pending[submissionRef];
3263
- await this.writeState({ ...state, pending });
5959
+ submissionRefOf(envelope) {
5960
+ return envelope.submission_ref;
5961
+ }
5962
+ expiresAtOf(envelope) {
5963
+ return envelope.expires_at;
5964
+ }
5965
+ createdAtOf(envelope) {
5966
+ return envelope.created_at;
3264
5967
  }
3265
5968
  async mapEnvelope(envelope) {
3266
5969
  const prompt = observation(envelope, "prompt");
@@ -3276,7 +5979,7 @@ var CodexProducer = class {
3276
5979
  const directoryIdentity = registration?.cwd ?? envelope.identity.host_session_ref;
3277
5980
  drafts.push({ frame_kind: "session_started", payload: compact({
3278
5981
  local_session_ref: envelope.identity.host_session_ref,
3279
- working_directory_ref: `workspace:${createHash5("sha256").update(directoryIdentity, "utf8").digest("hex")}`,
5982
+ working_directory_ref: `workspace:${createHash6("sha256").update(directoryIdentity, "utf8").digest("hex")}`,
3280
5983
  model: recordText(session.value, "model"),
3281
5984
  host_version: nestedText(session.value, "host_version"),
3282
5985
  observations: [session]
@@ -3301,21 +6004,6 @@ var CodexProducer = class {
3301
6004
  }) });
3302
6005
  return drafts;
3303
6006
  }
3304
- async readState() {
3305
- try {
3306
- const value = JSON.parse(await readFile2(this.statePath, "utf8"));
3307
- return decodeState(value, this.installationRef, this.epoch);
3308
- } catch (error) {
3309
- if (errorCode3(error) !== "ENOENT") throw error;
3310
- return { schema_version: STATE_SCHEMA, producer_installation_ref: this.installationRef, producer_epoch: this.epoch, next_sequence: 1, pending: {} };
3311
- }
3312
- }
3313
- async writeState(state) {
3314
- await mkdir3(this.store.directory, { recursive: true, mode: 448 });
3315
- const temporary = `${this.statePath}.${process.pid}.new`;
3316
- await writeFile(temporary, JSON.stringify(state), { mode: 384 });
3317
- await rename3(temporary, this.statePath);
3318
- }
3319
6007
  };
3320
6008
  function mapTerminal(envelope) {
3321
6009
  const timing = observation(envelope, "timing");
@@ -3343,7 +6031,7 @@ function compact(value) {
3343
6031
  return Object.fromEntries(Object.entries(value).filter((entry) => entry[1] !== void 0));
3344
6032
  }
3345
6033
  function asRecord(value) {
3346
- return isRecord5(value) ? value : void 0;
6034
+ return isRecord6(value) ? value : void 0;
3347
6035
  }
3348
6036
  function recordText(value, key) {
3349
6037
  const record3 = asRecord(value);
@@ -3357,53 +6045,14 @@ function nonNegativeNumber(value) {
3357
6045
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
3358
6046
  }
3359
6047
  function safeReasonRef(value) {
3360
- return SAFE_REF7.test(value) ? value : `reason:${createHash5("sha256").update(value, "utf8").digest("hex")}`;
3361
- }
3362
- function errorCode3(error) {
3363
- return typeof error === "object" && error !== null && "code" in error ? String(error.code) : null;
3364
- }
3365
- function decodeState(value, installationRef, epoch) {
3366
- if (!validStateHeader(value, installationRef)) {
3367
- throw new CodexHostAdapterError("storage", `Codex producer state header is malformed or belongs to another installation (${refusalFacts([
3368
- { name: "schema_version", value: isRecord5(value) ? value.schema_version : void 0, expected: STATE_SCHEMA },
3369
- { name: "producer_installation_ref", value: isRecord5(value) ? value.producer_installation_ref : void 0, expected: installationRef }
3370
- ])}).`);
3371
- }
3372
- if (Number(value.producer_epoch) > epoch) throw new CodexHostAdapterError("storage", `Codex producer state epoch is ahead of this installation (${refusalFact("producer_epoch", value.producer_epoch, `at most ${epoch}`)}).`);
3373
- const pending = {};
3374
- for (const [submissionRef, frames] of Object.entries(value.pending)) {
3375
- if (!SAFE_REF7.test(submissionRef) || !Array.isArray(frames) || frames.length === 0) throw new CodexHostAdapterError("storage", "Codex producer pending reservation is malformed.");
3376
- pending[submissionRef] = frames.map((frame) => decodeStoredFrame(frame, installationRef, Number(value.producer_epoch)));
3377
- }
3378
- return { schema_version: STATE_SCHEMA, producer_installation_ref: installationRef, producer_epoch: epoch, next_sequence: Number(value.next_sequence), pending };
3379
- }
3380
- function validStateHeader(value, installationRef) {
3381
- return isRecord5(value) && value.schema_version === STATE_SCHEMA && value.producer_installation_ref === installationRef && Number.isSafeInteger(value.producer_epoch) && Number(value.producer_epoch) > 0 && Number.isSafeInteger(value.next_sequence) && Number(value.next_sequence) > 0 && isRecord5(value.pending);
3382
- }
3383
- function decodeStoredFrame(value, installationRef, epoch) {
3384
- const json = Buffer.from(JSON.stringify(value), "utf8");
3385
- const encoded = Buffer.allocUnsafe(json.length + 4);
3386
- encoded.writeUInt32BE(json.length, 0);
3387
- json.copy(encoded, 4);
3388
- const frame = decodeHostProducerFrame(encoded);
3389
- if (frame.producer_id !== "codex" || frame.producer_installation_ref !== installationRef || frame.producer_epoch > epoch) throw new CodexHostAdapterError("storage", `Codex producer pending frame identity is malformed (${refusalFacts([
3390
- { name: "producer_id", value: frame.producer_id, expected: "codex" },
3391
- { name: "producer_installation_ref", value: frame.producer_installation_ref, expected: installationRef },
3392
- { name: "producer_epoch", value: frame.producer_epoch, expected: `at most ${epoch}` }
3393
- ])}).`);
3394
- return frame;
6048
+ return SAFE_REF7.test(value) ? value : `reason:${createHash6("sha256").update(value, "utf8").digest("hex")}`;
3395
6049
  }
3396
- function isRecord5(value) {
6050
+ function isRecord6(value) {
3397
6051
  return value !== null && typeof value === "object" && !Array.isArray(value);
3398
6052
  }
3399
6053
 
3400
- // host/codex/src/codex-transcript-watcher.ts
3401
- import { createHash as createHash7 } from "node:crypto";
3402
- import { O_NOFOLLOW as O_NOFOLLOW2, O_RDONLY as O_RDONLY3 } from "node:constants";
3403
- import { open as open5 } from "node:fs/promises";
3404
-
3405
6054
  // host/codex/src/codex-transcript-baseline.ts
3406
- import { createHash as createHash6 } from "node:crypto";
6055
+ import { createHash as createHash7 } from "node:crypto";
3407
6056
 
3408
6057
  // host/codex/src/codex-transcript-decoder.ts
3409
6058
  var SAFE_REF8 = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/u;
@@ -3415,40 +6064,40 @@ function decodeCodexTranscriptLine(line) {
3415
6064
  } catch {
3416
6065
  reject("Codex transcript record is not valid JSON.");
3417
6066
  }
3418
- if (!isRecord6(value)) reject("Codex transcript record envelope is malformed.");
6067
+ if (!isRecord7(value)) reject("Codex transcript record envelope is malformed.");
3419
6068
  const ordinal = safeOrdinal(value.ordinal);
3420
- const timestamp5 = safeTimestamp(value.timestamp);
3421
- if (!isRecord6(value.payload) || typeof value.type !== "string") reject("Codex transcript record payload is malformed.");
3422
- if (value.type === "session_meta") return decodeSessionMeta(value.payload, ordinal, timestamp5);
3423
- if (value.type === "turn_context") return decodeTurnContext(value.payload, ordinal, timestamp5);
3424
- if (value.type === "event_msg") return decodeEventMessage(value.payload, ordinal, timestamp5);
3425
- if (value.type === "response_item") return decodeResponseItem(value.payload, ordinal, timestamp5);
3426
- return { kind: "ignored", ordinal, timestamp: timestamp5 };
3427
- }
3428
- function decodeTurnContext(payload, ordinal, timestamp5) {
6069
+ const timestamp4 = safeTimestamp(value.timestamp);
6070
+ if (!isRecord7(value.payload) || typeof value.type !== "string") reject("Codex transcript record payload is malformed.");
6071
+ if (value.type === "session_meta") return decodeSessionMeta(value.payload, ordinal, timestamp4);
6072
+ if (value.type === "turn_context") return decodeTurnContext(value.payload, ordinal, timestamp4);
6073
+ if (value.type === "event_msg") return decodeEventMessage(value.payload, ordinal, timestamp4);
6074
+ if (value.type === "response_item") return decodeResponseItem(value.payload, ordinal, timestamp4);
6075
+ return { kind: "ignored", ordinal, timestamp: timestamp4 };
6076
+ }
6077
+ function decodeTurnContext(payload, ordinal, timestamp4) {
3429
6078
  return {
3430
6079
  kind: "turn_context",
3431
6080
  ordinal,
3432
- timestamp: timestamp5,
3433
- turn_id: safeRef4(payload.turn_id, "Codex turn context identity is invalid."),
6081
+ timestamp: timestamp4,
6082
+ turn_id: safeRef5(payload.turn_id, "Codex turn context identity is invalid."),
3434
6083
  model: boundedNonEmptyText(payload.model, 256, "Codex turn context model is invalid.")
3435
6084
  };
3436
6085
  }
3437
- function decodeSessionMeta(payload, ordinal, timestamp5) {
3438
- const sessionId = safeRef4(payload.id, "Codex transcript session identity is invalid.");
6086
+ function decodeSessionMeta(payload, ordinal, timestamp4) {
6087
+ const sessionId = safeRef5(payload.id, "Codex transcript session identity is invalid.");
3439
6088
  const cliVersion = boundedNonEmptyText(payload.cli_version, 64, "Codex transcript version is invalid.");
3440
- return { kind: "session_meta", ordinal, timestamp: timestamp5, session_id: sessionId, cli_version: cliVersion };
6089
+ return { kind: "session_meta", ordinal, timestamp: timestamp4, session_id: sessionId, cli_version: cliVersion };
3441
6090
  }
3442
- function decodeEventMessage(payload, ordinal, timestamp5) {
6091
+ function decodeEventMessage(payload, ordinal, timestamp4) {
3443
6092
  if (payload.type === "task_started") {
3444
- return { kind: "task_started", ordinal, timestamp: timestamp5, turn_id: safeRef4(payload.turn_id, "Codex task identity is invalid."), started_at: safeNumber(payload.started_at) };
6093
+ return { kind: "task_started", ordinal, timestamp: timestamp4, turn_id: safeRef5(payload.turn_id, "Codex task identity is invalid."), started_at: safeNumber(payload.started_at) };
3445
6094
  }
3446
6095
  if (payload.type === "task_complete") {
3447
6096
  return {
3448
6097
  kind: "task_complete",
3449
6098
  ordinal,
3450
- timestamp: timestamp5,
3451
- turn_id: safeRef4(payload.turn_id, "Codex task identity is invalid."),
6099
+ timestamp: timestamp4,
6100
+ turn_id: safeRef5(payload.turn_id, "Codex task identity is invalid."),
3452
6101
  started_at: safeNumber(payload.started_at),
3453
6102
  completed_at: safeNumber(payload.completed_at),
3454
6103
  duration_ms: safeNumber(payload.duration_ms),
@@ -3459,20 +6108,20 @@ function decodeEventMessage(payload, ordinal, timestamp5) {
3459
6108
  return {
3460
6109
  kind: "turn_aborted",
3461
6110
  ordinal,
3462
- timestamp: timestamp5,
3463
- turn_id: safeRef4(payload.turn_id, "Codex task identity is invalid."),
6111
+ timestamp: timestamp4,
6112
+ turn_id: safeRef5(payload.turn_id, "Codex task identity is invalid."),
3464
6113
  started_at: safeNumber(payload.started_at),
3465
6114
  completed_at: safeNumber(payload.completed_at),
3466
6115
  duration_ms: safeNumber(payload.duration_ms),
3467
6116
  reason: boundedText(payload.reason, 256, "Codex task abort reason is invalid.")
3468
6117
  };
3469
6118
  }
3470
- if (payload.type === "token_count") return decodeTokenCount(payload, ordinal, timestamp5);
3471
- return { kind: "ignored", ordinal, timestamp: timestamp5 };
6119
+ if (payload.type === "token_count") return decodeTokenCount(payload, ordinal, timestamp4);
6120
+ return { kind: "ignored", ordinal, timestamp: timestamp4 };
3472
6121
  }
3473
- function decodeTokenCount(payload, ordinal, timestamp5) {
3474
- if (payload.info === null) return { kind: "token_count", ordinal, timestamp: timestamp5 };
3475
- if (!isRecord6(payload.info)) return { kind: "token_count", ordinal, timestamp: timestamp5, usage_gap_reason: "token_count_shape_not_attributable" };
6122
+ function decodeTokenCount(payload, ordinal, timestamp4) {
6123
+ if (payload.info === null) return { kind: "token_count", ordinal, timestamp: timestamp4 };
6124
+ if (!isRecord7(payload.info)) return { kind: "token_count", ordinal, timestamp: timestamp4, usage_gap_reason: "token_count_shape_not_attributable" };
3476
6125
  const lastUsage = optionalTokenUsage(payload.info.last_token_usage);
3477
6126
  const totalUsage = optionalTokenUsage(payload.info.total_token_usage);
3478
6127
  const gap = lastUsage.status === "invalid" || totalUsage.status === "invalid";
@@ -3480,7 +6129,7 @@ function decodeTokenCount(payload, ordinal, timestamp5) {
3480
6129
  return {
3481
6130
  kind: "token_count",
3482
6131
  ordinal,
3483
- timestamp: timestamp5,
6132
+ timestamp: timestamp4,
3484
6133
  ...lastUsage.status === "valid" ? { last_usage: lastUsage.value } : {},
3485
6134
  ...totalUsage.status === "valid" ? { total_usage: totalUsage.value } : {},
3486
6135
  ...usageGapReason === void 0 ? {} : { usage_gap_reason: usageGapReason }
@@ -3496,7 +6145,7 @@ function optionalTokenUsage(value) {
3496
6145
  }
3497
6146
  }
3498
6147
  function decodeTokenUsage(value) {
3499
- if (!isRecord6(value)) reject("Codex token usage is malformed.");
6148
+ if (!isRecord7(value)) reject("Codex token usage is malformed.");
3500
6149
  const usage = {
3501
6150
  input_tokens: safeTokenCount(value.input_tokens),
3502
6151
  cached_input_tokens: safeTokenCount(value.cached_input_tokens),
@@ -3508,20 +6157,20 @@ function decodeTokenUsage(value) {
3508
6157
  if (usage.total_tokens !== usage.input_tokens + usage.output_tokens || usage.cached_input_tokens + usage.cache_write_input_tokens > usage.input_tokens || usage.reasoning_output_tokens > usage.output_tokens) reject("Codex token usage buckets are inconsistent.");
3509
6158
  return usage;
3510
6159
  }
3511
- function decodeResponseItem(payload, ordinal, timestamp5) {
3512
- if (payload.type !== "message" || payload.role !== "user") return { kind: "ignored", ordinal, timestamp: timestamp5 };
6160
+ function decodeResponseItem(payload, ordinal, timestamp4) {
6161
+ if (payload.type !== "message" || payload.role !== "user") return { kind: "ignored", ordinal, timestamp: timestamp4 };
3513
6162
  const metadata = userMessageMetadata(payload.internal_chat_message_metadata_passthrough);
3514
6163
  const inputKind = inputKindFromContentItems(metadata.content_item_kinds);
3515
- if (inputKind === void 0) return { kind: "ignored", ordinal, timestamp: timestamp5 };
6164
+ if (inputKind === void 0) return { kind: "ignored", ordinal, timestamp: timestamp4 };
3516
6165
  const prompt = userTextContent(payload.content);
3517
6166
  return {
3518
6167
  kind: "user_text",
3519
6168
  ordinal,
3520
- timestamp: timestamp5,
6169
+ timestamp: timestamp4,
3521
6170
  prompt,
3522
6171
  input_kind: inputKind,
3523
- message_id: safeRef4(payload.id, "Codex user message identity is invalid."),
3524
- turn_id: safeRef4(metadata.turn_id, "Codex user message task identity is invalid.")
6172
+ message_id: safeRef5(payload.id, "Codex user message identity is invalid."),
6173
+ turn_id: safeRef5(metadata.turn_id, "Codex user message task identity is invalid.")
3525
6174
  };
3526
6175
  }
3527
6176
  function inputKindFromContentItems(kinds) {
@@ -3530,13 +6179,13 @@ function inputKindFromContentItems(kinds) {
3530
6179
  return kinds[0] === "goal.internal_context" ? "host_automatic" : void 0;
3531
6180
  }
3532
6181
  function userMessageMetadata(value) {
3533
- if (!isRecord6(value) || !Array.isArray(value.content_item_kinds)) reject("Codex user message provenance is malformed.");
6182
+ if (!isRecord7(value) || !Array.isArray(value.content_item_kinds)) reject("Codex user message provenance is malformed.");
3534
6183
  return { ...value, content_item_kinds: value.content_item_kinds };
3535
6184
  }
3536
6185
  function userTextContent(value) {
3537
6186
  if (!Array.isArray(value)) reject(`Codex user text content is malformed (${refusalFact("kind", typeof value, "array")}).`);
3538
6187
  if (value.length !== 1) reject(`Codex user text content is malformed (${refusalFact("items", value.length, "exactly one")}).`);
3539
- if (!isRecord6(value[0]) || value[0].type !== "input_text") reject(`Codex user text content is malformed (${refusalFact("item_type", isRecord6(value[0]) ? value[0].type : typeof value[0], "input_text")}).`);
6188
+ if (!isRecord7(value[0]) || value[0].type !== "input_text") reject(`Codex user text content is malformed (${refusalFact("item_type", isRecord7(value[0]) ? value[0].type : typeof value[0], "input_text")}).`);
3540
6189
  return boundedText(value[0].text, MAX_PROMPT_BYTES, "Codex user text is invalid.");
3541
6190
  }
3542
6191
  function safeOrdinal(value) {
@@ -3557,7 +6206,7 @@ function safeTimestamp(value) {
3557
6206
  if (!Number.isFinite(Date.parse(value))) reject(`Codex transcript timestamp is invalid (${refusalFact("parsed_ms", Date.parse(value), "a finite epoch milliseconds value")}).`);
3558
6207
  return value;
3559
6208
  }
3560
- function safeRef4(value, message) {
6209
+ function safeRef5(value, message) {
3561
6210
  if (typeof value !== "string" || !SAFE_REF8.test(value)) reject(message);
3562
6211
  return value;
3563
6212
  }
@@ -3572,7 +6221,7 @@ function boundedNonEmptyText(value, maximum, message) {
3572
6221
  if (result.length === 0) reject(message);
3573
6222
  return result;
3574
6223
  }
3575
- function isRecord6(value) {
6224
+ function isRecord7(value) {
3576
6225
  return value !== null && typeof value === "object" && !Array.isArray(value);
3577
6226
  }
3578
6227
  function reject(message) {
@@ -3616,7 +6265,7 @@ function assertCodexTranscriptHeader(registration, record3) {
3616
6265
  ])}).`);
3617
6266
  }
3618
6267
  function digest(value) {
3619
- return createHash6("sha256").update(value).digest("hex");
6268
+ return createHash7("sha256").update(value).digest("hex");
3620
6269
  }
3621
6270
  function timestamp3(now) {
3622
6271
  const value = now();
@@ -3632,78 +6281,53 @@ function codexSubmissionReference(hostInputRef, event, ordinal) {
3632
6281
  }
3633
6282
 
3634
6283
  // host/codex/src/codex-transcript-watcher.ts
3635
- var READ_CHUNK_BYTES = 256 * 1024;
3636
- var TRANSCRIPT_MISSING_REASON = "transcript_missing";
3637
- var CodexTranscriptWatcher = class {
6284
+ var CodexTranscriptWatcher = class extends HostTranscriptWatcher {
3638
6285
  store;
3639
- outboxRetentionMs;
3640
- now;
3641
- log;
3642
- producerInstallationRef;
3643
6286
  registerCurrentPrompt;
6287
+ releaseCurrentPrompt;
6288
+ diagnostic;
3644
6289
  constructor(options) {
3645
- if (typeof options.outbox_dir !== "string" || options.outbox_dir.length === 0) throw new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid.");
3646
- this.store = new CodexOutboxStore(options.outbox_dir);
3647
- this.outboxRetentionMs = options.retention_ms ?? CODEX_DEFAULT_RETENTION_MS;
3648
- this.now = options.now ?? (() => /* @__PURE__ */ new Date());
3649
- this.log = options.log ?? ((line) => {
3650
- process.stderr.write(`${line}
3651
- `);
6290
+ super(options, {
6291
+ default_retention_ms: CODEX_DEFAULT_RETENTION_MS,
6292
+ invalid_outbox: () => new CodexHostAdapterError("configuration", "Codex transcript watcher outbox is invalid."),
6293
+ clock_failure: () => new CodexHostAdapterError("storage", "Codex watcher clock is invalid.")
3652
6294
  });
3653
- this.producerInstallationRef = options.producer_installation_ref;
6295
+ this.store = new CodexOutboxStore(options.outbox_dir);
3654
6296
  this.registerCurrentPrompt = options.register_current_prompt;
6297
+ this.releaseCurrentPrompt = options.release_current_prompt;
6298
+ this.diagnostic = options.diagnostic ?? (() => void 0);
3655
6299
  }
3656
- async scanOnce() {
3657
- const registrations = await this.store.listTranscriptRegistrations();
3658
- let records = 0;
3659
- let enqueued = 0;
3660
- let quarantined = 0;
3661
- for (const registration of registrations) {
3662
- const result = await this.scanRegistration(registration);
3663
- records += result.records;
3664
- enqueued += result.enqueued;
3665
- if (result.quarantined) quarantined += 1;
3666
- }
3667
- return { registrations: registrations.length, records, enqueued, quarantined };
6300
+ transcriptPathOf(registration) {
6301
+ return registration.transcript_path;
3668
6302
  }
3669
- async scanRegistration(registration) {
3670
- let handle;
3671
- try {
3672
- handle = await open5(registration.transcript_path, O_RDONLY3 | O_NOFOLLOW2);
3673
- const { size, device, inode } = await ownedCodexTranscriptFile(handle);
3674
- const preflight = await this.preflight(registration, handle, size, device, inode);
3675
- if (preflight.cursor === null) return preflight.result;
3676
- const complete = await readCompleteChunk(handle, preflight.cursor, size);
3677
- if (complete === "empty" || complete === "partial") return { records: 0, enqueued: 0, quarantined: false };
3678
- return await this.consumeCompleteChunk(registration, handle, preflight.cursor, complete, device, inode);
3679
- } catch (error) {
3680
- if (handle === void 0 && isMissingTranscript(error)) return await this.retireRegistration(registration);
3681
- await this.quarantineFailure(registration, handle);
3682
- return { records: 0, enqueued: 0, quarantined: true };
3683
- } finally {
3684
- await handle?.close();
3685
- }
6303
+ async listRegistrations() {
6304
+ return this.store.listTranscriptRegistrations();
3686
6305
  }
3687
- /**
3688
- * A transcript the Host deleted never comes back, so retrying its
3689
- * registration once per reconcile interval is a failure with no end: a
3690
- * long-lived installation collects one permanently failing registration for
3691
- * every session Codex or the operator removes. Retire it at the scan that
3692
- * finds it missing and say so once, so the removal is readable and the next
3693
- * scan has nothing left to retry. Only ENOENT means gone; a permission or
3694
- * busy failure is about this moment, not about the file, and keeps the
3695
- * registration for the next scan.
3696
- */
3697
- async retireRegistration(registration) {
3698
- await this.store.retireTranscriptRegistration(registration);
3699
- this.log(`Codex retired a transcript registration: transcript_path=${JSON.stringify(registration.transcript_path)}, reason=${TRANSCRIPT_MISSING_REASON}.`);
3700
- return { records: 0, enqueued: 0, quarantined: false };
6306
+ async scanOpened(handle, registration) {
6307
+ const { size, device, inode } = await ownedCodexTranscriptFile(handle);
6308
+ const preflight = await this.preflight(registration, handle, size, device, inode);
6309
+ if (preflight.cursor === null) return preflight.result;
6310
+ const complete = await this.readChunk(handle, preflight.cursor.offset, size);
6311
+ if (complete === "empty" || complete === "partial") return { records: 0, enqueued: 0, quarantined: false };
6312
+ return await this.consumeCompleteChunk(registration, handle, preflight.cursor, complete, device, inode);
6313
+ }
6314
+ async scanFailed(handle, registration, error) {
6315
+ this.diagnostic("watcher_scan_failed", codexTranscriptScanFailureKind(error));
6316
+ await this.quarantineFailure(registration, handle);
6317
+ return { records: 0, enqueued: 0, quarantined: true };
6318
+ }
6319
+ async retireMissing(registration) {
6320
+ await this.releaseStoredPromptBestEffort(registration.host_session_ref, await this.store.readTranscriptCursor(registration).catch(() => null));
6321
+ return this.retireMissingTranscript(registration.transcript_path, "Codex", () => this.store.retireTranscriptRegistration(registration));
3701
6322
  }
3702
6323
  async preflight(registration, handle, size, device, inode) {
3703
6324
  const existing = await this.store.readTranscriptCursor(registration);
3704
6325
  let cursor = existing ?? codexTranscriptInitialCursor(registration, device, inode, this.now);
3705
- if (cursor.status === "quarantined") return { cursor: null, result: { records: 0, enqueued: 0, quarantined: true } };
3706
- const reason = await cursorFailureReason(registration, handle, cursor, size, device, inode);
6326
+ if (cursor.status === "quarantined") {
6327
+ if (cursor.reason !== "transcript_malformed") await this.releaseStoredPromptBestEffort(registration.host_session_ref, cursor);
6328
+ return { cursor: null, result: { records: 0, enqueued: 0, quarantined: true } };
6329
+ }
6330
+ const reason = this.cursorIdentityReason(cursor, registration.transcript_path, device, inode) ?? await this.cursorBoundsReason(handle, cursor, size);
3707
6331
  if (reason === null) return { cursor, result: { records: 0, enqueued: 0, quarantined: false } };
3708
6332
  await this.quarantine(registration, cursor, device, inode, reason);
3709
6333
  return { cursor: null, result: { records: 0, enqueued: 0, quarantined: true } };
@@ -3729,39 +6353,53 @@ var CodexTranscriptWatcher = class {
3729
6353
  async observeSessionMetadata(registration, record3) {
3730
6354
  if (record3.kind !== "session_meta") return;
3731
6355
  const session = await this.store.readSession(registration.host_source_ref, registration.host_session_ref);
3732
- if (session !== null && isRecord7(session.value)) await this.store.saveSession({ ...session, value: { ...session.value, host_version: record3.cli_version } });
6356
+ if (session !== null && this.isRecord(session.value)) await this.store.saveSession({ ...session, value: { ...session.value, host_version: record3.cli_version } });
3733
6357
  }
3734
6358
  async commitCursor(registration, handle, cursor, consumedBytes, device, inode, lastOrdinal, activeTask) {
3735
6359
  const offset = cursor.offset + consumedBytes;
3736
- const anchorStart = Math.max(0, offset - CODEX_TRANSCRIPT_ANCHOR_BYTES);
3737
- const anchor = Buffer.alloc(offset - anchorStart);
3738
- if (anchor.length > 0) await handle.read(anchor, 0, anchor.length, anchorStart);
3739
- await this.store.writeTranscriptCursor({ schema_version: "ceal.codex_transcript_cursor.v1", host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, transcript_path: registration.transcript_path, device, inode, offset, last_ordinal: lastOrdinal, anchor_start: anchorStart, anchor_sha256: sha2562(anchor), header_validated: true, ...activeTask === void 0 ? {} : { active_task: activeTask }, status: "active", updated_at: timestamp4(this.now) });
6360
+ const anchor = await this.readAnchor(handle, offset, CODEX_TRANSCRIPT_ANCHOR_BYTES);
6361
+ await this.store.writeTranscriptCursor({ schema_version: "ceal.codex_transcript_cursor.v1", host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, transcript_path: registration.transcript_path, device, inode, offset, last_ordinal: lastOrdinal, anchor_start: anchor.start, anchor_sha256: anchor.sha256, header_validated: true, ...activeTask === void 0 ? {} : { active_task: activeTask }, status: "active", updated_at: this.stamp() });
3740
6362
  }
3741
6363
  async quarantineFailure(registration, handle) {
3742
6364
  if (handle === void 0) return;
3743
6365
  const stats = await handle.stat().catch(() => null);
3744
6366
  if (stats === null) return;
3745
6367
  const existing = await this.store.readTranscriptCursor(registration).catch(() => null);
3746
- await this.quarantine(registration, existing ?? codexTranscriptInitialCursor(registration, String(stats.dev), String(stats.ino), this.now), String(stats.dev), String(stats.ino), "transcript_malformed");
6368
+ const quarantined = {
6369
+ ...existing ?? codexTranscriptInitialCursor(registration, String(stats.dev), String(stats.ino), this.now),
6370
+ transcript_path: registration.transcript_path,
6371
+ device: String(stats.dev),
6372
+ inode: String(stats.ino),
6373
+ status: "quarantined",
6374
+ reason: "transcript_malformed",
6375
+ updated_at: this.stamp()
6376
+ };
6377
+ await this.store.writeTranscriptCursor(quarantined);
3747
6378
  }
3748
6379
  async processRecord(registration, activeTask, record3) {
3749
- if (record3.kind === "task_started") {
3750
- return { activeTask: { codex_turn_id: record3.turn_id, host_turn_ref: hostTurnReference(registration.host_source_ref, registration.host_session_ref, record3.turn_id), started_at: record3.timestamp }, enqueued: 0 };
3751
- }
6380
+ if (record3.kind === "task_started") return this.processTaskStarted(registration, activeTask, record3);
3752
6381
  if (record3.kind === "turn_context") return { ...activeTask === void 0 ? {} : { activeTask: record3.turn_id === activeTask.codex_turn_id ? { ...activeTask, model: record3.model } : activeTask }, enqueued: 0 };
3753
6382
  if (record3.kind === "token_count") return { ...activeTask === void 0 ? {} : { activeTask: accumulateTokenCount(activeTask, record3) }, enqueued: 0 };
3754
6383
  if (record3.kind === "user_text") return this.processUserInput(registration, activeTask, record3);
3755
6384
  if (record3.kind === "task_complete" || record3.kind === "turn_aborted") return this.processTerminal(registration, activeTask, record3);
3756
6385
  return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
3757
6386
  }
6387
+ async processTaskStarted(registration, activeTask, record3) {
6388
+ if (activeTask !== void 0 && activeTask.codex_turn_id !== record3.turn_id && activeTask.prompt_ref !== void 0) await this.releasePrompt(registration.host_session_ref, activeTask, activeTask.prompt_ref);
6389
+ return { activeTask: { codex_turn_id: record3.turn_id, host_turn_ref: hostTurnReference(registration.host_source_ref, registration.host_session_ref, record3.turn_id), started_at: record3.timestamp }, enqueued: 0 };
6390
+ }
3758
6391
  async processUserInput(registration, activeTask, record3) {
3759
- if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
6392
+ if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id) {
6393
+ const adopted = await this.adoptHookCorrelatedTurn(registration, activeTask, record3);
6394
+ if (adopted === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
6395
+ activeTask = adopted;
6396
+ }
3760
6397
  const hostInputRef = hostInputReference(registration.host_source_ref, registration.host_session_ref, record3.turn_id, record3.message_id, record3.ordinal, record3.prompt);
3761
6398
  const origin = activeTask.origin_host_input_ref === void 0;
3762
6399
  const promptValue = promptObservationValue(record3.prompt);
3763
6400
  const currentPromptRef = hostProducerPromptRef(promptValue.body_sha256);
3764
6401
  const promptRef = activeTask.prompt_ref ?? currentPromptRef;
6402
+ const steeredPromptRef = await this.steeredPromptRef(registration, activeTask, origin, currentPromptRef);
3765
6403
  const identity = { host_source_ref: registration.host_source_ref, host_session_ref: registration.host_session_ref, host_turn_ref: activeTask.host_turn_ref };
3766
6404
  const observations = [{
3767
6405
  observation_ref: observationRef("transcript_user_text", hostInputRef, record3.prompt),
@@ -3785,16 +6423,90 @@ var CodexTranscriptWatcher = class {
3785
6423
  origin_input: origin,
3786
6424
  submission_ref: codexSubmissionReference(hostInputRef, "input", record3.ordinal),
3787
6425
  created_at: record3.timestamp,
3788
- expires_at: expiration(this.now, this.outboxRetentionMs)
6426
+ expires_at: this.expire(this.outboxRetentionMs)
6427
+ };
6428
+ const persisted = await this.persistUserInputTurn(registration, activeTask, record3, hostInputRef, origin, currentPromptRef, promptRef, identity, envelope);
6429
+ if (steeredPromptRef !== null) await this.activateTranscriptTurnContext(identity, steeredPromptRef, envelope.expires_at);
6430
+ return persisted;
6431
+ }
6432
+ /**
6433
+ * The steered prompt to re-activate under the running task, or null when
6434
+ * there is nothing to repair. A steered message joins the running turn
6435
+ * with new prompt bytes but no task_started. When the steer hook already
6436
+ * replaced the turn selection (a turn id the hook did not recognize as
6437
+ * the running one, or a hook that ran before any context was live), the
6438
+ * running task's context no longer matches and the next invocation would
6439
+ * wait for a boundary that never comes. When the hook kept the live
6440
+ * selection, the context still matches and this stays null.
6441
+ */
6442
+ async steeredPromptRef(registration, activeTask, origin, currentPromptRef) {
6443
+ if (origin || activeTask.prompt_ref === void 0 || activeTask.prompt_ref === currentPromptRef) return null;
6444
+ const selection = await this.store.readInvocationTurnSelection(registration.host_source_ref, registration.host_session_ref).catch(() => null);
6445
+ return selection?.prompt_ref === currentPromptRef ? currentPromptRef : null;
6446
+ }
6447
+ /**
6448
+ * Adopt the live hooked turn when its transcript message arrives before
6449
+ * (or without) its task_started, as an interrupted turn's follow-up can.
6450
+ * The UserPromptSubmit hook names the exact hooked prompt, so only a
6451
+ * message carrying those bytes adopts; inherited history and other turns
6452
+ * stay ignored. A stale active task for another turn releases first, the
6453
+ * same as a task_started supersession.
6454
+ */
6455
+ async adoptHookCorrelatedTurn(registration, activeTask, record3) {
6456
+ const currentPromptRef = hostProducerPromptRef(promptObservationValue(record3.prompt).body_sha256);
6457
+ const selection = await this.store.readInvocationTurnSelection(registration.host_source_ref, registration.host_session_ref);
6458
+ if (selection?.prompt_ref !== currentPromptRef) return void 0;
6459
+ if (activeTask !== void 0 && activeTask.codex_turn_id !== record3.turn_id && activeTask.prompt_ref !== void 0) {
6460
+ await this.releasePrompt(registration.host_session_ref, activeTask, activeTask.prompt_ref);
6461
+ }
6462
+ return {
6463
+ codex_turn_id: record3.turn_id,
6464
+ host_turn_ref: hostTurnReference(registration.host_source_ref, registration.host_session_ref, record3.turn_id),
6465
+ started_at: record3.timestamp
3789
6466
  };
3790
- await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record3.prompt, envelope.expires_at);
3791
- await this.store.put(envelope);
3792
- if (origin) await this.store.activateInvocationContext(identity, promptRef, envelope.expires_at);
6467
+ }
6468
+ async persistUserInputTurn(registration, activeTask, record3, hostInputRef, origin, currentPromptRef, promptRef, identity, envelope) {
6469
+ const custodyRegistered = await this.registerPrompt(origin, registration, activeTask, currentPromptRef, record3.prompt, envelope.expires_at);
6470
+ if (custodyRegistered) this.diagnostic("watcher_turn_observed");
6471
+ try {
6472
+ await this.store.put(envelope);
6473
+ if (origin) await this.activateTranscriptTurnContext(identity, promptRef, envelope.expires_at);
6474
+ } catch (error) {
6475
+ if (custodyRegistered) await this.releasePrompt(registration.host_session_ref, activeTask, currentPromptRef).catch(() => void 0);
6476
+ throw error;
6477
+ }
3793
6478
  return { activeTask: { ...activeTask, origin_host_input_ref: activeTask.origin_host_input_ref ?? hostInputRef, prompt_ref: activeTask.prompt_ref ?? currentPromptRef }, enqueued: 1 };
3794
6479
  }
3795
6480
  async registerPrompt(origin, registration, activeTask, promptRef, prompt, expiresAt) {
3796
- if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return;
3797
- await this.registerCurrentPrompt({ producer_id: "codex", producer_installation_ref: this.producerInstallationRef, local_session_ref: registration.host_session_ref, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef, current_prompt: prompt, context_expires_at: expiresAt });
6481
+ if (!origin || this.producerInstallationRef === void 0 || this.registerCurrentPrompt === void 0) return false;
6482
+ const register = this.registerCurrentPrompt;
6483
+ const installationRef = this.producerInstallationRef;
6484
+ return registerHostCurrentPromptDiagnosed(
6485
+ () => register({ producer_id: "codex", producer_installation_ref: installationRef, local_session_ref: registration.host_session_ref, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef, current_prompt: prompt, context_expires_at: expiresAt }),
6486
+ (event) => this.diagnostic(event)
6487
+ );
6488
+ }
6489
+ async activateTranscriptTurnContext(identity, promptRef, expiresAt) {
6490
+ try {
6491
+ const selection = await this.store.readInvocationTurnSelection(identity.host_source_ref, identity.host_session_ref);
6492
+ const turnGenerationRef = selection?.prompt_ref === promptRef ? selection.turn_generation_ref : void 0;
6493
+ await this.store.activateInvocationContext(identity, promptRef, expiresAt, turnGenerationRef);
6494
+ this.diagnostic("activation_recorded");
6495
+ } catch (error) {
6496
+ this.diagnostic("activation_failed");
6497
+ throw error;
6498
+ }
6499
+ }
6500
+ async releasePrompt(sessionRef, activeTask, promptRef) {
6501
+ if (this.producerInstallationRef === void 0 || this.releaseCurrentPrompt === void 0) return;
6502
+ await this.releaseCurrentPrompt({ producer_id: "codex", producer_installation_ref: this.producerInstallationRef, local_session_ref: sessionRef, local_turn_ref: activeTask.host_turn_ref, prompt_ref: promptRef });
6503
+ }
6504
+ async releaseStoredPromptBestEffort(sessionRef, cursor) {
6505
+ await this.releaseActiveTaskBestEffort(sessionRef, cursor?.active_task);
6506
+ }
6507
+ async releaseActiveTaskBestEffort(sessionRef, activeTask) {
6508
+ if (activeTask?.prompt_ref === void 0) return;
6509
+ await this.releasePrompt(sessionRef, activeTask, activeTask.prompt_ref).catch(() => void 0);
3798
6510
  }
3799
6511
  async processTerminal(registration, activeTask, record3) {
3800
6512
  if (activeTask === void 0 || activeTask.codex_turn_id !== record3.turn_id || activeTask.origin_host_input_ref === void 0 || activeTask.prompt_ref === void 0) return { ...activeTask === void 0 ? {} : { activeTask }, enqueued: 0 };
@@ -3812,16 +6524,26 @@ var CodexTranscriptWatcher = class {
3812
6524
  origin_input: false,
3813
6525
  submission_ref: codexSubmissionReference(activeTask.origin_host_input_ref, "terminal", record3.ordinal),
3814
6526
  created_at: record3.timestamp,
3815
- expires_at: expiration(this.now, this.outboxRetentionMs)
6527
+ expires_at: this.expire(this.outboxRetentionMs)
3816
6528
  });
6529
+ await this.releasePrompt(registration.host_session_ref, activeTask, activeTask.prompt_ref);
3817
6530
  await this.store.clearInvocationContext(identity, this.now());
3818
6531
  return { enqueued: 1 };
3819
6532
  }
3820
6533
  async quarantine(registration, cursor, device, inode, reason) {
3821
- const quarantined = { ...cursor, transcript_path: registration.transcript_path, device, inode, status: "quarantined", reason, updated_at: timestamp4(this.now) };
6534
+ await this.releaseStoredPromptBestEffort(registration.host_session_ref, cursor);
6535
+ const quarantined = { ...cursor, transcript_path: registration.transcript_path, device, inode, status: "quarantined", reason, updated_at: this.stamp() };
3822
6536
  await this.store.writeTranscriptCursor(quarantined);
3823
6537
  }
3824
6538
  };
6539
+ function codexTranscriptScanFailureKind(error) {
6540
+ return transcriptScanFailureKind(error, (candidate) => {
6541
+ if (!(candidate instanceof CodexHostAdapterError)) return void 0;
6542
+ if (candidate.code === "payload_rejected") return "payload_rejected";
6543
+ if (candidate.code === "storage") return "read_error";
6544
+ return void 0;
6545
+ });
6546
+ }
3825
6547
  function accumulateTokenCount(activeTask, record3) {
3826
6548
  if (record3.usage_gap_reason !== void 0) return { ...activeTask, token_usage_gap_reason: record3.usage_gap_reason };
3827
6549
  const last = record3.last_usage;
@@ -3855,19 +6577,18 @@ function terminalCostValue() {
3855
6577
  return notRecorded("provider_cost_not_observed");
3856
6578
  }
3857
6579
  function notRecorded(reason) {
3858
- return { status: "not_recorded", reason };
6580
+ return hostObservationNotRecorded(reason);
3859
6581
  }
3860
6582
  function tokenObservationValue(usage) {
3861
6583
  return {
3862
- status: "available",
3863
- unit: "tokens",
3864
- input: usage.input_tokens,
3865
- output: usage.output_tokens,
3866
- total: usage.total_tokens,
3867
- cached_input: usage.cached_input_tokens,
3868
- cache_write_input: usage.cache_write_input_tokens,
3869
- reasoning_output: usage.reasoning_output_tokens,
3870
- source: "codex_transcript.event_msg.token_count.info.last_token_usage",
6584
+ ...createHostTokenObservationValue({
6585
+ input: usage.input_tokens,
6586
+ output: usage.output_tokens,
6587
+ total: usage.total_tokens,
6588
+ cached_input: usage.cached_input_tokens,
6589
+ cache_write_input: usage.cache_write_input_tokens,
6590
+ reasoning_output: usage.reasoning_output_tokens
6591
+ }, "codex_transcript.event_msg.token_count.info.last_token_usage"),
3871
6592
  attribution: "sequential_active_task",
3872
6593
  total_usage_role: "dedup_and_reset_detection_only"
3873
6594
  };
@@ -3901,65 +6622,24 @@ function looksLikeStaleRegression(current, previous, last) {
3901
6622
  if (previous.total_tokens <= 0 || current.total_tokens <= 0 || last.total_tokens <= 0) return false;
3902
6623
  return current.total_tokens * 100 >= previous.total_tokens * 98 || current.total_tokens + last.total_tokens * 2 >= previous.total_tokens;
3903
6624
  }
3904
- function isMissingTranscript(error) {
3905
- return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
3906
- }
3907
- async function cursorFailureReason(registration, handle, cursor, size, device, inode) {
3908
- if (cursor.device !== device || cursor.inode !== inode || cursor.transcript_path !== registration.transcript_path) return "transcript_replaced";
3909
- if (size < cursor.offset) return "transcript_truncated";
3910
- if (cursor.offset > 0 && !await anchorMatches(handle, cursor)) return "transcript_rewritten";
3911
- return null;
3912
- }
3913
- async function readCompleteChunk(handle, cursor, size) {
3914
- const available = Math.max(0, size - cursor.offset);
3915
- if (available === 0) return "empty";
3916
- const chunks = [];
3917
- let position = cursor.offset;
3918
- let total = 0;
3919
- let lastNewline = -1;
3920
- while (position < size) {
3921
- const buffer = Buffer.alloc(Math.min(READ_CHUNK_BYTES, size - position));
3922
- const read = await handle.read(buffer, 0, buffer.length, position);
3923
- if (read.bytesRead === 0) break;
3924
- const chunk = buffer.subarray(0, read.bytesRead);
3925
- chunks.push(chunk);
3926
- const newline = chunk.lastIndexOf(10);
3927
- if (newline >= 0) lastNewline = total + newline;
3928
- total += chunk.length;
3929
- position += chunk.length;
3930
- if (lastNewline >= 0) break;
3931
- }
3932
- if (lastNewline < 0) return "partial";
3933
- return Buffer.concat(chunks, total).subarray(0, lastNewline + 1);
3934
- }
3935
6625
  function assertRecordSequence(registration, cursor, records, lastOrdinal, record3) {
3936
6626
  if ((cursor.header_validated || records > 0) && record3.ordinal <= lastOrdinal) throw new CodexHostAdapterError("payload_rejected", `Codex transcript ordinal is not monotonic (${refusalFact("ordinal", record3.ordinal, `greater than ${lastOrdinal}`)}).`);
3937
6627
  if (!cursor.header_validated && records === 0) assertCodexTranscriptHeader(registration, record3);
3938
6628
  }
3939
- async function anchorMatches(handle, cursor) {
3940
- const buffer = Buffer.alloc(cursor.offset - cursor.anchor_start);
3941
- if (buffer.length > 0) await handle.read(buffer, 0, buffer.length, cursor.anchor_start);
3942
- return sha2562(buffer) === cursor.anchor_sha256;
3943
- }
3944
- function sha2562(value) {
3945
- return createHash7("sha256").update(value).digest("hex");
3946
- }
3947
- function isRecord7(value) {
3948
- return value !== null && typeof value === "object" && !Array.isArray(value);
3949
- }
3950
- function timestamp4(now) {
3951
- const value = now();
3952
- if (!Number.isFinite(value.getTime())) throw new CodexHostAdapterError("storage", "Codex watcher clock is invalid.");
3953
- return value.toISOString();
3954
- }
3955
- function expiration(now, retentionMs) {
3956
- return new Date(Date.parse(timestamp4(now)) + retentionMs).toISOString();
3957
- }
3958
6629
 
3959
6630
  // host/codex/src/codex-producer-runtime.ts
3960
6631
  async function drainCodexProducerOnce(options) {
3961
6632
  const promptPort = new HostRelayCurrentPromptPort(options.relay_endpoint, options.timeout_ms);
3962
- const scan = await new CodexTranscriptWatcher({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, register_current_prompt: (input) => promptPort.register(input) }).scanOnce();
6633
+ const scan = await new CodexTranscriptWatcher({
6634
+ outbox_dir: options.outbox_dir,
6635
+ producer_installation_ref: options.producer_installation_ref,
6636
+ register_current_prompt: (input) => promptPort.register(input),
6637
+ release_current_prompt: (identity) => promptPort.release(identity),
6638
+ diagnostic: (event, failure_kind) => writeHostServiceDiagnostic("codex", event, failure_kind)
6639
+ }).scanOnce().catch((error) => {
6640
+ writeHostServiceDiagnostic("codex", "watcher_scan_failed", codexTranscriptScanFailureKind(error));
6641
+ throw error;
6642
+ });
3963
6643
  const producer = new CodexProducer({ outbox_dir: options.outbox_dir, producer_installation_ref: options.producer_installation_ref, relay: new HostRelayIpcAdmissionPort(options.relay_endpoint, options.timeout_ms), ...options.producer_epoch === void 0 ? {} : { producer_epoch: options.producer_epoch }, ...options.now === void 0 ? {} : { now: options.now } });
3964
6644
  return { scanned: scan.enqueued, ...await producer.drainOutbox() };
3965
6645
  }
@@ -3982,15 +6662,52 @@ var CODEX_PRODUCER_DESCRIPTOR = {
3982
6662
  drain: drainCodexProducerOnce
3983
6663
  };
3984
6664
 
6665
+ // host/codex/src/codex-visible-output-budget.ts
6666
+ import { readFile as readFile3 } from "node:fs/promises";
6667
+ import { homedir } from "node:os";
6668
+ import { join as join5 } from "node:path";
6669
+ var import_toml = __toESM(require_toml(), 1);
6670
+ var CODEX_DEFAULT_TOOL_OUTPUT_TOKEN_LIMIT = 5e3;
6671
+ var CODEX_UTF8_BYTES_PER_OUTPUT_TOKEN = 4;
6672
+ async function resolveCodexVisibleOutputMaxBytes(environment = process.env) {
6673
+ const codexHome = environment.CODEX_HOME || join5(homedir(), ".codex");
6674
+ let source;
6675
+ try {
6676
+ source = await readFile3(join5(codexHome, "config.toml"), "utf8");
6677
+ } catch (error) {
6678
+ return isNotFound2(error) ? codexBytes(CODEX_DEFAULT_TOOL_OUTPUT_TOKEN_LIMIT) : void 0;
6679
+ }
6680
+ try {
6681
+ const parsed = import_toml.default.parse(source);
6682
+ if (!isRecord8(parsed)) return void 0;
6683
+ const configured = parsed.tool_output_token_limit;
6684
+ if (configured === void 0) return codexBytes(CODEX_DEFAULT_TOOL_OUTPUT_TOKEN_LIMIT);
6685
+ return typeof configured === "number" && Number.isSafeInteger(configured) && configured > 0 ? codexBytes(configured) : void 0;
6686
+ } catch {
6687
+ return void 0;
6688
+ }
6689
+ }
6690
+ function codexBytes(tokens) {
6691
+ return Math.min(tokens * CODEX_UTF8_BYTES_PER_OUTPUT_TOKEN, CEAL_CANONICAL_HTTP_MAX_RESPONSE_BYTES);
6692
+ }
6693
+ function isRecord8(value) {
6694
+ return value !== null && typeof value === "object" && !Array.isArray(value);
6695
+ }
6696
+ function isNotFound2(error) {
6697
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
6698
+ }
6699
+
3985
6700
  // host/codex/src/codex-invocation-authentication-command.ts
3986
6701
  var CODEX_INVOCATION_AUTHENTICATION_DESCRIPTOR = {
3987
6702
  producer_id: "codex",
6703
+ context_activation_wait_max_ms: CODEX_CONTEXT_ACTIVATION_WAIT_MAX_MS,
3988
6704
  create_store: (directory) => new CodexOutboxStore(directory),
3989
6705
  session_id_env: CODEX_THREAD_ID_ENVIRONMENT,
3990
6706
  session_ref: hostSessionReference,
3991
6707
  config_flag: HOST_PRODUCER_CONFIG_FLAG,
3992
6708
  parse_config_flag: parseHostProducerConfigFlag,
3993
- read_producer_config: (configPath) => readHostProducerConfig(CODEX_PRODUCER_DESCRIPTOR, configPath)
6709
+ read_producer_config: (configPath) => readHostProducerConfig(CODEX_PRODUCER_DESCRIPTOR, configPath),
6710
+ resolve_visible_output_max_bytes: () => resolveCodexVisibleOutputMaxBytes()
3994
6711
  };
3995
6712
  function runCodexInvocationAuthenticationCommand(args, options) {
3996
6713
  return runHostInvocationAuthenticationCommand(CODEX_INVOCATION_AUTHENTICATION_DESCRIPTOR, args, options);