zelari-code 0.2.1 → 0.2.2

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.
@@ -637,7 +637,7 @@ import { render } from "ink";
637
637
 
638
638
  // src/cli/app.tsx
639
639
  import React6, { useState as useState2, useMemo, useEffect, useRef } from "react";
640
- import { Box as Box6 } from "ink";
640
+ import { Box as Box6, useStdout } from "ink";
641
641
 
642
642
  // src/cli/components/Header.tsx
643
643
  import React from "react";
@@ -746,8 +746,52 @@ function CollapsibleToolOutput(props) {
746
746
  }
747
747
 
748
748
  // src/cli/components/ChatStream.tsx
749
- function ChatStream({ messages }) {
750
- return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", flexGrow: 1, paddingX: 1 }, messages.length === 0 ? /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "Ready. Type a prompt or /skill <name> to invoke a skill.") : messages.map((m) => {
749
+ function estimateMessageHeight(m, width) {
750
+ if (m.role === "tool") {
751
+ return 1;
752
+ }
753
+ const lines = m.content.split("\n");
754
+ let textRows = 0;
755
+ for (const line of lines) {
756
+ textRows += Math.max(1, Math.ceil(line.length / width));
757
+ }
758
+ return 1 + textRows + 1;
759
+ }
760
+ function ChatStream({ messages, height, width }) {
761
+ const visibleMessages = [];
762
+ let remainingHeight = height - 1;
763
+ for (let i = messages.length - 1; i >= 0; i--) {
764
+ const m = messages[i];
765
+ const mHeight = estimateMessageHeight(m, width);
766
+ if (remainingHeight - mHeight >= 0) {
767
+ visibleMessages.unshift(m);
768
+ remainingHeight -= mHeight;
769
+ } else {
770
+ if (remainingHeight > 2) {
771
+ const maxTextRows = remainingHeight - 2;
772
+ const lines = m.content.split("\n");
773
+ const truncatedLines = [];
774
+ let currentRows = 0;
775
+ for (let j = lines.length - 1; j >= 0; j--) {
776
+ const line = lines[j];
777
+ const lineRows = Math.max(1, Math.ceil(line.length / width));
778
+ if (currentRows + lineRows <= maxTextRows) {
779
+ truncatedLines.unshift(line);
780
+ currentRows += lineRows;
781
+ } else {
782
+ truncatedLines.unshift("... [truncated]");
783
+ break;
784
+ }
785
+ }
786
+ visibleMessages.unshift({
787
+ ...m,
788
+ content: truncatedLines.join("\n")
789
+ });
790
+ }
791
+ break;
792
+ }
793
+ }
794
+ return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", flexGrow: 1, paddingX: 1, height }, visibleMessages.length === 0 ? /* @__PURE__ */ React3.createElement(Text3, { dimColor: true }, "Ready. Type a prompt or /skill <name> to invoke a skill.") : visibleMessages.map((m) => {
751
795
  if (m.role === "tool") {
752
796
  return /* @__PURE__ */ React3.createElement(
753
797
  CollapsibleToolOutput,
@@ -785,8 +829,16 @@ function InputBar({ value, onChange, onSubmit, disabled }) {
785
829
  // src/cli/components/Sidebar.tsx
786
830
  import React5 from "react";
787
831
  import { Box as Box5, Text as Text5 } from "ink";
788
- function Sidebar({ skillList, sessionCount, isSlashMode }) {
789
- return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: 40, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: "cyan" }, "Skills & sessions"), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "Sessions: ", sessionCount), isSlashMode && /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "\u2328 slash command mode"), /* @__PURE__ */ React5.createElement(Box5, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Text5, null, skillList)));
832
+ function Sidebar({ skillList, sessionCount, isSlashMode, height }) {
833
+ const lines = skillList.split("\n");
834
+ const headerLines = 3 + (isSlashMode ? 1 : 0);
835
+ const maxSkillLines = Math.max(2, height - headerLines - 3);
836
+ const visibleSkillLines = lines.slice(0, maxSkillLines);
837
+ const showTruncatedIndicator = lines.length > maxSkillLines;
838
+ if (showTruncatedIndicator) {
839
+ visibleSkillLines.push(" ... (more in /skills)");
840
+ }
841
+ return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", width: 40, height, borderStyle: "single", borderColor: "gray", paddingX: 1 }, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: "cyan" }, "Skills & sessions"), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "Sessions: ", sessionCount), isSlashMode && /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "\u2328 slash command mode"), /* @__PURE__ */ React5.createElement(Box5, { marginTop: 1, flexDirection: "column" }, visibleSkillLines.map((line, idx) => /* @__PURE__ */ React5.createElement(Text5, { key: idx }, line))));
790
842
  }
791
843
 
792
844
  // src/cli/slashCommands.ts
@@ -4011,7 +4063,18 @@ var AgentHarness = class {
4011
4063
  signal: this.activeController?.signal
4012
4064
  }
4013
4065
  );
