@gemdoq/codi 0.1.6 → 0.1.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/cli.js CHANGED
@@ -337,7 +337,7 @@ import * as readline from "readline/promises";
337
337
  import { stdin as input, stdout as output } from "process";
338
338
  var isWindows = os.platform() === "win32";
339
339
  var SETTINGS_DIR = path2.join(
340
- process.env["HOME"] || process.env["USERPROFILE"] || "~",
340
+ process.env["HOME"] || process.env["USERPROFILE"] || os.homedir(),
341
341
  ".codi"
342
342
  );
343
343
  var SETTINGS_PATH = path2.join(SETTINGS_DIR, "settings.json");
@@ -503,6 +503,7 @@ async function runSetupWizard() {
503
503
  // src/config/config.ts
504
504
  init_esm_shims();
505
505
  import * as fs2 from "fs";
506
+ import * as os2 from "os";
506
507
  import * as path3 from "path";
507
508
  var DEFAULT_CONFIG = {
508
509
  provider: "openai",
@@ -532,7 +533,7 @@ var ConfigManager = class {
532
533
  this.loadAll();
533
534
  }
534
535
  loadAll() {
535
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
536
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os2.homedir();
536
537
  this.loadFile(path3.join(home, ".codi", "settings.json"));
537
538
  this.loadFile(path3.join(process.cwd(), ".codi", "settings.json"));
538
539
  this.loadFile(path3.join(process.cwd(), ".codi", "settings.local.json"));
@@ -609,7 +610,7 @@ var ConfigManager = class {
609
610
  return this.configPaths;
610
611
  }
611
612
  save(scope) {
612
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
613
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os2.homedir();
613
614
  let filePath;
614
615
  switch (scope) {
615
616
  case "user":
@@ -635,7 +636,7 @@ var configManager = new ConfigManager();
635
636
  init_esm_shims();
636
637
  import * as readline2 from "readline/promises";
637
638
  import { stdin as input2, stdout as output2 } from "process";
638
- import * as os2 from "os";
639
+ import * as os3 from "os";
639
640
  import chalk4 from "chalk";
640
641
  import { execSync } from "child_process";
641
642
  import { edit } from "external-editor";
@@ -823,19 +824,24 @@ var Repl = class {
823
824
  completer: (line) => completer(line),
824
825
  terminal: true
825
826
  });
826
- if (process.stdin.isTTY && os2.platform() !== "win32") {
827
+ if (process.stdin.isTTY && os3.platform() !== "win32") {
827
828
  process.stdout.write("\x1B[?2004h");
828
829
  }
829
- if (os2.platform() === "win32" && process.stdin.isTTY) {
830
+ if (os3.platform() === "win32" && process.stdin.isTTY) {
830
831
  process.stdin.on("keypress", (_str, key) => {
831
832
  if (key && key.sequence === "") {
832
833
  try {
833
- const clip = execSync("powershell -command Get-Clipboard", {
834
- encoding: "utf-8",
835
- timeout: 3e3
836
- }).replace(/\r\n$/, "");
834
+ const clip = execSync(
835
+ 'powershell -NoProfile -command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; Get-Clipboard"',
836
+ { encoding: "utf-8", timeout: 5e3, env: { ...process.env } }
837
+ ).replace(/\r\n/g, "\n").replace(/\n$/, "");
837
838
  if (clip && this.rl) {
838
- this.rl.write(clip);
839
+ const firstNewline = clip.indexOf("\n");
840
+ if (firstNewline === -1) {
841
+ this.rl.write(clip);
842
+ } else {
843
+ this.rl.write(clip.replace(/\n/g, "\\"));
844
+ }
839
845
  }
840
846
  } catch {
841
847
  }
@@ -906,7 +912,7 @@ var Repl = class {
906
912
  }
907
913
  }
908
914
  }
909
- if (process.stdin.isTTY && os2.platform() !== "win32") {
915
+ if (process.stdin.isTTY && os3.platform() !== "win32") {
910
916
  process.stdout.write("\x1B[?2004l");
911
917
  }
912
918
  }
@@ -929,8 +935,10 @@ var Repl = class {
929
935
  const cmd = input3.slice(1).trim();
930
936
  if (!cmd) return;
931
937
  try {
932
- const shell = os2.platform() === "win32" ? "powershell.exe" : void 0;
933
- const result = execSync(cmd, {
938
+ const isWin = os3.platform() === "win32";
939
+ const shell = isWin ? "powershell.exe" : void 0;
940
+ const finalCmd = isWin ? `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ${cmd}` : cmd;
941
+ const result = execSync(finalCmd, {
934
942
  encoding: "utf-8",
935
943
  stdio: ["inherit", "pipe", "pipe"],
936
944
  timeout: 3e4,
@@ -944,9 +952,20 @@ var Repl = class {
944
952
  }
945
953
  return;
946
954
  }
947
- let message = input3;
948
955
  const IMAGE_EXTS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".svg"]);
956
+ const MIME_MAP = {
957
+ ".png": "image/png",
958
+ ".jpg": "image/jpeg",
959
+ ".jpeg": "image/jpeg",
960
+ ".gif": "image/gif",
961
+ ".webp": "image/webp",
962
+ ".bmp": "image/bmp",
963
+ ".svg": "image/svg+xml"
964
+ };
949
965
  const atMatches = input3.match(/@([\w.\/\\:~-]+)/g);
966
+ let hasImages = false;
967
+ const imageBlocks = [];
968
+ let message = input3;
950
969
  if (atMatches) {
951
970
  for (const match of atMatches) {
952
971
  const filePath = match.slice(1);
@@ -955,19 +974,13 @@ var Repl = class {
955
974
  if (IMAGE_EXTS.has(ext)) {
956
975
  const data = readFileSync3(filePath);
957
976
  const base64 = data.toString("base64");
958
- const mimeMap = {
959
- ".png": "image/png",
960
- ".jpg": "image/jpeg",
961
- ".jpeg": "image/jpeg",
962
- ".gif": "image/gif",
963
- ".webp": "image/webp",
964
- ".bmp": "image/bmp",
965
- ".svg": "image/svg+xml"
966
- };
967
- const mime = mimeMap[ext] || "image/png";
968
- message = message.replace(match, `
969
- [Image: ${filePath}](data:${mime};base64,${base64})
970
- `);
977
+ const mime = MIME_MAP[ext] || "image/png";
978
+ imageBlocks.push({
979
+ type: "image",
980
+ source: { type: "base64", media_type: mime, data: base64 }
981
+ });
982
+ message = message.replace(match, `[\uC774\uBBF8\uC9C0: ${path5.basename(filePath)}]`);
983
+ hasImages = true;
971
984
  } else {
972
985
  const content = readFileSync3(filePath, "utf-8");
973
986
  message = message.replace(match, `
@@ -981,7 +994,15 @@ ${content}
981
994
  }
982
995
  }
983
996
  }
984
- await this.options.onMessage(message);
997
+ if (hasImages) {
998
+ const blocks = [
999
+ { type: "text", text: message.trim() },
1000
+ ...imageBlocks
1001
+ ];
1002
+ await this.options.onMessage(blocks);
1003
+ } else {
1004
+ await this.options.onMessage(message);
1005
+ }
985
1006
  }
986
1007
  openEditor() {
987
1008
  try {
@@ -1434,11 +1455,31 @@ LLM Error: ${errMsg}`));
1434
1455
  console.log("");
1435
1456
  }
1436
1457
  const results = await executor.executeMany(response.toolCalls);
1437
- const toolResults = results.map((r) => ({
1438
- tool_use_id: r.toolUseId,
1439
- content: r.result.output,
1440
- is_error: !r.result.success
1441
- }));
1458
+ const toolResults = results.map((r) => {
1459
+ if (r.result.metadata?.isImage && r.result.metadata.imageData) {
1460
+ const blocks = [
1461
+ { type: "text", text: r.result.output },
1462
+ {
1463
+ type: "image",
1464
+ source: {
1465
+ type: "base64",
1466
+ media_type: r.result.metadata.imageMimeType || "image/png",
1467
+ data: r.result.metadata.imageData
1468
+ }
1469
+ }
1470
+ ];
1471
+ return {
1472
+ tool_use_id: r.toolUseId,
1473
+ content: blocks,
1474
+ is_error: !r.result.success
1475
+ };
1476
+ }
1477
+ return {
1478
+ tool_use_id: r.toolUseId,
1479
+ content: r.result.output,
1480
+ is_error: !r.result.success
1481
+ };
1482
+ });
1442
1483
  conversation.addToolResults(toolResults);
1443
1484
  }
1444
1485
  }
@@ -1503,7 +1544,7 @@ function sleep(ms) {
1503
1544
 
1504
1545
  // src/agent/system-prompt.ts
1505
1546
  init_esm_shims();
1506
- import * as os3 from "os";
1547
+ import * as os4 from "os";
1507
1548
  import { execSync as execSync2 } from "child_process";
1508
1549
  var ROLE_DEFINITION = `You are Codi (\uCF54\uB514), a terminal-based AI coding agent. You help users with software engineering tasks including writing code, debugging, refactoring, and explaining code. You have access to tools for file manipulation, code search, shell execution, and more.
1509
1550
 
@@ -1615,7 +1656,7 @@ function buildSystemPrompt(context) {
1615
1656
  fragments.push(buildEnvironmentInfo(context));
1616
1657
  fragments.push(CONVERSATION_RULES);
1617
1658
  fragments.push(TOOL_HIERARCHY);
1618
- if (os3.platform() === "win32") {
1659
+ if (os4.platform() === "win32") {
1619
1660
  fragments.push(WINDOWS_RULES);
1620
1661
  }
1621
1662
  fragments.push(CODE_RULES);
@@ -1646,8 +1687,8 @@ function buildEnvironmentInfo(context) {
1646
1687
  const lines = [
1647
1688
  "# Environment",
1648
1689
  `- Date: ${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}`,
1649
- `- OS: ${os3.platform()} ${os3.release()}`,
1650
- `- Shell: ${process.env["SHELL"] || process.env["COMSPEC"] || "unknown"}`,
1690
+ `- OS: ${os4.platform()} ${os4.release()}`,
1691
+ `- Shell: ${os4.platform() === "win32" ? "PowerShell" : process.env["SHELL"] || "/bin/bash"}`,
1651
1692
  `- Working Directory: ${context.cwd}`,
1652
1693
  `- Model: ${context.model}`,
1653
1694
  `- Provider: ${context.provider}`
@@ -1718,12 +1759,13 @@ ${summaryContent}`;
1718
1759
  // src/agent/memory.ts
1719
1760
  init_esm_shims();
1720
1761
  import * as fs4 from "fs";
1762
+ import * as os5 from "os";
1721
1763
  import * as path6 from "path";
1722
1764
  import * as crypto from "crypto";
1723
1765
  var MemoryManager = class {
1724
1766
  memoryDir;
1725
1767
  constructor() {
1726
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
1768
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os5.homedir();
1727
1769
  const projectHash = crypto.createHash("md5").update(process.cwd()).digest("hex").slice(0, 8);
1728
1770
  const projectName = path6.basename(process.cwd());
1729
1771
  this.memoryDir = path6.join(home, ".codi", "projects", `${projectName}-${projectHash}`, "memory");
@@ -1780,12 +1822,13 @@ var memoryManager = new MemoryManager();
1780
1822
  // src/agent/session.ts
1781
1823
  init_esm_shims();
1782
1824
  import * as fs5 from "fs";
1825
+ import * as os6 from "os";
1783
1826
  import * as path7 from "path";
1784
1827
  import * as crypto2 from "crypto";
1785
1828
  var SessionManager = class {
1786
1829
  sessionsDir;
1787
1830
  constructor() {
1788
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
1831
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os6.homedir();
1789
1832
  this.sessionsDir = path7.join(home, ".codi", "sessions");
1790
1833
  }
1791
1834
  ensureDir() {
@@ -2208,9 +2251,9 @@ async function promptUser(tool, input3) {
2208
2251
  // src/hooks/hook-manager.ts
2209
2252
  init_esm_shims();
2210
2253
  import { exec } from "child_process";
2211
- import * as os4 from "os";
2254
+ import * as os7 from "os";
2212
2255
  function getDefaultShell() {
2213
- if (os4.platform() === "win32") {
2256
+ if (os7.platform() === "win32") {
2214
2257
  return "powershell.exe";
2215
2258
  }
2216
2259
  return void 0;
@@ -2247,7 +2290,9 @@ var HookManager = class {
2247
2290
  session_id: context["sessionId"],
2248
2291
  cwd: context["cwd"] || process.cwd()
2249
2292
  });
2250
- const proc = exec(command, {
2293
+ const isWin = os7.platform() === "win32";
2294
+ const finalCommand = isWin ? `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ${command}` : command;
2295
+ const proc = exec(finalCommand, {
2251
2296
  timeout: timeout || 5e3,
2252
2297
  cwd: process.cwd(),
2253
2298
  env: { ...process.env },
@@ -2288,6 +2333,7 @@ var hookManager = new HookManager();
2288
2333
  init_esm_shims();
2289
2334
  init_tool();
2290
2335
  import * as fs7 from "fs";
2336
+ import * as os8 from "os";
2291
2337
  import * as path9 from "path";
2292
2338
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2293
2339
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
@@ -2308,7 +2354,7 @@ var McpManager = class {
2308
2354
  }
2309
2355
  loadMcpConfigs() {
2310
2356
  const configs = {};
2311
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
2357
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os8.homedir();
2312
2358
  const paths = [
2313
2359
  path9.join(home, ".codi", "mcp.json"),
2314
2360
  path9.join(process.cwd(), ".codi", "mcp.json")
@@ -2512,7 +2558,7 @@ var subAgentTool = {
2512
2558
  // src/config/slash-commands.ts
2513
2559
  init_esm_shims();
2514
2560
  import * as fs8 from "fs";
2515
- import * as os5 from "os";
2561
+ import * as os9 from "os";
2516
2562
  import * as path10 from "path";
2517
2563
  import chalk11 from "chalk";
2518
2564
  function createBuiltinCommands() {
@@ -2923,7 +2969,7 @@ ${diff}
2923
2969
  console.log(chalk11.yellow("Usage: /search <keyword>"));
2924
2970
  return true;
2925
2971
  }
2926
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
2972
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os9.homedir();
2927
2973
  const sessionsDir = path10.join(home, ".codi", "sessions");
2928
2974
  if (!fs8.existsSync(sessionsDir)) {
2929
2975
  console.log(chalk11.dim("\nNo sessions found.\n"));
@@ -2975,8 +3021,10 @@ Search results for "${args}":
2975
3021
  }
2976
3022
  const { execSync: execSync5 } = await import("child_process");
2977
3023
  try {
2978
- const shell = os5.platform() === "win32" ? "powershell.exe" : void 0;
2979
- const output3 = execSync5(args, { encoding: "utf-8", cwd: process.cwd(), stdio: "pipe", shell });
3024
+ const isWin = os9.platform() === "win32";
3025
+ const shell = isWin ? "powershell.exe" : void 0;
3026
+ const fixCmd = isWin ? `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ${args}` : args;
3027
+ const output3 = execSync5(fixCmd, { encoding: "utf-8", cwd: process.cwd(), stdio: "pipe", shell });
2980
3028
  console.log(chalk11.green(`
2981
3029
  \u2713 Command succeeded. No errors to fix.
2982
3030
  `));
@@ -3026,7 +3074,7 @@ ${errorOutput}
3026
3074
  }
3027
3075
  function loadCustomCommands() {
3028
3076
  const commands = [];
3029
- const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
3077
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || os9.homedir();
3030
3078
  const dirs = [
3031
3079
  path10.join(home, ".codi", "commands"),
3032
3080
  path10.join(process.cwd(), ".codi", "commands")
@@ -3589,6 +3637,7 @@ async function builtinSearch(pattern, searchPath, input3, outputMode, headLimit)
3589
3637
  } catch {
3590
3638
  continue;
3591
3639
  }
3640
+ content = content.replace(/\r\n/g, "\n");
3592
3641
  const lines = content.split("\n");
3593
3642
  const matchedLineIndices = /* @__PURE__ */ new Set();
3594
3643
  let fileMatchCount = 0;
@@ -3683,9 +3732,9 @@ function collectFiles(dirPath, typeFilter, globFilter) {
3683
3732
  init_esm_shims();
3684
3733
  init_tool();
3685
3734
  import { exec as exec2, spawn } from "child_process";
3686
- import * as os6 from "os";
3735
+ import * as os10 from "os";
3687
3736
  function getDefaultShell2() {
3688
- if (os6.platform() === "win32") {
3737
+ if (os10.platform() === "win32") {
3689
3738
  return "powershell.exe";
3690
3739
  }
3691
3740
  return process.env["SHELL"] || "/bin/bash";
@@ -3694,7 +3743,7 @@ var backgroundTasks = /* @__PURE__ */ new Map();
3694
3743
  var taskCounter = 0;
3695
3744
  var bashTool = {
3696
3745
  name: "bash",
3697
- description: `Execute a shell command. Supports timeout (max 600s, default 120s) and background execution. The working directory persists between calls. Uses the platform default shell (bash on Unix, cmd.exe on Windows).`,
3746
+ description: `Execute a shell command. Supports timeout (max 600s, default 120s) and background execution. The working directory persists between calls. Uses the platform default shell (bash on Unix, PowerShell on Windows).`,
3698
3747
  inputSchema: {
3699
3748
  type: "object",
3700
3749
  properties: {
@@ -3718,7 +3767,8 @@ var bashTool = {
3718
3767
  return runBackgroundTask(command);
3719
3768
  }
3720
3769
  return new Promise((resolve10) => {
3721
- exec2(command, {
3770
+ const finalCommand = os10.platform() === "win32" ? `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ${command}` : command;
3771
+ exec2(finalCommand, {
3722
3772
  timeout,
3723
3773
  maxBuffer: 10 * 1024 * 1024,
3724
3774
  shell: getDefaultShell2(),
@@ -3754,7 +3804,8 @@ ${stderr}` : ""
3754
3804
  };
3755
3805
  function runBackgroundTask(command) {
3756
3806
  const taskId = `bg_${++taskCounter}`;
3757
- const proc = spawn(command, {
3807
+ const bgCommand = os10.platform() === "win32" ? `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8; ${command}` : command;
3808
+ const proc = spawn(bgCommand, {
3758
3809
  shell: getDefaultShell2(),
3759
3810
  cwd: process.cwd(),
3760
3811
  env: { ...process.env },
@@ -4292,13 +4343,38 @@ var AnthropicProvider = class {
4292
4343
  name: block.name,
4293
4344
  input: block.input
4294
4345
  };
4295
- case "tool_result":
4346
+ case "tool_result": {
4347
+ let trContent;
4348
+ if (typeof block.content === "string") {
4349
+ trContent = block.content;
4350
+ } else if (Array.isArray(block.content)) {
4351
+ trContent = [];
4352
+ for (const cb of block.content) {
4353
+ if (cb.type === "text") {
4354
+ trContent.push({ type: "text", text: cb.text });
4355
+ } else if (cb.type === "image") {
4356
+ trContent.push({
4357
+ type: "image",
4358
+ source: {
4359
+ type: "base64",
4360
+ media_type: cb.source.media_type,
4361
+ data: cb.source.data
4362
+ }
4363
+ });
4364
+ } else {
4365
+ trContent.push({ type: "text", text: JSON.stringify(cb) });
4366
+ }
4367
+ }
4368
+ } else {
4369
+ trContent = JSON.stringify(block.content);
4370
+ }
4296
4371
  return {
4297
4372
  type: "tool_result",
4298
4373
  tool_use_id: block.tool_use_id,
4299
- content: typeof block.content === "string" ? block.content : JSON.stringify(block.content),
4374
+ content: trContent,
4300
4375
  ...block.is_error ? { is_error: true } : {}
4301
4376
  };
4377
+ }
4302
4378
  default:
4303
4379
  return { type: "text", text: JSON.stringify(block) };
4304
4380
  }
@@ -4502,15 +4578,43 @@ var OpenAIProvider = class {
4502
4578
  }
4503
4579
  const hasToolResults = m.content.some((b) => b.type === "tool_result");
4504
4580
  if (hasToolResults) {
4581
+ const pendingImages = [];
4505
4582
  for (const block of m.content) {
4506
4583
  if (block.type === "tool_result") {
4507
- result.push({
4508
- role: "tool",
4509
- tool_call_id: block.tool_use_id,
4510
- content: typeof block.content === "string" ? block.content : JSON.stringify(block.content)
4511
- });
4584
+ if (Array.isArray(block.content)) {
4585
+ const textParts = [];
4586
+ for (const cb of block.content) {
4587
+ if (cb.type === "text") textParts.push(cb.text);
4588
+ else if (cb.type === "image") {
4589
+ pendingImages.push({
4590
+ type: "image_url",
4591
+ image_url: { url: `data:${cb.source.media_type};base64,${cb.source.data}` }
4592
+ });
4593
+ }
4594
+ }
4595
+ result.push({
4596
+ role: "tool",
4597
+ tool_call_id: block.tool_use_id,
4598
+ content: textParts.join("\n") || "(image)"
4599
+ });
4600
+ } else {
4601
+ result.push({
4602
+ role: "tool",
4603
+ tool_call_id: block.tool_use_id,
4604
+ content: block.content
4605
+ });
4606
+ }
4512
4607
  }
4513
4608
  }
4609
+ if (pendingImages.length > 0) {
4610
+ result.push({
4611
+ role: "user",
4612
+ content: [
4613
+ { type: "text", text: "\uC704 \uB3C4\uAD6C\uAC00 \uBC18\uD658\uD55C \uC774\uBBF8\uC9C0\uC785\uB2C8\uB2E4. \uC774 \uC774\uBBF8\uC9C0\uB97C \uBD84\uC11D\uC5D0 \uD65C\uC6A9\uD558\uC138\uC694." },
4614
+ ...pendingImages
4615
+ ]
4616
+ });
4617
+ }
4514
4618
  continue;
4515
4619
  }
4516
4620
  const hasToolUse = m.content.some((b) => b.type === "tool_use");
@@ -4701,7 +4805,14 @@ var OllamaProvider = class {
4701
4805
  } else if (block.type === "image") {
4702
4806
  images.push(block.source.data);
4703
4807
  } else if (block.type === "tool_result") {
4704
- textParts.push(`[Tool Result: ${typeof block.content === "string" ? block.content : JSON.stringify(block.content)}]`);
4808
+ if (Array.isArray(block.content)) {
4809
+ for (const cb of block.content) {
4810
+ if (cb.type === "text") textParts.push(cb.text);
4811
+ else if (cb.type === "image") images.push(cb.source.data);
4812
+ }
4813
+ } else {
4814
+ textParts.push(`[Tool Result: ${block.content}]`);
4815
+ }
4705
4816
  } else if (block.type === "tool_use") {
4706
4817
  textParts.push(`[Tool Call: ${block.name}(${JSON.stringify(block.input)})]`);
4707
4818
  }
@@ -4832,7 +4943,16 @@ async function main() {
4832
4943
  process.exit(0);
4833
4944
  }
4834
4945
  if (args.version) {
4835
- console.log("codi v0.1.0");
4946
+ try {
4947
+ const { readFileSync: readFileSync14 } = await import("fs");
4948
+ const { fileURLToPath: fileURLToPath3 } = await import("url");
4949
+ const p = await import("path");
4950
+ const dir = p.dirname(fileURLToPath3(import.meta.url));
4951
+ const pkg = JSON.parse(readFileSync14(p.join(dir, "..", "package.json"), "utf-8"));
4952
+ console.log(`codi v${pkg.version}`);
4953
+ } catch {
4954
+ console.log("codi v0.1.8");
4955
+ }
4836
4956
  process.exit(0);
4837
4957
  }
4838
4958
  if (await needsSetup()) {
@@ -4991,7 +5111,8 @@ async function main() {
4991
5111
  };
4992
5112
  const repl = new Repl({
4993
5113
  onMessage: async (message) => {
4994
- checkpointManager.create(conversation, message.slice(0, 50));
5114
+ const preview = typeof message === "string" ? message.slice(0, 50) : message.find((b) => b.type === "text")?.text?.slice(0, 50) || "image";
5115
+ checkpointManager.create(conversation, preview);
4995
5116
  if (compressor.shouldCompress(conversation)) {
4996
5117
  console.log(chalk13.dim("Auto-compacting conversation..."));
4997
5118
  await compressor.compress(conversation, provider);