thincoder 0.12.0 → 0.12.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.
package/README.md CHANGED
@@ -205,6 +205,9 @@ Code conventions: pure `.mjs`, no semicolons, no npm dependencies allowed (inclu
205
205
 
206
206
  ## Changelog
207
207
 
208
+ ### 0.12.1 (2026-07)
209
+ - **Fix: `/exit` screen artifacts** — `/exit` now uses synchronous `process.exit(0)` instead of the deferred cleanup callback, preventing the post-handler `render()` from redrawing the TUI over the cleaned terminal. Ctrl+C and `/exit` now produce identical clean exits.
210
+
208
211
  ### 0.12.0 (2026-07)
209
212
  - **Interactive slash command UX** — `/advisor`, `/think`, `/config`, `/mcp` now use persistent menu loops with live state feedback. Toggle, change settings, and see results without re-entering the command. Cursor position is remembered across menu cycles. `/plan` and `/auto` now show immediate local feedback (`❯ Plan: ON/OFF`).
210
213
  - **User-level AGENTS.md** — `~/.thincoder/AGENTS.md` is now loaded alongside the project-level `AGENTS.md`. User-level preferences (language, style, format) apply across all projects; project-level rules take priority.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thincoder",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
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/advisor.mjs CHANGED
@@ -541,6 +541,32 @@ export function resolveAdvisorProvider(agent) {
541
541
  return provider
542
542
  }
543
543
 
544
+ /**
545
+ * Whether every changed file across the review repos is documentation-only.
546
+ * Used to skip pointless code reviews for doc updates (README, docs/, LICENSE…).
547
+ */
548
+ function isDocOnlyChange(repos, cwd) {
549
+ const DOC_FILE = /(?:^|[/\\])(?:LICENSE|NOTICE|CHANGELOG|AUTHORS)(?:\.\w+)?$|\.(?:md|markdown|mdx|txt|rst|adoc)$/i
550
+ const targets = repos.length > 0 ? repos : [cwd]
551
+ let sawChanges = false
552
+ for (const repo of targets) {
553
+ let status = ""
554
+ try {
555
+ status = execFileSync("git", ["status", "--porcelain"], {
556
+ cwd: repo, encoding: "utf8", timeout: GIT_TIMEOUT, stdio: ["ignore", "pipe", "pipe"],
557
+ }).trim()
558
+ } catch { return false /* can't tell — let the advisor run */ }
559
+ if (!status) continue
560
+ sawChanges = true
561
+ for (const line of status.split("\n")) {
562
+ // porcelain: "XY path" or "XY old -> new" (rename)
563
+ const filePath = line.slice(3).split(" -> ").pop().replace(/^"|"$/g, "")
564
+ if (!DOC_FILE.test(filePath)) return false
565
+ }
566
+ }
567
+ return sawChanges
568
+ }
569
+
544
570
  export async function runAdvisorReview(agent, onOutput, signal) {
545
571
  const cfg = agent.config?.advisor
546
572
  if (!cfg?.enabled) return null
@@ -548,6 +574,12 @@ export async function runAdvisorReview(agent, onOutput, signal) {
548
574
  const repos = findReviewRepos(agent)
549
575
  if ((agent._touchedFiles ?? []).length === 0) return null
550
576
 
577
+ // Fast path: documentation-only changes need no code review — unless the project
578
+ // customized review criteria (.thincoder/advisor.md may genuinely care about docs).
579
+ if (!existsSync(join(agent.cwd, ADVISOR_MD_PATH)) && isDocOnlyChange(repos, agent.cwd)) {
580
+ return "No issues found — documentation-only changes, code review skipped."
581
+ }
582
+
551
583
  const provider = resolveAdvisorProvider(agent)
552
584
 
553
585
  // Set the advisor's cwd to the first repo (for tool context)
@@ -10,6 +10,7 @@ Review workflow:
10
10
  5. Produce your review table.
11
11
 
12
12
  Rules:
13
+ - First judge the task from the conversation background: if the changes are clearly non-code (documentation, comments, version bumps, config metadata) and cannot affect runtime behavior, reply immediately with the all-clear phrase — do NOT spend tool calls exploring.
13
14
  - Reply in the same language as the conversation background.
14
15
  - Respect the project's stated platform requirements — do not flag features as errors if they are valid under the project's target environment.
15
16
  - Output a Markdown table. This table becomes the sole basis for convergence in later rounds — be thorough.
@@ -1,5 +1,19 @@
1
- /** /exit command: exit TUI.
2
- * ctx: { exit } — exit is the cleanup + process.exit callback injected by index.mjs */
1
+ /** /exit command: exit TUI (same path as Ctrl+C).
2
+ * ctx: { agent, state } */
3
+ import { saveSession, archiveCurrent } from "../session.mjs"
4
+ import { closeAllMcp } from "../mcp.mjs"
5
+ import { ansi } from "./ansi.mjs"
6
+
3
7
  export async function handleExitCommand(ctx) {
4
- ctx.exit()
8
+ const { agent, state } = ctx
9
+ // Same cleanup sequence as Ctrl+C in key-handler.mjs
10
+ try {
11
+ archiveCurrent(agent.cwd)
12
+ saveSession(agent, state.lines)
13
+ } catch { /* save failure shouldn't block exit */ }
14
+ try { closeAllMcp(agent) } catch { /* exiting anyway */ }
15
+ process.stdin.setRawMode(false)
16
+ process.stdout.write(ansi.clearScreen + ansi.mouseOff + ansi.bracketedPasteOff + ansi.mainBuffer + ansi.showCursor + ansi.reset)
17
+ // Exit synchronously — prevents post-handler render() from redrawing the TUI
18
+ process.exit(0)
5
19
  }