Skip to content

SFR-271: add manager-style v1 task surface to ClawConnect MCP#23

Merged
jaruesink merged 5 commits into
mainfrom
codex/linear-mention-sfr-271-implement-manager-style-multi-taski
May 19, 2026
Merged

SFR-271: add manager-style v1 task surface to ClawConnect MCP#23
jaruesink merged 5 commits into
mainfrom
codex/linear-mention-sfr-271-implement-manager-style-multi-taski

Conversation

@jaruesink
Copy link
Copy Markdown
Contributor

@jaruesink jaruesink commented May 18, 2026

Motivation

  • Provide a lightweight, manager-friendly task surface so callers can coordinate and inspect multiple concurrent tasks without digging into low-level session details.
  • Offer a compact task summary model and listing API separate from session plumbing to support manager workflows (what needs attention) while keeping session tools for debugging (what happened).
  • Keep v1 stateless inside ClawConnect and avoid adding persistence or a plugin-backed annotation layer.

Description

  • Added TaskStatus and TaskSummary types and extended RunTaskResult with an optional taskId in packages/core/src/types.ts to represent manager-level tasks (v1 maps taskId to jobId).
  • Implemented listTasks(pool) in packages/core/src/tools.ts and exported it from packages/core/src/index.ts to enumerate compact task summaries across agents.
  • Added manager-facing tools:
    • list_tasks(view?) for compact task listings with active and all views.
    • get_task(taskId, detail?, mode?) for task inspection using detail presets: core, summary, updates, artifacts, diagnostics, full, and fullWithDiagnostics.
    • get_session(sessionId, mode?, limit?, after?, agent?) for session debugging with snapshot, events, and tail modes.
  • Wired the new surfaces through both the MCP server package and the ChatGPT connector app path.
  • Preserved existing run_task, check_task, and list_sessions behavior for backward compatibility while introducing the new task-level surfaces.

Testing

  • pnpm ready passes on the PR branch after the final detail enum update.
  • Live ChatGPT connector smoke-tested after refresh/rebuild:
    • list_tasks({ view: "all" })
    • list_tasks({ view: "active" })
    • get_task({ detail: "core" })
    • get_task({ detail: "updates" })
    • get_task({ detail: "full" })
    • get_task({ detail: "fullWithDiagnostics" })
    • get_session snapshot/events/tail behavior from earlier testing
  • CodeRabbit review comments were addressed and visible review threads are resolved.

Codex Task

Summary by CodeRabbit

  • New Features
    • View all tasks with lifecycle statuses (queued, running, blocked, needs-human, done, failed), IDs and timestamps
    • Retrieve detailed task snapshots: summaries, logs/updates, artifacts, diagnostics and error flags
    • Task creation now returns a task ID and optional agent for easier tracking
    • Inspect sessions with snapshot/events/tail modes, limit/after paging, and computed next-after for tails
    • Server tools: list and inspect tasks/sessions with configurable formatting and an "active" view filter

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds TaskStatus and TaskSummary types; extends RunTaskResult. Implements listTasks and getSession in core tools and re-exports them. MCP server and chat app add tools/formatters for listing and inspecting tasks and sessions with agent-scoped handlers.

Changes

Task Listing and Status Tracking

Layer / File(s) Summary
Task status and summary types
packages/core/src/types.ts
TaskStatus union covers lifecycle states. TaskSummary captures task/job/session ids, status, timestamps, and optional summary/error. RunTaskResult extended with optional taskId and agent.
Core tools imports and runTask return
packages/core/src/tools.ts
Adds TaskSummary import, extends runTask return object to include taskId, and adds helpers to map internal job states into TaskStatus.
Core list/get session functions
packages/core/src/tools.ts
listTasks(pool) aggregates the latest job per session into TaskSummary[]. getSession(pool, opts) locates a session, fetches latest job and logs, and returns either a snapshot or tail view with computed nextAfter and bounded limit/after.
Package public exports
packages/core/src/index.ts
Adds listTasks and getSession to tools re-exports; adds TaskSummary and TaskStatus to type re-exports.
MCP server task tools
packages/mcp/src/server.ts
Imports new core functions/types; adds ProviderConfig.formatListTasks and formatGetSession hooks with default formatters; wires formatters in createMcpServer; registers list_tasks (supports view="active") and get_task (uses checkTask, conditionally includes fields, propagates isError) tools; updates get_session to use fmtGetSession.
App: MCP tool schemas & handlers
apps/chatgpt/src/index.ts
Adds tool schemas for list_tasks, get_task, get_session and implements call handling that enforces agent scope, invokes core listTasks/checkTask/getSession, and builds structuredContent payloads.

Sequence Diagrams

sequenceDiagram
  participant Client
  participant listTasks_fn
  participant GatewayPool
  participant SessionStore
  Client->>listTasks_fn: listTasks(pool)
  listTasks_fn->>GatewayPool: iterate entries & sessions
  GatewayPool->>SessionStore: fetch latest job for session
  SessionStore-->>GatewayPool: job object
  listTasks_fn->>listTasks_fn: map job -> TaskSummary (mapTaskStatus)
  listTasks_fn-->>Client: TaskSummary[]
