copa-cli 0.9.0__tar.gz → 0.9.5__tar.gz

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 (38) hide show
  1. {copa_cli-0.9.0 → copa_cli-0.9.5}/PKG-INFO +11 -16
  2. {copa_cli-0.9.0 → copa_cli-0.9.5}/README.md +12 -17
  3. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/copa.zsh +67 -27
  4. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/PKG-INFO +11 -16
  5. {copa_cli-0.9.0 → copa_cli-0.9.5}/pyproject.toml +1 -1
  6. {copa_cli-0.9.0 → copa_cli-0.9.5}/LICENSE +0 -0
  7. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/__init__.py +0 -0
  8. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/__main__.py +0 -0
  9. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli.py +0 -0
  10. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli_common.py +0 -0
  11. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli_internal.py +0 -0
  12. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli_llm.py +0 -0
  13. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli_recipe.py +0 -0
  14. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/cli_share.py +0 -0
  15. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/config.py +0 -0
  16. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/db.py +0 -0
  17. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/evolve.py +0 -0
  18. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/fzf.py +0 -0
  19. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/history.py +0 -0
  20. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/llm.py +0 -0
  21. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/mcp_server.py +0 -0
  22. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/models.py +0 -0
  23. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/scanner.py +0 -0
  24. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/scoring.py +0 -0
  25. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa/sharing.py +0 -0
  26. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/SOURCES.txt +0 -0
  27. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/dependency_links.txt +0 -0
  28. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/entry_points.txt +0 -0
  29. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/requires.txt +0 -0
  30. {copa_cli-0.9.0 → copa_cli-0.9.5}/copa_cli.egg-info/top_level.txt +0 -0
  31. {copa_cli-0.9.0 → copa_cli-0.9.5}/setup.cfg +0 -0
  32. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_cli_and_sharing.py +0 -0
  33. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_db.py +0 -0
  34. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_fzf.py +0 -0
  35. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_modal.py +0 -0
  36. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_models.py +0 -0
  37. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_polish.py +0 -0
  38. {copa_cli-0.9.0 → copa_cli-0.9.5}/tests/test_scanner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copa-cli
3
- Version: 0.9.0
3
+ Version: 0.9.5
4
4
  Summary: Command Palette — smart command tracking, ranking, and sharing for your shell
5
5
  Author: Mark Stanford
6
6
  License-Expression: MIT
@@ -776,23 +776,18 @@ preview_size = "40%" # preview pane width (default: 40%)
776
776
 
777
777
  ![Composition](demos/08-composition.gif)
778
778
 
779
- Press **Ctrl+X** while a command is highlighted to open the compose submenu — a numbered menu of shell operators:
779
+ Press **Ctrl+X** while a command is highlighted to open the compose submenu — an fzf-powered operator picker with arrow keys, Tab, and highlighting:
780
780
 
781
- ```
782
- Compose: 1)| 2)&& 3)> 4)& 5)2>&1 6)2>/dev/null
783
- Select [1-6]:
784
- ```
785
-
786
- | # | Operator | Behavior | What happens |
787
- |---|---------------|------------|-------------------------------------------------------------|
788
- | 1 | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
789
- | 2 | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
790
- | 3 | `>` | continue | Appends `>` and re-opens fzf for the target |
791
- | 4 | `&` | close | Appends `&` and closes — run in background |
792
- | 5 | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
793
- | 6 | `2>/dev/null` | close | Appends `2>/dev/null` and closes — suppress stderr |
781
+ | Operator | Behavior | What happens |
782
+ |---------------|------------|-------------------------------------------------------------|
783
+ | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
784
+ | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
785
+ | `>` | continue | Appends `>` and re-opens fzf for the target |
786
+ | `&` | close | Appends `&` and closes — run in background |
787
+ | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
788
+ | `2>/dev/null` | close | Appends `2>/dev/null` and closes suppress stderr |
794
789
 
795
- "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt.
790
+ "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt. Press **Esc** to cancel and return to the main palette.
796
791
 
