@kernelonpanic/kitcode 1.3.2 → 1.3.3

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
@@ -3940,7 +3940,7 @@ function clip(value) {
3940
3940
  // package.json
3941
3941
  var package_default = {
3942
3942
  name: "@kernelonpanic/kitcode",
3943
- version: "1.3.2",
3943
+ version: "1.3.3",
3944
3944
  description: "Terminal coding agent with a config you never have to write by hand",
3945
3945
  type: "module",
3946
3946
  license: "MIT",
@@ -4008,7 +4008,7 @@ var package_default = {
4008
4008
 
4009
4009
  // src/version.ts
4010
4010
  var KITCODE_VERSION = package_default.version;
4011
- var KITCODE_COMMIT = true ? "993d55335487da4915fa49660911ba6e69aa3685" : "development";
4011
+ var KITCODE_COMMIT = true ? "81f72aca6f23448aa2239b7bd9175da0f9e5862c" : "development";
4012
4012
 
4013
4013
  // src/mcp/client.ts
4014
4014
  var clientInfo = { name: "kitcode", version: KITCODE_VERSION };
@@ -8665,6 +8665,18 @@ function appendInputHistory(history, value, limit = 100) {
8665
8665
  // src/ui/components/PromptInput.tsx
8666
8666
  import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
8667
8667
  var WINDOW2 = 6;
8668
+ var CAT_FRAME_MS = 500;
8669
+ var CAT_FRAMES = [
8670
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
8671
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ \u223F",
8672
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
8673
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ \u223E",
8674
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ ~",
8675
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ \u223F",
8676
+ "/\u1420-\uA788-\u141F\\ ~",
8677
+ "/\u1420\uFF61\uA788\uFF61\u141F\\ \u223E"
8678
+ ];
8679
+ var MAX_INPUT_ROWS = 6;
8668
8680
  var PromptInput = memo(function PromptInput2({
8669
8681
  value,
8670
8682
  onChange,
@@ -8679,8 +8691,19 @@ var PromptInput = memo(function PromptInput2({
8679
8691
  onListFiles
8680
8692
  }) {
8681
8693
  const theme = useTheme();
8682
- const { columns } = useTerminalSize();
8694
+ const { columns, rows } = useTerminalSize();
8695
+ const panelWidth = Math.max(2, columns - 1);
8696
+ const inputRows = Math.max(1, Math.min(MAX_INPUT_ROWS, rows - 16));
8683
8697
  const strings = useStrings();
8698
+ const [catFrame, setCatFrame] = useState4(0);
8699
+ useEffect(() => {
8700
+ if (!disabled) return;
8701
+ const timer = setInterval(() => setCatFrame((frame) => (frame + 1) % CAT_FRAMES.length), CAT_FRAME_MS);
8702
+ return () => clearInterval(timer);
8703
+ }, [disabled]);
8704
+ const panelColor = disabled ? theme.warn : theme.accent;
8705
+ const fullTitle = disabled ? `KitCode ${CAT_FRAMES[catFrame]}` : "KitCode";
8706
+ const panelTitle = fullTitle.slice(0, Math.max(0, panelWidth - 5));
8684
8707
  const safeValue = sanitizeTerminalText(value);
8685
8708
  const [selectionCursor, setSelectionCursor] = useState4(0);
8686
8709
  const [inputCursor, setInputCursor] = useState4(() => characters2(safeValue).length);
@@ -8843,28 +8866,64 @@ var PromptInput = memo(function PromptInput2({
8843
8866
  const start = Math.max(0, Math.min(active2 - WINDOW2 + 2, suggestions.length - WINDOW2));
8844
8867
  const visible = suggestions.slice(start, start + WINDOW2);
8845
8868
  const fileStart = Math.max(0, Math.min(active2 - WINDOW2 + 2, files.length - WINDOW2));
8846
- return /* @__PURE__ */ jsxs8(Box8, { width: columns, maxWidth: "100%", flexDirection: "column", marginTop: 1, flexShrink: 0, children: [
8847
- /* @__PURE__ */ jsxs8(
8848
- Box8,
8849
- {
8850
- width: "100%",
8851
- paddingX: 1,
8852
- children: [
8853
- /* @__PURE__ */ jsx8(Text8, { color: disabled ? "gray" : theme.accent, children: "\u203A " }),
8854
- /* @__PURE__ */ jsx8(Box8, { flexGrow: 1, flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsx8(EditableText, { value: safeValue, cursor: inputCursor, placeholder: strings.placeholder }) }),
8855
- pending && pending > 0 ? /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
8856
- " \xB7 ",
8857
- strings.queued(pending)
8858
- ] }) : null
8859
- ]
8860
- }
8861
- ),
8869
+ return /* @__PURE__ */ jsxs8(Box8, { width: panelWidth, maxWidth: "100%", flexDirection: "column", marginTop: 1, flexShrink: 0, children: [
8870
+ /* @__PURE__ */ jsxs8(Box8, { width: "100%", flexShrink: 0, children: [
8871
+ /* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256D" }) }),
8872
+ /* @__PURE__ */ jsx8(Box8, { flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsxs8(Text8, { color: panelColor, wrap: "truncate-end", children: [
8873
+ "\u2500 ",
8874
+ panelTitle,
8875
+ " "
8876
+ ] }) }),
8877
+ /* @__PURE__ */ jsx8(
8878
+ Box8,
8879
+ {
8880
+ flexGrow: 1,
8881
+ flexShrink: 1,
8882
+ minWidth: 0,
8883
+ height: 1,
8884
+ borderStyle: "single",
8885
+ borderColor: panelColor,
8886
+ borderTop: false,
8887
+ borderBottom: true,
8888
+ borderLeft: false,
8889
+ borderRight: false
8890
+ }
8891
+ ),
8892
+ /* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256E" }) })
8893
+ ] }),
8894
+ /* @__PURE__ */ jsxs8(Box8, { width: "100%", paddingX: 1, maxHeight: inputRows, overflowY: "hidden", children: [
8895
+ /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u203A " }),
8896
+ /* @__PURE__ */ jsx8(Box8, { flexGrow: 1, flexShrink: 1, minWidth: 0, children: /* @__PURE__ */ jsx8(EditableText, { value: safeValue, cursor: inputCursor, placeholder: strings.placeholder }) }),
8897
+ pending && pending > 0 ? /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
8898
+ " \xB7 ",
8899
+ strings.queued(pending)
8900
+ ] }) : null
8901
+ ] }),
8862
8902
  attachments.length > 0 && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
8863
8903
  " ",
8864
8904
  "\u{1F4CE} ",
8865
8905
  attachments.map(sanitizeTerminalText).join(" \xB7 ")
8866
8906
  ] }),
8867
- disabled && hint && /* @__PURE__ */ jsxs8(Text8, { dimColor: true, children: [
8907
+ /* @__PURE__ */ jsxs8(Box8, { width: "100%", flexShrink: 0, children: [
8908
+ /* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u2570" }) }),
8909
+ /* @__PURE__ */ jsx8(
8910
+ Box8,
8911
+ {
8912
+ flexGrow: 1,
8913
+ flexShrink: 1,
8914
+ minWidth: 0,
8915
+ height: 1,
8916
+ borderStyle: "single",
8917
+ borderColor: panelColor,
8918
+ borderTop: false,
8919
+ borderBottom: true,
8920
+ borderLeft: false,
8921
+ borderRight: false
8922
+ }
8923
+ ),
8924
+ /* @__PURE__ */ jsx8(Box8, { flexShrink: 0, children: /* @__PURE__ */ jsx8(Text8, { color: panelColor, children: "\u256F" }) })
8925
+ ] }),
8926
+ disabled && hint && /* @__PURE__ */ jsxs8(Text8, { color: theme.accent, children: [
8868
8927
  " ",
8869
8928
  sanitizeTerminalText(hint)
8870
8929
  ] }),
@@ -9758,6 +9817,8 @@ var Transcript = memo2(function Transcript2({
9758
9817
  }
9759
9818
  const live = liveAt === -1 ? [] : bubbles.slice(liveAt);
9760
9819
  const staticItems = [HEADER, ...stableRef.current];
9820
+ const agents = live.filter((bubble) => bubble.kind === "subagent");
9821
+ const groupedAgents = agents.length > 1;
9761
9822
  return /* @__PURE__ */ jsxs11(
9762
9823
  Box12,
9763
9824
  {
@@ -9768,7 +9829,7 @@ var Transcript = memo2(function Transcript2({
9768
9829
  overflowY: "hidden",
9769
9830
  children: [
9770
9831
  /* @__PURE__ */ jsx12(Static, { items: staticItems, children: (item) => item.kind === "header" ? /* @__PURE__ */ jsx12(Logo, { workspace }, "kitcode-header") : /* @__PURE__ */ jsx12(BubbleView, { bubble: item }, item.id) }),
9771
- /* @__PURE__ */ jsx12(
9832
+ /* @__PURE__ */ jsxs11(
9772
9833
  Box12,
9773
9834
  {
9774
9835
  flexDirection: "column",
@@ -9777,7 +9838,10 @@ var Transcript = memo2(function Transcript2({
9777
9838
  maxHeight: maxLiveRows,
9778
9839
  overflowY: "hidden",
9779
9840
  justifyContent: "flex-end",
9780
- children: live.map((bubble) => /* @__PURE__ */ jsx12(BubbleView, { bubble, maxRows: maxLiveRows }, bubble.id))
9841
+ children: [
9842
+ live.filter((bubble) => !groupedAgents || bubble.kind !== "subagent" && !(bubble.kind === "tool" && bubble.name === "task")).map((bubble) => /* @__PURE__ */ jsx12(BubbleView, { bubble, maxRows: maxLiveRows }, bubble.id)),
9843
+ groupedAgents && /* @__PURE__ */ jsx12(SubagentSummary, { agents })
9844
+ ]
9781
9845
  }
9782
9846
  )
9783
9847
  ]
@@ -9914,6 +9978,30 @@ function previewLines(content) {
9914
9978
  if (lines.length <= 6) return lines;
9915
9979
  return [...lines.slice(0, 6), `\u2026 ${lines.length - 6} more lines`];
9916
9980
  }
9981
+ var VISIBLE_SUBAGENTS = 3;
9982
+ function SubagentSummary({ agents }) {
9983
+ const theme = useTheme();
9984
+ const running = agents.filter((agent) => agent.state === "running");
9985
+ return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", marginTop: 1, minWidth: 0, children: [
9986
+ /* @__PURE__ */ jsxs11(Text11, { color: theme.accent, wrap: "truncate-end", children: [
9987
+ "Subagents: ",
9988
+ running.length,
9989
+ " running \xB7 ",
9990
+ agents.length - running.length,
9991
+ " done"
9992
+ ] }),
9993
+ running.slice(0, VISIBLE_SUBAGENTS).map((agent) => {
9994
+ const latest = agent.bubbles.at(-1);
9995
+ const progress = latest?.kind === "tool" ? latest.summary : latest?.kind === "assistant" ? sanitizeThinkingText(latest.text || latest.thinking, latest.streaming) : "waiting";
9996
+ return /* @__PURE__ */ jsxs11(Text11, { dimColor: true, wrap: "truncate-end", children: [
9997
+ agent.description,
9998
+ " \xB7 ",
9999
+ progress.replace(/\s+/g, " ").trim() || "waiting"
10000
+ ] }, agent.id);
10001
+ }),
10002
+ /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "/subagents \xB7 all active tasks" })
10003
+ ] });
10004
+ }
9917
10005
  function SubagentView({ bubble, maxRows }) {
9918
10006
  const theme = useTheme();
9919
10007
  const { columns } = useTerminalSize();