thincoder 0.8.6 → 0.8.7

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/tui/index.mjs +22 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thincoder",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "Thin coding agent - zero dependencies, no build step, Node.js native. Sharp code, zero bloat.",
5
5
  "keywords": [
6
6
  "ai",
package/src/tui/index.mjs CHANGED
@@ -97,8 +97,9 @@ export async function startTUI(agent, opts = {}) {
97
97
  let pasteAccum = ""
98
98
 
99
99
  process.stdin.on("data", (chunk) => {
100
- let text = mousePending + utf8Decoder.decode(chunk, { stream: true })
101
- mousePending = ""
100
+ try {
101
+ let text = mousePending + utf8Decoder.decode(chunk, { stream: true })
102
+ mousePending = ""
102
103
 
103
104
  // Bracketed paste: terminal wraps pasted text in \x1b[200~ ... \x1b[201~
104
105
  // Insert pasted content directly into state.input to avoid slow char-by-char keypress render
@@ -169,6 +170,9 @@ export async function startTUI(agent, opts = {}) {
169
170
  render()
170
171
  }
171
172
  if (text) keyStream.write(text)
173
+ } catch (e) {
174
+ pushLine(`[input-error] ${e.message || e}`, C.error)
175
+ }
172
176
  })
173
177
 
174
178
  let cleanedUp = false
@@ -235,7 +239,8 @@ export async function startTUI(agent, opts = {}) {
235
239
  }
236
240
 
237
241
  function render() {
238
- // Side effects: reset scroll + update ctxCache + clamp overlay scroll
242
+ try {
243
+ // Side effects: reset scroll + update ctxCache + clamp overlay scroll
239
244
  // (renderFrame is pure, side effects concentrated here)
240
245
  const dims = { cols: process.stdout.columns || 80, rows: process.stdout.rows || 24 }
241
246
  const layout = computeLayout(state, dims)
@@ -279,9 +284,14 @@ export async function startTUI(agent, opts = {}) {
279
284
  process.stdout.write(`\x1b[${cursorRow};${cursorCol}H${ansi.showCursor}`)
280
285
  }
281
286
  }
287
+ } catch (e) {
288
+ // Don't let a render error crash the TUI
289
+ }
282
290
  }
283
291
 
284
- process.stdout.on("resize", render)
292
+ process.stdout.on("resize", () => {
293
+ try { render() } catch { /* resize error — ignore */ }
294
+ })
285
295
 
286
296
  // ---------------------------------------------------------- Submit
287
297
 
@@ -386,7 +396,14 @@ export async function startTUI(agent, opts = {}) {
386
396
  wizardChooseProvider, wizardSubmitText, cancelWizard, wizardProviderItems,
387
397
  renderWizard, pushLine, cleanup,
388
398
  })
389
- keyStream.on("keypress", onKeypress)
399
+ keyStream.on("keypress", (str, key) => {
400
+ try {
401
+ onKeypress(str, key)
402
+ } catch (e) {
403
+ pushLine(`[input-error] ${e.message || e}`, C.error)
404
+ render()
405
+ }
406
+ })
390
407
 
391
408
  // ---------------------------------------------------------- Startup screen + background indexing
392
409