4014
- const resultStr = result.ok ? String(result.value) : result.error;
4066
+ let resultStr = "";
4067
+ if (result.ok) {
4068
+ if (typeof result.value === "string") {
4069
+ resultStr = result.value;
4070
+ } else if (typeof result.value === "object" && result.value !== null) {
4071
+ resultStr = JSON.stringify(result.value, null, 2);
4072
+ } else {
4073
+ resultStr = String(result.value);
4074
+ }
4075
+ } else {
4076
+ resultStr = result.error;
4077
+ }
4015
4078
  const endEvent = createBrainEvent(
4016
4079
  "tool_execution_end",
4017
4080
  this.sessionId,
@@ -6340,6 +6403,14 @@ function setCurrentBranch(_name, _baseDir) {
6340
6403
 
6341
6404
  // src/main/core/tools/zodBridge.ts
6342
6405
  function zodToJsonSchema(schema) {
6406
+ if (typeof schema.toJSONSchema === "function") {
6407
+ const res = schema.toJSONSchema();
6408
+ if (res && typeof res === "object") {
6409
+ const copy = { ...res };
6410
+ delete copy["$schema"];
6411
+ return copy;
6412
+ }
6413
+ }
6343
6414
  return _convert(schema);
6344
6415
  }
6345
6416
  function _convert(schema) {
@@ -21980,6 +22051,25 @@ function App() {
21980
22051
  const writerRef = useRef(null);
21981
22052
  const harnessRef = useRef(null);
21982
22053
  const [queueCount, setQueueCount] = useState2(0);
22054
+ const { stdout } = useStdout();
22055
+ const [size, setSize] = useState2({
22056
+ columns: stdout?.columns ?? 80,
22057
+ rows: stdout?.rows ?? 24
22058
+ });
22059
+ useEffect(() => {
22060
+ if (!stdout) return;
22061
+ const handleResize = () => {
22062
+ setSize({
22063
+ columns: stdout.columns ?? 80,
22064
+ rows: stdout.rows ?? 24
22065
+ });
22066
+ };
22067
+ stdout.on("resize", handleResize);
22068
+ return () => {
22069
+ stdout.off("resize", handleResize);
22070
+ };
22071
+ }, [stdout]);
22072
+ const chatWidth = Math.max(20, size.columns - 44);
21983
22073
  const skills = useMemo(() => listCodingSkills(), []);
21984
22074
  const skillList = useMemo(() => formatSkillList(skills), [skills]);
21985
22075
  const isSlashMode = input.startsWith("/");
@@ -22083,8 +22173,8 @@ function App() {
22083
22173
  toolList,
22084
22174
  "",
22085
22175
  "# Guidelines",
22086
- "- To understand a project, list files (bash: ls) and read key files (read_file), don't ask the user to paste them.",
22087
- "- Be proactive: explore, read, and act. Prefer doing over asking.",
22176
+ "- When the user asks you to write code, debug, or explore, be proactive: list files (bash: ls, list_files) and read key files (read_file) to understand the project instead of asking the user to paste file contents.",
22177
+ `- Only invoke tools when they are necessary to answer the user's prompt. If the user is just saying hello or greeting you (e.g., "ciao", "hello"), simply greet them back and ask how you can help, without running any commands or tools.`,
22088
22178
  "- When you finish a task, briefly summarize what you did."
22089
22179
  ].join("\n");
22090
22180
  const harness = new AgentHarness({
@@ -23413,7 +23503,7 @@ ${lines.join("\n")}`,
23413
23503
  }
23414
23504
  setInput("");
23415
23505
  };
23416
- return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column" }, /* @__PURE__ */ React6.createElement(
23506
+ return /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", width: size.columns, height: size.rows }, /* @__PURE__ */ React6.createElement(
23417
23507
  Header,
23418
23508
  {
23419
23509
  model: activeModel,
@@ -23424,12 +23514,13 @@ ${lines.join("\n")}`,
23424
23514
  totalTokens: sessionStats.totalTokens,
23425
23515
  totalCostUsd: sessionStats.totalCostUsd
23426
23516
  }
23427
- ), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "row" }, /* @__PURE__ */ React6.createElement(ChatStream, { messages }), /* @__PURE__ */ React6.createElement(
23517
+ ), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "row", height: size.rows - 6 }, /* @__PURE__ */ React6.createElement(ChatStream, { messages, height: size.rows - 6, width: chatWidth }), /* @__PURE__ */ React6.createElement(
23428
23518
  Sidebar,
23429
23519
  {
23430
23520
  skillList,
23431
23521
  sessionCount: messages.length,
23432
- isSlashMode
23522
+ isSlashMode,
23523
+ height: size.rows - 6
23433
23524
  }
23434
23525
  )), /* @__PURE__ */ React6.createElement(
23435
23526
  InputBar,
@@ -23443,7 +23534,7 @@ ${lines.join("\n")}`,
23443
23534
  }
23444
23535
 
23445
23536
  // src/cli/main.ts
23446
- var VERSION = "0.2.1";
23537
+ var VERSION = "0.2.2";
23447
23538
  async function backgroundUpdateCheck() {
23448
23539
  if (process.env.ANATHEMA_DEV === "1") return;
23449
23540
  await new Promise((resolve) => setTimeout(resolve, 3e3));