flavor-code 1.3.12 → 1.3.15

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.
@@ -18,7 +18,7 @@ import {
18
18
  thinkingWindow,
19
19
  transcriptReducer,
20
20
  withTimeout
21
- } from "./chunk-QC5OYQTB.js";
21
+ } from "./chunk-WB4IJXFT.js";
22
22
  import "./chunk-JFKRX2KG.js";
23
23
  import {
24
24
  Box_default,
@@ -1749,6 +1749,27 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
1749
1749
  const clipboardBusy = useRef4(false);
1750
1750
  const textBuf = useRef4({ pending: "", timer: null });
1751
1751
  const thinkingBuf = useRef4({ pending: "", timer: null });
1752
+ const promptDraftRef = useRef4({
1753
+ text: input,
1754
+ cursor: promptCursor,
1755
+ pastedBlocks,
1756
+ imageAttachments
1757
+ });
1758
+ promptDraftRef.current = { text: input, cursor: promptCursor, pastedBlocks, imageAttachments };
1759
+ const commitPromptDraft = (next) => {
1760
+ const current = promptDraftRef.current;
1761
+ const resolved = {
1762
+ text: next.text,
1763
+ cursor: next.cursor,
1764
+ pastedBlocks: next.pastedBlocks ?? current.pastedBlocks,
1765
+ imageAttachments: next.imageAttachments ?? current.imageAttachments
1766
+ };
1767
+ promptDraftRef.current = resolved;
1768
+ setInput(resolved.text);
1769
+ setPromptCursor(resolved.cursor);
1770
+ if (next.pastedBlocks !== void 0) setPastedBlocks(next.pastedBlocks);
1771
+ if (next.imageAttachments !== void 0) setImageAttachments(next.imageAttachments);
1772
+ };
1752
1773
  useTerminalTitle("Flavor Code");
1753
1774
  const flushText = () => {
1754
1775
  flushThinking();
@@ -1961,9 +1982,9 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
1961
1982
  const completedTokenLength = completedSlashTokenLength(input, slashCandidates, slashCompletion !== null);
1962
1983
  const selection = useSelection();
1963
1984
  const selectMention = (path) => {
1964
- const next = completeMentionSelection(input, promptCursor, path);
1965
- setInput(next.text);
1966
- setPromptCursor(next.cursor);
1985
+ const draft = promptDraftRef.current;
1986
+ const next = completeMentionSelection(draft.text, draft.cursor, path);
1987
+ commitPromptDraft(next);
1967
1988
  setMentionSelection(0);
1968
1989
  setDismissedMentionInput(next.text);
1969
1990
  };
@@ -2171,6 +2192,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2171
2192
  setInput("");
2172
2193
  setPastedBlocks([]);
2173
2194
  setImageAttachments([]);
2195
+ promptDraftRef.current = { text: "", cursor: 0, pastedBlocks: [], imageAttachments: [] };
2174
2196
  setClipboardNotice(void 0);
2175
2197
  setPromptCursor(0);
2176
2198
  setSlashSelection(0);
@@ -2205,37 +2227,41 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2205
2227
  return;
2206
2228
  }
2207
2229
  if (key.backspace) {
2208
- const imageEdit = removeLastCliImageOnBackspace(input, promptCursor, imageAttachments);
2230
+ const draft = promptDraftRef.current;
2231
+ const imageEdit = removeLastCliImageOnBackspace(draft.text, draft.cursor, draft.imageAttachments);
2209
2232
  if (imageEdit.handled) {
2210
2233
  setImageAttachments(imageEdit.images);
2234
+ promptDraftRef.current = { ...draft, imageAttachments: imageEdit.images };
2211
2235
  setClipboardNotice(imageEdit.images.length === 0 ? "Removed image attachment." : `Removed image attachment; ${imageEdit.images.length} remaining.`);
2212
2236
  return;
2213
2237
  }
2214
2238
  const next = editPromptWithPastedBlocks(
2215
- { text: input, cursor: promptCursor },
2239
+ { text: draft.text, cursor: draft.cursor },
2216
2240
  { type: "backspace" },
2217
- pastedBlocks
2241
+ draft.pastedBlocks
2218
2242
  );
2219
- setInput(next.text);
2220
- setPromptCursor(next.cursor);
2221
- setPastedBlocks(next.pastedBlocks);
2243
+ commitPromptDraft(next);
2222
2244
  setSlashSelection(0);
2223
2245
  setDismissedSlashInput(void 0);
2224
2246
  setMentionSelection(0);
2225
2247
  setDismissedMentionInput(void 0);
2226
2248
  } else if (key.delete) {
2227
- updatePrompt({ type: "delete" }, input, promptCursor, setInput, setPromptCursor);
2249
+ const draft = promptDraftRef.current;
2250
+ commitPromptDraft({ ...editPrompt({ text: draft.text, cursor: draft.cursor }, { type: "delete" }), pastedBlocks: draft.pastedBlocks });
2228
2251
  setSlashSelection(0);
2229
2252
  setDismissedSlashInput(void 0);
2230
2253
  setMentionSelection(0);
2231
2254
  setDismissedMentionInput(void 0);
2232
- } else if (key.leftArrow) setPromptCursor((value) => Math.max(0, value - 1));
2233
- else if (key.rightArrow) setPromptCursor((value) => Math.min([...input].length, value + 1));
2234
- else if (terminalAction?.type === "history" && terminalAction.direction === "up" && history.length) {
2255
+ } else if (key.leftArrow) {
2256
+ const draft = promptDraftRef.current;
2257
+ commitPromptDraft({ ...editPrompt({ text: draft.text, cursor: draft.cursor }, { type: "left" }), pastedBlocks: draft.pastedBlocks });
2258
+ } else if (key.rightArrow) {
2259
+ const draft = promptDraftRef.current;
2260
+ commitPromptDraft({ ...editPrompt({ text: draft.text, cursor: draft.cursor }, { type: "right" }), pastedBlocks: draft.pastedBlocks });
2261
+ } else if (terminalAction?.type === "history" && terminalAction.direction === "up" && history.length) {
2235
2262
  const next = navigateHistory({ history, cursor: historyCursor }, "up");
2236
2263
  setHistoryCursor(next.cursor);
2237
- setInput(next.input);
2238
- setPromptCursor(next.promptCursor);
2264
+ commitPromptDraft({ text: next.input, cursor: next.promptCursor, pastedBlocks: [] });
2239
2265
  setSlashSelection(0);
2240
2266
  setDismissedSlashInput(void 0);
2241
2267
  setMentionSelection(0);
@@ -2243,17 +2269,18 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2243
2269
  } else if (terminalAction?.type === "history" && terminalAction.direction === "down" && history.length) {
2244
2270
  const next = navigateHistory({ history, cursor: historyCursor }, "down");
2245
2271
  setHistoryCursor(next.cursor);
2246
- setInput(next.input);
2247
- setPromptCursor(next.promptCursor);
2272
+ commitPromptDraft({ text: next.input, cursor: next.promptCursor, pastedBlocks: [] });
2248
2273
  setSlashSelection(0);
2249
2274
  setDismissedSlashInput(void 0);
2250
2275
  setMentionSelection(0);
2251
2276
  setDismissedMentionInput(void 0);
2252
2277
  } else if (!key.ctrl && !key.meta && character) {
2253
- updatePrompt({ type: "insert", value: character }, input, promptCursor, setInput, setPromptCursor);
2254
- if (/[\r\n]/u.test(character)) {
2255
- setPastedBlocks((current) => [...current, { id: current.length + 1, text: character }]);
2256
- }
2278
+ const draft = promptDraftRef.current;
2279
+ const nextPastedBlocks = /[\r\n]/u.test(character) ? [...draft.pastedBlocks, { id: draft.pastedBlocks.length + 1, text: character }] : draft.pastedBlocks;
2280
+ commitPromptDraft({
2281
+ ...editPrompt({ text: draft.text, cursor: draft.cursor }, { type: "insert", value: character }),
2282
+ pastedBlocks: nextPastedBlocks
2283
+ });
2257
2284
  setSlashSelection(0);
2258
2285
  setDismissedSlashInput(void 0);
2259
2286
  setMentionSelection(0);
@@ -2330,6 +2357,73 @@ function StartingLayout({
2330
2357
  }
2331
2358
  );
2332
2359
  }
2360
+ var CLI_VISIBLE_TURN_LIMIT = 40;
2361
+ var CLI_VISIBLE_BLOCK_LIMIT = 320;
2362
+ var CLI_VISIBLE_BLOCKS_PER_TURN = 80;
2363
+ var CLI_VISIBLE_TEXT_CHARS = 32e3;
2364
+ function boundedCliDisplayText(text, limit = CLI_VISIBLE_TEXT_CHARS) {
2365
+ if (text.length <= limit) return text;
2366
+ const half = Math.floor((limit - 80) / 2);
2367
+ return `${text.slice(0, half)}
2368
+
2369
+ \u2026 ${text.length - half * 2} characters hidden to keep the terminal responsive \u2026
2370
+
2371
+ ${text.slice(-half)}`;
2372
+ }
2373
+ function boundedCliPresentation(presentation) {
2374
+ if (presentation.kind === "terminal") return {
2375
+ ...presentation,
2376
+ ...presentation.stdout === void 0 ? {} : { stdout: boundedCliDisplayText(presentation.stdout) },
2377
+ ...presentation.stderr === void 0 ? {} : { stderr: boundedCliDisplayText(presentation.stderr) }
2378
+ };
2379
+ if (presentation.kind === "job" && presentation.output !== void 0) return {
2380
+ ...presentation,
2381
+ output: boundedCliDisplayText(presentation.output)
2382
+ };
2383
+ return presentation;
2384
+ }
2385
+ function boundedCliTurn(turn, maxBlocks = CLI_VISIBLE_BLOCKS_PER_TURN) {
2386
+ const blockLimit = Math.max(1, Math.floor(maxBlocks));
2387
+ const hiddenBlocks = Math.max(0, turn.blocks.length - blockLimit);
2388
+ const visible = turn.blocks.slice(-blockLimit).map((block) => block.kind === "text" ? { ...block, text: boundedCliDisplayText(block.text) } : {
2389
+ ...block,
2390
+ ...block.details === void 0 ? {} : { details: boundedCliDisplayText(block.details) },
2391
+ ...block.presentation === void 0 ? {} : { presentation: boundedCliPresentation(block.presentation) }
2392
+ });
2393
+ const blocks = hiddenBlocks === 0 ? visible : [{
2394
+ kind: "status",
2395
+ id: `display-window:${turn.id}`,
2396
+ state: "info",
2397
+ text: `\xB7 ${hiddenBlocks} earlier output items hidden to keep the terminal responsive`
2398
+ }, ...visible];
2399
+ return {
2400
+ hiddenBlocks,
2401
+ turn: {
2402
+ ...turn,
2403
+ prompt: boundedCliDisplayText(turn.prompt, 16e3),
2404
+ blocks,
2405
+ statusLines: blocks.filter((block) => block.kind === "status").map((block) => block.text)
2406
+ }
2407
+ };
2408
+ }
2409
+ function cliTranscriptWindow(completed, maxTurns = CLI_VISIBLE_TURN_LIMIT, maxBlocks = CLI_VISIBLE_BLOCK_LIMIT) {
2410
+ const turns = [];
2411
+ let remainingBlocks = Math.max(1, Math.floor(maxBlocks));
2412
+ let hiddenBlocks = 0;
2413
+ for (let index = completed.length - 1; index >= 0 && turns.length < Math.max(1, Math.floor(maxTurns)); index -= 1) {
2414
+ const source = completed[index];
2415
+ if (remainingBlocks <= 0) break;
2416
+ const allowance = Math.min(CLI_VISIBLE_BLOCKS_PER_TURN, remainingBlocks);
2417
+ const bounded = boundedCliTurn(source, allowance);
2418
+ turns.push(bounded.turn);
2419
+ hiddenBlocks += bounded.hiddenBlocks;
2420
+ remainingBlocks -= Math.min(source.blocks.length, allowance);
2421
+ }
2422
+ turns.reverse();
2423
+ const hiddenTurns = completed.length - turns.length;
2424
+ for (let index = 0; index < hiddenTurns; index += 1) hiddenBlocks += completed[index]?.blocks.length ?? 0;
2425
+ return { turns, hiddenTurns, hiddenBlocks };
2426
+ }
2333
2427
  function TerminalLayout({
2334
2428
  model,
2335
2429
  serviceName,
@@ -2369,12 +2463,14 @@ function TerminalLayout({
2369
2463
  const activeTaskBlocks = active?.blocks.filter(
2370
2464
  (block) => block.kind === "status" && block.task !== void 0
2371
2465
  ) ?? [];
2372
- const activeWithoutTasks = active === void 0 ? void 0 : {
2466
+ const rawActiveWithoutTasks = active === void 0 ? void 0 : {
2373
2467
  ...active,
2374
2468
  blocks: active.blocks.filter(
2375
2469
  (block) => !(block.kind === "status" && block.task !== void 0)
2376
2470
  )
2377
2471
  };
2472
+ const activeWithoutTasks = rawActiveWithoutTasks === void 0 ? void 0 : boundedCliTurn(rawActiveWithoutTasks).turn;
2473
+ const completedWindow = cliTranscriptWindow(completed);
2378
2474
  const questionRows = questions === void 0 ? 0 : 4 + (questions[questionIndex]?.options.length ?? 0) + questions.length * 2;
2379
2475
  const memoryReviewRows = memoryReviews.length === 0 ? 0 : 5;
2380
2476
  const fixedBottomRows = (approval === void 0 ? 0 : 3) + questionRows + memoryReviewRows + menuRows + (pendingPrompt === void 0 ? 0 : 1) + imageAttachments.length + (clipboardNotice === void 0 ? 0 : 1) + 2;
@@ -2391,12 +2487,19 @@ function TerminalLayout({
2391
2487
  workspaceName
2392
2488
  ] }),
2393
2489
  /* @__PURE__ */ jsx5(Box_default, { height: 1 }),
2394
- completed.map((turn, index) => /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
2490
+ completedWindow.hiddenTurns > 0 || completedWindow.hiddenBlocks > 0 ? /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
2491
+ "\u2026 ",
2492
+ completedWindow.hiddenTurns,
2493
+ " earlier turns and ",
2494
+ completedWindow.hiddenBlocks,
2495
+ " output items are outside the live render window"
2496
+ ] }) : null,
2497
+ completedWindow.turns.map((turn, index) => /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
2395
2498
  index > 0 ? /* @__PURE__ */ jsx5(TurnSeparator, { width: columns }) : null,
2396
2499
  /* @__PURE__ */ jsx5(TurnView, { turn, interactive: false, workspaceName })
2397
2500
  ] }, turn.id)),
