reasonix 0.40.0 → 0.41.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.
Files changed (130) hide show
  1. package/README.md +21 -13
  2. package/README.zh-CN.md +19 -13
  3. package/dashboard/app.css +8 -4
  4. package/dashboard/dist/app.js +279 -224
  5. package/dashboard/dist/app.js.map +1 -1
  6. package/dist/cli/acp-64VQZLDJ.js +708 -0
  7. package/dist/cli/acp-64VQZLDJ.js.map +1 -0
  8. package/dist/cli/chat-ZAGX52RV.js +46 -0
  9. package/dist/cli/{chunk-UCMTWZKU.js → chunk-2CXPDAWX.js} +2 -2
  10. package/dist/cli/{chunk-CLAN6PVH.js → chunk-4H3ZRJ2U.js} +19 -7
  11. package/dist/cli/chunk-4H3ZRJ2U.js.map +1 -0
  12. package/dist/cli/{chunk-A5LSGEEK.js → chunk-4W2CICFQ.js} +21 -10
  13. package/dist/cli/{chunk-A5LSGEEK.js.map → chunk-4W2CICFQ.js.map} +1 -1
  14. package/dist/cli/{chunk-CZSJILQP.js → chunk-65Q5HQ26.js} +39 -1
  15. package/dist/cli/chunk-65Q5HQ26.js.map +1 -0
  16. package/dist/cli/{chunk-XHQIK7B6.js → chunk-7SPOFTMT.js} +2 -2
  17. package/dist/cli/{chunk-5GKJLNP2.js → chunk-7VFNPMKG.js} +2 -2
  18. package/dist/cli/{chunk-UVRXTSK3.js → chunk-A3LL4XDV.js} +8 -2
  19. package/dist/cli/chunk-A3LL4XDV.js.map +1 -0
  20. package/dist/cli/{chunk-VLNRQMCI.js → chunk-A7VHMMDE.js} +2 -2
  21. package/dist/cli/{chunk-R4YTW7PR.js → chunk-ARF3N2SY.js} +56 -12
  22. package/dist/cli/chunk-ARF3N2SY.js.map +1 -0
  23. package/dist/cli/{chunk-AVB3WZWU.js → chunk-AT6GGIBV.js} +10 -10
  24. package/dist/cli/{chunk-RFX7TYVV.js → chunk-BOFL3T45.js} +14 -1
  25. package/dist/cli/chunk-BOFL3T45.js.map +1 -0
  26. package/dist/cli/{chunk-SZH34P45.js → chunk-BYZGO3BX.js} +43 -17
  27. package/dist/cli/chunk-BYZGO3BX.js.map +1 -0
  28. package/dist/cli/{chunk-7DLHHBGN.js → chunk-CD4SCQL4.js} +6 -4
  29. package/dist/cli/chunk-CD4SCQL4.js.map +1 -0
  30. package/dist/cli/{chunk-HCC42PEI.js → chunk-CFY2XLY6.js} +6 -2
  31. package/dist/cli/chunk-CFY2XLY6.js.map +1 -0
  32. package/dist/cli/{chunk-26UDIXLD.js → chunk-F2AV2QDK.js} +493 -460
  33. package/dist/cli/chunk-F2AV2QDK.js.map +1 -0
  34. package/dist/cli/{chunk-KMWKGPFZ.js → chunk-H4OLWRSX.js} +10 -1
  35. package/dist/cli/chunk-H4OLWRSX.js.map +1 -0
  36. package/dist/cli/{chunk-4YV2GBYG.js → chunk-IEA6JOIP.js} +291 -98
  37. package/dist/cli/chunk-IEA6JOIP.js.map +1 -0
  38. package/dist/cli/{chunk-WKOMCPXP.js → chunk-KZYLMMU5.js} +21 -13
  39. package/dist/cli/chunk-KZYLMMU5.js.map +1 -0
  40. package/dist/cli/{chunk-JWCTX5S4.js → chunk-L7W3HJZQ.js} +2 -2
  41. package/dist/cli/{chunk-MRLXEMZ7.js → chunk-LN27AKV3.js} +1 -1
  42. package/dist/cli/chunk-LN27AKV3.js.map +1 -0
  43. package/dist/cli/{chunk-IYF36OCJ.js → chunk-LTXADNCO.js} +2 -2
  44. package/dist/cli/{chunk-H7PHYVPM.js → chunk-MHGPBJ2T.js} +44 -8
  45. package/dist/cli/chunk-MHGPBJ2T.js.map +1 -0
  46. package/dist/cli/{chunk-ULBW7DYL.js → chunk-RAUPWSYA.js} +2 -2
  47. package/dist/cli/chunk-SXLJBFIV.js +245 -0
  48. package/dist/cli/chunk-SXLJBFIV.js.map +1 -0
  49. package/dist/cli/{chunk-4X3NY5ZM.js → chunk-UV7XJUJH.js} +2 -2
  50. package/dist/cli/{chunk-XJLZ4HKU.js → chunk-VFG4GIT3.js} +2 -2
  51. package/dist/cli/{chunk-FFNOMR32.js → chunk-WE3YZULK.js} +2 -2
  52. package/dist/cli/chunk-Y5XNV3NX.js +25 -0
  53. package/dist/cli/chunk-Y5XNV3NX.js.map +1 -0
  54. package/dist/cli/{chunk-XST7BSZJ.js → chunk-YJFKFTAL.js} +7 -1
  55. package/dist/cli/chunk-YJFKFTAL.js.map +1 -0
  56. package/dist/cli/{code-YQGVLIT2.js → code-X3M6ENTQ.js} +38 -35
  57. package/dist/cli/{code-YQGVLIT2.js.map → code-X3M6ENTQ.js.map} +1 -1
  58. package/dist/cli/{commands-FQZOBLLZ.js → commands-QY7MSQG7.js} +4 -4
  59. package/dist/cli/{commit-ZS24SHPG.js → commit-BRCQ3OQO.js} +3 -3
  60. package/dist/cli/{desktop-6OLENOOO.js → desktop-ZTMHQR2Y.js} +247 -28
  61. package/dist/cli/desktop-ZTMHQR2Y.js.map +1 -0
  62. package/dist/cli/{diff-2VUKNGEI.js → diff-YASCB7PU.js} +7 -7
  63. package/dist/cli/{doctor-JO2WNN6C.js → doctor-XCN5ETVP.js} +9 -9
  64. package/dist/cli/{events-APSVNROZ.js → events-2AJTXR7I.js} +3 -3
  65. package/dist/cli/index.js +69 -35
  66. package/dist/cli/index.js.map +1 -1
  67. package/dist/cli/{mcp-DCKOE5RF.js → mcp-YMWBLRR7.js} +2 -2
  68. package/dist/cli/{mcp-browse-D6GBP5RQ.js → mcp-browse-XLDUE6SB.js} +7 -3
  69. package/dist/cli/mcp-browse-XLDUE6SB.js.map +1 -0
  70. package/dist/cli/{mcp-inspect-KFGFPJ3E.js → mcp-inspect-H4D2HSJP.js} +5 -7
  71. package/dist/cli/{mcp-inspect-KFGFPJ3E.js.map → mcp-inspect-H4D2HSJP.js.map} +1 -1
  72. package/dist/cli/{prompt-PKCCLLAD.js → prompt-RSIHN62V.js} +4 -3
  73. package/dist/cli/{prune-sessions-LV33R47N.js → prune-sessions-4N3BVST2.js} +2 -2
  74. package/dist/cli/{replay-WFCYX7XF.js → replay-3GTWM75X.js} +8 -8
  75. package/dist/cli/{run-IUJYEPMT.js → run-BLZPTRDX.js} +19 -21
  76. package/dist/cli/{run-IUJYEPMT.js.map → run-BLZPTRDX.js.map} +1 -1
  77. package/dist/cli/{server-CN4QPPVJ.js → server-DRFPXXSH.js} +16 -12
  78. package/dist/cli/{server-CN4QPPVJ.js.map → server-DRFPXXSH.js.map} +1 -1
  79. package/dist/cli/{sessions-F5GPGTJN.js → sessions-BOWFPTXT.js} +13 -13
  80. package/dist/cli/{setup-WWMDBPSB.js → setup-FQL2JJC2.js} +5 -5
  81. package/dist/cli/version-XQXYSJ5L.js +30 -0
  82. package/dist/index.d.ts +148 -103
  83. package/dist/index.js +468 -134
  84. package/dist/index.js.map +1 -1
  85. package/package.json +2 -1
  86. package/dist/cli/chat-G7CUW4ZI.js +0 -45
  87. package/dist/cli/chunk-26UDIXLD.js.map +0 -1
  88. package/dist/cli/chunk-4YV2GBYG.js.map +0 -1
  89. package/dist/cli/chunk-7DLHHBGN.js.map +0 -1
  90. package/dist/cli/chunk-CLAN6PVH.js.map +0 -1
  91. package/dist/cli/chunk-CPTZ5OHX.js +0 -18
  92. package/dist/cli/chunk-CPTZ5OHX.js.map +0 -1
  93. package/dist/cli/chunk-CZSJILQP.js.map +0 -1
  94. package/dist/cli/chunk-H7PHYVPM.js.map +0 -1
  95. package/dist/cli/chunk-HCC42PEI.js.map +0 -1
  96. package/dist/cli/chunk-KMWKGPFZ.js.map +0 -1
  97. package/dist/cli/chunk-MRLXEMZ7.js.map +0 -1
  98. package/dist/cli/chunk-R4YTW7PR.js.map +0 -1
  99. package/dist/cli/chunk-RFX7TYVV.js.map +0 -1
  100. package/dist/cli/chunk-SZH34P45.js.map +0 -1
  101. package/dist/cli/chunk-UVRXTSK3.js.map +0 -1
  102. package/dist/cli/chunk-WKOMCPXP.js.map +0 -1
  103. package/dist/cli/chunk-XST7BSZJ.js.map +0 -1
  104. package/dist/cli/desktop-6OLENOOO.js.map +0 -1
  105. package/dist/cli/mcp-browse-D6GBP5RQ.js.map +0 -1
  106. package/dist/cli/version-KQUPV6T5.js +0 -30
  107. /package/dist/cli/{chat-G7CUW4ZI.js.map → chat-ZAGX52RV.js.map} +0 -0
  108. /package/dist/cli/{chunk-UCMTWZKU.js.map → chunk-2CXPDAWX.js.map} +0 -0
  109. /package/dist/cli/{chunk-XHQIK7B6.js.map → chunk-7SPOFTMT.js.map} +0 -0
  110. /package/dist/cli/{chunk-5GKJLNP2.js.map → chunk-7VFNPMKG.js.map} +0 -0
  111. /package/dist/cli/{chunk-VLNRQMCI.js.map → chunk-A7VHMMDE.js.map} +0 -0
  112. /package/dist/cli/{chunk-AVB3WZWU.js.map → chunk-AT6GGIBV.js.map} +0 -0
  113. /package/dist/cli/{chunk-JWCTX5S4.js.map → chunk-L7W3HJZQ.js.map} +0 -0
  114. /package/dist/cli/{chunk-IYF36OCJ.js.map → chunk-LTXADNCO.js.map} +0 -0
  115. /package/dist/cli/{chunk-ULBW7DYL.js.map → chunk-RAUPWSYA.js.map} +0 -0
  116. /package/dist/cli/{chunk-4X3NY5ZM.js.map → chunk-UV7XJUJH.js.map} +0 -0
  117. /package/dist/cli/{chunk-XJLZ4HKU.js.map → chunk-VFG4GIT3.js.map} +0 -0
  118. /package/dist/cli/{chunk-FFNOMR32.js.map → chunk-WE3YZULK.js.map} +0 -0
  119. /package/dist/cli/{commands-FQZOBLLZ.js.map → commands-QY7MSQG7.js.map} +0 -0
  120. /package/dist/cli/{commit-ZS24SHPG.js.map → commit-BRCQ3OQO.js.map} +0 -0
  121. /package/dist/cli/{diff-2VUKNGEI.js.map → diff-YASCB7PU.js.map} +0 -0
  122. /package/dist/cli/{doctor-JO2WNN6C.js.map → doctor-XCN5ETVP.js.map} +0 -0
  123. /package/dist/cli/{events-APSVNROZ.js.map → events-2AJTXR7I.js.map} +0 -0
  124. /package/dist/cli/{mcp-DCKOE5RF.js.map → mcp-YMWBLRR7.js.map} +0 -0
  125. /package/dist/cli/{prompt-PKCCLLAD.js.map → prompt-RSIHN62V.js.map} +0 -0
  126. /package/dist/cli/{prune-sessions-LV33R47N.js.map → prune-sessions-4N3BVST2.js.map} +0 -0
  127. /package/dist/cli/{replay-WFCYX7XF.js.map → replay-3GTWM75X.js.map} +0 -0
  128. /package/dist/cli/{sessions-F5GPGTJN.js.map → sessions-BOWFPTXT.js.map} +0 -0
  129. /package/dist/cli/{setup-WWMDBPSB.js.map → setup-FQL2JJC2.js.map} +0 -0
  130. /package/dist/cli/{version-KQUPV6T5.js.map → version-XQXYSJ5L.js.map} +0 -0
