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,486 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Types
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
import type { DcpNudgeType } from "./pruner-types.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A record of a single tool call, keyed by toolCallId in DcpState.toolCalls.
|
|
9
|
+
*/
|
|
10
|
+
export interface ToolRecord {
|
|
11
|
+
/** Matches ToolResultMessage.toolCallId */
|
|
12
|
+
toolCallId: string
|
|
13
|
+
/** Matches ToolResultMessage.toolName */
|
|
14
|
+
toolName: string
|
|
15
|
+
/** The arguments passed to the tool (from the corresponding ToolCall) */
|
|
16
|
+
inputArgs: Record<string, unknown>
|
|
17
|
+
/**
|
|
18
|
+
* Deduplication fingerprint: `toolName::JSON(sortedArgs)`
|
|
19
|
+
* Two calls with the same name + identical args share the same fingerprint.
|
|
20
|
+
*/
|
|
21
|
+
inputFingerprint: string
|
|
22
|
+
/** Whether the tool result was an error */
|
|
23
|
+
isError: boolean
|
|
24
|
+
/**
|
|
25
|
+
* Zero-based index of the user turn during which this tool was called.
|
|
26
|
+
* Incremented each time a user message is encountered in the context stream.
|
|
27
|
+
*/
|
|
28
|
+
turnIndex: number
|
|
29
|
+
/** message.timestamp from the ToolResultMessage */
|
|
30
|
+
timestamp: number
|
|
31
|
+
/** Rough token estimate: sum of result text content lengths divided by 4 */
|
|
32
|
+
tokenEstimate: number
|
|
33
|
+
/** Completed textual tool output captured for protected-summary preservation. */
|
|
34
|
+
outputText?: string
|
|
35
|
+
/** Optional tool-specific result details captured for protected-summary preservation. */
|
|
36
|
+
outputDetails?: unknown
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface MessageIdMeta {
|
|
40
|
+
/** The actual message.timestamp associated with the visible DCP id. */
|
|
41
|
+
timestamp: number
|
|
42
|
+
/** Stable raw message key when available; falls back to timestamp-derived key. */
|
|
43
|
+
stableId?: string
|
|
44
|
+
/** The message role at the time the id was injected. */
|
|
45
|
+
role: string
|
|
46
|
+
/** Present when this visible message represents an active compression block. */
|
|
47
|
+
blockId?: number
|
|
48
|
+
/** Tool call metadata for tool-result-like messages. */
|
|
49
|
+
toolCallId?: string
|
|
50
|
+
toolName?: string
|
|
51
|
+
/** Plain text extracted from the message when the id was injected. */
|
|
52
|
+
text?: string
|
|
53
|
+
/** Rough token estimate for priority/candidate guidance. */
|
|
54
|
+
tokenEstimate?: number
|
|
55
|
+
/** Optional compression priority marker exposed with the visible message ID. */
|
|
56
|
+
priority?: "low" | "medium" | "high"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A compression block created by the `compress` tool.
|
|
61
|
+
* Tracks the range of messages that were summarised and where to inject the
|
|
62
|
+
* summary back into the context.
|
|
63
|
+
*/
|
|
64
|
+
export interface CompressionBlock {
|
|
65
|
+
/** Auto-incrementing integer ID */
|
|
66
|
+
id: number
|
|
67
|
+
/** Short human-readable topic label */
|
|
68
|
+
topic: string
|
|
69
|
+
/** LLM-generated summary text */
|
|
70
|
+
summary: string
|
|
71
|
+
/** Timestamp of the first message in the compressed range */
|
|
72
|
+
startTimestamp: number
|
|
73
|
+
/** Timestamp of the last message in the compressed range */
|
|
74
|
+
endTimestamp: number
|
|
75
|
+
/** Stable key of the first raw message when known. */
|
|
76
|
+
startMessageId?: string
|
|
77
|
+
/** Stable key of the last raw message when known. */
|
|
78
|
+
endMessageId?: string
|
|
79
|
+
/**
|
|
80
|
+
* Timestamp of the first message *after* the range — the summary is injected
|
|
81
|
+
* immediately before this message. Set to `Infinity` when the range extends
|
|
82
|
+
* to the end of the conversation.
|
|
83
|
+
*/
|
|
84
|
+
anchorTimestamp: number
|
|
85
|
+
/** Stable key of the raw message immediately after the range when known. */
|
|
86
|
+
anchorMessageId?: string
|
|
87
|
+
/** Tool call ID of the compress invocation that created this block. */
|
|
88
|
+
createdByToolCallId?: string
|
|
89
|
+
/** Whether this block is still being applied (false = soft-deleted) */
|
|
90
|
+
active: boolean
|
|
91
|
+
/** Token estimate for the summary text itself */
|
|
92
|
+
summaryTokenEstimate: number
|
|
93
|
+
/** Wall-clock time the block was created (Date.now()) */
|
|
94
|
+
createdAt: number
|
|
95
|
+
/** Older compression blocks subsumed by this block during roll-up. */
|
|
96
|
+
coveredBlockIds?: number[]
|
|
97
|
+
/** Whether this block was created from a range or a single raw message. */
|
|
98
|
+
mode?: "range" | "message"
|
|
99
|
+
/** Set when a user explicitly decompressed this block via /dcp decompress. */
|
|
100
|
+
deactivatedByUser?: boolean
|
|
101
|
+
/** Internal reason for automatic soft-deactivation. */
|
|
102
|
+
deactivatedReason?: string
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface DcpNudgeAnchor {
|
|
106
|
+
/** Monotonic local identifier for persisted reminder anchors. */
|
|
107
|
+
id: number
|
|
108
|
+
/** Kind of reminder that should be re-injected at this anchor. */
|
|
109
|
+
type: DcpNudgeType
|
|
110
|
+
/** Timestamp of the message that owns the reminder. */
|
|
111
|
+
anchorTimestamp: number
|
|
112
|
+
/** Stable raw message key for the anchor when available. */
|
|
113
|
+
anchorStableId?: string
|
|
114
|
+
/** Role of the anchored message at creation time. */
|
|
115
|
+
anchorRole: string
|
|
116
|
+
/** User turn index at creation time. */
|
|
117
|
+
turnIndex: number
|
|
118
|
+
/** Approximate context usage that triggered the reminder, as a 0-1 fraction. */
|
|
119
|
+
contextPercent?: number
|
|
120
|
+
/** Wall-clock creation time. */
|
|
121
|
+
createdAt: number
|
|
122
|
+
/** Wall-clock time of the latest re-application/update. */
|
|
123
|
+
updatedAt: number
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface DcpLastNudge {
|
|
127
|
+
type: DcpNudgeType
|
|
128
|
+
anchorId: number
|
|
129
|
+
anchorTimestamp: number
|
|
130
|
+
anchorStableId?: string
|
|
131
|
+
contextPercent?: number
|
|
132
|
+
createdAt: number
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Full runtime state for the DCP extension.
|
|
137
|
+
*/
|
|
138
|
+
export interface DcpState {
|
|
139
|
+
// ── Tool tracking ──────────────────────────────────────────────────────────
|
|
140
|
+
/** toolCallId → ToolRecord, populated when a tool_result event fires */
|
|
141
|
+
toolCalls: Map<string, ToolRecord>
|
|
142
|
+
/** Set of toolCallIds whose result messages should be suppressed in context */
|
|
143
|
+
prunedToolIds: Set<string>
|
|
144
|
+
/** toolCallId → reason used for human-readable pruning placeholders/stats. */
|
|
145
|
+
prunedToolReasons: Map<string, string>
|
|
146
|
+
|
|
147
|
+
// ── Compression ────────────────────────────────────────────────────────────
|
|
148
|
+
/** All compression blocks (both active and soft-deleted) */
|
|
149
|
+
compressionBlocks: CompressionBlock[]
|
|
150
|
+
/** Monotonically increasing counter used to assign CompressionBlock.id */
|
|
151
|
+
nextBlockId: number
|
|
152
|
+
|
|
153
|
+
// ── Message ID snapshot ────────────────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Maps the short LLM-visible message IDs (e.g. "m001") to the actual
|
|
156
|
+
* `timestamp` of that message as seen in the last `context` event.
|
|
157
|
+
*
|
|
158
|
+
* The `compress` tool receives ID strings from the LLM; this map lets us
|
|
159
|
+
* translate them back to real timestamps so compression blocks can reference
|
|
160
|
+
* message positions by timestamp (which is stable across pruning passes).
|
|
161
|
+
*/
|
|
162
|
+
messageIdSnapshot: Map<string, number>
|
|
163
|
+
/** Extra metadata for the visible DCP message IDs in messageIdSnapshot. */
|
|
164
|
+
messageMetaSnapshot: Map<string, MessageIdMeta>
|
|
165
|
+
|
|
166
|
+
// ── Turn tracking ──────────────────────────────────────────────────────────
|
|
167
|
+
/**
|
|
168
|
+
* Zero-based index of the current user turn.
|
|
169
|
+
* Incremented each time a user message is encountered while processing the
|
|
170
|
+
* context array in the `context` event handler.
|
|
171
|
+
*/
|
|
172
|
+
currentTurn: number
|
|
173
|
+
|
|
174
|
+
// ── Statistics ─────────────────────────────────────────────────────────────
|
|
175
|
+
/** Running total of tokens estimated to have been saved by pruning/compression */
|
|
176
|
+
tokensSaved: number
|
|
177
|
+
/** Number of discrete pruning operations performed */
|
|
178
|
+
totalPruneCount: number
|
|
179
|
+
/** Compression block IDs already counted in tokensSaved/totalPruneCount. */
|
|
180
|
+
accountedCompressionBlockIds: Set<number>
|
|
181
|
+
/** compressionBlockId → raw active-token savings estimate for that block. */
|
|
182
|
+
compressionTokenSavings: Map<number, number>
|
|
183
|
+
/** Tool result IDs already counted in tokensSaved/totalPruneCount. */
|
|
184
|
+
accountedPrunedToolIds: Set<string>
|
|
185
|
+
// ── Mode ───────────────────────────────────────────────────────────────────
|
|
186
|
+
/**
|
|
187
|
+
* When true, the extension will not autonomously emit compress nudges.
|
|
188
|
+
* Automatic deduplication/error-purge strategies may still run depending on
|
|
189
|
+
* the `manualMode.automaticStrategies` config flag.
|
|
190
|
+
*/
|
|
191
|
+
manualMode: boolean
|
|
192
|
+
|
|
193
|
+
// ── Nudge state ────────────────────────────────────────────────────────────
|
|
194
|
+
/**
|
|
195
|
+
* How many `context` events have fired since the last compress nudge was
|
|
196
|
+
* emitted. Reset to 0 after each nudge.
|
|
197
|
+
*/
|
|
198
|
+
nudgeCounter: number
|
|
199
|
+
/**
|
|
200
|
+
* The value of `currentTurn` at the time the last nudge was emitted.
|
|
201
|
+
* Kept as diagnostic/session state only. Nudges are intentionally not
|
|
202
|
+
* throttled to once per user turn: long autonomous work loops can consume a
|
|
203
|
+
* lot of context before the next user message, so nudgeFrequency must be able
|
|
204
|
+
* to emit repeated reminders inside the same turn.
|
|
205
|
+
*/
|
|
206
|
+
lastNudgeTurn: number
|
|
207
|
+
/** Persisted anchors where active reminders are injected until compression happens. */
|
|
208
|
+
nudgeAnchors: DcpNudgeAnchor[]
|
|
209
|
+
/** Next monotonic anchor ID. */
|
|
210
|
+
nextNudgeAnchorId: number
|
|
211
|
+
/** Diagnostic/telemetry snapshot for the latest emitted reminder. */
|
|
212
|
+
lastNudge?: DcpLastNudge
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
// Factory functions
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
|
|
219
|
+
/** Create a fresh, zeroed DcpState instance. */
|
|
220
|
+
export function createState(): DcpState {
|
|
221
|
+
return {
|
|
222
|
+
toolCalls: new Map(),
|
|
223
|
+
prunedToolIds: new Set(),
|
|
224
|
+
prunedToolReasons: new Map(),
|
|
225
|
+
compressionBlocks: [],
|
|
226
|
+
nextBlockId: 1,
|
|
227
|
+
messageIdSnapshot: new Map(),
|
|
228
|
+
messageMetaSnapshot: new Map(),
|
|
229
|
+
currentTurn: 0,
|
|
230
|
+
tokensSaved: 0,
|
|
231
|
+
totalPruneCount: 0,
|
|
232
|
+
accountedCompressionBlockIds: new Set(),
|
|
233
|
+
compressionTokenSavings: new Map(),
|
|
234
|
+
accountedPrunedToolIds: new Set(),
|
|
235
|
+
manualMode: false,
|
|
236
|
+
nudgeCounter: 0,
|
|
237
|
+
lastNudgeTurn: -1,
|
|
238
|
+
nudgeAnchors: [],
|
|
239
|
+
nextNudgeAnchorId: 1,
|
|
240
|
+
lastNudge: undefined,
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Reset `state` back to its initial values **in-place**.
|
|
246
|
+
* Preserves the object reference so other modules holding a reference see the
|
|
247
|
+
* reset immediately.
|
|
248
|
+
*/
|
|
249
|
+
export function resetState(state: DcpState): void {
|
|
250
|
+
state.toolCalls.clear()
|
|
251
|
+
state.prunedToolIds.clear()
|
|
252
|
+
state.prunedToolReasons.clear()
|
|
253
|
+
state.compressionBlocks = []
|
|
254
|
+
state.nextBlockId = 1
|
|
255
|
+
state.messageIdSnapshot.clear()
|
|
256
|
+
state.messageMetaSnapshot.clear()
|
|
257
|
+
state.currentTurn = 0
|
|
258
|
+
state.tokensSaved = 0
|
|
259
|
+
state.totalPruneCount = 0
|
|
260
|
+
state.accountedCompressionBlockIds.clear()
|
|
261
|
+
state.compressionTokenSavings.clear()
|
|
262
|
+
state.accountedPrunedToolIds.clear()
|
|
263
|
+
state.manualMode = false
|
|
264
|
+
state.nudgeCounter = 0
|
|
265
|
+
state.lastNudgeTurn = -1
|
|
266
|
+
state.nudgeAnchors = []
|
|
267
|
+
state.nextNudgeAnchorId = 1
|
|
268
|
+
state.lastNudge = undefined
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface SerializedDcpState {
|
|
272
|
+
compressionBlocks: CompressionBlock[]
|
|
273
|
+
nextBlockId: number
|
|
274
|
+
prunedToolIds: string[]
|
|
275
|
+
prunedToolReasons: Array<[string, string]>
|
|
276
|
+
toolCalls: ToolRecord[]
|
|
277
|
+
tokensSaved: number
|
|
278
|
+
totalPruneCount: number
|
|
279
|
+
accountedCompressionBlockIds: number[]
|
|
280
|
+
compressionTokenSavings: Array<[number, number]>
|
|
281
|
+
accountedPrunedToolIds: string[]
|
|
282
|
+
manualMode: boolean
|
|
283
|
+
nudgeAnchors?: DcpNudgeAnchor[]
|
|
284
|
+
nextNudgeAnchorId?: number
|
|
285
|
+
lastNudge?: DcpLastNudge
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function isToolRecord(value: unknown): value is ToolRecord {
|
|
289
|
+
if (!value || typeof value !== "object") return false
|
|
290
|
+
const record = value as Partial<ToolRecord>
|
|
291
|
+
return (
|
|
292
|
+
typeof record.toolCallId === "string" &&
|
|
293
|
+
typeof record.toolName === "string" &&
|
|
294
|
+
typeof record.inputFingerprint === "string"
|
|
295
|
+
)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function isNudgeAnchor(value: unknown): value is DcpNudgeAnchor {
|
|
299
|
+
if (!value || typeof value !== "object") return false
|
|
300
|
+
const anchor = value as Partial<DcpNudgeAnchor>
|
|
301
|
+
return (
|
|
302
|
+
typeof anchor.id === "number" &&
|
|
303
|
+
typeof anchor.type === "string" &&
|
|
304
|
+
Number.isFinite(anchor.anchorTimestamp) &&
|
|
305
|
+
typeof anchor.anchorRole === "string" &&
|
|
306
|
+
typeof anchor.turnIndex === "number" &&
|
|
307
|
+
typeof anchor.createdAt === "number" &&
|
|
308
|
+
typeof anchor.updatedAt === "number"
|
|
309
|
+
)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function isLastNudge(value: unknown): value is DcpLastNudge {
|
|
313
|
+
if (!value || typeof value !== "object") return false
|
|
314
|
+
const nudge = value as Partial<DcpLastNudge>
|
|
315
|
+
return (
|
|
316
|
+
typeof nudge.type === "string" &&
|
|
317
|
+
typeof nudge.anchorId === "number" &&
|
|
318
|
+
Number.isFinite(nudge.anchorTimestamp) &&
|
|
319
|
+
typeof nudge.createdAt === "number"
|
|
320
|
+
)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Serialize runtime state into a JSON-safe object for pi.appendEntry(). */
|
|
324
|
+
export function serializeState(state: DcpState): SerializedDcpState {
|
|
325
|
+
return {
|
|
326
|
+
compressionBlocks: state.compressionBlocks,
|
|
327
|
+
nextBlockId: state.nextBlockId,
|
|
328
|
+
prunedToolIds: Array.from(state.prunedToolIds),
|
|
329
|
+
prunedToolReasons: Array.from(state.prunedToolReasons.entries()),
|
|
330
|
+
toolCalls: Array.from(state.toolCalls.values()),
|
|
331
|
+
tokensSaved: state.tokensSaved,
|
|
332
|
+
totalPruneCount: state.totalPruneCount,
|
|
333
|
+
accountedCompressionBlockIds: Array.from(state.accountedCompressionBlockIds),
|
|
334
|
+
compressionTokenSavings: Array.from(state.compressionTokenSavings.entries()),
|
|
335
|
+
accountedPrunedToolIds: Array.from(state.accountedPrunedToolIds),
|
|
336
|
+
manualMode: state.manualMode,
|
|
337
|
+
nudgeAnchors: state.nudgeAnchors,
|
|
338
|
+
nextNudgeAnchorId: state.nextNudgeAnchorId,
|
|
339
|
+
lastNudge: state.lastNudge,
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Restore persisted DCP state into an already-reset state object.
|
|
345
|
+
* Handles older persisted payloads that did not include the newer accounting
|
|
346
|
+
* and tool-call fingerprint fields.
|
|
347
|
+
*/
|
|
348
|
+
export function restoreState(state: DcpState, data: unknown): void {
|
|
349
|
+
if (!data || typeof data !== "object") return
|
|
350
|
+
const saved = data as Partial<SerializedDcpState>
|
|
351
|
+
|
|
352
|
+
if (Array.isArray(saved.compressionBlocks)) {
|
|
353
|
+
const validBlocks = saved.compressionBlocks
|
|
354
|
+
.filter((b: any) => Number.isFinite(b?.startTimestamp) && Number.isFinite(b?.endTimestamp))
|
|
355
|
+
.map((b: any) => ({
|
|
356
|
+
...b,
|
|
357
|
+
anchorTimestamp: Number.isFinite(b.anchorTimestamp)
|
|
358
|
+
? b.anchorTimestamp
|
|
359
|
+
: b.endTimestamp + 1,
|
|
360
|
+
})) as CompressionBlock[]
|
|
361
|
+
state.compressionBlocks = validBlocks
|
|
362
|
+
state.nextBlockId =
|
|
363
|
+
typeof saved.nextBlockId === "number"
|
|
364
|
+
? saved.nextBlockId
|
|
365
|
+
: validBlocks.length > 0
|
|
366
|
+
? Math.max(0, ...validBlocks.map((b) => b.id)) + 1
|
|
367
|
+
: 1
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (Array.isArray(saved.prunedToolIds)) {
|
|
371
|
+
state.prunedToolIds = new Set(saved.prunedToolIds.filter((id): id is string => typeof id === "string"))
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (Array.isArray(saved.prunedToolReasons)) {
|
|
375
|
+
state.prunedToolReasons = new Map(
|
|
376
|
+
saved.prunedToolReasons.filter(
|
|
377
|
+
(entry): entry is [string, string] =>
|
|
378
|
+
Array.isArray(entry) && typeof entry[0] === "string" && typeof entry[1] === "string",
|
|
379
|
+
),
|
|
380
|
+
)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (Array.isArray(saved.toolCalls)) {
|
|
384
|
+
state.toolCalls = new Map(
|
|
385
|
+
saved.toolCalls
|
|
386
|
+
.filter(isToolRecord)
|
|
387
|
+
.map((record) => [record.toolCallId, record] as const),
|
|
388
|
+
)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (typeof saved.tokensSaved === "number") state.tokensSaved = saved.tokensSaved
|
|
392
|
+
if (typeof saved.totalPruneCount === "number") state.totalPruneCount = saved.totalPruneCount
|
|
393
|
+
|
|
394
|
+
if (Array.isArray(saved.accountedCompressionBlockIds)) {
|
|
395
|
+
state.accountedCompressionBlockIds = new Set(
|
|
396
|
+
saved.accountedCompressionBlockIds.filter((id): id is number => typeof id === "number"),
|
|
397
|
+
)
|
|
398
|
+
} else {
|
|
399
|
+
// Old payloads already persisted aggregate stats but not per-block accounting.
|
|
400
|
+
// Treat existing active blocks as accounted to avoid inflated stats after reload.
|
|
401
|
+
state.accountedCompressionBlockIds = new Set(state.compressionBlocks.map((b) => b.id))
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (Array.isArray(saved.compressionTokenSavings)) {
|
|
405
|
+
state.compressionTokenSavings = new Map(
|
|
406
|
+
saved.compressionTokenSavings.filter(
|
|
407
|
+
(entry): entry is [number, number] =>
|
|
408
|
+
Array.isArray(entry) && typeof entry[0] === "number" && typeof entry[1] === "number",
|
|
409
|
+
),
|
|
410
|
+
)
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (Array.isArray(saved.accountedPrunedToolIds)) {
|
|
414
|
+
state.accountedPrunedToolIds = new Set(
|
|
415
|
+
saved.accountedPrunedToolIds.filter((id): id is string => typeof id === "string"),
|
|
416
|
+
)
|
|
417
|
+
} else {
|
|
418
|
+
// Same migration safety for pre-accounting payloads.
|
|
419
|
+
state.accountedPrunedToolIds = new Set(state.prunedToolIds)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
if (typeof saved.manualMode === "boolean") {
|
|
423
|
+
state.manualMode = saved.manualMode
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (Array.isArray(saved.nudgeAnchors)) {
|
|
427
|
+
const seen = new Set<string>()
|
|
428
|
+
state.nudgeAnchors = saved.nudgeAnchors
|
|
429
|
+
.filter(isNudgeAnchor)
|
|
430
|
+
.filter((anchor) => {
|
|
431
|
+
const key = `${anchor.anchorStableId ?? ""}|${anchor.anchorTimestamp}`
|
|
432
|
+
if (seen.has(key)) return false
|
|
433
|
+
seen.add(key)
|
|
434
|
+
return true
|
|
435
|
+
})
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (typeof saved.nextNudgeAnchorId === "number" && saved.nextNudgeAnchorId > 0) {
|
|
439
|
+
state.nextNudgeAnchorId = Math.floor(saved.nextNudgeAnchorId)
|
|
440
|
+
} else if (state.nudgeAnchors.length > 0) {
|
|
441
|
+
state.nextNudgeAnchorId = Math.max(...state.nudgeAnchors.map((anchor) => anchor.id)) + 1
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (isLastNudge(saved.lastNudge)) {
|
|
445
|
+
state.lastNudge = saved.lastNudge
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// ---------------------------------------------------------------------------
|
|
450
|
+
// Fingerprinting
|
|
451
|
+
// ---------------------------------------------------------------------------
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Recursively sort the keys of a plain object so that two argument objects
|
|
455
|
+
* with the same entries in different key-insertion order produce the same JSON.
|
|
456
|
+
*/
|
|
457
|
+
function sortObjectKeys(value: unknown): unknown {
|
|
458
|
+
if (Array.isArray(value)) {
|
|
459
|
+
return value.map(sortObjectKeys)
|
|
460
|
+
}
|
|
461
|
+
if (value !== null && typeof value === "object") {
|
|
462
|
+
const obj = value as Record<string, unknown>
|
|
463
|
+
const sorted: Record<string, unknown> = {}
|
|
464
|
+
for (const key of Object.keys(obj).sort()) {
|
|
465
|
+
sorted[key] = sortObjectKeys(obj[key])
|
|
466
|
+
}
|
|
467
|
+
return sorted
|
|
468
|
+
}
|
|
469
|
+
return value
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Create a stable deduplication fingerprint for a tool call.
|
|
474
|
+
*
|
|
475
|
+
* Two calls with the same `toolName` and semantically identical `args`
|
|
476
|
+
* (regardless of key ordering) will produce the same fingerprint.
|
|
477
|
+
*
|
|
478
|
+
* Format: `<toolName>::<JSON of recursively key-sorted args>`
|
|
479
|
+
*/
|
|
480
|
+
export function createInputFingerprint(
|
|
481
|
+
toolName: string,
|
|
482
|
+
args: Record<string, unknown>,
|
|
483
|
+
): string {
|
|
484
|
+
const sorted = sortObjectKeys(args)
|
|
485
|
+
return `${toolName}::${JSON.stringify(sorted)}`
|
|
486
|
+
}
|