797
792
  When chaining, the prompt shows your accumulated command: `copa [git pull && ]>`.
798
793
 
@@ -746,23 +746,18 @@ preview_size = "40%" # preview pane width (default: 40%)
746
746
 
747
747
  ![Composition](demos/08-composition.gif)
748
748
 
749
- Press **Ctrl+X** while a command is highlighted to open the compose submenu — a numbered menu of shell operators:
750
-
751
- ```
752
- Compose: 1)| 2)&& 3)> 4)& 5)2>&1 6)2>/dev/null
753
- Select [1-6]:
754
- ```
755
-
756
- | # | Operator | Behavior | What happens |
757
- |---|---------------|------------|-------------------------------------------------------------|
758
- | 1 | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
759
- | 2 | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
760
- | 3 | `>` | continue | Appends `>` and re-opens fzf for the target |
761
- | 4 | `&` | close | Appends `&` and closes — run in background |
762
- | 5 | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
763
- | 6 | `2>/dev/null` | close | Appends `2>/dev/null` and closes — suppress stderr |
764
-
765
- "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt.
749
+ Press **Ctrl+X** while a command is highlighted to open the compose submenu — an fzf-powered operator picker with arrow keys, Tab, and highlighting:
750
+
751
+ | Operator | Behavior | What happens |
752
+ |---------------|------------|-------------------------------------------------------------|
753
+ | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
754
+ | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
755
+ | `>` | continue | Appends `>` and re-opens fzf for the target |
756
+ | `&` | close | Appends `&` and closes — run in background |
757
+ | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
758
+ | `2>/dev/null` | close | Appends `2>/dev/null` and closes suppress stderr |
759
+
760
+ "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt. Press **Esc** to cancel and return to the main palette.
766
761
 
767
762
  When chaining, the prompt shows your accumulated command: `copa [git pull && ]>`.
768
763
 
@@ -219,7 +219,7 @@ _copa_fzf_widget() {
219
219
  fi
220
220
 
221
221
  if [[ "$compose_action" == "COMPOSE" ]]; then
222
- # Show compose submenu
222
+ # Show compose submenu (fzf-based)
223
223
  local suffix
224
224
  suffix=$(_copa_compose_menu)
225
225
  if [[ -n "$suffix" ]]; then
@@ -231,8 +231,9 @@ _copa_fzf_widget() {
231
231
  LBUFFER="${accumulated}${cmd}${suffix}"
232
232
  fi
233
233
  else
234
- # Cancelled — put command in buffer as-is
235
- LBUFFER="${accumulated}${cmd}"
234
+ # Cancelled — return to the main fzf palette
235
+ accumulated="${accumulated}"
236
+ continue
236
237
  fi
237
238
  else
238
239
  LBUFFER="${accumulated}${cmd}"
@@ -248,33 +249,38 @@ _copa_fzf_widget() {
248
249
  zle reset-prompt
249
250
  }
250
251
 
251
- # --- Compose submenu: pick a shell operator ---
252
+ # --- Compose submenu: pick a shell operator via fzf ---
252
253
  _copa_compose_menu() {
253
254
  local choice
254
- local _copa_tty
255
- exec {_copa_tty}<>/dev/tty
256
-
257
- echo "" >&$_copa_tty
258
- echo " Compose operator:" >&$_copa_tty
259
- echo " 1: | pipe" >&$_copa_tty
260
- echo " 2: && chain" >&$_copa_tty
261
- echo " 3: > redirect" >&$_copa_tty
262
- echo " 4: & background" >&$_copa_tty
263
- echo " 5: 2>&1 merge stderr" >&$_copa_tty
264
- echo " 6: 2>/dev/null suppress stderr" >&$_copa_tty
265
- echo -n " Choice (1-6, q=cancel): " >&$_copa_tty
266
- read -u $_copa_tty choice
267
-
268
- exec {_copa_tty}<&-
255
+ choice=$(printf '%s\n' \
256
+ '| pipe → re-opens fzf' \
257
+ '&& chain → re-opens fzf' \
258
+ '> redirect → re-opens fzf' \
259
+ '& background' \
260
+ '2>&1 merge stderr' \
261
+ '2>/dev/null suppress stderr' \
262
+ | fzf \
263
+ --height 10 \
264
+ --layout reverse \
265
+ --prompt 'compose> ' \
266
+ --header 'Select operator · Tab/↑↓:navigate · Enter:select · Esc:cancel' \
267
+ --no-info \
268
+ --no-sort \
269
+ --pointer '▶' \
270
+ --color 'pointer:yellow' \
271
+ )
269
272
 
270
- case "$choice" in
271
- 1) echo " | " ;;
272
- 2) echo " && " ;;
273
- 3) echo " > " ;;
274
- 4) echo " &" ;;
275
- 5) echo " 2>&1" ;;
276
- 6) echo " 2>/dev/null" ;;
277
- *) echo "" ;;
273
+ [[ -z "$choice" ]] && return
274
+
275
+ # Extract operator (first whitespace-delimited token)
276
+ local op="${choice%% *}"
277
+ case "$op" in
278
+ '|') echo " | " ;;
279
+ '&&') echo " && " ;;
280
+ '>') echo " > " ;;
281
+ '&') echo " &" ;;
282
+ '2>&1') echo " 2>&1" ;;
283
+ '2>/dev/null') echo " 2>/dev/null" ;;
278
284
  esac
