# Services `ctx.services` is the stable public host facade. It is available to plugins that declare `ui` or `tooling` capabilities. ```json { "capabilities": ["ui", "tooling"] } ``` ## Workspace `services.workspace` reads the focused/current project, project context and project-owned files. Paths are relative to the project root; hosts reject absolute paths and traversal outside the workspace. Key APIs: - `getCurrentProject()` - `getProjectRoot(projectId?)` - `readProjectContext(projectId?)` - `updateProjectContext(content, projectId?)` - `readTextFile(path, projectId?)` - `writeTextFile(path, content, projectId?)` - `readBinaryFile(path, projectId?)` - `writeBinaryFile(path, bytes, projectId?)` - `listDirectory(path?, projectId?)` - `stat(path, projectId?)` - `watch(path, handler, projectId?)` - `queryStructure(query?)` ## Tasks `services.tasks` launches and inspects host-managed command tasks. Use `runCommand()` only after preconditions are satisfied. `ownerAgentId` must be a real agent id when work belongs to an agent workflow. `runCommand()` keeps its `cwd` project/workspace scoped: `cwd` must be a relative path under the project root. The host does not implicitly resolve `command` or `args` against the plugin package. Use the absolute `ctx.pluginRoot` supplied at activation time to construct an explicit path to a packaged script, and pass that path as `command` or as an argument to its interpreter. Treat package files as read-only. ```ts const script = `${ctx.pluginRoot.replace(/[\\/]+$/, "")}/scripts/check.mjs`; await ctx.services.tasks.runCommand({ projectId, ownerAgentId, label: "Run packaged check", command: "node", args: [script], cwd: "." }); ``` ## Tooling `services.tooling.diagnose()` checks executables, environment values and files from the host-controlled runtime. ## Events `services.events.subscribe()` provides best-effort bounded subscriptions to public plugin events such as workspace file changes and background task changes. Dispose subscriptions when no longer needed. ## Config `services.config` reads and updates structured JSON documents in project-owned locations. Use it for configuration the user expects to review/version. ## Terminal `services.terminal` opens, reattaches and closes terminal sessions: - `open({ cwd?, rows?, cols?, onData? })` - `reattach(sessionId, { onData? })` - `close(sessionId)` ## Windows `services.windows.open({ layoutType, state? })` opens a detached OS window for one of the calling plugin's declared layout contributions. See [Windows](windows.md).