terminal-ai-helper 1.3.6 → 2.0.0

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/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.6
1
+ 2.0.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-ai-helper",
3
- "version": "1.3.6",
3
+ "version": "2.0.0",
4
4
  "description": "The terminal that knows your next command Bash/Zsh suggestions that learn from your own history Offline and private with no account required",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,4 +36,4 @@
36
36
  "devDependencies": {
37
37
  "vitepress": "^1.6.3"
38
38
  }
39
- }
39
+ }
package/readme.md CHANGED
@@ -200,9 +200,10 @@ rc file.
200
200
 
201
201
  `tai update` stops rather than overwrite a copy you have edited yourself.
202
202
  `tai uninstall` removes the shell integration, the wrapper, the indexes, the
203
- SQLite history and the cached knowledge. The `~/.tai` folder stays — on an
204
- npm install, `npm rm -g terminal-ai-helper` removes the package itself.
205
- Restart the terminal afterwards.
203
+ SQLite history, the cached knowledge and the `~/.tai` checkout itself; a
204
+ folder that is not a tai checkout is named and left alone. On an npm install
205
+ it also runs `npm rm -g terminal-ai-helper` itself. Restart the terminal
206
+ afterwards.
206
207
 
207
208
  ## Why it stays fast
208
209
 
package/tai/cli.py CHANGED
@@ -505,6 +505,7 @@ def cmd_eval_jev(a) -> int:
505
505
 
506
506
  def cmd_uninstall(a) -> int:
507
507
  import shutil
508
+ import subprocess
508
509
  from pathlib import Path
509
510
 
510
511
  from tai.paths import data_dir
@@ -519,7 +520,17 @@ def cmd_uninstall(a) -> int:
519
520
  # BIN_DIR is the one that gets removed.
520
521
  wrapper = Path(os.environ.get("BIN_DIR") or home / ".local" / "bin") / "tai"
521
522
  removed = []
523
+ npm_door = False
522
524
  if wrapper.exists() or wrapper.is_symlink():
525
+ # The wrapper names the checkout it execs, and that name is the door:
526
+ # a wrapper pointing into node_modules means the package itself is
527
+ # still installed, and the uninstall is not done until npm has it
528
+ # back. Read before unlink; a wrapper that cannot be read still goes.
529
+ try:
530
+ npm_door = ("node_modules/terminal-ai-helper"
531
+ in wrapper.read_text(errors="replace"))
532
+ except OSError:
533
+ pass
523
534
  wrapper.unlink()
524
535
  removed.append(str(wrapper))
525
536
  if data.exists():
@@ -565,9 +576,47 @@ def cmd_uninstall(a) -> int:
565
576
  tmp.write_text(new, encoding="utf-8", errors="surrogateescape")
566
577
  os.replace(tmp, rc)
567
578
  removed.append(str(rc))
579
+ # The piped door clones the code itself to TAI_DIR (default ~/.tai), and
580
+ # leaving it behind would leave the program installed in every way but the
581
+ # wrapper — the same rule the rc blocks above are held to. What makes the
582
+ # directory tai's is its layout: cli.py and the installer inside it. A
583
+ # directory without that shape is not ours to delete, so it is named and
584
+ # kept. Last on purpose: this command usually runs from inside the checkout
585
+ # (the wrapper execs this very file), so removing it has to be the last
586
+ # thing the run does.
587
+ checkout = Path(os.environ.get("TAI_DIR") or home / ".tai")
588
+ left = None
589
+ if checkout.exists():
590
+ if ((checkout / "tai" / "cli.py").exists()
591
+ and (checkout / "install.sh").exists()):
592
+ shutil.rmtree(checkout)
593
+ removed.append(str(checkout))
594
+ else:
595
+ left = checkout
596
+ # The npm door's code is npm's to remove, and the running tree says the
597
+ # same thing the wrapper did — this process may itself be executing from
598
+ # the package npm owns. Last, for the same reason the checkout is: the
599
+ # tree this command runs from can be the thing being removed.
600
+ npm_note = ""
601
+ if npm_door or _install_method(_repo_dir()) == "npm":
602
+ npm = shutil.which("npm")
603
+ if npm:
604
+ done = subprocess.run([npm, "rm", "-g", "terminal-ai-helper"],
605
+ capture_output=True, text=True)
606
+ if done.returncode == 0:
607
+ removed.append("terminal-ai-helper (npm global package)")
608
+ else:
609
+ npm_note = done.stderr.strip()
610
+ else:
611
+ npm_note = ("npm is not on PATH — the package is removed with: "
612
+ "npm rm -g terminal-ai-helper")
568
613
  print("tai removed" if removed else "tai was not installed")
569
614
  for path in removed:
570
615
  print(f" removed {path}")
616
+ if left:
617
+ print(f" left {left} — not a tai checkout")
618
+ if npm_note:
619
+ print(f" {npm_note}")
571
620
  return 0
572
621
 
573
622