{ "description": "The following guidance helps you create a smoothly running Robogator script task from the very start", "dotnetVersion": "10.0.10", "c# approach": [ "Execution is handled by Roslyn 5", "Skip classes and namespaces, use top-level functions instead", "Using statements should include braces {} explicitly declare variable types instead of var", "When using async, always await to ensure the script completes before proceeding", "Only use standard .NET libraries or libraries specifically listed in this specification", "NEVER add a library reference directive of any kind. #r \"nuget: Npgsql, 10.0.3\", #r \"Npgsql.dll\", #:package Npgsql@10.0.3 and <PackageReference> are all invalid here and break the Roslyn compiler. Every library listed under 'libraries' is already referenced by the host, so a plain using directive for the documented namespace is the only thing a script needs. See 'references' for details", "NEVER output empty or blank console messages. Robogator handles all structural spacing automatically. If a blank line is absolutely required, you MUST pass an explicit empty string \"\" — never omit the content or send whitespace-only messages." ], "keys": [ "If a single key is needed, use the predefined keyDefaultFirst C# string variable (not a const) to access the required secrets or passwords in the script. If multiple keys are needed, use string key parameter key[\"firstKeyName\"], then string key parameter key[\"secondKeyName\"], and so on. Use this for API keys, passwords, and other secrets" ], "parameters": [ "Access Robogator string parameters dynamically via param[\"ParameterKey\"]. The key is a string, not a constant, and should either be defined by the user or provided in the response so the user knows how to name the Robogator parameter. Do not use it for sensitive keys and secrets, use keys instead" ], "cancellation": { "description": "Support the kill switch that cancels a running C# script at runtime. You may need to manually place cancellation stops in the script", "default": "Every Chat message creation checks for an ongoing cancellation by default", "longRunningLoops": "For long running loops where no Chat message is created during the loop, call Script.CancellationCheck() inside the loop. This lets the script be killed in a well-behaved and traceable way", "method": "Script.CancellationCheck();", "example": "using System.Threading; Console.WriteLine(\"Long running loop has started\"); for (int i = 0; i < 100; i++) { Script.CancellationCheck(); Thread.Sleep(2000); }" }, "errorLogging": { "description": "Manually set the state of a Chat message to 'Error occurred in runtime' while still writing a message to the Chat. Use this to log partial errors during a running Task without necessarily aborting it", "method": "Console.WriteLineError(\"This is an error\");", "behavior": "Writes the supplied text to the Chat and simultaneously sets that Chat message state to 'Error occurred in runtime'", "tryCatch": "Combine with try/catch so you can track errors even when the Task runs all the way to completion. This lets you record partial failures inside catch blocks while letting the rest of the Task continue", "trailStatistic": "Every partial error logged via Console.WriteLineError is counted toward the Trail statistic", "finishedTaskState": "If one or more partial errors were logged via Console.WriteLineError, the finished Task state is 'Error occurred in runtime'", "example": "try { Console.WriteLine(\"Processing record\"); /* work that may fail */ } catch (Exception ex) { Console.WriteLineError(\"This is an error: \" + ex.Message); }" }, "chatFormatting": { "description": "Special inline markers in Console.WriteLine output that Robogator renders in the Chat message. These only apply to Chat message content written to the console", "links": { "marker": "%", "usage": "Wrap a link with % at the start and % at the end to make it a one-click action. Works for web links and local file/folder paths. Robogator decides automatically whether to open the standard browser (web link), open Explorer (folder), or open the default app (file)", "example": "Console.WriteLine(@\"Open the web link %https://robogator.io% or a local directory %C:\\temp%\");" }, "bold": { "marker": "*", "usage": "Wrap a part of the message with * at the start and * at the end to render that part in bold", "example": "Console.WriteLine(\"Hello *World!* is bold\");" }, "json": { "marker": "~", "usage": "Wrap a serialized JSON string with ~ at the start and ~ at the end to render it as fully formatted, visually appealing JSON in the Chat message", "example": "string response = JsonSerializer.Serialize(obj); Console.WriteLine(\"~\" + response + \"~\");" } }, "references": { "description": "How libraries become available to a script. Read this before writing any using directive", "rule": "Standard .NET and every library listed under 'libraries' are already loaded and referenced by the Robogator host. A script declares nothing and installs nothing. A using directive for the documented namespace is both sufficient and the only permitted form", "forbidden": [ "#r \"nuget: Npgsql, 10.0.3\"", "#r \"Npgsql, 10.0.3\"", "#r \"Npgsql.dll\"", "#r \"C:\\path\\to\\Npgsql.dll\"", "#:package Npgsql@10.0.3", "#addin nuget:?package=Npgsql", "", "dotnet add package Npgsql" ], "reason": "Roslyn 5 scripting resolves #r only against assembly paths supplied by the host metadata resolver. The 'nuget:' form belongs to dotnet-script and C# Interactive, not to the compiler, and fails at compile time. The other forms are project-file or CLI syntax and are not valid C# at all", "wrong": "#r \"nuget: Npgsql, 10.0.3\"\nusing Npgsql;", "correct": "using Npgsql;", "unavailableLibrary": "If a required library is not listed under 'libraries', it is not available and cannot be added. Do not emit a reference directive for it and do not write code against it. Say in the response that the library is unavailable, then solve the task with standard .NET or with a listed library instead", "troubleshooting": "A CS0246 error such as 'The type or namespace name Npgsql could not be found' is never fixed by adding a reference directive in the script. It means the host has not referenced the assembly, which is a host configuration issue outside the script" }, "libraries": { "description": "All NuGet libraries available to the script in addition to standard .NET. This list is exhaustive. Do not use any library not listed here and never add one via a reference directive — see 'references'. Each entry is preloaded by the host and reached with a plain using directive for the given namespace", "pdf": { "nuget": "Syncfusion.Pdf.Net.Core", "version": "34.2.2", "namespace": "Syncfusion.Pdf", "use": "Create and edit PDFs", "images": "PdfBitmap is the Syncfusion type for rendering images in a PDF and uses an image stream PdfBitmap image = new PdfBitmap(imageStream), Syncfusion.Pdf does not accept a System.Drawing.Bitmap in the PdfBitmap constructor. It expects either: a Stream, or a file path" }, "htmlToPdf": { "nuget": "Syncfusion.HtmlToPdfConverter.Net.Windows", "version": "34.2.2", "namespace": "Syncfusion.HtmlConverter (not Syncfusion.PDF.HtmlConverter)", "use": "Convert HTML to PDF" }, "ocr": { "nuget": "Syncfusion.PDF.OCR.Net.Core", "version": "34.2.2", "namespace": "Syncfusion.OCRProcessor", "use": "OCR text from scanned PDFs" }, "pdfToImage": { "nuget": "Syncfusion.PdfToImageConverter.Net", "version": "34.2.2", "namespace": "Syncfusion.Pdf.Parsing", "use": "Render PDF pages to images" }, "sqlServer": { "nuget": "Microsoft.Data.SqlClient", "version": "7.0.2", "namespace": "Microsoft.Data.SqlClient", "use": "Connect to and query SQL Server databases" }, "browserAutomation": { "nuget": "Microsoft.Playwright", "version": "1.61.0", "namespace": "Microsoft.Playwright", "use": "Headless/headful browser automation and web scraping", "note": "Requires browser binaries in the runtime. If not preinstalled, run Microsoft.Playwright.Program.Main(new string[]{\"install\"}) once before launching a browser" }, "microsoftGraph": { "nuget": "Microsoft.Graph", "version": "6.5.0", "namespace": "Microsoft.Graph", "use": "Microsoft 365 / Graph API: mail, OneDrive, Teams, users, calendar, etc.", "note": "Authenticate by building GraphServiceClient with a credential from Azure.Identity, e.g. new ClientSecretCredential(tenantId, clientId, clientSecret)" }, "azureIdentity": { "nuget": "Azure.Identity", "version": "1.21.0", "namespace": "Azure.Identity", "use": "Credential types (ClientSecretCredential, DefaultAzureCredential, etc.) for Microsoft Graph and other Azure SDK clients" }, "outlookMessages": { "nuget": "MsgReader", "version": "6.1.0", "namespace": "MsgReader.Outlook", "use": "Parse Outlook .msg and .eml files (subject, body, attachments)" }, "ssh": { "nuget": "SSH.NET", "version": "2026.0.0", "namespace": "Renci.SshNet", "use": "SSH command execution, SFTP and SCP file transfer" }, "postgreSql": { "nuget": "Npgsql", "version": "10.0.3", "namespace": "Npgsql", "use": "Connect to and query PostgreSQL databases", "note": "Bind passwords via keys, never inline: string connString = \"Host=srv;Database=db;Username=user;Password=\" + keyDefaultFirst. Parameters are positional: use $1, $2 in the SQL and cmd.Parameters.AddWithValue(value) in order. For timestamp with time zone columns, DateTime values must have Kind=Utc or Npgsql throws" } } }