fourmis-agents-sdk 0.2.4 → 0.2.5

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/api.js CHANGED
@@ -369,6 +369,95 @@ async function openBrowser(url) {
369
369
  var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann", AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize", TOKEN_URL = "https://auth.openai.com/oauth/token", REDIRECT_URI = "http://localhost:1455/auth/callback", SCOPE = "openid profile email offline_access", CALLBACK_PORT = 1455;
370
370
  var init_openai_oauth = () => {};
371
371
 
372
+ // src/auth/gemini-oauth.ts
373
+ var exports_gemini_oauth = {};
374
+ __export(exports_gemini_oauth, {
375
+ loadTokensSync: () => loadTokensSync2,
376
+ loadTokens: () => loadTokens2,
377
+ isLoggedIn: () => isLoggedIn2,
378
+ getValidToken: () => getValidToken2
379
+ });
380
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
381
+ import { join as join2 } from "path";
382
+ import { homedir as homedir2 } from "os";
383
+ function getHome2() {
384
+ return process.env.HOME ?? homedir2();
385
+ }
386
+ function tokenPath2() {
387
+ return join2(getHome2(), ".gemini", "oauth_creds.json");
388
+ }
389
+ function loadTokens2() {
390
+ const p = tokenPath2();
391
+ try {
392
+ const raw = readFileSync2(p, "utf-8");
393
+ const data = JSON.parse(raw);
394
+ if (data.access_token && data.refresh_token) {
395
+ return data;
396
+ }
397
+ } catch {}
398
+ return null;
399
+ }
400
+ function loadTokensSync2() {
401
+ return loadTokens2();
402
+ }
403
+ function saveTokens2(tokens) {
404
+ const p = tokenPath2();
405
+ const dir = join2(getHome2(), ".gemini");
406
+ if (!existsSync2(dir)) {
407
+ const { mkdirSync: mkdirSync2 } = __require("fs");
408
+ mkdirSync2(dir, { recursive: true });
409
+ }
410
+ writeFileSync2(p, JSON.stringify(tokens, null, 2), { mode: 384 });
411
+ }
412
+ async function refreshAccessToken2(refreshToken) {
413
+ const res = await fetch(GOOGLE_TOKEN_URL, {
414
+ method: "POST",
415
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
416
+ body: new URLSearchParams({
417
+ grant_type: "refresh_token",
418
+ client_id: GEMINI_CLIENT_ID,
419
+ client_secret: GEMINI_CLIENT_SECRET,
420
+ refresh_token: refreshToken
421
+ })
422
+ });
423
+ if (!res.ok) {
424
+ const text = await res.text();
425
+ throw new Error(`Gemini token refresh failed (${res.status}): ${text}`);
426
+ }
427
+ return res.json();
428
+ }
429
+ async function getValidToken2() {
430
+ const tokens = loadTokens2();
431
+ if (!tokens)
432
+ return null;
433
+ const expiresAt = tokens.expires_at ?? tokens.expiry_date;
434
+ const needsRefresh = expiresAt ? expiresAt <= Date.now() + 300000 : true;
435
+ if (needsRefresh) {
436
+ try {
437
+ const fresh = await refreshAccessToken2(tokens.refresh_token);
438
+ const expiryMs = Date.now() + fresh.expires_in * 1000;
439
+ const updated = {
440
+ access_token: fresh.access_token,
441
+ refresh_token: fresh.refresh_token ?? tokens.refresh_token,
442
+ token_type: fresh.token_type ?? "Bearer",
443
+ expires_in: fresh.expires_in,
444
+ expires_at: expiryMs,
445
+ expiry_date: expiryMs
446
+ };
447
+ saveTokens2(updated);
448
+ return { accessToken: updated.access_token };
449
+ } catch {
450
+ return { accessToken: tokens.access_token };
451
+ }
452
+ }
453
+ return { accessToken: tokens.access_token };
454
+ }
455
+ function isLoggedIn2() {
456
+ return loadTokens2() !== null;
457
+ }
458
+ var GEMINI_CLIENT_ID = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com", GEMINI_CLIENT_SECRET = "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", GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
459
+ var init_gemini_oauth = () => {};
460
+
372
461
  // src/types.ts
373
462
  function uuid() {
374
463
  return crypto.randomUUID();
@@ -833,6 +922,67 @@ function findOpenAIPricing(model) {
833
922
  }
834
923
  return bestPricing;
835
924
  }
925
+ var GEMINI_PRICING = {
926
+ "gemini-2.5-pro": {
927
+ inputPerMillion: 1.25,
928
+ outputPerMillion: 10,
929
+ cacheReadPerMillion: 0.315
930
+ },
931
+ "gemini-2.5-flash": {
932
+ inputPerMillion: 0.15,
933
+ outputPerMillion: 0.6,
934
+ cacheReadPerMillion: 0.0375
935
+ },
936
+ "gemini-2.5-flash-lite": {
937
+ inputPerMillion: 0.075,
938
+ outputPerMillion: 0.3
939
+ },
940
+ "gemini-2.0-flash": {
941
+ inputPerMillion: 0.1,
942
+ outputPerMillion: 0.4,
943
+ cacheReadPerMillion: 0.025
944
+ },
945
+ "gemini-2.0-flash-lite": {
946
+ inputPerMillion: 0.075,
947
+ outputPerMillion: 0.3
948
+ }
949
+ };
950
+ var GEMINI_CONTEXT_WINDOWS = {
951
+ "gemini-2.5-pro": 1048576,
952
+ "gemini-2.5-flash": 1048576,
953
+ "gemini-2.5-flash-lite": 1048576,
954
+ "gemini-2.0-flash": 1048576,
955
+ "gemini-2.0-flash-lite": 1048576
956
+ };
957
+ var GEMINI_MAX_OUTPUT = {
958
+ "gemini-2.5-pro": 65536,
959
+ "gemini-2.5-flash": 65536,
960
+ "gemini-2.5-flash-lite": 65536,
961
+ "gemini-2.0-flash": 8192,
962
+ "gemini-2.0-flash-lite": 8192
963
+ };
964
+ function calculateGeminiCost(model, usage) {
965
+ const pricing = findGeminiPricing(model);
966
+ if (!pricing)
967
+ return 0;
968
+ const inputCost = usage.inputTokens / 1e6 * pricing.inputPerMillion;
969
+ const outputCost = usage.outputTokens / 1e6 * pricing.outputPerMillion;
970
+ const cacheReadCost = usage.cacheReadInputTokens / 1e6 * (pricing.cacheReadPerMillion ?? pricing.inputPerMillion);
971
+ return inputCost + outputCost + cacheReadCost;
972
+ }
973
+ function findGeminiPricing(model) {
974
+ if (GEMINI_PRICING[model])
975
+ return GEMINI_PRICING[model];
976
+ let bestKey = "";
977
+ let bestPricing;
978
+ for (const [key, pricing] of Object.entries(GEMINI_PRICING)) {
979
+ if (model.startsWith(key) && key.length > bestKey.length) {
980
+ bestKey = key;
981
+ bestPricing = pricing;
982
+ }
983
+ }
984
+ return bestPricing;
985
+ }
836
986
 
837
987
  // src/providers/anthropic.ts
838
988
  import Anthropic from "@anthropic-ai/sdk";
@@ -1469,6 +1619,398 @@ function loadTokensSync() {
1469
1619
  return null;
1470
1620
  }
1471
1621
 
1622
+ // src/providers/gemini.ts
1623
+ import { GoogleGenAI } from "@google/genai";
1624
+ var CODE_ASSIST_ENDPOINT = "https://cloudcode-pa.googleapis.com";
1625
+ var CODE_ASSIST_API_VERSION = "v1internal";
1626
+
1627
+ class GeminiAdapter {
1628
+ name = "gemini";
1629
+ client = null;
1630
+ oauthMode;
1631
+ currentAccessToken;
1632
+ projectId;
1633
+ constructor(options) {
1634
+ const key = options?.apiKey ?? process.env.GEMINI_API_KEY;
1635
+ if (key) {
1636
+ this.oauthMode = false;
1637
+ this.client = new GoogleGenAI({ apiKey: key });
1638
+ } else {
1639
+ const tokens = loadTokensSync3();
1640
+ if (tokens) {
1641
+ this.oauthMode = true;
1642
+ this.currentAccessToken = tokens.access_token;
1643
+ } else {
1644
+ this.oauthMode = false;
1645
+ this.client = new GoogleGenAI({ apiKey: "" });
1646
+ }
1647
+ }
1648
+ }
1649
+ async* chat(request) {
1650
+ if (this.oauthMode) {
1651
+ yield* this.chatCodeAssist(request);
1652
+ } else {
1653
+ yield* this.chatSdk(request);
1654
+ }
1655
+ }
1656
+ calculateCost(model, usage) {
1657
+ return calculateGeminiCost(model, usage);
1658
+ }
1659
+ getContextWindow(model) {
1660
+ return GEMINI_CONTEXT_WINDOWS[model] ?? 1048576;
1661
+ }
1662
+ supportsFeature(feature) {
1663
+ switch (feature) {
1664
+ case "streaming":
1665
+ case "tool_calling":
1666
+ case "image_input":
1667
+ case "structured_output":
1668
+ case "thinking":
1669
+ case "pdf_input":
1670
+ return true;
1671
+ default:
1672
+ return false;
1673
+ }
1674
+ }
1675
+ async* chatSdk(request) {
1676
+ const contents = this.convertMessages(request.messages);
1677
+ const tools = request.tools ? this.convertTools(request.tools) : undefined;
1678
+ const maxTokens = request.maxTokens ?? GEMINI_MAX_OUTPUT[request.model] ?? 65536;
1679
+ const config = {
1680
+ maxOutputTokens: maxTokens,
1681
+ abortSignal: request.signal ?? undefined
1682
+ };
1683
+ if (request.systemPrompt) {
1684
+ config.systemInstruction = request.systemPrompt;
1685
+ }
1686
+ if (request.temperature !== undefined) {
1687
+ config.temperature = request.temperature;
1688
+ }
1689
+ if (tools) {
1690
+ config.tools = [{ functionDeclarations: tools }];
1691
+ }
1692
+ const stream = await this.client.models.generateContentStream({
1693
+ model: request.model,
1694
+ contents,
1695
+ config
1696
+ });
1697
+ let hasToolCalls = false;
1698
+ for await (const chunk of stream) {
1699
+ if (chunk.usageMetadata) {
1700
+ const u = chunk.usageMetadata;
1701
+ const cached = u.cachedContentTokenCount ?? 0;
1702
+ yield {
1703
+ type: "usage",
1704
+ usage: {
1705
+ inputTokens: (u.promptTokenCount ?? 0) - cached,
1706
+ outputTokens: u.candidatesTokenCount ?? 0,
1707
+ cacheReadInputTokens: cached,
1708
+ cacheCreationInputTokens: 0
1709
+ }
1710
+ };
1711
+ }
1712
+ const candidate = chunk.candidates?.[0];
1713
+ if (!candidate?.content?.parts)
1714
+ continue;
1715
+ for (const part of candidate.content.parts) {
1716
+ if (part.text) {
1717
+ if (part.thought) {
1718
+ yield { type: "thinking_delta", text: part.text };
1719
+ } else {
1720
+ yield { type: "text_delta", text: part.text };
1721
+ }
1722
+ }
1723
+ if (part.functionCall) {
1724
+ hasToolCalls = true;
1725
+ yield {
1726
+ type: "tool_call",
1727
+ id: part.functionCall.id ?? crypto.randomUUID(),
1728
+ name: part.functionCall.name ?? "",
1729
+ input: part.functionCall.args ?? {}
1730
+ };
1731
+ }
1732
+ }
1733
+ if (candidate.finishReason) {
1734
+ yield {
1735
+ type: "done",
1736
+ stopReason: this.mapFinishReason(candidate.finishReason, hasToolCalls)
1737
+ };
1738
+ return;
1739
+ }
1740
+ }
1741
+ yield { type: "done", stopReason: hasToolCalls ? "tool_use" : "end_turn" };
1742
+ }
1743
+ async* chatCodeAssist(request) {
1744
+ await this.refreshTokenIfNeeded();
1745
+ await this.ensureProjectId();
1746
+ const contents = this.convertMessages(request.messages);
1747
+ const tools = request.tools ? this.convertTools(request.tools) : undefined;
1748
+ const maxTokens = request.maxTokens ?? GEMINI_MAX_OUTPUT[request.model] ?? 65536;
1749
+ const generationConfig = {
1750
+ maxOutputTokens: maxTokens
1751
+ };
1752
+ if (request.temperature !== undefined) {
1753
+ generationConfig.temperature = request.temperature;
1754
+ }
1755
+ const innerRequest = {
1756
+ contents,
1757
+ generationConfig
1758
+ };
1759
+ if (request.systemPrompt) {
1760
+ innerRequest.systemInstruction = {
1761
+ parts: [{ text: request.systemPrompt }]
1762
+ };
1763
+ }
1764
+ if (tools) {
1765
+ innerRequest.tools = [{ functionDeclarations: tools }];
1766
+ }
1767
+ const body = {
1768
+ model: request.model,
1769
+ project: this.projectId,
1770
+ request: innerRequest
1771
+ };
1772
+ const url = `${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:streamGenerateContent?alt=sse`;
1773
+ const res = await fetch(url, {
1774
+ method: "POST",
1775
+ headers: {
1776
+ "Content-Type": "application/json",
1777
+ Authorization: `Bearer ${this.currentAccessToken}`
1778
+ },
1779
+ body: JSON.stringify(body),
1780
+ signal: request.signal ?? undefined
1781
+ });
1782
+ if (!res.ok) {
1783
+ const text = await res.text();
1784
+ throw new Error(`Gemini Code Assist API error (${res.status}): ${text}`);
1785
+ }
1786
+ yield* this.parseSSEStream(res);
1787
+ }
1788
+ async* parseSSEStream(res) {
1789
+ const reader = res.body.getReader();
1790
+ const decoder = new TextDecoder;
1791
+ let buffer = "";
1792
+ let hasToolCalls = false;
1793
+ let dataLines = [];
1794
+ while (true) {
1795
+ const { done, value } = await reader.read();
1796
+ if (done)
1797
+ break;
1798
+ buffer += decoder.decode(value, { stream: true });
1799
+ const lines = buffer.split(`
1800
+ `);
1801
+ buffer = lines.pop() || "";
1802
+ for (const line of lines) {
1803
+ if (line.startsWith("data: ")) {
1804
+ dataLines.push(line.slice(6));
1805
+ } else if (line.trim() === "" && dataLines.length > 0) {
1806
+ const json = dataLines.join(`
1807
+ `);
1808
+ dataLines = [];
1809
+ let obj;
1810
+ try {
1811
+ obj = JSON.parse(json);
1812
+ } catch {
1813
+ continue;
1814
+ }
1815
+ const response = obj.response ?? obj;
1816
+ const candidate = response?.candidates?.[0];
1817
+ if (candidate?.content?.parts) {
1818
+ for (const part of candidate.content.parts) {
1819
+ if (part.text) {
1820
+ if (part.thought) {
1821
+ yield { type: "thinking_delta", text: part.text };
1822
+ } else {
1823
+ yield { type: "text_delta", text: part.text };
1824
+ }
1825
+ }
1826
+ if (part.functionCall) {
1827
+ hasToolCalls = true;
1828
+ yield {
1829
+ type: "tool_call",
1830
+ id: part.functionCall.id ?? crypto.randomUUID(),
1831
+ name: part.functionCall.name ?? "",
1832
+ input: part.functionCall.args ?? {}
1833
+ };
1834
+ }
1835
+ }
1836
+ }
1837
+ if (response?.usageMetadata) {
1838
+ const u = response.usageMetadata;
1839
+ const cached = u.cachedContentTokenCount ?? 0;
1840
+ yield {
1841
+ type: "usage",
1842
+ usage: {
1843
+ inputTokens: (u.promptTokenCount ?? 0) - cached,
1844
+ outputTokens: u.candidatesTokenCount ?? 0,
1845
+ cacheReadInputTokens: cached,
1846
+ cacheCreationInputTokens: 0
1847
+ }
1848
+ };
1849
+ }
1850
+ if (candidate?.finishReason) {
1851
+ yield {
1852
+ type: "done",
1853
+ stopReason: this.mapFinishReason(candidate.finishReason, hasToolCalls)
1854
+ };
1855
+ return;
1856
+ }
1857
+ }
1858
+ }
1859
+ }
1860
+ if (dataLines.length > 0) {
1861
+ const json = dataLines.join(`
1862
+ `);
1863
+ try {
1864
+ const obj = JSON.parse(json);
1865
+ const response = obj.response ?? obj;
1866
+ const candidate = response?.candidates?.[0];
1867
+ if (candidate?.finishReason) {
1868
+ yield {
1869
+ type: "done",
1870
+ stopReason: this.mapFinishReason(candidate.finishReason, hasToolCalls)
1871
+ };
1872
+ return;
1873
+ }
1874
+ } catch {}
1875
+ }
1876
+ yield { type: "done", stopReason: hasToolCalls ? "tool_use" : "end_turn" };
1877
+ }
1878
+ async refreshTokenIfNeeded() {
1879
+ if (!this.oauthMode)
1880
+ return;
1881
+ try {
1882
+ const { getValidToken: getValidToken3 } = await Promise.resolve().then(() => (init_gemini_oauth(), exports_gemini_oauth));
1883
+ const result = await getValidToken3();
1884
+ if (result && result.accessToken !== this.currentAccessToken) {
1885
+ this.currentAccessToken = result.accessToken;
1886
+ }
1887
+ } catch {}
1888
+ }
1889
+ async ensureProjectId() {
1890
+ if (this.projectId)
1891
+ return;
1892
+ this.projectId = process.env.GOOGLE_CLOUD_PROJECT ?? process.env.GOOGLE_CLOUD_PROJECT_ID ?? undefined;
1893
+ if (this.projectId)
1894
+ return;
1895
+ try {
1896
+ const res = await fetch(`${CODE_ASSIST_ENDPOINT}/${CODE_ASSIST_API_VERSION}:loadCodeAssist`, {
1897
+ method: "POST",
1898
+ headers: {
1899
+ "Content-Type": "application/json",
1900
+ Authorization: `Bearer ${this.currentAccessToken}`
1901
+ },
1902
+ body: JSON.stringify({
1903
+ metadata: {
1904
+ ideType: "IDE_UNSPECIFIED",
1905
+ platform: "PLATFORM_UNSPECIFIED",
1906
+ pluginType: "GEMINI"
1907
+ }
1908
+ })
1909
+ });
1910
+ if (res.ok) {
1911
+ const data = await res.json();
1912
+ this.projectId = data.cloudaicompanionProject;
1913
+ }
1914
+ } catch {}
1915
+ }
1916
+ convertMessages(messages) {
1917
+ const result = [];
1918
+ for (const msg of messages) {
1919
+ if (typeof msg.content === "string") {
1920
+ result.push({
1921
+ role: msg.role === "assistant" ? "model" : "user",
1922
+ parts: [{ text: msg.content }]
1923
+ });
1924
+ continue;
1925
+ }
1926
+ if (msg.role === "assistant") {
1927
+ const parts = [];
1928
+ for (const block of msg.content) {
1929
+ if (block.type === "text") {
1930
+ parts.push({ text: block.text });
1931
+ } else if (block.type === "tool_use") {
1932
+ parts.push({
1933
+ functionCall: {
1934
+ name: block.name,
1935
+ args: block.input
1936
+ }
1937
+ });
1938
+ }
1939
+ }
1940
+ if (parts.length > 0) {
1941
+ result.push({ role: "model", parts });
1942
+ }
1943
+ } else {
1944
+ const textParts = [];
1945
+ const functionResponseParts = [];
1946
+ for (const block of msg.content) {
1947
+ if (block.type === "text") {
1948
+ textParts.push({ text: block.text });
1949
+ } else if (block.type === "tool_result") {
1950
+ functionResponseParts.push({
1951
+ functionResponse: {
1952
+ name: findToolName(messages, block.tool_use_id) ?? "unknown",
1953
+ response: { result: block.content }
1954
+ }
1955
+ });
1956
+ }
1957
+ }
1958
+ if (functionResponseParts.length > 0) {
1959
+ result.push({ role: "user", parts: functionResponseParts });
1960
+ }
1961
+ if (textParts.length > 0) {
1962
+ result.push({ role: "user", parts: textParts });
1963
+ }
1964
+ }
1965
+ }
1966
+ return result;
1967
+ }
1968
+ convertTools(tools) {
1969
+ return tools.map((tool) => ({
1970
+ name: tool.name,
1971
+ description: tool.description,
1972
+ parameters: tool.inputSchema
1973
+ }));
1974
+ }
1975
+ mapFinishReason(reason, hasToolCalls) {
1976
+ if (hasToolCalls)
1977
+ return "tool_use";
1978
+ switch (reason) {
1979
+ case "STOP":
1980
+ return "end_turn";
1981
+ case "MAX_TOKENS":
1982
+ return "max_tokens";
1983
+ default:
1984
+ return "end_turn";
1985
+ }
1986
+ }
1987
+ }
1988
+ function findToolName(messages, toolUseId) {
1989
+ for (const msg of messages) {
1990
+ if (msg.role !== "assistant" || typeof msg.content === "string")
1991
+ continue;
1992
+ for (const block of msg.content) {
1993
+ if (block.type === "tool_use" && block.id === toolUseId) {
1994
+ return block.name;
1995
+ }
1996
+ }
1997
+ }
1998
+ return;
1999
+ }
2000
+ function loadTokensSync3() {
2001
+ const home = process.env.HOME ?? __require("os").homedir();
2002
+ const path = `${home}/.gemini/oauth_creds.json`;
2003
+ try {
2004
+ const fs = __require("fs");
2005
+ const raw = fs.readFileSync(path, "utf-8");
2006
+ const data = JSON.parse(raw);
2007
+ if (data.access_token && data.refresh_token) {
2008
+ return data;
2009
+ }
2010
+ } catch {}
2011
+ return null;
2012
+ }
2013
+
1472
2014
  // src/providers/registry.ts
1473
2015
  var providers = new Map;
1474
2016
  function registerProvider(name, adapter) {
@@ -1494,6 +2036,13 @@ function getProvider(name, options) {
1494
2036
  }
1495
2037
  return adapter;
1496
2038
  }
2039
+ if (name === "gemini") {
2040
+ const adapter = new GeminiAdapter(options);
2041
+ if (!options?.apiKey && !options?.baseUrl) {
2042
+ providers.set(name, adapter);
2043
+ }
2044
+ return adapter;
2045
+ }
1497
2046
  throw new Error(`Unknown provider: "${name}". Register it with registerProvider() first.`);
1498
2047
  }
