tarsk 0.3.43 → 0.4.4
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 +1 -1
- package/dist/agent/agent.error-utils.d.ts +14 -0
- package/dist/agent/agent.error-utils.js +52 -0
- package/dist/agent/agent.event-transformer.d.ts +55 -0
- package/dist/agent/agent.event-transformer.js +175 -0
- package/dist/agent/agent.executor.d.ts +26 -0
- package/dist/agent/agent.executor.js +286 -0
- package/dist/agent/agent.model-resolver.d.ts +22 -0
- package/dist/agent/agent.model-resolver.js +67 -0
- package/dist/agent/agent.process-manager.d.ts +57 -0
- package/dist/agent/agent.process-manager.js +262 -0
- package/dist/agent/agent.processing-state-manager.d.ts +74 -0
- package/dist/agent/agent.processing-state-manager.js +87 -0
- package/dist/agent/agent.prompt-loader.d.ts +16 -0
- package/dist/agent/agent.prompt-loader.js +227 -0
- package/dist/agent/agent.subagent-executor.d.ts +35 -0
- package/dist/agent/agent.subagent-executor.js +135 -0
- package/dist/bun/index.d.ts +2 -0
- package/dist/bun/index.js +165 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +22 -0
- package/dist/core/crypto.d.ts +29 -0
- package/dist/core/crypto.js +166 -0
- package/dist/core/dev-server-cache.d.ts +46 -0
- package/dist/core/dev-server-cache.js +59 -0
- package/dist/core/env-manager.d.ts +3 -0
- package/dist/core/env-manager.js +60 -0
- package/dist/core/error-responses.d.ts +61 -0
- package/dist/core/error-responses.js +64 -0
- package/dist/core/logger.d.ts +10 -0
- package/dist/core/logger.js +47 -0
- package/dist/core/paths.d.ts +22 -0
- package/dist/core/paths.js +26 -0
- package/dist/core/random-words.d.ts +18 -0
- package/dist/core/random-words.js +135 -0
- package/dist/core/response-builder.d.ts +50 -0
- package/dist/core/response-builder.js +56 -0
- package/dist/core/route-helpers.d.ts +47 -0
- package/dist/core/route-helpers.js +54 -0
- package/dist/core/run-command-detector.d.ts +26 -0
- package/dist/core/run-command-detector.js +98 -0
- package/dist/core/stream-helper.d.ts +44 -0
- package/dist/core/stream-helper.js +50 -0
- package/dist/core/utils.d.ts +43 -0
- package/dist/core/utils.js +113 -0
- package/dist/core/validation.d.ts +10 -0
- package/dist/core/validation.js +20 -0
- package/dist/database/database.d.ts +40 -0
- package/dist/database/database.encryption.d.ts +33 -0
- package/dist/database/database.encryption.js +62 -0
- package/dist/database/database.js +480 -0
- package/dist/database/database.state.d.ts +52 -0
- package/dist/database/database.state.js +119 -0
- package/dist/database/database.test-utils.d.ts +22 -0
- package/dist/database/database.test-utils.js +39 -0
- package/dist/database/database.types.d.ts +3 -0
- package/dist/database/database.types.js +2 -0
- package/dist/features/agents/agents.manager.d.ts +24 -0
- package/dist/features/agents/agents.manager.js +200 -0
- package/dist/features/ask-user/ask-user.routes.d.ts +9 -0
- package/dist/features/ask-user/ask-user.routes.js +35 -0
- package/dist/features/chat/chat-delete.route.d.ts +15 -0
- package/dist/features/chat/chat-delete.route.js +36 -0
- package/dist/features/chat/chat-post.route.d.ts +11 -0
- package/dist/features/chat/chat-post.route.js +270 -0
- package/dist/features/chat/chat-stop.route.d.ts +21 -0
- package/dist/features/chat/chat-stop.route.js +22 -0
- package/dist/features/chat/chat-subscribe.route.d.ts +9 -0
- package/dist/features/chat/chat-subscribe.route.js +71 -0
- package/dist/features/chat/chat.routes.d.ts +22 -0
- package/dist/features/chat/chat.routes.js +29 -0
- package/dist/features/conversations/conversations-delete.route.d.ts +16 -0
- package/dist/features/conversations/conversations-delete.route.js +34 -0
- package/dist/features/conversations/conversations-get-all.route.d.ts +16 -0
- package/dist/features/conversations/conversations-get-all.route.js +39 -0
- package/dist/features/conversations/conversations-get-by-id.route.d.ts +16 -0
- package/dist/features/conversations/conversations-get-by-id.route.js +38 -0
- package/dist/features/conversations/conversations-get-deleted.route.d.ts +15 -0
- package/dist/features/conversations/conversations-get-deleted.route.js +34 -0
- package/dist/features/conversations/conversations-get-messages.route.d.ts +16 -0
- package/dist/features/conversations/conversations-get-messages.route.js +49 -0
- package/dist/features/conversations/conversations.content.d.ts +28 -0
- package/dist/features/conversations/conversations.content.js +142 -0
- package/dist/features/conversations/conversations.database.d.ts +108 -0
- package/dist/features/conversations/conversations.database.js +373 -0
- package/dist/features/conversations/conversations.manager.d.ts +130 -0
- package/dist/features/conversations/conversations.manager.js +162 -0
- package/dist/features/conversations/conversations.routes.d.ts +21 -0
- package/dist/features/conversations/conversations.routes.js +38 -0
- package/dist/features/conversations/token-usage.route.d.ts +41 -0
- package/dist/features/conversations/token-usage.route.js +419 -0
- package/dist/features/git/git-commit.route.d.ts +12 -0
- package/dist/features/git/git-commit.route.js +39 -0
- package/dist/features/git/git-create-branch.route.d.ts +28 -0
- package/dist/features/git/git-create-branch.route.js +119 -0
- package/dist/features/git/git-create-pr.route.d.ts +13 -0
- package/dist/features/git/git-create-pr.route.js +50 -0
- package/dist/features/git/git-create-repo.route.d.ts +14 -0
- package/dist/features/git/git-create-repo.route.js +108 -0
- package/dist/features/git/git-diff.route.d.ts +30 -0
- package/dist/features/git/git-diff.route.js +189 -0
- package/dist/features/git/git-fetch.route.d.ts +12 -0
- package/dist/features/git/git-fetch.route.js +31 -0
- package/dist/features/git/git-generate-commit-message.route.d.ts +12 -0
- package/dist/features/git/git-generate-commit-message.route.js +76 -0
- package/dist/features/git/git-generate-pr-info.route.d.ts +13 -0
- package/dist/features/git/git-generate-pr-info.route.js +147 -0
- package/dist/features/git/git-github-status.route.d.ts +16 -0
- package/dist/features/git/git-github-status.route.js +68 -0
- package/dist/features/git/git-log.route.d.ts +17 -0
- package/dist/features/git/git-log.route.js +33 -0
- package/dist/features/git/git-pr-status.route.d.ts +15 -0
- package/dist/features/git/git-pr-status.route.js +33 -0
- package/dist/features/git/git-pull.route.d.ts +12 -0
- package/dist/features/git/git-pull.route.js +35 -0
- package/dist/features/git/git-push.route.d.ts +12 -0
- package/dist/features/git/git-push.route.js +46 -0
- package/dist/features/git/git-status-cache.database.d.ts +7 -0
- package/dist/features/git/git-status-cache.database.js +53 -0
- package/dist/features/git/git-status.route.d.ts +15 -0
- package/dist/features/git/git-status.route.js +62 -0
- package/dist/features/git/git-sync-branch.route.d.ts +4 -0
- package/dist/features/git/git-sync-branch.route.js +208 -0
- package/dist/features/git/git-unified-status.route.d.ts +30 -0
- package/dist/features/git/git-unified-status.route.js +165 -0
- package/dist/features/git/git-username.route.d.ts +3 -0
- package/dist/features/git/git-username.route.js +24 -0
- package/dist/features/git/git.manager.d.ts +139 -0
- package/dist/features/git/git.manager.js +352 -0
- package/dist/features/git/git.routes.d.ts +4 -0
- package/dist/features/git/git.routes.js +116 -0
- package/dist/features/git/git.utils.d.ts +82 -0
- package/dist/features/git/git.utils.js +1040 -0
- package/dist/features/mcp/mcp.config.d.ts +27 -0
- package/dist/features/mcp/mcp.config.js +148 -0
- package/dist/features/mcp/mcp.manager.d.ts +61 -0
- package/dist/features/mcp/mcp.manager.js +254 -0
- package/dist/features/mcp/mcp.popular.json +103 -0
- package/dist/features/mcp/mcp.routes.d.ts +13 -0
- package/dist/features/mcp/mcp.routes.js +159 -0
- package/dist/features/mcp/mcp.types.d.ts +80 -0
- package/dist/features/mcp/mcp.types.js +8 -0
- package/dist/features/metadata/metadata.manager.d.ts +126 -0
- package/dist/features/metadata/metadata.manager.js +423 -0
- package/dist/features/models/model-info-aihubmix.d.ts +25 -0
- package/dist/features/models/model-info-aihubmix.js +117 -0
- package/dist/features/models/model-info-openrouter.d.ts +25 -0
- package/dist/features/models/model-info-openrouter.js +104 -0
- package/dist/features/models/model-info.d.ts +37 -0
- package/dist/features/models/model-info.js +39 -0
- package/dist/features/models/models-catalog.d.ts +49 -0
- package/dist/features/models/models-catalog.js +80 -0
- package/dist/features/models/models-catalog.route.d.ts +43 -0
- package/dist/features/models/models-catalog.route.js +15 -0
- package/dist/features/models/models-get-available.route.d.ts +36 -0
- package/dist/features/models/models-get-available.route.js +66 -0
- package/dist/features/models/models-get-enabled.route.d.ts +33 -0
- package/dist/features/models/models-get-enabled.route.js +45 -0
- package/dist/features/models/models-get-model-info.route.d.ts +31 -0
- package/dist/features/models/models-get-model-info.route.js +84 -0
- package/dist/features/models/models-model-disable.route.d.ts +15 -0
- package/dist/features/models/models-model-disable.route.js +20 -0
- package/dist/features/models/models-model-enable.route.d.ts +13 -0
- package/dist/features/models/models-model-enable.route.js +20 -0
- package/dist/features/models/models-provider-refresh.route.d.ts +17 -0
- package/dist/features/models/models-provider-refresh.route.js +20 -0
- package/dist/features/models/models.manager.d.ts +58 -0
- package/dist/features/models/models.manager.js +138 -0
- package/dist/features/models/models.routes.d.ts +18 -0
- package/dist/features/models/models.routes.js +83 -0
- package/dist/features/models/open-router-models.d.ts +38 -0
- package/dist/features/models/open-router-models.js +73 -0
- package/dist/features/models/openai-models.d.ts +63 -0
- package/dist/features/models/openai-models.js +150 -0
- package/dist/features/onboarding/onboarding-get-git-check.route.d.ts +11 -0
- package/dist/features/onboarding/onboarding-get-git-check.route.js +28 -0
- package/dist/features/onboarding/onboarding-get-status.route.d.ts +12 -0
- package/dist/features/onboarding/onboarding-get-status.route.js +15 -0
- package/dist/features/onboarding/onboarding-post-complete.route.d.ts +12 -0
- package/dist/features/onboarding/onboarding-post-complete.route.js +15 -0
- package/dist/features/onboarding/onboarding-post-reset.route.d.ts +12 -0
- package/dist/features/onboarding/onboarding-post-reset.route.js +15 -0
- package/dist/features/onboarding/onboarding.routes.d.ts +18 -0
- package/dist/features/onboarding/onboarding.routes.js +28 -0
- package/dist/features/project-todos/project-todos.database.d.ts +38 -0
- package/dist/features/project-todos/project-todos.database.js +91 -0
- package/dist/features/project-todos/project-todos.routes.d.ts +4 -0
- package/dist/features/project-todos/project-todos.routes.js +94 -0
- package/dist/features/projects/projects-ai-files.route.d.ts +148 -0
- package/dist/features/projects/projects-ai-files.route.js +425 -0
- package/dist/features/projects/projects-commands.route.d.ts +27 -0
- package/dist/features/projects/projects-commands.route.js +39 -0
- package/dist/features/projects/projects-create.route.d.ts +19 -0
- package/dist/features/projects/projects-create.route.js +37 -0
- package/dist/features/projects/projects-delete.route.d.ts +24 -0
- package/dist/features/projects/projects-delete.route.js +34 -0
- package/dist/features/projects/projects-get.route.d.ts +47 -0
- package/dist/features/projects/projects-get.route.js +36 -0
- package/dist/features/projects/projects-list.route.d.ts +58 -0
- package/dist/features/projects/projects-list.route.js +59 -0
- package/dist/features/projects/projects-open-folder.route.d.ts +10 -0
- package/dist/features/projects/projects-open-folder.route.js +11 -0
- package/dist/features/projects/projects-open.route.d.ts +26 -0
- package/dist/features/projects/projects-open.route.js +49 -0
- package/dist/features/projects/projects-package-scripts.route.d.ts +15 -0
- package/dist/features/projects/projects-package-scripts.route.js +96 -0
- package/dist/features/projects/projects-run-command.route.d.ts +8 -0
- package/dist/features/projects/projects-run-command.route.js +21 -0
- package/dist/features/projects/projects-run.route.d.ts +51 -0
- package/dist/features/projects/projects-run.route.js +74 -0
- package/dist/features/projects/projects-update.route.d.ts +24 -0
- package/dist/features/projects/projects-update.route.js +81 -0
- package/dist/features/projects/projects.creator.d.ts +33 -0
- package/dist/features/projects/projects.creator.js +555 -0
- package/dist/features/projects/projects.database.d.ts +61 -0
- package/dist/features/projects/projects.database.js +212 -0
- package/dist/features/projects/projects.manager.d.ts +291 -0
- package/dist/features/projects/projects.manager.js +426 -0
- package/dist/features/projects/projects.open-with.d.ts +27 -0
- package/dist/features/projects/projects.open-with.js +156 -0
- package/dist/features/projects/projects.routes.d.ts +20 -0
- package/dist/features/projects/projects.routes.js +255 -0
- package/dist/features/projects/terminal-session-manager.d.ts +55 -0
- package/dist/features/projects/terminal-session-manager.js +90 -0
- package/dist/features/providers/provider-resolver.d.ts +13 -0
- package/dist/features/providers/provider-resolver.js +22 -0
- package/dist/features/providers/providers-get-credits.route.d.ts +15 -0
- package/dist/features/providers/providers-get-credits.route.js +51 -0
- package/dist/features/providers/providers-get.route.d.ts +16 -0
- package/dist/features/providers/providers-get.route.js +32 -0
- package/dist/features/providers/providers-open-external.route.d.ts +15 -0
- package/dist/features/providers/providers-open-external.route.js +49 -0
- package/dist/features/providers/providers-post-bulk-keys.route.d.ts +14 -0
- package/dist/features/providers/providers-post-bulk-keys.route.js +31 -0
- package/dist/features/providers/providers-post-keys.route.d.ts +14 -0
- package/dist/features/providers/providers-post-keys.route.js +25 -0
- package/dist/features/providers/providers.routes.d.ts +19 -0
- package/dist/features/providers/providers.routes.js +31 -0
- package/dist/features/rules/rules-post.route.d.ts +43 -0
- package/dist/features/rules/rules-post.route.js +89 -0
- package/dist/features/rules/rules.manager.d.ts +36 -0
- package/dist/features/rules/rules.manager.js +203 -0
- package/dist/features/rules/rules.routes.d.ts +12 -0
- package/dist/features/rules/rules.routes.js +13 -0
- package/dist/features/run/run-get-running.route.d.ts +15 -0
- package/dist/features/run/run-get-running.route.js +21 -0
- package/dist/features/run/run-post-start.route.d.ts +8 -0
- package/dist/features/run/run-post-start.route.js +21 -0
- package/dist/features/run/run-post-stop.route.d.ts +15 -0
- package/dist/features/run/run-post-stop.route.js +24 -0
- package/dist/features/run/run-post-suggest.route.d.ts +15 -0
- package/dist/features/run/run-post-suggest.route.js +21 -0
- package/dist/features/run/run-put-command.route.d.ts +15 -0
- package/dist/features/run/run-put-command.route.js +24 -0
- package/dist/features/run/run.routes.d.ts +19 -0
- package/dist/features/run/run.routes.js +31 -0
- package/dist/features/scaffold/index.d.ts +7 -0
- package/dist/features/scaffold/index.js +5 -0
- package/dist/features/scaffold/scaffold-get-templates.route.d.ts +27 -0
- package/dist/features/scaffold/scaffold-get-templates.route.js +17 -0
- package/dist/features/scaffold/scaffold-post.route.d.ts +8 -0
- package/dist/features/scaffold/scaffold-post.route.js +30 -0
- package/dist/features/scaffold/scaffold.routes.d.ts +10 -0
- package/dist/features/scaffold/scaffold.routes.js +16 -0
- package/dist/features/scaffold/scaffold.runner.d.ts +48 -0
- package/dist/features/scaffold/scaffold.runner.js +475 -0
- package/dist/features/scaffold/scaffold.types.d.ts +26 -0
- package/dist/features/scaffold/scaffold.types.js +5 -0
- package/dist/features/skills/skills.activation.d.ts +31 -0
- package/dist/features/skills/skills.activation.js +155 -0
- package/dist/features/skills/skills.manager.d.ts +35 -0
- package/dist/features/skills/skills.manager.js +251 -0
- package/dist/features/slash-commands/slash-commands-delete.route.d.ts +23 -0
- package/dist/features/slash-commands/slash-commands-delete.route.js +36 -0
- package/dist/features/slash-commands/slash-commands-get.route.d.ts +53 -0
- package/dist/features/slash-commands/slash-commands-get.route.js +54 -0
- package/dist/features/slash-commands/slash-commands-post.route.d.ts +39 -0
- package/dist/features/slash-commands/slash-commands-post.route.js +70 -0
- package/dist/features/slash-commands/slash-commands-put.route.d.ts +23 -0
- package/dist/features/slash-commands/slash-commands-put.route.js +36 -0
- package/dist/features/slash-commands/slash-commands.manager.d.ts +46 -0
- package/dist/features/slash-commands/slash-commands.manager.js +265 -0
- package/dist/features/slash-commands/slash-commands.routes.d.ts +13 -0
- package/dist/features/slash-commands/slash-commands.routes.js +20 -0
- package/dist/features/threads/threads-ai-files.route.d.ts +153 -0
- package/dist/features/threads/threads-ai-files.route.js +287 -0
- package/dist/features/threads/threads-conversation-folder-path.route.d.ts +14 -0
- package/dist/features/threads/threads-conversation-folder-path.route.js +23 -0
- package/dist/features/threads/threads-create.route.d.ts +22 -0
- package/dist/features/threads/threads-create.route.js +60 -0
- package/dist/features/threads/threads-delete.route.d.ts +25 -0
- package/dist/features/threads/threads-delete.route.js +35 -0
- package/dist/features/threads/threads-files.route.d.ts +15 -0
- package/dist/features/threads/threads-files.route.js +20 -0
- package/dist/features/threads/threads-fix-comments.route.d.ts +26 -0
- package/dist/features/threads/threads-fix-comments.route.js +45 -0
- package/dist/features/threads/threads-get.route.d.ts +30 -0
- package/dist/features/threads/threads-get.route.js +38 -0
- package/dist/features/threads/threads-list.route.d.ts +56 -0
- package/dist/features/threads/threads-list.route.js +58 -0
- package/dist/features/threads/threads-messages.route.d.ts +28 -0
- package/dist/features/threads/threads-messages.route.js +110 -0
- package/dist/features/threads/threads-open.route.d.ts +26 -0
- package/dist/features/threads/threads-open.route.js +62 -0
- package/dist/features/threads/threads-select.route.d.ts +25 -0
- package/dist/features/threads/threads-select.route.js +35 -0
- package/dist/features/threads/threads-update.route.d.ts +15 -0
- package/dist/features/threads/threads-update.route.js +30 -0
- package/dist/features/threads/threads.database.d.ts +68 -0
- package/dist/features/threads/threads.database.js +215 -0
- package/dist/features/threads/threads.manager.d.ts +204 -0
- package/dist/features/threads/threads.manager.js +505 -0
- package/dist/features/threads/threads.routes.d.ts +20 -0
- package/dist/features/threads/threads.routes.js +230 -0
- package/dist/features/todos/todos.database.d.ts +14 -0
- package/dist/features/todos/todos.database.js +31 -0
- package/dist/features/updates/updates.routes.d.ts +13 -0
- package/dist/features/updates/updates.routes.js +40 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +37 -10022
- package/dist/project-analyzer.d.ts +26 -0
- package/dist/project-analyzer.js +307 -0
- package/dist/public/assets/add-agent-view-B9IQjAwU.js +1 -0
- package/dist/public/assets/add-rule-view-BdZHurB3.js +7 -0
- package/dist/public/assets/add-skill-view-Cuu6Z0fr.js +1 -0
- package/dist/public/assets/add-slash-command-view-uW75Jvbh.js +1 -0
- package/dist/public/assets/conversation-history-view-D0OBxJMC.js +1 -0
- package/dist/public/assets/dialogs-config-DiFQjCeA.js +46 -0
- package/dist/public/assets/diff-view-B5XBM5UZ.js +3 -0
- package/dist/public/assets/file-tree-sidebar-DMX7fHi7.js +1 -0
- package/dist/public/assets/files-view-CUZn7G0o.js +1 -0
- package/dist/public/assets/history-view-B8HM78Wa.js +1 -0
- package/dist/public/assets/index-C-p81QYw.js +17 -0
- package/dist/public/assets/index-DhVMb7D6.css +1 -0
- package/dist/public/assets/mcp-manager-CEm1L3dn.js +1 -0
- package/dist/public/assets/mcp-server-edit-view-BAwMNOAH.js +5 -0
- package/dist/public/assets/mcp-servers-sidebar-Ncxq9Oj5.js +1 -0
- package/dist/public/assets/mcp-view-Cz7nelGQ.js +1 -0
- package/dist/public/assets/monaco-DvsnxTfD.js +11 -0
- package/dist/public/assets/onboarding-CvpvkF3X.js +1 -0
- package/dist/public/assets/onboarding-dialog-CKJw0ULj.js +1 -0
- package/dist/public/assets/project-settings-view-DJ1uvrTL.js +1 -0
- package/dist/public/assets/provider-details-view-CkS6WbnK.js +1 -0
- package/dist/public/assets/providers-sidebar-C4MF6i9d.js +1 -0
- package/dist/public/assets/radio-group-BItFbSTw.js +1 -0
- package/dist/public/assets/react-vendor-DkKo9QGO.js +17 -0
- package/dist/public/assets/rolldown-runtime-Dw2cE7zH.js +1 -0
- package/dist/public/assets/settings-view-C45kmAGH.js +2 -0
- package/dist/public/assets/store-BVVGurzl.js +2 -0
- package/dist/public/assets/use-toast-DEJkXPN4.js +1 -0
- package/dist/public/assets/utils-DY_quHB8.js +1 -0
- package/dist/public/fonts/google-sans.ttf +0 -0
- package/dist/public/fonts/zalando.ttf +0 -0
- package/dist/public/ide/android-studio.svg +1 -0
- package/dist/public/ide/cursor.svg +12 -0
- package/dist/public/ide/kiro.svg +11 -0
- package/dist/public/ide/terminal.svg +7 -0
- package/dist/public/ide/vscode.svg +2 -0
- package/dist/public/ide/windsurf.svg +3 -0
- package/dist/public/ide/xcode.svg +2 -0
- package/dist/public/index.html +13 -9
- package/dist/scaffold-templates.json +3 -12
- package/dist/server.d.ts +12 -0
- package/dist/server.js +142 -0
- package/dist/tools/agent-tool.d.ts +49 -0
- package/dist/tools/agent-tool.js +131 -0
- package/dist/tools/ask-user.d.ts +25 -0
- package/dist/tools/ask-user.js +74 -0
- package/dist/tools/ast-grep.d.ts +28 -0
- package/dist/tools/ast-grep.js +273 -0
- package/dist/tools/bash.d.ts +33 -0
- package/dist/tools/bash.js +186 -0
- package/dist/tools/edit-diff.d.ts +24 -0
- package/dist/tools/edit-diff.js +136 -0
- package/dist/tools/edit.d.ts +28 -0
- package/dist/tools/edit.js +78 -0
- package/dist/tools/find.d.ts +31 -0
- package/dist/tools/find.js +117 -0
- package/dist/tools/grep.d.ts +37 -0
- package/dist/tools/grep.js +231 -0
- package/dist/tools/index.d.ts +93 -0
- package/dist/tools/index.js +110 -0
- package/dist/tools/ls.d.ts +31 -0
- package/dist/tools/ls.js +108 -0
- package/dist/tools/mcp-tools.d.ts +31 -0
- package/dist/tools/mcp-tools.js +59 -0
- package/dist/tools/path-utils.d.ts +14 -0
- package/dist/tools/path-utils.js +87 -0
- package/dist/tools/read.d.ts +27 -0
- package/dist/tools/read.js +86 -0
- package/dist/tools/resolve-bin.d.ts +5 -0
- package/dist/tools/resolve-bin.js +28 -0
- package/dist/tools/shell.d.ts +7 -0
- package/dist/tools/shell.js +143 -0
- package/dist/tools/skill-reference-tool.d.ts +30 -0
- package/dist/tools/skill-reference-tool.js +171 -0
- package/dist/tools/skill-tool.d.ts +33 -0
- package/dist/tools/skill-tool.js +213 -0
- package/dist/tools/todo.d.ts +20 -0
- package/dist/tools/todo.js +168 -0
- package/dist/tools/tool-helpers.d.ts +78 -0
- package/dist/tools/tool-helpers.js +109 -0
- package/dist/tools/truncate.d.ts +31 -0
- package/dist/tools/truncate.js +164 -0
- package/dist/tools/write.d.ts +21 -0
- package/dist/tools/write.js +65 -0
- package/package.json +33 -27
- package/dist/public/assets/index-6jySngUQ.css +0 -1
- package/dist/public/assets/index-BjFpLTSj.js +0 -18
- package/dist/public/assets/monaco-w6PwaWGP.js +0 -11
- package/dist/public/assets/radix-ui-e1yigncZ.js +0 -1
- package/dist/public/assets/react-vendor-B6JfXZmN.js +0 -59
- package/dist/public/assets/ui-styling-CyCIFleB.js +0 -1
- package/dist/public/assets/utils-Dd_itR7L.js +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { createWriteStream, existsSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
import { spawnProcess } from "../core/utils.js";
|
|
7
|
+
import { getShellConfig, getShellEnv, killProcessTree } from "./shell.js";
|
|
8
|
+
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateTail, } from "./truncate.js";
|
|
9
|
+
function getTempFilePath() {
|
|
10
|
+
return join(tmpdir(), `tarsk-bash-${randomBytes(8).toString("hex")}.log`);
|
|
11
|
+
}
|
|
12
|
+
const bashSchema = Type.Object({
|
|
13
|
+
command: Type.String({ description: "Bash command to execute" }),
|
|
14
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (optional)" })),
|
|
15
|
+
});
|
|
16
|
+
const defaultBashOperations = {
|
|
17
|
+
exec: (command, cwd, { onData, signal, timeout, env }) => {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const { shell, args } = getShellConfig();
|
|
20
|
+
if (!existsSync(cwd)) {
|
|
21
|
+
reject(new Error(`Working directory does not exist: ${cwd}`));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const child = spawnProcess(shell, [...args, command], {
|
|
25
|
+
cwd,
|
|
26
|
+
detached: true,
|
|
27
|
+
env: (env
|
|
28
|
+
? Object.fromEntries(Object.entries(env)
|
|
29
|
+
.filter(([_, v]) => v !== undefined)
|
|
30
|
+
.map(([k, v]) => [k, v]))
|
|
31
|
+
: undefined) ??
|
|
32
|
+
Object.fromEntries(Object.entries(getShellEnv())
|
|
33
|
+
.filter(([_, v]) => v !== undefined)
|
|
34
|
+
.map(([k, v]) => [k, v])),
|
|
35
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
36
|
+
});
|
|
37
|
+
let timedOut = false;
|
|
38
|
+
let timeoutHandle;
|
|
39
|
+
if (timeout !== undefined && timeout > 0) {
|
|
40
|
+
timeoutHandle = setTimeout(() => {
|
|
41
|
+
timedOut = true;
|
|
42
|
+
if (child.pid)
|
|
43
|
+
killProcessTree(child.pid);
|
|
44
|
+
}, timeout * 1000);
|
|
45
|
+
}
|
|
46
|
+
if (child.stdout)
|
|
47
|
+
child.stdout.on("data", onData);
|
|
48
|
+
if (child.stderr)
|
|
49
|
+
child.stderr.on("data", onData);
|
|
50
|
+
child.on("error", (err) => {
|
|
51
|
+
if (timeoutHandle)
|
|
52
|
+
clearTimeout(timeoutHandle);
|
|
53
|
+
if (signal)
|
|
54
|
+
signal.removeEventListener("abort", onAbort);
|
|
55
|
+
reject(err);
|
|
56
|
+
});
|
|
57
|
+
const onAbort = () => {
|
|
58
|
+
if (child.pid)
|
|
59
|
+
killProcessTree(child.pid);
|
|
60
|
+
};
|
|
61
|
+
if (signal) {
|
|
62
|
+
if (signal.aborted)
|
|
63
|
+
onAbort();
|
|
64
|
+
else
|
|
65
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
66
|
+
}
|
|
67
|
+
child.on("close", (code) => {
|
|
68
|
+
if (timeoutHandle)
|
|
69
|
+
clearTimeout(timeoutHandle);
|
|
70
|
+
if (signal)
|
|
71
|
+
signal.removeEventListener("abort", onAbort);
|
|
72
|
+
if (signal?.aborted) {
|
|
73
|
+
reject(new Error("aborted"));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (timedOut) {
|
|
77
|
+
reject(new Error(`timeout:${timeout}`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
resolve({ exitCode: code });
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
export function createBashTool(cwd, options) {
|
|
86
|
+
const ops = options?.operations ?? defaultBashOperations;
|
|
87
|
+
const commandPrefix = options?.commandPrefix;
|
|
88
|
+
return {
|
|
89
|
+
name: "bash",
|
|
90
|
+
label: "bash",
|
|
91
|
+
description: `Execute a bash command in the current working directory. Output truncated to last ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB. Optionally provide a timeout in seconds.`,
|
|
92
|
+
parameters: bashSchema,
|
|
93
|
+
execute: async (_toolCallId, { command, timeout }, signal, onUpdate) => {
|
|
94
|
+
const resolvedCommand = commandPrefix ? `${commandPrefix}\n${command}` : command;
|
|
95
|
+
console.log(`[ai] bash-start: ${resolvedCommand}`);
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
let tempFilePath;
|
|
98
|
+
let tempFileStream;
|
|
99
|
+
let totalBytes = 0;
|
|
100
|
+
const chunks = [];
|
|
101
|
+
let chunksBytes = 0;
|
|
102
|
+
const maxChunksBytes = DEFAULT_MAX_BYTES * 2;
|
|
103
|
+
const handleData = (data) => {
|
|
104
|
+
totalBytes += data.length;
|
|
105
|
+
if (totalBytes > DEFAULT_MAX_BYTES && !tempFilePath) {
|
|
106
|
+
tempFilePath = getTempFilePath();
|
|
107
|
+
tempFileStream = createWriteStream(tempFilePath);
|
|
108
|
+
for (const chunk of chunks)
|
|
109
|
+
tempFileStream.write(chunk);
|
|
110
|
+
}
|
|
111
|
+
if (tempFileStream)
|
|
112
|
+
tempFileStream.write(data);
|
|
113
|
+
chunks.push(data);
|
|
114
|
+
chunksBytes += data.length;
|
|
115
|
+
while (chunksBytes > maxChunksBytes && chunks.length > 1) {
|
|
116
|
+
const removed = chunks.shift();
|
|
117
|
+
chunksBytes -= removed.length;
|
|
118
|
+
}
|
|
119
|
+
if (onUpdate) {
|
|
120
|
+
const fullText = Buffer.concat(chunks).toString("utf-8");
|
|
121
|
+
const truncation = truncateTail(fullText);
|
|
122
|
+
onUpdate({
|
|
123
|
+
content: [{ type: "text", text: truncation.content || "" }],
|
|
124
|
+
details: {
|
|
125
|
+
truncation: truncation.truncated ? truncation : undefined,
|
|
126
|
+
fullOutputPath: tempFilePath,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
ops
|
|
132
|
+
.exec(resolvedCommand, cwd, { onData: handleData, signal, timeout, env: getShellEnv() })
|
|
133
|
+
.then(({ exitCode }) => {
|
|
134
|
+
console.log(`[ai] bash-end: ${resolvedCommand}`);
|
|
135
|
+
if (tempFileStream)
|
|
136
|
+
tempFileStream.end();
|
|
137
|
+
const fullOutput = Buffer.concat(chunks).toString("utf-8");
|
|
138
|
+
const truncation = truncateTail(fullOutput);
|
|
139
|
+
let outputText = truncation.content || "(no output)";
|
|
140
|
+
let details;
|
|
141
|
+
if (truncation.truncated) {
|
|
142
|
+
details = { truncation, fullOutputPath: tempFilePath };
|
|
143
|
+
const startLine = truncation.totalLines - truncation.outputLines + 1;
|
|
144
|
+
const endLine = truncation.totalLines;
|
|
145
|
+
if (truncation.lastLinePartial) {
|
|
146
|
+
outputText += `\n\n[Showing last ${formatSize(truncation.outputBytes)} of line ${endLine}. Full output: ${tempFilePath}]`;
|
|
147
|
+
}
|
|
148
|
+
else if (truncation.truncatedBy === "lines") {
|
|
149
|
+
outputText += `\n\n[Showing lines ${startLine}-${endLine} of ${truncation.totalLines}. Full output: ${tempFilePath}]`;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
outputText += `\n\n[Showing lines ${startLine}-${endLine} (${formatSize(DEFAULT_MAX_BYTES)} limit). Full output: ${tempFilePath}]`;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (exitCode !== 0 && exitCode !== null) {
|
|
156
|
+
outputText += `\n\nCommand exited with code ${exitCode}`;
|
|
157
|
+
reject(new Error(outputText));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
resolve({ content: [{ type: "text", text: outputText }], details });
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
.catch((err) => {
|
|
164
|
+
console.log(`[ai] bash-end: ${resolvedCommand}`);
|
|
165
|
+
if (tempFileStream)
|
|
166
|
+
tempFileStream.end();
|
|
167
|
+
const output = Buffer.concat(chunks).toString("utf-8");
|
|
168
|
+
if (err.message === "aborted") {
|
|
169
|
+
reject(new Error(output ? `${output}\n\nCommand aborted` : "Command aborted"));
|
|
170
|
+
}
|
|
171
|
+
else if (err.message.startsWith("timeout:")) {
|
|
172
|
+
const secs = err.message.split(":")[1];
|
|
173
|
+
reject(new Error(output
|
|
174
|
+
? `${output}\n\nCommand timed out after ${secs} seconds`
|
|
175
|
+
: `Command timed out after ${secs} seconds`));
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
reject(err);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export const bashTool = createBashTool(process.cwd());
|
|
186
|
+
//# sourceMappingURL=bash.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared diff computation utilities for the edit tool.
|
|
3
|
+
*/
|
|
4
|
+
export declare function detectLineEnding(content: string): "\r\n" | "\n";
|
|
5
|
+
export declare function normalizeToLF(text: string): string;
|
|
6
|
+
export declare function restoreLineEndings(text: string, ending: "\r\n" | "\n"): string;
|
|
7
|
+
export declare function normalizeForFuzzyMatch(text: string): string;
|
|
8
|
+
export interface FuzzyMatchResult {
|
|
9
|
+
found: boolean;
|
|
10
|
+
index: number;
|
|
11
|
+
matchLength: number;
|
|
12
|
+
usedFuzzyMatch: boolean;
|
|
13
|
+
contentForReplacement: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult;
|
|
16
|
+
export declare function stripBom(content: string): {
|
|
17
|
+
bom: string;
|
|
18
|
+
text: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function generateDiffString(oldContent: string, newContent: string, contextLines?: number): {
|
|
21
|
+
diff: string;
|
|
22
|
+
firstChangedLine: number | undefined;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=edit-diff.d.ts.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared diff computation utilities for the edit tool.
|
|
3
|
+
*/
|
|
4
|
+
import * as Diff from "diff";
|
|
5
|
+
export function detectLineEnding(content) {
|
|
6
|
+
const crlfIdx = content.indexOf("\r\n");
|
|
7
|
+
const lfIdx = content.indexOf("\n");
|
|
8
|
+
if (lfIdx === -1)
|
|
9
|
+
return "\n";
|
|
10
|
+
if (crlfIdx === -1)
|
|
11
|
+
return "\n";
|
|
12
|
+
return crlfIdx < lfIdx ? "\r\n" : "\n";
|
|
13
|
+
}
|
|
14
|
+
export function normalizeToLF(text) {
|
|
15
|
+
return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
16
|
+
}
|
|
17
|
+
export function restoreLineEndings(text, ending) {
|
|
18
|
+
return ending === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
|
|
19
|
+
}
|
|
20
|
+
export function normalizeForFuzzyMatch(text) {
|
|
21
|
+
return text
|
|
22
|
+
.split("\n")
|
|
23
|
+
.map((line) => line.trimEnd())
|
|
24
|
+
.join("\n")
|
|
25
|
+
.replace(/[\u2018\u2019\u201A\u201B]/g, "'")
|
|
26
|
+
.replace(/[\u201C\u201D\u201E\u201F]/g, '"')
|
|
27
|
+
.replace(/[\u2010\u2011\u2012\u2013\u2014\u2015\u2212]/g, "-")
|
|
28
|
+
.replace(/[\u00A0\u2002-\u200A\u202F\u205F\u3000]/g, " ");
|
|
29
|
+
}
|
|
30
|
+
export function fuzzyFindText(content, oldText) {
|
|
31
|
+
const exactIndex = content.indexOf(oldText);
|
|
32
|
+
if (exactIndex !== -1) {
|
|
33
|
+
return {
|
|
34
|
+
found: true,
|
|
35
|
+
index: exactIndex,
|
|
36
|
+
matchLength: oldText.length,
|
|
37
|
+
usedFuzzyMatch: false,
|
|
38
|
+
contentForReplacement: content,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const fuzzyContent = normalizeForFuzzyMatch(content);
|
|
42
|
+
const fuzzyOldText = normalizeForFuzzyMatch(oldText);
|
|
43
|
+
const fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);
|
|
44
|
+
if (fuzzyIndex === -1) {
|
|
45
|
+
return {
|
|
46
|
+
found: false,
|
|
47
|
+
index: -1,
|
|
48
|
+
matchLength: 0,
|
|
49
|
+
usedFuzzyMatch: false,
|
|
50
|
+
contentForReplacement: content,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
found: true,
|
|
55
|
+
index: fuzzyIndex,
|
|
56
|
+
matchLength: fuzzyOldText.length,
|
|
57
|
+
usedFuzzyMatch: true,
|
|
58
|
+
contentForReplacement: fuzzyContent,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function stripBom(content) {
|
|
62
|
+
return content.startsWith("\uFEFF")
|
|
63
|
+
? { bom: "\uFEFF", text: content.slice(1) }
|
|
64
|
+
: { bom: "", text: content };
|
|
65
|
+
}
|
|
66
|
+
export function generateDiffString(oldContent, newContent, contextLines = 4) {
|
|
67
|
+
const parts = Diff.diffLines(oldContent, newContent);
|
|
68
|
+
const output = [];
|
|
69
|
+
const oldLines = oldContent.split("\n");
|
|
70
|
+
const newLines = newContent.split("\n");
|
|
71
|
+
const maxLineNum = Math.max(oldLines.length, newLines.length);
|
|
72
|
+
const lineNumWidth = String(maxLineNum).length;
|
|
73
|
+
let oldLineNum = 1;
|
|
74
|
+
let newLineNum = 1;
|
|
75
|
+
let lastWasChange = false;
|
|
76
|
+
let firstChangedLine;
|
|
77
|
+
for (let i = 0; i < parts.length; i++) {
|
|
78
|
+
const part = parts[i];
|
|
79
|
+
const raw = part.value.split("\n");
|
|
80
|
+
if (raw[raw.length - 1] === "") {
|
|
81
|
+
raw.pop();
|
|
82
|
+
}
|
|
83
|
+
if (part.added || part.removed) {
|
|
84
|
+
firstChangedLine ??= newLineNum;
|
|
85
|
+
for (const line of raw) {
|
|
86
|
+
if (part.added) {
|
|
87
|
+
output.push(`+${String(newLineNum).padStart(lineNumWidth, " ")} ${line}`);
|
|
88
|
+
newLineNum++;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
output.push(`-${String(oldLineNum).padStart(lineNumWidth, " ")} ${line}`);
|
|
92
|
+
oldLineNum++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
lastWasChange = true;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
const nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);
|
|
99
|
+
if (lastWasChange || nextPartIsChange) {
|
|
100
|
+
let linesToShow = raw;
|
|
101
|
+
let skipStart = 0;
|
|
102
|
+
let skipEnd = 0;
|
|
103
|
+
if (!lastWasChange) {
|
|
104
|
+
skipStart = Math.max(0, raw.length - contextLines);
|
|
105
|
+
linesToShow = raw.slice(skipStart);
|
|
106
|
+
}
|
|
107
|
+
if (!nextPartIsChange && linesToShow.length > contextLines) {
|
|
108
|
+
skipEnd = linesToShow.length - contextLines;
|
|
109
|
+
linesToShow = linesToShow.slice(0, contextLines);
|
|
110
|
+
}
|
|
111
|
+
if (skipStart > 0) {
|
|
112
|
+
output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
|
|
113
|
+
oldLineNum += skipStart;
|
|
114
|
+
newLineNum += skipStart;
|
|
115
|
+
}
|
|
116
|
+
for (const line of linesToShow) {
|
|
117
|
+
output.push(` ${String(oldLineNum).padStart(lineNumWidth, " ")} ${line}`);
|
|
118
|
+
oldLineNum++;
|
|
119
|
+
newLineNum++;
|
|
120
|
+
}
|
|
121
|
+
if (skipEnd > 0) {
|
|
122
|
+
output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
|
|
123
|
+
oldLineNum += skipEnd;
|
|
124
|
+
newLineNum += skipEnd;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
oldLineNum += raw.length;
|
|
129
|
+
newLineNum += raw.length;
|
|
130
|
+
}
|
|
131
|
+
lastWasChange = false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { diff: output.join("\n"), firstChangedLine };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=edit-diff.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
declare const editSchema: import("@sinclair/typebox").TObject<{
|
|
4
|
+
path: import("@sinclair/typebox").TString;
|
|
5
|
+
oldText: import("@sinclair/typebox").TString;
|
|
6
|
+
newText: import("@sinclair/typebox").TString;
|
|
7
|
+
}>;
|
|
8
|
+
export type EditToolInput = Static<typeof editSchema>;
|
|
9
|
+
export interface EditToolDetails {
|
|
10
|
+
diff: string;
|
|
11
|
+
firstChangedLine?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface EditOperations {
|
|
14
|
+
readFile: (absolutePath: string) => Promise<Buffer>;
|
|
15
|
+
writeFile: (absolutePath: string, content: string) => Promise<void>;
|
|
16
|
+
access: (absolutePath: string) => Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export interface EditToolOptions {
|
|
19
|
+
operations?: EditOperations;
|
|
20
|
+
}
|
|
21
|
+
export declare function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema>;
|
|
22
|
+
export declare const editTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
23
|
+
path: import("@sinclair/typebox").TString;
|
|
24
|
+
oldText: import("@sinclair/typebox").TString;
|
|
25
|
+
newText: import("@sinclair/typebox").TString;
|
|
26
|
+
}>, any>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=edit.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { constants } from "fs";
|
|
3
|
+
import { access as fsAccess, readFile as fsReadFile, writeFile as fsWriteFile } from "fs/promises";
|
|
4
|
+
import { detectLineEnding, fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
|
|
5
|
+
import { resolveToCwd, validatePathWithinCwd } from "./path-utils.js";
|
|
6
|
+
import { withAbortSignal } from "./tool-helpers.js";
|
|
7
|
+
const editSchema = Type.Object({
|
|
8
|
+
path: Type.String({ description: "Path to the file to edit (relative or absolute)" }),
|
|
9
|
+
oldText: Type.String({ description: "Exact text to find and replace (must match exactly)" }),
|
|
10
|
+
newText: Type.String({ description: "New text to replace the old text with" }),
|
|
11
|
+
});
|
|
12
|
+
const defaultEditOperations = {
|
|
13
|
+
readFile: (path) => fsReadFile(path),
|
|
14
|
+
writeFile: (path, content) => fsWriteFile(path, content, "utf-8"),
|
|
15
|
+
access: (path) => fsAccess(path, constants.R_OK | constants.W_OK),
|
|
16
|
+
};
|
|
17
|
+
export function createEditTool(cwd, options) {
|
|
18
|
+
const ops = options?.operations ?? defaultEditOperations;
|
|
19
|
+
return {
|
|
20
|
+
name: "edit",
|
|
21
|
+
label: "edit",
|
|
22
|
+
description: "Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.",
|
|
23
|
+
parameters: editSchema,
|
|
24
|
+
execute: async (_toolCallId, { path, oldText, newText }, signal) => {
|
|
25
|
+
const absolutePath = resolveToCwd(path, cwd);
|
|
26
|
+
validatePathWithinCwd(absolutePath, cwd);
|
|
27
|
+
return withAbortSignal(signal, async (isAborted) => {
|
|
28
|
+
try {
|
|
29
|
+
await ops.access(absolutePath);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new Error(`File not found: ${path}`);
|
|
33
|
+
}
|
|
34
|
+
if (isAborted())
|
|
35
|
+
return { content: [], details: undefined };
|
|
36
|
+
const buffer = await ops.readFile(absolutePath);
|
|
37
|
+
const rawContent = buffer.toString("utf-8");
|
|
38
|
+
if (isAborted())
|
|
39
|
+
return { content: [], details: undefined };
|
|
40
|
+
const { bom, text: content } = stripBom(rawContent);
|
|
41
|
+
const originalEnding = detectLineEnding(content);
|
|
42
|
+
const normalizedContent = normalizeToLF(content);
|
|
43
|
+
const normalizedOldText = normalizeToLF(oldText);
|
|
44
|
+
const normalizedNewText = normalizeToLF(newText);
|
|
45
|
+
const matchResult = fuzzyFindText(normalizedContent, normalizedOldText);
|
|
46
|
+
if (!matchResult.found) {
|
|
47
|
+
throw new Error(`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`);
|
|
48
|
+
}
|
|
49
|
+
const fuzzyContent = normalizeForFuzzyMatch(normalizedContent);
|
|
50
|
+
const fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);
|
|
51
|
+
const occurrences = fuzzyContent.split(fuzzyOldText).length - 1;
|
|
52
|
+
if (occurrences > 1) {
|
|
53
|
+
throw new Error(`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`);
|
|
54
|
+
}
|
|
55
|
+
if (isAborted())
|
|
56
|
+
return { content: [], details: undefined };
|
|
57
|
+
const baseContent = matchResult.contentForReplacement;
|
|
58
|
+
const newContent = baseContent.substring(0, matchResult.index) +
|
|
59
|
+
normalizedNewText +
|
|
60
|
+
baseContent.substring(matchResult.index + matchResult.matchLength);
|
|
61
|
+
if (baseContent === newContent) {
|
|
62
|
+
throw new Error(`No changes made to ${path}. The replacement produced identical content.`);
|
|
63
|
+
}
|
|
64
|
+
const finalContent = bom + restoreLineEndings(newContent, originalEnding);
|
|
65
|
+
await ops.writeFile(absolutePath, finalContent);
|
|
66
|
+
if (isAborted())
|
|
67
|
+
return { content: [], details: undefined };
|
|
68
|
+
const diffResult = generateDiffString(baseContent, newContent);
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: "text", text: `Successfully replaced text in ${path}.` }],
|
|
71
|
+
details: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export const editTool = createEditTool(process.cwd());
|
|
78
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
import { type TruncationResult } from "./truncate.js";
|
|
4
|
+
declare const findSchema: import("@sinclair/typebox").TObject<{
|
|
5
|
+
pattern: import("@sinclair/typebox").TString;
|
|
6
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
7
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
8
|
+
}>;
|
|
9
|
+
export type FindToolInput = Static<typeof findSchema>;
|
|
10
|
+
export interface FindToolDetails {
|
|
11
|
+
truncation?: TruncationResult;
|
|
12
|
+
resultLimitReached?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface FindOperations {
|
|
15
|
+
exists: (absolutePath: string) => Promise<boolean> | boolean;
|
|
16
|
+
glob: (pattern: string, cwd: string, options: {
|
|
17
|
+
ignore: string[];
|
|
18
|
+
limit: number;
|
|
19
|
+
}) => Promise<string[]> | string[];
|
|
20
|
+
}
|
|
21
|
+
export interface FindToolOptions {
|
|
22
|
+
operations?: FindOperations;
|
|
23
|
+
}
|
|
24
|
+
export declare function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema>;
|
|
25
|
+
export declare const findTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
26
|
+
pattern: import("@sinclair/typebox").TString;
|
|
27
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
28
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
29
|
+
}>, any>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=find.d.ts.map
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { globSync } from "glob";
|
|
6
|
+
import { resolveToCwd, validatePathWithinCwd } from "./path-utils.js";
|
|
7
|
+
import { DEFAULT_MAX_BYTES, formatSize, truncateHead } from "./truncate.js";
|
|
8
|
+
const findSchema = Type.Object({
|
|
9
|
+
pattern: Type.String({
|
|
10
|
+
description: "Glob pattern to match files, e.g. '*.ts', '**/*.json', or 'src/**/*.spec.ts'",
|
|
11
|
+
}),
|
|
12
|
+
path: Type.Optional(Type.String({ description: "Directory to search in (default: current directory)" })),
|
|
13
|
+
limit: Type.Optional(Type.Number({ description: "Maximum number of results (default: 1000)" })),
|
|
14
|
+
});
|
|
15
|
+
const DEFAULT_LIMIT = 1000;
|
|
16
|
+
const defaultFindOperations = {
|
|
17
|
+
exists: existsSync,
|
|
18
|
+
glob: async (pattern, searchCwd, { ignore, limit }) => {
|
|
19
|
+
const results = [];
|
|
20
|
+
try {
|
|
21
|
+
const found = globSync(pattern, {
|
|
22
|
+
cwd: searchCwd,
|
|
23
|
+
dot: true,
|
|
24
|
+
ignore: ["**/node_modules/**", "**/.git/**", ...ignore],
|
|
25
|
+
mark: false,
|
|
26
|
+
});
|
|
27
|
+
for (let i = 0; i < Math.min(found.length, limit); i++) {
|
|
28
|
+
results.push(path.join(searchCwd, found[i]));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// return empty on error
|
|
33
|
+
}
|
|
34
|
+
return results;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export function createFindTool(cwd, options) {
|
|
38
|
+
const customOps = options?.operations;
|
|
39
|
+
return {
|
|
40
|
+
name: "find",
|
|
41
|
+
label: "find",
|
|
42
|
+
description: `Search for files by glob pattern. Returns matching file paths relative to the search directory. Output truncated to ${DEFAULT_LIMIT} results or ${DEFAULT_MAX_BYTES / 1024}KB.`,
|
|
43
|
+
parameters: findSchema,
|
|
44
|
+
execute: async (_toolCallId, { pattern, path: searchDir, limit }, signal) => {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
if (signal?.aborted) {
|
|
47
|
+
reject(new Error("Operation aborted"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const onAbort = () => reject(new Error("Operation aborted"));
|
|
51
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
52
|
+
void (async () => {
|
|
53
|
+
try {
|
|
54
|
+
const searchPath = resolveToCwd(searchDir ?? ".", cwd);
|
|
55
|
+
const normalizedSearchPath = path.resolve(searchPath);
|
|
56
|
+
const homeDir = path.resolve(os.homedir());
|
|
57
|
+
if (normalizedSearchPath === homeDir) {
|
|
58
|
+
reject(new Error("Access denied: Searching the home directory is not allowed. Use a subdirectory instead."));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
validatePathWithinCwd(searchPath, cwd);
|
|
62
|
+
const effectiveLimit = limit ?? DEFAULT_LIMIT;
|
|
63
|
+
const ops = customOps ?? defaultFindOperations;
|
|
64
|
+
if (!(await ops.exists(searchPath))) {
|
|
65
|
+
reject(new Error(`Path not found: ${searchPath}`));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const results = await ops.glob(pattern, searchPath, {
|
|
69
|
+
ignore: ["**/node_modules/**", "**/.git/**"],
|
|
70
|
+
limit: effectiveLimit,
|
|
71
|
+
});
|
|
72
|
+
signal?.removeEventListener("abort", onAbort);
|
|
73
|
+
if (results.length === 0) {
|
|
74
|
+
resolve({
|
|
75
|
+
content: [{ type: "text", text: "No files found matching pattern" }],
|
|
76
|
+
details: undefined,
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const relativized = results.map((p) => {
|
|
81
|
+
if (p.startsWith(searchPath + path.sep) || p.startsWith(searchPath + "/")) {
|
|
82
|
+
return p.slice(searchPath.length + 1).replace(/\\/g, "/");
|
|
83
|
+
}
|
|
84
|
+
return path.relative(searchPath, p).replace(/\\/g, "/");
|
|
85
|
+
});
|
|
86
|
+
const resultLimitReached = relativized.length >= effectiveLimit;
|
|
87
|
+
const rawOutput = relativized.join("\n");
|
|
88
|
+
const truncation = truncateHead(rawOutput, { maxLines: Number.MAX_SAFE_INTEGER });
|
|
89
|
+
let resultOutput = truncation.content;
|
|
90
|
+
const details = {};
|
|
91
|
+
const notices = [];
|
|
92
|
+
if (resultLimitReached) {
|
|
93
|
+
notices.push(`${effectiveLimit} results limit reached. Use limit=${effectiveLimit * 2} for more, or refine pattern`);
|
|
94
|
+
details.resultLimitReached = effectiveLimit;
|
|
95
|
+
}
|
|
96
|
+
if (truncation.truncated) {
|
|
97
|
+
notices.push(`${formatSize(DEFAULT_MAX_BYTES)} limit reached`);
|
|
98
|
+
details.truncation = truncation;
|
|
99
|
+
}
|
|
100
|
+
if (notices.length > 0)
|
|
101
|
+
resultOutput += `\n\n[${notices.join(". ")}]`;
|
|
102
|
+
resolve({
|
|
103
|
+
content: [{ type: "text", text: resultOutput }],
|
|
104
|
+
details: Object.keys(details).length > 0 ? details : undefined,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
signal?.removeEventListener("abort", onAbort);
|
|
109
|
+
reject(e);
|
|
110
|
+
}
|
|
111
|
+
})();
|
|
112
|
+
});
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export const findTool = createFindTool(process.cwd());
|
|
117
|
+
//# sourceMappingURL=find.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
import { type TruncationResult } from "./truncate.js";
|
|
4
|
+
declare const grepSchema: import("@sinclair/typebox").TObject<{
|
|
5
|
+
pattern: import("@sinclair/typebox").TString;
|
|
6
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
7
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
8
|
+
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
9
|
+
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
10
|
+
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
11
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
12
|
+
}>;
|
|
13
|
+
export type GrepToolInput = Static<typeof grepSchema>;
|
|
14
|
+
export interface GrepToolDetails {
|
|
15
|
+
truncation?: TruncationResult;
|
|
16
|
+
matchLimitReached?: number;
|
|
17
|
+
linesTruncated?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface GrepOperations {
|
|
20
|
+
isDirectory: (absolutePath: string) => Promise<boolean> | boolean;
|
|
21
|
+
readFile: (absolutePath: string) => Promise<string> | string;
|
|
22
|
+
}
|
|
23
|
+
export interface GrepToolOptions {
|
|
24
|
+
operations?: GrepOperations;
|
|
25
|
+
}
|
|
26
|
+
export declare function createGrepTool(cwd: string, options?: GrepToolOptions): AgentTool<typeof grepSchema>;
|
|
27
|
+
export declare const grepTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
28
|
+
pattern: import("@sinclair/typebox").TString;
|
|
29
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
30
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
31
|
+
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
32
|
+
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
33
|
+
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
34
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
35
|
+
}>, any>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=grep.d.ts.map
|