shortcutxl 0.2.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/README.md +59 -0
- package/agent-docs/README.md +397 -0
- package/agent-docs/docs/compaction.md +390 -0
- package/agent-docs/docs/custom-provider.md +580 -0
- package/agent-docs/docs/development.md +69 -0
- package/agent-docs/docs/extensions.md +1971 -0
- package/agent-docs/docs/json.md +79 -0
- package/agent-docs/docs/keybindings.md +174 -0
- package/agent-docs/docs/models.md +293 -0
- package/agent-docs/docs/packages.md +209 -0
- package/agent-docs/docs/prompt-templates.md +67 -0
- package/agent-docs/docs/providers.md +186 -0
- package/agent-docs/docs/rpc.md +1317 -0
- package/agent-docs/docs/sdk.md +962 -0
- package/agent-docs/docs/session.md +412 -0
- package/agent-docs/docs/settings.md +223 -0
- package/agent-docs/docs/shell-aliases.md +13 -0
- package/agent-docs/docs/skills.md +231 -0
- package/agent-docs/docs/terminal-setup.md +70 -0
- package/agent-docs/docs/termux.md +127 -0
- package/agent-docs/docs/themes.md +295 -0
- package/agent-docs/docs/tree.md +219 -0
- package/agent-docs/docs/tui.md +887 -0
- package/agent-docs/docs/windows.md +17 -0
- package/agent-docs/examples/README.md +25 -0
- package/agent-docs/examples/extensions/README.md +205 -0
- package/agent-docs/examples/extensions/antigravity-image-gen.ts +447 -0
- package/agent-docs/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/agent-docs/examples/extensions/bash-spawn-hook.ts +30 -0
- package/agent-docs/examples/extensions/bookmark.ts +50 -0
- package/agent-docs/examples/extensions/built-in-tool-renderer.ts +256 -0
- package/agent-docs/examples/extensions/claude-rules.ts +86 -0
- package/agent-docs/examples/extensions/commands.ts +75 -0
- package/agent-docs/examples/extensions/confirm-destructive.ts +59 -0
- package/agent-docs/examples/extensions/custom-compaction.ts +126 -0
- package/agent-docs/examples/extensions/custom-footer.ts +63 -0
- package/agent-docs/examples/extensions/custom-header.ts +73 -0
- package/agent-docs/examples/extensions/custom-provider-anthropic/index.ts +660 -0
- package/agent-docs/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/agent-docs/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/agent-docs/examples/extensions/custom-provider-gitlab-duo/index.ts +362 -0
- package/agent-docs/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/agent-docs/examples/extensions/custom-provider-gitlab-duo/test.ts +88 -0
- package/agent-docs/examples/extensions/custom-provider-qwen-cli/index.ts +349 -0
- package/agent-docs/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
- package/agent-docs/examples/extensions/dirty-repo-guard.ts +56 -0
- package/agent-docs/examples/extensions/doom-overlay/README.md +46 -0
- package/agent-docs/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/agent-docs/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/agent-docs/examples/extensions/doom-overlay/doom-component.ts +133 -0
- package/agent-docs/examples/extensions/doom-overlay/doom-engine.ts +186 -0
- package/agent-docs/examples/extensions/doom-overlay/doom-keys.ts +108 -0
- package/agent-docs/examples/extensions/doom-overlay/index.ts +74 -0
- package/agent-docs/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/agent-docs/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/agent-docs/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/agent-docs/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/agent-docs/examples/extensions/dynamic-resources/index.ts +15 -0
- package/agent-docs/examples/extensions/dynamic-tools.ts +77 -0
- package/agent-docs/examples/extensions/event-bus.ts +43 -0
- package/agent-docs/examples/extensions/file-trigger.ts +41 -0
- package/agent-docs/examples/extensions/git-checkpoint.ts +53 -0
- package/agent-docs/examples/extensions/handoff.ts +155 -0
- package/agent-docs/examples/extensions/hello.ts +25 -0
- package/agent-docs/examples/extensions/inline-bash.ts +94 -0
- package/agent-docs/examples/extensions/input-transform.ts +43 -0
- package/agent-docs/examples/extensions/interactive-shell.ts +209 -0
- package/agent-docs/examples/extensions/mac-system-theme.ts +47 -0
- package/agent-docs/examples/extensions/message-renderer.ts +59 -0
- package/agent-docs/examples/extensions/minimal-mode.ts +430 -0
- package/agent-docs/examples/extensions/modal-editor.ts +90 -0
- package/agent-docs/examples/extensions/model-status.ts +31 -0
- package/agent-docs/examples/extensions/notify.ts +55 -0
- package/agent-docs/examples/extensions/overlay-qa-tests.ts +936 -0
- package/agent-docs/examples/extensions/overlay-test.ts +159 -0
- package/agent-docs/examples/extensions/permission-gate.ts +37 -0
- package/agent-docs/examples/extensions/pirate.ts +47 -0
- package/agent-docs/examples/extensions/plan-mode/README.md +65 -0
- package/agent-docs/examples/extensions/plan-mode/index.ts +363 -0
- package/agent-docs/examples/extensions/plan-mode/utils.ts +173 -0
- package/agent-docs/examples/extensions/preset.ts +418 -0
- package/agent-docs/examples/extensions/protected-paths.ts +30 -0
- package/agent-docs/examples/extensions/qna.ts +122 -0
- package/agent-docs/examples/extensions/question.ts +278 -0
- package/agent-docs/examples/extensions/questionnaire.ts +440 -0
- package/agent-docs/examples/extensions/rainbow-editor.ts +90 -0
- package/agent-docs/examples/extensions/reload-runtime.ts +37 -0
- package/agent-docs/examples/extensions/rpc-demo.ts +124 -0
- package/agent-docs/examples/extensions/sandbox/index.ts +324 -0
- package/agent-docs/examples/extensions/sandbox/package-lock.json +92 -0
- package/agent-docs/examples/extensions/sandbox/package.json +19 -0
- package/agent-docs/examples/extensions/send-user-message.ts +97 -0
- package/agent-docs/examples/extensions/session-name.ts +27 -0
- package/agent-docs/examples/extensions/shutdown-command.ts +69 -0
- package/agent-docs/examples/extensions/snake.ts +343 -0
- package/agent-docs/examples/extensions/space-invaders.ts +566 -0
- package/agent-docs/examples/extensions/ssh.ts +233 -0
- package/agent-docs/examples/extensions/status-line.ts +40 -0
- package/agent-docs/examples/extensions/subagent/README.md +172 -0
- package/agent-docs/examples/extensions/subagent/agents/planner.md +37 -0
- package/agent-docs/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/agent-docs/examples/extensions/subagent/agents/scout.md +50 -0
- package/agent-docs/examples/extensions/subagent/agents/worker.md +24 -0
- package/agent-docs/examples/extensions/subagent/agents.ts +130 -0
- package/agent-docs/examples/extensions/subagent/index.ts +1068 -0
- package/agent-docs/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/agent-docs/examples/extensions/subagent/prompts/implement.md +10 -0
- package/agent-docs/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/agent-docs/examples/extensions/summarize.ts +206 -0
- package/agent-docs/examples/extensions/system-prompt-header.ts +17 -0
- package/agent-docs/examples/extensions/timed-confirm.ts +72 -0
- package/agent-docs/examples/extensions/titlebar-spinner.ts +58 -0
- package/agent-docs/examples/extensions/todo.ts +314 -0
- package/agent-docs/examples/extensions/tool-override.ts +146 -0
- package/agent-docs/examples/extensions/tools.ts +145 -0
- package/agent-docs/examples/extensions/trigger-compact.ts +40 -0
- package/agent-docs/examples/extensions/truncated-tool.ts +194 -0
- package/agent-docs/examples/extensions/widget-placement.ts +17 -0
- package/agent-docs/examples/extensions/with-deps/index.ts +37 -0
- package/agent-docs/examples/extensions/with-deps/package-lock.json +31 -0
- package/agent-docs/examples/extensions/with-deps/package.json +22 -0
- package/agent-docs/examples/rpc-extension-ui.ts +654 -0
- package/agent-docs/examples/sdk/01-minimal.ts +22 -0
- package/agent-docs/examples/sdk/02-custom-model.ts +48 -0
- package/agent-docs/examples/sdk/03-custom-prompt.ts +55 -0
- package/agent-docs/examples/sdk/04-skills.ts +53 -0
- package/agent-docs/examples/sdk/05-tools.ts +56 -0
- package/agent-docs/examples/sdk/06-extensions.ts +88 -0
- package/agent-docs/examples/sdk/07-context-files.ts +40 -0
- package/agent-docs/examples/sdk/08-prompt-templates.ts +47 -0
- package/agent-docs/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/agent-docs/examples/sdk/10-settings.ts +54 -0
- package/agent-docs/examples/sdk/11-sessions.ts +48 -0
- package/agent-docs/examples/sdk/12-full-control.ts +82 -0
- package/agent-docs/examples/sdk/README.md +144 -0
- package/agent-docs/xll-skill.md +61 -0
- package/agent-docs/xll-spec.md +110 -0
- package/dist/cli/args.js +290 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/file-processor.js +79 -0
- package/dist/cli/list-models.js +92 -0
- package/dist/cli/package-commands.js +210 -0
- package/dist/cli/report-settings-errors.js +11 -0
- package/dist/cli/session-picker.js +34 -0
- package/dist/cli.js +19 -0
- package/dist/config.js +288 -0
- package/dist/core/abort.js +15 -0
- package/dist/core/agent-loop.js +352 -0
- package/dist/core/agent-session.js +2019 -0
- package/dist/core/agent.js +410 -0
- package/dist/core/auth-storage.js +456 -0
- package/dist/core/bash-executor.js +222 -0
- package/dist/core/compaction/branch-summarization.js +242 -0
- package/dist/core/compaction/compaction.js +610 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/utils.js +139 -0
- package/dist/core/defaults.js +6 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/exec.js +71 -0
- package/dist/core/export-html/ansi-to-html.js +256 -0
- package/dist/core/export-html/index.js +238 -0
- package/dist/core/export-html/session-view-model.js +342 -0
- package/dist/core/export-html/template.css +1110 -0
- package/dist/core/export-html/template.html +76 -0
- package/dist/core/export-html/template.js +1990 -0
- package/dist/core/export-html/tool-renderer.js +63 -0
- package/dist/core/export-html/vendor/highlight.min.js +7725 -0
- package/dist/core/export-html/vendor/marked.min.js +1803 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/loader.js +422 -0
- package/dist/core/extensions/runner.js +651 -0
- package/dist/core/extensions/types.js +35 -0
- package/dist/core/extensions/wrapper.js +102 -0
- package/dist/core/footer-data-provider.js +162 -0
- package/dist/core/index.js +9 -0
- package/dist/core/keybindings.js +153 -0
- package/dist/core/messages.js +133 -0
- package/dist/core/model-registry.js +539 -0
- package/dist/core/model-resolver.js +370 -0
- package/dist/core/package-manager.js +1485 -0
- package/dist/core/prompt-templates.js +253 -0
- package/dist/core/resolve-config-value.js +59 -0
- package/dist/core/resource-loader.js +700 -0
- package/dist/core/sdk.js +197 -0
- package/dist/core/session-bash.js +99 -0
- package/dist/core/session-compaction.js +165 -0
- package/dist/core/session-manager.js +1153 -0
- package/dist/core/session-models.js +99 -0
- package/dist/core/session-retry.js +155 -0
- package/dist/core/settings-manager.js +572 -0
- package/dist/core/skills.js +382 -0
- package/dist/core/slash-commands.js +31 -0
- package/dist/core/system-prompt.js +161 -0
- package/dist/core/theme.js +770 -0
- package/dist/core/timings.js +26 -0
- package/dist/core/tools/bash.js +258 -0
- package/dist/core/tools/edit-diff.js +245 -0
- package/dist/core/tools/edit.js +148 -0
- package/dist/core/tools/find.js +208 -0
- package/dist/core/tools/grep.js +246 -0
- package/dist/core/tools/index.js +67 -0
- package/dist/core/tools/ls.js +123 -0
- package/dist/core/tools/path-utils.js +81 -0
- package/dist/core/tools/read.js +160 -0
- package/dist/core/tools/truncate.js +70 -0
- package/dist/core/tools/write.js +82 -0
- package/dist/custom/agents/action.js +13 -0
- package/dist/custom/agents/document-reader.js +70 -0
- package/dist/custom/agents/general.js +26 -0
- package/dist/custom/agents/index.js +49 -0
- package/dist/custom/agents/installation.js +13 -0
- package/dist/custom/agents/types.js +7 -0
- package/dist/custom/auth/refresh-timer.js +33 -0
- package/dist/custom/auth/shortcut-oauth.js +145 -0
- package/dist/custom/constants.js +21 -0
- package/dist/custom/context/workbook-summary.js +73 -0
- package/dist/custom/credits/shortcut-credits.js +29 -0
- package/dist/custom/cron/cron-daemon-entry.js +18 -0
- package/dist/custom/cron/daemon-ipc.js +131 -0
- package/dist/custom/cron/daemon.js +224 -0
- package/dist/custom/cron/jobs.js +226 -0
- package/dist/custom/cron/run-log.js +51 -0
- package/dist/custom/cron/schedule.js +72 -0
- package/dist/custom/cron/status-line.js +98 -0
- package/dist/custom/cron/store.js +87 -0
- package/dist/custom/cron/types.js +8 -0
- package/dist/custom/dev/index.js +59 -0
- package/dist/custom/dev/trace-export.js +58 -0
- package/dist/custom/ensure-excel.js +63 -0
- package/dist/custom/excel-config.js +36 -0
- package/dist/custom/preflight.js +422 -0
- package/dist/custom/prompts/action.js +100 -0
- package/dist/custom/prompts/api.js +66 -0
- package/dist/custom/prompts/installation.js +124 -0
- package/dist/custom/prompts/shared.js +138 -0
- package/dist/custom/providers/llm-usage.js +42 -0
- package/dist/custom/providers/message-converter.js +74 -0
- package/dist/custom/providers/provider-ids.js +9 -0
- package/dist/custom/providers/register-openai-codex-provider.js +27 -0
- package/dist/custom/providers/register-shortcut-provider.js +52 -0
- package/dist/custom/providers/shortcut-invoke.js +117 -0
- package/dist/custom/providers/shortcut-stream.js +252 -0
- package/dist/custom/providers/sse-protocol.js +38 -0
- package/dist/custom/sync-xll.js +130 -0
- package/dist/custom/tools/cron.js +413 -0
- package/dist/custom/tools/excel-exec.js +167 -0
- package/dist/custom/tools/excel-range.js +50 -0
- package/dist/custom/tools/llm-analysis.js +265 -0
- package/dist/custom/tools/render-helpers.js +38 -0
- package/dist/custom/tools/switch-mode.js +94 -0
- package/dist/custom/tools/task/agents.js +6 -0
- package/dist/custom/tools/task/index.js +8 -0
- package/dist/custom/tools/task/render.js +348 -0
- package/dist/custom/tools/task/subprocess.js +320 -0
- package/dist/custom/tools/task/task.js +205 -0
- package/dist/custom/tools/todo-list.js +195 -0
- package/dist/custom/tracing/session-upload.js +93 -0
- package/dist/index.js +45 -0
- package/dist/main.js +613 -0
- package/dist/migrations.js +265 -0
- package/dist/modes/index.js +8 -0
- package/dist/modes/interactive/components/armin.js +337 -0
- package/dist/modes/interactive/components/assistant-message.js +94 -0
- package/dist/modes/interactive/components/bash-execution.js +171 -0
- package/dist/modes/interactive/components/bordered-loader.js +51 -0
- package/dist/modes/interactive/components/branch-summary-message.js +45 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +46 -0
- package/dist/modes/interactive/components/config-selector.js +488 -0
- package/dist/modes/interactive/components/countdown-timer.js +33 -0
- package/dist/modes/interactive/components/custom-editor.js +93 -0
- package/dist/modes/interactive/components/custom-message.js +81 -0
- package/dist/modes/interactive/components/daxnuts.js +140 -0
- package/dist/modes/interactive/components/diff.js +133 -0
- package/dist/modes/interactive/components/dynamic-border.js +21 -0
- package/dist/modes/interactive/components/extension-editor.js +105 -0
- package/dist/modes/interactive/components/extension-input.js +61 -0
- package/dist/modes/interactive/components/extension-selector.js +78 -0
- package/dist/modes/interactive/components/footer.js +309 -0
- package/dist/modes/interactive/components/index.js +33 -0
- package/dist/modes/interactive/components/keybinding-hints.js +61 -0
- package/dist/modes/interactive/components/layout.js +64 -0
- package/dist/modes/interactive/components/login-dialog.js +148 -0
- package/dist/modes/interactive/components/model-selector.js +237 -0
- package/dist/modes/interactive/components/oauth-selector.js +111 -0
- package/dist/modes/interactive/components/session-selector-search.js +157 -0
- package/dist/modes/interactive/components/session-selector.js +860 -0
- package/dist/modes/interactive/components/settings-selector.js +123 -0
- package/dist/modes/interactive/components/show-images-selector.js +35 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +48 -0
- package/dist/modes/interactive/components/theme-selector.js +47 -0
- package/dist/modes/interactive/components/thinking-selector.js +47 -0
- package/dist/modes/interactive/components/tool-execution.js +789 -0
- package/dist/modes/interactive/components/tool-group.js +106 -0
- package/dist/modes/interactive/components/tree-selector.js +962 -0
- package/dist/modes/interactive/components/user-message-selector.js +115 -0
- package/dist/modes/interactive/components/user-message.js +48 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/file-attachments.js +135 -0
- package/dist/modes/interactive/interactive-mode.js +3775 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +85 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.js +177 -0
- package/dist/modes/print-mode.js +101 -0
- package/dist/modes/rpc/rpc-client.js +387 -0
- package/dist/modes/rpc/rpc-mode.js +509 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/subagent-entry.js +145 -0
- package/dist/tool-names.js +34 -0
- package/dist/tui/autocomplete.js +596 -0
- package/dist/tui/components/box.js +104 -0
- package/dist/tui/components/cancellable-loader.js +35 -0
- package/dist/tui/components/editor.js +1679 -0
- package/dist/tui/components/image.js +69 -0
- package/dist/tui/components/input.js +433 -0
- package/dist/tui/components/loader.js +49 -0
- package/dist/tui/components/markdown.js +629 -0
- package/dist/tui/components/select-list.js +152 -0
- package/dist/tui/components/settings-list.js +185 -0
- package/dist/tui/components/spacer.js +23 -0
- package/dist/tui/components/text.js +89 -0
- package/dist/tui/components/truncated-text.js +51 -0
- package/dist/tui/editor-component.js +2 -0
- package/dist/tui/fuzzy.js +107 -0
- package/dist/tui/get-east-asian-width/index.js +32 -0
- package/dist/tui/get-east-asian-width/lookup.js +404 -0
- package/dist/tui/index.js +32 -0
- package/dist/tui/keybindings.js +114 -0
- package/dist/tui/keys.js +959 -0
- package/dist/tui/kill-ring.js +44 -0
- package/dist/tui/stdin-buffer.js +317 -0
- package/dist/tui/terminal-image.js +288 -0
- package/dist/tui/terminal.js +249 -0
- package/dist/tui/tui/autocomplete.js +596 -0
- package/dist/tui/tui/components/box.js +106 -0
- package/dist/tui/tui/components/cancellable-loader.js +35 -0
- package/dist/tui/tui/components/editor.js +1679 -0
- package/dist/tui/tui/components/image.js +69 -0
- package/dist/tui/tui/components/input.js +433 -0
- package/dist/tui/tui/components/loader.js +49 -0
- package/dist/tui/tui/components/markdown.js +629 -0
- package/dist/tui/tui/components/select-list.js +152 -0
- package/dist/tui/tui/components/settings-list.js +185 -0
- package/dist/tui/tui/components/spacer.js +23 -0
- package/dist/tui/tui/components/text.js +91 -0
- package/dist/tui/tui/components/truncated-text.js +51 -0
- package/dist/tui/tui/editor-component.js +2 -0
- package/dist/tui/tui/fuzzy.js +107 -0
- package/dist/tui/tui/get-east-asian-width/index.js +32 -0
- package/dist/tui/tui/get-east-asian-width/lookup.js +404 -0
- package/dist/tui/tui/index.js +32 -0
- package/dist/tui/tui/keybindings.js +114 -0
- package/dist/tui/tui/keys.js +959 -0
- package/dist/tui/tui/kill-ring.js +44 -0
- package/dist/tui/tui/stdin-buffer.js +317 -0
- package/dist/tui/tui/terminal-image.js +288 -0
- package/dist/tui/tui/terminal.js +249 -0
- package/dist/tui/tui/tui.js +955 -0
- package/dist/tui/tui/undo-stack.js +25 -0
- package/dist/tui/tui/utils.js +800 -0
- package/dist/tui/tui.js +955 -0
- package/dist/tui/undo-stack.js +25 -0
- package/dist/tui/utils.js +800 -0
- package/dist/utils/changelog.js +87 -0
- package/dist/utils/clipboard-image.js +164 -0
- package/dist/utils/clipboard-native.js +14 -0
- package/dist/utils/clipboard.js +67 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/git.js +166 -0
- package/dist/utils/image-convert.js +35 -0
- package/dist/utils/image-resize.js +183 -0
- package/dist/utils/mime.js +26 -0
- package/dist/utils/photon.js +121 -0
- package/dist/utils/shell.js +217 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/tools-manager.js +259 -0
- package/package.json +78 -0
- package/skills/excel-com-api/SKILL.md +74 -0
- package/skills/excel-com-api/excel-type-library.py +27767 -0
- package/skills/excel-com-api/office-type-library.py +10867 -0
- package/skills/integrations/SKILL.md +138 -0
- package/skills/integrations/alphasense.md +457 -0
- package/skills/integrations/bloomberg.md +803 -0
- package/skills/integrations/calcbench.md +315 -0
- package/skills/integrations/capiq.md +848 -0
- package/skills/integrations/dynamics-365-finance.md +354 -0
- package/skills/integrations/earnings_transcripts.md +387 -0
- package/skills/integrations/factset.md +758 -0
- package/skills/integrations/ice-fixed-income.md +344 -0
- package/skills/integrations/moodys-analytics.md +313 -0
- package/skills/integrations/morningstar.md +433 -0
- package/skills/integrations/nasdaq-data-link.md +249 -0
- package/skills/integrations/pitchbook.md +413 -0
- package/skills/integrations/preqin.md +422 -0
- package/skills/integrations/quickbooks.md +289 -0
- package/skills/integrations/quickfs.md +314 -0
- package/skills/integrations/refinitiv.md +473 -0
- package/skills/integrations/sage-intacct.md +401 -0
- package/skills/integrations/visible-alpha.md +320 -0
- package/skills/integrations/xero.md +393 -0
- package/skills/integrations/ycharts.md +306 -0
- package/skills/pdf-creation/SKILL.md +93 -0
- package/skills/pdf-extraction/SKILL.md +32 -0
- package/skills/powerpoint-creation/SKILL.md +110 -0
- package/skills/sec-edgar/SKILL.md +127 -0
- package/skills/sec-edgar/sec_to_pdf.py +109 -0
- package/xll/ShortcutXL.xll +0 -0
- package/xll/modules/debug_render.py +272 -0
- package/xll/modules/gameboy.py +241 -0
- package/xll/modules/pong.py +188 -0
- package/xll/modules/shortcut_xl/__init__.py +18 -0
- package/xll/modules/shortcut_xl/_categorize.py +200 -0
- package/xll/modules/shortcut_xl/_com.py +108 -0
- package/xll/modules/shortcut_xl/_format.py +252 -0
- package/xll/modules/shortcut_xl/_log.py +12 -0
- package/xll/modules/shortcut_xl/_managed.py +116 -0
- package/xll/modules/shortcut_xl/_registry.py +44 -0
- package/xll/modules/shortcut_xl/_threading.py +161 -0
- package/xll/modules/shortcut_xl/_tracking.py +283 -0
- package/xll/modules/stocks.py +100 -0
- package/xll/python3.dll +0 -0
- package/xll/python312.dll +0 -0
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC mode: Headless operation with JSON stdin/stdout protocol.
|
|
3
|
+
*
|
|
4
|
+
* Used for embedding the agent in other applications.
|
|
5
|
+
* Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.
|
|
6
|
+
*
|
|
7
|
+
* Protocol:
|
|
8
|
+
* - Commands: JSON objects with `type` field, optional `id` for correlation
|
|
9
|
+
* - Responses: JSON objects with `type: "response"`, `command`, `success`, and optional `data`/`error`
|
|
10
|
+
* - Events: AgentSessionEvent objects streamed as they occur
|
|
11
|
+
* - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response
|
|
12
|
+
*/
|
|
13
|
+
import * as crypto from 'node:crypto';
|
|
14
|
+
import * as readline from 'readline';
|
|
15
|
+
import { theme } from '../../core/theme.js';
|
|
16
|
+
/**
|
|
17
|
+
* Run in RPC mode.
|
|
18
|
+
* Listens for JSON commands on stdin, outputs events and responses on stdout.
|
|
19
|
+
*/
|
|
20
|
+
export async function runRpcMode(session) {
|
|
21
|
+
const output = (obj) => {
|
|
22
|
+
console.log(JSON.stringify(obj));
|
|
23
|
+
};
|
|
24
|
+
const success = (id, command, data) => {
|
|
25
|
+
if (data === undefined) {
|
|
26
|
+
return { id, type: 'response', command, success: true };
|
|
27
|
+
}
|
|
28
|
+
return { id, type: 'response', command, success: true, data };
|
|
29
|
+
};
|
|
30
|
+
const error = (id, command, message) => {
|
|
31
|
+
return { id, type: 'response', command, success: false, error: message };
|
|
32
|
+
};
|
|
33
|
+
// Pending extension UI requests waiting for response
|
|
34
|
+
const pendingExtensionRequests = new Map();
|
|
35
|
+
// Shutdown request flag
|
|
36
|
+
let shutdownRequested = false;
|
|
37
|
+
/** Helper for dialog methods with signal/timeout support */
|
|
38
|
+
function createDialogPromise(opts, defaultValue, request, parseResponse) {
|
|
39
|
+
if (opts?.signal?.aborted)
|
|
40
|
+
return Promise.resolve(defaultValue);
|
|
41
|
+
const id = crypto.randomUUID();
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
let timeoutId;
|
|
44
|
+
const cleanup = () => {
|
|
45
|
+
if (timeoutId)
|
|
46
|
+
clearTimeout(timeoutId);
|
|
47
|
+
opts?.signal?.removeEventListener('abort', onAbort);
|
|
48
|
+
pendingExtensionRequests.delete(id);
|
|
49
|
+
};
|
|
50
|
+
const onAbort = () => {
|
|
51
|
+
cleanup();
|
|
52
|
+
resolve(defaultValue);
|
|
53
|
+
};
|
|
54
|
+
opts?.signal?.addEventListener('abort', onAbort, { once: true });
|
|
55
|
+
if (opts?.timeout) {
|
|
56
|
+
timeoutId = setTimeout(() => {
|
|
57
|
+
cleanup();
|
|
58
|
+
resolve(defaultValue);
|
|
59
|
+
}, opts.timeout);
|
|
60
|
+
}
|
|
61
|
+
pendingExtensionRequests.set(id, {
|
|
62
|
+
resolve: (response) => {
|
|
63
|
+
cleanup();
|
|
64
|
+
resolve(parseResponse(response));
|
|
65
|
+
},
|
|
66
|
+
reject
|
|
67
|
+
});
|
|
68
|
+
output({ type: 'extension_ui_request', id, ...request });
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create an extension UI context that uses the RPC protocol.
|
|
73
|
+
*/
|
|
74
|
+
const createExtensionUIContext = () => ({
|
|
75
|
+
select: (title, options, opts) => createDialogPromise(opts, undefined, { method: 'select', title, options, timeout: opts?.timeout }, (r) => ('cancelled' in r && r.cancelled ? undefined : 'value' in r ? r.value : undefined)),
|
|
76
|
+
confirm: (title, message, opts) => createDialogPromise(opts, false, { method: 'confirm', title, message, timeout: opts?.timeout }, (r) => ('cancelled' in r && r.cancelled ? false : 'confirmed' in r ? r.confirmed : false)),
|
|
77
|
+
input: (title, placeholder, opts) => createDialogPromise(opts, undefined, { method: 'input', title, placeholder, timeout: opts?.timeout }, (r) => ('cancelled' in r && r.cancelled ? undefined : 'value' in r ? r.value : undefined)),
|
|
78
|
+
notify(message, type) {
|
|
79
|
+
// Fire and forget - no response needed
|
|
80
|
+
output({
|
|
81
|
+
type: 'extension_ui_request',
|
|
82
|
+
id: crypto.randomUUID(),
|
|
83
|
+
method: 'notify',
|
|
84
|
+
message,
|
|
85
|
+
notifyType: type
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
onTerminalInput() {
|
|
89
|
+
// Raw terminal input not supported in RPC mode
|
|
90
|
+
return () => { };
|
|
91
|
+
},
|
|
92
|
+
setStatus(key, text) {
|
|
93
|
+
// Fire and forget - no response needed
|
|
94
|
+
output({
|
|
95
|
+
type: 'extension_ui_request',
|
|
96
|
+
id: crypto.randomUUID(),
|
|
97
|
+
method: 'setStatus',
|
|
98
|
+
statusKey: key,
|
|
99
|
+
statusText: text
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
setWorkingMessage(_message) {
|
|
103
|
+
// Working message not supported in RPC mode - requires TUI loader access
|
|
104
|
+
},
|
|
105
|
+
setWidget(key, content, options) {
|
|
106
|
+
// Only support string arrays in RPC mode - factory functions are ignored
|
|
107
|
+
if (content === undefined || Array.isArray(content)) {
|
|
108
|
+
output({
|
|
109
|
+
type: 'extension_ui_request',
|
|
110
|
+
id: crypto.randomUUID(),
|
|
111
|
+
method: 'setWidget',
|
|
112
|
+
widgetKey: key,
|
|
113
|
+
widgetLines: content,
|
|
114
|
+
widgetPlacement: options?.placement
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// Component factories are not supported in RPC mode - would need TUI access
|
|
118
|
+
},
|
|
119
|
+
setFooter(_factory) {
|
|
120
|
+
// Custom footer not supported in RPC mode - requires TUI access
|
|
121
|
+
},
|
|
122
|
+
setHeader(_factory) {
|
|
123
|
+
// Custom header not supported in RPC mode - requires TUI access
|
|
124
|
+
},
|
|
125
|
+
setTitle(title) {
|
|
126
|
+
// Fire and forget - host can implement terminal title control
|
|
127
|
+
output({
|
|
128
|
+
type: 'extension_ui_request',
|
|
129
|
+
id: crypto.randomUUID(),
|
|
130
|
+
method: 'setTitle',
|
|
131
|
+
title
|
|
132
|
+
});
|
|
133
|
+
},
|
|
134
|
+
async custom() {
|
|
135
|
+
// Custom UI not supported in RPC mode
|
|
136
|
+
return undefined;
|
|
137
|
+
},
|
|
138
|
+
pasteToEditor(text) {
|
|
139
|
+
// Paste handling not supported in RPC mode - falls back to setEditorText
|
|
140
|
+
this.setEditorText(text);
|
|
141
|
+
},
|
|
142
|
+
setEditorText(text) {
|
|
143
|
+
// Fire and forget - host can implement editor control
|
|
144
|
+
output({
|
|
145
|
+
type: 'extension_ui_request',
|
|
146
|
+
id: crypto.randomUUID(),
|
|
147
|
+
method: 'set_editor_text',
|
|
148
|
+
text
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
getEditorText() {
|
|
152
|
+
// Synchronous method can't wait for RPC response
|
|
153
|
+
// Host should track editor state locally if needed
|
|
154
|
+
return '';
|
|
155
|
+
},
|
|
156
|
+
async editor(title, prefill) {
|
|
157
|
+
const id = crypto.randomUUID();
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
pendingExtensionRequests.set(id, {
|
|
160
|
+
resolve: (response) => {
|
|
161
|
+
if ('cancelled' in response && response.cancelled) {
|
|
162
|
+
resolve(undefined);
|
|
163
|
+
}
|
|
164
|
+
else if ('value' in response) {
|
|
165
|
+
resolve(response.value);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
resolve(undefined);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
reject
|
|
172
|
+
});
|
|
173
|
+
output({
|
|
174
|
+
type: 'extension_ui_request',
|
|
175
|
+
id,
|
|
176
|
+
method: 'editor',
|
|
177
|
+
title,
|
|
178
|
+
prefill
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
|
+
setEditorComponent() {
|
|
183
|
+
// Custom editor components not supported in RPC mode
|
|
184
|
+
},
|
|
185
|
+
get theme() {
|
|
186
|
+
return theme;
|
|
187
|
+
},
|
|
188
|
+
getAllThemes() {
|
|
189
|
+
return [];
|
|
190
|
+
},
|
|
191
|
+
getTheme(_name) {
|
|
192
|
+
return undefined;
|
|
193
|
+
},
|
|
194
|
+
setTheme(_theme) {
|
|
195
|
+
// Theme switching not supported in RPC mode
|
|
196
|
+
return { success: false, error: 'Theme switching not supported in RPC mode' };
|
|
197
|
+
},
|
|
198
|
+
getToolsExpanded() {
|
|
199
|
+
// Tool expansion not supported in RPC mode - no TUI
|
|
200
|
+
return false;
|
|
201
|
+
},
|
|
202
|
+
setToolsExpanded(_expanded) {
|
|
203
|
+
// Tool expansion not supported in RPC mode - no TUI
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
// Set up extensions with RPC-based UI context
|
|
207
|
+
await session.bindExtensions({
|
|
208
|
+
uiContext: createExtensionUIContext(),
|
|
209
|
+
commandContextActions: {
|
|
210
|
+
waitForIdle: () => session.agent.waitForIdle(),
|
|
211
|
+
newSession: async (options) => {
|
|
212
|
+
// Delegate to AgentSession (handles setup + agent state sync)
|
|
213
|
+
const success = await session.newSession(options);
|
|
214
|
+
return { cancelled: !success };
|
|
215
|
+
},
|
|
216
|
+
fork: async (entryId) => {
|
|
217
|
+
const result = await session.fork(entryId);
|
|
218
|
+
return { cancelled: result.cancelled };
|
|
219
|
+
},
|
|
220
|
+
navigateTree: async (targetId, options) => {
|
|
221
|
+
const result = await session.navigateTree(targetId, {
|
|
222
|
+
summarize: options?.summarize,
|
|
223
|
+
customInstructions: options?.customInstructions,
|
|
224
|
+
replaceInstructions: options?.replaceInstructions,
|
|
225
|
+
label: options?.label
|
|
226
|
+
});
|
|
227
|
+
return { cancelled: result.cancelled };
|
|
228
|
+
},
|
|
229
|
+
switchSession: async (sessionPath) => {
|
|
230
|
+
const success = await session.switchSession(sessionPath);
|
|
231
|
+
return { cancelled: !success };
|
|
232
|
+
},
|
|
233
|
+
reload: async () => {
|
|
234
|
+
await session.reload();
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
shutdownHandler: () => {
|
|
238
|
+
shutdownRequested = true;
|
|
239
|
+
},
|
|
240
|
+
onError: (err) => {
|
|
241
|
+
output({
|
|
242
|
+
type: 'extension_error',
|
|
243
|
+
extensionPath: err.extensionPath,
|
|
244
|
+
event: err.event,
|
|
245
|
+
error: err.error
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
// Output all agent events as JSON
|
|
250
|
+
session.subscribe((event) => {
|
|
251
|
+
output(event);
|
|
252
|
+
});
|
|
253
|
+
// Handle a single command
|
|
254
|
+
const handleCommand = async (command) => {
|
|
255
|
+
const id = command.id;
|
|
256
|
+
switch (command.type) {
|
|
257
|
+
// =================================================================
|
|
258
|
+
// Prompting
|
|
259
|
+
// =================================================================
|
|
260
|
+
case 'prompt': {
|
|
261
|
+
// Don't await - events will stream
|
|
262
|
+
// Extension commands are executed immediately, file prompt templates are expanded
|
|
263
|
+
// If streaming and streamingBehavior specified, queues via steer/followUp
|
|
264
|
+
session
|
|
265
|
+
.prompt(command.message, {
|
|
266
|
+
images: command.images,
|
|
267
|
+
streamingBehavior: command.streamingBehavior,
|
|
268
|
+
source: 'rpc'
|
|
269
|
+
})
|
|
270
|
+
.catch((e) => output(error(id, 'prompt', e.message)));
|
|
271
|
+
return success(id, 'prompt');
|
|
272
|
+
}
|
|
273
|
+
case 'steer': {
|
|
274
|
+
await session.steer(command.message, command.images);
|
|
275
|
+
return success(id, 'steer');
|
|
276
|
+
}
|
|
277
|
+
case 'follow_up': {
|
|
278
|
+
await session.followUp(command.message, command.images);
|
|
279
|
+
return success(id, 'follow_up');
|
|
280
|
+
}
|
|
281
|
+
case 'abort': {
|
|
282
|
+
await session.abort();
|
|
283
|
+
return success(id, 'abort');
|
|
284
|
+
}
|
|
285
|
+
case 'new_session': {
|
|
286
|
+
const options = command.parentSession
|
|
287
|
+
? { parentSession: command.parentSession }
|
|
288
|
+
: undefined;
|
|
289
|
+
const cancelled = !(await session.newSession(options));
|
|
290
|
+
return success(id, 'new_session', { cancelled });
|
|
291
|
+
}
|
|
292
|
+
// =================================================================
|
|
293
|
+
// State
|
|
294
|
+
// =================================================================
|
|
295
|
+
case 'get_state': {
|
|
296
|
+
const state = {
|
|
297
|
+
model: session.model,
|
|
298
|
+
thinkingLevel: session.thinkingLevel,
|
|
299
|
+
isStreaming: session.isStreaming,
|
|
300
|
+
isCompacting: session.isCompacting,
|
|
301
|
+
steeringMode: session.steeringMode,
|
|
302
|
+
followUpMode: session.followUpMode,
|
|
303
|
+
sessionFile: session.sessionFile,
|
|
304
|
+
sessionId: session.sessionId,
|
|
305
|
+
sessionName: session.sessionName,
|
|
306
|
+
autoCompactionEnabled: true,
|
|
307
|
+
messageCount: session.messages.length,
|
|
308
|
+
pendingMessageCount: session.pendingMessageCount
|
|
309
|
+
};
|
|
310
|
+
return success(id, 'get_state', state);
|
|
311
|
+
}
|
|
312
|
+
// =================================================================
|
|
313
|
+
// Model
|
|
314
|
+
// =================================================================
|
|
315
|
+
case 'set_model': {
|
|
316
|
+
const models = await session.modelRegistry.getAvailable();
|
|
317
|
+
const model = models.find((m) => m.provider === command.provider && m.id === command.modelId);
|
|
318
|
+
if (!model) {
|
|
319
|
+
return error(id, 'set_model', `Model not found: ${command.provider}/${command.modelId}`);
|
|
320
|
+
}
|
|
321
|
+
await session.setModel(model);
|
|
322
|
+
return success(id, 'set_model', model);
|
|
323
|
+
}
|
|
324
|
+
case 'cycle_model': {
|
|
325
|
+
const result = await session.cycleModel();
|
|
326
|
+
if (!result) {
|
|
327
|
+
return success(id, 'cycle_model', null);
|
|
328
|
+
}
|
|
329
|
+
return success(id, 'cycle_model', result);
|
|
330
|
+
}
|
|
331
|
+
case 'get_available_models': {
|
|
332
|
+
const models = await session.modelRegistry.getAvailable();
|
|
333
|
+
return success(id, 'get_available_models', { models });
|
|
334
|
+
}
|
|
335
|
+
// =================================================================
|
|
336
|
+
// Thinking
|
|
337
|
+
// =================================================================
|
|
338
|
+
case 'set_thinking_level': {
|
|
339
|
+
session.setThinkingLevel(command.level);
|
|
340
|
+
return success(id, 'set_thinking_level');
|
|
341
|
+
}
|
|
342
|
+
case 'cycle_thinking_level': {
|
|
343
|
+
const level = session.cycleThinkingLevel();
|
|
344
|
+
if (!level) {
|
|
345
|
+
return success(id, 'cycle_thinking_level', null);
|
|
346
|
+
}
|
|
347
|
+
return success(id, 'cycle_thinking_level', { level });
|
|
348
|
+
}
|
|
349
|
+
// =================================================================
|
|
350
|
+
// Compaction
|
|
351
|
+
// =================================================================
|
|
352
|
+
case 'compact': {
|
|
353
|
+
const result = await session.compact(command.customInstructions);
|
|
354
|
+
return success(id, 'compact', result);
|
|
355
|
+
}
|
|
356
|
+
// =================================================================
|
|
357
|
+
// Retry
|
|
358
|
+
// =================================================================
|
|
359
|
+
case 'set_auto_retry': {
|
|
360
|
+
session.setAutoRetryEnabled(command.enabled);
|
|
361
|
+
return success(id, 'set_auto_retry');
|
|
362
|
+
}
|
|
363
|
+
case 'abort_retry': {
|
|
364
|
+
session.abortRetry();
|
|
365
|
+
return success(id, 'abort_retry');
|
|
366
|
+
}
|
|
367
|
+
// =================================================================
|
|
368
|
+
// Bash
|
|
369
|
+
// =================================================================
|
|
370
|
+
case 'bash': {
|
|
371
|
+
const result = await session.executeBash(command.command);
|
|
372
|
+
return success(id, 'bash', result);
|
|
373
|
+
}
|
|
374
|
+
case 'abort_bash': {
|
|
375
|
+
session.abortBash();
|
|
376
|
+
return success(id, 'abort_bash');
|
|
377
|
+
}
|
|
378
|
+
// =================================================================
|
|
379
|
+
// Session
|
|
380
|
+
// =================================================================
|
|
381
|
+
case 'get_session_stats': {
|
|
382
|
+
const stats = session.getSessionStats();
|
|
383
|
+
return success(id, 'get_session_stats', stats);
|
|
384
|
+
}
|
|
385
|
+
case 'export_html': {
|
|
386
|
+
const path = await session.exportToHtml(command.outputPath);
|
|
387
|
+
return success(id, 'export_html', { path });
|
|
388
|
+
}
|
|
389
|
+
case 'switch_session': {
|
|
390
|
+
const cancelled = !(await session.switchSession(command.sessionPath));
|
|
391
|
+
return success(id, 'switch_session', { cancelled });
|
|
392
|
+
}
|
|
393
|
+
case 'fork': {
|
|
394
|
+
const result = await session.fork(command.entryId);
|
|
395
|
+
return success(id, 'fork', { text: result.selectedText, cancelled: result.cancelled });
|
|
396
|
+
}
|
|
397
|
+
case 'get_fork_messages': {
|
|
398
|
+
const messages = session.getUserMessagesForForking();
|
|
399
|
+
return success(id, 'get_fork_messages', { messages });
|
|
400
|
+
}
|
|
401
|
+
case 'get_last_assistant_text': {
|
|
402
|
+
const text = session.getLastAssistantText();
|
|
403
|
+
return success(id, 'get_last_assistant_text', { text });
|
|
404
|
+
}
|
|
405
|
+
case 'set_session_name': {
|
|
406
|
+
const name = command.name.trim();
|
|
407
|
+
if (!name) {
|
|
408
|
+
return error(id, 'set_session_name', 'Session name cannot be empty');
|
|
409
|
+
}
|
|
410
|
+
session.setSessionName(name);
|
|
411
|
+
return success(id, 'set_session_name');
|
|
412
|
+
}
|
|
413
|
+
// =================================================================
|
|
414
|
+
// Messages
|
|
415
|
+
// =================================================================
|
|
416
|
+
case 'get_messages': {
|
|
417
|
+
return success(id, 'get_messages', { messages: session.messages });
|
|
418
|
+
}
|
|
419
|
+
// =================================================================
|
|
420
|
+
// Commands (available for invocation via prompt)
|
|
421
|
+
// =================================================================
|
|
422
|
+
case 'get_commands': {
|
|
423
|
+
const commands = [];
|
|
424
|
+
// Extension commands
|
|
425
|
+
for (const { command, extensionPath } of session.extensionRunner?.getRegisteredCommandsWithPaths() ?? []) {
|
|
426
|
+
commands.push({
|
|
427
|
+
name: command.name,
|
|
428
|
+
description: command.description,
|
|
429
|
+
source: 'extension',
|
|
430
|
+
path: extensionPath
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
// Prompt templates (source is always "user" | "project" | "path" in coding-agent)
|
|
434
|
+
for (const template of session.promptTemplates) {
|
|
435
|
+
commands.push({
|
|
436
|
+
name: template.name,
|
|
437
|
+
description: template.description,
|
|
438
|
+
source: 'prompt',
|
|
439
|
+
location: template.source,
|
|
440
|
+
path: template.filePath
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
// Skills (source is always "user" | "project" | "path" in coding-agent)
|
|
444
|
+
for (const skill of session.resourceLoader.getSkills().skills) {
|
|
445
|
+
commands.push({
|
|
446
|
+
name: `skill:${skill.name}`,
|
|
447
|
+
description: skill.description,
|
|
448
|
+
source: 'skill',
|
|
449
|
+
location: skill.source,
|
|
450
|
+
path: skill.filePath
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return success(id, 'get_commands', { commands });
|
|
454
|
+
}
|
|
455
|
+
default: {
|
|
456
|
+
const unknownCommand = command;
|
|
457
|
+
return error(undefined, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
/**
|
|
462
|
+
* Check if shutdown was requested and perform shutdown if so.
|
|
463
|
+
* Called after handling each command when waiting for the next command.
|
|
464
|
+
*/
|
|
465
|
+
async function checkShutdownRequested() {
|
|
466
|
+
if (!shutdownRequested)
|
|
467
|
+
return;
|
|
468
|
+
const currentRunner = session.extensionRunner;
|
|
469
|
+
if (currentRunner?.hasHandlers('session_shutdown')) {
|
|
470
|
+
await currentRunner.emit({ type: 'session_shutdown' });
|
|
471
|
+
}
|
|
472
|
+
// Close readline interface to stop waiting for input
|
|
473
|
+
rl.close();
|
|
474
|
+
process.exit(0);
|
|
475
|
+
}
|
|
476
|
+
// Listen for JSON input
|
|
477
|
+
const rl = readline.createInterface({
|
|
478
|
+
input: process.stdin,
|
|
479
|
+
output: process.stdout,
|
|
480
|
+
terminal: false
|
|
481
|
+
});
|
|
482
|
+
rl.on('line', async (line) => {
|
|
483
|
+
try {
|
|
484
|
+
const parsed = JSON.parse(line);
|
|
485
|
+
// Handle extension UI responses
|
|
486
|
+
if (parsed.type === 'extension_ui_response') {
|
|
487
|
+
const response = parsed;
|
|
488
|
+
const pending = pendingExtensionRequests.get(response.id);
|
|
489
|
+
if (pending) {
|
|
490
|
+
pendingExtensionRequests.delete(response.id);
|
|
491
|
+
pending.resolve(response);
|
|
492
|
+
}
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
// Handle regular commands
|
|
496
|
+
const command = parsed;
|
|
497
|
+
const response = await handleCommand(command);
|
|
498
|
+
output(response);
|
|
499
|
+
// Check for deferred shutdown request (idle between commands)
|
|
500
|
+
await checkShutdownRequested();
|
|
501
|
+
}
|
|
502
|
+
catch (e) {
|
|
503
|
+
output(error(undefined, 'parse', `Failed to parse command: ${e.message}`));
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
// Keep process alive forever
|
|
507
|
+
return new Promise(() => { });
|
|
508
|
+
}
|
|
509
|
+
//# sourceMappingURL=rpc-mode.js.map
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal composition root for subagent child processes.
|
|
3
|
+
*
|
|
4
|
+
* Like main.ts, this wires together cli, core, custom, and modes — but skips
|
|
5
|
+
* everything a subagent doesn't need: migrations, file-backed settings/auth
|
|
6
|
+
* (which use proper-lockfile and cause contention when multiple subagents
|
|
7
|
+
* spawn concurrently), extensions, Excel config, theme init, model scanning.
|
|
8
|
+
*
|
|
9
|
+
* The parent already resolved auth (--api-key), model (--model), system
|
|
10
|
+
* prompt (--system-prompt), and tool selection (--tools/--custom-tools).
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
13
|
+
import { parseArgs } from './cli/args.js';
|
|
14
|
+
import { getAgentDir } from './config.js';
|
|
15
|
+
import { AuthStorage } from './core/auth-storage.js';
|
|
16
|
+
import { ModelRegistry } from './core/model-registry.js';
|
|
17
|
+
import { resolveCliModel } from './core/model-resolver.js';
|
|
18
|
+
import { DefaultResourceLoader } from './core/resource-loader.js';
|
|
19
|
+
import { createAgentSession } from './core/sdk.js';
|
|
20
|
+
import { SessionManager } from './core/session-manager.js';
|
|
21
|
+
import { SettingsManager } from './core/settings-manager.js';
|
|
22
|
+
import { allTools } from './core/tools/index.js';
|
|
23
|
+
import { EXCEL_HTTP_URL, SHORTCUT_LLM_PROXY_URL } from './custom/constants.js';
|
|
24
|
+
import { fetchWorkbookSummary, formatSummaryForLlm, parseWorkbookNames } from './custom/context/workbook-summary.js';
|
|
25
|
+
// TODO: Re-enable when we support multiple providers
|
|
26
|
+
// import { registerOpenAICodexProvider } from './custom/providers/register-openai-codex-provider.js';
|
|
27
|
+
import { registerShortcutProvider } from './custom/providers/register-shortcut-provider.js';
|
|
28
|
+
import { createExcelExecTool } from './custom/tools/excel-exec.js';
|
|
29
|
+
import { createLlmAnalysisTool } from './custom/tools/llm-analysis.js';
|
|
30
|
+
import { runPrintMode } from './modes/print-mode.js';
|
|
31
|
+
import { EXCEL_EXEC, LLM_ANALYSIS } from './tool-names.js';
|
|
32
|
+
export async function runSubagent(args) {
|
|
33
|
+
const parsed = parseArgs(args);
|
|
34
|
+
// Read-only auth: reads auth.json without file locking so concurrent
|
|
35
|
+
// subagents never contend. Never refreshes — the parent process owns
|
|
36
|
+
// token refresh and writes updated credentials to auth.json.
|
|
37
|
+
// A periodic reload() picks up the parent's refreshed tokens.
|
|
38
|
+
const settingsManager = SettingsManager.inMemory();
|
|
39
|
+
const authStorage = AuthStorage.createReadOnly();
|
|
40
|
+
const modelRegistry = new ModelRegistry(authStorage, undefined);
|
|
41
|
+
// Register Shortcut provider (needed for model resolution).
|
|
42
|
+
// Subagents use non-streaming invoke — no UI needs deltas, and the parent
|
|
43
|
+
// only reads final message_end events from stdout. Avoids SSE overhead.
|
|
44
|
+
registerShortcutProvider(modelRegistry, SHORTCUT_LLM_PROXY_URL, { streaming: false });
|
|
45
|
+
// TODO: Re-enable when we support multiple providers
|
|
46
|
+
// Register OpenAI Codex provider (ChatGPT Plus/Pro OAuth, gpt-5.4)
|
|
47
|
+
// registerOpenAICodexProvider(modelRegistry);
|
|
48
|
+
// Periodically re-read auth.json to pick up tokens refreshed by the parent.
|
|
49
|
+
// No refresh logic — just plain file reads.
|
|
50
|
+
const reloadTimer = setInterval(() => authStorage.reload(), 30_000);
|
|
51
|
+
reloadTimer.unref();
|
|
52
|
+
// Handle --api-key (parent passes the resolved key)
|
|
53
|
+
if (parsed.apiKey && parsed.model) {
|
|
54
|
+
const provider = parsed.model.includes('/') ? parsed.model.split('/')[0] : undefined;
|
|
55
|
+
if (provider) {
|
|
56
|
+
authStorage.setRuntimeApiKey(provider, parsed.apiKey);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Resolve model
|
|
60
|
+
let model;
|
|
61
|
+
if (parsed.model) {
|
|
62
|
+
const resolved = resolveCliModel({
|
|
63
|
+
cliProvider: parsed.provider,
|
|
64
|
+
cliModel: parsed.model,
|
|
65
|
+
modelRegistry
|
|
66
|
+
});
|
|
67
|
+
model = resolved.model;
|
|
68
|
+
}
|
|
69
|
+
// Resolve system prompt from --system-prompt (file path or literal)
|
|
70
|
+
let systemPrompt;
|
|
71
|
+
if (parsed.systemPrompt) {
|
|
72
|
+
systemPrompt = existsSync(parsed.systemPrompt)
|
|
73
|
+
? readFileSync(parsed.systemPrompt, 'utf-8')
|
|
74
|
+
: parsed.systemPrompt;
|
|
75
|
+
}
|
|
76
|
+
// Minimal resource loader with just the system prompt, no file discovery
|
|
77
|
+
const resourceLoader = new DefaultResourceLoader({
|
|
78
|
+
cwd: process.cwd(),
|
|
79
|
+
agentDir: getAgentDir(),
|
|
80
|
+
settingsManager,
|
|
81
|
+
systemPrompt: systemPrompt ?? '',
|
|
82
|
+
noExtensions: true,
|
|
83
|
+
noSkills: true,
|
|
84
|
+
noPromptTemplates: true,
|
|
85
|
+
noThemes: true
|
|
86
|
+
});
|
|
87
|
+
await resourceLoader.reload();
|
|
88
|
+
// Build tools
|
|
89
|
+
const tools = (() => {
|
|
90
|
+
if (parsed.noTools) {
|
|
91
|
+
return parsed.tools?.map((name) => allTools[name]) ?? [];
|
|
92
|
+
}
|
|
93
|
+
return parsed.tools?.map((name) => allTools[name]);
|
|
94
|
+
})();
|
|
95
|
+
// Build custom tools (no task tool — subagents don't spawn sub-subagents)
|
|
96
|
+
const customTools = [];
|
|
97
|
+
if (!parsed.noCustomTools) {
|
|
98
|
+
const customToolSet = parsed.customTools ? new Set(parsed.customTools) : null;
|
|
99
|
+
if (!customToolSet || customToolSet.has(EXCEL_EXEC)) {
|
|
100
|
+
customTools.push(createExcelExecTool(EXCEL_HTTP_URL));
|
|
101
|
+
}
|
|
102
|
+
if (!customToolSet || customToolSet.has(LLM_ANALYSIS)) {
|
|
103
|
+
customTools.push(createLlmAnalysisTool(SHORTCUT_LLM_PROXY_URL));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const { session } = await createAgentSession({
|
|
107
|
+
model,
|
|
108
|
+
thinkingLevel: parsed.thinking,
|
|
109
|
+
tools,
|
|
110
|
+
customTools,
|
|
111
|
+
sessionManager: parsed.sessionDir
|
|
112
|
+
? SessionManager.create(process.cwd(), parsed.sessionDir)
|
|
113
|
+
: SessionManager.inMemory(),
|
|
114
|
+
settingsManager,
|
|
115
|
+
authStorage,
|
|
116
|
+
modelRegistry,
|
|
117
|
+
resourceLoader,
|
|
118
|
+
prePromptContext: async () => {
|
|
119
|
+
const summary = await fetchWorkbookSummary();
|
|
120
|
+
if (!summary)
|
|
121
|
+
return null;
|
|
122
|
+
return {
|
|
123
|
+
text: formatSummaryForLlm(summary),
|
|
124
|
+
details: { workbooks: parseWorkbookNames(summary) }
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
// Resolve .txt file paths in messages to their contents (same pattern as
|
|
129
|
+
// backend's resolve_query_from_file). The parent writes the query to a .txt
|
|
130
|
+
// file to avoid cmd.exe argument splitting on Windows. Also allows the LLM
|
|
131
|
+
// to pass .txt file paths directly for batch/parallel calls with variables.
|
|
132
|
+
const messages = parsed.messages.map((msg) => {
|
|
133
|
+
const trimmed = msg.trim();
|
|
134
|
+
if (trimmed.endsWith('.txt') && !trimmed.includes(' ') && existsSync(trimmed)) {
|
|
135
|
+
return readFileSync(trimmed, 'utf-8');
|
|
136
|
+
}
|
|
137
|
+
return msg;
|
|
138
|
+
});
|
|
139
|
+
const mode = parsed.mode || 'text';
|
|
140
|
+
await runPrintMode(session, {
|
|
141
|
+
mode: mode,
|
|
142
|
+
messages
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=subagent-entry.js.map
|