### Install Dependencies and Run UI Source: https://github.com/obot-platform/nanobot/blob/main/workspaces.md Installs project dependencies using pnpm and starts the development server for the UI. ```shell pnpm i pnpm run dev ``` -------------------------------- ### Start Frontend Development Server (pnpm) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Starts the SvelteKit development server, which runs on port 5173. This command is executed from the './ui' directory. ```bash pnpm run dev ``` -------------------------------- ### Simple Review Workflow Example Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Example of a basic workflow for reviewing code changes. It includes frontmatter, inputs, and steps that reference each other. ```markdown --- name: code-review description: "Review code changes for quality issues." metadata: createdAt: "2026-01-15T09:00:00Z" --- ## Inputs - **target** (optional): Files to review. Default: `.` ## Steps ### 1. Find Changes Find all modified code files in {{input.target}}. ### 2. Review Code Review these files for quality issues: {{Find Changes}} Focus on: error handling, edge cases, and readability. ## Output {{Review Code}} ``` -------------------------------- ### Browser-use CLI Quick Start Commands Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Basic commands for navigating, inspecting, interacting, and closing a browser session. Use these for quick automation tasks. ```bash browser-use --browser chromium --headed open https://example.com # Navigate to URL ``` ```bash browser-use state # Get page elements with indices ``` ```bash browser-use click 5 # Click element by index ``` ```bash browser-use type "Hello World" # Type text ``` ```bash browser-use screenshot # Take screenshot ``` ```bash browser-use close # Close browser ``` -------------------------------- ### Install Nanobot CLI with Homebrew Source: https://github.com/obot-platform/nanobot/blob/main/README.md Installs the Nanobot CLI using Homebrew, enabling you to run and manage your MCP host. ```bash brew install obot-platform/tap/nanobot ``` -------------------------------- ### Minimal Nanobot Configuration Example Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md This example demonstrates a basic YAML configuration for Nanobot, defining an agent and an MCP server. Ensure your agent and MCP server configurations are correctly specified. ```yaml agents: myagent: name: My Agent model: gpt-4 mcpServers: my-mcp-server mcpServers: my-mcp-server: url: https://example.com/mcp ``` -------------------------------- ### Install Frontend Dependencies (pnpm) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Installs frontend dependencies using pnpm. This command is typically run within the './ui' directory. ```bash pnpm install ``` -------------------------------- ### Start Svelte development server Source: https://github.com/obot-platform/nanobot/blob/main/packages/ui/README.md Run `npm run dev` to start the development server. Use the `-- --open` flag to automatically open the application in a new browser tab. ```sh npm run dev # or start the server and open the app in a new browser tab npm run dev -- --open ``` -------------------------------- ### Example Integration Test Source: https://github.com/obot-platform/nanobot/blob/main/integration_test/README.md A Go test case demonstrating how to set up the LLM client, a tool call recorder with mock responses, and run the agent with a prompt. Asserts that a specific tool was called. ```go func TestMySkillBehavior(t *testing.T) { apiKey := os.Getenv("ANTHROPIC_API_KEY") if apiKey == "" { t.Fatal("ANTHROPIC_API_KEY must be set when running integration tests") } completer := llm.NewClient(llm.Config{ DefaultModel: "claude-sonnet-4-6", Anthropic: anthropic.Config{APIKey: apiKey}, }) recorder := newRecorder(map[string]ToolHandler{ // Register tools the agent is expected to call with mock responses. "bash": func(req mcp.CallToolRequest) *mcp.CallToolResult { return &mcp.CallToolResult{ Content: []mcp.Content{{Type: "text", Text: "mock output"}}, } }, }) ctx, svc := newTestRuntime(t, completer, recorder) if err := runAgent(ctx, svc, "my prompt"); err != nil { t.Fatalf("Complete() failed: %v", err) } call := recorder.find("bash") if call == nil { t.Fatalf("expected bash call\nall tool calls:\n%s", recorder.summary()) } // assert call.Arguments as needed } ``` -------------------------------- ### Run Nanobot with Configuration Source: https://github.com/obot-platform/nanobot/blob/main/README.md Starts the Nanobot MCP host using a specified YAML configuration file. The UI will be accessible at http://localhost:8080. ```bash nanobot run ./nanobot.yaml ``` -------------------------------- ### Workflow with Conditions Example Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Example of a workflow that uses conditional logic to determine its execution path. It analyzes an issue and applies a fix only if deemed safe. ```markdown --- name: smart-fix description: "Analyze an issue and apply a fix only if it's safe to do so." metadata: createdAt: "2026-01-15T09:00:00Z" --- ## Steps ### 1. Analyze Issue Analyze the reported issue and determine severity. ### 2. Check Safety Based on this analysis, determine if an automated fix is safe: {{Analyze Issue}} End your response with SAFE or UNSAFE. ### 3. Apply Fix Apply the fix for: {{Analyze Issue}} **Condition:** {{Check Safety}} contains SAFE ### 4. Create Manual Report Create a report explaining why manual intervention is needed: {{Analyze Issue}} **Condition:** {{Check Safety}} contains UNSAFE ``` -------------------------------- ### Get Page State and Screenshots Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Retrieve information about the current page or capture screenshots. ```bash browser-use state # Get URL, title, and clickable elements ``` ```bash browser-use screenshot # Take screenshot (outputs base64) ``` ```bash browser-use screenshot path.png # Save screenshot to file ``` ```bash browser-use screenshot --full path.png # Full page screenshot ``` -------------------------------- ### Install Published Workflow Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Use `installArtifact` to download and extract a published workflow into your local `workflows/` directory. This will overwrite any existing local workflow with the same name. ```javascript installArtifact({ "id": "" }) ``` ```javascript installArtifact({ "id": "", "version": 2 }) ``` -------------------------------- ### CAPTCHA Solving Workflow with browser-use Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Example of handling CAPTCHAs by pausing automation, informing the user, and resuming after manual intervention in VNC. Always use `--headed` mode when CAPTCHAs are expected. ```bash # You're automating a task and hit a CAPTCHA browser-use --browser chromium --headed open https://example.com browser-use state # → Detects CAPTCHA verification challenge # STOP and inform user: # "I've encountered a CAPTCHA that needs human verification. # Please open the BrowserView pane in the Nanobot UI # and solve the CAPTCHA. Let me know when you're done." # Wait for user confirmation, then continue: browser-use state # Verify CAPTCHA is solved browser-use click 5 # Continue with automation ``` -------------------------------- ### Execute Python Script with Dependencies Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/python-scripts.md Write a Python script with inline dependencies declared in a '# /// script' block. uv automatically installs these dependencies before running the script. Use this for tasks requiring external libraries like network requests. ```python #!/usr/bin/env python3 # /// script # requires-python = ">=3.11" dependencies = [ "requests", ] # /// import json import requests data = requests.get("https://api.example.com/data").json() print(json.dumps(data)) ``` ```bash uv run script.py ``` -------------------------------- ### Cookie Management Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Commands for getting, setting, clearing, importing, and exporting browser cookies. ```bash browser-use cookies get # Get all cookies ``` ```bash browser-use cookies get --url # Get cookies for specific URL ``` ```bash browser-use cookies set # Set a cookie ``` ```bash browser-use cookies set name val --domain .example.com --secure --http-only ``` ```bash browser-use cookies clear # Clear all cookies ``` ```bash browser-use cookies clear --url # Clear cookies for specific URL ``` ```bash browser-use cookies export # Export all cookies to JSON file ``` ```bash browser-use cookies export --url # Export cookies for specific URL ``` ```bash browser-use cookies import # Import cookies from JSON file ``` -------------------------------- ### Set up UI Development Environment Source: https://github.com/obot-platform/nanobot/blob/main/README.md Steps to prepare the UI directory for development, including removing old build artifacts and rebuilding the Nanobot binary. ```bash rm -rf ./ui/dist ``` ```bash make ``` ```bash cd ui npm run dev ``` -------------------------------- ### Run Nanobot with Configuration (Go) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Executes the nanobot binary using a specified configuration file. ```bash ./bin/nanobot run ./nanobot.yaml ``` -------------------------------- ### Build Frontend for Production (pnpm) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Builds the SvelteKit application for production deployment. ```bash pnpm run build ``` -------------------------------- ### Build Nanobot Binary (Go) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Builds the nanobot binary. This command also automatically builds the UI via go generate. Run this first if building manually with `go build` to ensure the UI is embedded. ```bash make ``` -------------------------------- ### Build and Run Nanobot with Workspaces Source: https://github.com/obot-platform/nanobot/blob/main/workspaces.md Builds the nanobot project using the make command and then runs it with a specified workspaces YAML configuration. ```shell make ./bin/nanobot run ./workspaces.yaml ``` -------------------------------- ### Run Nanobot with Directory Configuration Source: https://github.com/obot-platform/nanobot/blob/main/README.md Executes Nanobot using configurations from a specified directory. If no path is provided, it defaults to the .nanobot/ directory. ```bash nanobot run ./my-config/ ``` -------------------------------- ### Create a new Svelte project Source: https://github.com/obot-platform/nanobot/blob/main/packages/ui/README.md Use `npx sv create` to initialize a new Svelte project. Specify a directory name to create the project in a subfolder. ```sh npx sv create # create a new project in my-app npx sv create my-app ``` -------------------------------- ### Run Directory-Based Configuration Source: https://github.com/obot-platform/nanobot/blob/main/examples/directory-config/README.md Execute a nanobot project configured via a directory structure. This command initiates the nanobot with the specified configuration. ```bash nanobot run ./examples/directory-config/ ``` -------------------------------- ### Browser Modes for browser-use Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Demonstrates different browser modes: recommended headed Chromium, headless Chromium for background tasks, and 'real' Chrome for using existing user sessions. ```bash browser-use --browser chromium --headed open # Recommended default: visible Chromium window ``` ```bash browser-use --browser chromium open # Headless Chromium for explicit background runs ``` ```bash browser-use --browser real open # User's Chrome with login sessions ``` -------------------------------- ### Build Docker Image Source: https://github.com/obot-platform/nanobot/blob/main/workspaces.md Builds the Docker image for the sandbox package. Navigate to the correct directory before running. ```shell cd ./packages/sandbox/src/lib/ docker build -t sandbox-test . ``` -------------------------------- ### Open Browser with Profile Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Open a real browser instance using a specific Chrome profile, preserving its cookies and login data. ```bash browser-use --browser real --profile "Profile 1" open https://gmail.com ``` -------------------------------- ### Build Svelte project for production Source: https://github.com/obot-platform/nanobot/blob/main/packages/ui/README.md Execute `npm run build` to generate a production-ready build of your Svelte application. Preview the build using `npm run preview`. ```sh npm run build ``` -------------------------------- ### Run Go Tests Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Executes all Go tests within the project. ```bash go test ./... ``` -------------------------------- ### Generate Code (Go) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Generates code, including building the UI and running Go code generation. This is a prerequisite if building manually with `go build` to ensure the UI is embedded. ```bash go generate ./... ``` -------------------------------- ### Nanobot Single File Configuration Source: https://github.com/obot-platform/nanobot/blob/main/README.md Defines agents and MCP servers in a single YAML file. Nanobot automatically selects the LLM provider based on the model specified. ```yaml agents: dealer: name: Blackjack Dealer model: gpt-4.1 mcpServers: blackjackmcp mcpServers: blackjackmcp: url: https://blackjack.nanobot.ai/mcp ``` -------------------------------- ### Profile Management Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md List available local Chrome profiles for use with the `--browser real` option. ```bash browser-use profile list-local ``` -------------------------------- ### Navigate and Scroll Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Use these commands to navigate between web pages and control scrolling. ```bash browser-use open # Navigate to URL ``` ```bash browser-use back # Go back in history ``` ```bash browser-use scroll down # Scroll down ``` ```bash browser-use scroll up # Scroll up ``` -------------------------------- ### Shared Resources Configuration in nanobot.yaml Source: https://github.com/obot-platform/nanobot/blob/main/README.md Configures LLM providers and MCP servers for shared use across agents. MCP servers require a URL and authorization headers. ```yaml llmProviders: ollama: dialect: OpenResponses baseURL: http://localhost:11434/v1 mcpServers: store: url: https://example.com/mcp headers: Authorization: Bearer ${MY_TOKEN} ``` -------------------------------- ### Format Go Code Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Formats Go code according to standard Go conventions. ```bash gofmt -w . ``` -------------------------------- ### Lint and Format Frontend Code (pnpm) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Lints and formats the frontend code using pnpm scripts. ```bash pnpm run lint ``` ```bash pnpm run format ``` -------------------------------- ### Configure LLM Providers in nanobot.yaml Source: https://github.com/obot-platform/nanobot/blob/main/README.md Defines various LLM providers including built-in and custom options. Ensure API keys and base URLs are correctly set. Supports OpenAI, Anthropic, Azure, Bedrock, and Ollama. ```yaml llmProviders: # Built-in providers — shown here for reference or to override baseURL/headers openai: dialect: OpenAIResponses apiKey: ${OPENAI_API_KEY} baseURL: ${OPENAI_BASE_URL} # optional, default: https://api.openai.com/v1 anthropic: dialect: AnthropicMessages apiKey: ${ANTHROPIC_API_KEY} baseURL: ${ANTHROPIC_BASE_URL} # optional, default: https://api.anthropic.com/v1 # Custom providers pointing at any compatible endpoint azureOpenAI: dialect: OpenAIResponses apiKey: ${AZURE_API_KEY} baseURL: https://.cognitiveservices.azure.com/openai/v1 azureAnthropic: dialect: AnthropicMessages apiKey: ${AZURE_ANTHROPIC_KEY} baseURL: https://.services.ai.azure.com/anthropic/v1 bedrockOpenAI: dialect: OpenAIResponses apiKey: ${BEDROCK_API_KEY} baseURL: https://bedrock-mantle.us-east-1.api.aws/v1 ollama: dialect: OpenResponses baseURL: http://localhost:11434/v1 ``` -------------------------------- ### Execute JavaScript Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Run JavaScript code within the browser context and retrieve the result. ```bash browser-use eval "document.title" # Execute JavaScript, return result ``` -------------------------------- ### Run Integration Tests Source: https://github.com/obot-platform/nanobot/blob/main/integration_test/README.md Execute integration tests using a specific build tag and control the number of prompt runs. Ensure the ANTHROPIC_API_KEY is set. ```bash ANTHROPIC_API_KEY=... go test -tags integration ./integration_test/ -runs 5 ``` -------------------------------- ### Open Browser Without Profile Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Open a real browser instance without a specific profile, resulting in a fresh browser state with no existing logins. ```bash browser-use --browser real open https://gmail.com ``` -------------------------------- ### browser-use Headed Mode for VNC Viewing Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Use `--headed` mode with `browser-use` for visible browser sessions accessible via VNC. This is recommended for CAPTCHA solving and debugging. ```bash # RECOMMENDED DEFAULT (visible in VNC viewer, user can interact) browser-use --browser chromium --headed open https://example.com ``` ```bash # HEADLESS ONLY WHEN EXPLICITLY APPROPRIATE (faster, but user can't see it) browser-use --browser chromium open https://example.com ``` -------------------------------- ### Run Specific Go Test Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Executes a specific Go test case identified by its name within a given package. ```bash go test ./pkg/agents -run TestName ``` -------------------------------- ### Tab Management Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Commands for switching, closing, and managing browser tabs. ```bash browser-use switch # Switch to tab by index ``` ```bash browser-use close-tab # Close current tab ``` ```bash browser-use close-tab # Close specific tab ``` -------------------------------- ### List Available Subjects Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Use `listSubjects` to find valid user or group IDs for setting artifact permissions. Leave the query blank to list all visible subjects. ```javascript listSubjects({ "type": "user" | "group", "query": "..." }) ``` ```javascript listSubjects({ "type": "user" }) ``` -------------------------------- ### Session Management Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Commands to list, close, or close all active browser sessions. ```bash browser-use sessions # List active sessions ``` ```bash browser-use close # Close current session ``` ```bash browser-use close --all # Close all sessions ``` -------------------------------- ### Publish Workflow Artifact Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Use `publishArtifact` to bundle and upload a workflow to Obot. Ensure the workflow has a valid `SKILL.md` with frontmatter. This tool is used for the initial publication and subsequent updates. ```javascript publishArtifact({ "workflowName": "code-review" }) ``` -------------------------------- ### Additional Interactions Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Perform advanced interactions like hovering, double-clicking, and right-clicking on elements. ```bash browser-use hover # Hover over element (triggers CSS :hover) ``` ```bash browser-use dblclick # Double-click element ``` ```bash browser-use rightclick # Right-click element (context menu) ``` -------------------------------- ### Set OpenAI API Key Source: https://github.com/obot-platform/nanobot/blob/main/README.md Exports the OpenAI API key as an environment variable. Nanobot uses this to authenticate with OpenAI models. ```bash export OPENAI_API_KEY=sk-... ``` -------------------------------- ### Interact with Page Elements Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Perform actions like clicking, typing, and sending keys to elements identified by their index from `browser-use state`. ```bash browser-use click # Click element ``` ```bash browser-use type "text" # Type text into focused element ``` ```bash browser-use input "text" # Click element, then type text ``` ```bash browser-use keys "Enter" # Send keyboard keys ``` ```bash browser-use keys "Control+a" # Send key combination ``` ```bash browser-use select "option" # Select dropdown option ``` -------------------------------- ### Define MCP Servers in YAML Source: https://github.com/obot-platform/nanobot/blob/main/examples/directory-config/README.md Define MCP server details, including URL and authorization headers, in a YAML file. Ensure only one MCP server configuration file (YAML or JSON) is present. ```yaml myserver: url: https://example.com/mcp headers: Authorization: Bearer ${MY_TOKEN} ``` -------------------------------- ### Remove Old UI Build Artifacts Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Removes the old build directory for the UI before a new build process. ```bash rm -rf ./ui/dist ``` -------------------------------- ### Set Anthropic API Key Source: https://github.com/obot-platform/nanobot/blob/main/README.md Exports the Anthropic API key as an environment variable. Nanobot uses this to authenticate with Anthropic models. ```bash export ANTHROPIC_API_KEY=sk-ant-... ``` -------------------------------- ### Proposing Workflow Changes Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md When suggesting edits to a workflow, present the issue, the current step text, and the proposed change. Always seek user approval before applying modifications. ```markdown ## Proposed Changes to issue-triage.md ### 1. Step: Analyze Issues **Issue:** Agent returned prose instead of JSON. Had to retry. **Change:** Add explicit format requirement. Current: > Analyze each issue and categorize by priority. > Return the results as JSON. Proposed: > Analyze each issue and categorize by priority. > > Return as a JSON array: > [{"number": 1, "title": "...", "priority": "High|Medium|Low", "reason": "..."}] Apply these changes? (yes/no/select specific) ``` -------------------------------- ### Wait Conditions Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Pause execution until specific conditions are met, such as element visibility or text presence, with optional timeouts. ```bash browser-use wait selector "h1" # Wait for element to be visible ``` ```bash browser-use wait selector ".loading" --state hidden # Wait for element to disappear ``` ```bash browser-use wait selector "#btn" --state attached # Wait for element in DOM ``` ```bash browser-use wait text "Success" # Wait for text to appear ``` ```bash browser-use wait selector "h1" --timeout 5000 # Custom timeout in ms ``` -------------------------------- ### Search Published Workflows Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Use `searchArtifacts` to discover workflows shared by other users in the Obot registry. This is essential for finding public or published workflows. ```javascript searchArtifacts({ "query": "code review", "artifactType": "workflow" }) ``` ```javascript searchArtifacts({ "artifactType": "workflow" }) ``` -------------------------------- ### Information Retrieval Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Extract specific information from the page, such as title, HTML content, element text, values, attributes, and bounding boxes. ```bash browser-use get title # Get page title ``` ```bash browser-use get html # Get full page HTML ``` ```bash browser-use get html --selector "h1" # Get HTML of specific element ``` ```bash browser-use get text # Get text content of element ``` ```bash browser-use get value # Get value of input/textarea ``` ```bash browser-use get attributes # Get all attributes of element ``` ```bash browser-use get bbox # Get bounding box (x, y, width, height) ``` -------------------------------- ### Python Execution in Persistent Session Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/browser-use.md Execute Python code within a persistent session, allowing for variable storage and access to a `browser` object with various methods. ```bash browser-use python "x = 42" # Set variable ``` ```bash browser-use python "print(x)" # Access variable (outputs: 42) ``` ```bash browser-use python "print(browser.url)" # Access browser object ``` ```bash browser-use python --vars # Show defined variables ``` ```bash browser-use python --reset # Clear Python namespace ``` ```bash browser-use python --file script.py # Execute Python file ``` -------------------------------- ### Agent Definition in Markdown Source: https://github.com/obot-platform/nanobot/blob/main/README.md Defines an agent's name, model, MCP servers, and instructions. Markdown agents override configurations in nanobot.yaml with the same name. ```markdown --- name: Shopping Assistant model: anthropic/claude-3-7-sonnet-latest mcpServers: - store temperature: 0.7 --- You are a helpful shopping assistant. Help users find products and answer their questions. ``` -------------------------------- ### Type Checking Frontend Code (pnpm) Source: https://github.com/obot-platform/nanobot/blob/main/CLAUDE.md Performs type checking on the frontend TypeScript code. ```bash pnpm run check ``` -------------------------------- ### Python Script Output Conventions Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/python-scripts.md Follow these conventions for Python scripts: print structured JSON data to stdout for results, and print progress or debug information to stderr. Errors should also be printed to stderr and result in a non-zero exit code. ```python import sys import json # Output result print(json.dumps({"items": [...], "count": 42})) # Debug info (won't pollute output) print("Processed 42 items", file=sys.stderr) ``` -------------------------------- ### Set Artifact Sharing Permissions Source: https://github.com/obot-platform/nanobot/blob/main/pkg/servers/system/skills/workflows.md Use `setArtifactSubjects` to control who can access a specific version of a published artifact. Omitting the version updates the latest published version. An empty subjects list makes the version owner-only. ```javascript setArtifactSubjects({ "id": "", "version": , "subjects": [...] }) ``` ```javascript setArtifactSubjects({ "id": "", "subjects": [...] }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.