### Install a plugin Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Install a .dntr file or URL into the running Daintree instance using the 'install' command. ```bash npx daintree-plugin install ./my-plugin-0.1.0.dntr npx daintree-plugin install https://github.com/user/plugin/releases/latest/download/plugin.dntr ``` -------------------------------- ### Clone and Install Daintree from Source Source: https://github.com/daintreehq/daintree/blob/develop/README.md Clone the Daintree repository, navigate into the directory, and install dependencies using npm. ```bash git clone https://github.com/daintreehq/daintree.git cd daintree npm install ``` -------------------------------- ### Start the development loop Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Navigate into your plugin directory and run 'daintree-plugin dev' to start the hot-reload development server. ```bash cd my-plugin npx daintree-plugin dev ``` -------------------------------- ### Install daintree-plugin CLI Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Install the daintree-plugin CLI as a development dependency or use npx to run commands directly. ```bash npm install --save-dev daintree-plugin # or npx daintree-plugin ``` -------------------------------- ### Full plugin.json Schema Example Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/manifest.md This is a comprehensive example of a plugin.json manifest file, illustrating all major fields and their typical usage. ```json { // Scoped plugin identifier. Required. Format: "publisher.plugin-name". // Must be lowercase, use hyphens (not underscores), and contain exactly one period. "name": "acme.linear-planner", // Semver version. Required. "version": "0.1.0", // Human-readable display name. Optional; falls back to `name`. "displayName": "Linear Planner", // One-sentence description, shown in UI listings. "description": "Plan Linear issues as multi-step agent workflows.", // Path to the compiled ESM entry, relative to the plugin directory. // Optional — plugins with only static contributions (themes, static MCP // server configs) don't need one. "main": "dist/index.js", // Host version compatibility. Optional but strongly recommended. // Uses semver range syntax. "engines": { "daintree": "^0.8.0", }, // Declared capabilities, shown to the user at install time. // Disclosure-first with host-side policy effects (no Node sandbox). // See "Capabilities" below and ./trust-model.md. "capabilities": ["fs:project-read", "network:fetch"], // The plugin's UI and functional contributions. "contributes": { "panels": [ /* ... */ ], "toolbarButtons": [ /* ... */ ], "menuItems": [ /* ... */ ], "experimental_views": [ /* ... */ ], "experimental_mcpServers": [ /* ... */ ], "forgeProviders": [ /* ... */ ], "fileDecorationProviders": [ /* ... */ ], }, } ``` -------------------------------- ### Example Static Host URL Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/distribution.md This is an example of a URL pattern for a Daintree plugin archive hosted on a static file server. ```plaintext https://plugins.example.com/linear-planner.dntr ``` -------------------------------- ### Launch AI Coding Agents Source: https://github.com/daintreehq/daintree/blob/develop/help/README.md Quick start commands to launch supported AI coding agents from the 'help' directory. Ensure you have authenticated with the respective services beforehand. ```bash cd help claude # Claude Code gemini --approval-mode=plan # Gemini CLI (plan mode = read-only) codex # Codex CLI ``` -------------------------------- ### Write a Command Handler Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/getting-started.md Implement the logic for a command. This example shows how to display a toast message using the Daintree plugin SDK. ```typescript // src/say-hello.ts import { showToast } from "@daintreehq/plugin-sdk"; export default async function sayHello() { await showToast({ message: "Hello from my plugin" }); } ``` -------------------------------- ### Stats Wrapper Example Source: https://github.com/daintreehq/daintree/blob/develop/docs/themes/visual-guide.md Displays GitHub issues, PRs, and commit counts. Each segment is a clickable button. ```text [ Issues 3 | PRs 2 | Commits 5 ] ``` -------------------------------- ### Development Commands Source: https://github.com/daintreehq/daintree/blob/develop/docs/development.md Common npm scripts for development tasks like installation, running the dev server, building, testing, and fixing code. ```bash npm install # Install deps (or npm ci) npm run dev # Main + Renderer concurrent dev npm run build # Production build npm run check # typecheck + lint + format (run before commits) npm run fix # Auto-fix lint/format npm run test # Vitest once npm run test:watch # Vitest watch mode npm run rebuild # Rebuild node-pty for Electron npm run package # Build + electron-builder ``` -------------------------------- ### Keybinding Action Example Source: https://github.com/daintreehq/daintree/blob/develop/docs/architecture/action-system.md A keybinding configuration maps a key combination to an action ID. The handler then dispatches this action. ```typescript // Keybinding config maps key combo to action ID { key: "Cmd+T", action: "terminal.new" } // The keybinding handler calls dispatch internally ``` -------------------------------- ### Run Plugin Locally with Hot Reload Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/getting-started.md Starts the development server for your plugin, enabling hot reloading and local testing within Daintree. ```bash npm run dev ``` -------------------------------- ### Read Plugin Setting Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/contribution-points.md Example of how to retrieve a plugin setting value using the host API. Settings changes fire subscription callbacks. ```typescript const token = await host.settings.get("linear.apiToken"); ``` -------------------------------- ### Clone and Install Daintree Source: https://github.com/daintreehq/daintree/blob/develop/CONTRIBUTING.md Clone the Daintree repository and install its dependencies. This includes running a postinstall script to rebuild native modules for node-pty. ```bash git clone https://github.com/daintreehq/daintree.git cd daintree npm install # runs the postinstall rebuild for node-pty npm run dev # Main + Renderer with HMR ``` -------------------------------- ### Daintree CLI validation output example Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Example output from 'daintree-plugin validate' showing successful validation and warnings for missing fields. ```bash ✓ plugin.json is valid ⚠ engines.daintree omitted — consider adding ^0.8.0 ⚠ commands[0].keywords is empty — helps discoverability to add 2–3 terms ``` -------------------------------- ### Example GitHub Release Asset URL Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/distribution.md This is a typical URL pattern for downloading a Daintree plugin archive (.dntr file) directly from a GitHub release asset. ```plaintext https://github.com/gpriday/my-plugin/releases/latest/download/gpriday.my-plugin.dntr ``` -------------------------------- ### Configure Vite Plugin for Daintree Source: https://github.com/daintreehq/daintree/blob/develop/packages/plugin-vite/README.md Example Vite configuration in a plugin project using the Daintree Vite plugin. Ensure `build.lib` is configured for ES module output. ```typescript import { defineConfig } from "vite"; import { daintreePlugin } from "@daintreehq/plugin-vite"; export default defineConfig({ plugins: [daintreePlugin()], build: { lib: { entry: "src/index.tsx", formats: ["es"] }, }, }); ``` -------------------------------- ### Logging in Main Process Source: https://github.com/daintreehq/daintree/blob/develop/docs/development.md Example of using the logger utility in the main process for debugging. Import log functions and use them to log information or errors with optional data. ```typescript import { logInfo, logError } from "./utils/logger"; logInfo("ServiceName", "message", { data }); ``` -------------------------------- ### Example Pinned Version URL Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/distribution.md This URL pattern points to a specific version of a Daintree plugin archive, useful for ensuring reproducible installations. ```plaintext https://github.com/gpriday/my-plugin/releases/download/v0.2.0/gpriday.my-plugin.dntr ``` -------------------------------- ### Manual Cold-Start Performance Test Source: https://github.com/daintreehq/daintree/blob/develop/scripts/perf/README.md Run a manual, one-shot cold-start performance test. This command launches the packaged binary multiple times from a fresh profile to gather performance metrics. ```bash npm run perf:cold-start # 5 runs, text table npm run perf:cold-start -- --runs 10 # custom run count npm run perf:cold-start -- --json # structured JSON for diffing ``` -------------------------------- ### Build and Package for Microsoft Store Source: https://github.com/daintreehq/daintree/blob/develop/docs/distribution/microsoft-store.md Use this command to produce a .appx file locally for manual submission to Partner Center. The --publish never flag prevents automatic publishing. ```bash npm run build && npx electron-builder --win appx --publish never ``` -------------------------------- ### Agent Status Examples Source: https://github.com/daintreehq/daintree/blob/develop/docs/themes/visual-guide.md Examples of agent status chip text. ```text [Working] [Idle] [Waiting] [Approval] ``` -------------------------------- ### Conventional Commit Scope Examples Source: https://github.com/daintreehq/daintree/blob/develop/CONTRIBUTING.md Examples of common scopes used in Daintree commit messages. ```text Scopes are domain-specific and should match the area of the codebase you're touching — look at recent commits on `develop` for examples. Common ones: `ipc`, `terminal`, `pty`, `theme`, `setup`, `agents`, `worktree`, `ui`, `hydration`, `bulk`, `e2e`. ``` -------------------------------- ### Conventional Commit Message Examples Source: https://github.com/daintreehq/daintree/blob/develop/CONTRIBUTING.md Examples of well-formatted commit messages following the Conventional Commits standard. ```text fix(ipc): replace sliding-window rate limiter with leaky bucket for worktree creation feat(theme): accent colour override for themes refactor(toolbar): derive agent buttons dynamically from BUILT_IN_AGENT_IDS test(demo): replace fixed timeout with vi.waitFor in DemoCursor test ``` -------------------------------- ### Agent Startup Metrics Log Source: https://github.com/daintreehq/daintree/blob/develop/docs/development.md This log line captures essential metrics about agent startup, including IDs, timestamps, and durations. It's useful for comparing different agent launches. ```text [AgentStartup] {"agentId":"claude","cwdHash":"a1b2c3d4","terminalId":"...","spawnedAt":1700000000000,"firstByteAt":1700000000180,"bootCompleteAt":1700000000420,"bootDurationMs":420,"timeToFirstByteMs":180} ``` -------------------------------- ### Scaffold a new plugin Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Use the 'new' command to create a new plugin project with a predefined structure and dependencies. ```bash npx daintree-plugin new my-plugin ``` -------------------------------- ### Get Terminal Status Source: https://github.com/daintreehq/daintree/blob/develop/help/CLAUDE.md Retrieve the `agentState`, `waitingReason`, and `lastTransitionAt` for a specific terminal. Include `includeOutput` to get recent scrollback. ```json terminal.getStatus({ terminalIds: [] }) terminal.getStatus({ terminalIds: [], includeOutput: { lines: 30 } }) ``` -------------------------------- ### Development and Build Commands Source: https://github.com/daintreehq/daintree/blob/develop/GEMINI.md Common commands for running the development server, building for production, checking code style, fixing issues, and rebuilding native modules. ```bash npm run dev # Vite + Electron concurrent npm run build # Production build npm run check # typecheck + lint + format npm run fix # Auto-fix lint/format npm run rebuild # Rebuild node-pty ``` -------------------------------- ### Launch an Agent with a Task Source: https://github.com/daintreehq/daintree/blob/develop/scripts/help-src/CLAUDE.tasks.md Initiate a new agent (e.g., Claude, Codex) with a specific task prompt and worktree. The prompt is sent as the agent's first message. ```javascript agent.launch({ agentId: "claude" | "codex" | "gemini" | …, prompt: , worktreeId: }) ``` -------------------------------- ### Create a New Daintree Plugin Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/getting-started.md Use this command to scaffold a new Daintree plugin project. It prompts for necessary details and sets up the project structure. ```bash npx create-daintree-plugin my-first-plugin cd my-first-plugin ``` -------------------------------- ### Rebuild Node-Pty for Electron Source: https://github.com/daintreehq/daintree/blob/develop/README.md Run this command if you encounter PTY errors after installation. It rebuilds the node-pty module for Electron. ```bash npm run rebuild ``` -------------------------------- ### Package plugin for distribution Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/dev-loop.md Use the 'package' command to create a distributable .dntr file for your plugin. Optional flags include --verbose, --dry-run, --sourcemaps, and --skip-build. ```bash npx daintree-plugin package [--verbose] [--dry-run] [--sourcemaps] [--skip-build] ``` -------------------------------- ### Multi-Step Workflow with Completion Listener Source: https://github.com/daintreehq/daintree/blob/develop/docs/assistant-listeners.md Orchestrate a multi-step workflow by creating a worktree, launching an agent, and registering a listener for the agent's completion. After completion, retrieve the terminal output. ```javascript // Step 1: Create worktree and launch agent const wt = worktree_createWithRecipe({ branchName: "feature-x", recipeId: "dev" }); const agent = agent_launch({ agentId: "claude", worktreeId: wt.worktreeId, prompt: "Implement feature", }); // Step 2: Register completion listener register_listener({ eventType: "terminal:state-changed", filter: { terminalId: agent.terminalId, toState: "completed" }, }); // Step 3: Handle notification when received // (notification chunk arrives when agent completes) // Then check output and inform user terminal_getOutput({ terminalId: agent.terminalId, maxLines: 50 }); ``` -------------------------------- ### Session Token Validation Example Source: https://github.com/daintreehq/daintree/blob/develop/docs/assistant-listeners.md Validates session tokens to prevent stale observations by checking if the terminal was restarted since the observation began. ```typescript if (spawnedAt !== undefined && terminal.spawnedAt !== spawnedAt) { // Reject - terminal was restarted since observation began return false; } ``` -------------------------------- ### Programmatic Action Dispatch from UI Source: https://github.com/daintreehq/daintree/blob/develop/docs/architecture/action-system.md Example of how to dispatch an action programmatically from a React component using the `actionService`. Handles potential errors from the dispatch. ```typescript // In a React component import { actionService } from "@/services/ActionService"; const handleClick = async () => { const result = await actionService.dispatch("terminal.new"); if (!result.ok) { console.error(result.error.message); } }; ``` -------------------------------- ### Plugin Directory Structure Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/forge-provider.md This illustrates the typical file and directory layout for a new built-in Forge Provider plugin, such as for Gitea. It highlights key files like index.ts for activation and forgeProvider.ts for the main implementation. ```text plugins/builtin/gitea/ ├── plugin.json └── main/ ├── index.ts # activate() — registers the provider ├── forgeProvider.ts # the ForgeProviderImpl object ├── GiteaAuth.ts # token storage, client construction ├── GiteaQueries.ts # transport (REST/GraphQL) calls └── __tests__/ # unit tests, mirroring github's ``` -------------------------------- ### Get Agent State Source: https://github.com/daintreehq/daintree/blob/develop/help/CLAUDE.md An alternative to `terminal.getStatus` when there's a single agent of a specific kind in the project. Prefer `terminal.getStatus` when dealing with multiple agents of the same kind. ```json agent.getState({ agentId }) ``` -------------------------------- ### Running All Full E2E Test Buckets Source: https://github.com/daintreehq/daintree/blob/develop/docs/e2e-testing.md Execute all six comprehensive 'full-*' E2E test buckets. This provides extensive coverage. ```bash npm run test:e2e:full ``` -------------------------------- ### React View Component Implementation Source: https://github.com/daintreehq/daintree/blob/develop/docs/plugins/contribution-points.md Example of a React component that serves as a Daintree view. It utilizes hooks from the plugin SDK and handles cleanup via a disposeSignal. ```tsx // src/dashboard.tsx import { useEffect } from "react"; import type { PanelViewProps } from "@daintreehq/plugin-sdk"; import { useWorktree } from "@daintreehq/plugin-sdk/react"; export default function Dashboard({ panelId, pluginId, disposeSignal }: PanelViewProps) { const worktree = useWorktree(); useEffect(() => { const controller = new AbortController(); // Chain the host signal so the fetch aborts on unmount AND when the // host receives a `plugin:panel-kinds-changed` push that no longer // contains this kind — before main tears down plugin IPC handlers. const onAbort = (): void => controller.abort(); disposeSignal.addEventListener("abort", onAbort); void fetch(`plugin://${pluginId}/api/cost-summary`, { signal: controller.signal }); return () => { disposeSignal.removeEventListener("abort", onAbort); controller.abort(); }; }, [pluginId, disposeSignal]); return
Dashboard for {worktree?.name ?? "no worktree"}
; } ``` -------------------------------- ### Testing Commands Source: https://github.com/daintreehq/daintree/blob/develop/docs/development.md Commands to run tests, either once or in watch mode, and how to filter tests by path. ```bash npm run test # Run once npm run test:watch # Watch mode npm run test -- --run src/components # Filter by path ``` -------------------------------- ### Get Status of Multiple Terminals Source: https://github.com/daintreehq/daintree/blob/develop/scripts/help-src/CLAUDE.tasks.md Obtain the status and recent output for multiple terminals in a single API call. Useful for summarizing the state of the agent fleet. ```javascript terminal.getStatus({ terminalIds: [, , …], includeOutput: { lines: 30 } }) ``` -------------------------------- ### Get Status of Specific Terminals Source: https://github.com/daintreehq/daintree/blob/develop/scripts/help-src/CLAUDE.tasks.md Retrieve the agent state, waiting reason, and last transition time for specified terminals. Include scrollback output if needed. ```javascript terminal.getStatus({ terminalIds: [], includeOutput: { lines: 30 } }) ``` -------------------------------- ### Development Commands Source: https://github.com/daintreehq/daintree/blob/develop/CLAUDE.md Common npm scripts for development, building, testing, and packaging the Daintree project. ```bash npm run dev # Start Main + Renderer (Vite) npm run build # Production build npm run check # typecheck + lint + format npm run fix # Auto-fix lint/format issues npm run package # Distribute npm run rebuild # Rebuild native modules ``` -------------------------------- ### Run Standard Tests (Node.js) Source: https://github.com/daintreehq/daintree/blob/develop/electron/services/__tests__/README.md Execute standard integration tests using npm. PTY integration tests will be skipped if the native module is unavailable. ```bash npm test ```