terminal-ai-helper 2.2.0 → 2.3.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
- 2.2.0
1
+ 2.3.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminal-ai-helper",
3
- "version": "2.2.0",
3
+ "version": "2.3.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": {
@@ -562,6 +562,23 @@ _tai_line_init() {
562
562
  _TAI_ISEARCH=0
563
563
  region_highlight=()
564
564
  _tai_menu_close
565
+ # The prophecy. _TAI_SEQ answers "what did I run after this", and the fresh
566
+ # prompt is where that answer is taken — so the reset above is followed by
567
+ # the question, through the same _tai_update the redraw hook runs: it looks
568
+ # the empty buffer up against _TAI_LAST, judges the head's relative paths
569
+ # where the prompt stands, and paints the gray line the arrow accepts. The
570
+ # report: the sequence table held `sudo …` after the denied `systemctl …`
571
+ # and the prompt said nothing, because line-init only ever cleared, and no
572
+ # widget-triggered redraw fires before the first keystroke — by which time
573
+ # the buffer is no longer empty and the ordinary prefix lookup has replaced
574
+ # the question. Nothing here can answer before the first command has run:
575
+ # _TAI_LAST is set by precmd, so a shell that just opened queries an empty
576
+ # last command and paints nothing — the prophecy is learned, never a
577
+ # default. The query is cached, so the first real redraw of this line
578
+ # restores the answer instead of recomputing it, and every guard the redraw
579
+ # path applies (isearch stand-down, ours-only clearing, the paste rule) is
580
+ # this path's guard too, because it is the same call.
581
+ _tai_update
565
582
  }
566
583
 
567
584
  # The isearch flag the redraw hook stands down under, and the pair that
package/readme.md CHANGED
@@ -14,6 +14,9 @@ autocomplete that knows *you*:
14
14
  systemctl <→> restart nginx ← the hint, taken
15
15
  git <Tab> pull status ← your habits, ranked
16
16
  cd D<Tab> Desktop/ Documents/ Downloads/
17
+
18
+ systemctl stop cups.path
19
+ ❯ sudo systemctl stop cups.path ← what you did last time, already waiting
17
20
  ```
18
21
 
19
22
  ![tai in action — the hint, the ranked list, the filesystem, a typo
@@ -77,7 +80,11 @@ tai uninstall # remove everything tai added
77
80
  `Ctrl-F` takes it whole, `Alt-F` one word.
78
81
  2. **Press `Tab`.** On a first word your history ranks the lines it knows;
79
82
  `Enter` fills one in, a second `Enter` runs it.
80
- 3. **Run `tai web`.** A localhost dashboard of everything it learned, with a
83
+ 3. **Run a command and look at the next prompt.** When a command fails the way
84
+ it failed before, the empty line already shows, in grey, what you did about
85
+ it last time — `sudo …` after the denied `systemctl …`, `rm -r …` after the
86
+ refused `rm`. `→` takes it; typing replaces it.
87
+ 4. **Run `tai web`.** A localhost dashboard of everything it learned, with a
81
88
  try box that answers exactly what the prompt would.
82
89
 
83
90
  Every command you run teaches it — secrets, multi-line pastes and stray keys
@@ -88,7 +95,7 @@ machine. New commands show up within seconds; no restart, ever.
88
95
 
89
96
  | key | what it does |
90
97
  | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
91
- | `→` | take the hint at the end of the line, else move right |
98
+ | `→` | take the hint at the end of the line, else move right — on a fresh prompt the hint is what followed the command you just ran |
92
99
  | `Ctrl-F` | take the hint |
93
100
  | `Alt-F` / `Ctrl-Right` | take **one word** of the hint, leaving the rest to type (bash: `Ctrl-Right`) |
94
101
  | `Tab` | write what every candidate shares, then cycle files, folders and options; on a bare first word the learned lines come first, ranked like the dashboard |
@@ -137,6 +144,11 @@ memory, an array hit in microseconds.
137
144
  exists, here, on your PATH.
138
145
  - **A tool you have never run still gets an answer:** `tool --help`. Run it
139
146
  once and the real `--help` is learned in the background.
147
+ - **A fresh prompt carries what came next.** After a command, the empty line
148
+ shows in grey what your own history followed it with — ranked by how often
149
+ it followed, judged where the prompt stands like every suggestion. It is
150
+ learned or it is nothing: nothing built in, nothing before your first
151
+ command, and a follower whose path does not resolve here is not offered.
140
152
 
141
153
  - **If another plugin also draws hints, both work.** `→`, `Ctrl-F` and
142
154
  `Alt-F` take whatever is on screen, and tai never overwrites a hint it did
package/tai/index.py CHANGED
@@ -413,15 +413,19 @@ def build(max_commands: int = 20000) -> int:
413
413
 
414
414
  seq: dict[str, list[str]] = defaultdict(list)
415
415
  for prev, counter in eng.seq.items():
416
- # Sorted here, best first, because a shell now reads the order as the
417
- # ranking and not only as a tiebreak: the zsh menu shows a key's values in
418
- # the order they are stored, while _tai_best still re-ranks by
419
- # _TAI_SCORE to pick one. It used to add `count * 2.5` to a milli-score,
420
- # which is 0.08% of the value it was added to: the list looked
421
- # sequence-ranked and was really just base-score ranked with extra steps.
422
- values = [cmd for cmd, _ in sorted(
423
- ((cmd, scores.get(cmd, 0)) for cmd in counter),
424
- key=lambda x: (-x[1], x[0]))[:SEQ_CANDIDATE_CAP]]
416
+ # Ordered by how often the pair happened, then by how good the line is,
417
+ # best first — because the head of this list is the line a fresh prompt
418
+ # offers, and "what did I run after this" is answered by what followed
419
+ # *most*, not by the best-scoring line that ever did. The engine's own
420
+ # sequence factor is the pair's normalized count for the same reason;
421
+ # ordering the list by base score alone (an earlier shape, with the
422
+ # count discarded here) made the prophecy disagree with the engine on
423
+ # exactly the key the prophecy exists for: after `git add -A`, the
424
+ # history's `git commit -m …` lost the head to a bare `ls` that had
425
+ # merely followed once and scored well on its own.
426
+ values = [cmd for cmd, _, _ in sorted(
427
+ ((cmd, counter[cmd], scores.get(cmd, 0)) for cmd in counter),
428
+ key=lambda x: (-x[1], -x[2], x[0]))[:SEQ_CANDIDATE_CAP]]
425
429
  # A key whose every follower was stale has no answer left, and writing
426
430
  # it as an empty string puts `_TAI_SEQ[key] = ''` in the file. The zsh
427
431
  # plugin splits that into one empty line and the bash one reads it as an