@@ -1,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-4YV2GBYG.js";
3
- import "./chunk-XJLZ4HKU.js";
4
- import "./chunk-HCC42PEI.js";
5
- import "./chunk-XHQIK7B6.js";
6
- import "./chunk-R4YTW7PR.js";
2
+ import "./chunk-IEA6JOIP.js";
3
+ import "./chunk-VFG4GIT3.js";
4
+ import "./chunk-7SPOFTMT.js";
5
+ import "./chunk-CFY2XLY6.js";
6
+ import "./chunk-ARF3N2SY.js";
7
7
  import "./chunk-DAEAAVDF.js";
8
- import "./chunk-KMWKGPFZ.js";
8
+ import "./chunk-H4OLWRSX.js";
9
9
  import "./chunk-3Q3C4W66.js";
10
- import "./chunk-SZH34P45.js";
11
- import "./chunk-7DLHHBGN.js";
12
- import "./chunk-FFNOMR32.js";
10
+ import "./chunk-BYZGO3BX.js";
11
+ import "./chunk-CD4SCQL4.js";
12
+ import "./chunk-WE3YZULK.js";
13
13
  import "./chunk-5X7LZJDE.js";
14
14
  import {
15
15
  listSessions,
16
16
  loadSessionMessages,
17
17
  sessionPath
18
- } from "./chunk-XST7BSZJ.js";
19
- import "./chunk-H7PHYVPM.js";
20
- import "./chunk-CZSJILQP.js";
18
+ } from "./chunk-YJFKFTAL.js";
19
+ import "./chunk-MHGPBJ2T.js";
20
+ import "./chunk-65Q5HQ26.js";
21
21
  import "./chunk-ZTLZO42A.js";
