@datename/fastcode-termux 0.1.6-beta → 0.1.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.
Files changed (246) hide show
  1. package/README.md +6 -24
  2. package/dist/agent/guards.d.ts +0 -8
  3. package/dist/agent/guards.js +0 -195
  4. package/dist/agent/protocol.js +1 -4
  5. package/dist/agent/tools.d.ts +1 -3
  6. package/dist/agent/tools.js +377 -2
  7. package/dist/app.js +103 -335
  8. package/dist/cli.js +311 -362
  9. package/dist/commands/index.js +0 -22
  10. package/dist/commands/login.d.ts +2 -4
  11. package/dist/commands/login.js +10 -12
  12. package/dist/commands/logout.js +16 -8
  13. package/dist/commands/model.d.ts +0 -13
  14. package/dist/commands/model.js +22 -42
  15. package/dist/commands/provider.d.ts +0 -13
  16. package/dist/commands/provider.js +9 -20
  17. package/dist/commands/whoami.js +5 -6
  18. package/dist/config/store.d.ts +12 -32
  19. package/dist/config/store.js +65 -117
  20. package/dist/config/trust.d.ts +8 -21
  21. package/dist/config/trust.js +13 -99
  22. package/dist/lib/diagnostics.d.ts +4 -29
  23. package/dist/lib/diagnostics.js +4 -60
  24. package/dist/lib/http.d.ts +1 -11
  25. package/dist/lib/http.js +4 -62
  26. package/dist/providers/anthropic.d.ts +0 -1
  27. package/dist/providers/anthropic.js +0 -12
  28. package/dist/providers/custom.d.ts +0 -9
  29. package/dist/providers/deepseek.d.ts +0 -10
  30. package/dist/providers/deepseek.js +1 -2
  31. package/dist/providers/google.d.ts +0 -9
  32. package/dist/providers/groq.d.ts +0 -10
  33. package/dist/providers/groq.js +1 -2
  34. package/dist/providers/index.d.ts +201 -10
  35. package/dist/providers/index.js +0 -30
  36. package/dist/providers/mistral.d.ts +0 -10
  37. package/dist/providers/mistral.js +1 -2
  38. package/dist/providers/moonshot.d.ts +0 -10
  39. package/dist/providers/moonshot.js +1 -2
  40. package/dist/providers/ollama.d.ts +0 -9
  41. package/dist/providers/openai.d.ts +0 -10
  42. package/dist/providers/openai.js +1 -2
  43. package/dist/providers/openaiCompatible.d.ts +0 -9
  44. package/dist/providers/openaiCompatible.js +10 -58
  45. package/dist/providers/openrouter.d.ts +0 -10
  46. package/dist/providers/openrouter.js +1 -2
  47. package/dist/providers/qwen.d.ts +0 -10
  48. package/dist/providers/qwen.js +1 -2
  49. package/dist/providers/xai.d.ts +0 -10
  50. package/dist/providers/xai.js +1 -2
  51. package/dist/providers/zhipu.d.ts +0 -10
  52. package/dist/providers/zhipu.js +1 -2
  53. package/dist/session/log.d.ts +12 -35
  54. package/dist/session/log.js +10 -206
  55. package/dist/types.d.ts +1 -60
  56. package/dist/ui/Message.d.ts +7 -1
  57. package/dist/ui/Message.js +2 -13
  58. package/dist/ui/Prompt.d.ts +2 -1
  59. package/dist/ui/Prompt.js +2 -2
  60. package/dist/ui/Spinner.js +5 -11
  61. package/dist/ui/StatusBar.d.ts +1 -2
  62. package/dist/ui/StatusBar.js +5 -6
  63. package/package.json +1 -1
  64. package/src/agent/guards.ts +0 -196
  65. package/src/agent/protocol.ts +1 -4
  66. package/src/agent/tools.ts +377 -3
  67. package/src/app.ts +103 -335
  68. package/src/cli.ts +3 -30
  69. package/src/commands/index.ts +0 -22
  70. package/src/commands/login.ts +10 -12
  71. package/src/commands/logout.ts +16 -8
  72. package/src/commands/model.ts +22 -42
  73. package/src/commands/provider.ts +9 -20
  74. package/src/commands/whoami.ts +5 -6
  75. package/src/config/store.ts +69 -122
  76. package/src/config/trust.ts +21 -137
  77. package/src/lib/diagnostics.ts +4 -60
  78. package/src/lib/http.ts +4 -66
  79. package/src/providers/anthropic.ts +1 -13
  80. package/src/providers/deepseek.ts +1 -2
  81. package/src/providers/groq.ts +1 -2
  82. package/src/providers/index.ts +1 -32
  83. package/src/providers/mistral.ts +1 -2
  84. package/src/providers/moonshot.ts +1 -2
  85. package/src/providers/openai.ts +1 -2
  86. package/src/providers/openaiCompatible.ts +10 -58
  87. package/src/providers/openrouter.ts +1 -2
  88. package/src/providers/qwen.ts +1 -2
  89. package/src/providers/xai.ts +1 -2
  90. package/src/providers/zhipu.ts +1 -2
  91. package/src/session/log.ts +28 -267
  92. package/src/types.ts +1 -63
  93. package/src/ui/Message.ts +2 -13
  94. package/src/ui/Prompt.ts +2 -2
  95. package/src/ui/Spinner.ts +5 -11
  96. package/src/ui/StatusBar.ts +5 -6
  97. package/dist/agent/approval.d.ts +0 -50
  98. package/dist/agent/approval.js +0 -7
  99. package/dist/agent/compaction.d.ts +0 -39
  100. package/dist/agent/compaction.js +0 -227
  101. package/dist/agent/context.d.ts +0 -29
  102. package/dist/agent/context.js +0 -62
  103. package/dist/agent/ignore.d.ts +0 -11
  104. package/dist/agent/ignore.js +0 -129
  105. package/dist/agent/process-tree.d.ts +0 -2
  106. package/dist/agent/process-tree.js +0 -31
  107. package/dist/agent/protocol-mode.d.ts +0 -6
  108. package/dist/agent/protocol-mode.js +0 -51
  109. package/dist/agent/registry.d.ts +0 -17
  110. package/dist/agent/registry.js +0 -90
  111. package/dist/agent/runner.d.ts +0 -106
  112. package/dist/agent/runner.js +0 -352
  113. package/dist/agent/shell-session.d.ts +0 -37
  114. package/dist/agent/shell-session.js +0 -400
  115. package/dist/agent/stream.d.ts +0 -29
  116. package/dist/agent/stream.js +0 -103
  117. package/dist/agent/tool-schemas.d.ts +0 -2
  118. package/dist/agent/tool-schemas.js +0 -63
  119. package/dist/agent/tools/append_file.d.ts +0 -2
  120. package/dist/agent/tools/append_file.js +0 -26
  121. package/dist/agent/tools/apply_patch.d.ts +0 -10
  122. package/dist/agent/tools/apply_patch.js +0 -52
  123. package/dist/agent/tools/copy_file.d.ts +0 -2
  124. package/dist/agent/tools/copy_file.js +0 -30
  125. package/dist/agent/tools/delete_file.d.ts +0 -2
  126. package/dist/agent/tools/delete_file.js +0 -24
  127. package/dist/agent/tools/grep.d.ts +0 -2
  128. package/dist/agent/tools/grep.js +0 -23
  129. package/dist/agent/tools/index.d.ts +0 -2
  130. package/dist/agent/tools/index.js +0 -32
  131. package/dist/agent/tools/list_files.d.ts +0 -2
  132. package/dist/agent/tools/list_files.js +0 -17
  133. package/dist/agent/tools/make_dir.d.ts +0 -2
  134. package/dist/agent/tools/make_dir.js +0 -24
  135. package/dist/agent/tools/move_path.d.ts +0 -2
  136. package/dist/agent/tools/move_path.js +0 -47
  137. package/dist/agent/tools/paths.d.ts +0 -7
  138. package/dist/agent/tools/paths.js +0 -84
  139. package/dist/agent/tools/pwd.d.ts +0 -2
  140. package/dist/agent/tools/pwd.js +0 -10
  141. package/dist/agent/tools/read_file.d.ts +0 -2
  142. package/dist/agent/tools/read_file.js +0 -21
  143. package/dist/agent/tools/read_many.d.ts +0 -2
  144. package/dist/agent/tools/read_many.js +0 -25
  145. package/dist/agent/tools/readers.d.ts +0 -6
  146. package/dist/agent/tools/readers.js +0 -216
  147. package/dist/agent/tools/replace_in_file.d.ts +0 -2
  148. package/dist/agent/tools/replace_in_file.js +0 -30
  149. package/dist/agent/tools/shell.d.ts +0 -2
  150. package/dist/agent/tools/shell.js +0 -48
  151. package/dist/agent/tools/stat_path.d.ts +0 -2
  152. package/dist/agent/tools/stat_path.js +0 -31
  153. package/dist/agent/tools/types.d.ts +0 -39
  154. package/dist/agent/tools/types.js +0 -1
  155. package/dist/agent/tools/validate.d.ts +0 -6
  156. package/dist/agent/tools/validate.js +0 -29
  157. package/dist/agent/tools/write_file.d.ts +0 -2
  158. package/dist/agent/tools/write_file.js +0 -26
  159. package/dist/commands/attach.d.ts +0 -9
  160. package/dist/commands/attach.js +0 -15
  161. package/dist/commands/bg.d.ts +0 -7
  162. package/dist/commands/bg.js +0 -9
  163. package/dist/commands/cancel.d.ts +0 -10
  164. package/dist/commands/cancel.js +0 -10
  165. package/dist/commands/compact.d.ts +0 -10
  166. package/dist/commands/compact.js +0 -22
  167. package/dist/commands/context.d.ts +0 -7
  168. package/dist/commands/context.js +0 -24
  169. package/dist/commands/edit.d.ts +0 -10
  170. package/dist/commands/edit.js +0 -36
  171. package/dist/commands/effort.d.ts +0 -25
  172. package/dist/commands/effort.js +0 -48
  173. package/dist/commands/expand.d.ts +0 -10
  174. package/dist/commands/expand.js +0 -8
  175. package/dist/commands/jobs.d.ts +0 -7
  176. package/dist/commands/jobs.js +0 -16
  177. package/dist/commands/kill.d.ts +0 -7
  178. package/dist/commands/kill.js +0 -11
  179. package/dist/commands/steer.d.ts +0 -11
  180. package/dist/commands/steer.js +0 -13
  181. package/dist/lib/model-meta.d.ts +0 -19
  182. package/dist/lib/model-meta.js +0 -113
  183. package/dist/lib/native-tools.d.ts +0 -12
  184. package/dist/lib/native-tools.js +0 -21
  185. package/dist/lib/net.d.ts +0 -33
  186. package/dist/lib/net.js +0 -168
  187. package/dist/patch/apply.d.ts +0 -15
  188. package/dist/patch/apply.js +0 -172
  189. package/dist/patch/parse.d.ts +0 -29
  190. package/dist/patch/parse.js +0 -112
  191. package/dist/patch/plan.d.ts +0 -49
  192. package/dist/patch/plan.js +0 -273
  193. package/dist/session/projection.d.ts +0 -43
  194. package/dist/session/projection.js +0 -257
  195. package/dist/ui/Picker.d.ts +0 -8
  196. package/dist/ui/Picker.js +0 -24
  197. package/src/agent/approval.ts +0 -47
  198. package/src/agent/compaction.ts +0 -276
  199. package/src/agent/context.ts +0 -97
  200. package/src/agent/ignore.ts +0 -147
  201. package/src/agent/process-tree.ts +0 -32
  202. package/src/agent/protocol-mode.ts +0 -59
  203. package/src/agent/registry.ts +0 -98
  204. package/src/agent/runner.ts +0 -443
  205. package/src/agent/shell-session.ts +0 -449
  206. package/src/agent/stream.ts +0 -143
  207. package/src/agent/tool-schemas.ts +0 -67
  208. package/src/agent/tools/append_file.ts +0 -28
  209. package/src/agent/tools/apply_patch.ts +0 -54
  210. package/src/agent/tools/copy_file.ts +0 -32
  211. package/src/agent/tools/delete_file.ts +0 -26
  212. package/src/agent/tools/grep.ts +0 -25
  213. package/src/agent/tools/index.ts +0 -34
  214. package/src/agent/tools/list_files.ts +0 -19
  215. package/src/agent/tools/make_dir.ts +0 -26
  216. package/src/agent/tools/move_path.ts +0 -50
  217. package/src/agent/tools/paths.ts +0 -92
  218. package/src/agent/tools/pwd.ts +0 -12
  219. package/src/agent/tools/read_file.ts +0 -23
  220. package/src/agent/tools/read_many.ts +0 -27
  221. package/src/agent/tools/readers.ts +0 -228
  222. package/src/agent/tools/replace_in_file.ts +0 -32
  223. package/src/agent/tools/shell.ts +0 -53
  224. package/src/agent/tools/stat_path.ts +0 -33
  225. package/src/agent/tools/types.ts +0 -42
  226. package/src/agent/tools/validate.ts +0 -35
  227. package/src/agent/tools/write_file.ts +0 -28
  228. package/src/commands/attach.ts +0 -16
  229. package/src/commands/bg.ts +0 -9
  230. package/src/commands/cancel.ts +0 -10
  231. package/src/commands/compact.ts +0 -23
  232. package/src/commands/context.ts +0 -25
  233. package/src/commands/edit.ts +0 -37
  234. package/src/commands/effort.ts +0 -49
  235. package/src/commands/expand.ts +0 -8
  236. package/src/commands/jobs.ts +0 -17
  237. package/src/commands/kill.ts +0 -12
  238. package/src/commands/steer.ts +0 -13
  239. package/src/lib/model-meta.ts +0 -138
  240. package/src/lib/native-tools.ts +0 -32
  241. package/src/lib/net.ts +0 -204
  242. package/src/patch/apply.ts +0 -194
  243. package/src/patch/parse.ts +0 -131
  244. package/src/patch/plan.ts +0 -317
  245. package/src/session/projection.ts +0 -308
  246. package/src/ui/Picker.ts +0 -24
