indusagi 0.13.10 → 0.13.12

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.
Files changed (35) hide show
  1. package/dist/agent.js +204 -29
  2. package/dist/ai.js +204 -29
  3. package/dist/cli.js +92 -9
  4. package/dist/index.js +186 -21
  5. package/dist/llmgateway.js +81 -4
  6. package/dist/mcp.js +94 -12
  7. package/dist/react-host/jsx-dev-runtime.js +93 -0
  8. package/dist/react-ink.js +11 -5
  9. package/dist/runtime.js +81 -4
  10. package/dist/shell-app.js +92 -9
  11. package/dist/smithy.js +81 -4
  12. package/dist/swarm.js +81 -4
  13. package/dist/types/facade/agent.d.ts +1 -1
  14. package/dist/types/facade/agent.test.d.ts +1 -0
  15. package/dist/types/facade/ai.d.ts +1 -1
  16. package/dist/types/facade/bot/types.d.ts +3 -3
  17. package/dist/types/facade/mcp.d.ts +1 -1
  18. package/dist/types/facade/ml/adapters/openai-codex-responses.d.ts +1 -1
  19. package/dist/types/facade/ml/adapters/openai-codex-responses.test.d.ts +1 -0
  20. package/dist/types/facade/ml/adapters/openai-responses.d.ts +1 -1
  21. package/dist/types/facade/ml/adapters/openai-responses.test.d.ts +1 -0
  22. package/dist/types/facade/ml/adapters/simple-options.d.ts +2 -2
  23. package/dist/types/facade/ml/auth-store.d.ts +7 -0
  24. package/dist/types/facade/ml/auth-store.test.d.ts +1 -0
  25. package/dist/types/facade/ml/models.generated.d.ts +162 -0
  26. package/dist/types/facade/ml/types.d.ts +14 -1
  27. package/dist/types/llmgateway/connectors/openai-responses.test.d.ts +1 -0
  28. package/dist/types/llmgateway/contract/index.d.ts +2 -2
  29. package/dist/types/llmgateway/contract/model-card.d.ts +14 -0
  30. package/dist/types/llmgateway/contract/options.d.ts +3 -1
  31. package/dist/types/react-host/jsx-dev-runtime.d.ts +3 -0
  32. package/dist/types/react-host/loader.d.ts +1 -0
  33. package/dist/types/security/private-state.d.ts +3 -0
  34. package/dist/zoho.js +94 -12
  35. package/package.json +7 -2
package/dist/index.js CHANGED
@@ -199,6 +199,72 @@ var MODEL_CARDS = [
199
199
  cacheReadPerMTok: 0.275
200
200
  }
201
201
  },
202
+ {
203
+ id: "gpt-6-astra",
204
+ provider: "openai",
205
+ api: "openai-responses",
206
+ displayName: "GPT-6 Astra",
207
+ baseUrl: "https://api.openai.com/v1",
208
+ contextWindow: 105e4,
209
+ maxOutputTokens: 128e3,
210
+ modalities: ["text", "image"],
211
+ reasoning: true,
212
+ reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
213
+ longContextPricing: {
214
+ threshold: 272e3,
215
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
216
+ },
217
+ cost: {
218
+ inputPerMTok: 10,
219
+ outputPerMTok: 50,
220
+ cacheReadPerMTok: 1,
221
+ cacheWritePerMTok: 12.5
222
+ }
223
+ },
224
+ {
225
+ id: "gpt-6-luna",
226
+ provider: "openai",
227
+ api: "openai-responses",
228
+ displayName: "GPT-6 Luna",
229
+ baseUrl: "https://api.openai.com/v1",
230
+ contextWindow: 105e4,
231
+ maxOutputTokens: 128e3,
232
+ modalities: ["text", "image"],
233
+ reasoning: true,
234
+ reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
235
+ longContextPricing: {
236
+ threshold: 272e3,
237
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
238
+ },
239
+ cost: {
240
+ inputPerMTok: 0.1,
241
+ outputPerMTok: 0.5,
242
+ cacheReadPerMTok: 0.01,
243
+ cacheWritePerMTok: 0.125
244
+ }
245
+ },
246
+ {
247
+ id: "gpt-6-sol",
248
+ provider: "openai",
249
+ api: "openai-responses",
250
+ displayName: "GPT-6 Sol",
251
+ baseUrl: "https://api.openai.com/v1",
252
+ contextWindow: 105e4,
253
+ maxOutputTokens: 128e3,
254
+ modalities: ["text", "image"],
255
+ reasoning: true,
256
+ reasoningEfforts: ["high"],
257
+ longContextPricing: {
258
+ threshold: 272e3,
259
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
260
+ },
261
+ cost: {
262
+ inputPerMTok: 10,
263
+ outputPerMTok: 50,
264
+ cacheReadPerMTok: 1,
265
+ cacheWritePerMTok: 12.5
266
+ }
267
+ },
202
268
  // ── Google (Gemini) ─────────────────────────────────────────────────────