22
22
  import "./chunk-ORM6PK57.js";
23
23
  import "./chunk-CRPQUBP6.js";
@@ -100,4 +100,4 @@ function truncate(s, max) {
100
100
  export {
101
101
  sessionsCommand
102
102
  };
103
- //# sourceMappingURL=sessions-F5GPGTJN.js.map
103
+ //# sourceMappingURL=sessions-BOWFPTXT.js.map
@@ -2,11 +2,11 @@
2
2
  import {
3
3
  MultiSelect,
4
4
  SingleSelect
5
- } from "./chunk-A5LSGEEK.js";
5
+ } from "./chunk-4W2CICFQ.js";
6
6
  import {
7
7
  ThemeProvider,
8
8
  useTheme
9
- } from "./chunk-4X3NY5ZM.js";
9
+ } from "./chunk-UV7XJUJH.js";
10
10
  import {
11
11
  PRESET_DESCRIPTIONS
12
12
  } from "./chunk-E46ECXJD.js";
@@ -24,7 +24,7 @@ import {
24
24
  onLanguageChange,
25
25
  setLanguage,
26
26
  t
27
- } from "./chunk-H7PHYVPM.js";
27
+ } from "./chunk-MHGPBJ2T.js";
28
28
  import {
29
29
  defaultConfigPath,
30
30
  isPlausibleKey,
@@ -36,7 +36,7 @@ import {
36
36
  redactKey,
37
37
  resolveThemePreference,
38
38
  writeConfig
39
- } from "./chunk-CZSJILQP.js";
39
+ } from "./chunk-65Q5HQ26.js";
40
40
 