package/dist/types.d.ts CHANGED
@@ -5,26 +5,10 @@
5
5
  * what the chat loop needs (streaming completions, model list, auth).
6
6
  * Providers can layer richer behavior on top in their own modules.
7
7
  */
8
- export type Role = "system" | "user" | "assistant" | "tool";
9
- export type ReasoningEffort = "auto" | "low" | "medium" | "high" | "max";
10
- export interface NativeToolCall {
11
- id: string;
12
- name: string;
13
- arguments: string;
14
- }
15
- export interface ToolSchema {
16
- type: "function";
17
- function: {
18
- name: string;
19
- description: string;
20
- parameters: Record<string, any>;
21
- };
22
- }
8
+ export type Role = "system" | "user" | "assistant";
23
9
  export interface ChatMessage {
24
10
  role: Role;
25
11
  content: string;
26
- toolCalls?: NativeToolCall[];
27
- toolCallId?: string;
28
12
  }
29
13
  export interface ChatRequest {
30
14
  model: string;
@@ -35,26 +19,14 @@ export interface ChatRequest {
35
19
  temperature?: number;
36
20
  /** Soft cap for output tokens. */
37
21
  maxOutputTokens?: number;
38
- /**
39
- * Requested thinking depth. Providers that support it map this to their
40
- * native parameter (`reasoning_effort`, `thinking.budget_tokens`, …);
41
- * providers that don't should ignore it.
42
- */
43
- reasoningEffort?: ReasoningEffort;
44
22
  /** AbortSignal for cancellation (Esc / Ctrl+C). */
45
23
  signal?: AbortSignal;
46
- /** Stable idempotency key reused across retries of the same logical request. */
47
- clientRequestId?: string;
48
- /** Native function-calling schemas (auto mode only). */
49
- tools?: ToolSchema[];
50
24
  }
51
25
  export interface ChatChunk {
52
26
  /** Token text appended to the response. */
53
27
  delta: string;
54
28
  /** True on the final chunk. */
55
29
  done: boolean;
56
- /** Complete native tool calls (OpenAI-style) on the final chunk. */
57
- toolCalls?: NativeToolCall[];
58
30
  /** Provider-specific usage info on the final chunk. */
59
31
  usage?: {
60
32
  inputTokens?: number;
@@ -91,25 +63,6 @@ export interface Provider {
91
63
  listModels(apiKey: string | undefined): Promise<ProviderModel[]>;
92
64
  /** Stream a chat completion. */
93
65
  stream(req: ChatRequest, apiKey: string | undefined): ChatStream;
94
- /** Whether this provider/model honors ChatRequest.reasoningEffort. */
95
- supportsReasoning?(model: string): boolean;
96
- }
97
- export interface PickerItem {
98
- value: string;
99
- label: string;
100
- hint?: string;
101
- }
102
- /**
103
- * An interactive list a command can hand back to the app. The app renders it
104
- * with arrow keys, number shortcuts, and Enter (Esc cancels).
105
- */
106
- export interface PickerRequest {
107
- title: string;
108
- items: PickerItem[];
109
- /** Currently selected value, highlighted on open. */
110
- current?: string;
111
- onSelect(value: string, item: PickerItem): void;
112
- onCancel?(): void;
113
66
  }
114
67
  export interface SlashCommand {
115
68
  name: string;
@@ -128,8 +81,6 @@ export interface CommandResult {
128
81
  silent?: boolean;
129
82
  /** Quit the app after this command. */
130
83
  quit?: boolean;
131
- /** Open an interactive picker after the command runs. */
132
- picker?: PickerRequest;
133
84
  }
134
85
  export interface CommandContext {
135
86
  args: string[];
@@ -150,10 +101,6 @@ export interface AppStateSnapshot {
150
101
  enabledSkills: string[];
151
102
  enabledPlugins: string[];
152
103
  skillsRegistry: string;
153
- reasoningEffort: ReasoningEffort;
154
- expanded: boolean;
155
- busy: boolean;
156
- draft: string;
157
104
  }
158
105
  export interface AppActions {
159
106
  setProvider(id: string): void;
@@ -162,17 +109,11 @@ export interface AppActions {
162
109
  setAgentMode(enabled: boolean): void;
163
110
  setSystemPrompt(prompt: string): void;
164
111
  setSkillsRegistry(url: string): void;
165
- setReasoningEffort(effort: ReasoningEffort): void;
166
112
  enableSkill(name: string): void;
167
113
  disableSkill(name: string): void;
168
114
  enablePlugin(name: string): void;
169
115
  disablePlugin(name: string): void;
170
116
  clearHistory(): void;
171
- replaceHistory(messages: ChatMessage[]): void;
172
- cancelRun(): void;
173
- steer(text: string): void;
174
- setExpanded(value: boolean): void;
175
- setInput(text: string): void;
176
117
  pushSystemMessage(text: string): void;
177
118
  /** Begin the guided API-key flow (choose provider → model → key). */
178
119
  startLogin(options: {
@@ -1 +1,7 @@
1
- export declare const MessageBubble: ({ theme, role, content, streaming, markdown }: any) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
1
+ export declare const MessageBubble: ({ theme, role, content, streaming, markdown, }: {
2
+ theme: any;
3
+ role: any;
4
+ content: any;
5
+ streaming: any;
6
+ markdown: any;
7
+ }) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
@@ -6,19 +6,8 @@ const SIGIL = {
6
6
  assistant: "▍ FastCode",
7
7
  system: "✦ system",
8
8
  };
9
- const markdownCache = new Map();
10
- function cachedMarkdown(md) {
11
- const hit = markdownCache.get(md);
12
- if (hit !== undefined)
13
- return hit;
14
- const rendered = renderMarkdown(md);
15
- if (markdownCache.size > 200)
16
- markdownCache.clear();
17
- markdownCache.set(md, rendered);
18
- return rendered;
19
- }
20
- export const MessageBubble = ({ theme, role, content, streaming, markdown }) => {
9
+ export const MessageBubble = ({ theme, role, content, streaming, markdown, }) => {
21
10
  const color = role === "user" ? theme.user : role === "assistant" ? theme.assistant : theme.system;
22
- const display = markdown ? cachedMarkdown(content) : content;
11
+ const display = markdown ? renderMarkdown(content) : content;
23
12
  return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Text, { color: color, bold: true, children: [SIGIL[role], streaming ? _jsx(Text, { color: theme.muted, children: " (streaming)" }) : null] }), _jsx(Box, { marginLeft: 2, flexDirection: "column", children: _jsx(Text, { color: color, children: display || (streaming ? "…" : "") }) })] }));
24
13
  };
@@ -1,9 +1,10 @@
1
- export declare const Prompt: ({ theme, value, onChange, onSubmit, disabled, placeholder, mask, }: {
1
+ export declare const Prompt: ({ theme, value, onChange, onSubmit, disabled, placeholder, stable, mask, }: {
2
2
  theme: any;
3
3
  value: any;
4
4
  onChange: any;
5
5
  onSubmit: any;
6
6
  disabled: any;
7
7
  placeholder: any;
8
+ stable?: boolean;
8
9
  mask: any;
9
10
  }) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
package/dist/ui/Prompt.js CHANGED
@@ -15,9 +15,9 @@ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
15
15
  import { Box, Text } from "ink";
16
16
  import TextInput from "ink-text-input";
17
17
  import { COMMANDS } from "../commands/index.js";
18
- export const Prompt = ({ theme, value, onChange, onSubmit, disabled, placeholder, mask, }) => {
18
+ export const Prompt = ({ theme, value, onChange, onSubmit, disabled, placeholder, stable = false, mask, }) => {
19
19
  const suggestion = autocomplete(value);
20
- return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: disabled ? theme.muted : theme.accent, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: "\u276F " }), disabled ? (_jsx(Text, { color: theme.muted, children: placeholder ?? "Working… (Esc to cancel)" })) : (_jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: placeholder ?? "Type a message or /help …", showCursor: true, mask: mask }))] }), !disabled && suggestion ? (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: theme.muted, children: ["\u21AA ", suggestion] }) })) : null] }));
20
+ return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: disabled ? theme.muted : theme.accent, paddingX: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: theme.accent, bold: true, children: "\u276F " }), disabled ? (_jsx(Text, { color: theme.muted, children: placeholder ?? "Working… (Esc to cancel)" })) : (_jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: placeholder ?? "Type a message or /help …", showCursor: !stable, mask: mask }))] }), !disabled && suggestion ? (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: theme.muted, children: ["\u21AA ", suggestion] }) })) : null] }));
21
21
  };
