
Tools.pudu
Pudu94 lines7.1 KB
1/** @Domain.Catalog.Tools.Registry — every tool in listing order */2module PuduLangMcp.Domain.Catalog.Tools34import Std.List as List5import PuduLangMcp.Constants.Server as Server6import PuduLangMcp.Domain.Catalog.ToolSpec as ToolSpec789const LOOKUP: ToolSpec.Annotations = ToolSpec.Annotations{readOnly: true, destructive: false, idempotent: true, openWorld: false}1011const CONFINED_RUN: ToolSpec.Annotations = ToolSpec.Annotations{readOnly: true, destructive: false, idempotent: false, openWorld: false}1213const PROJECT_RUN: ToolSpec.Annotations = ToolSpec.Annotations{readOnly: false, destructive: false, idempotent: false, openWorld: true}141516const SOURCE_OR_PATH: Array[Str] = ["source", "path"]171819export fn all() -> Array[ToolSpec.ToolSpec] {20 [21 spec("pudu_docs_search", "Search Pudu documentation", "Search the Pudu language guide, site pages, release notes, and example programs. Answers the best-matching sections with their address for pudu_docs_read.", [22 ToolSpec.text("query", "Words or a qualified name to look for, such as 'error handling with Result' or 'Option.unwrapOr'.", true),23 ToolSpec.text("group", "Limit the search to one group: docs, pages, releases, or examples.", false),24 ToolSpec.integer("limit", "Most sections to answer.", false, 1, Server.MAX_SEARCH_LIMIT)25 ], [], LOOKUP),26 spec("pudu_docs_read", "Read Pudu documentation", "Read one document, or one section of it, by the slug pudu_docs_search answers. With no section, answers the whole document.", [27 ToolSpec.text("slug", "The document's slug, such as 'errors' or 'ownership'.", true),28 ToolSpec.text("group", "docs (default), pages, releases, or examples.", false),29 ToolSpec.text("section", "A section heading or its anchor, such as 'working-with-results'.", false)30 ], [], LOOKUP),31 spec("pudu_reference_search", "Search the Pudu API", "Search the installed standard library and the workspace's installed packages by name, description, or type shape such as 'Array[a] -> Option[a]'.", [32 ToolSpec.text("query", "A name, words from a description, or a type shape containing '->'.", true),33 ToolSpec.integer("limit", "Most declarations to answer.", false, 1, Server.MAX_SEARCH_LIMIT)34 ], [], LOOKUP),35 spec("pudu_module_reference", "Read a module's API", "Every public declaration of one module with its signature and documentation, such as Std.Json, from the installed toolchain or an installed package.", [36 ToolSpec.text("module", "The module name, such as 'Std.Json' or 'Std.Http.Server'.", true)37 ], [], LOOKUP),38 spec("pudu_check", "Check Pudu code", "Compile Pudu code and report its diagnostics without running it. Pass the code as 'source', or a file in the workspace as 'path'.", sourceOrPath(), SOURCE_OR_PATH, LOOKUP),39 spec("pudu_format", "Format Pudu code", "Answer the code as the Pudu formatter lays it out. Never writes files.", sourceOrPath(), SOURCE_OR_PATH, LOOKUP),40 spec("pudu_lint", "Lint Pudu code", "Report lint findings for Pudu code, each with its rule code and a suggested fix where one is safe.", sourceOrPath(), SOURCE_OR_PATH, LOOKUP),41 spec("pudu_run", "Run a Pudu program", "Run a program's main function confined: it may print, read the clock, and use threads, but not files, processes, the network, or foreign code. Answers its output and exit status.", [42 ToolSpec.text("source", "A complete program with a main function.", true),43 ToolSpec.integer("timeoutMs", "Stop the program after this many milliseconds.", false, 100, Server.MAX_RUN_TIMEOUT_MS)44 ], [], CONFINED_RUN),45 spec("pudu_test", "Run Pudu tests", "Run the workspace's test suites with pudu test, or the suites under one path. Tests run with the workspace's full permissions.", [46 ToolSpec.text("path", "A test file or directory inside the workspace; defaults to every standard test directory.", false),47 ToolSpec.integer("timeoutMs", "Stop the tests after this many milliseconds.", false, 100, Server.MAX_RUN_TIMEOUT_MS)48 ], [], PROJECT_RUN),49 position("pudu_hover", "Hover", "The type and documentation of the name at a position."),50 position("pudu_definition", "Go to definition", "Where the name at a position is declared, with the declaration's source."),51 position("pudu_references", "Find references", "Every use of the name at a position."),52 position("pudu_completion", "Complete code", "What could be written at a position: names, members, and keywords."),53 position("pudu_signature_help", "Signature help", "The signature of the call around a position and which argument the position is in."),54 position("pudu_code_actions", "Code actions", "Quick fixes the language server offers at a position."),55 spec("pudu_rename_preview", "Preview a rename", "The edits that would rename the name at a position. Nothing is written; apply the edits yourself.", positionProperties().push(ToolSpec.text("newName", "The new name.", true)), SOURCE_OR_PATH, LOOKUP),56 spec("pudu_document_symbols", "Outline Pudu code", "Every declaration in the code, with its kind and line.", sourceOrPath(), SOURCE_OR_PATH, LOOKUP),57 spec("pudu_workspace_symbols", "Find workspace symbols", "Declarations across the workspace whose names match a query.", [58 ToolSpec.text("query", "Part of a declaration's name.", true)59 ], [], LOOKUP),60 spec("pudu_toolchain", "Pudu toolchain", "The installed compiler's version and location, the standard library in use, the workspace root, and the documentation revision this server carries.", [], [], LOOKUP)61 ]62}636465export fn find(name: Str) -> Option[ToolSpec.ToolSpec] {66 List.find(&all(), |held: ToolSpec.ToolSpec| held.name == name)67}686970fn spec(name: Str, title: Str, description: Str, properties: Array[ToolSpec.Property], exactlyOne: Array[Str], annotations: ToolSpec.Annotations) -> ToolSpec.ToolSpec {71 ToolSpec.ToolSpec{name: name, title: title, description: description, properties: properties, exactlyOne: exactlyOne, annotations: annotations}72}737475fn sourceOrPath() -> Array[ToolSpec.Property] {76 [77 ToolSpec.text("source", "Pudu code, beginning with its module declaration.", false),78 ToolSpec.text("path", "A .pudu file relative to the workspace root.", false)79 ]80}818283fn positionProperties() -> Array[ToolSpec.Property] {84 sourceOrPath().concat([85 ToolSpec.integer("line", "The 1-based line.", true, 1, 1000000),86 ToolSpec.integer("character", "The 1-based character within the line.", true, 1, 100000)87 ])88}899091fn position(name: Str, title: Str, description: Str) -> ToolSpec.ToolSpec {92 spec(name, title, description + " Pass the code as 'source', or a workspace file as 'path', with a 1-based line and character.", positionProperties(), SOURCE_OR_PATH, LOOKUP)93}94