opencode-context-tree 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tui.js CHANGED
@@ -1,12 +1,16 @@
1
1
  // @bun
2
2
  var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
3
7
  var __export = (target, all) => {
4
8
  for (var name in all)
5
9
  __defProp(target, name, {
6
10
  get: all[name],
7
11
  enumerable: true,
8
12
  configurable: true,
9
- set: (newValue) => all[name] = () => newValue
13
+ set: __exportSetter.bind(all, name)
10
14
  });
11
15
  };
12
16
 
@@ -62,7 +66,17 @@ function contextSizeOf(messages) {
62
66
  }
63
67
  return { tokens: lastAssistantInput + newer, estimated: newer > 0 };
64
68
  }
65
- function bandFor(tokens) {
69
+ function bandFor(tokens, limit) {
70
+ if (limit && limit > 0) {
71
+ const r = tokens / limit;
72
+ if (r < 0.25)
73
+ return "low";
74
+ if (r < 0.6)
75
+ return "healthy";
76
+ if (r < 0.85)
77
+ return "filling";
78
+ return "red";
79
+ }
66
80
  if (tokens < 8000)
67
81
  return "low";
68
82
  if (tokens < 32000)
@@ -71,6 +85,12 @@ function bandFor(tokens) {
71
85
  return "filling";
72
86
  return "red";
73
87
  }
88
+ function contextBar(tokens, limit, cells = 5) {
89
+ if (!(limit > 0))
90
+ return "";
91
+ const filled = tokens <= 0 ? 0 : Math.min(cells, Math.max(1, Math.round(tokens / limit * cells)));
92
+ return "\u2593".repeat(filled) + "\u2591".repeat(cells - filled);
93
+ }
74
94
  function formatK(tokens) {
75
95
  if (tokens < 1000)
76
96
  return String(tokens);
@@ -78,7 +98,8 @@ function formatK(tokens) {
78
98
  return `${k.endsWith(".0") ? k.slice(0, -2) : k}k`;
79
99
  }
80
100
  function formatContext(size, limit) {
81
- return `ctx ${size.estimated ? "~" : ""}${formatK(size.tokens)}${limit ? `/${formatK(limit)}` : ""} \xB7 ${bandFor(size.tokens)}`;
101
+ const bar = limit ? `${contextBar(size.tokens, limit)} ` : "";
102
+ return `ctx ${bar}${size.estimated ? "~" : ""}${formatK(size.tokens)}${limit ? `/${formatK(limit)}` : ""} \xB7 ${bandFor(size.tokens, limit)}`;
82
103
  }
83
104
 
84
105
  // src/shared/store.ts
@@ -88,643 +109,643 @@ import path from "path";
88
109
  // node_modules/zod/v4/classic/external.js
89
110
  var exports_external = {};
90
111
  __export(exports_external, {
91
- xor: () => xor,
92
- xid: () => xid2,
93
- void: () => _void2,
94
- validateAsync: () => validateAsync,
95
- validate: () => validate,
96
- uuidv7: () => uuidv7,
97
- uuidv6: () => uuidv6,
98
- uuidv4: () => uuidv4,
99
- uuid: () => uuid2,
100
- util: () => exports_util,
101
- url: () => url,
102
- uppercase: () => _uppercase,
103
- unknown: () => unknown,
104
- union: () => union,
105
- undefined: () => _undefined3,
106
- ulid: () => ulid2,
107
- uint64: () => uint64,
108
- uint32: () => uint32,
109
- tuple: () => tuple,
110
- trim: () => _trim,
111
- treeifyError: () => treeifyError,
112
- transform: () => transform,
113
- toZod: () => toZod,
114
- toUpperCase: () => _toUpperCase,
115
- toLowerCase: () => _toLowerCase,
116
- toJSONSchema: () => toJSONSchema,
117
- templateLiteral: () => templateLiteral,
118
- symbol: () => symbol,
119
- superRefine: () => superRefine,
120
- success: () => success,
121
- stringbool: () => stringbool,
122
- stringFormat: () => stringFormat,
123
- string: () => string2,
124
- strictObject: () => strictObject,
125
- startsWith: () => _startsWith,
126
- slugify: () => _slugify,
127
- size: () => _size,
128
- setErrorMap: () => setErrorMap,
129
- set: () => set,
130
- safeParseAsync: () => safeParseAsync2,
131
- safeParse: () => safeParse2,
132
- safeEncodeAsync: () => safeEncodeAsync2,
133
- safeEncode: () => safeEncode2,
134
- safeDecodeAsync: () => safeDecodeAsync2,
135
- safeDecode: () => safeDecode2,
136
- registry: () => registry,
137
- regexes: () => exports_regexes,
138
- regex: () => _regex,
139
- refine: () => refine,
140
- record: () => record,
141
- readonly: () => readonly,
142
- property: () => _property,
143
- properties: () => _properties,
144
- promise: () => promise,
145
- prettifyError: () => prettifyError,
146
- preprocess: () => preprocess,
147
- prefault: () => prefault,
148
- positive: () => _positive,
149
- pipe: () => pipe,
150
- partialRecord: () => partialRecord,
151
- parseAsync: () => parseAsync2,
152
- parse: () => parse3,
153
- overwrite: () => _overwrite,
154
- output: () => output,
155
- optional: () => optional,
156
- object: () => object,
157
- number: () => number2,
158
- nullish: () => nullish2,
159
- nullable: () => nullable,
160
- null: () => _null3,
161
- normalize: () => _normalize,
162
- nonpositive: () => _nonpositive,
163
- nonoptional: () => nonoptional,
164
- nonnegative: () => _nonnegative,
165
- never: () => never,
166
- negative: () => _negative,
167
- nativeEnum: () => nativeEnum,
168
- nanoid: () => nanoid2,
169
- nan: () => nan,
170
- multipleOf: () => _multipleOf,
171
- minSize: () => _minSize,
172
- minLength: () => _minLength,
173
- mime: () => _mime,
174
- meta: () => meta2,
175
- memoizer: () => memoizer,
176
- maxSize: () => _maxSize,
177
- maxLength: () => _maxLength,
178
- map: () => map,
179
- mac: () => mac2,
180
- lte: () => _lte,
181
- lt: () => _lt,
182
- lowercase: () => _lowercase,
183
- looseRecord: () => looseRecord,
184
- looseObject: () => looseObject,
185
- locales: () => exports_locales,
186
- literal: () => literal,
187
- length: () => _length,
188
- lazy: () => lazy,
189
- ksuid: () => ksuid2,
190
- keyof: () => keyof,
191
- jwt: () => jwt,
192
- json: () => json,
193
- iso: () => exports_iso,
194
- ipv6: () => ipv62,
195
- ipv4: () => ipv42,
196
- invertCodec: () => invertCodec,
197
- intersection: () => intersection,
198
- int64: () => int64,
199
- int32: () => int32,
200
- int: () => int,
201
- instanceof: () => _instanceof,
202
- input: () => input,
203
- includes: () => _includes,
204
- httpUrl: () => httpUrl,
205
- hostname: () => hostname2,
206
- hex: () => hex2,
207
- hash: () => hash,
208
- guid: () => guid2,
209
- gte: () => _gte,
210
- gt: () => _gt,
211
- globalRegistry: () => globalRegistry,
212
- getErrorMap: () => getErrorMap,
213
- getDiscriminatedOption: () => getDiscriminatedOption,
214
- function: () => _function,
215
- fromJSONSchema: () => fromJSONSchema,
216
- formatError: () => formatError,
217
- float64: () => float64,
218
- float32: () => float32,
219
- flattenError: () => flattenError,
220
- file: () => file,
221
- exactOptional: () => exactOptional,
222
- enum: () => _enum2,
223
- endsWith: () => _endsWith,
224
- encodeAsync: () => encodeAsync2,
225
- encode: () => encode2,
226
- emoji: () => emoji2,
227
- email: () => email2,
228
- e164: () => e1642,
229
- discriminatedUnion: () => discriminatedUnion,
230
- describe: () => describe2,
231
- deepPartial: () => deepPartial,
232
- decodeAsync: () => decodeAsync2,
233
- decode: () => decode2,
234
- date: () => date2,
235
- custom: () => custom,
236
- cuid2: () => cuid22,
237
- cuid: () => cuid3,
238
- creditCard: () => creditCard2,
239
- core: () => exports_core2,
240
- config: () => config,
241
- compile: () => compile,
242
- coerce: () => exports_coerce,
243
- codec: () => codec,
244
- clone: () => clone,
245
- cidrv6: () => cidrv62,
246
- cidrv4: () => cidrv42,
247
- check: () => check,
248
- catch: () => _catch2,
249
- boolean: () => boolean2,
250
- bigint: () => bigint2,
251
- base64url: () => base64url2,
252
- base64: () => base642,
253
- array: () => array,
254
- any: () => any,
255
- _function: () => _function,
256
- _default: () => _default2,
257
- _ZodString: () => _ZodString,
258
- ZodXor: () => ZodXor,
259
- ZodXID: () => ZodXID,
260
- ZodVoid: () => ZodVoid,
261
- ZodUnknown: () => ZodUnknown,
262
- ZodUnion: () => ZodUnion,
263
- ZodUndefined: () => ZodUndefined,
264
- ZodUUID: () => ZodUUID,
265
- ZodURL: () => ZodURL,
266
- ZodULID: () => ZodULID,
267
- ZodType: () => ZodType,
268
- ZodTuple: () => ZodTuple,
269
- ZodTransform: () => ZodTransform,
270
- ZodTemplateLiteral: () => ZodTemplateLiteral,
271
- ZodSymbol: () => ZodSymbol,
272
- ZodSuccess: () => ZodSuccess,
273
- ZodStringFormat: () => ZodStringFormat,
274
- ZodString: () => ZodString,
275
- ZodSet: () => ZodSet,
276
- ZodRecord: () => ZodRecord,
277
- ZodRealError: () => ZodRealError,
278
- ZodReadonly: () => ZodReadonly,
279
- ZodPromise: () => ZodPromise,
280
- ZodPreprocess: () => ZodPreprocess,
281
- ZodPrefault: () => ZodPrefault,
282
- ZodPipe: () => ZodPipe,
283
- ZodOptional: () => ZodOptional,
284
- ZodObject: () => ZodObject,
285
- ZodNumberFormat: () => ZodNumberFormat,
286
- ZodNumber: () => ZodNumber,
287
- ZodNullable: () => ZodNullable,
288
- ZodNull: () => ZodNull,
289
- ZodNonOptional: () => ZodNonOptional,
290
- ZodNever: () => ZodNever,
291
- ZodNanoID: () => ZodNanoID,
292
- ZodNaN: () => ZodNaN,
293
- ZodMap: () => ZodMap,
294
- ZodMAC: () => ZodMAC,
295
- ZodLiteral: () => ZodLiteral,
296
- ZodLazy: () => ZodLazy,
297
- ZodKSUID: () => ZodKSUID,
298
- ZodJWT: () => ZodJWT,
299
- ZodIssueCode: () => ZodIssueCode,
300
- ZodIntersection: () => ZodIntersection,
301
- ZodISOTime: () => ZodISOTime,
302
- ZodISODuration: () => ZodISODuration,
303
- ZodISODateTime: () => ZodISODateTime,
304
- ZodISODate: () => ZodISODate,
305
- ZodIPv6: () => ZodIPv6,
306
- ZodIPv4: () => ZodIPv4,
307
- ZodGUID: () => ZodGUID,
308
- ZodFunction: () => ZodFunction,
309
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
310
- ZodFile: () => ZodFile,
311
- ZodExactOptional: () => ZodExactOptional,
312
- ZodError: () => ZodError,
313
- ZodEnum: () => ZodEnum,
314
- ZodEmoji: () => ZodEmoji,
315
- ZodEmail: () => ZodEmail,
316
- ZodE164: () => ZodE164,
317
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
318
- ZodDefault: () => ZodDefault,
319
- ZodDate: () => ZodDate,
320
- ZodCustomStringFormat: () => ZodCustomStringFormat,
321
- ZodCustom: () => ZodCustom,
322
- ZodCreditCard: () => ZodCreditCard,
323
- ZodCompileUnsupportedError: () => ZodCompileUnsupportedError,
324
- ZodCompileAsyncError: () => ZodCompileAsyncError,
325
- ZodCodec: () => ZodCodec,
326
- ZodCatch: () => ZodCatch,
327
- ZodCUID2: () => ZodCUID2,
328
- ZodCUID: () => ZodCUID,
329
- ZodCIDRv6: () => ZodCIDRv6,
330
- ZodCIDRv4: () => ZodCIDRv4,
331
- ZodBoolean: () => ZodBoolean,
332
- ZodBigIntFormat: () => ZodBigIntFormat,
333
- ZodBigInt: () => ZodBigInt,
334
- ZodBase64URL: () => ZodBase64URL,
335
- ZodBase64: () => ZodBase64,
336
- ZodArray: () => ZodArray,
337
- ZodAny: () => ZodAny,
338
- TimePrecision: () => TimePrecision,
339
- NEVER: () => NEVER,
340
- $output: () => $output,
112
+ $brand: () => $brand,
341
113
  $input: () => $input,
342
- $brand: () => $brand
343
- });
344
-
114
+ $output: () => $output,
115
+ NEVER: () => NEVER,
116
+ TimePrecision: () => TimePrecision,
117
+ ZodAny: () => ZodAny,
118
+ ZodArray: () => ZodArray,
119
+ ZodBase64: () => ZodBase64,
120
+ ZodBase64URL: () => ZodBase64URL,
121
+ ZodBigInt: () => ZodBigInt,
122
+ ZodBigIntFormat: () => ZodBigIntFormat,
123
+ ZodBoolean: () => ZodBoolean,
124
+ ZodCIDRv4: () => ZodCIDRv4,
125
+ ZodCIDRv6: () => ZodCIDRv6,
126
+ ZodCUID: () => ZodCUID,
127
+ ZodCUID2: () => ZodCUID2,
128
+ ZodCatch: () => ZodCatch,
129
+ ZodCodec: () => ZodCodec,
130
+ ZodCompileAsyncError: () => ZodCompileAsyncError,
131
+ ZodCompileUnsupportedError: () => ZodCompileUnsupportedError,
132
+ ZodCreditCard: () => ZodCreditCard,
133
+ ZodCustom: () => ZodCustom,
134
+ ZodCustomStringFormat: () => ZodCustomStringFormat,
135
+ ZodDate: () => ZodDate,
136
+ ZodDefault: () => ZodDefault,
137
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
138
+ ZodE164: () => ZodE164,
139
+ ZodEmail: () => ZodEmail,
140
+ ZodEmoji: () => ZodEmoji,
141
+ ZodEnum: () => ZodEnum,
142
+ ZodError: () => ZodError,
143
+ ZodExactOptional: () => ZodExactOptional,
144
+ ZodFile: () => ZodFile,
145
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
146
+ ZodFunction: () => ZodFunction,
147
+ ZodGUID: () => ZodGUID,
148
+ ZodIPv4: () => ZodIPv4,
149
+ ZodIPv6: () => ZodIPv6,
150
+ ZodISODate: () => ZodISODate,
151
+ ZodISODateTime: () => ZodISODateTime,
152
+ ZodISODuration: () => ZodISODuration,
153
+ ZodISOTime: () => ZodISOTime,
154
+ ZodIntersection: () => ZodIntersection,
155
+ ZodIssueCode: () => ZodIssueCode,
156
+ ZodJWT: () => ZodJWT,
157
+ ZodKSUID: () => ZodKSUID,
158
+ ZodLazy: () => ZodLazy,
159
+ ZodLiteral: () => ZodLiteral,
160
+ ZodMAC: () => ZodMAC,
161
+ ZodMap: () => ZodMap,
162
+ ZodNaN: () => ZodNaN,
163
+ ZodNanoID: () => ZodNanoID,
164
+ ZodNever: () => ZodNever,
165
+ ZodNonOptional: () => ZodNonOptional,
166
+ ZodNull: () => ZodNull,
167
+ ZodNullable: () => ZodNullable,
168
+ ZodNumber: () => ZodNumber,
169
+ ZodNumberFormat: () => ZodNumberFormat,
170
+ ZodObject: () => ZodObject,
171
+ ZodOptional: () => ZodOptional,
172
+ ZodPipe: () => ZodPipe,
173
+ ZodPrefault: () => ZodPrefault,
174
+ ZodPreprocess: () => ZodPreprocess,
175
+ ZodPromise: () => ZodPromise,
176
+ ZodReadonly: () => ZodReadonly,
177
+ ZodRealError: () => ZodRealError,
178
+ ZodRecord: () => ZodRecord,
179
+ ZodSet: () => ZodSet,
180
+ ZodString: () => ZodString,
181
+ ZodStringFormat: () => ZodStringFormat,
182
+ ZodSuccess: () => ZodSuccess,
183
+ ZodSymbol: () => ZodSymbol,
184
+ ZodTemplateLiteral: () => ZodTemplateLiteral,
185
+ ZodTransform: () => ZodTransform,
186
+ ZodTuple: () => ZodTuple,
187
+ ZodType: () => ZodType,
188
+ ZodULID: () => ZodULID,
189
+ ZodURL: () => ZodURL,
190
+ ZodUUID: () => ZodUUID,
191
+ ZodUndefined: () => ZodUndefined,
192
+ ZodUnion: () => ZodUnion,
193
+ ZodUnknown: () => ZodUnknown,
194
+ ZodVoid: () => ZodVoid,
195
+ ZodXID: () => ZodXID,
196
+ ZodXor: () => ZodXor,
197
+ _ZodString: () => _ZodString,
198
+ _default: () => _default2,
199
+ _function: () => _function,
200
+ any: () => any,
201
+ array: () => array,
202
+ base64: () => base642,
203
+ base64url: () => base64url2,
204
+ bigint: () => bigint2,
205
+ boolean: () => boolean2,
206
+ catch: () => _catch2,
207
+ check: () => check,
208
+ cidrv4: () => cidrv42,
209
+ cidrv6: () => cidrv62,
210
+ clone: () => clone,
211
+ codec: () => codec,
212
+ coerce: () => exports_coerce,
213
+ compile: () => compile,
214
+ config: () => config,
215
+ core: () => exports_core2,
216
+ creditCard: () => creditCard2,
217
+ cuid: () => cuid3,
218
+ cuid2: () => cuid22,
219
+ custom: () => custom,
220
+ date: () => date2,
221
+ decode: () => decode2,
222
+ decodeAsync: () => decodeAsync2,
223
+ deepPartial: () => deepPartial,
224
+ describe: () => describe2,
225
+ discriminatedUnion: () => discriminatedUnion,
226
+ e164: () => e1642,
227
+ email: () => email2,
228
+ emoji: () => emoji2,
229
+ encode: () => encode2,
230
+ encodeAsync: () => encodeAsync2,
231
+ endsWith: () => _endsWith,
232
+ enum: () => _enum2,
233
+ exactOptional: () => exactOptional,
234
+ file: () => file,
235
+ flattenError: () => flattenError,
236
+ float32: () => float32,
237
+ float64: () => float64,
238
+ formatError: () => formatError,
239
+ fromJSONSchema: () => fromJSONSchema,
240
+ function: () => _function,
241
+ getDiscriminatedOption: () => getDiscriminatedOption,
242
+ getErrorMap: () => getErrorMap,
243
+ globalRegistry: () => globalRegistry,
244
+ gt: () => _gt,
245
+ gte: () => _gte,
246
+ guid: () => guid2,
247
+ hash: () => hash,
248
+ hex: () => hex2,
249
+ hostname: () => hostname2,
250
+ httpUrl: () => httpUrl,
251
+ includes: () => _includes,
252
+ input: () => input,
253
+ instanceof: () => _instanceof,
254
+ int: () => int,
255
+ int32: () => int32,
256
+ int64: () => int64,
257
+ intersection: () => intersection,
258
+ invertCodec: () => invertCodec,
259
+ ipv4: () => ipv42,
260
+ ipv6: () => ipv62,
261
+ iso: () => exports_iso,
262
+ json: () => json,
263
+ jwt: () => jwt,
264
+ keyof: () => keyof,
265
+ ksuid: () => ksuid2,
266
+ lazy: () => lazy,
267
+ length: () => _length,
268
+ literal: () => literal,
269
+ locales: () => exports_locales,
270
+ looseObject: () => looseObject,
271
+ looseRecord: () => looseRecord,
272
+ lowercase: () => _lowercase,
273
+ lt: () => _lt,
274
+ lte: () => _lte,
275
+ mac: () => mac2,
276
+ map: () => map,
277
+ maxLength: () => _maxLength,
278
+ maxSize: () => _maxSize,
279
+ memoizer: () => memoizer,
280
+ meta: () => meta2,
281
+ mime: () => _mime,
282
+ minLength: () => _minLength,
283
+ minSize: () => _minSize,
284
+ multipleOf: () => _multipleOf,
285
+ nan: () => nan,
286
+ nanoid: () => nanoid2,
287
+ nativeEnum: () => nativeEnum,
288
+ negative: () => _negative,
289
+ never: () => never,
290
+ nonnegative: () => _nonnegative,
291
+ nonoptional: () => nonoptional,
292
+ nonpositive: () => _nonpositive,
293
+ normalize: () => _normalize,
294
+ null: () => _null3,
295
+ nullable: () => nullable,
296
+ nullish: () => nullish2,
297
+ number: () => number2,
298
+ object: () => object,
299
+ optional: () => optional,
300
+ output: () => output,
301
+ overwrite: () => _overwrite,
302
+ parse: () => parse3,
303
+ parseAsync: () => parseAsync2,
304
+ partialRecord: () => partialRecord,
305
+ pipe: () => pipe,
306
+ positive: () => _positive,
307
+ prefault: () => prefault,
308
+ preprocess: () => preprocess,
309
+ prettifyError: () => prettifyError,
310
+ promise: () => promise,
311
+ properties: () => _properties,
312
+ property: () => _property,
313
+ readonly: () => readonly,
314
+ record: () => record,
315
+ refine: () => refine,
316
+ regex: () => _regex,
317
+ regexes: () => exports_regexes,
318
+ registry: () => registry,
319
+ safeDecode: () => safeDecode2,
320
+ safeDecodeAsync: () => safeDecodeAsync2,
321
+ safeEncode: () => safeEncode2,
322
+ safeEncodeAsync: () => safeEncodeAsync2,
323
+ safeParse: () => safeParse2,
324
+ safeParseAsync: () => safeParseAsync2,
325
+ set: () => set,
326
+ setErrorMap: () => setErrorMap,
327
+ size: () => _size,
328
+ slugify: () => _slugify,
329
+ startsWith: () => _startsWith,
330
+ strictObject: () => strictObject,
331
+ string: () => string2,
332
+ stringFormat: () => stringFormat,
333
+ stringbool: () => stringbool,
334
+ success: () => success,
335
+ superRefine: () => superRefine,
336
+ symbol: () => symbol,
337
+ templateLiteral: () => templateLiteral,
338
+ toJSONSchema: () => toJSONSchema,
339
+ toLowerCase: () => _toLowerCase,
340
+ toUpperCase: () => _toUpperCase,
341
+ toZod: () => toZod,
342
+ transform: () => transform,
343
+ treeifyError: () => treeifyError,
344
+ trim: () => _trim,
345
+ tuple: () => tuple,
346
+ uint32: () => uint32,
347
+ uint64: () => uint64,
348
+ ulid: () => ulid2,
349
+ undefined: () => _undefined3,
350
+ union: () => union,
351
+ unknown: () => unknown,
352
+ uppercase: () => _uppercase,
353
+ url: () => url,
354
+ util: () => exports_util,
355
+ uuid: () => uuid2,
356
+ uuidv4: () => uuidv4,
357
+ uuidv6: () => uuidv6,
358
+ uuidv7: () => uuidv7,
359
+ validate: () => validate,
360
+ validateAsync: () => validateAsync,
361
+ void: () => _void2,
362
+ xid: () => xid2,
363
+ xor: () => xor
364
+ });
365
+
345
366
  // node_modules/zod/v4/core/index.js
346
367
  var exports_core2 = {};
347
368
  __export(exports_core2, {
348
- version: () => version,
349
- validateAsync: () => validateAsync,
350
- validate: () => validate,
351
- util: () => exports_util,
352
- urlProtocolOk: () => urlProtocolOk,
353
- urlHostnameOk: () => urlHostnameOk,
354
- treeifyError: () => treeifyError,
355
- toZod: () => toZod,
356
- toJSONSchema: () => toJSONSchema,
357
- toDotPath: () => toDotPath,
358
- stripTabAndNewline: () => stripTabAndNewline,
359
- standardProps: () => standardProps,
360
- safeParseAsync: () => safeParseAsync,
361
- safeParse: () => safeParse,
362
- safeEncodeAsync: () => safeEncodeAsync,
363
- safeEncode: () => safeEncode,
364
- safeDecodeAsync: () => safeDecodeAsync,
365
- safeDecode: () => safeDecode,
366
- registry: () => registry,
367
- regexes: () => exports_regexes,
368
- process: () => process2,
369
- prettifyError: () => prettifyError,
370
- parseURLObject: () => parseURLObject,
371
- parseAsync: () => parseAsync,
372
- parse: () => parse,
373
- meta: () => meta,
374
- mergeValues: () => mergeValues,
375
- memoizer: () => memoizer,
376
- locales: () => exports_locales,
377
- isValidJWT: () => isValidJWT,
378
- isValidIPv6: () => isValidIPv6,
379
- isValidCreditCard: () => isValidCreditCard,
380
- isValidCIDRv6: () => isValidCIDRv6,
381
- isValidBase64URL: () => isValidBase64URL,
382
- isValidBase64: () => isValidBase64,
383
- isRecursiveSchema: () => isRecursiveSchema,
384
- isBackEdge: () => isBackEdge,
385
- initializeContext: () => initializeContext,
386
- handleUnrepresentable: () => handleUnrepresentable,
387
- globalRegistry: () => globalRegistry,
388
- globalConfig: () => globalConfig,
389
- getDiscriminatedOption: () => getDiscriminatedOption,
390
- formatError: () => formatError,
391
- flattenError: () => flattenError,
392
- finalize: () => finalize,
393
- extractDefs: () => extractDefs,
394
- encodeAsync: () => encodeAsync,
395
- encode: () => encode,
396
- describe: () => describe,
397
- decodeAsync: () => decodeAsync,
398
- decode: () => decode,
399
- createToJSONSchemaMethod: () => createToJSONSchemaMethod,
400
- createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
401
- config: () => config,
402
- compileFn: () => compileFn,
403
- compile: () => compile,
404
- clone: () => clone,
405
- _xor: () => _xor,
406
- _xid: () => _xid,
407
- _void: () => _void,
408
- _uuidv7: () => _uuidv7,
409
- _uuidv6: () => _uuidv6,
410
- _uuidv4: () => _uuidv4,
411
- _uuid: () => _uuid,
412
- _url: () => _url,
413
- _uppercase: () => _uppercase,
414
- _unknown: () => _unknown,
415
- _union: () => _union,
416
- _undefined: () => _undefined2,
417
- _ulid: () => _ulid,
418
- _uint64: () => _uint64,
419
- _uint32: () => _uint32,
420
- _tuple: () => _tuple,
421
- _trim: () => _trim,
422
- _transform: () => _transform,
423
- _toUpperCase: () => _toUpperCase,
424
- _toLowerCase: () => _toLowerCase,
425
- _templateLiteral: () => _templateLiteral,
426
- _symbol: () => _symbol,
427
- _superRefine: () => _superRefine,
428
- _success: () => _success,
429
- _stringbool: () => _stringbool,
430
- _stringFormat: () => _stringFormat,
431
- _string: () => _string,
432
- _startsWith: () => _startsWith,
433
- _slugify: () => _slugify,
434
- _size: () => _size,
435
- _set: () => _set,
436
- _safeParseAsync: () => _safeParseAsync,
437
- _safeParse: () => _safeParse,
438
- _safeEncodeAsync: () => _safeEncodeAsync,
439
- _safeEncode: () => _safeEncode,
440
- _safeDecodeAsync: () => _safeDecodeAsync,
441
- _safeDecode: () => _safeDecode,
442
- _regex: () => _regex,
443
- _refine: () => _refine,
444
- _record: () => _record,
445
- _readonly: () => _readonly,
446
- _property: () => _property,
447
- _properties: () => _properties,
448
- _promise: () => _promise,
449
- _positive: () => _positive,
450
- _pipe: () => _pipe,
451
- _parseAsync: () => _parseAsync,
452
- _parse: () => _parse,
453
- _overwrite: () => _overwrite,
454
- _optional: () => _optional,
455
- _number: () => _number,
456
- _nullable: () => _nullable,
457
- _null: () => _null2,
458
- _normalize: () => _normalize,
459
- _nonpositive: () => _nonpositive,
460
- _nonoptional: () => _nonoptional,
461
- _nonnegative: () => _nonnegative,
462
- _never: () => _never,
463
- _negative: () => _negative,
464
- _nativeEnum: () => _nativeEnum,
465
- _nanoid: () => _nanoid,
466
- _nan: () => _nan,
467
- _multipleOf: () => _multipleOf,
468
- _minSize: () => _minSize,
469
- _minLength: () => _minLength,
470
- _min: () => _gte,
471
- _mime: () => _mime,
472
- _maxSize: () => _maxSize,
473
- _maxLength: () => _maxLength,
474
- _max: () => _lte,
475
- _map: () => _map,
476
- _mac: () => _mac,
477
- _lte: () => _lte,
478
- _lt: () => _lt,
479
- _lowercase: () => _lowercase,
480
- _literal: () => _literal,
481
- _length: () => _length,
482
- _lazy: () => _lazy,
483
- _ksuid: () => _ksuid,
484
- _jwt: () => _jwt,
485
- _isoTime: () => _isoTime,
486
- _isoDuration: () => _isoDuration,
487
- _isoDateTime: () => _isoDateTime,
488
- _isoDate: () => _isoDate,
489
- _ipv6: () => _ipv6,
490
- _ipv4: () => _ipv4,
491
- _intersection: () => _intersection,
492
- _int64: () => _int64,
493
- _int32: () => _int32,
494
- _int: () => _int,
495
- _includes: () => _includes,
496
- _guid: () => _guid,
497
- _gte: () => _gte,
498
- _gt: () => _gt,
499
- _float64: () => _float64,
500
- _float32: () => _float32,
501
- _file: () => _file,
502
- _enum: () => _enum,
503
- _endsWith: () => _endsWith,
504
- _encodeAsync: () => _encodeAsync,
505
- _encode: () => _encode,
506
- _emoji: () => _emoji2,
507
- _email: () => _email,
508
- _e164: () => _e164,
509
- _discriminatedUnion: () => _discriminatedUnion,
510
- _default: () => _default,
511
- _decodeAsync: () => _decodeAsync,
512
- _decode: () => _decode,
513
- _date: () => _date,
514
- _custom: () => _custom,
515
- _cuid2: () => _cuid2,
516
- _cuid: () => _cuid,
517
- _creditCard: () => _creditCard,
518
- _coercedString: () => _coercedString,
519
- _coercedNumber: () => _coercedNumber,
520
- _coercedDate: () => _coercedDate,
521
- _coercedBoolean: () => _coercedBoolean,
522
- _coercedBigint: () => _coercedBigint,
523
- _cidrv6: () => _cidrv6,
524
- _cidrv4: () => _cidrv4,
525
- _check: () => _check,
526
- _catch: () => _catch,
527
- _boolean: () => _boolean,
528
- _bigint: () => _bigint,
529
- _base64url: () => _base64url,
530
- _base64: () => _base64,
531
- _array: () => _array,
532
- _any: () => _any,
533
- ZodCompileUnsupportedError: () => ZodCompileUnsupportedError,
534
- ZodCompileAsyncError: () => ZodCompileAsyncError,
535
- URL_UNPARSEABLE: () => URL_UNPARSEABLE,
536
- URL_BAD_FORMAT: () => URL_BAD_FORMAT,
537
- TimePrecision: () => TimePrecision,
538
- NEVER: () => NEVER,
539
- JSONSchemaGenerator: () => JSONSchemaGenerator,
540
- JSONSchema: () => exports_json_schema,
541
- INVALID: () => INVALID,
542
- Doc: () => Doc,
543
- $output: () => $output,
544
- $input: () => $input,
545
- $constructor: () => $constructor,
546
- $brand: () => $brand,
547
- $ZodXor: () => $ZodXor,
548
- $ZodXID: () => $ZodXID,
549
- $ZodVoid: () => $ZodVoid,
550
- $ZodUnknown: () => $ZodUnknown,
551
- $ZodUnion: () => $ZodUnion,
552
- $ZodUndefined: () => $ZodUndefined,
553
- $ZodUUID: () => $ZodUUID,
554
- $ZodURL: () => $ZodURL,
555
- $ZodULID: () => $ZodULID,
556
- $ZodType: () => $ZodType,
557
- $ZodTuple: () => $ZodTuple,
558
- $ZodTransform: () => $ZodTransform,
559
- $ZodTemplateLiteral: () => $ZodTemplateLiteral,
560
- $ZodSymbol: () => $ZodSymbol,
561
- $ZodSuccess: () => $ZodSuccess,
562
- $ZodStringFormat: () => $ZodStringFormat,
563
- $ZodString: () => $ZodString,
564
- $ZodSet: () => $ZodSet,
565
- $ZodRegistry: () => $ZodRegistry,
566
- $ZodRecord: () => $ZodRecord,
567
- $ZodRealError: () => $ZodRealError,
568
- $ZodReadonly: () => $ZodReadonly,
569
- $ZodPromise: () => $ZodPromise,
570
- $ZodPreprocess: () => $ZodPreprocess,
571
- $ZodPrefault: () => $ZodPrefault,
572
- $ZodPipe: () => $ZodPipe,
573
- $ZodOptional: () => $ZodOptional,
574
- $ZodObjectJIT: () => $ZodObjectJIT,
575
- $ZodObject: () => $ZodObject,
576
- $ZodNumberFormat: () => $ZodNumberFormat,
577
- $ZodNumber: () => $ZodNumber,
578
- $ZodNullable: () => $ZodNullable,
579
- $ZodNull: () => $ZodNull,
580
- $ZodNonOptional: () => $ZodNonOptional,
581
- $ZodNever: () => $ZodNever,
582
- $ZodNanoID: () => $ZodNanoID,
583
- $ZodNaN: () => $ZodNaN,
584
- $ZodMap: () => $ZodMap,
585
- $ZodMAC: () => $ZodMAC,
586
- $ZodLiteral: () => $ZodLiteral,
587
- $ZodLazy: () => $ZodLazy,
588
- $ZodKSUID: () => $ZodKSUID,
589
- $ZodJWT: () => $ZodJWT,
590
- $ZodIntersection: () => $ZodIntersection,
591
- $ZodISOTime: () => $ZodISOTime,
592
- $ZodISODuration: () => $ZodISODuration,
593
- $ZodISODateTime: () => $ZodISODateTime,
594
- $ZodISODate: () => $ZodISODate,
595
- $ZodIPv6: () => $ZodIPv6,
596
- $ZodIPv4: () => $ZodIPv4,
597
- $ZodGUID: () => $ZodGUID,
598
- $ZodFunction: () => $ZodFunction,
599
- $ZodFile: () => $ZodFile,
600
- $ZodExactOptional: () => $ZodExactOptional,
601
- $ZodError: () => $ZodError,
602
- $ZodEnum: () => $ZodEnum,
603
- $ZodEncodeError: () => $ZodEncodeError,
604
- $ZodEmoji: () => $ZodEmoji,
605
- $ZodEmail: () => $ZodEmail,
606
- $ZodE164: () => $ZodE164,
607
- $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
608
- $ZodDefault: () => $ZodDefault,
609
- $ZodDate: () => $ZodDate,
610
- $ZodCyclicError: () => $ZodCyclicError,
611
- $ZodCustomStringFormat: () => $ZodCustomStringFormat,
612
- $ZodCustom: () => $ZodCustom,
613
- $ZodCreditCard: () => $ZodCreditCard,
614
- $ZodCodec: () => $ZodCodec,
615
- $ZodCheckUpperCase: () => $ZodCheckUpperCase,
616
- $ZodCheckStringFormat: () => $ZodCheckStringFormat,
617
- $ZodCheckStartsWith: () => $ZodCheckStartsWith,
618
- $ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
619
- $ZodCheckRegex: () => $ZodCheckRegex,
620
- $ZodCheckProperty: () => $ZodCheckProperty,
621
- $ZodCheckOverwrite: () => $ZodCheckOverwrite,
622
- $ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
623
- $ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
624
- $ZodCheckMinSize: () => $ZodCheckMinSize,
625
- $ZodCheckMinLength: () => $ZodCheckMinLength,
626
- $ZodCheckMimeType: () => $ZodCheckMimeType,
627
- $ZodCheckMaxSize: () => $ZodCheckMaxSize,
628
- $ZodCheckMaxLength: () => $ZodCheckMaxLength,
629
- $ZodCheckLowerCase: () => $ZodCheckLowerCase,
630
- $ZodCheckLessThan: () => $ZodCheckLessThan,
631
- $ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
632
- $ZodCheckIncludes: () => $ZodCheckIncludes,
633
- $ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
634
- $ZodCheckEndsWith: () => $ZodCheckEndsWith,
635
- $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
636
- $ZodCheck: () => $ZodCheck,
637
- $ZodCatch: () => $ZodCatch,
638
- $ZodCUID2: () => $ZodCUID2,
639
- $ZodCUID: () => $ZodCUID,
640
- $ZodCIDRv6: () => $ZodCIDRv6,
641
- $ZodCIDRv4: () => $ZodCIDRv4,
642
- $ZodBoolean: () => $ZodBoolean,
643
- $ZodBigIntFormat: () => $ZodBigIntFormat,
644
- $ZodBigInt: () => $ZodBigInt,
645
- $ZodBase64URL: () => $ZodBase64URL,
646
- $ZodBase64: () => $ZodBase64,
647
- $ZodAsyncError: () => $ZodAsyncError,
369
+ $ZodAny: () => $ZodAny,
648
370
  $ZodArray: () => $ZodArray,
649
- $ZodAny: () => $ZodAny
371
+ $ZodAsyncError: () => $ZodAsyncError,
372
+ $ZodBase64: () => $ZodBase64,
373
+ $ZodBase64URL: () => $ZodBase64URL,
374
+ $ZodBigInt: () => $ZodBigInt,
375
+ $ZodBigIntFormat: () => $ZodBigIntFormat,
376
+ $ZodBoolean: () => $ZodBoolean,
377
+ $ZodCIDRv4: () => $ZodCIDRv4,
378
+ $ZodCIDRv6: () => $ZodCIDRv6,
379
+ $ZodCUID: () => $ZodCUID,
380
+ $ZodCUID2: () => $ZodCUID2,
381
+ $ZodCatch: () => $ZodCatch,
382
+ $ZodCheck: () => $ZodCheck,
383
+ $ZodCheckBigIntFormat: () => $ZodCheckBigIntFormat,
384
+ $ZodCheckEndsWith: () => $ZodCheckEndsWith,
385
+ $ZodCheckGreaterThan: () => $ZodCheckGreaterThan,
386
+ $ZodCheckIncludes: () => $ZodCheckIncludes,
387
+ $ZodCheckLengthEquals: () => $ZodCheckLengthEquals,
388
+ $ZodCheckLessThan: () => $ZodCheckLessThan,
389
+ $ZodCheckLowerCase: () => $ZodCheckLowerCase,
390
+ $ZodCheckMaxLength: () => $ZodCheckMaxLength,
391
+ $ZodCheckMaxSize: () => $ZodCheckMaxSize,
392
+ $ZodCheckMimeType: () => $ZodCheckMimeType,
393
+ $ZodCheckMinLength: () => $ZodCheckMinLength,
394
+ $ZodCheckMinSize: () => $ZodCheckMinSize,
395
+ $ZodCheckMultipleOf: () => $ZodCheckMultipleOf,
396
+ $ZodCheckNumberFormat: () => $ZodCheckNumberFormat,
397
+ $ZodCheckOverwrite: () => $ZodCheckOverwrite,
398
+ $ZodCheckProperty: () => $ZodCheckProperty,
399
+ $ZodCheckRegex: () => $ZodCheckRegex,
400
+ $ZodCheckSizeEquals: () => $ZodCheckSizeEquals,
401
+ $ZodCheckStartsWith: () => $ZodCheckStartsWith,
402
+ $ZodCheckStringFormat: () => $ZodCheckStringFormat,
403
+ $ZodCheckUpperCase: () => $ZodCheckUpperCase,
404
+ $ZodCodec: () => $ZodCodec,
405
+ $ZodCreditCard: () => $ZodCreditCard,
406
+ $ZodCustom: () => $ZodCustom,
407
+ $ZodCustomStringFormat: () => $ZodCustomStringFormat,
408
+ $ZodCyclicError: () => $ZodCyclicError,
409
+ $ZodDate: () => $ZodDate,
410
+ $ZodDefault: () => $ZodDefault,
411
+ $ZodDiscriminatedUnion: () => $ZodDiscriminatedUnion,
412
+ $ZodE164: () => $ZodE164,
413
+ $ZodEmail: () => $ZodEmail,
414
+ $ZodEmoji: () => $ZodEmoji,
415
+ $ZodEncodeError: () => $ZodEncodeError,
416
+ $ZodEnum: () => $ZodEnum,
417
+ $ZodError: () => $ZodError,
418
+ $ZodExactOptional: () => $ZodExactOptional,
419
+ $ZodFile: () => $ZodFile,
420
+ $ZodFunction: () => $ZodFunction,
421
+ $ZodGUID: () => $ZodGUID,
422
+ $ZodIPv4: () => $ZodIPv4,
423
+ $ZodIPv6: () => $ZodIPv6,
424
+ $ZodISODate: () => $ZodISODate,
425
+ $ZodISODateTime: () => $ZodISODateTime,
426
+ $ZodISODuration: () => $ZodISODuration,
427
+ $ZodISOTime: () => $ZodISOTime,
428
+ $ZodIntersection: () => $ZodIntersection,
429
+ $ZodJWT: () => $ZodJWT,
430
+ $ZodKSUID: () => $ZodKSUID,
431
+ $ZodLazy: () => $ZodLazy,
432
+ $ZodLiteral: () => $ZodLiteral,
433
+ $ZodMAC: () => $ZodMAC,
434
+ $ZodMap: () => $ZodMap,
435
+ $ZodNaN: () => $ZodNaN,
436
+ $ZodNanoID: () => $ZodNanoID,
437
+ $ZodNever: () => $ZodNever,
438
+ $ZodNonOptional: () => $ZodNonOptional,
439
+ $ZodNull: () => $ZodNull,
440
+ $ZodNullable: () => $ZodNullable,
441
+ $ZodNumber: () => $ZodNumber,
442
+ $ZodNumberFormat: () => $ZodNumberFormat,
443
+ $ZodObject: () => $ZodObject,
444
+ $ZodObjectJIT: () => $ZodObjectJIT,
445
+ $ZodOptional: () => $ZodOptional,
446
+ $ZodPipe: () => $ZodPipe,
447
+ $ZodPrefault: () => $ZodPrefault,
448
+ $ZodPreprocess: () => $ZodPreprocess,
449
+ $ZodPromise: () => $ZodPromise,
450
+ $ZodReadonly: () => $ZodReadonly,
451
+ $ZodRealError: () => $ZodRealError,
452
+ $ZodRecord: () => $ZodRecord,
453
+ $ZodRegistry: () => $ZodRegistry,
454
+ $ZodSet: () => $ZodSet,
455
+ $ZodString: () => $ZodString,
456
+ $ZodStringFormat: () => $ZodStringFormat,
457
+ $ZodSuccess: () => $ZodSuccess,
458
+ $ZodSymbol: () => $ZodSymbol,
459
+ $ZodTemplateLiteral: () => $ZodTemplateLiteral,
460
+ $ZodTransform: () => $ZodTransform,
461
+ $ZodTuple: () => $ZodTuple,
462
+ $ZodType: () => $ZodType,
463
+ $ZodULID: () => $ZodULID,
464
+ $ZodURL: () => $ZodURL,
465
+ $ZodUUID: () => $ZodUUID,
466
+ $ZodUndefined: () => $ZodUndefined,
467
+ $ZodUnion: () => $ZodUnion,
468
+ $ZodUnknown: () => $ZodUnknown,
469
+ $ZodVoid: () => $ZodVoid,
470
+ $ZodXID: () => $ZodXID,
471
+ $ZodXor: () => $ZodXor,
472
+ $brand: () => $brand,
473
+ $constructor: () => $constructor,
474
+ $input: () => $input,
475
+ $output: () => $output,
476
+ Doc: () => Doc,
477
+ INVALID: () => INVALID,
478
+ JSONSchema: () => exports_json_schema,
479
+ JSONSchemaGenerator: () => JSONSchemaGenerator,
480
+ NEVER: () => NEVER,
481
+ TimePrecision: () => TimePrecision,
482
+ URL_BAD_FORMAT: () => URL_BAD_FORMAT,
483
+ URL_UNPARSEABLE: () => URL_UNPARSEABLE,
484
+ ZodCompileAsyncError: () => ZodCompileAsyncError,
485
+ ZodCompileUnsupportedError: () => ZodCompileUnsupportedError,
486
+ _any: () => _any,
487
+ _array: () => _array,
488
+ _base64: () => _base64,
489
+ _base64url: () => _base64url,
490
+ _bigint: () => _bigint,
491
+ _boolean: () => _boolean,
492
+ _catch: () => _catch,
493
+ _check: () => _check,
494
+ _cidrv4: () => _cidrv4,
495
+ _cidrv6: () => _cidrv6,
496
+ _coercedBigint: () => _coercedBigint,
497
+ _coercedBoolean: () => _coercedBoolean,
498
+ _coercedDate: () => _coercedDate,
499
+ _coercedNumber: () => _coercedNumber,
500
+ _coercedString: () => _coercedString,
501
+ _creditCard: () => _creditCard,
502
+ _cuid: () => _cuid,
503
+ _cuid2: () => _cuid2,
504
+ _custom: () => _custom,
505
+ _date: () => _date,
506
+ _decode: () => _decode,
507
+ _decodeAsync: () => _decodeAsync,
508
+ _default: () => _default,
509
+ _discriminatedUnion: () => _discriminatedUnion,
510
+ _e164: () => _e164,
511
+ _email: () => _email,
512
+ _emoji: () => _emoji2,
513
+ _encode: () => _encode,
514
+ _encodeAsync: () => _encodeAsync,
515
+ _endsWith: () => _endsWith,
516
+ _enum: () => _enum,
517
+ _file: () => _file,
518
+ _float32: () => _float32,
519
+ _float64: () => _float64,
520
+ _gt: () => _gt,
521
+ _gte: () => _gte,
522
+ _guid: () => _guid,
523
+ _includes: () => _includes,
524
+ _int: () => _int,
525
+ _int32: () => _int32,
526
+ _int64: () => _int64,
527
+ _intersection: () => _intersection,
528
+ _ipv4: () => _ipv4,
529
+ _ipv6: () => _ipv6,
530
+ _isoDate: () => _isoDate,
531
+ _isoDateTime: () => _isoDateTime,
532
+ _isoDuration: () => _isoDuration,
533
+ _isoTime: () => _isoTime,
534
+ _jwt: () => _jwt,
535
+ _ksuid: () => _ksuid,
536
+ _lazy: () => _lazy,
537
+ _length: () => _length,
538
+ _literal: () => _literal,
539
+ _lowercase: () => _lowercase,
540
+ _lt: () => _lt,
541
+ _lte: () => _lte,
542
+ _mac: () => _mac,
543
+ _map: () => _map,
544
+ _max: () => _lte,
545
+ _maxLength: () => _maxLength,
546
+ _maxSize: () => _maxSize,
547
+ _mime: () => _mime,
548
+ _min: () => _gte,
549
+ _minLength: () => _minLength,
550
+ _minSize: () => _minSize,
551
+ _multipleOf: () => _multipleOf,
552
+ _nan: () => _nan,
553
+ _nanoid: () => _nanoid,
554
+ _nativeEnum: () => _nativeEnum,
555
+ _negative: () => _negative,
556
+ _never: () => _never,
557
+ _nonnegative: () => _nonnegative,
558
+ _nonoptional: () => _nonoptional,
559
+ _nonpositive: () => _nonpositive,
560
+ _normalize: () => _normalize,
561
+ _null: () => _null2,
562
+ _nullable: () => _nullable,
563
+ _number: () => _number,
564
+ _optional: () => _optional,
565
+ _overwrite: () => _overwrite,
566
+ _parse: () => _parse,
567
+ _parseAsync: () => _parseAsync,
568
+ _pipe: () => _pipe,
569
+ _positive: () => _positive,
570
+ _promise: () => _promise,
571
+ _properties: () => _properties,
572
+ _property: () => _property,
573
+ _readonly: () => _readonly,
574
+ _record: () => _record,
575
+ _refine: () => _refine,
576
+ _regex: () => _regex,
577
+ _safeDecode: () => _safeDecode,
578
+ _safeDecodeAsync: () => _safeDecodeAsync,
579
+ _safeEncode: () => _safeEncode,
580
+ _safeEncodeAsync: () => _safeEncodeAsync,
581
+ _safeParse: () => _safeParse,
582
+ _safeParseAsync: () => _safeParseAsync,
583
+ _set: () => _set,
584
+ _size: () => _size,
585
+ _slugify: () => _slugify,
586
+ _startsWith: () => _startsWith,
587
+ _string: () => _string,
588
+ _stringFormat: () => _stringFormat,
589
+ _stringbool: () => _stringbool,
590
+ _success: () => _success,
591
+ _superRefine: () => _superRefine,
592
+ _symbol: () => _symbol,
593
+ _templateLiteral: () => _templateLiteral,
594
+ _toLowerCase: () => _toLowerCase,
595
+ _toUpperCase: () => _toUpperCase,
596
+ _transform: () => _transform,
597
+ _trim: () => _trim,
598
+ _tuple: () => _tuple,
599
+ _uint32: () => _uint32,
600
+ _uint64: () => _uint64,
601
+ _ulid: () => _ulid,
602
+ _undefined: () => _undefined2,
603
+ _union: () => _union,
604
+ _unknown: () => _unknown,
605
+ _uppercase: () => _uppercase,
606
+ _url: () => _url,
607
+ _uuid: () => _uuid,
608
+ _uuidv4: () => _uuidv4,
609
+ _uuidv6: () => _uuidv6,
610
+ _uuidv7: () => _uuidv7,
611
+ _void: () => _void,
612
+ _xid: () => _xid,
613
+ _xor: () => _xor,
614
+ clone: () => clone,
615
+ compile: () => compile,
616
+ compileFn: () => compileFn,
617
+ config: () => config,
618
+ createStandardJSONSchemaMethod: () => createStandardJSONSchemaMethod,
619
+ createToJSONSchemaMethod: () => createToJSONSchemaMethod,
620
+ decode: () => decode,
621
+ decodeAsync: () => decodeAsync,
622
+ describe: () => describe,
623
+ encode: () => encode,
624
+ encodeAsync: () => encodeAsync,
625
+ extractDefs: () => extractDefs,
626
+ finalize: () => finalize,
627
+ flattenError: () => flattenError,
628
+ formatError: () => formatError,
629
+ getDiscriminatedOption: () => getDiscriminatedOption,
630
+ globalConfig: () => globalConfig,
631
+ globalRegistry: () => globalRegistry,
632
+ handleUnrepresentable: () => handleUnrepresentable,
633
+ initializeContext: () => initializeContext,
634
+ isBackEdge: () => isBackEdge,
635
+ isRecursiveSchema: () => isRecursiveSchema,
636
+ isValidBase64: () => isValidBase64,
637
+ isValidBase64URL: () => isValidBase64URL,
638
+ isValidCIDRv6: () => isValidCIDRv6,
639
+ isValidCreditCard: () => isValidCreditCard,
640
+ isValidIPv6: () => isValidIPv6,
641
+ isValidJWT: () => isValidJWT,
642
+ locales: () => exports_locales,
643
+ memoizer: () => memoizer,
644
+ mergeValues: () => mergeValues,
645
+ meta: () => meta,
646
+ parse: () => parse,
647
+ parseAsync: () => parseAsync,
648
+ parseURLObject: () => parseURLObject,
649
+ prettifyError: () => prettifyError,
650
+ process: () => process2,
651
+ regexes: () => exports_regexes,
652
+ registry: () => registry,
653
+ safeDecode: () => safeDecode,
654
+ safeDecodeAsync: () => safeDecodeAsync,
655
+ safeEncode: () => safeEncode,
656
+ safeEncodeAsync: () => safeEncodeAsync,
657
+ safeParse: () => safeParse,
658
+ safeParseAsync: () => safeParseAsync,
659
+ standardProps: () => standardProps,
660
+ stripTabAndNewline: () => stripTabAndNewline,
661
+ toDotPath: () => toDotPath,
662
+ toJSONSchema: () => toJSONSchema,
663
+ toZod: () => toZod,
664
+ treeifyError: () => treeifyError,
665
+ urlHostnameOk: () => urlHostnameOk,
666
+ urlProtocolOk: () => urlProtocolOk,
667
+ util: () => exports_util,
668
+ validate: () => validate,
669
+ validateAsync: () => validateAsync,
670
+ version: () => version
650
671
  });
651
672
 
652
673
  // node_modules/zod/v4/core/util.js
653
674
  var exports_util = {};
654
675
  __export(exports_util, {
655
- unwrapMessage: () => unwrapMessage,
656
- uint8ArrayToHex: () => uint8ArrayToHex,
657
- uint8ArrayToBase64url: () => uint8ArrayToBase64url,
658
- uint8ArrayToBase64: () => uint8ArrayToBase64,
659
- toZod: () => toZod,
660
- stringifyPrimitive: () => stringifyPrimitive,
661
- slugify: () => slugify,
662
- shallowClone: () => shallowClone,
663
- safeExtend: () => safeExtend,
664
- required: () => required,
665
- randomString: () => randomString,
666
- propertyKeyTypes: () => propertyKeyTypes,
667
- promiseAllObject: () => promiseAllObject,
668
- primitiveTypes: () => primitiveTypes,
669
- prefixIssues: () => prefixIssues,
670
- pick: () => pick,
671
- partial: () => partial,
672
- parsedType: () => parsedType,
673
- own: () => own,
674
- optionalKeys: () => optionalKeys,
675
- omit: () => omit,
676
- objectClone: () => objectClone,
677
- numKeys: () => numKeys,
678
- nullish: () => nullish,
679
- normalizeParams: () => normalizeParams,
680
- mergeDefs: () => mergeDefs,
681
- merge: () => merge,
682
- members: () => members,
683
- jsonStringifyReplacer: () => jsonStringifyReplacer,
684
- joinValues: () => joinValues,
685
- issue: () => issue,
686
- isPlainObject: () => isPlainObject,
687
- isObject: () => isObject,
688
- installLazyProp: () => installLazyProp,
689
- hide: () => hide,
690
- hexToUint8Array: () => hexToUint8Array,
691
- getSizableOrigin: () => getSizableOrigin,
692
- getParsedType: () => getParsedType,
693
- getLengthableOrigin: () => getLengthableOrigin,
694
- getEnumValues: () => getEnumValues,
695
- getElementAtPath: () => getElementAtPath,
696
- floatSafeRemainder: () => floatSafeRemainder,
697
- finalizeIssue: () => finalizeIssue,
698
- extend: () => extend,
699
- explicitlyAborted: () => explicitlyAborted,
700
- escapeRegex: () => escapeRegex,
701
- esc: () => esc,
702
- defineLazyInternal: () => defineLazyInternal,
703
- defineLazy: () => defineLazy,
704
- createTransparentProxy: () => createTransparentProxy,
705
- constantCatch: () => constantCatch,
706
- codePointLength: () => codePointLength,
707
- cloneDef: () => cloneDef,
708
- clone: () => clone,
709
- cleanRegex: () => cleanRegex,
710
- cleanEnum: () => cleanEnum,
711
- captureStackTrace: () => captureStackTrace,
712
- cached: () => cached,
713
- base64urlToUint8Array: () => base64urlToUint8Array,
714
- base64ToUint8Array: () => base64ToUint8Array,
715
- attachSchema: () => attachSchema,
716
- assignProp: () => assignProp,
717
- assertNotEqual: () => assertNotEqual,
718
- assertNever: () => assertNever,
719
- assertIs: () => assertIs,
720
- assertEqual: () => assertEqual,
721
- assert: () => assert,
722
- allowsEval: () => allowsEval,
723
- aborted: () => aborted,
724
- NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
725
- Class: () => Class,
676
+ BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
726
677
  CONSTANT_CATCH: () => CONSTANT_CATCH,
727
- BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES
678
+ Class: () => Class,
679
+ NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
680
+ aborted: () => aborted,
681
+ allowsEval: () => allowsEval,
682
+ assert: () => assert,
683
+ assertEqual: () => assertEqual,
684
+ assertIs: () => assertIs,
685
+ assertNever: () => assertNever,
686
+ assertNotEqual: () => assertNotEqual,
687
+ assignProp: () => assignProp,
688
+ attachSchema: () => attachSchema,
689
+ base64ToUint8Array: () => base64ToUint8Array,
690
+ base64urlToUint8Array: () => base64urlToUint8Array,
691
+ cached: () => cached,
692
+ captureStackTrace: () => captureStackTrace,
693
+ cleanEnum: () => cleanEnum,
694
+ cleanRegex: () => cleanRegex,
695
+ clone: () => clone,
696
+ cloneDef: () => cloneDef,
697
+ codePointLength: () => codePointLength,
698
+ constantCatch: () => constantCatch,
699
+ createTransparentProxy: () => createTransparentProxy,
700
+ defineLazy: () => defineLazy,
701
+ defineLazyInternal: () => defineLazyInternal,
702
+ esc: () => esc,
703
+ escapeRegex: () => escapeRegex,
704
+ explicitlyAborted: () => explicitlyAborted,
705
+ extend: () => extend,
706
+ finalizeIssue: () => finalizeIssue,
707
+ floatSafeRemainder: () => floatSafeRemainder,
708
+ getElementAtPath: () => getElementAtPath,
709
+ getEnumValues: () => getEnumValues,
710
+ getLengthableOrigin: () => getLengthableOrigin,
711
+ getParsedType: () => getParsedType,
712
+ getSizableOrigin: () => getSizableOrigin,
713
+ hexToUint8Array: () => hexToUint8Array,
714
+ hide: () => hide,
715
+ installLazyProp: () => installLazyProp,
716
+ isObject: () => isObject,
717
+ isPlainObject: () => isPlainObject,
718
+ issue: () => issue,
719
+ joinValues: () => joinValues,
720
+ jsonStringifyReplacer: () => jsonStringifyReplacer,
721
+ members: () => members,
722
+ merge: () => merge,
723
+ mergeDefs: () => mergeDefs,
724
+ normalizeParams: () => normalizeParams,
725
+ nullish: () => nullish,
726
+ numKeys: () => numKeys,
727
+ objectClone: () => objectClone,
728
+ omit: () => omit,
729
+ optionalKeys: () => optionalKeys,
730
+ own: () => own,
731
+ parsedType: () => parsedType,
732
+ partial: () => partial,
733
+ pick: () => pick,
734
+ prefixIssues: () => prefixIssues,
735
+ primitiveTypes: () => primitiveTypes,
736
+ promiseAllObject: () => promiseAllObject,
737
+ propertyKeyTypes: () => propertyKeyTypes,
738
+ randomString: () => randomString,
739
+ required: () => required,
740
+ safeExtend: () => safeExtend,
741
+ shallowClone: () => shallowClone,
742
+ slugify: () => slugify,
743
+ stringifyPrimitive: () => stringifyPrimitive,
744
+ toZod: () => toZod,
745
+ uint8ArrayToBase64: () => uint8ArrayToBase64,
746
+ uint8ArrayToBase64url: () => uint8ArrayToBase64url,
747
+ uint8ArrayToHex: () => uint8ArrayToHex,
748
+ unwrapMessage: () => unwrapMessage
728
749
  });
729
750
  function assertEqual(val) {
730
751
  return val;
@@ -1948,67 +1969,67 @@ var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
1948
1969
  // node_modules/zod/v4/core/regexes.js
1949
1970
  var exports_regexes = {};
1950
1971
  __export(exports_regexes, {
1951
- xid: () => xid,
1952
- uuid7: () => uuid7,
1953
- uuid6: () => uuid6,
1954
- uuid4: () => uuid4,
1955
- uuid: () => uuid,
1956
- uppercase: () => uppercase,
1957
- unicodeEmail: () => unicodeEmail,
1958
- undefined: () => _undefined,
1959
- ulid: () => ulid,
1960
- time: () => time,
1961
- string: () => string,
1962
- sha512_hex: () => sha512_hex,
1963
- sha512_base64url: () => sha512_base64url,
1964
- sha512_base64: () => sha512_base64,
1965
- sha384_hex: () => sha384_hex,
1966
- sha384_base64url: () => sha384_base64url,
1967
- sha384_base64: () => sha384_base64,
1968
- sha256_hex: () => sha256_hex,
1969
- sha256_base64url: () => sha256_base64url,
1970
- sha256_base64: () => sha256_base64,
1971
- sha1_hex: () => sha1_hex,
1972
- sha1_base64url: () => sha1_base64url,
1973
- sha1_base64: () => sha1_base64,
1974
- rfc5322Email: () => rfc5322Email,
1975
- number: () => number,
1976
- null: () => _null,
1977
- nanoidOfLength: () => nanoidOfLength,
1978
- nanoid: () => nanoid,
1979
- md5_hex: () => md5_hex,
1980
- md5_base64url: () => md5_base64url,
1981
- md5_base64: () => md5_base64,
1982
- mac: () => mac,
1983
- lowercase: () => lowercase,
1984
- ksuid: () => ksuid,
1985
- ipv6: () => ipv6,
1986
- ipv4: () => ipv4,
1987
- integer: () => integer,
1988
- idnEmail: () => idnEmail,
1989
- httpProtocol: () => httpProtocol,
1990
- html5Email: () => html5Email,
1991
- hostname: () => hostname,
1992
- hex: () => hex,
1993
- guid: () => guid,
1994
- extendedDuration: () => extendedDuration,
1995
- emoji: () => emoji,
1996
- email: () => email,
1997
- e164: () => e164,
1998
- duration: () => duration,
1999
- domain: () => domain,
2000
- datetime: () => datetime,
2001
- date: () => date,
2002
- cuid2: () => cuid2,
2003
- cuid: () => cuid,
2004
- creditCard: () => creditCard,
2005
- cidrv6: () => cidrv6,
2006
- cidrv4: () => cidrv4,
2007
- browserEmail: () => browserEmail,
2008
- boolean: () => boolean,
2009
- bigint: () => bigint,
1972
+ base64: () => base64,
2010
1973
  base64url: () => base64url,
2011
- base64: () => base64
1974
+ bigint: () => bigint,
1975
+ boolean: () => boolean,
1976
+ browserEmail: () => browserEmail,
1977
+ cidrv4: () => cidrv4,
1978
+ cidrv6: () => cidrv6,
1979
+ creditCard: () => creditCard,
1980
+ cuid: () => cuid,
1981
+ cuid2: () => cuid2,
1982
+ date: () => date,
1983
+ datetime: () => datetime,
1984
+ domain: () => domain,
1985
+ duration: () => duration,
1986
+ e164: () => e164,
1987
+ email: () => email,
1988
+ emoji: () => emoji,
1989
+ extendedDuration: () => extendedDuration,
1990
+ guid: () => guid,
1991
+ hex: () => hex,
1992
+ hostname: () => hostname,
1993
+ html5Email: () => html5Email,
1994
+ httpProtocol: () => httpProtocol,
1995
+ idnEmail: () => idnEmail,
1996
+ integer: () => integer,
1997
+ ipv4: () => ipv4,
1998
+ ipv6: () => ipv6,
1999
+ ksuid: () => ksuid,
2000
+ lowercase: () => lowercase,
2001
+ mac: () => mac,
2002
+ md5_base64: () => md5_base64,
2003
+ md5_base64url: () => md5_base64url,
2004
+ md5_hex: () => md5_hex,
2005
+ nanoid: () => nanoid,
2006
+ nanoidOfLength: () => nanoidOfLength,
2007
+ null: () => _null,
2008
+ number: () => number,
2009
+ rfc5322Email: () => rfc5322Email,
2010
+ sha1_base64: () => sha1_base64,
2011
+ sha1_base64url: () => sha1_base64url,
2012
+ sha1_hex: () => sha1_hex,
2013
+ sha256_base64: () => sha256_base64,
2014
+ sha256_base64url: () => sha256_base64url,
2015
+ sha256_hex: () => sha256_hex,
2016
+ sha384_base64: () => sha384_base64,
2017
+ sha384_base64url: () => sha384_base64url,
2018
+ sha384_hex: () => sha384_hex,
2019
+ sha512_base64: () => sha512_base64,
2020
+ sha512_base64url: () => sha512_base64url,
2021
+ sha512_hex: () => sha512_hex,
2022
+ string: () => string,
2023
+ time: () => time,
2024
+ ulid: () => ulid,
2025
+ undefined: () => _undefined,
2026
+ unicodeEmail: () => unicodeEmail,
2027
+ uppercase: () => uppercase,
2028
+ uuid: () => uuid,
2029
+ uuid4: () => uuid4,
2030
+ uuid6: () => uuid6,
2031
+ uuid7: () => uuid7,
2032
+ xid: () => xid
2012
2033
  });
2013
2034
  var cuid = /^[cC][0-9a-z]{6,}$/;
2014
2035
  var cuid2 = /^[0-9a-z]+$/;
@@ -5188,68 +5209,68 @@ function isBackEdge(ctx, value) {
5188
5209
  // node_modules/zod/v4/locales/index.js
5189
5210
  var exports_locales = {};
5190
5211
  __export(exports_locales, {
5191
- zhTW: () => zh_TW_default,
5192
- zhCN: () => zh_CN_default,
5193
- yo: () => yo_default,
5194
- vi: () => vi_default,
5195
- uz: () => uz_default,
5196
- ur: () => ur_default,
5197
- uk: () => uk_default,
5198
- ua: () => ua_default,
5199
- tr: () => tr_default,
5200
- tk: () => tk_default,
5201
- th: () => th_default,
5202
- ta: () => ta_default,
5203
- sv: () => sv_default,
5204
- sl: () => sl_default,
5205
- sk: () => sk_default,
5206
- ru: () => ru_default,
5207
- ro: () => ro_default,
5208
- ptBR: () => pt_BR_default,
5209
- pt: () => pt_default,
5210
- ps: () => ps_default,
5211
- pl: () => pl_default,
5212
- ota: () => ota_default,
5213
- no: () => no_default,
5214
- nn: () => nn_default,
5215
- nl: () => nl_default,
5216
- ne: () => ne_default,
5217
- ms: () => ms_default,
5218
- mk: () => mk_default,
5219
- lt: () => lt_default,
5220
- ko: () => ko_default,
5221
- kn: () => kn_default,
5222
- km: () => km_default,
5223
- kh: () => kh_default,
5224
- ka: () => ka_default,
5225
- ja: () => ja_default,
5226
- it: () => it_default,
5227
- is: () => is_default,
5228
- id: () => id_default,
5229
- hy: () => hy_default,
5230
- hu: () => hu_default,
5231
- hr: () => hr_default,
5232
- hi: () => hi_default,
5233
- he: () => he_default,
5234
- gu: () => gu_default,
5235
- frCA: () => fr_CA_default,
5236
- fr: () => fr_default,
5237
- fi: () => fi_default,
5238
- fa: () => fa_default,
5239
- es: () => es_default,
5240
- eo: () => eo_default,
5241
- en: () => en_default,
5242
- el: () => el_default,
5243
- de: () => de_default,
5244
- da: () => da_default,
5245
- cs: () => cs_default,
5246
- ckb: () => ckb_default,
5247
- ca: () => ca_default,
5248
- bn: () => bn_default,
5249
- bg: () => bg_default,
5250
- be: () => be_default,
5212
+ ar: () => ar_default,
5251
5213
  az: () => az_default,
5252
- ar: () => ar_default
5214
+ be: () => be_default,
5215
+ bg: () => bg_default,
5216
+ bn: () => bn_default,
5217
+ ca: () => ca_default,
5218
+ ckb: () => ckb_default,
5219
+ cs: () => cs_default,
5220
+ da: () => da_default,
5221
+ de: () => de_default,
5222
+ el: () => el_default,
5223
+ en: () => en_default,
5224
+ eo: () => eo_default,
5225
+ es: () => es_default,
5226
+ fa: () => fa_default,
5227
+ fi: () => fi_default,
5228
+ fr: () => fr_default,
5229
+ frCA: () => fr_CA_default,
5230
+ gu: () => gu_default,
5231
+ he: () => he_default,
5232
+ hi: () => hi_default,
5233
+ hr: () => hr_default,
5234
+ hu: () => hu_default,
5235
+ hy: () => hy_default,
5236
+ id: () => id_default,
5237
+ is: () => is_default,
5238
+ it: () => it_default,
5239
+ ja: () => ja_default,
5240
+ ka: () => ka_default,
5241
+ kh: () => kh_default,
5242
+ km: () => km_default,
5243
+ kn: () => kn_default,
5244
+ ko: () => ko_default,
5245
+ lt: () => lt_default,
5246
+ mk: () => mk_default,
5247
+ ms: () => ms_default,
5248
+ ne: () => ne_default,
5249
+ nl: () => nl_default,
5250
+ nn: () => nn_default,
5251
+ no: () => no_default,
5252
+ ota: () => ota_default,
5253
+ pl: () => pl_default,
5254
+ ps: () => ps_default,
5255
+ pt: () => pt_default,
5256
+ ptBR: () => pt_BR_default,
5257
+ ro: () => ro_default,
5258
+ ru: () => ru_default,
5259
+ sk: () => sk_default,
5260
+ sl: () => sl_default,
5261
+ sv: () => sv_default,
5262
+ ta: () => ta_default,
5263
+ th: () => th_default,
5264
+ tk: () => tk_default,
5265
+ tr: () => tr_default,
5266
+ ua: () => ua_default,
5267
+ uk: () => uk_default,
5268
+ ur: () => ur_default,
5269
+ uz: () => uz_default,
5270
+ vi: () => vi_default,
5271
+ yo: () => yo_default,
5272
+ zhCN: () => zh_CN_default,
5273
+ zhTW: () => zh_TW_default
5253
5274
  });
5254
5275
 
5255
5276
  // node_modules/zod/v4/locales/ar.js
@@ -15377,7 +15398,7 @@ function finalize(ctx, schema) {
15377
15398
  result.$schema = "http://json-schema.org/draft-07/schema#";
15378
15399
  } else if (ctx.target === "draft-04") {
15379
15400
  result.$schema = "http://json-schema.org/draft-04/schema#";
15380
- } else if (ctx.target === "openapi-3.0") {} else {}
15401
+ } else if (ctx.target === "openapi-3.0") {}
15381
15402
  if (ctx.external?.uri) {
15382
15403
  const id = ctx.external.registry.get(schema)?.id;
15383
15404
  if (!id)
@@ -16213,213 +16234,213 @@ var exports_json_schema = {};
16213
16234
  // node_modules/zod/v4/classic/schemas.js
16214
16235
  var exports_schemas2 = {};
16215
16236
  __export(exports_schemas2, {
16216
- xor: () => xor,
16217
- xid: () => xid2,
16218
- void: () => _void2,
16219
- uuidv7: () => uuidv7,
16220
- uuidv6: () => uuidv6,
16221
- uuidv4: () => uuidv4,
16222
- uuid: () => uuid2,
16223
- url: () => url,
16224
- unknown: () => unknown,
16225
- union: () => union,
16226
- undefined: () => _undefined3,
16227
- ulid: () => ulid2,
16228
- uint64: () => uint64,
16229
- uint32: () => uint32,
16230
- tuple: () => tuple,
16231
- transform: () => transform,
16232
- templateLiteral: () => templateLiteral,
16233
- symbol: () => symbol,
16234
- superRefine: () => superRefine,
16235
- success: () => success,
16236
- stringbool: () => stringbool,
16237
- stringFormat: () => stringFormat,
16238
- string: () => string2,
16239
- strictObject: () => strictObject,
16240
- set: () => set,
16241
- refine: () => refine,
16242
- record: () => record,
16243
- readonly: () => readonly,
16244
- promise: () => promise,
16245
- preprocess: () => preprocess,
16246
- prefault: () => prefault,
16247
- pipe: () => pipe,
16248
- partialRecord: () => partialRecord,
16249
- optional: () => optional,
16250
- object: () => object,
16251
- number: () => number2,
16252
- nullish: () => nullish2,
16253
- nullable: () => nullable,
16254
- null: () => _null3,
16255
- nonoptional: () => nonoptional,
16256
- never: () => never,
16257
- nativeEnum: () => nativeEnum,
16258
- nanoid: () => nanoid2,
16259
- nan: () => nan,
16260
- meta: () => meta2,
16261
- map: () => map,
16262
- mac: () => mac2,
16263
- looseRecord: () => looseRecord,
16264
- looseObject: () => looseObject,
16265
- literal: () => literal,
16266
- lazy: () => lazy,
16267
- ksuid: () => ksuid2,
16268
- keyof: () => keyof,
16269
- jwt: () => jwt,
16270
- json: () => json,
16271
- ipv6: () => ipv62,
16272
- ipv4: () => ipv42,
16273
- invertCodec: () => invertCodec,
16274
- intersection: () => intersection,
16275
- int64: () => int64,
16276
- int32: () => int32,
16277
- int: () => int,
16278
- instanceof: () => _instanceof,
16279
- httpUrl: () => httpUrl,
16280
- hostname: () => hostname2,
16281
- hex: () => hex2,
16282
- hash: () => hash,
16283
- guid: () => guid2,
16284
- function: () => _function,
16285
- float64: () => float64,
16286
- float32: () => float32,
16287
- file: () => file,
16288
- exactOptional: () => exactOptional,
16289
- enum: () => _enum2,
16290
- emoji: () => emoji2,
16291
- email: () => email2,
16292
- e164: () => e1642,
16293
- discriminatedUnion: () => discriminatedUnion,
16294
- describe: () => describe2,
16295
- date: () => date2,
16296
- custom: () => custom,
16297
- cuid2: () => cuid22,
16298
- cuid: () => cuid3,
16299
- creditCard: () => creditCard2,
16300
- codec: () => codec,
16301
- cidrv6: () => cidrv62,
16302
- cidrv4: () => cidrv42,
16303
- check: () => check,
16304
- catch: () => _catch2,
16305
- boolean: () => boolean2,
16306
- bigint: () => bigint2,
16307
- base64url: () => base64url2,
16308
- base64: () => base642,
16309
- array: () => array,
16310
- any: () => any,
16311
- _function: () => _function,
16312
- _default: () => _default2,
16313
- _ZodString: () => _ZodString,
16314
- ZodXor: () => ZodXor,
16315
- ZodXID: () => ZodXID,
16316
- ZodVoid: () => ZodVoid,
16317
- ZodUnknown: () => ZodUnknown,
16318
- ZodUnion: () => ZodUnion,
16319
- ZodUndefined: () => ZodUndefined,
16320
- ZodUUID: () => ZodUUID,
16321
- ZodURL: () => ZodURL,
16322
- ZodULID: () => ZodULID,
16323
- ZodType: () => ZodType,
16324
- ZodTuple: () => ZodTuple,
16325
- ZodTransform: () => ZodTransform,
16326
- ZodTemplateLiteral: () => ZodTemplateLiteral,
16327
- ZodSymbol: () => ZodSymbol,
16328
- ZodSuccess: () => ZodSuccess,
16329
- ZodStringFormat: () => ZodStringFormat,
16330
- ZodString: () => ZodString,
16331
- ZodSet: () => ZodSet,
16332
- ZodRecord: () => ZodRecord,
16333
- ZodReadonly: () => ZodReadonly,
16334
- ZodPromise: () => ZodPromise,
16335
- ZodPreprocess: () => ZodPreprocess,
16336
- ZodPrefault: () => ZodPrefault,
16337
- ZodPipe: () => ZodPipe,
16338
- ZodOptional: () => ZodOptional,
16339
- ZodObject: () => ZodObject,
16340
- ZodNumberFormat: () => ZodNumberFormat,
16341
- ZodNumber: () => ZodNumber,
16342
- ZodNullable: () => ZodNullable,
16343
- ZodNull: () => ZodNull,
16344
- ZodNonOptional: () => ZodNonOptional,
16345
- ZodNever: () => ZodNever,
16346
- ZodNanoID: () => ZodNanoID,
16347
- ZodNaN: () => ZodNaN,
16348
- ZodMap: () => ZodMap,
16349
- ZodMAC: () => ZodMAC,
16350
- ZodLiteral: () => ZodLiteral,
16351
- ZodLazy: () => ZodLazy,
16352
- ZodKSUID: () => ZodKSUID,
16353
- ZodJWT: () => ZodJWT,
16354
- ZodIntersection: () => ZodIntersection,
16355
- ZodISOTime: () => ZodISOTime,
16356
- ZodISODuration: () => ZodISODuration,
16357
- ZodISODateTime: () => ZodISODateTime,
16358
- ZodISODate: () => ZodISODate,
16359
- ZodIPv6: () => ZodIPv6,
16360
- ZodIPv4: () => ZodIPv4,
16361
- ZodGUID: () => ZodGUID,
16362
- ZodFunction: () => ZodFunction,
16363
- ZodFile: () => ZodFile,
16364
- ZodExactOptional: () => ZodExactOptional,
16365
- ZodEnum: () => ZodEnum,
16366
- ZodEmoji: () => ZodEmoji,
16367
- ZodEmail: () => ZodEmail,
16368
- ZodE164: () => ZodE164,
16369
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
16370
- ZodDefault: () => ZodDefault,
16371
- ZodDate: () => ZodDate,
16372
- ZodCustomStringFormat: () => ZodCustomStringFormat,
16373
- ZodCustom: () => ZodCustom,
16374
- ZodCreditCard: () => ZodCreditCard,
16375
- ZodCodec: () => ZodCodec,
16376
- ZodCatch: () => ZodCatch,
16377
- ZodCUID2: () => ZodCUID2,
16378
- ZodCUID: () => ZodCUID,
16379
- ZodCIDRv6: () => ZodCIDRv6,
16380
- ZodCIDRv4: () => ZodCIDRv4,
16381
- ZodBoolean: () => ZodBoolean,
16382
- ZodBigIntFormat: () => ZodBigIntFormat,
16383
- ZodBigInt: () => ZodBigInt,
16384
- ZodBase64URL: () => ZodBase64URL,
16385
- ZodBase64: () => ZodBase64,
16237
+ ZodAny: () => ZodAny,
16386
16238
  ZodArray: () => ZodArray,
16387
- ZodAny: () => ZodAny
16239
+ ZodBase64: () => ZodBase64,
16240
+ ZodBase64URL: () => ZodBase64URL,
16241
+ ZodBigInt: () => ZodBigInt,
16242
+ ZodBigIntFormat: () => ZodBigIntFormat,
16243
+ ZodBoolean: () => ZodBoolean,
16244
+ ZodCIDRv4: () => ZodCIDRv4,
16245
+ ZodCIDRv6: () => ZodCIDRv6,
16246
+ ZodCUID: () => ZodCUID,
16247
+ ZodCUID2: () => ZodCUID2,
16248
+ ZodCatch: () => ZodCatch,
16249
+ ZodCodec: () => ZodCodec,
16250
+ ZodCreditCard: () => ZodCreditCard,
16251
+ ZodCustom: () => ZodCustom,
16252
+ ZodCustomStringFormat: () => ZodCustomStringFormat,
16253
+ ZodDate: () => ZodDate,
16254
+ ZodDefault: () => ZodDefault,
16255
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
16256
+ ZodE164: () => ZodE164,
16257
+ ZodEmail: () => ZodEmail,
16258
+ ZodEmoji: () => ZodEmoji,
16259
+ ZodEnum: () => ZodEnum,
16260
+ ZodExactOptional: () => ZodExactOptional,
16261
+ ZodFile: () => ZodFile,
16262
+ ZodFunction: () => ZodFunction,
16263
+ ZodGUID: () => ZodGUID,
16264
+ ZodIPv4: () => ZodIPv4,
16265
+ ZodIPv6: () => ZodIPv6,
16266
+ ZodISODate: () => ZodISODate,
16267
+ ZodISODateTime: () => ZodISODateTime,
16268
+ ZodISODuration: () => ZodISODuration,
16269
+ ZodISOTime: () => ZodISOTime,
16270
+ ZodIntersection: () => ZodIntersection,
16271
+ ZodJWT: () => ZodJWT,
16272
+ ZodKSUID: () => ZodKSUID,
16273
+ ZodLazy: () => ZodLazy,
16274
+ ZodLiteral: () => ZodLiteral,
16275
+ ZodMAC: () => ZodMAC,
16276
+ ZodMap: () => ZodMap,
16277
+ ZodNaN: () => ZodNaN,
16278
+ ZodNanoID: () => ZodNanoID,
16279
+ ZodNever: () => ZodNever,
16280
+ ZodNonOptional: () => ZodNonOptional,
16281
+ ZodNull: () => ZodNull,
16282
+ ZodNullable: () => ZodNullable,
16283
+ ZodNumber: () => ZodNumber,
16284
+ ZodNumberFormat: () => ZodNumberFormat,
16285
+ ZodObject: () => ZodObject,
16286
+ ZodOptional: () => ZodOptional,
16287
+ ZodPipe: () => ZodPipe,
16288
+ ZodPrefault: () => ZodPrefault,
16289
+ ZodPreprocess: () => ZodPreprocess,
16290
+ ZodPromise: () => ZodPromise,
16291
+ ZodReadonly: () => ZodReadonly,
16292
+ ZodRecord: () => ZodRecord,
16293
+ ZodSet: () => ZodSet,
16294
+ ZodString: () => ZodString,
16295
+ ZodStringFormat: () => ZodStringFormat,
16296
+ ZodSuccess: () => ZodSuccess,
16297
+ ZodSymbol: () => ZodSymbol,
16298
+ ZodTemplateLiteral: () => ZodTemplateLiteral,
16299
+ ZodTransform: () => ZodTransform,
16300
+ ZodTuple: () => ZodTuple,
16301
+ ZodType: () => ZodType,
16302
+ ZodULID: () => ZodULID,
16303
+ ZodURL: () => ZodURL,
16304
+ ZodUUID: () => ZodUUID,
16305
+ ZodUndefined: () => ZodUndefined,
16306
+ ZodUnion: () => ZodUnion,
16307
+ ZodUnknown: () => ZodUnknown,
16308
+ ZodVoid: () => ZodVoid,
16309
+ ZodXID: () => ZodXID,
16310
+ ZodXor: () => ZodXor,
16311
+ _ZodString: () => _ZodString,
16312
+ _default: () => _default2,
16313
+ _function: () => _function,
16314
+ any: () => any,
16315
+ array: () => array,
16316
+ base64: () => base642,
16317
+ base64url: () => base64url2,
16318
+ bigint: () => bigint2,
16319
+ boolean: () => boolean2,
16320
+ catch: () => _catch2,
16321
+ check: () => check,
16322
+ cidrv4: () => cidrv42,
16323
+ cidrv6: () => cidrv62,
16324
+ codec: () => codec,
16325
+ creditCard: () => creditCard2,
16326
+ cuid: () => cuid3,
16327
+ cuid2: () => cuid22,
16328
+ custom: () => custom,
16329
+ date: () => date2,
16330
+ describe: () => describe2,
16331
+ discriminatedUnion: () => discriminatedUnion,
16332
+ e164: () => e1642,
16333
+ email: () => email2,
16334
+ emoji: () => emoji2,
16335
+ enum: () => _enum2,
16336
+ exactOptional: () => exactOptional,
16337
+ file: () => file,
16338
+ float32: () => float32,
16339
+ float64: () => float64,
16340
+ function: () => _function,
16341
+ guid: () => guid2,
16342
+ hash: () => hash,
16343
+ hex: () => hex2,
16344
+ hostname: () => hostname2,
16345
+ httpUrl: () => httpUrl,
16346
+ instanceof: () => _instanceof,
16347
+ int: () => int,
16348
+ int32: () => int32,
16349
+ int64: () => int64,
16350
+ intersection: () => intersection,
16351
+ invertCodec: () => invertCodec,
16352
+ ipv4: () => ipv42,
16353
+ ipv6: () => ipv62,
16354
+ json: () => json,
16355
+ jwt: () => jwt,
16356
+ keyof: () => keyof,
16357
+ ksuid: () => ksuid2,
16358
+ lazy: () => lazy,
16359
+ literal: () => literal,
16360
+ looseObject: () => looseObject,
16361
+ looseRecord: () => looseRecord,
16362
+ mac: () => mac2,
16363
+ map: () => map,
16364
+ meta: () => meta2,
16365
+ nan: () => nan,
16366
+ nanoid: () => nanoid2,
16367
+ nativeEnum: () => nativeEnum,
16368
+ never: () => never,
16369
+ nonoptional: () => nonoptional,
16370
+ null: () => _null3,
16371
+ nullable: () => nullable,
16372
+ nullish: () => nullish2,
16373
+ number: () => number2,
16374
+ object: () => object,
16375
+ optional: () => optional,
16376
+ partialRecord: () => partialRecord,
16377
+ pipe: () => pipe,
16378
+ prefault: () => prefault,
16379
+ preprocess: () => preprocess,
16380
+ promise: () => promise,
16381
+ readonly: () => readonly,
16382
+ record: () => record,
16383
+ refine: () => refine,
16384
+ set: () => set,
16385
+ strictObject: () => strictObject,
16386
+ string: () => string2,
16387
+ stringFormat: () => stringFormat,
16388
+ stringbool: () => stringbool,
16389
+ success: () => success,
16390
+ superRefine: () => superRefine,
16391
+ symbol: () => symbol,
16392
+ templateLiteral: () => templateLiteral,
16393
+ transform: () => transform,
16394
+ tuple: () => tuple,
16395
+ uint32: () => uint32,
16396
+ uint64: () => uint64,
16397
+ ulid: () => ulid2,
16398
+ undefined: () => _undefined3,
16399
+ union: () => union,
16400
+ unknown: () => unknown,
16401
+ url: () => url,
16402
+ uuid: () => uuid2,
16403
+ uuidv4: () => uuidv4,
16404
+ uuidv6: () => uuidv6,
16405
+ uuidv7: () => uuidv7,
16406
+ void: () => _void2,
16407
+ xid: () => xid2,
16408
+ xor: () => xor
16388
16409
  });
16389
16410
 
16390
16411
  // node_modules/zod/v4/classic/checks.js
16391
16412
  var exports_checks2 = {};
16392
16413
  __export(exports_checks2, {
16393
- uppercase: () => _uppercase,
16394
- trim: () => _trim,
16395
- toUpperCase: () => _toUpperCase,
16396
- toLowerCase: () => _toLowerCase,
16397
- startsWith: () => _startsWith,
16398
- slugify: () => _slugify,
16399
- size: () => _size,
16400
- regex: () => _regex,
16401
- property: () => _property,
16402
- properties: () => _properties,
16403
- positive: () => _positive,
16404
- overwrite: () => _overwrite,
16405
- normalize: () => _normalize,
16406
- nonpositive: () => _nonpositive,
16407
- nonnegative: () => _nonnegative,
16408
- negative: () => _negative,
16409
- multipleOf: () => _multipleOf,
16410
- minSize: () => _minSize,
16411
- minLength: () => _minLength,
16412
- mime: () => _mime,
16413
- maxSize: () => _maxSize,
16414
- maxLength: () => _maxLength,
16415
- lte: () => _lte,
16416
- lt: () => _lt,
16417
- lowercase: () => _lowercase,
16418
- length: () => _length,
16419
- includes: () => _includes,
16420
- gte: () => _gte,
16414
+ endsWith: () => _endsWith,
16421
16415
  gt: () => _gt,
16422
- endsWith: () => _endsWith
16416
+ gte: () => _gte,
16417
+ includes: () => _includes,
16418
+ length: () => _length,
16419
+ lowercase: () => _lowercase,
16420
+ lt: () => _lt,
16421
+ lte: () => _lte,
16422
+ maxLength: () => _maxLength,
16423
+ maxSize: () => _maxSize,
16424
+ mime: () => _mime,
16425
+ minLength: () => _minLength,
16426
+ minSize: () => _minSize,
16427
+ multipleOf: () => _multipleOf,
16428
+ negative: () => _negative,
16429
+ nonnegative: () => _nonnegative,
16430
+ nonpositive: () => _nonpositive,
16431
+ normalize: () => _normalize,
16432
+ overwrite: () => _overwrite,
16433
+ positive: () => _positive,
16434
+ properties: () => _properties,
16435
+ property: () => _property,
16436
+ regex: () => _regex,
16437
+ size: () => _size,
16438
+ slugify: () => _slugify,
16439
+ startsWith: () => _startsWith,
16440
+ toLowerCase: () => _toLowerCase,
16441
+ toUpperCase: () => _toUpperCase,
16442
+ trim: () => _trim,
16443
+ uppercase: () => _uppercase
16423
16444
  });
16424
16445
 
16425
16446
  // node_modules/zod/v4/classic/errors.js
@@ -17913,14 +17934,14 @@ var ZodFirstPartyTypeKind;
17913
17934
  // node_modules/zod/v4/classic/iso.js
17914
17935
  var exports_iso = {};
17915
17936
  __export(exports_iso, {
17916
- time: () => time2,
17917
- duration: () => duration2,
17918
- datetime: () => datetime2,
17919
- date: () => date3,
17920
- ZodISOTime: () => ZodISOTime,
17921
- ZodISODuration: () => ZodISODuration,
17937
+ ZodISODate: () => ZodISODate,
17922
17938
  ZodISODateTime: () => ZodISODateTime,
17923
- ZodISODate: () => ZodISODate
17939
+ ZodISODuration: () => ZodISODuration,
17940
+ ZodISOTime: () => ZodISOTime,
17941
+ date: () => date3,
17942
+ datetime: () => datetime2,
17943
+ duration: () => duration2,
17944
+ time: () => time2
17924
17945
  });
17925
17946
  function datetime2(params) {
17926
17947
  return _isoDateTime(ZodISODateTime, params);
@@ -18653,11 +18674,11 @@ function output(schema) {
18653
18674
  // node_modules/zod/v4/classic/coerce.js
18654
18675
  var exports_coerce = {};
18655
18676
  __export(exports_coerce, {
18656
- string: () => string3,
18657
- number: () => number3,
18658
- date: () => date4,
18677
+ bigint: () => bigint3,
18659
18678
  boolean: () => boolean3,
18660
- bigint: () => bigint3
18679
+ date: () => date4,
18680
+ number: () => number3,
18681
+ string: () => string3
18661
18682
  });
18662
18683
  function string3(params) {
18663
18684
  return _coercedString(ZodString, params);
@@ -19109,6 +19130,8 @@ function debug(event, data) {
19109
19130
 
19110
19131
  // src/tui/actions.ts
19111
19132
  import { createSignal } from "solid-js";
19133
+ import fs4 from "fs";
19134
+ import path3 from "path";
19112
19135
 
19113
19136
  // src/core/decision.ts
19114
19137
  var DECISION_SYSTEM = "You write concise engineering decision records. You are given the transcript of a side branch of a coding session. Do NOT continue the conversation. Output ONLY the record in the exact markdown template requested, nothing else.";
@@ -19177,6 +19200,55 @@ function decisionMessageText(record2, branchName) {
19177
19200
  return body.startsWith("## Decision:") ? `\u25C6 ${body}` : `\u25C6 ## Decision: ${branchName}
19178
19201
  ${body}`;
19179
19202
  }
19203
+ var BULLET = /^(\s*)[-*\u2022]\s+/;
19204
+ var HEADING = /^(\s*(?:\u25C6\s*)?)#{1,6}\s*/;
19205
+ function stripMarkdown(text) {
19206
+ return text.replace(/[*`]/g, "");
19207
+ }
19208
+ function wrapLine(body, width, marker) {
19209
+ const room = Math.max(1, width - marker.length);
19210
+ const indent = " ".repeat(marker.length);
19211
+ const lines = [];
19212
+ let current = "";
19213
+ for (const raw of body.split(/\s+/).filter(Boolean)) {
19214
+ const word = raw.length > room ? `${raw.slice(0, Math.max(1, room - 1))}\u2026` : raw;
19215
+ if (current === "")
19216
+ current = word;
19217
+ else if (current.length + 1 + word.length <= room)
19218
+ current += ` ${word}`;
19219
+ else {
19220
+ lines.push(current);
19221
+ current = word;
19222
+ }
19223
+ }
19224
+ lines.push(current);
19225
+ return lines.map((line, i) => `${i === 0 ? marker : indent}${line}`.trimEnd());
19226
+ }
19227
+ function renderDecision(text, width) {
19228
+ const out = [];
19229
+ for (const raw of text.replace(/\r/g, "").trim().split(`
19230
+ `)) {
19231
+ const line = raw.trimEnd();
19232
+ if (line.trim() === "") {
19233
+ if (out.length > 0 && out[out.length - 1] !== "")
19234
+ out.push("");
19235
+ continue;
19236
+ }
19237
+ const bullet = BULLET.exec(line);
19238
+ const marker = bullet ? `${bullet[1]}- ` : "";
19239
+ const body = stripMarkdown(bullet ? line.slice(bullet[0].length) : line.replace(HEADING, "$1"));
19240
+ out.push(...wrapLine(body, width, marker));
19241
+ }
19242
+ return out;
19243
+ }
19244
+ function decisionSummary(text) {
19245
+ const lines = text.replace(/\r/g, "").split(`
19246
+ `).map((l) => stripMarkdown(l.replace(/^\s*\u25C6\s*/, "").replace(HEADING, "$1").replace(BULLET, "")).trim());
19247
+ const heading = lines.find((l) => /^Decision:\s*\S/i.test(l));
19248
+ const title = heading ? heading.replace(/^Decision:\s*/i, "").trim() : lines.find((l) => l !== "") ?? "";
19249
+ const outcome = lines.find((l) => /^Outcome:\s*\S/i.test(l))?.replace(/^Outcome:\s*/i, "").trim();
19250
+ return outcome ? { title, outcome } : { title };
19251
+ }
19180
19252
  function openSiblings(state, sessionID) {
19181
19253
  const me = state.sessions[sessionID];
19182
19254
  if (!me)
@@ -19558,19 +19630,67 @@ async function draftWithHelper(ctx, input2) {
19558
19630
  }
19559
19631
  }
19560
19632
  var MERGE_TRUST = "Your transcript is never rewritten; the record is appended to the trunk as a normal message.";
19633
+ var UNDO_KEY = "u";
19561
19634
  var MERGE_GATE_NOTICE = `Edit the \u25C6 decision record, then save to confirm (empty file or a non-zero exit aborts the merge).
19562
19635
  ${MERGE_TRUST}`;
19563
- function mergeDialogTitle(branchName, trunkTitle) {
19564
- return `Merge \u2387 ${branchName} \u2192 ${trunkTitle ? clip(trunkTitle, 28) : "the trunk"}`;
19636
+ var DISCARD_NOTICE = `${MERGE_TRUST}
19637
+ The branch is only marked rejected \u2014 ${UNDO_KEY} (alias x) undoes it.`;
19638
+ var TRUNK_LABEL = "trunk";
19639
+ function mergeTargetOf(label, messages) {
19640
+ const minimal = messages.map((m) => ({ info: m.role === "assistant" ? { role: "assistant", tokens: m.tokens } : { role: "user" }, parts: m.parts }));
19641
+ return { label, turns: messages.filter((m) => m.role === "user").length, tokens: contextSizeOf(minimal).tokens };
19642
+ }
19643
+ function ownTurnCount(messages, anchor2) {
19644
+ const anchorIndex = anchor2.messageID ? anchor2.parentMessageIDs.indexOf(anchor2.messageID) : -1;
19645
+ return messages.slice(anchorIndex + 1).filter((m) => m.role === "user").length;
19646
+ }
19647
+ function mergeDialogTitle(branchName, target2) {
19648
+ if (!target2 || typeof target2 === "string")
19649
+ return `Merge \u2387 ${branchName} \u2192 the trunk`;
19650
+ const where = target2.label === TRUNK_LABEL ? TRUNK_LABEL : `\u2387 ${clip(target2.label, 24)}`;
19651
+ return `Merge \u2387 ${branchName} \u2192 ${where} (${plural(target2.turns, "turn")}, ~${formatK(target2.tokens)})`;
19565
19652
  }
19566
19653
  function mergeDialogOptions(input2) {
19654
+ const folds = input2.turns === undefined ? "the branch" : plural(input2.turns, "turn");
19567
19655
  return [
19568
- { title: "Squash", value: "squash", description: "drafts a \u25C6 decision record you confirm" },
19569
- { title: "Squash without LLM", value: "squash-no-llm", description: "you write the record yourself" },
19570
- { title: "Discard", value: "discard", description: "rejected; nothing lands in the trunk" },
19656
+ { title: "Squash", value: "squash", description: `1 model call \xB7 folds ${folds} into one \u25C6 record` },
19657
+ { title: "Squash without LLM", value: "squash-no-llm", description: "you write it \xB7 no model call" },
19658
+ { title: "Discard", value: "discard", description: "rejected \xB7 nothing lands in the trunk" },
19571
19659
  ...input2.siblings > 0 ? [{ title: "Tournament", value: "tournament", description: "compare sibling branches and keep one" }] : []
19572
19660
  ];
19573
19661
  }
19662
+ function confirmDialog(ctx, title, message) {
19663
+ return new Promise((resolve) => {
19664
+ ctx.api.ui.dialog.replace(() => ctx.api.ui.DialogConfirm({
19665
+ title,
19666
+ message,
19667
+ onConfirm: () => {
19668
+ resolve(true);
19669
+ ctx.api.ui.dialog.clear();
19670
+ },
19671
+ onCancel: () => {
19672
+ resolve(false);
19673
+ ctx.api.ui.dialog.clear();
19674
+ }
19675
+ }), () => resolve(false));
19676
+ });
19677
+ }
19678
+ function promptDialog(ctx, title, placeholder) {
19679
+ return new Promise((resolve) => {
19680
+ ctx.api.ui.dialog.replace(() => ctx.api.ui.DialogPrompt({
19681
+ title,
19682
+ placeholder,
19683
+ onConfirm: (value) => {
19684
+ resolve(value);
19685
+ ctx.api.ui.dialog.clear();
19686
+ },
19687
+ onCancel: () => {
19688
+ resolve(undefined);
19689
+ ctx.api.ui.dialog.clear();
19690
+ }
19691
+ }), () => resolve(undefined));
19692
+ });
19693
+ }
19574
19694
  async function mergeBranch(ctx, input2) {
19575
19695
  const treeId = ctx.store.ensureTree(input2.sessionID, "tui");
19576
19696
  const state = ctx.store.stateFor(treeId);
@@ -19581,16 +19701,33 @@ async function mergeBranch(ctx, input2) {
19581
19701
  const name = branch.name ?? "branch";
19582
19702
  debug("merge.start", { mode: input2.mode, sessionID: input2.sessionID, parentID });
19583
19703
  await abortIfBusy(ctx, input2.sessionID);
19704
+ const parentMsgs = await ctx.api.client.session.messages({ sessionID: parentID, directory: ctx.directory }).catch(() => {
19705
+ return;
19706
+ });
19707
+ const parentMessageIDs = (parentMsgs?.data ?? []).map((m) => String(m.info.id));
19708
+ const own2 = await fetchOwnTranscript(ctx, input2.sessionID);
19709
+ const turns = ownTurnCount(own2.messages, { messageID: branch.anchorMessageID, parentMessageIDs });
19584
19710
  if (input2.mode === "discard") {
19585
- record2(ctx, treeId, "branch.closed", { sessionID: input2.sessionID, status: "rejected", note: input2.note });
19711
+ const ok = await confirmDialog(ctx, `Discard \u2387 ${name} (${plural(turns, "turn")})?`, DISCARD_NOTICE);
19712
+ if (!ok) {
19713
+ ctx.api.ui.toast({ variant: "warning", message: `\u2387 ${name} kept \u2014 nothing discarded` });
19714
+ return;
19715
+ }
19716
+ let note = input2.note;
19717
+ if (note === undefined) {
19718
+ const answer = await promptDialog(ctx, "Why? (optional note on the close marker)", "dead end");
19719
+ if (answer === undefined) {
19720
+ ctx.api.ui.toast({ variant: "warning", message: `\u2387 ${name} kept \u2014 nothing discarded` });
19721
+ return;
19722
+ }
19723
+ note = answer.trim() || undefined;
19724
+ }
19725
+ record2(ctx, treeId, "branch.closed", { sessionID: input2.sessionID, status: "rejected", note });
19586
19726
  await mirrorMetadata(ctx, input2.sessionID, { status: "rejected" });
19587
19727
  navigateToSession(ctx, parentID);
19588
19728
  ctx.api.ui.toast({ variant: "success", message: `\u2387 ${name} discarded \u2014 back on the trunk` });
19589
19729
  return parentID;
19590
19730
  }
19591
- const parentMsgs = await ctx.api.client.session.messages({ sessionID: parentID, directory: ctx.directory });
19592
- const parentMessageIDs = (parentMsgs.data ?? []).map((m) => String(m.info.id));
19593
- const own2 = await fetchOwnTranscript(ctx, input2.sessionID);
19594
19731
  const transcript = branchTranscriptText(own2, { messageID: branch.anchorMessageID, parentMessageIDs });
19595
19732
  const model = branch.branchModel ?? branch.trunkModel;
19596
19733
  const modelRef = model ? { providerID: model.split("/")[0], modelID: model.split("/").slice(1).join("/") } : undefined;
@@ -19650,15 +19787,28 @@ async function fetchOwnTranscript(ctx, sessionID) {
19650
19787
  return { sessionID, title: sessionID, status: "available", messages };
19651
19788
  }
19652
19789
  var BRANCH_DIALOG = { title: "Branch here \u2192 new OpenCode session", placeholder: "name, e.g. try-redis", modelTitle: "Model for this branch (Enter keeps the current one)" };
19790
+ var COPY_HINT = ".opencode/context-tree/last-copy.txt";
19791
+ function copyText(api2, text, directory) {
19792
+ const renderer = api2.renderer;
19793
+ if (text && renderer?.copyToClipboardOSC52?.(text))
19794
+ return { target: "clipboard", hint: "clipboard" };
19795
+ const file2 = path3.join(directory, COPY_HINT);
19796
+ fs4.mkdirSync(path3.dirname(file2), { recursive: true });
19797
+ fs4.writeFileSync(file2, text);
19798
+ return { target: "file", hint: COPY_HINT };
19799
+ }
19653
19800
  function clip(text, max) {
19654
19801
  return text.length > max ? `${text.slice(0, max - 1)}\u2026` : text;
19655
19802
  }
19803
+ function plural(n, noun) {
19804
+ return `${n} ${noun}${n === 1 ? "" : "s"}`;
19805
+ }
19656
19806
 
19657
19807
  // src/tui/route.tsx
19658
- import { createComponent as _$createComponent } from "@opentui/solid";
19659
- import { effect as _$effect } from "@opentui/solid";
19660
- import { createTextNode as _$createTextNode } from "@opentui/solid";
19661
19808
  import { memo as _$memo } from "@opentui/solid";
19809
+ import { createTextNode as _$createTextNode } from "@opentui/solid";
19810
+ import { effect as _$effect } from "@opentui/solid";
19811
+ import { createComponent as _$createComponent } from "@opentui/solid";
19662
19812
  import { insertNode as _$insertNode } from "@opentui/solid";
19663
19813
  import { insert as _$insert } from "@opentui/solid";
19664
19814
  import { setProp as _$setProp } from "@opentui/solid";
@@ -19667,6 +19817,8 @@ import { For, Show, createEffect, createMemo, createSignal as createSignal2, on,
19667
19817
 
19668
19818
  // src/core/actions.ts
19669
19819
  function planJump(row, ctx) {
19820
+ if (row.kind === "separator")
19821
+ return { kind: "noop", reason: "nothing to go to" };
19670
19822
  if (row.kind === "branch")
19671
19823
  return row.sessionID === ctx.currentSessionID ? { kind: "noop", reason: "you are here" } : { kind: "switch", sessionID: row.sessionID };
19672
19824
  const tr = ctx.transcripts[row.sessionID];
@@ -19694,15 +19846,33 @@ function planJump(row, ctx) {
19694
19846
  }
19695
19847
 
19696
19848
  // src/core/navigation.ts
19849
+ function scan(rows, index, dir) {
19850
+ for (let i = index;i >= 0 && i < rows.length; i += dir)
19851
+ if (rows[i].kind !== "separator")
19852
+ return i;
19853
+ return -1;
19854
+ }
19697
19855
  function moveSelection(rows, index, delta) {
19698
19856
  if (rows.length === 0)
19699
19857
  return -1;
19700
- const next = index + delta;
19701
- if (next < 0)
19702
- return 0;
19703
- if (next > rows.length - 1)
19704
- return rows.length - 1;
19705
- return next;
19858
+ const dir = delta < 0 ? -1 : 1;
19859
+ let i = Math.min(Math.max(index, 0), rows.length - 1);
19860
+ for (let step = Math.abs(delta);step > 0; step--) {
19861
+ const next = scan(rows, i + dir, dir);
19862
+ if (next === -1)
19863
+ break;
19864
+ i = next;
19865
+ }
19866
+ if (rows[i].kind !== "separator")
19867
+ return i;
19868
+ const ahead = scan(rows, i, dir);
19869
+ return ahead === -1 ? scan(rows, i, dir === 1 ? -1 : 1) : ahead;
19870
+ }
19871
+ function firstIndex(rows) {
19872
+ return scan(rows, 0, 1);
19873
+ }
19874
+ function lastIndex(rows) {
19875
+ return scan(rows, rows.length - 1, -1);
19706
19876
  }
19707
19877
  function nextBranchIndex(rows, index, dir) {
19708
19878
  if (rows.length === 0)
@@ -19725,39 +19895,40 @@ function toggleExpanded(expanded, sessionID) {
19725
19895
  next.add(sessionID);
19726
19896
  return next;
19727
19897
  }
19728
- var FILTER_ORDER = ["default", "no-tools", "user-only", "labeled", "all"];
19729
- function cycleFilter(filter) {
19730
- const idx = FILTER_ORDER.indexOf(filter);
19731
- return FILTER_ORDER[(idx + 1) % FILTER_ORDER.length];
19732
- }
19733
19898
  function resolveSelection(view, preferredId, currentRowId, previousIndex) {
19734
19899
  if (view.rows.length === 0)
19735
19900
  return -1;
19901
+ const land = (i) => {
19902
+ const ahead = scan(view.rows, i, 1);
19903
+ return ahead === -1 ? scan(view.rows, i, -1) : ahead;
19904
+ };
19736
19905
  if (preferredId !== undefined) {
19737
19906
  const exact = view.indexById[preferredId];
19738
19907
  if (exact !== undefined)
19739
- return exact;
19908
+ return land(exact);
19740
19909
  const owner = preferredId.split(":").slice(0, 2).join(":");
19741
19910
  for (let i = 0;i < view.rows.length; i++) {
19742
19911
  const row = view.rows[i];
19912
+ if (row.kind === "separator")
19913
+ continue;
19743
19914
  const rowOwner = row.kind === "branch" ? row.id : `${row.sessionID}:${row.messageID}`;
19744
19915
  if (rowOwner === owner)
19745
19916
  return i;
19746
19917
  }
19747
19918
  }
19748
19919
  if (previousIndex !== undefined && previousIndex >= 0)
19749
- return Math.min(previousIndex, view.rows.length - 1);
19920
+ return land(Math.min(previousIndex, view.rows.length - 1));
19750
19921
  if (currentRowId !== undefined) {
19751
19922
  const idx = view.indexById[currentRowId];
19752
19923
  if (idx !== undefined)
19753
- return idx;
19924
+ return land(idx);
19754
19925
  }
19755
19926
  if (view.currentRowId !== undefined) {
19756
19927
  const idx = view.indexById[view.currentRowId];
19757
19928
  if (idx !== undefined)
19758
- return idx;
19929
+ return land(idx);
19759
19930
  }
19760
- return 0;
19931
+ return land(0);
19761
19932
  }
19762
19933
 
19763
19934
  // src/core/transcript.ts
@@ -19829,6 +20000,7 @@ function messagePreview(message) {
19829
20000
  }
19830
20001
 
19831
20002
  // src/core/tree.ts
20003
+ var OFF_PATH_TEXT = "\u2500\u2500 not in this branch's context \u2500\u2500";
19832
20004
  var WARN_TOKENS = 1e4;
19833
20005
  function userText(message) {
19834
20006
  return message.parts.filter((p) => p.type === "text" && p.text).map((p) => p.text).join(`
@@ -19955,7 +20127,7 @@ function branchAllowed(filter) {
19955
20127
  function isCropped(ctx, messageID, partID) {
19956
20128
  return ctx.crops.some((c) => c.messageID === messageID && (c.partID === undefined || c.partID === partID));
19957
20129
  }
19958
- function emitAssistantRows(ctx, sessionID, message, depth, gutter, out) {
20130
+ function emitAssistantRows(ctx, sessionID, message, depth, gutter, inContext, out) {
19959
20131
  if (message.summary) {
19960
20132
  if (!stepAllowed(ctx.filter, "text"))
19961
20133
  return;
@@ -19981,19 +20153,29 @@ function emitAssistantRows(ctx, sessionID, message, depth, gutter, out) {
19981
20153
  durationMs: durationOfParts(message.parts),
19982
20154
  isError: false,
19983
20155
  isCropped: false,
19984
- warn: tokens >= WARN_TOKENS
20156
+ warn: tokens >= WARN_TOKENS,
20157
+ inContext
19985
20158
  });
19986
20159
  return;
19987
20160
  }
20161
+ const collapseThinking = ctx.filter !== "all";
20162
+ const rows = [];
20163
+ let thinkingMs;
19988
20164
  let first = true;
19989
20165
  for (const part of message.parts) {
19990
20166
  const kind = stepKind(part);
20167
+ if (collapseThinking && kind === "reasoning") {
20168
+ const ms = durationOfPart(part);
20169
+ if (ms !== undefined)
20170
+ thinkingMs = (thinkingMs ?? 0) + ms;
20171
+ continue;
20172
+ }
19991
20173
  const label = first ? ctx.labels[message.id] : undefined;
19992
20174
  if (!stepAllowed(ctx.filter, kind, Boolean(label)))
19993
20175
  continue;
19994
20176
  const { tokens, estimated } = stepTokensFor(part, message);
19995
20177
  first = false;
19996
- out.push({
20178
+ rows.push({
19997
20179
  kind: "step",
19998
20180
  id: `${sessionID}:${message.id}:${part.id}`,
19999
20181
  sessionID,
@@ -20009,9 +20191,40 @@ function emitAssistantRows(ctx, sessionID, message, depth, gutter, out) {
20009
20191
  isError: part.state?.status === "error",
20010
20192
  isCropped: isCropped(ctx, message.id, part.id),
20011
20193
  warn: tokens >= WARN_TOKENS,
20012
- label
20194
+ label,
20195
+ inContext
20013
20196
  });
20014
20197
  }
20198
+ if (rows.length > 0) {
20199
+ if (thinkingMs !== undefined)
20200
+ rows[0].thinkingMs = thinkingMs;
20201
+ } else if (collapseThinking) {
20202
+ const thinking = message.parts.filter((p) => stepKind(p) === "reasoning");
20203
+ const label = ctx.labels[message.id];
20204
+ if (thinking.length > 0 && stepAllowed(ctx.filter, "reasoning", Boolean(label))) {
20205
+ const tokens = thinking.reduce((sum, p) => sum + stepTokensFor(p, message).tokens, 0);
20206
+ rows.push({
20207
+ kind: "step",
20208
+ id: `${sessionID}:${message.id}:${thinking[0].id}`,
20209
+ sessionID,
20210
+ messageID: message.id,
20211
+ partID: thinking[0].id,
20212
+ depth,
20213
+ gutter,
20214
+ glyph: "\u25CB",
20215
+ preview: partPreview(thinking[0]),
20216
+ tokens,
20217
+ estimated: thinking.some((p) => stepTokensFor(p, message).estimated),
20218
+ durationMs: thinkingMs,
20219
+ isError: false,
20220
+ isCropped: isCropped(ctx, message.id, thinking[0].id),
20221
+ warn: tokens >= WARN_TOKENS,
20222
+ label,
20223
+ inContext
20224
+ });
20225
+ }
20226
+ }
20227
+ out.push(...rows);
20015
20228
  }
20016
20229
  function shownExpanded(ctx, sessionID) {
20017
20230
  const flagged = ctx.expanded.has(sessionID);
@@ -20072,11 +20285,21 @@ function emitChildBranches(ctx, sessionID, anchorMessageID, depth, gutter, out)
20072
20285
  pushBranch(ctx, branch, depth, gutter, i === visible.length - 1, showHeaders, out);
20073
20286
  });
20074
20287
  }
20288
+ function forkAnchorOf(ctx, sessionID) {
20289
+ const childID = ctx.onPathChild.get(sessionID);
20290
+ return childID ? ctx.state.sessions[childID]?.anchorMessageID : undefined;
20291
+ }
20075
20292
  function walkSession(ctx, sessionID, messages, depth, gutter, turnStart, out) {
20076
20293
  const lastUserIndex = findLastUserIndex(messages, ctx.filter);
20077
20294
  const counter = { turn: turnStart };
20078
20295
  let inPluginCommand = false;
20296
+ const forkAnchor = forkAnchorOf(ctx, sessionID);
20297
+ let inContext = ctx.onPath.has(sessionID);
20298
+ let separatorDue = inContext && forkAnchor === "";
20299
+ if (separatorDue)
20300
+ inContext = false;
20079
20301
  messages.forEach((message, i) => {
20302
+ const before = out.length;
20080
20303
  if (message.role === "user") {
20081
20304
  inPluginCommand = hiddenPluginTurn(ctx.filter, message);
20082
20305
  if (!inPluginCommand) {
@@ -20102,14 +20325,23 @@ function walkSession(ctx, sessionID, messages, depth, gutter, turnStart, out) {
20102
20325
  isCurrent: sessionID === ctx.currentSessionID,
20103
20326
  isTip: i === lastUserIndex,
20104
20327
  isDecision,
20105
- isSummary
20328
+ isSummary,
20329
+ inContext
20106
20330
  });
20107
20331
  }
20108
20332
  }
20109
20333
  } else if (!inPluginCommand) {
20110
- emitAssistantRows(ctx, sessionID, message, depth, gutter, out);
20334
+ emitAssistantRows(ctx, sessionID, message, depth, gutter, inContext, out);
20111
20335
  }
20112
20336
  emitChildBranches(ctx, sessionID, message.id, depth, gutter, out);
20337
+ if (separatorDue && out.length > before) {
20338
+ out.splice(before, 0, { kind: "separator", id: `separator:${sessionID}`, depth, gutter, text: OFF_PATH_TEXT });
20339
+ separatorDue = false;
20340
+ }
20341
+ if (inContext && message.id === forkAnchor) {
20342
+ inContext = false;
20343
+ separatorDue = true;
20344
+ }
20113
20345
  });
20114
20346
  }
20115
20347
  function rowSearchFields(row) {
@@ -20120,6 +20352,8 @@ function rowSearchFields(row) {
20120
20352
  return row.label ? [row.preview, row.label] : [row.preview];
20121
20353
  case "branch":
20122
20354
  return row.model ? [row.name, row.model, row.status] : [row.name, row.status];
20355
+ case "separator":
20356
+ return [];
20123
20357
  }
20124
20358
  }
20125
20359
  function rowMatches(row, needle) {
@@ -20152,17 +20386,17 @@ function applySearch(rows, search) {
20152
20386
  return rows.filter((_, i) => keep[i]);
20153
20387
  }
20154
20388
  function computeTotalTokens(transcript) {
20155
- let lastIndex = -1;
20389
+ let lastIndex2 = -1;
20156
20390
  let lastInput = 0;
20157
20391
  transcript.messages.forEach((m, idx) => {
20158
20392
  if (m.role === "assistant" && typeof m.tokens?.input === "number") {
20159
- lastIndex = idx;
20393
+ lastIndex2 = idx;
20160
20394
  lastInput = m.tokens.input;
20161
20395
  }
20162
20396
  });
20163
20397
  let counted = 0;
20164
20398
  let guessed = 0;
20165
- for (let i = Math.max(lastIndex, 0);i < transcript.messages.length; i++) {
20399
+ for (let i = Math.max(lastIndex2, 0);i < transcript.messages.length; i++) {
20166
20400
  const m = transcript.messages[i];
20167
20401
  if (m.role === "user") {
20168
20402
  guessed += estimateTokens(userText(m));
@@ -20175,7 +20409,7 @@ function computeTotalTokens(transcript) {
20175
20409
  if (p.type === "tool" || typeof output2 !== "number")
20176
20410
  guessed += estimateTokens(partText2(p));
20177
20411
  }
20178
- return { tokens: lastInput + counted + guessed, estimated: lastIndex === -1 || guessed > 0 };
20412
+ return { tokens: lastInput + counted + guessed, estimated: lastIndex2 === -1 || guessed > 0 };
20179
20413
  }
20180
20414
  function currentChainOf(state, currentSessionID) {
20181
20415
  return [...ancestorChainOf(state, currentSessionID), currentSessionID];
@@ -20227,7 +20461,7 @@ function buildTreeView(o) {
20227
20461
  let currentRowId;
20228
20462
  for (let i = rows.length - 1;i >= 0; i--) {
20229
20463
  const r = rows[i];
20230
- if (r.kind !== "branch" && r.sessionID === o.currentSessionID) {
20464
+ if ((r.kind === "turn" || r.kind === "step") && r.sessionID === o.currentSessionID) {
20231
20465
  currentRowId = r.id;
20232
20466
  break;
20233
20467
  }
@@ -20319,111 +20553,141 @@ function spanOf(m) {
20319
20553
  const end = m.time.completed ?? m.parts.reduce((e, p) => Math.max(e, p.state?.time?.end ?? p.time?.end ?? 0), 0);
20320
20554
  return end > m.time.created ? end - m.time.created : 0;
20321
20555
  }
20322
- function buildLanes(transcript, mode) {
20323
- const columns = [];
20556
+ var EVENT_GLYPH = "\u25AC";
20557
+ function ctreeKindOf2(message) {
20558
+ for (const p of message.parts) {
20559
+ const ctree = p.metadata?.["ctree"];
20560
+ if (ctree?.kind)
20561
+ return ctree.kind;
20562
+ }
20563
+ return;
20564
+ }
20565
+ function isContextMessage(message) {
20566
+ return message.summary === true || ctreeKindOf2(message) === "summary";
20567
+ }
20568
+ function messageEvent(message, turn) {
20569
+ const ms = spanOf(message);
20570
+ return {
20571
+ lane: "input",
20572
+ kind: isContextMessage(message) ? "context" : "user",
20573
+ messageID: message.id,
20574
+ turn,
20575
+ startMs: message.time.created,
20576
+ ...ms > 0 ? { durationMs: ms } : {},
20577
+ tokens: message.parts.reduce((s, p) => s + estimateTokens(p.text ?? ""), 0)
20578
+ };
20579
+ }
20580
+ function partEvent(message, part, turn) {
20581
+ const t = part.state?.time ?? part.time;
20582
+ const base = {
20583
+ messageID: message.id,
20584
+ partID: part.id,
20585
+ turn,
20586
+ startMs: t?.start ?? message.time.created,
20587
+ ...t?.start !== undefined && t?.end !== undefined ? { durationMs: Math.max(0, t.end - t.start) } : {}
20588
+ };
20589
+ if (part.type === "tool")
20590
+ return { ...base, lane: "tools", kind: "tool", error: part.state?.status === "error", tokens: estimateTokens(part.state?.output ?? "") + estimateTokens(JSON.stringify(part.state?.input ?? "")) };
20591
+ return { ...base, lane: "model", kind: part.type === "reasoning" ? "reasoning" : "text", tokens: estimateTokens(part.text ?? "") };
20592
+ }
20593
+ function eventsOf(transcript) {
20594
+ const out = [];
20324
20595
  for (const turn of turnsOf(transcript.messages)) {
20325
- if (mode === "calls") {
20326
- let any2 = false;
20327
- for (const m of turn.assistants) {
20328
- for (const p of m.parts) {
20329
- if (p.type !== "tool")
20330
- continue;
20331
- any2 = true;
20332
- const out = p.state?.output ?? "";
20333
- const t = p.state?.time;
20334
- columns.push({ messageID: m.id, userMessageID: turn.user?.id, partID: p.id, turn: turn.index, input: m.tokens?.input ?? 0, output: 0, tool: estimateTokens(out), toolError: p.state?.status === "error", ms: t?.start !== undefined && t?.end !== undefined ? t.end - t.start : 0 });
20335
- }
20336
- }
20337
- if (!any2) {
20338
- const last2 = turn.assistants.at(-1);
20339
- columns.push({ messageID: last2?.id ?? turn.user?.id ?? "", userMessageID: turn.user?.id, turn: turn.index, input: last2?.tokens?.input ?? 0, output: last2?.tokens?.output ?? 0, tool: 0, toolError: false, ms: last2 ? spanOf(last2) : 0 });
20340
- }
20341
- continue;
20342
- }
20343
- const last = turn.assistants.at(-1);
20344
- let tool = 0;
20345
- let toolError = false;
20346
- let ms = 0;
20347
- let output2 = 0;
20596
+ if (turn.user)
20597
+ out.push(messageEvent(turn.user, turn.index));
20348
20598
  for (const m of turn.assistants) {
20349
- output2 += m.tokens?.output ?? 0;
20350
- ms += spanOf(m);
20599
+ const context = isContextMessage(m);
20600
+ if (context)
20601
+ out.push(messageEvent(m, turn.index));
20351
20602
  for (const p of m.parts) {
20352
- if (p.type !== "tool")
20603
+ const kind = stepKind(p);
20604
+ if (kind === "other" || context && kind !== "tool")
20353
20605
  continue;
20354
- tool += estimateTokens(p.state?.output ?? "");
20355
- if (p.state?.status === "error")
20356
- toolError = true;
20606
+ out.push(partEvent(m, p, turn.index));
20357
20607
  }
20358
20608
  }
20359
- columns.push({ messageID: last?.id ?? turn.user?.id ?? "", userMessageID: turn.user?.id, turn: turn.index, input: last?.tokens?.input ?? 0, output: output2, tool, toolError, ms });
20360
20609
  }
20361
- return { mode, columns };
20610
+ return out;
20362
20611
  }
20363
- var BLOCKS = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
20364
- function sparkline(values, width, scale) {
20365
- if (values.length === 0 || width <= 0)
20366
- return "";
20367
- const cells = fitColumns(values, width);
20368
- const max = Math.max(1, scale ?? 0, ...cells);
20369
- return cells.map((v) => v <= 0 ? " " : BLOCKS[Math.min(7, Math.floor(v / max * 7.999))]).join("");
20612
+ function gapBefore(events, i, mode) {
20613
+ return mode === "turns" && events[i].turn !== events[i - 1].turn ? 2 : 1;
20370
20614
  }
20371
- function fitColumns(values, width) {
20372
- if (values.length === 0)
20373
- return [];
20374
- if (values.length === width)
20375
- return values.slice();
20376
- const out = [];
20377
- if (values.length > width) {
20378
- const per = values.length / width;
20379
- for (let i = 0;i < width; i++) {
20380
- const a = Math.floor(i * per);
20381
- const b = Math.max(a + 1, Math.floor((i + 1) * per));
20382
- out.push(Math.max(...values.slice(a, b)));
20383
- }
20384
- return out;
20615
+ function firstFitting(events, mode, width) {
20616
+ let cells = 0;
20617
+ for (let i = events.length - 1;i >= 0; i--) {
20618
+ const next = cells === 0 ? 1 : cells + 1 + gapBefore(events, i + 1, mode);
20619
+ if (next > width)
20620
+ return i + 1;
20621
+ cells = next;
20385
20622
  }
20386
- const rep = width / values.length;
20387
- for (let i = 0;i < width; i++)
20388
- out.push(values[Math.min(values.length - 1, Math.floor(i / rep))]);
20389
- return out;
20623
+ return 0;
20390
20624
  }
20391
- function durationWeighted(lanes, width) {
20392
- const total = lanes.columns.reduce((s, c) => s + Math.max(1, c.ms), 0) || 1;
20393
- const input2 = [];
20394
- const output2 = [];
20395
- const tool = [];
20396
- const toolError = [];
20397
- const owner = [];
20398
- lanes.columns.forEach((c, i) => {
20399
- const cells = Math.max(1, Math.round(Math.max(1, c.ms) / total * width));
20400
- for (let k = 0;k < cells; k++) {
20401
- input2.push(c.input);
20402
- output2.push(c.output);
20403
- tool.push(c.tool);
20404
- toolError.push(c.toolError);
20405
- owner.push(i);
20406
- }
20625
+ function durationWidths(events, budget) {
20626
+ const total = events.reduce((s, e) => s + Math.max(0, e.durationMs ?? 0), 0);
20627
+ if (total <= 0)
20628
+ return events.map(() => 1);
20629
+ const widths = events.map((e) => Math.max(1, Math.round(Math.max(0, e.durationMs ?? 0) / total * budget)));
20630
+ let over = widths.reduce((s, v) => s + v, 0) - budget;
20631
+ while (over > 0) {
20632
+ let widest = -1;
20633
+ for (let i = 0;i < widths.length; i++)
20634
+ if ((widths[i] ?? 0) > 1 && (widest < 0 || (widths[i] ?? 0) > (widths[widest] ?? 0)))
20635
+ widest = i;
20636
+ if (widest < 0)
20637
+ break;
20638
+ widths[widest] = (widths[widest] ?? 1) - 1;
20639
+ over--;
20640
+ }
20641
+ return widths;
20642
+ }
20643
+ function buildEventStrip(transcript, mode, width) {
20644
+ const w = Math.max(0, Math.floor(width));
20645
+ const all = eventsOf(transcript);
20646
+ const truncatedLeft = firstFitting(all, mode, w);
20647
+ const events = all.slice(truncatedLeft);
20648
+ const gaps = events.map((_, i) => i === 0 ? 0 : gapBefore(events, i, mode));
20649
+ const widths = mode === "duration" ? durationWidths(events, w - gaps.reduce((s, g) => s + g, 0)) : events.map(() => 1);
20650
+ const blank = () => Array.from({ length: w }, () => null);
20651
+ const lanes = { input: blank(), model: blank(), tools: blank() };
20652
+ const empty = { input: true, model: true, tools: true };
20653
+ const spans = [];
20654
+ let cursor = 0;
20655
+ events.forEach((e, i) => {
20656
+ const start = cursor + (gaps[i] ?? 0);
20657
+ const end = Math.min(w, start + (widths[i] ?? 1));
20658
+ for (let c = start;c < end; c++)
20659
+ lanes[e.lane][c] = { lane: e.lane, eventIndex: i, glyph: EVENT_GLYPH, ...e.error ? { error: true } : {} };
20660
+ spans.push({ start, end });
20661
+ empty[e.lane] = false;
20662
+ cursor = start + (widths[i] ?? 1);
20407
20663
  });
20408
- return { input: input2, output: output2, tool, toolError, columnAt: (cell) => owner[Math.min(owner.length - 1, Math.max(0, cell))] ?? 0 };
20664
+ return { events, width: w, lanes, spans, empty, truncatedLeft };
20409
20665
  }
20410
- function columnFor(lanes, messageID, partID) {
20666
+ function stripIndexFor(strip, messageID, partID) {
20411
20667
  if (partID) {
20412
- const i2 = lanes.columns.findIndex((c) => c.partID === partID);
20413
- if (i2 >= 0)
20414
- return i2;
20668
+ const byPart = strip.events.findIndex((e) => e.partID === partID);
20669
+ if (byPart >= 0)
20670
+ return byPart;
20415
20671
  }
20416
- const i = lanes.columns.findIndex((c) => c.messageID === messageID || c.userMessageID === messageID);
20417
- return i >= 0 ? i : -1;
20672
+ return strip.events.findIndex((e) => e.messageID === messageID);
20418
20673
  }
20419
20674
 
20420
20675
  // src/core/consumers.ts
20676
+ var THINKING = "(thinking)";
20677
+ var THINKING_NOTE = "provider reasoning \xB7 not croppable";
20421
20678
  function consumers(transcript, opts = {}) {
20422
20679
  const acc = new Map;
20423
- const add = (source, kind, tokens) => {
20424
- const c = acc.get(source) ?? { source, kind, tokens: 0, count: 0, share: 0 };
20680
+ const add = (source, kind, tokens, message, part) => {
20681
+ const c = acc.get(source) ?? { source, kind, tokens: 0, count: 0, share: 0, entries: [] };
20425
20682
  c.tokens += tokens;
20426
20683
  c.count += 1;
20684
+ c.entries.push({
20685
+ messageID: message.id,
20686
+ partID: part.id,
20687
+ tokens,
20688
+ preview: partPreview(part),
20689
+ croppable: part.type === "tool" && part.state?.status === "completed"
20690
+ });
20427
20691
  acc.set(source, c);
20428
20692
  };
20429
20693
  for (const m of transcript.messages) {
@@ -20431,25 +20695,32 @@ function consumers(transcript, opts = {}) {
20431
20695
  if (opts.cropped?.has(p.id))
20432
20696
  continue;
20433
20697
  if (p.type === "tool")
20434
- add(p.tool ?? "tool", "tool", estimateTokens(p.state?.output ?? "") + estimateTokens(JSON.stringify(p.state?.input ?? "")));
20698
+ add(p.tool ?? "tool", "tool", estimateTokens(p.state?.output ?? "") + estimateTokens(JSON.stringify(p.state?.input ?? "")), m, p);
20435
20699
  else if (p.type === "text") {
20436
20700
  const kind = p.metadata?.["ctree"]?.kind;
20437
20701
  if (kind === "decision")
20438
- add("\u25C6 decisions", "decision", estimateTokens(p.text ?? ""));
20702
+ add("\u25C6 decisions", "decision", estimateTokens(p.text ?? ""), m, p);
20439
20703
  else if (kind === "summary")
20440
- add("\u25C7 branch summaries", "summary", estimateTokens(p.text ?? ""));
20704
+ add("\u25C7 branch summaries", "summary", estimateTokens(p.text ?? ""), m, p);
20441
20705
  else if (m.role === "user")
20442
- add("\u25CF user prompts", "user", estimateTokens(p.text ?? ""));
20706
+ add("\u25CF user prompts", "user", estimateTokens(p.text ?? ""), m, p);
20443
20707
  else if (m.summary)
20444
- add("\u25C7 compaction summaries", "summary", estimateTokens(p.text ?? ""));
20708
+ add("\u25C7 compaction summaries", "summary", estimateTokens(p.text ?? ""), m, p);
20445
20709
  else
20446
- add("\u25CB assistant text", "assistant", estimateTokens(p.text ?? ""));
20710
+ add("\u25CB assistant text", "assistant", estimateTokens(p.text ?? ""), m, p);
20447
20711
  } else if (p.type === "reasoning")
20448
- add("(thinking)", "reasoning", estimateTokens(p.text ?? ""));
20712
+ add(THINKING, "reasoning", estimateTokens(p.text ?? ""), m, p);
20449
20713
  }
20450
20714
  }
20451
20715
  const total = [...acc.values()].reduce((s, c) => s + c.tokens, 0) || 1;
20452
- return [...acc.values()].map((c) => ({ ...c, share: c.tokens / total })).sort((a, b) => b.tokens - a.tokens);
20716
+ const limit = opts.limit !== undefined && opts.limit > 0 ? opts.limit : undefined;
20717
+ return [...acc.values()].map((c) => ({
20718
+ ...c,
20719
+ share: c.tokens / total,
20720
+ ...limit === undefined ? {} : { shareOfWindow: c.tokens / limit },
20721
+ ...c.kind === "reasoning" ? { note: THINKING_NOTE } : {},
20722
+ entries: c.entries.sort((a, b) => b.tokens - a.tokens)
20723
+ })).sort((a, b) => b.tokens - a.tokens);
20453
20724
  }
20454
20725
  function bar(share, width) {
20455
20726
  const n = Math.round(share * width);
@@ -20457,8 +20728,8 @@ function bar(share, width) {
20457
20728
  }
20458
20729
 
20459
20730
  // src/tui/route.tsx
20460
- import fs4 from "fs";
20461
- import path3 from "path";
20731
+ import fs5 from "fs";
20732
+ import path4 from "path";
20462
20733
 
20463
20734
  // src/core/cropplan.ts
20464
20735
  function sha8(text) {
@@ -20688,7 +20959,14 @@ function textOf(row) {
20688
20959
  return plain(row.preview);
20689
20960
  return `assistant: ${plain(row.preview)}`;
20690
20961
  }
20962
+ function thoughtOf(row) {
20963
+ if (row.kind !== "step" || row.thinkingMs === undefined)
20964
+ return "";
20965
+ return ` \xB7 ${(row.thinkingMs / 1000).toFixed(row.thinkingMs < 1e4 ? 1 : 0)}s thought`;
20966
+ }
20691
20967
  function rowLine(row, width, here) {
20968
+ if (row.kind === "separator")
20969
+ return `${row.gutter}${row.text}`;
20692
20970
  const tokens = `${row.kind !== "branch" && row.estimated ? "~" : ""}${formatK(row.tokens)}`;
20693
20971
  const marker = here ? " \u2190 here" : "";
20694
20972
  let body;
@@ -20701,32 +20979,82 @@ function rowLine(row, width, here) {
20701
20979
  } else {
20702
20980
  const flags = row.kind === "step" ? `${row.label ? ` [${row.label}]` : ""}${row.isCropped ? " \u2702" : ""}${row.warn ? " \u26A0" : ""}${row.isError ? " \u2717" : ""}` : row.label ? ` [${row.label}]` : "";
20703
20981
  const dur = row.kind === "step" && row.durationMs !== undefined ? ` ${(row.durationMs / 1000).toFixed(row.durationMs < 1e4 ? 1 : 0)}s` : "";
20704
- body = `${row.gutter}${glyphOf(row)} ${textOf(row)}${flags}${dur}${marker}`;
20982
+ body = `${row.gutter}${glyphOf(row)} ${textOf(row)}${flags}${dur}${thoughtOf(row)}${marker}`;
20705
20983
  }
20706
20984
  return fitRow(body, tokens, width);
20707
20985
  }
20986
+ function segmentsOf(line, query, thought) {
20987
+ const ranges = [];
20988
+ if (query) {
20989
+ const at = line.toLowerCase().indexOf(query.toLowerCase());
20990
+ if (at >= 0)
20991
+ ranges.push({
20992
+ at,
20993
+ len: query.length,
20994
+ kind: "match"
20995
+ });
20996
+ }
20997
+ if (thought) {
20998
+ const at = line.lastIndexOf(thought);
20999
+ if (at >= 0)
21000
+ ranges.push({
21001
+ at,
21002
+ len: thought.length,
21003
+ kind: "dim"
21004
+ });
21005
+ }
21006
+ if (ranges.length === 0)
21007
+ return [{
21008
+ text: line,
21009
+ kind: "plain"
21010
+ }];
21011
+ const out = [];
21012
+ let cursor = 0;
21013
+ for (const r of ranges.sort((a, b) => a.at - b.at)) {
21014
+ if (r.at < cursor)
21015
+ continue;
21016
+ if (r.at > cursor)
21017
+ out.push({
21018
+ text: line.slice(cursor, r.at),
21019
+ kind: "plain"
21020
+ });
21021
+ out.push({
21022
+ text: line.slice(r.at, r.at + r.len),
21023
+ kind: r.kind
21024
+ });
21025
+ cursor = r.at + r.len;
21026
+ }
21027
+ if (cursor < line.length)
21028
+ out.push({
21029
+ text: line.slice(cursor),
21030
+ kind: "plain"
21031
+ });
21032
+ return out;
21033
+ }
20708
21034
  var DEFAULT_KEYS = {
20709
21035
  up: ["up", "k"],
20710
21036
  down: ["down", "j"],
20711
21037
  jump_up: ["shift+up", "shift+k"],
20712
21038
  jump_down: ["shift+down", "shift+j"],
20713
- first: ["g"],
21039
+ half_up: ["ctrl+u"],
21040
+ half_down: ["ctrl+d"],
21041
+ first: ["gg"],
20714
21042
  last: ["shift+g"],
20715
21043
  prev_branch: ["["],
20716
21044
  next_branch: ["]"],
20717
21045
  fold: ["left", "h"],
20718
21046
  unfold: ["right", "l"],
20719
- toggle: ["e"],
21047
+ toggle: ["tab", "e"],
20720
21048
  go: ["return"],
20721
21049
  branch: ["b"],
20722
21050
  crop: ["c"],
20723
21051
  crop_toggle_mode: ["t"],
20724
21052
  mark: ["space"],
20725
21053
  auto: ["a"],
20726
- undo: ["x"],
21054
+ undo: ["u", "x"],
20727
21055
  merge: ["m"],
20728
21056
  inspector: ["i"],
20729
- consumers: ["u"],
21057
+ consumers: ["s"],
20730
21058
  copy: ["y"],
20731
21059
  mode_duration: ["1"],
20732
21060
  mode_turns: ["2"],
@@ -20735,13 +21063,43 @@ var DEFAULT_KEYS = {
20735
21063
  decisions: ["shift+d"],
20736
21064
  export: ["shift+e"],
20737
21065
  label: ["shift+l"],
20738
- filter: ["f"],
21066
+ filter_pick: ["f"],
21067
+ filter_prev: ["shift+f"],
20739
21068
  search: ["/"],
21069
+ search_next: ["n"],
21070
+ search_prev: ["shift+n"],
20740
21071
  help: ["?", "shift+/"],
20741
21072
  back: ["q", "escape"]
20742
21073
  };
21074
+ var EMPTY_TRANSCRIPT = {
21075
+ sessionID: "",
21076
+ title: "",
21077
+ status: "available",
21078
+ messages: []
21079
+ };
20743
21080
  var NO_BRANCHES = "No branches yet \xB7 b forks here into a real OpenCode session; nothing is copied or deleted.";
20744
- var HELP = ["? help \xB7 ? or esc closes", "Reading the screen \u2014 a whole-tree outline (Pi) fused with a trajectory (DSH)", " the entire tree, oldest first: trunk at the left, branches nested at their fork point", " \u25CF user: \u2026 \xB7 \u25CB assistant: \u2026 \xB7 \u2699 [bash $ \u2026] / [tool: arg] \u2192 out \xB7 \u25C6 decision \xB7 \u2263 summary", " \u2387 = a branch: a real, separate OpenCode session, hung off the message it forked from", " \u2502 \u251C \u2570 connectors draw the branch topology; \u2190 here marks the session you are in", " \u25BE open / \u25B8 folded \u2014 the path to where you are is open by default; \u2192 \u2190 (or e) toggle a branch", " right column is tokens; ~ means estimated \xB7 \u26A0 \u226510k \xB7 \u2702 cropped \xB7 \u2717 tool error", "Keys", " move \u2191\u2193 j k \xB7 J K by 20 \xB7 g G first/last \xB7 [ ] branch rows \xB7 \u2192 \u2190 e fold", " act \u23CE go/switch \xB7 b branch \xB7 m merge \xB7 c crop \xB7 x undo \xB7 L label \xB7 y copy", " in crop mode: space mark \xB7 a auto \xB7 t result\u21C4turn \xB7 \u23CE apply \xB7 esc leave", " DSH i inspector (Status/Payload/Result/Timing) \xB7 1 2 3 lanes (Duration/Turns/Calls) \xB7 0 off", " views u consumers \xB7 D decisions \xB7 E export \xB7 f filter \xB7 / search \xB7 q back"];
21081
+ var HELP = ["? help \xB7 ? or esc closes", "Move", " \u2191\u2193 j k \xB7 J K by 20 \xB7 ctrl+d ctrl+u half page \xB7 gg top \xB7 G bottom \xB7 [ ] branch rows", " h l \u2190 \u2192 fold/unfold a branch \xB7 Tab (or e) toggle \xB7 / live search \xB7 n N next/prev match", "Act", " \u23CE go \u2014 a \u2387 header switches to it \xB7 a user turn forks & prefills it \xB7 a step forks after it", " b branch \xB7 m merge \xB7 c crop mode (space mark \xB7 a auto \xB7 t result\u21C4turn \xB7 \u23CE apply \xB7 esc leave)", " u undo (alias x) \xB7 L label \xB7 y copy \xB7 E export decisions", "Views", " i inspector \xB7 1 2 3 lanes (duration/turns/calls) \xB7 0 off \xB7 s consumers \xB7 D decisions \xB7 f F filter", "Legend", " \u25CF user \xB7 \u25CB assistant \xB7 \u2699 tool step \xB7 \u25C6 decision \xB7 \u2263 summary \xB7 \u2387 branch (a real OpenCode session)", " \u2502 \u251C \u2570 draw the topology \xB7 \u25BE open \u25B8 folded \xB7 \u2190 here is the session you are in", " dim rows are not sent to the model; \u2500\u2500 not in this branch's context \u2500\u2500 is where your path forked", " right column is tokens; ~ estimated \xB7 \u26A0 \u226510k \xB7 \u2702 cropped \xB7 \u2717 tool error", " \u2387 colours: open green \xB7 squashed blue \xB7 rejected/discarded red \xB7 abandoned grey"];
21082
+ var FILTERS = [{
21083
+ title: "default",
21084
+ value: "default",
21085
+ description: "user turns, assistant text, tool steps"
21086
+ }, {
21087
+ title: "no-tools",
21088
+ value: "no-tools",
21089
+ description: "hide \u2699 tool steps"
21090
+ }, {
21091
+ title: "user-only",
21092
+ value: "user-only",
21093
+ description: "\u25CF user turns only"
21094
+ }, {
21095
+ title: "labeled",
21096
+ value: "labeled",
21097
+ description: "labelled rows only"
21098
+ }, {
21099
+ title: "all",
21100
+ value: "all",
21101
+ description: "everything, thinking parts included"
21102
+ }];
20745
21103
  function bindingsFor(overrides) {
20746
21104
  const out = [];
20747
21105
  for (const [cmd, keys] of Object.entries(DEFAULT_KEYS))
@@ -20773,6 +21131,8 @@ function TreeRoute(props) {
20773
21131
  const [expanded, setExpanded] = createSignal2(new Set(api2.kv.get(`ctree.expanded.${sessionID}`, [])));
20774
21132
  const [filter, setFilter] = createSignal2(api2.kv.get("ctree.filter", "default"));
20775
21133
  const [search, setSearch] = createSignal2("");
21134
+ const [searchMode, setSearchMode] = createSignal2(false);
21135
+ let searchBefore = "";
20776
21136
  const [selected, setSelected] = createSignal2(0);
20777
21137
  const [others, setOthers] = createSignal2({});
20778
21138
  const [busy, setBusy] = createSignal2();
@@ -20782,7 +21142,9 @@ function TreeRoute(props) {
20782
21142
  const [lanesOn, setLanesOn] = createSignal2(api2.kv.get("ctree.lanesOn", false));
20783
21143
  const [inspector, setInspector] = createSignal2(api2.kv.get("ctree.inspector", false));
20784
21144
  const [consumerIndex, setConsumerIndex] = createSignal2(0);
21145
+ const [consumerOpen, setConsumerOpen] = createSignal2(new Set);
20785
21146
  const [decisionIndex, setDecisionIndex] = createSignal2(0);
21147
+ const [decisionScroll, setDecisionScroll] = createSignal2(0);
20786
21148
  const [marked, setMarked] = createSignal2(new Set);
20787
21149
  const state = createMemo(() => {
20788
21150
  tick();
@@ -20897,19 +21259,23 @@ function TreeRoute(props) {
20897
21259
  api2.renderer.on("resize", onResize);
20898
21260
  onCleanup(() => void api2.renderer.off("resize", onResize));
20899
21261
  const cols = () => size().cols;
20900
- const height = () => Math.max(8, size().rows - 8 - (lanesOn() && size().rows >= 12 ? 3 : 0));
21262
+ const helpHeight = () => panel() === "help" ? Math.min(HELP.length, Math.max(0, size().rows - 12)) : 0;
21263
+ const height = () => Math.max(4, size().rows - 8 - (lanesOn() && size().rows >= 12 ? 3 : 0) - helpHeight());
20901
21264
  const width = () => Math.max(60, cols() - 4);
21265
+ const overflow = () => view().rows.length > height() - 2;
21266
+ const rowsHeight = () => overflow() ? height() - 2 : height();
20902
21267
  const windowStart = createMemo(() => {
20903
- const h = height();
21268
+ const h = rowsHeight();
20904
21269
  const s = selected();
20905
21270
  const n = view().rows.length;
20906
- const start = Math.max(0, Math.min(s - Math.floor(h / 2), n - h));
20907
- return start;
21271
+ return Math.max(0, Math.min(s - Math.floor(h / 2), n - h));
20908
21272
  });
20909
- const visible = createMemo(() => view().rows.slice(windowStart(), windowStart() + height()));
21273
+ const visible = createMemo(() => view().rows.slice(windowStart(), windowStart() + rowsHeight()));
21274
+ const hiddenAbove = () => windowStart();
21275
+ const hiddenBelow = () => Math.max(0, view().rows.length - windowStart() - rowsHeight());
20910
21276
  const live = () => sessionID ? liveTranscript(api2, sessionID) : undefined;
20911
21277
  const currentMessageOf = (row) => {
20912
- if (row.kind === "branch")
21278
+ if (row.kind === "branch" || row.kind === "separator")
20913
21279
  return;
20914
21280
  if (row.sessionID === sessionID)
20915
21281
  return row.messageID;
@@ -20954,10 +21320,35 @@ function TreeRoute(props) {
20954
21320
  const list = cropMode() === "result" ? resultCands() : turnCands();
20955
21321
  return list.filter((c) => m.has(markKey(c)));
20956
21322
  });
21323
+ function modeForRow(row) {
21324
+ if (row.kind === "step" && resultCands().some((c) => c.partID === (currentPartOf(row) ?? row.partID)))
21325
+ return "result";
21326
+ if (row.kind !== "branch" && row.kind !== "separator" && turnCands().some((c) => c.anchorMessageID === currentMessageOf(row)))
21327
+ return "turn";
21328
+ return;
21329
+ }
21330
+ const armed = () => {
21331
+ const row = current();
21332
+ const c = row ? candidateOf(row) : undefined;
21333
+ if (!c)
21334
+ return false;
21335
+ const key = markKey(c);
21336
+ return marked().has(`${key}:warned`) && !marked().has(key);
21337
+ };
20957
21338
  function toggleMark() {
20958
21339
  const row = current();
20959
21340
  if (!row)
20960
21341
  return;
21342
+ if (!cropMode()) {
21343
+ const mode = modeForRow(row);
21344
+ if (!mode) {
21345
+ api2.ui.toast({
21346
+ message: "nothing croppable on this row \u2014 c opens crop mode"
21347
+ });
21348
+ return;
21349
+ }
21350
+ setCropMode(mode);
21351
+ }
20961
21352
  const c = candidateOf(row);
20962
21353
  debug("crop.mark", {
20963
21354
  row: row.id,
@@ -20989,6 +21380,13 @@ function TreeRoute(props) {
20989
21380
  next.add(key);
20990
21381
  setMarked(next);
20991
21382
  }
21383
+ async function leaveCropMode() {
21384
+ const n = selectedCandidates().length;
21385
+ if (n > 0 && !await confirm(`Drop ${n} mark${n === 1 ? "" : "s"}?`, "Nothing has been cropped yet \u2014 the marks are lost, the transcript is untouched."))
21386
+ return;
21387
+ setCropMode(undefined);
21388
+ setMarked(new Set);
21389
+ }
20992
21390
  function autoMarkAll() {
20993
21391
  if (cropMode() !== "result")
20994
21392
  return;
@@ -21066,69 +21464,54 @@ function TreeRoute(props) {
21066
21464
  },
21067
21465
  parts: m.parts
21068
21466
  }))));
21069
- const band = () => bandFor(contextSize().tokens);
21467
+ const band = () => bandFor(contextSize().tokens, contextLimit());
21070
21468
  const branchOfCurrent = () => sessionID ? state().sessions[sessionID] : undefined;
21071
21469
  const userTurns = () => (live()?.messages ?? []).filter((m) => m.role === "user").length;
21072
- const lanes = createMemo(() => live() ? buildLanes(live(), laneMode() === "duration" ? "turns" : laneMode()) : {
21073
- mode: laneMode(),
21074
- columns: []
21075
- });
21076
21470
  const laneWidth = () => Math.max(10, Math.min(width() - 46, 80));
21077
- const laneSeries = createMemo(() => {
21078
- const l = lanes();
21079
- if (laneMode() === "duration") {
21080
- const w = durationWeighted(l, laneWidth());
21081
- return {
21082
- input: w.input,
21083
- output: w.output,
21084
- tool: w.tool,
21085
- toolError: w.toolError,
21086
- cellFor: (col) => w.input.findIndex((_, i) => w.columnAt(i) === col)
21087
- };
21088
- }
21089
- const n = l.columns.length;
21090
- const cellFor = (col) => n === 0 ? -1 : Math.floor(col * laneWidth() / Math.max(n, laneWidth())) + (n < laneWidth() ? Math.floor(laneWidth() / n / 2) : 0);
21091
- return {
21092
- input: l.columns.map((c) => c.input),
21093
- output: l.columns.map((c) => c.output),
21094
- tool: l.columns.map((c) => c.tool),
21095
- toolError: l.columns.map((c) => c.toolError),
21096
- cellFor
21097
- };
21098
- });
21099
- const cursorCell = createMemo(() => {
21471
+ const strip = createMemo(() => buildEventStrip(live() ?? EMPTY_TRANSCRIPT, laneMode(), laneWidth()));
21472
+ const cursorEvent = createMemo(() => {
21100
21473
  const row = current();
21101
- if (!row || row.kind === "branch")
21474
+ if (!row || row.kind === "branch" || row.kind === "separator")
21102
21475
  return -1;
21103
21476
  const mid = currentMessageOf(row) ?? row.messageID;
21104
21477
  const pid = row.kind === "step" ? currentPartOf(row) ?? row.partID : undefined;
21105
- const col = columnFor(lanes(), mid, pid);
21106
- return col < 0 ? -1 : laneSeries().cellFor(col);
21478
+ return stripIndexFor(strip(), mid, pid);
21107
21479
  });
21108
- const laneLine = (values, scale) => {
21109
- const line = sparkline(fitColumns(values, laneWidth()), laneWidth(), scale);
21110
- const cur = cursorCell();
21111
- if (cur < 0 || cur >= line.length)
21112
- return line;
21113
- return `${line.slice(0, cur)}\u25AE${line.slice(cur + 1)}`;
21114
- };
21115
- const toolRuns = createMemo(() => {
21116
- const line = laneLine(laneSeries().tool);
21117
- const mask = fitColumns(laneSeries().toolError.map((e) => e ? 1 : 0), laneWidth());
21480
+ const cellColor = (cell) => {
21481
+ if (cell.error)
21482
+ return t.error;
21483
+ const e = strip().events[cell.eventIndex];
21484
+ if (!e)
21485
+ return t.textMuted;
21486
+ if (e.lane === "tools")
21487
+ return t.warning;
21488
+ if (e.lane === "input")
21489
+ return e.kind === "user" ? t.success : t.textMuted;
21490
+ return e.kind === "reasoning" ? t.textMuted : t.accent;
21491
+ };
21492
+ const laneRuns = (lane) => {
21493
+ const cur = cursorEvent();
21118
21494
  const runs = [];
21119
- for (let i = 0;i < line.length; i++) {
21120
- const error61 = (mask[i] ?? 0) > 0;
21495
+ for (const cell of strip().lanes[lane]) {
21496
+ const sel = cell !== null && cell.eventIndex === cur;
21497
+ const color = cell === null ? t.textMuted : cellColor(cell);
21498
+ const fg = sel ? t.background : color;
21499
+ const bg = sel ? color : undefined;
21121
21500
  const last = runs[runs.length - 1];
21122
- if (last && last.error === error61)
21123
- last.text += line[i];
21501
+ if (last && last.fg === fg && last.bg === bg)
21502
+ last.text += cell?.glyph ?? " ";
21124
21503
  else
21125
21504
  runs.push({
21126
- text: line[i],
21127
- error: error61
21505
+ text: cell?.glyph ?? " ",
21506
+ fg,
21507
+ bg
21128
21508
  });
21129
21509
  }
21130
21510
  return runs;
21131
- });
21511
+ };
21512
+ const inputRuns = createMemo(() => laneRuns("input"));
21513
+ const modelRuns = createMemo(() => laneRuns("model"));
21514
+ const toolRuns = createMemo(() => laneRuns("tools"));
21132
21515
  const contextLimit = createMemo(() => sessionID ? modelContextLimit(api2, sessionID) : undefined);
21133
21516
  const laneRoom = () => height() >= 12 && panel() === "tree";
21134
21517
  const showLanes = () => laneRoom() && lanesOn() && userTurns() >= 3;
@@ -21150,7 +21533,7 @@ function TreeRoute(props) {
21150
21533
  const noBranchesLines = () => NO_BRANCHES.length + 2 <= rowWidth() ? [NO_BRANCHES] : NO_BRANCHES.split(/(?<=;) /);
21151
21534
  const inspectorLines = createMemo(() => {
21152
21535
  const row = current();
21153
- if (!row)
21536
+ if (!row || row.kind === "separator")
21154
21537
  return [];
21155
21538
  const w = inspectorWidth() - 3;
21156
21539
  const clip2 = (x) => x.length > w ? `${x.slice(0, w - 1)}\u2026` : x;
@@ -21197,19 +21580,37 @@ function TreeRoute(props) {
21197
21580
  const msg = tr?.messages.find((m) => m.id === row.messageID);
21198
21581
  const turn = view().rows.slice(0, view().indexById[row.id] + 1).filter((r) => r.kind === "turn").at(-1);
21199
21582
  if (row.kind === "turn") {
21200
- head(`${row.isDecision ? "\u25C6 decision" : row.isSummary ? "\u25C7 summary" : "\u25CF user"} \xB7 T${row.turn}`);
21583
+ const text = msg?.parts.map((p) => p.text ?? "").join(`
21584
+ `) ?? row.preview;
21585
+ if (row.isDecision) {
21586
+ head(`\u25C6 ${decisionSummary(text).title}`);
21587
+ kv("Tokens", `~${formatK(row.tokens)}`);
21588
+ const lines = renderDecision(text, w);
21589
+ for (const l of lines.slice(0, 16))
21590
+ out.push({
21591
+ fg: t.text,
21592
+ text: l
21593
+ });
21594
+ if (lines.length > 16)
21595
+ muted(`\u2026 ${lines.length - 16} more lines (y to copy)`);
21596
+ return out;
21597
+ }
21598
+ head(`${row.isSummary ? "\u25C7 summary" : "\u25CF user"} \xB7 T${row.turn}`);
21201
21599
  if (row.label)
21202
21600
  kv("Label", row.label);
21203
21601
  kv("Tokens", `~${formatK(row.tokens)}`);
21204
21602
  kv("At", msg ? new Date(msg.time.created).toISOString().slice(11, 19) : "?");
21205
- block("Text", msg?.parts.map((p) => p.text ?? "").join(`
21206
- `) ?? row.preview, 14);
21603
+ if (!row.inContext)
21604
+ muted("not in this branch's context");
21605
+ block("Text", text, 14);
21207
21606
  return out;
21208
21607
  }
21209
21608
  const part = msg?.parts.find((p) => p.id === row.partID);
21210
21609
  const stepNo = msg ? msg.parts.filter((p) => p.type === "tool" || p.type === "text").findIndex((p) => p.id === row.partID) + 1 : 0;
21211
21610
  head(`${row.glyph} ${part?.type === "tool" ? part.tool : row.glyph === "\u25C7" ? "compaction" : "assistant"} \xB7 T${turn?.kind === "turn" ? turn.turn : "?"} \xB7 step ${stepNo}`);
21212
21611
  kv("Hierarchy", `T${turn?.kind === "turn" ? turn.turn : "?"} \u203A assistant \u203A step ${stepNo}`);
21612
+ if (!row.inContext)
21613
+ muted("not in this branch's context");
21213
21614
  if (part?.type === "tool") {
21214
21615
  const st = part.state;
21215
21616
  const dur = st?.time?.start !== undefined && st?.time?.end !== undefined ? `${st.time.end - st.time.start} ms` : "?";
@@ -21219,25 +21620,66 @@ function TreeRoute(props) {
21219
21620
  block("Result", String(st?.output ?? ""), 10);
21220
21621
  kv("Timing", st?.time?.start ? `started ${new Date(st.time.start).toISOString().slice(11, 23)} \xB7 ${dur} \xB7 session ts` : "n/a");
21221
21622
  const cand = resultCands().find((c) => c.partID === (currentPartOf(row) ?? row.partID));
21222
- kv("Crop", row.isCropped ? "\u2702 cropped (x to restore)" : cand ? cand.protections.length ? `protected: ${cand.protections.join(", ")}` : "c then space to stub this result" : "n/a");
21623
+ kv("Crop", row.isCropped ? `\u2702 cropped (${UNDO_KEY} to restore)` : cand ? cand.protections.length ? `protected: ${cand.protections.join(", ")}` : "c then space to stub this result" : "n/a");
21223
21624
  } else {
21224
21625
  kv("Tokens", `~${formatK(row.tokens)}`);
21225
21626
  if (row.durationMs !== undefined)
21226
21627
  kv("Duration", `${(row.durationMs / 1000).toFixed(1)} s`);
21628
+ if (row.thinkingMs !== undefined)
21629
+ kv("Thought", `${(row.thinkingMs / 1000).toFixed(1)} s`);
21227
21630
  block("Text", part?.text ?? row.preview, 14);
21228
21631
  }
21229
21632
  return out;
21230
21633
  });
21231
21634
  const consumerRows = createMemo(() => live() ? consumers(live(), {
21232
- cropped: alreadyCropped()
21635
+ cropped: alreadyCropped(),
21636
+ limit: contextLimit()
21233
21637
  }) : []);
21638
+ const consumerLines = createMemo(() => consumerRows().flatMap((c) => [{
21639
+ bucket: c
21640
+ }, ...consumerOpen().has(c.source) ? c.entries.map((e) => ({
21641
+ bucket: c,
21642
+ entry: e
21643
+ })) : []]));
21644
+ const consumerLine = () => consumerLines()[Math.min(consumerIndex(), consumerLines().length - 1)];
21645
+ const consumerMax = () => Math.max(1, ...consumerRows().map((c) => c.tokens));
21646
+ function toggleConsumer(open2) {
21647
+ const line = consumerLine();
21648
+ if (!line)
21649
+ return;
21650
+ const next = new Set(consumerOpen());
21651
+ if (open2)
21652
+ next.add(line.bucket.source);
21653
+ else
21654
+ next.delete(line.bucket.source);
21655
+ setConsumerOpen(next);
21656
+ }
21657
+ function markConsumerEntry() {
21658
+ const line = consumerLine();
21659
+ if (!line)
21660
+ return;
21661
+ if (!line.entry) {
21662
+ toggleConsumer(true);
21663
+ return;
21664
+ }
21665
+ const cand = line.entry.croppable ? resultCands().find((r) => r.partID === line.entry?.partID) : undefined;
21666
+ if (!cand)
21667
+ return;
21668
+ setCropMode("result");
21669
+ const next = new Set(marked());
21670
+ if (next.has(cand.partID))
21671
+ next.delete(cand.partID);
21672
+ else
21673
+ next.add(cand.partID);
21674
+ setMarked(next);
21675
+ }
21234
21676
  function cropConsumer() {
21235
- const c = consumerRows()[consumerIndex()];
21677
+ const c = consumerLine()?.bucket;
21236
21678
  setPanel("tree");
21237
21679
  if (!c || c.kind !== "tool") {
21238
21680
  setCropMode("result");
21239
21681
  api2.ui.toast({
21240
- message: c ? `${c.source} is not a tool result; mark rows by hand` : "nothing to crop"
21682
+ message: c ? c.note ?? `${c.source} is not a tool result; mark rows by hand` : "nothing to crop"
21241
21683
  });
21242
21684
  return;
21243
21685
  }
@@ -21250,20 +21692,18 @@ function TreeRoute(props) {
21250
21692
  }
21251
21693
  function copySelected() {
21252
21694
  const row = current();
21253
- if (!row || row.kind === "branch")
21695
+ if (!row || row.kind === "branch" || row.kind === "separator")
21254
21696
  return;
21255
21697
  const tr = row.sessionID === sessionID ? live() : others()[row.sessionID];
21256
21698
  const msg = tr?.messages.find((m) => m.id === row.messageID);
21257
21699
  const text = row.kind === "step" ? String(msg?.parts.find((p) => p.id === row.partID)?.state?.output ?? msg?.parts.find((p) => p.id === row.partID)?.text ?? "") : msg?.parts.map((p) => p.text ?? "").join(`
21258
21700
  `) ?? "";
21259
- const file2 = path3.join(directory, ".opencode", "context-tree", "last-copy.txt");
21260
21701
  try {
21261
- fs4.mkdirSync(path3.dirname(file2), {
21262
- recursive: true
21263
- });
21264
- fs4.writeFileSync(file2, text);
21702
+ const {
21703
+ hint
21704
+ } = copyText(api2, text, directory);
21265
21705
  api2.ui.toast({
21266
- message: `saved ${text.length} chars \u2192 .opencode/context-tree/last-copy.txt`
21706
+ message: `copied ${text.length} chars \u2192 ${hint}`
21267
21707
  });
21268
21708
  } catch (e) {
21269
21709
  api2.ui.toast({
@@ -21389,6 +21829,10 @@ function TreeRoute(props) {
21389
21829
  bump();
21390
21830
  }
21391
21831
  }
21832
+ const sessionLabel = (id) => {
21833
+ const name = state().sessions[id]?.name;
21834
+ return name ? `\u2387 ${name}` : others()[id]?.title ?? api2.state.session.get(id)?.title ?? id;
21835
+ };
21392
21836
  async function jump() {
21393
21837
  const row = current();
21394
21838
  if (!row || !sessionID)
@@ -21411,16 +21855,19 @@ function TreeRoute(props) {
21411
21855
  });
21412
21856
  return;
21413
21857
  }
21414
- if (plan.kind === "fork" && plan.mode === "redo") {
21415
- const ok = await confirm("Redo this turn on a new branch?", "The message is copied into the prompt; nothing is deleted.");
21416
- if (!ok)
21417
- return;
21418
- }
21858
+ const from = sessionLabel(plan.sessionID);
21859
+ const ok = await confirm(plan.kind === "switch" ? `Switch to ${from}?` : plan.mode === "redo" ? "Fork & prefill this turn?" : "Fork after this step?", plan.kind === "switch" ? `The session you are on now stays exactly as it is. ${UNDO_KEY} undoes this.` : `A new OpenCode session forks from ${from} at this point; nothing is deleted. ${UNDO_KEY} undoes this.`);
21860
+ if (!ok)
21861
+ return;
21419
21862
  const summary = await askSummary();
21420
- await executeJump(ctx, plan, {
21863
+ const target2 = await executeJump(ctx, plan, {
21421
21864
  currentSessionID: sessionID,
21422
21865
  summary
21423
21866
  });
21867
+ if (target2)
21868
+ api2.ui.toast({
21869
+ message: `moved to ${sessionLabel(target2)} \xB7 ${UNDO_KEY} undoes it`
21870
+ });
21424
21871
  });
21425
21872
  }
21426
21873
  async function branch() {
@@ -21473,7 +21920,7 @@ function TreeRoute(props) {
21473
21920
  }
21474
21921
  async function label() {
21475
21922
  const row = current();
21476
- if (!row || row.kind === "branch")
21923
+ if (!row || row.kind === "branch" || row.kind === "separator")
21477
21924
  return;
21478
21925
  const st = state();
21479
21926
  const existing = st.labels[row.messageID]?.label;
@@ -21491,7 +21938,7 @@ function TreeRoute(props) {
21491
21938
  const row = current();
21492
21939
  if (!row)
21493
21940
  return;
21494
- const target2 = row.kind === "branch" ? row.sessionID : row.depth > 0 ? row.sessionID : undefined;
21941
+ const target2 = row.kind === "separator" ? undefined : row.kind === "branch" || row.depth > 0 ? row.sessionID : undefined;
21495
21942
  if (!target2)
21496
21943
  return;
21497
21944
  const shown = row.kind === "branch" ? row.expanded : true;
@@ -21525,14 +21972,18 @@ function TreeRoute(props) {
21525
21972
  return;
21526
21973
  }
21527
21974
  const siblings = Object.values(state().sessions).filter((x) => x.parentSessionID === b.parentSessionID && x.sessionID !== sessionID && x.status === "open").length;
21528
- const mode = await select(mergeDialogTitle(b.name ?? "branch", others()[b.parentSessionID]?.title), mergeDialogOptions({
21529
- siblings
21975
+ const parent = others()[b.parentSessionID];
21976
+ const target2 = mergeTargetOf(b.parentSessionID === state().root ? TRUNK_LABEL : state().sessions[b.parentSessionID]?.name ?? TRUNK_LABEL, parent?.messages ?? []);
21977
+ const turns = ownTurnCount(live()?.messages ?? [], {
21978
+ messageID: b.anchorMessageID,
21979
+ parentMessageIDs: parent?.messages.map((m) => m.id) ?? []
21980
+ });
21981
+ const mode = await select(mergeDialogTitle(b.name ?? "branch", target2), mergeDialogOptions({
21982
+ siblings,
21983
+ turns
21530
21984
  }));
21531
21985
  if (!mode)
21532
21986
  return;
21533
- let note;
21534
- if (mode === "discard")
21535
- note = await prompt("Why? (optional note on the close marker)", "dead end") ?? undefined;
21536
21987
  const inApp = !hasEditor() ? async (draft) => {
21537
21988
  const ok = await confirm("Accept the drafted record as-is?", `${draft.slice(0, 400)}${draft.length > 400 ? "\u2026" : ""}
21538
21989
 
@@ -21545,7 +21996,6 @@ ${MERGE_TRUST}
21545
21996
  await mergeBranch(ctx, {
21546
21997
  sessionID,
21547
21998
  mode,
21548
- note,
21549
21999
  confirm: inApp
21550
22000
  });
21551
22001
  });
@@ -21557,9 +22007,9 @@ ${MERGE_TRUST}
21557
22007
  sessionID: d.sessionID,
21558
22008
  at: d.recordedAt
21559
22009
  }));
21560
- const file2 = path3.join(directory, "ctree-decisions.md");
22010
+ const file2 = path4.join(directory, "ctree-decisions.md");
21561
22011
  try {
21562
- fs4.writeFileSync(file2, exportDecisions(records));
22012
+ fs5.writeFileSync(file2, exportDecisions(records));
21563
22013
  api2.ui.toast({
21564
22014
  variant: "success",
21565
22015
  message: `wrote ${records.length} record${records.length === 1 ? "" : "s"} \u2192 ${file2}`
@@ -21575,7 +22025,7 @@ ${MERGE_TRUST}
21575
22025
  const d = decisions()[decisionIndex()];
21576
22026
  if (!d)
21577
22027
  return;
21578
- const idx = view().rows.findIndex((r) => r.kind !== "branch" && r.messageID === d.messageID);
22028
+ const idx = view().rows.findIndex((r) => (r.kind === "turn" || r.kind === "step") && r.messageID === d.messageID);
21579
22029
  setPanel("tree");
21580
22030
  if (idx >= 0)
21581
22031
  setSelected(idx);
@@ -21584,125 +22034,251 @@ ${MERGE_TRUST}
21584
22034
  message: "that record lives in another session"
21585
22035
  });
21586
22036
  }
22037
+ const treePanel = () => panel() === "tree";
22038
+ const inCrop = () => cropMode() !== undefined;
22039
+ const treeIdle = () => treePanel() && !inCrop();
22040
+ const listPanel = () => treePanel() || panel() === "consumers";
22041
+ function setFilterTo(next) {
22042
+ setFilter(next);
22043
+ api2.kv.set("ctree.filter", next);
22044
+ }
22045
+ async function pickFilter() {
22046
+ const next = await select("Filter rows", FILTERS.map((f) => ({
22047
+ title: `${f.value === filter() ? "\u25CF" : " "} ${f.title}`,
22048
+ value: f.value,
22049
+ description: f.description
22050
+ })));
22051
+ if (next)
22052
+ setFilterTo(next);
22053
+ }
22054
+ function moveIndex(delta) {
22055
+ if (panel() === "decisions") {
22056
+ setDecisionIndex((i) => Math.min(Math.max(0, decisions().length - 1), Math.max(0, i + delta)));
22057
+ setDecisionScroll(0);
22058
+ return;
22059
+ }
22060
+ if (panel() === "consumers") {
22061
+ setConsumerIndex((i) => Math.min(Math.max(0, consumerLines().length - 1), Math.max(0, i + delta)));
22062
+ return;
22063
+ }
22064
+ setSelected((i) => moveSelection(view().rows, i, delta));
22065
+ }
22066
+ function halfPage(dir) {
22067
+ const half = Math.max(1, Math.floor(height() / 2));
22068
+ if (panel() === "decisions")
22069
+ setDecisionScroll((s) => Math.max(0, s + dir * half));
22070
+ else
22071
+ moveIndex(dir * half);
22072
+ }
22073
+ function gotoEdge(dir) {
22074
+ if (panel() === "decisions") {
22075
+ setDecisionIndex(dir === -1 ? 0 : Math.max(0, decisions().length - 1));
22076
+ setDecisionScroll(0);
22077
+ return;
22078
+ }
22079
+ if (panel() === "consumers") {
22080
+ setConsumerIndex(dir === -1 ? 0 : Math.max(0, consumerLines().length - 1));
22081
+ return;
22082
+ }
22083
+ const i = dir === -1 ? firstIndex(view().rows) : lastIndex(view().rows);
22084
+ if (i >= 0)
22085
+ setSelected(i);
22086
+ }
22087
+ const matchIn = (line) => {
22088
+ const q = search().trim().toLowerCase();
22089
+ return q ? line.toLowerCase().indexOf(q) : -1;
22090
+ };
22091
+ function moveMatch(dir) {
22092
+ const rows = view().rows;
22093
+ const q = search().trim();
22094
+ if (rows.length === 0 || !q)
22095
+ return;
22096
+ for (let step = 1;step <= rows.length; step++) {
22097
+ const i = ((selected() + dir * step) % rows.length + rows.length) % rows.length;
22098
+ if (rows[i].kind !== "separator" && matchIn(rowLine(rows[i], rowWidth(), false)) >= 0) {
22099
+ setSelected(i);
22100
+ return;
22101
+ }
22102
+ }
22103
+ api2.ui.toast({
22104
+ message: `no other row matches "${q}"`
22105
+ });
22106
+ }
22107
+ function enterSearch() {
22108
+ searchBefore = search();
22109
+ setSearchMode(true);
22110
+ }
22111
+ function exitSearch(commit) {
22112
+ if (!commit)
22113
+ setSearch(searchBefore);
22114
+ setSearchMode(false);
22115
+ }
22116
+ const stopTyping = api2.keymap.intercept("key", (input2) => {
22117
+ if (!searchMode())
22118
+ return;
22119
+ const ev = input2.event;
22120
+ if (ev.eventType === "release" || ev.ctrl || ev.meta)
22121
+ return;
22122
+ const take = () => input2.consume({
22123
+ preventDefault: true,
22124
+ stopPropagation: true
22125
+ });
22126
+ if (ev.name === "escape")
22127
+ return void (exitSearch(false), take());
22128
+ if (ev.name === "return" || ev.name === "enter")
22129
+ return void (exitSearch(true), take());
22130
+ if (ev.name === "backspace")
22131
+ return void (setSearch((q) => q.slice(0, -1)), take());
22132
+ const char = ev.sequence?.length === 1 && ev.sequence >= " " && ev.sequence !== "\x7F" ? ev.sequence : ev.name.length === 1 ? ev.name : undefined;
22133
+ if (char === undefined)
22134
+ return;
22135
+ setSearch((q) => q + char);
22136
+ take();
22137
+ });
22138
+ onCleanup(() => stopTyping());
21587
22139
  const off = api2.keymap.registerLayer({
21588
22140
  mode: "base",
21589
22141
  commands: [{
21590
22142
  name: "ctree.up",
21591
22143
  hidden: true,
21592
- run: () => panel() === "decisions" ? setDecisionIndex((i) => Math.max(0, i - 1)) : panel() === "consumers" ? setConsumerIndex((i) => Math.max(0, i - 1)) : setSelected((i) => moveSelection(view().rows, i, -1))
22144
+ run: () => moveIndex(-1)
21593
22145
  }, {
21594
22146
  name: "ctree.down",
21595
22147
  hidden: true,
21596
- run: () => panel() === "decisions" ? setDecisionIndex((i) => Math.min(Math.max(0, decisions().length - 1), i + 1)) : panel() === "consumers" ? setConsumerIndex((i) => Math.min(Math.max(0, consumerRows().length - 1), i + 1)) : setSelected((i) => moveSelection(view().rows, i, 1))
22148
+ run: () => moveIndex(1)
21597
22149
  }, {
21598
22150
  name: "ctree.jump_up",
21599
22151
  hidden: true,
21600
- run: () => setSelected((i) => moveSelection(view().rows, i, -20))
22152
+ enabled: treePanel,
22153
+ run: () => moveIndex(-20)
21601
22154
  }, {
21602
22155
  name: "ctree.jump_down",
21603
22156
  hidden: true,
21604
- run: () => setSelected((i) => moveSelection(view().rows, i, 20))
22157
+ enabled: treePanel,
22158
+ run: () => moveIndex(20)
22159
+ }, {
22160
+ name: "ctree.half_up",
22161
+ hidden: true,
22162
+ run: () => halfPage(-1)
22163
+ }, {
22164
+ name: "ctree.half_down",
22165
+ hidden: true,
22166
+ run: () => halfPage(1)
21605
22167
  }, {
21606
22168
  name: "ctree.first",
21607
22169
  hidden: true,
21608
- run: () => setSelected(0)
22170
+ run: () => gotoEdge(-1)
21609
22171
  }, {
21610
22172
  name: "ctree.last",
21611
22173
  hidden: true,
21612
- run: () => setSelected(Math.max(0, view().rows.length - 1))
22174
+ run: () => gotoEdge(1)
21613
22175
  }, {
21614
22176
  name: "ctree.prev_branch",
21615
22177
  hidden: true,
22178
+ enabled: treePanel,
21616
22179
  run: () => setSelected((i) => nextBranchIndex(view().rows, i, -1))
21617
22180
  }, {
21618
22181
  name: "ctree.next_branch",
21619
22182
  hidden: true,
22183
+ enabled: treePanel,
21620
22184
  run: () => setSelected((i) => nextBranchIndex(view().rows, i, 1))
21621
22185
  }, {
21622
22186
  name: "ctree.fold",
21623
22187
  hidden: true,
21624
- run: () => foldOrUnfold(false)
22188
+ enabled: listPanel,
22189
+ run: () => panel() === "consumers" ? toggleConsumer(false) : foldOrUnfold(false)
21625
22190
  }, {
21626
22191
  name: "ctree.unfold",
21627
22192
  hidden: true,
21628
- run: () => foldOrUnfold(true)
22193
+ enabled: listPanel,
22194
+ run: () => panel() === "consumers" ? toggleConsumer(true) : foldOrUnfold(true)
21629
22195
  }, {
21630
22196
  name: "ctree.toggle",
21631
22197
  hidden: true,
22198
+ enabled: treePanel,
21632
22199
  run: () => foldOrUnfold(!(current()?.kind === "branch" && current().expanded))
21633
22200
  }, {
21634
22201
  name: "ctree.go",
21635
22202
  hidden: true,
21636
- run: () => void (panel() === "decisions" ? jumpToDecision() : panel() === "consumers" ? cropConsumer() : cropMode() ? applyMarked() : jump())
22203
+ run: () => void (panel() === "decisions" ? jumpToDecision() : panel() === "consumers" ? toggleConsumer(!consumerOpen().has(consumerLine()?.bucket.source ?? "")) : cropMode() ? applyMarked() : jump())
21637
22204
  }, {
21638
22205
  name: "ctree.branch",
21639
22206
  hidden: true,
22207
+ enabled: treeIdle,
21640
22208
  run: () => void branch()
21641
22209
  }, {
21642
22210
  name: "ctree.label",
21643
22211
  hidden: true,
22212
+ enabled: treeIdle,
21644
22213
  run: () => void label()
21645
22214
  }, {
21646
- name: "ctree.filter",
22215
+ name: "ctree.filter_pick",
21647
22216
  hidden: true,
21648
- run: () => {
21649
- const next = cycleFilter(filter());
21650
- setFilter(next);
21651
- api2.kv.set("ctree.filter", next);
21652
- }
22217
+ enabled: () => !inCrop(),
22218
+ run: () => void pickFilter()
22219
+ }, {
22220
+ name: "ctree.filter_prev",
22221
+ hidden: true,
22222
+ enabled: () => !inCrop(),
22223
+ run: () => setFilterTo(FILTERS[(FILTERS.findIndex((f) => f.value === filter()) - 1 + FILTERS.length) % FILTERS.length].value)
21653
22224
  }, {
21654
22225
  name: "ctree.search",
21655
22226
  hidden: true,
21656
- run: () => void prompt("Search rows (empty to clear)", "bash, redis, label\u2026", search()).then((v) => {
21657
- if (v !== undefined)
21658
- setSearch(v.trim());
21659
- })
22227
+ enabled: treeIdle,
22228
+ run: () => enterSearch()
22229
+ }, {
22230
+ name: "ctree.search_next",
22231
+ hidden: true,
22232
+ enabled: treePanel,
22233
+ run: () => moveMatch(1)
22234
+ }, {
22235
+ name: "ctree.search_prev",
22236
+ hidden: true,
22237
+ enabled: treePanel,
22238
+ run: () => moveMatch(-1)
21660
22239
  }, {
21661
22240
  name: "ctree.crop",
21662
22241
  hidden: true,
22242
+ enabled: listPanel,
21663
22243
  run: () => {
21664
22244
  if (panel() === "consumers") {
21665
22245
  cropConsumer();
21666
22246
  return;
21667
22247
  }
21668
- if (panel() !== "tree")
21669
- return;
21670
- if (cropMode()) {
21671
- setCropMode(undefined);
21672
- setMarked(new Set);
21673
- } else
22248
+ if (cropMode())
22249
+ leaveCropMode();
22250
+ else
21674
22251
  setCropMode("result");
21675
22252
  }
21676
22253
  }, {
21677
22254
  name: "ctree.crop_toggle_mode",
21678
22255
  hidden: true,
21679
- run: () => {
21680
- if (!cropMode())
21681
- return;
21682
- setCropMode(cropMode() === "result" ? "turn" : "result");
21683
- setMarked(new Set);
21684
- }
22256
+ enabled: inCrop,
22257
+ run: () => setCropMode(cropMode() === "result" ? "turn" : "result")
21685
22258
  }, {
21686
22259
  name: "ctree.mark",
21687
22260
  hidden: true,
21688
- enabled: () => Boolean(cropMode()),
21689
- run: () => toggleMark()
22261
+ enabled: listPanel,
22262
+ run: () => panel() === "consumers" ? markConsumerEntry() : toggleMark()
21690
22263
  }, {
21691
22264
  name: "ctree.auto",
21692
22265
  hidden: true,
21693
- enabled: () => Boolean(cropMode()),
22266
+ enabled: inCrop,
21694
22267
  run: () => autoMarkAll()
21695
22268
  }, {
21696
22269
  name: "ctree.undo",
21697
22270
  hidden: true,
22271
+ enabled: treeIdle,
21698
22272
  run: () => void undo()
21699
22273
  }, {
21700
22274
  name: "ctree.merge",
21701
22275
  hidden: true,
22276
+ enabled: treeIdle,
21702
22277
  run: () => void merge2()
21703
22278
  }, {
21704
22279
  name: "ctree.inspector",
21705
22280
  hidden: true,
22281
+ enabled: () => !inCrop(),
21706
22282
  run: () => {
21707
22283
  setInspector(!inspector());
21708
22284
  api2.kv.set("ctree.inspector", inspector());
@@ -21710,26 +22286,32 @@ ${MERGE_TRUST}
21710
22286
  }, {
21711
22287
  name: "ctree.consumers",
21712
22288
  hidden: true,
22289
+ enabled: () => !inCrop(),
21713
22290
  run: () => setPanel(panel() === "consumers" ? "tree" : "consumers")
21714
22291
  }, {
21715
22292
  name: "ctree.copy",
21716
22293
  hidden: true,
22294
+ enabled: treeIdle,
21717
22295
  run: () => copySelected()
21718
22296
  }, {
21719
22297
  name: "ctree.mode_duration",
21720
22298
  hidden: true,
22299
+ enabled: treePanel,
21721
22300
  run: () => setLane("duration")
21722
22301
  }, {
21723
22302
  name: "ctree.mode_turns",
21724
22303
  hidden: true,
22304
+ enabled: treePanel,
21725
22305
  run: () => setLane("turns")
21726
22306
  }, {
21727
22307
  name: "ctree.mode_calls",
21728
22308
  hidden: true,
22309
+ enabled: treePanel,
21729
22310
  run: () => setLane("calls")
21730
22311
  }, {
21731
22312
  name: "ctree.lanes_off",
21732
22313
  hidden: true,
22314
+ enabled: treePanel,
21733
22315
  run: () => {
21734
22316
  setLanesOn(false);
21735
22317
  api2.kv.set("ctree.lanesOn", false);
@@ -21737,6 +22319,7 @@ ${MERGE_TRUST}
21737
22319
  }, {
21738
22320
  name: "ctree.decisions",
21739
22321
  hidden: true,
22322
+ enabled: () => !inCrop(),
21740
22323
  run: () => setPanel(panel() === "decisions" ? "tree" : "decisions")
21741
22324
  }, {
21742
22325
  name: "ctree.export",
@@ -21756,8 +22339,11 @@ ${MERGE_TRUST}
21756
22339
  return;
21757
22340
  }
21758
22341
  if (cropMode()) {
21759
- setCropMode(undefined);
21760
- setMarked(new Set);
22342
+ leaveCropMode();
22343
+ return;
22344
+ }
22345
+ if (search()) {
22346
+ setSearch("");
21761
22347
  return;
21762
22348
  }
21763
22349
  back();
@@ -21771,18 +22357,64 @@ ${MERGE_TRUST}
21771
22357
  const root = state().root;
21772
22358
  return (root && root !== sessionID ? others()[root]?.title : undefined) ?? sessionTitle();
21773
22359
  };
21774
- const where = () => {
22360
+ const modeTag = () => cropMode() ? " \xB7 crop mode" : searchMode() ? " \xB7 search" : "";
22361
+ const headLine = () => {
21775
22362
  const b = branchOfCurrent();
21776
- if (!b)
21777
- return "trunk";
21778
- return `\u2387 ${b.name ?? sessionTitle()} (${b.status}${b.model ? ` \xB7 ${b.model.split("/").pop()}` : ""})`;
22363
+ const lead = "\u250C Context tree \xB7 ";
22364
+ const where = b ? `\u2387 ${clip(b.name ?? sessionTitle(), 28)}${b.status === "open" ? "" : ` (${b.status})`} \u2190 ` : "";
22365
+ const tail = b ? "" : " \xB7 trunk";
22366
+ const room = cols() - 4 - formatContext(contextSize(), contextLimit()).length - modeTag().length - lead.length - where.length - tail.length - 3;
22367
+ return `${lead}${where}${clip(title(), Math.max(8, room))}${tail}${modeTag()} `;
22368
+ };
22369
+ const statusLine = () => {
22370
+ const n = view().rows.length;
22371
+ const pos = `${n ? Math.min(selected() + 1, n) : 0}/${n}`;
22372
+ if (cropMode()) {
22373
+ const a = armed();
22374
+ return `\u2702 crop mode (${cropMode()}) \xB7 space mark \xB7 a auto \xB7 t result\u21C4turn \xB7 \u23CE apply \xB7 esc leave \xB7 marked ${selectedCandidates().length} ~${formatK(reclaimed(selectedCandidates()))}${a ? " \xB7 armed \u2014 space again to override" : ""}`;
22375
+ }
22376
+ if (searchMode())
22377
+ return `search: ${search()}\u258F \xB7 ${pos} rows \xB7 \u23CE keeps it \xB7 esc clears`;
22378
+ return `filter: ${filter()}${search() ? ` search: "${search()}"` : ""}${busy() ? ` \u2026 ${busy()}` : ""} ${pos} rows`;
22379
+ };
22380
+ const goVerb = () => {
22381
+ const row = current();
22382
+ if (!row)
22383
+ return "\u23CE go";
22384
+ if (row.kind === "branch")
22385
+ return row.isCurrent ? "\u23CE you are here" : `\u23CE switch to \u2387 ${clip(row.name, 20)}`;
22386
+ if (row.kind === "separator")
22387
+ return "\u23CE go";
22388
+ if (row.id === view().currentRowId)
22389
+ return "\u23CE you are here";
22390
+ return row.kind === "turn" ? "\u23CE fork & prefill this turn" : "\u23CE fork after this step";
22391
+ };
22392
+ const footer = () => {
22393
+ if (cropMode())
22394
+ return "space mark a auto t result\u21C4turn \u23CE apply esc leave";
22395
+ if (panel() === "decisions")
22396
+ return "\u23CE jump to record E export q back";
22397
+ if (panel() === "consumers")
22398
+ return "\u23CE expand space mark c crop q back";
22399
+ if (panel() === "help")
22400
+ return "esc/q back";
22401
+ return `${goVerb()} b branch m merge c crop ${UNDO_KEY} undo s consumers ? help q back`;
22402
+ };
22403
+ const showsTree = () => panel() === "tree" || panel() === "help";
22404
+ const emptyText = () => {
22405
+ const q = search().trim();
22406
+ if (q)
22407
+ return `no rows match "${q}" \xB7 esc clears`;
22408
+ if (filter() !== "default")
22409
+ return `no rows match filter: ${filter()} \xB7 f changes it`;
22410
+ return "(no messages yet \u2014 chat first, then open the tree)";
21779
22411
  };
21780
22412
  return (() => {
21781
- var _el$ = _$createElement("box"), _el$2 = _$createElement("box"), _el$3 = _$createElement("text"), _el$4 = _$createElement("text"), _el$17 = _$createElement("text"), _el$18 = _$createTextNode(`\u2502 `), _el$19 = _$createTextNode(` `), _el$20 = _$createTextNode(` rows`), _el$31 = _$createElement("box"), _el$32 = _$createElement("box"), _el$34 = _$createElement("text"), _el$35 = _$createTextNode(`\u2514 `);
22413
+ var _el$ = _$createElement("box"), _el$2 = _$createElement("box"), _el$3 = _$createElement("text"), _el$4 = _$createElement("text"), _el$16 = _$createElement("text"), _el$17 = _$createTextNode(`\u2502 `), _el$28 = _$createElement("box"), _el$29 = _$createElement("box"), _el$35 = _$createElement("text"), _el$36 = _$createTextNode(`\u2514 `);
21782
22414
  _$insertNode(_el$, _el$2);
21783
- _$insertNode(_el$, _el$17);
21784
- _$insertNode(_el$, _el$31);
21785
- _$insertNode(_el$, _el$34);
22415
+ _$insertNode(_el$, _el$16);
22416
+ _$insertNode(_el$, _el$28);
22417
+ _$insertNode(_el$, _el$35);
21786
22418
  _$setProp(_el$, "flexDirection", "column");
21787
22419
  _$setProp(_el$, "padding", 1);
21788
22420
  _$setProp(_el$, "width", "100%");
@@ -21790,7 +22422,7 @@ ${MERGE_TRUST}
21790
22422
  _$insertNode(_el$2, _el$3);
21791
22423
  _$insertNode(_el$2, _el$4);
21792
22424
  _$setProp(_el$2, "flexDirection", "row");
21793
- _$insert(_el$3, () => `\u250C Context tree \xB7 ${title()} \xB7 ${where()} `);
22425
+ _$insert(_el$3, headLine);
21794
22426
  _$insert(_el$4, () => formatContext(contextSize(), contextLimit()));
21795
22427
  _$insert(_el$, _$createComponent(Show, {
21796
22428
  get when() {
@@ -21798,16 +22430,55 @@ ${MERGE_TRUST}
21798
22430
  },
21799
22431
  get children() {
21800
22432
  return [(() => {
21801
- var _el$5 = _$createElement("text"), _el$6 = _$createTextNode(`\u2502 Input `), _el$7 = _$createTextNode(` `), _el$8 = _$createTextNode(` \xB7 `), _el$9 = _$createTextNode(` \xB7 `);
22433
+ var _el$5 = _$createElement("box"), _el$6 = _$createElement("text"), _el$7 = _$createElement("text");
21802
22434
  _$insertNode(_el$5, _el$6);
21803
22435
  _$insertNode(_el$5, _el$7);
21804
- _$insertNode(_el$5, _el$8);
21805
- _$insertNode(_el$5, _el$9);
21806
- _$insert(_el$5, () => laneLine(laneSeries().input, contextLimit()), _el$7);
21807
- _$insert(_el$5, () => laneMode() === "duration" ? "[1] Duration" : " 1 duration", _el$8);
21808
- _$insert(_el$5, () => laneMode() === "turns" ? "[2] Turns" : " 2 turns", _el$9);
21809
- _$insert(_el$5, () => laneMode() === "calls" ? "[3] Calls" : " 3 calls", null);
21810
- _$effect((_$p) => _$setProp(_el$5, "fg", t.info, _$p));
22436
+ _$setProp(_el$5, "flexDirection", "row");
22437
+ _$insert(_el$6, () => `\u2502 Input ${strip().truncatedLeft > 0 ? `\u2026${strip().truncatedLeft}` : ""}`);
22438
+ _$insert(_el$5, _$createComponent(Show, {
22439
+ get when() {
22440
+ return !strip().empty.input;
22441
+ },
22442
+ get fallback() {
22443
+ return (() => {
22444
+ var _el$37 = _$createElement("text");
22445
+ _$insert(_el$37, () => "no input".padEnd(laneWidth()));
22446
+ _$effect((_$p) => _$setProp(_el$37, "fg", t.textMuted, _$p));
22447
+ return _el$37;
22448
+ })();
22449
+ },
22450
+ get children() {
22451
+ return _$createComponent(For, {
22452
+ get each() {
22453
+ return inputRuns();
22454
+ },
22455
+ children: (r) => (() => {
22456
+ var _el$38 = _$createElement("text");
22457
+ _$insert(_el$38, () => r.text);
22458
+ _$effect((_p$) => {
22459
+ var { fg: _v$0, bg: _v$1 } = r;
22460
+ _v$0 !== _p$.e && (_p$.e = _$setProp(_el$38, "fg", _v$0, _p$.e));
22461
+ _v$1 !== _p$.t && (_p$.t = _$setProp(_el$38, "bg", _v$1, _p$.t));
22462
+ return _p$;
22463
+ }, {
22464
+ e: undefined,
22465
+ t: undefined
22466
+ });
22467
+ return _el$38;
22468
+ })()
22469
+ });
22470
+ }
22471
+ }), _el$7);
22472
+ _$insert(_el$7, () => ` ${laneMode() === "duration" ? "[1] Duration" : " 1 duration"} \xB7 ${laneMode() === "turns" ? "[2] Turns" : " 2 turns"} \xB7 ${laneMode() === "calls" ? "[3] Calls" : " 3 calls"} \xB7 0 off`);
22473
+ _$effect((_p$) => {
22474
+ var { textMuted: _v$, textMuted: _v$2 } = t;
22475
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$6, "fg", _v$, _p$.e));
22476
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$7, "fg", _v$2, _p$.t));
22477
+ return _p$;
22478
+ }, {
22479
+ e: undefined,
22480
+ t: undefined
22481
+ });
21811
22482
  return _el$5;
21812
22483
  })(), _$createComponent(Show, {
21813
22484
  get when() {
@@ -21815,92 +22486,136 @@ ${MERGE_TRUST}
21815
22486
  },
21816
22487
  get children() {
21817
22488
  return [(() => {
21818
- var _el$0 = _$createElement("text"), _el$1 = _$createTextNode(`\u2502 Model `);
21819
- _$insertNode(_el$0, _el$1);
21820
- _$insert(_el$0, () => laneLine(laneSeries().output), null);
21821
- _$effect((_$p) => _$setProp(_el$0, "fg", t.accent, _$p));
21822
- return _el$0;
22489
+ var _el$8 = _$createElement("box"), _el$9 = _$createElement("text");
22490
+ _$insertNode(_el$8, _el$9);
22491
+ _$setProp(_el$8, "flexDirection", "row");
22492
+ _$insertNode(_el$9, _$createTextNode(`\u2502 Model `));
22493
+ _$insert(_el$8, _$createComponent(Show, {
22494
+ get when() {
22495
+ return !strip().empty.model;
22496
+ },
22497
+ get fallback() {
22498
+ return (() => {
22499
+ var _el$39 = _$createElement("text");
22500
+ _$insert(_el$39, () => "no model steps".padEnd(laneWidth()));
22501
+ _$effect((_$p) => _$setProp(_el$39, "fg", t.textMuted, _$p));
22502
+ return _el$39;
22503
+ })();
22504
+ },
22505
+ get children() {
22506
+ return _$createComponent(For, {
22507
+ get each() {
22508
+ return modelRuns();
22509
+ },
22510
+ children: (r) => (() => {
22511
+ var _el$40 = _$createElement("text");
22512
+ _$insert(_el$40, () => r.text);
22513
+ _$effect((_p$) => {
22514
+ var { fg: _v$10, bg: _v$11 } = r;
22515
+ _v$10 !== _p$.e && (_p$.e = _$setProp(_el$40, "fg", _v$10, _p$.e));
22516
+ _v$11 !== _p$.t && (_p$.t = _$setProp(_el$40, "bg", _v$11, _p$.t));
22517
+ return _p$;
22518
+ }, {
22519
+ e: undefined,
22520
+ t: undefined
22521
+ });
22522
+ return _el$40;
22523
+ })()
22524
+ });
22525
+ }
22526
+ }), null);
22527
+ _$effect((_$p) => _$setProp(_el$9, "fg", t.textMuted, _$p));
22528
+ return _el$8;
21823
22529
  })(), (() => {
21824
- var _el$10 = _$createElement("box"), _el$11 = _$createElement("text"), _el$13 = _$createElement("text");
21825
- _$insertNode(_el$10, _el$11);
21826
- _$insertNode(_el$10, _el$13);
21827
- _$setProp(_el$10, "flexDirection", "row");
21828
- _$insertNode(_el$11, _$createTextNode(`\u2502 Tools `));
21829
- _$insert(_el$10, _$createComponent(For, {
21830
- get each() {
21831
- return toolRuns();
22530
+ var _el$1 = _$createElement("box"), _el$10 = _$createElement("text"), _el$12 = _$createElement("text");
22531
+ _$insertNode(_el$1, _el$10);
22532
+ _$insertNode(_el$1, _el$12);
22533
+ _$setProp(_el$1, "flexDirection", "row");
22534
+ _$insertNode(_el$10, _$createTextNode(`\u2502 Tools `));
22535
+ _$insert(_el$1, _$createComponent(Show, {
22536
+ get when() {
22537
+ return !strip().empty.tools;
21832
22538
  },
21833
- children: (run) => (() => {
21834
- var _el$36 = _$createElement("text");
21835
- _$insert(_el$36, () => run.text);
21836
- _$effect((_$p) => _$setProp(_el$36, "fg", run.error ? t.error : t.warning, _$p));
21837
- return _el$36;
21838
- })()
21839
- }), _el$13);
21840
- _$insertNode(_el$13, _$createTextNode(` i inspector \xB7 u consumers`));
22539
+ get fallback() {
22540
+ return (() => {
22541
+ var _el$41 = _$createElement("text");
22542
+ _$insert(_el$41, () => "no tool calls".padEnd(laneWidth()));
22543
+ _$effect((_$p) => _$setProp(_el$41, "fg", t.textMuted, _$p));
22544
+ return _el$41;
22545
+ })();
22546
+ },
22547
+ get children() {
22548
+ return _$createComponent(For, {
22549
+ get each() {
22550
+ return toolRuns();
22551
+ },
22552
+ children: (r) => (() => {
22553
+ var _el$42 = _$createElement("text");
22554
+ _$insert(_el$42, () => r.text);
22555
+ _$effect((_p$) => {
22556
+ var { fg: _v$12, bg: _v$13 } = r;
22557
+ _v$12 !== _p$.e && (_p$.e = _$setProp(_el$42, "fg", _v$12, _p$.e));
22558
+ _v$13 !== _p$.t && (_p$.t = _$setProp(_el$42, "bg", _v$13, _p$.t));
22559
+ return _p$;
22560
+ }, {
22561
+ e: undefined,
22562
+ t: undefined
22563
+ });
22564
+ return _el$42;
22565
+ })()
22566
+ });
22567
+ }
22568
+ }), _el$12);
22569
+ _$insertNode(_el$12, _$createTextNode(` i inspector \xB7 s consumers`));
21841
22570
  _$effect((_p$) => {
21842
- var { warning: _v$, warning: _v$2 } = t;
21843
- _v$ !== _p$.e && (_p$.e = _$setProp(_el$11, "fg", _v$, _p$.e));
21844
- _v$2 !== _p$.t && (_p$.t = _$setProp(_el$13, "fg", _v$2, _p$.t));
22571
+ var { textMuted: _v$3, textMuted: _v$4 } = t;
22572
+ _v$3 !== _p$.e && (_p$.e = _$setProp(_el$10, "fg", _v$3, _p$.e));
22573
+ _v$4 !== _p$.t && (_p$.t = _$setProp(_el$12, "fg", _v$4, _p$.t));
21845
22574
  return _p$;
21846
22575
  }, {
21847
22576
  e: undefined,
21848
22577
  t: undefined
21849
22578
  });
21850
- return _el$10;
22579
+ return _el$1;
21851
22580
  })()];
21852
22581
  }
21853
22582
  })];
21854
22583
  }
21855
- }), _el$17);
22584
+ }), _el$16);
21856
22585
  _$insert(_el$, _$createComponent(Show, {
21857
22586
  get when() {
21858
22587
  return _$memo(() => !!(laneRoom() && lanesOn()))() && !showLanes();
21859
22588
  },
21860
22589
  get children() {
21861
- var _el$15 = _$createElement("text");
21862
- _$insertNode(_el$15, _$createTextNode(`\u2502 lanes appear after 3 turns`));
21863
- _$effect((_$p) => _$setProp(_el$15, "fg", t.textMuted, _$p));
21864
- return _el$15;
21865
- }
21866
- }), _el$17);
21867
- _$insertNode(_el$17, _el$18);
21868
- _$insertNode(_el$17, _el$19);
21869
- _$insertNode(_el$17, _el$20);
21870
- _$insert(_el$17, (() => {
21871
- var _c$ = _$memo(() => !!cropMode());
21872
- return () => _c$() ? `\u2702 crop mode (${cropMode()}) \xB7 space mark \xB7 a auto \xB7 t result\u21C4turn \xB7 \u23CE apply \xB7 esc leave \xB7 marked ${selectedCandidates().length} ~${formatK(reclaimed(selectedCandidates()))}` : `filter: ${filter()}`;
21873
- })(), _el$19);
21874
- _$insert(_el$17, (() => {
21875
- var _c$2 = _$memo(() => !!search());
21876
- return () => _c$2() ? ` search: "${search()}"` : "";
21877
- })(), _el$19);
21878
- _$insert(_el$17, (() => {
21879
- var _c$3 = _$memo(() => !!busy());
21880
- return () => _c$3() ? ` \u2026 ${busy()}` : "";
21881
- })(), _el$19);
21882
- _$insert(_el$17, () => view().rows.length, _el$20);
22590
+ var _el$14 = _$createElement("text");
22591
+ _$insertNode(_el$14, _$createTextNode(`\u2502 lanes appear after 3 turns`));
22592
+ _$effect((_$p) => _$setProp(_el$14, "fg", t.textMuted, _$p));
22593
+ return _el$14;
22594
+ }
22595
+ }), _el$16);
22596
+ _$insertNode(_el$16, _el$17);
22597
+ _$insert(_el$16, statusLine, null);
21883
22598
  _$insert(_el$, _$createComponent(Show, {
21884
22599
  get when() {
21885
22600
  return panel() === "decisions";
21886
22601
  },
21887
22602
  get children() {
21888
22603
  return [(() => {
21889
- var _el$21 = _$createElement("text"), _el$22 = _$createTextNode(`\u2502 \u25C6 decisions on this tree (`), _el$23 = _$createTextNode(`) \xB7 \u23CE jump to record \xB7 E export markdown \xB7 D back`);
21890
- _$insertNode(_el$21, _el$22);
21891
- _$insertNode(_el$21, _el$23);
21892
- _$insert(_el$21, () => decisions().length, _el$23);
21893
- _$effect((_$p) => _$setProp(_el$21, "fg", t.accent, _$p));
21894
- return _el$21;
22604
+ var _el$18 = _$createElement("text"), _el$19 = _$createTextNode(`\u2502 \u25C6 decisions on this tree (`), _el$20 = _$createTextNode(`) \xB7 \u23CE jump to record \xB7 E export markdown \xB7 q back`);
22605
+ _$insertNode(_el$18, _el$19);
22606
+ _$insertNode(_el$18, _el$20);
22607
+ _$insert(_el$18, () => decisions().length, _el$20);
22608
+ _$effect((_$p) => _$setProp(_el$18, "fg", t.accent, _$p));
22609
+ return _el$18;
21895
22610
  })(), _$createComponent(Show, {
21896
22611
  get when() {
21897
22612
  return decisions().length === 0;
21898
22613
  },
21899
22614
  get children() {
21900
- var _el$24 = _$createElement("text");
21901
- _$insertNode(_el$24, _$createTextNode(`\u2502 (none yet \u2014 /merge a branch to write one)`));
21902
- _$effect((_$p) => _$setProp(_el$24, "fg", t.textMuted, _$p));
21903
- return _el$24;
22615
+ var _el$21 = _$createElement("text");
22616
+ _$insertNode(_el$21, _$createTextNode(`\u2502 (none yet \u2014 /merge a branch to write one)`));
22617
+ _$effect((_$p) => _$setProp(_el$21, "fg", t.textMuted, _$p));
22618
+ return _el$21;
21904
22619
  }
21905
22620
  }), _$createComponent(For, {
21906
22621
  get each() {
@@ -21908,132 +22623,142 @@ ${MERGE_TRUST}
21908
22623
  },
21909
22624
  children: (d, i) => {
21910
22625
  const sel = () => i() === decisionIndex();
21911
- const lines = () => (d.text ?? "").split(`
21912
- `).slice(0, sel() ? 12 : 1);
22626
+ const body = () => renderDecision(d.text ?? "", width() - 6);
22627
+ const room = () => Math.max(3, height() - decisions().length);
22628
+ const start = () => Math.min(decisionScroll(), Math.max(0, body().length - room()));
22629
+ const more = () => Math.max(0, body().length - start() - room());
21913
22630
  return (() => {
21914
- var _el$37 = _$createElement("box"), _el$38 = _$createElement("text"), _el$39 = _$createTextNode(` `), _el$40 = _$createTextNode(` \xB7 `);
21915
- _$insertNode(_el$37, _el$38);
21916
- _$setProp(_el$37, "flexDirection", "column");
21917
- _$insertNode(_el$38, _el$39);
21918
- _$insertNode(_el$38, _el$40);
21919
- _$insert(_el$38, () => sel() ? "\u203A" : "\u2502", _el$39);
21920
- _$insert(_el$38, () => d.hidden ? "\u25C7 (hidden from model) " : "\u25C6 ", _el$40);
21921
- _$insert(_el$38, () => d.branchName, _el$40);
21922
- _$insert(_el$38, () => new Date(d.recordedAt).toISOString().slice(0, 16).replace("T", " "), null);
21923
- _$insert(_el$38, (() => {
21924
- var _c$4 = _$memo(() => !!d.siblings.length);
21925
- return () => _c$4() ? ` \xB7 \u2717 ${d.siblings.map((x) => x.name).join(", ")}` : "";
22631
+ var _el$43 = _$createElement("box"), _el$44 = _$createElement("text"), _el$45 = _$createTextNode(` `), _el$46 = _$createTextNode(` \xB7 `);
22632
+ _$insertNode(_el$43, _el$44);
22633
+ _$setProp(_el$43, "flexDirection", "column");
22634
+ _$insertNode(_el$44, _el$45);
22635
+ _$insertNode(_el$44, _el$46);
22636
+ _$insert(_el$44, () => sel() ? "\u203A" : "\u2502", _el$45);
22637
+ _$insert(_el$44, () => d.hidden ? "\u25C7 (hidden from model) " : "\u25C6 ", _el$46);
22638
+ _$insert(_el$44, () => clip(decisionSummary(d.text ?? "").title || d.branchName, 48), _el$46);
22639
+ _$insert(_el$44, () => new Date(d.recordedAt).toISOString().slice(0, 16).replace("T", " "), null);
22640
+ _$insert(_el$44, (() => {
22641
+ var _c$3 = _$memo(() => !!d.siblings.length);
22642
+ return () => _c$3() ? ` \xB7 \u2717 ${d.siblings.map((x) => x.name).join(", ")}` : "";
21926
22643
  })(), null);
21927
- _$insert(_el$37, _$createComponent(For, {
22644
+ _$insert(_el$43, _$createComponent(For, {
21928
22645
  get each() {
21929
- return _$memo(() => !!sel())() ? lines().slice(1) : [];
22646
+ return _$memo(() => !!sel())() ? body().slice(start(), start() + room()) : [];
21930
22647
  },
21931
22648
  children: (l) => (() => {
21932
- var _el$41 = _$createElement("text"), _el$42 = _$createTextNode(`\u2502 `);
21933
- _$insertNode(_el$41, _el$42);
21934
- _$insert(_el$41, () => l.slice(0, width() - 6), null);
21935
- _$effect((_$p) => _$setProp(_el$41, "fg", t.text, _$p));
21936
- return _el$41;
22649
+ var _el$48 = _$createElement("text");
22650
+ _$insert(_el$48, `\u2502 ${l}`);
22651
+ _$effect((_$p) => _$setProp(_el$48, "fg", t.text, _$p));
22652
+ return _el$48;
21937
22653
  })()
21938
22654
  }), null);
22655
+ _$insert(_el$43, _$createComponent(Show, {
22656
+ get when() {
22657
+ return _$memo(() => !!sel())() && more() > 0;
22658
+ },
22659
+ get children() {
22660
+ var _el$47 = _$createElement("text");
22661
+ _$insert(_el$47, () => `\u2502 \u2026 ${more()} more lines \u2193 (ctrl+d)`);
22662
+ _$effect((_$p) => _$setProp(_el$47, "fg", t.textMuted, _$p));
22663
+ return _el$47;
22664
+ }
22665
+ }), null);
21939
22666
  _$effect((_p$) => {
21940
- var _v$8 = sel() ? t.background : t.accent, _v$9 = sel() ? t.primary : undefined;
21941
- _v$8 !== _p$.e && (_p$.e = _$setProp(_el$38, "fg", _v$8, _p$.e));
21942
- _v$9 !== _p$.t && (_p$.t = _$setProp(_el$38, "bg", _v$9, _p$.t));
22667
+ var _v$14 = sel() ? t.background : t.accent, _v$15 = sel() ? t.primary : undefined;
22668
+ _v$14 !== _p$.e && (_p$.e = _$setProp(_el$44, "fg", _v$14, _p$.e));
22669
+ _v$15 !== _p$.t && (_p$.t = _$setProp(_el$44, "bg", _v$15, _p$.t));
21943
22670
  return _p$;
21944
22671
  }, {
21945
22672
  e: undefined,
21946
22673
  t: undefined
21947
22674
  });
21948
- return _el$37;
22675
+ return _el$43;
21949
22676
  })();
21950
22677
  }
21951
22678
  })];
21952
22679
  }
21953
- }), _el$31);
22680
+ }), _el$28);
21954
22681
  _$insert(_el$, _$createComponent(Show, {
21955
22682
  get when() {
21956
22683
  return panel() === "consumers";
21957
22684
  },
21958
22685
  get children() {
21959
22686
  return [(() => {
21960
- var _el$26 = _$createElement("text"), _el$27 = _$createTextNode(`\u2502 what's filling the context \xB7 `), _el$28 = _$createTextNode(` total \xB7 c crop \xB7 u/esc back`);
21961
- _$insertNode(_el$26, _el$27);
21962
- _$insertNode(_el$26, _el$28);
21963
- _$insert(_el$26, () => formatK(view().totalTokens), _el$28);
21964
- _$effect((_$p) => _$setProp(_el$26, "fg", t.accent, _$p));
21965
- return _el$26;
22687
+ var _el$23 = _$createElement("text"), _el$24 = _$createTextNode(`\u2502 what's filling the context \xB7 `), _el$25 = _$createTextNode(` total \xB7 source \xB7 %tree \xB7 %window \xB7 tokens \xB7 entries`);
22688
+ _$insertNode(_el$23, _el$24);
22689
+ _$insertNode(_el$23, _el$25);
22690
+ _$insert(_el$23, () => formatK(view().totalTokens), _el$25);
22691
+ _$effect((_$p) => _$setProp(_el$23, "fg", t.accent, _$p));
22692
+ return _el$23;
21966
22693
  })(), _$createComponent(For, {
21967
22694
  get each() {
21968
- return consumerRows();
22695
+ return consumerLines();
21969
22696
  },
21970
- children: (c, i) => {
22697
+ children: (line, i) => {
21971
22698
  const sel = () => i() === consumerIndex();
22699
+ const c = line.bucket;
22700
+ const fg = () => sel() ? t.background : line.entry ? t.textMuted : c.kind === "tool" ? t.warning : t.text;
22701
+ const window = () => c.shareOfWindow === undefined ? "\u2013" : `${(c.shareOfWindow * 100).toFixed(0)}%`;
22702
+ const entry = line.entry;
21972
22703
  return (() => {
21973
- var _el$43 = _$createElement("text"), _el$44 = _$createTextNode(` `), _el$45 = _$createTextNode(` `), _el$46 = _$createTextNode(` `), _el$47 = _$createTextNode(` `), _el$48 = _$createTextNode(` \xB7 `), _el$49 = _$createTextNode(` entr`);
21974
- _$insertNode(_el$43, _el$44);
21975
- _$insertNode(_el$43, _el$45);
21976
- _$insertNode(_el$43, _el$46);
21977
- _$insertNode(_el$43, _el$47);
21978
- _$insertNode(_el$43, _el$48);
21979
- _$insertNode(_el$43, _el$49);
21980
- _$insert(_el$43, () => sel() ? "\u203A" : "\u2502", _el$44);
21981
- _$insert(_el$43, () => c.source.padEnd(22).slice(0, 22), _el$45);
21982
- _$insert(_el$43, () => `${(c.share * 100).toFixed(0)}%`.padStart(4), _el$46);
21983
- _$insert(_el$43, () => bar(c.share, 24), _el$47);
21984
- _$insert(_el$43, () => formatK(c.tokens).padStart(6), _el$48);
21985
- _$insert(_el$43, () => c.count, _el$49);
21986
- _$insert(_el$43, () => c.count === 1 ? "y" : "ies", null);
22704
+ var _el$49 = _$createElement("text"), _el$50 = _$createTextNode(` `);
22705
+ _$insertNode(_el$49, _el$50);
22706
+ _$insert(_el$49, () => sel() ? "\u203A" : "\u2502", _el$50);
22707
+ _$insert(_el$49, () => entry ? fitRow(` ${entry.croppable ? marked().has(entry.partID ?? "") ? "[x]" : "[ ]" : " "} ${plain(entry.preview)}${entry.croppable ? "" : ` \xB7 ${c.note ?? "not a completed tool result"}`}`, formatK(entry.tokens), width() - 4) : `${consumerOpen().has(c.source) ? "\u25BE" : "\u25B8"} ${c.source.padEnd(20).slice(0, 20)} ${`${(c.share * 100).toFixed(0)}%`.padStart(4)} ${window().padStart(5)} ${bar(c.tokens / consumerMax(), 18)} ${formatK(c.tokens).padStart(6)} \xB7 ${c.count} entr${c.count === 1 ? "y" : "ies"}${c.note ? ` \xB7 ${c.note}` : ""}`, null);
21987
22708
  _$effect((_p$) => {
21988
- var _v$0 = sel() ? t.background : c.kind === "tool" ? t.warning : t.text, _v$1 = sel() ? t.primary : undefined;
21989
- _v$0 !== _p$.e && (_p$.e = _$setProp(_el$43, "fg", _v$0, _p$.e));
21990
- _v$1 !== _p$.t && (_p$.t = _$setProp(_el$43, "bg", _v$1, _p$.t));
22709
+ var _v$16 = fg(), _v$17 = sel() ? t.primary : undefined;
22710
+ _v$16 !== _p$.e && (_p$.e = _$setProp(_el$49, "fg", _v$16, _p$.e));
22711
+ _v$17 !== _p$.t && (_p$.t = _$setProp(_el$49, "bg", _v$17, _p$.t));
21991
22712
  return _p$;
21992
22713
  }, {
21993
22714
  e: undefined,
21994
22715
  t: undefined
21995
22716
  });
21996
- return _el$43;
22717
+ return _el$49;
21997
22718
  })();
21998
22719
  }
21999
22720
  })];
22000
22721
  }
22001
- }), _el$31);
22002
- _$insert(_el$, _$createComponent(For, {
22003
- get each() {
22004
- return _$memo(() => panel() === "help")() ? HELP.slice(0, Math.max(6, size().rows - 5)) : [];
22005
- },
22006
- children: (l) => (() => {
22007
- var _el$50 = _$createElement("text"), _el$51 = _$createTextNode(`\u2502 `);
22008
- _$insertNode(_el$50, _el$51);
22009
- _$insert(_el$50, l, null);
22010
- _$effect((_$p) => _$setProp(_el$50, "fg", l.startsWith(" ") ? t.textMuted : t.accent, _$p));
22011
- return _el$50;
22012
- })()
22013
- }), _el$31);
22722
+ }), _el$28);
22014
22723
  _$insert(_el$, _$createComponent(Show, {
22015
22724
  get when() {
22016
- return _$memo(() => panel() === "tree")() && view().rows.length === 0;
22725
+ return _$memo(() => !!showsTree())() && view().rows.length === 0;
22726
+ },
22727
+ get children() {
22728
+ var _el$26 = _$createElement("text"), _el$27 = _$createTextNode(`\u2502 `);
22729
+ _$insertNode(_el$26, _el$27);
22730
+ _$insert(_el$26, emptyText, null);
22731
+ _$effect((_$p) => _$setProp(_el$26, "fg", t.textMuted, _$p));
22732
+ return _el$26;
22733
+ }
22734
+ }), _el$28);
22735
+ _$insertNode(_el$28, _el$29);
22736
+ _$setProp(_el$28, "flexDirection", "row");
22737
+ _$setProp(_el$28, "flexGrow", 1);
22738
+ _$setProp(_el$29, "flexDirection", "column");
22739
+ _$setProp(_el$29, "flexGrow", 1);
22740
+ _$insert(_el$29, _$createComponent(Show, {
22741
+ get when() {
22742
+ return _$memo(() => !!showsTree())() && overflow();
22017
22743
  },
22018
22744
  get children() {
22019
- var _el$29 = _$createElement("text");
22020
- _$insertNode(_el$29, _$createTextNode(`\u2502 (no messages yet \u2014 chat first, then open the tree)`));
22021
- _$effect((_$p) => _$setProp(_el$29, "fg", t.textMuted, _$p));
22022
- return _el$29;
22023
- }
22024
- }), _el$31);
22025
- _$insertNode(_el$31, _el$32);
22026
- _$setProp(_el$31, "flexDirection", "row");
22027
- _$setProp(_el$31, "flexGrow", 1);
22028
- _$setProp(_el$32, "flexDirection", "column");
22029
- _$setProp(_el$32, "flexGrow", 1);
22030
- _$insert(_el$32, _$createComponent(For, {
22745
+ var _el$30 = _$createElement("text"), _el$31 = _$createTextNode(`\u2502 `);
22746
+ _$insertNode(_el$30, _el$31);
22747
+ _$insert(_el$30, (() => {
22748
+ var _c$ = _$memo(() => hiddenAbove() > 0);
22749
+ return () => _c$() ? `\u2191 ${hiddenAbove()} more` : "";
22750
+ })(), null);
22751
+ _$effect((_$p) => _$setProp(_el$30, "fg", t.textMuted, _$p));
22752
+ return _el$30;
22753
+ }
22754
+ }), null);
22755
+ _$insert(_el$29, _$createComponent(For, {
22031
22756
  get each() {
22032
- return _$memo(() => panel() === "tree")() ? visible() : [];
22757
+ return _$memo(() => !!showsTree())() ? visible() : [];
22033
22758
  },
22034
22759
  children: (row, i) => {
22035
22760
  const isSel = () => windowStart() + i() === selected();
22036
- const color = () => row.kind === "branch" ? statusColor(t, row) : row.kind === "turn" ? row.isDecision ? t.accent : t.text : row.isError ? t.error : row.warn ? t.warning : t.textMuted;
22761
+ const color = () => row.kind === "separator" ? t.textMuted : row.kind === "branch" ? statusColor(t, row) : !row.inContext ? t.textMuted : row.kind === "turn" ? row.isDecision ? t.accent : t.text : row.isError ? t.error : row.warn ? t.warning : t.textMuted;
22037
22762
  const mark = () => {
22038
22763
  if (!cropMode())
22039
22764
  return "";
@@ -22044,70 +22769,139 @@ ${MERGE_TRUST}
22044
22769
  const prot = c.protections.filter((p) => p !== "too-small");
22045
22770
  return `${on2 ? "[x]" : "[ ]"}${prot.length ? "!" : " "}`;
22046
22771
  };
22047
- return (() => {
22048
- var _el$52 = _$createElement("text"), _el$53 = _$createTextNode(` `);
22049
- _$insertNode(_el$52, _el$53);
22050
- _$insert(_el$52, () => isSel() ? "\u203A" : "\u2502", _el$53);
22051
- _$insert(_el$52, mark, null);
22052
- _$insert(_el$52, () => rowLine(row, rowWidth(), row.id === view().currentRowId), null);
22053
- _$effect((_p$) => {
22054
- var _v$10 = isSel() ? t.background : color(), _v$11 = isSel() ? t.primary : undefined;
22055
- _v$10 !== _p$.e && (_p$.e = _$setProp(_el$52, "fg", _v$10, _p$.e));
22056
- _v$11 !== _p$.t && (_p$.t = _$setProp(_el$52, "bg", _v$11, _p$.t));
22057
- return _p$;
22058
- }, {
22059
- e: undefined,
22060
- t: undefined
22061
- });
22062
- return _el$52;
22063
- })();
22772
+ const prefix = () => `${isSel() ? "\u203A" : "\u2502"} ${mark()}`;
22773
+ const segs = () => segmentsOf(rowLine(row, rowWidth(), row.id === view().currentRowId), search().trim(), thoughtOf(row));
22774
+ return _$createComponent(Show, {
22775
+ get when() {
22776
+ return segs().length > 1;
22777
+ },
22778
+ get fallback() {
22779
+ return (() => {
22780
+ var _el$53 = _$createElement("text");
22781
+ _$insert(_el$53, prefix, null);
22782
+ _$insert(_el$53, () => segs()[0]?.text, null);
22783
+ _$effect((_p$) => {
22784
+ var _v$20 = isSel() ? t.background : color(), _v$21 = isSel() ? t.primary : undefined;
22785
+ _v$20 !== _p$.e && (_p$.e = _$setProp(_el$53, "fg", _v$20, _p$.e));
22786
+ _v$21 !== _p$.t && (_p$.t = _$setProp(_el$53, "bg", _v$21, _p$.t));
22787
+ return _p$;
22788
+ }, {
22789
+ e: undefined,
22790
+ t: undefined
22791
+ });
22792
+ return _el$53;
22793
+ })();
22794
+ },
22795
+ get children() {
22796
+ var _el$51 = _$createElement("box"), _el$52 = _$createElement("text");
22797
+ _$insertNode(_el$51, _el$52);
22798
+ _$setProp(_el$51, "flexDirection", "row");
22799
+ _$insert(_el$52, prefix);
22800
+ _$insert(_el$51, _$createComponent(For, {
22801
+ get each() {
22802
+ return segs();
22803
+ },
22804
+ children: (s) => (() => {
22805
+ var _el$54 = _$createElement("text");
22806
+ _$insert(_el$54, () => s.text);
22807
+ _$effect((_p$) => {
22808
+ var _v$22 = s.kind === "match" ? t.background : s.kind === "dim" ? t.textMuted : isSel() ? t.background : color(), _v$23 = s.kind === "match" ? t.accent : isSel() ? t.primary : undefined;
22809
+ _v$22 !== _p$.e && (_p$.e = _$setProp(_el$54, "fg", _v$22, _p$.e));
22810
+ _v$23 !== _p$.t && (_p$.t = _$setProp(_el$54, "bg", _v$23, _p$.t));
22811
+ return _p$;
22812
+ }, {
22813
+ e: undefined,
22814
+ t: undefined
22815
+ });
22816
+ return _el$54;
22817
+ })()
22818
+ }), null);
22819
+ _$effect((_p$) => {
22820
+ var _v$18 = isSel() ? t.background : color(), _v$19 = isSel() ? t.primary : undefined;
22821
+ _v$18 !== _p$.e && (_p$.e = _$setProp(_el$52, "fg", _v$18, _p$.e));
22822
+ _v$19 !== _p$.t && (_p$.t = _$setProp(_el$52, "bg", _v$19, _p$.t));
22823
+ return _p$;
22824
+ }, {
22825
+ e: undefined,
22826
+ t: undefined
22827
+ });
22828
+ return _el$51;
22829
+ }
22830
+ });
22064
22831
  }
22065
22832
  }), null);
22066
- _$insert(_el$32, _$createComponent(For, {
22833
+ _$insert(_el$29, _$createComponent(Show, {
22834
+ get when() {
22835
+ return _$memo(() => !!showsTree())() && overflow();
22836
+ },
22837
+ get children() {
22838
+ var _el$32 = _$createElement("text"), _el$33 = _$createTextNode(`\u2502 `);
22839
+ _$insertNode(_el$32, _el$33);
22840
+ _$insert(_el$32, (() => {
22841
+ var _c$2 = _$memo(() => hiddenBelow() > 0);
22842
+ return () => _c$2() ? `\u2026 ${hiddenBelow()} more \u2193` : "";
22843
+ })(), null);
22844
+ _$effect((_$p) => _$setProp(_el$32, "fg", t.textMuted, _$p));
22845
+ return _el$32;
22846
+ }
22847
+ }), null);
22848
+ _$insert(_el$29, _$createComponent(For, {
22849
+ get each() {
22850
+ return _$memo(() => !!(showsTree() && view().rows.length > 0 && !view().rows.some((r) => r.kind === "branch")))() ? noBranchesLines() : [];
22851
+ },
22852
+ children: (l) => (() => {
22853
+ var _el$55 = _$createElement("text"), _el$56 = _$createTextNode(`\u2502 `);
22854
+ _$insertNode(_el$55, _el$56);
22855
+ _$insert(_el$55, l, null);
22856
+ _$effect((_$p) => _$setProp(_el$55, "fg", t.textMuted, _$p));
22857
+ return _el$55;
22858
+ })()
22859
+ }), null);
22860
+ _$insert(_el$29, _$createComponent(For, {
22067
22861
  get each() {
22068
- return _$memo(() => !!(panel() === "tree" && view().rows.length > 0 && !view().rows.some((r) => r.kind === "branch")))() ? noBranchesLines() : [];
22862
+ return _$memo(() => panel() === "help")() ? HELP.slice(0, helpHeight()) : [];
22069
22863
  },
22070
22864
  children: (l) => (() => {
22071
- var _el$54 = _$createElement("text"), _el$55 = _$createTextNode(`\u2502 `);
22072
- _$insertNode(_el$54, _el$55);
22073
- _$insert(_el$54, l, null);
22074
- _$effect((_$p) => _$setProp(_el$54, "fg", t.textMuted, _$p));
22075
- return _el$54;
22865
+ var _el$57 = _$createElement("text"), _el$58 = _$createTextNode(`\u2502 `);
22866
+ _$insertNode(_el$57, _el$58);
22867
+ _$insert(_el$57, l, null);
22868
+ _$effect((_$p) => _$setProp(_el$57, "fg", l.startsWith(" ") ? t.textMuted : t.accent, _$p));
22869
+ return _el$57;
22076
22870
  })()
22077
22871
  }), null);
22078
- _$insert(_el$31, _$createComponent(Show, {
22872
+ _$insert(_el$28, _$createComponent(Show, {
22079
22873
  get when() {
22080
22874
  return showInspector();
22081
22875
  },
22082
22876
  get children() {
22083
- var _el$33 = _$createElement("box");
22084
- _$setProp(_el$33, "flexDirection", "column");
22085
- _$setProp(_el$33, "paddingLeft", 1);
22086
- _$insert(_el$33, _$createComponent(For, {
22877
+ var _el$34 = _$createElement("box");
22878
+ _$setProp(_el$34, "flexDirection", "column");
22879
+ _$setProp(_el$34, "paddingLeft", 1);
22880
+ _$insert(_el$34, _$createComponent(For, {
22087
22881
  get each() {
22088
22882
  return inspectorLines();
22089
22883
  },
22090
22884
  children: (l) => (() => {
22091
- var _el$56 = _$createElement("text"), _el$57 = _$createTextNode(`\u2503 `);
22092
- _$insertNode(_el$56, _el$57);
22093
- _$insert(_el$56, () => l.text, null);
22094
- _$effect((_$p) => _$setProp(_el$56, "fg", l.fg, _$p));
22095
- return _el$56;
22885
+ var _el$59 = _$createElement("text"), _el$60 = _$createTextNode(`\u2503 `);
22886
+ _$insertNode(_el$59, _el$60);
22887
+ _$insert(_el$59, () => l.text, null);
22888
+ _$effect((_$p) => _$setProp(_el$59, "fg", l.fg, _$p));
22889
+ return _el$59;
22096
22890
  })()
22097
22891
  }));
22098
- _$effect((_$p) => _$setProp(_el$33, "width", inspectorWidth(), _$p));
22099
- return _el$33;
22892
+ _$effect((_$p) => _$setProp(_el$34, "width", inspectorWidth(), _$p));
22893
+ return _el$34;
22100
22894
  }
22101
22895
  }), null);
22102
- _$insertNode(_el$34, _el$35);
22103
- _$insert(_el$34, () => cropMode() ? "space mark a auto t result\u21C4turn \u23CE apply esc leave" : "\u23CE go b branch m merge c crop i inspector 1\xB72\xB73 lanes x undo ? help q back", null);
22896
+ _$insertNode(_el$35, _el$36);
22897
+ _$insert(_el$35, footer, null);
22104
22898
  _$effect((_p$) => {
22105
- var { background: _v$3, primary: _v$4 } = t, _v$5 = t[BAND_KEY[band()]], _v$6 = cropMode() ? t.warning : t.textMuted, _v$7 = cropMode() ? t.warning : t.textMuted;
22106
- _v$3 !== _p$.e && (_p$.e = _$setProp(_el$, "backgroundColor", _v$3, _p$.e));
22107
- _v$4 !== _p$.t && (_p$.t = _$setProp(_el$3, "fg", _v$4, _p$.t));
22108
- _v$5 !== _p$.a && (_p$.a = _$setProp(_el$4, "fg", _v$5, _p$.a));
22109
- _v$6 !== _p$.o && (_p$.o = _$setProp(_el$17, "fg", _v$6, _p$.o));
22110
- _v$7 !== _p$.i && (_p$.i = _$setProp(_el$34, "fg", _v$7, _p$.i));
22899
+ var { background: _v$5, primary: _v$6 } = t, _v$7 = t[BAND_KEY[band()]], _v$8 = cropMode() ? t.warning : searchMode() ? t.accent : t.textMuted, _v$9 = cropMode() ? t.warning : t.textMuted;
22900
+ _v$5 !== _p$.e && (_p$.e = _$setProp(_el$, "backgroundColor", _v$5, _p$.e));
22901
+ _v$6 !== _p$.t && (_p$.t = _$setProp(_el$3, "fg", _v$6, _p$.t));
22902
+ _v$7 !== _p$.a && (_p$.a = _$setProp(_el$4, "fg", _v$7, _p$.a));
22903
+ _v$8 !== _p$.o && (_p$.o = _$setProp(_el$16, "fg", _v$8, _p$.o));
22904
+ _v$9 !== _p$.i && (_p$.i = _$setProp(_el$35, "fg", _v$9, _p$.i));
22111
22905
  return _p$;
22112
22906
  }, {
22113
22907
  e: undefined,
@@ -22338,7 +23132,7 @@ var tui = async (api2, rawOptions) => {
22338
23132
  adoptSoon();
22339
23133
  });
22340
23134
  api2.lifecycle?.onDispose(offCreated);
22341
- const promptDialog = (title, placeholder) => new Promise((resolve) => {
23135
+ const promptDialog2 = (title, placeholder) => new Promise((resolve) => {
22342
23136
  api2.ui.dialog.replace(() => api2.ui.DialogPrompt({
22343
23137
  title,
22344
23138
  placeholder,
@@ -22395,7 +23189,7 @@ var tui = async (api2, rawOptions) => {
22395
23189
  if (!sessionID)
22396
23190
  return;
22397
23191
  await new Promise((r) => setTimeout(r, 30));
22398
- const name = await promptDialog(BRANCH_DIALOG.title, BRANCH_DIALOG.placeholder);
23192
+ const name = await promptDialog2(BRANCH_DIALOG.title, BRANCH_DIALOG.placeholder);
22399
23193
  debug("branch.named", {
22400
23194
  name
22401
23195
  });
@@ -22433,7 +23227,7 @@ var tui = async (api2, rawOptions) => {
22433
23227
  const last = api2.state.session.messages(sessionID).at(-1);
22434
23228
  if (!last)
22435
23229
  return;
22436
- const value = await promptDialog("Label (empty to remove)", "checkpoint");
23230
+ const value = await promptDialog2("Label (empty to remove)", "checkpoint");
22437
23231
  if (value === undefined)
22438
23232
  return;
22439
23233
  setLabel({
@@ -22478,11 +23272,20 @@ var tui = async (api2, rawOptions) => {
22478
23272
  });
22479
23273
  return;
22480
23274
  }
23275
+ const parent = await fetchTranscript(api2, branch.parentSessionID, directory).catch(() => {
23276
+ return;
23277
+ });
23278
+ const parentLabel = branch.parentSessionID === state.root ? TRUNK_LABEL : state.sessions[branch.parentSessionID]?.name ?? TRUNK_LABEL;
23279
+ const turns = ownTurnCount(api2.state.session.messages(sessionID), {
23280
+ messageID: branch.anchorMessageID,
23281
+ parentMessageIDs: parent?.messages.map((m) => m.id) ?? []
23282
+ });
22481
23283
  const mode = await new Promise((resolve) => {
22482
23284
  api2.ui.dialog.replace(() => api2.ui.DialogSelect({
22483
- title: mergeDialogTitle(branch.name ?? "branch", api2.state.session.get(branch.parentSessionID)?.title),
23285
+ title: mergeDialogTitle(branch.name ?? "branch", parent ? mergeTargetOf(parentLabel, parent.messages) : undefined),
22484
23286
  options: mergeDialogOptions({
22485
- siblings: openSiblings(state, sessionID).length
23287
+ siblings: openSiblings(state, sessionID).length,
23288
+ turns
22486
23289
  }),
22487
23290
  onSelect: (o) => {
22488
23291
  resolve(o.value);
@@ -22577,6 +23380,8 @@ ${MERGE_TRUST}`,
22577
23380
  return store.stateForSession(props.session_id);
22578
23381
  });
22579
23382
  const branch = () => st()?.sessions[props.session_id];
23383
+ const size = createMemo2(() => contextSizeOf(toMinimalMessages(api2.state.session.messages(props.session_id), api2.state.part)));
23384
+ const limit = createMemo2(() => modelContextLimit(api2, props.session_id));
22580
23385
  const crops = () => st()?.activeCrops(props.session_id) ?? [];
22581
23386
  const hidden = () => crops().reduce((s, c) => s + c.targets.reduce((x, y) => x + y.estTokens, 0), 0);
22582
23387
  const siblings = () => Object.values(st()?.sessions ?? {}).filter((b) => b.parentSessionID === props.session_id && b.status === "open").length;
@@ -22587,9 +23392,10 @@ ${MERGE_TRUST}`,
22587
23392
  return `${b.status}${title && room > 3 ? ` \xB7 from "${clip(title, room)}"` : ""}`;
22588
23393
  };
22589
23394
  return (() => {
22590
- var _el$ = _$createElement2("box"), _el$2 = _$createElement2("text"), _el$3 = _$createElement2("b"), _el$8 = _$createElement2("text");
23395
+ var _el$ = _$createElement2("box"), _el$2 = _$createElement2("text"), _el$3 = _$createElement2("b"), _el$7 = _$createElement2("text"), _el$9 = _$createElement2("text");
22591
23396
  _$insertNode2(_el$, _el$2);
22592
- _$insertNode2(_el$, _el$8);
23397
+ _$insertNode2(_el$, _el$7);
23398
+ _$insertNode2(_el$, _el$9);
22593
23399
  _$setProp2(_el$, "flexDirection", "column");
22594
23400
  _$insertNode2(_el$2, _el$3);
22595
23401
  _$insertNode2(_el$3, _$createTextNode2(`Context tree`));
@@ -22599,10 +23405,10 @@ ${MERGE_TRUST}`,
22599
23405
  },
22600
23406
  get fallback() {
22601
23407
  return (() => {
22602
- var _el$0 = _$createElement2("text");
22603
- _$insert2(_el$0, () => `trunk${siblings() ? ` \xB7 ${siblings()} branch${siblings() === 1 ? "" : "es"}` : ""}`);
22604
- _$effect2((_$p) => _$setProp2(_el$0, "fg", t.text, _$p));
22605
- return _el$0;
23408
+ var _el$1 = _$createElement2("text");
23409
+ _$insert2(_el$1, () => `trunk${siblings() ? ` \xB7 ${siblings()} branch${siblings() === 1 ? "" : "es"}` : ""}`);
23410
+ _$effect2((_$p) => _$setProp2(_el$1, "fg", t.text, _$p));
23411
+ return _el$1;
22606
23412
  })();
22607
23413
  },
22608
23414
  get children() {
@@ -22618,27 +23424,30 @@ ${MERGE_TRUST}`,
22618
23424
  return _el$6;
22619
23425
  })()];
22620
23426
  }
22621
- }), _el$8);
23427
+ }), _el$7);
23428
+ _$insert2(_el$7, () => formatContext(size(), limit()));
22622
23429
  _$insert2(_el$, _$createComponent2(Show2, {
22623
23430
  get when() {
22624
23431
  return crops().length;
22625
23432
  },
22626
23433
  get children() {
22627
- var _el$7 = _$createElement2("text");
22628
- _$insert2(_el$7, () => `\u2702 ${crops().length} crop${crops().length === 1 ? "" : "s"} \xB7 ~${formatK(hidden())} hidden`);
22629
- _$effect2((_$p) => _$setProp2(_el$7, "fg", t.warning, _$p));
22630
- return _el$7;
23434
+ var _el$8 = _$createElement2("text");
23435
+ _$insert2(_el$8, () => `\u2702 ${crops().length} crop${crops().length === 1 ? "" : "s"} \xB7 ~${formatK(hidden())} hidden`);
23436
+ _$effect2((_$p) => _$setProp2(_el$8, "fg", t.warning, _$p));
23437
+ return _el$8;
22631
23438
  }
22632
- }), _el$8);
22633
- _$insertNode2(_el$8, _$createTextNode2(`/tree \xB7 ctrl+q`));
23439
+ }), _el$9);
23440
+ _$insertNode2(_el$9, _$createTextNode2(`/tree \xB7 ctrl+q`));
22634
23441
  _$effect2((_p$) => {
22635
- var { text: _v$, textMuted: _v$2 } = t;
23442
+ var _v$ = t.text, _v$2 = t[BAND_COLOR[bandFor(size().tokens, limit())]], _v$3 = t.textMuted;
22636
23443
  _v$ !== _p$.e && (_p$.e = _$setProp2(_el$2, "fg", _v$, _p$.e));
22637
- _v$2 !== _p$.t && (_p$.t = _$setProp2(_el$8, "fg", _v$2, _p$.t));
23444
+ _v$2 !== _p$.t && (_p$.t = _$setProp2(_el$7, "fg", _v$2, _p$.t));
23445
+ _v$3 !== _p$.a && (_p$.a = _$setProp2(_el$9, "fg", _v$3, _p$.a));
22638
23446
  return _p$;
22639
23447
  }, {
22640
23448
  e: undefined,
22641
- t: undefined
23449
+ t: undefined,
23450
+ a: undefined
22642
23451
  });
22643
23452
  return _el$;
22644
23453
  })();
@@ -22646,12 +23455,12 @@ ${MERGE_TRUST}`,
22646
23455
  session_prompt_right: (_ctx, props) => {
22647
23456
  const t = api2.theme.current;
22648
23457
  const size = createMemo2(() => contextSizeOf(toMinimalMessages(api2.state.session.messages(props.session_id), api2.state.part)));
22649
- const band = () => bandFor(size().tokens);
22650
23458
  const branch = () => {
22651
23459
  journalRevision();
22652
23460
  return store.stateForSession(props.session_id)?.sessions[props.session_id];
22653
23461
  };
22654
23462
  const limit = createMemo2(() => modelContextLimit(api2, props.session_id));
23463
+ const band = () => bandFor(size().tokens, limit());
22655
23464
  const reserve = () => api2.state.config.compaction?.reserved ?? 16384;
22656
23465
  const [trend, setTrend] = createSignal3("");
22657
23466
  let prevTokens = 0;
@@ -22707,7 +23516,7 @@ ${MERGE_TRUST}`,
22707
23516
  redNudged = true;
22708
23517
  api2.ui.toast({
22709
23518
  variant: "warning",
22710
- message: "context is in the red band (\u226564k) \u2014 consider /tree \u2192 c crop, or /merge a branch",
23519
+ message: `context is in the red band (${limit() ? "\u226585% of the window" : "\u226564k"}) \u2014 consider /tree \u2192 c crop, or /merge a branch`,
22711
23520
  duration: 6000
22712
23521
  });
22713
23522
  } else if (b === "low" || b === "healthy")
@@ -22724,10 +23533,10 @@ ${MERGE_TRUST}`,
22724
23533
  guardNudged = false;
22725
23534
  });
22726
23535
  return (() => {
22727
- var _el$1 = _$createElement2("text");
22728
- _$insert2(_el$1, () => `${branch() ? `\u2387 ${branchLabel(api2, props.session_id, branch().name, 24)} \xB7 ` : ""}${formatContext(size(), limit())}${trend()}`);
22729
- _$effect2((_$p) => _$setProp2(_el$1, "fg", t[BAND_COLOR[band()]], _$p));
22730
- return _el$1;
23536
+ var _el$10 = _$createElement2("text");
23537
+ _$insert2(_el$10, () => `${branch() ? `\u2387 ${branchLabel(api2, props.session_id, branch().name, 24)} \xB7 ` : ""}${formatContext(size(), limit())}${trend()}`);
23538
+ _$effect2((_$p) => _$setProp2(_el$10, "fg", t[BAND_COLOR[band()]], _$p));
23539
+ return _el$10;
22731
23540
  })();
22732
23541
  }
22733
23542
  }