22
22
  function autocomplete(value) {
23
23
  if (!value.startsWith("/") || value.includes(" "))
@@ -21,19 +21,13 @@ const VERBS = [
21
21
  ];
22
22
  export const Spinner = ({ theme, label, stable = false }) => {
23
23
  const [tick, setTick] = useState(0);
24
- // stable UI only lowers the redraw rate; it must still animate. A frozen
25
- // frame made long waits look like a hang.
26
- const configured = Number(process.env["FASTCODE_SPINNER_MS"]);
27
- const interval = Number.isFinite(configured) && configured >= 60
28
- ? configured
29
- : stable
30
- ? 120
31
- : 80;
32
24
  useEffect(() => {
33
- const id = setInterval(() => setTick((t) => t + 1), interval);
25
+ if (stable)
26
+ return;
27
+ const id = setInterval(() => setTick((t) => t + 1), 80);
34
28
  return () => clearInterval(id);
35
- }, [interval]);
36
- const frame = FRAMES[tick % FRAMES.length];
29
+ }, [stable]);
30
+ const frame = stable ? "⠋" : FRAMES[tick % FRAMES.length];
37
31
  const verb = label ?? VERBS[Math.floor(tick / 24) % VERBS.length];
38
32
  return (_jsxs(Text, { color: theme.accent, children: [frame, " ", _jsxs(Text, { color: theme.muted, children: [verb, "\u2026"] })] }));
