5.0 KiB
Services
ctx.services is the stable public host facade. It is available to plugins that
declare ui or tooling capabilities.
{
"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?)execTool(request)
Short external tools
services.workspace.execTool() runs a short external executable already available
to the host. It is generic: IdeA does not expose Git, SVN, formatter, or linter
semantics. The plugin owns the arguments and parses the returned output.
const result = await ctx.services!.workspace.execTool({
projectId,
command: "tool",
args: ["status", "--short"],
cwd: ".",
timeoutMs: 5_000,
maxStdoutBytes: 256_000,
maxStderrBytes: 64_000
});
The host passes command and args directly without a shell. The plugin must
declare a matching permissions.workspaceExec.allow rule, be active for the
project, and use a project-relative cwd. IdeA canonicalizes the cwd, bounds
time/stdin/output/concurrency, exposes only an allowlisted environment, applies
the project filesystem sandbox where supported, and audits metadata without
captured stdout/stderr contents. This API returns output directly and never
creates a visible Work/background-task entry.
Current host maxima are 30 seconds, 1,000,000 stdout bytes, 256,000 stderr bytes, and 64,000 stdin bytes. Requested output/time values above a maximum are clamped; zero is rejected. Output is returned as lossy UTF-8 with explicit truncation flags.
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. Unlike manifest-declared MCP servers, runCommand() does not
substitute ${pluginRoot} or ${appDataDir}.
const script = `${ctx.pluginRoot.replace(/[\\/]+$/, "")}/scripts/check.mjs`;
await ctx.services.tasks.runCommand({
projectId,
ownerAgentId,
label: "Run packaged check",
command: "node",
args: [script],
cwd: "."
});
This task example uses node as a host executable visible to the task
environment. That is not the contract for contributes.mcpServers: MCP server
command values are resolved by the plugin manifest rules documented in
Manifest, where a bare command: "node" is package-relative
unless external host-command handling is explicitly enabled.
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.
Resolving this promise means the window was opened or focused. Its
alreadyOpen flag reports which happened; both outcomes are successful and a
menu handler should return status: "opened". Do not gate a diagnostic window
on optional tool availability when that window can present the unavailable
state. A rejection means the window operation itself was impossible and may be
logged or returned as status: "failed"; do not expose its raw error to users.
Scheduled tasks
Project scheduled tasks are exposed through native Tauri/HTTP commands and the
native idea_scheduled_task_* MCP tools. They are intentionally not available as
an activate(ctx) plugin service in V1, and plugins must not emulate them with
system cron or repository-owned auto-executed files.