Loading
sequenceDiagram
  participant MCP_Client
  participant list_tasks_tool
  participant listTasks_fn
  participant MCP_Server
  participant checkTask_fn
  MCP_Client->>list_tasks_tool: invoke list_tasks(view)
  list_tasks_tool->>listTasks_fn: listTasks(pool)
  listTasks_fn-->>list_tasks_tool: TaskSummary[]
  list_tasks_tool->>list_tasks_tool: filter by view and format via fmtListTasks
  list_tasks_tool-->>MCP_Client: McpToolResponse
  MCP_Client->>MCP_Server: invoke get_task(taskId, include)
  MCP_Server->>checkTask_fn: checkTask(pool, jobId)
  checkTask_fn-->>MCP_Server: snapshot or null
  MCP_Server->>MCP_Client: formatted McpToolResponse
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding manager-style task surface functionality to ClawConnect MCP, which aligns with the primary objectives of adding TaskStatus, TaskSummary types, listTasks() implementation, and new MCP tool endpoints.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/linear-mention-sfr-271-implement-manager-style-multi-taski

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/tools.ts`:
- Around line 29-33: The mapping in mapTaskStatus incorrectly collapses
intervention-required states into "failed"; update mapTaskStatus to explicitly
return "needs-human" when input is "needs-human" and "blocked" when input is
"blocked" (in addition to keeping "running" -> "running",
"completed"/"completed_no_summary" -> "done", and default -> "failed") so
manager workflows can distinguish human-intervention states; apply the same
explicit mappings to the other occurrence of mapTaskStatus in the file and
ensure TaskSummary["status"] types include "needs-human" and "blocked" if
necessary.
- Line 49: The code sets summary: job.summary ?? session.lastSummary which can
surface stale summaries from prior jobs; change this to avoid falling back to
session.lastSummary for per-task listings — instead set summary to job.summary
(or null/undefined) and only use session.lastSummary in contexts that are
explicitly session-level; update the assignment in the block that defines
summary (referencing job.summary and session.lastSummary) so per-task entries do
not inherit session.lastSummary.

In `@packages/mcp/src/server.ts`:
- Line 260: The summary field currently treats include: [] as "not provided" and
returns snapshot.summary; update the logic in the get_task response construction
(the expression that sets summary) to distinguish undefined include from an
explicit empty array — i.e. only return snapshot.summary when include is
strictly undefined, otherwise return snapshot.summary only if
include.includes("summary") is true; locate the expression with summary:
include?.length ? (include.includes("summary") ? snapshot.summary : undefined) :
snapshot.summary and change it to check include === undefined vs
include.includes("summary").
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 68c4fd0b-d9fd-454e-9306-9f0532c1d3ab

📥 Commits

Reviewing files that changed from the base of the PR and between 04f11d9 and eafb357.

📒 Files selected for processing (4)
  • packages/core/src/index.ts
  • packages/core/src/tools.ts
  • packages/core/src/types.ts
  • packages/mcp/src/server.ts

Comment thread packages/core/src/tools.ts
Comment thread packages/core/src/tools.ts Outdated
Comment thread packages/mcp/src/server.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/core/src/tools.ts (1)

31-43: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve explicit "needs-human" / "blocked" statuses in fallback mapping.

deriveTaskStatus can still fall back to mapTaskStatus(job.status) (Line 42), but mapTaskStatus currently downgrades unknown statuses to "failed". That still collapses explicit intervention states if they arrive via job.status.

Suggested minimal fix
 function mapTaskStatus(status: string): TaskSummary["status"] {
   if (status === "running") return "running";
   if (status === "completed" || status === "completed_no_summary") return "done";
+  if (status === "needs-human") return "needs-human";
+  if (status === "blocked") return "blocked";
   return "failed";
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/tools.ts` around lines 31 - 43, mapTaskStatus currently
downgrades any unrecognized status to "failed", which can overwrite explicit
"needs-human" and "blocked" states when deriveTaskStatus falls back to it;
update mapTaskStatus (and keep deriveTaskStatus as-is) so it preserves those
intervention statuses by returning "needs-human" when status === "needs-human"
and "blocked" when status === "blocked" (or more generally return the incoming
status when it already matches a valid TaskSummary["status"]) instead of mapping
them to "failed".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/core/src/tools.ts`:
- Around line 31-43: mapTaskStatus currently downgrades any unrecognized status
to "failed", which can overwrite explicit "needs-human" and "blocked" states
when deriveTaskStatus falls back to it; update mapTaskStatus (and keep
deriveTaskStatus as-is) so it preserves those intervention statuses by returning
"needs-human" when status === "needs-human" and "blocked" when status ===
"blocked" (or more generally return the incoming status when it already matches
a valid TaskSummary["status"]) instead of mapping them to "failed".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 34fdf1e5-d4cb-494a-a061-79aa1c0c61ec

📥 Commits

Reviewing files that changed from the base of the PR and between eafb357 and 521d397.

📒 Files selected for processing (4)
  • packages/core/src/index.ts
  • packages/core/src/tools.ts
  • packages/core/src/types.ts
  • packages/mcp/src/server.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/index.ts
  • packages/core/src/types.ts

…aden active view

- mapTaskStatus now preserves needs-human, blocked, and queued instead of
  collapsing them to failed. deriveTaskStatus already handled these before
  falling through, but the fallback path no longer loses semantics.

- list_tasks(view='active') now includes all non-terminal statuses (queued,
  running, blocked, needs-human) instead of only running.

- Add isActiveTaskStatus predicate with ACTIVE_STATUSES set for clarity.

Review feedback addressed:
- CodeRabbit: mapTaskStatus can collapse needs-human/blocked to failed
- CodeRabbit: active view should mean non-terminal, not just running
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/mcp/src/server.ts`:
- Line 267: The not-found branch in the get_task handler currently returns
defaultFormatCheckTask(result) directly; change it to use the configured
provider formatter (call provider.formatCheckTask(result) or the equivalent
configured check formatter used by check_task) and only fall back to
defaultFormatCheckTask(result) when the provider/formatter is undefined; update
the get_task flow that references result and provider so get_task and check_task
use the same provider.formatCheckTask behavior for consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fd75e6cc-0e76-40da-9472-5a207a32196e