39
33
  };
@@ -1,4 +1,4 @@
1
- export declare const StatusBar: ({ theme, providerId, model, inputTokens, outputTokens, costUsd, enabledSkillCount, reasoningEffort, hint, }: {
1
+ export declare const StatusBar: ({ theme, providerId, model, inputTokens, outputTokens, costUsd, enabledSkillCount, hint, }: {
2
2
  theme: any;
3
3
  providerId: any;
4
4
  model: any;
@@ -6,6 +6,5 @@ export declare const StatusBar: ({ theme, providerId, model, inputTokens, output
6
6
  outputTokens: any;
7
7
  costUsd: any;
8
8
  enabledSkillCount: any;
9
- reasoningEffort: any;
10
9
  hint: any;
11
10
  }) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
@@ -1,20 +1,19 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useStdout } from "ink";
3
3
  import { platformLabel } from "../lib/platform.js";
4
- export const StatusBar = ({ theme, providerId, model, inputTokens, outputTokens, costUsd, enabledSkillCount, reasoningEffort, hint, }) => {
4
+ export const StatusBar = ({ theme, providerId, model, inputTokens, outputTokens, costUsd, enabledSkillCount, hint, }) => {
5
5
  const { stdout } = useStdout();
6
6
  const columns = stdout?.columns ?? process.stdout.columns ?? 80;
7
7
  const compact = columns < 88;
8
8
  const cost = costUsd > 0 ? `$${costUsd.toFixed(4)}` : "$0.0000";
9
9
  const providerModel = `${providerId}/${model}`;
10
10
  const label = compact ? truncate(providerModel, Math.max(18, columns - 28)) : providerModel;
11
- const effort = reasoningEffort && reasoningEffort !== "auto" ? `effort:${reasoningEffort}` : "";
12
- return (_jsxs(Box, { flexDirection: compact ? "column" : "row", justifyContent: "space-between", borderStyle: "round", borderColor: theme.border, paddingX: 1, children: [_jsxs(Text, { color: theme.muted, children: [_jsx(Text, { color: theme.accent, children: "\u25CF" }), " ", label, _jsx(Text, { color: theme.muted, children: " \u00B7 " }), inputTokens, "\u2191 ", outputTokens, "\u2193 ", cost, effort ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: " \u00B7 " }), effort] })) : null, !compact ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: " \u00B7 " }), "skills: ", enabledSkillCount, _jsx(Text, { color: theme.muted, children: " \u00B7 " }), platformLabel()] })) : null] }), _jsx(Text, { color: theme.muted, children: compact
13
- ? `${effort ? effort + " \u00B7 " : ""}${platformLabel()} \u00B7 skills:${enabledSkillCount} \u00B7 ${hint ?? "/help \u00B7 esc \u00B7 ctrl+c"}`
14
- : hint ?? "/help \u00B7 esc cancel \u00B7 ctrl+c quit" })] }));
11
+ return (_jsxs(Box, { flexDirection: compact ? "column" : "row", justifyContent: "space-between", borderStyle: "round", borderColor: theme.border, paddingX: 1, children: [_jsxs(Text, { color: theme.muted, children: [_jsx(Text, { color: theme.accent, children: "\u25CF" }), " ", label, _jsx(Text, { color: theme.muted, children: " \u00B7 " }), inputTokens, "\u2191 ", outputTokens, "\u2193 ", cost, !compact ? (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: " \u00B7 " }), "skills: ", enabledSkillCount, _jsx(Text, { color: theme.muted, children: " \u00B7 " }), platformLabel()] })) : null] }), _jsx(Text, { color: theme.muted, children: compact
12
+ ? `${platformLabel()} · skills:${enabledSkillCount} · ${hint ?? "/help · esc · ctrl+c"}`
13
+ : hint ?? "/help · esc cancel · ctrl+c quit" })] }));
15
14
  };
