shortcutxl 0.2.2 → 0.2.3
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/dist/custom/agents/clone.js +1 -1
- package/dist/custom/agents/document-reader.js +1 -1
- package/dist/custom/prompts/action.js +18 -4
- package/dist/custom/prompts/api.js +12 -14
- package/dist/custom/tools/excel-exec.js +1 -1
- package/dist/custom/tools/task/render.js +9 -3
- package/package.json +1 -1
- package/skills/{excel-com-api → com-advanced-api}/SKILL.md +1 -1
- package/skills/pdf-extraction/SKILL.md +0 -32
- /package/skills/{excel-com-api → com-advanced-api}/excel-type-library.py +0 -0
- /package/skills/{excel-com-api → com-advanced-api}/office-type-library.py +0 -0
|
@@ -8,7 +8,7 @@ const NAME = 'clone';
|
|
|
8
8
|
const DESCRIPTION = `\
|
|
9
9
|
A full clone of the main agent with tools (read, bash, edit, write, grep, excel_exec, task).
|
|
10
10
|
Can spawn general and document_reader subagents but cannot spawn other clones.
|
|
11
|
-
|
|
11
|
+
Can parallelize the summoning of this agent for independent batches of tasks that are perfectly parallelizable.`;
|
|
12
12
|
const SYSTEM_PROMPT = buildActionPrompt();
|
|
13
13
|
export const cloneAgent = {
|
|
14
14
|
name: NAME,
|
|
@@ -25,7 +25,7 @@ WORKFLOW:
|
|
|
25
25
|
4. Always sanity-check and verify extractions — use both methods and compare when accuracy is critical.
|
|
26
26
|
|
|
27
27
|
PROGRAMMATIC EXTRACTION (bash): IMPORTANT -- pip install any packages you currently do not have
|
|
28
|
-
- camelot:
|
|
28
|
+
- camelot: always use this first, esp for tables. Returns pre-split DataFrame columns. Use flavor='stream' for borderless tables.
|
|
29
29
|
- pdftotext -layout: Cleanest column-aligned output (CLI tool).
|
|
30
30
|
- PyMuPDF (fitz): Fastest Python-native option. Use sort=True for layout-aware extraction.
|
|
31
31
|
- pdfplumber: Good table detection but loses internal spaces.
|
|
@@ -18,22 +18,36 @@ import { CODING_GUIDELINES, COMMUNICATION_GUIDELINES, DATA_FORMATTING_GUIDELINES
|
|
|
18
18
|
// Prompt sections — all static content lives here as module-level constants.
|
|
19
19
|
// The function at the bottom only resolves runtime paths and assembles them.
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
|
-
const CORE = `\
|
|
21
|
+
const CORE = () => `\
|
|
22
22
|
Your name is Shortcut, an expert financial spreadsheet assistant that lives on the user's computer with Excel superpowers
|
|
23
23
|
Deliver professional-grade results with precise calculations, consistent formatting, and proper validation for business professionals
|
|
24
|
+
Current date: ${new Date().toISOString().slice(0, 10)}. Use this as single source of truth for time, overriding pretrained knowledge. Verify recency with tools for time-sensitive facts.
|
|
25
|
+
|
|
26
|
+
General flow: execute code → verify → update todo list → iterate on feedback. Respond in Markdown, be brief
|
|
24
27
|
Avoid over-interpretation and don't be extra. Only make changes that are directly requested or clearly necessary
|
|
25
28
|
Keep solutions simple and focused. For example, don't add extra sheets, reformat untouched areas, or make "improvements" beyond what was asked
|
|
26
29
|
|
|
27
30
|
## Tools
|
|
28
31
|
excel_exec: use it for all Excel interactions
|
|
29
|
-
- an HTTP server at ${EXCEL_HTTP_URL} is run inside the Excel process.
|
|
32
|
+
- an HTTP server at ${EXCEL_HTTP_URL} is run inside the Excel process. Auto-reloads via the registry when Excel starts
|
|
30
33
|
- health check: curl ${EXCEL_HTTP_URL}/config
|
|
31
|
-
- runs Python embedded inside Excel's process — direct access to the COM API via app
|
|
32
34
|
|
|
33
35
|
bash: use it for everything else, including python
|
|
34
36
|
- runs a separate Python subprocess
|
|
35
37
|
- write python files in the modules directory to create UDFs (User-Defined Function). See your xll docs for more information
|
|
36
38
|
|
|
39
|
+
PDF Processing:
|
|
40
|
+
- You MUST ALWAYS use document readers to understand and extract data from PDFs, no matter if it is programmatic extraction of multimodel extraction.
|
|
41
|
+
- First understand the task, then parallelize document readers to optimize performance when tasks can be broken down into independent components. Always leave the real work to the document readers
|
|
42
|
+
- After calling document_readers, read the generated files.
|
|
43
|
+
- When writing extracted data to the workbook, add source reference notes to extracted numeric values and key textual values (see notes and comments section). Keep notes strictly in the parseable format — put extra commentary in adjacent cells.
|
|
44
|
+
|
|
45
|
+
Excel Processing:
|
|
46
|
+
- Only spawn subagents to read and explore workbooks that are too difficult to do single-threaded AND if user queries are vague or contain unknown unknowns
|
|
47
|
+
- For example, user queries that say "fix this" for >10 sheet workbooks, or multiple worksheets with 10+ sections, high referential dependencies, etc
|
|
48
|
+
- For everything else it is generally always faster and more accurate to do it yourself than via offloading to workbook readers
|
|
49
|
+
- Even if the workbook is insanely complex, a clear or directed user query does not require subagent orchestration to find relevant sections
|
|
50
|
+
|
|
37
51
|
## Debugging HTTP server health
|
|
38
52
|
- if excel_exec or health checks fail, check if Excel is currently running
|
|
39
53
|
- if Excel is not running, we need to run it -- ask the user if they want a specific file open or if you can just open a blank workbook
|
|
@@ -75,7 +89,7 @@ export function buildActionPrompt() {
|
|
|
75
89
|
const agentDocsDir = resolve(join(getPackageDir(), 'agent-docs'));
|
|
76
90
|
const installedMarker = getInstalledMarkerPath();
|
|
77
91
|
return [
|
|
78
|
-
CORE,
|
|
92
|
+
CORE(),
|
|
79
93
|
EXPLORATION_GUIDELINES,
|
|
80
94
|
DATA_FORMATTING_GUIDELINES,
|
|
81
95
|
NUMBER_FORMAT_REFERENCE,
|
|
@@ -22,25 +22,23 @@ Multiple agents may operate on the same Excel instance concurrently. Follow thes
|
|
|
22
22
|
- For new workbooks, we must skip the splash screen. To do this, create a workbook in the temp dir via openpyxl or use an existing one. Then open it via start
|
|
23
23
|
- Do NOT use /e or other command-line flags — Excel interprets them as file paths
|
|
24
24
|
- If the user references a file that isn't open, explore the filesystem to locate it, then open it
|
|
25
|
-
- For files that you are only reading from (attached workbooks, reference files): open them headlessly. This avoids cluttering the user's Excel with files they don't need to see or edit
|
|
26
25
|
|
|
27
|
-
### Workbook References — NEVER use
|
|
26
|
+
### Workbook References — NEVER use *ACTIVE* workbook, worksheet, etc
|
|
28
27
|
- At the start of a task, list workbooks to find the right name: [wb.Name for wb in app.Workbooks]
|
|
29
|
-
-
|
|
30
|
-
- NEVER use: app.ActiveWorkbook, app.ActiveSheet, app.ActiveCell, app.Selection
|
|
28
|
+
- NEVER use: app.ActiveWorkbook, app.ActiveSheet, app.ActiveCell, app.Selection, app.Sheets("Sheet1") (implicitly uses ActiveWorkbook)
|
|
31
29
|
- These are global mutable state — another agent or the user can change them between your lines of code
|
|
30
|
+
- Always reference workbooks / worksheets / ranges by name: app.Workbooks("MyFile.xlsx")
|
|
32
31
|
|
|
33
|
-
###
|
|
34
|
-
-
|
|
35
|
-
- NEVER use: app.Sheets("Sheet1") (implicitly uses ActiveWorkbook)
|
|
32
|
+
### After opening a workbook
|
|
33
|
+
- Get the used range per sheet to understand initial workbook context
|
|
36
34
|
|
|
37
|
-
###
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
### Attachments, File-transfers, and Read-Only Operations
|
|
36
|
+
- The general principle is to avoid cluttering the user's Excel with files they don't need to see or edit
|
|
37
|
+
- for small read operations, open workbooks one at a time via COM to read them
|
|
38
|
+
- for bulk read operations: use openpyxl / xlrd as opposed to opening them via COM
|
|
39
|
+
- for data transfers, avoid Sheet.Copy and Sheet.Move — they silently create new "BookX" workbooks instead of inserting into the target
|
|
40
|
+
- isntead, use range.Copy to copy data+formatting over. Also copy column widths/row heights manually if needed
|
|
41
|
+
- For reordering: Use a VBA macro via app.Run() since .Move() within the same workbook also breaks through the Python COM bridge
|
|
44
42
|
|
|
45
43
|
### Common Patterns
|
|
46
44
|
- Read a table to Python: ws.Range("A1:D100").Value — returns a tuple of tuples
|
|
@@ -42,7 +42,7 @@ function wrapCode(userCode) {
|
|
|
42
42
|
/** What the LLM sees — hides the context-manager wrapper. */
|
|
43
43
|
const VISIBLE_PREAMBLE = `from shortcut_xl import xl_app\napp = xl_app()\n`;
|
|
44
44
|
const TOOL_DESCRIPTION = `\
|
|
45
|
-
Execute Python code in Excel
|
|
45
|
+
Execute Python code in Excel.
|
|
46
46
|
The code runs in-process with access to the Excel COM API via app (an Excel.Application COM object, same API as VBA).
|
|
47
47
|
Stdout/stderr are captured. Use print() to return values.
|
|
48
48
|
|
|
@@ -216,10 +216,16 @@ const MAX_EXPANDED_TOOL_CALLS = 15;
|
|
|
216
216
|
export function renderTaskGroup(members, options, theme) {
|
|
217
217
|
const { expanded } = options;
|
|
218
218
|
const lines = [];
|
|
219
|
-
// Determine agent type from first member's args
|
|
219
|
+
// Determine agent type from first member's args.
|
|
220
|
+
// While args are still streaming, subagent_type may not yet be present —
|
|
221
|
+
// avoid defaulting to 'general' which would flash incorrectly.
|
|
220
222
|
const firstArgs = members[0]?.args;
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
+
const anyPartial = members.some((m) => m.isPartial);
|
|
224
|
+
const rawType = firstArgs?.subagent_type;
|
|
225
|
+
const agentType = rawType ?? (anyPartial ? undefined : 'general');
|
|
226
|
+
const agentLabel = agentType
|
|
227
|
+
? formatAgentGroupLabel(agentType, members.length)
|
|
228
|
+
: `${members.length} Agent${members.length > 1 ? 's' : ''}`;
|
|
223
229
|
// Header icon: all done or any error; no icon when still running
|
|
224
230
|
const allDone = members.every((m) => !m.isPartial);
|
|
225
231
|
const headerIcon = groupHeaderIcon(members, theme);
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: com-advanced-api
|
|
3
3
|
description: Excel COM object model reference for win32com/pywin32. Use when you need to look up Excel COM properties, methods, enums, or constants for automation via Python. Covers Application, Workbook, Worksheet, Range, Chart, PivotTable, Shape, formatting, and all xl* constants.
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pdf-extraction
|
|
3
|
-
description: Use when extracting data from PDFs. Covers programmatic extraction vs multimodal LLM approaches.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# PDF Data Extraction
|
|
7
|
-
|
|
8
|
-
## When to Use Programmatic Extraction
|
|
9
|
-
|
|
10
|
-
Use for **structured data with >500 data points** (tables, financial statements, transaction lists). Fast, cheap, accurate, deterministic.
|
|
11
|
-
|
|
12
|
-
## When to Use Multimodal LLMs
|
|
13
|
-
- **Scanned documents** - No machine-readable text layer
|
|
14
|
-
- **Complex layouts** - Multi-column, nested tables, mixed text/images
|
|
15
|
-
- **Charts and figures** - Visual data that can't be extracted programmatically
|
|
16
|
-
- **Verification** - Spot-check programmatic extraction results
|
|
17
|
-
- **Small extractions** - <500 data points where speed doesn't matter
|
|
18
|
-
|
|
19
|
-
## Programmatic Library Selection
|
|
20
|
-
|
|
21
|
-
| Library | Best For | Gotchas |
|
|
22
|
-
|---------|----------|---------|
|
|
23
|
-
| **camelot** | Tables with clear borders | `flavor='stream'` for borderless; requires ghostscript |
|
|
24
|
-
| **pdftotext -layout** | Column-aligned text (ideal for LLM input) | CLI only, no Python API for layout mode |
|
|
25
|
-
| **PyMuPDF (fitz)** | Speed, general extraction | Use `sort=True` for reading order; less accurate table detection |
|
|
26
|
-
| **pdfplumber** | Table detection | Loses internal spaces in text cells |
|
|
27
|
-
|
|
28
|
-
## Key Practices
|
|
29
|
-
|
|
30
|
-
1. **Use multiple methods and compare** - Run 2-3 extractors, compare row counts and spot-check values
|
|
31
|
-
2. **Sanity checks** - Verify nulls, empty values, column alignment after extraction
|
|
32
|
-
3. **Hybrid approach** - Programmatic for bulk structured data, LLM for edge cases and verification
|
|
File without changes
|
|
File without changes
|