doc(sdk): add host logger support in plugin examples (#11363)

* doc(sdk): add host logger support in plugin examples

Add examples to use the exposed `ctx.logger` to plugins via the `setup` second argument for
diagnostics. Wire logging into the agents-squad example to record setup,
subagent starts, follow-ups, and async failures, with a `logPluginError`
helper that falls back to severity-tagged logs. Update README with
logger usage guidance and examples.

* patches
This commit is contained in:
Bee
2026-06-08 16:29:38 -07:00
committed by GitHub
parent cfc2250717
commit 2ad4146de1
3 changed files with 65 additions and 2 deletions
+30 -1
View File
@@ -19,13 +19,41 @@ Examples include:
- `mac-notify.ts` - macOS Notification Center alerts
- `custom-compaction.ts` - Custom context compaction
- `automation-events.ts` - Plugin event emission
- `background-terminal.ts` - Background shell jobs with logging
- `background-terminal.ts` - Background shell jobs with setup and job logging
```bash
cline plugin install https://github.com/cline/cline/blob/main/sdk/examples/plugins/weather-metrics.ts
cline -i "What's the weather like in Tokyo and Paris?"
```
Plugin setup receives a host logger through the second `setup` argument. Use
`ctx.logger` for setup-time diagnostics and logs emitted during tool calls:
```ts
setup(api, ctx) {
ctx.logger?.log("my-plugin setup", {
sessionId: ctx.session?.sessionId,
workspaceRoot: ctx.workspaceInfo?.rootPath,
});
try {
// Register tools or perform plugin setup work.
} catch (error) {
if (ctx.logger?.error) {
ctx.logger.error("my-plugin setup failed", { error });
} else {
ctx.logger?.log("my-plugin setup failed", { error, severity: "error" });
}
throw error;
}
}
```
`ctx.logger` is session-scoped. For detached work that can outlive the session,
such as background processes, persist status to plugin-owned storage or report
completion through the host event channel instead of calling the captured logger
from long-lived callbacks.
### [`./plugins/typescript-lsp/`](./plugins/typescript-lsp)
TypeScript LSP plugin that gives the agent a `goto_definition` tool powered by the TypeScript Language Service API. Resolves through imports, re-exports, and type aliases -- much more precise than text search.
@@ -47,6 +75,7 @@ cline -i "Find where createTool is defined"
- Export a reusable plugin module for `.cline/plugins`
- Start background subagents from the main session
- Load bundled or custom agent presets and skills
- Log setup, subagent starts, and follow-ups through `ctx.logger`
Includes pre-configured agents:
- **Anvil** - Build and compile
+22 -1
View File
@@ -506,7 +506,15 @@ const plugin: AgentPlugin = {
name: "portable-subagents",
manifest: { capabilities: ["tools"] },
setup(api) {
setup(api, ctx) {
const logger = ctx.logger;
logger?.log("portable-subagents plugin setup", {
sessionId: ctx.session?.sessionId,
defaultPreset: DEFAULT_AGENT_PRESET,
backendMode: DEFAULT_BACKEND_MODE,
workspaceRoot: ctx.workspaceInfo?.rootPath,
});
// -- start_subagent: Start a new subagent session --
api.registerTool(
toRegisteredTool(
@@ -571,6 +579,14 @@ const plugin: AgentPlugin = {
status: "running",
};
subagents.set(sessionId, subagent);
logger?.log("Started subagent", {
sessionId,
toolName: "start_subagent",
label: input.label,
preset: def?.name ?? input.preset,
providerId,
modelId,
});
void runSubagentTurn(
subagent,
input.task,
@@ -655,6 +671,11 @@ const plugin: AgentPlugin = {
subagent.error = undefined;
subagents.set(subagent.sessionId, subagent);
logger?.log("Queued subagent follow-up", {
sessionId: subagent.sessionId,
toolName: "message_subagent",
label: subagent.name,
});
void runSubagentTurn(
subagent,
input.prompt,
@@ -266,6 +266,11 @@ const plugin: AgentPlugin = {
workspaceContext?.rootPath?.trim() ||
sessionDefaultCwd;
setupSessionId = ctx.session?.sessionId?.trim() || undefined;
ctx.logger?.log("background-terminal plugin setup", {
sessionId: setupSessionId,
defaultCwd: sessionDefaultCwd,
jobsDir: JOBS_DIR,
});
api.registerTool(
createTool<unknown, Record<string, unknown>>({
@@ -311,6 +316,14 @@ const plugin: AgentPlugin = {
notifyParent,
resolveToolSessionId(context),
);
ctx.logger?.log("Started background command", {
sessionId: record.sessionId,
toolName: "start_background_command",
jobId: record.jobId,
cwd: record.cwd,
shell: record.shell,
pid: record.pid,
});
return {
jobId: record.jobId,