16
15
  function truncate(value, max) {
17
16
  if (value.length <= max)
18
17
  return value;
19
- return `${value.slice(0, Math.max(1, max - 1))}\u2026`;
18
+ return `${value.slice(0, Math.max(1, max - 1))}…`;
20
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datename/fastcode-termux",
3
- "version": "0.1.6-beta",
3
+ "version": "0.1.6",
4
4
  "description": "FastCode — a blazing-fast TUI coding assistant. Multi-LLM, skills.sh skills, slash commands. Works on Termux, Linux, Windows, and macOS.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,5 +1,3 @@
1
- import { normalize, resolve } from "node:path";
2
-
3
1
  /**
4
2
  * Dangerous-command guard.
5
3
  *
@@ -74,197 +72,3 @@ export function evaluateShellCommand(command) {
74
72
  }
75
73
  return { allow: true, output: undefined };
76
74
  }
77
- export const READ_ONLY_TOOLS = new Set([
78
- "pwd", "read_file", "read_many", "list_files", "grep", "stat_path",
79
- ]);
80
- const READ_ONLY_COMMANDS = new Set([
81
- "pwd", "ls", "dir", "cat", "head", "tail", "wc", "stat", "file", "du", "df",
82
- "grep", "rg", "egrep", "fgrep", "which", "whereis", "where", "whoami", "id",
83
- "groups", "uname", "date", "uptime", "printenv", "echo", "printf",
84
- "true", "false", "basename", "dirname", "realpath", "readlink", "tree",
85
- "more", "less", "jq", "cut", "tr",
86
- ]);
87
- const READ_ONLY_PREFIXES = new Set([
88
- "git status", "git diff", "git log", "git show", "git rev-parse",
89
- "git ls-files", "git blame", "git grep", "git describe", "git merge-base",
90
- "git cat-file", "git rev-list", "git shortlog", "git whatchanged",
91
- "npm ls", "npm list", "npm view", "npm outdated", "npm explain", "npm why",
92
- "pnpm list", "pnpm ls", "yarn list", "yarn info",
93
- "cargo tree", "go list", "pip list", "pip show",
94
- "docker ps", "docker images", "docker logs",
95
- ]);
96
- const NON_READ_ONLY_LEADERS = new Set([
97
- "cd", "sudo", "doas", "env", "xargs", "time", "command", "eval", "exec",
98
- "source", ".", "sh", "bash", "zsh", "fish", "powershell", "cmd",
99
- ]);
100
- function scanCommand(command, onChar) {
101
- let quote = "";
102
- let escaped = false;
103
- for (let i = 0; i < command.length; i += 1) {
104
- const char = command[i];
105
- if (escaped) {
106
- escaped = false;
107
- onChar(char, i, quote);
108
- continue;
109
- }
110
- if (char === "\\") {
111
- escaped = true;
112
- onChar(char, i, quote);
113
- continue;
114
- }
115
- if (quote) {
116
- if (char === quote)
117
- quote = "";
118
- onChar(char, i, quote);
119
- continue;
120
- }
121
- if (char === '"' || char === "'") {
122
- quote = char;
123
- onChar(char, i, quote);
124
- continue;
125
- }
126
- onChar(char, i, quote);
127
- }
128
- return quote === "";
129
- }
130
- function hasWriteRedirection(command) {
131
- let found = false;
132
- const balanced = scanCommand(command, (char, index, quote) => {
133
- if (quote || char !== ">")
134
- return;
135
- const previous = command[index - 1];
136
- if (previous === "=")
137
- return;
138
- found = true;
139
- });
140
- return !balanced || found;
141
- }
142
- function hasCommandSubstitution(command) {
143
- let found = false;
144
- const balanced = scanCommand(command, (char, index, quote) => {
145
- if (quote)
146
- return;
147
- if (char === "`" || (char === "$" && command[index + 1] === "("))
148
- found = true;
149
- });
150
- return !balanced || found;
151
- }
152
- export function splitCommandSegments(command) {
153
- const parts = [];
154
- let current = "";
155
- let quote = "";
156
- let escaped = false;
157
- for (let i = 0; i < command.length; i += 1) {
158
- const char = command[i];
159
- if (escaped) {
160
- current += char;
161
- escaped = false;
162
- continue;
163
- }
164
- if (char === "\\") {
165
- current += char;
166
- escaped = true;
167
- continue;
168
- }
169
- if (quote) {
170
- current += char;
171
- if (char === quote)
172
- quote = "";
173
- continue;
174
- }
175
- if (char === '"' || char === "'") {
176
- quote = char;
177
- current += char;
178
- continue;
179
- }
180
- const next = command[i + 1];
181
- if ((char === "&" && next === "&") || (char === "|" && next === "|")) {
182
- parts.push(current);
183
- current = "";
184
- i += 1;
185
- continue;
186
- }
187
- if (char === ";" || char === "|" || char === "&" || char === "\n") {
188
- parts.push(current);
189
- current = "";
190
- continue;
191
- }
192
- current += char;
193
- }
194
- parts.push(current);
195
- return parts.map((part) => part.trim()).filter(Boolean);
196
- }
197
- function isReadOnlySegment(segment) {
198
- const tokens = segment.split(/\s+/).filter(Boolean);
199
- if (tokens.length === 0)
200
- return true;
201
- const first = tokens[0].toLowerCase();
202
- const second = (tokens[1] ?? "").toLowerCase();
203
- if (NON_READ_ONLY_LEADERS.has(first))
204
- return false;
205
- if (READ_ONLY_PREFIXES.has(first + " " + second))
206
- return true;
207
- if (READ_ONLY_COMMANDS.has(first))
208
- return true;
209
- return false;
210
- }
211
- export function isReadOnlyCommand(command) {
212
- const cmd = String(command ?? "").trim();
213
- if (!cmd)
214
- return false;
215
- if (hasWriteRedirection(cmd) || hasCommandSubstitution(cmd))
216
- return false;
217
- const segments = splitCommandSegments(cmd);
218
- if (segments.length === 0)
219
- return false;
220
- return segments.every(isReadOnlySegment);
221
- }
222
- export function isReadOnlyToolCall(call) {
223
- const tool = typeof call?.tool === "string" ? call.tool : "";
224
- if (tool === "shell")
225
- return isReadOnlyCommand(call.command);
226
- return READ_ONLY_TOOLS.has(tool);
227
- }
228
- export function loopExemptTools() {
229
- const raw = process.env["FASTCODE_LOOP_EXEMPT"] ?? "";
230
- return new Set(raw.split(",").map((entry) => entry.trim()).filter(Boolean));
231
- }
232
- export function isLoopExempt(tool) {
233
- return loopExemptTools().has(String(tool ?? ""));
234
- }
235
- function stableValue(value) {
236
- if (value === undefined)
237
- return "null";
238
- if (value === null || typeof value !== "object")
239
- return JSON.stringify(value);
240
- if (Array.isArray(value))
241
- return "[" + value.map((entry) => stableValue(entry)).join(",") + "]";
242
- const keys = Object.keys(value).sort().filter((key) => value[key] !== undefined);
243
- return "{" + keys.map((key) => JSON.stringify(key) + ":" + stableValue(value[key])).join(",") + "}";
244
- }
245
- export function stableStringify(value) {
246
- return stableValue(value);
247
- }
248
- function normalizeFingerprintPath(value, cwd) {
249
- let normalized = normalize(resolve(cwd, value));
250
- if (normalized.length > 1)
251
- normalized = normalized.replace(/[\\/]+$/, "");
252
- return normalized;
253
- }
254
- function fingerprintValue(key, value, cwd) {
255
- if (typeof value === "string" && (key === "path" || key === "from" || key === "to" || key === "cwd"))
256
- return normalizeFingerprintPath(value, cwd);
257
- if (key === "paths" && Array.isArray(value))
258
- return value.map((entry) => typeof entry === "string" ? normalizeFingerprintPath(entry, cwd) : entry);
259
- return value;
260
- }
261
- export function toolCallFingerprint(call, cwd = process.cwd()) {
262
- const tool = typeof call?.tool === "string" ? call.tool : "unknown";
263
- const args = {};
264
- for (const key of Object.keys(call ?? {}).sort()) {
265
- if (key === "tool" || key === "timeoutMs")
266
- continue;
267
- args[key] = fingerprintValue(key, call[key], cwd);
268
- }
269
- return tool + ":" + stableStringify(args);
270
- }
@@ -97,16 +97,13 @@ You can inspect and change the user's machine by emitting exactly one or more to
97
97
  Available tools:
98
98
  - shell: {"tool":"shell","command":"command to run"}
99
99
  - shell with timeout: {"tool":"shell","command":"npm test","timeoutMs":120000}
100
- - shell poll (long commands return a session id): {"tool":"shell","session_id":"sh_..."}
101
- Polling returns only new output; use waitMs to wait briefly for more.
102
100
  - pwd: {"tool":"pwd"}
103
101
  - read_file: {"tool":"read_file","path":"path/to/file"}
104
102
  - read_many: {"tool":"read_many","paths":["file1","file2"]}
105
103
  - write_file: {"tool":"write_file","path":"path/to/file","content":"full file contents"}
106
104
  - append_file: {"tool":"append_file","path":"path/to/file","content":"text to append"}
107
105
  - apply_patch: {"tool":"apply_patch","patch":"*** Begin Patch\\n*** Update File: path\\n@@\\n-old\\n+new\\n*** End Patch\\n"}
108
- - list_files: {"tool":"list_files","path":"optional/path","maxDepth":2,"detail":false}
109
- - read_file is capped (default 200KB); grep skips files over 1MB. .fastcodeignore is honored.
106
+ - list_files: {"tool":"list_files","path":"optional/path","maxDepth":2}
110
107
  - grep: {"tool":"grep","pattern":"text or regex","path":"optional/path"}
111
108
  - replace_in_file: {"tool":"replace_in_file","path":"path/to/file","find":"exact text","replace":"replacement"}
112
109
  - stat_path: {"tool":"stat_path","path":"path/to/file"}