shortcutxl 0.3.66 → 0.3.68
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/BINARY-INVENTORY.json +9 -9
- package/CHANGELOG.md +3 -3
- package/agent-docs/README.md +19 -0
- package/agent-docs/docs/keybindings.md +84 -78
- package/dist/ai/types.d.ts +1 -0
- package/dist/ai/utils/validation.js +6 -2
- package/dist/ai/validation.d.ts +1 -0
- package/dist/ai/validation.js +6 -2
- package/dist/app/background/tool-summaries.js +2 -1
- package/dist/app/prompts/com-api.js +7 -1
- package/dist/app/prompts/spreadjs-api-reference.json +19 -1
- package/dist/app/providers/register-shortcut-provider.js +46 -1
- package/dist/app/providers/shortcut-llm-proxy-client.d.ts +2 -0
- package/dist/app/providers/shortcut-llm-proxy-client.js +15 -3
- package/dist/app/session/model-manager.js +2 -2
- package/dist/app/session/session-models.d.ts +4 -0
- package/dist/app/session/session-models.js +25 -0
- package/dist/app/tools/execute-tool.d.ts +5 -0
- package/dist/app/tools/execute-tool.js +25 -11
- package/dist/app/tools/llm-analysis.js +2 -1
- package/dist/app/tools/take-screenshot.js +2 -1
- package/dist/cli.js +4989 -4193
- package/dist/contracts/host-tool.d.ts +1 -0
- package/dist/contracts/host-tool.js +14 -0
- package/dist/core/prompts/agent-guidelines.d.ts +1 -1
- package/dist/core/prompts/agent-guidelines.js +32 -12
- package/dist/embedded-agent/anthropic-messages-transport.js +24 -0
- package/dist/embedded-agent/compose.js +14 -9
- package/dist/embedded-agent/host-tools/execute-code/allowed-functions.json +13 -1
- package/dist/embedded-agent/host-tools/execute-code/contract.d.ts +1 -1
- package/dist/embedded-agent/host-tools/execute-code/contract.js +34 -6
- package/dist/embedded-agent/host-tools/execute-code/syntax-repair.d.ts +2 -0
- package/dist/embedded-agent/host-tools/execute-code/syntax-repair.js +59 -0
- package/dist/embedded-agent/host-tools/execute-tool/contract.d.ts +2 -1
- package/dist/embedded-agent/host-tools/execute-tool/contract.js +31 -9
- package/dist/embedded-agent/host-tools/execute-tool/index.d.ts +1 -1
- package/dist/embedded-agent/host-tools/execute-tool/index.js +1 -1
- package/dist/embedded-agent/host-tools/get-tool-info/contract.js +27 -16
- package/dist/embedded-agent/host-tools/task/agents/clone.js +1 -1
- package/dist/embedded-agent/host-tools/task/contract.js +4 -4
- package/dist/embedded-agent/model-registry.d.ts +0 -1
- package/dist/embedded-agent/model-registry.js +3 -3
- package/dist/embedded-agent/prompt/build.js +1 -1
- package/dist/embedded-agent/prompt/uploads.d.ts +0 -16
- package/dist/embedded-agent/prompt/uploads.js +0 -8
- package/dist/main.js +3 -1
- package/dist/model-ids.d.ts +4 -0
- package/dist/model-ids.js +6 -1
- package/dist/shell/components/index.d.ts +1 -1
- package/dist/shell/components/index.js +1 -1
- package/dist/shell/components/interactive-shell-layout.d.ts +23 -0
- package/dist/shell/components/interactive-shell-layout.js +33 -1
- package/dist/shell/components/line-selection-scroll-container.js +3 -1
- package/dist/shell/components/primitives/footer.d.ts +9 -1
- package/dist/shell/components/primitives/footer.js +33 -11
- package/dist/shell/components/primitives/index.d.ts +1 -1
- package/dist/shell/components/primitives/index.js +1 -1
- package/dist/shell/components/primitives/keybinding-hints.d.ts +18 -5
- package/dist/shell/components/primitives/keybinding-hints.js +46 -12
- package/dist/shell/components/selectors/model-selector.js +2 -23
- package/dist/shell/index.d.ts +2 -2
- package/dist/shell/index.js +2 -2
- package/dist/shell/interactive/editor-defaults.d.ts +5 -0
- package/dist/shell/interactive/editor-defaults.js +5 -0
- package/dist/shell/interactive/interactive-mode.d.ts +17 -2
- package/dist/shell/interactive/interactive-mode.js +150 -15
- package/dist/shell/interactive/prompt-history-wiring.d.ts +12 -0
- package/dist/shell/interactive/prompt-history-wiring.js +45 -0
- package/dist/shell/keybindings.d.ts +18 -5
- package/dist/shell/keybindings.js +68 -20
- package/dist/shell/presentation/slash-command-rendering.js +3 -11
- package/dist/shell/prompt-history-store.d.ts +39 -0
- package/dist/shell/prompt-history-store.js +154 -0
- package/dist/tui/components/editor.d.ts +20 -1
- package/dist/tui/components/editor.js +264 -10
- package/dist/tui/editor-component.d.ts +16 -1
- package/dist/tui/index.d.ts +1 -0
- package/dist/tui/index.js +1 -0
- package/dist/tui/keybindings.d.ts +5 -1
- package/dist/tui/keybindings.js +9 -3
- package/dist/tui/keys.d.ts +16 -13
- package/dist/tui/keys.js +8 -6
- package/dist/utils/structured-clone-safe.js +33 -7
- package/package.json +52 -53
- package/user-docs/dist/shortcutxl-docs.pdf +0 -0
- package/xll/ShortcutXL.xll +0 -0
- package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/pip-26.1.2.dist-info/RECORD +3 -3
- package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
- package/xll/python/Scripts/httpx.exe +0 -0
- package/xll/python/Scripts/idna.exe +0 -0
- package/xll/python/Scripts/pip.exe +0 -0
- package/xll/python/Scripts/pip3.13.exe +0 -0
- package/xll/python/Scripts/pip3.exe +0 -0
- package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
- package/xll/python/Scripts/pywin32_testall.exe +0 -0
package/BINARY-INVENTORY.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-07-
|
|
3
|
+
"generatedAt": "2026-07-07T16:51:48.477Z",
|
|
4
4
|
"package": "shortcutxl",
|
|
5
5
|
"binaryExtensions": [
|
|
6
6
|
".dll",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
{
|
|
13
13
|
"path": "xll/ShortcutXL.xll",
|
|
14
|
-
"sha256": "
|
|
14
|
+
"sha256": "cfa2fd09be91611de19c4783e7cf811e12de681c5ac4992b7581e6193802d6b5",
|
|
15
15
|
"source": "ShortcutXL native XLL build",
|
|
16
16
|
"version": "package",
|
|
17
17
|
"builtBy": "shortcut",
|
|
@@ -523,7 +523,7 @@
|
|
|
523
523
|
},
|
|
524
524
|
{
|
|
525
525
|
"path": "xll/python/Scripts/httpx.exe",
|
|
526
|
-
"sha256": "
|
|
526
|
+
"sha256": "513600b1071b099e3cd29c6822e6b7e426e56b39516250024232eb800d3a39a9",
|
|
527
527
|
"source": "httpx console launcher installed into embedded Python",
|
|
528
528
|
"version": "see packaged httpx distribution",
|
|
529
529
|
"builtBy": "third-party",
|
|
@@ -531,7 +531,7 @@
|
|
|
531
531
|
},
|
|
532
532
|
{
|
|
533
533
|
"path": "xll/python/Scripts/idna.exe",
|
|
534
|
-
"sha256": "
|
|
534
|
+
"sha256": "b0523c05ff7312a8c3be28567369c1c70d8ab8c76185b2c54b6b74a268475257",
|
|
535
535
|
"source": "Python package console launcher installed into embedded Python",
|
|
536
536
|
"version": "see owning Python package metadata in site-packages",
|
|
537
537
|
"builtBy": "third-party",
|
|
@@ -539,7 +539,7 @@
|
|
|
539
539
|
},
|
|
540
540
|
{
|
|
541
541
|
"path": "xll/python/Scripts/pip.exe",
|
|
542
|
-
"sha256": "
|
|
542
|
+
"sha256": "0d4a9f4b4fe84443b91e90e05a45017fbcd2a6e26ccd86719c1d73aac5ec3279",
|
|
543
543
|
"source": "pip console launcher installed into embedded Python",
|
|
544
544
|
"version": "see packaged pip distribution",
|
|
545
545
|
"builtBy": "third-party",
|
|
@@ -547,7 +547,7 @@
|
|
|
547
547
|
},
|
|
548
548
|
{
|
|
549
549
|
"path": "xll/python/Scripts/pip3.13.exe",
|
|
550
|
-
"sha256": "
|
|
550
|
+
"sha256": "0d4a9f4b4fe84443b91e90e05a45017fbcd2a6e26ccd86719c1d73aac5ec3279",
|
|
551
551
|
"source": "pip console launcher installed into embedded Python",
|
|
552
552
|
"version": "see packaged pip distribution",
|
|
553
553
|
"builtBy": "third-party",
|
|
@@ -555,7 +555,7 @@
|
|
|
555
555
|
},
|
|
556
556
|
{
|
|
557
557
|
"path": "xll/python/Scripts/pip3.exe",
|
|
558
|
-
"sha256": "
|
|
558
|
+
"sha256": "0d4a9f4b4fe84443b91e90e05a45017fbcd2a6e26ccd86719c1d73aac5ec3279",
|
|
559
559
|
"source": "pip console launcher installed into embedded Python",
|
|
560
560
|
"version": "see packaged pip distribution",
|
|
561
561
|
"builtBy": "third-party",
|
|
@@ -563,7 +563,7 @@
|
|
|
563
563
|
},
|
|
564
564
|
{
|
|
565
565
|
"path": "xll/python/Scripts/pywin32_postinstall.exe",
|
|
566
|
-
"sha256": "
|
|
566
|
+
"sha256": "d12dacb337e27c293f084cf871043c010d6e17ebcea54fa5b33b90172246413d",
|
|
567
567
|
"source": "Python package console launcher installed into embedded Python",
|
|
568
568
|
"version": "see owning Python package metadata in site-packages",
|
|
569
569
|
"builtBy": "third-party",
|
|
@@ -571,7 +571,7 @@
|
|
|
571
571
|
},
|
|
572
572
|
{
|
|
573
573
|
"path": "xll/python/Scripts/pywin32_testall.exe",
|
|
574
|
-
"sha256": "
|
|
574
|
+
"sha256": "91433e91bc8ba60593d601cf5e182d31a20aaed423e729f2238ae63467b0a5be",
|
|
575
575
|
"source": "Python package console launcher installed into embedded Python",
|
|
576
576
|
"version": "see owning Python package metadata in site-packages",
|
|
577
577
|
"builtBy": "third-party",
|
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.3.
|
|
3
|
+
## [0.3.68]
|
|
4
4
|
|
|
5
|
-
- **
|
|
6
|
-
- **
|
|
5
|
+
- **Model availability fix** - Introducing GLM 5.2 and Pivot models for eligible individual CLI accounts, not teams plans.
|
|
6
|
+
- **Persistent prompt history** — Your prompt history now persists across CLI sessions and can be accessed by up/down arrows.
|
|
7
7
|
|
|
8
8
|
## [0.3.65]
|
|
9
9
|
|
package/agent-docs/README.md
CHANGED
|
@@ -315,6 +315,25 @@ shortcut config # Enable/disable package resources
|
|
|
315
315
|
| `--session-dir <dir>` | Custom session storage directory |
|
|
316
316
|
| `--no-session` | Ephemeral mode (don't save) |
|
|
317
317
|
|
|
318
|
+
### Permission Options
|
|
319
|
+
|
|
320
|
+
Shortcut has separate controls for runtime permissions and spreadsheet permissions. Use the flag that matches the permission boundary you want to bypass for a single session.
|
|
321
|
+
|
|
322
|
+
| Option | Description |
|
|
323
|
+
|--------|-------------|
|
|
324
|
+
| `--skip-runtime-permissions` | Bypass runtime filesystem and shell approval checks for this session |
|
|
325
|
+
| `--skip-spreadsheet-permissions` | Allow headless spreadsheet auto-approval for this session |
|
|
326
|
+
|
|
327
|
+
Runtime and spreadsheet approvals are separate. `--skip-runtime-permissions` affects runtime-owned filesystem and shell checks; it does not change spreadsheet approvals. `--skip-spreadsheet-permissions` affects headless spreadsheet approval only; it does not bypass runtime filesystem or shell checks.
|
|
328
|
+
|
|
329
|
+
Use both flags when a non-interactive run needs both runtime access and spreadsheet auto-approval:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
shortcut --skip-runtime-permissions --skip-spreadsheet-permissions -p "..."
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
In an interactive session, use `/permissions skip-runtime-permissions` to inspect or change the runtime bypass setting.
|
|
336
|
+
|
|
318
337
|
### Resource Options
|
|
319
338
|
|
|
320
339
|
| Option | Description |
|
|
@@ -4,7 +4,7 @@ All keyboard shortcuts can be customized via `~/.shortcut/agent/keybindings.json
|
|
|
4
4
|
|
|
5
5
|
## Key Format
|
|
6
6
|
|
|
7
|
-
`modifier+key` where modifiers are `ctrl`, `shift`, `alt` (combinable) and keys are:
|
|
7
|
+
`modifier+key` where modifiers are `ctrl`, `shift`, `alt`/`option`/`meta` (combinable) and keys are:
|
|
8
8
|
|
|
9
9
|
- **Letters:** `a-z`
|
|
10
10
|
- **Special:** `escape`, `esc`, `enter`, `return`, `tab`, `space`, `backspace`, `delete`, `insert`, `clear`, `home`, `end`, `pageUp`, `pageDown`, `up`, `down`, `left`, `right`
|
|
@@ -13,121 +13,127 @@ All keyboard shortcuts can be customized via `~/.shortcut/agent/keybindings.json
|
|
|
13
13
|
|
|
14
14
|
Modifier combinations: `ctrl+shift+x`, `alt+ctrl+x`, `ctrl+shift+alt+x`, etc.
|
|
15
15
|
|
|
16
|
+
On macOS, Shortcut displays the Alt/Meta modifier as `Option`. In config files, `alt`, `option`, and `meta` are accepted as aliases for the same terminal modifier, so `"option+p"` and `"alt+p"` behave the same when your terminal sends Option as Meta/Alt input.
|
|
17
|
+
|
|
16
18
|
## All Actions
|
|
17
19
|
|
|
18
20
|
### Cursor Movement
|
|
19
21
|
|
|
20
|
-
| Action
|
|
21
|
-
|
|
22
|
-
| `cursorUp`
|
|
23
|
-
| `cursorDown`
|
|
24
|
-
| `cursorLeft`
|
|
25
|
-
| `cursorRight`
|
|
26
|
-
| `cursorWordLeft`
|
|
27
|
-
| `cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right
|
|
28
|
-
| `cursorLineStart` | `home`, `ctrl+a`
|
|
29
|
-
| `cursorLineEnd`
|
|
30
|
-
| `jumpForward`
|
|
31
|
-
| `jumpBackward`
|
|
32
|
-
| `pageUp`
|
|
33
|
-
| `pageDown`
|
|
22
|
+
| Action | Default | Description |
|
|
23
|
+
| ----------------- | ---------------------------------- | -------------------------- |
|
|
24
|
+
| `cursorUp` | `up` | Move cursor up |
|
|
25
|
+
| `cursorDown` | `down` | Move cursor down |
|
|
26
|
+
| `cursorLeft` | `left`, `ctrl+b` | Move cursor left |
|
|
27
|
+
| `cursorRight` | `right`, `ctrl+f` | Move cursor right |
|
|
28
|
+
| `cursorWordLeft` | `alt+left`, `ctrl+left`, `alt+b` | Move cursor word left |
|
|
29
|
+
| `cursorWordRight` | `alt+right`, `ctrl+right`, `alt+f` | Move cursor word right |
|
|
30
|
+
| `cursorLineStart` | `home`, `ctrl+a` | Move to line start |
|
|
31
|
+
| `cursorLineEnd` | `end`, `ctrl+e` | Move to line end |
|
|
32
|
+
| `jumpForward` | `ctrl+]` | Jump forward to character |
|
|
33
|
+
| `jumpBackward` | `ctrl+alt+]` | Jump backward to character |
|
|
34
|
+
| `pageUp` | `pageUp` | Scroll up by page |
|
|
35
|
+
| `pageDown` | `pageDown` | Scroll down by page |
|
|
34
36
|
|
|
35
37
|
### Deletion
|
|
36
38
|
|
|
37
|
-
| Action
|
|
38
|
-
|
|
39
|
-
| `deleteCharBackward` | `backspace`
|
|
40
|
-
| `deleteCharForward`
|
|
41
|
-
| `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward
|
|
42
|
-
| `deleteWordForward`
|
|
43
|
-
| `deleteToLineStart`
|
|
44
|
-
| `deleteToLineEnd`
|
|
39
|
+
| Action | Default | Description |
|
|
40
|
+
| -------------------- | ------------------------- | ------------------------- |
|
|
41
|
+
| `deleteCharBackward` | `backspace` | Delete character backward |
|
|
42
|
+
| `deleteCharForward` | `delete`, `ctrl+d` | Delete character forward |
|
|
43
|
+
| `deleteWordBackward` | `ctrl+w`, `alt+backspace` | Delete word backward |
|
|
44
|
+
| `deleteWordForward` | `alt+d`, `alt+delete` | Delete word forward |
|
|
45
|
+
| `deleteToLineStart` | `ctrl+u` | Delete to line start |
|
|
46
|
+
| `deleteToLineEnd` | `ctrl+k` | Delete to line end |
|
|
45
47
|
|
|
46
48
|
### Text Input
|
|
47
49
|
|
|
48
|
-
| Action
|
|
49
|
-
|
|
50
|
-
| `newLine` | `shift+enter` | Insert new line
|
|
51
|
-
| `submit`
|
|
52
|
-
| `tab`
|
|
50
|
+
| Action | Default | Description |
|
|
51
|
+
| --------- | ------------- | ------------------ |
|
|
52
|
+
| `newLine` | `shift+enter` | Insert new line |
|
|
53
|
+
| `submit` | `enter` | Submit input |
|
|
54
|
+
| `tab` | `tab` | Tab / autocomplete |
|
|
53
55
|
|
|
54
56
|
### Kill Ring
|
|
55
57
|
|
|
56
|
-
| Action
|
|
57
|
-
|
|
58
|
-
| `yank`
|
|
59
|
-
| `yankPop` | `alt+y`
|
|
60
|
-
| `undo`
|
|
58
|
+
| Action | Default | Description |
|
|
59
|
+
| --------- | -------- | ------------------------------------- |
|
|
60
|
+
| `yank` | `ctrl+y` | Paste most recently deleted text |
|
|
61
|
+
| `yankPop` | `alt+y` | Cycle through deleted text after yank |
|
|
62
|
+
| `undo` | `ctrl+-` | Undo last edit |
|
|
61
63
|
|
|
62
64
|
### Clipboard
|
|
63
65
|
|
|
64
|
-
| Action
|
|
65
|
-
|
|
66
|
-
| `copy`
|
|
67
|
-
| `pasteImage` | `ctrl+v` | Paste image from clipboard |
|
|
66
|
+
| Action | Default | Description |
|
|
67
|
+
| ------------ | ----------------------------- | -------------------------- |
|
|
68
|
+
| `copy` | `ctrl+c` | Copy selection |
|
|
69
|
+
| `pasteImage` | `ctrl+v` (`alt+v` on Windows) | Paste image from clipboard |
|
|
68
70
|
|
|
69
71
|
### Application
|
|
70
72
|
|
|
71
|
-
| Action
|
|
72
|
-
|
|
73
|
-
| `interrupt`
|
|
74
|
-
| `clear`
|
|
75
|
-
| `exit`
|
|
76
|
-
| `suspend`
|
|
77
|
-
| `
|
|
73
|
+
| Action | Default | Description |
|
|
74
|
+
| ------------------------------- | ----------- | ------------------------------------------------ |
|
|
75
|
+
| `interrupt` | `escape` | Cancel / abort |
|
|
76
|
+
| `clear` | `ctrl+c` | Clear editor |
|
|
77
|
+
| `exit` | `ctrl+d` | Exit (when editor empty) |
|
|
78
|
+
| `suspend` | `ctrl+z` | Suspend to background |
|
|
79
|
+
| `toggleAutoApprove` | `shift+tab` | Toggle auto-approve |
|
|
80
|
+
| `toggleRuntimePermissionBypass` | `alt+r` | Toggle file/shell permission bypass |
|
|
81
|
+
| `toggleFastMode` | `alt+f` | Toggle fast mode |
|
|
82
|
+
| `externalEditor` | `ctrl+g` | Open in external editor (`$VISUAL` or `$EDITOR`) |
|
|
78
83
|
|
|
79
84
|
### Session
|
|
80
85
|
|
|
81
|
-
| Action
|
|
82
|
-
|
|
83
|
-
| `newSession` |
|
|
84
|
-
| `tree`
|
|
85
|
-
| `fork`
|
|
86
|
-
| `resume`
|
|
86
|
+
| Action | Default | Description |
|
|
87
|
+
| ------------ | -------- | -------------------------------------- |
|
|
88
|
+
| `newSession` | _(none)_ | Start a new session (`/new`) |
|
|
89
|
+
| `tree` | _(none)_ | Open session tree navigator (`/tree`) |
|
|
90
|
+
| `fork` | _(none)_ | Fork current session (`/fork`) |
|
|
91
|
+
| `resume` | _(none)_ | Open session resume picker (`/resume`) |
|
|
92
|
+
| `cycleMode` | `alt+m` | Cycle agent mode |
|
|
87
93
|
|
|
88
94
|
### Models & Thinking
|
|
89
95
|
|
|
90
|
-
| Action
|
|
91
|
-
|
|
92
|
-
| `selectModel`
|
|
93
|
-
| `cycleModelForward`
|
|
94
|
-
| `cycleModelBackward` | `shift+
|
|
95
|
-
| `cycleThinkingLevel` | `
|
|
96
|
+
| Action | Default | Description |
|
|
97
|
+
| -------------------- | ------------- | ----------------------- |
|
|
98
|
+
| `selectModel` | `ctrl+l` | Open model selector |
|
|
99
|
+
| `cycleModelForward` | `alt+p` | Cycle to next model |
|
|
100
|
+
| `cycleModelBackward` | `shift+alt+p` | Cycle to previous model |
|
|
101
|
+
| `cycleThinkingLevel` | `alt+t` | Cycle thinking level |
|
|
96
102
|
|
|
97
103
|
### Display
|
|
98
104
|
|
|
99
|
-
| Action
|
|
100
|
-
|
|
101
|
-
| `expandTools`
|
|
105
|
+
| Action | Default | Description |
|
|
106
|
+
| ---------------- | -------- | ------------------------------- |
|
|
107
|
+
| `expandTools` | `ctrl+o` | Collapse/expand tool output |
|
|
102
108
|
| `toggleThinking` | `ctrl+t` | Collapse/expand thinking blocks |
|
|
103
109
|
|
|
104
110
|
### Message Queue
|
|
105
111
|
|
|
106
|
-
| Action
|
|
107
|
-
|
|
108
|
-
| `followUp` | `alt+enter` | Queue follow-up message
|
|
109
|
-
| `dequeue`
|
|
112
|
+
| Action | Default | Description |
|
|
113
|
+
| ---------- | ----------- | --------------------------------- |
|
|
114
|
+
| `followUp` | `alt+enter` | Queue follow-up message |
|
|
115
|
+
| `dequeue` | `alt+up` | Restore queued messages to editor |
|
|
110
116
|
|
|
111
117
|
### Selection (Lists, Pickers)
|
|
112
118
|
|
|
113
|
-
| Action
|
|
114
|
-
|
|
115
|
-
| `selectUp`
|
|
116
|
-
| `selectDown`
|
|
117
|
-
| `selectPageUp`
|
|
118
|
-
| `selectPageDown` | `pageDown`
|
|
119
|
-
| `selectConfirm`
|
|
120
|
-
| `selectCancel`
|
|
119
|
+
| Action | Default | Description |
|
|
120
|
+
| ---------------- | ------------------ | ------------------- |
|
|
121
|
+
| `selectUp` | `up` | Move selection up |
|
|
122
|
+
| `selectDown` | `down` | Move selection down |
|
|
123
|
+
| `selectPageUp` | `pageUp` | Page up in list |
|
|
124
|
+
| `selectPageDown` | `pageDown` | Page down in list |
|
|
125
|
+
| `selectConfirm` | `enter` | Confirm selection |
|
|
126
|
+
| `selectCancel` | `escape`, `ctrl+c` | Cancel selection |
|
|
121
127
|
|
|
122
128
|
### Session Picker
|
|
123
129
|
|
|
124
|
-
| Action
|
|
125
|
-
|
|
126
|
-
| `toggleSessionPath`
|
|
127
|
-
| `toggleSessionSort`
|
|
128
|
-
| `toggleSessionNamedFilter` | `ctrl+n`
|
|
129
|
-
| `renameSession`
|
|
130
|
-
| `deleteSession`
|
|
130
|
+
| Action | Default | Description |
|
|
131
|
+
| -------------------------- | ---------------- | --------------------------------- |
|
|
132
|
+
| `toggleSessionPath` | `ctrl+p` | Toggle path display |
|
|
133
|
+
| `toggleSessionSort` | `ctrl+s` | Toggle sort mode |
|
|
134
|
+
| `toggleSessionNamedFilter` | `ctrl+n` | Toggle named-only filter |
|
|
135
|
+
| `renameSession` | `ctrl+r` | Rename session |
|
|
136
|
+
| `deleteSession` | `ctrl+d` | Delete session |
|
|
131
137
|
| `deleteSessionNoninvasive` | `ctrl+backspace` | Delete session (when query empty) |
|
|
132
138
|
|
|
133
139
|
## Custom Configuration
|
package/dist/ai/types.d.ts
CHANGED
|
@@ -148,6 +148,7 @@ export interface Tool<TParameters extends TSchema = TSchema> {
|
|
|
148
148
|
name: string;
|
|
149
149
|
description: string;
|
|
150
150
|
parameters: TParameters;
|
|
151
|
+
normalizeArguments?: (args: unknown, toolCall: ToolCall) => unknown;
|
|
151
152
|
}
|
|
152
153
|
export interface Context {
|
|
153
154
|
systemPrompt?: string;
|
|
@@ -23,6 +23,10 @@ if (!isBrowserExtension) {
|
|
|
23
23
|
console.warn('AJV validation disabled due to CSP restrictions');
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
+
function getValidationArgs(tool, toolCall) {
|
|
27
|
+
const args = structuredClone(toolCall.arguments);
|
|
28
|
+
return tool.normalizeArguments ? tool.normalizeArguments(args, toolCall) : args;
|
|
29
|
+
}
|
|
26
30
|
/**
|
|
27
31
|
* Finds a tool by name and validates the tool call arguments against its TypeBox schema
|
|
28
32
|
* @param tools Array of tool definitions
|
|
@@ -49,12 +53,12 @@ export function validateToolArguments(tool, toolCall) {
|
|
|
49
53
|
if (!ajv || isBrowserExtension) {
|
|
50
54
|
// Trust the LLM's output without validation
|
|
51
55
|
// Browser extensions can't use AJV due to Manifest V3 CSP restrictions
|
|
52
|
-
return toolCall
|
|
56
|
+
return getValidationArgs(tool, toolCall);
|
|
53
57
|
}
|
|
54
58
|
// Compile the schema
|
|
55
59
|
const validate = ajv.compile(tool.parameters);
|
|
56
60
|
// Clone arguments so AJV can safely mutate for type coercion
|
|
57
|
-
const args =
|
|
61
|
+
const args = getValidationArgs(tool, toolCall);
|
|
58
62
|
// Validate the arguments (AJV mutates args in-place for type coercion)
|
|
59
63
|
if (validate(args)) {
|
|
60
64
|
return args;
|
package/dist/ai/validation.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { ToolCall } from './types.js';
|
|
|
3
3
|
interface ValidatedTool {
|
|
4
4
|
name: string;
|
|
5
5
|
parameters: TSchema;
|
|
6
|
+
normalizeArguments?: (args: unknown, toolCall: ToolCall) => unknown;
|
|
6
7
|
}
|
|
7
8
|
export declare function validateToolArguments<TArgs = unknown>(tool: ValidatedTool, toolCall: ToolCall): TArgs;
|
|
8
9
|
export {};
|
package/dist/ai/validation.js
CHANGED
|
@@ -20,12 +20,16 @@ if (!isBrowserExtension) {
|
|
|
20
20
|
console.warn('AJV validation disabled due to CSP restrictions');
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
function getValidationArgs(tool, toolCall) {
|
|
24
|
+
const args = structuredClone(toolCall.arguments);
|
|
25
|
+
return tool.normalizeArguments ? tool.normalizeArguments(args, toolCall) : args;
|
|
26
|
+
}
|
|
23
27
|
export function validateToolArguments(tool, toolCall) {
|
|
24
28
|
if (!ajv || isBrowserExtension) {
|
|
25
|
-
return toolCall
|
|
29
|
+
return getValidationArgs(tool, toolCall);
|
|
26
30
|
}
|
|
27
31
|
const validate = ajv.compile(tool.parameters);
|
|
28
|
-
const args =
|
|
32
|
+
const args = getValidationArgs(tool, toolCall);
|
|
29
33
|
if (validate(args)) {
|
|
30
34
|
return args;
|
|
31
35
|
}
|
|
@@ -127,7 +127,13 @@ export function getExcelComApiGuidelines(filterTag) {
|
|
|
127
127
|
===========================
|
|
128
128
|
## Shortcut Wrapper API
|
|
129
129
|
===========================
|
|
130
|
-
Workbook, Worksheet, and helpers are pre-injected in execute_code (no import needed)
|
|
130
|
+
Workbook, Worksheet, and helpers are pre-injected in execute_code (no import needed).
|
|
131
|
+
|
|
132
|
+
### ALWAYS start a task like this (app is already injected — do NOT import win32com or Dispatch Excel):
|
|
133
|
+
names = [wb.Name for wb in app.Workbooks] # find the target workbook name
|
|
134
|
+
wb = Workbook(app.Workbooks("YourFile.xlsx")) # wrap the COM object — NOT a filename string: Workbook("YourFile.xlsx") fails
|
|
135
|
+
print(wb.getSheetNames()) # use getSheetNames() — NOT wb.SheetNames
|
|
136
|
+
ws = wb.getSheet("Sheet1") # use getSheet(name) — NOT wb.Worksheets(...)`;
|
|
131
137
|
const sections = [COM_GUIDELINES, header];
|
|
132
138
|
for (const [name, cls] of Object.entries(ref.interfaces)) {
|
|
133
139
|
sections.push(renderSection(name, cls, filterTag));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"functions": {
|
|
5
5
|
"getAPIInfo": {
|
|
6
6
|
"signature": "getAPIInfo(functionName: string): string;",
|
|
7
|
-
"docstring": "Retrieves extended API documentation for less common functions. Returns docstring, function signature, parameters, return types, and all parameter type definitions.\n\nMerging/unmerging cells: addSpanAt, removeSpanAt\nCopying: cutAndPasteRange (move/cut-paste within same workbook), copySheet (full sheet duplication within same workbook)\nSheet dimensions: setTotalRowCount, setTotalColumnCount, expandSheetToFit\n - CRITICAL: SpreadJS initializes sheets with 10K rows and 100 columns. Writing to cells beyond these limits will SILENTLY FAIL unless you expand first!\n - Example: sheet.expandSheetToFit(\"A60000\"); sheet.setCell(\"A60000\", \"data\");\nNamed ranges: getNamedRangeInfo, addNamedRange, removeNamedRange\n@example general.getAPIInfo(\"addSpanAt\");",
|
|
7
|
+
"docstring": "Retrieves extended API documentation for less common functions. Returns docstring, function signature, parameters, return types, and all parameter type definitions.\n\nMerging/unmerging cells: addSpanAt, removeSpanAt\nSizing (all in px coordinates): setColumnWidthAt, setRowHeightAt, autoFitColumnsAt\nCopying: cutAndPasteRange (move/cut-paste within same workbook), copySheet (full sheet duplication within same workbook)\nSheet dimensions: setTotalRowCount, setTotalColumnCount, expandSheetToFit\n - CRITICAL: SpreadJS initializes sheets with 10K rows and 100 columns. Writing to cells beyond these limits will SILENTLY FAIL unless you expand first!\n - Example: sheet.expandSheetToFit(\"A60000\"); sheet.setCell(\"A60000\", \"data\");\nNamed ranges: getNamedRangeInfo, addNamedRange, removeNamedRange\n@example general.getAPIInfo(\"addSpanAt\");",
|
|
8
8
|
"usedTypes": [],
|
|
9
9
|
"tags": ["action", "ask"]
|
|
10
10
|
},
|
|
@@ -221,6 +221,12 @@
|
|
|
221
221
|
"usedTypes": [],
|
|
222
222
|
"tags": ["action", "ask"]
|
|
223
223
|
},
|
|
224
|
+
"autoFitColumnsAt": {
|
|
225
|
+
"signature": "autoFitColumnsAt(columnRange: string): void;",
|
|
226
|
+
"docstring": "Auto-fit the columns specified by columnRange e.g. autoFitColumnsAt(\"A:G\");\n@example sheet.autoFitColumnsAt(\"A:G\");",
|
|
227
|
+
"usedTypes": [],
|
|
228
|
+
"tags": ["hidden", "approval"]
|
|
229
|
+
},
|
|
224
230
|
"clearFormatting": {
|
|
225
231
|
"signature": "clearFormatting(range: string, properties?: (keyof Style)[]): void;",
|
|
226
232
|
"docstring": "Clear formatting from a range of cells. Clears all formatting if no properties specified.\nPass specific Style keys to clear only those properties.",
|
|
@@ -245,12 +251,24 @@
|
|
|
245
251
|
"usedTypes": [],
|
|
246
252
|
"tags": ["action", "approval"]
|
|
247
253
|
},
|
|
254
|
+
"setColumnWidthAt": {
|
|
255
|
+
"signature": "setColumnWidthAt(columnLetter: string, width: number): void;",
|
|
256
|
+
"docstring": "Set explicit width for the given column in pixels. Default column width is 72px.\n@example setColumnWidthAt(\"A\", 100);",
|
|
257
|
+
"usedTypes": [],
|
|
258
|
+
"tags": ["action", "approval"]
|
|
259
|
+
},
|
|
248
260
|
"getDependentCells": {
|
|
249
261
|
"signature": "getDependentCells(address: string): string;",
|
|
250
262
|
"docstring": "Get all cells that depend on the given cell",
|
|
251
263
|
"usedTypes": [],
|
|
252
264
|
"tags": ["action", "ask"]
|
|
253
265
|
},
|
|
266
|
+
"setRowHeightAt": {
|
|
267
|
+
"signature": "setRowHeightAt(rowAddress: string, height: number): void;",
|
|
268
|
+
"docstring": "Set explicit height for the given row in pixels. Default row height is 21px.\n@example setRowHeightAt(\"1\", 100);",
|
|
269
|
+
"usedTypes": [],
|
|
270
|
+
"tags": ["hidden", "approval"]
|
|
271
|
+
},
|
|
254
272
|
"addSpanAt": {
|
|
255
273
|
"signature": "addSpanAt(address: string, rowCount: number, colCount: number): void;",
|
|
256
274
|
"docstring": "Merge a range starting from the cell at address (e.g., \"A1\")",
|
|
@@ -33,6 +33,50 @@ const BUILTIN_STREAM_BY_TRANSPORT = {
|
|
|
33
33
|
'openai-responses': streamSimpleOpenAIResponses,
|
|
34
34
|
'google-vertex': streamSimpleGoogleVertexGateway
|
|
35
35
|
};
|
|
36
|
+
function headerValue(value) {
|
|
37
|
+
const trimmed = value?.trim();
|
|
38
|
+
return trimmed ? trimmed : undefined;
|
|
39
|
+
}
|
|
40
|
+
function isMainAgentStreamOptions(options) {
|
|
41
|
+
if (!options)
|
|
42
|
+
return false;
|
|
43
|
+
return (typeof options.convertToLlm === 'function' ||
|
|
44
|
+
options.userMessageId !== undefined ||
|
|
45
|
+
options.agentMode !== undefined ||
|
|
46
|
+
options.initialFileId !== undefined ||
|
|
47
|
+
options.fileAttachmentIds !== undefined ||
|
|
48
|
+
options.interactionMode !== undefined ||
|
|
49
|
+
options.speed !== undefined);
|
|
50
|
+
}
|
|
51
|
+
function createShortcutApiV2AttributionHeaders(options) {
|
|
52
|
+
const attribution = options;
|
|
53
|
+
const headers = {
|
|
54
|
+
'X-Agent-Runtime': 'shortcutxl_cli'
|
|
55
|
+
};
|
|
56
|
+
const userMessageId = headerValue(attribution?.userMessageId);
|
|
57
|
+
if (userMessageId)
|
|
58
|
+
headers['X-Turn-Id'] = userMessageId;
|
|
59
|
+
const agentMode = headerValue(attribution?.agentMode);
|
|
60
|
+
if (agentMode)
|
|
61
|
+
headers['X-Agent-Mode'] = agentMode;
|
|
62
|
+
const interactionMode = headerValue(attribution?.interactionMode);
|
|
63
|
+
if (interactionMode)
|
|
64
|
+
headers['X-Interaction-Mode'] = interactionMode;
|
|
65
|
+
const llmOperation = headerValue(attribution?.llmOperation) ??
|
|
66
|
+
(isMainAgentStreamOptions(attribution) ? 'chat' : undefined);
|
|
67
|
+
if (llmOperation)
|
|
68
|
+
headers['X-LLM-Operation'] = llmOperation;
|
|
69
|
+
const initialFileId = headerValue(attribution?.initialFileId);
|
|
70
|
+
if (initialFileId)
|
|
71
|
+
headers['X-Initial-File-Id'] = initialFileId;
|
|
72
|
+
if (attribution?.fileAttachmentIds?.length) {
|
|
73
|
+
headers['X-File-Attachment-Ids'] = attribution.fileAttachmentIds.join(',');
|
|
74
|
+
}
|
|
75
|
+
if (attribution?.speed === 'fast' || attribution?.speed === 'standard') {
|
|
76
|
+
headers['X-Shortcut-Speed'] = attribution.speed;
|
|
77
|
+
}
|
|
78
|
+
return headers;
|
|
79
|
+
}
|
|
36
80
|
/**
|
|
37
81
|
* Dispatch a Shortcut model to its provider-native stream function, routed at
|
|
38
82
|
* the api-v2 gateway with Shortcut auth. `options.apiKey` is the Shortcut
|
|
@@ -53,7 +97,8 @@ export function createShortcutApiV2Dispatcher(getExtraHeaders) {
|
|
|
53
97
|
const shortcutToken = options?.apiKey ?? '';
|
|
54
98
|
const authHeaders = {
|
|
55
99
|
Authorization: `Bearer ${shortcutToken}`,
|
|
56
|
-
...getExtraHeaders()
|
|
100
|
+
...getExtraHeaders(),
|
|
101
|
+
...createShortcutApiV2AttributionHeaders(options)
|
|
57
102
|
};
|
|
58
103
|
// Present the model to the native stream function under its real transport,
|
|
59
104
|
// with the base URL shaped the way that transport's SDK expects (the OpenAI
|
|
@@ -14,6 +14,7 @@ export interface ShortcutLlmAttribution {
|
|
|
14
14
|
sessionId?: string;
|
|
15
15
|
userMessageId?: string;
|
|
16
16
|
}
|
|
17
|
+
export type ShortcutLlmProxyOperation = 'code_preview' | 'compaction' | 'file_naming' | 'formula_trace' | 'llm_analysis' | 'sandbox_llm' | 'screenshot' | 'sentiment_analysis' | 'subagent' | 'suggestions' | 'summarize';
|
|
17
18
|
/**
|
|
18
19
|
* A helper LLM request. `messages` uses the simplified role/content shape
|
|
19
20
|
* callers already build (`system`/`human`, string or OpenAI-style content
|
|
@@ -28,6 +29,7 @@ export interface ShortcutLlmProxyRequest {
|
|
|
28
29
|
max_tokens?: number;
|
|
29
30
|
max_output_tokens?: number;
|
|
30
31
|
speed?: 'fast' | 'standard';
|
|
32
|
+
llmOperation?: ShortcutLlmProxyOperation;
|
|
31
33
|
}
|
|
32
34
|
export interface ShortcutLlmMessage {
|
|
33
35
|
role: 'system' | 'human' | 'user' | 'ai' | 'assistant';
|
|
@@ -43,6 +43,8 @@ export function mapShortcutLlmProxyError(error) {
|
|
|
43
43
|
}
|
|
44
44
|
/** Parse an OpenAI-style data URI (`data:<mime>;base64,<data>`) into parts. */
|
|
45
45
|
function parseDataUri(url) {
|
|
46
|
+
// [\s\S]* matches everything (incl. newlines) without the `s` dotAll flag,
|
|
47
|
+
// which requires an es2018+ target; keeps this parser target-agnostic.
|
|
46
48
|
const match = /^data:([^;]+);base64,([\s\S]*)$/.exec(url);
|
|
47
49
|
if (!match)
|
|
48
50
|
return undefined;
|
|
@@ -108,6 +110,18 @@ function collectAssistantText(events) {
|
|
|
108
110
|
return text;
|
|
109
111
|
})();
|
|
110
112
|
}
|
|
113
|
+
function createShortcutLlmProxyHeaders(request, attribution) {
|
|
114
|
+
const headers = {};
|
|
115
|
+
if (attribution?.sessionId)
|
|
116
|
+
headers['X-Session-Id'] = attribution.sessionId;
|
|
117
|
+
if (attribution?.userMessageId)
|
|
118
|
+
headers['X-Turn-Id'] = attribution.userMessageId;
|
|
119
|
+
if (request.llmOperation)
|
|
120
|
+
headers['X-LLM-Operation'] = request.llmOperation;
|
|
121
|
+
if (request.speed)
|
|
122
|
+
headers['X-Shortcut-Speed'] = request.speed;
|
|
123
|
+
return Object.keys(headers).length > 0 ? headers : undefined;
|
|
124
|
+
}
|
|
111
125
|
/**
|
|
112
126
|
* Create a Shortcut helper LLM client backed by the model registry's native
|
|
113
127
|
* transport path (api-v2). All helper calls share the main agent's transport.
|
|
@@ -129,9 +143,7 @@ export function createShortcutLlmProxyClient(options) {
|
|
|
129
143
|
throw new ShortcutLlmProxyError('missing-transport', `No stream transport registered for model "${request.model}" (api ${model.api}).`);
|
|
130
144
|
}
|
|
131
145
|
const attribution = options.getAttribution?.();
|
|
132
|
-
const headers = attribution
|
|
133
|
-
? { 'X-Session-Id': attribution.sessionId }
|
|
134
|
-
: undefined;
|
|
146
|
+
const headers = createShortcutLlmProxyHeaders(request, attribution);
|
|
135
147
|
const stream = apiProvider.streamSimple(model, toContext(request), {
|
|
136
148
|
apiKey,
|
|
137
149
|
maxTokens: request.max_tokens ?? request.max_output_tokens,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Stable deps (agent, registries, managers) are constructor-injected.
|
|
7
7
|
* Part of the AgentSession extracted modules.
|
|
8
8
|
*/
|
|
9
|
-
import { clampThinkingLevel, computeNextModel, cycleThinkingLevel as computeNextThinkingLevel, getAvailableThinkingLevels } from './session-models.js';
|
|
9
|
+
import { clampThinkingLevel, computeNextModel, cycleThinkingLevel as computeNextThinkingLevel, filterInteractiveSelectableModels, getAvailableThinkingLevels } from './session-models.js';
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Manager
|
|
12
12
|
// ============================================================================
|
|
@@ -29,7 +29,7 @@ export class ModelManager {
|
|
|
29
29
|
}
|
|
30
30
|
/** Cycle to the next available model. Returns result or undefined if none available. */
|
|
31
31
|
async cycleModel(direction = 'forward') {
|
|
32
|
-
const available = await this._modelRegistry.getAvailable();
|
|
32
|
+
const available = filterInteractiveSelectableModels(await this._modelRegistry.getAvailable());
|
|
33
33
|
const next = computeNextModel(available, this._agent.state.model, direction);
|
|
34
34
|
if (!next)
|
|
35
35
|
return undefined;
|
|
@@ -32,6 +32,10 @@ export declare function clampThinkingLevel(level: ThinkingLevel, availableLevels
|
|
|
32
32
|
* @returns The next level, or undefined if model doesn't support thinking.
|
|
33
33
|
*/
|
|
34
34
|
export declare function cycleThinkingLevel(currentLevel: ThinkingLevel, model: Model<any> | undefined): ThinkingLevel | undefined;
|
|
35
|
+
/** True when a model should be shown by interactive model controls and hotkey cycling. */
|
|
36
|
+
export declare function isInteractiveSelectableModel(model: Model<any>): boolean;
|
|
37
|
+
/** Filter raw available models to the same curated set used by `/model`. */
|
|
38
|
+
export declare function filterInteractiveSelectableModels(models: Model<any>[]): Model<any>[];
|
|
35
39
|
/**
|
|
36
40
|
* Compute the next model in the cycle.
|
|
37
41
|
* Pure index math — does not mutate state.
|