📥 Commits

Reviewing files that changed from the base of the PR and between 521d397 and 92454d2.

📒 Files selected for processing (2)
  • packages/core/src/tools.ts
  • packages/mcp/src/server.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/tools.ts

Comment thread packages/mcp/src/server.ts
jaruesink added 2 commits May 19, 2026 00:01
The new manager-style tools (get_task, list_tasks, get_session) were only
registered in packages/mcp/src/server.ts (MCP SDK server). The ChatGPT
connector has its own hand-rolled JSON-RPC handler and was never updated.

Root cause: ChatGPT connector's buildTools() and tools/call handler had no
knowledge of get_task / list_tasks / get_session. Calls would hit the
"Unknown tool" error path, or the tools were invisible via tools/list.

Changes:
- Import listTasks, getSession, TaskSummary from @clawconnect/core
- Add list_tasks, get_task, get_session tool definitions to buildTools()
- Add tools/call handlers with proper scope filtering
- get_task.include is respected: undefined = summary only, [] = core only,
  specific includes add only those fields
Replace include?: ('summary'|'updates'|'artifacts'|'diagnostics')[]
with detail?: 'core'|'summary'|'updates'|'artifacts'|'diagnostics'|'full'|'fullWithDiagnostics'

Avoids non-empty array tool-bridge issues by using a single enum value
instead of an array. Omitted detail defaults to 'summary' (same behavior).

Applied in packages/mcp/src/server.ts and apps/chatgpt/src/index.ts.
pnpm ready passes cleanly.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
packages/mcp/src/server.ts (1)

270-272: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the configured check formatter for get_task misses.

Line 272 still bypasses provider.formatCheckTask, so custom providers get inconsistent not-found output between check_task and get_task.

Suggested fix
     async ({ taskId, detail, mode }) => {
       const result = await checkTask(pool, { jobId: taskId, mode: (mode as CheckMode) ?? defaultMode });
-      if (!result.found) return defaultFormatCheckTask(result);
+      if (!result.found) return fmtCheck(result);
       const snapshot = result.snapshot;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/mcp/src/server.ts` around lines 270 - 272, When a checkTask call
returns not found in the get_task handler, don't always return
defaultFormatCheckTask; instead call the configured provider's formatter
(provider.formatCheckTask) so custom providers get consistent "not found"
output. Update the async handler that calls checkTask (the block using { taskId,
detail, mode }) to branch on result.found and, when false, invoke
provider.formatCheckTask(result, { detail, mode }) (or the provider's expected
signature) and return that output instead of defaultFormatCheckTask; keep
defaultFormatCheckTask as the fallback if provider.formatCheckTask is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/mcp/src/server.ts`:
- Around line 270-272: When a checkTask call returns not found in the get_task
handler, don't always return defaultFormatCheckTask; instead call the configured
provider's formatter (provider.formatCheckTask) so custom providers get
consistent "not found" output. Update the async handler that calls checkTask
(the block using { taskId, detail, mode }) to branch on result.found and, when
false, invoke provider.formatCheckTask(result, { detail, mode }) (or the
provider's expected signature) and return that output instead of
defaultFormatCheckTask; keep defaultFormatCheckTask as the fallback if
provider.formatCheckTask is missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4cbe4472-e13d-4649-966a-39c623bc6bb5

📥 Commits

Reviewing files that changed from the base of the PR and between 4abe959 and d94cd1e.

📒 Files selected for processing (2)
  • apps/chatgpt/src/index.ts
  • packages/mcp/src/server.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/chatgpt/src/index.ts

@jaruesink jaruesink merged commit 26a11d5 into main May 19, 2026
1 check passed
@jaruesink jaruesink deleted the codex/linear-mention-sfr-271-implement-manager-style-multi-taski branch May 19, 2026 05:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant