thatgfsj-code 1.0.2 → 2.2.9

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 (63) hide show
  1. package/.nwt/meta.json +5 -0
  2. package/CHANGELOG.md +244 -0
  3. package/DEVELOPMENT.md +286 -0
  4. package/README.md +23 -1
  5. package/dist/app/index.d.ts +14 -0
  6. package/dist/app/index.d.ts.map +1 -1
  7. package/dist/app/index.js +21 -5
  8. package/dist/app/index.js.map +1 -1
  9. package/dist/cmd/index.d.ts +21 -0
  10. package/dist/cmd/index.d.ts.map +1 -1
  11. package/dist/cmd/index.js +144 -12
  12. package/dist/cmd/index.js.map +1 -1
  13. package/dist/session/index.d.ts +11 -0
  14. package/dist/session/index.d.ts.map +1 -1
  15. package/dist/session/index.js +83 -1
  16. package/dist/session/index.js.map +1 -1
  17. package/dist/tools/nwt.d.ts +14 -4
  18. package/dist/tools/nwt.d.ts.map +1 -1
  19. package/dist/tools/nwt.js +160 -13
  20. package/dist/tools/nwt.js.map +1 -1
  21. package/dist/tui/components/ChatList.d.ts.map +1 -1
  22. package/dist/tui/components/ChatList.js +4 -3
  23. package/dist/tui/components/ChatList.js.map +1 -1
  24. package/dist/tui/components/Header.d.ts.map +1 -1
  25. package/dist/tui/components/Header.js +2 -1
  26. package/dist/tui/components/Header.js.map +1 -1
  27. package/dist/tui/components/ToolCall.d.ts +1 -1
  28. package/dist/tui/components/ToolCall.d.ts.map +1 -1
  29. package/dist/tui/components/ToolCall.js +9 -4
  30. package/dist/tui/components/ToolCall.js.map +1 -1
  31. package/dist/tui/hooks/useChat.d.ts.map +1 -1
  32. package/dist/tui/hooks/useChat.js +47 -6
  33. package/dist/tui/hooks/useChat.js.map +1 -1
  34. package/dist/tui/hooks/useCommands.d.ts.map +1 -1
  35. package/dist/tui/hooks/useCommands.js +21 -0
  36. package/dist/tui/hooks/useCommands.js.map +1 -1
  37. package/dist/tui/welcome.d.ts.map +1 -1
  38. package/dist/tui/welcome.js +3 -2
  39. package/dist/tui/welcome.js.map +1 -1
  40. package/dist/utils/thinking.d.ts +59 -0
  41. package/dist/utils/thinking.d.ts.map +1 -0
  42. package/dist/utils/thinking.js +107 -0
  43. package/dist/utils/thinking.js.map +1 -0
  44. package/dist/version.d.ts +16 -0
  45. package/dist/version.d.ts.map +1 -0
  46. package/dist/version.js +16 -0
  47. package/dist/version.js.map +1 -0
  48. package/install.bat +63 -0
  49. package/install.ps1 +238 -0
  50. package/install.sh +113 -0
  51. package/package.json +5 -2
  52. package/src/app/index.ts +21 -5
  53. package/src/cmd/index.tsx +145 -13
  54. package/src/session/index.ts +82 -1
  55. package/src/tools/nwt.ts +181 -13
  56. package/src/tui/components/ChatList.tsx +15 -6
  57. package/src/tui/components/Header.tsx +2 -1
  58. package/src/tui/components/ToolCall.tsx +46 -10
  59. package/src/tui/hooks/useChat.ts +50 -6
  60. package/src/tui/hooks/useCommands.ts +22 -0
  61. package/src/tui/welcome.ts +3 -2
  62. package/src/utils/thinking.ts +122 -0
  63. package/src/version.ts +16 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Thinking block extraction + compression
