kimiflare 0.4.0 → 0.5.0

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
@@ -21,19 +21,30 @@ function readReasoningEffortEnv() {
21
21
  if (raw === "low" || raw === "medium" || raw === "high") return raw;
22
22
  return void 0;
23
23
  }
24
+ function readCoauthorEnv() {
25
+ const enabled = process.env.KIMIFLARE_COAUTHOR;
26
+ if (enabled === "0" || enabled === "false") return void 0;
27
+ const name = process.env.KIMIFLARE_COAUTHOR_NAME || "kimiflare";
28
+ const email = process.env.KIMIFLARE_COAUTHOR_EMAIL || "sinameraji@users.noreply.github.com";
29
+ return { enabled: true, name, email };
30
+ }
24
31
  async function loadConfig() {
25
32
  const envAccount = process.env.CLOUDFLARE_ACCOUNT_ID ?? process.env.CF_ACCOUNT_ID;
26
33
  const envToken = process.env.CLOUDFLARE_API_TOKEN ?? process.env.CF_API_TOKEN;
27
34
  const envModel = process.env.KIMI_MODEL ?? DEFAULT_MODEL;
28
35
  const envEffort = readReasoningEffortEnv();
29
36
  const envTheme = process.env.KIMI_THEME;
37
+ const envCoauthor = readCoauthorEnv();
30
38
  if (envAccount && envToken) {
31
39
  return {
32
40
  accountId: envAccount,
33
41
  apiToken: envToken,
34
42
  model: envModel,
35
43
  theme: envTheme,
36
- reasoningEffort: envEffort
44
+ reasoningEffort: envEffort,
45
+ coauthor: envCoauthor?.enabled ?? true,
46
+ coauthorName: envCoauthor?.name,
47
+ coauthorEmail: envCoauthor?.email
37
48
  };
38
49
  }
39
50
  try {
@@ -45,7 +56,10 @@ async function loadConfig() {
45
56
  apiToken: envToken ?? parsed.apiToken,
46
57
  model: envModel ?? parsed.model ?? DEFAULT_MODEL,
47
58
  theme: envTheme ?? parsed.theme,
48
- reasoningEffort: envEffort ?? parsed.reasoningEffort
59
+ reasoningEffort: envEffort ?? parsed.reasoningEffort,
60
+ coauthor: envCoauthor?.enabled ?? parsed.coauthor ?? true,
61
+ coauthorName: envCoauthor?.name ?? parsed.coauthorName,
62
+ coauthorEmail: envCoauthor?.email ?? parsed.coauthorEmail
49
63
  };
50
64
  }
51
65
  } catch {
@@ -358,7 +372,7 @@ async function runAgentTurn(opts2) {
358
372
  const result = await opts2.executor.run(
359
373
  { id: tc.id, name: tc.function.name, arguments: tc.function.arguments },
360
374
  opts2.callbacks.askPermission,
361
- { cwd: opts2.cwd, signal: opts2.signal, onTasks: opts2.callbacks.onTasks }
375
+ { cwd: opts2.cwd, signal: opts2.signal, onTasks: opts2.callbacks.onTasks, coauthor: opts2.coauthor }
362
376
  );
363
377
  opts2.messages.push({
364
378
  role: "tool",
@@ -451,7 +465,8 @@ How to work:
451
465
  - If a tool returns an error, read it carefully and adjust; do not retry the same call blindly.
452
466
  - You have a 262k-token context window. Read as much of a file as needed rather than guessing.
453
467
  - If a request is ambiguous, ask one focused question instead of making large assumptions.
454
- - When you finish a task, stop. Do not add a closing summary.`;
468
+ - When you finish a task, stop. Do not add a closing summary.
469
+ - When creating git commits, you may include \`Co-authored-by: kimiflare <sinameraji@users.noreply.github.com>\` 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.`;
455
470
  const ctx = loadContextFile(opts2.cwd);
456
471
  const contextBlock = ctx ? `
457
472
 
@@ -652,10 +667,23 @@ function formatBashTitle(raw) {
652
667
  if (m) cmd = m[2].trim();
653
668
  return `$ ${cmd}`.slice(0, 120);
654
669
  }
670
+ function injectCoauthor(command, coauthor) {
671
+ if (!coauthor) return command;
672
+ const trailer = `Co-authored-by: ${coauthor.name} <${coauthor.email}>`;
673
+ const trimmed = command.trim();
674
+ if (!/\bgit\s+commit\b/.test(trimmed)) return command;
675
+ if (command.includes(trailer)) return command;
676
+ if (/\b(--dry-run|-n)\b/.test(trimmed) && !/-m\b|--message\b/.test(trimmed)) return command;
677
+ const tmpFile = `/tmp/kf-coauthor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
678
+ const check = `! git log -1 --pretty=%B 2>/dev/null | grep -qF "${trailer}"`;
679
+ const append = `git log -1 --pretty=%B | git interpret-trailers --trailer "${trailer}" > "${tmpFile}" && git commit --amend -F "${tmpFile}" --no-edit && rm -f "${tmpFile}"`;
680
+ return `(${command}) && ${check} && ${append}`;
681
+ }
655
682
  function runBash(args, ctx) {
656
683
  const timeout = Math.min(Math.max(1e3, args.timeout_ms ?? DEFAULT_TIMEOUT), MAX_TIMEOUT);
684
+ const command = injectCoauthor(args.command, ctx.coauthor);
657
685
  return new Promise((resolve2, reject) => {
658
- const child = spawn("bash", ["-lc", args.command], {
686
+ const child = spawn("bash", ["-lc", command], {
659
687
  cwd: ctx.cwd,
660
688
  signal: ctx.signal
661
689
  });
@@ -2454,18 +2482,28 @@ function cachePath() {
2454
2482
  const xdg = process.env.XDG_CONFIG_HOME || join3(homedir4(), ".config");
2455
2483
  return join3(xdg, "kimiflare", "update-check.json");
2456
2484
  }
2457
- function localPackageJsonPath() {
2458
- const here = dirname2(fileURLToPath(import.meta.url));
2459
- return join3(here, "..", "..", "package.json");
2485
+ async function findPackageJson(startDir) {
2486
+ let dir = startDir;
2487
+ while (true) {
2488
+ const candidate = join3(dir, "package.json");
2489
+ try {
2490
+ const raw = await readFile6(candidate, "utf8");
2491
+ const parsed = JSON.parse(raw);
2492
+ if (parsed.name === "kimiflare" && parsed.version) {
2493
+ return { path: candidate, version: parsed.version };
2494
+ }
2495
+ } catch {
2496
+ }
2497
+ const parent = dirname2(dir);
2498
+ if (parent === dir) break;
2499
+ dir = parent;
2500
+ }
2501
+ return null;
2460
2502
  }
2461
2503
  async function readLocalVersion() {
2462
- try {
2463
- const raw = await readFile6(localPackageJsonPath(), "utf8");
2464
- const parsed = JSON.parse(raw);
2465
- return parsed.version ?? null;
2466
- } catch {
2467
- return null;
2468
- }
2504
+ const here = dirname2(fileURLToPath(import.meta.url));
2505
+ const found = await findPackageJson(here);
2506
+ return found?.version ?? null;
2469
2507
  }
2470
2508
  async function readCache() {
2471
2509
  try {
@@ -2525,13 +2563,18 @@ async function checkForUpdate() {
2525
2563
  return { hasUpdate, localVersion, latestVersion };
2526
2564
  }
2527
2565
  async function isGitRepo() {
2528
- try {
2529
- const here = dirname2(fileURLToPath(import.meta.url));
2530
- await access(join3(here, "..", "..", ".git"));
2531
- return true;
2532
- } catch {
2533
- return false;
2566
+ let dir = dirname2(fileURLToPath(import.meta.url));
2567
+ while (true) {
2568
+ try {
2569
+ await access(join3(dir, ".git"));
2570
+ return true;
2571
+ } catch {
2572
+ }
2573
+ const parent = dirname2(dir);
2574
+ if (parent === dir) break;
2575
+ dir = parent;
2534
2576
  }
2577
+ return false;
2535
2578
  }
2536
2579
  var CACHE_TTL_MS, NPM_REGISTRY;
2537
2580
  var init_update_check = __esm({
@@ -3105,6 +3148,7 @@ function App({ initialCfg }) {
3105
3148
  cwd,
3106
3149
  signal: controller.signal,
3107
3150
  reasoningEffort: effortRef.current,
3151
+ coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "sinameraji@users.noreply.github.com" } : void 0,
3108
3152
  callbacks: {
3109
3153
  onAssistantStart: () => {
3110
3154
  const id = nextAssistantId++;
@@ -3455,6 +3499,7 @@ use: /thinking low | medium | high`
3455
3499
  cwd: process.cwd(),
3456
3500
  signal: controller.signal,
3457
3501
  reasoningEffort: effortRef.current,
3502
+ coauthor: cfg.coauthor !== false ? { name: cfg.coauthorName || "kimiflare", email: cfg.coauthorEmail || "sinameraji@users.noreply.github.com" } : void 0,
3458
3503
  callbacks: {
3459
3504
  onAssistantStart: () => {
3460
3505
  const id = nextAssistantId++;
@@ -3822,6 +3867,7 @@ async function runPrintMode(opts2) {
3822
3867
  executor,
3823
3868
  cwd,
3824
3869
  signal: controller.signal,
3870
+ coauthor: opts2.coauthor !== false ? { name: opts2.coauthorName || "kimiflare", email: opts2.coauthorEmail || "sinameraji@users.noreply.github.com" } : void 0,
3825
3871
  callbacks: {
3826
3872
  onReasoningDelta: opts2.showReasoning ? (delta) => {
3827
3873
  if (!printedReasoningHeader) {