thatgfsj-code 2.2.9 → 3.0.1

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 (190) hide show
  1. package/CHANGELOG.md +15 -67
  2. package/dist/app/index.d.ts +28 -5
  3. package/dist/app/index.d.ts.map +1 -1
  4. package/dist/app/index.js +76 -10
  5. package/dist/app/index.js.map +1 -1
  6. package/dist/cache/fingerprint.d.ts +49 -0
  7. package/dist/cache/fingerprint.d.ts.map +1 -0
  8. package/dist/cache/fingerprint.js +100 -0
  9. package/dist/cache/fingerprint.js.map +1 -0
  10. package/dist/cache/index.d.ts +15 -0
  11. package/dist/cache/index.d.ts.map +1 -0
  12. package/dist/cache/index.js +15 -0
  13. package/dist/cache/index.js.map +1 -0
  14. package/dist/cache/smartModel.d.ts +40 -0
  15. package/dist/cache/smartModel.d.ts.map +1 -0
  16. package/dist/cache/smartModel.js +43 -0
  17. package/dist/cache/smartModel.js.map +1 -0
  18. package/dist/cache/stats.d.ts +93 -0
  19. package/dist/cache/stats.d.ts.map +1 -0
  20. package/dist/cache/stats.js +155 -0
  21. package/dist/cache/stats.js.map +1 -0
  22. package/dist/cache/volatile.d.ts +32 -0
  23. package/dist/cache/volatile.d.ts.map +1 -0
  24. package/dist/cache/volatile.js +44 -0
  25. package/dist/cache/volatile.js.map +1 -0
  26. package/dist/cmd/index.js +49 -57
  27. package/dist/cmd/index.js.map +1 -1
  28. package/dist/config/index.d.ts.map +1 -1
  29. package/dist/config/index.js +8 -0
  30. package/dist/config/index.js.map +1 -1
  31. package/dist/config/types.d.ts +14 -0
  32. package/dist/config/types.d.ts.map +1 -1
  33. package/dist/llm/anthropic.d.ts +55 -5
  34. package/dist/llm/anthropic.d.ts.map +1 -1
  35. package/dist/llm/anthropic.js +172 -26
  36. package/dist/llm/anthropic.js.map +1 -1
  37. package/dist/llm/index.d.ts +26 -8
  38. package/dist/llm/index.d.ts.map +1 -1
  39. package/dist/llm/index.js +83 -15
  40. package/dist/llm/index.js.map +1 -1
  41. package/dist/llm/openai.d.ts +28 -8
  42. package/dist/llm/openai.d.ts.map +1 -1
  43. package/dist/llm/openai.js +58 -8
  44. package/dist/llm/openai.js.map +1 -1
  45. package/dist/llm/provider.d.ts +40 -8
  46. package/dist/llm/provider.d.ts.map +1 -1
  47. package/dist/llm/provider.js +8 -1
  48. package/dist/llm/provider.js.map +1 -1
  49. package/dist/prompts/index.d.ts +32 -0
  50. package/dist/prompts/index.d.ts.map +1 -1
  51. package/dist/prompts/index.js +33 -11
  52. package/dist/prompts/index.js.map +1 -1
  53. package/dist/session/index.d.ts +32 -3
  54. package/dist/session/index.d.ts.map +1 -1
  55. package/dist/session/index.js +51 -36
  56. package/dist/session/index.js.map +1 -1
  57. package/dist/skills/brainstorming.js +33 -33
  58. package/dist/skills/code-review.js +35 -35
  59. package/dist/skills/executing-plans.js +18 -18
  60. package/dist/skills/frontend-design.js +25 -25
  61. package/dist/skills/git-workflow.js +26 -26
  62. package/dist/skills/improve-architecture.js +28 -28
  63. package/dist/skills/neuroweave.js +37 -37
  64. package/dist/skills/playwright.js +62 -62
  65. package/dist/skills/prototype.js +20 -20
  66. package/dist/skills/subagent.js +19 -19
  67. package/dist/skills/supabase.js +34 -34
  68. package/dist/skills/systematic-debugging.js +34 -34
  69. package/dist/skills/tdd.js +29 -29
  70. package/dist/skills/triage.js +25 -25
  71. package/dist/skills/verification.js +22 -22
  72. package/dist/skills/writing-plans.js +32 -32
  73. package/dist/tools/nwt.js +16 -16
  74. package/dist/tui/app.d.ts.map +1 -1
  75. package/dist/tui/app.js +9 -2
  76. package/dist/tui/app.js.map +1 -1
  77. package/dist/tui/components/Header.d.ts +8 -0
  78. package/dist/tui/components/Header.d.ts.map +1 -1
  79. package/dist/tui/components/Header.js +17 -4
  80. package/dist/tui/components/Header.js.map +1 -1
  81. package/dist/tui/components/InitWizard.d.ts +12 -1
  82. package/dist/tui/components/InitWizard.d.ts.map +1 -1
  83. package/dist/tui/components/InitWizard.js +58 -3
  84. package/dist/tui/components/InitWizard.js.map +1 -1
  85. package/dist/tui/components/ModelSelector.d.ts +3 -1
  86. package/dist/tui/components/ModelSelector.d.ts.map +1 -1
  87. package/dist/tui/components/ModelSelector.js +24 -7
  88. package/dist/tui/components/ModelSelector.js.map +1 -1
  89. package/dist/tui/components/ToolCall.d.ts.map +1 -1
  90. package/dist/tui/components/ToolCall.js +1 -6
  91. package/dist/tui/components/ToolCall.js.map +1 -1
  92. package/dist/tui/components/UserInput.d.ts.map +1 -1
  93. package/dist/tui/components/UserInput.js +20 -0
  94. package/dist/tui/components/UserInput.js.map +1 -1
  95. package/dist/tui/hooks/useChat.d.ts +22 -0
  96. package/dist/tui/hooks/useChat.d.ts.map +1 -1
  97. package/dist/tui/hooks/useChat.js +82 -46
  98. package/dist/tui/hooks/useChat.js.map +1 -1
  99. package/dist/tui/hooks/useCommands.d.ts.map +1 -1
  100. package/dist/tui/hooks/useCommands.js +57 -0
  101. package/dist/tui/hooks/useCommands.js.map +1 -1
  102. package/dist/tui/welcome.d.ts.map +1 -1
  103. package/dist/tui/welcome.js +2 -3
  104. package/dist/tui/welcome.js.map +1 -1
  105. package/dist/types.d.ts +79 -6
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/types.js +7 -0
  108. package/dist/types.js.map +1 -1
  109. package/dist/utils/stableStringify.d.ts +21 -0
  110. package/dist/utils/stableStringify.d.ts.map +1 -0
  111. package/dist/utils/stableStringify.js +53 -0
  112. package/dist/utils/stableStringify.js.map +1 -0
  113. package/dist/utils/thinking.d.ts.map +1 -1
  114. package/dist/utils/thinking.js +0 -3
  115. package/dist/utils/thinking.js.map +1 -1
  116. package/package.json +7 -6
  117. package/src/app/index.ts +189 -124
  118. package/src/cache/fingerprint.ts +101 -0
  119. package/src/cache/index.ts +15 -0
  120. package/src/cache/smartModel.ts +52 -0
  121. package/src/cache/stats.ts +199 -0
  122. package/src/cache/volatile.ts +47 -0
  123. package/src/cmd/index.tsx +288 -292
  124. package/src/config/index.ts +156 -148
  125. package/src/config/providers.ts +234 -234
  126. package/src/config/types.ts +67 -53
  127. package/src/hooks/index.ts +111 -111
  128. package/src/llm/anthropic.ts +388 -243
  129. package/src/llm/gemini.ts +169 -169
  130. package/src/llm/index.ts +265 -200
  131. package/src/llm/openai.ts +243 -196
  132. package/src/llm/provider.ts +66 -34
  133. package/src/prompts/index.ts +260 -220
  134. package/src/session/compactor.ts +103 -103
  135. package/src/session/index.ts +181 -168
  136. package/src/session/message.ts +42 -42
  137. package/src/skills/brainstorming.ts +43 -43
  138. package/src/skills/code-review.ts +45 -45
  139. package/src/skills/executing-plans.ts +27 -27
  140. package/src/skills/frontend-design.ts +35 -35
  141. package/src/skills/git-workflow.ts +36 -36
  142. package/src/skills/improve-architecture.ts +38 -38
  143. package/src/skills/index.ts +136 -136
  144. package/src/skills/neuroweave.ts +47 -47
  145. package/src/skills/playwright.ts +72 -72
  146. package/src/skills/prototype.ts +30 -30
  147. package/src/skills/subagent.ts +28 -28
  148. package/src/skills/supabase.ts +44 -44
  149. package/src/skills/systematic-debugging.ts +44 -44
  150. package/src/skills/tdd.ts +39 -39
  151. package/src/skills/triage.ts +35 -35
  152. package/src/skills/verification.ts +31 -31
  153. package/src/skills/writing-plans.ts +42 -42
  154. package/src/tools/nwt.ts +598 -598
  155. package/src/tools/types.ts +122 -122
  156. package/src/tui/app.tsx +200 -186
  157. package/src/tui/components/ChatList.tsx +41 -41
  158. package/src/tui/components/ChatMessage.tsx +54 -54
  159. package/src/tui/components/Header.tsx +56 -29
  160. package/src/tui/components/InitWizard.tsx +217 -132
  161. package/src/tui/components/Markdown.tsx +35 -35
  162. package/src/tui/components/ModelSelector.tsx +107 -87
  163. package/src/tui/components/StatusBar.tsx +30 -30
  164. package/src/tui/components/Thinking.tsx +17 -17
  165. package/src/tui/components/ToolCall.tsx +102 -107
  166. package/src/tui/components/UserInput.tsx +151 -131
  167. package/src/tui/hooks/useChat.ts +287 -238
  168. package/src/tui/hooks/useCommands.ts +234 -176
  169. package/src/tui/index.ts +6 -6
  170. package/src/tui/welcome.ts +177 -178
  171. package/src/types.ts +104 -42
  172. package/src/utils/diff.ts +71 -71
  173. package/src/utils/project.ts +99 -99
  174. package/src/utils/stableStringify.ts +47 -0
  175. package/src/utils/thinking.ts +118 -121
  176. package/tests/cache/fingerprint.test.ts +75 -0
  177. package/tests/cache/providerCatalog.test.ts +31 -0
  178. package/tests/cache/stableStringify.test.ts +43 -0
  179. package/tests/cache/stats.test.ts +146 -0
  180. package/tests/cache/volatile.test.ts +75 -0
  181. package/tests/smoke-pollution.mjs +78 -0
  182. package/tests/smoke-thinking.mjs +110 -0
  183. package/tests/smoke-tool-stream.mjs +69 -0
  184. package/tests/smoke-tool.mjs +117 -0
  185. package/.nwt/meta.json +0 -5
  186. package/dist/version.d.ts +0 -16
  187. package/dist/version.d.ts.map +0 -1
  188. package/dist/version.js +0 -16
  189. package/dist/version.js.map +0 -1
  190. package/src/version.ts +0 -16