41
41
  // src/cli/commands/setup.tsx
42
42
  import { render } from "ink";
@@ -513,4 +513,4 @@ async function setupCommand(opts = {}) {
513
513
  export {
514
514
  setupCommand
515
515
  };
516
- //# sourceMappingURL=setup-WWMDBPSB.js.map
516
+ //# sourceMappingURL=setup-FQL2JJC2.js.map
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import "./chunk-IEA6JOIP.js";
3
+ import "./chunk-VFG4GIT3.js";
4
+ import "./chunk-7SPOFTMT.js";
5
+ import "./chunk-CFY2XLY6.js";
6
+ import "./chunk-ARF3N2SY.js";
7
+ import "./chunk-DAEAAVDF.js";
8
+ import "./chunk-H4OLWRSX.js";
9
+ import "./chunk-3Q3C4W66.js";
10
+ import "./chunk-BYZGO3BX.js";
11
+ import "./chunk-CD4SCQL4.js";
12
+ import "./chunk-WE3YZULK.js";
13
+ import "./chunk-5X7LZJDE.js";
14
+ import "./chunk-YJFKFTAL.js";
15
+ import "./chunk-MHGPBJ2T.js";
16
+ import "./chunk-65Q5HQ26.js";
17
+ import "./chunk-ZTLZO42A.js";
18
+ import "./chunk-ORM6PK57.js";
19
+ import {
20
+ VERSION
21
+ } from "./chunk-CRPQUBP6.js";
22
+
23
+ // src/cli/commands/version.ts
24
+ function versionCommand() {
25
+ console.log(`reasonix ${VERSION}`);
26
+ }
27
+ export {
28
+ versionCommand
29
+ };
30
+ //# sourceMappingURL=version-XQXYSJ5L.js.map
package/dist/index.d.ts CHANGED
@@ -636,13 +636,16 @@ interface ImmutablePrefixOptions {
636
636
  fewShots?: readonly ChatMessage[];
637
637
  }
638
638
  declare class ImmutablePrefix {
639
- readonly system: string;
639
+ /** Stable across turns; rebuilt only on /new when REASONIX.md changed on disk. */
640
+ system: string;
640
641
  /** Each `addTool` costs one cache-miss turn — DeepSeek's prefix cache is keyed by full tool list. */
641
642
  private _toolSpecs;
642
643
  readonly fewShots: readonly ChatMessage[];
643
- /** Invalidated only via `addTool`; bypassing it leaves cache stale → fingerprint diverges from sent prefix. */
644
+ /** Invalidated by addTool / removeTool / replaceSystem; bypassing any of those leaves cache stale → fingerprint diverges from sent prefix. */
644
645
  private _fingerprintCache;
645
646
  constructor(opts: ImmutablePrefixOptions);
647
+ /** Replaces the system prompt; returns true iff the string actually changed. Caller must accept a cache miss on the next turn. */
648
+ replaceSystem(s: string): boolean;
646
649
  get toolSpecs(): readonly ToolSpec[];
647
650
  toMessages(): ChatMessage[];
648
651
  tools(): ToolSpec[];
@@ -766,6 +769,8 @@ interface CacheFirstLoopOptions {
766
769
  hookCwd?: string;
767
770
  /** PauseGate bridge — defaults to singleton, injectable for tests. */
768
771
  confirmationGate?: PauseGate;
772
+ /** Re-runs the prompt builder (applyMemoryStack / codeSystemPrompt) on /new so REASONIX.md edits take effect without a restart. Accepting a cache miss is the price. */
773
+ rebuildSystem?: () => string;
769
774
  }
770
775
  interface ReconfigurableOptions {
771
776
  model?: string;
@@ -798,6 +803,7 @@ declare class CacheFirstLoop {
798
803
  readonly confirmationGate: PauseGate;
799
804
  /** Number of messages that were pre-loaded from the session file. */
800
805
  readonly resumedMessageCount: number;
806
+ private readonly _rebuildSystem;
801
807
  private _turn;
802
808
  private _streamPreference;
803
809
  /** Threaded through HTTP + every tool dispatch so Esc cancels in-flight work, not after. */
@@ -807,6 +813,7 @@ declare class CacheFirstLoop {
807
813
  private _proArmedForNextTurn;
808
814
  private _escalateThisTurn;
809
815
  private readonly _turnFailures;
816
+ private readonly _readOnlyLoop;
810
817
  private _turnSelfCorrected;
811
818
  private _foldedThisTurn;
812
819
  private _toolDispatchesThisStep;
@@ -827,10 +834,11 @@ declare class CacheFirstLoop {
827
834
  appendAndPersist(message: ChatMessage): void;
828
835
  /** Swap the just-appended assistant entry — used by self-correction to restore the original tool_calls without dropping reasoning_content. */
829
836
  private replaceTailAssistantMessage;
830
- /** "New chat" — drops in-memory messages, archives the on-disk transcript so it survives in Sessions, keeps sessionName so the prefix cache stays warm. */
837
+ /** "New chat" — drops in-memory messages, archives the on-disk transcript so it survives in Sessions, keeps sessionName so the prefix cache stays warm. Re-runs the system-prompt builder if one was wired (issue #778: REASONIX.md edits otherwise need a restart). */
831
838
  clearLog(): {
832
839
  dropped: number;
833
840
  archived: string | null;
841
+ systemRebuilt: boolean;
834
842
  };
835
843
  configure(opts: ReconfigurableOptions): void;
836
844
  /** `null` disables the cap; any change re-arms the 80% warning. */
@@ -848,6 +856,10 @@ declare class CacheFirstLoop {
848
856
  private modelForCurrentCall;
849
857
  /** Returns true ONLY on the tipping call — caller surfaces a one-shot warning. */
850
858
  private noteToolFailureSignal;
859
+ /** Returns true ONLY on the call where the read-only streak crosses the threshold (#681). */
860
+ private noteReadOnlyToolCall;
861
+ /** A call counts as mutating when its definition reports `readOnly !== true` and any dynamic `readOnlyCheck` doesn't override that for these args. */
862
+ private isMutating;
851
863
  private runOneToolCall;
852
864
  /** Stable per-call id used as the inflight key AND threaded into tool_start / tool events so the UI matches them up. */
853
865
  private inflightIdFor;
@@ -928,7 +940,7 @@ interface ParsedAtQuery {
928
940
  }
929
941
  /** Split `src/auth/log` → `{dir: "src/auth", filter: "log"}`; trailing slash sets `trailingSlash` and clears filter. */
930
942
  declare function parseAtQuery(query: string): ParsedAtQuery;
931
- /** Trailing-token only, anchored at end-of-input — distinct from `AT_MENTION_PATTERN` which scans all. */
943
+ /** Trailing-token only, anchored at end-of-input — distinct from `AT_MENTION_PATTERN` which scans all. `\p{L}\p{N}` for CJK and other non-ASCII filenames. */
932
944
  declare const AT_PICKER_PREFIX: RegExp;
933
945
  declare function detectAtPicker(input: string): {
934
946
  query: string;
@@ -1012,13 +1024,136 @@ declare function memoryEnabled(): boolean;
1012
1024
  /** Deterministic — same memory file always yields the same prefix hash. */
1013
1025
  declare function applyProjectMemory(basePrompt: string, rootDir: string): string;
1014
1026
 
1027
+ type ThemeName = "default" | "dark" | "light" | "tokyo-night" | "github-dark" | "github-light" | "high-contrast";
1028
+
1029
+ type LanguageCode = "EN" | "zh-CN";
1030
+
1031
+ /** Shared exclude defaults + resolver — chunker, directory_tree, and dashboard read from here. */
1032
+ interface IndexUserConfig {
1033
+ excludeDirs?: string[];
1034
+ excludeFiles?: string[];
1035
+ excludeExts?: string[];
1036
+ excludePatterns?: string[];
1037
+ respectGitignore?: boolean;
1038
+ maxFileBytes?: number;
1039
+ }
1040
+
1041
+ /** Library reads only DEEPSEEK_API_KEY from env; the CLI bridges config.json → env var. */
1042
+
1043
+ /** Legacy `fast|smart|max` kept for back-compat with existing config.json files. */
1044
+ type PresetName = "auto" | "flash" | "pro" | "fast" | "smart" | "max";
1045
+ /** Single trust dial: review queues edits + gates shell; auto applies + gates shell; yolo skips both gates. */
1046
+ type EditMode = "review" | "auto" | "yolo";
1047
+ type ReasoningEffort = "high" | "max";
1048
+ type EmbeddingProvider = "ollama" | "openai-compat";
1049
+ interface OllamaEmbeddingUserConfig {
1050
+ baseUrl?: string;
1051
+ model?: string;
1052
+ }
1053
+ interface OpenAICompatEmbeddingUserConfig {
1054
+ baseUrl?: string;
1055
+ apiKey?: string;
1056
+ model?: string;
1057
+ extraBody?: Record<string, unknown>;
1058
+ }
1059
+ interface SemanticEmbeddingUserConfig {
1060
+ provider?: EmbeddingProvider;
1061
+ ollama?: OllamaEmbeddingUserConfig;
1062
+ openaiCompat?: OpenAICompatEmbeddingUserConfig;
1063
+ }
1064
+ interface ReasonixConfig {
1065
+ apiKey?: string;
1066
+ baseUrl?: string;
1067
+ lang?: LanguageCode;
1068
+ preset?: PresetName;
1069
+ editMode?: EditMode;
1070
+ editModeHintShown?: boolean;
1071
+ mouseClipboardHintShown?: boolean;
1072
+ reasoningEffort?: ReasoningEffort;
1073
+ /** Default workspace root for the desktop client. CLI uses cwd. */
1074
+ workspaceDir?: string;
1075
+ /** Last N workspace paths the desktop client has opened, most recent first. */
1076
+ recentWorkspaces?: string[];
1077
+ /** Desktop only — `openWith` value for clicking file links. Empty/undefined = OS default app. Examples: "code", "cursor", "C:\\path\\to\\editor.exe". */
1078
+ editor?: string;
1079
+ theme?: ThemeName | "auto";
1080
+ /** Stored as `--mcp`-format strings so one parser handles both flag and config. */
1081
+ mcp?: string[];
1082
+ /** Names of servers in `mcp` to skip on bridge — see `/mcp disable <name>`. */
1083
+ mcpDisabled?: string[];
1084
+ /** Env overlay per MCP server name (matches the `name=` prefix of the spec). Stdio transports merge this over process.env; SSE/HTTP ignore it. */
1085
+ mcpEnv?: Record<string, Record<string, string>>;
1086
+ session?: string | null;
1087
+ setupCompleted?: boolean;
1088
+ search?: boolean;
1089
+ /** Web search engine backend: "mojeek" (default, scrapes Mojeek) or "searxng" (self-hosted SearXNG). */
1090
+ webSearchEngine?: "mojeek" | "searxng";
1091
+ /** Base URL for SearXNG instance (default http://localhost:8080). */
1092
+ webSearchEndpoint?: string;
1093
+ dashboard?: {
1094
+ /** Pin the embedded dashboard to a fixed port — required for stable SSH tunnels. 0/absent → ephemeral. */
1095
+ port?: number;
1096
+ };
1097
+ escalation?: {
1098
+ /** Per-turn repair/error signal count required to escalate flash→pro. Defaults to 3. Out-of-range → default. */
1099
+ failureThreshold?: number;
1100
+ };
1101
+ /** Per-field visibility toggles for the bottom status row. All default to true (visible). */
1102
+ statusBar?: {
1103
+ showBalance?: boolean;
1104
+ showSessionCost?: boolean;
1105
+ showTurnCost?: boolean;
1106
+ showCacheHit?: boolean;
1107
+ showVersion?: boolean;
1108
+ showFeedbackHint?: boolean;
1109
+ };
1110
+ projects?: {
1111
+ [absoluteRootDir: string]: {
1112
+ shellAllowed?: string[];
1113
+ /** Absolute directory prefixes the user pre-approved for outside-sandbox file access (#684). */
1114
+ pathAllowed?: string[];
1115
+ };
1116
+ };
1117
+ index?: IndexUserConfig;
1118
+ semantic?: SemanticEmbeddingUserConfig;
1119
+ /** User-declared extensions to the built-in memory types (#709). Unknown types round-trip even without a declaration; declaring one lets you attach a default priority + lifecycle. */
1120
+ memory?: {
1121
+ customTypes?: CustomMemoryTypeConfig[];
1122
+ };
1123
+ }
1124
+ interface CustomMemoryTypeConfig {
1125
+ name: string;
1126
+ description?: string;
1127
+ priority?: "low" | "medium" | "high";
1128
+ expires?: "project_end";
1129
+ }
1130
+ declare function defaultConfigPath(): string;
1131
+ declare function readConfig(path?: string): ReasonixConfig;
1132
+ declare function writeConfig(cfg: ReasonixConfig, path?: string): void;
1133
+ /** Resolve the API key from env var first, then the config file. */
1134
+ declare function loadApiKey(path?: string): string | undefined;
1135
+ /** env > config > undefined. Client falls back to api.deepseek.com when undefined. */
1136
+ declare function loadBaseUrl(path?: string): string | undefined;
1137
+ declare function saveBaseUrl(url: string, path?: string): void;
1138
+ declare function saveApiKey(key: string, path?: string): void;
1139
+ /** Self-hosted DeepSeek-compatible endpoints may issue any token shape, so we only typo-guard here — the real auth check is the first API call against `baseUrl`. */
1140
+ declare function isPlausibleKey(key: string): boolean;
1141
+ /** Mask a key for display: `sk-abcd...wxyz`. */
1142
+ declare function redactKey(key: string): string;
1143
+
1015
1144
  /** User-private memory pinned into the immutable prefix; distinct from committable REASONIX.md. */
1145
+
1016
1146
  declare const USER_MEMORY_DIR = "memory";
1017
1147
  declare const MEMORY_INDEX_FILE = "MEMORY.md";
1018
1148
  /** Cap on the index file content loaded into the prefix, per scope. */
1019
1149
  declare const MEMORY_INDEX_MAX_CHARS = 4000;
1020
- type MemoryType = "user" | "feedback" | "project" | "reference";
1150
+ declare const BUILTIN_MEMORY_TYPES: readonly ["user", "feedback", "project", "reference"];
1151
+ type BuiltinMemoryType = (typeof BUILTIN_MEMORY_TYPES)[number];
1152
+ /** Built-ins plus any string declared in `config.memory.customTypes`. Unknown values are accepted (round-tripped verbatim). */
1153
+ type MemoryType = BuiltinMemoryType | (string & {});
1021
1154
  type MemoryScope = "global" | "project";
1155
+ type MemoryPriority = "low" | "medium" | "high";
1156
+ type MemoryExpires = "project_end";
1022
1157
  interface MemoryEntry {
1023
1158
  name: string;
1024
1159
  type: MemoryType;
@@ -1027,6 +1162,10 @@ interface MemoryEntry {
1027
1162
  body: string;
1028
1163
  /** ISO date string (YYYY-MM-DD). */
1029
1164
  createdAt: string;
1165
+ /** Explicit per-entry priority; absent → resolve from config default for `type`, else "medium". */
1166
+ priority?: MemoryPriority;
1167
+ /** Lifecycle hint. `project_end` → cleared by `/memory clear project`. */
1168
+ expires?: MemoryExpires;
1030
1169
  }
1031
1170
  interface MemoryStoreOptions {
1032
1171
  /** Override `~/.reasonix` — tests set this to a tmpdir. */
@@ -1040,6 +1179,8 @@ interface WriteInput {
1040
1179
  scope: MemoryScope;
1041
1180
  description: string;
1042
1181
  body: string;
1182
+ priority?: MemoryPriority;
1183
+ expires?: MemoryExpires;
1043
1184
  }
1044
1185
  /** Throws on path-injection (../, /, leading dot). Allowed: 3-40 chars, alnum/_/-, interior `.`. */
1045
1186
  declare function sanitizeMemoryName(raw: string): string;
@@ -1074,6 +1215,7 @@ declare class MemoryStore {
1074
1215
  declare function applyUserMemory(basePrompt: string, opts?: {
1075
1216
  homeDir?: string;
1076
1217
  projectRoot?: string;
1218
+ cfg?: ReasonixConfig;
1077
1219
  }): string;
1078
1220
  declare function applyMemoryStack(basePrompt: string, rootDir: string): string;
1079
1221
 
@@ -1273,6 +1415,7 @@ declare class JobRegistry {
1273
1415
  }): JobReadResult | null;
1274
1416
  waitForJob(id: number, opts?: {
1275
1417
  timeoutMs?: number;
1418
+ waitFor?: "exit" | "output-or-exit";
1276
1419
  }): Promise<JobWaitResult | null>;
1277
1420
  /** SIGTERM, wait graceMs, then SIGKILL. Idempotent on already-exited jobs. */
1278
1421
  stop(id: number, opts?: {
@@ -2080,104 +2223,6 @@ interface CodeSystemPromptOptions {
2080
2223
  }
2081
2224
  declare function codeSystemPrompt(rootDir: string, opts?: CodeSystemPromptOptions): string;
2082
2225
 
2083
- type ThemeName = "default" | "dark" | "light" | "tokyo-night" | "github-dark" | "github-light" | "high-contrast";
2084
-
2085
- type LanguageCode = "EN" | "zh-CN";
2086
-
2087
- /** Shared exclude defaults + resolver — chunker, directory_tree, and dashboard read from here. */
2088
- interface IndexUserConfig {
2089
- excludeDirs?: string[];
2090
- excludeFiles?: string[];
2091
- excludeExts?: string[];
2092
- excludePatterns?: string[];
2093
- respectGitignore?: boolean;
2094
- maxFileBytes?: number;
2095
- }
2096
-
2097
- /** Library reads only DEEPSEEK_API_KEY from env; the CLI bridges config.json → env var. */
2098
-
2099
- /** Legacy `fast|smart|max` kept for back-compat with existing config.json files. */
2100
- type PresetName = "auto" | "flash" | "pro" | "fast" | "smart" | "max";
2101
- /** Single trust dial: review queues edits + gates shell; auto applies + gates shell; yolo skips both gates. */
2102
- type EditMode = "review" | "auto" | "yolo";
2103
- type ReasoningEffort = "high" | "max";
2104
- type EmbeddingProvider = "ollama" | "openai-compat";
2105
- interface OllamaEmbeddingUserConfig {
2106
- baseUrl?: string;
2107
- model?: string;
2108
- }
2109
- interface OpenAICompatEmbeddingUserConfig {
2110
- baseUrl?: string;
2111
- apiKey?: string;
2112
- model?: string;
2113
- extraBody?: Record<string, unknown>;
2114
- }
2115
- interface SemanticEmbeddingUserConfig {
2116
- provider?: EmbeddingProvider;
2117
- ollama?: OllamaEmbeddingUserConfig;
2118
- openaiCompat?: OpenAICompatEmbeddingUserConfig;
2119
- }
2120
- interface ReasonixConfig {
2121
- apiKey?: string;
2122
- baseUrl?: string;
2123
- lang?: LanguageCode;
2124
- preset?: PresetName;
2125
- editMode?: EditMode;
2126
- editModeHintShown?: boolean;
2127
- mouseClipboardHintShown?: boolean;
2128
- reasoningEffort?: ReasoningEffort;
2129
- /** Default workspace root for the desktop client. CLI uses cwd. */
2130
- workspaceDir?: string;
2131
- /** Last N workspace paths the desktop client has opened, most recent first. */
2132
- recentWorkspaces?: string[];
2133
- /** Desktop only — `openWith` value for clicking file links. Empty/undefined = OS default app. Examples: "code", "cursor", "C:\\path\\to\\editor.exe". */
2134
- editor?: string;
2135
- theme?: ThemeName | "auto";
2136
- /** Stored as `--mcp`-format strings so one parser handles both flag and config. */
2137
- mcp?: string[];
2138
- /** Names of servers in `mcp` to skip on bridge — see `/mcp disable <name>`. */
2139
- mcpDisabled?: string[];
2140
- /** Env overlay per MCP server name (matches the `name=` prefix of the spec). Stdio transports merge this over process.env; SSE/HTTP ignore it. */
2141
- mcpEnv?: Record<string, Record<string, string>>;
2142
- session?: string | null;
2143
- setupCompleted?: boolean;
2144
- search?: boolean;
2145
- /** Web search engine backend: "mojeek" (default, scrapes Mojeek) or "searxng" (self-hosted SearXNG). */
2146
- webSearchEngine?: "mojeek" | "searxng";
2147
- /** Base URL for SearXNG instance (default http://localhost:8080). */
2148
- webSearchEndpoint?: string;
2149
- dashboard?: {
2150
- /** Pin the embedded dashboard to a fixed port — required for stable SSH tunnels. 0/absent → ephemeral. */
2151
- port?: number;
2152
- };
2153
- escalation?: {
2154
- /** Per-turn repair/error signal count required to escalate flash→pro. Defaults to 3. Out-of-range → default. */
2155
- failureThreshold?: number;
2156
- };
2157
- projects?: {
2158
- [absoluteRootDir: string]: {
2159
- shellAllowed?: string[];
2160
- /** Absolute directory prefixes the user pre-approved for outside-sandbox file access (#684). */
2161
- pathAllowed?: string[];
2162
- };
2163
- };
2164
- index?: IndexUserConfig;
2165
- semantic?: SemanticEmbeddingUserConfig;
2166
- }
2167
- declare function defaultConfigPath(): string;
2168
- declare function readConfig(path?: string): ReasonixConfig;
2169
- declare function writeConfig(cfg: ReasonixConfig, path?: string): void;
2170
- /** Resolve the API key from env var first, then the config file. */
2171
- declare function loadApiKey(path?: string): string | undefined;
2172
- /** env > config > undefined. Client falls back to api.deepseek.com when undefined. */
2173
- declare function loadBaseUrl(path?: string): string | undefined;
2174
- declare function saveBaseUrl(url: string, path?: string): void;
2175
- declare function saveApiKey(key: string, path?: string): void;
2176
- /** Self-hosted DeepSeek-compatible endpoints may issue any token shape, so we only typo-guard here — the real auth check is the first API call against `baseUrl`. */
2177
- declare function isPlausibleKey(key: string): boolean;
2178
- /** Mask a key for display: `sk-abcd...wxyz`. */
2179
- declare function redactKey(key: string): string;
2180
-
2181
2226
  /** VERSION sourced from package.json so it never drifts from npm; latest-check returns null on any failure. */
2182
2227
  /** TTL for the on-disk cache entry. 24h keeps noise low; users who
2183
2228
  * want a fresh check can run `reasonix update` which passes