@kernelonpanic/kitcode 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1430,6 +1430,10 @@ async function runTurn(cfg, history, hooks, signal) {
1430
1430
  let pauses = 0;
1431
1431
  let steps = 0;
1432
1432
  for (; ; ) {
1433
+ if (signal.aborted) {
1434
+ hooks.onEvent({ type: "turn_end", stopReason: "aborted" });
1435
+ return sanitizeHistory(messages);
1436
+ }
1433
1437
  if (++steps > MAX_TURN_STEPS) {
1434
1438
  hooks.onEvent({
1435
1439
  type: "notice",
@@ -1516,12 +1520,16 @@ async function consumeStream(cfg, messages, hooks, signal, maxTokens) {
1516
1520
  signal
1517
1521
  };
1518
1522
  let outcome;
1523
+ let text = "";
1524
+ let thinking = "";
1519
1525
  for await (const event of streamWithRetry(cfg.provider, request, cfg.modelRef, signal)) {
1520
1526
  switch (event.type) {
1521
1527
  case "text_delta":
1528
+ text += event.text;
1522
1529
  hooks.onEvent({ type: "text_delta", text: event.text });
1523
1530
  break;
1524
1531
  case "thinking_delta":
1532
+ thinking += event.text;
1525
1533
  hooks.onEvent({ type: "thinking_delta", text: event.text });
1526
1534
  break;
1527
1535
  case "usage":
@@ -1540,7 +1548,12 @@ async function consumeStream(cfg, messages, hooks, signal, maxTokens) {
1540
1548
  }
1541
1549
  }
1542
1550
  if (outcome) return outcome;
1543
- if (signal.aborted) return { content: [], stopReason: "aborted" };
1551
+ if (signal.aborted) {
1552
+ const content = [];
1553
+ if (thinking) content.push({ type: "thinking", text: thinking });
1554
+ if (text) content.push({ type: "text", text });
1555
+ return { content, stopReason: "aborted" };
1556
+ }
1544
1557
  throw new Error(
1545
1558
  `"${cfg.provider.id}" ended the stream without completing the turn \u2014 nothing was generated. The endpoint answered, but not with a usable ${cfg.provider.kind} response.`
1546
1559
  );
@@ -1550,8 +1563,29 @@ async function* streamWithRetry(provider, request, modelRef, signal) {
1550
1563
  for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
1551
1564
  if (signal.aborted) return;
1552
1565
  try {
1553
- for await (const event of provider.stream(request)) {
1554
- yield event;
1566
+ const stream = provider.stream(request)[Symbol.asyncIterator]();
1567
+ let cancel;
1568
+ let cancelTimer;
1569
+ const cancelled = new Promise((resolve3) => {
1570
+ cancel = () => {
1571
+ cancelTimer ??= setTimeout(() => resolve3({ done: true, value: void 0 }), 100);
1572
+ };
1573
+ signal.addEventListener("abort", cancel, { once: true });
1574
+ if (signal.aborted) cancel();
1575
+ });
1576
+ try {
1577
+ for (; ; ) {
1578
+ const next = await Promise.race([stream.next(), cancelled]);
1579
+ if (next.done) break;
1580
+ if (!signal.aborted || next.value.type === "usage" || next.value.type === "done") {
1581
+ yield next.value;
1582
+ }
1583
+ if (next.value.type === "done") break;
1584
+ }
1585
+ } finally {
1586
+ signal.removeEventListener("abort", cancel);
1587
+ if (cancelTimer !== void 0) clearTimeout(cancelTimer);
1588
+ void stream.return?.().catch(() => void 0);
1555
1589
  }
1556
1590
  return;
1557
1591
  } catch (error) {
@@ -3499,7 +3533,7 @@ function clip(value) {
3499
3533
  // package.json
3500
3534
  var package_default = {
3501
3535
  name: "@kernelonpanic/kitcode",
3502
- version: "1.2.8",
3536
+ version: "1.2.9",
3503
3537
  description: "Terminal coding agent with a config you never have to write by hand",
3504
3538
  type: "module",
3505
3539
  license: "MIT",
@@ -3567,7 +3601,7 @@ var package_default = {
3567
3601
 
3568
3602
  // src/version.ts
3569
3603
  var KITCODE_VERSION = package_default.version;
3570
- var KITCODE_COMMIT = true ? "422e80dd7cd81a1c20f186b1e3ab36d6e0779b89" : "development";
3604
+ var KITCODE_COMMIT = true ? "cc499fc443e73408f49b928f204b77c48e9d2d05" : "development";
3571
3605
 
3572
3606
  // src/mcp/client.ts
3573
3607
  var clientInfo = { name: "kitcode", version: KITCODE_VERSION };
@@ -7067,6 +7101,10 @@ function validateKey(value) {
7067
7101
  // src/app/tui.tsx
7068
7102
  import { render } from "ink";
7069
7103
 
7104
+ // src/ui/App.tsx
7105
+ import { Box as Box13, Text as Text12, useApp, useInput as useInput2, useStdout as useStdout2 } from "ink";
7106
+ import { useCallback, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef4, useState as useState5 } from "react";
7107
+
7070
7108
  // src/ui/terminal-size.ts
7071
7109
  import { useStdout } from "ink";
7072
7110
  import { useMemo, useSyncExternalStore } from "react";
@@ -7107,10 +7145,6 @@ function useTerminalSize() {
7107
7145
  return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
7108
7146
  }
7109
7147
 
7110
- // src/ui/App.tsx
7111
- import { Box as Box13, Text as Text12, useApp, useInput as useInput2 } from "ink";
7112
- import { useCallback, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef4, useState as useState5 } from "react";
7113
-
7114
7148
  // src/mcp/add.ts
7115
7149
  var SERVER_NAME = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
7116
7150
  function parseMcpAddArgs(args) {
@@ -9598,7 +9632,8 @@ function App({
9598
9632
  initialHistory,
9599
9633
  warnings = []
9600
9634
  }) {
9601
- const { exit } = useApp();
9635
+ const { exit, suspendTerminal } = useApp();
9636
+ const { stdout } = useStdout2();
9602
9637
  const { rows } = useTerminalSize();
9603
9638
  const [transcript, setTranscript] = useState5(
9604
9639
  () => warnings.reduce((state, text) => pushNotice(state, "warn", text), fromHistory(initialHistory))
@@ -9634,6 +9669,9 @@ function App({
9634
9669
  const [context, setContext] = useState5(() => runtime.modelContext());
9635
9670
  const transcriptEvents = useRef4([]);
9636
9671
  const transcriptTimer = useRef4(null);
9672
+ const clearScreen = useCallback(() => {
9673
+ if (stdout.isTTY) stdout.write("\x1B[2J\x1B[3J\x1B[H");
9674
+ }, [stdout]);
9637
9675
  const replaceAttachments = useCallback((next) => {
9638
9676
  attachmentsRef.current = next;
9639
9677
  setAttachments(next);
@@ -9801,12 +9839,20 @@ function App({
9801
9839
  exit();
9802
9840
  return;
9803
9841
  case "clear":
9842
+ if (busyRef.current && abort.current) {
9843
+ abort.current.abort();
9844
+ }
9845
+ queueRef.current = [];
9846
+ setPendingCount(0);
9804
9847
  await runtime.newSession();
9805
9848
  history.current = [];
9806
9849
  replaceAttachments([]);
9807
9850
  setPromptHistory([]);
9808
- setTranscript(emptyTranscript());
9809
- setTranscriptRevision((revision) => revision + 1);
9851
+ await suspendTerminal(async () => {
9852
+ setTranscript(emptyTranscript());
9853
+ setTranscriptRevision((revision) => revision + 1);
9854
+ clearScreen();
9855
+ });
9810
9856
  sessionStart.current = Date.now();
9811
9857
  turns.current = 0;
9812
9858
  void runtime.persist([]).catch(