@@ -1,131 +1,151 @@
1
- /** @jsxImportSource react */
2
- import React, { useState } from 'react';
3
- import { Box, Text, useInput, useApp, useFocus } from 'ink';
4
- import { COMMAND_LIST } from '../hooks/useCommands.js';
5
-
6
- interface Props {
7
- onSubmit: (input: string) => void;
8
- onCancel: () => void;
9
- disabled?: boolean;
10
- }
11
-
12
- export function UserInput({ onSubmit, onCancel, disabled }: Props) {
13
- const [value, setValue] = useState('');
14
- const [history, setHistory] = useState<string[]>([]);
15
- const [historyIdx, setHistoryIdx] = useState(-1);
16
- const [selectedCmd, setSelectedCmd] = useState(0);
17
- const { exit } = useApp();
18
- useFocus({ autoFocus: true });
19
-
20
- const showCommands = value.startsWith('/') && value.length > 0 && !value.includes(' ');
21
- const filteredCommands = showCommands
22
- ? COMMAND_LIST.filter(c => c.name.startsWith(value))
23
- : [];
24
-
25
- useInput((input, key) => {
26
- // ESC - cancel/clear (always works, even when disabled)
27
- if (key.escape) {
28
- setValue('');
29
- setSelectedCmd(0);
30
- setHistoryIdx(-1);
31
- onCancel();
32
- return;
33
- }
34
-
35
- if (disabled) return;
36
-
37
- // Command selector navigation
38
- if (showCommands && filteredCommands.length > 0) {
39
- if (key.upArrow) {
40
- setSelectedCmd(prev => Math.max(0, prev - 1));
41
- return;
42
- }
43
- if (key.downArrow) {
44
- setSelectedCmd(prev => Math.min(filteredCommands.length - 1, prev + 1));
45
- return;
46
- }
47
- if (key.tab || key.return) {
48
- const selected = filteredCommands[selectedCmd] || filteredCommands[0];
49
- setValue(selected.name + ' ');
50
- setSelectedCmd(0);
51
- return;
52
- }
53
- }
54
-
55
- if (key.return) {
56
- const trimmed = value.trim();
57
- if (trimmed) {
58
- if (trimmed === 'exit' || trimmed === 'quit') {
59
- exit();
60
- return;
61
- }
62
- setHistory(prev => [...prev, trimmed]);
63
- setHistoryIdx(-1);
64
- onSubmit(trimmed);
65
- setValue('');
66
- setSelectedCmd(0);
67
- }
68
- return;
69
- }
70
-
71
- if (key.upArrow && history.length > 0) {
72
- const newIdx = historyIdx === -1 ? history.length - 1 : Math.max(0, historyIdx - 1);
73
- setHistoryIdx(newIdx);
74
- setValue(history[newIdx]);
75
- return;
76
- }
77
-
78
- if (key.downArrow && historyIdx >= 0) {
79
- const newIdx = historyIdx + 1;
80
- if (newIdx >= history.length) {
81
- setHistoryIdx(-1);
82
- setValue('');
83
- } else {
84
- setHistoryIdx(newIdx);
85
- setValue(history[newIdx]);
86
- }
87
- return;
88
- }
89
-
90
- if (key.backspace || key.delete) {
91
- setValue(v => v.slice(0, -1));
92
- setSelectedCmd(0);
93
- return;
94
- }
95
-
96
- if (key.ctrl && input === 'c') {
97
- exit();
98
- return;
99
- }
100
-
101
- if (input && !key.ctrl && !key.meta) {
102
- setValue(v => v + input);
103
- setSelectedCmd(0);
104
- }
105
- });
106
-
107
- return (
108
- <Box flexDirection="column">
109
- {showCommands && filteredCommands.length > 0 && (
110
- <Box flexDirection="column" paddingLeft={2} marginBottom={0}>
111
- {filteredCommands.map((cmd, i) => (
112
- <Box key={cmd.name}>
113
- <Text color={i === selectedCmd ? '#06B6D4' : '#64748B'}>
114
- {i === selectedCmd ? '▸ ' : ' '}
115
- </Text>
116
- <Text color={i === selectedCmd ? '#06B6D4' : '#94A3B8'} bold={i === selectedCmd}>
117
- {cmd.name}
118
- </Text>
119
- <Text color="#64748B"> {cmd.desc}</Text>
120
- </Box>
121
- ))}
122
- </Box>
123
- )}
124
- <Box paddingY={0}>
125
- <Text color="#06B6D4" bold>{disabled ? ' ' : '❯ '}</Text>
126
- <Text>{value}</Text>
127
- {!disabled && <Text color="#06B6D4">█</Text>}
128
- </Box>
129
- </Box>
130
- );
131
- }
1
+ /** @jsxImportSource react */
2
+ import React, { useState } from 'react';
3
+ import { Box, Text, useInput, useApp, useFocus } from 'ink';
4
+ import { COMMAND_LIST } from '../hooks/useCommands.js';
5
+
6
+ interface Props {
7
+ onSubmit: (input: string) => void;
8
+ onCancel: () => void;
9
+ disabled?: boolean;
10
+ }
11
+
12
+ export function UserInput({ onSubmit, onCancel, disabled }: Props) {
13
+ const [value, setValue] = useState('');
14
+ const [history, setHistory] = useState<string[]>([]);
15
+ const [historyIdx, setHistoryIdx] = useState(-1);
16
+ const [selectedCmd, setSelectedCmd] = useState(0);
17
+ const { exit } = useApp();
18
+ useFocus({ autoFocus: true });
19
+
20
+ const showCommands = value.startsWith('/') && value.length > 0 && !value.includes(' ');
21
+ const filteredCommands = showCommands
22
+ ? COMMAND_LIST.filter(c => c.name.startsWith(value))
23
+ : [];
24
+
25
+ useInput((input, key) => {
26
+ // ESC - cancel/clear (always works, even when disabled)
27
+ if (key.escape) {
28
+ setValue('');
29
+ setSelectedCmd(0);
30
+ setHistoryIdx(-1);
31
+ onCancel();
32
+ return;
33
+ }
34
+
35
+ if (disabled) return;
36
+
37
+ // Command selector navigation
38
+ if (showCommands && filteredCommands.length > 0) {
39
+ if (key.upArrow) {
40
+ setSelectedCmd(prev => Math.max(0, prev - 1));
41
+ return;
42
+ }
43
+ if (key.downArrow) {
44
+ setSelectedCmd(prev => Math.min(filteredCommands.length - 1, prev + 1));
45
+ return;
46
+ }
47
+ if (key.tab || key.return) {
48
+ const selected = filteredCommands[selectedCmd] || filteredCommands[0];
49
+ // v3.0.0 bug fix: previously we set `value = selected.name + ' '` and
50
+ // returned, which forced the user to press Enter a SECOND time to
51
+ // actually execute the command. For single-word commands like
52
+ // /模型 /新建 /压缩 /帮助 /技能 etc. that meant: "press Enter twice
53
+ // to switch model", which is confusing and a reproduce-and-exit
54
+ // vector if the user panics and Ctrl+C's in the middle.
55
+ //
56
+ // Fix: when Enter is pressed on a command-list item, EXECUTE the
57
+ // command directly. If the user wants to append args (e.g. /模型
58
+ // <name>), they can type them after the slash. Tab still writes
59
+ // the name into the input so the user can append text.
60
+ if (key.return) {
61
+ setSelectedCmd(0);
62
+ setValue('');
63
+ setHistory(prev => [...prev, selected.name]);
64
+ setHistoryIdx(-1);
65
+ onSubmit(selected.name);
66
+ return;
67
+ }
68
+ // Tab: write the name into the input so the user can append args.
69
+ setValue(selected.name + ' ');
70
+ setSelectedCmd(0);
71
+ return;
72
+ }
73
+ }
74
+
75
+ if (key.return) {
76
+ const trimmed = value.trim();
77
+ if (trimmed) {
78
+ if (trimmed === 'exit' || trimmed === 'quit') {
79
+ exit();
80
+ return;
81
+ }
82
+ setHistory(prev => [...prev, trimmed]);
83
+ setHistoryIdx(-1);
84
+ onSubmit(trimmed);
85
+ setValue('');
86
+ setSelectedCmd(0);
87
+ }
88
+ return;
89
+ }
90
+
91
+ if (key.upArrow && history.length > 0) {
92
+ const newIdx = historyIdx === -1 ? history.length - 1 : Math.max(0, historyIdx - 1);
93
+ setHistoryIdx(newIdx);
94
+ setValue(history[newIdx]);
95
+ return;
96
+ }
97
+
98
+ if (key.downArrow && historyIdx >= 0) {
99
+ const newIdx = historyIdx + 1;
100
+ if (newIdx >= history.length) {
101
+ setHistoryIdx(-1);
102
+ setValue('');
103
+ } else {
104
+ setHistoryIdx(newIdx);
105
+ setValue(history[newIdx]);
106
+ }
107
+ return;
108
+ }
109
+
110
+ if (key.backspace || key.delete) {
111
+ setValue(v => v.slice(0, -1));
112
+ setSelectedCmd(0);
113
+ return;
114
+ }
115
+
116
+ if (key.ctrl && input === 'c') {
117
+ exit();
118
+ return;
119
+ }
120
+
121
+ if (input && !key.ctrl && !key.meta) {
122
+ setValue(v => v + input);
123
+ setSelectedCmd(0);
124
+ }
125
+ });
126
+
127
+ return (
128
+ <Box flexDirection="column">
129
+ {showCommands && filteredCommands.length > 0 && (
130
+ <Box flexDirection="column" paddingLeft={2} marginBottom={0}>
131
+ {filteredCommands.map((cmd, i) => (
132
+ <Box key={cmd.name}>
133
+ <Text color={i === selectedCmd ? '#06B6D4' : '#64748B'}>
134
+ {i === selectedCmd ? '▸ ' : ' '}
135
+ </Text>
136
+ <Text color={i === selectedCmd ? '#06B6D4' : '#94A3B8'} bold={i === selectedCmd}>
137
+ {cmd.name}
138
+ </Text>
139
+ <Text color="#64748B"> {cmd.desc}</Text>
140
+ </Box>
141
+ ))}
142
+ </Box>
143
+ )}
144
+ <Box paddingY={0}>
145
+ <Text color="#06B6D4" bold>{disabled ? ' ' : '❯ '}</Text>
146
+ <Text>{value}</Text>
147
+ {!disabled && <Text color="#06B6D4">█</Text>}
148
+ </Box>
149
+ </Box>
150
+ );
151
+ }