@pentoshi/clai 0.2.3 → 0.2.6

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.
@@ -0,0 +1,20 @@
1
+ export interface ThinkingResult {
2
+ visible: string;
3
+ hasThinking: boolean;
4
+ thinkContent: string;
5
+ }
6
+ export declare function stripThinking(text: string): ThinkingResult;
7
+ export declare function rememberThinking(content: string): void;
8
+ export declare function rememberThinkingFromText(text: string): ThinkingResult;
9
+ export declare function clearThinking(): void;
10
+ export declare function getLastThinking(): string;
11
+ export declare function isThinkingVisible(): boolean;
12
+ export declare function toggleThinkingVisibility(): boolean;
13
+ export declare function renderThinkingBlock(content?: string): string;
14
+ export declare function renderThinkingHiddenNotice(): string;
15
+ export declare function renderThinkingSummary(content: string): string;
16
+ export declare function renderThinkingToggleMessage(): string;
17
+ export declare function createThinkingStreamParser(onVisible: (text: string) => void): {
18
+ push(token: string): void;
19
+ finish(): ThinkingResult;
20
+ };
@@ -0,0 +1,167 @@
1
+ import chalk from "chalk";
2
+ let lastThinkContent = "";
3
+ let thinkingVisible = false;
4
+ function trimBlocks(blocks) {
5
+ return blocks
6
+ .map((block) => block.trim())
7
+ .filter(Boolean)
8
+ .join("\n\n");
9
+ }
10
+ function findOpenTag(text) {
11
+ const match = /<think\b[^>]*>/i.exec(text);
12
+ if (!match)
13
+ return undefined;
14
+ return { index: match.index, length: match[0].length };
15
+ }
16
+ function findCloseTag(text) {
17
+ const match = /<\/think>/i.exec(text);
18
+ if (!match)
19
+ return undefined;
20
+ return { index: match.index, length: match[0].length };
21
+ }
22
+ export function stripThinking(text) {
23
+ const thinkBlocks = [];
24
+ const visible = text
25
+ .replace(/<think\b[^>]*>([\s\S]*?)(?:<\/think>|$)/gi, (_match, content) => {
26
+ thinkBlocks.push(content);
27
+ return "";
28
+ })
29
+ .trim();
30
+ const thinkContent = trimBlocks(thinkBlocks);
31
+ return { visible, hasThinking: thinkContent.length > 0, thinkContent };
32
+ }
33
+ export function rememberThinking(content) {
34
+ const trimmed = content.trim();
35
+ if (trimmed)
36
+ lastThinkContent = trimmed;
37
+ }
38
+ export function rememberThinkingFromText(text) {
39
+ const result = stripThinking(text);
40
+ if (result.hasThinking)
41
+ rememberThinking(result.thinkContent);
42
+ return result;
43
+ }
44
+ export function clearThinking() {
45
+ lastThinkContent = "";
46
+ }
47
+ export function getLastThinking() {
48
+ return lastThinkContent;
49
+ }
50
+ export function isThinkingVisible() {
51
+ return thinkingVisible;
52
+ }
53
+ export function toggleThinkingVisibility() {
54
+ thinkingVisible = !thinkingVisible;
55
+ return thinkingVisible;
56
+ }
57
+ export function renderThinkingBlock(content = lastThinkContent) {
58
+ return [
59
+ chalk.dim("--- thinking -----------------------------------"),
60
+ chalk.dim(content),
61
+ chalk.dim("-----------------------------------------------"),
62
+ ].join("\n");
63
+ }
64
+ export function renderThinkingHiddenNotice() {
65
+ return chalk.dim(" [thinking hidden - Ctrl+T to show]");
66
+ }
67
+ export function renderThinkingSummary(content) {
68
+ return thinkingVisible ? renderThinkingBlock(content) : renderThinkingHiddenNotice();
69
+ }
70
+ export function renderThinkingToggleMessage() {
71
+ const visible = toggleThinkingVisibility();
72
+ if (lastThinkContent && visible)
73
+ return renderThinkingBlock(lastThinkContent);
74
+ if (lastThinkContent)
75
+ return chalk.dim(" thinking hidden");
76
+ return chalk.dim(` thinking ${visible ? "will be shown" : "will be hidden"}`);
77
+ }
78
+ export function createThinkingStreamParser(onVisible) {
79
+ let pending = "";
80
+ let visible = "";
81
+ let inThink = false;
82
+ let thinkBuffer = "";
83
+ const thinkBlocks = [];
84
+ const emitVisible = (text) => {
85
+ if (!text)
86
+ return;
87
+ visible += text;
88
+ onVisible(text);
89
+ };
90
+ const emitThinking = (text) => {
91
+ if (!text)
92
+ return;
93
+ thinkBuffer += text;
94
+ };
95
+ const finishThinkingBlock = () => {
96
+ if (thinkBuffer.trim())
97
+ thinkBlocks.push(thinkBuffer);
98
+ thinkBuffer = "";
99
+ };
100
+ const processPending = (flush) => {
101
+ while (pending.length > 0) {
102
+ if (inThink) {
103
+ const closeTag = findCloseTag(pending);
104
+ if (closeTag) {
105
+ emitThinking(pending.slice(0, closeTag.index));
106
+ finishThinkingBlock();
107
+ pending = pending.slice(closeTag.index + closeTag.length);
108
+ inThink = false;
109
+ continue;
110
+ }
111
+ if (flush) {
112
+ emitThinking(pending);
113
+ pending = "";
114
+ continue;
115
+ }
116
+ const partialClose = pending.toLowerCase().lastIndexOf("</think");
117
+ const safeLength = partialClose >= 0
118
+ ? partialClose
119
+ : Math.max(0, pending.length - "</think>".length + 1);
120
+ if (safeLength === 0)
121
+ break;
122
+ emitThinking(pending.slice(0, safeLength));
123
+ pending = pending.slice(safeLength);
124
+ continue;
125
+ }
126
+ const openTag = findOpenTag(pending);
127
+ if (openTag) {
128
+ emitVisible(pending.slice(0, openTag.index));
129
+ pending = pending.slice(openTag.index + openTag.length);
130
+ inThink = true;
131
+ thinkBuffer = "";
132
+ continue;
133
+ }
134
+ if (flush) {
135
+ emitVisible(pending);
136
+ pending = "";
137
+ continue;
138
+ }
139
+ const partialOpen = pending.toLowerCase().lastIndexOf("<think");
140
+ const safeLength = partialOpen >= 0 ? partialOpen : Math.max(0, pending.length - "<think".length + 1);
141
+ if (safeLength === 0)
142
+ break;
143
+ emitVisible(pending.slice(0, safeLength));
144
+ pending = pending.slice(safeLength);
145
+ }
146
+ };
147
+ return {
148
+ push(token) {
149
+ pending += token;
150
+ processPending(false);
151
+ },
152
+ finish() {
153
+ processPending(true);
154
+ if (inThink)
155
+ finishThinkingBlock();
156
+ const thinkContent = trimBlocks(thinkBlocks);
157
+ if (thinkContent)
158
+ rememberThinking(thinkContent);
159
+ return {
160
+ visible,
161
+ hasThinking: thinkContent.length > 0,
162
+ thinkContent,
163
+ };
164
+ },
165
+ };
166
+ }
167
+ //# sourceMappingURL=thinking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thinking.js","sourceRoot":"","sources":["../../src/ui/thinking.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pentoshi/clai",
3
- "version": "0.2.3",
3
+ "version": "0.2.6",
4
4
  "description": "A fast, cross-platform AI CLI assistant with ask and agent modes for shell tasks, file operations, and cybersecurity workflows.",
5
5
  "type": "module",
6
6
  "license": "MIT",