kimiflare 0.13.1 → 0.13.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.
package/dist/index.js CHANGED
@@ -782,7 +782,7 @@ How to work:
782
782
  - You have a 262k-token context window. Read as much of a file as needed rather than guessing.
783
783
  - If a request is ambiguous, ask one focused question instead of making large assumptions.
784
784
  - When you finish a task, stop. Do not add a closing summary.
785
- - When creating git commits, you may include \`Co-authored-by: kimiflare <kimiflare@proton.me>\` in the commit message so kimiflare is credited as a contributor. The bash tool will also auto-append this trailer when it detects \`git commit\` commands.`;
785
+ - When creating git commits, you must include \`Co-authored-by: kimiflare <kimiflare@proton.me>\` in the commit message so kimiflare is credited as a contributor. The bash tool will also auto-append this trailer when it detects git commit-creating commands.`;
786
786
  const ctx = loadContextFile(opts2.cwd);
787
787
  const contextBlock = ctx ? `
788
788
 
@@ -977,6 +977,8 @@ var init_edit = __esm({
977
977
 
978
978
  // src/tools/bash.ts
979
979
  import { spawn } from "child_process";
980
+ import { tmpdir } from "os";
981
+ import { join as join3 } from "path";
980
982
  function formatBashTitle(raw) {
981
983
  let cmd = (raw ?? "").trim();
982
984
  const m = cmd.match(/^cd\s+([^\s&;]+)\s*(?:&&|;)\s*(.*)$/);
@@ -987,13 +989,28 @@ function injectCoauthor(command, coauthor) {
987
989
  if (!coauthor) return command;
988
990
  const trailer = `Co-authored-by: ${coauthor.name} <${coauthor.email}>`;
989
991
  const trimmed = command.trim();
990
- if (!/\bgit\s+commit\b/.test(trimmed)) return command;
991
992
  if (command.includes(trailer)) return command;
992
- if (/\b(--dry-run|-n)\b/.test(trimmed) && !/-m\b|--message\b/.test(trimmed)) return command;
993
- const tmpFile = `/tmp/kf-coauthor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
994
- const check = `! git log -1 --pretty=%B 2>/dev/null | grep -qF "${trailer}"`;
995
- const append = `git log -1 --pretty=%B | git interpret-trailers --trailer "${trailer}" > "${tmpFile}" && git commit --amend -F "${tmpFile}" --no-edit && rm -f "${tmpFile}"`;
996
- return `(${command}) && ${check} && ${append}`;
993
+ const createsCommit = /\bgit\s+(commit|merge|revert|cherry-pick)\b/.test(trimmed);
994
+ const isRebaseContinue = /\bgit\s+rebase\b/.test(trimmed) && !/\b--abort\b|\b--skip\b/.test(trimmed);
995
+ const mentionsGit = /\bgit\b/.test(trimmed);
996
+ if (!createsCommit && !isRebaseContinue && !mentionsGit) return command;
997
+ const tmpFile = join3(tmpdir(), `kf-coauthor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
998
+ const amendBlock = `
999
+ if ! git log -1 --pretty=%B 2>/dev/null | grep -qF "${trailer}"; then
1000
+ git log -1 --pretty=%B | git interpret-trailers --trailer "${trailer}" > "${tmpFile}" && git commit --amend -F "${tmpFile}" --no-edit && rm -f "${tmpFile}"
1001
+ fi
1002
+ `.trim();
1003
+ if (createsCommit || isRebaseContinue) {
1004
+ return `(${command}) && { ${amendBlock}; }`;
1005
+ }
1006
+ const beforeHead = `git rev-parse HEAD 2>/dev/null || echo "NO_HEAD"`;
1007
+ const afterCheck = `
1008
+ _KF_AFTER_HEAD=$(git rev-parse HEAD 2>/dev/null || echo "NO_HEAD")
1009
+ if [ "$_KF_BEFORE_HEAD" != "$_KF_AFTER_HEAD" ] && [ "$_KF_AFTER_HEAD" != "NO_HEAD" ]; then
1010
+ ${amendBlock}
1011
+ fi
1012
+ `.trim();
1013
+ return `_KF_BEFORE_HEAD=$(${beforeHead}); (${command}); _KF_EXIT=$?; [ $_KF_EXIT -eq 0 ] && { ${afterCheck}; }; exit $_KF_EXIT`;
997
1014
  }
998
1015
  function runBash(args, ctx) {
999
1016
  const timeout = Math.min(Math.max(1e3, args.timeout_ms ?? DEFAULT_TIMEOUT), MAX_TIMEOUT);
@@ -1437,16 +1454,16 @@ var init_executor = __esm({
1437
1454
  // src/util/update-check.ts
1438
1455
  import { readFile as readFile6, writeFile as writeFile4, mkdir as mkdir3, access } from "fs/promises";
1439
1456
  import { homedir as homedir4 } from "os";
1440
- import { join as join3, dirname as dirname2 } from "path";
1457
+ import { join as join4, dirname as dirname2 } from "path";
1441
1458
  import { fileURLToPath } from "url";
1442
1459
  function cachePath() {
1443
- const xdg = process.env.XDG_CONFIG_HOME || join3(homedir4(), ".config");
1444
- return join3(xdg, "kimiflare", "update-check.json");
1460
+ const xdg = process.env.XDG_CONFIG_HOME || join4(homedir4(), ".config");
1461
+ return join4(xdg, "kimiflare", "update-check.json");
1445
1462
  }
1446
1463
  async function findPackageJson(startDir) {
1447
1464
  let dir = startDir;
1448
1465
  while (true) {
1449
- const candidate = join3(dir, "package.json");
1466
+ const candidate = join4(dir, "package.json");
1450
1467
  try {
1451
1468
  const raw = await readFile6(candidate, "utf8");
1452
1469
  const parsed = JSON.parse(raw);
@@ -1530,7 +1547,7 @@ async function isGitRepo() {
1530
1547
  let dir = dirname2(fileURLToPath(import.meta.url));
1531
1548
  while (true) {
1532
1549
  try {
1533
- await access(join3(dir, ".git"));
1550
+ await access(join4(dir, ".git"));
1534
1551
  return true;
1535
1552
  } catch {
1536
1553
  }
@@ -3481,10 +3498,10 @@ var init_theme = __esm({
3481
3498
  // src/sessions.ts
3482
3499
  import { readFile as readFile7, writeFile as writeFile5, mkdir as mkdir4, readdir, stat as stat2 } from "fs/promises";
3483
3500
  import { homedir as homedir5 } from "os";
3484
- import { join as join4 } from "path";
3501
+ import { join as join5 } from "path";
3485
3502
  function sessionsDir() {
3486
- const xdg = process.env.XDG_DATA_HOME || join4(homedir5(), ".local", "share");
3487
- return join4(xdg, "kimiflare", "sessions");
3503
+ const xdg = process.env.XDG_DATA_HOME || join5(homedir5(), ".local", "share");
3504
+ return join5(xdg, "kimiflare", "sessions");
3488
3505
  }
3489
3506
  function sanitize(text) {
3490
3507
  return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
@@ -3497,7 +3514,7 @@ function makeSessionId(firstPrompt) {
3497
3514
  async function saveSession(file) {
3498
3515
  const dir = sessionsDir();
3499
3516
  await mkdir4(dir, { recursive: true });
3500
- const path = join4(dir, `${file.id}.json`);
3517
+ const path = join5(dir, `${file.id}.json`);
3501
3518
  await writeFile5(path, JSON.stringify(file, null, 2), "utf8");
3502
3519
  return path;
3503
3520
  }
@@ -3512,7 +3529,7 @@ async function listSessions(limit = 30) {
3512
3529
  const summaries = [];
3513
3530
  for (const name of entries) {
3514
3531
  if (!name.endsWith(".json")) continue;
3515
- const path = join4(dir, name);
3532
+ const path = join5(dir, name);
3516
3533
  try {
3517
3534
  const [s, raw] = await Promise.all([stat2(path), readFile7(path, "utf8")]);
3518
3535
  const parsed = JSON.parse(raw);
@@ -3589,7 +3606,7 @@ __export(app_exports, {
3589
3606
  import { useState as useState6, useRef as useRef3, useEffect as useEffect4, useCallback } from "react";
3590
3607
  import { Box as Box12, Text as Text13, useApp, useInput as useInput2, render } from "ink";
3591
3608
  import { existsSync } from "fs";
3592
- import { join as join5 } from "path";
3609
+ import { join as join6 } from "path";
3593
3610
  import { unlink } from "fs/promises";
3594
3611
  import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
3595
3612
  function capEvents(prev) {
@@ -3963,13 +3980,13 @@ function App({ initialCfg, initialUpdateResult }) {
3963
3980
  }
3964
3981
  const cwd = process.cwd();
3965
3982
  for (const name of ["KIMI.md", "KIMIFLARE.md", "AGENT.md"]) {
3966
- if (existsSync(join5(cwd, name))) {
3983
+ if (existsSync(join6(cwd, name))) {
3967
3984
  setEvents((e) => [
3968
3985
  ...e,
3969
3986
  {
3970
3987
  kind: "info",
3971
3988
  key: mkKey(),
3972
- text: `${name} already exists at ${join5(cwd, name)} \u2014 delete it first if you want to regenerate`
3989
+ text: `${name} already exists at ${join6(cwd, name)} \u2014 delete it first if you want to regenerate`
3973
3990
  }
3974
3991
  ]);
3975
3992
  return;
@@ -4094,7 +4111,7 @@ function App({ initialCfg, initialUpdateResult }) {
4094
4111
  cfg,
4095
4112
  (text) => setEvents((es) => [...es, { kind: "info", key: mkKey(), text }])
4096
4113
  );
4097
- if (existsSync(join5(cwd, "KIMI.md"))) {
4114
+ if (existsSync(join6(cwd, "KIMI.md"))) {
4098
4115
  messagesRef.current[0] = {
4099
4116
  role: "system",
4100
4117
  content: buildSystemPrompt({
@@ -4802,11 +4819,11 @@ init_update_check();
4802
4819
  import { Command } from "commander";
4803
4820
  import { readFileSync as readFileSync2 } from "fs";
4804
4821
  import { fileURLToPath as fileURLToPath2 } from "url";
4805
- import { dirname as dirname3, join as join6 } from "path";
4822
+ import { dirname as dirname3, join as join7 } from "path";
4806
4823
  function readPackageVersion() {
4807
4824
  try {
4808
4825
  const here = dirname3(fileURLToPath2(import.meta.url));
4809
- const pkg = JSON.parse(readFileSync2(join6(here, "..", "package.json"), "utf8"));
4826
+ const pkg = JSON.parse(readFileSync2(join7(here, "..", "package.json"), "utf8"));
4810
4827
  return pkg.version ?? "0.0.0";
4811
4828
  } catch {
4812
4829
  return "0.0.0";