1499
2048
  function listProviders() {
@@ -2210,9 +2759,9 @@ class PermissionManager {
2210
2759
  }
2211
2760
 
2212
2761
  // src/settings.ts
2213
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
2214
- import { dirname as dirname2, join as join2 } from "path";
2215
- import { homedir as homedir2 } from "os";
2762
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
2763
+ import { dirname as dirname2, join as join3 } from "path";
2764
+ import { homedir as homedir3 } from "os";
2216
2765
 
2217
2766
  class SettingsManager {
2218
2767
  cwd;
@@ -2290,36 +2839,36 @@ class SettingsManager {
2290
2839
  return;
2291
2840
  }
2292
2841
  const dir = dirname2(path);
2293
- if (!existsSync2(dir))
2842
+ if (!existsSync3(dir))
2294
2843
  mkdirSync2(dir, { recursive: true });
2295
- writeFileSync2(path, JSON.stringify(data, null, 2) + `
2844
+ writeFileSync3(path, JSON.stringify(data, null, 2) + `
2296
2845
  `);
2297
2846
  }
2298
2847
  sourceToPath(source) {
2299
2848
  switch (source) {
2300
2849
  case "user":
2301
- return join2(homedir2(), ".claude", "settings.json");
2850
+ return join3(homedir3(), ".claude", "settings.json");
2302
2851
  case "project":
2303
- return join2(this.cwd, ".claude", "settings.json");
2852
+ return join3(this.cwd, ".claude", "settings.json");
2304
2853
  case "local":
2305
- return join2(this.cwd, ".claude", "settings.local.json");
2854
+ return join3(this.cwd, ".claude", "settings.local.json");
2306
2855
  }
2307
2856
  }
2308
2857
  destinationToPath(destination) {
2309
2858
  switch (destination) {
2310
2859
  case "userSettings":
2311
- return join2(homedir2(), ".claude", "settings.json");
2860
+ return join3(homedir3(), ".claude", "settings.json");
2312
2861
  case "projectSettings":
2313
- return join2(this.cwd, ".claude", "settings.json");
2862
+ return join3(this.cwd, ".claude", "settings.json");
2314
2863
  case "localSettings":
2315
- return join2(this.cwd, ".claude", "settings.local.json");
2864
+ return join3(this.cwd, ".claude", "settings.local.json");
2316
2865
  default:
2317
2866
  return null;
2318
2867
  }
2319
2868
  }
2320
2869
  readJson(path) {
2321
2870
  try {
2322
- const content = readFileSync2(path, "utf-8");
2871
+ const content = readFileSync3(path, "utf-8");
2323
2872
  return JSON.parse(content);
2324
2873
  } catch {
2325
2874
  return null;
@@ -2337,8 +2886,8 @@ class SettingsManager {
2337
2886
  }
2338
2887
 
2339
2888
  // src/utils/system-prompt.ts
2340
- import { readFileSync as readFileSync3 } from "fs";
2341
- import { join as join3 } from "path";
2889
+ import { readFileSync as readFileSync4 } from "fs";
2890
+ import { join as join4 } from "path";
2342
2891
  var CORE_IDENTITY = `You are an AI coding agent. You help users with software engineering tasks by reading, writing, and modifying code. You have access to tools that let you interact with the filesystem and execute commands.
2343
2892
 
2344
2893
  You are highly capable and can help users complete complex tasks that would otherwise be too difficult or time-consuming.`;
@@ -2419,7 +2968,7 @@ ${instructions}`);
2419
2968
  function readProjectInstructions(cwd) {
2420
2969
  for (const name of ["CLAUDE.md", "AGENTS.md"]) {
2421
2970
  try {
2422
- const content = readFileSync3(join3(cwd, name), "utf-8").trim();
2971
+ const content = readFileSync4(join4(cwd, name), "utf-8").trim();
2423
2972
  if (content)
2424
2973
  return content;
2425
2974
  } catch {}
@@ -2932,21 +3481,21 @@ class TaskManager {
2932
3481
  }
2933
3482
 
2934
3483
  // src/utils/session-store.ts
2935
- import { readFileSync as readFileSync4, appendFileSync, mkdirSync as mkdirSync3, readdirSync, statSync } from "fs";
2936
- import { join as join4 } from "path";
2937
- import { homedir as homedir3 } from "os";
3484
+ import { readFileSync as readFileSync5, appendFileSync, mkdirSync as mkdirSync3, readdirSync, statSync } from "fs";
3485
+ import { join as join5 } from "path";
3486
+ import { homedir as homedir4 } from "os";
2938
3487
  function sanitizeCwd(cwd) {
2939
3488
  return cwd.replace(/[/.]/g, "-");
2940
3489
  }
2941
3490
  function sessionsDir(cwd) {
2942
- return join4(homedir3(), ".claude", "projects", sanitizeCwd(cwd));
3491
+ return join5(homedir4(), ".claude", "projects", sanitizeCwd(cwd));
2943
3492
  }
2944
3493
  function ensureDir(dir) {
2945
3494
  mkdirSync3(dir, { recursive: true });
2946
3495
  }
2947
3496
  function logMessage(dir, sessionId, entry) {
2948
3497
  ensureDir(dir);
2949
- const filePath = join4(dir, `${sessionId}.jsonl`);
3498
+ const filePath = join5(dir, `${sessionId}.jsonl`);
2950
3499
  appendFileSync(filePath, JSON.stringify(entry) + `
2951
3500
  `);
2952
3501
  }
@@ -2984,7 +3533,7 @@ function findLatestSession(cwd) {
2984
3533
  const dir = sessionsDir(cwd);
2985
3534
  try {
2986
3535
  const files = readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) => {
2987
- const filePath = join4(dir, f);
3536
+ const filePath = join5(dir, f);
2988
3537
  try {
2989
3538
  return { name: f, mtime: statSync(filePath).mtimeMs };
2990
3539
  } catch {
@@ -3000,10 +3549,10 @@ function findLatestSession(cwd) {
3000
3549
  }
3001
3550
  function loadSessionMessages(cwd, sessionId) {
3002
3551
  const dir = sessionsDir(cwd);
3003
- const filePath = join4(dir, `${sessionId}.jsonl`);
3552
+ const filePath = join5(dir, `${sessionId}.jsonl`);
3004
3553
  let lines;
3005
3554
  try {
3006
- lines = readFileSync4(filePath, "utf-8").trim().split(`
3555
+ lines = readFileSync5(filePath, "utf-8").trim().split(`
3007
3556
  `).filter(Boolean);
3008
3557
  } catch {
3009
3558
  return [];