pi-ui-extend 0.1.1
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 +307 -0
- package/bin/pix.mjs +219 -0
- package/dist/app/app.d.ts +96 -0
- package/dist/app/app.js +871 -0
- package/dist/app/blink-controller.d.ts +23 -0
- package/dist/app/blink-controller.js +82 -0
- package/dist/app/cli.d.ts +8 -0
- package/dist/app/cli.js +83 -0
- package/dist/app/clipboard.d.ts +1 -0
- package/dist/app/clipboard.js +24 -0
- package/dist/app/command-controller.d.ts +18 -0
- package/dist/app/command-controller.js +58 -0
- package/dist/app/command-host.d.ts +44 -0
- package/dist/app/command-host.js +1 -0
- package/dist/app/command-model-actions.d.ts +12 -0
- package/dist/app/command-model-actions.js +176 -0
- package/dist/app/command-navigation-actions.d.ts +19 -0
- package/dist/app/command-navigation-actions.js +267 -0
- package/dist/app/command-registry.d.ts +32 -0
- package/dist/app/command-registry.js +225 -0
- package/dist/app/command-runtime.d.ts +5 -0
- package/dist/app/command-runtime.js +32 -0
- package/dist/app/command-session-actions.d.ts +20 -0
- package/dist/app/command-session-actions.js +295 -0
- package/dist/app/constants.d.ts +52 -0
- package/dist/app/constants.js +103 -0
- package/dist/app/conversation-entry-renderer.d.ts +21 -0
- package/dist/app/conversation-entry-renderer.js +81 -0
- package/dist/app/conversation-shell-renderer.d.ts +5 -0
- package/dist/app/conversation-shell-renderer.js +43 -0
- package/dist/app/conversation-tool-renderer.d.ts +16 -0
- package/dist/app/conversation-tool-renderer.js +216 -0
- package/dist/app/conversation-viewport.d.ts +55 -0
- package/dist/app/conversation-viewport.js +252 -0
- package/dist/app/dcp-stats.d.ts +2 -0
- package/dist/app/dcp-stats.js +116 -0
- package/dist/app/editor-layout-renderer.d.ts +31 -0
- package/dist/app/editor-layout-renderer.js +211 -0
- package/dist/app/editor-panels.d.ts +4 -0
- package/dist/app/editor-panels.js +130 -0
- package/dist/app/extension-actions-controller.d.ts +22 -0
- package/dist/app/extension-actions-controller.js +60 -0
- package/dist/app/extension-event-bus.d.ts +3 -0
- package/dist/app/extension-event-bus.js +23 -0
- package/dist/app/extension-ui-controller.d.ts +57 -0
- package/dist/app/extension-ui-controller.js +532 -0
- package/dist/app/file-link-opener.d.ts +2 -0
- package/dist/app/file-link-opener.js +66 -0
- package/dist/app/file-links.d.ts +10 -0
- package/dist/app/file-links.js +117 -0
- package/dist/app/guards.d.ts +3 -0
- package/dist/app/guards.js +9 -0
- package/dist/app/icons.d.ts +37 -0
- package/dist/app/icons.js +97 -0
- package/dist/app/id.d.ts +1 -0
- package/dist/app/id.js +4 -0
- package/dist/app/image-click-targets.d.ts +5 -0
- package/dist/app/image-click-targets.js +32 -0
- package/dist/app/image-opener.d.ts +2 -0
- package/dist/app/image-opener.js +64 -0
- package/dist/app/input-action-controller.d.ts +47 -0
- package/dist/app/input-action-controller.js +209 -0
- package/dist/app/input-controller.d.ts +60 -0
- package/dist/app/input-controller.js +425 -0
- package/dist/app/input-paste-handler.d.ts +27 -0
- package/dist/app/input-paste-handler.js +146 -0
- package/dist/app/menu-items-controller.d.ts +32 -0
- package/dist/app/menu-items-controller.js +182 -0
- package/dist/app/message-content.d.ts +8 -0
- package/dist/app/message-content.js +115 -0
- package/dist/app/model-ref.d.ts +13 -0
- package/dist/app/model-ref.js +50 -0
- package/dist/app/model-usage-controller.d.ts +35 -0
- package/dist/app/model-usage-controller.js +99 -0
- package/dist/app/model-usage-status.d.ts +125 -0
- package/dist/app/model-usage-status.js +749 -0
- package/dist/app/mouse-controller.d.ts +182 -0
- package/dist/app/mouse-controller.js +968 -0
- package/dist/app/native-modifiers.d.ts +3 -0
- package/dist/app/native-modifiers.js +60 -0
- package/dist/app/nerd-font-controller.d.ts +11 -0
- package/dist/app/nerd-font-controller.js +90 -0
- package/dist/app/popup-action-controller.d.ts +44 -0
- package/dist/app/popup-action-controller.js +278 -0
- package/dist/app/popup-menu-controller.d.ts +183 -0
- package/dist/app/popup-menu-controller.js +1070 -0
- package/dist/app/prompt-enhancer-controller.d.ts +40 -0
- package/dist/app/prompt-enhancer-controller.js +215 -0
- package/dist/app/queued-message-controller.d.ts +62 -0
- package/dist/app/queued-message-controller.js +377 -0
- package/dist/app/render-controller.d.ts +41 -0
- package/dist/app/render-controller.js +378 -0
- package/dist/app/render-text.d.ts +19 -0
- package/dist/app/render-text.js +67 -0
- package/dist/app/request-history.d.ts +23 -0
- package/dist/app/request-history.js +131 -0
- package/dist/app/runtime.d.ts +39 -0
- package/dist/app/runtime.js +195 -0
- package/dist/app/screen-selection.d.ts +6 -0
- package/dist/app/screen-selection.js +9 -0
- package/dist/app/screen-styler.d.ts +34 -0
- package/dist/app/screen-styler.js +168 -0
- package/dist/app/scroll-controller.d.ts +51 -0
- package/dist/app/scroll-controller.js +207 -0
- package/dist/app/session-event-controller.d.ts +69 -0
- package/dist/app/session-event-controller.js +338 -0
- package/dist/app/session-history.d.ts +23 -0
- package/dist/app/session-history.js +164 -0
- package/dist/app/session-lifecycle-controller.d.ts +55 -0
- package/dist/app/session-lifecycle-controller.js +116 -0
- package/dist/app/session-search.d.ts +24 -0
- package/dist/app/session-search.js +215 -0
- package/dist/app/shell-command.d.ts +27 -0
- package/dist/app/shell-command.js +176 -0
- package/dist/app/shell-controller.d.ts +28 -0
- package/dist/app/shell-controller.js +124 -0
- package/dist/app/slash-commands.d.ts +6 -0
- package/dist/app/slash-commands.js +75 -0
- package/dist/app/startup-checks.d.ts +8 -0
- package/dist/app/startup-checks.js +59 -0
- package/dist/app/startup-info.d.ts +3 -0
- package/dist/app/startup-info.js +176 -0
- package/dist/app/status-controller.d.ts +35 -0
- package/dist/app/status-controller.js +105 -0
- package/dist/app/status-line-renderer.d.ts +68 -0
- package/dist/app/status-line-renderer.js +453 -0
- package/dist/app/subagents-files.d.ts +10 -0
- package/dist/app/subagents-files.js +193 -0
- package/dist/app/subagents-model.d.ts +23 -0
- package/dist/app/subagents-model.js +224 -0
- package/dist/app/subagents-widget-controller.d.ts +43 -0
- package/dist/app/subagents-widget-controller.js +311 -0
- package/dist/app/tab-line-renderer.d.ts +26 -0
- package/dist/app/tab-line-renderer.js +222 -0
- package/dist/app/tabs-controller.d.ts +100 -0
- package/dist/app/tabs-controller.js +885 -0
- package/dist/app/terminal-controller.d.ts +40 -0
- package/dist/app/terminal-controller.js +135 -0
- package/dist/app/terminal-edit-shortcuts.d.ts +23 -0
- package/dist/app/terminal-edit-shortcuts.js +138 -0
- package/dist/app/terminal-output-buffer.d.ts +20 -0
- package/dist/app/terminal-output-buffer.js +52 -0
- package/dist/app/toast-controller.d.ts +13 -0
- package/dist/app/toast-controller.js +40 -0
- package/dist/app/toast-renderer.d.ts +9 -0
- package/dist/app/toast-renderer.js +79 -0
- package/dist/app/todo-model.d.ts +22 -0
- package/dist/app/todo-model.js +179 -0
- package/dist/app/todo-widget-controller.d.ts +21 -0
- package/dist/app/todo-widget-controller.js +59 -0
- package/dist/app/tool-block-renderer.d.ts +26 -0
- package/dist/app/tool-block-renderer.js +439 -0
- package/dist/app/types.d.ts +550 -0
- package/dist/app/types.js +1 -0
- package/dist/app/update.d.ts +36 -0
- package/dist/app/update.js +315 -0
- package/dist/app/voice-controller.d.ts +52 -0
- package/dist/app/voice-controller.js +600 -0
- package/dist/app/workspace-actions-controller.d.ts +40 -0
- package/dist/app/workspace-actions-controller.js +215 -0
- package/dist/app/workspace-undo.d.ts +44 -0
- package/dist/app/workspace-undo.js +215 -0
- package/dist/config.d.ts +62 -0
- package/dist/config.js +527 -0
- package/dist/context-progress-bar.d.ts +17 -0
- package/dist/context-progress-bar.js +48 -0
- package/dist/default-pix-config.d.ts +1 -0
- package/dist/default-pix-config.js +375 -0
- package/dist/fuzzy.d.ts +23 -0
- package/dist/fuzzy.js +165 -0
- package/dist/input-editor-files.d.ts +15 -0
- package/dist/input-editor-files.js +62 -0
- package/dist/input-editor.d.ts +186 -0
- package/dist/input-editor.js +835 -0
- package/dist/main.d.ts +1 -0
- package/dist/main.js +12 -0
- package/dist/markdown-format.d.ts +22 -0
- package/dist/markdown-format.js +542 -0
- package/dist/sdk.d.ts +3 -0
- package/dist/sdk.js +1 -0
- package/dist/syntax-highlight.d.ts +22 -0
- package/dist/syntax-highlight.js +528 -0
- package/dist/terminal-width.d.ts +6 -0
- package/dist/terminal-width.js +245 -0
- package/dist/theme.d.ts +56 -0
- package/dist/theme.js +118 -0
- package/dist/tool-renderers/apply-patch.d.ts +2 -0
- package/dist/tool-renderers/apply-patch.js +36 -0
- package/dist/tool-renderers/ast.d.ts +2 -0
- package/dist/tool-renderers/ast.js +5 -0
- package/dist/tool-renderers/compress.d.ts +2 -0
- package/dist/tool-renderers/compress.js +126 -0
- package/dist/tool-renderers/index.d.ts +3 -0
- package/dist/tool-renderers/index.js +44 -0
- package/dist/tool-renderers/question.d.ts +2 -0
- package/dist/tool-renderers/question.js +88 -0
- package/dist/tool-renderers/read.d.ts +2 -0
- package/dist/tool-renderers/read.js +36 -0
- package/dist/tool-renderers/repo.d.ts +2 -0
- package/dist/tool-renderers/repo.js +13 -0
- package/dist/tool-renderers/shell.d.ts +3 -0
- package/dist/tool-renderers/shell.js +27 -0
- package/dist/tool-renderers/skill.d.ts +2 -0
- package/dist/tool-renderers/skill.js +132 -0
- package/dist/tool-renderers/subagents.d.ts +2 -0
- package/dist/tool-renderers/subagents.js +51 -0
- package/dist/tool-renderers/todo.d.ts +2 -0
- package/dist/tool-renderers/todo.js +9 -0
- package/dist/tool-renderers/types.d.ts +42 -0
- package/dist/tool-renderers/types.js +1 -0
- package/dist/tool-renderers/utils.d.ts +31 -0
- package/dist/tool-renderers/utils.js +230 -0
- package/dist/tool-renderers/web.d.ts +3 -0
- package/dist/tool-renderers/web.js +9 -0
- package/dist/tool-renderers/write.d.ts +2 -0
- package/dist/tool-renderers/write.js +42 -0
- package/dist/ui.d.ts +56 -0
- package/dist/ui.js +94 -0
- package/docs/release.md +81 -0
- package/extensions/question/contract.ts +100 -0
- package/extensions/question/index.ts +34 -0
- package/extensions/question/render.ts +28 -0
- package/extensions/question/result.ts +86 -0
- package/extensions/question/tool-description.ts +11 -0
- package/extensions/question/tui.ts +629 -0
- package/extensions/question/types.ts +123 -0
- package/extensions/session-title/config.ts +169 -0
- package/extensions/session-title/index.ts +459 -0
- package/extensions/terminal-bell/index.ts +315 -0
- package/external/pi-tools-suite/README.md +242 -0
- package/external/pi-tools-suite/index.ts +1 -0
- package/external/pi-tools-suite/licenses/ollama-pi-web-search.MIT +21 -0
- package/external/pi-tools-suite/licenses/opencode-mystatus-MIT.txt +21 -0
- package/external/pi-tools-suite/package.json +53 -0
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +194 -0
- package/external/pi-tools-suite/src/antigravity-auth/commands.ts +80 -0
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +26 -0
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +20 -0
- package/external/pi-tools-suite/src/antigravity-auth/index.ts +104 -0
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +86 -0
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +305 -0
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +423 -0
- package/external/pi-tools-suite/src/antigravity-auth/status.ts +78 -0
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +302 -0
- package/external/pi-tools-suite/src/antigravity-auth/types.ts +113 -0
- package/external/pi-tools-suite/src/ast-grep/index.ts +6 -0
- package/external/pi-tools-suite/src/ast-grep/render.ts +70 -0
- package/external/pi-tools-suite/src/ast-grep/schema.ts +109 -0
- package/external/pi-tools-suite/src/ast-grep/tool.ts +345 -0
- package/external/pi-tools-suite/src/ast-grep/types.ts +55 -0
- package/external/pi-tools-suite/src/ast-grep/utils.ts +65 -0
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +222 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +518 -0
- package/external/pi-tools-suite/src/async-subagents/constants.ts +11 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +74 -0
- package/external/pi-tools-suite/src/async-subagents/core/attachment-bridge.ts +133 -0
- package/external/pi-tools-suite/src/async-subagents/core/cleanup.ts +66 -0
- package/external/pi-tools-suite/src/async-subagents/core/concurrency.ts +90 -0
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +819 -0
- package/external/pi-tools-suite/src/async-subagents/core/log-limits.ts +166 -0
- package/external/pi-tools-suite/src/async-subagents/core/model-fallback.ts +133 -0
- package/external/pi-tools-suite/src/async-subagents/core/paths.ts +47 -0
- package/external/pi-tools-suite/src/async-subagents/core/pi-invocation.ts +35 -0
- package/external/pi-tools-suite/src/async-subagents/core/presets.ts +67 -0
- package/external/pi-tools-suite/src/async-subagents/core/process.ts +15 -0
- package/external/pi-tools-suite/src/async-subagents/core/prompt.ts +66 -0
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +224 -0
- package/external/pi-tools-suite/src/async-subagents/core/retry.ts +191 -0
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +259 -0
- package/external/pi-tools-suite/src/async-subagents/core/sessions.ts +138 -0
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +688 -0
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +281 -0
- package/external/pi-tools-suite/src/async-subagents/core/stop.ts +131 -0
- package/external/pi-tools-suite/src/async-subagents/core/structured-result.ts +237 -0
- package/external/pi-tools-suite/src/async-subagents/core/tool-guard.ts +34 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +150 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +184 -0
- package/external/pi-tools-suite/src/async-subagents/core/utils.ts +11 -0
- package/external/pi-tools-suite/src/async-subagents/format.ts +41 -0
- package/external/pi-tools-suite/src/async-subagents/index.ts +422 -0
- package/external/pi-tools-suite/src/async-subagents/lib.ts +88 -0
- package/external/pi-tools-suite/src/async-subagents/live.ts +10 -0
- package/external/pi-tools-suite/src/async-subagents/polling.ts +83 -0
- package/external/pi-tools-suite/src/async-subagents/render.ts +230 -0
- package/external/pi-tools-suite/src/async-subagents/subagent-overlay.ts +77 -0
- package/external/pi-tools-suite/src/async-subagents/tasks.ts +120 -0
- package/external/pi-tools-suite/src/async-subagents/tools/cleanup.ts +99 -0
- package/external/pi-tools-suite/src/async-subagents/tools/result.ts +179 -0
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +372 -0
- package/external/pi-tools-suite/src/async-subagents/tools/status.ts +60 -0
- package/external/pi-tools-suite/src/async-subagents/tools/stop.ts +79 -0
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +152 -0
- package/external/pi-tools-suite/src/async-subagents/tools/wait.ts +67 -0
- package/external/pi-tools-suite/src/async-subagents/types.ts +45 -0
- package/external/pi-tools-suite/src/async-subagents/ui.ts +5 -0
- package/external/pi-tools-suite/src/compress/commands.ts +440 -0
- package/external/pi-tools-suite/src/compress/compress-tool.ts +368 -0
- package/external/pi-tools-suite/src/compress/compression-blocks.ts +524 -0
- package/external/pi-tools-suite/src/compress/config.ts +310 -0
- package/external/pi-tools-suite/src/compress/dcp-tui-filter.ts +498 -0
- package/external/pi-tools-suite/src/compress/index.ts +397 -0
- package/external/pi-tools-suite/src/compress/prompts.ts +269 -0
- package/external/pi-tools-suite/src/compress/pruner-candidates.ts +176 -0
- package/external/pi-tools-suite/src/compress/pruner-compression-blocks.ts +260 -0
- package/external/pi-tools-suite/src/compress/pruner-message-ids.ts +147 -0
- package/external/pi-tools-suite/src/compress/pruner-metadata.ts +268 -0
- package/external/pi-tools-suite/src/compress/pruner-nudge.ts +315 -0
- package/external/pi-tools-suite/src/compress/pruner-tools.ts +263 -0
- package/external/pi-tools-suite/src/compress/pruner-types.ts +25 -0
- package/external/pi-tools-suite/src/compress/pruner.ts +92 -0
- package/external/pi-tools-suite/src/compress/state.ts +486 -0
- package/external/pi-tools-suite/src/compress/ui.ts +308 -0
- package/external/pi-tools-suite/src/config.ts +176 -0
- package/external/pi-tools-suite/src/context-usage.ts +31 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +355 -0
- package/external/pi-tools-suite/src/index.ts +46 -0
- package/external/pi-tools-suite/src/lib/lsp.ts +62 -0
- package/external/pi-tools-suite/src/lib/project.ts +42 -0
- package/external/pi-tools-suite/src/lib/tool-args.ts +137 -0
- package/external/pi-tools-suite/src/lsp/_shared/config.ts +156 -0
- package/external/pi-tools-suite/src/lsp/_shared/glob.ts +60 -0
- package/external/pi-tools-suite/src/lsp/_shared/output.ts +102 -0
- package/external/pi-tools-suite/src/lsp/_shared/paths.ts +138 -0
- package/external/pi-tools-suite/src/lsp/_shared/runner.ts +64 -0
- package/external/pi-tools-suite/src/lsp/_shared/template.ts +23 -0
- package/external/pi-tools-suite/src/lsp/_shared/trust.ts +116 -0
- package/external/pi-tools-suite/src/lsp/_shared/types.ts +98 -0
- package/external/pi-tools-suite/src/lsp/async.ts +29 -0
- package/external/pi-tools-suite/src/lsp/child-process.ts +81 -0
- package/external/pi-tools-suite/src/lsp/client.ts +340 -0
- package/external/pi-tools-suite/src/lsp/constants.ts +9 -0
- package/external/pi-tools-suite/src/lsp/diagnostics-store.ts +64 -0
- package/external/pi-tools-suite/src/lsp/documents.ts +24 -0
- package/external/pi-tools-suite/src/lsp/index.ts +31 -0
- package/external/pi-tools-suite/src/lsp/lsp-utils.ts +37 -0
- package/external/pi-tools-suite/src/lsp/manager.ts +190 -0
- package/external/pi-tools-suite/src/lsp/mutation-events.ts +78 -0
- package/external/pi-tools-suite/src/lsp/renderer.ts +1 -0
- package/external/pi-tools-suite/src/lsp/tool-result.ts +6 -0
- package/external/pi-tools-suite/src/lsp/tsserver.ts +107 -0
- package/external/pi-tools-suite/src/lsp/types.ts +15 -0
- package/external/pi-tools-suite/src/model-tools/apply-patch.ts +590 -0
- package/external/pi-tools-suite/src/model-tools/index.ts +430 -0
- package/external/pi-tools-suite/src/model-tools/path-utils.ts +6 -0
- package/external/pi-tools-suite/src/model-tools/tool-args.ts +11 -0
- package/external/pi-tools-suite/src/prompt-commands/index.ts +349 -0
- package/external/pi-tools-suite/src/repo-discovery/index.ts +384 -0
- package/external/pi-tools-suite/src/repo-discovery/project.ts +7 -0
- package/external/pi-tools-suite/src/startup-section.ts +13 -0
- package/external/pi-tools-suite/src/terminal-bell/index.ts +309 -0
- package/external/pi-tools-suite/src/todo/index.ts +201 -0
- package/external/pi-tools-suite/src/todo/state/auto-clear.ts +13 -0
- package/external/pi-tools-suite/src/todo/state/invariants.ts +21 -0
- package/external/pi-tools-suite/src/todo/state/persistence.ts +94 -0
- package/external/pi-tools-suite/src/todo/state/replay.ts +38 -0
- package/external/pi-tools-suite/src/todo/state/selectors.ts +49 -0
- package/external/pi-tools-suite/src/todo/state/state-reducer.ts +362 -0
- package/external/pi-tools-suite/src/todo/state/state.ts +18 -0
- package/external/pi-tools-suite/src/todo/state/store.ts +52 -0
- package/external/pi-tools-suite/src/todo/state/task-graph.ts +57 -0
- package/external/pi-tools-suite/src/todo/todo.ts +487 -0
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +143 -0
- package/external/pi-tools-suite/src/todo/tool/types.ts +188 -0
- package/external/pi-tools-suite/src/todo/view/format.ts +18 -0
- package/external/pi-tools-suite/src/todo/view/labels.ts +13 -0
- package/external/pi-tools-suite/src/tool-descriptions.ts +369 -0
- package/external/pi-tools-suite/src/usage/index.ts +152 -0
- package/external/pi-tools-suite/src/usage/lib/copilot.ts +535 -0
- package/external/pi-tools-suite/src/usage/lib/google.ts +478 -0
- package/external/pi-tools-suite/src/usage/lib/openai.ts +268 -0
- package/external/pi-tools-suite/src/usage/lib/types.ts +114 -0
- package/external/pi-tools-suite/src/usage/lib/utils.ts +134 -0
- package/external/pi-tools-suite/src/usage/lib/zhipu.ts +228 -0
- package/external/pi-tools-suite/src/web-search/index.ts +397 -0
- package/package.json +89 -0
- package/skills/context7/SKILL.md +69 -0
- package/skills/context7/scripts/context7.sh +73 -0
- package/skills/handoff/SKILL.md +15 -0
- package/skills/pdf/LICENSE.txt +30 -0
- package/skills/pdf/SKILL.md +314 -0
- package/skills/pdf/forms.md +294 -0
- package/skills/pdf/reference.md +612 -0
- package/skills/pdf/scripts/check_bounding_boxes.py +65 -0
- package/skills/pdf/scripts/check_fillable_fields.py +11 -0
- package/skills/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/skills/pdf/scripts/create_validation_image.py +37 -0
- package/skills/pdf/scripts/extract_form_field_info.py +122 -0
- package/skills/pdf/scripts/extract_form_structure.py +115 -0
- package/skills/pdf/scripts/fill_fillable_fields.py +98 -0
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/skills/playwright-cli/SKILL.md +388 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/spec-driven-testing.md +305 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +134 -0
- package/skills/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright-cli/references/video-recording.md +143 -0
- package/skills/simplify/SKILL.md +51 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +485 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +247 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +328 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
deleteRunDirs,
|
|
6
|
+
getActiveSubagentPresetName,
|
|
7
|
+
getRunState,
|
|
8
|
+
getRunRoot,
|
|
9
|
+
getSubagentRegistryPath,
|
|
10
|
+
isBlindModelRef,
|
|
11
|
+
loadSubagentConfig,
|
|
12
|
+
listRunDirs,
|
|
13
|
+
loadSubagentRegistry,
|
|
14
|
+
removeSubagentRunsFromRegistry,
|
|
15
|
+
stopAgents,
|
|
16
|
+
type AgentCompletionHandler,
|
|
17
|
+
type StopSignal,
|
|
18
|
+
} from "./lib.js";
|
|
19
|
+
import { buildUltraworkPrompt, isUltraworkEnvEnabled, registerCommands } from "./commands.js";
|
|
20
|
+
import { agentStrategyPrompt, appendAgentStrategyPrompt } from "./core/agent-strategy.js";
|
|
21
|
+
import {
|
|
22
|
+
bridgeImageAttachments,
|
|
23
|
+
removeImageAttachmentBridgeState,
|
|
24
|
+
type BridgedImageAttachment,
|
|
25
|
+
type BridgeImageAttachmentsResult,
|
|
26
|
+
} from "./core/attachment-bridge.js";
|
|
27
|
+
import { appendUltraworkAutoHint, decideUltraworkAuto, isGptLikeModel, isUltraworkAutoEnvEnabled } from "./core/ultrawork-auto.js";
|
|
28
|
+
import { SubagentOverlay } from "./subagent-overlay.js";
|
|
29
|
+
import { registerSubagentsTool } from "./tools/subagents.js";
|
|
30
|
+
import type { LiveAgent, SubagentsLiveStateEvent } from "./types.js";
|
|
31
|
+
import { publishStartupSection } from "../startup-section.js";
|
|
32
|
+
|
|
33
|
+
const SUBAGENTS_LIVE_COUNT_EVENT = "pi-tools-suite:async-subagents:live-count";
|
|
34
|
+
const SUBAGENTS_LIVE_STATE_EVENT = "pi-tools-suite:async-subagents:live-state";
|
|
35
|
+
const SESSION_SHUTDOWN_KILL_GRACE_MS = 500;
|
|
36
|
+
|
|
37
|
+
interface ShutdownTarget {
|
|
38
|
+
runDir: string;
|
|
39
|
+
agentIds?: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function createLiveStatePayload(
|
|
43
|
+
liveAgents: Map<string, Map<string, LiveAgent>>,
|
|
44
|
+
sessionFile: string | undefined,
|
|
45
|
+
): SubagentsLiveStateEvent {
|
|
46
|
+
const runs: SubagentsLiveStateEvent["runs"] = [];
|
|
47
|
+
let count = 0;
|
|
48
|
+
for (const [runDir, liveRun] of liveAgents.entries()) {
|
|
49
|
+
const matchingLiveAgents = [...liveRun.values()].filter((agent) => agentMatchesSession(agent, sessionFile));
|
|
50
|
+
if (matchingLiveAgents.length === 0) continue;
|
|
51
|
+
const agentIds = matchingLiveAgents.map((agent) => agent.agentId);
|
|
52
|
+
const state = getRunState(runDir, agentIds, { includeLineCounts: false, checkRpcPromptFailure: false });
|
|
53
|
+
const activeAgents = state.agents.filter((agent) => !isTerminalAgentStatus(agent.status));
|
|
54
|
+
if (activeAgents.length === 0) continue;
|
|
55
|
+
count += activeAgents.length;
|
|
56
|
+
const tasks = matchingLiveAgents.map((agent) => agent.preview).filter((preview): preview is NonNullable<typeof preview> => Boolean(preview));
|
|
57
|
+
runs.push({
|
|
58
|
+
runDir,
|
|
59
|
+
agents: activeAgents,
|
|
60
|
+
...(tasks.length > 0 ? { tasks } : {}),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
version: 1,
|
|
65
|
+
count,
|
|
66
|
+
runs,
|
|
67
|
+
...(sessionFile ? { sessionFile } : {}),
|
|
68
|
+
checkedAt: Date.now(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function agentMatchesSession(agent: LiveAgent, sessionFile: string | undefined): boolean {
|
|
73
|
+
if (!sessionFile || !agent.parentSession) return true;
|
|
74
|
+
return pathsEqual(sessionFile, agent.parentSession);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isTerminalAgentStatus(status: ReturnType<typeof getRunState>["agents"][number]["status"]): boolean {
|
|
78
|
+
return status === "done" || status === "failed" || status === "stopped";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default function (pi: ExtensionAPI) {
|
|
82
|
+
const liveAgents = new Map<string, Map<string, LiveAgent>>();
|
|
83
|
+
const subagentOverlay = new SubagentOverlay(liveAgents);
|
|
84
|
+
let sawAutoUltraworkCandidate = false;
|
|
85
|
+
let currentSessionFile: string | undefined;
|
|
86
|
+
publishSubagentPresetsStartupSection();
|
|
87
|
+
|
|
88
|
+
function refreshSubagentOverlay(): void {
|
|
89
|
+
subagentOverlay.update();
|
|
90
|
+
const liveState = createLiveStatePayload(liveAgents, currentSessionFile);
|
|
91
|
+
pi.events?.emit?.(SUBAGENTS_LIVE_COUNT_EVENT, { count: liveState.count });
|
|
92
|
+
pi.events?.emit?.(SUBAGENTS_LIVE_STATE_EVENT, liveState);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
const handleAgentCompletion: AgentCompletionHandler = ({ runDir, agentId }) => {
|
|
98
|
+
const liveRun = liveAgents.get(runDir);
|
|
99
|
+
liveRun?.delete(agentId);
|
|
100
|
+
if (liveRun?.size === 0) liveAgents.delete(runDir);
|
|
101
|
+
refreshSubagentOverlay();
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
registerSubagentsTool(pi, liveAgents, handleAgentCompletion, refreshSubagentOverlay);
|
|
105
|
+
registerCommands(pi);
|
|
106
|
+
|
|
107
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
108
|
+
sawAutoUltraworkCandidate = false;
|
|
109
|
+
currentSessionFile = sessionFileFromContext(ctx);
|
|
110
|
+
subagentOverlay.restoreRunningAgents(ctx.cwd, currentSessionFile);
|
|
111
|
+
refreshSubagentOverlay();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
pi.on("tool_execution_end", async (event) => {
|
|
115
|
+
if (event.toolName !== "subagents" && !event.toolName.startsWith("async_subagents_")) return;
|
|
116
|
+
refreshSubagentOverlay();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
pi.on("before_agent_start", async (event, ctx) => {
|
|
120
|
+
const strategyPrompt = agentStrategyPrompt({
|
|
121
|
+
modelRef: modelRefFromContext(ctx),
|
|
122
|
+
customPrompt: Boolean(event?.systemPromptOptions?.customPrompt),
|
|
123
|
+
});
|
|
124
|
+
const visionPrompt = visionCapabilityPrompt(event, ctx);
|
|
125
|
+
if (!strategyPrompt && !visionPrompt) return undefined;
|
|
126
|
+
let systemPrompt = event.systemPrompt ?? "";
|
|
127
|
+
if (strategyPrompt) systemPrompt = appendAgentStrategyPrompt(systemPrompt, strategyPrompt);
|
|
128
|
+
if (visionPrompt) systemPrompt = appendAgentStrategyPrompt(systemPrompt, visionPrompt);
|
|
129
|
+
return { systemPrompt };
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
pi.on("input", async (event, ctx) => {
|
|
133
|
+
if (event.source === "extension") return { action: "continue" as const };
|
|
134
|
+
const text = event.text.trim();
|
|
135
|
+
if (!text || text.startsWith("/")) return { action: "continue" as const };
|
|
136
|
+
if (/^run ultrawork mode\b/i.test(text)) return { action: "continue" as const };
|
|
137
|
+
if (isUltraworkEnvEnabled()) {
|
|
138
|
+
return {
|
|
139
|
+
action: "transform" as const,
|
|
140
|
+
text: buildUltraworkPrompt(event.text),
|
|
141
|
+
images: event.images,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (sawAutoUltraworkCandidate || !isUltraworkAutoEnvEnabled()) return { action: "continue" as const };
|
|
146
|
+
sawAutoUltraworkCandidate = true;
|
|
147
|
+
if (isGptLikeModel(modelRefFromContext(ctx))) return { action: "continue" as const };
|
|
148
|
+
|
|
149
|
+
const config = safeLoadSubagentConfig(ctx?.cwd ?? process.cwd());
|
|
150
|
+
if (!config) return { action: "continue" as const };
|
|
151
|
+
const decision = await decideUltraworkAuto(event.text, config, ctx ?? {});
|
|
152
|
+
if (decision === "none") return { action: "continue" as const };
|
|
153
|
+
if (decision === "hint") {
|
|
154
|
+
return {
|
|
155
|
+
action: "transform" as const,
|
|
156
|
+
text: appendUltraworkAutoHint(event.text),
|
|
157
|
+
images: event.images,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
action: "transform" as const,
|
|
162
|
+
text: buildUltraworkPrompt(event.text),
|
|
163
|
+
images: event.images,
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
pi.on("session_shutdown", async (event, ctx) => {
|
|
168
|
+
subagentOverlay.dispose();
|
|
169
|
+
if (event?.reason === "reload" || event?.reason === "fork") return;
|
|
170
|
+
try {
|
|
171
|
+
await cleanupProjectSubagentState(ctx.cwd, liveAgents);
|
|
172
|
+
liveAgents.clear();
|
|
173
|
+
refreshSubagentOverlay();
|
|
174
|
+
} catch {
|
|
175
|
+
// Shutdown cleanup is best-effort and must never block the main session from closing.
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function sessionFileFromContext(ctx: unknown): string | undefined {
|
|
180
|
+
const sessionManager = (ctx as { sessionManager?: { getSessionFile?: unknown } } | undefined)?.sessionManager;
|
|
181
|
+
if (typeof sessionManager?.getSessionFile !== "function") return undefined;
|
|
182
|
+
const sessionFile = sessionManager.getSessionFile();
|
|
183
|
+
return typeof sessionFile === "string" && sessionFile.trim() ? sessionFile : undefined;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function pathsEqual(left: string, right: string): boolean {
|
|
187
|
+
return normalizePath(left) === normalizePath(right);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function normalizePath(filePath: string): string {
|
|
191
|
+
const resolved = path.resolve(filePath);
|
|
192
|
+
try {
|
|
193
|
+
return fs.realpathSync.native(resolved);
|
|
194
|
+
} catch {
|
|
195
|
+
return resolved;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function safeLoadSubagentConfig(cwd: string) {
|
|
200
|
+
try {
|
|
201
|
+
return loadSubagentConfig(cwd);
|
|
202
|
+
} catch {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function startupSubagentPresetList(cwd = process.cwd()): string {
|
|
208
|
+
try {
|
|
209
|
+
const config = loadSubagentConfig(cwd);
|
|
210
|
+
const presets = config.presets ?? {};
|
|
211
|
+
const activePreset = getActiveSubagentPresetName();
|
|
212
|
+
const names = sortedStartupPresetNames(Object.keys(presets), activePreset);
|
|
213
|
+
if (names.length === 0) return "no presets";
|
|
214
|
+
return names.map((name) => formatStartupPresetName(name, activePreset)).join(", ");
|
|
215
|
+
} catch (error) {
|
|
216
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
217
|
+
return `error loading presets: ${message}`;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function sortedStartupPresetNames(names: string[], activePreset?: string): string[] {
|
|
222
|
+
const sorted = names.sort();
|
|
223
|
+
return activePreset && sorted.includes(activePreset)
|
|
224
|
+
? [activePreset, ...sorted.filter((name) => name !== activePreset)]
|
|
225
|
+
: sorted;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function formatStartupPresetName(name: string, activePreset?: string): string {
|
|
229
|
+
return activePreset === name ? underlineText(name) : name;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function underlineText(text: string): string {
|
|
233
|
+
return `\x1b[4m${text}\x1b[24m`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function publishSubagentPresetsStartupSection(): void {
|
|
237
|
+
publishStartupSection({
|
|
238
|
+
id: "async-subagents-presets",
|
|
239
|
+
title: "sub-agent presets (/subagent-preset)",
|
|
240
|
+
body: startupSubagentPresetList(),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function modelRefFromContext(ctx: unknown): string | undefined {
|
|
245
|
+
if (!ctx || typeof ctx !== "object") return undefined;
|
|
246
|
+
const model = (ctx as { model?: unknown }).model;
|
|
247
|
+
if (!model) return undefined;
|
|
248
|
+
if (typeof model === "string") return model;
|
|
249
|
+
if (typeof model === "object") {
|
|
250
|
+
const candidate = model as { provider?: unknown; providerId?: unknown; id?: unknown; model?: unknown; modelId?: unknown; name?: unknown };
|
|
251
|
+
const provider = typeof candidate.provider === "string" ? candidate.provider : typeof candidate.providerId === "string" ? candidate.providerId : undefined;
|
|
252
|
+
const modelId = typeof candidate.modelId === "string"
|
|
253
|
+
? candidate.modelId
|
|
254
|
+
: typeof candidate.id === "string"
|
|
255
|
+
? candidate.id
|
|
256
|
+
: typeof candidate.model === "string"
|
|
257
|
+
? candidate.model
|
|
258
|
+
: typeof candidate.name === "string"
|
|
259
|
+
? candidate.name
|
|
260
|
+
: undefined;
|
|
261
|
+
if (provider && modelId) return `${provider}/${modelId}`;
|
|
262
|
+
return modelId;
|
|
263
|
+
}
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function visionCapabilityPrompt(event: unknown, ctx: unknown): string | undefined {
|
|
268
|
+
const support = parentModelImageSupport(ctx);
|
|
269
|
+
if (support === true) return visionCapableParentPrompt(event);
|
|
270
|
+
if (support !== false) return undefined;
|
|
271
|
+
const imageCount = attachedImageCount(event);
|
|
272
|
+
const subagentsAvailable = selectedToolsInclude(event, "subagents");
|
|
273
|
+
const bridge = subagentsAvailable && imageCount > 0
|
|
274
|
+
? bridgeImageAttachments((ctx as { cwd?: string } | undefined)?.cwd ?? process.cwd(), event)
|
|
275
|
+
: undefined;
|
|
276
|
+
const attachmentWarning = imageCount > 0
|
|
277
|
+
? `This turn includes ${imageCount} attached image(s), but the current parent model cannot inspect them directly.`
|
|
278
|
+
: "The current parent model cannot inspect images/screenshots directly.";
|
|
279
|
+
const delegation = subagentsAvailable
|
|
280
|
+
? visionSubagentDelegationText(bridge?.attachments ?? [])
|
|
281
|
+
: "If visual understanding is required, ask the user to switch to a vision-capable model or provide a path that can be inspected by a vision-capable helper.";
|
|
282
|
+
const bridgeWarning = visionBridgeWarning(bridge);
|
|
283
|
+
return [
|
|
284
|
+
"Vision capability constraint:",
|
|
285
|
+
attachmentWarning,
|
|
286
|
+
"Do not claim to have viewed or understood image contents yourself.",
|
|
287
|
+
bridgeWarning,
|
|
288
|
+
delegation,
|
|
289
|
+
bridge?.attachments.length
|
|
290
|
+
? "Use those bridged paths exactly as imagePaths if delegating."
|
|
291
|
+
: "If an image only arrived as an attachment and no local file path/reference is available to subagents, ask the user for a file path or to switch the parent model to one with image input support.",
|
|
292
|
+
].filter(Boolean).join(" ");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function parentModelImageSupport(ctx: unknown): boolean | undefined {
|
|
296
|
+
const model = (ctx as { model?: unknown } | undefined)?.model;
|
|
297
|
+
const cwd = (ctx as { cwd?: string } | undefined)?.cwd ?? process.cwd();
|
|
298
|
+
const config = safeLoadSubagentConfig(cwd);
|
|
299
|
+
const modelRef = modelRefFromContext(ctx);
|
|
300
|
+
if (config && isBlindModelRef(modelRef, config)) return false;
|
|
301
|
+
return modelImageInputSupport(model) === true ? true : undefined;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function visionCapableParentPrompt(event: unknown): string | undefined {
|
|
305
|
+
if (attachedImageCount(event) === 0 && !promptContainsImagePath(event)) return undefined;
|
|
306
|
+
return [
|
|
307
|
+
"Vision capability note:",
|
|
308
|
+
"The current parent model supports image input.",
|
|
309
|
+
"If the user provided image attachments or local image file paths, inspect them directly first; for local paths, use the read tool on the image path.",
|
|
310
|
+
"Do not delegate to a vision sub-agent solely to gain visual access; use a vision sub-agent only when the user explicitly asks to delegate/parallelize or a separate visual review is useful.",
|
|
311
|
+
].join(" ");
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function visionSubagentDelegationText(attachments: BridgedImageAttachment[]): string {
|
|
315
|
+
if (attachments.length === 0) {
|
|
316
|
+
return "If visual understanding is required, delegate to the subagents tool with subagentType='vision' plus imagePaths/focus when the image is available as a local file path.";
|
|
317
|
+
}
|
|
318
|
+
const imagePaths = attachments.map((attachment) => attachment.relativePath);
|
|
319
|
+
return `Attached images were saved for vision delegation. If visual understanding is required, delegate to the subagents tool with subagentType='vision' and imagePaths=${JSON.stringify(imagePaths)} plus a focused task/focus.`;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function visionBridgeWarning(bridge: BridgeImageAttachmentsResult | undefined): string | undefined {
|
|
323
|
+
if (!bridge) return undefined;
|
|
324
|
+
if (bridge.error) return `Attempted to save attached images for delegation, but failed: ${bridge.error}.`;
|
|
325
|
+
if (bridge.skipped > 0) return `${bridge.skipped} attached image(s) could not be saved because their type or data was unsupported.`;
|
|
326
|
+
return undefined;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function modelImageInputSupport(model: unknown): boolean | undefined {
|
|
330
|
+
if (!model || typeof model !== "object") return undefined;
|
|
331
|
+
const input = (model as { input?: unknown }).input;
|
|
332
|
+
if (!Array.isArray(input)) return undefined;
|
|
333
|
+
return input.some((value) => value === "image");
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function attachedImageCount(event: unknown): number {
|
|
337
|
+
const images = (event as { images?: unknown } | undefined)?.images;
|
|
338
|
+
return Array.isArray(images) ? images.length : 0;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function promptContainsImagePath(event: unknown): boolean {
|
|
342
|
+
const prompt = (event as { prompt?: unknown } | undefined)?.prompt;
|
|
343
|
+
return typeof prompt === "string" && /(?:^|\s)(?:\.?\.?\/|~\/|\/)[^\s]+\.(?:png|jpe?g|gif|webp)\b/i.test(prompt);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function selectedToolsInclude(event: unknown, toolName: string): boolean {
|
|
347
|
+
const selectedTools = (event as { systemPromptOptions?: { selectedTools?: unknown } } | undefined)?.systemPromptOptions?.selectedTools;
|
|
348
|
+
return !Array.isArray(selectedTools) || selectedTools.includes(toolName);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async function cleanupProjectSubagentState(cwd: string, liveAgents: Map<string, Map<string, LiveAgent>>): Promise<void> {
|
|
352
|
+
const shutdownTargets = collectShutdownTargets(cwd, liveAgents);
|
|
353
|
+
const signaled = signalShutdownTargets(shutdownTargets, "SIGTERM");
|
|
354
|
+
if (signaled > 0) await sleep(SESSION_SHUTDOWN_KILL_GRACE_MS);
|
|
355
|
+
signalShutdownTargets(shutdownTargets, "SIGKILL");
|
|
356
|
+
|
|
357
|
+
const runDirs = listRunDirs(cwd);
|
|
358
|
+
for (const runDir of runDirs) stopRunBestEffort(runDir, undefined, "SIGKILL");
|
|
359
|
+
deleteRunDirs(runDirs);
|
|
360
|
+
removeSubagentRunsFromRegistry(cwd, runDirs);
|
|
361
|
+
removeEmptySubagentState(cwd);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function collectShutdownTargets(cwd: string, liveAgents: Map<string, Map<string, LiveAgent>>): ShutdownTarget[] {
|
|
365
|
+
const targets = new Map<string, Set<string> | undefined>();
|
|
366
|
+
for (const runDir of listRunDirs(cwd)) targets.set(runDir, undefined);
|
|
367
|
+
for (const [runDir, liveRun] of liveAgents) {
|
|
368
|
+
const existing = targets.get(runDir);
|
|
369
|
+
if (existing === undefined && targets.has(runDir)) continue;
|
|
370
|
+
targets.set(runDir, new Set(liveRun.keys()));
|
|
371
|
+
}
|
|
372
|
+
return [...targets].map(([runDir, agentIds]) => ({
|
|
373
|
+
runDir,
|
|
374
|
+
...(agentIds ? { agentIds: [...agentIds] } : {}),
|
|
375
|
+
}));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function signalShutdownTargets(targets: ShutdownTarget[], signal: StopSignal): number {
|
|
379
|
+
let signaled = 0;
|
|
380
|
+
for (const target of targets) {
|
|
381
|
+
try {
|
|
382
|
+
const state = getRunState(target.runDir, target.agentIds);
|
|
383
|
+
for (const agent of state.agents) {
|
|
384
|
+
if (agent.status !== "running" || !agent.pid || agent.pid <= 0) continue;
|
|
385
|
+
try {
|
|
386
|
+
process.kill(agent.pid, signal);
|
|
387
|
+
signaled += 1;
|
|
388
|
+
} catch {
|
|
389
|
+
// Process may have exited between status read and signal delivery.
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
} catch {
|
|
393
|
+
// Keep shutdown best-effort even when run state cannot be read.
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return signaled;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function sleep(ms: number): Promise<void> {
|
|
400
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function stopRunBestEffort(runDir: string, agentIds: string[] | undefined, signal: StopSignal): void {
|
|
404
|
+
try {
|
|
405
|
+
stopAgents(runDir, agentIds, { signal });
|
|
406
|
+
} catch {
|
|
407
|
+
// Keep cleanup best-effort even if a process is already gone or cannot be signaled.
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function removeEmptySubagentState(cwd: string): void {
|
|
412
|
+
removeImageAttachmentBridgeState(cwd);
|
|
413
|
+
const registry = loadSubagentRegistry(cwd);
|
|
414
|
+
if (Object.keys(registry.runs).length === 0 && Object.keys(registry.agents).length === 0) {
|
|
415
|
+
fs.rmSync(getSubagentRegistryPath(cwd), { force: true });
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
fs.rmdirSync(getRunRoot(cwd));
|
|
419
|
+
} catch {
|
|
420
|
+
// Leave non-empty or concurrently used state intact.
|
|
421
|
+
}
|
|
422
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
AgentCompletionHandler,
|
|
3
|
+
AgentResult,
|
|
4
|
+
AgentState,
|
|
5
|
+
AgentTask,
|
|
6
|
+
RetryConfig,
|
|
7
|
+
RpcEventHandler,
|
|
8
|
+
RpcEventRecord,
|
|
9
|
+
RunState,
|
|
10
|
+
SpawnedAgent,
|
|
11
|
+
StructuredResult,
|
|
12
|
+
} from "./core/types.js";
|
|
13
|
+
|
|
14
|
+
export { createRunDir, getRunRoot, resolveRunDir, validateBasename } from "./core/paths.js";
|
|
15
|
+
export type { CopySubagentConfigSampleResult, ResolvedAgentTaskConfig, ResolvedSubagentRoutingConfig, ResolveAgentTaskOptions, SubagentConfig, SubagentPreset, SubagentRoutingConfig, SubagentTypeConfig, SubagentVisionConfig } from "./core/config.js";
|
|
16
|
+
export {
|
|
17
|
+
configFiles,
|
|
18
|
+
copySubagentConfigSample,
|
|
19
|
+
currentModelRef,
|
|
20
|
+
defaultSubagentType,
|
|
21
|
+
DEFAULT_MAX_CONCURRENT,
|
|
22
|
+
DEFAULT_RETRY_CONFIG,
|
|
23
|
+
DEFAULT_ROUTING_CONFIG,
|
|
24
|
+
existingSubagentConfigFiles,
|
|
25
|
+
getDefaultSubagentConfigPath,
|
|
26
|
+
getSubagentConfigInitTargetPath,
|
|
27
|
+
getSubagentConfigSamplePath,
|
|
28
|
+
isBlindModelRef,
|
|
29
|
+
loadSubagentConfig,
|
|
30
|
+
resolveAgentTaskConfig,
|
|
31
|
+
resolveRetryConfig,
|
|
32
|
+
resolveSubagentRoutingConfig,
|
|
33
|
+
selectSubagentType,
|
|
34
|
+
shouldForceCurrentSubagentModel,
|
|
35
|
+
} from "./core/config.js";
|
|
36
|
+
export { routeSubagentTasks } from "./core/routing.js";
|
|
37
|
+
export type { RoutedSubagentTasks, SubagentRoutingContext } from "./core/routing.js";
|
|
38
|
+
export type { SubagentPresetSelectionState } from "./core/presets.js";
|
|
39
|
+
export { getActiveSubagentPresetName, getSessionSubagentPresetOverride, getSubagentPresetSelectionPath, loadSubagentPresetSelection, saveSubagentPresetSelection, setActiveSubagentPreset, setSessionSubagentPresetOverride } from "./core/presets.js";
|
|
40
|
+
export { isQuotaLimitCompletion, nextFallbackModel, rememberSessionModelFallback, resetSessionModelFallbacks, selectSessionModelWithFallback } from "./core/model-fallback.js";
|
|
41
|
+
export type { SessionModelFallbackSelection } from "./core/model-fallback.js";
|
|
42
|
+
export { generatePrompt, writePromptFile } from "./core/prompt.js";
|
|
43
|
+
export { getPiInvocation } from "./core/pi-invocation.js";
|
|
44
|
+
export {
|
|
45
|
+
findLatestSubagentRunDir,
|
|
46
|
+
findSubagentRunDirsForAgent,
|
|
47
|
+
getSubagentRegistryPath,
|
|
48
|
+
listSubagentRunDirs,
|
|
49
|
+
loadSubagentRegistry,
|
|
50
|
+
recordSubagentRun,
|
|
51
|
+
removeSubagentRunsFromRegistry,
|
|
52
|
+
resolveSubagentAgentRunDir,
|
|
53
|
+
resolveSubagentRunDir,
|
|
54
|
+
saveSubagentRegistry,
|
|
55
|
+
SUBAGENT_REGISTRY_FILE,
|
|
56
|
+
} from "./core/registry.js";
|
|
57
|
+
export type { SubagentRegistry, SubagentRegistryAgent, SubagentRegistryRun } from "./core/registry.js";
|
|
58
|
+
export { DEFAULT_AGENT_TIMEOUT_MS, shouldPersistSubagentSessions, spawnAgent } from "./core/spawn.js";
|
|
59
|
+
export { getAgentState, getRunState, readResult, waitForAgents } from "./core/state.js";
|
|
60
|
+
export { stopAgents, validateStopSignal } from "./core/stop.js";
|
|
61
|
+
export type { StopAgentResult, StopSignal } from "./core/stop.js";
|
|
62
|
+
export { cleanupCompletedRuns, deleteCleanupCandidates, deleteRunDirs, findCleanupCandidates } from "./core/cleanup.js";
|
|
63
|
+
export { createSemaphore } from "./core/concurrency.js";
|
|
64
|
+
export type { Semaphore } from "./core/concurrency.js";
|
|
65
|
+
export { spawnAgentWithRetry } from "./core/retry.js";
|
|
66
|
+
export type { RetryableSpawnOptions } from "./core/retry.js";
|
|
67
|
+
export { buildStructuredResult, readStructuredResult, writeStructuredResult } from "./core/structured-result.js";
|
|
68
|
+
export type { WriteStructuredResultOptions } from "./core/structured-result.js";
|
|
69
|
+
export { DEFAULT_DEBUG_EVENTS_LOG_MAX_BYTES, DEFAULT_EVENTS_LOG_MAX_BYTES, DEFAULT_RPC_EVENT_LINE_MAX_CHARS, DEFAULT_STDERR_LOG_MAX_BYTES, resolveSubagentLogLimits } from "./core/log-limits.js";
|
|
70
|
+
export type { BoundedFileWriter, DeferredFileWriter, SubagentLogLimits } from "./core/log-limits.js";
|
|
71
|
+
export {
|
|
72
|
+
ensureSessionFileLink,
|
|
73
|
+
findLatestSessionFile,
|
|
74
|
+
findSubagentSessionByFile,
|
|
75
|
+
getAgentSessionDir,
|
|
76
|
+
listRunDirs,
|
|
77
|
+
listSubagentSessionRecords,
|
|
78
|
+
readParentSessionLink,
|
|
79
|
+
readReturnSessionLink,
|
|
80
|
+
readSessionFileLink,
|
|
81
|
+
SUBAGENT_PARENT_SESSION_FILE,
|
|
82
|
+
SUBAGENT_RETURN_SESSION_FILE,
|
|
83
|
+
SUBAGENT_SESSION_FILE,
|
|
84
|
+
writeParentSessionLink,
|
|
85
|
+
writeReturnSessionLink,
|
|
86
|
+
writeSessionFileLink,
|
|
87
|
+
} from "./core/sessions.js";
|
|
88
|
+
export type { SubagentSessionRecord } from "./core/sessions.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { LiveAgent } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export function getLiveRun(liveAgents: Map<string, Map<string, LiveAgent>>, runDir: string): Map<string, LiveAgent> {
|
|
4
|
+
let run = liveAgents.get(runDir);
|
|
5
|
+
if (!run) {
|
|
6
|
+
run = new Map();
|
|
7
|
+
liveAgents.set(runDir, run);
|
|
8
|
+
}
|
|
9
|
+
return run;
|
|
10
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { AgentState, RunState } from "./lib.js";
|
|
2
|
+
import { getRunState } from "./lib.js";
|
|
3
|
+
import { DEFAULT_SPAWN_WATCH_SECONDS, DEFAULT_UPDATE_INTERVAL_SECONDS, MAX_WATCH_SECONDS } from "./constants.js";
|
|
4
|
+
import { renderPlainRunSummary } from "./render.js";
|
|
5
|
+
import type { SubagentRunRenderDetails, TextToolUpdate } from "./types.js";
|
|
6
|
+
|
|
7
|
+
function isTerminalAgent(agent: AgentState): boolean {
|
|
8
|
+
return agent.status === "done" || agent.status === "failed" || agent.status === "stopped";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isRunTerminal(state: RunState, failFast: boolean): boolean {
|
|
12
|
+
if (state.agents.length === 0) return true;
|
|
13
|
+
if (failFast && state.agents.some((agent) => agent.status === "failed" || agent.status === "stopped")) return true;
|
|
14
|
+
return state.agents.every(isTerminalAgent);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function clampWatchSeconds(value: unknown, fallback = DEFAULT_SPAWN_WATCH_SECONDS): number {
|
|
18
|
+
const seconds = typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
19
|
+
return Math.max(0, Math.min(MAX_WATCH_SECONDS, seconds));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function emitRunUpdate(
|
|
23
|
+
onUpdate: ((partialResult: TextToolUpdate) => void) | undefined,
|
|
24
|
+
details: SubagentRunRenderDetails,
|
|
25
|
+
): void {
|
|
26
|
+
onUpdate?.({
|
|
27
|
+
content: [{ type: "text", text: renderPlainRunSummary(details) }],
|
|
28
|
+
details,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function sleepWithAbort(ms: number, signal?: AbortSignal): Promise<void> {
|
|
33
|
+
if (ms <= 0 || signal?.aborted) return;
|
|
34
|
+
await new Promise<void>((resolve) => {
|
|
35
|
+
let timeout: NodeJS.Timeout | undefined;
|
|
36
|
+
const abort = () => {
|
|
37
|
+
if (timeout) clearTimeout(timeout);
|
|
38
|
+
signal?.removeEventListener("abort", abort);
|
|
39
|
+
resolve();
|
|
40
|
+
};
|
|
41
|
+
timeout = setTimeout(() => {
|
|
42
|
+
signal?.removeEventListener("abort", abort);
|
|
43
|
+
resolve();
|
|
44
|
+
}, ms);
|
|
45
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export async function pollRunWithUpdates(
|
|
50
|
+
runDir: string,
|
|
51
|
+
agentIds: string[] | undefined,
|
|
52
|
+
options: {
|
|
53
|
+
mode: SubagentRunRenderDetails["mode"];
|
|
54
|
+
tasks?: SubagentRunRenderDetails["tasks"];
|
|
55
|
+
timeoutSeconds: number;
|
|
56
|
+
intervalSeconds?: number;
|
|
57
|
+
failFast?: boolean;
|
|
58
|
+
signal?: AbortSignal;
|
|
59
|
+
onUpdate?: (partialResult: TextToolUpdate) => void;
|
|
60
|
+
},
|
|
61
|
+
): Promise<RunState> {
|
|
62
|
+
const start = Date.now();
|
|
63
|
+
const intervalMs = Math.max(250, (options.intervalSeconds ?? DEFAULT_UPDATE_INTERVAL_SECONDS) * 1000);
|
|
64
|
+
const timeoutMs = Math.max(0, options.timeoutSeconds * 1000);
|
|
65
|
+
let state = getRunState(runDir, agentIds);
|
|
66
|
+
|
|
67
|
+
while (true) {
|
|
68
|
+
state = getRunState(runDir, agentIds);
|
|
69
|
+
emitRunUpdate(options.onUpdate, {
|
|
70
|
+
runDir,
|
|
71
|
+
agents: state.agents,
|
|
72
|
+
tasks: options.tasks,
|
|
73
|
+
mode: options.mode,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (isRunTerminal(state, options.failFast ?? false)) return state;
|
|
77
|
+
if (options.signal?.aborted) return state;
|
|
78
|
+
const elapsedMs = Date.now() - start;
|
|
79
|
+
if (elapsedMs >= timeoutMs) return state;
|
|
80
|
+
|
|
81
|
+
await sleepWithAbort(Math.min(intervalMs, timeoutMs - elapsedMs), options.signal);
|
|
82
|
+
}
|
|
83
|
+
}
|