3
+ *
4
+ * Models that aren't truly reasoning-capable (Qwen, DeepSeek-V3 chat,
5
+ * Kimi, etc.) still emit `<think>...</think>` blocks as plain text
6
+ * inside their response. These blocks can be hundreds of lines of
7
+ * internal monologue that the user doesn't want to see scroll by.
8
+ *
9
+ * opencode handles this by separating reasoning into its own stream
10
+ * part at the protocol level. We don't have that luxury — the model
11
+ * is emitting everything as a single `content` field. So we use the
12
+ * same regex-strip approach opencode uses internally (see
13
+ * packages/opencode/src/session/prompt.ts line 244).
14
+ *
15
+ * Three block delimiters are supported:
16
+ * 1. <think>...</think> — DeepSeek / Qwen / Kimi
17
+ * 2. <reasoning>...</reasoning> — OpenRouter-style
18
+ * 3. [THINK]...[/THINK] — some custom fine-tunes
19
+ *
20
+ * Usage:
21
+ * const { thinking, conclusion } = splitThinking(fullContent);
22
+ * if (thinking && compress) {
23
+ * render(`💭 ${summarize(thinking)}\n${conclusion}`);
24
+ * } else {
25
+ * render(fullContent);
26
+ * }
27
+ */
28
+
29
+ export interface ThinkingSplit {
30
+ /** Raw `<think>...` content, or empty if none. */
31
+ thinking: string;
32
+ /** Content with thinking blocks stripped + trimmed. */
33
+ conclusion: string;
34
+ /** How many lines the thinking block spanned. */
35
+ thinkingLines: number;
36
+ /** First non-empty line of the thinking block (heuristic summary). */
37
+ thinkingHint: string;
38
+ }
39
+
40
+ /**
41
+ * All known thinking-block delimiters, in priority order. The regex
42
+ * flags `gi` (global, case-insensitive) so `[THINK]` and `<think>`
43
+ * are both caught, and so multiple blocks collapse cleanly.
44
+ */
45
+ const THINKING_PATTERNS: RegExp[] = [
46
+ /<think>[\s\S]*?<\/think>/gi,
47
+ /<thinking>[\s\S]*?<\/thinking>/gi,
48
+ /<reasoning>[\s\S]*?<\/reasoning>/gi,
49
+ /<THINK>[\s\S]*?<\/THINK>/gi, // v2.2.7 edge: case variant
50
+ /\[THINK\][\s\S]*?\[\/THINK\]/gi,
51
+ /\[\/?think\]/gi, // bare [think] / [/think] (rare)
52
+ ];
53
+
54
+ export function splitThinking(content: string): ThinkingSplit {
55
+ if (!content) {
56
+ return { thinking: '', conclusion: '', thinkingLines: 0, thinkingHint: '' };
57
+ }
58
+
59
+ let thinking = '';
60
+ let remaining = content;
61
+
62
+ for (const pat of THINKING_PATTERNS) {
63
+ const matches = remaining.match(pat);
64
+ if (matches) {
65
+ thinking += matches.join('\n');
66
+ remaining = remaining.replace(pat, '');
67
+ }
68
+ }
69
+
70
+ const conclusion = remaining.trim();
71
+ const thinkingLines = thinking ? thinking.split('\n').length : 0;
72
+ const thinkingHint = firstNonEmptyLine(thinking);
73
+
74
+ return { thinking, conclusion, thinkingLines, thinkingHint };
75
+ }
76
+
77
+ /**
78
+ * Build a short, single-line summary of a thinking block, suitable
79
+ * for collapsed display. Returns something like:
80
+ * "💭 thought for 24 lines: The user is asking about Win+E..."
81
+ * Falls back to "(no hint)" if the block is empty.
82
+ */
83
+ export function summarizeThinking(split: ThinkingSplit): string {
84
+ if (!split.thinking) return '';
85
+ const hint = split.thinkingHint.length > 60
86
+ ? split.thinkingHint.slice(0, 57) + '...'
87
+ : split.thinkingHint;
88
+ return `💭 thought for ${split.thinkingLines} line${split.thinkingLines === 1 ? '' : 's'}${hint ? `: ${hint}` : ''}`;
89
+ }
90
+
91
+ /**
92
+ * Render full content with thinking blocks compressed (collapsed to
93
+ * a single-line indicator). If `showThinking` is true, returns the
94
+ * content unchanged (debug mode).
95
+ */
96
+ export function compressThinking(content: string, showThinking: boolean = false): string {
97
+ if (showThinking || !content) return content;
98
+ const split = splitThinking(content);
99
+ if (!split.thinking) return content;
100
+ const summary = summarizeThinking(split);
101
+ return summary ? `${summary}\n${split.conclusion}` : split.conclusion;
102
+ }
103
+
104
+ function firstNonEmptyLine(s: string): string {
105
+ if (!s) return '';
106
+ for (const line of s.split('\n')) {
107
+ // Strip any leading/trailing thinking-tag fragments that may have
108
+ // been captured by the regex (e.g. "<think>The user said..."
109
+ // or "...</think>"). We strip ALL occurrences to handle the
110
+ // case where the first line wraps across a tag.
111
+ const t = line
112
+ .trim()
113
+ .replace(/<\/?think>/gi, '')
114
+ .replace(/<\/?reasoning>/gi, '')
115
+ .replace(/\[\/?THINK\]/gi, '')
116
+ .trim();
117
+ if (t) return t;
118
+ }
119
+ return '';
120
+ }
121
+
122
+ export { THINKING_PATTERNS };
package/src/version.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Product version (what users see in --version, the TUI header, and
3
+ * the welcome screen). This is SEPARATE from the npm package version
4
+ * (`package.json` `version` field) — see the dual-version scheme docs
5
+ * in CHANGELOG.md (v2.2.2 entry).
6
+ *
7
+ * Bump this when shipping a user-visible change. Bump package.json
8
+ * version (npm version) at the same time. They are both +0.0.1 per
9
+ * release.
10
+ */
11
+ export const PRODUCT_VERSION = '0.4.6';
12
+
13
+ /**
14
+ * Convenience: format with leading "v" for display contexts.
15
+ */
16
+ export const PRODUCT_VERSION_DISPLAY = `v${PRODUCT_VERSION}`;