2398
2501
  activeWithoutTasks === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
2399
- completed.length > 0 ? /* @__PURE__ */ jsx5(TurnSeparator, { width: columns }) : null,
2502
+ completedWindow.turns.length > 0 ? /* @__PURE__ */ jsx5(TurnSeparator, { width: columns }) : null,
2400
2503
  /* @__PURE__ */ jsx5(TurnView, { turn: activeWithoutTasks, interactive: activeSession, workspaceName })
2401
2504
  ] })
2402
2505
  ] }),
@@ -3443,11 +3546,6 @@ function navigateHistory(state, direction) {
3443
3546
  const input = state.history[cursor] ?? "";
3444
3547
  return { cursor, input, promptCursor: [...input].length };
3445
3548
  }
3446
- function updatePrompt(edit, text, cursor, setText, setCursor) {
3447
- const next = editPrompt({ text, cursor }, edit);
3448
- setText(next.text);
3449
- setCursor(next.cursor);
3450
- }
3451
3549
  async function submitSafely(session, prompt, report) {
3452
3550
  try {
3453
3551
  await session.submit(prompt);
@@ -3499,6 +3597,10 @@ function safeReport(report, value) {
3499
3597
  }
3500
3598
  export {
3501
3599
  App,
3600
+ CLI_VISIBLE_BLOCKS_PER_TURN,
3601
+ CLI_VISIBLE_BLOCK_LIMIT,
3602
+ CLI_VISIBLE_TEXT_CHARS,
3603
+ CLI_VISIBLE_TURN_LIMIT,
3502
3604
  FooterStatus,
3503
3605
  HISTORY_CAP,
3504
3606
  MentionMenu,
@@ -3507,7 +3609,9 @@ export {
3507
3609
  SinglePendingPrompt,
3508
3610
  TerminalLayout,
3509
3611
  appRuntimeOptions,
3612
+ boundedCliTurn,
3510
3613
  classifyTerminalInput,
3614
+ cliTranscriptWindow,
3511
3615
  closeAndDisposeRuntime,
3512
3616
  completionKeyAction,
3513
3617
  editPrompt,
@@ -4,7 +4,7 @@ import {
4
4
  message,
5
5
  redactErrorText,
6
6
  redactSecrets
7
- } from "./chunk-QC5OYQTB.js";
7
+ } from "./chunk-WB4IJXFT.js";
8
8
 
9
9
  // src/rpc/server.ts
10
10
  import { createInterface } from "readline";