203
269
  {
204
270
  id: "gemini-2.5-pro",
@@ -943,6 +1009,7 @@ function anthropicThinkingBudget(level, maxOutput) {
943
1009
  low: 0.2,
944
1010
  medium: 0.4,
945
1011
  high: 0.6,
1012
+ xhigh: 0.8,
946
1013
  max: 0.8
947
1014
  };
948
1015
  if (level === "off") {
@@ -1747,13 +1814,17 @@ function readNumber2(o, key) {
1747
1814
  const v = o[key];
1748
1815
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1749
1816
  }
1750
- function reasoningEffort(level) {
1817
+ function reasoningEffort(model, level) {
1818
+ if (model.reasoningEfforts?.includes(level)) {
1819
+ return level;
1820
+ }
1751
1821
  switch (level) {
1752
1822
  case "low":
1753
1823
  return "low";
1754
1824
  case "medium":
1755
1825
  return "medium";
1756
1826
  case "high":
1827
+ case "xhigh":
1757
1828
  case "max":
1758
1829
  return "high";
1759
1830
  }
@@ -1794,14 +1865,18 @@ function buildBody2(model, c, opts) {
1794
1865
  if (ceiling > 0) {
1795
1866
  body.max_output_tokens = ceiling;
1796
1867
  }
1797
- if (opts.temperature !== void 0) {
1868
+ const usesFixedGpt6Sampling = ["gpt-6-astra", "gpt-6-sol", "gpt-6-luna"].includes(model.id);
1869
+ if (!usesFixedGpt6Sampling && opts.temperature !== void 0) {
1798
1870
  body.temperature = opts.temperature;
1799
1871
  }
1800
- if (opts.topP !== void 0) {
1872
+ if (!usesFixedGpt6Sampling && opts.topP !== void 0) {
1801
1873
  body.top_p = opts.topP;
1802
1874
  }
1803
1875
  if (model.reasoning && opts.thinking !== void 0 && opts.thinking !== "off") {
1804
- body.reasoning = { effort: reasoningEffort(opts.thinking) };
1876
+ const effort = reasoningEffort(model, opts.thinking);
1877
+ if (effort !== void 0) {
1878
+ body.reasoning = { effort };
1879
+ }
1805
1880
  }
1806
1881
  return body;
1807
1882
  }
@@ -2076,6 +2151,7 @@ function geminiThinkingBudget(level, maxOutput) {
2076
2151
  low: 0.2,
2077
2152
  medium: 0.4,
2078
2153
  high: 0.6,
2154
+ xhigh: 0.8,
2079
2155
  max: 0.8
2080
2156
  };
2081
2157
  const budget = Math.floor(maxOutput * fraction[level]);
@@ -2369,6 +2445,7 @@ function thinkingBudget(level, maxOutput) {
2369
2445
  low: 0.2,
2370
2446
  medium: 0.4,
2371
2447
  high: 0.6,
2448
+ xhigh: 0.8,
2372
2449
  max: 0.8
2373
2450
  };
2374
2451
  return Math.max(0, Math.floor(maxOutput * fraction[level]));
@@ -9584,8 +9661,96 @@ function platformOpenCommand(url) {
9584
9661
  }
9585
9662
 
9586
9663
  // src/facade/mcp-core/oauth/token-store.ts
9587
- import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
9588
- import { dirname, join as join2 } from "node:path";
9664
+ import { join as join2 } from "node:path";
9665
+
9666
+ // src/security/private-state.ts
9667
+ import {
9668
+ chmodSync,
9669
+ closeSync,
9670
+ constants,
9671
+ fchmodSync,
9672
+ fstatSync,
9673
+ lstatSync,
9674
+ mkdirSync,
9675
+ openSync,
9676
+ readFileSync,
9677
+ renameSync,
9678
+ rmSync,
9679
+ writeFileSync
9680
+ } from "node:fs";
9681
+ import { randomUUID } from "node:crypto";
9682
+ import { dirname } from "node:path";
9683
+ var NO_FOLLOW = constants.O_NOFOLLOW ?? 0;
9684
+ var isPosix = () => process.platform !== "win32";
9685
+ function assertOwned(uid, path2) {
9686
+ if (!isPosix() || process.getuid === void 0) return;
9687
+ if (uid !== process.getuid()) throw new Error(`Refusing sensitive path not owned by the current user: ${path2}`);
9688
+ }
9689
+ function ensurePrivateDirectorySync(path2) {
9690
+ try {
9691
+ const current = lstatSync(path2);
9692
+ if (current.isSymbolicLink() || !current.isDirectory()) throw new Error(`Refusing non-directory sensitive state path: ${path2}`);
9693
+ assertOwned(current.uid, path2);
9694
+ } catch (error) {
9695
+ if (error.code !== "ENOENT") throw error;
9696
+ mkdirSync(path2, { recursive: true, mode: 448 });
9697
+ }
9698
+ if (isPosix()) chmodSync(path2, 448);
9699
+ }
9700
+ function validateExistingFile(path2) {
9701
+ try {
9702
+ const current = lstatSync(path2);
9703
+ if (current.isSymbolicLink() || !current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path2}`);
9704
+ assertOwned(current.uid, path2);
9705
+ } catch (error) {
9706
+ if (error.code === "ENOENT") return;
9707
+ throw error;
9708
+ }
9709
+ }
9710
+ function readPrivateFileSync(path2) {
9711
+ ensurePrivateDirectorySync(dirname(path2));
9712
+ validateExistingFile(path2);
9713
+ let fd;
9714
+ try {
9715
+ fd = openSync(path2, constants.O_RDONLY | NO_FOLLOW);
9716
+ } catch (error) {
9717
+ if (error.code === "ENOENT") return null;
9718
+ throw error;
9719
+ }
9720
+ try {
9721
+ const current = fstatSync(fd);
9722
+ if (!current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path2}`);
9723
+ assertOwned(current.uid, path2);
9724
+ if (isPosix()) fchmodSync(fd, 384);
9725
+ return readFileSync(fd, "utf8");
9726
+ } finally {
9727
+ closeSync(fd);
9728
+ }
9729
+ }
9730
+ function atomicWritePrivateFileSync(path2, content) {
9731
+ ensurePrivateDirectorySync(dirname(path2));
9732
+ validateExistingFile(path2);
9733
+ const temporary = `${path2}.tmp-${process.pid}-${randomUUID()}`;
9734
+ let fd;
9735
+ try {
9736
+ fd = openSync(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | NO_FOLLOW, 384);
9737
+ writeFileSync(fd, content, "utf8");
9738
+ if (isPosix()) fchmodSync(fd, 384);
9739
+ closeSync(fd);
9740
+ fd = void 0;
9741
+ renameSync(temporary, path2);
9742
+ if (isPosix()) chmodSync(path2, 384);
9743
+ } catch (error) {
9744
+ if (fd !== void 0) closeSync(fd);
9745
+ try {
9746
+ rmSync(temporary, { force: true });
9747
+ } catch {
9748
+ }
9749
+ throw error;
9750
+ }
9751
+ }
9752
+
9753
+ // src/facade/mcp-core/oauth/token-store.ts
9589
9754
  function defaultCredentialsDir() {
9590
9755
  const xdg = process.env.XDG_CONFIG_HOME;
9591
9756
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -9602,10 +9767,11 @@ function credentialsPath(credentialsDir, id) {
9602
9767
  }
9603
9768
  function readMcpOAuthState(credentialsDir, id) {
9604
9769
  const path2 = credentialsPath(credentialsDir, id);
9605
- if (!existsSync(path2)) return void 0;
9606
9770
  let raw;
9607
9771
  try {
9608
- raw = readFileSync(path2, "utf8");
9772
+ const stored = readPrivateFileSync(path2);
9773
+ if (stored === null) return void 0;
9774
+ raw = stored;
9609
9775
  } catch (e) {
9610
9776
  return void 0;
9611
9777
  }
@@ -9620,15 +9786,8 @@ function readMcpOAuthState(credentialsDir, id) {
9620
9786
  }
9621
9787
  function writeMcpOAuthState(credentialsDir, state) {
9622
9788
  const path2 = credentialsPath(credentialsDir, state.id);
9623
- mkdirSync(dirname(path2), { recursive: true });
9624
- const tmp = `${path2}.tmp-${process.pid}-${Date.now()}`;
9625
9789
  const json = JSON.stringify({ ...state, updatedAt: Date.now() }, null, 2);
9626
- writeFileSync(tmp, json, { mode: 384 });
9627
- renameSync(tmp, path2);
9628
- try {
9629
- chmodSync(path2, 384);
9630
- } catch {
9631
- }
9790
+ atomicWritePrivateFileSync(path2, json);
9632
9791
  }
9633
9792
  function clearMcpOAuthState(credentialsDir, id) {
9634
9793
  const path2 = credentialsPath(credentialsDir, id);
@@ -15555,9 +15714,9 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
15555
15714
  const inner = (headingToken.tokens ?? []).map((child) => formatToken(child, theme, highlight)).join("");
15556
15715
  const colored = theme.role("heading", inner);
15557
15716
  if (headingToken.depth === 1) {
15558
- return chalk2.bold.italic.underline(colored) + EOL + EOL;
15717
+ return chalk2.bold.underline(`${theme.role("heading", "\u25B0")} ${colored}`) + EOL;
15559
15718
  }
15560
- return chalk2.bold(colored) + EOL + EOL;
15719
+ return chalk2.bold(`${theme.role("heading", "\u25C6")} ${colored}`) + EOL;
15561
15720
  }
15562
15721
  case "hr":
15563
15722
  return "---";
@@ -15591,8 +15750,14 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
15591
15750
  return (token.tokens ?? []).map(
15592
15751
  (child) => `${" ".repeat(listDepth)}${formatToken(child, theme, highlight, listDepth + 1, orderedListNumber, token)}`
15593
15752
  ).join("");
15594
- case "paragraph":
15595
- return (token.tokens ?? []).map((child) => formatToken(child, theme, highlight)).join("") + EOL;
15753
+ case "paragraph": {
15754
+ const children = token.tokens ?? [];
15755
+ const body = children.map((child) => formatToken(child, theme, highlight)).join("");
15756
+ if (children.length === 1 && children[0]?.type === "strong") {
15757
+ return `${theme.role("heading", "\u25C6")} ${body}${EOL}`;
15758
+ }
15759
+ return body + EOL;
15760
+ }
15596
15761
  case "space":
15597
15762
  case "br":
15598
15763
  return EOL;
@@ -15602,7 +15767,7 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
15602
15767
  return textToken.text;
15603
15768
  }
15604
15769
  if (parent?.type === "list_item") {
15605
- const marker = orderedListNumber === null ? "-" : `${getListNumber(listDepth, orderedListNumber)}.`;
15770
+ const marker = orderedListNumber === null ? "\u2022" : `${getListNumber(listDepth, orderedListNumber)}.`;
15606
15771
  const body = textToken.tokens ? textToken.tokens.map((child) => formatToken(child, theme, highlight, listDepth, orderedListNumber, token)).join("") : textToken.text;
15607
15772
  return `${marker} ${body}${EOL}`;
15608
15773
  }
@@ -169,6 +169,72 @@ var MODEL_CARDS = [
169
169
  cacheReadPerMTok: 0.275
170
170
  }
171
171
  },
172
+ {
173
+ id: "gpt-6-astra",
174
+ provider: "openai",
175
+ api: "openai-responses",
176
+ displayName: "GPT-6 Astra",
177
+ baseUrl: "https://api.openai.com/v1",
178
+ contextWindow: 105e4,
179
+ maxOutputTokens: 128e3,
180
+ modalities: ["text", "image"],
181
+ reasoning: true,
182
+ reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
183
+ longContextPricing: {
184
+ threshold: 272e3,
185
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
186
+ },
187
+ cost: {
188
+ inputPerMTok: 10,
189
+ outputPerMTok: 50,
190
+ cacheReadPerMTok: 1,
191
+ cacheWritePerMTok: 12.5
192
+ }
193
+ },
194
+ {
195
+ id: "gpt-6-luna",
196
+ provider: "openai",
197
+ api: "openai-responses",
198
+ displayName: "GPT-6 Luna",
199
+ baseUrl: "https://api.openai.com/v1",
200
+ contextWindow: 105e4,
201
+ maxOutputTokens: 128e3,
202
+ modalities: ["text", "image"],
203
+ reasoning: true,
204
+ reasoningEfforts: ["low", "medium", "high", "xhigh", "max"],
205
+ longContextPricing: {
206
+ threshold: 272e3,
207
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
208
+ },
209
+ cost: {
210
+ inputPerMTok: 0.1,
211
+ outputPerMTok: 0.5,
212
+ cacheReadPerMTok: 0.01,
213
+ cacheWritePerMTok: 0.125
214
+ }
215
+ },
216
+ {
217
+ id: "gpt-6-sol",
218
+ provider: "openai",
219
+ api: "openai-responses",
220
+ displayName: "GPT-6 Sol",
221
+ baseUrl: "https://api.openai.com/v1",
222
+ contextWindow: 105e4,
223
+ maxOutputTokens: 128e3,
224
+ modalities: ["text", "image"],
225
+ reasoning: true,
226
+ reasoningEfforts: ["high"],
227
+ longContextPricing: {
228
+ threshold: 272e3,
229
+ multipliers: { input: 2, output: 1.5, cacheRead: 2, cacheWrite: 2 }
230
+ },
231
+ cost: {
232
+ inputPerMTok: 10,
233
+ outputPerMTok: 50,
234
+ cacheReadPerMTok: 1,
235
+ cacheWritePerMTok: 12.5
236
+ }
237
+ },
172
238
  // ── Google (Gemini) ─────────────────────────────────────────────────────
173
239
  {
174
240
  id: "gemini-2.5-pro",
@@ -913,6 +979,7 @@ function anthropicThinkingBudget(level, maxOutput) {
913
979
  low: 0.2,
914
980
  medium: 0.4,
915
981
  high: 0.6,
982
+ xhigh: 0.8,
916
983
  max: 0.8
917
984
  };
918
985
  if (level === "off") {
@@ -1717,13 +1784,17 @@ function readNumber2(o, key) {
1717
1784
  const v = o[key];
1718
1785
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
1719
1786
  }
1720
- function reasoningEffort(level) {
1787
+ function reasoningEffort(model, level) {
1788
+ if (model.reasoningEfforts?.includes(level)) {
1789
+ return level;
1790
+ }
1721
1791
  switch (level) {
1722
1792
  case "low":
1723
1793
  return "low";
1724
1794
  case "medium":
1725
1795
  return "medium";
1726
1796
  case "high":
1797
+ case "xhigh":
1727
1798
  case "max":
1728
1799
  return "high";
1729
1800
  }
@@ -1764,14 +1835,18 @@ function buildBody2(model, c, opts) {
1764
1835
  if (ceiling > 0) {
1765
1836
  body.max_output_tokens = ceiling;
1766
1837
  }
1767
- if (opts.temperature !== void 0) {
1838
+ const usesFixedGpt6Sampling = ["gpt-6-astra", "gpt-6-sol", "gpt-6-luna"].includes(model.id);
1839
+ if (!usesFixedGpt6Sampling && opts.temperature !== void 0) {
1768
1840
  body.temperature = opts.temperature;
1769
1841
  }
1770
- if (opts.topP !== void 0) {
1842
+ if (!usesFixedGpt6Sampling && opts.topP !== void 0) {
1771
1843
  body.top_p = opts.topP;
1772
1844
  }
1773
1845
  if (model.reasoning && opts.thinking !== void 0 && opts.thinking !== "off") {
1774
- body.reasoning = { effort: reasoningEffort(opts.thinking) };
1846
+ const effort = reasoningEffort(model, opts.thinking);
1847
+ if (effort !== void 0) {
1848
+ body.reasoning = { effort };
1849
+ }
1775
1850
  }
1776
1851
  return body;
1777
1852
  }
@@ -2046,6 +2121,7 @@ function geminiThinkingBudget(level, maxOutput) {
2046
2121
  low: 0.2,
2047
2122
  medium: 0.4,
2048
2123
  high: 0.6,
2124
+ xhigh: 0.8,
2049
2125
  max: 0.8
2050
2126
  };
2051
2127
  const budget = Math.floor(maxOutput * fraction[level]);
@@ -2339,6 +2415,7 @@ function thinkingBudget(level, maxOutput) {
2339
2415
  low: 0.2,
2340
2416
  medium: 0.4,
2341
2417
  high: 0.6,
2418
+ xhigh: 0.8,
2342
2419
  max: 0.8
2343
2420
  };
2344
2421
  return Math.max(0, Math.floor(maxOutput * fraction[level]));
package/dist/mcp.js CHANGED
@@ -1881,8 +1881,96 @@ function platformOpenCommand(url) {
1881
1881
  }
1882
1882
 
1883
1883
  // src/facade/mcp-core/oauth/token-store.ts
1884
- import { chmodSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
1885
- import { dirname as dirname2, join as join2 } from "node:path";
1884
+ import { join as join2 } from "node:path";
1885
+
1886
+ // src/security/private-state.ts
1887
+ import {
1888
+ chmodSync,
1889
+ closeSync,
1890
+ constants,
1891
+ fchmodSync,
1892
+ fstatSync,
1893
+ lstatSync,
1894
+ mkdirSync as mkdirSync2,
1895
+ openSync,
1896
+ readFileSync as readFileSync2,
1897
+ renameSync,
1898
+ rmSync,
1899
+ writeFileSync as writeFileSync2
1900
+ } from "node:fs";
1901
+ import { randomUUID } from "node:crypto";
1902
+ import { dirname as dirname2 } from "node:path";
1903
+ var NO_FOLLOW = constants.O_NOFOLLOW ?? 0;
1904
+ var isPosix = () => process.platform !== "win32";
1905
+ function assertOwned(uid, path) {
1906
+ if (!isPosix() || process.getuid === void 0) return;
1907
+ if (uid !== process.getuid()) throw new Error(`Refusing sensitive path not owned by the current user: ${path}`);
1908
+ }
1909
+ function ensurePrivateDirectorySync(path) {
1910
+ try {
1911
+ const current = lstatSync(path);
1912
+ if (current.isSymbolicLink() || !current.isDirectory()) throw new Error(`Refusing non-directory sensitive state path: ${path}`);
1913
+ assertOwned(current.uid, path);
1914
+ } catch (error) {
1915
+ if (error.code !== "ENOENT") throw error;
1916
+ mkdirSync2(path, { recursive: true, mode: 448 });
1917
+ }
1918
+ if (isPosix()) chmodSync(path, 448);
1919
+ }
1920
+ function validateExistingFile(path) {
1921
+ try {
1922
+ const current = lstatSync(path);
1923
+ if (current.isSymbolicLink() || !current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path}`);
1924
+ assertOwned(current.uid, path);
1925
+ } catch (error) {
1926
+ if (error.code === "ENOENT") return;
1927
+ throw error;
1928
+ }
1929
+ }
1930
+ function readPrivateFileSync(path) {
1931
+ ensurePrivateDirectorySync(dirname2(path));
1932
+ validateExistingFile(path);
1933
+ let fd;
1934
+ try {
1935
+ fd = openSync(path, constants.O_RDONLY | NO_FOLLOW);
1936
+ } catch (error) {
1937
+ if (error.code === "ENOENT") return null;
1938
+ throw error;
1939
+ }
1940
+ try {
1941
+ const current = fstatSync(fd);
1942
+ if (!current.isFile()) throw new Error(`Refusing non-regular sensitive file: ${path}`);
1943
+ assertOwned(current.uid, path);
1944
+ if (isPosix()) fchmodSync(fd, 384);
1945
+ return readFileSync2(fd, "utf8");
1946
+ } finally {
1947
+ closeSync(fd);
1948
+ }
1949
+ }
1950
+ function atomicWritePrivateFileSync(path, content) {
1951
+ ensurePrivateDirectorySync(dirname2(path));
1952
+ validateExistingFile(path);
1953
+ const temporary = `${path}.tmp-${process.pid}-${randomUUID()}`;
1954
+ let fd;
1955
+ try {
1956
+ fd = openSync(temporary, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | NO_FOLLOW, 384);
1957
+ writeFileSync2(fd, content, "utf8");
1958
+ if (isPosix()) fchmodSync(fd, 384);
1959
+ closeSync(fd);
1960
+ fd = void 0;
1961
+ renameSync(temporary, path);
1962
+ if (isPosix()) chmodSync(path, 384);
1963
+ } catch (error) {
1964
+ if (fd !== void 0) closeSync(fd);
1965
+ try {
1966
+ rmSync(temporary, { force: true });
1967
+ } catch {
1968
+ }
1969
+ throw error;
1970
+ }
1971
+ }
1972
+
1973
+ // src/facade/mcp-core/oauth/token-store.ts
1886
1974
  function defaultCredentialsDir() {
1887
1975
  const xdg = process.env.XDG_CONFIG_HOME;
1888
1976
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -1899,10 +1987,11 @@ function credentialsPath(credentialsDir, id) {
1899
1987
  }
1900
1988
  function readMcpOAuthState(credentialsDir, id) {
1901
1989
  const path = credentialsPath(credentialsDir, id);
1902
- if (!existsSync2(path)) return void 0;
1903
1990
  let raw;
1904
1991
  try {
1905
- raw = readFileSync2(path, "utf8");
1992
+ const stored = readPrivateFileSync(path);
1993
+ if (stored === null) return void 0;
1994
+ raw = stored;
1906
1995
  } catch (e) {
1907
1996
  return void 0;
1908
1997
  }
@@ -1917,15 +2006,8 @@ function readMcpOAuthState(credentialsDir, id) {
1917
2006
  }
1918
2007
  function writeMcpOAuthState(credentialsDir, state) {
1919
2008
  const path = credentialsPath(credentialsDir, state.id);
1920
- mkdirSync2(dirname2(path), { recursive: true });
1921
- const tmp = `${path}.tmp-${process.pid}-${Date.now()}`;
1922
2009
  const json = JSON.stringify({ ...state, updatedAt: Date.now() }, null, 2);
1923
- writeFileSync2(tmp, json, { mode: 384 });
1924
- renameSync(tmp, path);
1925
- try {
1926
- chmodSync(path, 384);
1927
- } catch {
1928
- }
2010
+ atomicWritePrivateFileSync(path, json);
1929
2011
  }
1930
2012
  function clearMcpOAuthState(credentialsDir, id) {
1931
2013
  const path = credentialsPath(credentialsDir, id);
@@ -0,0 +1,93 @@
1
+ // src/react-host/loader.ts
2
+ import { createRequire } from "node:module";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
+ function findPackageRoot(start) {
7
+ let current = path.resolve(start);
8
+ while (true) {
9
+ const packageJson = path.join(current, "package.json");
10
+ if (fs.existsSync(packageJson)) {
11
+ return current;
12
+ }
13
+ const parent = path.dirname(current);
14
+ if (parent === current) {
15
+ return null;
16
+ }
17
+ current = parent;
18
+ }
19
+ }
20
+ function createPackageRequire(packageRoot) {
21
+ return createRequire(path.join(packageRoot, "package.json"));
22
+ }
23
+ function candidatePackageRoots() {
24
+ const roots = /* @__PURE__ */ new Set();
25
+ const addCandidate = (candidate) => {
26
+ if (!candidate) {
27
+ return;
28
+ }
29
+ const root = findPackageRoot(candidate);
30
+ if (root) {
31
+ roots.add(root);
32
+ }
33
+ };
34
+ const argv1 = process.argv[1];
35
+ let argv1Real;
36
+ if (argv1) {
37
+ try {
38
+ argv1Real = fs.realpathSync(argv1);
39
+ } catch {
40
+ argv1Real = argv1;
41
+ }
42
+ }
43
+ const packageRoot = fileURLToPath(new URL("../../..", import.meta.url));
44
+ addCandidate(process.env.INDUSAGI_REACT_HOST_ROOT);
45
+ addCandidate(argv1Real ? path.dirname(argv1Real) : void 0);
46
+ addCandidate(argv1 ? path.dirname(argv1) : void 0);
47
+ addCandidate(process.env.INIT_CWD);
48
+ addCandidate(process.cwd());
49
+ addCandidate(packageRoot);
50
+ return [...roots];
51
+ }
52
+ function resolveHostModule(specifier) {
53
+ const failures = [];
54
+ for (const packageRoot of candidatePackageRoots()) {
55
+ try {
56
+ return createPackageRequire(packageRoot).resolve(specifier);
57
+ } catch (error) {
58
+ failures.push(`${packageRoot}: ${String(error.message ?? error)}`);
59
+ }
60
+ }
61
+ throw new Error(
62
+ `Unable to resolve host module "${specifier}" from any detected package root.
63
+ ${failures.join("\n")}`
64
+ );
65
+ }
66
+ function normalizeModuleNamespace(moduleNamespace) {
67
+ const defaultExport = moduleNamespace.default;
68
+ if (defaultExport && typeof defaultExport === "object") {
69
+ return { ...defaultExport, ...moduleNamespace };
70
+ }
71
+ return moduleNamespace;
72
+ }
73
+ async function importHostModule(specifier) {
74
+ const resolved = resolveHostModule(specifier);
75
+ const moduleNamespace = await import(pathToFileURL(resolved).href);
76
+ return normalizeModuleNamespace(moduleNamespace);
77
+ }
78
+ var jsxDevRuntimeInstance = null;
79
+ function loadHostJsxDevRuntime() {
80
+ if (!jsxDevRuntimeInstance) {
81
+ jsxDevRuntimeInstance = importHostModule("react/jsx-dev-runtime");
82
+ }
83
+ return jsxDevRuntimeInstance;
84
+ }
85
+
86
+ // src/react-host/jsx-dev-runtime.ts
87
+ var jsxDevRuntime = await loadHostJsxDevRuntime();
88
+ var Fragment = jsxDevRuntime.Fragment;
89
+ var jsxDEV = jsxDevRuntime.jsxDEV;
90
+ export {
91
+ Fragment,
92
+ jsxDEV
93
+ };
package/dist/react-ink.js CHANGED
@@ -1209,9 +1209,9 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
1209
1209
  const inner = (headingToken.tokens ?? []).map((child) => formatToken(child, theme, highlight)).join("");
1210
1210
  const colored = theme.role("heading", inner);
1211
1211
  if (headingToken.depth === 1) {
1212
- return chalk2.bold.italic.underline(colored) + EOL + EOL;
1212
+ return chalk2.bold.underline(`${theme.role("heading", "\u25B0")} ${colored}`) + EOL;
1213
1213
  }
1214
- return chalk2.bold(colored) + EOL + EOL;
1214
+ return chalk2.bold(`${theme.role("heading", "\u25C6")} ${colored}`) + EOL;
1215
1215
  }
1216
1216
  case "hr":
1217
1217
  return "---";
@@ -1245,8 +1245,14 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
1245
1245
  return (token.tokens ?? []).map(
1246
1246
  (child) => `${" ".repeat(listDepth)}${formatToken(child, theme, highlight, listDepth + 1, orderedListNumber, token)}`
1247
1247
  ).join("");
1248
- case "paragraph":
1249
- return (token.tokens ?? []).map((child) => formatToken(child, theme, highlight)).join("") + EOL;
1248
+ case "paragraph": {
1249
+ const children = token.tokens ?? [];
1250
+ const body = children.map((child) => formatToken(child, theme, highlight)).join("");
1251
+ if (children.length === 1 && children[0]?.type === "strong") {
1252
+ return `${theme.role("heading", "\u25C6")} ${body}${EOL}`;
1253
+ }
1254
+ return body + EOL;
1255
+ }
1250
1256
  case "space":
1251
1257
  case "br":
1252
1258
  return EOL;
@@ -1256,7 +1262,7 @@ function formatToken(token, theme, highlight = null, listDepth = 0, orderedListN
1256
1262
  return textToken.text;
1257
1263
  }
1258
1264
  if (parent?.type === "list_item") {
1259
- const marker = orderedListNumber === null ? "-" : `${getListNumber(listDepth, orderedListNumber)}.`;
1265
+ const marker = orderedListNumber === null ? "\u2022" : `${getListNumber(listDepth, orderedListNumber)}.`;
1260
1266
  const body = textToken.tokens ? textToken.tokens.map((child) => formatToken(child, theme, highlight, listDepth, orderedListNumber, token)).join("") : textToken.text;
1261
1267
  return `${marker} ${body}${EOL}`;
1262
1268
  }