279
285
  }
280
286
 
@@ -458,10 +464,14 @@ fi # end _COPA_COMPLETION_MODE != 'never'
458
464
  # Shows grey suggestion text after the cursor as you type.
459
465
  # Controlled by _COPA_SUGGEST_ENABLED (set via copa _fzf-config).
460
466
  if [[ "$_COPA_SUGGEST_ENABLED" == 'true' ]]; then
467
+ zmodload zsh/datetime 2>/dev/null # provides EPOCHREALTIME for debouncing
461
468
 
462
469
  typeset -g _COPA_SUGGESTION=""
463
470
  typeset -g _COPA_SUGGEST_LATCHED=0 # 1 = suppressed (backspace latch)
464
471
  typeset -g _COPA_SUGGEST_PENDING="" # full suggestion passed to completion system
472
+ typeset -g _COPA_SUGGEST_PASTING=0 # 1 = inside a bracketed paste
473
+ typeset -g _COPA_SUGGEST_LAST_FETCH=0 # epoch ms of last fetch
474
+ typeset -gi _COPA_SUGGEST_DEBOUNCE_MS=80 # min ms between fetches
465
475
 
466
476
  # _copa_suggest_clear is always defined (used by _copa_fzf_widget)
467
477
  _copa_suggest_clear() {
@@ -476,9 +486,27 @@ _copa_suggest_fetch() {
476
486
  _COPA_SUGGEST_PENDING=""
477
487
  POSTDISPLAY=""
478
488
  region_highlight=()
489
+ (( _COPA_SUGGEST_PASTING )) && return # skip during paste
479
490
  (( _COPA_SUGGEST_LATCHED )) && return # suppressed by backspace latch
480
491
  (( ${#BUFFER} < _COPA_SUGGEST_MIN_LENGTH )) && return
481
492
  (( CURSOR != ${#BUFFER} )) && return # skip if cursor not at end
493
+
494
+ # Debounce: skip if last fetch was too recent (avoids subprocess flood on fast typing)
495
+ local now_ms
496
+ if [[ -n "$EPOCHREALTIME" ]]; then
497
+ # EPOCHREALTIME is e.g. "1774041695.803544" — extract seconds and first 3 decimals
498
+ local secs="${EPOCHREALTIME%%.*}"
499
+ local frac="${EPOCHREALTIME#*.}"
500
+ frac="${frac:0:3}" # first 3 digits = milliseconds
501
+ now_ms=$(( secs * 1000 + ${frac:-0} ))
502
+ else
503
+ now_ms=$(( EPOCHSECONDS * 1000 ))
504
+ fi
505
+ if (( now_ms - _COPA_SUGGEST_LAST_FETCH < _COPA_SUGGEST_DEBOUNCE_MS )); then
506
+ return
507
+ fi
508
+ _COPA_SUGGEST_LAST_FETCH=$now_ms
509
+
482
510
  local result
483
511
  local _suggest_args=("$BUFFER")
484
512
  [[ "$_COPA_SUGGEST_DIR_AWARE" == 'true' ]] && _suggest_args+=(--cwd "$PWD")
@@ -495,6 +523,18 @@ _copa_suggest_fetch() {
495
523
 
496
524
  # --- Widget wrappers ---
497
525
 
526
+ # Bracketed paste: suppress suggestions during paste, fetch once at end.
527
+ # Terminals send ESC[200~ before paste and ESC[201~ after.
528
+ _copa_suggest_bracketed_paste() {
529
+ _COPA_SUGGEST_PASTING=1
530
+ _copa_suggest_clear
531
+ zle .bracketed-paste
532
+ _COPA_SUGGEST_PASTING=0
533
+ _COPA_SUGGEST_LATCHED=0
534
+ _copa_suggest_fetch
535
+ }
536
+ zle -N bracketed-paste _copa_suggest_bracketed_paste
537
+
498
538
  # self-insert: type a character, unlatch, then fetch suggestion
499
539
  _copa_suggest_self_insert() {
500
540
  _COPA_SUGGEST_LATCHED=0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: copa-cli
3
- Version: 0.9.0
3
+ Version: 0.9.5
4
4
  Summary: Command Palette — smart command tracking, ranking, and sharing for your shell
5
5
  Author: Mark Stanford
6
6
  License-Expression: MIT
@@ -776,23 +776,18 @@ preview_size = "40%" # preview pane width (default: 40%)
776
776
 
777
777
  ![Composition](demos/08-composition.gif)
778
778
 
779
- Press **Ctrl+X** while a command is highlighted to open the compose submenu — a numbered menu of shell operators:
779
+ Press **Ctrl+X** while a command is highlighted to open the compose submenu — an fzf-powered operator picker with arrow keys, Tab, and highlighting:
780
780
 
781
- ```
782
- Compose: 1)| 2)&& 3)> 4)& 5)2>&1 6)2>/dev/null
783
- Select [1-6]:
784
- ```
785
-
786
- | # | Operator | Behavior | What happens |
787
- |---|---------------|------------|-------------------------------------------------------------|
788
- | 1 | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
789
- | 2 | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
790
- | 3 | `>` | continue | Appends `>` and re-opens fzf for the target |
791
- | 4 | `&` | close | Appends `&` and closes — run in background |
792
- | 5 | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
793
- | 6 | `2>/dev/null` | close | Appends `2>/dev/null` and closes — suppress stderr |
781
+ | Operator | Behavior | What happens |
782
+ |---------------|------------|-------------------------------------------------------------|
783
+ | `\|` | continue | Appends `\|` and re-opens fzf to select the next command |
784
+ | `&&` | continue | Appends `&&` and re-opens fzf to chain another command |
785
+ | `>` | continue | Appends `>` and re-opens fzf for the target |
786
+ | `&` | close | Appends `&` and closes — run in background |
787
+ | `2>&1` | close | Appends `2>&1` and closes — merge stderr |
788
+ | `2>/dev/null` | close | Appends `2>/dev/null` and closes suppress stderr |
794
789
 
795
- "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt.
790
+ "Continue" operators re-open fzf so you can build multi-command pipelines. "Close" operators place the final command in your prompt. Press **Esc** to cancel and return to the main palette.
796
791
 
797
792
  When chaining, the prompt shows your accumulated command: `copa [git pull && ]>`.
798
793
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "copa-cli"
7
- version = "0.9.0"
7
+ version = "0.9.5"
8
8
  description = "Command Palette — smart command tracking, ranking, and sharing for your shell"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes